diff options
author | Bart Schaefer <schaefer@zsh.org> | 2023-11-15 20:16:04 -0800 |
---|---|---|
committer | Bart Schaefer <schaefer@zsh.org> | 2023-11-15 20:16:04 -0800 |
commit | e6ad117ccb548c8411610571c92fa4094f275460 (patch) | |
tree | 81ea94a83fd4d1dfdc20d19da322ccd767eaf709 /Src | |
parent | be223aedee772fc31e12ec8c5277f50aae25b0fe (diff) | |
download | zsh-e6ad117ccb548c8411610571c92fa4094f275460.tar.gz zsh-e6ad117ccb548c8411610571c92fa4094f275460.tar.xz zsh-e6ad117ccb548c8411610571c92fa4094f275460.zip |
52202: improve handling of quoting in ${var/pattern/replacement}
Diffstat (limited to 'Src')
-rw-r--r-- | Src/lex.c | 53 | ||||
-rw-r--r-- | Src/subst.c | 7 |
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 : ""; |