diff --git a/pkg/api/form.go b/pkg/api/form.go index 11a6a275..df5b2868 100644 --- a/pkg/api/form.go +++ b/pkg/api/form.go @@ -31,6 +31,7 @@ import ( "github.com/pdfcpu/pdfcpu/pkg/pdfcpu/create" "github.com/pdfcpu/pdfcpu/pkg/pdfcpu/form" "github.com/pdfcpu/pdfcpu/pkg/pdfcpu/model" + "github.com/pdfcpu/pdfcpu/pkg/pdfcpu/types" "github.com/pkg/errors" ) @@ -479,6 +480,66 @@ func ExportFormFile(inFilePDF, outFileJSON string, conf *model.Configuration) (e return ExportFormJSON(f1, f2, inFilePDF, conf) } +func validateComboBoxValues(f form.Form) error { + for _, cb := range f.ComboBoxes { + if cb.Value == "" || cb.Editable { + continue + } + if len(cb.Options) > 0 { + if !types.MemberOf(cb.Value, cb.Options) { + return errors.Errorf("pdfcpu: fill field name: \"%s\" unknown value: \"%s\" - options: %v\n", cb.Name, cb.Value, cb.Options) + } + } + } + return nil +} + +func validateListBoxValues(f form.Form) error { + for _, lb := range f.ListBoxes { + if len(lb.Values) == 0 { + continue + } + if len(lb.Options) > 0 { + for _, v := range lb.Values { + if !types.MemberOf(v, lb.Options) { + return errors.Errorf("pdfcpu: fill field name: \"%s\" unknown value: \"%s\" - options: %v\n", lb.Name, v, lb.Options) + } + } + } + } + return nil +} + +func validateRadioButtonGroupValues(f form.Form) error { + for _, rbg := range f.RadioButtonGroups { + if rbg.Value == "" { + continue + } + if len(rbg.Options) > 0 { + if !types.MemberOf(rbg.Value, rbg.Options) { + return errors.Errorf("pdfcpu: fill field name: \"%s\" unknown value: \"%s\" - options: %v\n", rbg.Name, rbg.Value, rbg.Options) + } + } + } + return nil +} + +func validateOptionValues(f form.Form) error { + if err := validateRadioButtonGroupValues(f); err != nil { + return err + } + + if err := validateComboBoxValues(f); err != nil { + return err + } + + if err := validateListBoxValues(f); err != nil { + return err + } + + return nil +} + // FillForm populates the form rs with data from rd and writes the result to w. func FillForm(rs io.ReadSeeker, rd io.Reader, w io.Writer, conf *model.Configuration) error { if rs == nil { @@ -528,6 +589,14 @@ func FillForm(rs io.ReadSeeker, rd io.Reader, w io.Writer, conf *model.Configura f := formGroup.Forms[0] + if err := validateOptionValues(f); err != nil { + return err + } + + if log.CLIEnabled() { + log.CLI.Println("filling...") + } + ok, pp, err := form.FillForm(ctx, form.FillDetails(&f, nil), f.Pages, form.JSON) if err != nil { return err diff --git a/pkg/pdfcpu/form/fill.go b/pkg/pdfcpu/form/fill.go index b92adaad..8915a3f7 100644 --- a/pkg/pdfcpu/form/fill.go +++ b/pkg/pdfcpu/form/fill.go @@ -610,7 +610,7 @@ func fillBtn( return nil } - if len(d.ArrayEntry("Kids")) > 0 && primitives.FieldFlags(*ff)&primitives.FieldRadio > 0 { + if len(d.ArrayEntry("Kids")) > 0 { if err := fillRadioButtonGroup(ctx, d, id, name, locked, format, fillDetails, ok); err != nil { return err } diff --git a/pkg/pdfcpu/form/form.go b/pkg/pdfcpu/form/form.go index 3c7e7eac..0efa08c5 100644 --- a/pkg/pdfcpu/form/form.go +++ b/pkg/pdfcpu/form/form.go @@ -360,9 +360,7 @@ func collectBtn(xRefTable *model.XRefTable, d types.Dict, f *Field, fm *FieldMet } if len(d.ArrayEntry("Kids")) > 0 { - if ff != nil && primitives.FieldFlags(*ff)&primitives.FieldRadio > 0 { - return collectRadioButtonGroup(xRefTable, d, f, fm) - } + return collectRadioButtonGroup(xRefTable, d, f, fm) } f.Typ = FTCheckBox diff --git a/pkg/pdfcpu/model/xreftable.go b/pkg/pdfcpu/model/xreftable.go index 08f44f86..ffd96767 100644 --- a/pkg/pdfcpu/model/xreftable.go +++ b/pkg/pdfcpu/model/xreftable.go @@ -2810,7 +2810,7 @@ func (xRefTable *XRefTable) RectForArray(a types.Array) (*types.Rectangle, error return nil, err } - ury, err := xRefTable.DereferenceNumber(a[2]) + ury, err := xRefTable.DereferenceNumber(a[3]) if err != nil { return nil, err }