From 804ec044727028892e76b74aeeda2c056482181c Mon Sep 17 00:00:00 2001 From: Francois Gouget Date: Thu, 14 Jun 2007 11:46:29 +0200 Subject: [PATCH] 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. --- programs/regedit/regproc.c | 105 +++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 58 deletions(-) diff --git a/programs/regedit/regproc.c b/programs/regedit/regproc.c index befa971a39e..368f5c5be59 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 */ + 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; }