From 49a8839638cb335a2fe8a3a332e97fbb01027a72 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 22 Sep 2019 23:40:10 +0200 Subject: [PATCH] ash: fix BASE##nn bashism for bases 36..64 function old new delta evaluate_string 876 932 +56 Signed-off-by: Denys Vlasenko --- shell/math.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/shell/math.c b/shell/math.c index 0c806ad39..af1ab55c0 100644 --- a/shell/math.c +++ b/shell/math.c @@ -540,11 +540,29 @@ static arith_t strto_arith_t(const char *nptr, char **endptr) /* bash allows "N#" (empty "nnnn" part) */ for (;;) { unsigned digit = (unsigned)*nptr - '0'; - if (digit >= 10 || digit >= base) { + if (digit >= 10) { + /* *nptr is not 0..9 */ + if (*nptr > 'z') + break; /* this rejects e.g. $((64#~)) */ + /* in bases up to 36, case does not matter for a-z */ digit = (unsigned)(*nptr | 0x20) - ('a' - 10); - if (digit >= base) - break; + if (base > 36 && *nptr <= '_') { + /* otherwise, A-Z,@,_ are 36..61,62,63 */ + if (*nptr == '@') + digit = 62; + else if (*nptr == '_') + digit = 63; + else if (digit < 36) /* A-Z */ + digit += 36 - 10; + else + break; /* error, such as [ or \ */ + } + //bb_error_msg("ch:'%c'%d digit:%u", *nptr, *nptr, digit); + //if (digit < 10) - example where we need this? + // break; } + if (digit >= base) + break; /* bash does not check for overflows */ n = n * base + digit; nptr++; -- 2.25.1