diff --git a/bin/sh/histedit.c b/bin/sh/histedit.c --- a/bin/sh/histedit.c +++ b/bin/sh/histedit.c @@ -605,7 +605,7 @@ { char *free_path = NULL, *path; const char *dirname; - char **matches = NULL; + char **matches = NULL, **rmatches, *duplicate; size_t i = 0, size = 16, uniq; size_t curpos = end - start, lcstring = -1; @@ -631,7 +631,6 @@ } while ((entry = readdir(dir)) != NULL) { struct stat statb; - char **rmatches; if (strncmp(entry->d_name, text, curpos) != 0) continue; @@ -642,7 +641,11 @@ continue; } else if (entry->d_type != DT_REG) continue; - matches[++i] = strdup(entry->d_name); + matches[++i] = duplicate = strdup(entry->d_name); + if (duplicate == NULL) { + closedir(dir); + goto out; + } if (i < size - 1) continue; size *= 2; @@ -655,6 +658,20 @@ } closedir(dir); } + for (const unsigned char *bp = builtincmd; *bp != 0; bp += 2 + bp[0]) { + if (curpos > bp[0] || memcmp(bp + 2, text, curpos) != 0) + continue; + matches[++i] = duplicate = strndup(bp + 2, bp[0]); + if (duplicate == NULL) + goto out; + if (i < size - 1) + continue; + size *= 2; + rmatches = reallocarray(matches, size, sizeof(matches[0])); + if (rmatches == NULL) + goto out; + matches = rmatches; + } out: free(free_path); if (i == 0) {