Bug 1361443 - FileReader should support ReadSegments() not returning the whole size, r=smaug
--- a/dom/file/FileReader.cpp
+++ b/dom/file/FileReader.cpp
@@ -275,16 +275,18 @@ FileReader::DoAsyncWait()
return NS_OK;
}
nsresult
FileReader::DoReadData(uint64_t aCount)
{
MOZ_ASSERT(mAsyncStream);
+ uint32_t bytesRead = 0;
+
if (mDataFormat == FILE_AS_BINARY) {
//Continuously update our binary string as data comes in
uint32_t oldLen = mResult.Length();
MOZ_ASSERT(mResult.Length() == mDataLen, "unexpected mResult length");
if (uint64_t(oldLen) + aCount > UINT32_MAX)
return NS_ERROR_OUT_OF_MEMORY;
char16_t *buf = nullptr;
mResult.GetMutableData(&buf, oldLen + aCount, fallible);
@@ -296,53 +298,46 @@ FileReader::DoReadData(uint64_t aCount)
// with a nsIAsyncInputStream, in content process, we need to wrap a
// nsIBufferedInputStream around it.
if (!mBufferedStream) {
rv = NS_NewBufferedInputStream(getter_AddRefs(mBufferedStream),
mAsyncStream, 8192);
NS_ENSURE_SUCCESS(rv, rv);
}
- uint32_t bytesRead = 0;
rv = mBufferedStream->ReadSegments(ReadFuncBinaryString, buf + oldLen,
aCount, &bytesRead);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
- MOZ_ASSERT(bytesRead == aCount, "failed to read data");
+ mResult.Truncate(oldLen + bytesRead);
}
else {
CheckedInt<uint64_t> size = mDataLen;
size += aCount;
//Update memory buffer to reflect the contents of the file
if (!size.isValid() ||
// PR_Realloc doesn't support over 4GB memory size even if 64-bit OS
size.value() > UINT32_MAX ||
size.value() > mTotal) {
return NS_ERROR_OUT_OF_MEMORY;
}
- if (mDataFormat != FILE_AS_ARRAYBUFFER) {
- mFileData = (char *) realloc(mFileData, mDataLen + aCount);
- NS_ENSURE_TRUE(mFileData, NS_ERROR_OUT_OF_MEMORY);
- }
+ MOZ_DIAGNOSTIC_ASSERT(mFileData);
+ MOZ_RELEASE_ASSERT((mDataLen + aCount) <= mTotal);
- uint32_t bytesRead = 0;
- MOZ_DIAGNOSTIC_ASSERT(mFileData);
nsresult rv = mAsyncStream->Read(mFileData + mDataLen, aCount, &bytesRead);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
-
- MOZ_ASSERT(bytesRead == aCount, "failed to read data");
}
- mDataLen += aCount;
+ mDataLen += bytesRead;
return NS_OK;
}
// Helper methods
void
FileReader::ReadFileContent(Blob& aBlob,
const nsAString &aCharset,
@@ -411,18 +406,25 @@ FileReader::ReadFileContent(Blob& aBlob,
MOZ_ASSERT(mAsyncStream);
mTotal = mBlob->GetSize(aRv);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
- if (mDataFormat == FILE_AS_ARRAYBUFFER) {
- mFileData = js_pod_malloc<char>(mTotal);
+ // Binary Format doesn't need a post-processing of the data. Everything is
+ // written directly into mResult.
+ if (mDataFormat != FILE_AS_BINARY) {
+ if (mDataFormat == FILE_AS_ARRAYBUFFER) {
+ mFileData = js_pod_malloc<char>(mTotal);
+ } else {
+ mFileData = (char *) malloc(mTotal);
+ }
+
if (!mFileData) {
NS_WARNING("Preallocation failed for ReadFileData");
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return;
}
}
aRv = DoAsyncWait();