diff options
author | Stefan Sperling <stsp@cvs.openbsd.org> | 2013-01-20 14:47:47 +0000 |
---|---|---|
committer | Stefan Sperling <stsp@cvs.openbsd.org> | 2013-01-20 14:47:47 +0000 |
commit | 7bff3aca9d4d5ea111bbd14f169280c63b44d861 (patch) | |
tree | dca66165dd1146a848c4e868f31447f500191656 | |
parent | 3dd5cdf7689319f4b7aa72ac645d3ff1d6383dcb (diff) |
Fix backslash escaping during filename tab-completion in ksh.
Diff originally submitted by Alexander Polakov, with a small tweak from me
to avoid breaking tab-completion of environment variables (problem pointed
out by bentley).
ok sthen halex mpi
-rw-r--r-- | bin/ksh/edit.c | 32 | ||||
-rw-r--r-- | bin/ksh/lex.c | 6 | ||||
-rw-r--r-- | bin/ksh/lex.h | 3 |
3 files changed, 15 insertions, 26 deletions
diff --git a/bin/ksh/edit.c b/bin/ksh/edit.c index ec72d546c18..67841af9590 100644 --- a/bin/ksh/edit.c +++ b/bin/ksh/edit.c @@ -1,4 +1,4 @@ -/* $OpenBSD: edit.c,v 1.35 2012/09/10 01:25:30 tedu Exp $ */ +/* $OpenBSD: edit.c,v 1.36 2013/01/20 14:47:46 stsp Exp $ */ /* * Command line editing - common code @@ -348,7 +348,7 @@ x_file_glob(int flags, const char *str, int slen, char ***wordsp) { char *toglob; char **words; - int nwords, i, idx, escaping; + int nwords; XPtrV w; struct source *s, *sold; @@ -357,20 +357,6 @@ x_file_glob(int flags, const char *str, int slen, char ***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) */ @@ -378,7 +364,7 @@ x_file_glob(int flags, const char *str, int slen, char ***wordsp) s = pushs(SWSTR, ATEMP); s->start = s->str = toglob; source = s; - if (yylex(ONEWORD) != LWORD) { + if (yylex(ONEWORD|UNESCAPE) != LWORD) { source = sold; internal_errorf(0, "fileglob: substitute error"); return 0; @@ -394,15 +380,13 @@ x_file_glob(int flags, const char *str, int slen, char ***wordsp) if (nwords == 1) { struct stat statb; - /* Check if globbing failed (returned glob pattern), - * but be careful (E.g. toglob == "ab*" when the file - * "ab*" exists is not an error). - * Also, check for empty result - happens if we tried - * to glob something which evaluated to an empty - * string (e.g., "$FOO" when there is no FOO, etc). + /* Check if file exists, also, check for empty + * result - happens if we tried to glob something + * which evaluated to an empty string (e.g., + * "$FOO" when there is no FOO, etc). */ if ((strcmp(words[0], toglob) == 0 && - stat(words[0], &statb) < 0) || + lstat(words[0], &statb) < 0) || words[0][0] == '\0') { x_free_words(nwords, words); words = NULL; diff --git a/bin/ksh/lex.c b/bin/ksh/lex.c index da91ba68965..73e5610eeb3 100644 --- a/bin/ksh/lex.c +++ b/bin/ksh/lex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lex.c,v 1.45 2011/03/09 09:30:39 okan Exp $ */ +/* $OpenBSD: lex.c,v 1.46 2013/01/20 14:47:46 stsp Exp $ */ /* * lexical analysis and source input @@ -299,6 +299,10 @@ yylex(int cf) } /* FALLTHROUGH */ default: + if (cf & UNESCAPE) { + *wp++ = QCHAR, *wp++ = c; + break; + } Xcheck(ws, wp); if (c) { /* trailing \ is lost */ *wp++ = CHAR, *wp++ = '\\'; diff --git a/bin/ksh/lex.h b/bin/ksh/lex.h index 0904fbda1d9..0b2f2a2cae3 100644 --- a/bin/ksh/lex.h +++ b/bin/ksh/lex.h @@ -1,4 +1,4 @@ -/* $OpenBSD: lex.h,v 1.11 2006/05/29 18:22:24 otto Exp $ */ +/* $OpenBSD: lex.h,v 1.12 2013/01/20 14:47:46 stsp Exp $ */ /* * Source input, lexer and parser @@ -113,6 +113,7 @@ typedef union { #define CMDWORD BIT(8) /* parsing simple command (alias related) */ #define HEREDELIM BIT(9) /* parsing <<,<<- delimiter */ #define HEREDOC BIT(10) /* parsing heredoc */ +#define UNESCAPE BIT(11) /* remove backslashes */ #define HERES 10 /* max << in line */ |