From: Pádraig Brady Date: Mon, 24 Sep 2018 02:35:24 +0000 (-0700) Subject: echo: always process escapes when POSIXLY_CORRECT is set X-Git-Tag: v8.31~66 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8d328706c6ef0264dffb923f96431af1e26dcddd;p=thirdparty%2Fcoreutils.git echo: always process escapes when POSIXLY_CORRECT is set * src/echo.c (main): Always enable backslash processing if POSIXLY_CORRECT is set. * tests/misc/echo.sh: Add (the first) test for the echo command. * tests/local.mk: Reference the new test. * tests/misc/printf.sh: Update a stale comment. * doc/coreutils.texi (echo invocation). Mention that POSIXLY_CORRECT now always enables backslash processing. * NEWS: Mention the change in behavior. Fixes https://bugs.gnu.org/32703 Issue identified by Eric Blake. --- diff --git a/NEWS b/NEWS index a8fa5f2e43..088810fe8b 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,12 @@ GNU coreutils NEWS -*- outline -*- [This bug was present in "the beginning".] df no longer corrupts displayed multibyte characters on macOS. + [bug introduced with coreutils-8.18] + +** Changes in behavior + + echo now always processes backslash escapes when the POSIXLY_CORRECT + environment variable is set. When possible 'ln A B' now merely links A to B and reports an error if this fails, instead of statting A and B before linking. This diff --git a/doc/coreutils.texi b/doc/coreutils.texi index 30155bb86a..f8339d73f8 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -12608,7 +12608,7 @@ If the @env{POSIXLY_CORRECT} environment variable is set, then when @command{echo}'s first argument is not @option{-n} it outputs option-like arguments instead of treating them as options. For example, @code{echo -ne hello} outputs @samp{-ne hello} instead of -plain @samp{hello}. +plain @samp{hello}. Also backslash escapes are always enabled. POSIX does not require support for any options, and says that the behavior of @command{echo} is implementation-defined if any diff --git a/src/echo.c b/src/echo.c index 9958a8ec63..2aee5acfbd 100644 --- a/src/echo.c +++ b/src/echo.c @@ -108,8 +108,9 @@ int main (int argc, char **argv) { bool display_return = true; + bool posixly_correct = getenv ("POSIXLY_CORRECT"); bool allow_options = - (! getenv ("POSIXLY_CORRECT") + (! posixly_correct || (! DEFAULT_ECHO_TO_XPG && 1 < argc && STREQ (argv[1], "-n"))); /* System V machines already have a /bin/sh with a v9 behavior. @@ -189,7 +190,7 @@ main (int argc, char **argv) just_echo: - if (do_v9) + if (do_v9 || posixly_correct) { while (argc > 0) { diff --git a/tests/local.mk b/tests/local.mk index 84d3469797..5823886f84 100644 --- a/tests/local.mk +++ b/tests/local.mk @@ -237,6 +237,7 @@ all_tests = \ tests/fmt/base.pl \ tests/fmt/long-line.sh \ tests/fmt/goal-option.sh \ + tests/misc/echo.sh \ tests/misc/env.sh \ tests/misc/ptx.pl \ tests/misc/test.pl \ diff --git a/tests/misc/echo.sh b/tests/misc/echo.sh new file mode 100755 index 0000000000..53e87fb71a --- /dev/null +++ b/tests/misc/echo.sh @@ -0,0 +1,66 @@ +#!/bin/sh +# basic tests for echo + +# Copyright (C) 2018 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +prog='env echo' + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ echo + + +# Verify the methods of specifying "Escape": +# Note 4 octal digits are allowed (unlike printf which uses up to 3) +printf '%s\n' . . . . . | tr . '\033' > exp +$prog -n -e '\x1b\n\e\n\33\n\033\n\0033\n' > out || fail=1 +compare exp out || fail=1 + +# Incomplete hex escapes are output as is (unlike printf) +printf '\\x\n' > exp +$prog -n -e '\x\n' > out || fail=1 +compare exp out || fail=1 + +# Always output -- (unlike printf) +$prog -- 'foo' > out || fail=1 +$prog -n -e -- 'foo\n' >> out || fail=1 +cat <<\EOF > exp +-- foo +-- foo +EOF +compare exp out || fail=1 + +# Ensure \c stops processing +$prog -e 'foo\n\cbar' > out || fail=1 +printf 'foo\n' > exp +compare exp out || fail=1 + +# With POSIXLY_CORRECT: +# only -n as the first (separate) option enables option processing +# -E is ignored +# escapes are processed by default +POSIXLY_CORRECT=1 $prog -n -E 'foo\n' > out || fail=1 +POSIXLY_CORRECT=1 $prog -nE 'foo' >> out || fail=1 +POSIXLY_CORRECT=1 $prog -E -n 'foo' >> out || fail=1 +POSIXLY_CORRECT=1 $prog --version >> out || fail=1 +cat <<\EOF > exp +foo +-nE foo +-E -n foo +--version +EOF +compare exp out || fail=1 + +Exit $fail diff --git a/tests/misc/printf.sh b/tests/misc/printf.sh index 8716c56c8c..dccabbe8c8 100755 --- a/tests/misc/printf.sh +++ b/tests/misc/printf.sh @@ -60,9 +60,8 @@ $prog '5 % +d\n' 234 >> out || fail=1 # coreutils-5.0.1, it would print six bytes: "6 \41\n". $prog '6 \41\n' | tr '\41' '!' >> out -# Note that as of coreutils-5.0.1, printf with a format of '\0002x' -# prints a NUL byte followed by the digit '2' and an 'x'. -# By contrast bash's printf outputs the same thing as $(printf '\2x') does. +# Note that as of coreutils-5.0.1, printf with a format of '\0002y' +# prints a NUL byte followed by the digit '2' and a 'y'. $prog '7 \2y \02y \002y \0002y\n' |tr '\0\2' '*=' >> out $prog '8 %b %b %b %b\n' '\1y' '\01y' '\001y' '\0001y'|tr '\1' = >> out