From 2069ea698f4ff570c7d065b899f16a88725aca85 Mon Sep 17 00:00:00 2001 From: Hans Christian Schmitz Date: Tue, 31 Aug 2021 19:00:50 +0200 Subject: [PATCH] Implement fuzzing for the GLSL parser (#1301) * Implement fuzzing for the GLSL parser * Remove arbitrary dependency from naga Derive `Arbitrary` for proxy objects in `fuzz/fuzz_targets/glsl_parser.rs` instead. --- fuzz/Cargo.toml | 9 ++++++- fuzz/fuzz_targets/glsl_parser.rs | 46 ++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 fuzz/fuzz_targets/glsl_parser.rs 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); +});