Diff
Modified: trunk/LayoutTests/ChangeLog (95786 => 95787)
--- trunk/LayoutTests/ChangeLog 2011-09-23 06:59:38 UTC (rev 95786)
+++ trunk/LayoutTests/ChangeLog 2011-09-23 07:18:48 UTC (rev 95787)
@@ -93,6 +93,31 @@
2011-09-22 Gavin Barraclough <[email protected]>
+ Incorrect this value passed to callbacks.
+ https://bugs.webkit.org/show_bug.cgi?id=68668
+
+ Reviewed by Oliver Hunt.
+
+ From Array/String prototype function. Should be undefined, but
+ global object is passed instead (this is visible for strict callbacks).
+
+ * fast/js/array-prototype-properties-expected.txt:
+ * fast/js/script-tests/strict-callback-this.js: Added.
+ (strictThrowThisString):
+ (nonstrictThrowThisString):
+ (testArrayPrototypeSort):
+ (testArrayPrototypeFilter):
+ (testArrayPrototypeMap):
+ (testArrayPrototypeEvery):
+ (testArrayPrototypeForEach):
+ (testArrayPrototypeSome):
+ (testStringPrototypeReplace):
+ * fast/js/strict-callback-this-expected.txt: Added.
+ * fast/js/strict-callback-this.html: Added.
+ * ietestcenter/_javascript_/15.3.4.5-0-2-expected.txt:
+
+2011-09-22 Gavin Barraclough <[email protected]>
+
Function.prototype.bind.length shoudl be 1.
Rubber stamped by Olier Hunt.
Modified: trunk/LayoutTests/fast/js/array-prototype-properties-expected.txt (95786 => 95787)
--- trunk/LayoutTests/fast/js/array-prototype-properties-expected.txt 2011-09-23 06:59:38 UTC (rev 95786)
+++ trunk/LayoutTests/fast/js/array-prototype-properties-expected.txt 2011-09-23 07:18:48 UTC (rev 95787)
@@ -23,7 +23,7 @@
FAIL Array.prototype.filter.call(undefined, toString) should throw an exception. Was [object Object].
FAIL Array.prototype.reduce.call(undefined, toString) should throw an exception. Was [object Object].
FAIL Array.prototype.reduceRight.call(undefined, toString) should throw an exception. Was [object Object].
-FAIL Array.prototype.map.call(undefined, toString) should throw an exception. Was [object DOMWindow].
+FAIL Array.prototype.map.call(undefined, toString) should throw an exception. Was [object Undefined].
PASS successfullyParsed is true
TEST COMPLETE
Added: trunk/LayoutTests/fast/js/script-tests/strict-callback-this.js (0 => 95787)
--- trunk/LayoutTests/fast/js/script-tests/strict-callback-this.js (rev 0)
+++ trunk/LayoutTests/fast/js/script-tests/strict-callback-this.js 2011-09-23 07:18:48 UTC (rev 95787)
@@ -0,0 +1,105 @@
+description(
+"This tests that a call to array/string prototype methods pass the correct this value (undefined) to strict callees."
+);
+
+var undefinedString = String(undefined);
+var globalObjectString = String(this);
+
+function strictThrowThisString()
+{
+ "use strict";
+ throw String(this);
+}
+
+function nonstrictThrowThisString()
+{
+ throw String(this);
+}
+
+function testArrayPrototypeSort(callback)
+{
+ try {
+ [1,2].sort(callback);
+ } catch (e) {
+ return e;
+ }
+ return "FAILED";
+}
+
+function testArrayPrototypeFilter(callback)
+{
+ try {
+ [1,2].filter(callback);
+ } catch (e) {
+ return e;
+ }
+ return "FAILED";
+}
+
+function testArrayPrototypeMap(callback)
+{
+ try {
+ [1,2].map(callback);
+ } catch (e) {
+ return e;
+ }
+ return "FAILED";
+}
+
+function testArrayPrototypeEvery(callback)
+{
+ try {
+ [1,2].every(callback);
+ } catch (e) {
+ return e;
+ }
+ return "FAILED";
+}
+
+function testArrayPrototypeForEach(callback)
+{
+ try {
+ [1,2].forEach(callback);
+ } catch (e) {
+ return e;
+ }
+ return "FAILED";
+}
+
+function testArrayPrototypeSome(callback)
+{
+ try {
+ [1,2].some(callback);
+ } catch (e) {
+ return e;
+ }
+ return "FAILED";
+}
+
+function testStringPrototypeReplace(callback)
+{
+ try {
+ "1,2".replace('1', callback);
+ } catch (e) {
+ return e;
+ }
+ return "FAILED";
+}
+
+shouldBe('testArrayPrototypeSort(strictThrowThisString)', 'undefinedString');
+shouldBe('testArrayPrototypeFilter(strictThrowThisString)', 'undefinedString');
+shouldBe('testArrayPrototypeMap(strictThrowThisString)', 'undefinedString');
+shouldBe('testArrayPrototypeEvery(strictThrowThisString)', 'undefinedString');
+shouldBe('testArrayPrototypeForEach(strictThrowThisString)', 'undefinedString');
+shouldBe('testArrayPrototypeSome(strictThrowThisString)', 'undefinedString');
+shouldBe('testStringPrototypeReplace(strictThrowThisString)', 'undefinedString');
+
+shouldBe('testArrayPrototypeSort(nonstrictThrowThisString)', 'globalObjectString');
+shouldBe('testArrayPrototypeFilter(nonstrictThrowThisString)', 'globalObjectString');
+shouldBe('testArrayPrototypeMap(nonstrictThrowThisString)', 'globalObjectString');
+shouldBe('testArrayPrototypeEvery(nonstrictThrowThisString)', 'globalObjectString');
+shouldBe('testArrayPrototypeForEach(nonstrictThrowThisString)', 'globalObjectString');
+shouldBe('testArrayPrototypeSome(nonstrictThrowThisString)', 'globalObjectString');
+shouldBe('testStringPrototypeReplace(nonstrictThrowThisString)', 'globalObjectString');
+
+var successfullyParsed = true;
Added: trunk/LayoutTests/fast/js/strict-callback-this-expected.txt (0 => 95787)
--- trunk/LayoutTests/fast/js/strict-callback-this-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/js/strict-callback-this-expected.txt 2011-09-23 07:18:48 UTC (rev 95787)
@@ -0,0 +1,23 @@
+This tests that a call to array/string prototype methods pass the correct this value (undefined) to strict callees.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS testArrayPrototypeSort(strictThrowThisString) is undefinedString
+PASS testArrayPrototypeFilter(strictThrowThisString) is undefinedString
+PASS testArrayPrototypeMap(strictThrowThisString) is undefinedString
+PASS testArrayPrototypeEvery(strictThrowThisString) is undefinedString
+PASS testArrayPrototypeForEach(strictThrowThisString) is undefinedString
+PASS testArrayPrototypeSome(strictThrowThisString) is undefinedString
+PASS testStringPrototypeReplace(strictThrowThisString) is undefinedString
+PASS testArrayPrototypeSort(nonstrictThrowThisString) is globalObjectString
+PASS testArrayPrototypeFilter(nonstrictThrowThisString) is globalObjectString
+PASS testArrayPrototypeMap(nonstrictThrowThisString) is globalObjectString
+PASS testArrayPrototypeEvery(nonstrictThrowThisString) is globalObjectString
+PASS testArrayPrototypeForEach(nonstrictThrowThisString) is globalObjectString
+PASS testArrayPrototypeSome(nonstrictThrowThisString) is globalObjectString
+PASS testStringPrototypeReplace(nonstrictThrowThisString) is globalObjectString
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/js/strict-callback-this.html (0 => 95787)
--- trunk/LayoutTests/fast/js/strict-callback-this.html (rev 0)
+++ trunk/LayoutTests/fast/js/strict-callback-this.html 2011-09-23 07:18:48 UTC (rev 95787)
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href=""
+<script src=""
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src=""
+<script src=""
+</body>
+</html>
Modified: trunk/Source/_javascript_Core/ChangeLog (95786 => 95787)
--- trunk/Source/_javascript_Core/ChangeLog 2011-09-23 06:59:38 UTC (rev 95786)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-09-23 07:18:48 UTC (rev 95787)
@@ -46,6 +46,29 @@
2011-09-22 Gavin Barraclough <[email protected]>
+ Incorrect this value passed to callbacks.
+ https://bugs.webkit.org/show_bug.cgi?id=68668
+
+ Reviewed by Oliver Hunt.
+
+ From Array/String prototype function. Should be undefined, but
+ global object is passed instead (this is visible for strict callbacks).
+
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoFuncSort):
+ (JSC::arrayProtoFuncFilter):
+ (JSC::arrayProtoFuncMap):
+ (JSC::arrayProtoFuncEvery):
+ (JSC::arrayProtoFuncForEach):
+ (JSC::arrayProtoFuncSome):
+ * runtime/JSArray.cpp:
+ (JSC::AVLTreeAbstractorForArrayCompare::compare_key_key):
+ (JSC::JSArray::sort):
+ * runtime/StringPrototype.cpp:
+ (JSC::stringProtoFuncReplace):
+
+2011-09-22 Gavin Barraclough <[email protected]>
+
Function.prototype.bind.length shoudl be 1.
Rubber stamped by Olier Hunt.
Modified: trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp (95786 => 95787)
--- trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp 2011-09-23 06:59:38 UTC (rev 95786)
+++ trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp 2011-09-23 07:18:48 UTC (rev 95787)
@@ -543,7 +543,7 @@
MarkedArgumentBuffer l;
l.append(jObj);
l.append(minObj);
- compareResult = call(exec, function, callType, callData, exec->globalThisValue(), l).toNumber(exec);
+ compareResult = call(exec, function, callType, callData, jsUndefined(), l).toNumber(exec);
} else
compareResult = (jObj.toString(exec) < minObj.toString(exec)) ? -1 : 1;
@@ -671,7 +671,7 @@
if (callType == CallTypeNone)
return throwVMTypeError(exec);
- JSObject* applyThis = exec->argument(1).isUndefinedOrNull() ? exec->globalThisValue() : exec->argument(1).toObject(exec);
+ JSValue applyThis = exec->argument(1);
JSArray* resultArray = constructEmptyArray(exec);
unsigned filterIndex = 0;
@@ -730,7 +730,7 @@
if (callType == CallTypeNone)
return throwVMTypeError(exec);
- JSObject* applyThis = exec->argument(1).isUndefinedOrNull() ? exec->globalThisValue() : exec->argument(1).toObject(exec);
+ JSValue applyThis = exec->argument(1);
JSArray* resultArray = constructEmptyArray(exec, length);
unsigned k = 0;
@@ -792,7 +792,7 @@
if (callType == CallTypeNone)
return throwVMTypeError(exec);
- JSObject* applyThis = exec->argument(1).isUndefinedOrNull() ? exec->globalThisValue() : exec->argument(1).toObject(exec);
+ JSValue applyThis = exec->argument(1);
JSValue result = jsBoolean(true);
@@ -850,7 +850,7 @@
if (callType == CallTypeNone)
return throwVMTypeError(exec);
- JSObject* applyThis = exec->argument(1).isUndefinedOrNull() ? exec->globalThisValue() : exec->argument(1).toObject(exec);
+ JSValue applyThis = exec->argument(1);
unsigned k = 0;
if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) {
@@ -900,7 +900,7 @@
if (callType == CallTypeNone)
return throwVMTypeError(exec);
- JSObject* applyThis = exec->argument(1).isUndefinedOrNull() ? exec->globalThisValue() : exec->argument(1).toObject(exec);
+ JSValue applyThis = exec->argument(1);
JSValue result = jsBoolean(false);
Modified: trunk/Source/_javascript_Core/runtime/JSArray.cpp (95786 => 95787)
--- trunk/Source/_javascript_Core/runtime/JSArray.cpp 2011-09-23 06:59:38 UTC (rev 95786)
+++ trunk/Source/_javascript_Core/runtime/JSArray.cpp 2011-09-23 07:18:48 UTC (rev 95787)
@@ -1016,7 +1016,6 @@
JSValue m_compareFunction;
CallType m_compareCallType;
const CallData* m_compareCallData;
- JSValue m_globalThisValue;
OwnPtr<CachedCall> m_cachedCall;
handle get_less(handle h) { return m_nodes[h].lt & 0x7FFFFFFF; }
@@ -1055,7 +1054,7 @@
double compareResult;
if (m_cachedCall) {
- m_cachedCall->setThis(m_globalThisValue);
+ m_cachedCall->setThis(jsUndefined());
m_cachedCall->setArgument(0, va);
m_cachedCall->setArgument(1, vb);
compareResult = m_cachedCall->call().toNumber(m_cachedCall->newCallFrame(m_exec));
@@ -1063,7 +1062,7 @@
MarkedArgumentBuffer arguments;
arguments.append(va);
arguments.append(vb);
- compareResult = call(m_exec, m_compareFunction, m_compareCallType, *m_compareCallData, m_globalThisValue, arguments).toNumber(m_exec);
+ compareResult = call(m_exec, m_compareFunction, m_compareCallType, *m_compareCallData, jsUndefined(), arguments).toNumber(m_exec);
}
return (compareResult < 0) ? -1 : 1; // Not passing equality through, because we need to store all values, even if equivalent.
}
@@ -1099,7 +1098,6 @@
tree.abstractor().m_compareFunction = compareFunction;
tree.abstractor().m_compareCallType = callType;
tree.abstractor().m_compareCallData = &callData;
- tree.abstractor().m_globalThisValue = exec->globalThisValue();
tree.abstractor().m_nodes.grow(nodeCount);
if (callType == CallTypeJS)
Modified: trunk/Source/_javascript_Core/runtime/StringPrototype.cpp (95786 => 95787)
--- trunk/Source/_javascript_Core/runtime/StringPrototype.cpp 2011-09-23 06:59:38 UTC (rev 95786)
+++ trunk/Source/_javascript_Core/runtime/StringPrototype.cpp 2011-09-23 07:18:48 UTC (rev 95787)
@@ -448,7 +448,7 @@
cachedCall.setArgument(i++, jsNumber(completeMatchStart));
cachedCall.setArgument(i++, sourceVal);
- cachedCall.setThis(exec->globalThisValue());
+ cachedCall.setThis(jsUndefined());
JSValue result = cachedCall.call();
if (LIKELY(result.isString()))
replacements.append(asString(result)->value(exec));
@@ -495,7 +495,7 @@
args.append(jsNumber(completeMatchStart));
args.append(sourceVal);
- replacements.append(call(exec, replacement, callType, callData, exec->globalThisValue(), args).toString(exec));
+ replacements.append(call(exec, replacement, callType, callData, jsUndefined(), args).toString(exec));
if (exec->hadException())
break;
} else {
@@ -551,7 +551,7 @@
args.append(jsNumber(matchPos));
args.append(sourceVal);
- replacementString = call(exec, replacement, callType, callData, exec->globalThisValue(), args).toString(exec);
+ replacementString = call(exec, replacement, callType, callData, jsUndefined(), args).toString(exec);
}
size_t matchEnd = matchPos + matchLen;