Skip to content
This repository was archived by the owner on Jan 26, 2026. It is now read-only.

Commit 977c076

Browse files
committed
uri: Handle filesystem paths in xmlBuildRelativeURISafe
This mainly fixes issues on Windows but should also fix a few general corner cases. Should fix #745.
1 parent 6fa2573 commit 977c076

2 files changed

Lines changed: 289 additions & 66 deletions

File tree

testparser.c

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66

77
#include <libxml/parser.h>
8+
#include <libxml/uri.h>
89
#include <libxml/xmlreader.h>
910
#include <libxml/xmlwriter.h>
1011
#include <libxml/HTMLparser.h>
@@ -386,6 +387,135 @@ testWriterClose(void){
386387
}
387388
#endif
388389

390+
typedef struct {
391+
const char *uri;
392+
const char *base;
393+
const char *result;
394+
} xmlRelativeUriTest;
395+
396+
static int
397+
testBuildRelativeUri(void) {
398+
xmlChar *res;
399+
int err = 0;
400+
int i;
401+
402+
static const xmlRelativeUriTest tests[] = {
403+
{
404+
"/a/b1/c1",
405+
"/a/b2/c2",
406+
"../b1/c1"
407+
}, {
408+
"a/b1/c1",
409+
"a/b2/c2",
410+
"../b1/c1"
411+
}, {
412+
"a/././b1/x/y/../z/../.././c1",
413+
"./a/./b2/././b2",
414+
"../b1/c1"
415+
}, {
416+
"file:///a/b1/c1",
417+
"/a/b2/c2",
418+
"../b1/c1"
419+
}, {
420+
"/a/b1/c1",
421+
"file:///a/b2/c2",
422+
"../b1/c1"
423+
}, {
424+
"a/b1/c1",
425+
"/a/b2/c2",
426+
NULL
427+
}, {
428+
"/a/b1/c1",
429+
"a/b2/c2",
430+
"file:///a/b1/c1"
431+
}, {
432+
"http://example.org/a/b1/c1",
433+
"http://example.org/a/b2/c2",
434+
"../b1/c1"
435+
}, {
436+
"http://example.org/a/b1/c1",
437+
"https://example.org/a/b2/c2",
438+
NULL
439+
}, {
440+
"http://example.org/a/b1/c1",
441+
"http://localhost/a/b2/c2",
442+
NULL
443+
}, {
444+
"with space/x x/y y",
445+
"with space/b2/c2",
446+
"../x%20x/y%20y"
447+
}, {
448+
"with space/x x/y y",
449+
"/b2/c2",
450+
"with%20space/x%20x/y%20y"
451+
}
452+
#if defined(_WIN32) || defined(__CYGWIN__)
453+
, {
454+
"\\a\\b1\\c1",
455+
"\\a\\b2\\c2",
456+
"../b1/c1"
457+
}, {
458+
"\\a\\b1\\c1",
459+
"/a/b2/c2",
460+
"../b1/c1"
461+
}, {
462+
"a\\b1\\c1",
463+
"a/b2/c2",
464+
"../b1/c1"
465+
}, {
466+
"file://server/a/b1/c1",
467+
"\\\\?\\UNC\\server\\a\\b2\\c2",
468+
"../b1/c1"
469+
}, {
470+
"file://server/a/b1/c1",
471+
"\\\\server\\a\\b2\\c2",
472+
"../b1/c1"
473+
}, {
474+
"file:///x:/a/b1/c1",
475+
"x:\\a\\b2\\c2",
476+
"../b1/c1"
477+
}, {
478+
"file:///x:/a/b1/c1",
479+
"\\\\?\\x:\\a\\b2\\c2",
480+
"../b1/c1"
481+
}, {
482+
"file:///x:/a/b1/c1",
483+
"file:///y:/a/b2/c2",
484+
NULL
485+
}, {
486+
"x:/a/b1/c1",
487+
"y:/a/b2/c2",
488+
"file:///x:/a/b1/c1"
489+
}, {
490+
"/a/b1/c1",
491+
"y:/a/b2/c2",
492+
"file:///a/b1/c1"
493+
}, {
494+
"\\server\\a\\b1\\c1",
495+
"a/b2/c2",
496+
"file:///server/a/b1/c1"
497+
}
498+
#endif
499+
};
500+
501+
for (i = 0; (size_t) i < sizeof(tests) / sizeof(tests[0]); i++) {
502+
const xmlRelativeUriTest *test = tests + i;
503+
const char *expect;
504+
505+
res = xmlBuildRelativeURI(BAD_CAST test->uri, BAD_CAST test->base);
506+
expect = test->result ? test->result : test->uri;
507+
if (!xmlStrEqual(res, BAD_CAST expect)) {
508+
fprintf(stderr, "xmlBuildRelativeURI failed uri=%s base=%s "
509+
"result=%s expected=%s\n", test->uri, test->base,
510+
res, expect);
511+
err = 1;
512+
}
513+
xmlFree(res);
514+
}
515+
516+
return err;
517+
}
518+
389519
int
390520
main(void) {
391521
int err = 0;
@@ -413,6 +543,7 @@ main(void) {
413543
#ifdef LIBXML_WRITER_ENABLED
414544
err |= testWriterClose();
415545
#endif
546+
err |= testBuildRelativeUri();
416547

417548
return err;
418549
}

0 commit comments

Comments
 (0)