return php_url_parse_ex(str, strlen(str));
}
+static const char *binary_strcspn(const char *s, const char *e, const char *chars) {
+ while (*chars) {
+ const char *p = memchr(s, *chars, e - s);
+ if (p) {
+ e = p;
+ }
+ chars++;
+ }
+ return e;
+}
+
+ static int is_userinfo_valid(const char *str, size_t len)
+ {
+ char *valid = "-._~!$&'()*+,;=:";
+ char *p = str;
+ while (p - str < len) {
+ if (isalpha(*p) || isdigit(*p) || strchr(valid, *p)) {
+ p++;
+ } else if (*p == '%' && p - str <= len - 3 && isdigit(*(p+1)) && isxdigit(*(p+2))) {
+ p += 3;
+ } else {
+ return 0;
+ }
+ }
+ return 1;
+ }
+
+ /* {{{ php_url_parse
+ */
PHPAPI php_url *php_url_parse_ex(char const *str, size_t length)
+{
+ zend_bool has_port;
+ return php_url_parse_ex2(str, length, &has_port);
+}
+
+/* {{{ php_url_parse_ex2
+ */
+PHPAPI php_url *php_url_parse_ex2(char const *str, size_t length, zend_bool *has_port)
{
char port_buf[6];
php_url *ret = ecalloc(1, sizeof(php_url));
/* check for login and password */
if ((p = zend_memrchr(s, '@', (e-s)))) {
if ((pp = memchr(s, ':', (p-s)))) {
- ret->user = estrndup(s, (pp-s));
- php_replace_controlchars_ex(ret->user, (pp - s));
+ ret->user = zend_string_init(s, (pp-s), 0);
+ php_replace_controlchars_ex(ZSTR_VAL(ret->user), ZSTR_LEN(ret->user));
pp++;
- ret->pass = estrndup(pp, (p-pp));
- php_replace_controlchars_ex(ret->pass, (p-pp));
+ ret->pass = zend_string_init(pp, (p-pp), 0);
+ php_replace_controlchars_ex(ZSTR_VAL(ret->pass), ZSTR_LEN(ret->pass));
} else {
- ret->user = zend_string_init(s, (p-s), 0);
- if (!is_userinfo_valid(s, p-s)) {
- goto check_port;
- }
- ret->user = estrndup(s, (p-s));
- php_replace_controlchars_ex(ret->user, (p-s));
-
++ if (!is_userinfo_valid(s, p-s)) {
++ goto check_port;
++ }
++ ret->user = zend_string_init(s, (p-s), 0);
+ php_replace_controlchars_ex(ZSTR_VAL(ret->user), ZSTR_LEN(ret->user));
}
s = p + 1;