diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-07 15:50:14 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-07 15:50:14 +0100 |
commit | 64074a1767f69b186ce58cafb7eb95bc1aa0dda9 (patch) | |
tree | 026187a294956fcab7b6c6b543fd1b10f57b5400 | |
parent | ffdcebdffe8a2b6261e3eb468d7c19fd0b454a87 (diff) | |
download | busybox-64074a1767f69b186ce58cafb7eb95bc1aa0dda9.tar.gz |
bc: do not perform domr limit checks when they can't work (e.g. on 32-bit arches)
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@googlemail.com>
-rw-r--r-- | miscutils/bc.c | 109 |
1 files 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; } |