fix infinite loop
This commit is contained in:
@@ -124,6 +124,38 @@ module HexaPDF
|
||||
end
|
||||
end
|
||||
|
||||
module CycleSafeEachField
|
||||
def each_field(terminal_only: true)
|
||||
return to_enum(__method__, terminal_only:) unless block_given?
|
||||
|
||||
seen = Set.new.compare_by_identity
|
||||
|
||||
process_field_array = lambda do |array|
|
||||
array.each_with_index do |field, index|
|
||||
next if field.nil?
|
||||
|
||||
unless field.respond_to?(:type) && field.type == :XXAcroFormField
|
||||
array[index] = field = HexaPDF::Type::AcroForm::Field.wrap(document, field)
|
||||
end
|
||||
|
||||
next unless seen.add?(field.value)
|
||||
|
||||
if field.terminal_field?
|
||||
yield(field)
|
||||
else
|
||||
yield(field) unless terminal_only
|
||||
|
||||
process_field_array.call(field[:Kids])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
process_field_array.call(root_fields)
|
||||
|
||||
self
|
||||
end
|
||||
end
|
||||
|
||||
module CycleSafeFullFieldName
|
||||
def full_field_name(seen = Set.new.compare_by_identity)
|
||||
return field_name unless seen.add?(value)
|
||||
@@ -139,3 +171,4 @@ end
|
||||
|
||||
HexaPDF::Type::AcroForm::Field.singleton_class.prepend(HexaPDF::CycleSafeInheritedValue)
|
||||
HexaPDF::Type::AcroForm::Field.prepend(HexaPDF::CycleSafeFullFieldName)
|
||||
HexaPDF::Type::AcroForm::Form.prepend(HexaPDF::CycleSafeEachField)
|
||||
|
||||
@@ -264,7 +264,7 @@ module Templates
|
||||
[process_fields_array(pdf, fields_index.values), annots_index]
|
||||
end
|
||||
|
||||
def process_fields_array(pdf, array, acc = [])
|
||||
def process_fields_array(pdf, array, acc = [], seen = Set.new.compare_by_identity)
|
||||
array.each_with_index do |field, index|
|
||||
next if field.nil?
|
||||
|
||||
@@ -272,10 +272,12 @@ module Templates
|
||||
array[index] = field = HexaPDF::Type::AcroForm::Field.wrap(pdf, field)
|
||||
end
|
||||
|
||||
next unless seen.add?(field.value)
|
||||
|
||||
if field.terminal_field?
|
||||
acc << field
|
||||
else
|
||||
process_fields_array(pdf, field[:Kids], acc)
|
||||
process_fields_array(pdf, field[:Kids], acc, seen)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user