Skip to content

echo: don't expand \u, \U and \" in -e - #14475

Merged
cakebaker merged 1 commit into
uutils:mainfrom
SichenLiang:echo-no-unicode-escapes
Sep 10, 2026
Merged

cakebaker merged 1 commit into
uutils:mainfrom
SichenLiang:echo-no-unicode-escapes

Conversation

@SichenLiang

@SichenLiang SichenLiang commented Sep 9, 2026 •

Copy link
Copy Markdown
Contributor

uutils' echo -e expands \u, \U and \". GNU's echo has none of the three and
prints them as written. Our own --help already lists only the sequences GNU has:

\ \a \b \c \e \f \n \r \t \v \0NNN \xHH

so the implementation is the outlier here, not the documentation.

echo -e '[\u0041]'        GNU [\u0041]        before [A]    after [\u0041]
echo -e '[\U00000041]'    GNU [\U00000041]    before [A]    after [\U00000041]
echo -e '[\"]'            GNU [\"]            before ["]    after [\"]

Malformed forms were losing text as well, since parse_unicode consumes its digit
window before validating it:

echo -e '[\uzzzz]'        GNU [\uzzzz]        before [\x]   after [\uzzzz]

printf keeps all three, on its format string and on %b, and is byte identical
before and after across the escapes I tested, exit status and stderr included.

Measured against GNU coreutils 9.11, LC_ALL=C.

This touches escape.rs, mod.rs and echo.rs, which #14406 also edits. A trial merge
gives five mechanical conflict hunks and no semantic disagreement, so whichever lands
first the other is a small re-resolve.

Fixes #14414

@github-actions

github-actions Bot commented Sep 9, 2026 •

Copy link
Copy Markdown

GNU testsuite comparison:

Skipping an intermittent issue tests/cut/bounded-memory (passes in this run but fails in the 'main' branch)
Skipping an intermittent issue tests/date/date-locale-hour (passes in this run but fails in the 'main' branch)
Congrats! The gnu test tests/cp/link-heap is now passing!
Congrats! The gnu test tests/tail/pipe-f is now passing!

GNU's echo recognizes only \a \b \c \e \f \n \r \t \v \\ \0NNN \NNN and
\xHH after -e.  uucore's escape parser is shared with printf, which also
recognizes \", \uHHHH and \UHHHHHHHH, so echo -e picked those up as well:
echo -e '\u0041' printed A instead of \u0041.

Add an EscapeSet parameter alongside the existing OctalParsing one, and
have echo ask for the set without \", \u and \U.  Those three then fall
through to the unknown-escape arm and are emitted verbatim, backslash
included, which is what GNU does.  printf keeps the full set on both its
format-string and %b paths.
@SichenLiang
SichenLiang force-pushed the echo-no-unicode-escapes branch from 0cbc779 to ff1614b Compare September 9, 2026 12:45
@cakebaker
cakebaker merged commit f604ab9 into uutils:main Sep 10, 2026
175 checks passed
@cakebaker

Copy link
Copy Markdown
Contributor

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

echo: -e expands \u and \U, GNU echo prints them literally

2 participants