diff mbox series

expand: Fix scanleft/right for !FNMATCH_IS_ENABLED && quotes

Message ID ZzlT_1CY5AjxtqAs@gondor.apana.org.au (mailing list archive)
State Under Review
Delegated to: Herbert Xu
Headers show
Series expand: Fix scanleft/right for !FNMATCH_IS_ENABLED && quotes | expand

Commit Message

Herbert Xu Nov. 17, 2024, 2:25 a.m. UTC
Johannes Altmanninger <aclopte@gmail.com> wrote:
> I'm hitting an easily reproducible crash.
> It bisects to c5bf970 (expand: Add multi-byte support to pmatch, 2024-06-02).
> 
> After bisecting I reduced it to this example (probably not minimal)
> 
>        echo \\ | dash -c 'foo=$(cat; printf .); foo=${foo%.}'

Thanks for the report.  This patch should fix the problem:

---8<---
When our own pmatch is used, loc2 is unused in scanleft/right
when quotes is true.  However, it is still needed when quotes
is false.

Fix the scanleft/right code so that loc2 is always updated (so
it will be garbage when quotes is true) but only returned depending
on the value of quotes.

Fixes: c5bf9702ea11 ("expand: Add multi-byte support to pmatch")
Reported-by: Johannes Altmanninger <aclopte@gmail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Comments

Johannes Altmanninger Nov. 17, 2024, 6:55 a.m. UTC | #1
On Sun, Nov 17, 2024 at 10:25:03AM +0800, Herbert Xu wrote:
> Johannes Altmanninger <aclopte@gmail.com> wrote:
> > I'm hitting an easily reproducible crash.
> > It bisects to c5bf970 (expand: Add multi-byte support to pmatch, 2024-06-02).
> > 
> > After bisecting I reduced it to this example (probably not minimal)
> > 
> >        echo \\ | dash -c 'foo=$(cat; printf .); foo=${foo%.}'
> 
> Thanks for the report.  This patch should fix the problem:

thanks this works for me. I've been using master for the trap fix.
diff mbox series

Patch

diff --git a/src/expand.c b/src/expand.c
index d73f29c..7a30648 100644
--- a/src/expand.c
+++ b/src/expand.c
@@ -621,18 +621,15 @@  static char *scanleft(char *startp, char *endp, char *rmesc, char *rmescend,
 		match = pmatch(str, s);
 		*(FNMATCH_IS_ENABLED ? loc2 : loc) = c;
 		if (match)
-			return FNMATCH_IS_ENABLED && quotes ? loc : loc2;
+			return quotes ? loc : loc2;
 
 		if (!c)
 			break;
 
 		mb = mbnext(loc);
 		loc += (mb & 0xff) + (mb >> 8);
-		if (unlikely(FNMATCH_IS_ENABLED || !quotes)) {
-			ml = (mb >> 8) > 3 ? (mb >> 8) - 2 : 1;
-			loc2 += ml;
-		} else
-			loc2 = loc;
+		ml = (mb >> 8) > 3 ? (mb >> 8) - 2 : 1;
+		loc2 += ml;
 	} while (1);
 	return 0;
 }
@@ -645,8 +642,7 @@  static char *scanright(char *startp, char *endp, char *rmesc, char *rmescend,
 	char *loc;
 	char *loc2;
 
-	for (loc = endp, loc2 = rmescend;;
-	     FNMATCH_IS_ENABLED ? loc2-- : (loc2 = loc)) {
+	for (loc = endp, loc2 = rmescend;; loc2--) {
 		char *s = FNMATCH_IS_ENABLED ? loc2 : loc;
 		char c = *s;
 		unsigned ml;
@@ -659,7 +655,7 @@  static char *scanright(char *startp, char *endp, char *rmesc, char *rmescend,
 		match = pmatch(str, s);
 		*(FNMATCH_IS_ENABLED ? loc2 : loc) = c;
 		if (match)
-			return FNMATCH_IS_ENABLED && quotes ? loc : loc2;
+			return quotes ? loc : loc2;
 		if (--loc < startp)
 			break;
 		if (!esc--)
@@ -676,8 +672,7 @@  static char *scanright(char *startp, char *endp, char *rmesc, char *rmescend,
 		loc -= ml + 2;
 		if (*loc == (char)CTLESC)
 			loc--;
-		if (FNMATCH_IS_ENABLED)
-			loc2 -= ml - 1;
+		loc2 -= ml - 1;
 	}
 	return 0;
 }