@@ -1646,6 +1646,8 @@ PHP_FUNCTION(socket_get_option)
1646
1646
struct timeval tv ;
1647
1647
#ifdef PHP_WIN32
1648
1648
DWORD timeout = 0 ;
1649
+ #else
1650
+ struct timeval timeout ;
1649
1651
#endif
1650
1652
socklen_t optlen ;
1651
1653
php_socket * php_sock ;
@@ -1749,23 +1751,19 @@ PHP_FUNCTION(socket_get_option)
1749
1751
1750
1752
case SO_RCVTIMEO :
1751
1753
case SO_SNDTIMEO :
1752
- #ifndef PHP_WIN32
1753
- optlen = sizeof (tv );
1754
-
1755
- if (getsockopt (php_sock -> bsd_socket , level , optname , (char * )& tv , & optlen ) != 0 ) {
1756
- PHP_SOCKET_ERROR (php_sock , "Unable to retrieve socket option" , errno );
1757
- RETURN_FALSE ;
1758
- }
1759
- #else
1760
1754
optlen = sizeof (timeout );
1761
1755
1762
1756
if (getsockopt (php_sock -> bsd_socket , level , optname , (char * )& timeout , & optlen ) != 0 ) {
1763
1757
PHP_SOCKET_ERROR (php_sock , "Unable to retrieve socket option" , errno );
1764
1758
RETURN_FALSE ;
1765
1759
}
1766
1760
1761
+ #ifndef PHP_WIN32
1762
+ tv .tv_sec = timeout .tv_sec ;
1763
+ tv .tv_usec = timeout .tv_usec ;
1764
+ #else
1767
1765
tv .tv_sec = timeout ? (long )(timeout / 1000 ) : 0 ;
1768
- tv .tv_usec = timeout ? (long )((timeout * 1000 ) % 1000000 ) : 0 ;
1766
+ tv .tv_usec = timeout ? (long )((timeout % 1000 ) * 1000 ) : 0 ;
1769
1767
#endif
1770
1768
1771
1769
array_init (return_value );
@@ -2046,7 +2044,24 @@ PHP_FUNCTION(socket_set_option)
2046
2044
optlen = sizeof (tv );
2047
2045
opt_ptr = & tv ;
2048
2046
#else
2049
- timeout = Z_LVAL_P (sec ) * 1000 + Z_LVAL_P (usec ) / 1000 ;
2047
+ if (valsec < 0 || valsec > ULONG_MAX / 1000 ) {
2048
+ zend_argument_value_error (4 , "\"%s\" must be between 0 and %u" , sec_key , (ULONG_MAX / 1000 ));
2049
+ RETURN_THROWS ();
2050
+ }
2051
+
2052
+ timeout = valsec * 1000 ;
2053
+
2054
+
2055
+ /*
2056
+ * We deliberately throw if (valusec / 1000) > ULONG_MAX, treating it as a programmer error.
2057
+ * On Windows, ULONG_MAX = 2^32, unlike ZEND_LONG_MAX = 2^63.
2058
+ */
2059
+ if (valusec < 0 || timeout > ULONG_MAX - (valusec / 1000 )) {
2060
+ zend_argument_value_error (4 , "\"%s\" must be between 0 and %u" , usec_key , (DWORD )(ULONG_MAX - (valusec / 1000 )));
2061
+ RETURN_THROWS ();
2062
+ }
2063
+
2064
+ timeout += valusec / 1000 ;
2050
2065
optlen = sizeof (timeout );
2051
2066
opt_ptr = & timeout ;
2052
2067
#endif
0 commit comments