csplit: a `/REGEX/` pattern after a line-number pattern never tests the line the split stopped at
メンテナーはふだん 1 日以内に返信
評価
調査の方向性
The bug is in the csplit implementation, in SplitWriter::do_to_line and SplitWriter::do_to_match. The line-number pattern leaves line N buffered, and do_to_match drains that buffer without testing it. Read the tests in tests/by-util/test_csplit.rs, especially test_line_num_range_with_up_to_match3, which has a NOTE about the wrong behaviour. Done means the three reproduction commands match GNU 9.12 and that NOTE is removed. Open PR #15444 already targets this, so check it before starting.
索引モデルが issue の本文から書いたものです。
説明
After a line-number pattern N, line N is the current line. A following /REGEX/ pattern should test it. uutils csplit starts searching at line N+1, so line N goes into the next file without being tested.
The GNU manual (csplit invocation) says:
n: Create an output file containing the input up to but not including line n (a positive integer).
/regexp/[offset]: Create an output file containing the current line up to (but not including) the next line of the input file that contains a match for regexp.
The only lines the manual excludes from later regexp searches are "lines within a negative offset of a regexp pattern". GNU coreutils 9.12 tests line N:
printf 'a\n1\n2\n' | csplit - 2 '/[0-9]/'
# GNU 9.12: 2 / 0 / 4
# uutils: 2 / 2 / 2 (line "1" matches /[0-9]/ but goes into xx01)
seq 4 | csplit - 3 /3/
# GNU 9.12: 4 / 0 / 4
# uutils: 4 / 4
# csplit: '/3/': match not found (exit 1)
seq 50 > 50.txt; csplit 50.txt 10 /10/ -k
# GNU 9.12: 18 / 0 / 123
# uutils: 18 / 123
# csplit: '/10/': match not found (exit 1)
So lines land in the wrong output file. When the only match is on line N, csplit fails with "match not found", and without -k it deletes the files it already wrote. No options are needed to hit it.
Upstream's tests already note the difference. In tests/by-util/test_csplit.rs, test_line_num_range_with_up_to_match3 (the third command above) has the comment // NOTE: output different than gnu's: the pattern /10/ is matched but should not. GNU does match line 10 there and prints 18 0 123.
Versions. uutils main 2e28cc3042006f5811e05040232b6154bb905465 and the 0.12.0 release binary, Linux x86_64, LC_ALL=C, compared with GNU coreutils 9.12 (and 9.4, which prints the same).
Where. SplitWriter::do_to_line stops at line N and leaves it buffered for the next pattern. SplitWriter::do_to_match then writes the buffered lines into the new split without matching them (// NOTE: drain the buffer of input_iter, no match should be done within.). That is right for lines an earlier regex already looked at, but not for a line held back by a line-number pattern.
Related, in the same function: #6126 (--suppress-matched with a line number that was already passed).
Found with an automated differential tester that compares uutils with GNU 9.12. I reproduced it by hand on main and on 0.12.0.
Reproduction steps
export LC_ALL=C
cd "$(mktemp -d)"
printf 'a\n1\n2\n' | csplit - 2 '/[0-9]/'; echo "exit=$?"
# GNU 9.12: 2 / 0 / 4, exit=0 (xx00 = "a", xx01 = empty, xx02 = "1\n2")
# uutils: 2 / 2 / 2, exit=0 (xx00 = "a", xx01 = "1", xx02 = "2")
rm -f xx*
seq 4 | csplit - 3 /3/; echo "exit=$?"
# GNU 9.12: 4 / 0 / 4, exit=0
# uutils: 4 / 4, "csplit: '/3/': match not found", exit=1
- 主要言語
- Rust
- スター
- 24.3k
- フォーク
- 2.1k
- 平均マージ
- 2日 28分
- マージ済み PR(30日)
- 313
環境構築
このプロジェクトの開発コンテナを、あなたの GitHub アカウントでブラウザ上に起動します。
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
uutils/coreutils のほかの issue
-
fmt -p: an unprefixed last line without a newline gets one added対応中かも @fixfon が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
メンテナーはふだん 1 日以内に返信
-
numfmt: a tab between fields is kept, GNU prints a space対応中かも @fixfon が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
メンテナーはふだん 1 日以内に返信
-
minorbug(mv): invalid mode errors not quoted対応中かも @henrimarconni が 5 日前に担当しました。 オープンU - mv
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
メンテナーはふだん 1 日以内に返信
-
ptx: break file missing path in error message対応中かも @Franklin-Qi が 5 日前に担当しました。 オープンU - ptx
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
uutils/coreutils#15307 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
minorbug(stat): os errno not stripped when failing to flush stdout対応中かも @cestercian が 12 日前に担当しました。 オープンU - stat
難易度 2/5 1〜3時間 初心者へのやさしさ 67/100
uutils/coreutils#15200 · コメント 3 件 ·
メンテナーはふだん 1 日以内に返信
uutils/coreutils の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
longbridge/gpui-kit#3620 ·
メンテナーはふだん 1 日以内に返信
-
corro-client drops the last byte of a response line that has no trailing newline対応中かも @RaphaelFakhri が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
-
proxy: include denial_category in the "proxy request denied" log line対応中かも @sreyas-endor が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 77/100
nolabs-ai/nono#2172 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
enhancement
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
metasequoiaime/msime#9113 ·
メンテナーはふだん 1 日以内に返信
-
[Enhancement] Make use of available space to display more processes when maximized in Memory pageオープン
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
pop-os/cosmic-monitor#126 ·
メンテナーはふだん 1 日以内に返信