Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adjust fuzzing configs to match what's in QuickJS #836

Merged
merged 2 commits into from
Nov 19, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
5 changes: 5 additions & 0 deletions crates/javy/src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,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);
}
Loading