mirror of
https://github.com/php/php-src.git
synced 2024-11-24 02:15:04 +08:00
Fix #78210: Invalid pointer address
This is actually about three distinct issues: * If an empty string is passed as $address to `stream_socket_sendto()`, the `sa` is not initialized, so we must not pass it as `addr` to `php_stream_xport_sendto()`. * On POSIX, `recvfrom()` truncates messages which are too long to fit into the specified buffer (unless `MSG_PEEK` is given), discards the excessive bytes, and returns the buffer length. On Windows, the same happens, but `recvfrom()` returns `SOCKET_ERROR` with the error code `WSAEMSGSIZE`. We have to catch this for best POSIX compatibility. * In `php_network_parse_network_address_with_port()`, we have to zero `in6` (not only its alias `sa`) to properly support IPv6. Co-Authored-By: Nikita Popov <nikita.ppv@googlemail.com>
This commit is contained in:
parent
2462f2dab1
commit
53797c206a
1
NEWS
1
NEWS
@ -4,6 +4,7 @@ PHP NEWS
|
|||||||
|
|
||||||
- Core:
|
- Core:
|
||||||
. Fixed bug #79364 (When copy empty array, next key is unspecified). (cmb)
|
. Fixed bug #79364 (When copy empty array, next key is unspecified). (cmb)
|
||||||
|
. Fixed bug #78210 (Invalid pointer address). (cmb, Nikita)
|
||||||
|
|
||||||
- Spl:
|
- Spl:
|
||||||
. Fixed bug #75673 (SplStack::unserialize() behavior). (cmb)
|
. Fixed bug #75673 (SplStack::unserialize() behavior). (cmb)
|
||||||
|
@ -366,7 +366,7 @@ PHP_FUNCTION(stream_socket_sendto)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RETURN_LONG(php_stream_xport_sendto(stream, data, datalen, (int)flags, target_addr ? &sa : NULL, sl));
|
RETURN_LONG(php_stream_xport_sendto(stream, data, datalen, (int)flags, target_addr_len ? &sa : NULL, sl));
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
@ -512,9 +512,11 @@ PHPAPI int php_network_parse_network_address_with_port(const char *addr, zend_lo
|
|||||||
zend_string *errstr = NULL;
|
zend_string *errstr = NULL;
|
||||||
#if HAVE_IPV6
|
#if HAVE_IPV6
|
||||||
struct sockaddr_in6 *in6 = (struct sockaddr_in6*)sa;
|
struct sockaddr_in6 *in6 = (struct sockaddr_in6*)sa;
|
||||||
#endif
|
|
||||||
|
|
||||||
memset(sa, 0, sizeof(struct sockaddr));
|
memset(in6, 0, sizeof(struct sockaddr_in6));
|
||||||
|
#else
|
||||||
|
memset(in4, 0, sizeof(struct sockaddr_in));
|
||||||
|
#endif
|
||||||
|
|
||||||
if (*addr == '[') {
|
if (*addr == '[') {
|
||||||
colon = memchr(addr + 1, ']', addrlen-1);
|
colon = memchr(addr + 1, ']', addrlen-1);
|
||||||
|
@ -272,6 +272,12 @@ static inline int sock_recvfrom(php_netstream_data_t *sock, char *buf, size_t bu
|
|||||||
socklen_t sl = sizeof(sa);
|
socklen_t sl = sizeof(sa);
|
||||||
ret = recvfrom(sock->socket, buf, XP_SOCK_BUF_SIZE(buflen), flags, (struct sockaddr*)&sa, &sl);
|
ret = recvfrom(sock->socket, buf, XP_SOCK_BUF_SIZE(buflen), flags, (struct sockaddr*)&sa, &sl);
|
||||||
ret = (ret == SOCK_CONN_ERR) ? -1 : ret;
|
ret = (ret == SOCK_CONN_ERR) ? -1 : ret;
|
||||||
|
#ifdef PHP_WIN32
|
||||||
|
/* POSIX discards excess bytes without signalling failure; emulate this on Windows */
|
||||||
|
if (ret == -1 && WSAGetLastError() == WSAEMSGSIZE) {
|
||||||
|
ret = buflen;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (sl) {
|
if (sl) {
|
||||||
php_network_populate_name_from_sockaddr((struct sockaddr*)&sa, sl,
|
php_network_populate_name_from_sockaddr((struct sockaddr*)&sa, sl,
|
||||||
textaddr, addr, addrlen);
|
textaddr, addr, addrlen);
|
||||||
|
Loading…
Reference in New Issue
Block a user