ruby-ole 1.2.3 → 1.2.4

Sign up to get free protection for your applications and to get access to all the features.
data/ChangeLog CHANGED
@@ -1,3 +1,8 @@
1
+ == 1.2.4 / ...
2
+
3
+ - Make all tests pass on windows (issue #1).
4
+ - Make all tests pass on a power pc (running ubuntu).
5
+
1
6
  == 1.2.3 / 2007-12-28
2
7
 
3
8
  - MBAT write support re-implmented. Can now write files over ~8mb again.
data/Rakefile CHANGED
@@ -53,7 +53,7 @@ spec = Gem::Specification.new do |s|
53
53
  s.rubyforge_project = %q{ruby-ole}
54
54
 
55
55
  s.executables = ['oletool']
56
- s.files = ['Rakefile', 'ChangeLog']
56
+ s.files = ['Rakefile', 'ChangeLog', 'data/propids.yaml']
57
57
  s.files += FileList['lib/**/*.rb']
58
58
  s.files += FileList['test/test_*.rb', 'test/*.doc']
59
59
  s.files += FileList['test/oleWithDirs.ole', 'test/test_SummaryInformation']
@@ -0,0 +1,56 @@
1
+ "{f29f85e0-4ff9-1068-ab91-08002b27b3d9}":
2
+ - FMTID_SummaryInformation
3
+ - 2: doc_title
4
+ 3: doc_subject
5
+ 4: doc_author
6
+ 5: doc_keywords
7
+ 6: doc_comments
8
+ 7: doc_template
9
+ 8: doc_last_author
10
+ 9: doc_rev_number
11
+ 10: doc_edit_time
12
+ 11: doc_last_printed
13
+ 12: doc_created_time
14
+ 13: doc_last_saved_time
15
+ 14: doc_page_count
16
+ 15: doc_word_count
17
+ 16: doc_char_count
18
+ 18: doc_app_name
19
+ 19: security
20
+
21
+ "{d5cdd502-2e9c-101b-9397-08002b2cf9ae}":
22
+ - FMTID_DocSummaryInfo
23
+ - 2: doc_category
24
+ 3: doc_presentation_target
25
+ 4: doc_byte_count
26
+ 5: doc_line_count
27
+ 6: doc_para_count
28
+ 7: doc_slide_count
29
+ 8: doc_note_count
30
+ 9: doc_hidden_count
31
+ 10: mmclips
32
+ 11: scale_crop
33
+ 12: heading_pairs
34
+ 13: doc_part_titles
35
+ 14: doc_manager
36
+ 15: doc_company
37
+ 16: links_up_to_date
38
+
39
+ "{d5cdd505-2e9c-101b-9397-08002b2cf9ae}":
40
+ - FMTID_UserDefinedProperties
41
+ - {}
42
+
43
+ # just dumped these all here. if i can confirm any of these
44
+ # better, i can update this file so they're recognized.
45
+ #0b63e343-9ccc-11d0-bcdb-00805fccce04
46
+ #0b63e350-9ccc-11d0-bcdb-00805fccce04 NetLibrary propset?
47
+ #31f400a0-fd07-11cf-b9bd-00aa003db18e ScriptInfo propset?
48
+ #49691c90-7e17-101a-a91c-08002b2ecda9 Query propset?
49
+ #560c36c0-503a-11cf-baa1-00004c752a9a
50
+ #70eb7a10-55d9-11cf-b75b-00aa0051fe20 HTMLInfo propset
51
+ #85ac0960-1819-11d1-896f-00805f053bab message propset?
52
+ #aa568eec-e0e5-11cf-8fda-00aa00a14f93 NNTP SummaryInformation propset?
53
+ #b725f130-47ef-101a-a5f1-02608c9eebac Storage propset
54
+ #c82bf596-b831-11d0-b733-00aa00a1ebd2 NetLibraryInfo propset
55
+ #c82bf597-b831-11d0-b733-00aa00a1ebd2 LinkInformation propset?
56
+ #d1b5d3f0-c0b3-11cf-9a92-00a0c908dbf1 LinkInformation propset?
@@ -132,7 +132,11 @@ module Ole # :nodoc:
132
132
  # just for the .. and . handling
133
133
  # Hmmm, FIXME: won't work on windows i think. on windows it will prepend
134
134
  # the current drive i believe. may just need to strip the first 2 chars.
135
- File.expand_path path
135
+ if RUBY_PLATFORM =~ /win/o
136
+ File.expand_path(path)[2..-1]
137
+ else
138
+ File.expand_path path
139
+ end
136
140
  end
137
141
 
138
142
  # +orig_path+ is just so that we can use the requested path
@@ -1,4 +1,5 @@
1
1
  require 'ole/types'
2
+ require 'yaml'
2
3
 
3
4
  module Ole
4
5
  module Types
@@ -13,30 +14,41 @@ module Ole
13
14
  #
14
15
  class PropertySet
15
16
  HEADER_SIZE = 28
16
- HEADER_UNPACK = "vvVa#{Clsid::SIZE}V"
17
+ HEADER_PACK = "vvVa#{Clsid::SIZE}V"
17
18
  OS_MAP = {
18
19
  0 => :win16,
19
20
  1 => :mac,
20
- 2 => :win32
21
+ 2 => :win32,
22
+ 0x20001 => :ooffice, # open office on linux...
21
23
  }
22
24
 
23
25
  # define a smattering of the property set guids.
24
- FMTID_SummaryInformation = Clsid.parse '{f29f85e0-4ff9-1068-ab91-08002b27b3d9}'
25
- FMTID_DocSummaryInformation = Clsid.parse '{d5cdd502-2e9c-101b-9397-08002b2cf9ae}'
26
- FMTID_UserDefinedProperties = Clsid.parse '{d5cdd505-2e9c-101b-9397-08002b2cf9ae}'
26
+ #FMTID_SummaryInformation = Clsid.parse '{f29f85e0-4ff9-1068-ab91-08002b27b3d9}'
27
+ #FMTID_DocSummaryInformation = Clsid.parse '{d5cdd502-2e9c-101b-9397-08002b2cf9ae}'
28
+ #FMTID_UserDefinedProperties = Clsid.parse '{d5cdd505-2e9c-101b-9397-08002b2cf9ae}'
29
+
30
+ DATA = YAML.load_file(File.dirname(__FILE__) + '/../../data/propids.yaml').
31
+ inject({}) { |hash, (key, value)| hash.update Clsid.parse(key) => value }
32
+
33
+ module Constants
34
+ DATA.each { |guid, (name, map)| const_set name, guid }
35
+ end
36
+
37
+ include Constants
27
38
 
28
39
  class Section < Struct.new(:guid, :offset)
29
40
  include Variant::Constants
30
41
  include Enumerable
31
42
 
32
43
  SIZE = Clsid::SIZE + 4
33
- UNPACK_STR = "a#{Clsid::SIZE}v"
44
+ PACK = "a#{Clsid::SIZE}v"
34
45
 
35
46
  attr_reader :length
36
47
  def initialize str, property_set
37
48
  @property_set = property_set
38
- super(*str.unpack(UNPACK_STR))
49
+ super(*str.unpack(PACK))
39
50
  self.guid = Clsid.load guid
51
+ @map = DATA[guid] ? DATA[guid][1] : nil
40
52
  load_header
41
53
  end
42
54
 
@@ -66,9 +78,30 @@ module Ole
66
78
  self
67
79
  end
68
80
 
81
+ def [] key
82
+ unless Integer === key
83
+ return unless @map and key = @map.invert[key]
84
+ end
85
+ return unless result = properties.assoc(key)
86
+ result.last
87
+ end
88
+
89
+ def method_missing name, *args
90
+ if args.empty? and @map and @map.values.include? name.to_s
91
+ self[name.to_s]
92
+ else
93
+ super
94
+ end
95
+ end
96
+
69
97
  def properties
70
- to_enum.to_a
98
+ @properties ||= to_enum.to_a
71
99
  end
100
+
101
+ #def to_h
102
+ # properties.inject({}) do |hash, (key, type, value)|
103
+ # hash.update
104
+ #end
72
105
  end
73
106
 
74
107
  attr_reader :io, :signature, :unknown, :os, :guid, :sections
@@ -81,7 +114,7 @@ module Ole
81
114
  end
82
115
 
83
116
  def load_header str
84
- @signature, @unknown, @os_id, @guid, @num_sections = str.unpack HEADER_UNPACK
117
+ @signature, @unknown, @os_id, @guid, @num_sections = str.unpack HEADER_PACK
85
118
  # should i check that unknown == 0? it usually is. so is the guid actually
86
119
  @guid = Clsid.load @guid
87
120
  @os = OS_MAP[@os_id] || Log.warn("unknown operating system id #{@os_id}")
@@ -92,5 +125,48 @@ module Ole
92
125
  end
93
126
  end
94
127
  end
128
+
129
+ class Storage
130
+ # i'm thinking - search for a property set in +filenames+ containing a
131
+ # section with guid +guid+. then yield it. can read/write to it in the
132
+ # block.
133
+ # propsets themselves can have guids, but they are often all null.
134
+ def with_property_set guid, filenames=nil
135
+ end
136
+
137
+ class PropertySetSectionProxy
138
+ attr_reader :obj, :section_num
139
+ def initialize obj, section_num
140
+ @obj, @section_num = obj, section_num
141
+ end
142
+
143
+ def method_missing name, *args, &block
144
+ obj.open do |io|
145
+ section = Types::PropertySet.new(io).sections[section_num]
146
+ section.send name, *args, &block
147
+ end
148
+ end
149
+ end
150
+
151
+ # this will be changed to use with_property_set
152
+ def summary_information
153
+ dirent = root["\005SummaryInformation"]
154
+ dirent.open do |io|
155
+ propset = Types::PropertySet.new(io)
156
+ sections = propset.sections
157
+ # this will maybe get wrapped up as
158
+ # section = propset[guid]
159
+ # maybe taking it one step further, i'd hide the section thing,
160
+ # and let you use composite keys, like
161
+ # propset[4, guid] eg in MAPI, and just propset.doc_author.
162
+ section = sections.find do |section|
163
+ section.guid == Types::PropertySet::FMTID_SummaryInformation
164
+ end
165
+ return PropertySetSectionProxy.new(dirent, sections.index(section))
166
+ end
167
+ end
168
+
169
+ alias summary_info :summary_information
170
+ end
95
171
  end
96
172
 
@@ -67,7 +67,7 @@ module Ole # :nodoc:
67
67
  class FormatError < StandardError # :nodoc:
68
68
  end
69
69
 
70
- VERSION = '1.2.3'
70
+ VERSION = '1.2.4'
71
71
 
72
72
  # options used at creation time
73
73
  attr_reader :params
@@ -151,7 +151,7 @@ module Ole # :nodoc:
151
151
  # create an empty bbat.
152
152
  @bbat = AllocationTable::Big.new self
153
153
  mbat_blocks = (0...@header.num_mbat).map { |i| i + @header.mbat_start }
154
- bbat_chain = (header_block[Header::SIZE..-1] + @bbat.read(mbat_blocks)).unpack 'L*'
154
+ bbat_chain = (header_block[Header::SIZE..-1] + @bbat.read(mbat_blocks)).unpack 'V*'
155
155
  # am i using num_bat in the right way?
156
156
  @bbat.load @bbat.read(bbat_chain[0, @header.num_bat])
157
157
 
@@ -308,12 +308,12 @@ module Ole # :nodoc:
308
308
  q = @bbat.block_size / 4
309
309
  mbat_data += [AllocationTable::AVAIL] *((mbat_data.length / q.to_f).ceil * q - mbat_data.length)
310
310
  ranges = @bbat.ranges((0...num_mbat_blocks).map { |i| @header.mbat_start + i })
311
- RangesIO.open(@io, :ranges => ranges) { |io| io.write mbat_data.pack('L*') }
311
+ RangesIO.open(@io, :ranges => ranges) { |io| io.write mbat_data.pack('V*') }
312
312
  end
313
313
 
314
314
  # now seek back and write the header out
315
315
  @io.seek 0
316
- @io.write @header.to_s + bbat_chain[0, 109].pack('L*')
316
+ @io.write @header.to_s + bbat_chain[0, 109].pack('V*')
317
317
  @io.flush
318
318
  end
319
319
 
@@ -333,10 +333,13 @@ module Ole # :nodoc:
333
333
  end
334
334
 
335
335
  # could be useful with mis-behaving ole documents. or to just clean them up.
336
- # FIXME: heard Tempfile is not binary on windows. check
337
336
  def repack temp=:file
338
337
  case temp
339
- when :file; Tempfile.open 'ole-repack', &method(:repack_using_io)
338
+ when :file
339
+ Tempfile.open 'ole-repack' do |io|
340
+ io.binmode
341
+ repack_using_io io
342
+ end
340
343
  when :mem; StringIO.open(&method(:repack_using_io))
341
344
  else raise ArgumentError, "unknown temp backing #{temp.inspect}"
342
345
  end
@@ -372,7 +375,7 @@ module Ole # :nodoc:
372
375
  :reserved, :csectdir, :num_bat, :dirent_start, :transacting_signature, :threshold,
373
376
  :sbat_start, :num_sbat, :mbat_start, :num_mbat
374
377
  )
375
- PACK = 'a8 a16 S2 a2 S2 a6 L3 a4 L5'
378
+ PACK = 'a8 a16 v2 a2 v2 a6 V3 a4 V5'
376
379
  SIZE = 0x4c
377
380
  # i have seen it pointed out that the first 4 bytes of hex,
378
381
  # 0xd0cf11e0, is supposed to spell out docfile. hmmm :)
@@ -462,7 +465,7 @@ module Ole # :nodoc:
462
465
  end
463
466
 
464
467
  def load data
465
- replace data.unpack('L*')
468
+ replace data.unpack('V*')
466
469
  end
467
470
 
468
471
  def truncate
@@ -486,7 +489,7 @@ module Ole # :nodoc:
486
489
  # do you really use AVAIL? they probably extend past end of file, and may shortly
487
490
  # be used for the bat. not really good.
488
491
  table += [AVAIL] * (num - (table.length % num)) if (table.length % num) != 0
489
- table.pack 'L*'
492
+ table.pack 'V*'
490
493
  end
491
494
 
492
495
  # rewrote this to be non-recursive as it broke on a large attachment
@@ -716,7 +719,7 @@ module Ole # :nodoc:
716
719
  )
717
720
  include RecursivelyEnumerable
718
721
 
719
- PACK = 'a64 S C C L3 a16 L a8 a8 L2 a4'
722
+ PACK = 'a64 v C C V3 a16 V a8 a8 V2 a4'
720
723
  SIZE = 128
721
724
  TYPE_MAP = {
722
725
  # this is temporary
@@ -754,7 +757,7 @@ module Ole # :nodoc:
754
757
  super(*values)
755
758
 
756
759
  # extra parsing from the actual struct values
757
- @name = params[:name] || Types::Variant.load(Types::VT_LPWSTR, name_utf16[0...name_len].sub(/\x00\x00$/, ''))
760
+ @name = params[:name] || Types::Variant.load(Types::VT_LPWSTR, name_utf16[0...name_len])
758
761
  @type = if params[:type]
759
762
  unless TYPE_MAP.values.include?(params[:type])
760
763
  raise ArgumentError, "unknown type #{params[:type].inspect}"
@@ -22,7 +22,17 @@ module Ole # :nodoc:
22
22
  end
23
23
  end
24
24
 
25
- class Lpstr < Data
25
+ class Lpstr < String
26
+ def self.load str
27
+ # not sure if its always there, but there is often a trailing
28
+ # null byte.
29
+ new str.chomp(0.chr)
30
+ end
31
+
32
+ def self.dump str
33
+ # do i need to append the null byte?
34
+ str.to_s
35
+ end
26
36
  end
27
37
 
28
38
  # for VT_LPWSTR
@@ -31,10 +41,11 @@ module Ole # :nodoc:
31
41
  TO_UTF16 = Iconv.new 'utf-16le', 'utf-8'
32
42
 
33
43
  def self.load str
34
- new FROM_UTF16.iconv(str)
44
+ new FROM_UTF16.iconv(str).chomp(0.chr)
35
45
  end
36
46
 
37
47
  def self.dump str
48
+ # need to append nulls?
38
49
  TO_UTF16.iconv str
39
50
  end
40
51
  end
@@ -50,7 +61,7 @@ module Ole # :nodoc:
50
61
  # Converts +str+ to two 32 bit time values, comprising the high and low 32 bits of
51
62
  # the 100's of nanoseconds since 1st january 1601 (Epoch).
52
63
  def self.load str
53
- low, high = str.to_s.unpack 'L2'
64
+ low, high = str.to_s.unpack 'V2'
54
65
  # we ignore these, without even warning about it
55
66
  return nil if low == 0 and high == 0
56
67
  # switched to rational, and fixed the off by 1 second error i sometimes got.
@@ -74,7 +85,7 @@ module Ole # :nodoc:
74
85
  # don't bother to use const_get here
75
86
  bignum = (time - EPOCH) * 86400 * 1e7.to_i
76
87
  high, low = bignum.divmod 1 << 32
77
- [low, high].pack 'L2'
88
+ [low, high].pack 'V2'
78
89
  end
79
90
  end
80
91
 
@@ -85,7 +96,7 @@ module Ole # :nodoc:
85
96
  # helper method for creating a Guid from that readable form (#format).
86
97
  class Clsid < String
87
98
  SIZE = 16
88
- UNPACK = 'L S S CC C6'
99
+ PACK = 'V v v CC C6'
89
100
 
90
101
  def self.load str
91
102
  new str.to_s
@@ -103,14 +114,14 @@ module Ole # :nodoc:
103
114
  # this is pretty ugly
104
115
  vals[3] = ('%04x' % vals[3]).scan(/../).map(&:hex)
105
116
  vals[4] = ('%012x' % vals[4]).scan(/../).map(&:hex)
106
- guid = new vals.flatten.pack(UNPACK)
117
+ guid = new vals.flatten.pack(PACK)
107
118
  return guid unless guid.delete('{}') == str.downcase.delete('{}')
108
119
  end
109
120
  raise ArgumentError, 'invalid guid - %p' % str
110
121
  end
111
122
 
112
123
  def format
113
- "%08x-%04x-%04x-%02x%02x-#{'%02x' * 6}" % unpack(UNPACK)
124
+ "%08x-%04x-%04x-%02x%02x-#{'%02x' * 6}" % unpack(PACK)
114
125
  end
115
126
 
116
127
  def inspect
Binary file
@@ -49,7 +49,7 @@ end
49
49
 
50
50
  class OleFsNonmutatingTest < Test::Unit::TestCase
51
51
  def setup
52
- @ole = Ole::Storage.open TEST_DIR + '/oleWithDirs.ole'
52
+ @ole = Ole::Storage.open TEST_DIR + '/oleWithDirs.ole', 'rb'
53
53
  end
54
54
 
55
55
  def teardown
@@ -502,7 +502,7 @@ end
502
502
  class OleFsFileStatTest < Test::Unit::TestCase
503
503
 
504
504
  def setup
505
- @ole = Ole::Storage.open TEST_DIR + '/oleWithDirs.ole'
505
+ @ole = Ole::Storage.open TEST_DIR + '/oleWithDirs.ole', 'rb'
506
506
  end
507
507
 
508
508
  def teardown
@@ -569,7 +569,7 @@ class OleFsFileMutatingTest < Test::Unit::TestCase
569
569
  def setup
570
570
  # we use an in memory copy of the file instead of the original
571
571
  # file based.
572
- @io = StringIO.new File.read(TEST_DIR + '/oleWithDirs.ole')
572
+ @io = StringIO.new open(TEST_DIR + '/oleWithDirs.ole', 'rb', &:read)
573
573
  end
574
574
 
575
575
  def teardown
@@ -660,12 +660,10 @@ class OleFsFileMutatingTest < Test::Unit::TestCase
660
660
  end
661
661
 
662
662
  class ZipFsDirectoryTest < Test::Unit::TestCase
663
- TEST_ZIP = "zipWithDirs_copy.zip"
664
-
665
663
  def setup
666
664
  # we use an in memory copy of the file instead of the original
667
665
  # file based.
668
- @io = StringIO.new File.read(TEST_DIR + '/oleWithDirs.ole')
666
+ @io = StringIO.new open(TEST_DIR + '/oleWithDirs.ole', 'rb', &:read)
669
667
  end
670
668
 
671
669
  def teardown
@@ -10,6 +10,8 @@ require 'tempfile'
10
10
  class TestWriteMbat < Test::Unit::TestCase
11
11
  def test_write_mbat
12
12
  Tempfile.open 'myolefile' do |temp|
13
+ temp.binmode
14
+
13
15
  # this used to raise an error at flush time, due to failure to write the mbat
14
16
  Ole::Storage.open temp do |ole|
15
17
  # create a 10mb file
@@ -3,13 +3,14 @@
3
3
  $: << File.dirname(__FILE__) + '/../lib'
4
4
 
5
5
  require 'test/unit'
6
+ require 'ole/storage'
6
7
  require 'ole/property_set'
7
8
 
8
9
  class TestTypes < Test::Unit::TestCase
9
10
  include Ole::Types
10
11
 
11
12
  def setup
12
- @io = open File.dirname(__FILE__) + '/test_SummaryInformation'
13
+ @io = open File.dirname(__FILE__) + '/test_SummaryInformation', 'rb'
13
14
  end
14
15
 
15
16
  def teardown
@@ -18,13 +19,22 @@ class TestTypes < Test::Unit::TestCase
18
19
 
19
20
  def test_property_set
20
21
  propset = PropertySet.new @io
22
+ assert_equal :mac, propset.os
21
23
  assert_equal 1, propset.sections.length
22
24
  section = propset.sections.first
23
25
  assert_equal 14, section.length
24
26
  assert_equal 'f29f85e0-4ff9-1068-ab91-08002b27b3d9', section.guid.format
25
27
  assert_equal PropertySet::FMTID_SummaryInformation, section.guid
26
- # i expect this null byte should have be stripped. need to fix the encoding functions.
27
- assert_equal "Charles Lowe\000", section.properties.assoc(4).last
28
+ assert_equal 'Charles Lowe', section.properties.assoc(4).last
29
+ # new named support
30
+ assert_equal 'Charles Lowe', section.doc_author
31
+ end
32
+
33
+ def test_ole_storage_integration
34
+ Ole::Storage.open File.dirname(__FILE__) + '/test.doc', 'rb' do |ole|
35
+ assert_equal 'Charles Lowe', ole.summary_info.doc_author
36
+ assert_equal 'Title', ole.summary_info.doc_title
37
+ end
28
38
  end
29
39
  end
30
40
 
@@ -7,6 +7,8 @@ require 'ole/storage'
7
7
  require 'digest/sha1'
8
8
  require 'stringio'
9
9
  require 'tempfile'
10
+ require 'zlib'
11
+ require 'base64'
10
12
 
11
13
  #
12
14
  # = TODO
@@ -60,12 +62,51 @@ class TestStorageRead < Test::Unit::TestCase
60
62
  end
61
63
 
62
64
  def test_read
65
+ # this data should probably be put elsewhere. not asserting
66
+ # using hashes anymore, cause they were different on the mac.
67
+ data = <<-end
68
+ eJxjZGBgYkADAABKAAQ=
69
+
70
+ eJxjZPj3n5mLgeE/EDBwMjGAwAEwyeAmAyR8M5OL8ovz00oUwvOLUhTM9Ax0
71
+ XfKzS3NT80oYuEDywSBxl/xkBgEgD8TWA3LA8npmYGMAKWQZqA==
72
+
73
+ eJztVs9rE0EU/mZ32m5smyZtUlKQunhIezAV6knwYGoRxRLQBG89zCabdiE7
74
+ K9kJpt7Es1DwLxCsP+jJqycv/S/8I9SrmPgmuy0pK1ilNZd8MPt233zz7dud
75
+ H+99OXBR+pziILgYgglkqaUvIYFs0pWEBSyzIfsHLKeA3Fl0Y6wTX4d2K7bH
76
+ uEvP6i90zhuf6P21fxpp0C9nOMOvGuMcUQ1811ZuqOjSVWuzszm8eb52cFR+
77
+ K/k7yd9L/kHyV6OO8gJBezwT7/UVaj/xY9QRjXHhMDoM5rapZ39o/ntRZ2+0
78
+ sY3xv0C5xkhT1rXo7gHmBr5VWg7f+gbZqU23KTotSqaT5L+Ba2waDmjR1AsQ
79
+ qZnf6BVRvv29/5rsUtkJhXpWqiohG6LdCOu7ba+pRFud5veuMBisiKl7rmh4
80
+ ckfn8jnkv2KxC4tNYpujfhk2NjKaZyNVo0PadoLGni4sMshDM3XlcD3D2DzL
81
+ gW95oaJcmj3Rv6r174gnyguk1p9HvqtHpdmE/pTHDIUBb50VMHFfNlwS5Fig
82
+ /ihKrcQH+wPoExCflMZJjWRSxZFf3Cd+zfPd0K64T+1HgS8kZshroLrnO0EL
83
+ 00VNKbc90cKqpi9UPN/phBHXrgQ37a2EwpIelI6JVSFD4kQSGxQVs14WgCMK
84
+ ZXcQ7WHtYxPWw5JupyuJqLLgeLHPEt5jz4r5CxXWcbY=
85
+
86
+ eJzt0z1oU2EcRvE3rR+tWtGtOBQ3hS4tODgWKnQRlM5dHAoZCuIHaLcsBaGT
87
+ hIBksQmlQ1wCTgF3Q+Z0cHN1lZBQQhL/N60fUEEKh5bK+cHleXlJw+2hHY5S
88
+ yqXjsruvW++/HzzK3/jwdirN3/n4ZSHu2vspXY+9Gc/ro88txN107P3YK7EP
89
+ Yq/GPo6diV2LvRabj52KfRl7IbYQeyn2Xezl2N3Yi7H12MnYT7ETsc3Yley+
90
+ ndIoZN9xN55n8eyM32F2/M6F9vHfYyTa3lm/wH/Ipjyb8mzKsynPpjyb8mzK
91
+ synPpjyb8mzKsynPpjyb8mzKsynPpjyb8mzKsynPpjyb8mzKsynPpjyb8mzK
92
+ synPpjyb8mzKsynPpjyb8mzKsynPpjyb8mzKsynPpjyb8mzKsynPpjyb8mzK
93
+ synPpjyb8mzKsynPpjyb8mzKsynPpjyb8mzKsynPpjyb8mzKsynPpjyb8mzK
94
+ synPpjyb8mzKsynPpjyb8mzKsynPpjyb8mzKsynPpjyb8mzKsynPpjyb8mzK
95
+ synPpjyb8mzKsynPpjyb8mzKsynPpjyb8mzKsynPpjyb8mzKsynPpjyb8mzK
96
+ synPpjyb8mzKsynPpjyb8mzKsynPpjyb8mzKsynPpjyb8mzKsynPpjyb8mzK
97
+ synPpjyb8mzKsynPpjyb8mzKsynPpjyb8mzKsynPpjyb8mzKsynPprx/NO33
98
+ +7VaLQ6VSqVUKpXL5cFg0Gq1Go1GtVptNpvFYrFer8dNp9M5lRc+B078dzoc
99
+ Dnu93uGh2+3G+deNDvm/z7Mpz6Y8m/JsyrMpz6Y8m/JsyrMpz6a8vYmU0rdB
100
+ SnOx2XkxnqX02/j8ZnXzb+fCrcr09r3Puexnc0efz84z8SznnzzfWH9x++HT
101
+ V+s/7//8zEnOPwDhN6kw
102
+ end
103
+ expect = data.split(/\n\s*\n/).map { |chunk| Zlib::Inflate.inflate Base64.decode64(chunk) }
104
+
63
105
  # test the ole storage type
64
106
  type = 'Microsoft Word 6.0-Dokument'
65
107
  assert_equal type, (@ole.root/"\001CompObj").read[/^.{32}([^\x00]+)/m, 1]
66
108
  # i was actually not loading data correctly before, so carefully check everything here
67
- hashes = [-482597081, 285782478, 134862598, -863988921]
68
- assert_equal hashes, @ole.root.children.map { |child| child.read.hash }
109
+ assert_equal expect, @ole.root.children.map { |child| child.read }
69
110
  end
70
111
  end
71
112
 
@@ -86,7 +127,7 @@ class TestStorageWrite < Test::Unit::TestCase
86
127
  # of checks involving writes that resize their file bigger/smaller, that resize
87
128
  # the bats to more blocks, that resizes the sb_blocks, that has migration etc.
88
129
  def test_write_hash
89
- io = StringIO.open File.read("#{TEST_DIR}/test_word_6.doc")
130
+ io = StringIO.open open("#{TEST_DIR}/test_word_6.doc", 'rb', &:read)
90
131
  assert_equal '9974e354def8471225f548f82b8d81c701221af7', sha1(io.string)
91
132
  Ole::Storage.open(io, :update_timestamps => false) { }
92
133
  # hash changed. used to be efa8cfaf833b30b1d1d9381771ddaafdfc95305c
@@ -99,7 +140,7 @@ class TestStorageWrite < Test::Unit::TestCase
99
140
  end
100
141
 
101
142
  def test_plain_repack
102
- io = StringIO.open File.read("#{TEST_DIR}/test_word_6.doc")
143
+ io = StringIO.open open("#{TEST_DIR}/test_word_6.doc", 'rb', &:read)
103
144
  assert_equal '9974e354def8471225f548f82b8d81c701221af7', sha1(io.string)
104
145
  Ole::Storage.open io, :update_timestamps => false, &:repack
105
146
  # note equivalence to the above flush, repack, flush
@@ -11,7 +11,7 @@ class TestSupport < Test::Unit::TestCase
11
11
  def test_file
12
12
  assert_equal 4096, open("#{TEST_DIR}/oleWithDirs.ole") { |f| f.size }
13
13
  # point is to have same interface as:
14
- assert_equal 4096, StringIO.open(File.read("#{TEST_DIR}/oleWithDirs.ole")).size
14
+ assert_equal 4096, StringIO.open(open("#{TEST_DIR}/oleWithDirs.ole", 'rb', &:read)).size
15
15
  end
16
16
 
17
17
  def test_enumerable
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
3
3
  specification_version: 1
4
4
  name: ruby-ole
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.2.3
7
- date: 2007-12-28 00:00:00 +11:00
6
+ version: 1.2.4
7
+ date: 2008-01-10 00:00:00 +11:00
8
8
  summary: Ruby OLE library.
9
9
  require_paths:
10
10
  - lib
@@ -31,6 +31,7 @@ authors:
31
31
  files:
32
32
  - Rakefile
33
33
  - ChangeLog
34
+ - data/propids.yaml
34
35
  - bin/oletool
35
36
  - lib/ole/ranges_io.rb
36
37
  - lib/ole/property_set.rb
@@ -48,6 +49,7 @@ files:
48
49
  - test/test_filesystem.rb
49
50
  - test/test_word_6.doc
50
51
  - test/test_word_95.doc
52
+ - test/test.doc
51
53
  - test/test_word_97.doc
52
54
  - test/oleWithDirs.ole
53
55
  - test/test_SummaryInformation