diff --git a/NEWS b/NEWS index d4427c5f9bb1..bbeb0cba5711 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,11 @@ This documents significant changes in the dev branch of ksh 93u+m. For full details, see the git log at: https://github.com/ksh93/ksh Uppercase BUG_* IDs are shell bug IDs as used by the Modernish shell library. +2024-08-19: + +- Fixed a corner-case bug: for an empty set of positional parameters, + "$@$@" would generate one empty field instead of zero fields like "$@". + 2024-07-31: - Fixed a bug where printf %T, after having printed the time in UTC once diff --git a/src/cmd/ksh93/include/version.h b/src/cmd/ksh93/include/version.h index a81d9a32cf93..c5fd7dae8244 100644 --- a/src/cmd/ksh93/include/version.h +++ b/src/cmd/ksh93/include/version.h @@ -18,7 +18,7 @@ #define SH_RELEASE_FORK "93u+m" /* only change if you develop a new ksh93 fork */ #define SH_RELEASE_SVER "1.1.0-alpha" /* semantic version number: https://semver.org */ -#define SH_RELEASE_DATE "2024-08-01" /* must be in this format for $((.sh.version)) */ +#define SH_RELEASE_DATE "2024-08-19" /* must be in this format for $((.sh.version)) */ #define SH_RELEASE_CPYR "(c) 2020-2024 Contributors to ksh " SH_RELEASE_FORK /* Scripts sometimes field-split ${.sh.version}, so don't change amount of whitespace. */ diff --git a/src/cmd/ksh93/sh/macro.c b/src/cmd/ksh93/sh/macro.c index 0d2f3407411f..4164a9f52deb 100644 --- a/src/cmd/ksh93/sh/macro.c +++ b/src/cmd/ksh93/sh/macro.c @@ -60,6 +60,7 @@ typedef struct _mac_ char *ifsp; /* pointer to IFS value */ int fields; /* number of fields */ short quoted; /* set when word has quotes */ + short atspecial; /* quoted count at which special-casing for "$@" with no PPs has been applied */ unsigned char ifs; /* first byte of IFS */ char atmode; /* when processing $@ */ char quote; /* set within double quoted contexts */ @@ -1882,9 +1883,9 @@ static int varsub(Mac_t *mp) if(v || c=='/' && offset>=0) stkseek(stkp,offset); } - /* check for quoted @ */ - if(mode=='@' && mp->quote && !v && c!='-') - mp->quoted-=2; + /* discount the quotes around $@ if there are zero PPs, so that empty "$@" generates zero fields */ + if(mode=='@' && mp->quote && !v && c!='-' && mp->atspecial != mp->quoted) + mp->quoted -= 2, mp->atspecial = mp->quoted; retry2: if(v && (!nulflg || *v ) && c!='+') { diff --git a/src/cmd/ksh93/tests/quoting.sh b/src/cmd/ksh93/tests/quoting.sh index 15d2daf49c50..0f89ced62746 100755 --- a/src/cmd/ksh93/tests/quoting.sh +++ b/src/cmd/ksh93/tests/quoting.sh @@ -2,7 +2,7 @@ # # # This software is part of the ast package # # Copyright (c) 1982-2011 AT&T Intellectual Property # -# Copyright (c) 2020-2022 Contributors to ksh 93u+m # +# Copyright (c) 2020-2024 Contributors to ksh 93u+m # # and is licensed under the # # Eclipse Public License, Version 2.0 # # # @@ -369,4 +369,33 @@ case x in $x) err_exit "case \$x='$x' should not match x";; esac +# ====== +# https://austingroupbugs.net/view.php?id=1852 +# https://mail.gnu.org/archive/html/bug-bash/2024-08/msg00132.html +unset e E q i +for e in 3 '"$@"' 5 '"$@$@"' 7 '"$@$@$@"' 9 '"$@$@$@$@"' 11 '"$@$@$@$@$@"' 13 '"$@$@$@$@$@$@"' \ + 5 '"$@""$@"' 7 '"$@""$@""$@"' 9 '"$@""$@""$@""$@"' 11 '"$@""$@""$@""$@""$@"' 13 '"$@""$@""$@""$@""$@""$@"' +do [[ $e == [0-9]* ]] && i=$e && continue + set -- # set zero PPs + eval "set -- $e" + (($# == 0)) || err_exit "$e does not yield zero fields for zero positional parameters (got $#)" + set -- one two three + eval "set -- $e" + (($# == i)) || err_exit "$e does not yield $i fields for 3 positional parameters (got $#)" + for q in "''" '""' + do for q in "$q" "$q$q" "$q$q$q" "$q$q$q$q" "$q$q$q$q$q" "$q$q$q$q$q$q" + do for E in "$q$e" "$e$q" "$q$e$q" + do set -- # set zero PPs + eval "set -- $E" + (($# == 1)) || err_exit "$E does not yield one field for zero positional parameters (got $#)" + set -- one two three + eval "set -- $E" + (($# == i)) || err_exit "$E does not yield $i fields for 3 positional parameters (got $#)" + done + done + done + ((i+=2)) +done + +# ====== exit $((Errors<125?Errors:125))