diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 7b0042b7d965..8a4ffd15a537 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -7761,12 +7761,37 @@ void nsContentUtils::SetKeyboardIndicatorsOnRemoteChildren( }); } +bool nsContentUtils::IPCDataTransferItemHasKnownFlavor( + const IPCDataTransferItem& aItem) { + // Unknown types are converted to kCustomTypesMime. + // FIXME(bug 1776879) text/plain is converted to text/unicode still. + if (aItem.flavor().EqualsASCII(kCustomTypesMime) || + aItem.flavor().EqualsASCII(kUnicodeMime)) { + return true; + } + + for (const char* format : DataTransfer::kKnownFormats) { + if (aItem.flavor().EqualsASCII(format)) { + return true; + } + } + + return false; +} + nsresult nsContentUtils::IPCTransferableToTransferable( const IPCDataTransfer& aDataTransfer, bool aAddDataFlavor, - nsITransferable* aTransferable) { + nsITransferable* aTransferable, const bool aFilterUnknownFlavors) { nsresult rv; const nsTArray& items = aDataTransfer.items(); for (const auto& item : items) { + if (aFilterUnknownFlavors && !IPCDataTransferItemHasKnownFlavor(item)) { + NS_WARNING( + "Ignoring unknown flavor in " + "nsContentUtils::IPCTransferableToTransferable"); + continue; + } + if (aAddDataFlavor) { aTransferable->AddDataFlavor(item.flavor().get()); } @@ -7836,11 +7861,11 @@ nsresult nsContentUtils::IPCTransferableToTransferable( const IPCDataTransfer& aDataTransfer, const bool& aIsPrivateData, nsIPrincipal* aRequestingPrincipal, const nsContentPolicyType& aContentPolicyType, bool aAddDataFlavor, - nsITransferable* aTransferable) { + nsITransferable* aTransferable, const bool aFilterUnknownFlavors) { aTransferable->SetIsPrivateData(aIsPrivateData); nsresult rv = IPCTransferableToTransferable(aDataTransfer, aAddDataFlavor, - aTransferable); + aTransferable, aFilterUnknownFlavors); NS_ENSURE_SUCCESS(rv, rv); aTransferable->SetRequestingPrincipal(aRequestingPrincipal); diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h index 4610d7b3c3f8..c90a596e19d9 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -2872,15 +2872,18 @@ class nsContentUtils { */ static bool IsFlavorImage(const nsACString& aFlavor); + static bool IPCDataTransferItemHasKnownFlavor( + const mozilla::dom::IPCDataTransferItem& aItem); + static nsresult IPCTransferableToTransferable( const mozilla::dom::IPCDataTransfer& aDataTransfer, bool aAddDataFlavor, - nsITransferable* aTransferable); + nsITransferable* aTransferable, const bool aFilterUnknownFlavors); static nsresult IPCTransferableToTransferable( const mozilla::dom::IPCDataTransfer& aDataTransfer, const bool& aIsPrivateData, nsIPrincipal* aRequestingPrincipal, const nsContentPolicyType& aContentPolicyType, bool aAddDataFlavor, - nsITransferable* aTransferable); + nsITransferable* aTransferable, const bool aFilterUnknownFlavors); static nsresult IPCTransferableItemToVariant( const mozilla::dom::IPCDataTransferItem& aDataTransferItem, diff --git a/dom/events/DataTransfer.cpp b/dom/events/DataTransfer.cpp index 1030dca96024..593ff87d52d6 100644 --- a/dom/events/DataTransfer.cpp +++ b/dom/events/DataTransfer.cpp @@ -888,29 +888,6 @@ already_AddRefed DataTransfer::GetTransferable( const uint32_t baseLength = sizeof(uint32_t) + 1; uint32_t totalCustomLength = baseLength; - const char* knownFormats[] = {kTextMime, - kHTMLMime, - kNativeHTMLMime, - kRTFMime, - kURLMime, - kURLDataMime, - kURLDescriptionMime, - kURLPrivateMime, - kPNGImageMime, - kJPEGImageMime, - kGIFImageMime, - kNativeImageMime, - kFileMime, - kFilePromiseMime, - kFilePromiseURLMime, - kFilePromiseDestFilename, - kFilePromiseDirectoryMime, - kMozTextInternal, - kHTMLContext, - kHTMLInfo, - kImageRequestMime, - kPDFJSMime}; - /* * Two passes are made here to iterate over all of the types. First, look for * any types that are not in the list of known types. For this pass, @@ -946,8 +923,8 @@ already_AddRefed DataTransfer::GetTransferable( // If the data is of one of the well-known formats, use it directly. bool isCustomFormat = true; - for (uint32_t f = 0; f < ArrayLength(knownFormats); f++) { - if (type.EqualsASCII(knownFormats[f])) { + for (const char* format : kKnownFormats) { + if (type.EqualsASCII(format)) { isCustomFormat = false; break; } diff --git a/dom/events/DataTransfer.h b/dom/events/DataTransfer.h index 629c9cc2d7b7..80cc5a7f3a05 100644 --- a/dom/events/DataTransfer.h +++ b/dom/events/DataTransfer.h @@ -393,6 +393,30 @@ class DataTransfer final : public nsISupports, public nsWrapperCache { bool aPlainTextOnly, nsTArray* aResult); + // Formats that are "known" and won't be converted to the kCustomTypesMime. + static inline const char* const kKnownFormats[] = {kTextMime, + kHTMLMime, + kNativeHTMLMime, + kRTFMime, + kURLMime, + kURLDataMime, + kURLDescriptionMime, + kURLPrivateMime, + kPNGImageMime, + kJPEGImageMime, + kGIFImageMime, + kNativeImageMime, + kFileMime, + kFilePromiseMime, + kFilePromiseURLMime, + kFilePromiseDestFilename, + kFilePromiseDirectoryMime, + kMozTextInternal, + kHTMLContext, + kHTMLInfo, + kImageRequestMime, + kPDFJSMime}; + protected: // caches text and uri-list data formats that exist in the drag service or // clipboard for retrieval later. diff --git a/dom/events/RemoteDragStartData.cpp b/dom/events/RemoteDragStartData.cpp index f1ec265b65c4..7e2f9d78c8e3 100644 --- a/dom/events/RemoteDragStartData.cpp +++ b/dom/events/RemoteDragStartData.cpp @@ -43,6 +43,13 @@ void RemoteDragStartData::AddInitialDnDDataTo( for (uint32_t i = 0; i < mDataTransfer.Length(); ++i) { nsTArray& itemArray = mDataTransfer[i].items(); for (auto& item : itemArray) { + if (!nsContentUtils::IPCDataTransferItemHasKnownFlavor(item)) { + NS_WARNING( + "Ignoring unknown flavor in " + "RemoteDragStartData::AddInitialDnDDataTo"); + continue; + } + RefPtr variant = new nsVariantCC(); // Special case kFilePromiseMime so that we get the right // nsIFlavorDataProvider for it. diff --git a/dom/ipc/BrowserChild.cpp b/dom/ipc/BrowserChild.cpp index b5cc2abef252..2ef9ae69b577 100644 --- a/dom/ipc/BrowserChild.cpp +++ b/dom/ipc/BrowserChild.cpp @@ -2242,7 +2242,7 @@ mozilla::ipc::IPCResult BrowserChild::RecvPasteTransferable( rv = nsContentUtils::IPCTransferableToTransferable( aDataTransfer, aIsPrivateData, aRequestingPrincipal, aContentPolicyType, - true /* aAddDataFlavor */, trans); + true /* aAddDataFlavor */, trans, false /* aFilterUnknownFlavors */); NS_ENSURE_SUCCESS(rv, IPC_OK()); nsCOMPtr ourDocShell = do_GetInterface(WebNavigation()); diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index a8b1890f23da..013f64d5b3a6 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -3417,7 +3417,7 @@ mozilla::ipc::IPCResult ContentParent::RecvSetClipboard( rv = nsContentUtils::IPCTransferableToTransferable( aDataTransfer, aIsPrivateData, aRequestingPrincipal, aContentPolicyType, - true /* aAddDataFlavor */, trans); + true /* aAddDataFlavor */, trans, true /* aFilterUnknownFlavors */); NS_ENSURE_SUCCESS(rv, IPC_OK()); clipboard->SetData(trans, nullptr, aWhichClipboard); diff --git a/widget/nsClipboardProxy.cpp b/widget/nsClipboardProxy.cpp index 453be3b086af..47915afcb271 100644 --- a/widget/nsClipboardProxy.cpp +++ b/widget/nsClipboardProxy.cpp @@ -57,7 +57,8 @@ nsClipboardProxy::GetData(nsITransferable* aTransferable, ContentChild::GetSingleton()->SendGetClipboard(types, aWhichClipboard, &dataTransfer); return nsContentUtils::IPCTransferableToTransferable( - dataTransfer, false /* aAddDataFlavor */, aTransferable); + dataTransfer, false /* aAddDataFlavor */, aTransferable, + false /* aFilterUnknownFlavors */); } NS_IMETHODIMP @@ -136,7 +137,8 @@ RefPtr nsClipboardProxy::AsyncGetData( /* resolve */ [promise, transferable](const IPCDataTransfer& ipcDataTransfer) { nsresult rv = nsContentUtils::IPCTransferableToTransferable( - ipcDataTransfer, false /* aAddDataFlavor */, transferable); + ipcDataTransfer, false /* aAddDataFlavor */, transferable, + false /* aFilterUnknownFlavors */); if (NS_FAILED(rv)) { promise->Reject(rv, __func__); return;