Bug 1043106 - StorageEvent should have the storageArea of the correct window, r=smaug

This commit is contained in:
Andrea Marchesini 2014-08-13 14:56:25 +02:00
parent 6d11177ad7
commit cee6e5a10e
5 changed files with 85 additions and 4 deletions

View File

@ -2676,6 +2676,12 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
if (!aState) {
if (reUseInnerWindow) {
// The storage objects contain the URL of the window. We have to recreate
// them when the innerWindow is reused.
newInnerWindow->mLocalStorage = nullptr;
newInnerWindow->mSessionStorage = nullptr;
if (newInnerWindow->mDoc != aDocument) {
newInnerWindow->mDoc = aDocument;
@ -11428,11 +11434,15 @@ nsGlobalWindow::Observe(nsISupports* aSubject, const char* aTopic,
// Clone the storage event included in the observer notification. We want
// to dispatch clones rather than the original event.
ErrorResult error;
nsRefPtr<StorageEvent> newEvent =
CloneStorageEvent(fireMozStorageChanged ?
NS_LITERAL_STRING("MozStorageChanged") :
NS_LITERAL_STRING("storage"),
event);
event, error);
if (error.Failed()) {
return error.ErrorCode();
}
newEvent->SetTrusted(true);
@ -11528,7 +11538,8 @@ nsGlobalWindow::Observe(nsISupports* aSubject, const char* aTopic,
already_AddRefed<StorageEvent>
nsGlobalWindow::CloneStorageEvent(const nsAString& aType,
const nsRefPtr<StorageEvent>& aEvent)
const nsRefPtr<StorageEvent>& aEvent,
ErrorResult& aRv)
{
MOZ_ASSERT(IsInnerWindow());
@ -11540,7 +11551,26 @@ nsGlobalWindow::CloneStorageEvent(const nsAString& aType,
aEvent->GetOldValue(dict.mOldValue);
aEvent->GetNewValue(dict.mNewValue);
aEvent->GetUrl(dict.mUrl);
dict.mStorageArea = aEvent->GetStorageArea();
nsRefPtr<DOMStorage> storageArea = aEvent->GetStorageArea();
MOZ_ASSERT(storageArea);
nsRefPtr<DOMStorage> storage;
if (storageArea->GetType() == DOMStorage::LocalStorage) {
storage = GetLocalStorage(aRv);
} else {
MOZ_ASSERT(storageArea->GetType() == DOMStorage::SessionStorage);
storage = GetSessionStorage(aRv);
}
if (aRv.Failed() || !storage) {
return nullptr;
}
MOZ_ASSERT(storage);
MOZ_ASSERT(storage->IsForkOf(storageArea));
dict.mStorageArea = storage;
nsRefPtr<StorageEvent> event = StorageEvent::Constructor(this, aType, dict);
return event.forget();

View File

@ -1386,7 +1386,8 @@ protected:
// Inner windows only.
already_AddRefed<mozilla::dom::StorageEvent>
CloneStorageEvent(const nsAString& aType,
const nsRefPtr<mozilla::dom::StorageEvent>& aEvent);
const nsRefPtr<mozilla::dom::StorageEvent>& aEvent,
mozilla::ErrorResult& aRv);
// Outer windows only.
nsDOMWindowList* GetWindowList();

View File

@ -24,6 +24,7 @@ skip-if = buildapp == 'mulet'
[test_bug989665.html]
[test_bug999456.html]
[test_bug1022229.html]
[test_bug1043106.html]
[test_clearTimeoutIntervalNoArg.html]
[test_consoleEmptyStack.html]
[test_constructor-assignment.html]

View File

@ -0,0 +1,43 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1043106
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1043106</title>
<script type="application/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=1043106">Mozilla Bug 1043106</a>
<iframe id="iframe"></iframe>
<script type="application/javascript">
var storage;
window.addEventListener("storage", function (event) {
ok(event.storageArea, storage, "The storageArea is correct");
runTests();
}, false);
var tests = [ { key: 'localStorage', storage: localStorage },
{ key: 'sessionStorage', storage: sessionStorage } ];
function runTests() {
if (!tests.length) {
SimpleTest.finish();
return;
}
var t = tests.shift();
storage = t.storage;
var ifr = document.getElementById("iframe");
ifr.src = "data:text/html,<script>" + t.key + ".setItem(\"a\",\"b\");</" + "script>";
}
SimpleTest.waitForExplicitFinish();
runTests();
</script>
</body>
</html>

View File

@ -126,6 +126,12 @@ public:
bool IsPrivate() const { return mIsPrivate; }
bool IsSessionOnly() const { return mIsSessionOnly; }
bool IsForkOf(const DOMStorage* aOther) const
{
MOZ_ASSERT(aOther);
return mCache == aOther->mCache;
}
private:
~DOMStorage();