aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-12-25 18:37:52 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2018-12-25 18:37:52 +0100
commit2638454464b944f9c407326257851bab13c045ec (patch)
tree6afd3f8d336f4f22cc7bf87b40d896fadeff8879
parent5fa74b9efc538b55ec164ce3886eeea782016487 (diff)
downloadbusybox-w32-2638454464b944f9c407326257851bab13c045ec.tar.gz
busybox-w32-2638454464b944f9c407326257851bab13c045ec.tar.bz2
busybox-w32-2638454464b944f9c407326257851bab13c045ec.zip
bc: add code to detect errors like "print 1 print 2"
function old new delta zbc_vm_process 831 925 +94 zbc_program_exec 3964 3976 +12 zdc_program_execStr 506 512 +6 zbc_lex_next 2161 2167 +6 zbc_program_assign 419 424 +5 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 5/0 up/down: 123/0) Total: 123 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--miscutils/bc.c49
1 files changed, 39 insertions, 10 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c
index 7c8edcf33..8b44d4425 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -711,6 +711,7 @@ dc_LEX_to_INST[] = { // starts at XC_LEX_OP_POWER // corresponding XC/DC_L
711 711
712typedef struct BcLex { 712typedef struct BcLex {
713 const char *buf; 713 const char *buf;
714 const char *lex_next_at; // last lex_next() was called at this string
714 size_t i; 715 size_t i;
715 size_t line; 716 size_t line;
716 size_t len; 717 size_t len;
@@ -2990,9 +2991,11 @@ static BC_STATUS zbc_lex_next(BcLex *l)
2990 } 2991 }
2991 // here it's guaranteed that l->i is below l->len 2992 // here it's guaranteed that l->i is below l->len
2992 } 2993 }
2994 l->lex_next_at = l->buf + l->i;
2993 dbg_lex("next string to parse:'%.*s'", 2995 dbg_lex("next string to parse:'%.*s'",
2994 (int)(strchrnul(l->buf + l->i, '\n') - (l->buf + l->i)), 2996 (int)(strchrnul(l->lex_next_at, '\n') - l->lex_next_at),
2995 l->buf + l->i); 2997 l->lex_next_at
2998 );
2996 if (IS_BC) { 2999 if (IS_BC) {
2997 IF_BC(s = zbc_lex_token(l)); 3000 IF_BC(s = zbc_lex_token(l));
2998 } else { 3001 } else {
@@ -6756,13 +6759,38 @@ static BC_STATUS zbc_vm_process(const char *text)
6756 6759
6757 dbg_lex("%s:%d G.prs.l.lex:%d, parsing...", __func__, __LINE__, G.prs.l.lex); 6760 dbg_lex("%s:%d G.prs.l.lex:%d, parsing...", __func__, __LINE__, G.prs.l.lex);
6758 if (IS_BC) { 6761 if (IS_BC) {
6759// FIXME: "eating" of stmt delimiters is coded inconsistently 6762#if ENABLE_BC
6760// (sometimes zbc_parse_stmt() eats the delimiter, sometimes don't), 6763 s = zbc_parse_stmt_or_funcdef(&G.prs);
6761// which causes bugs such as "print 1 print 2" erroneously accepted, 6764 if (s) goto err;
6762// or "print 1 else 2" detecting parse error only after executing 6765
6763// "print 1" part. 6766 // Check that next token is not bogus, and skip over
6764 IF_BC(s = zbc_parse_stmt_or_funcdef(&G.prs)); 6767 // stmt delimiter(s) - newlines and semicolons
6768 s = 1; // s == 1 on first iteration only
6769 for (;;) {
6770 if (G.prs.l.lex == XC_LEX_EOF)
6771 goto execute; // this goto avoids resetting 's' to zero
6772 if (G.prs.l.lex != BC_LEX_SCOLON
6773 && G.prs.l.lex != XC_LEX_NLINE
6774 ) {
6775 const char *err_at;
6776 // Not newline and not semicolon
6777 if (s == 0) // saw at least one NL/semicolon before it?
6778 break; // yes, good
6779//TODO: commolalize for other parse errors:
6780 err_at = G.prs.l.lex_next_at ? G.prs.l.lex_next_at : "UNKNOWN";
6781 bc_error_fmt("bad statement terminator at '%.*s'",
6782 (int)(strchrnul(err_at, '\n') - err_at),
6783 err_at
6784 );
6785 goto err;
6786 }
6787 // NL or semicolon: skip it, set s = 0, repeat
6788 s = zbc_lex_next(&G.prs.l);
6789 if (s) goto err;
6790 }
6791#endif
6765 } else { 6792 } else {
6793#if ENABLE_DC
6766 // Most of dc parsing assumes all whitespace, 6794 // Most of dc parsing assumes all whitespace,
6767 // including '\n', is eaten. 6795 // including '\n', is eaten.
6768 while (G.prs.l.lex == XC_LEX_NLINE) { 6796 while (G.prs.l.lex == XC_LEX_NLINE) {
@@ -6771,14 +6799,15 @@ static BC_STATUS zbc_vm_process(const char *text)
6771 if (G.prs.l.lex == XC_LEX_EOF) 6799 if (G.prs.l.lex == XC_LEX_EOF)
6772 goto done; 6800 goto done;
6773 } 6801 }
6774 IF_DC(s = zdc_parse_expr(&G.prs)); 6802 s = zdc_parse_expr(&G.prs);
6803#endif
6775 } 6804 }
6776 if (s || G_interrupt) { 6805 if (s || G_interrupt) {
6777 err: 6806 err:
6778 bc_parse_reset(&G.prs); // includes bc_program_reset() 6807 bc_parse_reset(&G.prs); // includes bc_program_reset()
6779 RETURN_STATUS(BC_STATUS_FAILURE); 6808 RETURN_STATUS(BC_STATUS_FAILURE);
6780 } 6809 }
6781 6810 IF_BC(execute:)
6782 dbg_lex("%s:%d executing...", __func__, __LINE__); 6811 dbg_lex("%s:%d executing...", __func__, __LINE__);
6783 s = zbc_program_exec(); 6812 s = zbc_program_exec();
6784 if (s) { 6813 if (s) {