-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add SHOPT_PRINTF_LEGACY: non-compliant printf option parsing
On some systems, the external printf(1) allows formatters that begin with a '-' without a preceding '--' options terminator argument. The acceptance of this obsolete syntax violates POSIX because printf falls under the regular utility syntax guidelines. This situation makes it difficult to add options to printf as an extension (which POSIX allows) while maintaining backward compatibility. But some systems come with old sh scripts that depend on the obsolete printf behaviour, so ksh needs to adapt if it is to be accpeptable as a replacement system shell on these. Illumos, in particular, ships a patched ksh 93u+ 2012-08-01 that completely disables option parsing in printf and replaces it with a kludge that only recognises the POSIX '--' options terminator. This matches some external printf commands but kills 'printf --man' and friends and makes the addition of 'printf -v' impossible. This commit adds a compile-time option that provides good-enough compatibility with the obsolete printf behaviour, while keeping our own built-in printf options usable. By default, this is only compiled in if the external printf(1) command on the system where ksh is built exhibits the obsolete behaviour. It can be manually (de)activated regardless of this by setting SHOPT_PRINTF_LEGACY to 0 or 1 src/cmd/ksh93/SHOPT.sh. src/cmd/ksh93/SHOPT.sh, src/cmd/ksh93/Mamfile: - Add SHOPT_PRINTF_LEGACY compile-time option. - When no value is given, probe if external printf(1) accepts a formatter starting with - without preceding --, and emit a #define for SHOPT_PRINTF_LEGACY if found. src/cmd/ksh93/bltins/print.c: b_print(): - If SHOPT_PRINTF_LEGACY is on and b_print() is called from printf, maximise backward compatibility without killing our options using a two-pronged approach: - If the first argument contains a % or a \, disable option parsing: that is very likely a format operand even if it starts with '-', and it cannot be a valid printf option. - When about to throw an error on an invalid option (c==':'), check if the error occurred on the first argument (note that optget leaves opt_info.index==1 on error in a short option, but 2 on error in a long option). If so, ignore the error and treat the argument as a format operand regardless of content. (Note that for --man, etc., c=='?', which is not affected.) src/cmd/ksh93/sh/shtests: - For the regression tests, we need to check of SHOPT_PRINTF_LEGACY was enabled by default at compile time, which we cannot tell from the SHOPT.sh file. Scan the generated shopt.h file and use its definitions as variables as well, overriding any from SHOPT.sh. src/cmd/ksh93/tests/builtins.sh: - Do not check for correct handling of an invalid option in printf if SHOPT_PRINTF_LEGACY is on.
- Loading branch information
Showing
10 changed files
with
105 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,7 +8,7 @@ valgrindflags='--xml=yes --log-file=/dev/null --track-origins=yes --read-var-inf | |
|
||
USAGE=$' | ||
[-s8? | ||
@(#)$Id: shtests (ksh 93u+m) 2023-05-18 $ | ||
@(#)$Id: shtests (ksh 93u+m) 2024-02-11 $ | ||
] | ||
[-author?David Korn <[email protected]>] | ||
[-author?Glenn Fowler <[email protected]>] | ||
|
@@ -274,9 +274,12 @@ if [[ -d /usr/ucb ]] | |
then PATH=$PATH:/usr/ucb | ||
fi | ||
PATH=$PATH:$d | ||
if [[ $INSTALLROOT && -r $INSTALLROOT/bin/.paths ]] | ||
then PATH=$INSTALLROOT/bin:$PATH | ||
if [[ ! -v INSTALLROOT || $INSTALLROOT != /* ]] | ||
then echo "$0: cannot continue: INSTALLROOT must be set" >&2 | ||
echo "$0: invoke me after 'bin/package use', or via 'bin/shtests' or 'bin/package test'" >&2 | ||
exit 1 | ||
fi | ||
PATH=$INSTALLROOT/bin:$PATH | ||
if [[ ${SHELL%/*} != $INSTALLROOT/bin ]] | ||
then PATH=${SHELL%/*}:$PATH | ||
fi | ||
|
@@ -308,12 +311,27 @@ fi | |
export HOME=$tmp | ||
|
||
# make the SHOPT_* macros available to the tests as environment variables | ||
command unset "${!SHOPT_@}" 2>/dev/null | ||
SHOPT() | ||
{ | ||
[[ $1 == *=* ]] && eval "export SHOPT_${ printf %q "${1%%=*}"; }=${ printf %q "${1#*=}"; }" | ||
} | ||
. "${SHOPTFILE:-../SHOPT.sh}" | ||
unset -f SHOPT | ||
# override with probed values from shopt.h: | ||
# change '#define SHOPT_foo = bar' to 'export SHOPT_foo=bar' and evaluate | ||
if [[ -f $INSTALLROOT/src/cmd/ksh93/shopt.h ]] && | ||
i=$(sed -n $'/^#[ \t]*define[ \t][ \t]*SHOPT_/ { | ||
s/.*define[ \t][ \t]*// | ||
s/[ \t][ \t]*/=/ | ||
s/^/export / | ||
p | ||
}' "$INSTALLROOT"/src/cmd/ksh93/shopt.h) | ||
then eval "$i" || exit | ||
else echo "$0: cannot grep shopt.h" >&2 | ||
exit 1 | ||
fi | ||
|
||
[[ -n $SHOPT_MULTIBYTE ]] || SHOPT_MULTIBYTE=$( LC_ALL=C.UTF-8; x=$'\xc3\xa9'; print $(( ${#x}==1 )) ) | ||
if (( !SHOPT_MULTIBYTE && utf8 && !posix && !compile )) | ||
then echo "-u/--utf8 is unavailable because multibyte support was not compiled in." >&2 | ||
|