diff options
Diffstat (limited to 'cmd-line-utils/libedit/readline.c')
-rw-r--r-- | cmd-line-utils/libedit/readline.c | 240 |
1 files changed, 179 insertions, 61 deletions
diff --git a/cmd-line-utils/libedit/readline.c b/cmd-line-utils/libedit/readline.c index 9069b46d1f8..5b40ade582c 100644 --- a/cmd-line-utils/libedit/readline.c +++ b/cmd-line-utils/libedit/readline.c @@ -1,4 +1,4 @@ -/* $NetBSD: readline.c,v 1.19 2001/01/10 08:10:45 jdolecek Exp $ */ +/* $NetBSD: readline.c,v 1.28 2003/03/10 01:14:54 christos Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -36,7 +36,11 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "compat.h" +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +__RCSID("$NetBSD: readline.c,v 1.28 2003/03/10 01:14:54 christos Exp $"); +#endif /* not lint && not SCCSID */ + #include <sys/types.h> #include <sys/stat.h> #include <stdio.h> @@ -47,14 +51,13 @@ #include <stdlib.h> #include <unistd.h> #include <limits.h> +#ifdef HAVE_ALLOCA_H +#include <alloca.h> +#endif #include "histedit.h" #include "readline/readline.h" -#include "sys.h" #include "el.h" #include "fcns.h" /* for EL_NUM_FCNS */ -#ifdef HAVE_ALLOCA_H -#include <alloca.h> -#endif /* for rl_complete() */ #define TAB '\r' @@ -65,7 +68,11 @@ /* readline compatibility stuff - look at readline sources/documentation */ /* to see what these variables mean */ const char *rl_library_version = "EditLine wrapper"; -const char *rl_readline_name = ""; +static char empty[] = { '\0' }; +static char expand_chars[] = { ' ', '\t', '\n', '=', '(', '\0' }; +static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$', + '>', '<', '=', ';', '|', '&', '{', '(', '\0' }; +char *rl_readline_name = empty; FILE *rl_instream = NULL; FILE *rl_outstream = NULL; int rl_point = 0; @@ -77,12 +84,12 @@ int history_length = 0; int max_input_history = 0; char history_expansion_char = '!'; char history_subst_char = '^'; -const char *history_no_expand_chars = " \t\n=("; +char *history_no_expand_chars = expand_chars; Function *history_inhibit_expansion_function = NULL; int rl_inhibit_completion = 0; int rl_attempted_completion_over = 0; -const char *rl_basic_word_break_characters = " \t\n\"\\'`@$><=;|&{("; +char *rl_basic_word_break_characters = break_chars; char *rl_completer_word_break_characters = NULL; char *rl_completer_quote_characters = NULL; CPFunction *rl_completion_entry_function = NULL; @@ -215,6 +222,11 @@ rl_initialize(void) /* for proper prompt printing in readline() */ el_rl_prompt = strdup(""); + if (el_rl_prompt == NULL) { + history_end(h); + el_end(e); + return -1; + } el_set(e, EL_PROMPT, _get_prompt); el_set(e, EL_SIGNAL, 1); @@ -250,8 +262,8 @@ rl_initialize(void) * and rl_line_buffer directly. */ li = el_line(e); - /* LINTED const cast */ - rl_line_buffer = (char *) li->buffer; + /* a cheesy way to get rid of const cast. */ + rl_line_buffer = memchr(li->buffer, *li->buffer, 1); rl_point = rl_end = 0; return (0); @@ -268,6 +280,7 @@ readline(const char *prompt) HistEvent ev; int count; const char *ret; + char *buf; if (e == NULL || h == NULL) rl_initialize(); @@ -278,28 +291,28 @@ readline(const char *prompt) if (strcmp(el_rl_prompt, prompt) != 0) { free(el_rl_prompt); el_rl_prompt = strdup(prompt); + if (el_rl_prompt == NULL) + return NULL; } /* get one line from input stream */ ret = el_gets(e, &count); if (ret && count > 0) { - char *foo; int lastidx; - foo = strdup(ret); + buf = strdup(ret); + if (buf == NULL) + return NULL; lastidx = count - 1; - if (foo[lastidx] == '\n') - foo[lastidx] = '\0'; - - ret = foo; + if (buf[lastidx] == '\n') + buf[lastidx] = '\0'; } else - ret = NULL; + buf = NULL; history(h, &ev, H_GETSIZE); history_length = ev.num; - /* LINTED const cast */ - return (char *) ret; + return buf; } /* @@ -333,6 +346,8 @@ _rl_compat_sub(const char *str, const char *what, const char *with, size_t size, i; result = malloc((size = 16)); + if (result == NULL) + return NULL; temp = str; with_len = strlen(with); what_len = strlen(what); @@ -343,8 +358,14 @@ _rl_compat_sub(const char *str, const char *what, const char *with, i = new - temp; add = i + with_len; if (i + add + 1 >= size) { + char *nresult; size += add + 1; - result = realloc(result, size); + nresult = realloc(result, size); + if (nresult == NULL) { + free(result); + return NULL; + } + result = nresult; } (void) strncpy(&result[len], temp, i); len += i; @@ -354,8 +375,14 @@ _rl_compat_sub(const char *str, const char *what, const char *with, } else { add = strlen(temp); if (len + add + 1 >= size) { + char *nresult; size += add + 1; - result = realloc(result, size); + nresult = realloc(result, size); + if (nresult == NULL) { + free(result); + return NULL; + } + result = nresult; } (void) strcpy(&result[len], temp); /* safe */ len += add; @@ -392,7 +419,7 @@ _history_expand_command(const char *command, size_t cmdlen, char **result) *result = NULL; - cmd = (char*) alloca(cmdlen + 1); + cmd = alloca(cmdlen + 1); (void) strncpy(cmd, command, cmdlen); cmd[cmdlen] = 0; @@ -425,7 +452,7 @@ _history_expand_command(const char *command, size_t cmdlen, char **result) return (-1); prefix = 0; } - search = (char*) alloca(len + 1); + search = alloca(len + 1); (void) strncpy(search, &cmd[idx], len); search[len] = '\0'; @@ -498,6 +525,8 @@ _history_expand_command(const char *command, size_t cmdlen, char **result) cmd++; line = strdup(event_data); + if (line == NULL) + return 0; for (; *cmd; cmd++) { if (*cmd == ':') continue; @@ -515,7 +544,7 @@ _history_expand_command(const char *command, size_t cmdlen, char **result) g_on = 2; else if (*cmd == 's' || *cmd == '&') { char *what, *with, delim; - size_t len, from_len; + unsigned int len, from_len; size_t size; if (*cmd == '&' && (from == NULL || to == NULL)) @@ -524,23 +553,36 @@ _history_expand_command(const char *command, size_t cmdlen, char **result) delim = *(++cmd), cmd++; size = 16; what = realloc(from, size); + if (what == NULL) { + free(from); + return 0; + } len = 0; for (; *cmd && *cmd != delim; cmd++) { if (*cmd == '\\' && *(cmd + 1) == delim) cmd++; - if (len >= size) - what = realloc(what, + if (len >= size) { + char *nwhat; + nwhat = realloc(what, (size <<= 1)); + if (nwhat == NULL) { + free(what); + return 0; + } + what = nwhat; + } what[len++] = *cmd; } what[len] = '\0'; from = what; if (*what == '\0') { free(what); - if (search) + if (search) { from = strdup(search); - else { + if (from == NULL) + return 0; + } else { from = NULL; return (-1); } @@ -551,12 +593,22 @@ _history_expand_command(const char *command, size_t cmdlen, char **result) size = 16; with = realloc(to, size); + if (with == NULL) { + free(to); + return -1; + } len = 0; from_len = strlen(from); for (; *cmd && *cmd != delim; cmd++) { if (len + from_len + 1 >= size) { + char *nwith; size += from_len + 1; - with = realloc(with, size); + nwith = realloc(with, size); + if (nwith == NULL) { + free(with); + return -1; + } + with = nwith; } if (*cmd == '&') { /* safe */ @@ -575,8 +627,10 @@ _history_expand_command(const char *command, size_t cmdlen, char **result) tempcmd = _rl_compat_sub(line, from, to, (g_on) ? 1 : 0); - free(line); - line = tempcmd; + if (tempcmd) { + free(line); + line = tempcmd; + } g_on = 0; } } @@ -622,14 +676,21 @@ _history_expand_command(const char *command, size_t cmdlen, char **result) } cmdsize = 1, cmdlen = 0; - tempcmd = malloc(cmdsize); + if ((tempcmd = malloc(cmdsize)) == NULL) + return 0; for (i = start; start <= i && i <= end; i++) { int arr_len; arr_len = strlen(arr[i]); if (cmdlen + arr_len + 1 >= cmdsize) { + char *ntempcmd; cmdsize += arr_len + 1; - tempcmd = realloc(tempcmd, cmdsize); + ntempcmd = realloc(tempcmd, cmdsize); + if (ntempcmd == NULL) { + free(tempcmd); + return 0; + } + tempcmd = ntempcmd; } (void) strcpy(&tempcmd[cmdlen], arr[i]); /* safe */ cmdlen += arr_len; @@ -662,10 +723,12 @@ history_expand(char *str, char **output) rl_initialize(); *output = strdup(str); /* do it early */ + if (*output == NULL) + return 0; if (str[0] == history_subst_char) { /* ^foo^foo2^ is equivalent to !!:s^foo^foo2^ */ - temp = (char*) alloca(4 + strlen(str) + 1); + temp = alloca(4 + strlen(str) + 1); temp[0] = temp[1] = history_expansion_char; temp[2] = ':'; temp[3] = 's'; @@ -674,8 +737,14 @@ history_expand(char *str, char **output) } #define ADD_STRING(what, len) \ { \ - if (idx + len + 1 > size) \ - result = realloc(result, (size += len + 1)); \ + if (idx + len + 1 > size) { \ + char *nresult = realloc(result, (size += len + 1));\ + if (nresult == NULL) { \ + free(*output); \ + return 0; \ + } \ + result = nresult; \ + } \ (void)strncpy(&result[idx], what, len); \ idx += len; \ result[idx] = '\0'; \ @@ -789,11 +858,21 @@ history_tokenize(const char *str) } if (result_idx + 2 >= size) { + char **nresult; size <<= 1; - result = realloc(result, size * sizeof(char *)); + nresult = realloc(result, size * sizeof(char *)); + if (nresult == NULL) { + free(result); + return NULL; + } + result = nresult; } len = i - start; temp = malloc(len + 1); + if (temp == NULL) { + free(result); + return NULL; + } (void) strncpy(temp, &str[start], len); temp[len] = '\0'; result[result_idx++] = temp; @@ -1158,11 +1237,15 @@ tilde_expand(char *txt) return (strdup(txt)); temp = strchr(txt + 1, '/'); - if (temp == NULL) + if (temp == NULL) { temp = strdup(txt + 1); - else { + if (temp == NULL) + return NULL; + } else { len = temp - txt + 1; /* text until string after slash */ temp = malloc(len); + if (temp == NULL) + return NULL; (void) strncpy(temp, txt + 1, len - 2); temp[len - 2] = '\0'; } @@ -1176,6 +1259,8 @@ tilde_expand(char *txt) txt += len; temp = malloc(strlen(pass->pw_dir) + 1 + strlen(txt) + 1); + if (temp == NULL) + return NULL; (void) sprintf(temp, "%s/%s", pass->pw_dir, txt); return (temp); @@ -1200,28 +1285,45 @@ filename_completion_function(const char *text, int state) size_t len; if (state == 0 || dir == NULL) { - if (dir != NULL) { - closedir(dir); - dir = NULL; - } temp = strrchr(text, '/'); if (temp) { + char *nptr; temp++; - filename = realloc(filename, strlen(temp) + 1); + nptr = realloc(filename, strlen(temp) + 1); + if (nptr == NULL) { + free(filename); + return NULL; + } + filename = nptr; (void) strcpy(filename, temp); len = temp - text; /* including last slash */ - dirname = realloc(dirname, len + 1); + nptr = realloc(dirname, len + 1); + if (nptr == NULL) { + free(filename); + return NULL; + } + dirname = nptr; (void) strncpy(dirname, text, len); dirname[len] = '\0'; } else { filename = strdup(text); + if (filename == NULL) + return NULL; dirname = NULL; } /* support for ``~user'' syntax */ if (dirname && *dirname == '~') { + char *nptr; temp = tilde_expand(dirname); - dirname = realloc(dirname, strlen(temp) + 1); + if (temp == NULL) + return NULL; + nptr = realloc(dirname, strlen(temp) + 1); + if (nptr == NULL) { + free(dirname); + return NULL; + } + dirname = nptr; (void) strcpy(dirname, temp); /* safe */ free(temp); /* no longer needed */ } @@ -1230,6 +1332,10 @@ filename_completion_function(const char *text, int state) if (filename_len == 0) return (NULL); /* no expansion possible */ + if (dir != NULL) { + (void)closedir(dir); + dir = NULL; + } dir = opendir(dirname ? dirname : "."); if (!dir) return (NULL); /* cannot open the directory */ @@ -1239,7 +1345,7 @@ filename_completion_function(const char *text, int state) /* otherwise, get first entry where first */ /* filename_len characters are equal */ if (entry->d_name[0] == filename[0] -#ifdef HAVE_DIRENT_H +#ifndef STRUCT_DIRENT_HAS_D_NAMLEN && strlen(entry->d_name) >= filename_len #else && entry->d_namlen >= filename_len @@ -1252,21 +1358,26 @@ filename_completion_function(const char *text, int state) if (entry) { /* match found */ struct stat stbuf; -#ifdef HAVE_DIRENT_H +#ifndef STRUCT_DIRENT_HAS_D_NAMLEN len = strlen(entry->d_name) + #else len = entry->d_namlen + #endif ((dirname) ? strlen(dirname) : 0) + 1 + 1; temp = malloc(len); + if (temp == NULL) + return NULL; (void) sprintf(temp, "%s%s", dirname ? dirname : "", entry->d_name); /* safe */ /* test, if it's directory */ if (stat(temp, &stbuf) == 0 && S_ISDIR(stbuf.st_mode)) strcat(temp, "/"); /* safe */ - } else + } else { + (void)closedir(dir); + dir = NULL; temp = NULL; + } return (temp); } @@ -1331,16 +1442,24 @@ completion_matches(const char *text, CPFunction *genfunc) matches = 0; match_list_len = 1; while ((retstr = (*genfunc) (text, matches)) != NULL) { - if (matches + 1 >= match_list_len) { + /* allow for list terminator here */ + if (matches + 2 >= match_list_len) { + char **nmatch_list; match_list_len <<= 1; - match_list = realloc(match_list, + nmatch_list = realloc(match_list, match_list_len * sizeof(char *)); + if (nmatch_list == NULL) { + free(match_list); + return NULL; + } + match_list = nmatch_list; + } match_list[++matches] = retstr; } if (!match_list) - return (char **) NULL; /* nothing found */ + return NULL; /* nothing found */ /* find least denominator and insert it to match_list[0] */ which = 2; @@ -1354,14 +1473,15 @@ completion_matches(const char *text, CPFunction *genfunc) } retstr = malloc(max_equal + 1); + if (retstr == NULL) { + free(match_list); + return NULL; + } (void) strncpy(retstr, match_list[1], max_equal); retstr[max_equal] = '\0'; match_list[0] = retstr; /* add NULL as last pointer to the array */ - if (matches + 1 >= match_list_len) - match_list = realloc(match_list, - (match_list_len + 1) * sizeof(char *)); match_list[matches + 1] = (char *) NULL; return (match_list); @@ -1374,10 +1494,8 @@ static int _rl_qsort_string_compare(i1, i2) const void *i1, *i2; { - /*LINTED const castaway*/ - const char *s1 = ((const char **)i1)[0]; - /*LINTED const castaway*/ - const char *s2 = ((const char **)i2)[0]; + const char *s1 = ((const char * const *)i1)[0]; + const char *s2 = ((const char * const *)i2)[0]; return strcasecmp(s1, s2); } @@ -1459,7 +1577,7 @@ rl_complete_internal(int what_to_do) ctemp--; len = li->cursor - ctemp; - temp = (char*) alloca(len + 1); + temp = alloca(len + 1); (void) strncpy(temp, ctemp, len); temp[len] = '\0'; |