Backing out mrbkap's fix for bug 399587, in the hope of fixing bug 410323 and perhaps bug 410291.

This commit is contained in:
jruderman@hmc.edu 2008-01-03 20:12:48 -08:00
Родитель 8d7ec82ab9
Коммит cb1d9da831
13 изменённых файлов: 95 добавлений и 337 удалений

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

@ -2155,7 +2155,7 @@ nsHTMLDocument::OpenCommon(const nsACString& aContentType, PRBool aReplace)
NS_FAILED(callerPrincipal->Equals(NodePrincipal(), &samePrincipal)) ||
!samePrincipal) {
SetIsInitialDocument(PR_FALSE);
}
}
rv = window->SetNewDocument(this, nsnull, PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);

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

@ -4737,21 +4737,6 @@ nsWindowSH::DelProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
return NS_ERROR_DOM_SECURITY_ERR;
}
// Notify any XOWs on our outer window.
nsGlobalWindow *outerWin = win->GetOuterWindowInternal();
if (outerWin) {
nsCOMPtr<nsIXPConnectWrappedNative> wn;
nsIXPConnect *xpc = nsContentUtils::XPConnect();
nsresult rv =
xpc->GetWrappedNativeOfJSObject(cx, outerWin->GetGlobalJSObject(),
getter_AddRefs(wn));
NS_ENSURE_SUCCESS(rv, rv);
rv = xpc->UpdateXOWs(cx, wn, nsIXPConnect::XPC_XOW_CLEARSCOPE);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
}
@ -5880,8 +5865,10 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
// a different context.
if (!win->IsChromeWindow()) {
rv = sXPConnect->GetXOWForObject(cx, win->GetGlobalJSObject(),
JSVAL_TO_OBJECT(v), &v);
rv = sXPConnect->GetCrossOriginWrapperForObject(cx,
win->GetGlobalJSObject(),
JSVAL_TO_OBJECT(v),
&v);
NS_ENSURE_SUCCESS(rv, rv);
}
@ -5992,7 +5979,9 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
sDoSecurityCheckInAddProperty = PR_FALSE;
if (!win->IsChromeWindow()) {
rv = sXPConnect->GetXOWForObject(cx, scope, JSVAL_TO_OBJECT(v), &v);
rv = sXPConnect->GetCrossOriginWrapperForObject(cx, scope,
JSVAL_TO_OBJECT(v),
&v);
NS_ENSURE_SUCCESS(rv, rv);
}
@ -6100,8 +6089,10 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
scope = oldWin->GetGlobalJSObject();
}
rv = sXPConnect->GetXOWForObject(cx, scope, JSVAL_TO_OBJECT(winVal),
&winVal);
rv = sXPConnect->GetCrossOriginWrapperForObject(cx,
scope,
JSVAL_TO_OBJECT(winVal),
&winVal);
NS_ENSURE_SUCCESS(rv, rv);
}
PRBool ok =
@ -6311,7 +6302,7 @@ nsWindowSH::OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
}
scope = ::JS_GetGlobalForObject(cx, scope);
jsval v;
rv = sXPConnect->GetXOWForObject(cx, scope, winObj, &v);
rv = sXPConnect->GetCrossOriginWrapperForObject(cx, scope, winObj, &v);
*_retval = NS_SUCCEEDED(rv) ? JSVAL_TO_OBJECT(v) : nsnull;
}
@ -7657,8 +7648,8 @@ nsDocumentSH::PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
nsGlobalWindow *internalWin = static_cast<nsGlobalWindow *>(sgo);
if (!internalWin->IsChromeWindow()) {
rv = sXPConnect->GetXOWForObject(cx, sgo->GetGlobalJSObject(), obj,
&docVal);
rv = sXPConnect->GetCrossOriginWrapperForObject(cx, sgo->GetGlobalJSObject(),
obj, &docVal);
NS_ENSURE_SUCCESS(rv, rv);
}

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

@ -447,7 +447,7 @@ interface nsIXPCFunctionThisTranslator : nsISupports
{ 0xbd, 0xd6, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }
%}
[uuid(e2342762-0055-4900-838a-7ef1dddde4c2)]
[uuid(8a47448a-66b0-4beb-a5a2-24f22e9c9dea)]
interface nsIXPConnect : nsISupports
{
%{ C++
@ -729,26 +729,9 @@ interface nsIXPConnect : nsISupports
* @param aParent The parent to create the wrapper with.
* @param aWrappedObj The object to wrap.
*/
[noscript] JSVal getXOWForObject(in JSContextPtr aJSContext,
in JSObjectPtr aParent,
in JSObjectPtr aWrappedObj);
/**
* Tells updateXOWs to clear the scope of all of the XOWs it finds.
*/
const PRUint32 XPC_XOW_CLEARSCOPE = 1;
/**
* Performs an operation over all of |object|'s XOWs such as clearing
* their scopes or updating their concept of the current principal.
*
* @param aJSContext A context to use to perform JS operations.
* @param aObject Which XPCWrappedNative we should find the XOWs for.
* @param aWay What operation to perform.
*/
[noscript] void updateXOWs(in JSContextPtr aJSContext,
in nsIXPConnectWrappedNative aObject,
in PRUint32 aWay);
[noscript] JSVal getCrossOriginWrapperForObject(in JSContextPtr aJSContext,
in JSObjectPtr aParent,
in JSObjectPtr aWrappedObj);
/**
* Root JS objects held by aHolder.

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

@ -191,44 +191,6 @@ GetSecurityManager()
return gScriptSecurityManager;
}
JSBool
XPC_XOW_WrapperMoved(JSContext *cx, XPCWrappedNative *innerObj,
XPCWrappedNativeScope *newScope)
{
typedef WrappedNative2WrapperMap::Link Link;
XPCJSRuntime *rt = nsXPConnect::GetRuntime();
WrappedNative2WrapperMap *map = innerObj->GetScope()->GetWrapperMap();
Link *link;
{ // Scoped lock
XPCAutoLock al(rt->GetMapLock());
link = map->FindLink(innerObj->GetFlatJSObject());
}
if (!link) {
// No link here means that there were no XOWs for this object.
return JS_TRUE;
}
JSObject *xow = link->obj;
{ // Scoped lock.
XPCAutoLock al(rt->GetMapLock());
if (!newScope->GetWrapperMap()->AddLink(innerObj->GetFlatJSObject(), link))
return JS_FALSE;
map->Remove(innerObj->GetFlatJSObject());
}
if (!xow) {
// Nothing else to do.
return JS_TRUE;
}
return JS_SetReservedSlot(cx, xow, XPCWrapper::sNumSlots,
PRIVATE_TO_JSVAL(newScope)) &&
JS_SetParent(cx, xow, newScope->GetGlobalJSObject());
}
static JSBool
IsValFrame(JSContext *cx, JSObject *obj, jsval v, XPCWrappedNative *wn)
{
@ -473,34 +435,43 @@ XPC_XOW_WrapObject(JSContext *cx, JSObject *parent, jsval *vp)
XPCCallContext ccx(NATIVE_CALLER, cx);
NS_ENSURE_TRUE(ccx.IsValid(), JS_FALSE);
// The parent must be the inner global object for its scope.
parent = JS_GetGlobalForObject(cx, parent);
JSClass *clasp = JS_GET_CLASS(cx, parent);
if (clasp->flags & JSCLASS_IS_EXTENDED) {
JSExtendedClass *xclasp = reinterpret_cast<JSExtendedClass *>(clasp);
if (xclasp->innerObject) {
parent = xclasp->innerObject(cx, parent);
if (!parent) {
return JS_FALSE;
}
}
}
XPCWrappedNativeScope *parentScope =
XPCWrappedNativeScope::FindInJSObjectScope(ccx, parent);
XPCWrappedNativeScope *wrapperScope = wn->GetScope();
#ifdef DEBUG_mrbkap
printf("Wrapping object at %p (%s) [%p]\n",
printf("Wrapping object at %p (%s) [%p %p]\n",
(void *)wrappedObj, JS_GET_CLASS(cx, wrappedObj)->name,
(void *)parentScope);
(void *)parentScope, (void *)wrapperScope);
#endif
JSObject *outerObj = nsnull;
WrappedNative2WrapperMap *map = parentScope->GetWrapperMap();
JSBool sameOrigin = (parentScope == wrapperScope);
WrappedNative2WrapperMap *map =
sameOrigin ? wrapperScope->GetWrapperMap() : parentScope->GetWrapperMap();
if (sameOrigin) {
outerObj = wn->GetWrapper();
if (outerObj && JS_GET_CLASS(cx, outerObj) == &sXPC_XOW_JSClass.base) {
#ifdef DEBUG_mrbkap
printf("But found a wrapper already there %p!\n", (void *)outerObj);
#endif
*vp = OBJECT_TO_JSVAL(outerObj);
return JS_TRUE;
}
}
{ // Scoped lock
XPCAutoLock al(rt->GetMapLock());
outerObj = map->Find(wrappedObj);
if (outerObj) {
outerObj = map->Add(wrappedObj, outerObj);
if (sameOrigin) {
wn->SetWrapper(nsnull);
}
} else {
outerObj = map->Find(wrappedObj);
}
}
if (outerObj) {
@ -509,6 +480,9 @@ XPC_XOW_WrapObject(JSContext *cx, JSObject *parent, jsval *vp)
#ifdef DEBUG_mrbkap
printf("But found a wrapper in the map %p!\n", (void *)outerObj);
#endif
if (sameOrigin) {
wn->SetWrapper(outerObj);
}
*vp = OBJECT_TO_JSVAL(outerObj);
return JS_TRUE;
}
@ -533,10 +507,14 @@ XPC_XOW_WrapObject(JSContext *cx, JSObject *parent, jsval *vp)
}
*vp = OBJECT_TO_JSVAL(outerObj);
{ // Scoped lock
if (!sameOrigin) {
XPCAutoLock al(rt->GetMapLock());
map->Add(wn->GetScope()->GetWrapperMap(), wrappedObj, outerObj);
map->Add(wrappedObj, outerObj);
} else {
#ifdef DEBUG_mrbkap
printf("Setting wrapper to %p\n", (void *)outerObj);
#endif
wn->SetWrapper(outerObj);
}
return JS_TRUE;

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

@ -1061,7 +1061,28 @@ XPCNativeWrapper::GetNewOrUsed(JSContext *cx, XPCWrappedNative *wrapper)
}
JSObject *obj = wrapper->GetWrapper();
if (obj && XPCNativeWrapper::IsNativeWrapper(cx, obj)) {
return obj;
}
XPCWrappedNativeScope *scope = wrapper->GetScope();
XPCJSRuntime *rt = nsXPConnect::GetRuntime();
{ // Scoped lock.
XPCAutoLock al(rt->GetMapLock());
if (obj) {
obj = scope->GetWrapperMap()->Add(wrapper->GetFlatJSObject(), obj);
wrapper->SetWrapper(nsnull);
} else {
obj = scope->GetWrapperMap()->Find(wrapper->GetFlatJSObject());
}
}
if (obj) {
NS_ASSERTION(XPCNativeWrapper::IsNativeWrapper(cx, obj),
"Weird object in the wrapper map");
wrapper->SetWrapper(obj);
return obj;
}

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

@ -74,10 +74,6 @@ XPC_XOW_WrapFunction(JSContext *cx, JSObject *wrapperObj, JSObject *funobj,
JSBool
XPC_XOW_RewrapIfNeeded(JSContext *cx, JSObject *wrapperObj, jsval *vp);
JSBool
XPC_XOW_WrapperMoved(JSContext *cx, XPCWrappedNative *innerObj,
XPCWrappedNativeScope *newScope);
nsresult
IsWrapperSameOrigin(JSContext *cx, JSObject *wrappedObj);

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

@ -1916,66 +1916,16 @@ nsXPConnect::GetWrappedNativePrototype(JSContext * aJSContext,
/* [noscript] JSVal GetCrossOriginWrapperForValue(in JSContextPtr aJSContext, in JSVal aCurrentVal); */
NS_IMETHODIMP
nsXPConnect::GetXOWForObject(JSContext * aJSContext,
JSObject * aParent,
JSObject * aWrappedObj,
jsval * rval)
nsXPConnect::GetCrossOriginWrapperForObject(JSContext * aJSContext,
JSObject * aParent,
JSObject * aWrappedObj,
jsval * rval)
{
*rval = OBJECT_TO_JSVAL(aWrappedObj);
return XPC_XOW_WrapObject(aJSContext, aParent, rval)
? NS_OK : NS_ERROR_FAILURE;
}
static inline PRBool
PerformOp(JSContext *cx, PRUint32 aWay, JSObject *obj)
{
NS_ASSERTION(aWay == nsIXPConnect::XPC_XOW_CLEARSCOPE,
"Nothing else is implemented yet");
JS_ClearScope(cx, obj);
return PR_TRUE;
}
/* [noscript] void updateXOWs (in JSContextPtr aJSContext,
* in nsIXPConnectJSObjectHolder aObject,
* in PRUint32 aWay); */
NS_IMETHODIMP
nsXPConnect::UpdateXOWs(JSContext* aJSContext,
nsIXPConnectWrappedNative* aObject,
PRUint32 aWay)
{
typedef WrappedNative2WrapperMap::Link Link;
XPCWrappedNative* wn = static_cast<XPCWrappedNative *>(aObject);
XPCWrappedNativeScope* scope = wn->GetScope();
WrappedNative2WrapperMap* map = scope->GetWrapperMap();
Link* list;
{
XPCJSRuntime* rt = nsXPConnect::GetRuntime();
XPCAutoLock al(rt->GetMapLock());
list = map->FindLink(wn->GetFlatJSObject());
}
if(!list)
return NS_OK; // No wrappers to update.
AutoJSRequestWithNoCallContext req(aJSContext);
Link* cur = list;
if(cur->obj && !PerformOp(aJSContext, aWay, cur->obj))
return NS_ERROR_FAILURE;
for(cur = (Link *)PR_NEXT_LINK(list); cur != list;
cur = (Link *)PR_NEXT_LINK(cur))
{
if(!PerformOp(aJSContext, aWay, cur->obj))
return NS_ERROR_FAILURE;
}
return NS_OK;
}
/* void releaseJSContext (in JSContextPtr aJSContext, in PRBool noGC); */
NS_IMETHODIMP
nsXPConnect::ReleaseJSContext(JSContext * aJSContext, PRBool noGC)

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

@ -652,24 +652,6 @@ XPCNativeWrapperMap::~XPCNativeWrapperMap()
/***************************************************************************/
// implement WrappedNative2WrapperMap...
struct JSDHashTableOps
WrappedNative2WrapperMap::sOps = { nsnull };
// static
void
WrappedNative2WrapperMap::ClearLink(JSDHashTable* table,
JSDHashEntryHdr* entry)
{
Entry* e = static_cast<Entry*>(entry);
e->key = nsnull;
if(e->value)
{
PR_REMOVE_LINK(e->value);
delete e->value;
e->value = nsnull;
}
}
// static
WrappedNative2WrapperMap*
WrappedNative2WrapperMap::newMap(int size)
@ -683,13 +665,8 @@ WrappedNative2WrapperMap::newMap(int size)
WrappedNative2WrapperMap::WrappedNative2WrapperMap(int size)
{
if(!sOps.allocTable)
{
sOps = *JS_DHashGetStubOps();
sOps.clearEntry = WrappedNative2WrapperMap::ClearLink;
}
mTable = JS_NewDHashTable(&sOps, nsnull, sizeof(Entry), size);
mTable = JS_NewDHashTable(JS_DHashGetStubOps(), nsnull,
sizeof(Entry), size);
}
WrappedNative2WrapperMap::~WrappedNative2WrapperMap()
@ -698,70 +675,4 @@ WrappedNative2WrapperMap::~WrappedNative2WrapperMap()
JS_DHashTableDestroy(mTable);
}
JSObject*
WrappedNative2WrapperMap::Add(WrappedNative2WrapperMap* head,
JSObject* wrappedObject,
JSObject* wrapper)
{
NS_PRECONDITION(wrappedObject,"bad param");
Entry* entry = (Entry*)
JS_DHashTableOperate(mTable, wrappedObject, JS_DHASH_ADD);
if(!entry)
return nsnull;
NS_ASSERTION(!entry->key || this == head, "dangling pointer?");
entry->key = wrappedObject;
Link* l = new Link;
if(!l)
return nsnull;
PR_INIT_CLIST(l);
l->obj = wrapper;
if(this != head)
{
Link* headLink = head->FindLink(wrappedObject);
if(!headLink)
{
Entry* dummy = (Entry*)
JS_DHashTableOperate(head->mTable, wrappedObject, JS_DHASH_ADD);
dummy->key = wrappedObject;
headLink = dummy->value = new Link;
if(!headLink)
{
Remove(wrappedObject);
return nsnull;
}
PR_INIT_CLIST(headLink);
headLink->obj = nsnull;
}
PR_INSERT_BEFORE(l, headLink);
}
entry->value = l;
return wrapper;
}
PRBool
WrappedNative2WrapperMap::AddLink(JSObject* wrappedObject, Link* oldLink)
{
Entry* entry = (Entry*)
JS_DHashTableOperate(mTable, wrappedObject, JS_DHASH_ADD);
if(!entry)
return PR_FALSE;
NS_ASSERTION(!entry->key, "Eh? What's happening?");
entry->key = wrappedObject;
Link* newLink = entry->value = new Link;
if(!newLink)
{
Remove(wrappedObject);
return PR_FALSE;
}
PR_INSERT_LINK(newLink, oldLink);
PR_REMOVE_AND_INIT_LINK(oldLink);
newLink->obj = oldLink->obj;
return PR_TRUE;
}
/***************************************************************************/

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

@ -686,21 +686,12 @@ private:
class WrappedNative2WrapperMap
{
static struct JSDHashTableOps sOps;
static void ClearLink(JSDHashTable* table, JSDHashEntryHdr* entry);
public:
struct Link : public PRCList
{
JSObject *obj;
};
struct Entry : public JSDHashEntryHdr
{
// Note: key must be the flat JSObject for a wrapped native.
JSObject* key;
Link* value;
JSObject* value;
};
static WrappedNative2WrapperMap* newMap(int size);
@ -712,29 +703,26 @@ public:
JS_DHashTableOperate(mTable, wrapper, JS_DHASH_LOOKUP);
if(JS_DHASH_ENTRY_IS_FREE(entry))
return nsnull;
return entry->value->obj;
return entry->value;
}
// Note: If the entry already exists, then this will overwrite the
// existing entry, returning the old value.
JSObject* Add(WrappedNative2WrapperMap* head,
JSObject* wrappedObject,
JSObject* wrapper);
// Function to find a link.
Link* FindLink(JSObject* wrappedObject)
inline JSObject* Add(JSObject* wrapper, JSObject *obj)
{
NS_PRECONDITION(wrapper,"bad param");
Entry* entry = (Entry*)
JS_DHashTableOperate(mTable, wrappedObject, JS_DHASH_LOOKUP);
if(JS_DHASH_ENTRY_IS_BUSY(entry))
return entry->value;
return nsnull;
JS_DHashTableOperate(mTable, wrapper, JS_DHASH_ADD);
if(!entry)
return nsnull;
JSObject *old;
if(!entry->key)
entry->key = wrapper;
old = entry->value;
entry->value = obj;
return old;
}
// "Internal" function to add an empty link without doing unnecessary
// work.
PRBool AddLink(JSObject* wrappedObject, Link* oldLink);
inline void Remove(JSObject* wrapper)
{
NS_PRECONDITION(wrapper,"bad param");
@ -746,11 +734,9 @@ public:
{return JS_DHashTableEnumerate(mTable, f, arg);}
~WrappedNative2WrapperMap();
private:
WrappedNative2WrapperMap(); // no implementation
WrappedNative2WrapperMap(int size);
private:
JSDHashTable *mTable;
};

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

@ -91,7 +91,6 @@
#include "prlong.h"
#include "prmem.h"
#include "prenv.h"
#include "prclist.h"
#include "nsString.h"
#include "nsReadableUtils.h"
#include "nsXPIDLString.h"

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

@ -1158,10 +1158,6 @@ XPCWrappedNative::ReparentWrapperIfFound(XPCCallContext& ccx,
{
// Oh, so now we need to move the wrapper to a different scope.
// First notify any XOWs.
nsXPConnect* xpc = nsXPConnect::GetXPConnect();
xpc->UpdateXOWs(ccx, wrapper, nsIXPConnect::XPC_XOW_CLEARSCOPE);
AutoMarkingWrappedNativeProtoPtr oldProto(ccx);
AutoMarkingWrappedNativeProtoPtr newProto(ccx);
@ -1183,12 +1179,6 @@ XPCWrappedNative::ReparentWrapperIfFound(XPCCallContext& ccx,
}
}
if(!XPC_XOW_WrapperMoved(ccx, wrapper, aNewScope))
{
NS_RELEASE(wrapper);
return NS_ERROR_FAILURE;
}
Native2WrappedNativeMap* oldMap = aOldScope->GetWrappedNativeMap();
Native2WrappedNativeMap* newMap = aNewScope->GetWrappedNativeMap();

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

@ -45,7 +45,6 @@ include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
_TEST_FILES = test_bug390488.html \
test_bug393269.html \
test_wrappers.html \
$(NULL)

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

@ -1,46 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=393269
-->
<head>
<title>Test for Bug 393269</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=393269">Mozilla Bug 393269</a>
<iframe id="ifr"></iframe>
<pre id="test">
<script class="testbody" type="text/javascript">
(function () {
/** Test for Bug 393269 **/
var doc = $("ifr").contentDocument;
is("UTF-8", doc.characterSet, "control, getting a property");
doc.open();
try {
is("UTF-8", doc.characterSet,
"can get a property after 1 document.open")
} catch (e) {
fail("Shouldn't have thrown: " + e);
return;
} finally {
doc.close();
}
doc.open();
try {
is("UTF-8", doc.characterSet,
"can get a property after 2 document.opens")
} catch (e) {
fail("Shouldn't have thrown: " + e);
} finally {
doc.close();
}
})();
</script>
</pre>
</body>
</html>