csplit: --suffix-format with a huge field width panics (Result::unwrap on a formatter error)
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 24.1k
- Forks
- 2k
- Avg merge
- 1d 5h
- Merged PRs (30d)
- 365
Description
Summary
csplit --suffix-format=FMT accepts a printf-style conversion whose field width is unbounded. A very large width makes the internal formatter return an OutOfMemory error ("formatting width too large"), which is .unwrap()-ed and aborts the process (SIGABRT, exit 134) instead of being reported gracefully. GNU csplit prints csplit: memory exhausted and exits 1.
Steps to reproduce
$ printf 'a\nb\nc\n' > in
$ csplit --suffix-format='%9999999999999999999d' in 1
thread 'main' panicked at src/uu/csplit/src/split_name.rs:67:43:
called `Result::unwrap()` on an `Err` value: Custom { kind: OutOfMemory, error: "formatting width too large" }
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
$ echo $?
134
Expected behavior (GNU)
$ printf 'a\nb\nc\n' > in
$ /usr/bin/csplit --suffix-format='%9999999999999999999d' in 1
csplit: memory exhausted
$ echo $?
1
Root cause
SplitName::get formats the split index into the user-supplied format and unwraps the result:
// src/uu/csplit/src/split_name.rs:65-69
fn get(&self, n: usize) -> String {
let mut v = Vec::new();
self.format.fmt(&mut v, n as u64).unwrap(); // line 67: Err on huge width
String::from_utf8(v).unwrap()
}
Format::parse accepts an arbitrarily large width, and fmt returns Err(OutOfMemory) when that width is unrepresentable; the .unwrap() turns it into an abort.
Related
Same class as #12599 (split -a <huge>), fixed in #12609 by rejecting oversized suffix lengths. This is the csplit-side analogue.
Found by our static analysis tooling.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in src/uu/csplit/src/split_name.rs at SplitName::get and the formatter call on line 67. Run the reported csplit --suffix-format reproduction, then trace how get is used to preserve error handling. Done means the huge-width case reports a memory error and exits 1 instead of panicking, while normal suffix formatting still works.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100