⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 179682 in webkit


Ignore:
Timestamp:
Feb 5, 2015, 12:58:38 AM (12 years ago)
Author:
saambarati1@gmail.com
Message:

Crash in uninitialized deconstructing variable.
​https://bugs.webkit.org/show_bug.cgi?id=141070

Reviewed by Michael Saboff.

Source/JavaScriptCore:

According to the ES6 spec, when a destructuring pattern occurs
as the left hand side of an assignment inside a var declaration
statement, the assignment must also have a right hand side value.
"var {x} = {};" is a legal syntactic statement, but,
"var {x};" is a syntactic error.

Section 13.2.2 of the latest draft ES6 spec specifies this requirement:
​https://people.mozilla.org/~jorendorff/es6-draft.html#sec-variable-statement

  • parser/Parser.cpp:

(JSC::Parser<LexerType>::parseVarDeclaration):
(JSC::Parser<LexerType>::parseVarDeclarationList):
(JSC::Parser<LexerType>::parseForStatement):

  • parser/Parser.h:

LayoutTests:

  • js/parser-syntax-check-expected.txt:
  • js/script-tests/parser-syntax-check.js:
Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r179673 r179682  
     12015-02-05  Saam Barati  <saambarati1@gmail.com>
     2
     3        Crash in uninitialized deconstructing variable.
     4        https://bugs.webkit.org/show_bug.cgi?id=141070
     5
     6        Reviewed by Michael Saboff.
     7
     8        * js/parser-syntax-check-expected.txt:
     9        * js/script-tests/parser-syntax-check.js:
     10
    1112015-02-04  Brent Fulgham  <bfulgham@apple.com>
    212
  • trunk/LayoutTests/js/parser-syntax-check-expected.txt

    r172380 r179682  
    679679PASS Valid:   "for ({of} in of){}" with ReferenceError
    680680PASS Valid:   "function f() { for ({of} in of){} }"
     681PASS Invalid: "for (var of = x of of){}"
     682PASS Invalid: "function f() { for (var of = x of of){} }"
     683PASS Invalid: "for (var {of} = x of of){}"
     684PASS Invalid: "function f() { for (var {of} = x of of){} }"
     685PASS Invalid: "for (var [of] = x of of){}"
     686PASS Invalid: "function f() { for (var [of] = x of of){} }"
    681687PASS Invalid: "for (of of of of){}"
    682688PASS Invalid: "function f() { for (of of of of){} }"
    … …  
    766772PASS Valid:   "var {1:x}=1"
    767773PASS Valid:   "function f() { var {1:x}=1 }"
     774PASS Valid:   "var {x}=1"
     775PASS Valid:   "function f() { var {x}=1 }"
     776PASS Valid:   "var {x, y}=1"
     777PASS Valid:   "function f() { var {x, y}=1 }"
     778PASS Valid:   "var [x]=1"
     779PASS Valid:   "function f() { var [x]=1 }"
     780PASS Valid:   "var [x, y]=1"
     781PASS Valid:   "function f() { var [x, y]=1 }"
    768782PASS Valid:   "[x]=1"
    769783PASS Valid:   "function f() { [x]=1 }"
    … …  
    788802PASS Valid:   "({a:a}=1=1)" with ReferenceError
    789803PASS Valid:   "function f() { ({a:a}=1=1) }"
     804PASS Invalid: "var {x}"
     805PASS Invalid: "function f() { var {x} }"
     806PASS Invalid: "var {x, y}"
     807PASS Invalid: "function f() { var {x, y} }"
     808PASS Invalid: "var {x} = 20, {x, y}"
     809PASS Invalid: "function f() { var {x} = 20, {x, y} }"
     810PASS Invalid: "var {foo:bar, bar:baz}"
     811PASS Invalid: "function f() { var {foo:bar, bar:baz} }"
     812PASS Invalid: "var [x]"
     813PASS Invalid: "function f() { var [x] }"
     814PASS Invalid: "var [x, y]"
     815PASS Invalid: "function f() { var [x, y] }"
     816PASS Invalid: "var [x] = [], [x, y]"
     817PASS Invalid: "function f() { var [x] = [], [x, y] }"
    790818PASS Invalid: "({get [x](){}})"
    791819PASS Invalid: "function f() { ({get [x](){}}) }"
  • trunk/LayoutTests/js/script-tests/parser-syntax-check.js

    r172380 r179682  
    429429valid("for ([of] in of){}")
    430430valid("for ({of} in of){}")
     431invalid("for (var of = x of of){}")
     432invalid("for (var {of} = x of of){}")
     433invalid("for (var [of] = x of of){}")
    431434
    432435
    … …  
    476479valid("'use strict'; ({a: b}=null)")
    477480valid("var {1:x}=1")
     481valid("var {x}=1")
     482valid("var {x, y}=1")
     483valid("var [x]=1")
     484valid("var [x, y]=1")
    478485valid("[x]=1")
    479486valid("var [x]=1")
    … …  
    487494valid("({a}=1=1)")
    488495valid("({a:a}=1=1)")
     496invalid("var {x}")
     497invalid("var {x, y}")
     498invalid("var {x} = 20, {x, y}")
     499invalid("var {foo:bar, bar:baz}")
     500invalid("var [x]")
     501invalid("var [x, y]")
     502invalid("var [x] = [], [x, y]")
    489503invalid("({get [x](){}})")
    490504invalid("({set [x](){}})")
  • trunk/Source/JavaScriptCore/ChangeLog

    r179666 r179682  
     12015-02-05  Saam Barati  <saambarati1@gmail.com>
     2
     3        Crash in uninitialized deconstructing variable.
     4        https://bugs.webkit.org/show_bug.cgi?id=141070
     5
     6        Reviewed by Michael Saboff.
     7
     8        According to the ES6 spec, when a destructuring pattern occurs
     9        as the left hand side of an assignment inside a var declaration
     10        statement, the assignment must also have a right hand side value.
     11        "var {x} = {};" is a legal syntactic statement, but,
     12        "var {x};" is a syntactic error.
     13
     14        Section 13.2.2 of the latest draft ES6 spec specifies this requirement:
     15        https://people.mozilla.org/~jorendorff/es6-draft.html#sec-variable-statement
     16
     17        * parser/Parser.cpp:
     18        (JSC::Parser<LexerType>::parseVarDeclaration):
     19        (JSC::Parser<LexerType>::parseVarDeclarationList):
     20        (JSC::Parser<LexerType>::parseForStatement):
     21        * parser/Parser.h:
     22
    1232015-02-04  Gyuyoung Kim  <gyuyoung.kim@samsung.com>
    224
  • trunk/Source/JavaScriptCore/parser/Parser.cpp

    r179371 r179682  
    379379    TreeExpression scratch2 = 0;
    380380    JSTextPosition scratch3;
    381     TreeExpression varDecls = parseVarDeclarationList(context, scratch, scratch1, scratch2, scratch3, scratch3, scratch3);
     381    TreeExpression varDecls = parseVarDeclarationList(context, scratch, scratch1, scratch2, scratch3, scratch3, scratch3, VarDeclarationContext);
    382382    propagateError();
    383383    failIfFalse(autoSemiColon(), "Expected ';' after var declaration");
    … …  
    448448
    449449template <typename LexerType>
    450 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseVarDeclarationList(TreeBuilder& context, int& declarations, TreeDeconstructionPattern& lastPattern, TreeExpression& lastInitializer, JSTextPosition& identStart, JSTextPosition& initStart, JSTextPosition& initEnd)
     450template <class TreeBuilder> TreeExpression Parser<LexerType>::parseVarDeclarationList(TreeBuilder& context, int& declarations, TreeDeconstructionPattern& lastPattern, TreeExpression& lastInitializer, JSTextPosition& identStart, JSTextPosition& initStart, JSTextPosition& initEnd, VarDeclarationListContext declarationListContext)
    451451{
    452452    TreeExpression head = 0;
    … …  
    488488            failIfFalse(pattern, "Cannot parse this deconstruction pattern");
    489489            hasInitializer = match(EQUAL);
     490            failIfTrue(declarationListContext == VarDeclarationContext && !hasInitializer, "Expected an initializer in destructuring variable declaration");
    490491            lastPattern = pattern;
    491492            if (hasInitializer) {
    … …  
    736737        JSTextPosition initStart;
    737738        JSTextPosition initEnd;
    738         decls = parseVarDeclarationList(context, declarations, forInTarget, forInInitializer, declsStart, initStart, initEnd);
     739        decls = parseVarDeclarationList(context, declarations, forInTarget, forInInitializer, declsStart, initStart, initEnd, ForLoopContext);
    739740        m_allowsIn = true;
    740741        propagateError();
  • trunk/Source/JavaScriptCore/parser/Parser.h

    r179371 r179682  
    743743    template <class TreeBuilder> ALWAYS_INLINE TreeFunctionBody parseFunctionBody(TreeBuilder&);
    744744    template <class TreeBuilder> ALWAYS_INLINE TreeFormalParameterList parseFormalParameters(TreeBuilder&);
    745     template <class TreeBuilder> TreeExpression parseVarDeclarationList(TreeBuilder&, int& declarations, TreeDeconstructionPattern& lastPattern, TreeExpression& lastInitializer, JSTextPosition& identStart, JSTextPosition& initStart, JSTextPosition& initEnd);
     745    enum VarDeclarationListContext { ForLoopContext, VarDeclarationContext };
     746    template <class TreeBuilder> TreeExpression parseVarDeclarationList(TreeBuilder&, int& declarations, TreeDeconstructionPattern& lastPattern, TreeExpression& lastInitializer, JSTextPosition& identStart, JSTextPosition& initStart, JSTextPosition& initEnd, VarDeclarationListContext);
    746747    template <class TreeBuilder> NEVER_INLINE TreeConstDeclList parseConstDeclarationList(TreeBuilder&);
    747748
Note: See TracChangeset for help on using the changeset viewer.