Bug 250543
| Summary: | ImageData() should return a DOMException if index or size is too big | ||
|---|---|---|---|
| Product: | WebKit | Reporter: | Karl Dubost <karlcow> |
| Component: | Canvas | Assignee: | Nobody <webkit-unassigned> |
| Status: | NEW | ||
| Severity: | Normal | CC: | annevk, dino, foxrider5980, webkit-bug-importer |
| Priority: | P2 | Keywords: | BrowserCompat, GoodFirstBug, InRadar, WPTImpact |
| Version: | Safari Technology Preview | ||
| Hardware: | Unspecified | ||
| OS: | Unspecified | ||
Karl Dubost
new ImageData(1 << 31, 1 << 31);
returns in Safari TP160
rangeerror: Cannot allocate a buffer of this size
while it returns
Firefox: Uncaught DOMException: Index or size is negative or greater than the allowed amount
Chrome: Uncaught DOMException: Failed to construct 'ImageData': The requested image size exceeds the supported range.
See https://searchfox.org/wubkat/rev/12fc92585a259a29b2522e7e902492be45a57b6a/Source/WebCore/html/ImageData.cpp#87-123
This is expected to pass
http://wpt.live/html/canvas/element/pixel-manipulation/2d.imageData.object.ctor.basics.html
https://wpt.fyi/results/html/canvas/element/pixel-manipulation/2d.imageData.object.ctor.basics.html
| Attachments | ||
|---|---|---|
| Add attachment proposed patch, testcase, etc. |
Radar WebKit Bug Importer
<rdar://problem/104461776>
Anne van Kesteren
I think this is a bug in Chromium and Gecko. https://html.spec.whatwg.org/#initialize-an-imagedata-object quite clearly states to reuse the RangeError exception for OOM.
I guess 1 << 31 somehow ends up being treated as a positive integer due to IDL? That's the one thing I'm not totally clear on.
Karl Dubost
As of today, the current spec text:
To initialize an ImageData object imageData,
given
a positive integer number of pixels per row pixelsPerRow,
a positive integer number of rows rows,
an ImageDataSettings settings,
an optional ImageDataArray source,
and an optional PredefinedColorSpace defaultColorSpace:
If source was given:
If
settings["pixelFormat"] equals "rgba-unorm8"
and source is not a Uint8ClampedArray,
then
throw an "InvalidStateError" DOMException. (*INVALID STATE ERROR*)
If
settings["pixelFormat"] is "rgba-float16"
and source is not a Float16Array,
then
throw an "InvalidStateError" DOMException. (*INVALID STATE ERROR*)
Initialize the data attribute of imageData to source.
Otherwise (source was not given):
If
settings["pixelFormat"] is "rgba-unorm8",
then
initialize the data attribute of imageData to a new Uint8ClampedArray object.
The Uint8ClampedArray object must use a new ArrayBuffer for its storage,
and must have a zero byte offset and byte length equal to the length of its storage, in bytes.
The storage ArrayBuffer must have a length of 4 × rows × pixelsPerRow bytes.
Otherwise,
if
settings["pixelFormat"] is "rgba-float16",
then
initialize the data attribute of imageData to a new Float16Array object.
The Float16Array object must use a new ArrayBuffer for its storage,
and must have a zero byte offset and byte length equal to the length of its storage, in bytes.
The storage ArrayBuffer must have a length of 8 × rows × pixelsPerRow bytes.
If
the storage ArrayBuffer could not be allocated,
then
rethrow the RangeError thrown by JavaScript, (*RANGE ERROR*)
and return.
Karl Dubost
1 << 31
is the equivalent to 2³¹ or 2,147,483,648.
The IDL says:
https://html.spec.whatwg.org/#the-imagedata-interface
interface ImageData {
constructor(unsigned long sw, unsigned long sh, optional ImageDataSettings settings = {});
constructor(ImageDataArray data, unsigned long sw, optional unsigned long sh, optional ImageDataSettings settings = {});
readonly attribute unsigned long width;
readonly attribute unsigned long height;
readonly attribute ImageDataArray data;
readonly attribute ImageDataPixelFormat pixelFormat;
readonly attribute PredefinedColorSpace colorSpace;
};
There are different type of tests in the WPT file.
It fails: (WITHOUT A SOURCE)
assert_throws_dom("INDEX_SIZE_ERR", function() { new ImageData(1 << 31, 1 << 31); });
it passes (WITH A SOURCE)
assert_throws_dom("INDEX_SIZE_ERR", function() { new ImageData(imageData.data, 1 << 31); });
assert_throws_dom("INDEX_SIZE_ERR", function() { new ImageData(imageData.data, 1 << 24, 1 << 31); });
it also fails, but for different reasons.
_assertSame(imageDataFromData.data, imageData.data, "imageDataFromData.data", "imageData.data");
_assertSame(imageDataFromData.data, data, "imageDataFromData.data", "data");
So probably, Anne you are right here,
Without a source it should go to the RANGE ERROR
With new ImageData(1 << 31, 1 << 31);
Safari returns
RangeError: Cannot allocate a buffer of this size
Firefox
Uncaught DOMException: Index or size is negative or greater than the allowed amount
Chrome
Uncaught IndexSizeError: Failed to construct 'ImageData': The requested image size exceeds the supported range.
Karl Dubost
Opened https://github.com/web-platform-tests/wpt/issues/55611