报告生成成功之后,原文件还在吗:一次PPT输出路径覆盖实测
文档差异工具输出“报告已生成”时,我们通常会去看报告是否清楚、差异是否准确。还应核对另一件事:两份输入文档有没有保持原样。今天在PPT-diff的HTML报告模式中,我用合成文件复现了一种输出路径误用:把报告路径选成输入PPTX,程序完成解析和比较后,会将对应输入替换为HTML,最后仍正常返回。
这次测试没有使用个人或业务演示文稿,也没有启动PowerPoint。全部输入由脚本临时生成;唯一关闭的动作,是CLI末尾可选的自动打开文件。解析、比较、输出路径处理和HTML写入都执行上游原代码。问题已提交为Issue #73,本文记录验证方法,不把建议写成已经合并的修复。
输入有效,为什么仍然会丢失
实测版本固定在main提交db6c75892650854abf663c91b66ead486fde1299,环境为Windows、Python 3.12.14和python-pptx 1.0.2。两份输入各有一页、一个普通文本框,文字分别为Budget 100和Budget 120。输入格式合法,可以独立解析,差异比较也能识别文字发生变化。
问题出现在更靠后的输出步骤。scripts/main.py取出args.output,转成绝对路径后交给报告生成器;scripts/report_generator.py用写模式打开目标。目标如果就是旧版或新版PPTX,写模式会先截断已有文件,然后写入HTML。此前成功读取了输入,并不能保护它免受后续写操作影响。Python的open官方文档明确区分了截断写入的w和独占创建的x。
因此,只验证输入存在、能打开、能解析,覆盖不到这类错误。这里需要检查的是输入与输出之间的关系。文件扩展名也不能充当隔离措施:PPTX后缀的路径仍然可以被当作文本目标写入,真正的格式取决于文件内容。
四个对照实验
我为每个场景重新生成两份测试文件,运行前分别计算SHA256,运行后再次计算,同时用zipfile.is_zipfile()检查PPTX的ZIP结构。不同场景没有复用上一轮已被覆盖的文件,避免把初始损坏混进结果。
| 报告目标 | 旧版摘要保持 | 新版摘要保持 | 结构检查 |
|---|---|---|---|
| 独立report.html | 是 | 是 | 两份输入仍是ZIP |
| 旧版old.pptx | 否 | 是 | 旧版不再是ZIP |
| 新版new.pptx | 是 | 否 | 新版不再是ZIP |
| not-used/../old.pptx | 否 | 是 | 旧版不再是ZIP |
第四组的中间目录也由脚本创建。它与直接写old.pptx最终指向同一位置,用来证明不能只比较用户输入的两段路径字符串。四组都没有抛出异常,三组覆盖场景也都打印了报告生成成功。相反,第一组正常生成HTML的同时,两份输入摘要和结构均保持不变。
摘要变化和结构检查回答不同的问题。SHA256变化说明字节内容发生变化;结构检查说明它已经不能作为普通PPTX压缩包读取。再读取被覆盖测试文件中的HTML标记,可以把损坏直接关联到报告写入,而不是含糊地归因于解析器或PowerPoint兼容性。
把“未修改输入”纳入验收
测试中使用的核心核对很短,下面是已经执行过的检查方式。before在运行CLI前保存,new仅指本次新建的合成输入;完整安全复现脚本放在Issue中,不要拿真实文档测试覆盖。
from hashlib import sha256
from zipfile import is_zipfile
before = sha256(new.read_bytes()).hexdigest()
# 在新建测试目录中执行目标CLI,然后核对:
input_preserved = before == sha256(new.read_bytes()).hexdigest()
still_pptx_zip = is_zipfile(new)
正常报告场景要求两份输入的摘要都保持。拒绝危险输出时,也应在返回后核对摘要,防止程序先动了文件、随后才发现冲突。不能只断言某个错误字符串出现,或者只检查退出码。
这个方法同样适用于转换器、图片压缩脚本和批量导出工具:先确定哪些输入必须只读,再在成功和失败两条路径上检查它们。测试数据应由程序生成,输出也放在明确的新目录;发生预期内的破坏时,受影响的只应是这批可丢弃样本。
路径检查还要区分哪些边界
修复方向是写入前识别输出是否指向任一输入。路径规范化可以处理部分相对路径与..差异;目标已存在时,还需要判断文件身份,而不是只看名字。Path.samefile官方文档说明了同一文件判断及可能抛出的访问错误。不能把访问失败默认当成安全。
本次实际验证了直接相等和..别名,没有执行硬链接、符号链接或并发替换测试。这些是后续应补的验收项,不能从现有四组结果推导为全部通过。对于不需要覆盖已有报告的工作流,独占创建输出能进一步减少误覆盖;需要主动覆盖时,也应把“覆盖旧报告”和“覆盖输入文档”分成不同判断。
这次没有修改上游程序,也没有宣称一段路径比较能解决全部文件系统竞争。当前可确认的是:有效输入会被最终输出步骤覆盖,且普通独立报告控制组没有这个问题。让“成功生成输出”和“保持输入完整”都成为可检查的条件,文档工具的验收才覆盖到保存环节。
- 点赞
- 收藏
- 关注作者
评论(0)