quartz: Cope with invalid audio headers being detect as valid

Bruno Jesus 00cpxxx at gmail.com
Sun Sep 13 14:21:53 CDT 2015


The game from bug https://bugs.winehq.org/show_bug.cgi?id=35163 has a
mp3 file with a bad ID3v2 tag, the length from the tag is incorrect so
after skipping it we will find a part of a mp3 comment that
unfortunately matches an audio header. This patch ensures the audio
header is OK by jumping to the next frame and testing it too.

There are 2 concurrent crashes in bug 35163, this patch fixes the
least common crash.
-------------- next part --------------
diff --git a/dlls/quartz/mpegsplit.c b/dlls/quartz/mpegsplit.c
index 1ed352b..52292ea 100644
--- a/dlls/quartz/mpegsplit.c
+++ b/dlls/quartz/mpegsplit.c
@@ -478,7 +478,7 @@ static HRESULT MPEGSplitter_pre_connect(IPin *iface, IPin *pConnectPin, ALLOCATO
     HRESULT hr;
     LONGLONG pos = 0; /* in bytes */
     BYTE header[10];
-    int streamtype = 0;
+    int streamtype;
     LONGLONG total, avail;
     AM_MEDIA_TYPE amt;
     PIN_INFO piOutput;
@@ -516,12 +516,37 @@ static HRESULT MPEGSplitter_pre_connect(IPin *iface, IPin *pConnectPin, ALLOCATO
         hr = IAsyncReader_SyncRead(pPin->pReader, pos, 4, header);
         if (SUCCEEDED(hr))
             pos += 4;
-        TRACE("%x:%x:%x:%x\n", header[0], header[1], header[2], header[3]);
     } while (0);
 
-    while(SUCCEEDED(hr) && !(streamtype=MPEGSplitter_head_check(header)))
+    while(SUCCEEDED(hr))
     {
-        TRACE("%x:%x:%x:%x\n", header[0], header[1], header[2], header[3]);
+        TRACE("Testing header %x:%x:%x:%x\n", header[0], header[1], header[2], header[3]);
+
+        streamtype = MPEGSplitter_head_check(header);
+        if (streamtype == MPEG_AUDIO_HEADER)
+        {
+            LONGLONG length;
+            if (parse_header(header, &length, NULL) == S_OK)
+            {
+                BYTE next_header[4];
+                /* Ensure we have a valid header by seeking for the next frame, some bad
+                 * encoded ID3v2 may have an incorrect length and we end up finding bytes
+                 * like FF FE 00 28 which are nothing more than a Unicode BOM followed by
+                 * ')' character from inside a ID3v2 tag. Unfortunately that sequence
+                 * matches like a valid mpeg audio header.
+                 */
+                hr = IAsyncReader_SyncRead(pPin->pReader, pos + length - 4, 4, next_header);
+                if (FAILED(hr))
+                    break;
+                if (parse_header(next_header, &length, NULL) == S_OK)
+                    break;
+                TRACE("%x:%x:%x:%x is a fake audio header, looking for next...\n",
+                      header[0], header[1], header[2], header[3]);
+            }
+        }
+        else if (streamtype) /* Video or System stream */
+            break;
+
         /* No valid header yet; shift by a byte and check again */
         memmove(header, header+1, 3);
         hr = IAsyncReader_SyncRead(pPin->pReader, pos++, 1, header + 3);


More information about the wine-patches mailing list