mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-07-30 22:43:14 +03:00
Rewrite/cleanup/tests of URI normalization:
- uri.c: rewrite of xmlNormalizeURIPath from Paul D. Smith - test/URI/smith.uri result/URI/smith.uri Makefile.am: added the new tests for URI normalization - testURI.c: fixed stoopid bugs - result/VC/OneID3 result/VC/UniqueElementTypeDeclaration: the URI in the error messages are now properly normalized Daniel
This commit is contained in:
@ -1,3 +1,12 @@
|
|||||||
|
Fri Feb 2 18:04:35 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
|
||||||
|
|
||||||
|
* uri.c: rewrite of xmlNormalizeURIPath from Paul D. Smith
|
||||||
|
* test/URI/smith.uri result/URI/smith.uri Makefile.am:
|
||||||
|
added the new tests for URI normalization
|
||||||
|
* testURI.c: fixed stoopid bugs
|
||||||
|
* result/VC/OneID3 result/VC/UniqueElementTypeDeclaration:
|
||||||
|
the URI in the error messages are now properly normalized
|
||||||
|
|
||||||
Fri Feb 2 09:18:53 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
|
Fri Feb 2 09:18:53 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
|
||||||
|
|
||||||
* uri.c: applied Marc Sanfacon's patch for xmlNormalizeURIPath
|
* uri.c: applied Marc Sanfacon's patch for xmlNormalizeURIPath
|
||||||
|
13
Makefile.am
13
Makefile.am
@ -237,6 +237,19 @@ URItests : testURI
|
|||||||
diff $(srcdir)/result/URI/$$name result.$$name ; \
|
diff $(srcdir)/result/URI/$$name result.$$name ; \
|
||||||
rm result.$$name ; \
|
rm result.$$name ; \
|
||||||
fi ; fi ; done)
|
fi ; fi ; done)
|
||||||
|
@(for i in $(srcdir)/test/URI/*.uri ; do \
|
||||||
|
name=`basename $$i`; \
|
||||||
|
if [ ! -d $$i ] ; then \
|
||||||
|
if [ ! -f $(srcdir)/result/URI/$$name ] ; then \
|
||||||
|
echo New test file $$name ; \
|
||||||
|
$(top_builddir)/testURI < $$i > $(srcdir)/result/URI/$$name ; \
|
||||||
|
else \
|
||||||
|
echo Testing $$name ; \
|
||||||
|
$(top_builddir)/testURI < $$i > result.$$name ; \
|
||||||
|
grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0";\
|
||||||
|
diff $(srcdir)/result/URI/$$name result.$$name ; \
|
||||||
|
rm result.$$name ; \
|
||||||
|
fi ; fi ; done)
|
||||||
|
|
||||||
XPathtests : testXPath
|
XPathtests : testXPath
|
||||||
@echo "##"
|
@echo "##"
|
||||||
|
40
aclocal.m4
vendored
40
aclocal.m4
vendored
@ -620,31 +620,35 @@ esac
|
|||||||
])
|
])
|
||||||
|
|
||||||
# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
|
# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
|
||||||
# the libltdl convenience library, adds --enable-ltdl-convenience to
|
# the libltdl convenience library and INCLTDL to the include flags for
|
||||||
# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor
|
# the libltdl header and adds --enable-ltdl-convenience to the
|
||||||
# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed
|
# configure arguments. Note that LIBLTDL and INCLTDL are not
|
||||||
# to be `${top_builddir}/libltdl'. Make sure you start DIR with
|
# AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If DIR is not
|
||||||
# '${top_builddir}/' (note the single quotes!) if your package is not
|
# provided, it is assumed to be `libltdl'. LIBLTDL will be prefixed
|
||||||
# flat, and, if you're not using automake, define top_builddir as
|
# with '${top_builddir}/' and INCLTDL will be prefixed with
|
||||||
# appropriate in the Makefiles.
|
# '${top_srcdir}/' (note the single quotes!). If your package is not
|
||||||
|
# flat and you're not using automake, define top_builddir and
|
||||||
|
# top_srcdir appropriately in the Makefiles.
|
||||||
AC_DEFUN(AC_LIBLTDL_CONVENIENCE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
|
AC_DEFUN(AC_LIBLTDL_CONVENIENCE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
|
||||||
case "$enable_ltdl_convenience" in
|
case "$enable_ltdl_convenience" in
|
||||||
no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
|
no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
|
||||||
"") enable_ltdl_convenience=yes
|
"") enable_ltdl_convenience=yes
|
||||||
ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
|
ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
|
||||||
esac
|
esac
|
||||||
LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdlc.la
|
LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la
|
||||||
INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
|
INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
|
||||||
])
|
])
|
||||||
|
|
||||||
# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
|
# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
|
||||||
# the libltdl installable library, and adds --enable-ltdl-install to
|
# the libltdl installable library and INCLTDL to the include flags for
|
||||||
# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor
|
# the libltdl header and adds --enable-ltdl-install to the configure
|
||||||
# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed
|
# arguments. Note that LIBLTDL and INCLTDL are not AC_SUBSTed, nor is
|
||||||
# to be `${top_builddir}/libltdl'. Make sure you start DIR with
|
# AC_CONFIG_SUBDIRS called. If DIR is not provided and an installed
|
||||||
# '${top_builddir}/' (note the single quotes!) if your package is not
|
# libltdl is not found, it is assumed to be `libltdl'. LIBLTDL will
|
||||||
# flat, and, if you're not using automake, define top_builddir as
|
# be prefixed with '${top_builddir}/' and INCLTDL will be prefixed
|
||||||
# appropriate in the Makefiles.
|
# with '${top_srcdir}/' (note the single quotes!). If your package is
|
||||||
|
# not flat and you're not using automake, define top_builddir and
|
||||||
|
# top_srcdir appropriately in the Makefiles.
|
||||||
# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
|
# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
|
||||||
AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
|
AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
|
||||||
AC_CHECK_LIB(ltdl, main,
|
AC_CHECK_LIB(ltdl, main,
|
||||||
@ -657,8 +661,8 @@ AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
|
|||||||
])
|
])
|
||||||
if test x"$enable_ltdl_install" = x"yes"; then
|
if test x"$enable_ltdl_install" = x"yes"; then
|
||||||
ac_configure_args="$ac_configure_args --enable-ltdl-install"
|
ac_configure_args="$ac_configure_args --enable-ltdl-install"
|
||||||
LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdl.la
|
LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la
|
||||||
INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
|
INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
|
||||||
else
|
else
|
||||||
ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
|
ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
|
||||||
LIBLTDL="-lltdl"
|
LIBLTDL="-lltdl"
|
||||||
|
15
result/URI/smith.uri
Normal file
15
result/URI/smith.uri
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/bar
|
||||||
|
bar
|
||||||
|
bar
|
||||||
|
bar
|
||||||
|
baz
|
||||||
|
|
||||||
|
foo/
|
||||||
|
foo
|
||||||
|
foo
|
||||||
|
../foo./
|
||||||
|
../foo/
|
||||||
|
/foo
|
||||||
|
../foo
|
||||||
|
../../foo
|
||||||
|
../../../foo
|
@ -1,3 +1,3 @@
|
|||||||
./test/VC/dtds/doc.dtd:2: validity error: Element doc has ID attributes defined in the internal and external subset : val
|
test/VC/dtds/doc.dtd:2: validity error: Element doc has ID attributes defined in the internal and external subset : val
|
||||||
<!ATTLIST doc val ID #IMPLIED>
|
<!ATTLIST doc val ID #IMPLIED>
|
||||||
^
|
^
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
./test/VC/dtds/a.dtd:1: validity error: Redefinition of element a
|
test/VC/dtds/a.dtd:1: validity error: Redefinition of element a
|
||||||
<!ELEMENT a (#PCDATA | b | c)*>
|
<!ELEMENT a (#PCDATA | b | c)*>
|
||||||
^
|
^
|
||||||
|
15
test/URI/smith.uri
Normal file
15
test/URI/smith.uri
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/foo/../bar
|
||||||
|
foo/../bar
|
||||||
|
./foo/../bar
|
||||||
|
foo/./../bar
|
||||||
|
foo/bar/.././../baz
|
||||||
|
foo/..
|
||||||
|
foo/bar/..
|
||||||
|
./foo
|
||||||
|
././foo
|
||||||
|
.././foo./
|
||||||
|
.././foo/.
|
||||||
|
/foo
|
||||||
|
../foo
|
||||||
|
../../foo
|
||||||
|
../../../foo
|
10
testURI.c
10
testURI.c
@ -27,11 +27,8 @@ int main(int argc, char **argv) {
|
|||||||
const char *base = NULL;
|
const char *base = NULL;
|
||||||
xmlChar *composite;
|
xmlChar *composite;
|
||||||
|
|
||||||
if (argv[arg] == NULL) {
|
if ((argv[arg] != NULL) &&
|
||||||
printf("Usage: %s [-base URI] URI ...\n", argv[0]);
|
((!strcmp(argv[arg], "-base")) || (!strcmp(argv[arg], "--base")))) {
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
if ((!strcmp(argv[arg], "-base")) || (!strcmp(argv[arg], "--base"))) {
|
|
||||||
arg++;
|
arg++;
|
||||||
base = argv[arg];
|
base = argv[arg];
|
||||||
if (base != NULL)
|
if (base != NULL)
|
||||||
@ -64,6 +61,7 @@ int main(int argc, char **argv) {
|
|||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
printf("%s : error %d\n", str, ret);
|
printf("%s : error %d\n", str, ret);
|
||||||
else {
|
else {
|
||||||
|
xmlNormalizeURIPath(uri->path);
|
||||||
xmlPrintURI(stdout, uri);
|
xmlPrintURI(stdout, uri);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
@ -99,5 +97,5 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
xmlFreeURI(uri);
|
xmlFreeURI(uri);
|
||||||
xmlMemoryDump();
|
xmlMemoryDump();
|
||||||
exit(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
179
uri.c
179
uri.c
@ -606,6 +606,7 @@ xmlFreeURI(xmlURIPtr uri) {
|
|||||||
* *
|
* *
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
|
#if 0
|
||||||
/**
|
/**
|
||||||
* xmlNormalizeURIPath:
|
* xmlNormalizeURIPath:
|
||||||
* @path: pointer to the path string
|
* @path: pointer to the path string
|
||||||
@ -739,6 +740,184 @@ xmlNormalizeURIPath(char *path) {
|
|||||||
}
|
}
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
/**
|
||||||
|
* xmlNormalizeURIPath:
|
||||||
|
* @path: pointer to the path string
|
||||||
|
*
|
||||||
|
* Applies the 5 normalization steps to a path string--that is, RFC 2396
|
||||||
|
* Section 5.2, steps 6.c through 6.g.
|
||||||
|
*
|
||||||
|
* Normalization occurs directly on the string, no new allocation is done
|
||||||
|
*
|
||||||
|
* Returns 0 or an error code
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
xmlNormalizeURIPath(char *path) {
|
||||||
|
char *cur, *out;
|
||||||
|
|
||||||
|
if (path == NULL)
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
/* Skip all initial "/" chars. We want to get to the beginning of the
|
||||||
|
* first non-empty segment.
|
||||||
|
*/
|
||||||
|
cur = path;
|
||||||
|
while (cur[0] == '/')
|
||||||
|
++cur;
|
||||||
|
if (cur[0] == '\0')
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
/* Keep everything we've seen so far. */
|
||||||
|
out = cur;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Analyze each segment in sequence for cases (c) and (d).
|
||||||
|
*/
|
||||||
|
while (cur[0] != '\0') {
|
||||||
|
/*
|
||||||
|
* c) All occurrences of "./", where "." is a complete path segment,
|
||||||
|
* are removed from the buffer string.
|
||||||
|
*/
|
||||||
|
if ((cur[0] == '.') && (cur[1] == '/')) {
|
||||||
|
cur += 2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* d) If the buffer string ends with "." as a complete path segment,
|
||||||
|
* that "." is removed.
|
||||||
|
*/
|
||||||
|
if ((cur[0] == '.') && (cur[1] == '\0'))
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Otherwise keep the segment. */
|
||||||
|
while (cur[0] != '/') {
|
||||||
|
if (cur[0] == '\0')
|
||||||
|
goto done_cd;
|
||||||
|
(out++)[0] = (cur++)[0];
|
||||||
|
}
|
||||||
|
(out++)[0] = (cur++)[0];
|
||||||
|
}
|
||||||
|
done_cd:
|
||||||
|
out[0] = '\0';
|
||||||
|
|
||||||
|
/* Reset to the beginning of the first segment for the next sequence. */
|
||||||
|
cur = path;
|
||||||
|
while (cur[0] == '/')
|
||||||
|
++cur;
|
||||||
|
if (cur[0] == '\0')
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Analyze each segment in sequence for cases (e) and (f).
|
||||||
|
*
|
||||||
|
* e) All occurrences of "<segment>/../", where <segment> is a
|
||||||
|
* complete path segment not equal to "..", are removed from the
|
||||||
|
* buffer string. Removal of these path segments is performed
|
||||||
|
* iteratively, removing the leftmost matching pattern on each
|
||||||
|
* iteration, until no matching pattern remains.
|
||||||
|
*
|
||||||
|
* f) If the buffer string ends with "<segment>/..", where <segment>
|
||||||
|
* is a complete path segment not equal to "..", that
|
||||||
|
* "<segment>/.." is removed.
|
||||||
|
*
|
||||||
|
* To satisfy the "iterative" clause in (e), we need to collapse the
|
||||||
|
* string every time we find something that needs to be removed. Thus,
|
||||||
|
* we don't need to keep two pointers into the string: we only need a
|
||||||
|
* "current position" pointer.
|
||||||
|
*/
|
||||||
|
while (1) {
|
||||||
|
char *segp;
|
||||||
|
|
||||||
|
/* At the beginning of each iteration of this loop, "cur" points to
|
||||||
|
* the first character of the segment we want to examine.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Find the end of the current segment. */
|
||||||
|
segp = cur;
|
||||||
|
while ((segp[0] != '/') && (segp[0] != '\0'))
|
||||||
|
++segp;
|
||||||
|
|
||||||
|
/* If this is the last segment, we're done (we need at least two
|
||||||
|
* segments to meet the criteria for the (e) and (f) cases).
|
||||||
|
*/
|
||||||
|
if (segp[0] == '\0')
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* If the first segment is "..", or if the next segment _isn't_ "..",
|
||||||
|
* keep this segment and try the next one.
|
||||||
|
*/
|
||||||
|
++segp;
|
||||||
|
if (((cur[0] == '.') && (cur[1] == '.') && (segp == cur+3))
|
||||||
|
|| ((segp[0] != '.') || (segp[1] != '.')
|
||||||
|
|| ((segp[2] != '/') && (segp[2] != '\0')))) {
|
||||||
|
cur = segp;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we get here, remove this segment and the next one and back up
|
||||||
|
* to the previous segment (if there is one), to implement the
|
||||||
|
* "iteratively" clause. It's pretty much impossible to back up
|
||||||
|
* while maintaining two pointers into the buffer, so just compact
|
||||||
|
* the whole buffer now.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* If this is the end of the buffer, we're done. */
|
||||||
|
if (segp[2] == '\0') {
|
||||||
|
cur[0] = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
strcpy(cur, segp + 3);
|
||||||
|
|
||||||
|
/* If there are no previous segments, then keep going from here. */
|
||||||
|
segp = cur;
|
||||||
|
while ((segp > path) && ((--segp)[0] == '/'))
|
||||||
|
;
|
||||||
|
if (segp == path)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* "segp" is pointing to the end of a previous segment; find it's
|
||||||
|
* start. We need to back up to the previous segment and start
|
||||||
|
* over with that to handle things like "foo/bar/../..". If we
|
||||||
|
* don't do this, then on the first pass we'll remove the "bar/..",
|
||||||
|
* but be pointing at the second ".." so we won't realize we can also
|
||||||
|
* remove the "foo/..".
|
||||||
|
*/
|
||||||
|
cur = segp;
|
||||||
|
while ((cur > path) && (cur[-1] != '/'))
|
||||||
|
--cur;
|
||||||
|
}
|
||||||
|
out[0] = '\0';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* g) If the resulting buffer string still begins with one or more
|
||||||
|
* complete path segments of "..", then the reference is
|
||||||
|
* considered to be in error. Implementations may handle this
|
||||||
|
* error by retaining these components in the resolved path (i.e.,
|
||||||
|
* treating them as part of the final URI), by removing them from
|
||||||
|
* the resolved path (i.e., discarding relative levels above the
|
||||||
|
* root), or by avoiding traversal of the reference.
|
||||||
|
*
|
||||||
|
* We discard them from the final path.
|
||||||
|
*/
|
||||||
|
if (path[0] == '/') {
|
||||||
|
cur = path;
|
||||||
|
while ((cur[1] == '.') && (cur[2] == '.')
|
||||||
|
&& ((cur[3] == '/') || (cur[3] == '\0')))
|
||||||
|
cur += 3;
|
||||||
|
|
||||||
|
if (cur != path) {
|
||||||
|
out = path;
|
||||||
|
while (cur[0] != '\0')
|
||||||
|
(out++)[0] = (cur++)[0];
|
||||||
|
out[0] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlURIUnescapeString:
|
* xmlURIUnescapeString:
|
||||||
|
Reference in New Issue
Block a user