From 1aafac73368e2396b0b6aa08332b5cd63faf3cc2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 10 May 2025 11:40:19 +0200 Subject: [PATCH 1/6] Bump golang.org/x/crypto from 0.33.0 to 0.35.0 (#68) --- go.mod | 6 ++++-- go.sum | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index cd94148..11d6e73 100644 --- a/go.mod +++ b/go.mod @@ -1,12 +1,14 @@ module github.com/digitorus/pdfsign -go 1.22 +go 1.23.0 + +toolchain go1.23.6 require ( github.com/digitorus/pdf v0.1.2 github.com/digitorus/pkcs7 v0.0.0-20230818184609-3a137a874352 github.com/digitorus/timestamp v0.0.0-20231217203849-220c5c2851b7 github.com/mattetti/filebuffer v1.0.1 - golang.org/x/crypto v0.33.0 + golang.org/x/crypto v0.35.0 golang.org/x/text v0.22.0 ) diff --git a/go.sum b/go.sum index efe10c3..eed5847 100644 --- a/go.sum +++ b/go.sum @@ -7,7 +7,7 @@ github.com/digitorus/timestamp v0.0.0-20231217203849-220c5c2851b7 h1:lxmTCgmHE1G github.com/digitorus/timestamp v0.0.0-20231217203849-220c5c2851b7/go.mod h1:GvWntX9qiTlOud0WkQ6ewFm0LPy5JUR1Xo0Ngbd1w6Y= github.com/mattetti/filebuffer v1.0.1 h1:gG7pyfnSIZCxdoKq+cPa8T0hhYtD9NxCdI4D7PTjRLM= github.com/mattetti/filebuffer v1.0.1/go.mod h1:YdMURNDOttIiruleeVr6f56OrMc+MydEnTcXwtkxNVs= -golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= -golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= +golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= +golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= From 6cbaf97a7046c16d2a55d5b3e06fac8fc3395dee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 10 May 2025 09:41:34 +0000 Subject: [PATCH 2/6] Bump golang.org/x/text from 0.22.0 to 0.25.0 Bumps [golang.org/x/text](https://github.com/golang/text) from 0.22.0 to 0.25.0. - [Release notes](https://github.com/golang/text/releases) - [Commits](https://github.com/golang/text/compare/v0.22.0...v0.25.0) --- updated-dependencies: - dependency-name: golang.org/x/text dependency-version: 0.25.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 11d6e73..4949b27 100644 --- a/go.mod +++ b/go.mod @@ -10,5 +10,5 @@ require ( github.com/digitorus/timestamp v0.0.0-20231217203849-220c5c2851b7 github.com/mattetti/filebuffer v1.0.1 golang.org/x/crypto v0.35.0 - golang.org/x/text v0.22.0 + golang.org/x/text v0.25.0 ) diff --git a/go.sum b/go.sum index eed5847..a0c2832 100644 --- a/go.sum +++ b/go.sum @@ -9,5 +9,5 @@ github.com/mattetti/filebuffer v1.0.1 h1:gG7pyfnSIZCxdoKq+cPa8T0hhYtD9NxCdI4D7PT github.com/mattetti/filebuffer v1.0.1/go.mod h1:YdMURNDOttIiruleeVr6f56OrMc+MydEnTcXwtkxNVs= golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= -golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= +golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= From e026bf1577cb81300c1ea886c2079125bc98f245 Mon Sep 17 00:00:00 2001 From: Paul van Brouwershaven Date: Mon, 12 May 2025 09:28:04 +0200 Subject: [PATCH 3/6] Add newline, fix #71 --- sign/pdftrailer.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sign/pdftrailer.go b/sign/pdftrailer.go index 8268731..6227ae4 100644 --- a/sign/pdftrailer.go +++ b/sign/pdftrailer.go @@ -43,7 +43,7 @@ func (context *SignContext) writeTrailer() error { lines[i] = " " + strings.TrimSpace(line) } } - trailer_string = strings.Join(lines, "\n") + trailer_string = strings.Join(lines, "\n") + "\n" // Write the new trailer. if _, err := context.OutputBuffer.Write([]byte(trailer_string)); err != nil { @@ -54,7 +54,6 @@ func (context *SignContext) writeTrailer() error { return err } } - // Write the new xref start position. if _, err := context.OutputBuffer.Write([]byte(strconv.FormatInt(context.NewXrefStart, 10) + "\n")); err != nil { return err From bf1f8610311e70177b051d9b8906be1a40ace355 Mon Sep 17 00:00:00 2001 From: Paul van Brouwershaven Date: Mon, 12 May 2025 10:21:10 +0200 Subject: [PATCH 4/6] Ensure PDF version is at least 1.5 for SigFlags and UF support --- sign/pdfcatalog.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sign/pdfcatalog.go b/sign/pdfcatalog.go index a8c0d07..b5b8537 100644 --- a/sign/pdfcatalog.go +++ b/sign/pdfcatalog.go @@ -28,9 +28,10 @@ func (context *SignContext) createCatalog() ([]byte, error) { // written in the PDF file (for example, /1.4). // // If an incremental upgrade requires a version that is higher than specified by the document. - // if context.PDFReader.PDFVersion < "2.0" { - // catalog_buffer.WriteString(" /Version /2.0") - // } + // Ensure PDF version is at least 1.5 to support SigFlags in acroFormDict (1.4) and UF in the fileSpecDict (1.5) + if v, err := strconv.ParseFloat(context.PDFReader.PDFVersion, 64); err == nil && v < 1.5 { + catalog_buffer.WriteString(" /Version /1.5") + } // Retrieve the root, its pointer and set the root string root := context.PDFReader.Trailer().Key("Root") From 0f834debb71c7cd0a3663f8ddb6e5b2415595687 Mon Sep 17 00:00:00 2001 From: Paul van Brouwershaven Date: Mon, 12 May 2025 10:57:42 +0200 Subject: [PATCH 5/6] Fix test removed invalid source test file --- sign/pdfcatalog.go | 2 +- sign/pdfcatalog_test.go | 8 ++++---- sign/pdfxref_test.go | 1 - testfiles/testfile21.pdf | Bin 6804 -> 0 bytes 4 files changed, 5 insertions(+), 6 deletions(-) delete mode 100644 testfiles/testfile21.pdf diff --git a/sign/pdfcatalog.go b/sign/pdfcatalog.go index b5b8537..8f16c18 100644 --- a/sign/pdfcatalog.go +++ b/sign/pdfcatalog.go @@ -30,7 +30,7 @@ func (context *SignContext) createCatalog() ([]byte, error) { // If an incremental upgrade requires a version that is higher than specified by the document. // Ensure PDF version is at least 1.5 to support SigFlags in acroFormDict (1.4) and UF in the fileSpecDict (1.5) if v, err := strconv.ParseFloat(context.PDFReader.PDFVersion, 64); err == nil && v < 1.5 { - catalog_buffer.WriteString(" /Version /1.5") + catalog_buffer.WriteString(" /Version /1.5\n") } // Retrieve the root, its pointer and set the root string diff --git a/sign/pdfcatalog_test.go b/sign/pdfcatalog_test.go index e47a4ab..76da046 100644 --- a/sign/pdfcatalog_test.go +++ b/sign/pdfcatalog_test.go @@ -21,11 +21,11 @@ var testFiles = []struct { }, }, { - file: "../testfiles/testfile21.pdf", + file: "../testfiles/testfile12.pdf", expectedCatalogs: map[CertType]string{ - CertificationSignature: "<<\n /Type /Catalog\n /Metadata 8 0 R\n /Names 6 0 R\n /Pages 9 0 R\n /AcroForm <<\n /Fields [16 0 R]\n /SigFlags 3\n >>\n>>\n", - UsageRightsSignature: "<<\n /Type /Catalog\n /Metadata 8 0 R\n /Names 6 0 R\n /Pages 9 0 R\n /AcroForm <<\n /Fields [16 0 R]\n /SigFlags 1\n >>\n>>\n", - ApprovalSignature: "<<\n /Type /Catalog\n /Metadata 8 0 R\n /Names 6 0 R\n /Pages 9 0 R\n /AcroForm <<\n /Fields [16 0 R]\n /SigFlags 3\n >>\n>>\n", + CertificationSignature: "<<\n /Type /Catalog\n /Version /1.5\n /Outlines 2 0 R\n /Pages 3 0 R\n /AcroForm <<\n /Fields [16 0 R]\n /SigFlags 3\n >>\n>>\n", + UsageRightsSignature: "<<\n /Type /Catalog\n /Version /1.5\n /Outlines 2 0 R\n /Pages 3 0 R\n /AcroForm <<\n /Fields [16 0 R]\n /SigFlags 1\n >>\n>>\n", + ApprovalSignature: "<<\n /Type /Catalog\n /Version /1.5\n /Outlines 2 0 R\n /Pages 3 0 R\n /AcroForm <<\n /Fields [16 0 R]\n /SigFlags 3\n >>\n>>\n", }, }, } diff --git a/sign/pdfxref_test.go b/sign/pdfxref_test.go index 1a81a11..a107ca9 100644 --- a/sign/pdfxref_test.go +++ b/sign/pdfxref_test.go @@ -20,7 +20,6 @@ func TestGetLastObjectIDFromXref(t *testing.T) { {"testfile16.pdf", 567}, {"testfile17.pdf", 20}, {"testfile20.pdf", 10}, - {"testfile21.pdf", 16}, } for _, tc := range testCases { diff --git a/testfiles/testfile21.pdf b/testfiles/testfile21.pdf deleted file mode 100644 index f7f09080c19c3727be7a35642dcaedb0096b0262..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6804 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 Xe*Sbyae}yfdX1JOqM}lUrV{@Pd6&r9 From 7feb03999bf30526b30f15a2bf9da9cd230545c1 Mon Sep 17 00:00:00 2001 From: Paul van Brouwershaven Date: Mon, 12 May 2025 11:08:51 +0200 Subject: [PATCH 6/6] Enhance handling of PDF Contents in createIncPageUpdate to preserve stream structure --- sign/pdfvisualsignature.go | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/sign/pdfvisualsignature.go b/sign/pdfvisualsignature.go index 6e9e957..23c43c4 100644 --- a/sign/pdfvisualsignature.go +++ b/sign/pdfvisualsignature.go @@ -128,9 +128,25 @@ func (context *SignContext) createIncPageUpdate(pageNumber, annot uint32) ([]byt // TODO: Update digitorus/pdf to get raw values without resolving pointers for _, key := range page.Keys() { switch key { - case "Contents", "Parent": + case "Parent": ptr := page.Key(key).GetPtr() page_buffer.WriteString(fmt.Sprintf(" /%s %d 0 R\n", key, ptr.GetID())) + case "Contents": + // Special handling for Contents - must preserve stream structure + contentsValue := page.Key(key) + if contentsValue.Kind() == pdf.Array { + // If Contents is an array, keep it as an array reference + page_buffer.WriteString(" /Contents [") + for i := 0; i < contentsValue.Len(); i++ { + ptr := contentsValue.Index(i).GetPtr() + page_buffer.WriteString(fmt.Sprintf(" %d 0 R", ptr.GetID())) + } + page_buffer.WriteString(" ]\n") + } else { + // If Contents is a single reference, keep it as a single reference + ptr := contentsValue.GetPtr() + page_buffer.WriteString(fmt.Sprintf(" /%s %d 0 R\n", key, ptr.GetID())) + } case "Annots": page_buffer.WriteString(" /Annots [\n") for i := 0; i < page.Key("Annots").Len(); i++ {