forked from mirrors/gecko-dev
Bug 1869868 part 2 - do not consult DLP when copy/pasting items in the same tab r=edgar,dlp-reviewers,credential-management-reviewers,handyman,sgalich
Differential Revision: https://phabricator.services.mozilla.com/D205744
This commit is contained in:
parent
8ee343bb45
commit
37d28f9cf5
25 changed files with 205 additions and 70 deletions
|
|
@ -2175,7 +2175,10 @@ class nsContextMenu {
|
|||
var clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(
|
||||
Ci.nsIClipboardHelper
|
||||
);
|
||||
clipboard.copyString(addresses);
|
||||
clipboard.copyString(
|
||||
addresses,
|
||||
this.actor.manager.browsingContext.currentWindowGlobal
|
||||
);
|
||||
}
|
||||
|
||||
// Extract phone and put it on clipboard
|
||||
|
|
@ -2195,7 +2198,10 @@ class nsContextMenu {
|
|||
var clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(
|
||||
Ci.nsIClipboardHelper
|
||||
);
|
||||
clipboard.copyString(phone);
|
||||
clipboard.copyString(
|
||||
phone,
|
||||
this.actor.manager.browsingContext.currentWindowGlobal
|
||||
);
|
||||
}
|
||||
|
||||
copyLink() {
|
||||
|
|
@ -2204,7 +2210,10 @@ class nsContextMenu {
|
|||
var clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(
|
||||
Ci.nsIClipboardHelper
|
||||
);
|
||||
clipboard.copyString(linkURL);
|
||||
clipboard.copyString(
|
||||
linkURL,
|
||||
this.actor.manager.browsingContext.currentWindowGlobal
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2220,7 +2229,10 @@ class nsContextMenu {
|
|||
let clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(
|
||||
Ci.nsIClipboardHelper
|
||||
);
|
||||
clipboard.copyString(strippedLinkURL);
|
||||
clipboard.copyString(
|
||||
strippedLinkURL,
|
||||
this.actor.manager.browsingContext.currentWindowGlobal
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2458,7 +2470,10 @@ class nsContextMenu {
|
|||
var clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(
|
||||
Ci.nsIClipboardHelper
|
||||
);
|
||||
clipboard.copyString(this.originalMediaURL);
|
||||
clipboard.copyString(
|
||||
this.originalMediaURL,
|
||||
this.actor.manager.browsingContext.currentWindowGlobal
|
||||
);
|
||||
}
|
||||
|
||||
getImageText() {
|
||||
|
|
|
|||
|
|
@ -160,7 +160,11 @@ export class AboutLoginsChild extends JSWindowActorChild {
|
|||
}
|
||||
|
||||
#aboutLoginsCopyLoginDetail(detail) {
|
||||
lazy.ClipboardHelper.copyString(detail, lazy.ClipboardHelper.Sensitive);
|
||||
lazy.ClipboardHelper.copyString(
|
||||
detail,
|
||||
this.windowContext,
|
||||
lazy.ClipboardHelper.Sensitive
|
||||
);
|
||||
}
|
||||
|
||||
#aboutLoginsCreateLogin(login) {
|
||||
|
|
|
|||
|
|
@ -553,6 +553,7 @@ export var Policies = {
|
|||
["IsPerUser", "is_per_user"],
|
||||
["ShowBlockedResult", "show_blocked_result"],
|
||||
["DefaultAllow", "default_allow"],
|
||||
["BypassForSameTabOperations", "bypass_for_same_tab_operations"],
|
||||
];
|
||||
for (let pref of boolPrefs) {
|
||||
if (pref[0] in param) {
|
||||
|
|
|
|||
|
|
@ -267,6 +267,9 @@
|
|||
},
|
||||
"DefaultAllow": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"BypassForSameTabOperations": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -332,7 +332,8 @@ static nsresult PutToClipboard(
|
|||
rv = CreateTransferable(aEncodedDocumentWithContext, aDocument, transferable);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = clipboard->SetData(transferable, nullptr, aClipboardID);
|
||||
rv = clipboard->SetData(transferable, nullptr, aClipboardID,
|
||||
aDocument.GetWindowContext());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return rv;
|
||||
|
|
@ -455,9 +456,9 @@ nsresult nsCopySupport::GetContents(const nsACString& aMimeType,
|
|||
return docEncoder->EncodeToString(outdata);
|
||||
}
|
||||
|
||||
nsresult nsCopySupport::ImageCopy(nsIImageLoadingContent* aImageElement,
|
||||
nsILoadContext* aLoadContext,
|
||||
int32_t aCopyFlags) {
|
||||
nsresult nsCopySupport::ImageCopy(
|
||||
nsIImageLoadingContent* aImageElement, nsILoadContext* aLoadContext,
|
||||
int32_t aCopyFlags, mozilla::dom::WindowContext* aSettingWindowContext) {
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsINode> imageNode = do_QueryInterface(aImageElement, &rv);
|
||||
|
|
@ -527,11 +528,13 @@ nsresult nsCopySupport::ImageCopy(nsIImageLoadingContent* aImageElement,
|
|||
// check whether the system supports the selection clipboard or not.
|
||||
if (clipboard->IsClipboardTypeSupported(nsIClipboard::kSelectionClipboard)) {
|
||||
// put the transferable on the clipboard
|
||||
rv = clipboard->SetData(trans, nullptr, nsIClipboard::kSelectionClipboard);
|
||||
rv = clipboard->SetData(trans, nullptr, nsIClipboard::kSelectionClipboard,
|
||||
aSettingWindowContext);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return clipboard->SetData(trans, nullptr, nsIClipboard::kGlobalClipboard);
|
||||
return clipboard->SetData(trans, nullptr, nsIClipboard::kGlobalClipboard,
|
||||
aSettingWindowContext);
|
||||
}
|
||||
|
||||
static nsresult AppendString(nsITransferable* aTransferable,
|
||||
|
|
@ -928,7 +931,12 @@ bool nsCopySupport::FireClipboardEvent(EventMessage aEventMessage,
|
|||
NS_ENSURE_TRUE(transferable, false);
|
||||
|
||||
// put the transferable on the clipboard
|
||||
nsresult rv = clipboard->SetData(transferable, nullptr, aClipboardType);
|
||||
WindowContext* settingWindowContext = nullptr;
|
||||
if (aPresShell && aPresShell->GetDocument()) {
|
||||
settingWindowContext = aPresShell->GetDocument()->GetWindowContext();
|
||||
}
|
||||
nsresult rv = clipboard->SetData(transferable, nullptr, aClipboardType,
|
||||
settingWindowContext);
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ class PresShell;
|
|||
namespace dom {
|
||||
class Document;
|
||||
class Selection;
|
||||
class WindowContext;
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
@ -46,7 +47,8 @@ class nsCopySupport {
|
|||
mozilla::dom::Document* aDoc, nsAString& outdata);
|
||||
|
||||
static nsresult ImageCopy(nsIImageLoadingContent* aImageElement,
|
||||
nsILoadContext* aLoadContext, int32_t aCopyFlags);
|
||||
nsILoadContext* aLoadContext, int32_t aCopyFlags,
|
||||
mozilla::dom::WindowContext* aSettingWindowContext);
|
||||
|
||||
// Get the selection as a transferable.
|
||||
// @param aSelection Can be nullptr.
|
||||
|
|
|
|||
|
|
@ -731,7 +731,8 @@ already_AddRefed<Promise> Clipboard::Write(
|
|||
RefPtr<ClipboardWriteCallback> callback =
|
||||
MakeRefPtr<ClipboardWriteCallback>(p, aData[0]);
|
||||
nsresult rv = clipboard->AsyncSetData(nsIClipboard::kGlobalClipboard,
|
||||
callback, getter_AddRefs(request));
|
||||
owner->GetWindowContext(), callback,
|
||||
getter_AddRefs(request));
|
||||
if (NS_FAILED(rv)) {
|
||||
p->MaybeReject(rv);
|
||||
return p.forget();
|
||||
|
|
|
|||
|
|
@ -3409,7 +3409,8 @@ void ContentParent::OnVarChanged(const GfxVarUpdate& aVar) {
|
|||
}
|
||||
|
||||
mozilla::ipc::IPCResult ContentParent::RecvSetClipboard(
|
||||
const IPCTransferable& aTransferable, const int32_t& aWhichClipboard) {
|
||||
const IPCTransferable& aTransferable, const int32_t& aWhichClipboard,
|
||||
const MaybeDiscarded<WindowContext>& aRequestingWindowContext) {
|
||||
// aRequestingPrincipal is allowed to be nullptr here.
|
||||
|
||||
if (!ValidatePrincipal(aTransferable.requestingPrincipal(),
|
||||
|
|
@ -3434,7 +3435,12 @@ mozilla::ipc::IPCResult ContentParent::RecvSetClipboard(
|
|||
true /* aFilterUnknownFlavors */);
|
||||
NS_ENSURE_SUCCESS(rv, IPC_OK());
|
||||
|
||||
clipboard->SetData(trans, nullptr, aWhichClipboard);
|
||||
// OK if this is null
|
||||
RefPtr<WindowGlobalParent> window;
|
||||
if (!aRequestingWindowContext.IsDiscarded()) {
|
||||
window = aRequestingWindowContext.get_canonical();
|
||||
}
|
||||
clipboard->SetData(trans, nullptr, aWhichClipboard, window);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
|
@ -3682,10 +3688,15 @@ mozilla::ipc::IPCResult ContentParent::RecvGetClipboardDataSnapshotSync(
|
|||
|
||||
already_AddRefed<PClipboardWriteRequestParent>
|
||||
ContentParent::AllocPClipboardWriteRequestParent(
|
||||
const int32_t& aClipboardType) {
|
||||
const int32_t& aClipboardType,
|
||||
const MaybeDiscarded<WindowContext>& aSettingWindowContext) {
|
||||
WindowContext* settingWindowContext = nullptr;
|
||||
if (!aSettingWindowContext.IsDiscarded()) {
|
||||
settingWindowContext = aSettingWindowContext.get();
|
||||
}
|
||||
RefPtr<ClipboardWriteRequestParent> request =
|
||||
MakeAndAddRef<ClipboardWriteRequestParent>(this);
|
||||
request->Init(aClipboardType);
|
||||
request->Init(aClipboardType, settingWindowContext);
|
||||
return request.forget();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -949,8 +949,9 @@ class ContentParent final : public PContentParent,
|
|||
PBrowserParent* aBrowser,
|
||||
const MaybeDiscarded<BrowsingContext>& aContext);
|
||||
|
||||
mozilla::ipc::IPCResult RecvSetClipboard(const IPCTransferable& aTransferable,
|
||||
const int32_t& aWhichClipboard);
|
||||
mozilla::ipc::IPCResult RecvSetClipboard(
|
||||
const IPCTransferable& aTransferable, const int32_t& aWhichClipboard,
|
||||
const MaybeDiscarded<WindowContext>& aRequestingWindowContext);
|
||||
|
||||
mozilla::ipc::IPCResult RecvGetClipboard(
|
||||
nsTArray<nsCString>&& aTypes, const int32_t& aWhichClipboard,
|
||||
|
|
@ -975,7 +976,9 @@ class ContentParent final : public PContentParent,
|
|||
ClipboardReadRequestOrError* aRequestOrError);
|
||||
|
||||
already_AddRefed<PClipboardWriteRequestParent>
|
||||
AllocPClipboardWriteRequestParent(const int32_t& aClipboardType);
|
||||
AllocPClipboardWriteRequestParent(
|
||||
const int32_t& aClipboardType,
|
||||
const MaybeDiscarded<WindowContext>& aSettingWindowContext);
|
||||
|
||||
mozilla::ipc::IPCResult RecvGetIconForExtension(const nsACString& aFileExt,
|
||||
const uint32_t& aIconSize,
|
||||
|
|
|
|||
|
|
@ -1219,7 +1219,7 @@ parent:
|
|||
|
||||
// Places the items within dataTransfer on the clipboard.
|
||||
async SetClipboard(IPCTransferable aTransferable,
|
||||
int32_t aWhichClipboard);
|
||||
int32_t aWhichClipboard, MaybeDiscardedWindowContext aRequestingWindowContext);
|
||||
|
||||
// Given a list of supported types, returns the clipboard data for the
|
||||
// first type that matches.
|
||||
|
|
@ -1252,8 +1252,12 @@ parent:
|
|||
* and that the data will be sent over another IPC message once it is ready.
|
||||
* @param aClipboardType
|
||||
* The clipboard type defined in nsIClipboard.
|
||||
* @param aSettingWindowContext
|
||||
* The window context that is setting the clipboard, if any. This is used
|
||||
* to possibly bypass Content Analysis if a set clipboard and get clipboard
|
||||
* operation are done on the same page.
|
||||
*/
|
||||
async PClipboardWriteRequest(int32_t aClipboardType);
|
||||
async PClipboardWriteRequest(int32_t aClipboardType, MaybeDiscardedWindowContext aSettingWindowContext);
|
||||
|
||||
sync GetIconForExtension(nsCString aFileExt, uint32_t aIconSize)
|
||||
returns (uint8_t[] bits);
|
||||
|
|
|
|||
|
|
@ -1265,7 +1265,7 @@ nsresult gfxUtils::EncodeSourceSurface(SourceSurface* aSurface,
|
|||
nsCOMPtr<nsIClipboardHelper> clipboard(
|
||||
do_GetService("@mozilla.org/widget/clipboardhelper;1", &rv));
|
||||
if (clipboard) {
|
||||
clipboard->CopyString(NS_ConvertASCIItoUTF16(dataURI));
|
||||
clipboard->CopyString(NS_ConvertASCIItoUTF16(dataURI), nullptr);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
|
|
|
|||
|
|
@ -2426,7 +2426,7 @@ NS_IMETHODIMP nsDocumentViewer::CopyLinkLocation() {
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// copy the href onto the clipboard
|
||||
return clipboard->CopyString(locationText);
|
||||
return clipboard->CopyString(locationText, mDocument->GetWindowContext());
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocumentViewer::CopyImage(int32_t aCopyFlags) {
|
||||
|
|
@ -2436,7 +2436,8 @@ NS_IMETHODIMP nsDocumentViewer::CopyImage(int32_t aCopyFlags) {
|
|||
NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsILoadContext> loadContext(mContainer);
|
||||
return nsCopySupport::ImageCopy(node, loadContext, aCopyFlags);
|
||||
return nsCopySupport::ImageCopy(node, loadContext, aCopyFlags,
|
||||
mDocument->GetWindowContext());
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocumentViewer::GetCopyable(bool* aCopyable) {
|
||||
|
|
|
|||
|
|
@ -1211,6 +1211,13 @@
|
|||
value: true
|
||||
mirror: always
|
||||
|
||||
# Should Firefox bypass content analysis for pastes and drags whose source
|
||||
# is the same tab?
|
||||
- name: browser.contentanalysis.bypass_for_same_tab_operations
|
||||
type: bool
|
||||
value: false
|
||||
mirror: always
|
||||
|
||||
# Content blocking for Enhanced Tracking Protection
|
||||
- name: browser.contentblocking.database.enabled
|
||||
type: bool
|
||||
|
|
|
|||
|
|
@ -816,6 +816,7 @@ NS_IMETHODIMP ContentAnalysisResult::GetShouldAllowContent(
|
|||
ALLOW_DUE_TO_CONTENT_ANALYSIS_NOT_ACTIVE ||
|
||||
result == NoContentAnalysisResult::
|
||||
ALLOW_DUE_TO_CONTEXT_EXEMPT_FROM_CONTENT_ANALYSIS ||
|
||||
result == NoContentAnalysisResult::ALLOW_DUE_TO_SAME_TAB_SOURCE ||
|
||||
result == NoContentAnalysisResult::ALLOW_DUE_TO_COULD_NOT_GET_DATA;
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ namespace contentanalysis {
|
|||
enum class NoContentAnalysisResult : uint8_t {
|
||||
ALLOW_DUE_TO_CONTENT_ANALYSIS_NOT_ACTIVE,
|
||||
ALLOW_DUE_TO_CONTEXT_EXEMPT_FROM_CONTENT_ANALYSIS,
|
||||
ALLOW_DUE_TO_SAME_TAB_SOURCE,
|
||||
ALLOW_DUE_TO_COULD_NOT_GET_DATA,
|
||||
DENY_DUE_TO_CANCELED,
|
||||
DENY_DUE_TO_INVALID_JSON_RESPONSE,
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ const kClientSignaturePref = "client_signature";
|
|||
const kPerUserPref = "is_per_user";
|
||||
const kShowBlockedPref = "show_blocked_result";
|
||||
const kDefaultAllowPref = "default_allow";
|
||||
const kBypassForSameTabOperationsPref = "bypass_for_same_tab_operations";
|
||||
|
||||
const ca = Cc["@mozilla.org/contentanalysis;1"].getService(
|
||||
Ci.nsIContentAnalysis
|
||||
|
|
@ -88,6 +89,7 @@ add_task(async function test_ca_enterprise_config() {
|
|||
IsPerUser: true,
|
||||
ShowBlockedResult: false,
|
||||
DefaultAllow: true,
|
||||
BypassForSameTabOperations: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
@ -139,6 +141,13 @@ add_task(async function test_ca_enterprise_config() {
|
|||
true,
|
||||
"default allow match"
|
||||
);
|
||||
is(
|
||||
Services.prefs.getBoolPref(
|
||||
"browser.contentanalysis." + kBypassForSameTabOperationsPref
|
||||
),
|
||||
true,
|
||||
"bypass for same tab operations match"
|
||||
);
|
||||
PoliciesPrefTracker.stop();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,9 @@ ClipboardWriteRequestParent::ClipboardWriteRequestParent(
|
|||
|
||||
ClipboardWriteRequestParent::~ClipboardWriteRequestParent() = default;
|
||||
|
||||
nsresult ClipboardWriteRequestParent::Init(const int32_t& aClipboardType) {
|
||||
nsresult ClipboardWriteRequestParent::Init(
|
||||
const int32_t& aClipboardType,
|
||||
mozilla::dom::WindowContext* aSettingWindowContext) {
|
||||
nsCOMPtr<nsIClipboard> clipboard(do_GetService(kCClipboardCID));
|
||||
if (!clipboard) {
|
||||
Unused << PClipboardWriteRequestParent::Send__delete__(this,
|
||||
|
|
@ -35,8 +37,9 @@ nsresult ClipboardWriteRequestParent::Init(const int32_t& aClipboardType) {
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult rv = clipboard->AsyncSetData(aClipboardType, this,
|
||||
getter_AddRefs(mAsyncSetClipboardData));
|
||||
nsresult rv =
|
||||
clipboard->AsyncSetData(aClipboardType, aSettingWindowContext, this,
|
||||
getter_AddRefs(mAsyncSetClipboardData));
|
||||
if (NS_FAILED(rv)) {
|
||||
Unused << PClipboardWriteRequestParent::Send__delete__(this, rv);
|
||||
return rv;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@ class ClipboardWriteRequestParent final
|
|||
|
||||
explicit ClipboardWriteRequestParent(ContentParent* aManager);
|
||||
|
||||
nsresult Init(const int32_t& aClipboardType);
|
||||
nsresult Init(const int32_t& aClipboardType,
|
||||
mozilla::dom::WindowContext* aSettingWindowContext);
|
||||
|
||||
IPCResult RecvSetData(const IPCTransferable& aTransferable);
|
||||
IPCResult Recv__delete__(nsresult aReason);
|
||||
|
|
|
|||
|
|
@ -211,9 +211,11 @@ NS_IMPL_ISUPPORTS(nsBaseClipboard::AsyncSetClipboardData,
|
|||
|
||||
nsBaseClipboard::AsyncSetClipboardData::AsyncSetClipboardData(
|
||||
int32_t aClipboardType, nsBaseClipboard* aClipboard,
|
||||
mozilla::dom::WindowContext* aSettingWindowContext,
|
||||
nsIAsyncClipboardRequestCallback* aCallback)
|
||||
: mClipboardType(aClipboardType),
|
||||
mClipboard(aClipboard),
|
||||
mWindowContext(aSettingWindowContext),
|
||||
mCallback(aCallback) {
|
||||
MOZ_ASSERT(mClipboard);
|
||||
MOZ_ASSERT(
|
||||
|
|
@ -247,7 +249,8 @@ nsBaseClipboard::AsyncSetClipboardData::SetData(nsITransferable* aTransferable,
|
|||
|
||||
RefPtr<AsyncSetClipboardData> request =
|
||||
std::move(mClipboard->mPendingWriteRequests[mClipboardType]);
|
||||
nsresult rv = mClipboard->SetData(aTransferable, aOwner, mClipboardType);
|
||||
nsresult rv = mClipboard->SetData(aTransferable, aOwner, mClipboardType,
|
||||
mWindowContext);
|
||||
MaybeNotifyCallback(rv);
|
||||
|
||||
return rv;
|
||||
|
|
@ -292,7 +295,8 @@ void nsBaseClipboard::RejectPendingAsyncSetDataRequestIfAny(
|
|||
}
|
||||
|
||||
NS_IMETHODIMP nsBaseClipboard::AsyncSetData(
|
||||
int32_t aWhichClipboard, nsIAsyncClipboardRequestCallback* aCallback,
|
||||
int32_t aWhichClipboard, mozilla::dom::WindowContext* aSettingWindowContext,
|
||||
nsIAsyncClipboardRequestCallback* aCallback,
|
||||
nsIAsyncSetClipboardData** _retval) {
|
||||
MOZ_CLIPBOARD_LOG("%s: clipboard=%d", __FUNCTION__, aWhichClipboard);
|
||||
|
||||
|
|
@ -308,8 +312,8 @@ NS_IMETHODIMP nsBaseClipboard::AsyncSetData(
|
|||
|
||||
// Create a new AsyncSetClipboardData.
|
||||
RefPtr<AsyncSetClipboardData> request =
|
||||
mozilla::MakeRefPtr<AsyncSetClipboardData>(aWhichClipboard, this,
|
||||
aCallback);
|
||||
mozilla::MakeRefPtr<AsyncSetClipboardData>(
|
||||
aWhichClipboard, this, aSettingWindowContext, aCallback);
|
||||
mPendingWriteRequests[aWhichClipboard] = request;
|
||||
request.forget(_retval);
|
||||
return NS_OK;
|
||||
|
|
@ -408,7 +412,7 @@ nsBaseClipboard::CheckClipboardContentAnalysisAsFile(
|
|||
|
||||
void nsBaseClipboard::CheckClipboardContentAnalysis(
|
||||
mozilla::dom::WindowGlobalParent* aWindow, nsITransferable* aTransferable,
|
||||
SafeContentAnalysisResultCallback* aResolver) {
|
||||
int32_t aClipboardType, SafeContentAnalysisResultCallback* aResolver) {
|
||||
using namespace mozilla::contentanalysis;
|
||||
|
||||
// Content analysis is only needed if an outside webpage has access to
|
||||
|
|
@ -441,8 +445,24 @@ void nsBaseClipboard::CheckClipboardContentAnalysis(
|
|||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> currentURI = aWindow->Canonical()->GetDocumentURI();
|
||||
uint64_t innerWindowId = aWindow->InnerWindowId();
|
||||
if (mozilla::StaticPrefs::
|
||||
browser_contentanalysis_bypass_for_same_tab_operations()) {
|
||||
const auto* clipboardCache = GetClipboardCacheIfValid(aClipboardType);
|
||||
if (clipboardCache) {
|
||||
if (clipboardCache->GetInnerWindowId().isSome() &&
|
||||
*(clipboardCache->GetInnerWindowId()) == innerWindowId) {
|
||||
// If the same page copied this data to the clipboard (and the above
|
||||
// preference is set) we can skip content analysis and immediately allow
|
||||
// this.
|
||||
aResolver->Callback(ContentAnalysisResult::FromNoResult(
|
||||
NoContentAnalysisResult::ALLOW_DUE_TO_SAME_TAB_SOURCE));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> currentURI = aWindow->Canonical()->GetDocumentURI();
|
||||
nsTArray<nsCString> flavors;
|
||||
rv = aTransferable->FlavorsTransferableCanExport(flavors);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
|
|
@ -482,7 +502,7 @@ void nsBaseClipboard::CheckClipboardContentAnalysis(
|
|||
|
||||
bool nsBaseClipboard::CheckClipboardContentAnalysisSync(
|
||||
mozilla::dom::WindowGlobalParent* aWindow,
|
||||
const nsCOMPtr<nsITransferable>& trans) {
|
||||
const nsCOMPtr<nsITransferable>& trans, int32_t aClipboardType) {
|
||||
bool requestDone = false;
|
||||
RefPtr<nsIContentAnalysisResult> result;
|
||||
auto callback = mozilla::MakeRefPtr<SafeContentAnalysisResultCallback>(
|
||||
|
|
@ -490,7 +510,7 @@ bool nsBaseClipboard::CheckClipboardContentAnalysisSync(
|
|||
result = std::move(aResult);
|
||||
requestDone = true;
|
||||
});
|
||||
CheckClipboardContentAnalysis(aWindow, trans, callback);
|
||||
CheckClipboardContentAnalysis(aWindow, trans, aClipboardType, callback);
|
||||
mozilla::SpinEventLoopUntil("CheckClipboardContentAnalysisSync"_ns,
|
||||
[&requestDone]() -> bool { return requestDone; });
|
||||
return result->GetShouldAllowContent();
|
||||
|
|
@ -527,9 +547,9 @@ NS_IMPL_ISUPPORTS(nsBaseClipboard, nsIClipboard)
|
|||
* Sets the transferable object
|
||||
*
|
||||
*/
|
||||
NS_IMETHODIMP nsBaseClipboard::SetData(nsITransferable* aTransferable,
|
||||
nsIClipboardOwner* aOwner,
|
||||
int32_t aWhichClipboard) {
|
||||
NS_IMETHODIMP nsBaseClipboard::SetData(
|
||||
nsITransferable* aTransferable, nsIClipboardOwner* aOwner,
|
||||
int32_t aWhichClipboard, mozilla::dom::WindowContext* aWindowContext) {
|
||||
NS_ASSERTION(aTransferable, "clipboard given a null transferable");
|
||||
|
||||
MOZ_CLIPBOARD_LOG("%s: clipboard=%d", __FUNCTION__, aWhichClipboard);
|
||||
|
|
@ -580,7 +600,10 @@ NS_IMETHODIMP nsBaseClipboard::SetData(nsITransferable* aTransferable,
|
|||
return result.unwrapErr();
|
||||
}
|
||||
|
||||
clipboardCache->Update(aTransferable, aOwner, result.unwrap());
|
||||
clipboardCache->Update(aTransferable, aOwner, result.unwrap(),
|
||||
aWindowContext
|
||||
? mozilla::Some(aWindowContext->InnerWindowId())
|
||||
: mozilla::Nothing());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
@ -623,7 +646,7 @@ NS_IMETHODIMP nsBaseClipboard::GetData(
|
|||
GetDataFromClipboardCache(aTransferable, aWhichClipboard))) {
|
||||
// maybe try to fill in more types? Is there a point?
|
||||
if (!CheckClipboardContentAnalysisSync(aWindowContext->Canonical(),
|
||||
aTransferable)) {
|
||||
aTransferable, aWhichClipboard)) {
|
||||
aTransferable->ClearAllData();
|
||||
return NS_ERROR_CONTENT_BLOCKED;
|
||||
}
|
||||
|
|
@ -638,7 +661,7 @@ NS_IMETHODIMP nsBaseClipboard::GetData(
|
|||
return rv;
|
||||
}
|
||||
if (!CheckClipboardContentAnalysisSync(aWindowContext->Canonical(),
|
||||
aTransferable)) {
|
||||
aTransferable, aWhichClipboard)) {
|
||||
aTransferable->ClearAllData();
|
||||
return NS_ERROR_CONTENT_BLOCKED;
|
||||
}
|
||||
|
|
@ -1203,7 +1226,7 @@ NS_IMETHODIMP nsBaseClipboard::AsyncGetClipboardData::GetData(
|
|||
mClipboard->CheckClipboardContentAnalysis(
|
||||
mRequestingWindowContext ? mRequestingWindowContext->Canonical()
|
||||
: nullptr,
|
||||
aTransferable, contentAnalysisCallback);
|
||||
aTransferable, mClipboardType, contentAnalysisCallback);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
@ -1233,7 +1256,7 @@ NS_IMETHODIMP nsBaseClipboard::AsyncGetClipboardData::GetData(
|
|||
self->mRequestingWindowContext
|
||||
? self->mRequestingWindowContext->Canonical()
|
||||
: nullptr,
|
||||
transferable, contentAnalysisCallback);
|
||||
transferable, self->mClipboardType, contentAnalysisCallback);
|
||||
});
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,9 +44,12 @@ class nsBaseClipboard : public nsIClipboard {
|
|||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIClipboard
|
||||
NS_IMETHOD SetData(nsITransferable* aTransferable, nsIClipboardOwner* aOwner,
|
||||
int32_t aWhichClipboard) override final;
|
||||
NS_IMETHOD SetData(
|
||||
nsITransferable* aTransferable, nsIClipboardOwner* aOwner,
|
||||
int32_t aWhichClipboard,
|
||||
mozilla::dom::WindowContext* aWindowContext) override final;
|
||||
NS_IMETHOD AsyncSetData(int32_t aWhichClipboard,
|
||||
mozilla::dom::WindowContext* aSettingWindowContext,
|
||||
nsIAsyncClipboardRequestCallback* aCallback,
|
||||
nsIAsyncSetClipboardData** _retval) override final;
|
||||
NS_IMETHOD GetData(
|
||||
|
|
@ -108,6 +111,7 @@ class nsBaseClipboard : public nsIClipboard {
|
|||
NS_DECL_NSIASYNCSETCLIPBOARDDATA
|
||||
|
||||
AsyncSetClipboardData(int32_t aClipboardType, nsBaseClipboard* aClipboard,
|
||||
mozilla::dom::WindowContext* aRequestingWindowContext,
|
||||
nsIAsyncClipboardRequestCallback* aCallback);
|
||||
|
||||
private:
|
||||
|
|
@ -125,6 +129,7 @@ class nsBaseClipboard : public nsIClipboard {
|
|||
// NotifyCallback()) once nsBaseClipboard stops tracking us. This is
|
||||
// also used to indicate whether this request is valid.
|
||||
nsBaseClipboard* mClipboard;
|
||||
RefPtr<mozilla::dom::WindowContext> mWindowContext;
|
||||
// mCallback will be nullified once the callback is notified to ensure the
|
||||
// callback is only notified once.
|
||||
nsCOMPtr<nsIAsyncClipboardRequestCallback> mCallback;
|
||||
|
|
@ -174,22 +179,26 @@ class nsBaseClipboard : public nsIClipboard {
|
|||
*/
|
||||
void Clear();
|
||||
void Update(nsITransferable* aTransferable,
|
||||
nsIClipboardOwner* aClipboardOwner, int32_t aSequenceNumber) {
|
||||
nsIClipboardOwner* aClipboardOwner, int32_t aSequenceNumber,
|
||||
mozilla::Maybe<uint64_t> aInnerWindowId) {
|
||||
// Clear first to notify the old clipboard owner.
|
||||
Clear();
|
||||
mTransferable = aTransferable;
|
||||
mClipboardOwner = aClipboardOwner;
|
||||
mSequenceNumber = aSequenceNumber;
|
||||
mInnerWindowId = aInnerWindowId;
|
||||
}
|
||||
nsITransferable* GetTransferable() const { return mTransferable; }
|
||||
nsIClipboardOwner* GetClipboardOwner() const { return mClipboardOwner; }
|
||||
int32_t GetSequenceNumber() const { return mSequenceNumber; }
|
||||
mozilla::Maybe<uint64_t> GetInnerWindowId() const { return mInnerWindowId; }
|
||||
nsresult GetData(nsITransferable* aTransferable) const;
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsITransferable> mTransferable;
|
||||
nsCOMPtr<nsIClipboardOwner> mClipboardOwner;
|
||||
int32_t mSequenceNumber = -1;
|
||||
mozilla::Maybe<uint64_t> mInnerWindowId;
|
||||
};
|
||||
|
||||
class SafeContentAnalysisResultCallback final
|
||||
|
|
@ -245,10 +254,10 @@ class nsBaseClipboard : public nsIClipboard {
|
|||
int32_t aClipboardType);
|
||||
bool CheckClipboardContentAnalysisSync(
|
||||
mozilla::dom::WindowGlobalParent* aWindow,
|
||||
const nsCOMPtr<nsITransferable>& trans);
|
||||
const nsCOMPtr<nsITransferable>& trans, int32_t aClipboardType);
|
||||
void CheckClipboardContentAnalysis(
|
||||
mozilla::dom::WindowGlobalParent* aWindow, nsITransferable* aTransferable,
|
||||
SafeContentAnalysisResultCallback* aResolver);
|
||||
int32_t aClipboardType, SafeContentAnalysisResultCallback* aResolver);
|
||||
// - true means a content analysis request was fired
|
||||
// - false means there is no text data in the transferable
|
||||
// - NoContentAnalysisResult means there was an error
|
||||
|
|
|
|||
|
|
@ -36,9 +36,10 @@ nsClipboardHelper::~nsClipboardHelper() {
|
|||
*****************************************************************************/
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsClipboardHelper::CopyStringToClipboard(const nsAString& aString,
|
||||
int32_t aClipboardID,
|
||||
SensitiveData aSensitive) {
|
||||
nsClipboardHelper::CopyStringToClipboard(
|
||||
const nsAString& aString, int32_t aClipboardID,
|
||||
mozilla::dom::WindowContext* aSettingWindowContext,
|
||||
SensitiveData aSensitive) {
|
||||
nsresult rv;
|
||||
|
||||
// get the clipboard
|
||||
|
|
@ -92,20 +93,22 @@ nsClipboardHelper::CopyStringToClipboard(const nsAString& aString,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// put the transferable on the clipboard
|
||||
rv = clipboard->SetData(trans, nullptr, aClipboardID);
|
||||
rv = clipboard->SetData(trans, nullptr, aClipboardID, aSettingWindowContext);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsClipboardHelper::CopyString(const nsAString& aString,
|
||||
SensitiveData aSensitive) {
|
||||
nsClipboardHelper::CopyString(
|
||||
const nsAString& aString,
|
||||
mozilla::dom::WindowContext* aSettingWindowContext,
|
||||
SensitiveData aSensitive) {
|
||||
nsresult rv;
|
||||
|
||||
// copy to the global clipboard. it's bad if this fails in any way.
|
||||
rv = CopyStringToClipboard(aString, nsIClipboard::kGlobalClipboard,
|
||||
aSensitive);
|
||||
aSettingWindowContext, aSensitive);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// unix also needs us to copy to the selection clipboard. this will
|
||||
|
|
@ -117,7 +120,8 @@ nsClipboardHelper::CopyString(const nsAString& aString,
|
|||
// if this fails in any way other than "not being unix", we'll get
|
||||
// the assertion we need in CopyStringToClipboard, and we needn't
|
||||
// assert again here.
|
||||
CopyStringToClipboard(aString, nsIClipboard::kSelectionClipboard, aSensitive);
|
||||
CopyStringToClipboard(aString, nsIClipboard::kSelectionClipboard,
|
||||
aSettingWindowContext, aSensitive);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,8 @@ nsClipboardProxy::nsClipboardProxy() : mClipboardCaps(false, false, false) {}
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsClipboardProxy::SetData(nsITransferable* aTransferable,
|
||||
nsIClipboardOwner* anOwner, int32_t aWhichClipboard) {
|
||||
nsIClipboardOwner* anOwner, int32_t aWhichClipboard,
|
||||
mozilla::dom::WindowContext* aWindowContext) {
|
||||
#if defined(ACCESSIBILITY) && defined(XP_WIN)
|
||||
a11y::Compatibility::SuppressA11yForClipboardCopy();
|
||||
#endif
|
||||
|
|
@ -41,17 +42,19 @@ nsClipboardProxy::SetData(nsITransferable* aTransferable,
|
|||
IPCTransferable ipcTransferable;
|
||||
nsContentUtils::TransferableToIPCTransferable(aTransferable, &ipcTransferable,
|
||||
false, nullptr);
|
||||
child->SendSetClipboard(std::move(ipcTransferable), aWhichClipboard);
|
||||
child->SendSetClipboard(std::move(ipcTransferable), aWhichClipboard,
|
||||
aWindowContext);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsClipboardProxy::AsyncSetData(
|
||||
int32_t aWhichClipboard, nsIAsyncClipboardRequestCallback* aCallback,
|
||||
int32_t aWhichClipboard, mozilla::dom::WindowContext* aSettingWindowContext,
|
||||
nsIAsyncClipboardRequestCallback* aCallback,
|
||||
nsIAsyncSetClipboardData** _retval) {
|
||||
RefPtr<ClipboardWriteRequestChild> request =
|
||||
MakeRefPtr<ClipboardWriteRequestChild>(aCallback);
|
||||
ContentChild::GetSingleton()->SendPClipboardWriteRequestConstructor(
|
||||
request, aWhichClipboard);
|
||||
request, aWhichClipboard, aSettingWindowContext);
|
||||
request.forget(_retval);
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -115,20 +115,28 @@ interface nsIClipboard : nsISupports
|
|||
* @param aTransferable The transferable
|
||||
* @param anOwner The owner of the transferable
|
||||
* @param aWhichClipboard Specifies the clipboard to which this operation applies.
|
||||
* @result NS_Ok if no errors
|
||||
* @param aSettingWindowContext [optional]
|
||||
* The window context that is setting the clipboard, if any. This is used
|
||||
* to possibly bypass Content Analysis if a set clipboard and get clipboard
|
||||
* operation are done on the same page.
|
||||
* @result NS_OK if no errors
|
||||
*/
|
||||
|
||||
void setData ( in nsITransferable aTransferable, in nsIClipboardOwner anOwner,
|
||||
in long aWhichClipboard ) ;
|
||||
void setData (in nsITransferable aTransferable, in nsIClipboardOwner anOwner,
|
||||
in long aWhichClipboard, [optional] in WindowContext aSettingWindowContext);
|
||||
|
||||
/**
|
||||
* Requests setting data to the native clipboard. The acutal set occur
|
||||
* Requests setting data to the native clipboard. The actual set occurs
|
||||
* when the data is provided by calling nsIAsyncSetClipboardData::setData().
|
||||
* The result will be notified by nsIClipboardCallback. A new set request
|
||||
* will cancel any prior pending requests, if any exist.
|
||||
*
|
||||
* @param aWhichClipboard
|
||||
* Specifies the clipboard to which this operation applies.
|
||||
* @param aSettingWindowContext [optional]
|
||||
* The window context that is setting the clipboard, if any. This is used
|
||||
* to possibly bypass Content Analysis if a set clipboard and get clipboard
|
||||
* operation are done on the same page.
|
||||
* @param aCallback [optional]
|
||||
* The callback object that will be notified upon completion.
|
||||
* @return nsIAsyncSetClipboardData
|
||||
|
|
@ -136,6 +144,7 @@ interface nsIClipboard : nsISupports
|
|||
* data is provided by calling nsIAsyncSetClipboardData::setData().
|
||||
*/
|
||||
nsIAsyncSetClipboardData asyncSetData(in long aWhichClipboard,
|
||||
[optional] in WindowContext aSettingWindowContext,
|
||||
[optional] in nsIAsyncClipboardRequestCallback aCallback);
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -29,17 +29,29 @@ interface nsIClipboardHelper : nsISupports
|
|||
* @param aString, the string to copy to the clipboard
|
||||
* @param aClipboardID, the ID of the clipboard to copy to
|
||||
* (eg. kSelectionClipboard -- see nsIClipboard.idl)
|
||||
* @param aSettingWindowContext
|
||||
* The window context that is setting the clipboard, if any. This is used
|
||||
* to possibly bypass Content Analysis if a set clipboard and get clipboard
|
||||
* operation are done on the same page.
|
||||
* @param aSensitive, optional flag to indicate that data is sensitive, like a password.
|
||||
* That will exclude data from Cloud Clipboard/Clipboard History on Windows.
|
||||
*/
|
||||
void copyStringToClipboard(in AString aString, in long aClipboardID,
|
||||
[optional] in WindowContext aSettingWindowContext,
|
||||
[optional, default(NotSensitive)] in nsIClipboardHelper_SensitiveData aSensitive);
|
||||
|
||||
/**
|
||||
* copy string to (default) clipboard
|
||||
*
|
||||
* @param aString, the string to copy to the clipboard
|
||||
* @param aSettingWindowContext
|
||||
* The window context that is setting the clipboard, if any. This is used
|
||||
* to possibly bypass Content Analysis if a set clipboard and get clipboard
|
||||
* operation are done on the same page.
|
||||
* @param aSensitive, optional flag to indicate that data is sensitive, like a password.
|
||||
* That will exclude data from Cloud Clipboard/Clipboard History on Windows.
|
||||
*/
|
||||
void copyString(in AString aString,
|
||||
[optional] in WindowContext aSettingWindowContext,
|
||||
[optional, default(NotSensitive)] in nsIClipboardHelper_SensitiveData aSensitive);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ clipboardTypes.forEach(function (type) {
|
|||
let priorResult;
|
||||
let priorRequest;
|
||||
let priorPromise = new Promise(resolve => {
|
||||
priorRequest = clipboard.asyncSetData(type, {
|
||||
priorRequest = clipboard.asyncSetData(type, null, {
|
||||
QueryInterface: SpecialPowers.ChromeUtils.generateQI([
|
||||
"nsIAsyncSetClipboardDataCallback",
|
||||
]),
|
||||
|
|
@ -119,7 +119,7 @@ clipboardTypes.forEach(function (type) {
|
|||
|
||||
// Create a pending asyncSetData request
|
||||
let result;
|
||||
let request = clipboard.asyncSetData(type, rv => {
|
||||
let request = clipboard.asyncSetData(type, null, rv => {
|
||||
result = rv;
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue