ReactOS 0.4.15-dev-8417-gb6b82fe
uri.c File Reference
#include "libxml.h"
#include <limits.h>
#include <string.h>
#include <libxml/xmlmemory.h>
#include <libxml/uri.h>
#include <libxml/globals.h>
#include <libxml/xmlerror.h>
Include dependency graph for uri.c:

Go to the source code of this file.

Macros

#define IN_LIBXML
 
#define MAX_URI_LENGTH   1024 * 1024
 
#define IS_ALPHA(x)   (IS_LOWALPHA(x) || IS_UPALPHA(x))
 
#define IS_LOWALPHA(x)   (((x) >= 'a') && ((x) <= 'z'))
 
#define IS_UPALPHA(x)   (((x) >= 'A') && ((x) <= 'Z'))
 
#define IS_DIGIT(x)   (((x) >= '0') && ((x) <= '9'))
 
#define IS_ALPHANUM(x)   (IS_ALPHA(x) || IS_DIGIT(x))
 
#define IS_MARK(x)
 
#define IS_UNWISE(p)
 
#define IS_RESERVED(x)
 
#define IS_UNRESERVED(x)   (IS_ALPHANUM(x) || IS_MARK(x))
 
#define NEXT(p)   ((*p == '%')? p += 3 : p++)
 
#define STRNDUP(s, n)   (char *) xmlStrndup((const xmlChar *)(s), (n))
 
#define ISA_DIGIT(p)   ((*(p) >= '0') && (*(p) <= '9'))
 
#define ISA_ALPHA(p)
 
#define ISA_HEXDIG(p)
 
#define ISA_SUB_DELIM(p)
 
#define ISA_GEN_DELIM(p)
 
#define ISA_RESERVED(p)   (ISA_GEN_DELIM(p) || (ISA_SUB_DELIM(p)))
 
#define ISA_UNRESERVED(p)
 
#define ISA_PCT_ENCODED(p)    ((*(p) == '%') && (ISA_HEXDIG(p + 1)) && (ISA_HEXDIG(p + 2)))
 
#define ISA_PCHAR(p)
 
#define NULLCHK(p)
 
#define IS_WINDOWS_PATH(p)
 

Functions

static void xmlURIErrMemory (const char *extra)
 
static void xmlCleanURI (xmlURIPtr uri)
 
static int xmlParse3986Scheme (xmlURIPtr uri, const char **str)
 
static int xmlParse3986Fragment (xmlURIPtr uri, const char **str)
 
static int xmlParse3986Query (xmlURIPtr uri, const char **str)
 
static int xmlParse3986Port (xmlURIPtr uri, const char **str)
 
static int xmlParse3986Userinfo (xmlURIPtr uri, const char **str)
 
static int xmlParse3986DecOctet (const char **str)
 
static int xmlParse3986Host (xmlURIPtr uri, const char **str)
 
static int xmlParse3986Authority (xmlURIPtr uri, const char **str)
 
static int xmlParse3986Segment (const char **str, char forbid, int empty)
 
static int xmlParse3986PathAbEmpty (xmlURIPtr uri, const char **str)
 
static int xmlParse3986PathAbsolute (xmlURIPtr uri, const char **str)
 
static int xmlParse3986PathRootless (xmlURIPtr uri, const char **str)
 
static int xmlParse3986PathNoScheme (xmlURIPtr uri, const char **str)
 
static int xmlParse3986HierPart (xmlURIPtr uri, const char **str)
 
static int xmlParse3986RelativeRef (xmlURIPtr uri, const char *str)
 
static int xmlParse3986URI (xmlURIPtr uri, const char *str)
 
static int xmlParse3986URIReference (xmlURIPtr uri, const char *str)
 
xmlURIPtr xmlParseURI (const char *str)
 
int xmlParseURIReference (xmlURIPtr uri, const char *str)
 
xmlURIPtr xmlParseURIRaw (const char *str, int raw)
 
xmlURIPtr xmlCreateURI (void)
 
static xmlCharxmlSaveUriRealloc (xmlChar *ret, int *max)
 
xmlCharxmlSaveUri (xmlURIPtr uri)
 
void xmlPrintURI (FILE *stream, xmlURIPtr uri)
 
void xmlFreeURI (xmlURIPtr uri)
 
int xmlNormalizeURIPath (char *path)
 
static int is_hex (char c)
 
charxmlURIUnescapeString (const char *str, int len, char *target)
 
xmlCharxmlURIEscapeStr (const xmlChar *str, const xmlChar *list)
 
xmlCharxmlURIEscape (const xmlChar *str)
 
xmlCharxmlBuildURI (const xmlChar *URI, const xmlChar *base)
 
xmlCharxmlBuildRelativeURI (const xmlChar *URI, const xmlChar *base)
 
xmlCharxmlCanonicPath (const xmlChar *path)
 
xmlCharxmlPathToURI (const xmlChar *path)
 

Macro Definition Documentation

◆ IN_LIBXML

#define IN_LIBXML

uri.c: set of generic URI related routines

Reference: RFCs 3986, 2732 and 2373

See Copyright for the status of this software.

danie.nosp@m.l@ve.nosp@m.illar.nosp@m.d.co.nosp@m.m

Definition at line 11 of file uri.c.

◆ IS_ALPHA

#define IS_ALPHA (   x)    (IS_LOWALPHA(x) || IS_UPALPHA(x))

Definition at line 59 of file uri.c.

◆ IS_ALPHANUM

#define IS_ALPHANUM (   x)    (IS_ALPHA(x) || IS_DIGIT(x))

Definition at line 89 of file uri.c.

◆ IS_DIGIT

#define IS_DIGIT (   x)    (((x) >= '0') && ((x) <= '9'))

Definition at line 83 of file uri.c.

◆ IS_LOWALPHA

#define IS_LOWALPHA (   x)    (((x) >= 'a') && ((x) <= 'z'))

Definition at line 68 of file uri.c.

◆ IS_MARK

#define IS_MARK (   x)
Value:
(((x) == '-') || ((x) == '_') || ((x) == '.') || \
((x) == '!') || ((x) == '~') || ((x) == '*') || ((x) == '\'') || \
((x) == '(') || ((x) == ')'))
GLint GLint GLint GLint GLint x
Definition: gl.h:1548

Definition at line 95 of file uri.c.

◆ IS_RESERVED

#define IS_RESERVED (   x)
Value:
(((x) == ';') || ((x) == '/') || ((x) == '?') || \
((x) == ':') || ((x) == '@') || ((x) == '&') || ((x) == '=') || \
((x) == '+') || ((x) == '$') || ((x) == ',') || ((x) == '[') || \
((x) == ']'))

Definition at line 112 of file uri.c.

◆ IS_UNRESERVED

#define IS_UNRESERVED (   x)    (IS_ALPHANUM(x) || IS_MARK(x))

Definition at line 121 of file uri.c.

◆ IS_UNWISE

#define IS_UNWISE (   p)
Value:
(((*(p) == '{')) || ((*(p) == '}')) || ((*(p) == '|')) || \
((*(p) == '\\')) || ((*(p) == '^')) || ((*(p) == '[')) || \
((*(p) == ']')) || ((*(p) == '`')))
GLfloat GLfloat p
Definition: glext.h:8902

Definition at line 103 of file uri.c.

◆ IS_UPALPHA

#define IS_UPALPHA (   x)    (((x) >= 'A') && ((x) <= 'Z'))

Definition at line 75 of file uri.c.

◆ IS_WINDOWS_PATH

#define IS_WINDOWS_PATH (   p)
Value:
((p != NULL) && \
(((p[0] >= 'a') && (p[0] <= 'z')) || \
((p[0] >= 'A') && (p[0] <= 'Z'))) && \
(p[1] == ':') && ((p[2] == '/') || (p[2] == '\\')))
#define NULL
Definition: types.h:112

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

Constructs a canonic path from the specified path.

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 argument is NULL, the function returns NULL.

Definition at line 2374 of file uri.c.

◆ ISA_ALPHA

#define ISA_ALPHA (   p)
Value:
(((*(p) >= 'a') && (*(p) <= 'z')) || \
((*(p) >= 'A') && (*(p) <= 'Z')))

Definition at line 148 of file uri.c.

◆ ISA_DIGIT

#define ISA_DIGIT (   p)    ((*(p) >= '0') && (*(p) <= '9'))

Definition at line 147 of file uri.c.

◆ ISA_GEN_DELIM

#define ISA_GEN_DELIM (   p)
Value:
(((*(p) == ':')) || ((*(p) == '/')) || ((*(p) == '?')) || \
((*(p) == '#')) || ((*(p) == '[')) || ((*(p) == ']')) || \
((*(p) == '@')))

Definition at line 167 of file uri.c.

◆ ISA_HEXDIG

#define ISA_HEXDIG (   p)
Value:
(ISA_DIGIT(p) || ((*(p) >= 'a') && (*(p) <= 'f')) || \
((*(p) >= 'A') && (*(p) <= 'F')))
#define ISA_DIGIT(p)
Definition: uri.c:147

Definition at line 150 of file uri.c.

◆ ISA_PCHAR

#define ISA_PCHAR (   p)
Value:
((*(p) == ':')) || ((*(p) == '@')))
#define ISA_SUB_DELIM(p)
Definition: uri.c:158
#define ISA_PCT_ENCODED(p)
Definition: uri.c:187
#define ISA_UNRESERVED(p)
Definition: uri.c:180

Definition at line 193 of file uri.c.

◆ ISA_PCT_ENCODED

#define ISA_PCT_ENCODED (   p)     ((*(p) == '%') && (ISA_HEXDIG(p + 1)) && (ISA_HEXDIG(p + 2)))

Definition at line 187 of file uri.c.

◆ ISA_RESERVED

#define ISA_RESERVED (   p)    (ISA_GEN_DELIM(p) || (ISA_SUB_DELIM(p)))

Definition at line 175 of file uri.c.

◆ ISA_SUB_DELIM

#define ISA_SUB_DELIM (   p)
Value:
(((*(p) == '!')) || ((*(p) == '$')) || ((*(p) == '&')) || \
((*(p) == '(')) || ((*(p) == ')')) || ((*(p) == '*')) || \
((*(p) == '+')) || ((*(p) == ',')) || ((*(p) == ';')) || \
((*(p) == '=')) || ((*(p) == '\'')))

Definition at line 158 of file uri.c.

◆ ISA_UNRESERVED

#define ISA_UNRESERVED (   p)
Value:
((ISA_ALPHA(p)) || (ISA_DIGIT(p)) || ((*(p) == '-')) || \
((*(p) == '.')) || ((*(p) == '_')) || ((*(p) == '~')))
#define ISA_ALPHA(p)
Definition: uri.c:148

Definition at line 180 of file uri.c.

◆ MAX_URI_LENGTH

#define MAX_URI_LENGTH   1024 * 1024

MAX_URI_LENGTH:

The definition of the URI regexp in the above RFC has no size limit In practice they are usually relatively 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

Definition at line 34 of file uri.c.

◆ NEXT

#define NEXT (   p)    ((*p == '%')? p += 3 : p++)

Definition at line 127 of file uri.c.

◆ NULLCHK

#define NULLCHK (   p)
Value:
if(!p) { \
xmlURIErrMemory("escaping URI value\n"); \
xmlFreeURI(uri); \
xmlFree(ret); \
return NULL; } \
const char * uri
Definition: sec_mgr.c:1588
int ret

◆ STRNDUP

#define STRNDUP (   s,
  n 
)    (char *) xmlStrndup((const xmlChar *)(s), (n))

Definition at line 139 of file uri.c.

Function Documentation

◆ is_hex()

static int is_hex ( char  c)
static

Definition at line 1597 of file uri.c.

1597 {
1598 if (((c >= '0') && (c <= '9')) ||
1599 ((c >= 'a') && (c <= 'f')) ||
1600 ((c >= 'A') && (c <= 'F')))
1601 return(1);
1602 return(0);
1603}
const GLubyte * c
Definition: glext.h:8905

◆ xmlBuildRelativeURI()

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 2173 of file uri.c.

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

◆ xmlBuildURI()

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 1892 of file uri.c.

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

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

◆ xmlCanonicPath()

xmlChar * xmlCanonicPath ( const xmlChar path)

Definition at line 2380 of file uri.c.

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

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

◆ xmlCleanURI()

static void xmlCleanURI ( xmlURIPtr  uri)
static

xmlCleanURI: @uri: pointer to an xmlURI

Make sure the xmlURI struct is free of content

Definition at line 1357 of file uri.c.

1357 {
1358 if (uri == NULL) return;
1359
1360 if (uri->scheme != NULL) xmlFree(uri->scheme);
1361 uri->scheme = NULL;
1362 if (uri->server != NULL) xmlFree(uri->server);
1363 uri->server = NULL;
1364 if (uri->user != NULL) xmlFree(uri->user);
1365 uri->user = NULL;
1366 if (uri->path != NULL) xmlFree(uri->path);
1367 uri->path = NULL;
1368 if (uri->fragment != NULL) xmlFree(uri->fragment);
1369 uri->fragment = NULL;
1370 if (uri->opaque != NULL) xmlFree(uri->opaque);
1371 uri->opaque = NULL;
1372 if (uri->authority != NULL) xmlFree(uri->authority);
1373 uri->authority = NULL;
1374 if (uri->query != NULL) xmlFree(uri->query);
1375 uri->query = NULL;
1376 if (uri->query_raw != NULL) xmlFree(uri->query_raw);
1377 uri->query_raw = NULL;
1378}

Referenced by xmlParse3986RelativeRef(), xmlParse3986URI(), and xmlParse3986URIReference().

◆ xmlCreateURI()

xmlURIPtr xmlCreateURI ( void  )

xmlCreateURI:

Simply creates an empty xmlURI

Returns the new structure or NULL in case of error

Definition at line 1020 of file uri.c.

1020 {
1021 xmlURIPtr ret;
1022
1023 ret = (xmlURIPtr) xmlMalloc(sizeof(xmlURI));
1024 if (ret == NULL) {
1025 xmlURIErrMemory("creating URI structure\n");
1026 return(NULL);
1027 }
1028 memset(ret, 0, sizeof(xmlURI));
1029 return(ret);
1030}
#define memset(x, y, z)
Definition: compat.h:39
xmlURI * xmlURIPtr
Definition: uri.h:32

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

◆ xmlFreeURI()

void xmlFreeURI ( xmlURIPtr  uri)

xmlFreeURI: @uri: pointer to an xmlURI

Free up the xmlURI struct

Definition at line 1387 of file uri.c.

1387 {
1388 if (uri == NULL) return;
1389
1390 if (uri->scheme != NULL) xmlFree(uri->scheme);
1391 if (uri->server != NULL) xmlFree(uri->server);
1392 if (uri->user != NULL) xmlFree(uri->user);
1393 if (uri->path != NULL) xmlFree(uri->path);
1394 if (uri->fragment != NULL) xmlFree(uri->fragment);
1395 if (uri->opaque != NULL) xmlFree(uri->opaque);
1396 if (uri->authority != NULL) xmlFree(uri->authority);
1397 if (uri->query != NULL) xmlFree(uri->query);
1398 if (uri->query_raw != NULL) xmlFree(uri->query_raw);
1399 xmlFree(uri);
1400}

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

◆ xmlNormalizeURIPath()

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 1420 of file uri.c.

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

Referenced by xmlBuildURI().

◆ xmlParse3986Authority()

static int xmlParse3986Authority ( xmlURIPtr  uri,
const char **  str 
)
static

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

Parse an authority part and fills in the appropriate fields of the @uri structure

authority = [ userinfo "@" ] host [ ":" port ]

Returns 0 or the error code

Definition at line 516 of file uri.c.

517{
518 const char *cur;
519 int ret;
520
521 cur = *str;
522 /*
523 * try to parse an userinfo and check for the trailing @
524 */
526 if ((ret != 0) || (*cur != '@'))
527 cur = *str;
528 else
529 cur++;
531 if (ret != 0) return(ret);
532 if (*cur == ':') {
533 cur++;
535 if (ret != 0) return(ret);
536 }
537 *str = cur;
538 return(0);
539}
const WCHAR * str
static int xmlParse3986Host(xmlURIPtr uri, const char **str)
Definition: uri.c:440
static int xmlParse3986Userinfo(xmlURIPtr uri, const char **str)
Definition: uri.c:365
static int xmlParse3986Port(xmlURIPtr uri, const char **str)
Definition: uri.c:326

Referenced by xmlParse3986HierPart(), and xmlParse3986RelativeRef().

◆ xmlParse3986DecOctet()

static int xmlParse3986DecOctet ( const char **  str)
static

xmlParse3986DecOctet: @str: the string to analyze

dec-octet = DIGIT ; 0-9 / x31-39 DIGIT ; 10-99 / "1" 2DIGIT ; 100-199 / "2" x30-34 DIGIT ; 200-249 / "25" x30-35 ; 250-255

Skip a dec-octet.

Returns 0 if found and skipped, 1 otherwise

Definition at line 402 of file uri.c.

402 {
403 const char *cur = *str;
404
405 if (!(ISA_DIGIT(cur)))
406 return(1);
407 if (!ISA_DIGIT(cur+1))
408 cur++;
409 else if ((*cur != '0') && (ISA_DIGIT(cur + 1)) && (!ISA_DIGIT(cur+2)))
410 cur += 2;
411 else if ((*cur == '1') && (ISA_DIGIT(cur + 1)) && (ISA_DIGIT(cur + 2)))
412 cur += 3;
413 else if ((*cur == '2') && (*(cur + 1) >= '0') &&
414 (*(cur + 1) <= '4') && (ISA_DIGIT(cur + 2)))
415 cur += 3;
416 else if ((*cur == '2') && (*(cur + 1) == '5') &&
417 (*(cur + 2) >= '0') && (*(cur + 1) <= '5'))
418 cur += 3;
419 else
420 return(1);
421 *str = cur;
422 return(0);
423}

Referenced by xmlParse3986Host().

◆ xmlParse3986Fragment()

static int xmlParse3986Fragment ( xmlURIPtr  uri,
const char **  str 
)
static

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

Parse the query part of an URI

fragment = *( pchar / "/" / "?" ) NOTE: the strict syntax as defined by 3986 does not allow '[' and ']' in the fragment identifier but this is used very broadly for xpointer scheme selection, so we are allowing it here to not break for example all the DocBook processing chains.

Returns 0 or the error code

Definition at line 245 of file uri.c.

246{
247 const char *cur;
248
249 if (str == NULL)
250 return (-1);
251
252 cur = *str;
253
254 while ((ISA_PCHAR(cur)) || (*cur == '/') || (*cur == '?') ||
255 (*cur == '[') || (*cur == ']') ||
256 ((uri != NULL) && (uri->cleanup & 1) && (IS_UNWISE(cur))))
257 NEXT(cur);
258 if (uri != NULL) {
259 if (uri->fragment != NULL)
260 xmlFree(uri->fragment);
261 if (uri->cleanup & 2)
262 uri->fragment = STRNDUP(*str, cur - *str);
263 else
264 uri->fragment = xmlURIUnescapeString(*str, cur - *str, NULL);
265 }
266 *str = cur;
267 return (0);
268}
#define STRNDUP(s, n)
Definition: uri.c:139
char * xmlURIUnescapeString(const char *str, int len, char *target)
Definition: uri.c:1620
#define IS_UNWISE(p)
Definition: uri.c:103
#define NEXT(p)
Definition: uri.c:127
#define ISA_PCHAR(p)
Definition: uri.c:193

Referenced by xmlParse3986RelativeRef(), and xmlParse3986URI().

◆ xmlParse3986HierPart()

static int xmlParse3986HierPart ( xmlURIPtr  uri,
const char **  str 
)
static

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

Parse an hierarchical part and fills in the appropriate fields of the @uri structure

hier-part = "//" authority path-abempty / path-absolute / path-rootless / path-empty

Returns 0 or the error code

Definition at line 760 of file uri.c.

761{
762 const char *cur;
763 int ret;
764
765 cur = *str;
766
767 if ((*cur == '/') && (*(cur + 1) == '/')) {
768 cur += 2;
770 if (ret != 0) return(ret);
771 if (uri->server == NULL)
772 uri->port = -1;
774 if (ret != 0) return(ret);
775 *str = cur;
776 return(0);
777 } else if (*cur == '/') {
779 if (ret != 0) return(ret);
780 } else if (ISA_PCHAR(cur)) {
782 if (ret != 0) return(ret);
783 } else {
784 /* path-empty is effectively empty */
785 if (uri != NULL) {
786 if (uri->path != NULL) xmlFree(uri->path);
787 uri->path = NULL;
788 }
789 }
790 *str = cur;
791 return (0);
792}
static int xmlParse3986PathAbsolute(xmlURIPtr uri, const char **str)
Definition: uri.c:627
static int xmlParse3986Authority(xmlURIPtr uri, const char **str)
Definition: uri.c:516
static int xmlParse3986PathAbEmpty(xmlURIPtr uri, const char **str)
Definition: uri.c:587
static int xmlParse3986PathRootless(xmlURIPtr uri, const char **str)
Definition: uri.c:673

Referenced by xmlParse3986URI().

◆ xmlParse3986Host()

static int xmlParse3986Host ( xmlURIPtr  uri,
const char **  str 
)
static

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

Parse an host part and fills in the appropriate fields of the @uri structure

host = IP-literal / IPv4address / reg-name IP-literal = "[" ( IPv6address / IPvFuture ) "]" IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet reg-name = *( unreserved / pct-encoded / sub-delims )

Returns 0 or the error code

Definition at line 440 of file uri.c.

441{
442 const char *cur = *str;
443 const char *host;
444
445 host = cur;
446 /*
447 * IPv6 and future addressing scheme are enclosed between brackets
448 */
449 if (*cur == '[') {
450 cur++;
451 while ((*cur != ']') && (*cur != 0))
452 cur++;
453 if (*cur != ']')
454 return(1);
455 cur++;
456 goto found;
457 }
458 /*
459 * try to parse an IPv4
460 */
461 if (ISA_DIGIT(cur)) {
462 if (xmlParse3986DecOctet(&cur) != 0)
463 goto not_ipv4;
464 if (*cur != '.')
465 goto not_ipv4;
466 cur++;
467 if (xmlParse3986DecOctet(&cur) != 0)
468 goto not_ipv4;
469 if (*cur != '.')
470 goto not_ipv4;
471 if (xmlParse3986DecOctet(&cur) != 0)
472 goto not_ipv4;
473 if (*cur != '.')
474 goto not_ipv4;
475 if (xmlParse3986DecOctet(&cur) != 0)
476 goto not_ipv4;
477 goto found;
478not_ipv4:
479 cur = *str;
480 }
481 /*
482 * then this should be a hostname which can be empty
483 */
485 NEXT(cur);
486found:
487 if (uri != NULL) {
488 if (uri->authority != NULL) xmlFree(uri->authority);
489 uri->authority = NULL;
490 if (uri->server != NULL) xmlFree(uri->server);
491 if (cur != host) {
492 if (uri->cleanup & 2)
493 uri->server = STRNDUP(host, cur - host);
494 else
495 uri->server = xmlURIUnescapeString(host, cur - host, NULL);
496 } else
497 uri->server = NULL;
498 }
499 *str = cur;
500 return(0);
501}
static int xmlParse3986DecOctet(const char **str)
Definition: uri.c:402
char * host
Definition: whois.c:55

Referenced by xmlParse3986Authority().

◆ xmlParse3986PathAbEmpty()

static int xmlParse3986PathAbEmpty ( xmlURIPtr  uri,
const char **  str 
)
static

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

Parse an path absolute or empty and fills in the appropriate fields of the @uri structure

path-abempty = *( "/" segment )

Returns 0 or the error code

Definition at line 587 of file uri.c.

588{
589 const char *cur;
590 int ret;
591
592 cur = *str;
593
594 while (*cur == '/') {
595 cur++;
596 ret = xmlParse3986Segment(&cur, 0, 1);
597 if (ret != 0) return(ret);
598 }
599 if (uri != NULL) {
600 if (uri->path != NULL) xmlFree(uri->path);
601 if (*str != cur) {
602 if (uri->cleanup & 2)
603 uri->path = STRNDUP(*str, cur - *str);
604 else
605 uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
606 } else {
607 uri->path = NULL;
608 }
609 }
610 *str = cur;
611 return (0);
612}
static int xmlParse3986Segment(const char **str, char forbid, int empty)
Definition: uri.c:558

Referenced by xmlParse3986HierPart(), and xmlParse3986RelativeRef().

◆ xmlParse3986PathAbsolute()

static int xmlParse3986PathAbsolute ( xmlURIPtr  uri,
const char **  str 
)
static

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

Parse an path absolute and fills in the appropriate fields of the @uri structure

path-absolute = "/" [ segment-nz *( "/" segment ) ]

Returns 0 or the error code

Definition at line 627 of file uri.c.

628{
629 const char *cur;
630 int ret;
631
632 cur = *str;
633
634 if (*cur != '/')
635 return(1);
636 cur++;
637 ret = xmlParse3986Segment(&cur, 0, 0);
638 if (ret == 0) {
639 while (*cur == '/') {
640 cur++;
641 ret = xmlParse3986Segment(&cur, 0, 1);
642 if (ret != 0) return(ret);
643 }
644 }
645 if (uri != NULL) {
646 if (uri->path != NULL) xmlFree(uri->path);
647 if (cur != *str) {
648 if (uri->cleanup & 2)
649 uri->path = STRNDUP(*str, cur - *str);
650 else
651 uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
652 } else {
653 uri->path = NULL;
654 }
655 }
656 *str = cur;
657 return (0);
658}

Referenced by xmlParse3986HierPart(), and xmlParse3986RelativeRef().

◆ xmlParse3986PathNoScheme()

static int xmlParse3986PathNoScheme ( xmlURIPtr  uri,
const char **  str 
)
static

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

Parse an path which is not a scheme and fills in the appropriate fields of the @uri structure

path-noscheme = segment-nz-nc *( "/" segment )

Returns 0 or the error code

Definition at line 715 of file uri.c.

716{
717 const char *cur;
718 int ret;
719
720 cur = *str;
721
722 ret = xmlParse3986Segment(&cur, ':', 0);
723 if (ret != 0) return(ret);
724 while (*cur == '/') {
725 cur++;
726 ret = xmlParse3986Segment(&cur, 0, 1);
727 if (ret != 0) return(ret);
728 }
729 if (uri != NULL) {
730 if (uri->path != NULL) xmlFree(uri->path);
731 if (cur != *str) {
732 if (uri->cleanup & 2)
733 uri->path = STRNDUP(*str, cur - *str);
734 else
735 uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
736 } else {
737 uri->path = NULL;
738 }
739 }
740 *str = cur;
741 return (0);
742}

Referenced by xmlParse3986RelativeRef().

◆ xmlParse3986PathRootless()

static int xmlParse3986PathRootless ( xmlURIPtr  uri,
const char **  str 
)
static

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

Parse an path without root and fills in the appropriate fields of the @uri structure

path-rootless = segment-nz *( "/" segment )

Returns 0 or the error code

Definition at line 673 of file uri.c.

674{
675 const char *cur;
676 int ret;
677
678 cur = *str;
679
680 ret = xmlParse3986Segment(&cur, 0, 0);
681 if (ret != 0) return(ret);
682 while (*cur == '/') {
683 cur++;
684 ret = xmlParse3986Segment(&cur, 0, 1);
685 if (ret != 0) return(ret);
686 }
687 if (uri != NULL) {
688 if (uri->path != NULL) xmlFree(uri->path);
689 if (cur != *str) {
690 if (uri->cleanup & 2)
691 uri->path = STRNDUP(*str, cur - *str);
692 else
693 uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
694 } else {
695 uri->path = NULL;
696 }
697 }
698 *str = cur;
699 return (0);
700}

Referenced by xmlParse3986HierPart().

◆ xmlParse3986Port()

static int xmlParse3986Port ( xmlURIPtr  uri,
const char **  str 
)
static

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

Parse a port part and fills in the appropriate fields of the @uri structure

port = *DIGIT

Returns 0 or the error code

Definition at line 326 of file uri.c.

327{
328 const char *cur = *str;
329 int port = 0;
330
331 if (ISA_DIGIT(cur)) {
332 while (ISA_DIGIT(cur)) {
333 int digit = *cur - '0';
334
335 if (port > INT_MAX / 10)
336 return(1);
337 port *= 10;
338 if (port > INT_MAX - digit)
339 return(1);
340 port += digit;
341
342 cur++;
343 }
344 if (uri != NULL)
345 uri->port = port;
346 *str = cur;
347 return(0);
348 }
349 return(1);
350}
USHORT port
Definition: uri.c:228
#define INT_MAX
Definition: limits.h:40

Referenced by xmlParse3986Authority().

◆ xmlParse3986Query()

static int xmlParse3986Query ( xmlURIPtr  uri,
const char **  str 
)
static

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

Parse the query part of an URI

query = *uric

Returns 0 or the error code

Definition at line 282 of file uri.c.

283{
284 const char *cur;
285
286 if (str == NULL)
287 return (-1);
288
289 cur = *str;
290
291 while ((ISA_PCHAR(cur)) || (*cur == '/') || (*cur == '?') ||
292 ((uri != NULL) && (uri->cleanup & 1) && (IS_UNWISE(cur))))
293 NEXT(cur);
294 if (uri != NULL) {
295 if (uri->query != NULL)
296 xmlFree(uri->query);
297 if (uri->cleanup & 2)
298 uri->query = STRNDUP(*str, cur - *str);
299 else
300 uri->query = xmlURIUnescapeString(*str, cur - *str, NULL);
301
302 /* Save the raw bytes of the query as well.
303 * See: http://mail.gnome.org/archives/xml/2007-April/thread.html#00114
304 */
305 if (uri->query_raw != NULL)
306 xmlFree (uri->query_raw);
307 uri->query_raw = STRNDUP (*str, cur - *str);
308 }
309 *str = cur;
310 return (0);
311}

Referenced by xmlParse3986RelativeRef(), and xmlParse3986URI().

◆ xmlParse3986RelativeRef()

static int xmlParse3986RelativeRef ( xmlURIPtr  uri,
const char str 
)
static

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

Parse an URI string and fills in the appropriate fields of the @uri structure

relative-ref = relative-part [ "?" query ] [ "#" fragment ] relative-part = "//" authority path-abempty / path-absolute / path-noscheme / path-empty

Returns 0 or the error code

Definition at line 811 of file uri.c.

811 {
812 int ret;
813
814 if ((*str == '/') && (*(str + 1) == '/')) {
815 str += 2;
817 if (ret != 0) return(ret);
819 if (ret != 0) return(ret);
820 } else if (*str == '/') {
822 if (ret != 0) return(ret);
823 } else if (ISA_PCHAR(str)) {
825 if (ret != 0) return(ret);
826 } else {
827 /* path-empty is effectively empty */
828 if (uri != NULL) {
829 if (uri->path != NULL) xmlFree(uri->path);
830 uri->path = NULL;
831 }
832 }
833
834 if (*str == '?') {
835 str++;
837 if (ret != 0) return(ret);
838 }
839 if (*str == '#') {
840 str++;
842 if (ret != 0) return(ret);
843 }
844 if (*str != 0) {
846 return(1);
847 }
848 return(0);
849}
static int xmlParse3986Query(xmlURIPtr uri, const char **str)
Definition: uri.c:282
static int xmlParse3986PathNoScheme(xmlURIPtr uri, const char **str)
Definition: uri.c:715
static void xmlCleanURI(xmlURIPtr uri)
Definition: uri.c:1357
static int xmlParse3986Fragment(xmlURIPtr uri, const char **str)
Definition: uri.c:245

Referenced by xmlParse3986URIReference().

◆ xmlParse3986Scheme()

static int xmlParse3986Scheme ( xmlURIPtr  uri,
const char **  str 
)
static

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

Parse an URI scheme

ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )

Returns 0 or the error code

Definition at line 209 of file uri.c.

209 {
210 const char *cur;
211
212 if (str == NULL)
213 return(-1);
214
215 cur = *str;
216 if (!ISA_ALPHA(cur))
217 return(2);
218 cur++;
219 while (ISA_ALPHA(cur) || ISA_DIGIT(cur) ||
220 (*cur == '+') || (*cur == '-') || (*cur == '.')) cur++;
221 if (uri != NULL) {
222 if (uri->scheme != NULL) xmlFree(uri->scheme);
223 uri->scheme = STRNDUP(*str, cur - *str);
224 }
225 *str = cur;
226 return(0);
227}

Referenced by xmlParse3986URI().

◆ xmlParse3986Segment()

static int xmlParse3986Segment ( const char **  str,
char  forbid,
int  empty 
)
static

xmlParse3986Segment: @str: the string to analyze @forbid: an optional forbidden character @empty: allow an empty segment

Parse a segment and fills in the appropriate fields of the @uri structure

segment = pchar segment-nz = 1*pchar segment-nz-nc = 1( unreserved / pct-encoded / sub-delims / "@" ) ; non-zero-length segment without any colon ":"

Returns 0 or the error code

Definition at line 558 of file uri.c.

559{
560 const char *cur;
561
562 cur = *str;
563 if (!ISA_PCHAR(cur)) {
564 if (empty)
565 return(0);
566 return(1);
567 }
568 while (ISA_PCHAR(cur) && (*cur != forbid))
569 NEXT(cur);
570 *str = cur;
571 return (0);
572}
static const WCHAR empty[]
Definition: main.c:47

Referenced by xmlParse3986PathAbEmpty(), xmlParse3986PathAbsolute(), xmlParse3986PathNoScheme(), and xmlParse3986PathRootless().

◆ xmlParse3986URI()

static int xmlParse3986URI ( xmlURIPtr  uri,
const char str 
)
static

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

Parse an URI string and fills in the appropriate fields of the @uri structure

scheme ":" hier-part [ "?" query ] [ "#" fragment ]

Returns 0 or the error code

Definition at line 865 of file uri.c.

865 {
866 int ret;
867
869 if (ret != 0) return(ret);
870 if (*str != ':') {
871 return(1);
872 }
873 str++;
875 if (ret != 0) return(ret);
876 if (*str == '?') {
877 str++;
879 if (ret != 0) return(ret);
880 }
881 if (*str == '#') {
882 str++;
884 if (ret != 0) return(ret);
885 }
886 if (*str != 0) {
888 return(1);
889 }
890 return(0);
891}
static int xmlParse3986HierPart(xmlURIPtr uri, const char **str)
Definition: uri.c:760
static int xmlParse3986Scheme(xmlURIPtr uri, const char **str)
Definition: uri.c:209

Referenced by xmlParse3986URIReference().

◆ xmlParse3986URIReference()

static int xmlParse3986URIReference ( xmlURIPtr  uri,
const char str 
)
static

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

Parse an URI reference string and fills in the appropriate fields of the @uri structure

URI-reference = URI / relative-ref

Returns 0 or the error code

Definition at line 906 of file uri.c.

906 {
907 int ret;
908
909 if (str == NULL)
910 return(-1);
912
913 /*
914 * Try first to parse absolute refs, then fallback to relative if
915 * it fails.
916 */
918 if (ret != 0) {
921 if (ret != 0) {
923 return(ret);
924 }
925 }
926 return(0);
927}
static int xmlParse3986URI(xmlURIPtr uri, const char *str)
Definition: uri.c:865
static int xmlParse3986RelativeRef(xmlURIPtr uri, const char *str)
Definition: uri.c:811

Referenced by xmlParseURI(), and xmlParseURIReference().

◆ xmlParse3986Userinfo()

static int xmlParse3986Userinfo ( xmlURIPtr  uri,
const char **  str 
)
static

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

Parse an user information part and fills in the appropriate fields of the @uri structure

userinfo = *( unreserved / pct-encoded / sub-delims / ":" )

Returns 0 or the error code

Definition at line 365 of file uri.c.

366{
367 const char *cur;
368
369 cur = *str;
371 ISA_SUB_DELIM(cur) || (*cur == ':'))
372 NEXT(cur);
373 if (*cur == '@') {
374 if (uri != NULL) {
375 if (uri->user != NULL) xmlFree(uri->user);
376 if (uri->cleanup & 2)
377 uri->user = STRNDUP(*str, cur - *str);
378 else
379 uri->user = xmlURIUnescapeString(*str, cur - *str, NULL);
380 }
381 *str = cur;
382 return(0);
383 }
384 return(1);
385}

Referenced by xmlParse3986Authority().

◆ xmlParseURI()

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 940 of file uri.c.

940 {
942 int ret;
943
944 if (str == NULL)
945 return(NULL);
946 uri = xmlCreateURI();
947 if (uri != NULL) {
949 if (ret) {
951 return(NULL);
952 }
953 }
954 return(uri);
955}
static int xmlParse3986URIReference(xmlURIPtr uri, const char *str)
Definition: uri.c:906

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

◆ xmlParseURIRaw()

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 986 of file uri.c.

986 {
988 int ret;
989
990 if (str == NULL)
991 return(NULL);
992 uri = xmlCreateURI();
993 if (uri != NULL) {
994 if (raw) {
995 uri->cleanup |= 2;
996 }
998 if (ret) {
1000 return(NULL);
1001 }
1002 }
1003 return(uri);
1004}

◆ xmlParseURIReference()

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 970 of file uri.c.

970 {
972}

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

◆ xmlPathToURI()

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 2521 of file uri.c.

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

Referenced by xmlSAX2StartDocument().

◆ xmlPrintURI()

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 1340 of file uri.c.

1340 {
1341 xmlChar *out;
1342
1343 out = xmlSaveUri(uri);
1344 if (out != NULL) {
1345 fprintf(stream, "%s", (char *) out);
1346 xmlFree(out);
1347 }
1348}
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
Definition: parse.h:23

◆ xmlSaveUri()

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 1066 of file uri.c.

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

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

◆ xmlSaveUriRealloc()

static xmlChar * xmlSaveUriRealloc ( xmlChar ret,
int max 
)
static

xmlSaveUriRealloc:

Function to handle properly a reallocation when saving an URI Also imposes some limit on the length of an URI string output

Definition at line 1039 of file uri.c.

1039 {
1040 xmlChar *temp;
1041 int tmp;
1042
1043 if (*max > MAX_URI_LENGTH) {
1044 xmlURIErrMemory("reaching arbitrary MAX_URI_LENGTH limit\n");
1045 return(NULL);
1046 }
1047 tmp = *max * 2;
1048 temp = (xmlChar *) xmlRealloc(ret, (tmp + 1));
1049 if (temp == NULL) {
1050 xmlURIErrMemory("saving URI\n");
1051 return(NULL);
1052 }
1053 *max = tmp;
1054 return(temp);
1055}
XMLPUBVAR xmlReallocFunc xmlRealloc
Definition: globals.h:250
#define MAX_URI_LENGTH
Definition: uri.c:34

Referenced by xmlSaveUri(), and xmlURIEscapeStr().

◆ xmlURIErrMemory()

static void xmlURIErrMemory ( const char extra)
static

Definition at line 37 of file uri.c.

38{
39 if (extra)
40 __xmlRaiseError(NULL, NULL, NULL,
43 extra, NULL, NULL, 0, 0,
44 "Memory allocation failed : %s\n", extra);
45 else
46 __xmlRaiseError(NULL, NULL, NULL,
49 NULL, NULL, NULL, 0, 0,
50 "Memory allocation failed\n");
51}
@ extra
Definition: id3.c:95
@ XML_ERR_FATAL
Definition: xmlerror.h:28
@ XML_FROM_URI
Definition: xmlerror.h:67
@ XML_ERR_NO_MEMORY
Definition: xmlerror.h:102

Referenced by xmlBuildURI(), xmlCreateURI(), xmlSaveUri(), xmlSaveUriRealloc(), xmlURIEscapeStr(), and xmlURIUnescapeString().

◆ xmlURIEscape()

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 1752 of file uri.c.

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

◆ xmlURIEscapeStr()

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) and the characters in the exception list.

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

Definition at line 1679 of file uri.c.

1679 {
1680 xmlChar *ret, ch;
1681 xmlChar *temp;
1682 const xmlChar *in;
1683 int len, out;
1684
1685 if (str == NULL)
1686 return(NULL);
1687 if (str[0] == 0)
1688 return(xmlStrdup(str));
1689 len = xmlStrlen(str);
1690 if (!(len > 0)) return(NULL);
1691
1692 len += 20;
1694 if (ret == NULL) {
1695 xmlURIErrMemory("escaping URI value\n");
1696 return(NULL);
1697 }
1698 in = (const xmlChar *) str;
1699 out = 0;
1700 while(*in != 0) {
1701 if (len - out <= 3) {
1703 if (temp == NULL) {
1704 xmlURIErrMemory("escaping URI value\n");
1705 xmlFree(ret);
1706 return(NULL);
1707 }
1708 ret = temp;
1709 }
1710
1711 ch = *in;
1712
1713 if ((ch != '@') && (!IS_UNRESERVED(ch)) && (!xmlStrchr(list, ch))) {
1714 unsigned char val;
1715 ret[out++] = '%';
1716 val = ch >> 4;
1717 if (val <= 9)
1718 ret[out++] = '0' + val;
1719 else
1720 ret[out++] = 'A' + val - 0xA;
1721 val = ch & 0xF;
1722 if (val <= 9)
1723 ret[out++] = '0' + val;
1724 else
1725 ret[out++] = 'A' + val - 0xA;
1726 in++;
1727 } else {
1728 ret[out++] = *in++;
1729 }
1730
1731 }
1732 ret[out] = 0;
1733 return(ret);
1734}
Definition: list.h:37
GLuint in
Definition: glext.h:9616
XMLPUBFUN const xmlChar *XMLCALL xmlStrchr(const xmlChar *str, xmlChar val)
Definition: xmlstring.c:325

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

◆ xmlURIUnescapeString()

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 1620 of file uri.c.

1620 {
1621 char *ret, *out;
1622 const char *in;
1623
1624 if (str == NULL)
1625 return(NULL);
1626 if (len <= 0) len = strlen(str);
1627 if (len < 0) return(NULL);
1628
1629 if (target == NULL) {
1630 ret = (char *) xmlMallocAtomic(len + 1);
1631 if (ret == NULL) {
1632 xmlURIErrMemory("unescaping URI value\n");
1633 return(NULL);
1634 }
1635 } else
1636 ret = target;
1637 in = str;
1638 out = ret;
1639 while(len > 0) {
1640 if ((len > 2) && (*in == '%') && (is_hex(in[1])) && (is_hex(in[2]))) {
1641 int c = 0;
1642 in++;
1643 if ((*in >= '0') && (*in <= '9'))
1644 c = (*in - '0');
1645 else if ((*in >= 'a') && (*in <= 'f'))
1646 c = (*in - 'a') + 10;
1647 else if ((*in >= 'A') && (*in <= 'F'))
1648 c = (*in - 'A') + 10;
1649 in++;
1650 if ((*in >= '0') && (*in <= '9'))
1651 c = c * 16 + (*in - '0');
1652 else if ((*in >= 'a') && (*in <= 'f'))
1653 c = c * 16 + (*in - 'a') + 10;
1654 else if ((*in >= 'A') && (*in <= 'F'))
1655 c = c * 16 + (*in - 'A') + 10;
1656 in++;
1657 len -= 3;
1658 *out++ = (char) c;
1659 } else {
1660 *out++ = *in++;
1661 len--;
1662 }
1663 }
1664 *out = 0;
1665 return(ret);
1666}
unsigned char
Definition: typeof.h:29
#define is_hex(c)
Definition: registry.c:430
GLenum target
Definition: glext.h:7315

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