Ejemplo n.º 1
0
void
DataTransfer::CacheExternalData(const char* aFormat, uint32_t aIndex, nsIPrincipal* aPrincipal)
{
  if (strcmp(aFormat, kUnicodeMime) == 0) {
    SetDataWithPrincipal(NS_LITERAL_STRING("text/plain"), nullptr, aIndex, aPrincipal);
  } else {
    if (strcmp(aFormat, kURLDataMime) == 0) {
      SetDataWithPrincipal(NS_LITERAL_STRING("text/uri-list"), nullptr, aIndex, aPrincipal);
    }
    SetDataWithPrincipal(NS_ConvertUTF8toUTF16(aFormat), nullptr, aIndex, aPrincipal);
  }
}
Ejemplo n.º 2
0
void
nsDOMDataTransfer::CacheExternalFormats()
{
  // 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.
  const char* formats[] = { kFileMime, kHTMLMime, kURLMime, kURLDataMime, kUnicodeMime };

  PRUint32 count;
  dragSession->GetNumDropItems(&count);
  for (PRUint32 c = 0; c < count; c++) {
    for (PRUint32 f = 0; f < NS_ARRAY_LENGTH(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.
      PRBool 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) {
        if (strcmp(formats[f], kUnicodeMime) == 0) {
          SetDataWithPrincipal(NS_LITERAL_STRING("text/plain"), nsnull, c, sysPrincipal);
        }
        else {
          if (strcmp(formats[f], kURLDataMime) == 0)
            SetDataWithPrincipal(NS_LITERAL_STRING("text/uri-list"), nsnull, c, sysPrincipal);
          SetDataWithPrincipal(NS_ConvertUTF8toUTF16(formats[f]), nsnull, c, sysPrincipal);
        }
      }
    }
  }
}
Ejemplo n.º 3
0
NS_IMETHODIMP
DataTransfer::MozSetDataAt(const nsAString& aFormat, nsIVariant* aData,
                           uint32_t aIndex)
{
  if (aFormat.IsEmpty()) {
    return NS_OK;
  }

  if (mReadOnly) {
    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
  }

  // Specifying an index less than the current length will replace an existing
  // item. Specifying an index equal to the current length will add a new item.
  if (aIndex > mItems.Length()) {
    return NS_ERROR_DOM_INDEX_SIZE_ERR;
  }

  // Only the first item is valid for clipboard events
  if (aIndex > 0 &&
      (mEventType == NS_CUT || mEventType == NS_COPY || mEventType == NS_PASTE)) {
    return NS_ERROR_DOM_INDEX_SIZE_ERR;
  }

  // don't allow non-chrome to add file data
  // XXX perhaps this should also limit any non-string type as well
  if ((aFormat.EqualsLiteral("application/x-moz-file-promise") ||
       aFormat.EqualsLiteral("application/x-moz-file")) &&
       !nsContentUtils::IsCallerChrome()) {
    return NS_ERROR_DOM_SECURITY_ERR;
  }

  return SetDataWithPrincipal(aFormat, aData, aIndex,
                              nsContentUtils::SubjectPrincipal());
}
Ejemplo n.º 4
0
DataTransferItem* DataTransferItemList::Add(File& aData,
                                            nsIPrincipal& aSubjectPrincipal,
                                            ErrorResult& aRv) {
  if (mDataTransfer->IsReadOnly()) {
    return nullptr;
  }

  nsCOMPtr<nsISupports> supports = do_QueryObject(&aData);
  nsCOMPtr<nsIWritableVariant> data = new nsVariantCC();
  data->SetAsISupports(supports);

  nsAutoString type;
  aData.GetType(type);

  if (!DataTransfer::PrincipalMaySetData(type, data, &aSubjectPrincipal)) {
    aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
    return nullptr;
  }

  // We need to add this as a new item, as multiple files can't exist in the
  // same item in the Moz DataTransfer layout. It will be appended at the end of
  // the internal specced layout.
  uint32_t index = mIndexedItems.Length();
  RefPtr<DataTransferItem> item =
      SetDataWithPrincipal(type, data, index, &aSubjectPrincipal,
                           /* aInsertOnly = */ true,
                           /* aHidden = */ false, aRv);
  if (NS_WARN_IF(aRv.Failed())) {
    return nullptr;
  }
  MOZ_ASSERT(item->Kind() == DataTransferItem::KIND_FILE);

  return item;
}
Ejemplo n.º 5
0
DataTransferItem* DataTransferItemList::Add(const nsAString& aData,
                                            const nsAString& aType,
                                            nsIPrincipal& aSubjectPrincipal,
                                            ErrorResult& aRv) {
  if (NS_WARN_IF(mDataTransfer->IsReadOnly())) {
    return nullptr;
  }

  RefPtr<nsVariantCC> data(new nsVariantCC());
  data->SetAsAString(aData);

  nsAutoString format;
  mDataTransfer->GetRealFormat(aType, format);

  if (!DataTransfer::PrincipalMaySetData(format, data, &aSubjectPrincipal)) {
    aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
    return nullptr;
  }

  // We add the textual data to index 0. We set aInsertOnly to true, as we don't
  // want to update an existing entry if it is already present, as per the spec.
  RefPtr<DataTransferItem> item =
      SetDataWithPrincipal(format, data, 0, &aSubjectPrincipal,
                           /* aInsertOnly = */ true,
                           /* aHidden = */ false, aRv);
  if (NS_WARN_IF(aRv.Failed())) {
    return nullptr;
  }
  MOZ_ASSERT(item->Kind() != DataTransferItem::KIND_FILE);

  return item;
}
Ejemplo n.º 6
0
NS_IMETHODIMP
nsDOMDataTransfer::MozSetDataAt(const nsAString& aFormat,
                                nsIVariant* aData,
                                PRUint32 aIndex)
{
  NS_ENSURE_TRUE(aData, NS_ERROR_NULL_POINTER);

  if (aFormat.IsEmpty())
    return NS_OK;

  if (mReadOnly)
    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;

  // Specifying an index less than the current length will replace an existing
  // item. Specifying an index equal to the current length will add a new item.
  if (aIndex > mItems.Length())
    return NS_ERROR_DOM_INDEX_SIZE_ERR;

  // don't allow non-chrome to add file data
  // XXX perhaps this should also limit any non-string type as well
  if ((aFormat.EqualsLiteral("application/x-moz-file-promise") ||
       aFormat.EqualsLiteral("application/x-moz-file")) &&
       !nsContentUtils::IsCallerTrustedForCapability("UniversalXPConnect")) {
    return NS_ERROR_DOM_SECURITY_ERR;
  }

  nsresult rv = NS_OK;
  nsIPrincipal* principal = GetCurrentPrincipal(&rv);
  NS_ENSURE_SUCCESS(rv, rv);
  return SetDataWithPrincipal(aFormat, aData, aIndex, principal);
}
Ejemplo n.º 7
0
void
DataTransfer::FillInExternalCustomTypes(nsIVariant* aData, uint32_t aIndex,
                                        nsIPrincipal* aPrincipal)
{
  char* chrs;
  uint32_t len = 0;
  nsresult rv = aData->GetAsStringWithSize(&len, &chrs);
  if (NS_FAILED(rv)) {
    return;
  }

  nsAutoCString str;
  str.Adopt(chrs, len);

  nsCOMPtr<nsIInputStream> stringStream;
  NS_NewCStringInputStream(getter_AddRefs(stringStream), str);

  nsCOMPtr<nsIBinaryInputStream> stream =
    do_CreateInstance("@mozilla.org/binaryinputstream;1");
  if (!stream) {
    return;
  }

  rv = stream->SetInputStream(stringStream);
  NS_ENSURE_SUCCESS_VOID(rv);

  uint32_t type;
  do {
    rv = stream->Read32(&type);
    NS_ENSURE_SUCCESS_VOID(rv);
    if (type == eCustomClipboardTypeId_String) {
      uint32_t formatLength;
      rv = stream->Read32(&formatLength);
      NS_ENSURE_SUCCESS_VOID(rv);
      char* formatBytes;
      rv = stream->ReadBytes(formatLength, &formatBytes);
      NS_ENSURE_SUCCESS_VOID(rv);
      nsAutoString format;
      format.Adopt(reinterpret_cast<char16_t*>(formatBytes),
                   formatLength / sizeof(char16_t));

      uint32_t dataLength;
      rv = stream->Read32(&dataLength);
      NS_ENSURE_SUCCESS_VOID(rv);
      char* dataBytes;
      rv = stream->ReadBytes(dataLength, &dataBytes);
      NS_ENSURE_SUCCESS_VOID(rv);
      nsAutoString data;
      data.Adopt(reinterpret_cast<char16_t*>(dataBytes),
                 dataLength / sizeof(char16_t));

      RefPtr<nsVariantCC> variant = new nsVariantCC();
      rv = variant->SetAsAString(data);
      NS_ENSURE_SUCCESS_VOID(rv);

      SetDataWithPrincipal(format, variant, aIndex, aPrincipal);
    }
  } while (type != eCustomClipboardTypeId_None);
}
Ejemplo n.º 8
0
void
DataTransfer::FillInExternalCustomTypes(nsIVariant* aData, uint32_t aIndex,
                                        nsIPrincipal* aPrincipal)
{
  char* chrs;
  uint32_t len = 0;
  nsresult rv = aData->GetAsStringWithSize(&len, &chrs);
  if (NS_FAILED(rv)) {
    return;
  }

  CheckedInt<int32_t> checkedLen(len);
  if (!checkedLen.isValid()) {
    return;
  }

  nsCOMPtr<nsIInputStream> stringStream;
  NS_NewByteInputStream(getter_AddRefs(stringStream), chrs, checkedLen.value(),
                        NS_ASSIGNMENT_ADOPT);

  nsCOMPtr<nsIObjectInputStream> stream =
    NS_NewObjectInputStream(stringStream);

  uint32_t type;
  do {
    rv = stream->Read32(&type);
    NS_ENSURE_SUCCESS_VOID(rv);
    if (type == eCustomClipboardTypeId_String) {
      uint32_t formatLength;
      rv = stream->Read32(&formatLength);
      NS_ENSURE_SUCCESS_VOID(rv);
      char* formatBytes;
      rv = stream->ReadBytes(formatLength, &formatBytes);
      NS_ENSURE_SUCCESS_VOID(rv);
      nsAutoString format;
      format.Adopt(reinterpret_cast<char16_t*>(formatBytes),
                   formatLength / sizeof(char16_t));

      uint32_t dataLength;
      rv = stream->Read32(&dataLength);
      NS_ENSURE_SUCCESS_VOID(rv);
      char* dataBytes;
      rv = stream->ReadBytes(dataLength, &dataBytes);
      NS_ENSURE_SUCCESS_VOID(rv);
      nsAutoString data;
      data.Adopt(reinterpret_cast<char16_t*>(dataBytes),
                 dataLength / sizeof(char16_t));

      RefPtr<nsVariantCC> variant = new nsVariantCC();
      rv = variant->SetAsAString(data);
      NS_ENSURE_SUCCESS_VOID(rv);

      SetDataWithPrincipal(format, variant, aIndex, aPrincipal);
    }
  } while (type != eCustomClipboardTypeId_None);
}
Ejemplo n.º 9
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);
  }
}
Ejemplo n.º 10
0
nsresult
DataTransfer::SetDataAtInternal(const nsAString& aFormat, nsIVariant* aData,
                                uint32_t aIndex,
                                nsIPrincipal* aSubjectPrincipal)
{
  if (aFormat.IsEmpty()) {
    return NS_OK;
  }

  if (mReadOnly) {
    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
  }

  // Specifying an index less than the current length will replace an existing
  // item. Specifying an index equal to the current length will add a new item.
  if (aIndex > mItems.Length()) {
    return NS_ERROR_DOM_INDEX_SIZE_ERR;
  }

  // Only the first item is valid for clipboard events
  if (aIndex > 0 &&
      (mEventMessage == eCut || mEventMessage == eCopy ||
       mEventMessage == ePaste)) {
    return NS_ERROR_DOM_INDEX_SIZE_ERR;
  }

  // Don't allow the custom type to be assigned.
  if (aFormat.EqualsLiteral(kCustomTypesMime)) {
    return NS_ERROR_TYPE_ERR;
  }

  // Don't allow non-chrome to add non-string or file data. We'll block file
  // promises as well which are used internally for drags to the desktop.
  if (!nsContentUtils::IsSystemPrincipal(aSubjectPrincipal)) {
    if (aFormat.EqualsLiteral(kFilePromiseMime) ||
        aFormat.EqualsLiteral(kFileMime)) {
      return NS_ERROR_DOM_SECURITY_ERR;
    }

    uint16_t type;
    aData->GetDataType(&type);
    if (type == nsIDataType::VTYPE_INTERFACE ||
        type == nsIDataType::VTYPE_INTERFACE_IS) {
      return NS_ERROR_DOM_SECURITY_ERR;
    }
  }

  return SetDataWithPrincipal(aFormat, aData, aIndex, aSubjectPrincipal);
}
Ejemplo n.º 11
0
nsresult
DataTransfer::SetDataAtInternal(const nsAString& aFormat, nsIVariant* aData,
                                uint32_t aIndex,
                                nsIPrincipal* aSubjectPrincipal)
{
  if (aFormat.IsEmpty()) {
    return NS_OK;
  }

  if (mReadOnly) {
    return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
  }

  // Specifying an index less than the current length will replace an existing
  // item. Specifying an index equal to the current length will add a new item.
  if (aIndex > MozItemCount()) {
    return NS_ERROR_DOM_INDEX_SIZE_ERR;
  }

  // Only the first item is valid for clipboard events
  if (aIndex > 0 &&
      (mEventMessage == eCut || mEventMessage == eCopy ||
       mEventMessage == ePaste)) {
    return NS_ERROR_DOM_INDEX_SIZE_ERR;
  }

  // Don't allow the custom type to be assigned.
  if (aFormat.EqualsLiteral(kCustomTypesMime)) {
    return NS_ERROR_TYPE_ERR;
  }

  if (!PrincipalMaySetData(aFormat, aData, aSubjectPrincipal)) {
    return NS_ERROR_DOM_SECURITY_ERR;
  }

  return SetDataWithPrincipal(aFormat, aData, aIndex, aSubjectPrincipal);
}