Files
Simon Farre 90fdec60cd Bug 2034329 - Anchor DOMStringList to a specified realm. r=smaug,dom-core
DOMStringList::GetParentObject() returned nullptr, so FindAssociatedGlobal in
BindingUtils.h:1845 fell back to JS::CurrentGlobalOrNull(cx), stamping the JS
wrapper into the first caller's compartment. If an extension content script got
there first, subsequent page access required a content→extension CCW, which
security policy blocks, breaking sites like Gmail.

Fix by passing the Document (or inner window) as the DOMStringList parent, so
FindAssociatedGlobal always anchors the wrapper to the content realm — the same
mechanism that makes things like nsContentList immune to this problem.

Differential Revision: https://phabricator.services.mozilla.com/D296198
2026-04-27 08:23:58 +00:00

87 lines
2.3 KiB
C++

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_DOMStringList_h
#define mozilla_dom_DOMStringList_h
#include "nsCOMPtr.h"
#include "nsISupports.h"
#include "nsString.h"
#include "nsTArray.h"
#include "nsWrapperCache.h"
namespace mozilla::dom {
class DOMStringList : public nsISupports, public nsWrapperCache {
protected:
virtual ~DOMStringList();
public:
explicit DOMStringList(nsISupports* aParent = nullptr) : mParent(aParent) {}
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(DOMStringList)
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
nsISupports* GetParentObject() { return mParent; }
void IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aResult) {
EnsureFresh();
if (aIndex < mNames.Length()) {
aFound = true;
aResult = mNames[aIndex];
} else {
aFound = false;
}
}
void Item(uint32_t aIndex, nsAString& aResult) {
EnsureFresh();
if (aIndex < mNames.Length()) {
aResult = mNames[aIndex];
} else {
aResult.SetIsVoid(true);
}
}
uint32_t Length() {
EnsureFresh();
return mNames.Length();
}
bool Contains(const nsAString& aString) {
EnsureFresh();
return mNames.Contains(aString);
}
bool Add(const nsAString& aName) {
// XXXbz(Bug 1631374) mNames should really be a fallible array; otherwise
// this return value is meaningless. return mNames.AppendElement(aName) !=
// nullptr;
mNames.AppendElement(aName);
return true;
}
void Clear() { mNames.Clear(); }
nsTArray<nsString>& StringArray() { return mNames; }
void CopyList(nsTArray<nsString>& aNames) { aNames = mNames.Clone(); }
protected:
// A method that subclasses can override to modify mNames as needed
// before we index into it or return its length or whatnot.
virtual void EnsureFresh() {}
// XXXbz we really want this to be a fallible array, but we end up passing it
// to consumers who declare themselves as taking and nsTArray. :(
nsTArray<nsString> mNames;
nsCOMPtr<nsISupports> mParent;
};
} // namespace mozilla::dom
#endif /* mozilla_dom_DOMStringList_h */