From bafff8eca28d201c052d4ca4edf109a8302a9131 Mon Sep 17 00:00:00 2001 From: Martijn Dekker Date: Tue, 7 Jun 2022 17:52:12 +0100 Subject: [PATCH] Fix crash on setting attribute to variable with getn discipline The 'getn' discipline is experimental and undocumented, the only mention of it being an old mailing list post from David Korn: https://www.mail-archive.com/ast-users@research.att.com/msg00601.html But it still should not crash. $ LC_NUMERIC=C ENV=/./dev/null arch/*/bin/ksh $ foo.getn() { .sh.value=2.3*4.5; } $ typeset -F foo Memory fault src/cmd/ksh93/sh/nvdisc.c: assign(): - Check that the nvalue union has a non-NULL pointer before using it. Progresses: https://github.com/ksh93/ksh/issues/435 --- src/cmd/ksh93/sh/nvdisc.c | 2 +- src/cmd/ksh93/tests/variables.sh | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/cmd/ksh93/sh/nvdisc.c b/src/cmd/ksh93/sh/nvdisc.c index 0e5b53b0efaf..38717b834591 100644 --- a/src/cmd/ksh93/sh/nvdisc.c +++ b/src/cmd/ksh93/sh/nvdisc.c @@ -367,7 +367,7 @@ static void assign(Namval_t *np,const char* val,int flags,Namfun_t *handle) done: if(bp== &block) block_done(bp); - if(nq && nq->nvalue.rp->running==1) + if(nq && nq->nvalue.rp && nq->nvalue.rp->running==1) { nq->nvalue.rp->running=0; _nv_unset(nq,0); diff --git a/src/cmd/ksh93/tests/variables.sh b/src/cmd/ksh93/tests/variables.sh index 0e496a2c3919..5c48b2113965 100755 --- a/src/cmd/ksh93/tests/variables.sh +++ b/src/cmd/ksh93/tests/variables.sh @@ -1369,5 +1369,13 @@ got=$("$SHELL" -c $'foo=baz; foo+=_foo "$SHELL" -c \'print $foo\'; print $foo') [[ $exp == "$got" ]] || err_exit "using the += operator for invocation-local assignments changes variables outside of the invocation-local scope" \ "(expected $(printf %q "$exp"), got $(printf %q "$got"))" +# ====== +# Crash when setting attribute after getn (numeric get) discipline +# https://github.com/ksh93/ksh/issues/435#issuecomment-1148813866 +got=$("$SHELL" -c 'foo.getn() { .sh.value=2.3*4.5; }; typeset -F2 foo; typeset -p foo' 2>&1) +exp='typeset -F 2 foo=10.35' +[[ $got == "$exp" ]] || err_exit "Setting attribute after setting getn discipline fails" \ + "(expected $(printf %q "$exp"), got $(printf %q "$got"))" + # ====== exit $((Errors<125?Errors:125))