13473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 257560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * uri.c: set of generic URI related routines 33473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 4d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Reference: RFCs 3986, 2732 and 2373 53473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 63473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * See Copyright for the status of this software. 73473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 8c5d64345cf19bfd72418eb0a837869b0462e9130Daniel Veillard * daniel@veillard.com 93473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1134ce8bece2f22cc99d25221b77315cd008f4866bDaniel Veillard#define IN_LIBXML 1270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese#include "libxml.h" 1370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese 143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <string.h> 153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/xmlmemory.h> 173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/uri.h> 18d0463560300f1d8b3e41d70c3728ed84fdc8dd30Daniel Veillard#include <libxml/globals.h> 193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/xmlerror.h> 203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2157560386503be0fd023f3b7537fd496784f3be18Daniel Veillard/** 2257560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * MAX_URI_LENGTH: 2357560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * 2457560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * The definition of the URI regexp in the above RFC has no size limit 2557560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * In practice they are usually relativey short except for the 2657560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * data URI scheme as defined in RFC 2397. Even for data URI the usual 2757560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * maximum size before hitting random practical limits is around 64 KB 2857560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * and 4KB is usually a maximum admitted limit for proper operations. 2957560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * The value below is more a security limit than anything else and 3057560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * really should never be hit by 'normal' operations 3157560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * Set to 1 MByte in 2012, this is only enforced on output 3257560386503be0fd023f3b7537fd496784f3be18Daniel Veillard */ 3357560386503be0fd023f3b7537fd496784f3be18Daniel Veillard#define MAX_URI_LENGTH 1024 * 1024 3457560386503be0fd023f3b7537fd496784f3be18Daniel Veillard 3557560386503be0fd023f3b7537fd496784f3be18Daniel Veillardstatic void 3657560386503be0fd023f3b7537fd496784f3be18Daniel VeillardxmlURIErrMemory(const char *extra) 3757560386503be0fd023f3b7537fd496784f3be18Daniel Veillard{ 3857560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (extra) 3957560386503be0fd023f3b7537fd496784f3be18Daniel Veillard __xmlRaiseError(NULL, NULL, NULL, 4057560386503be0fd023f3b7537fd496784f3be18Daniel Veillard NULL, NULL, XML_FROM_URI, 4157560386503be0fd023f3b7537fd496784f3be18Daniel Veillard XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, 4257560386503be0fd023f3b7537fd496784f3be18Daniel Veillard extra, NULL, NULL, 0, 0, 4357560386503be0fd023f3b7537fd496784f3be18Daniel Veillard "Memory allocation failed : %s\n", extra); 4457560386503be0fd023f3b7537fd496784f3be18Daniel Veillard else 4557560386503be0fd023f3b7537fd496784f3be18Daniel Veillard __xmlRaiseError(NULL, NULL, NULL, 4657560386503be0fd023f3b7537fd496784f3be18Daniel Veillard NULL, NULL, XML_FROM_URI, 4757560386503be0fd023f3b7537fd496784f3be18Daniel Veillard XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, 4857560386503be0fd023f3b7537fd496784f3be18Daniel Veillard NULL, NULL, NULL, 0, 0, 4957560386503be0fd023f3b7537fd496784f3be18Daniel Veillard "Memory allocation failed\n"); 5057560386503be0fd023f3b7537fd496784f3be18Daniel Veillard} 5157560386503be0fd023f3b7537fd496784f3be18Daniel Veillard 52d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic void xmlCleanURI(xmlURIPtr uri); 533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 55d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Old rule from 2396 used in legacy handling code 563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * alpha = lowalpha | upalpha 573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define IS_ALPHA(x) (IS_LOWALPHA(x) || IS_UPALPHA(x)) 593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | 633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | 643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * "u" | "v" | "w" | "x" | "y" | "z" 653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define IS_LOWALPHA(x) (((x) >= 'a') && ((x) <= 'z')) 683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * upalpha = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | 713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | 723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * "U" | "V" | "W" | "X" | "Y" | "Z" 733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define IS_UPALPHA(x) (((x) >= 'A') && ((x) <= 'Z')) 753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 76be3eb2088e3e27b897b57855382f80a737f974ceDaniel Veillard#ifdef IS_DIGIT 77be3eb2088e3e27b897b57855382f80a737f974ceDaniel Veillard#undef IS_DIGIT 78be3eb2088e3e27b897b57855382f80a737f974ceDaniel Veillard#endif 793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" 813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define IS_DIGIT(x) (((x) >= '0') && ((x) <= '9')) 833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * alphanum = alpha | digit 863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define IS_ALPHANUM(x) (IS_ALPHA(x) || IS_DIGIT(x)) 893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" 923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 94d7af555327843a9938a913205ac703c13c225603Daniel Veillard#define IS_MARK(x) (((x) == '-') || ((x) == '_') || ((x) == '.') || \ 95d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((x) == '!') || ((x) == '~') || ((x) == '*') || ((x) == '\'') || \ 963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((x) == '(') || ((x) == ')')) 973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 98d7af555327843a9938a913205ac703c13c225603Daniel Veillard/* 99d7af555327843a9938a913205ac703c13c225603Daniel Veillard * unwise = "{" | "}" | "|" | "\" | "^" | "`" 100d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 1013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 102d7af555327843a9938a913205ac703c13c225603Daniel Veillard#define IS_UNWISE(p) \ 103d7af555327843a9938a913205ac703c13c225603Daniel Veillard (((*(p) == '{')) || ((*(p) == '}')) || ((*(p) == '|')) || \ 104d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == '\\')) || ((*(p) == '^')) || ((*(p) == '[')) || \ 105d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == ']')) || ((*(p) == '`'))) 1063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 107015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack * reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | "," | 108d7af555327843a9938a913205ac703c13c225603Daniel Veillard * "[" | "]" 1093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 111d7af555327843a9938a913205ac703c13c225603Daniel Veillard#define IS_RESERVED(x) (((x) == ';') || ((x) == '/') || ((x) == '?') || \ 112d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((x) == ':') || ((x) == '@') || ((x) == '&') || ((x) == '=') || \ 113d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((x) == '+') || ((x) == '$') || ((x) == ',') || ((x) == '[') || \ 114d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((x) == ']')) 1153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 1173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * unreserved = alphanum | mark 1183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define IS_UNRESERVED(x) (IS_ALPHANUM(x) || IS_MARK(x)) 1213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 123d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Skip to next pointer char, handle escaped sequences 1243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 126d7af555327843a9938a913205ac703c13c225603Daniel Veillard#define NEXT(p) ((*p == '%')? p += 3 : p++) 1273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 129d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Productions from the spec. 130d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 131d7af555327843a9938a913205ac703c13c225603Daniel Veillard * authority = server | reg_name 132d7af555327843a9938a913205ac703c13c225603Daniel Veillard * reg_name = 1*( unreserved | escaped | "$" | "," | 133d7af555327843a9938a913205ac703c13c225603Daniel Veillard * ";" | ":" | "@" | "&" | "=" | "+" ) 134d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 135d7af555327843a9938a913205ac703c13c225603Daniel Veillard * path = [ abs_path | opaque_part ] 1363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 137d7af555327843a9938a913205ac703c13c225603Daniel Veillard 138d7af555327843a9938a913205ac703c13c225603Daniel Veillard#define STRNDUP(s, n) (char *) xmlStrndup((const xmlChar *)(s), (n)) 139d7af555327843a9938a913205ac703c13c225603Daniel Veillard 140d7af555327843a9938a913205ac703c13c225603Daniel Veillard/************************************************************************ 141d7af555327843a9938a913205ac703c13c225603Daniel Veillard * * 142d7af555327843a9938a913205ac703c13c225603Daniel Veillard * RFC 3986 parser * 143d7af555327843a9938a913205ac703c13c225603Daniel Veillard * * 144d7af555327843a9938a913205ac703c13c225603Daniel Veillard ************************************************************************/ 145d7af555327843a9938a913205ac703c13c225603Daniel Veillard 146d7af555327843a9938a913205ac703c13c225603Daniel Veillard#define ISA_DIGIT(p) ((*(p) >= '0') && (*(p) <= '9')) 147d7af555327843a9938a913205ac703c13c225603Daniel Veillard#define ISA_ALPHA(p) (((*(p) >= 'a') && (*(p) <= 'z')) || \ 148d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) >= 'A') && (*(p) <= 'Z'))) 149d7af555327843a9938a913205ac703c13c225603Daniel Veillard#define ISA_HEXDIG(p) \ 150d7af555327843a9938a913205ac703c13c225603Daniel Veillard (ISA_DIGIT(p) || ((*(p) >= 'a') && (*(p) <= 'f')) || \ 151d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) >= 'A') && (*(p) <= 'F'))) 1523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 154d7af555327843a9938a913205ac703c13c225603Daniel Veillard * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" 155d7af555327843a9938a913205ac703c13c225603Daniel Veillard * / "*" / "+" / "," / ";" / "=" 1563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 157d7af555327843a9938a913205ac703c13c225603Daniel Veillard#define ISA_SUB_DELIM(p) \ 158d7af555327843a9938a913205ac703c13c225603Daniel Veillard (((*(p) == '!')) || ((*(p) == '$')) || ((*(p) == '&')) || \ 159d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == '(')) || ((*(p) == ')')) || ((*(p) == '*')) || \ 160d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == '+')) || ((*(p) == ',')) || ((*(p) == ';')) || \ 1612ee91eb6587191de876dbcf147d99bc9b8c7799dDaniel Veillard ((*(p) == '=')) || ((*(p) == '\''))) 1623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 164d7af555327843a9938a913205ac703c13c225603Daniel Veillard * gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" 1653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 166d7af555327843a9938a913205ac703c13c225603Daniel Veillard#define ISA_GEN_DELIM(p) \ 167d7af555327843a9938a913205ac703c13c225603Daniel Veillard (((*(p) == ':')) || ((*(p) == '/')) || ((*(p) == '?')) || \ 168d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == '#')) || ((*(p) == '[')) || ((*(p) == ']')) || \ 169d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == '@'))) 1703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 172d7af555327843a9938a913205ac703c13c225603Daniel Veillard * reserved = gen-delims / sub-delims 1733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 174d7af555327843a9938a913205ac703c13c225603Daniel Veillard#define ISA_RESERVED(p) (ISA_GEN_DELIM(p) || (ISA_SUB_DELIM(p))) 1753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 177d7af555327843a9938a913205ac703c13c225603Daniel Veillard * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" 1783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 179d7af555327843a9938a913205ac703c13c225603Daniel Veillard#define ISA_UNRESERVED(p) \ 180d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((ISA_ALPHA(p)) || (ISA_DIGIT(p)) || ((*(p) == '-')) || \ 181d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == '.')) || ((*(p) == '_')) || ((*(p) == '~'))) 1823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 184d7af555327843a9938a913205ac703c13c225603Daniel Veillard * pct-encoded = "%" HEXDIG HEXDIG 1853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 186d7af555327843a9938a913205ac703c13c225603Daniel Veillard#define ISA_PCT_ENCODED(p) \ 187d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == '%') && (ISA_HEXDIG(p + 1)) && (ISA_HEXDIG(p + 2))) 1883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 190d7af555327843a9938a913205ac703c13c225603Daniel Veillard * pchar = unreserved / pct-encoded / sub-delims / ":" / "@" 1913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 192d7af555327843a9938a913205ac703c13c225603Daniel Veillard#define ISA_PCHAR(p) \ 193d7af555327843a9938a913205ac703c13c225603Daniel Veillard (ISA_UNRESERVED(p) || ISA_PCT_ENCODED(p) || ISA_SUB_DELIM(p) || \ 194d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == ':')) || ((*(p) == '@'))) 1953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 196d7af555327843a9938a913205ac703c13c225603Daniel Veillard/** 197d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986Scheme: 198d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an URI structure 199d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: pointer to the string to analyze 200d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 201d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse an URI scheme 202d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 203d7af555327843a9938a913205ac703c13c225603Daniel Veillard * ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) 204d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 205d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 206d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 207d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 208d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986Scheme(xmlURIPtr uri, const char **str) { 209d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *cur; 2103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 211d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (str == NULL) 212d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(-1); 213bb6808ea16b16055727ceb73d45a7f748b14ccfdDaniel Veillard 214d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = *str; 215d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (!ISA_ALPHA(cur)) 216d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(2); 217d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur++; 218d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (ISA_ALPHA(cur) || ISA_DIGIT(cur) || 219d7af555327843a9938a913205ac703c13c225603Daniel Veillard (*cur == '+') || (*cur == '-') || (*cur == '.')) cur++; 220d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri != NULL) { 221d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->scheme != NULL) xmlFree(uri->scheme); 222d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->scheme = STRNDUP(*str, cur - *str); 223d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 224d7af555327843a9938a913205ac703c13c225603Daniel Veillard *str = cur; 225d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(0); 226d7af555327843a9938a913205ac703c13c225603Daniel Veillard} 227bb6808ea16b16055727ceb73d45a7f748b14ccfdDaniel Veillard 228d7af555327843a9938a913205ac703c13c225603Daniel Veillard/** 229d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986Fragment: 230d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an URI structure 231d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: pointer to the string to analyze 232d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 233d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse the query part of an URI 234d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 23584c45df8d88f2b44f9c16474795fa2d30265bc21Daniel Veillard * fragment = *( pchar / "/" / "?" ) 23684c45df8d88f2b44f9c16474795fa2d30265bc21Daniel Veillard * NOTE: the strict syntax as defined by 3986 does not allow '[' and ']' 23784c45df8d88f2b44f9c16474795fa2d30265bc21Daniel Veillard * in the fragment identifier but this is used very broadly for 23884c45df8d88f2b44f9c16474795fa2d30265bc21Daniel Veillard * xpointer scheme selection, so we are allowing it here to not break 23984c45df8d88f2b44f9c16474795fa2d30265bc21Daniel Veillard * for example all the DocBook processing chains. 240d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 241d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 2423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 243d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 244d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986Fragment(xmlURIPtr uri, const char **str) 245d7af555327843a9938a913205ac703c13c225603Daniel Veillard{ 246d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *cur; 2473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 248d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (str == NULL) 249d7af555327843a9938a913205ac703c13c225603Daniel Veillard return (-1); 2503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 251d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = *str; 252d7af555327843a9938a913205ac703c13c225603Daniel Veillard 253d7af555327843a9938a913205ac703c13c225603Daniel Veillard while ((ISA_PCHAR(cur)) || (*cur == '/') || (*cur == '?') || 25484c45df8d88f2b44f9c16474795fa2d30265bc21Daniel Veillard (*cur == '[') || (*cur == ']') || 255d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((uri != NULL) && (uri->cleanup & 1) && (IS_UNWISE(cur)))) 256d7af555327843a9938a913205ac703c13c225603Daniel Veillard NEXT(cur); 257d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri != NULL) { 258d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->fragment != NULL) 259d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFree(uri->fragment); 260d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->cleanup & 2) 261d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->fragment = STRNDUP(*str, cur - *str); 262d7af555327843a9938a913205ac703c13c225603Daniel Veillard else 263d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->fragment = xmlURIUnescapeString(*str, cur - *str, NULL); 264d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 265d7af555327843a9938a913205ac703c13c225603Daniel Veillard *str = cur; 266d7af555327843a9938a913205ac703c13c225603Daniel Veillard return (0); 267d7af555327843a9938a913205ac703c13c225603Daniel Veillard} 268d7af555327843a9938a913205ac703c13c225603Daniel Veillard 269d7af555327843a9938a913205ac703c13c225603Daniel Veillard/** 270d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986Query: 271d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an URI structure 272d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: pointer to the string to analyze 2733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 274d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse the query part of an URI 2753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 276d7af555327843a9938a913205ac703c13c225603Daniel Veillard * query = *uric 277d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 278d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 2793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 280d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 281d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986Query(xmlURIPtr uri, const char **str) 282d7af555327843a9938a913205ac703c13c225603Daniel Veillard{ 283d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *cur; 2843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 285d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (str == NULL) 286d7af555327843a9938a913205ac703c13c225603Daniel Veillard return (-1); 287336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard 288d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = *str; 289d7af555327843a9938a913205ac703c13c225603Daniel Veillard 290d7af555327843a9938a913205ac703c13c225603Daniel Veillard while ((ISA_PCHAR(cur)) || (*cur == '/') || (*cur == '?') || 291d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((uri != NULL) && (uri->cleanup & 1) && (IS_UNWISE(cur)))) 292d7af555327843a9938a913205ac703c13c225603Daniel Veillard NEXT(cur); 293d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri != NULL) { 294d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->query != NULL) 295d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFree(uri->query); 296d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->cleanup & 2) 297d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->query = STRNDUP(*str, cur - *str); 298d7af555327843a9938a913205ac703c13c225603Daniel Veillard else 299d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->query = xmlURIUnescapeString(*str, cur - *str, NULL); 300d7af555327843a9938a913205ac703c13c225603Daniel Veillard 301d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* Save the raw bytes of the query as well. 302d7af555327843a9938a913205ac703c13c225603Daniel Veillard * See: http://mail.gnome.org/archives/xml/2007-April/thread.html#00114 303d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 304d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->query_raw != NULL) 305d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFree (uri->query_raw); 306d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->query_raw = STRNDUP (*str, cur - *str); 307d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 308d7af555327843a9938a913205ac703c13c225603Daniel Veillard *str = cur; 309d7af555327843a9938a913205ac703c13c225603Daniel Veillard return (0); 310d7af555327843a9938a913205ac703c13c225603Daniel Veillard} 3113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 3123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 313d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986Port: 314d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an URI structure 315d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string to analyze 3163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 317d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse a port part and fills in the appropriate fields 318d7af555327843a9938a913205ac703c13c225603Daniel Veillard * of the @uri structure 3193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 320d7af555327843a9938a913205ac703c13c225603Daniel Veillard * port = *DIGIT 321d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 322d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 3233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 324d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 325d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986Port(xmlURIPtr uri, const char **str) 326d7af555327843a9938a913205ac703c13c225603Daniel Veillard{ 327d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *cur = *str; 3283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 329d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ISA_DIGIT(cur)) { 330d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri != NULL) 331d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->port = 0; 332d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (ISA_DIGIT(cur)) { 333d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri != NULL) 334d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->port = uri->port * 10 + (*cur - '0'); 335d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur++; 336d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 337d7af555327843a9938a913205ac703c13c225603Daniel Veillard *str = cur; 338d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(0); 3393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 340d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(1); 3413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 3423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 3433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 344d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986Userinfo: 345d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an URI structure 346d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string to analyze 3473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 348d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse an user informations part and fills in the appropriate fields 349d7af555327843a9938a913205ac703c13c225603Daniel Veillard * of the @uri structure 3503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 351d7af555327843a9938a913205ac703c13c225603Daniel Veillard * userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) 352d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 353d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 3543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 355d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 356d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986Userinfo(xmlURIPtr uri, const char **str) 357d7af555327843a9938a913205ac703c13c225603Daniel Veillard{ 358d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *cur; 3593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 360d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = *str; 361d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (ISA_UNRESERVED(cur) || ISA_PCT_ENCODED(cur) || 362d7af555327843a9938a913205ac703c13c225603Daniel Veillard ISA_SUB_DELIM(cur) || (*cur == ':')) 363d7af555327843a9938a913205ac703c13c225603Daniel Veillard NEXT(cur); 364d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (*cur == '@') { 365d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri != NULL) { 366d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->user != NULL) xmlFree(uri->user); 367d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->cleanup & 2) 368d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->user = STRNDUP(*str, cur - *str); 369d7af555327843a9938a913205ac703c13c225603Daniel Veillard else 370d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->user = xmlURIUnescapeString(*str, cur - *str, NULL); 371d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 372d7af555327843a9938a913205ac703c13c225603Daniel Veillard *str = cur; 373d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(0); 374d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 375d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(1); 376d7af555327843a9938a913205ac703c13c225603Daniel Veillard} 3773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 378d7af555327843a9938a913205ac703c13c225603Daniel Veillard/** 379d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986DecOctet: 380d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string to analyze 381d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 382d7af555327843a9938a913205ac703c13c225603Daniel Veillard * dec-octet = DIGIT ; 0-9 383d7af555327843a9938a913205ac703c13c225603Daniel Veillard * / %x31-39 DIGIT ; 10-99 384d7af555327843a9938a913205ac703c13c225603Daniel Veillard * / "1" 2DIGIT ; 100-199 385d7af555327843a9938a913205ac703c13c225603Daniel Veillard * / "2" %x30-34 DIGIT ; 200-249 386d7af555327843a9938a913205ac703c13c225603Daniel Veillard * / "25" %x30-35 ; 250-255 387d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 388d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Skip a dec-octet. 389d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 390d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 if found and skipped, 1 otherwise 391d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 392d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 393d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986DecOctet(const char **str) { 394d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *cur = *str; 3953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 396d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (!(ISA_DIGIT(cur))) 397d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(1); 398d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (!ISA_DIGIT(cur+1)) 399d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur++; 400d7af555327843a9938a913205ac703c13c225603Daniel Veillard else if ((*cur != '0') && (ISA_DIGIT(cur + 1)) && (!ISA_DIGIT(cur+2))) 401d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur += 2; 402d7af555327843a9938a913205ac703c13c225603Daniel Veillard else if ((*cur == '1') && (ISA_DIGIT(cur + 1)) && (ISA_DIGIT(cur + 2))) 403d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur += 3; 404d7af555327843a9938a913205ac703c13c225603Daniel Veillard else if ((*cur == '2') && (*(cur + 1) >= '0') && 405d7af555327843a9938a913205ac703c13c225603Daniel Veillard (*(cur + 1) <= '4') && (ISA_DIGIT(cur + 2))) 406d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur += 3; 407d7af555327843a9938a913205ac703c13c225603Daniel Veillard else if ((*cur == '2') && (*(cur + 1) == '5') && 408d7af555327843a9938a913205ac703c13c225603Daniel Veillard (*(cur + 2) >= '0') && (*(cur + 1) <= '5')) 409d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur += 3; 410d7af555327843a9938a913205ac703c13c225603Daniel Veillard else 411d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(1); 412d7af555327843a9938a913205ac703c13c225603Daniel Veillard *str = cur; 413d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(0); 414d7af555327843a9938a913205ac703c13c225603Daniel Veillard} 415d7af555327843a9938a913205ac703c13c225603Daniel Veillard/** 416d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986Host: 417d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an URI structure 418d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string to analyze 419d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 420d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse an host part and fills in the appropriate fields 421d7af555327843a9938a913205ac703c13c225603Daniel Veillard * of the @uri structure 422d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 423d7af555327843a9938a913205ac703c13c225603Daniel Veillard * host = IP-literal / IPv4address / reg-name 424d7af555327843a9938a913205ac703c13c225603Daniel Veillard * IP-literal = "[" ( IPv6address / IPvFuture ) "]" 425d7af555327843a9938a913205ac703c13c225603Daniel Veillard * IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet 426d7af555327843a9938a913205ac703c13c225603Daniel Veillard * reg-name = *( unreserved / pct-encoded / sub-delims ) 427d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 428d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 429d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 430d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 431d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986Host(xmlURIPtr uri, const char **str) 432d7af555327843a9938a913205ac703c13c225603Daniel Veillard{ 433d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *cur = *str; 434d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *host; 4353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 436d7af555327843a9938a913205ac703c13c225603Daniel Veillard host = cur; 437d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* 438d7af555327843a9938a913205ac703c13c225603Daniel Veillard * IPv6 and future adressing scheme are enclosed between brackets 439d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 440d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (*cur == '[') { 441d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur++; 442d7af555327843a9938a913205ac703c13c225603Daniel Veillard while ((*cur != ']') && (*cur != 0)) 443d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur++; 444d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (*cur != ']') 445d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(1); 446d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur++; 447d7af555327843a9938a913205ac703c13c225603Daniel Veillard goto found; 4483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 449d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* 450d7af555327843a9938a913205ac703c13c225603Daniel Veillard * try to parse an IPv4 451d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 452d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ISA_DIGIT(cur)) { 453d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (xmlParse3986DecOctet(&cur) != 0) 454d7af555327843a9938a913205ac703c13c225603Daniel Veillard goto not_ipv4; 455d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (*cur != '.') 456d7af555327843a9938a913205ac703c13c225603Daniel Veillard goto not_ipv4; 457d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur++; 458d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (xmlParse3986DecOctet(&cur) != 0) 459d7af555327843a9938a913205ac703c13c225603Daniel Veillard goto not_ipv4; 460d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (*cur != '.') 461d7af555327843a9938a913205ac703c13c225603Daniel Veillard goto not_ipv4; 462d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (xmlParse3986DecOctet(&cur) != 0) 463d7af555327843a9938a913205ac703c13c225603Daniel Veillard goto not_ipv4; 464d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (*cur != '.') 465d7af555327843a9938a913205ac703c13c225603Daniel Veillard goto not_ipv4; 466d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (xmlParse3986DecOctet(&cur) != 0) 467d7af555327843a9938a913205ac703c13c225603Daniel Veillard goto not_ipv4; 468d7af555327843a9938a913205ac703c13c225603Daniel Veillard goto found; 469d7af555327843a9938a913205ac703c13c225603Daniel Veillardnot_ipv4: 470d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = *str; 471d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 472d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* 473d7af555327843a9938a913205ac703c13c225603Daniel Veillard * then this should be a hostname which can be empty 474d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 475d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (ISA_UNRESERVED(cur) || ISA_PCT_ENCODED(cur) || ISA_SUB_DELIM(cur)) 476d7af555327843a9938a913205ac703c13c225603Daniel Veillard NEXT(cur); 477d7af555327843a9938a913205ac703c13c225603Daniel Veillardfound: 478d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri != NULL) { 479d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->authority != NULL) xmlFree(uri->authority); 480d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->authority = NULL; 481d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->server != NULL) xmlFree(uri->server); 482d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (cur != host) { 483d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->cleanup & 2) 484d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->server = STRNDUP(host, cur - host); 485d7af555327843a9938a913205ac703c13c225603Daniel Veillard else 486d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->server = xmlURIUnescapeString(host, cur - host, NULL); 487d7af555327843a9938a913205ac703c13c225603Daniel Veillard } else 488d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->server = NULL; 489d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 490d7af555327843a9938a913205ac703c13c225603Daniel Veillard *str = cur; 491d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(0); 492d7af555327843a9938a913205ac703c13c225603Daniel Veillard} 493d7af555327843a9938a913205ac703c13c225603Daniel Veillard 494d7af555327843a9938a913205ac703c13c225603Daniel Veillard/** 495d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986Authority: 496d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an URI structure 497d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string to analyze 498d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 499d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse an authority part and fills in the appropriate fields 500d7af555327843a9938a913205ac703c13c225603Daniel Veillard * of the @uri structure 501d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 502d7af555327843a9938a913205ac703c13c225603Daniel Veillard * authority = [ userinfo "@" ] host [ ":" port ] 503d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 504d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 505d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 506d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 507d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986Authority(xmlURIPtr uri, const char **str) 508d7af555327843a9938a913205ac703c13c225603Daniel Veillard{ 509d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *cur; 510d7af555327843a9938a913205ac703c13c225603Daniel Veillard int ret; 511d7af555327843a9938a913205ac703c13c225603Daniel Veillard 512d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = *str; 513d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* 514d7af555327843a9938a913205ac703c13c225603Daniel Veillard * try to parse an userinfo and check for the trailing @ 515d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 516d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Userinfo(uri, &cur); 517d7af555327843a9938a913205ac703c13c225603Daniel Veillard if ((ret != 0) || (*cur != '@')) 518d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = *str; 519d7af555327843a9938a913205ac703c13c225603Daniel Veillard else 520d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur++; 521d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Host(uri, &cur); 522d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 523d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (*cur == ':') { 524f582d14fbcba1cd1e6598d556d8838ea6f4788baDaniel Veillard cur++; 525d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Port(uri, &cur); 526d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 527d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 528d7af555327843a9938a913205ac703c13c225603Daniel Veillard *str = cur; 529d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(0); 530d7af555327843a9938a913205ac703c13c225603Daniel Veillard} 531d7af555327843a9938a913205ac703c13c225603Daniel Veillard 532d7af555327843a9938a913205ac703c13c225603Daniel Veillard/** 533d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986Segment: 534d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string to analyze 535d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @forbid: an optional forbidden character 536d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @empty: allow an empty segment 537d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 538d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse a segment and fills in the appropriate fields 539d7af555327843a9938a913205ac703c13c225603Daniel Veillard * of the @uri structure 540d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 541d7af555327843a9938a913205ac703c13c225603Daniel Veillard * segment = *pchar 542d7af555327843a9938a913205ac703c13c225603Daniel Veillard * segment-nz = 1*pchar 543d7af555327843a9938a913205ac703c13c225603Daniel Veillard * segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" ) 544d7af555327843a9938a913205ac703c13c225603Daniel Veillard * ; non-zero-length segment without any colon ":" 545d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 546d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 547d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 548d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 549d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986Segment(const char **str, char forbid, int empty) 550d7af555327843a9938a913205ac703c13c225603Daniel Veillard{ 551d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *cur; 552d7af555327843a9938a913205ac703c13c225603Daniel Veillard 553d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = *str; 554d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (!ISA_PCHAR(cur)) { 555d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (empty) 556d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(0); 557d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(1); 558fdd27d2718b9d6ef234092fb6cddfd7e9916feb6Daniel Veillard } 559d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (ISA_PCHAR(cur) && (*cur != forbid)) 560d7af555327843a9938a913205ac703c13c225603Daniel Veillard NEXT(cur); 561d7af555327843a9938a913205ac703c13c225603Daniel Veillard *str = cur; 562d7af555327843a9938a913205ac703c13c225603Daniel Veillard return (0); 563d7af555327843a9938a913205ac703c13c225603Daniel Veillard} 564d7af555327843a9938a913205ac703c13c225603Daniel Veillard 565d7af555327843a9938a913205ac703c13c225603Daniel Veillard/** 566d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986PathAbEmpty: 567d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an URI structure 568d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string to analyze 569d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 570d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse an path absolute or empty and fills in the appropriate fields 571d7af555327843a9938a913205ac703c13c225603Daniel Veillard * of the @uri structure 572d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 573d7af555327843a9938a913205ac703c13c225603Daniel Veillard * path-abempty = *( "/" segment ) 574d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 575d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 576d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 577d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 578d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986PathAbEmpty(xmlURIPtr uri, const char **str) 579d7af555327843a9938a913205ac703c13c225603Daniel Veillard{ 580d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *cur; 581d7af555327843a9938a913205ac703c13c225603Daniel Veillard int ret; 582d7af555327843a9938a913205ac703c13c225603Daniel Veillard 583d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = *str; 584d7af555327843a9938a913205ac703c13c225603Daniel Veillard 585d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (*cur == '/') { 586d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur++; 587d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Segment(&cur, 0, 1); 588d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 589d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 590d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri != NULL) { 591d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->path != NULL) xmlFree(uri->path); 5921358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard if (*str != cur) { 5931358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard if (uri->cleanup & 2) 5941358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard uri->path = STRNDUP(*str, cur - *str); 5951358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard else 5961358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard uri->path = xmlURIUnescapeString(*str, cur - *str, NULL); 5971358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard } else { 5981358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard uri->path = NULL; 5991358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard } 600d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 601d7af555327843a9938a913205ac703c13c225603Daniel Veillard *str = cur; 602d7af555327843a9938a913205ac703c13c225603Daniel Veillard return (0); 603d7af555327843a9938a913205ac703c13c225603Daniel Veillard} 604d7af555327843a9938a913205ac703c13c225603Daniel Veillard 605d7af555327843a9938a913205ac703c13c225603Daniel Veillard/** 606d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986PathAbsolute: 607d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an URI structure 608d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string to analyze 609d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 610d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse an path absolute and fills in the appropriate fields 611d7af555327843a9938a913205ac703c13c225603Daniel Veillard * of the @uri structure 612d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 613d7af555327843a9938a913205ac703c13c225603Daniel Veillard * path-absolute = "/" [ segment-nz *( "/" segment ) ] 614d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 615d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 616d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 617d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 618d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986PathAbsolute(xmlURIPtr uri, const char **str) 619d7af555327843a9938a913205ac703c13c225603Daniel Veillard{ 620d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *cur; 621d7af555327843a9938a913205ac703c13c225603Daniel Veillard int ret; 622d7af555327843a9938a913205ac703c13c225603Daniel Veillard 623d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = *str; 624d7af555327843a9938a913205ac703c13c225603Daniel Veillard 625d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (*cur != '/') 626d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(1); 627d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur++; 628d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Segment(&cur, 0, 0); 629d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret == 0) { 630d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (*cur == '/') { 631d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur++; 632d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Segment(&cur, 0, 1); 633d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 6343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 635fdd27d2718b9d6ef234092fb6cddfd7e9916feb6Daniel Veillard } 636d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri != NULL) { 637d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->path != NULL) xmlFree(uri->path); 6381358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard if (cur != *str) { 6391358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard if (uri->cleanup & 2) 6401358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard uri->path = STRNDUP(*str, cur - *str); 6411358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard else 6421358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard uri->path = xmlURIUnescapeString(*str, cur - *str, NULL); 6431358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard } else { 6441358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard uri->path = NULL; 6451358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard } 6463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 647d7af555327843a9938a913205ac703c13c225603Daniel Veillard *str = cur; 648d7af555327843a9938a913205ac703c13c225603Daniel Veillard return (0); 6493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 6503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 652d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986PathRootless: 653d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an URI structure 654d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string to analyze 6553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 656d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse an path without root and fills in the appropriate fields 657d7af555327843a9938a913205ac703c13c225603Daniel Veillard * of the @uri structure 658d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 659d7af555327843a9938a913205ac703c13c225603Daniel Veillard * path-rootless = segment-nz *( "/" segment ) 660d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 661d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 6623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 663d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 664d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986PathRootless(xmlURIPtr uri, const char **str) 665d7af555327843a9938a913205ac703c13c225603Daniel Veillard{ 666d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *cur; 667d7af555327843a9938a913205ac703c13c225603Daniel Veillard int ret; 6683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 669d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = *str; 670d7af555327843a9938a913205ac703c13c225603Daniel Veillard 671d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Segment(&cur, 0, 0); 672d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 673d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (*cur == '/') { 674d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur++; 675d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Segment(&cur, 0, 1); 676d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 677d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 678d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri != NULL) { 679d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->path != NULL) xmlFree(uri->path); 6801358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard if (cur != *str) { 6811358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard if (uri->cleanup & 2) 6821358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard uri->path = STRNDUP(*str, cur - *str); 6831358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard else 6841358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard uri->path = xmlURIUnescapeString(*str, cur - *str, NULL); 6851358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard } else { 6861358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard uri->path = NULL; 6871358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard } 6883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 689d7af555327843a9938a913205ac703c13c225603Daniel Veillard *str = cur; 690d7af555327843a9938a913205ac703c13c225603Daniel Veillard return (0); 6913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 6923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 694d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986PathNoScheme: 695d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an URI structure 696d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string to analyze 6973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 698d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse an path which is not a scheme and fills in the appropriate fields 699d7af555327843a9938a913205ac703c13c225603Daniel Veillard * of the @uri structure 700d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 701d7af555327843a9938a913205ac703c13c225603Daniel Veillard * path-noscheme = segment-nz-nc *( "/" segment ) 702d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 703d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 7043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 705d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 706d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986PathNoScheme(xmlURIPtr uri, const char **str) 707d7af555327843a9938a913205ac703c13c225603Daniel Veillard{ 708d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *cur; 709d7af555327843a9938a913205ac703c13c225603Daniel Veillard int ret; 7103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 711d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = *str; 712d7af555327843a9938a913205ac703c13c225603Daniel Veillard 713d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Segment(&cur, ':', 0); 714d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 715d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (*cur == '/') { 716d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur++; 717d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Segment(&cur, 0, 1); 718d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 719d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 720d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri != NULL) { 721d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->path != NULL) xmlFree(uri->path); 7221358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard if (cur != *str) { 7231358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard if (uri->cleanup & 2) 7241358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard uri->path = STRNDUP(*str, cur - *str); 7251358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard else 7261358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard uri->path = xmlURIUnescapeString(*str, cur - *str, NULL); 7271358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard } else { 7281358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard uri->path = NULL; 7291358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard } 730d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 731d7af555327843a9938a913205ac703c13c225603Daniel Veillard *str = cur; 732d7af555327843a9938a913205ac703c13c225603Daniel Veillard return (0); 733d7af555327843a9938a913205ac703c13c225603Daniel Veillard} 734d7af555327843a9938a913205ac703c13c225603Daniel Veillard 735d7af555327843a9938a913205ac703c13c225603Daniel Veillard/** 736d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986HierPart: 737d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an URI structure 738d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string to analyze 739d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 740d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse an hierarchical part and fills in the appropriate fields 741d7af555327843a9938a913205ac703c13c225603Daniel Veillard * of the @uri structure 742d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 743d7af555327843a9938a913205ac703c13c225603Daniel Veillard * hier-part = "//" authority path-abempty 744d7af555327843a9938a913205ac703c13c225603Daniel Veillard * / path-absolute 745d7af555327843a9938a913205ac703c13c225603Daniel Veillard * / path-rootless 746d7af555327843a9938a913205ac703c13c225603Daniel Veillard * / path-empty 747d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 748d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 749d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 750d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 751d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986HierPart(xmlURIPtr uri, const char **str) 752d7af555327843a9938a913205ac703c13c225603Daniel Veillard{ 753d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *cur; 754d7af555327843a9938a913205ac703c13c225603Daniel Veillard int ret; 755d7af555327843a9938a913205ac703c13c225603Daniel Veillard 756d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = *str; 757d7af555327843a9938a913205ac703c13c225603Daniel Veillard 758d7af555327843a9938a913205ac703c13c225603Daniel Veillard if ((*cur == '/') && (*(cur + 1) == '/')) { 759d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur += 2; 760d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Authority(uri, &cur); 761d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 762beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard if (uri->server == NULL) 763beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard uri->port = -1; 764d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986PathAbEmpty(uri, &cur); 765d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 766d7af555327843a9938a913205ac703c13c225603Daniel Veillard *str = cur; 767d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(0); 768d7af555327843a9938a913205ac703c13c225603Daniel Veillard } else if (*cur == '/') { 769d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986PathAbsolute(uri, &cur); 770d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 771d7af555327843a9938a913205ac703c13c225603Daniel Veillard } else if (ISA_PCHAR(cur)) { 772d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986PathRootless(uri, &cur); 773d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 774d7af555327843a9938a913205ac703c13c225603Daniel Veillard } else { 775d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* path-empty is effectively empty */ 776d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri != NULL) { 777d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->path != NULL) xmlFree(uri->path); 778d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->path = NULL; 779d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 780d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 781d7af555327843a9938a913205ac703c13c225603Daniel Veillard *str = cur; 782d7af555327843a9938a913205ac703c13c225603Daniel Veillard return (0); 783d7af555327843a9938a913205ac703c13c225603Daniel Veillard} 784d7af555327843a9938a913205ac703c13c225603Daniel Veillard 785d7af555327843a9938a913205ac703c13c225603Daniel Veillard/** 786d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986RelativeRef: 787d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an URI structure 788d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string to analyze 789d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 790d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse an URI string and fills in the appropriate fields 791d7af555327843a9938a913205ac703c13c225603Daniel Veillard * of the @uri structure 792d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 793d7af555327843a9938a913205ac703c13c225603Daniel Veillard * relative-ref = relative-part [ "?" query ] [ "#" fragment ] 794d7af555327843a9938a913205ac703c13c225603Daniel Veillard * relative-part = "//" authority path-abempty 795d7af555327843a9938a913205ac703c13c225603Daniel Veillard * / path-absolute 796d7af555327843a9938a913205ac703c13c225603Daniel Veillard * / path-noscheme 797d7af555327843a9938a913205ac703c13c225603Daniel Veillard * / path-empty 798d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 799d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 800d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 801d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 802d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986RelativeRef(xmlURIPtr uri, const char *str) { 803d7af555327843a9938a913205ac703c13c225603Daniel Veillard int ret; 804d7af555327843a9938a913205ac703c13c225603Daniel Veillard 805d7af555327843a9938a913205ac703c13c225603Daniel Veillard if ((*str == '/') && (*(str + 1) == '/')) { 806d7af555327843a9938a913205ac703c13c225603Daniel Veillard str += 2; 807d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Authority(uri, &str); 808d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 809d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986PathAbEmpty(uri, &str); 810d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 811d7af555327843a9938a913205ac703c13c225603Daniel Veillard } else if (*str == '/') { 812d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986PathAbsolute(uri, &str); 813d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 814d7af555327843a9938a913205ac703c13c225603Daniel Veillard } else if (ISA_PCHAR(str)) { 815d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986PathNoScheme(uri, &str); 816d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 817d7af555327843a9938a913205ac703c13c225603Daniel Veillard } else { 818d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* path-empty is effectively empty */ 819d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri != NULL) { 820d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->path != NULL) xmlFree(uri->path); 821d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->path = NULL; 822d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 823d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 824d7af555327843a9938a913205ac703c13c225603Daniel Veillard 825d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (*str == '?') { 826d7af555327843a9938a913205ac703c13c225603Daniel Veillard str++; 827d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Query(uri, &str); 828d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 829d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 830d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (*str == '#') { 831d7af555327843a9938a913205ac703c13c225603Daniel Veillard str++; 832d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Fragment(uri, &str); 833d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 834d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 835d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (*str != 0) { 836d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlCleanURI(uri); 837d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(1); 838d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 839d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(0); 8403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 8413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 842d7af555327843a9938a913205ac703c13c225603Daniel Veillard 8433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 844d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986URI: 845d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an URI structure 846d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string to analyze 8473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 848d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse an URI string and fills in the appropriate fields 849d7af555327843a9938a913205ac703c13c225603Daniel Veillard * of the @uri structure 850d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 851d7af555327843a9938a913205ac703c13c225603Daniel Veillard * scheme ":" hier-part [ "?" query ] [ "#" fragment ] 852d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 853d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 8543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 855d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 856d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986URI(xmlURIPtr uri, const char *str) { 857d7af555327843a9938a913205ac703c13c225603Daniel Veillard int ret; 8583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 859d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Scheme(uri, &str); 860d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 861d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (*str != ':') { 862d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(1); 863d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 864d7af555327843a9938a913205ac703c13c225603Daniel Veillard str++; 865d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986HierPart(uri, &str); 866d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 867d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (*str == '?') { 868d7af555327843a9938a913205ac703c13c225603Daniel Veillard str++; 869d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Query(uri, &str); 870d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 871d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 872d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (*str == '#') { 873d7af555327843a9938a913205ac703c13c225603Daniel Veillard str++; 874d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Fragment(uri, &str); 875d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 876d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 877d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (*str != 0) { 878d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlCleanURI(uri); 879d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(1); 880d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 881d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(0); 8823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 8833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 885d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986URIReference: 886d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an URI structure 887d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string to analyze 8883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 889d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse an URI reference string and fills in the appropriate fields 890d7af555327843a9938a913205ac703c13c225603Daniel Veillard * of the @uri structure 8913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 892d7af555327843a9938a913205ac703c13c225603Daniel Veillard * URI-reference = URI / relative-ref 8933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 894d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 8953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 896d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 897d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986URIReference(xmlURIPtr uri, const char *str) { 898d7af555327843a9938a913205ac703c13c225603Daniel Veillard int ret; 8993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 900d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (str == NULL) 9013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 902d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlCleanURI(uri); 9033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 9043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 905d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Try first to parse absolute refs, then fallback to relative if 906d7af555327843a9938a913205ac703c13c225603Daniel Veillard * it fails. 9073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 908d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986URI(uri, str); 909d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) { 910d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlCleanURI(uri); 911d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986RelativeRef(uri, str); 912d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) { 913d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlCleanURI(uri); 914d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(ret); 9153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 9163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 917d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(0); 918d7af555327843a9938a913205ac703c13c225603Daniel Veillard} 9193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 920d7af555327843a9938a913205ac703c13c225603Daniel Veillard/** 921d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParseURI: 922d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the URI string to analyze 923d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 924d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse an URI based on RFC 3986 925d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 926d7af555327843a9938a913205ac703c13c225603Daniel Veillard * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ] 927d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 928d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns a newly built xmlURIPtr or NULL in case of error 929d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 930d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlURIPtr 931d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParseURI(const char *str) { 932d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlURIPtr uri; 933d7af555327843a9938a913205ac703c13c225603Daniel Veillard int ret; 9343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 935d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (str == NULL) 936d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(NULL); 937d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri = xmlCreateURI(); 938d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri != NULL) { 939d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986URIReference(uri, str); 940d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret) { 941d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFreeURI(uri); 942d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(NULL); 943d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 9443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 945d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(uri); 946d7af555327843a9938a913205ac703c13c225603Daniel Veillard} 9473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 948d7af555327843a9938a913205ac703c13c225603Daniel Veillard/** 949d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParseURIReference: 950d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an URI structure 951d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string to analyze 952d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 953d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse an URI reference string based on RFC 3986 and fills in the 954d7af555327843a9938a913205ac703c13c225603Daniel Veillard * appropriate fields of the @uri structure 955d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 956d7af555327843a9938a913205ac703c13c225603Daniel Veillard * URI-reference = URI / relative-ref 957d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 958d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 959d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 960d7af555327843a9938a913205ac703c13c225603Daniel Veillardint 961d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParseURIReference(xmlURIPtr uri, const char *str) { 962d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(xmlParse3986URIReference(uri, str)); 963d7af555327843a9938a913205ac703c13c225603Daniel Veillard} 9643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 965d7af555327843a9938a913205ac703c13c225603Daniel Veillard/** 966d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParseURIRaw: 967d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the URI string to analyze 968d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @raw: if 1 unescaping of URI pieces are disabled 969d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 970d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse an URI but allows to keep intact the original fragments. 971d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 972d7af555327843a9938a913205ac703c13c225603Daniel Veillard * URI-reference = URI / relative-ref 973d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 974d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns a newly built xmlURIPtr or NULL in case of error 975d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 976d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlURIPtr 977d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParseURIRaw(const char *str, int raw) { 978d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlURIPtr uri; 979d7af555327843a9938a913205ac703c13c225603Daniel Veillard int ret; 9803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 981d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (str == NULL) 982d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(NULL); 983d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri = xmlCreateURI(); 984d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri != NULL) { 985d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (raw) { 986d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->cleanup |= 2; 987d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 988d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParseURIReference(uri, str); 989d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret) { 990d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFreeURI(uri); 991d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(NULL); 992d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 993d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 994d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(uri); 9953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 9963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 997d7af555327843a9938a913205ac703c13c225603Daniel Veillard/************************************************************************ 998d7af555327843a9938a913205ac703c13c225603Daniel Veillard * * 999d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Generic URI structure functions * 1000d7af555327843a9938a913205ac703c13c225603Daniel Veillard * * 1001d7af555327843a9938a913205ac703c13c225603Daniel Veillard ************************************************************************/ 1002d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1003d7af555327843a9938a913205ac703c13c225603Daniel Veillard/** 1004d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlCreateURI: 1005d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 1006d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Simply creates an empty xmlURI 1007d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 1008d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns the new structure or NULL in case of error 1009d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 1010d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlURIPtr 1011d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlCreateURI(void) { 1012d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlURIPtr ret; 1013d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1014d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = (xmlURIPtr) xmlMalloc(sizeof(xmlURI)); 1015d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret == NULL) { 101657560386503be0fd023f3b7537fd496784f3be18Daniel Veillard xmlURIErrMemory("creating URI structure\n"); 1017d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(NULL); 1018d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1019d7af555327843a9938a913205ac703c13c225603Daniel Veillard memset(ret, 0, sizeof(xmlURI)); 1020d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(ret); 1021966a31e222f478b8ab3174617794808aa90f20c0Daniel Veillard} 1022966a31e222f478b8ab3174617794808aa90f20c0Daniel Veillard 10233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 102457560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * xmlSaveUriRealloc: 102557560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * 102657560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * Function to handle properly a reallocation when saving an URI 102757560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * Also imposes some limit on the length of an URI string output 102857560386503be0fd023f3b7537fd496784f3be18Daniel Veillard */ 102957560386503be0fd023f3b7537fd496784f3be18Daniel Veillardstatic xmlChar * 103057560386503be0fd023f3b7537fd496784f3be18Daniel VeillardxmlSaveUriRealloc(xmlChar *ret, int *max) { 103157560386503be0fd023f3b7537fd496784f3be18Daniel Veillard xmlChar *temp; 103257560386503be0fd023f3b7537fd496784f3be18Daniel Veillard int tmp; 103357560386503be0fd023f3b7537fd496784f3be18Daniel Veillard 103457560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (*max > MAX_URI_LENGTH) { 103557560386503be0fd023f3b7537fd496784f3be18Daniel Veillard xmlURIErrMemory("reaching arbitrary MAX_URI_LENGTH limit\n"); 103657560386503be0fd023f3b7537fd496784f3be18Daniel Veillard return(NULL); 103757560386503be0fd023f3b7537fd496784f3be18Daniel Veillard } 103857560386503be0fd023f3b7537fd496784f3be18Daniel Veillard tmp = *max * 2; 103957560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = (xmlChar *) xmlRealloc(ret, (tmp + 1)); 104057560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) { 104157560386503be0fd023f3b7537fd496784f3be18Daniel Veillard xmlURIErrMemory("saving URI\n"); 104257560386503be0fd023f3b7537fd496784f3be18Daniel Veillard return(NULL); 104357560386503be0fd023f3b7537fd496784f3be18Daniel Veillard } 104457560386503be0fd023f3b7537fd496784f3be18Daniel Veillard *max = tmp; 104557560386503be0fd023f3b7537fd496784f3be18Daniel Veillard return(temp); 104657560386503be0fd023f3b7537fd496784f3be18Daniel Veillard} 104757560386503be0fd023f3b7537fd496784f3be18Daniel Veillard 104857560386503be0fd023f3b7537fd496784f3be18Daniel Veillard/** 1049d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlSaveUri: 1050d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an xmlURI 10513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1052d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Save the URI as an escaped string 10533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1054d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns a new string (to be deallocated by caller) 10553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1056d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlChar * 1057d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlSaveUri(xmlURIPtr uri) { 1058d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlChar *ret = NULL; 1059d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlChar *temp; 1060d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *p; 1061d7af555327843a9938a913205ac703c13c225603Daniel Veillard int len; 1062d7af555327843a9938a913205ac703c13c225603Daniel Veillard int max; 10633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1064d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri == NULL) return(NULL); 1065d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1066d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1067d7af555327843a9938a913205ac703c13c225603Daniel Veillard max = 80; 1068d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = (xmlChar *) xmlMallocAtomic((max + 1) * sizeof(xmlChar)); 1069d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret == NULL) { 107057560386503be0fd023f3b7537fd496784f3be18Daniel Veillard xmlURIErrMemory("saving URI\n"); 10713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 1072d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1073d7af555327843a9938a913205ac703c13c225603Daniel Veillard len = 0; 10743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1075d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->scheme != NULL) { 1076d7af555327843a9938a913205ac703c13c225603Daniel Veillard p = uri->scheme; 1077d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (*p != 0) { 1078d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len >= max) { 107957560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 108057560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 1081d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = temp; 1082d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1083d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = *p++; 10843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1085d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len >= max) { 108657560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 108757560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 108857560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 1089d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1090d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = ':'; 1091d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1092d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->opaque != NULL) { 1093d7af555327843a9938a913205ac703c13c225603Daniel Veillard p = uri->opaque; 1094d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (*p != 0) { 1095d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len + 3 >= max) { 109657560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 109757560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 109857560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 1099d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1100d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (IS_RESERVED(*(p)) || IS_UNRESERVED(*(p))) 1101d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = *p++; 1102d7af555327843a9938a913205ac703c13c225603Daniel Veillard else { 1103d7af555327843a9938a913205ac703c13c225603Daniel Veillard int val = *(unsigned char *)p++; 1104d7af555327843a9938a913205ac703c13c225603Daniel Veillard int hi = val / 0x10, lo = val % 0x10; 1105d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = '%'; 1106d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = hi + (hi > 9? 'A'-10 : '0'); 1107d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = lo + (lo > 9? 'A'-10 : '0'); 1108d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1109d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1110d7af555327843a9938a913205ac703c13c225603Daniel Veillard } else { 1111beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard if ((uri->server != NULL) || (uri->port == -1)) { 1112d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len + 3 >= max) { 111357560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 111457560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 111557560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 1116d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1117d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = '/'; 1118d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = '/'; 1119d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->user != NULL) { 1120d7af555327843a9938a913205ac703c13c225603Daniel Veillard p = uri->user; 1121d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (*p != 0) { 1122d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len + 3 >= max) { 112357560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 112457560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 112557560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 1126d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1127d7af555327843a9938a913205ac703c13c225603Daniel Veillard if ((IS_UNRESERVED(*(p))) || 1128d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == ';')) || ((*(p) == ':')) || 1129d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == '&')) || ((*(p) == '=')) || 1130d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == '+')) || ((*(p) == '$')) || 1131d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == ','))) 1132d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = *p++; 1133d7af555327843a9938a913205ac703c13c225603Daniel Veillard else { 1134d7af555327843a9938a913205ac703c13c225603Daniel Veillard int val = *(unsigned char *)p++; 1135d7af555327843a9938a913205ac703c13c225603Daniel Veillard int hi = val / 0x10, lo = val % 0x10; 1136d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = '%'; 1137d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = hi + (hi > 9? 'A'-10 : '0'); 1138d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = lo + (lo > 9? 'A'-10 : '0'); 1139d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1140d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1141d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len + 3 >= max) { 114257560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 114357560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 114457560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 1145d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1146d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = '@'; 1147d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1148beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard if (uri->server != NULL) { 1149beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard p = uri->server; 1150beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard while (*p != 0) { 1151beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard if (len >= max) { 1152beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 1153beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard if (temp == NULL) goto mem_error; 1154beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard ret = temp; 1155beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard } 1156beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard ret[len++] = *p++; 1157d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1158beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard if (uri->port > 0) { 1159beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard if (len + 10 >= max) { 1160beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 1161beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard if (temp == NULL) goto mem_error; 1162beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard ret = temp; 1163beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard } 1164beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard len += snprintf((char *) &ret[len], max - len, ":%d", uri->port); 1165d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1166d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1167d7af555327843a9938a913205ac703c13c225603Daniel Veillard } else if (uri->authority != NULL) { 1168d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len + 3 >= max) { 116957560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 117057560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 117157560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 1172d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1173d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = '/'; 1174d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = '/'; 1175d7af555327843a9938a913205ac703c13c225603Daniel Veillard p = uri->authority; 1176d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (*p != 0) { 1177d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len + 3 >= max) { 117857560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 117957560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 118057560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 1181d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1182d7af555327843a9938a913205ac703c13c225603Daniel Veillard if ((IS_UNRESERVED(*(p))) || 1183d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == '$')) || ((*(p) == ',')) || ((*(p) == ';')) || 1184d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == ':')) || ((*(p) == '@')) || ((*(p) == '&')) || 1185d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == '=')) || ((*(p) == '+'))) 1186d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = *p++; 1187d7af555327843a9938a913205ac703c13c225603Daniel Veillard else { 1188d7af555327843a9938a913205ac703c13c225603Daniel Veillard int val = *(unsigned char *)p++; 1189d7af555327843a9938a913205ac703c13c225603Daniel Veillard int hi = val / 0x10, lo = val % 0x10; 1190d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = '%'; 1191d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = hi + (hi > 9? 'A'-10 : '0'); 1192d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = lo + (lo > 9? 'A'-10 : '0'); 1193d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1194d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1195d7af555327843a9938a913205ac703c13c225603Daniel Veillard } else if (uri->scheme != NULL) { 1196d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len + 3 >= max) { 119757560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 119857560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 119957560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 1200d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 12013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1202d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->path != NULL) { 1203d7af555327843a9938a913205ac703c13c225603Daniel Veillard p = uri->path; 1204d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* 1205d7af555327843a9938a913205ac703c13c225603Daniel Veillard * the colon in file:///d: should not be escaped or 1206d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Windows accesses fail later. 1207d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 1208d7af555327843a9938a913205ac703c13c225603Daniel Veillard if ((uri->scheme != NULL) && 1209d7af555327843a9938a913205ac703c13c225603Daniel Veillard (p[0] == '/') && 1210d7af555327843a9938a913205ac703c13c225603Daniel Veillard (((p[1] >= 'a') && (p[1] <= 'z')) || 1211d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((p[1] >= 'A') && (p[1] <= 'Z'))) && 1212d7af555327843a9938a913205ac703c13c225603Daniel Veillard (p[2] == ':') && 1213d7af555327843a9938a913205ac703c13c225603Daniel Veillard (xmlStrEqual(BAD_CAST uri->scheme, BAD_CAST "file"))) { 1214d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len + 3 >= max) { 121557560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 121657560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 121757560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 1218d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1219d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = *p++; 1220d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = *p++; 1221d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = *p++; 1222d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1223d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (*p != 0) { 1224d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len + 3 >= max) { 122557560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 122657560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 122757560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 1228d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1229d7af555327843a9938a913205ac703c13c225603Daniel Veillard if ((IS_UNRESERVED(*(p))) || ((*(p) == '/')) || 1230d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == ';')) || ((*(p) == '@')) || ((*(p) == '&')) || 1231d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == '=')) || ((*(p) == '+')) || ((*(p) == '$')) || 1232d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == ','))) 1233d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = *p++; 1234d7af555327843a9938a913205ac703c13c225603Daniel Veillard else { 1235d7af555327843a9938a913205ac703c13c225603Daniel Veillard int val = *(unsigned char *)p++; 1236d7af555327843a9938a913205ac703c13c225603Daniel Veillard int hi = val / 0x10, lo = val % 0x10; 1237d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = '%'; 1238d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = hi + (hi > 9? 'A'-10 : '0'); 1239d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = lo + (lo > 9? 'A'-10 : '0'); 1240d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 12413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 12423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1243d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->query_raw != NULL) { 1244d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len + 1 >= max) { 124557560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 124657560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 124757560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 1248d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1249d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = '?'; 1250d7af555327843a9938a913205ac703c13c225603Daniel Veillard p = uri->query_raw; 1251d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (*p != 0) { 1252d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len + 1 >= max) { 125357560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 125457560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 125557560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 1256d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1257d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = *p++; 1258d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1259d7af555327843a9938a913205ac703c13c225603Daniel Veillard } else if (uri->query != NULL) { 1260d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len + 3 >= max) { 126157560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 126257560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 126357560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 1264d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1265d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = '?'; 1266d7af555327843a9938a913205ac703c13c225603Daniel Veillard p = uri->query; 1267d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (*p != 0) { 1268d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len + 3 >= max) { 126957560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 127057560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 127157560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 1272d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 127357560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if ((IS_UNRESERVED(*(p))) || (IS_RESERVED(*(p)))) 1274d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = *p++; 1275d7af555327843a9938a913205ac703c13c225603Daniel Veillard else { 1276d7af555327843a9938a913205ac703c13c225603Daniel Veillard int val = *(unsigned char *)p++; 1277d7af555327843a9938a913205ac703c13c225603Daniel Veillard int hi = val / 0x10, lo = val % 0x10; 1278d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = '%'; 1279d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = hi + (hi > 9? 'A'-10 : '0'); 1280d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = lo + (lo > 9? 'A'-10 : '0'); 1281d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1282d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 12833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 12844def3bd94c4c34ad0b7b2848f7f43a62c9ea067cDaniel Veillard } 1285d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->fragment != NULL) { 1286d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len + 3 >= max) { 128757560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 128857560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 128957560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 1290d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1291d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = '#'; 1292d7af555327843a9938a913205ac703c13c225603Daniel Veillard p = uri->fragment; 1293d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (*p != 0) { 1294d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len + 3 >= max) { 129557560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 129657560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 129757560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 1298d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 129957560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if ((IS_UNRESERVED(*(p))) || (IS_RESERVED(*(p)))) 1300d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = *p++; 1301d7af555327843a9938a913205ac703c13c225603Daniel Veillard else { 1302d7af555327843a9938a913205ac703c13c225603Daniel Veillard int val = *(unsigned char *)p++; 1303d7af555327843a9938a913205ac703c13c225603Daniel Veillard int hi = val / 0x10, lo = val % 0x10; 1304d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = '%'; 1305d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = hi + (hi > 9? 'A'-10 : '0'); 1306d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = lo + (lo > 9? 'A'-10 : '0'); 1307d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1308d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 13093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1310d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len >= max) { 131157560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 131257560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 131357560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 13143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 131513cee4e37ba9f2a401f976e069539514ebfce7bcDaniel Veillard ret[len] = 0; 1316d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(ret); 131757560386503be0fd023f3b7537fd496784f3be18Daniel Veillard 131857560386503be0fd023f3b7537fd496784f3be18Daniel Veillardmem_error: 131957560386503be0fd023f3b7537fd496784f3be18Daniel Veillard xmlFree(ret); 132057560386503be0fd023f3b7537fd496784f3be18Daniel Veillard return(NULL); 13213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 13223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 1324d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlPrintURI: 1325d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @stream: a FILE* for the output 1326d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an xmlURI 13273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1328d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Prints the URI in the stream @stream. 13293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1330d7af555327843a9938a913205ac703c13c225603Daniel Veillardvoid 1331d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlPrintURI(FILE *stream, xmlURIPtr uri) { 1332d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlChar *out; 13333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1334d7af555327843a9938a913205ac703c13c225603Daniel Veillard out = xmlSaveUri(uri); 1335d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (out != NULL) { 1336d7af555327843a9938a913205ac703c13c225603Daniel Veillard fprintf(stream, "%s", (char *) out); 1337d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFree(out); 13383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 13393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 13403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 1342d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlCleanURI: 1343d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an xmlURI 13443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1345d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Make sure the xmlURI struct is free of content 13463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1347d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic void 1348d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlCleanURI(xmlURIPtr uri) { 1349d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri == NULL) return; 13503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1351d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->scheme != NULL) xmlFree(uri->scheme); 1352d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->scheme = NULL; 1353d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->server != NULL) xmlFree(uri->server); 1354d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->server = NULL; 1355d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->user != NULL) xmlFree(uri->user); 1356d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->user = NULL; 1357d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->path != NULL) xmlFree(uri->path); 1358d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->path = NULL; 1359d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->fragment != NULL) xmlFree(uri->fragment); 1360d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->fragment = NULL; 1361d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->opaque != NULL) xmlFree(uri->opaque); 1362d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->opaque = NULL; 1363d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->authority != NULL) xmlFree(uri->authority); 1364d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->authority = NULL; 1365d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->query != NULL) xmlFree(uri->query); 1366d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->query = NULL; 1367d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->query_raw != NULL) xmlFree(uri->query_raw); 1368d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->query_raw = NULL; 1369d7af555327843a9938a913205ac703c13c225603Daniel Veillard} 13704def3bd94c4c34ad0b7b2848f7f43a62c9ea067cDaniel Veillard 1371d7af555327843a9938a913205ac703c13c225603Daniel Veillard/** 1372d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlFreeURI: 1373d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an xmlURI 1374d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 1375d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Free up the xmlURI struct 1376d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 1377d7af555327843a9938a913205ac703c13c225603Daniel Veillardvoid 1378d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlFreeURI(xmlURIPtr uri) { 1379d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri == NULL) return; 1380d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1381d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->scheme != NULL) xmlFree(uri->scheme); 1382d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->server != NULL) xmlFree(uri->server); 1383d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->user != NULL) xmlFree(uri->user); 1384d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->path != NULL) xmlFree(uri->path); 1385d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->fragment != NULL) xmlFree(uri->fragment); 1386d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->opaque != NULL) xmlFree(uri->opaque); 1387d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->authority != NULL) xmlFree(uri->authority); 1388d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->query != NULL) xmlFree(uri->query); 1389d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->query_raw != NULL) xmlFree(uri->query_raw); 1390d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFree(uri); 13913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 13923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1393d7af555327843a9938a913205ac703c13c225603Daniel Veillard/************************************************************************ 1394d7af555327843a9938a913205ac703c13c225603Daniel Veillard * * 1395d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Helper functions * 1396d7af555327843a9938a913205ac703c13c225603Daniel Veillard * * 1397d7af555327843a9938a913205ac703c13c225603Daniel Veillard ************************************************************************/ 1398d7af555327843a9938a913205ac703c13c225603Daniel Veillard 13993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 1400d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlNormalizeURIPath: 1401d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @path: pointer to the path string 14023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1403d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Applies the 5 normalization steps to a path string--that is, RFC 2396 1404d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Section 5.2, steps 6.c through 6.g. 14053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1406d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Normalization occurs directly on the string, no new allocation is done 1407d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 1408d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or an error code 14093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1410d7af555327843a9938a913205ac703c13c225603Daniel Veillardint 1411d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlNormalizeURIPath(char *path) { 1412d7af555327843a9938a913205ac703c13c225603Daniel Veillard char *cur, *out; 14133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1414d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (path == NULL) 14153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 14163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1417d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* Skip all initial "/" chars. We want to get to the beginning of the 1418d7af555327843a9938a913205ac703c13c225603Daniel Veillard * first non-empty segment. 14193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1420d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = path; 1421d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (cur[0] == '/') 1422d7af555327843a9938a913205ac703c13c225603Daniel Veillard ++cur; 1423d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (cur[0] == '\0') 1424d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(0); 1425d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1426d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* Keep everything we've seen so far. */ 1427d7af555327843a9938a913205ac703c13c225603Daniel Veillard out = cur; 1428d7af555327843a9938a913205ac703c13c225603Daniel Veillard 14293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 1430d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Analyze each segment in sequence for cases (c) and (d). 14313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1432d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (cur[0] != '\0') { 1433015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack /* 1434d7af555327843a9938a913205ac703c13c225603Daniel Veillard * c) All occurrences of "./", where "." is a complete path segment, 1435d7af555327843a9938a913205ac703c13c225603Daniel Veillard * are removed from the buffer string. 1436015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack */ 1437d7af555327843a9938a913205ac703c13c225603Daniel Veillard if ((cur[0] == '.') && (cur[1] == '/')) { 1438d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur += 2; 1439d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* '//' normalization should be done at this point too */ 1440d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (cur[0] == '/') 14413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 1442d7af555327843a9938a913205ac703c13c225603Daniel Veillard continue; 14433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 14443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1445d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* 1446d7af555327843a9938a913205ac703c13c225603Daniel Veillard * d) If the buffer string ends with "." as a complete path segment, 1447d7af555327843a9938a913205ac703c13c225603Daniel Veillard * that "." is removed. 1448d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 1449d7af555327843a9938a913205ac703c13c225603Daniel Veillard if ((cur[0] == '.') && (cur[1] == '\0')) 1450d7af555327843a9938a913205ac703c13c225603Daniel Veillard break; 14513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1452d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* Otherwise keep the segment. */ 1453d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (cur[0] != '/') { 1454d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (cur[0] == '\0') 1455d7af555327843a9938a913205ac703c13c225603Daniel Veillard goto done_cd; 1456d7af555327843a9938a913205ac703c13c225603Daniel Veillard (out++)[0] = (cur++)[0]; 1457d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1458d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* nomalize // */ 1459d7af555327843a9938a913205ac703c13c225603Daniel Veillard while ((cur[0] == '/') && (cur[1] == '/')) 1460d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur++; 14614def3bd94c4c34ad0b7b2848f7f43a62c9ea067cDaniel Veillard 1462d7af555327843a9938a913205ac703c13c225603Daniel Veillard (out++)[0] = (cur++)[0]; 14633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1464d7af555327843a9938a913205ac703c13c225603Daniel Veillard done_cd: 1465d7af555327843a9938a913205ac703c13c225603Daniel Veillard out[0] = '\0'; 1466d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1467d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* Reset to the beginning of the first segment for the next sequence. */ 1468d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = path; 1469d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (cur[0] == '/') 1470d7af555327843a9938a913205ac703c13c225603Daniel Veillard ++cur; 1471d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (cur[0] == '\0') 1472d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(0); 1473d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1474d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* 1475d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Analyze each segment in sequence for cases (e) and (f). 1476d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 1477d7af555327843a9938a913205ac703c13c225603Daniel Veillard * e) All occurrences of "<segment>/../", where <segment> is a 1478d7af555327843a9938a913205ac703c13c225603Daniel Veillard * complete path segment not equal to "..", are removed from the 1479d7af555327843a9938a913205ac703c13c225603Daniel Veillard * buffer string. Removal of these path segments is performed 1480d7af555327843a9938a913205ac703c13c225603Daniel Veillard * iteratively, removing the leftmost matching pattern on each 1481d7af555327843a9938a913205ac703c13c225603Daniel Veillard * iteration, until no matching pattern remains. 1482d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 1483d7af555327843a9938a913205ac703c13c225603Daniel Veillard * f) If the buffer string ends with "<segment>/..", where <segment> 1484d7af555327843a9938a913205ac703c13c225603Daniel Veillard * is a complete path segment not equal to "..", that 1485d7af555327843a9938a913205ac703c13c225603Daniel Veillard * "<segment>/.." is removed. 1486d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 1487d7af555327843a9938a913205ac703c13c225603Daniel Veillard * To satisfy the "iterative" clause in (e), we need to collapse the 1488d7af555327843a9938a913205ac703c13c225603Daniel Veillard * string every time we find something that needs to be removed. Thus, 1489d7af555327843a9938a913205ac703c13c225603Daniel Veillard * we don't need to keep two pointers into the string: we only need a 1490d7af555327843a9938a913205ac703c13c225603Daniel Veillard * "current position" pointer. 1491d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 1492d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (1) { 1493d7af555327843a9938a913205ac703c13c225603Daniel Veillard char *segp, *tmp; 14943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1495d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* At the beginning of each iteration of this loop, "cur" points to 1496d7af555327843a9938a913205ac703c13c225603Daniel Veillard * the first character of the segment we want to examine. 1497d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 14983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1499d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* Find the end of the current segment. */ 1500d7af555327843a9938a913205ac703c13c225603Daniel Veillard segp = cur; 1501d7af555327843a9938a913205ac703c13c225603Daniel Veillard while ((segp[0] != '/') && (segp[0] != '\0')) 1502d7af555327843a9938a913205ac703c13c225603Daniel Veillard ++segp; 15034def3bd94c4c34ad0b7b2848f7f43a62c9ea067cDaniel Veillard 1504d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* If this is the last segment, we're done (we need at least two 1505d7af555327843a9938a913205ac703c13c225603Daniel Veillard * segments to meet the criteria for the (e) and (f) cases). 1506d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 1507d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (segp[0] == '\0') 1508d7af555327843a9938a913205ac703c13c225603Daniel Veillard break; 15093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1510d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* If the first segment is "..", or if the next segment _isn't_ "..", 1511d7af555327843a9938a913205ac703c13c225603Daniel Veillard * keep this segment and try the next one. 1512d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 1513d7af555327843a9938a913205ac703c13c225603Daniel Veillard ++segp; 1514d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (((cur[0] == '.') && (cur[1] == '.') && (segp == cur+3)) 1515d7af555327843a9938a913205ac703c13c225603Daniel Veillard || ((segp[0] != '.') || (segp[1] != '.') 1516d7af555327843a9938a913205ac703c13c225603Daniel Veillard || ((segp[2] != '/') && (segp[2] != '\0')))) { 1517d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = segp; 1518d7af555327843a9938a913205ac703c13c225603Daniel Veillard continue; 15194def3bd94c4c34ad0b7b2848f7f43a62c9ea067cDaniel Veillard } 15203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1521d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* If we get here, remove this segment and the next one and back up 1522d7af555327843a9938a913205ac703c13c225603Daniel Veillard * to the previous segment (if there is one), to implement the 1523d7af555327843a9938a913205ac703c13c225603Daniel Veillard * "iteratively" clause. It's pretty much impossible to back up 1524d7af555327843a9938a913205ac703c13c225603Daniel Veillard * while maintaining two pointers into the buffer, so just compact 1525d7af555327843a9938a913205ac703c13c225603Daniel Veillard * the whole buffer now. 15264def3bd94c4c34ad0b7b2848f7f43a62c9ea067cDaniel Veillard */ 15273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1528d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* If this is the end of the buffer, we're done. */ 1529d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (segp[2] == '\0') { 1530d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur[0] = '\0'; 1531d7af555327843a9938a913205ac703c13c225603Daniel Veillard break; 15324def3bd94c4c34ad0b7b2848f7f43a62c9ea067cDaniel Veillard } 1533d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* Valgrind complained, strcpy(cur, segp + 3); */ 1534cedf84d35ab127dd24f9bcbf8b8339518d0e8928Nico Weber /* string will overlap, do not use strcpy */ 1535cedf84d35ab127dd24f9bcbf8b8339518d0e8928Nico Weber tmp = cur; 1536cedf84d35ab127dd24f9bcbf8b8339518d0e8928Nico Weber segp += 3; 1537cedf84d35ab127dd24f9bcbf8b8339518d0e8928Nico Weber while ((*tmp++ = *segp++) != 0) 1538cedf84d35ab127dd24f9bcbf8b8339518d0e8928Nico Weber ; 15393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1540d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* If there are no previous segments, then keep going from here. */ 1541d7af555327843a9938a913205ac703c13c225603Daniel Veillard segp = cur; 1542d7af555327843a9938a913205ac703c13c225603Daniel Veillard while ((segp > path) && ((--segp)[0] == '/')) 1543d7af555327843a9938a913205ac703c13c225603Daniel Veillard ; 1544d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (segp == path) 1545d7af555327843a9938a913205ac703c13c225603Daniel Veillard continue; 15463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1547d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* "segp" is pointing to the end of a previous segment; find it's 1548d7af555327843a9938a913205ac703c13c225603Daniel Veillard * start. We need to back up to the previous segment and start 1549d7af555327843a9938a913205ac703c13c225603Daniel Veillard * over with that to handle things like "foo/bar/../..". If we 1550d7af555327843a9938a913205ac703c13c225603Daniel Veillard * don't do this, then on the first pass we'll remove the "bar/..", 1551d7af555327843a9938a913205ac703c13c225603Daniel Veillard * but be pointing at the second ".." so we won't realize we can also 1552d7af555327843a9938a913205ac703c13c225603Daniel Veillard * remove the "foo/..". 1553d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 1554d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = segp; 1555d7af555327843a9938a913205ac703c13c225603Daniel Veillard while ((cur > path) && (cur[-1] != '/')) 1556d7af555327843a9938a913205ac703c13c225603Daniel Veillard --cur; 1557d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1558d7af555327843a9938a913205ac703c13c225603Daniel Veillard out[0] = '\0'; 15593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 15603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 1561d7af555327843a9938a913205ac703c13c225603Daniel Veillard * g) If the resulting buffer string still begins with one or more 1562d7af555327843a9938a913205ac703c13c225603Daniel Veillard * complete path segments of "..", then the reference is 1563d7af555327843a9938a913205ac703c13c225603Daniel Veillard * considered to be in error. Implementations may handle this 1564d7af555327843a9938a913205ac703c13c225603Daniel Veillard * error by retaining these components in the resolved path (i.e., 1565d7af555327843a9938a913205ac703c13c225603Daniel Veillard * treating them as part of the final URI), by removing them from 1566d7af555327843a9938a913205ac703c13c225603Daniel Veillard * the resolved path (i.e., discarding relative levels above the 1567d7af555327843a9938a913205ac703c13c225603Daniel Veillard * root), or by avoiding traversal of the reference. 1568d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 1569d7af555327843a9938a913205ac703c13c225603Daniel Veillard * We discard them from the final path. 15703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1571d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (path[0] == '/') { 1572d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = path; 1573d7af555327843a9938a913205ac703c13c225603Daniel Veillard while ((cur[0] == '/') && (cur[1] == '.') && (cur[2] == '.') 1574d7af555327843a9938a913205ac703c13c225603Daniel Veillard && ((cur[3] == '/') || (cur[3] == '\0'))) 1575d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur += 3; 15763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1577d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (cur != path) { 1578d7af555327843a9938a913205ac703c13c225603Daniel Veillard out = path; 1579d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (cur[0] != '\0') 1580d7af555327843a9938a913205ac703c13c225603Daniel Veillard (out++)[0] = (cur++)[0]; 1581d7af555327843a9938a913205ac703c13c225603Daniel Veillard out[0] = 0; 1582d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 15833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 15843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 15853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 15863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 15873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1588d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int is_hex(char c) { 1589d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (((c >= '0') && (c <= '9')) || 1590d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((c >= 'a') && (c <= 'f')) || 1591d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((c >= 'A') && (c <= 'F'))) 15923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 1593d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(0); 15943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 15953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 15963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 1597d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlURIUnescapeString: 1598d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string to unescape 1599d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @len: the length in bytes to unescape (or <= 0 to indicate full string) 1600d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @target: optional destination buffer 16013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1602d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Unescaping routine, but does not check that the string is an URI. The 1603d7af555327843a9938a913205ac703c13c225603Daniel Veillard * output is a direct unsigned char translation of %XX values (no encoding) 1604d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Note that the length of the result can only be smaller or same size as 1605d7af555327843a9938a913205ac703c13c225603Daniel Veillard * the input string. 16063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1607d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns a copy of the string, but unescaped, will return NULL only in case 1608d7af555327843a9938a913205ac703c13c225603Daniel Veillard * of error 16093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1610d7af555327843a9938a913205ac703c13c225603Daniel Veillardchar * 1611d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlURIUnescapeString(const char *str, int len, char *target) { 1612d7af555327843a9938a913205ac703c13c225603Daniel Veillard char *ret, *out; 1613d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *in; 16143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 16153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (str == NULL) 1616d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(NULL); 1617d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len <= 0) len = strlen(str); 1618d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len < 0) return(NULL); 1619d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1620d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (target == NULL) { 1621d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = (char *) xmlMallocAtomic(len + 1); 1622d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret == NULL) { 162357560386503be0fd023f3b7537fd496784f3be18Daniel Veillard xmlURIErrMemory("unescaping URI value\n"); 1624d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(NULL); 16253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1626d7af555327843a9938a913205ac703c13c225603Daniel Veillard } else 1627d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = target; 1628d7af555327843a9938a913205ac703c13c225603Daniel Veillard in = str; 1629d7af555327843a9938a913205ac703c13c225603Daniel Veillard out = ret; 1630d7af555327843a9938a913205ac703c13c225603Daniel Veillard while(len > 0) { 1631d7af555327843a9938a913205ac703c13c225603Daniel Veillard if ((len > 2) && (*in == '%') && (is_hex(in[1])) && (is_hex(in[2]))) { 1632d7af555327843a9938a913205ac703c13c225603Daniel Veillard in++; 163357560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if ((*in >= '0') && (*in <= '9')) 1634d7af555327843a9938a913205ac703c13c225603Daniel Veillard *out = (*in - '0'); 1635d7af555327843a9938a913205ac703c13c225603Daniel Veillard else if ((*in >= 'a') && (*in <= 'f')) 1636d7af555327843a9938a913205ac703c13c225603Daniel Veillard *out = (*in - 'a') + 10; 1637d7af555327843a9938a913205ac703c13c225603Daniel Veillard else if ((*in >= 'A') && (*in <= 'F')) 1638d7af555327843a9938a913205ac703c13c225603Daniel Veillard *out = (*in - 'A') + 10; 1639d7af555327843a9938a913205ac703c13c225603Daniel Veillard in++; 164057560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if ((*in >= '0') && (*in <= '9')) 1641d7af555327843a9938a913205ac703c13c225603Daniel Veillard *out = *out * 16 + (*in - '0'); 1642d7af555327843a9938a913205ac703c13c225603Daniel Veillard else if ((*in >= 'a') && (*in <= 'f')) 1643d7af555327843a9938a913205ac703c13c225603Daniel Veillard *out = *out * 16 + (*in - 'a') + 10; 1644d7af555327843a9938a913205ac703c13c225603Daniel Veillard else if ((*in >= 'A') && (*in <= 'F')) 1645d7af555327843a9938a913205ac703c13c225603Daniel Veillard *out = *out * 16 + (*in - 'A') + 10; 1646d7af555327843a9938a913205ac703c13c225603Daniel Veillard in++; 1647d7af555327843a9938a913205ac703c13c225603Daniel Veillard len -= 3; 1648d7af555327843a9938a913205ac703c13c225603Daniel Veillard out++; 1649d7af555327843a9938a913205ac703c13c225603Daniel Veillard } else { 1650d7af555327843a9938a913205ac703c13c225603Daniel Veillard *out++ = *in++; 1651d7af555327843a9938a913205ac703c13c225603Daniel Veillard len--; 16523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 16533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1654d7af555327843a9938a913205ac703c13c225603Daniel Veillard *out = 0; 16553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 16563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 16573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 16583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 1659d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlURIEscapeStr: 1660d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: string to escape 1661d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @list: exception list string of chars not to escape 16623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1663d7af555327843a9938a913205ac703c13c225603Daniel Veillard * This routine escapes a string to hex, ignoring reserved characters (a-z) 1664d7af555327843a9938a913205ac703c13c225603Daniel Veillard * and the characters in the exception list. 16653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1666d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns a new escaped string or NULL in case of error. 16673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1668d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlChar * 1669d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlURIEscapeStr(const xmlChar *str, const xmlChar *list) { 1670d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlChar *ret, ch; 1671d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlChar *temp; 1672d7af555327843a9938a913205ac703c13c225603Daniel Veillard const xmlChar *in; 167357560386503be0fd023f3b7537fd496784f3be18Daniel Veillard int len, out; 16743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 16753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (str == NULL) 1676d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(NULL); 1677d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (str[0] == 0) 1678d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(xmlStrdup(str)); 1679d7af555327843a9938a913205ac703c13c225603Daniel Veillard len = xmlStrlen(str); 1680d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (!(len > 0)) return(NULL); 16813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1682d7af555327843a9938a913205ac703c13c225603Daniel Veillard len += 20; 1683d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = (xmlChar *) xmlMallocAtomic(len); 1684d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret == NULL) { 168557560386503be0fd023f3b7537fd496784f3be18Daniel Veillard xmlURIErrMemory("escaping URI value\n"); 1686d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(NULL); 16873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1688d7af555327843a9938a913205ac703c13c225603Daniel Veillard in = (const xmlChar *) str; 1689d7af555327843a9938a913205ac703c13c225603Daniel Veillard out = 0; 1690d7af555327843a9938a913205ac703c13c225603Daniel Veillard while(*in != 0) { 1691d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len - out <= 3) { 169257560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &len); 1693d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (temp == NULL) { 169457560386503be0fd023f3b7537fd496784f3be18Daniel Veillard xmlURIErrMemory("escaping URI value\n"); 1695d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFree(ret); 1696d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(NULL); 1697d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1698d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = temp; 1699d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1700d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1701d7af555327843a9938a913205ac703c13c225603Daniel Veillard ch = *in; 1702d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1703d7af555327843a9938a913205ac703c13c225603Daniel Veillard if ((ch != '@') && (!IS_UNRESERVED(ch)) && (!xmlStrchr(list, ch))) { 1704d7af555327843a9938a913205ac703c13c225603Daniel Veillard unsigned char val; 1705d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[out++] = '%'; 1706d7af555327843a9938a913205ac703c13c225603Daniel Veillard val = ch >> 4; 1707d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (val <= 9) 1708d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[out++] = '0' + val; 1709d7af555327843a9938a913205ac703c13c225603Daniel Veillard else 1710d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[out++] = 'A' + val - 0xA; 1711d7af555327843a9938a913205ac703c13c225603Daniel Veillard val = ch & 0xF; 1712d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (val <= 9) 1713d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[out++] = '0' + val; 1714d7af555327843a9938a913205ac703c13c225603Daniel Veillard else 1715d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[out++] = 'A' + val - 0xA; 1716d7af555327843a9938a913205ac703c13c225603Daniel Veillard in++; 1717d7af555327843a9938a913205ac703c13c225603Daniel Veillard } else { 1718d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[out++] = *in++; 1719d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 17203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 17213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1722d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[out] = 0; 1723d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(ret); 17243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 17253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 17263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 1727d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlURIEscape: 1728d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string of the URI to escape 17293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1730d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Escaping routine, does not do validity checks ! 1731d7af555327843a9938a913205ac703c13c225603Daniel Veillard * It will try to escape the chars needing this, but this is heuristic 1732d7af555327843a9938a913205ac703c13c225603Daniel Veillard * based it's impossible to be sure. 17333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1734d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns an copy of the string, but escaped 1735d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 1736d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 25 May 2001 1737d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Uses xmlParseURI and xmlURIEscapeStr to try to escape correctly 1738d7af555327843a9938a913205ac703c13c225603Daniel Veillard * according to RFC2396. 1739d7af555327843a9938a913205ac703c13c225603Daniel Veillard * - Carl Douglas 17403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1741d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlChar * 1742d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlURIEscape(const xmlChar * str) 1743d7af555327843a9938a913205ac703c13c225603Daniel Veillard{ 1744d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlChar *ret, *segment = NULL; 17453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlURIPtr uri; 1746d7af555327843a9938a913205ac703c13c225603Daniel Veillard int ret2; 1747d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1748d7af555327843a9938a913205ac703c13c225603Daniel Veillard#define NULLCHK(p) if(!p) { \ 174957560386503be0fd023f3b7537fd496784f3be18Daniel Veillard xmlURIErrMemory("escaping URI value\n"); \ 175057560386503be0fd023f3b7537fd496784f3be18Daniel Veillard xmlFreeURI(uri); \ 175157560386503be0fd023f3b7537fd496784f3be18Daniel Veillard return NULL; } \ 17523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 17533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (str == NULL) 1754d7af555327843a9938a913205ac703c13c225603Daniel Veillard return (NULL); 1755d7af555327843a9938a913205ac703c13c225603Daniel Veillard 17563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor uri = xmlCreateURI(); 17573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (uri != NULL) { 1758d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* 1759d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Allow escaping errors in the unescaped form 1760d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 1761d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->cleanup = 1; 1762d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret2 = xmlParseURIReference(uri, (const char *)str); 1763d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret2) { 1764d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFreeURI(uri); 1765d7af555327843a9938a913205ac703c13c225603Daniel Veillard return (NULL); 1766d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 17673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 17683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1769d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (!uri) 1770d7af555327843a9938a913205ac703c13c225603Daniel Veillard return NULL; 1771336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard 1772d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = NULL; 1773d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1774d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->scheme) { 1775d7af555327843a9938a913205ac703c13c225603Daniel Veillard segment = xmlURIEscapeStr(BAD_CAST uri->scheme, BAD_CAST "+-."); 1776d7af555327843a9938a913205ac703c13c225603Daniel Veillard NULLCHK(segment) 1777d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, segment); 1778d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, BAD_CAST ":"); 1779d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFree(segment); 1780336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard } 1781d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1782d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->authority) { 1783d7af555327843a9938a913205ac703c13c225603Daniel Veillard segment = 1784d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlURIEscapeStr(BAD_CAST uri->authority, BAD_CAST "/?;:@"); 1785d7af555327843a9938a913205ac703c13c225603Daniel Veillard NULLCHK(segment) 1786d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, BAD_CAST "//"); 1787d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, segment); 1788d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFree(segment); 1789d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1790d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1791d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->user) { 1792d7af555327843a9938a913205ac703c13c225603Daniel Veillard segment = xmlURIEscapeStr(BAD_CAST uri->user, BAD_CAST ";:&=+$,"); 1793d7af555327843a9938a913205ac703c13c225603Daniel Veillard NULLCHK(segment) 179457560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = xmlStrcat(ret,BAD_CAST "//"); 1795d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, segment); 1796d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, BAD_CAST "@"); 1797d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFree(segment); 1798d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1799d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1800d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->server) { 1801d7af555327843a9938a913205ac703c13c225603Daniel Veillard segment = xmlURIEscapeStr(BAD_CAST uri->server, BAD_CAST "/?;:@"); 1802d7af555327843a9938a913205ac703c13c225603Daniel Veillard NULLCHK(segment) 1803d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->user == NULL) 1804d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, BAD_CAST "//"); 1805d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, segment); 1806d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFree(segment); 1807d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1808d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1809d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->port) { 1810d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlChar port[10]; 1811d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1812d7af555327843a9938a913205ac703c13c225603Daniel Veillard snprintf((char *) port, 10, "%d", uri->port); 1813d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, BAD_CAST ":"); 1814d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, port); 1815d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1816d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1817d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->path) { 1818d7af555327843a9938a913205ac703c13c225603Daniel Veillard segment = 1819d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlURIEscapeStr(BAD_CAST uri->path, BAD_CAST ":@&=+$,/?;"); 1820d7af555327843a9938a913205ac703c13c225603Daniel Veillard NULLCHK(segment) 1821d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, segment); 1822d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFree(segment); 1823d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1824d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1825d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->query_raw) { 1826d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, BAD_CAST "?"); 1827d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, BAD_CAST uri->query_raw); 1828d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1829d7af555327843a9938a913205ac703c13c225603Daniel Veillard else if (uri->query) { 1830d7af555327843a9938a913205ac703c13c225603Daniel Veillard segment = 1831d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlURIEscapeStr(BAD_CAST uri->query, BAD_CAST ";/?:@&=+,$"); 1832d7af555327843a9938a913205ac703c13c225603Daniel Veillard NULLCHK(segment) 1833d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, BAD_CAST "?"); 1834d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, segment); 1835d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFree(segment); 1836d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1837d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1838d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->opaque) { 1839d7af555327843a9938a913205ac703c13c225603Daniel Veillard segment = xmlURIEscapeStr(BAD_CAST uri->opaque, BAD_CAST ""); 1840d7af555327843a9938a913205ac703c13c225603Daniel Veillard NULLCHK(segment) 1841d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, segment); 1842d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFree(segment); 1843d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1844d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1845d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->fragment) { 1846d7af555327843a9938a913205ac703c13c225603Daniel Veillard segment = xmlURIEscapeStr(BAD_CAST uri->fragment, BAD_CAST "#"); 1847d7af555327843a9938a913205ac703c13c225603Daniel Veillard NULLCHK(segment) 1848d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, BAD_CAST "#"); 1849d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, segment); 1850d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFree(segment); 1851d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1852d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1853d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFreeURI(uri); 1854d7af555327843a9938a913205ac703c13c225603Daniel Veillard#undef NULLCHK 1855d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1856d7af555327843a9938a913205ac703c13c225603Daniel Veillard return (ret); 1857336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard} 1858336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard 18593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 18603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 18613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Public functions * 18623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 18633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 18643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 18653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 18663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlBuildURI: 18673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @URI: the URI instance found in the document 18683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @base: the base value 18693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 18703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Computes he final URI of the reference done by checking that 18713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the given URI is valid, and building the final URI using the 187257560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * base URI. This is processed according to section 5.2 of the 18733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * RFC 2396 18743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 18753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 5.2. Resolving Relative References to Absolute Form 18763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 18773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns a new URI string (to be freed by the caller) or NULL in case 18783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of error. 18793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 18803473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlChar * 18813473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlBuildURI(const xmlChar *URI, const xmlChar *base) { 18823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *val = NULL; 188356a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard int ret, len, indx, cur, out; 18843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlURIPtr ref = NULL; 18853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlURIPtr bas = NULL; 18863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlURIPtr res = NULL; 18873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 18883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 18893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1) The URI reference is parsed into the potential four components and 18903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * fragment identifier, as described in Section 4.3. 18913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 18923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * NOTE that a completely empty URI is treated by modern browsers 18933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * as a reference to "." rather than as a synonym for the current 18943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * URI. Should we do that here? 18953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 189657560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (URI == NULL) 18973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = -1; 18983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else { 18993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*URI) { 19003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ref = xmlCreateURI(); 19013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ref == NULL) 19023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto done; 19033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = xmlParseURIReference(ref, (const char *) URI); 19043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 19053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 19063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = 0; 19073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 19083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret != 0) 19093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto done; 19107b4b2f9d8fc712c49beaf75985161a130c77d13aDaniel Veillard if ((ref != NULL) && (ref->scheme != NULL)) { 19117b4b2f9d8fc712c49beaf75985161a130c77d13aDaniel Veillard /* 19127b4b2f9d8fc712c49beaf75985161a130c77d13aDaniel Veillard * The URI is absolute don't modify. 19137b4b2f9d8fc712c49beaf75985161a130c77d13aDaniel Veillard */ 19147b4b2f9d8fc712c49beaf75985161a130c77d13aDaniel Veillard val = xmlStrdup(URI); 19157b4b2f9d8fc712c49beaf75985161a130c77d13aDaniel Veillard goto done; 19167b4b2f9d8fc712c49beaf75985161a130c77d13aDaniel Veillard } 19173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (base == NULL) 19183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = -1; 19193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else { 19203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor bas = xmlCreateURI(); 19213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (bas == NULL) 19223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto done; 19233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = xmlParseURIReference(bas, (const char *) base); 19243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 19253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret != 0) { 19263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ref) 19273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val = xmlSaveUri(ref); 19283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto done; 19293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 19303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ref == NULL) { 19313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 19323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the base fragment must be ignored 19333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 19343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (bas->fragment != NULL) { 19353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(bas->fragment); 19363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor bas->fragment = NULL; 19373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 19383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val = xmlSaveUri(bas); 19393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto done; 19403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 19413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 19423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 19433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 2) If the path component is empty and the scheme, authority, and 19443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * query components are undefined, then it is a reference to the 19453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * current document and we are done. Otherwise, the reference URI's 19463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * query and fragment components are defined as found (or not found) 19473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * within the URI reference and not inherited from the base URI. 19483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 19493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * NOTE that in modern browsers, the parsing differs from the above 19503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * in the following aspect: the query component is allowed to be 19513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * defined while still treating this as a reference to the current 19523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * document. 19533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 19543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res = xmlCreateURI(); 19553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (res == NULL) 19563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto done; 19573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ref->scheme == NULL) && (ref->path == NULL) && 19583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((ref->authority == NULL) && (ref->server == NULL))) { 19593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (bas->scheme != NULL) 19603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->scheme = xmlMemStrdup(bas->scheme); 19613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (bas->authority != NULL) 19623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->authority = xmlMemStrdup(bas->authority); 19633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (bas->server != NULL) { 19643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->server = xmlMemStrdup(bas->server); 19653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (bas->user != NULL) 19663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->user = xmlMemStrdup(bas->user); 196757560386503be0fd023f3b7537fd496784f3be18Daniel Veillard res->port = bas->port; 19683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 19693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (bas->path != NULL) 19703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->path = xmlMemStrdup(bas->path); 1971a1413b84f7163d57c6251d5f4251186368efd859Daniel Veillard if (ref->query_raw != NULL) 1972a1413b84f7163d57c6251d5f4251186368efd859Daniel Veillard res->query_raw = xmlMemStrdup (ref->query_raw); 1973a1413b84f7163d57c6251d5f4251186368efd859Daniel Veillard else if (ref->query != NULL) 19743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->query = xmlMemStrdup(ref->query); 1975a1413b84f7163d57c6251d5f4251186368efd859Daniel Veillard else if (bas->query_raw != NULL) 1976a1413b84f7163d57c6251d5f4251186368efd859Daniel Veillard res->query_raw = xmlMemStrdup(bas->query_raw); 19773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (bas->query != NULL) 19783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->query = xmlMemStrdup(bas->query); 19793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ref->fragment != NULL) 19803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->fragment = xmlMemStrdup(ref->fragment); 19813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto step_7; 19823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 19833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 19843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 19853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 3) If the scheme component is defined, indicating that the reference 19863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * starts with a scheme name, then the reference is interpreted as an 19873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * absolute URI and we are done. Otherwise, the reference URI's 19883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * scheme is inherited from the base URI's scheme component. 19893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 19903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ref->scheme != NULL) { 19913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val = xmlSaveUri(ref); 19923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto done; 19933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 19943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (bas->scheme != NULL) 19953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->scheme = xmlMemStrdup(bas->scheme); 199657560386503be0fd023f3b7537fd496784f3be18Daniel Veillard 1997a1413b84f7163d57c6251d5f4251186368efd859Daniel Veillard if (ref->query_raw != NULL) 1998a1413b84f7163d57c6251d5f4251186368efd859Daniel Veillard res->query_raw = xmlMemStrdup(ref->query_raw); 1999a1413b84f7163d57c6251d5f4251186368efd859Daniel Veillard else if (ref->query != NULL) 20009231ff9250af7e22104cc5e9406f0dd43e86aec0Daniel Veillard res->query = xmlMemStrdup(ref->query); 20019231ff9250af7e22104cc5e9406f0dd43e86aec0Daniel Veillard if (ref->fragment != NULL) 20029231ff9250af7e22104cc5e9406f0dd43e86aec0Daniel Veillard res->fragment = xmlMemStrdup(ref->fragment); 20033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 20053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 4) If the authority component is defined, then the reference is a 20063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * network-path and we skip to step 7. Otherwise, the reference 20073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * URI's authority is inherited from the base URI's authority 20083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * component, which will also be undefined if the URI scheme does not 20093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * use an authority component. 20103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 20113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ref->authority != NULL) || (ref->server != NULL)) { 20123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ref->authority != NULL) 20133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->authority = xmlMemStrdup(ref->authority); 20143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else { 20153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->server = xmlMemStrdup(ref->server); 20163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ref->user != NULL) 20173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->user = xmlMemStrdup(ref->user); 201857560386503be0fd023f3b7537fd496784f3be18Daniel Veillard res->port = ref->port; 20193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 20203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ref->path != NULL) 20213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->path = xmlMemStrdup(ref->path); 20223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto step_7; 20233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 20243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (bas->authority != NULL) 20253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->authority = xmlMemStrdup(bas->authority); 20263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (bas->server != NULL) { 20273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->server = xmlMemStrdup(bas->server); 20283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (bas->user != NULL) 20293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->user = xmlMemStrdup(bas->user); 203057560386503be0fd023f3b7537fd496784f3be18Daniel Veillard res->port = bas->port; 20313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 20323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 20343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 5) If the path component begins with a slash character ("/"), then 20353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the reference is an absolute-path and we skip to step 7. 20363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 20373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ref->path != NULL) && (ref->path[0] == '/')) { 20383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->path = xmlMemStrdup(ref->path); 20393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto step_7; 20403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 20413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 20443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 6) If this step is reached, then we are resolving a relative-path 20453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * reference. The relative path needs to be merged with the base 20463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * URI's path. Although there are many ways to do this, we will 20473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * describe a simple method using a separate string buffer. 20483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 20493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Allocate a buffer large enough for the result string. 20503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 20513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor len = 2; /* extra / and 0 */ 20523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ref->path != NULL) 20533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor len += strlen(ref->path); 20543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (bas->path != NULL) 20553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor len += strlen(bas->path); 20563c908dca479ed50dca24b8593bca90e40dbde6b8Daniel Veillard res->path = (char *) xmlMallocAtomic(len); 20573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (res->path == NULL) { 205857560386503be0fd023f3b7537fd496784f3be18Daniel Veillard xmlURIErrMemory("resolving URI against base\n"); 20593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto done; 20603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 20613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->path[0] = 0; 20623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 20643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * a) All but the last segment of the base URI's path component is 20653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * copied to the buffer. In other words, any characters after the 20663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * last (right-most) slash character, if any, are excluded. 20673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 20683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = 0; 20693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor out = 0; 20703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (bas->path != NULL) { 20713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (bas->path[cur] != 0) { 20723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((bas->path[cur] != 0) && (bas->path[cur] != '/')) 20733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 20743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (bas->path[cur] == 0) 20753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 20763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 20783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (out < cur) { 20793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->path[out] = bas->path[out]; 20803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor out++; 20813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 20823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 20833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 20843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->path[out] = 0; 20853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 20873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * b) The reference's path component is appended to the buffer 20883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string. 20893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 20903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ref->path != NULL && ref->path[0] != 0) { 209156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard indx = 0; 20923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 20933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Ensure the path includes a '/' 20943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 20953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((out == 0) && (bas->server != NULL)) 20963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->path[out++] = '/'; 209756a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard while (ref->path[indx] != 0) { 209856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard res->path[out++] = ref->path[indx++]; 20993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 21003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 21013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->path[out] = 0; 21023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 21033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 21043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Steps c) to h) are really path normalization steps 21053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 21063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNormalizeURIPath(res->path); 21073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 21083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstep_7: 21093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 21103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 21113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 7) The resulting URI components, including any inherited from the 21123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * base URI, are recombined to give the absolute form of the URI 21133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * reference. 21143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 21153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val = xmlSaveUri(res); 21163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 21173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylordone: 21183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ref != NULL) 21193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFreeURI(ref); 21203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (bas != NULL) 21213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFreeURI(bas); 21223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (res != NULL) 21233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFreeURI(res); 21243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(val); 21253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 21263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2127f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic/** 2128f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * xmlBuildRelativeURI: 2129f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * @URI: the URI reference under consideration 2130f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * @base: the base value 2131f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * 2132f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * Expresses the URI of the reference in terms relative to the 2133f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * base. Some examples of this operation include: 2134f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * base = "http://site1.com/docs/book1.html" 2135f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * URI input URI returned 2136f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * docs/pic1.gif pic1.gif 2137f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * docs/img/pic1.gif img/pic1.gif 2138f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * img/pic1.gif ../img/pic1.gif 2139f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * http://site1.com/docs/pic1.gif pic1.gif 2140f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * http://site2.com/docs/pic1.gif http://site2.com/docs/pic1.gif 2141f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * 2142f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * base = "docs/book1.html" 2143f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * URI input URI returned 2144f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * docs/pic1.gif pic1.gif 2145f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * docs/img/pic1.gif img/pic1.gif 2146f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * img/pic1.gif ../img/pic1.gif 2147f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * http://site1.com/docs/pic1.gif http://site1.com/docs/pic1.gif 2148f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * 2149f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * 2150f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * Note: if the URI reference is really wierd or complicated, it may be 2151f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * worthwhile to first convert it into a "nice" one by calling 2152f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * xmlBuildURI (using 'base') before calling this routine, 2153f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * since this routine (for reasonable efficiency) assumes URI has 2154f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * already been through some validation. 2155f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * 2156f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * Returns a new URI string (to be freed by the caller) or NULL in case 2157f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * error. 2158f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack */ 2159f7789b13c59ef9d9e73047543c704c6ab21a6212William M. BrackxmlChar * 2160f7789b13c59ef9d9e73047543c704c6ab21a6212William M. BrackxmlBuildRelativeURI (const xmlChar * URI, const xmlChar * base) 2161f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack{ 2162f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack xmlChar *val = NULL; 2163f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack int ret; 2164f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack int ix; 2165f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack int pos = 0; 2166f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack int nbslash = 0; 2167820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack int len; 2168f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack xmlURIPtr ref = NULL; 2169f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack xmlURIPtr bas = NULL; 2170f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack xmlChar *bptr, *uptr, *vptr; 21710f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard int remove_path = 0; 2172f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack 2173f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack if ((URI == NULL) || (*URI == 0)) 2174f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack return NULL; 2175f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack 2176f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack /* 2177f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * First parse URI into a standard form 2178f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack */ 2179f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack ref = xmlCreateURI (); 2180f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack if (ref == NULL) 2181f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack return NULL; 218238c4b332c4ec2f0db5ee601abaa9b46ec2e272e2William M. Brack /* If URI not already in "relative" form */ 218338c4b332c4ec2f0db5ee601abaa9b46ec2e272e2William M. Brack if (URI[0] != '.') { 218438c4b332c4ec2f0db5ee601abaa9b46ec2e272e2William M. Brack ret = xmlParseURIReference (ref, (const char *) URI); 218538c4b332c4ec2f0db5ee601abaa9b46ec2e272e2William M. Brack if (ret != 0) 218638c4b332c4ec2f0db5ee601abaa9b46ec2e272e2William M. Brack goto done; /* Error in URI, return NULL */ 218738c4b332c4ec2f0db5ee601abaa9b46ec2e272e2William M. Brack } else 218838c4b332c4ec2f0db5ee601abaa9b46ec2e272e2William M. Brack ref->path = (char *)xmlStrdup(URI); 2189f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack 2190f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack /* 2191f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * Next parse base into the same standard form 2192f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack */ 2193f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack if ((base == NULL) || (*base == 0)) { 2194f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack val = xmlStrdup (URI); 2195f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack goto done; 2196f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack } 2197f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack bas = xmlCreateURI (); 2198f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack if (bas == NULL) 2199f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack goto done; 220038c4b332c4ec2f0db5ee601abaa9b46ec2e272e2William M. Brack if (base[0] != '.') { 220138c4b332c4ec2f0db5ee601abaa9b46ec2e272e2William M. Brack ret = xmlParseURIReference (bas, (const char *) base); 220238c4b332c4ec2f0db5ee601abaa9b46ec2e272e2William M. Brack if (ret != 0) 220338c4b332c4ec2f0db5ee601abaa9b46ec2e272e2William M. Brack goto done; /* Error in base, return NULL */ 220438c4b332c4ec2f0db5ee601abaa9b46ec2e272e2William M. Brack } else 220538c4b332c4ec2f0db5ee601abaa9b46ec2e272e2William M. Brack bas->path = (char *)xmlStrdup(base); 2206f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack 2207f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack /* 2208f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * If the scheme / server on the URI differs from the base, 2209f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * just return the URI 2210f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack */ 2211f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack if ((ref->scheme != NULL) && 22120f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard ((bas->scheme == NULL) || 22130f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard (xmlStrcmp ((xmlChar *)bas->scheme, (xmlChar *)ref->scheme)) || 22140f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard (xmlStrcmp ((xmlChar *)bas->server, (xmlChar *)ref->server)))) { 2215f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack val = xmlStrdup (URI); 2216f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack goto done; 2217f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack } 22180f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard if (xmlStrEqual((xmlChar *)bas->path, (xmlChar *)ref->path)) { 22190f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard val = xmlStrdup(BAD_CAST ""); 22200f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard goto done; 22210f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard } 22220f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard if (bas->path == NULL) { 22230f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard val = xmlStrdup((xmlChar *)ref->path); 22240f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard goto done; 22250f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard } 22260f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard if (ref->path == NULL) { 22270f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard ref->path = (char *) "/"; 22280f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard remove_path = 1; 22290f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard } 2230f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack 2231f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack /* 2232f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * At this point (at last!) we can compare the two paths 2233f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * 2234820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack * First we take care of the special case where either of the 2235820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack * two path components may be missing (bug 316224) 2236f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack */ 2237820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack if (bas->path == NULL) { 2238820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack if (ref->path != NULL) { 22390f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard uptr = (xmlChar *) ref->path; 2240820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack if (*uptr == '/') 2241820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack uptr++; 2242504201966dbcc76b0d3c60d85e36133188620f6cWilliam M. Brack /* exception characters from xmlSaveUri */ 2243504201966dbcc76b0d3c60d85e36133188620f6cWilliam M. Brack val = xmlURIEscapeStr(uptr, BAD_CAST "/;&=+$,"); 2244820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack } 2245820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack goto done; 2246f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack } 2247820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack bptr = (xmlChar *)bas->path; 2248820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack if (ref->path == NULL) { 2249820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack for (ix = 0; bptr[ix] != 0; ix++) { 2250820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack if (bptr[ix] == '/') 2251820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack nbslash++; 2252820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack } 2253820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack uptr = NULL; 2254820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack len = 1; /* this is for a string terminator only */ 2255f2a657aa599bf9e9a1cbf4082ba885d177f05697William M. Brack } else { 2256f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack /* 2257820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack * Next we compare the two strings and find where they first differ 2258f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack */ 2259820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack if ((ref->path[pos] == '.') && (ref->path[pos+1] == '/')) 2260820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack pos += 2; 2261820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack if ((*bptr == '.') && (bptr[1] == '/')) 2262820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack bptr += 2; 2263820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack else if ((*bptr == '/') && (ref->path[pos] != '/')) 2264820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack bptr++; 2265820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack while ((bptr[pos] == ref->path[pos]) && (bptr[pos] != 0)) 2266820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack pos++; 2267820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack 2268820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack if (bptr[pos] == ref->path[pos]) { 22690f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard val = xmlStrdup(BAD_CAST ""); 2270820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack goto done; /* (I can't imagine why anyone would do this) */ 2271820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack } 2272820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack 2273820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack /* 2274820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack * In URI, "back up" to the last '/' encountered. This will be the 2275820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack * beginning of the "unique" suffix of URI 2276820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack */ 2277820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack ix = pos; 2278820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack if ((ref->path[ix] == '/') && (ix > 0)) 2279820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack ix--; 22800f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard else if ((ref->path[ix] == 0) && (ix > 1) && (ref->path[ix - 1] == '/')) 22810f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard ix -= 2; 2282820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack for (; ix > 0; ix--) { 2283820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack if (ref->path[ix] == '/') 2284820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack break; 2285820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack } 2286820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack if (ix == 0) { 2287820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack uptr = (xmlChar *)ref->path; 2288820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack } else { 2289820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack ix++; 2290820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack uptr = (xmlChar *)&ref->path[ix]; 2291f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack } 2292f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack 2293820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack /* 2294820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack * In base, count the number of '/' from the differing point 2295820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack */ 2296820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack if (bptr[pos] != ref->path[pos]) {/* check for trivial URI == base */ 2297820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack for (; bptr[ix] != 0; ix++) { 2298820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack if (bptr[ix] == '/') 2299820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack nbslash++; 2300820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack } 2301820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack } 2302820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack len = xmlStrlen (uptr) + 1; 2303820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack } 230457560386503be0fd023f3b7537fd496784f3be18Daniel Veillard 2305f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack if (nbslash == 0) { 2306820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack if (uptr != NULL) 2307504201966dbcc76b0d3c60d85e36133188620f6cWilliam M. Brack /* exception characters from xmlSaveUri */ 2308504201966dbcc76b0d3c60d85e36133188620f6cWilliam M. Brack val = xmlURIEscapeStr(uptr, BAD_CAST "/;&=+$,"); 2309f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack goto done; 2310f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack } 2311f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack 2312f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack /* 2313f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * Allocate just enough space for the returned string - 2314f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * length of the remainder of the URI, plus enough space 2315f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * for the "../" groups, plus one for the terminator 2316f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack */ 2317820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack val = (xmlChar *) xmlMalloc (len + 3 * nbslash); 2318f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack if (val == NULL) { 231957560386503be0fd023f3b7537fd496784f3be18Daniel Veillard xmlURIErrMemory("building relative URI\n"); 2320f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack goto done; 2321f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack } 2322f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack vptr = val; 2323f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack /* 2324f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * Put in as many "../" as needed 2325f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack */ 2326f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack for (; nbslash>0; nbslash--) { 2327f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack *vptr++ = '.'; 2328f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack *vptr++ = '.'; 2329f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack *vptr++ = '/'; 2330f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack } 2331f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack /* 2332f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * Finish up with the end of the URI 2333f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack */ 23340f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard if (uptr != NULL) { 23350f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard if ((vptr > val) && (len > 0) && 23360f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard (uptr[0] == '/') && (vptr[-1] == '/')) { 23370f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard memcpy (vptr, uptr + 1, len - 1); 23380f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard vptr[len - 2] = 0; 23390f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard } else { 23400f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard memcpy (vptr, uptr, len); 23410f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard vptr[len - 1] = 0; 23420f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard } 23430f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard } else { 2344820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack vptr[len - 1] = 0; 23450f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard } 2346f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack 2347504201966dbcc76b0d3c60d85e36133188620f6cWilliam M. Brack /* escape the freshly-built path */ 2348504201966dbcc76b0d3c60d85e36133188620f6cWilliam M. Brack vptr = val; 2349504201966dbcc76b0d3c60d85e36133188620f6cWilliam M. Brack /* exception characters from xmlSaveUri */ 2350504201966dbcc76b0d3c60d85e36133188620f6cWilliam M. Brack val = xmlURIEscapeStr(vptr, BAD_CAST "/;&=+$,"); 2351504201966dbcc76b0d3c60d85e36133188620f6cWilliam M. Brack xmlFree(vptr); 2352504201966dbcc76b0d3c60d85e36133188620f6cWilliam M. Brack 23530f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillarddone: 2354f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack /* 2355f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * Free the working variables 2356f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack */ 23570f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard if (remove_path != 0) 23580f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard ref->path = NULL; 2359f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack if (ref != NULL) 2360f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack xmlFreeURI (ref); 2361f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack if (bas != NULL) 2362f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack xmlFreeURI (bas); 2363f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack 2364f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack return val; 2365f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack} 2366f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack 2367f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack/** 2368f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic * xmlCanonicPath: 2369f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic * @path: the resource locator in a filesystem notation 2370f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic * 237157560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * Constructs a canonic path from the specified path. 2372f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic * 237357560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * Returns a new canonic path, or a duplicate of the path parameter if the 2374f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic * construction fails. The caller is responsible for freeing the memory occupied 237557560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * by the returned string. If there is insufficient memory available, or the 2376f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic * argument is NULL, the function returns NULL. 2377f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic */ 237857560386503be0fd023f3b7537fd496784f3be18Daniel Veillard#define IS_WINDOWS_PATH(p) \ 2379f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic ((p != NULL) && \ 2380f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic (((p[0] >= 'a') && (p[0] <= 'z')) || \ 2381f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic ((p[0] >= 'A') && (p[0] <= 'Z'))) && \ 2382f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic (p[1] == ':') && ((p[2] == '/') || (p[2] == '\\'))) 2383b8efdda0a31947d5291fcb9221040fdab88dc549Daniel VeillardxmlChar * 2384f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor ZlatkovicxmlCanonicPath(const xmlChar *path) 2385f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic{ 23862224227818b8196ea9250235038e069f6bc03a55William M. Brack/* 23872224227818b8196ea9250235038e069f6bc03a55William M. Brack * For Windows implementations, additional work needs to be done to 23882224227818b8196ea9250235038e069f6bc03a55William M. Brack * replace backslashes in pathnames with "forward slashes" 23892224227818b8196ea9250235038e069f6bc03a55William M. Brack */ 239057560386503be0fd023f3b7537fd496784f3be18Daniel Veillard#if defined(_WIN32) && !defined(__CYGWIN__) 2391ce07616c089bf22653e31e2f7286cfdd8462857fIgor Zlatkovic int len = 0; 2392ce07616c089bf22653e31e2f7286cfdd8462857fIgor Zlatkovic int i = 0; 2393ce07616c089bf22653e31e2f7286cfdd8462857fIgor Zlatkovic xmlChar *p = NULL; 2394c64b8e984c13a0d989dea436c13128b289a4d4d6Daniel Veillard#endif 2395f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic xmlURIPtr uri; 2396336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard xmlChar *ret; 2397336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard const xmlChar *absuri; 2398f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic 2399f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic if (path == NULL) 2400f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic return(NULL); 240169f8a13e52d4d4afd34e7642ce99c9cd0fcd8f03Daniel Veillard 240255b899a23acfa2e1bb36026b50a8f7cb36dc4fdaMichael Stahl#if defined(_WIN32) 240355b899a23acfa2e1bb36026b50a8f7cb36dc4fdaMichael Stahl /* 240455b899a23acfa2e1bb36026b50a8f7cb36dc4fdaMichael Stahl * We must not change the backslashes to slashes if the the path 240555b899a23acfa2e1bb36026b50a8f7cb36dc4fdaMichael Stahl * starts with \\?\ 240655b899a23acfa2e1bb36026b50a8f7cb36dc4fdaMichael Stahl * Those paths can be up to 32k characters long. 240755b899a23acfa2e1bb36026b50a8f7cb36dc4fdaMichael Stahl * Was added specifically for OpenOffice, those paths can't be converted 240855b899a23acfa2e1bb36026b50a8f7cb36dc4fdaMichael Stahl * to URIs anyway. 240955b899a23acfa2e1bb36026b50a8f7cb36dc4fdaMichael Stahl */ 241055b899a23acfa2e1bb36026b50a8f7cb36dc4fdaMichael Stahl if ((path[0] == '\\') && (path[1] == '\\') && (path[2] == '?') && 241155b899a23acfa2e1bb36026b50a8f7cb36dc4fdaMichael Stahl (path[3] == '\\') ) 241255b899a23acfa2e1bb36026b50a8f7cb36dc4fdaMichael Stahl return xmlStrdup((const xmlChar *) path); 241355b899a23acfa2e1bb36026b50a8f7cb36dc4fdaMichael Stahl#endif 241455b899a23acfa2e1bb36026b50a8f7cb36dc4fdaMichael Stahl 241555b899a23acfa2e1bb36026b50a8f7cb36dc4fdaMichael Stahl /* sanitize filename starting with // so it can be used as URI */ 241669f8a13e52d4d4afd34e7642ce99c9cd0fcd8f03Daniel Veillard if ((path[0] == '/') && (path[1] == '/') && (path[2] != '/')) 241769f8a13e52d4d4afd34e7642ce99c9cd0fcd8f03Daniel Veillard path++; 241869f8a13e52d4d4afd34e7642ce99c9cd0fcd8f03Daniel Veillard 2419c64b8e984c13a0d989dea436c13128b289a4d4d6Daniel Veillard if ((uri = xmlParseURI((const char *) path)) != NULL) { 2420f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic xmlFreeURI(uri); 2421f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic return xmlStrdup(path); 2422f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic } 2423f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic 24242224227818b8196ea9250235038e069f6bc03a55William M. Brack /* Check if this is an "absolute uri" */ 2425336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard absuri = xmlStrstr(path, BAD_CAST "://"); 2426336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard if (absuri != NULL) { 2427336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard int l, j; 2428336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard unsigned char c; 2429336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard xmlChar *escURI; 2430336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard 2431336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard /* 2432336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard * this looks like an URI where some parts have not been 24332224227818b8196ea9250235038e069f6bc03a55William M. Brack * escaped leading to a parsing problem. Check that the first 2434336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard * part matches a protocol. 2435336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard */ 2436336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard l = absuri - path; 24372224227818b8196ea9250235038e069f6bc03a55William M. Brack /* Bypass if first part (part before the '://') is > 20 chars */ 2438336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard if ((l <= 0) || (l > 20)) 2439336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard goto path_processing; 24402224227818b8196ea9250235038e069f6bc03a55William M. Brack /* Bypass if any non-alpha characters are present in first part */ 2441336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard for (j = 0;j < l;j++) { 2442336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard c = path[j]; 2443336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard if (!(((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')))) 2444336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard goto path_processing; 2445336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard } 2446336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard 24472224227818b8196ea9250235038e069f6bc03a55William M. Brack /* Escape all except the characters specified in the supplied path */ 2448336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard escURI = xmlURIEscapeStr(path, BAD_CAST ":/?_.#&;="); 2449336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard if (escURI != NULL) { 24502224227818b8196ea9250235038e069f6bc03a55William M. Brack /* Try parsing the escaped path */ 2451336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard uri = xmlParseURI((const char *) escURI); 24522224227818b8196ea9250235038e069f6bc03a55William M. Brack /* If successful, return the escaped string */ 2453336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard if (uri != NULL) { 2454336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard xmlFreeURI(uri); 2455336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard return escURI; 2456336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard } 2457336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard } 2458336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard } 2459336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard 2460336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillardpath_processing: 24612224227818b8196ea9250235038e069f6bc03a55William M. Brack/* For Windows implementations, replace backslashes with 'forward slashes' */ 246257560386503be0fd023f3b7537fd496784f3be18Daniel Veillard#if defined(_WIN32) && !defined(__CYGWIN__) 2463336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard /* 24642224227818b8196ea9250235038e069f6bc03a55William M. Brack * Create a URI structure 2465336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard */ 2466f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic uri = xmlCreateURI(); 24672224227818b8196ea9250235038e069f6bc03a55William M. Brack if (uri == NULL) { /* Guard against 'out of memory' */ 2468a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(NULL); 2469a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard } 2470f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic 2471f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic len = xmlStrlen(path); 2472f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic if ((len > 2) && IS_WINDOWS_PATH(path)) { 24732224227818b8196ea9250235038e069f6bc03a55William M. Brack /* make the scheme 'file' */ 2474f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic uri->scheme = xmlStrdup(BAD_CAST "file"); 24752224227818b8196ea9250235038e069f6bc03a55William M. Brack /* allocate space for leading '/' + path + string terminator */ 2476b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard uri->path = xmlMallocAtomic(len + 2); 2477b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard if (uri->path == NULL) { 24782224227818b8196ea9250235038e069f6bc03a55William M. Brack xmlFreeURI(uri); /* Guard agains 'out of memory' */ 2479b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard return(NULL); 2480b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard } 24812224227818b8196ea9250235038e069f6bc03a55William M. Brack /* Put in leading '/' plus path */ 2482f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic uri->path[0] = '/'; 2483ce07616c089bf22653e31e2f7286cfdd8462857fIgor Zlatkovic p = uri->path + 1; 2484ce07616c089bf22653e31e2f7286cfdd8462857fIgor Zlatkovic strncpy(p, path, len + 1); 2485ce07616c089bf22653e31e2f7286cfdd8462857fIgor Zlatkovic } else { 2486b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard uri->path = xmlStrdup(path); 2487b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard if (uri->path == NULL) { 2488b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard xmlFreeURI(uri); 2489b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard return(NULL); 2490b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard } 2491ce07616c089bf22653e31e2f7286cfdd8462857fIgor Zlatkovic p = uri->path; 2492ce07616c089bf22653e31e2f7286cfdd8462857fIgor Zlatkovic } 24932224227818b8196ea9250235038e069f6bc03a55William M. Brack /* Now change all occurences of '\' to '/' */ 2494ce07616c089bf22653e31e2f7286cfdd8462857fIgor Zlatkovic while (*p != '\0') { 2495ce07616c089bf22653e31e2f7286cfdd8462857fIgor Zlatkovic if (*p == '\\') 2496ce07616c089bf22653e31e2f7286cfdd8462857fIgor Zlatkovic *p = '/'; 2497ce07616c089bf22653e31e2f7286cfdd8462857fIgor Zlatkovic p++; 2498ce07616c089bf22653e31e2f7286cfdd8462857fIgor Zlatkovic } 24998f3392ef69ec36d34a389336c4df66bcce26969bDaniel Veillard 2500b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard if (uri->scheme == NULL) { 25012224227818b8196ea9250235038e069f6bc03a55William M. Brack ret = xmlStrdup((const xmlChar *) uri->path); 2502b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard } else { 2503b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard ret = xmlSaveUri(uri); 2504b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard } 25058f3392ef69ec36d34a389336c4df66bcce26969bDaniel Veillard 2506f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic xmlFreeURI(uri); 2507336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard#else 2508336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard ret = xmlStrdup((const xmlChar *) path); 2509336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard#endif 2510f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic return(ret); 2511f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic} 25123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2513b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard/** 2514b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard * xmlPathToURI: 2515b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard * @path: the resource locator in a filesystem notation 2516b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard * 2517b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard * Constructs an URI expressing the existing path 2518b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard * 251957560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * Returns a new URI, or a duplicate of the path parameter if the 2520b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard * construction fails. The caller is responsible for freeing the memory 2521b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard * occupied by the returned string. If there is insufficient memory available, 2522b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard * or the argument is NULL, the function returns NULL. 2523b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard */ 2524b8efdda0a31947d5291fcb9221040fdab88dc549Daniel VeillardxmlChar * 2525b8efdda0a31947d5291fcb9221040fdab88dc549Daniel VeillardxmlPathToURI(const xmlChar *path) 2526b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard{ 2527b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard xmlURIPtr uri; 2528b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard xmlURI temp; 2529b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard xmlChar *ret, *cal; 2530b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard 2531b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard if (path == NULL) 2532b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard return(NULL); 2533b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard 2534b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard if ((uri = xmlParseURI((const char *) path)) != NULL) { 2535b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard xmlFreeURI(uri); 2536b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard return xmlStrdup(path); 2537b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard } 2538b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard cal = xmlCanonicPath(path); 2539b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard if (cal == NULL) 2540b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard return(NULL); 2541481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard#if defined(_WIN32) && !defined(__CYGWIN__) 254257560386503be0fd023f3b7537fd496784f3be18Daniel Veillard /* xmlCanonicPath can return an URI on Windows (is that the intended behaviour?) 2543481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard If 'cal' is a valid URI allready then we are done here, as continuing would make 2544481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard it invalid. */ 2545481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard if ((uri = xmlParseURI((const char *) cal)) != NULL) { 2546481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard xmlFreeURI(uri); 2547481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard return cal; 2548481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard } 2549481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard /* 'cal' can contain a relative path with backslashes. If that is processed 2550481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard by xmlSaveURI, they will be escaped and the external entity loader machinery 2551481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard will fail. So convert them to slashes. Misuse 'ret' for walking. */ 2552481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard ret = cal; 2553481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard while (*ret != '\0') { 2554481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard if (*ret == '\\') 2555481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard *ret = '/'; 2556481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard ret++; 2557481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard } 2558481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard#endif 2559b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard memset(&temp, 0, sizeof(temp)); 2560b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard temp.path = (char *) cal; 2561b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard ret = xmlSaveUri(&temp); 2562b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard xmlFree(cal); 2563b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard return(ret); 2564b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard} 25655d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard#define bottom_uri 25665d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard#include "elfgcchack.h" 2567