void DataTransfer::CacheExternalDragFormats() { // Called during the constructor to cache the formats available from an // external drag. The data associated with each format will be set to null. // This data will instead only be retrieved in FillInExternalDragData when // asked for, as it may be time consuming for the source application to // generate it. nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession(); if (!dragSession) { return; } // make sure that the system principal is used for external drags nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager(); nsCOMPtr<nsIPrincipal> sysPrincipal; ssm->GetSystemPrincipal(getter_AddRefs(sysPrincipal)); // there isn't a way to get a list of the formats that might be available on // all platforms, so just check for the types that can actually be imported // XXXndeakin there are some other formats but those are platform specific. // NOTE: kFileMime must have index 0 const char* formats[] = { kFileMime, kHTMLMime, kURLMime, kURLDataMime, kUnicodeMime, kPNGImageMime }; uint32_t count; dragSession->GetNumDropItems(&count); for (uint32_t c = 0; c < count; c++) { bool hasFileData = false; dragSession->IsDataFlavorSupported(kFileMime, &hasFileData); // First, check for the special format that holds custom types. bool supported; dragSession->IsDataFlavorSupported(kCustomTypesMime, &supported); if (supported) { FillInExternalCustomTypes(c, sysPrincipal); } for (uint32_t f = 0; f < ArrayLength(formats); f++) { // IsDataFlavorSupported doesn't take an index as an argument and just // checks if any of the items support a particular flavor, even though // the GetData method does take an index. Here, we just assume that // every item being dragged has the same set of flavors. bool supported; dragSession->IsDataFlavorSupported(formats[f], &supported); // if the format is supported, add an item to the array with null as // the data. When retrieved, GetRealData will read the data. if (supported) { CacheExternalData(formats[f], c, sysPrincipal, /* hidden = */ f && hasFileData); } } } }
void DataTransfer::SetDataWithPrincipalFromOtherProcess(const nsAString& aFormat, nsIVariant* aData, uint32_t aIndex, nsIPrincipal* aPrincipal) { if (aFormat.EqualsLiteral(kCustomTypesMime)) { FillInExternalCustomTypes(aData, aIndex, aPrincipal); } else { SetDataWithPrincipal(aFormat, aData, aIndex, aPrincipal); } }
void DataTransfer::FillInExternalCustomTypes(uint32_t aIndex, nsIPrincipal* aPrincipal) { TransferItem item; item.mFormat.AssignLiteral(kCustomTypesMime); FillInExternalData(item, aIndex); if (!item.mData) { return; } FillInExternalCustomTypes(item.mData, aIndex, aPrincipal); }
void DataTransfer::CacheExternalClipboardFormats(bool aPlainTextOnly) { // Called during the constructor for paste events to cache the formats // available on the clipboard. As with CacheExternalDragFormats, the // data will only be retrieved when needed. NS_ASSERTION(mEventMessage == ePaste, "caching clipboard data for invalid event"); nsCOMPtr<nsIPrincipal> sysPrincipal = nsContentUtils::GetSystemPrincipal(); nsTArray<nsCString> typesArray; if (XRE_IsContentProcess()) { ContentChild::GetSingleton()->SendGetExternalClipboardFormats(mClipboardType, aPlainTextOnly, &typesArray); } else { GetExternalClipboardFormats(mClipboardType, aPlainTextOnly, &typesArray); } if (aPlainTextOnly) { // The only thing that will be in types is kUnicodeMime MOZ_ASSERT(typesArray.IsEmpty() || typesArray.Length() == 1); if (typesArray.Length() == 1) { CacheExternalData(kUnicodeMime, 0, sysPrincipal, false); } return; } bool hasFileData = false; for (const nsCString& type: typesArray) { if (type.EqualsLiteral(kCustomTypesMime)) { FillInExternalCustomTypes(0, sysPrincipal); } else if (type.EqualsLiteral(kFileMime) && XRE_IsContentProcess()) { // We will be ignoring any application/x-moz-file files found in the paste // datatransfer within e10s, as they will fail top be sent over IPC. Because of // that, we will unset hasFileData, whether or not it would have been set. // (bug 1308007) hasFileData = false; continue; } else { // We expect that if kFileMime is supported, then it will be the either at // index 0 or at index 1 in the typesArray returned by GetExternalClipboardFormats if (type.EqualsLiteral(kFileMime) && !XRE_IsContentProcess()) { hasFileData = true; } // If we aren't the file data, and we have file data, we want to be hidden CacheExternalData(type.get(), 0, sysPrincipal, /* hidden = */ !type.EqualsLiteral(kFileMime) && hasFileData); } } }
void DataTransfer::CacheExternalClipboardFormats() { NS_ASSERTION(mEventMessage == ePaste, "caching clipboard data for invalid event"); // Called during the constructor for paste events to cache the formats // available on the clipboard. As with CacheExternalDragFormats, the // data will only be retrieved when needed. nsCOMPtr<nsIClipboard> clipboard = do_GetService("@mozilla.org/widget/clipboard;1"); if (!clipboard || mClipboardType < 0) { return; } nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager(); nsCOMPtr<nsIPrincipal> sysPrincipal; ssm->GetSystemPrincipal(getter_AddRefs(sysPrincipal)); // Check if the clipboard has any files bool hasFileData = false; const char *fileMime[] = { kFileMime }; clipboard->HasDataMatchingFlavors(fileMime, 1, mClipboardType, &hasFileData); // there isn't a way to get a list of the formats that might be available on // all platforms, so just check for the types that can actually be imported. // Note that the loop below assumes that kCustomTypesMime will be first. const char* formats[] = { kCustomTypesMime, kFileMime, kHTMLMime, kRTFMime, kURLMime, kURLDataMime, kUnicodeMime, kPNGImageMime, kJPEGImageMime, kGIFImageMime }; for (uint32_t f = 0; f < mozilla::ArrayLength(formats); ++f) { // check each format one at a time bool supported; clipboard->HasDataMatchingFlavors(&(formats[f]), 1, mClipboardType, &supported); // if the format is supported, add an item to the array with null as // the data. When retrieved, GetRealData will read the data. if (supported) { if (f == 0) { FillInExternalCustomTypes(0, sysPrincipal); } else { // If we aren't the file data, and we have file data, we want to be hidden CacheExternalData(formats[f], 0, sysPrincipal, /* hidden = */ f != 1 && hasFileData); } } } }
void DataTransfer::FillInExternalCustomTypes(uint32_t aIndex, nsIPrincipal* aPrincipal) { RefPtr<DataTransferItem> item = new DataTransferItem(this, NS_LITERAL_STRING(kCustomTypesMime), DataTransferItem::KIND_STRING); item->SetIndex(aIndex); nsCOMPtr<nsIVariant> variant = item->DataNoSecurityCheck(); if (!variant) { return; } FillInExternalCustomTypes(variant, aIndex, aPrincipal); }
void DataTransfer::SetDataWithPrincipalFromOtherProcess(const nsAString& aFormat, nsIVariant* aData, uint32_t aIndex, nsIPrincipal* aPrincipal, bool aHidden) { if (aFormat.EqualsLiteral(kCustomTypesMime)) { FillInExternalCustomTypes(aData, aIndex, aPrincipal); } else { nsAutoString format; GetRealFormat(aFormat, format); ErrorResult rv; RefPtr<DataTransferItem> item = mItems->SetDataWithPrincipal(format, aData, aIndex, aPrincipal, /* aInsertOnly = */ false, aHidden, rv); if (NS_WARN_IF(rv.Failed())) { rv.SuppressException(); } } }
void DataTransfer::CacheExternalClipboardFormats() { NS_ASSERTION(mEventMessage == ePaste, "caching clipboard data for invalid event"); // Called during the constructor for paste events to cache the formats // available on the clipboard. As with CacheExternalDragFormats, the // data will only be retrieved when needed. nsCOMPtr<nsIClipboard> clipboard = do_GetService("@mozilla.org/widget/clipboard;1"); if (!clipboard || mClipboardType < 0) { return; } nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager(); nsCOMPtr<nsIPrincipal> sysPrincipal; ssm->GetSystemPrincipal(getter_AddRefs(sysPrincipal)); // Check if the clipboard has any files bool hasFileData = false; const char *fileMime[] = { kFileMime }; clipboard->HasDataMatchingFlavors(fileMime, 1, mClipboardType, &hasFileData); // We will be ignoring any application/x-moz-file files found in the paste // datatransfer within e10s, as they will fail to be sent over IPC. Because of // that, we will unset hasFileData, whether or not it would have been set. // (bug 1308007) if (XRE_IsContentProcess()) { hasFileData = false; } // there isn't a way to get a list of the formats that might be available on // all platforms, so just check for the types that can actually be imported. // NOTE: kCustomTypesMime must have index 0, kFileMime index 1 const char* formats[] = { kCustomTypesMime, kFileMime, kHTMLMime, kRTFMime, kURLMime, kURLDataMime, kUnicodeMime, kPNGImageMime }; for (uint32_t f = 0; f < mozilla::ArrayLength(formats); ++f) { // check each format one at a time bool supported; clipboard->HasDataMatchingFlavors(&(formats[f]), 1, mClipboardType, &supported); // if the format is supported, add an item to the array with null as // the data. When retrieved, GetRealData will read the data. if (supported) { if (f == 0) { FillInExternalCustomTypes(0, sysPrincipal); } else { // In non-e10s we support pasting files from explorer.exe. // Unfortunately, we fail to send that data over IPC in e10s, so we // don't want to add the item to the DataTransfer and end up producing a // null `application/x-moz-file`. (bug 1308007) if (XRE_IsContentProcess() && f == 1) { continue; } // If we aren't the file data, and we have file data, we want to be hidden CacheExternalData(formats[f], 0, sysPrincipal, /* hidden = */ f != 1 && hasFileData); } } } }