Ignore:
Timestamp:
Jul 1, 2016, 5:59:38 PM (9 years ago)
Author:
[email protected]
Message:

fix "ASSERTION FAILED: currentOffset() >= currentLineStartOffset()"
https://bugs.webkit.org/show_bug.cgi?id=158572
<rdar://problem/26884092>

Reviewed by Mark Lam.

Source/JavaScriptCore:

There is a bug in our lexer when we notice the pattern:
<return|continue|break|...etc> // some comment here
Our code will say that the token for the comment is a semicolon.
This is the correct semantics, however, it would give the semicolon
a start offset of the comment, but it will give its line start offset
the newline after the comment. This breaks the invariant in the lexer/parser
that the offset for the current line starting point must be less than or equal to
than the start offset of any token on that line. This invariant was broken because
the line start offset was greater than the token start offset. To maintain this
invariant, we claim that the semicolon token is located where the comment starts,
and that its line start offset is the line start offset for the line with the
comment on it. There are other solutions that maintain this invariant, but this
solution provides the best error messages.

  • parser/Lexer.cpp:

(JSC::Lexer<T>::lex):

  • parser/Parser.h:

(JSC::Parser::internalSaveLexerState):

  • tests/stress/obscure-error-message-dont-crash.js: Added.

(try.eval.or.catch):

LayoutTests:

  • js/parser-syntax-check-expected.txt:
  • js/script-tests/parser-syntax-check.js:

(invalid.or.break.catch):
(catch): Deleted.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/parser/Lexer.cpp

    r202280 r202768  
    17841784    m_terminator = false;
    17851785
     1786    auto fillTokenInfo = [&] (int lineNumber, int endOffset, int lineStartOffset, JSTextPosition endPosition) {
     1787        tokenLocation->line = lineNumber;
     1788        tokenLocation->endOffset = endOffset;
     1789        tokenLocation->lineStartOffset = lineStartOffset;
     1790        ASSERT(tokenLocation->endOffset >= tokenLocation->lineStartOffset);
     1791        tokenRecord->m_endPosition = endPosition;
     1792        m_lastToken = token;
     1793    };
     1794
    17861795start:
    17871796    skipWhitespace();
     
    22582267
    22592268inSingleLineComment:
    2260     while (!isLineTerminator(m_current)) {
    2261         if (atEnd())
    2262             return EOFTOK;
    2263         shift();
    2264     }
    2265     shiftLineTerminator();
    2266     m_atLineStart = true;
    2267     m_terminator = true;
    2268     m_lineStart = m_code;
    2269     if (!lastTokenWasRestrKeyword())
    2270         goto start;
    2271 
    2272     token = SEMICOLON;
    2273     // Fall through into returnToken.
     2269    {
     2270        auto lineNumber = m_lineNumber;
     2271        auto endOffset = currentOffset();
     2272        auto lineStartOffset = currentLineStartOffset();
     2273        auto endPosition = currentPosition();
     2274
     2275        while (!isLineTerminator(m_current)) {
     2276            if (atEnd())
     2277                return EOFTOK;
     2278            shift();
     2279        }
     2280        shiftLineTerminator();
     2281        m_atLineStart = true;
     2282        m_terminator = true;
     2283        m_lineStart = m_code;
     2284        if (!lastTokenWasRestrKeyword())
     2285            goto start;
     2286
     2287        token = SEMICOLON;
     2288        fillTokenInfo(lineNumber, endOffset, lineStartOffset, endPosition);
     2289        return token;
     2290    }
    22742291
    22752292returnToken:
    2276     tokenLocation->line = m_lineNumber;
    2277     tokenLocation->endOffset = currentOffset();
    2278     tokenLocation->lineStartOffset = currentLineStartOffset();
    2279     ASSERT(tokenLocation->endOffset >= tokenLocation->lineStartOffset);
    2280     tokenRecord->m_endPosition = currentPosition();
    2281     m_lastToken = token;
     2293    fillTokenInfo(m_lineNumber, currentOffset(), currentLineStartOffset(), currentPosition());
    22822294    return token;
    22832295
    22842296returnError:
    22852297    m_error = true;
    2286     tokenLocation->line = m_lineNumber;
    2287     tokenLocation->endOffset = currentOffset();
    2288     tokenLocation->lineStartOffset = currentLineStartOffset();
    2289     ASSERT(tokenLocation->endOffset >= tokenLocation->lineStartOffset);
    2290     tokenRecord->m_endPosition = currentPosition();
     2298    fillTokenInfo(m_lineNumber, currentOffset(), currentLineStartOffset(), currentPosition());
    22912299    RELEASE_ASSERT(token & ErrorTokenFlag);
    22922300    return token;
Note: See TracChangeset for help on using the changeset viewer.