msadpcm32.acm: Stop converting data instead of crashing (try 2)

Bruno Jesus 00cpxxx at gmail.com
Tue Sep 29 09:06:21 CDT 2015


Signed-off-by: Bruno Jesus <00cpxxx at gmail.com>

try 2:
Downgrade a ERR to WARN as requested by Andrew Eikum.

Tomb Raider 3 uses a single archive with all wav files inside, when
playing some specific sounds it passes incorrect lengths of data that
reach the next wav file header. This causes an assert in the code that
is now gracefully handled.

Fixes bug https://bugs.winehq.org/show_bug.cgi?id=21000
-------------- next part --------------
diff --git a/dlls/msadp32.acm/msadp32.c b/dlls/msadp32.acm/msadp32.c
index 2c61575..24e0c6a 100644
--- a/dlls/msadp32.acm/msadp32.c
+++ b/dlls/msadp32.acm/msadp32.c
@@ -249,9 +249,17 @@ static	void cvtSSms16K(const ACMDRVSTREAMINSTANCE *adsi,
     {
         const unsigned char*    in_src = src;
 
-        assert(*src <= 6);
+        /* Catch a problem from Tomb Raider III (bug 21000) where it passes
+         * invalid data after a valid sequence of blocks */
+        if (*src > 6 || *(src + 1) > 6)
+        {
+            /* Recalculate the amount of used output buffer. We are not changing
+             * nsrc, let's assume the bad data was parsed */
+            *ndst -= nblock * nsamp_blk * adsi->pwfxDst->nBlockAlign;
+            WARN("Invalid ADPCM data, stopping conversion\n");
+            break;
+        }
         coeffL = MSADPCM_CoeffSet[*src++];
-        assert(*src <= 6);
         coeffR = MSADPCM_CoeffSet[*src++];
 
         ideltaL  = R16(src);    src += 2;


More information about the wine-patches mailing list