From fc7aa7a296cf13d13aae5457f4f7cd2b73700234 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 8 Jan 2019 18:08:48 +0100 Subject: [PATCH 38/84] 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 --- miscutils/bc.c | 36 +++++++++++++++++++++--------------- 1 file 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) 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 -- 2.16.2