diff --git a/docs/configuration.md b/docs/configuration.md index bd14b15d..af81cc8f 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -16,8 +16,8 @@ Run `nyx config path` to see the exact directory on your system. ## File Precedence -1. **`nyx.conf`** -- Default config (auto-created from built-in template on first run) -2. **`nyx.local`** -- User overrides (loaded on top of defaults) +1. **`nyx.conf`**: default config (auto-created from built-in template on first run) +2. **`nyx.local`**: user overrides (loaded on top of defaults) Both files are optional. CLI flags take precedence over both. @@ -40,7 +40,7 @@ excluded_extensions = ["jpg", "png", "exe"] excluded_extensions = ["foo", "jpg"] # Effective result: -# ["exe", "foo", "jpg", "png"] -- sorted, deduped union +# ["exe", "foo", "jpg", "png"] (sorted, deduped union) ``` --- @@ -423,9 +423,9 @@ State analysis requires `mode = "full"` or `mode = "taint"`. It has no effect in ### Engine-version mismatch is handled automatically Nyx stores the scanner's `CARGO_PKG_VERSION` in the project index database. -When the version recorded in the DB differs from the running binary; or the -row is missing entirely; every cached summary, SSA body, and file-hash row -is wiped on the next open so the next scan rebuilds the index against the new +When the version recorded in the DB differs from the running binary, or the +row is missing entirely, every cached summary, SSA body, and file-hash row +is wiped on the next open. The next scan rebuilds the index against the new engine. No flag is needed; CI pipelines keep working across upgrades. The rebuild is logged at `info` level: @@ -468,4 +468,4 @@ On the next scan Nyx builds a fresh index from scratch. ## Reserved Fields -Some config fields are defined but not yet implemented. They are marked `(RESERVED)` in the default config and accept values without effect. This allows forward-compatible config files; settings will activate when the feature is implemented without requiring config changes. +Some config fields are defined but not yet implemented. They are marked `(RESERVED)` in the default config and accept values without effect. Config files stay forward-compatible: settings start having an effect when the feature ships, with no edit needed. diff --git a/src/cfg_analysis/dominators.rs b/src/cfg_analysis/dominators.rs index 319023f0..fbc92c71 100644 --- a/src/cfg_analysis/dominators.rs +++ b/src/cfg_analysis/dominators.rs @@ -100,38 +100,6 @@ fn build_reversed_graph(cfg: &Cfg) -> Graph { rev } -/// Find all nodes matching a specific callee name pattern. -#[allow(dead_code)] -pub fn find_call_nodes_matching(cfg: &Cfg, matchers: &[&str]) -> Vec { - 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 { use std::collections::VecDeque; diff --git a/src/commands/scan.rs b/src/commands/scan.rs index 91fb50ad..e7eb396d 100644 --- a/src/commands/scan.rs +++ b/src/commands/scan.rs @@ -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>, diff --git a/src/commands/surface.rs b/src/commands/surface.rs index 04720504..e25338c0 100644 --- a/src/commands/surface.rs +++ b/src/commands/surface.rs @@ -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 diff --git a/src/lib.rs b/src/lib.rs index bd9e5c68..a247f57e 100644 --- a/src/lib.rs +++ b/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 diff --git a/src/patterns/mod.rs b/src/patterns/mod.rs index 5777a419..01e1f3dd 100644 --- a/src/patterns/mod.rs +++ b/src/patterns/mod.rs @@ -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 {