anthropics / anthropics/skills

pdf skill: extract_form_field_info.py corrupts/crashes on comboboxes whose /Opt entries are bare strings

Đang mở Phù hợp với người mới
#1,469 0 bình luận 0 reaction 0 người được giao Xem trên GitHub
Ngôn ngữ chính
Python
Star
176k
Fork
20.9k
Merge trung bình
7 giờ 21 phút
Pull request đã merge (30 ngày)
5

Mô tả

## Summary

`skills/pdf/scripts/extract_form_field_info.py` assumes every choice-field option (`/Opt`) is a `[export_value, display_text]` pair. Per ISO 32000-1 §12.7.4.4, an `/Opt` array entry may instead be a **single text string** (used as both the export value and the display text). On such fields the script silently produces corrupted output, and crashes outright when any option is a single character.

## Buggy code (`skills/pdf/scripts/extract_form_field_info.py`, lines 35-41)

```python
elif ft == "/Ch":
field_dict["type"] = "choice"
states = field.get("/_States_", [])
field_dict["choice_options"] = [{
"value": state[0],
"text": state[1],
} for state in states]
```

`states` comes from pypdf's `/_States_`, which for `/Ch` fields is the raw `/Opt` array verbatim (`pypdf/_doc_common.py`: `retval[key]["/_States_"] = obj["/Opt"]`). When `/Opt` holds bare strings, `state[0]`/`state[1]` index into the string instead of a pair.

## Reproduction

Create a combobox whose `/Opt` is bare strings, then run the script (pypdf 6.13.1):

```python
from pypdf import PdfWriter
from pypdf.generic import (DictionaryObject, ArrayObject, NameObject,
TextStringObject, NumberObject)
w = PdfWriter(); page = w.add_blank_page(width=300, height=300)
f = DictionaryObject()
f[NameObject("/FT")] = NameObject("/Ch")
f[NameObject("/T")] = TextStringObject("colors")
f[NameObject("/Ff")] = NumberObject(1 << 17) # Combo
f[NameObject("/Opt")] = ArrayObject([TextStringObject(s) for s in ("Red","Green","Blue")])
f[NameObject("/Subtype")] = NameObject("/Widget")
f[NameObject("/Rect")] = ArrayObject([NumberObject(x) for x in (50,50,250,80)])
f[NameObject("/P")] = page.indirect_reference
ref = w._add_object(f); page[NameObject("/Annots")] = ArrayObject([ref])
acro = DictionaryObject(); acro[NameObject("/Fields")] = ArrayObject([ref])
w._root_object[NameObject("/AcroForm")] = w._add_object(acro)
w.write(open("bare_opt.pdf","wb"))
```

```
$ python extract_form_field_info.py bare_opt.pdf out.json
```

**Result — silent corruption:**

```json
"choice_options": [
{"value": "R", "text": "e"},
{"value": "G", "text": "r"},
{"value": "B", "text": "l"}
]
```

`"Red"` becomes `value="R", text="e"` (chars 0 and 1 of the string).

**Result with a single-character option (e.g. `/Opt = ["A","B"]`) — hard crash:**

```
File "extract_form_field_info.py", line 40, in make_field_dict
"text": state[1],
IndexError: string index out of range
```

## Impact

Any real-world PDF using string-form `/Opt` (common for simple dropdowns) either gets its choice values/labels garbled one character at a time — with no error — or crashes the whole extraction on a single-letter option. Because the output feeds downstream form-filling, the corruption is silent and misleading.

## Suggested fix

Normalize each entry, treating a bare string as its own value and text:

```python
field_dict["choice_options"] = [
{"value": s, "text": s} if isinstance(s, str) else {"value": s[0], "text": s[1]}
for s in states
]
```

Environment: pypdf 6.13.1, Python 3.13; upstream file fetched from `anthropics/skills@main`.

Hướng dẫn đóng góp

Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này

Hướng nghiên cứu

Start in skills/pdf/scripts/extract_form_field_info.py at the choice-field handling around lines 35-41, then run the supplied bare_opt.pdf reproduction with pypdf 6.13.1. Done means bare-string options retain the same value and text, paired options remain supported, and single-character options no longer crash.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
python
Lĩnh vực
tooling
Loại issue
Lỗi
Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức độ hoạt động
Ít trao đổi
Độ rõ ràng
Đặc tả rõ ràng
Mức phù hợp với người mới
88/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.