@@ -1871,8 +1871,16 @@ PHP_FUNCTION(socket_set_option)
18711871 const char l_onoff_key [] = "l_onoff" ;
18721872 const char l_linger_key [] = "l_linger" ;
18731873
1874- convert_to_array (arg4 );
1875- opt_ht = Z_ARRVAL_P (arg4 );
1874+ if (Z_TYPE_P (arg4 ) != IS_ARRAY ) {
1875+ if (UNEXPECTED (Z_TYPE_P (arg4 ) != IS_OBJECT )) {
1876+ zend_argument_type_error (4 , "must be of type array when argument #3 ($option) is SO_LINGER, %s given" , zend_zval_value_name (arg4 ));
1877+ RETURN_THROWS ();
1878+ } else {
1879+ opt_ht = Z_OBJPROP_P (arg4 );
1880+ }
1881+ } else {
1882+ opt_ht = Z_ARRVAL_P (arg4 );
1883+ }
18761884
18771885 if ((l_onoff = zend_hash_str_find (opt_ht , l_onoff_key , sizeof (l_onoff_key ) - 1 )) == NULL ) {
18781886 zend_argument_value_error (4 , "must have key \"%s\"" , l_onoff_key );
@@ -1883,11 +1891,21 @@ PHP_FUNCTION(socket_set_option)
18831891 RETURN_THROWS ();
18841892 }
18851893
1886- convert_to_long (l_onoff );
1887- convert_to_long (l_linger );
1894+ zend_long val_lonoff = zval_get_long (l_onoff );
1895+ zend_long val_linger = zval_get_long (l_linger );
1896+
1897+ if (val_lonoff < 0 || val_lonoff > USHRT_MAX ) {
1898+ zend_argument_value_error (4 , "\"%s\" must be between 0 and %u" , l_onoff_key , USHRT_MAX );
1899+ RETURN_THROWS ();
1900+ }
1901+
1902+ if (val_linger < 0 || val_linger > USHRT_MAX ) {
1903+ zend_argument_value_error (4 , "\"%s\" must be between 0 and %d" , l_linger , USHRT_MAX );
1904+ RETURN_THROWS ();
1905+ }
18881906
1889- lv .l_onoff = (unsigned short )Z_LVAL_P ( l_onoff ) ;
1890- lv .l_linger = (unsigned short )Z_LVAL_P ( l_linger ) ;
1907+ lv .l_onoff = (unsigned short )val_lonoff ;
1908+ lv .l_linger = (unsigned short )val_linger ;
18911909
18921910 optlen = sizeof (lv );
18931911 opt_ptr = & lv ;
@@ -1899,8 +1917,18 @@ PHP_FUNCTION(socket_set_option)
18991917 const char sec_key [] = "sec" ;
19001918 const char usec_key [] = "usec" ;
19011919
1902- convert_to_array (arg4 );
1903- opt_ht = Z_ARRVAL_P (arg4 );
1920+ if (Z_TYPE_P (arg4 ) != IS_ARRAY ) {
1921+ if (UNEXPECTED (Z_TYPE_P (arg4 ) != IS_OBJECT )) {
1922+ zend_argument_type_error (4 , "must be of type array when argument #3 ($option) is %s, %s given" ,
1923+ optname == SO_RCVTIMEO ? "SO_RCVTIMEO" : "SO_SNDTIMEO" ,
1924+ zend_zval_value_name (arg4 ));
1925+ RETURN_THROWS ();
1926+ } else {
1927+ opt_ht = Z_OBJPROP_P (arg4 );
1928+ }
1929+ } else {
1930+ opt_ht = Z_ARRVAL_P (arg4 );
1931+ }
19041932
19051933 if ((sec = zend_hash_str_find (opt_ht , sec_key , sizeof (sec_key ) - 1 )) == NULL ) {
19061934 zend_argument_value_error (4 , "must have key \"%s\"" , sec_key );
@@ -1911,15 +1939,16 @@ PHP_FUNCTION(socket_set_option)
19111939 RETURN_THROWS ();
19121940 }
19131941
1914- convert_to_long (sec );
1915- convert_to_long (usec );
1942+ zend_long valsec = zval_get_long (sec );
1943+ zend_long valusec = zval_get_long (usec );
19161944#ifndef PHP_WIN32
1917- tv .tv_sec = Z_LVAL_P ( sec ) ;
1918- tv .tv_usec = Z_LVAL_P ( usec ) ;
1945+ tv .tv_sec = valsec ;
1946+ tv .tv_usec = valusec ;
19191947 optlen = sizeof (tv );
19201948 opt_ptr = & tv ;
19211949#else
1922- timeout = Z_LVAL_P (sec ) * 1000 + Z_LVAL_P (usec ) / 1000 ;
1950+ timeout = valsec * 1000 + valusec / 1000 ;
1951+
19231952 optlen = sizeof (int );
19241953 opt_ptr = & timeout ;
19251954#endif
@@ -1971,15 +2000,15 @@ PHP_FUNCTION(socket_set_option)
19712000
19722001#ifdef SO_ATTACH_REUSEPORT_CBPF
19732002 case SO_ATTACH_REUSEPORT_CBPF : {
1974- convert_to_long (arg4 );
2003+ zend_long cbpf_val = zval_get_long (arg4 );
19752004
1976- if (!Z_LVAL_P ( arg4 ) ) {
2005+ if (!cbpf_val ) {
19772006 ov = 1 ;
19782007 optlen = sizeof (ov );
19792008 opt_ptr = & ov ;
19802009 optname = SO_DETACH_BPF ;
19812010 } else {
1982- uint32_t k = (uint32_t )Z_LVAL_P ( arg4 ) ;
2011+ uint32_t k = (uint32_t )cbpf_val ;
19832012 static struct sock_filter cbpf [8 ] = {0 };
19842013 static struct sock_fprog bpfprog ;
19852014
@@ -2006,8 +2035,7 @@ PHP_FUNCTION(socket_set_option)
20062035
20072036 default :
20082037default_case :
2009- convert_to_long (arg4 );
2010- ov = Z_LVAL_P (arg4 );
2038+ ov = zval_get_long (arg4 );
20112039
20122040 optlen = sizeof (ov );
20132041 opt_ptr = & ov ;
0 commit comments