feat(documents): PDF 文本层抽取(S6 第一段;扫描件仍诚实拒绝)
- 依赖:github.com/ledongthuc/pdf(**BSD-3-Clause**,非 MIT —— 子代理核了 LICENSE 并纠正了任务书的写法;零传递依赖;无 cgo/无外部进程;体积 strip 后 +285.5 KiB / +0.74%,在 detached worktree 里量取,产出写到仓库外)。被否候选:pdfcpu 无文本抽取、rsc.io/pdf 停更、pdfium/poppler/mupdf 需 cgo 撞红线。
- 实现:魔数 %PDF- 是唯一入口判定(名字/声明指向 PDF 而字节无魔数 ⇒ ErrUnsupported,绝不退回纯文本抽);逐页 GetPlainText(页间仅去首尾空白);ExtractorVersion v2→v3(所有 sidecar 一次性重抽);页数上限 5000 + 字节安全上限复用;新增哨兵 ErrPDFEncrypted / ErrPDFDamaged。
- 诚实边界:无文本层(扫描件)⇒ ErrNoTextLayer 且文案含「图片型/无文本层 PDF,需要 OCR(当前未做)」;加密/损坏各自可判、绝不 panic、不回空正文假装成功。
- 白名单与成对裁决:.pdf 纳入(22→23),且 ContentAllowed 做双向裁决(.pdf 只收嗅探为 application/pdf;PDF 字节只收在 .pdf 名下);读侧真 PDF 如实下发 application/pdf,仍 attachment + nosniff(不可内联)。
- 1 处 panic 兜底已如实登记:该库对「xref 指向文件外」畸形件会在 NumPage() 直接 panic(已用仓库外程序复现),单二进制常驻后端不能因 587 字节上传件崩掉 ⇒ defer recover 折成 ErrPDFDamaged;损坏类主用例仍走库的真出错路径。
- 主会话独立验收:隔离 worktree(B1 的 14 文件)build/vet 绿、全树 59 包 0 FAIL、PDF 用例 13 PASS、双平台交叉编译绿;变异独立复现(魔数裁决短路 ⇒ 魔数/成对裁决用例红)。
- ⚠️ 契约漂移(已排 C2):Docs 仍写「22 项白名单 / 嗅探仅放行 text/plain」,与本切片的 23 项 + 成对裁决不一致 ⇒ 需升 v0.61 登记 .pdf 与新的边界。
This commit is contained in:
1 parent
c4e09afd38
commit
f82c76df27
14 files changed
+926
-94
No files matched your search
@@ -29,8 +29,10 @@ type Sidecar struct {
|
||||
Status string
|
||||
// Reason 是 Status == unreadable 时的诚实原因(正文位置为空)。
|
||||
Reason string
|
||||
// Kind 是抽取所得内容的种类(text / csv / tsv)。
|
||||
// Kind 是抽取所得内容的种类(text / csv / tsv / pdf)。
|
||||
Kind string
|
||||
// Pages 是 PDF 的页数(其它种类为 0)。
|
||||
Pages int
|
||||
// Chars 是抽取期写盘时的正文字符数(rune)。
|
||||
Chars int
|
||||
// Truncated 报告 sidecar 正文在**抽取期**是否撞上了安全上限
|
||||
@@ -68,6 +70,7 @@ func ReadSidecar(dataDir, name string) (Sidecar, error) {
|
||||
Status: rec.Status,
|
||||
Reason: rec.Reason,
|
||||
Kind: rec.Kind,
|
||||
Pages: rec.Pages,
|
||||
Chars: rec.Chars,
|
||||
Truncated: rec.Truncated,
|
||||
Text: rec.Text,
|
||||
@@ -123,6 +126,7 @@ func (s *sidecarStore) loadSidecar(name string) (cachedExtract, error) {
|
||||
Status: meta.Status,
|
||||
Reason: meta.Reason,
|
||||
Kind: meta.Kind,
|
||||
Pages: meta.Pages,
|
||||
Chars: meta.Chars,
|
||||
Truncated: meta.Truncated,
|
||||
Text: body,
|
||||
|
||||
Reference in new issue
Block a user