From a910b8cca23a9679dcba7259f8affb29790a5c3a Mon Sep 17 00:00:00 2001 From: FredApps <153173854+FredApps@users.noreply.github.com> Date: Sun, 1 Nov 2026 12:33:26 +0100 Subject: [PATCH] fix(automation): reject invalid transform coefficients Reject malformed matrices instead of dropping non-numeric coefficients and applying an unintended transform. The regression failed against the previous parser on GGEO-AI02; all 1721 scoped tests pass with the fix. Co-Authored-By: Codex GPT-6.1 --- crates/automation/src/dispatch.rs | 7 +++++-- crates/automation/tests/it/automation.rs | 9 ++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/crates/automation/src/dispatch.rs b/crates/automation/src/dispatch.rs index e8fc8d66fb..da1c3a6d20 100644 --- a/crates/automation/src/dispatch.rs +++ b/crates/automation/src/dispatch.rs @@ -425,8 +425,11 @@ impl Automation { ImageEdit::Move([u0[0].min(u1[0]) as f64, u0[1].min(u1[1]) as f64, u0[0].max(u1[0]) as f64, u0[1].max(u1[1]) as f64]) } "transform" => { - let m: Vec = - a.get("matrix").and_then(Value::as_array).map(|x| x.iter().filter_map(Value::as_f64).collect()).unwrap_or_default(); + let m: Vec = a + .get("matrix") + .and_then(Value::as_array) + .and_then(|x| x.iter().map(Value::as_f64).collect()) + .ok_or_else(|| ToolError::InvalidArgs("transform needs matrix: 6 numbers [a, b, c, d, e, f]".into()))?; let m = <[f64; 6]>::try_from(m) .map_err(|_| ToolError::InvalidArgs("transform needs matrix: 6 numbers [a, b, c, d, e, f]".into()))?; ImageEdit::Transform(view_transform_to_user(&self.doc(&a)?.info.pages[page], m)?) diff --git a/crates/automation/tests/it/automation.rs b/crates/automation/tests/it/automation.rs index 52083cfc67..520e0b22d1 100644 --- a/crates/automation/tests/it/automation.rs +++ b/crates/automation/tests/it/automation.rs @@ -3538,7 +3538,14 @@ fn transforming_page_images_through_tools() { // Flat, non-finite, short and missing matrices are refused before anything changes. let before = rect(&mut a); - for bad in [json!([1, 2, 2, 4, 0, 0]), json!([0, 0, 0, 0, 0, 0]), json!([1e300, 0, 0, 1e300, 0, 0]), json!([1, 0, 0, 1])] { + for bad in [ + json!([1, 2, 2, 4, 0, 0]), + json!([0, 0, 0, 0, 0, 0]), + json!([1e300, 0, 0, 1e300, 0, 0]), + json!([1, 0, 0, 1]), + json!([1, 0, "invalid", 0, 1, 10, 0]), + json!([1, 0, null, 0, 1, 10, 0]), + ] { let r = a.call("image_edit", &json!({ "doc": made, "page": 1, "image": 1, "action": "transform", "matrix": bad })); assert!(matches!(r, Err(ToolError::InvalidArgs(_))), "{bad}: {r:?}"); }