Skip to content

Commit 1a14443

Browse files
committed
changes from review also attempt to prevent UB with timeout on windows.
1 parent 6c5f436 commit 1a14443

File tree

1 file changed

+23
-13
lines changed

1 file changed

+23
-13
lines changed

ext/sockets/sockets.c

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1877,7 +1877,6 @@ PHP_FUNCTION(socket_set_option)
18771877
RETURN_THROWS();
18781878
}
18791879

1880-
convert_to_array(arg4);
18811880
opt_ht = Z_ARRVAL_P(arg4);
18821881

18831882
if ((l_onoff = zend_hash_str_find(opt_ht, l_onoff_key, sizeof(l_onoff_key) - 1)) == NULL) {
@@ -1889,29 +1888,29 @@ PHP_FUNCTION(socket_set_option)
18891888
RETURN_THROWS();
18901889
}
18911890

1892-
zend_long zl_onoff = zval_try_get_long(l_onoff, &failed);
1891+
zend_long vall_lonoff = zval_try_get_long(l_onoff, &failed);
18931892
if (failed) {
18941893
zend_argument_type_error(4, "\"%s\" must be of type int, %s given", l_onoff_key, zend_zval_value_name(l_onoff));
18951894
RETURN_THROWS();
18961895
}
1897-
zend_long zl_linger = zval_try_get_long(l_linger, &failed);
1896+
zend_long vall_linger = zval_try_get_long(l_linger, &failed);
18981897
if (failed) {
18991898
zend_argument_type_error(4, "\"%s\" must be of type int, %s given", l_linger_key, zend_zval_value_name(l_linger));
19001899
RETURN_THROWS();
19011900
}
19021901

1903-
if (zl_onoff < 0 || zl_onoff > USHRT_MAX) {
1902+
if (vall_lonoff < 0 || vall_lonoff > USHRT_MAX) {
19041903
zend_argument_value_error(4, "\"%s\" must be between 0 and %u", l_onoff_key, USHRT_MAX);
19051904
RETURN_THROWS();
19061905
}
19071906

1908-
if (zl_linger < 0 || zl_linger > USHRT_MAX) {
1907+
if (vall_linger < 0 || vall_linger > USHRT_MAX) {
19091908
zend_argument_value_error(4, "\"%s\" must be between 0 and %d", l_linger, USHRT_MAX);
19101909
RETURN_THROWS();
19111910
}
19121911

1913-
lv.l_onoff = (unsigned short)zl_onoff;
1914-
lv.l_linger = (unsigned short)zl_linger;
1912+
lv.l_onoff = (unsigned short)vall_lonoff;
1913+
lv.l_linger = (unsigned short)vall_linger;
19151914

19161915
optlen = sizeof(lv);
19171916
opt_ptr = &lv;
@@ -1928,7 +1927,6 @@ PHP_FUNCTION(socket_set_option)
19281927
RETURN_THROWS();
19291928
}
19301929

1931-
convert_to_array(arg4);
19321930
opt_ht = Z_ARRVAL_P(arg4);
19331931

19341932
if ((sec = zend_hash_str_find(opt_ht, sec_key, sizeof(sec_key) - 1)) == NULL) {
@@ -1940,23 +1938,35 @@ PHP_FUNCTION(socket_set_option)
19401938
RETURN_THROWS();
19411939
}
19421940

1943-
zend_long zsec = zval_try_get_long(sec, &failed);
1941+
zend_long valsec = zval_try_get_long(sec, &failed);
19441942
if (failed) {
19451943
zend_argument_type_error(4, "\"%s\" must be of type int, %s given", sec_key, zend_zval_value_name(sec));
19461944
RETURN_THROWS();
19471945
}
1948-
zend_long zusec = zval_try_get_long(usec, &failed);
1946+
zend_long valusec = zval_try_get_long(usec, &failed);
19491947
if (failed) {
19501948
zend_argument_type_error(4, "\"%s\" must be of type int, %s given", usec_key, zend_zval_value_name(usec));
19511949
RETURN_THROWS();
19521950
}
19531951
#ifndef PHP_WIN32
1954-
tv.tv_sec = zsec;
1955-
tv.tv_usec = zusec;
1952+
tv.tv_sec = valsec;
1953+
tv.tv_usec = valusec;
19561954
optlen = sizeof(tv);
19571955
opt_ptr = &tv;
19581956
#else
1959-
timeout = zsec * 1000 + zusec / 1000;
1957+
if (valsec < 0 || valsec > INT_MAX / 1000) {
1958+
zend_argument_value_error(4, "\"%s\" must be between 0 and %d", sec_key, INT_MAX / 1000);
1959+
RETURN_THROWS();
1960+
}
1961+
1962+
timeout = valsec * 1000;
1963+
1964+
if (valusec < 0 || timeout > INT_MAX - (valusec / 1000)) {
1965+
zend_argument_value_error(4, "\"%s\" must be between 0 and %u", usec_key, (DWORD)(INT_MAX - (valusec / 1000)));
1966+
RETURN_THROWS();
1967+
}
1968+
1969+
timeout += valusec / 1000;
19601970
optlen = sizeof(int);
19611971
opt_ptr = &timeout;
19621972
#endif

0 commit comments

Comments
 (0)