aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2023-06-19 09:44:04 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2023-06-19 09:44:04 +0200
commita165098922ddbfbca3579538f50b44002ab0fae7 (patch)
tree92c812989b6208ff7803f7818d19080f21be9e35
parent79b90cbece5d69c4d370347c347f3d17bd1156c6 (diff)
downloadbusybox-w32-a165098922ddbfbca3579538f50b44002ab0fae7.tar.gz
busybox-w32-a165098922ddbfbca3579538f50b44002ab0fae7.tar.bz2
busybox-w32-a165098922ddbfbca3579538f50b44002ab0fae7.zip
shell/math: fix comments about jammed-together num+num corner cases
function old new delta evaluate_string 1478 1470 -8 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--shell/math.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/shell/math.c b/shell/math.c
index e5447e767..d9986335a 100644
--- a/shell/math.c
+++ b/shell/math.c
@@ -613,7 +613,7 @@ evaluate_string(arith_state_t *math_state, const char *expr)
613 const char *start_expr = expr = skip_whitespace(expr); 613 const char *start_expr = expr = skip_whitespace(expr);
614 614
615 { 615 {
616 unsigned expr_len = strlen(expr) + 2; 616 unsigned expr_len = strlen(expr);
617 /* If LOTS of whitespace, do not blow up the estimation */ 617 /* If LOTS of whitespace, do not blow up the estimation */
618 const char *p = expr; 618 const char *p = expr;
619 while (*p) { 619 while (*p) {
@@ -625,14 +625,21 @@ evaluate_string(arith_state_t *math_state, const char *expr)
625 p++; 625 p++;
626 } 626 }
627 } 627 }
628 /* There can be no more than expr_len/2 628 dbg("expr:'%s' expr_len:%u", expr, expr_len);
629 /* expr_len deep opstack is needed. Think "------------7".
630 * Only "?" operator temporarily needs two opstack slots
631 * (IOW: more than one slot), but its second slot (LPAREN)
632 * is popped off when ":" is reached.
633 */
634 opstackptr = opstack = alloca(expr_len * sizeof(opstack[0]));
635 /* There can be no more than (expr_len/2 + 1)
629 * integers/names in any given correct or incorrect expression. 636 * integers/names in any given correct or incorrect expression.
630 * (modulo "09v09v09v09v09v" case, 637 * (modulo "09", "0v" cases where 2 chars are 2 ints/names,
631 * but we have code to detect that early) 638 * but we have code to detect that early)
632 */ 639 */
633 dbg("expr:'%s' expr_len:%u", expr, expr_len); 640 expr_len = (expr_len / 2)
634 numstackptr = numstack = alloca((expr_len / 2) * sizeof(numstack[0])); 641 + 1 /* "1+2" has two nums, 2 = len/2+1, NOT len/2 */;
635 opstackptr = opstack = alloca(expr_len * sizeof(opstack[0])); 642 numstackptr = numstack = alloca(expr_len * sizeof(numstack[0]));
636 } 643 }
637 644
638 /* Start with a left paren */ 645 /* Start with a left paren */
@@ -714,8 +721,9 @@ evaluate_string(arith_state_t *math_state, const char *expr)
714 dbg("[%d] val:%lld", (int)(numstackptr - numstack), numstackptr->val); 721 dbg("[%d] val:%lld", (int)(numstackptr - numstack), numstackptr->val);
715 /* A number can't be followed by another number, or a variable name. 722 /* A number can't be followed by another number, or a variable name.
716 * We'd catch this later anyway, but this would require numstack[] 723 * We'd catch this later anyway, but this would require numstack[]
717 * to be twice as deep to handle strings where _every_ char is 724 * to be ~twice as deep to handle strings where _every_ char is
718 * a new number or name. Example: 09v09v09v09v09v09v09v09v09v 725 * a new number or name.
726 * Examples: "09" is two numbers, "0v" is number and name.
719 */ 727 */
720 if (isalnum(*expr) || *expr == '_') 728 if (isalnum(*expr) || *expr == '_')
721 goto syntax_err; 729 goto syntax_err;