@@ -1930,8 +1930,16 @@ PHP_FUNCTION(socket_set_option)
19301930 const char l_onoff_key [] = "l_onoff" ;
19311931 const char l_linger_key [] = "l_linger" ;
19321932
1933- convert_to_array (arg4 );
1934- opt_ht = Z_ARRVAL_P (arg4 );
1933+ if (Z_TYPE_P (arg4 ) != IS_ARRAY ) {
1934+ if (UNEXPECTED (Z_TYPE_P (arg4 ) != IS_OBJECT )) {
1935+ zend_argument_type_error (4 , "must be of type array when argument #3 ($option) is SO_LINGER, %s given" , zend_zval_value_name (arg4 ));
1936+ RETURN_THROWS ();
1937+ } else {
1938+ opt_ht = Z_OBJPROP_P (arg4 );
1939+ }
1940+ } else {
1941+ opt_ht = Z_ARRVAL_P (arg4 );
1942+ }
19351943
19361944 if ((l_onoff = zend_hash_str_find (opt_ht , l_onoff_key , sizeof (l_onoff_key ) - 1 )) == NULL ) {
19371945 zend_argument_value_error (4 , "must have key \"%s\"" , l_onoff_key );
@@ -1942,11 +1950,21 @@ PHP_FUNCTION(socket_set_option)
19421950 RETURN_THROWS ();
19431951 }
19441952
1945- convert_to_long (l_onoff );
1946- convert_to_long (l_linger );
1953+ zend_long val_lonoff = zval_get_long (l_onoff );
1954+ zend_long val_linger = zval_get_long (l_linger );
1955+
1956+ if (val_lonoff < 0 || val_lonoff > USHRT_MAX ) {
1957+ zend_argument_value_error (4 , "\"%s\" must be between 0 and %u" , l_onoff_key , USHRT_MAX );
1958+ RETURN_THROWS ();
1959+ }
1960+
1961+ if (val_linger < 0 || val_linger > USHRT_MAX ) {
1962+ zend_argument_value_error (4 , "\"%s\" must be between 0 and %d" , l_linger , USHRT_MAX );
1963+ RETURN_THROWS ();
1964+ }
19471965
1948- lv .l_onoff = (unsigned short )Z_LVAL_P ( l_onoff ) ;
1949- lv .l_linger = (unsigned short )Z_LVAL_P ( l_linger ) ;
1966+ lv .l_onoff = (unsigned short )val_lonoff ;
1967+ lv .l_linger = (unsigned short )val_linger ;
19501968
19511969 optlen = sizeof (lv );
19521970 opt_ptr = & lv ;
@@ -1958,8 +1976,18 @@ PHP_FUNCTION(socket_set_option)
19581976 const char sec_key [] = "sec" ;
19591977 const char usec_key [] = "usec" ;
19601978
1961- convert_to_array (arg4 );
1962- opt_ht = Z_ARRVAL_P (arg4 );
1979+ if (Z_TYPE_P (arg4 ) != IS_ARRAY ) {
1980+ if (UNEXPECTED (Z_TYPE_P (arg4 ) != IS_OBJECT )) {
1981+ zend_argument_type_error (4 , "must be of type array when argument #3 ($option) is %s, %s given" ,
1982+ optname == SO_RCVTIMEO ? "SO_RCVTIMEO" : "SO_SNDTIMEO" ,
1983+ zend_zval_value_name (arg4 ));
1984+ RETURN_THROWS ();
1985+ } else {
1986+ opt_ht = Z_OBJPROP_P (arg4 );
1987+ }
1988+ } else {
1989+ opt_ht = Z_ARRVAL_P (arg4 );
1990+ }
19631991
19641992 if ((sec = zend_hash_str_find (opt_ht , sec_key , sizeof (sec_key ) - 1 )) == NULL ) {
19651993 zend_argument_value_error (4 , "must have key \"%s\"" , sec_key );
@@ -1970,15 +1998,16 @@ PHP_FUNCTION(socket_set_option)
19701998 RETURN_THROWS ();
19711999 }
19722000
1973- convert_to_long (sec );
1974- convert_to_long (usec );
2001+ zend_long valsec = zval_get_long (sec );
2002+ zend_long valusec = zval_get_long (usec );
19752003#ifndef PHP_WIN32
1976- tv .tv_sec = Z_LVAL_P ( sec ) ;
1977- tv .tv_usec = Z_LVAL_P ( usec ) ;
2004+ tv .tv_sec = valsec ;
2005+ tv .tv_usec = valusec ;
19782006 optlen = sizeof (tv );
19792007 opt_ptr = & tv ;
19802008#else
1981- timeout = Z_LVAL_P (sec ) * 1000 + Z_LVAL_P (usec ) / 1000 ;
2009+ timeout = valsec * 1000 + valusec / 1000 ;
2010+
19822011 optlen = sizeof (int );
19832012 opt_ptr = & timeout ;
19842013#endif
@@ -2030,15 +2059,15 @@ PHP_FUNCTION(socket_set_option)
20302059
20312060#ifdef SO_ATTACH_REUSEPORT_CBPF
20322061 case SO_ATTACH_REUSEPORT_CBPF : {
2033- convert_to_long (arg4 );
2062+ zend_long cbpf_val = zval_get_long (arg4 );
20342063
2035- if (!Z_LVAL_P ( arg4 ) ) {
2064+ if (!cbpf_val ) {
20362065 ov = 1 ;
20372066 optlen = sizeof (ov );
20382067 opt_ptr = & ov ;
20392068 optname = SO_DETACH_BPF ;
20402069 } else {
2041- uint32_t k = (uint32_t )Z_LVAL_P ( arg4 ) ;
2070+ uint32_t k = (uint32_t )cbpf_val ;
20422071 static struct sock_filter cbpf [8 ] = {0 };
20432072 static struct sock_fprog bpfprog ;
20442073
@@ -2065,8 +2094,7 @@ PHP_FUNCTION(socket_set_option)
20652094
20662095 default :
20672096default_case :
2068- convert_to_long (arg4 );
2069- ov = Z_LVAL_P (arg4 );
2097+ ov = zval_get_long (arg4 );
20702098
20712099 optlen = sizeof (ov );
20722100 opt_ptr = & ov ;
0 commit comments