diff --git a/lib/cfpropertylist/rbBinaryCFPropertyList.rb b/lib/cfpropertylist/rbBinaryCFPropertyList.rb index da84b63..80b9c5b 100644 --- a/lib/cfpropertylist/rbBinaryCFPropertyList.rb +++ b/lib/cfpropertylist/rbBinaryCFPropertyList.rb @@ -31,11 +31,12 @@ def load(opts) buff = fd.read(32) offset_size, object_ref_size, number_of_objects, top_object, table_offset = buff.unpack "x6CCx4Nx4Nx4N" + raise CFFormatError.new("#{file}: Invalid offset_size #{offset_size}") unless [1, 2, 3, 4].include?(offset_size) # after that, get the offset table fd.seek(table_offset, IO::SEEK_SET) coded_offset_table = fd.read(number_of_objects * offset_size) - raise CFFormatError.new("#{file}: Format error!") unless coded_offset_table.bytesize == number_of_objects * offset_size + raise CFFormatError.new("#{file}: Format error!") unless coded_offset_table && coded_offset_table.bytesize == number_of_objects * offset_size @count_objects = number_of_objects diff --git a/test/test_binary.rb b/test/test_binary.rb index 927c3c4..953ae00 100644 --- a/test/test_binary.rb +++ b/test/test_binary.rb @@ -39,4 +39,28 @@ def test_bytes_needed CFPropertyList::Binary.bytes_needed(2**64) end end + + def test_invalid_offset_size + header = "bplist00" + object = "\x08" + offset_table = "\x00" + trailer = [0,0,0,0,0,0, 5, 1, 0,0,0,0, 0,0,0,1, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,9].pack("C*") + + plist = CFPropertyList::List.new + assert_raises CFFormatError do + plist.load_str(header + object + offset_table + trailer, CFPropertyList::List::FORMAT_BINARY) + end + end + + def test_offset_table_overflow + header = "bplist00" + object = "\x08" + offset_table = "\x00" * 10 + trailer = [0,0,0,0,0,0, 1, 1, 0,0,0,0, 0,0,0,20, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,1,0].pack("C*") + + plist = CFPropertyList::List.new + assert_raises CFFormatError do + plist.load_str(header + object + offset_table + trailer, CFPropertyList::List::FORMAT_BINARY) + end + end end