Bug 684601 - window.toString.call() with native JS Object; r=bz

This commit is contained in:
Gabor Krizsanits 2012-10-09 17:21:53 +02:00
Родитель e8eace5748
Коммит c497e1461d
2 изменённых файлов: 52 добавлений и 7 удалений

Просмотреть файл

@ -606,7 +606,7 @@ public:
JSString *
nsOuterWindowProxy::obj_toString(JSContext *cx, JSObject *proxy)
{
JS_ASSERT(js::IsProxy(proxy));
MOZ_ASSERT(js::IsProxy(proxy));
return JS_NewStringCopyZ(cx, "[object Window]");
}
@ -626,8 +626,29 @@ nsOuterWindowProxy::finalize(JSFreeOp *fop, JSObject *proxy)
nsOuterWindowProxy
nsOuterWindowProxy::singleton;
class nsChromeOuterWindowProxy : public nsOuterWindowProxy
{
public:
nsChromeOuterWindowProxy() : nsOuterWindowProxy() {}
virtual JSString *obj_toString(JSContext *cx, JSObject *wrapper);
static nsChromeOuterWindowProxy singleton;
};
JSString *
nsChromeOuterWindowProxy::obj_toString(JSContext *cx, JSObject *proxy)
{
MOZ_ASSERT(js::IsProxy(proxy));
return JS_NewStringCopyZ(cx, "[object ChromeWindow]");
}
nsChromeOuterWindowProxy
nsChromeOuterWindowProxy::singleton;
static JSObject*
NewOuterWindowProxy(JSContext *cx, JSObject *parent)
NewOuterWindowProxy(JSContext *cx, JSObject *parent, bool isChrome)
{
JSAutoCompartment ac(cx, parent);
JSObject *proto;
@ -635,7 +656,9 @@ NewOuterWindowProxy(JSContext *cx, JSObject *parent)
return nullptr;
JSObject *obj = js::Wrapper::New(cx, parent, proto, parent,
&nsOuterWindowProxy::singleton);
isChrome ? &nsChromeOuterWindowProxy::singleton
: &nsOuterWindowProxy::singleton);
NS_ASSERTION(js::GetObjectClass(obj)->ext.innerObject, "bad class");
return obj;
}
@ -1673,7 +1696,8 @@ nsGlobalWindow::CreateOuterObject(nsGlobalWindow* aNewInner)
{
JSContext* cx = mContext->GetNativeContext();
if (IsChromeWindow()) {
bool isChrome = IsChromeWindow();
if (isChrome) {
// Always enable E4X for XUL and other chrome content -- there is no
// need to preserve the <!-- script hiding hack from JS-in-HTML daze
// (introduced in 1995 for graceful script degradation in Netscape 1,
@ -1681,7 +1705,8 @@ nsGlobalWindow::CreateOuterObject(nsGlobalWindow* aNewInner)
JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_MOAR_XML);
}
JSObject* outer = NewOuterWindowProxy(cx, aNewInner->FastGetGlobalJSObject());
JSObject* outer = NewOuterWindowProxy(cx, aNewInner->FastGetGlobalJSObject(),
isChrome);
if (!outer) {
return NS_ERROR_FAILURE;
}
@ -1987,7 +2012,8 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
mJSObject = mContext->GetNativeGlobal();
SetWrapper(mJSObject);
} else {
JSObject *outerObject = NewOuterWindowProxy(cx, xpc_UnmarkGrayObject(newInnerWindow->mJSObject));
JSObject *outerObject = NewOuterWindowProxy(cx, xpc_UnmarkGrayObject(newInnerWindow->mJSObject),
thisChrome);
if (!outerObject) {
NS_ERROR("out of memory");
return NS_ERROR_FAILURE;

Просмотреть файл

@ -11,7 +11,9 @@
#include "XPCWrapper.h"
#include "nsWrapperCacheInlines.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/Preferences.h"
using namespace mozilla;
/***************************************************************************/
// All of the exceptions thrown into JS from this file go through here.
@ -254,8 +256,25 @@ DefinePropertyIfFound(XPCCallContext& ccx,
if (!found) {
if (reflectToStringAndToSource) {
JSNative call;
uint32_t flags = 0;
if (id == rt->GetStringID(XPCJSRuntime::IDX_TO_STRING)) {
if (scriptableInfo) {
nsCOMPtr<nsIClassInfo> classInfo = do_QueryInterface(
scriptableInfo->GetCallback());
if (classInfo) {
nsresult rv = classInfo->GetFlags(&flags);
if (NS_FAILED(rv))
return Throw(rv, ccx);
}
}
bool overwriteToString = !(flags & nsIClassInfo::DOM_OBJECT)
|| Preferences::GetBool("dom.XPCToStringForDOMClasses", false);
if(id == rt->GetStringID(XPCJSRuntime::IDX_TO_STRING)
&& overwriteToString)
{
call = XPC_WN_Shared_ToString;
name = rt->GetStringName(XPCJSRuntime::IDX_TO_STRING);
id = rt->GetStringID(XPCJSRuntime::IDX_TO_STRING);