危险指令¶
这个项目里有一类命令必须被单独看待:危险命令。
什么叫危险命令¶
危险命令通常具有以下特征之一:
- 会删除文件;
- 会覆盖工作区内容;
- 会改写 refs;
- 会批量写对象;
- 会对仓库状态做不可逆前进。
典型例子包括:
reset --hardcheckoutswitchrmstash popupdate-ref- pack 解包
- fetch / push / clone 中的目标路径和 ref 更新
为什么它们必须单独设计¶
因为这类命令的 bug 代价很高。
它们不像普通文本处理逻辑,出错了可以重试一下就过去。
出错时,最坏情况可能是:
- 用户文件被删;
- 仓库状态半写入;
- 分支指针错误移动;
- 工作区和 index 脱节。
必须做哪些保护¶
最关键的保护包括:
- 路径必须在仓库内部;
- 防止
..路径逃逸; - 防止绝对路径误操作;
- 防止符号链接逃逸;
- 删除前确认文件是可解释的追踪文件;
- 删除前确认目标对象和 tree 是可读的;
- 用锁文件和原子替换保护元数据写入。
项目把这些保护写进工程要求,是因为“事后补安全”通常补不干净。