https://git.reactos.org/?p=reactos.git;a=commitdiff;h=208ef143d3ed2a55e7c1d5...
commit 208ef143d3ed2a55e7c1d57b8db776dabaa1073f Author: winesync ros-dev@reactos.org AuthorDate: Tue Dec 8 18:31:47 2020 +0100 Commit: Jérôme Gardou zefklop@users.noreply.github.com CommitDate: Tue Jan 5 11:03:13 2021 +0100
[WINESYNC] 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.
wine-staging patch by Michael Müller michael@fds-team.de --- dll/win32/wininet/http.c | 185 ++++++++--------- ...ields_should_fail_if_they_do_not_exist_yet.diff | 225 +++++++++++++++++++++ 2 files changed, 318 insertions(+), 92 deletions(-)
diff --git a/dll/win32/wininet/http.c b/dll/win32/wininet/http.c index 28d48c1eb6b..7f0c1073b3b 100644 --- a/dll/win32/wininet/http.c +++ b/dll/win32/wininet/http.c @@ -6116,127 +6116,128 @@ 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%08x\n", debugstr_w(field), debugstr_w(value), dwModifier);
EnterCriticalSection( &request->headers_section );
- /* REPLACE wins out over ADD */ - if (dwModifier & HTTP_ADDHDR_FLAG_REPLACE) - dwModifier &= ~HTTP_ADDHDR_FLAG_ADD; - - if (dwModifier & HTTP_ADDHDR_FLAG_ADD) - index = -1; - else - index = HTTP_GetCustomHeaderIndex(request, field, 0, request_only); - + index = HTTP_GetCustomHeaderIndex(request, field, 0, request_only); if (index >= 0) { - if (dwModifier & HTTP_ADDHDR_FLAG_ADD_IF_NEW) - { - LeaveCriticalSection( &request->headers_section ); - return ERROR_HTTP_INVALID_HEADER; - } lphttpHdr = &request->custHeaders[index]; - } - else if (value) - { - HTTPHEADERW hdr;
- hdr.lpszField = (LPWSTR)field; - hdr.lpszValue = (LPWSTR)value; - hdr.wFlags = hdr.wCount = 0; + /* replace existing header if FLAG_REPLACE is given */ + if (dwModifier & HTTP_ADDHDR_FLAG_REPLACE) + { + HTTP_DeleteCustomHeader( request, index );
- if (dwModifier & HTTP_ADDHDR_FLAG_REQ) - hdr.wFlags |= HDR_ISREQUEST; + if (value && value[0]) + { + HTTPHEADERW hdr;
- res = HTTP_InsertCustomHeader(request, &hdr); - LeaveCriticalSection( &request->headers_section ); - return res; - } - /* no value to delete */ - else - { - LeaveCriticalSection( &request->headers_section ); - return ERROR_SUCCESS; - } + hdr.lpszField = (LPWSTR)field; + hdr.lpszValue = (LPWSTR)value; + hdr.wFlags = hdr.wCount = 0;
- if (dwModifier & HTTP_ADDHDR_FLAG_REQ) - lphttpHdr->wFlags |= HDR_ISREQUEST; - else - lphttpHdr->wFlags &= ~HDR_ISREQUEST; + if (dwModifier & HTTP_ADDHDR_FLAG_REQ) + hdr.wFlags |= HDR_ISREQUEST;
- if (dwModifier & HTTP_ADDHDR_FLAG_REPLACE) - { - HTTP_DeleteCustomHeader( request, index ); + res = HTTP_InsertCustomHeader( request, &hdr ); + } + + goto out; + }
- if (value && value[0]) + /* do not add new header if FLAG_ADD_IF_NEW is set */ + if (dwModifier & HTTP_ADDHDR_FLAG_ADD_IF_NEW) { - HTTPHEADERW hdr; + res = ERROR_HTTP_INVALID_HEADER; /* FIXME */ + goto out; + }
- hdr.lpszField = (LPWSTR)field; - hdr.lpszValue = (LPWSTR)value; - hdr.wFlags = hdr.wCount = 0; + /* handle appending to existing header */ + if (dwModifier & COALESCEFLAGS) + { + 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) - hdr.wFlags |= HDR_ISREQUEST; - - res = HTTP_InsertCustomHeader(request, &hdr); - LeaveCriticalSection( &request->headers_section ); - return res; - } + lphttpHdr->wFlags |= HDR_ISREQUEST; + else + lphttpHdr->wFlags &= ~HDR_ISREQUEST;
- LeaveCriticalSection( &request->headers_section ); - return ERROR_SUCCESS; - } - else if (dwModifier & COALESCEFLAGS) - { - LPWSTR lpsztmp; - WCHAR ch = 0; - INT len = 0; - INT origlen = lstrlenW(lphttpHdr->lpszValue); - INT valuelen = lstrlenW(value); + if (dwModifier & HTTP_ADDHDR_FLAG_COALESCE_WITH_COMMA) + { + ch = ','; + lphttpHdr->wFlags |= HDR_COMMADELIMITED; + } + else if (dwModifier & HTTP_ADDHDR_FLAG_COALESCE_WITH_SEMICOLON) + { + ch = ';'; + lphttpHdr->wFlags |= HDR_COMMADELIMITED; + }
- if (dwModifier & HTTP_ADDHDR_FLAG_COALESCE_WITH_COMMA) - { - ch = ','; - lphttpHdr->wFlags |= HDR_COMMADELIMITED; - } - else if (dwModifier & HTTP_ADDHDR_FLAG_COALESCE_WITH_SEMICOLON) - { - ch = ';'; - lphttpHdr->wFlags |= HDR_COMMADELIMITED; - } + len = origlen + valuelen + ((ch > 0) ? 2 : 0);
- len = origlen + valuelen + ((ch > 0) ? 2 : 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++; + }
- 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) + memcpy(&lphttpHdr->lpszValue[origlen], value, valuelen*sizeof(WCHAR)); + lphttpHdr->lpszValue[len] = '\0'; + } + else { - lphttpHdr->lpszValue[origlen] = ch; - origlen++; - lphttpHdr->lpszValue[origlen] = ' '; - origlen++; + WARN("heap_realloc (%d bytes) failed\n",len+1); + res = ERROR_OUTOFMEMORY; }
- 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; + goto out; } } + + /* FIXME: What about other combinations? */ + if ((dwModifier & ~HTTP_ADDHDR_FLAG_REQ) == HTTP_ADDHDR_FLAG_REPLACE) + { + res = ERROR_HTTP_HEADER_NOT_FOUND; + goto out; + } + + /* FIXME: What if value == ""? */ + if (value) + { + HTTPHEADERW hdr; + + hdr.lpszField = (LPWSTR)field; + hdr.lpszValue = (LPWSTR)value; + hdr.wFlags = hdr.wCount = 0; + + if (dwModifier & HTTP_ADDHDR_FLAG_REQ) + hdr.wFlags |= HDR_ISREQUEST; + + res = HTTP_InsertCustomHeader( request, &hdr ); + goto out; + } + + /* FIXME: What if value == NULL? */ +out: TRACE("<-- %d\n", res); LeaveCriticalSection( &request->headers_section ); return res; diff --git a/sdk/tools/winesync/wininet_staging/0005-wininet__Replacing_header_fields_should_fail_if_they_do_not_exist_yet.diff b/sdk/tools/winesync/wininet_staging/0005-wininet__Replacing_header_fields_should_fail_if_they_do_not_exist_yet.diff new file mode 100644 index 00000000000..9d5ab4e28a6 --- /dev/null +++ b/sdk/tools/winesync/wininet_staging/0005-wininet__Replacing_header_fields_should_fail_if_they_do_not_exist_yet.diff @@ -0,0 +1,225 @@ +diff --git a/dll/win32/wininet/http.c b/dll/win32/wininet/http.c +index f7d9e29b96..09566b7cde 100644 +--- a/dll/win32/wininet/http.c ++++ b/dll/win32/wininet/http.c +@@ -6112,127 +6112,128 @@ 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%08x\n", debugstr_w(field), debugstr_w(value), dwModifier); + + EnterCriticalSection( &request->headers_section ); + +- /* REPLACE wins out over ADD */ +- if (dwModifier & HTTP_ADDHDR_FLAG_REPLACE) +- dwModifier &= ~HTTP_ADDHDR_FLAG_ADD; +- +- if (dwModifier & HTTP_ADDHDR_FLAG_ADD) +- index = -1; +- else +- index = HTTP_GetCustomHeaderIndex(request, field, 0, request_only); +- ++ index = HTTP_GetCustomHeaderIndex(request, field, 0, request_only); + if (index >= 0) + { +- if (dwModifier & HTTP_ADDHDR_FLAG_ADD_IF_NEW) +- { +- LeaveCriticalSection( &request->headers_section ); +- return ERROR_HTTP_INVALID_HEADER; +- } + lphttpHdr = &request->custHeaders[index]; +- } +- else if (value) +- { +- HTTPHEADERW hdr; + +- hdr.lpszField = (LPWSTR)field; +- hdr.lpszValue = (LPWSTR)value; +- hdr.wFlags = hdr.wCount = 0; ++ /* replace existing header if FLAG_REPLACE is given */ ++ if (dwModifier & HTTP_ADDHDR_FLAG_REPLACE) ++ { ++ HTTP_DeleteCustomHeader( request, index ); + +- if (dwModifier & HTTP_ADDHDR_FLAG_REQ) +- hdr.wFlags |= HDR_ISREQUEST; ++ if (value && value[0]) ++ { ++ HTTPHEADERW hdr; + +- res = HTTP_InsertCustomHeader(request, &hdr); +- LeaveCriticalSection( &request->headers_section ); +- return res; +- } +- /* no value to delete */ +- else +- { +- LeaveCriticalSection( &request->headers_section ); +- return ERROR_SUCCESS; +- } ++ hdr.lpszField = (LPWSTR)field; ++ hdr.lpszValue = (LPWSTR)value; ++ hdr.wFlags = hdr.wCount = 0; + +- if (dwModifier & HTTP_ADDHDR_FLAG_REQ) +- lphttpHdr->wFlags |= HDR_ISREQUEST; +- else +- lphttpHdr->wFlags &= ~HDR_ISREQUEST; ++ if (dwModifier & HTTP_ADDHDR_FLAG_REQ) ++ hdr.wFlags |= HDR_ISREQUEST; + +- if (dwModifier & HTTP_ADDHDR_FLAG_REPLACE) +- { +- HTTP_DeleteCustomHeader( request, index ); ++ res = HTTP_InsertCustomHeader( request, &hdr ); ++ } ++ ++ goto out; ++ } + +- if (value && value[0]) ++ /* do not add new header if FLAG_ADD_IF_NEW is set */ ++ if (dwModifier & HTTP_ADDHDR_FLAG_ADD_IF_NEW) + { +- HTTPHEADERW hdr; ++ res = ERROR_HTTP_INVALID_HEADER; /* FIXME */ ++ goto out; ++ } + +- hdr.lpszField = (LPWSTR)field; +- hdr.lpszValue = (LPWSTR)value; +- hdr.wFlags = hdr.wCount = 0; ++ /* handle appending to existing header */ ++ if (dwModifier & COALESCEFLAGS) ++ { ++ 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) +- hdr.wFlags |= HDR_ISREQUEST; +- +- res = HTTP_InsertCustomHeader(request, &hdr); +- LeaveCriticalSection( &request->headers_section ); +- return res; +- } ++ lphttpHdr->wFlags |= HDR_ISREQUEST; ++ else ++ lphttpHdr->wFlags &= ~HDR_ISREQUEST; + +- LeaveCriticalSection( &request->headers_section ); +- return ERROR_SUCCESS; +- } +- else if (dwModifier & COALESCEFLAGS) +- { +- LPWSTR lpsztmp; +- WCHAR ch = 0; +- INT len = 0; +- INT origlen = lstrlenW(lphttpHdr->lpszValue); +- INT valuelen = lstrlenW(value); ++ if (dwModifier & HTTP_ADDHDR_FLAG_COALESCE_WITH_COMMA) ++ { ++ ch = ','; ++ lphttpHdr->wFlags |= HDR_COMMADELIMITED; ++ } ++ else if (dwModifier & HTTP_ADDHDR_FLAG_COALESCE_WITH_SEMICOLON) ++ { ++ ch = ';'; ++ lphttpHdr->wFlags |= HDR_COMMADELIMITED; ++ } + +- if (dwModifier & HTTP_ADDHDR_FLAG_COALESCE_WITH_COMMA) +- { +- ch = ','; +- lphttpHdr->wFlags |= HDR_COMMADELIMITED; +- } +- else if (dwModifier & HTTP_ADDHDR_FLAG_COALESCE_WITH_SEMICOLON) +- { +- ch = ';'; +- lphttpHdr->wFlags |= HDR_COMMADELIMITED; +- } ++ len = origlen + valuelen + ((ch > 0) ? 2 : 0); + +- len = origlen + valuelen + ((ch > 0) ? 2 : 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++; ++ } + +- 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) ++ memcpy(&lphttpHdr->lpszValue[origlen], value, valuelen*sizeof(WCHAR)); ++ lphttpHdr->lpszValue[len] = '\0'; ++ } ++ else + { +- lphttpHdr->lpszValue[origlen] = ch; +- origlen++; +- lphttpHdr->lpszValue[origlen] = ' '; +- origlen++; ++ WARN("heap_realloc (%d bytes) failed\n",len+1); ++ res = ERROR_OUTOFMEMORY; + } + +- 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; ++ goto out; + } + } ++ ++ /* FIXME: What about other combinations? */ ++ if ((dwModifier & ~HTTP_ADDHDR_FLAG_REQ) == HTTP_ADDHDR_FLAG_REPLACE) ++ { ++ res = ERROR_HTTP_HEADER_NOT_FOUND; ++ goto out; ++ } ++ ++ /* FIXME: What if value == ""? */ ++ if (value) ++ { ++ HTTPHEADERW hdr; ++ ++ hdr.lpszField = (LPWSTR)field; ++ hdr.lpszValue = (LPWSTR)value; ++ hdr.wFlags = hdr.wCount = 0; ++ ++ if (dwModifier & HTTP_ADDHDR_FLAG_REQ) ++ hdr.wFlags |= HDR_ISREQUEST; ++ ++ res = HTTP_InsertCustomHeader( request, &hdr ); ++ goto out; ++ } ++ ++ /* FIXME: What if value == NULL? */ ++out: + TRACE("<-- %d\n", res); + LeaveCriticalSection( &request->headers_section ); + return res;