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> 1522e01bd4c5bc675bd3313404abb570a865917859Brian C. Young#include <limits.h> 163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/xmlmemory.h> 183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/uri.h> 19d0463560300f1d8b3e41d70c3728ed84fdc8dd30Daniel Veillard#include <libxml/globals.h> 203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/xmlerror.h> 213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2257560386503be0fd023f3b7537fd496784f3be18Daniel Veillard/** 2357560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * MAX_URI_LENGTH: 2457560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * 2557560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * The definition of the URI regexp in the above RFC has no size limit 2657560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * In practice they are usually relativey short except for the 2757560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * data URI scheme as defined in RFC 2397. Even for data URI the usual 2857560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * maximum size before hitting random practical limits is around 64 KB 2957560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * and 4KB is usually a maximum admitted limit for proper operations. 3057560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * The value below is more a security limit than anything else and 3157560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * really should never be hit by 'normal' operations 3257560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * Set to 1 MByte in 2012, this is only enforced on output 3357560386503be0fd023f3b7537fd496784f3be18Daniel Veillard */ 3457560386503be0fd023f3b7537fd496784f3be18Daniel Veillard#define MAX_URI_LENGTH 1024 * 1024 3557560386503be0fd023f3b7537fd496784f3be18Daniel Veillard 3657560386503be0fd023f3b7537fd496784f3be18Daniel Veillardstatic void 3757560386503be0fd023f3b7537fd496784f3be18Daniel VeillardxmlURIErrMemory(const char *extra) 3857560386503be0fd023f3b7537fd496784f3be18Daniel Veillard{ 3957560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (extra) 4057560386503be0fd023f3b7537fd496784f3be18Daniel Veillard __xmlRaiseError(NULL, NULL, NULL, 4157560386503be0fd023f3b7537fd496784f3be18Daniel Veillard NULL, NULL, XML_FROM_URI, 4257560386503be0fd023f3b7537fd496784f3be18Daniel Veillard XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, 4357560386503be0fd023f3b7537fd496784f3be18Daniel Veillard extra, NULL, NULL, 0, 0, 4457560386503be0fd023f3b7537fd496784f3be18Daniel Veillard "Memory allocation failed : %s\n", extra); 4557560386503be0fd023f3b7537fd496784f3be18Daniel Veillard else 4657560386503be0fd023f3b7537fd496784f3be18Daniel Veillard __xmlRaiseError(NULL, NULL, NULL, 4757560386503be0fd023f3b7537fd496784f3be18Daniel Veillard NULL, NULL, XML_FROM_URI, 4857560386503be0fd023f3b7537fd496784f3be18Daniel Veillard XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, 4957560386503be0fd023f3b7537fd496784f3be18Daniel Veillard NULL, NULL, NULL, 0, 0, 5057560386503be0fd023f3b7537fd496784f3be18Daniel Veillard "Memory allocation failed\n"); 5157560386503be0fd023f3b7537fd496784f3be18Daniel Veillard} 5257560386503be0fd023f3b7537fd496784f3be18Daniel Veillard 53d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic void xmlCleanURI(xmlURIPtr uri); 543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 56d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Old rule from 2396 used in legacy handling code 573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * alpha = lowalpha | upalpha 583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define IS_ALPHA(x) (IS_LOWALPHA(x) || IS_UPALPHA(x)) 603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | 643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | 653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * "u" | "v" | "w" | "x" | "y" | "z" 663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define IS_LOWALPHA(x) (((x) >= 'a') && ((x) <= 'z')) 693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * upalpha = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | 723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | 733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * "U" | "V" | "W" | "X" | "Y" | "Z" 743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define IS_UPALPHA(x) (((x) >= 'A') && ((x) <= 'Z')) 763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 77be3eb2088e3e27b897b57855382f80a737f974ceDaniel Veillard#ifdef IS_DIGIT 78be3eb2088e3e27b897b57855382f80a737f974ceDaniel Veillard#undef IS_DIGIT 79be3eb2088e3e27b897b57855382f80a737f974ceDaniel Veillard#endif 803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" 823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define IS_DIGIT(x) (((x) >= '0') && ((x) <= '9')) 843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * alphanum = alpha | digit 873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define IS_ALPHANUM(x) (IS_ALPHA(x) || IS_DIGIT(x)) 903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" 933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 95d7af555327843a9938a913205ac703c13c225603Daniel Veillard#define IS_MARK(x) (((x) == '-') || ((x) == '_') || ((x) == '.') || \ 96d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((x) == '!') || ((x) == '~') || ((x) == '*') || ((x) == '\'') || \ 973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((x) == '(') || ((x) == ')')) 983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 99d7af555327843a9938a913205ac703c13c225603Daniel Veillard/* 100d7af555327843a9938a913205ac703c13c225603Daniel Veillard * unwise = "{" | "}" | "|" | "\" | "^" | "`" 101d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 1023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 103d7af555327843a9938a913205ac703c13c225603Daniel Veillard#define IS_UNWISE(p) \ 104d7af555327843a9938a913205ac703c13c225603Daniel Veillard (((*(p) == '{')) || ((*(p) == '}')) || ((*(p) == '|')) || \ 105d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == '\\')) || ((*(p) == '^')) || ((*(p) == '[')) || \ 106d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == ']')) || ((*(p) == '`'))) 1073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 108015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack * reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | "," | 109d7af555327843a9938a913205ac703c13c225603Daniel Veillard * "[" | "]" 1103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 112d7af555327843a9938a913205ac703c13c225603Daniel Veillard#define IS_RESERVED(x) (((x) == ';') || ((x) == '/') || ((x) == '?') || \ 113d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((x) == ':') || ((x) == '@') || ((x) == '&') || ((x) == '=') || \ 114d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((x) == '+') || ((x) == '$') || ((x) == ',') || ((x) == '[') || \ 115d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((x) == ']')) 1163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 1183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * unreserved = alphanum | mark 1193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define IS_UNRESERVED(x) (IS_ALPHANUM(x) || IS_MARK(x)) 1223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 124d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Skip to next pointer char, handle escaped sequences 1253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 127d7af555327843a9938a913205ac703c13c225603Daniel Veillard#define NEXT(p) ((*p == '%')? p += 3 : p++) 1283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 130d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Productions from the spec. 131d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 132d7af555327843a9938a913205ac703c13c225603Daniel Veillard * authority = server | reg_name 133d7af555327843a9938a913205ac703c13c225603Daniel Veillard * reg_name = 1*( unreserved | escaped | "$" | "," | 134d7af555327843a9938a913205ac703c13c225603Daniel Veillard * ";" | ":" | "@" | "&" | "=" | "+" ) 135d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 136d7af555327843a9938a913205ac703c13c225603Daniel Veillard * path = [ abs_path | opaque_part ] 1373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 138d7af555327843a9938a913205ac703c13c225603Daniel Veillard 139d7af555327843a9938a913205ac703c13c225603Daniel Veillard#define STRNDUP(s, n) (char *) xmlStrndup((const xmlChar *)(s), (n)) 140d7af555327843a9938a913205ac703c13c225603Daniel Veillard 141d7af555327843a9938a913205ac703c13c225603Daniel Veillard/************************************************************************ 142d7af555327843a9938a913205ac703c13c225603Daniel Veillard * * 143d7af555327843a9938a913205ac703c13c225603Daniel Veillard * RFC 3986 parser * 144d7af555327843a9938a913205ac703c13c225603Daniel Veillard * * 145d7af555327843a9938a913205ac703c13c225603Daniel Veillard ************************************************************************/ 146d7af555327843a9938a913205ac703c13c225603Daniel Veillard 147d7af555327843a9938a913205ac703c13c225603Daniel Veillard#define ISA_DIGIT(p) ((*(p) >= '0') && (*(p) <= '9')) 148d7af555327843a9938a913205ac703c13c225603Daniel Veillard#define ISA_ALPHA(p) (((*(p) >= 'a') && (*(p) <= 'z')) || \ 149d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) >= 'A') && (*(p) <= 'Z'))) 150d7af555327843a9938a913205ac703c13c225603Daniel Veillard#define ISA_HEXDIG(p) \ 151d7af555327843a9938a913205ac703c13c225603Daniel Veillard (ISA_DIGIT(p) || ((*(p) >= 'a') && (*(p) <= 'f')) || \ 152d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) >= 'A') && (*(p) <= 'F'))) 1533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 155d7af555327843a9938a913205ac703c13c225603Daniel Veillard * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" 156d7af555327843a9938a913205ac703c13c225603Daniel Veillard * / "*" / "+" / "," / ";" / "=" 1573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 158d7af555327843a9938a913205ac703c13c225603Daniel Veillard#define ISA_SUB_DELIM(p) \ 159d7af555327843a9938a913205ac703c13c225603Daniel Veillard (((*(p) == '!')) || ((*(p) == '$')) || ((*(p) == '&')) || \ 160d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == '(')) || ((*(p) == ')')) || ((*(p) == '*')) || \ 161d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == '+')) || ((*(p) == ',')) || ((*(p) == ';')) || \ 1622ee91eb6587191de876dbcf147d99bc9b8c7799dDaniel Veillard ((*(p) == '=')) || ((*(p) == '\''))) 1633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 165d7af555327843a9938a913205ac703c13c225603Daniel Veillard * gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" 1663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 167d7af555327843a9938a913205ac703c13c225603Daniel Veillard#define ISA_GEN_DELIM(p) \ 168d7af555327843a9938a913205ac703c13c225603Daniel Veillard (((*(p) == ':')) || ((*(p) == '/')) || ((*(p) == '?')) || \ 169d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == '#')) || ((*(p) == '[')) || ((*(p) == ']')) || \ 170d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == '@'))) 1713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 173d7af555327843a9938a913205ac703c13c225603Daniel Veillard * reserved = gen-delims / sub-delims 1743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 175d7af555327843a9938a913205ac703c13c225603Daniel Veillard#define ISA_RESERVED(p) (ISA_GEN_DELIM(p) || (ISA_SUB_DELIM(p))) 1763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 178d7af555327843a9938a913205ac703c13c225603Daniel Veillard * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" 1793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 180d7af555327843a9938a913205ac703c13c225603Daniel Veillard#define ISA_UNRESERVED(p) \ 181d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((ISA_ALPHA(p)) || (ISA_DIGIT(p)) || ((*(p) == '-')) || \ 182d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == '.')) || ((*(p) == '_')) || ((*(p) == '~'))) 1833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 185d7af555327843a9938a913205ac703c13c225603Daniel Veillard * pct-encoded = "%" HEXDIG HEXDIG 1863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 187d7af555327843a9938a913205ac703c13c225603Daniel Veillard#define ISA_PCT_ENCODED(p) \ 188d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == '%') && (ISA_HEXDIG(p + 1)) && (ISA_HEXDIG(p + 2))) 1893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* 191d7af555327843a9938a913205ac703c13c225603Daniel Veillard * pchar = unreserved / pct-encoded / sub-delims / ":" / "@" 1923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 193d7af555327843a9938a913205ac703c13c225603Daniel Veillard#define ISA_PCHAR(p) \ 194d7af555327843a9938a913205ac703c13c225603Daniel Veillard (ISA_UNRESERVED(p) || ISA_PCT_ENCODED(p) || ISA_SUB_DELIM(p) || \ 195d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == ':')) || ((*(p) == '@'))) 1963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 197d7af555327843a9938a913205ac703c13c225603Daniel Veillard/** 198d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986Scheme: 199d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an URI structure 200d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: pointer to the string to analyze 201d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 202d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse an URI scheme 203d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 204d7af555327843a9938a913205ac703c13c225603Daniel Veillard * ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) 205d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 206d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 207d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 208d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 209d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986Scheme(xmlURIPtr uri, const char **str) { 210d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *cur; 2113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 212d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (str == NULL) 213d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(-1); 214bb6808ea16b16055727ceb73d45a7f748b14ccfdDaniel Veillard 215d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = *str; 216d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (!ISA_ALPHA(cur)) 217d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(2); 218d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur++; 219d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (ISA_ALPHA(cur) || ISA_DIGIT(cur) || 220d7af555327843a9938a913205ac703c13c225603Daniel Veillard (*cur == '+') || (*cur == '-') || (*cur == '.')) cur++; 221d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri != NULL) { 222d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->scheme != NULL) xmlFree(uri->scheme); 223d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->scheme = STRNDUP(*str, cur - *str); 224d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 225d7af555327843a9938a913205ac703c13c225603Daniel Veillard *str = cur; 226d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(0); 227d7af555327843a9938a913205ac703c13c225603Daniel Veillard} 228bb6808ea16b16055727ceb73d45a7f748b14ccfdDaniel Veillard 229d7af555327843a9938a913205ac703c13c225603Daniel Veillard/** 230d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986Fragment: 231d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an URI structure 232d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: pointer to the string to analyze 233d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 234d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse the query part of an URI 235d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 23684c45df8d88f2b44f9c16474795fa2d30265bc21Daniel Veillard * fragment = *( pchar / "/" / "?" ) 23784c45df8d88f2b44f9c16474795fa2d30265bc21Daniel Veillard * NOTE: the strict syntax as defined by 3986 does not allow '[' and ']' 23884c45df8d88f2b44f9c16474795fa2d30265bc21Daniel Veillard * in the fragment identifier but this is used very broadly for 23984c45df8d88f2b44f9c16474795fa2d30265bc21Daniel Veillard * xpointer scheme selection, so we are allowing it here to not break 24084c45df8d88f2b44f9c16474795fa2d30265bc21Daniel Veillard * for example all the DocBook processing chains. 241d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 242d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 2433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 244d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 245d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986Fragment(xmlURIPtr uri, const char **str) 246d7af555327843a9938a913205ac703c13c225603Daniel Veillard{ 247d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *cur; 2483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 249d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (str == NULL) 250d7af555327843a9938a913205ac703c13c225603Daniel Veillard return (-1); 2513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 252d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = *str; 253d7af555327843a9938a913205ac703c13c225603Daniel Veillard 254d7af555327843a9938a913205ac703c13c225603Daniel Veillard while ((ISA_PCHAR(cur)) || (*cur == '/') || (*cur == '?') || 25584c45df8d88f2b44f9c16474795fa2d30265bc21Daniel Veillard (*cur == '[') || (*cur == ']') || 256d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((uri != NULL) && (uri->cleanup & 1) && (IS_UNWISE(cur)))) 257d7af555327843a9938a913205ac703c13c225603Daniel Veillard NEXT(cur); 258d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri != NULL) { 259d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->fragment != NULL) 260d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFree(uri->fragment); 261d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->cleanup & 2) 262d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->fragment = STRNDUP(*str, cur - *str); 263d7af555327843a9938a913205ac703c13c225603Daniel Veillard else 264d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->fragment = xmlURIUnescapeString(*str, cur - *str, NULL); 265d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 266d7af555327843a9938a913205ac703c13c225603Daniel Veillard *str = cur; 267d7af555327843a9938a913205ac703c13c225603Daniel Veillard return (0); 268d7af555327843a9938a913205ac703c13c225603Daniel Veillard} 269d7af555327843a9938a913205ac703c13c225603Daniel Veillard 270d7af555327843a9938a913205ac703c13c225603Daniel Veillard/** 271d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986Query: 272d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an URI structure 273d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: pointer to the string to analyze 2743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 275d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse the query part of an URI 2763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 277d7af555327843a9938a913205ac703c13c225603Daniel Veillard * query = *uric 278d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 279d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 2803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 281d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 282d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986Query(xmlURIPtr uri, const char **str) 283d7af555327843a9938a913205ac703c13c225603Daniel Veillard{ 284d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *cur; 2853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 286d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (str == NULL) 287d7af555327843a9938a913205ac703c13c225603Daniel Veillard return (-1); 288336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard 289d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = *str; 290d7af555327843a9938a913205ac703c13c225603Daniel Veillard 291d7af555327843a9938a913205ac703c13c225603Daniel Veillard while ((ISA_PCHAR(cur)) || (*cur == '/') || (*cur == '?') || 292d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((uri != NULL) && (uri->cleanup & 1) && (IS_UNWISE(cur)))) 293d7af555327843a9938a913205ac703c13c225603Daniel Veillard NEXT(cur); 294d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri != NULL) { 295d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->query != NULL) 296d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFree(uri->query); 297d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->cleanup & 2) 298d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->query = STRNDUP(*str, cur - *str); 299d7af555327843a9938a913205ac703c13c225603Daniel Veillard else 300d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->query = xmlURIUnescapeString(*str, cur - *str, NULL); 301d7af555327843a9938a913205ac703c13c225603Daniel Veillard 302d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* Save the raw bytes of the query as well. 303d7af555327843a9938a913205ac703c13c225603Daniel Veillard * See: http://mail.gnome.org/archives/xml/2007-April/thread.html#00114 304d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 305d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->query_raw != NULL) 306d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFree (uri->query_raw); 307d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->query_raw = STRNDUP (*str, cur - *str); 308d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 309d7af555327843a9938a913205ac703c13c225603Daniel Veillard *str = cur; 310d7af555327843a9938a913205ac703c13c225603Daniel Veillard return (0); 311d7af555327843a9938a913205ac703c13c225603Daniel Veillard} 3123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 3133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 314d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986Port: 315d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an URI structure 316d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string to analyze 3173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 318846cf015a77b9bca7b90c17c1f608ece3e268dadMichael Paddon * Parse a port part and fills in the appropriate fields 319d7af555327843a9938a913205ac703c13c225603Daniel Veillard * of the @uri structure 3203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 321d7af555327843a9938a913205ac703c13c225603Daniel Veillard * port = *DIGIT 322d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 323d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 3243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 325d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 326d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986Port(xmlURIPtr uri, const char **str) 327d7af555327843a9938a913205ac703c13c225603Daniel Veillard{ 328d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *cur = *str; 329846cf015a77b9bca7b90c17c1f608ece3e268dadMichael Paddon unsigned port = 0; /* unsigned for defined overflow behavior */ 3303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 331d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ISA_DIGIT(cur)) { 332d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (ISA_DIGIT(cur)) { 333846cf015a77b9bca7b90c17c1f608ece3e268dadMichael Paddon port = port * 10 + (*cur - '0'); 334846cf015a77b9bca7b90c17c1f608ece3e268dadMichael Paddon 335d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur++; 336d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 337846cf015a77b9bca7b90c17c1f608ece3e268dadMichael Paddon if (uri != NULL) 33822e01bd4c5bc675bd3313404abb570a865917859Brian C. Young uri->port = port & USHRT_MAX; /* port value modulo INT_MAX+1 */ 339d7af555327843a9938a913205ac703c13c225603Daniel Veillard *str = cur; 340d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(0); 3413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 342d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(1); 3433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 3443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 3453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 346d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986Userinfo: 347d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an URI structure 348d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string to analyze 3493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 350d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse an user informations part and fills in the appropriate fields 351d7af555327843a9938a913205ac703c13c225603Daniel Veillard * of the @uri structure 3523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 353d7af555327843a9938a913205ac703c13c225603Daniel Veillard * userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) 354d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 355d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 3563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 357d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 358d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986Userinfo(xmlURIPtr uri, const char **str) 359d7af555327843a9938a913205ac703c13c225603Daniel Veillard{ 360d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *cur; 3613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 362d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = *str; 363d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (ISA_UNRESERVED(cur) || ISA_PCT_ENCODED(cur) || 364d7af555327843a9938a913205ac703c13c225603Daniel Veillard ISA_SUB_DELIM(cur) || (*cur == ':')) 365d7af555327843a9938a913205ac703c13c225603Daniel Veillard NEXT(cur); 366d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (*cur == '@') { 367d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri != NULL) { 368d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->user != NULL) xmlFree(uri->user); 369d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->cleanup & 2) 370d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->user = STRNDUP(*str, cur - *str); 371d7af555327843a9938a913205ac703c13c225603Daniel Veillard else 372d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->user = xmlURIUnescapeString(*str, cur - *str, NULL); 373d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 374d7af555327843a9938a913205ac703c13c225603Daniel Veillard *str = cur; 375d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(0); 376d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 377d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(1); 378d7af555327843a9938a913205ac703c13c225603Daniel Veillard} 3793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 380d7af555327843a9938a913205ac703c13c225603Daniel Veillard/** 381d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986DecOctet: 382d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string to analyze 383d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 384d7af555327843a9938a913205ac703c13c225603Daniel Veillard * dec-octet = DIGIT ; 0-9 385d7af555327843a9938a913205ac703c13c225603Daniel Veillard * / %x31-39 DIGIT ; 10-99 386d7af555327843a9938a913205ac703c13c225603Daniel Veillard * / "1" 2DIGIT ; 100-199 387d7af555327843a9938a913205ac703c13c225603Daniel Veillard * / "2" %x30-34 DIGIT ; 200-249 388d7af555327843a9938a913205ac703c13c225603Daniel Veillard * / "25" %x30-35 ; 250-255 389d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 390d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Skip a dec-octet. 391d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 392d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 if found and skipped, 1 otherwise 393d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 394d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 395d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986DecOctet(const char **str) { 396d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *cur = *str; 3973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 398d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (!(ISA_DIGIT(cur))) 399d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(1); 400d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (!ISA_DIGIT(cur+1)) 401d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur++; 402d7af555327843a9938a913205ac703c13c225603Daniel Veillard else if ((*cur != '0') && (ISA_DIGIT(cur + 1)) && (!ISA_DIGIT(cur+2))) 403d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur += 2; 404d7af555327843a9938a913205ac703c13c225603Daniel Veillard else if ((*cur == '1') && (ISA_DIGIT(cur + 1)) && (ISA_DIGIT(cur + 2))) 405d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur += 3; 406d7af555327843a9938a913205ac703c13c225603Daniel Veillard else if ((*cur == '2') && (*(cur + 1) >= '0') && 407d7af555327843a9938a913205ac703c13c225603Daniel Veillard (*(cur + 1) <= '4') && (ISA_DIGIT(cur + 2))) 408d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur += 3; 409d7af555327843a9938a913205ac703c13c225603Daniel Veillard else if ((*cur == '2') && (*(cur + 1) == '5') && 410d7af555327843a9938a913205ac703c13c225603Daniel Veillard (*(cur + 2) >= '0') && (*(cur + 1) <= '5')) 411d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur += 3; 412d7af555327843a9938a913205ac703c13c225603Daniel Veillard else 413d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(1); 414d7af555327843a9938a913205ac703c13c225603Daniel Veillard *str = cur; 415d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(0); 416d7af555327843a9938a913205ac703c13c225603Daniel Veillard} 417d7af555327843a9938a913205ac703c13c225603Daniel Veillard/** 418d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986Host: 419d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an URI structure 420d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string to analyze 421d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 422d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse an host part and fills in the appropriate fields 423d7af555327843a9938a913205ac703c13c225603Daniel Veillard * of the @uri structure 424d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 425d7af555327843a9938a913205ac703c13c225603Daniel Veillard * host = IP-literal / IPv4address / reg-name 426d7af555327843a9938a913205ac703c13c225603Daniel Veillard * IP-literal = "[" ( IPv6address / IPvFuture ) "]" 427d7af555327843a9938a913205ac703c13c225603Daniel Veillard * IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet 428d7af555327843a9938a913205ac703c13c225603Daniel Veillard * reg-name = *( unreserved / pct-encoded / sub-delims ) 429d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 430d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 431d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 432d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 433d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986Host(xmlURIPtr uri, const char **str) 434d7af555327843a9938a913205ac703c13c225603Daniel Veillard{ 435d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *cur = *str; 436d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *host; 4373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 438d7af555327843a9938a913205ac703c13c225603Daniel Veillard host = cur; 439d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* 440d7af555327843a9938a913205ac703c13c225603Daniel Veillard * IPv6 and future adressing scheme are enclosed between brackets 441d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 442d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (*cur == '[') { 443d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur++; 444d7af555327843a9938a913205ac703c13c225603Daniel Veillard while ((*cur != ']') && (*cur != 0)) 445d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur++; 446d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (*cur != ']') 447d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(1); 448d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur++; 449d7af555327843a9938a913205ac703c13c225603Daniel Veillard goto found; 4503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 451d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* 452d7af555327843a9938a913205ac703c13c225603Daniel Veillard * try to parse an IPv4 453d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 454d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ISA_DIGIT(cur)) { 455d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (xmlParse3986DecOctet(&cur) != 0) 456d7af555327843a9938a913205ac703c13c225603Daniel Veillard goto not_ipv4; 457d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (*cur != '.') 458d7af555327843a9938a913205ac703c13c225603Daniel Veillard goto not_ipv4; 459d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur++; 460d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (xmlParse3986DecOctet(&cur) != 0) 461d7af555327843a9938a913205ac703c13c225603Daniel Veillard goto not_ipv4; 462d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (*cur != '.') 463d7af555327843a9938a913205ac703c13c225603Daniel Veillard goto not_ipv4; 464d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (xmlParse3986DecOctet(&cur) != 0) 465d7af555327843a9938a913205ac703c13c225603Daniel Veillard goto not_ipv4; 466d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (*cur != '.') 467d7af555327843a9938a913205ac703c13c225603Daniel Veillard goto not_ipv4; 468d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (xmlParse3986DecOctet(&cur) != 0) 469d7af555327843a9938a913205ac703c13c225603Daniel Veillard goto not_ipv4; 470d7af555327843a9938a913205ac703c13c225603Daniel Veillard goto found; 471d7af555327843a9938a913205ac703c13c225603Daniel Veillardnot_ipv4: 472d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = *str; 473d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 474d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* 475d7af555327843a9938a913205ac703c13c225603Daniel Veillard * then this should be a hostname which can be empty 476d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 477d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (ISA_UNRESERVED(cur) || ISA_PCT_ENCODED(cur) || ISA_SUB_DELIM(cur)) 478d7af555327843a9938a913205ac703c13c225603Daniel Veillard NEXT(cur); 479d7af555327843a9938a913205ac703c13c225603Daniel Veillardfound: 480d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri != NULL) { 481d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->authority != NULL) xmlFree(uri->authority); 482d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->authority = NULL; 483d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->server != NULL) xmlFree(uri->server); 484d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (cur != host) { 485d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->cleanup & 2) 486d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->server = STRNDUP(host, cur - host); 487d7af555327843a9938a913205ac703c13c225603Daniel Veillard else 488d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->server = xmlURIUnescapeString(host, cur - host, NULL); 489d7af555327843a9938a913205ac703c13c225603Daniel Veillard } else 490d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->server = NULL; 491d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 492d7af555327843a9938a913205ac703c13c225603Daniel Veillard *str = cur; 493d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(0); 494d7af555327843a9938a913205ac703c13c225603Daniel Veillard} 495d7af555327843a9938a913205ac703c13c225603Daniel Veillard 496d7af555327843a9938a913205ac703c13c225603Daniel Veillard/** 497d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986Authority: 498d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an URI structure 499d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string to analyze 500d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 501d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse an authority part and fills in the appropriate fields 502d7af555327843a9938a913205ac703c13c225603Daniel Veillard * of the @uri structure 503d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 504d7af555327843a9938a913205ac703c13c225603Daniel Veillard * authority = [ userinfo "@" ] host [ ":" port ] 505d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 506d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 507d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 508d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 509d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986Authority(xmlURIPtr uri, const char **str) 510d7af555327843a9938a913205ac703c13c225603Daniel Veillard{ 511d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *cur; 512d7af555327843a9938a913205ac703c13c225603Daniel Veillard int ret; 513d7af555327843a9938a913205ac703c13c225603Daniel Veillard 514d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = *str; 515d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* 516d7af555327843a9938a913205ac703c13c225603Daniel Veillard * try to parse an userinfo and check for the trailing @ 517d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 518d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Userinfo(uri, &cur); 519d7af555327843a9938a913205ac703c13c225603Daniel Veillard if ((ret != 0) || (*cur != '@')) 520d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = *str; 521d7af555327843a9938a913205ac703c13c225603Daniel Veillard else 522d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur++; 523d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Host(uri, &cur); 524d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 525d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (*cur == ':') { 526f582d14fbcba1cd1e6598d556d8838ea6f4788baDaniel Veillard cur++; 527d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Port(uri, &cur); 528d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 529d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 530d7af555327843a9938a913205ac703c13c225603Daniel Veillard *str = cur; 531d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(0); 532d7af555327843a9938a913205ac703c13c225603Daniel Veillard} 533d7af555327843a9938a913205ac703c13c225603Daniel Veillard 534d7af555327843a9938a913205ac703c13c225603Daniel Veillard/** 535d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986Segment: 536d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string to analyze 537d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @forbid: an optional forbidden character 538d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @empty: allow an empty segment 539d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 540d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse a segment and fills in the appropriate fields 541d7af555327843a9938a913205ac703c13c225603Daniel Veillard * of the @uri structure 542d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 543d7af555327843a9938a913205ac703c13c225603Daniel Veillard * segment = *pchar 544d7af555327843a9938a913205ac703c13c225603Daniel Veillard * segment-nz = 1*pchar 545d7af555327843a9938a913205ac703c13c225603Daniel Veillard * segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" ) 546d7af555327843a9938a913205ac703c13c225603Daniel Veillard * ; non-zero-length segment without any colon ":" 547d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 548d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 549d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 550d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 551d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986Segment(const char **str, char forbid, int empty) 552d7af555327843a9938a913205ac703c13c225603Daniel Veillard{ 553d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *cur; 554d7af555327843a9938a913205ac703c13c225603Daniel Veillard 555d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = *str; 556d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (!ISA_PCHAR(cur)) { 557d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (empty) 558d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(0); 559d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(1); 560fdd27d2718b9d6ef234092fb6cddfd7e9916feb6Daniel Veillard } 561d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (ISA_PCHAR(cur) && (*cur != forbid)) 562d7af555327843a9938a913205ac703c13c225603Daniel Veillard NEXT(cur); 563d7af555327843a9938a913205ac703c13c225603Daniel Veillard *str = cur; 564d7af555327843a9938a913205ac703c13c225603Daniel Veillard return (0); 565d7af555327843a9938a913205ac703c13c225603Daniel Veillard} 566d7af555327843a9938a913205ac703c13c225603Daniel Veillard 567d7af555327843a9938a913205ac703c13c225603Daniel Veillard/** 568d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986PathAbEmpty: 569d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an URI structure 570d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string to analyze 571d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 572d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse an path absolute or empty and fills in the appropriate fields 573d7af555327843a9938a913205ac703c13c225603Daniel Veillard * of the @uri structure 574d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 575d7af555327843a9938a913205ac703c13c225603Daniel Veillard * path-abempty = *( "/" segment ) 576d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 577d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 578d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 579d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 580d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986PathAbEmpty(xmlURIPtr uri, const char **str) 581d7af555327843a9938a913205ac703c13c225603Daniel Veillard{ 582d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *cur; 583d7af555327843a9938a913205ac703c13c225603Daniel Veillard int ret; 584d7af555327843a9938a913205ac703c13c225603Daniel Veillard 585d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = *str; 586d7af555327843a9938a913205ac703c13c225603Daniel Veillard 587d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (*cur == '/') { 588d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur++; 589d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Segment(&cur, 0, 1); 590d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 591d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 592d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri != NULL) { 593d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->path != NULL) xmlFree(uri->path); 5941358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard if (*str != cur) { 5951358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard if (uri->cleanup & 2) 5961358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard uri->path = STRNDUP(*str, cur - *str); 5971358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard else 5981358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard uri->path = xmlURIUnescapeString(*str, cur - *str, NULL); 5991358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard } else { 6001358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard uri->path = NULL; 6011358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard } 602d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 603d7af555327843a9938a913205ac703c13c225603Daniel Veillard *str = cur; 604d7af555327843a9938a913205ac703c13c225603Daniel Veillard return (0); 605d7af555327843a9938a913205ac703c13c225603Daniel Veillard} 606d7af555327843a9938a913205ac703c13c225603Daniel Veillard 607d7af555327843a9938a913205ac703c13c225603Daniel Veillard/** 608d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986PathAbsolute: 609d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an URI structure 610d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string to analyze 611d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 612d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse an path absolute and fills in the appropriate fields 613d7af555327843a9938a913205ac703c13c225603Daniel Veillard * of the @uri structure 614d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 615d7af555327843a9938a913205ac703c13c225603Daniel Veillard * path-absolute = "/" [ segment-nz *( "/" segment ) ] 616d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 617d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 618d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 619d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 620d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986PathAbsolute(xmlURIPtr uri, const char **str) 621d7af555327843a9938a913205ac703c13c225603Daniel Veillard{ 622d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *cur; 623d7af555327843a9938a913205ac703c13c225603Daniel Veillard int ret; 624d7af555327843a9938a913205ac703c13c225603Daniel Veillard 625d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = *str; 626d7af555327843a9938a913205ac703c13c225603Daniel Veillard 627d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (*cur != '/') 628d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(1); 629d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur++; 630d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Segment(&cur, 0, 0); 631d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret == 0) { 632d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (*cur == '/') { 633d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur++; 634d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Segment(&cur, 0, 1); 635d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 6363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 637fdd27d2718b9d6ef234092fb6cddfd7e9916feb6Daniel Veillard } 638d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri != NULL) { 639d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->path != NULL) xmlFree(uri->path); 6401358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard if (cur != *str) { 6411358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard if (uri->cleanup & 2) 6421358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard uri->path = STRNDUP(*str, cur - *str); 6431358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard else 6441358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard uri->path = xmlURIUnescapeString(*str, cur - *str, NULL); 6451358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard } else { 6461358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard uri->path = NULL; 6471358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard } 6483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 649d7af555327843a9938a913205ac703c13c225603Daniel Veillard *str = cur; 650d7af555327843a9938a913205ac703c13c225603Daniel Veillard return (0); 6513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 6523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 654d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986PathRootless: 655d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an URI structure 656d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string to analyze 6573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 658d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse an path without root and fills in the appropriate fields 659d7af555327843a9938a913205ac703c13c225603Daniel Veillard * of the @uri structure 660d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 661d7af555327843a9938a913205ac703c13c225603Daniel Veillard * path-rootless = segment-nz *( "/" segment ) 662d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 663d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 6643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 665d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 666d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986PathRootless(xmlURIPtr uri, const char **str) 667d7af555327843a9938a913205ac703c13c225603Daniel Veillard{ 668d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *cur; 669d7af555327843a9938a913205ac703c13c225603Daniel Veillard int ret; 6703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 671d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = *str; 672d7af555327843a9938a913205ac703c13c225603Daniel Veillard 673d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Segment(&cur, 0, 0); 674d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 675d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (*cur == '/') { 676d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur++; 677d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Segment(&cur, 0, 1); 678d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 679d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 680d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri != NULL) { 681d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->path != NULL) xmlFree(uri->path); 6821358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard if (cur != *str) { 6831358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard if (uri->cleanup & 2) 6841358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard uri->path = STRNDUP(*str, cur - *str); 6851358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard else 6861358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard uri->path = xmlURIUnescapeString(*str, cur - *str, NULL); 6871358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard } else { 6881358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard uri->path = NULL; 6891358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard } 6903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 691d7af555327843a9938a913205ac703c13c225603Daniel Veillard *str = cur; 692d7af555327843a9938a913205ac703c13c225603Daniel Veillard return (0); 6933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 6943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 6953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 696d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986PathNoScheme: 697d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an URI structure 698d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string to analyze 6993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 700d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse an path which is not a scheme and fills in the appropriate fields 701d7af555327843a9938a913205ac703c13c225603Daniel Veillard * of the @uri structure 702d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 703d7af555327843a9938a913205ac703c13c225603Daniel Veillard * path-noscheme = segment-nz-nc *( "/" segment ) 704d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 705d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 7063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 707d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 708d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986PathNoScheme(xmlURIPtr uri, const char **str) 709d7af555327843a9938a913205ac703c13c225603Daniel Veillard{ 710d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *cur; 711d7af555327843a9938a913205ac703c13c225603Daniel Veillard int ret; 7123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 713d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = *str; 714d7af555327843a9938a913205ac703c13c225603Daniel Veillard 715d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Segment(&cur, ':', 0); 716d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 717d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (*cur == '/') { 718d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur++; 719d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Segment(&cur, 0, 1); 720d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 721d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 722d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri != NULL) { 723d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->path != NULL) xmlFree(uri->path); 7241358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard if (cur != *str) { 7251358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard if (uri->cleanup & 2) 7261358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard uri->path = STRNDUP(*str, cur - *str); 7271358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard else 7281358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard uri->path = xmlURIUnescapeString(*str, cur - *str, NULL); 7291358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard } else { 7301358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard uri->path = NULL; 7311358fef9aa2c3fea5ed3d6ee50c7eb4d6f92b247Daniel Veillard } 732d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 733d7af555327843a9938a913205ac703c13c225603Daniel Veillard *str = cur; 734d7af555327843a9938a913205ac703c13c225603Daniel Veillard return (0); 735d7af555327843a9938a913205ac703c13c225603Daniel Veillard} 736d7af555327843a9938a913205ac703c13c225603Daniel Veillard 737d7af555327843a9938a913205ac703c13c225603Daniel Veillard/** 738d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986HierPart: 739d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an URI structure 740d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string to analyze 741d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 742d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse an hierarchical part and fills in the appropriate fields 743d7af555327843a9938a913205ac703c13c225603Daniel Veillard * of the @uri structure 744d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 745d7af555327843a9938a913205ac703c13c225603Daniel Veillard * hier-part = "//" authority path-abempty 746d7af555327843a9938a913205ac703c13c225603Daniel Veillard * / path-absolute 747d7af555327843a9938a913205ac703c13c225603Daniel Veillard * / path-rootless 748d7af555327843a9938a913205ac703c13c225603Daniel Veillard * / path-empty 749d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 750d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 751d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 752d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 753d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986HierPart(xmlURIPtr uri, const char **str) 754d7af555327843a9938a913205ac703c13c225603Daniel Veillard{ 755d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *cur; 756d7af555327843a9938a913205ac703c13c225603Daniel Veillard int ret; 757d7af555327843a9938a913205ac703c13c225603Daniel Veillard 758d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = *str; 759d7af555327843a9938a913205ac703c13c225603Daniel Veillard 760d7af555327843a9938a913205ac703c13c225603Daniel Veillard if ((*cur == '/') && (*(cur + 1) == '/')) { 761d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur += 2; 762d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Authority(uri, &cur); 763d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 764beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard if (uri->server == NULL) 765beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard uri->port = -1; 766d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986PathAbEmpty(uri, &cur); 767d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 768d7af555327843a9938a913205ac703c13c225603Daniel Veillard *str = cur; 769d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(0); 770d7af555327843a9938a913205ac703c13c225603Daniel Veillard } else if (*cur == '/') { 771d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986PathAbsolute(uri, &cur); 772d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 773d7af555327843a9938a913205ac703c13c225603Daniel Veillard } else if (ISA_PCHAR(cur)) { 774d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986PathRootless(uri, &cur); 775d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 776d7af555327843a9938a913205ac703c13c225603Daniel Veillard } else { 777d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* path-empty is effectively empty */ 778d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri != NULL) { 779d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->path != NULL) xmlFree(uri->path); 780d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->path = NULL; 781d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 782d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 783d7af555327843a9938a913205ac703c13c225603Daniel Veillard *str = cur; 784d7af555327843a9938a913205ac703c13c225603Daniel Veillard return (0); 785d7af555327843a9938a913205ac703c13c225603Daniel Veillard} 786d7af555327843a9938a913205ac703c13c225603Daniel Veillard 787d7af555327843a9938a913205ac703c13c225603Daniel Veillard/** 788d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986RelativeRef: 789d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an URI structure 790d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string to analyze 791d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 792d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse an URI string and fills in the appropriate fields 793d7af555327843a9938a913205ac703c13c225603Daniel Veillard * of the @uri structure 794d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 795d7af555327843a9938a913205ac703c13c225603Daniel Veillard * relative-ref = relative-part [ "?" query ] [ "#" fragment ] 796d7af555327843a9938a913205ac703c13c225603Daniel Veillard * relative-part = "//" authority path-abempty 797d7af555327843a9938a913205ac703c13c225603Daniel Veillard * / path-absolute 798d7af555327843a9938a913205ac703c13c225603Daniel Veillard * / path-noscheme 799d7af555327843a9938a913205ac703c13c225603Daniel Veillard * / path-empty 800d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 801d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 802d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 803d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 804d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986RelativeRef(xmlURIPtr uri, const char *str) { 805d7af555327843a9938a913205ac703c13c225603Daniel Veillard int ret; 806d7af555327843a9938a913205ac703c13c225603Daniel Veillard 807d7af555327843a9938a913205ac703c13c225603Daniel Veillard if ((*str == '/') && (*(str + 1) == '/')) { 808d7af555327843a9938a913205ac703c13c225603Daniel Veillard str += 2; 809d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Authority(uri, &str); 810d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 811d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986PathAbEmpty(uri, &str); 812d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 813d7af555327843a9938a913205ac703c13c225603Daniel Veillard } else if (*str == '/') { 814d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986PathAbsolute(uri, &str); 815d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 816d7af555327843a9938a913205ac703c13c225603Daniel Veillard } else if (ISA_PCHAR(str)) { 817d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986PathNoScheme(uri, &str); 818d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 819d7af555327843a9938a913205ac703c13c225603Daniel Veillard } else { 820d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* path-empty is effectively empty */ 821d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri != NULL) { 822d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->path != NULL) xmlFree(uri->path); 823d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->path = NULL; 824d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 825d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 826d7af555327843a9938a913205ac703c13c225603Daniel Veillard 827d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (*str == '?') { 828d7af555327843a9938a913205ac703c13c225603Daniel Veillard str++; 829d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Query(uri, &str); 830d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 831d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 832d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (*str == '#') { 833d7af555327843a9938a913205ac703c13c225603Daniel Veillard str++; 834d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Fragment(uri, &str); 835d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 836d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 837d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (*str != 0) { 838d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlCleanURI(uri); 839d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(1); 840d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 841d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(0); 8423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 8433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 844d7af555327843a9938a913205ac703c13c225603Daniel Veillard 8453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 846d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986URI: 847d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an URI structure 848d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string to analyze 8493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 850d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse an URI string and fills in the appropriate fields 851d7af555327843a9938a913205ac703c13c225603Daniel Veillard * of the @uri structure 852d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 853d7af555327843a9938a913205ac703c13c225603Daniel Veillard * scheme ":" hier-part [ "?" query ] [ "#" fragment ] 854d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 855d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 8563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 857d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 858d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986URI(xmlURIPtr uri, const char *str) { 859d7af555327843a9938a913205ac703c13c225603Daniel Veillard int ret; 8603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 861d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Scheme(uri, &str); 862d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 863d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (*str != ':') { 864d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(1); 865d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 866d7af555327843a9938a913205ac703c13c225603Daniel Veillard str++; 867d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986HierPart(uri, &str); 868d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 869d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (*str == '?') { 870d7af555327843a9938a913205ac703c13c225603Daniel Veillard str++; 871d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Query(uri, &str); 872d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 873d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 874d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (*str == '#') { 875d7af555327843a9938a913205ac703c13c225603Daniel Veillard str++; 876d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986Fragment(uri, &str); 877d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) return(ret); 878d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 879d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (*str != 0) { 880d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlCleanURI(uri); 881d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(1); 882d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 883d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(0); 8843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 8853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 8863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 887d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParse3986URIReference: 888d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an URI structure 889d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string to analyze 8903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 891d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse an URI reference string and fills in the appropriate fields 892d7af555327843a9938a913205ac703c13c225603Daniel Veillard * of the @uri structure 8933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 894d7af555327843a9938a913205ac703c13c225603Daniel Veillard * URI-reference = URI / relative-ref 8953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 896d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 8973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 898d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int 899d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParse3986URIReference(xmlURIPtr uri, const char *str) { 900d7af555327843a9938a913205ac703c13c225603Daniel Veillard int ret; 9013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 902d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (str == NULL) 9033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 904d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlCleanURI(uri); 9053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 9063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 907d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Try first to parse absolute refs, then fallback to relative if 908d7af555327843a9938a913205ac703c13c225603Daniel Veillard * it fails. 9093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 910d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986URI(uri, str); 911d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) { 912d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlCleanURI(uri); 913d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986RelativeRef(uri, str); 914d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret != 0) { 915d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlCleanURI(uri); 916d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(ret); 9173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 9183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 919d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(0); 920d7af555327843a9938a913205ac703c13c225603Daniel Veillard} 9213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 922d7af555327843a9938a913205ac703c13c225603Daniel Veillard/** 923d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParseURI: 924d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the URI string to analyze 925d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 926d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse an URI based on RFC 3986 927d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 928d7af555327843a9938a913205ac703c13c225603Daniel Veillard * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ] 929d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 930d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns a newly built xmlURIPtr or NULL in case of error 931d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 932d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlURIPtr 933d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParseURI(const char *str) { 934d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlURIPtr uri; 935d7af555327843a9938a913205ac703c13c225603Daniel Veillard int ret; 9363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 937d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (str == NULL) 938d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(NULL); 939d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri = xmlCreateURI(); 940d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri != NULL) { 941d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParse3986URIReference(uri, str); 942d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret) { 943d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFreeURI(uri); 944d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(NULL); 945d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 9463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 947d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(uri); 948d7af555327843a9938a913205ac703c13c225603Daniel Veillard} 9493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 950d7af555327843a9938a913205ac703c13c225603Daniel Veillard/** 951d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParseURIReference: 952d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an URI structure 953d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string to analyze 954d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 955d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse an URI reference string based on RFC 3986 and fills in the 956d7af555327843a9938a913205ac703c13c225603Daniel Veillard * appropriate fields of the @uri structure 957d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 958d7af555327843a9938a913205ac703c13c225603Daniel Veillard * URI-reference = URI / relative-ref 959d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 960d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or the error code 961d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 962d7af555327843a9938a913205ac703c13c225603Daniel Veillardint 963d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParseURIReference(xmlURIPtr uri, const char *str) { 964d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(xmlParse3986URIReference(uri, str)); 965d7af555327843a9938a913205ac703c13c225603Daniel Veillard} 9663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 967d7af555327843a9938a913205ac703c13c225603Daniel Veillard/** 968d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlParseURIRaw: 969d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the URI string to analyze 970d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @raw: if 1 unescaping of URI pieces are disabled 971d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 972d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Parse an URI but allows to keep intact the original fragments. 973d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 974d7af555327843a9938a913205ac703c13c225603Daniel Veillard * URI-reference = URI / relative-ref 975d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 976d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns a newly built xmlURIPtr or NULL in case of error 977d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 978d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlURIPtr 979d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlParseURIRaw(const char *str, int raw) { 980d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlURIPtr uri; 981d7af555327843a9938a913205ac703c13c225603Daniel Veillard int ret; 9823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 983d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (str == NULL) 984d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(NULL); 985d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri = xmlCreateURI(); 986d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri != NULL) { 987d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (raw) { 988d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->cleanup |= 2; 989d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 990d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlParseURIReference(uri, str); 991d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret) { 992d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFreeURI(uri); 993d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(NULL); 994d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 995d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 996d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(uri); 9973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 9983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 999d7af555327843a9938a913205ac703c13c225603Daniel Veillard/************************************************************************ 1000d7af555327843a9938a913205ac703c13c225603Daniel Veillard * * 1001d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Generic URI structure functions * 1002d7af555327843a9938a913205ac703c13c225603Daniel Veillard * * 1003d7af555327843a9938a913205ac703c13c225603Daniel Veillard ************************************************************************/ 1004d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1005d7af555327843a9938a913205ac703c13c225603Daniel Veillard/** 1006d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlCreateURI: 1007d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 1008d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Simply creates an empty xmlURI 1009d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 1010d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns the new structure or NULL in case of error 1011d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 1012d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlURIPtr 1013d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlCreateURI(void) { 1014d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlURIPtr ret; 1015d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1016d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = (xmlURIPtr) xmlMalloc(sizeof(xmlURI)); 1017d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret == NULL) { 101857560386503be0fd023f3b7537fd496784f3be18Daniel Veillard xmlURIErrMemory("creating URI structure\n"); 1019d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(NULL); 1020d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1021d7af555327843a9938a913205ac703c13c225603Daniel Veillard memset(ret, 0, sizeof(xmlURI)); 1022d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(ret); 1023966a31e222f478b8ab3174617794808aa90f20c0Daniel Veillard} 1024966a31e222f478b8ab3174617794808aa90f20c0Daniel Veillard 10253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 102657560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * xmlSaveUriRealloc: 102757560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * 102857560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * Function to handle properly a reallocation when saving an URI 102957560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * Also imposes some limit on the length of an URI string output 103057560386503be0fd023f3b7537fd496784f3be18Daniel Veillard */ 103157560386503be0fd023f3b7537fd496784f3be18Daniel Veillardstatic xmlChar * 103257560386503be0fd023f3b7537fd496784f3be18Daniel VeillardxmlSaveUriRealloc(xmlChar *ret, int *max) { 103357560386503be0fd023f3b7537fd496784f3be18Daniel Veillard xmlChar *temp; 103457560386503be0fd023f3b7537fd496784f3be18Daniel Veillard int tmp; 103557560386503be0fd023f3b7537fd496784f3be18Daniel Veillard 103657560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (*max > MAX_URI_LENGTH) { 103757560386503be0fd023f3b7537fd496784f3be18Daniel Veillard xmlURIErrMemory("reaching arbitrary MAX_URI_LENGTH limit\n"); 103857560386503be0fd023f3b7537fd496784f3be18Daniel Veillard return(NULL); 103957560386503be0fd023f3b7537fd496784f3be18Daniel Veillard } 104057560386503be0fd023f3b7537fd496784f3be18Daniel Veillard tmp = *max * 2; 104157560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = (xmlChar *) xmlRealloc(ret, (tmp + 1)); 104257560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) { 104357560386503be0fd023f3b7537fd496784f3be18Daniel Veillard xmlURIErrMemory("saving URI\n"); 104457560386503be0fd023f3b7537fd496784f3be18Daniel Veillard return(NULL); 104557560386503be0fd023f3b7537fd496784f3be18Daniel Veillard } 104657560386503be0fd023f3b7537fd496784f3be18Daniel Veillard *max = tmp; 104757560386503be0fd023f3b7537fd496784f3be18Daniel Veillard return(temp); 104857560386503be0fd023f3b7537fd496784f3be18Daniel Veillard} 104957560386503be0fd023f3b7537fd496784f3be18Daniel Veillard 105057560386503be0fd023f3b7537fd496784f3be18Daniel Veillard/** 1051d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlSaveUri: 1052d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an xmlURI 10533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1054d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Save the URI as an escaped string 10553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1056d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns a new string (to be deallocated by caller) 10573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1058d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlChar * 1059d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlSaveUri(xmlURIPtr uri) { 1060d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlChar *ret = NULL; 1061d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlChar *temp; 1062d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *p; 1063d7af555327843a9938a913205ac703c13c225603Daniel Veillard int len; 1064d7af555327843a9938a913205ac703c13c225603Daniel Veillard int max; 10653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1066d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri == NULL) return(NULL); 1067d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1068d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1069d7af555327843a9938a913205ac703c13c225603Daniel Veillard max = 80; 1070d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = (xmlChar *) xmlMallocAtomic((max + 1) * sizeof(xmlChar)); 1071d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret == NULL) { 107257560386503be0fd023f3b7537fd496784f3be18Daniel Veillard xmlURIErrMemory("saving URI\n"); 10733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(NULL); 1074d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1075d7af555327843a9938a913205ac703c13c225603Daniel Veillard len = 0; 10763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1077d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->scheme != NULL) { 1078d7af555327843a9938a913205ac703c13c225603Daniel Veillard p = uri->scheme; 1079d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (*p != 0) { 1080d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len >= max) { 108157560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 108257560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 1083d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = temp; 1084d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1085d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = *p++; 10863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1087d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len >= max) { 108857560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 108957560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 109057560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 1091d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1092d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = ':'; 1093d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1094d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->opaque != NULL) { 1095d7af555327843a9938a913205ac703c13c225603Daniel Veillard p = uri->opaque; 1096d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (*p != 0) { 1097d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len + 3 >= max) { 109857560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 109957560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 110057560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 1101d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1102d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (IS_RESERVED(*(p)) || IS_UNRESERVED(*(p))) 1103d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = *p++; 1104d7af555327843a9938a913205ac703c13c225603Daniel Veillard else { 1105d7af555327843a9938a913205ac703c13c225603Daniel Veillard int val = *(unsigned char *)p++; 1106d7af555327843a9938a913205ac703c13c225603Daniel Veillard int hi = val / 0x10, lo = val % 0x10; 1107d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = '%'; 1108d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = hi + (hi > 9? 'A'-10 : '0'); 1109d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = lo + (lo > 9? 'A'-10 : '0'); 1110d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1111d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1112d7af555327843a9938a913205ac703c13c225603Daniel Veillard } else { 1113beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard if ((uri->server != NULL) || (uri->port == -1)) { 1114d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len + 3 >= max) { 111557560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 111657560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 111757560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 1118d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1119d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = '/'; 1120d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = '/'; 1121d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->user != NULL) { 1122d7af555327843a9938a913205ac703c13c225603Daniel Veillard p = uri->user; 1123d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (*p != 0) { 1124d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len + 3 >= max) { 112557560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 112657560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 112757560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 1128d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1129d7af555327843a9938a913205ac703c13c225603Daniel Veillard if ((IS_UNRESERVED(*(p))) || 1130d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == ';')) || ((*(p) == ':')) || 1131d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == '&')) || ((*(p) == '=')) || 1132d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == '+')) || ((*(p) == '$')) || 1133d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == ','))) 1134d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = *p++; 1135d7af555327843a9938a913205ac703c13c225603Daniel Veillard else { 1136d7af555327843a9938a913205ac703c13c225603Daniel Veillard int val = *(unsigned char *)p++; 1137d7af555327843a9938a913205ac703c13c225603Daniel Veillard int hi = val / 0x10, lo = val % 0x10; 1138d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = '%'; 1139d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = hi + (hi > 9? 'A'-10 : '0'); 1140d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = lo + (lo > 9? 'A'-10 : '0'); 1141d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1142d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1143d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len + 3 >= max) { 114457560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 114557560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 114657560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 1147d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1148d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = '@'; 1149d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1150beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard if (uri->server != NULL) { 1151beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard p = uri->server; 1152beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard while (*p != 0) { 1153beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard if (len >= max) { 1154beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 1155beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard if (temp == NULL) goto mem_error; 1156beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard ret = temp; 1157beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard } 1158beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard ret[len++] = *p++; 1159d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1160beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard if (uri->port > 0) { 1161beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard if (len + 10 >= max) { 1162beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 1163beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard if (temp == NULL) goto mem_error; 1164beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard ret = temp; 1165beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard } 1166beb7281055dbf0ed4d041022a67c6c5cfd126f25Daniel Veillard len += snprintf((char *) &ret[len], max - len, ":%d", uri->port); 1167d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1168d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1169d7af555327843a9938a913205ac703c13c225603Daniel Veillard } else if (uri->authority != NULL) { 1170d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len + 3 >= max) { 117157560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 117257560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 117357560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 1174d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1175d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = '/'; 1176d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = '/'; 1177d7af555327843a9938a913205ac703c13c225603Daniel Veillard p = uri->authority; 1178d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (*p != 0) { 1179d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len + 3 >= max) { 118057560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 118157560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 118257560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 1183d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1184d7af555327843a9938a913205ac703c13c225603Daniel Veillard if ((IS_UNRESERVED(*(p))) || 1185d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == '$')) || ((*(p) == ',')) || ((*(p) == ';')) || 1186d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == ':')) || ((*(p) == '@')) || ((*(p) == '&')) || 1187d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == '=')) || ((*(p) == '+'))) 1188d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = *p++; 1189d7af555327843a9938a913205ac703c13c225603Daniel Veillard else { 1190d7af555327843a9938a913205ac703c13c225603Daniel Veillard int val = *(unsigned char *)p++; 1191d7af555327843a9938a913205ac703c13c225603Daniel Veillard int hi = val / 0x10, lo = val % 0x10; 1192d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = '%'; 1193d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = hi + (hi > 9? 'A'-10 : '0'); 1194d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = lo + (lo > 9? 'A'-10 : '0'); 1195d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1196d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1197d7af555327843a9938a913205ac703c13c225603Daniel Veillard } else if (uri->scheme != NULL) { 1198d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len + 3 >= max) { 119957560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 120057560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 120157560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 1202d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 12033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1204d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->path != NULL) { 1205d7af555327843a9938a913205ac703c13c225603Daniel Veillard p = uri->path; 1206d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* 1207d7af555327843a9938a913205ac703c13c225603Daniel Veillard * the colon in file:///d: should not be escaped or 1208d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Windows accesses fail later. 1209d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 1210d7af555327843a9938a913205ac703c13c225603Daniel Veillard if ((uri->scheme != NULL) && 1211d7af555327843a9938a913205ac703c13c225603Daniel Veillard (p[0] == '/') && 1212d7af555327843a9938a913205ac703c13c225603Daniel Veillard (((p[1] >= 'a') && (p[1] <= 'z')) || 1213d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((p[1] >= 'A') && (p[1] <= 'Z'))) && 1214d7af555327843a9938a913205ac703c13c225603Daniel Veillard (p[2] == ':') && 1215d7af555327843a9938a913205ac703c13c225603Daniel Veillard (xmlStrEqual(BAD_CAST uri->scheme, BAD_CAST "file"))) { 1216d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len + 3 >= max) { 121757560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 121857560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 121957560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 1220d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1221d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = *p++; 1222d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = *p++; 1223d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = *p++; 1224d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1225d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (*p != 0) { 1226d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len + 3 >= max) { 122757560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 122857560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 122957560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 1230d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1231d7af555327843a9938a913205ac703c13c225603Daniel Veillard if ((IS_UNRESERVED(*(p))) || ((*(p) == '/')) || 1232d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == ';')) || ((*(p) == '@')) || ((*(p) == '&')) || 1233d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == '=')) || ((*(p) == '+')) || ((*(p) == '$')) || 1234d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((*(p) == ','))) 1235d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = *p++; 1236d7af555327843a9938a913205ac703c13c225603Daniel Veillard else { 1237d7af555327843a9938a913205ac703c13c225603Daniel Veillard int val = *(unsigned char *)p++; 1238d7af555327843a9938a913205ac703c13c225603Daniel Veillard int hi = val / 0x10, lo = val % 0x10; 1239d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = '%'; 1240d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = hi + (hi > 9? 'A'-10 : '0'); 1241d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = lo + (lo > 9? 'A'-10 : '0'); 1242d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 12433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 12443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1245d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->query_raw != NULL) { 1246d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len + 1 >= max) { 124757560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 124857560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 124957560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 1250d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1251d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = '?'; 1252d7af555327843a9938a913205ac703c13c225603Daniel Veillard p = uri->query_raw; 1253d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (*p != 0) { 1254d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len + 1 >= max) { 125557560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 125657560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 125757560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 1258d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1259d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = *p++; 1260d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1261d7af555327843a9938a913205ac703c13c225603Daniel Veillard } else if (uri->query != NULL) { 1262d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len + 3 >= max) { 126357560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 126457560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 126557560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 1266d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1267d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = '?'; 1268d7af555327843a9938a913205ac703c13c225603Daniel Veillard p = uri->query; 1269d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (*p != 0) { 1270d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len + 3 >= max) { 127157560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 127257560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 127357560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 1274d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 127557560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if ((IS_UNRESERVED(*(p))) || (IS_RESERVED(*(p)))) 1276d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = *p++; 1277d7af555327843a9938a913205ac703c13c225603Daniel Veillard else { 1278d7af555327843a9938a913205ac703c13c225603Daniel Veillard int val = *(unsigned char *)p++; 1279d7af555327843a9938a913205ac703c13c225603Daniel Veillard int hi = val / 0x10, lo = val % 0x10; 1280d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = '%'; 1281d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = hi + (hi > 9? 'A'-10 : '0'); 1282d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = lo + (lo > 9? 'A'-10 : '0'); 1283d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1284d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 12853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 12864def3bd94c4c34ad0b7b2848f7f43a62c9ea067cDaniel Veillard } 1287d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->fragment != NULL) { 1288d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len + 3 >= max) { 128957560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 129057560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 129157560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 1292d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1293d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = '#'; 1294d7af555327843a9938a913205ac703c13c225603Daniel Veillard p = uri->fragment; 1295d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (*p != 0) { 1296d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len + 3 >= max) { 129757560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 129857560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 129957560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 1300d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 130157560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if ((IS_UNRESERVED(*(p))) || (IS_RESERVED(*(p)))) 1302d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = *p++; 1303d7af555327843a9938a913205ac703c13c225603Daniel Veillard else { 1304d7af555327843a9938a913205ac703c13c225603Daniel Veillard int val = *(unsigned char *)p++; 1305d7af555327843a9938a913205ac703c13c225603Daniel Veillard int hi = val / 0x10, lo = val % 0x10; 1306d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = '%'; 1307d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = hi + (hi > 9? 'A'-10 : '0'); 1308d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[len++] = lo + (lo > 9? 'A'-10 : '0'); 1309d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1310d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 13113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1312d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len >= max) { 131357560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &max); 131457560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (temp == NULL) goto mem_error; 131557560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = temp; 13163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 131713cee4e37ba9f2a401f976e069539514ebfce7bcDaniel Veillard ret[len] = 0; 1318d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(ret); 131957560386503be0fd023f3b7537fd496784f3be18Daniel Veillard 132057560386503be0fd023f3b7537fd496784f3be18Daniel Veillardmem_error: 132157560386503be0fd023f3b7537fd496784f3be18Daniel Veillard xmlFree(ret); 132257560386503be0fd023f3b7537fd496784f3be18Daniel Veillard return(NULL); 13233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 13243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 1326d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlPrintURI: 1327d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @stream: a FILE* for the output 1328d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an xmlURI 13293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1330d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Prints the URI in the stream @stream. 13313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1332d7af555327843a9938a913205ac703c13c225603Daniel Veillardvoid 1333d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlPrintURI(FILE *stream, xmlURIPtr uri) { 1334d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlChar *out; 13353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1336d7af555327843a9938a913205ac703c13c225603Daniel Veillard out = xmlSaveUri(uri); 1337d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (out != NULL) { 1338d7af555327843a9938a913205ac703c13c225603Daniel Veillard fprintf(stream, "%s", (char *) out); 1339d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFree(out); 13403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 13413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 13423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 13433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 1344d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlCleanURI: 1345d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an xmlURI 13463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1347d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Make sure the xmlURI struct is free of content 13483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1349d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic void 1350d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlCleanURI(xmlURIPtr uri) { 1351d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri == NULL) return; 13523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1353d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->scheme != NULL) xmlFree(uri->scheme); 1354d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->scheme = NULL; 1355d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->server != NULL) xmlFree(uri->server); 1356d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->server = NULL; 1357d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->user != NULL) xmlFree(uri->user); 1358d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->user = NULL; 1359d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->path != NULL) xmlFree(uri->path); 1360d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->path = NULL; 1361d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->fragment != NULL) xmlFree(uri->fragment); 1362d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->fragment = NULL; 1363d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->opaque != NULL) xmlFree(uri->opaque); 1364d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->opaque = NULL; 1365d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->authority != NULL) xmlFree(uri->authority); 1366d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->authority = NULL; 1367d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->query != NULL) xmlFree(uri->query); 1368d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->query = NULL; 1369d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->query_raw != NULL) xmlFree(uri->query_raw); 1370d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->query_raw = NULL; 1371d7af555327843a9938a913205ac703c13c225603Daniel Veillard} 13724def3bd94c4c34ad0b7b2848f7f43a62c9ea067cDaniel Veillard 1373d7af555327843a9938a913205ac703c13c225603Daniel Veillard/** 1374d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlFreeURI: 1375d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @uri: pointer to an xmlURI 1376d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 1377d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Free up the xmlURI struct 1378d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 1379d7af555327843a9938a913205ac703c13c225603Daniel Veillardvoid 1380d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlFreeURI(xmlURIPtr uri) { 1381d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri == NULL) return; 1382d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1383d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->scheme != NULL) xmlFree(uri->scheme); 1384d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->server != NULL) xmlFree(uri->server); 1385d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->user != NULL) xmlFree(uri->user); 1386d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->path != NULL) xmlFree(uri->path); 1387d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->fragment != NULL) xmlFree(uri->fragment); 1388d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->opaque != NULL) xmlFree(uri->opaque); 1389d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->authority != NULL) xmlFree(uri->authority); 1390d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->query != NULL) xmlFree(uri->query); 1391d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->query_raw != NULL) xmlFree(uri->query_raw); 1392d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFree(uri); 13933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 13943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1395d7af555327843a9938a913205ac703c13c225603Daniel Veillard/************************************************************************ 1396d7af555327843a9938a913205ac703c13c225603Daniel Veillard * * 1397d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Helper functions * 1398d7af555327843a9938a913205ac703c13c225603Daniel Veillard * * 1399d7af555327843a9938a913205ac703c13c225603Daniel Veillard ************************************************************************/ 1400d7af555327843a9938a913205ac703c13c225603Daniel Veillard 14013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 1402d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlNormalizeURIPath: 1403d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @path: pointer to the path string 14043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1405d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Applies the 5 normalization steps to a path string--that is, RFC 2396 1406d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Section 5.2, steps 6.c through 6.g. 14073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1408d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Normalization occurs directly on the string, no new allocation is done 1409d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 1410d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns 0 or an error code 14113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1412d7af555327843a9938a913205ac703c13c225603Daniel Veillardint 1413d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlNormalizeURIPath(char *path) { 1414d7af555327843a9938a913205ac703c13c225603Daniel Veillard char *cur, *out; 14153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1416d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (path == NULL) 14173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(-1); 14183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1419d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* Skip all initial "/" chars. We want to get to the beginning of the 1420d7af555327843a9938a913205ac703c13c225603Daniel Veillard * first non-empty segment. 14213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1422d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = path; 1423d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (cur[0] == '/') 1424d7af555327843a9938a913205ac703c13c225603Daniel Veillard ++cur; 1425d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (cur[0] == '\0') 1426d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(0); 1427d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1428d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* Keep everything we've seen so far. */ 1429d7af555327843a9938a913205ac703c13c225603Daniel Veillard out = cur; 1430d7af555327843a9938a913205ac703c13c225603Daniel Veillard 14313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 1432d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Analyze each segment in sequence for cases (c) and (d). 14333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1434d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (cur[0] != '\0') { 1435015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack /* 1436d7af555327843a9938a913205ac703c13c225603Daniel Veillard * c) All occurrences of "./", where "." is a complete path segment, 1437d7af555327843a9938a913205ac703c13c225603Daniel Veillard * are removed from the buffer string. 1438015ccb2c747fb73561e2fe72d6214585dd9985e8William M. Brack */ 1439d7af555327843a9938a913205ac703c13c225603Daniel Veillard if ((cur[0] == '.') && (cur[1] == '/')) { 1440d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur += 2; 1441d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* '//' normalization should be done at this point too */ 1442d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (cur[0] == '/') 14433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 1444d7af555327843a9938a913205ac703c13c225603Daniel Veillard continue; 14453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 14463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1447d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* 1448d7af555327843a9938a913205ac703c13c225603Daniel Veillard * d) If the buffer string ends with "." as a complete path segment, 1449d7af555327843a9938a913205ac703c13c225603Daniel Veillard * that "." is removed. 1450d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 1451d7af555327843a9938a913205ac703c13c225603Daniel Veillard if ((cur[0] == '.') && (cur[1] == '\0')) 1452d7af555327843a9938a913205ac703c13c225603Daniel Veillard break; 14533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1454d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* Otherwise keep the segment. */ 1455d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (cur[0] != '/') { 1456d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (cur[0] == '\0') 1457d7af555327843a9938a913205ac703c13c225603Daniel Veillard goto done_cd; 1458d7af555327843a9938a913205ac703c13c225603Daniel Veillard (out++)[0] = (cur++)[0]; 1459d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1460d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* nomalize // */ 1461d7af555327843a9938a913205ac703c13c225603Daniel Veillard while ((cur[0] == '/') && (cur[1] == '/')) 1462d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur++; 14634def3bd94c4c34ad0b7b2848f7f43a62c9ea067cDaniel Veillard 1464d7af555327843a9938a913205ac703c13c225603Daniel Veillard (out++)[0] = (cur++)[0]; 14653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1466d7af555327843a9938a913205ac703c13c225603Daniel Veillard done_cd: 1467d7af555327843a9938a913205ac703c13c225603Daniel Veillard out[0] = '\0'; 1468d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1469d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* Reset to the beginning of the first segment for the next sequence. */ 1470d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = path; 1471d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (cur[0] == '/') 1472d7af555327843a9938a913205ac703c13c225603Daniel Veillard ++cur; 1473d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (cur[0] == '\0') 1474d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(0); 1475d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1476d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* 1477d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Analyze each segment in sequence for cases (e) and (f). 1478d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 1479d7af555327843a9938a913205ac703c13c225603Daniel Veillard * e) All occurrences of "<segment>/../", where <segment> is a 1480d7af555327843a9938a913205ac703c13c225603Daniel Veillard * complete path segment not equal to "..", are removed from the 1481d7af555327843a9938a913205ac703c13c225603Daniel Veillard * buffer string. Removal of these path segments is performed 1482d7af555327843a9938a913205ac703c13c225603Daniel Veillard * iteratively, removing the leftmost matching pattern on each 1483d7af555327843a9938a913205ac703c13c225603Daniel Veillard * iteration, until no matching pattern remains. 1484d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 1485d7af555327843a9938a913205ac703c13c225603Daniel Veillard * f) If the buffer string ends with "<segment>/..", where <segment> 1486d7af555327843a9938a913205ac703c13c225603Daniel Veillard * is a complete path segment not equal to "..", that 1487d7af555327843a9938a913205ac703c13c225603Daniel Veillard * "<segment>/.." is removed. 1488d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 1489d7af555327843a9938a913205ac703c13c225603Daniel Veillard * To satisfy the "iterative" clause in (e), we need to collapse the 1490d7af555327843a9938a913205ac703c13c225603Daniel Veillard * string every time we find something that needs to be removed. Thus, 1491d7af555327843a9938a913205ac703c13c225603Daniel Veillard * we don't need to keep two pointers into the string: we only need a 1492d7af555327843a9938a913205ac703c13c225603Daniel Veillard * "current position" pointer. 1493d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 1494d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (1) { 1495d7af555327843a9938a913205ac703c13c225603Daniel Veillard char *segp, *tmp; 14963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1497d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* At the beginning of each iteration of this loop, "cur" points to 1498d7af555327843a9938a913205ac703c13c225603Daniel Veillard * the first character of the segment we want to examine. 1499d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 15003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1501d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* Find the end of the current segment. */ 1502d7af555327843a9938a913205ac703c13c225603Daniel Veillard segp = cur; 1503d7af555327843a9938a913205ac703c13c225603Daniel Veillard while ((segp[0] != '/') && (segp[0] != '\0')) 1504d7af555327843a9938a913205ac703c13c225603Daniel Veillard ++segp; 15054def3bd94c4c34ad0b7b2848f7f43a62c9ea067cDaniel Veillard 1506d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* If this is the last segment, we're done (we need at least two 1507d7af555327843a9938a913205ac703c13c225603Daniel Veillard * segments to meet the criteria for the (e) and (f) cases). 1508d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 1509d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (segp[0] == '\0') 1510d7af555327843a9938a913205ac703c13c225603Daniel Veillard break; 15113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1512d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* If the first segment is "..", or if the next segment _isn't_ "..", 1513d7af555327843a9938a913205ac703c13c225603Daniel Veillard * keep this segment and try the next one. 1514d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 1515d7af555327843a9938a913205ac703c13c225603Daniel Veillard ++segp; 1516d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (((cur[0] == '.') && (cur[1] == '.') && (segp == cur+3)) 1517d7af555327843a9938a913205ac703c13c225603Daniel Veillard || ((segp[0] != '.') || (segp[1] != '.') 1518d7af555327843a9938a913205ac703c13c225603Daniel Veillard || ((segp[2] != '/') && (segp[2] != '\0')))) { 1519d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = segp; 1520d7af555327843a9938a913205ac703c13c225603Daniel Veillard continue; 15214def3bd94c4c34ad0b7b2848f7f43a62c9ea067cDaniel Veillard } 15223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1523d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* If we get here, remove this segment and the next one and back up 1524d7af555327843a9938a913205ac703c13c225603Daniel Veillard * to the previous segment (if there is one), to implement the 1525d7af555327843a9938a913205ac703c13c225603Daniel Veillard * "iteratively" clause. It's pretty much impossible to back up 1526d7af555327843a9938a913205ac703c13c225603Daniel Veillard * while maintaining two pointers into the buffer, so just compact 1527d7af555327843a9938a913205ac703c13c225603Daniel Veillard * the whole buffer now. 15284def3bd94c4c34ad0b7b2848f7f43a62c9ea067cDaniel Veillard */ 15293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1530d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* If this is the end of the buffer, we're done. */ 1531d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (segp[2] == '\0') { 1532d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur[0] = '\0'; 1533d7af555327843a9938a913205ac703c13c225603Daniel Veillard break; 15344def3bd94c4c34ad0b7b2848f7f43a62c9ea067cDaniel Veillard } 1535d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* Valgrind complained, strcpy(cur, segp + 3); */ 1536cedf84d35ab127dd24f9bcbf8b8339518d0e8928Nico Weber /* string will overlap, do not use strcpy */ 1537cedf84d35ab127dd24f9bcbf8b8339518d0e8928Nico Weber tmp = cur; 1538cedf84d35ab127dd24f9bcbf8b8339518d0e8928Nico Weber segp += 3; 1539cedf84d35ab127dd24f9bcbf8b8339518d0e8928Nico Weber while ((*tmp++ = *segp++) != 0) 1540cedf84d35ab127dd24f9bcbf8b8339518d0e8928Nico Weber ; 15413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1542d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* If there are no previous segments, then keep going from here. */ 1543d7af555327843a9938a913205ac703c13c225603Daniel Veillard segp = cur; 1544d7af555327843a9938a913205ac703c13c225603Daniel Veillard while ((segp > path) && ((--segp)[0] == '/')) 1545d7af555327843a9938a913205ac703c13c225603Daniel Veillard ; 1546d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (segp == path) 1547d7af555327843a9938a913205ac703c13c225603Daniel Veillard continue; 15483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1549d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* "segp" is pointing to the end of a previous segment; find it's 1550d7af555327843a9938a913205ac703c13c225603Daniel Veillard * start. We need to back up to the previous segment and start 1551d7af555327843a9938a913205ac703c13c225603Daniel Veillard * over with that to handle things like "foo/bar/../..". If we 1552d7af555327843a9938a913205ac703c13c225603Daniel Veillard * don't do this, then on the first pass we'll remove the "bar/..", 1553d7af555327843a9938a913205ac703c13c225603Daniel Veillard * but be pointing at the second ".." so we won't realize we can also 1554d7af555327843a9938a913205ac703c13c225603Daniel Veillard * remove the "foo/..". 1555d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 1556d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = segp; 1557d7af555327843a9938a913205ac703c13c225603Daniel Veillard while ((cur > path) && (cur[-1] != '/')) 1558d7af555327843a9938a913205ac703c13c225603Daniel Veillard --cur; 1559d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1560d7af555327843a9938a913205ac703c13c225603Daniel Veillard out[0] = '\0'; 15613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 15623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 1563d7af555327843a9938a913205ac703c13c225603Daniel Veillard * g) If the resulting buffer string still begins with one or more 1564d7af555327843a9938a913205ac703c13c225603Daniel Veillard * complete path segments of "..", then the reference is 1565d7af555327843a9938a913205ac703c13c225603Daniel Veillard * considered to be in error. Implementations may handle this 1566d7af555327843a9938a913205ac703c13c225603Daniel Veillard * error by retaining these components in the resolved path (i.e., 1567d7af555327843a9938a913205ac703c13c225603Daniel Veillard * treating them as part of the final URI), by removing them from 1568d7af555327843a9938a913205ac703c13c225603Daniel Veillard * the resolved path (i.e., discarding relative levels above the 1569d7af555327843a9938a913205ac703c13c225603Daniel Veillard * root), or by avoiding traversal of the reference. 1570d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 1571d7af555327843a9938a913205ac703c13c225603Daniel Veillard * We discard them from the final path. 15723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1573d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (path[0] == '/') { 1574d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur = path; 1575d7af555327843a9938a913205ac703c13c225603Daniel Veillard while ((cur[0] == '/') && (cur[1] == '.') && (cur[2] == '.') 1576d7af555327843a9938a913205ac703c13c225603Daniel Veillard && ((cur[3] == '/') || (cur[3] == '\0'))) 1577d7af555327843a9938a913205ac703c13c225603Daniel Veillard cur += 3; 15783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1579d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (cur != path) { 1580d7af555327843a9938a913205ac703c13c225603Daniel Veillard out = path; 1581d7af555327843a9938a913205ac703c13c225603Daniel Veillard while (cur[0] != '\0') 1582d7af555327843a9938a913205ac703c13c225603Daniel Veillard (out++)[0] = (cur++)[0]; 1583d7af555327843a9938a913205ac703c13c225603Daniel Veillard out[0] = 0; 1584d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 15853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 15863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 15873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(0); 15883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 15893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1590d7af555327843a9938a913205ac703c13c225603Daniel Veillardstatic int is_hex(char c) { 1591d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (((c >= '0') && (c <= '9')) || 1592d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((c >= 'a') && (c <= 'f')) || 1593d7af555327843a9938a913205ac703c13c225603Daniel Veillard ((c >= 'A') && (c <= 'F'))) 15943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(1); 1595d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(0); 15963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 15973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 15983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 1599d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlURIUnescapeString: 1600d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string to unescape 1601d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @len: the length in bytes to unescape (or <= 0 to indicate full string) 1602d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @target: optional destination buffer 16033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1604d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Unescaping routine, but does not check that the string is an URI. The 1605d7af555327843a9938a913205ac703c13c225603Daniel Veillard * output is a direct unsigned char translation of %XX values (no encoding) 1606d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Note that the length of the result can only be smaller or same size as 1607d7af555327843a9938a913205ac703c13c225603Daniel Veillard * the input string. 16083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1609d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns a copy of the string, but unescaped, will return NULL only in case 1610d7af555327843a9938a913205ac703c13c225603Daniel Veillard * of error 16113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1612d7af555327843a9938a913205ac703c13c225603Daniel Veillardchar * 1613d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlURIUnescapeString(const char *str, int len, char *target) { 1614d7af555327843a9938a913205ac703c13c225603Daniel Veillard char *ret, *out; 1615d7af555327843a9938a913205ac703c13c225603Daniel Veillard const char *in; 16163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 16173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (str == NULL) 1618d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(NULL); 1619d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len <= 0) len = strlen(str); 1620d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len < 0) return(NULL); 1621d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1622d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (target == NULL) { 1623d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = (char *) xmlMallocAtomic(len + 1); 1624d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret == NULL) { 162557560386503be0fd023f3b7537fd496784f3be18Daniel Veillard xmlURIErrMemory("unescaping URI value\n"); 1626d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(NULL); 16273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1628d7af555327843a9938a913205ac703c13c225603Daniel Veillard } else 1629d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = target; 1630d7af555327843a9938a913205ac703c13c225603Daniel Veillard in = str; 1631d7af555327843a9938a913205ac703c13c225603Daniel Veillard out = ret; 1632d7af555327843a9938a913205ac703c13c225603Daniel Veillard while(len > 0) { 1633d7af555327843a9938a913205ac703c13c225603Daniel Veillard if ((len > 2) && (*in == '%') && (is_hex(in[1])) && (is_hex(in[2]))) { 1634d7af555327843a9938a913205ac703c13c225603Daniel Veillard in++; 163557560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if ((*in >= '0') && (*in <= '9')) 1636d7af555327843a9938a913205ac703c13c225603Daniel Veillard *out = (*in - '0'); 1637d7af555327843a9938a913205ac703c13c225603Daniel Veillard else if ((*in >= 'a') && (*in <= 'f')) 1638d7af555327843a9938a913205ac703c13c225603Daniel Veillard *out = (*in - 'a') + 10; 1639d7af555327843a9938a913205ac703c13c225603Daniel Veillard else if ((*in >= 'A') && (*in <= 'F')) 1640d7af555327843a9938a913205ac703c13c225603Daniel Veillard *out = (*in - 'A') + 10; 1641d7af555327843a9938a913205ac703c13c225603Daniel Veillard in++; 164257560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if ((*in >= '0') && (*in <= '9')) 1643d7af555327843a9938a913205ac703c13c225603Daniel Veillard *out = *out * 16 + (*in - '0'); 1644d7af555327843a9938a913205ac703c13c225603Daniel Veillard else if ((*in >= 'a') && (*in <= 'f')) 1645d7af555327843a9938a913205ac703c13c225603Daniel Veillard *out = *out * 16 + (*in - 'a') + 10; 1646d7af555327843a9938a913205ac703c13c225603Daniel Veillard else if ((*in >= 'A') && (*in <= 'F')) 1647d7af555327843a9938a913205ac703c13c225603Daniel Veillard *out = *out * 16 + (*in - 'A') + 10; 1648d7af555327843a9938a913205ac703c13c225603Daniel Veillard in++; 1649d7af555327843a9938a913205ac703c13c225603Daniel Veillard len -= 3; 1650d7af555327843a9938a913205ac703c13c225603Daniel Veillard out++; 1651d7af555327843a9938a913205ac703c13c225603Daniel Veillard } else { 1652d7af555327843a9938a913205ac703c13c225603Daniel Veillard *out++ = *in++; 1653d7af555327843a9938a913205ac703c13c225603Daniel Veillard len--; 16543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 16553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1656d7af555327843a9938a913205ac703c13c225603Daniel Veillard *out = 0; 16573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(ret); 16583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 16593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 16603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 1661d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlURIEscapeStr: 1662d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: string to escape 1663d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @list: exception list string of chars not to escape 16643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1665d7af555327843a9938a913205ac703c13c225603Daniel Veillard * This routine escapes a string to hex, ignoring reserved characters (a-z) 1666d7af555327843a9938a913205ac703c13c225603Daniel Veillard * and the characters in the exception list. 16673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1668d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns a new escaped string or NULL in case of error. 16693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1670d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlChar * 1671d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlURIEscapeStr(const xmlChar *str, const xmlChar *list) { 1672d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlChar *ret, ch; 1673d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlChar *temp; 1674d7af555327843a9938a913205ac703c13c225603Daniel Veillard const xmlChar *in; 167557560386503be0fd023f3b7537fd496784f3be18Daniel Veillard int len, out; 16763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 16773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (str == NULL) 1678d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(NULL); 1679d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (str[0] == 0) 1680d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(xmlStrdup(str)); 1681d7af555327843a9938a913205ac703c13c225603Daniel Veillard len = xmlStrlen(str); 1682d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (!(len > 0)) return(NULL); 16833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1684d7af555327843a9938a913205ac703c13c225603Daniel Veillard len += 20; 1685d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = (xmlChar *) xmlMallocAtomic(len); 1686d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret == NULL) { 168757560386503be0fd023f3b7537fd496784f3be18Daniel Veillard xmlURIErrMemory("escaping URI value\n"); 1688d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(NULL); 16893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1690d7af555327843a9938a913205ac703c13c225603Daniel Veillard in = (const xmlChar *) str; 1691d7af555327843a9938a913205ac703c13c225603Daniel Veillard out = 0; 1692d7af555327843a9938a913205ac703c13c225603Daniel Veillard while(*in != 0) { 1693d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (len - out <= 3) { 169457560386503be0fd023f3b7537fd496784f3be18Daniel Veillard temp = xmlSaveUriRealloc(ret, &len); 1695d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (temp == NULL) { 169657560386503be0fd023f3b7537fd496784f3be18Daniel Veillard xmlURIErrMemory("escaping URI value\n"); 1697d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFree(ret); 1698d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(NULL); 1699d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1700d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = temp; 1701d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1702d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1703d7af555327843a9938a913205ac703c13c225603Daniel Veillard ch = *in; 1704d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1705d7af555327843a9938a913205ac703c13c225603Daniel Veillard if ((ch != '@') && (!IS_UNRESERVED(ch)) && (!xmlStrchr(list, ch))) { 1706d7af555327843a9938a913205ac703c13c225603Daniel Veillard unsigned char val; 1707d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[out++] = '%'; 1708d7af555327843a9938a913205ac703c13c225603Daniel Veillard val = ch >> 4; 1709d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (val <= 9) 1710d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[out++] = '0' + val; 1711d7af555327843a9938a913205ac703c13c225603Daniel Veillard else 1712d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[out++] = 'A' + val - 0xA; 1713d7af555327843a9938a913205ac703c13c225603Daniel Veillard val = ch & 0xF; 1714d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (val <= 9) 1715d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[out++] = '0' + val; 1716d7af555327843a9938a913205ac703c13c225603Daniel Veillard else 1717d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[out++] = 'A' + val - 0xA; 1718d7af555327843a9938a913205ac703c13c225603Daniel Veillard in++; 1719d7af555327843a9938a913205ac703c13c225603Daniel Veillard } else { 1720d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[out++] = *in++; 1721d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 17223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 17233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 1724d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret[out] = 0; 1725d7af555327843a9938a913205ac703c13c225603Daniel Veillard return(ret); 17263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 17273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 17283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 1729d7af555327843a9938a913205ac703c13c225603Daniel Veillard * xmlURIEscape: 1730d7af555327843a9938a913205ac703c13c225603Daniel Veillard * @str: the string of the URI to escape 17313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1732d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Escaping routine, does not do validity checks ! 1733d7af555327843a9938a913205ac703c13c225603Daniel Veillard * It will try to escape the chars needing this, but this is heuristic 1734d7af555327843a9938a913205ac703c13c225603Daniel Veillard * based it's impossible to be sure. 17353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1736d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Returns an copy of the string, but escaped 1737d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 1738d7af555327843a9938a913205ac703c13c225603Daniel Veillard * 25 May 2001 1739d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Uses xmlParseURI and xmlURIEscapeStr to try to escape correctly 1740d7af555327843a9938a913205ac703c13c225603Daniel Veillard * according to RFC2396. 1741d7af555327843a9938a913205ac703c13c225603Daniel Veillard * - Carl Douglas 17423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 1743d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlChar * 1744d7af555327843a9938a913205ac703c13c225603Daniel VeillardxmlURIEscape(const xmlChar * str) 1745d7af555327843a9938a913205ac703c13c225603Daniel Veillard{ 1746d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlChar *ret, *segment = NULL; 17473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlURIPtr uri; 1748d7af555327843a9938a913205ac703c13c225603Daniel Veillard int ret2; 1749d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1750d7af555327843a9938a913205ac703c13c225603Daniel Veillard#define NULLCHK(p) if(!p) { \ 175157560386503be0fd023f3b7537fd496784f3be18Daniel Veillard xmlURIErrMemory("escaping URI value\n"); \ 175257560386503be0fd023f3b7537fd496784f3be18Daniel Veillard xmlFreeURI(uri); \ 175357560386503be0fd023f3b7537fd496784f3be18Daniel Veillard return NULL; } \ 17543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 17553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (str == NULL) 1756d7af555327843a9938a913205ac703c13c225603Daniel Veillard return (NULL); 1757d7af555327843a9938a913205ac703c13c225603Daniel Veillard 17583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor uri = xmlCreateURI(); 17593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (uri != NULL) { 1760d7af555327843a9938a913205ac703c13c225603Daniel Veillard /* 1761d7af555327843a9938a913205ac703c13c225603Daniel Veillard * Allow escaping errors in the unescaped form 1762d7af555327843a9938a913205ac703c13c225603Daniel Veillard */ 1763d7af555327843a9938a913205ac703c13c225603Daniel Veillard uri->cleanup = 1; 1764d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret2 = xmlParseURIReference(uri, (const char *)str); 1765d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (ret2) { 1766d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFreeURI(uri); 1767d7af555327843a9938a913205ac703c13c225603Daniel Veillard return (NULL); 1768d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 17693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 17703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 1771d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (!uri) 1772d7af555327843a9938a913205ac703c13c225603Daniel Veillard return NULL; 1773336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard 1774d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = NULL; 1775d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1776d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->scheme) { 1777d7af555327843a9938a913205ac703c13c225603Daniel Veillard segment = xmlURIEscapeStr(BAD_CAST uri->scheme, BAD_CAST "+-."); 1778d7af555327843a9938a913205ac703c13c225603Daniel Veillard NULLCHK(segment) 1779d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, segment); 1780d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, BAD_CAST ":"); 1781d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFree(segment); 1782336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard } 1783d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1784d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->authority) { 1785d7af555327843a9938a913205ac703c13c225603Daniel Veillard segment = 1786d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlURIEscapeStr(BAD_CAST uri->authority, BAD_CAST "/?;:@"); 1787d7af555327843a9938a913205ac703c13c225603Daniel Veillard NULLCHK(segment) 1788d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, BAD_CAST "//"); 1789d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, segment); 1790d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFree(segment); 1791d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1792d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1793d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->user) { 1794d7af555327843a9938a913205ac703c13c225603Daniel Veillard segment = xmlURIEscapeStr(BAD_CAST uri->user, BAD_CAST ";:&=+$,"); 1795d7af555327843a9938a913205ac703c13c225603Daniel Veillard NULLCHK(segment) 179657560386503be0fd023f3b7537fd496784f3be18Daniel Veillard ret = xmlStrcat(ret,BAD_CAST "//"); 1797d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, segment); 1798d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, BAD_CAST "@"); 1799d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFree(segment); 1800d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1801d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1802d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->server) { 1803d7af555327843a9938a913205ac703c13c225603Daniel Veillard segment = xmlURIEscapeStr(BAD_CAST uri->server, BAD_CAST "/?;:@"); 1804d7af555327843a9938a913205ac703c13c225603Daniel Veillard NULLCHK(segment) 1805d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->user == NULL) 1806d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, BAD_CAST "//"); 1807d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, segment); 1808d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFree(segment); 1809d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1810d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1811d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->port) { 1812d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlChar port[10]; 1813d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1814d7af555327843a9938a913205ac703c13c225603Daniel Veillard snprintf((char *) port, 10, "%d", uri->port); 1815d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, BAD_CAST ":"); 1816d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, port); 1817d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1818d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1819d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->path) { 1820d7af555327843a9938a913205ac703c13c225603Daniel Veillard segment = 1821d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlURIEscapeStr(BAD_CAST uri->path, BAD_CAST ":@&=+$,/?;"); 1822d7af555327843a9938a913205ac703c13c225603Daniel Veillard NULLCHK(segment) 1823d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, segment); 1824d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFree(segment); 1825d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1826d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1827d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->query_raw) { 1828d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, BAD_CAST "?"); 1829d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, BAD_CAST uri->query_raw); 1830d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1831d7af555327843a9938a913205ac703c13c225603Daniel Veillard else if (uri->query) { 1832d7af555327843a9938a913205ac703c13c225603Daniel Veillard segment = 1833d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlURIEscapeStr(BAD_CAST uri->query, BAD_CAST ";/?:@&=+,$"); 1834d7af555327843a9938a913205ac703c13c225603Daniel Veillard NULLCHK(segment) 1835d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, BAD_CAST "?"); 1836d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, segment); 1837d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFree(segment); 1838d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1839d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1840d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->opaque) { 1841d7af555327843a9938a913205ac703c13c225603Daniel Veillard segment = xmlURIEscapeStr(BAD_CAST uri->opaque, BAD_CAST ""); 1842d7af555327843a9938a913205ac703c13c225603Daniel Veillard NULLCHK(segment) 1843d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, segment); 1844d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFree(segment); 1845d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1846d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1847d7af555327843a9938a913205ac703c13c225603Daniel Veillard if (uri->fragment) { 1848d7af555327843a9938a913205ac703c13c225603Daniel Veillard segment = xmlURIEscapeStr(BAD_CAST uri->fragment, BAD_CAST "#"); 1849d7af555327843a9938a913205ac703c13c225603Daniel Veillard NULLCHK(segment) 1850d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, BAD_CAST "#"); 1851d7af555327843a9938a913205ac703c13c225603Daniel Veillard ret = xmlStrcat(ret, segment); 1852d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFree(segment); 1853d7af555327843a9938a913205ac703c13c225603Daniel Veillard } 1854d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1855d7af555327843a9938a913205ac703c13c225603Daniel Veillard xmlFreeURI(uri); 1856d7af555327843a9938a913205ac703c13c225603Daniel Veillard#undef NULLCHK 1857d7af555327843a9938a913205ac703c13c225603Daniel Veillard 1858d7af555327843a9938a913205ac703c13c225603Daniel Veillard return (ret); 1859336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard} 1860336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard 18613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************ 18623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 18633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Public functions * 18643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * * 18653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/ 18663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 18673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/** 18683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlBuildURI: 18693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @URI: the URI instance found in the document 18703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @base: the base value 18713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 18723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Computes he final URI of the reference done by checking that 18733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the given URI is valid, and building the final URI using the 187457560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * base URI. This is processed according to section 5.2 of the 18753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * RFC 2396 18763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 18773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 5.2. Resolving Relative References to Absolute Form 18783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 18793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns a new URI string (to be freed by the caller) or NULL in case 18803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of error. 18813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 18823473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlChar * 18833473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlBuildURI(const xmlChar *URI, const xmlChar *base) { 18843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlChar *val = NULL; 188556a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard int ret, len, indx, cur, out; 18863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlURIPtr ref = NULL; 18873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlURIPtr bas = NULL; 18883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlURIPtr res = NULL; 18893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 18903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 18913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 1) The URI reference is parsed into the potential four components and 18923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * fragment identifier, as described in Section 4.3. 18933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 18943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * NOTE that a completely empty URI is treated by modern browsers 18953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * as a reference to "." rather than as a synonym for the current 18963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * URI. Should we do that here? 18973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 189857560386503be0fd023f3b7537fd496784f3be18Daniel Veillard if (URI == NULL) 18993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = -1; 19003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else { 19013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (*URI) { 19023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ref = xmlCreateURI(); 19033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ref == NULL) 19043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto done; 19053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = xmlParseURIReference(ref, (const char *) URI); 19063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 19073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else 19083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = 0; 19093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 19103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret != 0) 19113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto done; 19127b4b2f9d8fc712c49beaf75985161a130c77d13aDaniel Veillard if ((ref != NULL) && (ref->scheme != NULL)) { 19137b4b2f9d8fc712c49beaf75985161a130c77d13aDaniel Veillard /* 19147b4b2f9d8fc712c49beaf75985161a130c77d13aDaniel Veillard * The URI is absolute don't modify. 19157b4b2f9d8fc712c49beaf75985161a130c77d13aDaniel Veillard */ 19167b4b2f9d8fc712c49beaf75985161a130c77d13aDaniel Veillard val = xmlStrdup(URI); 19177b4b2f9d8fc712c49beaf75985161a130c77d13aDaniel Veillard goto done; 19187b4b2f9d8fc712c49beaf75985161a130c77d13aDaniel Veillard } 19193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (base == NULL) 19203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = -1; 19213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else { 19223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor bas = xmlCreateURI(); 19233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (bas == NULL) 19243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto done; 19253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ret = xmlParseURIReference(bas, (const char *) base); 19263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 19273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ret != 0) { 19283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ref) 19293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val = xmlSaveUri(ref); 19303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto done; 19313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 19323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ref == NULL) { 19333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 19343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the base fragment must be ignored 19353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 19363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (bas->fragment != NULL) { 19373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFree(bas->fragment); 19383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor bas->fragment = NULL; 19393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 19403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val = xmlSaveUri(bas); 19413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto done; 19423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 19433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 19443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 19453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 2) If the path component is empty and the scheme, authority, and 19463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * query components are undefined, then it is a reference to the 19473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * current document and we are done. Otherwise, the reference URI's 19483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * query and fragment components are defined as found (or not found) 19493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * within the URI reference and not inherited from the base URI. 19503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 19513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * NOTE that in modern browsers, the parsing differs from the above 19523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * in the following aspect: the query component is allowed to be 19533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * defined while still treating this as a reference to the current 19543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * document. 19553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 19563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res = xmlCreateURI(); 19573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (res == NULL) 19583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto done; 19593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ref->scheme == NULL) && (ref->path == NULL) && 19603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ((ref->authority == NULL) && (ref->server == NULL))) { 19613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (bas->scheme != NULL) 19623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->scheme = xmlMemStrdup(bas->scheme); 19633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (bas->authority != NULL) 19643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->authority = xmlMemStrdup(bas->authority); 19653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (bas->server != NULL) { 19663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->server = xmlMemStrdup(bas->server); 19673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (bas->user != NULL) 19683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->user = xmlMemStrdup(bas->user); 196957560386503be0fd023f3b7537fd496784f3be18Daniel Veillard res->port = bas->port; 19703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 19713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (bas->path != NULL) 19723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->path = xmlMemStrdup(bas->path); 1973a1413b84f7163d57c6251d5f4251186368efd859Daniel Veillard if (ref->query_raw != NULL) 1974a1413b84f7163d57c6251d5f4251186368efd859Daniel Veillard res->query_raw = xmlMemStrdup (ref->query_raw); 1975a1413b84f7163d57c6251d5f4251186368efd859Daniel Veillard else if (ref->query != NULL) 19763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->query = xmlMemStrdup(ref->query); 1977a1413b84f7163d57c6251d5f4251186368efd859Daniel Veillard else if (bas->query_raw != NULL) 1978a1413b84f7163d57c6251d5f4251186368efd859Daniel Veillard res->query_raw = xmlMemStrdup(bas->query_raw); 19793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (bas->query != NULL) 19803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->query = xmlMemStrdup(bas->query); 19813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ref->fragment != NULL) 19823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->fragment = xmlMemStrdup(ref->fragment); 19833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto step_7; 19843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 19853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 19863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 19873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 3) If the scheme component is defined, indicating that the reference 19883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * starts with a scheme name, then the reference is interpreted as an 19893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * absolute URI and we are done. Otherwise, the reference URI's 19903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * scheme is inherited from the base URI's scheme component. 19913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 19923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ref->scheme != NULL) { 19933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val = xmlSaveUri(ref); 19943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto done; 19953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 19963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (bas->scheme != NULL) 19973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->scheme = xmlMemStrdup(bas->scheme); 199857560386503be0fd023f3b7537fd496784f3be18Daniel Veillard 1999a1413b84f7163d57c6251d5f4251186368efd859Daniel Veillard if (ref->query_raw != NULL) 2000a1413b84f7163d57c6251d5f4251186368efd859Daniel Veillard res->query_raw = xmlMemStrdup(ref->query_raw); 2001a1413b84f7163d57c6251d5f4251186368efd859Daniel Veillard else if (ref->query != NULL) 20029231ff9250af7e22104cc5e9406f0dd43e86aec0Daniel Veillard res->query = xmlMemStrdup(ref->query); 20039231ff9250af7e22104cc5e9406f0dd43e86aec0Daniel Veillard if (ref->fragment != NULL) 20049231ff9250af7e22104cc5e9406f0dd43e86aec0Daniel Veillard res->fragment = xmlMemStrdup(ref->fragment); 20053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 20073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 4) If the authority component is defined, then the reference is a 20083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * network-path and we skip to step 7. Otherwise, the reference 20093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * URI's authority is inherited from the base URI's authority 20103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * component, which will also be undefined if the URI scheme does not 20113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * use an authority component. 20123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 20133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ref->authority != NULL) || (ref->server != NULL)) { 20143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ref->authority != NULL) 20153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->authority = xmlMemStrdup(ref->authority); 20163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else { 20173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->server = xmlMemStrdup(ref->server); 20183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ref->user != NULL) 20193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->user = xmlMemStrdup(ref->user); 202057560386503be0fd023f3b7537fd496784f3be18Daniel Veillard res->port = ref->port; 20213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 20223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ref->path != NULL) 20233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->path = xmlMemStrdup(ref->path); 20243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto step_7; 20253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 20263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (bas->authority != NULL) 20273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->authority = xmlMemStrdup(bas->authority); 20283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor else if (bas->server != NULL) { 20293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->server = xmlMemStrdup(bas->server); 20303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (bas->user != NULL) 20313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->user = xmlMemStrdup(bas->user); 203257560386503be0fd023f3b7537fd496784f3be18Daniel Veillard res->port = bas->port; 20333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 20343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 20363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 5) If the path component begins with a slash character ("/"), then 20373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the reference is an absolute-path and we skip to step 7. 20383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 20393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((ref->path != NULL) && (ref->path[0] == '/')) { 20403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->path = xmlMemStrdup(ref->path); 20413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto step_7; 20423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 20433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 20463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 6) If this step is reached, then we are resolving a relative-path 20473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * reference. The relative path needs to be merged with the base 20483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * URI's path. Although there are many ways to do this, we will 20493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * describe a simple method using a separate string buffer. 20503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 20513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Allocate a buffer large enough for the result string. 20523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 20533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor len = 2; /* extra / and 0 */ 20543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ref->path != NULL) 20553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor len += strlen(ref->path); 20563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (bas->path != NULL) 20573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor len += strlen(bas->path); 20583c908dca479ed50dca24b8593bca90e40dbde6b8Daniel Veillard res->path = (char *) xmlMallocAtomic(len); 20593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (res->path == NULL) { 206057560386503be0fd023f3b7537fd496784f3be18Daniel Veillard xmlURIErrMemory("resolving URI against base\n"); 20613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor goto done; 20623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 20633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->path[0] = 0; 20643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 20663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * a) All but the last segment of the base URI's path component is 20673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * copied to the buffer. In other words, any characters after the 20683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * last (right-most) slash character, if any, are excluded. 20693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 20703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur = 0; 20713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor out = 0; 20723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (bas->path != NULL) { 20733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (bas->path[cur] != 0) { 20743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while ((bas->path[cur] != 0) && (bas->path[cur] != '/')) 20753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 20763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (bas->path[cur] == 0) 20773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor break; 20783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor cur++; 20803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor while (out < cur) { 20813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->path[out] = bas->path[out]; 20823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor out++; 20833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 20843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 20853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 20863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->path[out] = 0; 20873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 20883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 20893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * b) The reference's path component is appended to the buffer 20903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string. 20913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 20923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ref->path != NULL && ref->path[0] != 0) { 209356a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard indx = 0; 20943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 20953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Ensure the path includes a '/' 20963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 20973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if ((out == 0) && (bas->server != NULL)) 20983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->path[out++] = '/'; 209956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard while (ref->path[indx] != 0) { 210056a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard res->path[out++] = ref->path[indx++]; 21013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 21023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor } 21033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor res->path[out] = 0; 21043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 21053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 21063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Steps c) to h) are really path normalization steps 21073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 21083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlNormalizeURIPath(res->path); 21093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 21103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstep_7: 21113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 21123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor /* 21133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 7) The resulting URI components, including any inherited from the 21143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * base URI, are recombined to give the absolute form of the URI 21153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * reference. 21163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */ 21173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor val = xmlSaveUri(res); 21183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 21193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylordone: 21203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (ref != NULL) 21213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFreeURI(ref); 21223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (bas != NULL) 21233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFreeURI(bas); 21243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor if (res != NULL) 21253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor xmlFreeURI(res); 21263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor return(val); 21273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor} 21283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2129f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic/** 2130f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * xmlBuildRelativeURI: 2131f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * @URI: the URI reference under consideration 2132f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * @base: the base value 2133f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * 2134f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * Expresses the URI of the reference in terms relative to the 2135f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * base. Some examples of this operation include: 2136f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * base = "http://site1.com/docs/book1.html" 2137f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * URI input URI returned 2138f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * docs/pic1.gif pic1.gif 2139f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * docs/img/pic1.gif img/pic1.gif 2140f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * img/pic1.gif ../img/pic1.gif 2141f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * http://site1.com/docs/pic1.gif pic1.gif 2142f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * http://site2.com/docs/pic1.gif http://site2.com/docs/pic1.gif 2143f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * 2144f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * base = "docs/book1.html" 2145f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * URI input URI returned 2146f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * docs/pic1.gif pic1.gif 2147f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * docs/img/pic1.gif img/pic1.gif 2148f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * img/pic1.gif ../img/pic1.gif 2149f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * http://site1.com/docs/pic1.gif http://site1.com/docs/pic1.gif 2150f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * 2151f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * 2152f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * Note: if the URI reference is really wierd or complicated, it may be 2153f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * worthwhile to first convert it into a "nice" one by calling 2154f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * xmlBuildURI (using 'base') before calling this routine, 2155f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * since this routine (for reasonable efficiency) assumes URI has 2156f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * already been through some validation. 2157f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * 2158f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * Returns a new URI string (to be freed by the caller) or NULL in case 2159f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * error. 2160f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack */ 2161f7789b13c59ef9d9e73047543c704c6ab21a6212William M. BrackxmlChar * 2162f7789b13c59ef9d9e73047543c704c6ab21a6212William M. BrackxmlBuildRelativeURI (const xmlChar * URI, const xmlChar * base) 2163f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack{ 2164f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack xmlChar *val = NULL; 2165f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack int ret; 2166f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack int ix; 2167f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack int pos = 0; 2168f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack int nbslash = 0; 2169820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack int len; 2170f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack xmlURIPtr ref = NULL; 2171f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack xmlURIPtr bas = NULL; 2172f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack xmlChar *bptr, *uptr, *vptr; 21730f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard int remove_path = 0; 2174f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack 2175f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack if ((URI == NULL) || (*URI == 0)) 2176f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack return NULL; 2177f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack 2178f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack /* 2179f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * First parse URI into a standard form 2180f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack */ 2181f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack ref = xmlCreateURI (); 2182f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack if (ref == NULL) 2183f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack return NULL; 218438c4b332c4ec2f0db5ee601abaa9b46ec2e272e2William M. Brack /* If URI not already in "relative" form */ 218538c4b332c4ec2f0db5ee601abaa9b46ec2e272e2William M. Brack if (URI[0] != '.') { 218638c4b332c4ec2f0db5ee601abaa9b46ec2e272e2William M. Brack ret = xmlParseURIReference (ref, (const char *) URI); 218738c4b332c4ec2f0db5ee601abaa9b46ec2e272e2William M. Brack if (ret != 0) 218838c4b332c4ec2f0db5ee601abaa9b46ec2e272e2William M. Brack goto done; /* Error in URI, return NULL */ 218938c4b332c4ec2f0db5ee601abaa9b46ec2e272e2William M. Brack } else 219038c4b332c4ec2f0db5ee601abaa9b46ec2e272e2William M. Brack ref->path = (char *)xmlStrdup(URI); 2191f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack 2192f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack /* 2193f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * Next parse base into the same standard form 2194f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack */ 2195f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack if ((base == NULL) || (*base == 0)) { 2196f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack val = xmlStrdup (URI); 2197f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack goto done; 2198f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack } 2199f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack bas = xmlCreateURI (); 2200f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack if (bas == NULL) 2201f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack goto done; 220238c4b332c4ec2f0db5ee601abaa9b46ec2e272e2William M. Brack if (base[0] != '.') { 220338c4b332c4ec2f0db5ee601abaa9b46ec2e272e2William M. Brack ret = xmlParseURIReference (bas, (const char *) base); 220438c4b332c4ec2f0db5ee601abaa9b46ec2e272e2William M. Brack if (ret != 0) 220538c4b332c4ec2f0db5ee601abaa9b46ec2e272e2William M. Brack goto done; /* Error in base, return NULL */ 220638c4b332c4ec2f0db5ee601abaa9b46ec2e272e2William M. Brack } else 220738c4b332c4ec2f0db5ee601abaa9b46ec2e272e2William M. Brack bas->path = (char *)xmlStrdup(base); 2208f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack 2209f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack /* 2210f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * If the scheme / server on the URI differs from the base, 2211f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * just return the URI 2212f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack */ 2213f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack if ((ref->scheme != NULL) && 22140f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard ((bas->scheme == NULL) || 22150f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard (xmlStrcmp ((xmlChar *)bas->scheme, (xmlChar *)ref->scheme)) || 22160f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard (xmlStrcmp ((xmlChar *)bas->server, (xmlChar *)ref->server)))) { 2217f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack val = xmlStrdup (URI); 2218f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack goto done; 2219f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack } 22200f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard if (xmlStrEqual((xmlChar *)bas->path, (xmlChar *)ref->path)) { 22210f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard val = xmlStrdup(BAD_CAST ""); 22220f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard goto done; 22230f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard } 22240f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard if (bas->path == NULL) { 22250f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard val = xmlStrdup((xmlChar *)ref->path); 22260f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard goto done; 22270f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard } 22280f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard if (ref->path == NULL) { 22290f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard ref->path = (char *) "/"; 22300f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard remove_path = 1; 22310f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard } 2232f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack 2233f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack /* 2234f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * At this point (at last!) we can compare the two paths 2235f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * 2236820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack * First we take care of the special case where either of the 2237820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack * two path components may be missing (bug 316224) 2238f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack */ 2239820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack if (bas->path == NULL) { 2240820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack if (ref->path != NULL) { 22410f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard uptr = (xmlChar *) ref->path; 2242820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack if (*uptr == '/') 2243820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack uptr++; 2244504201966dbcc76b0d3c60d85e36133188620f6cWilliam M. Brack /* exception characters from xmlSaveUri */ 2245504201966dbcc76b0d3c60d85e36133188620f6cWilliam M. Brack val = xmlURIEscapeStr(uptr, BAD_CAST "/;&=+$,"); 2246820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack } 2247820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack goto done; 2248f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack } 2249820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack bptr = (xmlChar *)bas->path; 2250820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack if (ref->path == NULL) { 2251820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack for (ix = 0; bptr[ix] != 0; ix++) { 2252820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack if (bptr[ix] == '/') 2253820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack nbslash++; 2254820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack } 2255820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack uptr = NULL; 2256820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack len = 1; /* this is for a string terminator only */ 2257f2a657aa599bf9e9a1cbf4082ba885d177f05697William M. Brack } else { 2258f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack /* 2259820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack * Next we compare the two strings and find where they first differ 2260f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack */ 2261820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack if ((ref->path[pos] == '.') && (ref->path[pos+1] == '/')) 2262820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack pos += 2; 2263820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack if ((*bptr == '.') && (bptr[1] == '/')) 2264820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack bptr += 2; 2265820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack else if ((*bptr == '/') && (ref->path[pos] != '/')) 2266820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack bptr++; 2267820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack while ((bptr[pos] == ref->path[pos]) && (bptr[pos] != 0)) 2268820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack pos++; 2269820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack 2270820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack if (bptr[pos] == ref->path[pos]) { 22710f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard val = xmlStrdup(BAD_CAST ""); 2272820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack goto done; /* (I can't imagine why anyone would do this) */ 2273820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack } 2274820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack 2275820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack /* 2276820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack * In URI, "back up" to the last '/' encountered. This will be the 2277820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack * beginning of the "unique" suffix of URI 2278820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack */ 2279820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack ix = pos; 2280820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack if ((ref->path[ix] == '/') && (ix > 0)) 2281820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack ix--; 22820f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard else if ((ref->path[ix] == 0) && (ix > 1) && (ref->path[ix - 1] == '/')) 22830f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard ix -= 2; 2284820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack for (; ix > 0; ix--) { 2285820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack if (ref->path[ix] == '/') 2286820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack break; 2287820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack } 2288820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack if (ix == 0) { 2289820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack uptr = (xmlChar *)ref->path; 2290820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack } else { 2291820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack ix++; 2292820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack uptr = (xmlChar *)&ref->path[ix]; 2293f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack } 2294f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack 2295820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack /* 2296820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack * In base, count the number of '/' from the differing point 2297820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack */ 2298820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack if (bptr[pos] != ref->path[pos]) {/* check for trivial URI == base */ 2299820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack for (; bptr[ix] != 0; ix++) { 2300820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack if (bptr[ix] == '/') 2301820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack nbslash++; 2302820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack } 2303820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack } 2304820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack len = xmlStrlen (uptr) + 1; 2305820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack } 230657560386503be0fd023f3b7537fd496784f3be18Daniel Veillard 2307f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack if (nbslash == 0) { 2308820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack if (uptr != NULL) 2309504201966dbcc76b0d3c60d85e36133188620f6cWilliam M. Brack /* exception characters from xmlSaveUri */ 2310504201966dbcc76b0d3c60d85e36133188620f6cWilliam M. Brack val = xmlURIEscapeStr(uptr, BAD_CAST "/;&=+$,"); 2311f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack goto done; 2312f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack } 2313f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack 2314f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack /* 2315f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * Allocate just enough space for the returned string - 2316f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * length of the remainder of the URI, plus enough space 2317f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * for the "../" groups, plus one for the terminator 2318f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack */ 2319820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack val = (xmlChar *) xmlMalloc (len + 3 * nbslash); 2320f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack if (val == NULL) { 232157560386503be0fd023f3b7537fd496784f3be18Daniel Veillard xmlURIErrMemory("building relative URI\n"); 2322f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack goto done; 2323f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack } 2324f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack vptr = val; 2325f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack /* 2326f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * Put in as many "../" as needed 2327f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack */ 2328f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack for (; nbslash>0; nbslash--) { 2329f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack *vptr++ = '.'; 2330f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack *vptr++ = '.'; 2331f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack *vptr++ = '/'; 2332f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack } 2333f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack /* 2334f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * Finish up with the end of the URI 2335f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack */ 23360f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard if (uptr != NULL) { 23370f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard if ((vptr > val) && (len > 0) && 23380f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard (uptr[0] == '/') && (vptr[-1] == '/')) { 23390f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard memcpy (vptr, uptr + 1, len - 1); 23400f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard vptr[len - 2] = 0; 23410f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard } else { 23420f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard memcpy (vptr, uptr, len); 23430f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard vptr[len - 1] = 0; 23440f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard } 23450f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard } else { 2346820d5ed74771a2efc2a7b42386b9710d4f129e48William M. Brack vptr[len - 1] = 0; 23470f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard } 2348f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack 2349504201966dbcc76b0d3c60d85e36133188620f6cWilliam M. Brack /* escape the freshly-built path */ 2350504201966dbcc76b0d3c60d85e36133188620f6cWilliam M. Brack vptr = val; 2351504201966dbcc76b0d3c60d85e36133188620f6cWilliam M. Brack /* exception characters from xmlSaveUri */ 2352504201966dbcc76b0d3c60d85e36133188620f6cWilliam M. Brack val = xmlURIEscapeStr(vptr, BAD_CAST "/;&=+$,"); 2353504201966dbcc76b0d3c60d85e36133188620f6cWilliam M. Brack xmlFree(vptr); 2354504201966dbcc76b0d3c60d85e36133188620f6cWilliam M. Brack 23550f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillarddone: 2356f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack /* 2357f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack * Free the working variables 2358f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack */ 23590f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard if (remove_path != 0) 23600f7b33101b1850f671e81b15f3aecc7a332c813fDaniel Veillard ref->path = NULL; 2361f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack if (ref != NULL) 2362f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack xmlFreeURI (ref); 2363f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack if (bas != NULL) 2364f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack xmlFreeURI (bas); 2365f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack 2366f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack return val; 2367f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack} 2368f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack 2369f7789b13c59ef9d9e73047543c704c6ab21a6212William M. Brack/** 2370f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic * xmlCanonicPath: 2371f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic * @path: the resource locator in a filesystem notation 2372f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic * 237357560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * Constructs a canonic path from the specified path. 2374f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic * 237557560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * Returns a new canonic path, or a duplicate of the path parameter if the 2376f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic * construction fails. The caller is responsible for freeing the memory occupied 237757560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * by the returned string. If there is insufficient memory available, or the 2378f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic * argument is NULL, the function returns NULL. 2379f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic */ 238057560386503be0fd023f3b7537fd496784f3be18Daniel Veillard#define IS_WINDOWS_PATH(p) \ 2381f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic ((p != NULL) && \ 2382f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic (((p[0] >= 'a') && (p[0] <= 'z')) || \ 2383f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic ((p[0] >= 'A') && (p[0] <= 'Z'))) && \ 2384f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic (p[1] == ':') && ((p[2] == '/') || (p[2] == '\\'))) 2385b8efdda0a31947d5291fcb9221040fdab88dc549Daniel VeillardxmlChar * 2386f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor ZlatkovicxmlCanonicPath(const xmlChar *path) 2387f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic{ 23882224227818b8196ea9250235038e069f6bc03a55William M. Brack/* 23892224227818b8196ea9250235038e069f6bc03a55William M. Brack * For Windows implementations, additional work needs to be done to 23902224227818b8196ea9250235038e069f6bc03a55William M. Brack * replace backslashes in pathnames with "forward slashes" 23912224227818b8196ea9250235038e069f6bc03a55William M. Brack */ 239257560386503be0fd023f3b7537fd496784f3be18Daniel Veillard#if defined(_WIN32) && !defined(__CYGWIN__) 2393ce07616c089bf22653e31e2f7286cfdd8462857fIgor Zlatkovic int len = 0; 2394ce07616c089bf22653e31e2f7286cfdd8462857fIgor Zlatkovic int i = 0; 2395ce07616c089bf22653e31e2f7286cfdd8462857fIgor Zlatkovic xmlChar *p = NULL; 2396c64b8e984c13a0d989dea436c13128b289a4d4d6Daniel Veillard#endif 2397f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic xmlURIPtr uri; 2398336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard xmlChar *ret; 2399336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard const xmlChar *absuri; 2400f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic 2401f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic if (path == NULL) 2402f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic return(NULL); 240369f8a13e52d4d4afd34e7642ce99c9cd0fcd8f03Daniel Veillard 240455b899a23acfa2e1bb36026b50a8f7cb36dc4fdaMichael Stahl#if defined(_WIN32) 240555b899a23acfa2e1bb36026b50a8f7cb36dc4fdaMichael Stahl /* 240655b899a23acfa2e1bb36026b50a8f7cb36dc4fdaMichael Stahl * We must not change the backslashes to slashes if the the path 240755b899a23acfa2e1bb36026b50a8f7cb36dc4fdaMichael Stahl * starts with \\?\ 240855b899a23acfa2e1bb36026b50a8f7cb36dc4fdaMichael Stahl * Those paths can be up to 32k characters long. 240955b899a23acfa2e1bb36026b50a8f7cb36dc4fdaMichael Stahl * Was added specifically for OpenOffice, those paths can't be converted 241055b899a23acfa2e1bb36026b50a8f7cb36dc4fdaMichael Stahl * to URIs anyway. 241155b899a23acfa2e1bb36026b50a8f7cb36dc4fdaMichael Stahl */ 241255b899a23acfa2e1bb36026b50a8f7cb36dc4fdaMichael Stahl if ((path[0] == '\\') && (path[1] == '\\') && (path[2] == '?') && 241355b899a23acfa2e1bb36026b50a8f7cb36dc4fdaMichael Stahl (path[3] == '\\') ) 241455b899a23acfa2e1bb36026b50a8f7cb36dc4fdaMichael Stahl return xmlStrdup((const xmlChar *) path); 241555b899a23acfa2e1bb36026b50a8f7cb36dc4fdaMichael Stahl#endif 241655b899a23acfa2e1bb36026b50a8f7cb36dc4fdaMichael Stahl 241755b899a23acfa2e1bb36026b50a8f7cb36dc4fdaMichael Stahl /* sanitize filename starting with // so it can be used as URI */ 241869f8a13e52d4d4afd34e7642ce99c9cd0fcd8f03Daniel Veillard if ((path[0] == '/') && (path[1] == '/') && (path[2] != '/')) 241969f8a13e52d4d4afd34e7642ce99c9cd0fcd8f03Daniel Veillard path++; 242069f8a13e52d4d4afd34e7642ce99c9cd0fcd8f03Daniel Veillard 2421c64b8e984c13a0d989dea436c13128b289a4d4d6Daniel Veillard if ((uri = xmlParseURI((const char *) path)) != NULL) { 2422f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic xmlFreeURI(uri); 2423f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic return xmlStrdup(path); 2424f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic } 2425f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic 24262224227818b8196ea9250235038e069f6bc03a55William M. Brack /* Check if this is an "absolute uri" */ 2427336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard absuri = xmlStrstr(path, BAD_CAST "://"); 2428336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard if (absuri != NULL) { 2429336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard int l, j; 2430336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard unsigned char c; 2431336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard xmlChar *escURI; 2432336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard 2433336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard /* 2434336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard * this looks like an URI where some parts have not been 24352224227818b8196ea9250235038e069f6bc03a55William M. Brack * escaped leading to a parsing problem. Check that the first 2436336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard * part matches a protocol. 2437336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard */ 2438336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard l = absuri - path; 24392224227818b8196ea9250235038e069f6bc03a55William M. Brack /* Bypass if first part (part before the '://') is > 20 chars */ 2440336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard if ((l <= 0) || (l > 20)) 2441336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard goto path_processing; 24422224227818b8196ea9250235038e069f6bc03a55William M. Brack /* Bypass if any non-alpha characters are present in first part */ 2443336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard for (j = 0;j < l;j++) { 2444336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard c = path[j]; 2445336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard if (!(((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')))) 2446336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard goto path_processing; 2447336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard } 2448336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard 24492224227818b8196ea9250235038e069f6bc03a55William M. Brack /* Escape all except the characters specified in the supplied path */ 2450336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard escURI = xmlURIEscapeStr(path, BAD_CAST ":/?_.#&;="); 2451336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard if (escURI != NULL) { 24522224227818b8196ea9250235038e069f6bc03a55William M. Brack /* Try parsing the escaped path */ 2453336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard uri = xmlParseURI((const char *) escURI); 24542224227818b8196ea9250235038e069f6bc03a55William M. Brack /* If successful, return the escaped string */ 2455336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard if (uri != NULL) { 2456336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard xmlFreeURI(uri); 2457336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard return escURI; 2458336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard } 2459336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard } 2460336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard } 2461336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard 2462336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillardpath_processing: 24632224227818b8196ea9250235038e069f6bc03a55William M. Brack/* For Windows implementations, replace backslashes with 'forward slashes' */ 246457560386503be0fd023f3b7537fd496784f3be18Daniel Veillard#if defined(_WIN32) && !defined(__CYGWIN__) 2465336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard /* 24662224227818b8196ea9250235038e069f6bc03a55William M. Brack * Create a URI structure 2467336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard */ 2468f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic uri = xmlCreateURI(); 24692224227818b8196ea9250235038e069f6bc03a55William M. Brack if (uri == NULL) { /* Guard against 'out of memory' */ 2470a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard return(NULL); 2471a76fe5ca11ebf9e9322dfcf7728dc55077086d43Daniel Veillard } 2472f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic 2473f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic len = xmlStrlen(path); 2474f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic if ((len > 2) && IS_WINDOWS_PATH(path)) { 24752224227818b8196ea9250235038e069f6bc03a55William M. Brack /* make the scheme 'file' */ 2476f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic uri->scheme = xmlStrdup(BAD_CAST "file"); 24772224227818b8196ea9250235038e069f6bc03a55William M. Brack /* allocate space for leading '/' + path + string terminator */ 2478b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard uri->path = xmlMallocAtomic(len + 2); 2479b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard if (uri->path == NULL) { 24802224227818b8196ea9250235038e069f6bc03a55William M. Brack xmlFreeURI(uri); /* Guard agains 'out of memory' */ 2481b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard return(NULL); 2482b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard } 24832224227818b8196ea9250235038e069f6bc03a55William M. Brack /* Put in leading '/' plus path */ 2484f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic uri->path[0] = '/'; 2485ce07616c089bf22653e31e2f7286cfdd8462857fIgor Zlatkovic p = uri->path + 1; 2486ce07616c089bf22653e31e2f7286cfdd8462857fIgor Zlatkovic strncpy(p, path, len + 1); 2487ce07616c089bf22653e31e2f7286cfdd8462857fIgor Zlatkovic } else { 2488b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard uri->path = xmlStrdup(path); 2489b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard if (uri->path == NULL) { 2490b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard xmlFreeURI(uri); 2491b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard return(NULL); 2492b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard } 2493ce07616c089bf22653e31e2f7286cfdd8462857fIgor Zlatkovic p = uri->path; 2494ce07616c089bf22653e31e2f7286cfdd8462857fIgor Zlatkovic } 24952224227818b8196ea9250235038e069f6bc03a55William M. Brack /* Now change all occurences of '\' to '/' */ 2496ce07616c089bf22653e31e2f7286cfdd8462857fIgor Zlatkovic while (*p != '\0') { 2497ce07616c089bf22653e31e2f7286cfdd8462857fIgor Zlatkovic if (*p == '\\') 2498ce07616c089bf22653e31e2f7286cfdd8462857fIgor Zlatkovic *p = '/'; 2499ce07616c089bf22653e31e2f7286cfdd8462857fIgor Zlatkovic p++; 2500ce07616c089bf22653e31e2f7286cfdd8462857fIgor Zlatkovic } 25018f3392ef69ec36d34a389336c4df66bcce26969bDaniel Veillard 2502b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard if (uri->scheme == NULL) { 25032224227818b8196ea9250235038e069f6bc03a55William M. Brack ret = xmlStrdup((const xmlChar *) uri->path); 2504b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard } else { 2505b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard ret = xmlSaveUri(uri); 2506b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard } 25078f3392ef69ec36d34a389336c4df66bcce26969bDaniel Veillard 2508f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic xmlFreeURI(uri); 2509336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard#else 2510336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard ret = xmlStrdup((const xmlChar *) path); 2511336a8e13bf013d6cf260c8b78a1129cef1e3662cDaniel Veillard#endif 2512f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic return(ret); 2513f2238e6e553f0fa039ed084c436b38dbb33a0c86Igor Zlatkovic} 25143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor 2515b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard/** 2516b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard * xmlPathToURI: 2517b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard * @path: the resource locator in a filesystem notation 2518b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard * 2519b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard * Constructs an URI expressing the existing path 2520b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard * 252157560386503be0fd023f3b7537fd496784f3be18Daniel Veillard * Returns a new URI, or a duplicate of the path parameter if the 2522b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard * construction fails. The caller is responsible for freeing the memory 2523b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard * occupied by the returned string. If there is insufficient memory available, 2524b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard * or the argument is NULL, the function returns NULL. 2525b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard */ 2526b8efdda0a31947d5291fcb9221040fdab88dc549Daniel VeillardxmlChar * 2527b8efdda0a31947d5291fcb9221040fdab88dc549Daniel VeillardxmlPathToURI(const xmlChar *path) 2528b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard{ 2529b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard xmlURIPtr uri; 2530b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard xmlURI temp; 2531b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard xmlChar *ret, *cal; 2532b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard 2533b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard if (path == NULL) 2534b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard return(NULL); 2535b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard 2536b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard if ((uri = xmlParseURI((const char *) path)) != NULL) { 2537b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard xmlFreeURI(uri); 2538b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard return xmlStrdup(path); 2539b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard } 2540b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard cal = xmlCanonicPath(path); 2541b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard if (cal == NULL) 2542b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard return(NULL); 2543481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard#if defined(_WIN32) && !defined(__CYGWIN__) 254457560386503be0fd023f3b7537fd496784f3be18Daniel Veillard /* xmlCanonicPath can return an URI on Windows (is that the intended behaviour?) 2545481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard If 'cal' is a valid URI allready then we are done here, as continuing would make 2546481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard it invalid. */ 2547481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard if ((uri = xmlParseURI((const char *) cal)) != NULL) { 2548481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard xmlFreeURI(uri); 2549481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard return cal; 2550481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard } 2551481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard /* 'cal' can contain a relative path with backslashes. If that is processed 2552481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard by xmlSaveURI, they will be escaped and the external entity loader machinery 2553481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard will fail. So convert them to slashes. Misuse 'ret' for walking. */ 2554481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard ret = cal; 2555481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard while (*ret != '\0') { 2556481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard if (*ret == '\\') 2557481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard *ret = '/'; 2558481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard ret++; 2559481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard } 2560481dcfcff3945620a05b8cdbc2f3c7aa5de7a470Daniel Veillard#endif 2561b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard memset(&temp, 0, sizeof(temp)); 2562b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard temp.path = (char *) cal; 2563b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard ret = xmlSaveUri(&temp); 2564b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard xmlFree(cal); 2565b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard return(ret); 2566b8efdda0a31947d5291fcb9221040fdab88dc549Daniel Veillard} 25675d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard#define bottom_uri 25685d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard#include "elfgcchack.h" 2569