From 1dc9c8ced829a8236678c1ee3fa207e04d58e233 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Thu, 23 Jul 2026 19:40:32 +1000 Subject: [PATCH] Add option to skip pdf byte normalization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ports the SkipPdfNormalization setting from Verify.PDFium (3fd22e9). Adds a SettingsTask/VerifySettings extension backed by a context key, so a caller whose producer already emits byte-deterministic documents can snapshot the bytes as produced. Normalizing those again copies the buffer, rescans it, and — when the XMP packet is canonicalized — rebuilds it and repairs the cross-reference table, all to change nothing. Default behaviour is unchanged: without the setting the bytes are normalized. SkipPdfNormalizationTests asserts the pairing rather than just that the setting round-trips: the skipped snapshot holds the producer's own bytes and the default one holds the neutralized bytes. A premise test pins that the sample is not already normalization-invariant, so the pair cannot both pass vacuously. --- src/Directory.Build.props | 2 +- ...otHoldsTheNeutralizedBytes#00.verified.png | Bin 0 -> 14647 bytes ...otHoldsTheNeutralizedBytes#01.verified.png | Bin 0 -> 9465 bytes ...pshotHoldsTheNeutralizedBytes.verified.pdf | Bin 0 -> 2715 bytes ...pshotHoldsTheProducerBytes#00.verified.png | Bin 0 -> 14647 bytes ...pshotHoldsTheProducerBytes#01.verified.png | Bin 0 -> 9465 bytes ...SnapshotHoldsTheProducerBytes.verified.pdf | Bin 0 -> 2715 bytes src/Tests/SkipPdfNormalizationTests.cs | 27 ++++++++++++++ ...Tests.SkipPdfNormalization#00.verified.png | Bin 0 -> 14647 bytes ...Tests.SkipPdfNormalization#01.verified.png | Bin 0 -> 9465 bytes .../Tests.SkipPdfNormalization.verified.pdf | Bin 0 -> 2715 bytes src/Tests/Tests.cs | 5 +++ src/Verify.ImageMagick/ImageMagickSettings.cs | 34 +++++++++++++++++- .../VerifyImageMagick_Pdf.cs | 14 ++++++-- 14 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 src/Tests/SkipPdfNormalizationTests.NormalizedSnapshotHoldsTheNeutralizedBytes#00.verified.png create mode 100644 src/Tests/SkipPdfNormalizationTests.NormalizedSnapshotHoldsTheNeutralizedBytes#01.verified.png create mode 100644 src/Tests/SkipPdfNormalizationTests.NormalizedSnapshotHoldsTheNeutralizedBytes.verified.pdf create mode 100644 src/Tests/SkipPdfNormalizationTests.SkippedSnapshotHoldsTheProducerBytes#00.verified.png create mode 100644 src/Tests/SkipPdfNormalizationTests.SkippedSnapshotHoldsTheProducerBytes#01.verified.png create mode 100644 src/Tests/SkipPdfNormalizationTests.SkippedSnapshotHoldsTheProducerBytes.verified.pdf create mode 100644 src/Tests/SkipPdfNormalizationTests.cs create mode 100644 src/Tests/Tests.SkipPdfNormalization#00.verified.png create mode 100644 src/Tests/Tests.SkipPdfNormalization#01.verified.png create mode 100644 src/Tests/Tests.SkipPdfNormalization.verified.pdf diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 640ee5fe..60ac9a92 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -2,7 +2,7 @@ CS1591 - 3.9.0 + 3.10.0 1.0.0 enable preview diff --git a/src/Tests/SkipPdfNormalizationTests.NormalizedSnapshotHoldsTheNeutralizedBytes#00.verified.png b/src/Tests/SkipPdfNormalizationTests.NormalizedSnapshotHoldsTheNeutralizedBytes#00.verified.png new file mode 100644 index 0000000000000000000000000000000000000000..3967adf436a275d774953426965a1871b6afa2b4 GIT binary patch literal 14647 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 TWJZ+z4W!k2oiaK)b$r@CD3F>K literal 0 HcmV?d00001 diff --git a/src/Tests/SkipPdfNormalizationTests.SkippedSnapshotHoldsTheProducerBytes#00.verified.png b/src/Tests/SkipPdfNormalizationTests.SkippedSnapshotHoldsTheProducerBytes#00.verified.png new file mode 100644 index 0000000000000000000000000000000000000000..f5f3e4e588395d40fb29ec2dd7358314f5674cf8 GIT binary patch literal 14647 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 azTT0|!`tJ(13v8m`5Zp}edD3CKmHeS+-zO| literal 0 HcmV?d00001 diff --git a/src/Tests/SkipPdfNormalizationTests.SkippedSnapshotHoldsTheProducerBytes#01.verified.png b/src/Tests/SkipPdfNormalizationTests.SkippedSnapshotHoldsTheProducerBytes#01.verified.png new file mode 100644 index 0000000000000000000000000000000000000000..0abd159802904174e990abfca7b0f1459df93b47 GIT binary patch literal 9465 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 literal 0 HcmV?d00001 diff --git a/src/Tests/SkipPdfNormalizationTests.SkippedSnapshotHoldsTheProducerBytes.verified.pdf b/src/Tests/SkipPdfNormalizationTests.SkippedSnapshotHoldsTheProducerBytes.verified.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c8b6351dfa3ee7890d0ceb0bda72a2ea6ddb7c3e GIT binary patch literal 2715 zcmbtWdvFug9v*z4Mx*snwL;4pD74b-?%B;|H=zl(O#>*Ykk*PVDBJ8wyENI2yPGyi zWd;!x1O`e)U`EHw9dPtAI^J4kK&hA4?PadO_yA?jZl85 zt5Gcgb(C$MrUq)E(MX|ss5%%k7ExZ539Wbm!QfQx)MJKvNzFoI+!om+*PcGQM=ezu8e~qlzUHWd#dwupVo-Y1P>KJ#X(>-OQpEq6T zI{WW+{+r^7*LNM-^88E5GmgSZ`lN?%tu1#J_F35W*M`~;?nf6?%P2#md)&%v#hu*$v5A&5VGX5Jiz&A zU!)4Q$g>j~tWDI^1rn_Rhh&-QHkHSmv2Y}ex zF^m-4l5X43E+&fWu02R+_1!fsalu{vxH!78zw&CUiT zP7ocbB1ZaV!qr1fMc)szRc!yCoPDqah=MAGK;Kr!b>(7>0H< zWkR&Y!|dTelkD+A8C;fje0auOU@;8_%`^dMGo5`1JIApc5j15i00|v_2qj|z0=iE| zniw8^hKw}XxiKbz8EpcPQ7u$^D;$D=Qt}l%!+8Pl@a{_^u$b$Hs2QmSGOWOx Ki;Ju8^ZpK!u%KlC literal 0 HcmV?d00001 diff --git a/src/Tests/SkipPdfNormalizationTests.cs b/src/Tests/SkipPdfNormalizationTests.cs new file mode 100644 index 00000000..64ea43f8 --- /dev/null +++ b/src/Tests/SkipPdfNormalizationTests.cs @@ -0,0 +1,27 @@ +using DeterministicPdf; + +// The Tests entry for SkipPdfNormalization only proves the setting round-trips through a +// verification. These assert the wiring it is actually there for: with the setting the snapshotted +// bytes are the producer's own, and without it they are the normalized ones. +[TestFixture] +public class SkipPdfNormalizationTests +{ + [Test] + public void SampleIsNotAlreadyNormalized() + { + // The premise the pair below rests on. If sample.pdf were already byte-identical to its + // normalized form they would both pass while asserting nothing. + var raw = File.ReadAllBytes("sample.pdf"); + + Assert.That(PdfNormalizer.Normalize(raw), Is.Not.EqualTo(raw)); + } + + [Test] + public Task SkippedSnapshotHoldsTheProducerBytes() => + Verify(new MemoryStream(File.ReadAllBytes("sample.pdf")), "pdf") + .SkipPdfNormalization(); + + [Test] + public Task NormalizedSnapshotHoldsTheNeutralizedBytes() => + Verify(new MemoryStream(File.ReadAllBytes("sample.pdf")), "pdf"); +} diff --git a/src/Tests/Tests.SkipPdfNormalization#00.verified.png b/src/Tests/Tests.SkipPdfNormalization#00.verified.png new file mode 100644 index 0000000000000000000000000000000000000000..f5f3e4e588395d40fb29ec2dd7358314f5674cf8 GIT binary patch literal 14647 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 azTT0|!`tJ(13v8m`5Zp}edD3CKmHeS+-zO| literal 0 HcmV?d00001 diff --git a/src/Tests/Tests.SkipPdfNormalization#01.verified.png b/src/Tests/Tests.SkipPdfNormalization#01.verified.png new file mode 100644 index 0000000000000000000000000000000000000000..0abd159802904174e990abfca7b0f1459df93b47 GIT binary patch literal 9465 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 literal 0 HcmV?d00001 diff --git a/src/Tests/Tests.SkipPdfNormalization.verified.pdf b/src/Tests/Tests.SkipPdfNormalization.verified.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c8b6351dfa3ee7890d0ceb0bda72a2ea6ddb7c3e GIT binary patch literal 2715 zcmbtWdvFug9v*z4Mx*snwL;4pD74b-?%B;|H=zl(O#>*Ykk*PVDBJ8wyENI2yPGyi zWd;!x1O`e)U`EHw9dPtAI^J4kK&hA4?PadO_yA?jZl85 zt5Gcgb(C$MrUq)E(MX|ss5%%k7ExZ539Wbm!QfQx)MJKvNzFoI+!om+*PcGQM=ezu8e~qlzUHWd#dwupVo-Y1P>KJ#X(>-OQpEq6T zI{WW+{+r^7*LNM-^88E5GmgSZ`lN?%tu1#J_F35W*M`~;?nf6?%P2#md)&%v#hu*$v5A&5VGX5Jiz&A zU!)4Q$g>j~tWDI^1rn_Rhh&-QHkHSmv2Y}ex zF^m-4l5X43E+&fWu02R+_1!fsalu{vxH!78zw&CUiT zP7ocbB1ZaV!qr1fMc)szRc!yCoPDqah=MAGK;Kr!b>(7>0H< zWkR&Y!|dTelkD+A8C;fje0auOU@;8_%`^dMGo5`1JIApc5j15i00|v_2qj|z0=iE| zniw8^hKw}XxiKbz8EpcPQ7u$^D;$D=Qt}l%!+8Pl@a{_^u$b$Hs2QmSGOWOx Ki;Ju8^ZpK!u%KlC literal 0 HcmV?d00001 diff --git a/src/Tests/Tests.cs b/src/Tests/Tests.cs index 79000d81..fd941a53 100644 --- a/src/Tests/Tests.cs +++ b/src/Tests/Tests.cs @@ -160,6 +160,11 @@ public Task VerifyPdf() => public Task VerifyWebp() => VerifyFile("sample.webp"); + [Test] + public Task SkipPdfNormalization() => + VerifyFile("sample.pdf") + .SkipPdfNormalization(); + [Test] public Task VerifyPdfWithName() => Verify(targets: [new("pdf", File.OpenRead("sample.pdf"), "name")]); diff --git a/src/Verify.ImageMagick/ImageMagickSettings.cs b/src/Verify.ImageMagick/ImageMagickSettings.cs index c57c5ac4..072dd0e1 100644 --- a/src/Verify.ImageMagick/ImageMagickSettings.cs +++ b/src/Verify.ImageMagick/ImageMagickSettings.cs @@ -92,4 +92,36 @@ public static SettingsTask ImageMagickPdfPassword(this SettingsTask settings, st return pdfPassword; } -} \ No newline at end of file + + ///

+ /// Snapshots the pdf bytes exactly as produced, skipping the normalization that neutralizes the + /// trailer /ID, the /CreationDate and /ModDate, and the XMP dates and + /// identifiers. Use it when the producer already emits byte-deterministic documents, since + /// normalizing them again copies the whole buffer, rescans it, and — when the XMP packet is + /// canonicalized — rebuilds it and repairs the cross-reference table, all to change nothing. + /// + /// + /// Only skip this when the producer is genuinely deterministic. Without it a freshly generated + /// pdf carries a wall-clock /CreationDate and a fresh /ID, so the snapshot differs + /// on every run. + /// + /// The XMP canonicalization is worth calling out because it is the pass that changes bytes for + /// an already-deterministic producer: it collapses the packet's whitespace, so enabling or + /// disabling this setting on an existing suite shifts the stored .verified.pdf even + /// though nothing about the document changed. Expect to re-accept those snapshots once. + /// + /// + public static void SkipPdfNormalization(this VerifySettings settings) => + settings.Context["ImageMagick.SkipNormalization"] = true; + + /// + public static SettingsTask SkipPdfNormalization(this SettingsTask settings) + { + settings.CurrentSettings.SkipPdfNormalization(); + return settings; + } + + internal static bool Normalize(this IReadOnlyDictionary context) => + !context.TryGetValue("ImageMagick.SkipNormalization", out var value) || + value is not true; +} diff --git a/src/Verify.ImageMagick/VerifyImageMagick_Pdf.cs b/src/Verify.ImageMagick/VerifyImageMagick_Pdf.cs index 2127aac0..3e9b85fd 100644 --- a/src/Verify.ImageMagick/VerifyImageMagick_Pdf.cs +++ b/src/Verify.ImageMagick/VerifyImageMagick_Pdf.cs @@ -74,8 +74,9 @@ internal static ConversionResult Convert(string? name, Stream stream, IReadOnlyD if (includePdf) { stream.Position = 0; + var pdf = context.Normalize() ? PdfNormalizer.Normalize(stream) : CopyRemaining(stream); targets.Add( - new("pdf", PdfNormalizer.Normalize(stream), name, performConversion: false) + new("pdf", pdf, name, performConversion: false) { BypassComparersForSubsequentOnDifference = true }); @@ -84,4 +85,13 @@ internal static ConversionResult Convert(string? name, Stream stream, IReadOnlyD targets.AddRange(streams.Select(_ => new Target("png", _, name))); return new(null, targets); } -} \ No newline at end of file + + // The source stream is consumed elsewhere in this method, so the pdf target gets its own copy. + static MemoryStream CopyRemaining(Stream stream) + { + var target = new MemoryStream(); + stream.CopyTo(target); + target.Position = 0; + return target; + } +}