Changeset 196690 in webkit
- Timestamp:
- Feb 17, 2016 12:38:27 AM (8 years ago)
- Location:
- trunk
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r196688 r196690 1 2016-02-17 Chris Dumez <cdumez@apple.com> 2 3 Window should have its 'constructor' property on the prototype 4 https://bugs.webkit.org/show_bug.cgi?id=154037 5 <rdar://problem/24689078> 6 7 Reviewed by Gavin Barraclough. 8 9 * http/tests/security/cross-origin-window-property-access-expected.txt: 10 * http/tests/security/cross-origin-window-property-access.html: 11 Add checks to make sure it still is not possible to access 12 window.constructor cross-origin. 13 14 * js/getOwnPropertyDescriptor-window-attributes-expected.txt: 15 * js/getOwnPropertyDescriptor-window-attributes.html: 16 Update test now that window has it's "constructor" attribute 17 on the prototype. 18 1 19 2016-02-16 Carlos Garcia Campos <cgarcia@igalia.com> 2 20 -
trunk/LayoutTests/http/tests/security/cross-origin-window-property-access-expected.txt
r196220 r196690 4 4 CONSOLE MESSAGE: line 1: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a frame with origin "http://localhost:8000". Protocols, domains, and ports must match. 5 5 CONSOLE MESSAGE: line 1: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a frame with origin "http://localhost:8000". Protocols, domains, and ports must match. 6 CONSOLE MESSAGE: line 15: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a frame with origin "http://localhost:8000". Protocols, domains, and ports must match. 7 CONSOLE MESSAGE: line 15: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a frame with origin "http://localhost:8000". Protocols, domains, and ports must match. 6 8 Tests that using another window's property getter does not bypass cross-origin checks. 7 9 … … 15 17 PASS Object.getOwnPropertyDescriptor(window, "navigator").get.call(crossOriginWindow) returned undefined. 16 18 PASS Object.getOwnPropertyDescriptor(window, "screenX").get.call(crossOriginWindow) returned undefined. 19 PASS Object.getOwnPropertyDescriptor(window.__proto__, "constructor").get.call(crossOriginWindow) threw exception TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(window.__proto__, "constructor").get.call'). 20 PASS Object.getOwnPropertyDescriptor(window.__proto__, "constructor").get.call(crossOriginWindow.__proto__) threw exception TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(window.__proto__, "constructor").get.call'). 21 PASS crossOriginWindow.constructor returned undefined. 22 PASS Object.getOwnPropertyDescriptor(crossOriginWindow.__proto__, "constructor").value threw exception TypeError: undefined is not an object (evaluating 'Object.getOwnPropertyDescriptor(crossOriginWindow.__proto__, "constructor")'). 17 23 PASS Object.getOwnPropertyDescriptor(window, "location").get.call(crossOriginWindow) === crossOriginWindow.location is true 18 24 PASS successfullyParsed is true -
trunk/LayoutTests/http/tests/security/cross-origin-window-property-access.html
r196220 r196690 33 33 shouldThrowOrReturnUndefined('Object.getOwnPropertyDescriptor(window, "navigator").get.call(crossOriginWindow)'); 34 34 shouldThrowOrReturnUndefined('Object.getOwnPropertyDescriptor(window, "screenX").get.call(crossOriginWindow)'); 35 shouldThrowOrReturnUndefined('Object.getOwnPropertyDescriptor(window.__proto__, "constructor").get.call(crossOriginWindow)'); 36 shouldThrowOrReturnUndefined('Object.getOwnPropertyDescriptor(window.__proto__, "constructor").get.call(crossOriginWindow.__proto__)'); 37 shouldThrowOrReturnUndefined('crossOriginWindow.constructor'); 38 shouldThrowOrReturnUndefined('Object.getOwnPropertyDescriptor(crossOriginWindow.__proto__, "constructor").value'); 35 39 shouldBeTrue('Object.getOwnPropertyDescriptor(window, "location").get.call(crossOriginWindow) === crossOriginWindow.location'); 36 40 finishJSTest(); -
trunk/LayoutTests/imported/w3c/ChangeLog
r196673 r196690 1 2016-02-17 Chris Dumez <cdumez@apple.com> 2 3 Window should have its 'constructor' property on the prototype 4 https://bugs.webkit.org/show_bug.cgi?id=154037 5 <rdar://problem/24689078> 6 7 Reviewed by Gavin Barraclough. 8 9 Rebaseline W3C test now that one more check is passing. 10 11 * web-platform-tests/html/dom/interfaces-expected.txt: 12 1 13 2016-02-16 Chris Dumez <cdumez@apple.com> 2 14 -
trunk/LayoutTests/imported/w3c/web-platform-tests/html/dom/interfaces-expected.txt
r196676 r196690 3812 3812 PASS Window interface object name 3813 3813 FAIL Window interface: existence and properties of interface prototype object assert_equals: Class name for prototype of Window.prototype is not "WindowProperties" expected "[object WindowProperties]" but got "[object EventTargetPrototype]" 3814 FAIL Window interface: existence and properties of interface prototype object's "constructor" property assert_own_property: Window.prototype does not have own property "constructor" expected property "constructor" missing 3814 PASS Window interface: existence and properties of interface prototype object's "constructor" property 3815 3815 PASS Window interface: attribute self 3816 3816 PASS Window interface: attribute name -
trunk/LayoutTests/js/getOwnPropertyDescriptor-window-attributes-expected.txt
r196374 r196690 55 55 PASS descriptor.value is window.Node 56 56 57 * window. constructor57 * window.__proto__.constructor 58 58 PASS descriptor.enumerable is false 59 59 PASS descriptor.writable is true -
trunk/LayoutTests/js/getOwnPropertyDescriptor-window-attributes.html
r196374 r196690 63 63 64 64 debug(""); 65 // FIXME: 'constructor' should be on the prototype. 66 debug("* window.constructor"); 67 descriptor = Object.getOwnPropertyDescriptor(window, "constructor"); 65 debug("* window.__proto__.constructor"); 66 descriptor = Object.getOwnPropertyDescriptor(window.__proto__, "constructor"); 68 67 shouldBeFalse("descriptor.enumerable"); 69 68 shouldBeTrue("descriptor.writable"); -
trunk/Source/WebCore/ChangeLog
r196688 r196690 1 2016-02-17 Chris Dumez <cdumez@apple.com> 2 3 Window should have its 'constructor' property on the prototype 4 https://bugs.webkit.org/show_bug.cgi?id=154037 5 <rdar://problem/24689078> 6 7 Reviewed by Gavin Barraclough. 8 9 Window should have its 'constructor' property on the prototype as per 10 the Web IDL specification: 11 http://heycam.github.io/webidl/#interface-prototype-object 12 13 Firefox and Chrome already match the specification. 14 15 No new tests, covered by: 16 - fast/dom/Window/window-constructor-settable.html 17 - fast/dom/Window/window-constructor.html 18 - http/tests/security/cross-origin-window-property-access.html 19 - imported/w3c/web-platform-tests/html/dom/interfaces.html 20 21 * bindings/scripts/CodeGeneratorJS.pm: 22 (ConstructorShouldBeOnInstance): Deleted. 23 Drop this routine as all constructors are now on the prototype. 24 25 (InstancePropertyCount): 26 Do not account for constructor properties as these can only be 27 on the prototype now. 28 29 (PrototypePropertyCount): 30 Increment the property count by 1 if the interface has a constructor 31 property (e.g. [NoInterfaceObject] interfaces do not have one). 32 33 (GeneratePropertiesHashTable): 34 Stop calling ConstructorShouldBeOnInstance() as it no longer exists. 35 Always generated the "constructor" property if: 36 1. We are generating the prototype hash table. 37 and 38 2. The interface needs a constructor (i.e. not marked as 39 [NoInterfaceObject]). 40 41 (GenerateImplementation): 42 - Drop code handling the case where ConstructorShouldBeOnInstance() 43 returns true as constructors are not always on the prototype and 44 the ConstructorShouldBeOnInstance() routine has been dropped. 45 - Drop code handling [CustomProxyToJSObject]. Now that the constructor 46 is always on the prototype, we never need to cast thisValue to a 47 JSDOMWindow (by calling toJSDOMWindow). In the Window case, thisValue 48 is now casted to a JSDOMWindowPrototype*, similarly to other interfaces 49 so we don't need a special casting function anymore. 50 - Stop generating security checks. This only impacts Window as it is the 51 only interface marked as [CheckSecurity]. The cross-origin checking code 52 as it was would not work when "constructor" is on the prototype because 53 thisValue is a JSDOMWindowPrototype, not a JSDOMWindow and we have no 54 way of getting the wrapped window. Also, the security check is no longer 55 needed because: 56 1. Accessing crossOriginWindow.constructor will not work now that 57 constructor is on the prototype because 58 JSDOMWindow::getOwnPropertySlot() already prevents access to the 59 prototype in the cross-origin case. 60 2. "constructor" is a value property, not a getter/setter. Therefore, 61 it is no possible to use the getter/setter from a same origin window 62 instance and call it on a cross origin window. 63 1 64 2016-02-16 Carlos Garcia Campos <cgarcia@igalia.com> 2 65 -
trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
r196673 r196690 682 682 } 683 683 684 sub ConstructorShouldBeOnInstance685 {686 my $interface = shift;687 688 # FIXME: constructor should always be on the prototype:689 # http://www.w3.org/TR/WebIDL/#interface-prototype-object690 return 1 if $interface->extendedAttributes->{"CheckSecurity"};691 return 0;692 }693 694 684 sub AttributeShouldBeOnInstanceForCompatibility 695 685 { … … 791 781 } 792 782 $count += InstanceFunctionCount($interface); 793 $count++ if ConstructorShouldBeOnInstance($interface);794 783 return $count; 795 784 } … … 803 792 } 804 793 $count += PrototypeFunctionCount($interface); 805 $count++ if !ConstructorShouldBeOnInstance($interface);794 $count++ if NeedsConstructorProperty($interface); 806 795 return $count; 807 796 } … … 1389 1378 my $propertyCount = $isInstance ? InstancePropertyCount($interface) : PrototypePropertyCount($interface); 1390 1379 1391 if (ConstructorShouldBeOnInstance($interface) == $isInstance) { 1392 1393 if (NeedsConstructorProperty($interface)) { 1394 die if !$propertyCount; 1395 push(@$hashKeys, "constructor"); 1396 my $getter = "js" . $interfaceName . "Constructor"; 1397 push(@$hashValue1, $getter); 1398 1399 my $setter = "setJS" . $interfaceName . "Constructor"; 1400 push(@$hashValue2, $setter); 1401 push(@$hashSpecials, "DontEnum"); 1402 } 1380 if (!$isInstance && NeedsConstructorProperty($interface)) { 1381 die if !$propertyCount; 1382 push(@$hashKeys, "constructor"); 1383 my $getter = "js" . $interfaceName . "Constructor"; 1384 push(@$hashValue1, $getter); 1385 1386 my $setter = "setJS" . $interfaceName . "Constructor"; 1387 push(@$hashValue2, $setter); 1388 push(@$hashSpecials, "DontEnum"); 1403 1389 } 1404 1390 … … 2524 2510 my $constructorFunctionName = "js" . $interfaceName . "Constructor"; 2525 2511 2526 if ($interface->extendedAttributes->{"CustomProxyToJSObject"}) { 2527 push(@implContent, "EncodedJSValue ${constructorFunctionName}(ExecState* state, EncodedJSValue thisValue, PropertyName)\n"); 2528 push(@implContent, "{\n"); 2529 push(@implContent, " ${className}* domObject = to${className}(JSValue::decode(thisValue));\n"); 2530 } elsif (ConstructorShouldBeOnInstance($interface)) { 2531 push(@implContent, "EncodedJSValue ${constructorFunctionName}(ExecState* state, EncodedJSValue thisValue, PropertyName)\n"); 2532 push(@implContent, "{\n"); 2533 push(@implContent, " ${className}* domObject = " . GetCastingHelperForThisObject($interface) . "(JSValue::decode(thisValue));\n"); 2534 } else { 2535 push(@implContent, "EncodedJSValue ${constructorFunctionName}(ExecState* state, EncodedJSValue thisValue, PropertyName)\n"); 2536 push(@implContent, "{\n"); 2537 push(@implContent, " ${className}Prototype* domObject = jsDynamicCast<${className}Prototype*>(JSValue::decode(thisValue));\n"); 2538 } 2512 push(@implContent, "EncodedJSValue ${constructorFunctionName}(ExecState* state, EncodedJSValue thisValue, PropertyName)\n"); 2513 push(@implContent, "{\n"); 2514 push(@implContent, " ${className}Prototype* domObject = jsDynamicCast<${className}Prototype*>(JSValue::decode(thisValue));\n"); 2539 2515 push(@implContent, " if (!domObject)\n"); 2540 2516 push(@implContent, " return throwVMTypeError(state);\n"); 2541 2542 if ($interface->extendedAttributes->{"CheckSecurity"}) {2543 die if !ConstructorShouldBeOnInstance($interface);2544 push(@implContent, " if (!BindingSecurity::shouldAllowAccessToDOMWindow(state, domObject->wrapped()))\n");2545 push(@implContent, " return JSValue::encode(jsUndefined());\n");2546 }2547 2517 2548 2518 if (!$interface->extendedAttributes->{"NoInterfaceObject"}) { … … 2562 2532 push(@implContent, "{\n"); 2563 2533 push(@implContent, " JSValue value = JSValue::decode(encodedValue);\n"); 2564 if ($interface->extendedAttributes->{"CustomProxyToJSObject"}) { 2565 push(@implContent, " ${className}* domObject = to${className}(JSValue::decode(thisValue));\n"); 2566 } elsif (ConstructorShouldBeOnInstance($interface)) { 2567 push(@implContent, " ${className}* domObject = " . GetCastingHelperForThisObject($interface) . "(JSValue::decode(thisValue));\n"); 2568 } else { 2569 push(@implContent, " ${className}Prototype* domObject = jsDynamicCast<${className}Prototype*>(JSValue::decode(thisValue));\n"); 2570 } 2534 push(@implContent, " ${className}Prototype* domObject = jsDynamicCast<${className}Prototype*>(JSValue::decode(thisValue));\n"); 2571 2535 push(@implContent, " if (UNLIKELY(!domObject)) {\n"); 2572 2536 push(@implContent, " throwVMTypeError(state);\n"); 2573 2537 push(@implContent, " return;\n"); 2574 2538 push(@implContent, " }\n"); 2575 if ($interface->extendedAttributes->{"CheckSecurity"}) {2576 if ($interfaceName eq "DOMWindow") {2577 push(@implContent, " if (!BindingSecurity::shouldAllowAccessToDOMWindow(state, domObject->wrapped()))\n");2578 } else {2579 push(@implContent, " if (!shouldAllowAccessToFrame(state, domObject->wrapped().frame()))\n");2580 }2581 push(@implContent, " return;\n");2582 }2583 2539 2584 2540 push(@implContent, " // Shadowing a built-in constructor\n"); -
trunk/Source/WebCore/bindings/scripts/test/JS/JSTestActiveDOMObject.cpp
r196563 r196690 74 74 /* Hash table */ 75 75 76 static const struct CompactHashIndex JSTestActiveDOMObjectTableIndex[4] = { 77 { 1, -1 }, 76 static const struct CompactHashIndex JSTestActiveDOMObjectTableIndex[2] = { 78 77 { 0, -1 }, 79 78 { -1, -1 }, 80 { -1, -1 },81 79 }; 82 80 … … 84 82 static const HashTableValue JSTestActiveDOMObjectTableValues[] = 85 83 { 86 { "constructor", DontEnum, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestActiveDOMObjectConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSTestActiveDOMObjectConstructor) } },87 84 { "excitingAttr", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestActiveDOMObjectExcitingAttr), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, 88 85 }; 89 86 90 static const HashTable JSTestActiveDOMObjectTable = { 2, 3, true, JSTestActiveDOMObjectTableValues, JSTestActiveDOMObjectTableIndex };87 static const HashTable JSTestActiveDOMObjectTable = { 1, 1, true, JSTestActiveDOMObjectTableValues, JSTestActiveDOMObjectTableIndex }; 91 88 template<> JSValue JSTestActiveDOMObjectConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject) 92 89 { … … 108 105 static const HashTableValue JSTestActiveDOMObjectPrototypeTableValues[] = 109 106 { 107 { "constructor", DontEnum, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestActiveDOMObjectConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSTestActiveDOMObjectConstructor) } }, 110 108 { "excitingFunction", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestActiveDOMObjectPrototypeFunctionExcitingFunction), (intptr_t) (1) } }, 111 109 { "postMessage", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestActiveDOMObjectPrototypeFunctionPostMessage), (intptr_t) (1) } }, … … 171 169 EncodedJSValue jsTestActiveDOMObjectConstructor(ExecState* state, EncodedJSValue thisValue, PropertyName) 172 170 { 173 JSTestActiveDOMObject * domObject = jsDynamicCast<JSTestActiveDOMObject*>(JSValue::decode(thisValue));171 JSTestActiveDOMObjectPrototype* domObject = jsDynamicCast<JSTestActiveDOMObjectPrototype*>(JSValue::decode(thisValue)); 174 172 if (!domObject) 175 173 return throwVMTypeError(state); 176 if (!BindingSecurity::shouldAllowAccessToDOMWindow(state, domObject->wrapped()))177 return JSValue::encode(jsUndefined());178 174 return JSValue::encode(JSTestActiveDOMObject::getConstructor(state->vm(), domObject->globalObject())); 179 175 } … … 182 178 { 183 179 JSValue value = JSValue::decode(encodedValue); 184 JSTestActiveDOMObject * domObject = jsDynamicCast<JSTestActiveDOMObject*>(JSValue::decode(thisValue));180 JSTestActiveDOMObjectPrototype* domObject = jsDynamicCast<JSTestActiveDOMObjectPrototype*>(JSValue::decode(thisValue)); 185 181 if (UNLIKELY(!domObject)) { 186 182 throwVMTypeError(state); 187 183 return; 188 184 } 189 if (!shouldAllowAccessToFrame(state, domObject->wrapped().frame()))190 return;191 185 // Shadowing a built-in constructor 192 186 domObject->putDirect(state->vm(), state->propertyNames().constructor, value);
Note: See TracChangeset
for help on using the changeset viewer.