* 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:
Eli Peter 2026-02-25 21:16:36 -05:00 committed by GitHub
parent 19b578c5c4
commit 1bbe4b1cfb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
456 changed files with 25628 additions and 1228 deletions

View file

@ -0,0 +1,12 @@
#include <stdio.h>
/* Both branches close f — no leak on any path.
Expected: NO state- findings. */
void both_close(int cond) {
FILE *f = fopen("data.txt", "r");
if (cond) {
fclose(f);
} else {
fclose(f);
}
}

13
tests/fixtures/state/chain_ops.c vendored Normal file
View file

@ -0,0 +1,13 @@
#include <stdio.h>
/* Multiple resource operations in sequence: open → read → write → close.
Tests that repeated uses do not corrupt lifecycle state.
Expected: NO state- findings. */
void chain_ops(void) {
FILE *f = fopen("data.txt", "r");
char buf[256];
fread(buf, 1, sizeof(buf), f);
fwrite(buf, 1, sizeof(buf), f);
fread(buf, 1, sizeof(buf), f);
fclose(f);
}

9
tests/fixtures/state/clean.c vendored Normal file
View file

@ -0,0 +1,9 @@
#include <stdio.h>
void clean_usage() {
FILE *f = fopen("data.txt", "r");
char buf[256];
fread(buf, 1, sizeof(buf), f);
fclose(f);
// Clean: open, use, close — no bugs
}

7
tests/fixtures/state/double_close.c vendored Normal file
View file

@ -0,0 +1,7 @@
#include <stdio.h>
void double_close_bug() {
FILE *f = fopen("data.txt", "r");
fclose(f);
fclose(f); // BUG: double close
}

View file

@ -0,0 +1,14 @@
#include <stdio.h>
/* fclose inside a branch, then unconditional fclose after.
True path: fclose(OPENCLOSED), then fclose(CLOSED) = double close.
False path: skip inner fclose, then fclose(OPENCLOSED) = fine.
Converged state at the second fclose: OPEN|CLOSED (join).
Expected: NO state-double-close (conservative: join masks the bug). */
void double_close_branch(int cond) {
FILE *f = fopen("data.txt", "r");
if (cond) {
fclose(f);
}
fclose(f);
}

View file

@ -0,0 +1,10 @@
#include <stdio.h>
/* Straight-line double close — no branching ambiguity.
The converged state at the second fclose is definitely CLOSED.
Expected: state-double-close. */
void double_close_straight(void) {
FILE *f = fopen("data.txt", "r");
fclose(f);
fclose(f);
}

View file

@ -0,0 +1,11 @@
#include <stdio.h>
/* Early return leaks on the error path; normal path closes.
Expected: state-resource-leak-possible (may-leak). */
void early_return_leak(int err) {
FILE *f = fopen("data.txt", "r");
if (err) {
return;
}
fclose(f);
}

11
tests/fixtures/state/handle_overwrite.c vendored Normal file
View file

@ -0,0 +1,11 @@
#include <stdio.h>
/* The first fopen result is overwritten by the second fopen.
The first handle leaks silently because per-variable tracking
loses the old allocation. The second handle is properly closed.
Expected: NO state- findings (known per-variable-tracking limitation). */
void overwrite_handle(void) {
FILE *f = fopen("a.txt", "r");
f = fopen("b.txt", "r");
fclose(f);
}

14
tests/fixtures/state/loop_clean.c vendored Normal file
View file

@ -0,0 +1,14 @@
#include <stdio.h>
/* Open before loop, use inside loop, close after loop.
The back-edge should not prevent convergence.
Expected: NO state- findings. */
void loop_clean(void) {
FILE *f = fopen("data.txt", "r");
char buf[256];
int i;
for (i = 0; i < 10; i++) {
fread(buf, 1, sizeof(buf), f);
}
fclose(f);
}

View file

@ -0,0 +1,16 @@
#include <stdio.h>
/* Close before the loop, then use inside the loop body.
The back-edge means the use node joins CLOSED (first iter)
with CLOSED (back-edge, still CLOSED). The converged state
at the fread call is CLOSED use-after-close.
Expected: state-use-after-close. */
void loop_use_after_close(void) {
FILE *f = fopen("data.txt", "r");
fclose(f);
char buf[256];
int i;
for (i = 0; i < 10; i++) {
fread(buf, 1, sizeof(buf), f);
}
}

View file

@ -0,0 +1,10 @@
#include <stdlib.h>
/* malloc followed by free — clean.
Tests the memory resource pair.
Expected: NO state- findings. */
void malloc_free_clean(void) {
void *p = malloc(100);
*(char *)p = 'x';
free(p);
}

9
tests/fixtures/state/malloc_leak.c vendored Normal file
View file

@ -0,0 +1,9 @@
#include <stdlib.h>
/* malloc without free — resource leak.
Tests the memory resource pair (malloc free).
Expected: state-resource-leak. */
void malloc_leak(void) {
void *p = malloc(100);
*(char *)p = 'x';
}

10
tests/fixtures/state/may_leak_branch.c vendored Normal file
View file

@ -0,0 +1,10 @@
#include <stdio.h>
/* Only the true branch closes f; the false branch leaks.
Expected: state-resource-leak-possible (NOT state-resource-leak). */
void may_leak(int cond) {
FILE *f = fopen("data.txt", "r");
if (cond) {
fclose(f);
}
}

11
tests/fixtures/state/multiple_handles.c vendored Normal file
View file

@ -0,0 +1,11 @@
#include <stdio.h>
/* Two separate handles: f1 is closed, f2 is leaked.
Expected: state-resource-leak for f2, NO state-resource-leak for f1.
(The finding message should contain "f2".) */
void multiple_handles(void) {
FILE *f1 = fopen("a.txt", "r");
FILE *f2 = fopen("b.txt", "r");
fclose(f1);
/* f2 never closed */
}

View file

@ -0,0 +1,16 @@
#include <stdio.h>
/* Nested if — only the innermost branch closes.
Path truetrue: fclose CLOSED (clean)
Path truefalse: no close OPEN (leak)
Path false: no close OPEN (leak)
Joined at exit: OPEN|CLOSED may-leak.
Expected: state-resource-leak-possible. */
void nested_branch_leak(int a, int b) {
FILE *f = fopen("data.txt", "r");
if (a) {
if (b) {
fclose(f);
}
}
}

View file

@ -0,0 +1,12 @@
#include <stdio.h>
/* Open, close, then reopen the same variable and close again.
The second fopen overwrites CLOSED with OPEN; the second fclose
brings it back to CLOSED. Clean usage.
Expected: NO state- findings. */
void reopen_after_close(void) {
FILE *f = fopen("a.txt", "r");
fclose(f);
f = fopen("b.txt", "r");
fclose(f);
}

9
tests/fixtures/state/resource_leak.c vendored Normal file
View file

@ -0,0 +1,9 @@
#include <stdio.h>
void resource_leak_bug() {
FILE *f = fopen("data.txt", "r");
if (f == NULL) {
return;
}
// Missing fclose(f) — resource leak
}

View file

@ -0,0 +1,8 @@
#include <stdio.h>
void use_after_close_bug() {
FILE *f = fopen("data.txt", "r");
fclose(f);
char buf[256];
fread(buf, 1, sizeof(buf), f); // BUG: use after close
}

View file

@ -0,0 +1,16 @@
#include <stdio.h>
/* fclose in one branch, then unconditional fread after.
True path: fclose(f) fread(CLOSED) = use-after-close.
False path: fread(OPEN) = fine.
Converged state at fread: OPEN|CLOSED (join).
Expected: NO state-use-after-close (conservative: join masks it).
Expected: state-resource-leak-possible (false path never closes). */
void use_closed_branch(int cond) {
FILE *f = fopen("data.txt", "r");
if (cond) {
fclose(f);
}
char buf[256];
fread(buf, 1, sizeof(buf), f);
}