aboutsummaryrefslogtreecommitdiff
path: root/miscutils/bc.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2019-01-08 18:08:48 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2019-01-08 18:10:00 +0100
commitfc7aa7a296cf13d13aae5457f4f7cd2b73700234 (patch)
tree322b3d74f6664b18ed29b72a251e16783cf99e5c /miscutils/bc.c
parentce51140664d82300d25b096b4a41f01fdfd766b3 (diff)
downloadbusybox-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.c36
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