|
BASH PATCH REPORT
|
|
=================
|
|
|
|
Bash-Release: 4.3
|
|
Patch-ID: bash43-010
|
|
|
|
Bug-Reported-by: Albert Shih <Albert.Shih@obspm.fr>
|
|
Bug-Reference-ID: Wed, 5 Mar 2014 23:01:40 +0100
|
|
Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2014-03/msg00028.html
|
|
|
|
Bug-Description:
|
|
|
|
Patch (apply with `patch -p0'):
|
|
|
|
This patch changes the behavior of programmable completion to compensate
|
|
for two assumptions made by the bash-completion package. Bash-4.3 changed
|
|
to dequote the argument to programmable completion only under certain
|
|
circumstances, to make the behavior of compgen more consistent when run
|
|
from the command line -- closer to the behavior when run by a shell function
|
|
run as part of programmable completion. Bash-completion can pass quoted
|
|
arguments to compgen when the original word to be completed was not quoted,
|
|
expecting programmable completion to dequote the word before attempting
|
|
completion.
|
|
|
|
This patch fixes two cases:
|
|
|
|
1. An empty string that bash-completion passes to compgen as a quoted null
|
|
string ('').
|
|
|
|
2. An unquoted word that bash-completion quotes using single quotes or
|
|
backslashes before passing it to compgen.
|
|
|
|
In these cases, since readline did not detect a quote character in the original
|
|
word to be completed, bash-4.3
|
|
|
|
--- a/externs.h
|
|
+++ b/externs.h
|
|
@@ -324,6 +324,7 @@ extern char *sh_un_double_quote __P((cha
|
|
extern char *sh_backslash_quote __P((char *, const char *, int));
|
|
extern char *sh_backslash_quote_for_double_quotes __P((char *));
|
|
extern int sh_contains_shell_metas __P((char *));
|
|
+extern int sh_contains_quotes __P((char *));
|
|
|
|
/* declarations for functions defined in lib/sh/spell.c */
|
|
extern int spname __P((char *, char *));
|
|
--- a/lib/sh/shquote.c
|
|
+++ b/lib/sh/shquote.c
|
|
@@ -311,3 +311,17 @@ sh_contains_shell_metas (string)
|
|
|
|
return (0);
|
|
}
|
|
+
|
|
+int
|
|
+sh_contains_quotes (string)
|
|
+ char *string;
|
|
+{
|
|
+ char *s;
|
|
+
|
|
+ for (s = string; s && *s; s++)
|
|
+ {
|
|
+ if (*s == '\'' || *s == '"' || *s == '\\')
|
|
+ return 1;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
--- a/pcomplete.c
|
|
+++ b/pcomplete.c
|
|
@@ -183,6 +183,7 @@ ITEMLIST it_variables = { LIST_DYNAMIC,
|
|
|
|
COMPSPEC *pcomp_curcs;
|
|
const char *pcomp_curcmd;
|
|
+const char *pcomp_curtxt;
|
|
|
|
#ifdef DEBUG
|
|
/* Debugging code */
|
|
@@ -753,6 +754,32 @@ pcomp_filename_completion_function (text
|
|
quoted strings. */
|
|
dfn = (*rl_filename_dequoting_function) ((char *)text, rl_completion_quote_character);
|
|
}
|
|
+ /* Intended to solve a mismatched assumption by bash-completion. If
|
|
+ the text to be completed is empty, but bash-completion turns it into
|
|
+ a quoted string ('') assuming that this code will dequote it before
|
|
+ calling readline, do the dequoting. */
|
|
+ else if (iscompgen && iscompleting &&
|
|
+ pcomp_curtxt && *pcomp_curtxt == 0 &&
|
|
+ text && (*text == '\'' || *text == '"') && text[1] == text[0] && text[2] == 0 &&
|
|
+ rl_filename_dequoting_function)
|
|
+ dfn = (*rl_filename_dequoting_function) ((char *)text, rl_completion_quote_character);
|
|
+ /* Another mismatched assumption by bash-completion. If compgen is being
|
|
+ run as part of bash-completion, and the argument to compgen is not
|
|
+ the same as the word originally passed to the programmable completion
|
|
+ code, dequote the argument if it has quote characters. It's an
|
|
+ attempt to detect when bash-completion is quoting its filename
|
|
+ argument before calling compgen. */
|
|
+ /* We could check whether gen_shell_function_matches is in the call
|
|
+ stack by checking whether the gen-shell-function-matches tag is in
|
|
+ the unwind-protect stack, but there's no function to do that yet.
|
|
+ We could simply check whether we're executing in a function by
|
|
+ checking variable_context, and may end up doing that. */
|
|
+ else if (iscompgen && iscompleting && rl_filename_dequoting_function &&
|
|
+ pcomp_curtxt && text &&
|
|
+ STREQ (pcomp_curtxt, text) == 0 &&
|
|
+ variable_context &&
|
|
+ sh_contains_quotes (text)) /* guess */
|
|
+ dfn = (*rl_filename_dequoting_function) ((char *)text, rl_completion_quote_character);
|
|
else
|
|
dfn = savestring (text);
|
|
}
|
|
@@ -1522,7 +1549,7 @@ gen_progcomp_completions (ocmd, cmd, wor
|
|
COMPSPEC **lastcs;
|
|
{
|
|
COMPSPEC *cs, *oldcs;
|
|
- const char *oldcmd;
|
|
+ const char *oldcmd, *oldtxt;
|
|
STRINGLIST *ret;
|
|
|
|
cs = progcomp_search (ocmd);
|
|
@@ -1545,14 +1572,17 @@ gen_progcomp_completions (ocmd, cmd, wor
|
|
|
|
oldcs = pcomp_curcs;
|
|
oldcmd = pcomp_curcmd;
|
|
+ oldtxt = pcomp_curtxt;
|
|
|
|
pcomp_curcs = cs;
|
|
pcomp_curcmd = cmd;
|
|
+ pcomp_curtxt = word;
|
|
|
|
ret = gen_compspec_completions (cs, cmd, word, start, end, foundp);
|
|
|
|
pcomp_curcs = oldcs;
|
|
pcomp_curcmd = oldcmd;
|
|
+ pcomp_curtxt = oldtxt;
|
|
|
|
/* We need to conditionally handle setting *retryp here */
|
|
if (retryp)
|
|
--- a/patchlevel.h
|
|
+++ b/patchlevel.h
|
|
@@ -25,6 +25,6 @@
|
|
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
|
|
looks for to find the patch level (for the sccs version string). */
|
|
|
|
-#define PATCHLEVEL 9
|
|
+#define PATCHLEVEL 10
|
|
|
|
#endif /* _PATCHLEVEL_H_ */
|