diff --git a/js/src/js.msg b/js/src/js.msg index 7975ca614c90..13e0f703a6c6 100644 --- a/js/src/js.msg +++ b/js/src/js.msg @@ -217,7 +217,7 @@ MSG_DEF(JSMSG_UNTERMINATED_REGEXP, 141, 0, JSEXN_SYNTAXERR, "unterminated reg MSG_DEF(JSMSG_BAD_REGEXP_FLAG, 142, 0, JSEXN_SYNTAXERR, "invalid flag after regular expression") MSG_DEF(JSMSG_SHARPVAR_TOO_BIG, 143, 0, JSEXN_SYNTAXERR, "overlarge sharp variable number") MSG_DEF(JSMSG_ILLEGAL_CHARACTER, 144, 0, JSEXN_SYNTAXERR, "illegal character") -MSG_DEF(JSMSG_BAD_OCTAL, 145, 1, JSEXN_NONE, "{0} is not a legal ECMA-262 numeric constant") +MSG_DEF(JSMSG_BAD_OCTAL, 145, 1, JSEXN_NONE, "{0} is not a legal ECMA-262 octal constant") MSG_DEF(JSMSG_BAD_INDIRECT_CALL, 146, 1, JSEXN_EVALERR, "function {0} must be called directly, and not by way of a function of another name.") MSG_DEF(JSMSG_UNCAUGHT_EXCEPTION, 147, 1, JSEXN_NONE, "uncaught exception: {0}") MSG_DEF(JSMSG_INVALID_BACKREF, 148, 0, JSEXN_SYNTAXERR, "non-octal digit in an escape sequence that doesn't match a back-reference") diff --git a/js/src/jsparse.c b/js/src/jsparse.c index 1547dc03be50..27cd1b4a647b 100644 --- a/js/src/jsparse.c +++ b/js/src/jsparse.c @@ -292,10 +292,12 @@ CheckFinalReturn(JSParseNode *pn) if (!pn->pn_head) return JS_FALSE; return CheckFinalReturn(PN_LAST(pn)); + case TOK_IF: ok = CheckFinalReturn(pn->pn_kid2); ok &= pn->pn_kid3 && CheckFinalReturn(pn->pn_kid3); return ok; + #if JS_HAS_SWITCH_STATEMENT case TOK_SWITCH: ok = JS_TRUE; @@ -312,10 +314,36 @@ CheckFinalReturn(JSParseNode *pn) ok &= hasDefault; return ok; #endif /* JS_HAS_SWITCH_STATEMENT */ + case TOK_WITH: return CheckFinalReturn(pn->pn_right); + case TOK_RETURN: return JS_TRUE; + +#if JS_HAS_EXCEPTIONS + case TOK_THROW: + return JS_TRUE; + + case TOK_TRY: + /* If we have a finally block that returns, we are done. */ + if (pn->pn_kid3 && CheckFinalReturn(pn->pn_kid3)) + return JS_TRUE; + + /* Else check the try block and any and all catch statements. */ + ok = CheckFinalReturn(pn->pn_kid1); + if (pn->pn_kid2) + ok &= CheckFinalReturn(pn->pn_kid2); + return ok; + + case TOK_CATCH: + /* Check this block's code and iterate over further catch blocks. */ + ok = CheckFinalReturn(pn->pn_kid3); + for (pn2 = pn->pn_kid2; pn2; pn2 = pn2->pn_kid2) + ok &= CheckFinalReturn(pn2->pn_kid3); + return ok; +#endif + default: return JS_FALSE; } @@ -1191,15 +1219,15 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc) return NULL; MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_TRY); - pn->pn_kid2 = NULL; catchtail = pn; - while(js_PeekToken(cx, ts) == TOK_CATCH) { + while (js_PeekToken(cx, ts) == TOK_CATCH) { /* check for another catch after unconditional catch */ - if (!catchtail->pn_kid1->pn_expr) { + if (catchtail != pn && !catchtail->pn_kid1->pn_expr) { js_ReportCompileErrorNumber(cx, ts, JSREPORT_ERROR, JSMSG_CATCH_AFTER_GENERAL); return NULL; } + /* * legal catch forms are: * catch (v) @@ -1502,7 +1530,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc) #if JS_HAS_DEBUGGER_KEYWORD case TOK_DEBUGGER: - if(!WellTerminated(cx, ts, TOK_ERROR)) + if (!WellTerminated(cx, ts, TOK_ERROR)) return NULL; pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY); if (!pn) diff --git a/js/src/jsscan.c b/js/src/jsscan.c index c537272a799d..2ace266a6896 100644 --- a/js/src/jsscan.c +++ b/js/src/jsscan.c @@ -803,27 +803,29 @@ retry: c = GetChar(ts); radix = 16; } else if (JS7_ISDEC(c)) { + radix = 8; + } + } + + while (JS7_ISHEX(c)) { + if (radix < 16) { + if (JS7_ISLET(c)) + break; + /* * We permit 08 and 09 as decimal numbers, which makes our * behaviour a superset of the ECMA numeric grammar. We might * not always be so permissive, so we warn about it. */ - if (c > '7' && JSVERSION_IS_ECMA(cx->version)) { + if (radix == 8 && c >= '8') { if (!js_ReportCompileErrorNumber(cx, ts, JSREPORT_WARNING, JSMSG_BAD_OCTAL, c == '8' ? "08" : "09")) { RETURN(TOK_ERROR); } radix = 10; - } else { - radix = 8; } - } - } - - while (JS7_ISHEX(c)) { - if (radix < 16 && (JS7_ISLET(c) || (radix == 8 && c >= '8'))) - break; + } if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c)) RETURN(TOK_ERROR); c = GetChar(ts);