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>
This commit is contained in:
parent
ffdcebdffe
commit
64074a1767
109
miscutils/bc.c
109
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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user