mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-06-11 19:18:01 +02:00
52202: improve handling of quoting in ${var/pattern/replacement}
This commit is contained in:
parent
be223aedee
commit
e6ad117ccb
4 changed files with 49 additions and 25 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
2023-11-15 Bart Schaefer <schaefer@zsh.org>
|
||||||
|
|
||||||
|
* 52202: Src/lex.c, Src/subst.c, Test/D04parameter.ztst: improve
|
||||||
|
handling of quoting in ${var/pattern/replacement}. Still not
|
||||||
|
perfect, e.g., deeply nested expansions in the pattern may fail.
|
||||||
|
|
||||||
2023-11-14 Oliver Kiddle <opk@zsh.org>
|
2023-11-14 Oliver Kiddle <opk@zsh.org>
|
||||||
|
|
||||||
* github #106: Matt Koscica: Completion/Unix/Command/_tmux,
|
* github #106: Matt Koscica: Completion/Unix/Command/_tmux,
|
||||||
|
|
53
Src/lex.c
53
Src/lex.c
|
@ -938,7 +938,7 @@ gettokstr(int c, int sub)
|
||||||
{
|
{
|
||||||
int bct = 0, pct = 0, brct = 0, seen_brct = 0, fdpar = 0;
|
int bct = 0, pct = 0, brct = 0, seen_brct = 0, fdpar = 0;
|
||||||
int intpos = 1, in_brace_param = 0, cmdsubst = 0;
|
int intpos = 1, in_brace_param = 0, cmdsubst = 0;
|
||||||
int inquote, unmatched = 0;
|
int inquote, unmatched = 0, in_pattern = 0;
|
||||||
enum lextok peek;
|
enum lextok peek;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
int ocmdsp = cmdsp;
|
int ocmdsp = cmdsp;
|
||||||
|
@ -1160,7 +1160,7 @@ gettokstr(int c, int sub)
|
||||||
if (bct-- == in_brace_param) {
|
if (bct-- == in_brace_param) {
|
||||||
if (cmdsubst)
|
if (cmdsubst)
|
||||||
cmdpop();
|
cmdpop();
|
||||||
in_brace_param = cmdsubst = 0;
|
in_brace_param = cmdsubst = in_pattern = 0;
|
||||||
}
|
}
|
||||||
c = Outbrace;
|
c = Outbrace;
|
||||||
break;
|
break;
|
||||||
|
@ -1309,7 +1309,8 @@ gettokstr(int c, int sub)
|
||||||
lexbuf.ptr--, lexbuf.len--;
|
lexbuf.ptr--, lexbuf.len--;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
} else if (in_pattern && c == '/')
|
||||||
|
add(Bnull);
|
||||||
add(c);
|
add(c);
|
||||||
}
|
}
|
||||||
ALLOWHIST
|
ALLOWHIST
|
||||||
|
@ -1397,26 +1398,36 @@ gettokstr(int c, int sub)
|
||||||
*/
|
*/
|
||||||
c = Dash;
|
c = Dash;
|
||||||
break;
|
break;
|
||||||
case LX2_BANG:
|
case LX2_BANG:
|
||||||
/*
|
/*
|
||||||
* Same logic as Dash, for ! to perform negation in range.
|
* Same logic as Dash, for ! to perform negation in range.
|
||||||
*/
|
*/
|
||||||
if (seen_brct)
|
if (seen_brct)
|
||||||
c = Bang;
|
c = Bang;
|
||||||
else
|
else
|
||||||
c = '!';
|
c = '!';
|
||||||
}
|
case LX2_OTHER:
|
||||||
add(c);
|
if (in_brace_param) {
|
||||||
c = hgetc();
|
if (c == '/') {
|
||||||
if (intpos)
|
if (in_pattern == 0)
|
||||||
|
in_pattern = 2;
|
||||||
|
else
|
||||||
|
--in_pattern;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
add(c);
|
||||||
|
c = hgetc();
|
||||||
|
if (intpos)
|
||||||
intpos--;
|
intpos--;
|
||||||
if (lexstop)
|
if (lexstop)
|
||||||
break;
|
break;
|
||||||
if (!cmdsubst && in_brace_param && act == LX2_STRING &&
|
if (!cmdsubst && in_brace_param && act == LX2_STRING &&
|
||||||
(c == '|' || c == Bar || inblank(c))) {
|
(c == '|' || c == Bar || inblank(c))) {
|
||||||
cmdsubst = in_brace_param;
|
cmdsubst = in_brace_param;
|
||||||
cmdpush(CS_CURSH);
|
cmdpush(CS_CURSH);
|
||||||
}
|
} else if (in_pattern == 2 && c != '/')
|
||||||
|
in_pattern = 1;
|
||||||
}
|
}
|
||||||
brk:
|
brk:
|
||||||
if (errflag) {
|
if (errflag) {
|
||||||
|
|
|
@ -3088,6 +3088,13 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
|
||||||
chuck(ptr);
|
chuck(ptr);
|
||||||
else
|
else
|
||||||
ptr++;
|
ptr++;
|
||||||
|
} else if (c == Dnull) {
|
||||||
|
chuck(ptr);
|
||||||
|
while (*ptr && *ptr != c)
|
||||||
|
ptr++;
|
||||||
|
if (*ptr == Dnull)
|
||||||
|
chuck(ptr);
|
||||||
|
ptr--; /* Outer loop is about to increment */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
replstr = (*ptr && ptr[1]) ? ptr+1 : "";
|
replstr = (*ptr && ptr[1]) ? ptr+1 : "";
|
||||||
|
|
|
@ -2762,13 +2762,13 @@ F:behavior, see http://austingroupbugs.net/view.php?id=888
|
||||||
|
|
||||||
slash='/'
|
slash='/'
|
||||||
print -r -- x${slash/'/'}y
|
print -r -- x${slash/'/'}y
|
||||||
-Df:(users/28784) substituting a single-quoted backslash, part #1: slash
|
0:(users/28784) substituting a single-quoted backslash, part #1: slash
|
||||||
>xy
|
>xy
|
||||||
|
|
||||||
single_quote="'"
|
single_quote="'"
|
||||||
print -r -- x${single_quote/'/'}y
|
print -r -- x${single_quote/$'/'}y
|
||||||
-Df:(users/28784) substituting a single-quoted backslash, part #2: single quote
|
0:(users/28784) substituting a single-quoted backslash, part #2: single quote
|
||||||
>x/y
|
>x'y
|
||||||
|
|
||||||
control="foobar"
|
control="foobar"
|
||||||
print -r -- x${control/'bar'}y
|
print -r -- x${control/'bar'}y
|
||||||
|
|
Loading…
Reference in a new issue