mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-10-24 18:33:22 +00:00
fix(forms): skip a field of an unread kind before it claims shared widgets
This commit is contained in:
@@ -826,12 +826,8 @@ fn walk(
|
||||
}
|
||||
return;
|
||||
}
|
||||
let widget_refs: Vec<ObjRef> = if d.contains(b"Rect") { vec![r] } else { kids };
|
||||
let widget_refs: Vec<ObjRef> = widget_refs.into_iter().filter(|w| seen.widgets.insert(*w)).collect();
|
||||
let actions = actions_of(doc, d, &widget_refs, &mut seen.scripts);
|
||||
let button = (inh.ft.as_deref() == Some(b"Btn") && inh.ff.unwrap_or(0) & flags::PUSH_BUTTON != 0)
|
||||
.then(|| button_action(doc, d, &widget_refs, &mut seen.scripts))
|
||||
.flatten();
|
||||
// A field of no kind this reads is skipped before it claims widgets or scripts, which a later
|
||||
// field listing them then reads.
|
||||
let ff = inh.ff.unwrap_or(0);
|
||||
let kind = match inh.ft.as_deref() {
|
||||
Some(b"Tx") => FieldKind::Text,
|
||||
@@ -843,6 +839,12 @@ fn walk(
|
||||
Some(b"Sig") => FieldKind::Signature,
|
||||
_ => return,
|
||||
};
|
||||
let widget_refs: Vec<ObjRef> = if d.contains(b"Rect") { vec![r] } else { kids };
|
||||
let widget_refs: Vec<ObjRef> = widget_refs.into_iter().filter(|w| seen.widgets.insert(*w)).collect();
|
||||
let actions = actions_of(doc, d, &widget_refs, &mut seen.scripts);
|
||||
let button = (inh.ft.as_deref() == Some(b"Btn") && inh.ff.unwrap_or(0) & flags::PUSH_BUTTON != 0)
|
||||
.then(|| button_action(doc, d, &widget_refs, &mut seen.scripts))
|
||||
.flatten();
|
||||
let widgets = widget_refs
|
||||
.into_iter()
|
||||
.filter_map(|w| {
|
||||
|
||||
@@ -3040,3 +3040,19 @@ fn a_widget_listed_repeatedly_is_read_once() {
|
||||
let widgets: Vec<usize> = all.iter().map(|f| f.widgets.len()).collect();
|
||||
assert_eq!(widgets, [1, 0], "{:?}", all.iter().map(|f| &f.name).collect::<Vec<_>>());
|
||||
}
|
||||
|
||||
/// A field of a kind that isn't read doesn't claim the widget it shares with a field that is.
|
||||
#[test]
|
||||
fn a_skipped_field_leaves_its_widget_to_the_next() {
|
||||
let doc = document(&[
|
||||
"<< /Type /Catalog /Pages 4 0 R /AcroForm << /Fields [2 0 R 3 0 R] >> >>".into(),
|
||||
"<< /FT /Zz /T (odd) /Kids [6 0 R] >>".into(),
|
||||
"<< /FT /Tx /T (b) /Kids [6 0 R] >>".into(),
|
||||
"<< /Type /Pages /Kids [5 0 R] /Count 1 >>".into(),
|
||||
"<< /Type /Page /Parent 4 0 R /MediaBox [0 0 100 100] /Annots [6 0 R] >>".into(),
|
||||
"<< /Type /Annot /Subtype /Widget /Parent 3 0 R /Rect [0 0 10 10] >>".into(),
|
||||
]);
|
||||
let all = fields(&doc);
|
||||
let widgets: Vec<(&str, usize)> = all.iter().map(|f| (f.name.as_str(), f.widgets.len())).collect();
|
||||
assert_eq!(widgets, [("b", 1)]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user