diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2019-01-08 18:08:48 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2019-01-08 18:10:00 +0100 |
commit | fc7aa7a296cf13d13aae5457f4f7cd2b73700234 (patch) | |
tree | 322b3d74f6664b18ed29b72a251e16783cf99e5c /miscutils/bc.c | |
parent | ce51140664d82300d25b096b4a41f01fdfd766b3 (diff) | |
download | busybox-w32-fc7aa7a296cf13d13aae5457f4f7cd2b73700234.tar.gz busybox-w32-fc7aa7a296cf13d13aae5457f4f7cd2b73700234.tar.bz2 busybox-w32-fc7aa7a296cf13d13aae5457f4f7cd2b73700234.zip |
bc: disallow invalid syntax like "{ print 1 print 2 }"
statement parsing must NOT eat the terminator: caller needs to know
what it was, to correctly decide whether it is a valid one.
function old new delta
zxc_program_read - 234 +234
zdc_program_printStream - 144 +144
zbc_parse_stmt_possibly_auto 1413 1460 +47
zxc_vm_process 869 859 -10
zxc_program_exec 4116 4101 -15
zdc_program_asciify 368 - -368
------------------------------------------------------------------------------
(add/remove: 2/1 grow/shrink: 1/2 up/down: 425/-393) Total: 32 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'miscutils/bc.c')
-rw-r--r-- | miscutils/bc.c | 36 |
1 files changed, 21 insertions, 15 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c index bf174dafb..faf6226e1 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c | |||
@@ -4554,11 +4554,11 @@ static BC_STATUS zbc_parse_stmt_possibly_auto(bool auto_allowed) | |||
4554 | 4554 | ||
4555 | if (p->lex == XC_LEX_NLINE) { | 4555 | if (p->lex == XC_LEX_NLINE) { |
4556 | dbg_lex_done("%s:%d done (seen XC_LEX_NLINE)", __func__, __LINE__); | 4556 | dbg_lex_done("%s:%d done (seen XC_LEX_NLINE)", __func__, __LINE__); |
4557 | RETURN_STATUS(zxc_lex_next()); | 4557 | RETURN_STATUS(s); |
4558 | } | 4558 | } |
4559 | if (p->lex == BC_LEX_SCOLON) { | 4559 | if (p->lex == BC_LEX_SCOLON) { |
4560 | dbg_lex_done("%s:%d done (seen BC_LEX_SCOLON)", __func__, __LINE__); | 4560 | dbg_lex_done("%s:%d done (seen BC_LEX_SCOLON)", __func__, __LINE__); |
4561 | RETURN_STATUS(zxc_lex_next()); | 4561 | RETURN_STATUS(s); |
4562 | } | 4562 | } |
4563 | 4563 | ||
4564 | if (p->lex == BC_LEX_LBRACE) { | 4564 | if (p->lex == BC_LEX_LBRACE) { |
@@ -4574,9 +4574,19 @@ static BC_STATUS zbc_parse_stmt_possibly_auto(bool auto_allowed) | |||
4574 | } | 4574 | } |
4575 | while (p->lex != BC_LEX_RBRACE) { | 4575 | while (p->lex != BC_LEX_RBRACE) { |
4576 | dbg_lex("%s:%d block parsing loop", __func__, __LINE__); | 4576 | dbg_lex("%s:%d block parsing loop", __func__, __LINE__); |
4577 | //FIXME: prevent wrong syntax such as "{ print 1 print 2 }" | ||
4578 | s = zbc_parse_stmt(); | 4577 | s = zbc_parse_stmt(); |
4579 | if (s) RETURN_STATUS(s); | 4578 | if (s) RETURN_STATUS(s); |
4579 | // Check that next token is a correct stmt delimiter - | ||
4580 | // disallows "print 1 print 2" and such. | ||
4581 | if (p->lex == BC_LEX_RBRACE) | ||
4582 | break; | ||
4583 | if (p->lex != BC_LEX_SCOLON | ||
4584 | && p->lex != XC_LEX_NLINE | ||
4585 | ) { | ||
4586 | RETURN_STATUS(bc_error_at("bad statement terminator")); | ||
4587 | } | ||
4588 | s = zxc_lex_next(); | ||
4589 | if (s) RETURN_STATUS(s); | ||
4580 | } | 4590 | } |
4581 | s = zxc_lex_next(); | 4591 | s = zxc_lex_next(); |
4582 | dbg_lex_done("%s:%d done (seen BC_LEX_RBRACE)", __func__, __LINE__); | 4592 | dbg_lex_done("%s:%d done (seen BC_LEX_RBRACE)", __func__, __LINE__); |
@@ -4665,9 +4675,11 @@ static BC_STATUS zbc_parse_stmt_or_funcdef(void) | |||
4665 | BcStatus s; | 4675 | BcStatus s; |
4666 | 4676 | ||
4667 | dbg_lex_enter("%s:%d entered", __func__, __LINE__); | 4677 | dbg_lex_enter("%s:%d entered", __func__, __LINE__); |
4668 | if (p->lex == XC_LEX_EOF) | 4678 | //why? |
4669 | s = bc_error("end of file"); | 4679 | // if (p->lex == XC_LEX_EOF) |
4670 | else if (p->lex == BC_LEX_KEY_DEFINE) { | 4680 | // s = bc_error("end of file"); |
4681 | // else | ||
4682 | if (p->lex == BC_LEX_KEY_DEFINE) { | ||
4671 | dbg_lex("%s:%d p->lex:BC_LEX_KEY_DEFINE", __func__, __LINE__); | 4683 | dbg_lex("%s:%d p->lex:BC_LEX_KEY_DEFINE", __func__, __LINE__); |
4672 | s = zbc_parse_funcdef(); | 4684 | s = zbc_parse_funcdef(); |
4673 | } else { | 4685 | } else { |
@@ -6781,7 +6793,6 @@ static BC_STATUS zxc_vm_process(const char *text) | |||
6781 | s = zxc_parse_text_init(text); // does the first zxc_lex_next() | 6793 | s = zxc_parse_text_init(text); // does the first zxc_lex_next() |
6782 | if (s) RETURN_STATUS(s); | 6794 | if (s) RETURN_STATUS(s); |
6783 | 6795 | ||
6784 | IF_BC(check_eof:) | ||
6785 | while (G.prs.lex != XC_LEX_EOF) { | 6796 | while (G.prs.lex != XC_LEX_EOF) { |
6786 | BcInstPtr *ip; | 6797 | BcInstPtr *ip; |
6787 | BcFunc *f; | 6798 | BcFunc *f; |
@@ -6789,14 +6800,6 @@ static BC_STATUS zxc_vm_process(const char *text) | |||
6789 | dbg_lex("%s:%d G.prs.lex:%d, parsing...", __func__, __LINE__, G.prs.lex); | 6800 | dbg_lex("%s:%d G.prs.lex:%d, parsing...", __func__, __LINE__, G.prs.lex); |
6790 | if (IS_BC) { | 6801 | if (IS_BC) { |
6791 | #if ENABLE_BC | 6802 | #if ENABLE_BC |
6792 | if (G.prs.lex == BC_LEX_SCOLON | ||
6793 | || G.prs.lex == XC_LEX_NLINE | ||
6794 | ) { | ||
6795 | s = zxc_lex_next(); | ||
6796 | if (s) goto err; | ||
6797 | goto check_eof; | ||
6798 | } | ||
6799 | |||
6800 | s = zbc_parse_stmt_or_funcdef(); | 6803 | s = zbc_parse_stmt_or_funcdef(); |
6801 | if (s) goto err; | 6804 | if (s) goto err; |
6802 | 6805 | ||
@@ -6855,6 +6858,9 @@ static BC_STATUS zxc_vm_process(const char *text) | |||
6855 | #endif | 6858 | #endif |
6856 | IF_BC(bc_vec_pop_all(&f->strs);) | 6859 | IF_BC(bc_vec_pop_all(&f->strs);) |
6857 | IF_BC(bc_vec_pop_all(&f->consts);) | 6860 | IF_BC(bc_vec_pop_all(&f->consts);) |
6861 | // We are at SCOLON/NLINE, skip it: | ||
6862 | s = zxc_lex_next(); | ||
6863 | if (s) goto err; | ||
6858 | } else { | 6864 | } else { |
6859 | if (G.prog.results.len == 0 | 6865 | if (G.prog.results.len == 0 |
6860 | && G.prog.vars.len == 0 | 6866 | && G.prog.vars.len == 0 |