Bug 1271249 - Blob URL should not be shared across non-private and private windows, r=ehsan

This commit is contained in:
Andrea Marchesini 2016-05-17 20:34:39 +02:00
Родитель db0f2224b6
Коммит 9d6c9f459a
7 изменённых файлов: 95 добавлений и 12 удалений

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

@ -13,6 +13,7 @@ support-files =
head.js
popup.html
title.sjs
empty_file.html
[browser_privatebrowsing_DownloadLastDirWithCPS.js]
[browser_privatebrowsing_about.js]
@ -45,3 +46,4 @@ tags = trackingprotection
[browser_privatebrowsing_zoom.js]
[browser_privatebrowsing_zoomrestore.js]
[browser_privatebrowsing_newtab_from_popup.js]
[browser_privatebrowsing_blobUrl.js]

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

@ -0,0 +1,47 @@
"use strict";
// Here we want to test that blob URLs are not available between private and
// non-private browsing.
const BASE_URI = "http://mochi.test:8888/browser/browser/components/"
+ "privatebrowsing/test/browser/empty_file.html";
add_task(function* test() {
info("Creating a normal window...");
let win = yield BrowserTestUtils.openNewBrowserWindow();
let tab = win.gBrowser.selectedBrowser;
tab.loadURI(BASE_URI);
yield BrowserTestUtils.browserLoaded(tab);
let blobURL;
info("Creating a blob URL...");
yield ContentTask.spawn(tab, null, function() {
return Promise.resolve(content.window.URL.createObjectURL(new content.window.Blob([123])));
}).then(newURL => { blobURL = newURL });
info("Blob URL: " + blobURL);
info("Creating a private window...");
let privateWin = yield BrowserTestUtils.openNewBrowserWindow({ private: true });
let privateTab = privateWin.gBrowser.selectedBrowser;
privateTab.loadURI(BASE_URI);
yield BrowserTestUtils.browserLoaded(privateTab);
yield ContentTask.spawn(privateTab, blobURL, function(url) {
return new Promise(resolve => {
var xhr = new content.window.XMLHttpRequest();
try {
xhr.open("GET", url);
resolve("OpenSucceeded");
} catch(e) {
resolve("OpenThrew");
}
});
}).then(status => {
is(status, "OpenThrew", "Using a blob URI from one user context id in another should not work");
});
yield BrowserTestUtils.closeWindow(win);
yield BrowserTestUtils.closeWindow(privateWin);
});

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

@ -0,0 +1 @@
<html><body></body></html>

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

@ -129,16 +129,28 @@ void
URL::CreateObjectURL(const GlobalObject& aGlobal, MediaSource& aSource,
const objectURLOptions& aOptions,
nsAString& aResult,
ErrorResult& aError)
ErrorResult& aRv)
{
nsCOMPtr<nsIPrincipal> principal = nsContentUtils::ObjectPrincipal(aGlobal.Get());
nsCOMPtr<nsIPrincipal> principal =
nsContentUtils::ObjectPrincipal(aGlobal.Get());
if (NS_WARN_IF(!principal)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
nsCOMPtr<nsPIDOMWindowInner> window =
do_QueryInterface(aGlobal.GetAsSupports());
if (NS_WARN_IF(!window)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
nsCString url;
nsresult rv = nsHostObjectProtocolHandler::
aRv = nsHostObjectProtocolHandler::
AddDataEntry(NS_LITERAL_CSTRING(MEDIASOURCEURI_SCHEME),
&aSource, principal, url);
if (NS_FAILED(rv)) {
aError.Throw(rv);
&aSource, principal,
nsGlobalWindow::Cast(window)->IsPrivateBrowsing(), url);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
@ -166,11 +178,18 @@ URL::CreateObjectURLInternal(const GlobalObject& aGlobal, nsISupports* aObject,
nsCOMPtr<nsIPrincipal> principal = nsContentUtils::ObjectPrincipal(aGlobal.Get());
nsCOMPtr<nsPIDOMWindowInner> window =
do_QueryInterface(aGlobal.GetAsSupports());
if (NS_WARN_IF(!window)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
nsAutoCString url;
nsresult rv = nsHostObjectProtocolHandler::AddDataEntry(aScheme, aObject,
principal, url);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
aRv = nsHostObjectProtocolHandler::
AddDataEntry(aScheme, aObject, principal,
nsGlobalWindow::Cast(window)->IsPrivateBrowsing(), url);
if (NS_WARN_IF(aRv.Failed())) {
return;
}

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

@ -32,6 +32,7 @@ struct DataInfo
// mObject is expected to be an nsIDOMBlob, DOMMediaStream, or MediaSource
nsCOMPtr<nsISupports> mObject;
nsCOMPtr<nsIPrincipal> mPrincipal;
bool mPrivateBrowsing;
nsCString mStack;
};
@ -321,6 +322,7 @@ nsresult
nsHostObjectProtocolHandler::AddDataEntry(const nsACString& aScheme,
nsISupports* aObject,
nsIPrincipal* aPrincipal,
bool aPrivateBrowsing,
nsACString& aUri)
{
Init();
@ -336,6 +338,7 @@ nsHostObjectProtocolHandler::AddDataEntry(const nsACString& aScheme,
info->mObject = aObject;
info->mPrincipal = aPrincipal;
info->mPrivateBrowsing = aPrivateBrowsing;
mozilla::BlobURLsReporter::GetJSStackForBlob(info);
gDataTable->Put(aUri, info);
@ -537,6 +540,17 @@ nsHostObjectProtocolHandler::NewChannel2(nsIURI* uri,
return NS_ERROR_DOM_BAD_URI;
}
bool usePrivateBrowsing = false;
ErrorResult rv;
rv = aLoadInfo->GetUsePrivateBrowsing(&usePrivateBrowsing);
if (NS_WARN_IF(rv.Failed())) {
return rv.StealNSResult();
}
if (info->mPrivateBrowsing != usePrivateBrowsing) {
return NS_ERROR_DOM_BAD_URI;
}
nsCOMPtr<BlobImpl> blob = do_QueryInterface(info->mObject);
if (!blob) {
return NS_ERROR_DOM_BAD_URI;
@ -551,7 +565,6 @@ nsHostObjectProtocolHandler::NewChannel2(nsIURI* uri,
}
#endif
ErrorResult rv;
nsCOMPtr<nsIInputStream> stream;
blob->GetInternalStream(getter_AddRefs(stream), rv);
if (NS_WARN_IF(rv.Failed())) {

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

@ -54,6 +54,7 @@ public:
static nsresult AddDataEntry(const nsACString& aScheme,
nsISupports* aObject,
nsIPrincipal* aPrincipal,
bool aIsPrivateBrowsing,
nsACString& aUri);
static void RemoveDataEntry(const nsACString& aUri);
static nsIPrincipal* GetDataEntryPrincipal(const nsACString& aUri);

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

@ -129,7 +129,7 @@ public:
nsAutoCString url;
nsresult rv = nsHostObjectProtocolHandler::AddDataEntry(
NS_LITERAL_CSTRING(BLOBURI_SCHEME),
mBlobImpl, principal, url);
mBlobImpl, principal, mWorkerPrivate->IsInPrivateBrowsing(), url);
if (NS_FAILED(rv)) {
NS_WARNING("Failed to add data entry for the blob!");