Bug 1716622 - Limit ImageData typed array to 2 GB. r=edgar

After we enabled support for large ArrayBuffers on 64-bit platforms, we could
also create larger ImageData objects. WebIDL bindings check for large ArrayBuffer{View}s
but not when they're wrapped in an ImageData.

It seems safest to limit ImageData arrays to the old 2 GB for now until we need larger
buffers.

Differential Revision: https://phabricator.services.mozilla.com/D121595
This commit is contained in:
Jan de Mooij
2021-08-06 14:23:24 +00:00
parent e8fe7ba0e7
commit 1279a55a8f
3 changed files with 66 additions and 2 deletions

View File

@@ -93,3 +93,4 @@ skip-if = debug == false
skip-if = debug == false
[test_large_arraybuffers.html]
skip-if = (debug == false || bits == 32) # Large ArrayBuffers are only supported on 64-bit platforms.
[test_large_imageData.html]

View File

@@ -0,0 +1,59 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1716622
-->
<head>
<meta charset="utf-8">
<title>Test for large ImageData</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1716622">Mozilla Bug 1716622</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
<canvas id="canvas" width="800" height="800"></canvas>
<script type="application/javascript">
SimpleTest.waitForExplicitFinish();
function go() {
var ctx = document.getElementById("canvas").getContext("2d");
var ex = null;
try {
ctx.createImageData(23175, 23175);
} catch (e) {
ex = e;
}
ok(ex.toString().includes("Invalid width or height"),
"Expected createImageData exception");
ex = null;
try {
ctx.createImageData(33000, 33000);
} catch (e) {
ex = e;
}
ok(ex.toString().includes("Invalid width or height"),
"Expected createImageData exception");
ex = null;
try {
ctx.getImageData(0, 0, 23175, 23175);
} catch (e) {
ex = e;
}
ok(ex.toString().includes("negative or greater than the allowed amount"),
"Expected getImageData exception");
SimpleTest.finish();
}
go();
</script>
</body>
</html>

View File

@@ -5048,8 +5048,10 @@ nsresult CanvasRenderingContext2D::GetImageDataArray(
nsIPrincipal& aSubjectPrincipal, JSObject** aRetval) {
MOZ_ASSERT(aWidth && aHeight);
// Restrict the typed array length to INT32_MAX because that's all we support
// in dom::TypedArray::ComputeState.
CheckedInt<uint32_t> len = CheckedInt<uint32_t>(aWidth) * aHeight * 4;
if (!len.isValid()) {
if (!len.isValid() || len.value() > INT32_MAX) {
return NS_ERROR_DOM_INDEX_SIZE_ERR;
}
@@ -5334,8 +5336,10 @@ static already_AddRefed<ImageData> CreateImageData(
if (aW == 0) aW = 1;
if (aH == 0) aH = 1;
// Restrict the typed array length to INT32_MAX because that's all we support
// in dom::TypedArray::ComputeState.
CheckedInt<uint32_t> len = CheckedInt<uint32_t>(aW) * aH * 4;
if (!len.isValid()) {
if (!len.isValid() || len.value() > INT32_MAX) {
aError.ThrowIndexSizeError("Invalid width or height");
return nullptr;
}