Skip to content

Commit

Permalink
Refactor code based on tests
Browse files Browse the repository at this point in the history
  • Loading branch information
tomascco committed Oct 20, 2023
1 parent 42fc30a commit 483e9b7
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 36 deletions.
1 change: 0 additions & 1 deletion lib/rubrik.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

require "sorbet-runtime"
require "pdf-reader"
require "irb"

module Rubrik
class Error < StandardError; end
Expand Down
29 changes: 8 additions & 21 deletions lib/rubrik/document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,18 @@ class Document
SIGNATURE_SIZE = 8_192

sig {returns(T.any(File, Tempfile, StringIO))}
attr_reader :io
attr_accessor :io

sig {returns(PDF::Reader::ObjectHash)}
attr_reader :objects
attr_accessor :objects

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

sig {returns(PDF::Reader::Reference)}
attr_reader :interactive_form_id
attr_accessor :modified_objects

sig {returns(Integer)}
attr_reader :last_object_id
attr_accessor :last_object_id

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

sig {params(input: T.any(File, Tempfile, StringIO)).void}
def initialize(input)
Expand Down Expand Up @@ -63,7 +62,7 @@ def add_signature_field
V: signature_value_id,
Type: :Annot,
Subtype: :Widget,
Rect: [20, 20, 120, 120],
Rect: [0, 0, 0, 0],
F: 4,
P: first_page_reference
}
Expand All @@ -87,7 +86,7 @@ def interactive_form
sig {void}
def fetch_or_create_interactive_form!
root_ref = objects.trailer[:Root]
root = T.let(objects.fetch(root_ref), Hash)
root = T.let(objects.fetch(root_ref), T::Hash[Symbol, T.untyped])

if root.key?(:AcroForm)
form_id = root[:AcroForm]
Expand All @@ -111,17 +110,5 @@ def fetch_or_create_interactive_form!
def assign_new_object_id!
PDF::Reader::Reference.new(self.last_object_id += 1, 0)
end

sig {params(io: T.any(File, Tempfile, StringIO)).returns(T.any(File, Tempfile, StringIO))}
attr_writer :io

sig {params(objects: PDF::Reader::ObjectHash).returns(PDF::Reader::ObjectHash)}
attr_writer :objects

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

sig {params(last_object_id: Integer).returns(Integer)}
attr_writer :last_object_id
end
end
25 changes: 14 additions & 11 deletions lib/rubrik/document/increment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ module Increment
extend T::Sig
extend self

sig {params(document: Rubrik::Document, io: T.any(File, Tempfile, StringIO)).returns(T.any(File, Tempfile, StringIO))}
sig {params(document: Rubrik::Document, io: T.any(File, Tempfile, StringIO)).void}
def call(document, io:)
document.io.rewind
IO.copy_stream(T.unsafe(document.io), T.unsafe(io))
IO.copy_stream(document.io, io)

io << "\n"
new_xref = Array.new

new_xref = T.let([], T::Array[T::Hash[Symbol, Integer]])
new_xref << {id: 0}

document.modified_objects.each do |object|
integer_id = T.let(object[:id].to_i, Integer)
Expand All @@ -31,18 +33,22 @@ def call(document, io:)
new_xref_pos = io.pos

new_xref_subsections = new_xref
.sort_by { _1[:id] }
.chunk_while { _1[:id] + 1 == _2[:id] }
.sort_by { |entry| entry.fetch(:id) }
.chunk_while { _1.fetch(:id) + 1 == _2[:id] }

io << "xref\n"
io << "0 1\n"
io << "0000000000 65535 f\n"

new_xref_subsections.each do |subsection|
starting_id = subsection.first[:id]
starting_id = T.must(subsection.first).fetch(:id)
length = subsection.length

io << "#{starting_id} #{length}\n"

if starting_id.zero?
io << "0000000000 65535 f\n"
subsection.shift
end

subsection.each { |entry| io << "#{format("%010d", entry[:offset])} 00000 n\n" }
end

Expand All @@ -51,9 +57,6 @@ def call(document, io:)
io << "startxref\n"
io << "#{new_xref_pos.to_s}\n"
io << "%%EOF\n"

io.rewind
io
end

private
Expand Down
5 changes: 2 additions & 3 deletions lib/rubrik/fill_signature.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ module FillSignature
private_key: OpenSSL::PKey::RSA,
public_key: OpenSSL::X509::Certificate,
certificate_chain: T::Array[OpenSSL::X509::Certificate])
.returns(T.any(File, StringIO, Tempfile))}
.void}

FIRST_OFFSET = 0

Expand All @@ -29,8 +29,7 @@ def call(io, signature_value_ref:, private_key:, public_key:, certificate_chain:
io.gets("<")

first_length = io.pos - 1
# we need to double the SIGNATURE_SIZE because the hex encoding double the data size
# we also need to sum +2 to account for "<" and ">" of the hex string
# We need to sum +2 to account for "<" and ">" of the hex string
second_offset = first_length + Document::SIGNATURE_SIZE + 2
second_length = io.size - second_offset

Expand Down
3 changes: 3 additions & 0 deletions lib/rubrik/sign.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ module Sign
certificate_chain: T::Array[OpenSSL::X509::Certificate])
.void}
def self.call(input, output, private_key:, public_key:, certificate_chain: [])
input.binmode
output.reopen(T.unsafe(output), "wb+") if !output.is_a?(StringIO)

document = Rubrik::Document.new(input)

document.add_signature_field
Expand Down

0 comments on commit 483e9b7

Please sign in to comment.