Skip to content

Commit bfd6176

Browse files
authored
Adjust fuzzing configs to match what's in QuickJS (#836)
* Adjust fuzzing configs to match what's in QuickJS * Forgot we set the GC here. It gets overriden by the later call.
1 parent d8fc3c3 commit bfd6176

File tree

7 files changed

+73
-9
lines changed

7 files changed

+73
-9
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ wasmtime = "23"
2323
wasmtime-wasi = "23"
2424
wasi-common = "23"
2525
anyhow = "1.0"
26-
javy = { path = "crates/javy", version = "3.0.3-alpha.1" }
26+
javy = { path = "crates/javy", version = "3.1.0-alpha.1" }
2727
tempfile = "3.13.0"
2828
uuid = { version = "1.11", features = ["v4"] }
2929
serde = { version = "1.0", default-features = false }

crates/javy/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ Versioning](https://semver.org/spec/v2.0.0.html).
88

99
## [Unreleased]
1010

11+
### Added
12+
13+
- `gc_threshold`, `memory_limit`, and `max_stack_size` properties for `Config`.
14+
1115
## [3.0.2] - 2024-11-12
1216

1317
### Changed

crates/javy/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "javy"
3-
version = "3.0.3-alpha.1"
3+
version = "3.1.0-alpha.1"
44
authors.workspace = true
55
edition.workspace = true
66
license.workspace = true

crates/javy/src/config.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,14 @@ pub struct Config {
5959
/// This setting requires the `JSON` intrinsic to be enabled, and the `json`
6060
/// crate feature to be enabled as well.
6161
pub(crate) simd_json_builtins: bool,
62+
/// The threshold to trigger garbage collection. Default is usize::MAX.
63+
pub(crate) gc_threshold: usize,
64+
/// The limit on the max amount of memory the runtime will use. Default is
65+
/// unlimited.
66+
pub(crate) memory_limit: usize,
67+
/// The limit on the max size of stack the runtime will use. Default is
68+
/// 256 * 1024.
69+
pub(crate) max_stack_size: usize,
6270
}
6371

6472
impl Default for Config {
@@ -71,6 +79,9 @@ impl Default for Config {
7179
javy_intrinsics: JavyIntrinsics::empty(),
7280
redirect_stdout_to_stderr: false,
7381
simd_json_builtins: false,
82+
gc_threshold: usize::MAX,
83+
memory_limit: usize::MAX,
84+
max_stack_size: 256 * 1024, // from rquickjs
7485
}
7586
}
7687
}
@@ -198,6 +209,27 @@ impl Config {
198209
self
199210
}
200211

212+
/// The number of bytes to use to trigger garbage collection.
213+
/// The default is usize::MAX.
214+
pub fn gc_threshold(&mut self, bytes: usize) -> &mut Self {
215+
self.gc_threshold = bytes;
216+
self
217+
}
218+
219+
/// The limit on the max amount of memory the runtime will use. Default is
220+
/// unlimited.
221+
pub fn memory_limit(&mut self, bytes: usize) -> &mut Self {
222+
self.memory_limit = bytes;
223+
self
224+
}
225+
226+
/// The limit on the max size of stack the runtime will use. Default is
227+
/// 256 * 1024.
228+
pub fn max_stack_size(&mut self, bytes: usize) -> &mut Self {
229+
self.max_stack_size = bytes;
230+
self
231+
}
232+
201233
pub(crate) fn validate(self) -> Result<Self> {
202234
if self.simd_json_builtins && !self.intrinsics.contains(JSIntrinsics::JSON) {
203235
bail!("JSON Intrinsic is required to override JSON.parse and JSON.stringify");

crates/javy/src/runtime.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,6 @@ impl Runtime {
4444
pub fn new(config: Config) -> Result<Self> {
4545
let rt = ManuallyDrop::new(QRuntime::new()?);
4646

47-
// See comment above about configuring GC behaviour.
48-
rt.set_gc_threshold(usize::MAX);
4947
let context = Self::build_from_config(&rt, config)?;
5048
Ok(Self { inner: rt, context })
5149
}
@@ -54,6 +52,11 @@ impl Runtime {
5452
let cfg = cfg.validate()?;
5553
let intrinsics = &cfg.intrinsics;
5654
let javy_intrinsics = &cfg.javy_intrinsics;
55+
56+
rt.set_gc_threshold(cfg.gc_threshold);
57+
rt.set_memory_limit(cfg.memory_limit);
58+
rt.set_max_stack_size(cfg.max_stack_size);
59+
5760
// We always set Random given that the principles around snapshotting and
5861
// random are applicable when using Javy from the CLI (the usage of
5962
// Wizer from the CLI is not optional).

fuzz/fuzz_targets/json_differential.rs

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,19 @@ static SETUP: Once = Once::new();
1717

1818
fuzz_target!(|data: ArbitraryValue| {
1919
SETUP.call_once(|| {
20+
let mut ref_config = Config::default();
21+
setup_config(&mut ref_config);
22+
2023
let mut config = Config::default();
24+
setup_config(&mut config);
2125
config.simd_json_builtins(true).javy_json(true);
2226

2327
unsafe {
2428
RT = Some(Runtime::new(std::mem::take(&mut config)).expect("Runtime to be created"));
25-
REF_RT =
26-
Some(Runtime::new(Config::default()).expect("Reference runtime to be created"));
29+
REF_RT = Some(
30+
Runtime::new(std::mem::take(&mut ref_config))
31+
.expect("Reference runtime to be created"),
32+
);
2733
};
2834
});
2935

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

45+
let input = data.to_string();
46+
let brace_count = input.chars().filter(|&c| c == '{').count();
47+
// Higher numbers of braces tends to cause a stack overflow (more braces
48+
// use more stack space).
49+
if brace_count > 350 {
50+
return Ok(());
51+
}
52+
3953
rt.context().with(|cx| {
4054
let globals = cx.globals();
41-
globals.set("INPUT", JSString::from_str(cx.clone(), &data.to_string())?)?;
55+
56+
globals.set("INPUT", JSString::from_str(cx.clone(), &input)?)?;
4257

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

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

5570
ref_rt.context().with(|cx| {
5671
let globals = cx.globals();
57-
globals.set("INPUT", JSString::from_str(cx.clone(), &data.to_string())?)?;
72+
globals.set("INPUT", JSString::from_str(cx.clone(), &input)?)?;
5873

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

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

7388
Ok(())
7489
}
90+
91+
fn setup_config(config: &mut Config) {
92+
config
93+
// https://github.com/bellard/quickjs/blob/6e2e68fd0896957f92eb6c242a2e048c1ef3cae0/quickjs.c#L1644
94+
.gc_threshold(256 * 1024)
95+
// https://github.com/bellard/quickjs/blob/6e2e68fd0896957f92eb6c242a2e048c1ef3cae0/fuzz/fuzz_common.c#L33
96+
.memory_limit(0x4000000)
97+
// https://github.com/bellard/quickjs/blob/6e2e68fd0896957f92eb6c242a2e048c1ef3cae0/fuzz/fuzz_common.c#L35
98+
.max_stack_size(0x10000);
99+
}

0 commit comments

Comments
 (0)