diff options
author | David Leonard <d@cvs.openbsd.org> | 1999-11-14 22:04:03 +0000 |
---|---|---|
committer | David Leonard <d@cvs.openbsd.org> | 1999-11-14 22:04:03 +0000 |
commit | 927e778570087ee7dbae3245e2bd0cd787d7ce6b (patch) | |
tree | 9a2285f36a2026cbe0d6a75b912482292fc19d71 /bin/ksh | |
parent | 44878276ee07b9b57ddadb0f9a8694c887f5b926 (diff) |
quote metachars when completing filenames from jdolecek@netbsd. ok millert@
Diffstat (limited to 'bin/ksh')
-rw-r--r-- | bin/ksh/edit.c | 63 | ||||
-rw-r--r-- | bin/ksh/edit.h | 3 | ||||
-rw-r--r-- | bin/ksh/emacs.c | 22 | ||||
-rw-r--r-- | bin/ksh/vi.c | 23 |
4 files changed, 98 insertions, 13 deletions
diff --git a/bin/ksh/edit.c b/bin/ksh/edit.c index 79bee4ab6df..6b383785f8b 100644 --- a/bin/ksh/edit.c +++ b/bin/ksh/edit.c @@ -1,4 +1,4 @@ -/* $OpenBSD: edit.c,v 1.10 1999/06/15 01:18:33 millert Exp $ */ +/* $OpenBSD: edit.c,v 1.11 1999/11/14 22:04:02 d Exp $ */ /* * Command line editing - common code @@ -555,7 +555,7 @@ x_file_glob(flags, str, slen, wordsp) { char *toglob; char **words; - int nwords; + int nwords, i, idx, escaping; XPtrV w; struct source *s, *sold; @@ -564,6 +564,20 @@ x_file_glob(flags, str, slen, wordsp) toglob = add_glob(str, slen); + /* remove all escaping backward slashes */ + escaping = 0; + for(i = 0, idx = 0; toglob[i]; i++) { + if (toglob[i] == '\\' && !escaping) { + escaping = 1; + continue; + } + + toglob[idx] = toglob[i]; + idx++; + if (escaping) escaping = 0; + } + toglob[idx] = '\0'; + /* * Convert "foo*" (toglob) to an array of strings (words) */ @@ -750,11 +764,14 @@ x_locate_word(buf, buflen, pos, startp, is_commandp) /* Keep going backwards to start of word (has effect of allowing * one blank after the end of a word) */ - for (; start > 0 && IS_WORDC(buf[start - 1]); start--) + for (; (start > 0 && IS_WORDC(buf[start - 1])) + || (start > 1 && buf[start-2] == '\\'); start--) ; /* Go forwards to end of word */ - for (end = start; end < buflen && IS_WORDC(buf[end]); end++) - ; + for (end = start; end < buflen && IS_WORDC(buf[end]); end++) { + if (buf[end] == '\\' && (end+1) < buflen && buf[end+1] == ' ') + end++; + } if (is_commandp) { int iscmd; @@ -1021,4 +1038,40 @@ glob_path(flags, pat, wp, path) Xfree(xs, xp); } +/* + * if argument string contains any special characters, they will + * be escaped and the result will be put into edit buffer by + * keybinding-specific function + */ +int +x_escape(s, len, putbuf_func) + const char *s; + size_t len; + int putbuf_func ARGS((const char *s, size_t len)); +{ + size_t add, wlen; + const char *ifs = str_val(local("IFS", 0)); + int rval=0; + + for (add = 0, wlen = len; wlen - add > 0; add++) { + if (strchr("\\$(){}*&;|<>\"'", s[add]) || strchr(ifs, s[add])) { + if (putbuf_func(s, add) != 0) { + rval = -1; + break; + } + + putbuf_func("\\", 1); + putbuf_func(&s[add], 1); + + add++; + wlen -= add; + s += add; + add = -1; /* after the increment it will go to 0 */ + } + } + if (wlen > 0 && rval == 0) + rval = putbuf_func(s, wlen); + + return (rval); +} #endif /* EDIT */ diff --git a/bin/ksh/edit.h b/bin/ksh/edit.h index fd29701cc06..d8f3641d399 100644 --- a/bin/ksh/edit.h +++ b/bin/ksh/edit.h @@ -1,4 +1,4 @@ -/* $OpenBSD: edit.h,v 1.2 1996/08/19 20:08:48 downsj Exp $ */ +/* $OpenBSD: edit.h,v 1.3 1999/11/14 22:04:02 d Exp $ */ /* NAME: * edit.h - globals for edit modes @@ -57,6 +57,7 @@ int x_cf_glob ARGS((int flags, const char *buf, int buflen, int pos, int *startp int x_longest_prefix ARGS((int nwords, char *const *words)); int x_basename ARGS((const char *s, const char *se)); void x_free_words ARGS((int nwords, char **words)); +int x_escape ARGS((const char *, size_t, int (*)(const char *s, size_t len))); /* emacs.c */ int x_emacs ARGS((char *buf, size_t len)); void x_init_emacs ARGS((void)); diff --git a/bin/ksh/emacs.c b/bin/ksh/emacs.c index ea035cf4cd0..44a9b5b6632 100644 --- a/bin/ksh/emacs.c +++ b/bin/ksh/emacs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: emacs.c,v 1.11 1999/08/04 19:11:13 millert Exp $ */ +/* $OpenBSD: emacs.c,v 1.12 1999/11/14 22:04:02 d Exp $ */ /* * Emacs-like command line editing and history @@ -144,6 +144,7 @@ static int x_comment ARGS((int c)); static int x_fold_case ARGS((int c)); static char *x_lastcp ARGS((void)); static void do_complete ARGS((int flags, Comp_type type)); +static int x_emacs_putbuf ARGS((const char *s, size_t len)); /* The lines between START-FUNC-TAB .. END-FUNC-TAB are run through a @@ -472,6 +473,21 @@ x_ins(s) return 0; } +/* + * this is used for x_escape() in do_complete() + */ +static int +x_emacs_putbuf(s, len) + const char *s; + size_t len; +{ + int rval; + + if ((rval = x_do_ins(s, len)) != 0) + return (rval); + return (rval); +} + static int x_del_back(c) int c; @@ -1832,8 +1848,8 @@ do_complete(flags, type) if (nlen > 0) { x_goto(xbuf + start); x_delete(end - start, FALSE); - words[0][nlen] = '\0'; - x_ins(words[0]); + x_escape(words[0], nlen, x_emacs_putbuf); + x_adjust(); /* If single match is not a directory, add a * space to the end... */ diff --git a/bin/ksh/vi.c b/bin/ksh/vi.c index 607c571d180..ad7b67b3802 100644 --- a/bin/ksh/vi.c +++ b/bin/ksh/vi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vi.c,v 1.7 1999/07/14 13:37:24 millert Exp $ */ +/* $OpenBSD: vi.c,v 1.8 1999/11/14 22:04:02 d Exp $ */ /* * vi command editing @@ -65,6 +65,7 @@ static void x_vi_zotc ARGS((int c)); static void vi_pprompt ARGS((int full)); static void vi_error ARGS((void)); static void vi_macro_reset ARGS((void)); +static int x_vi_putbuf ARGS((const char *s, size_t len)); #define C_ 0x1 /* a valid command that isn't a M_, E_, U_ */ #define M_ 0x2 /* movement command (h, l, etc.) */ @@ -1472,6 +1473,17 @@ edit_reset(buf, len) holdlen = 0; } +/* + * this is used for calling x_escape() in complete_word() + */ +static int +x_vi_putbuf(s, len) + const char *s; + size_t len; +{ + return putbuf(s, len, 0); +} + static int putbuf(buf, len, repl) const char *buf; @@ -2070,9 +2082,12 @@ complete_word(command, count) buf = save_edstate(es); del_range(start, end); es->cursor = start; - if (putbuf(match, match_len, 0) != 0) - rval = -1; - else if (is_unique) { + + /* escape all shell-sensitive characters and put the result into + * command buffer */ + rval = x_escape(match, match_len, x_vi_putbuf); + + if (rval == 0 && is_unique) { /* If exact match, don't undo. Allows directory completions * to be used (ie, complete the next portion of the path). */ |