The HTTP response header status text can be empty, so process_response_status_text would erroneously return E_OUTOFMEMORY.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/mshtml_private.h | 6 +++--- dlls/wininet/tests/http.c | 7 +++++++ 2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index ad1fca0..0a7c3a2 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -1392,11 +1392,11 @@ static inline char *heap_strndupWtoU(LPCWSTR str, unsigned len) char *ret = NULL; DWORD size;
- if(str && len) { - size = WideCharToMultiByte(CP_UTF8, 0, str, len, NULL, 0, NULL, NULL); + if(str) { + size = len ? WideCharToMultiByte(CP_UTF8, 0, str, len, NULL, 0, NULL, NULL) : 0; ret = heap_alloc(size + 1); if(ret) { - WideCharToMultiByte(CP_UTF8, 0, str, len, ret, size, NULL, NULL); + if(len) WideCharToMultiByte(CP_UTF8, 0, str, len, ret, size, NULL, NULL); ret[size] = '\0'; } } diff --git a/dlls/wininet/tests/http.c b/dlls/wininet/tests/http.c index ec576ae..bc1b829 100644 --- a/dlls/wininet/tests/http.c +++ b/dlls/wininet/tests/http.c @@ -4526,6 +4526,13 @@ static const http_status_test_t http_status_tests[] = { 200, "" }, + { + "HTTP/1.1 200 \r\n" + "Content-Length: 1\r\n" + "\r\nx", + 200, + "" + }, { "HTTP/1.1 410 \r\n" "Content-Length: 1\r\n"
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
The HTTP response header status text can be empty and without any space before it at all (we have tests in wininet/http for this, although this isn't used for them, but having behavior match is sensible).
dlls/mshtml/navigate.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c index e750ff2..d5ec368 100644 --- a/dlls/mshtml/navigate.c +++ b/dlls/mshtml/navigate.c @@ -1690,8 +1690,9 @@ static HRESULT process_response_status_text(const WCHAR *header, const WCHAR *he return E_FAIL; header = wcschr(header + 1, ' '); if(!header || header >= header_end) - return E_FAIL; - ++header; + header = header_end; + else + ++header;
*status_text = heap_strndupWtoU(header, header_end - header);
Signed-off-by: Jacek Caban jacek@codeweavers.com
Gecko can cancel an async request sometime between async_start_doc_binding registers it and on_start_nsrequest actually processes it. The latter should not attempt to continue in this case.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/binding.h | 1 + dlls/mshtml/navigate.c | 4 ++++ dlls/mshtml/nsio.c | 3 +++ 3 files changed, 8 insertions(+)
diff --git a/dlls/mshtml/binding.h b/dlls/mshtml/binding.h index 26a337f..9a04386 100644 --- a/dlls/mshtml/binding.h +++ b/dlls/mshtml/binding.h @@ -51,6 +51,7 @@ typedef struct { nsIURI *referrer; char *content_type; char *charset; + nsresult status; UINT32 response_status; char *response_status_text; REQUEST_METHOD request_method; diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c index d5ec368..e6f2035 100644 --- a/dlls/mshtml/navigate.c +++ b/dlls/mshtml/navigate.c @@ -981,6 +981,10 @@ static HRESULT on_start_nsrequest(nsChannelBSC *This) { nsresult nsres;
+ /* Async request can be cancelled before we got to it */ + if(NS_FAILED(This->nschannel->status)) + return E_ABORT; /* FIXME: map status to HRESULT */ + This->nschannel->binding = This;
/* FIXME: it's needed for http connections from BindToObject. */ diff --git a/dlls/mshtml/nsio.c b/dlls/mshtml/nsio.c index e0b8bed..e1a1d6e 100644 --- a/dlls/mshtml/nsio.c +++ b/dlls/mshtml/nsio.c @@ -610,6 +610,9 @@ static nsresult NSAPI nsChannel_Cancel(nsIHttpChannel *iface, nsresult aStatus)
TRACE("(%p)->(%08lx)\n", This, aStatus);
+ if(NS_FAILED(aStatus)) + This->status = aStatus; + if(This->binding && This->binding->bsc.binding) IBinding_Abort(This->binding->bsc.binding); else
Signed-off-by: Jacek Caban jacek@codeweavers.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/nsio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/mshtml/nsio.c b/dlls/mshtml/nsio.c index e1a1d6e..f1859e2 100644 --- a/dlls/mshtml/nsio.c +++ b/dlls/mshtml/nsio.c @@ -599,9 +599,9 @@ static nsresult NSAPI nsChannel_GetStatus(nsIHttpChannel *iface, nsresult *aStat { nsChannel *This = impl_from_nsIHttpChannel(iface);
- WARN("(%p)->(%p) returning NS_OK\n", This, aStatus); + TRACE("(%p)->(%p) returning %#lx\n", This, aStatus, This->status);
- return *aStatus = NS_OK; + return *aStatus = This->status; }
static nsresult NSAPI nsChannel_Cancel(nsIHttpChannel *iface, nsresult aStatus)
Signed-off-by: Jacek Caban jacek@codeweavers.com
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=115609
Your paranoid android.
=== w8adm (32 bit report) ===
wininet: http.c:697: Test failed: req_error = 12007 http.c:708: Test failed: expected status 11 (INTERNET_STATUS_NAME_RESOLVED) 1 times, received 0 times http.c:721: Test failed: expected status 30 (INTERNET_STATUS_SENDING_REQUEST) 1 times, received 0 times http.c:722: Test failed: expected status 31 (INTERNET_STATUS_REQUEST_SENT) 1 times, received 0 times http.c:723: Test failed: expected status 40 (INTERNET_STATUS_RECEIVING_RESPONSE) 1 times, received 0 times http.c:724: Test failed: expected status 41 (INTERNET_STATUS_RESPONSE_RECEIVED) 1 times, received 0 times http.c:733: Test failed: flags = 8, expected 0 http.c:747: Test failed: Expected any header character, got 0x00 http.c:774: Test failed: Expected 0x0000, got 7777 http.c:937: Test failed: Returned zero size in response to request complete http.c:376: Test failed: unexpected status 10 (INTERNET_STATUS_RESOLVING_NAME) http.c:376: Test failed: unexpected status 11 (INTERNET_STATUS_NAME_RESOLVED) http.c:718: Test failed: expected status 10 (INTERNET_STATUS_RESOLVING_NAME) 0 times, received 1 times http.c:719: Test failed: expected status 11 (INTERNET_STATUS_NAME_RESOLVED) 0 times, received 1 times