Tue Aug 16 18:17:19 2011 UTC ()
Increase robustness of LZW decoding to avoid buffer overflow on
arbitrary manipulated input streams in combination with uninitalised
memory.


(joerg)
diff -r1.1.1.1 -r1.2 xsrc/xfree/xc/extras/freetype2/src/lzw/zopen.c

cvs diff -r1.1.1.1 -r1.2 xsrc/xfree/xc/extras/freetype2/src/lzw/Attic/zopen.c (expand / switch to unified diff)

--- xsrc/xfree/xc/extras/freetype2/src/lzw/Attic/zopen.c 2005/03/18 13:07:34 1.1.1.1
+++ xsrc/xfree/xc/extras/freetype2/src/lzw/Attic/zopen.c 2011/08/16 18:17:19 1.2
@@ -1,15 +1,15 @@ @@ -1,15 +1,15 @@
1/* $XFree86: xc/extras/freetype2/src/lzw/zopen.c,v 1.2 2004/12/16 22:15:48 tsi Exp $ */ 1/* $XFree86: xc/extras/freetype2/src/lzw/zopen.c,v 1.2 2004/12/16 22:15:48 tsi Exp $ */
2/* $NetBSD: zopen.c,v 1.1.1.1 2005/03/18 13:07:34 tron Exp $ */ 2/* $NetBSD: zopen.c,v 1.2 2011/08/16 18:17:19 joerg Exp $ */
3 3
4/*- 4/*-
5 * Copyright (c) 1985, 1986, 1992, 1993 5 * Copyright (c) 1985, 1986, 1992, 1993
6 * The Regents of the University of California. All rights reserved. 6 * The Regents of the University of California. All rights reserved.
7 * 7 *
8 * This code is derived from software contributed to Berkeley by 8 * This code is derived from software contributed to Berkeley by
9 * Diomidis Spinellis and James A. Woods, derived from original 9 * Diomidis Spinellis and James A. Woods, derived from original
10 * work by Spencer Thomas and Joseph Orost. 10 * work by Spencer Thomas and Joseph Orost.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions 13 * modification, are permitted provided that the following conditions
14 * are met: 14 * are met:
15 * 1. Redistributions of source code must retain the above copyright 15 * 1. Redistributions of source code must retain the above copyright
@@ -37,27 +37,27 @@ @@ -37,27 +37,27 @@
37/*- 37/*-
38 * 38 *
39 * Copyright (c) 2004 39 * Copyright (c) 2004
40 * Albert Chin-A-Young. 40 * Albert Chin-A-Young.
41 * 41 *
42 * Modified to work with FreeType's PCF driver. 42 * Modified to work with FreeType's PCF driver.
43 * 43 *
44 */ 44 */
45 45
46#if defined(LIBC_SCCS) && !defined(lint) 46#if defined(LIBC_SCCS) && !defined(lint)
47#if 0 47#if 0
48static char sccsid[] = "@(#)zopen.c 8.1 (Berkeley) 6/27/93"; 48static char sccsid[] = "@(#)zopen.c 8.1 (Berkeley) 6/27/93";
49#else 49#else
50static char rcsid[] = "$NetBSD: zopen.c,v 1.1.1.1 2005/03/18 13:07:34 tron Exp $"; 50static char rcsid[] = "$NetBSD: zopen.c,v 1.2 2011/08/16 18:17:19 joerg Exp $";
51#endif 51#endif
52#endif /* LIBC_SCCS and not lint */ 52#endif /* LIBC_SCCS and not lint */
53 53
54/*- 54/*-
55 * fcompress.c - File compression ala IEEE Computer, June 1984. 55 * fcompress.c - File compression ala IEEE Computer, June 1984.
56 * 56 *
57 * Compress authors: 57 * Compress authors:
58 * Spencer W. Thomas (decvax!utah-cs!thomas) 58 * Spencer W. Thomas (decvax!utah-cs!thomas)
59 * Jim McKie (decvax!mcvax!jim) 59 * Jim McKie (decvax!mcvax!jim)
60 * Steve Davies (decvax!vax135!petsd!peora!srd) 60 * Steve Davies (decvax!vax135!petsd!peora!srd)
61 * Ken Turkowski (decvax!decwrl!turtlevax!ken) 61 * Ken Turkowski (decvax!decwrl!turtlevax!ken)
62 * James A. Woods (decvax!ihnp4!ames!jaw) 62 * James A. Woods (decvax!ihnp4!ames!jaw)
63 * Joe Orost (decvax!vax135!petsd!joe) 63 * Joe Orost (decvax!vax135!petsd!joe)
@@ -204,87 +204,83 @@ zread(s_zstate_t *zs) @@ -204,87 +204,83 @@ zread(s_zstate_t *zs)
204 goto middle; 204 goto middle;
205 case S_EOF: 205 case S_EOF:
206 goto eof; 206 goto eof;
207 } 207 }
208 208
209 maxbits = *(zs->next_in); /* Set -b from file. */ 209 maxbits = *(zs->next_in); /* Set -b from file. */
210 zs->avail_in--; 210 zs->avail_in--;
211 zs->next_in++; 211 zs->next_in++;
212 zs->total_in++; 212 zs->total_in++;
213 in_count--; 213 in_count--;
214 block_compress = maxbits & BLOCK_MASK; 214 block_compress = maxbits & BLOCK_MASK;
215 maxbits &= BIT_MASK; 215 maxbits &= BIT_MASK;
216 maxmaxcode = 1L << maxbits; 216 maxmaxcode = 1L << maxbits;
217 if (maxbits > BITS) { 217 if (maxbits > BITS || maxbits < 12) {
218 return -1; 218 return -1;
219 } 219 }
220 /* As above, initialize the first 256 entries in the table. */ 220 /* As above, initialize the first 256 entries in the table. */
221 maxcode = MAXCODE(n_bits = INIT_BITS); 221 maxcode = MAXCODE(n_bits = INIT_BITS);
222 for (code = 255; code >= 0; code--) { 222 for (code = 255; code >= 0; code--) {
223 tab_prefixof(code) = 0; 223 tab_prefixof(code) = 0;
224 tab_suffixof(code) = (char_type) code; 224 tab_suffixof(code) = (char_type) code;
225 } 225 }
226 free_ent = block_compress ? FIRST : 256; 226 free_ent = block_compress ? FIRST : 256;
227 227 oldcode = -1;
228 finchar = oldcode = getcode(zs); 
229 if (oldcode == -1) /* EOF already? */ 
230 return 0; /* Get out of here */ 
231 
232 /* First code must be 8 bits = char. */ 
233 *(zs->next_out)++ = (unsigned char)finchar; 
234 zs->total_out++; 
235 count--; 
236 stackp = de_stack; 228 stackp = de_stack;
237 229
238 while ((code = getcode(zs)) > -1) { 230 while ((code = getcode(zs)) > -1) {
239 if ((code == CLEAR) && block_compress) { 231 if ((code == CLEAR) && block_compress) {
240 for (code = 255; code >= 0; code--) 232 for (code = 255; code >= 0; code--)
241 tab_prefixof(code) = 0; 233 tab_prefixof(code) = 0;
242 clear_flg = 1; 234 clear_flg = 1;
243 free_ent = FIRST - 1; 235 free_ent = FIRST ;
244 if ((code = getcode(zs)) == -1) 236 oldcode = -1;
245 /* O, untimely death! */ 237 continue;
246 break; 
247 } 238 }
248 incode = code; 239 incode = code;
249 240
250 /* Special case for KwKwK string. */ 241 /* Special case for KwKwK string. */
251 if (code >= free_ent) { 242 if (code >= free_ent) {
 243 if (code > free_ent || oldcode == -1) {
 244 /* Bad stream. */
 245 errno = EINVAL;
 246 return (-1);
 247 }
252 *stackp++ = finchar; 248 *stackp++ = finchar;
253 code = oldcode; 249 code = oldcode;
254 } 250 }
255 251
256 /* Generate output characters in reverse order. */ 252 /* Generate output characters in reverse order. */
257 while (code >= 256) { 253 while (code >= 256) {
258 *stackp++ = tab_suffixof(code); 254 *stackp++ = tab_suffixof(code);
259 code = tab_prefixof(code); 255 code = tab_prefixof(code);
260 } 256 }
261 *stackp++ = finchar = tab_suffixof(code); 257 *stackp++ = finchar = tab_suffixof(code);
262 258
263 /* And put them out in forward order. */ 259 /* And put them out in forward order. */
264middle: 260middle:
265 if (stackp == de_stack) 261 if (stackp == de_stack)
266 continue; 262 continue;
267 263
268 do { 264 do {
269 if (count-- == 0) { 265 if (count-- == 0) {
270 return zs->avail_out; 266 return zs->avail_out;
271 } 267 }
272 *(zs->next_out)++ = *--stackp; 268 *(zs->next_out)++ = *--stackp;
273 zs->total_out++; 269 zs->total_out++;
274 } while (stackp > de_stack); 270 } while (stackp > de_stack);
275 271
276 /* Generate the new entry. */ 272 /* Generate the new entry. */
277 if ((code = free_ent) < maxmaxcode) { 273 if ((code = free_ent) < maxmaxcode && oldcode != -1) {
278 tab_prefixof(code) = (unsigned short) oldcode; 274 tab_prefixof(code) = (unsigned short) oldcode;
279 tab_suffixof(code) = finchar; 275 tab_suffixof(code) = finchar;
280 free_ent = code + 1; 276 free_ent = code + 1;
281 } 277 }
282 278
283 /* Remember previous code. */ 279 /* Remember previous code. */
284 oldcode = incode; 280 oldcode = incode;
285 } 281 }
286 /* state = S_EOF; */ 282 /* state = S_EOF; */
287eof: return (zs->avail_out - count); 283eof: return (zs->avail_out - count);
288} 284}
289 285
290/*- 286/*-