mirror of
https://github.com/elicpeter/nyx.git
synced 2026-06-30 20:39:39 +02:00
[pitboss] sweep after phase 14: 5 deferred items resolved
This commit is contained in:
parent
bd1bd0ce84
commit
919bc4e7e2
4 changed files with 64 additions and 48 deletions
|
|
@ -524,13 +524,18 @@ fn generate_harness_java(spec: &HarnessSpec, shape: JavaShape, entry_class: &str
|
||||||
""
|
""
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Reflection imports are only used by shapes whose helpers / catch
|
||||||
|
// clause reference them; emitting them for `StaticMethod` /
|
||||||
|
// `StaticMain` produces unused-import warnings under javac -Xlint.
|
||||||
|
let imports = if shape_uses_reflection(shape) {
|
||||||
|
"import java.lang.reflect.Method;\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.InvocationTargetException;\n\n"
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
};
|
||||||
|
|
||||||
format!(
|
format!(
|
||||||
r#"// Nyx dynamic harness — auto-generated, do not edit (Phase 14 — JavaShape::{shape:?}).
|
r#"// Nyx dynamic harness — auto-generated, do not edit (Phase 14 — JavaShape::{shape:?}).
|
||||||
import java.lang.reflect.Method;
|
{imports}public class NyxHarness {{
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
|
|
||||||
public class NyxHarness {{
|
|
||||||
{probe}
|
{probe}
|
||||||
{helpers}
|
{helpers}
|
||||||
public static void main(String[] args) {{
|
public static void main(String[] args) {{
|
||||||
|
|
@ -557,6 +562,7 @@ public class NyxHarness {{
|
||||||
}}
|
}}
|
||||||
"#,
|
"#,
|
||||||
shape = shape,
|
shape = shape,
|
||||||
|
imports = imports,
|
||||||
probe = probe,
|
probe = probe,
|
||||||
helpers = helpers,
|
helpers = helpers,
|
||||||
pre_call = pre_call,
|
pre_call = pre_call,
|
||||||
|
|
@ -989,4 +995,53 @@ mod tests {
|
||||||
let harness = emit(&spec).unwrap();
|
let harness = emit(&spec).unwrap();
|
||||||
assert_eq!(harness.entry_subpath, Some("Entry.java".to_owned()));
|
assert_eq!(harness.entry_subpath, Some("Entry.java".to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn detect_shape_reads_file_and_returns_shape() {
|
||||||
|
// Drive the public `detect_shape(spec)` wrapper end-to-end:
|
||||||
|
// write a representative source to a tempfile, then assert the
|
||||||
|
// wrapper reads it and produces the expected JavaShape variant.
|
||||||
|
let dir = std::env::temp_dir().join(format!(
|
||||||
|
"nyx_detect_shape_{}",
|
||||||
|
std::process::id()
|
||||||
|
));
|
||||||
|
let _ = std::fs::create_dir_all(&dir);
|
||||||
|
let cases: &[(&str, &str, &str, EntryKind, JavaShape)] = &[
|
||||||
|
(
|
||||||
|
"Servlet.java",
|
||||||
|
"import javax.servlet.http.HttpServletRequest;\npublic class Servlet extends HttpServlet { public void doGet(HttpServletRequest r, HttpServletResponse w) {} }",
|
||||||
|
"doGet",
|
||||||
|
EntryKind::HttpRoute,
|
||||||
|
JavaShape::ServletDoGet,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"Spring.java",
|
||||||
|
"@RestController\npublic class Spring { @GetMapping(\"/x\") public String run(String p) { return p; } }",
|
||||||
|
"run",
|
||||||
|
EntryKind::HttpRoute,
|
||||||
|
JavaShape::SpringController,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"MainClass.java",
|
||||||
|
"public class MainClass { public static void main(String[] args) {} }",
|
||||||
|
"main",
|
||||||
|
EntryKind::CliSubcommand,
|
||||||
|
JavaShape::StaticMain,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"Plain.java",
|
||||||
|
"public class Plain { public static void run(String p) {} }",
|
||||||
|
"run",
|
||||||
|
EntryKind::Function,
|
||||||
|
JavaShape::StaticMethod,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
for (name, body, entry_name, kind, expected) in cases {
|
||||||
|
let path = dir.join(name);
|
||||||
|
std::fs::write(&path, body).expect("write fixture");
|
||||||
|
let spec = make_spec_with(*kind, entry_name, path.to_str().unwrap());
|
||||||
|
assert_eq!(detect_shape(&spec), *expected, "case {name}");
|
||||||
|
}
|
||||||
|
let _ = std::fs::remove_dir_all(&dir);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,24 +50,6 @@ pub fn emit(spec: &HarnessSpec) -> Result<HarnessSource, UnsupportedReason> {
|
||||||
js_shared::emit(spec, false)
|
js_shared::emit(spec, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Derive the JS module name from an entry file path.
|
|
||||||
///
|
|
||||||
/// Always returns `"entry"` because the JS harness stages the entry file at
|
|
||||||
/// `workdir/entry.js` so `require('./entry')` is the only path that resolves
|
|
||||||
/// regardless of the source file's original name.
|
|
||||||
pub fn entry_module_name(_entry_file: &str) -> String {
|
|
||||||
"entry".to_owned()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Derive the entry filename from an entry file path.
|
|
||||||
///
|
|
||||||
/// Always `"entry.js"` for the JS surface; TypeScript uses `"entry.ts"` (see
|
|
||||||
/// [`crate::dynamic::lang::typescript`]) and ESM-default shapes use
|
|
||||||
/// `"entry.mjs"` (handled inside `js_shared`).
|
|
||||||
pub fn entry_module_filename(_entry_file: &str) -> String {
|
|
||||||
"entry.js".to_owned()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
@ -164,11 +146,4 @@ mod tests {
|
||||||
assert!(hint.contains("Phase 13"));
|
assert!(hint.contains("Phase 13"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn entry_module_name_is_always_entry_to_match_copy_destination() {
|
|
||||||
assert_eq!(entry_module_name("src/handlers/login.js"), "entry");
|
|
||||||
assert_eq!(entry_module_name("app.ts"), "entry");
|
|
||||||
assert_eq!(entry_module_name("handler.mjs"), "entry");
|
|
||||||
assert_eq!(entry_module_name("no_ext"), "entry");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -988,7 +988,7 @@ fn finalize_spec(
|
||||||
sink_line: u32,
|
sink_line: u32,
|
||||||
derivation: SpecDerivationStrategy,
|
derivation: SpecDerivationStrategy,
|
||||||
) -> HarnessSpec {
|
) -> HarnessSpec {
|
||||||
let toolchain_id = toolchain_id_for_lang(lang).to_owned();
|
let toolchain_id = default_toolchain_id(lang).to_owned();
|
||||||
let stubs_required = StubKind::for_cap(expected_cap);
|
let stubs_required = StubKind::for_cap(expected_cap);
|
||||||
let mut spec = HarnessSpec {
|
let mut spec = HarnessSpec {
|
||||||
finding_id: format!("{:016x}", diag.stable_hash),
|
finding_id: format!("{:016x}", diag.stable_hash),
|
||||||
|
|
@ -1031,7 +1031,7 @@ pub fn outermost_entry(steps: &[crate::evidence::FlowStep]) -> Option<EntryRef>
|
||||||
|
|
||||||
/// Default toolchain label for a language (informational; harness builder
|
/// Default toolchain label for a language (informational; harness builder
|
||||||
/// may override for locally-installed compilers/runtimes).
|
/// may override for locally-installed compilers/runtimes).
|
||||||
fn toolchain_id_for_lang(lang: Lang) -> &'static str {
|
pub fn default_toolchain_id(lang: Lang) -> &'static str {
|
||||||
match lang {
|
match lang {
|
||||||
Lang::Rust => "rust-stable",
|
Lang::Rust => "rust-stable",
|
||||||
Lang::C => "gcc-stable",
|
Lang::C => "gcc-stable",
|
||||||
|
|
|
||||||
|
|
@ -283,17 +283,7 @@ pub fn run_shape_fixture_lang(
|
||||||
u64::from_le_bytes(bytes.as_bytes()[..8].try_into().unwrap())
|
u64::from_le_bytes(bytes.as_bytes()[..8].try_into().unwrap())
|
||||||
});
|
});
|
||||||
|
|
||||||
let toolchain_id = match lang {
|
let toolchain_id = nyx_scanner::dynamic::spec::default_toolchain_id(lang);
|
||||||
nyx_scanner::symbol::Lang::Python => "python-3",
|
|
||||||
nyx_scanner::symbol::Lang::JavaScript | nyx_scanner::symbol::Lang::TypeScript => "node-20",
|
|
||||||
nyx_scanner::symbol::Lang::Rust => "rust-stable",
|
|
||||||
nyx_scanner::symbol::Lang::Go => "go-1.21",
|
|
||||||
nyx_scanner::symbol::Lang::Java => "java-17",
|
|
||||||
nyx_scanner::symbol::Lang::Php => "php-8",
|
|
||||||
nyx_scanner::symbol::Lang::Ruby => "ruby-3",
|
|
||||||
nyx_scanner::symbol::Lang::C => "gcc",
|
|
||||||
nyx_scanner::symbol::Lang::Cpp => "g++",
|
|
||||||
};
|
|
||||||
|
|
||||||
let spec = HarnessSpec {
|
let spec = HarnessSpec {
|
||||||
finding_id: spec_hash.clone(),
|
finding_id: spec_hash.clone(),
|
||||||
|
|
@ -482,11 +472,7 @@ pub fn run_harness_snapshot_lang(
|
||||||
std::fs::copy(&fixture_src, &dst).expect("copy fixture into tempdir");
|
std::fs::copy(&fixture_src, &dst).expect("copy fixture into tempdir");
|
||||||
let entry_file = dst.to_string_lossy().into_owned();
|
let entry_file = dst.to_string_lossy().into_owned();
|
||||||
|
|
||||||
let toolchain_id = match lang {
|
let toolchain_id = nyx_scanner::dynamic::spec::default_toolchain_id(lang);
|
||||||
nyx_scanner::symbol::Lang::Python => "python-3",
|
|
||||||
nyx_scanner::symbol::Lang::JavaScript | nyx_scanner::symbol::Lang::TypeScript => "node-20",
|
|
||||||
_ => "unknown",
|
|
||||||
};
|
|
||||||
|
|
||||||
let spec = HarnessSpec {
|
let spec = HarnessSpec {
|
||||||
finding_id: "0000000000000001".into(),
|
finding_id: "0000000000000001".into(),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue