Bug 1466061 - unknown blob URLs, when opened as top-level domain, should show an error page , r=mayhemer

This commit is contained in:
Andrea Marchesini 2018-06-13 09:25:59 -07:00
Родитель d44aec000f
Коммит 281d3ab8fa
5 изменённых файлов: 174 добавлений и 62 удалений

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

@ -0,0 +1,92 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BlobURLChannel.h"
using namespace mozilla::dom;
BlobURLChannel::BlobURLChannel(nsIURI* aURI,
nsILoadInfo* aLoadInfo)
: mInitialized(false)
{
SetURI(aURI);
SetOriginalURI(aURI);
SetLoadInfo(aLoadInfo);
// If we're sandboxed, make sure to clear any owner the channel
// might already have.
if (aLoadInfo && aLoadInfo->GetLoadingSandboxed()) {
SetOwner(nullptr);
}
}
BlobURLChannel::~BlobURLChannel() = default;
void
BlobURLChannel::InitFailed()
{
MOZ_ASSERT(!mInitialized);
MOZ_ASSERT(!mInputStream);
mInitialized = true;
}
void
BlobURLChannel::Initialize(BlobImpl* aBlobImpl)
{
MOZ_ASSERT(!mInitialized);
nsAutoString contentType;
aBlobImpl->GetType(contentType);
SetContentType(NS_ConvertUTF16toUTF8(contentType));
if (aBlobImpl->IsFile()) {
nsString filename;
aBlobImpl->GetName(filename);
SetContentDispositionFilename(filename);
}
ErrorResult rv;
uint64_t size = aBlobImpl->GetSize(rv);
if (NS_WARN_IF(rv.Failed())) {
InitFailed();
return;
}
SetContentLength(size);
aBlobImpl->CreateInputStream(getter_AddRefs(mInputStream), rv);
if (NS_WARN_IF(rv.Failed())) {
InitFailed();
return;
}
MOZ_ASSERT(mInputStream);
mInitialized = true;
}
nsresult
BlobURLChannel::OpenContentStream(bool aAsync, nsIInputStream** aResult,
nsIChannel** aChannel)
{
MOZ_ASSERT(mInitialized);
if (!mInputStream) {
return NS_ERROR_MALFORMED_URI;
}
EnableSynthesizedProgressEvents(true);
nsCOMPtr<nsIInputStream> stream = mInputStream;
stream.forget(aResult);
return NS_OK;
}
void
BlobURLChannel::OnChannelDone()
{
mInputStream = nullptr;
}

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

@ -0,0 +1,53 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_BlobURLChannel_h
#define mozilla_dom_BlobURLChannel_h
#include "nsBaseChannel.h"
#include "nsCOMPtr.h"
#include "nsIInputStream.h"
class nsIURI;
namespace mozilla {
namespace dom {
class BlobImpl;
class BlobURLChannel final : public nsBaseChannel
{
public:
BlobURLChannel(nsIURI* aURI, nsILoadInfo* aLoadInfo);
// This method is called when there is not a valid BlobImpl for this channel.
// This method will make ::OpenContentStream to return NS_ERROR_MALFORMED_URI.
void InitFailed();
// There is a valid BlobImpl for the channel. The blob's inputStream will be
// used when ::OpenContentStream is called.
void Initialize(BlobImpl* aBlobImpl);
private:
~BlobURLChannel();
nsresult OpenContentStream(bool aAsync, nsIInputStream** aResult,
nsIChannel** aChannel) override;
void OnChannelDone() override;
// If Initialize() is called, this will contain the blob's inputStream.
nsCOMPtr<nsIInputStream> mInputStream;
// This boolean is used to check that InitFailed() or Initialize() are called
// just once.
bool mInitialized;
};
} // dom namespace
} // mozilla namespace
#endif /* mozilla_dom_BlobURLChannel_h */

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

@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BlobURLProtocolHandler.h"
#include "BlobURLChannel.h"
#include "mozilla/dom/BlobURL.h"
#include "mozilla/dom/ChromeUtils.h"
@ -841,29 +842,34 @@ BlobURLProtocolHandler::NewURI(const nsACString& aSpec,
}
NS_IMETHODIMP
BlobURLProtocolHandler::NewChannel2(nsIURI* uri,
BlobURLProtocolHandler::NewChannel2(nsIURI* aURI,
nsILoadInfo* aLoadInfo,
nsIChannel** result)
nsIChannel** aResult)
{
*result = nullptr;
RefPtr<BlobURLChannel> channel = new BlobURLChannel(aURI, aLoadInfo);
DataInfo* info = GetDataInfoFromURI(uri, true /*aAlsoIfRevoked */);
auto raii = MakeScopeExit([&] {
channel->InitFailed();
channel.forget(aResult);
});
DataInfo* info = GetDataInfoFromURI(aURI, true /*aAlsoIfRevoked */);
if (!info || info->mObjectType != DataInfo::eBlobImpl || !info->mBlobImpl) {
return NS_ERROR_DOM_BAD_URI;
return NS_OK;
}
RefPtr<BlobImpl> blobImpl = info->mBlobImpl;
nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(uri);
nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(aURI);
if (!uriPrinc) {
return NS_ERROR_DOM_BAD_URI;
return NS_OK;
}
nsCOMPtr<nsIPrincipal> principal;
nsresult rv = uriPrinc->GetPrincipal(getter_AddRefs(principal));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_SUCCESS(rv, NS_OK);
if (!principal) {
return NS_ERROR_DOM_BAD_URI;
return NS_OK;
}
MOZ_ASSERT(info->mPrincipal == principal);
@ -881,47 +887,13 @@ BlobURLProtocolHandler::NewChannel2(nsIURI* uri,
!nsContentUtils::IsSystemPrincipal(aLoadInfo->LoadingPrincipal()) &&
!ChromeUtils::IsOriginAttributesEqualIgnoringFPD(aLoadInfo->GetOriginAttributes(),
BasePrincipal::Cast(principal)->OriginAttributesRef())) {
return NS_ERROR_DOM_BAD_URI;
return NS_OK;
}
ErrorResult error;
nsCOMPtr<nsIInputStream> stream;
blobImpl->CreateInputStream(getter_AddRefs(stream), error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
nsAutoString contentType;
blobImpl->GetType(contentType);
nsCOMPtr<nsIChannel> channel;
rv = NS_NewInputStreamChannelInternal(getter_AddRefs(channel),
uri,
stream.forget(),
NS_ConvertUTF16toUTF8(contentType),
EmptyCString(), // aContentCharset
aLoadInfo);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (blobImpl->IsFile()) {
nsString filename;
blobImpl->GetName(filename);
channel->SetContentDispositionFilename(filename);
}
uint64_t size = blobImpl->GetSize(error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
channel->SetOriginalURI(uri);
channel->SetContentType(NS_ConvertUTF16toUTF8(contentType));
channel->SetContentLength(size);
channel.forget(result);
raii.release();
channel->Initialize(blobImpl);
channel.forget(aResult);
return NS_OK;
}

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

@ -15,12 +15,14 @@ EXPORTS.mozilla.dom += [
UNIFIED_SOURCES += [
'BlobURL.cpp',
'BlobURLChannel.cpp',
'BlobURLProtocolHandler.cpp',
'FontTableURIProtocolHandler.cpp',
]
LOCAL_INCLUDES += [
'/dom/file',
'/netwerk/base',
]
include('/ipc/chromium/chromium-config.mozbuild')

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

@ -1,34 +1,27 @@
[url-with-xhr.any.worker.html]
expected: TIMEOUT
[XHR of a revoked URL should fail]
expected: TIMEOUT
[Only exact matches should revoke URLs, using XHR]
expected: NOTRUN
expected: FAIL
[Appending a query string should cause XHR to fail]
expected: NOTRUN
[Appending a path should cause XHR to fail]
expected: NOTRUN
expected: FAIL
[XHR with method "HEAD" should fail]
expected: NOTRUN
expected: FAIL
[XHR with method "POST" should fail]
expected: NOTRUN
expected: FAIL
[XHR with method "DELETE" should fail]
expected: NOTRUN
expected: FAIL
[XHR with method "OPTIONS" should fail]
expected: NOTRUN
expected: FAIL
[XHR with method "PUT" should fail]
expected: NOTRUN
expected: FAIL
[XHR with method "CUSTOM" should fail]
expected: NOTRUN
expected: FAIL
[url-with-xhr.any.html]