diff --git a/ext/standard/tests/network/gh24616.phpt b/ext/standard/tests/network/gh24616.phpt new file mode 100644 index 00000000000..5a039805f8a --- /dev/null +++ b/ext/standard/tests/network/gh24616.phpt @@ -0,0 +1,37 @@ +--TEST-- +GH-24616 (fsockopen()/stream_socket_client() accept TCP ports above 65535) +--FILE-- + +--EXPECT-- +bool(false) +bool(true) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(true) diff --git a/ext/standard/tests/streams/bug69521.phpt b/ext/standard/tests/streams/bug69521.phpt index d335a68736e..71b619e79f0 100644 --- a/ext/standard/tests/streams/bug69521.phpt +++ b/ext/standard/tests/streams/bug69521.phpt @@ -2,8 +2,8 @@ Bug #69521 (Segfault in gc_collect_cycles()) --FILE-- 65535) { + return FAILURE; } tmp = estrndup(addr, colon - addr); diff --git a/main/streams/xp_socket.c b/main/streams/xp_socket.c index ac4194936b5..558463c5cbe 100644 --- a/main/streams/xp_socket.c +++ b/main/streams/xp_socket.c @@ -615,6 +615,17 @@ static inline int parse_unix_address(php_stream_xport_param *xparam, struct sock } #endif +static inline bool parse_port(const char *str, int *portno) +{ + /* Like atoi(), but reject ports that do not fit in 16 bits */ + zend_long port = ZEND_STRTOL(str, NULL, 10); + if (port < 0 || port > 65535) { + return false; + } + *portno = (int) port; + return true; +} + static inline char *parse_ip_address_ex(const char *str, size_t str_len, int *portno, int get_err, zend_string **err) { const char *colon; @@ -635,7 +646,12 @@ static inline char *parse_ip_address_ex(const char *str, size_t str_len, int *po } return NULL; } - *portno = atoi(p + 2); + if (!parse_port(p + 2, portno)) { + if (get_err) { + *err = strpprintf(0, "Failed to parse port of address \"%s\"", str); + } + return NULL; + } return estrndup(str + 1, p - str - 1); } #endif @@ -645,7 +661,12 @@ static inline char *parse_ip_address_ex(const char *str, size_t str_len, int *po colon = NULL; } if (colon) { - *portno = atoi(colon + 1); + if (!parse_port(colon + 1, portno)) { + if (get_err) { + *err = strpprintf(0, "Failed to parse port of address \"%s\"", str); + } + return NULL; + } host = estrndup(str, colon - str); } else { if (get_err) {