diff options
Diffstat (limited to 'js/src')
-rw-r--r-- | js/src/frontend/TokenStream.cpp | 57 | ||||
-rw-r--r-- | js/src/frontend/TokenStream.h | 5 | ||||
-rw-r--r-- | js/src/irregexp/RegExpParser.cpp | 6 | ||||
-rw-r--r-- | js/src/irregexp/RegExpParser.h | 2 | ||||
-rw-r--r-- | js/src/js.msg | 2 |
5 files changed, 51 insertions, 21 deletions
diff --git a/js/src/frontend/TokenStream.cpp b/js/src/frontend/TokenStream.cpp index e8d622d38..abb7228eb 100644 --- a/js/src/frontend/TokenStream.cpp +++ b/js/src/frontend/TokenStream.cpp @@ -821,6 +821,19 @@ TokenStream::error(unsigned errorNumber, ...) va_end(args); } +void +TokenStream::errorAt(uint32_t offset, unsigned errorNumber, ...) +{ + va_list args; + va_start(args, errorNumber); +#ifdef DEBUG + bool result = +#endif + reportCompileErrorNumberVA(offset, JSREPORT_ERROR, errorNumber, args); + MOZ_ASSERT(!result, "reporting an error returned true?"); + va_end(args); +} + // We have encountered a '\': check for a Unicode escape sequence after it. // Return the length of the escape sequence and the character code point (by // value) if we found a Unicode escape sequence. Otherwise, return 0. In both @@ -1869,32 +1882,47 @@ TokenStream::getTokenInternal(TokenKind* ttp, Modifier modifier) } bool -TokenStream::getBracedUnicode(uint32_t* cp) +TokenStream::matchBracedUnicode(bool* matched, uint32_t* cp) { + if (peekChar() != '{') { + *matched = false; + return true; + } + consumeKnownChar('{'); + uint32_t start = userbuf.offset(); + bool first = true; - int32_t c; uint32_t code = 0; - while (true) { - c = getCharIgnoreEOL(); - if (c == EOF) + do { + int32_t c = getCharIgnoreEOL(); + if (c == EOF) { + error(JSMSG_MALFORMED_ESCAPE, "Unicode"); return false; + } if (c == '}') { - if (first) + if (first) { + error(JSMSG_MALFORMED_ESCAPE, "Unicode"); return false; + } break; } - if (!JS7_ISHEX(c)) + if (!JS7_ISHEX(c)) { + error(JSMSG_MALFORMED_ESCAPE, "Unicode"); return false; + } code = (code << 4) | JS7_UNHEX(c); - if (code > unicode::NonBMPMax) + if (code > unicode::NonBMPMax) { + errorAt(start, JSMSG_UNICODE_OVERFLOW, "escape sequence"); return false; + } first = false; - } + } while (true); + *matched = true; *cp = code; return true; } @@ -1936,12 +1964,11 @@ TokenStream::getStringOrTemplateToken(int untilChar, Token** tp) // Unicode character specification. case 'u': { - if (peekChar() == '{') { - uint32_t code; - if (!getBracedUnicode(&code)) { - error(JSMSG_MALFORMED_ESCAPE, "Unicode"); - return false; - } + bool matched; + uint32_t code; + if (!matchBracedUnicode(&matched, &code)) + return false; + if (matched) { MOZ_ASSERT(code <= unicode::NonBMPMax); if (code < unicode::NonBMPMin) { diff --git a/js/src/frontend/TokenStream.h b/js/src/frontend/TokenStream.h index 18e9cb3ca..19385b499 100644 --- a/js/src/frontend/TokenStream.h +++ b/js/src/frontend/TokenStream.h @@ -368,6 +368,9 @@ class MOZ_STACK_CLASS TokenStream // Report the given error at the current offset. void error(unsigned errorNumber, ...); + // Report the given error at the given offset. + void errorAt(uint32_t offset, unsigned errorNumber, ...); + // Warn at the current offset. MOZ_MUST_USE bool warning(unsigned errorNumber, ...); @@ -952,7 +955,7 @@ class MOZ_STACK_CLASS TokenStream MOZ_MUST_USE bool getTokenInternal(TokenKind* ttp, Modifier modifier); - MOZ_MUST_USE bool getBracedUnicode(uint32_t* code); + MOZ_MUST_USE bool matchBracedUnicode(bool* matched, uint32_t* code); MOZ_MUST_USE bool getStringOrTemplateToken(int untilChar, Token** tp); int32_t getChar(); diff --git a/js/src/irregexp/RegExpParser.cpp b/js/src/irregexp/RegExpParser.cpp index ccc6ae3eb..8bd88047a 100644 --- a/js/src/irregexp/RegExpParser.cpp +++ b/js/src/irregexp/RegExpParser.cpp @@ -243,10 +243,10 @@ RegExpParser<CharT>::RegExpParser(frontend::TokenStream& ts, LifoAlloc* alloc, template <typename CharT> RegExpTree* -RegExpParser<CharT>::ReportError(unsigned errorNumber) +RegExpParser<CharT>::ReportError(unsigned errorNumber, const char* param /* = nullptr */) { gc::AutoSuppressGC suppressGC(ts.context()); - ts.reportError(errorNumber); + ts.reportError(errorNumber, param); return nullptr; } @@ -350,7 +350,7 @@ RegExpParser<CharT>::ParseBracedHexEscape(widechar* value) } code = (code << 4) | d; if (code > unicode::NonBMPMax) { - ReportError(JSMSG_UNICODE_OVERFLOW); + ReportError(JSMSG_UNICODE_OVERFLOW, "regular expression"); return false; } Advance(); diff --git a/js/src/irregexp/RegExpParser.h b/js/src/irregexp/RegExpParser.h index b5228a86f..0a7e61858 100644 --- a/js/src/irregexp/RegExpParser.h +++ b/js/src/irregexp/RegExpParser.h @@ -211,7 +211,7 @@ class RegExpParser bool ParseBackReferenceIndex(int* index_out); bool ParseClassAtom(char16_t* char_class, widechar *value); - RegExpTree* ReportError(unsigned errorNumber); + RegExpTree* ReportError(unsigned errorNumber, const char* param = nullptr); void Advance(); void Advance(int dist) { next_pos_ += dist - 1; diff --git a/js/src/js.msg b/js/src/js.msg index 50817f50f..495e3bfad 100644 --- a/js/src/js.msg +++ b/js/src/js.msg @@ -502,7 +502,7 @@ MSG_DEF(JSMSG_RANGE_WITH_CLASS_ESCAPE, 0, JSEXN_SYNTAXERR, "character class esca MSG_DEF(JSMSG_RAW_BRACE_IN_REGEP, 0, JSEXN_SYNTAXERR, "raw brace is not allowed in regular expression with unicode flag") MSG_DEF(JSMSG_RAW_BRACKET_IN_REGEP, 0, JSEXN_SYNTAXERR, "raw bracket is not allowed in regular expression with unicode flag") MSG_DEF(JSMSG_TOO_MANY_PARENS, 0, JSEXN_INTERNALERR, "too many parentheses in regular expression") -MSG_DEF(JSMSG_UNICODE_OVERFLOW, 0, JSEXN_SYNTAXERR, "unicode codepoint should not be greater than 0x10FFFF in regular expression") +MSG_DEF(JSMSG_UNICODE_OVERFLOW, 1, JSEXN_SYNTAXERR, "Unicode codepoint must not be greater than 0x10FFFF in {0}") MSG_DEF(JSMSG_UNMATCHED_RIGHT_PAREN, 0, JSEXN_SYNTAXERR, "unmatched ) in regular expression") MSG_DEF(JSMSG_UNTERM_CLASS, 0, JSEXN_SYNTAXERR, "unterminated character class") |