Skip to content

echo escape conformance: xpg_echo + the \0nnn octal rule (batch83) - #284

Merged
brianjfox merged 2 commits into
mainfrom
fix/testsuite-batch83
Jul 24, 2026
Merged

echo escape conformance: xpg_echo + the \0nnn octal rule (batch83)#284
brianjfox merged 2 commits into
mainfrom
fix/testsuite-batch83

Conversation

@brianjfox

Copy link
Copy Markdown
Owner

Summary

Two related echo escape-handling fixes surfaced by builtins2.sub (builtins byte-diff 179 → 172, no regressions).

1. echo octal is \0nnn, not a bare \nnn

bash's echo (with -e, and with xpg_echo) accepts only the \0nnn octal escape; a bare \1..\7 stays literal — unlike printf %b, which interprets \nnn. gnash's shared decode_b interpreted the bare form in both, so echo -e "\101" printed A instead of literal \101. Added a bare_octal parameter (default true, preserving printf %b) and pass false from echo.

2. honor the xpg_echo shopt

shopt -s xpg_echo now makes echo interpret backslash escapes by default (as if -e), matching bash (do_v9 = xpg_echo). In POSIX mode with xpg_echo, option parsing is skipped entirely so -n/-e/-E print literally (bash's posixly_correct && xpg_echo short-circuit). gnash previously recognized the shopt name but ignored it.

$ shopt -s xpg_echo; echo 'a\tb'      →  a<TAB>b
$ echo -e '\101 \0101'               →  \101 A
$ printf '%b\n' '\101'               →  A

Testing

  • ctest 22/22
  • Scoreboard: builtins 179 → 172, zero regressions across the full suite
  • builtins2.sub now matches bash byte-for-byte; verified octal/hex/xpg/posix cases against bash 5.3

Closes #283.

bash's echo (with -e, and with xpg_echo) accepts only the \0nnn octal escape;
a bare \1..\7 is left literal, unlike printf's %b which does interpret \nnn
(echo.def vs printf.def).  gnash's shared decode_b interpreted the bare form in
both, so `echo -e "\101"' printed `A' instead of the literal `\101'.

Add a bare_octal parameter (default true, preserving printf %b) and pass false
from echo, so a bare \nnn stays literal there while \0nnn still decodes.
`shopt -s xpg_echo' should make echo interpret backslash escapes by default, as
if `-e' were given (bash echo.def: do_v9 = xpg_echo).  gnash recognized the
shopt name but never acted on it.  Initialize echo's escape interpretation from
xpg_echo, and -- matching bash's `posixly_correct && xpg_echo' short-circuit --
skip option parsing entirely in POSIX mode with xpg_echo, so -n/-e/-E are then
printed literally.

Closes #283.
@brianjfox
brianjfox merged commit a6d7715 into main Jul 24, 2026
1 check passed
@brianjfox
brianjfox deleted the fix/testsuite-batch83 branch July 24, 2026 16:46
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 does not honor the xpg_echo shopt

1 participant