Skip Menu |

This queue is for tickets about the PDF-Tiny CPAN distribution.

Report information
The Basics
Id: 131989
Status: new
Priority: 0/
Queue: PDF-Tiny

People
Owner: Nobody in particular
Requestors: BULKDD [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: 0.09
Fixed in: (no value)



Subject: [PATCH] stop changing the permanent File/Doc ID between saves
PDF official spec, prior to this patch all PDF files emitted that were sucked in from disk were outputted with new permanent doc IDs against the standard ---------------------------- File identifiers are defined by the optional ID entry in a PDF file’s trailer dictionary (see Section 3.4.4, “File Trailer”; see also implementation note 162 in Appendix H). The value of this entry is an array of two byte strings. The first byte string is a permanent identifier based on the contents of the file at the time it was originally created and does not change when the file is incrementally updated. The second byte string is a changing identifier based on the file’s contents at the time it was last updated. ----------------------------
Subject: 0001-stop-changing-the-permanent-File-Doc-ID-between-save.patch
From b98fc4544f3cc5b51c084a9a956c78f53c3bdcc5 Mon Sep 17 00:00:00 2001 From: bulk88 <bulk88@hotmail.com> Date: Thu, 27 Feb 2020 04:10:56 -0500 Subject: [PATCH] stop changing the permanent File/Doc ID between saves -it is never to be changed once it is created but the unique per save ID must be modified between saves -2nd ID string in append() is irrelavent and unless it is a virgin document will never equal first ID --- lib/PDF/Tiny.pm | 9 ++++-- t/doc_half_id.pdf | 46 +++++++++++++++++++++++++++ t/doc_id.pdf | 55 ++++++++++++++++++++++++++++++++ t/doc_no_id.pdf | 45 +++++++++++++++++++++++++++ t/id.t | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 245 insertions(+), 3 deletions(-) create mode 100644 t/doc_half_id.pdf create mode 100644 t/doc_id.pdf create mode 100644 t/doc_no_id.pdf create mode 100644 t/id.t diff --git a/lib/PDF/Tiny.pm b/lib/PDF/Tiny.pm index 04e63ea..be6bcdc 100644 --- a/lib/PDF/Tiny.pm +++ b/lib/PDF/Tiny.pm @@ -320,8 +320,7 @@ sub append { # append to the file before we reach the trailer. my $id_array = $self->vivify_obj('array',"/ID"); if (@{$$id_array[1]} == 2 - and $self->vivify_obj('str', $id_array, 0)->[1] ne $self->[id] - || $self->vivify_obj('str', $id_array, 1)->[1] ne $self->[id]) { + and $self->vivify_obj('str', $id_array, 0)->[1] ne $self->[id]) { # User has assigned his own id. Leave it alone. } else { @@ -401,7 +400,11 @@ sub print { # User has assigned his own id. Leave it alone. } else { - @{$$id_array[1]} = (['str', time."" ^ "".rand ^ "".(0+$self)])x2; + $self->vivify_obj('str', $id_array, 0)->[1] + ||= time."" ^ "".rand ^ "".(0+$self); + $self->vivify_obj('str', $id_array, 1)->[1] + ^= time."" ^ "".rand ^ "".(0+$self); + @{$$id_array[1]} = @{$$id_array[1]}[0,1]; } # We assume that if this points to a cross-reference stream’s dictionary diff --git a/t/doc_half_id.pdf b/t/doc_half_id.pdf new file mode 100644 index 0000000..84200c4 --- /dev/null +++ b/t/doc_half_id.pdf @@ -0,0 +1,46 @@ +%PDF-1.6 +%%μῦ + +1 0 obj +<< + /Count 1 + /Type /Pages + /Kids [ 3 0 R ] +>> +endobj + +2 0 obj +<< + /Pages 1 0 R + /Type /Catalog +>> +endobj + +3 0 obj +<< + /CropBox [ 0 0 456 667.2 ] + /Parent 1 0 R + /Rotate 0 + /MediaBox [ 0 0 456 667.2 ] + /Resources << + >> + /Type /Page +>> +endobj + +xref +0 4 +0000000000 65536 f +0000000018 00000 n +0000000084 00000 n +0000000138 00000 n + +trailer +<< + /Size 4 + /Root 2 0 R + /ID [ <62EA1E6966534A17A62CF38355B15448> ] +>> +startxref +282 +%%EOF diff --git a/t/doc_id.pdf b/t/doc_id.pdf new file mode 100644 index 0000000..9e7dac4 --- /dev/null +++ b/t/doc_id.pdf @@ -0,0 +1,55 @@ +%PDF-1.6 +%%μῦ + +1 0 obj +<< + /Count 1 + /Type /Pages + /Kids [ 4 0 R ] +>> +endobj + +2 0 obj +<< + /CreationDate (D:20200227031823-05'00') + /ModDate (D:20200227031823-05'00') +>> +endobj + +3 0 obj +<< + /Pages 1 0 R + /Type /Catalog +>> +endobj + +4 0 obj +<< + /CropBox [ 0 0 456 667.2 ] + /Parent 1 0 R + /Rotate 0 + /MediaBox [ 0 0 456 667.2 ] + /Resources << + >> + /Type /Page +>> +endobj + +xref +0 5 +0000000000 65536 f +0000000018 00000 n +0000000084 00000 n +0000000185 00000 n +0000000239 00000 n + +trailer +<< + /Size 5 + /Info 2 0 R + /Root 3 0 R + /ID [ <62EA1E6966534A17A62CF38355B15448> <256332B5E11F45468CC156AD8DFAB4B2> ] +>> +startxref +383 +%%EOF diff --git a/t/doc_no_id.pdf b/t/doc_no_id.pdf new file mode 100644 index 0000000..5582334 --- /dev/null +++ b/t/doc_no_id.pdf @@ -0,0 +1,45 @@ +%PDF-1.6 +%%μῦ + +1 0 obj +<< + /Count 1 + /Type /Pages + /Kids [ 3 0 R ] +>> +endobj + +2 0 obj +<< + /Pages 1 0 R + /Type /Catalog +>> +endobj + +3 0 obj +<< + /CropBox [ 0 0 456 667.2 ] + /Parent 1 0 R + /Rotate 0 + /MediaBox [ 0 0 456 667.2 ] + /Resources << + >> + /Type /Page +>> +endobj + +xref +0 4 +0000000000 65536 f +0000000018 00000 n +0000000084 00000 n +0000000138 00000 n + +trailer +<< + /Size 4 + /Root 2 0 R +>> +startxref +282 +%%EOF diff --git a/t/id.t b/t/id.t new file mode 100644 index 0000000..cfab260 --- /dev/null +++ b/t/id.t @@ -0,0 +1,93 @@ +#!/usr/bin/perl +BEGIN {$^W=0} +use strict; + +use lib 't'; + +use PDF::Tiny; +use File::Copy; + +use tests 12; # print +my $pdf = new PDF'Tiny "t/doc_id.pdf"; +my $ID = $pdf->get_obj('/ID'); +#first string in array +my $orig_perm_ID = $ID->[1]->[0]->[1]; +my $orig_modified_ID = $ID->[1]->[1]->[1]; +ok($orig_perm_ID, "permanent doc ID found"); +my $fn = tempfile; +$pdf->print(filename=>$fn); +undef($pdf); +$pdf = new PDF'Tiny $fn; +$ID = $pdf->get_obj('/ID'); +#first string in array is perm ID, 2nd string is unstable per-save CRC style ID +my $new_perm_ID = $ID->[1]->[0]->[1]; +my $new_modified_ID = $ID->[1]->[1]->[1]; +is($orig_perm_ID, $new_perm_ID, + "permanent doc ID must not change on file input to output"); +isnt($orig_modified_ID, $new_modified_ID, + "modified doc ID must change on file input to output"); + + +$pdf = new PDF'Tiny "t/doc_half_id.pdf"; +$ID = $pdf->get_obj('/ID'); +#first string in array +$orig_perm_ID = $ID->[1]->[0]->[1]; +$orig_modified_ID = exists $ID->[1]->[1] ? $ID->[1]->[1]->[1] : undef; #avoid vivify +$fn = tempfile; +$pdf->print(filename=>$fn); +undef($pdf); +$pdf = new PDF'Tiny $fn; +$ID = $pdf->get_obj('/ID'); +#first string in array is perm ID, 2nd string is unstable per-save CRC style ID +$new_perm_ID = $ID->[1]->[0]->[1]; +$new_modified_ID = $ID->[1]->[1]->[1]; +is($orig_perm_ID, $new_perm_ID, + "permanent doc ID must not change on file input to output"); +isnt($orig_modified_ID, $new_modified_ID, + "modified doc ID must change on file input to output"); + + +$pdf = new PDF'Tiny "t/doc_no_id.pdf"; +$ID = $pdf->get_obj('/ID'); +#first string in array +$orig_perm_ID = $ID->[1]->[0]->[1]; +is($orig_perm_ID, undef, "pdf with no doc ID has no ID"); +$orig_modified_ID = $ID->[1]->[1]->[1]; +is($orig_modified_ID, undef, "pdf with no doc ID has no ID"); +$fn = tempfile; +$pdf->print(filename=>$fn); +undef($pdf); +$pdf = new PDF'Tiny $fn; +$ID = $pdf->get_obj('/ID'); +#first string in array is perm ID, 2nd string is unstable per-save CRC style ID +my $new_perm_ID = $ID->[1]->[0]->[1]; +my $new_modified_ID = $ID->[1]->[1]->[1]; +isnt($orig_perm_ID, $new_perm_ID, + "permanent doc ID must not change on file input to output"); +isnt($orig_modified_ID, $new_modified_ID, + "modified doc ID must change on file input to output"); + + +$pdf = new PDF'Tiny "t/doc_id.pdf"; +$ID = $pdf->get_obj('/ID'); +#first string in array +$orig_perm_ID = $ID->[1]->[0]->[1]; +$orig_modified_ID = $ID->[1]->[1]->[1]; +ok($orig_perm_ID, "permanent doc ID found"); +$fn = tempfile; +copy("t/doc_id.pdf", $fn) or die "Copy failed: $!"; +undef($pdf); +$pdf = new PDF'Tiny $fn; +my $Info = $pdf->get_obj('/Info'); +$Info->[1]->{FooDate} = ['str', 'fakedate']; +$pdf->modified('/Info'); +$pdf->append(); +$pdf = new PDF'Tiny $fn; +$ID = $pdf->get_obj('/ID'); +#first string in array is perm ID, 2nd string is unstable per-save CRC style ID +my $new_perm_ID = $ID->[1]->[0]->[1]; +my $new_modified_ID = $ID->[1]->[1]->[1]; +is($orig_perm_ID, $new_perm_ID, + "permanent doc ID must not change on file input to output"); +isnt($orig_modified_ID, $new_modified_ID, + "modified doc ID must change on file input to output"); -- 2.5.0.windows.1