diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index 94f0342d261..909145ef494 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -48,6 +48,7 @@ #include "AccessCheck.h" #include "xpcprivate.h" +#include "XPCWrapper.h" #include "nscore.h" #include "nsDOMClassInfo.h" @@ -516,7 +517,6 @@ static const char kDOMStringBundleURL[] = #define WINDOW_SCRIPTABLE_FLAGS \ (nsIXPCScriptable::WANT_GETPROPERTY | \ - nsIXPCScriptable::WANT_SETPROPERTY | \ nsIXPCScriptable::WANT_PRECREATE | \ nsIXPCScriptable::WANT_FINALIZE | \ nsIXPCScriptable::WANT_EQUALITY | \ @@ -5269,39 +5269,6 @@ nsWindowSH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, return NS_OK; } -NS_IMETHODIMP -nsWindowSH::SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, - JSObject *obj, jsid id, jsval *vp, PRBool *_retval) -{ - if (id == sLocation_id) { - JSAutoRequest ar(cx); - - JSString *val = ::JS_ValueToString(cx, *vp); - NS_ENSURE_TRUE(val, NS_ERROR_UNEXPECTED); - - nsCOMPtr window = do_QueryWrappedNative(wrapper); - NS_ENSURE_TRUE(window, NS_ERROR_UNEXPECTED); - - nsCOMPtr location; - nsresult rv = window->GetLocation(getter_AddRefs(location)); - NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && location, rv); - - nsCOMPtr holder; - rv = WrapNative(cx, obj, location, &NS_GET_IID(nsIDOMLocation), PR_TRUE, - vp, getter_AddRefs(holder)); - NS_ENSURE_SUCCESS(rv, rv); - - nsDependentJSString depStr; - NS_ENSURE_TRUE(depStr.init(cx, val), NS_ERROR_UNEXPECTED); - - rv = location->SetHref(depStr); - - return NS_FAILED(rv) ? rv : NS_SUCCESS_I_DID_SOMETHING; - } - - return NS_OK; -} - NS_IMETHODIMP nsWindowSH::Enumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx, JSObject *obj, PRBool *_retval) @@ -6392,6 +6359,68 @@ static JSNewResolveOp sOtherResolveFuncs[] = { mozilla::dom::workers::ResolveWorkerClasses }; +template +static nsresult +LocationSetterGuts(JSContext *cx, JSObject *obj, jsval *vp) +{ + // This function duplicates some of the logic in XPC_WN_HelperSetProperty + XPCWrappedNative *wrapper = + XPCWrappedNative::GetWrappedNativeOfJSObject(cx, obj); + + // The error checks duplicate code in THROW_AND_RETURN_IF_BAD_WRAPPER + NS_ENSURE_TRUE(wrapper, NS_ERROR_XPC_BAD_OP_ON_WN_PROTO); + NS_ENSURE_TRUE(wrapper->IsValid(), NS_ERROR_XPC_HAS_BEEN_SHUTDOWN); + + nsCOMPtr xpcomObj = do_QueryWrappedNative(wrapper); + NS_ENSURE_TRUE(xpcomObj, NS_ERROR_UNEXPECTED); + + nsCOMPtr location; + nsresult rv = xpcomObj->GetLocation(getter_AddRefs(location)); + NS_ENSURE_SUCCESS(rv, rv); + + JSString *val = ::JS_ValueToString(cx, *vp); + NS_ENSURE_TRUE(val, NS_ERROR_UNEXPECTED); + + nsDependentJSString depStr; + NS_ENSURE_TRUE(depStr.init(cx, val), NS_ERROR_UNEXPECTED); + + rv = location->SetHref(depStr); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr holder; + return WrapNative(cx, JS_GetGlobalForScopeChain(cx), location, + &NS_GET_IID(nsIDOMLocation), PR_TRUE, vp, + getter_AddRefs(holder)); +} + +template +static JSBool +LocationSetter(JSContext *cx, JSObject *obj, jsid id, JSBool strict, + jsval *vp) +{ + nsresult rv = LocationSetterGuts(cx, obj, vp); + if (NS_FAILED(rv)) { + if (!::JS_IsExceptionPending(cx)) { + nsDOMClassInfo::ThrowJSException(cx, rv); + } + return JS_FALSE; + } + + return JS_TRUE; +} + +static JSBool +LocationSetterUnwrapper(JSContext *cx, JSObject *obj, jsid id, JSBool strict, + jsval *vp) +{ + JSObject *wrapped = XPCWrapper::UnsafeUnwrapSecurityWrapper(obj); + if (wrapped) { + obj = wrapped; + } + + return LocationSetter(cx, obj, id, strict, vp); +} + NS_IMETHODIMP nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, JSObject *obj, jsid id, PRUint32 flags, @@ -6544,7 +6573,8 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_ENSURE_SUCCESS(rv, rv); JSBool ok = JS_WrapValue(cx, &v) && - JS_DefinePropertyById(cx, obj, id, v, nsnull, nsnull, + JS_DefinePropertyById(cx, obj, id, v, nsnull, + LocationSetterUnwrapper, JSPROP_PERMANENT | JSPROP_ENUMERATE); if (!ok) { @@ -8177,7 +8207,8 @@ nsDocumentSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, JSAutoRequest ar(cx); - JSBool ok = ::JS_DefinePropertyById(cx, obj, id, v, nsnull, nsnull, + JSBool ok = ::JS_DefinePropertyById(cx, obj, id, v, nsnull, + LocationSetter, JSPROP_PERMANENT | JSPROP_ENUMERATE); if (!ok) { @@ -8222,34 +8253,6 @@ NS_IMETHODIMP nsDocumentSH::SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, JSObject *obj, jsid id, jsval *vp, PRBool *_retval) { - if (id == sLocation_id) { - nsCOMPtr doc = do_QueryWrappedNative(wrapper); - NS_ENSURE_TRUE(doc, NS_ERROR_UNEXPECTED); - - nsCOMPtr location; - nsresult rv = doc->GetLocation(getter_AddRefs(location)); - NS_ENSURE_SUCCESS(rv, rv); - - if (location) { - JSAutoRequest ar(cx); - - JSString *val = ::JS_ValueToString(cx, *vp); - NS_ENSURE_TRUE(val, NS_ERROR_UNEXPECTED); - - nsDependentJSString depStr; - NS_ENSURE_TRUE(depStr.init(cx, val), NS_ERROR_UNEXPECTED); - - rv = location->SetHref(depStr); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr holder; - rv = WrapNative(cx, JS_GetGlobalForScopeChain(cx), location, - &NS_GET_IID(nsIDOMLocation), PR_TRUE, vp, - getter_AddRefs(holder)); - return NS_FAILED(rv) ? rv : NS_SUCCESS_I_DID_SOMETHING; - } - } - if (id == sDocumentURIObject_id && IsPrivilegedScript()) { // We don't want privileged script that can read this property to set it, // but _do_ want to allow everyone else to set a value they can then read. diff --git a/dom/base/nsDOMClassInfo.h b/dom/base/nsDOMClassInfo.h index 7f0e94bba1a..5efb38084cb 100644 --- a/dom/base/nsDOMClassInfo.h +++ b/dom/base/nsDOMClassInfo.h @@ -407,8 +407,6 @@ public: #endif NS_IMETHOD GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, JSObject *obj, jsid id, jsval *vp, PRBool *_retval); - NS_IMETHOD SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, - JSObject *obj, jsid id, jsval *vp, PRBool *_retval); NS_IMETHOD Enumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx, JSObject *obj, PRBool *_retval); NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, diff --git a/dom/tests/mochitest/dom-level0/Makefile.in b/dom/tests/mochitest/dom-level0/Makefile.in index 55ace1c5d62..a08896bb4a8 100644 --- a/dom/tests/mochitest/dom-level0/Makefile.in +++ b/dom/tests/mochitest/dom-level0/Makefile.in @@ -55,6 +55,7 @@ _TEST_FILES = \ test_location.html \ test_innerWidthHeight_script.html \ innerWidthHeight_script.html \ + test_location_setters.html \ $(NULL) libs:: $(_TEST_FILES) diff --git a/dom/tests/mochitest/dom-level0/test_location_setters.html b/dom/tests/mochitest/dom-level0/test_location_setters.html new file mode 100644 index 00000000000..eb159c7ff2d --- /dev/null +++ b/dom/tests/mochitest/dom-level0/test_location_setters.html @@ -0,0 +1,78 @@ + + + + + Test for Bug 639720 + + + + +Mozilla Bug 639720 +

+ +

+ +
+
+
+ +