From fdb9781ebb5bfa593a959c056204b067451e2fd4 Mon Sep 17 00:00:00 2001 From: Martijn Dekker Date: Wed, 30 Sep 2020 00:34:02 +0200 Subject: [PATCH] Fix 'typeset -xu', 'typeset -xl' (rhbz#1188377) 'typeset -xu' and 'typeset -xl' would export the variable but fail to change case in the value under certain conditions. Original patch: https://src.fedoraproject.org/rpms/ksh/blob/642af4d6/f/ksh-20120801-xufix.patch This applies the patch essentially without change and adds a regression test based on the reproducer provided in the RH bug. Unfortunately there is no description of how the patch works and it's a little obscure to me. As far as I can figure out, the cause of the problem was that nv_newattr() erroneously processed a nonexistent size option-argument such as what can be given to options like typeset -F, e.g. typeset -F3 for 3 digits after the dot. A nonexistent size argument is represented by the value of -1. --- NEWS | 5 +++++ src/cmd/ksh93/bltins/typeset.c | 1 + src/cmd/ksh93/include/version.h | 2 +- src/cmd/ksh93/sh/name.c | 4 +++- src/cmd/ksh93/tests/attributes.sh | 17 +++++++++++++++++ 5 files changed, 27 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 5a04ba33603a..e261d1d0ee24 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,11 @@ For full details, see the git log at: https://github.com/ksh93/ksh Any uppercase BUG_* names are modernish shell bug IDs. +2020-09-30: + +- Fixed: 'typeset -xu' and 'typeset -xl' (export + change case) failed to + change the case of a variable's value in certain conditions. + 2020-09-28: - While executing a ksh-style function, ksh 93u+ ignored all signals for which diff --git a/src/cmd/ksh93/bltins/typeset.c b/src/cmd/ksh93/bltins/typeset.c index dff817b20a05..c013510dd25e 100644 --- a/src/cmd/ksh93/bltins/typeset.c +++ b/src/cmd/ksh93/bltins/typeset.c @@ -94,6 +94,7 @@ int b_readonly(int argc,char *argv[],Shbltin_t *context) memset((void*)&tdata,0,sizeof(tdata)); tdata.sh = context->shp; tdata.aflag = '-'; + tdata.argnum = -1; /* tell nv_newattr() that we should not change size */ while((flag = optget(argv,*command=='e'?sh_optexport:sh_optreadonly))) switch(flag) { case 'p': diff --git a/src/cmd/ksh93/include/version.h b/src/cmd/ksh93/include/version.h index 901a973f463e..a3870c1c8ba3 100644 --- a/src/cmd/ksh93/include/version.h +++ b/src/cmd/ksh93/include/version.h @@ -17,4 +17,4 @@ * David Korn * * * ***********************************************************************/ -#define SH_RELEASE "93u+m 2020-09-28" +#define SH_RELEASE "93u+m 2020-09-30" diff --git a/src/cmd/ksh93/sh/name.c b/src/cmd/ksh93/sh/name.c index 59ff09d8cb54..11d87338b7e1 100644 --- a/src/cmd/ksh93/sh/name.c +++ b/src/cmd/ksh93/sh/name.c @@ -2954,10 +2954,12 @@ void nv_newattr (register Namval_t *np, unsigned newatts, int size) nv_onattr(np,NV_EXPORT); sh_envput(shp->env,np); } - if((n^newatts)==NV_EXPORT) + if((n^newatts)==NV_EXPORT && size==-1) return; } oldsize = nv_size(np); + if(size==-1) + size = oldsize; if((size==oldsize|| (n&NV_INTEGER)) && !trans && ((n^newatts)&~NV_NOCHANGE)==0) { if(size) diff --git a/src/cmd/ksh93/tests/attributes.sh b/src/cmd/ksh93/tests/attributes.sh index a3b61609ca3f..d3c2e0e8d677 100755 --- a/src/cmd/ksh93/tests/attributes.sh +++ b/src/cmd/ksh93/tests/attributes.sh @@ -30,6 +30,23 @@ integer Errors=0 [[ -d $tmp && -w $tmp && $tmp == "$PWD" ]] || { err\_exit "$LINENO" '$tmp not set; run this from shtests. Aborting.'; exit 1; } +# ====== +# as of 93u+, typeset -xu/-xl failed to change case in a value (rhbz#1188377) +# (this test failed to fail when it was added at the end, so it's at the start) +unset test_u test_xu test_txu +typeset -u test_u=uppercase +typeset -xu test_xu=uppercase +typeset -txu test_txu=uppercase +typeset -l test_l=LOWERCASE +typeset -xl test_xl=LOWERCASE +typeset -txl test_txl=LOWERCASE +exp="UPPERCASE UPPERCASE UPPERCASE lowercase lowercase lowercase" +got="${test_u} ${test_xu} ${test_txu} ${test_l} ${test_xl} ${test_txl}" +[[ $got == "$exp" ]] || err_exit "typeset failed to change case in variable" \ + "(expected $(printf %q "$exp"), got $(printf %q "$got"))" +unset ${!test_*} + +# ====== r=readonly u=Uppercase l=Lowercase i=22 i8=10 L=abc L5=def uL5=abcdef xi=20 x=export t=tagged H=hostname LZ5=026 RZ5=026 Z5=123 lR5=ABcdef R5=def n=l for option in u l i i8 L L5 LZ5 RZ5 Z5 r x H t R5 uL5 lR5 xi n