lib/hexapdf/parser.rb in hexapdf-0.13.0 vs lib/hexapdf/parser.rb in hexapdf-0.14.0
- old
+ new
@@ -265,10 +265,31 @@
trailer = @tokenizer.next_object
unless trailer.kind_of?(Hash)
raise_malformed("Trailer is #{trailer.class} instead of dictionary ", pos: @tokenizer.pos)
end
+ unless trailer[:Prev] || xref.max_oid == 0 || xref.entry?(0)
+ first_entry = xref[xref.oids[0]]
+ test_entry = xref[xref.oids[-1]]
+ @tokenizer.pos = test_entry.pos + @header_offset
+ test_oid = @tokenizer.next_token
+ first_oid = first_entry.oid
+
+ force_failure = !first_entry.free? || first_entry.gen != 65535 ||
+ !test_oid.kind_of?(Integer) || xref.oids[-1] - test_oid != first_oid
+ maybe_raise("Main cross-reference section has invalid numbering",
+ pos: offset + @header_offset, force: force_failure)
+
+ new_xref = XRefSection.new
+ xref.oids.each do |oid|
+ entry = xref[oid]
+ entry.oid -= first_oid
+ new_xref.send(:[]=, entry.oid, entry.gen, entry)
+ end
+ xref = new_xref
+ end
+
[xref, trailer]
end
# Returns the offset of the main cross-reference section/stream.
#
@@ -357,11 +378,12 @@
@document.config['parser.on_correctable_error'].call(@document, msg, @tokenizer.pos)
xref = XRefSection.new
@tokenizer.pos = 0
while true
+ @tokenizer.skip_whitespace
pos = @tokenizer.pos
- @tokenizer.scan_until(/(\n|\r\n?)+|\z/)
+ @tokenizer.scan_until(/(\n|\r\n?)+/)
next_new_line_pos = @tokenizer.pos
@tokenizer.pos = pos
token = @tokenizer.next_token rescue nil
if token.kind_of?(Integer)