From 1224d9be47e5235f39556d9118c9893ee6e68a4c Mon Sep 17 00:00:00 2001 From: Přemysl Eric Janouch
Date: Fri, 4 Sep 2020 15:34:33 +0200 Subject: Return errors rather than mangle documents --- LICENSE | 2 +- README.adoc | 4 ++-- pdf-simple-sign.cpp | 16 +++++++++++----- pdf/pdf.go | 15 ++++++++++++--- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/LICENSE b/LICENSE index 19ca8b1..3bfb256 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2017, Přemysl Eric Janouch
+Copyright (c) 2017 - 2020, Přemysl Eric Janouch
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. diff --git a/README.adoc b/README.adoc index 59bfdef..46bc9ed 100644 --- a/README.adoc +++ b/README.adoc @@ -5,8 +5,8 @@ pdf-simple-sign 'pdf-simple-sign' is a simple PDF signer intended for documents produced by the Cairo library. As such, it currently comes with some restrictions: - * the document may not have any forms or signatures already, as they will be - overwitten + * the document may not have any forms or signatures already, as they would be + overwritten * the document may not employ cross-reference streams, or must constitute a hybrid-reference file at least * the document may not be newer than PDF 1.6 already, or it will get downgraded diff --git a/pdf-simple-sign.cpp b/pdf-simple-sign.cpp index 818270e..b724f69 100644 --- a/pdf-simple-sign.cpp +++ b/pdf-simple-sign.cpp @@ -2,7 +2,7 @@ // // pdf-simple-sign: simple PDF signer // -// Copyright (c) 2017, Přemysl Eric Janouch
+// Copyright (c) 2017 - 2020, Přemysl Eric Janouch
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted.
@@ -869,15 +869,21 @@ static std::string pdf_sign(std::string& document) {
if (page.type != pdf_object::DICT)
return "invalid or unsupported page tree";
- // XXX assuming this won't be an indirectly referenced array
auto& annots = page.dict["Annots"];
- if (annots.type != pdf_object::ARRAY)
+ if (annots.type != pdf_object::ARRAY) {
+ // TODO indirectly referenced arrays might not be that hard to support
+ if (annots.type != pdf_object::END)
+ return "unexpected Annots";
+
annots = {pdf_object::ARRAY};
+ }
annots.array.emplace_back(pdf_object::REFERENCE, sigfield_n, 0);
pdf.update(page.n, [&]{ pdf.document += pdf_serialize(page); });
// 8.6.1 Interactive Form Dictionary
- // XXX assuming there are no forms already, overwriting everything
+ if (root.dict.count("AcroForm"))
+ return "the document already contains forms, they would be overwritten";
+
root.dict["AcroForm"] = {std::map
+// Copyright (c) 2018 - 2020, Přemysl Eric Janouch
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted.
@@ -32,6 +32,7 @@ import (
"crypto/ecdsa"
"crypto/rsa"
"crypto/x509"
+
"go.mozilla.org/pkcs7"
"golang.org/x/crypto/pkcs12"
)
@@ -1166,9 +1167,13 @@ func Sign(document []byte,
return nil, errors.New("invalid or unsupported page tree")
}
- // XXX: Assuming this won't be an indirectly referenced array.
annots := page.Dict["Annots"]
if annots.Kind != Array {
+ // TODO(p): Indirectly referenced arrays might not be
+ // that hard to support.
+ if annots.Kind != End {
+ return nil, errors.New("unexpected Annots")
+ }
annots = NewArray(nil)
}
annots.Array = append(annots.Array, NewReference(sigfieldN, 0))
@@ -1179,7 +1184,11 @@ func Sign(document []byte,
})
// 8.6.1 Interactive Form Dictionary
- // XXX: Assuming there are no forms already, overwriting everything.
+ if _, ok := root.Dict["AcroForm"]; ok {
+ return nil, errors.New("the document already contains forms, " +
+ "they would be overwritten")
+ }
+
root.Dict["AcroForm"] = NewDict(map[string]Object{
"Fields": NewArray([]Object{NewReference(sigfieldN, 0)}),
"SigFlags": NewNumeric(3 /* SignaturesExist | AppendOnly */),
--
cgit v1.2.3-70-g09d2