Example #1
0
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);
      }
    }
  }
}
Example #2
0
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);
  }
}
Example #3
0
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);
}
Example #4
0
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);
    }
  }
}
Example #5
0
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);
      }
    }
  }
}
Example #6
0
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);
}
Example #7
0
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();
    }
  }
}
Example #8
0
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);
      }
    }
  }
}