Commit f5e4dad6 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

msi: Fix handling of NULL buffer in MsiGetProductPropertyW() (Coverity).

parent 93829e4b
...@@ -2714,17 +2714,17 @@ UINT WINAPI MsiGetProductPropertyW(MSIHANDLE hProduct, LPCWSTR szProperty, ...@@ -2714,17 +2714,17 @@ UINT WINAPI MsiGetProductPropertyW(MSIHANDLE hProduct, LPCWSTR szProperty,
if (lstrlenW(val) >= *pccbValue) if (lstrlenW(val) >= *pccbValue)
{ {
lstrcpynW(szValue, val, *pccbValue); if (szValue) lstrcpynW(szValue, val, *pccbValue);
*pccbValue = lstrlenW(val);
r = ERROR_MORE_DATA; r = ERROR_MORE_DATA;
} }
else else
{ {
lstrcpyW(szValue, val); if (szValue) lstrcpyW(szValue, val);
*pccbValue = lstrlenW(val);
r = ERROR_SUCCESS; r = ERROR_SUCCESS;
} }
*pccbValue = lstrlenW(val);
done: done:
if (view) if (view)
{ {
......
...@@ -8293,13 +8293,21 @@ static void test_emptypackage(void) ...@@ -8293,13 +8293,21 @@ static void test_emptypackage(void)
static void test_MsiGetProductProperty(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; MSIHANDLE hprod, hdb;
CHAR val[MAX_PATH]; CHAR val[MAX_PATH];
CHAR path[MAX_PATH]; CHAR path[MAX_PATH];
CHAR query[MAX_PATH]; CHAR query[MAX_PATH];
CHAR keypath[MAX_PATH*2]; CHAR keypath[MAX_PATH*2];
CHAR prodcode[MAX_PATH]; CHAR prodcode[MAX_PATH];
WCHAR prodcodeW[MAX_PATH];
CHAR prod_squashed[MAX_PATH]; CHAR prod_squashed[MAX_PATH];
WCHAR prod_squashedW[MAX_PATH];
HKEY prodkey, userkey, props; HKEY prodkey, userkey, props;
DWORD size; DWORD size;
LONG res; LONG res;
...@@ -8310,6 +8318,8 @@ static void test_MsiGetProductProperty(void) ...@@ -8310,6 +8318,8 @@ static void test_MsiGetProductProperty(void)
lstrcatA(path, "\\"); lstrcatA(path, "\\");
create_test_guid(prodcode, prod_squashed); create_test_guid(prodcode, prod_squashed);
MultiByteToWideChar(CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH);
squash_guid(prodcodeW, prod_squashedW);
if (is_wow64) if (is_wow64)
access |= KEY_WOW64_64KEY; access |= KEY_WOW64_64KEY;
...@@ -8400,6 +8410,15 @@ static void test_MsiGetProductProperty(void) ...@@ -8400,6 +8410,15 @@ static void test_MsiGetProductProperty(void)
"Expected val to be unchanged, got \"%s\"\n", val); "Expected val to be unchanged, got \"%s\"\n", val);
ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); 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 */ /* szProperty is NULL */
size = MAX_PATH; size = MAX_PATH;
lstrcpyA(val, "apple"); lstrcpyA(val, "apple");
...@@ -8410,6 +8429,15 @@ static void test_MsiGetProductProperty(void) ...@@ -8410,6 +8429,15 @@ static void test_MsiGetProductProperty(void)
"Expected val to be unchanged, got \"%s\"\n", val); "Expected val to be unchanged, got \"%s\"\n", val);
ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size); 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 */ /* szProperty is empty */
size = MAX_PATH; size = MAX_PATH;
lstrcpyA(val, "apple"); lstrcpyA(val, "apple");
...@@ -8418,6 +8446,13 @@ static void test_MsiGetProductProperty(void) ...@@ -8418,6 +8446,13 @@ static void test_MsiGetProductProperty(void)
ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val); ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
ok(size == 0, "Expected 0, got %d\n", size); 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 */ /* get the property */
size = MAX_PATH; size = MAX_PATH;
lstrcpyA(val, "apple"); lstrcpyA(val, "apple");
...@@ -8428,6 +8463,15 @@ static void test_MsiGetProductProperty(void) ...@@ -8428,6 +8463,15 @@ static void test_MsiGetProductProperty(void)
ok(size == lstrlenA(prodcode), ok(size == lstrlenA(prodcode),
"Expected %d, got %d\n", lstrlenA(prodcode), size); "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 */ /* lpValueBuf is NULL */
size = MAX_PATH; size = MAX_PATH;
r = MsiGetProductPropertyA(hprod, "ProductCode", NULL, &size); r = MsiGetProductPropertyA(hprod, "ProductCode", NULL, &size);
...@@ -8435,6 +8479,12 @@ static void test_MsiGetProductProperty(void) ...@@ -8435,6 +8479,12 @@ static void test_MsiGetProductProperty(void)
ok(size == lstrlenA(prodcode), ok(size == lstrlenA(prodcode),
"Expected %d, got %d\n", lstrlenA(prodcode), size); "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 */ /* pcchValueBuf is NULL */
lstrcpyA(val, "apple"); lstrcpyA(val, "apple");
r = MsiGetProductPropertyA(hprod, "ProductCode", val, NULL); r = MsiGetProductPropertyA(hprod, "ProductCode", val, NULL);
...@@ -8445,6 +8495,15 @@ static void test_MsiGetProductProperty(void) ...@@ -8445,6 +8495,15 @@ static void test_MsiGetProductProperty(void)
ok(size == lstrlenA(prodcode), ok(size == lstrlenA(prodcode),
"Expected %d, got %d\n", lstrlenA(prodcode), size); "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 */ /* pcchValueBuf is too small */
size = 4; size = 4;
lstrcpyA(val, "apple"); lstrcpyA(val, "apple");
...@@ -8455,6 +8514,15 @@ static void test_MsiGetProductProperty(void) ...@@ -8455,6 +8514,15 @@ static void test_MsiGetProductProperty(void)
ok(size == lstrlenA(prodcode), ok(size == lstrlenA(prodcode),
"Expected %d, got %d\n", lstrlenA(prodcode), size); "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 */ /* pcchValueBuf does not leave room for NULL terminator */
size = lstrlenA(prodcode); size = lstrlenA(prodcode);
lstrcpyA(val, "apple"); lstrcpyA(val, "apple");
...@@ -8465,6 +8533,15 @@ static void test_MsiGetProductProperty(void) ...@@ -8465,6 +8533,15 @@ static void test_MsiGetProductProperty(void)
ok(size == lstrlenA(prodcode), ok(size == lstrlenA(prodcode),
"Expected %d, got %d\n", lstrlenA(prodcode), size); "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 */ /* pcchValueBuf has enough room for NULL terminator */
size = lstrlenA(prodcode) + 1; size = lstrlenA(prodcode) + 1;
lstrcpyA(val, "apple"); lstrcpyA(val, "apple");
...@@ -8475,6 +8552,15 @@ static void test_MsiGetProductProperty(void) ...@@ -8475,6 +8552,15 @@ static void test_MsiGetProductProperty(void)
ok(size == lstrlenA(prodcode), ok(size == lstrlenA(prodcode),
"Expected %d, got %d\n", lstrlenA(prodcode), size); "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 */ /* nonexistent property */
size = MAX_PATH; size = MAX_PATH;
lstrcpyA(val, "apple"); lstrcpyA(val, "apple");
...@@ -8483,6 +8569,13 @@ static void test_MsiGetProductProperty(void) ...@@ -8483,6 +8569,13 @@ static void test_MsiGetProductProperty(void)
ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val); ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
ok(size == 0, "Expected 0, got %d\n", size); 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"); r = MsiSetPropertyA(hprod, "NewProperty", "value");
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
...@@ -8494,6 +8587,13 @@ static void test_MsiGetProductProperty(void) ...@@ -8494,6 +8587,13 @@ static void test_MsiGetProductProperty(void)
ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val); ok(!lstrcmpA(val, ""), "Expected \"\", got \"%s\"\n", val);
ok(size == 0, "Expected 0, got %d\n", size); 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"); r = MsiSetPropertyA(hprod, "ProductCode", "value");
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r); ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
...@@ -8507,6 +8607,15 @@ static void test_MsiGetProductProperty(void) ...@@ -8507,6 +8607,15 @@ static void test_MsiGetProductProperty(void)
ok(size == lstrlenA(prodcode), ok(size == lstrlenA(prodcode),
"Expected %d, got %d\n", lstrlenA(prodcode), size); "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); MsiCloseHandle(hprod);
RegDeleteValueA(props, "LocalPackage"); RegDeleteValueA(props, "LocalPackage");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment