Backed out changeset 9dfe3fe4ccc5 (bug 1871135) for causing mochitest failures in nsClipboardProxy.cpp CLOSED TREE

This commit is contained in:
Cristian Tuns 2024-02-12 12:04:41 -05:00
Родитель 592571a8e6
Коммит 2b828fa42e
20 изменённых файлов: 78 добавлений и 476 удалений

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

@ -21,7 +21,6 @@
#include "imgIContainer.h"
#include "imgITools.h"
#include "nsComponentManagerUtils.h"
#include "nsGlobalWindowInner.h"
#include "nsIClipboard.h"
#include "nsIFile.h"
#include "nsIInputStream.h"
@ -173,15 +172,7 @@ void DataTransferItem::FillInExternalData() {
return;
}
nsCOMPtr<nsIGlobalObject> global = mDataTransfer->GetGlobal();
WindowContext* windowContext = nullptr;
if (global) {
const auto* innerWindow = global->GetAsInnerWindow();
windowContext = innerWindow ? innerWindow->GetWindowContext() : nullptr;
}
MOZ_ASSERT(windowContext);
nsresult rv = clipboard->GetData(trans, mDataTransfer->ClipboardType(),
windowContext);
nsresult rv = clipboard->GetData(trans, mDataTransfer->ClipboardType());
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}

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

@ -197,7 +197,6 @@
#include "nsICaptivePortalService.h"
#include "nsICertOverrideService.h"
#include "nsIClipboard.h"
#include "nsIContentAnalysis.h"
#include "nsIContentProcess.h"
#include "nsIContentSecurityPolicy.h"
#include "nsICookie.h"
@ -3463,23 +3462,8 @@ static Result<nsCOMPtr<nsITransferable>, nsresult> CreateTransferable(
mozilla::ipc::IPCResult ContentParent::RecvGetClipboard(
nsTArray<nsCString>&& aTypes, const int32_t& aWhichClipboard,
const MaybeDiscarded<WindowContext>& aRequestingWindowContext,
IPCTransferableData* aTransferableData) {
nsresult rv;
// We expect content processes to always pass a non-null window so Content
// Analysis can analyze it. (if Content Analysis is active)
// There may be some cases when a window is closing, etc., in
// which case returning no clipboard content should not be a problem.
if (aRequestingWindowContext.IsDiscarded()) {
NS_WARNING(
"discarded window passed to RecvGetClipboard(); returning no clipboard "
"content");
return IPC_OK();
}
if (aRequestingWindowContext.IsNull()) {
return IPC_FAIL(this, "passed null window to RecvGetClipboard()");
}
RefPtr<WindowGlobalParent> window = aRequestingWindowContext.get_canonical();
// Retrieve clipboard
nsCOMPtr<nsIClipboard> clipboard(do_GetService(kCClipboardCID, &rv));
if (NS_FAILED(rv)) {
@ -3494,7 +3478,7 @@ mozilla::ipc::IPCResult ContentParent::RecvGetClipboard(
// Get data from clipboard
nsCOMPtr<nsITransferable> trans = result.unwrap();
clipboard->GetData(trans, aWhichClipboard, window);
clipboard->GetData(trans, aWhichClipboard);
nsContentUtils::TransferableToIPCTransferableData(
trans, aTransferableData, true /* aInSyncMessage */, this);

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

@ -955,7 +955,6 @@ class ContentParent final : public PContentParent,
mozilla::ipc::IPCResult RecvGetClipboard(
nsTArray<nsCString>&& aTypes, const int32_t& aWhichClipboard,
const MaybeDiscarded<WindowContext>& aRequestingWindowContext,
IPCTransferableData* aTransferableData);
mozilla::ipc::IPCResult RecvEmptyClipboard(const int32_t& aWhichClipboard);

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

@ -1220,10 +1220,7 @@ parent:
// Given a list of supported types, returns the clipboard data for the
// first type that matches.
// aRequestingWindowContext is the window that is requesting the clipboard,
// which is used for content analysis.
sync GetClipboard(nsCString[] aTypes, int32_t aWhichClipboard,
MaybeDiscardedWindowContext aRequestingWindowContext)
sync GetClipboard(nsCString[] aTypes, int32_t aWhichClipboard)
returns (IPCTransferableData transferableData);
// Returns a list of formats supported by the clipboard

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

@ -2323,12 +2323,7 @@ nsresult HTMLEditor::PasteInternal(int32_t aClipboardType) {
return NS_ERROR_FAILURE;
}
// Get the Data from the clipboard
auto* windowContext = GetDocument()->GetWindowContext();
if (!windowContext) {
NS_WARNING("No window context");
return NS_ERROR_FAILURE;
}
rv = clipboard->GetData(transferable, aClipboardType, windowContext);
rv = clipboard->GetData(transferable, aClipboardType);
if (NS_FAILED(rv)) {
NS_WARNING("nsIClipboard::GetData() failed");
return rv;
@ -2362,8 +2357,7 @@ nsresult HTMLEditor::PasteInternal(int32_t aClipboardType) {
NS_WARNING_ASSERTION(
NS_SUCCEEDED(rvIgnored),
"nsITransferable::AddDataFlavor(kHTMLContext) failed, but ignored");
rvIgnored =
clipboard->GetData(contextTransferable, aClipboardType, windowContext);
rvIgnored = clipboard->GetData(contextTransferable, aClipboardType);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),
"nsIClipboard::GetData() failed, but ignored");
nsCOMPtr<nsISupports> contextDataObj;
@ -2393,9 +2387,7 @@ nsresult HTMLEditor::PasteInternal(int32_t aClipboardType) {
NS_WARNING_ASSERTION(
NS_SUCCEEDED(rvIgnored),
"nsITransferable::AddDataFlavor(kHTMLInfo) failed, but ignored");
rvIgnored =
clipboard->GetData(infoTransferable, aClipboardType, windowContext);
clipboard->GetData(infoTransferable, aClipboardType);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),
"nsIClipboard::GetData() failed, but ignored");
nsCOMPtr<nsISupports> infoDataObj;
@ -2561,11 +2553,6 @@ nsresult HTMLEditor::PasteNoFormattingAsAction(
NS_WARNING("Editor didn't have document, but ignored");
return NS_OK;
}
auto* windowContext = GetDocument()->GetWindowContext();
if (!windowContext) {
NS_WARNING("Editor didn't have document window context, but ignored");
return NS_OK;
}
Result<nsCOMPtr<nsITransferable>, nsresult> maybeTransferable =
EditorUtils::CreateTransferableForPlainText(*GetDocument());
@ -2586,7 +2573,7 @@ nsresult HTMLEditor::PasteNoFormattingAsAction(
}
// Get the Data from the clipboard
rv = clipboard->GetData(transferable, aClipboardType, windowContext);
rv = clipboard->GetData(transferable, aClipboardType);
if (NS_FAILED(rv)) {
NS_WARNING("nsIClipboard::GetData() failed");
return rv;
@ -2830,12 +2817,6 @@ nsresult HTMLEditor::PasteAsPlaintextQuotation(int32_t aSelectionType) {
}
RefPtr<Document> destdoc = GetDocument();
auto* windowContext = GetDocument()->GetWindowContext();
if (!windowContext) {
NS_WARNING("Editor didn't have document window context");
return NS_ERROR_FAILURE;
}
nsILoadContext* loadContext = destdoc ? destdoc->GetLoadContext() : nullptr;
DebugOnly<nsresult> rvIgnored = transferable->Init(loadContext);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),
@ -2848,7 +2829,7 @@ nsresult HTMLEditor::PasteAsPlaintextQuotation(int32_t aSelectionType) {
"nsITransferable::AddDataFlavor(kTextMime) failed, but ignored");
// Get the Data from the clipboard
rvIgnored = clipboard->GetData(transferable, aSelectionType, windowContext);
rvIgnored = clipboard->GetData(transferable, aSelectionType);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),
"nsIClipboard::GetData() failed, but ignored");

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

@ -599,13 +599,8 @@ nsresult TextEditor::HandlePasteAsQuotation(
return NS_OK;
}
auto* windowContext = GetDocument()->GetWindowContext();
if (!windowContext) {
NS_WARNING("Editor didn't have document window context");
return NS_ERROR_FAILURE;
}
// Get the Data from the clipboard
rv = clipboard->GetData(trans, aClipboardType, windowContext);
clipboard->GetData(trans, aClipboardType);
// Now we ask the transferable for the data
// it still owns the data, we just have a pointer to it.

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

@ -193,13 +193,7 @@ nsresult TextEditor::HandlePaste(AutoEditActionDataSetter& aEditActionData,
return NS_OK; // XXX Why?
}
// Get the Data from the clipboard.
auto* windowContext = GetDocument()->GetWindowContext();
if (!windowContext) {
NS_WARNING("Editor didn't have document window context");
return NS_ERROR_FAILURE;
}
rv = clipboard->GetData(transferable, aClipboardType, windowContext);
rv = clipboard->GetData(transferable, aClipboardType);
if (NS_FAILED(rv)) {
NS_WARNING("nsIClipboard::GetData() failed, but ignored");
return NS_OK; // XXX Why?

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

@ -128,9 +128,8 @@ ContentAnalysisRequest::GetFilePath(nsAString& aFilePath) {
}
NS_IMETHODIMP
ContentAnalysisRequest::GetUrl(nsIURI** aUrl) {
NS_ENSURE_ARG_POINTER(aUrl);
NS_IF_ADDREF(*aUrl = mUrl);
ContentAnalysisRequest::GetUrl(nsAString& aUrl) {
aUrl = mUrl;
return NS_OK;
}
@ -197,8 +196,8 @@ nsresult ContentAnalysis::CreateContentAnalysisClient(nsCString&& aPipePathName,
ContentAnalysisRequest::ContentAnalysisRequest(
AnalysisType aAnalysisType, nsString aString, bool aStringIsFilePath,
nsCString aSha256Digest, nsCOMPtr<nsIURI> aUrl,
OperationType aOperationType, dom::WindowGlobalParent* aWindowGlobalParent)
nsCString aSha256Digest, nsString aUrl, OperationType aOperationType,
dom::WindowGlobalParent* aWindowGlobalParent)
: mAnalysisType(aAnalysisType),
mUrl(std::move(aUrl)),
mSha256Digest(std::move(aSha256Digest)),
@ -297,14 +296,11 @@ static nsresult ConvertToProtobuf(
auto* requestData = aOut->mutable_request_data();
nsCOMPtr<nsIURI> url;
rv = aIn->GetUrl(getter_AddRefs(url));
nsString url;
rv = aIn->GetUrl(url);
NS_ENSURE_SUCCESS(rv, rv);
nsCString urlString;
rv = url->GetSpec(urlString);
NS_ENSURE_SUCCESS(rv, rv);
if (!urlString.IsEmpty()) {
requestData->set_url(urlString.get());
if (!url.IsEmpty()) {
requestData->set_url(NS_ConvertUTF16toUTF8(url).get());
}
nsString email;
@ -639,12 +635,9 @@ NS_IMETHODIMP ContentAnalysisResult::GetShouldAllowContent(
bool* aShouldAllowContent) {
if (mValue.is<NoContentAnalysisResult>()) {
NoContentAnalysisResult result = mValue.as<NoContentAnalysisResult>();
// Note that we allow content if we're unable to get it (for example, if
// there's clipboard content that is not text or file)
*aShouldAllowContent =
result == NoContentAnalysisResult::AGENT_NOT_PRESENT ||
result == NoContentAnalysisResult::NO_PARENT_BROWSER ||
result == NoContentAnalysisResult::ERROR_COULD_NOT_GET_DATA;
result == NoContentAnalysisResult::NO_PARENT_BROWSER;
} else {
*aShouldAllowContent =
ShouldAllowAction(mValue.as<nsIContentAnalysisResponse::Action>());
@ -1004,7 +997,8 @@ ContentAnalysis::AnalyzeContentRequestCallback(
mozilla::services::GetObserverService();
obsServ->NotifyObservers(aRequest, "dlp-request-made", nullptr);
return RunAnalyzeRequestTask(aRequest, aAutoAcknowledge, aCallback);
rv = RunAnalyzeRequestTask(aRequest, aAutoAcknowledge, aCallback);
return rv;
}
NS_IMETHODIMP

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

@ -31,7 +31,7 @@ class ContentAnalysisRequest final : public nsIContentAnalysisRequest {
ContentAnalysisRequest(AnalysisType aAnalysisType, nsString aString,
bool aStringIsFilePath, nsCString aSha256Digest,
nsCOMPtr<nsIURI> aUrl, OperationType aOperationType,
nsString aUrl, OperationType aOperationType,
dom::WindowGlobalParent* aWindowGlobalParent);
static nsresult GetFileDigest(const nsAString& aFilePath,
nsCString& aDigestString);
@ -53,7 +53,7 @@ class ContentAnalysisRequest final : public nsIContentAnalysisRequest {
// The URL containing the file download/upload or to which web content is
// being uploaded.
nsCOMPtr<nsIURI> mUrl;
nsString mUrl;
// Sha256 digest of file.
nsCString mSha256Digest;

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

@ -83,15 +83,6 @@ class ContentAnalysisResult : public nsIContentAnalysisResult {
return FromNoResult(NoContentAnalysisResult::ERROR_INVALID_JSON_RESPONSE);
}
static RefPtr<ContentAnalysisResult> FromContentAnalysisResponse(
nsIContentAnalysisResponse* aResponse) {
if (aResponse->GetShouldAllowContent()) {
return FromAction(nsIContentAnalysisResponse::Action::eAllow);
} else {
return FromAction(nsIContentAnalysisResponse::Action::eBlock);
}
}
private:
explicit ContentAnalysisResult(nsIContentAnalysisResponse::Action aAction)
: mValue(aAction) {}

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

@ -5,7 +5,6 @@
#include "nsISupports.idl"
interface nsIURI;
webidl WindowGlobalParent;
[scriptable, uuid(06e6a60f-3a2b-41fa-a63b-fea7a7f71649)]
@ -133,7 +132,7 @@ interface nsIContentAnalysisRequest : nsISupports
// The URL containing the file download/upload or to which web content is
// being uploaded.
readonly attribute nsIURI url;
readonly attribute AString url;
// Sha256 digest of file. Callers may pass in an empty string to have the
// content analysis code calculate this.
@ -173,7 +172,7 @@ interface nsIContentAnalysis : nsISupports
* True if content analysis should be consulted. Must only be accessed from
* the parent process's main thread.
*/
readonly attribute boolean isActive;
readonly attribute bool isActive;
/**
* True if content analysis might be active, and False if content analysis

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

@ -159,7 +159,7 @@ function commonDialogOnLoad() {
resources: [],
analysisType: Ci.nsIContentAnalysisRequest.eBulkDataEntry,
operationTypeForDisplay: Ci.nsIContentAnalysisRequest.eClipboard,
url: args.owningBrowsingContext.currentURI,
url: args.owningBrowsingContext.currentURI.spec,
textContent: data,
windowGlobalParent:
args.owningBrowsingContext.currentWindowContext,

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

@ -5,27 +5,21 @@
#include "nsBaseClipboard.h"
#include "ContentAnalysis.h"
#include "mozilla/contentanalysis/ContentAnalysisIPCTypes.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/CanonicalBrowsingContext.h"
#include "mozilla/dom/Document.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/PromiseNativeHandler.h"
#include "mozilla/dom/WindowGlobalParent.h"
#include "mozilla/dom/WindowContext.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/MoveOnlyFunction.h"
#include "mozilla/RefPtr.h"
#include "mozilla/Services.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/StaticPrefs_dom.h"
#include "mozilla/StaticPrefs_widget.h"
#include "nsContentUtils.h"
#include "nsFocusManager.h"
#include "nsIClipboardOwner.h"
#include "nsIPromptService.h"
#include "nsISupportsPrimitives.h"
#include "nsError.h"
#include "nsXPCOM.h"
@ -59,13 +53,11 @@ class UserConfirmationRequest final
UserConfirmationRequest(int32_t aClipboardType,
Document* aRequestingChromeDocument,
nsIPrincipal* aRequestingPrincipal,
nsBaseClipboard* aClipboard,
mozilla::dom::WindowContext* aRequestingWindowContext)
nsBaseClipboard* aClipboard)
: mClipboardType(aClipboardType),
mRequestingChromeDocument(aRequestingChromeDocument),
mRequestingPrincipal(aRequestingPrincipal),
mClipboard(aClipboard),
mRequestingWindowContext(aRequestingWindowContext) {
mClipboard(aClipboard) {
MOZ_ASSERT(
mClipboard->nsIClipboard::IsClipboardTypeSupported(aClipboardType));
}
@ -77,13 +69,10 @@ class UserConfirmationRequest final
mozilla::ErrorResult& aRv) override;
bool IsEqual(int32_t aClipboardType, Document* aRequestingChromeDocument,
nsIPrincipal* aRequestingPrincipal,
mozilla::dom::WindowContext* aRequestingWindowContext) const {
nsIPrincipal* aRequestingPrincipal) const {
return ClipboardType() == aClipboardType &&
RequestingChromeDocument() == aRequestingChromeDocument &&
RequestingPrincipal()->Equals(aRequestingPrincipal) &&
(mRequestingWindowContext && aRequestingWindowContext &&
mRequestingWindowContext->Id() == aRequestingWindowContext->Id());
RequestingPrincipal()->Equals(aRequestingPrincipal);
}
int32_t ClipboardType() const { return mClipboardType; }
@ -119,7 +108,6 @@ class UserConfirmationRequest final
MOZ_ASSERT(!request->mFlavorList.IsEmpty());
MOZ_ASSERT(request->mCallback);
mClipboard->AsyncGetDataInternal(request->mFlavorList, mClipboardType,
mRequestingWindowContext,
request->mCallback);
}
}
@ -135,7 +123,6 @@ class UserConfirmationRequest final
RefPtr<Document> mRequestingChromeDocument;
const nsCOMPtr<nsIPrincipal> mRequestingPrincipal;
const RefPtr<nsBaseClipboard> mClipboard;
const RefPtr<mozilla::dom::WindowContext> mRequestingWindowContext;
// Track the pending read requests that wait for user confirmation.
nsTArray<UniquePtr<ClipboardGetRequest>> mPendingClipboardGetRequests;
};
@ -300,228 +287,6 @@ NS_IMETHODIMP nsBaseClipboard::AsyncSetData(
return NS_OK;
}
namespace {
class SafeContentAnalysisResultCallback final
: public nsIContentAnalysisCallback {
public:
explicit SafeContentAnalysisResultCallback(
std::function<void(RefPtr<nsIContentAnalysisResult>&&)> aResolver)
: mResolver(std::move(aResolver)) {}
void Callback(RefPtr<nsIContentAnalysisResult>&& aResult) {
MOZ_ASSERT(mResolver, "Called SafeContentAnalysisResultCallback twice!");
if (auto resolver = std::move(mResolver)) {
resolver(std::move(aResult));
}
}
NS_IMETHODIMP ContentResult(nsIContentAnalysisResponse* aResponse) override {
using namespace mozilla::contentanalysis;
RefPtr<ContentAnalysisResult> result =
ContentAnalysisResult::FromContentAnalysisResponse(aResponse);
Callback(result);
return NS_OK;
}
NS_IMETHODIMP Error(nsresult aError) override {
using namespace mozilla::contentanalysis;
Callback(ContentAnalysisResult::FromNoResult(
NoContentAnalysisResult::ERROR_OTHER));
return NS_OK;
}
NS_DECL_THREADSAFE_ISUPPORTS
private:
// Private destructor to force this to be allocated in a RefPtr, which is
// necessary for safe usage.
~SafeContentAnalysisResultCallback() {
MOZ_ASSERT(!mResolver, "SafeContentAnalysisResultCallback never called!");
}
mozilla::MoveOnlyFunction<void(RefPtr<nsIContentAnalysisResult>&&)> mResolver;
};
NS_IMPL_ISUPPORTS(SafeContentAnalysisResultCallback,
nsIContentAnalysisCallback);
} // namespace
// Returning:
// - true means a content analysis request was fired
// - false means there is no text data in the transferable
// - NoContentAnalysisResult means there was an error
static mozilla::Result<bool, mozilla::contentanalysis::NoContentAnalysisResult>
CheckClipboardContentAnalysisAsText(
uint64_t aInnerWindowId, SafeContentAnalysisResultCallback* aResolver,
nsIURI* aDocumentURI, nsIContentAnalysis* aContentAnalysis,
nsITransferable* aTextTrans) {
using namespace mozilla::contentanalysis;
nsCOMPtr<nsISupports> transferData;
if (NS_FAILED(aTextTrans->GetTransferData(kTextMime,
getter_AddRefs(transferData)))) {
return false;
}
nsCOMPtr<nsISupportsString> textData = do_QueryInterface(transferData);
if (MOZ_UNLIKELY(!textData)) {
return false;
}
nsString text;
if (NS_FAILED(textData->GetData(text))) {
return mozilla::Err(NoContentAnalysisResult::ERROR_OTHER);
}
RefPtr<mozilla::dom::WindowGlobalParent> window =
mozilla::dom::WindowGlobalParent::GetByInnerWindowId(aInnerWindowId);
if (!window) {
// The window has gone away in the meantime
return mozilla::Err(NoContentAnalysisResult::ERROR_OTHER);
}
nsCOMPtr<nsIContentAnalysisRequest> contentAnalysisRequest =
new ContentAnalysisRequest(
nsIContentAnalysisRequest::AnalysisType::eBulkDataEntry,
std::move(text), false, EmptyCString(), aDocumentURI,
nsIContentAnalysisRequest::OperationType::eClipboard, window);
nsresult rv = aContentAnalysis->AnalyzeContentRequestCallback(
contentAnalysisRequest, /* aAutoAcknowledge */ true, aResolver);
if (NS_FAILED(rv)) {
return mozilla::Err(NoContentAnalysisResult::ERROR_OTHER);
}
return true;
}
// Returning:
// - true means a content analysis request was fired
// - false means there is no file data in the transferable
// - NoContentAnalysisResult means there was an error
static mozilla::Result<bool, mozilla::contentanalysis::NoContentAnalysisResult>
CheckClipboardContentAnalysisAsFile(
uint64_t aInnerWindowId, SafeContentAnalysisResultCallback* aResolver,
nsIURI* aDocumentURI, nsIContentAnalysis* aContentAnalysis,
nsITransferable* aFileTrans) {
using namespace mozilla::contentanalysis;
nsCOMPtr<nsISupports> transferData;
nsresult rv =
aFileTrans->GetTransferData(kFileMime, getter_AddRefs(transferData));
nsString filePath;
if (NS_SUCCEEDED(rv)) {
if (nsCOMPtr<nsIFile> file = do_QueryInterface(transferData)) {
rv = file->GetPath(filePath);
} else {
MOZ_ASSERT_UNREACHABLE("clipboard data had kFileMime but no nsIFile!");
return mozilla::Err(NoContentAnalysisResult::ERROR_OTHER);
}
}
if (NS_FAILED(rv) || filePath.IsEmpty()) {
return false;
}
RefPtr<mozilla::dom::WindowGlobalParent> window =
mozilla::dom::WindowGlobalParent::GetByInnerWindowId(aInnerWindowId);
if (!window) {
// The window has gone away in the meantime
return mozilla::Err(NoContentAnalysisResult::ERROR_OTHER);
}
// Let the content analysis code calculate the digest
nsCOMPtr<nsIContentAnalysisRequest> contentAnalysisRequest =
new ContentAnalysisRequest(
nsIContentAnalysisRequest::AnalysisType::eBulkDataEntry,
std::move(filePath), true, EmptyCString(), aDocumentURI,
nsIContentAnalysisRequest::OperationType::eCustomDisplayString,
window);
rv = aContentAnalysis->AnalyzeContentRequestCallback(
contentAnalysisRequest,
/* aAutoAcknowledge */ true, aResolver);
if (NS_FAILED(rv)) {
return mozilla::Err(NoContentAnalysisResult::ERROR_OTHER);
}
return true;
}
static void CheckClipboardContentAnalysis(
mozilla::dom::WindowGlobalParent* aWindow, nsITransferable* aTransferable,
SafeContentAnalysisResultCallback* aResolver) {
using namespace mozilla::contentanalysis;
// Content analysis is only needed if an outside webpage has access to
// the data. So, skip content analysis if there is:
// - no associated window (for example, scripted clipboard read by system
// code)
// - the window is a chrome docshell
// - the window is being rendered in the parent process (for example,
// about:support and the like)
if (!aWindow || aWindow->GetBrowsingContext()->IsChrome() ||
aWindow->IsInProcess()) {
aResolver->Callback(ContentAnalysisResult::FromNoResult(
NoContentAnalysisResult::NO_PARENT_BROWSER));
return;
}
nsCOMPtr<nsIContentAnalysis> contentAnalysis =
mozilla::components::nsIContentAnalysis::Service();
if (!contentAnalysis) {
aResolver->Callback(ContentAnalysisResult::FromNoResult(
NoContentAnalysisResult::ERROR_OTHER));
return;
}
bool contentAnalysisIsActive;
nsresult rv = contentAnalysis->GetIsActive(&contentAnalysisIsActive);
if (MOZ_LIKELY(NS_FAILED(rv) || !contentAnalysisIsActive)) {
aResolver->Callback(ContentAnalysisResult::FromNoResult(
NoContentAnalysisResult::AGENT_NOT_PRESENT));
return;
}
nsCOMPtr<nsIURI> currentURI = aWindow->Canonical()->GetDocumentURI();
uint64_t innerWindowId = aWindow->InnerWindowId();
nsTArray<nsCString> flavors;
rv = aTransferable->FlavorsTransferableCanExport(flavors);
if (NS_WARN_IF(NS_FAILED(rv))) {
aResolver->Callback(ContentAnalysisResult::FromNoResult(
NoContentAnalysisResult::ERROR_OTHER));
return;
}
bool keepChecking = true;
if (flavors.Contains(kFileMime)) {
auto fileResult = CheckClipboardContentAnalysisAsFile(
innerWindowId, aResolver, currentURI, contentAnalysis, aTransferable);
if (fileResult.isErr()) {
aResolver->Callback(
ContentAnalysisResult::FromNoResult(fileResult.unwrapErr()));
return;
}
keepChecking = !fileResult.unwrap();
}
if (keepChecking) {
// Failed to get the clipboard data as a file, so try as text
auto textResult = CheckClipboardContentAnalysisAsText(
innerWindowId, aResolver, currentURI, contentAnalysis, aTransferable);
if (textResult.isErr()) {
aResolver->Callback(
ContentAnalysisResult::FromNoResult(textResult.unwrapErr()));
return;
}
if (!textResult.unwrap()) {
// Couldn't get file or text data from this
aResolver->Callback(ContentAnalysisResult::FromNoResult(
NoContentAnalysisResult::ERROR_COULD_NOT_GET_DATA));
return;
}
}
}
static bool CheckClipboardContentAnalysisSync(
mozilla::dom::WindowGlobalParent* aWindow,
const nsCOMPtr<nsITransferable>& trans) {
bool requestDone = false;
RefPtr<nsIContentAnalysisResult> result;
auto callback = mozilla::MakeRefPtr<SafeContentAnalysisResultCallback>(
[&requestDone, &result](RefPtr<nsIContentAnalysisResult>&& aResult) {
result = std::move(aResult);
requestDone = true;
});
CheckClipboardContentAnalysis(aWindow, trans, callback);
mozilla::SpinEventLoopUntil("CheckClipboardContentAnalysisSync"_ns,
[&requestDone]() -> bool { return requestDone; });
return result->GetShouldAllowContent();
}
nsBaseClipboard::nsBaseClipboard(const ClipboardCapabilities& aClipboardCaps)
: mClipboardCaps(aClipboardCaps) {
using mozilla::MakeUnique;
@ -627,9 +392,8 @@ nsresult nsBaseClipboard::GetDataFromClipboardCache(
/**
* Gets the transferable object from system clipboard.
*/
NS_IMETHODIMP nsBaseClipboard::GetData(
nsITransferable* aTransferable, int32_t aWhichClipboard,
mozilla::dom::WindowContext* aWindowContext) {
NS_IMETHODIMP nsBaseClipboard::GetData(nsITransferable* aTransferable,
int32_t aWhichClipboard) {
MOZ_CLIPBOARD_LOG("%s: clipboard=%d", __FUNCTION__, aWhichClipboard);
if (!aTransferable) {
@ -650,33 +414,19 @@ NS_IMETHODIMP nsBaseClipboard::GetData(
if (NS_SUCCEEDED(
GetDataFromClipboardCache(aTransferable, aWhichClipboard))) {
// maybe try to fill in more types? Is there a point?
if (!CheckClipboardContentAnalysisSync(aWindowContext->Canonical(),
aTransferable)) {
aTransferable->ClearAllData();
return NS_ERROR_CONTENT_BLOCKED;
}
return NS_OK;
}
// at this point we can't satisfy the request from cache data so let's look
// for things other people put on the system clipboard
}
nsresult rv = GetNativeClipboardData(aTransferable, aWhichClipboard);
if (NS_FAILED(rv)) {
return rv;
}
if (!CheckClipboardContentAnalysisSync(aWindowContext->Canonical(),
aTransferable)) {
aTransferable->ClearAllData();
return NS_ERROR_CONTENT_BLOCKED;
}
return NS_OK;
return GetNativeClipboardData(aTransferable, aWhichClipboard);
}
void nsBaseClipboard::MaybeRetryGetAvailableFlavors(
const nsTArray<nsCString>& aFlavorList, int32_t aWhichClipboard,
nsIAsyncClipboardGetCallback* aCallback, int32_t aRetryCount,
mozilla::dom::WindowContext* aRequestingWindowContext) {
nsIAsyncClipboardGetCallback* aCallback, int32_t aRetryCount) {
// Note we have to get the clipboard sequence number first before the actual
// read. This is to use it to verify the clipboard data is still the one we
// try to read, instead of the later state.
@ -693,9 +443,8 @@ void nsBaseClipboard::MaybeRetryGetAvailableFlavors(
AsyncHasNativeClipboardDataMatchingFlavors(
aFlavorList, aWhichClipboard,
[self = RefPtr{this}, callback = nsCOMPtr{aCallback}, aWhichClipboard,
aRetryCount, flavorList = aFlavorList.Clone(), sequenceNumber,
requestingWindowContext =
RefPtr{aRequestingWindowContext}](auto aFlavorsOrError) {
aRetryCount, flavorList = aFlavorList.Clone(),
sequenceNumber](auto aFlavorsOrError) {
if (aFlavorsOrError.isErr()) {
MOZ_CLIPBOARD_LOG(
"%s: unable to get available flavors for clipboard %d.",
@ -718,8 +467,7 @@ void nsBaseClipboard::MaybeRetryGetAvailableFlavors(
auto asyncGetClipboardData =
mozilla::MakeRefPtr<AsyncGetClipboardData>(
aWhichClipboard, sequenceNumber,
std::move(aFlavorsOrError.unwrap()), false, self,
requestingWindowContext);
std::move(aFlavorsOrError.unwrap()), false, self);
callback->OnSuccess(asyncGetClipboardData);
return;
}
@ -730,8 +478,7 @@ void nsBaseClipboard::MaybeRetryGetAvailableFlavors(
"doesn't match, retry (%d) ..",
__FUNCTION__, aWhichClipboard, aRetryCount);
self->MaybeRetryGetAvailableFlavors(flavorList, aWhichClipboard,
callback, aRetryCount - 1,
requestingWindowContext);
callback, aRetryCount - 1);
return;
}
@ -763,8 +510,7 @@ NS_IMETHODIMP nsBaseClipboard::AsyncGetData(
dom_events_testing_asyncClipboard_DoNotUseDirectly() ||
nsContentUtils::PrincipalHasPermission(*aRequestingPrincipal,
nsGkAtoms::clipboardRead)) {
AsyncGetDataInternal(aFlavorList, aWhichClipboard, aRequestingWindowContext,
aCallback);
AsyncGetDataInternal(aFlavorList, aWhichClipboard, aCallback);
return NS_OK;
}
@ -778,8 +524,7 @@ NS_IMETHODIMP nsBaseClipboard::AsyncGetData(
if (aRequestingPrincipal->Subsumes(principal)) {
MOZ_CLIPBOARD_LOG("%s: native clipboard data is from same-origin page.",
__FUNCTION__);
AsyncGetDataInternal(aFlavorList, aWhichClipboard,
aRequestingWindowContext, aCallback);
AsyncGetDataInternal(aFlavorList, aWhichClipboard, aCallback);
return NS_OK;
}
}
@ -799,7 +544,6 @@ NS_IMETHODIMP nsBaseClipboard::AsyncGetData(
void nsBaseClipboard::AsyncGetDataInternal(
const nsTArray<nsCString>& aFlavorList, int32_t aClipboardType,
mozilla::dom::WindowContext* aRequestingWindowContext,
nsIAsyncClipboardGetCallback* aCallback) {
MOZ_ASSERT(nsIClipboard::IsClipboardTypeSupported(aClipboardType));
@ -832,7 +576,7 @@ void nsBaseClipboard::AsyncGetDataInternal(
// be found in cache?
auto asyncGetClipboardData = mozilla::MakeRefPtr<AsyncGetClipboardData>(
aClipboardType, clipboardCache->GetSequenceNumber(),
std::move(results), true, this, aRequestingWindowContext);
std::move(results), true, this);
aCallback->OnSuccess(asyncGetClipboardData);
return;
}
@ -843,8 +587,7 @@ void nsBaseClipboard::AsyncGetDataInternal(
}
MaybeRetryGetAvailableFlavors(aFlavorList, aClipboardType, aCallback,
kGetAvailableFlavorsRetryCount,
aRequestingWindowContext);
kGetAvailableFlavorsRetryCount);
}
NS_IMETHODIMP nsBaseClipboard::EmptyClipboard(int32_t aWhichClipboard) {
@ -1047,8 +790,8 @@ void nsBaseClipboard::RequestUserConfirmation(
// If there is a pending user confirmation request, check if we could reuse
// it. If not, reject the request.
if (sUserConfirmationRequest) {
if (sUserConfirmationRequest->IsEqual(
aClipboardType, chromeDoc, aRequestingPrincipal, aWindowContext)) {
if (sUserConfirmationRequest->IsEqual(aClipboardType, chromeDoc,
aRequestingPrincipal)) {
sUserConfirmationRequest->AddClipboardGetRequest(aFlavorList, aCallback);
return;
}
@ -1073,7 +816,7 @@ void nsBaseClipboard::RequestUserConfirmation(
}
sUserConfirmationRequest = new UserConfirmationRequest(
aClipboardType, chromeDoc, aRequestingPrincipal, this, aWindowContext);
aClipboardType, chromeDoc, aRequestingPrincipal, this);
sUserConfirmationRequest->AddClipboardGetRequest(aFlavorList, aCallback);
promise->AppendNativeHandler(sUserConfirmationRequest);
}
@ -1084,14 +827,12 @@ NS_IMPL_ISUPPORTS(nsBaseClipboard::AsyncGetClipboardData,
nsBaseClipboard::AsyncGetClipboardData::AsyncGetClipboardData(
int32_t aClipboardType, int32_t aSequenceNumber,
nsTArray<nsCString>&& aFlavors, bool aFromCache,
nsBaseClipboard* aClipboard,
mozilla::dom::WindowContext* aRequestingWindowContext)
nsBaseClipboard* aClipboard)
: mClipboardType(aClipboardType),
mSequenceNumber(aSequenceNumber),
mFlavors(std::move(aFlavors)),
mFromCache(aFromCache),
mClipboard(aClipboard),
mRequestingWindowContext(aRequestingWindowContext) {
mClipboard(aClipboard) {
MOZ_ASSERT(mClipboard);
MOZ_ASSERT(
mClipboard->nsIClipboard::IsClipboardTypeSupported(mClipboardType));
@ -1138,19 +879,6 @@ NS_IMETHODIMP nsBaseClipboard::AsyncGetClipboardData::GetData(
MOZ_ASSERT(mClipboard);
auto contentAnalysisCallback =
mozilla::MakeRefPtr<SafeContentAnalysisResultCallback>(
[transferable = nsCOMPtr{aTransferable},
callback = nsCOMPtr{aCallback}](
RefPtr<nsIContentAnalysisResult>&& aResult) {
if (aResult->GetShouldAllowContent()) {
callback->OnComplete(NS_OK);
} else {
transferable->ClearAllData();
callback->OnComplete(NS_ERROR_CONTENT_BLOCKED);
}
});
if (mFromCache) {
const auto* clipboardCache =
mClipboard->GetClipboardCacheIfValid(mClipboardType);
@ -1160,8 +888,7 @@ NS_IMETHODIMP nsBaseClipboard::AsyncGetClipboardData::GetData(
MOZ_DIAGNOSTIC_ASSERT(clipboardCache->GetSequenceNumber() ==
mSequenceNumber);
if (NS_SUCCEEDED(clipboardCache->GetData(aTransferable))) {
CheckClipboardContentAnalysis(mRequestingWindowContext->Canonical(),
aTransferable, contentAnalysisCallback);
aCallback->OnComplete(NS_OK);
return NS_OK;
}
@ -1173,23 +900,10 @@ NS_IMETHODIMP nsBaseClipboard::AsyncGetClipboardData::GetData(
// valid after we get the result.
mClipboard->AsyncGetNativeClipboardData(
aTransferable, mClipboardType,
[callback = nsCOMPtr{aCallback}, self = RefPtr{this},
transferable = nsCOMPtr{aTransferable},
contentAnalysisCallback =
std::move(contentAnalysisCallback)](nsresult aResult) mutable {
if (NS_FAILED(aResult)) {
callback->OnComplete(aResult);
return;
}
[callback = nsCOMPtr{aCallback}, self = RefPtr{this}](nsresult aResult) {
// `IsValid()` checks the clipboard sequence number to ensure the data
// we are requesting is still valid.
if (!self->IsValid()) {
callback->OnComplete(NS_ERROR_FAILURE);
return;
}
CheckClipboardContentAnalysis(
self->mRequestingWindowContext->Canonical(), transferable,
contentAnalysisCallback);
callback->OnComplete(self->IsValid() ? aResult : NS_ERROR_FAILURE);
});
return NS_OK;
}

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

@ -47,9 +47,8 @@ class nsBaseClipboard : public nsIClipboard {
NS_IMETHOD AsyncSetData(int32_t aWhichClipboard,
nsIAsyncClipboardRequestCallback* aCallback,
nsIAsyncSetClipboardData** _retval) override final;
NS_IMETHOD GetData(
nsITransferable* aTransferable, int32_t aWhichClipboard,
mozilla::dom::WindowContext* aWindowContext) override final;
NS_IMETHOD GetData(nsITransferable* aTransferable,
int32_t aWhichClipboard) override final;
NS_IMETHOD AsyncGetData(
const nsTArray<nsCString>& aFlavorList, int32_t aWhichClipboard,
mozilla::dom::WindowContext* aRequestingWindowContext,
@ -62,10 +61,9 @@ class nsBaseClipboard : public nsIClipboard {
NS_IMETHOD IsClipboardTypeSupported(int32_t aWhichClipboard,
bool* aRetval) override final;
void AsyncGetDataInternal(
const nsTArray<nsCString>& aFlavorList, int32_t aClipboardType,
mozilla::dom::WindowContext* aRequestingWindowContext,
nsIAsyncClipboardGetCallback* aCallback);
void AsyncGetDataInternal(const nsTArray<nsCString>& aFlavorList,
int32_t aClipboardType,
nsIAsyncClipboardGetCallback* aCallback);
using GetDataCallback = mozilla::MoveOnlyFunction<void(nsresult)>;
using HasMatchingFlavorsCallback = mozilla::MoveOnlyFunction<void(
@ -126,11 +124,9 @@ class nsBaseClipboard : public nsIClipboard {
class AsyncGetClipboardData final : public nsIAsyncGetClipboardData {
public:
AsyncGetClipboardData(
int32_t aClipboardType, int32_t aSequenceNumber,
nsTArray<nsCString>&& aFlavors, bool aFromCache,
nsBaseClipboard* aClipboard,
mozilla::dom::WindowContext* aRequestingWindowContext);
AsyncGetClipboardData(int32_t aClipboardType, int32_t aSequenceNumber,
nsTArray<nsCString>&& aFlavors, bool aFromCache,
nsBaseClipboard* aClipboard);
NS_DECL_ISUPPORTS
NS_DECL_NSIASYNCGETCLIPBOARDDATA
@ -151,8 +147,6 @@ class nsBaseClipboard : public nsIClipboard {
const bool mFromCache;
// This is also used to indicate whether this request is still valid.
RefPtr<nsBaseClipboard> mClipboard;
// The requesting window, which is used for Content Analysis purposes.
RefPtr<mozilla::dom::WindowContext> mRequestingWindowContext;
};
class ClipboardCache final {
@ -186,10 +180,10 @@ class nsBaseClipboard : public nsIClipboard {
int32_t mSequenceNumber = -1;
};
void MaybeRetryGetAvailableFlavors(
const nsTArray<nsCString>& aFlavorList, int32_t aWhichClipboard,
nsIAsyncClipboardGetCallback* aCallback, int32_t aRetryCount,
mozilla::dom::WindowContext* aRequestingWindowContext);
void MaybeRetryGetAvailableFlavors(const nsTArray<nsCString>& aFlavorList,
int32_t aWhichClipboard,
nsIAsyncClipboardGetCallback* aCallback,
int32_t aRetryCount);
// Return clipboard cache if the cached data is valid, otherwise clear the
// cached data and returns null.

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

@ -12,7 +12,6 @@
#include "mozilla/dom/ContentChild.h"
#include "mozilla/net/CookieJarSettings.h"
#include "mozilla/Maybe.h"
#include "mozilla/dom/WindowGlobalChild.h"
#include "mozilla/Unused.h"
#include "nsArrayUtils.h"
#include "nsBaseClipboard.h"
@ -58,20 +57,13 @@ NS_IMETHODIMP nsClipboardProxy::AsyncSetData(
NS_IMETHODIMP
nsClipboardProxy::GetData(nsITransferable* aTransferable,
int32_t aWhichClipboard,
mozilla::dom::WindowContext* aWindowContext) {
MOZ_DIAGNOSTIC_ASSERT(aWindowContext && aWindowContext->IsInProcess(),
"content clipboard reads must be associated with an "
"in-process WindowContext");
if (aWindowContext->IsDiscarded()) {
return NS_ERROR_NOT_AVAILABLE;
}
int32_t aWhichClipboard) {
nsTArray<nsCString> types;
aTransferable->FlavorsTransferableCanImport(types);
IPCTransferableData transferable;
ContentChild::GetSingleton()->SendGetClipboard(types, aWhichClipboard,
aWindowContext, &transferable);
&transferable);
return nsContentUtils::IPCTransferableDataToTransferable(
transferable, false /* aAddDataFlavor */, aTransferable,
false /* aFilterUnknownFlavors */);

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

@ -145,20 +145,14 @@ interface nsIClipboard : nsISupports
*
* @param aTransferable The transferable
* @param aWhichClipboard Specifies the clipboard to which this operation applies.
* @param aRequestingWindowContext [optional]
* The window context window that is requesting the clipboard, which is
* used for content analysis. Passing null means that the content is
* exempt from content analysis. (for example, scripted clipboard read by
* system code) This parameter should not be null when calling this from a
* content process.
* @result NS_OK if no errors
*/
void getData ( in nsITransferable aTransferable, in long aWhichClipboard, [optional] in WindowContext aRequestingWindowContext) ;
void getData ( in nsITransferable aTransferable, in long aWhichClipboard ) ;
/**
* Requests getting data asynchronously from the native clipboard. This does
* not actually retrieve the data, but returns a nsIAsyncGetClipboardData
* not actually retreive the data, but returns a nsIAsyncGetClipboardData
* contains current avaiable data formats. If the native clipboard is
* updated, either by us or other application, the existing
* nsIAsyncGetClipboardData becomes invalid.

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

@ -168,11 +168,6 @@ interface nsITransferable : nsISupports
*/
void setTransferData(in string aFlavor, in nsISupports aData);
/**
* Removes the data from all flavors.
*/
void clearAllData();
/**
* Add the data flavor, indicating that this transferable
* can receive this type of flavor

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

@ -110,14 +110,6 @@ void DataStruct::GetData(nsISupports** aData) {
data.forget(aData);
}
//-------------------------------------------------------------------------
void DataStruct::ClearData() {
if (mCacheFD) {
PR_Close(mCacheFD);
}
mData = nullptr;
}
//-------------------------------------------------------------------------
nsresult DataStruct::WriteCache(void* aData, uint32_t aDataLen) {
MOZ_ASSERT(aData && aDataLen);
@ -374,14 +366,6 @@ nsTransferable::SetTransferData(const char* aFlavor, nsISupports* aData) {
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsTransferable::ClearAllData() {
for (auto& entry : mDataArray) {
entry.ClearData();
}
return NS_OK;
}
//
// AddDataFlavor
//

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

@ -33,7 +33,6 @@ struct DataStruct {
const nsCString& GetFlavor() const { return mFlavor; }
void SetData(nsISupports* aData, bool aIsPrivateData);
void GetData(nsISupports** aData);
void ClearData();
bool IsDataAvailable() const { return mData || mCacheFD; }
protected:

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

@ -717,19 +717,25 @@ nsFilePicker::CheckContentAnalysisService() {
__func__);
}
nsCOMPtr<nsIURI> uri = mBrowsingContext->Canonical()->GetCurrentURI();
RefPtr<nsIURI> uri = mBrowsingContext->Canonical()->GetCurrentURI();
nsCString uriCString;
rv = uri->GetSpec(uriCString);
if (NS_WARN_IF(NS_FAILED(rv))) {
return nsFilePicker::ContentAnalysisResponse::CreateAndReject(rv, __func__);
}
nsString uriString = NS_ConvertUTF8toUTF16(uriCString);
auto processOneItem = [self = RefPtr{this},
contentAnalysis = std::move(contentAnalysis),
uri =
std::move(uri)](const mozilla::PathString& aItem) {
uriString = std::move(uriString)](
const mozilla::PathString& aItem) {
nsCString emptyDigestString;
auto* windowGlobal =
self->mBrowsingContext->Canonical()->GetCurrentWindowGlobal();
nsCOMPtr<nsIContentAnalysisRequest> contentAnalysisRequest(
new mozilla::contentanalysis::ContentAnalysisRequest(
nsIContentAnalysisRequest::AnalysisType::eFileAttached, aItem, true,
std::move(emptyDigestString), uri,
std::move(emptyDigestString), uriString,
nsIContentAnalysisRequest::OperationType::eCustomDisplayString,
windowGlobal));
@ -744,8 +750,7 @@ nsFilePicker::CheckContentAnalysisService() {
[promise](nsresult aError) { promise->Reject(aError, __func__); });
nsresult rv = contentAnalysis->AnalyzeContentRequestCallback(
contentAnalysisRequest, /* aAutoAcknowledge */ true,
contentAnalysisCallback);
contentAnalysisRequest, true, contentAnalysisCallback);
if (NS_WARN_IF(NS_FAILED(rv))) {
promise->Reject(rv, __func__);
}