diff --git a/config/initializers/hexapdf.rb b/config/initializers/hexapdf.rb index 2552cdaf..6897b41c 100644 --- a/config/initializers/hexapdf.rb +++ b/config/initializers/hexapdf.rb @@ -110,4 +110,32 @@ module HexaPDF end end end + + module CycleSafeInheritedValue + def inherited_value(field, name) + seen = Set.new.compare_by_identity + seen << field.value + + while field.value[name].nil? && (parent = field[:Parent]) && seen.add?(parent.value) + field = parent + end + + field.value[name].nil? ? nil : field[name] + end + end + + module CycleSafeFullFieldName + def full_field_name(seen = Set.new.compare_by_identity) + return field_name unless seen.add?(value) + + if key?(:Parent) + [self[:Parent].full_field_name(seen), field_name].compact.join('.') + else + field_name + end + end + end end + +HexaPDF::Type::AcroForm::Field.singleton_class.prepend(HexaPDF::CycleSafeInheritedValue) +HexaPDF::Type::AcroForm::Field.prepend(HexaPDF::CycleSafeFullFieldName) diff --git a/lib/templates/find_acro_fields.rb b/lib/templates/find_acro_fields.rb index 7940145a..c59e381a 100644 --- a/lib/templates/find_acro_fields.rb +++ b/lib/templates/find_acro_fields.rb @@ -251,7 +251,9 @@ module Templates fields_index[annot.hash] ||= HexaPDF::Type::AcroForm::Field.wrap(pdf, annot) elsif annot.key?(:Parent) field = annot[:Parent] - field = field[:Parent] while field[:Parent] + seen = Set.new.compare_by_identity + + field = field[:Parent] while field[:Parent] && seen.add?(field.value) annots_index[field.hash] ||= page fields_index[field.hash] ||= HexaPDF::Type::AcroForm::Field.wrap(pdf, field)