2015.06.11 16:15 "Re: [Tiff] Long standing bug in LibTIFF LZW compression", by Lee Howard
Attached is the untested patch. (I'm merely following Andy's instructions in creating a patch for him.)
On 05/08/2015 10:51 AM, Andy Cave wrote:
Dear All,
There is a longstanding bug in the LZW decompressor in LibTIFF. It fails to decode files that contain two consecutive CODE_CLEAR codes. These are allowed by the LZW spec and the same data sequence is correctly decoded by Acrobat if you wrap the data in a PDF file.
The fix is simple:
- Add "do {" after the line "if (code == CODE_CLEAR) {" in both LZWDecode and LZWDecodeCompat.
- Add "} while (code == CODE_CLEAR);" before the line " if (code == CODE_EOI)" (half a dozen lines or so down from the first change) in both LZWDecode and LZWDecodeCompat.
- I have no idea how to submit a diff of the fix or fix the public domain source, so if someone could help who knows how to, it should do no harm to fix the bug.
--- libtiff/tif_lzw.c.orig 2015-06-11 09:09:07.333492975 -0700
+++ libtiff/tif_lzw.c 2015-06-11 09:13:16.110060482 -0700
@@ -436,13 +436,15 @@
if (code == CODE_EOI)
break;
if (code == CODE_CLEAR) {
- free_entp = sp->dec_codetab + CODE_FIRST;
- _TIFFmemset(free_entp, 0,
- (CSIZE - CODE_FIRST) * sizeof (code_t));
- nbits = BITS_MIN;
- nbitsmask = MAXCODE(BITS_MIN);
- maxcodep = sp->dec_codetab + nbitsmask-1;
- NextCode(tif, sp, bp, code, GetNextCode);
+ do {
+ free_entp = sp->dec_codetab + CODE_FIRST;
+ _TIFFmemset(free_entp, 0,
+ (CSIZE - CODE_FIRST) * sizeof (code_t));
+ nbits = BITS_MIN;
+ nbitsmask = MAXCODE(BITS_MIN);
+ maxcodep = sp->dec_codetab + nbitsmask-1;
+ NextCode(tif, sp, bp, code, GetNextCode);
+ } while (code == CODE_CLEAR); /* consecutive CODE_CLEAR codes */
if (code == CODE_EOI)
break;
if (code >= CODE_CLEAR) {
@@ -655,13 +657,15 @@
if (code == CODE_EOI)
break;
if (code == CODE_CLEAR) {
- free_entp = sp->dec_codetab + CODE_FIRST;
- _TIFFmemset(free_entp, 0,
- (CSIZE - CODE_FIRST) * sizeof (code_t));
- nbits = BITS_MIN;
- nbitsmask = MAXCODE(BITS_MIN);
- maxcodep = sp->dec_codetab + nbitsmask;
- NextCode(tif, sp, bp, code, GetNextCodeCompat);
+ do {
+ free_entp = sp->dec_codetab + CODE_FIRST;
+ _TIFFmemset(free_entp, 0,
+ (CSIZE - CODE_FIRST) * sizeof (code_t));
+ nbits = BITS_MIN;
+ nbitsmask = MAXCODE(BITS_MIN);
+ maxcodep = sp->dec_codetab + nbitsmask;
+ NextCode(tif, sp, bp, code, GetNextCodeCompat);
+ } while (code == CODE_CLEAR); /* consecutive CODE_CLEAR codes */
if (code == CODE_EOI)
break;
if (code >= CODE_CLEAR) {