[PATCH v2 06/12] dir: free allocations on parse-error paths in `read_one_dir()`
From: Johannes Schindelin via GitGitGadget <hidden>
Date: 2026-07-05 08:24:43
Subsystem:
the rest · Maintainer:
Linus Torvalds
From: Johannes Schindelin via GitGitGadget <hidden>
Date: 2026-07-05 08:24:43
Subsystem:
the rest · Maintainer:
Linus Torvalds
From: Johannes Schindelin <redacted> Two of `read_one_dir()`'s parse-error early returns leak ud.untracked and ud.dirs. Plug them. The other early returns in the same function are fine: they occur after the `xmalloc()`+`memcpy()` that copies ud into `*untracked_`, at which point ownership is transferred to the caller. `read_untracked_extension()` then releases everything via `free_untracked_cache()` on failure. Pointed out by Coverity. Assisted-by: Claude Opus 4.6 Signed-off-by: Johannes Schindelin <redacted> --- dir.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/dir.c b/dir.c
index 32430090dc..23335b9f7a 100644
--- a/dir.c
+++ b/dir.c@@ -3792,13 +3792,18 @@ static int read_one_dir(struct untracked_cache_dir **untracked_, ALLOC_ARRAY(ud.untracked, ud.untracked_nr); ud.dirs_alloc = ud.dirs_nr = decode_varint(&data); - if (data > end) + if (data > end) { + free(ud.untracked); return -1; + } ALLOC_ARRAY(ud.dirs, ud.dirs_nr); eos = memchr(data, '\0', end - data); - if (!eos || eos == end) + if (!eos || eos == end) { + free(ud.untracked); + free(ud.dirs); return -1; + } *untracked_ = untracked = xmalloc(st_add3(sizeof(*untracked), eos - data, 1)); memcpy(untracked, &ud, sizeof(ud));
--
gitgitgadget