Zebediah Figura : mp3dmod: Handle a NULL buffer passed to IMediaObject::ProcessOutput().

Alexandre Julliard julliard at winehq.org
Wed Feb 26 16:14:06 CST 2020


Module: wine
Branch: master
Commit: 1673af4ce01985664153623b6618ae8b6b25df18
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=1673af4ce01985664153623b6618ae8b6b25df18

Author: Zebediah Figura <z.figura12 at gmail.com>
Date:   Wed Feb 26 00:19:23 2020 -0600

mp3dmod: Handle a NULL buffer passed to IMediaObject::ProcessOutput().

Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/mp3dmod/mp3dmod.c       | 14 ++++++++++++++
 dlls/mp3dmod/tests/mp3dmod.c | 41 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+)

diff --git a/dlls/mp3dmod/mp3dmod.c b/dlls/mp3dmod/mp3dmod.c
index 65b48de711..05d56eff72 100644
--- a/dlls/mp3dmod/mp3dmod.c
+++ b/dlls/mp3dmod/mp3dmod.c
@@ -456,6 +456,20 @@ static HRESULT WINAPI MediaObject_ProcessOutput(IMediaObject *iface, DWORD flags
 
     buffers[0].dwStatus = 0;
 
+    if (!buffers[0].pBuffer)
+    {
+        while ((err = mpg123_read(This->mh, NULL, 0, &written)) == MPG123_NEW_FORMAT);
+        if (err == MPG123_NEED_MORE)
+            return S_OK;
+        else if (err == MPG123_ERR)
+            ERR("mpg123_read() failed: %s\n", mpg123_strerror(This->mh));
+        else if (err != MPG123_OK)
+            ERR("mpg123_read() returned %d\n", err);
+
+        buffers[0].dwStatus = DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE;
+        return S_OK;
+    }
+
     if (!This->buffer)
         return S_FALSE;
 
diff --git a/dlls/mp3dmod/tests/mp3dmod.c b/dlls/mp3dmod/tests/mp3dmod.c
index e66ad3ace0..9e845f5915 100644
--- a/dlls/mp3dmod/tests/mp3dmod.c
+++ b/dlls/mp3dmod/tests/mp3dmod.c
@@ -235,9 +235,50 @@ static void test_convert(void)
     ok(hr == S_FALSE, "got %#x\n", hr);
     ok(output.dwStatus == 0, "got %#x\n", output.dwStatus);
 
+    output.pBuffer = NULL;
+    output.dwStatus = 0xdeadbeef;
+    output.rtTimestamp = 0xdeadbeef;
+    output.rtTimelength = 0xdeadbeef;
+    hr = IMediaObject_ProcessOutput(dmo, DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER, 1, &output, &status);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+    ok(!output.pBuffer, "Got buffer %p.\n", output.pBuffer);
+    ok(!output.dwStatus, "Got status %#x.\n", output.dwStatus);
+    ok(output.rtTimestamp == 0xdeadbeef, "Got timestamp %s.\n", wine_dbgstr_longlong(output.rtTimestamp));
+    ok(output.rtTimelength == 0xdeadbeef, "Got length %s.\n", wine_dbgstr_longlong(output.rtTimelength));
+
     hr = IMediaObject_ProcessInput(dmo, 0, &inbuf.IMediaBuffer_iface, 0, 0, 0);
     ok(hr == S_OK, "got %#x\n", hr);
 
+    hr = IMediaObject_ProcessInput(dmo, 0, &inbuf.IMediaBuffer_iface, 0, 0, 0);
+    ok(hr == DMO_E_NOTACCEPTING, "Got hr %#x.\n", hr);
+
+    output.pBuffer = NULL;
+    output.dwStatus = 0xdeadbeef;
+    output.rtTimestamp = 0xdeadbeef;
+    output.rtTimelength = 0xdeadbeef;
+    hr = IMediaObject_ProcessOutput(dmo, DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER, 1, &output, &status);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+    ok(!output.pBuffer, "Got buffer %p.\n", output.pBuffer);
+    ok(output.dwStatus == O_INCOMPLETE, "Got status %#x.\n", output.dwStatus);
+    ok(output.rtTimestamp == 0xdeadbeef, "Got timestamp %s.\n", wine_dbgstr_longlong(output.rtTimestamp));
+    ok(output.rtTimelength == 0xdeadbeef, "Got length %s.\n", wine_dbgstr_longlong(output.rtTimelength));
+    ok(inbuf.refcount == 2, "Got refcount %d.\n", inbuf.refcount);
+
+    hr = IMediaObject_ProcessOutput(dmo, 0, 1, &output, &status);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+    ok(!output.pBuffer, "Got buffer %p.\n", output.pBuffer);
+    ok(output.dwStatus == O_INCOMPLETE, "Got status %#x.\n", output.dwStatus);
+    ok(output.rtTimestamp == 0xdeadbeef, "Got timestamp %s.\n", wine_dbgstr_longlong(output.rtTimestamp));
+    ok(output.rtTimelength == 0xdeadbeef, "Got length %s.\n", wine_dbgstr_longlong(output.rtTimelength));
+    ok(inbuf.refcount == 2, "Got refcount %d.\n", inbuf.refcount);
+
+    output.pBuffer = &outbuf.IMediaBuffer_iface;
+    outbuf.len = 0;
+    outbuf.maxlen = 5000;
+    hr = IMediaObject_ProcessOutput(dmo, 0, 1, &output, &status);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+    ok(outbuf.len > 1152 && outbuf.len <= 5000, "got %u\n", written);
+
     IMediaObject_Release(dmo);
     ok(inbuf.refcount == 1, "Got outstanding refcount %d.\n", inbuf.refcount);
     ok(outbuf.refcount == 1, "Got outstanding refcount %d.\n", outbuf.refcount);




More information about the wine-cvs mailing list