summaryrefslogtreecommitdiff
path: root/Src
diff options
context:
space:
mode:
authorBart Schaefer <schaefer@zsh.org>2023-11-15 20:16:04 -0800
committerBart Schaefer <schaefer@zsh.org>2023-11-15 20:16:04 -0800
commite6ad117ccb548c8411610571c92fa4094f275460 (patch)
tree81ea94a83fd4d1dfdc20d19da322ccd767eaf709 /Src
parentbe223aedee772fc31e12ec8c5277f50aae25b0fe (diff)
downloadzsh-e6ad117ccb548c8411610571c92fa4094f275460.tar.gz
zsh-e6ad117ccb548c8411610571c92fa4094f275460.zip
52202: improve handling of quoting in ${var/pattern/replacement}
Diffstat (limited to 'Src')
-rw-r--r--Src/lex.c53
-rw-r--r--Src/subst.c7
2 files changed, 39 insertions, 21 deletions
diff --git a/Src/lex.c b/Src/lex.c
index 33b17cc95..31b130b07 100644
--- a/Src/lex.c
+++ b/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 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) {
diff --git a/Src/subst.c b/Src/subst.c
index 60d850feb..4ef1d1269 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -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 : "";