aboutsummaryrefslogtreecommitdiff
path: root/contrib/libedit/filecomplete.c
diff options
context:
space:
mode:
authorBaptiste Daroussin <bapt@FreeBSD.org>2021-03-22 14:34:14 +0000
committerBaptiste Daroussin <bapt@FreeBSD.org>2021-03-22 14:34:14 +0000
commitf9a159da2a292968cd5c37b56a6c43b6af8c5eed (patch)
tree6068c188fd0adbf0cfbc185d62250f6bd08960db /contrib/libedit/filecomplete.c
parenta0409676120c1e558d0ade943019934e0f15118d (diff)
parent881fcf9c3caf82a2f97a17b6ca91eb0b1b0320cd (diff)
Diffstat (limited to 'contrib/libedit/filecomplete.c')
-rw-r--r--contrib/libedit/filecomplete.c221
1 files changed, 113 insertions, 108 deletions
diff --git a/contrib/libedit/filecomplete.c b/contrib/libedit/filecomplete.c
index 662a0bb85d0b..61579024926c 100644
--- a/contrib/libedit/filecomplete.c
+++ b/contrib/libedit/filecomplete.c
@@ -1,4 +1,4 @@
-/* $NetBSD: filecomplete.c,v 1.58 2019/09/08 05:50:58 abhinav Exp $ */
+/* $NetBSD: filecomplete.c,v 1.64 2020/01/05 07:12:05 abhinav Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
-__RCSID("$NetBSD: filecomplete.c,v 1.58 2019/09/08 05:50:58 abhinav Exp $");
+__RCSID("$NetBSD: filecomplete.c,v 1.64 2020/01/05 07:12:05 abhinav Exp $");
#endif /* not lint && not SCCSID */
#include <sys/types.h>
@@ -86,8 +86,7 @@ fn_tilde_expand(const char *txt)
temp = el_calloc(len, sizeof(*temp));
if (temp == NULL)
return NULL;
- (void)strncpy(temp, txt + 1, len - 2);
- temp[len - 2] = '\0';
+ (void)strlcpy(temp, txt + 1, len - 1);
}
if (temp[0] == 0) {
#ifdef HAVE_GETPW_R_POSIX
@@ -354,8 +353,7 @@ fn_filename_completion_function(const char *text, int state)
return NULL;
}
dirname = nptr;
- (void)strncpy(dirname, text, len);
- dirname[len] = '\0';
+ (void)strlcpy(dirname, text, len + 1);
} else {
el_free(filename);
if (*text == 0)
@@ -509,8 +507,7 @@ completion_matches(const char *text, char *(*genfunc)(const char *, int))
el_free(match_list);
return NULL;
}
- (void)strncpy(retstr, match_list[1], max_equal);
- retstr[max_equal] = '\0';
+ (void)strlcpy(retstr, match_list[1], max_equal + 1);
match_list[0] = retstr;
/* add NULL as last pointer to the array */
@@ -586,10 +583,12 @@ fn_display_match_list(EditLine * el, char **matches, size_t num, size_t width,
static wchar_t *
find_word_to_complete(const wchar_t * cursor, const wchar_t * buffer,
- const wchar_t * word_break, const wchar_t * special_prefixes, size_t * length)
+ const wchar_t * word_break, const wchar_t * special_prefixes, size_t * length,
+ int do_unescape)
{
/* We now look backwards for the start of a filename/variable word */
const wchar_t *ctemp = cursor;
+ wchar_t *temp;
size_t len;
/* if the cursor is placed at a slash or a quote, we need to find the
@@ -614,12 +613,8 @@ find_word_to_complete(const wchar_t * cursor, const wchar_t * buffer,
if (ctemp - buffer >= 2 && ctemp[-2] == '\\') {
ctemp -= 2;
continue;
- } else if (ctemp - buffer >= 2 &&
- (ctemp[-2] == '\'' || ctemp[-2] == '"')) {
- ctemp--;
- continue;
- } else
- break;
+ }
+ break;
}
if (special_prefixes && wcschr(special_prefixes, ctemp[-1]))
break;
@@ -632,10 +627,16 @@ find_word_to_complete(const wchar_t * cursor, const wchar_t * buffer,
ctemp++;
}
*length = len;
- wchar_t *unescaped_word = unescape_string(ctemp, len);
- if (unescaped_word == NULL)
- return NULL;
- return unescaped_word;
+ if (do_unescape) {
+ wchar_t *unescaped_word = unescape_string(ctemp, len);
+ if (unescaped_word == NULL)
+ return NULL;
+ return unescaped_word;
+ }
+ temp = el_malloc((len + 1) * sizeof(*temp));
+ (void) wcsncpy(temp, ctemp, len);
+ temp[len] = '\0';
+ return temp;
}
/*
@@ -665,6 +666,7 @@ fn_complete(EditLine *el,
size_t len;
int what_to_do = '\t';
int retval = CC_NORM;
+ int do_unescape = attempted_completion_function == NULL? 1: 0;
if (el->el_state.lastcmd == el->el_state.thiscmd)
what_to_do = '?';
@@ -680,7 +682,7 @@ fn_complete(EditLine *el,
li = el_wline(el);
temp = find_word_to_complete(li->cursor,
- li->buffer, word_break, special_prefixes, &len);
+ li->buffer, word_break, special_prefixes, &len, do_unescape);
if (temp == NULL)
goto out;
@@ -706,107 +708,110 @@ fn_complete(EditLine *el,
if (over != NULL)
*over = 0;
- if (matches) {
- int i;
- size_t matches_num, maxlen, match_len, match_display=1;
- int single_match = matches[2] == NULL &&
- (matches[1] == NULL || strcmp(matches[0], matches[1]) == 0);
-
- retval = CC_REFRESH;
-
- if (matches[0][0] != '\0') {
- el_deletestr(el, (int)len);
- if (!attempted_completion_function)
- completion = escape_filename(el, matches[0],
- single_match, app_func);
- else
- completion = strdup(matches[0]);
- if (completion == NULL)
- goto out;
- if (single_match) {
- /* We found exact match. Add a space after it,
- * unless we do filename completion and the
- * object is a directory. Also do necessary
- * escape quoting
- */
- el_winsertstr(el,
- ct_decode_string(completion, &el->el_scratch));
- } else {
- /* Only replace the completed string with
- * common part of possible matches if there is
- * possible completion.
- */
- el_winsertstr(el,
- ct_decode_string(completion, &el->el_scratch));
- }
- free(completion);
- }
+ if (matches == NULL) {
+ goto out;
+ }
+ int i;
+ size_t matches_num, maxlen, match_len, match_display=1;
+ int single_match = matches[2] == NULL &&
+ (matches[1] == NULL || strcmp(matches[0], matches[1]) == 0);
+
+ retval = CC_REFRESH;
+
+ if (matches[0][0] != '\0') {
+ el_deletestr(el, (int)len);
+ if (!attempted_completion_function)
+ completion = escape_filename(el, matches[0],
+ single_match, app_func);
+ else
+ completion = strdup(matches[0]);
+ if (completion == NULL)
+ goto out;
+ /*
+ * Replace the completed string with the common part of
+ * all possible matches if there is a possible completion.
+ */
+ el_winsertstr(el,
+ ct_decode_string(completion, &el->el_scratch));
- if (!single_match && (what_to_do == '!' || what_to_do == '?')) {
+ if (single_match && attempted_completion_function) {
/*
- * More than one match and requested to list possible
- * matches.
+ * We found an exact match. Add a space after
+ * it, unless we do filename completion and the
+ * object is a directory. Also do necessary
+ * escape quoting
*/
+ el_winsertstr(el, ct_decode_string(
+ (*app_func)(completion), &el->el_scratch));
+ }
+ free(completion);
+ }
- for(i = 1, maxlen = 0; matches[i]; i++) {
- match_len = strlen(matches[i]);
- if (match_len > maxlen)
- maxlen = match_len;
- }
- /* matches[1] through matches[i-1] are available */
- matches_num = (size_t)(i - 1);
- /* newline to get on next line from command line */
- (void)fprintf(el->el_outfile, "\n");
+ if (!single_match && (what_to_do == '!' || what_to_do == '?')) {
+ /*
+ * More than one match and requested to list possible
+ * matches.
+ */
- /*
- * If there are too many items, ask user for display
- * confirmation.
- */
- if (matches_num > query_items) {
- (void)fprintf(el->el_outfile,
- "Display all %zu possibilities? (y or n) ",
- matches_num);
- (void)fflush(el->el_outfile);
- if (getc(stdin) != 'y')
- match_display = 0;
- (void)fprintf(el->el_outfile, "\n");
- }
+ for(i = 1, maxlen = 0; matches[i]; i++) {
+ match_len = strlen(matches[i]);
+ if (match_len > maxlen)
+ maxlen = match_len;
+ }
+ /* matches[1] through matches[i-1] are available */
+ matches_num = (size_t)(i - 1);
- if (match_display) {
- /*
- * Interface of this function requires the
- * strings be matches[1..num-1] for compat.
- * We have matches_num strings not counting
- * the prefix in matches[0], so we need to
- * add 1 to matches_num for the call.
- */
- fn_display_match_list(el, matches,
- matches_num+1, maxlen, app_func);
- }
- retval = CC_REDISPLAY;
- } else if (matches[0][0]) {
+ /* newline to get on next line from command line */
+ (void)fprintf(el->el_outfile, "\n");
+
+ /*
+ * If there are too many items, ask user for display
+ * confirmation.
+ */
+ if (matches_num > query_items) {
+ (void)fprintf(el->el_outfile,
+ "Display all %zu possibilities? (y or n) ",
+ matches_num);
+ (void)fflush(el->el_outfile);
+ if (getc(stdin) != 'y')
+ match_display = 0;
+ (void)fprintf(el->el_outfile, "\n");
+ }
+
+ if (match_display) {
/*
- * There was some common match, but the name was
- * not complete enough. Next tab will print possible
- * completions.
+ * Interface of this function requires the
+ * strings be matches[1..num-1] for compat.
+ * We have matches_num strings not counting
+ * the prefix in matches[0], so we need to
+ * add 1 to matches_num for the call.
*/
- el_beep(el);
- } else {
- /* lcd is not a valid object - further specification */
- /* is needed */
- el_beep(el);
- retval = CC_NORM;
+ fn_display_match_list(el, matches,
+ matches_num+1, maxlen, app_func);
}
-
- /* free elements of array and the array itself */
- for (i = 0; matches[i]; i++)
- el_free(matches[i]);
- el_free(matches);
- matches = NULL;
+ retval = CC_REDISPLAY;
+ } else if (matches[0][0]) {
+ /*
+ * There was some common match, but the name was
+ * not complete enough. Next tab will print possible
+ * completions.
+ */
+ el_beep(el);
+ } else {
+ /* lcd is not a valid object - further specification */
+ /* is needed */
+ el_beep(el);
+ retval = CC_NORM;
}
+ /* free elements of array and the array itself */
+ for (i = 0; matches[i]; i++)
+ el_free(matches[i]);
+ el_free(matches);
+ matches = NULL;
+
out:
el_free(temp);
return retval;