>From 81802d8daf94684300b55272d171e65b53d5fede Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Mon, 6 Dec 2010 17:10:31 +0100 Subject: [PATCH] echo,printf,stat: Allow only 8-bit octal input for backslash-escaped chars * src/echo.c: (usage) Document \NNN octal format in --help (main) Allow only 8-bit octal input for backslash-escaped chars * src/printf.c: (print_esc) Likewise * src/stat.c: (print_it) Likewise * doc/coreutils.texi: Clarify printf documentation about byte octal input * tests/misc/printf: Add test for "like 9-bit" octal value backslash-escaped char --- NEWS | 4 ++++ doc/coreutils.texi | 6 +++--- src/echo.c | 7 ++++++- src/printf.c | 10 +++++++--- src/stat.c | 4 +++- tests/misc/printf | 3 +++ 6 files changed, 26 insertions(+), 8 deletions(-) diff --git a/NEWS b/NEWS index c3110a3..c8a45ee 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,10 @@ GNU coreutils NEWS -*- outline -*- sort -u with at least two threads could attempt to read through a corrupted pointer. [bug introduced in coreutils-8.6] + echo, printf and stat now don't allow 9-bit octal values for + backslash-escaped chars. + + ** New features split accepts the --number option to generate a specific number of files. diff --git a/doc/coreutils.texi b/doc/coreutils.texi index 34d9ff0..11a9d16 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -11116,9 +11116,9 @@ the command @samp{printf %g 3,14} is an error. @kindex address@hidden @kindex address@hidden @command{printf} interprets @address@hidden in @var{format} as an octal number -(if @var{ooo} is 1 to 3 octal digits) specifying a character to print, -and @address@hidden as a hexadecimal number (if @var{hh} is 1 to 2 hex -digits) specifying a character to print. +(if @var{ooo} is 1 to 3 octal digits byte value) specifying a character +to print, and @address@hidden as a hexadecimal number (if @var{hh} is +1 to 2 hex digits) specifying a character to print. @kindex \uhhhh @kindex \Uhhhhhhhh diff --git a/src/echo.c b/src/echo.c index 6a1eeed..b72dcd5 100644 --- a/src/echo.c +++ b/src/echo.c @@ -78,6 +78,7 @@ If -e is in effect, the following sequences are recognized:\n\ "), stdout); fputs (_("\ \\0NNN byte with octal value NNN (1 to 3 digits)\n\ + \\NNN byte with octal value NNN (1 to 3 digits)\n\ \\xHH byte with hexadecimal value HH (1 to 2 digits)\n\ "), stdout); printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME); @@ -197,6 +198,7 @@ just_echo: { char const *s = argv[0]; unsigned char c; + bool threeoctdigits = false; while ((c = *s++)) { @@ -235,12 +237,15 @@ just_echo: c = *s++; /* Fall through. */ case '1': case '2': case '3': + if (c < '4') + threeoctdigits = true; case '4': case '5': case '6': case '7': c -= '0'; if ('0' <= *s && *s <= '7') c = c * 8 + (*s++ - '0'); - if ('0' <= *s && *s <= '7') + if (threeoctdigits && '0' <= *s && *s <= '7') c = c * 8 + (*s++ - '0'); + threeoctdigits = false; break; case '\\': break; diff --git a/src/printf.c b/src/printf.c index 1f5451e..ca05118 100644 --- a/src/printf.c +++ b/src/printf.c @@ -236,6 +236,7 @@ print_esc (const char *escstart, bool octal_0) const char *p = escstart + 1; int esc_value = 0; /* Value of \nnn escape. */ int esc_length; /* Length of \nnn escape. */ + int max_octdigits = 3; /* Maximum length of byte octal input. */ if (*p == 'x') { @@ -252,9 +253,12 @@ print_esc (const char *escstart, bool octal_0) { /* Parse \0ooo (if octal_0 && *p == '0') or \ooo (otherwise). Allow \ooo if octal_0 && *p != '0'; this is an undocumented - extension to POSIX that is compatible with Bash 2.05b. */ - for (esc_length = 0, p += octal_0 && *p == '0'; - esc_length < 3 && isodigit (*p); + extension to POSIX that is compatible with Bash 2.05b. + If the octal character begins with number 4 or higher, + only 2 octal digits fit to byte */ + for (esc_length = 0, p += octal_0 && *p == '0', + max_octdigits -= '4' <= *p; + esc_length < max_octdigits && isodigit (*p); ++esc_length, ++p) esc_value = esc_value * 8 + octtobin (*p); putchar (esc_value); diff --git a/src/stat.c b/src/stat.c index b419f19..005aa8e 100644 --- a/src/stat.c +++ b/src/stat.c @@ -1096,7 +1096,9 @@ print_it (char const *format, char const *filename, { int esc_value = octtobin (*b); int esc_length = 1; /* number of octal digits */ - for (++b; esc_length < 3 && isodigit (*b); + int max_octdigits = 3; /* maximum length of byte octal input */ + for (max_octdigits -= '4' <= *b, ++b; + esc_length < max_octdigits && isodigit (*b); ++esc_length, ++b) { esc_value = esc_value * 8 + octtobin (*b); diff --git a/tests/misc/printf b/tests/misc/printf index b02352b..9c99853 100755 --- a/tests/misc/printf +++ b/tests/misc/printf @@ -72,6 +72,8 @@ POSIXLY_CORRECT=1 \ "$prog" '11 %*c\n' 2 x >>out || fail=1 +"$prog" '12 \0610\n' >>out || fail=1 + "$prog" '%#d\n' 0 >>out 2> /dev/null && fail=1 "$prog" '%0s\n' 0 >>out 2> /dev/null && fail=1 @@ -92,6 +94,7 @@ cat <<\EOF > exp 9 0 x 10 0x 11 x +12 10 EOF compare out exp || fail=1 -- 1.7.1