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)