mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-10-24 10:08:00 -06:00
fix(sign): a widget counts as signed only when its /V resolves to a dictionary
This commit is contained in:
@@ -1788,7 +1788,10 @@ fn change_kind(doc: &Document, old: &Document, d: &Dict, before: Option<&Dict>)
|
||||
// A signature widget that already held a signature is what the signature shows: moving it or
|
||||
// swapping its appearance can hide the signed page under it. Judged by the signed revision,
|
||||
// so relabelling the widget now does not change that.
|
||||
if before.is_some_and(|b| b.name(b"Subtype") == Some(b"Widget") && b.contains(b"V") && b.name(b"FT") == Some(b"Sig")) && before != Some(d) {
|
||||
if before.is_some_and(|b| {
|
||||
b.name(b"Subtype") == Some(b"Widget") && b.name(b"FT") == Some(b"Sig") && b.get(b"V").is_some_and(|v| old.resolve(v).as_dict().is_some())
|
||||
}) && before != Some(d)
|
||||
{
|
||||
return kind::PAGE_CONTENT;
|
||||
}
|
||||
match ty {
|
||||
|
||||
@@ -2602,3 +2602,19 @@ fn freeing_a_signed_object_or_rewriting_the_signed_widget_is_a_page_content_chan
|
||||
assert_eq!(moved.status, Status::Invalid, "{:?}", moved.modification);
|
||||
assert!(matches!(&moved.modification, Modification::Disallowed(k) if k.contains(&kind::PAGE_CONTENT)), "{:?}", moved.modification);
|
||||
}
|
||||
|
||||
/// An existing signature field whose `/V` is null is unsigned: signing it rewrites its widget,
|
||||
/// and that is a signature, not a change to what an earlier signature shows.
|
||||
#[test]
|
||||
fn signing_a_field_with_a_null_value_after_another_signature_keeps_the_first_valid() {
|
||||
let id = pkcs12::open(&data("rsa-aes.p12"), "test").unwrap();
|
||||
let trust = TrustStore { certs: vec![id.certificate.clone()] };
|
||||
let first = pdfcraft_sign::sign(&open(&fixture()), &id, &opts()).unwrap();
|
||||
let second = pdfcraft_sign::sign(&open(&first), &id, &SignOptions { field: Some("Approval".into()), ..opts() }).unwrap();
|
||||
let all = signatures(&open(&second), &second, &trust);
|
||||
assert!(
|
||||
all.iter().filter(|s| s.signed).all(|s| s.status == Status::Valid),
|
||||
"{:?}",
|
||||
all.iter().map(|s| (&s.status, &s.modification)).collect::<Vec<_>>()
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user