Skip to content

Commit 750f3d3

Browse files
bp1222nikic
authored andcommitted
Improve getaddrinfo implementation
* Fix some leaks * Improve some comparisons and casts * Raise a notice when an unknown hint is provided
1 parent b8b47ed commit 750f3d3

File tree

2 files changed

+31
-21
lines changed

2 files changed

+31
-21
lines changed

ext/sockets/sockets.c

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2516,36 +2516,38 @@ PHP_FUNCTION(socket_export_stream)
25162516
Gets array with contents of getaddrinfo about the given hostname. */
25172517
PHP_FUNCTION(socket_addrinfo_lookup)
25182518
{
2519+
char *service = NULL;
2520+
size_t service_len;
25192521
zend_string *hostname, *key;
2520-
zval *hint, *service, *zhints = NULL;
2522+
zval *hint, *zhints = NULL;
25212523

25222524
struct addrinfo hints, *result, *rp, *res;
25232525

25242526
memset(&hints, 0, sizeof(hints));
25252527

2526-
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S|za", &hostname, &service, &zhints) == FAILURE) {
2528+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S|sa", &hostname, &service, &service_len, &zhints) == FAILURE) {
25272529
RETURN_NULL();
25282530
}
25292531

25302532
if (zhints) {
25312533
ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(zhints), key, hint) {
25322534
if (key) {
2533-
if (strcmp(ZSTR_VAL(key), "ai_flags") == 0) {
2534-
hints.ai_flags = Z_LVAL_P(hint);
2535-
} else if (strcmp(ZSTR_VAL(key), "ai_socktype") == 0) {
2536-
hints.ai_socktype = Z_LVAL_P(hint);
2537-
} else if (strcmp(ZSTR_VAL(key), "ai_protocol") == 0) {
2538-
hints.ai_protocol = Z_LVAL_P(hint);
2539-
} else if (strcmp(ZSTR_VAL(key), "ai_family") == 0) {
2540-
hints.ai_family = Z_LVAL_P(hint);
2535+
if (zend_string_equals_literal(key, "ai_flags")) {
2536+
hints.ai_flags = zval_get_long(hint);
2537+
} else if (zend_string_equals_literal(key, "ai_socktype")) {
2538+
hints.ai_socktype = zval_get_long(hint);
2539+
} else if (zend_string_equals_literal(key, "ai_protocol")) {
2540+
hints.ai_protocol = zval_get_long(hint);
2541+
} else if (zend_string_equals_literal(key, "ai_family")) {
2542+
hints.ai_family = zval_get_long(hint);
2543+
} else {
2544+
php_error_docref(NULL, E_NOTICE, "Unknown hint %s", ZSTR_VAL(key));
25412545
}
25422546
}
25432547
} ZEND_HASH_FOREACH_END();
25442548
}
25452549

2546-
convert_to_string(service);
2547-
2548-
if (getaddrinfo(ZSTR_VAL(hostname), Z_STRVAL_P(service), &hints, &result) != 0) {
2550+
if (getaddrinfo(ZSTR_VAL(hostname), service, &hints, &result) != 0) {
25492551
RETURN_FALSE;
25502552
}
25512553

@@ -2578,18 +2580,17 @@ PHP_FUNCTION(socket_addrinfo_bind)
25782580
zval *arg1;
25792581
int retval;
25802582
struct addrinfo *ai;
2581-
php_socket *php_sock = php_create_socket();
2583+
php_socket *php_sock;
25822584

25832585
if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &arg1) == FAILURE) {
2584-
efree(php_sock);
25852586
return;
25862587
}
25872588

25882589
if ((ai = (struct addrinfo *) zend_fetch_resource(Z_RES_P(arg1), le_addrinfo_name, le_addrinfo)) == NULL) {
2589-
efree(php_sock);
25902590
RETURN_FALSE;
25912591
}
25922592

2593+
php_sock = php_create_socket();
25932594
php_sock->bsd_socket = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
25942595
php_sock->type = ai->ai_family;
25952596

@@ -2607,7 +2608,9 @@ PHP_FUNCTION(socket_addrinfo_bind)
26072608
case AF_UNIX:
26082609
{
26092610
// AF_UNIX sockets via getaddrino are not implemented due to security problems
2610-
break;
2611+
close(php_sock->bsd_socket);
2612+
efree(php_sock);
2613+
RETURN_FALSE;
26112614
}
26122615

26132616
case AF_INET:
@@ -2620,12 +2623,14 @@ PHP_FUNCTION(socket_addrinfo_bind)
26202623
}
26212624
default:
26222625
php_error_docref(NULL, E_WARNING, "unsupported socket type '%d', must be AF_UNIX, AF_INET, or AF_INET6", php_sock->type);
2626+
close(php_sock->bsd_socket);
26232627
efree(php_sock);
26242628
RETURN_FALSE;
26252629
}
26262630

26272631
if (retval != 0) {
26282632
PHP_SOCKET_ERROR(php_sock, "unable to bind address", errno);
2633+
close(php_sock->bsd_socket);
26292634
efree(php_sock);
26302635
RETURN_FALSE;
26312636
}
@@ -2641,18 +2646,17 @@ PHP_FUNCTION(socket_addrinfo_connect)
26412646
zval *arg1;
26422647
int retval;
26432648
struct addrinfo *ai;
2644-
php_socket *php_sock = php_create_socket();
2649+
php_socket *php_sock;
26452650

26462651
if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &arg1) == FAILURE) {
2647-
efree(php_sock);
26482652
return;
26492653
}
26502654

26512655
if ((ai = (struct addrinfo *) zend_fetch_resource(Z_RES_P(arg1), le_addrinfo_name, le_addrinfo)) == NULL) {
2652-
efree(php_sock);
26532656
RETURN_FALSE;
26542657
}
26552658

2659+
php_sock = php_create_socket();
26562660
php_sock->bsd_socket = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
26572661
php_sock->type = ai->ai_family;
26582662

@@ -2670,7 +2674,9 @@ PHP_FUNCTION(socket_addrinfo_connect)
26702674
case AF_UNIX:
26712675
{
26722676
// AF_UNIX sockets via getaddrino are not implemented due to security problems
2673-
break;
2677+
close(php_sock->bsd_socket);
2678+
efree(php_sock);
2679+
RETURN_FALSE;
26742680
}
26752681

26762682
case AF_INET:
@@ -2683,12 +2689,14 @@ PHP_FUNCTION(socket_addrinfo_connect)
26832689
}
26842690
default:
26852691
php_error_docref(NULL, E_WARNING, "unsupported socket type '%d', must be AF_UNIX, AF_INET, or AF_INET6", php_sock->type);
2692+
close(php_sock->bsd_socket);
26862693
efree(php_sock);
26872694
RETURN_FALSE;
26882695
}
26892696

26902697
if (retval != 0) {
26912698
PHP_SOCKET_ERROR(php_sock, "unable to connect address", errno);
2699+
close(php_sock->bsd_socket);
26922700
efree(php_sock);
26932701
RETURN_FALSE;
26942702
}

ext/sockets/tests/socket_addrinfo_lookup.phpt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@ if (!extension_loaded('sockets')) {
1010
$addrinfo = socket_addrinfo_lookup('127.0.0.1', 2000, array(
1111
'ai_family' => AF_INET,
1212
'ai_socktype' => SOCK_DGRAM,
13+
'invalid' => null,
1314
));
1415
var_dump($addrinfo[0]);
1516
echo "Done";
1617
--EXPECTF--
18+
Notice: socket_addrinfo_lookup(): Unknown hint invalid in %ssocket_addrinfo_lookup.php on line %d
1719
resource(%d) of type (AddressInfo)
1820
Done

0 commit comments

Comments
 (0)