1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-05-22 00:11:30 +02:00

52202: improve handling of quoting in ${var/pattern/replacement}

This commit is contained in:
Bart Schaefer 2023-11-15 20:16:04 -08:00
parent be223aedee
commit e6ad117ccb
4 changed files with 49 additions and 25 deletions

View file

@ -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>
* github #106: Matt Koscica: Completion/Unix/Command/_tmux,

View file

@ -938,7 +938,7 @@ gettokstr(int c, int sub)
{
int bct = 0, pct = 0, brct = 0, seen_brct = 0, fdpar = 0;
int intpos = 1, in_brace_param = 0, cmdsubst = 0;
int inquote, unmatched = 0;
int inquote, unmatched = 0, in_pattern = 0;
enum lextok peek;
#ifdef DEBUG
int ocmdsp = cmdsp;
@ -1160,7 +1160,7 @@ gettokstr(int c, int sub)
if (bct-- == in_brace_param) {
if (cmdsubst)
cmdpop();
in_brace_param = cmdsubst = 0;
in_brace_param = cmdsubst = in_pattern = 0;
}
c = Outbrace;
break;
@ -1309,7 +1309,8 @@ gettokstr(int c, int sub)
lexbuf.ptr--, lexbuf.len--;
else
break;
}
} else if (in_pattern && c == '/')
add(Bnull);
add(c);
}
ALLOWHIST
@ -1397,26 +1398,36 @@ gettokstr(int c, int sub)
*/
c = Dash;
break;
case LX2_BANG:
/*
* Same logic as Dash, for ! to perform negation in range.
*/
if (seen_brct)
c = Bang;
else
c = '!';
}
add(c);
c = hgetc();
if (intpos)
case LX2_BANG:
/*
* Same logic as Dash, for ! to perform negation in range.
*/
if (seen_brct)
c = Bang;
else
c = '!';
case LX2_OTHER:
if (in_brace_param) {
if (c == '/') {
if (in_pattern == 0)
in_pattern = 2;
else
--in_pattern;
}
}
}
add(c);
c = hgetc();
if (intpos)
intpos--;
if (lexstop)
if (lexstop)
break;
if (!cmdsubst && in_brace_param && act == LX2_STRING &&
(c == '|' || c == Bar || inblank(c))) {
cmdsubst = in_brace_param;
cmdpush(CS_CURSH);
}
if (!cmdsubst && in_brace_param && act == LX2_STRING &&
(c == '|' || c == Bar || inblank(c))) {
cmdsubst = in_brace_param;
cmdpush(CS_CURSH);
} else if (in_pattern == 2 && c != '/')
in_pattern = 1;
}
brk:
if (errflag) {

View file

@ -3088,6 +3088,13 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
chuck(ptr);
else
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 : "";

View file

@ -2762,13 +2762,13 @@ F:behavior, see http://austingroupbugs.net/view.php?id=888
slash='/'
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
single_quote="'"
print -r -- x${single_quote/'/'}y
-Df:(users/28784) substituting a single-quoted backslash, part #2: single quote
>x/y
print -r -- x${single_quote/$'/'}y
0:(users/28784) substituting a single-quoted backslash, part #2: single quote
>x'y
control="foobar"
print -r -- x${control/'bar'}y