mirror of
https://github.com/elicpeter/nyx.git
synced 2026-07-06 20:42:10 +02:00
refactor(dynamic): replace reflective invocation with route replay logic for Micronaut and Quarkus, remove annotation stubs, and enhance runtime path binding
This commit is contained in:
parent
61bfc0cf96
commit
41c7b73575
26 changed files with 1256 additions and 224 deletions
|
|
@ -1018,10 +1018,10 @@ pub(crate) fn collect_idents(n: Node, code: &[u8], out: &mut Vec<String>) {
|
|||
/// AST kind names for subscript / index expressions
|
||||
/// across the languages whose container-element flow we model.
|
||||
///
|
||||
/// JS/TS use `subscript_expression`; Python uses `subscript`; Go uses
|
||||
/// `index_expression`. Other languages either lower indexing through
|
||||
/// method calls (Rust slice indexing) or are out of scope for the
|
||||
/// initial W5 rollout (Java/Ruby/PHP/C/C++).
|
||||
/// JS/TS and C/C++ use `subscript_expression`; Python uses `subscript`;
|
||||
/// Go uses `index_expression`. Other languages either lower indexing
|
||||
/// through method calls (Rust slice indexing) or are out of scope for
|
||||
/// the initial W5 rollout (Java/Ruby/PHP).
|
||||
#[inline]
|
||||
pub(crate) fn is_subscript_kind(kind: &str) -> bool {
|
||||
matches!(
|
||||
|
|
@ -1086,7 +1086,8 @@ pub(crate) fn subscript_components<'a>(n: Node<'a>, code: &'a [u8]) -> Option<(S
|
|||
return None;
|
||||
}
|
||||
let arr_text = text_of(arr, code)?;
|
||||
// PHP-style `$x` strip not needed here, Go/JS/Python don't use it.
|
||||
// PHP-style `$x` strip not needed here; the supported languages
|
||||
// don't use it for local array identifiers.
|
||||
let idx_text = text_of(idx, code)?;
|
||||
Some((arr_text, idx_text))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2507,6 +2507,23 @@ pub(super) fn push_node<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
// Conditions can contain source/sink calls whose argument side effects are
|
||||
// load-bearing for taint, e.g. C `if (!fgets(buf, n, stdin)) return;`.
|
||||
// Classify the condition call so output-parameter sources still lower as
|
||||
// SSA calls while the CFG node keeps its branch shape.
|
||||
if labels.is_empty()
|
||||
&& matches!(lookup(lang, ast.kind()), Kind::If | Kind::While)
|
||||
&& let Some(cond) = ast.child_by_field_name("condition")
|
||||
&& let Some((ident, ident_span)) = first_call_ident_with_span(cond, lang, code)
|
||||
&& let Some(l) = classify(lang, &ident, extra)
|
||||
{
|
||||
labels.push(l);
|
||||
text = ident;
|
||||
if inner_text_span.is_none() {
|
||||
inner_text_span = Some(ident_span);
|
||||
}
|
||||
}
|
||||
|
||||
// For `if let` / `while let` patterns: try to classify the value expression
|
||||
// in the let-condition as a source/sink. E.g. `if let Ok(cmd) = env::var("CMD")`
|
||||
// should recognise `env::var` as a taint source and label this node accordingly.
|
||||
|
|
@ -3143,11 +3160,12 @@ pub(super) fn push_node<'a>(
|
|||
};
|
||||
|
||||
// Extract condition metadata for If nodes.
|
||||
let (condition_text, condition_vars, condition_negated) = if kind == StmtKind::If {
|
||||
extract_condition_raw(ast, lang, code)
|
||||
} else {
|
||||
(None, Vec::new(), false)
|
||||
};
|
||||
let (condition_text, condition_vars, condition_negated) =
|
||||
if matches!(lookup(lang, ast.kind()), Kind::If) {
|
||||
extract_condition_raw(ast, lang, code)
|
||||
} else {
|
||||
(None, Vec::new(), false)
|
||||
};
|
||||
|
||||
// Extract per-argument identifiers for Call nodes.
|
||||
// Also extract for gated-sink nodes so payload-arg filtering works.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue