summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Sperling <stsp@cvs.openbsd.org>2013-01-20 14:47:47 +0000
committerStefan Sperling <stsp@cvs.openbsd.org>2013-01-20 14:47:47 +0000
commit7bff3aca9d4d5ea111bbd14f169280c63b44d861 (patch)
treedca66165dd1146a848c4e868f31447f500191656
parent3dd5cdf7689319f4b7aa72ac645d3ff1d6383dcb (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.c32
-rw-r--r--bin/ksh/lex.c6
-rw-r--r--bin/ksh/lex.h3
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 */