mirror of
https://github.com/elicpeter/nyx.git
synced 2026-06-15 20:05:13 +02:00
Python fp and docs updtes (#58)
* refactor: Update comments for clarity and add expectations.json files for performance metrics * feat: Implement FP guard for JS/TS local-collection receivers to suppress missing ownership checks * feat: Enhance Rust parameter handling to classify local collections and prevent false ownership checks * refactor: Simplify code formatting for better readability in multiple files * refactor: Improve UTF-8 sequence length handling and enhance clarity in loop iteration * feat: Update Java and Python patterns to include new security rules * refactor: Improve comment clarity and consistency across multiple Rust files * refactor: Simplify code formatting for improved readability in integration tests and module files * refactor: Improve comment formatting and enhance clarity in assertions across multiple files
This commit is contained in:
parent
4db0805de6
commit
a438886217
291 changed files with 9485 additions and 3851 deletions
|
|
@ -1,6 +1,6 @@
|
|||
//! String abstract domain for abstract interpretation.
|
||||
//!
|
||||
//! Tracks known prefix, suffix, and — when provably bounded — the finite set
|
||||
//! Tracks known prefix, suffix, and, when provably bounded, the finite set
|
||||
//! of possible concrete string values. Used for SSRF suppression (URL prefix
|
||||
//! proves host is locked), command-injection suppression (lookup result
|
||||
//! bounded to a safe set of literals), and general string analysis.
|
||||
|
|
@ -78,7 +78,7 @@ impl StringFact {
|
|||
/// the finite domain is `{s}`.
|
||||
///
|
||||
/// Empty prefix/suffix are normalised to `None` because "starts/ends with
|
||||
/// the empty string" carries no constraint — keeping `Some("")` would
|
||||
/// the empty string" carries no constraint, keeping `Some("")` would
|
||||
/// break join idempotence (`Some("")` ⊔ `Some("")` collapses to `None`).
|
||||
pub fn exact(s: &str) -> Self {
|
||||
let prefix = truncate_prefix(s);
|
||||
|
|
@ -134,7 +134,7 @@ impl StringFact {
|
|||
/// Inputs are sorted and deduped. If the cardinality exceeds
|
||||
/// [`MAX_DOMAIN_SIZE`] or the input is empty, the domain collapses to
|
||||
/// `None` (Top on this sub-field). The prefix/suffix sub-fields remain
|
||||
/// unset — callers can combine with [`Self::exact`] for single-element
|
||||
/// unset, callers can combine with [`Self::exact`] for single-element
|
||||
/// sets if tighter facts are desired.
|
||||
pub fn finite_set(values: Vec<String>) -> Self {
|
||||
let mut v = values;
|
||||
|
|
@ -411,7 +411,7 @@ fn truncate_suffix(s: &str) -> String {
|
|||
/// Longest common prefix of two strings, char-aligned.
|
||||
///
|
||||
/// Iterates by `char` rather than `byte` so multi-byte UTF-8 code points are
|
||||
/// either kept whole or dropped — a byte-wise comparison would slice into the
|
||||
/// either kept whole or dropped, a byte-wise comparison would slice into the
|
||||
/// middle of a code point and produce mojibake (`x as char` on a UTF-8
|
||||
/// continuation byte yields a garbage Latin-1 character).
|
||||
pub fn longest_common_prefix(a: &str, b: &str) -> String {
|
||||
|
|
@ -746,7 +746,7 @@ mod tests {
|
|||
let a = StringFact::from_prefix("https://api.example.com/");
|
||||
let b = StringFact::from_prefix("https://db.example.com/");
|
||||
let r = a.join(&b);
|
||||
// Common prefix is "https://" — anything past that diverges.
|
||||
// Common prefix is "https://", anything past that diverges.
|
||||
assert_eq!(
|
||||
r.prefix.as_deref(),
|
||||
Some("https://"),
|
||||
|
|
@ -781,7 +781,7 @@ mod tests {
|
|||
]
|
||||
}
|
||||
|
||||
/// `x ⊔ x = x` — join is idempotent across all sample shapes.
|
||||
/// `x ⊔ x = x`, join is idempotent across all sample shapes.
|
||||
#[test]
|
||||
fn join_idempotent_string() {
|
||||
for a in sample_strings() {
|
||||
|
|
@ -789,7 +789,7 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
/// `x ⊔ y = y ⊔ x` — join is commutative.
|
||||
/// `x ⊔ y = y ⊔ x`, join is commutative.
|
||||
#[test]
|
||||
fn join_commutative_string() {
|
||||
let xs = sample_strings();
|
||||
|
|
@ -806,7 +806,7 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
/// `x ⊓ x = x` — meet is idempotent.
|
||||
/// `x ⊓ x = x`, meet is idempotent.
|
||||
#[test]
|
||||
fn meet_idempotent_string() {
|
||||
for a in sample_strings() {
|
||||
|
|
@ -814,7 +814,7 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
/// `x ⊓ y = y ⊓ x` — meet is commutative.
|
||||
/// `x ⊓ y = y ⊓ x`, meet is commutative.
|
||||
#[test]
|
||||
fn meet_commutative_string() {
|
||||
let xs = sample_strings();
|
||||
|
|
@ -844,7 +844,7 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
/// `x ⊑ x` — leq is reflexive.
|
||||
/// `x ⊑ x`, leq is reflexive.
|
||||
#[test]
|
||||
fn leq_reflexive_string() {
|
||||
for a in sample_strings() {
|
||||
|
|
@ -852,7 +852,7 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
/// **Soundness**: `widen(a, b) ⊒ join(a, b)` — widening must
|
||||
/// **Soundness**: `widen(a, b) ⊒ join(a, b)`, widening must
|
||||
/// over-approximate join, otherwise dataflow loses information.
|
||||
#[test]
|
||||
fn widen_over_approximates_join_string() {
|
||||
|
|
@ -905,7 +905,7 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
/// Empty-string exact value must distinguish from Top — it is a
|
||||
/// Empty-string exact value must distinguish from Top, it is a
|
||||
/// singleton (`{""}`), not unconstrained. After the empty-prefix
|
||||
/// normalisation, prefix/suffix are `None` (carry no extra info)
|
||||
/// but the `domain` field still pins the value to exactly `""`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue