From a73c705b0c864a9ce042fca6e72e0c92d4ad8237 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Fri, 16 Dec 2022 23:22:33 +0100 Subject: 51212: remove STOUC() macro This served as a workaround for ancient compilers where casts to unsigned char were broken. --- Src/math.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Src/math.c') diff --git a/Src/math.c b/Src/math.c index 777ad9c31..12c8d6f6b 100644 --- a/Src/math.c +++ b/Src/math.c @@ -955,7 +955,7 @@ getcvar(char *s) } } #endif - mn.u.l = STOUC(*t == Meta ? t[1] ^ 32 : *t); + mn.u.l = (unsigned char) (*t == Meta ? t[1] ^ 32 : *t); } unqueue_signals(); return mn; -- cgit v1.2.3 From 4345eed1fe5dd6c881b948331cfa8f4a48beda42 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Thu, 22 Jun 2023 13:36:40 -0700 Subject: 51887: namespaces recognized in math, incorrect usages rejected. --- ChangeLog | 3 +++ Src/math.c | 10 +++++++--- Src/params.c | 27 +++++++++++++++++++++++++- Test/K02parameter.ztst | 52 ++++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 86 insertions(+), 6 deletions(-) (limited to 'Src/math.c') diff --git a/ChangeLog b/ChangeLog index e48073e80..0011cc947 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2023-06-22 Bart Schaefer + * 51887: Src/math.c, Src/params.c, Test/K02parameter.ztst: + namespaces recognized in math, incorrect usages rejected. + * Marlon Richert: 51860: Completion/Base/Completer/_prefix, Test/Y01completion.ztst, Test/comptest: simplify suffix handling in _prefix to remove longstanding and less accurate hack; tests. diff --git a/Src/math.c b/Src/math.c index 12c8d6f6b..a060181ed 100644 --- a/Src/math.c +++ b/Src/math.c @@ -641,7 +641,9 @@ zzlex(void) return MINUSEQ; } if (unary) { - if (idigit(*ptr) || *ptr == '.') { + if (idigit(*ptr) || + (*ptr == '.' && + (idigit(ptr[1]) || !itype_end(ptr, INAMESPC, 0)))) { int ctype = lexconstant(); if (ctype == NUM) { @@ -835,7 +837,9 @@ zzlex(void) case Dnull: break; default: - if (idigit(*--ptr) || *ptr == '.') + if (idigit(*--ptr) || + (*ptr == '.' && + (idigit(ptr[1]) || !itype_end(ptr, INAMESPC, 0)))) return lexconstant(); if (*ptr == '#') { if (*++ptr == '\\' || *ptr == '#') { @@ -857,7 +861,7 @@ zzlex(void) } cct = 1; } - if ((ie = itype_end(ptr, IIDENT, 0)) != ptr) { + if ((ie = itype_end(ptr, INAMESPC, 0)) != ptr) { int func = 0; char *p; diff --git a/Src/params.c b/Src/params.c index 021d341e8..2b0837e03 100644 --- a/Src/params.c +++ b/Src/params.c @@ -1226,6 +1226,26 @@ isident(char *s) if (!*s) /* empty string is definitely not valid */ return 0; + /* This partly duplicates code in itype_end(), but we need to + * distinguish the leading namespace at this point to check the + * correctness of the identifier that follows + */ + if (*s == '.') { + if (idigit(s[1])) + return 0; /* Namespace must not start with a digit */ + /* Reject identifiers beginning with a digit in namespaces. + * Move this out below this block to also reject v.1x form. + */ + if ((ss = itype_end(s + (*s == '.'), IIDENT, 0))) { + if (*ss == '.') { + if (!ss[1]) + return 0; + if (idigit(ss[1])) + s = ss + 1; + } + } + } + if (idigit(*s)) { /* If the first character is `s' is a digit, then all must be */ for (ss = ++s; *ss; ss++) @@ -2148,7 +2168,12 @@ fetchvalue(Value v, char **pptr, int bracks, int flags) pm = (Param) paramtab->getnode2(paramtab, *t == '0' ? "0" : t); else pm = (Param) paramtab->getnode(paramtab, *t == '0' ? "0" : t); - if (sav) + if (!pm && *t == '.' && !isident(t)) { + /* badly formed namespace reference */ + if (sav) + *s = sav; + return NULL; + } else if (sav) *s = sav; *pptr = s; if (!pm || ((pm->node.flags & PM_UNSET) && diff --git a/Test/K02parameter.ztst b/Test/K02parameter.ztst index 8a1be1e36..0b1a8dd4a 100644 --- a/Test/K02parameter.ztst +++ b/Test/K02parameter.ztst @@ -100,7 +100,55 @@ F:Braces are required >.k02.array >characters + k.=empty k.2=test - print ${k.2} + print ${k.} ${k.2} 0:Parse without leading dot (future proofing) ->test +>empty test + + .k=OK + print ${.k} +0:Bare namespace is usable (ksh compatibility) +>OK + + .k.=empty +1:Namespace must precede an identifier, assignment +?(eval):1: not an identifier: .k. + + typeset .k.=empty +1:Namespace must precede an identifier, typeset +?(eval):typeset:1: not valid in this context: .k. + + print ${.k.} +1:Namespace must precede an identifier, reference +?(eval):1: bad substitution + + .2.b=not +1:Namespace identifier must not begin with a digit, assignment +?(eval):1: not an identifier: .2.b + + typeset .2.b=not +1:Namespace identifier must not begin with a digit, typeset +?(eval):typeset:1: not valid in this context: .2.b + + print ${.2.b} +1:Namespace identifier must not begin with a digit, reference +?(eval):1: bad substitution + + .not.2b=question +1:Identifier starting with a digit must be all digits, assignment +?(eval):1: not an identifier: .not.2b + + typeset .not.2b=question +1:Identifier starting with a digit must be all digits, typeset +?(eval):typeset:1: not valid in this context: .not.2b + + print ${.not.2b} +1:Identifier starting with a digit must be all digits, reference +?(eval):1: bad substitution + + integer .var.d=0 + float .var.f=.2 + print $((.var.x = ++.var.d - -.var.f)) +0:Namespaces in math context +>1.2 -- cgit v1.2.3 From 1f861ceba1d5740798caa0a3f208f3047c6e3ff5 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Wed, 24 Jan 2024 18:00:16 -0800 Subject: 52492: prevent indexing error on recursive arithmetic in array subscript Operator returns error when operand returns error --- ChangeLog | 3 +++ Src/math.c | 7 ++++++- 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'Src/math.c') diff --git a/ChangeLog b/ChangeLog index d46ce5fe5..b876cb6d1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-01-24 Bart Schaefer + * 52492: Src/math.c: prevent indexing error when using recursive + arithmetic in array subscript (operator stops on operand error) + * 52482: Src/subst.c: strip trailing newlines in emulation modes of ${ command; }, for bash/ksh compatibility diff --git a/Src/math.c b/Src/math.c index a060181ed..50b69d6a1 100644 --- a/Src/math.c +++ b/Src/math.c @@ -352,6 +352,8 @@ getmathparam(struct mathvalue *mptr) } return zero_mnumber; } + if (errflag) + return zero_mnumber; } result = getnumvalue(mptr->pval); if (isset(FORCEFLOAT) && result.type == MN_INTEGER) { @@ -1367,8 +1369,11 @@ op(int what) } spval = &stack[sp].val; - if (stack[sp].val.type == MN_UNSET) + if (stack[sp].val.type == MN_UNSET) { *spval = getmathparam(stack + sp); + if (errflag) + return; + } switch (what) { case NOT: if (spval->type & MN_FLOAT) { -- cgit v1.2.3 From 6c50d155625d83bde35dc78bc6920c9795462d58 Mon Sep 17 00:00:00 2001 From: Bart Schaefer Date: Sat, 24 Feb 2024 21:16:15 -0800 Subject: 52597: fix character counts in context of operator and operand errors --- ChangeLog | 3 +++ Src/math.c | 25 ++++++++++++++++++------- 2 files changed, 21 insertions(+), 7 deletions(-) (limited to 'Src/math.c') diff --git a/ChangeLog b/ChangeLog index 9f7289cea..684820f92 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2024-02-24 Bart Schaefer + * 52597: Src/math.c: fix multibyte and metafied character counts + when providing context for operator and operand errors + * 52596: Src/exec.c: metafy interpreter name for error message * Stephane: 52591: Src/builtin.c: printf builtin must pass diff --git a/Src/math.c b/Src/math.c index 50b69d6a1..d97dae238 100644 --- a/Src/math.c +++ b/Src/math.c @@ -1557,21 +1557,32 @@ checkunary(int mtokc, char *mptr) errmsg = 2; } if (errmsg) { - int len, over = 0; + int len = 0, over = 0; char *errtype = errmsg == 2 ? "operator" : "operand"; while (inblank(*mptr)) mptr++; - len = ztrlen(mptr); - if (len > 10) { - len = 10; - over = 1; + if (isset(MULTIBYTE)) + MB_CHARINIT(); + while (over < 10 && mptr[len]) { + if (isset(MULTIBYTE)) + len += MB_METACHARLEN(mptr+len); + else + len += (mptr[len] == Meta ? 2 : 1); + ++over; + } + if ((over = mptr[len])) { + mptr = dupstring(mptr); + if (mptr[len] == Meta) + mptr[len+1] = 0; + else + mptr[len] = 0; } if (!*mptr) zerr("bad math expression: %s expected at end of string", errtype); else - zerr("bad math expression: %s expected at `%l%s'", - errtype, mptr, len, over ? "..." : ""); + zerr("bad math expression: %s expected at `%s%s'", + errtype, mptr, over ? "..." : ""); } unary = !(tp & OP_OPF); } -- cgit v1.2.3