aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-12-17 11:58:20 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2018-12-17 11:58:20 +0100
commitb44a7f1d6642e2da39e9f27e0b504f662ca443a2 (patch)
tree80593654277f46a82b5a7eab8efe766da5fc1872
parente42cc19b51febacba5e8f30f548bf294018d9e7c (diff)
downloadbusybox-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.c113
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
809static const //BcLexType - should be this type, but narrower type saves size:
810uint8_t
811dc_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
818static const //BcLexType - should be this type
819uint8_t
820dc_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
848static const //BcInst - should be this type. Using signed narrow type since BC_INST_INVALID is -1 809static const //BcInst - should be this type. Using signed narrow type since BC_INST_INVALID is -1
849int8_t 810int8_t
850dc_parse_insts[] = { 811dc_parse_insts[] = {
@@ -1063,6 +1024,8 @@ static ERRORFUNC int bc_error(const char *msg)
1063} 1024}
1064static ERRORFUNC int bc_error_bad_character(char c) 1025static 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}
1068static ERRORFUNC int bc_error_bad_expression(void) 1031static 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
3371static BC_STATUS zdc_lex_token(BcLex *l) 3334static 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':