@@ -1646,6 +1646,8 @@ PHP_FUNCTION(socket_get_option)
16461646 struct timeval tv ;
16471647#ifdef PHP_WIN32
16481648 DWORD timeout = 0 ;
1649+ #else
1650+ struct timeval timeout ;
16491651#endif
16501652 socklen_t optlen ;
16511653 php_socket * php_sock ;
@@ -1749,23 +1751,19 @@ PHP_FUNCTION(socket_get_option)
17491751
17501752 case SO_RCVTIMEO :
17511753 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
17601754 optlen = sizeof (timeout );
17611755
17621756 if (getsockopt (php_sock -> bsd_socket , level , optname , (char * )& timeout , & optlen ) != 0 ) {
17631757 PHP_SOCKET_ERROR (php_sock , "Unable to retrieve socket option" , errno );
17641758 RETURN_FALSE ;
17651759 }
17661760
1761+ #ifndef PHP_WIN32
1762+ tv .tv_sec = timeout .tv_sec ;
1763+ tv .tv_usec = timeout .tv_usec ;
1764+ #else
17671765 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 ;
17691767#endif
17701768
17711769 array_init (return_value );
@@ -2046,7 +2044,24 @@ PHP_FUNCTION(socket_set_option)
20462044 optlen = sizeof (tv );
20472045 opt_ptr = & tv ;
20482046#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 ;
20502065 optlen = sizeof (timeout );
20512066 opt_ptr = & timeout ;
20522067#endif
0 commit comments