Bug 832014 part 8. Switch Location to WebIDL bindings. r=peterv,bholley

This commit is contained in:
Boris Zbarsky 2014-07-11 19:32:46 -04:00
parent 296f475579
commit 13b4ac0823
9 changed files with 54 additions and 39 deletions

View File

@ -32,6 +32,7 @@
#include "nsCycleCollectionParticipant.h"
#include "nsNullPrincipal.h"
#include "ScriptSettings.h"
#include "mozilla/dom/LocationBinding.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -60,6 +61,7 @@ nsLocation::nsLocation(nsPIDOMWindow* aWindow, nsIDocShell *aDocShell)
{
MOZ_ASSERT(aDocShell);
MOZ_ASSERT(mInnerWindow->IsInnerWindow());
SetIsDOMBinding();
mDocShell = do_GetWeakReference(aDocShell);
}
@ -1031,3 +1033,9 @@ nsLocation::CallerSubsumes()
NS_ENSURE_SUCCESS(rv, false);
return subsumes;
}
JSObject*
nsLocation::WrapObject(JSContext* aCx)
{
return LocationBinding::Wrap(aCx, this);
}

View File

@ -134,6 +134,7 @@ public:
{
return mInnerWindow;
}
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
protected:
virtual ~nsLocation();

View File

@ -742,11 +742,7 @@ DOMInterfaces = {
},
'Location': {
# NOTE: Before you turn on codegen for Location, make sure all the
# Unforgeable stuff is dealt with.
'nativeType': 'nsLocation',
'skipGen': True,
'register': False
},
'MediaList': {

View File

@ -26,13 +26,13 @@ try {
/* Check that we can touch various properties */
isnot(e.lineNumber, undefined, "Unexpected line number"); //This line number is dependent on the implementation of the SpecialPowers API
is(e.name, "NS_ERROR_MALFORMED_URI", "Unexpected exception name");
isnot(e.message, "", "Should have a message");
ise(e.message, "", "Should not have a message for this case");
isnot(e.result, 0, "Should have a result");
is(e.result, SpecialPowers.Cr.NS_ERROR_MALFORMED_URI);
}
is(threw, true, "Not enough arguments to a call should throw");
is(threw, true, "We need a different testcase for XPConnect exceptions?");
</script>
</pre>
</body>

View File

@ -50,7 +50,9 @@ try {
this.__defineGetter__.call(window.location, 'href', function(){});
ok(false, "shouldn't be able to override location.href");
} catch (e) {
ok(/shadow/.exec(e.message), "Should be caught by the anti-shadow mechanism.");
ok(/shadow/.exec(e.message) ||
/can't redefine non-configurable/.exec(e.message),
"Should be caught by the anti-shadow mechanism.");
}
// Try deleting the property.
@ -61,17 +63,16 @@ delete Object.getPrototypeOf(window.location).href;
ok(typeof window.location.href !== 'undefined',
"shouldn't be able to delete the property off of the prototype");
try {
this.__defineGetter__.call(Object.getPrototypeOf(window.location), 'href', function(){});
ok(false, "shouldn't be able to use the prototype");
} catch (e) {
}
this.__defineGetter__.call(Object.getPrototypeOf(window.location), 'href', function(){});
ok(true, "should be able to define things on the prototype");
try {
this.__defineSetter__.call(window.location, 'href', function(){});
ok(false, "overrode a setter for location.href?");
} catch (e) {
ok(/shadow/.exec(e.message), "Should be caught by the anti-shadow mechanism.");
ok(/shadow/.exec(e.message) ||
/can't redefine non-configurable/.exec(e.message),
"Should be caught by the anti-shadow mechanism.");
}
try {

View File

@ -3,7 +3,7 @@
<head>
<script>
var gTS = window.location.toString;
var gGHR = Object.__lookupGetter__.call(window.location, 'href');
var gGHR = Object.getOwnPropertyDescriptor(window.location, 'href').get;
function getTests(fromOuter) {
function loc() fromOuter ? window.location : location;
@ -23,18 +23,12 @@ function getTests(fromOuter) {
getLocationApply3: function() {
return Function.call.apply(gTS, [loc()]);
},
getLocationViaPrototype: function() {
return Location.prototype.toString.call(loc());
},
getHref: function() {
return loc().href;
},
getHrefViaApply: function() {
return Function.call.apply(gGHR, [loc()]);
},
getHrefViaPrototype: function() {
return Object.getOwnPropertyDescriptor(Location.prototype, 'href').get.call(loc());
}
}
};

View File

@ -26,7 +26,9 @@ function checkThrows(f, desc, skipMessageCheck) {
} catch (e) {
ok(true, "threw correctly");
if (!skipMessageCheck)
ok(/denied/.exec(e), "Correctly threw a security exception: " + e);
ok(/denied/.exec(e) ||
/can't redefine non-configurable property/.exec(e),
"Correctly threw a security exception: " + e);
}
}
@ -35,24 +37,13 @@ checkThrows(function() { "use strict"; location.valueOf = 'hah'; }, 'Shadow with
checkThrows(function() { "use strict"; location.valueOf = function() { return {a: 'hah'};} }, 'Shadow with function', /* skipMessageCheck = */ true);
checkThrows(function() { Object.defineProperty(location, 'valueOf', { value: function() { return 'hah'; } }); }, 'defineProperty with value');
checkThrows(function() { delete location.valueOf; Object.defineProperty(location, 'valueOf', { value: function() { return 'hah'; } }); }, 'delete + defineProperty with value');
checkThrows(function() { Object.defineProperty(location, 'valueOf', { getter: function() { return 'hah'; } }); }, 'defineProperty with getter');
checkThrows(function() { delete location.valueOf; Object.defineProperty(location, 'valueOf', { getter: function() { return 'hah'; } }); }, 'delete + defineProperty with getter');
checkThrows(function() { Object.defineProperty(location, 'valueOf', { get: function() { return 'hah'; } }); }, 'defineProperty with getter');
checkThrows(function() { delete location.valueOf; Object.defineProperty(location, 'valueOf', { get: function() { return 'hah'; } }); }, 'delete + defineProperty with getter');
Object.prototype.valueOf = function() { return 'hah'; };
is(({}).valueOf(), 'hah', "Shadowing on Object.prototype works for vanilla objects");
is(location.valueOf(), location, "Shadowing on Object.prototype and Location.prototype doesn't for location objects");
// Make sure that Location.prototype can't be mucked with.
function checkProto() {
"use strict"
checkThrows(function() { Location.prototype.foo = 'hah'; }, 'adding new property to Location.prototype', /* skipMessageCheck = */ true);
checkThrows(function() { Location.prototype.valueOf = 'hah'; }, 'defining valueOf on Location.prototype', /* skipMessageCheck = */ true);
checkThrows(function() { delete Location.prototype.toString; }, 'deleting property on Location.prototype', /* skipMessageCheck = */ true);
checkThrows(function() { Location.prototype.toString = 'hah'; }, 'setting property on Location.prototype', /* skipMessageCheck = */ true);
checkThrows(function() { Object.defineProperty(Location.prototype, 'toString', {value: 'hah'}); }, 'defining property on Location.prototype', /* skipMessageCheck = */ true);
};
checkProto();
</script>
</pre>
</body>

View File

@ -35,12 +35,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=802557
// [getter, description, locationObj, bound]
gGetters = [[ location.toString, 'toString from LW' ],
[ gLoc.toString, 'toString from XLW' ],
[ Location.prototype.toString, 'toString from Location.prototype' ],
[ iWin.Location.prototype.toString, 'toString from iWin.Location.prototype' ],
[ Object.__lookupGetter__.call(location, 'href'), 'href getter from LW' ],
[ Object.__lookupGetter__.call(gLoc, 'href'), 'href getter from XLW' ],
[ Object.getOwnPropertyDescriptor(Location.prototype, 'href').get, 'href getter from Location.prototype' ],
[ Object.getOwnPropertyDescriptor(iWin.Location.prototype, 'href').get, 'href getter from iWin.Location.prototype' ],
[ Object.getOwnPropertyDescriptor(location, 'href').get, 'href getter from location' ],
[ Object.getOwnPropertyDescriptor(gLoc, 'href').get, 'href getter from iWin.location' ],
[ function() { return this + ''; }, 'implicit conversion via [[DefaultValue]]', /* doMessageCheck = */ true ]];
gGetters.forEach(function(item) {
try {
@ -71,6 +69,32 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=802557
var f = gTestFunctions[fun];
checkThrows(f, "calling " + fun);
}
// Verify that URL.prototype.toString can't be applied to Location
var threw = false;
try {
URL.prototype.toString.call(location);
} catch (e) {
threw = true;
}
ok(threw,
"Should not be able to use URL.prototype.toString on a Location instance");
// Verify that URL.prototype.href getter can't be applied to Location
threw = false;
var reachedTest = false;
try {
var get = Object.getOwnPropertyDescriptor(URL.prototype, "href").get;
is(typeof(get), "function", "Should have an href getter on URL.prototype");
var reachedTest = true;
get.call(location);
} catch (e) {
threw = true;
}
ok(reachedTest,
"Should not be able to find URL.prototype.href getter");
ok(threw,
"Should not be able to use URL.prototype.href getter on a Location instance");
SimpleTest.finish();
}
}

View File

@ -23,7 +23,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=870423
check(window, sowin, 'Location', function(win) { return win.location; });
ok(xowin instanceof Window, "Cross-origin instanceof should work");
todo(xowin.location instanceof Location, "Cross-origin instanceof should work");
ok(xowin.location instanceof Location, "Cross-origin instanceof should work");
SimpleTest.finish();
}