[git commit branch/1_30_stable] bc: disallow invalid syntax like "{ print 1 print 2 }"

Denys Vlasenko vda.linux at googlemail.com
Thu Feb 14 13:40:57 UTC 2019


commit: https://git.busybox.net/busybox/commit/?id=715273a992edb0943fdffb9bc9bb9b506de9f7de
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/1_30_stable

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 at googlemail.com>
---
 miscutils/bc.c | 36 +++++++++++++++++++++---------------
 1 file changed, 21 insertions(+), 15 deletions(-)

diff --git a/miscutils/bc.c b/miscutils/bc.c
index 74884557a..b196957f4 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -4554,11 +4554,11 @@ static BC_STATUS zbc_parse_stmt_possibly_auto(bool auto_allowed)
 
 	if (p->lex == XC_LEX_NLINE) {
 		dbg_lex_done("%s:%d done (seen XC_LEX_NLINE)", __func__, __LINE__);
-		RETURN_STATUS(zxc_lex_next());
+		RETURN_STATUS(s);
 	}
 	if (p->lex == BC_LEX_SCOLON) {
 		dbg_lex_done("%s:%d done (seen BC_LEX_SCOLON)", __func__, __LINE__);
-		RETURN_STATUS(zxc_lex_next());
+		RETURN_STATUS(s);
 	}
 
 	if (p->lex == BC_LEX_LBRACE) {
@@ -4574,9 +4574,19 @@ static BC_STATUS zbc_parse_stmt_possibly_auto(bool auto_allowed)
 		}
 		while (p->lex != BC_LEX_RBRACE) {
 			dbg_lex("%s:%d block parsing loop", __func__, __LINE__);
-//FIXME: prevent wrong syntax such as "{ print 1 print 2 }"
 			s = zbc_parse_stmt();
 			if (s) RETURN_STATUS(s);
+			// Check that next token is a correct stmt delimiter -
+			// disallows "print 1 print 2" and such.
+			if (p->lex == BC_LEX_RBRACE)
+				break;
+			if (p->lex != BC_LEX_SCOLON
+			 && p->lex != XC_LEX_NLINE
+			) {
+				RETURN_STATUS(bc_error_at("bad statement terminator"));
+			}
+		        s = zxc_lex_next();
+			if (s) RETURN_STATUS(s);
 		}
 		s = zxc_lex_next();
 		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)
 	BcStatus s;
 
 	dbg_lex_enter("%s:%d entered", __func__, __LINE__);
-	if (p->lex == XC_LEX_EOF)
-		s = bc_error("end of file");
-	else if (p->lex == BC_LEX_KEY_DEFINE) {
+//why?
+//	if (p->lex == XC_LEX_EOF)
+//		s = bc_error("end of file");
+//	else
+	if (p->lex == BC_LEX_KEY_DEFINE) {
 		dbg_lex("%s:%d p->lex:BC_LEX_KEY_DEFINE", __func__, __LINE__);
 		s = zbc_parse_funcdef();
 	} else {
@@ -6781,7 +6793,6 @@ static BC_STATUS zxc_vm_process(const char *text)
 	s = zxc_parse_text_init(text); // does the first zxc_lex_next()
 	if (s) RETURN_STATUS(s);
 
- IF_BC(check_eof:)
 	while (G.prs.lex != XC_LEX_EOF) {
 		BcInstPtr *ip;
 		BcFunc *f;
@@ -6789,14 +6800,6 @@ static BC_STATUS zxc_vm_process(const char *text)
 		dbg_lex("%s:%d G.prs.lex:%d, parsing...", __func__, __LINE__, G.prs.lex);
 		if (IS_BC) {
 #if ENABLE_BC
-			if (G.prs.lex == BC_LEX_SCOLON
-			 || G.prs.lex == XC_LEX_NLINE
-			) {
-				s = zxc_lex_next();
-				if (s) goto err;
-				goto check_eof;
-			}
-
 			s = zbc_parse_stmt_or_funcdef();
 			if (s) goto err;
 
@@ -6855,6 +6858,9 @@ static BC_STATUS zxc_vm_process(const char *text)
 #endif
 			IF_BC(bc_vec_pop_all(&f->strs);)
 			IF_BC(bc_vec_pop_all(&f->consts);)
+			// We are at SCOLON/NLINE, skip it:
+			s = zxc_lex_next();
+			if (s) goto err;
 		} else {
 			if (G.prog.results.len == 0
 			 && G.prog.vars.len == 0


More information about the busybox-cvs mailing list