Ignore:
Timestamp:
Sep 23, 2015, 3:37:36 PM (10 years ago)
Author:
[email protected]
Message:

JSC allows invalid var declarations when the declared name is the same as a let/const variable
https://bugs.webkit.org/show_bug.cgi?id=147600

Reviewed by Yusuke Suzuki.

Source/JavaScriptCore:

We had an ordering bug where if you first declared a "let"
variable then a "var" variable with the same name, you wouldn't
get a syntax error. But, if you did it in the reverse order,
you would. This patch fixes this syntax error to be order independent.

  • parser/Parser.cpp:

(JSC::Parser<LexerType>::parseVariableDeclarationList):
(JSC::Parser<LexerType>::createBindingPattern):
(JSC::Parser<LexerType>::parseFunctionDeclaration):

  • parser/Parser.h:

(JSC::Scope::declareVariable):

LayoutTests:

  • js/let-syntax-expected.txt:
  • js/script-tests/let-syntax.js:

(hasSyntaxError):

File:
1 edited

Legend:

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

    r189504 r190188  
    605605                    if (declarationType == DeclarationType::ConstDeclaration)
    606606                        internalFailWithMessage(false, "Cannot declare a const variable twice: '", name->impl(), "'");
    607                     RELEASE_ASSERT_NOT_REACHED();
     607                    ASSERT(declarationType == DeclarationType::VarDeclaration);
     608                    internalFailWithMessage(false, "Cannot declare a var variable that shadows a let/const/class variable: '", name->impl(), "'");
    608609                }
    609610            }
     
    668669    ASSERT(name.impl()->isAtomic() || name.impl()->isSymbol());
    669670
    670     if (kind == DestructureToVariables)
    671         failIfTrueIfStrict(declareVariable(&name) & DeclarationResult::InvalidStrictMode, "Cannot declare a variable named '", name.impl(), "' in strict mode");
    672     else if (kind == DestructureToLet || kind == DestructureToConst) {
     671    if (kind == DestructureToVariables) {
     672        DeclarationResultMask declarationResult = declareVariable(&name);
     673        failIfTrueIfStrict(declarationResult & DeclarationResult::InvalidStrictMode, "Cannot declare a variable named '", name.impl(), "' in strict mode");
     674        if (declarationResult & DeclarationResult::InvalidDuplicateDeclaration)
     675            internalFailWithMessage(false, "Cannot declare a var variable that shadows a let/const/class variable: '", name.impl(), "'");
     676    } else if (kind == DestructureToLet || kind == DestructureToConst) {
    673677        DeclarationResultMask declarationResult = declareVariable(&name, kind == DestructureToLet ? DeclarationType::LetDeclaration : DeclarationType::ConstDeclaration);
    674678        if (declarationResult != DeclarationResult::Valid) {
     
    18741878        functionKeywordStart, functionInfo, StandardFunctionParseType)), "Cannot parse this function");
    18751879    failIfFalse(functionInfo.name, "Function statements must have a name");
    1876     failIfTrueIfStrict(declareVariable(functionInfo.name) & DeclarationResult::InvalidStrictMode, "Cannot declare a function named '", functionInfo.name->impl(), "' in strict mode");
     1880    DeclarationResultMask declarationResult = declareVariable(functionInfo.name);
     1881    failIfTrueIfStrict(declarationResult & DeclarationResult::InvalidStrictMode, "Cannot declare a function named '", functionInfo.name->impl(), "' in strict mode");
     1882    if (declarationResult & DeclarationResult::InvalidDuplicateDeclaration)
     1883        internalFailWithMessage(false, "Cannot declare a function that shadows a let/const/class variable '", functionInfo.name->impl(), "' in strict mode");
    18771884    if (exportType == ExportType::Exported) {
    18781885        semanticFailIfFalse(exportName(*functionInfo.name), "Cannot export a duplicate function name: '", functionInfo.name->impl(), "'");
Note: See TracChangeset for help on using the changeset viewer.