[5/8] regedit: Make the dword and binary data parsing both more
flexible and stricter.
Francois Gouget
fgouget at codeweavers.com
Thu Jun 14 04:46:29 CDT 2007
Make sure it does not modify the value if the data is invalid.
---
Testing on Windows 98 and Windows XP shows that the native regedit
allows the following:
"Good1"=hex:1,2,3
"Good2"=hex:1,2,
"Good3"=dword:1
However it ignores following because they are invalid:
"Bad1"=hex:123,4
"Bad2"=hex:12,,34
"Bad3"=hex:12,,
"Bad4"=hex:1,u,2
"Bad5"=hex:1u,2
"Bad6"=dword:123456789
"Bad7"=dword:u
"Bad8"=dword:1u2
This patch also gets rid of this very dubious piece of code:
int b_len = strlen (val_data)+2/3;
programs/regedit/regproc.c | 109 ++++++++++++++++++++------------------------
1 files changed, 49 insertions(+), 60 deletions(-)
diff --git a/programs/regedit/regproc.c b/programs/regedit/regproc.c
index 0840c46..368f5c5 100644
--- a/programs/regedit/regproc.c
+++ b/programs/regedit/regproc.c
@@ -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 */
-
- ULONG strLen = strlen(str);
- ULONG strPos = 0;
- DWORD byteCount = 0;
-
- 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];
+ char *s;
+ BYTE *d, *data;
+
+ /* The worst case is 1 digit + 1 comma per byte */
+ *size=(strlen(str)+1)/2;
+ data=HeapAlloc(GetProcessHeap(), 0, *size);
+ CHECK_ENOUGH_MEMORY(data);
+
+ 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;
+ 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;
}
--
1.4.4.4
More information about the wine-patches
mailing list