| 缺陷账 E4:不支持的 PDF 特性从 500 归 422(+ 顺带修 7 处"文件损坏"误落 500) ## 判断:归 422,且用专用类型区分"我们没实现"与"文件坏了" 文件存在/完好/参数合法,只是**用了我们没实现的特性** → 422「内容不可处理」; 500 会诱导调用方对同一个文件**无限重试**。 本仓先例:加密版本不支持异常 已按同一理由归 422(端点失败.cs / 解密.cs)。 **不用 501**(语义锚在方法上,会被当 5xx 重试类)。 ## 实现 异常.cs 新增 不支持特性异常 : NotSupportedException; Pdf.Server/端点失败.cs 新增分支 → **422 + 类型="不支持的特性" + 处理[]**。 改抛新类型的能力缺口站点:滤镜.cs(未知滤镜 LZW/RunLength 等)、 图像对象.cs 6 处(JPX / 位深 / 颜色空间 / Indexed)。 **故意不映射普通 NotSupportedException**:展开滤镜名 未传解引用回调属**调用方契约错** (BCL 抛的),继续 500 —— 不掩盖真 bug。 ## 顺带修(新发现) 图像数据不完整 / Indexed 格式异常 / 调色板缺失 / 尺寸≤0 这些**文件损坏**类 原先也是裸 NotSupportedException → 500,与"文件坏了应 422"相反 → 改抛 非法PDF异常 → 422 类型="输入文件损坏"。 (内部降级信号保持原样。) 测试:Parse 87+2跳 → **88+2跳**(+1 用例,1 处断言更新); Pdf.Server 67 → **68**(+1 用例)。 若团队更倾向 501,只需改 端点失败.cs 那个新分支的状态码(单点)。 | 3 天前 |
| Nong.Pdf 首提交:源码 + README(生命绿×麦穗金头图)+ 许可证 | 1 个月前 |
| Nong.Pdf 首提交:源码 + README(生命绿×麦穗金头图)+ 许可证 | 1 个月前 |
| 补充 Apache-2.0 许可证文件(README 已声明,此处落盘正式文本) | 1 个月前 |
| Nong.Pdf 首提交:源码 + README(生命绿×麦穗金头图)+ 许可证 | 1 个月前 |
| 重写 README:按当前实现写对象模型/过滤器/加密边界 - 对外类型:文档/页面/交叉引用表/对象扫描器/滤镜/图像对象/解密器 - 依赖改为 Nong.Sharp.Read/Write(旧文写“无 Nong 内部依赖”) - 加密只支持 V4/R4 AESV2,输入上限 100MB,未实现滤镜报错不静默 | 3 天前 |
| 重写 README:按当前实现写对象模型/过滤器/加密边界 - 对外类型:文档/页面/交叉引用表/对象扫描器/滤镜/图像对象/解密器 - 依赖改为 Nong.Sharp.Read/Write(旧文写“无 Nong 内部依赖”) - 加密只支持 V4/R4 AESV2,输入上限 100MB,未实现滤镜报错不静默 | 3 天前 |
| 缺陷账 D4/A5(本仓侧):专用异常类型 + 读侧输入阈值 ## D4 新增 非法PDF异常 : InvalidOperationException → 422 替换 文档.cs(6 处)+ 交叉引用表.cs + 页树.cs 的裸 InvalidOperationException。 此前读损坏 PDF 会落 **500**(错误契约.按异常分流 不认 InvalidOperationException), 调用方看不出"是文件坏了(该换文件)"。 **基类为什么选 InvalidOperationException**(写在 异常.cs 头注里): 本包定位是"纯 PDF 规范、零依赖"(只引 Sharp.Read/Write),**不能引 Service.Base** (会拖进 Microsoft.AspNetCore.App 框架引用)。基类沿用原实现抛的类型 → 任何既有 catch (InvalidOperationException) 不改也能接住(最小惊喜)。 (InvalidDataException 在 BCL 里是 sealed,当不了基类。) 状态码映射放在 Pdf 自己的壳(Pdf.Server/端点失败.cs,判具体类型 → 422)。 ## A5 读侧输入阈值(新增 Pdf输入过大异常 : ArgumentException → 400) 文档 构造入口加体积检查:路径入口先查大小再 ReadAllBytes,字节入口查数组长。 env 沿用写侧 NONG_PDF_MAX_INPUT_MB(缺省 100MB)——此前读侧无任何上限, 大 PDF 整份读进内存。 新增 Tests/输入阈值测试.cs;交叉引用测试.cs 4 处断言改新类型; 状态码契约测试.cs 加 HTTP 端到端(好件 200 / 坏件 422 / 超大 400)。 实机验证(临时端口 18702,已清理):好件 200 / 坏件 422「输入文件损坏」/ 超大 400「输入错误」。 测试:Parse 83+2跳 → **87+2跳**;Pdf.Server 63 → **67**。 | 3 天前 |
| 缺陷账 E4:不支持的 PDF 特性从 500 归 422(+ 顺带修 7 处"文件损坏"误落 500) ## 判断:归 422,且用专用类型区分"我们没实现"与"文件坏了" 文件存在/完好/参数合法,只是**用了我们没实现的特性** → 422「内容不可处理」; 500 会诱导调用方对同一个文件**无限重试**。 本仓先例:加密版本不支持异常 已按同一理由归 422(端点失败.cs / 解密.cs)。 **不用 501**(语义锚在方法上,会被当 5xx 重试类)。 ## 实现 异常.cs 新增 不支持特性异常 : NotSupportedException; Pdf.Server/端点失败.cs 新增分支 → **422 + 类型="不支持的特性" + 处理[]**。 改抛新类型的能力缺口站点:滤镜.cs(未知滤镜 LZW/RunLength 等)、 图像对象.cs 6 处(JPX / 位深 / 颜色空间 / Indexed)。 **故意不映射普通 NotSupportedException**:展开滤镜名 未传解引用回调属**调用方契约错** (BCL 抛的),继续 500 —— 不掩盖真 bug。 ## 顺带修(新发现) 图像数据不完整 / Indexed 格式异常 / 调色板缺失 / 尺寸≤0 这些**文件损坏**类 原先也是裸 NotSupportedException → 500,与"文件坏了应 422"相反 → 改抛 非法PDF异常 → 422 类型="输入文件损坏"。 (内部降级信号保持原样。) 测试:Parse 87+2跳 → **88+2跳**(+1 用例,1 处断言更新); Pdf.Server 67 → **68**(+1 用例)。 若团队更倾向 501,只需改 端点失败.cs 那个新分支的状态码(单点)。 | 3 天前 |
| 修剩余 15 个 bug(Parse 9 红清零 + 5 个仓的 6 项) ## Pdf.Parse(9 红 → 全绿,81P/0F/2S) 交叉引用表.cs 增量更新新段 trailer 缺 /Root → 改新→旧「首见即取」合并 trailer 图像对象.cs 1-bit 灰度行对齐三处长度统一 ((宽+7)/8)*高 图像对象.cs Indexed 1/4 位深新增 展开索引位流(MSB 先、行对齐、按最大索引扩表) 对象扫描器.cs /Length 间接引用 + 数据含 endstream 截断 → 加长度解析回调 文档.cs 传入长度解引用回调 滤镜.cs /Filter 间接引用 → 展开滤镜名 解引用或诚实报错 滤镜.cs LZW/RunLength/CCITT **静默直通** → 解一段 改白名单 (Flate/ASCIIHex 解,DCT/JPX 直通,余抛)—— 此前与 :88 的注释承诺矛盾 ## 5 个仓的 6 项 Sharp.Color/颜色处理.cs 直方图均衡的 最小累计 恒为 0(break 前漏加当前 bin) → 均匀中灰 (10,10,10) 此前被映射成纯白 Media.Speak/本地合成源.cs 模型定位.取 已保证文件存在,其后的 File.Exists 检查是 **死代码** → 新增 必需模型 门禁,兑现 FileNotFoundException 契约 Vision.Layout/整页兜底.cs scnet 轮询 结果Url="" 却判 is null(**永假**) → 空判超时抛人话异常;非 2xx 补退避(此前 continue 跳过循环尾 delay → 无退避忙轮询) Vision.Formula/乱码检测.cs 有效字符.Length < 2 与注释不符 → == 0 (单字符合法公式 x/1 此前被误判乱码) Vision.Table/表格类型判断.cs 全黑图被判有线表 → 暗底占比 ≥90% 判非有线表 反向验证 3 项改回旧写法均变红。 测试:Parse 81P/0F/2S、Color 10、Speak 7、Layout 39、Formula 43、Table 24 全绿; Info 40P/2S、Text 15、Export 34P/2S、Server 63 与基线一致。 注:两处测试断言改动属"记录性绊线"改写而非迁就失败 (池化缓冲长度被 ArrayPool 桶取整、未解引用 /Filter 新契约必须抛异常)。 新发现未改:图像对象.滤镜链 对 /Filter 间接引用同样静默当无滤镜。 | 3 天前 |
| 埋雷与静默失败:Formula 两处正则/死代码 + Layout 死分支 + Pdf 滤镜间接引用 ## ① 公式后处理.前处理 16 对齐补边 = 死代码 → 删 目标尺寸 是 const 384(= 16×24),对齐高/宽 恒为 384,值 1 灰 pad 的 else 分支永不执行(不是条件写错,是尺寸恒对齐)。删除对齐计算与 else, 张量仍 1×1×384×384,行为不变。 ## ② 公式后处理.修复环境 正则元字符 = 真 bug → 修 @"\\begin\{" + 环境 + @"\}" 里 align* 的 * 被当量词 → 匹配的是 \begin{align} 而非 \begin{align*},**align* 不平衡时永远补不齐**, 且 align* 迭代会误统计普通 align。三处 pattern 改用 Regex.Escape(环境)。 新增 4 条 align* 测试;反向验证:改回旧写法 → 2 条红。 ## ③ 版面后处理.合并包含 外层 if = 死代码 → 删 外层 i∈大图 && j∉大图 + 内层两分支都 continue,等价于紧随的 j∉大图 continue。删外层+内层,保留唯一有效判据。行为不变。 ## ④ Pdf /Filter 间接引用 = 静默当"无滤镜" → 解引用 + 诚实报错 上一轮修了 滤镜.cs 那条链,这条链漏了: 图像对象.滤镜链 不解引用 → 间接 /Filter 落入空链 → **压缩字节当像素** 流对象.解码字节() 不传解引用回调 → Pdf.Text 遇间接 /Filter 会抛 修法:滤镜链 改用 滤镜.展开滤镜名(_流.字典.取("Filter"), _取对象) (该方法 private→public);解码字节 加可选 解引用 参数透传, 4 个有文档上下文的调用点传 文档.取对象。 反向验证:改回旧 switch → 图像测试红(像素 0 vs 120);不传回调 → NotSupportedException 红。 测试全绿:Formula 52 / Layout 43 / Parse 83P+2S / Text 15 / Info 40P+2S / Export 34P+2S / Server 63。 | 3 天前 |
| 缺陷账 E4:不支持的 PDF 特性从 500 归 422(+ 顺带修 7 处"文件损坏"误落 500) ## 判断:归 422,且用专用类型区分"我们没实现"与"文件坏了" 文件存在/完好/参数合法,只是**用了我们没实现的特性** → 422「内容不可处理」; 500 会诱导调用方对同一个文件**无限重试**。 本仓先例:加密版本不支持异常 已按同一理由归 422(端点失败.cs / 解密.cs)。 **不用 501**(语义锚在方法上,会被当 5xx 重试类)。 ## 实现 异常.cs 新增 不支持特性异常 : NotSupportedException; Pdf.Server/端点失败.cs 新增分支 → **422 + 类型="不支持的特性" + 处理[]**。 改抛新类型的能力缺口站点:滤镜.cs(未知滤镜 LZW/RunLength 等)、 图像对象.cs 6 处(JPX / 位深 / 颜色空间 / Indexed)。 **故意不映射普通 NotSupportedException**:展开滤镜名 未传解引用回调属**调用方契约错** (BCL 抛的),继续 500 —— 不掩盖真 bug。 ## 顺带修(新发现) 图像数据不完整 / Indexed 格式异常 / 调色板缺失 / 尺寸≤0 这些**文件损坏**类 原先也是裸 NotSupportedException → 500,与"文件坏了应 422"相反 → 改抛 非法PDF异常 → 422 类型="输入文件损坏"。 (内部降级信号保持原样。) 测试:Parse 87+2跳 → **88+2跳**(+1 用例,1 处断言更新); Pdf.Server 67 → **68**(+1 用例)。 若团队更倾向 501,只需改 端点失败.cs 那个新分支的状态码(单点)。 | 3 天前 |
| 摘除注释里的纯引用尾巴(报告 NN / 审计 P0-NN) 这些编号是当时施工台账的指针,报告本身不在仓里,读者按它查不到任何东西, 只剩一句「(报告 39)」的空引用。编号是句中唯一冗余的,摘掉句子照样成立,所以机械摘除。 不动的那批说清楚:另外 240 处单据号嵌在有信息的句子里(说明某条判据是哪次实测立起来的、 什么形状曾经过不去),删编号会把「为什么」一起删掉;全仓还有约 3670 个日期戳,多是 「2026-10-05 实测驱动」这种出处标注,属于要逐句重写的文档债务,不硬删。 这批的范围与理由记在 knowledge/nong-web-端点改名对照.md。 | 1 天前 |
| 缺陷账 E4:不支持的 PDF 特性从 500 归 422(+ 顺带修 7 处"文件损坏"误落 500) ## 判断:归 422,且用专用类型区分"我们没实现"与"文件坏了" 文件存在/完好/参数合法,只是**用了我们没实现的特性** → 422「内容不可处理」; 500 会诱导调用方对同一个文件**无限重试**。 本仓先例:加密版本不支持异常 已按同一理由归 422(端点失败.cs / 解密.cs)。 **不用 501**(语义锚在方法上,会被当 5xx 重试类)。 ## 实现 异常.cs 新增 不支持特性异常 : NotSupportedException; Pdf.Server/端点失败.cs 新增分支 → **422 + 类型="不支持的特性" + 处理[]**。 改抛新类型的能力缺口站点:滤镜.cs(未知滤镜 LZW/RunLength 等)、 图像对象.cs 6 处(JPX / 位深 / 颜色空间 / Indexed)。 **故意不映射普通 NotSupportedException**:展开滤镜名 未传解引用回调属**调用方契约错** (BCL 抛的),继续 500 —— 不掩盖真 bug。 ## 顺带修(新发现) 图像数据不完整 / Indexed 格式异常 / 调色板缺失 / 尺寸≤0 这些**文件损坏**类 原先也是裸 NotSupportedException → 500,与"文件坏了应 422"相反 → 改抛 非法PDF异常 → 422 类型="输入文件损坏"。 (内部降级信号保持原样。) 测试:Parse 87+2跳 → **88+2跳**(+1 用例,1 处断言更新); Pdf.Server 67 → **68**(+1 用例)。 若团队更倾向 501,只需改 端点失败.cs 那个新分支的状态码(单点)。 | 3 天前 |
| Nong.Pdf 首提交:源码 + README(生命绿×麦穗金头图)+ 许可证 | 1 个月前 |
| Nong.Pdf 首提交:源码 + README(生命绿×麦穗金头图)+ 许可证 | 1 个月前 |
| 摘除注释里的纯引用尾巴(报告 NN / 审计 P0-NN) 这些编号是当时施工台账的指针,报告本身不在仓里,读者按它查不到任何东西, 只剩一句「(报告 39)」的空引用。编号是句中唯一冗余的,摘掉句子照样成立,所以机械摘除。 不动的那批说清楚:另外 240 处单据号嵌在有信息的句子里(说明某条判据是哪次实测立起来的、 什么形状曾经过不去),删编号会把「为什么」一起删掉;全仓还有约 3670 个日期戳,多是 「2026-10-05 实测驱动」这种出处标注,属于要逐句重写的文档债务,不硬删。 这批的范围与理由记在 knowledge/nong-web-端点改名对照.md。 | 1 天前 |
| 缺陷账 D4/A5(本仓侧):专用异常类型 + 读侧输入阈值 ## D4 新增 非法PDF异常 : InvalidOperationException → 422 替换 文档.cs(6 处)+ 交叉引用表.cs + 页树.cs 的裸 InvalidOperationException。 此前读损坏 PDF 会落 **500**(错误契约.按异常分流 不认 InvalidOperationException), 调用方看不出"是文件坏了(该换文件)"。 **基类为什么选 InvalidOperationException**(写在 异常.cs 头注里): 本包定位是"纯 PDF 规范、零依赖"(只引 Sharp.Read/Write),**不能引 Service.Base** (会拖进 Microsoft.AspNetCore.App 框架引用)。基类沿用原实现抛的类型 → 任何既有 catch (InvalidOperationException) 不改也能接住(最小惊喜)。 (InvalidDataException 在 BCL 里是 sealed,当不了基类。) 状态码映射放在 Pdf 自己的壳(Pdf.Server/端点失败.cs,判具体类型 → 422)。 ## A5 读侧输入阈值(新增 Pdf输入过大异常 : ArgumentException → 400) 文档 构造入口加体积检查:路径入口先查大小再 ReadAllBytes,字节入口查数组长。 env 沿用写侧 NONG_PDF_MAX_INPUT_MB(缺省 100MB)——此前读侧无任何上限, 大 PDF 整份读进内存。 新增 Tests/输入阈值测试.cs;交叉引用测试.cs 4 处断言改新类型; 状态码契约测试.cs 加 HTTP 端到端(好件 200 / 坏件 422 / 超大 400)。 实机验证(临时端口 18702,已清理):好件 200 / 坏件 422「输入文件损坏」/ 超大 400「输入错误」。 测试:Parse 83+2跳 → **87+2跳**;Pdf.Server 63 → **67**。 | 3 天前 |