From ec84f3463bb1750c51e062b80c3ce16dabb972e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Sat, 16 May 2015 03:16:15 +0200 Subject: [PATCH] wininet: Replacing header fields should fail if they do not exist yet. A lot of details are not properly covered by tests yet and were marked with FIXME comments. The implementation was written in such a way that it behaves identical to the old code in such situations. --- dlls/wininet/http.c | 197 ++++++++++++++++++++++---------------------- 1 file changed, 99 insertions(+), 98 deletions(-) diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c index 575ebab24c6..132ed61e1de 100644 --- a/dlls/wininet/http.c +++ b/dlls/wininet/http.c @@ -6112,130 +6112,131 @@ static LPWSTR * HTTP_InterpretHttpHeader(LPCWSTR buffer) static DWORD HTTP_ProcessHeader(http_request_t *request, LPCWSTR field, LPCWSTR value, DWORD dwModifier) { - LPHTTPHEADERW lphttpHdr = NULL; + LPHTTPHEADERW lphttpHdr; INT index; BOOL request_only = !!(dwModifier & HTTP_ADDHDR_FLAG_REQ); - DWORD res = ERROR_HTTP_INVALID_HEADER; + DWORD res = ERROR_SUCCESS; TRACE("--> %s: %s - 0x%08lx\n", debugstr_w(field), debugstr_w(value), dwModifier); EnterCriticalSection( &request->headers_section ); - /* REPLACE wins out over ADD */ - if (dwModifier & HTTP_ADDREQ_FLAG_REPLACE) - dwModifier &= ~HTTP_ADDREQ_FLAG_ADD; + index = HTTP_GetCustomHeaderIndex(request, field, 0, request_only); + if (index >= 0) + { + lphttpHdr = &request->custHeaders[index]; - if (dwModifier & HTTP_ADDREQ_FLAG_ADD) - index = -1; - else - index = HTTP_GetCustomHeaderIndex(request, field, 0, request_only); - - if (index >= 0) - { - if (dwModifier & HTTP_ADDREQ_FLAG_ADD_IF_NEW) + /* replace existing header if FLAG_REPLACE is given */ + if (dwModifier & HTTP_ADDREQ_FLAG_REPLACE) { - LeaveCriticalSection( &request->headers_section ); - return ERROR_HTTP_INVALID_HEADER; - } - lphttpHdr = &request->custHeaders[index]; - } - else if (value) - { - HTTPHEADERW hdr; + HTTP_DeleteCustomHeader( request, index ); - hdr.lpszField = (LPWSTR)field; - hdr.lpszValue = (LPWSTR)value; - hdr.wFlags = hdr.wCount = 0; + if (value && value[0]) + { + HTTPHEADERW hdr; - if (dwModifier & HTTP_ADDHDR_FLAG_REQ) - hdr.wFlags |= HDR_ISREQUEST; + hdr.lpszField = (LPWSTR)field; + hdr.lpszValue = (LPWSTR)value; + hdr.wFlags = hdr.wCount = 0; - res = HTTP_InsertCustomHeader(request, &hdr); - LeaveCriticalSection( &request->headers_section ); - return res; - } - /* no value to delete */ - else - { - LeaveCriticalSection( &request->headers_section ); - return ERROR_SUCCESS; - } + if (dwModifier & HTTP_ADDHDR_FLAG_REQ) + hdr.wFlags |= HDR_ISREQUEST; - if (dwModifier & HTTP_ADDHDR_FLAG_REQ) - lphttpHdr->wFlags |= HDR_ISREQUEST; - else - lphttpHdr->wFlags &= ~HDR_ISREQUEST; + res = HTTP_InsertCustomHeader( request, &hdr ); + } - if (dwModifier & HTTP_ADDREQ_FLAG_REPLACE) - { - HTTP_DeleteCustomHeader( request, index ); + goto out; + } - if (value && value[0]) + /* do not add new header if FLAG_ADD_IF_NEW is set */ + if (dwModifier & HTTP_ADDREQ_FLAG_ADD_IF_NEW) + { + res = ERROR_HTTP_INVALID_HEADER; /* FIXME */ + goto out; + } + + /* handle appending to existing header */ + if (dwModifier & COALESCEFLAGS) { - HTTPHEADERW hdr; + LPWSTR lpsztmp; + WCHAR ch = 0; + INT len = 0; + INT origlen = lstrlenW(lphttpHdr->lpszValue); + INT valuelen = lstrlenW(value); + + /* FIXME: Should it really clear HDR_ISREQUEST? */ + if (dwModifier & HTTP_ADDHDR_FLAG_REQ) + lphttpHdr->wFlags |= HDR_ISREQUEST; + else + lphttpHdr->wFlags &= ~HDR_ISREQUEST; - hdr.lpszField = (LPWSTR)field; - hdr.lpszValue = (LPWSTR)value; - hdr.wFlags = hdr.wCount = 0; + if (dwModifier & HTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA) + { + ch = ','; + lphttpHdr->wFlags |= HDR_COMMADELIMITED; + } + else if (dwModifier & HTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON) + { + ch = ';'; + lphttpHdr->wFlags |= HDR_COMMADELIMITED; + } - if (dwModifier & HTTP_ADDHDR_FLAG_REQ) - hdr.wFlags |= HDR_ISREQUEST; + len = origlen + valuelen + ((ch > 0) ? 2 : 0); - res = HTTP_InsertCustomHeader(request, &hdr); - LeaveCriticalSection( &request->headers_section ); - return res; - } + lpsztmp = heap_realloc(lphttpHdr->lpszValue, (len+1)*sizeof(WCHAR)); + if (lpsztmp) + { + lphttpHdr->lpszValue = lpsztmp; + /* FIXME: Increment lphttpHdr->wCount. Perhaps lpszValue should be an array */ + if (ch > 0) + { + lphttpHdr->lpszValue[origlen] = ch; + origlen++; + lphttpHdr->lpszValue[origlen] = ' '; + origlen++; + } - LeaveCriticalSection( &request->headers_section ); - return ERROR_SUCCESS; - } - else if (dwModifier & COALESCEFLAGS) + memcpy(&lphttpHdr->lpszValue[origlen], value, valuelen*sizeof(WCHAR)); + lphttpHdr->lpszValue[len] = '\0'; + } + else + { + WARN("heap_realloc (%d bytes) failed\n",len+1); + res = ERROR_OUTOFMEMORY; + } + + goto out; + } + } + + /* FIXME: What about other combinations? */ + if ((dwModifier & ~HTTP_ADDHDR_FLAG_REQ) == HTTP_ADDREQ_FLAG_REPLACE) { - LPWSTR lpsztmp; - WCHAR ch = 0; - INT len = 0; - INT origlen = lstrlenW(lphttpHdr->lpszValue); - INT valuelen = lstrlenW(value); + res = ERROR_HTTP_HEADER_NOT_FOUND; + goto out; + } - if (dwModifier & HTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA) - { - ch = ','; - lphttpHdr->wFlags |= HDR_COMMADELIMITED; - } - else if (dwModifier & HTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON) - { - ch = ';'; - lphttpHdr->wFlags |= HDR_COMMADELIMITED; - } + /* FIXME: What if value == ""? */ + if (value) + { + HTTPHEADERW hdr; - len = origlen + valuelen + ((ch > 0) ? 2 : 0); + hdr.lpszField = (LPWSTR)field; + hdr.lpszValue = (LPWSTR)value; + hdr.wFlags = hdr.wCount = 0; - lpsztmp = heap_realloc(lphttpHdr->lpszValue, (len+1)*sizeof(WCHAR)); - if (lpsztmp) - { - lphttpHdr->lpszValue = lpsztmp; - /* FIXME: Increment lphttpHdr->wCount. Perhaps lpszValue should be an array */ - if (ch > 0) - { - lphttpHdr->lpszValue[origlen] = ch; - origlen++; - lphttpHdr->lpszValue[origlen] = ' '; - origlen++; - } + if (dwModifier & HTTP_ADDHDR_FLAG_REQ) + hdr.wFlags |= HDR_ISREQUEST; - memcpy(&lphttpHdr->lpszValue[origlen], value, valuelen*sizeof(WCHAR)); - lphttpHdr->lpszValue[len] = '\0'; - res = ERROR_SUCCESS; - } - else - { - WARN("heap_realloc (%d bytes) failed\n",len+1); - res = ERROR_OUTOFMEMORY; - } + res = HTTP_InsertCustomHeader( request, &hdr ); + goto out; } - TRACE("<-- %ld\n", res); - LeaveCriticalSection( &request->headers_section ); - return res; + + /* FIXME: What if value == NULL? */ +out: + TRACE("<-- %ld\n", res); + LeaveCriticalSection( &request->headers_section ); + return res; } /*********************************************************************** -- 2.35.1