diff panics (broken-pipe unwrap) when its stdout is closed early
还没有人认领这个 Issue。
评估
调研方向
从 src/diff.rs:94 和 src/side_diff.rs:353-356 中确定的输出写入开始,然后使用提供的 seq、sed 和 head 命令复现普通模式和并排模式。验证向已关闭管道输出不再触发 panic 或打印错误,并且两种模式都像 GNU diff 一样以预期的 SIGPIPE 状态终止。
由索引模型根据 Issue 内容生成。
描述
Summary
When diff's standard output is a pipe whose reader closes early (e.g. diff … | head), uutils diff aborts with a panic (exit 134, core dump)
instead of dying cleanly to SIGPIPE like GNU (exit 141). The output is written with a bare .unwrap() on the write_all/push_output result; the BrokenPipe error is unwrapped and, under panic="abort", aborts the process. This affects every output mode: the normal/context/unified/ed path writes the buffered result in src/diff.rs:94, and the side-by-side (-y) path writes each line in src/side_diff.rs:353-356.
Steps to reproduce
$ seq 1 100000 > b1; seq 1 100000 | sed 's/5/X/' > b2
$ diffutils diff b1 b2 | head -1
thread 'main' panicked at src/diff.rs:94:41:
called `Result::unwrap()` on an `Err` value: Os { code: 32, kind: BrokenPipe, message: "Broken pipe" }
$ echo "${PIPESTATUS[0]}"
134
Side-by-side mode hits the sibling site src/side_diff.rs:353:
$ diffutils diff -y b1 b2 | head -1
thread 'main' panicked at src/side_diff.rs:353:87:
called `Result::unwrap()` on an `Err` value: Os { code: 32, kind: BrokenPipe, message: "Broken pipe" }
$ echo "${PIPESTATUS[0]}"
134
Expected behavior
Match GNU: a closed output pipe terminates the program via SIGPIPE (exit 141) with no error message and no core dump.
$ /usr/bin/diff b1 b2 | head -1
1c1
$ echo "${PIPESTATUS[0]}"
141
$ /usr/bin/diff -y b1 b2 | head -1
1 < 1
$ echo "${PIPESTATUS[0]}"
141
Root cause
The full diff output (normal/context/unified/ed) is buffered and written once:
// src/diff.rs:94
io::stdout().write_all(&result).unwrap();
Side-by-side writes each line straight to the locked stdout and unwraps every
write:
// src/side_diff.rs:353-356
push_output(...).unwrap(); // and the sibling unwraps at :354, :356
Any write_all/push_output error — BrokenPipe in the common pipe-closed case — is unwrapped and aborts.
Found by our static analysis tooling.
- 主要语言
- Rust
- 星标
- 276
- 派生
- 39
- 平均合并
- 4 天 12 小时
- 30 天内合并 PR
- 3
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
uutils/diffutils 的其他 Issue
-
难度 2/5 1-3 小时 新手友好度 70/100
-
难度 2/5 1-3 小时 新手友好度 85/100
-
难度 2/5 1-3 小时 新手友好度 72/100
-
难度 2/5 1-3 小时 新手友好度 68/100
-
难度 4/5 3-5 天 新手友好度 45/100
相似的 Issue
-
bug github_actions
难度 2/5 1-3 小时 新手友好度 75/100
registrystack/registry-stack#1393 ·
-
难度 2/5 1-3 小时 新手友好度 75/100
longbridge/gpui-kit#3223 ·
-
bug engine
难度 2/5 1-3 小时 新手友好度 65/100
rocky-data/rocky#2181 ·
-
难度 2/5 1-3 小时 新手友好度 70/100
oasisprotocol/oasis-sdk#2523 ·
-
bot:ai-assisted component:indexer QA-roadmap status:untriaged
难度 2/5 1-3 小时 新手友好度 75/100
midnightntwrk/midnight-indexer#1557 ·