Example #1
0
void
MultipartBlobImpl::InitializeChromeFile(Blob& aBlob,
                                        const ChromeFilePropertyBag& aBag,
                                        ErrorResult& aRv)
{
  NS_ASSERTION(!mImmutable, "Something went wrong ...");

  if (mImmutable) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return;
  }

  MOZ_ASSERT(nsContentUtils::IsCallerChrome());

  mName = aBag.mName;
  mContentType = aBag.mType;
  mIsFromNsIFile = true;

  // XXXkhuey this is terrible
  if (mContentType.IsEmpty()) {
    aBlob.GetType(mContentType);
  }


  BlobSet blobSet;
  blobSet.AppendBlobImpl(aBlob.Impl());
  mBlobImpls = blobSet.GetBlobImpls();

  SetLengthAndModifiedDate();
}
Example #2
0
void
MultipartBlobImpl::InitializeBlob(
       JSContext* aCx,
       const Sequence<OwningArrayBufferOrArrayBufferViewOrBlobOrString>& aData,
       const nsAString& aContentType,
       bool aNativeEOL,
       ErrorResult& aRv)
{
  mContentType = aContentType;
  BlobSet blobSet;

  for (uint32_t i = 0, len = aData.Length(); i < len; ++i) {
    const OwningArrayBufferOrArrayBufferViewOrBlobOrString& data = aData[i];

    if (data.IsBlob()) {
      nsRefPtr<Blob> blob = data.GetAsBlob().get();
      blobSet.AppendBlobImpl(blob->Impl());
    }

    else if (data.IsString()) {
      aRv = blobSet.AppendString(data.GetAsString(), aNativeEOL, aCx);
      if (aRv.Failed()) {
        return;
      }
    }

    else if (data.IsArrayBuffer()) {
      const ArrayBuffer& buffer = data.GetAsArrayBuffer();
      buffer.ComputeLengthAndData();
      aRv = blobSet.AppendVoidPtr(buffer.Data(), buffer.Length());
      if (aRv.Failed()) {
        return;
      }
    }

    else if (data.IsArrayBufferView()) {
      const ArrayBufferView& buffer = data.GetAsArrayBufferView();
      buffer.ComputeLengthAndData();
      aRv = blobSet.AppendVoidPtr(buffer.Data(), buffer.Length());
      if (aRv.Failed()) {
        return;
      }
    }

    else {
      MOZ_CRASH("Impossible blob data type.");
    }
  }


  mBlobImpls = blobSet.GetBlobImpls();
  SetLengthAndModifiedDate();
}
Example #3
0
void
MultipartBlobImpl::InitializeBlob(const Sequence<Blob::BlobPart>& aData,
                                  const nsAString& aContentType,
                                  bool aNativeEOL,
                                  ErrorResult& aRv)
{
  mContentType = aContentType;
  BlobSet blobSet;

  for (uint32_t i = 0, len = aData.Length(); i < len; ++i) {
    const Blob::BlobPart& data = aData[i];

    if (data.IsBlob()) {
      RefPtr<Blob> blob = data.GetAsBlob().get();
      blobSet.AppendBlobImpl(blob->Impl());
    }

    else if (data.IsUSVString()) {
      aRv = blobSet.AppendString(data.GetAsUSVString(), aNativeEOL);
      if (aRv.Failed()) {
        return;
      }
    }

    else if (data.IsArrayBuffer()) {
      const ArrayBuffer& buffer = data.GetAsArrayBuffer();
      buffer.ComputeLengthAndData();
      aRv = blobSet.AppendVoidPtr(buffer.Data(), buffer.Length());
      if (aRv.Failed()) {
        return;
      }
    }

    else if (data.IsArrayBufferView()) {
      const ArrayBufferView& buffer = data.GetAsArrayBufferView();
      buffer.ComputeLengthAndData();
      aRv = blobSet.AppendVoidPtr(buffer.Data(), buffer.Length());
      if (aRv.Failed()) {
        return;
      }
    }

    else {
      MOZ_CRASH("Impossible blob data type.");
    }
  }


  mBlobImpls = blobSet.GetBlobImpls();
  SetLengthAndModifiedDate(aRv);
  NS_WARNING_ASSERTION(!aRv.Failed(), "SetLengthAndModifiedDate failed");
}
Example #4
0
void
MultipartBlobImpl::InitializeChromeFile(nsPIDOMWindow* aWindow,
                                        nsIFile* aFile,
                                        const ChromeFilePropertyBag& aBag,
                                        bool aIsFromNsIFile,
                                        ErrorResult& aRv)
{
  NS_ASSERTION(!mImmutable, "Something went wrong ...");
  if (mImmutable) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return;
  }

  MOZ_ASSERT(nsContentUtils::IsCallerChrome());

  mName = aBag.mName;
  mContentType = aBag.mType;
  mIsFromNsIFile = aIsFromNsIFile;

  bool exists;
  aRv = aFile->Exists(&exists);
  if (NS_WARN_IF(aRv.Failed())) {
    return;
  }

  if (!exists) {
    aRv.Throw(NS_ERROR_FILE_NOT_FOUND);
    return;
  }

  bool isDir;
  aRv = aFile->IsDirectory(&isDir);
  if (NS_WARN_IF(aRv.Failed())) {
    return;
  }

  if (isDir) {
    aRv.Throw(NS_ERROR_FILE_IS_DIRECTORY);
    return;
  }

  if (mName.IsEmpty()) {
    aFile->GetLeafName(mName);
  }

  nsRefPtr<File> blob = File::CreateFromFile(aWindow, aFile, aBag.mTemporary);

  // Pre-cache size.
  blob->GetSize(aRv);
  if (NS_WARN_IF(aRv.Failed())) {
    return;
  }

  // Pre-cache modified date.
  blob->GetLastModified(aRv);
  if (NS_WARN_IF(aRv.Failed())) {
    return;
  }

  // XXXkhuey this is terrible
  if (mContentType.IsEmpty()) {
    blob->GetType(mContentType);
  }

  BlobSet blobSet;
  blobSet.AppendBlobImpl(static_cast<File*>(blob.get())->Impl());
  mBlobImpls = blobSet.GetBlobImpls();

  SetLengthAndModifiedDate();
}
Example #5
0
nsresult
MultipartBlobImpl::InitializeChromeFile(nsIFile* aFile,
                                        const nsAString& aType,
                                        const nsAString& aName,
                                        bool aLastModifiedPassed,
                                        int64_t aLastModified,
                                        bool aIsFromNsIFile)
{
  MOZ_ASSERT(!mImmutable, "Something went wrong ...");
  if (mImmutable) {
    return NS_ERROR_UNEXPECTED;
  }

  mName = aName;
  mContentType = aType;
  mIsFromNsIFile = aIsFromNsIFile;

  bool exists;
  nsresult rv= aFile->Exists(&exists);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  if (!exists) {
    return NS_ERROR_FILE_NOT_FOUND;
  }

  bool isDir;
  rv = aFile->IsDirectory(&isDir);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  if (isDir) {
    return NS_ERROR_FILE_IS_DIRECTORY;
  }

  if (mName.IsEmpty()) {
    aFile->GetLeafName(mName);
  }

  RefPtr<File> blob = File::CreateFromFile(nullptr, aFile);

  // Pre-cache size.
  ErrorResult error;
  blob->GetSize(error);
  if (NS_WARN_IF(error.Failed())) {
    return error.StealNSResult();
  }

  // Pre-cache modified date.
  blob->GetLastModified(error);
  if (NS_WARN_IF(error.Failed())) {
    return error.StealNSResult();
  }

  // XXXkhuey this is terrible
  if (mContentType.IsEmpty()) {
    blob->GetType(mContentType);
  }

  BlobSet blobSet;
  blobSet.AppendBlobImpl(static_cast<File*>(blob.get())->Impl());
  mBlobImpls = blobSet.GetBlobImpls();

  SetLengthAndModifiedDate(error);
  if (NS_WARN_IF(error.Failed())) {
    return error.StealNSResult();
  }

  if (aLastModifiedPassed) {
    SetLastModified(aLastModified);
  }

  return NS_OK;
}
nsresult
nsDOMMultipartFile::InitInternal(JSContext* aCx,
                                 PRUint32 aArgc,
                                 jsval* aArgv,
                                 UnwrapFuncPtr aUnwrapFunc)
{
  bool nativeEOL = false;
  if (aArgc > 1) {
    mozilla::dom::BlobPropertyBag d;
    nsresult rv = d.Init(aCx, &aArgv[1]);
    NS_ENSURE_SUCCESS(rv, rv);
    mContentType = d.type;
    if (d.endings.EqualsLiteral("native")) {
      nativeEOL = true;
    } else if (!d.endings.EqualsLiteral("transparent")) {
      return NS_ERROR_DOM_INVALID_STATE_ERR;
    }
  }

  if (aArgc > 0) {
    if (!aArgv[0].isObject()) {
      return NS_ERROR_INVALID_ARG; // We're not interested
    }

    JSObject& obj = aArgv[0].toObject();

    if (!JS_IsArrayObject(aCx, &obj)) {
      return NS_ERROR_INVALID_ARG; // We're not interested
    }

    BlobSet blobSet;

    uint32_t length;
    JS_ALWAYS_TRUE(JS_GetArrayLength(aCx, &obj, &length));
    for (uint32_t i = 0; i < length; ++i) {
      jsval element;
      if (!JS_GetElement(aCx, &obj, i, &element))
        return NS_ERROR_INVALID_ARG;

      if (element.isObject()) {
        JSObject& obj = element.toObject();
        nsCOMPtr<nsIDOMBlob> blob = aUnwrapFunc(aCx, &obj);
        if (blob) {
          // Flatten so that multipart blobs will never nest
          nsDOMFileBase* file = static_cast<nsDOMFileBase*>(
              static_cast<nsIDOMBlob*>(blob));
          const nsTArray<nsCOMPtr<nsIDOMBlob> >*
              subBlobs = file->GetSubBlobs();
          if (subBlobs) {
            blobSet.AppendBlobs(*subBlobs);
          } else {
            blobSet.AppendBlob(blob);
          }
        } else if (JS_IsArrayBufferObject(&obj, aCx)) {
          blobSet.AppendArrayBuffer(&obj, aCx);
        } else {
          // neither arraybuffer nor blob
          return NS_ERROR_DOM_INVALID_STATE_ERR;
        }
      } else if (element.isString()) {
        blobSet.AppendString(element.toString(), nativeEOL, aCx);
      } else {
        // neither object nor string
        return NS_ERROR_DOM_INVALID_STATE_ERR;
      }
    }

    mBlobs = blobSet.GetBlobs();
  }

  return NS_OK;
}
nsresult
nsDOMMultipartFile::InitInternal(JSContext* aCx,
                                 uint32_t aArgc,
                                 jsval* aArgv,
                                 UnwrapFuncPtr aUnwrapFunc)
{
  bool nativeEOL = false;
  if (aArgc > 1) {
    if (NS_IsMainThread()) {
      BlobPropertyBag d;
      if (!d.Init(aCx, nullptr, aArgv[1])) {
        return NS_ERROR_TYPE_ERR;
      }
      mContentType = d.type;
      nativeEOL = d.endings == EndingTypesValues::Native;
    } else {
      BlobPropertyBagWorkers d;
      if (!d.Init(aCx, nullptr, aArgv[1])) {
        return NS_ERROR_TYPE_ERR;
      }
      mContentType = d.type;
      nativeEOL = d.endings == EndingTypesValues::Native;
    }
  }

  if (aArgc > 0) {
    if (!aArgv[0].isObject()) {
      return NS_ERROR_TYPE_ERR; // We're not interested
    }

    JSObject& obj = aArgv[0].toObject();
    if (!JS_IsArrayObject(aCx, &obj)) {
      return NS_ERROR_TYPE_ERR; // We're not interested
    }

    BlobSet blobSet;

    uint32_t length;
    JS_ALWAYS_TRUE(JS_GetArrayLength(aCx, &obj, &length));
    for (uint32_t i = 0; i < length; ++i) {
      jsval element;
      if (!JS_GetElement(aCx, &obj, i, &element))
        return NS_ERROR_TYPE_ERR;

      if (element.isObject()) {
        JSObject& obj = element.toObject();
        nsCOMPtr<nsIDOMBlob> blob = aUnwrapFunc(aCx, &obj);
        if (blob) {
          // Flatten so that multipart blobs will never nest
          nsDOMFileBase* file = static_cast<nsDOMFileBase*>(
              static_cast<nsIDOMBlob*>(blob));
          const nsTArray<nsCOMPtr<nsIDOMBlob> >*
              subBlobs = file->GetSubBlobs();
          if (subBlobs) {
            blobSet.AppendBlobs(*subBlobs);
          } else {
            blobSet.AppendBlob(blob);
          }
          continue;
        }
        if (JS_IsArrayBufferViewObject(&obj, aCx)) {
          blobSet.AppendVoidPtr(JS_GetArrayBufferViewData(&obj, aCx),
                                JS_GetArrayBufferViewByteLength(&obj, aCx));
          continue;
        }
        if (JS_IsArrayBufferObject(&obj, aCx)) {
          blobSet.AppendArrayBuffer(&obj, aCx);
          continue;
        }
        // neither Blob nor ArrayBuffer(View)
      } else if (element.isString()) {
        blobSet.AppendString(element.toString(), nativeEOL, aCx);
        continue;
      }
      // coerce it to a string
      JSString* str = JS_ValueToString(aCx, element);
      NS_ENSURE_TRUE(str, NS_ERROR_TYPE_ERR);
      blobSet.AppendString(str, nativeEOL, aCx);
    }

    mBlobs = blobSet.GetBlobs();
  }

  return NS_OK;
}
nsresult
nsDOMMultipartFile::InitFile(JSContext* aCx,
                             uint32_t aArgc,
                             jsval* aArgv)
{
  nsresult rv;

  NS_ASSERTION(!mImmutable, "Something went wrong ...");
  NS_ENSURE_TRUE(!mImmutable, NS_ERROR_UNEXPECTED);

  if (!nsContentUtils::IsCallerChrome()) {
    return NS_ERROR_DOM_SECURITY_ERR; // Real short trip
  }

  NS_ENSURE_TRUE(aArgc > 0, NS_ERROR_UNEXPECTED);

  bool nativeEOL = false;
  if (aArgc > 1) {
    FilePropertyBag d;
    if (!d.Init(aCx, nullptr, aArgv[1])) {
      return NS_ERROR_TYPE_ERR;
    }
    mName = d.mName;
    mContentType = d.mType;
    nativeEOL = d.mEndings == EndingTypesValues::Native;
  }

  // We expect to get a path to represent as a File object,
  // an nsIFile, or an nsIDOMFile.
  nsCOMPtr<nsIFile> file;
  nsCOMPtr<nsIDOMFile> domFile;
  if (!aArgv[0].isString()) {
    // Lets see if it's an nsIFile
    if (!aArgv[0].isObject()) {
      return NS_ERROR_UNEXPECTED; // We're not interested
    }

    JSObject* obj = &aArgv[0].toObject();

    nsISupports* supports =
      nsContentUtils::XPConnect()->GetNativeOfWrapper(aCx, obj);
    if (!supports) {
      return NS_ERROR_UNEXPECTED;
    }

    domFile = do_QueryInterface(supports);
    file = do_QueryInterface(supports);
    if (!domFile && !file) {
      return NS_ERROR_UNEXPECTED;
    }
  } else {
    // It's a string
    JSString* str = JS_ValueToString(aCx, aArgv[0]);
    NS_ENSURE_TRUE(str, NS_ERROR_XPC_BAD_CONVERT_JS);

    nsDependentJSString xpcomStr;
    if (!xpcomStr.init(aCx, str)) {
      return NS_ERROR_XPC_BAD_CONVERT_JS;
    }

    rv = NS_NewLocalFile(xpcomStr, false, getter_AddRefs(file));
    NS_ENSURE_SUCCESS(rv, rv);
  }

  if (file) {
    bool exists;
    rv = file->Exists(&exists);
    NS_ENSURE_SUCCESS(rv, rv);
    NS_ENSURE_TRUE(exists, NS_ERROR_FILE_NOT_FOUND);

    bool isDir;
    rv = file->IsDirectory(&isDir);
    NS_ENSURE_SUCCESS(rv, rv);
    NS_ENSURE_FALSE(isDir, NS_ERROR_FILE_IS_DIRECTORY);

    if (mName.IsEmpty()) {
      file->GetLeafName(mName);
    }

    domFile = new nsDOMFileFile(file);
  }
  
  // XXXkhuey this is terrible
  if (mContentType.IsEmpty()) {
    domFile->GetType(mContentType);
  }

  BlobSet blobSet;
  blobSet.AppendBlob(domFile);
  mBlobs = blobSet.GetBlobs();

  return NS_OK;
}
nsresult
DOMMultipartFileImpl::InitChromeFile(JSContext* aCx,
                                     uint32_t aArgc,
                                     JS::Value* aArgv)
{
  nsresult rv;

  NS_ASSERTION(!mImmutable, "Something went wrong ...");
  NS_ENSURE_TRUE(!mImmutable, NS_ERROR_UNEXPECTED);
  MOZ_ASSERT(nsContentUtils::IsCallerChrome());
  NS_ENSURE_TRUE(aArgc > 0, NS_ERROR_UNEXPECTED);

  if (aArgc > 1) {
    FilePropertyBag d;
    if (!d.Init(aCx, JS::Handle<JS::Value>::fromMarkedLocation(&aArgv[1]))) {
      return NS_ERROR_TYPE_ERR;
    }
    mName = d.mName;
    mContentType = d.mType;
  }


  // We expect to get a path to represent as a File object or
  // Blob object, an nsIFile, or an nsIDOMFile.
  nsCOMPtr<nsIFile> file;
  nsCOMPtr<nsIDOMBlob> blob;
  if (!aArgv[0].isString()) {
    // Lets see if it's an nsIFile
    if (!aArgv[0].isObject()) {
      return NS_ERROR_UNEXPECTED; // We're not interested
    }

    JSObject* obj = &aArgv[0].toObject();

    nsISupports* supports =
      nsContentUtils::XPConnect()->GetNativeOfWrapper(aCx, obj);
    if (!supports) {
      return NS_ERROR_UNEXPECTED;
    }

    blob = do_QueryInterface(supports);
    file = do_QueryInterface(supports);
    if (!blob && !file) {
      return NS_ERROR_UNEXPECTED;
    }

    mIsFromNsiFile = true;
  } else {
    // It's a string
    JSString* str = JS::ToString(aCx, JS::Handle<JS::Value>::fromMarkedLocation(&aArgv[0]));
    NS_ENSURE_TRUE(str, NS_ERROR_XPC_BAD_CONVERT_JS);

    nsAutoJSString xpcomStr;
    if (!xpcomStr.init(aCx, str)) {
      return NS_ERROR_XPC_BAD_CONVERT_JS;
    }

    rv = NS_NewLocalFile(xpcomStr, false, getter_AddRefs(file));
    NS_ENSURE_SUCCESS(rv, rv);
  }

  if (file) {
    bool exists;
    rv = file->Exists(&exists);
    NS_ENSURE_SUCCESS(rv, rv);
    NS_ENSURE_TRUE(exists, NS_ERROR_FILE_NOT_FOUND);

    bool isDir;
    rv = file->IsDirectory(&isDir);
    NS_ENSURE_SUCCESS(rv, rv);
    NS_ENSURE_FALSE(isDir, NS_ERROR_FILE_IS_DIRECTORY);

    if (mName.IsEmpty()) {
      file->GetLeafName(mName);
    }

    nsRefPtr<DOMFile> domFile = DOMFile::CreateFromFile(file);

    // Pre-cache size.
    uint64_t unused;
    rv = domFile->GetSize(&unused);
    NS_ENSURE_SUCCESS(rv, rv);

    // Pre-cache modified date.
    rv = domFile->GetMozLastModifiedDate(&unused);
    NS_ENSURE_SUCCESS(rv, rv);

    blob = domFile.forget();
  }

  // XXXkhuey this is terrible
  if (mContentType.IsEmpty()) {
    blob->GetType(mContentType);
  }

  BlobSet blobSet;
  blobSet.AppendBlobImpl(static_cast<DOMFile*>(blob.get())->Impl());
  mBlobImpls = blobSet.GetBlobImpls();

  SetLengthAndModifiedDate();

  return NS_OK;
}
nsresult
DOMMultipartFileImpl::ParseBlobArrayArgument(JSContext* aCx, JS::Value& aValue,
                                             bool aNativeEOL,
                                             UnwrapFuncPtr aUnwrapFunc)
{
  if (!aValue.isObject()) {
    return NS_ERROR_TYPE_ERR; // We're not interested
  }

  JS::Rooted<JSObject*> obj(aCx, &aValue.toObject());
  if (!JS_IsArrayObject(aCx, obj)) {
    return NS_ERROR_TYPE_ERR; // We're not interested
  }

  BlobSet blobSet;

  uint32_t length;
  MOZ_ALWAYS_TRUE(JS_GetArrayLength(aCx, obj, &length));
  for (uint32_t i = 0; i < length; ++i) {
    JS::Rooted<JS::Value> element(aCx);
    if (!JS_GetElement(aCx, obj, i, &element))
      return NS_ERROR_TYPE_ERR;

    if (element.isObject()) {
      JS::Rooted<JSObject*> obj(aCx, &element.toObject());
      nsCOMPtr<nsIDOMBlob> blob = aUnwrapFunc(aCx, obj);
      if (blob) {
        nsRefPtr<DOMFileImpl> blobImpl =
          static_cast<DOMFile*>(blob.get())->Impl();

        // Flatten so that multipart blobs will never nest
        const nsTArray<nsRefPtr<DOMFileImpl>>* subBlobImpls =
          blobImpl->GetSubBlobImpls();
        if (subBlobImpls) {
          blobSet.AppendBlobImpls(*subBlobImpls);
        } else {
          blobSet.AppendBlobImpl(blobImpl);
        }
        continue;
      }
      if (JS_IsArrayBufferViewObject(obj)) {
        nsresult rv = blobSet.AppendVoidPtr(
                                          JS_GetArrayBufferViewData(obj),
                                          JS_GetArrayBufferViewByteLength(obj));
        NS_ENSURE_SUCCESS(rv, rv);
        continue;
      }
      if (JS_IsArrayBufferObject(obj)) {
        nsresult rv = blobSet.AppendArrayBuffer(obj);
        NS_ENSURE_SUCCESS(rv, rv);
        continue;
      }
    }

    // coerce it to a string
    JSString* str = JS::ToString(aCx, element);
    NS_ENSURE_TRUE(str, NS_ERROR_TYPE_ERR);

    nsresult rv = blobSet.AppendString(str, aNativeEOL, aCx);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  mBlobImpls = blobSet.GetBlobImpls();

  SetLengthAndModifiedDate();

  return NS_OK;
}