Module: wine Branch: master Commit: f5e4dad68cd32e5b9a3cfc1cea284c5bf7c276f3 URL: http://source.winehq.org/git/wine.git/?a=commit;h=f5e4dad68cd32e5b9a3cfc1cea...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Sun Dec 11 14:46:16 2016 +0300
msi: Fix handling of NULL buffer in MsiGetProductPropertyW() (Coverity).
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com Signed-off-by: Hans Leidekker hans@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/msi/msi.c | 8 ++-- dlls/msi/tests/package.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+), 4 deletions(-)
diff --git a/dlls/msi/msi.c b/dlls/msi/msi.c index 892c756..ce29c26 100644 --- a/dlls/msi/msi.c +++ b/dlls/msi/msi.c @@ -2714,17 +2714,17 @@ UINT WINAPI MsiGetProductPropertyW(MSIHANDLE hProduct, LPCWSTR szProperty,
if (lstrlenW(val) >= *pccbValue) { - lstrcpynW(szValue, val, *pccbValue); - *pccbValue = lstrlenW(val); + if (szValue) lstrcpynW(szValue, val, *pccbValue); r = ERROR_MORE_DATA; } else { - lstrcpyW(szValue, val); - *pccbValue = lstrlenW(val); + if (szValue) lstrcpyW(szValue, val); r = ERROR_SUCCESS; }
+ *pccbValue = lstrlenW(val); + done: if (view) { diff --git a/dlls/msi/tests/package.c b/dlls/msi/tests/package.c index 6bdacd7..748d25f 100644 --- a/dlls/msi/tests/package.c +++ b/dlls/msi/tests/package.c @@ -8293,13 +8293,21 @@ static void test_emptypackage(void)
static void test_MsiGetProductProperty(void) { + static const WCHAR prodcode_propW[] = {'P','r','o','d','u','c','t','C','o','d','e',0}; + static const WCHAR nonexistantW[] = {'I','D','o','n','t','E','x','i','s','t',0}; + static const WCHAR newpropW[] = {'N','e','w','P','r','o','p','e','r','t','y',0}; + static const WCHAR appleW[] = {'a','p','p','l','e',0}; + static const WCHAR emptyW[] = {0}; + WCHAR valW[MAX_PATH]; MSIHANDLE hprod, hdb; CHAR val[MAX_PATH]; CHAR path[MAX_PATH]; CHAR query[MAX_PATH]; CHAR keypath[MAX_PATH*2]; CHAR prodcode[MAX_PATH]; + WCHAR prodcodeW[MAX_PATH]; CHAR prod_squashed[MAX_PATH]; + WCHAR prod_squashedW[MAX_PATH]; HKEY prodkey, userkey, props; DWORD size; LONG res; @@ -8310,6 +8318,8 @@ static void test_MsiGetProductProperty(void) lstrcatA(path, "\");
create_test_guid(prodcode, prod_squashed); + MultiByteToWideChar(CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH); + squash_guid(prodcodeW, prod_squashedW);
if (is_wow64) access |= KEY_WOW64_64KEY; @@ -8400,6 +8410,15 @@ static void test_MsiGetProductProperty(void) "Expected val to be unchanged, got "%s"\n", val); ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
+ size = MAX_PATH; + lstrcpyW(valW, appleW); + r = MsiGetProductPropertyW(0xdeadbeef, prodcode_propW, valW, &size); + ok(r == ERROR_INVALID_HANDLE, + "Expected ERROR_INVALID_HANDLE, got %d\n", r); + ok(!lstrcmpW(valW, appleW), + "Expected val to be unchanged, got %s\n", wine_dbgstr_w(valW)); + ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); + /* szProperty is NULL */ size = MAX_PATH; lstrcpyA(val, "apple"); @@ -8410,6 +8429,15 @@ static void test_MsiGetProductProperty(void) "Expected val to be unchanged, got "%s"\n", val); ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
+ size = MAX_PATH; + lstrcpyW(valW, appleW); + r = MsiGetProductPropertyW(hprod, NULL, valW, &size); + ok(r == ERROR_INVALID_PARAMETER, + "Expected ERROR_INVALID_PARAMETER, got %d\n", r); + ok(!lstrcmpW(valW, appleW), + "Expected val to be unchanged, got %s\n", wine_dbgstr_w(valW)); + ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); + /* szProperty is empty */ size = MAX_PATH; lstrcpyA(val, "apple"); @@ -8418,6 +8446,13 @@ static void test_MsiGetProductProperty(void) ok(!lstrcmpA(val, ""), "Expected "", got "%s"\n", val); ok(size == 0, "Expected 0, got %d\n", size);
+ size = MAX_PATH; + lstrcpyW(valW, appleW); + r = MsiGetProductPropertyW(hprod, emptyW, valW, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(*valW == 0, "Expected "", got %s\n", wine_dbgstr_w(valW)); + ok(size == 0, "Expected 0, got %d\n", size); + /* get the property */ size = MAX_PATH; lstrcpyA(val, "apple"); @@ -8428,6 +8463,15 @@ static void test_MsiGetProductProperty(void) ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
+ size = MAX_PATH; + lstrcpyW(valW, appleW); + r = MsiGetProductPropertyW(hprod, prodcode_propW, valW, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpW(valW, prodcodeW), + "Expected %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW)); + ok(size == lstrlenW(prodcodeW), + "Expected %d, got %d\n", lstrlenW(prodcodeW), size); + /* lpValueBuf is NULL */ size = MAX_PATH; r = MsiGetProductPropertyA(hprod, "ProductCode", NULL, &size); @@ -8435,6 +8479,12 @@ static void test_MsiGetProductProperty(void) ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
+ size = MAX_PATH; + r = MsiGetProductPropertyW(hprod, prodcode_propW, NULL, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(size == lstrlenW(prodcodeW), + "Expected %d, got %d\n", lstrlenW(prodcodeW), size); + /* pcchValueBuf is NULL */ lstrcpyA(val, "apple"); r = MsiGetProductPropertyA(hprod, "ProductCode", val, NULL); @@ -8445,6 +8495,15 @@ static void test_MsiGetProductProperty(void) ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
+ lstrcpyW(valW, appleW); + r = MsiGetProductPropertyW(hprod, prodcode_propW, valW, NULL); + ok(r == ERROR_INVALID_PARAMETER, + "Expected ERROR_INVALID_PARAMETER, got %d\n", r); + ok(!lstrcmpW(valW, appleW), + "Expected val to be unchanged, got %s\n", wine_dbgstr_w(valW)); + ok(size == lstrlenW(prodcodeW), + "Expected %d, got %d\n", lstrlenW(prodcodeW), size); + /* pcchValueBuf is too small */ size = 4; lstrcpyA(val, "apple"); @@ -8455,6 +8514,15 @@ static void test_MsiGetProductProperty(void) ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
+ size = 4; + lstrcpyW(valW, appleW); + r = MsiGetProductPropertyW(hprod, prodcode_propW, valW, &size); + ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r); + ok(!memcmp(valW, prodcodeW, 3 * sizeof(WCHAR)), + "Expected first 3 chars of %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW)); + ok(size == lstrlenW(prodcodeW), + "Expected %d, got %d\n", lstrlenW(prodcodeW), size); + /* pcchValueBuf does not leave room for NULL terminator */ size = lstrlenA(prodcode); lstrcpyA(val, "apple"); @@ -8465,6 +8533,15 @@ static void test_MsiGetProductProperty(void) ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
+ size = lstrlenW(prodcodeW); + lstrcpyW(valW, appleW); + r = MsiGetProductPropertyW(hprod, prodcode_propW, valW, &size); + ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r); + ok(!memcmp(valW, prodcodeW, lstrlenW(prodcodeW) - 1), + "Expected first 37 chars of %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW)); + ok(size == lstrlenW(prodcodeW), + "Expected %d, got %d\n", lstrlenW(prodcodeW), size); + /* pcchValueBuf has enough room for NULL terminator */ size = lstrlenA(prodcode) + 1; lstrcpyA(val, "apple"); @@ -8475,6 +8552,15 @@ static void test_MsiGetProductProperty(void) ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
+ size = lstrlenW(prodcodeW) + 1; + lstrcpyW(valW, appleW); + r = MsiGetProductPropertyW(hprod, prodcode_propW, valW, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpW(valW, prodcodeW), + "Expected %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW)); + ok(size == lstrlenW(prodcodeW), + "Expected %d, got %d\n", lstrlenW(prodcodeW), size); + /* nonexistent property */ size = MAX_PATH; lstrcpyA(val, "apple"); @@ -8483,6 +8569,13 @@ static void test_MsiGetProductProperty(void) ok(!lstrcmpA(val, ""), "Expected "", got "%s"\n", val); ok(size == 0, "Expected 0, got %d\n", size);
+ size = MAX_PATH; + lstrcpyW(valW, appleW); + r = MsiGetProductPropertyW(hprod, nonexistantW, valW, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpW(valW, emptyW), "Expected "", got %s\n", wine_dbgstr_w(valW)); + ok(size == 0, "Expected 0, got %d\n", size); + r = MsiSetPropertyA(hprod, "NewProperty", "value"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
@@ -8494,6 +8587,13 @@ static void test_MsiGetProductProperty(void) ok(!lstrcmpA(val, ""), "Expected "", got "%s"\n", val); ok(size == 0, "Expected 0, got %d\n", size);
+ size = MAX_PATH; + lstrcpyW(valW, appleW); + r = MsiGetProductPropertyW(hprod, newpropW, valW, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpW(valW, emptyW), "Expected "", got %s\n", wine_dbgstr_w(valW)); + ok(size == 0, "Expected 0, got %d\n", size); + r = MsiSetPropertyA(hprod, "ProductCode", "value"); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
@@ -8507,6 +8607,15 @@ static void test_MsiGetProductProperty(void) ok(size == lstrlenA(prodcode), "Expected %d, got %d\n", lstrlenA(prodcode), size);
+ size = MAX_PATH; + lstrcpyW(valW, appleW); + r = MsiGetProductPropertyW(hprod, prodcode_propW, valW, &size); + ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); + ok(!lstrcmpW(valW, prodcodeW), + "Expected %s, got %s\n", wine_dbgstr_w(prodcodeW), wine_dbgstr_w(valW)); + ok(size == lstrlenW(prodcodeW), + "Expected %d, got %d\n", lstrlenW(prodcodeW), size); + MsiCloseHandle(hprod);
RegDeleteValueA(props, "LocalPackage");