The POSIX standard for printf(1) says: > 7. An additional conversion specifier character, b, shall be supported as > follows. The argument shall be taken to be a string that may contain > <backslash>-escape sequences. The following <backslash>-escape sequences > shall be supported: ... > -- "\0ddd", where ddd is a zero, one, two, or three-digit octal number > that shall be converted to a byte with the numeric value specified > by the octal number This is broken due to the Gentoo patch dash-0.5.5.1-octal.patch. Expected result: $ printf '%b' '\0204' | hexdump -C 00000000 84 |.| Actual result: $ printf '%b' '\0204' | hexdump -C 00000000 10 34 |.4| The correct patch to fix bug #337329 appears to be: diff --git a/src/bltin/printf.c b/src/bltin/printf.c index 5f9e81c..19b882f 100644 --- a/src/bltin/printf.c +++ b/src/bltin/printf.c @@ -287,8 +287,7 @@ conv_escape(char *str, int *conv_ch) value = '\\'; goto out; - case '0': case '1': case '2': case '3': - case '4': case '5': case '6': case '7': + case '0': ch = 3; value = 0; do { Reproducible: Always
Having investigated a bit more, my previously proposed patch is wrong because it breaks handling of octal escapes in the printf(1) format string, which do not have a leading zero. The patch attached to bug #337329 [1] is closer but a bit too aggressive. [1] https://bugs.gentoo.org/attachment.cgi?id=247514 The correct patch is: diff --git a/src/bltin/printf.c b/src/bltin/printf.c index 5f9e81c..b17e6dc 100644 --- a/src/bltin/printf.c +++ b/src/bltin/printf.c @@ -260,6 +260,11 @@ conv_escape_str(char *str) ch += k; } while (--i); continue; + } else if ('1' <= ch && ch < '8') { + /* Stop conv_escape handling these as octal. */ + ch = '\\'; + str--; + continue; } /* Finally test for sequences valid in the format string */
(In reply to John Keeping from comment #1) thanks for the heads up, but unfortunately, not even this patch is sufficient. i think we need to plumb down the logic of whether this is `echo` or `printf`.
Upstream is not going to take any patch on this [1], and I agree that dash conforms to POSIX in this area. Since dash has been the default on Debian for a while now, I wonder if Gentoo could just drop the patch and allow the upstream behaviour. I would hope that most problems will already have been caught and fixed. [1] http://article.gmane.org/gmane.comp.shells.dash/1026
(In reply to SpanKY from comment #2) actually, your patch is sufficient if we want echo to conform to XSI. bash doesn't do this by default while dash does. bash requires `shopt -s xpg_echo` to be enabled. for sake of simplicity/size/speed, i think we should neuter dash's echo so it simply writes back exactly what it is given and does not respect any option at all.
(In reply to John Keeping from comment #3) i had a similar discussion a while ago: http://thread.gmane.org/gmane.comp.shells.dash/664 while POSIX gives `echo` wide berth to generate whatever junk it wants when it sees a backslash, that doesn't mean the shell should include (arguably) garbage behavior. i'm just going to neuter the echo and see what happens.
should be all set now in the tree; thanks for the report! Commit message: Replace the octal patch with a dumb echo patch http://sources.gentoo.org/app-shells/dash/dash-0.5.8.1-r2.ebuild?rev=1.1 http://sources.gentoo.org/app-shells/dash/files/dash-0.5.8.1-dumb-echo.patch?rev=1.1
(In reply to SpanKY from comment #5) > i'm just going to neuter the echo and see what happens. JFYI: this change breaks icu, see bug 528022. Of course this is not a fault of dash.
The dumb echo patch breaks sys-apps/pm-utils, too, it looks, if /bin/sh -> dash: From setting PM_DEBUG=true and then running 'pm-suspend': Thu Nov 27 08:53:13 EST 2014: performing suspend + sync + do_suspend + echo -n mem sh: echo: I/O error + r=128 + date + log Thu Nov 27 08:53:14 EST 2014: Awake. That 'echo -n mem' fails because I'll bet the '-n' is echoed in the output and fails whatever it was trying to do. I'll create a bug for this later on. Just documenting it here in case anyone else comes searching...
This patch also breaks, among other things, ncurses' configure script: http://mika.l3ib.org/tmp/42d8b8166e889bf39e344301380a1cc8.txt First run is with patch, second is without.
(In reply to Joshua Kinard from comment #8) (In reply to Mikael Magnusson from comment #9) packages that rely on `echo -n` are broken. please file bugs for them, and perhaps contact the respective upstreams as well. it's pretty trivial to resolve in a portable way: -echo -n foo +printf "%s\n" foo