Skip to content

Commit

Permalink
Merge pull request #803 from silvergasp/fuzz-ast
Browse files Browse the repository at this point in the history
fuzz: Add ast fuzzer
  • Loading branch information
schungx committed Dec 31, 2023
2 parents 0e884ab + bf187e1 commit f505f42
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 0 deletions.
7 changes: 7 additions & 0 deletions fuzz/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ edition = "2018"
cargo-fuzz = true

[dependencies]
anyhow = "1.0.78"
arbitrary = { version = "1.3.2", features = ["derive"] }
libfuzzer-sys = "0.4"
rhai = { path = "..", features = ["fuzz", "decimal", "metadata", "debugging"] }
Expand All @@ -24,3 +25,9 @@ name = "scripting"
path = "fuzz_targets/scripting.rs"
test = false
doc = false

[[bin]]
name = "ast"
path = "fuzz_targets/ast.rs"
test = false
doc = false
56 changes: 56 additions & 0 deletions fuzz/fuzz_targets/ast.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#![no_main]
use rhai::{Engine, OptimizationLevel};

use anyhow::Result;
use arbitrary::Arbitrary;
use libfuzzer_sys::fuzz_target;
use std::{hint::black_box};

#[derive(Debug, Clone, Arbitrary)]
struct Ctx<'a> {
script: &'a str,
optimization_level: OptimizationLevel,
}

fn fuzz(ctx: Ctx) -> Result<()> {
let mut engine = Engine::new();

engine.set_max_string_size(1000);
engine.set_max_array_size(500);
engine.set_max_map_size(500);
engine.set_max_variables(1000);
engine.set_max_modules(1000);
engine.set_max_call_levels(10);
engine.set_max_expr_depths(50, 5);
engine.set_optimization_level(ctx.optimization_level);

// Don't actually print to stdout, but also don't optimise
// printing code away.
engine.on_debug(|x, src, pos| _ = black_box((x, src, pos)));
engine.on_print(move |s| {
_ = black_box(s);
});

// Limit the length of scripts.
let script = ctx.script.chars().take(32 * 1024).collect::<String>();

let ast = engine.compile(script)?;
_ = black_box(format!("{ast:?}"));
_ = black_box(ast.iter_functions().count());
_ = black_box(ast.iter_literal_variables(true, true).count());
_ = black_box(ast.walk(&mut |_| true));

let mut function_only_ast = ast.clone_functions_only();
assert!(function_only_ast.clear_functions().iter_functions().count() == 0);

let function_only_ast = ast.clone_functions_only_filtered(|_, _, _, _, _| true);
_ = black_box(function_only_ast.merge(&ast));

Ok(())
}

fuzz_target!(|ctx: Ctx| {
if let Err(e) = fuzz(ctx) {
_ = black_box(format!("{e}"));
}
});

0 comments on commit f505f42

Please sign in to comment.