mirror of
https://github.com/servo/servo
synced 2026-04-25 17:15:48 +02:00
script: Fix panic in compressedTexSubImage2D when no base image exists (#44050)
Calling `compressedTexSubImage2D` without a prior `compressedTexImage2D` for the same texture target and level caused the panic at `tex_image_2d.rs:633` because `image_info_for_target` returned `None` and `.unwrap()` was called on it. Per the WebGL spec, this should generate `GL_INVALID_OPERATION` instead of panicking. So this PR replaces the unwrap with proper error handling. And also includes a WPT crash test that reproduces the original panic. Fixes #43527 --------- Signed-off-by: thebabalola <t.babalolajoseph@gmail.com>
This commit is contained in:
@@ -53,6 +53,8 @@ pub(crate) enum TexImageValidationError {
|
||||
InvalidCompressionFormat,
|
||||
/// Invalid X/Y texture offset parameters.
|
||||
InvalidOffsets,
|
||||
/// No base image has been defined for this texture target and level.
|
||||
MissingBaseTexture,
|
||||
}
|
||||
|
||||
impl std::error::Error for TexImageValidationError {}
|
||||
@@ -80,6 +82,7 @@ impl fmt::Display for TexImageValidationError {
|
||||
NonPotTexture => "Expected a power of two texture",
|
||||
InvalidCompressionFormat => "Unrecognized texture compression format",
|
||||
InvalidOffsets => "Invalid X/Y texture offset parameters",
|
||||
MissingBaseTexture => "No base image defined for this texture target and level",
|
||||
};
|
||||
write!(f, "TexImageValidationError({})", description)
|
||||
}
|
||||
@@ -630,7 +633,12 @@ impl WebGLValidator for CompressedTexSubImage2DValidator<'_> {
|
||||
compression,
|
||||
} = self.compression_validator.validate()?;
|
||||
|
||||
let tex_info = texture.image_info_for_target(&target, level).unwrap();
|
||||
// GL_INVALID_OPERATION is generated if no base image has been defined
|
||||
// for this texture target and level via compressedTexImage2D.
|
||||
let Some(tex_info) = texture.image_info_for_target(&target, level) else {
|
||||
context.webgl_error(InvalidOperation);
|
||||
return Err(TexImageValidationError::MissingBaseTexture);
|
||||
};
|
||||
|
||||
// GL_INVALID_VALUE is generated if:
|
||||
// - xoffset or yoffset is less than 0
|
||||
|
||||
26
tests/wpt/meta/MANIFEST.json
vendored
26
tests/wpt/meta/MANIFEST.json
vendored
@@ -244603,7 +244603,7 @@
|
||||
"before-after-pseudo-element-scrolling.html": [
|
||||
"805c01af85b7e01f73bda4a1ee90db50fa83ce60",
|
||||
[
|
||||
"css/css-overflow/before-after-pseudo-element-scrolling.html",
|
||||
null,
|
||||
[
|
||||
[
|
||||
"/css/css-overflow/reference/before-after-pseudo-element-scrolling-ref.html",
|
||||
@@ -295379,7 +295379,7 @@
|
||||
"word-break-keep-all-011.html": [
|
||||
"c1d7af2496894ef609115d3b4fc01cb54ffb32a7",
|
||||
[
|
||||
"css/css-text/word-break/word-break-keep-all-011.html",
|
||||
null,
|
||||
[
|
||||
[
|
||||
"/css/css-text/word-break/reference/word-break-keep-all-011-ref.html",
|
||||
@@ -378843,7 +378843,7 @@
|
||||
"caret-visibility-after-creation-in-script.html": [
|
||||
"6e9e8fd1618fd9fd4bb90a1bc2a8199c2e447764",
|
||||
[
|
||||
"html/rendering/replaced-elements/the-textarea-element/caret-visibility-after-creation-in-script.html",
|
||||
null,
|
||||
[
|
||||
[
|
||||
"/html/rendering/replaced-elements/the-textarea-element/caret-visibility-after-creation-in-script-ref.html",
|
||||
@@ -563188,10 +563188,6 @@
|
||||
"a5e37dce95b00834aa3d3b58008762f5801e9e5d",
|
||||
[]
|
||||
],
|
||||
"browser.runtime.extension.js": [
|
||||
"c41a1b795ea829493364767e9ea3403f0586c1bc",
|
||||
[]
|
||||
],
|
||||
"resources": {
|
||||
"runtime": {
|
||||
"background.js": [
|
||||
@@ -902757,6 +902753,15 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"web-extensions": {
|
||||
"browser.runtime.extension.js": [
|
||||
"c41a1b795ea829493364767e9ea3403f0586c1bc",
|
||||
[
|
||||
"web-extensions/browser.runtime.extension.html",
|
||||
{}
|
||||
]
|
||||
]
|
||||
},
|
||||
"web-locks": {
|
||||
"acquire.https.any.js": [
|
||||
"54ae6f30e7add6f45c6b5ba7161999b5a6078871",
|
||||
@@ -915672,6 +915677,13 @@
|
||||
{}
|
||||
]
|
||||
],
|
||||
"compressed-tex-sub-image-2d-without-base-image.html": [
|
||||
"4627a2b4ba3c6759d5bd1194c6a86c97b466165f",
|
||||
[
|
||||
null,
|
||||
{}
|
||||
]
|
||||
],
|
||||
"compressedTexImage2D.html": [
|
||||
"a974c65002448c0df1beb97f93d5cd1476f254ca",
|
||||
[
|
||||
|
||||
37
tests/wpt/tests/webgl/compressed-tex-sub-image-2d-without-base-image.html
vendored
Normal file
37
tests/wpt/tests/webgl/compressed-tex-sub-image-2d-without-base-image.html
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<!doctype html>
|
||||
<title>compressedTexSubImage2D without prior compressedTexImage2D generates INVALID_OPERATION</title>
|
||||
<link rel=author title="Babalola Taiwo Joseph" href=mailto:t.babalolajoseph@gmail.com>
|
||||
<link rel=help href=https://www.khronos.org/registry/webgl/specs/latest/#5.14.8>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
|
||||
<div id=log></div>
|
||||
<script>
|
||||
test(function() {
|
||||
var canvas = document.createElement("canvas");
|
||||
var gl = canvas.getContext("webgl");
|
||||
assert_true(!!gl, "WebGL context should be available");
|
||||
|
||||
var s3tc = gl.getExtension("WEBGL_compressed_texture_s3tc");
|
||||
var etc1 = gl.getExtension("WEBGL_compressed_texture_etc1");
|
||||
|
||||
var format, dataSize;
|
||||
if (s3tc) {
|
||||
format = s3tc.COMPRESSED_RGB_S3TC_DXT1_EXT;
|
||||
dataSize = 8;
|
||||
} else if (etc1) {
|
||||
format = etc1.COMPRESSED_RGB_ETC1_WEBGL;
|
||||
dataSize = 8;
|
||||
}
|
||||
|
||||
assert_true(!!format, "A supported compressed texture format must be available");
|
||||
|
||||
var texture = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, texture);
|
||||
|
||||
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 4, 4, format, new Uint8Array(dataSize));
|
||||
|
||||
assert_equals(gl.getError(), gl.INVALID_OPERATION,
|
||||
"compressedTexSubImage2D without a prior compressedTexImage2D should generate INVALID_OPERATION");
|
||||
}, "compressedTexSubImage2D without base image generates INVALID_OPERATION");
|
||||
</script>
|
||||
Reference in New Issue
Block a user