Zebediah Figura : msacm32: Add invalid parameter checks for acmFormatDetails().

Alexandre Julliard julliard at winehq.org
Thu Jun 8 15:54:57 CDT 2017


Module: wine
Branch: master
Commit: 1e30f79b70c5717ef9b710bf81e4e12d1cc46534
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=1e30f79b70c5717ef9b710bf81e4e12d1cc46534

Author: Zebediah Figura <z.figura12 at gmail.com>
Date:   Wed Jun  7 16:07:51 2017 -0500

msacm32: Add invalid parameter checks for acmFormatDetails().

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/msacm32/format.c      |  37 +++++++++++--
 dlls/msacm32/tests/msacm.c | 131 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 165 insertions(+), 3 deletions(-)

diff --git a/dlls/msacm32/format.c b/dlls/msacm32/format.c
index 902807c..05d4fbe 100644
--- a/dlls/msacm32/format.c
+++ b/dlls/msacm32/format.c
@@ -68,7 +68,7 @@ static BOOL CALLBACK MSACM_FillFormatTagsCB(HACMDRIVERID hadid,
 	    HACMDRIVER		had;
 
 	    if (acmDriverOpen(&had, hadid, 0) == MMSYSERR_NOERROR) {
-		ACMFORMATDETAILSW	afd;
+		ACMFORMATDETAILSW	afd = {0};
                 unsigned int            i, len;
 		MMRESULT		mmr;
 		WCHAR			buffer[ACMFORMATDETAILS_FORMAT_CHARS+16];
@@ -87,6 +87,7 @@ static BOOL CALLBACK MSACM_FillFormatTagsCB(HACMDRIVERID hadid,
                     int j;
 
 		    afd.dwFormatIndex = i;
+		    afd.fdwSupport = 0;
 		    mmr = acmFormatDetailsW(had, &afd, ACM_FORMATDETAILSF_INDEX);
 		    if (mmr == MMSYSERR_NOERROR) {
                        lstrcpynW(buffer, afd.szFormat, ACMFORMATTAGDETAILS_FORMATTAG_CHARS + 1);
@@ -112,7 +113,7 @@ static BOOL CALLBACK MSACM_FillFormatTagsCB(HACMDRIVERID hadid,
 	    HACMDRIVER		had;
 
 	    if (acmDriverOpen(&had, hadid, 0) == MMSYSERR_NOERROR) {
-		ACMFORMATDETAILSW	afd;
+		ACMFORMATDETAILSW	afd = {0};
 
 		afd.cbStruct = sizeof(afd);
 		afd.dwFormatTag = paftd->dwFormatTag;
@@ -376,10 +377,14 @@ MMRESULT WINAPI acmFormatDetailsA(HACMDRIVER had, PACMFORMATDETAILSA pafd,
     ACMFORMATDETAILSW	afdw;
     MMRESULT		mmr;
 
+    if (!pafd)
+        return MMSYSERR_INVALPARAM;
+
     memset(&afdw, 0, sizeof(afdw));
     afdw.cbStruct = sizeof(afdw);
     afdw.dwFormatIndex = pafd->dwFormatIndex;
     afdw.dwFormatTag = pafd->dwFormatTag;
+    afdw.fdwSupport = pafd->fdwSupport;
     afdw.pwfx = pafd->pwfx;
     afdw.cbwfx = pafd->cbwfx;
 
@@ -401,11 +406,27 @@ MMRESULT WINAPI acmFormatDetailsW(HACMDRIVER had, PACMFORMATDETAILSW pafd, DWORD
     MMRESULT			mmr;
     static const WCHAR		fmt1[] = {'%','d',' ','H','z',0};
     static const WCHAR		fmt2[] = {';',' ','%','d',' ','b','i','t','s',0};
+    ACMFORMATTAGDETAILSW	aftd = {0};
 
     TRACE("(%p, %p, %d)\n", had, pafd, fdwDetails);
 
+    if (!pafd)
+        return MMSYSERR_INVALPARAM;
+
     if (pafd->cbStruct < sizeof(*pafd)) return MMSYSERR_INVALPARAM;
 
+    if (!pafd->pwfx)
+        return MMSYSERR_INVALPARAM;
+
+    if (pafd->cbwfx < sizeof(PCMWAVEFORMAT))
+        return MMSYSERR_INVALPARAM;
+
+    if (pafd->fdwSupport)
+        return MMSYSERR_INVALPARAM;
+
+    if (pafd->pwfx->wFormatTag == WAVE_FORMAT_UNKNOWN)
+        return MMSYSERR_INVALPARAM;
+
     switch (fdwDetails) {
     case ACM_FORMATDETAILSF_FORMAT:
 	if (pafd->dwFormatTag != pafd->pwfx->wFormatTag) {
@@ -430,7 +451,16 @@ MMRESULT WINAPI acmFormatDetailsW(HACMDRIVER had, PACMFORMATDETAILSW pafd, DWORD
 	}
 	break;
     case ACM_FORMATDETAILSF_INDEX:
-	/* should check pafd->dwFormatIndex < aftd->cStandardFormats */
+        aftd.cbStruct = sizeof(aftd);
+        aftd.dwFormatTag = pafd->dwFormatTag;
+        mmr = acmFormatTagDetailsW(had, &aftd, ACM_FORMATTAGDETAILSF_FORMATTAG);
+        if (mmr != MMSYSERR_NOERROR)
+            break;
+        if (pafd->dwFormatIndex >= aftd.cStandardFormats)
+        {
+            mmr = MMSYSERR_INVALPARAM;
+            break;
+        }
 	mmr = MSACM_Message(had, ACMDM_FORMAT_DETAILS, (LPARAM)pafd, fdwDetails);
 	break;
     default:
@@ -581,6 +611,7 @@ static BOOL MSACM_FormatEnumHelper(PWINE_ACMDRIVERID padid, HACMDRIVER had,
             for (j = 0; j < aftd.cStandardFormats; j++) {
                 pafd->dwFormatIndex = j;
                 pafd->dwFormatTag = aftd.dwFormatTag;
+                pafd->fdwSupport = 0;
                 if (acmFormatDetailsW(had, pafd, ACM_FORMATDETAILSF_INDEX) != MMSYSERR_NOERROR)
                     continue;
 
diff --git a/dlls/msacm32/tests/msacm.c b/dlls/msacm32/tests/msacm.c
index f5ab168..894dd53 100644
--- a/dlls/msacm32/tests/msacm.c
+++ b/dlls/msacm32/tests/msacm.c
@@ -38,9 +38,109 @@ static BOOL CALLBACK FormatTagEnumProc(HACMDRIVERID hadid,
                                        DWORD_PTR dwInstance,
                                        DWORD fdwSupport)
 {
+    MMRESULT rc;
+    HACMDRIVER had;
+
     if (winetest_interactive)
         trace("   Format 0x%04x: %s\n", paftd->dwFormatTag, paftd->szFormatTag);
 
+    rc = acmDriverOpen(&had, hadid, 0);
+    ok(rc == MMSYSERR_NOERROR || rc == MMSYSERR_NODRIVER,
+       "acmDriverOpen(): rc = %08x, should be %08x\n",
+       rc, MMSYSERR_NOERROR);
+
+    if (rc == MMSYSERR_NOERROR)
+    {
+        ACMFORMATDETAILSA fd = {0};
+        WAVEFORMATEX *pwfx;
+        DWORD i;
+
+        fd.cbStruct = sizeof(fd);
+        if (paftd->cbFormatSize < sizeof(WAVEFORMATEX))
+            pwfx = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WAVEFORMATEX));
+        else
+            pwfx = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, paftd->cbFormatSize);
+        fd.pwfx = pwfx;
+        fd.cbwfx = paftd->cbFormatSize;
+        fd.dwFormatTag = paftd->dwFormatTag;
+
+        /* try bad pwfx */
+        fd.pwfx = NULL;
+        rc = acmFormatDetailsA(had, &fd, ACM_FORMATDETAILSF_FORMAT);
+        ok(rc == MMSYSERR_INVALPARAM,
+           "acmFormatDetailsA(): rc = %08x, should be %08x\n",
+           rc, MMSYSERR_INVALPARAM);
+        fd.pwfx = pwfx;
+
+        /* try bad wFormatTag */
+        fd.pwfx->wFormatTag = WAVE_FORMAT_UNKNOWN;
+        rc = acmFormatDetailsA(had, &fd, ACM_FORMATDETAILSF_FORMAT);
+        ok(rc == MMSYSERR_INVALPARAM,
+           "acmFormatDetailsA(): rc = %08x, should be %08x\n",
+           rc, MMSYSERR_INVALPARAM);
+        fd.pwfx->wFormatTag = paftd->dwFormatTag;
+
+        /* try bad fdwSupport */
+        fd.fdwSupport = 0xdeadbeef;
+        rc = acmFormatDetailsA(had, &fd, ACM_FORMATDETAILSF_FORMAT);
+        ok(rc == MMSYSERR_INVALPARAM,
+           "acmFormatDetailsA(): rc = %08x, should be %08x\n",
+           rc, MMSYSERR_INVALPARAM);
+        fd.fdwSupport = 0;
+
+        /* try bad pwfx structure size */
+        fd.cbwfx = sizeof(PCMWAVEFORMAT)-1;
+        rc = acmFormatDetailsA(had, &fd, ACM_FORMATDETAILSF_FORMAT);
+        ok(rc == MMSYSERR_INVALPARAM,
+           "acmFormatDetailsA(): rc = %08x, should be %08x\n",
+           rc, MMSYSERR_INVALPARAM);
+        fd.cbwfx = paftd->cbFormatSize;
+
+        /* test bad parameters (all zero) */
+        rc = acmFormatDetailsA(had, &fd, ACM_FORMATDETAILSF_FORMAT);
+        ok(rc == ACMERR_NOTPOSSIBLE,
+           "acmFormatDetailsA(): rc = %08x, should be %08x\n",
+           rc, ACMERR_NOTPOSSIBLE);
+
+        /* test index */
+        for (i = 0; i < paftd->cStandardFormats; i++)
+        {
+            fd.dwFormatIndex = i;
+
+            fd.fdwSupport = 0;
+            fd.cbwfx = paftd->cbFormatSize;
+            fd.pwfx->cbSize = 0xbeef;
+            rc = acmFormatDetailsA(had, &fd, ACM_FORMATDETAILSF_INDEX);
+            ok(rc == MMSYSERR_NOERROR,
+               "acmFormatDetailsA(): rc = %08x, should be %08x\n",
+               rc, MMSYSERR_NOERROR);
+
+            /* Windows will write cbSize (and other data) even if the
+             * given cbwfx is not large enough */
+            fd.fdwSupport = 0;
+            fd.cbwfx = sizeof(PCMWAVEFORMAT);
+            fd.pwfx->cbSize = 0xbeef;
+            rc = acmFormatDetailsA(had, &fd, ACM_FORMATDETAILSF_INDEX);
+            todo_wine_if(rc != MMSYSERR_NOERROR) /* remove when fixed */
+            ok(rc == MMSYSERR_NOERROR,
+               "acmFormatDetailsA(): rc = %08x, should be %08x\n",
+               rc, MMSYSERR_NOERROR);
+            if (paftd->dwFormatTag != WAVE_FORMAT_PCM)
+                todo_wine_if(fd.pwfx->cbSize != paftd->cbFormatSize - sizeof(WAVEFORMATEX)) /* remove when fixed */
+                ok(fd.pwfx->cbSize == paftd->cbFormatSize - sizeof(WAVEFORMATEX),
+                   "got %d\n", fd.pwfx->cbSize);
+        }
+
+        /* one more */
+        fd.dwFormatIndex = paftd->cStandardFormats;
+        fd.fdwSupport = 0;
+        rc = acmFormatDetailsA(had, &fd, ACM_FORMATDETAILSF_INDEX);
+        ok(rc == MMSYSERR_INVALPARAM,
+           "acmFormatDetailsA(): rc = %08x, should be %08x\n",
+           rc, MMSYSERR_INVALPARAM);
+
+        HeapFree(GetProcessHeap(), 0, pwfx);
+    }
     return TRUE;
 }
 
@@ -411,6 +511,37 @@ static BOOL CALLBACK DriverEnumProc(HACMDRIVERID hadid,
                "acmFormatTagEnumA(): rc = %08x, should be %08x\n",
                rc, MMSYSERR_NOERROR);
 
+            /* try bad pointer */
+            rc = acmFormatDetailsA(had, NULL, ACM_FORMATDETAILSF_INDEX);
+            ok(rc == MMSYSERR_INVALPARAM,
+               "acmFormatDetailsA(): rc = %08x, should be %08x\n",
+               rc, MMSYSERR_INVALPARAM);
+
+            /* try bad structure size */
+            ZeroMemory(&fd, sizeof(fd));
+            rc = acmFormatDetailsA(had, &fd, ACM_FORMATDETAILSF_INDEX);
+            ok(rc == MMSYSERR_INVALPARAM,
+               "acmFormatDetailsA(): rc = %08x, should be %08x\n",
+               rc, MMSYSERR_INVALPARAM);
+
+            fd.cbStruct = sizeof(fd) - 1;
+            rc = acmFormatDetailsA(had, &fd, ACM_FORMATDETAILSF_INDEX);
+            ok(rc == MMSYSERR_INVALPARAM,
+               "acmFormatDetailsA(): rc = %08x, should be %08x\n",
+               rc, MMSYSERR_INVALPARAM);
+
+            fd.cbStruct = sizeof(fd);
+            fd.pwfx = pwfx;
+            ZeroMemory(fd.pwfx, dwSize);
+            fd.cbwfx = dwSize;
+            fd.dwFormatTag = WAVE_FORMAT_UNKNOWN;
+
+            /* try WAVE_FORMAT_UNKNOWN */
+            rc = acmFormatDetailsA(had, &fd, ACM_FORMATDETAILSF_INDEX);
+            ok(rc == MMSYSERR_INVALPARAM,
+               "acmFormatDetailsA(): rc = %08x, should be %08x\n",
+               rc, MMSYSERR_INVALPARAM);
+
             HeapFree(GetProcessHeap(), 0, pwfx);
 
             /* try invalid handle */




More information about the wine-cvs mailing list