Ignore:
Timestamp:
Jun 1, 2009, 9:40:16 PM (16 years ago)
Author:
[email protected]
Message:

Tidy up the literal parser.

Reviewed by Gavin Barraclogh.

Make the number lexing in the LiteralParser exactly match the JSON spec, which
makes us cover more cases, but also more strict. Also made string lexing only
allow double-quoted strings.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/runtime/LiteralParser.cpp

    r43424 r44343  
    101101            return TokColon;
    102102        case '"':
    103         case '\'':
    104103            return lexString(token);
    105104
    106         // Numbers are trickier so we only allow the most basic form, basically
    107         // * [1-9][0-9]*(\.[0-9]*)?
    108         // * \.[0-9]*
    109         // * 0(\.[0-9]*)?
     105        case '-':
    110106        case '0':
    111             // If a number starts with 0 it's expected to be octal.  It seems silly
    112             // to attempt to handle this case, so we abort
    113             if (m_ptr < m_end - 1 && isASCIIDigit(m_ptr[1]))
    114                 return TokError;
    115             return lexNumber(token);
    116         case '.':
    117             // If a number starts with a '.' it must be followed by a digit
    118             if (!(m_ptr < m_end - 1 && isASCIIDigit(m_ptr[1])))
    119                 return TokError;
    120             return lexNumber(token);
    121107        case '1':
    122108        case '2':
     
    135121LiteralParser::TokenType LiteralParser::Lexer::lexString(LiteralParserToken& token)
    136122{
    137     UChar terminator = *m_ptr;
    138123    ++m_ptr;
    139     while (m_ptr < m_end && isSafeStringCharacter(*m_ptr) && *m_ptr != terminator)
    140         ++m_ptr;
    141     if (m_ptr >= m_end || *m_ptr != terminator) {
     124    while (m_ptr < m_end && isSafeStringCharacter(*m_ptr) && *m_ptr != '"')
     125        ++m_ptr;
     126    if (m_ptr >= m_end || *m_ptr != '"') {
    142127        token.type = TokError;
    143128        token.end = ++m_ptr;
     
    151136LiteralParser::TokenType LiteralParser::Lexer::lexNumber(LiteralParserToken& token)
    152137{
    153     bool beginsWithDot = *m_ptr == '.';
    154     ++m_ptr;
    155     while (m_ptr < m_end && isASCIIDigit(*m_ptr))
    156         ++m_ptr;
    157 
    158     if (!beginsWithDot && m_ptr < m_end - 1 && *m_ptr == '.') {
    159         ++m_ptr;
     138    // ES5 and json.org define numbers as
     139    // number
     140    //     int
     141    //     int frac? exp?
     142    //
     143    // int
     144    //     -? 0
     145    //     -? digit1-9 digits?
     146    //
     147    // digits
     148    //     digit digits?
     149    //
     150    // -?(0 | [1-9][0-9]*) ('.' [0-9]+)? ([eE][+-]? [0-9]+)?
     151
     152    if (m_ptr < m_end && *m_ptr == '-') // -?
     153        ++m_ptr;
     154   
     155    // (0 | [1-9][0-9]*)
     156    if (m_ptr < m_end && *m_ptr == '0') // 0
     157        ++m_ptr;
     158    else if (m_ptr < m_end && *m_ptr >= '1' && *m_ptr <= '9') { // [1-9]
     159        ++m_ptr;
     160        // [0-9]*
    160161        while (m_ptr < m_end && isASCIIDigit(*m_ptr))
    161162            ++m_ptr;
    162     }
    163 
    164     if (m_ptr < m_end) {
    165         if (*m_ptr == 'x' || *m_ptr == 'X' || *m_ptr == 'e' || *m_ptr == 'E') {
    166             token.type = TokError;
     163    } else
     164        return TokError;
     165
     166    // ('.' [0-9]+)?
     167    if (m_ptr < m_end && *m_ptr == '.') {
     168        ++m_ptr;
     169        // [0-9]+
     170        if (m_ptr >= m_end && !isASCIIDigit(*m_ptr))
    167171            return TokError;
    168         }
    169     }
     172
     173        ++m_ptr;
     174        while (m_ptr < m_end && isASCIIDigit(*m_ptr))
     175            ++m_ptr;
     176    }
     177
     178    //  ([eE][+-]? [0-9]+)?
     179    if (m_ptr < m_end && (*m_ptr == 'e' || *m_ptr == 'E')) { // [eE]
     180        ++m_ptr;
     181
     182        // [-+]?
     183        if (m_ptr < m_end && (*m_ptr == '-' || *m_ptr == '+'))
     184            ++m_ptr;
     185
     186        // [0-9]+
     187        if (m_ptr >= m_end && !isASCIIDigit(*m_ptr))
     188            return TokError;
     189       
     190        ++m_ptr;
     191        while (m_ptr < m_end && isASCIIDigit(*m_ptr))
     192            ++m_ptr;
     193    }
     194   
    170195    token.type = TokNumber;
    171196    token.end = m_ptr;
Note: See TracChangeset for help on using the changeset viewer.