uutils / uutils/coreutils

csplit: --suffix-format with a huge field width panics (Result::unwrap on a formatter error)

Open Beginner friendly
#12,763 5 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

U - csplit
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.