regedit: Make the dword and binary data parsing both more flexible and stricter.

Make sure it does not modify the value if the data is invalid.
This commit is contained in:
Francois Gouget 2007-06-14 11:46:29 +02:00 committed by Alexandre Julliard
parent 90d7707235
commit 804ec04472

View File

@ -70,59 +70,55 @@ if (!(p)) \
/******************************************************************************
* Converts a hex representation of a DWORD into a DWORD.
*/
static DWORD convertHexToDWord(char *str, BYTE *buf)
static BOOL convertHexToDWord(char* str, DWORD *dw)
{
DWORD dw;
char xbuf[9];
memcpy(xbuf,str,8);
xbuf[8]='\0';
sscanf(xbuf,"%08x",&dw);
memcpy(buf,&dw,sizeof(DWORD));
return sizeof(DWORD);
char dummy;
if (strlen(str) > 8 || sscanf(str, "%x%c", dw, &dummy) != 1) {
fprintf(stderr,"%s: ERROR, invalid hex value\n", getAppName());
return FALSE;
}
return TRUE;
}
/******************************************************************************
* Converts a hex comma separated values list into a hex list.
* The Hex input string must be in exactly the correct form.
* Converts a hex comma separated values list into a binary string.
*/
static DWORD convertHexCSVToHex(char *str, BYTE *buf, ULONG bufLen)
static BYTE* convertHexCSVToHex(char *str, DWORD *size)
{
char *s = str; /* Pointer to current */
char *b = (char*) buf; /* Pointer to result */
char *s;
BYTE *d, *data;
ULONG strLen = strlen(str);
ULONG strPos = 0;
DWORD byteCount = 0;
/* The worst case is 1 digit + 1 comma per byte */
*size=(strlen(str)+1)/2;
data=HeapAlloc(GetProcessHeap(), 0, *size);
CHECK_ENOUGH_MEMORY(data);
memset(buf, 0, bufLen);
/*
* warn the user if we are here with a string longer than 2 bytes that does
* not contains ",". It is more likely because the data is invalid.
*/
if ( ( strLen > 2) && ( strchr(str, ',') == NULL) )
fprintf(stderr,"%s: WARNING converting CSV hex stream with no comma, "
"input data seems invalid.\n", getAppName());
if (strLen > 3*bufLen)
fprintf(stderr,"%s: ERROR converting CSV hex stream. Too long\n",
getAppName());
while (strPos < strLen) {
char xbuf[3];
s = str;
d = data;
*size=0;
while (*s != '\0') {
UINT wc;
char dummy;
memcpy(xbuf,s,2); xbuf[2]='\0';
sscanf(xbuf,"%02x",&wc);
if (byteCount < bufLen)
*b++ =(unsigned char)wc;
if (s[1] != ',' && s[1] != '\0' && s[2] != ',' && s[2] != '\0') {
fprintf(stderr,"%s: ERROR converting CSV hex stream. Invalid sequence at '%s'\n",
getAppName(), s);
HeapFree(GetProcessHeap(), 0, data);
return NULL;
}
if (sscanf(s, "%x%c", &wc, &dummy) < 1 || dummy != ',') {
fprintf(stderr,"%s: ERROR converting CSV hex stream. Invalid value at '%s'\n",
getAppName(), s);
HeapFree(GetProcessHeap(), 0, data);
return NULL;
}
*d++ =(BYTE)wc;
(*size)++;
s+=3;
strPos+=3;
byteCount++;
s+=(wc < 0x10 ? 2 : 3);
}
return byteCount;
return data;
}
/******************************************************************************
@ -216,11 +212,9 @@ static void REGPROC_unescape_string(LPSTR str)
static HRESULT setValue(LPSTR val_name, LPSTR val_data)
{
HRESULT hRes;
DWORD dwDataType, dwParseType = 0;
DWORD dwDataType, dwParseType;
LPBYTE lpbData;
BYTE convert[KEY_MAX_LEN];
BYTE *bBigBuffer = 0;
DWORD dwLen;
DWORD dwData, dwLen;
if ( (val_name == NULL) || (val_data == NULL) )
return ERROR_INVALID_PARAMETER;
@ -248,21 +242,16 @@ static HRESULT setValue(LPSTR val_name, LPSTR val_data)
}
else if (dwParseType == REG_DWORD) /* Convert the dword types */
{
dwLen = convertHexToDWord(val_data, convert);
lpbData = convert;
if (!convertHexToDWord(val_data, &dwData))
return ERROR_INVALID_DATA;
lpbData = (BYTE*)&dwData;
dwLen = sizeof(dwData);
}
else if (dwParseType == REG_BINARY) /* Convert the binary data */
{
int b_len = strlen (val_data)+2/3;
if (b_len > KEY_MAX_LEN) {
bBigBuffer = HeapAlloc (GetProcessHeap(), 0, b_len);
CHECK_ENOUGH_MEMORY(bBigBuffer);
dwLen = convertHexCSVToHex(val_data, bBigBuffer, b_len);
lpbData = bBigBuffer;
} else {
dwLen = convertHexCSVToHex(val_data, convert, KEY_MAX_LEN);
lpbData = convert;
}
lpbData = convertHexCSVToHex(val_data, &dwLen);
if (!lpbData)
return ERROR_INVALID_DATA;
}
else /* unknown format */
{
@ -277,8 +266,8 @@ static HRESULT setValue(LPSTR val_name, LPSTR val_data)
dwDataType,
lpbData,
dwLen);
HeapFree (GetProcessHeap(), 0, bBigBuffer);
if (dwParseType == REG_BINARY)
HeapFree(GetProcessHeap(), 0, lpbData);
return hRes;
}