diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-17 11:58:20 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-17 11:58:20 +0100 |
commit | b44a7f1d6642e2da39e9f27e0b504f662ca443a2 (patch) | |
tree | 80593654277f46a82b5a7eab8efe766da5fc1872 | |
parent | e42cc19b51febacba5e8f30f548bf294018d9e7c (diff) | |
download | busybox-w32-b44a7f1d6642e2da39e9f27e0b504f662ca443a2.tar.gz busybox-w32-b44a7f1d6642e2da39e9f27e0b504f662ca443a2.tar.bz2 busybox-w32-b44a7f1d6642e2da39e9f27e0b504f662ca443a2.zip |
bc: tighten up input NUL handling
function old new delta
static.dc_lex_tokens - 90 +90
bc_error_bad_character 17 31 +14
static.dc_lex_regs - 13 +13
bc_read_line 406 410 +4
bc_program_index 64 66 +2
dc_lex_regs 13 - -13
zdc_parse_expr 671 656 -15
zbc_lex_next 2318 2230 -88
dc_lex_tokens 91 - -91
------------------------------------------------------------------------------
(add/remove: 2/2 grow/shrink: 3/2 up/down: 123/-207) Total: -84 bytes
text data bss dec hex filename
981667 485 7296 989448 f1908 busybox_old
981599 485 7296 989380 f18c4 busybox_unstripped
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | miscutils/bc.c | 113 |
1 files changed, 64 insertions, 49 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c index 1fb1b00b3..214ea44ab 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c | |||
@@ -806,45 +806,6 @@ enum { | |||
806 | #endif // ENABLE_BC | 806 | #endif // ENABLE_BC |
807 | 807 | ||
808 | #if ENABLE_DC | 808 | #if ENABLE_DC |
809 | static const //BcLexType - should be this type, but narrower type saves size: | ||
810 | uint8_t | ||
811 | dc_lex_regs[] = { | ||
812 | BC_LEX_OP_REL_EQ, BC_LEX_OP_REL_LE, BC_LEX_OP_REL_GE, BC_LEX_OP_REL_NE, | ||
813 | BC_LEX_OP_REL_LT, BC_LEX_OP_REL_GT, BC_LEX_SCOLON, BC_LEX_COLON, | ||
814 | BC_LEX_ELSE, BC_LEX_LOAD, BC_LEX_LOAD_POP, BC_LEX_OP_ASSIGN, | ||
815 | BC_LEX_STORE_PUSH, | ||
816 | }; | ||
817 | |||
818 | static const //BcLexType - should be this type | ||
819 | uint8_t | ||
820 | dc_lex_tokens[] = { | ||
821 | BC_LEX_OP_MODULUS, BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_LPAREN, | ||
822 | BC_LEX_INVALID, BC_LEX_OP_MULTIPLY, BC_LEX_OP_PLUS, BC_LEX_INVALID, | ||
823 | BC_LEX_OP_MINUS, BC_LEX_INVALID, BC_LEX_OP_DIVIDE, | ||
824 | BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_INVALID, | ||
825 | BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_INVALID, | ||
826 | BC_LEX_INVALID, BC_LEX_INVALID, | ||
827 | BC_LEX_COLON, BC_LEX_SCOLON, BC_LEX_OP_REL_GT, BC_LEX_OP_REL_EQ, | ||
828 | BC_LEX_OP_REL_LT, BC_LEX_KEY_READ, BC_LEX_INVALID, | ||
829 | BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_INVALID, | ||
830 | BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_EQ_NO_REG, BC_LEX_INVALID, | ||
831 | BC_LEX_KEY_IBASE, BC_LEX_INVALID, BC_LEX_KEY_SCALE, BC_LEX_LOAD_POP, | ||
832 | BC_LEX_INVALID, BC_LEX_OP_BOOL_NOT, BC_LEX_KEY_OBASE, BC_LEX_PRINT_STREAM, | ||
833 | BC_LEX_NQUIT, BC_LEX_POP, BC_LEX_STORE_PUSH, BC_LEX_INVALID, BC_LEX_INVALID, | ||
834 | BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_SCALE_FACTOR, BC_LEX_INVALID, | ||
835 | BC_LEX_KEY_LENGTH, BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_INVALID, | ||
836 | BC_LEX_OP_POWER, BC_LEX_NEG, BC_LEX_INVALID, | ||
837 | BC_LEX_ASCIIFY, BC_LEX_INVALID, BC_LEX_CLEAR_STACK, BC_LEX_DUPLICATE, | ||
838 | BC_LEX_ELSE, BC_LEX_PRINT_STACK, BC_LEX_INVALID, BC_LEX_INVALID, | ||
839 | BC_LEX_STORE_IBASE, BC_LEX_INVALID, BC_LEX_STORE_SCALE, BC_LEX_LOAD, | ||
840 | BC_LEX_INVALID, BC_LEX_PRINT_POP, BC_LEX_STORE_OBASE, BC_LEX_KEY_PRINT, | ||
841 | BC_LEX_KEY_QUIT, BC_LEX_SWAP, BC_LEX_OP_ASSIGN, BC_LEX_INVALID, | ||
842 | BC_LEX_INVALID, BC_LEX_KEY_SQRT, BC_LEX_INVALID, BC_LEX_EXECUTE, | ||
843 | BC_LEX_INVALID, BC_LEX_STACK_LEVEL, | ||
844 | BC_LEX_LBRACE, BC_LEX_OP_MODEXP, BC_LEX_INVALID, BC_LEX_OP_DIVMOD, | ||
845 | BC_LEX_INVALID | ||
846 | }; | ||
847 | |||
848 | static const //BcInst - should be this type. Using signed narrow type since BC_INST_INVALID is -1 | 809 | static const //BcInst - should be this type. Using signed narrow type since BC_INST_INVALID is -1 |
849 | int8_t | 810 | int8_t |
850 | dc_parse_insts[] = { | 811 | dc_parse_insts[] = { |
@@ -1063,6 +1024,8 @@ static ERRORFUNC int bc_error(const char *msg) | |||
1063 | } | 1024 | } |
1064 | static ERRORFUNC int bc_error_bad_character(char c) | 1025 | static ERRORFUNC int bc_error_bad_character(char c) |
1065 | { | 1026 | { |
1027 | if (!c) | ||
1028 | IF_ERROR_RETURN_POSSIBLE(return) bc_error("NUL character"); | ||
1066 | IF_ERROR_RETURN_POSSIBLE(return) bc_error_fmt("bad character '%c'", c); | 1029 | IF_ERROR_RETURN_POSSIBLE(return) bc_error_fmt("bad character '%c'", c); |
1067 | } | 1030 | } |
1068 | static ERRORFUNC int bc_error_bad_expression(void) | 1031 | static ERRORFUNC int bc_error_bad_expression(void) |
@@ -1376,7 +1339,7 @@ static void bc_read_line(BcVec *vec, FILE *fp) | |||
1376 | goto intr; | 1339 | goto intr; |
1377 | } | 1340 | } |
1378 | #endif | 1341 | #endif |
1379 | c = fgetc(fp); | 1342 | do c = fgetc(fp); while (c == '\0'); |
1380 | if (c == EOF) { | 1343 | if (c == EOF) { |
1381 | if (ferror(fp)) | 1344 | if (ferror(fp)) |
1382 | bb_perror_msg_and_die("input error"); | 1345 | bb_perror_msg_and_die("input error"); |
@@ -3125,11 +3088,11 @@ static BC_STATUS zbc_lex_token(BcLex *l) | |||
3125 | 3088 | ||
3126 | // This is the workhorse of the lexer. | 3089 | // This is the workhorse of the lexer. |
3127 | switch (c) { | 3090 | switch (c) { |
3128 | case '\0': // probably never reached | 3091 | // case '\0': // probably never reached |
3129 | l->i--; | 3092 | // l->i--; |
3130 | l->t.t = BC_LEX_EOF; | 3093 | // l->t.t = BC_LEX_EOF; |
3131 | l->newline = true; | 3094 | // l->newline = true; |
3132 | break; | 3095 | // break; |
3133 | case '\n': | 3096 | case '\n': |
3134 | l->t.t = BC_LEX_NLINE; | 3097 | l->t.t = BC_LEX_NLINE; |
3135 | l->newline = true; | 3098 | l->newline = true; |
@@ -3370,6 +3333,58 @@ static BC_STATUS zdc_lex_string(BcLex *l) | |||
3370 | 3333 | ||
3371 | static BC_STATUS zdc_lex_token(BcLex *l) | 3334 | static BC_STATUS zdc_lex_token(BcLex *l) |
3372 | { | 3335 | { |
3336 | static const //BcLexType - should be this type, but narrower type saves size: | ||
3337 | uint8_t | ||
3338 | dc_lex_regs[] = { | ||
3339 | BC_LEX_OP_REL_EQ, BC_LEX_OP_REL_LE, BC_LEX_OP_REL_GE, BC_LEX_OP_REL_NE, | ||
3340 | BC_LEX_OP_REL_LT, BC_LEX_OP_REL_GT, BC_LEX_SCOLON, BC_LEX_COLON, | ||
3341 | BC_LEX_ELSE, BC_LEX_LOAD, BC_LEX_LOAD_POP, BC_LEX_OP_ASSIGN, | ||
3342 | BC_LEX_STORE_PUSH, | ||
3343 | }; | ||
3344 | static const //BcLexType - should be this type | ||
3345 | uint8_t | ||
3346 | dc_lex_tokens[] = { | ||
3347 | /* %&'( */ | ||
3348 | BC_LEX_OP_MODULUS, BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_LPAREN, | ||
3349 | /* )*+, */ | ||
3350 | BC_LEX_INVALID, BC_LEX_OP_MULTIPLY, BC_LEX_OP_PLUS, BC_LEX_INVALID, | ||
3351 | /* -./ */ | ||
3352 | BC_LEX_OP_MINUS, BC_LEX_INVALID, BC_LEX_OP_DIVIDE, | ||
3353 | /* 0123456789 */ | ||
3354 | BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_INVALID, | ||
3355 | BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_INVALID, | ||
3356 | BC_LEX_INVALID, BC_LEX_INVALID, | ||
3357 | /* :;<=>?@ */ | ||
3358 | BC_LEX_COLON, BC_LEX_SCOLON, BC_LEX_OP_REL_GT, BC_LEX_OP_REL_EQ, | ||
3359 | BC_LEX_OP_REL_LT, BC_LEX_KEY_READ, BC_LEX_INVALID, | ||
3360 | /* ABCDEFGH */ | ||
3361 | BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_INVALID, | ||
3362 | BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_EQ_NO_REG, BC_LEX_INVALID, | ||
3363 | /* IJKLMNOP */ | ||
3364 | BC_LEX_KEY_IBASE, BC_LEX_INVALID, BC_LEX_KEY_SCALE, BC_LEX_LOAD_POP, | ||
3365 | BC_LEX_INVALID, BC_LEX_OP_BOOL_NOT, BC_LEX_KEY_OBASE, BC_LEX_PRINT_STREAM, | ||
3366 | /* QRSTUVWXY */ | ||
3367 | BC_LEX_NQUIT, BC_LEX_POP, BC_LEX_STORE_PUSH, BC_LEX_INVALID, BC_LEX_INVALID, | ||
3368 | BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_SCALE_FACTOR, BC_LEX_INVALID, | ||
3369 | /* Z[\] */ | ||
3370 | BC_LEX_KEY_LENGTH, BC_LEX_INVALID, BC_LEX_INVALID, BC_LEX_INVALID, | ||
3371 | /* ^_` */ | ||
3372 | BC_LEX_OP_POWER, BC_LEX_NEG, BC_LEX_INVALID, | ||
3373 | /* abcdefgh */ | ||
3374 | BC_LEX_ASCIIFY, BC_LEX_INVALID, BC_LEX_CLEAR_STACK, BC_LEX_DUPLICATE, | ||
3375 | BC_LEX_ELSE, BC_LEX_PRINT_STACK, BC_LEX_INVALID, BC_LEX_INVALID, | ||
3376 | /* ijklmnop */ | ||
3377 | BC_LEX_STORE_IBASE, BC_LEX_INVALID, BC_LEX_STORE_SCALE, BC_LEX_LOAD, | ||
3378 | BC_LEX_INVALID, BC_LEX_PRINT_POP, BC_LEX_STORE_OBASE, BC_LEX_KEY_PRINT, | ||
3379 | /* qrstuvwx */ | ||
3380 | BC_LEX_KEY_QUIT, BC_LEX_SWAP, BC_LEX_OP_ASSIGN, BC_LEX_INVALID, | ||
3381 | BC_LEX_INVALID, BC_LEX_KEY_SQRT, BC_LEX_INVALID, BC_LEX_EXECUTE, | ||
3382 | /* yz */ | ||
3383 | BC_LEX_INVALID, BC_LEX_STACK_LEVEL, | ||
3384 | /* {|}~ */ | ||
3385 | BC_LEX_LBRACE, BC_LEX_OP_MODEXP, BC_LEX_INVALID, BC_LEX_OP_DIVMOD, | ||
3386 | }; | ||
3387 | |||
3373 | BcStatus s = BC_STATUS_SUCCESS; | 3388 | BcStatus s = BC_STATUS_SUCCESS; |
3374 | char c = l->buf[l->i++], c2; | 3389 | char c = l->buf[l->i++], c2; |
3375 | size_t i; | 3390 | size_t i; |
@@ -3380,16 +3395,16 @@ static BC_STATUS zdc_lex_token(BcLex *l) | |||
3380 | } | 3395 | } |
3381 | 3396 | ||
3382 | if (c >= '%' && c <= '~' | 3397 | if (c >= '%' && c <= '~' |
3383 | && (l->t.t = dc_lex_tokens[(c - '%')]) != BC_LEX_INVALID | 3398 | && (l->t.t = dc_lex_tokens[c - '%']) != BC_LEX_INVALID |
3384 | ) { | 3399 | ) { |
3385 | RETURN_STATUS(s); | 3400 | RETURN_STATUS(s); |
3386 | } | 3401 | } |
3387 | 3402 | ||
3388 | // This is the workhorse of the lexer. | 3403 | // This is the workhorse of the lexer. |
3389 | switch (c) { | 3404 | switch (c) { |
3390 | case '\0': | 3405 | // case '\0': // probably never reached |
3391 | l->t.t = BC_LEX_EOF; | 3406 | // l->t.t = BC_LEX_EOF; |
3392 | break; | 3407 | // break; |
3393 | case '\n': | 3408 | case '\n': |
3394 | case '\t': | 3409 | case '\t': |
3395 | case '\v': | 3410 | case '\v': |