Firefox crashes on FileReader readAsDataURL of large file (>100mb)
Categories
(Core :: DOM: File, defect, P3)
Tracking
()
People
(Reporter: cian, Assigned: sg)
References
Details
(Keywords: crash, testcase)
Crash Data
Attachments
(2 files, 1 obsolete file)
Updated•12 years ago
|
| Reporter | ||
Comment 2•12 years ago
|
||
| Reporter | ||
Updated•12 years ago
|
Updated•12 years ago
|
Comment 3•12 years ago
|
||
| Reporter | ||
Comment 4•12 years ago
|
||
| Reporter | ||
Comment 5•12 years ago
|
||
Updated•12 years ago
|
Comment 6•12 years ago
|
||
Comment 7•12 years ago
|
||
Comment 8•12 years ago
|
||
Comment 9•12 years ago
|
||
Updated•12 years ago
|
Updated•10 years ago
|
Updated•7 years ago
|
Updated•6 years ago
|
Updated•5 years ago
|
Comment 10•5 years ago
|
||
Trying with current nightly the test still crashes (with a 2.4 GB file)
Apparently we have an OOM error treatment here:
if (!AppendASCIItoUTF16(encodedData, aResult, fallible)) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
that does not work well such that we encounter this MOZ_RELEASE_ASSERT. Unfortunately the code of AppendASCIItoUTF16 seems to be inlined, the next step would be to try the same with a debug build.
Comment 11•5 years ago
|
||
I suspect we are crashing at the Substring in Base64Encode(Substring(aFileData, aDataLen), encodedData) beforehand.
Comment 12•5 years ago
•
|
||
Ah, that might have been inlined here as well, thanks. There inside I read:
if (aBinary.Length() > (UINT32_MAX / 4) * 3) {
return NS_ERROR_FAILURE;
}
which is indeed > 2.4 GB and might differ from kMaxCapacity which I assume is < 2.4 GB (probably 2 GB minus some bytes?).
This would indicate that files of size < aprox. 2 GB can work (if we have enough memory), such that I would not be to worried about impact here (probably kMaxCapacity once was much smaller? The current boundary formula dates from 2017 according to bug 1349719). Still the error handling and different max. constants in use should be improved here, IMHO.
Comment 13•5 years ago
•
|
||
Running the crash in the debugger confirms the assumption from comment 11.
Though Substring just wraps the already allocated memory here it still checks the length against its kMaxCapacity member, which is significantly lower (aprox. 1GB) - and issues a MOZ_RELEASE_ASSERT(CheckCapacity(aLength), "String is too large.");. Though I can understand the rationale behind assuming string allocations to not require explicit OOM error handling, in this case it would be advisable to have it.
A naive approach could be to hand-check the allowed capacity like
// CheckCapacity checks, if the data can fit into a nsTSubstring
if (!nsTSubstring<char>::CheckCapacity(aDataLen)) {
return NS_ERROR_OUT_OF_MEMORY;
}
auto tmp = Substring(aFileData, aDataLen);
nsCString encodedData;
nsresult rv = Base64Encode(tmp, encodedData);
NS_ENSURE_SUCCESS(rv, rv);
but nsTSubstring<char>::CheckCapacity(aDataLen) is a protected member of nsTSubstring. Probably a cleaner approach would be to add a public static function that checks capacity before constructing the substring object?
Comment 14•5 years ago
•
|
||
(In reply to Jens Stutte [:jstutte] (REO for FF 81) from comment #12)
This would indicate that files of size < aprox. 2 GB can work (if we have enough memory)
So looking at the value of kMaxCapacity, the debugger tells me indeed that it's 2147483637, which is "aprox. 2 GB". The rationale behind this is probably to be safe against signed/unsigned conversions of 32Bit length values. The hard limit for length would be uint_32, it seems.
I see two options here:
-
Define an own (lower)
const uint32_t kMaxFileAsDataURLLength = 2147400000;and check it beforehand. This is probably safe, as it is very unlikely, that future modifications ofnsTSubstringwill reducekMaxCapacitysignificantly or thatuint32_twill ever have more/less than 32 bit (still a constant reads kind of bad here). -
Add a factory function with error handling and use it here (and who knows where else). This is probably only a good idea, if we expect more places in our codebase where we could hit this limit through normal operations.
If I try 1), I get an alert "Problem while reading ubuntu-19.10-desktop-amd64(1).iso (2463842304 bytes): NotReadableError", which is probably an improvable error message for this case, but the crash goes away.
Comment 15•5 years ago
|
||
Updated•5 years ago
|
| Assignee | ||
Comment 16•5 years ago
|
||
Updated•5 years ago
|
| Assignee | ||
Updated•5 years ago
|
| Assignee | ||
Updated•5 years ago
|
Comment 17•5 years ago
|
||
Comment 18•5 years ago
|
||
| bugherder | ||
Updated•5 years ago
|
Description
•