mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-02-15 04:32:24 +00:00
Fix "$*" doing pattern matching if $IFS is wildcard (BUG_IFSGLOBS)
The bug is that "$*", and related expansions such as "${arr[*]}", etc., do pattern matching if the first character of $IFS is a wildcard. For example, the following: IFS=* set -- F '' case BUGFREE in BUG"$*") echo bug ;; esac outputs 'bug'. This bug can be reproduced in every other glob pattern matching context as well, but not in pathname expansion. src/cmd/ksh93/sh/macro.c: varsub(): - When joining fields into one for a "$*"-type expansion, check if a glob pattern matching operation follows (mp->pattern is set). If so, write a preceding backslash to escape the separator. Resolves: https://github.com/ksh93/ksh/issues/489 Resolves: https://github.com/att/ast/issues/12
This commit is contained in:
parent
441dcc0483
commit
9f6841c37e
4 changed files with 49 additions and 3 deletions
5
NEWS
5
NEWS
|
@ -3,6 +3,11 @@ For full details, see the git log at: https://github.com/ksh93/ksh/tree/1.0
|
|||
|
||||
Any uppercase BUG_* names are modernish shell bug IDs.
|
||||
|
||||
2022-07-28:
|
||||
|
||||
- Fixed BUG_IFSGLOBS ("$*" does pattern matching if the first character of
|
||||
$IFS is a wildcard).
|
||||
|
||||
2022-07-27:
|
||||
|
||||
- Fixed a bug introduced on 2022-02-08 where $PPID was incorrect when a script
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
#include <releaseflags.h>
|
||||
|
||||
#define SH_RELEASE_FORK "93u+m" /* only change if you develop a new ksh93 fork */
|
||||
#define SH_RELEASE_SVER "1.0.0-rc.3" /* semantic version number: https://semver.org */
|
||||
#define SH_RELEASE_DATE "2022-07-27" /* must be in this format for $((.sh.version)) */
|
||||
#define SH_RELEASE_SVER "1.0.0-rc.4" /* semantic version number: https://semver.org */
|
||||
#define SH_RELEASE_DATE "2022-07-28" /* must be in this format for $((.sh.version)) */
|
||||
#define SH_RELEASE_CPYR "(c) 2020-2022 Contributors to ksh " SH_RELEASE_FORK
|
||||
|
||||
/* Scripts sometimes field-split ${.sh.version}, so don't change amount of whitespace. */
|
||||
|
|
|
@ -59,7 +59,7 @@ typedef struct _mac_
|
|||
char quote; /* set within double quoted contexts */
|
||||
char lit; /* set within single quotes */
|
||||
char split; /* set when word splitting is possible */
|
||||
char pattern; /* set when file expansion follows */
|
||||
char pattern; /* set when glob pattern expansion or matching follows */
|
||||
char patfound; /* set if pattern character found */
|
||||
char assign; /* set for assignments */
|
||||
char arith; /* set for ((...)) */
|
||||
|
@ -1985,6 +1985,8 @@ retry2:
|
|||
* We're joining fields into one; write the output field separator, which may be multi-byte.
|
||||
* For "$@" it's a space, for "$*" it's the 1st char of IFS (space if unset, none if empty).
|
||||
*/
|
||||
if(mp->pattern) /* avoid BUG_IFSGLOBS */
|
||||
sfputc(sfio_ptr, '\\');
|
||||
if(mode == '@' || !mp->ifsp) /* if expanding $@ or if IFS is unset... */
|
||||
sfputc(sfio_ptr, ' ');
|
||||
else if(mp->ifs) /* else if IFS is non-empty... */
|
||||
|
|
|
@ -313,5 +313,44 @@ three
|
|||
[[ $got == "$exp" ]] || err_exit "Line continuation broken within backtick command substitution" \
|
||||
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
|
||||
|
||||
# ======
|
||||
# BUG_IFSGLOBS: https://github.com/ksh93/ksh/issues/489
|
||||
# "$*" does pattern matching if the first char of $IFS is a wildcard
|
||||
|
||||
IFS=* # output field separator for "$*"
|
||||
set -- F '' # "$*" is now "F*"
|
||||
exp=BUGFREE
|
||||
got=${exp%"$*"} # the quoted "*" in "F*" should not act as a wildcard
|
||||
[[ $got == "$exp" ]] || err_exit 'BUG_IGSGLOBS reproducer 1' \
|
||||
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
|
||||
case BUGFREE in
|
||||
BUG"$*") err_exit 'BUG_IFSGLOBS reproducer 2' ;;
|
||||
BUGFREE) ;;
|
||||
*) err_exit 'BUG_IFSGLOBS reproducer 2 fails badly' ;;
|
||||
esac
|
||||
|
||||
IFS=?
|
||||
exp=abcd
|
||||
set a c
|
||||
got=${exp#"$*"}
|
||||
[[ $got == "$exp" ]] || err_exit 'BUG_IFSGLOBS reproducer 3' \
|
||||
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
|
||||
case abc in
|
||||
"$*") err_exit 'BUG_IFSGLOBS reproducer 4' ;;
|
||||
esac
|
||||
[[ abc = "$*" ]] && err_exit 'BUG_IFSGLOBS reproducer 5'
|
||||
|
||||
# https://unix.stackexchange.com/questions/411001/using-case-and-arrays-together-in-bash/411006#411006
|
||||
IFS='|'
|
||||
arr=(opt1 opt2 opt3)
|
||||
case opt2 in
|
||||
@("${arr[*]}"))
|
||||
err_exit 'BUG_IFSGLOBS reproducer 6' ;;
|
||||
esac
|
||||
[[ opt2 == @("${arr[*]}") ]] && err_exit 'BUG_IFSGLOBS reproducer 7'
|
||||
unset arr
|
||||
|
||||
IFS=$' \t\n'
|
||||
|
||||
# ======
|
||||
exit $((Errors<125?Errors:125))
|
||||
|
|
Loading…
Reference in a new issue