зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1237595 - FormData ctor and form submission should create empty Blob/File when a input type=file is not set, r=smaug
This commit is contained in:
Родитель
d7f8317f74
Коммит
d64cfad447
|
@ -957,6 +957,32 @@ BlobImplFile::LookupAndCacheIsDirectory()
|
|||
mDirState = isDir ? BlobDirState::eIsDir : BlobDirState::eIsNotDir;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// BlobImplEmptyFile implementation
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(BlobImplEmptyFile, BlobImpl)
|
||||
|
||||
already_AddRefed<BlobImpl>
|
||||
BlobImplEmptyFile::CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||
const nsAString& aContentType,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(!aStart && !aLength);
|
||||
RefPtr<BlobImpl> impl = new BlobImplEmptyFile(aContentType);
|
||||
return impl.forget();
|
||||
}
|
||||
|
||||
void
|
||||
BlobImplEmptyFile::GetInternalStream(nsIInputStream** aStream,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
nsresult rv = NS_NewCStringInputStream(aStream, EmptyCString());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
aRv.Throw(rv);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// BlobImplMemory implementation
|
||||
|
||||
|
|
|
@ -833,6 +833,31 @@ private:
|
|||
bool mIsTemporary;
|
||||
};
|
||||
|
||||
class BlobImplEmptyFile final : public BlobImplBase
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
explicit BlobImplEmptyFile(const nsAString& aContentType)
|
||||
: BlobImplBase(EmptyString(), aContentType, 0 /* aLength */)
|
||||
{}
|
||||
|
||||
virtual void GetInternalStream(nsIInputStream** aStream,
|
||||
ErrorResult& aRv) override;
|
||||
|
||||
virtual already_AddRefed<BlobImpl>
|
||||
CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||
const nsAString& aContentType, ErrorResult& aRv) override;
|
||||
|
||||
virtual bool IsMemoryFile() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
~BlobImplEmptyFile() {}
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
|
@ -179,6 +179,8 @@ FormData::Has(const nsAString& aName)
|
|||
nsresult
|
||||
FormData::AddNameFilePair(const nsAString& aName, File* aFile)
|
||||
{
|
||||
MOZ_ASSERT(aFile);
|
||||
|
||||
FormDataTuple* data = mFormData.AppendElement();
|
||||
SetNameFilePair(data, aName, aFile);
|
||||
return NS_OK;
|
||||
|
@ -272,12 +274,10 @@ FormData::SetNameFilePair(FormDataTuple* aData,
|
|||
File* aFile)
|
||||
{
|
||||
MOZ_ASSERT(aData);
|
||||
MOZ_ASSERT(aFile);
|
||||
|
||||
aData->name = aName;
|
||||
if (aFile) {
|
||||
aData->value.SetAsFile() = aFile;
|
||||
} else {
|
||||
aData->value.SetAsUSVString() = EmptyString();
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
@ -364,7 +364,7 @@ FormData::GetSendInfo(nsIInputStream** aBody, uint64_t* aContentLength,
|
|||
fs.AddNameValuePair(mFormData[i].name,
|
||||
mFormData[i].value.GetAsUSVString());
|
||||
} else {
|
||||
fs.AddNameFilePair(mFormData[i].name, nullptr);
|
||||
MOZ_CRASH("This should no be possible.");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,16 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=789315
|
|||
<form id="a"><input name="b" type="file"/></form>
|
||||
|
||||
<script type="text/javascript">
|
||||
is(new FormData(document.getElementById('a')).get('b'), "", "This should return an empty string.");
|
||||
var obj = new FormData(document.getElementById('a')).get('b');
|
||||
|
||||
ok(obj instanceof File, "This should return an empty File");
|
||||
is(obj.size, 0, "Size should be 0");
|
||||
is(obj.name, "", "Name should be an empty string");
|
||||
is(obj.type, "application/octet-stream", "Type should be application/octet-stream");
|
||||
|
||||
var o = obj.slice(10, 100, "foo/bar");
|
||||
is(o.size, 0, "The new blob has size 0");
|
||||
is(o.type, "foo/bar", "The new blob has type foo/bar");
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
|
|
@ -5593,9 +5593,10 @@ HTMLInputElement::SubmitNamesValues(nsFormSubmission* aFormSubmission)
|
|||
}
|
||||
|
||||
if (files.IsEmpty()) {
|
||||
// If no file was selected, pretend we had an empty file with an
|
||||
// empty filename.
|
||||
aFormSubmission->AddNameFilePair(name, nullptr);
|
||||
RefPtr<BlobImpl> blobImpl =
|
||||
new BlobImplEmptyFile(NS_LITERAL_STRING("application/octet-stream"));
|
||||
RefPtr<File> file = File::Create(OwnerDoc()->GetInnerWindow(), blobImpl);
|
||||
aFormSubmission->AddNameFilePair(name, file);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -167,15 +167,15 @@ nsresult
|
|||
nsFSURLEncoded::AddNameFilePair(const nsAString& aName,
|
||||
File* aFile)
|
||||
{
|
||||
MOZ_ASSERT(aFile);
|
||||
|
||||
if (!mWarnedFileControl) {
|
||||
SendJSWarning(mDocument, "ForgotFileEnctypeWarning", nullptr, 0);
|
||||
mWarnedFileControl = true;
|
||||
}
|
||||
|
||||
nsAutoString filename;
|
||||
if (aFile) {
|
||||
aFile->GetName(filename);
|
||||
}
|
||||
|
||||
return AddNameValuePair(aName, filename);
|
||||
}
|
||||
|
@ -441,14 +441,13 @@ nsresult
|
|||
nsFSMultipartFormData::AddNameFilePair(const nsAString& aName,
|
||||
File* aFile)
|
||||
{
|
||||
MOZ_ASSERT(aFile);
|
||||
|
||||
// Encode the control name
|
||||
nsAutoCString nameStr;
|
||||
nsresult rv = EncodeVal(aName, nameStr, true);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCString filename, contentType;
|
||||
nsCOMPtr<nsIInputStream> fileStream;
|
||||
if (aFile) {
|
||||
nsAutoString filename16;
|
||||
aFile->GetName(filename16);
|
||||
|
||||
|
@ -464,6 +463,7 @@ nsFSMultipartFormData::AddNameFilePair(const nsAString& aName,
|
|||
filename16 = filepath16 + filename16;
|
||||
}
|
||||
|
||||
nsAutoCString filename;
|
||||
rv = EncodeVal(filename16, filename, true);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
@ -473,12 +473,15 @@ nsFSMultipartFormData::AddNameFilePair(const nsAString& aName,
|
|||
if (contentType16.IsEmpty()) {
|
||||
contentType16.AssignLiteral("application/octet-stream");
|
||||
}
|
||||
|
||||
nsAutoCString contentType;
|
||||
contentType.Adopt(nsLinebreakConverter::
|
||||
ConvertLineBreaks(NS_ConvertUTF16toUTF8(contentType16).get(),
|
||||
nsLinebreakConverter::eLinebreakAny,
|
||||
nsLinebreakConverter::eLinebreakSpace));
|
||||
|
||||
// Get input stream
|
||||
nsCOMPtr<nsIInputStream> fileStream;
|
||||
aFile->GetInternalStream(getter_AddRefs(fileStream), error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
|
@ -493,10 +496,6 @@ nsFSMultipartFormData::AddNameFilePair(const nsAString& aName,
|
|||
|
||||
fileStream = bufferedStream;
|
||||
}
|
||||
}
|
||||
else {
|
||||
contentType.AssignLiteral("application/octet-stream");
|
||||
}
|
||||
|
||||
//
|
||||
// Make MIME block for name/value pair
|
||||
|
@ -619,9 +618,7 @@ nsFSTextPlain::AddNameFilePair(const nsAString& aName,
|
|||
File* aFile)
|
||||
{
|
||||
nsAutoString filename;
|
||||
if (aFile) {
|
||||
aFile->GetName(filename);
|
||||
}
|
||||
|
||||
AddNameValuePair(aName, filename);
|
||||
return NS_OK;
|
||||
|
|
|
@ -258,7 +258,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=523771
|
|||
<p>
|
||||
File input:
|
||||
<input type=file name="file_1" class="setfile">
|
||||
<input type=file name="file_2" class="setfile empty">
|
||||
<input type=file name="file_2">
|
||||
<input type=file name="" class="setfile">
|
||||
<input type=file name="">
|
||||
<input type=file class="setfile">
|
||||
|
@ -268,7 +268,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=523771
|
|||
Multifile input:
|
||||
<input multiple type=file name="file_3" class="setfile">
|
||||
<input multiple type=file name="file_4" class="setfile multi">
|
||||
<input multiple type=file name="file_5" class="setfile empty">
|
||||
<input multiple type=file name="file_5">
|
||||
<input multiple type=file name="" class="setfile">
|
||||
<input multiple type=file name="" class="setfile multi">
|
||||
<input multiple type=file name="">
|
||||
|
@ -426,7 +426,6 @@ function onFilesOpened(files) {
|
|||
|
||||
let singleFile = textFile;
|
||||
let multiFile = [textFile, imageFile];
|
||||
emptyFile = new File([], "", { type: "application/octet-stream" });
|
||||
|
||||
var addList = document.getElementsByClassName("setfile");
|
||||
let i = 0;
|
||||
|
@ -434,8 +433,6 @@ function onFilesOpened(files) {
|
|||
while (input = addList[i++]) {
|
||||
if (input.classList.contains("multi")) {
|
||||
SpecialPowers.wrap(input).mozSetFileArray(multiFile);
|
||||
} else if (input.classList.contains("empty")) {
|
||||
SpecialPowers.wrap(input).mozSetFileArray([emptyFile]);
|
||||
} else {
|
||||
SpecialPowers.wrap(input).mozSetFileArray([singleFile]);
|
||||
}
|
||||
|
@ -449,6 +446,7 @@ function onFilesOpened(files) {
|
|||
myFile2 = input.files[1];
|
||||
is(myFile1.size, 20, "File1 size");
|
||||
is(myFile2.size, 2711, "File2 size");
|
||||
emptyFile = { name: "", type: "application/octet-stream" };
|
||||
|
||||
// Now, actually run the tests; see below.
|
||||
onFilesSet();
|
||||
|
|
Загрузка…
Ссылка в новой задаче