From 0a66252a192ab1833371e2758ed2933f0ec18b18 Mon Sep 17 00:00:00 2001 From: Matthias Valvekens Date: Thu, 2 Nov 2023 07:45:01 +0100 Subject: [PATCH] Change ByteRange placeholder to allow bigger input Fixes #336 --- pyhanko/sign/signers/pdf_byterange.py | 21 ++++++++++++++------- pyhanko_tests/test_signing.py | 19 +++++++++++++++++++ 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/pyhanko/sign/signers/pdf_byterange.py b/pyhanko/sign/signers/pdf_byterange.py index eb362037..7f793153 100644 --- a/pyhanko/sign/signers/pdf_byterange.py +++ b/pyhanko/sign/signers/pdf_byterange.py @@ -34,6 +34,9 @@ ] +BYTE_RANGE_ARR_PLACE_HOLDER_LENGTH = 60 + + class SigByteRangeObject(generic.PdfObject): """ Internal class to handle the ``/ByteRange`` arrays themselves. @@ -70,13 +73,17 @@ def fill_offsets(self, stream, sig_start, sig_end, eof): def write_to_stream(self, stream, handler=None, container_ref=None): if self._range_object_offset is None: self._range_object_offset = stream.tell() - string_repr = "[ %08d %08d %08d %08d ]" % ( - 0, - self.first_region_len, - self.second_region_offset, - self.second_region_len, - ) - stream.write(string_repr.encode('ascii')) + stream.write(b"[]") + stream.write(b" " * BYTE_RANGE_ARR_PLACE_HOLDER_LENGTH) + else: + string_repr = b"[%d %d %d %d]" % ( + 0, + self.first_region_len, + self.second_region_offset, + self.second_region_len, + ) + assert len(string_repr) <= BYTE_RANGE_ARR_PLACE_HOLDER_LENGTH + 2 + stream.write(string_repr) class DERPlaceholder(generic.PdfObject): diff --git a/pyhanko_tests/test_signing.py b/pyhanko_tests/test_signing.py index dfc4d5da..7c493f50 100644 --- a/pyhanko_tests/test_signing.py +++ b/pyhanko_tests/test_signing.py @@ -154,6 +154,25 @@ def test_simple_sign_fresh_doc(): val_untrusted(emb) +def test_simple_sign_120mb_file(): + # put this in a function to avoid putting multiple copies + # of a huge buffer in locals + def _gen_signed(): + w = IncrementalPdfFileWriter(BytesIO(MINIMAL)) + w.root['/YugeObject'] = w.add_object( + generic.StreamObject(stream_data=bytes(120 * 1024 * 1024)) + ) + w.update_root() + + meta = signers.PdfSignatureMetadata(field_name='Sig1') + return signers.sign_pdf(w, meta, signer=SELF_SIGN) + + r = PdfFileReader(_gen_signed()) + emb = r.embedded_signatures[0] + assert emb.field_name == 'Sig1' + val_untrusted(emb) + + def test_append_sigfield_tu_on_signing(): buf = BytesIO(MINIMAL) w = IncrementalPdfFileWriter(buf)