commit 033492720c88a064b134f6851ee0f4a876cd4d6c Author: Tomas Hoger Date: Sun Oct 9 19:51:50 2011 +0200 Support compress files with maxbits < 12 The compress decompression code used by libXfont rejects valid archives with maxbits less than 12 (compress allows values 9 - 16, 16 is the default). This is because maxbits-12 is used as index to hsize_table[]. That looks like an incorrect port of the original compress code, where: - hsize depended on BITS, the maximum maxbits value supported by particular build, rather than on maxbits value from the particular input file - the same hsize was used for all BITS <= 12 The quick way to verify the problem is: compress -b 11 fontfile.bdf bdftopcf -o /dev/null fontfile.bdf.Z which fails, while 12-16 works correctly. This fix removes hsize_table and uses 1 << maxbits (aka maxmaxcode) as tab_prefix size. As decompression code does not use hashing as compression code, there does not seem to be a reason to allocate any extra space. Note: In this fix, maxbits == 9 is still rejected early. AFAICS compress is able to generate such files (unknown how correct such output is), but is unable to uncompress them correctly. diff --git a/src/fontfile/decompress.c b/src/fontfile/decompress.c index 6405d76..20971df 100644 --- a/src/fontfile/decompress.c +++ b/src/fontfile/decompress.c @@ -124,14 +124,6 @@ typedef struct _compressedFILE { } CompressedFile; -static int hsize_table[] = { - 5003, /* 12 bits - 80% occupancy */ - 9001, /* 13 bits - 91% occupancy */ - 18013, /* 14 bits - 91% occupancy */ - 35023, /* 15 bits - 94% occupancy */ - 69001 /* 16 bits - 95% occupancy */ -}; - static int BufCompressedClose ( BufFilePtr f, int doClose ); static int BufCompressedFill ( BufFilePtr f ); static code_int getcode ( CompressedFile *file ); @@ -142,7 +134,6 @@ BufFilePushCompressed (BufFilePtr f) { int code; int maxbits; - int hsize; CompressedFile *file; int extra; @@ -155,11 +146,10 @@ BufFilePushCompressed (BufFilePtr f) if (code == BUFFILEEOF) return 0; maxbits = code & BIT_MASK; - if (maxbits > BITS || maxbits < 12) + if (maxbits > BITS || maxbits <= INIT_BITS) return 0; - hsize = hsize_table[maxbits - 12]; extra = (1 << maxbits) * sizeof (char_type) + - hsize * sizeof (unsigned short); + (1 << maxbits) * sizeof (unsigned short); file = malloc (sizeof (CompressedFile) + extra); if (!file) return 0;