Fixed reg_load_val

Reported by George Zaytsev from Positive Technologies
This commit is contained in:
akallabeth 2021-12-22 09:32:11 +01:00 committed by akallabeth
parent ce4a9ad1e7
commit df67d2796f

View File

@ -53,21 +53,40 @@ static struct reg_data_type REG_DATA_TYPE_TABLE[] = { { "\"", 1, REG_SZ },
{ "hex:", 4, REG_BINARY },
{ "hex(2):\"", 8, REG_EXPAND_SZ },
{ "hex(7):\"", 8, REG_MULTI_SZ },
{ "hex(b):\"", 8, REG_QWORD },
{ NULL, 0, 0 } };
{ "hex(b):\"", 8, REG_QWORD } };
static char* REG_DATA_TYPE_STRINGS[] = { "REG_NONE",
"REG_SZ",
"REG_EXPAND_SZ",
"REG_BINARY",
"REG_DWORD",
"REG_DWORD_BIG_ENDIAN",
"REG_LINK",
"REG_MULTI_SZ",
"REG_RESOURCE_LIST",
"REG_FULL_RESOURCE_DESCRIPTOR",
"REG_RESOURCE_REQUIREMENTS_LIST",
"REG_QWORD" };
static char* reg_data_type_string(DWORD type)
{
switch (type)
{
case REG_NONE:
return "REG_NONE";
case REG_SZ:
return "REG_SZ";
case REG_EXPAND_SZ:
return "REG_EXPAND_SZ";
case REG_BINARY:
return "REG_BINARY";
case REG_DWORD:
return "REG_DWORD";
case REG_DWORD_BIG_ENDIAN:
return "REG_DWORD_BIG_ENDIAN";
case REG_LINK:
return "REG_LINK";
case REG_MULTI_SZ:
return "REG_MULTI_SZ";
case REG_RESOURCE_LIST:
return "REG_RESOURCE_LIST";
case REG_FULL_RESOURCE_DESCRIPTOR:
return "REG_FULL_RESOURCE_DESCRIPTOR";
case REG_RESOURCE_REQUIREMENTS_LIST:
return "REG_RESOURCE_REQUIREMENTS_LIST";
case REG_QWORD:
return "REG_QWORD";
default:
return "REG_UNKNOWN";
}
}
static void reg_load_start(Reg* reg)
{
@ -115,14 +134,16 @@ static void reg_load_finish(Reg* reg)
static RegVal* reg_load_value(Reg* reg, RegKey* key)
{
int index;
char* p[5];
char* p[5] = { 0 };
size_t length;
char* name;
char* name = NULL;
char* type;
char* data;
RegVal* value;
RegVal* value = NULL;
WINPR_ASSERT(reg);
WINPR_ASSERT(key);
p[0] = reg->line + 1;
p[1] = strstr(p[0], "\"=");
p[2] = p[1] + 2;
@ -135,65 +156,81 @@ static RegVal* reg_load_value(Reg* reg, RegKey* key)
data = p[3] + 1;
length = p[1] - p[0];
name = (char*)malloc(length + 1);
if (length < 1)
goto fail;
name = (char*)calloc(length + 1, sizeof(char));
if (!name)
return NULL;
goto fail;
memcpy(name, p[0], length);
name[length] = '\0';
value = (RegVal*)malloc(sizeof(RegVal));
value = (RegVal*)calloc(1, sizeof(RegVal));
if (!value)
{
free(name);
return NULL;
}
goto fail;
value->name = name;
value->type = REG_NONE;
value->next = value->prev = NULL;
for (index = 0; REG_DATA_TYPE_TABLE[index].length > 0; index++)
for (index = 0; index < ARRAYSIZE(REG_DATA_TYPE_TABLE); index++)
{
if (strncmp(type, REG_DATA_TYPE_TABLE[index].tag, REG_DATA_TYPE_TABLE[index].length) == 0)
const struct reg_data_type* current = &REG_DATA_TYPE_TABLE[index];
WINPR_ASSERT(current->tag);
WINPR_ASSERT(current->length > 0);
WINPR_ASSERT(current->type != REG_NONE);
if (strncmp(type, current->tag, current->length) == 0)
{
value->type = REG_DATA_TYPE_TABLE[index].type;
value->type = current->type;
break;
}
}
if (value->type == REG_DWORD)
switch (value->type)
{
unsigned long val;
errno = 0;
val = strtoul(data, NULL, 16);
if ((errno != 0) || (val > UINT32_MAX))
case REG_DWORD:
{
free(value);
free(name);
return NULL;
unsigned long val;
errno = 0;
val = strtoul(data, NULL, 16);
if ((errno != 0) || (val > UINT32_MAX))
goto fail;
value->data.dword = (DWORD)val;
}
value->data.dword = val;
}
else if (value->type == REG_SZ)
{
p[4] = strchr(data, '"');
p[4][0] = '\0';
value->data.string = _strdup(data);
if (!value->data.string)
break;
case REG_SZ:
{
free(value);
free(name);
return NULL;
size_t len, cmp;
char* end;
char* start = strchr(data, '"');
if (!start)
goto fail;
/* Check for terminating quote, check it is the last symbol */
len = strlen(start);
end = strchr(start + 1, '"');
if (!end)
goto fail;
cmp = end - start + 1;
if (len != cmp)
goto fail;
if (start[0] == '"')
start++;
if (end[0] == '"')
end[0] = '\0';
value->data.string = _strdup(start);
if (!value->data.string)
goto fail;
}
}
else
{
WLog_ERR(TAG, "unimplemented format: %s", REG_DATA_TYPE_STRINGS[value->type]);
break;
default:
WLog_ERR(TAG, "unimplemented format: %s", reg_data_type_string(value->type));
break;
}
if (!key->values)
@ -214,6 +251,11 @@ static RegVal* reg_load_value(Reg* reg, RegKey* key)
}
return value;
fail:
free(value);
free(name);
return NULL;
}
static BOOL reg_load_has_next_line(Reg* reg)
@ -375,7 +417,7 @@ static void reg_unload_value(Reg* reg, RegVal* value)
}
else
{
WLog_ERR(TAG, "unimplemented format: %s", REG_DATA_TYPE_STRINGS[value->type]);
WLog_ERR(TAG, "unimplemented format: %s", reg_data_type_string(value->type));
}
free(value);