Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(63)

Side by Side Diff: third_party/libxml/uri.c

Issue 2951008: Update libxml to 2.7.7. (Closed) Base URL: http://src.chromium.org/git/chromium.git
Patch Set: Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /** 1 /**
2 * uri.c: set of generic URI related routines 2 * uri.c: set of generic URI related routines
3 * 3 *
4 * Reference: RFCs 2396, 2732 and 2373 4 * Reference: RFCs 3986, 2732 and 2373
5 * 5 *
6 * See Copyright for the status of this software. 6 * See Copyright for the status of this software.
7 * 7 *
8 * daniel@veillard.com 8 * daniel@veillard.com
9 */ 9 */
10 10
11 #define IN_LIBXML 11 #define IN_LIBXML
12 #include "libxml.h" 12 #include "libxml.h"
13 13
14 #include <string.h> 14 #include <string.h>
15 15
16 #include <libxml/xmlmemory.h> 16 #include <libxml/xmlmemory.h>
17 #include <libxml/uri.h> 17 #include <libxml/uri.h>
18 #include <libxml/globals.h> 18 #include <libxml/globals.h>
19 #include <libxml/xmlerror.h> 19 #include <libxml/xmlerror.h>
20 20
21 /************************************************************************ 21 static void xmlCleanURI(xmlURIPtr uri);
22 *» » » » » » » » » *
23 *» » Macros to differentiate various character type» » *
24 *» » » directly extracted from RFC 2396» » *
25 *» » » » » » » » » *
26 ************************************************************************/
27 22
28 /* 23 /*
24 * Old rule from 2396 used in legacy handling code
29 * alpha = lowalpha | upalpha 25 * alpha = lowalpha | upalpha
30 */ 26 */
31 #define IS_ALPHA(x) (IS_LOWALPHA(x) || IS_UPALPHA(x)) 27 #define IS_ALPHA(x) (IS_LOWALPHA(x) || IS_UPALPHA(x))
32 28
33 29
34 /* 30 /*
35 * lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | 31 * lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" |
36 * "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | 32 * "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" |
37 * "u" | "v" | "w" | "x" | "y" | "z" 33 * "u" | "v" | "w" | "x" | "y" | "z"
38 */ 34 */
(...skipping 15 matching lines...) Expand all
54 */ 50 */
55 #define IS_DIGIT(x) (((x) >= '0') && ((x) <= '9')) 51 #define IS_DIGIT(x) (((x) >= '0') && ((x) <= '9'))
56 52
57 /* 53 /*
58 * alphanum = alpha | digit 54 * alphanum = alpha | digit
59 */ 55 */
60 56
61 #define IS_ALPHANUM(x) (IS_ALPHA(x) || IS_DIGIT(x)) 57 #define IS_ALPHANUM(x) (IS_ALPHA(x) || IS_DIGIT(x))
62 58
63 /* 59 /*
64 * hex = digit | "A" | "B" | "C" | "D" | "E" | "F" |
65 * "a" | "b" | "c" | "d" | "e" | "f"
66 */
67
68 #define IS_HEX(x) ((IS_DIGIT(x)) || (((x) >= 'a') && ((x) <= 'f')) || \
69 (((x) >= 'A') && ((x) <= 'F')))
70
71 /*
72 * mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" 60 * mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
73 */ 61 */
74 62
75 #define IS_MARK(x) (((x) == '-') || ((x) == '_') || ((x) == '.') ||» \ 63 #define IS_MARK(x) (((x) == '-') || ((x) == '_') || ((x) == '.') || \
76 ((x) == '!') || ((x) == '~') || ((x) == '*') || ((x) == '\'') ||» \ 64 ((x) == '!') || ((x) == '~') || ((x) == '*') || ((x) == '\'') || \
77 ((x) == '(') || ((x) == ')')) 65 ((x) == '(') || ((x) == ')'))
78 66
67 /*
68 * unwise = "{" | "}" | "|" | "\" | "^" | "`"
69 */
79 70
71 #define IS_UNWISE(p) \
72 (((*(p) == '{')) || ((*(p) == '}')) || ((*(p) == '|')) || \
73 ((*(p) == '\\')) || ((*(p) == '^')) || ((*(p) == '[')) || \
74 ((*(p) == ']')) || ((*(p) == '`')))
80 /* 75 /*
81 * reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | "," | 76 * reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | "," |
82 * » "[" | "]" 77 * "[" | "]"
83 */ 78 */
84 79
85 #define IS_RESERVED(x) (((x) == ';') || ((x) == '/') || ((x) == '?') ||»\ 80 #define IS_RESERVED(x) (((x) == ';') || ((x) == '/') || ((x) == '?') || \
86 ((x) == ':') || ((x) == '@') || ((x) == '&') || ((x) == '=') ||»\ 81 ((x) == ':') || ((x) == '@') || ((x) == '&') || ((x) == '=') || \
87 » ((x) == '+') || ((x) == '$') || ((x) == ',') || ((x) == '[') || \ 82 ((x) == '+') || ((x) == '$') || ((x) == ',') || ((x) == '[') || \
88 » ((x) == ']')) 83 ((x) == ']'))
89 84
90 /* 85 /*
91 * unreserved = alphanum | mark 86 * unreserved = alphanum | mark
92 */ 87 */
93 88
94 #define IS_UNRESERVED(x) (IS_ALPHANUM(x) || IS_MARK(x)) 89 #define IS_UNRESERVED(x) (IS_ALPHANUM(x) || IS_MARK(x))
95 90
96 /* 91 /*
97 * escaped = "%" hex hex
98 */
99
100 #define IS_ESCAPED(p) ((*(p) == '%') && (IS_HEX((p)[1])) && \
101 (IS_HEX((p)[2])))
102
103 /*
104 * uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" |
105 * "&" | "=" | "+" | "$" | ","
106 */
107 #define IS_URIC_NO_SLASH(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) ||\
108 ((*(p) == ';')) || ((*(p) == '?')) || ((*(p) == ':')) ||\
109 ((*(p) == '@')) || ((*(p) == '&')) || ((*(p) == '=')) ||\
110 ((*(p) == '+')) || ((*(p) == '$')) || ((*(p) == ',')))
111
112 /*
113 * pchar = unreserved | escaped | ":" | "@" | "&" | "=" | "+" | "$" | ","
114 */
115 #define IS_PCHAR(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) || \
116 ((*(p) == ':')) || ((*(p) == '@')) || ((*(p) == '&')) ||\
117 ((*(p) == '=')) || ((*(p) == '+')) || ((*(p) == '$')) ||\
118 ((*(p) == ',')))
119
120 /*
121 * rel_segment = 1*( unreserved | escaped |
122 * ";" | "@" | "&" | "=" | "+" | "$" | "," )
123 */
124
125 #define IS_SEGMENT(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) || \
126 ((*(p) == ';')) || ((*(p) == '@')) || ((*(p) == '&')) || \
127 ((*(p) == '=')) || ((*(p) == '+')) || ((*(p) == '$')) || \
128 ((*(p) == ',')))
129
130 /*
131 * scheme = alpha *( alpha | digit | "+" | "-" | "." )
132 */
133
134 #define IS_SCHEME(x) ((IS_ALPHA(x)) || (IS_DIGIT(x)) || \
135 ((x) == '+') || ((x) == '-') || ((x) == '.'))
136
137 /*
138 * reg_name = 1*( unreserved | escaped | "$" | "," |
139 * ";" | ":" | "@" | "&" | "=" | "+" )
140 */
141
142 #define IS_REG_NAME(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) || \
143 ((*(p) == '$')) || ((*(p) == ',')) || ((*(p) == ';')) || \
144 ((*(p) == ':')) || ((*(p) == '@')) || ((*(p) == '&')) || \
145 ((*(p) == '=')) || ((*(p) == '+')))
146
147 /*
148 * userinfo = *( unreserved | escaped | ";" | ":" | "&" | "=" |
149 * "+" | "$" | "," )
150 */
151 #define IS_USERINFO(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) || \
152 ((*(p) == ';')) || ((*(p) == ':')) || ((*(p) == '&')) || \
153 ((*(p) == '=')) || ((*(p) == '+')) || ((*(p) == '$')) || \
154 ((*(p) == ',')))
155
156 /*
157 * uric = reserved | unreserved | escaped
158 */
159
160 #define IS_URIC(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) || \
161 (IS_RESERVED(*(p))))
162
163 /*
164 * unwise = "{" | "}" | "|" | "\" | "^" | "`"
165 */
166
167 #define IS_UNWISE(p) \
168 (((*(p) == '{')) || ((*(p) == '}')) || ((*(p) == '|')) || \
169 ((*(p) == '\\')) || ((*(p) == '^')) || ((*(p) == '[')) || \
170 ((*(p) == ']')) || ((*(p) == '`')))
171
172 /*
173 * Skip to next pointer char, handle escaped sequences 92 * Skip to next pointer char, handle escaped sequences
174 */ 93 */
175 94
176 #define NEXT(p) ((*p == '%')? p += 3 : p++) 95 #define NEXT(p) ((*p == '%')? p += 3 : p++)
177 96
178 /* 97 /*
179 * Productions from the spec. 98 * Productions from the spec.
180 * 99 *
181 * authority = server | reg_name 100 * authority = server | reg_name
182 * reg_name = 1*( unreserved | escaped | "$" | "," | 101 * reg_name = 1*( unreserved | escaped | "$" | "," |
183 * ";" | ":" | "@" | "&" | "=" | "+" ) 102 * ";" | ":" | "@" | "&" | "=" | "+" )
184 * 103 *
185 * path = [ abs_path | opaque_part ] 104 * path = [ abs_path | opaque_part ]
186 */ 105 */
187 106
188 #define STRNDUP(s, n) (char *) xmlStrndup((const xmlChar *)(s), (n)) 107 #define STRNDUP(s, n) (char *) xmlStrndup((const xmlChar *)(s), (n))
189 108
190 /************************************************************************ 109 /************************************************************************
191 * * 110 * *
111 * RFC 3986 parser *
112 * *
113 ************************************************************************/
114
115 #define ISA_DIGIT(p) ((*(p) >= '0') && (*(p) <= '9'))
116 #define ISA_ALPHA(p) (((*(p) >= 'a') && (*(p) <= 'z')) || \
117 ((*(p) >= 'A') && (*(p) <= 'Z')))
118 #define ISA_HEXDIG(p) \
119 (ISA_DIGIT(p) || ((*(p) >= 'a') && (*(p) <= 'f')) || \
120 ((*(p) >= 'A') && (*(p) <= 'F')))
121
122 /*
123 * sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
124 * / "*" / "+" / "," / ";" / "="
125 */
126 #define ISA_SUB_DELIM(p) \
127 (((*(p) == '!')) || ((*(p) == '$')) || ((*(p) == '&')) || \
128 ((*(p) == '(')) || ((*(p) == ')')) || ((*(p) == '*')) || \
129 ((*(p) == '+')) || ((*(p) == ',')) || ((*(p) == ';')) || \
130 ((*(p) == '=')))
131
132 /*
133 * gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
134 */
135 #define ISA_GEN_DELIM(p) \
136 (((*(p) == ':')) || ((*(p) == '/')) || ((*(p) == '?')) || \
137 ((*(p) == '#')) || ((*(p) == '[')) || ((*(p) == ']')) || \
138 ((*(p) == '@')))
139
140 /*
141 * reserved = gen-delims / sub-delims
142 */
143 #define ISA_RESERVED(p) (ISA_GEN_DELIM(p) || (ISA_SUB_DELIM(p)))
144
145 /*
146 * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
147 */
148 #define ISA_UNRESERVED(p) \
149 ((ISA_ALPHA(p)) || (ISA_DIGIT(p)) || ((*(p) == '-')) || \
150 ((*(p) == '.')) || ((*(p) == '_')) || ((*(p) == '~')))
151
152 /*
153 * pct-encoded = "%" HEXDIG HEXDIG
154 */
155 #define ISA_PCT_ENCODED(p) \
156 ((*(p) == '%') && (ISA_HEXDIG(p + 1)) && (ISA_HEXDIG(p + 2)))
157
158 /*
159 * pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
160 */
161 #define ISA_PCHAR(p) \
162 (ISA_UNRESERVED(p) || ISA_PCT_ENCODED(p) || ISA_SUB_DELIM(p) || \
163 ((*(p) == ':')) || ((*(p) == '@')))
164
165 /**
166 * xmlParse3986Scheme:
167 * @uri: pointer to an URI structure
168 * @str: pointer to the string to analyze
169 *
170 * Parse an URI scheme
171 *
172 * ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
173 *
174 * Returns 0 or the error code
175 */
176 static int
177 xmlParse3986Scheme(xmlURIPtr uri, const char **str) {
178 const char *cur;
179
180 if (str == NULL)
181 return(-1);
182
183 cur = *str;
184 if (!ISA_ALPHA(cur))
185 return(2);
186 cur++;
187 while (ISA_ALPHA(cur) || ISA_DIGIT(cur) ||
188 (*cur == '+') || (*cur == '-') || (*cur == '.')) cur++;
189 if (uri != NULL) {
190 if (uri->scheme != NULL) xmlFree(uri->scheme);
191 uri->scheme = STRNDUP(*str, cur - *str);
192 }
193 *str = cur;
194 return(0);
195 }
196
197 /**
198 * xmlParse3986Fragment:
199 * @uri: pointer to an URI structure
200 * @str: pointer to the string to analyze
201 *
202 * Parse the query part of an URI
203 *
204 * fragment = *( pchar / "/" / "?" )
205 * NOTE: the strict syntax as defined by 3986 does not allow '[' and ']'
206 * in the fragment identifier but this is used very broadly for
207 * xpointer scheme selection, so we are allowing it here to not break
208 * for example all the DocBook processing chains.
209 *
210 * Returns 0 or the error code
211 */
212 static int
213 xmlParse3986Fragment(xmlURIPtr uri, const char **str)
214 {
215 const char *cur;
216
217 if (str == NULL)
218 return (-1);
219
220 cur = *str;
221
222 while ((ISA_PCHAR(cur)) || (*cur == '/') || (*cur == '?') ||
223 (*cur == '[') || (*cur == ']') ||
224 ((uri != NULL) && (uri->cleanup & 1) && (IS_UNWISE(cur))))
225 NEXT(cur);
226 if (uri != NULL) {
227 if (uri->fragment != NULL)
228 xmlFree(uri->fragment);
229 if (uri->cleanup & 2)
230 uri->fragment = STRNDUP(*str, cur - *str);
231 else
232 uri->fragment = xmlURIUnescapeString(*str, cur - *str, NULL);
233 }
234 *str = cur;
235 return (0);
236 }
237
238 /**
239 * xmlParse3986Query:
240 * @uri: pointer to an URI structure
241 * @str: pointer to the string to analyze
242 *
243 * Parse the query part of an URI
244 *
245 * query = *uric
246 *
247 * Returns 0 or the error code
248 */
249 static int
250 xmlParse3986Query(xmlURIPtr uri, const char **str)
251 {
252 const char *cur;
253
254 if (str == NULL)
255 return (-1);
256
257 cur = *str;
258
259 while ((ISA_PCHAR(cur)) || (*cur == '/') || (*cur == '?') ||
260 ((uri != NULL) && (uri->cleanup & 1) && (IS_UNWISE(cur))))
261 NEXT(cur);
262 if (uri != NULL) {
263 if (uri->query != NULL)
264 xmlFree(uri->query);
265 if (uri->cleanup & 2)
266 uri->query = STRNDUP(*str, cur - *str);
267 else
268 uri->query = xmlURIUnescapeString(*str, cur - *str, NULL);
269
270 /* Save the raw bytes of the query as well.
271 * See: http://mail.gnome.org/archives/xml/2007-April/thread.html#00114
272 */
273 if (uri->query_raw != NULL)
274 xmlFree (uri->query_raw);
275 uri->query_raw = STRNDUP (*str, cur - *str);
276 }
277 *str = cur;
278 return (0);
279 }
280
281 /**
282 * xmlParse3986Port:
283 * @uri: pointer to an URI structure
284 * @str: the string to analyze
285 *
286 * Parse a port part and fills in the appropriate fields
287 * of the @uri structure
288 *
289 * port = *DIGIT
290 *
291 * Returns 0 or the error code
292 */
293 static int
294 xmlParse3986Port(xmlURIPtr uri, const char **str)
295 {
296 const char *cur = *str;
297
298 if (ISA_DIGIT(cur)) {
299 if (uri != NULL)
300 uri->port = 0;
301 while (ISA_DIGIT(cur)) {
302 if (uri != NULL)
303 uri->port = uri->port * 10 + (*cur - '0');
304 cur++;
305 }
306 *str = cur;
307 return(0);
308 }
309 return(1);
310 }
311
312 /**
313 * xmlParse3986Userinfo:
314 * @uri: pointer to an URI structure
315 * @str: the string to analyze
316 *
317 * Parse an user informations part and fills in the appropriate fields
318 * of the @uri structure
319 *
320 * userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
321 *
322 * Returns 0 or the error code
323 */
324 static int
325 xmlParse3986Userinfo(xmlURIPtr uri, const char **str)
326 {
327 const char *cur;
328
329 cur = *str;
330 while (ISA_UNRESERVED(cur) || ISA_PCT_ENCODED(cur) ||
331 ISA_SUB_DELIM(cur) || (*cur == ':'))
332 NEXT(cur);
333 if (*cur == '@') {
334 if (uri != NULL) {
335 if (uri->user != NULL) xmlFree(uri->user);
336 if (uri->cleanup & 2)
337 uri->user = STRNDUP(*str, cur - *str);
338 else
339 uri->user = xmlURIUnescapeString(*str, cur - *str, NULL);
340 }
341 *str = cur;
342 return(0);
343 }
344 return(1);
345 }
346
347 /**
348 * xmlParse3986DecOctet:
349 * @str: the string to analyze
350 *
351 * dec-octet = DIGIT ; 0-9
352 * / %x31-39 DIGIT ; 10-99
353 * / "1" 2DIGIT ; 100-199
354 * / "2" %x30-34 DIGIT ; 200-249
355 * / "25" %x30-35 ; 250-255
356 *
357 * Skip a dec-octet.
358 *
359 * Returns 0 if found and skipped, 1 otherwise
360 */
361 static int
362 xmlParse3986DecOctet(const char **str) {
363 const char *cur = *str;
364
365 if (!(ISA_DIGIT(cur)))
366 return(1);
367 if (!ISA_DIGIT(cur+1))
368 cur++;
369 else if ((*cur != '0') && (ISA_DIGIT(cur + 1)) && (!ISA_DIGIT(cur+2)))
370 cur += 2;
371 else if ((*cur == '1') && (ISA_DIGIT(cur + 1)) && (ISA_DIGIT(cur + 2)))
372 cur += 3;
373 else if ((*cur == '2') && (*(cur + 1) >= '0') &&
374 (*(cur + 1) <= '4') && (ISA_DIGIT(cur + 2)))
375 cur += 3;
376 else if ((*cur == '2') && (*(cur + 1) == '5') &&
377 (*(cur + 2) >= '0') && (*(cur + 1) <= '5'))
378 cur += 3;
379 else
380 return(1);
381 *str = cur;
382 return(0);
383 }
384 /**
385 * xmlParse3986Host:
386 * @uri: pointer to an URI structure
387 * @str: the string to analyze
388 *
389 * Parse an host part and fills in the appropriate fields
390 * of the @uri structure
391 *
392 * host = IP-literal / IPv4address / reg-name
393 * IP-literal = "[" ( IPv6address / IPvFuture ) "]"
394 * IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
395 * reg-name = *( unreserved / pct-encoded / sub-delims )
396 *
397 * Returns 0 or the error code
398 */
399 static int
400 xmlParse3986Host(xmlURIPtr uri, const char **str)
401 {
402 const char *cur = *str;
403 const char *host;
404
405 host = cur;
406 /*
407 * IPv6 and future adressing scheme are enclosed between brackets
408 */
409 if (*cur == '[') {
410 cur++;
411 while ((*cur != ']') && (*cur != 0))
412 cur++;
413 if (*cur != ']')
414 return(1);
415 cur++;
416 goto found;
417 }
418 /*
419 * try to parse an IPv4
420 */
421 if (ISA_DIGIT(cur)) {
422 if (xmlParse3986DecOctet(&cur) != 0)
423 goto not_ipv4;
424 if (*cur != '.')
425 goto not_ipv4;
426 cur++;
427 if (xmlParse3986DecOctet(&cur) != 0)
428 goto not_ipv4;
429 if (*cur != '.')
430 goto not_ipv4;
431 if (xmlParse3986DecOctet(&cur) != 0)
432 goto not_ipv4;
433 if (*cur != '.')
434 goto not_ipv4;
435 if (xmlParse3986DecOctet(&cur) != 0)
436 goto not_ipv4;
437 goto found;
438 not_ipv4:
439 cur = *str;
440 }
441 /*
442 * then this should be a hostname which can be empty
443 */
444 while (ISA_UNRESERVED(cur) || ISA_PCT_ENCODED(cur) || ISA_SUB_DELIM(cur))
445 NEXT(cur);
446 found:
447 if (uri != NULL) {
448 if (uri->authority != NULL) xmlFree(uri->authority);
449 uri->authority = NULL;
450 if (uri->server != NULL) xmlFree(uri->server);
451 if (cur != host) {
452 if (uri->cleanup & 2)
453 uri->server = STRNDUP(host, cur - host);
454 else
455 uri->server = xmlURIUnescapeString(host, cur - host, NULL);
456 } else
457 uri->server = NULL;
458 }
459 *str = cur;
460 return(0);
461 }
462
463 /**
464 * xmlParse3986Authority:
465 * @uri: pointer to an URI structure
466 * @str: the string to analyze
467 *
468 * Parse an authority part and fills in the appropriate fields
469 * of the @uri structure
470 *
471 * authority = [ userinfo "@" ] host [ ":" port ]
472 *
473 * Returns 0 or the error code
474 */
475 static int
476 xmlParse3986Authority(xmlURIPtr uri, const char **str)
477 {
478 const char *cur;
479 int ret;
480
481 cur = *str;
482 /*
483 * try to parse an userinfo and check for the trailing @
484 */
485 ret = xmlParse3986Userinfo(uri, &cur);
486 if ((ret != 0) || (*cur != '@'))
487 cur = *str;
488 else
489 cur++;
490 ret = xmlParse3986Host(uri, &cur);
491 if (ret != 0) return(ret);
492 if (*cur == ':') {
493 cur++;
494 ret = xmlParse3986Port(uri, &cur);
495 if (ret != 0) return(ret);
496 }
497 *str = cur;
498 return(0);
499 }
500
501 /**
502 * xmlParse3986Segment:
503 * @str: the string to analyze
504 * @forbid: an optional forbidden character
505 * @empty: allow an empty segment
506 *
507 * Parse a segment and fills in the appropriate fields
508 * of the @uri structure
509 *
510 * segment = *pchar
511 * segment-nz = 1*pchar
512 * segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
513 * ; non-zero-length segment without any colon ":"
514 *
515 * Returns 0 or the error code
516 */
517 static int
518 xmlParse3986Segment(const char **str, char forbid, int empty)
519 {
520 const char *cur;
521
522 cur = *str;
523 if (!ISA_PCHAR(cur)) {
524 if (empty)
525 return(0);
526 return(1);
527 }
528 while (ISA_PCHAR(cur) && (*cur != forbid))
529 NEXT(cur);
530 *str = cur;
531 return (0);
532 }
533
534 /**
535 * xmlParse3986PathAbEmpty:
536 * @uri: pointer to an URI structure
537 * @str: the string to analyze
538 *
539 * Parse an path absolute or empty and fills in the appropriate fields
540 * of the @uri structure
541 *
542 * path-abempty = *( "/" segment )
543 *
544 * Returns 0 or the error code
545 */
546 static int
547 xmlParse3986PathAbEmpty(xmlURIPtr uri, const char **str)
548 {
549 const char *cur;
550 int ret;
551
552 cur = *str;
553
554 while (*cur == '/') {
555 cur++;
556 ret = xmlParse3986Segment(&cur, 0, 1);
557 if (ret != 0) return(ret);
558 }
559 if (uri != NULL) {
560 if (uri->path != NULL) xmlFree(uri->path);
561 if (*str != cur) {
562 if (uri->cleanup & 2)
563 uri->path = STRNDUP(*str, cur - *str);
564 else
565 uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
566 } else {
567 uri->path = NULL;
568 }
569 }
570 *str = cur;
571 return (0);
572 }
573
574 /**
575 * xmlParse3986PathAbsolute:
576 * @uri: pointer to an URI structure
577 * @str: the string to analyze
578 *
579 * Parse an path absolute and fills in the appropriate fields
580 * of the @uri structure
581 *
582 * path-absolute = "/" [ segment-nz *( "/" segment ) ]
583 *
584 * Returns 0 or the error code
585 */
586 static int
587 xmlParse3986PathAbsolute(xmlURIPtr uri, const char **str)
588 {
589 const char *cur;
590 int ret;
591
592 cur = *str;
593
594 if (*cur != '/')
595 return(1);
596 cur++;
597 ret = xmlParse3986Segment(&cur, 0, 0);
598 if (ret == 0) {
599 while (*cur == '/') {
600 cur++;
601 ret = xmlParse3986Segment(&cur, 0, 1);
602 if (ret != 0) return(ret);
603 }
604 }
605 if (uri != NULL) {
606 if (uri->path != NULL) xmlFree(uri->path);
607 if (cur != *str) {
608 if (uri->cleanup & 2)
609 uri->path = STRNDUP(*str, cur - *str);
610 else
611 uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
612 } else {
613 uri->path = NULL;
614 }
615 }
616 *str = cur;
617 return (0);
618 }
619
620 /**
621 * xmlParse3986PathRootless:
622 * @uri: pointer to an URI structure
623 * @str: the string to analyze
624 *
625 * Parse an path without root and fills in the appropriate fields
626 * of the @uri structure
627 *
628 * path-rootless = segment-nz *( "/" segment )
629 *
630 * Returns 0 or the error code
631 */
632 static int
633 xmlParse3986PathRootless(xmlURIPtr uri, const char **str)
634 {
635 const char *cur;
636 int ret;
637
638 cur = *str;
639
640 ret = xmlParse3986Segment(&cur, 0, 0);
641 if (ret != 0) return(ret);
642 while (*cur == '/') {
643 cur++;
644 ret = xmlParse3986Segment(&cur, 0, 1);
645 if (ret != 0) return(ret);
646 }
647 if (uri != NULL) {
648 if (uri->path != NULL) xmlFree(uri->path);
649 if (cur != *str) {
650 if (uri->cleanup & 2)
651 uri->path = STRNDUP(*str, cur - *str);
652 else
653 uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
654 } else {
655 uri->path = NULL;
656 }
657 }
658 *str = cur;
659 return (0);
660 }
661
662 /**
663 * xmlParse3986PathNoScheme:
664 * @uri: pointer to an URI structure
665 * @str: the string to analyze
666 *
667 * Parse an path which is not a scheme and fills in the appropriate fields
668 * of the @uri structure
669 *
670 * path-noscheme = segment-nz-nc *( "/" segment )
671 *
672 * Returns 0 or the error code
673 */
674 static int
675 xmlParse3986PathNoScheme(xmlURIPtr uri, const char **str)
676 {
677 const char *cur;
678 int ret;
679
680 cur = *str;
681
682 ret = xmlParse3986Segment(&cur, ':', 0);
683 if (ret != 0) return(ret);
684 while (*cur == '/') {
685 cur++;
686 ret = xmlParse3986Segment(&cur, 0, 1);
687 if (ret != 0) return(ret);
688 }
689 if (uri != NULL) {
690 if (uri->path != NULL) xmlFree(uri->path);
691 if (cur != *str) {
692 if (uri->cleanup & 2)
693 uri->path = STRNDUP(*str, cur - *str);
694 else
695 uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
696 } else {
697 uri->path = NULL;
698 }
699 }
700 *str = cur;
701 return (0);
702 }
703
704 /**
705 * xmlParse3986HierPart:
706 * @uri: pointer to an URI structure
707 * @str: the string to analyze
708 *
709 * Parse an hierarchical part and fills in the appropriate fields
710 * of the @uri structure
711 *
712 * hier-part = "//" authority path-abempty
713 * / path-absolute
714 * / path-rootless
715 * / path-empty
716 *
717 * Returns 0 or the error code
718 */
719 static int
720 xmlParse3986HierPart(xmlURIPtr uri, const char **str)
721 {
722 const char *cur;
723 int ret;
724
725 cur = *str;
726
727 if ((*cur == '/') && (*(cur + 1) == '/')) {
728 cur += 2;
729 ret = xmlParse3986Authority(uri, &cur);
730 if (ret != 0) return(ret);
731 ret = xmlParse3986PathAbEmpty(uri, &cur);
732 if (ret != 0) return(ret);
733 *str = cur;
734 return(0);
735 } else if (*cur == '/') {
736 ret = xmlParse3986PathAbsolute(uri, &cur);
737 if (ret != 0) return(ret);
738 } else if (ISA_PCHAR(cur)) {
739 ret = xmlParse3986PathRootless(uri, &cur);
740 if (ret != 0) return(ret);
741 } else {
742 /* path-empty is effectively empty */
743 if (uri != NULL) {
744 if (uri->path != NULL) xmlFree(uri->path);
745 uri->path = NULL;
746 }
747 }
748 *str = cur;
749 return (0);
750 }
751
752 /**
753 * xmlParse3986RelativeRef:
754 * @uri: pointer to an URI structure
755 * @str: the string to analyze
756 *
757 * Parse an URI string and fills in the appropriate fields
758 * of the @uri structure
759 *
760 * relative-ref = relative-part [ "?" query ] [ "#" fragment ]
761 * relative-part = "//" authority path-abempty
762 * / path-absolute
763 * / path-noscheme
764 * / path-empty
765 *
766 * Returns 0 or the error code
767 */
768 static int
769 xmlParse3986RelativeRef(xmlURIPtr uri, const char *str) {
770 int ret;
771
772 if ((*str == '/') && (*(str + 1) == '/')) {
773 str += 2;
774 ret = xmlParse3986Authority(uri, &str);
775 if (ret != 0) return(ret);
776 ret = xmlParse3986PathAbEmpty(uri, &str);
777 if (ret != 0) return(ret);
778 } else if (*str == '/') {
779 ret = xmlParse3986PathAbsolute(uri, &str);
780 if (ret != 0) return(ret);
781 } else if (ISA_PCHAR(str)) {
782 ret = xmlParse3986PathNoScheme(uri, &str);
783 if (ret != 0) return(ret);
784 } else {
785 /* path-empty is effectively empty */
786 if (uri != NULL) {
787 if (uri->path != NULL) xmlFree(uri->path);
788 uri->path = NULL;
789 }
790 }
791
792 if (*str == '?') {
793 str++;
794 ret = xmlParse3986Query(uri, &str);
795 if (ret != 0) return(ret);
796 }
797 if (*str == '#') {
798 str++;
799 ret = xmlParse3986Fragment(uri, &str);
800 if (ret != 0) return(ret);
801 }
802 if (*str != 0) {
803 xmlCleanURI(uri);
804 return(1);
805 }
806 return(0);
807 }
808
809
810 /**
811 * xmlParse3986URI:
812 * @uri: pointer to an URI structure
813 * @str: the string to analyze
814 *
815 * Parse an URI string and fills in the appropriate fields
816 * of the @uri structure
817 *
818 * scheme ":" hier-part [ "?" query ] [ "#" fragment ]
819 *
820 * Returns 0 or the error code
821 */
822 static int
823 xmlParse3986URI(xmlURIPtr uri, const char *str) {
824 int ret;
825
826 ret = xmlParse3986Scheme(uri, &str);
827 if (ret != 0) return(ret);
828 if (*str != ':') {
829 return(1);
830 }
831 str++;
832 ret = xmlParse3986HierPart(uri, &str);
833 if (ret != 0) return(ret);
834 if (*str == '?') {
835 str++;
836 ret = xmlParse3986Query(uri, &str);
837 if (ret != 0) return(ret);
838 }
839 if (*str == '#') {
840 str++;
841 ret = xmlParse3986Fragment(uri, &str);
842 if (ret != 0) return(ret);
843 }
844 if (*str != 0) {
845 xmlCleanURI(uri);
846 return(1);
847 }
848 return(0);
849 }
850
851 /**
852 * xmlParse3986URIReference:
853 * @uri: pointer to an URI structure
854 * @str: the string to analyze
855 *
856 * Parse an URI reference string and fills in the appropriate fields
857 * of the @uri structure
858 *
859 * URI-reference = URI / relative-ref
860 *
861 * Returns 0 or the error code
862 */
863 static int
864 xmlParse3986URIReference(xmlURIPtr uri, const char *str) {
865 int ret;
866
867 if (str == NULL)
868 return(-1);
869 xmlCleanURI(uri);
870
871 /*
872 * Try first to parse absolute refs, then fallback to relative if
873 * it fails.
874 */
875 ret = xmlParse3986URI(uri, str);
876 if (ret != 0) {
877 xmlCleanURI(uri);
878 ret = xmlParse3986RelativeRef(uri, str);
879 if (ret != 0) {
880 xmlCleanURI(uri);
881 return(ret);
882 }
883 }
884 return(0);
885 }
886
887 /**
888 * xmlParseURI:
889 * @str: the URI string to analyze
890 *
891 * Parse an URI based on RFC 3986
892 *
893 * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
894 *
895 * Returns a newly built xmlURIPtr or NULL in case of error
896 */
897 xmlURIPtr
898 xmlParseURI(const char *str) {
899 xmlURIPtr uri;
900 int ret;
901
902 if (str == NULL)
903 return(NULL);
904 uri = xmlCreateURI();
905 if (uri != NULL) {
906 ret = xmlParse3986URIReference(uri, str);
907 if (ret) {
908 xmlFreeURI(uri);
909 return(NULL);
910 }
911 }
912 return(uri);
913 }
914
915 /**
916 * xmlParseURIReference:
917 * @uri: pointer to an URI structure
918 * @str: the string to analyze
919 *
920 * Parse an URI reference string based on RFC 3986 and fills in the
921 * appropriate fields of the @uri structure
922 *
923 * URI-reference = URI / relative-ref
924 *
925 * Returns 0 or the error code
926 */
927 int
928 xmlParseURIReference(xmlURIPtr uri, const char *str) {
929 return(xmlParse3986URIReference(uri, str));
930 }
931
932 /**
933 * xmlParseURIRaw:
934 * @str: the URI string to analyze
935 * @raw: if 1 unescaping of URI pieces are disabled
936 *
937 * Parse an URI but allows to keep intact the original fragments.
938 *
939 * URI-reference = URI / relative-ref
940 *
941 * Returns a newly built xmlURIPtr or NULL in case of error
942 */
943 xmlURIPtr
944 xmlParseURIRaw(const char *str, int raw) {
945 xmlURIPtr uri;
946 int ret;
947
948 if (str == NULL)
949 return(NULL);
950 uri = xmlCreateURI();
951 if (uri != NULL) {
952 if (raw) {
953 uri->cleanup |= 2;
954 }
955 ret = xmlParseURIReference(uri, str);
956 if (ret) {
957 xmlFreeURI(uri);
958 return(NULL);
959 }
960 }
961 return(uri);
962 }
963
964 /************************************************************************
965 * *
192 * Generic URI structure functions * 966 * Generic URI structure functions *
193 * * 967 * *
194 ************************************************************************/ 968 ************************************************************************/
195 969
196 /** 970 /**
197 * xmlCreateURI: 971 * xmlCreateURI:
198 * 972 *
199 * Simply creates an empty xmlURI 973 * Simply creates an empty xmlURI
200 * 974 *
201 * Returns the new structure or NULL in case of error 975 * Returns the new structure or NULL in case of error
(...skipping 16 matching lines...) Expand all
218 * xmlSaveUri: 992 * xmlSaveUri:
219 * @uri: pointer to an xmlURI 993 * @uri: pointer to an xmlURI
220 * 994 *
221 * Save the URI as an escaped string 995 * Save the URI as an escaped string
222 * 996 *
223 * Returns a new string (to be deallocated by caller) 997 * Returns a new string (to be deallocated by caller)
224 */ 998 */
225 xmlChar * 999 xmlChar *
226 xmlSaveUri(xmlURIPtr uri) { 1000 xmlSaveUri(xmlURIPtr uri) {
227 xmlChar *ret = NULL; 1001 xmlChar *ret = NULL;
1002 xmlChar *temp;
228 const char *p; 1003 const char *p;
229 int len; 1004 int len;
230 int max; 1005 int max;
231 1006
232 if (uri == NULL) return(NULL); 1007 if (uri == NULL) return(NULL);
233 1008
234 1009
235 max = 80; 1010 max = 80;
236 ret = (xmlChar *) xmlMallocAtomic((max + 1) * sizeof(xmlChar)); 1011 ret = (xmlChar *) xmlMallocAtomic((max + 1) * sizeof(xmlChar));
237 if (ret == NULL) { 1012 if (ret == NULL) {
238 xmlGenericError(xmlGenericErrorContext, 1013 xmlGenericError(xmlGenericErrorContext,
239 "xmlSaveUri: out of memory\n"); 1014 "xmlSaveUri: out of memory\n");
240 return(NULL); 1015 return(NULL);
241 } 1016 }
242 len = 0; 1017 len = 0;
243 1018
244 if (uri->scheme != NULL) { 1019 if (uri->scheme != NULL) {
245 p = uri->scheme; 1020 p = uri->scheme;
246 while (*p != 0) { 1021 while (*p != 0) {
247 if (len >= max) { 1022 if (len >= max) {
248 max *= 2; 1023 max *= 2;
249 » » ret = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar)); 1024 » » temp = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));
250 » » if (ret == NULL) { 1025 » » if (temp == NULL) {
251 xmlGenericError(xmlGenericErrorContext, 1026 xmlGenericError(xmlGenericErrorContext,
252 "xmlSaveUri: out of memory\n"); 1027 "xmlSaveUri: out of memory\n");
1028 xmlFree(ret);
253 return(NULL); 1029 return(NULL);
254 } 1030 }
1031 ret = temp;
255 } 1032 }
256 ret[len++] = *p++; 1033 ret[len++] = *p++;
257 } 1034 }
258 if (len >= max) { 1035 if (len >= max) {
259 max *= 2; 1036 max *= 2;
260 » ret = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar)); 1037 » temp = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));
261 » if (ret == NULL) { 1038 » if (temp == NULL) {
262 xmlGenericError(xmlGenericErrorContext, 1039 xmlGenericError(xmlGenericErrorContext,
263 "xmlSaveUri: out of memory\n"); 1040 "xmlSaveUri: out of memory\n");
1041 xmlFree(ret);
264 return(NULL); 1042 return(NULL);
265 } 1043 }
1044 ret = temp;
266 } 1045 }
267 ret[len++] = ':'; 1046 ret[len++] = ':';
268 } 1047 }
269 if (uri->opaque != NULL) { 1048 if (uri->opaque != NULL) {
270 p = uri->opaque; 1049 p = uri->opaque;
271 while (*p != 0) { 1050 while (*p != 0) {
272 if (len + 3 >= max) { 1051 if (len + 3 >= max) {
273 max *= 2; 1052 max *= 2;
274 » » ret = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar)); 1053 » » temp = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));
275 » » if (ret == NULL) { 1054 » » if (temp == NULL) {
276 xmlGenericError(xmlGenericErrorContext, 1055 xmlGenericError(xmlGenericErrorContext,
277 "xmlSaveUri: out of memory\n"); 1056 "xmlSaveUri: out of memory\n");
1057 xmlFree(ret);
278 return(NULL); 1058 return(NULL);
279 } 1059 }
1060 ret = temp;
280 } 1061 }
281 if (IS_RESERVED(*(p)) || IS_UNRESERVED(*(p))) 1062 if (IS_RESERVED(*(p)) || IS_UNRESERVED(*(p)))
282 ret[len++] = *p++; 1063 ret[len++] = *p++;
283 else { 1064 else {
284 int val = *(unsigned char *)p++; 1065 int val = *(unsigned char *)p++;
285 int hi = val / 0x10, lo = val % 0x10; 1066 int hi = val / 0x10, lo = val % 0x10;
286 ret[len++] = '%'; 1067 ret[len++] = '%';
287 ret[len++] = hi + (hi > 9? 'A'-10 : '0'); 1068 ret[len++] = hi + (hi > 9? 'A'-10 : '0');
288 ret[len++] = lo + (lo > 9? 'A'-10 : '0'); 1069 ret[len++] = lo + (lo > 9? 'A'-10 : '0');
289 } 1070 }
290 } 1071 }
291 } else { 1072 } else {
292 if (uri->server != NULL) { 1073 if (uri->server != NULL) {
293 if (len + 3 >= max) { 1074 if (len + 3 >= max) {
294 max *= 2; 1075 max *= 2;
295 » » ret = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar)); 1076 » » temp = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));
296 » » if (ret == NULL) { 1077 » » if (temp == NULL) {
297 xmlGenericError(xmlGenericErrorContext, 1078 xmlGenericError(xmlGenericErrorContext,
298 "xmlSaveUri: out of memory\n"); 1079 "xmlSaveUri: out of memory\n");
1080 xmlFree(ret);
299 return(NULL); 1081 return(NULL);
300 } 1082 }
1083 ret = temp;
301 } 1084 }
302 ret[len++] = '/'; 1085 ret[len++] = '/';
303 ret[len++] = '/'; 1086 ret[len++] = '/';
304 if (uri->user != NULL) { 1087 if (uri->user != NULL) {
305 p = uri->user; 1088 p = uri->user;
306 while (*p != 0) { 1089 while (*p != 0) {
307 if (len + 3 >= max) { 1090 if (len + 3 >= max) {
308 max *= 2; 1091 max *= 2;
309 » » » ret = (xmlChar *) xmlRealloc(ret, 1092 » » » temp = (xmlChar *) xmlRealloc(ret,
310 (max + 1) * sizeof(xmlChar)); 1093 (max + 1) * sizeof(xmlChar));
311 » » » if (ret == NULL) { 1094 » » » if (temp == NULL) {
312 xmlGenericError(xmlGenericErrorContext, 1095 xmlGenericError(xmlGenericErrorContext,
313 "xmlSaveUri: out of memory\n"); 1096 "xmlSaveUri: out of memory\n");
1097 xmlFree(ret);
314 return(NULL); 1098 return(NULL);
315 } 1099 }
1100 ret = temp;
316 } 1101 }
317 if ((IS_UNRESERVED(*(p))) || 1102 if ((IS_UNRESERVED(*(p))) ||
318 ((*(p) == ';')) || ((*(p) == ':')) || 1103 ((*(p) == ';')) || ((*(p) == ':')) ||
319 ((*(p) == '&')) || ((*(p) == '=')) || 1104 ((*(p) == '&')) || ((*(p) == '=')) ||
320 ((*(p) == '+')) || ((*(p) == '$')) || 1105 ((*(p) == '+')) || ((*(p) == '$')) ||
321 ((*(p) == ','))) 1106 ((*(p) == ',')))
322 ret[len++] = *p++; 1107 ret[len++] = *p++;
323 else { 1108 else {
324 int val = *(unsigned char *)p++; 1109 int val = *(unsigned char *)p++;
325 int hi = val / 0x10, lo = val % 0x10; 1110 int hi = val / 0x10, lo = val % 0x10;
326 ret[len++] = '%'; 1111 ret[len++] = '%';
327 ret[len++] = hi + (hi > 9? 'A'-10 : '0'); 1112 ret[len++] = hi + (hi > 9? 'A'-10 : '0');
328 ret[len++] = lo + (lo > 9? 'A'-10 : '0'); 1113 ret[len++] = lo + (lo > 9? 'A'-10 : '0');
329 } 1114 }
330 } 1115 }
331 if (len + 3 >= max) { 1116 if (len + 3 >= max) {
332 max *= 2; 1117 max *= 2;
333 » » ret = (xmlChar *) xmlRealloc(ret, 1118 » » temp = (xmlChar *) xmlRealloc(ret,
334 (max + 1) * sizeof(xmlChar)); 1119 (max + 1) * sizeof(xmlChar));
335 » » if (ret == NULL) { 1120 » » if (temp == NULL) {
336 xmlGenericError(xmlGenericErrorContext, 1121 xmlGenericError(xmlGenericErrorContext,
337 "xmlSaveUri: out of memory\n"); 1122 "xmlSaveUri: out of memory\n");
1123 xmlFree(ret);
338 return(NULL); 1124 return(NULL);
339 } 1125 }
1126 ret = temp;
340 } 1127 }
341 ret[len++] = '@'; 1128 ret[len++] = '@';
342 } 1129 }
343 p = uri->server; 1130 p = uri->server;
344 while (*p != 0) { 1131 while (*p != 0) {
345 if (len >= max) { 1132 if (len >= max) {
346 max *= 2; 1133 max *= 2;
347 » » ret = (xmlChar *) xmlRealloc(ret, 1134 » » temp = (xmlChar *) xmlRealloc(ret,
348 (max + 1) * sizeof(xmlChar)); 1135 (max + 1) * sizeof(xmlChar));
349 » » if (ret == NULL) { 1136 » » if (temp == NULL) {
350 xmlGenericError(xmlGenericErrorContext, 1137 xmlGenericError(xmlGenericErrorContext,
351 "xmlSaveUri: out of memory\n"); 1138 "xmlSaveUri: out of memory\n");
1139 xmlFree(ret);
352 return(NULL); 1140 return(NULL);
353 } 1141 }
1142 ret = temp;
354 } 1143 }
355 ret[len++] = *p++; 1144 ret[len++] = *p++;
356 } 1145 }
357 if (uri->port > 0) { 1146 if (uri->port > 0) {
358 if (len + 10 >= max) { 1147 if (len + 10 >= max) {
359 max *= 2; 1148 max *= 2;
360 » » ret = (xmlChar *) xmlRealloc(ret, 1149 » » temp = (xmlChar *) xmlRealloc(ret,
361 (max + 1) * sizeof(xmlChar)); 1150 (max + 1) * sizeof(xmlChar));
362 » » if (ret == NULL) { 1151 » » if (temp == NULL) {
363 xmlGenericError(xmlGenericErrorContext, 1152 xmlGenericError(xmlGenericErrorContext,
364 "xmlSaveUri: out of memory\n"); 1153 "xmlSaveUri: out of memory\n");
1154 xmlFree(ret);
365 return(NULL); 1155 return(NULL);
366 } 1156 }
1157 ret = temp;
367 } 1158 }
368 len += snprintf((char *) &ret[len], max - len, ":%d", uri->port) ; 1159 len += snprintf((char *) &ret[len], max - len, ":%d", uri->port) ;
369 } 1160 }
370 } else if (uri->authority != NULL) { 1161 } else if (uri->authority != NULL) {
371 if (len + 3 >= max) { 1162 if (len + 3 >= max) {
372 max *= 2; 1163 max *= 2;
373 » » ret = (xmlChar *) xmlRealloc(ret, 1164 » » temp = (xmlChar *) xmlRealloc(ret,
374 (max + 1) * sizeof(xmlChar)); 1165 (max + 1) * sizeof(xmlChar));
375 » » if (ret == NULL) { 1166 » » if (temp == NULL) {
376 » » xmlGenericError(xmlGenericErrorContext, 1167 » » » xmlGenericError(xmlGenericErrorContext,
377 » » » "xmlSaveUri: out of memory\n"); 1168 » » » » "xmlSaveUri: out of memory\n");
378 » » return(NULL); 1169 xmlFree(ret);
379 » » } 1170 » » » return(NULL);
1171 » » }
1172 » » ret = temp;
380 } 1173 }
381 ret[len++] = '/'; 1174 ret[len++] = '/';
382 ret[len++] = '/'; 1175 ret[len++] = '/';
383 p = uri->authority; 1176 p = uri->authority;
384 while (*p != 0) { 1177 while (*p != 0) {
385 if (len + 3 >= max) { 1178 if (len + 3 >= max) {
386 max *= 2; 1179 max *= 2;
387 » » ret = (xmlChar *) xmlRealloc(ret, 1180 » » temp = (xmlChar *) xmlRealloc(ret,
388 (max + 1) * sizeof(xmlChar)); 1181 (max + 1) * sizeof(xmlChar));
389 » » if (ret == NULL) { 1182 » » if (temp == NULL) {
390 xmlGenericError(xmlGenericErrorContext, 1183 xmlGenericError(xmlGenericErrorContext,
391 "xmlSaveUri: out of memory\n"); 1184 "xmlSaveUri: out of memory\n");
1185 xmlFree(ret);
392 return(NULL); 1186 return(NULL);
393 } 1187 }
1188 ret = temp;
394 } 1189 }
395 if ((IS_UNRESERVED(*(p))) || 1190 if ((IS_UNRESERVED(*(p))) ||
396 ((*(p) == '$')) || ((*(p) == ',')) || ((*(p) == ';')) || 1191 ((*(p) == '$')) || ((*(p) == ',')) || ((*(p) == ';')) ||
397 ((*(p) == ':')) || ((*(p) == '@')) || ((*(p) == '&')) || 1192 ((*(p) == ':')) || ((*(p) == '@')) || ((*(p) == '&')) ||
398 ((*(p) == '=')) || ((*(p) == '+'))) 1193 ((*(p) == '=')) || ((*(p) == '+')))
399 ret[len++] = *p++; 1194 ret[len++] = *p++;
400 else { 1195 else {
401 int val = *(unsigned char *)p++; 1196 int val = *(unsigned char *)p++;
402 int hi = val / 0x10, lo = val % 0x10; 1197 int hi = val / 0x10, lo = val % 0x10;
403 ret[len++] = '%'; 1198 ret[len++] = '%';
404 ret[len++] = hi + (hi > 9? 'A'-10 : '0'); 1199 ret[len++] = hi + (hi > 9? 'A'-10 : '0');
405 ret[len++] = lo + (lo > 9? 'A'-10 : '0'); 1200 ret[len++] = lo + (lo > 9? 'A'-10 : '0');
406 } 1201 }
407 } 1202 }
408 } else if (uri->scheme != NULL) { 1203 } else if (uri->scheme != NULL) {
409 if (len + 3 >= max) { 1204 if (len + 3 >= max) {
410 max *= 2; 1205 max *= 2;
411 » » ret = (xmlChar *) xmlRealloc(ret, 1206 » » temp = (xmlChar *) xmlRealloc(ret,
412 (max + 1) * sizeof(xmlChar)); 1207 (max + 1) * sizeof(xmlChar));
413 » » if (ret == NULL) { 1208 » » if (temp == NULL) {
414 » » xmlGenericError(xmlGenericErrorContext, 1209 » » » xmlGenericError(xmlGenericErrorContext,
415 » » » "xmlSaveUri: out of memory\n"); 1210 » » » » "xmlSaveUri: out of memory\n");
416 » » return(NULL); 1211 xmlFree(ret);
417 » » } 1212 » » » return(NULL);
1213 » » }
1214 » » ret = temp;
418 } 1215 }
419 ret[len++] = '/'; 1216 ret[len++] = '/';
420 ret[len++] = '/'; 1217 ret[len++] = '/';
421 } 1218 }
422 if (uri->path != NULL) { 1219 if (uri->path != NULL) {
423 p = uri->path; 1220 p = uri->path;
424 /* 1221 /*
425 * the colon in file:///d: should not be escaped or 1222 * the colon in file:///d: should not be escaped or
426 * Windows accesses fail later. 1223 * Windows accesses fail later.
427 */ 1224 */
428 if ((uri->scheme != NULL) && 1225 if ((uri->scheme != NULL) &&
429 (p[0] == '/') && 1226 (p[0] == '/') &&
430 (((p[1] >= 'a') && (p[1] <= 'z')) || 1227 (((p[1] >= 'a') && (p[1] <= 'z')) ||
431 ((p[1] >= 'A') && (p[1] <= 'Z'))) && 1228 ((p[1] >= 'A') && (p[1] <= 'Z'))) &&
432 (p[2] == ':') && 1229 (p[2] == ':') &&
433 » (xmlStrEqual(uri->scheme, BAD_CAST "file"))) { 1230 » (xmlStrEqual(BAD_CAST uri->scheme, BAD_CAST "file"))) {
434 if (len + 3 >= max) { 1231 if (len + 3 >= max) {
435 max *= 2; 1232 max *= 2;
436 ret = (xmlChar *) xmlRealloc(ret, 1233 ret = (xmlChar *) xmlRealloc(ret,
437 (max + 1) * sizeof(xmlChar)); 1234 (max + 1) * sizeof(xmlChar));
438 if (ret == NULL) { 1235 if (ret == NULL) {
439 xmlGenericError(xmlGenericErrorContext, 1236 xmlGenericError(xmlGenericErrorContext,
440 "xmlSaveUri: out of memory\n"); 1237 "xmlSaveUri: out of memory\n");
441 return(NULL); 1238 return(NULL);
442 } 1239 }
443 } 1240 }
444 ret[len++] = *p++; 1241 ret[len++] = *p++;
445 ret[len++] = *p++; 1242 ret[len++] = *p++;
446 ret[len++] = *p++; 1243 ret[len++] = *p++;
447 } 1244 }
448 while (*p != 0) { 1245 while (*p != 0) {
449 if (len + 3 >= max) { 1246 if (len + 3 >= max) {
450 max *= 2; 1247 max *= 2;
451 » » ret = (xmlChar *) xmlRealloc(ret, 1248 » » temp = (xmlChar *) xmlRealloc(ret,
452 (max + 1) * sizeof(xmlChar)); 1249 (max + 1) * sizeof(xmlChar));
453 » » if (ret == NULL) { 1250 » » if (temp == NULL) {
454 xmlGenericError(xmlGenericErrorContext, 1251 xmlGenericError(xmlGenericErrorContext,
455 "xmlSaveUri: out of memory\n"); 1252 "xmlSaveUri: out of memory\n");
1253 xmlFree(ret);
456 return(NULL); 1254 return(NULL);
457 } 1255 }
1256 ret = temp;
458 } 1257 }
459 if ((IS_UNRESERVED(*(p))) || ((*(p) == '/')) || 1258 if ((IS_UNRESERVED(*(p))) || ((*(p) == '/')) ||
460 ((*(p) == ';')) || ((*(p) == '@')) || ((*(p) == '&')) || 1259 ((*(p) == ';')) || ((*(p) == '@')) || ((*(p) == '&')) ||
461 ((*(p) == '=')) || ((*(p) == '+')) || ((*(p) == '$')) || 1260 ((*(p) == '=')) || ((*(p) == '+')) || ((*(p) == '$')) ||
462 ((*(p) == ','))) 1261 ((*(p) == ',')))
463 ret[len++] = *p++; 1262 ret[len++] = *p++;
464 else { 1263 else {
465 int val = *(unsigned char *)p++; 1264 int val = *(unsigned char *)p++;
466 int hi = val / 0x10, lo = val % 0x10; 1265 int hi = val / 0x10, lo = val % 0x10;
467 ret[len++] = '%'; 1266 ret[len++] = '%';
468 ret[len++] = hi + (hi > 9? 'A'-10 : '0'); 1267 ret[len++] = hi + (hi > 9? 'A'-10 : '0');
469 ret[len++] = lo + (lo > 9? 'A'-10 : '0'); 1268 ret[len++] = lo + (lo > 9? 'A'-10 : '0');
470 } 1269 }
471 } 1270 }
472 } 1271 }
473 if (uri->query_raw != NULL) { 1272 if (uri->query_raw != NULL) {
474 if (len + 1 >= max) { 1273 if (len + 1 >= max) {
475 max *= 2; 1274 max *= 2;
476 » » ret = (xmlChar *) xmlRealloc(ret, 1275 » » temp = (xmlChar *) xmlRealloc(ret,
477 (max + 1) * sizeof(xmlChar)); 1276 (max + 1) * sizeof(xmlChar));
478 » » if (ret == NULL) { 1277 » » if (temp == NULL) {
479 » » xmlGenericError(xmlGenericErrorContext, 1278 » » » xmlGenericError(xmlGenericErrorContext,
480 » » » "xmlSaveUri: out of memory\n"); 1279 » » » » "xmlSaveUri: out of memory\n");
481 » » return(NULL); 1280 xmlFree(ret);
482 » » } 1281 » » » return(NULL);
1282 » » }
1283 » » ret = temp;
483 } 1284 }
484 ret[len++] = '?'; 1285 ret[len++] = '?';
485 p = uri->query_raw; 1286 p = uri->query_raw;
486 while (*p != 0) { 1287 while (*p != 0) {
487 if (len + 1 >= max) { 1288 if (len + 1 >= max) {
488 max *= 2; 1289 max *= 2;
489 » » ret = (xmlChar *) xmlRealloc(ret, 1290 » » temp = (xmlChar *) xmlRealloc(ret,
490 (max + 1) * sizeof(xmlChar)); 1291 (max + 1) * sizeof(xmlChar));
491 » » if (ret == NULL) { 1292 » » if (temp == NULL) {
492 xmlGenericError(xmlGenericErrorContext, 1293 xmlGenericError(xmlGenericErrorContext,
493 "xmlSaveUri: out of memory\n"); 1294 "xmlSaveUri: out of memory\n");
1295 xmlFree(ret);
494 return(NULL); 1296 return(NULL);
495 } 1297 }
1298 ret = temp;
496 } 1299 }
497 ret[len++] = *p++; 1300 ret[len++] = *p++;
498 } 1301 }
499 } else if (uri->query != NULL) { 1302 } else if (uri->query != NULL) {
500 if (len + 3 >= max) { 1303 if (len + 3 >= max) {
501 max *= 2; 1304 max *= 2;
502 » » ret = (xmlChar *) xmlRealloc(ret, 1305 » » temp = (xmlChar *) xmlRealloc(ret,
503 (max + 1) * sizeof(xmlChar)); 1306 (max + 1) * sizeof(xmlChar));
504 » » if (ret == NULL) { 1307 » » if (temp == NULL) {
505 » » xmlGenericError(xmlGenericErrorContext, 1308 » » » xmlGenericError(xmlGenericErrorContext,
506 » » » "xmlSaveUri: out of memory\n"); 1309 » » » » "xmlSaveUri: out of memory\n");
507 » » return(NULL); 1310 xmlFree(ret);
508 » » } 1311 » » » return(NULL);
1312 » » }
1313 » » ret = temp;
509 } 1314 }
510 ret[len++] = '?'; 1315 ret[len++] = '?';
511 p = uri->query; 1316 p = uri->query;
512 while (*p != 0) { 1317 while (*p != 0) {
513 if (len + 3 >= max) { 1318 if (len + 3 >= max) {
514 max *= 2; 1319 max *= 2;
515 » » ret = (xmlChar *) xmlRealloc(ret, 1320 » » temp = (xmlChar *) xmlRealloc(ret,
516 (max + 1) * sizeof(xmlChar)); 1321 (max + 1) * sizeof(xmlChar));
517 » » if (ret == NULL) { 1322 » » if (temp == NULL) {
518 xmlGenericError(xmlGenericErrorContext, 1323 xmlGenericError(xmlGenericErrorContext,
519 "xmlSaveUri: out of memory\n"); 1324 "xmlSaveUri: out of memory\n");
1325 xmlFree(ret);
520 return(NULL); 1326 return(NULL);
521 } 1327 }
1328 ret = temp;
522 } 1329 }
523 if ((IS_UNRESERVED(*(p))) || (IS_RESERVED(*(p)))) 1330 if ((IS_UNRESERVED(*(p))) || (IS_RESERVED(*(p))))
524 ret[len++] = *p++; 1331 ret[len++] = *p++;
525 else { 1332 else {
526 int val = *(unsigned char *)p++; 1333 int val = *(unsigned char *)p++;
527 int hi = val / 0x10, lo = val % 0x10; 1334 int hi = val / 0x10, lo = val % 0x10;
528 ret[len++] = '%'; 1335 ret[len++] = '%';
529 ret[len++] = hi + (hi > 9? 'A'-10 : '0'); 1336 ret[len++] = hi + (hi > 9? 'A'-10 : '0');
530 ret[len++] = lo + (lo > 9? 'A'-10 : '0'); 1337 ret[len++] = lo + (lo > 9? 'A'-10 : '0');
531 } 1338 }
532 } 1339 }
533 } 1340 }
534 } 1341 }
535 if (uri->fragment != NULL) { 1342 if (uri->fragment != NULL) {
536 if (len + 3 >= max) { 1343 if (len + 3 >= max) {
537 max *= 2; 1344 max *= 2;
538 » ret = (xmlChar *) xmlRealloc(ret, 1345 » temp = (xmlChar *) xmlRealloc(ret,
539 (max + 1) * sizeof(xmlChar)); 1346 (max + 1) * sizeof(xmlChar));
540 » if (ret == NULL) { 1347 » if (temp == NULL) {
541 » » xmlGenericError(xmlGenericErrorContext, 1348 » » » xmlGenericError(xmlGenericErrorContext,
542 » » » "xmlSaveUri: out of memory\n"); 1349 » » » » "xmlSaveUri: out of memory\n");
543 » » return(NULL); 1350 xmlFree(ret);
544 » } 1351 » » » return(NULL);
1352 » » }
1353 » » ret = temp;
545 } 1354 }
546 ret[len++] = '#'; 1355 ret[len++] = '#';
547 p = uri->fragment; 1356 p = uri->fragment;
548 while (*p != 0) { 1357 while (*p != 0) {
549 if (len + 3 >= max) { 1358 if (len + 3 >= max) {
550 max *= 2; 1359 max *= 2;
551 » » ret = (xmlChar *) xmlRealloc(ret, 1360 » » temp = (xmlChar *) xmlRealloc(ret,
552 (max + 1) * sizeof(xmlChar)); 1361 (max + 1) * sizeof(xmlChar));
553 » » if (ret == NULL) { 1362 » » if (temp == NULL) {
554 » » xmlGenericError(xmlGenericErrorContext, 1363 » » » xmlGenericError(xmlGenericErrorContext,
555 » » » "xmlSaveUri: out of memory\n"); 1364 » » » » "xmlSaveUri: out of memory\n");
556 » » return(NULL); 1365 xmlFree(ret);
557 » » } 1366 » » » return(NULL);
1367 » » }
1368 » » ret = temp;
558 } 1369 }
559 if ((IS_UNRESERVED(*(p))) || (IS_RESERVED(*(p)))) 1370 if ((IS_UNRESERVED(*(p))) || (IS_RESERVED(*(p))))
560 ret[len++] = *p++; 1371 ret[len++] = *p++;
561 else { 1372 else {
562 int val = *(unsigned char *)p++; 1373 int val = *(unsigned char *)p++;
563 int hi = val / 0x10, lo = val % 0x10; 1374 int hi = val / 0x10, lo = val % 0x10;
564 ret[len++] = '%'; 1375 ret[len++] = '%';
565 ret[len++] = hi + (hi > 9? 'A'-10 : '0'); 1376 ret[len++] = hi + (hi > 9? 'A'-10 : '0');
566 ret[len++] = lo + (lo > 9? 'A'-10 : '0'); 1377 ret[len++] = lo + (lo > 9? 'A'-10 : '0');
567 } 1378 }
568 } 1379 }
569 } 1380 }
570 if (len >= max) { 1381 if (len >= max) {
571 max *= 2; 1382 max *= 2;
572 » ret = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar)); 1383 » temp = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));
573 » if (ret == NULL) { 1384 » if (temp == NULL) {
574 » xmlGenericError(xmlGenericErrorContext, 1385 » » » xmlGenericError(xmlGenericErrorContext,
575 » » "xmlSaveUri: out of memory\n"); 1386 » » » » "xmlSaveUri: out of memory\n");
576 » return(NULL); 1387 xmlFree(ret);
577 » } 1388 » » » return(NULL);
1389 » » }
1390 » » ret = temp;
578 } 1391 }
579 ret[len++] = 0; 1392 ret[len] = 0;
580 return(ret); 1393 return(ret);
581 } 1394 }
582 1395
583 /** 1396 /**
584 * xmlPrintURI: 1397 * xmlPrintURI:
585 * @stream: a FILE* for the output 1398 * @stream: a FILE* for the output
586 * @uri: pointer to an xmlURI 1399 * @uri: pointer to an xmlURI
587 * 1400 *
588 * Prints the URI in the stream @stream. 1401 * Prints the URI in the stream @stream.
589 */ 1402 */
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
921 * @list: exception list string of chars not to escape 1734 * @list: exception list string of chars not to escape
922 * 1735 *
923 * This routine escapes a string to hex, ignoring reserved characters (a-z) 1736 * This routine escapes a string to hex, ignoring reserved characters (a-z)
924 * and the characters in the exception list. 1737 * and the characters in the exception list.
925 * 1738 *
926 * Returns a new escaped string or NULL in case of error. 1739 * Returns a new escaped string or NULL in case of error.
927 */ 1740 */
928 xmlChar * 1741 xmlChar *
929 xmlURIEscapeStr(const xmlChar *str, const xmlChar *list) { 1742 xmlURIEscapeStr(const xmlChar *str, const xmlChar *list) {
930 xmlChar *ret, ch; 1743 xmlChar *ret, ch;
1744 xmlChar *temp;
931 const xmlChar *in; 1745 const xmlChar *in;
932 1746
933 unsigned int len, out; 1747 unsigned int len, out;
934 1748
935 if (str == NULL) 1749 if (str == NULL)
936 return(NULL); 1750 return(NULL);
937 if (str[0] == 0) 1751 if (str[0] == 0)
938 return(xmlStrdup(str)); 1752 return(xmlStrdup(str));
939 len = xmlStrlen(str); 1753 len = xmlStrlen(str);
940 if (!(len > 0)) return(NULL); 1754 if (!(len > 0)) return(NULL);
941 1755
942 len += 20; 1756 len += 20;
943 ret = (xmlChar *) xmlMallocAtomic(len); 1757 ret = (xmlChar *) xmlMallocAtomic(len);
944 if (ret == NULL) { 1758 if (ret == NULL) {
945 xmlGenericError(xmlGenericErrorContext, 1759 xmlGenericError(xmlGenericErrorContext,
946 "xmlURIEscapeStr: out of memory\n"); 1760 "xmlURIEscapeStr: out of memory\n");
947 return(NULL); 1761 return(NULL);
948 } 1762 }
949 in = (const xmlChar *) str; 1763 in = (const xmlChar *) str;
950 out = 0; 1764 out = 0;
951 while(*in != 0) { 1765 while(*in != 0) {
952 if (len - out <= 3) { 1766 if (len - out <= 3) {
953 len += 20; 1767 len += 20;
954 » ret = (xmlChar *) xmlRealloc(ret, len); 1768 » temp = (xmlChar *) xmlRealloc(ret, len);
955 » if (ret == NULL) { 1769 » if (temp == NULL) {
956 xmlGenericError(xmlGenericErrorContext, 1770 xmlGenericError(xmlGenericErrorContext,
957 "xmlURIEscapeStr: out of memory\n"); 1771 "xmlURIEscapeStr: out of memory\n");
1772 xmlFree(ret);
958 return(NULL); 1773 return(NULL);
959 } 1774 }
1775 ret = temp;
960 } 1776 }
961 1777
962 ch = *in; 1778 ch = *in;
963 1779
964 if ((ch != '@') && (!IS_UNRESERVED(ch)) && (!xmlStrchr(list, ch))) { 1780 if ((ch != '@') && (!IS_UNRESERVED(ch)) && (!xmlStrchr(list, ch))) {
965 unsigned char val; 1781 unsigned char val;
966 ret[out++] = '%'; 1782 ret[out++] = '%';
967 val = ch >> 4; 1783 val = ch >> 4;
968 if (val <= 9) 1784 if (val <= 9)
969 ret[out++] = '0' + val; 1785 ret[out++] = '0' + val;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1002 xmlChar * 1818 xmlChar *
1003 xmlURIEscape(const xmlChar * str) 1819 xmlURIEscape(const xmlChar * str)
1004 { 1820 {
1005 xmlChar *ret, *segment = NULL; 1821 xmlChar *ret, *segment = NULL;
1006 xmlURIPtr uri; 1822 xmlURIPtr uri;
1007 int ret2; 1823 int ret2;
1008 1824
1009 #define NULLCHK(p) if(!p) { \ 1825 #define NULLCHK(p) if(!p) { \
1010 xmlGenericError(xmlGenericErrorContext, \ 1826 xmlGenericError(xmlGenericErrorContext, \
1011 "xmlURIEscape: out of memory\n"); \ 1827 "xmlURIEscape: out of memory\n"); \
1012 return NULL; } 1828 xmlFreeURI(uri); \
1829 return NULL; } \
1013 1830
1014 if (str == NULL) 1831 if (str == NULL)
1015 return (NULL); 1832 return (NULL);
1016 1833
1017 uri = xmlCreateURI(); 1834 uri = xmlCreateURI();
1018 if (uri != NULL) { 1835 if (uri != NULL) {
1019 /* 1836 /*
1020 * Allow escaping errors in the unescaped form 1837 * Allow escaping errors in the unescaped form
1021 */ 1838 */
1022 uri->cleanup = 1; 1839 uri->cleanup = 1;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1055 ret = xmlStrcat(ret,BAD_CAST "//"); 1872 ret = xmlStrcat(ret,BAD_CAST "//");
1056 ret = xmlStrcat(ret, segment); 1873 ret = xmlStrcat(ret, segment);
1057 ret = xmlStrcat(ret, BAD_CAST "@"); 1874 ret = xmlStrcat(ret, BAD_CAST "@");
1058 xmlFree(segment); 1875 xmlFree(segment);
1059 } 1876 }
1060 1877
1061 if (uri->server) { 1878 if (uri->server) {
1062 segment = xmlURIEscapeStr(BAD_CAST uri->server, BAD_CAST "/?;:@"); 1879 segment = xmlURIEscapeStr(BAD_CAST uri->server, BAD_CAST "/?;:@");
1063 NULLCHK(segment) 1880 NULLCHK(segment)
1064 if (uri->user == NULL) 1881 if (uri->user == NULL)
1065 »» ret = xmlStrcat(ret, BAD_CAST "//"); 1882 » » ret = xmlStrcat(ret, BAD_CAST "//");
1066 ret = xmlStrcat(ret, segment); 1883 ret = xmlStrcat(ret, segment);
1067 xmlFree(segment); 1884 xmlFree(segment);
1068 } 1885 }
1069 1886
1070 if (uri->port) { 1887 if (uri->port) {
1071 xmlChar port[10]; 1888 xmlChar port[10];
1072 1889
1073 snprintf((char *) port, 10, "%d", uri->port); 1890 snprintf((char *) port, 10, "%d", uri->port);
1074 ret = xmlStrcat(ret, BAD_CAST ":"); 1891 ret = xmlStrcat(ret, BAD_CAST ":");
1075 ret = xmlStrcat(ret, port); 1892 ret = xmlStrcat(ret, port);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1112 } 1929 }
1113 1930
1114 xmlFreeURI(uri); 1931 xmlFreeURI(uri);
1115 #undef NULLCHK 1932 #undef NULLCHK
1116 1933
1117 return (ret); 1934 return (ret);
1118 } 1935 }
1119 1936
1120 /************************************************************************ 1937 /************************************************************************
1121 * * 1938 * *
1122 * Escaped URI parsing *
1123 * *
1124 ************************************************************************/
1125
1126 /**
1127 * xmlParseURIFragment:
1128 * @uri: pointer to an URI structure
1129 * @str: pointer to the string to analyze
1130 *
1131 * Parse an URI fragment string and fills in the appropriate fields
1132 * of the @uri structure.
1133 *
1134 * fragment = *uric
1135 *
1136 * Returns 0 or the error code
1137 */
1138 static int
1139 xmlParseURIFragment(xmlURIPtr uri, const char **str)
1140 {
1141 const char *cur;
1142
1143 if (str == NULL)
1144 return (-1);
1145
1146 cur = *str;
1147
1148 while (IS_URIC(cur) || IS_UNWISE(cur))
1149 NEXT(cur);
1150 if (uri != NULL) {
1151 if (uri->fragment != NULL)
1152 xmlFree(uri->fragment);
1153 if (uri->cleanup & 2)
1154 uri->fragment = STRNDUP(*str, cur - *str);
1155 else
1156 uri->fragment = xmlURIUnescapeString(*str, cur - *str, NULL);
1157 }
1158 *str = cur;
1159 return (0);
1160 }
1161
1162 /**
1163 * xmlParseURIQuery:
1164 * @uri: pointer to an URI structure
1165 * @str: pointer to the string to analyze
1166 *
1167 * Parse the query part of an URI
1168 *
1169 * query = *uric
1170 *
1171 * Returns 0 or the error code
1172 */
1173 static int
1174 xmlParseURIQuery(xmlURIPtr uri, const char **str)
1175 {
1176 const char *cur;
1177
1178 if (str == NULL)
1179 return (-1);
1180
1181 cur = *str;
1182
1183 while ((IS_URIC(cur)) ||
1184 ((uri != NULL) && (uri->cleanup & 1) && (IS_UNWISE(cur))))
1185 NEXT(cur);
1186 if (uri != NULL) {
1187 if (uri->query != NULL)
1188 xmlFree(uri->query);
1189 if (uri->cleanup & 2)
1190 uri->query = STRNDUP(*str, cur - *str);
1191 else
1192 uri->query = xmlURIUnescapeString(*str, cur - *str, NULL);
1193
1194 /* Save the raw bytes of the query as well.
1195 * See: http://mail.gnome.org/archives/xml/2007-April/thread.html#00114
1196 */
1197 if (uri->query_raw != NULL)
1198 xmlFree (uri->query_raw);
1199 uri->query_raw = STRNDUP (*str, cur - *str);
1200 }
1201 *str = cur;
1202 return (0);
1203 }
1204
1205 /**
1206 * xmlParseURIScheme:
1207 * @uri: pointer to an URI structure
1208 * @str: pointer to the string to analyze
1209 *
1210 * Parse an URI scheme
1211 *
1212 * scheme = alpha *( alpha | digit | "+" | "-" | "." )
1213 *
1214 * Returns 0 or the error code
1215 */
1216 static int
1217 xmlParseURIScheme(xmlURIPtr uri, const char **str) {
1218 const char *cur;
1219
1220 if (str == NULL)
1221 return(-1);
1222
1223 cur = *str;
1224 if (!IS_ALPHA(*cur))
1225 return(2);
1226 cur++;
1227 while (IS_SCHEME(*cur)) cur++;
1228 if (uri != NULL) {
1229 if (uri->scheme != NULL) xmlFree(uri->scheme);
1230 uri->scheme = STRNDUP(*str, cur - *str);
1231 }
1232 *str = cur;
1233 return(0);
1234 }
1235
1236 /**
1237 * xmlParseURIOpaquePart:
1238 * @uri: pointer to an URI structure
1239 * @str: pointer to the string to analyze
1240 *
1241 * Parse an URI opaque part
1242 *
1243 * opaque_part = uric_no_slash *uric
1244 *
1245 * Returns 0 or the error code
1246 */
1247 static int
1248 xmlParseURIOpaquePart(xmlURIPtr uri, const char **str)
1249 {
1250 const char *cur;
1251
1252 if (str == NULL)
1253 return (-1);
1254
1255 cur = *str;
1256 if (!((IS_URIC_NO_SLASH(cur)) ||
1257 ((uri != NULL) && (uri->cleanup & 1) && (IS_UNWISE(cur))))) {
1258 return (3);
1259 }
1260 NEXT(cur);
1261 while ((IS_URIC(cur)) ||
1262 ((uri != NULL) && (uri->cleanup & 1) && (IS_UNWISE(cur))))
1263 NEXT(cur);
1264 if (uri != NULL) {
1265 if (uri->opaque != NULL)
1266 xmlFree(uri->opaque);
1267 if (uri->cleanup & 2)
1268 uri->opaque = STRNDUP(*str, cur - *str);
1269 else
1270 uri->opaque = xmlURIUnescapeString(*str, cur - *str, NULL);
1271 }
1272 *str = cur;
1273 return (0);
1274 }
1275
1276 /**
1277 * xmlParseURIServer:
1278 * @uri: pointer to an URI structure
1279 * @str: pointer to the string to analyze
1280 *
1281 * Parse a server subpart of an URI, it's a finer grain analysis
1282 * of the authority part.
1283 *
1284 * server = [ [ userinfo "@" ] hostport ]
1285 * userinfo = *( unreserved | escaped |
1286 * ";" | ":" | "&" | "=" | "+" | "$" | "," )
1287 * hostport = host [ ":" port ]
1288 * host = hostname | IPv4address | IPv6reference
1289 * hostname = *( domainlabel "." ) toplabel [ "." ]
1290 * domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
1291 * toplabel = alpha | alpha *( alphanum | "-" ) alphanum
1292 * IPv6reference = "[" IPv6address "]"
1293 * IPv6address = hexpart [ ":" IPv4address ]
1294 * IPv4address = 1*3digit "." 1*3digit "." 1*3digit "." 1*3digit
1295 * hexpart = hexseq | hexseq "::" [ hexseq ]| "::" [ hexseq ]
1296 * hexseq = hex4 *( ":" hex4)
1297 * hex4 = 1*4hexdig
1298 * port = *digit
1299 *
1300 * Returns 0 or the error code
1301 */
1302 static int
1303 xmlParseURIServer(xmlURIPtr uri, const char **str) {
1304 const char *cur;
1305 const char *host, *tmp;
1306 const int IPV4max = 4;
1307 const int IPV6max = 8;
1308 int oct;
1309
1310 if (str == NULL)
1311 return(-1);
1312
1313 cur = *str;
1314
1315 /*
1316 * is there a userinfo ?
1317 */
1318 while (IS_USERINFO(cur)) NEXT(cur);
1319 if (*cur == '@') {
1320 if (uri != NULL) {
1321 if (uri->user != NULL) xmlFree(uri->user);
1322 if (uri->cleanup & 2)
1323 uri->user = STRNDUP(*str, cur - *str);
1324 else
1325 uri->user = xmlURIUnescapeString(*str, cur - *str, NULL);
1326 }
1327 cur++;
1328 } else {
1329 if (uri != NULL) {
1330 if (uri->user != NULL) xmlFree(uri->user);
1331 uri->user = NULL;
1332 }
1333 cur = *str;
1334 }
1335 /*
1336 * This can be empty in the case where there is no server
1337 */
1338 host = cur;
1339 if (*cur == '/') {
1340 if (uri != NULL) {
1341 if (uri->authority != NULL) xmlFree(uri->authority);
1342 uri->authority = NULL;
1343 if (uri->server != NULL) xmlFree(uri->server);
1344 uri->server = NULL;
1345 uri->port = 0;
1346 }
1347 return(0);
1348 }
1349 /*
1350 * host part of hostport can denote an IPV4 address, an IPV6 address
1351 * or an unresolved name. Check the IP first, its easier to detect
1352 * errors if wrong one.
1353 * An IPV6 address must start with a '[' and end with a ']'.
1354 */
1355 if (*cur == '[') {
1356 int compress=0;
1357 cur++;
1358 for (oct = 0; oct < IPV6max; ++oct) {
1359 if (*cur == ':') {
1360 if (compress)
1361 return(3); /* multiple compression attempted */
1362 if (!oct) { /* initial char is compression */
1363 if (*++cur != ':')
1364 return(3);
1365 }
1366 compress = 1; /* set compression-encountered flag */
1367 cur++; /* skip over the second ':' */
1368 continue;
1369 }
1370 while(IS_HEX(*cur)) cur++;
1371 if (oct == (IPV6max-1))
1372 continue;
1373 if (*cur != ':')
1374 break;
1375 cur++;
1376 }
1377 if ((!compress) && (oct != IPV6max))
1378 return(3);
1379 if (*cur != ']')
1380 return(3);
1381 if (uri != NULL) {
1382 if (uri->server != NULL) xmlFree(uri->server);
1383 uri->server = (char *)xmlStrndup((xmlChar *)host+1,
1384 (cur-host)-1);
1385 }
1386 cur++;
1387 } else {
1388 /*
1389 * Not IPV6, maybe IPV4
1390 */
1391 for (oct = 0; oct < IPV4max; ++oct) {
1392 if (*cur == '.')
1393 return(3); /* e.g. http://.xml/ or http://18.29..30/ */
1394 while(IS_DIGIT(*cur)) cur++;
1395 if (oct == (IPV4max-1))
1396 continue;
1397 if (*cur != '.')
1398 break;
1399 cur++;
1400 }
1401 }
1402 if ((host[0] != '[') && (oct < IPV4max || (*cur == '.' && cur++) ||
1403 IS_ALPHA(*cur))) {
1404 /* maybe host_name */
1405 if (!IS_ALPHANUM(*cur))
1406 return(4); /* e.g. http://xml.$oft */
1407 do {
1408 do ++cur; while (IS_ALPHANUM(*cur));
1409 if (*cur == '-') {
1410 --cur;
1411 if (*cur == '.')
1412 return(5); /* e.g. http://xml.-soft */
1413 ++cur;
1414 continue;
1415 }
1416 if (*cur == '.') {
1417 --cur;
1418 if (*cur == '-')
1419 return(6); /* e.g. http://xml-.soft */
1420 if (*cur == '.')
1421 return(7); /* e.g. http://xml..soft */
1422 ++cur;
1423 continue;
1424 }
1425 break;
1426 } while (1);
1427 tmp = cur;
1428 if (tmp[-1] == '.')
1429 --tmp; /* e.g. http://xml.$Oft/ */
1430 do --tmp; while (tmp >= host && IS_ALPHANUM(*tmp));
1431 if ((++tmp == host || tmp[-1] == '.') && !IS_ALPHA(*tmp))
1432 return(8); /* e.g. http://xmlsOft.0rg/ */
1433 }
1434 if (uri != NULL) {
1435 if (uri->authority != NULL) xmlFree(uri->authority);
1436 uri->authority = NULL;
1437 if (host[0] != '[') { /* it's not an IPV6 addr */
1438 if (uri->server != NULL) xmlFree(uri->server);
1439 if (uri->cleanup & 2)
1440 uri->server = STRNDUP(host, cur - host);
1441 else
1442 uri->server = xmlURIUnescapeString(host, cur - host, NULL);
1443 }
1444 }
1445 /*
1446 * finish by checking for a port presence.
1447 */
1448 if (*cur == ':') {
1449 cur++;
1450 if (IS_DIGIT(*cur)) {
1451 if (uri != NULL)
1452 uri->port = 0;
1453 while (IS_DIGIT(*cur)) {
1454 if (uri != NULL)
1455 uri->port = uri->port * 10 + (*cur - '0');
1456 cur++;
1457 }
1458 }
1459 }
1460 *str = cur;
1461 return(0);
1462 }
1463
1464 /**
1465 * xmlParseURIRelSegment:
1466 * @uri: pointer to an URI structure
1467 * @str: pointer to the string to analyze
1468 *
1469 * Parse an URI relative segment
1470 *
1471 * rel_segment = 1*( unreserved | escaped | ";" | "@" | "&" | "=" |
1472 * "+" | "$" | "," )
1473 *
1474 * Returns 0 or the error code
1475 */
1476 static int
1477 xmlParseURIRelSegment(xmlURIPtr uri, const char **str)
1478 {
1479 const char *cur;
1480
1481 if (str == NULL)
1482 return (-1);
1483
1484 cur = *str;
1485 if (!((IS_SEGMENT(cur)) ||
1486 ((uri != NULL) && (uri->cleanup & 1) && (IS_UNWISE(cur))))) {
1487 return (3);
1488 }
1489 NEXT(cur);
1490 while ((IS_SEGMENT(cur)) ||
1491 ((uri != NULL) && (uri->cleanup & 1) && (IS_UNWISE(cur))))
1492 NEXT(cur);
1493 if (uri != NULL) {
1494 if (uri->path != NULL)
1495 xmlFree(uri->path);
1496 if (uri->cleanup & 2)
1497 uri->path = STRNDUP(*str, cur - *str);
1498 else
1499 uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
1500 }
1501 *str = cur;
1502 return (0);
1503 }
1504
1505 /**
1506 * xmlParseURIPathSegments:
1507 * @uri: pointer to an URI structure
1508 * @str: pointer to the string to analyze
1509 * @slash: should we add a leading slash
1510 *
1511 * Parse an URI set of path segments
1512 *
1513 * path_segments = segment *( "/" segment )
1514 * segment = *pchar *( ";" param )
1515 * param = *pchar
1516 *
1517 * Returns 0 or the error code
1518 */
1519 static int
1520 xmlParseURIPathSegments(xmlURIPtr uri, const char **str, int slash)
1521 {
1522 const char *cur;
1523
1524 if (str == NULL)
1525 return (-1);
1526
1527 cur = *str;
1528
1529 do {
1530 while ((IS_PCHAR(cur)) ||
1531 ((uri != NULL) && (uri->cleanup & 1) && (IS_UNWISE(cur))))
1532 NEXT(cur);
1533 while (*cur == ';') {
1534 cur++;
1535 while ((IS_PCHAR(cur)) ||
1536 ((uri != NULL) && (uri->cleanup & 1) && (IS_UNWISE(cur))))
1537 NEXT(cur);
1538 }
1539 if (*cur != '/')
1540 break;
1541 cur++;
1542 } while (1);
1543 if (uri != NULL) {
1544 int len, len2 = 0;
1545 char *path;
1546
1547 /*
1548 * Concat the set of path segments to the current path
1549 */
1550 len = cur - *str;
1551 if (slash)
1552 len++;
1553
1554 if (uri->path != NULL) {
1555 len2 = strlen(uri->path);
1556 len += len2;
1557 }
1558 path = (char *) xmlMallocAtomic(len + 1);
1559 if (path == NULL) {
1560 xmlGenericError(xmlGenericErrorContext,
1561 "xmlParseURIPathSegments: out of memory\n");
1562 *str = cur;
1563 return (-1);
1564 }
1565 if (uri->path != NULL)
1566 memcpy(path, uri->path, len2);
1567 if (slash) {
1568 path[len2] = '/';
1569 len2++;
1570 }
1571 path[len2] = 0;
1572 if (cur - *str > 0) {
1573 if (uri->cleanup & 2) {
1574 memcpy(&path[len2], *str, cur - *str);
1575 path[len2 + (cur - *str)] = 0;
1576 } else
1577 xmlURIUnescapeString(*str, cur - *str, &path[len2]);
1578 }
1579 if (uri->path != NULL)
1580 xmlFree(uri->path);
1581 uri->path = path;
1582 }
1583 *str = cur;
1584 return (0);
1585 }
1586
1587 /**
1588 * xmlParseURIAuthority:
1589 * @uri: pointer to an URI structure
1590 * @str: pointer to the string to analyze
1591 *
1592 * Parse the authority part of an URI.
1593 *
1594 * authority = server | reg_name
1595 * server = [ [ userinfo "@" ] hostport ]
1596 * reg_name = 1*( unreserved | escaped | "$" | "," | ";" | ":" |
1597 * "@" | "&" | "=" | "+" )
1598 *
1599 * Note : this is completely ambiguous since reg_name is allowed to
1600 * use the full set of chars in use by server:
1601 *
1602 * 3.2.1. Registry-based Naming Authority
1603 *
1604 * The structure of a registry-based naming authority is specific
1605 * to the URI scheme, but constrained to the allowed characters
1606 * for an authority component.
1607 *
1608 * Returns 0 or the error code
1609 */
1610 static int
1611 xmlParseURIAuthority(xmlURIPtr uri, const char **str) {
1612 const char *cur;
1613 int ret;
1614
1615 if (str == NULL)
1616 return(-1);
1617
1618 cur = *str;
1619
1620 /*
1621 * try first to parse it as a server string.
1622 */
1623 ret = xmlParseURIServer(uri, str);
1624 if ((ret == 0) && (*str != NULL) &&
1625 ((**str == 0) || (**str == '/') || (**str == '?')))
1626 return(0);
1627 *str = cur;
1628
1629 /*
1630 * failed, fallback to reg_name
1631 */
1632 if (!IS_REG_NAME(cur)) {
1633 return(5);
1634 }
1635 NEXT(cur);
1636 while (IS_REG_NAME(cur)) NEXT(cur);
1637 if (uri != NULL) {
1638 if (uri->server != NULL) xmlFree(uri->server);
1639 uri->server = NULL;
1640 if (uri->user != NULL) xmlFree(uri->user);
1641 uri->user = NULL;
1642 if (uri->authority != NULL) xmlFree(uri->authority);
1643 if (uri->cleanup & 2)
1644 uri->authority = STRNDUP(*str, cur - *str);
1645 else
1646 uri->authority = xmlURIUnescapeString(*str, cur - *str, NULL);
1647 }
1648 *str = cur;
1649 return(0);
1650 }
1651
1652 /**
1653 * xmlParseURIHierPart:
1654 * @uri: pointer to an URI structure
1655 * @str: pointer to the string to analyze
1656 *
1657 * Parse an URI hierarchical part
1658 *
1659 * hier_part = ( net_path | abs_path ) [ "?" query ]
1660 * abs_path = "/" path_segments
1661 * net_path = "//" authority [ abs_path ]
1662 *
1663 * Returns 0 or the error code
1664 */
1665 static int
1666 xmlParseURIHierPart(xmlURIPtr uri, const char **str) {
1667 int ret;
1668 const char *cur;
1669
1670 if (str == NULL)
1671 return(-1);
1672
1673 cur = *str;
1674
1675 if ((cur[0] == '/') && (cur[1] == '/')) {
1676 cur += 2;
1677 ret = xmlParseURIAuthority(uri, &cur);
1678 if (ret != 0)
1679 return(ret);
1680 if (cur[0] == '/') {
1681 cur++;
1682 ret = xmlParseURIPathSegments(uri, &cur, 1);
1683 }
1684 } else if (cur[0] == '/') {
1685 cur++;
1686 ret = xmlParseURIPathSegments(uri, &cur, 1);
1687 } else {
1688 return(4);
1689 }
1690 if (ret != 0)
1691 return(ret);
1692 if (*cur == '?') {
1693 cur++;
1694 ret = xmlParseURIQuery(uri, &cur);
1695 if (ret != 0)
1696 return(ret);
1697 }
1698 *str = cur;
1699 return(0);
1700 }
1701
1702 /**
1703 * xmlParseAbsoluteURI:
1704 * @uri: pointer to an URI structure
1705 * @str: pointer to the string to analyze
1706 *
1707 * Parse an URI reference string and fills in the appropriate fields
1708 * of the @uri structure
1709 *
1710 * absoluteURI = scheme ":" ( hier_part | opaque_part )
1711 *
1712 * Returns 0 or the error code
1713 */
1714 static int
1715 xmlParseAbsoluteURI(xmlURIPtr uri, const char **str) {
1716 int ret;
1717 const char *cur;
1718
1719 if (str == NULL)
1720 return(-1);
1721
1722 cur = *str;
1723
1724 ret = xmlParseURIScheme(uri, str);
1725 if (ret != 0) return(ret);
1726 if (**str != ':') {
1727 *str = cur;
1728 return(1);
1729 }
1730 (*str)++;
1731 if (**str == '/')
1732 return(xmlParseURIHierPart(uri, str));
1733 return(xmlParseURIOpaquePart(uri, str));
1734 }
1735
1736 /**
1737 * xmlParseRelativeURI:
1738 * @uri: pointer to an URI structure
1739 * @str: pointer to the string to analyze
1740 *
1741 * Parse an relative URI string and fills in the appropriate fields
1742 * of the @uri structure
1743 *
1744 * relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ]
1745 * abs_path = "/" path_segments
1746 * net_path = "//" authority [ abs_path ]
1747 * rel_path = rel_segment [ abs_path ]
1748 *
1749 * Returns 0 or the error code
1750 */
1751 static int
1752 xmlParseRelativeURI(xmlURIPtr uri, const char **str) {
1753 int ret = 0;
1754 const char *cur;
1755
1756 if (str == NULL)
1757 return(-1);
1758
1759 cur = *str;
1760 if ((cur[0] == '/') && (cur[1] == '/')) {
1761 cur += 2;
1762 ret = xmlParseURIAuthority(uri, &cur);
1763 if (ret != 0)
1764 return(ret);
1765 if (cur[0] == '/') {
1766 cur++;
1767 ret = xmlParseURIPathSegments(uri, &cur, 1);
1768 }
1769 } else if (cur[0] == '/') {
1770 cur++;
1771 ret = xmlParseURIPathSegments(uri, &cur, 1);
1772 } else if (cur[0] != '#' && cur[0] != '?') {
1773 ret = xmlParseURIRelSegment(uri, &cur);
1774 if (ret != 0)
1775 return(ret);
1776 if (cur[0] == '/') {
1777 cur++;
1778 ret = xmlParseURIPathSegments(uri, &cur, 1);
1779 }
1780 }
1781 if (ret != 0)
1782 return(ret);
1783 if (*cur == '?') {
1784 cur++;
1785 ret = xmlParseURIQuery(uri, &cur);
1786 if (ret != 0)
1787 return(ret);
1788 }
1789 *str = cur;
1790 return(ret);
1791 }
1792
1793 /**
1794 * xmlParseURIReference:
1795 * @uri: pointer to an URI structure
1796 * @str: the string to analyze
1797 *
1798 * Parse an URI reference string and fills in the appropriate fields
1799 * of the @uri structure
1800 *
1801 * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
1802 *
1803 * Returns 0 or the error code
1804 */
1805 int
1806 xmlParseURIReference(xmlURIPtr uri, const char *str) {
1807 int ret;
1808 const char *tmp = str;
1809
1810 if (str == NULL)
1811 return(-1);
1812 xmlCleanURI(uri);
1813
1814 /*
1815 * Try first to parse absolute refs, then fallback to relative if
1816 * it fails.
1817 */
1818 ret = xmlParseAbsoluteURI(uri, &str);
1819 if (ret != 0) {
1820 xmlCleanURI(uri);
1821 str = tmp;
1822 ret = xmlParseRelativeURI(uri, &str);
1823 }
1824 if (ret != 0) {
1825 xmlCleanURI(uri);
1826 return(ret);
1827 }
1828
1829 if (*str == '#') {
1830 str++;
1831 ret = xmlParseURIFragment(uri, &str);
1832 if (ret != 0) return(ret);
1833 }
1834 if (*str != 0) {
1835 xmlCleanURI(uri);
1836 return(1);
1837 }
1838 return(0);
1839 }
1840
1841 /**
1842 * xmlParseURI:
1843 * @str: the URI string to analyze
1844 *
1845 * Parse an URI
1846 *
1847 * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
1848 *
1849 * Returns a newly built xmlURIPtr or NULL in case of error
1850 */
1851 xmlURIPtr
1852 xmlParseURI(const char *str) {
1853 xmlURIPtr uri;
1854 int ret;
1855
1856 if (str == NULL)
1857 return(NULL);
1858 uri = xmlCreateURI();
1859 if (uri != NULL) {
1860 ret = xmlParseURIReference(uri, str);
1861 if (ret) {
1862 xmlFreeURI(uri);
1863 return(NULL);
1864 }
1865 }
1866 return(uri);
1867 }
1868
1869 /**
1870 * xmlParseURIRaw:
1871 * @str: the URI string to analyze
1872 * @raw: if 1 unescaping of URI pieces are disabled
1873 *
1874 * Parse an URI but allows to keep intact the original fragments.
1875 *
1876 * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
1877 *
1878 * Returns a newly built xmlURIPtr or NULL in case of error
1879 */
1880 xmlURIPtr
1881 xmlParseURIRaw(const char *str, int raw) {
1882 xmlURIPtr uri;
1883 int ret;
1884
1885 if (str == NULL)
1886 return(NULL);
1887 uri = xmlCreateURI();
1888 if (uri != NULL) {
1889 if (raw) {
1890 uri->cleanup |= 2;
1891 }
1892 ret = xmlParseURIReference(uri, str);
1893 if (ret) {
1894 xmlFreeURI(uri);
1895 return(NULL);
1896 }
1897 }
1898 return(uri);
1899 }
1900
1901 /************************************************************************
1902 * *
1903 * Public functions * 1939 * Public functions *
1904 * * 1940 * *
1905 ************************************************************************/ 1941 ************************************************************************/
1906 1942
1907 /** 1943 /**
1908 * xmlBuildURI: 1944 * xmlBuildURI:
1909 * @URI: the URI instance found in the document 1945 * @URI: the URI instance found in the document
1910 * @base: the base value 1946 * @base: the base value
1911 * 1947 *
1912 * Computes he final URI of the reference done by checking that 1948 * Computes he final URI of the reference done by checking that
(...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after
2588 } 2624 }
2589 #endif 2625 #endif
2590 memset(&temp, 0, sizeof(temp)); 2626 memset(&temp, 0, sizeof(temp));
2591 temp.path = (char *) cal; 2627 temp.path = (char *) cal;
2592 ret = xmlSaveUri(&temp); 2628 ret = xmlSaveUri(&temp);
2593 xmlFree(cal); 2629 xmlFree(cal);
2594 return(ret); 2630 return(ret);
2595 } 2631 }
2596 #define bottom_uri 2632 #define bottom_uri
2597 #include "elfgcchack.h" 2633 #include "elfgcchack.h"
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698