mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-11-29 03:31:01 +01:00
27479: prevent completions split across backslash-newline
from causing too much mayhem
This commit is contained in:
parent
7bc089c6be
commit
7293565963
2 changed files with 65 additions and 23 deletions
|
|
@ -1,3 +1,9 @@
|
|||
2009-12-07 Peter Stephenson <p.w.stephenson@ntlworld.com>
|
||||
|
||||
* 27479: Src/Zle/zle_tricky.c: prevent completions
|
||||
split across backlash-newline continuations from
|
||||
causing mayhem.
|
||||
|
||||
2009-12-05 Peter Stephenson <p.w.stephenson@ntlworld.com>
|
||||
|
||||
* 27466: Doc/Zsh/zle.yo: document 27453.
|
||||
|
|
@ -12451,5 +12457,5 @@
|
|||
|
||||
*****************************************************
|
||||
* This is used by the shell to define $ZSH_PATCHLEVEL
|
||||
* $Revision: 1.4835 $
|
||||
* $Revision: 1.4836 $
|
||||
*****************************************************
|
||||
|
|
|
|||
|
|
@ -1066,6 +1066,10 @@ get_comp_string(void)
|
|||
{
|
||||
int t0, tt0, i, j, k, cp, rd, sl, ocs, ins, oins, ia, parct, varq = 0;
|
||||
int ona = noaliases;
|
||||
/*
|
||||
* Index of word being considered
|
||||
*/
|
||||
int wordpos;
|
||||
/*
|
||||
* qsub fixes up the offset into the current completion word
|
||||
* for changes made by the lexer. That currently means the
|
||||
|
|
@ -1141,7 +1145,7 @@ get_comp_string(void)
|
|||
lexsave();
|
||||
inpush(dupstrspace(linptr), 0, NULL);
|
||||
strinbeg(0);
|
||||
i = tt0 = cp = rd = ins = oins = linarr = parct = ia = redirpos = 0;
|
||||
wordpos = tt0 = cp = rd = ins = oins = linarr = parct = ia = redirpos = 0;
|
||||
|
||||
/* This loop is possibly the wrong way to do this. It goes through *
|
||||
* the previously massaged command line using the lexer. It stores *
|
||||
|
|
@ -1154,8 +1158,9 @@ get_comp_string(void)
|
|||
do {
|
||||
qsub = 0;
|
||||
|
||||
lincmd = ((incmdpos && !ins && !incond) || (oins == 2 && i == 2) ||
|
||||
(ins == 3 && i == 1));
|
||||
lincmd = ((incmdpos && !ins && !incond) ||
|
||||
(oins == 2 && wordpos == 2) ||
|
||||
(ins == 3 && wordpos == 1));
|
||||
linredir = (inredir && !ins);
|
||||
oins = ins;
|
||||
/* Get the next token. */
|
||||
|
|
@ -1198,7 +1203,7 @@ get_comp_string(void)
|
|||
strcpy(rdop, tokstrings[tok]);
|
||||
strcpy(rdstr, rdop);
|
||||
/* Record if we haven't had the command word yet */
|
||||
if (i == redirpos)
|
||||
if (wordpos == redirpos)
|
||||
redirpos++;
|
||||
}
|
||||
if (tok == DINPAR)
|
||||
|
|
@ -1208,7 +1213,7 @@ get_comp_string(void)
|
|||
if (tok == ENDINPUT)
|
||||
break;
|
||||
if ((ins && (tok == DOLOOP || tok == SEPER)) ||
|
||||
(ins == 2 && i == 2) || (ins == 3 && i == 3) ||
|
||||
(ins == 2 && wordpos == 2) || (ins == 3 && wordpos == 3) ||
|
||||
tok == BAR || tok == AMPER ||
|
||||
tok == BARAMP || tok == AMPERBANG ||
|
||||
((tok == DBAR || tok == DAMPER) && !incond) ||
|
||||
|
|
@ -1226,7 +1231,7 @@ get_comp_string(void)
|
|||
if (tt)
|
||||
break;
|
||||
/* Otherwise reset the variables we are collecting data in. */
|
||||
i = tt0 = cp = rd = ins = redirpos = 0;
|
||||
wordpos = tt0 = cp = rd = ins = redirpos = 0;
|
||||
}
|
||||
if (lincmd && (tok == STRING || tok == FOR || tok == FOREACH ||
|
||||
tok == SELECT || tok == REPEAT || tok == CASE)) {
|
||||
|
|
@ -1236,15 +1241,46 @@ get_comp_string(void)
|
|||
zsfree(cmdstr);
|
||||
cmdstr = ztrdup(tokstr);
|
||||
/* If everything before is a redirection, don't reset the index */
|
||||
if (i != redirpos)
|
||||
i = redirpos = 0;
|
||||
if (wordpos != redirpos)
|
||||
wordpos = redirpos = 0;
|
||||
}
|
||||
if (!zleparse && !tt0) {
|
||||
/* This is done when the lexer reached the word the cursor is on. */
|
||||
tt = tokstr ? dupstring(tokstr) : NULL;
|
||||
|
||||
/*
|
||||
* If there was a proper interface between this
|
||||
* function and the lexical analyser, we wouldn't
|
||||
* have to fix things up.
|
||||
*
|
||||
* Fix up backslash-newline pairs in zlemetaline
|
||||
* that the lexer will have removed. As we're
|
||||
* looking back at the zlemetaline version it's
|
||||
* still using untokenized quotes.
|
||||
*/
|
||||
for (i = j = k = 0, u = zlemetaline + wb;
|
||||
u < zlemetaline + we; u++) {
|
||||
if (*u == '`' && !(k & 1))
|
||||
i++;
|
||||
else if (*u == '\"' && !(k & 1) && !(i & 1))
|
||||
j++;
|
||||
else if (*u == '\'' && !(j & 1))
|
||||
k++;
|
||||
else if (*u == '\\' && u[1] && !(k & 1))
|
||||
{
|
||||
if (u[1] == '\n') {
|
||||
/* Removed by lexer in tt */
|
||||
qsub += 2;
|
||||
}
|
||||
u++;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Fix up RCQUOTES quotes that the
|
||||
* the lexer will also have removed.
|
||||
*/
|
||||
if (isset(RCQUOTES) && tt) {
|
||||
char *tt1, *e = tt + zlemetacs - wb;
|
||||
char *tt1, *e = tt + zlemetacs - wb - qsub;
|
||||
for (tt1 = tt; *tt1; tt1++) {
|
||||
if (*tt1 == Snull) {
|
||||
char *p;
|
||||
|
|
@ -1259,7 +1295,7 @@ get_comp_string(void)
|
|||
chuck(tt + zlemetacs - wb - qsub);
|
||||
tt0 = tok;
|
||||
/* Store the number of this word. */
|
||||
clwpos = i;
|
||||
clwpos = wordpos;
|
||||
cp = lincmd;
|
||||
rd = linredir;
|
||||
ia = linarr;
|
||||
|
|
@ -1279,39 +1315,39 @@ get_comp_string(void)
|
|||
if (!tokstr)
|
||||
continue;
|
||||
/* Hack to allow completion after `repeat n do'. */
|
||||
if (oins == 2 && !i && !strcmp(tokstr, "do"))
|
||||
if (oins == 2 && !wordpos && !strcmp(tokstr, "do"))
|
||||
ins = 3;
|
||||
/* We need to store the token strings of all words (for some of *
|
||||
* the more complicated compctl -x things). They are stored in *
|
||||
* the clwords array. Make this array big enough. */
|
||||
if (i + 1 == clwsize) {
|
||||
if (wordpos + 1 == clwsize) {
|
||||
int n;
|
||||
clwords = (char **)realloc(clwords,
|
||||
(clwsize *= 2) * sizeof(char *));
|
||||
for(n = clwsize; --n > i; )
|
||||
for(n = clwsize; --n > wordpos; )
|
||||
clwords[n] = NULL;
|
||||
}
|
||||
zsfree(clwords[i]);
|
||||
zsfree(clwords[wordpos]);
|
||||
/* And store the current token string. */
|
||||
clwords[i] = ztrdup(tokstr);
|
||||
clwords[wordpos] = ztrdup(tokstr);
|
||||
sl = strlen(tokstr);
|
||||
/* Sometimes the lexer gives us token strings ending with *
|
||||
* spaces we delete the spaces. */
|
||||
while (sl && clwords[i][sl - 1] == ' ' &&
|
||||
(sl < 2 || (clwords[i][sl - 2] != Bnull &&
|
||||
clwords[i][sl - 2] != Meta)))
|
||||
clwords[i][--sl] = '\0';
|
||||
while (sl && clwords[wordpos][sl - 1] == ' ' &&
|
||||
(sl < 2 || (clwords[wordpos][sl - 2] != Bnull &&
|
||||
clwords[wordpos][sl - 2] != Meta)))
|
||||
clwords[wordpos][--sl] = '\0';
|
||||
/* If this is the word the cursor is in and we added a `x', *
|
||||
* remove it. */
|
||||
if (clwpos == i++ && addedx) {
|
||||
if (clwpos == wordpos++ && addedx) {
|
||||
zlemetacs_qsub = zlemetacs - qsub;
|
||||
chuck(&clwords[i - 1][((zlemetacs_qsub - wb) >= sl) ?
|
||||
chuck(&clwords[wordpos - 1][((zlemetacs_qsub - wb) >= sl) ?
|
||||
(sl - 1) : (zlemetacs_qsub - wb)]);
|
||||
}
|
||||
} while (tok != LEXERR && tok != ENDINPUT &&
|
||||
(tok != SEPER || (zleparse && !tt0)));
|
||||
/* Calculate the number of words stored in the clwords array. */
|
||||
clwnum = (tt || !i) ? i : i - 1;
|
||||
clwnum = (tt || !wordpos) ? wordpos : wordpos - 1;
|
||||
zsfree(clwords[clwnum]);
|
||||
clwords[clwnum] = NULL;
|
||||
t0 = tt0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue