Tue Apr 14 05:30:24 2015 UTC ()
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.


(snj)
diff -r1.10 -r1.10.20.1 src/lib/libedit/chartype.c
diff -r1.10 -r1.10.18.1 src/lib/libedit/chartype.h

cvs diff -r1.10 -r1.10.20.1 src/lib/libedit/chartype.c (expand / switch to unified diff)

--- src/lib/libedit/chartype.c 2011/08/16 16:25:15 1.10
+++ src/lib/libedit/chartype.c 2015/04/14 05:30:24 1.10.20.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: chartype.c,v 1.10 2011/08/16 16:25:15 christos Exp $ */ 1/* $NetBSD: chartype.c,v 1.10.20.1 2015/04/14 05:30:24 snj Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2009 The NetBSD Foundation, Inc. 4 * Copyright (c) 2009 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -28,136 +28,144 @@ @@ -28,136 +28,144 @@
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE. 33 * POSSIBILITY OF SUCH DAMAGE.
34 */ 34 */
35 35
36/* 36/*
37 * chartype.c: character classification and meta information 37 * chartype.c: character classification and meta information
38 */ 38 */
39#include "config.h" 39#include "config.h"
40#if !defined(lint) && !defined(SCCSID) 40#if !defined(lint) && !defined(SCCSID)
41__RCSID("$NetBSD: chartype.c,v 1.10 2011/08/16 16:25:15 christos Exp $"); 41__RCSID("$NetBSD: chartype.c,v 1.10.20.1 2015/04/14 05:30:24 snj Exp $");
42#endif /* not lint && not SCCSID */ 42#endif /* not lint && not SCCSID */
43#include "el.h" 43#include "el.h"
44#include <stdlib.h> 44#include <stdlib.h>
45 45
46#define CT_BUFSIZ ((size_t)1024) 46#define CT_BUFSIZ ((size_t)1024)
47 47
48#ifdef WIDECHAR 48#ifdef WIDECHAR
49protected void 49protected int
50ct_conv_buff_resize(ct_buffer_t *conv, size_t mincsize, size_t minwsize) 50ct_conv_cbuff_resize(ct_buffer_t *conv, size_t csize)
51{ 51{
52 void *p; 52 void *p;
53 if (mincsize > conv->csize) { 53
54 conv->csize = mincsize; 54 if (csize <= conv->csize)
55 p = el_realloc(conv->cbuff, conv->csize * sizeof(*conv->cbuff)); 55 return 0;
56 if (p == NULL) { 56
57 conv->csize = 0; 57 conv->csize = csize;
58 el_free(conv->cbuff); 58
59 conv->cbuff = NULL; 59 p = el_realloc(conv->cbuff, conv->csize * sizeof(*conv->cbuff));
60 } else  60 if (p == NULL) {
61 conv->cbuff = p; 61 conv->csize = 0;
 62 el_free(conv->cbuff);
 63 conv->cbuff = NULL;
 64 return -1;
62 } 65 }
 66 conv->cbuff = p;
 67 return 0;
 68}
63 69
64 if (minwsize > conv->wsize) { 70protected int
65 conv->wsize = minwsize; 71ct_conv_wbuff_resize(ct_buffer_t *conv, size_t wsize)
66 p = el_realloc(conv->wbuff, conv->wsize * sizeof(*conv->wbuff)); 72{
67 if (p == NULL) { 73 void *p;
68 conv->wsize = 0; 74
69 el_free(conv->wbuff); 75 if (wsize <= conv->wsize)
70 conv->wbuff = NULL; 76 return 0;
71 } else 77
72 conv->wbuff = p; 78 conv->wsize = wsize;
 79
 80 p = el_realloc(conv->wbuff, conv->wsize * sizeof(*conv->wbuff));
 81 if (p == NULL) {
 82 conv->wsize = 0;
 83 el_free(conv->wbuff);
 84 conv->wbuff = NULL;
 85 return -1;
73 } 86 }
 87 conv->wbuff = p;
 88 return 0;
74} 89}
75 90
76 91
77public char * 92public char *
78ct_encode_string(const Char *s, ct_buffer_t *conv) 93ct_encode_string(const Char *s, ct_buffer_t *conv)
79{ 94{
80 char *dst; 95 char *dst;
81 ssize_t used = 0; 96 ssize_t used;
82 97
83 if (!s) 98 if (!s)
84 return NULL; 99 return NULL;
85 if (!conv->cbuff) 
86 ct_conv_buff_resize(conv, CT_BUFSIZ, (size_t)0); 
87 if (!conv->cbuff) 
88 return NULL; 
89 100
90 dst = conv->cbuff; 101 dst = conv->cbuff;
91 while (*s) { 102 for (;;) {
92 used = (ssize_t)(conv->csize - (size_t)(dst - conv->cbuff)); 103 used = (ssize_t)(dst - conv->cbuff);
93 if (used < 5) { 104 if ((conv->csize - (size_t)used) < 5) {
94 used = dst - conv->cbuff; 105 if (ct_conv_cbuff_resize(conv,
95 ct_conv_buff_resize(conv, conv->csize + CT_BUFSIZ, 106 conv->csize + CT_BUFSIZ) == -1)
96 (size_t)0); 
97 if (!conv->cbuff) 
98 return NULL; 107 return NULL;
99 dst = conv->cbuff + used; 108 dst = conv->cbuff + used;
100 } 109 }
 110 if (!*s)
 111 break;
101 used = ct_encode_char(dst, (size_t)5, *s); 112 used = ct_encode_char(dst, (size_t)5, *s);
102 if (used == -1) /* failed to encode, need more buffer space */ 113 if (used == -1) /* failed to encode, need more buffer space */
103 abort(); 114 abort();
104 ++s; 115 ++s;
105 dst += used; 116 dst += used;
106 } 117 }
107 *dst = '\0'; 118 *dst = '\0';
108 return conv->cbuff; 119 return conv->cbuff;
109} 120}
110 121
111public Char * 122public Char *
112ct_decode_string(const char *s, ct_buffer_t *conv) 123ct_decode_string(const char *s, ct_buffer_t *conv)
113{ 124{
114 size_t len = 0; 125 size_t len;
115 126
116 if (!s) 127 if (!s)
117 return NULL; 128 return NULL;
118 if (!conv->wbuff) 
119 ct_conv_buff_resize(conv, (size_t)0, CT_BUFSIZ); 
120 if (!conv->wbuff) 
121 return NULL; 
122 129
123 len = ct_mbstowcs(NULL, s, (size_t)0); 130 len = ct_mbstowcs(NULL, s, (size_t)0);
124 if (len == (size_t)-1) 131 if (len == (size_t)-1)
125 return NULL; 132 return NULL;
126 if (len > conv->wsize) 133
127 ct_conv_buff_resize(conv, (size_t)0, len + 1); 134 if (conv->wsize < ++len)
128 if (!conv->wbuff) 135 if (ct_conv_wbuff_resize(conv, len + CT_BUFSIZ) == -1)
129 return NULL; 136 return NULL;
 137
130 ct_mbstowcs(conv->wbuff, s, conv->wsize); 138 ct_mbstowcs(conv->wbuff, s, conv->wsize);
131 return conv->wbuff; 139 return conv->wbuff;
132} 140}
133 141
134 142
135protected Char ** 143protected Char **
136ct_decode_argv(int argc, const char *argv[], ct_buffer_t *conv) 144ct_decode_argv(int argc, const char *argv[], ct_buffer_t *conv)
137{ 145{
138 size_t bufspace; 146 size_t bufspace;
139 int i; 147 int i;
140 Char *p; 148 Char *p;
141 Char **wargv; 149 Char **wargv;
142 ssize_t bytes; 150 ssize_t bytes;
143 151
144 /* Make sure we have enough space in the conversion buffer to store all 152 /* Make sure we have enough space in the conversion buffer to store all
145 * the argv strings. */ 153 * the argv strings. */
146 for (i = 0, bufspace = 0; i < argc; ++i) 154 for (i = 0, bufspace = 0; i < argc; ++i)
147 bufspace += argv[i] ? strlen(argv[i]) + 1 : 0; 155 bufspace += argv[i] ? strlen(argv[i]) + 1 : 0;
148 ct_conv_buff_resize(conv, (size_t)0, bufspace); 156 if (conv->wsize < ++bufspace)
149 if (!conv->wsize) 157 if (ct_conv_wbuff_resize(conv, bufspace + CT_BUFSIZ) == -1)
150 return NULL; 158 return NULL;
151 159
152 wargv = el_malloc((size_t)argc * sizeof(*wargv)); 160 wargv = el_malloc((size_t)argc * sizeof(*wargv));
153 161
154 for (i = 0, p = conv->wbuff; i < argc; ++i) { 162 for (i = 0, p = conv->wbuff; i < argc; ++i) {
155 if (!argv[i]) { /* don't pass null pointers to mbstowcs */ 163 if (!argv[i]) { /* don't pass null pointers to mbstowcs */
156 wargv[i] = NULL; 164 wargv[i] = NULL;
157 continue; 165 continue;
158 } else { 166 } else {
159 wargv[i] = p; 167 wargv[i] = p;
160 bytes = (ssize_t)mbstowcs(p, argv[i], bufspace); 168 bytes = (ssize_t)mbstowcs(p, argv[i], bufspace);
161 } 169 }
162 if (bytes == -1) { 170 if (bytes == -1) {
163 el_free(wargv); 171 el_free(wargv);

cvs diff -r1.10 -r1.10.18.1 src/lib/libedit/chartype.h (expand / switch to unified diff)

--- src/lib/libedit/chartype.h 2011/11/16 01:45:10 1.10
+++ src/lib/libedit/chartype.h 2015/04/14 05:30:24 1.10.18.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: chartype.h,v 1.10 2011/11/16 01:45:10 christos Exp $ */ 1/* $NetBSD: chartype.h,v 1.10.18.1 2015/04/14 05:30:24 snj Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2009 The NetBSD Foundation, Inc. 4 * Copyright (c) 2009 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -179,37 +179,39 @@ typedef struct ct_buffer_t { @@ -179,37 +179,39 @@ typedef struct ct_buffer_t {
179#define ct_encode_string __ct_encode_string 179#define ct_encode_string __ct_encode_string
180/* Encode a wide-character string and return the UTF-8 encoded result. */ 180/* Encode a wide-character string and return the UTF-8 encoded result. */
181public char *ct_encode_string(const Char *, ct_buffer_t *); 181public char *ct_encode_string(const Char *, ct_buffer_t *);
182 182
183#define ct_decode_string __ct_decode_string 183#define ct_decode_string __ct_decode_string
184/* Decode a (multi)?byte string and return the wide-character string result. */ 184/* Decode a (multi)?byte string and return the wide-character string result. */
185public Char *ct_decode_string(const char *, ct_buffer_t *); 185public Char *ct_decode_string(const char *, ct_buffer_t *);
186 186
187/* Decode a (multi)?byte argv string array. 187/* Decode a (multi)?byte argv string array.
188 * The pointer returned must be free()d when done. */ 188 * The pointer returned must be free()d when done. */
189protected Char **ct_decode_argv(int, const char *[], ct_buffer_t *); 189protected Char **ct_decode_argv(int, const char *[], ct_buffer_t *);
190 190
191/* Resizes the conversion buffer(s) if needed. */ 191/* Resizes the conversion buffer(s) if needed. */
192protected void ct_conv_buff_resize(ct_buffer_t *, size_t, size_t); 192protected int ct_conv_cbuff_resize(ct_buffer_t *, size_t);
 193protected int ct_conv_wbuff_resize(ct_buffer_t *, size_t);
193protected ssize_t ct_encode_char(char *, size_t, Char); 194protected ssize_t ct_encode_char(char *, size_t, Char);
194protected size_t ct_enc_width(Char); 195protected size_t ct_enc_width(Char);
195 196
196#define ct_free_argv(s) el_free(s) 197#define ct_free_argv(s) el_free(s)
197 198
198#else 199#else
199#define ct_encode_string(s, b) (s) 200#define ct_encode_string(s, b) (s)
200#define ct_decode_string(s, b) (s) 201#define ct_decode_string(s, b) (s)
201#define ct_decode_argv(l, s, b) (s) 202#define ct_decode_argv(l, s, b) (s)
202#define ct_conv_buff_resize(b, os, ns) 203#define ct_conv_cbuff_resize(b, s) ((s) == (0))
 204#define ct_conv_wbuff_resize(b, s) ((s) == (0))
203#define ct_encode_char(d, l, s) (*d = s, 1) 205#define ct_encode_char(d, l, s) (*d = s, 1)
204#define ct_free_argv(s) 206#define ct_free_argv(s)
205#endif 207#endif
206 208
207#ifndef NARROWCHAR 209#ifndef NARROWCHAR
208/* Encode a characted into the destination buffer, provided there is sufficent 210/* Encode a characted into the destination buffer, provided there is sufficent
209 * buffer space available. Returns the number of bytes used up (zero if the 211 * buffer space available. Returns the number of bytes used up (zero if the
210 * character cannot be encoded, -1 if there was not enough space available). */ 212 * character cannot be encoded, -1 if there was not enough space available). */
211 213
212/* The maximum buffer size to hold the most unwieldly visual representation, 214/* The maximum buffer size to hold the most unwieldly visual representation,
213 * in this case \U+nnnnn. */ 215 * in this case \U+nnnnn. */
214#define VISUAL_WIDTH_MAX ((size_t)8) 216#define VISUAL_WIDTH_MAX ((size_t)8)
215 217