aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2023-07-02 17:58:20 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2023-07-02 17:58:20 +0200
commit045924ed7d3c887cce1c6a22a0b4e0b692719154 (patch)
tree62bcf0ddaa7f09205583e643709ee69828fc4354
parent38f769ab4e5f6cd2ffab88300ddaddef3aac3345 (diff)
downloadbusybox-w32-045924ed7d3c887cce1c6a22a0b4e0b692719154.tar.gz
busybox-w32-045924ed7d3c887cce1c6a22a0b4e0b692719154.tar.bz2
busybox-w32-045924ed7d3c887cce1c6a22a0b4e0b692719154.zip
shell/math: do not accept $((36#@))
function old new delta parse_with_base 170 174 +4 arith_apply 996 991 -5 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/1 up/down: 4/-5) Total: -1 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--shell/math.c38
1 files changed, 22 insertions, 16 deletions
diff --git a/shell/math.c b/shell/math.c
index beb89d140..b06d1ae3c 100644
--- a/shell/math.c
+++ b/shell/math.c
@@ -128,7 +128,8 @@ typedef unsigned char operator;
128 * Consider * and / 128 * Consider * and /
129 */ 129 */
130#define tok_decl(prec,id) (((id)<<5) | (prec)) 130#define tok_decl(prec,id) (((id)<<5) | (prec))
131#define PREC(op) ((op) & 0x1F) 131#define ID_SHIFT 5
132#define PREC(op) ((op) & 0x1f)
132 133
133#define PREC_LPAREN 0 134#define PREC_LPAREN 0
134#define TOK_LPAREN tok_decl(0,0) 135#define TOK_LPAREN tok_decl(0,0)
@@ -146,14 +147,16 @@ typedef unsigned char operator;
146#define TOK_AND_ASSIGN tok_decl(2,1) 147#define TOK_AND_ASSIGN tok_decl(2,1)
147#define TOK_OR_ASSIGN tok_decl(2,2) 148#define TOK_OR_ASSIGN tok_decl(2,2)
148#define TOK_XOR_ASSIGN tok_decl(2,3) 149#define TOK_XOR_ASSIGN tok_decl(2,3)
149#define TOK_PLUS_ASSIGN tok_decl(2,4) 150#define TOK_ADD_ASSIGN tok_decl(2,4)
150#define TOK_MINUS_ASSIGN tok_decl(2,5) 151#define TOK_SUB_ASSIGN tok_decl(2,5)
151#define TOK_LSHIFT_ASSIGN tok_decl(2,6) 152#define TOK_LSHIFT_ASSIGN tok_decl(2,6)
152#define TOK_RSHIFT_ASSIGN tok_decl(2,7) 153#define TOK_RSHIFT_ASSIGN tok_decl(2,7)
153 154
154#define PREC_ASSIGN2 3 155#define PREC_ASSIGN2 3
155#define TOK_MUL_ASSIGN tok_decl(3,0) 156#define TOK_MUL_ASSIGN tok_decl(3,0)
156#define TOK_DIV_ASSIGN tok_decl(3,1) 157/* "/" and "/=" ops have the same id bits */
158#define DIV_ID1 1
159#define TOK_DIV_ASSIGN tok_decl(3,DIV_ID1)
157#define TOK_REM_ASSIGN tok_decl(3,2) 160#define TOK_REM_ASSIGN tok_decl(3,2)
158 161
159#define fix_assignment_prec(prec) do { prec -= (prec == 3); } while (0) 162#define fix_assignment_prec(prec) do { prec -= (prec == 3); } while (0)
@@ -198,7 +201,7 @@ typedef unsigned char operator;
198#define TOK_SUB tok_decl(13,1) 201#define TOK_SUB tok_decl(13,1)
199 202
200#define TOK_MUL tok_decl(14,0) 203#define TOK_MUL tok_decl(14,0)
201#define TOK_DIV tok_decl(14,1) 204#define TOK_DIV tok_decl(14,DIV_ID1)
202#define TOK_REM tok_decl(14,2) 205#define TOK_REM tok_decl(14,2)
203 206
204/* Exponent is right associative */ 207/* Exponent is right associative */
@@ -408,9 +411,9 @@ arith_apply(arith_state_t *math_state, operator op, var_or_num_t *numstack, var_
408 rez = (rez <= right_side_val); 411 rez = (rez <= right_side_val);
409 else if (op == TOK_MUL || op == TOK_MUL_ASSIGN) 412 else if (op == TOK_MUL || op == TOK_MUL_ASSIGN)
410 rez *= right_side_val; 413 rez *= right_side_val;
411 else if (op == TOK_ADD || op == TOK_PLUS_ASSIGN) 414 else if (op == TOK_ADD || op == TOK_ADD_ASSIGN)
412 rez += right_side_val; 415 rez += right_side_val;
413 else if (op == TOK_SUB || op == TOK_MINUS_ASSIGN) 416 else if (op == TOK_SUB || op == TOK_SUB_ASSIGN)
414 rez -= right_side_val; 417 rez -= right_side_val;
415 else if (op == TOK_ASSIGN || op == TOK_COMMA) 418 else if (op == TOK_ASSIGN || op == TOK_COMMA)
416 rez = right_side_val; 419 rez = right_side_val;
@@ -439,11 +442,11 @@ arith_apply(arith_state_t *math_state, operator op, var_or_num_t *numstack, var_
439 * Make sure to at least not SEGV here: 442 * Make sure to at least not SEGV here:
440 */ 443 */
441 if (right_side_val == -1 444 if (right_side_val == -1
442 && rez << 1 == 0 /* MAX_NEGATIVE_INT or 0 */ 445 && (rez << 1) == 0 /* MAX_NEGATIVE_INT or 0 */
443 ) { 446 ) {
444 right_side_val = 1; 447 right_side_val = 1;
445 } 448 }
446 if (op == TOK_DIV || op == TOK_DIV_ASSIGN) 449 if (op & (DIV_ID1 << ID_SHIFT)) /* DIV or DIV_ASSIGN? */
447 rez /= right_side_val; 450 rez /= right_side_val;
448 else 451 else
449 rez %= right_side_val; 452 rez %= right_side_val;
@@ -505,8 +508,8 @@ static const char op_tokens[] ALIGN1 = {
505 '*','=', 0, TOK_MUL_ASSIGN, 508 '*','=', 0, TOK_MUL_ASSIGN,
506 '/','=', 0, TOK_DIV_ASSIGN, 509 '/','=', 0, TOK_DIV_ASSIGN,
507 '%','=', 0, TOK_REM_ASSIGN, 510 '%','=', 0, TOK_REM_ASSIGN,
508 '+','=', 0, TOK_PLUS_ASSIGN, 511 '+','=', 0, TOK_ADD_ASSIGN,
509 '-','=', 0, TOK_MINUS_ASSIGN, 512 '-','=', 0, TOK_SUB_ASSIGN,
510 '-','-', 0, TOK_POST_DEC, 513 '-','-', 0, TOK_POST_DEC,
511 '^','=', 0, TOK_XOR_ASSIGN, 514 '^','=', 0, TOK_XOR_ASSIGN,
512 '+','+', 0, TOK_POST_INC, 515 '+','+', 0, TOK_POST_INC,
@@ -542,12 +545,15 @@ static arith_t parse_with_base(const char *nptr, char **endptr, unsigned base)
542 for (;;) { 545 for (;;) {
543 unsigned digit = (unsigned)*nptr - '0'; 546 unsigned digit = (unsigned)*nptr - '0';
544 if (digit >= 10 /* not 0..9 */ 547 if (digit >= 10 /* not 0..9 */
545 && digit <= 'z' - '0' /* needed to reject e.g. $((64#~)) */ 548 && digit <= 'z' - '0' /* reject e.g. $((64#~)) */
546 ) { 549 ) {
547 /* in bases up to 36, case does not matter for a-z */ 550 /* current char is one of :;<=>?@A..Z[\]^_`a..z */
551
552 /* in bases up to 36, case does not matter for a-z,
553 * map A..Z and a..z to 10..35: */
548 digit = (unsigned)(*nptr | 0x20) - ('a' - 10); 554 digit = (unsigned)(*nptr | 0x20) - ('a' - 10);
549 if (base > 36 && *nptr <= '_') { 555 if (base > 36 && *nptr <= '_') {
550 /* otherwise, A-Z,@,_ are 36-61,62,63 */ 556 /* base > 36: A-Z,@,_ are 36-61,62,63 */
551 if (*nptr == '_') 557 if (*nptr == '_')
552 digit = 63; 558 digit = 63;
553 else if (*nptr == '@') 559 else if (*nptr == '@')
@@ -558,8 +564,8 @@ static arith_t parse_with_base(const char *nptr, char **endptr, unsigned base)
558 break; /* error: one of [\]^ */ 564 break; /* error: one of [\]^ */
559 } 565 }
560 //bb_error_msg("ch:'%c'%d digit:%u", *nptr, *nptr, digit); 566 //bb_error_msg("ch:'%c'%d digit:%u", *nptr, *nptr, digit);
561 //if (digit < 10) - example where we need this? 567 if (digit < 10) /* reject e.g. $((36#@)) */
562 // break; 568 break;
563 } 569 }
564 if (digit >= base) 570 if (digit >= base)
565 break; 571 break;