Fix doube free in completion

When falling back to rl_filename_completion_fuction as compentry
generator, the complete() function caused double free because the
generator did not return a strdup'ed entry but one of its own that
it freed when done.

Fixes #56

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg 2024-12-07 10:38:57 +01:00
parent 22bdb0478c
commit c7437c8ce3

View File

@ -243,9 +243,7 @@ char *el_filename_complete(char *pathname, int *match)
char *rl_filename_completion_function(const char *text, int state) char *rl_filename_completion_function(const char *text, int state)
{ {
char *dir; static char **av, *dir, *file;
char *file;
static char **av;
static size_t i, ac; static size_t i, ac;
if (!state) { if (!state) {
@ -253,21 +251,36 @@ char *rl_filename_completion_function(const char *text, int state)
return NULL; return NULL;
ac = FindMatches(dir, file, &av); ac = FindMatches(dir, file, &av);
if (!ac) {
free(dir); free(dir);
free(file); free(file);
if (!ac)
return NULL; return NULL;
}
i = 0; i = 0;
} }
if (i < ac) if (i < ac) {
return av[i++]; size_t len = (dir ? strlen(dir) : 0) + strlen(av[i]) + 3;
char *ptr = malloc(len);
if (ptr) {
snprintf(ptr, len, "%s%s", dir, av[i++]);
if (ac == 1)
rl_add_slash(ptr, ptr);
return ptr;
}
}
do { do {
free(av[--i]); free(av[--i]);
} while (i > 0); } while (i > 0);
free(av);
free(dir);
free(file);
return NULL; return NULL;
} }
@ -367,8 +380,12 @@ static char *complete(char *token, int *match)
free(word); free(word);
word = NULL; word = NULL;
if (words[0])
/* Exactly one match -- finish it off. */
if (words[0] && !words[1]) {
*match = 1;
word = strdup(words[0] + len); word = strdup(words[0] + len);
}
while (words[i]) while (words[i])
free(words[i++]); free(words[i++]);
@ -378,6 +395,9 @@ static char *complete(char *token, int *match)
return word; return word;
} }
if (word)
free(word);
fallback: fallback:
return el_filename_complete(token, match); return el_filename_complete(token, match);
} }