aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2023-07-02 19:32:12 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2023-07-02 19:32:12 +0200
commitcc9543fed1f916f62a63cfbe9eaefba3df8e22cb (patch)
treeca45333b5d738d2ccad7fb2ef65a3b8f423b4b6f
parent045924ed7d3c887cce1c6a22a0b4e0b692719154 (diff)
downloadbusybox-w32-cc9543fed1f916f62a63cfbe9eaefba3df8e22cb.tar.gz
busybox-w32-cc9543fed1f916f62a63cfbe9eaefba3df8e22cb.tar.bz2
busybox-w32-cc9543fed1f916f62a63cfbe9eaefba3df8e22cb.zip
shell/math: avoid $((3**999999999999999999)) to take years
function old new delta arith_apply 991 1030 +39 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--shell/math.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/shell/math.c b/shell/math.c
index b06d1ae3c..e90a38f05 100644
--- a/shell/math.c
+++ b/shell/math.c
@@ -155,7 +155,7 @@ typedef unsigned char operator;
155#define PREC_ASSIGN2 3 155#define PREC_ASSIGN2 3
156#define TOK_MUL_ASSIGN tok_decl(3,0) 156#define TOK_MUL_ASSIGN tok_decl(3,0)
157/* "/" and "/=" ops have the same id bits */ 157/* "/" and "/=" ops have the same id bits */
158#define DIV_ID1 1 158#define DIV_ID1 1
159#define TOK_DIV_ASSIGN tok_decl(3,DIV_ID1) 159#define TOK_DIV_ASSIGN tok_decl(3,DIV_ID1)
160#define TOK_REM_ASSIGN tok_decl(3,2) 160#define TOK_REM_ASSIGN tok_decl(3,2)
161 161
@@ -422,8 +422,19 @@ arith_apply(arith_state_t *math_state, operator op, var_or_num_t *numstack, var_
422 if (right_side_val < 0) 422 if (right_side_val < 0)
423 return "exponent less than 0"; 423 return "exponent less than 0";
424 c = 1; 424 c = 1;
425 while (--right_side_val >= 0) 425 while (right_side_val != 0) {
426 if ((right_side_val & 1) == 0) {
427 /* this if() block is not necessary for correctness,
428 * but otherwise echo $((3**999999999999999999))
429 * takes a VERY LONG time
430 * (and it's not interruptible by ^C)
431 */
432 rez *= rez;
433 right_side_val >>= 1;
434 }
426 c *= rez; 435 c *= rez;
436 right_side_val--;
437 }
427 rez = c; 438 rez = c;
428 } 439 }
429 else /*if (op == TOK_DIV || op == TOK_DIV_ASSIGN 440 else /*if (op == TOK_DIV || op == TOK_DIV_ASSIGN
@@ -550,7 +561,7 @@ static arith_t parse_with_base(const char *nptr, char **endptr, unsigned base)
550 /* current char is one of :;<=>?@A..Z[\]^_`a..z */ 561 /* current char is one of :;<=>?@A..Z[\]^_`a..z */
551 562
552 /* in bases up to 36, case does not matter for a-z, 563 /* in bases up to 36, case does not matter for a-z,
553 * map A..Z and a..z to 10..35: */ 564 * map @A..Z and `a..z to 9..35: */
554 digit = (unsigned)(*nptr | 0x20) - ('a' - 10); 565 digit = (unsigned)(*nptr | 0x20) - ('a' - 10);
555 if (base > 36 && *nptr <= '_') { 566 if (base > 36 && *nptr <= '_') {
556 /* base > 36: A-Z,@,_ are 36-61,62,63 */ 567 /* base > 36: A-Z,@,_ are 36-61,62,63 */