summaryrefslogtreecommitdiff
path: root/uri.c
diff options
context:
space:
mode:
authorAron Xu <aron@debian.org>2014-10-26 07:02:25 +0800
committerAron Xu <aron@debian.org>2014-10-26 07:02:25 +0800
commit3871a83a5f0aebd8c00879eab14fe901c93dbfcf (patch)
treeb022967f880b7fb1e56c8cc4c3f200d6ffbc9efd /uri.c
parent7042e17490515a990a45aa7237d11bc49ab0eaf0 (diff)
downloadlibxml2-3871a83a5f0aebd8c00879eab14fe901c93dbfcf.tar.gz
Imported Upstream version 2.9.2+dfsg1
Diffstat (limited to 'uri.c')
-rw-r--r--uri.c424
1 files changed, 177 insertions, 247 deletions
diff --git a/uri.c b/uri.c
index 7e2f525..ff47abb 100644
--- a/uri.c
+++ b/uri.c
@@ -1,12 +1,10 @@
/**
- * uri.c: set of generic URI related routines
+ * uri.c: set of generic URI related routines
*
* Reference: RFCs 3986, 2732 and 2373
*
* See Copyright for the status of this software.
*
- * TODO: that module behaves really badly on OOM situation
- *
* daniel@veillard.com
*/
@@ -20,6 +18,37 @@
#include <libxml/globals.h>
#include <libxml/xmlerror.h>
+/**
+ * MAX_URI_LENGTH:
+ *
+ * The definition of the URI regexp in the above RFC has no size limit
+ * In practice they are usually relativey short except for the
+ * data URI scheme as defined in RFC 2397. Even for data URI the usual
+ * maximum size before hitting random practical limits is around 64 KB
+ * and 4KB is usually a maximum admitted limit for proper operations.
+ * The value below is more a security limit than anything else and
+ * really should never be hit by 'normal' operations
+ * Set to 1 MByte in 2012, this is only enforced on output
+ */
+#define MAX_URI_LENGTH 1024 * 1024
+
+static void
+xmlURIErrMemory(const char *extra)
+{
+ if (extra)
+ __xmlRaiseError(NULL, NULL, NULL,
+ NULL, NULL, XML_FROM_URI,
+ XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0,
+ extra, NULL, NULL, 0, 0,
+ "Memory allocation failed : %s\n", extra);
+ else
+ __xmlRaiseError(NULL, NULL, NULL,
+ NULL, NULL, XML_FROM_URI,
+ XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0,
+ NULL, NULL, NULL, 0, 0,
+ "Memory allocation failed\n");
+}
+
static void xmlCleanURI(xmlURIPtr uri);
/*
@@ -730,6 +759,8 @@ xmlParse3986HierPart(xmlURIPtr uri, const char **str)
cur += 2;
ret = xmlParse3986Authority(uri, &cur);
if (ret != 0) return(ret);
+ if (uri->server == NULL)
+ uri->port = -1;
ret = xmlParse3986PathAbEmpty(uri, &cur);
if (ret != 0) return(ret);
*str = cur;
@@ -982,8 +1013,7 @@ xmlCreateURI(void) {
ret = (xmlURIPtr) xmlMalloc(sizeof(xmlURI));
if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlCreateURI: out of memory\n");
+ xmlURIErrMemory("creating URI structure\n");
return(NULL);
}
memset(ret, 0, sizeof(xmlURI));
@@ -991,6 +1021,31 @@ xmlCreateURI(void) {
}
/**
+ * xmlSaveUriRealloc:
+ *
+ * Function to handle properly a reallocation when saving an URI
+ * Also imposes some limit on the length of an URI string output
+ */
+static xmlChar *
+xmlSaveUriRealloc(xmlChar *ret, int *max) {
+ xmlChar *temp;
+ int tmp;
+
+ if (*max > MAX_URI_LENGTH) {
+ xmlURIErrMemory("reaching arbitrary MAX_URI_LENGTH limit\n");
+ return(NULL);
+ }
+ tmp = *max * 2;
+ temp = (xmlChar *) xmlRealloc(ret, (tmp + 1));
+ if (temp == NULL) {
+ xmlURIErrMemory("saving URI\n");
+ return(NULL);
+ }
+ *max = tmp;
+ return(temp);
+}
+
+/**
* xmlSaveUri:
* @uri: pointer to an xmlURI
*
@@ -1012,8 +1067,7 @@ xmlSaveUri(xmlURIPtr uri) {
max = 80;
ret = (xmlChar *) xmlMallocAtomic((max + 1) * sizeof(xmlChar));
if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
+ xmlURIErrMemory("saving URI\n");
return(NULL);
}
len = 0;
@@ -1022,28 +1076,16 @@ xmlSaveUri(xmlURIPtr uri) {
p = uri->scheme;
while (*p != 0) {
if (len >= max) {
- max *= 2;
- temp = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));
- if (temp == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- xmlFree(ret);
- return(NULL);
- }
+ temp = xmlSaveUriRealloc(ret, &max);
+ if (temp == NULL) goto mem_error;
ret = temp;
}
ret[len++] = *p++;
}
if (len >= max) {
- max *= 2;
- temp = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));
- if (temp == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- xmlFree(ret);
- return(NULL);
- }
- ret = temp;
+ temp = xmlSaveUriRealloc(ret, &max);
+ if (temp == NULL) goto mem_error;
+ ret = temp;
}
ret[len++] = ':';
}
@@ -1051,15 +1093,9 @@ xmlSaveUri(xmlURIPtr uri) {
p = uri->opaque;
while (*p != 0) {
if (len + 3 >= max) {
- max *= 2;
- temp = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));
- if (temp == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- xmlFree(ret);
- return(NULL);
- }
- ret = temp;
+ temp = xmlSaveUriRealloc(ret, &max);
+ if (temp == NULL) goto mem_error;
+ ret = temp;
}
if (IS_RESERVED(*(p)) || IS_UNRESERVED(*(p)))
ret[len++] = *p++;
@@ -1072,17 +1108,11 @@ xmlSaveUri(xmlURIPtr uri) {
}
}
} else {
- if (uri->server != NULL) {
+ if ((uri->server != NULL) || (uri->port == -1)) {
if (len + 3 >= max) {
- max *= 2;
- temp = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));
- if (temp == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- xmlFree(ret);
- return(NULL);
- }
- ret = temp;
+ temp = xmlSaveUriRealloc(ret, &max);
+ if (temp == NULL) goto mem_error;
+ ret = temp;
}
ret[len++] = '/';
ret[len++] = '/';
@@ -1090,16 +1120,9 @@ xmlSaveUri(xmlURIPtr uri) {
p = uri->user;
while (*p != 0) {
if (len + 3 >= max) {
- max *= 2;
- temp = (xmlChar *) xmlRealloc(ret,
- (max + 1) * sizeof(xmlChar));
- if (temp == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- xmlFree(ret);
- return(NULL);
- }
- ret = temp;
+ temp = xmlSaveUriRealloc(ret, &max);
+ if (temp == NULL) goto mem_error;
+ ret = temp;
}
if ((IS_UNRESERVED(*(p))) ||
((*(p) == ';')) || ((*(p) == ':')) ||
@@ -1116,78 +1139,45 @@ xmlSaveUri(xmlURIPtr uri) {
}
}
if (len + 3 >= max) {
- max *= 2;
- temp = (xmlChar *) xmlRealloc(ret,
- (max + 1) * sizeof(xmlChar));
- if (temp == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- xmlFree(ret);
- return(NULL);
- }
- ret = temp;
+ temp = xmlSaveUriRealloc(ret, &max);
+ if (temp == NULL) goto mem_error;
+ ret = temp;
}
ret[len++] = '@';
}
- p = uri->server;
- while (*p != 0) {
- if (len >= max) {
- max *= 2;
- temp = (xmlChar *) xmlRealloc(ret,
- (max + 1) * sizeof(xmlChar));
- if (temp == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- xmlFree(ret);
- return(NULL);
+ if (uri->server != NULL) {
+ p = uri->server;
+ while (*p != 0) {
+ if (len >= max) {
+ temp = xmlSaveUriRealloc(ret, &max);
+ if (temp == NULL) goto mem_error;
+ ret = temp;
}
- ret = temp;
+ ret[len++] = *p++;
}
- ret[len++] = *p++;
- }
- if (uri->port > 0) {
- if (len + 10 >= max) {
- max *= 2;
- temp = (xmlChar *) xmlRealloc(ret,
- (max + 1) * sizeof(xmlChar));
- if (temp == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- xmlFree(ret);
- return(NULL);
+ if (uri->port > 0) {
+ if (len + 10 >= max) {
+ temp = xmlSaveUriRealloc(ret, &max);
+ if (temp == NULL) goto mem_error;
+ ret = temp;
}
- ret = temp;
+ len += snprintf((char *) &ret[len], max - len, ":%d", uri->port);
}
- len += snprintf((char *) &ret[len], max - len, ":%d", uri->port);
}
} else if (uri->authority != NULL) {
if (len + 3 >= max) {
- max *= 2;
- temp = (xmlChar *) xmlRealloc(ret,
- (max + 1) * sizeof(xmlChar));
- if (temp == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- xmlFree(ret);
- return(NULL);
- }
- ret = temp;
+ temp = xmlSaveUriRealloc(ret, &max);
+ if (temp == NULL) goto mem_error;
+ ret = temp;
}
ret[len++] = '/';
ret[len++] = '/';
p = uri->authority;
while (*p != 0) {
if (len + 3 >= max) {
- max *= 2;
- temp = (xmlChar *) xmlRealloc(ret,
- (max + 1) * sizeof(xmlChar));
- if (temp == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- xmlFree(ret);
- return(NULL);
- }
- ret = temp;
+ temp = xmlSaveUriRealloc(ret, &max);
+ if (temp == NULL) goto mem_error;
+ ret = temp;
}
if ((IS_UNRESERVED(*(p))) ||
((*(p) == '$')) || ((*(p) == ',')) || ((*(p) == ';')) ||
@@ -1204,19 +1194,10 @@ xmlSaveUri(xmlURIPtr uri) {
}
} else if (uri->scheme != NULL) {
if (len + 3 >= max) {
- max *= 2;
- temp = (xmlChar *) xmlRealloc(ret,
- (max + 1) * sizeof(xmlChar));
- if (temp == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- xmlFree(ret);
- return(NULL);
- }
- ret = temp;
+ temp = xmlSaveUriRealloc(ret, &max);
+ if (temp == NULL) goto mem_error;
+ ret = temp;
}
- ret[len++] = '/';
- ret[len++] = '/';
}
if (uri->path != NULL) {
p = uri->path;
@@ -1231,14 +1212,9 @@ xmlSaveUri(xmlURIPtr uri) {
(p[2] == ':') &&
(xmlStrEqual(BAD_CAST uri->scheme, BAD_CAST "file"))) {
if (len + 3 >= max) {
- max *= 2;
- ret = (xmlChar *) xmlRealloc(ret,
- (max + 1) * sizeof(xmlChar));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- return(NULL);
- }
+ temp = xmlSaveUriRealloc(ret, &max);
+ if (temp == NULL) goto mem_error;
+ ret = temp;
}
ret[len++] = *p++;
ret[len++] = *p++;
@@ -1246,16 +1222,9 @@ xmlSaveUri(xmlURIPtr uri) {
}
while (*p != 0) {
if (len + 3 >= max) {
- max *= 2;
- temp = (xmlChar *) xmlRealloc(ret,
- (max + 1) * sizeof(xmlChar));
- if (temp == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- xmlFree(ret);
- return(NULL);
- }
- ret = temp;
+ temp = xmlSaveUriRealloc(ret, &max);
+ if (temp == NULL) goto mem_error;
+ ret = temp;
}
if ((IS_UNRESERVED(*(p))) || ((*(p) == '/')) ||
((*(p) == ';')) || ((*(p) == '@')) || ((*(p) == '&')) ||
@@ -1273,63 +1242,35 @@ xmlSaveUri(xmlURIPtr uri) {
}
if (uri->query_raw != NULL) {
if (len + 1 >= max) {
- max *= 2;
- temp = (xmlChar *) xmlRealloc(ret,
- (max + 1) * sizeof(xmlChar));
- if (temp == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- xmlFree(ret);
- return(NULL);
- }
- ret = temp;
+ temp = xmlSaveUriRealloc(ret, &max);
+ if (temp == NULL) goto mem_error;
+ ret = temp;
}
ret[len++] = '?';
p = uri->query_raw;
while (*p != 0) {
if (len + 1 >= max) {
- max *= 2;
- temp = (xmlChar *) xmlRealloc(ret,
- (max + 1) * sizeof(xmlChar));
- if (temp == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- xmlFree(ret);
- return(NULL);
- }
- ret = temp;
+ temp = xmlSaveUriRealloc(ret, &max);
+ if (temp == NULL) goto mem_error;
+ ret = temp;
}
ret[len++] = *p++;
}
} else if (uri->query != NULL) {
if (len + 3 >= max) {
- max *= 2;
- temp = (xmlChar *) xmlRealloc(ret,
- (max + 1) * sizeof(xmlChar));
- if (temp == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- xmlFree(ret);
- return(NULL);
- }
- ret = temp;
+ temp = xmlSaveUriRealloc(ret, &max);
+ if (temp == NULL) goto mem_error;
+ ret = temp;
}
ret[len++] = '?';
p = uri->query;
while (*p != 0) {
if (len + 3 >= max) {
- max *= 2;
- temp = (xmlChar *) xmlRealloc(ret,
- (max + 1) * sizeof(xmlChar));
- if (temp == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- xmlFree(ret);
- return(NULL);
- }
- ret = temp;
+ temp = xmlSaveUriRealloc(ret, &max);
+ if (temp == NULL) goto mem_error;
+ ret = temp;
}
- if ((IS_UNRESERVED(*(p))) || (IS_RESERVED(*(p))))
+ if ((IS_UNRESERVED(*(p))) || (IS_RESERVED(*(p))))
ret[len++] = *p++;
else {
int val = *(unsigned char *)p++;
@@ -1343,33 +1284,19 @@ xmlSaveUri(xmlURIPtr uri) {
}
if (uri->fragment != NULL) {
if (len + 3 >= max) {
- max *= 2;
- temp = (xmlChar *) xmlRealloc(ret,
- (max + 1) * sizeof(xmlChar));
- if (temp == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- xmlFree(ret);
- return(NULL);
- }
- ret = temp;
+ temp = xmlSaveUriRealloc(ret, &max);
+ if (temp == NULL) goto mem_error;
+ ret = temp;
}
ret[len++] = '#';
p = uri->fragment;
while (*p != 0) {
if (len + 3 >= max) {
- max *= 2;
- temp = (xmlChar *) xmlRealloc(ret,
- (max + 1) * sizeof(xmlChar));
- if (temp == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- xmlFree(ret);
- return(NULL);
- }
- ret = temp;
+ temp = xmlSaveUriRealloc(ret, &max);
+ if (temp == NULL) goto mem_error;
+ ret = temp;
}
- if ((IS_UNRESERVED(*(p))) || (IS_RESERVED(*(p))))
+ if ((IS_UNRESERVED(*(p))) || (IS_RESERVED(*(p))))
ret[len++] = *p++;
else {
int val = *(unsigned char *)p++;
@@ -1381,18 +1308,16 @@ xmlSaveUri(xmlURIPtr uri) {
}
}
if (len >= max) {
- max *= 2;
- temp = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));
- if (temp == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- xmlFree(ret);
- return(NULL);
- }
- ret = temp;
+ temp = xmlSaveUriRealloc(ret, &max);
+ if (temp == NULL) goto mem_error;
+ ret = temp;
}
ret[len] = 0;
return(ret);
+
+mem_error:
+ xmlFree(ret);
+ return(NULL);
}
/**
@@ -1695,8 +1620,7 @@ xmlURIUnescapeString(const char *str, int len, char *target) {
if (target == NULL) {
ret = (char *) xmlMallocAtomic(len + 1);
if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlURIUnescapeString: out of memory\n");
+ xmlURIErrMemory("unescaping URI value\n");
return(NULL);
}
} else
@@ -1706,14 +1630,14 @@ xmlURIUnescapeString(const char *str, int len, char *target) {
while(len > 0) {
if ((len > 2) && (*in == '%') && (is_hex(in[1])) && (is_hex(in[2]))) {
in++;
- if ((*in >= '0') && (*in <= '9'))
+ if ((*in >= '0') && (*in <= '9'))
*out = (*in - '0');
else if ((*in >= 'a') && (*in <= 'f'))
*out = (*in - 'a') + 10;
else if ((*in >= 'A') && (*in <= 'F'))
*out = (*in - 'A') + 10;
in++;
- if ((*in >= '0') && (*in <= '9'))
+ if ((*in >= '0') && (*in <= '9'))
*out = *out * 16 + (*in - '0');
else if ((*in >= 'a') && (*in <= 'f'))
*out = *out * 16 + (*in - 'a') + 10;
@@ -1746,8 +1670,7 @@ xmlURIEscapeStr(const xmlChar *str, const xmlChar *list) {
xmlChar *ret, ch;
xmlChar *temp;
const xmlChar *in;
-
- unsigned int len, out;
+ int len, out;
if (str == NULL)
return(NULL);
@@ -1759,19 +1682,16 @@ xmlURIEscapeStr(const xmlChar *str, const xmlChar *list) {
len += 20;
ret = (xmlChar *) xmlMallocAtomic(len);
if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlURIEscapeStr: out of memory\n");
+ xmlURIErrMemory("escaping URI value\n");
return(NULL);
}
in = (const xmlChar *) str;
out = 0;
while(*in != 0) {
if (len - out <= 3) {
- len += 20;
- temp = (xmlChar *) xmlRealloc(ret, len);
+ temp = xmlSaveUriRealloc(ret, &len);
if (temp == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlURIEscapeStr: out of memory\n");
+ xmlURIErrMemory("escaping URI value\n");
xmlFree(ret);
return(NULL);
}
@@ -1826,10 +1746,9 @@ xmlURIEscape(const xmlChar * str)
int ret2;
#define NULLCHK(p) if(!p) { \
- xmlGenericError(xmlGenericErrorContext, \
- "xmlURIEscape: out of memory\n"); \
- xmlFreeURI(uri); \
- return NULL; } \
+ xmlURIErrMemory("escaping URI value\n"); \
+ xmlFreeURI(uri); \
+ return NULL; } \
if (str == NULL)
return (NULL);
@@ -1872,7 +1791,7 @@ xmlURIEscape(const xmlChar * str)
if (uri->user) {
segment = xmlURIEscapeStr(BAD_CAST uri->user, BAD_CAST ";:&=+$,");
NULLCHK(segment)
- ret = xmlStrcat(ret,BAD_CAST "//");
+ ret = xmlStrcat(ret,BAD_CAST "//");
ret = xmlStrcat(ret, segment);
ret = xmlStrcat(ret, BAD_CAST "@");
xmlFree(segment);
@@ -1950,7 +1869,7 @@ xmlURIEscape(const xmlChar * str)
*
* Computes he final URI of the reference done by checking that
* the given URI is valid, and building the final URI using the
- * base URI. This is processed according to section 5.2 of the
+ * base URI. This is processed according to section 5.2 of the
* RFC 2396
*
* 5.2. Resolving Relative References to Absolute Form
@@ -1974,7 +1893,7 @@ xmlBuildURI(const xmlChar *URI, const xmlChar *base) {
* as a reference to "." rather than as a synonym for the current
* URI. Should we do that here?
*/
- if (URI == NULL)
+ if (URI == NULL)
ret = -1;
else {
if (*URI) {
@@ -2045,7 +1964,7 @@ xmlBuildURI(const xmlChar *URI, const xmlChar *base) {
res->server = xmlMemStrdup(bas->server);
if (bas->user != NULL)
res->user = xmlMemStrdup(bas->user);
- res->port = bas->port;
+ res->port = bas->port;
}
if (bas->path != NULL)
res->path = xmlMemStrdup(bas->path);
@@ -2074,7 +1993,7 @@ xmlBuildURI(const xmlChar *URI, const xmlChar *base) {
}
if (bas->scheme != NULL)
res->scheme = xmlMemStrdup(bas->scheme);
-
+
if (ref->query_raw != NULL)
res->query_raw = xmlMemStrdup(ref->query_raw);
else if (ref->query != NULL)
@@ -2096,7 +2015,7 @@ xmlBuildURI(const xmlChar *URI, const xmlChar *base) {
res->server = xmlMemStrdup(ref->server);
if (ref->user != NULL)
res->user = xmlMemStrdup(ref->user);
- res->port = ref->port;
+ res->port = ref->port;
}
if (ref->path != NULL)
res->path = xmlMemStrdup(ref->path);
@@ -2108,7 +2027,7 @@ xmlBuildURI(const xmlChar *URI, const xmlChar *base) {
res->server = xmlMemStrdup(bas->server);
if (bas->user != NULL)
res->user = xmlMemStrdup(bas->user);
- res->port = bas->port;
+ res->port = bas->port;
}
/*
@@ -2136,8 +2055,7 @@ xmlBuildURI(const xmlChar *URI, const xmlChar *base) {
len += strlen(bas->path);
res->path = (char *) xmlMallocAtomic(len);
if (res->path == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlBuildURI: out of memory\n");
+ xmlURIErrMemory("resolving URI against base\n");
goto done;
}
res->path[0] = 0;
@@ -2383,7 +2301,7 @@ xmlBuildRelativeURI (const xmlChar * URI, const xmlChar * base)
}
len = xmlStrlen (uptr) + 1;
}
-
+
if (nbslash == 0) {
if (uptr != NULL)
/* exception characters from xmlSaveUri */
@@ -2398,8 +2316,7 @@ xmlBuildRelativeURI (const xmlChar * URI, const xmlChar * base)
*/
val = (xmlChar *) xmlMalloc (len + 3 * nbslash);
if (val == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlBuildRelativeURI: out of memory\n");
+ xmlURIErrMemory("building relative URI\n");
goto done;
}
vptr = val;
@@ -2451,14 +2368,14 @@ done:
* xmlCanonicPath:
* @path: the resource locator in a filesystem notation
*
- * Constructs a canonic path from the specified path.
+ * Constructs a canonic path from the specified path.
*
- * Returns a new canonic path, or a duplicate of the path parameter if the
+ * Returns a new canonic path, or a duplicate of the path parameter if the
* construction fails. The caller is responsible for freeing the memory occupied
- * by the returned string. If there is insufficient memory available, or the
+ * by the returned string. If there is insufficient memory available, or the
* argument is NULL, the function returns NULL.
*/
-#define IS_WINDOWS_PATH(p) \
+#define IS_WINDOWS_PATH(p) \
((p != NULL) && \
(((p[0] >= 'a') && (p[0] <= 'z')) || \
((p[0] >= 'A') && (p[0] <= 'Z'))) && \
@@ -2470,7 +2387,7 @@ xmlCanonicPath(const xmlChar *path)
* For Windows implementations, additional work needs to be done to
* replace backslashes in pathnames with "forward slashes"
*/
-#if defined(_WIN32) && !defined(__CYGWIN__)
+#if defined(_WIN32) && !defined(__CYGWIN__)
int len = 0;
int i = 0;
xmlChar *p = NULL;
@@ -2482,7 +2399,20 @@ xmlCanonicPath(const xmlChar *path)
if (path == NULL)
return(NULL);
- /* sanitize filename starting with // so it can be used as URI */
+#if defined(_WIN32)
+ /*
+ * We must not change the backslashes to slashes if the the path
+ * starts with \\?\
+ * Those paths can be up to 32k characters long.
+ * Was added specifically for OpenOffice, those paths can't be converted
+ * to URIs anyway.
+ */
+ if ((path[0] == '\\') && (path[1] == '\\') && (path[2] == '?') &&
+ (path[3] == '\\') )
+ return xmlStrdup((const xmlChar *) path);
+#endif
+
+ /* sanitize filename starting with // so it can be used as URI */
if ((path[0] == '/') && (path[1] == '/') && (path[2] != '/'))
path++;
@@ -2529,7 +2459,7 @@ xmlCanonicPath(const xmlChar *path)
path_processing:
/* For Windows implementations, replace backslashes with 'forward slashes' */
-#if defined(_WIN32) && !defined(__CYGWIN__)
+#if defined(_WIN32) && !defined(__CYGWIN__)
/*
* Create a URI structure
*/
@@ -2586,7 +2516,7 @@ path_processing:
*
* Constructs an URI expressing the existing path
*
- * Returns a new URI, or a duplicate of the path parameter if the
+ * Returns a new URI, or a duplicate of the path parameter if the
* construction fails. The caller is responsible for freeing the memory
* occupied by the returned string. If there is insufficient memory available,
* or the argument is NULL, the function returns NULL.
@@ -2609,7 +2539,7 @@ xmlPathToURI(const xmlChar *path)
if (cal == NULL)
return(NULL);
#if defined(_WIN32) && !defined(__CYGWIN__)
- /* xmlCanonicPath can return an URI on Windows (is that the intended behaviour?)
+ /* xmlCanonicPath can return an URI on Windows (is that the intended behaviour?)
If 'cal' is a valid URI allready then we are done here, as continuing would make
it invalid. */
if ((uri = xmlParseURI((const char *) cal)) != NULL) {