ReactOS 0.4.16-dev-2208-g6350669
uri.h File Reference
#include <stdio.h>
#include <libxml/xmlversion.h>
#include <libxml/xmlstring.h>
Include dependency graph for uri.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _xmlURI
 

Typedefs

typedef struct _xmlURI xmlURI
 
typedef xmlURIxmlURIPtr
 

Functions

XMLPUBFUN xmlURIPtr xmlCreateURI (void)
 
XMLPUBFUN xmlCharxmlBuildURI (const xmlChar *URI, const xmlChar *base)
 
XMLPUBFUN xmlCharxmlBuildRelativeURI (const xmlChar *URI, const xmlChar *base)
 
XMLPUBFUN xmlURIPtr xmlParseURI (const char *str)
 
XMLPUBFUN xmlURIPtr xmlParseURIRaw (const char *str, int raw)
 
XMLPUBFUN int xmlParseURIReference (xmlURIPtr uri, const char *str)
 
XMLPUBFUN xmlCharxmlSaveUri (xmlURIPtr uri)
 
XMLPUBFUN void xmlPrintURI (FILE *stream, xmlURIPtr uri)
 
XMLPUBFUN xmlCharxmlURIEscapeStr (const xmlChar *str, const xmlChar *list)
 
XMLPUBFUN charxmlURIUnescapeString (const char *str, int len, char *target)
 
XMLPUBFUN int xmlNormalizeURIPath (char *path)
 
XMLPUBFUN xmlCharxmlURIEscape (const xmlChar *str)
 
XMLPUBFUN void xmlFreeURI (xmlURIPtr uri)
 
XMLPUBFUN xmlCharxmlCanonicPath (const xmlChar *path)
 
XMLPUBFUN xmlCharxmlPathToURI (const xmlChar *path)
 

Typedef Documentation

◆ xmlURI

Summary: library of generic URI related routines Description: library of generic URI related routines Implements RFC 2396

Copy: See Copyright for the status of this software.

Author: Daniel Veillard xmlURI:

A parsed URI reference. This is a struct containing the various fields as described in RFC 2396 but separated for further processing.

Note: query is a deprecated field which is incorrectly unescaped. query_raw takes precedence over query if the former is set. See: http://mail.gnome.org/archives/xml/2007-April/thread.html#00127

Definition at line 32 of file uri.h.

◆ xmlURIPtr

typedef xmlURI* xmlURIPtr

Definition at line 33 of file uri.h.

Function Documentation

◆ xmlBuildRelativeURI()

XMLPUBFUN xmlChar * xmlBuildRelativeURI ( const xmlChar URI,
const xmlChar base 
)

xmlBuildRelativeURI: @URI: the URI reference under consideration @base: the base value

Expresses the URI of the reference in terms relative to the base. Some examples of this operation include: base = "http://site1.com/docs/book1.html" URI input URI returned docs/pic1.gif pic1.gif docs/img/pic1.gif img/pic1.gif img/pic1.gif ../img/pic1.gif http://site1.com/docs/pic1.gif pic1.gif http://site2.com/docs/pic1.gif http://site2.com/docs/pic1.gif

base = "docs/book1.html" URI input URI returned docs/pic1.gif pic1.gif docs/img/pic1.gif img/pic1.gif img/pic1.gif ../img/pic1.gif http://site1.com/docs/pic1.gif http://site1.com/docs/pic1.gif

Note: if the URI reference is really weird or complicated, it may be worthwhile to first convert it into a "nice" one by calling xmlBuildURI (using 'base') before calling this routine, since this routine (for reasonable efficiency) assumes URI has already been through some validation.

Returns a new URI string (to be freed by the caller) or NULL in case error.

Definition at line 2186 of file uri.c.

2187{
2188 xmlChar *val = NULL;
2189 int ret;
2190 int ix;
2191 int nbslash = 0;
2192 int len;
2193 xmlURIPtr ref = NULL;
2194 xmlURIPtr bas = NULL;
2195 xmlChar *bptr, *uptr, *vptr;
2196 int remove_path = 0;
2197
2198 if ((URI == NULL) || (*URI == 0))
2199 return NULL;
2200
2201 /*
2202 * First parse URI into a standard form
2203 */
2204 ref = xmlCreateURI ();
2205 if (ref == NULL)
2206 return NULL;
2207 /* If URI not already in "relative" form */
2208 if (URI[0] != '.') {
2209 ret = xmlParseURIReference (ref, (const char *) URI);
2210 if (ret != 0)
2211 goto done; /* Error in URI, return NULL */
2212 } else
2213 ref->path = (char *)xmlStrdup(URI);
2214
2215 /*
2216 * Next parse base into the same standard form
2217 */
2218 if ((base == NULL) || (*base == 0)) {
2219 val = xmlStrdup (URI);
2220 goto done;
2221 }
2222 bas = xmlCreateURI ();
2223 if (bas == NULL)
2224 goto done;
2225 if (base[0] != '.') {
2226 ret = xmlParseURIReference (bas, (const char *) base);
2227 if (ret != 0)
2228 goto done; /* Error in base, return NULL */
2229 } else
2230 bas->path = (char *)xmlStrdup(base);
2231
2232 /*
2233 * If the scheme / server on the URI differs from the base,
2234 * just return the URI
2235 */
2236 if ((ref->scheme != NULL) &&
2237 ((bas->scheme == NULL) ||
2238 (xmlStrcmp ((xmlChar *)bas->scheme, (xmlChar *)ref->scheme)) ||
2239 (xmlStrcmp ((xmlChar *)bas->server, (xmlChar *)ref->server)) ||
2240 (bas->port != ref->port))) {
2241 val = xmlStrdup (URI);
2242 goto done;
2243 }
2244 if (xmlStrEqual((xmlChar *)bas->path, (xmlChar *)ref->path)) {
2245 val = xmlStrdup(BAD_CAST "");
2246 goto done;
2247 }
2248 if (bas->path == NULL) {
2249 val = xmlStrdup((xmlChar *)ref->path);
2250 goto done;
2251 }
2252 if (ref->path == NULL) {
2253 ref->path = (char *) "/";
2254 remove_path = 1;
2255 }
2256
2257 /*
2258 * At this point (at last!) we can compare the two paths
2259 *
2260 * First we take care of the special case where either of the
2261 * two path components may be missing (bug 316224)
2262 */
2263 bptr = (xmlChar *)bas->path;
2264 {
2265 xmlChar *rptr = (xmlChar *) ref->path;
2266 int pos = 0;
2267
2268 /*
2269 * Next we compare the two strings and find where they first differ
2270 */
2271 if ((*rptr == '.') && (rptr[1] == '/'))
2272 rptr += 2;
2273 if ((*bptr == '.') && (bptr[1] == '/'))
2274 bptr += 2;
2275 else if ((*bptr == '/') && (*rptr != '/'))
2276 bptr++;
2277 while ((bptr[pos] == rptr[pos]) && (bptr[pos] != 0))
2278 pos++;
2279
2280 if (bptr[pos] == rptr[pos]) {
2281 val = xmlStrdup(BAD_CAST "");
2282 goto done; /* (I can't imagine why anyone would do this) */
2283 }
2284
2285 /*
2286 * In URI, "back up" to the last '/' encountered. This will be the
2287 * beginning of the "unique" suffix of URI
2288 */
2289 ix = pos;
2290 for (; ix > 0; ix--) {
2291 if (rptr[ix - 1] == '/')
2292 break;
2293 }
2294 uptr = (xmlChar *)&rptr[ix];
2295
2296 /*
2297 * In base, count the number of '/' from the differing point
2298 */
2299 for (; bptr[ix] != 0; ix++) {
2300 if (bptr[ix] == '/')
2301 nbslash++;
2302 }
2303
2304 /*
2305 * e.g: URI="foo/" base="foo/bar" -> "./"
2306 */
2307 if (nbslash == 0 && !uptr[0]) {
2308 val = xmlStrdup(BAD_CAST "./");
2309 goto done;
2310 }
2311
2312 len = xmlStrlen (uptr) + 1;
2313 }
2314
2315 if (nbslash == 0) {
2316 if (uptr != NULL)
2317 /* exception characters from xmlSaveUri */
2318 val = xmlURIEscapeStr(uptr, BAD_CAST "/;&=+$,");
2319 goto done;
2320 }
2321
2322 /*
2323 * Allocate just enough space for the returned string -
2324 * length of the remainder of the URI, plus enough space
2325 * for the "../" groups, plus one for the terminator
2326 */
2327 val = (xmlChar *) xmlMalloc (len + 3 * nbslash);
2328 if (val == NULL) {
2329 xmlURIErrMemory("building relative URI\n");
2330 goto done;
2331 }
2332 vptr = val;
2333 /*
2334 * Put in as many "../" as needed
2335 */
2336 for (; nbslash>0; nbslash--) {
2337 *vptr++ = '.';
2338 *vptr++ = '.';
2339 *vptr++ = '/';
2340 }
2341 /*
2342 * Finish up with the end of the URI
2343 */
2344 if (uptr != NULL) {
2345 if ((vptr > val) && (len > 0) &&
2346 (uptr[0] == '/') && (vptr[-1] == '/')) {
2347 memcpy (vptr, uptr + 1, len - 1);
2348 vptr[len - 2] = 0;
2349 } else {
2350 memcpy (vptr, uptr, len);
2351 vptr[len - 1] = 0;
2352 }
2353 } else {
2354 vptr[len - 1] = 0;
2355 }
2356
2357 /* escape the freshly-built path */
2358 vptr = val;
2359 /* exception characters from xmlSaveUri */
2360 val = xmlURIEscapeStr(vptr, BAD_CAST "/;&=+$,");
2361 xmlFree(vptr);
2362
2363done:
2364 /*
2365 * Free the working variables
2366 */
2367 if (remove_path != 0)
2368 ref->path = NULL;
2369 if (ref != NULL)
2370 xmlFreeURI (ref);
2371 if (bas != NULL)
2372 xmlFreeURI (bas);
2373
2374 return val;
2375}
#define NULL
Definition: types.h:112
return ret
Definition: mutex.c:146
GLuint GLfloat * val
Definition: glext.h:7180
GLenum GLsizei len
Definition: glext.h:6722
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
xmlFreeFunc xmlFree
Definition: globals.c:184
xmlMallocFunc xmlMalloc
Definition: globals.c:193
xmlChar * xmlURIEscapeStr(const xmlChar *str, const xmlChar *list)
Definition: uri.c:1689
static void xmlURIErrMemory(const char *extra)
Definition: uri.c:41
void xmlFreeURI(xmlURIPtr uri)
Definition: uri.c:1396
int xmlParseURIReference(xmlURIPtr uri, const char *str)
Definition: uri.c:977
xmlURIPtr xmlCreateURI(void)
Definition: uri.c:1027
Definition: uri.h:34
char * server
Definition: uri.h:38
char * path
Definition: uri.h:41
int port
Definition: uri.h:40
char * scheme
Definition: uri.h:35
Definition: send.c:48
XMLPUBFUN int xmlStrlen(const xmlChar *str)
Definition: xmlstring.c:428
XMLPUBFUN int xmlStrcmp(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:135
#define BAD_CAST
Definition: xmlstring.h:35
XMLPUBFUN int xmlStrEqual(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:162
unsigned char xmlChar
Definition: xmlstring.h:28
XMLPUBFUN xmlChar * xmlStrdup(const xmlChar *cur)
Definition: xmlstring.c:69

◆ xmlBuildURI()

XMLPUBFUN xmlChar * xmlBuildURI ( const xmlChar URI,
const xmlChar base 
)

xmlBuildURI: @URI: the URI instance found in the document @base: the base value

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 RFC 2396

5.2. Resolving Relative References to Absolute Form

Returns a new URI string (to be freed by the caller) or NULL in case of error.

Definition at line 1902 of file uri.c.

1902 {
1903 xmlChar *val = NULL;
1904 int ret, len, indx, cur, out;
1905 xmlURIPtr ref = NULL;
1906 xmlURIPtr bas = NULL;
1907 xmlURIPtr res = NULL;
1908
1909 /*
1910 * 1) The URI reference is parsed into the potential four components and
1911 * fragment identifier, as described in Section 4.3.
1912 *
1913 * NOTE that a completely empty URI is treated by modern browsers
1914 * as a reference to "." rather than as a synonym for the current
1915 * URI. Should we do that here?
1916 */
1917 if (URI == NULL)
1918 ret = -1;
1919 else {
1920 if (*URI) {
1921 ref = xmlCreateURI();
1922 if (ref == NULL)
1923 goto done;
1924 ret = xmlParseURIReference(ref, (const char *) URI);
1925 }
1926 else
1927 ret = 0;
1928 }
1929 if (ret != 0)
1930 goto done;
1931 if ((ref != NULL) && (ref->scheme != NULL)) {
1932 /*
1933 * The URI is absolute don't modify.
1934 */
1935 val = xmlStrdup(URI);
1936 goto done;
1937 }
1938 if (base == NULL)
1939 ret = -1;
1940 else {
1941 bas = xmlCreateURI();
1942 if (bas == NULL)
1943 goto done;
1944 ret = xmlParseURIReference(bas, (const char *) base);
1945 }
1946 if (ret != 0) {
1947 if (ref)
1948 val = xmlSaveUri(ref);
1949 goto done;
1950 }
1951 if (ref == NULL) {
1952 /*
1953 * the base fragment must be ignored
1954 */
1955 if (bas->fragment != NULL) {
1956 xmlFree(bas->fragment);
1957 bas->fragment = NULL;
1958 }
1959 val = xmlSaveUri(bas);
1960 goto done;
1961 }
1962
1963 /*
1964 * 2) If the path component is empty and the scheme, authority, and
1965 * query components are undefined, then it is a reference to the
1966 * current document and we are done. Otherwise, the reference URI's
1967 * query and fragment components are defined as found (or not found)
1968 * within the URI reference and not inherited from the base URI.
1969 *
1970 * NOTE that in modern browsers, the parsing differs from the above
1971 * in the following aspect: the query component is allowed to be
1972 * defined while still treating this as a reference to the current
1973 * document.
1974 */
1975 res = xmlCreateURI();
1976 if (res == NULL)
1977 goto done;
1978 if ((ref->scheme == NULL) && (ref->path == NULL) &&
1979 ((ref->authority == NULL) && (ref->server == NULL) &&
1980 (ref->port == PORT_EMPTY))) {
1981 if (bas->scheme != NULL)
1982 res->scheme = xmlMemStrdup(bas->scheme);
1983 if (bas->authority != NULL)
1984 res->authority = xmlMemStrdup(bas->authority);
1985 else {
1986 if (bas->server != NULL)
1987 res->server = xmlMemStrdup(bas->server);
1988 if (bas->user != NULL)
1989 res->user = xmlMemStrdup(bas->user);
1990 res->port = bas->port;
1991 }
1992 if (bas->path != NULL)
1993 res->path = xmlMemStrdup(bas->path);
1994 if (ref->query_raw != NULL)
1995 res->query_raw = xmlMemStrdup (ref->query_raw);
1996 else if (ref->query != NULL)
1997 res->query = xmlMemStrdup(ref->query);
1998 else if (bas->query_raw != NULL)
1999 res->query_raw = xmlMemStrdup(bas->query_raw);
2000 else if (bas->query != NULL)
2001 res->query = xmlMemStrdup(bas->query);
2002 if (ref->fragment != NULL)
2003 res->fragment = xmlMemStrdup(ref->fragment);
2004 goto step_7;
2005 }
2006
2007 /*
2008 * 3) If the scheme component is defined, indicating that the reference
2009 * starts with a scheme name, then the reference is interpreted as an
2010 * absolute URI and we are done. Otherwise, the reference URI's
2011 * scheme is inherited from the base URI's scheme component.
2012 */
2013 if (ref->scheme != NULL) {
2014 val = xmlSaveUri(ref);
2015 goto done;
2016 }
2017 if (bas->scheme != NULL)
2018 res->scheme = xmlMemStrdup(bas->scheme);
2019
2020 if (ref->query_raw != NULL)
2021 res->query_raw = xmlMemStrdup(ref->query_raw);
2022 else if (ref->query != NULL)
2023 res->query = xmlMemStrdup(ref->query);
2024 if (ref->fragment != NULL)
2025 res->fragment = xmlMemStrdup(ref->fragment);
2026
2027 /*
2028 * 4) If the authority component is defined, then the reference is a
2029 * network-path and we skip to step 7. Otherwise, the reference
2030 * URI's authority is inherited from the base URI's authority
2031 * component, which will also be undefined if the URI scheme does not
2032 * use an authority component.
2033 */
2034 if ((ref->authority != NULL) || (ref->server != NULL) ||
2035 (ref->port != PORT_EMPTY)) {
2036 if (ref->authority != NULL)
2037 res->authority = xmlMemStrdup(ref->authority);
2038 else {
2039 if (ref->server != NULL)
2040 res->server = xmlMemStrdup(ref->server);
2041 if (ref->user != NULL)
2042 res->user = xmlMemStrdup(ref->user);
2043 res->port = ref->port;
2044 }
2045 if (ref->path != NULL)
2046 res->path = xmlMemStrdup(ref->path);
2047 goto step_7;
2048 }
2049 if (bas->authority != NULL)
2050 res->authority = xmlMemStrdup(bas->authority);
2051 else if ((bas->server != NULL) || (bas->port != PORT_EMPTY)) {
2052 if (bas->server != NULL)
2053 res->server = xmlMemStrdup(bas->server);
2054 if (bas->user != NULL)
2055 res->user = xmlMemStrdup(bas->user);
2056 res->port = bas->port;
2057 }
2058
2059 /*
2060 * 5) If the path component begins with a slash character ("/"), then
2061 * the reference is an absolute-path and we skip to step 7.
2062 */
2063 if ((ref->path != NULL) && (ref->path[0] == '/')) {
2064 res->path = xmlMemStrdup(ref->path);
2065 goto step_7;
2066 }
2067
2068
2069 /*
2070 * 6) If this step is reached, then we are resolving a relative-path
2071 * reference. The relative path needs to be merged with the base
2072 * URI's path. Although there are many ways to do this, we will
2073 * describe a simple method using a separate string buffer.
2074 *
2075 * Allocate a buffer large enough for the result string.
2076 */
2077 len = 2; /* extra / and 0 */
2078 if (ref->path != NULL)
2079 len += strlen(ref->path);
2080 if (bas->path != NULL)
2081 len += strlen(bas->path);
2082 res->path = (char *) xmlMallocAtomic(len);
2083 if (res->path == NULL) {
2084 xmlURIErrMemory("resolving URI against base\n");
2085 goto done;
2086 }
2087 res->path[0] = 0;
2088
2089 /*
2090 * a) All but the last segment of the base URI's path component is
2091 * copied to the buffer. In other words, any characters after the
2092 * last (right-most) slash character, if any, are excluded.
2093 */
2094 cur = 0;
2095 out = 0;
2096 if (bas->path != NULL) {
2097 while (bas->path[cur] != 0) {
2098 while ((bas->path[cur] != 0) && (bas->path[cur] != '/'))
2099 cur++;
2100 if (bas->path[cur] == 0)
2101 break;
2102
2103 cur++;
2104 while (out < cur) {
2105 res->path[out] = bas->path[out];
2106 out++;
2107 }
2108 }
2109 }
2110 res->path[out] = 0;
2111
2112 /*
2113 * b) The reference's path component is appended to the buffer
2114 * string.
2115 */
2116 if (ref->path != NULL && ref->path[0] != 0) {
2117 indx = 0;
2118 /*
2119 * Ensure the path includes a '/'
2120 */
2121 if ((out == 0) && ((bas->server != NULL) || bas->port != PORT_EMPTY))
2122 res->path[out++] = '/';
2123 while (ref->path[indx] != 0) {
2124 res->path[out++] = ref->path[indx++];
2125 }
2126 }
2127 res->path[out] = 0;
2128
2129 /*
2130 * Steps c) to h) are really path normalization steps
2131 */
2132 xmlNormalizeURIPath(res->path);
2133
2134step_7:
2135
2136 /*
2137 * 7) The resulting URI components, including any inherited from the
2138 * base URI, are recombined to give the absolute form of the URI
2139 * reference.
2140 */
2141 val = xmlSaveUri(res);
2142
2143done:
2144 if (ref != NULL)
2145 xmlFreeURI(ref);
2146 if (bas != NULL)
2147 xmlFreeURI(bas);
2148 if (res != NULL)
2149 xmlFreeURI(res);
2150 return(val);
2151}
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1592
FxCollectionEntry * cur
GLuint res
Definition: glext.h:9613
xmlMallocFunc xmlMallocAtomic
Definition: globals.c:204
xmlStrdupFunc xmlMemStrdup
Definition: globals.c:235
xmlChar * xmlSaveUri(xmlURIPtr uri)
Definition: uri.c:1074
int xmlNormalizeURIPath(char *path)
Definition: uri.c:1429
#define PORT_EMPTY
Definition: uri.c:37
char * authority
Definition: uri.h:37
char * query_raw
Definition: uri.h:45
char * user
Definition: uri.h:39
char * query
Definition: uri.h:42
char * fragment
Definition: uri.h:43
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383

Referenced by xmlCreateEntityParserCtxtInternal(), xmlSAX2EntityDecl(), xmlSAX2ResolveEntity(), xmlSAX2UnparsedEntityDecl(), xsltDocumentElem(), xsltDocumentFunction(), xsltLoadStylesheetPI(), xsltParseStylesheetImport(), and xsltParseStylesheetInclude().

◆ xmlCanonicPath()

XMLPUBFUN xmlChar * xmlCanonicPath ( const xmlChar path)

Definition at line 2394 of file uri.c.

2395{
2396/*
2397 * For Windows implementations, additional work needs to be done to
2398 * replace backslashes in pathnames with "forward slashes"
2399 */
2400#if defined(_WIN32)
2401 int len = 0;
2402 char *p = NULL;
2403#endif
2404 xmlURIPtr uri;
2405 xmlChar *ret;
2406 const xmlChar *absuri;
2407
2408 if (path == NULL)
2409 return(NULL);
2410
2411#if defined(_WIN32)
2412 /*
2413 * We must not change the backslashes to slashes if the the path
2414 * starts with \\?\
2415 * Those paths can be up to 32k characters long.
2416 * Was added specifically for OpenOffice, those paths can't be converted
2417 * to URIs anyway.
2418 */
2419 if ((path[0] == '\\') && (path[1] == '\\') && (path[2] == '?') &&
2420 (path[3] == '\\') )
2421 return xmlStrdup((const xmlChar *) path);
2422#endif
2423
2424 /* sanitize filename starting with // so it can be used as URI */
2425 if ((path[0] == '/') && (path[1] == '/') && (path[2] != '/'))
2426 path++;
2427
2428 if ((uri = xmlParseURI((const char *) path)) != NULL) {
2429 xmlFreeURI(uri);
2430 return xmlStrdup(path);
2431 }
2432
2433 /* Check if this is an "absolute uri" */
2434 absuri = xmlStrstr(path, BAD_CAST "://");
2435 if (absuri != NULL) {
2436 int l, j;
2437 unsigned char c;
2438 xmlChar *escURI;
2439
2440 /*
2441 * this looks like an URI where some parts have not been
2442 * escaped leading to a parsing problem. Check that the first
2443 * part matches a protocol.
2444 */
2445 l = absuri - path;
2446 /* Bypass if first part (part before the '://') is > 20 chars */
2447 if ((l <= 0) || (l > 20))
2448 goto path_processing;
2449 /* Bypass if any non-alpha characters are present in first part */
2450 for (j = 0;j < l;j++) {
2451 c = path[j];
2452 if (!(((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))))
2453 goto path_processing;
2454 }
2455
2456 /* Escape all except the characters specified in the supplied path */
2457 escURI = xmlURIEscapeStr(path, BAD_CAST ":/?_.#&;=");
2458 if (escURI != NULL) {
2459 /* Try parsing the escaped path */
2460 uri = xmlParseURI((const char *) escURI);
2461 /* If successful, return the escaped string */
2462 if (uri != NULL) {
2463 xmlFreeURI(uri);
2464 return escURI;
2465 }
2466 xmlFree(escURI);
2467 }
2468 }
2469
2470path_processing:
2471/* For Windows implementations, replace backslashes with 'forward slashes' */
2472#if defined(_WIN32)
2473 /*
2474 * Create a URI structure
2475 */
2476 uri = xmlCreateURI();
2477 if (uri == NULL) { /* Guard against 'out of memory' */
2478 return(NULL);
2479 }
2480
2481 len = xmlStrlen(path);
2482 if ((len > 2) && IS_WINDOWS_PATH(path)) {
2483 /* make the scheme 'file' */
2484 uri->scheme = (char *) xmlStrdup(BAD_CAST "file");
2485 /* allocate space for leading '/' + path + string terminator */
2486 uri->path = xmlMallocAtomic(len + 2);
2487 if (uri->path == NULL) {
2488 xmlFreeURI(uri); /* Guard against 'out of memory' */
2489 return(NULL);
2490 }
2491 /* Put in leading '/' plus path */
2492 uri->path[0] = '/';
2493 p = uri->path + 1;
2494 strncpy(p, (char *) path, len + 1);
2495 } else {
2496 uri->path = (char *) xmlStrdup(path);
2497 if (uri->path == NULL) {
2498 xmlFreeURI(uri);
2499 return(NULL);
2500 }
2501 p = uri->path;
2502 }
2503 /* Now change all occurrences of '\' to '/' */
2504 while (*p != '\0') {
2505 if (*p == '\\')
2506 *p = '/';
2507 p++;
2508 }
2509
2510 if (uri->scheme == NULL) {
2511 ret = xmlStrdup((const xmlChar *) uri->path);
2512 } else {
2513 ret = xmlSaveUri(uri);
2514 }
2515
2516 xmlFreeURI(uri);
2517#else
2518 ret = xmlStrdup((const xmlChar *) path);
2519#endif
2520 return(ret);
2521}
r l[0]
Definition: byte_order.h:168
const GLubyte * c
Definition: glext.h:8905
GLfloat GLfloat p
Definition: glext.h:8902
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define c
Definition: ke_i.h:80
const char * uri
Definition: sec_mgr.c:1588
strncpy
Definition: string.h:335
#define IS_WINDOWS_PATH(p)
Definition: uri.c:2388
xmlURIPtr xmlParseURI(const char *str)
Definition: uri.c:947
XMLPUBFUN const xmlChar * xmlStrstr(const xmlChar *str, const xmlChar *val)
Definition: xmlstring.c:347

Referenced by xmlCtxtResetPush(), xmlNewInputFromFile(), xmlPathToURI(), and xmlSAX2ExternalSubset().

◆ xmlCreateURI()

XMLPUBFUN xmlURIPtr xmlCreateURI ( void  )

xmlCreateURI:

Simply creates an empty xmlURI

Returns the new structure or NULL in case of error

Definition at line 1027 of file uri.c.

1027 {
1028 xmlURIPtr ret;
1029
1030 ret = (xmlURIPtr) xmlMalloc(sizeof(xmlURI));
1031 if (ret == NULL) {
1032 xmlURIErrMemory("creating URI structure\n");
1033 return(NULL);
1034 }
1035 memset(ret, 0, sizeof(xmlURI));
1036 ret->port = PORT_EMPTY;
1037 return(ret);
1038}
#define memset(x, y, z)
Definition: compat.h:39
xmlURI * xmlURIPtr
Definition: uri.h:33

Referenced by xmlBuildRelativeURI(), xmlBuildURI(), xmlCanonicPath(), xmlParseURI(), xmlParseURIRaw(), xmlURIEscape(), and xsltCheckWrite().

◆ xmlFreeURI()

XMLPUBFUN void xmlFreeURI ( xmlURIPtr  uri)

xmlFreeURI: @uri: pointer to an xmlURI

Free up the xmlURI struct

Definition at line 1396 of file uri.c.

1396 {
1397 if (uri == NULL) return;
1398
1399 if (uri->scheme != NULL) xmlFree(uri->scheme);
1400 if (uri->server != NULL) xmlFree(uri->server);
1401 if (uri->user != NULL) xmlFree(uri->user);
1402 if (uri->path != NULL) xmlFree(uri->path);
1403 if (uri->fragment != NULL) xmlFree(uri->fragment);
1404 if (uri->opaque != NULL) xmlFree(uri->opaque);
1405 if (uri->authority != NULL) xmlFree(uri->authority);
1406 if (uri->query != NULL) xmlFree(uri->query);
1407 if (uri->query_raw != NULL) xmlFree(uri->query_raw);
1408 xmlFree(uri);
1409}

Referenced by xmlBuildURI(), xmlCanonicPath(), xmlParseEntityDecl(), xmlParseStartTag2(), xmlParseURI(), xmlParseURIRaw(), xmlPathToURI(), xmlURIEscape(), xsltCheckRead(), xsltCheckWrite(), xsltDocumentFunction(), and xsltLoadStylesheetPI().

◆ xmlNormalizeURIPath()

XMLPUBFUN int xmlNormalizeURIPath ( char path)

xmlNormalizeURIPath: @path: pointer to the path string

Applies the 5 normalization steps to a path string–that is, RFC 2396 Section 5.2, steps 6.c through 6.g.

Normalization occurs directly on the string, no new allocation is done

Returns 0 or an error code

Definition at line 1429 of file uri.c.

1429 {
1430 char *cur, *out;
1431
1432 if (path == NULL)
1433 return(-1);
1434
1435 /* Skip all initial "/" chars. We want to get to the beginning of the
1436 * first non-empty segment.
1437 */
1438 cur = path;
1439 while (cur[0] == '/')
1440 ++cur;
1441 if (cur[0] == '\0')
1442 return(0);
1443
1444 /* Keep everything we've seen so far. */
1445 out = cur;
1446
1447 /*
1448 * Analyze each segment in sequence for cases (c) and (d).
1449 */
1450 while (cur[0] != '\0') {
1451 /*
1452 * c) All occurrences of "./", where "." is a complete path segment,
1453 * are removed from the buffer string.
1454 */
1455 if ((cur[0] == '.') && (cur[1] == '/')) {
1456 cur += 2;
1457 /* '//' normalization should be done at this point too */
1458 while (cur[0] == '/')
1459 cur++;
1460 continue;
1461 }
1462
1463 /*
1464 * d) If the buffer string ends with "." as a complete path segment,
1465 * that "." is removed.
1466 */
1467 if ((cur[0] == '.') && (cur[1] == '\0'))
1468 break;
1469
1470 /* Otherwise keep the segment. */
1471 while (cur[0] != '/') {
1472 if (cur[0] == '\0')
1473 goto done_cd;
1474 (out++)[0] = (cur++)[0];
1475 }
1476 /* normalize // */
1477 while ((cur[0] == '/') && (cur[1] == '/'))
1478 cur++;
1479
1480 (out++)[0] = (cur++)[0];
1481 }
1482 done_cd:
1483 out[0] = '\0';
1484
1485 /* Reset to the beginning of the first segment for the next sequence. */
1486 cur = path;
1487 while (cur[0] == '/')
1488 ++cur;
1489 if (cur[0] == '\0')
1490 return(0);
1491
1492 /*
1493 * Analyze each segment in sequence for cases (e) and (f).
1494 *
1495 * e) All occurrences of "<segment>/../", where <segment> is a
1496 * complete path segment not equal to "..", are removed from the
1497 * buffer string. Removal of these path segments is performed
1498 * iteratively, removing the leftmost matching pattern on each
1499 * iteration, until no matching pattern remains.
1500 *
1501 * f) If the buffer string ends with "<segment>/..", where <segment>
1502 * is a complete path segment not equal to "..", that
1503 * "<segment>/.." is removed.
1504 *
1505 * To satisfy the "iterative" clause in (e), we need to collapse the
1506 * string every time we find something that needs to be removed. Thus,
1507 * we don't need to keep two pointers into the string: we only need a
1508 * "current position" pointer.
1509 */
1510 while (1) {
1511 char *segp, *tmp;
1512
1513 /* At the beginning of each iteration of this loop, "cur" points to
1514 * the first character of the segment we want to examine.
1515 */
1516
1517 /* Find the end of the current segment. */
1518 segp = cur;
1519 while ((segp[0] != '/') && (segp[0] != '\0'))
1520 ++segp;
1521
1522 /* If this is the last segment, we're done (we need at least two
1523 * segments to meet the criteria for the (e) and (f) cases).
1524 */
1525 if (segp[0] == '\0')
1526 break;
1527
1528 /* If the first segment is "..", or if the next segment _isn't_ "..",
1529 * keep this segment and try the next one.
1530 */
1531 ++segp;
1532 if (((cur[0] == '.') && (cur[1] == '.') && (segp == cur+3))
1533 || ((segp[0] != '.') || (segp[1] != '.')
1534 || ((segp[2] != '/') && (segp[2] != '\0')))) {
1535 cur = segp;
1536 continue;
1537 }
1538
1539 /* If we get here, remove this segment and the next one and back up
1540 * to the previous segment (if there is one), to implement the
1541 * "iteratively" clause. It's pretty much impossible to back up
1542 * while maintaining two pointers into the buffer, so just compact
1543 * the whole buffer now.
1544 */
1545
1546 /* If this is the end of the buffer, we're done. */
1547 if (segp[2] == '\0') {
1548 cur[0] = '\0';
1549 break;
1550 }
1551 /* Valgrind complained, strcpy(cur, segp + 3); */
1552 /* string will overlap, do not use strcpy */
1553 tmp = cur;
1554 segp += 3;
1555 while ((*tmp++ = *segp++) != 0)
1556 ;
1557
1558 /* If there are no previous segments, then keep going from here. */
1559 segp = cur;
1560 while ((segp > path) && ((--segp)[0] == '/'))
1561 ;
1562 if (segp == path)
1563 continue;
1564
1565 /* "segp" is pointing to the end of a previous segment; find it's
1566 * start. We need to back up to the previous segment and start
1567 * over with that to handle things like "foo/bar/../..". If we
1568 * don't do this, then on the first pass we'll remove the "bar/..",
1569 * but be pointing at the second ".." so we won't realize we can also
1570 * remove the "foo/..".
1571 */
1572 cur = segp;
1573 while ((cur > path) && (cur[-1] != '/'))
1574 --cur;
1575 }
1576 out[0] = '\0';
1577
1578 /*
1579 * g) If the resulting buffer string still begins with one or more
1580 * complete path segments of "..", then the reference is
1581 * considered to be in error. Implementations may handle this
1582 * error by retaining these components in the resolved path (i.e.,
1583 * treating them as part of the final URI), by removing them from
1584 * the resolved path (i.e., discarding relative levels above the
1585 * root), or by avoiding traversal of the reference.
1586 *
1587 * We discard them from the final path.
1588 */
1589 if (path[0] == '/') {
1590 cur = path;
1591 while ((cur[0] == '/') && (cur[1] == '.') && (cur[2] == '.')
1592 && ((cur[3] == '/') || (cur[3] == '\0')))
1593 cur += 3;
1594
1595 if (cur != path) {
1596 out = path;
1597 while (cur[0] != '\0')
1598 (out++)[0] = (cur++)[0];
1599 out[0] = 0;
1600 }
1601 }
1602
1603 return(0);
1604}

Referenced by xmlBuildURI().

◆ xmlParseURI()

XMLPUBFUN xmlURIPtr xmlParseURI ( const char str)

xmlParseURI: @str: the URI string to analyze

Parse an URI based on RFC 3986

URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]

Returns a newly built xmlURIPtr or NULL in case of error

Definition at line 947 of file uri.c.

947 {
949 int ret;
950
951 if (str == NULL)
952 return(NULL);
953 uri = xmlCreateURI();
954 if (uri != NULL) {
956 if (ret) {
958 return(NULL);
959 }
960 }
961 return(uri);
962}
const WCHAR * str
static int xmlParse3986URIReference(xmlURIPtr uri, const char *str)
Definition: uri.c:913

Referenced by xmlCanonicPath(), xmlParseEntityDecl(), xmlParseStartTag2(), xmlPathToURI(), xsltCheckRead(), xsltCheckWrite(), xsltDocumentFunction(), and xsltLoadStylesheetPI().

◆ xmlParseURIRaw()

XMLPUBFUN xmlURIPtr xmlParseURIRaw ( const char str,
int  raw 
)

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 = URI / relative-ref

Returns a newly built xmlURIPtr or NULL in case of error

Definition at line 993 of file uri.c.

993 {
995 int ret;
996
997 if (str == NULL)
998 return(NULL);
999 uri = xmlCreateURI();
1000 if (uri != NULL) {
1001 if (raw) {
1002 uri->cleanup |= 2;
1003 }
1005 if (ret) {
1006 xmlFreeURI(uri);
1007 return(NULL);
1008 }
1009 }
1010 return(uri);
1011}

◆ xmlParseURIReference()

XMLPUBFUN int xmlParseURIReference ( xmlURIPtr  uri,
const char str 
)

xmlParseURIReference: @uri: pointer to an URI structure @str: the string to analyze

Parse an URI reference string based on RFC 3986 and fills in the appropriate fields of the @uri structure

URI-reference = URI / relative-ref

Returns 0 or the error code

Definition at line 977 of file uri.c.

977 {
979}

Referenced by xmlBuildRelativeURI(), xmlBuildURI(), xmlParseURIRaw(), and xmlURIEscape().

◆ xmlPathToURI()

XMLPUBFUN xmlChar * xmlPathToURI ( const xmlChar path)

xmlPathToURI: @path: the resource locator in a filesystem notation

Constructs an URI expressing the existing path

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.

Definition at line 2535 of file uri.c.

2536{
2537 xmlURIPtr uri;
2538 xmlURI temp;
2539 xmlChar *ret, *cal;
2540
2541 if (path == NULL)
2542 return(NULL);
2543
2544 if ((uri = xmlParseURI((const char *) path)) != NULL) {
2545 xmlFreeURI(uri);
2546 return xmlStrdup(path);
2547 }
2548 cal = xmlCanonicPath(path);
2549 if (cal == NULL)
2550 return(NULL);
2551#if defined(_WIN32)
2552 /* xmlCanonicPath can return an URI on Windows (is that the intended behaviour?)
2553 If 'cal' is a valid URI already then we are done here, as continuing would make
2554 it invalid. */
2555 if ((uri = xmlParseURI((const char *) cal)) != NULL) {
2556 xmlFreeURI(uri);
2557 return cal;
2558 }
2559 /* 'cal' can contain a relative path with backslashes. If that is processed
2560 by xmlSaveURI, they will be escaped and the external entity loader machinery
2561 will fail. So convert them to slashes. Misuse 'ret' for walking. */
2562 ret = cal;
2563 while (*ret != '\0') {
2564 if (*ret == '\\')
2565 *ret = '/';
2566 ret++;
2567 }
2568#endif
2569 memset(&temp, 0, sizeof(temp));
2570 temp.path = (char *) cal;
2571 ret = xmlSaveUri(&temp);
2572 xmlFree(cal);
2573 return(ret);
2574}
static calc_node_t temp
Definition: rpn_ieee.c:38
xmlChar * xmlCanonicPath(const xmlChar *path)
Definition: uri.c:2394

Referenced by xmlSAX2StartDocument().

◆ xmlPrintURI()

XMLPUBFUN void xmlPrintURI ( FILE stream,
xmlURIPtr  uri 
)

xmlPrintURI: @stream: a FILE* for the output @uri: pointer to an xmlURI

Prints the URI in the stream @stream.

Definition at line 1349 of file uri.c.

1349 {
1350 xmlChar *out;
1351
1352 out = xmlSaveUri(uri);
1353 if (out != NULL) {
1354 fprintf(stream, "%s", (char *) out);
1355 xmlFree(out);
1356 }
1357}
int WINAPIV fprintf(FILE *file, const char *format,...)
Definition: file.c:5549
Definition: parse.h:23

◆ xmlSaveUri()

XMLPUBFUN xmlChar * xmlSaveUri ( xmlURIPtr  uri)

xmlSaveUri: @uri: pointer to an xmlURI

Save the URI as an escaped string

Returns a new string (to be deallocated by caller)

Definition at line 1074 of file uri.c.

1074 {
1075 xmlChar *ret = NULL;
1076 xmlChar *temp;
1077 const char *p;
1078 int len;
1079 int max;
1080
1081 if (uri == NULL) return(NULL);
1082
1083
1084 max = 80;
1085 ret = (xmlChar *) xmlMallocAtomic(max + 1);
1086 if (ret == NULL) {
1087 xmlURIErrMemory("saving URI\n");
1088 return(NULL);
1089 }
1090 len = 0;
1091
1092 if (uri->scheme != NULL) {
1093 p = uri->scheme;
1094 while (*p != 0) {
1095 if (len >= max) {
1097 if (temp == NULL) goto mem_error;
1098 ret = temp;
1099 }
1100 ret[len++] = *p++;
1101 }
1102 if (len >= max) {
1104 if (temp == NULL) goto mem_error;
1105 ret = temp;
1106 }
1107 ret[len++] = ':';
1108 }
1109 if (uri->opaque != NULL) {
1110 p = uri->opaque;
1111 while (*p != 0) {
1112 if (len + 3 >= max) {
1114 if (temp == NULL) goto mem_error;
1115 ret = temp;
1116 }
1117 if (IS_RESERVED(*(p)) || IS_UNRESERVED(*(p)))
1118 ret[len++] = *p++;
1119 else {
1120 int val = *(unsigned char *)p++;
1121 int hi = val / 0x10, lo = val % 0x10;
1122 ret[len++] = '%';
1123 ret[len++] = hi + (hi > 9? 'A'-10 : '0');
1124 ret[len++] = lo + (lo > 9? 'A'-10 : '0');
1125 }
1126 }
1127 } else {
1128 if ((uri->server != NULL) || (uri->port != PORT_EMPTY)) {
1129 if (len + 3 >= max) {
1131 if (temp == NULL) goto mem_error;
1132 ret = temp;
1133 }
1134 ret[len++] = '/';
1135 ret[len++] = '/';
1136 if (uri->user != NULL) {
1137 p = uri->user;
1138 while (*p != 0) {
1139 if (len + 3 >= max) {
1141 if (temp == NULL) goto mem_error;
1142 ret = temp;
1143 }
1144 if ((IS_UNRESERVED(*(p))) ||
1145 ((*(p) == ';')) || ((*(p) == ':')) ||
1146 ((*(p) == '&')) || ((*(p) == '=')) ||
1147 ((*(p) == '+')) || ((*(p) == '$')) ||
1148 ((*(p) == ',')))
1149 ret[len++] = *p++;
1150 else {
1151 int val = *(unsigned char *)p++;
1152 int hi = val / 0x10, lo = val % 0x10;
1153 ret[len++] = '%';
1154 ret[len++] = hi + (hi > 9? 'A'-10 : '0');
1155 ret[len++] = lo + (lo > 9? 'A'-10 : '0');
1156 }
1157 }
1158 if (len + 3 >= max) {
1160 if (temp == NULL) goto mem_error;
1161 ret = temp;
1162 }
1163 ret[len++] = '@';
1164 }
1165 if (uri->server != NULL) {
1166 p = uri->server;
1167 while (*p != 0) {
1168 if (len >= max) {
1170 if (temp == NULL) goto mem_error;
1171 ret = temp;
1172 }
1173 /* TODO: escaping? */
1174 ret[len++] = (xmlChar) *p++;
1175 }
1176 }
1177 if (uri->port > 0) {
1178 if (len + 10 >= max) {
1180 if (temp == NULL) goto mem_error;
1181 ret = temp;
1182 }
1183 len += snprintf((char *) &ret[len], max - len, ":%d", uri->port);
1184 }
1185 } else if (uri->authority != NULL) {
1186 if (len + 3 >= max) {
1188 if (temp == NULL) goto mem_error;
1189 ret = temp;
1190 }
1191 ret[len++] = '/';
1192 ret[len++] = '/';
1193 p = uri->authority;
1194 while (*p != 0) {
1195 if (len + 3 >= max) {
1197 if (temp == NULL) goto mem_error;
1198 ret = temp;
1199 }
1200 if ((IS_UNRESERVED(*(p))) ||
1201 ((*(p) == '$')) || ((*(p) == ',')) || ((*(p) == ';')) ||
1202 ((*(p) == ':')) || ((*(p) == '@')) || ((*(p) == '&')) ||
1203 ((*(p) == '=')) || ((*(p) == '+')))
1204 ret[len++] = *p++;
1205 else {
1206 int val = *(unsigned char *)p++;
1207 int hi = val / 0x10, lo = val % 0x10;
1208 ret[len++] = '%';
1209 ret[len++] = hi + (hi > 9? 'A'-10 : '0');
1210 ret[len++] = lo + (lo > 9? 'A'-10 : '0');
1211 }
1212 }
1213 } else if (uri->scheme != NULL) {
1214 if (len + 3 >= max) {
1216 if (temp == NULL) goto mem_error;
1217 ret = temp;
1218 }
1219 }
1220 if (uri->path != NULL) {
1221 p = uri->path;
1222 /*
1223 * the colon in file:///d: should not be escaped or
1224 * Windows accesses fail later.
1225 */
1226 if ((uri->scheme != NULL) &&
1227 (p[0] == '/') &&
1228 (((p[1] >= 'a') && (p[1] <= 'z')) ||
1229 ((p[1] >= 'A') && (p[1] <= 'Z'))) &&
1230 (p[2] == ':') &&
1231 (xmlStrEqual(BAD_CAST uri->scheme, BAD_CAST "file"))) {
1232 if (len + 3 >= max) {
1234 if (temp == NULL) goto mem_error;
1235 ret = temp;
1236 }
1237 ret[len++] = *p++;
1238 ret[len++] = *p++;
1239 ret[len++] = *p++;
1240 }
1241 while (*p != 0) {
1242 if (len + 3 >= max) {
1244 if (temp == NULL) goto mem_error;
1245 ret = temp;
1246 }
1247 if ((IS_UNRESERVED(*(p))) || ((*(p) == '/')) ||
1248 ((*(p) == ';')) || ((*(p) == '@')) || ((*(p) == '&')) ||
1249 ((*(p) == '=')) || ((*(p) == '+')) || ((*(p) == '$')) ||
1250 ((*(p) == ',')))
1251 ret[len++] = *p++;
1252 else {
1253 int val = *(unsigned char *)p++;
1254 int hi = val / 0x10, lo = val % 0x10;
1255 ret[len++] = '%';
1256 ret[len++] = hi + (hi > 9? 'A'-10 : '0');
1257 ret[len++] = lo + (lo > 9? 'A'-10 : '0');
1258 }
1259 }
1260 }
1261 if (uri->query_raw != NULL) {
1262 if (len + 1 >= max) {
1264 if (temp == NULL) goto mem_error;
1265 ret = temp;
1266 }
1267 ret[len++] = '?';
1268 p = uri->query_raw;
1269 while (*p != 0) {
1270 if (len + 1 >= max) {
1272 if (temp == NULL) goto mem_error;
1273 ret = temp;
1274 }
1275 ret[len++] = *p++;
1276 }
1277 } else if (uri->query != NULL) {
1278 if (len + 3 >= max) {
1280 if (temp == NULL) goto mem_error;
1281 ret = temp;
1282 }
1283 ret[len++] = '?';
1284 p = uri->query;
1285 while (*p != 0) {
1286 if (len + 3 >= max) {
1288 if (temp == NULL) goto mem_error;
1289 ret = temp;
1290 }
1291 if ((IS_UNRESERVED(*(p))) || (IS_RESERVED(*(p))))
1292 ret[len++] = *p++;
1293 else {
1294 int val = *(unsigned char *)p++;
1295 int hi = val / 0x10, lo = val % 0x10;
1296 ret[len++] = '%';
1297 ret[len++] = hi + (hi > 9? 'A'-10 : '0');
1298 ret[len++] = lo + (lo > 9? 'A'-10 : '0');
1299 }
1300 }
1301 }
1302 }
1303 if (uri->fragment != NULL) {
1304 if (len + 3 >= max) {
1306 if (temp == NULL) goto mem_error;
1307 ret = temp;
1308 }
1309 ret[len++] = '#';
1310 p = uri->fragment;
1311 while (*p != 0) {
1312 if (len + 3 >= max) {
1314 if (temp == NULL) goto mem_error;
1315 ret = temp;
1316 }
1317 if ((IS_UNRESERVED(*(p))) || (IS_RESERVED(*(p))))
1318 ret[len++] = *p++;
1319 else {
1320 int val = *(unsigned char *)p++;
1321 int hi = val / 0x10, lo = val % 0x10;
1322 ret[len++] = '%';
1323 ret[len++] = hi + (hi > 9? 'A'-10 : '0');
1324 ret[len++] = lo + (lo > 9? 'A'-10 : '0');
1325 }
1326 }
1327 }
1328 if (len >= max) {
1330 if (temp == NULL) goto mem_error;
1331 ret = temp;
1332 }
1333 ret[len] = 0;
1334 return(ret);
1335
1336mem_error:
1337 xmlFree(ret);
1338 return(NULL);
1339}
#define IS_RESERVED(x)
Definition: uri.c:116
static xmlChar * xmlSaveUriRealloc(xmlChar *ret, int *max)
Definition: uri.c:1047
#define IS_UNRESERVED(x)
Definition: uri.c:125
#define max(a, b)
Definition: svc.c:63
#define snprintf
Definition: wintirpc.h:48

Referenced by xmlBuildURI(), xmlCanonicPath(), xmlPathToURI(), xmlPrintURI(), and xsltDocumentFunction().

◆ xmlURIEscape()

XMLPUBFUN xmlChar * xmlURIEscape ( const xmlChar str)

xmlURIEscape: @str: the string of the URI to escape

Escaping routine, does not do validity checks ! It will try to escape the chars needing this, but this is heuristic based it's impossible to be sure.

Returns an copy of the string, but escaped

25 May 2001 Uses xmlParseURI and xmlURIEscapeStr to try to escape correctly according to RFC2396.

  • Carl Douglas

Definition at line 1762 of file uri.c.

1763{
1764 xmlChar *ret, *segment = NULL;
1765 xmlURIPtr uri;
1766 int ret2;
1767
1768 if (str == NULL)
1769 return (NULL);
1770
1771 uri = xmlCreateURI();
1772 if (uri != NULL) {
1773 /*
1774 * Allow escaping errors in the unescaped form
1775 */
1776 uri->cleanup = 1;
1777 ret2 = xmlParseURIReference(uri, (const char *)str);
1778 if (ret2) {
1779 xmlFreeURI(uri);
1780 return (NULL);
1781 }
1782 }
1783
1784 if (!uri)
1785 return NULL;
1786
1787 ret = NULL;
1788
1789#define NULLCHK(p) if(!p) { \
1790 xmlURIErrMemory("escaping URI value\n"); \
1791 xmlFreeURI(uri); \
1792 xmlFree(ret); \
1793 return NULL; } \
1794
1795 if (uri->scheme) {
1796 segment = xmlURIEscapeStr(BAD_CAST uri->scheme, BAD_CAST "+-.");
1797 NULLCHK(segment)
1798 ret = xmlStrcat(ret, segment);
1799 ret = xmlStrcat(ret, BAD_CAST ":");
1800 xmlFree(segment);
1801 }
1802
1803 if (uri->authority) {
1804 segment =
1805 xmlURIEscapeStr(BAD_CAST uri->authority, BAD_CAST "/?;:@");
1806 NULLCHK(segment)
1807 ret = xmlStrcat(ret, BAD_CAST "//");
1808 ret = xmlStrcat(ret, segment);
1809 xmlFree(segment);
1810 }
1811
1812 if (uri->user) {
1813 segment = xmlURIEscapeStr(BAD_CAST uri->user, BAD_CAST ";:&=+$,");
1814 NULLCHK(segment)
1815 ret = xmlStrcat(ret,BAD_CAST "//");
1816 ret = xmlStrcat(ret, segment);
1817 ret = xmlStrcat(ret, BAD_CAST "@");
1818 xmlFree(segment);
1819 }
1820
1821 if (uri->server) {
1822 segment = xmlURIEscapeStr(BAD_CAST uri->server, BAD_CAST "/?;:@");
1823 NULLCHK(segment)
1824 if (uri->user == NULL)
1825 ret = xmlStrcat(ret, BAD_CAST "//");
1826 ret = xmlStrcat(ret, segment);
1827 xmlFree(segment);
1828 }
1829
1830 if (uri->port > 0) {
1831 xmlChar port[11];
1832
1833 snprintf((char *) port, 11, "%d", uri->port);
1834 ret = xmlStrcat(ret, BAD_CAST ":");
1835 ret = xmlStrcat(ret, port);
1836 }
1837
1838 if (uri->path) {
1839 segment =
1840 xmlURIEscapeStr(BAD_CAST uri->path, BAD_CAST ":@&=+$,/?;");
1841 NULLCHK(segment)
1842 ret = xmlStrcat(ret, segment);
1843 xmlFree(segment);
1844 }
1845
1846 if (uri->query_raw) {
1847 ret = xmlStrcat(ret, BAD_CAST "?");
1848 ret = xmlStrcat(ret, BAD_CAST uri->query_raw);
1849 }
1850 else if (uri->query) {
1851 segment =
1852 xmlURIEscapeStr(BAD_CAST uri->query, BAD_CAST ";/?:@&=+,$");
1853 NULLCHK(segment)
1854 ret = xmlStrcat(ret, BAD_CAST "?");
1855 ret = xmlStrcat(ret, segment);
1856 xmlFree(segment);
1857 }
1858
1859 if (uri->opaque) {
1860 segment = xmlURIEscapeStr(BAD_CAST uri->opaque, BAD_CAST "");
1861 NULLCHK(segment)
1862 ret = xmlStrcat(ret, segment);
1863 xmlFree(segment);
1864 }
1865
1866 if (uri->fragment) {
1867 segment = xmlURIEscapeStr(BAD_CAST uri->fragment, BAD_CAST "#");
1868 NULLCHK(segment)
1869 ret = xmlStrcat(ret, BAD_CAST "#");
1870 ret = xmlStrcat(ret, segment);
1871 xmlFree(segment);
1872 }
1873
1874 xmlFreeURI(uri);
1875#undef NULLCHK
1876
1877 return (ret);
1878}
USHORT port
Definition: uri.c:228
#define NULLCHK(p)
XMLPUBFUN xmlChar * xmlStrcat(xmlChar *cur, const xmlChar *add)
Definition: xmlstring.c:524

◆ xmlURIEscapeStr()

XMLPUBFUN xmlChar * xmlURIEscapeStr ( const xmlChar str,
const xmlChar list 
)

xmlURIEscapeStr: @str: string to escape @list: exception list string of chars not to escape

This routine escapes a string to hex, ignoring reserved characters (a-z, A-Z, 0-9, "@-_.!~*'()") and the characters in the exception list.

Returns a new escaped string or NULL in case of error.

Definition at line 1689 of file uri.c.

1689 {
1690 xmlChar *ret, ch;
1691 xmlChar *temp;
1692 const xmlChar *in;
1693 int len, out;
1694
1695 if (str == NULL)
1696 return(NULL);
1697 if (str[0] == 0)
1698 return(xmlStrdup(str));
1699 len = xmlStrlen(str);
1700 if (!(len > 0)) return(NULL);
1701
1702 len += 20;
1704 if (ret == NULL) {
1705 xmlURIErrMemory("escaping URI value\n");
1706 return(NULL);
1707 }
1708 in = (const xmlChar *) str;
1709 out = 0;
1710 while(*in != 0) {
1711 if (len - out <= 3) {
1713 if (temp == NULL) {
1714 xmlURIErrMemory("escaping URI value\n");
1715 xmlFree(ret);
1716 return(NULL);
1717 }
1718 ret = temp;
1719 }
1720
1721 ch = *in;
1722
1723 if ((ch != '@') && (!IS_UNRESERVED(ch)) && (!xmlStrchr(list, ch))) {
1724 unsigned char val;
1725 ret[out++] = '%';
1726 val = ch >> 4;
1727 if (val <= 9)
1728 ret[out++] = '0' + val;
1729 else
1730 ret[out++] = 'A' + val - 0xA;
1731 val = ch & 0xF;
1732 if (val <= 9)
1733 ret[out++] = '0' + val;
1734 else
1735 ret[out++] = 'A' + val - 0xA;
1736 in++;
1737 } else {
1738 ret[out++] = *in++;
1739 }
1740
1741 }
1742 ret[out] = 0;
1743 return(ret);
1744}
Definition: list.h:37
unsigned char ch[4][2]
Definition: console.c:118
GLuint in
Definition: glext.h:9616
XMLPUBFUN const xmlChar * xmlStrchr(const xmlChar *str, xmlChar val)
Definition: xmlstring.c:327

Referenced by xmlCanonicPath(), xmlURIEscape(), and xsltDocumentElem().

◆ xmlURIUnescapeString()

XMLPUBFUN char * xmlURIUnescapeString ( const char str,
int  len,
char target 
)

xmlURIUnescapeString: @str: the string to unescape @len: the length in bytes to unescape (or <= 0 to indicate full string) @target: optional destination buffer

Unescaping routine, but does not check that the string is an URI. The output is a direct unsigned char translation of XX values (no encoding) Note that the length of the result can only be smaller or same size as the input string.

Returns a copy of the string, but unescaped, will return NULL only in case of error

Definition at line 1629 of file uri.c.

1629 {
1630 char *ret, *out;
1631 const char *in;
1632
1633 if (str == NULL)
1634 return(NULL);
1635 if (len <= 0) len = strlen(str);
1636 if (len < 0) return(NULL);
1637
1638 if (target == NULL) {
1639 ret = (char *) xmlMallocAtomic(len + 1);
1640 if (ret == NULL) {
1641 xmlURIErrMemory("unescaping URI value\n");
1642 return(NULL);
1643 }
1644 } else
1645 ret = target;
1646 in = str;
1647 out = ret;
1648 while(len > 0) {
1649 if ((len > 2) && (*in == '%') && (is_hex(in[1])) && (is_hex(in[2]))) {
1650 int c = 0;
1651 in++;
1652 if ((*in >= '0') && (*in <= '9'))
1653 c = (*in - '0');
1654 else if ((*in >= 'a') && (*in <= 'f'))
1655 c = (*in - 'a') + 10;
1656 else if ((*in >= 'A') && (*in <= 'F'))
1657 c = (*in - 'A') + 10;
1658 in++;
1659 if ((*in >= '0') && (*in <= '9'))
1660 c = c * 16 + (*in - '0');
1661 else if ((*in >= 'a') && (*in <= 'f'))
1662 c = c * 16 + (*in - 'a') + 10;
1663 else if ((*in >= 'A') && (*in <= 'F'))
1664 c = c * 16 + (*in - 'A') + 10;
1665 in++;
1666 len -= 3;
1667 /* Explicit sign change */
1668 *out++ = (char) c;
1669 } else {
1670 *out++ = *in++;
1671 len--;
1672 }
1673 }
1674 *out = 0;
1675 return(ret);
1676}
unsigned char
Definition: typeof.h:29
#define is_hex(c)
Definition: registry.c:430
Definition: tools.h:99

Referenced by xmlParse3986Fragment(), xmlParse3986Host(), xmlParse3986PathAbEmpty(), xmlParse3986PathAbsolute(), xmlParse3986PathNoScheme(), xmlParse3986PathRootless(), xmlParse3986Query(), and xmlParse3986Userinfo().