uutils / uutils/coreutils

printf: `"%q" $'\001'\'$'\001'` produces incorrect output

Open
#9,638 2 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

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

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.