Backed out 5 changesets (bug 1427726) for failing linux asan at modules/libjar/test/unit/test_bug407303.js on a CLOSED TREE

Backed out changeset ee9abd6f1ba5 (bug 1427726)
Backed out changeset b1b76f9dff73 (bug 1427726)
Backed out changeset f41cf7811770 (bug 1427726)
Backed out changeset cb35e7b10235 (bug 1427726)
Backed out changeset 753ece6c9f1b (bug 1427726)

--HG--
rename : modules/libjar/test/mochitest/bug1173171.zip => modules/libjar/test/mochitest/bug403331.zip
rename : modules/libjar/test/mochitest/bug1173171.zip^headers^ => modules/libjar/test/mochitest/bug403331.zip^headers^
This commit is contained in:
Andreea Pavel 2018-04-11 12:46:20 +03:00
parent f4081d2372
commit f9b34d3781
29 changed files with 546 additions and 45 deletions

View File

@ -97,6 +97,10 @@ add_task(async function startup() {
min: 20,
max: 55,
},
// This seems to get called frequently only on infra.
"network.jar.block-remote-files": {
max: 500,
},
};
let startupRecorder = Cc["@mozilla.org/test/startuprecorder;1"].getService().wrappedJSObject;
@ -157,6 +161,8 @@ add_task(async function open_10_tabs() {
min: 5,
max: 20,
},
// This seems to get called frequently only on infra.
"network.jar.block-remote-files": { },
};
Services.prefs.resetStats();

View File

@ -1609,6 +1609,24 @@ nsDocShell::GetParentCharset(const Encoding*& aCharset,
NS_IF_ADDREF(*aPrincipal = mParentCharsetPrincipal);
}
NS_IMETHODIMP
nsDocShell::GetChannelIsUnsafe(bool* aUnsafe)
{
*aUnsafe = false;
nsIChannel* channel = GetCurrentDocChannel();
if (!channel) {
return NS_OK;
}
nsCOMPtr<nsIJARChannel> jarChannel = do_QueryInterface(channel);
if (!jarChannel) {
return NS_OK;
}
return jarChannel->GetIsUnsafe(aUnsafe);
}
NS_IMETHODIMP
nsDocShell::GetHasMixedActiveContentLoaded(bool* aHasMixedActiveContentLoaded)
{
@ -1667,6 +1685,12 @@ nsDocShell::GetAllowPlugins(bool* aAllowPlugins)
NS_ENSURE_ARG_POINTER(aAllowPlugins);
*aAllowPlugins = mAllowPlugins;
if (!mAllowPlugins) {
return NS_OK;
}
bool unsafe;
*aAllowPlugins = NS_SUCCEEDED(GetChannelIsUnsafe(&unsafe)) && !unsafe;
return NS_OK;
}
@ -1880,6 +1904,12 @@ nsDocShell::GetAllowMetaRedirects(bool* aReturn)
NS_ENSURE_ARG_POINTER(aReturn);
*aReturn = mAllowMetaRedirects;
if (!mAllowMetaRedirects) {
return NS_OK;
}
bool unsafe;
*aReturn = NS_SUCCEEDED(GetChannelIsUnsafe(&unsafe)) && !unsafe;
return NS_OK;
}
@ -9551,6 +9581,34 @@ nsDocShell::InternalLoad(nsIURI* aURI,
}
}
// Don't allow loads that would inherit our security context
// if this document came from an unsafe channel.
{
bool willInherit;
// This condition needs to match the one in
// nsContentUtils::ChannelShouldInheritPrincipal.
// Except we reverse the rv check to be safe in case
// nsContentUtils::URIInheritsSecurityContext fails here and
// succeeds there.
rv = nsContentUtils::URIInheritsSecurityContext(aURI, &willInherit);
if (NS_FAILED(rv) || willInherit || NS_IsAboutBlank(aURI)) {
nsCOMPtr<nsIDocShellTreeItem> treeItem = this;
do {
nsCOMPtr<nsIDocShell> itemDocShell = do_QueryInterface(treeItem);
bool isUnsafe;
if (itemDocShell &&
NS_SUCCEEDED(itemDocShell->GetChannelIsUnsafe(&isUnsafe)) &&
isUnsafe) {
return NS_ERROR_DOM_SECURITY_ERR;
}
nsCOMPtr<nsIDocShellTreeItem> parent;
treeItem->GetSameTypeParent(getter_AddRefs(parent));
parent.swap(treeItem);
} while (treeItem);
}
}
nsIDocument* doc = mContentViewer ? mContentViewer->GetDocument()
: nullptr;

View File

@ -582,6 +582,13 @@ interface nsIDocShell : nsIDocShellTreeItem
*/
readonly attribute boolean isInUnload;
/**
* Find out if the currently loaded document came from a suspicious channel
* (such as a JAR channel where the server-returned content type isn't a
* known JAR type).
*/
readonly attribute boolean channelIsUnsafe;
/**
* This attribute determines whether Mixed Active Content is loaded on the
* document. When it is true, mixed active content was not blocked and has

View File

@ -1,6 +1,8 @@
[DEFAULT]
support-files =
bug123696-subframe.html
bug369814.jar
bug369814.zip
bug404548-subframe.html
bug404548-subframe_window.html
bug413310-post.sjs
@ -14,6 +16,7 @@ support-files =
file_anchor_scroll_after_document_open.html
file_bfcache_plus_hash_1.html
file_bfcache_plus_hash_2.html
file_bug369814.html
file_bug385434_1.html
file_bug385434_2.html
file_bug385434_3.html
@ -54,6 +57,7 @@ support-files =
[test_anchor_scroll_after_document_open.html]
[test_bfcache_plus_hash.html]
[test_bug123696.html]
[test_bug369814.html]
[test_bug384014.html]
[test_bug385434.html]
[test_bug387979.html]

View File

@ -2005,6 +2005,14 @@ nsGlobalWindowOuter::SetNewDocument(nsIDocument* aDocument,
NS_ENSURE_SUCCESS(rv, rv);
}
// If the document comes from a JAR, check if the channel was determined
// to be unsafe. If so, permanently disable script on the compartment by
// calling Block() and throwing away the key.
nsCOMPtr<nsIJARChannel> jarChannel = do_QueryInterface(aDocument->GetChannel());
if (jarChannel && jarChannel->GetIsUnsafe()) {
xpc::Scriptability::Get(newInnerGlobal).Block();
}
if (mArguments) {
newInnerWindow->DefineArgumentsProperty(mArguments);
mArguments = nullptr;

View File

@ -121,6 +121,7 @@ support-files =
file_bug769117.html
file_bug782342.txt
file_bug787778.sjs
file_bug804395.jar
file_bug869432.eventsource
file_bug869432.eventsource^headers^
file_bug907892.html
@ -544,6 +545,7 @@ skip-if = toolkit == 'android' #bug 687032
[test_bug787778.html]
[test_bug789315.html]
[test_bug789856.html]
[test_bug804395.html]
[test_bug809003.html]
[test_bug810494.html]
[test_bug811701.html]

View File

@ -19,6 +19,8 @@ support-files =
bug340800_iframe.txt
bug369370-popup.png
bug372098-link-target.html
bug392567.jar
bug392567.jar^headers^
bug441930_iframe.html
bug445004-inner.html
bug445004-inner.js
@ -249,6 +251,7 @@ skip-if = toolkit == 'android' #TIMED_OUT
[test_bug389797.html]
[test_bug390975.html]
[test_bug391994.html]
[test_bug392567.html]
[test_bug394700.html]
[test_bug395107.html]
[test_bug401160.xhtml]

View File

@ -2,6 +2,7 @@
support-files =
file_CrossSiteXHR_cache_server.sjs
file_CrossSiteXHR_inner.html
file_CrossSiteXHR_inner.jar
file_CrossSiteXHR_inner_data.sjs
file_CrossSiteXHR_server.sjs

View File

@ -39,6 +39,9 @@ var origins =
{ server: 'http://\u03c0\u03b1\u03c1\u03ac\u03b4\u03b5\u03b9\u03b3\u03bc\u03b1.\u03b4\u03bf\u03ba\u03b9\u03bc\u03ae',
origin: 'http://xn--hxajbheg2az3al.xn--jxalpdlp'
},
{ origin: 'http://example.org',
file: 'jar:http://example.org/tests/dom/security/test/cors/file_CrossSiteXHR_inner.jar!/file_CrossSiteXHR_inner.html'
},
{ origin: 'null',
file: 'http://example.org/tests/dom/security/test/cors/file_CrossSiteXHR_inner_data.sjs'
},
@ -159,7 +162,9 @@ function* runTest() {
}
addLoadEvent(function() {
gen.next();
SpecialPowers.pushPrefEnv({"set": [["network.jar.block-remote-files", false]]}, function() {
gen.next();
});
});
</script>
</pre>

View File

@ -6,6 +6,8 @@ support-files =
postMessage_hash.html
postMessage_helper.html
postMessage_idn_helper.html
postMessage.jar
postMessage.jar^headers^
postMessage_joined_helper2.html
postMessage_joined_helper.html
postMessage_onOther.html
@ -27,6 +29,7 @@ skip-if = toolkit == 'android' #bug 894914 - wrong data - got FAIL, expected mes
[test_postMessage_hash.html]
[test_postMessage.html]
[test_postMessage_idn.xhtml]
[test_postMessage_jar.html]
[test_postMessage_joined.html]
[test_postMessage_onOther.html]
[test_postMessage_origin.xhtml]

Binary file not shown.

View File

@ -0,0 +1,52 @@
<!DOCTYPE html>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=430251
-->
<head>
<title>postMessage's interaction with pages at jar: URIs</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="browserFu.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<base href="http://mochi.test:8888/" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=430251">Mozilla Bug 430251</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<script class="testbody" type="application/javascript">
/** Test for Bug 430251 **/
SimpleTest.waitForExplicitFinish();
function receiveMessage(evt)
{
is(evt.origin, "http://mochi.test:8888", "wrong sender");
ok(evt.source === window.frames.kid, "wrong source");
is(evt.data, "finish-test", "wrong data");
is(evt.lastEventId, "", "wrong lastEventId");
SimpleTest.finish();
}
window.addEventListener("message", receiveMessage);
addLoadEvent(function() {
SpecialPowers.pushPrefEnv({"set": [["network.jar.block-remote-files", false]]}, function() {
var iframe = document.createElement('iframe');
iframe.setAttribute('src', 'jar:http://mochi.test:8888/tests/dom/tests/mochitest/whatwg/postMessage.jar!/postMessage_jar.html');
iframe.setAttribute('name', 'kid');
document.getElementById("content").appendChild(iframe);
iframe.onload = function() {
window.frames.kid.postMessage("start-test", "http://mochi.test:8888");
}
});
});
</script>
</pre>
</body>
</html>

View File

@ -5,6 +5,7 @@ support-files =
frame_script.js
head.js
!/dom/base/test/file_empty.html
!/dom/base/test/file_bug945152.jar
[browser_bug1047663.js]
[browser_bug1104623.js]

View File

@ -1,6 +0,0 @@
function handleRequest(request, response) {
response.processAsync();
response.write("Hello");
setTimeout(function() { response.finish(); }, 100000); // wait 100 seconds.
}

View File

@ -3,7 +3,7 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
var gURL = "http://example.org/tests/dom/workers/test/bug1063538.sjs";
var gJar = "jar:http://example.org/tests/dom/base/test/file_bug945152.jar!/data_big.txt";
var xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true});
var progressFired = false;
@ -20,6 +20,6 @@ xhr.onprogress = function(e) {
};
onmessage = function(e) {
xhr.open("GET", gURL, true);
xhr.open("GET", gJar, true);
xhr.send();
}

View File

@ -94,6 +94,7 @@ support-files =
script_createFile.js
worker_suspended.js
window_suspended.html
!/dom/base/test/file_bug945152.jar
!/dom/notification/test/mochitest/MockServices.js
!/dom/notification/test/mochitest/NotificationTest.js
!/dom/xhr/tests/relativeLoad_import.js

View File

@ -38,7 +38,9 @@ function runTest() {
SimpleTest.waitForExplicitFinish();
addLoadEvent(function() {
SpecialPowers.pushPermissions([{'type': 'systemXHR', 'allow': true, 'context': document}], runTest);
SpecialPowers.pushPrefEnv({"set": [["network.jar.block-remote-files", false]]}, function() {
SpecialPowers.pushPermissions([{'type': 'systemXHR', 'allow': true, 'context': document}], runTest);
});
});
</script>

View File

@ -11,6 +11,14 @@ interface nsIZipEntry;
[scriptable, builtinclass, uuid(e72b179b-d5df-4d87-b5de-fd73a65c60f6)]
interface nsIJARChannel : nsIChannel
{
/**
* Returns TRUE if the JAR file is not safe (if the content type reported
* by the server for a remote JAR is not of an expected type). Scripting,
* redirects, and plugins should be disabled when loading from this
* channel.
*/
[infallible] readonly attribute boolean isUnsafe;
/**
* Returns the JAR file. May be null if the jar is remote.
* Setting the JAR file is optional and overrides the JAR

View File

@ -194,14 +194,19 @@ nsJARInputThunk::IsNonBlocking(bool *nonBlocking)
nsJARChannel::nsJARChannel()
: mOpened(false)
, mContentDisposition(0)
, mContentLength(-1)
, mLoadFlags(LOAD_NORMAL)
, mStatus(NS_OK)
, mIsPending(false)
, mEnableOMT(true)
, mPendingEvent()
, mIsUnsafe(true)
, mBlockRemoteFiles(false)
{
LOG(("nsJARChannel::nsJARChannel [this=%p]\n", this));
mBlockRemoteFiles = Preferences::GetBool("network.jar.block-remote-files", false);
// hold an owning reference to the jar handler
mJarHandler = gJarHandler;
}
@ -263,7 +268,7 @@ nsJARChannel::CreateJarInput(nsIZipReaderCache *jarCache, nsJARInputThunk **resu
{
LOG(("nsJARChannel::CreateJarInput [this=%p]\n", this));
MOZ_ASSERT(resultInput);
MOZ_ASSERT(mJarFile);
MOZ_ASSERT(mJarFile || mTempMem);
// important to pass a clone of the file since the nsIFile impl is not
// necessarily MT-safe
@ -279,6 +284,7 @@ nsJARChannel::CreateJarInput(nsIZipReaderCache *jarCache, nsJARInputThunk **resu
if (mPreCachedJarReader) {
reader = mPreCachedJarReader;
} else if (jarCache) {
MOZ_ASSERT(mJarFile);
if (mInnerJarEntry.IsEmpty())
rv = jarCache->GetZip(clonedFile, getter_AddRefs(reader));
else
@ -290,7 +296,12 @@ nsJARChannel::CreateJarInput(nsIZipReaderCache *jarCache, nsJARInputThunk **resu
if (NS_FAILED(rv))
return rv;
rv = outerReader->Open(clonedFile);
if (mJarFile) {
rv = outerReader->Open(clonedFile);
} else {
rv = outerReader->OpenMemory(mTempMem->Elements(),
mTempMem->Length());
}
if (NS_FAILED(rv))
return rv;
@ -433,6 +444,9 @@ nsJARChannel::OpenLocalFile()
MOZ_ASSERT(mIsPending);
MOZ_ASSERT(mJarFile);
// Local files are always considered safe.
mIsUnsafe = false;
nsresult rv;
// Set mLoadGroup and mOpened before AsyncOpen return, and set back if
@ -885,7 +899,11 @@ nsJARChannel::SetContentCharset(const nsACString &aContentCharset)
NS_IMETHODIMP
nsJARChannel::GetContentDisposition(uint32_t *aContentDisposition)
{
return NS_ERROR_NOT_AVAILABLE;
if (mContentDispositionHeader.IsEmpty())
return NS_ERROR_NOT_AVAILABLE;
*aContentDisposition = mContentDisposition;
return NS_OK;
}
NS_IMETHODIMP
@ -909,7 +927,11 @@ nsJARChannel::SetContentDispositionFilename(const nsAString &aContentDisposition
NS_IMETHODIMP
nsJARChannel::GetContentDispositionHeader(nsACString &aContentDispositionHeader)
{
return NS_ERROR_NOT_AVAILABLE;
if (mContentDispositionHeader.IsEmpty())
return NS_ERROR_NOT_AVAILABLE;
aContentDispositionHeader = mContentDispositionHeader;
return NS_OK;
}
NS_IMETHODIMP
@ -936,14 +958,15 @@ nsJARChannel::Open(nsIInputStream **stream)
NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
mJarFile = nullptr;
mIsUnsafe = true;
nsresult rv = LookupFile();
if (NS_FAILED(rv))
return rv;
// If mJarFile was not set by LookupFile, we can't open a channel.
// If mJarInput was not set by LookupFile, the JAR is a remote jar.
if (!mJarFile) {
NS_NOTREACHED("only file-backed jars are supported");
NS_NOTREACHED("need sync downloader");
return NS_ERROR_NOT_IMPLEMENTED;
}
@ -954,6 +977,8 @@ nsJARChannel::Open(nsIInputStream **stream)
input.forget(stream);
mOpened = true;
// local files are always considered safe
mIsUnsafe = false;
return NS_OK;
}
@ -978,11 +1003,14 @@ nsJARChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctx)
nsContentUtils::IsSystemPrincipal(mLoadInfo->LoadingPrincipal())),
"security flags in loadInfo but asyncOpen2() not called");
LOG(("nsJARChannel::AsyncOpen [this=%p]\n", this));
NS_ENSURE_ARG_POINTER(listener);
NS_ENSURE_TRUE(!mOpened, NS_ERROR_IN_PROGRESS);
NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
mJarFile = nullptr;
mIsUnsafe = true;
// Initialize mProgressSink
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, mProgressSink);
@ -992,17 +1020,6 @@ nsJARChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctx)
mIsPending = true;
nsresult rv = LookupFile();
if (NS_FAILED(rv) || !mJarFile) {
// Not a local file...
mIsPending = false;
mListenerContext = nullptr;
mListener = nullptr;
mCallbacks = nullptr;
mProgressSink = nullptr;
return mJarFile ? rv : NS_ERROR_UNSAFE_CONTENT_TYPE;
}
rv = OpenLocalFile();
if (NS_FAILED(rv)) {
mIsPending = false;
mListenerContext = nullptr;
@ -1012,6 +1029,70 @@ nsJARChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctx)
return rv;
}
nsCOMPtr<nsIChannel> channel;
if (!mJarFile) {
// Not a local file...
// Check preferences to see if all remote jar support should be disabled
if (mBlockRemoteFiles) {
mIsUnsafe = true;
mIsPending = false;
mListenerContext = nullptr;
mListener = nullptr;
mCallbacks = nullptr;
mProgressSink = nullptr;
return NS_ERROR_UNSAFE_CONTENT_TYPE;
}
// kick off an async download of the base URI...
nsCOMPtr<nsIStreamListener> downloader = new MemoryDownloader(this);
uint32_t loadFlags =
mLoadFlags & ~(LOAD_DOCUMENT_URI | LOAD_CALL_CONTENT_SNIFFERS);
rv = NS_NewChannelInternal(getter_AddRefs(channel),
mJarBaseURI,
mLoadInfo,
nullptr, // PerformanceStorage
mLoadGroup,
mCallbacks,
loadFlags);
if (NS_FAILED(rv)) {
mIsPending = false;
mListenerContext = nullptr;
mListener = nullptr;
mCallbacks = nullptr;
mProgressSink = nullptr;
return rv;
}
if (mLoadInfo && mLoadInfo->GetEnforceSecurity()) {
rv = channel->AsyncOpen2(downloader);
}
else {
rv = channel->AsyncOpen(downloader, nullptr);
}
}
else {
rv = OpenLocalFile();
if (NS_SUCCEEDED(rv)) {
return NS_OK;
}
}
if (NS_FAILED(rv)) {
mIsPending = false;
mListenerContext = nullptr;
mListener = nullptr;
mCallbacks = nullptr;
mProgressSink = nullptr;
return rv;
}
if (mLoadGroup)
mLoadGroup->AddRequest(this, nullptr);
mOpened = true;
LOG(("nsJARChannel::AsyncOpen [this=%p] 8\n", this));
return NS_OK;
}
@ -1019,23 +1100,30 @@ NS_IMETHODIMP
nsJARChannel::AsyncOpen2(nsIStreamListener *aListener)
{
LOG(("nsJARChannel::AsyncOpen2 [this=%p]\n", this));
nsCOMPtr<nsIStreamListener> listener = aListener;
nsresult rv = nsContentSecurityManager::doContentSecurityCheck(this, listener);
if (NS_FAILED(rv)) {
mIsPending = false;
mListenerContext = nullptr;
mListener = nullptr;
mCallbacks = nullptr;
mProgressSink = nullptr;
return rv;
}
nsCOMPtr<nsIStreamListener> listener = aListener;
nsresult rv = nsContentSecurityManager::doContentSecurityCheck(this, listener);
if (NS_FAILED(rv)) {
mIsPending = false;
mListenerContext = nullptr;
mListener = nullptr;
mCallbacks = nullptr;
mProgressSink = nullptr;
return rv;
}
return AsyncOpen(listener, nullptr);
return AsyncOpen(listener, nullptr);
}
//-----------------------------------------------------------------------------
// nsIJARChannel
//-----------------------------------------------------------------------------
NS_IMETHODIMP
nsJARChannel::GetIsUnsafe(bool *isUnsafe)
{
*isUnsafe = mIsUnsafe;
return NS_OK;
}
NS_IMETHODIMP
nsJARChannel::GetJarFile(nsIFile **aFile)
{
@ -1122,6 +1210,116 @@ nsJARChannel::GetZipEntry(nsIZipEntry **aZipEntry)
return reader->GetEntry(mJarEntry, aZipEntry);
}
//-----------------------------------------------------------------------------
// mozilla::net::MemoryDownloader::IObserver
//-----------------------------------------------------------------------------
void
nsJARChannel::OnDownloadComplete(MemoryDownloader* aDownloader,
nsIRequest *request,
nsISupports *context,
nsresult status,
MemoryDownloader::Data aData)
{
nsresult rv;
nsCOMPtr<nsIChannel> channel(do_QueryInterface(request));
if (channel) {
uint32_t loadFlags;
channel->GetLoadFlags(&loadFlags);
if (loadFlags & LOAD_REPLACE) {
// Update our URI to reflect any redirects that happen during
// the HTTP request.
if (!mOriginalURI) {
SetOriginalURI(mJarURI);
}
nsCOMPtr<nsIURI> innerURI;
rv = channel->GetURI(getter_AddRefs(innerURI));
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIJARURI> newURI;
rv = mJarURI->CloneWithJARFile(innerURI,
getter_AddRefs(newURI));
if (NS_SUCCEEDED(rv)) {
mJarURI = newURI;
}
}
if (NS_SUCCEEDED(status)) {
status = rv;
}
}
}
if (NS_SUCCEEDED(status) && channel) {
// In case the load info object has changed during a redirect,
// grab it from the target channel.
channel->GetLoadInfo(getter_AddRefs(mLoadInfo));
// Grab the security info from our base channel
channel->GetSecurityInfo(getter_AddRefs(mSecurityInfo));
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
if (httpChannel) {
// We only want to run scripts if the server really intended to
// send us a JAR file. Check the server-supplied content type for
// a JAR type.
nsAutoCString header;
Unused << httpChannel->GetResponseHeader(
NS_LITERAL_CSTRING("Content-Type"), header);
nsAutoCString contentType;
nsAutoCString charset;
NS_ParseResponseContentType(header, contentType, charset);
nsAutoCString channelContentType;
channel->GetContentType(channelContentType);
mIsUnsafe = !(contentType.Equals(channelContentType) &&
(contentType.EqualsLiteral("application/java-archive") ||
contentType.EqualsLiteral("application/x-jar")));
} else {
nsCOMPtr<nsIJARChannel> innerJARChannel(do_QueryInterface(channel));
if (innerJARChannel) {
mIsUnsafe = innerJARChannel->GetIsUnsafe();
}
}
channel->GetContentDispositionHeader(mContentDispositionHeader);
mContentDisposition = NS_GetContentDispositionFromHeader(mContentDispositionHeader, this);
}
// This is a defense-in-depth check for the preferences to see if all remote jar
// support should be disabled. This check may not be needed.
MOZ_RELEASE_ASSERT(!mBlockRemoteFiles);
if (NS_SUCCEEDED(status) && mIsUnsafe &&
!Preferences::GetBool("network.jar.open-unsafe-types", false)) {
status = NS_ERROR_UNSAFE_CONTENT_TYPE;
}
if (NS_SUCCEEDED(status)) {
// Refuse to unpack view-source: jars even if open-unsafe-types is set.
nsCOMPtr<nsIViewSourceChannel> viewSource = do_QueryInterface(channel);
if (viewSource) {
status = NS_ERROR_UNSAFE_CONTENT_TYPE;
}
}
if (NS_SUCCEEDED(status)) {
mTempMem = Move(aData);
RefPtr<nsJARInputThunk> input;
rv = CreateJarInput(nullptr, getter_AddRefs(input));
if (NS_SUCCEEDED(rv)) {
// create input stream pump
rv = NS_NewInputStreamPump(getter_AddRefs(mPump), input.forget());
if (NS_SUCCEEDED(rv))
rv = mPump->AsyncRead(this, nullptr);
}
status = rv;
}
if (NS_FAILED(status)) {
NotifyError(status);
}
}
//-----------------------------------------------------------------------------
// nsIStreamListener
//-----------------------------------------------------------------------------

View File

@ -33,6 +33,7 @@ class nsInputStreamPump;
//-----------------------------------------------------------------------------
class nsJARChannel final : public nsIJARChannel
, public mozilla::net::MemoryDownloader::IObserver
, public nsIStreamListener
, public nsIThreadRetargetableRequest
, public nsIThreadRetargetableStreamListener
@ -65,6 +66,12 @@ private:
nsresult CheckPendingEvents();
void NotifyError(nsresult aError);
void FireOnProgress(uint64_t aProgress);
virtual void OnDownloadComplete(mozilla::net::MemoryDownloader* aDownloader,
nsIRequest* aRequest,
nsISupports* aCtxt,
nsresult aStatus,
mozilla::net::MemoryDownloader::Data aData)
override;
nsCString mSpec;
@ -83,6 +90,10 @@ private:
nsCOMPtr<nsISupports> mListenerContext;
nsCString mContentType;
nsCString mContentCharset;
nsCString mContentDispositionHeader;
/* mContentDisposition is uninitialized if mContentDispositionHeader is
* empty */
uint32_t mContentDisposition;
int64_t mContentLength;
uint32_t mLoadFlags;
nsresult mStatus;
@ -95,6 +106,9 @@ private:
uint32_t suspendCount;
} mPendingEvent;
bool mIsUnsafe;
mozilla::net::MemoryDownloader::Data mTempMem;
nsCOMPtr<nsIInputStreamPump> mPump;
// mRequest is only non-null during OnStartRequest, so we'll have a pointer
// to the request if we get called back via RetargetDeliveryTo.
@ -108,6 +122,9 @@ private:
// use StreamTransportService as background thread
nsCOMPtr<nsIEventTarget> mWorker;
// True if this channel should not download any remote files.
bool mBlockRemoteFiles;
};
#endif // nsJARChannel_h__

View File

@ -0,0 +1 @@
Content-Type: application/java-archive

View File

@ -1,5 +1,11 @@
[test_bug1173171.html]
[DEFAULT]
support-files =
bug1173171.zip
bug1173171.zip^headers^
bug403331.zip
bug403331.zip^headers^
openredirect.sjs
!/dom/base/test/file_bug945152.jar
[test_bug403331.html]
[test_bug1034143_mapped.html]
run-if = os == 'linux'
[test_bug1173171.html]

View File

@ -0,0 +1,5 @@
function handleRequest(request, response)
{
response.setStatusLine(request.httpVersion, 301, "Moved Permanently");
response.setHeader("Location", request.queryString, false);
}

View File

@ -0,0 +1,53 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1034143
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 945152</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=1034143">Mozilla Bug 1034143</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
// Ensure that XMLHttpRequest's memory-mapping code can handle a case
// where the nsIJARChannel's jarFile property is null, but which is
// otherwise eligible for bug 945152's memory-mapping optimization.
function runTest() {
const jarURL = "jar:http://example.org/tests/dom/base/test/file_bug945152.jar!/data_1.txt";
let xhr = new XMLHttpRequest({ mozAnon: true, mozSystem: true });
xhr.open("GET", jarURL);
xhr.onerror = function onerror(e) {
ok(false, "JAR XHR failed: " + e.status);
SimpleTest.finish();
};
xhr.onload = function onload(e) {
ok(xhr.status == 200, "Status is 200");
let ct = xhr.getResponseHeader("Content-Type");
ok(!ct.includes("mem-mapped"), "Data is not memory-mapped");
SimpleTest.finish();
};
xhr.responseType = 'arraybuffer';
xhr.send();
}
SimpleTest.waitForExplicitFinish();
addLoadEvent(function() {
SpecialPowers.pushPrefEnv({"set": [["dom.mapped_arraybuffer.enabled", true],
["network.jar.block-remote-files", false]]}, function() {
SpecialPowers.pushPermissions([{'type': 'systemXHR', 'allow': true, 'context': document}], runTest);
});
});
</script>
</pre>
</body>
</html>

View File

@ -18,6 +18,15 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1173171
/** Test for Bug 1173171 **/
// __setPref(key, value)__.
// Set a pref value asynchronously, returning a prmoise that resolves
// when it succeeds.
let pushPref = function (key, value) {
return new Promise(function(resolve, reject) {
SpecialPowers.pushPrefEnv({"set": [[key, value]]}, resolve);
});
};
// __xhr(method, url, responseType__.
// A simple async XMLHttpRequest call.
// Returns a promise with the response.
@ -40,9 +49,12 @@ let jarURL = "jar:http://mochi.test:8888/tests/modules/libjar/test/mochitest/bug
// Test behavior when blocking is deactivated and activated.
add_task(async function() {
let shouldBlock = true;
let response = await xhr("GET", jarURL, "document");
is(response, null, "Remote jars should be blocked.");
for (let shouldBlock of [false, true]) {
await pushPref("network.jar.block-remote-files", shouldBlock);
let response = await xhr("GET", jarURL, "document");
ok(shouldBlock === (response === null),
"Remote jars should be blocked if and only if the 'network.jar.block-remote-files' pref is active.");
}
});
</script>

View File

@ -0,0 +1,47 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=403331
-->
<head>
<title>Test for Bug 403331</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<iframe id="testFrame"></iframe>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 403331 **/
SimpleTest.waitForExplicitFinish();
function runTest() {
var testFrame = document.getElementById('testFrame');
// Try a redirected load from another domain to this one.
testFrame.onload = function() {
// If properly redirected, we'll be able to access elements in the loaded
// document.
var item = testFrame.contentDocument.getElementById('testitem');
is(item.textContent, "testcontents", "Should be able to access the child document");
SimpleTest.finish();
}
testFrame.src = "jar:http://example.org:80/tests/modules/libjar/test/mochitest/openredirect.sjs?http://mochi.test:8888/tests/modules/libjar/test/mochitest/bug403331.zip!/test.html";
}
addLoadEvent(function() {
SpecialPowers.pushPrefEnv({"set": [["network.jar.block-remote-files", false]]}, runTest);
});
</script>
</pre>
</body>
</html>

View File

@ -1892,6 +1892,13 @@ pref("network.websocket.delay-failed-reconnects", true);
// Equal to the DEFAULT_RECONNECTION_TIME_VALUE value in nsEventSource.cpp
pref("dom.server-events.default-reconnection-time", 5000); // in milliseconds
// If false, remote JAR files that are served with a content type other than
// application/java-archive or application/x-jar will not be opened
// by the jar channel.
pref("network.jar.open-unsafe-types", false);
// If true, loading remote JAR files using the jar: protocol will be prevented.
pref("network.jar.block-remote-files", true);
// This preference, if true, causes all UTF-8 domain names to be normalized to
// punycode. The intention is to allow UTF-8 domain names as input, but never
// generate them from punycode.