diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index a95afc0f44..ceb30ea551 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -9,11 +9,12 @@ edition = "2018" cargo-fuzz = true [dependencies] +arbitrary = { version = "1.0.2", features = ["derive"] } libfuzzer-sys = "0.4" [dependencies.naga] path = ".." -features = ["spv-in", "wgsl-in"] +features = ["spv-in", "wgsl-in", "glsl-in"] # Prevent this from interfering with workspaces [workspace] @@ -30,3 +31,9 @@ name = "wgsl_parser" path = "fuzz_targets/wgsl_parser.rs" test = false doc = false + +[[bin]] +name = "glsl_parser" +path = "fuzz_targets/glsl_parser.rs" +test = false +doc = false diff --git a/fuzz/fuzz_targets/glsl_parser.rs b/fuzz/fuzz_targets/glsl_parser.rs new file mode 100644 index 0000000000..b600eb513f --- /dev/null +++ b/fuzz/fuzz_targets/glsl_parser.rs @@ -0,0 +1,46 @@ +#![no_main] +use arbitrary::Arbitrary; +use libfuzzer_sys::fuzz_target; +use naga::{ + front::glsl::{Options, Parser}, + FastHashMap, ShaderStage, +}; + +#[derive(Debug, Arbitrary)] +enum ShaderStageProxy { + Vertex, + Fragment, + Compute, +} + +impl From for ShaderStage { + fn from(proxy: ShaderStageProxy) -> Self { + match proxy { + ShaderStageProxy::Vertex => ShaderStage::Vertex, + ShaderStageProxy::Fragment => ShaderStage::Fragment, + ShaderStageProxy::Compute => ShaderStage::Compute, + } + } +} + +#[derive(Debug, Arbitrary)] +struct OptionsProxy { + pub stage: ShaderStageProxy, + pub defines: FastHashMap, +} + +impl From for Options { + fn from(proxy: OptionsProxy) -> Self { + Options { + stage: proxy.stage.into(), + defines: proxy.defines, + } + } +} + +fuzz_target!(|data: (OptionsProxy, String)| { + let (options, source) = data; + // Ensure the parser can handle potentially malformed strings without crashing. + let mut parser = Parser::default(); + let _result = parser.parse(&options.into(), &source); +});