Ignore:
Timestamp:
Mar 31, 2015, 12:42:56 PM (10 years ago)
Author:
[email protected]
Message:

eval("this.foo") causes a crash if this had not been initialized in a derived class's constructor
https://bugs.webkit.org/show_bug.cgi?id=142883

Reviewed by Filip Pizlo.

The crash was caused by eval inside the constructor of a derived class not checking TDZ.

Fixed the bug by adding a parser flag that forces the TDZ check to be always emitted when accessing "this"
in eval inside a derived class' constructor.

  • bytecode/EvalCodeCache.h:

(JSC::EvalCodeCache::getSlow):

  • bytecompiler/NodesCodegen.cpp:

(JSC::ThisNode::emitBytecode):

  • debugger/DebuggerCallFrame.cpp:

(JSC::DebuggerCallFrame::evaluate):

  • interpreter/Interpreter.cpp:

(JSC::eval):

  • parser/ASTBuilder.h:

(JSC::ASTBuilder::thisExpr):

  • parser/NodeConstructors.h:

(JSC::ThisNode::ThisNode):

  • parser/Nodes.h:
  • parser/Parser.cpp:

(JSC::Parser<LexerType>::Parser):
(JSC::Parser<LexerType>::parsePrimaryExpression):

  • parser/Parser.h:

(JSC::parse):

  • parser/ParserModes.h:
  • parser/SyntaxChecker.h:

(JSC::SyntaxChecker::thisExpr):

  • runtime/CodeCache.cpp:

(JSC::CodeCache::getGlobalCodeBlock):
(JSC::CodeCache::getProgramCodeBlock):
(JSC::CodeCache::getEvalCodeBlock):

  • runtime/CodeCache.h:

(JSC::SourceCodeKey::SourceCodeKey):

  • runtime/Executable.cpp:

(JSC::EvalExecutable::create):

  • runtime/Executable.h:
  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::createEvalCodeBlock):

  • runtime/JSGlobalObject.h:
  • runtime/JSGlobalObjectFunctions.cpp:

(JSC::globalFuncEval):

  • tests/stress/class-syntax-no-tdz-in-eval.js: Added.
  • tests/stress/class-syntax-tdz-in-eval.js: Added.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/CodeCache.cpp

    r182038 r182198  
    7676
    7777template <class UnlinkedCodeBlockType, class ExecutableType>
    78 UnlinkedCodeBlockType* CodeCache::getGlobalCodeBlock(VM& vm, ExecutableType* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
     78UnlinkedCodeBlockType* CodeCache::getGlobalCodeBlock(VM& vm, ExecutableType* executable, const SourceCode& source, JSParserBuiltinMode builtinMode,
     79    JSParserStrictMode strictMode, ThisTDZMode thisTDZMode, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
    7980{
    80     SourceCodeKey key = SourceCodeKey(source, String(), CacheTypes<UnlinkedCodeBlockType>::codeType, builtinMode, strictMode);
     81    SourceCodeKey key = SourceCodeKey(source, String(), CacheTypes<UnlinkedCodeBlockType>::codeType, builtinMode, strictMode, thisTDZMode);
    8182    SourceCodeValue* cache = m_sourceCode.findCacheAndUpdateAge(key);
    8283    bool canCache = debuggerMode == DebuggerOff && profilerMode == ProfilerOff && !vm.typeProfiler() && !vm.controlFlowProfiler();
     
    9596    std::unique_ptr<RootNode> rootNode = parse<RootNode>(
    9697        &vm, source, 0, Identifier(), builtinMode, strictMode,
    97         JSParserCodeType::Program, error);
     98        JSParserCodeType::Program, error, 0, ConstructorKind::None, thisTDZMode);
    9899    if (!rootNode)
    99100        return nullptr;
     
    123124UnlinkedProgramCodeBlock* CodeCache::getProgramCodeBlock(VM& vm, ProgramExecutable* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
    124125{
    125     return getGlobalCodeBlock<UnlinkedProgramCodeBlock>(vm, executable, source, builtinMode, strictMode, debuggerMode, profilerMode, error);
     126    return getGlobalCodeBlock<UnlinkedProgramCodeBlock>(vm, executable, source, builtinMode, strictMode, ThisTDZMode::CheckIfNeeded, debuggerMode, profilerMode, error);
    126127}
    127128
    128 UnlinkedEvalCodeBlock* CodeCache::getEvalCodeBlock(VM& vm, EvalExecutable* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
     129UnlinkedEvalCodeBlock* CodeCache::getEvalCodeBlock(VM& vm, EvalExecutable* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, ThisTDZMode thisTDZMode, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error)
    129130{
    130     return getGlobalCodeBlock<UnlinkedEvalCodeBlock>(vm, executable, source, builtinMode, strictMode, debuggerMode, profilerMode, error);
     131    return getGlobalCodeBlock<UnlinkedEvalCodeBlock>(vm, executable, source, builtinMode, strictMode, thisTDZMode, debuggerMode, profilerMode, error);
    131132}
    132133
Note: See TracChangeset for help on using the changeset viewer.