about summary refs log tree commit diff
path: root/Src
diff options
context:
space:
mode:
Diffstat (limited to 'Src')
-rw-r--r--Src/glob.c2
-rw-r--r--Src/subst.c31
2 files changed, 22 insertions, 11 deletions
diff --git a/Src/glob.c b/Src/glob.c
index 394e91d01..aa0ce1ac4 100644
--- a/Src/glob.c
+++ b/Src/glob.c
@@ -1246,7 +1246,7 @@ zglob(LinkList list, LinkNode np, int nountok)
 			int arglen;
 
 			/* Find matching delimiters */
-			tt = get_strarg(s, &arglen);
+			tt = get_strarg(s, &arglen, NULL);
 			if (!*tt) {
 			    zerr("missing end of name");
 			    data = 0;
diff --git a/Src/subst.c b/Src/subst.c
index 3a5b9b353..06e16c183 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -1224,8 +1224,9 @@ get_strarg(char *s, int *lenp)
 
 /*
  * Get an integer argument; update *s to the end of the
- * final delimiter.  *delmatchp is set to 1 if we have matching
- * delimiters and there was no error in the evaluation, else 0.
+ * final delimiter.  *delmatchp is set to the length of the
+ * matched delimiter if we have matching, delimiters and there was no error in
+ * the evaluation, else 0.
  */
 
 /**/
@@ -1255,7 +1256,7 @@ get_intarg(char **s, int *delmatchp)
 	return -1;
     if (ret < 0)
 	ret = -ret;
-    *delmatchp = 1;
+    *delmatchp = arglen;
     return ret < 0 ? -ret : ret;
 }
 
@@ -1602,7 +1603,8 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
 
 	    for (s++; (c = *s) != ')' && c != Outpar; s++, tt = 0) {
 		int arglen;	/* length of modifier argument */
-		int delmatch;	/* integer delimiters matched OK */
+		int dellen;	/* length of matched delimiter, 0 if not */
+		char *del0;	/* pointer to initial delimiter */
 
 		switch (c) {
 		case ')':
@@ -1634,7 +1636,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
 		    break;
 		case 'I':
 		    s++;
-		    flnum = get_intarg(&s, &delmatch);
+		    flnum = get_intarg(&s, &dellen);
 		    if (flnum < 0)
 			goto flagerr;
 		    s--;
@@ -1734,15 +1736,21 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
 		/* fall through */
 		case 'r':
 		    s++;
-		    num = get_intarg(&s, &delmatch);
+		    /* delimiter position */
+		    del0 = s;
+		    num = get_intarg(&s, &dellen);
 		    if (num < 0)
 			goto flagerr;
 		    if (tt)
 			prenum = num;
 		    else
 			postnum = num;
-		    if (!delmatch)
+		    /* must have same delimiter if more arguments */
+		    if (!dellen || memcmp(del0, s, dellen)) {
+			/* decrement since loop will increment */
+			s--;
 			break;
+		    }
 		    t = get_strarg(s, &arglen);
 		    if (!*t)
 			goto flagerr;
@@ -1755,7 +1763,9 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
 		    *t = sav;
 		    sav = *s;
 		    s = t + arglen;
-		    if (UNTOK(*s) != UNTOK(sav)) {
+		    /* again, continue only if another start delimiter */
+		    if (memcmp(del0, s, dellen)) {
+			/* decrement since loop will increment */
 			s--;
 			break;
 		    }
@@ -1769,6 +1779,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
 		    else
 			UNTOK_AND_ESCAPE(postone, s + arglen)
 		    *t = sav;
+		    /* -1 since loop will increment */
 		    s = t + arglen - 1;
 		    break;
 
@@ -3310,7 +3321,7 @@ modify(char **str, char **ptr)
 {
     char *ptr1, *ptr2, *ptr3, *lptr, c, *test, *sep, *t, *tt, tc, *e;
     char *copy, *all, *tmp, sav, sav1, *ptr1end;
-    int gbal, wall, rec, al, nl, charlen, delmatch;
+    int gbal, wall, rec, al, nl, charlen, dellen;
     convchar_t del;
 
     test = NULL;
@@ -3436,7 +3447,7 @@ modify(char **str, char **ptr)
 		break;
 	    case 'F':
 		(*ptr)++;
-		rec = get_intarg(ptr, &delmatch);
+		rec = get_intarg(ptr, &dellen);
 		break;
 	    default:
 		*ptr = lptr;