mirror of
https://github.com/elicpeter/nyx.git
synced 2026-06-15 20:05:13 +02:00
[pitboss/grind] cleanup session-0004 (20260521T201327Z-3848)
This commit is contained in:
parent
368f628054
commit
f827552bbd
6 changed files with 37 additions and 69 deletions
|
|
@ -100,38 +100,6 @@ fn build_reversed_graph(cfg: &Cfg) -> Graph<NodeInfo, EdgeKind> {
|
|||
rev
|
||||
}
|
||||
|
||||
/// Find all nodes matching a specific callee name pattern.
|
||||
#[allow(dead_code)]
|
||||
pub fn find_call_nodes_matching(cfg: &Cfg, matchers: &[&str]) -> Vec<NodeIndex> {
|
||||
cfg.node_indices()
|
||||
.filter(|&idx| {
|
||||
if cfg[idx].kind != StmtKind::Call {
|
||||
return false;
|
||||
}
|
||||
if let Some(callee) = &cfg[idx].call.callee {
|
||||
let callee_lower = callee.to_ascii_lowercase();
|
||||
matchers.iter().any(|m| {
|
||||
let ml = m.to_ascii_lowercase();
|
||||
if ml.ends_with('_') {
|
||||
callee_lower.starts_with(&ml)
|
||||
} else {
|
||||
callee_lower.ends_with(&ml)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Check if there exists any path from `from` to `to` in the CFG.
|
||||
#[allow(dead_code)]
|
||||
pub fn has_path(cfg: &Cfg, from: NodeIndex, to: NodeIndex) -> bool {
|
||||
let reachable = reachable_set(cfg, from);
|
||||
reachable.contains(&to)
|
||||
}
|
||||
|
||||
/// Compute shortest distance (in hops) from `from` to `to`.
|
||||
pub fn shortest_distance(cfg: &Cfg, from: NodeIndex, to: NodeIndex) -> Option<usize> {
|
||||
use std::collections::VecDeque;
|
||||
|
|
|
|||
|
|
@ -1314,7 +1314,7 @@ fn topo_refine_enabled() -> bool {
|
|||
/// files that contain a caller of a changed key in the next iteration.
|
||||
/// This reduces per-iteration cost from O(|batch.files|) to
|
||||
/// O(|dirty_files|), which is typically a small fraction of the
|
||||
/// batch for SCCs larger than 4–8 functions.
|
||||
/// batch for SCCs larger than 4 to 8 functions.
|
||||
///
|
||||
/// When `call_graph` is missing an edge (e.g. a summary was inserted
|
||||
/// after graph construction), we conservatively fall back to
|
||||
|
|
@ -1914,14 +1914,14 @@ fn run_topo_batches(
|
|||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Two‑pass scanning (no index)
|
||||
// Two-pass scanning (no index)
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
/// Walk the filesystem and perform a two‑pass scan:
|
||||
/// Walk the filesystem and perform a two-pass scan:
|
||||
///
|
||||
/// **Pass 1** – Parse every file and extract function summaries.
|
||||
/// **Pass 2** – Re‑parse every file and run taint analysis with the
|
||||
/// merged cross‑file summaries.
|
||||
/// **Pass 1**: parse every file and extract function summaries.
|
||||
/// **Pass 2**: re-parse every file and run taint analysis with the
|
||||
/// merged cross-file summaries.
|
||||
///
|
||||
/// AST pattern queries are run during pass 2 (they don't depend on summaries).
|
||||
pub(crate) fn scan_filesystem(
|
||||
|
|
@ -2423,20 +2423,20 @@ pub(crate) fn scan_filesystem_with_observer(
|
|||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Two‑pass scanning (with index)
|
||||
// Two-pass scanning (with index)
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
/// Indexed two‑pass scan:
|
||||
/// Indexed two-pass scan:
|
||||
///
|
||||
/// **Pass 1** – For every file that needs scanning, extract summaries and
|
||||
/// persist them to the database. Unchanged files keep their
|
||||
/// existing summaries.
|
||||
/// **Pass 2** – Load *all* summaries from the DB, merge them, and re‑run
|
||||
/// taint analysis on every file with the full cross‑file view.
|
||||
/// Files whose *own* code has not changed AND whose
|
||||
/// dependencies have not changed can serve cached issues
|
||||
/// instead. (Today we conservatively re‑analyse every file in
|
||||
/// pass 2; caching will be refined in approach 2 / 3.)
|
||||
/// **Pass 1**: for every file that needs scanning, extract summaries and
|
||||
/// persist them to the database. Unchanged files keep their
|
||||
/// existing summaries.
|
||||
/// **Pass 2**: load *all* summaries from the DB, merge them, and re-run
|
||||
/// taint analysis on every file with the full cross-file view.
|
||||
/// Files whose *own* code has not changed AND whose
|
||||
/// dependencies have not changed can serve cached issues
|
||||
/// instead. (Today we conservatively re-analyse every file in
|
||||
/// pass 2; caching will be refined later.)
|
||||
pub fn scan_with_index_parallel(
|
||||
project: &str,
|
||||
pool: Arc<Pool<SqliteConnectionManager>>,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//! Phase 23 — `nyx surface` subcommand.
|
||||
//! `nyx surface` subcommand.
|
||||
//!
|
||||
//! Walks the project tree, builds a [`SurfaceMap`] from the framework
|
||||
//! probes (plus any persisted data-store / external-service /
|
||||
|
|
@ -6,10 +6,10 @@
|
|||
//! map in the format requested by the user.
|
||||
//!
|
||||
//! Output formats:
|
||||
//! * `text` — indented tree per entry-point, grouped by file
|
||||
//! * `json` — canonical JSON (byte-identical to the SQLite payload)
|
||||
//! * `dot` — graphviz source, ready to pipe through `dot -Tsvg`
|
||||
//! * `svg` — graphviz source rendered via the local `dot` binary
|
||||
//! * `text`: indented tree per entry-point, grouped by file
|
||||
//! * `json`: canonical JSON (byte-identical to the SQLite payload)
|
||||
//! * `dot`: graphviz source, ready to pipe through `dot -Tsvg`
|
||||
//! * `svg`: graphviz source rendered via the local `dot` binary
|
||||
//!
|
||||
//! The command is read-only: it never persists to SQLite and never
|
||||
//! modifies the project tree. It tries to load a previously persisted
|
||||
|
|
|
|||
12
src/lib.rs
12
src/lib.rs
|
|
@ -50,13 +50,13 @@
|
|||
//!
|
||||
//! Each [`commands::scan::Diag`] carries:
|
||||
//!
|
||||
//! - `path`, `line`, `col` — source location of the sink
|
||||
//! - `id` — rule identifier (e.g. `taint-unsanitised-flow`, `cfg-auth-gap`)
|
||||
//! - `severity` — Critical / High / Medium / Low / Info
|
||||
//! - `confidence` — Low / Medium / High; capped at Medium when an engine
|
||||
//! - `path`, `line`, `col`: source location of the sink
|
||||
//! - `id`: rule identifier (e.g. `taint-unsanitised-flow`, `cfg-auth-gap`)
|
||||
//! - `severity`: Critical / High / Medium / Low / Info
|
||||
//! - `confidence`: Low / Medium / High; capped at Medium when an engine
|
||||
//! budget was hit
|
||||
//! - `rank_score` — deterministic attack-surface score for truncation ordering
|
||||
//! - `evidence` — optional [`evidence::Evidence`] with source/sink spans,
|
||||
//! - `rank_score`: deterministic attack-surface score for truncation ordering
|
||||
//! - `evidence`: optional [`evidence::Evidence`] with source/sink spans,
|
||||
//! flow steps, and [`engine_notes::EngineNote`] values describing precision loss
|
||||
//!
|
||||
//! Engine notes communicate when a bound was hit. A finding carrying
|
||||
|
|
|
|||
|
|
@ -193,8 +193,8 @@ impl SeverityFilter {
|
|||
|
||||
/// Pattern confidence tier.
|
||||
///
|
||||
/// * **A** – Structural presence alone is high-signal (e.g. `gets()`, `eval()`).
|
||||
/// * **B** – Requires a simple heuristic guard in the query (e.g. SQL with
|
||||
/// * **A**: structural presence alone is high-signal (e.g. `gets()`, `eval()`).
|
||||
/// * **B**: requires a simple heuristic guard in the query (e.g. SQL with
|
||||
/// concatenated arg, file-open with non-literal path).
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize)]
|
||||
pub enum PatternTier {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue