diff options
author | Alan Coopersmith <alan.coopersmith@oracle.com> | 2024-01-21 15:20:46 -0800 |
---|---|---|
committer | Alan Coopersmith <alan.coopersmith@oracle.com> | 2024-01-21 15:20:46 -0800 |
commit | b7d18901774b955e000610b4138e93ed528613f7 (patch) | |
tree | e7d35652d19917c1a91eaf15179f0b48c6b362d1 | |
parent | a92147737501dc07996d7211a7b56f2b3f9cf3f6 (diff) |
Plug memory leaks in error paths of ScanDir()
Found by -Wanalyzer-malloc-leak warning from gcc 13.2
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
-rw-r--r-- | miscfuncs.c | 39 |
1 files changed, 25 insertions, 14 deletions
diff --git a/miscfuncs.c b/miscfuncs.c index c6f1d18..ac476f2 100644 --- a/miscfuncs.c +++ b/miscfuncs.c @@ -43,36 +43,38 @@ ScanDir( { register char **names; register ENTRY *E; - register DIR *Dp; - register int i; - register int size; + register DIR *Dp = NULL; + register size_t i = 0; + register size_t size; /* Get initial list space and open directory. */ size = INITIAL_SIZE; - if (!(names = (char **)malloc(size * sizeof(char *))) || + if (!(names = malloc(size * sizeof(char *))) || !(Dp = opendir(Name))) - return(-1); + goto failure; /* Read entries in the directory. */ - for (i = 0; (E = readdir(Dp)); ) + while ((E = readdir(Dp))) { if (!Selector || (*Selector)(E->d_name)) { /* User wants them all, or he wants this one. */ if (++i >= size) { + char **newnames = NULL; size <<= 1; - names = (char**)realloc((char *)names, size * sizeof(char*)); - if (!names) { - closedir(Dp); - return(-1); + newnames = realloc(names, size * sizeof(char*)); + if (!newnames) { + i--; + goto failure; } + names = newnames; } /* Copy the entry. */ - if (!(names[i - 1] = (char *)malloc(strlen(E->d_name) + 1))) { - closedir(Dp); - return(-1); + names[i - 1] = strdup(E->d_name); + if (names[i - 1] == NULL) { + goto failure; } - (void)strcpy(names[i - 1], E->d_name); } + } /* Close things off. */ names[i] = (char *)0; @@ -85,4 +87,13 @@ ScanDir( (int (*)(const void *, const void *))StrCmp); return(i); + + failure: + for (size_t n = 0; n < i; n++) { + free(names[i]); + } + free(names); + if (Dp != NULL) + closedir(Dp); + return(-1); } |