mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 819900 - File constructor. r=sicking
This commit is contained in:
parent
e1935ec872
commit
2c924a4923
@ -176,7 +176,22 @@ nsDOMMultipartFile::Initialize(nsISupports* aOwner,
|
||||
if (!mIsFile) {
|
||||
return InitBlob(aCx, aArgs.length(), aArgs.array(), GetXPConnectNative);
|
||||
}
|
||||
return InitFile(aCx, aArgs.length(), aArgs.array());
|
||||
|
||||
if (!nsContentUtils::IsCallerChrome()) {
|
||||
return InitFile(aCx, aArgs.length(), aArgs.array());
|
||||
}
|
||||
|
||||
if (aArgs.length() > 0) {
|
||||
JS::Value* argv = aArgs.array();
|
||||
if (argv[0].isObject()) {
|
||||
JS::Rooted<JSObject*> obj(aCx, &argv[0].toObject());
|
||||
if (JS_IsArrayObject(aCx, obj)) {
|
||||
return InitFile(aCx, aArgs.length(), aArgs.array());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return InitChromeFile(aCx, aArgs.length(), aArgs.array());
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -196,66 +211,72 @@ nsDOMMultipartFile::InitBlob(JSContext* aCx,
|
||||
}
|
||||
|
||||
if (aArgc > 0) {
|
||||
if (!aArgv[0].isObject()) {
|
||||
return NS_ERROR_TYPE_ERR; // We're not interested
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> obj(aCx, &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) {
|
||||
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) {
|
||||
// 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)) {
|
||||
blobSet.AppendVoidPtr(JS_GetArrayBufferViewData(obj),
|
||||
JS_GetArrayBufferViewByteLength(obj));
|
||||
continue;
|
||||
}
|
||||
if (JS_IsArrayBufferObject(obj)) {
|
||||
blobSet.AppendArrayBuffer(obj);
|
||||
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 ParseBlobArrayArgument(aCx, aArgv[0], nativeEOL, aUnwrapFunc);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMMultipartFile::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;
|
||||
JS_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) {
|
||||
// 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)) {
|
||||
blobSet.AppendVoidPtr(JS_GetArrayBufferViewData(obj),
|
||||
JS_GetArrayBufferViewByteLength(obj));
|
||||
continue;
|
||||
}
|
||||
if (JS_IsArrayBufferObject(obj)) {
|
||||
blobSet.AppendArrayBuffer(obj);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// coerce it to a string
|
||||
JSString* str = JS_ValueToString(aCx, element);
|
||||
NS_ENSURE_TRUE(str, NS_ERROR_TYPE_ERR);
|
||||
blobSet.AppendString(str, aNativeEOL, aCx);
|
||||
}
|
||||
|
||||
mBlobs = blobSet.GetBlobs();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMMultipartFile::GetMozFullPathInternal(nsAString &aFilename)
|
||||
{
|
||||
@ -273,19 +294,15 @@ nsDOMMultipartFile::GetMozFullPathInternal(nsAString &aFilename)
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMMultipartFile::InitFile(JSContext* aCx,
|
||||
uint32_t aArgc,
|
||||
JS::Value* aArgv)
|
||||
nsDOMMultipartFile::InitChromeFile(JSContext* aCx,
|
||||
uint32_t aArgc,
|
||||
JS::Value* 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
|
||||
}
|
||||
|
||||
MOZ_ASSERT(nsContentUtils::IsCallerChrome());
|
||||
NS_ENSURE_TRUE(aArgc > 0, NS_ERROR_UNEXPECTED);
|
||||
|
||||
if (aArgc > 1) {
|
||||
@ -367,6 +384,43 @@ nsDOMMultipartFile::InitFile(JSContext* aCx,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMMultipartFile::InitFile(JSContext* aCx,
|
||||
uint32_t aArgc,
|
||||
JS::Value* aArgv)
|
||||
{
|
||||
NS_ASSERTION(!mImmutable, "Something went wrong ...");
|
||||
NS_ENSURE_TRUE(!mImmutable, NS_ERROR_UNEXPECTED);
|
||||
|
||||
if (aArgc < 2) {
|
||||
return NS_ERROR_TYPE_ERR;
|
||||
}
|
||||
|
||||
// File name
|
||||
JSString* str = JS_ValueToString(aCx, aArgv[1]);
|
||||
NS_ENSURE_TRUE(str, NS_ERROR_XPC_BAD_CONVERT_JS);
|
||||
|
||||
nsDependentJSString xpcomStr;
|
||||
if (!xpcomStr.init(aCx, str)) {
|
||||
return NS_ERROR_XPC_BAD_CONVERT_JS;
|
||||
}
|
||||
|
||||
mName = xpcomStr;
|
||||
|
||||
// Optional params
|
||||
bool nativeEOL = false;
|
||||
if (aArgc > 2) {
|
||||
BlobPropertyBag d;
|
||||
if (!d.Init(aCx, JS::Handle<JS::Value>::fromMarkedLocation(&aArgv[2]))) {
|
||||
return NS_ERROR_TYPE_ERR;
|
||||
}
|
||||
mContentType = d.mType;
|
||||
nativeEOL = d.mEndings == EndingTypes::Native;
|
||||
}
|
||||
|
||||
return ParseBlobArrayArgument(aCx, aArgv[0], nativeEOL, GetXPConnectNative);
|
||||
}
|
||||
|
||||
nsresult
|
||||
BlobSet::AppendVoidPtr(const void* aData, uint32_t aLength)
|
||||
{
|
||||
|
@ -73,6 +73,9 @@ public:
|
||||
nsresult InitFile(JSContext* aCx,
|
||||
uint32_t aArgc,
|
||||
JS::Value* aArgv);
|
||||
nsresult InitChromeFile(JSContext* aCx,
|
||||
uint32_t aArgc,
|
||||
JS::Value* aArgv);
|
||||
|
||||
already_AddRefed<nsIDOMBlob>
|
||||
CreateSlice(uint64_t aStart, uint64_t aLength, const nsAString& aContentType) MOZ_OVERRIDE;
|
||||
@ -103,6 +106,9 @@ public:
|
||||
NS_IMETHOD GetMozFullPathInternal(nsAString& aFullPath) MOZ_OVERRIDE;
|
||||
|
||||
protected:
|
||||
nsresult ParseBlobArrayArgument(JSContext* aCx, JS::Value& aValue,
|
||||
bool aNativeEOL, UnwrapFuncPtr aUnwrapFunc);
|
||||
|
||||
nsTArray<nsCOMPtr<nsIDOMBlob> > mBlobs;
|
||||
bool mIsFromNsiFile;
|
||||
};
|
||||
|
@ -576,3 +576,4 @@ support-files =
|
||||
[test_xhr_progressevents.html]
|
||||
[test_xhr_send_readystate.html]
|
||||
[test_xhr_withCredentials.html]
|
||||
[test_file_from_blob.html]
|
||||
|
111
content/base/test/test_file_from_blob.html
Normal file
111
content/base/test/test_file_from_blob.html
Normal file
@ -0,0 +1,111 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=819900
|
||||
-->
|
||||
<head>
|
||||
<title>Test for crash caused by unloading and reloading srcdoc iframes</title>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=819900">Mozilla Bug 819900</a>
|
||||
|
||||
<pre id="test">
|
||||
<script>
|
||||
|
||||
var b = new Blob(['1234567890']);
|
||||
ok(b, 'Blob created');
|
||||
is(b.size, 10, 'Blob has the right size');
|
||||
|
||||
var status = false;
|
||||
try {
|
||||
f = new File(b);
|
||||
} catch(e) {
|
||||
status = true;
|
||||
}
|
||||
ok(status, "File throws if the second argument is missing");
|
||||
|
||||
status = false;
|
||||
try {
|
||||
f = new File(42, 'foobar.txt');
|
||||
} catch(e) {
|
||||
status = true;
|
||||
}
|
||||
ok(status, "File throws if the argument is not an array");
|
||||
|
||||
status = false;
|
||||
try {
|
||||
f = new File({}, 'foobar.txt');
|
||||
} catch(e) {
|
||||
status = true;
|
||||
}
|
||||
ok(status, "File throws if the argument is not an array");
|
||||
|
||||
status = false;
|
||||
try {
|
||||
f = new File("hello world", 'foobar.txt');
|
||||
} catch(e) {
|
||||
status = true;
|
||||
}
|
||||
ok(status, "File throws if the argument is not an array");
|
||||
|
||||
f = new File(['1234567890'], '');
|
||||
ok(f, 'File created');
|
||||
is(f.size, 10, 'File has the right size');
|
||||
is(f.name, '');
|
||||
is(f.type, '');
|
||||
|
||||
f = new File(['1234567890'], 42);
|
||||
ok(f, 'File created');
|
||||
is(f.size, 10, 'File has the right size');
|
||||
is(f.name, '42');
|
||||
is(f.type, '');
|
||||
|
||||
f = new File(['1234567890'], 'text.txt');
|
||||
ok(f, 'File created');
|
||||
is(f.size, 10, 'File has the right size');
|
||||
is(f.name, 'text.txt');
|
||||
is(f.type, '');
|
||||
|
||||
f = new File(['1234567890'], 'text.txt', { type: 'plain/text' });
|
||||
ok(f, 'File created');
|
||||
is(f.size, 10, 'File has the right size');
|
||||
is(f.name, 'text.txt');
|
||||
is(f.type, 'plain/text');
|
||||
|
||||
f = new File([b], 'text.txt');
|
||||
ok(f, 'File created');
|
||||
is(f.name, 'text.txt');
|
||||
is(f.type, '');
|
||||
is(f.size, b.size);
|
||||
|
||||
f = new File([b], 'test.txt', { type: 'plain/text' });
|
||||
ok(f, 'File created');
|
||||
is(f.name, 'test.txt');
|
||||
is(f.type, 'plain/text');
|
||||
is(f.size, b.size);
|
||||
|
||||
f = new File([b, b], 'test.txt', { type: 'plain/text' });
|
||||
ok(f, 'File created');
|
||||
is(f.name, 'test.txt');
|
||||
is(f.type, 'plain/text');
|
||||
is(f.size, b.size * 2);
|
||||
|
||||
var f2 = new File([f, f], 'test.txt', { type: 'plain/text' });
|
||||
ok(f2, 'File created');
|
||||
is(f2.name, 'test.txt');
|
||||
is(f2.type, 'plain/text');
|
||||
is(f2.size, f.size * 2);
|
||||
|
||||
var f2 = new File([f, f], 'test.txt', b);
|
||||
ok(f2, 'File created');
|
||||
is(f2.name, 'test.txt');
|
||||
is(f2.type, b.type);
|
||||
is(f2.size, f.size * 2);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
Reference in New Issue
Block a user