Skip to content

Commit

Permalink
Adjust fuzzing configs to match what's in QuickJS (#836)
Browse files Browse the repository at this point in the history
* Adjust fuzzing configs to match what's in QuickJS

* Forgot we set the GC here. It gets overriden by the later call.
  • Loading branch information
jeffcharles authored Nov 19, 2024
1 parent d8fc3c3 commit bfd6176
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 9 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ wasmtime = "23"
wasmtime-wasi = "23"
wasi-common = "23"
anyhow = "1.0"
javy = { path = "crates/javy", version = "3.0.3-alpha.1" }
javy = { path = "crates/javy", version = "3.1.0-alpha.1" }
tempfile = "3.13.0"
uuid = { version = "1.11", features = ["v4"] }
serde = { version = "1.0", default-features = false }
Expand Down
4 changes: 4 additions & 0 deletions crates/javy/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

- `gc_threshold`, `memory_limit`, and `max_stack_size` properties for `Config`.

## [3.0.2] - 2024-11-12

### Changed
Expand Down
2 changes: 1 addition & 1 deletion crates/javy/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "javy"
version = "3.0.3-alpha.1"
version = "3.1.0-alpha.1"
authors.workspace = true
edition.workspace = true
license.workspace = true
Expand Down
32 changes: 32 additions & 0 deletions crates/javy/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ pub struct Config {
/// This setting requires the `JSON` intrinsic to be enabled, and the `json`
/// crate feature to be enabled as well.
pub(crate) simd_json_builtins: bool,
/// The threshold to trigger garbage collection. Default is usize::MAX.
pub(crate) gc_threshold: usize,
/// The limit on the max amount of memory the runtime will use. Default is
/// unlimited.
pub(crate) memory_limit: usize,
/// The limit on the max size of stack the runtime will use. Default is
/// 256 * 1024.
pub(crate) max_stack_size: usize,
}

impl Default for Config {
Expand All @@ -71,6 +79,9 @@ impl Default for Config {
javy_intrinsics: JavyIntrinsics::empty(),
redirect_stdout_to_stderr: false,
simd_json_builtins: false,
gc_threshold: usize::MAX,
memory_limit: usize::MAX,
max_stack_size: 256 * 1024, // from rquickjs
}
}
}
Expand Down Expand Up @@ -198,6 +209,27 @@ impl Config {
self
}

/// The number of bytes to use to trigger garbage collection.
/// The default is usize::MAX.
pub fn gc_threshold(&mut self, bytes: usize) -> &mut Self {
self.gc_threshold = bytes;
self
}

/// The limit on the max amount of memory the runtime will use. Default is
/// unlimited.
pub fn memory_limit(&mut self, bytes: usize) -> &mut Self {
self.memory_limit = bytes;
self
}

/// The limit on the max size of stack the runtime will use. Default is
/// 256 * 1024.
pub fn max_stack_size(&mut self, bytes: usize) -> &mut Self {
self.max_stack_size = bytes;
self
}

pub(crate) fn validate(self) -> Result<Self> {
if self.simd_json_builtins && !self.intrinsics.contains(JSIntrinsics::JSON) {
bail!("JSON Intrinsic is required to override JSON.parse and JSON.stringify");
Expand Down
7 changes: 5 additions & 2 deletions crates/javy/src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ impl Runtime {
pub fn new(config: Config) -> Result<Self> {
let rt = ManuallyDrop::new(QRuntime::new()?);

// See comment above about configuring GC behaviour.
rt.set_gc_threshold(usize::MAX);
let context = Self::build_from_config(&rt, config)?;
Ok(Self { inner: rt, context })
}
Expand All @@ -54,6 +52,11 @@ impl Runtime {
let cfg = cfg.validate()?;
let intrinsics = &cfg.intrinsics;
let javy_intrinsics = &cfg.javy_intrinsics;

rt.set_gc_threshold(cfg.gc_threshold);
rt.set_memory_limit(cfg.memory_limit);
rt.set_max_stack_size(cfg.max_stack_size);

// We always set Random given that the principles around snapshotting and
// random are applicable when using Javy from the CLI (the usage of
// Wizer from the CLI is not optional).
Expand Down
33 changes: 29 additions & 4 deletions fuzz/fuzz_targets/json_differential.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,19 @@ static SETUP: Once = Once::new();

fuzz_target!(|data: ArbitraryValue| {
SETUP.call_once(|| {
let mut ref_config = Config::default();
setup_config(&mut ref_config);

let mut config = Config::default();
setup_config(&mut config);
config.simd_json_builtins(true).javy_json(true);

unsafe {
RT = Some(Runtime::new(std::mem::take(&mut config)).expect("Runtime to be created"));
REF_RT =
Some(Runtime::new(Config::default()).expect("Reference runtime to be created"));
REF_RT = Some(
Runtime::new(std::mem::take(&mut ref_config))
.expect("Reference runtime to be created"),
);
};
});

Expand All @@ -36,9 +42,18 @@ fn exec(data: &ArbitraryValue) -> Result<()> {
let mut output: Option<String> = None;
let mut ref_output: Option<String> = None;

let input = data.to_string();
let brace_count = input.chars().filter(|&c| c == '{').count();
// Higher numbers of braces tends to cause a stack overflow (more braces
// use more stack space).
if brace_count > 350 {
return Ok(());
}

rt.context().with(|cx| {
let globals = cx.globals();
globals.set("INPUT", JSString::from_str(cx.clone(), &data.to_string())?)?;

globals.set("INPUT", JSString::from_str(cx.clone(), &input)?)?;

let result: Result<(), _> = cx.eval(JSON_PROGRAM);

Expand All @@ -54,7 +69,7 @@ fn exec(data: &ArbitraryValue) -> Result<()> {

ref_rt.context().with(|cx| {
let globals = cx.globals();
globals.set("INPUT", JSString::from_str(cx.clone(), &data.to_string())?)?;
globals.set("INPUT", JSString::from_str(cx.clone(), &input)?)?;

let result: Result<(), _> = cx.eval(JSON_PROGRAM);

Expand All @@ -72,3 +87,13 @@ fn exec(data: &ArbitraryValue) -> Result<()> {

Ok(())
}

fn setup_config(config: &mut Config) {
config
// https://github.com/bellard/quickjs/blob/6e2e68fd0896957f92eb6c242a2e048c1ef3cae0/quickjs.c#L1644
.gc_threshold(256 * 1024)
// https://github.com/bellard/quickjs/blob/6e2e68fd0896957f92eb6c242a2e048c1ef3cae0/fuzz/fuzz_common.c#L33
.memory_limit(0x4000000)
// https://github.com/bellard/quickjs/blob/6e2e68fd0896957f92eb6c242a2e048c1ef3cae0/fuzz/fuzz_common.c#L35
.max_stack_size(0x10000);
}

0 comments on commit bfd6176

Please sign in to comment.