[SCM] WebKit Debian packaging branch, webkit-1.3, updated. upstream/1.3.7-4207-g178b198

oliver at apple.com oliver at apple.com
Sun Feb 20 23:04:11 UTC 2011


The following commit has been merged in the webkit-1.3 branch:
commit fc1b3f8f2c8930fccfb244ce73d4e9cccf0fcf57
Author: oliver at apple.com <oliver at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Sun Jan 16 23:54:40 2011 +0000

    2011-01-16  Oliver Hunt  <oliver at apple.com>
    
            Reviewed by Geoffrey Garen.
    
            Strict mode restrictions on arguments and eval usage aren't complete
            https://bugs.webkit.org/show_bug.cgi?id=52528
    
            Add a helper function to aid parse failure tests by testing both direct
            eval/global code, and nested code (so that we test the syntax checker
            mode as well)
    
            * fast/js/basic-strict-mode-expected.txt:
            * fast/js/script-tests/basic-strict-mode.js:
            (shouldBeSyntaxError):
    2011-01-16  Oliver Hunt  <oliver at apple.com>
    
            Reviewed by Geoffrey Garen.
    
            Strict mode restrictions on arguments and eval usage aren't complete
            https://bugs.webkit.org/show_bug.cgi?id=52528
    
            Fix a few bugs in strict mode where we incorrect allow mutation of
            arguments and eval in the parser.
    
            Alas the "optimisation" used by the syntax checker for validating
            binary and unary expressions was too aggressive: we do actually need
            a stack for operations and operands although it needn't be as complete
            as that used for the full AST builder.
    
            Also disallow assignment to arguments in all cases as allowing arguments
            to be assignable is always an error in strict mode, regardless of context.
    
            * parser/ASTBuilder.h:
            (JSC::ASTBuilder::BinaryExprContext::BinaryExprContext):
            (JSC::ASTBuilder::UnaryExprContext::UnaryExprContext):
            * parser/JSParser.cpp:
            (JSC::JSParser::parseAssignmentExpression):
            (JSC::JSParser::parseBinaryExpression):
            (JSC::JSParser::parseUnaryExpression):
            * parser/SyntaxChecker.h:
            (JSC::SyntaxChecker::BinaryExprContext::BinaryExprContext):
            (JSC::SyntaxChecker::BinaryExprContext::~BinaryExprContext):
            (JSC::SyntaxChecker::UnaryExprContext::UnaryExprContext):
            (JSC::SyntaxChecker::UnaryExprContext::~UnaryExprContext):
            (JSC::SyntaxChecker::appendBinaryExpressionInfo):
            (JSC::SyntaxChecker::operatorStackPop):
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@75896 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 0188d73..2210dc4 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,18 @@
+2011-01-16  Oliver Hunt  <oliver at apple.com>
+
+        Reviewed by Geoffrey Garen.
+
+        Strict mode restrictions on arguments and eval usage aren't complete
+        https://bugs.webkit.org/show_bug.cgi?id=52528
+
+        Add a helper function to aid parse failure tests by testing both direct
+        eval/global code, and nested code (so that we test the syntax checker
+        mode as well)
+
+        * fast/js/basic-strict-mode-expected.txt:
+        * fast/js/script-tests/basic-strict-mode.js:
+        (shouldBeSyntaxError):
+
 2011-01-16  Robert Hogan  <robert at webkit.org>
 
         Unreviewed, re-skip test after r75894.
diff --git a/LayoutTests/fast/js/basic-strict-mode-expected.txt b/LayoutTests/fast/js/basic-strict-mode-expected.txt
index fade4cf..de70568 100644
--- a/LayoutTests/fast/js/basic-strict-mode-expected.txt
+++ b/LayoutTests/fast/js/basic-strict-mode-expected.txt
@@ -29,18 +29,31 @@ PASS testThis.apply() is undefined
 PASS testThis.call(undefined) is undefined
 PASS testThis.apply(undefined) is undefined
 PASS (function eval(){'use strict';}) threw exception SyntaxError: Parse error.
+PASS (function(){(function eval(){'use strict';})}) threw exception SyntaxError: Parse error.
 PASS (function (eval){'use strict';}) threw exception SyntaxError: Parse error.
+PASS (function(){(function (eval){'use strict';})}) threw exception SyntaxError: Parse error.
 PASS (function arguments(){'use strict';}) threw exception SyntaxError: Parse error.
+PASS (function(){(function arguments(){'use strict';})}) threw exception SyntaxError: Parse error.
 PASS (function (arguments){'use strict';}) threw exception SyntaxError: Parse error.
+PASS (function(){(function (arguments){'use strict';})}) threw exception SyntaxError: Parse error.
 PASS (function (){'use strict'; var eval;}) threw exception SyntaxError: Parse error.
+PASS (function(){(function (){'use strict'; var eval;})}) threw exception SyntaxError: Parse error.
 PASS (function (){'use strict'; var arguments;}) threw exception SyntaxError: Parse error.
+PASS (function(){(function (){'use strict'; var arguments;})}) threw exception SyntaxError: Parse error.
 PASS (function (){'use strict'; try{}catch(eval){}}) threw exception SyntaxError: Parse error.
+PASS (function(){(function (){'use strict'; try{}catch(eval){}})}) threw exception SyntaxError: Parse error.
 PASS (function (){'use strict'; try{}catch(arguments){}}) threw exception SyntaxError: Parse error.
+PASS (function(){(function (){'use strict'; try{}catch(arguments){}})}) threw exception SyntaxError: Parse error.
 PASS (function (a, a){'use strict';}) threw exception SyntaxError: Parse error.
+PASS (function(){(function (a, a){'use strict';})}) threw exception SyntaxError: Parse error.
 PASS (function (a){'use strict'; delete a;})() threw exception SyntaxError: Parse error.
+PASS (function(){(function (a){'use strict'; delete a;})()}) threw exception SyntaxError: Parse error.
 PASS (function (){'use strict'; var a; delete a;})() threw exception SyntaxError: Parse error.
+PASS (function(){(function (){'use strict'; var a; delete a;})()}) threw exception SyntaxError: Parse error.
 PASS (function (){var a; function f() {'use strict'; delete a;} })() threw exception SyntaxError: Parse error.
+PASS (function(){(function (){var a; function f() {'use strict'; delete a;} })()}) threw exception SyntaxError: Parse error.
 PASS (function (){'use strict'; with(1){};}) threw exception SyntaxError: Parse error.
+PASS (function(){(function (){'use strict'; with(1){};})}) threw exception SyntaxError: Parse error.
 PASS (function (){'use strict'; arguments.callee; })() threw exception TypeError: Unable to access callee of strict mode function.
 PASS (function (){'use strict'; arguments.caller; })() threw exception TypeError: Unable to access caller of strict mode function.
 PASS (function f(){'use strict'; f.arguments; })() threw exception TypeError: Can't access arguments object of a strict mode function.
@@ -54,22 +67,37 @@ PASS (function f(arg){'use strict'; f.caller; })() threw exception TypeError: Ca
 PASS (function f(arg){'use strict'; f.arguments=5; })() threw exception TypeError: Cannot access arguments property of a strict mode function.
 PASS (function f(arg){'use strict'; f.caller=5; })() threw exception TypeError: Cannot access caller property of a strict mode function.
 PASS 'use strict'; (function (){with(1){};}) threw exception SyntaxError: Parse error.
+PASS (function(){'use strict'; (function (){with(1){};})}) threw exception SyntaxError: Parse error.
 PASS 'use strict'; (function (){var a; delete a;}) threw exception SyntaxError: Parse error.
+PASS (function(){'use strict'; (function (){var a; delete a;})}) threw exception SyntaxError: Parse error.
 PASS 'use strict'; var a; (function (){ delete a;}) threw exception SyntaxError: Parse error.
+PASS (function(){'use strict'; var a; (function (){ delete a;})}) threw exception SyntaxError: Parse error.
 PASS var a; (function (){ 'use strict'; delete a;}) threw exception SyntaxError: Parse error.
+PASS (function(){var a; (function (){ 'use strict'; delete a;})}) threw exception SyntaxError: Parse error.
 PASS 'misc directive'; 'use strict'; with({}){} threw exception SyntaxError: Parse error.
+PASS (function(){'misc directive'; 'use strict'; with({}){}}) threw exception SyntaxError: Parse error.
 PASS 'use strict'; return threw exception SyntaxError: Parse error.
 PASS 'use strict'; break threw exception SyntaxError: Parse error.
+PASS (function(){'use strict'; break}) threw exception SyntaxError: Parse error.
 PASS 'use strict'; continue threw exception SyntaxError: Parse error.
+PASS (function(){'use strict'; continue}) threw exception SyntaxError: Parse error.
 PASS 'use strict'; for(;;)return threw exception SyntaxError: Parse error.
 PASS 'use strict'; for(;;)break missingLabel threw exception SyntaxError: Parse error.
+PASS (function(){'use strict'; for(;;)break missingLabel}) threw exception SyntaxError: Parse error.
 PASS 'use strict'; for(;;)continue missingLabel threw exception SyntaxError: Parse error.
+PASS (function(){'use strict'; for(;;)continue missingLabel}) threw exception SyntaxError: Parse error.
 PASS 'use strict'; 007; threw exception SyntaxError: Parse error.
+PASS (function(){'use strict'; 007;}) threw exception SyntaxError: Parse error.
 PASS 'use strict'; '\007'; threw exception SyntaxError: Parse error.
+PASS (function(){'use strict'; '\007';}) threw exception SyntaxError: Parse error.
 PASS '\007'; 'use strict'; threw exception SyntaxError: Parse error.
+PASS (function(){'\007'; 'use strict';}) threw exception SyntaxError: Parse error.
 PASS 'use strict'; delete aDeletableProperty; threw exception SyntaxError: Parse error.
+PASS (function(){'use strict'; delete aDeletableProperty;}) threw exception SyntaxError: Parse error.
 PASS 'use strict'; (function (){ delete someDeclaredGlobal;}) threw exception SyntaxError: Parse error.
+PASS (function(){'use strict'; (function (){ delete someDeclaredGlobal;})}) threw exception SyntaxError: Parse error.
 PASS (function (){ 'use strict'; delete someDeclaredGlobal;}) threw exception SyntaxError: Parse error.
+PASS (function(){(function (){ 'use strict'; delete someDeclaredGlobal;})}) threw exception SyntaxError: Parse error.
 PASS 'use strict'; if (0) { someGlobal = 'Shouldn\'t be able to assign this.'; }; true; is true
 PASS 'use strict'; someGlobal = 'Shouldn\'t be able to assign this.';  threw exception ReferenceError: Strict mode forbids implicit creation of global property 'someGlobal'.
 PASS 'use strict'; eval('var introducedVariable = "FAIL: variable introduced into containing scope";'); introducedVariable threw exception ReferenceError: Can't find variable: introducedVariable.
@@ -77,25 +105,44 @@ PASS 'use strict'; objectWithReadonlyProperty.prop = 'fail' threw exception Type
 PASS 'use strict'; delete objectWithReadonlyProperty.prop threw exception TypeError: Unable to delete property..
 PASS 'use strict'; delete objectWithReadonlyProperty[readonlyPropName] threw exception TypeError: Unable to delete property..
 PASS 'use strict'; ++eval threw exception SyntaxError: Parse error.
+PASS (function(){'use strict'; ++eval}) threw exception SyntaxError: Parse error.
 PASS 'use strict'; eval++ threw exception SyntaxError: Parse error.
+PASS (function(){'use strict'; eval++}) threw exception SyntaxError: Parse error.
 PASS 'use strict'; --eval threw exception SyntaxError: Parse error.
+PASS (function(){'use strict'; --eval}) threw exception SyntaxError: Parse error.
 PASS 'use strict'; eval-- threw exception SyntaxError: Parse error.
+PASS (function(){'use strict'; eval--}) threw exception SyntaxError: Parse error.
 PASS 'use strict'; function f() { ++arguments } threw exception SyntaxError: Parse error.
+PASS (function(){'use strict'; function f() { ++arguments }}) threw exception SyntaxError: Parse error.
 PASS 'use strict'; function f() { arguments++ } threw exception SyntaxError: Parse error.
+PASS (function(){'use strict'; function f() { arguments++ }}) threw exception SyntaxError: Parse error.
 PASS 'use strict'; function f() { --arguments } threw exception SyntaxError: Parse error.
+PASS (function(){'use strict'; function f() { --arguments }}) threw exception SyntaxError: Parse error.
 PASS 'use strict'; function f() { arguments-- } threw exception SyntaxError: Parse error.
-PASS global.eval('"use strict"; if (0) ++arguments; true;') is true
+PASS (function(){'use strict'; function f() { arguments-- }}) threw exception SyntaxError: Parse error.
+PASS global.eval('"use strict"; if (0) ++arguments; true;') threw exception SyntaxError: Parse error.
 PASS 'use strict'; ++(1, eval) threw exception ReferenceError: Prefix ++ operator applied to value that is not a reference..
+PASS (function(){'use strict'; ++(1, eval)}) threw exception SyntaxError: Parse error.
 PASS 'use strict'; (1, eval)++ threw exception ReferenceError: Postfix ++ operator applied to value that is not a reference..
+PASS (function(){'use strict'; (1, eval)++}) threw exception SyntaxError: Parse error.
 PASS 'use strict'; --(1, eval) threw exception ReferenceError: Prefix -- operator applied to value that is not a reference..
+PASS (function(){'use strict'; --(1, eval)}) threw exception SyntaxError: Parse error.
 PASS 'use strict'; (1, eval)-- threw exception ReferenceError: Postfix -- operator applied to value that is not a reference..
+PASS (function(){'use strict'; (1, eval)--}) threw exception SyntaxError: Parse error.
 PASS 'use strict'; function f() { ++(1, arguments) } threw exception SyntaxError: Parse error.
+PASS (function(){'use strict'; function f() { ++(1, arguments) }}) threw exception SyntaxError: Parse error.
 PASS 'use strict'; function f() { (1, arguments)++ } threw exception SyntaxError: Parse error.
+PASS (function(){'use strict'; function f() { (1, arguments)++ }}) threw exception SyntaxError: Parse error.
 PASS 'use strict'; function f() { --(1, arguments) } threw exception SyntaxError: Parse error.
+PASS (function(){'use strict'; function f() { --(1, arguments) }}) threw exception SyntaxError: Parse error.
 PASS 'use strict'; function f() { (1, arguments)-- } threw exception SyntaxError: Parse error.
+PASS (function(){'use strict'; function f() { (1, arguments)-- }}) threw exception SyntaxError: Parse error.
 PASS 'use strict'; if (0) delete +a.b threw exception SyntaxError: Parse error.
+PASS (function(){'use strict'; if (0) delete +a.b}) threw exception SyntaxError: Parse error.
 PASS 'use strict'; if (0) delete ++a.b threw exception SyntaxError: Parse error.
+PASS (function(){'use strict'; if (0) delete ++a.b}) threw exception SyntaxError: Parse error.
 PASS 'use strict'; if (0) delete void a.b threw exception SyntaxError: Parse error.
+PASS (function(){'use strict'; if (0) delete void a.b}) threw exception SyntaxError: Parse error.
 PASS (function (a){'use strict'; a = false; return a !== arguments[0]; })(true) is true
 PASS (function (a){'use strict'; arguments[0] = false; return a !== arguments[0]; })(true) is true
 PASS (function (a){'use strict'; a=false; return arguments; })(true)[0] is true
@@ -128,9 +175,23 @@ PASS (function f(arg){'use strict'; var descriptor = Object.getOwnPropertyDescri
 PASS (function f(arg){'use strict'; var descriptor = Object.getOwnPropertyDescriptor(f, 'arguments'); return descriptor.get === descriptor.set; })() is true
 PASS 'use strict'; (function f() { for(var i in this); })(); true; is true
 PASS 'use strict'̻ threw exception SyntaxError: Parse error.
+PASS (function(){'use strict'̻}) threw exception SyntaxError: Parse error.
 PASS 'use strict'5.f threw exception SyntaxError: Parse error.
+PASS (function(){'use strict'5.f}) threw exception SyntaxError: Parse error.
 PASS 'use strict';̻ threw exception SyntaxError: Parse error.
+PASS (function(){'use strict';̻}) threw exception SyntaxError: Parse error.
 PASS 'use strict';5.f threw exception SyntaxError: Parse error.
+PASS (function(){'use strict';5.f}) threw exception SyntaxError: Parse error.
+PASS 'use strict';1-(eval=1); threw exception SyntaxError: Parse error.
+PASS (function(){'use strict';1-(eval=1);}) threw exception SyntaxError: Parse error.
+PASS 'use strict';arguments=1; threw exception SyntaxError: Parse error.
+PASS (function(){'use strict';arguments=1;}) threw exception SyntaxError: Parse error.
+PASS 'use strict';1-(arguments=1); threw exception SyntaxError: Parse error.
+PASS (function(){'use strict';1-(arguments=1);}) threw exception SyntaxError: Parse error.
+PASS 'use strict';var a=(eval=1); threw exception SyntaxError: Parse error.
+PASS (function(){'use strict';var a=(eval=1);}) threw exception SyntaxError: Parse error.
+PASS 'use strict';var a=(arguments=1); threw exception SyntaxError: Parse error.
+PASS (function(){'use strict';var a=(arguments=1);}) threw exception SyntaxError: Parse error.
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/LayoutTests/fast/js/script-tests/basic-strict-mode.js b/LayoutTests/fast/js/script-tests/basic-strict-mode.js
index c13beac..0cefcdd 100644
--- a/LayoutTests/fast/js/script-tests/basic-strict-mode.js
+++ b/LayoutTests/fast/js/script-tests/basic-strict-mode.js
@@ -16,6 +16,11 @@ function testThisBracketAccess(prop) {
 function testGlobalAccess() {
     return testThis();
 }
+function shouldBeSyntaxError(str) {
+    shouldThrow(str);
+    shouldThrow("(function(){" + str + "})");
+}
+
 shouldBe("testThis.call(null)", "null");
 shouldBe("testThis.call(1)", "1");
 shouldBe("testThis.call(true)", "true");
@@ -44,19 +49,19 @@ shouldBe("testThis.apply()", "undefined");
 shouldBe("testThis.call(undefined)", "undefined");
 shouldBe("testThis.apply(undefined)", "undefined");
 
-shouldThrow("(function eval(){'use strict';})");
-shouldThrow("(function (eval){'use strict';})");
-shouldThrow("(function arguments(){'use strict';})");
-shouldThrow("(function (arguments){'use strict';})");
-shouldThrow("(function (){'use strict'; var eval;})");
-shouldThrow("(function (){'use strict'; var arguments;})");
-shouldThrow("(function (){'use strict'; try{}catch(eval){}})");
-shouldThrow("(function (){'use strict'; try{}catch(arguments){}})");
-shouldThrow("(function (a, a){'use strict';})");
-shouldThrow("(function (a){'use strict'; delete a;})()");
-shouldThrow("(function (){'use strict'; var a; delete a;})()");
-shouldThrow("(function (){var a; function f() {'use strict'; delete a;} })()");
-shouldThrow("(function (){'use strict'; with(1){};})");
+shouldBeSyntaxError("(function eval(){'use strict';})");
+shouldBeSyntaxError("(function (eval){'use strict';})");
+shouldBeSyntaxError("(function arguments(){'use strict';})");
+shouldBeSyntaxError("(function (arguments){'use strict';})");
+shouldBeSyntaxError("(function (){'use strict'; var eval;})");
+shouldBeSyntaxError("(function (){'use strict'; var arguments;})");
+shouldBeSyntaxError("(function (){'use strict'; try{}catch(eval){}})");
+shouldBeSyntaxError("(function (){'use strict'; try{}catch(arguments){}})");
+shouldBeSyntaxError("(function (a, a){'use strict';})");
+shouldBeSyntaxError("(function (a){'use strict'; delete a;})()");
+shouldBeSyntaxError("(function (){'use strict'; var a; delete a;})()");
+shouldBeSyntaxError("(function (){var a; function f() {'use strict'; delete a;} })()");
+shouldBeSyntaxError("(function (){'use strict'; with(1){};})");
 shouldThrow("(function (){'use strict'; arguments.callee; })()");
 shouldThrow("(function (){'use strict'; arguments.caller; })()");
 shouldThrow("(function f(){'use strict'; f.arguments; })()");
@@ -69,27 +74,27 @@ shouldThrow("(function f(arg){'use strict'; f.arguments; })()");
 shouldThrow("(function f(arg){'use strict'; f.caller; })()");
 shouldThrow("(function f(arg){'use strict'; f.arguments=5; })()");
 shouldThrow("(function f(arg){'use strict'; f.caller=5; })()");
-shouldThrow("'use strict'; (function (){with(1){};})");
-shouldThrow("'use strict'; (function (){var a; delete a;})");
-shouldThrow("'use strict'; var a; (function (){ delete a;})");
-shouldThrow("var a; (function (){ 'use strict'; delete a;})");
-shouldThrow("'misc directive'; 'use strict'; with({}){}");
+shouldBeSyntaxError("'use strict'; (function (){with(1){};})");
+shouldBeSyntaxError("'use strict'; (function (){var a; delete a;})");
+shouldBeSyntaxError("'use strict'; var a; (function (){ delete a;})");
+shouldBeSyntaxError("var a; (function (){ 'use strict'; delete a;})");
+shouldBeSyntaxError("'misc directive'; 'use strict'; with({}){}");
 shouldThrow("'use strict'; return");
-shouldThrow("'use strict'; break");
-shouldThrow("'use strict'; continue");
+shouldBeSyntaxError("'use strict'; break");
+shouldBeSyntaxError("'use strict'; continue");
 shouldThrow("'use strict'; for(;;)return");
-shouldThrow("'use strict'; for(;;)break missingLabel");
-shouldThrow("'use strict'; for(;;)continue missingLabel");
-shouldThrow("'use strict'; 007;");
-shouldThrow("'use strict'; '\\007';");
-shouldThrow("'\\007'; 'use strict';");
+shouldBeSyntaxError("'use strict'; for(;;)break missingLabel");
+shouldBeSyntaxError("'use strict'; for(;;)continue missingLabel");
+shouldBeSyntaxError("'use strict'; 007;");
+shouldBeSyntaxError("'use strict'; '\\007';");
+shouldBeSyntaxError("'\\007'; 'use strict';");
 
 var someDeclaredGlobal;
 aDeletableProperty = 'test';
 
-shouldThrow("'use strict'; delete aDeletableProperty;");
-shouldThrow("'use strict'; (function (){ delete someDeclaredGlobal;})");
-shouldThrow("(function (){ 'use strict'; delete someDeclaredGlobal;})");
+shouldBeSyntaxError("'use strict'; delete aDeletableProperty;");
+shouldBeSyntaxError("'use strict'; (function (){ delete someDeclaredGlobal;})");
+shouldBeSyntaxError("(function (){ 'use strict'; delete someDeclaredGlobal;})");
 shouldBeTrue("'use strict'; if (0) { someGlobal = 'Shouldn\\'t be able to assign this.'; }; true;");
 shouldThrow("'use strict'; someGlobal = 'Shouldn\\'t be able to assign this.'; ");
 shouldThrow("'use strict'; eval('var introducedVariable = \"FAIL: variable introduced into containing scope\";'); introducedVariable");
@@ -99,27 +104,27 @@ shouldThrow("'use strict'; objectWithReadonlyProperty.prop = 'fail'");
 shouldThrow("'use strict'; delete objectWithReadonlyProperty.prop");
 readonlyPropName = "prop";
 shouldThrow("'use strict'; delete objectWithReadonlyProperty[readonlyPropName]");
-shouldThrow("'use strict'; ++eval");
-shouldThrow("'use strict'; eval++");
-shouldThrow("'use strict'; --eval");
-shouldThrow("'use strict'; eval--");
-shouldThrow("'use strict'; function f() { ++arguments }");
-shouldThrow("'use strict'; function f() { arguments++ }");
-shouldThrow("'use strict'; function f() { --arguments }");
-shouldThrow("'use strict'; function f() { arguments-- }");
+shouldBeSyntaxError("'use strict'; ++eval");
+shouldBeSyntaxError("'use strict'; eval++");
+shouldBeSyntaxError("'use strict'; --eval");
+shouldBeSyntaxError("'use strict'; eval--");
+shouldBeSyntaxError("'use strict'; function f() { ++arguments }");
+shouldBeSyntaxError("'use strict'; function f() { arguments++ }");
+shouldBeSyntaxError("'use strict'; function f() { --arguments }");
+shouldBeSyntaxError("'use strict'; function f() { arguments-- }");
 var global = this;
-shouldBeTrue("global.eval('\"use strict\"; if (0) ++arguments; true;')");
-shouldThrow("'use strict'; ++(1, eval)");
-shouldThrow("'use strict'; (1, eval)++");
-shouldThrow("'use strict'; --(1, eval)");
-shouldThrow("'use strict'; (1, eval)--");
-shouldThrow("'use strict'; function f() { ++(1, arguments) }");
-shouldThrow("'use strict'; function f() { (1, arguments)++ }");
-shouldThrow("'use strict'; function f() { --(1, arguments) }");
-shouldThrow("'use strict'; function f() { (1, arguments)-- }");
-shouldThrow("'use strict'; if (0) delete +a.b");
-shouldThrow("'use strict'; if (0) delete ++a.b");
-shouldThrow("'use strict'; if (0) delete void a.b");
+shouldThrow("global.eval('\"use strict\"; if (0) ++arguments; true;')");
+shouldBeSyntaxError("'use strict'; ++(1, eval)");
+shouldBeSyntaxError("'use strict'; (1, eval)++");
+shouldBeSyntaxError("'use strict'; --(1, eval)");
+shouldBeSyntaxError("'use strict'; (1, eval)--");
+shouldBeSyntaxError("'use strict'; function f() { ++(1, arguments) }");
+shouldBeSyntaxError("'use strict'; function f() { (1, arguments)++ }");
+shouldBeSyntaxError("'use strict'; function f() { --(1, arguments) }");
+shouldBeSyntaxError("'use strict'; function f() { (1, arguments)-- }");
+shouldBeSyntaxError("'use strict'; if (0) delete +a.b");
+shouldBeSyntaxError("'use strict'; if (0) delete ++a.b");
+shouldBeSyntaxError("'use strict'; if (0) delete void a.b");
 
 shouldBeTrue("(function (a){'use strict'; a = false; return a !== arguments[0]; })(true)");
 shouldBeTrue("(function (a){'use strict'; arguments[0] = false; return a !== arguments[0]; })(true)");
@@ -157,9 +162,13 @@ shouldBeTrue("(function f(arg){'use strict'; var descriptor = Object.getOwnPrope
 shouldBeTrue("(function f(arg){'use strict'; var descriptor = Object.getOwnPropertyDescriptor(f, 'arguments'); return descriptor.get === descriptor.set; })()");
 shouldBeTrue("'use strict'; (function f() { for(var i in this); })(); true;")
 
-shouldThrow("'use strict'\u033b");
-shouldThrow("'use strict'5.f");
-shouldThrow("'use strict';\u033b");
-shouldThrow("'use strict';5.f");
-
+shouldBeSyntaxError("'use strict'\u033b");
+shouldBeSyntaxError("'use strict'5.f");
+shouldBeSyntaxError("'use strict';\u033b");
+shouldBeSyntaxError("'use strict';5.f");
+shouldBeSyntaxError("'use strict';1-(eval=1);");
+shouldBeSyntaxError("'use strict';arguments=1;");
+shouldBeSyntaxError("'use strict';1-(arguments=1);");
+shouldBeSyntaxError("'use strict';var a=(eval=1);");
+shouldBeSyntaxError("'use strict';var a=(arguments=1);");
 var successfullyParsed = true;
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index cab64b3..9eb0f9a 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,36 @@
+2011-01-16  Oliver Hunt  <oliver at apple.com>
+
+        Reviewed by Geoffrey Garen.
+
+        Strict mode restrictions on arguments and eval usage aren't complete
+        https://bugs.webkit.org/show_bug.cgi?id=52528
+
+        Fix a few bugs in strict mode where we incorrect allow mutation of
+        arguments and eval in the parser.
+
+        Alas the "optimisation" used by the syntax checker for validating
+        binary and unary expressions was too aggressive: we do actually need
+        a stack for operations and operands although it needn't be as complete
+        as that used for the full AST builder.
+
+        Also disallow assignment to arguments in all cases as allowing arguments
+        to be assignable is always an error in strict mode, regardless of context.
+
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::BinaryExprContext::BinaryExprContext):
+        (JSC::ASTBuilder::UnaryExprContext::UnaryExprContext):
+        * parser/JSParser.cpp:
+        (JSC::JSParser::parseAssignmentExpression):
+        (JSC::JSParser::parseBinaryExpression):
+        (JSC::JSParser::parseUnaryExpression):
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::BinaryExprContext::BinaryExprContext):
+        (JSC::SyntaxChecker::BinaryExprContext::~BinaryExprContext):
+        (JSC::SyntaxChecker::UnaryExprContext::UnaryExprContext):
+        (JSC::SyntaxChecker::UnaryExprContext::~UnaryExprContext):
+        (JSC::SyntaxChecker::appendBinaryExpressionInfo):
+        (JSC::SyntaxChecker::operatorStackPop):
+
 2011-01-15  Geoffrey Garen  <ggaren at apple.com>
 
         Reviewed by Oliver Hunt.
diff --git a/Source/JavaScriptCore/parser/ASTBuilder.h b/Source/JavaScriptCore/parser/ASTBuilder.h
index 409c6ab..337c87e 100644
--- a/Source/JavaScriptCore/parser/ASTBuilder.h
+++ b/Source/JavaScriptCore/parser/ASTBuilder.h
@@ -80,6 +80,13 @@ public:
     {
         m_scopes.append(Scope(globalData));
     }
+    
+    struct BinaryExprContext {
+        BinaryExprContext(ASTBuilder&) {}
+    };
+    struct UnaryExprContext {
+        UnaryExprContext(ASTBuilder&) {}
+    };
 
     typedef SyntaxChecker FunctionBodyBuilder;
 
diff --git a/Source/JavaScriptCore/parser/JSParser.cpp b/Source/JavaScriptCore/parser/JSParser.cpp
index 640f603..0299621 100644
--- a/Source/JavaScriptCore/parser/JSParser.cpp
+++ b/Source/JavaScriptCore/parser/JSParser.cpp
@@ -1490,6 +1490,7 @@ template <typename TreeBuilder> TreeExpression JSParser::parseAssignmentExpressi
         next();
         if (strictMode() && m_lastIdentifier && context.isResolve(lhs)) {
             failIfTrueIfStrict(m_globalData->propertyNames->eval == *m_lastIdentifier);
+            failIfTrueIfStrict(m_globalData->propertyNames->arguments == *m_lastIdentifier);
             declareWrite(m_lastIdentifier);
             m_lastIdentifier = 0;
         }
@@ -1545,6 +1546,7 @@ template <class TreeBuilder> TreeExpression JSParser::parseBinaryExpression(Tree
 
     int operandStackDepth = 0;
     int operatorStackDepth = 0;
+    typename TreeBuilder::BinaryExprContext binaryExprContext(context);
     while (true) {
         int exprStart = tokenStart();
         int initialAssignments = m_assignmentCount;
@@ -1942,6 +1944,7 @@ endMemberExpression:
 
 template <class TreeBuilder> TreeExpression JSParser::parseUnaryExpression(TreeBuilder& context)
 {
+    typename TreeBuilder::UnaryExprContext unaryExprContext(context);
     AllowInOverride allowInOverride(this);
     int tokenStackDepth = 0;
     bool modifiesExpr = false;
@@ -1977,9 +1980,7 @@ template <class TreeBuilder> TreeExpression JSParser::parseUnaryExpression(TreeB
     bool isEvalOrArguments = false;
     if (strictMode() && !m_syntaxAlreadyValidated) {
         if (context.isResolve(expr)) {
-            isEvalOrArguments = m_globalData->propertyNames->eval == *m_lastIdentifier;
-            if (!isEvalOrArguments && currentScope()->isFunction())
-                isEvalOrArguments = m_globalData->propertyNames->arguments == *m_lastIdentifier;
+            isEvalOrArguments = *m_lastIdentifier == m_globalData->propertyNames->eval || *m_lastIdentifier == m_globalData->propertyNames->arguments;
         }
     }
     failIfTrueIfStrict(isEvalOrArguments && modifiesExpr);
diff --git a/Source/JavaScriptCore/parser/SyntaxChecker.h b/Source/JavaScriptCore/parser/SyntaxChecker.h
index 3e64126..1b5497a 100644
--- a/Source/JavaScriptCore/parser/SyntaxChecker.h
+++ b/Source/JavaScriptCore/parser/SyntaxChecker.h
@@ -31,8 +31,38 @@
 namespace JSC {
 class SyntaxChecker {
 public:
+    struct BinaryExprContext {
+        BinaryExprContext(SyntaxChecker& context)
+            : m_context(&context)
+        {
+            m_context->m_topBinaryExprs.append(m_context->m_topBinaryExpr);
+            m_context->m_topBinaryExpr = 0;
+        }
+        ~BinaryExprContext()
+        {
+            m_context->m_topBinaryExpr = m_context->m_topBinaryExprs.last();
+            m_context->m_topBinaryExprs.removeLast();
+        }
+    private:
+        SyntaxChecker* m_context;
+    };
+    struct UnaryExprContext {
+        UnaryExprContext(SyntaxChecker& context)
+            : m_context(&context)
+        {
+            m_context->m_topUnaryTokens.append(m_context->m_topUnaryToken);
+            m_context->m_topUnaryToken = 0;
+        }
+        ~UnaryExprContext()
+        {
+            m_context->m_topUnaryToken = m_context->m_topUnaryTokens.last();
+            m_context->m_topUnaryTokens.removeLast();
+        }
+    private:
+        SyntaxChecker* m_context;
+    };
+    
     SyntaxChecker(JSGlobalData* , Lexer*)
-        : m_topBinaryExpr(0)
     {
     }
 
@@ -212,6 +242,8 @@ public:
 private:
     int m_topBinaryExpr;
     int m_topUnaryToken;
+    Vector<int, 8> m_topBinaryExprs;
+    Vector<int, 8> m_topUnaryTokens;
 };
 
 }

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list