diff --git a/ext/canvas/lib.rs b/ext/canvas/lib.rs index 97adfdbb93..a8bae55531 100644 --- a/ext/canvas/lib.rs +++ b/ext/canvas/lib.rs @@ -8,6 +8,7 @@ use image::imageops::FilterType; use image::AnimationDecoder; use image::GenericImage; use image::GenericImageView; +use image::ImageDecoder; use image::Pixel; use serde::Deserialize; use serde::Serialize; @@ -210,10 +211,16 @@ fn op_image_decode( if decoder.is_apng()? { return Err(type_error("Animation image is not supported.")); } + if decoder.color_type() != image::ColorType::Rgba8 { + return Err(type_error("Supports 8-bit RGBA only.")); + } image::DynamicImage::from_decoder(decoder)? } "image/jpeg" => { let decoder = image::codecs::jpeg::JpegDecoder::new(reader)?; + if decoder.color_type() != image::ColorType::Rgb8 { + return Err(type_error("Supports 8-bit RGB only.")); + } image::DynamicImage::from_decoder(decoder)? } "image/gif" => { @@ -227,10 +234,16 @@ fn op_image_decode( } "image/bmp" => { let decoder = image::codecs::bmp::BmpDecoder::new(reader)?; + if decoder.color_type() != image::ColorType::Rgba8 { + return Err(type_error("Supports 8-bit RGBA only.")); + } image::DynamicImage::from_decoder(decoder)? } "image/x-icon" => { let decoder = image::codecs::ico::IcoDecoder::new(reader)?; + if decoder.color_type() != image::ColorType::Rgba8 { + return Err(type_error("Supports 8-bit RGBA only.")); + } image::DynamicImage::from_decoder(decoder)? } "image/webp" => { diff --git a/tests/testdata/image/1x1-red16.png b/tests/testdata/image/1x1-red16.png new file mode 100644 index 0000000000..ee9e279c14 Binary files /dev/null and b/tests/testdata/image/1x1-red16.png differ diff --git a/tests/unit/image_bitmap_test.ts b/tests/unit/image_bitmap_test.ts index faceb198fb..a988145fa2 100644 --- a/tests/unit/image_bitmap_test.ts +++ b/tests/unit/image_bitmap_test.ts @@ -162,6 +162,13 @@ Deno.test(async function imageBitmapFromBlob() { // deno-fmt-ignore assertEquals(Deno[Deno.internal].getBitmapData(imageBitmap), new Uint8Array([255, 0, 0, 255])); } + { + const imageData = new Blob( + [await Deno.readFile(`${prefix}/1x1-red16.png`)], + { type: "image/png" }, + ); + await assertRejects(() => createImageBitmap(imageData), TypeError); + } { const imageData = new Blob( [await Deno.readFile(`${prefix}/1x1-red8.jpeg`)],