sonar

Scan files at memory bandwidth speed.
Log | Files | Refs

commit b65b98b0476133970c7bc70285c076776b8f5c62
parent d9269bfe5f0a6e8c089176269eff2f9d75c9dd64
Author: Jack Mordaunt <jackmordaunt.dev@gmail.com>
Date:   Sun, 20 Sep 2026 07:42:03 -0300

main: free the table when projecting it fails

The defer that destroys the table sat below the switch that fills it, so the
early return from a failed `to_tree` skipped it and dropped a whole MFT. The
projection's first act is to reserve a node per record slot, which is exactly
where an out-of-memory lands, so the path that leaks most is the one most likely
to be taken.

Registering it beside the declaration covers every return instead. Ordering is
unchanged: it still runs before the tree is destroyed, and the table still
outlives the names the tree borrows from it.

Diffstat:
Mmain.odin | 8+++++---
1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/main.odin b/main.odin @@ -133,6 +133,11 @@ run :: proc() -> int { // keeps its own table, which carries what only NTFS knows. m: ntfs.Mft have_mft := false + // Registered before the read, not after the switch: projecting the table can fail, + // and a defer below that point never covers the return it takes. + defer if have_mft { + ntfs.mft_destroy(&m) + } switch choice.engine { case .Mft: err := ntfs.read_mft(resolved.volume, &m, opts) @@ -167,9 +172,6 @@ run :: proc() -> int { } case .None: } - defer if have_mft { - ntfs.mft_destroy(&m) - } elapsed := time.tick_since(start) if have_mft {