[git commit] bc: do not perform domr limit checks when they can't work (e.g. on 32-bit arches)

Denys Vlasenko vda.linux at googlemail.com
Fri Dec 7 14:50:14 UTC 2018


commit: https://git.busybox.net/busybox/commit/?id=64074a1767f69b186ce58cafb7eb95bc1aa0dda9
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

Also, optimize printing of messages with fixed limit strings
by including limits as strings.

function                                             old     new   delta
bc_num_ulong                                         103      95      -8
bc_lex_number                                        296     281     -15
dc_lex_token                                         701     684     -17
bc_lex_name                                           90      73     -17
bc_num_shift                                          72      54     -18
bc_lex_token                                        1299    1280     -19
bc_parse_stmt                                       1868    1768    -100
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/7 up/down: 0/-194)           Total: -194 bytes
   text	   data	    bss	    dec	    hex	filename
 985814	    485	   7296	 993595	  f293b	busybox_old
 985526	    485	   7296	 993307	  f281b	busybox_unstripped

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 miscutils/bc.c | 109 ++++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 76 insertions(+), 33 deletions(-)

diff --git a/miscutils/bc.c b/miscutils/bc.c
index 9eafa80e9..3da03b437 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -725,14 +725,39 @@ typedef unsigned long (*BcProgramBuiltIn)(BcNum *);
 #define BC_MAX(a, b) ((a) > (b) ? (a) : (b))
 #define BC_MIN(a, b) ((a) < (b) ? (a) : (b))
 
-#define BC_MAX_OBASE  ((unsigned) 999)
-#define BC_MAX_DIM    ((unsigned) INT_MAX)
-#define BC_MAX_SCALE  ((unsigned) UINT_MAX)
-#define BC_MAX_STRING ((unsigned) UINT_MAX - 1)
-#define BC_MAX_NAME   BC_MAX_STRING
-#define BC_MAX_NUM    BC_MAX_STRING
-#define BC_MAX_EXP    ((unsigned long) LONG_MAX)
-#define BC_MAX_VARS   ((unsigned long) SIZE_MAX - 1)
+#define BC_MAX_OBASE    ((unsigned) 999)
+#define BC_MAX_DIM      ((unsigned) INT_MAX)
+#define BC_MAX_SCALE    ((unsigned) UINT_MAX)
+#define BC_MAX_STRING   ((unsigned) UINT_MAX - 1)
+#define BC_MAX_NUM      BC_MAX_STRING
+// Unused apart from "limits" message. Just show a "biggish number" there.
+//#define BC_MAX_NAME     BC_MAX_STRING
+//#define BC_MAX_EXP      ((unsigned long) LONG_MAX)
+//#define BC_MAX_VARS     ((unsigned long) SIZE_MAX - 1)
+#define BC_MAX_NAME_STR "999999999"
+#define BC_MAX_EXP_STR  "999999999"
+#define BC_MAX_VARS_STR "999999999"
+
+#define BC_MAX_OBASE_STR "999"
+
+#if INT_MAX == 2147483647
+# define BC_MAX_DIM_STR "2147483647"
+#elif INT_MAX == 9223372036854775807
+# define BC_MAX_DIM_STR "9223372036854775807"
+#else
+# error Strange INT_MAX
+#endif
+
+#if UINT_MAX == 4294967295
+# define BC_MAX_SCALE_STR  "4294967295"
+# define BC_MAX_STRING_STR "4294967294"
+#elif UINT_MAX == 18446744073709551615
+# define BC_MAX_SCALE_STR  "18446744073709551615"
+# define BC_MAX_STRING_STR "18446744073709551614"
+#else
+# error Strange UINT_MAX
+#endif
+#define BC_MAX_NUM_STR BC_MAX_STRING_STR
 
 struct globals {
 	IF_FEATURE_BC_SIGNALS(smallint ttyin;)
@@ -1590,8 +1615,12 @@ static void bc_num_split(BcNum *restrict n, size_t idx, BcNum *restrict a,
 static BcStatus bc_num_shift(BcNum *n, size_t places)
 {
 	if (places == 0 || n->len == 0) return BC_STATUS_SUCCESS;
-	if (places + n->len > BC_MAX_NUM)
-		return bc_error("number too long: must be [1, BC_NUM_MAX]");
+
+	// This check makes sense only if size_t is (much) larger than BC_MAX_NUM.
+	if (SIZE_MAX > (BC_MAX_NUM | 0xff)) {
+		if (places + n->len > BC_MAX_NUM)
+			return bc_error("number too long: must be [1,"BC_MAX_NUM_STR"]");
+	}
 
 	if (n->rdx >= places)
 		n->rdx -= places;
@@ -2891,8 +2920,11 @@ static BcStatus bc_lex_number(BcLex *l, char start)
 	}
 
 	len = i + !last_pt - bslashes * 2;
-	if (len > BC_MAX_NUM)
-		return bc_error("number too long: must be [1, BC_NUM_MAX]");
+	// This check makes sense only if size_t is (much) larger than BC_MAX_NUM.
+	if (SIZE_MAX > (BC_MAX_NUM | 0xff)) {
+		if (len > BC_MAX_NUM)
+			return bc_error("number too long: must be [1,"BC_MAX_NUM_STR"]");
+	}
 
 	bc_vec_pop_all(&l->t.v);
 	bc_vec_expand(&l->t.v, len + 1);
@@ -2929,8 +2961,11 @@ static BcStatus bc_lex_name(BcLex *l)
 
 	while ((c >= 'a' && c <= 'z') || isdigit(c) || c == '_') c = buf[++i];
 
-	if (i > BC_MAX_STRING)
-		return bc_error("name too long: must be [1, BC_NAME_MAX]");
+	// This check makes sense only if size_t is (much) larger than BC_MAX_STRING.
+	if (SIZE_MAX > (BC_MAX_STRING | 0xff)) {
+		if (i > BC_MAX_STRING)
+			return bc_error("name too long: must be [1,"BC_MAX_STRING_STR"]");
+	}
 	bc_vec_string(&l->t.v, i, buf);
 
 	// Increment the index. We minus 1 because it has already been incremented.
@@ -3047,8 +3082,11 @@ static BcStatus bc_lex_string(BcLex *l)
 	}
 
 	len = i - l->i;
-	if (len > BC_MAX_STRING)
-		return bc_error("string too long: must be [1, BC_STRING_MAX]");
+	// This check makes sense only if size_t is (much) larger than BC_MAX_STRING.
+	if (SIZE_MAX > (BC_MAX_STRING | 0xff)) {
+		if (len > BC_MAX_STRING)
+			return bc_error("string too long: must be [1,"BC_MAX_STRING_STR"]");
+	}
 	bc_vec_string(&l->t.v, len, l->buf + l->i);
 
 	l->i = i + 1;
@@ -3426,8 +3464,11 @@ static BcStatus dc_lex_string(BcLex *l)
 	}
 
 	bc_vec_pushZeroByte(&l->t.v);
-	if (i - l->i > BC_MAX_STRING)
-		return bc_error("string too long: must be [1, BC_STRING_MAX]");
+	// This check makes sense only if size_t is (much) larger than BC_MAX_STRING.
+	if (SIZE_MAX > (BC_MAX_STRING | 0xff)) {
+		if (i - l->i > BC_MAX_STRING)
+			return bc_error("string too long: must be [1,"BC_MAX_STRING_STR"]");
+	}
 
 	l->i = i;
 	l->line += nls;
@@ -4700,14 +4741,16 @@ static BcStatus bc_parse_stmt(BcParse *p)
 			// the output is produced at _parse time_.
 			s = bc_lex_next(&p->l);
 			if (s) return s;
-			printf("BC_BASE_MAX     = %u\n", BC_MAX_OBASE);
-			printf("BC_DIM_MAX      = %u\n", BC_MAX_DIM);
-			printf("BC_SCALE_MAX    = %u\n", BC_MAX_SCALE);
-			printf("BC_STRING_MAX   = %u\n", BC_MAX_STRING);
-			printf("BC_NAME_MAX     = %u\n", BC_MAX_NAME);
-			printf("BC_NUM_MAX      = %u\n", BC_MAX_NUM);
-			printf("MAX Exponent    = %lu\n", BC_MAX_EXP);
-			printf("Number of vars  = %lu\n", BC_MAX_VARS);
+			printf(
+				"BC_BASE_MAX     = "BC_MAX_OBASE_STR "\n"
+				"BC_DIM_MAX      = "BC_MAX_DIM_STR   "\n"
+				"BC_SCALE_MAX    = "BC_MAX_SCALE_STR "\n"
+				"BC_STRING_MAX   = "BC_MAX_STRING_STR"\n"
+				"BC_NAME_MAX     = "BC_MAX_NAME_STR  "\n"
+				"BC_NUM_MAX      = "BC_MAX_NUM_STR   "\n"
+				"MAX Exponent    = "BC_MAX_EXP_STR   "\n"
+				"Number of vars  = "BC_MAX_VARS_STR  "\n"
+			);
 			break;
 		}
 
@@ -5903,12 +5946,12 @@ static BcStatus bc_program_assign(char inst)
 
 	if (ib || sc || left->t == BC_RESULT_OBASE) {
 		static const char *const msg[] = {
-			"bad ibase; must be [2, 16]",           //BC_RESULT_IBASE
-			"bad scale; must be [0, BC_SCALE_MAX]", //BC_RESULT_SCALE
-			NULL, //can't happen                    //BC_RESULT_LAST
-			NULL, //can't happen                    //BC_RESULT_CONSTANT
-			NULL, //can't happen                    //BC_RESULT_ONE
-			"bad obase; must be [2, BC_BASE_MAX]",  //BC_RESULT_OBASE
+			"bad ibase; must be [2,16]",                 //BC_RESULT_IBASE
+			"bad scale; must be [0,"BC_MAX_SCALE_STR"]", //BC_RESULT_SCALE
+			NULL, //can't happen                         //BC_RESULT_LAST
+			NULL, //can't happen                         //BC_RESULT_CONSTANT
+			NULL, //can't happen                         //BC_RESULT_ONE
+			"bad obase; must be [2,"BC_MAX_OBASE_STR"]", //BC_RESULT_OBASE
 		};
 		size_t *ptr;
 		unsigned long val, max;
@@ -6020,7 +6063,7 @@ static BcStatus bc_program_pushArray(char *code, size_t *bgn,
 		if (s) goto err;
 
 		if (temp > BC_MAX_DIM) {
-			s = bc_error("array too long; must be [1, BC_DIM_MAX]");
+			s = bc_error("array too long; must be [1,"BC_MAX_DIM_STR"]");
 			goto err;
 		}
 


More information about the busybox-cvs mailing list