Commit 9aff5c88 authored by Hugh McMaster's avatar Hugh McMaster Committed by Alexandre Julliard

regedit: Validate REG_SZ import data before processing it any further.

parent 0481f31d
...@@ -264,13 +264,19 @@ static DWORD getDataType(LPWSTR *lpValue, DWORD* parse_type) ...@@ -264,13 +264,19 @@ static DWORD getDataType(LPWSTR *lpValue, DWORD* parse_type)
} }
/****************************************************************************** /******************************************************************************
* Replaces escape sequences with the characters. * Replaces escape sequences with their character equivalents and
* null-terminates the string on the first non-escaped double quote.
*
* Assigns a pointer to the remaining unparsed data in the line.
* Returns TRUE or FALSE to indicate whether a closing double quote was found.
*/ */
static int REGPROC_unescape_string(WCHAR* str) static BOOL REGPROC_unescape_string(WCHAR *str, WCHAR **unparsed)
{ {
int str_idx = 0; /* current character under analysis */ int str_idx = 0; /* current character under analysis */
int val_idx = 0; /* the last character of the unescaped string */ int val_idx = 0; /* the last character of the unescaped string */
int len = lstrlenW(str); int len = lstrlenW(str);
BOOL ret;
for (str_idx = 0; str_idx < len; str_idx++, val_idx++) { for (str_idx = 0; str_idx < len; str_idx++, val_idx++) {
if (str[str_idx] == '\\') { if (str[str_idx] == '\\') {
str_idx++; str_idx++;
...@@ -293,12 +299,17 @@ static int REGPROC_unescape_string(WCHAR* str) ...@@ -293,12 +299,17 @@ static int REGPROC_unescape_string(WCHAR* str)
str[val_idx] = str[str_idx]; str[val_idx] = str[str_idx];
break; break;
} }
} else if (str[str_idx] == '"') {
break;
} else { } else {
str[val_idx] = str[str_idx]; str[val_idx] = str[str_idx];
} }
} }
ret = (str[str_idx] == '"');
*unparsed = str + str_idx + 1;
str[val_idx] = '\0'; str[val_idx] = '\0';
return val_idx; return ret;
} }
static HKEY parseKeyName(LPWSTR lpKeyName, LPWSTR *lpKeyPath) static HKEY parseKeyName(LPWSTR lpKeyName, LPWSTR *lpKeyPath)
...@@ -397,12 +408,14 @@ static LONG setValue(WCHAR* val_name, WCHAR* val_data, BOOL is_unicode) ...@@ -397,12 +408,14 @@ static LONG setValue(WCHAR* val_name, WCHAR* val_data, BOOL is_unicode)
if (dwParseType == REG_SZ) /* no conversion for string */ if (dwParseType == REG_SZ) /* no conversion for string */
{ {
dwLen = REGPROC_unescape_string(val_data); WCHAR *line;
if(!dwLen || val_data[dwLen-1] != '"') if (!REGPROC_unescape_string(val_data, &line))
return ERROR_INVALID_DATA;
while (*line == ' ' || *line == '\t') line++;
if (*line && *line != ';')
return ERROR_INVALID_DATA; return ERROR_INVALID_DATA;
val_data[dwLen-1] = '\0'; /* remove last quotes */
lpbData = (BYTE*) val_data; lpbData = (BYTE*) val_data;
dwLen = dwLen * sizeof(WCHAR); /* size is in bytes */ dwLen = (lstrlenW(val_data) + 1) * sizeof(WCHAR); /* size is in bytes */
} }
else if (dwParseType == REG_DWORD) /* Convert the dword types */ else if (dwParseType == REG_DWORD) /* Convert the dword types */
{ {
...@@ -520,6 +533,7 @@ static void processSetValue(WCHAR* line, BOOL is_unicode) ...@@ -520,6 +533,7 @@ static void processSetValue(WCHAR* line, BOOL is_unicode)
{ {
WCHAR* val_name; /* registry value name */ WCHAR* val_name; /* registry value name */
WCHAR* val_data; /* registry value data */ WCHAR* val_data; /* registry value data */
WCHAR* p;
int line_idx = 0; /* current character under analysis */ int line_idx = 0; /* current character under analysis */
LONG res; LONG res;
...@@ -570,7 +584,7 @@ static void processSetValue(WCHAR* line, BOOL is_unicode) ...@@ -570,7 +584,7 @@ static void processSetValue(WCHAR* line, BOOL is_unicode)
while (line_idx > 0 && isspaceW(val_data[line_idx-1])) line_idx--; while (line_idx > 0 && isspaceW(val_data[line_idx-1])) line_idx--;
val_data[line_idx] = '\0'; val_data[line_idx] = '\0';
REGPROC_unescape_string(val_name); REGPROC_unescape_string(val_name, &p);
res = setValue(val_name, val_data, is_unicode); res = setValue(val_name, val_data, is_unicode);
if ( res != ERROR_SUCCESS ) if ( res != ERROR_SUCCESS )
output_message(STRING_SETVALUE_FAILED, val_name, currentKeyName); output_message(STRING_SETVALUE_FAILED, val_name, currentKeyName);
......
...@@ -560,8 +560,8 @@ static void test_invalid_import(void) ...@@ -560,8 +560,8 @@ static void test_invalid_import(void)
"[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n"
"\"Test15a\"=\"foo\"bar\"\n" "\"Test15a\"=\"foo\"bar\"\n"
"\"Test15b\"=\"foo\"\"bar\"\n\n"); "\"Test15b\"=\"foo\"\"bar\"\n\n");
todo_wine verify_reg_nonexist(hkey, "Test15a"); verify_reg_nonexist(hkey, "Test15a");
todo_wine verify_reg_nonexist(hkey, "Test15b"); verify_reg_nonexist(hkey, "Test15b");
exec_import_str("REGEDIT4\n\n" exec_import_str("REGEDIT4\n\n"
"[HKEY_CURRENT_USER\\" KEY_BASE "]\n" "[HKEY_CURRENT_USER\\" KEY_BASE "]\n"
...@@ -607,7 +607,7 @@ static void test_comments(void) ...@@ -607,7 +607,7 @@ static void test_comments(void)
"\"Wine5\"=dword:01020304 #comment\n" "\"Wine5\"=dword:01020304 #comment\n"
"\"Wine6\"=dword:02040608 ;comment\n\n"); "\"Wine6\"=dword:02040608 ;comment\n\n");
verify_reg_nonexist(hkey, "Wine3"); verify_reg_nonexist(hkey, "Wine3");
todo_wine verify_reg(hkey, "Wine4", REG_SZ, "Value 2", 8, 0); verify_reg(hkey, "Wine4", REG_SZ, "Value 2", 8, 0);
verify_reg_nonexist(hkey, "Wine5"); verify_reg_nonexist(hkey, "Wine5");
dword = 0x2040608; dword = 0x2040608;
verify_reg(hkey, "Wine6", REG_DWORD, &dword, sizeof(dword), 0); verify_reg(hkey, "Wine6", REG_DWORD, &dword, sizeof(dword), 0);
...@@ -639,9 +639,9 @@ static void test_comments(void) ...@@ -639,9 +639,9 @@ static void test_comments(void)
verify_reg_nonexist(hkey, "Comment2"); verify_reg_nonexist(hkey, "Comment2");
verify_reg_nonexist(hkey, "Comment3"); verify_reg_nonexist(hkey, "Comment3");
verify_reg_nonexist(hkey, "Comment4"); verify_reg_nonexist(hkey, "Comment4");
todo_wine verify_reg_nonexist(hkey, "Wine11"); verify_reg_nonexist(hkey, "Wine11");
verify_reg_nonexist(hkey, "Comment5"); verify_reg_nonexist(hkey, "Comment5");
verify_reg(hkey, "Wine12", REG_SZ, "Value 7", 8, TODO_REG_SIZE|TODO_REG_DATA); verify_reg(hkey, "Wine12", REG_SZ, "Value 7", 8, 0);
verify_reg_nonexist(hkey, "Comment6"); verify_reg_nonexist(hkey, "Comment6");
exec_import_str("REGEDIT4\n\n" exec_import_str("REGEDIT4\n\n"
...@@ -690,8 +690,8 @@ static void test_comments(void) ...@@ -690,8 +690,8 @@ static void test_comments(void)
"\"Wine26b\"=\"Value2\"\t\t;comment\n" "\"Wine26b\"=\"Value2\"\t\t;comment\n"
"\"Wine26c\"=\"Value3\" #comment\n" "\"Wine26c\"=\"Value3\" #comment\n"
"\"Wine26d\"=\"Value4\"\t\t#comment\n\n"); "\"Wine26d\"=\"Value4\"\t\t#comment\n\n");
todo_wine verify_reg(hkey, "Wine26a", REG_SZ, "Value1", 7, 0); verify_reg(hkey, "Wine26a", REG_SZ, "Value1", 7, 0);
todo_wine verify_reg(hkey, "Wine26b", REG_SZ, "Value2", 7, 0); verify_reg(hkey, "Wine26b", REG_SZ, "Value2", 7, 0);
verify_reg_nonexist(hkey, "Wine26c"); verify_reg_nonexist(hkey, "Wine26c");
verify_reg_nonexist(hkey, "Wine26d"); verify_reg_nonexist(hkey, "Wine26d");
......
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