Use dynamically allocated heap allocated buffers in
HTTP_InterpretHTTPHeader to avoid buffer overflow on large headers.
This commit is contained in:
parent
12df80a748
commit
b72a682751
|
@ -93,7 +93,7 @@ BOOL HTTP_GetResponseHeaders(LPWININETHTTPREQW lpwhr);
|
||||||
BOOL HTTP_ProcessHeader(LPWININETHTTPREQW lpwhr, LPCWSTR field, LPCWSTR value, DWORD dwModifier);
|
BOOL HTTP_ProcessHeader(LPWININETHTTPREQW lpwhr, LPCWSTR field, LPCWSTR value, DWORD dwModifier);
|
||||||
BOOL HTTP_ReplaceHeaderValue( LPHTTPHEADERW lphttpHdr, LPCWSTR lpsztmp );
|
BOOL HTTP_ReplaceHeaderValue( LPHTTPHEADERW lphttpHdr, LPCWSTR lpsztmp );
|
||||||
void HTTP_CloseConnection(LPWININETHTTPREQW lpwhr);
|
void HTTP_CloseConnection(LPWININETHTTPREQW lpwhr);
|
||||||
BOOL HTTP_InterpretHttpHeader(LPWSTR buffer, LPWSTR field, INT fieldlen, LPWSTR value, INT valuelen);
|
LPWSTR * HTTP_InterpretHttpHeader(LPCWSTR buffer);
|
||||||
INT HTTP_GetStdHeaderIndex(LPCWSTR lpszField);
|
INT HTTP_GetStdHeaderIndex(LPCWSTR lpszField);
|
||||||
BOOL HTTP_InsertCustomHeader(LPWININETHTTPREQW lpwhr, LPHTTPHEADERW lpHdr);
|
BOOL HTTP_InsertCustomHeader(LPWININETHTTPREQW lpwhr, LPHTTPHEADERW lpHdr);
|
||||||
INT HTTP_GetCustomHeaderIndex(LPWININETHTTPREQW lpwhr, LPCWSTR lpszField);
|
INT HTTP_GetCustomHeaderIndex(LPWININETHTTPREQW lpwhr, LPCWSTR lpszField);
|
||||||
|
@ -168,7 +168,6 @@ static BOOL WINAPI HTTP_HttpAddRequestHeadersW(LPWININETHTTPREQW lpwhr,
|
||||||
LPWSTR lpszStart;
|
LPWSTR lpszStart;
|
||||||
LPWSTR lpszEnd;
|
LPWSTR lpszEnd;
|
||||||
LPWSTR buffer;
|
LPWSTR buffer;
|
||||||
WCHAR value[MAX_FIELD_VALUE_LEN], field[MAX_FIELD_LEN];
|
|
||||||
BOOL bSuccess = FALSE;
|
BOOL bSuccess = FALSE;
|
||||||
DWORD len;
|
DWORD len;
|
||||||
|
|
||||||
|
@ -186,6 +185,8 @@ static BOOL WINAPI HTTP_HttpAddRequestHeadersW(LPWININETHTTPREQW lpwhr,
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
LPWSTR * pFieldAndValue;
|
||||||
|
|
||||||
lpszEnd = lpszStart;
|
lpszEnd = lpszStart;
|
||||||
|
|
||||||
while (*lpszEnd != '\0')
|
while (*lpszEnd != '\0')
|
||||||
|
@ -204,11 +205,15 @@ static BOOL WINAPI HTTP_HttpAddRequestHeadersW(LPWININETHTTPREQW lpwhr,
|
||||||
lpszEnd += 2; /* Jump over \r\n */
|
lpszEnd += 2; /* Jump over \r\n */
|
||||||
}
|
}
|
||||||
TRACE("interpreting header %s\n", debugstr_w(lpszStart));
|
TRACE("interpreting header %s\n", debugstr_w(lpszStart));
|
||||||
if (HTTP_InterpretHttpHeader(lpszStart, field, MAX_FIELD_LEN, value, MAX_FIELD_VALUE_LEN))
|
pFieldAndValue = HTTP_InterpretHttpHeader(lpszStart);
|
||||||
bSuccess = HTTP_ProcessHeader(lpwhr, field, value, dwModifier | HTTP_ADDHDR_FLAG_REQ);
|
if (pFieldAndValue)
|
||||||
|
{
|
||||||
|
bSuccess = HTTP_ProcessHeader(lpwhr, pFieldAndValue[0],
|
||||||
|
pFieldAndValue[1], dwModifier | HTTP_ADDHDR_FLAG_REQ);
|
||||||
|
HTTP_FreeTokens(pFieldAndValue);
|
||||||
|
}
|
||||||
|
|
||||||
lpszStart = lpszEnd;
|
lpszStart = lpszEnd;
|
||||||
|
|
||||||
} while (bSuccess);
|
} while (bSuccess);
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(), 0, buffer);
|
HeapFree(GetProcessHeap(), 0, buffer);
|
||||||
|
@ -1981,7 +1986,6 @@ BOOL HTTP_GetResponseHeaders(LPWININETHTTPREQW lpwhr)
|
||||||
DWORD buflen = MAX_REPLY_LEN;
|
DWORD buflen = MAX_REPLY_LEN;
|
||||||
BOOL bSuccess = FALSE;
|
BOOL bSuccess = FALSE;
|
||||||
INT rc = 0;
|
INT rc = 0;
|
||||||
WCHAR value[MAX_FIELD_VALUE_LEN], field[MAX_FIELD_LEN];
|
|
||||||
static const WCHAR szCrLf[] = {'\r','\n',0};
|
static const WCHAR szCrLf[] = {'\r','\n',0};
|
||||||
char bufferA[MAX_REPLY_LEN];
|
char bufferA[MAX_REPLY_LEN];
|
||||||
LPWSTR status_code, status_text;
|
LPWSTR status_code, status_text;
|
||||||
|
@ -2046,7 +2050,9 @@ BOOL HTTP_GetResponseHeaders(LPWININETHTTPREQW lpwhr)
|
||||||
{
|
{
|
||||||
buflen = MAX_REPLY_LEN;
|
buflen = MAX_REPLY_LEN;
|
||||||
if (NETCON_getNextLine(&lpwhr->netConnection, bufferA, &buflen))
|
if (NETCON_getNextLine(&lpwhr->netConnection, bufferA, &buflen))
|
||||||
{
|
{
|
||||||
|
LPWSTR * pFieldAndValue;
|
||||||
|
|
||||||
TRACE("got line %s, now interpretting\n", debugstr_a(bufferA));
|
TRACE("got line %s, now interpretting\n", debugstr_a(bufferA));
|
||||||
MultiByteToWideChar( CP_ACP, 0, bufferA, buflen, buffer, MAX_REPLY_LEN );
|
MultiByteToWideChar( CP_ACP, 0, bufferA, buflen, buffer, MAX_REPLY_LEN );
|
||||||
|
|
||||||
|
@ -2061,10 +2067,14 @@ BOOL HTTP_GetResponseHeaders(LPWININETHTTPREQW lpwhr)
|
||||||
cchRawHeaders += sizeof(szCrLf)/sizeof(szCrLf[0])-1;
|
cchRawHeaders += sizeof(szCrLf)/sizeof(szCrLf[0])-1;
|
||||||
lpszRawHeaders[cchRawHeaders] = '\0';
|
lpszRawHeaders[cchRawHeaders] = '\0';
|
||||||
|
|
||||||
if (!HTTP_InterpretHttpHeader(buffer, field, MAX_FIELD_LEN, value, MAX_FIELD_VALUE_LEN))
|
pFieldAndValue = HTTP_InterpretHttpHeader(buffer);
|
||||||
|
if (!pFieldAndValue)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
HTTP_ProcessHeader(lpwhr, field, value, (HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE));
|
HTTP_ProcessHeader(lpwhr, pFieldAndValue[0], pFieldAndValue[1],
|
||||||
|
HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE);
|
||||||
|
|
||||||
|
HTTP_FreeTokens(pFieldAndValue);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2089,6 +2099,26 @@ lend:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void strip_spaces(LPWSTR start)
|
||||||
|
{
|
||||||
|
LPWSTR str = start;
|
||||||
|
LPWSTR end;
|
||||||
|
|
||||||
|
while (*str == ' ' && *str != '\0')
|
||||||
|
str++;
|
||||||
|
|
||||||
|
if (str != start)
|
||||||
|
memmove(start, str, sizeof(WCHAR) * (strlenW(str) + 1));
|
||||||
|
|
||||||
|
end = start + strlenW(start) - 1;
|
||||||
|
while (end >= start && *end == ' ')
|
||||||
|
{
|
||||||
|
*end = '\0';
|
||||||
|
end--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* HTTP_InterpretHttpHeader (internal)
|
* HTTP_InterpretHttpHeader (internal)
|
||||||
*
|
*
|
||||||
|
@ -2096,59 +2126,50 @@ lend:
|
||||||
*
|
*
|
||||||
* RETURNS
|
* RETURNS
|
||||||
*
|
*
|
||||||
* TRUE on success
|
* Pointer to array of field, value, NULL on success.
|
||||||
* FALSE on error
|
* NULL on error.
|
||||||
*/
|
*/
|
||||||
static INT stripSpaces(LPCWSTR lpszSrc, LPWSTR lpszStart, INT *len)
|
LPWSTR * HTTP_InterpretHttpHeader(LPCWSTR buffer)
|
||||||
{
|
{
|
||||||
LPCWSTR lpsztmp;
|
LPWSTR * pTokenPair;
|
||||||
INT srclen;
|
LPWSTR pszColon;
|
||||||
|
INT len;
|
||||||
|
|
||||||
srclen = 0;
|
pTokenPair = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pTokenPair)*3);
|
||||||
|
|
||||||
while (*lpszSrc == ' ' && *lpszSrc != '\0')
|
pszColon = strchrW(buffer, ':');
|
||||||
lpszSrc++;
|
/* must have two tokens */
|
||||||
|
if (!pszColon)
|
||||||
lpsztmp = lpszSrc;
|
|
||||||
while(*lpsztmp != '\0')
|
|
||||||
{
|
{
|
||||||
if (*lpsztmp != ' ')
|
HTTP_FreeTokens(pTokenPair);
|
||||||
srclen = lpsztmp - lpszSrc + 1;
|
return NULL;
|
||||||
|
|
||||||
lpsztmp++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*len = min(*len, srclen);
|
pTokenPair[0] = HeapAlloc(GetProcessHeap(), 0, (pszColon - buffer + 1) * sizeof(WCHAR));
|
||||||
strncpyW(lpszStart, lpszSrc, *len);
|
if (!pTokenPair[0])
|
||||||
lpszStart[*len] = '\0';
|
|
||||||
|
|
||||||
return *len;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BOOL HTTP_InterpretHttpHeader(LPWSTR buffer, LPWSTR field, INT fieldlen, LPWSTR value, INT valuelen)
|
|
||||||
{
|
|
||||||
WCHAR *pd;
|
|
||||||
BOOL bSuccess = FALSE;
|
|
||||||
|
|
||||||
TRACE("\n");
|
|
||||||
|
|
||||||
*field = '\0';
|
|
||||||
*value = '\0';
|
|
||||||
|
|
||||||
pd = strchrW(buffer, ':');
|
|
||||||
if (pd)
|
|
||||||
{
|
{
|
||||||
*pd = '\0';
|
HTTP_FreeTokens(pTokenPair);
|
||||||
if (stripSpaces(buffer, field, &fieldlen) > 0)
|
return NULL;
|
||||||
{
|
|
||||||
if (stripSpaces(pd+1, value, &valuelen) > 0)
|
|
||||||
bSuccess = TRUE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
memcpy(pTokenPair[0], buffer, (pszColon - buffer) * sizeof(WCHAR));
|
||||||
|
pTokenPair[0][pszColon - buffer] = '\0';
|
||||||
|
|
||||||
TRACE("%d: field(%s) Value(%s)\n", bSuccess, debugstr_w(field), debugstr_w(value));
|
/* skip colon */
|
||||||
return bSuccess;
|
pszColon++;
|
||||||
|
len = strlenW(pszColon);
|
||||||
|
pTokenPair[1] = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
|
||||||
|
if (!pTokenPair[1])
|
||||||
|
{
|
||||||
|
HTTP_FreeTokens(pTokenPair);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memcpy(pTokenPair[1], pszColon, (len + 1) * sizeof(WCHAR));
|
||||||
|
|
||||||
|
strip_spaces(pTokenPair[0]);
|
||||||
|
strip_spaces(pTokenPair[1]);
|
||||||
|
|
||||||
|
TRACE("field(%s) Value(%s)\n", debugstr_w(pTokenPair[0]), debugstr_w(pTokenPair[1]));
|
||||||
|
return pTokenPair;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2530,7 +2551,7 @@ INT HTTP_GetCustomHeaderIndex(LPWININETHTTPREQW lpwhr, LPCWSTR lpszField)
|
||||||
if (index >= lpwhr->nCustHeaders)
|
if (index >= lpwhr->nCustHeaders)
|
||||||
index = -1;
|
index = -1;
|
||||||
|
|
||||||
TRACE("Return: %lu\n", index);
|
TRACE("Return: %ld\n", index);
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue