From 47d20d913dea40997711f3be9146cc60cf4fa156 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Gyebn=C3=A1r?= Date: Thu, 7 Nov 2024 16:35:36 +0100 Subject: [PATCH] Fixes crash when there's a missing texture argument (#6486) --- CHANGELOG.md | 4 ++++ naga/src/valid/analyzer.rs | 10 ++++++++-- naga/tests/validation.rs | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index abfbe5ee7..2087875ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,6 +64,10 @@ Bottom level categories: ### Bug Fixes +#### Naga + +- Fix crash when a texture argument is missing. By @aedm in [#6486](https://github.com/gfx-rs/wgpu/pull/6486) + #### General - Ensure that `Features::TIMESTAMP_QUERY` is set when using timestamp writes in render and compute passes. By @ErichDonGubler in [#6497](https://github.com/gfx-rs/wgpu/pull/6497). diff --git a/naga/src/valid/analyzer.rs b/naga/src/valid/analyzer.rs index af95fd098..6b4679632 100644 --- a/naga/src/valid/analyzer.rs +++ b/naga/src/valid/analyzer.rs @@ -421,7 +421,10 @@ impl FunctionInfo { let image_storage = match sampling.image { GlobalOrArgument::Global(var) => GlobalOrArgument::Global(var), GlobalOrArgument::Argument(i) => { - let handle = arguments[i as usize]; + let Some(handle) = arguments.get(i as usize).cloned() else { + // Argument count mismatch, will be reported later by validate_call + break; + }; GlobalOrArgument::from_expression(expression_arena, handle).map_err( |source| { FunctionError::Expression { handle, source } @@ -434,7 +437,10 @@ impl FunctionInfo { let sampler_storage = match sampling.sampler { GlobalOrArgument::Global(var) => GlobalOrArgument::Global(var), GlobalOrArgument::Argument(i) => { - let handle = arguments[i as usize]; + let Some(handle) = arguments.get(i as usize).cloned() else { + // Argument count mismatch, will be reported later by validate_call + break; + }; GlobalOrArgument::from_expression(expression_arena, handle).map_err( |source| { FunctionError::Expression { handle, source } diff --git a/naga/tests/validation.rs b/naga/tests/validation.rs index b8a30c49b..df8fad2ac 100644 --- a/naga/tests/validation.rs +++ b/naga/tests/validation.rs @@ -606,3 +606,40 @@ fn binding_arrays_cannot_hold_scalars() { assert!(t.validator.validate(&t.module).is_err()); } + +#[cfg(feature = "wgsl-in")] +#[test] +fn validation_error_messages() { + let cases = [( + r#"@group(0) @binding(0) var my_sampler: sampler; + + fn foo(tex: texture_2d) -> vec4 { + return textureSampleLevel(tex, my_sampler, vec2f(0, 0), 0.0); + } + + fn main() { + foo(); + } + "#, + "\ +error: Function [1] 'main' is invalid + ┌─ wgsl:7:17 + │ \n7 │ ╭ fn main() { +8 │ │ foo(); + │ │ ^^^^ invalid function call + │ ╰──────────────────────────^ naga::Function [1] + │ \n = Call to [0] is invalid + = Requires 1 arguments, but 0 are provided + +", + )]; + + for (source, expected_err) in cases { + let module = naga::front::wgsl::parse_str(source).unwrap(); + let err = valid::Validator::new(Default::default(), valid::Capabilities::all()) + .validate_no_overrides(&module) + .expect_err("module should be invalid"); + println!("{}", err.emit_to_string(source)); + assert_eq!(err.emit_to_string(source), expected_err); + } +}