Allow IDNA/punycode hosts
[m6w6/ext-http] / src / php_http_url.c
index 07121df42c0d9c7992e72c92a70639ec0520e7fc..9140c6824e32ad2a7819b20982fd322d4e111187 100644 (file)
@@ -1095,9 +1095,7 @@ static ZEND_RESULT_CODE parse_hostinfo(struct parse_state *state, const char *pt
                        state->buffer[state->offset++] = *ptr;
                        break;
 
-               case '!': case '$': case '&': case '\'': case '(': case ')': case '*':
-               case '+': case ',': case ';': case '=': /* sub-delims */
-               case '-': case '.': case '_': case '~': /* unreserved */
+               case '.':
                        if (port || !label) {
                                /* sort of a compromise, just ensure we don't end up
                                 * with a dot at the beginning or two consecutive dots
@@ -1112,6 +1110,21 @@ static ZEND_RESULT_CODE parse_hostinfo(struct parse_state *state, const char *pt
                        label = NULL;
                        break;
 
+               case '-':
+                       if (!label) {
+                               /* sort of a compromise, just ensure we don't end up
+                                * with a hyphen at the beginning
+                                */
+                               php_error_docref(NULL TSRMLS_CC, E_WARNING,
+                                               "Failed to parse %s; unexpected '%c' at pos %u in '%s'",
+                                               port ? "port" : "host",
+                                               (unsigned char) *ptr, (unsigned) (ptr - tmp), tmp);
+                               return FAILURE;
+                       }
+                       /* no break */
+               case '_': case '~': /* unreserved */
+               case '!': case '$': case '&': case '\'': case '(': case ')': case '*':
+               case '+': case ',': case ';': case '=': /* sub-delims */
                case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
                case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
                case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U':