script: Let canvas serialization to image fail gracefully (#37184)

Instead of panicking when serialization of canvas to image data (whether
through `toBlob()` or via `toDataURL()`), properly handle failed
serialization. This is an implementation of the appropriate error
handling from the specification text.

Testing: This change includes a new Serov-specific test, because it is
impossible to know what the canvas size limits are of all browsers.
Fixes: #36840.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
Martin Robinson 2025-05-29 18:09:05 +02:00 committed by GitHub
parent 36e4886da1
commit 559ba4b3ee
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 100 additions and 40 deletions

View file

@ -12850,6 +12850,13 @@
]
]
},
"canvas-oversize-serialization.html": [
"3330ee2b8c4e33a18a3e17151fd7c398c9a5d024",
[
null,
{}
]
],
"canvas.initial.reset.2dstate.html": [
"e276ed09ffcf16eff16b784c622b93665c4109ee",
[

View file

@ -0,0 +1,31 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Serializing a large canvas does not panic</title>
<link rel=help href="https://html.spec.whatwg.org/multipage/#dom-canvas-todataurl">
<link rel=help href="https://html.spec.whatwg.org/multipage/#dom-canvas-toblob">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<!-- This is not a standard WPT tests, because canvas size limits are specific
to browsers. For us, failure to serialize depends on both canvas size limits
and also whether or not the image library we use (image-rs) produces an error
when we attempt serialization. -->
<canvas id="canvas" width="2000000"></canvas>
<script>
test(function() {
assert_equals(canvas.toDataURL("image/webp", 0.5), 'data:,');
}, "Calling toDataURL on an oversized canvas results in an empty URL.");
async_test(function(t) {
canvas.toBlob((blob) => {
assert_equals(blob, null);
t.done();
}, "image/webp", 0.5);
}, "Calling toBlob() on an oversized canvas results in a null blob");
</script>
</body>
</html>