Skip to content

Commit

Permalink
Account unused object ids
Browse files Browse the repository at this point in the history
  • Loading branch information
tomascco committed Oct 22, 2023
1 parent 03bb107 commit 04221f3
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 4 deletions.
20 changes: 18 additions & 2 deletions lib/rubrik/document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,25 @@ class Document
sig {returns(PDF::Reader::ObjectHash)}
attr_accessor :objects

sig {returns(Integer)}
attr_accessor :first_free_object_id

sig {returns(T::Array[{id: PDF::Reader::Reference, value: T.untyped}])}
attr_accessor :modified_objects

sig {returns(Integer)}
attr_accessor :last_object_id

private :io=, :objects=, :modified_objects=, :last_object_id=
private :io=, :objects=, :first_free_object_id=, :modified_objects=, :last_object_id=

sig {params(input: T.any(File, Tempfile, StringIO)).void}
def initialize(input)
self.io = input
self.objects = PDF::Reader::ObjectHash.new(input)
self.last_object_id = objects.size

self.last_object_id = objects.trailer[:Size] - 1
self.first_free_object_id = find_first_free_object_id

self.modified_objects = []

fetch_or_create_interactive_form!
Expand Down Expand Up @@ -87,6 +93,16 @@ def interactive_form
T.must(modified_objects.first).fetch(:value)
end

sig{returns(Integer)}
def find_first_free_object_id
return 0 if last_object_id == objects.size

xref = objects.send(:xref).instance_variable_get(:@xref)
missing_ids = (1..last_object_id).to_a - xref.keys

T.must(missing_ids.min)
end

sig {void}
def fetch_or_create_interactive_form!
root_ref = objects.trailer[:Root]
Expand Down
2 changes: 1 addition & 1 deletion lib/rubrik/document/increment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def call(document, io:)
io << "#{starting_id} #{length}\n"

if starting_id.zero?
io << "0000000000 65535 f \n"
io << "#{format("%010d", document.first_free_object_id)} 65535 f \n"
subsection.shift
end

Expand Down
2 changes: 1 addition & 1 deletion test/rubrik/document_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def test_initialize_document_without_interactive_form
# Assert
assert_equal(input, document.send(:io))
# FACT: the interactive form was created
assert_equal(5, document.last_object_id)
assert_equal(6, document.last_object_id)
assert_kind_of(PDF::Reader::ObjectHash, document.objects)

acro_form = document.modified_objects.find { |obj| obj.dig(:value, :Type) == :Catalog }
Expand Down
Binary file modified test/support/without_interactive_form.expected.pdf
Binary file not shown.
Binary file modified test/support/without_interactive_form.pdf
Binary file not shown.

0 comments on commit 04221f3

Please sign in to comment.