diff options
Diffstat (limited to 'Source/JavaScriptCore/runtime/LiteralParser.cpp')
-rw-r--r-- | Source/JavaScriptCore/runtime/LiteralParser.cpp | 59 |
1 files changed, 35 insertions, 24 deletions
diff --git a/Source/JavaScriptCore/runtime/LiteralParser.cpp b/Source/JavaScriptCore/runtime/LiteralParser.cpp index f594518b6..f55498381 100644 --- a/Source/JavaScriptCore/runtime/LiteralParser.cpp +++ b/Source/JavaScriptCore/runtime/LiteralParser.cpp @@ -28,12 +28,13 @@ #include "LiteralParser.h" #include "ButterflyInlines.h" +#include "CodeBlock.h" #include "CopiedSpaceInlines.h" #include "JSArray.h" #include "JSString.h" #include "Lexer.h" #include "ObjectConstructor.h" -#include "Operations.h" +#include "JSCInlines.h" #include "StrongInlines.h" #include <wtf/ASCIICType.h> #include <wtf/dtoa.h> @@ -57,20 +58,20 @@ bool LiteralParser<CharType>::tryJSONPParse(Vector<JSONPData>& results, bool nee do { Vector<JSONPPathEntry> path; // Unguarded next to start off the lexer - Identifier name = Identifier(&m_exec->vm(), m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start); + Identifier name = Identifier::fromString(&m_exec->vm(), m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start); JSONPPathEntry entry; if (name == m_exec->vm().propertyNames->varKeyword) { if (m_lexer.next() != TokIdentifier) return false; entry.m_type = JSONPPathEntryTypeDeclare; - entry.m_pathEntryName = Identifier(&m_exec->vm(), m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start); + entry.m_pathEntryName = Identifier::fromString(&m_exec->vm(), m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start); path.append(entry); } else { entry.m_type = JSONPPathEntryTypeDot; - entry.m_pathEntryName = Identifier(&m_exec->vm(), m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start); + entry.m_pathEntryName = Identifier::fromString(&m_exec->vm(), m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start); path.append(entry); } - if (m_exec->vm().keywords->isKeyword(entry.m_pathEntryName)) + if (isLexerKeyword(entry.m_pathEntryName)) return false; TokenType tokenType = m_lexer.next(); if (entry.m_type == JSONPPathEntryTypeDeclare && tokenType != TokAssign) @@ -94,7 +95,7 @@ bool LiteralParser<CharType>::tryJSONPParse(Vector<JSONPData>& results, bool nee entry.m_type = JSONPPathEntryTypeDot; if (m_lexer.next() != TokIdentifier) return false; - entry.m_pathEntryName = Identifier(&m_exec->vm(), m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start); + entry.m_pathEntryName = Identifier::fromString(&m_exec->vm(), m_lexer.currentToken().start, m_lexer.currentToken().end - m_lexer.currentToken().start); break; } case TokLParen: { @@ -135,17 +136,17 @@ ALWAYS_INLINE const Identifier LiteralParser<CharType>::makeIdentifier(const LCh if (!length) return m_exec->vm().propertyNames->emptyIdentifier; if (characters[0] >= MaximumCachableCharacter) - return Identifier(&m_exec->vm(), characters, length); + return Identifier::fromString(&m_exec->vm(), characters, length); if (length == 1) { if (!m_shortIdentifiers[characters[0]].isNull()) return m_shortIdentifiers[characters[0]]; - m_shortIdentifiers[characters[0]] = Identifier(&m_exec->vm(), characters, length); + m_shortIdentifiers[characters[0]] = Identifier::fromString(&m_exec->vm(), characters, length); return m_shortIdentifiers[characters[0]]; } if (!m_recentIdentifiers[characters[0]].isNull() && Identifier::equal(m_recentIdentifiers[characters[0]].impl(), characters, length)) return m_recentIdentifiers[characters[0]]; - m_recentIdentifiers[characters[0]] = Identifier(&m_exec->vm(), characters, length); + m_recentIdentifiers[characters[0]] = Identifier::fromString(&m_exec->vm(), characters, length); return m_recentIdentifiers[characters[0]]; } @@ -155,17 +156,17 @@ ALWAYS_INLINE const Identifier LiteralParser<CharType>::makeIdentifier(const UCh if (!length) return m_exec->vm().propertyNames->emptyIdentifier; if (characters[0] >= MaximumCachableCharacter) - return Identifier(&m_exec->vm(), characters, length); + return Identifier::fromString(&m_exec->vm(), characters, length); if (length == 1) { if (!m_shortIdentifiers[characters[0]].isNull()) return m_shortIdentifiers[characters[0]]; - m_shortIdentifiers[characters[0]] = Identifier(&m_exec->vm(), characters, length); + m_shortIdentifiers[characters[0]] = Identifier::fromString(&m_exec->vm(), characters, length); return m_shortIdentifiers[characters[0]]; } if (!m_recentIdentifiers[characters[0]].isNull() && Identifier::equal(m_recentIdentifiers[characters[0]].impl(), characters, length)) return m_recentIdentifiers[characters[0]]; - m_recentIdentifiers[characters[0]] = Identifier(&m_exec->vm(), characters, length); + m_recentIdentifiers[characters[0]] = Identifier::fromString(&m_exec->vm(), characters, length); return m_recentIdentifiers[characters[0]]; } @@ -281,7 +282,7 @@ template <ParserMode mode> TokenType LiteralParser<CharType>::Lexer::lex(Literal return lexString<mode, '\''>(token); } } - m_lexErrorMessage = String::format("Unrecognized token '%c'", *m_ptr).impl(); + m_lexErrorMessage = String::format("Unrecognized token '%c'", *m_ptr); return TokError; } @@ -406,7 +407,7 @@ template <ParserMode mode, char terminator> ALWAYS_INLINE TokenType LiteralParse } // uNNNN == 5 characters for (int i = 1; i < 5; i++) { if (!isASCIIHexDigit(m_ptr[i])) { - m_lexErrorMessage = String::format("\"\\%s\" is not a valid unicode escape", String(m_ptr, 5).ascii().data()).impl(); + m_lexErrorMessage = String::format("\"\\%s\" is not a valid unicode escape", String(m_ptr, 5).ascii().data()); return TokError; } } @@ -420,7 +421,7 @@ template <ParserMode mode, char terminator> ALWAYS_INLINE TokenType LiteralParse m_ptr++; break; } - m_lexErrorMessage = String::format("Invalid escape character %c", *m_ptr).impl(); + m_lexErrorMessage = String::format("Invalid escape character %c", *m_ptr); return TokError; } } @@ -497,7 +498,7 @@ TokenType LiteralParser<CharType>::Lexer::lexNumber(LiteralParserToken<CharType> while (m_ptr < m_end && isASCIIDigit(*m_ptr)) ++m_ptr; } else if (m_ptr < m_end && (*m_ptr != 'e' && *m_ptr != 'E') && (m_ptr - token.start) < 10) { - int result = 0; + double result = 0; token.type = TokNumber; token.end = m_ptr; const CharType* digit = token.start; @@ -548,15 +549,16 @@ JSValue LiteralParser<CharType>::parse(ParserState initialState) JSValue lastValue; Vector<ParserState, 16, UnsafeVectorOverflow> stateStack; Vector<Identifier, 16, UnsafeVectorOverflow> identifierStack; + HashSet<JSObject*> visitedUnderscoreProto; while (1) { switch(state) { startParseArray: case StartParseArray: { JSArray* array = constructEmptyArray(m_exec, 0); objectStack.append(array); - // fallthrough } doParseArrayStartExpression: + FALLTHROUGH; case DoParseArrayStartExpression: { TokenType lastToken = m_lexer.currentToken().type; if (m_lexer.next() == TokRBracket) { @@ -649,11 +651,20 @@ JSValue LiteralParser<CharType>::parse(ParserState initialState) { JSObject* object = asObject(objectStack.last()); PropertyName ident = identifierStack.last(); - unsigned i = ident.asIndex(); - if (i != PropertyName::NotAnIndex) - object->putDirectIndex(m_exec, i, lastValue); - else - object->putDirect(m_exec->vm(), ident, lastValue); + if (m_mode != StrictJSON && ident == m_exec->vm().propertyNames->underscoreProto) { + if (!visitedUnderscoreProto.add(object).isNewEntry) { + m_parseErrorMessage = ASCIILiteral("Attempted to redefine __proto__ property"); + return JSValue(); + } + CodeBlock* codeBlock = m_exec->codeBlock(); + PutPropertySlot slot(object, codeBlock ? codeBlock->isStrictMode() : false); + objectStack.last().put(m_exec, ident, lastValue, slot); + } else { + if (Optional<uint32_t> index = parseIndex(ident)) + object->putDirectIndex(m_exec, index.value(), lastValue); + else + object->putDirect(m_exec->vm(), ident, lastValue); + } identifierStack.removeLast(); if (m_lexer.currentToken().type == TokComma) goto doParseObjectStartExpression; @@ -711,9 +722,9 @@ JSValue LiteralParser<CharType>::parse(ParserState initialState) case TokIdentifier: { const LiteralParserToken<CharType>& token = m_lexer.currentToken(); if (token.stringIs8Bit) - m_parseErrorMessage = String::format("Unexpected identifier \"%s\"", String(m_lexer.currentToken().stringToken8, m_lexer.currentToken().stringLength).ascii().data()).impl(); + m_parseErrorMessage = String::format("Unexpected identifier \"%s\"", String(m_lexer.currentToken().stringToken8, m_lexer.currentToken().stringLength).ascii().data()); else - m_parseErrorMessage = String::format("Unexpected identifier \"%s\"", String(m_lexer.currentToken().stringToken16, m_lexer.currentToken().stringLength).ascii().data()).impl(); + m_parseErrorMessage = String::format("Unexpected identifier \"%s\"", String(m_lexer.currentToken().stringToken16, m_lexer.currentToken().stringLength).ascii().data()); return JSValue(); } case TokColon: |