Module Name: src Committed By: christos Date: Sun Feb 22 00:46:58 UTC 2015
Modified Files: src/lib/libedit: chartype.c chartype.h Log Message: PR/49683: Amir Plivatsky: Off-by-one comparison in ct_decode_string() leading to out of bounds referrence. XXX: pullup-7 To generate a diff of this commit: cvs rdiff -u -r1.10 -r1.11 src/lib/libedit/chartype.c cvs rdiff -u -r1.11 -r1.12 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.11 --- src/lib/libedit/chartype.c:1.10 Tue Aug 16 12:25:15 2011 +++ src/lib/libedit/chartype.c Sat Feb 21 19:46:58 2015 @@ -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 @@ __RCSID("$NetBSD: chartype.c,v 1.10 2011 #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 @@ ct_conv_buff_resize(ct_buffer_t *conv, s conv->csize = 0; el_free(conv->cbuff); conv->cbuff = NULL; + return -1; } else conv->cbuff = p; } @@ -68,9 +69,11 @@ ct_conv_buff_resize(ct_buffer_t *conv, s conv->wsize = 0; el_free(conv->wbuff); conv->wbuff = NULL; + return -1; } else conv->wbuff = p; } + return 0; } @@ -78,26 +81,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_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 @@ 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->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 @@ 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->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)); Index: src/lib/libedit/chartype.h diff -u src/lib/libedit/chartype.h:1.11 src/lib/libedit/chartype.h:1.12 --- src/lib/libedit/chartype.h:1.11 Tue Feb 17 17:49:26 2015 +++ src/lib/libedit/chartype.h Sat Feb 21 19:46:58 2015 @@ -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 @@ 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_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);