Skip to content

Commit

Permalink
Fix if (0);"test"||fail() 2v19 regression - strings after if(0) did…
Browse files Browse the repository at this point in the history
…n't get interpreted

Ensure eval("1;;;")==1 - eval("1;")==1 before, but not eval("1;;")

We hit this with minification in the AT library... If there's a string right after an if(0) it
doesn't get parsed!

This happens because since 2v19ish we're no longer storing string contents in RAM if
we're not supposed to be executing. But we need to be sure we don't Lex too far ahead
with execute=false set
  • Loading branch information
gfwilliams committed Sep 13, 2023
1 parent e51db23 commit 1f80e6e
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 3 deletions.
2 changes: 2 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
Bangle.js2: When rendering overlays, *do not* use the current FG/BG color for 1 bit overlays
nRF52 SDK15: Fix UART when >1 central link enabled
Bangle.js2: Allow 2 central links at once
Fix `if (0);"test"||fail()` 2v19 regression - strings after if(0) didn't get interpreted
Ensure eval("1;;;")==1 - eval("1;")==1 before, but not eval("1;;")

2v19 : Fix Object.values/entries for numeric keys after 2v18 regression (fix #2375)
nRF52: for SD>5 use static buffers for advertising and scan response data (#2367)
Expand Down
13 changes: 10 additions & 3 deletions src/jsparse.c
Original file line number Diff line number Diff line change
Expand Up @@ -2318,7 +2318,6 @@ NO_INLINE JsVar *jspeBlockOrStatement() {
return 0;
} else {
JsVar *v = jspeStatement();
if (lex->tk==';') JSP_ASSERT_MATCH(';');
return v;
}
}
Expand All @@ -2330,6 +2329,7 @@ NO_INLINE JsVar *jspParse() {
while (!JSP_SHOULDNT_PARSE && lex->tk != LEX_EOF) {
jsvUnLock(v);
v = jspeBlockOrStatement();
while (lex->tk==';') JSP_ASSERT_MATCH(';');
jsvCheckReferenceError(v);
}
return v;
Expand Down Expand Up @@ -2410,7 +2410,9 @@ NO_INLINE JsVar *jspeStatementIf() {
JSP_SAVE_EXECUTE();
if (!cond) jspSetNoExecute();
JsExecFlags hasError = 0;
JsVar *a = jspeBlockOrStatement();
JsVar *a = 0;
if (lex->tk!=';')
a = jspeBlockOrStatement();
hasError |= execInfo.execute&EXEC_ERROR_MASK;
if (!cond) {
jsvUnLock(a);
Expand All @@ -2419,11 +2421,16 @@ NO_INLINE JsVar *jspeStatementIf() {
} else {
result = a;
}
/* We must manually parse ';' here, because if we did it when execInfo.execute==false (eg `if(0);`)
then if a String comes straight after it wouldn't have been interpreted */
if (lex->tk==';') JSP_ASSERT_MATCH(';');
if (lex->tk==LEX_R_ELSE) {
JSP_ASSERT_MATCH(LEX_R_ELSE);
JSP_SAVE_EXECUTE();
if (cond) jspSetNoExecute();
JsVar *a = jspeBlockOrStatement();
JsVar *a = 0;
if (lex->tk!=';')
a = jspeBlockOrStatement();
hasError |= execInfo.execute&EXEC_ERROR_MASK;
if (cond) {
jsvUnLock(a);
Expand Down
20 changes: 20 additions & 0 deletions tests/test_string_noparse.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
function fail(n) {
throw new Error("FAILED at "+n);
}

/* We hit this with minification in the AT library... If there's a string right after an if(0) it
doesn't get parsed!
This happens because since 2v19ish we're no longer storing string contents in RAM if
we're not supposed to be executing. But we need to be sure we don't Lex too far ahead
with execute=false set
*/

while (0) 1;"test"||fail("while") // ok
for (;0;);"test"||fail("for") // ok
if (1) 1;"test"||fail("if(1)1;") // ok
if (0) 1;"test"||fail("if(0)1;") // failed
if (0);"test"||fail("if(0);") // failed
if (1);else;"test"||fail("if(1);else;") // failed
// if we got here we're ok
result=1

0 comments on commit 1f80e6e

Please sign in to comment.