diff --git a/ext/filter/logical_filters.c b/ext/filter/logical_filters.c index 0ce76ae2dd45f..2cf2651867e64 100644 --- a/ext/filter/logical_filters.c +++ b/ext/filter/logical_filters.c @@ -452,6 +452,8 @@ void php_filter_validate_regexp(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ } /* }}} */ +static int _php_filter_validate_ipv6(char *str, int str_len TSRMLS_DC); + void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ { php_url *url; @@ -471,28 +473,36 @@ void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ } if (url->scheme != NULL && (!strcasecmp(url->scheme, "http") || !strcasecmp(url->scheme, "https"))) { - char *e, *s; + char *e, *s, *t; unsigned char i = 1; - size_t len; + size_t l; if (url->host == NULL) { goto bad_url; } - len = strlen(url->host); + s = url->host; + l = strlen(s); + e = url->host + l; + t = e - 1; + + /* An IPv6 enclosed by square brackets is a valid hostname */ + if (*s == '[' && *t == ']' && _php_filter_validate_ipv6((s + 1), l - 2 TSRMLS_CC)) { + php_url_free(url); + return; + } /* Ignore trailing dot */ - if (*(url->host + len - 1) == '.') { - len--; + if (*t == '.') { + e = t; + l--; } - if (len > 253) { + /* The total length of an hostname cannot exceed 253 characters (final dot not included) */ + if (l > 253) { goto bad_url; } - e = url->host + len; - s = url->host; - /* First char of hostname must be alphanumeric */ if(!isalnum((int)*(unsigned char *)s)) { goto bad_url; diff --git a/ext/filter/tests/015.phpt b/ext/filter/tests/015.phpt index cf59d9ee359cb..a5d764934a3c7 100644 --- a/ext/filter/tests/015.phpt +++ b/ext/filter/tests/015.phpt @@ -15,6 +15,10 @@ $values = Array( 'http://toolongtoolongtoolongtoolongtoolongtoolongtoolongtoolongtoolongtoolong.com', 'http://eauBcFReEmjLcoZwI0RuONNnwU4H9r151juCaqTI5VeIP5jcYIqhx1lh5vV00l2rTs6y7hOp7rYw42QZiq6VIzjcYrRm8gFRMk9U9Wi1grL8Mr5kLVloYLthHgyA94QK3SaXCATklxgo6XvcbXIqAGG7U0KxTr8hJJU1p2ZQ2mXHmp4DhYP8N9SRuEKzaCPcSIcW7uj21jZqBigsLsNAXEzU8SPXZjmVQVtwQATPWeWyGW4GuJhjP4Q8o0.com', 'http://kDTvHt1PPDgX5EiP2MwiXjcoWNOhhTuOVAUWJ3TmpBYCC9QoJV114LMYrV3Zl58.kDTvHt1PPDgX5EiP2MwiXjcoWNOhhTuOVAUWJ3TmpBYCC9QoJV114LMYrV3Zl58.kDTvHt1PPDgX5EiP2MwiXjcoWNOhhTuOVAUWJ3TmpBYCC9QoJV114LMYrV3Zl58.CQ1oT5Uq3jJt6Uhy3VH9u3Gi5YhfZCvZVKgLlaXNFhVKB1zJxvunR7SJa.com.', +'http://[2001:0db8:0000:85a3:0000:0000:ac1f:8001]', +'http://[2001:db8:0:85a3:0:0:ac1f:8001]:123/me.html', +'http://[2001:db8:0:85a3::ac1f:8001]/', +'http://[::1]', 'http://cont-ains.h-yph-en-s.com', 'http://..com', 'http://a.-bc.com', @@ -71,6 +75,10 @@ string(79) "http://www.thelongestdomainnameintheworldandthensomeandthensomemorea bool(false) bool(false) string(261) "http://kDTvHt1PPDgX5EiP2MwiXjcoWNOhhTuOVAUWJ3TmpBYCC9QoJV114LMYrV3Zl58.kDTvHt1PPDgX5EiP2MwiXjcoWNOhhTuOVAUWJ3TmpBYCC9QoJV114LMYrV3Zl58.kDTvHt1PPDgX5EiP2MwiXjcoWNOhhTuOVAUWJ3TmpBYCC9QoJV114LMYrV3Zl58.CQ1oT5Uq3jJt6Uhy3VH9u3Gi5YhfZCvZVKgLlaXNFhVKB1zJxvunR7SJa.com." +string(48) "http://[2001:0db8:0000:85a3:0000:0000:ac1f:8001]" +string(50) "http://[2001:db8:0:85a3:0:0:ac1f:8001]:123/me.html" +string(36) "http://[2001:db8:0:85a3::ac1f:8001]/" +string(12) "http://[::1]" string(31) "http://cont-ains.h-yph-en-s.com" bool(false) bool(false)