ref: 86c3c69c15dfc46238e2e0822876982b21aa53f9
parent: 57b6a6148d072d30d7bcd071411316369190a57c
author: Tomas Hoger <[email protected]>
date: Sun Sep 11 05:08:40 EDT 2011
Protect against loops in the prefix table. LZW decompressor did not sufficiently check codes read from the input LZW stream. A specially-crafted or corrupted input could create a loop in the prefix table, which leads to memory usage spikes, as there's no decompression stack size limit. * src/lzw/ftzopen.c (ft_lzwstate_io) <FT_LZW_PHASE_START>: First code in valid LZW stream must be 0..255. <FT_LZW_PHASE_CODE>: In the special KwKwK case, code == free_ent, code > free_ent is invalid.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2011-09-11 Tomas Hoger <[email protected]>
+
+ Protect against loops in the prefix table.
+
+ LZW decompressor did not sufficiently check codes read from the
+ input LZW stream. A specially-crafted or corrupted input could
+ create a loop in the prefix table, which leads to memory usage
+ spikes, as there's no decompression stack size limit.
+
+ * src/lzw/ftzopen.c (ft_lzwstate_io) <FT_LZW_PHASE_START>: First
+ code in valid LZW stream must be 0..255.
+ <FT_LZW_PHASE_CODE>: In the special KwKwK case, code == free_ent,
+ code > free_ent is invalid.
+
2011-09-09 Werner Lemberg <[email protected]>
Better tracing of metrics.
--- a/src/lzw/ftzopen.c
+++ b/src/lzw/ftzopen.c
@@ -8,7 +8,7 @@
/* be used to parse compressed PCF fonts, as found with many X11 server */
/* distributions. */
/* */
-/* Copyright 2005, 2006, 2007, 2009 by David Turner. */
+/* Copyright 2005-2007, 2009, 2011 by David Turner. */
/* */
/* This file is part of the FreeType project, and may only be used, */
/* modified, and distributed under the terms of the FreeType project */
@@ -279,7 +279,7 @@
: state->max_free + 1;
c = ft_lzwstate_get_code( state );
- if ( c < 0 )
+ if ( c < 0 || c > 255 )
goto Eof;
old_code = old_char = (FT_UInt)c;
@@ -326,6 +326,10 @@
/* special case for KwKwKwK */
if ( code - 256U >= state->free_ent )
{
+ /* corrupted LZW stream */
+ if ( code - 256U > state->free_ent )
+ goto Eof;
+
FTLZW_STACK_PUSH( old_char );
code = old_code;
}