summaryrefslogtreecommitdiff
path: root/uri.c
diff options
context:
space:
mode:
Diffstat (limited to 'uri.c')
-rw-r--r--uri.c175
1 files changed, 138 insertions, 37 deletions
diff --git a/uri.c b/uri.c
index d2fa521..a00415c 100644
--- a/uri.c
+++ b/uri.c
@@ -185,6 +185,8 @@
* path = [ abs_path | opaque_part ]
*/
+#define STRNDUP(s, n) (char *) xmlStrndup((const xmlChar *)(s), (n))
+
/************************************************************************
* *
* Generic URI structure functions *
@@ -1086,7 +1088,10 @@ xmlParseURIFragment(xmlURIPtr uri, const char **str)
if (uri != NULL) {
if (uri->fragment != NULL)
xmlFree(uri->fragment);
- uri->fragment = xmlURIUnescapeString(*str, cur - *str, NULL);
+ if (uri->cleanup & 2)
+ uri->fragment = STRNDUP(*str, cur - *str);
+ else
+ uri->fragment = xmlURIUnescapeString(*str, cur - *str, NULL);
}
*str = cur;
return (0);
@@ -1111,12 +1116,16 @@ xmlParseURIQuery(xmlURIPtr uri, const char **str)
if (str == NULL)
return (-1);
- while (IS_URIC(cur) || ((uri != NULL) && (uri->cleanup) && (IS_UNWISE(cur))))
+ while ((IS_URIC(cur)) ||
+ ((uri != NULL) && (uri->cleanup & 1) && (IS_UNWISE(cur))))
NEXT(cur);
if (uri != NULL) {
if (uri->query != NULL)
xmlFree(uri->query);
- uri->query = xmlURIUnescapeString(*str, cur - *str, NULL);
+ if (uri->cleanup & 2)
+ uri->query = STRNDUP(*str, cur - *str);
+ else
+ uri->query = xmlURIUnescapeString(*str, cur - *str, NULL);
}
*str = cur;
return (0);
@@ -1147,8 +1156,7 @@ xmlParseURIScheme(xmlURIPtr uri, const char **str) {
while (IS_SCHEME(*cur)) cur++;
if (uri != NULL) {
if (uri->scheme != NULL) xmlFree(uri->scheme);
- /* !!! strndup */
- uri->scheme = xmlURIUnescapeString(*str, cur - *str, NULL);
+ uri->scheme = STRNDUP(*str, cur - *str);
}
*str = cur;
return(0);
@@ -1174,16 +1182,21 @@ xmlParseURIOpaquePart(xmlURIPtr uri, const char **str)
return (-1);
cur = *str;
- if (!(IS_URIC_NO_SLASH(cur) || ((uri != NULL) && (uri->cleanup) && (IS_UNWISE(cur))))) {
+ if (!((IS_URIC_NO_SLASH(cur)) ||
+ ((uri != NULL) && (uri->cleanup & 1) && (IS_UNWISE(cur))))) {
return (3);
}
NEXT(cur);
- while (IS_URIC(cur) || ((uri != NULL) && (uri->cleanup) && (IS_UNWISE(cur))))
+ while ((IS_URIC(cur)) ||
+ ((uri != NULL) && (uri->cleanup & 1) && (IS_UNWISE(cur))))
NEXT(cur);
if (uri != NULL) {
if (uri->opaque != NULL)
xmlFree(uri->opaque);
- uri->opaque = xmlURIUnescapeString(*str, cur - *str, NULL);
+ if (uri->cleanup & 2)
+ uri->opaque = STRNDUP(*str, cur - *str);
+ else
+ uri->opaque = xmlURIUnescapeString(*str, cur - *str, NULL);
}
*str = cur;
return (0);
@@ -1235,7 +1248,10 @@ xmlParseURIServer(xmlURIPtr uri, const char **str) {
if (*cur == '@') {
if (uri != NULL) {
if (uri->user != NULL) xmlFree(uri->user);
- uri->user = xmlURIUnescapeString(*str, cur - *str, NULL);
+ if (uri->cleanup & 2)
+ uri->path = STRNDUP(*str, cur - *str);
+ else
+ uri->user = xmlURIUnescapeString(*str, cur - *str, NULL);
}
cur++;
} else {
@@ -1349,7 +1365,10 @@ xmlParseURIServer(xmlURIPtr uri, const char **str) {
uri->authority = NULL;
if (host[0] != '[') { /* it's not an IPV6 addr */
if (uri->server != NULL) xmlFree(uri->server);
- uri->server = xmlURIUnescapeString(host, cur - host, NULL);
+ if (uri->cleanup & 2)
+ uri->server = STRNDUP(host, cur - host);
+ else
+ uri->server = xmlURIUnescapeString(host, cur - host, NULL);
}
}
/*
@@ -1392,16 +1411,21 @@ xmlParseURIRelSegment(xmlURIPtr uri, const char **str)
return (-1);
cur = *str;
- if (!(IS_SEGMENT(cur) || ((uri != NULL) && (uri->cleanup) && (IS_UNWISE(cur))))) {
+ if (!((IS_SEGMENT(cur)) ||
+ ((uri != NULL) && (uri->cleanup & 1) && (IS_UNWISE(cur))))) {
return (3);
}
NEXT(cur);
- while (IS_SEGMENT(cur) || ((uri != NULL) && (uri->cleanup) && (IS_UNWISE(cur))))
+ while ((IS_SEGMENT(cur)) ||
+ ((uri != NULL) && (uri->cleanup & 1) && (IS_UNWISE(cur))))
NEXT(cur);
if (uri != NULL) {
if (uri->path != NULL)
xmlFree(uri->path);
- uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
+ if (uri->cleanup & 2)
+ uri->path = STRNDUP(*str, cur - *str);
+ else
+ uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
}
*str = cur;
return (0);
@@ -1432,11 +1456,13 @@ xmlParseURIPathSegments(xmlURIPtr uri, const char **str, int slash)
cur = *str;
do {
- while (IS_PCHAR(cur) || ((uri != NULL) && (uri->cleanup) && (IS_UNWISE(cur))))
+ while ((IS_PCHAR(cur)) ||
+ ((uri != NULL) && (uri->cleanup & 1) && (IS_UNWISE(cur))))
NEXT(cur);
while (*cur == ';') {
cur++;
- while (IS_PCHAR(cur) || ((uri != NULL) && (uri->cleanup) && (IS_UNWISE(cur))))
+ while ((IS_PCHAR(cur)) ||
+ ((uri != NULL) && (uri->cleanup & 1) && (IS_UNWISE(cur))))
NEXT(cur);
}
if (*cur != '/')
@@ -1472,8 +1498,13 @@ xmlParseURIPathSegments(xmlURIPtr uri, const char **str, int slash)
len2++;
}
path[len2] = 0;
- if (cur - *str > 0)
- xmlURIUnescapeString(*str, cur - *str, &path[len2]);
+ if (cur - *str > 0) {
+ if (uri->cleanup & 2) {
+ memcpy(&path[len2], *str, cur - *str);
+ path[len2 + (cur - *str)] = 0;
+ } else
+ xmlURIUnescapeString(*str, cur - *str, &path[len2]);
+ }
if (uri->path != NULL)
xmlFree(uri->path);
uri->path = path;
@@ -1538,7 +1569,10 @@ xmlParseURIAuthority(xmlURIPtr uri, const char **str) {
if (uri->user != NULL) xmlFree(uri->user);
uri->user = NULL;
if (uri->authority != NULL) xmlFree(uri->authority);
- uri->authority = xmlURIUnescapeString(*str, cur - *str, NULL);
+ if (uri->cleanup & 2)
+ uri->authority = STRNDUP(*str, cur - *str);
+ else
+ uri->authority = xmlURIUnescapeString(*str, cur - *str, NULL);
}
*str = cur;
return(0);
@@ -1761,6 +1795,38 @@ xmlParseURI(const char *str) {
return(uri);
}
+/**
+ * xmlParseURIRaw:
+ * @str: the URI string to analyze
+ * @raw: if 1 unescaping of URI pieces are disabled
+ *
+ * Parse an URI but allows to keep intact the original fragments.
+ *
+ * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
+ *
+ * Returns a newly built xmlURIPtr or NULL in case of error
+ */
+xmlURIPtr
+xmlParseURIRaw(const char *str, int raw) {
+ xmlURIPtr uri;
+ int ret;
+
+ if (str == NULL)
+ return(NULL);
+ uri = xmlCreateURI();
+ if (uri != NULL) {
+ if (raw) {
+ uri->cleanup |= 2;
+ }
+ ret = xmlParseURIReference(uri, str);
+ if (ret) {
+ xmlFreeURI(uri);
+ return(NULL);
+ }
+ }
+ return(uri);
+}
+
/************************************************************************
* *
* Public functions *
@@ -2070,14 +2136,6 @@ xmlBuildRelativeURI (const xmlChar * URI, const xmlChar * base)
if ((URI == NULL) || (*URI == 0))
return NULL;
- /*
- * Special case - if URI starts with '.', we assume it's already
- * in relative form, so nothing to do.
- */
- if (*URI == '.') {
- val = xmlStrdup (URI);
- goto done;
- }
/*
* First parse URI into a standard form
@@ -2085,9 +2143,13 @@ xmlBuildRelativeURI (const xmlChar * URI, const xmlChar * base)
ref = xmlCreateURI ();
if (ref == NULL)
return NULL;
- ret = xmlParseURIReference (ref, (const char *) URI);
- if (ret != 0)
- goto done; /* Error in URI, return NULL */
+ /* If URI not already in "relative" form */
+ if (URI[0] != '.') {
+ ret = xmlParseURIReference (ref, (const char *) URI);
+ if (ret != 0)
+ goto done; /* Error in URI, return NULL */
+ } else
+ ref->path = (char *)xmlStrdup(URI);
/*
* Next parse base into the same standard form
@@ -2099,9 +2161,12 @@ xmlBuildRelativeURI (const xmlChar * URI, const xmlChar * base)
bas = xmlCreateURI ();
if (bas == NULL)
goto done;
- ret = xmlParseURIReference (bas, (const char *) base);
- if (ret != 0)
- goto done; /* Error in base, return NULL */
+ if (base[0] != '.') {
+ ret = xmlParseURIReference (bas, (const char *) base);
+ if (ret != 0)
+ goto done; /* Error in base, return NULL */
+ } else
+ bas->path = (char *)xmlStrdup(base);
/*
* If the scheme / server on the URI differs from the base,
@@ -2230,8 +2295,9 @@ xmlCanonicPath(const xmlChar *path)
int i = 0;
xmlChar *p = NULL;
#endif
- xmlChar *ret;
xmlURIPtr uri;
+ xmlChar *ret;
+ const xmlChar *absuri;
if (path == NULL)
return(NULL);
@@ -2240,12 +2306,47 @@ xmlCanonicPath(const xmlChar *path)
return xmlStrdup(path);
}
+ absuri = xmlStrstr(path, BAD_CAST "://");
+ if (absuri != NULL) {
+ int l, j;
+ unsigned char c;
+ xmlChar *escURI;
+
+ /*
+ * this looks like an URI where some parts have not been
+ * escaped leading to a parsing problem check that the first
+ * part matches a protocol.
+ */
+ l = absuri - path;
+ if ((l <= 0) || (l > 20))
+ goto path_processing;
+ for (j = 0;j < l;j++) {
+ c = path[j];
+ if (!(((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))))
+ goto path_processing;
+ }
+
+ escURI = xmlURIEscapeStr(path, BAD_CAST ":/?_.#&;=");
+ if (escURI != NULL) {
+ uri = xmlParseURI((const char *) escURI);
+ if (uri != NULL) {
+ xmlFreeURI(uri);
+ return escURI;
+ }
+ xmlFreeURI(uri);
+ }
+ }
+
+path_processing:
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /*
+ * This really need to be cleaned up by someone with a Windows box
+ */
uri = xmlCreateURI();
if (uri == NULL) {
return(NULL);
}
-#if defined(_WIN32) && !defined(__CYGWIN__)
len = xmlStrlen(path);
if ((len > 2) && IS_WINDOWS_PATH(path)) {
uri->scheme = xmlStrdup(BAD_CAST "file");
@@ -2262,15 +2363,15 @@ xmlCanonicPath(const xmlChar *path)
*p = '/';
p++;
}
-#else
- uri->path = (char *) xmlStrdup((const xmlChar *) path);
-#endif
if (uri->path == NULL) {
xmlFreeURI(uri);
return(NULL);
}
ret = xmlSaveUri(uri);
xmlFreeURI(uri);
+#else
+ ret = xmlStrdup((const xmlChar *) path);
+#endif
return(ret);
}