diff options
author | Boris Lytochkin <lytboris@php.net> | 2013-02-07 14:49:45 +0400 |
---|---|---|
committer | Boris Lytochkin <lytboris@php.net> | 2013-02-07 14:49:45 +0400 |
commit | 6c5c04888d95c7e5f7d3b355df6c302cb23161d0 (patch) | |
tree | cdb58cd8f4b065021ae11bf5c690cb2a669dde1d /ext/snmp | |
parent | 4730bc86801e593b8e910e3dce30e32cd758adee (diff) | |
parent | ed6763420c10c5eb47d6db675322ecaa6de079b6 (diff) | |
download | php-git-6c5c04888d95c7e5f7d3b355df6c302cb23161d0.tar.gz |
Merge branch 'PHP-5.4' into PHP-5.5
* PHP-5.4:
fix bug #64124 (IPv6 malformed)
Diffstat (limited to 'ext/snmp')
-rw-r--r-- | ext/snmp/snmp.c | 23 | ||||
-rw-r--r-- | ext/snmp/tests/bug64124.phpt | 40 |
2 files changed, 52 insertions, 11 deletions
diff --git a/ext/snmp/snmp.c b/ext/snmp/snmp.c index 2e5b5f1363..6f2f070f21 100644 --- a/ext/snmp/snmp.c +++ b/ext/snmp/snmp.c @@ -1111,8 +1111,7 @@ static int php_snmp_parse_oid(zval *object, int st, struct objid_query *objid_qu static int netsnmp_session_init(php_snmp_session **session_p, int version, char *hostname, char *community, int timeout, int retries TSRMLS_DC) { php_snmp_session *session; - char *pptr; - char buf[MAX_NAME_LEN]; + char *pptr, *host_ptr; int force_ipv6 = FALSE; int n; struct sockaddr **psal; @@ -1126,8 +1125,6 @@ static int netsnmp_session_init(php_snmp_session **session_p, int version, char } memset(session, 0, sizeof(php_snmp_session)); - strlcpy(buf, hostname, sizeof(buf)); - snmp_sess_init(session); session->version = version; @@ -1138,13 +1135,15 @@ static int netsnmp_session_init(php_snmp_session **session_p, int version, char php_error_docref(NULL TSRMLS_CC, E_WARNING, "emalloc() failed while copying hostname"); return (-1); } - *(session->peername) = '\0'; + /* we copy original hostname for further processing */ + strlcpy(session->peername, hostname, MAX_NAME_LEN); + host_ptr = session->peername; /* Reading the hostname and its optional non-default port number */ - if (*hostname == '[') { /* IPv6 address */ + if (*host_ptr == '[') { /* IPv6 address */ force_ipv6 = TRUE; - hostname++; - if ((pptr = strchr(hostname, ']'))) { + host_ptr++; + if ((pptr = strchr(host_ptr, ']'))) { if (pptr[1] == ':') { session->remote_port = atoi(pptr + 2); } @@ -1154,7 +1153,7 @@ static int netsnmp_session_init(php_snmp_session **session_p, int version, char return (-1); } } else { /* IPv4 address */ - if ((pptr = strchr(hostname, ':'))) { + if ((pptr = strchr(host_ptr, ':'))) { session->remote_port = atoi(pptr + 1); *pptr = '\0'; } @@ -1162,11 +1161,13 @@ static int netsnmp_session_init(php_snmp_session **session_p, int version, char /* since Net-SNMP library requires 'udp6:' prefix for all IPv6 addresses (in FQDN form too) we need to perform possible name resolution before running any SNMP queries */ - if ((n = php_network_getaddresses(hostname, SOCK_DGRAM, &psal, NULL TSRMLS_CC)) == 0) { /* some resover error */ + if ((n = php_network_getaddresses(host_ptr, SOCK_DGRAM, &psal, NULL TSRMLS_CC)) == 0) { /* some resolver error */ /* warnings sent, bailing out */ return (-1); } + /* we have everything we need in psal, flush peername and fill it properly */ + *(session->peername) = '\0'; res = psal; while (n-- > 0) { pptr = session->peername; @@ -1196,7 +1197,7 @@ static int netsnmp_session_init(php_snmp_session **session_p, int version, char } if (strlen(session->peername) == 0) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown failure while resolving '%s'", buf); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown failure while resolving '%s'", hostname); return (-1); } /* XXX FIXME diff --git a/ext/snmp/tests/bug64124.phpt b/ext/snmp/tests/bug64124.phpt new file mode 100644 index 0000000000..454b06dcf1 --- /dev/null +++ b/ext/snmp/tests/bug64124.phpt @@ -0,0 +1,40 @@ +--TEST-- +Bug #64124 IPv6 malformed +--CREDITS-- +Boris Lytochkin +--SKIPIF-- +<?php +require_once(dirname(__FILE__).'/skipif.inc'); + +$packed = str_repeat(chr(0), 15) . chr(1); +if (@inet_ntop($packed) === false) { + die("skip no IPv6 support"); +} +?> +--FILE-- +<?php +require_once(dirname(__FILE__).'/snmp_include.inc'); + +# hostname variable was modified inline in netsnmp_session_init() +# Should be checked with IPv6 since IPv4 processing code do not alter pointer position + +//EXPECTF format is quickprint OFF +snmp_set_quick_print(false); +snmp_set_valueretrieval(SNMP_VALUE_PLAIN); + +$checkvar = "$hostname6_port"; + +var_dump(snmpget($checkvar, $community, '.1.3.6.1.2.1.1.1.0')); +var_dump(($checkvar === $hostname6_port)); +var_dump(snmpget($checkvar, $community, '.1.3.6.1.2.1.1.1.0')); +var_dump(($checkvar === $hostname6_port)); +var_dump(snmpget($checkvar, $community, '.1.3.6.1.2.1.1.1.0')); +var_dump(($checkvar === $hostname6_port)); +?> +--EXPECTF-- +%unicode|string%(%d) "%s" +bool(true) +%unicode|string%(%d) "%s" +bool(true) +%unicode|string%(%d) "%s" +bool(true) |