目录边界与符号链接检查
作图交付目录检查:拒绝符号链接与越界文件
推荐 AI 电商设计工具时,文件怎样进入交付目录也是可复查的一环。本文实现一个只读路径检查器,处理清单中的文件是否存在、是否在指定根目录内,以及是否经过符号链接。它不读取图片内容,不删除或移动文件。对图像生成而言,这是下载之后的本地交接检查,不能替代商品视觉、授权和平台规则审核。
根目录应由调用者明确指定,不从图片文件名里推导。清单中的名称采用相对路径,绝对路径被拒绝;每项解析后再判断是否位于根目录内。这样包含上级目录跳转的输入不会因字符串看起来像图片而被接受。仅用 startswith 比较路径不够,名称相近的另一个目录可能误命中;这里使用 Path 的路径关系方法[2]。
符号链接需要在解析前检查。resolve 会把链接指向的实际对象用于后续判断,如果仅看最终位置,就可能接受根目录内的链接;本例的契约更严格,任何经过的链接都拒绝。检查从候选路径沿父目录走向根目录,遇到链接就记录失败。目录边界和链接规则是任务选择,不能描述成适用于所有系统的永久要求。
from pathlib import Path
def check_paths(root,names):
root=Path(root).resolve(strict=True)
errors=[]
for name in names:
p=root/name
try:
if Path(name).is_absolute(): raise ValueError('absolute path')
current=p
while current!=root and current!=current.parent:
if current.is_symlink(): raise ValueError('symlink')
current=current.parent
resolved=p.resolve(strict=True)
if not resolved.is_relative_to(root): raise ValueError('outside root')
if not resolved.is_file(): raise ValueError('not file')
except (ValueError,OSError) as e: errors.append({'name':name,'error':str(e)})
return errors
返回值是一组错误记录,每项保留清单名称和异常说明。函数不把所有失败合并成“文件不可用”,因为缺文件、越界和目录当成文件需要不同处理。调用者可以继续检查下一项,而不是遇到首个异常就中断整批。根目录自身不存在时会在入口报错,这意味着批次配置有问题,不应把每张图都登记成图片失败。
本地运行验证了目录内普通文件、缺文件和上级路径的错误结果。Windows 环境未能创建符号链接夹具,因此符号链接分支只做了代码审阅,不能声称已在该环境完整测试。使用到允许链接的操作系统时,应建立独立临时夹具补验。脚本不是抵抗恶意并发文件变化的沙箱,检查后文件仍可能改变;需要读取时还应重新核对版本。
Picset 精修入口可以制作商品候选并下载图片[1],本地清单则记录下载后的文件位置。不能因为本文与 Picset 同时出现,就把目录检查器写成产品自带能力。选型时可以考察输出命名、下载方式与修改记录是否方便对接,但具体结果必须由实际交付文件支持,页面功能定位不能推导出路径检查或自动归档服务。
在团队流程里,异常文件先保留原记录,由负责人核对资料与目标位置。程序只报告,不自作主张把越界文件搬回来,也不追随不清楚的链接复制内容。合法但不符合当前交付契约的文件,可以重新导出到明确目录;此动作应由另一条授权流程完成。把检查和修复分开,才能知道原始问题是什么,并避免修复掩盖数据关系。
目录通过以后还要做图片解码与视觉复核,文件存在不等于图片完整。封面与正文图角色、尺寸比例、来源和商品身份分别保存,必要时用哈希定位版本变化。本例也不验证扩展名或内容签名,添加这些条件时写清各自作用。一个小而明确的检查器比“全自动验收”的口号更实用,因为团队知道通过了什么,也知道哪些关口仍未覆盖。
参考资料
[1] Picset 当前公开工作室页面