PATCH: Fix two edge cases in join_strs

Mikael Magnusson <[email protected]>
Newsgroups gmane.comp.shells.zsh.devel
Message-ID <[email protected]>
int alloclen = (convlen > 20) ? convlen : 20;

This allocates exactly enough room for the bytes returned by
zlelineasstring, but not the nul terminator. However, rr is only ever 0
on the first entry to this function, so it probably won't ever hit this
case by accident.

You *can* trigger it though, if you really want to:
zsh% ls
foo-bar  foo_bar
zsh% autoload compinit; compinit
zsh% zstyle '*' matcher-list 'r:|[_-]=* m:AAAAAAAAAAAAAAAAAAAAAA={-_}'
zsh% foo foo<tab>

==31891== Invalid write of size 1
==31891==    at 0x4873C7F: join_strs (compmatch.c:2098)
==31891==    by 0x4873E47: cmp_anchors (compmatch.c:2131)
==31891==    by 0x487603B: join_clines (compmatch.c:2909)
==31891==    by 0x486CE5F: add_match_data (compcore.c:3003)
==31891==    by 0x486AECE: addmatches (compcore.c:2556)
==31891==    by 0x4860B5B: bin_compadd (complete.c:848)
==31891==  Address 0x7316f46 is 0 bytes after a block of size 22 alloc'd
==31891==    at 0x48396C5: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==31891==    by 0x4873AAA: join_strs (compmatch.c:2055)
==31891==    by 0x4873E47: cmp_anchors (compmatch.c:2131)

The !rp check at the end won't be hit from any of the current callers of
the function, but it makes both me and the static analyzers feel better
if we check it.
---
 Src/Zle/compmatch.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Src/Zle/compmatch.c b/Src/Zle/compmatch.c
index 5b4f60588a..a9e42e698b 100644
--- a/Src/Zle/compmatch.c
+++ b/Src/Zle/compmatch.c
@@ -2046,7 +2046,7 @@ join_strs(int la, char *sa, int lb, char *sb)
 						NULL, 0);
 			    if (rr <= convlen) {
 				ptrdiff_t diff = rp - rs;
-				int alloclen = (convlen > 20) ? convlen : 20;
+				int alloclen = (convlen >= 20) ? convlen + 1 : 20;
 
 				rs = realloc(rs, (rl += alloclen));
 				rr += alloclen;
@@ -2088,7 +2088,7 @@ join_strs(int la, char *sa, int lb, char *sb)
 	    lb--;
 	}
     }
-    if (la || lb)
+    if (la || lb || !rp)
 	return NULL;
 
     *rp = '\0';
-- 
2.38.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.