diff options
author | Evgeny Kotkov <kotkov@apache.org> | 2022-10-20 06:17:23 +0000 |
---|---|---|
committer | Evgeny Kotkov <kotkov@apache.org> | 2022-10-20 06:17:23 +0000 |
commit | 96b81a06953c5670fccccedfb0df66739745c24b (patch) | |
tree | 50f20967570559e30a885a364499075cbee86a96 | |
parent | 7b07b731d0fa62dc88ec8b69650dca6d888ea2a9 (diff) | |
download | apr-96b81a06953c5670fccccedfb0df66739745c24b.tar.gz |
On 1.7.x branch: Merge r1904716 from 1.8.x branch:
Win32: Stop apr_socket_sendv() from splitting iovecs into multiple possible
WSABUFs and error out on theoretical cases that cannot be handled with a
single WSASend().
git-svn-id: https://svn.apache.org/repos/asf/apr/apr/branches/1.7.x@1904718 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | network_io/win32/sendrecv.c | 54 |
1 files changed, 22 insertions, 32 deletions
diff --git a/network_io/win32/sendrecv.c b/network_io/win32/sendrecv.c index 3fa0c8dda..f5f23d2c7 100644 --- a/network_io/win32/sendrecv.c +++ b/network_io/win32/sendrecv.c @@ -100,53 +100,43 @@ APR_DECLARE(apr_status_t) apr_socket_sendv(apr_socket_t *sock, { apr_status_t rc = APR_SUCCESS; apr_ssize_t rv; - apr_size_t cur_len; - apr_int32_t nvec = 0; - int i, j = 0; + apr_size_t total_len; + apr_int32_t i; DWORD dwBytes = 0; WSABUF *pWsaBuf; + total_len = 0; for (i = 0; i < in_vec; i++) { - cur_len = vec[i].iov_len; - nvec++; - while (cur_len > APR_DWORD_MAX) { - nvec++; - cur_len -= APR_DWORD_MAX; - } + apr_size_t iov_len = vec[i].iov_len; + if (iov_len > MAXDWORD) { + /* WSASend() returns NumberOfBytesSent as DWORD, so any iovec + should be less than that. */ + return APR_EINVAL; + } + total_len += iov_len; + if (total_len > MAXDWORD) { + /* WSASend() returns NumberOfBytesSent as DWORD, so the total size + should be less than that. */ + return APR_EINVAL; + } } - pWsaBuf = (nvec <= WSABUF_ON_STACK) ? _alloca(sizeof(WSABUF) * (nvec)) - : malloc(sizeof(WSABUF) * (nvec)); + pWsaBuf = (in_vec <= WSABUF_ON_STACK) ? _alloca(sizeof(WSABUF) * (in_vec)) + : malloc(sizeof(WSABUF) * (in_vec)); if (!pWsaBuf) return APR_ENOMEM; for (i = 0; i < in_vec; i++) { - char * base = vec[i].iov_base; - cur_len = vec[i].iov_len; - - do { - if (cur_len > APR_DWORD_MAX) { - pWsaBuf[j].buf = base; - pWsaBuf[j].len = APR_DWORD_MAX; - cur_len -= APR_DWORD_MAX; - base += APR_DWORD_MAX; - } - else { - pWsaBuf[j].buf = base; - pWsaBuf[j].len = (DWORD)cur_len; - cur_len = 0; - } - j++; - - } while (cur_len > 0); + pWsaBuf[i].buf = vec[i].iov_base; + pWsaBuf[i].len = (ULONG) vec[i].iov_len; } #ifndef _WIN32_WCE - rv = WSASend(sock->socketdes, pWsaBuf, nvec, &dwBytes, 0, NULL, NULL); + rv = WSASend(sock->socketdes, pWsaBuf, in_vec, &dwBytes, 0, NULL, NULL); if (rv == SOCKET_ERROR) { rc = apr_get_netos_error(); } #else - for (i = 0; i < nvec; i++) { + for (i = 0; i < in_vec; i++) { rv = send(sock->socketdes, pWsaBuf[i].buf, pWsaBuf[i].len, 0); if (rv == SOCKET_ERROR) { rc = apr_get_netos_error(); @@ -155,7 +145,7 @@ APR_DECLARE(apr_status_t) apr_socket_sendv(apr_socket_t *sock, dwBytes += rv; } #endif - if (nvec > WSABUF_ON_STACK) + if (in_vec > WSABUF_ON_STACK) free(pWsaBuf); *nbytes = dwBytes; |