applied a set of patches from Lorenzo Viali correcting URI parsing errors.

* uri.c: applied a set of patches from Lorenzo Viali correcting
  URI parsing errors.
Daniel
diff --git a/uri.c b/uri.c
index 70aee47..ab03767 100644
--- a/uri.c
+++ b/uri.c
@@ -272,10 +272,7 @@
 		    return(NULL);
 		}
 	    }
-	    if ((IS_UNRESERVED(*(p))) ||
-	        ((*(p) == ';')) || ((*(p) == '?')) || ((*(p) == ':')) ||
-	        ((*(p) == '@')) || ((*(p) == '&')) || ((*(p) == '=')) ||
-	        ((*(p) == '+')) || ((*(p) == '$')) || ((*(p) == ',')))
+	    if (IS_RESERVED(*(p)) || IS_UNRESERVED(*(p)))
 		ret[len++] = *p++;
 	    else {
 		int val = *(unsigned char *)p++;
@@ -769,7 +766,7 @@
      */
     if (path[0] == '/') {
       cur = path;
-      while ((cur[1] == '.') && (cur[2] == '.')
+      while ((cur[0] == '/') && (cur[1] == '.') && (cur[2] == '.')
              && ((cur[3] == '/') || (cur[3] == '\0')))
 	cur += 3;
 
@@ -1094,7 +1091,7 @@
     if (str == NULL)
         return (-1);
 
-    while (IS_URIC(cur) || ((uri->cleanup) && (IS_UNWISE(cur))))
+    while (IS_URIC(cur) || ((uri != NULL) && (uri->cleanup) && (IS_UNWISE(cur))))
         NEXT(cur);
     if (uri != NULL) {
         if (uri->query != NULL)
@@ -1157,11 +1154,11 @@
         return (-1);
 
     cur = *str;
-    if (!(IS_URIC_NO_SLASH(cur) || ((uri->cleanup) && (IS_UNWISE(cur))))) {
+    if (!(IS_URIC_NO_SLASH(cur) || ((uri != NULL) && (uri->cleanup) && (IS_UNWISE(cur))))) {
         return (3);
     }
     NEXT(cur);
-    while (IS_URIC(cur) || ((uri->cleanup) && (IS_UNWISE(cur))))
+    while (IS_URIC(cur) || ((uri != NULL) && (uri->cleanup) && (IS_UNWISE(cur))))
         NEXT(cur);
     if (uri != NULL) {
         if (uri->opaque != NULL)
@@ -1197,6 +1194,8 @@
 xmlParseURIServer(xmlURIPtr uri, const char **str) {
     const char *cur;
     const char *host, *tmp;
+    const int IPmax = 4;
+    int oct;
 
     if (str == NULL)
 	return(-1);
@@ -1239,63 +1238,53 @@
      * or an unresolved name. Check the IP first, it easier to detect
      * errors if wrong one
      */
-    if (IS_DIGIT(*cur)) {
+    for (oct = 0; oct < IPmax; ++oct) {
+        if (*cur == '.')
+            return(3); /* e.g. http://.xml/ or http://18.29..30/ */
         while(IS_DIGIT(*cur)) cur++;
-	if (*cur != '.')
-	    goto host_name;
-	cur++;
-	if (!IS_DIGIT(*cur))
-	    goto host_name;
-        while(IS_DIGIT(*cur)) cur++;
-	if (*cur != '.')
-	    goto host_name;
-	cur++;
-	if (!IS_DIGIT(*cur))
-	    goto host_name;
-        while(IS_DIGIT(*cur)) cur++;
-	if (*cur != '.')
-	    goto host_name;
-	cur++;
-	if (!IS_DIGIT(*cur))
-	    goto host_name;
-        while(IS_DIGIT(*cur)) cur++;
-	if (uri != NULL) {
-	    if (uri->authority != NULL) xmlFree(uri->authority);
-	    uri->authority = NULL;
-	    if (uri->server != NULL) xmlFree(uri->server);
-	    uri->server = xmlURIUnescapeString(host, cur - host, NULL);
-	}
-	goto host_done;
+        if (oct == (IPmax-1))
+            continue;
+        if (*cur != '.')
+	    break;
+        cur++;
     }
-host_name:
-    /*
-     * the hostname production as-is is a parser nightmare.
-     * simplify it to 
-     * hostname = *( domainlabel "." ) domainlabel [ "." ]
-     * and just make sure the last label starts with a non numeric char.
-     */
-    if (!IS_ALPHANUM(*cur))
-        return(6);
-    while (IS_ALPHANUM(*cur)) {
-        while ((IS_ALPHANUM(*cur)) || (*cur == '-')) cur++;
-	if (*cur == '.')
-	    cur++;
+    if (oct < IPmax || (*cur == '.' && cur++) || IS_ALPHA(*cur)) {
+        /* maybe host_name */
+        if (!IS_ALPHANUM(*cur))
+            return(4); /* e.g. http://xml.$oft */
+        do {
+            do ++cur; while (IS_ALPHANUM(*cur));
+            if (*cur == '-') {
+	        --cur;
+                if (*cur == '.')
+                    return(5); /* e.g. http://xml.-soft */
+	        ++cur;
+		continue;
+            }
+    	    if (*cur == '.') {
+	        --cur;
+                if (*cur == '-')
+                    return(6); /* e.g. http://xml-.soft */
+                if (*cur == '.')
+                    return(7); /* e.g. http://xml..soft */
+	        ++cur;
+		continue;
+            }
+	    break;
+        } while (1);
+        tmp = cur;
+        if (tmp[-1] == '.')
+            --tmp; /* e.g. http://xml.$Oft/ */
+        do --tmp; while (tmp >= host && IS_ALPHANUM(*tmp));
+        if ((++tmp == host || tmp[-1] == '.') && !IS_ALPHA(*tmp))
+            return(8); /* e.g. http://xmlsOft.0rg/ */
     }
-    tmp = cur;
-    tmp--;
-    while (IS_ALPHANUM(*tmp) && (*tmp != '.') && (tmp >= host)) tmp--;
-    tmp++;
-    if (!IS_ALPHA(*tmp))
-        return(7);
     if (uri != NULL) {
 	if (uri->authority != NULL) xmlFree(uri->authority);
 	uri->authority = NULL;
 	if (uri->server != NULL) xmlFree(uri->server);
 	uri->server = xmlURIUnescapeString(host, cur - host, NULL);
     }
-
-host_done:
-
     /*
      * finish by checking for a port presence.
      */
@@ -1336,11 +1325,11 @@
         return (-1);
 
     cur = *str;
-    if (!(IS_SEGMENT(cur) || ((uri->cleanup) && (IS_UNWISE(cur))))) {
+    if (!(IS_SEGMENT(cur) || ((uri != NULL) && (uri->cleanup) && (IS_UNWISE(cur))))) {
         return (3);
     }
     NEXT(cur);
-    while (IS_SEGMENT(cur) || ((uri->cleanup) && (IS_UNWISE(cur))))
+    while (IS_SEGMENT(cur) || ((uri != NULL) && (uri->cleanup) && (IS_UNWISE(cur))))
         NEXT(cur);
     if (uri != NULL) {
         if (uri->path != NULL)
@@ -1376,11 +1365,11 @@
     cur = *str;
 
     do {
-        while (IS_PCHAR(cur) || ((uri->cleanup) && (IS_UNWISE(cur))))
+        while (IS_PCHAR(cur) || ((uri != NULL) && (uri->cleanup) && (IS_UNWISE(cur))))
             NEXT(cur);
         while (*cur == ';') {
             cur++;
-            while (IS_PCHAR(cur) || ((uri->cleanup) && (IS_UNWISE(cur))))
+            while (IS_PCHAR(cur) || ((uri != NULL) && (uri->cleanup) && (IS_UNWISE(cur))))
                 NEXT(cur);
         }
         if (*cur != '/')
@@ -1825,11 +1814,6 @@
 	    res->fragment = xmlMemStrdup(ref->fragment);
 	goto step_7;
     }
- 
-    if (ref->query != NULL)
-	res->query = xmlMemStrdup(ref->query);
-    if (ref->fragment != NULL)
-	res->fragment = xmlMemStrdup(ref->fragment);
 
     /*
      * 3) If the scheme component is defined, indicating that the reference
@@ -1843,6 +1827,11 @@
     }
     if (bas->scheme != NULL)
 	res->scheme = xmlMemStrdup(bas->scheme);
+ 
+    if (ref->query != NULL)
+	res->query = xmlMemStrdup(ref->query);
+    if (ref->fragment != NULL)
+	res->fragment = xmlMemStrdup(ref->fragment);
 
     /*
      * 4) If the authority component is defined, then the reference is a