diff options
Diffstat (limited to 'shell/math.c')
-rw-r--r-- | shell/math.c | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/shell/math.c b/shell/math.c index eaf4f2453..aac5017d0 100644 --- a/shell/math.c +++ b/shell/math.c | |||
@@ -537,11 +537,40 @@ static arith_t strto_arith_t(const char *nptr, char **endptr) | |||
537 | base = (unsigned)n; | 537 | base = (unsigned)n; |
538 | n = 0; | 538 | n = 0; |
539 | nptr = *endptr + 1; | 539 | nptr = *endptr + 1; |
540 | /* bash allows "N#" (empty "nnnn" part) */ | 540 | for (;;) { |
541 | while (isdigit(*nptr)) { | 541 | unsigned digit = (unsigned)*nptr - '0'; |
542 | if (digit >= 10 /* not 0..9 */ | ||
543 | && digit <= 'z' - '0' /* needed to reject e.g. $((64#~)) */ | ||
544 | ) { | ||
545 | /* in bases up to 36, case does not matter for a-z */ | ||
546 | digit = (unsigned)(*nptr | 0x20) - ('a' - 10); | ||
547 | if (base > 36 && *nptr <= '_') { | ||
548 | /* otherwise, A-Z,@,_ are 36-61,62,63 */ | ||
549 | if (*nptr == '_') | ||
550 | digit = 63; | ||
551 | else if (*nptr == '@') | ||
552 | digit = 62; | ||
553 | else if (digit < 36) /* A-Z */ | ||
554 | digit += 36 - 10; | ||
555 | else | ||
556 | break; /* error: one of [\]^ */ | ||
557 | } | ||
558 | //bb_error_msg("ch:'%c'%d digit:%u", *nptr, *nptr, digit); | ||
559 | //if (digit < 10) - example where we need this? | ||
560 | // break; | ||
561 | } | ||
562 | if (digit >= base) | ||
563 | break; | ||
542 | /* bash does not check for overflows */ | 564 | /* bash does not check for overflows */ |
543 | n = n * base + (*nptr++ - '0'); | 565 | n = n * base + digit; |
566 | nptr++; | ||
544 | } | 567 | } |
568 | /* Note: we do not set errno on bad chars, we just set a pointer | ||
569 | * to the first invalid char. For example, this allows | ||
570 | * "N#" (empty "nnnn" part): 64#+1 is a valid expression, | ||
571 | * it means 64# + 1, whereas 64#~... is not, since ~ is not a valid | ||
572 | * operator. | ||
573 | */ | ||
545 | *endptr = (char*)nptr; | 574 | *endptr = (char*)nptr; |
546 | return n; | 575 | return n; |
547 | } | 576 | } |