mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-11-12 08:52:40 +00:00
M12: sign_document reads every argument before the preSign scripts run
This commit is contained in:
@@ -253,6 +253,11 @@ impl Automation {
|
||||
// A dynamic form's signing scripts run only when asked: what preSign changes is signed,
|
||||
// and the caller hasn't seen it. What they changed is listed.
|
||||
let run_scripts = a.opt_bool("run_form_scripts")?.unwrap_or(false);
|
||||
// Every argument is read before the preSign scripts change anything, so a bad one is
|
||||
// refused with the document as it was.
|
||||
let reason = a.opt_str("reason")?.map(str::to_string);
|
||||
let location = a.opt_str("location")?.map(str::to_string);
|
||||
let contact = a.opt_str("contact")?.map(str::to_string);
|
||||
let signing = field.clone();
|
||||
let scripted = signing.as_deref().is_some_and(|f| {
|
||||
self.session.sign_event_scripted(doc_id, f, SignEvent::Before) || self.session.sign_event_scripted(doc_id, f, SignEvent::After)
|
||||
@@ -278,19 +283,8 @@ impl Automation {
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
let opts = SignOptions {
|
||||
field,
|
||||
page,
|
||||
rect,
|
||||
reason: a.opt_str("reason")?.map(str::to_string),
|
||||
location: a.opt_str("location")?.map(str::to_string),
|
||||
contact: a.opt_str("contact")?.map(str::to_string),
|
||||
certify,
|
||||
appearance,
|
||||
appearance_labels,
|
||||
graphic,
|
||||
..SignOptions::default()
|
||||
};
|
||||
let opts =
|
||||
SignOptions { field, page, rect, reason, location, contact, certify, appearance, appearance_labels, graphic, ..SignOptions::default() };
|
||||
let signed = self.session.sign(doc_id, &id, opts).map_err(|e| match e {
|
||||
// A graphic the signer refuses is the caller's to fix.
|
||||
pdfcraft_engine::EditError::Sign(m) if m.starts_with("the signature graphic") => bad(m),
|
||||
|
||||
@@ -5804,6 +5804,21 @@ fn signing_an_xfa_box_runs_its_signing_scripts_through_tools() {
|
||||
"{unasked}"
|
||||
);
|
||||
let doc = ok(&mut a, "doc_open", json!({ "path": "form.pdf" }))["doc"].as_u64().unwrap();
|
||||
// A bad argument is refused before the preSign scripts run.
|
||||
let bad = a.call(
|
||||
"sign_document",
|
||||
&json!({ "doc": doc, "id": "ada.p12", "password": "secret12", "field": name("sign"), "out": "bad.pdf", "run_form_scripts": true, "reason": 5 }),
|
||||
);
|
||||
assert!(matches!(bad, Err(ToolError::InvalidArgs(_))), "{bad:?}");
|
||||
let now = ok(&mut a, "form_fields", json!({ "doc": doc }));
|
||||
assert!(
|
||||
now["fields"]
|
||||
.as_array()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.any(|f| f["name"].as_str().is_some_and(|n| n == "when" || n.ends_with(".when[0]")) && f["value"].is_null()),
|
||||
"{now}"
|
||||
);
|
||||
// A signed file that can't be written (`out` is a folder): not signed, and what preSign did
|
||||
// is taken back.
|
||||
std::fs::create_dir_all(dir.join("taken")).unwrap();
|
||||
|
||||
Reference in New Issue
Block a user