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:
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 {