If rl_filename_rewrite_hook returns a new string for a filename (which I guess only happens on macOS with bash), it is in most cases not free-d.
run() { for ((i=0; i<=10000; i++)); do ((i%1000)) || ps -o rss= $BASHPID compgen -f . >/dev/null done } $ (run) 2160 4576 6864 9040 11232 13424 15584 17712 19856 22000 24144 --- diff --git a/lib/readline/complete.c b/lib/readline/complete.c index bf7cc856..99556a35 100644 --- a/lib/readline/complete.c +++ b/lib/readline/complete.c @@ -2521,6 +2521,9 @@ rl_filename_completion_function (const char *text, int state) convfn = dentry = 0; while (directory && (entry = readdir (directory))) { + if (convfn != dentry) + xfree (convfn); + convfn = dentry = entry->d_name; convlen = dentlen = D_NAMLEN (entry); @@ -2572,6 +2575,9 @@ rl_filename_completion_function (const char *text, int state) users_dirname = (char *)NULL; } + if (convfn != dentry) + xfree (convfn); + return (char *)NULL; } else