diff --git a/dom/html/nsHTMLDocument.cpp b/dom/html/nsHTMLDocument.cpp
index 973b9cdd8dd0..e981df36ae75 100644
--- a/dom/html/nsHTMLDocument.cpp
+++ b/dom/html/nsHTMLDocument.cpp
@@ -1225,6 +1225,32 @@ nsHTMLDocument::GetCookie(nsAString& aCookie)
return rv.ErrorCode();
}
+already_AddRefed
+nsHTMLDocument::CreateDummyChannelForCookies(nsIURI* aCodebaseURI)
+{
+ // The cookie service reads the privacy status of the channel we pass to it in
+ // order to determine which cookie database to query. In some cases we don't
+ // have a proper channel to hand it to the cookie service though. This
+ // function creates a dummy channel that is not used to load anything, for the
+ // sole purpose of handing it to the cookie service. DO NOT USE THIS CHANNEL
+ // FOR ANY OTHER PURPOSE.
+ MOZ_ASSERT(!mChannel);
+
+ nsCOMPtr channel;
+ NS_NewChannel(getter_AddRefs(channel), aCodebaseURI, this,
+ nsILoadInfo::SEC_NORMAL,
+ nsIContentPolicy::TYPE_INVALID);
+ nsCOMPtr pbChannel =
+ do_QueryInterface(channel);
+ nsCOMPtr docShell(mDocumentContainer);
+ nsCOMPtr loadContext = do_QueryInterface(docShell);
+ if (!pbChannel || !loadContext) {
+ return nullptr;
+ }
+ pbChannel->SetPrivate(loadContext->UsePrivateBrowsing());
+ return channel.forget();
+}
+
void
nsHTMLDocument::GetCookie(nsAString& aCookie, ErrorResult& rv)
{
@@ -1257,8 +1283,16 @@ nsHTMLDocument::GetCookie(nsAString& aCookie, ErrorResult& rv)
return;
}
+ nsCOMPtr channel(mChannel);
+ if (!channel) {
+ channel = CreateDummyChannelForCookies(codebaseURI);
+ if (!channel) {
+ return;
+ }
+ }
+
nsXPIDLCString cookie;
- service->GetCookieString(codebaseURI, mChannel, getter_Copies(cookie));
+ service->GetCookieString(codebaseURI, channel, getter_Copies(cookie));
// CopyUTF8toUTF16 doesn't handle error
// because it assumes that the input is valid.
nsContentUtils::ConvertStringFromEncoding(NS_LITERAL_CSTRING("UTF-8"),
@@ -1302,8 +1336,16 @@ nsHTMLDocument::SetCookie(const nsAString& aCookie, ErrorResult& rv)
return;
}
+ nsCOMPtr channel(mChannel);
+ if (!channel) {
+ channel = CreateDummyChannelForCookies(codebaseURI);
+ if (!channel) {
+ return;
+ }
+ }
+
NS_ConvertUTF16toUTF8 cookie(aCookie);
- service->SetCookieString(codebaseURI, nullptr, cookie.get(), mChannel);
+ service->SetCookieString(codebaseURI, nullptr, cookie.get(), channel);
}
}
diff --git a/dom/html/nsHTMLDocument.h b/dom/html/nsHTMLDocument.h
index 0812dc41e703..170563a699bd 100644
--- a/dom/html/nsHTMLDocument.h
+++ b/dom/html/nsHTMLDocument.h
@@ -275,6 +275,9 @@ protected:
nsresult CreateAndAddWyciwygChannel(void);
nsresult RemoveWyciwygChannel(void);
+ // This should *ONLY* be used in GetCookie/SetCookie.
+ already_AddRefed CreateDummyChannelForCookies(nsIURI* aCodebaseURI);
+
/**
* Like IsEditingOn(), but will flush as needed first.
*/