summary refs log tree commit diff
diff options
context:
space:
mode:
authorBart Schaefer <schaefer@ipost.com>2022-04-04 09:14:59 -0700
committerBart Schaefer <schaefer@ipost.com>2022-04-04 09:14:59 -0700
commitc77cdb27db1c85b1842922a0b2cc4344478dd56b (patch)
tree6256d72c0e8f8aa54ea9adbafe4271f2a6006956
parent29f97c1f9447335c8f088f1cf809d90004e78053 (diff)
downloadzsh-c77cdb27db1c85b1842922a0b2cc4344478dd56b.tar.gz
zsh-c77cdb27db1c85b1842922a0b2cc4344478dd56b.tar.xz
zsh-c77cdb27db1c85b1842922a0b2cc4344478dd56b.zip
49955: Src/glob.c: fix bad free in incremental-pattern-search matching
-rw-r--r--ChangeLog6
-rw-r--r--Src/Zle/zle_refresh.c2
-rw-r--r--Src/glob.c13
3 files changed, 18 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index cde6bfc2d..11ebb7d66 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2022-04-03  Bart Schaefer  <schaefer@zsh.org>
+
+	* 49955 (with thanks to Madhu <enometh@meer.net>): Src/glob.c:
+	fix bad free in incremental-pattern-search matching (observed
+	only when compiled without MULTIBYTE support)
+
 2022-04-03  Mikael Magnusson  <mikachu@gmail.com>
 
 	* 49959: Completion/Zsh/Context/_brace_parameter:
diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c
index d9d9503e2..c8c6f78c6 100644
--- a/Src/Zle/zle_refresh.c
+++ b/Src/Zle/zle_refresh.c
@@ -255,7 +255,9 @@ int cost;
 #endif
 
 static const REFRESH_ELEMENT zr_cr = { ZWC('\r'), 0 };
+#ifdef MULTIBYTE_support
 static const REFRESH_ELEMENT zr_dt = { ZWC('.'), 0 };
+#endif
 static const REFRESH_ELEMENT zr_nl = { ZWC('\n'), 0 };
 static const REFRESH_ELEMENT zr_sp = { ZWC(' '), 0 };
 static const REFRESH_ELEMENT zr_zr = { ZWC('\0'), 0 };
diff --git a/Src/glob.c b/Src/glob.c
index 349862531..d4ffc2274 100644
--- a/Src/glob.c
+++ b/Src/glob.c
@@ -3286,6 +3286,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 	return 1;
     }
     if (matched) {
+        /* Default is to match at the start; see comment in MULTIBYTE above */
 	switch (fl & (SUB_END|SUB_LONG|SUB_SUBSTR)) {
 	case 0:
 	case SUB_LONG:
@@ -3355,7 +3356,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 	    /* longest or smallest at start with substrings */
 	    t = s;
 	    if (fl & SUB_GLOBAL) {
-		imd.repllist = newlinklist();
+		imd.repllist = (fl & SUB_LIST) ? znewlinklist() : newlinklist();
 		if (repllistp)
 		    *repllistp = imd.repllist;
 	    }
@@ -3405,6 +3406,8 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 			 * which is already marked for replacement.
 			 */
 			matched = 1;
+			if (t == send)
+			    break;
 			while (t < mpos) {
 			    ioff++;
 			    umlen--;
@@ -3412,8 +3415,10 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 			}
 			break;
 		    }
+		    if (t == send)
+			break;
 		}
-	    } while (matched);
+	    } while (matched && t < send);
 	    /*
 	     * check if we can match a blank string, if so do it
 	     * at the start.  Goodness knows if this is a good idea
@@ -3485,6 +3490,8 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
 	 * Results from get_match_ret in repllist are all metafied.
 	 */
 	s = *sp;
+	if (fl & SUB_LIST)
+	    return 1;
 	i = 0;			/* start of last chunk we got from *sp */
 	for (nd = firstnode(imd.repllist); nd; incnode(nd)) {
 	    rd = (Repldata) getdata(nd);
@@ -3514,7 +3521,7 @@ igetmatch(char **sp, Patprog p, int fl, int n, char *replstr,
     imd.replstr = NULL;
     imd.repllist = NULL;
     *sp = get_match_ret(&imd, 0, 0);
-    return 1;
+    return (fl & SUB_RETFAIL) ? 0 : 1;
 }
 
 /**/