From d07bacd44ab6b659ed3c51804f2a7c36e70bca56 Mon Sep 17 00:00:00 2001 From: tg Date: Thu, 17 Mar 2011 21:57:50 +0000 Subject: [PATCH] =?UTF-8?q?=E2=80=A2=20fix=20check=20for=20empty=20pattern?= =?UTF-8?q?=20in=20${foo/bar/baz}=20expansion:=20the=20=20=20character=20a?= =?UTF-8?q?nchoring=20the=20pattern=20(=E2=80=98#=E2=80=99=20or=20?= =?UTF-8?q?=E2=80=98%=E2=80=99)=20must=20be=20skipped=20=20=20if=20one=20w?= =?UTF-8?q?as=20used;=20fixes=20=E2=80=9CBLA=3D"#test";=20echo=20"${BLA//#?= =?UTF-8?q?/}"=E2=80=9D=20busy=20=20=20looping=20(due=20to=20null=20patter?= =?UTF-8?q?n)=20found=20by=20Jb=5Fboin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- eval.c | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/eval.c b/eval.c index a43ae7c..c7bbbaf 100644 --- a/eval.c +++ b/eval.c @@ -22,7 +22,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.101 2011/03/16 20:31:33 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.102 2011/03/17 21:57:50 tg Exp $"); /* * string expansion @@ -464,12 +464,44 @@ expand(const char *cp, /* input word */ *d = '\0'; afree(tpat0, ATEMP); - /* reject empty pattern */ - if (!*pat || gmatchx("", pat, false)) + /* check for special cases */ + d = str_val(st->var); + switch (*pat) { + case '#': + /* anchor at begin */ + tpat0 = pat + 1; + tpat1 = rrep; + tpat2 = d; + break; + case '%': + /* anchor at end */ + tpat0 = pat + 1; + tpat1 = d; + tpat2 = rrep; + break; + case '\0': + /* empty pattern */ goto no_repl; + default: + tpat0 = pat; + /* silence gcc */ + tpat1 = tpat2 = NULL; + } + if (gmatchx(null, tpat0, false)) { + /* + * pattern matches + * the empty string + */ + if (tpat0 == pat) + goto no_repl; + /* but is anchored */ + s = shf_smprintf("%s%s", + tpat1, tpat2); + goto do_repl; + } /* prepare string on which to work */ - strdupx(s, str_val(st->var), ATEMP); + strdupx(s, d, ATEMP); sbeg = s; /* first see if we have any match at all */ @@ -527,6 +559,7 @@ expand(const char *cp, /* input word */ goto again_repl; end_repl: afree(tpat1, ATEMP); + do_repl: x.str = s; no_repl: afree(pat, ATEMP);