Summary
SignatureAppearance.Page is documented as "Page number (1-based) where the signature
annotation is placed", but the value is never read by the signing pipeline. Regardless
of what Page is set to, the visible signature widget annotation is always attached to
the first page of the document.
Root cause
In SimpleSign.PAdES/Signing/PdfSignatureWriter.cs, the page used to anchor the
signature widget annotation is always resolved via:
var (pageObjNum, pageObjDictStart, pageObjDictEnd) = PdfStructureParser.FindFirstPageObject(inputMem.Span);
options.Appearance.Page is never read anywhere in this file to select a different
page — it's not used to pick which page object to resolve.
Looking at SimpleSign.Pdf/PdfStructureParser.cs, there is currently no method to
locate the Nth page — only:
public static (int ObjNum, int DictStart, int DictEnd) FindFirstPageObject(ReadOnlySpan<byte> data)
So there's no way, even internally, to resolve any page other than the first for the
signature annotation.
Repro
var appearance = new SignatureAppearance
{
Page = 3, // PDF has 4+ pages
X = 50,
Y = 50,
AutoPosition = false
};
var signed = await SimpleSigner
.Document(pdfBytes)
.WithCertificate(cert)
.WithAppearance(appearance)
.SignAsync();
Expected: signature widget appears on page 3.
Actual: signature widget appears on page 1, every time, regardless of the Page value.
Environment
- Package:
SimpleSign.Brasil (and SimpleSign core)
- Version: 0.7.0
- Target framework: .NET 8
Suggested fix
Add a page-resolution method to PdfStructureParser that walks the /Pages → /Kids
tree to the Nth page (reusing the same traversal/ObjStm-fallback logic already present
in FindFirstPageObjNumFromCatalog), e.g.:
public static (int ObjNum, int DictStart, int DictEnd) FindNthPageObject(ReadOnlySpan<byte> data, int pageNumber)
And in PdfSignatureWriter.cs, branch on options.Appearance?.Page:
var (pageObjNum, pageObjDictStart, pageObjDictEnd) =
(options.Appearance?.Page ?? 1) > 1
? PdfStructureParser.FindNthPageObject(inputMem.Span, options.Appearance.Page)
: PdfStructureParser.FindFirstPageObject(inputMem.Span);
Happy to help test against real-world PDFs (including PDFs with pages in compressed
ObjStm) if useful — this is a blocker for us for any multi-page document where the
signature isn't meant to go on page 1.
Summary
SignatureAppearance.Pageis documented as "Page number (1-based) where the signatureannotation is placed", but the value is never read by the signing pipeline. Regardless
of what
Pageis set to, the visible signature widget annotation is always attached tothe first page of the document.
Root cause
In
SimpleSign.PAdES/Signing/PdfSignatureWriter.cs, the page used to anchor thesignature widget annotation is always resolved via:
options.Appearance.Pageis never read anywhere in this file to select a differentpage — it's not used to pick which page object to resolve.
Looking at
SimpleSign.Pdf/PdfStructureParser.cs, there is currently no method tolocate the Nth page — only:
So there's no way, even internally, to resolve any page other than the first for the
signature annotation.
Repro
Expected: signature widget appears on page 3.
Actual: signature widget appears on page 1, every time, regardless of the
Pagevalue.Environment
SimpleSign.Brasil(andSimpleSigncore)Suggested fix
Add a page-resolution method to
PdfStructureParserthat walks the/Pages→/Kidstree to the Nth page (reusing the same traversal/ObjStm-fallback logic already present
in
FindFirstPageObjNumFromCatalog), e.g.:And in
PdfSignatureWriter.cs, branch onoptions.Appearance?.Page:Happy to help test against real-world PDFs (including PDFs with pages in compressed
ObjStm) if useful — this is a blocker for us for any multi-page document where thesignature isn't meant to go on page 1.