mirror of
https://github.com/elicpeter/nyx.git
synced 2026-06-27 20:29:39 +02:00
Phase 1 (#33)
* chore: Exclude CLAUDE.md from Cargo.toml * feat: add callgraph module and integrate into main analysis flow * feat: enhance CLI with new severity filtering and analysis modes * feat: update CHANGELOG with recent enhancements and fixes to severity filtering and output handling * feat: implement state-model dataflow analysis for resource lifecycle and auth state * feat: enhance diagnostic output formatting and add evidence structure * feat: implement attack surface ranking for diagnostics with scoring and sorting * feat: add comprehensive documentation for installation, usage, and rules reference * feat: add multiple language support for command execution and evaluation endpoints * feat: implement inline suppression for findings using `nyx:ignore` comments * feat: add confidence levels to AST patterns and update output structure * feat: implement low-noise prioritization system with category filtering, rollup grouping, and configurable budgets * feat: bump version to 0.4.0 and update changelog with new features and improvements * feat: add dead code allowances to various functions in mod.rs and real_world_tests.rs
This commit is contained in:
parent
19b578c5c4
commit
1bbe4b1cfb
456 changed files with 25628 additions and 1228 deletions
27
tests/fixtures/real_world/cpp/state/fopen_lifecycle.cpp
vendored
Normal file
27
tests/fixtures/real_world/cpp/state/fopen_lifecycle.cpp
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#include <cstdio>
|
||||
|
||||
void leak() {
|
||||
FILE *f = fopen("/tmp/test", "r");
|
||||
char buf[256];
|
||||
fgets(buf, sizeof(buf), f);
|
||||
}
|
||||
|
||||
void clean() {
|
||||
FILE *f = fopen("/tmp/test", "r");
|
||||
char buf[256];
|
||||
fgets(buf, sizeof(buf), f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void double_close() {
|
||||
FILE *f = fopen("/tmp/test", "r");
|
||||
fclose(f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void use_after_close() {
|
||||
FILE *f = fopen("/tmp/test", "r");
|
||||
fclose(f);
|
||||
char buf[256];
|
||||
fgets(buf, sizeof(buf), f);
|
||||
}
|
||||
45
tests/fixtures/real_world/cpp/state/fopen_lifecycle.expect.json
vendored
Normal file
45
tests/fixtures/real_world/cpp/state/fopen_lifecycle.expect.json
vendored
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
{
|
||||
"description": "C++ FILE* lifecycle patterns: leak, double close, use after close",
|
||||
"tags": [
|
||||
"state",
|
||||
"resource-lifecycle"
|
||||
],
|
||||
"modes": [
|
||||
"full"
|
||||
],
|
||||
"expected": [
|
||||
{
|
||||
"rule_id": "state-resource-leak",
|
||||
"severity": null,
|
||||
"must_match": true,
|
||||
"line_range": [
|
||||
2,
|
||||
8
|
||||
],
|
||||
"evidence_contains": [],
|
||||
"notes": "fopen at line 4 never closed in leak()"
|
||||
},
|
||||
{
|
||||
"rule_id": "state-double-close",
|
||||
"severity": null,
|
||||
"must_match": true,
|
||||
"line_range": [
|
||||
16,
|
||||
21
|
||||
],
|
||||
"evidence_contains": [],
|
||||
"notes": "fclose called twice on same FILE* in double_close()"
|
||||
},
|
||||
{
|
||||
"rule_id": "state-use-after-close",
|
||||
"severity": null,
|
||||
"must_match": true,
|
||||
"line_range": [
|
||||
23,
|
||||
29
|
||||
],
|
||||
"evidence_contains": [],
|
||||
"notes": "fgets on f after fclose in use_after_close()"
|
||||
}
|
||||
]
|
||||
}
|
||||
11
tests/fixtures/real_world/cpp/state/malloc_branches.cpp
vendored
Normal file
11
tests/fixtures/real_world/cpp/state/malloc_branches.cpp
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
void branch_leak(int flag) {
|
||||
char *buf = (char*)malloc(256);
|
||||
if (flag) {
|
||||
strcpy(buf, "hello");
|
||||
free(buf);
|
||||
}
|
||||
// buf leaked if !flag
|
||||
}
|
||||
24
tests/fixtures/real_world/cpp/state/malloc_branches.expect.json
vendored
Normal file
24
tests/fixtures/real_world/cpp/state/malloc_branches.expect.json
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"description": "C++ malloc branch leak: only freed in one branch of conditional",
|
||||
"tags": [
|
||||
"state",
|
||||
"resource-leak",
|
||||
"branching"
|
||||
],
|
||||
"modes": [
|
||||
"full"
|
||||
],
|
||||
"expected": [
|
||||
{
|
||||
"rule_id": "state-resource-leak-possible",
|
||||
"severity": null,
|
||||
"must_match": false,
|
||||
"line_range": [
|
||||
3,
|
||||
12
|
||||
],
|
||||
"evidence_contains": [],
|
||||
"notes": "malloc at line 5 only freed when flag is true \u2014 aspirational branch-aware state analysis"
|
||||
}
|
||||
]
|
||||
}
|
||||
18
tests/fixtures/real_world/cpp/state/new_delete.cpp
vendored
Normal file
18
tests/fixtures/real_world/cpp/state/new_delete.cpp
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#include <cstring>
|
||||
|
||||
void leak() {
|
||||
char *buf = new char[1024];
|
||||
strcpy(buf, "hello");
|
||||
}
|
||||
|
||||
void clean() {
|
||||
char *buf = new char[1024];
|
||||
strcpy(buf, "hello");
|
||||
delete[] buf;
|
||||
}
|
||||
|
||||
void double_delete() {
|
||||
char *buf = new char[1024];
|
||||
delete[] buf;
|
||||
delete[] buf;
|
||||
}
|
||||
34
tests/fixtures/real_world/cpp/state/new_delete.expect.json
vendored
Normal file
34
tests/fixtures/real_world/cpp/state/new_delete.expect.json
vendored
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"description": "C++ new[]/delete[] lifecycle: leak and double delete patterns",
|
||||
"tags": [
|
||||
"state",
|
||||
"resource-lifecycle"
|
||||
],
|
||||
"modes": [
|
||||
"full"
|
||||
],
|
||||
"expected": [
|
||||
{
|
||||
"rule_id": "state-resource-leak",
|
||||
"severity": null,
|
||||
"must_match": false,
|
||||
"line_range": [
|
||||
2,
|
||||
7
|
||||
],
|
||||
"evidence_contains": [],
|
||||
"notes": "new char[1024] at line 4 never deleted \u2014 aspirational, requires new/delete tracking"
|
||||
},
|
||||
{
|
||||
"rule_id": "state-double-close",
|
||||
"severity": null,
|
||||
"must_match": false,
|
||||
"line_range": [
|
||||
14,
|
||||
19
|
||||
],
|
||||
"evidence_contains": [],
|
||||
"notes": "delete[] called twice \u2014 aspirational, requires new/delete tracking"
|
||||
}
|
||||
]
|
||||
}
|
||||
12
tests/fixtures/real_world/cpp/state/smart_ptr_vs_raw.cpp
vendored
Normal file
12
tests/fixtures/real_world/cpp/state/smart_ptr_vs_raw.cpp
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#include <memory>
|
||||
#include <cstdlib>
|
||||
|
||||
void smart_clean() {
|
||||
auto ptr = std::make_unique<int>(42);
|
||||
// automatically cleaned up
|
||||
}
|
||||
|
||||
void raw_leak() {
|
||||
int *ptr = new int(42);
|
||||
// never deleted
|
||||
}
|
||||
24
tests/fixtures/real_world/cpp/state/smart_ptr_vs_raw.expect.json
vendored
Normal file
24
tests/fixtures/real_world/cpp/state/smart_ptr_vs_raw.expect.json
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"description": "Smart pointer vs raw new: unique_ptr auto-cleans, raw pointer leaks",
|
||||
"tags": [
|
||||
"state",
|
||||
"resource-leak",
|
||||
"smart-pointer"
|
||||
],
|
||||
"modes": [
|
||||
"full"
|
||||
],
|
||||
"expected": [
|
||||
{
|
||||
"rule_id": "state-resource-leak",
|
||||
"severity": null,
|
||||
"must_match": false,
|
||||
"line_range": [
|
||||
8,
|
||||
13
|
||||
],
|
||||
"evidence_contains": [],
|
||||
"notes": "new int(42) at line 10 never deleted \u2014 aspirational, requires new/delete tracking"
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue