Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libedit PR/49683: Amir Plivatsky: Off-by-one comparison ...



details:   https://anonhg.NetBSD.org/src/rev/e5c76cbc2ed7
branches:  trunk
changeset: 336257:e5c76cbc2ed7
user:      christos <christos%NetBSD.org@localhost>
date:      Sun Feb 22 00:46:58 2015 +0000

description:
PR/49683: Amir Plivatsky: Off-by-one comparison in ct_decode_string() leading
to out of bounds referrence.
XXX: pullup-7

diffstat:

 lib/libedit/chartype.c |  51 +++++++++++++++++++++++--------------------------
 lib/libedit/chartype.h |   4 +-
 2 files changed, 26 insertions(+), 29 deletions(-)

diffs (143 lines):

diff -r 3e93523adf62 -r e5c76cbc2ed7 lib/libedit/chartype.c
--- a/lib/libedit/chartype.c    Sat Feb 21 23:13:00 2015 +0000
+++ b/lib/libedit/chartype.c    Sun Feb 22 00:46:58 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: chartype.c,v 1.10 2011/08/16 16:25:15 christos Exp $   */
+/*     $NetBSD: chartype.c,v 1.11 2015/02/22 00:46:58 christos 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.11 2015/02/22 00:46:58 christos Exp $");
 #endif /* not lint && not SCCSID */
 #include "el.h"
 #include <stdlib.h>
@@ -46,7 +46,7 @@
 #define CT_BUFSIZ ((size_t)1024)
 
 #ifdef WIDECHAR
-protected void
+protected int
 ct_conv_buff_resize(ct_buffer_t *conv, size_t mincsize, size_t minwsize)
 {
        void *p;
@@ -57,6 +57,7 @@
                        conv->csize = 0;
                        el_free(conv->cbuff);
                        conv->cbuff = NULL;
+                       return -1;
                } else 
                        conv->cbuff = p;
        }
@@ -68,9 +69,11 @@
                        conv->wsize = 0;
                        el_free(conv->wbuff);
                        conv->wbuff = NULL;
+                       return -1;
                } else
                        conv->wbuff = p;
        }
+       return 0;
 }
 
 
@@ -78,26 +81,22 @@
 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_buff_resize(conv, conv->csize + CT_BUFSIZ,
+                           (size_t)0) == -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 +110,19 @@
 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->csize < ++len)
+               if (ct_conv_buff_resize(conv, (size_t)0, len + CT_BUFSIZ) == -1)
+                       return NULL;
+
        ct_mbstowcs(conv->wbuff, s, conv->wsize);
        return conv->wbuff;
 }
@@ -145,9 +141,10 @@
         * 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->csize < ++bufspace)
+               if (ct_conv_buff_resize(conv, (size_t)0, bufspace + CT_BUFSIZ)
+                   == -1)
+                       return NULL;
 
        wargv = el_malloc((size_t)argc * sizeof(*wargv));
 
diff -r 3e93523adf62 -r e5c76cbc2ed7 lib/libedit/chartype.h
--- a/lib/libedit/chartype.h    Sat Feb 21 23:13:00 2015 +0000
+++ b/lib/libedit/chartype.h    Sun Feb 22 00:46:58 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: chartype.h,v 1.11 2015/02/17 22:49:26 christos Exp $   */
+/*     $NetBSD: chartype.h,v 1.12 2015/02/22 00:46:58 christos Exp $   */
 
 /*-
  * Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -189,7 +189,7 @@
 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_buff_resize(ct_buffer_t *, size_t, size_t);
 protected ssize_t ct_encode_char(char *, size_t, Char);
 protected size_t ct_enc_width(Char);
 



Home | Main Index | Thread Index | Old Index