Bug 250543

Summary: ImageData() should return a DOMException if index or size is too big
Product: WebKit Reporter: Karl Dubost <karlcow>
Component: CanvasAssignee: 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
Reported 2023-01-12 21:24:19 PST
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
Radar WebKit Bug Importer
Comment 1 2023-01-19 21:25:17 PST
Anne van Kesteren
Comment 2 2023-08-26 08:16:53 PDT
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
Comment 3 2025-05-29 19:36:39 PDT
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
Comment 4 2025-05-29 20:01:15 PDT
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
Comment 6 2025-10-22 22:46:28 PDT
Note You need to log in before you can comment on or make changes to this bug.