diff --git a/NEWS b/NEWS index bdea546ec..6997b58ba 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,14 @@ For full details, see the git log at: https://github.com/ksh93/ksh Any uppercase BUG_* names are modernish shell bug IDs. +2021-02-01: + +- Fixed: scalar arrays (-a) and associative arrays (-A) of a type created by + 'enum' allowed values not specified by the enum type, corrupting results. + +- Fixed: the "${array[@]}" expansion for associative arrays of a type created + by 'enum' expanded to random numbers instead of the array's values. + 2021-01-30: - The -x option to the 'command' built-in now causes it to bypass built-ins @@ -12,7 +20,7 @@ Any uppercase BUG_* names are modernish shell bug IDs. a command with many arguments was divided into several command invocations. - The 2020-08-16 fix is improved with a compile-time feature test that - detects if and how the OS uses data alignment in the arguments list, + detects if the OS requires extra bytes per argument in the arguments list, maximising the efficiency of 'command -x' for the system it runs on. 2021-01-24: diff --git a/src/cmd/ksh93/bltins/enum.c b/src/cmd/ksh93/bltins/enum.c index 1bb99abf1..672593e17 100644 --- a/src/cmd/ksh93/bltins/enum.c +++ b/src/cmd/ksh93/bltins/enum.c @@ -150,8 +150,7 @@ static void put_enum(Namval_t* np,const char *val,int flags,Namfun_t *fp) } i++; } - if(nv_isattr(np,NV_NOFREE)) - error(ERROR_exit(1), "%s: invalid value %s",nv_name(np),val); + error(ERROR_exit(1), "%s: invalid value %s",nv_name(np),val); } static char* get_enum(register Namval_t* np, Namfun_t *fp) diff --git a/src/cmd/ksh93/include/version.h b/src/cmd/ksh93/include/version.h index 073c261cd..42e2399b7 100644 --- a/src/cmd/ksh93/include/version.h +++ b/src/cmd/ksh93/include/version.h @@ -20,7 +20,7 @@ #define SH_RELEASE_FORK "93u+m" /* only change if you develop a new ksh93 fork */ #define SH_RELEASE_SVER "1.0.0-alpha" /* semantic version number: https://semver.org */ -#define SH_RELEASE_DATE "2021-01-31" /* must be in this format for $((.sh.version)) */ +#define SH_RELEASE_DATE "2021-02-01" /* must be in this format for $((.sh.version)) */ #define SH_RELEASE_CPYR "(c) 2020-2021 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/array.c b/src/cmd/ksh93/sh/array.c index bfc1ba059..9adefe927 100644 --- a/src/cmd/ksh93/sh/array.c +++ b/src/cmd/ksh93/sh/array.c @@ -407,11 +407,7 @@ static Namval_t *array_find(Namval_t *np,Namarr_t *arp, int flag) int nv_arraysettype(Namval_t *np, Namval_t *tp, const char *sub, int flags) { Namval_t *nq; - char *av[2]; - int rdonly = nv_isattr(np,NV_RDONLY); - int xtrace = sh_isoption(SH_XTRACE); Namarr_t *ap = nv_arrayptr(np); - av[1] = 0; sh.last_table = 0; if(!ap->table) { @@ -420,30 +416,20 @@ int nv_arraysettype(Namval_t *np, Namval_t *tp, const char *sub, int flags) } if(nq = nv_search(sub, ap->table, NV_ADD)) { + char *saved_value; + int rdonly = nv_isattr(np,NV_RDONLY); if(!nq->nvfun && nq->nvalue.cp && *nq->nvalue.cp==0) _nv_unset(nq,NV_RDONLY); nv_arraychild(np,nq,0); if(!nv_isattr(tp,NV_BINARY)) - { - sfprintf(sh.strbuf,"%s=%s",nv_name(nq),nv_getval(np)); - av[0] = strdup(sfstruse(sh.strbuf)); - } + saved_value = stkcopy(stkstd,nv_getval(np)); if(!nv_clone(tp,nq,flags|NV_NOFREE)) return(0); - ap->nelem |= ARRAY_SCAN; if(!rdonly) nv_offattr(nq,NV_RDONLY); if(!nv_isattr(tp,NV_BINARY)) - { - if(xtrace) - sh_offoption(SH_XTRACE); - ap->nelem &= ~ARRAY_SCAN; - sh_eval(sh_sfeval(av),0); - ap->nelem |= ARRAY_SCAN; - free((void*)av[0]); - if(xtrace) - sh_onoption(SH_XTRACE); - } + nv_putval(nq,saved_value,0); + ap->nelem |= ARRAY_SCAN; return(1); } return(0); diff --git a/src/cmd/ksh93/sh/name.c b/src/cmd/ksh93/sh/name.c index 5ebf6abbe..4a0b0667c 100644 --- a/src/cmd/ksh93/sh/name.c +++ b/src/cmd/ksh93/sh/name.c @@ -389,6 +389,8 @@ void nv_setlist(register struct argnod *arg,register int flags, Namval_t *typ) if(array&NV_ARRAY) { nv_setarray(np,nv_associative); + if(typ) + nv_settype(np,typ,0); } else { diff --git a/src/cmd/ksh93/tests/enum.sh b/src/cmd/ksh93/tests/enum.sh index 0cd63d96e..6e5fcbb0a 100755 --- a/src/cmd/ksh93/tests/enum.sh +++ b/src/cmd/ksh93/tests/enum.sh @@ -74,4 +74,16 @@ arr[green]=foo read -A arr <<< 'x y z xx yy' [[ ${arr[1]} == ${arr[green]} ]] || err_exit 'arr[1] != arr[green] after read' +# enum arrays didn't block unspecified values +# https://github.com/ksh93/ksh/issues/87 +exp=': Color_t: clr[2]: invalid value WRONG' +got=$(set +x; redirect 2>&1; Color_t -a clr=(red blue WRONG yellow); printf '%s\n' "${clr[@]}") +(((e = $?) == 1)) && [[ $got == *"$exp" ]] || err_exit "indexed enum array, unspecified value:" \ + "expected status 1, *$(printf %q "$exp"); got status $e, $(printf %q "$got")" +exp=': clr: invalid value BAD' +got=$(set +x; redirect 2>&1; Color_t -A clr=([foo]=red [bar]=blue [bad]=BAD); printf '%s\n' "${clr[@]}") +(((e = $?) == 1)) && [[ $got == *"$exp" ]] || err_exit "associative enum array, unspecified value:" \ + "expected status 1, *$(printf %q "$exp"); got status $e, $(printf %q "$got")" + +# ====== exit $((Errors<125?Errors:125))