From: Hans Leidekker Subject: msi: Format registry values before interpreting value type. Message-Id: <1414674546.10079.1.camel@codeweavers.com> Date: Thu, 30 Oct 2014 14:09:06 +0100 --- dlls/msi/action.c | 24 ++++++++++-------------- dlls/msi/tests/action.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 58 insertions(+), 16 deletions(-) diff --git a/dlls/msi/action.c b/dlls/msi/action.c index e310ba3..66c2858 100644 --- a/dlls/msi/action.c +++ b/dlls/msi/action.c @@ -2438,9 +2438,9 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package) return MSI_SetFeatureStates(package); } -static BYTE *parse_value( MSIPACKAGE *package, const WCHAR *value, DWORD *type, DWORD *size ) +static BYTE *parse_value( MSIPACKAGE *package, const WCHAR *value, DWORD len, DWORD *type, DWORD *size ) { - BYTE *data = NULL; + BYTE *data; if (!value) { @@ -2529,19 +2529,18 @@ static BYTE *parse_value( MSIPACKAGE *package, const WCHAR *value, DWORD *type, else { const WCHAR *ptr = value; - DWORD len; *type = REG_SZ; if (value[0] == '#') { - ptr++; + ptr++; len--; if (value[1] == '%') { - ptr++; + ptr++; len--; *type = REG_EXPAND_SZ; } } - len = deformat_string( package, ptr, (WCHAR **)&data ); + data = (BYTE *)msi_strdupW( ptr, len ); if (len > strlenW( (const WCHAR *)data )) *type = REG_MULTI_SZ; *size = (len + 1) * sizeof(WCHAR); } @@ -2872,14 +2871,11 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param) msi_free(keypath); return ERROR_FUNCTION_FAILED; } - str = msi_record_get_string( row, 5, &len ); - if (str && len > strlenW( str )) - { - type = REG_MULTI_SZ; - new_size = (len + 1) * sizeof(WCHAR); - new_value = (BYTE *)msi_strdupW( str, len ); - } - else new_value = parse_value( package, str, &type, &new_size ); + str = msi_record_get_string( row, 5, NULL ); + len = deformat_string( package, str, &deformated ); + new_value = parse_value( package, deformated, len, &type, &new_size ); + + msi_free( deformated ); deformat_string(package, name, &deformated); if (!is_special_entry( name )) diff --git a/dlls/msi/tests/action.c b/dlls/msi/tests/action.c index 9f1651d..a8903d9 100644 --- a/dlls/msi/tests/action.c +++ b/dlls/msi/tests/action.c @@ -186,7 +186,8 @@ static const char property_dat[] = "SERVNAME2\tTestService2\n" "SERVDISP\tTestServiceDisp\n" "SERVDISP2\tTestServiceDisp2\n" - "MSIFASTINSTALL\t1\n"; + "MSIFASTINSTALL\t1\n" + "regdata15\t#x01\n"; static const char environment_dat[] = "Environment\tName\tValue\tComponent_\n" @@ -514,7 +515,11 @@ static const char wrv_registry_dat[] = "regdata8\t2\tSOFTWARE\\Wine\\msitest\tValue4\tone[~]two\taugustus\n" "regdata9\t2\tSOFTWARE\\Wine\\msitest\tValue5\t[~]one[~]two[~]three\taugustus\n" "regdata10\t2\tSOFTWARE\\Wine\\msitest\tValue6\t[~]\taugustus\n" - "regdata11\t2\tSOFTWARE\\Wine\\msitest\tValue7\t[~]two\taugustus\n"; + "regdata11\t2\tSOFTWARE\\Wine\\msitest\tValue7\t[~]two\taugustus\n" + "regdata12\t2\tSOFTWARE\\Wine\\msitest\tValue8\t#1\taugustus\n" + "regdata13\t2\tSOFTWARE\\Wine\\msitest\tValue9\t#x1\taugustus\n" + "regdata14\t2\tSOFTWARE\\Wine\\msitest\tValue10\t#x01\taugustus\n" + "regdata15\t2\tSOFTWARE\\Wine\\msitest\tValue11\t[regdata15]\taugustus\n"; static const char cf_directory_dat[] = "Directory\tDirectory_Parent\tDefaultDir\n" @@ -4923,6 +4928,7 @@ static void test_write_registry_values(void) HKEY hkey; DWORD type, size; CHAR path[MAX_PATH]; + BYTE buf[8]; if (is_process_limited()) { @@ -5055,6 +5061,42 @@ static void test_write_registry_values(void) ok(size == 5, "Expected 5, got %d\n", size); ok(type == REG_MULTI_SZ, "Expected REG_MULTI_SZ, got %d\n", type); + size = sizeof(buf); + type = 0xdeadbeef; + memset(buf, 0, size); + res = RegQueryValueExA(hkey, "Value8", NULL, &type, buf, &size); + ok(res == ERROR_SUCCESS, "got %u\n", res); + ok(*(DWORD *)buf == 1, "got %u\n", *(DWORD *)buf); + ok(size == 4, "got %u\n", size); + ok(type == REG_DWORD, "got %u\n", type); + + size = sizeof(buf); + type = 0xdeadbeef; + memset(buf, 0, size); + res = RegQueryValueExA(hkey, "Value9", NULL, &type, buf, &size); + ok(res == ERROR_SUCCESS, "got %u\n", res); + ok(buf[0] == 1, "got %u\n", buf[0]); + ok(size == 1, "got %u\n", size); + ok(type == REG_BINARY, "got %u\n", type); + + size = sizeof(buf); + type = 0xdeadbeef; + memset(buf, 0, size); + res = RegQueryValueExA(hkey, "Value10", NULL, &type, buf, &size); + ok(res == ERROR_SUCCESS, "got %u\n", res); + ok(buf[0] == 1, "got %u\n", buf[0]); + ok(size == 1, "got %u\n", size); + ok(type == REG_BINARY, "got %u\n", type); + + size = sizeof(buf); + type = 0xdeadbeef; + memset(buf, 0, size); + res = RegQueryValueExA(hkey, "Value11", NULL, &type, buf, &size); + ok(res == ERROR_SUCCESS, "got %u\n", res); + ok(buf[0] == 1, "got %u\n", buf[0]); + ok(size == 1, "got %u\n", size); + ok(type == REG_BINARY, "got %u\n", type); + RegDeleteValueA(hkey, "Value"); RegDeleteValueA(hkey, "Value1"); RegDeleteValueA(hkey, "Value2"); @@ -5063,6 +5105,10 @@ static void test_write_registry_values(void) RegDeleteValueA(hkey, "Value5"); RegDeleteValueA(hkey, "Value6"); RegDeleteValueA(hkey, "Value7"); + RegDeleteValueA(hkey, "Value8"); + RegDeleteValueA(hkey, "Value9"); + RegDeleteValueA(hkey, "Value10"); + RegDeleteValueA(hkey, "Value11"); RegCloseKey(hkey); RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine\\msitest");