mirror of
https://github.com/elicpeter/nyx.git
synced 2026-07-06 20:42:10 +02:00
[pitboss] sweep after phase 04: 2 deferred items resolved
This commit is contained in:
parent
8583b29796
commit
637b733928
5 changed files with 105 additions and 21 deletions
|
|
@ -131,15 +131,36 @@ fn probe_kind_deserialize_serdes() {
|
|||
|
||||
#[test]
|
||||
fn lang_emitter_dispatches_to_deserialize_harness() {
|
||||
for (lang, entry_file, entry_name, marker) in [
|
||||
(Lang::Java, "tests/dynamic_fixtures/deserialize/java/vuln.java",
|
||||
"run", "RestrictedObjectInputStream"),
|
||||
(Lang::Python, "tests/dynamic_fixtures/deserialize/python/vuln.py",
|
||||
"run", "RestrictedUnpickler"),
|
||||
(Lang::Php, "tests/dynamic_fixtures/deserialize/php/vuln.php",
|
||||
"run", "allowed_classes"),
|
||||
(Lang::Ruby, "tests/dynamic_fixtures/deserialize/ruby/vuln.rb",
|
||||
"run", "Marshal.load"),
|
||||
// `sink_callee_marker` is the per-language deserialize sink call
|
||||
// string the harness writes into the JSON probe record — the
|
||||
// resolveClass / find_class / unserialize / Marshal.load boundary
|
||||
// the brief calls out. Pinning the marker here keeps the test
|
||||
// honest about which guard each lang's harness names.
|
||||
for (lang, entry_file, entry_name, sink_callee_marker) in [
|
||||
(
|
||||
Lang::Java,
|
||||
"tests/dynamic_fixtures/deserialize/java/vuln.java",
|
||||
"run",
|
||||
"ObjectInputStream.resolveClass",
|
||||
),
|
||||
(
|
||||
Lang::Python,
|
||||
"tests/dynamic_fixtures/deserialize/python/vuln.py",
|
||||
"run",
|
||||
"pickle.Unpickler.find_class",
|
||||
),
|
||||
(
|
||||
Lang::Php,
|
||||
"tests/dynamic_fixtures/deserialize/php/vuln.php",
|
||||
"run",
|
||||
"unserialize",
|
||||
),
|
||||
(
|
||||
Lang::Ruby,
|
||||
"tests/dynamic_fixtures/deserialize/ruby/vuln.rb",
|
||||
"run",
|
||||
"Marshal.load",
|
||||
),
|
||||
] {
|
||||
let spec = make_spec(lang, entry_file, entry_name);
|
||||
let harness = lang::emit(&spec)
|
||||
|
|
@ -148,12 +169,11 @@ fn lang_emitter_dispatches_to_deserialize_harness() {
|
|||
harness.source.contains("NYX_GADGET_CLASS:"),
|
||||
"{lang:?} deserialize harness must parse NYX_GADGET_CLASS marker",
|
||||
);
|
||||
// Each lang's harness either splices the relevant guard
|
||||
// construct directly or names the equivalent constant. The
|
||||
// assertions below pin only the parts the harness emitter
|
||||
// generates (not the fixture), so the test stays green even
|
||||
// when the fixture moves.
|
||||
let _ = marker; // marker validated by inspecting the fixture, not the harness.
|
||||
assert!(
|
||||
harness.source.contains(sink_callee_marker),
|
||||
"{lang:?} deserialize harness must name {sink_callee_marker:?} as the \
|
||||
resolveClass / find_class equivalent sink callee",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -229,12 +229,17 @@ fn binary_null_heavy_input_is_skipped() {
|
|||
|
||||
/// Invalid UTF-8 in a recognised source extension must not panic.
|
||||
/// tree-sitter can operate on raw bytes; we just check that it survives.
|
||||
/// Budget widened from 2 s to 10 s after the pitboss parallel `cargo test`
|
||||
/// invocation surfaced ~2.8 s wall time under shared-runner CPU pressure
|
||||
/// even though the isolated test runs well under 100 ms. The point is
|
||||
/// to catch a runaway, not to benchmark, so 10 s leaves clear headroom
|
||||
/// without masking a real regression.
|
||||
#[test]
|
||||
fn invalid_utf8_does_not_panic() {
|
||||
let bytes = b"\xff\xfe\xfd\xfc\n\xde\xad\xbe\xef\n// trailing\n".to_vec();
|
||||
let path = Path::new("junk.rs");
|
||||
let cfg = hostile_cfg();
|
||||
let _ = with_time_budget(Duration::from_secs(2), "invalid utf8", || {
|
||||
let _ = with_time_budget(Duration::from_secs(10), "invalid utf8", || {
|
||||
run_rules_on_bytes(&bytes, path, &cfg, None, None).expect("invalid UTF-8 should not error")
|
||||
});
|
||||
}
|
||||
|
|
@ -260,10 +265,13 @@ fn empty_file_is_noop() {
|
|||
/// right-associative expression, the latter is a separate stress case
|
||||
/// dominated by recursive descent and not representative of real input.
|
||||
///
|
||||
/// Generous debug-build budget (20 s) because the full analysis pipeline
|
||||
/// Generous debug-build budget (40 s) because the full analysis pipeline
|
||||
/// runs on every statement; release builds are an order of magnitude
|
||||
/// faster. The point is to guard against regressions that are
|
||||
/// super-linear in statement count, not to benchmark.
|
||||
/// super-linear in statement count, not to benchmark. Budget widened
|
||||
/// from 20 s after the pitboss parallel `cargo test` invocation surfaced
|
||||
/// 24-25 s wall time under shared-runner CPU pressure even though the
|
||||
/// isolated test runs in ~3.7 s.
|
||||
#[test]
|
||||
fn very_long_single_line_parses() {
|
||||
run_on_prod_stack(|| {
|
||||
|
|
@ -275,7 +283,7 @@ fn very_long_single_line_parses() {
|
|||
|
||||
let path = Path::new("long_line.js");
|
||||
let cfg = hostile_cfg();
|
||||
let _ = with_time_budget(Duration::from_secs(20), "long line parse", || {
|
||||
let _ = with_time_budget(Duration::from_secs(40), "long line parse", || {
|
||||
run_rules_on_bytes(s.as_bytes(), path, &cfg, None, None)
|
||||
.expect("long-line file should parse")
|
||||
});
|
||||
|
|
@ -348,7 +356,10 @@ fn deeply_nested_if_statements_do_not_stack_overflow() {
|
|||
|
||||
/// Lots of small functions in one file stresses the pass-1/pass-2 bookkeeping
|
||||
/// (summary extraction, callgraph build). 2 000 functions is cheap but
|
||||
/// plausible for generated code.
|
||||
/// plausible for generated code. Budget widened from 15 s after the
|
||||
/// pitboss parallel `cargo test` invocation surfaced 15.3 s under
|
||||
/// shared-runner CPU pressure even though the isolated test runs in
|
||||
/// ~3.7 s.
|
||||
#[test]
|
||||
fn many_small_functions_do_not_explode() {
|
||||
let mut s = String::with_capacity(2000 * 32);
|
||||
|
|
@ -358,7 +369,7 @@ fn many_small_functions_do_not_explode() {
|
|||
|
||||
let path = Path::new("many_funcs.js");
|
||||
let cfg = hostile_cfg();
|
||||
let _ = with_time_budget(Duration::from_secs(15), "many-funcs scan", || {
|
||||
let _ = with_time_budget(Duration::from_secs(30), "many-funcs scan", || {
|
||||
run_rules_on_bytes(s.as_bytes(), path, &cfg, None, None)
|
||||
.expect("many-functions file should scan")
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue