[git commit branch/1_31_stable] ash: fix BASE##nn bashism for bases 36..64

Denys Vlasenko vda.linux at googlemail.com
Mon Oct 21 14:54:40 UTC 2019


commit: https://git.busybox.net/busybox/commit/?id=49a8839638cb335a2fe8a3a332e97fbb01027a72
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/1_31_stable

function                                             old     new   delta
evaluate_string                                      876     932     +56

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 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++;


More information about the busybox-cvs mailing list