Module Name:    src
Committed By:   snj
Date:           Tue Apr 14 05:30:24 UTC 2015

Modified Files:
        src/lib/libedit [netbsd-7]: chartype.c chartype.h

Log Message:
Pull up following revision(s) (requested by christos in ticket #679):
        lib/libedit/chartype.c: revisions 1.11, 1.12
        lib/libedit/chartype.h: revisions 1.12, 1.13
PR/49683: Amir Plivatsky: Off-by-one comparison in ct_decode_string() leading
to out of bounds referrence.
--
split the allocation functions, their mixed usage was too confusing.


To generate a diff of this commit:
cvs rdiff -u -r1.10 -r1.10.20.1 src/lib/libedit/chartype.c
cvs rdiff -u -r1.10 -r1.10.18.1 src/lib/libedit/chartype.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libedit/chartype.c
diff -u src/lib/libedit/chartype.c:1.10 src/lib/libedit/chartype.c:1.10.20.1
--- src/lib/libedit/chartype.c:1.10	Tue Aug 16 16:25:15 2011
+++ src/lib/libedit/chartype.c	Tue Apr 14 05:30:24 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: chartype.c,v 1.10 2011/08/16 16:25:15 christos Exp $	*/
+/*	$NetBSD: chartype.c,v 1.10.20.1 2015/04/14 05:30:24 snj Exp $	*/
 
 /*-
  * Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@
  */
 #include "config.h"
 #if !defined(lint) && !defined(SCCSID)
-__RCSID("$NetBSD: chartype.c,v 1.10 2011/08/16 16:25:15 christos Exp $");
+__RCSID("$NetBSD: chartype.c,v 1.10.20.1 2015/04/14 05:30:24 snj Exp $");
 #endif /* not lint && not SCCSID */
 #include "el.h"
 #include <stdlib.h>
@@ -46,31 +46,46 @@ __RCSID("$NetBSD: chartype.c,v 1.10 2011
 #define CT_BUFSIZ ((size_t)1024)
 
 #ifdef WIDECHAR
-protected void
-ct_conv_buff_resize(ct_buffer_t *conv, size_t mincsize, size_t minwsize)
+protected int
+ct_conv_cbuff_resize(ct_buffer_t *conv, size_t csize)
 {
 	void *p;
-	if (mincsize > conv->csize) {
-		conv->csize = mincsize;
-		p = el_realloc(conv->cbuff, conv->csize * sizeof(*conv->cbuff));
-		if (p == NULL) {
-			conv->csize = 0;
-			el_free(conv->cbuff);
-			conv->cbuff = NULL;
-		} else 
-			conv->cbuff = p;
+
+	if (csize <= conv->csize)
+		return 0;
+
+	conv->csize = csize;
+
+	p = el_realloc(conv->cbuff, conv->csize * sizeof(*conv->cbuff));
+	if (p == NULL) {
+		conv->csize = 0;
+		el_free(conv->cbuff);
+		conv->cbuff = NULL;
+		return -1;
 	}
+	conv->cbuff = p;
+	return 0;
+}
 
-	if (minwsize > conv->wsize) {
-		conv->wsize = minwsize;
-		p = el_realloc(conv->wbuff, conv->wsize * sizeof(*conv->wbuff));
-		if (p == NULL) {
-			conv->wsize = 0;
-			el_free(conv->wbuff);
-			conv->wbuff = NULL;
-		} else
-			conv->wbuff = p;
+protected int
+ct_conv_wbuff_resize(ct_buffer_t *conv, size_t wsize)
+{
+	void *p;
+
+	if (wsize <= conv->wsize) 
+		return 0;
+
+	conv->wsize = wsize;
+
+	p = el_realloc(conv->wbuff, conv->wsize * sizeof(*conv->wbuff));
+	if (p == NULL) {
+		conv->wsize = 0;
+		el_free(conv->wbuff);
+		conv->wbuff = NULL;
+		return -1;
 	}
+	conv->wbuff = p;
+	return 0;
 }
 
 
@@ -78,26 +93,22 @@ public char *
 ct_encode_string(const Char *s, ct_buffer_t *conv)
 {
 	char *dst;
-	ssize_t used = 0;
+	ssize_t used;
 
 	if (!s)
 		return NULL;
-	if (!conv->cbuff)
-		ct_conv_buff_resize(conv, CT_BUFSIZ, (size_t)0);
-	if (!conv->cbuff)
-		return NULL;
 
 	dst = conv->cbuff;
-	while (*s) {
-		used = (ssize_t)(conv->csize - (size_t)(dst - conv->cbuff));
-		if (used < 5) {
-			used = dst - conv->cbuff;
-			ct_conv_buff_resize(conv, conv->csize + CT_BUFSIZ,
-			    (size_t)0);
-			if (!conv->cbuff)
+	for (;;) {
+		used = (ssize_t)(dst - conv->cbuff);
+		if ((conv->csize - (size_t)used) < 5) {
+			if (ct_conv_cbuff_resize(conv,
+			    conv->csize + CT_BUFSIZ) == -1)
 				return NULL;
 			dst = conv->cbuff + used;
 		}
+		if (!*s)
+			break;
 		used = ct_encode_char(dst, (size_t)5, *s);
 		if (used == -1) /* failed to encode, need more buffer space */
 			abort();
@@ -111,22 +122,19 @@ ct_encode_string(const Char *s, ct_buffe
 public Char *
 ct_decode_string(const char *s, ct_buffer_t *conv)
 {
-	size_t len = 0;
+	size_t len;
 
 	if (!s)
 		return NULL;
-	if (!conv->wbuff)
-		ct_conv_buff_resize(conv, (size_t)0, CT_BUFSIZ);
-	if (!conv->wbuff)
-		return NULL;
 
 	len = ct_mbstowcs(NULL, s, (size_t)0);
 	if (len == (size_t)-1)
 		return NULL;
-	if (len > conv->wsize)
-		ct_conv_buff_resize(conv, (size_t)0, len + 1);
-	if (!conv->wbuff)
-		return NULL;
+
+	if (conv->wsize < ++len)
+		if (ct_conv_wbuff_resize(conv, len + CT_BUFSIZ) == -1)
+			return NULL;
+
 	ct_mbstowcs(conv->wbuff, s, conv->wsize);
 	return conv->wbuff;
 }
@@ -145,9 +153,9 @@ ct_decode_argv(int argc, const char *arg
 	 * the argv strings. */
 	for (i = 0, bufspace = 0; i < argc; ++i)
 		bufspace += argv[i] ? strlen(argv[i]) + 1 : 0;
-	ct_conv_buff_resize(conv, (size_t)0, bufspace);
-	if (!conv->wsize)
-		return NULL;
+	if (conv->wsize < ++bufspace)
+		if (ct_conv_wbuff_resize(conv, bufspace + CT_BUFSIZ) == -1)
+			return NULL;
 
 	wargv = el_malloc((size_t)argc * sizeof(*wargv));
 

Index: src/lib/libedit/chartype.h
diff -u src/lib/libedit/chartype.h:1.10 src/lib/libedit/chartype.h:1.10.18.1
--- src/lib/libedit/chartype.h:1.10	Wed Nov 16 01:45:10 2011
+++ src/lib/libedit/chartype.h	Tue Apr 14 05:30:24 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: chartype.h,v 1.10 2011/11/16 01:45:10 christos Exp $	*/
+/*	$NetBSD: chartype.h,v 1.10.18.1 2015/04/14 05:30:24 snj Exp $	*/
 
 /*-
  * Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -189,7 +189,8 @@ public Char *ct_decode_string(const char
 protected Char **ct_decode_argv(int, const char *[],  ct_buffer_t *);
 
 /* Resizes the conversion buffer(s) if needed. */
-protected void ct_conv_buff_resize(ct_buffer_t *, size_t, size_t);
+protected int ct_conv_cbuff_resize(ct_buffer_t *, size_t);
+protected int ct_conv_wbuff_resize(ct_buffer_t *, size_t);
 protected ssize_t ct_encode_char(char *, size_t, Char);
 protected size_t ct_enc_width(Char);
 
@@ -199,7 +200,8 @@ protected size_t ct_enc_width(Char);
 #define	ct_encode_string(s, b)	(s)
 #define ct_decode_string(s, b)	(s)
 #define ct_decode_argv(l, s, b)	(s)
-#define ct_conv_buff_resize(b, os, ns)
+#define ct_conv_cbuff_resize(b, s) ((s) == (0))
+#define ct_conv_wbuff_resize(b, s) ((s) == (0))
 #define ct_encode_char(d, l, s)	(*d = s, 1)
 #define ct_free_argv(s)
 #endif

Reply via email to