mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:18:48 +00:00
CORS: A "data:" URL = the same-origin
This commit is contained in:
@@ -796,7 +796,7 @@ EventSource::InitChannelAndRequestEventSource()
|
||||
|
||||
nsRefPtr<nsCORSListenerProxy> listener =
|
||||
new nsCORSListenerProxy(this, mPrincipal, mWithCredentials);
|
||||
rv = listener->Init(mHttpChannel);
|
||||
rv = listener->Init(mHttpChannel, DataURIHandling::Allow);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Start reading from the channel
|
||||
|
||||
@@ -504,7 +504,7 @@ ImportLoader::Open()
|
||||
nsRefPtr<nsCORSListenerProxy> corsListener =
|
||||
new nsCORSListenerProxy(this, principal,
|
||||
/* aWithCredentials */ false);
|
||||
rv = corsListener->Init(channel, true);
|
||||
rv = corsListener->Init(channel, DataURIHandling::Allow);
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
|
||||
rv = channel->AsyncOpen(corsListener, nullptr);
|
||||
|
||||
@@ -1201,7 +1201,7 @@ Navigator::SendBeacon(const nsAString& aUrl,
|
||||
principal,
|
||||
true);
|
||||
|
||||
rv = cors->Init(channel, true);
|
||||
rv = cors->Init(channel, DataURIHandling::Allow);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
// Start a preflight if cross-origin and content type is not whitelisted
|
||||
|
||||
@@ -367,7 +367,7 @@ nsScriptLoader::StartLoad(nsScriptLoadRequest *aRequest, const nsAString &aType,
|
||||
nsRefPtr<nsCORSListenerProxy> corsListener =
|
||||
new nsCORSListenerProxy(listener, mDocument->NodePrincipal(),
|
||||
withCredentials);
|
||||
rv = corsListener->Init(channel);
|
||||
rv = corsListener->Init(channel, DataURIHandling::Allow);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
listener = corsListener;
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ nsSyncLoader::LoadDocument(nsIChannel* aChannel,
|
||||
if (aLoaderPrincipal) {
|
||||
nsRefPtr<nsCORSListenerProxy> corsListener =
|
||||
new nsCORSListenerProxy(listener, aLoaderPrincipal, false);
|
||||
rv = corsListener->Init(mChannel);
|
||||
rv = corsListener->Init(mChannel, DataURIHandling::Disallow);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
listener = corsListener;
|
||||
}
|
||||
|
||||
@@ -2932,7 +2932,7 @@ nsXMLHttpRequest::Send(nsIVariant* aVariant, const Nullable<RequestBody>& aBody)
|
||||
// a same-origin request right now, since it could be redirected.
|
||||
nsRefPtr<nsCORSListenerProxy> corsListener =
|
||||
new nsCORSListenerProxy(listener, mPrincipal, withCredentials);
|
||||
rv = corsListener->Init(mChannel, true);
|
||||
rv = corsListener->Init(mChannel, DataURIHandling::Allow);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
listener = corsListener;
|
||||
}
|
||||
|
||||
@@ -778,3 +778,4 @@ skip-if = buildapp == 'mulet' || buildapp == 'b2g'
|
||||
[test_bug1118689.html]
|
||||
skip-if = buildapp == 'mulet' || buildapp == 'b2g'
|
||||
[test_getAttribute_after_createAttribute.html]
|
||||
[test_script_loader_crossorigin_data_url.html]
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>Test for handling of 'crossorigin' attribute on script with data: URL</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
// We're going to mess with window.onerror.
|
||||
setup({ allow_uncaught_exception: true });
|
||||
</script>
|
||||
<!-- First check that data: scripts with @crossorigin run at all -->
|
||||
<script>
|
||||
var ran = false;
|
||||
</script>
|
||||
<script crossorigin src="data:application/javascript,ran = true"></script>
|
||||
<script>
|
||||
test(function() {
|
||||
assert_true(ran);
|
||||
}, "script@crossorigin with data: src should have run");
|
||||
</script>
|
||||
<!-- Then check that their syntax errors are not sanitized -->
|
||||
<script>
|
||||
var errorFired = false;
|
||||
ran = false;
|
||||
window.onerror = function(message, uri, line) {
|
||||
errorFired = true;
|
||||
test(function() {
|
||||
assert_equals(line, 3);
|
||||
}, "Should have a useful line number for exception in script@crossorigin with data: src");
|
||||
}
|
||||
</script>
|
||||
<script crossorigin src="data:application/javascript,var%20a;%0aran=true%0anoSuchFunctionHere()"></script>
|
||||
<script>
|
||||
test(function() {
|
||||
assert_true(ran, "Script with error should have run");
|
||||
assert_true(errorFired, "Script with error should have fired onerror");
|
||||
}, "Should run and correctly fire onerror");
|
||||
</script>
|
||||
@@ -472,7 +472,7 @@ FetchDriver::HttpFetch(bool aCORSFlag, bool aCORSPreflightFlag, bool aAuthentica
|
||||
// directly.
|
||||
nsRefPtr<nsCORSListenerProxy> corsListener =
|
||||
new nsCORSListenerProxy(this, mPrincipal, useCredentials);
|
||||
rv = corsListener->Init(chan, true /* allow data uri */);
|
||||
rv = corsListener->Init(chan, DataURIHandling::Allow);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return FailWithNetworkError();
|
||||
}
|
||||
|
||||
@@ -1254,7 +1254,7 @@ nsresult HTMLMediaElement::LoadResource()
|
||||
new nsCORSListenerProxy(loadListener,
|
||||
NodePrincipal(),
|
||||
GetCORSMode() == CORS_USE_CREDENTIALS);
|
||||
rv = corsListener->Init(channel);
|
||||
rv = corsListener->Init(channel, DataURIHandling::Allow);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
listener = corsListener;
|
||||
} else {
|
||||
|
||||
@@ -619,7 +619,7 @@ nsresult ChannelMediaResource::OpenChannel(nsIStreamListener** aStreamListener)
|
||||
element->NodePrincipal(),
|
||||
false);
|
||||
NS_ENSURE_TRUE(crossSiteListener, NS_ERROR_OUT_OF_MEMORY);
|
||||
rv = crossSiteListener->Init(mChannel);
|
||||
rv = crossSiteListener->Init(mChannel, DataURIHandling::Allow);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
listener = crossSiteListener;
|
||||
} else {
|
||||
|
||||
@@ -467,7 +467,7 @@ nsCORSListenerProxy::~nsCORSListenerProxy()
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsCORSListenerProxy::Init(nsIChannel* aChannel, bool aAllowDataURI)
|
||||
nsCORSListenerProxy::Init(nsIChannel* aChannel, DataURIHandling aAllowDataURI)
|
||||
{
|
||||
aChannel->GetNotificationCallbacks(getter_AddRefs(mOuterNotificationCallbacks));
|
||||
aChannel->SetNotificationCallbacks(this);
|
||||
@@ -780,7 +780,7 @@ nsCORSListenerProxy::OnRedirectVerifyCallback(nsresult result)
|
||||
NS_ASSERTION(mNewRedirectChannel, "mNewRedirectChannel not set in callback");
|
||||
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
nsresult rv = UpdateChannel(mNewRedirectChannel);
|
||||
nsresult rv = UpdateChannel(mNewRedirectChannel, DataURIHandling::Disallow);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("nsCORSListenerProxy::OnRedirectVerifyCallback: "
|
||||
"UpdateChannel() returned failure");
|
||||
@@ -800,7 +800,8 @@ nsCORSListenerProxy::OnRedirectVerifyCallback(nsresult result)
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsCORSListenerProxy::UpdateChannel(nsIChannel* aChannel, bool aAllowDataURI)
|
||||
nsCORSListenerProxy::UpdateChannel(nsIChannel* aChannel,
|
||||
DataURIHandling aAllowDataURI)
|
||||
{
|
||||
nsCOMPtr<nsIURI> uri, originalURI;
|
||||
nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
|
||||
@@ -809,7 +810,7 @@ nsCORSListenerProxy::UpdateChannel(nsIChannel* aChannel, bool aAllowDataURI)
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// exempt data URIs from the same origin check.
|
||||
if (aAllowDataURI && originalURI == uri) {
|
||||
if (aAllowDataURI == DataURIHandling::Allow && originalURI == uri) {
|
||||
bool dataScheme = false;
|
||||
rv = uri->SchemeIs("data", &dataScheme);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@@ -1208,7 +1209,7 @@ NS_StartCORSPreflight(nsIChannel* aRequestChannel,
|
||||
new nsCORSListenerProxy(preflightListener, aPrincipal,
|
||||
aWithCredentials, method,
|
||||
aUnsafeHeaders);
|
||||
rv = corsListener->Init(preflightChannel);
|
||||
rv = corsListener->Init(preflightChannel, DataURIHandling::Disallow);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
preflightListener = corsListener;
|
||||
|
||||
|
||||
@@ -29,6 +29,12 @@ NS_StartCORSPreflight(nsIChannel* aRequestChannel,
|
||||
nsTArray<nsCString>& aACUnsafeHeaders,
|
||||
nsIChannel** aPreflightChannel);
|
||||
|
||||
enum class DataURIHandling
|
||||
{
|
||||
Allow,
|
||||
Disallow
|
||||
};
|
||||
|
||||
class nsCORSListenerProxy final : public nsIStreamListener,
|
||||
public nsIInterfaceRequestor,
|
||||
public nsIChannelEventSink,
|
||||
@@ -56,12 +62,12 @@ public:
|
||||
|
||||
static void Shutdown();
|
||||
|
||||
nsresult Init(nsIChannel* aChannel, bool aAllowDataURI = false);
|
||||
nsresult Init(nsIChannel* aChannel, DataURIHandling aAllowDataURI);
|
||||
|
||||
private:
|
||||
~nsCORSListenerProxy();
|
||||
|
||||
nsresult UpdateChannel(nsIChannel* aChannel, bool aAllowDataURI = false);
|
||||
nsresult UpdateChannel(nsIChannel* aChannel, DataURIHandling aAllowDataURI);
|
||||
nsresult CheckRequestApproved(nsIRequest* aRequest);
|
||||
|
||||
nsCOMPtr<nsIStreamListener> mOuterListener;
|
||||
|
||||
@@ -505,7 +505,7 @@ txCompileObserver::startLoad(nsIURI* aUri, txStylesheetCompiler* aCompiler,
|
||||
// Always install in case of redirects
|
||||
nsRefPtr<nsCORSListenerProxy> listener =
|
||||
new nsCORSListenerProxy(sink, aReferrerPrincipal, false);
|
||||
rv = listener->Init(channel);
|
||||
rv = listener->Init(channel, DataURIHandling::Disallow);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return channel->AsyncOpen(listener, parser);
|
||||
|
||||
@@ -1525,7 +1525,7 @@ bool imgLoader::ValidateRequestWithNewChannel(imgRequest *request,
|
||||
bool withCredentials = aCORSMode == imgIRequest::CORS_USE_CREDENTIALS;
|
||||
nsRefPtr<nsCORSListenerProxy> corsproxy =
|
||||
new nsCORSListenerProxy(listener, aLoadingPrincipal, withCredentials);
|
||||
rv = corsproxy->Init(newChannel);
|
||||
rv = corsproxy->Init(newChannel, DataURIHandling::Allow);
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
@@ -2071,7 +2071,7 @@ nsresult imgLoader::LoadImage(nsIURI *aURI,
|
||||
|
||||
nsRefPtr<nsCORSListenerProxy> corsproxy =
|
||||
new nsCORSListenerProxy(pl, aLoadingPrincipal, withCredentials);
|
||||
rv = corsproxy->Init(newChannel);
|
||||
rv = corsproxy->Init(newChannel, DataURIHandling::Allow);
|
||||
if (NS_FAILED(rv)) {
|
||||
PR_LOG(GetImgLog(), PR_LOG_DEBUG,
|
||||
("[this=%p] imgLoader::LoadImage -- nsCORSListenerProxy "
|
||||
|
||||
@@ -95,3 +95,4 @@ skip-if = toolkit == "gonk" #Bug 997034 - canvas.toDataURL() often causes lost c
|
||||
[test_image_buffer_limit.html]
|
||||
#run-if = toolkit == "gonk" #Image buffer limit is only set for Firefox OS currently.
|
||||
disabled = bug 1060869
|
||||
[test_image_crossorigin_data_url.html]
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>Test for handling of 'crossorigin' attribute on CSS link with data: URL</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<div id="log"></div>
|
||||
<div id="someuniqueidhere"></div>
|
||||
<img id="testimg" crossorigin src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mP4z8AAAAMBAQD3A0FDAAAAAElFTkSuQmCC">
|
||||
<script>
|
||||
var t = async_test("img@crossorigin with data: src");
|
||||
window.addEventListener("load", t.step_func_done(function() {
|
||||
var img = document.getElementById("testimg");
|
||||
assert_equals(img.naturalWidth, 1, "Should have 1px width");
|
||||
assert_equals(img.naturalHeight, 1, "Should have 1px height");
|
||||
var c = document.createElement("canvas");
|
||||
c.width = c.height = 1;
|
||||
var ctx = c.getContext("2d");
|
||||
ctx.drawImage(img, 0, 0);
|
||||
var data = ctx.getImageData(0, 0, 1, 1);
|
||||
assert_equals(data.width, 1, "Should have 1px data width");
|
||||
assert_equals(data.height, 1, "Should have 1px data height");
|
||||
assert_equals(data.data[0], 255, "Should have lots of red");
|
||||
assert_equals(data.data[1], 0, "Should have no green");
|
||||
assert_equals(data.data[2], 0, "Should have no blue");
|
||||
assert_equals(data.data[3], 255, "Should have no translucency");
|
||||
}));
|
||||
</script>
|
||||
@@ -462,7 +462,9 @@ FontFaceSet::StartLoad(gfxUserFontEntry* aUserFontEntry,
|
||||
} else {
|
||||
nsRefPtr<nsCORSListenerProxy> listener =
|
||||
new nsCORSListenerProxy(streamLoader, aUserFontEntry->GetPrincipal(), false);
|
||||
rv = listener->Init(channel);
|
||||
// Doesn't matter what data: URI handling we use here, since we
|
||||
// don't even use a CORS listener proxy for the data: case.
|
||||
rv = listener->Init(channel, DataURIHandling::Disallow);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = channel->AsyncOpen(listener, nullptr);
|
||||
}
|
||||
|
||||
@@ -1670,7 +1670,7 @@ Loader::LoadSheet(SheetLoadData* aLoadData, StyleSheetState aSheetState)
|
||||
nsRefPtr<nsCORSListenerProxy> corsListener =
|
||||
new nsCORSListenerProxy(streamLoader, aLoadData->mLoaderPrincipal,
|
||||
withCredentials);
|
||||
rv = corsListener->Init(channel);
|
||||
rv = corsListener->Init(channel, DataURIHandling::Allow);
|
||||
if (NS_FAILED(rv)) {
|
||||
#ifdef DEBUG
|
||||
mSyncCallback = false;
|
||||
|
||||
@@ -261,3 +261,4 @@ support-files = bug732209-css.sjs
|
||||
[test_animations_async_tests.html]
|
||||
support-files = ../../reftests/fonts/Ahem.ttf
|
||||
[test_setPropertyWithNull.html]
|
||||
[test_css_loader_crossorigin_data_url.html]
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>Test for handling of 'crossorigin' attribute on CSS link with data: URL</title>
|
||||
<link id="testlink" crossorigin rel="stylesheet" href="data:text/css,%23someuniqueidhere{display:none}">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<div id="log"></div>
|
||||
<div id="someuniqueidhere"></div>
|
||||
<script>
|
||||
var t = async_test("link@crossorigin with data: href");
|
||||
window.addEventListener("load", t.step_func_done(function() {
|
||||
assert_equals(getComputedStyle(document.getElementById("someuniqueidhere")).display,
|
||||
"none", "sheet should be applied");
|
||||
assert_equals(document.getElementById("testlink").sheet.cssRules[0].style.display,
|
||||
"none", "should be able to read data from the sheet");
|
||||
}));
|
||||
</script>
|
||||
Reference in New Issue
Block a user