printf: `"%q" $'\001'\'$'\001'` produces incorrect output
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 24.1k
- Forks
- 2k
- Avg merge
- 1d 5h
- Merged PRs (30d)
- 365
Description
I've randomly stumbled across https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=992161, a bugreport against GNU Coreutils that they fixed in v9.6.
However, it turns out Rust Coreutils also produces incorrect output for the same command (a different incorrect output than GNU Coreutils used to).
At current main HEAD:
prompt$ ./target/release/coreutils printf "%q\n" $'\001'\'$'\001'
"'$'\001''''$'\001"
The last cmdline parameter is a 3-byte string: a 0x01 byte, an apostrophe, and one more 0x01.
The output is supposed to be a string which, if placed in a shell command line in unquoted context, produces the same string.
However, this output expands to 17 bytes (tested in busybox ash, bash, dash, ksh, mksh, zsh):
prompt$ printf "%s" "'$'\001''''$'\001" | od -t x1
0000000 27 24 27 5c 30 30 31 27 27 27 27 24 27 5c 30 30
0000020 31
0000021
The string, after shell expansion, obviously starts with an apostrophe which is already wrong, and also has multiple literal apostrophes in the middle. Even if the $'\001' construct was interpreted inside double quotes (which it is not), the missing trailing ' in the second such string would also pose a problem.
The first command's output, if copy-pasted into the second command's corresponding parameter, needs to output the same 3 bytes mentioned above, e.g.:
# bash 5.2.37's builtin printf
prompt$ printf "%q\n" $'\001'\'$'\001'
$'\001\'\001'
prompt$ printf "%s" $'\001\'\001' | od -t x1
0000000 01 27 01
0000003
# GNU Coreutils current main HEAD's printf
prompt$ ./src/printf "%q\n" $'\001'\'$'\001'
''$'\001'\'''$'\001'
prompt$ printf "%s" ''$'\001'\'''$'\001' | od -t x1
0000000 01 27 01
0000003
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 with the Rust coreutils printf entry point and reproduce the reported command using the byte sequence 0x01, apostrophe, 0x01. Compare its output with the bash and GNU Coreutils examples, then verify that the generated unquoted shell text round-trips to the same three bytes.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust, shell
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100