diff options
| author | Max Horn | 2003-03-08 23:35:46 +0000 | 
|---|---|---|
| committer | Max Horn | 2003-03-08 23:35:46 +0000 | 
| commit | 6e18bdfdb36044320ee1973de58a2df713b056bf (patch) | |
| tree | 2217a2d17a6d3c4266da63395fdb86ad0cc37e71 | |
| parent | d8dc1295fbd4f1a80f7a935667bdd073e2467cd0 (diff) | |
| download | scummvm-rg350-6e18bdfdb36044320ee1973de58a2df713b056bf.tar.gz scummvm-rg350-6e18bdfdb36044320ee1973de58a2df713b056bf.tar.bz2 scummvm-rg350-6e18bdfdb36044320ee1973de58a2df713b056bf.zip | |
more cleanup; added an error in case we encounter a 'real' input overflow (more than one byte, or one byte overflow but number of bits needed exceeds 8)
svn-id: r6780
| -rw-r--r-- | scumm/bundle.cpp | 47 | 
1 files changed, 27 insertions, 20 deletions
| diff --git a/scumm/bundle.cpp b/scumm/bundle.cpp index a7e197e4e4..a6bcf84d57 100644 --- a/scumm/bundle.cpp +++ b/scumm/bundle.cpp @@ -798,7 +798,7 @@ int32 Bundle::decompressCodec(int32 codec, byte *comp_input, byte *comp_output,  			int32 sDWord1[MAX_CHANNELS] = {0, 0};  			int32 sDWord2[MAX_CHANNELS] = {0, 0};  			int32 tableEntrySum, imcTableEntry, curTablePos, outputWord, adder; -			byte decompTable, otherTablePos, var3b; +			byte decompTable, otherTablePos, bitMask;  			byte *readPos, *dst;  			uint16 readWord; @@ -854,28 +854,34 @@ int32 Bundle::decompressCodec(int32 codec, byte *comp_input, byte *comp_output,  				destPos = l * 2;  				if (channels == 2) { -					if (l == 0) { -						if (left == 0) -							return output_size; +					if (l == 0)  						left++; -						left >>= 1; -					} else { -						if (left <= 1) -							return output_size; -						left >>= 1; -					} -				} else { -					if (left == 0) -						return output_size; +					left >>= 1;  				}  				while (left--) {  					curTableEntry = _destImcTable[curTablePos];  					decompTable = curTableEntry - 2; -					var3b = (1 << decompTable) << 1; +					bitMask = (1 << decompTable) << 1;  					readPos = src + (tableEntrySum >> 3); -					if (readPos+1 >= (comp_input+input_size)) { -						warning("Overflow!!! %d >= %d", (int)readPos+1, (int)comp_input+input_size); +					 +					// FIXME - it seems the decoder often reads exactly one byte too +					// far - that is, it reads 2 bytes at once, and the second byte +					// is just outside the buffer. However, it seems of these two bytes, +					// only the upper one is actually used, so this should be fine. +					// Still, I put this error message into place. If somebody one day +					// encounters a situation where the second byte would be used, too, +					// then this would indicate there is a bug in the decoder... +					if (readPos + 1 >= comp_input + input_size) { +						// OK an overflow... if it is more than one byte or if we +						// need more than 8 bit of data -> error +						if (readPos + 1 > comp_input + input_size || +						    curTableEntry + (tableEntrySum & 7) > 8) { +							error("decompressCodec: input buffer overflow: %d bytes over (we need %d bits of data)", +									(int)((readPos+1) - (comp_input+input_size))+1, +									curTableEntry + (tableEntrySum & 7) +								); +						}  					}  					readWord = (uint16)(READ_BE_UINT16(readPos) << (tableEntrySum & 7));  					otherTablePos = (byte)(readWord >> (16 - curTableEntry)); @@ -884,10 +890,12 @@ int32 Bundle::decompressCodec(int32 codec, byte *comp_input, byte *comp_output,  						<< (7 - curTableEntry)) + (curTablePos << 6);  					imcTableEntry >>= (curTableEntry - 1);  					adder = imcTableEntry + _destImcTable2[esiReg]; -					if ((otherTablePos & var3b) != 0) { +					if ((otherTablePos & bitMask) != 0) {  						adder = -adder;  					}  					outputWord += adder; + +					// Clip outputWord to 16 bit signed, and write it into the destination stream  					if (outputWord > 0x7fff)  						outputWord = 0x7fff;  					if (outputWord < -0x8000) @@ -895,17 +903,16 @@ int32 Bundle::decompressCodec(int32 codec, byte *comp_input, byte *comp_output,  					dst[destPos] = ((int16)outputWord) >> 8;  					dst[destPos + 1] = (byte)(outputWord); +					// Adjust the curTablePos / imcTableEntry  					assert(decompTable < 6);  					curTablePos += (signed char)imxOtherTable[decompTable][otherTablePos]; - -					// Clip data  					if (curTablePos > 88)  						curTablePos = 88;  					if (curTablePos < 0)  						curTablePos = 0; +					imcTableEntry = imcTable[curTablePos];  					destPos += channels << 1; -					imcTableEntry = imcTable[curTablePos];  				}  			}  		} | 
