From 40ee59d609a4597e904888a2242e318aba6cab81 Mon Sep 17 00:00:00 2001 From: Thomas Faber Date: Sun, 12 Sep 2021 13:24:24 -0400 Subject: [PATCH] [LIBXML2] Update to version 2.9.12. CORE-17766 --- media/doc/3rd Party Files.txt | 2 +- sdk/include/reactos/libs/libxml/c14n.h | 10 +- sdk/include/reactos/libs/libxml/parser.h | 16 +- sdk/include/reactos/libs/libxml/tree.h | 6 +- sdk/include/reactos/libs/libxml/xmlIO.h | 2 + sdk/include/reactos/libs/libxml/xmlexports.h | 154 +-- sdk/include/reactos/libs/libxml/xmlschemas.h | 2 +- sdk/include/reactos/libs/libxml/xmlversion.h | 14 +- .../reactos/libs/libxml/xmlversion.h.in | 4 +- sdk/include/reactos/libs/libxml/xpath.h | 4 +- sdk/lib/3rdparty/libxml2/ChangeLog | 214 +-- sdk/lib/3rdparty/libxml2/HTMLparser.c | 1207 +++++++++-------- sdk/lib/3rdparty/libxml2/HTMLtree.c | 493 +++---- sdk/lib/3rdparty/libxml2/README | 2 +- sdk/lib/3rdparty/libxml2/SAX2.c | 174 +-- sdk/lib/3rdparty/libxml2/TODO | 8 +- sdk/lib/3rdparty/libxml2/buf.c | 16 +- sdk/lib/3rdparty/libxml2/c14n.c | 20 +- sdk/lib/3rdparty/libxml2/catalog.c | 18 +- sdk/lib/3rdparty/libxml2/config.h | 6 + sdk/lib/3rdparty/libxml2/debugXML.c | 10 +- sdk/lib/3rdparty/libxml2/dict.c | 4 +- sdk/lib/3rdparty/libxml2/encoding.c | 100 +- sdk/lib/3rdparty/libxml2/entities.c | 58 +- sdk/lib/3rdparty/libxml2/error.c | 26 +- sdk/lib/3rdparty/libxml2/globals.c | 2 +- sdk/lib/3rdparty/libxml2/hash.c | 2 +- .../3rdparty/libxml2/include/win32config.h | 6 +- sdk/lib/3rdparty/libxml2/list.c | 2 +- sdk/lib/3rdparty/libxml2/nanoftp.c | 29 +- sdk/lib/3rdparty/libxml2/nanohttp.c | 14 +- sdk/lib/3rdparty/libxml2/parser.c | 637 ++++----- sdk/lib/3rdparty/libxml2/parserInternals.c | 17 +- sdk/lib/3rdparty/libxml2/relaxng.c | 12 +- sdk/lib/3rdparty/libxml2/schematron.c | 4 +- sdk/lib/3rdparty/libxml2/threads.c | 5 +- sdk/lib/3rdparty/libxml2/tree.c | 81 +- sdk/lib/3rdparty/libxml2/trio.c | 2 +- sdk/lib/3rdparty/libxml2/trio.h | 2 +- sdk/lib/3rdparty/libxml2/triodef.h | 2 +- sdk/lib/3rdparty/libxml2/trionan.c | 6 +- sdk/lib/3rdparty/libxml2/trionan.h | 2 +- sdk/lib/3rdparty/libxml2/triop.h | 2 +- sdk/lib/3rdparty/libxml2/triostr.c | 2 +- sdk/lib/3rdparty/libxml2/triostr.h | 2 +- sdk/lib/3rdparty/libxml2/uri.c | 31 +- sdk/lib/3rdparty/libxml2/valid.c | 65 +- sdk/lib/3rdparty/libxml2/xinclude.c | 221 +-- sdk/lib/3rdparty/libxml2/xmlIO.c | 55 +- sdk/lib/3rdparty/libxml2/xmlcatalog.c | 2 +- sdk/lib/3rdparty/libxml2/xmllint.c | 48 +- sdk/lib/3rdparty/libxml2/xmlmemory.c | 2 +- sdk/lib/3rdparty/libxml2/xmlreader.c | 112 +- sdk/lib/3rdparty/libxml2/xmlregexp.c | 137 +- sdk/lib/3rdparty/libxml2/xmlsave.c | 1145 ++++++++-------- sdk/lib/3rdparty/libxml2/xmlschemas.c | 529 +++++--- sdk/lib/3rdparty/libxml2/xmlschemastypes.c | 214 ++- sdk/lib/3rdparty/libxml2/xmlstring.c | 21 +- sdk/lib/3rdparty/libxml2/xpath.c | 173 ++- sdk/lib/3rdparty/libxml2/xpointer.c | 61 +- 60 files changed, 3385 insertions(+), 2832 deletions(-) diff --git a/media/doc/3rd Party Files.txt b/media/doc/3rd Party Files.txt index c0d4d7dcb69..ae3c85ff2ae 100644 --- a/media/doc/3rd Party Files.txt +++ b/media/doc/3rd Party Files.txt @@ -233,7 +233,7 @@ URL: https://github.com/win-iconv/win-iconv Title: LibXML Path: sdk/lib/libxml2 -Used Version: 2.9.10 +Used Version: 2.9.12 License: MIT (https://spdx.org/licenses/MIT.htmlf) URL: http://xmlsoft.org, ftp://xmlsoft.org/libxml2/ diff --git a/sdk/include/reactos/libs/libxml/c14n.h b/sdk/include/reactos/libs/libxml/c14n.h index d74847df842..af93de63a4c 100644 --- a/sdk/include/reactos/libs/libxml/c14n.h +++ b/sdk/include/reactos/libs/libxml/c14n.h @@ -16,17 +16,19 @@ */ #ifndef __XML_C14N_H__ #define __XML_C14N_H__ + +#include + #ifdef LIBXML_C14N_ENABLED #ifdef LIBXML_OUTPUT_ENABLED +#include +#include + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ -#include -#include -#include - /* * XML Canonicalization * http://www.w3.org/TR/xml-c14n diff --git a/sdk/include/reactos/libs/libxml/parser.h b/sdk/include/reactos/libs/libxml/parser.h index c295554f36a..0ba1c387a97 100644 --- a/sdk/include/reactos/libs/libxml/parser.h +++ b/sdk/include/reactos/libs/libxml/parser.h @@ -79,7 +79,7 @@ struct _xmlParserInput { /** * xmlParserNodeInfo: * - * The parser can be asked to collect Node informations, i.e. at what + * The parser can be asked to collect Node information, i.e. at what * place in the file they were detected. * NOTE: This is off by default and not very well tested. */ @@ -169,6 +169,8 @@ typedef enum { XML_PARSE_READER = 5 } xmlParserMode; +typedef struct _xmlStartTag xmlStartTag; + /** * xmlParserCtxt: * @@ -231,7 +233,7 @@ struct _xmlParserCtxt { int nameMax; /* Max depth of the parsing stack */ const xmlChar * *nameTab; /* array of nodes */ - long nbChars; /* number of xmlChar processed */ + long nbChars; /* unused */ long checkIndex; /* used by progressive parsing lookup */ int keepBlanks; /* ugly but ... */ int disableSAX; /* SAX callbacks are disabled */ @@ -280,7 +282,7 @@ struct _xmlParserCtxt { int nsMax; /* the size of the arrays */ const xmlChar * *nsTab; /* the array of prefix/namespace name */ int *attallocs; /* which attribute were allocated */ - void * *pushTab; /* array of data for push */ + xmlStartTag *pushTab; /* array of data for push */ xmlHashTablePtr attsDefault; /* defaulted attributes if any */ xmlHashTablePtr attsSpecial; /* non-CDATA attributes if any */ int nsWellFormed; /* is the document XML Namespace okay */ @@ -296,7 +298,7 @@ struct _xmlParserCtxt { xmlAttrPtr freeAttrs; /* List of freed attributes nodes */ /* - * the complete error informations for the last error. + * the complete error information for the last error. */ xmlError lastError; xmlParserMode parseMode; /* the parser mode */ @@ -329,7 +331,7 @@ struct _xmlSAXLocator { * xmlSAXHandler: * * A SAX handler is bunch of callbacks called by the parser when processing - * of the input generate data or structure informations. + * of the input generate data or structure information. */ /** @@ -685,7 +687,7 @@ typedef int (*hasExternalSubsetSAXFunc) (void *ctx); * attribute values. * * SAX2 callback when an element start has been detected by the parser. - * It provides the namespace informations for the element, as well as + * It provides the namespace information for the element, as well as * the new namespace declarations on the element. */ @@ -707,7 +709,7 @@ typedef void (*startElementNsSAX2Func) (void *ctx, * @URI: the element namespace name if available * * SAX2 callback when an element end has been detected by the parser. - * It provides the namespace informations for the element. + * It provides the namespace information for the element. */ typedef void (*endElementNsSAX2Func) (void *ctx, diff --git a/sdk/include/reactos/libs/libxml/tree.h b/sdk/include/reactos/libs/libxml/tree.h index 6cfd73188cf..1e79be92ea9 100644 --- a/sdk/include/reactos/libs/libxml/tree.h +++ b/sdk/include/reactos/libs/libxml/tree.h @@ -443,7 +443,7 @@ struct _xmlAttr { struct _xmlDoc *doc; /* the containing document */ xmlNs *ns; /* pointer to the associated namespace */ xmlAttributeType atype; /* the attribute type if validating */ - void *psvi; /* for type/PSVI informations */ + void *psvi; /* for type/PSVI information */ }; /** @@ -502,7 +502,7 @@ struct _xmlNode { xmlChar *content; /* the content */ struct _xmlAttr *properties;/* properties list */ xmlNs *nsDef; /* namespace definitions on this node */ - void *psvi; /* for type/PSVI informations */ + void *psvi; /* for type/PSVI information */ unsigned short line; /* line number */ unsigned short extra; /* extra data for XPath/XSLT */ }; @@ -578,7 +578,7 @@ struct _xmlDoc { int charset; /* Internal flag for charset handling, actually an xmlCharEncoding */ struct _xmlDict *dict; /* dict used to allocate names or NULL */ - void *psvi; /* for type/PSVI informations */ + void *psvi; /* for type/PSVI information */ int parseFlags; /* set of xmlParserOption used to parse the document */ int properties; /* set of xmlDocProperties for this document diff --git a/sdk/include/reactos/libs/libxml/xmlIO.h b/sdk/include/reactos/libs/libxml/xmlIO.h index 8690d668c25..095b2f56d96 100644 --- a/sdk/include/reactos/libs/libxml/xmlIO.h +++ b/sdk/include/reactos/libs/libxml/xmlIO.h @@ -217,6 +217,8 @@ xmlParserInputBufferPtr */ XMLPUBFUN void XMLCALL xmlCleanupOutputCallbacks (void); +XMLPUBFUN int XMLCALL + xmlPopOutputCallbacks (void); XMLPUBFUN void XMLCALL xmlRegisterDefaultOutputCallbacks(void); XMLPUBFUN xmlOutputBufferPtr XMLCALL diff --git a/sdk/include/reactos/libs/libxml/xmlexports.h b/sdk/include/reactos/libs/libxml/xmlexports.h index f03af0d03a6..aceede5ec05 100644 --- a/sdk/include/reactos/libs/libxml/xmlexports.h +++ b/sdk/include/reactos/libs/libxml/xmlexports.h @@ -3,43 +3,46 @@ * Description: macros for marking symbols as exportable/importable. * * Copy: See Copyright for the status of this software. - * - * Author: Igor Zlatovic */ #ifndef __XML_EXPORTS_H__ #define __XML_EXPORTS_H__ -/** - * XMLPUBFUN, XMLPUBVAR, XMLCALL - * - * Macros which declare an exportable function, an exportable variable and - * the calling convention used for functions. - * - * Please use an extra block for every platform/compiler combination when - * modifying this, rather than overlong #ifdef lines. This helps - * readability as well as the fact that different compilers on the same - * platform might need different definitions. - */ +#if defined(_WIN32) || defined(__CYGWIN__) +/** DOC_DISABLE */ + +#ifdef LIBXML_STATIC + #define XMLPUBLIC +#elif defined(IN_LIBXML) + #define XMLPUBLIC __declspec(dllexport) +#else + #define XMLPUBLIC __declspec(dllimport) +#endif + +#if defined(LIBXML_FASTCALL) + #define XMLCALL __fastcall +#else + #define XMLCALL __cdecl +#endif +#define XMLCDECL __cdecl + +/** DOC_ENABLE */ +#else /* not Windows */ /** - * XMLPUBFUN: + * XMLPUBLIC: * - * Macros which declare an exportable function + * Macro which declares a public symbol */ -#define XMLPUBFUN -/** - * XMLPUBVAR: - * - * Macros which declare an exportable variable - */ -#define XMLPUBVAR extern +#define XMLPUBLIC + /** * XMLCALL: * - * Macros which declare the called convention for exported functions + * Macro which declares the calling convention for exported functions */ #define XMLCALL + /** * XMLCDECL: * @@ -48,100 +51,21 @@ */ #define XMLCDECL -/** DOC_DISABLE */ +#endif /* platform switch */ -/* Windows platform with MS compiler */ -#if defined(_WIN32) && defined(_MSC_VER) - #undef XMLPUBFUN - #undef XMLPUBVAR - #undef XMLCALL - #undef XMLCDECL - #if defined(IN_LIBXML) && !defined(LIBXML_STATIC) - #define XMLPUBFUN __declspec(dllexport) - #define XMLPUBVAR __declspec(dllexport) - #else - #define XMLPUBFUN - #if !defined(LIBXML_STATIC) - #define XMLPUBVAR __declspec(dllimport) extern - #else - #define XMLPUBVAR extern - #endif - #endif - #if defined(LIBXML_FASTCALL) - #define XMLCALL __fastcall - #else - #define XMLCALL __cdecl - #endif - #define XMLCDECL __cdecl -#endif +/* + * XMLPUBFUN: + * + * Macro which declares an exportable function + */ +#define XMLPUBFUN XMLPUBLIC -/* Windows platform with Borland compiler */ -#if defined(_WIN32) && defined(__BORLANDC__) - #undef XMLPUBFUN - #undef XMLPUBVAR - #undef XMLCALL - #undef XMLCDECL - #if defined(IN_LIBXML) && !defined(LIBXML_STATIC) - #define XMLPUBFUN __declspec(dllexport) - #define XMLPUBVAR __declspec(dllexport) extern - #else - #define XMLPUBFUN - #if !defined(LIBXML_STATIC) - #define XMLPUBVAR __declspec(dllimport) extern - #else - #define XMLPUBVAR extern - #endif - #endif - #define XMLCALL __cdecl - #define XMLCDECL __cdecl -#endif - -/* Windows platform with GNU compiler (Mingw) */ -#if defined(_WIN32) && defined(__MINGW32__) - #undef XMLPUBFUN - #undef XMLPUBVAR - #undef XMLCALL - #undef XMLCDECL - /* - * if defined(IN_LIBXML) this raises problems on mingw with msys - * _imp__xmlFree listed as missing. Try to workaround the problem - * by also making that declaration when compiling client code. - */ - #if defined(IN_LIBXML) && !defined(LIBXML_STATIC) - #define XMLPUBFUN __declspec(dllexport) - #define XMLPUBVAR __declspec(dllexport) extern - #else - #define XMLPUBFUN - #if !defined(LIBXML_STATIC) - #define XMLPUBVAR __declspec(dllimport) extern - #else - #define XMLPUBVAR extern - #endif - #endif - #define XMLCALL __cdecl - #define XMLCDECL __cdecl -#endif - -/* Cygwin platform (does not define _WIN32), GNU compiler */ -#if defined(__CYGWIN__) - #undef XMLPUBFUN - #undef XMLPUBVAR - #undef XMLCALL - #undef XMLCDECL - #if defined(IN_LIBXML) && !defined(LIBXML_STATIC) - #define XMLPUBFUN __declspec(dllexport) - #define XMLPUBVAR __declspec(dllexport) - #else - #define XMLPUBFUN - #if !defined(LIBXML_STATIC) - #define XMLPUBVAR __declspec(dllimport) extern - #else - #define XMLPUBVAR extern - #endif - #endif - #define XMLCALL __cdecl - #define XMLCDECL __cdecl -#endif +/** + * XMLPUBVAR: + * + * Macro which declares an exportable variable + */ +#define XMLPUBVAR XMLPUBLIC extern /* Compatibility */ #if !defined(LIBXML_DLL_IMPORT) diff --git a/sdk/include/reactos/libs/libxml/xmlschemas.h b/sdk/include/reactos/libs/libxml/xmlschemas.h index 97930c7c3f4..b90e9d18c6e 100644 --- a/sdk/include/reactos/libs/libxml/xmlschemas.h +++ b/sdk/include/reactos/libs/libxml/xmlschemas.h @@ -122,7 +122,7 @@ typedef xmlSchemaValidCtxt *xmlSchemaValidCtxtPtr; * @line: returned line information * * A schemas validation locator, a callback called by the validator. - * This is used when file or node informations are not available + * This is used when file or node information are not available * to find out what file and line number are affected * * Returns: 0 in case of success and -1 in case of error diff --git a/sdk/include/reactos/libs/libxml/xmlversion.h b/sdk/include/reactos/libs/libxml/xmlversion.h index 2ac15f54044..cd2dc1dbc1d 100644 --- a/sdk/include/reactos/libs/libxml/xmlversion.h +++ b/sdk/include/reactos/libs/libxml/xmlversion.h @@ -1,6 +1,6 @@ /* - * Summary: compile-time version informations - * Description: compile-time version informations for the XML library + * Summary: compile-time version information + * Description: compile-time version information for the XML library * * Copy: See Copyright for the status of this software. * @@ -29,28 +29,28 @@ XMLPUBFUN void XMLCALL xmlCheckVersion(int version); * * the version string like "1.2.3" */ -#define LIBXML_DOTTED_VERSION "2.9.10" +#define LIBXML_DOTTED_VERSION "2.9.12" /** * LIBXML_VERSION: * * the version number: 1.2.3 value is 10203 */ -#define LIBXML_VERSION 20910 +#define LIBXML_VERSION 20912 /** * LIBXML_VERSION_STRING: * * the version number string, 1.2.3 value is "10203" */ -#define LIBXML_VERSION_STRING "20910" +#define LIBXML_VERSION_STRING "20912" /** * LIBXML_VERSION_EXTRA: * * extra version information, used to show a CVS compilation */ -#define LIBXML_VERSION_EXTRA "-GITv2.9.10-rc1-2-ga5bb6aaa2" +#define LIBXML_VERSION_EXTRA "-GITv2.9.11" /** * LIBXML_TEST_VERSION: @@ -58,7 +58,7 @@ XMLPUBFUN void XMLCALL xmlCheckVersion(int version); * Macro to check that the libxml version in use is compatible with * the version the software has been compiled against */ -#define LIBXML_TEST_VERSION xmlCheckVersion(20910); +#define LIBXML_TEST_VERSION xmlCheckVersion(20912); #ifndef VMS #if 0 diff --git a/sdk/include/reactos/libs/libxml/xmlversion.h.in b/sdk/include/reactos/libs/libxml/xmlversion.h.in index 964f10d81ab..c995fe512bd 100644 --- a/sdk/include/reactos/libs/libxml/xmlversion.h.in +++ b/sdk/include/reactos/libs/libxml/xmlversion.h.in @@ -1,6 +1,6 @@ /* - * Summary: compile-time version informations - * Description: compile-time version informations for the XML library + * Summary: compile-time version information + * Description: compile-time version information for the XML library * * Copy: See Copyright for the status of this software. * diff --git a/sdk/include/reactos/libs/libxml/xpath.h b/sdk/include/reactos/libs/libxml/xpath.h index 4ef3909b409..539593fa506 100644 --- a/sdk/include/reactos/libs/libxml/xpath.h +++ b/sdk/include/reactos/libs/libxml/xpath.h @@ -359,8 +359,6 @@ struct _xmlXPathContext { unsigned long opLimit; unsigned long opCount; int depth; - int maxDepth; - int maxParserDepth; }; /* @@ -373,7 +371,7 @@ typedef xmlXPathCompExpr *xmlXPathCompExprPtr; /** * xmlXPathParserContext: * - * An XPath parser context. It contains pure parsing informations, + * An XPath parser context. It contains pure parsing information, * an xmlXPathContext, and the stack of objects. */ struct _xmlXPathParserContext { diff --git a/sdk/lib/3rdparty/libxml2/ChangeLog b/sdk/lib/3rdparty/libxml2/ChangeLog index b3f3fc1ff1b..264067061aa 100644 --- a/sdk/lib/3rdparty/libxml2/ChangeLog +++ b/sdk/lib/3rdparty/libxml2/ChangeLog @@ -379,7 +379,7 @@ Tue Aug 26 09:42:08 CEST 2008 Daniel Veillard * test/schemas/regexp-char-ref_0.xml test/schemas/regexp-char-ref_0.xsd test/schemas/regexp-char-ref_1.xsd result/schemas/regexp-char-ref_0_0 result/schemas/regexp-char-ref_1_0: Volker Grabsch also provided - regession tests for this + regression tests for this Tue Aug 26 09:25:39 CEST 2008 Daniel Veillard @@ -475,7 +475,7 @@ Thu Jul 31 10:15:53 CEST 2008 Daniel Veillard * include/libxml/xmlerror.h parser.c: clean up namespace errors checking and reporting, errors when a document is labelled as UTF-16 while it is parsed as UTF-8 and no encoding was given - explicitely. + explicitly. * result/errors/webdav.xml.*: some warnings are no recategorized as Namespace errors @@ -663,7 +663,7 @@ Thu Apr 3 11:44:57 CEST 2008 Daniel Veillard Thu Apr 3 11:02:02 CEST 2008 Daniel Veillard - * HTMLparser.c: apparently it's okay to forget the semicolumn after + * HTMLparser.c: apparently it's okay to forget the semicolon after entity refs in HTML, fixing char refs parsing accordingly based on T. Manske patch, this should fix #517653 @@ -787,7 +787,7 @@ Wed Mar 12 18:56:22 CET 2008 Daniel Veillard Wed Mar 12 10:22:01 CET 2008 Daniel Veillard - * python/types.c: fix a memory errro when using namespace nodes + * python/types.c: fix a memory error when using namespace nodes returned from XPath queries, should fix #521699 * python/tests/Makefile.am python/tests/xpathns.py: add a specific regression test for it @@ -917,7 +917,7 @@ Fri Jan 25 20:01:42 CET 2007 Rob Richards Thu Jan 24 15:37:04 CET 2008 Daniel Veillard - * parser.c: fix a memeory leak in internal subset parsing with + * parser.c: fix a memory leak in internal subset parsing with a fix from Ashwin * test/errors/content1.xml result/errors/content1.xml*: add test to regressions @@ -1230,7 +1230,7 @@ Thu May 10 01:52:42 CEST 2007 Daniel Veillard * list.c: applied patch to fix xmlListAppend() from Georges-André SILBER - * valid.c: also fix the place wher it was called. + * valid.c: also fix the place where it was called. Wed May 2 18:47:33 CEST 2007 Daniel Veillard @@ -1424,7 +1424,7 @@ Thu Jan 4 18:27:49 CET 2007 Daniel Veillard test/relaxng/empty1_0.xml test/relaxng/comps.rng test/relaxng/empty0.rng test/relaxng/empty0_0.xml test/relaxng/empty1_1.xml: tests which were apparently - never commited to CVS + never committed to CVS Wed Jan 3 16:05:21 PST 2007 Aleksey Sanin @@ -1531,7 +1531,7 @@ Tue Oct 17 18:12:34 CEST 2006 Daniel Veillard * HTMLparser.c: fixing HTML minimized attribute values to be generated internally if not present, fixes bug #332124 * result/HTML/doc2.htm.sax result/HTML/doc3.htm.sax - result/HTML/wired.html.sax: this affects the SAX event strem for + result/HTML/wired.html.sax: this affects the SAX event stream for a few test cases Tue Oct 17 17:56:31 CEST 2006 Daniel Veillard @@ -1627,7 +1627,7 @@ Wed Oct 11 23:11:58 CEST 2006 Daniel Veillard Wed Oct 11 18:40:00 CEST 2006 Daniel Veillard - * valid.c: fixed a weird error where validity context whould not + * valid.c: fixed a weird error where validity context would not show up if warnings were disabled pointed out by Bob Stayton * xmlIO.c doc/generator.py: cleanup and fix to regenerate the docs * doc//* testapi.c: rebuilt the docs @@ -1740,7 +1740,7 @@ Thu Aug 17 00:48:31 CEST 2006 Rob Richards Wed Aug 16 01:15:12 CEST 2006 Rob Richards * HTMLtree.c xmlsave.c: Add linefeeds to error messages allowing - for consistant handling. + for consistent handling. Tue Aug 15 15:02:18 CEST 2006 Kasimier Buchcik @@ -1857,7 +1857,7 @@ Mon Jun 26 16:22:50 CEST 2006 Kasimier Buchcik initialized to zero here; this could lead to the activation of the axis rewrite code in xmlXPathNodeCollectAndTest() when @rewriteType is randomly set to the value 1. A test - (hardcoding the intial value to 1) revealed that the + (hardcoding the initial value to 1) revealed that the resulting incorrect behaviour is similar to the behaviour as described by Arnold Hendriks on the mailing list; so I hope that will fix the issue. @@ -1912,7 +1912,7 @@ Fri Jun 16 21:37:44 CEST 2006 Kasimier Buchcik for my custom handling of ns-references in my DOM wrapper. Substituted code which created the XML namespace decl on the doc for a call to xmlTreeEnsureXMLDecl(). Removed - those nastly "warnigns" from the docs of the clone/adopt + those nasty "warnings" from the docs of the clone/adopt functions; they work fine on my side. Mon Jun 12 13:23:11 CEST 2006 Kasimier Buchcik @@ -2033,7 +2033,7 @@ Tue May 30 11:21:34 CEST 2006 Kasimier Buchcik Mon May 29 18:06:17 CEST 2006 Kasimier Buchcik * xpath.c include/libxml/xpath.h: Added an XPath object cache. - It sits on an xmlXPathContext and need to be explicitely + It sits on an xmlXPathContext and need to be explicitly activated (or deactivated again) with xmlXPathContextSetObjectCache(). The cache consists of 5 lists for node-set, string, number, boolean and misc XPath @@ -2052,7 +2052,7 @@ Wed May 24 10:54:25 CEST 2006 Kasimier Buchcik * xpath.c: Removed a memcpy if xmlXPathNodeSetMerge(); it seems we really need to walk the whole list, since those - nastly namespace nodes need to be added with + nasty namespace nodes need to be added with xmlXPathNodeSetDupNs(); thus a pure memcpy is not possible. A flag on the node-set indicating if namespace nodes are in the set would help here; this is the 3rd flag which would @@ -2063,7 +2063,7 @@ Wed May 24 10:54:25 CEST 2006 Kasimier Buchcik 2) Of what type are the nodes in the set (or of mixed type)? This would allow for faster merging of node-sets. 3) Are namespace nodes in the set? - This would allow to skipp all the namespace node specific + This would allow to skip all the namespace node specific special handling. Faster node-set merging if the first set is empty; just memcpy the set. @@ -2485,7 +2485,7 @@ Mon Jan 9 15:33:16 CET 2006 Daniel Veillard Thu Jan 5 16:25:06 CET 2006 Daniel Veillard - * NEWS configure.in libxml.spec.in testapi.c doc/*: upated the news + * NEWS configure.in libxml.spec.in testapi.c doc/*: updated the news regenerated the docs, preparing for release of 2.6.23 * pattern.c xmlschemas.c: fixed some comments @@ -2520,7 +2520,7 @@ Wed Jan 4 18:07:47 CET 2006 Daniel Veillard Wed Jan 4 15:00:51 CET 2006 Daniel Veillard * SAX2.c: fix bug #324432 with - * test/ns7 resul//ns7*: added to the regression tests + * test/ns7 result/ns7*: added to the regression tests Wed Jan 4 10:53:56 CET 2006 Daniel Veillard @@ -2861,7 +2861,7 @@ Fri Oct 21 10:50:14 EDT 2005 Rob Richards Wed Oct 19 16:53:47 BST 2005 Daniel Veillard - * xmlregexp.c: commiting a some fixes and debug done yesterday in + * xmlregexp.c: committing a some fixes and debug done yesterday in the London airport. Thu Oct 20 12:54:23 CEST 2005 Kasimier Buchcik @@ -2932,7 +2932,7 @@ Fri Oct 14 16:21:22 CEST 2005 Kasimier Buchcik Allowed IDCs to resolve also to nodes of complex type with simple content. Added check for keyrefs with references to keyrefs. - IDC target-nodes were interferring with IDC node-tables, + IDC target-nodes were interfering with IDC node-tables, since they used one list of entries only. I separated this one big list into 3 lists: 1 for IDC node-table entries, 1 for _duplicates_ of IDC node-table entries and 1 for @@ -3053,7 +3053,7 @@ Mon Sep 12 21:00:53 CEST 2005 Kasimier Buchcik * xmlschemas.c include/libxml/schemasInternals.h include/libxml/xmlerror.h: Completion of the schema graph. Centralisation, more robustness of the schema document - aquisition story. Centralised and restructured component fixup. + acquisition story. Centralised and restructured component fixup. Fixed attribute derivation when 'prohibiting' attribute uses. Added warnings: when schema documents cannot be localized during imports; when we get duplicate and pointless attribute @@ -3385,7 +3385,7 @@ Wed Aug 10 18:21:41 CEST 2005 Daniel Veillard list values. * test/relaxng/307377* result/relaxng/307377* Makefile.am runtest.c: added examples to the regression tests, problem is that streaming - version gives slightly more informations. + version gives slightly more information. Wed Aug 10 15:25:53 CEST 2005 Daniel Veillard @@ -3398,7 +3398,7 @@ Wed Aug 10 11:59:46 CEST 2005 Kasimier Buchcik Tue Aug 9 23:37:22 CEST 2005 Daniel Veillard * xmlregexp.c: fixed a determinism detection problem exposed by - ##other tests commited by Kasimier, also added a small speedup + ##other tests committed by Kasimier, also added a small speedup of determinism detection. * test/results/any6_2_0* any8_1_0* any7_1_2* any7_2_2*: added the results to the regression tests now @@ -3424,7 +3424,7 @@ Tue Aug 9 13:07:27 CEST 2005 Daniel Veillard * result/schemas/any7* test/schemas/any7: completed the tests and added the results * result/schemas/any3_0_0.err result/schemas/any5_0_0.err - result/schemas/any5_1_0.err: this slightly chnages the output + result/schemas/any5_1_0.err: this slightly changes the output from 3 existing tests Mon Aug 8 22:33:08 CEST 2005 Daniel Veillard @@ -3468,7 +3468,7 @@ Mon Aug 8 01:41:53 CEST 2005 Daniel Veillard Sun Aug 7 12:39:35 CEST 2005 Daniel Veillard - * test/relaxng/docbook_0.xml: get rid of the dependancy on a locally + * test/relaxng/docbook_0.xml: get rid of the dependency on a locally installed DTD * uri.c include/libxml/uri.h xmlIO.c nanoftp.c nanohttp.c: try to cleanup the Path/URI conversion mess, needed fixing in various @@ -3522,7 +3522,7 @@ Sat Jul 30 17:26:58 EDT 2005 Daniel Veillard Sat Jul 30 17:08:07 EDT 2005 Daniel Veillard - * schematron.c xmllint.c include/libxml/schematron.h: commiting + * schematron.c xmllint.c include/libxml/schematron.h: committing work done on the plane last week-end Sat Jul 30 15:16:29 CEST 2005 Daniel Veillard @@ -4029,7 +4029,7 @@ Mon Jun 27 01:01:32 CEST 2005 Daniel Veillard Sun Jun 26 20:08:24 CEST 2005 Daniel Veillard - * include/libxml/valid.h valid.c: avoid name glob in agruments as + * include/libxml/valid.h valid.c: avoid name glob in arguments as it matches the glob() routine. * runtest.c Makefile.am: first steps toward a C regression test framework. @@ -4463,7 +4463,7 @@ Fri Apr 1 16:07:59 CEST 2005 Daniel Veillard * doc/apibuild.py doc/elfgcchack.xsl: revamped the elfgcchack.h format to cope with gcc4 change of aliasing allowed scopes, had - to add extra informations to doc/libxml2-api.xml to separate + to add extra information to doc/libxml2-api.xml to separate the header from the c module source. * *.c: updated all c library files to add a #define bottom_xxx and reimport elfgcchack.h thereafter, and a bit of cleanups. @@ -4955,9 +4955,9 @@ Fri Jan 28 18:37:18 CET 2005 Daniel Veillard Fri Jan 28 16:51:47 CET 2005 Kasimier Buchcik - * xmlschemas.c: Corrected an ambigious symbol-space for + * xmlschemas.c: Corrected an ambiguous symbol-space for local attribute declarations. IFDEFed more IDC code to - surpress compiler warnings. + suppress compiler warnings. Fri Jan 28 00:57:04 CET 2005 Daniel Veillard @@ -4978,7 +4978,7 @@ Thu Jan 27 13:39:04 CET 2005 Kasimier Buchcik Added an initial skeleton for indentity-constraints. This is all defined out, since not complete, plus it needs support from other modules. - Added machanism to store element information for the + Added mechanism to store element information for the ancestor-or-self axis; this is needed for identity-constraints and should be helpful for a future streamable validation. * include/libxml/xmlerror.h: Added an error code for @@ -5028,7 +5028,7 @@ Sun Jan 23 21:14:20 CET 2005 Daniel Veillard Sun Jan 23 18:35:00 CET 2005 Daniel Veillard - * parser.c: boosting common commnent parsing code, it was really + * parser.c: boosting common comment parsing code, it was really slow. * test/comment[3-5].xml result//comment[3-5].xml*: added sprecific regression tests @@ -5179,7 +5179,7 @@ Sat Jan 8 23:04:10 CET 2005 Daniel Veillard Fri Jan 7 14:54:51 CET 2005 Daniel Veillard * TODO: small update - * xmlregexp.c: trying to add an API to get useful error informations + * xmlregexp.c: trying to add an API to get useful error information back from a failing regexp context. Thu Jan 6 17:35:41 HKT 2005 William Brack @@ -5280,7 +5280,7 @@ Sat Dec 25 18:10:02 HKT 2004 William Brack Fri Dec 24 16:31:22 HKT 2004 William Brack - * python/generator.py: added most required entires to + * python/generator.py: added most required entries to foreign encoding table, plus some additional logic to assure only the 1st param uses the 't#' format. Fixes bug #152286, but may still have some other UTF-16 problems. @@ -5360,7 +5360,7 @@ Fri Nov 26 13:09:04 CET 2004 Kasimier Buchcik of elements for which a declaration existed were still processed by the wildcard mechanism (reported by philippe ventrillon to the mailing list). - Changed the import and include machanism to share dictionaries. + Changed the import and include mechanism to share dictionaries. Fri Nov 26 11:44:36 CET 2004 Daniel Veillard @@ -5640,7 +5640,7 @@ Tue Nov 2 15:49:34 CET 2004 Daniel Veillard * SAX2.c nanoftp.c parser.c parserInternals.c tree.c xmlIO.c xmlstring.c: various API hardeing changes as a result of running the first set of automatic API regression tests. - * test/slashdot16.xml: apparently missing from CVS, commited it + * test/slashdot16.xml: apparently missing from CVS, committed it Mon Nov 1 15:54:18 CET 2004 Daniel Veillard @@ -5867,7 +5867,7 @@ Wed Sep 29 15:00:11 CEST 2004 Kasimier Buchcik model group "all". * test/schemas/bug152470_1.xsd: Removed an "abstract" attribute, which broke the test. - * xstc/xstc.py: Workaround to accomodate case insensitive + * xstc/xstc.py: Workaround to accommodate case insensitive test definitions in ms-test.def.xml (was missing in a previous commit). @@ -5961,7 +5961,7 @@ Thu Sep 16 13:24:27 CEST 2004 Kasimier Buchcik * xmlschemas.c include/libxml/schemasInternals.h test/schemas/bug152470_1.* result/schemas/bug152470_1_1*: - Simpified attribute wildcard creation and assignment to get rid + Simplified attribute wildcard creation and assignment to get rid of memory leaks. Restructured the validation process. Restructured and expanded parsing of . @@ -5978,7 +5978,7 @@ Thu Sep 16 13:24:27 CEST 2004 Kasimier Buchcik 'anyType' using the short-hand form (see bug # 152470, submitted by Thilo Jeremias). * include/libxml/xmlschematypes.h: Cleaned up some comments. - * xstc/xstc.py: Workaround to accomodate case insensitive + * xstc/xstc.py: Workaround to accommodate case insensitive test definitions in ms-test.def.xml. * result/schemas/deter0_0_0.err result/schemas/ns0_0_2.err result/schemas/ns0_1_2.err: Adapted. @@ -6321,7 +6321,7 @@ Sat Aug 14 13:18:57 CEST 2004 Daniel Veillard to document xmlSchemasSetValidErrors() limitations, #141827 * error.c: Add information in generic and structured error setter functions that this need to be done per thread #144308 - * xmlsave.c: fixed bug whith missing NOTATION(s) serialization + * xmlsave.c: fixed bug with missing NOTATION(s) serialization bug #144162 * doc/xmllint.xml: typo fix #144840 @@ -6691,7 +6691,7 @@ Tue Jun 8 21:27:03 HKT 2004 William Brack Tue Jun 8 14:01:14 CEST 2004 Daniel Veillard * parser.c xmlreader.c include/libxml/parser.h: fixed a serious - problem when substituing entities using the Reader, the entities + problem when substituting entities using the Reader, the entities content might be freed and if rereferenced would crash * Makefile.am test/* result/*: added a new test case and a new test operation for the reader with substitution of entities. @@ -6847,7 +6847,7 @@ Sun May 16 03:06:31 CEST 2004 Daniel Veillard Sat May 15 20:14:21 CEST 2004 Daniel Veillard * doc/ChangeLog.awk doc/ChangeLog.xsl: first steps of a good - ChangeLog page generation. The awk shoudl escape characters + ChangeLog page generation. The awk should escape characters not okay in XML and the xslt should make links to functions or variables or bug reported in the entries. @@ -7049,7 +7049,7 @@ Sun Apr 18 23:45:46 CEST 2004 Daniel Veillard Sun Apr 18 22:51:43 CEST 2004 Daniel Veillard - * xpath.c: relaxed id() to not check taht the name(s) passed + * xpath.c: relaxed id() to not check that the name(s) passed are actually NCName, decided this in agreement with Aleksey Sanin since existing specs like Visa3D broke that conformance checking and other tools seems to not implement it sigh... @@ -7062,7 +7062,7 @@ Sun Apr 18 21:46:17 CEST 2004 Daniel Veillard * xpath.c: work around Microsoft compiler NaN bug raise reported by Mark Vakoc * xmlschemas.c include/libxml/schemasInternals.h - include/libxml/xmlerror.h: fixed a recusive extention schemas + include/libxml/xmlerror.h: fixed a recursive extension schemas compilation error raised by taihei goi Sun Apr 18 16:57:02 CEST 2004 Daniel Veillard @@ -7228,7 +7228,7 @@ Tue Mar 23 12:35:08 CET 2004 Daniel Veillard * configure.in doc/* News: preparing 2.6.8 release, updated and rebuilt the docs. - * Makefile.am: use valgring fro the new Python based regression tests + * Makefile.am: use valgring for the new Python based regression tests Mon Mar 22 20:07:27 CET 2004 Daniel Veillard @@ -7292,7 +7292,7 @@ Wed Mar 10 17:22:48 CET 2004 Daniel Veillard Wed Mar 10 19:42:22 HKT 2004 William Brack - * doc/search.php: Minor change for later verson of php requiring + * doc/search.php: Minor change for later version of php requiring $HTTP_GET_VARS. Wed Mar 10 00:12:31 HKT 2004 William Brack @@ -7361,8 +7361,8 @@ Thu Mar 4 15:00:45 CET 2004 Daniel Veillard Thu Mar 4 14:39:38 CET 2004 Daniel Veillard - * Makefile.am tree.c xmlsave.c include/libxml/xmlsave.h: commiting - the new xmlsave module before the actuall big code change. + * Makefile.am tree.c xmlsave.c include/libxml/xmlsave.h: committing + the new xmlsave module before the actual big code change. Thu Mar 4 12:38:53 CET 2004 Daniel Veillard @@ -7872,7 +7872,7 @@ Mon Jan 5 20:47:07 MST 2004 John Fleck Tue Jan 6 00:10:33 CET 2004 Daniel Veillard - * rngparser.c: commiting the compact relax ng parser. It's not + * rngparser.c: committing the compact relax ng parser. It's not completely finished, it's not integrated but I want to save the current state @@ -8026,7 +8026,7 @@ Wed Dec 24 00:29:30 CET 2003 Daniel Veillard Tue Dec 23 15:14:37 HKT 2003 William Brack * valid.c: fixed bug concerning validation using external - dtd of element with mutiple namespace declarations + dtd of element with multiple namespace declarations (Bug 129821) Tue Dec 23 11:41:42 HKT 2003 William Brack @@ -8407,7 +8407,7 @@ Thu Nov 20 12:54:30 CET 2003 Daniel Veillard * doc/examples/*: added his test as the xmlWriter example * doc/html/ doc/*.html: this resulted in some improvements * include/libxml/hash.h: fixed an inclusion problem when - wasn't preceeded by + wasn't preceded by Wed Nov 19 17:19:35 CET 2003 Daniel Veillard @@ -8430,7 +8430,7 @@ Wed Nov 19 00:48:56 CET 2003 Daniel Veillard Tue Nov 18 21:51:15 CET 2003 Daniel Veillard * include/libxml/*.h include/libxml/*.h.in: modified the file - header to add more informations, painful... + header to add more information, painful... * genChRanges.py genUnicode.py: updated to generate said changes in headers * doc/apibuild.py: extract headers, add them to libxml2-api.xml @@ -8572,7 +8572,7 @@ Wed Nov 12 01:38:16 CET 2003 Daniel Veillard added autogeneration of a web page for the examples * doc/examples/example1.c doc/examples/.cvsignore doc/examples/examples.xml doc/examples/index.py: updated the - informations extracted, improved the format and indexing. + information extracted, improved the format and indexing. Tue Nov 11 22:08:59 CET 2003 Daniel Veillard @@ -8774,7 +8774,7 @@ Tue Oct 28 16:42:16 CET 2003 Daniel Veillard * error.c valid.c include/libxml/xmlerror.h: fixing bug #125653 sometimes the error handlers can get a parser context on DTD errors, and sometime they don't. So be very careful when trying - to grab those informations. + to grab those information. Tue Oct 28 15:26:18 CET 2003 Daniel Veillard @@ -8884,7 +8884,7 @@ Mon Oct 20 19:02:53 CEST 2003 Daniel Veillard * python/tests/Makefile.am python/tests/reader7.py python/tests/walker.py: adding regression testing for the new xmlreader APIs, new APIs for reader creation, including - makeing reader "walker" operating on preparsed document trees. + making reader "walker" operating on preparsed document trees. Sun Oct 20 22:37:03 HKT 2003 William Brack @@ -9084,7 +9084,7 @@ Fri Oct 10 16:45:20 CEST 2003 Daniel Veillard Fri Oct 10 16:19:17 CEST 2003 Daniel Veillard * include/libxml/tree.h: make room in Doc, Element, Attributes - for PSVI type informations. + for PSVI type information. Fri Oct 10 16:08:02 CEST 2003 Daniel Veillard @@ -9251,7 +9251,7 @@ Fri Oct 3 00:19:02 CEST 2003 Daniel Veillard scrolling to see where thing broke wasn't pleasant * configure.in: some beta4 preparation, but not ready yet * error.c globals.c include/libxml/globals.h include/libxml/xmlerror.h: - new error handling code, last error informations are stored + new error handling code, last error information are stored in the parsing context or a global variable, new APIs to handle the xmlErrorPtr type. * parser.c parserInternals.c valid.c : started migrating to the @@ -9261,7 +9261,7 @@ Fri Oct 3 00:19:02 CEST 2003 Daniel Veillard * parser.c: small potential buffer access problem in push code provided by Justin Fletcher * result/*.sax result/VC/PENesting* result/namespaces/* - result/valid/*.err: some error messages were sligthly changed. + result/valid/*.err: some error messages were slightly changed. Thu Oct 2 13:01:13 2003 Aleksey Sanin @@ -9369,7 +9369,7 @@ Sun Sep 28 02:15:07 CEST 2003 Daniel Veillard * include/libxml/SAX.h include/libxml/parser.h: move the SAXv1 block definitions to parser.h fixes bug #123380 * xmlreader.c include/libxml/xmlreader.h: reinstanciate - the attribute and element pool borken 2 commits ago. + the attribute and element pool broken 2 commits ago. Start playing with an entry point to preserve a subtree. * entities.c: remove a warning. @@ -9436,7 +9436,7 @@ Thu Sep 25 16:23:58 CEST 2003 Daniel Veillard include/libxml/globals.h include/libxml/SAX.h: make sure the global variables for the default SAX handler are V1 ones to avoid ABI compat problems. - * xmlreader.c: cleanup of uneeded code + * xmlreader.c: cleanup of unneeded code * hash.c: fix a comment Thu Sep 25 14:16:51 CEST 2003 Daniel Veillard @@ -9734,7 +9734,7 @@ Sun Sep 7 11:11:45 CEST 2003 Daniel Veillard * dict.c: allow to give -1 for undefined length in lookups * include/libxml/parser.h parser.c parserInternals.c testSAX.c: first round of work on the new SAX2 interfaces, the API - will change but commiting before changing for historical + will change but committing before changing for historical reference. Sat Sep 6 10:55:01 PTD 2003 William Brack @@ -10091,7 +10091,7 @@ Thu Aug 7 21:13:22 HKT 2003 William Brack Wed Aug 6 12:32:11 HKT 2003 William Brack * error.c trionan.[ch] testThreads.c python/generator.py: - further small changes to elminate most of the remaining + further small changes to eliminate most of the remaining warnings. Tue Aug 5 23:51:21 HKT 2003 William Brack @@ -10130,7 +10130,7 @@ Sun Aug 3 21:02:30 EDT 2003 Daniel Veillard * valid.c: fixed another problem with namespaces on element in mixed content case * python/tests/reader2.py: updated the testcase with - Bjorn Reese fix to reader for unsignificant white space + Bjorn Reese fix to reader for insignificant white space * parser.c HTMLparser.c: cleanup. Sun Aug 3 20:55:40 EDT 2003 Daniel Veillard @@ -10151,7 +10151,7 @@ Sun Aug 3 18:56:54 EDT 2003 Daniel Veillard Fri Aug 1 23:55:23 HKT 2003 William Brack Coninuing work on bug 118559 - * DOCBparser.c: removed 2 unsed vars + * DOCBparser.c: removed 2 unused vars * xmlregexp.c: changed some numeric const to their enum symbols * xmlreader.c: changed one var define from int to enum (a little more to be done, awaiting co-ordination) @@ -10318,7 +10318,7 @@ Thu Jul 10 16:02:47 CEST 2003 Daniel Veillard Tue Jul 8 16:02:19 CEST 2003 Daniel Veillard - * globals.c threads.c: fixes some problem when freeing unititialized + * globals.c threads.c: fixes some problem when freeing uninitialized mutexes Tue Jul 8 14:15:07 CEST 2003 Daniel Veillard @@ -10373,7 +10373,7 @@ Sat Jul 5 22:30:25 CEST 2003 Daniel Veillard Sat Jul 5 00:51:30 HKT 2003 William Brack Fixed problem with multi-threading, shown by the test program - testThreads. After fix, ran mutiple tests on various speed + testThreads. After fix, ran multiple tests on various speed machines (single and dual processor X86), which all seem okay. * catalog.c: added missing xmlRMutexUnlock in xmlLoadCatalog @@ -10451,7 +10451,7 @@ Thu Jun 5 11:31:02 CEST 2003 Daniel Veillard Mon Jun 2 21:56:15 MVT 2003 Daniel Veillard - * relaxng.c xmlschemas.c include/libxml/schemasInternals.h: commiting + * relaxng.c xmlschemas.c include/libxml/schemasInternals.h: committing some work done while in the Maldives (hence the timezone on the laptop !) * result/schemas/length3* test/schemas/deter0_* @@ -11398,7 +11398,7 @@ Wed Feb 19 14:26:51 CET 2003 Daniel Veillard Wed Feb 19 01:17:48 CET 2003 Daniel Veillard - * relaxng.c: guess what ! Relax-NG bugfixing, what a surprize... + * relaxng.c: guess what ! Relax-NG bugfixing, what a surprise... Tue Feb 18 22:09:50 CET 2003 Daniel Veillard @@ -11929,10 +11929,10 @@ Mon Jan 6 14:06:07 CET 2003 Daniel Veillard * configure.in NEWS: preparing 2.5.0 release * SAX.c: only warn in pedantic mode about namespace name - brokeness + brokenness * globals.c: fix a doc generation problem * uri.c: fix #101520 - * doc/*: updated and rebuilt the doc for the release, includuding + * doc/*: updated and rebuilt the doc for the release, including stylesheet update * python/Makefile.am: fix a filename bug @@ -12092,7 +12092,7 @@ Sun Dec 29 12:13:18 CET 2002 Daniel Veillard Sat Dec 28 23:49:12 CET 2002 Daniel Veillard * xmlreader.c include/libxml/xmlreader.h doc/libxml2-api.xml: - extended the XmlTextReader API a bit, addding accessors for + extended the XmlTextReader API a bit, adding accessors for the current doc and node, and an entity substitution mode for the parser. * python/libxml.py python/libxml2class.txt: related updates @@ -12479,7 +12479,7 @@ Sun Nov 17 10:25:43 CET 2002 Daniel Veillard Sat Nov 16 16:30:25 CET 2002 Daniel Veillard - * parser.c xpath.c: fixing #96925 wich was also dependent on the + * parser.c xpath.c: fixing #96925 which was also dependent on the processing of parsed entities, and XPath computation on sustitued entities. * testXPath.c: make sure entities are substituted. @@ -12715,7 +12715,7 @@ Wed Oct 16 16:05:38 CEST 2002 Daniel Veillard Tue Oct 15 12:41:01 CEST 2002 Daniel Veillard - * README: updated the contact informations + * README: updated the contact information Tue Oct 15 10:35:57 CEST 2002 Daniel Veillard @@ -13009,7 +13009,7 @@ Thu Sep 5 13:10:57 CEST 2002 Daniel Veillard Thu Sep 5 12:57:38 CEST 2002 Daniel Veillard - * valid.c: try to provide file and line informations, not all + * valid.c: try to provide file and line information, not all messages are covered, but it's a (good) start Thu Sep 5 12:49:35 CEST 2002 Daniel Veillard @@ -13060,7 +13060,7 @@ Wed Aug 28 13:44:54 CEST 2002 Daniel Veillard Sun Aug 25 16:38:05 CEST 2002 Daniel Veillard - * xmlIO.c: handle Windows sepecific file://localhost/ semantic ... + * xmlIO.c: handle Windows specific file://localhost/ semantic ... Thu Aug 22 22:03:19 CEST 2002 Daniel Veillard @@ -13394,7 +13394,7 @@ Mon Jun 03 00:04:21 2002 Chema Celorio * tree.h: added xmlDocFormatDump which is just as xmlDocDump but with the format parameter - * tree.c: made xmlDocDump a wrapper arround xmlDocFormatDump + * tree.c: made xmlDocDump a wrapper around xmlDocFormatDump Fri May 31 12:16:48 2002 Aleksey Sanin @@ -13499,13 +13499,13 @@ Wed May 15 00:25:34 CEST 2002 Igor Zlatkovic Tue May 14 13:00:48 CEST 2002 Daniel Veillard - * xpath.c: fixing an XPath function evalutation bug pointed out + * xpath.c: fixing an XPath function evaluation bug pointed out by Alexey Efimov where the context was lost when evaluating the function arguments Mon 13 May 2002 11:37:39 PM PDT Aleksey Sanin - * xpath.c include/libxml/xpathInternals.h: maked xmlXPathNodeSetAddNs() + * xpath.c include/libxml/xpathInternals.h: made xmlXPathNodeSetAddNs() function public for XMLSec performance optimizations Mon May 13 12:32:22 CEST 2002 Daniel Veillard @@ -13542,7 +13542,7 @@ Wed 01 May 2002 11:29:27 AM PDT Aleksey Sanin * include/libxml/xmlIO.h win32/dsp/libxml2.def.src win32/libxml2.def.src xmlIO.c: exported default 'file:', 'http:' and 'ftp:' protocols input handlers - and maked protocols comparisson case insensitive + and made protocols comparison case insensitive Tue Apr 30 16:29:05 CEST 2002 Daniel Veillard @@ -13999,7 +13999,7 @@ Mon Mar 11 10:10:30 CET 2002 Daniel Veillard Sun Mar 10 17:47:58 CET 2002 Daniel Veillard * valid.c: applied patch from Dodji Seketeli fixing an - uninitailized variable in xmlValidGetValidElements() + uninitialized variable in xmlValidGetValidElements() Sat Mar 9 15:10:49 CET 2002 Daniel Veillard @@ -14139,12 +14139,12 @@ Fri Mar 1 17:12:15 CET 2002 Daniel Veillard Fri Mar 1 13:56:12 CET 2002 Daniel Veillard - * python/*: commiting some Python bindings work done while travelling + * python/*: committing some Python bindings work done while travelling Fri Mar 1 10:11:15 CET 2002 Daniel Veillard * xmllint.c: close #72663 and #72658, don't memdump unless compiled - explicitely with memory debugging switched on + explicitly with memory debugging switched on Sat Feb 23 11:08:09 CET 2002 Daniel Veillard @@ -14496,7 +14496,7 @@ Sat Feb 2 11:25:51 CET 2002 Daniel Veillard Sat Feb 2 10:13:52 CET 2002 Daniel Veillard * configure.in libxml.spec.in python/Makefile.am python/TODO - python/generator.py python/libxml2class.txt: added more informations + python/generator.py python/libxml2class.txt: added more information in the libxml2-python package including docs. Slightly changed the class hierarchy * python/tests/*: added basic regression tests infrastructure too @@ -14543,7 +14543,7 @@ Wed Jan 30 21:51:26 CET 2002 Daniel Veillard Wed Jan 30 17:35:33 CET 2002 Daniel Veillard * python/generator.py python/libxml.c python/libxml.py - python/libxml_wrap.h: commited early version of a python binding + python/libxml_wrap.h: committed early version of a python binding for private use only ATM Sat Jan 26 22:41:13 CET 2002 Daniel Veillard @@ -15441,7 +15441,7 @@ Thu Sep 20 15:54:29 CEST 2001 Daniel Veillard Wed Sep 19 10:01:37 CEST 2001 Daniel Veillard * Makefile.am libxml.spec.in: backing up non-documented changes - commited without review or aproval by Jens Finke + committed without review or approval by Jens Finke * HACKING: made 100% clear that no commit should be done directly Mon Sep 17 18:52:37 CEST 2001 Daniel Veillard @@ -15586,7 +15586,7 @@ Sat Aug 25 15:30:17 CEST 2001 Daniel Veillard Thu Aug 23 23:16:32 CEST 2001 Daniel Veillard * catalog.c xmlIO.c: started some serious testing and fixed - a few bug and optmization needs. + a few bug and optimization needs. Thu Aug 23 17:26:58 CEST 2001 Daniel Veillard @@ -15874,7 +15874,7 @@ Tue Jul 24 15:39:11 CEST 2001 Daniel Veillard this slightly * include/libxml/parser.h SAX.c parser.c parserInternals.c xmllint.c: make element content line number generation - optionnal to avoid breaking old apps added interface to switch + optional to avoid breaking old apps added interface to switch Tue Jul 24 15:06:58 CEST 2001 Daniel Veillard @@ -16543,7 +16543,7 @@ Sun May 20 15:15:46 CEST 2001 Daniel Veillard Sat May 19 17:11:15 CEST 2001 Daniel Veillard - * doc/xml.html: update with 2.3.9 informations + * doc/xml.html: update with 2.3.9 information Sat May 19 16:50:47 CEST 2001 Daniel Veillard @@ -16738,7 +16738,7 @@ Sat Apr 28 18:54:28 CEST 2001 Daniel Veillard Sat Apr 28 16:33:05 CEST 2001 Daniel Veillard * xpath.c: simple and efficient optimization, XPath functions - aways bind to the same code, cache this + always bind to the same code, cache this * TODO: updated (by saying some is obsolete) Sat Apr 28 14:23:30 CEST 2001 Daniel Veillard @@ -16977,7 +16977,7 @@ Thu Apr 12 10:50:34 CEST 2001 Daniel Veillard Wed Apr 11 16:37:50 CEST 2001 Daniel Veillard * tree.h: include xmlmemory.h this seems to havoid a nasty glibc - bug where the linktime verions of free() won't work ... + bug where the linktime versions of free() won't work ... Wed Apr 11 14:21:31 CEST 2001 Daniel Veillard @@ -17376,7 +17376,7 @@ Thu Feb 15 15:57:14 CET 2001 Daniel Veillard Wed Feb 14 11:35:39 CET 2001 Daniel Veillard * hash.[ch]: added Paolo Casarini patch to provide Delete from - hash functionnalities. + hash functionalities. * doc/html/* : rebuild the doc Tue Feb 13 18:01:48 CET 2001 Daniel Veillard @@ -17514,7 +17514,7 @@ Thu Jan 25 13:34:11 CET 2001 Daniel Veillard Wed Jan 24 20:27:28 COT 2001 Alejandro Forero - * xmlIO.c (xmlFileOpen, xmlFileOpenW): Removed unnecesary checks. + * xmlIO.c (xmlFileOpen, xmlFileOpenW): Removed unnecessary checks. * xmlIO.c (xmlCheckFilename): Function added to know whether a given filename points to a valid file (not a directory). @@ -17551,7 +17551,7 @@ Mon Jan 22 10:35:40 CET 2001 Daniel Veillard of the data format with node set, as well as operators. * HTMLtree.c: added a newline at the end of the doctype output whe this one is not present initially. - * tree.c: make sure taht the parent and doc pointers are properly + * tree.c: make sure that the parent and doc pointers are properly set when copying attributes (lists). Sun Jan 21 10:47:38 CET 2001 Daniel Veillard @@ -17613,7 +17613,7 @@ Sat Jan 6 22:05:09 CET 2001 Daniel Veillard Sat Jan 6 19:13:27 CET 2001 Daniel Veillard - * Makefile.am: applied patch fro make check from Martin Vidner + * Makefile.am: applied patch for make check from Martin Vidner Thu Jan 4 19:07:49 CET 2001 Daniel Veillard @@ -17667,7 +17667,7 @@ Wed Dec 27 12:35:49 CET 2000 Daniel Veillard of xmllint too when using --memory flag, added a memory test suite at the Makefile level. * xpathInternals.h xpath.[ch] xpointer.c: fixed problems - with namespace use when encountering QNames in XPath evalation, + with namespace use when encountering QNames in XPath evaluation, added xmlns() scheme in XPointer. * nanoftp.c : incorporated a fix * parser.c xmlIO.c: fixed problems raised with encoding when using @@ -17892,7 +17892,7 @@ Sun Oct 22 13:59:50 CEST 2000 Daniel Veillard * valid.c: handling of blank nodes in DTd validation (raised by problems with a posteriori validation). * nanohttp.c: changing behaviour on HTTP write stuff. - * HTMLtree.c: forced body and html to be explicitely closed. + * HTMLtree.c: forced body and html to be explicitly closed. * xpath.h: exported more XPath functions. Sun Oct 15 22:28:32 CEST 2000 Daniel Veillard @@ -18037,7 +18037,7 @@ Fri Oct 6 12:58:04 CEST 2000 Daniel Veillard Thu Oct 5 18:13:15 CEST 2000 Daniel Veillard - * debugXML.c testXPath.c xpath.[ch]: got pissed by some nastyness + * debugXML.c testXPath.c xpath.[ch]: got pissed by some nastiness in the XPath engine, rewrote large parts of it, now it's far cleaner and in sync with the REC not an old WD. Fixed a parsing problem in the interactive XML shell found when testing XPath. @@ -18895,7 +18895,7 @@ Tue Dec 21 14:29:34 CET 1999 Daniel Veillard * result/HTML/*.htm*: Updated the HTML examples regression tests output * SAX.c tree.c: fixed bug on defaulting namespaces on attributes * debugXML.c: fixed a bug on printing default namespaces. - * HTMLtree.c: fixed a problem when outputing XML parsed docs as HTML + * HTMLtree.c: fixed a problem when outputting XML parsed docs as HTML Mon Dec 20 16:20:55 CET 1999 Daniel Veillard @@ -18922,7 +18922,7 @@ Sat Dec 18 16:07:03 CET 1999 Daniel Veillard Thu Dec 16 16:19:29 CET 1999 Daniel Veillard * tree.c: fixed a bug introduced in 1.8.0 and breaking default - namespace recognition, and Dia as a resul :-( + namespace recognition, and Dia as a result :-( * encoding.c: closed bug #3950 Wed Dec 15 19:22:23 CET 1999 Daniel Veillard @@ -18952,7 +18952,7 @@ Sun Dec 12 13:08:15 CET 1999 Daniel Veillard buffers instead, this was really needed, validation was breaking in strange ways due to that. Added xmlParseStringPEReference() and other parsing from strings functions. Entities processing - modified again, but PERef are still not handled correcly but + modified again, but PERef are still not handled correctly but unless you're Eve Maller you won't notice :-) * HTMLparser.c: large changes toward reliability, and switched to lowercase internal tags, XHTML is lowercase, so it will help @@ -19042,8 +19042,8 @@ Mon Oct 25 12:13:25 CEST 1999 Daniel Veillard a new release out * HTMLparser.c: fixed auto-close bugs on list items, zeroing some structures, comments before and after the - main element, and other nastyness - * HTMLtree.c tree.c: accomodate the extended HTML supported + main element, and other nastiness + * HTMLtree.c tree.c: accommodate the extended HTML supported * configure.in: pushing 1.7.4 * test/ent8 and related outputs : added a new test for bug #2784 * test/HTML/wired.html and related output: a nasty HTML example @@ -19450,7 +19450,7 @@ Sun Jan 31 22:06:48 CET 1999 Daniel Veillard * valid.[ch], tree.c, parser.c : more work toward full parsing of XML DTDs. - * README: added informations about mailing-list and on-line + * README: added information about mailing-list and on-line documentation 1999-01-27 Raja R Harinath @@ -19535,7 +19535,7 @@ Thu Oct 29 00:48:45 EST 1998 Daniel Veillard Wed Oct 28 17:56:35 EST 1998 Daniel Veillard - * tree.[ch]: more cleanup on the API, made the tree mor conformant. + * tree.[ch]: more cleanup on the API, made the tree more conformant. Tue Oct 27 17:54:00 EST 1998 Daniel Veillard @@ -19594,7 +19594,7 @@ Sat Oct 17 02:43:21 EDT 1998 Daniel Veillard Tue Oct 13 21:46:57 EDT 1998 Daniel Veillard * tree.h, tree.c, parser.c: added prev and doc pointers to Node, - and changed NODEs contants for conformity with DOM Level 1 + and changed NODEs constants for conformity with DOM Level 1 Wed Oct 7 23:42:46 EDT 1998 Daniel Veillard @@ -19631,7 +19631,7 @@ Mon Sep 21 20:11:13 EDT 1998 Daniel Veillard 1998-08-20 Raja R Harinath - * error.h: New file. Contains prototyes from `error.c'. + * error.h: New file. Contains prototypes from `error.c'. Thu Aug 13 19:02:34 1998 Tom Tromey @@ -19662,13 +19662,13 @@ Sun Jul 26 17:29:52 EDT 1998 Daniel Veillard Sun Jul 26 00:17:51 EDT 1998 Daniel Veillard * configure.in: added test for CPP - * AUTHORS, Changelog: the original ones didn't get commited but the + * AUTHORS, Changelog: the original ones didn't get committed but the glib ones instead, fixed. * Makefile.am: corrected an error in library naming Fri Jul 24 16:47:14 1998 Daniel Veillard - * integrated code developped at W3C + * integrated code developed at W3C * changed the original Copyright * migrated to automake * prefixed the filenames by xml_ to avoid filename clashes diff --git a/sdk/lib/3rdparty/libxml2/HTMLparser.c b/sdk/lib/3rdparty/libxml2/HTMLparser.c index 7b6d68961c4..b56363a3a03 100644 --- a/sdk/lib/3rdparty/libxml2/HTMLparser.c +++ b/sdk/lib/3rdparty/libxml2/HTMLparser.c @@ -69,7 +69,7 @@ static void htmlParseComment(htmlParserCtxtPtr ctxt); /** * htmlErrMemory: * @ctxt: an HTML parser context - * @extra: extra informations + * @extra: extra information * * Handle a redefinition of attribute error */ @@ -296,7 +296,7 @@ htmlNodeInfoPop(htmlParserCtxtPtr ctxt) #define UPPER (toupper(*ctxt->input->cur)) -#define SKIP(val) ctxt->nbChars += (val),ctxt->input->cur += (val),ctxt->input->col+=(val) +#define SKIP(val) ctxt->input->cur += (val),ctxt->input->col+=(val) #define NXT(val) ctxt->input->cur[(val)] @@ -330,7 +330,7 @@ htmlNodeInfoPop(htmlParserCtxtPtr ctxt) if (*(ctxt->input->cur) == '\n') { \ ctxt->input->line++; ctxt->input->col = 1; \ } else ctxt->input->col++; \ - ctxt->token = 0; ctxt->input->cur += l; ctxt->nbChars++; \ + ctxt->token = 0; ctxt->input->cur += l; \ } while (0) /************ @@ -414,6 +414,10 @@ htmlFindEncoding(xmlParserCtxtPtr ctxt) { static int htmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) { + const unsigned char *cur; + unsigned char c; + unsigned int val; + if (ctxt->instate == XML_PARSER_EOF) return(0); @@ -421,99 +425,29 @@ htmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) { *len = 0; return(ctxt->token); } - if (ctxt->charset == XML_CHAR_ENCODING_UTF8) { - /* - * We are supposed to handle UTF8, check it's valid - * From rfc2044: encoding of the Unicode values on UTF-8: - * - * UCS-4 range (hex.) UTF-8 octet sequence (binary) - * 0000 0000-0000 007F 0xxxxxxx - * 0000 0080-0000 07FF 110xxxxx 10xxxxxx - * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx - * - * Check for the 0x110000 limit too - */ - const unsigned char *cur = ctxt->input->cur; - unsigned char c; - unsigned int val; - - c = *cur; - if (c & 0x80) { - if (cur[1] == 0) { - xmlParserInputGrow(ctxt->input, INPUT_CHUNK); - cur = ctxt->input->cur; - } - if ((cur[1] & 0xc0) != 0x80) - goto encoding_error; - if ((c & 0xe0) == 0xe0) { - - if (cur[2] == 0) { - xmlParserInputGrow(ctxt->input, INPUT_CHUNK); - cur = ctxt->input->cur; - } - if ((cur[2] & 0xc0) != 0x80) - goto encoding_error; - if ((c & 0xf0) == 0xf0) { - if (cur[3] == 0) { - xmlParserInputGrow(ctxt->input, INPUT_CHUNK); - cur = ctxt->input->cur; - } - if (((c & 0xf8) != 0xf0) || - ((cur[3] & 0xc0) != 0x80)) - goto encoding_error; - /* 4-byte code */ - *len = 4; - val = (cur[0] & 0x7) << 18; - val |= (cur[1] & 0x3f) << 12; - val |= (cur[2] & 0x3f) << 6; - val |= cur[3] & 0x3f; - } else { - /* 3-byte code */ - *len = 3; - val = (cur[0] & 0xf) << 12; - val |= (cur[1] & 0x3f) << 6; - val |= cur[2] & 0x3f; - } - } else { - /* 2-byte code */ - *len = 2; - val = (cur[0] & 0x1f) << 6; - val |= cur[1] & 0x3f; - } - if (!IS_CHAR(val)) { - htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR, - "Char 0x%X out of allowed range\n", val); - } - return(val); - } else { - if ((*ctxt->input->cur == 0) && - (ctxt->input->cur < ctxt->input->end)) { - htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR, - "Char 0x%X out of allowed range\n", 0); - *len = 1; - return(' '); - } - /* 1-byte code */ - *len = 1; - return((int) *ctxt->input->cur); - } - } - /* - * Assume it's a fixed length encoding (1) with - * a compatible encoding for the ASCII set, since - * XML constructs only use < 128 chars - */ - *len = 1; - if ((int) *ctxt->input->cur < 0x80) - return((int) *ctxt->input->cur); - - /* - * Humm this is bad, do an automatic flow conversion - */ - { + if (ctxt->charset != XML_CHAR_ENCODING_UTF8) { xmlChar * guess; xmlCharEncodingHandlerPtr handler; + /* + * Assume it's a fixed length encoding (1) with + * a compatible encoding for the ASCII set, since + * HTML constructs only use < 128 chars + */ + if ((int) *ctxt->input->cur < 0x80) { + *len = 1; + if ((*ctxt->input->cur == 0) && + (ctxt->input->cur < ctxt->input->end)) { + htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR, + "Char 0x%X out of allowed range\n", 0); + return(' '); + } + return((int) *ctxt->input->cur); + } + + /* + * Humm this is bad, do an automatic flow conversion + */ guess = htmlFindEncoding(ctxt); if (guess == NULL) { xmlSwitchEncoding(ctxt, XML_CHAR_ENCODING_8859_1); @@ -523,7 +457,12 @@ htmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) { ctxt->input->encoding = guess; handler = xmlFindCharEncodingHandler((const char *) guess); if (handler != NULL) { - xmlSwitchToEncoding(ctxt, handler); + /* + * Don't use UTF-8 encoder which isn't required and + * can produce invalid UTF-8. + */ + if (!xmlStrEqual(BAD_CAST handler->name, BAD_CAST "UTF-8")) + xmlSwitchToEncoding(ctxt, handler); } else { htmlParseErr(ctxt, XML_ERR_INVALID_ENCODING, "Unsupported encoding %s", guess, NULL); @@ -532,7 +471,86 @@ htmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) { ctxt->charset = XML_CHAR_ENCODING_UTF8; } - return(xmlCurrentChar(ctxt, len)); + /* + * We are supposed to handle UTF8, check it's valid + * From rfc2044: encoding of the Unicode values on UTF-8: + * + * UCS-4 range (hex.) UTF-8 octet sequence (binary) + * 0000 0000-0000 007F 0xxxxxxx + * 0000 0080-0000 07FF 110xxxxx 10xxxxxx + * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx + * + * Check for the 0x110000 limit too + */ + cur = ctxt->input->cur; + c = *cur; + if (c & 0x80) { + if ((c & 0x40) == 0) + goto encoding_error; + if (cur[1] == 0) { + xmlParserInputGrow(ctxt->input, INPUT_CHUNK); + cur = ctxt->input->cur; + } + if ((cur[1] & 0xc0) != 0x80) + goto encoding_error; + if ((c & 0xe0) == 0xe0) { + + if (cur[2] == 0) { + xmlParserInputGrow(ctxt->input, INPUT_CHUNK); + cur = ctxt->input->cur; + } + if ((cur[2] & 0xc0) != 0x80) + goto encoding_error; + if ((c & 0xf0) == 0xf0) { + if (cur[3] == 0) { + xmlParserInputGrow(ctxt->input, INPUT_CHUNK); + cur = ctxt->input->cur; + } + if (((c & 0xf8) != 0xf0) || + ((cur[3] & 0xc0) != 0x80)) + goto encoding_error; + /* 4-byte code */ + *len = 4; + val = (cur[0] & 0x7) << 18; + val |= (cur[1] & 0x3f) << 12; + val |= (cur[2] & 0x3f) << 6; + val |= cur[3] & 0x3f; + if (val < 0x10000) + goto encoding_error; + } else { + /* 3-byte code */ + *len = 3; + val = (cur[0] & 0xf) << 12; + val |= (cur[1] & 0x3f) << 6; + val |= cur[2] & 0x3f; + if (val < 0x800) + goto encoding_error; + } + } else { + /* 2-byte code */ + *len = 2; + val = (cur[0] & 0x1f) << 6; + val |= cur[1] & 0x3f; + if (val < 0x80) + goto encoding_error; + } + if (!IS_CHAR(val)) { + htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR, + "Char 0x%X out of allowed range\n", val); + } + return(val); + } else { + if ((*ctxt->input->cur == 0) && + (ctxt->input->cur < ctxt->input->end)) { + htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR, + "Char 0x%X out of allowed range\n", 0); + *len = 1; + return(' '); + } + /* 1-byte code */ + *len = 1; + return((int) *ctxt->input->cur); + } encoding_error: /* @@ -557,7 +575,16 @@ encoding_error: BAD_CAST buffer, NULL); } - ctxt->charset = XML_CHAR_ENCODING_8859_1; + /* + * Don't switch encodings twice. Note that if there's an encoder, we + * shouldn't receive invalid UTF-8 anyway. + * + * Note that if ctxt->input->buf == NULL, switching encodings is + * impossible, see Gitlab issue #34. + */ + if ((ctxt->input->buf != NULL) && + (ctxt->input->buf->encoder == NULL)) + xmlSwitchEncoding(ctxt, XML_CHAR_ENCODING_8859_1); *len = 1; return((int) *ctxt->input->cur); } @@ -584,7 +611,6 @@ htmlSkipBlankChars(xmlParserCtxtPtr ctxt) { ctxt->input->line++; ctxt->input->col = 1; } else ctxt->input->col++; ctxt->input->cur++; - ctxt->nbChars++; if (*ctxt->input->cur == 0) xmlParserInputGrow(ctxt->input, INPUT_CHUNK); } @@ -1046,102 +1072,266 @@ html40ElementTable[] = { } }; +typedef struct { + const char *oldTag; + const char *newTag; +} htmlStartCloseEntry; + /* * start tags that imply the end of current element */ -static const char * const htmlStartClose[] = { -"form", "form", "p", "hr", "h1", "h2", "h3", "h4", "h5", "h6", - "dl", "ul", "ol", "menu", "dir", "address", "pre", - "listing", "xmp", "head", NULL, -"head", "p", NULL, -"title", "p", NULL, -"body", "head", "style", "link", "title", "p", NULL, -"frameset", "head", "style", "link", "title", "p", NULL, -"li", "p", "h1", "h2", "h3", "h4", "h5", "h6", "dl", "address", - "pre", "listing", "xmp", "head", "li", NULL, -"hr", "p", "head", NULL, -"h1", "p", "head", NULL, -"h2", "p", "head", NULL, -"h3", "p", "head", NULL, -"h4", "p", "head", NULL, -"h5", "p", "head", NULL, -"h6", "p", "head", NULL, -"dir", "p", "head", NULL, -"address", "p", "head", "ul", NULL, -"pre", "p", "head", "ul", NULL, -"listing", "p", "head", NULL, -"xmp", "p", "head", NULL, -"blockquote", "p", "head", NULL, -"dl", "p", "dt", "menu", "dir", "address", "pre", "listing", - "xmp", "head", NULL, -"dt", "p", "menu", "dir", "address", "pre", "listing", "xmp", - "head", "dd", NULL, -"dd", "p", "menu", "dir", "address", "pre", "listing", "xmp", - "head", "dt", NULL, -"ul", "p", "head", "ol", "menu", "dir", "address", "pre", - "listing", "xmp", NULL, -"ol", "p", "head", "ul", NULL, -"menu", "p", "head", "ul", NULL, -"p", "p", "head", "h1", "h2", "h3", "h4", "h5", "h6", FONTSTYLE, NULL, -"div", "p", "head", NULL, -"noscript", "script", NULL, -"center", "font", "b", "i", "p", "head", NULL, -"a", "a", "head", NULL, -"caption", "p", NULL, -"colgroup", "caption", "colgroup", "col", "p", NULL, -"col", "caption", "col", "p", NULL, -"table", "p", "head", "h1", "h2", "h3", "h4", "h5", "h6", "pre", - "listing", "xmp", "a", NULL, -"th", "th", "td", "p", "span", "font", "a", "b", "i", "u", NULL, -"td", "th", "td", "p", "span", "font", "a", "b", "i", "u", NULL, -"tr", "th", "td", "tr", "caption", "col", "colgroup", "p", NULL, -"thead", "caption", "col", "colgroup", NULL, -"tfoot", "th", "td", "tr", "caption", "col", "colgroup", "thead", - "tbody", "p", NULL, -"tbody", "th", "td", "tr", "caption", "col", "colgroup", "thead", - "tfoot", "tbody", "p", NULL, -"optgroup", "option", NULL, -"option", "option", NULL, -"fieldset", "legend", "p", "head", "h1", "h2", "h3", "h4", "h5", "h6", - "pre", "listing", "xmp", "a", NULL, -/* most tags in in FONTSTYLE, PHRASE and SPECIAL should close */ -"tt", "head", NULL, -"i", "head", NULL, -"b", "head", NULL, -"u", "head", NULL, -"s", "head", NULL, -"strike", "head", NULL, -"big", "head", NULL, -"small", "head", NULL, - -"em", "head", NULL, -"strong", "head", NULL, -"dfn", "head", NULL, -"code", "head", NULL, -"samp", "head", NULL, -"kbd", "head", NULL, -"var", "head", NULL, -"cite", "head", NULL, -"abbr", "head", NULL, -"acronym", "head", NULL, - -/* "a" */ -"img", "head", NULL, -/* "applet" */ -/* "embed" */ -/* "object" */ -"font", "head", NULL, -/* "basefont" */ -"br", "head", NULL, -/* "script" */ -"map", "head", NULL, -"q", "head", NULL, -"sub", "head", NULL, -"sup", "head", NULL, -"span", "head", NULL, -"bdo", "head", NULL, -"iframe", "head", NULL, -NULL +static const htmlStartCloseEntry htmlStartClose[] = { + { "a", "a" }, + { "a", "fieldset" }, + { "a", "table" }, + { "a", "td" }, + { "a", "th" }, + { "address", "dd" }, + { "address", "dl" }, + { "address", "dt" }, + { "address", "form" }, + { "address", "li" }, + { "address", "ul" }, + { "b", "center" }, + { "b", "p" }, + { "b", "td" }, + { "b", "th" }, + { "big", "p" }, + { "caption", "col" }, + { "caption", "colgroup" }, + { "caption", "tbody" }, + { "caption", "tfoot" }, + { "caption", "thead" }, + { "caption", "tr" }, + { "col", "col" }, + { "col", "colgroup" }, + { "col", "tbody" }, + { "col", "tfoot" }, + { "col", "thead" }, + { "col", "tr" }, + { "colgroup", "colgroup" }, + { "colgroup", "tbody" }, + { "colgroup", "tfoot" }, + { "colgroup", "thead" }, + { "colgroup", "tr" }, + { "dd", "dt" }, + { "dir", "dd" }, + { "dir", "dl" }, + { "dir", "dt" }, + { "dir", "form" }, + { "dir", "ul" }, + { "dl", "form" }, + { "dl", "li" }, + { "dt", "dd" }, + { "dt", "dl" }, + { "font", "center" }, + { "font", "td" }, + { "font", "th" }, + { "form", "form" }, + { "h1", "fieldset" }, + { "h1", "form" }, + { "h1", "li" }, + { "h1", "p" }, + { "h1", "table" }, + { "h2", "fieldset" }, + { "h2", "form" }, + { "h2", "li" }, + { "h2", "p" }, + { "h2", "table" }, + { "h3", "fieldset" }, + { "h3", "form" }, + { "h3", "li" }, + { "h3", "p" }, + { "h3", "table" }, + { "h4", "fieldset" }, + { "h4", "form" }, + { "h4", "li" }, + { "h4", "p" }, + { "h4", "table" }, + { "h5", "fieldset" }, + { "h5", "form" }, + { "h5", "li" }, + { "h5", "p" }, + { "h5", "table" }, + { "h6", "fieldset" }, + { "h6", "form" }, + { "h6", "li" }, + { "h6", "p" }, + { "h6", "table" }, + { "head", "a" }, + { "head", "abbr" }, + { "head", "acronym" }, + { "head", "address" }, + { "head", "b" }, + { "head", "bdo" }, + { "head", "big" }, + { "head", "blockquote" }, + { "head", "body" }, + { "head", "br" }, + { "head", "center" }, + { "head", "cite" }, + { "head", "code" }, + { "head", "dd" }, + { "head", "dfn" }, + { "head", "dir" }, + { "head", "div" }, + { "head", "dl" }, + { "head", "dt" }, + { "head", "em" }, + { "head", "fieldset" }, + { "head", "font" }, + { "head", "form" }, + { "head", "frameset" }, + { "head", "h1" }, + { "head", "h2" }, + { "head", "h3" }, + { "head", "h4" }, + { "head", "h5" }, + { "head", "h6" }, + { "head", "hr" }, + { "head", "i" }, + { "head", "iframe" }, + { "head", "img" }, + { "head", "kbd" }, + { "head", "li" }, + { "head", "listing" }, + { "head", "map" }, + { "head", "menu" }, + { "head", "ol" }, + { "head", "p" }, + { "head", "pre" }, + { "head", "q" }, + { "head", "s" }, + { "head", "samp" }, + { "head", "small" }, + { "head", "span" }, + { "head", "strike" }, + { "head", "strong" }, + { "head", "sub" }, + { "head", "sup" }, + { "head", "table" }, + { "head", "tt" }, + { "head", "u" }, + { "head", "ul" }, + { "head", "var" }, + { "head", "xmp" }, + { "hr", "form" }, + { "i", "center" }, + { "i", "p" }, + { "i", "td" }, + { "i", "th" }, + { "legend", "fieldset" }, + { "li", "li" }, + { "link", "body" }, + { "link", "frameset" }, + { "listing", "dd" }, + { "listing", "dl" }, + { "listing", "dt" }, + { "listing", "fieldset" }, + { "listing", "form" }, + { "listing", "li" }, + { "listing", "table" }, + { "listing", "ul" }, + { "menu", "dd" }, + { "menu", "dl" }, + { "menu", "dt" }, + { "menu", "form" }, + { "menu", "ul" }, + { "ol", "form" }, + { "ol", "ul" }, + { "option", "optgroup" }, + { "option", "option" }, + { "p", "address" }, + { "p", "blockquote" }, + { "p", "body" }, + { "p", "caption" }, + { "p", "center" }, + { "p", "col" }, + { "p", "colgroup" }, + { "p", "dd" }, + { "p", "dir" }, + { "p", "div" }, + { "p", "dl" }, + { "p", "dt" }, + { "p", "fieldset" }, + { "p", "form" }, + { "p", "frameset" }, + { "p", "h1" }, + { "p", "h2" }, + { "p", "h3" }, + { "p", "h4" }, + { "p", "h5" }, + { "p", "h6" }, + { "p", "head" }, + { "p", "hr" }, + { "p", "li" }, + { "p", "listing" }, + { "p", "menu" }, + { "p", "ol" }, + { "p", "p" }, + { "p", "pre" }, + { "p", "table" }, + { "p", "tbody" }, + { "p", "td" }, + { "p", "tfoot" }, + { "p", "th" }, + { "p", "title" }, + { "p", "tr" }, + { "p", "ul" }, + { "p", "xmp" }, + { "pre", "dd" }, + { "pre", "dl" }, + { "pre", "dt" }, + { "pre", "fieldset" }, + { "pre", "form" }, + { "pre", "li" }, + { "pre", "table" }, + { "pre", "ul" }, + { "s", "p" }, + { "script", "noscript" }, + { "small", "p" }, + { "span", "td" }, + { "span", "th" }, + { "strike", "p" }, + { "style", "body" }, + { "style", "frameset" }, + { "tbody", "tbody" }, + { "tbody", "tfoot" }, + { "td", "tbody" }, + { "td", "td" }, + { "td", "tfoot" }, + { "td", "th" }, + { "td", "tr" }, + { "tfoot", "tbody" }, + { "th", "tbody" }, + { "th", "td" }, + { "th", "tfoot" }, + { "th", "th" }, + { "th", "tr" }, + { "thead", "tbody" }, + { "thead", "tfoot" }, + { "title", "body" }, + { "title", "frameset" }, + { "tr", "tbody" }, + { "tr", "tfoot" }, + { "tr", "tr" }, + { "tt", "p" }, + { "u", "p" }, + { "u", "td" }, + { "u", "th" }, + { "ul", "address" }, + { "ul", "form" }, + { "ul", "menu" }, + { "ul", "ol" }, + { "ul", "pre" }, + { "xmp", "dd" }, + { "xmp", "dl" }, + { "xmp", "dt" }, + { "xmp", "fieldset" }, + { "xmp", "form" }, + { "xmp", "li" }, + { "xmp", "table" }, + { "xmp", "ul" } }; /* @@ -1211,9 +1401,6 @@ static const elementPriority htmlEndPriority[] = { {NULL, 100} /* Default priority */ }; -static const char** htmlStartCloseIndex[100]; -static int htmlStartCloseIndexinitialized = 0; - /************************************************************************ * * * functions to handle HTML specific data * @@ -1223,24 +1410,18 @@ static int htmlStartCloseIndexinitialized = 0; /** * htmlInitAutoClose: * - * Initialize the htmlStartCloseIndex for fast lookup of closing tags names. - * This is not reentrant. Call xmlInitParser() once before processing in - * case of use in multithreaded programs. + * This is a no-op now. */ void htmlInitAutoClose(void) { - int indx, i = 0; +} - if (htmlStartCloseIndexinitialized) return; +static int +htmlCompareTags(const void *key, const void *member) { + const xmlChar *tag = (const xmlChar *) key; + const htmlElemDesc *desc = (const htmlElemDesc *) member; - for (indx = 0;indx < 100;indx ++) htmlStartCloseIndex[indx] = NULL; - indx = 0; - while ((htmlStartClose[i] != NULL) && (indx < 100 - 1)) { - htmlStartCloseIndex[indx++] = (const char**) &htmlStartClose[i]; - while (htmlStartClose[i] != NULL) i++; - i++; - } - htmlStartCloseIndexinitialized = 1; + return(xmlStrcasecmp(tag, BAD_CAST desc->name)); } /** @@ -1253,14 +1434,12 @@ htmlInitAutoClose(void) { */ const htmlElemDesc * htmlTagLookup(const xmlChar *tag) { - unsigned int i; + if (tag == NULL) + return(NULL); - for (i = 0; i < (sizeof(html40ElementTable) / - sizeof(html40ElementTable[0]));i++) { - if (!xmlStrcasecmp(tag, BAD_CAST html40ElementTable[i].name)) - return((htmlElemDescPtr) &html40ElementTable[i]); - } - return(NULL); + return((const htmlElemDesc *) bsearch(tag, html40ElementTable, + sizeof(html40ElementTable) / sizeof(htmlElemDesc), + sizeof(htmlElemDesc), htmlCompareTags)); } /** @@ -1281,6 +1460,19 @@ htmlGetEndPriority (const xmlChar *name) { } +static int +htmlCompareStartClose(const void *vkey, const void *member) { + const htmlStartCloseEntry *key = (const htmlStartCloseEntry *) vkey; + const htmlStartCloseEntry *entry = (const htmlStartCloseEntry *) member; + int ret; + + ret = strcmp(key->oldTag, entry->oldTag); + if (ret == 0) + ret = strcmp(key->newTag, entry->newTag); + + return(ret); +} + /** * htmlCheckAutoClose: * @newtag: The new tag name @@ -1288,37 +1480,21 @@ htmlGetEndPriority (const xmlChar *name) { * * Checks whether the new tag is one of the registered valid tags for * closing old. - * Initialize the htmlStartCloseIndex for fast lookup of closing tags names. * * Returns 0 if no, 1 if yes. */ static int htmlCheckAutoClose(const xmlChar * newtag, const xmlChar * oldtag) { - int i, indx; - const char **closed = NULL; + htmlStartCloseEntry key; + void *res; - if (htmlStartCloseIndexinitialized == 0) - htmlInitAutoClose(); - - /* inefficient, but not a big deal */ - for (indx = 0; indx < 100; indx++) { - closed = htmlStartCloseIndex[indx]; - if (closed == NULL) - return (0); - if (xmlStrEqual(BAD_CAST * closed, newtag)) - break; - } - - i = closed - htmlStartClose; - i++; - while (htmlStartClose[i] != NULL) { - if (xmlStrEqual(BAD_CAST htmlStartClose[i], oldtag)) { - return (1); - } - i++; - } - return (0); + key.oldTag = (const char *) oldtag; + key.newTag = (const char *) newtag; + res = bsearch(&key, htmlStartClose, + sizeof(htmlStartClose) / sizeof(htmlStartCloseEntry), + sizeof(htmlStartCloseEntry), htmlCompareStartClose); + return(res != NULL); } /** @@ -2482,7 +2658,6 @@ htmlParseName(htmlParserCtxtPtr ctxt) { count = in - ctxt->input->cur; ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count); ctxt->input->cur = in; - ctxt->nbChars += count; ctxt->input->col += count; return(ret); } @@ -2789,47 +2964,39 @@ htmlParseAttValue(htmlParserCtxtPtr ctxt) { static xmlChar * htmlParseSystemLiteral(htmlParserCtxtPtr ctxt) { size_t len = 0, startPosition = 0; + int err = 0; + int quote; xmlChar *ret = NULL; - if (CUR == '"') { - NEXT; - - if (CUR_PTR < BASE_PTR) - return(ret); - startPosition = CUR_PTR - BASE_PTR; - - while ((IS_CHAR_CH(CUR)) && (CUR != '"')) { - NEXT; - len++; - } - if (!IS_CHAR_CH(CUR)) { - htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, - "Unfinished SystemLiteral\n", NULL, NULL); - } else { - ret = xmlStrndup((BASE_PTR+startPosition), len); - NEXT; - } - } else if (CUR == '\'') { - NEXT; - - if (CUR_PTR < BASE_PTR) - return(ret); - startPosition = CUR_PTR - BASE_PTR; - - while ((IS_CHAR_CH(CUR)) && (CUR != '\'')) { - NEXT; - len++; - } - if (!IS_CHAR_CH(CUR)) { - htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, - "Unfinished SystemLiteral\n", NULL, NULL); - } else { - ret = xmlStrndup((BASE_PTR+startPosition), len); - NEXT; - } - } else { + if ((CUR != '"') && (CUR != '\'')) { htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, - " or ' expected\n", NULL, NULL); + "SystemLiteral \" or ' expected\n", NULL, NULL); + return(NULL); + } + quote = CUR; + NEXT; + + if (CUR_PTR < BASE_PTR) + return(ret); + startPosition = CUR_PTR - BASE_PTR; + + while ((CUR != 0) && (CUR != quote)) { + /* TODO: Handle UTF-8 */ + if (!IS_CHAR_CH(CUR)) { + htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR, + "Invalid char in SystemLiteral 0x%X\n", CUR); + err = 1; + } + NEXT; + len++; + } + if (CUR != quote) { + htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, + "Unfinished SystemLiteral\n", NULL, NULL); + } else { + NEXT; + if (err == 0) + ret = xmlStrndup((BASE_PTR+startPosition), len); } return(ret); @@ -2849,51 +3016,42 @@ htmlParseSystemLiteral(htmlParserCtxtPtr ctxt) { static xmlChar * htmlParsePubidLiteral(htmlParserCtxtPtr ctxt) { size_t len = 0, startPosition = 0; + int err = 0; + int quote; xmlChar *ret = NULL; + + if ((CUR != '"') && (CUR != '\'')) { + htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, + "PubidLiteral \" or ' expected\n", NULL, NULL); + return(NULL); + } + quote = CUR; + NEXT; + /* * Name ::= (Letter | '_') (NameChar)* */ - if (CUR == '"') { - NEXT; + if (CUR_PTR < BASE_PTR) + return(ret); + startPosition = CUR_PTR - BASE_PTR; - if (CUR_PTR < BASE_PTR) - return(ret); - startPosition = CUR_PTR - BASE_PTR; - - while (IS_PUBIDCHAR_CH(CUR)) { - len++; - NEXT; + while ((CUR != 0) && (CUR != quote)) { + if (!IS_PUBIDCHAR_CH(CUR)) { + htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR, + "Invalid char in PubidLiteral 0x%X\n", CUR); + err = 1; } - - if (CUR != '"') { - htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, - "Unfinished PubidLiteral\n", NULL, NULL); - } else { - ret = xmlStrndup((BASE_PTR + startPosition), len); - NEXT; - } - } else if (CUR == '\'') { + len++; NEXT; + } - if (CUR_PTR < BASE_PTR) - return(ret); - startPosition = CUR_PTR - BASE_PTR; - - while ((IS_PUBIDCHAR_CH(CUR)) && (CUR != '\'')){ - len++; - NEXT; - } - - if (CUR != '\'') { - htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, - "Unfinished PubidLiteral\n", NULL, NULL); - } else { - ret = xmlStrndup((BASE_PTR + startPosition), len); - NEXT; - } + if (CUR != '"') { + htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, + "Unfinished PubidLiteral\n", NULL, NULL); } else { - htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, - "PubidLiteral \" or ' expected\n", NULL, NULL); + NEXT; + if (err == 0) + ret = xmlStrndup((BASE_PTR + startPosition), len); } return(ret); @@ -2928,7 +3086,7 @@ htmlParseScript(htmlParserCtxtPtr ctxt) { SHRINK; cur = CUR_CHAR(l); - while (IS_CHAR_CH(cur)) { + while (cur != 0) { if ((cur == '<') && (NXT(1) == '/')) { /* * One should break here, the specification is clear: @@ -2959,7 +3117,12 @@ htmlParseScript(htmlParserCtxtPtr ctxt) { } } } - COPY_BUF(l,buf,nbchar,cur); + if (IS_CHAR(cur)) { + COPY_BUF(l,buf,nbchar,cur); + } else { + htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR, + "Invalid char in CDATA 0x%X\n", cur); + } if (nbchar >= HTML_PARSER_BIG_BUFFER_SIZE) { buf[nbchar] = 0; if (ctxt->sax->cdataBlock!= NULL) { @@ -2977,14 +3140,6 @@ htmlParseScript(htmlParserCtxtPtr ctxt) { cur = CUR_CHAR(l); } - if ((!(IS_CHAR_CH(cur))) && (!((cur == 0) && (ctxt->progressive)))) { - htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR, - "Invalid char in CDATA 0x%X\n", cur); - if (ctxt->input->cur < ctxt->input->end) { - NEXT; - } - } - if ((nbchar != 0) && (ctxt->sax != NULL) && (!ctxt->disableSAX)) { buf[nbchar] = 0; if (ctxt->sax->cdataBlock!= NULL) { @@ -3232,7 +3387,7 @@ htmlParsePI(htmlParserCtxtPtr ctxt) { } SKIP_BLANKS; cur = CUR_CHAR(l); - while (IS_CHAR(cur) && (cur != '>')) { + while ((cur != 0) && (cur != '>')) { if (len + 5 >= size) { xmlChar *tmp; @@ -3251,7 +3406,13 @@ htmlParsePI(htmlParserCtxtPtr ctxt) { GROW; count = 0; } - COPY_BUF(l,buf,len,cur); + if (IS_CHAR(cur)) { + COPY_BUF(l,buf,len,cur); + } else { + htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR, + "Invalid char in processing instruction " + "0x%X\n", cur); + } NEXTL(l); cur = CUR_CHAR(l); if (cur == 0) { @@ -3300,6 +3461,7 @@ htmlParseComment(htmlParserCtxtPtr ctxt) { int q, ql; int r, rl; int cur, l; + int next, nl; xmlParserInputState state; /* @@ -3321,17 +3483,32 @@ htmlParseComment(htmlParserCtxtPtr ctxt) { len = 0; buf[len] = 0; q = CUR_CHAR(ql); - if (!IS_CHAR(q)) + if (q == 0) goto unfinished; NEXTL(ql); r = CUR_CHAR(rl); - if (!IS_CHAR(r)) + if (r == 0) goto unfinished; NEXTL(rl); cur = CUR_CHAR(l); - while (IS_CHAR(cur) && + while ((cur != 0) && ((cur != '>') || (r != '-') || (q != '-'))) { + NEXTL(l); + next = CUR_CHAR(nl); + if (next == 0) { + SHRINK; + GROW; + next = CUR_CHAR(nl); + } + + if ((q == '-') && (r == '-') && (cur == '!') && (next == '>')) { + htmlParseErr(ctxt, XML_ERR_COMMENT_NOT_FINISHED, + "Comment incorrectly closed by '--!>'", NULL, NULL); + cur = '>'; + break; + } + if (len + 5 >= size) { xmlChar *tmp; @@ -3345,21 +3522,22 @@ htmlParseComment(htmlParserCtxtPtr ctxt) { } buf = tmp; } - COPY_BUF(ql,buf,len,q); + if (IS_CHAR(q)) { + COPY_BUF(ql,buf,len,q); + } else { + htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR, + "Invalid char in comment 0x%X\n", q); + } + q = r; ql = rl; r = cur; rl = l; - NEXTL(l); - cur = CUR_CHAR(l); - if (cur == 0) { - SHRINK; - GROW; - cur = CUR_CHAR(l); - } + cur = next; + l = nl; } buf[len] = 0; - if (IS_CHAR(cur)) { + if (cur == '>') { NEXT; if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) && (!ctxt->disableSAX)) @@ -3400,13 +3578,16 @@ htmlParseCharRef(htmlParserCtxtPtr ctxt) { ((NXT(2) == 'x') || NXT(2) == 'X')) { SKIP(3); while (CUR != ';') { - if ((CUR >= '0') && (CUR <= '9')) - val = val * 16 + (CUR - '0'); - else if ((CUR >= 'a') && (CUR <= 'f')) - val = val * 16 + (CUR - 'a') + 10; - else if ((CUR >= 'A') && (CUR <= 'F')) - val = val * 16 + (CUR - 'A') + 10; - else { + if ((CUR >= '0') && (CUR <= '9')) { + if (val < 0x110000) + val = val * 16 + (CUR - '0'); + } else if ((CUR >= 'a') && (CUR <= 'f')) { + if (val < 0x110000) + val = val * 16 + (CUR - 'a') + 10; + } else if ((CUR >= 'A') && (CUR <= 'F')) { + if (val < 0x110000) + val = val * 16 + (CUR - 'A') + 10; + } else { htmlParseErr(ctxt, XML_ERR_INVALID_HEX_CHARREF, "htmlParseCharRef: missing semicolon\n", NULL, NULL); @@ -3419,9 +3600,10 @@ htmlParseCharRef(htmlParserCtxtPtr ctxt) { } else if ((CUR == '&') && (NXT(1) == '#')) { SKIP(2); while (CUR != ';') { - if ((CUR >= '0') && (CUR <= '9')) - val = val * 10 + (CUR - '0'); - else { + if ((CUR >= '0') && (CUR <= '9')) { + if (val < 0x110000) + val = val * 10 + (CUR - '0'); + } else { htmlParseErr(ctxt, XML_ERR_INVALID_DEC_CHARREF, "htmlParseCharRef: missing semicolon\n", NULL, NULL); @@ -3440,6 +3622,9 @@ htmlParseCharRef(htmlParserCtxtPtr ctxt) { */ if (IS_CHAR(val)) { return(val); + } else if (val >= 0x110000) { + htmlParseErr(ctxt, XML_ERR_INVALID_CHAR, + "htmlParseCharRef: value too large\n", NULL, NULL); } else { htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR, "htmlParseCharRef: invalid xmlChar value %d\n", @@ -3499,9 +3684,12 @@ htmlParseDocTypeDecl(htmlParserCtxtPtr ctxt) { if (CUR != '>') { htmlParseErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, "DOCTYPE improperly terminated\n", NULL, NULL); - /* We shouldn't try to resynchronize ... */ + /* Ignore bogus content */ + while ((CUR != 0) && (CUR != '>')) + NEXT; } - NEXT; + if (CUR == '>') + NEXT; /* * Create or update the document accordingly to the DOCTYPE @@ -3779,7 +3967,7 @@ htmlParseStartTag(htmlParserCtxtPtr ctxt) { /* Dump the bogus tag like browsers do */ - while ((IS_CHAR_CH(CUR)) && (CUR != '>') && + while ((CUR != 0) && (CUR != '>') && (ctxt->instate != XML_PARSER_EOF)) NEXT; return -1; @@ -3835,11 +4023,9 @@ htmlParseStartTag(htmlParserCtxtPtr ctxt) { * (S Attribute)* S? */ SKIP_BLANKS; - while ((IS_CHAR_CH(CUR)) && + while ((CUR != 0) && (CUR != '>') && ((CUR != '/') || (NXT(1) != '>'))) { - long cons = ctxt->nbChars; - GROW; attname = htmlParseAttribute(ctxt, &attvalue); if (attname != NULL) { @@ -3898,7 +4084,7 @@ htmlParseStartTag(htmlParserCtxtPtr ctxt) { xmlFree(attvalue); /* Dump the bogus attribute string up to the next blank or * the end of the tag. */ - while ((IS_CHAR_CH(CUR)) && + while ((CUR != 0) && !(IS_BLANK_CH(CUR)) && (CUR != '>') && ((CUR != '/') || (NXT(1) != '>'))) NEXT; @@ -3906,12 +4092,6 @@ htmlParseStartTag(htmlParserCtxtPtr ctxt) { failed: SKIP_BLANKS; - if (cons == ctxt->nbChars) { - htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR, - "htmlParseStartTag: problem parsing attributes\n", - NULL, NULL); - break; - } } /* @@ -3979,19 +4159,14 @@ htmlParseEndTag(htmlParserCtxtPtr ctxt) * We should definitely be at the ending "S? '>'" part */ SKIP_BLANKS; - if ((!IS_CHAR_CH(CUR)) || (CUR != '>')) { + if (CUR != '>') { htmlParseErr(ctxt, XML_ERR_GT_REQUIRED, "End tag : expected '>'\n", NULL, NULL); - if (ctxt->recovery) { - /* - * We're not at the ending > !! - * Error, unless in recover mode where we search forwards - * until we find a > - */ - while (CUR != '\0' && CUR != '>') NEXT; - NEXT; - } - } else + /* Skip to next '>' */ + while ((CUR != 0) && (CUR != '>')) + NEXT; + } + if (CUR == '>') NEXT; /* @@ -4032,12 +4207,10 @@ htmlParseEndTag(htmlParserCtxtPtr ctxt) * With the exception that the autoclose may have popped stuff out * of the stack. */ - if (!xmlStrEqual(name, ctxt->name)) { - if ((ctxt->name != NULL) && (!xmlStrEqual(ctxt->name, name))) { - htmlParseErr(ctxt, XML_ERR_TAG_NAME_MISMATCH, - "Opening and ending tag mismatch: %s and %s\n", - name, ctxt->name); - } + if ((ctxt->name != NULL) && (!xmlStrEqual(ctxt->name, name))) { + htmlParseErr(ctxt, XML_ERR_TAG_NAME_MISMATCH, + "Opening and ending tag mismatch: %s and %s\n", + name, ctxt->name); } /* @@ -4152,8 +4325,6 @@ htmlParseContent(htmlParserCtxtPtr ctxt) { currentNode = xmlStrdup(ctxt->name); depth = ctxt->nameNr; while (1) { - long cons = ctxt->nbChars; - GROW; if (ctxt->instate == XML_PARSER_EOF) @@ -4181,7 +4352,7 @@ htmlParseContent(htmlParserCtxtPtr ctxt) { "htmlParseStartTag: invalid element name\n", NULL, NULL); /* Dump the bogus tag like browsers do */ - while ((IS_CHAR_CH(CUR)) && (CUR != '>')) + while ((CUR != 0) && (CUR != '>')) NEXT; if (currentNode != NULL) @@ -4273,15 +4444,6 @@ htmlParseContent(htmlParserCtxtPtr ctxt) { else { htmlParseCharData(ctxt); } - - if (cons == ctxt->nbChars) { - if (ctxt->node != NULL) { - htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR, - "detected an error in element content\n", - NULL, NULL); - } - break; - } } GROW; } @@ -4396,7 +4558,7 @@ htmlParseElement(htmlParserCtxtPtr ctxt) { */ currentNode = xmlStrdup(ctxt->name); depth = ctxt->nameNr; - while (IS_CHAR_CH(CUR)) { + while (CUR != 0) { oldptr = ctxt->input->cur; htmlParseContent(ctxt); if (oldptr==ctxt->input->cur) break; @@ -4413,7 +4575,7 @@ htmlParseElement(htmlParserCtxtPtr ctxt) { node_info.node = ctxt->node; xmlParserAddNodeInfo(ctxt, &node_info); } - if (!IS_CHAR_CH(CUR)) { + if (CUR == 0) { htmlAutoCloseOnEnd(ctxt); } @@ -4434,7 +4596,7 @@ htmlParserFinishElementParsing(htmlParserCtxtPtr ctxt) { xmlParserAddNodeInfo(ctxt, ctxt->nodeInfo); htmlNodeInfoPop(ctxt); } - if (!IS_CHAR_CH(CUR)) { + if (CUR == 0) { htmlAutoCloseOnEnd(ctxt); } } @@ -4552,8 +4714,6 @@ htmlParseContentInternal(htmlParserCtxtPtr ctxt) { currentNode = xmlStrdup(ctxt->name); depth = ctxt->nameNr; while (1) { - long cons = ctxt->nbChars; - GROW; if (ctxt->instate == XML_PARSER_EOF) @@ -4583,7 +4743,7 @@ htmlParseContentInternal(htmlParserCtxtPtr ctxt) { "htmlParseStartTag: invalid element name\n", NULL, NULL); /* Dump the bogus tag like browsers do */ - while ((IS_CHAR_CH(CUR)) && (CUR != '>')) + while ((CUR == 0) && (CUR != '>')) NEXT; htmlParserFinishElementParsing(ctxt); @@ -4687,15 +4847,6 @@ htmlParseContentInternal(htmlParserCtxtPtr ctxt) { else { htmlParseCharData(ctxt); } - - if (cons == ctxt->nbChars) { - if (ctxt->node != NULL) { - htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR, - "detected an error in element content\n", - NULL, NULL); - } - break; - } } GROW; } @@ -4959,7 +5110,6 @@ htmlInitParserCtxt(htmlParserCtxtPtr ctxt) ctxt->vctxt.warning = xmlParserValidityWarning; ctxt->record_info = 0; ctxt->validate = 0; - ctxt->nbChars = 0; ctxt->checkIndex = 0; ctxt->catalogs = NULL; xmlInitNodeInfoSeq(&ctxt->node_seq); @@ -5119,7 +5269,7 @@ htmlCreateDocParserCtxt(const xmlChar *cur, const char *encoding) { * @first: the first char to lookup * @next: the next char to lookup or zero * @third: the next char to lookup or zero - * @comment: flag to force checking inside comments + * @ignoreattrval: skip over attribute values * * Try to find if a sequence (first, next, third) or just (first next) or * (first) is available in the input stream. @@ -5133,13 +5283,11 @@ htmlCreateDocParserCtxt(const xmlChar *cur, const char *encoding) { */ static int htmlParseLookupSequence(htmlParserCtxtPtr ctxt, xmlChar first, - xmlChar next, xmlChar third, int iscomment, - int ignoreattrval) + xmlChar next, xmlChar third, int ignoreattrval) { int base, len; htmlParserInputPtr in; const xmlChar *buf; - int incomment = 0; int invalue = 0; char valdellim = 0x0; @@ -5151,8 +5299,11 @@ htmlParseLookupSequence(htmlParserCtxtPtr ctxt, xmlChar first, if (base < 0) return (-1); - if (ctxt->checkIndex > base) + if (ctxt->checkIndex > base) { base = ctxt->checkIndex; + /* Abuse hasPErefs member to restore current state. */ + invalue = ctxt->hasPErefs & 1 ? 1 : 0; + } if (in->buf == NULL) { buf = in->base; @@ -5168,14 +5319,6 @@ htmlParseLookupSequence(htmlParserCtxtPtr ctxt, xmlChar first, else if (next) len--; for (; base < len; base++) { - if ((!incomment) && (base + 4 < len) && (!iscomment)) { - if ((buf[base] == '<') && (buf[base + 1] == '!') && - (buf[base + 2] == '-') && (buf[base + 3] == '-')) { - incomment = 1; - /* do not increment past */ - base += 2; - } - } if (ignoreattrval) { if (buf[base] == '"' || buf[base] == '\'') { if (invalue) { @@ -5192,16 +5335,6 @@ htmlParseLookupSequence(htmlParserCtxtPtr ctxt, xmlChar first, continue; } } - if (incomment) { - if (base + 3 > len) - return (-1); - if ((buf[base] == '-') && (buf[base + 1] == '-') && - (buf[base + 2] == '>')) { - incomment = 0; - base += 2; - } - continue; - } if (buf[base] == first) { if (third != 0) { if ((buf[base + 1] != next) || (buf[base + 2] != third)) @@ -5228,8 +5361,12 @@ htmlParseLookupSequence(htmlParserCtxtPtr ctxt, xmlChar first, return (base - (in->cur - in->base)); } } - if ((!incomment) && (!invalue)) - ctxt->checkIndex = base; + ctxt->checkIndex = base; + /* Abuse hasPErefs member to track current state. */ + if (invalue) + ctxt->hasPErefs |= 1; + else + ctxt->hasPErefs &= ~1; #ifdef DEBUG_PUSH if (next == 0) xmlGenericError(xmlGenericErrorContext, @@ -5246,79 +5383,38 @@ htmlParseLookupSequence(htmlParserCtxtPtr ctxt, xmlChar first, } /** - * htmlParseLookupChars: + * htmlParseLookupCommentEnd: * @ctxt: an HTML parser context - * @stop: Array of chars, which stop the lookup. - * @stopLen: Length of stop-Array * - * Try to find if any char of the stop-Array is available in the input - * stream. + * Try to find a comment end tag in the input stream + * The search includes "-->" as well as WHATWG-recommended incorrectly-closed tags. + * (See https://html.spec.whatwg.org/multipage/parsing.html#parse-error-incorrectly-closed-comment) * This function has a side effect of (possibly) incrementing ctxt->checkIndex * to avoid rescanning sequences of bytes, it DOES change the state of the * parser, do not use liberally. + * This wraps to htmlParseLookupSequence() * - * Returns the index to the current parsing point if a stopChar - * is available, -1 otherwise. + * Returns the index to the current parsing point if the full sequence is available, -1 otherwise. */ static int -htmlParseLookupChars(htmlParserCtxtPtr ctxt, const xmlChar * stop, - int stopLen) +htmlParseLookupCommentEnd(htmlParserCtxtPtr ctxt) { - int base, len; - htmlParserInputPtr in; - const xmlChar *buf; - int incomment = 0; - int i; + int mark = 0; + int cur = CUR_PTR - BASE_PTR; - in = ctxt->input; - if (in == NULL) - return (-1); - - base = in->cur - in->base; - if (base < 0) - return (-1); - - if (ctxt->checkIndex > base) - base = ctxt->checkIndex; - - if (in->buf == NULL) { - buf = in->base; - len = in->length; - } else { - buf = xmlBufContent(in->buf->buffer); - len = xmlBufUse(in->buf->buffer); + while (mark >= 0) { + mark = htmlParseLookupSequence(ctxt, '-', '-', 0, 0); + if ((mark < 0) || + (NXT(mark+2) == '>') || + ((NXT(mark+2) == '!') && (NXT(mark+3) == '>'))) { + return mark; + } + ctxt->checkIndex = cur + mark + 1; } - - for (; base < len; base++) { - if (!incomment && (base + 4 < len)) { - if ((buf[base] == '<') && (buf[base + 1] == '!') && - (buf[base + 2] == '-') && (buf[base + 3] == '-')) { - incomment = 1; - /* do not increment past */ - base += 2; - } - } - if (incomment) { - if (base + 3 > len) - return (-1); - if ((buf[base] == '-') && (buf[base + 1] == '-') && - (buf[base + 2] == '>')) { - incomment = 0; - base += 2; - } - continue; - } - for (i = 0; i < stopLen; ++i) { - if (buf[base] == stop[i]) { - ctxt->checkIndex = 0; - return (base - (in->cur - in->base)); - } - } - } - ctxt->checkIndex = base; - return (-1); + return mark; } + /** * htmlParseTryOrFinish: * @ctxt: an HTML parser context @@ -5332,7 +5428,7 @@ static int htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) { int ret = 0; htmlParserInputPtr in; - int avail = 0; + ptrdiff_t avail = 0; xmlChar cur, next; htmlParserNodeInfo node_info; @@ -5397,7 +5493,8 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) { if (in->buf == NULL) avail = in->length - (in->cur - in->base); else - avail = xmlBufUse(in->buf->buffer) - (in->cur - in->base); + avail = (ptrdiff_t)xmlBufUse(in->buf->buffer) - + (in->cur - in->base); if ((avail == 0) && (terminate)) { htmlAutoCloseOnEnd(ctxt); if ((ctxt->nameNr == 0) && (ctxt->instate != XML_PARSER_EOF)) { @@ -5411,6 +5508,12 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) { } if (avail < 1) goto done; + /* + * This is done to make progress and avoid an infinite loop + * if a parsing attempt was aborted by hitting a NUL byte. After + * changing htmlCurrentChar, this probably isn't necessary anymore. + * We should consider removing this check. + */ cur = in->cur[0]; if (cur == 0) { SKIP(1); @@ -5433,7 +5536,8 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) { if (in->buf == NULL) avail = in->length - (in->cur - in->base); else - avail = xmlBufUse(in->buf->buffer) - (in->cur - in->base); + avail = (ptrdiff_t)xmlBufUse(in->buf->buffer) - + (in->cur - in->base); } if ((ctxt->sax) && (ctxt->sax->setDocumentLocator)) ctxt->sax->setDocumentLocator(ctxt->userData, @@ -5450,7 +5554,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) { (UPP(6) == 'Y') && (UPP(7) == 'P') && (UPP(8) == 'E')) { if ((!terminate) && - (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0)) + (htmlParseLookupSequence(ctxt, '>', 0, 0, 1) < 0)) goto done; #ifdef DEBUG_PUSH xmlGenericError(xmlGenericErrorContext, @@ -5475,14 +5579,15 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) { if (in->buf == NULL) avail = in->length - (in->cur - in->base); else - avail = xmlBufUse(in->buf->buffer) - (in->cur - in->base); + avail = (ptrdiff_t)xmlBufUse(in->buf->buffer) - + (in->cur - in->base); /* * no chars in buffer */ if (avail < 1) goto done; /* - * not enouth chars in buffer + * not enough chars in buffer */ if (avail < 2) { if (!terminate) @@ -5495,8 +5600,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) { cur = in->cur[0]; if ((cur == '<') && (next == '!') && (in->cur[2] == '-') && (in->cur[3] == '-')) { - if ((!terminate) && - (htmlParseLookupSequence(ctxt, '-', '-', '>', 1, 1) < 0)) + if ((!terminate) && (htmlParseLookupCommentEnd(ctxt) < 0)) goto done; #ifdef DEBUG_PUSH xmlGenericError(xmlGenericErrorContext, @@ -5506,7 +5610,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) { ctxt->instate = XML_PARSER_MISC; } else if ((cur == '<') && (next == '?')) { if ((!terminate) && - (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0)) + (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0)) goto done; #ifdef DEBUG_PUSH xmlGenericError(xmlGenericErrorContext, @@ -5520,7 +5624,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) { (UPP(6) == 'Y') && (UPP(7) == 'P') && (UPP(8) == 'E')) { if ((!terminate) && - (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0)) + (htmlParseLookupSequence(ctxt, '>', 0, 0, 1) < 0)) goto done; #ifdef DEBUG_PUSH xmlGenericError(xmlGenericErrorContext, @@ -5536,7 +5640,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) { (avail < 9)) { goto done; } else { - ctxt->instate = XML_PARSER_START_TAG; + ctxt->instate = XML_PARSER_CONTENT; #ifdef DEBUG_PUSH xmlGenericError(xmlGenericErrorContext, "HPP: entering START_TAG\n"); @@ -5548,15 +5652,15 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) { if (in->buf == NULL) avail = in->length - (in->cur - in->base); else - avail = xmlBufUse(in->buf->buffer) - (in->cur - in->base); + avail = (ptrdiff_t)xmlBufUse(in->buf->buffer) - + (in->cur - in->base); if (avail < 2) goto done; cur = in->cur[0]; next = in->cur[1]; if ((cur == '<') && (next == '!') && (in->cur[2] == '-') && (in->cur[3] == '-')) { - if ((!terminate) && - (htmlParseLookupSequence(ctxt, '-', '-', '>', 1, 1) < 0)) + if ((!terminate) && (htmlParseLookupCommentEnd(ctxt) < 0)) goto done; #ifdef DEBUG_PUSH xmlGenericError(xmlGenericErrorContext, @@ -5566,7 +5670,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) { ctxt->instate = XML_PARSER_PROLOG; } else if ((cur == '<') && (next == '?')) { if ((!terminate) && - (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0)) + (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0)) goto done; #ifdef DEBUG_PUSH xmlGenericError(xmlGenericErrorContext, @@ -5578,7 +5682,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) { (avail < 4)) { goto done; } else { - ctxt->instate = XML_PARSER_START_TAG; + ctxt->instate = XML_PARSER_CONTENT; #ifdef DEBUG_PUSH xmlGenericError(xmlGenericErrorContext, "HPP: entering START_TAG\n"); @@ -5589,7 +5693,8 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) { if (in->buf == NULL) avail = in->length - (in->cur - in->base); else - avail = xmlBufUse(in->buf->buffer) - (in->cur - in->base); + avail = (ptrdiff_t)xmlBufUse(in->buf->buffer) - + (in->cur - in->base); if (avail < 1) goto done; cur = in->cur[0]; @@ -5602,8 +5707,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) { next = in->cur[1]; if ((cur == '<') && (next == '!') && (in->cur[2] == '-') && (in->cur[3] == '-')) { - if ((!terminate) && - (htmlParseLookupSequence(ctxt, '-', '-', '>', 1, 1) < 0)) + if ((!terminate) && (htmlParseLookupCommentEnd(ctxt) < 0)) goto done; #ifdef DEBUG_PUSH xmlGenericError(xmlGenericErrorContext, @@ -5613,7 +5717,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) { ctxt->instate = XML_PARSER_EPILOG; } else if ((cur == '<') && (next == '?')) { if ((!terminate) && - (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0)) + (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0)) goto done; #ifdef DEBUG_PUSH xmlGenericError(xmlGenericErrorContext, @@ -5648,7 +5752,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) { if (avail < 1) goto done; /* - * not enouth chars in buffer + * not enough chars in buffer */ if (avail < 2) { if (!terminate) @@ -5677,7 +5781,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) { break; } if ((!terminate) && - (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0)) + (htmlParseLookupSequence(ctxt, '>', 0, 0, 1) < 0)) goto done; /* Capture start position */ @@ -5769,7 +5873,6 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) { } case XML_PARSER_CONTENT: { xmlChar chr[2] = { 0, 0 }; - long cons; /* * Handle preparsed entities and charRef @@ -5814,7 +5917,6 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) { goto done; cur = in->cur[0]; next = in->cur[1]; - cons = ctxt->nbChars; if ((xmlStrEqual(ctxt->name, BAD_CAST"script")) || (xmlStrEqual(ctxt->name, BAD_CAST"style"))) { /* @@ -5824,7 +5926,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) { int idx; xmlChar val; - idx = htmlParseLookupSequence(ctxt, '<', '/', 0, 0, 0); + idx = htmlParseLookupSequence(ctxt, '<', '/', 0, 0); if (idx < 0) goto done; val = in->cur[idx + 2]; @@ -5851,7 +5953,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) { (UPP(6) == 'Y') && (UPP(7) == 'P') && (UPP(8) == 'E')) { if ((!terminate) && - (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0)) + (htmlParseLookupSequence(ctxt, '>', 0, 0, 1) < 0)) goto done; htmlParseErr(ctxt, XML_HTML_STRUCURE_ERROR, "Misplaced DOCTYPE declaration\n", @@ -5859,9 +5961,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) { htmlParseDocTypeDecl(ctxt); } else if ((cur == '<') && (next == '!') && (in->cur[2] == '-') && (in->cur[3] == '-')) { - if ((!terminate) && - (htmlParseLookupSequence( - ctxt, '-', '-', '>', 1, 1) < 0)) + if ((!terminate) && (htmlParseLookupCommentEnd(ctxt) < 0)) goto done; #ifdef DEBUG_PUSH xmlGenericError(xmlGenericErrorContext, @@ -5871,7 +5971,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) { ctxt->instate = XML_PARSER_CONTENT; } else if ((cur == '<') && (next == '?')) { if ((!terminate) && - (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0)) + (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0)) goto done; #ifdef DEBUG_PUSH xmlGenericError(xmlGenericErrorContext, @@ -5890,24 +5990,35 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) { #endif break; } else if (cur == '<') { - ctxt->instate = XML_PARSER_START_TAG; - ctxt->checkIndex = 0; + if ((!terminate) && (next == 0)) + goto done; + /* + * Only switch to START_TAG if the next character + * starts a valid name. Otherwise, htmlParseStartTag + * might return without consuming all characters + * up to the final '>'. + */ + if ((IS_ASCII_LETTER(next)) || + (next == '_') || (next == ':') || (next == '.')) { + ctxt->instate = XML_PARSER_START_TAG; + ctxt->checkIndex = 0; #ifdef DEBUG_PUSH - xmlGenericError(xmlGenericErrorContext, - "HPP: entering START_TAG\n"); + xmlGenericError(xmlGenericErrorContext, + "HPP: entering START_TAG\n"); #endif + } else { + htmlParseErr(ctxt, XML_ERR_NAME_REQUIRED, + "htmlParseTryOrFinish: " + "invalid element name\n", + NULL, NULL); + htmlCheckParagraph(ctxt); + if ((ctxt->sax != NULL) && + (ctxt->sax->characters != NULL)) + ctxt->sax->characters(ctxt->userData, + in->cur, 1); + NEXT; + } break; - } else if (cur == '&') { - if ((!terminate) && - (htmlParseLookupChars(ctxt, - BAD_CAST "; >/", 4) < 0)) - goto done; -#ifdef DEBUG_PUSH - xmlGenericError(xmlGenericErrorContext, - "HPP: Parsing Reference\n"); -#endif - /* TODO: check generation of subtrees if noent !!! */ - htmlParseReference(ctxt); } else { /* * check that the text sequence is complete @@ -5916,25 +6027,24 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) { * data detection. */ if ((!terminate) && - (htmlParseLookupChars(ctxt, BAD_CAST "<&", 2) < 0)) + (htmlParseLookupSequence(ctxt, '<', 0, 0, 0) < 0)) goto done; ctxt->checkIndex = 0; #ifdef DEBUG_PUSH xmlGenericError(xmlGenericErrorContext, "HPP: Parsing char data\n"); #endif - htmlParseCharData(ctxt); + while ((ctxt->instate != XML_PARSER_EOF) && + (cur != '<') && (in->cur < in->end)) { + if (cur == '&') { + htmlParseReference(ctxt); + } else { + htmlParseCharData(ctxt); + } + cur = in->cur[0]; + } } } - if (cons == ctxt->nbChars) { - if (ctxt->node != NULL) { - htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR, - "detected an error in element content\n", - NULL, NULL); - } - NEXT; - break; - } break; } @@ -5942,7 +6052,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) { if (avail < 2) goto done; if ((!terminate) && - (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0)) + (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0)) goto done; htmlParseEndTag(ctxt); if (ctxt->nameNr == 0) { @@ -6124,12 +6234,12 @@ htmlParseChunk(htmlParserCtxtPtr ctxt, const char *chunk, int size, int res; res = xmlParserInputBufferPush(ctxt->input->buf, size, chunk); + xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur); if (res < 0) { ctxt->errNo = XML_PARSER_EOF; ctxt->disableSAX = 1; return (XML_PARSER_EOF); } - xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur); #ifdef DEBUG_PUSH xmlGenericError(xmlGenericErrorContext, "HPP: pushed %d\n", size); #endif @@ -6148,12 +6258,12 @@ htmlParseChunk(htmlParserCtxtPtr ctxt, const char *chunk, int size, size_t current = ctxt->input->cur - ctxt->input->base; nbchars = xmlCharEncInput(in, terminate); + xmlBufSetInputBaseCur(in->buffer, ctxt->input, base, current); if (nbchars < 0) { htmlParseErr(ctxt, XML_ERR_INVALID_ENCODING, "encoder error\n", NULL, NULL); return(XML_ERR_INVALID_ENCODING); } - xmlBufSetInputBaseCur(in->buffer, ctxt->input, base, current); } } } @@ -6671,7 +6781,6 @@ htmlCtxtReset(htmlParserCtxtPtr ctxt) ctxt->vctxt.error = xmlParserValidityError; ctxt->vctxt.warning = xmlParserValidityWarning; ctxt->record_info = 0; - ctxt->nbChars = 0; ctxt->checkIndex = 0; ctxt->inSubset = 0; ctxt->errNo = XML_ERR_OK; diff --git a/sdk/lib/3rdparty/libxml2/HTMLtree.c b/sdk/lib/3rdparty/libxml2/HTMLtree.c index db63b371f06..24434d453e1 100644 --- a/sdk/lib/3rdparty/libxml2/HTMLtree.c +++ b/sdk/lib/3rdparty/libxml2/HTMLtree.c @@ -226,7 +226,7 @@ found_head: found_meta: /* * Search and update all the remaining the meta elements carrying - * encoding informations + * encoding information */ while (cur != NULL) { if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) { @@ -345,7 +345,7 @@ xmlAllocOutputBufferInternal(xmlCharEncodingHandlerPtr encoder); ************************************************************************/ /** * htmlSaveErrMemory: - * @extra: extra informations + * @extra: extra information * * Handle an out of memory condition */ @@ -359,7 +359,7 @@ htmlSaveErrMemory(const char *extra) * htmlSaveErr: * @code: the error number * @node: the location of the error. - * @extra: extra informations + * @extra: extra information * * Handle an out of memory condition */ @@ -518,7 +518,7 @@ htmlNodeDumpFileFormat(FILE *out, xmlDocPtr doc, buf = xmlOutputBufferCreateFile(out, handler); if (buf == NULL) return(0); - htmlNodeDumpFormatOutput(buf, doc, cur, encoding, format); + htmlNodeDumpFormatOutput(buf, doc, cur, NULL, format); ret = xmlOutputBufferClose(buf); return(ret); @@ -670,13 +670,11 @@ htmlDtdDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, * @buf: the HTML buffer output * @doc: the document * @cur: the attribute pointer - * @encoding: the encoding string * * Dump an HTML attribute */ static void -htmlAttrDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur, - const char *encoding ATTRIBUTE_UNUSED) { +htmlAttrDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur) { xmlChar *value; /* @@ -706,49 +704,22 @@ htmlAttrDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur, (!xmlStrcasecmp(cur->name, BAD_CAST "src")) || ((!xmlStrcasecmp(cur->name, BAD_CAST "name")) && (!xmlStrcasecmp(cur->parent->name, BAD_CAST "a"))))) { + xmlChar *escaped; xmlChar *tmp = value; - /* xmlURIEscapeStr() escapes '"' so it can be safely used. */ - xmlBufCCat(buf->buffer, "\""); while (IS_BLANK_CH(*tmp)) tmp++; - /* URI Escape everything, except server side includes. */ - for ( ; ; ) { - xmlChar *escaped; - xmlChar endChar; - xmlChar *end = NULL; - xmlChar *start = (xmlChar *)xmlStrstr(tmp, BAD_CAST ""); - if (end != NULL) { - *start = '\0'; - } - } - - /* Escape the whole string, or until start (set to '\0'). */ - escaped = xmlURIEscapeStr(tmp, BAD_CAST"@/:=?;#%&,+"); - if (escaped != NULL) { - xmlBufCat(buf->buffer, escaped); - xmlFree(escaped); - } else { - xmlBufCat(buf->buffer, tmp); - } - - if (end == NULL) { /* Everything has been written. */ - break; - } - - /* Do not escape anything within server side includes. */ - *start = '<'; /* Restore the first character of "") */ - endChar = *end; - *end = '\0'; - xmlBufCat(buf->buffer, start); - *end = endChar; - tmp = end; + /* + * the < and > have already been escaped at the entity level + * And doing so here breaks server side includes + */ + escaped = xmlURIEscapeStr(tmp, BAD_CAST"@/:=?;#%&,+<>"); + if (escaped != NULL) { + xmlBufWriteQuotedString(buf->buffer, escaped); + xmlFree(escaped); + } else { + xmlBufWriteQuotedString(buf->buffer, value); } - - xmlBufCCat(buf->buffer, "\""); } else { xmlBufWriteQuotedString(buf->buffer, value); } @@ -759,63 +730,22 @@ htmlAttrDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur, } } -/** - * htmlAttrListDumpOutput: - * @buf: the HTML buffer output - * @doc: the document - * @cur: the first attribute pointer - * @encoding: the encoding string - * - * Dump a list of HTML attributes - */ -static void -htmlAttrListDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur, const char *encoding) { - if (cur == NULL) { - return; - } - while (cur != NULL) { - htmlAttrDumpOutput(buf, doc, cur, encoding); - cur = cur->next; - } -} - - - -/** - * htmlNodeListDumpOutput: - * @buf: the HTML buffer output - * @doc: the document - * @cur: the first node - * @encoding: the encoding string - * @format: should formatting spaces been added - * - * Dump an HTML node list, recursive behaviour,children are printed too. - */ -static void -htmlNodeListDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, - xmlNodePtr cur, const char *encoding, int format) { - if (cur == NULL) { - return; - } - while (cur != NULL) { - htmlNodeDumpFormatOutput(buf, doc, cur, encoding, format); - cur = cur->next; - } -} - /** * htmlNodeDumpFormatOutput: * @buf: the HTML buffer output * @doc: the document * @cur: the current node - * @encoding: the encoding string + * @encoding: the encoding string (unused) * @format: should formatting spaces been added * * Dump an HTML node, recursive behaviour,children are printed too. */ void htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, - xmlNodePtr cur, const char *encoding, int format) { + xmlNodePtr cur, const char *encoding ATTRIBUTE_UNUSED, + int format) { + xmlNodePtr root; + xmlAttrPtr attr; const htmlElemDesc * info; xmlInitParser(); @@ -823,172 +753,199 @@ htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, if ((cur == NULL) || (buf == NULL)) { return; } - /* - * Special cases. - */ - if (cur->type == XML_DTD_NODE) - return; - if ((cur->type == XML_HTML_DOCUMENT_NODE) || - (cur->type == XML_DOCUMENT_NODE)){ - htmlDocContentDumpOutput(buf, (xmlDocPtr) cur, encoding); - return; - } - if (cur->type == XML_ATTRIBUTE_NODE) { - htmlAttrDumpOutput(buf, doc, (xmlAttrPtr) cur, encoding); - return; - } - if (cur->type == HTML_TEXT_NODE) { - if (cur->content != NULL) { - if (((cur->name == (const xmlChar *)xmlStringText) || - (cur->name != (const xmlChar *)xmlStringTextNoenc)) && - ((cur->parent == NULL) || - ((xmlStrcasecmp(cur->parent->name, BAD_CAST "script")) && - (xmlStrcasecmp(cur->parent->name, BAD_CAST "style"))))) { - xmlChar *buffer; - buffer = xmlEncodeEntitiesReentrant(doc, cur->content); - if (buffer != NULL) { - xmlOutputBufferWriteString(buf, (const char *)buffer); - xmlFree(buffer); - } - } else { - xmlOutputBufferWriteString(buf, (const char *)cur->content); - } - } - return; - } - if (cur->type == HTML_COMMENT_NODE) { - if (cur->content != NULL) { - xmlOutputBufferWriteString(buf, ""); - } - return; - } - if (cur->type == HTML_PI_NODE) { - if (cur->name == NULL) - return; - xmlOutputBufferWriteString(buf, "name); - if (cur->content != NULL) { - xmlOutputBufferWriteString(buf, " "); - xmlOutputBufferWriteString(buf, (const char *)cur->content); - } - xmlOutputBufferWriteString(buf, ">"); - return; - } - if (cur->type == HTML_ENTITY_REF_NODE) { - xmlOutputBufferWriteString(buf, "&"); - xmlOutputBufferWriteString(buf, (const char *)cur->name); - xmlOutputBufferWriteString(buf, ";"); - return; - } - if (cur->type == HTML_PRESERVE_NODE) { - if (cur->content != NULL) { - xmlOutputBufferWriteString(buf, (const char *)cur->content); - } - return; - } + root = cur; + while (1) { + switch (cur->type) { + case XML_HTML_DOCUMENT_NODE: + case XML_DOCUMENT_NODE: + if (((xmlDocPtr) cur)->intSubset != NULL) { + htmlDtdDumpOutput(buf, (xmlDocPtr) cur, NULL); + } + if (cur->children != NULL) { + cur = cur->children; + continue; + } + break; - /* - * Get specific HTML info for that node. - */ - if (cur->ns == NULL) - info = htmlTagLookup(cur->name); - else - info = NULL; + case XML_ELEMENT_NODE: + /* + * Get specific HTML info for that node. + */ + if (cur->ns == NULL) + info = htmlTagLookup(cur->name); + else + info = NULL; - xmlOutputBufferWriteString(buf, "<"); - if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) { - xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix); - xmlOutputBufferWriteString(buf, ":"); - } - xmlOutputBufferWriteString(buf, (const char *)cur->name); - if (cur->nsDef) - xmlNsListDumpOutput(buf, cur->nsDef); - if (cur->properties != NULL) - htmlAttrListDumpOutput(buf, doc, cur->properties, encoding); - - if ((info != NULL) && (info->empty)) { - xmlOutputBufferWriteString(buf, ">"); - if ((format) && (!info->isinline) && (cur->next != NULL)) { - if ((cur->next->type != HTML_TEXT_NODE) && - (cur->next->type != HTML_ENTITY_REF_NODE) && - (cur->parent != NULL) && - (cur->parent->name != NULL) && - (cur->parent->name[0] != 'p')) /* p, pre, param */ - xmlOutputBufferWriteString(buf, "\n"); - } - return; - } - if (((cur->type == XML_ELEMENT_NODE) || (cur->content == NULL)) && - (cur->children == NULL)) { - if ((info != NULL) && (info->saveEndTag != 0) && - (xmlStrcmp(BAD_CAST info->name, BAD_CAST "html")) && - (xmlStrcmp(BAD_CAST info->name, BAD_CAST "body"))) { - xmlOutputBufferWriteString(buf, ">"); - } else { - xmlOutputBufferWriteString(buf, ">ns != NULL) && (cur->ns->prefix != NULL)) { xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix); xmlOutputBufferWriteString(buf, ":"); } - xmlOutputBufferWriteString(buf, (const char *)cur->name); - xmlOutputBufferWriteString(buf, ">"); - } - if ((format) && (cur->next != NULL) && - (info != NULL) && (!info->isinline)) { - if ((cur->next->type != HTML_TEXT_NODE) && - (cur->next->type != HTML_ENTITY_REF_NODE) && - (cur->parent != NULL) && - (cur->parent->name != NULL) && - (cur->parent->name[0] != 'p')) /* p, pre, param */ - xmlOutputBufferWriteString(buf, "\n"); - } - return; - } - xmlOutputBufferWriteString(buf, ">"); - if ((cur->type != XML_ELEMENT_NODE) && - (cur->content != NULL)) { - /* - * Uses the OutputBuffer property to automatically convert - * invalids to charrefs - */ + xmlOutputBufferWriteString(buf, (const char *)cur->name); + if (cur->nsDef) + xmlNsListDumpOutput(buf, cur->nsDef); + attr = cur->properties; + while (attr != NULL) { + htmlAttrDumpOutput(buf, doc, attr); + attr = attr->next; + } - xmlOutputBufferWriteString(buf, (const char *) cur->content); - } - if (cur->children != NULL) { - if ((format) && (info != NULL) && (!info->isinline) && - (cur->children->type != HTML_TEXT_NODE) && - (cur->children->type != HTML_ENTITY_REF_NODE) && - (cur->children != cur->last) && - (cur->name != NULL) && - (cur->name[0] != 'p')) /* p, pre, param */ - xmlOutputBufferWriteString(buf, "\n"); - htmlNodeListDumpOutput(buf, doc, cur->children, encoding, format); - if ((format) && (info != NULL) && (!info->isinline) && - (cur->last->type != HTML_TEXT_NODE) && - (cur->last->type != HTML_ENTITY_REF_NODE) && - (cur->children != cur->last) && - (cur->name != NULL) && - (cur->name[0] != 'p')) /* p, pre, param */ - xmlOutputBufferWriteString(buf, "\n"); - } - xmlOutputBufferWriteString(buf, "ns != NULL) && (cur->ns->prefix != NULL)) { - xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix); - xmlOutputBufferWriteString(buf, ":"); - } - xmlOutputBufferWriteString(buf, (const char *)cur->name); - xmlOutputBufferWriteString(buf, ">"); - if ((format) && (info != NULL) && (!info->isinline) && - (cur->next != NULL)) { - if ((cur->next->type != HTML_TEXT_NODE) && - (cur->next->type != HTML_ENTITY_REF_NODE) && - (cur->parent != NULL) && - (cur->parent->name != NULL) && - (cur->parent->name[0] != 'p')) /* p, pre, param */ - xmlOutputBufferWriteString(buf, "\n"); + if ((info != NULL) && (info->empty)) { + xmlOutputBufferWriteString(buf, ">"); + } else if (cur->children == NULL) { + if ((info != NULL) && (info->saveEndTag != 0) && + (xmlStrcmp(BAD_CAST info->name, BAD_CAST "html")) && + (xmlStrcmp(BAD_CAST info->name, BAD_CAST "body"))) { + xmlOutputBufferWriteString(buf, ">"); + } else { + xmlOutputBufferWriteString(buf, ">ns != NULL) && (cur->ns->prefix != NULL)) { + xmlOutputBufferWriteString(buf, + (const char *)cur->ns->prefix); + xmlOutputBufferWriteString(buf, ":"); + } + xmlOutputBufferWriteString(buf, (const char *)cur->name); + xmlOutputBufferWriteString(buf, ">"); + } + } else { + xmlOutputBufferWriteString(buf, ">"); + if ((format) && (info != NULL) && (!info->isinline) && + (cur->children->type != HTML_TEXT_NODE) && + (cur->children->type != HTML_ENTITY_REF_NODE) && + (cur->children != cur->last) && + (cur->name != NULL) && + (cur->name[0] != 'p')) /* p, pre, param */ + xmlOutputBufferWriteString(buf, "\n"); + cur = cur->children; + continue; + } + + if ((format) && (cur->next != NULL) && + (info != NULL) && (!info->isinline)) { + if ((cur->next->type != HTML_TEXT_NODE) && + (cur->next->type != HTML_ENTITY_REF_NODE) && + (cur->parent != NULL) && + (cur->parent->name != NULL) && + (cur->parent->name[0] != 'p')) /* p, pre, param */ + xmlOutputBufferWriteString(buf, "\n"); + } + + break; + + case XML_ATTRIBUTE_NODE: + htmlAttrDumpOutput(buf, doc, (xmlAttrPtr) cur); + break; + + case HTML_TEXT_NODE: + if (cur->content == NULL) + break; + if (((cur->name == (const xmlChar *)xmlStringText) || + (cur->name != (const xmlChar *)xmlStringTextNoenc)) && + ((cur->parent == NULL) || + ((xmlStrcasecmp(cur->parent->name, BAD_CAST "script")) && + (xmlStrcasecmp(cur->parent->name, BAD_CAST "style"))))) { + xmlChar *buffer; + + buffer = xmlEncodeEntitiesReentrant(doc, cur->content); + if (buffer != NULL) { + xmlOutputBufferWriteString(buf, (const char *)buffer); + xmlFree(buffer); + } + } else { + xmlOutputBufferWriteString(buf, (const char *)cur->content); + } + break; + + case HTML_COMMENT_NODE: + if (cur->content != NULL) { + xmlOutputBufferWriteString(buf, ""); + } + break; + + case HTML_PI_NODE: + if (cur->name != NULL) { + xmlOutputBufferWriteString(buf, "name); + if (cur->content != NULL) { + xmlOutputBufferWriteString(buf, " "); + xmlOutputBufferWriteString(buf, + (const char *)cur->content); + } + xmlOutputBufferWriteString(buf, ">"); + } + break; + + case HTML_ENTITY_REF_NODE: + xmlOutputBufferWriteString(buf, "&"); + xmlOutputBufferWriteString(buf, (const char *)cur->name); + xmlOutputBufferWriteString(buf, ";"); + break; + + case HTML_PRESERVE_NODE: + if (cur->content != NULL) { + xmlOutputBufferWriteString(buf, (const char *)cur->content); + } + break; + + default: + break; + } + + while (1) { + if (cur == root) + return; + if (cur->next != NULL) { + cur = cur->next; + break; + } + + /* + * The parent should never be NULL here but we want to handle + * corrupted documents gracefully. + */ + if (cur->parent == NULL) + return; + cur = cur->parent; + + if ((cur->type == XML_HTML_DOCUMENT_NODE) || + (cur->type == XML_DOCUMENT_NODE)) { + xmlOutputBufferWriteString(buf, "\n"); + } else { + if ((format) && (cur->ns == NULL)) + info = htmlTagLookup(cur->name); + else + info = NULL; + + if ((format) && (info != NULL) && (!info->isinline) && + (cur->last->type != HTML_TEXT_NODE) && + (cur->last->type != HTML_ENTITY_REF_NODE) && + (cur->children != cur->last) && + (cur->name != NULL) && + (cur->name[0] != 'p')) /* p, pre, param */ + xmlOutputBufferWriteString(buf, "\n"); + + xmlOutputBufferWriteString(buf, "ns != NULL) && (cur->ns->prefix != NULL)) { + xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix); + xmlOutputBufferWriteString(buf, ":"); + } + xmlOutputBufferWriteString(buf, (const char *)cur->name); + xmlOutputBufferWriteString(buf, ">"); + + if ((format) && (info != NULL) && (!info->isinline) && + (cur->next != NULL)) { + if ((cur->next->type != HTML_TEXT_NODE) && + (cur->next->type != HTML_ENTITY_REF_NODE) && + (cur->parent != NULL) && + (cur->parent->name != NULL) && + (cur->parent->name[0] != 'p')) /* p, pre, param */ + xmlOutputBufferWriteString(buf, "\n"); + } + } + } } } @@ -997,63 +954,45 @@ htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, * @buf: the HTML buffer output * @doc: the document * @cur: the current node - * @encoding: the encoding string + * @encoding: the encoding string (unused) * * Dump an HTML node, recursive behaviour,children are printed too, * and formatting returns/spaces are added. */ void htmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, - xmlNodePtr cur, const char *encoding) { - htmlNodeDumpFormatOutput(buf, doc, cur, encoding, 1); + xmlNodePtr cur, const char *encoding ATTRIBUTE_UNUSED) { + htmlNodeDumpFormatOutput(buf, doc, cur, NULL, 1); } /** * htmlDocContentDumpFormatOutput: * @buf: the HTML buffer output * @cur: the document - * @encoding: the encoding string + * @encoding: the encoding string (unused) * @format: should formatting spaces been added * * Dump an HTML document. */ void htmlDocContentDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr cur, - const char *encoding, int format) { - int type; - - xmlInitParser(); - - if ((buf == NULL) || (cur == NULL)) - return; - - /* - * force to output the stuff as HTML, especially for entities - */ - type = cur->type; - cur->type = XML_HTML_DOCUMENT_NODE; - if (cur->intSubset != NULL) { - htmlDtdDumpOutput(buf, cur, NULL); - } - if (cur->children != NULL) { - htmlNodeListDumpOutput(buf, cur, cur->children, encoding, format); - } - xmlOutputBufferWriteString(buf, "\n"); - cur->type = (xmlElementType) type; + const char *encoding ATTRIBUTE_UNUSED, + int format) { + htmlNodeDumpFormatOutput(buf, cur, (xmlNodePtr) cur, NULL, format); } /** * htmlDocContentDumpOutput: * @buf: the HTML buffer output * @cur: the document - * @encoding: the encoding string + * @encoding: the encoding string (unused) * * Dump an HTML document. Formatting return/spaces are added. */ void htmlDocContentDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr cur, - const char *encoding) { - htmlDocContentDumpFormatOutput(buf, cur, encoding, 1); + const char *encoding ATTRIBUTE_UNUSED) { + htmlNodeDumpFormatOutput(buf, cur, (xmlNodePtr) cur, NULL, 1); } /************************************************************************ diff --git a/sdk/lib/3rdparty/libxml2/README b/sdk/lib/3rdparty/libxml2/README index 5c7bddf8de2..495751781d4 100644 --- a/sdk/lib/3rdparty/libxml2/README +++ b/sdk/lib/3rdparty/libxml2/README @@ -19,7 +19,7 @@ To assert build quality: There is 3 standalone tools runtest.c runsuite.c testapi.c, which should compile as part of the build or as any application would. Launch them from this directory to get results, runtest checks - the proper functionning of libxml2 main APIs while testapi does + the proper functioning of libxml2 main APIs while testapi does a full coverage check. Report failures to the list. To report bugs, follow the instructions at: diff --git a/sdk/lib/3rdparty/libxml2/SAX2.c b/sdk/lib/3rdparty/libxml2/SAX2.c index 5f141f9a3cc..99019a984cd 100644 --- a/sdk/lib/3rdparty/libxml2/SAX2.c +++ b/sdk/lib/3rdparty/libxml2/SAX2.c @@ -590,36 +590,6 @@ xmlSAX2GetEntity(void *ctx, const xmlChar *name) } else { ret = xmlGetDocEntity(ctxt->myDoc, name); } - if ((ret != NULL) && - ((ctxt->validate) || (ctxt->replaceEntities)) && - (ret->children == NULL) && - (ret->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) { - int val; - - /* - * for validation purposes we really need to fetch and - * parse the external entity - */ - xmlNodePtr children; - unsigned long oldnbent = ctxt->nbentities; - - val = xmlParseCtxtExternalEntity(ctxt, ret->URI, - ret->ExternalID, &children); - if (val == 0) { - xmlAddChildList((xmlNodePtr) ret, children); - } else { - xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_PROCESSING, - "Failure to process entity %s\n", name, NULL); - ctxt->validate = 0; - return(NULL); - } - ret->owner = 1; - if (ret->checked == 0) { - ret->checked = (ctxt->nbentities - oldnbent + 1) * 2; - if ((ret->content != NULL) && (xmlStrchr(ret->content, '<'))) - ret->checked |= 1; - } - } return(ret); } @@ -1693,23 +1663,23 @@ xmlSAX2StartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts) } } - /* - * Insert all the defaulted attributes from the DTD especially namespaces - */ - if ((!ctxt->html) && - ((ctxt->myDoc->intSubset != NULL) || - (ctxt->myDoc->extSubset != NULL))) { - xmlCheckDefaultedAttributes(ctxt, name, prefix, atts); - } + if (!ctxt->html) { + /* + * Insert all the defaulted attributes from the DTD especially + * namespaces + */ + if ((ctxt->myDoc->intSubset != NULL) || + (ctxt->myDoc->extSubset != NULL)) { + xmlCheckDefaultedAttributes(ctxt, name, prefix, atts); + } - /* - * process all the attributes whose name start with "xmlns" - */ - if (atts != NULL) { - i = 0; - att = atts[i++]; - value = atts[i++]; - if (!ctxt->html) { + /* + * process all the attributes whose name start with "xmlns" + */ + if (atts != NULL) { + i = 0; + att = atts[i++]; + value = atts[i++]; while ((att != NULL) && (value != NULL)) { if ((att[0] == 'x') && (att[1] == 'm') && (att[2] == 'l') && (att[3] == 'n') && (att[4] == 's')) @@ -1718,30 +1688,30 @@ xmlSAX2StartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts) att = atts[i++]; value = atts[i++]; } - } - } + } - /* - * Search the namespace, note that since the attributes have been - * processed, the local namespaces are available. - */ - ns = xmlSearchNs(ctxt->myDoc, ret, prefix); - if ((ns == NULL) && (parent != NULL)) - ns = xmlSearchNs(ctxt->myDoc, parent, prefix); - if ((prefix != NULL) && (ns == NULL)) { - ns = xmlNewNs(ret, NULL, prefix); - xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE, - "Namespace prefix %s is not defined\n", - prefix, NULL); - } + /* + * Search the namespace, note that since the attributes have been + * processed, the local namespaces are available. + */ + ns = xmlSearchNs(ctxt->myDoc, ret, prefix); + if ((ns == NULL) && (parent != NULL)) + ns = xmlSearchNs(ctxt->myDoc, parent, prefix); + if ((prefix != NULL) && (ns == NULL)) { + ns = xmlNewNs(ret, NULL, prefix); + xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE, + "Namespace prefix %s is not defined\n", + prefix, NULL); + } - /* - * set the namespace node, making sure that if the default namespace - * is unbound on a parent we simply keep it NULL - */ - if ((ns != NULL) && (ns->href != NULL) && - ((ns->href[0] != 0) || (ns->prefix != NULL))) - xmlSetNs(ret, ns); + /* + * set the namespace node, making sure that if the default namespace + * is unbound on a parent we simply keep it NULL + */ + if ((ns != NULL) && (ns->href != NULL) && + ((ns->href[0] != 0) || (ns->prefix != NULL))) + xmlSetNs(ret, ns); + } /* * process all the other attributes @@ -2203,7 +2173,7 @@ xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt, * attribute values. * * SAX2 callback when an element start has been detected by the parser. - * It provides the namespace informations for the element, as well as + * It provides the namespace information for the element, as well as * the new namespace declarations on the element. */ void @@ -2456,7 +2426,7 @@ xmlSAX2StartElementNs(void *ctx, * @URI: the element namespace name if available * * SAX2 callback when an element end has been detected by the parser. - * It provides the namespace informations for the element. + * It provides the namespace information for the element. */ void xmlSAX2EndElementNs(void *ctx, @@ -2523,20 +2493,21 @@ xmlSAX2Reference(void *ctx, const xmlChar *name) } /** - * xmlSAX2Characters: + * xmlSAX2Text: * @ctx: the user data (XML parser context) * @ch: a xmlChar string * @len: the number of xmlChar + * @type: text or cdata * - * receiving some chars from the parser. + * Append characters. */ -void -xmlSAX2Characters(void *ctx, const xmlChar *ch, int len) +static void +xmlSAX2Text(xmlParserCtxtPtr ctxt, const xmlChar *ch, int len, + xmlElementType type) { - xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; xmlNodePtr lastChild; - if (ctx == NULL) return; + if (ctxt == NULL) return; #ifdef DEBUG_SAX xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2Characters(%.30s, %d)\n", ch, len); @@ -2565,7 +2536,10 @@ xmlSAX2Characters(void *ctx, const xmlChar *ch, int len) * elements. Use an attribute in the structure !!! */ if (lastChild == NULL) { - lastChild = xmlSAX2TextNode(ctxt, ch, len); + if (type == XML_TEXT_NODE) + lastChild = xmlSAX2TextNode(ctxt, ch, len); + else + lastChild = xmlNewCDataBlock(ctxt->myDoc, ch, len); if (lastChild != NULL) { ctxt->node->children = lastChild; ctxt->node->last = lastChild; @@ -2579,8 +2553,9 @@ xmlSAX2Characters(void *ctx, const xmlChar *ch, int len) } } else { int coalesceText = (lastChild != NULL) && - (lastChild->type == XML_TEXT_NODE) && - (lastChild->name == xmlStringText); + (lastChild->type == type) && + ((type != XML_TEXT_NODE) || + (lastChild->name == xmlStringText)); if ((coalesceText) && (ctxt->nodemem != 0)) { /* * The whole point of maintaining nodelen and nodemem, @@ -2637,7 +2612,10 @@ xmlSAX2Characters(void *ctx, const xmlChar *ch, int len) } } else { /* Mixed content, first time */ - lastChild = xmlSAX2TextNode(ctxt, ch, len); + if (type == XML_TEXT_NODE) + lastChild = xmlSAX2TextNode(ctxt, ch, len); + else + lastChild = xmlNewCDataBlock(ctxt->myDoc, ch, len); if (lastChild != NULL) { xmlAddChild(ctxt->node, lastChild); if (ctxt->node->children != NULL) { @@ -2649,6 +2627,20 @@ xmlSAX2Characters(void *ctx, const xmlChar *ch, int len) } } +/** + * xmlSAX2Characters: + * @ctx: the user data (XML parser context) + * @ch: a xmlChar string + * @len: the number of xmlChar + * + * receiving some chars from the parser. + */ +void +xmlSAX2Characters(void *ctx, const xmlChar *ch, int len) +{ + xmlSAX2Text((xmlParserCtxtPtr) ctx, ch, len, XML_TEXT_NODE); +} + /** * xmlSAX2IgnorableWhitespace: * @ctx: the user data (XML parser context) @@ -2805,27 +2797,7 @@ xmlSAX2Comment(void *ctx, const xmlChar *value) void xmlSAX2CDataBlock(void *ctx, const xmlChar *value, int len) { - xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; - xmlNodePtr ret, lastChild; - - if (ctx == NULL) return; -#ifdef DEBUG_SAX - xmlGenericError(xmlGenericErrorContext, - "SAX.pcdata(%.10s, %d)\n", value, len); -#endif - lastChild = xmlGetLastChild(ctxt->node); -#ifdef DEBUG_SAX_TREE - xmlGenericError(xmlGenericErrorContext, - "add chars to %s \n", ctxt->node->name); -#endif - if ((lastChild != NULL) && - (lastChild->type == XML_CDATA_SECTION_NODE)) { - xmlTextConcat(lastChild, value, len); - } else { - ret = xmlNewCDataBlock(ctxt->myDoc, value, len); - if (xmlAddChild(ctxt->node, ret) == NULL) - xmlFreeNode(ret); - } + xmlSAX2Text((xmlParserCtxtPtr) ctx, value, len, XML_CDATA_SECTION_NODE); } static int xmlSAX2DefaultVersionValue = 2; diff --git a/sdk/lib/3rdparty/libxml2/TODO b/sdk/lib/3rdparty/libxml2/TODO index 9c322249824..94d34c8b6ef 100644 --- a/sdk/lib/3rdparty/libxml2/TODO +++ b/sdk/lib/3rdparty/libxml2/TODO @@ -202,7 +202,7 @@ Done: by the XML parser, UTF-8 should be checked when there is no "encoding" declared ! - Support for UTF-8 and UTF-16 encoding - => added some convertion routines provided by Martin Durst + => added some conversion routines provided by Martin Durst patched them, got fixes from @@@ I plan to keep everything internally as UTF-8 (or ISO-Latin-X) this is slightly more costly but more compact, and recent processors @@ -212,7 +212,7 @@ Done: is enabled, tested the ISO->UTF-8 stuff - External entities loading: - allow override by client code - - make sure it is alled for all external entities referenced + - make sure it is called for all external entities referenced Done, client code should use xmlSetExternalEntityLoader() to set the default loading routine. It will be called each time an external entity entity resolution is triggered. @@ -245,8 +245,8 @@ Done: most cases ! - progressive reading. The entity support is a first step toward - asbtraction of an input stream. A large part of the context is still - located on the stack, moving to a state machine and putting everyting + abstraction of an input stream. A large part of the context is still + located on the stack, moving to a state machine and putting everything in the parsing context should provide an adequate solution. => Rather than progressive parsing, give more power to the SAX-like interface. Currently the DOM-like representation is built but diff --git a/sdk/lib/3rdparty/libxml2/buf.c b/sdk/lib/3rdparty/libxml2/buf.c index d46da365142..24368d379f8 100644 --- a/sdk/lib/3rdparty/libxml2/buf.c +++ b/sdk/lib/3rdparty/libxml2/buf.c @@ -83,7 +83,7 @@ struct _xmlBuf { /** * xmlBufMemoryError: - * @extra: extra informations + * @extra: extra information * * Handle an out of memory condition * To be improved... @@ -98,7 +98,7 @@ xmlBufMemoryError(xmlBufPtr buf, const char *extra) /** * xmlBufOverflowError: - * @extra: extra informations + * @extra: extra information * * Handle a buffer overflow error * To be improved... @@ -1233,10 +1233,12 @@ xmlBufBackToBuffer(xmlBufPtr buf) { * Keep the buffer but provide a truncated size value. */ xmlBufOverflowError(buf, "Allocated size too big for xmlBuffer"); + ret->use = (int) buf->use; ret->size = INT_MAX; + } else { + ret->use = (int) buf->use; + ret->size = (int) buf->size; } - ret->use = (int) buf->use; - ret->size = (int) buf->size; ret->alloc = buf->alloc; ret->content = buf->content; ret->contentIO = buf->contentIO; @@ -1332,8 +1334,12 @@ xmlBufGetInputBase(xmlBufPtr buf, xmlParserInputPtr input) { int xmlBufSetInputBaseCur(xmlBufPtr buf, xmlParserInputPtr input, size_t base, size_t cur) { - if ((input == NULL) || (buf == NULL) || (buf->error)) + if (input == NULL) return(-1); + if ((buf == NULL) || (buf->error)) { + input->base = input->cur = input->end = BAD_CAST ""; + return(-1); + } CHECK_COMPAT(buf) input->base = &buf->content[base]; input->cur = input->base + cur; diff --git a/sdk/lib/3rdparty/libxml2/c14n.c b/sdk/lib/3rdparty/libxml2/c14n.c index 5b3fbe70c6c..3efcd92eefa 100644 --- a/sdk/lib/3rdparty/libxml2/c14n.c +++ b/sdk/lib/3rdparty/libxml2/c14n.c @@ -132,7 +132,7 @@ static xmlChar *xmlC11NNormalizeString(const xmlChar * input, /** * xmlC14NErrMemory: - * @extra: extra informations + * @extra: extra information * * Handle a redefinition of memory error */ @@ -147,7 +147,7 @@ xmlC14NErrMemory(const char *extra) /** * xmlC14NErrParam: - * @extra: extra informations + * @extra: extra information * * Handle a redefinition of param error */ @@ -162,7 +162,7 @@ xmlC14NErrParam(const char *extra) /** * xmlC14NErrInternal: - * @extra: extra informations + * @extra: extra information * * Handle a redefinition of internal error */ @@ -177,7 +177,7 @@ xmlC14NErrInternal(const char *extra) /** * xmlC14NErrInvalidNode: - * @extra: extra informations + * @extra: extra information * * Handle a redefinition of invalid node error */ @@ -192,7 +192,7 @@ xmlC14NErrInvalidNode(const char *node_type, const char *extra) /** * xmlC14NErrUnknownNode: - * @extra: extra informations + * @extra: extra information * * Handle a redefinition of unknown node error */ @@ -207,7 +207,7 @@ xmlC14NErrUnknownNode(int node_type, const char *extra) /** * xmlC14NErrRelativeNamespace: - * @extra: extra informations + * @extra: extra information * * Handle a redefinition of relative namespace error */ @@ -228,7 +228,7 @@ xmlC14NErrRelativeNamespace(const char *ns_uri) * @node: the context node * @error: the error code * @msg: the message - * @extra: extra informations + * @extra: extra information * * Handle a redefinition of attribute error */ @@ -2033,13 +2033,13 @@ xmlC14NDocDumpMemory(xmlDocPtr doc, xmlNodeSetPtr nodes, } ret = xmlBufUse(buf->buffer); - if (ret > 0) { + if (ret >= 0) { *doc_txt_ptr = xmlStrndup(xmlBufContent(buf->buffer), ret); } (void) xmlOutputBufferClose(buf); - if ((*doc_txt_ptr == NULL) && (ret > 0)) { - xmlC14NErrMemory("coping canonicalized document"); + if ((*doc_txt_ptr == NULL) && (ret >= 0)) { + xmlC14NErrMemory("copying canonicalized document"); return (-1); } return (ret); diff --git a/sdk/lib/3rdparty/libxml2/catalog.c b/sdk/lib/3rdparty/libxml2/catalog.c index 7328fd319c0..effbb2e6f48 100644 --- a/sdk/lib/3rdparty/libxml2/catalog.c +++ b/sdk/lib/3rdparty/libxml2/catalog.c @@ -216,7 +216,7 @@ static int xmlCatalogInitialized = 0; /** * xmlCatalogErrMemory: - * @extra: extra informations + * @extra: extra information * * Handle an out of memory condition */ @@ -234,7 +234,7 @@ xmlCatalogErrMemory(const char *extra) * @catal: the Catalog entry * @node: the context node * @msg: the error message - * @extra: extra informations + * @extra: extra information * * Handle a catalog error */ @@ -924,7 +924,7 @@ xmlParseCatalogFile(const char *filename) { xmlBufResetInput(buf->buffer, inputStream); inputPush(ctxt, inputStream); - if ((ctxt->directory == NULL) && (directory == NULL)) + if (ctxt->directory == NULL) directory = xmlParserGetDirectory(filename); if ((ctxt->directory == NULL) && (directory != NULL)) ctxt->directory = directory; @@ -2069,8 +2069,7 @@ xmlCatalogListXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID, ret = xmlCatalogXMLResolve(catal->children, pubID, sysID); if (ret != NULL) { break; - } else if ((catal->children != NULL) && - (catal->children->depth > MAX_CATAL_DEPTH)) { + } else if (catal->children->depth > MAX_CATAL_DEPTH) { ret = NULL; break; } @@ -2353,7 +2352,7 @@ xmlParseSGMLCatalog(xmlCatalogPtr catal, const xmlChar *value, xmlCatalogEntryType type = XML_CATA_NONE; cur = xmlParseSGMLCatalogName(cur, &name); - if (name == NULL) { + if (cur == NULL || name == NULL) { /* error */ break; } @@ -3254,6 +3253,7 @@ xmlLoadCatalogs(const char *pathss) { while ((*cur != 0) && (*cur != PATH_SEPARATOR) && (!xmlIsBlank_ch(*cur))) cur++; path = xmlStrndup((const xmlChar *)paths, cur - paths); + if (path != NULL) { #ifdef _WIN32 iLen = strlen((const char*)path); for(i = 0; i < iLen; i++) { @@ -3262,7 +3262,6 @@ xmlLoadCatalogs(const char *pathss) { } } #endif - if (path != NULL) { xmlLoadCatalog((const char *) path); xmlFree(path); } @@ -3427,9 +3426,10 @@ xmlCatalogAdd(const xmlChar *type, const xmlChar *orig, const xmlChar *replace) (xmlStrEqual(type, BAD_CAST "catalog"))) { xmlDefaultCatalog = xmlCreateNewCatalog(XML_XML_CATALOG_TYPE, xmlCatalogDefaultPrefer); - xmlDefaultCatalog->xml = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL, + if (xmlDefaultCatalog != NULL) { + xmlDefaultCatalog->xml = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL, orig, NULL, xmlCatalogDefaultPrefer, NULL); - + } xmlRMutexUnlock(xmlCatalogMutex); return(0); } diff --git a/sdk/lib/3rdparty/libxml2/config.h b/sdk/lib/3rdparty/libxml2/config.h index 55aa50cf4e4..d6756c32de0 100644 --- a/sdk/lib/3rdparty/libxml2/config.h +++ b/sdk/lib/3rdparty/libxml2/config.h @@ -1,6 +1,9 @@ /* config.h. Generated from config.h.in by configure. */ /* config.h.in. Generated from configure.in by autoheader. */ +/* A form that will not confuse apibuild.py */ +/* #undef ATTRIBUTE_DESTRUCTOR */ + /* Type cast for the gethostbyname() argument */ #define GETHOSTBYNAME_ARG_CAST @@ -10,6 +13,9 @@ /* Define to 1 if you have the header file. */ /* #undef HAVE_ARPA_NAMESER_H */ +/* Define if __attribute__((destructor)) is accepted */ +/* #undef HAVE_ATTRIBUTE_DESTRUCTOR */ + /* Whether struct sockaddr::__ss_family exists */ /* #undef HAVE_BROKEN_SS_FAMILY */ diff --git a/sdk/lib/3rdparty/libxml2/debugXML.c b/sdk/lib/3rdparty/libxml2/debugXML.c index d855555861d..7a2ca47d225 100644 --- a/sdk/lib/3rdparty/libxml2/debugXML.c +++ b/sdk/lib/3rdparty/libxml2/debugXML.c @@ -1342,7 +1342,7 @@ xmlCtxtDumpDTD(xmlDebugCtxtPtr ctxt, xmlDtdPtr dtd) * @output: the FILE * for the output * @str: the string * - * Dumps informations about the string, shorten it if necessary + * Dumps information about the string, shorten it if necessary */ void xmlDebugDumpString(FILE * output, const xmlChar * str) @@ -2190,7 +2190,7 @@ xmlShellRegisterRootNamespaces(xmlShellCtxtPtr ctxt, char *arg ATTRIBUTE_UNUSED, * @node2: unused * * Implements the XML shell function "grep" - * dumps informations about the node (namespace, attributes, content). + * dumps information about the node (namespace, attributes, content). * * Returns 0 */ @@ -2268,7 +2268,7 @@ xmlShellGrep(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED, * @node2: unused * * Implements the XML shell function "dir" - * dumps informations about the node (namespace, attributes, content). + * dumps information about the node (namespace, attributes, content). * * Returns 0 */ @@ -2302,7 +2302,7 @@ xmlShellDir(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED, * @node2: unused * * Implements the XML shell function "dir" - * dumps informations about the node (namespace, attributes, content). + * dumps information about the node (namespace, attributes, content). * * Returns 0 */ @@ -2900,7 +2900,7 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input, fprintf(ctxt->output, "\tbye leave shell\n"); fprintf(ctxt->output, "\tcat [node] display node or current node\n"); fprintf(ctxt->output, "\tcd [path] change directory to path or to root\n"); - fprintf(ctxt->output, "\tdir [path] dumps informations about the node (namespace, attributes, content)\n"); + fprintf(ctxt->output, "\tdir [path] dumps information about the node (namespace, attributes, content)\n"); fprintf(ctxt->output, "\tdu [path] show the structure of the subtree under path or the current node\n"); fprintf(ctxt->output, "\texit leave shell\n"); fprintf(ctxt->output, "\thelp display this help\n"); diff --git a/sdk/lib/3rdparty/libxml2/dict.c b/sdk/lib/3rdparty/libxml2/dict.c index 336e046aecf..90e4d81403c 100644 --- a/sdk/lib/3rdparty/libxml2/dict.c +++ b/sdk/lib/3rdparty/libxml2/dict.c @@ -10,7 +10,7 @@ * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. * * Author: daniel@veillard.com @@ -452,7 +452,7 @@ xmlDictComputeFastKey(const xmlChar *name, int namelen, int seed) { unsigned long value = seed; if (name == NULL) return(0); - value = *name; + value += *name; value <<= 5; if (namelen > 10) { value += name[namelen - 1]; diff --git a/sdk/lib/3rdparty/libxml2/encoding.c b/sdk/lib/3rdparty/libxml2/encoding.c index ad4d8a63a31..cdff6ae7bfb 100644 --- a/sdk/lib/3rdparty/libxml2/encoding.c +++ b/sdk/lib/3rdparty/libxml2/encoding.c @@ -76,7 +76,7 @@ static int xmlLittleEndian = 1; /** * xmlEncodingErrMemory: - * @extra: extra informations + * @extra: extra information * * Handle an out of memory condition */ @@ -170,7 +170,7 @@ closeIcuConverter(uconv_t *conv) * Returns 0 if success, or -1 otherwise * The value of @inlen after return is the number of octets consumed * if the return value is positive, else unpredictable. - * The value of @outlen after return is the number of octets consumed. + * The value of @outlen after return is the number of octets produced. */ static int asciiToUTF8(unsigned char* out, int *outlen, @@ -217,7 +217,7 @@ asciiToUTF8(unsigned char* out, int *outlen, * Returns 0 if success, -2 if the transcoding fails, or -1 otherwise * The value of @inlen after return is the number of octets consumed * if the return value is positive, else unpredictable. - * The value of @outlen after return is the number of octets consumed. + * The value of @outlen after return is the number of octets produced. */ static int UTF8Toascii(unsigned char* out, int *outlen, @@ -301,7 +301,7 @@ UTF8Toascii(unsigned char* out, int *outlen, * Returns the number of bytes written if success, or -1 otherwise * The value of @inlen after return is the number of octets consumed * if the return value is positive, else unpredictable. - * The value of @outlen after return is the number of octets consumed. + * The value of @outlen after return is the number of octets produced. */ int isolat1ToUTF8(unsigned char* out, int *outlen, @@ -373,6 +373,11 @@ UTF8ToUTF8(unsigned char* out, int *outlen, if (len < 0) return(-1); + /* + * FIXME: Conversion functions must assure valid UTF-8, so we have + * to check for UTF-8 validity. Preferably, this converter shouldn't + * be used at all. + */ memcpy(out, inb, len); *outlen = len; @@ -396,7 +401,7 @@ UTF8ToUTF8(unsigned char* out, int *outlen, or -1 otherwise * The value of @inlen after return is the number of octets consumed * if the return value is positive, else unpredictable. - * The value of @outlen after return is the number of octets consumed. + * The value of @outlen after return is the number of octets produced. */ int UTF8Toisolat1(unsigned char* out, int *outlen, @@ -496,13 +501,18 @@ UTF16LEToUTF8(unsigned char* out, int *outlen, { unsigned char* outstart = out; const unsigned char* processed = inb; - unsigned char* outend = out + *outlen; + unsigned char* outend; unsigned short* in = (unsigned short*) inb; unsigned short* inend; unsigned int c, d, inlen; unsigned char *tmp; int bits; + if (*outlen == 0) { + *inlenb = 0; + return(0); + } + outend = out + *outlen; if ((*inlenb % 2) == 1) (*inlenb)--; inlen = *inlenb / 2; @@ -1483,16 +1493,25 @@ xmlRegisterCharEncodingHandler(xmlCharEncodingHandlerPtr handler) { if ((handler == NULL) || (handlers == NULL)) { xmlEncodingErr(XML_I18N_NO_HANDLER, "xmlRegisterCharEncodingHandler: NULL handler !\n", NULL); - return; + goto free_handler; } if (nbCharEncodingHandler >= MAX_ENCODING_HANDLERS) { xmlEncodingErr(XML_I18N_EXCESS_HANDLER, "xmlRegisterCharEncodingHandler: Too many handler registered, see %s\n", "MAX_ENCODING_HANDLERS"); - return; + goto free_handler; } handlers[nbCharEncodingHandler++] = handler; + return; + +free_handler: + if (handler != NULL) { + if (handler->name != NULL) { + xmlFree(handler->name); + } + xmlFree(handler); + } } /** @@ -1784,7 +1803,7 @@ xmlFindCharEncodingHandler(const char *name) { * @cd: iconv converter data structure * @out: a pointer to an array of bytes to store the result * @outlen: the length of @out - * @in: a pointer to an array of ISO Latin 1 chars + * @in: a pointer to an array of input bytes * @inlen: the length of @in * * Returns 0 if success, or @@ -1795,7 +1814,7 @@ xmlFindCharEncodingHandler(const char *name) { * * The value of @inlen after return is the number of octets consumed * as the return value is positive, else unpredictable. - * The value of @outlen after return is the number of octets consumed. + * The value of @outlen after return is the number of octets produced. */ static int xmlIconvWrapper(iconv_t cd, unsigned char *out, int *outlen, @@ -1851,7 +1870,7 @@ xmlIconvWrapper(iconv_t cd, unsigned char *out, int *outlen, * @toUnicode : non-zero if toUnicode. 0 otherwise. * @out: a pointer to an array of bytes to store the result * @outlen: the length of @out - * @in: a pointer to an array of ISO Latin 1 chars + * @in: a pointer to an array of input bytes * @inlen: the length of @in * @flush: if true, indicates end of input * @@ -1863,7 +1882,7 @@ xmlIconvWrapper(iconv_t cd, unsigned char *out, int *outlen, * * The value of @inlen after return is the number of octets consumed * as the return value is positive, else unpredictable. - * The value of @outlen after return is the number of octets consumed. + * The value of @outlen after return is the number of octets produced. */ static int xmlUconvWrapper(uconv_t *cd, int toUnicode, unsigned char *out, int *outlen, @@ -1912,6 +1931,25 @@ xmlUconvWrapper(uconv_t *cd, int toUnicode, unsigned char *out, int *outlen, * * ************************************************************************/ +/** + * xmlEncInputChunk: + * @handler: encoding handler + * @out: a pointer to an array of bytes to store the result + * @outlen: the length of @out + * @in: a pointer to an array of input bytes + * @inlen: the length of @in + * @flush: flush (ICU-related) + * + * Returns 0 if success, or + * -1 by lack of space, or + * -2 if the transcoding fails (for *in is not valid utf8 string or + * the result of transformation can't fit into the encoding we want), or + * -3 if there the last byte can't form a single output char. + * + * The value of @inlen after return is the number of octets consumed + * as the return value is 0, else unpredictable. + * The value of @outlen after return is the number of octets produced. + */ static int xmlEncInputChunk(xmlCharEncodingHandler *handler, unsigned char *out, int *outlen, const unsigned char *in, int *inlen, int flush) { @@ -1920,6 +1958,8 @@ xmlEncInputChunk(xmlCharEncodingHandler *handler, unsigned char *out, if (handler->input != NULL) { ret = handler->input(out, outlen, in, inlen); + if (ret > 0) + ret = 0; } #ifdef LIBXML_ICONV_ENABLED else if (handler->iconv_in != NULL) { @@ -1941,7 +1981,25 @@ xmlEncInputChunk(xmlCharEncodingHandler *handler, unsigned char *out, return(ret); } -/* Returns -4 if no output function was found. */ +/** + * xmlEncOutputChunk: + * @handler: encoding handler + * @out: a pointer to an array of bytes to store the result + * @outlen: the length of @out + * @in: a pointer to an array of input bytes + * @inlen: the length of @in + * + * Returns 0 if success, or + * -1 by lack of space, or + * -2 if the transcoding fails (for *in is not valid utf8 string or + * the result of transformation can't fit into the encoding we want), or + * -3 if there the last byte can't form a single output char. + * -4 if no output function was found. + * + * The value of @inlen after return is the number of octets consumed + * as the return value is 0, else unpredictable. + * The value of @outlen after return is the number of octets produced. + */ static int xmlEncOutputChunk(xmlCharEncodingHandler *handler, unsigned char *out, int *outlen, const unsigned char *in, int *inlen) { @@ -1949,6 +2007,8 @@ xmlEncOutputChunk(xmlCharEncodingHandler *handler, unsigned char *out, if (handler->output != NULL) { ret = handler->output(out, outlen, in, inlen); + if (ret > 0) + ret = 0; } #ifdef LIBXML_ICONV_ENABLED else if (handler->iconv_out != NULL) { @@ -1958,7 +2018,7 @@ xmlEncOutputChunk(xmlCharEncodingHandler *handler, unsigned char *out, #ifdef LIBXML_ICU_ENABLED else if (handler->uconv_out != NULL) { ret = xmlUconvWrapper(handler->uconv_out, 0, out, outlen, in, inlen, - TRUE); + 1); } #endif /* LIBXML_ICU_ENABLED */ else { @@ -2054,7 +2114,7 @@ xmlCharEncFirstLineInt(xmlCharEncodingHandler *handler, xmlBufferPtr out, */ if (ret == -3) ret = 0; if (ret == -1) ret = 0; - return(ret); + return(written ? written : ret); } /** @@ -2184,7 +2244,7 @@ xmlCharEncFirstLineInput(xmlParserInputBufferPtr input, int len) */ if (ret == -3) ret = 0; if (ret == -1) ret = 0; - return(ret); + return(c_out ? c_out : ret); } /** @@ -2394,7 +2454,7 @@ xmlCharEncOutput(xmlOutputBufferPtr output, int init) { int ret; size_t written; - size_t writtentot = 0; + int writtentot = 0; size_t toconv; int c_in; int c_out; @@ -2427,7 +2487,7 @@ retry: xmlGenericError(xmlGenericErrorContext, "initialized encoder\n"); #endif - return(0); + return(c_out); } /* @@ -2540,7 +2600,7 @@ retry: goto retry; } } - return(ret); + return(writtentot ? writtentot : ret); } #endif @@ -2705,7 +2765,7 @@ retry: goto retry; } } - return(ret); + return(writtentot ? writtentot : ret); } /** diff --git a/sdk/lib/3rdparty/libxml2/entities.c b/sdk/lib/3rdparty/libxml2/entities.c index d575e9d177b..1a8f86f0dc2 100644 --- a/sdk/lib/3rdparty/libxml2/entities.c +++ b/sdk/lib/3rdparty/libxml2/entities.c @@ -71,7 +71,7 @@ static xmlEntity xmlEntityApos = { /** * xmlEntitiesErrMemory: - * @extra: extra informations + * @extra: extra information * * Handle an out of memory condition */ @@ -210,7 +210,7 @@ xmlAddEntity(xmlDtdPtr dtd, const xmlChar *name, int type, const xmlChar *content) { xmlDictPtr dict = NULL; xmlEntitiesTablePtr table = NULL; - xmlEntityPtr ret; + xmlEntityPtr ret, predef; if (name == NULL) return(NULL); @@ -223,6 +223,44 @@ xmlAddEntity(xmlDtdPtr dtd, const xmlChar *name, int type, case XML_INTERNAL_GENERAL_ENTITY: case XML_EXTERNAL_GENERAL_PARSED_ENTITY: case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY: + predef = xmlGetPredefinedEntity(name); + if (predef != NULL) { + int valid = 0; + + /* 4.6 Predefined Entities */ + if ((type == XML_INTERNAL_GENERAL_ENTITY) && + (content != NULL)) { + int c = predef->content[0]; + + if (((content[0] == c) && (content[1] == 0)) && + ((c == '>') || (c == '\'') || (c == '"'))) { + valid = 1; + } else if ((content[0] == '&') && (content[1] == '#')) { + if (content[2] == 'x') { + xmlChar *hex = BAD_CAST "0123456789ABCDEF"; + xmlChar ref[] = "00;"; + + ref[0] = hex[c / 16 % 16]; + ref[1] = hex[c % 16]; + if (xmlStrcasecmp(&content[3], ref) == 0) + valid = 1; + } else { + xmlChar ref[] = "00;"; + + ref[0] = '0' + c / 10 % 10; + ref[1] = '0' + c % 10; + if (xmlStrEqual(&content[2], ref)) + valid = 1; + } + } + } + if (!valid) { + xmlEntitiesErr(XML_ERR_ENTITY_PROCESSING, + "xmlAddEntity: invalid redeclaration of predefined" + " entity"); + return(NULL); + } + } if (dtd->entities == NULL) dtd->entities = xmlHashCreateDict(0, dict); table = dtd->entities; @@ -666,11 +704,25 @@ xmlEncodeEntitiesInternal(xmlDocPtr doc, const xmlChar *input, int attr) { } else { /* * We assume we have UTF-8 input. + * It must match either: + * 110xxxxx 10xxxxxx + * 1110xxxx 10xxxxxx 10xxxxxx + * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * That is: + * cur[0] is 11xxxxxx + * cur[1] is 10xxxxxx + * cur[2] is 10xxxxxx if cur[0] is 111xxxxx + * cur[3] is 10xxxxxx if cur[0] is 1111xxxx + * cur[0] is not 11111xxx */ char buf[11], *ptr; int val = 0, l = 1; - if (*cur < 0xC0) { + if (((cur[0] & 0xC0) != 0xC0) || + ((cur[1] & 0xC0) != 0x80) || + (((cur[0] & 0xE0) == 0xE0) && ((cur[2] & 0xC0) != 0x80)) || + (((cur[0] & 0xF0) == 0xF0) && ((cur[3] & 0xC0) != 0x80)) || + (((cur[0] & 0xF8) == 0xF8))) { xmlEntitiesErr(XML_CHECK_NOT_UTF8, "xmlEncodeEntities: input not UTF-8"); if (doc != NULL) diff --git a/sdk/lib/3rdparty/libxml2/error.c b/sdk/lib/3rdparty/libxml2/error.c index b7d5b36bc79..9ff1c2ba490 100644 --- a/sdk/lib/3rdparty/libxml2/error.c +++ b/sdk/lib/3rdparty/libxml2/error.c @@ -146,7 +146,7 @@ xmlSetStructuredErrorFunc(void *ctx, xmlStructuredErrorFunc handler) { * xmlParserPrintFileInfo: * @input: an xmlParserInputPtr input * - * Displays the associated file and line informations for the current input + * Displays the associated file and line information for the current input */ void @@ -557,6 +557,7 @@ __xmlRaiseError(xmlStructuredErrorFunc schannel, * of the usual "base" (doc->URL) for the node (bug 152623). */ xmlNodePtr prev = baseptr; + char *href = NULL; int inclcount = 0; while (prev != NULL) { if (prev->prev == NULL) @@ -564,21 +565,20 @@ __xmlRaiseError(xmlStructuredErrorFunc schannel, else { prev = prev->prev; if (prev->type == XML_XINCLUDE_START) { - if (--inclcount < 0) - break; + if (inclcount > 0) { + --inclcount; + } else { + href = (char *) xmlGetProp(prev, BAD_CAST "href"); + if (href != NULL) + break; + } } else if (prev->type == XML_XINCLUDE_END) inclcount++; } } - if (prev != NULL) { - if (prev->type == XML_XINCLUDE_START) { - prev->type = XML_ELEMENT_NODE; - to->file = (char *) xmlGetProp(prev, BAD_CAST "href"); - prev->type = XML_XINCLUDE_START; - } else { - to->file = (char *) xmlGetProp(prev, BAD_CAST "href"); - } - } else + if (href != NULL) + to->file = href; + else #endif to->file = (char *) xmlStrdup(baseptr->doc->URL); if ((to->file == NULL) && (node != NULL) && (node->doc != NULL)) { @@ -643,7 +643,7 @@ __xmlRaiseError(xmlStructuredErrorFunc schannel, * @domain: where the error comes from * @code: the error code * @node: the context node - * @extra: extra informations + * @extra: extra information * * Handle an out of memory condition */ diff --git a/sdk/lib/3rdparty/libxml2/globals.c b/sdk/lib/3rdparty/libxml2/globals.c index 7bf985f487a..0c0bdb44a83 100644 --- a/sdk/lib/3rdparty/libxml2/globals.c +++ b/sdk/lib/3rdparty/libxml2/globals.c @@ -215,7 +215,7 @@ int oldXMLWDcompatibility = 0; /* DEPRECATED */ /** * xmlParserDebugEntities: * - * Global setting, asking the parser to print out debugging informations. + * Global setting, asking the parser to print out debugging information. * while handling entities. * Disabled by default */ diff --git a/sdk/lib/3rdparty/libxml2/hash.c b/sdk/lib/3rdparty/libxml2/hash.c index a83d979b64a..afa094ef907 100644 --- a/sdk/lib/3rdparty/libxml2/hash.c +++ b/sdk/lib/3rdparty/libxml2/hash.c @@ -11,7 +11,7 @@ * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. * * Author: breese@users.sourceforge.net diff --git a/sdk/lib/3rdparty/libxml2/include/win32config.h b/sdk/lib/3rdparty/libxml2/include/win32config.h index ffbd7051280..54392f4961e 100644 --- a/sdk/lib/3rdparty/libxml2/include/win32config.h +++ b/sdk/lib/3rdparty/libxml2/include/win32config.h @@ -28,7 +28,7 @@ #endif /* - * Windows platforms may define except + * Windows platforms may define except */ #undef except @@ -37,9 +37,9 @@ #include #if defined(_MSC_VER) || defined(__BORLANDC__) /* MS C-runtime has functions which can be used in order to determine if - a given floating-point variable contains NaN, (+-)INF. These are + a given floating-point variable contains NaN, (+-)INF. These are preferred, because floating-point technology is considered proprietary - by MS and we can assume that their functions know more about their + by MS and we can assume that their functions know more about their oddities than we do. */ #include /* Bjorn Reese figured a quite nice construct for isinf() using the _fpclass diff --git a/sdk/lib/3rdparty/libxml2/list.c b/sdk/lib/3rdparty/libxml2/list.c index 24da6b1e9b6..20207155190 100644 --- a/sdk/lib/3rdparty/libxml2/list.c +++ b/sdk/lib/3rdparty/libxml2/list.c @@ -9,7 +9,7 @@ * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. * * Author: Gary.Pennington@uk.sun.com diff --git a/sdk/lib/3rdparty/libxml2/nanoftp.c b/sdk/lib/3rdparty/libxml2/nanoftp.c index 54fa026d1bc..18c1ce4377c 100644 --- a/sdk/lib/3rdparty/libxml2/nanoftp.c +++ b/sdk/lib/3rdparty/libxml2/nanoftp.c @@ -158,7 +158,7 @@ int have_ipv6(void) { /** * xmlFTPErrMemory: - * @extra: extra informations + * @extra: extra information * * Handle an out of memory condition */ @@ -172,7 +172,7 @@ xmlFTPErrMemory(const char *extra) * xmlNanoFTPInit: * * Initialize the FTP protocol layer. - * Currently it just checks for proxy informations, + * Currently it just checks for proxy information, * and get the hostname */ @@ -218,7 +218,7 @@ xmlNanoFTPInit(void) { /** * xmlNanoFTPCleanup: * - * Cleanup the FTP protocol layer. This cleanup proxy informations. + * Cleanup the FTP protocol layer. This cleanup proxy information. */ void @@ -250,7 +250,7 @@ xmlNanoFTPCleanup(void) { * @passwd: the proxy password * @type: the type of proxy 1 for using SITE, 2 for USER a@b * - * Setup the FTP proxy informations. + * Setup the FTP proxy information. * This can also be done by using ftp_proxy ftp_proxy_user and * ftp_proxy_password environment variables. */ @@ -412,7 +412,7 @@ xmlNanoFTPUpdateURL(void *ctx, const char *URL) { * (Re)Initialize the FTP Proxy context by parsing the URL and finding * the protocol host port it indicates. * Should be like ftp://myproxy/ or ftp://myproxy:3128/ - * A NULL URL cleans up proxy informations. + * A NULL URL cleans up proxy information. */ void @@ -1251,8 +1251,7 @@ xmlNanoFTPConnectTo(const char *server, int port) { xmlNanoFTPFreeCtxt(ctxt); return(NULL); } - if (port != 0) - ctxt->port = port; + ctxt->port = port; res = xmlNanoFTPConnect(ctxt); if (res < 0) { xmlNanoFTPFreeCtxt(ctxt); @@ -1268,7 +1267,7 @@ xmlNanoFTPConnectTo(const char *server, int port) { * * Tries to change the remote directory * - * Returns -1 incase of error, 1 if CWD worked, 0 if it failed + * Returns -1 in case of error, 1 if CWD worked, 0 if it failed */ int @@ -1317,7 +1316,7 @@ xmlNanoFTPCwd(void *ctx, const char *directory) { * * Tries to delete an item (file or directory) from server * - * Returns -1 incase of error, 1 if DELE worked, 0 if it failed + * Returns -1 in case of error, 1 if DELE worked, 0 if it failed */ int @@ -1367,7 +1366,7 @@ xmlNanoFTPDele(void *ctx, const char *file) { * Try to open a data connection to the server. Currently only * passive mode is supported. * - * Returns -1 incase of error, 0 otherwise + * Returns -1 in case of error, 0 otherwise */ SOCKET @@ -1540,7 +1539,7 @@ xmlNanoFTPGetConnection(void *ctx) { * * Close the data connection from the server * - * Returns -1 incase of error, 0 otherwise + * Returns -1 in case of error, 0 otherwise */ int @@ -1591,7 +1590,7 @@ xmlNanoFTPCloseConnection(void *ctx) { * * Parse at most one entry from the listing. * - * Returns -1 incase of error, the length of data parsed otherwise + * Returns -1 in case of error, the length of data parsed otherwise */ static int @@ -1719,7 +1718,7 @@ xmlNanoFTPParseList(const char *list, ftpListCallback callback, void *userData) * Do a listing on the server. All files info are passed back * in the callbacks. * - * Returns -1 incase of error, 0 otherwise + * Returns -1 in case of error, 0 otherwise */ int @@ -1894,7 +1893,7 @@ xmlNanoFTPGetSocket(void *ctx, const char *filename) { * Fetch the given file from the server. All data are passed back * in the callbacks. The last callback has a size of 0 block. * - * Returns -1 incase of error, 0 otherwise + * Returns -1 in case of error, 0 otherwise */ int @@ -2024,7 +2023,7 @@ xmlNanoFTPOpen(const char *URL) { * * Close the connection and both control and transport * - * Returns -1 incase of error, 0 otherwise + * Returns -1 in case of error, 0 otherwise */ int diff --git a/sdk/lib/3rdparty/libxml2/nanohttp.c b/sdk/lib/3rdparty/libxml2/nanohttp.c index 018b7e189b7..8e840f58b76 100644 --- a/sdk/lib/3rdparty/libxml2/nanohttp.c +++ b/sdk/lib/3rdparty/libxml2/nanohttp.c @@ -160,7 +160,7 @@ static int xmlNanoHTTPFetchContent( void * ctx, char ** ptr, int * len ); /** * xmlHTTPErrMemory: - * @extra: extra informations + * @extra: extra information * * Handle an out of memory condition */ @@ -213,7 +213,7 @@ int have_ipv6(void) { * xmlNanoHTTPInit: * * Initialize the HTTP protocol layer. - * Currently it just checks for proxy informations + * Currently it just checks for proxy information */ void @@ -344,7 +344,7 @@ xmlNanoHTTPScanURL(xmlNanoHTTPCtxtPtr ctxt, const char *URL) { * (Re)Initialize the HTTP Proxy context by parsing the URL and finding * the protocol host port it indicates. * Should be like http://myproxy/ or http://myproxy:3128/ - * A NULL URL cleans up proxy informations. + * A NULL URL cleans up proxy information. */ void @@ -650,7 +650,7 @@ xmlNanoHTTPRecv(xmlNanoHTTPCtxtPtr ctxt) * @ctxt: an HTTP context * * Read one line in the HTTP server output, usually for extracting - * the HTTP protocol informations from the answer header. + * the HTTP protocol information from the answer header. * * Returns a newly allocated string with a copy of the line, or NULL * which indicate the end of the input. @@ -693,7 +693,7 @@ xmlNanoHTTPReadLine(xmlNanoHTTPCtxtPtr ctxt) { * @ctxt: an HTTP context * @line: an HTTP header line * - * Try to extract useful informations from the server answer. + * Try to extract useful information from the server answer. * We currently parse and process: * - The HTTP revision/ return code * - The Content-Type, Mime-Type and charset used @@ -1625,7 +1625,7 @@ xmlNanoHTTPMethod(const char *URL, const char *method, const char *input, * This function try to fetch the indicated resource via HTTP GET * and save it's content in the file. * - * Returns -1 in case of failure, 0 incase of success. The contentType, + * Returns -1 in case of failure, 0 in case of success. The contentType, * if provided must be freed by the caller */ int @@ -1675,7 +1675,7 @@ xmlNanoHTTPFetch(const char *URL, const char *filename, char **contentType) { * This function saves the output of the HTTP transaction to a file * It closes and free the context at the end * - * Returns -1 in case of failure, 0 incase of success. + * Returns -1 in case of failure, 0 in case of success. */ int xmlNanoHTTPSave(void *ctxt, const char *filename) { diff --git a/sdk/lib/3rdparty/libxml2/parser.c b/sdk/lib/3rdparty/libxml2/parser.c index 6025c0ed19e..c9312fa48d9 100644 --- a/sdk/lib/3rdparty/libxml2/parser.c +++ b/sdk/lib/3rdparty/libxml2/parser.c @@ -87,6 +87,13 @@ #include "buf.h" #include "enc.h" +struct _xmlStartTag { + const xmlChar *prefix; + const xmlChar *URI; + int line; + int nsNr; +}; + static void xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info); @@ -133,6 +140,7 @@ xmlParserEntityCheck(xmlParserCtxtPtr ctxt, size_t size, xmlEntityPtr ent, size_t replacement) { size_t consumed = 0; + int i; if ((ctxt == NULL) || (ctxt->options & XML_PARSE_HUGE)) return (0); @@ -170,6 +178,28 @@ xmlParserEntityCheck(xmlParserCtxtPtr ctxt, size_t size, rep = NULL; } } + + /* + * Prevent entity exponential check, not just replacement while + * parsing the DTD + * The check is potentially costly so do that only once in a thousand + */ + if ((ctxt->instate == XML_PARSER_DTD) && (ctxt->nbentities > 10000) && + (ctxt->nbentities % 1024 == 0)) { + for (i = 0;i < ctxt->inputNr;i++) { + consumed += ctxt->inputTab[i]->consumed + + (ctxt->inputTab[i]->cur - ctxt->inputTab[i]->base); + } + if (ctxt->nbentities > consumed * XML_PARSER_NON_LINEAR) { + xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL); + ctxt->instate = XML_PARSER_EOF; + return (1); + } + consumed = 0; + } + + + if (replacement != 0) { if (replacement < XML_MAX_TEXT_LENGTH) return(0); @@ -1073,11 +1103,15 @@ xmlHasFeature(xmlFeature feature) */ static void xmlDetectSAX2(xmlParserCtxtPtr ctxt) { + xmlSAXHandlerPtr sax; if (ctxt == NULL) return; + sax = ctxt->sax; #ifdef LIBXML_SAX1_ENABLED - if ((ctxt->sax) && (ctxt->sax->initialized == XML_SAX2_MAGIC) && - ((ctxt->sax->startElementNs != NULL) || - (ctxt->sax->endElementNs != NULL))) ctxt->sax2 = 1; + if ((sax) && (sax->initialized == XML_SAX2_MAGIC) && + ((sax->startElementNs != NULL) || + (sax->endElementNs != NULL) || + ((sax->startElement == NULL) && (sax->endElement == NULL)))) + ctxt->sax2 = 1; #else ctxt->sax2 = 1; #endif /* LIBXML_SAX1_ENABLED */ @@ -1834,6 +1868,8 @@ nodePop(xmlParserCtxtPtr ctxt) * @value: the element name * @prefix: the element prefix * @URI: the element namespace name + * @line: the current line number for error messages + * @nsNr: the number of namespaces pushed on the namespace table * * Pushes a new element name/prefix/URL on top of the name stack * @@ -1841,11 +1877,13 @@ nodePop(xmlParserCtxtPtr ctxt) */ static int nameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value, - const xmlChar *prefix, const xmlChar *URI, int nsNr) + const xmlChar *prefix, const xmlChar *URI, int line, int nsNr) { + xmlStartTag *tag; + if (ctxt->nameNr >= ctxt->nameMax) { const xmlChar * *tmp; - void **tmp2; + xmlStartTag *tmp2; ctxt->nameMax *= 2; tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab, ctxt->nameMax * @@ -1855,8 +1893,8 @@ nameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value, goto mem_error; } ctxt->nameTab = tmp; - tmp2 = (void **) xmlRealloc((void * *)ctxt->pushTab, - ctxt->nameMax * 3 * + tmp2 = (xmlStartTag *) xmlRealloc((void * *)ctxt->pushTab, + ctxt->nameMax * sizeof(ctxt->pushTab[0])); if (tmp2 == NULL) { ctxt->nameMax /= 2; @@ -1864,16 +1902,18 @@ nameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value, } ctxt->pushTab = tmp2; } else if (ctxt->pushTab == NULL) { - ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 * + ctxt->pushTab = (xmlStartTag *) xmlMalloc(ctxt->nameMax * sizeof(ctxt->pushTab[0])); if (ctxt->pushTab == NULL) goto mem_error; } ctxt->nameTab[ctxt->nameNr] = value; ctxt->name = value; - ctxt->pushTab[ctxt->nameNr * 3] = (void *) prefix; - ctxt->pushTab[ctxt->nameNr * 3 + 1] = (void *) URI; - ctxt->pushTab[ctxt->nameNr * 3 + 2] = (void *) (ptrdiff_t) nsNr; + tag = &ctxt->pushTab[ctxt->nameNr]; + tag->prefix = prefix; + tag->URI = URI; + tag->line = line; + tag->nsNr = nsNr; return (ctxt->nameNr++); mem_error: xmlErrMemory(ctxt, NULL); @@ -2055,7 +2095,7 @@ static int spacePop(xmlParserCtxtPtr ctxt) { ((unsigned char *) s)[ 9 ] == c10 ) #define SKIP(val) do { \ - ctxt->nbChars += (val),ctxt->input->cur += (val),ctxt->input->col+=(val); \ + ctxt->input->cur += (val),ctxt->input->col+=(val); \ if (*ctxt->input->cur == 0) \ xmlParserInputGrow(ctxt->input, INPUT_CHUNK); \ } while (0) @@ -2066,7 +2106,6 @@ static int spacePop(xmlParserCtxtPtr ctxt) { if (*(ctxt->input->cur) == '\n') { \ ctxt->input->line++; ctxt->input->col = 1; \ } else ctxt->input->col++; \ - ctxt->nbChars++; \ ctxt->input->cur++; \ } \ if (*ctxt->input->cur == 0) \ @@ -2119,7 +2158,6 @@ static void xmlGROW (xmlParserCtxtPtr ctxt) { #define NEXT1 { \ ctxt->input->col++; \ ctxt->input->cur++; \ - ctxt->nbChars++; \ if (*ctxt->input->cur == 0) \ xmlParserInputGrow(ctxt->input, INPUT_CHUNK); \ } @@ -2156,7 +2194,7 @@ xmlSkipBlankChars(xmlParserCtxtPtr ctxt) { * It's Okay to use CUR/NEXT here since all the blanks are on * the ASCII range. */ - if ((ctxt->inputNr == 1) && (ctxt->instate != XML_PARSER_DTD)) { + if (ctxt->instate != XML_PARSER_DTD) { const xmlChar *cur; /* * if we are in the document content, go really fast @@ -2332,7 +2370,6 @@ xmlParseCharRef(xmlParserCtxtPtr ctxt) { if (RAW == ';') { /* on purpose to avoid reentrancy problems with NEXT and SKIP */ ctxt->input->col++; - ctxt->nbChars ++; ctxt->input->cur++; } } else if ((RAW == '&') && (NXT(1) == '#')) { @@ -2361,7 +2398,6 @@ xmlParseCharRef(xmlParserCtxtPtr ctxt) { if (RAW == ';') { /* on purpose to avoid reentrancy problems with NEXT and SKIP */ ctxt->input->col++; - ctxt->nbChars ++; ctxt->input->cur++; } } else { @@ -2646,7 +2682,8 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len, else c = 0; while ((c != 0) && (c != end) && /* non input consuming loop */ - (c != end2) && (c != end3)) { + (c != end2) && (c != end3) && + (ctxt->instate != XML_PARSER_EOF)) { if (c == 0) break; if ((c == '&') && (str[1] == '#')) { @@ -2683,8 +2720,10 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len, rep = xmlStringDecodeEntities(ctxt, ent->content, what, 0, 0, 0); ctxt->depth--; - if (rep == NULL) + if (rep == NULL) { + ent->content[0] = 0; goto int_error; + } current = rep; while (*current != 0) { /* non input consuming loop */ @@ -2739,8 +2778,11 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len, rep = xmlStringDecodeEntities(ctxt, ent->content, what, 0, 0, 0); ctxt->depth--; - if (rep == NULL) + if (rep == NULL) { + if (ent->content != NULL) + ent->content[0] = 0; goto int_error; + } current = rep; while (*current != 0) { /* non input consuming loop */ buffer[nbchars++] = *current++; @@ -3332,7 +3374,6 @@ xmlParseName(xmlParserCtxtPtr ctxt) { } ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count); ctxt->input->cur = in; - ctxt->nbChars += count; ctxt->input->col += count; if (ret == NULL) xmlErrMemory(ctxt, NULL); @@ -3455,7 +3496,6 @@ xmlParseNCName(xmlParserCtxtPtr ctxt) { } ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count); ctxt->input->cur = in; - ctxt->nbChars += count; ctxt->input->col += count; if (ret == NULL) { xmlErrMemory(ctxt, NULL); @@ -3492,10 +3532,10 @@ xmlParseNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *other) { while (*in != 0 && *in == *cmp) { ++in; ++cmp; - ctxt->input->col++; } if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) { /* success */ + ctxt->input->col += in - ctxt->input->cur; ctxt->input->cur = in; return (const xmlChar*) 1; } @@ -3911,7 +3951,6 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) { "AttValue length too long\n"); goto mem_error; } - if (c == 0) break; if (c == '&') { in_space = 0; if (NXT(1) == '#') { @@ -4206,6 +4245,7 @@ xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) { } count++; if (count > 50) { + SHRINK; GROW; count = 0; if (ctxt->instate == XML_PARSER_EOF) { @@ -4293,6 +4333,7 @@ xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) { buf[len++] = cur; count++; if (count > 50) { + SHRINK; GROW; count = 0; if (ctxt->instate == XML_PARSER_EOF) { @@ -4508,7 +4549,7 @@ get_more: if (ctxt->instate == XML_PARSER_EOF) return; in = ctxt->input->cur; - } while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09)); + } while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09) || (*in == 0x0a)); nbchar = 0; } ctxt->input->line = line; @@ -4573,6 +4614,7 @@ xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata) { } count++; if (count > 50) { + SHRINK; GROW; count = 0; if (ctxt->instate == XML_PARSER_EOF) @@ -4778,6 +4820,7 @@ xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf, count++; if (count > 50) { + SHRINK; GROW; count = 0; if (ctxt->instate == XML_PARSER_EOF) { @@ -4989,7 +5032,7 @@ get_more: ctxt->input->col++; goto get_more; } - } while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09)); + } while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09) || (*in == 0x0a)); xmlParseCommentComplex(ctxt, buf, len, size); ctxt->instate = state; return; @@ -5053,7 +5096,7 @@ xmlParsePITarget(xmlParserCtxtPtr ctxt) { * * * Occurs only if allowed by the user and if happening in the Misc - * part of the document before any doctype informations + * part of the document before any doctype information * This will add the given catalog to the parsing context in order * to be used if there is a resolution need further down in the document */ @@ -5188,6 +5231,7 @@ xmlParsePI(xmlParserCtxtPtr ctxt) { } count++; if (count > 50) { + SHRINK; GROW; if (ctxt->instate == XML_PARSER_EOF) { xmlFree(buf); @@ -6084,14 +6128,20 @@ xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt, int inputchk) { NEXT; if (elem == NULL) { ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR); - if (ret == NULL) return(NULL); + if (ret == NULL) { + xmlFreeDocElementContent(ctxt->myDoc, cur); + return(NULL); + } ret->c1 = cur; if (cur != NULL) cur->parent = ret; cur = ret; } else { n = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR); - if (n == NULL) return(NULL); + if (n == NULL) { + xmlFreeDocElementContent(ctxt->myDoc, ret); + return(NULL); + } n->c1 = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT); if (n->c1 != NULL) n->c1->parent = n; @@ -6194,6 +6244,8 @@ xmlParseElementChildrenContentDeclPriv(xmlParserCtxtPtr ctxt, int inputchk, SKIP_BLANKS; cur = ret = xmlParseElementChildrenContentDeclPriv(ctxt, inputid, depth + 1); + if (cur == NULL) + return(NULL); SKIP_BLANKS; GROW; } else { @@ -6327,6 +6379,11 @@ xmlParseElementChildrenContentDeclPriv(xmlParserCtxtPtr ctxt, int inputchk, SKIP_BLANKS; last = xmlParseElementChildrenContentDeclPriv(ctxt, inputid, depth + 1); + if (last == NULL) { + if (ret != NULL) + xmlFreeDocElementContent(ctxt->myDoc, ret); + return(NULL); + } SKIP_BLANKS; } else { elem = xmlParseName(ctxt); @@ -6852,6 +6909,7 @@ void xmlParseTextDecl(xmlParserCtxtPtr ctxt) { xmlChar *version; const xmlChar *encoding; + int oldstate; /* * We know that 'instate; + ctxt->instate = XML_PARSER_START; + if (SKIP_BLANKS == 0) { xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Space needed after 'instate = oldstate; return; } if ((encoding == NULL) && (ctxt->errNo == XML_ERR_OK)) { @@ -6909,6 +6972,8 @@ xmlParseTextDecl(xmlParserCtxtPtr ctxt) { MOVETO_ENDTAG(CUR_PTR); NEXT; } + + ctxt->instate = oldstate; } /** @@ -7146,6 +7211,7 @@ xmlParseReference(xmlParserCtxtPtr ctxt) { ent->checked |= 1; if (ret == XML_ERR_ENTITY_LOOP) { xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL); + xmlHaltParser(ctxt); xmlFreeNodeList(list); return; } @@ -7159,42 +7225,38 @@ xmlParseReference(xmlParserCtxtPtr ctxt) { (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY))&& (ent->children == NULL)) { ent->children = list; - if (ctxt->replaceEntities) { - /* - * Prune it directly in the generated document - * except for single text nodes. - */ - if (((list->type == XML_TEXT_NODE) && - (list->next == NULL)) || - (ctxt->parseMode == XML_PARSE_READER)) { - list->parent = (xmlNodePtr) ent; - list = NULL; - ent->owner = 1; - } else { - ent->owner = 0; - while (list != NULL) { - list->parent = (xmlNodePtr) ctxt->node; - list->doc = ctxt->myDoc; - if (list->next == NULL) - ent->last = list; - list = list->next; - } - list = ent->children; + /* + * Prune it directly in the generated document + * except for single text nodes. + */ + if ((ctxt->replaceEntities == 0) || + (ctxt->parseMode == XML_PARSE_READER) || + ((list->type == XML_TEXT_NODE) && + (list->next == NULL))) { + ent->owner = 1; + while (list != NULL) { + list->parent = (xmlNodePtr) ent; + xmlSetTreeDoc(list, ent->doc); + if (list->next == NULL) + ent->last = list; + list = list->next; + } + list = NULL; + } else { + ent->owner = 0; + while (list != NULL) { + list->parent = (xmlNodePtr) ctxt->node; + list->doc = ctxt->myDoc; + if (list->next == NULL) + ent->last = list; + list = list->next; + } + list = ent->children; #ifdef LIBXML_LEGACY_ENABLED - if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) - xmlAddEntityReference(ent, list, NULL); + if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) + xmlAddEntityReference(ent, list, NULL); #endif /* LIBXML_LEGACY_ENABLED */ - } - } else { - ent->owner = 1; - while (list != NULL) { - list->parent = (xmlNodePtr) ent; - xmlSetTreeDoc(list, ent->doc); - if (list->next == NULL) - ent->last = list; - list = list->next; - } - } + } } else { xmlFreeNodeList(list); list = NULL; @@ -7580,7 +7642,7 @@ xmlParseEntityRef(xmlParserCtxtPtr ctxt) { * not contain a <. */ else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) && - (ent != NULL) && + (ent != NULL) && (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY)) { if (((ent->checked & 1) || (ent->checked == 0)) && (ent->content != NULL) && (xmlStrchr(ent->content, '<'))) { @@ -7924,6 +7986,9 @@ xmlParsePEReference(xmlParserCtxtPtr ctxt) xmlChar start[4]; xmlCharEncoding enc; + if (xmlParserEntityCheck(ctxt, 0, entity, 0)) + return; + if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) && ((ctxt->options & XML_PARSE_NOENT) == 0) && ((ctxt->options & XML_PARSE_DTDVALID) == 0) && @@ -8629,7 +8694,7 @@ xmlParseEndTag1(xmlParserCtxtPtr ctxt, int line) { * */ if (name != (xmlChar*)1) { - if (name == NULL) name = BAD_CAST "unparseable"; + if (name == NULL) name = BAD_CAST "unparsable"; xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH, "Opening and ending tag mismatch: %s line %d and %s\n", ctxt->name, line, name); @@ -8822,6 +8887,7 @@ xmlParseQNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *name, } if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) { /* success */ + ctxt->input->col += in - ctxt->input->cur; ctxt->input->cur = in; return((const xmlChar*) 1); } @@ -9622,10 +9688,8 @@ done: */ static void -xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlChar *prefix, - const xmlChar *URI, int line, int nsNr, int tlen) { +xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlStartTag *tag) { const xmlChar *name; - size_t curLength; GROW; if ((RAW != '<') || (NXT(1) != '/')) { @@ -9634,24 +9698,10 @@ xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlChar *prefix, } SKIP(2); - curLength = ctxt->input->end - ctxt->input->cur; - if ((tlen > 0) && (curLength >= (size_t)tlen) && - (xmlStrncmp(ctxt->input->cur, ctxt->name, tlen) == 0)) { - if ((curLength >= (size_t)(tlen + 1)) && - (ctxt->input->cur[tlen] == '>')) { - ctxt->input->cur += tlen + 1; - ctxt->input->col += tlen + 1; - goto done; - } - ctxt->input->cur += tlen; - ctxt->input->col += tlen; - name = (xmlChar*)1; - } else { - if (prefix == NULL) - name = xmlParseNameAndCompare(ctxt, ctxt->name); - else - name = xmlParseQNameAndCompare(ctxt, ctxt->name, prefix); - } + if (tag->prefix == NULL) + name = xmlParseNameAndCompare(ctxt, ctxt->name); + else + name = xmlParseQNameAndCompare(ctxt, ctxt->name, tag->prefix); /* * We should definitely be at the ending "S? '>'" part @@ -9672,26 +9722,23 @@ xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlChar *prefix, * */ if (name != (xmlChar*)1) { - if (name == NULL) name = BAD_CAST "unparseable"; - if ((line == 0) && (ctxt->node != NULL)) - line = ctxt->node->line; + if (name == NULL) name = BAD_CAST "unparsable"; xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH, "Opening and ending tag mismatch: %s line %d and %s\n", - ctxt->name, line, name); + ctxt->name, tag->line, name); } /* * SAX: End of Tag */ -done: if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) && (!ctxt->disableSAX)) - ctxt->sax->endElementNs(ctxt->userData, ctxt->name, prefix, URI); + ctxt->sax->endElementNs(ctxt->userData, ctxt->name, tag->prefix, + tag->URI); spacePop(ctxt); - if (nsNr != 0) - nsPop(ctxt, nsNr); - return; + if (tag->nsNr != 0) + nsPop(ctxt, tag->nsNr); } /** @@ -9773,6 +9820,7 @@ xmlParseCDSect(xmlParserCtxtPtr ctxt) { sl = l; count++; if (count > 50) { + SHRINK; GROW; if (ctxt->instate == XML_PARSER_EOF) { xmlFree(buf); @@ -9806,16 +9854,15 @@ xmlParseCDSect(xmlParserCtxtPtr ctxt) { } /** - * xmlParseContent: + * xmlParseContentInternal: * @ctxt: an XML parser context * - * Parse a content: - * - * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)* + * Parse a content sequence. Stops at EOF or 'nameNr; GROW; @@ -9890,6 +9937,30 @@ xmlParseContent(xmlParserCtxtPtr ctxt) { } } +/** + * xmlParseContent: + * @ctxt: an XML parser context + * + * Parse a content sequence. Stops at EOF or 'nameNr; + + xmlParseContentInternal(ctxt); + + if ((ctxt->instate != XML_PARSER_EOF) && (ctxt->nameNr > nameNr)) { + const xmlChar *name = ctxt->nameTab[ctxt->nameNr - 1]; + int line = ctxt->pushTab[ctxt->nameNr - 1].line; + xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED, + "Premature end of data in tag %s line %d\n", + name, line, NULL); + } +} + /** * xmlParseElement: * @ctxt: an XML parser context @@ -9908,9 +9979,20 @@ void xmlParseElement(xmlParserCtxtPtr ctxt) { if (xmlParseElementStart(ctxt) != 0) return; - xmlParseContent(ctxt); + + xmlParseContentInternal(ctxt); if (ctxt->instate == XML_PARSER_EOF) return; + + if (CUR == 0) { + const xmlChar *name = ctxt->nameTab[ctxt->nameNr - 1]; + int line = ctxt->pushTab[ctxt->nameNr - 1].line; + xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED, + "Premature end of data in tag %s line %d\n", + name, line, NULL); + return; + } + xmlParseElementEnd(ctxt); } @@ -9969,12 +10051,7 @@ xmlParseElementStart(xmlParserCtxtPtr ctxt) { spacePop(ctxt); return(-1); } - if (ctxt->sax2) - nameNsPush(ctxt, name, prefix, URI, ctxt->nsNr - nsNr); -#ifdef LIBXML_SAX1_ENABLED - else - namePush(ctxt, name); -#endif /* LIBXML_SAX1_ENABLED */ + nameNsPush(ctxt, name, prefix, URI, line, ctxt->nsNr - nsNr); ret = ctxt->node; #ifdef LIBXML_VALID_ENABLED @@ -10067,10 +10144,7 @@ xmlParseElementEnd(xmlParserCtxtPtr ctxt) { * parse the end of tag: 'sax2) { - const xmlChar *prefix = ctxt->pushTab[ctxt->nameNr * 3 - 3]; - const xmlChar *URI = ctxt->pushTab[ctxt->nameNr * 3 - 2]; - int nsNr = (ptrdiff_t) ctxt->pushTab[ctxt->nameNr * 3 - 1]; - xmlParseEndTag2(ctxt, prefix, URI, 0, nsNr, 0); + xmlParseEndTag2(ctxt, &ctxt->pushTab[ctxt->nameNr - 1]); namePop(ctxt); } #ifdef LIBXML_SAX1_ENABLED @@ -11345,6 +11419,7 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) { const xmlChar *name; const xmlChar *prefix = NULL; const xmlChar *URI = NULL; + int line = ctxt->input->line; int nsNr = ctxt->nsNr; if ((avail < 2) && (ctxt->inputNr == 1)) @@ -11442,12 +11517,7 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) { nodePop(ctxt); spacePop(ctxt); } - if (ctxt->sax2) - nameNsPush(ctxt, name, prefix, URI, ctxt->nsNr - nsNr); -#ifdef LIBXML_SAX1_ENABLED - else - namePush(ctxt, name); -#endif /* LIBXML_SAX1_ENABLED */ + nameNsPush(ctxt, name, prefix, URI, line, ctxt->nsNr - nsNr); ctxt->instate = XML_PARSER_CONTENT; ctxt->progressive = 1; @@ -11564,11 +11634,7 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) { } } if (ctxt->sax2) { - xmlParseEndTag2(ctxt, - (void *) ctxt->pushTab[ctxt->nameNr * 3 - 3], - (void *) ctxt->pushTab[ctxt->nameNr * 3 - 2], 0, - (int) (ptrdiff_t) - ctxt->pushTab[ctxt->nameNr * 3 - 1], 0); + xmlParseEndTag2(ctxt, &ctxt->pushTab[ctxt->nameNr - 1]); nameNsPop(ctxt); } #ifdef LIBXML_SAX1_ENABLED @@ -12230,12 +12296,12 @@ xmldecl_done: } } res = xmlParserInputBufferPush(ctxt->input->buf, size, chunk); + xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur); if (res < 0) { ctxt->errNo = XML_PARSER_EOF; xmlHaltParser(ctxt); return (XML_PARSER_EOF); } - xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur); #ifdef DEBUG_PUSH xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size); #endif @@ -12250,6 +12316,7 @@ xmldecl_done: size_t current = ctxt->input->cur - ctxt->input->base; nbchars = xmlCharEncInput(in, terminate); + xmlBufSetInputBaseCur(in->buffer, ctxt->input, base, current); if (nbchars < 0) { /* TODO 2.6.0 */ xmlGenericError(xmlGenericErrorContext, @@ -12257,7 +12324,6 @@ xmldecl_done: xmlHaltParser(ctxt); return(XML_ERR_INVALID_ENCODING); } - xmlBufSetInputBaseCur(in->buffer, ctxt->input, base, current); } } } @@ -12895,196 +12961,28 @@ xmlParseDTD(const xmlChar *ExternalID, const xmlChar *SystemID) { int xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx, const xmlChar *URL, const xmlChar *ID, xmlNodePtr *lst) { - xmlParserCtxtPtr ctxt; - xmlDocPtr newDoc; - xmlNodePtr newRoot; - xmlSAXHandlerPtr oldsax = NULL; - int ret = 0; - xmlChar start[4]; - xmlCharEncoding enc; + void *userData; if (ctx == NULL) return(-1); - - if (((ctx->depth > 40) && ((ctx->options & XML_PARSE_HUGE) == 0)) || - (ctx->depth > 1024)) { - return(XML_ERR_ENTITY_LOOP); - } - - if (lst != NULL) - *lst = NULL; - if ((URL == NULL) && (ID == NULL)) - return(-1); - if (ctx->myDoc == NULL) /* @@ relax but check for dereferences */ - return(-1); - - ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, ctx); - if (ctxt == NULL) { - return(-1); - } - - oldsax = ctxt->sax; - ctxt->sax = ctx->sax; - xmlDetectSAX2(ctxt); - newDoc = xmlNewDoc(BAD_CAST "1.0"); - if (newDoc == NULL) { - xmlFreeParserCtxt(ctxt); - return(-1); - } - newDoc->properties = XML_DOC_INTERNAL; - if (ctx->myDoc->dict) { - newDoc->dict = ctx->myDoc->dict; - xmlDictReference(newDoc->dict); - } - if (ctx->myDoc != NULL) { - newDoc->intSubset = ctx->myDoc->intSubset; - newDoc->extSubset = ctx->myDoc->extSubset; - } - if (ctx->myDoc->URL != NULL) { - newDoc->URL = xmlStrdup(ctx->myDoc->URL); - } - newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL); - if (newRoot == NULL) { - ctxt->sax = oldsax; - xmlFreeParserCtxt(ctxt); - newDoc->intSubset = NULL; - newDoc->extSubset = NULL; - xmlFreeDoc(newDoc); - return(-1); - } - xmlAddChild((xmlNodePtr) newDoc, newRoot); - nodePush(ctxt, newDoc->children); - if (ctx->myDoc == NULL) { - ctxt->myDoc = newDoc; - } else { - ctxt->myDoc = ctx->myDoc; - newDoc->children->doc = ctx->myDoc; - } - /* - * Get the 4 first bytes and decode the charset - * if enc != XML_CHAR_ENCODING_NONE - * plug some encoding conversion routines. - */ - GROW - if ((ctxt->input->end - ctxt->input->cur) >= 4) { - start[0] = RAW; - start[1] = NXT(1); - start[2] = NXT(2); - start[3] = NXT(3); - enc = xmlDetectCharEncoding(start, 4); - if (enc != XML_CHAR_ENCODING_NONE) { - xmlSwitchEncoding(ctxt, enc); - } - } - - /* - * Parse a possible text declaration first - */ - if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) { - xmlParseTextDecl(ctxt); - /* - * An XML-1.0 document can't reference an entity not XML-1.0 - */ - if ((xmlStrEqual(ctx->version, BAD_CAST "1.0")) && - (!xmlStrEqual(ctxt->input->version, BAD_CAST "1.0"))) { - xmlFatalErrMsg(ctxt, XML_ERR_VERSION_MISMATCH, - "Version mismatch between document and entity\n"); - } - } - - /* - * If the user provided its own SAX callbacks then reuse the - * useData callback field, otherwise the expected setup in a + * If the user provided their own SAX callbacks, then reuse the + * userData callback field, otherwise the expected setup in a * DOM builder is to have userData == ctxt */ if (ctx->userData == ctx) - ctxt->userData = ctxt; + userData = NULL; else - ctxt->userData = ctx->userData; - - /* - * Doing validity checking on chunk doesn't make sense - */ - ctxt->instate = XML_PARSER_CONTENT; - ctxt->validate = ctx->validate; - ctxt->valid = ctx->valid; - ctxt->loadsubset = ctx->loadsubset; - ctxt->depth = ctx->depth + 1; - ctxt->replaceEntities = ctx->replaceEntities; - if (ctxt->validate) { - ctxt->vctxt.error = ctx->vctxt.error; - ctxt->vctxt.warning = ctx->vctxt.warning; - } else { - ctxt->vctxt.error = NULL; - ctxt->vctxt.warning = NULL; - } - ctxt->vctxt.nodeTab = NULL; - ctxt->vctxt.nodeNr = 0; - ctxt->vctxt.nodeMax = 0; - ctxt->vctxt.node = NULL; - if (ctxt->dict != NULL) xmlDictFree(ctxt->dict); - ctxt->dict = ctx->dict; - ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3); - ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5); - ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36); - ctxt->dictNames = ctx->dictNames; - ctxt->attsDefault = ctx->attsDefault; - ctxt->attsSpecial = ctx->attsSpecial; - ctxt->linenumbers = ctx->linenumbers; - - xmlParseContent(ctxt); - - ctx->validate = ctxt->validate; - ctx->valid = ctxt->valid; - if ((RAW == '<') && (NXT(1) == '/')) { - xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL); - } else if (RAW != 0) { - xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL); - } - if (ctxt->node != newDoc->children) { - xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL); - } - - if (!ctxt->wellFormed) { - if (ctxt->errNo == 0) - ret = 1; - else - ret = ctxt->errNo; - } else { - if (lst != NULL) { - xmlNodePtr cur; - - /* - * Return the newly created nodeset after unlinking it from - * they pseudo parent. - */ - cur = newDoc->children->children; - *lst = cur; - while (cur != NULL) { - cur->parent = NULL; - cur = cur->next; - } - newDoc->children->children = NULL; - } - ret = 0; - } - ctxt->sax = oldsax; - ctxt->dict = NULL; - ctxt->attsDefault = NULL; - ctxt->attsSpecial = NULL; - xmlFreeParserCtxt(ctxt); - newDoc->intSubset = NULL; - newDoc->extSubset = NULL; - xmlFreeDoc(newDoc); - - return(ret); + userData = ctx->userData; + return xmlParseExternalEntityPrivate(ctx->myDoc, ctx, ctx->sax, + userData, ctx->depth + 1, + URL, ID, lst); } /** * xmlParseExternalEntityPrivate: * @doc: the document the chunk pertains to * @oldctxt: the previous parser context if available - * @sax: the SAX handler bloc (possibly NULL) + * @sax: the SAX handler block (possibly NULL) * @user_data: The user data returned on SAX callbacks (possibly NULL) * @depth: Used for loop detection, use 0 * @URL: the URL for the entity to load @@ -13127,25 +13025,6 @@ xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt, ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, oldctxt); if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY); ctxt->userData = ctxt; - if (oldctxt != NULL) { - ctxt->_private = oldctxt->_private; - ctxt->loadsubset = oldctxt->loadsubset; - ctxt->validate = oldctxt->validate; - ctxt->external = oldctxt->external; - ctxt->record_info = oldctxt->record_info; - ctxt->node_seq.maximum = oldctxt->node_seq.maximum; - ctxt->node_seq.length = oldctxt->node_seq.length; - ctxt->node_seq.buffer = oldctxt->node_seq.buffer; - } else { - /* - * Doing validity checking on chunk without context - * doesn't make sense - */ - ctxt->_private = NULL; - ctxt->validate = 0; - ctxt->external = 2; - ctxt->loadsubset = 0; - } if (sax != NULL) { oldsax = ctxt->sax; ctxt->sax = sax; @@ -13155,28 +13034,25 @@ xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt, xmlDetectSAX2(ctxt); newDoc = xmlNewDoc(BAD_CAST "1.0"); if (newDoc == NULL) { - ctxt->node_seq.maximum = 0; - ctxt->node_seq.length = 0; - ctxt->node_seq.buffer = NULL; xmlFreeParserCtxt(ctxt); return(XML_ERR_INTERNAL_ERROR); } newDoc->properties = XML_DOC_INTERNAL; - newDoc->intSubset = doc->intSubset; - newDoc->extSubset = doc->extSubset; - newDoc->dict = doc->dict; - xmlDictReference(newDoc->dict); - - if (doc->URL != NULL) { - newDoc->URL = xmlStrdup(doc->URL); + if (doc) { + newDoc->intSubset = doc->intSubset; + newDoc->extSubset = doc->extSubset; + if (doc->dict) { + newDoc->dict = doc->dict; + xmlDictReference(newDoc->dict); + } + if (doc->URL != NULL) { + newDoc->URL = xmlStrdup(doc->URL); + } } newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL); if (newRoot == NULL) { if (sax != NULL) ctxt->sax = oldsax; - ctxt->node_seq.maximum = 0; - ctxt->node_seq.length = 0; - ctxt->node_seq.buffer = NULL; xmlFreeParserCtxt(ctxt); newDoc->intSubset = NULL; newDoc->extSubset = NULL; @@ -13185,8 +13061,12 @@ xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt, } xmlAddChild((xmlNodePtr) newDoc, newRoot); nodePush(ctxt, newDoc->children); - ctxt->myDoc = doc; - newRoot->doc = doc; + if (doc == NULL) { + ctxt->myDoc = newDoc; + } else { + ctxt->myDoc = doc; + newRoot->doc = doc; + } /* * Get the 4 first bytes and decode the charset @@ -13210,10 +13090,53 @@ xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt, */ if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) { xmlParseTextDecl(ctxt); + /* + * An XML-1.0 document can't reference an entity not XML-1.0 + */ + if ((xmlStrEqual(oldctxt->version, BAD_CAST "1.0")) && + (!xmlStrEqual(ctxt->input->version, BAD_CAST "1.0"))) { + xmlFatalErrMsg(ctxt, XML_ERR_VERSION_MISMATCH, + "Version mismatch between document and entity\n"); + } } ctxt->instate = XML_PARSER_CONTENT; ctxt->depth = depth; + if (oldctxt != NULL) { + ctxt->_private = oldctxt->_private; + ctxt->loadsubset = oldctxt->loadsubset; + ctxt->validate = oldctxt->validate; + ctxt->valid = oldctxt->valid; + ctxt->replaceEntities = oldctxt->replaceEntities; + if (oldctxt->validate) { + ctxt->vctxt.error = oldctxt->vctxt.error; + ctxt->vctxt.warning = oldctxt->vctxt.warning; + ctxt->vctxt.userData = oldctxt->vctxt.userData; + } + ctxt->external = oldctxt->external; + if (ctxt->dict) xmlDictFree(ctxt->dict); + ctxt->dict = oldctxt->dict; + ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3); + ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5); + ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36); + ctxt->dictNames = oldctxt->dictNames; + ctxt->attsDefault = oldctxt->attsDefault; + ctxt->attsSpecial = oldctxt->attsSpecial; + ctxt->linenumbers = oldctxt->linenumbers; + ctxt->record_info = oldctxt->record_info; + ctxt->node_seq.maximum = oldctxt->node_seq.maximum; + ctxt->node_seq.length = oldctxt->node_seq.length; + ctxt->node_seq.buffer = oldctxt->node_seq.buffer; + } else { + /* + * Doing validity checking on chunk without context + * doesn't make sense + */ + ctxt->_private = NULL; + ctxt->validate = 0; + ctxt->external = 2; + ctxt->loadsubset = 0; + } xmlParseContent(ctxt); @@ -13273,6 +13196,11 @@ xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt, if (sax != NULL) ctxt->sax = oldsax; if (oldctxt != NULL) { + ctxt->dict = NULL; + ctxt->attsDefault = NULL; + ctxt->attsSpecial = NULL; + oldctxt->validate = ctxt->validate; + oldctxt->valid = ctxt->valid; oldctxt->node_seq.maximum = ctxt->node_seq.maximum; oldctxt->node_seq.length = ctxt->node_seq.length; oldctxt->node_seq.buffer = ctxt->node_seq.buffer; @@ -13292,7 +13220,7 @@ xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt, /** * xmlParseExternalEntity: * @doc: the document the chunk pertains to - * @sax: the SAX handler bloc (possibly NULL) + * @sax: the SAX handler block (possibly NULL) * @user_data: The user data returned on SAX callbacks (possibly NULL) * @depth: Used for loop detection, use 0 * @URL: the URL for the entity to load @@ -13318,8 +13246,8 @@ xmlParseExternalEntity(xmlDocPtr doc, xmlSAXHandlerPtr sax, void *user_data, /** * xmlParseBalancedChunkMemory: - * @doc: the document the chunk pertains to - * @sax: the SAX handler bloc (possibly NULL) + * @doc: the document the chunk pertains to (must not be NULL) + * @sax: the SAX handler block (possibly NULL) * @user_data: The user data returned on SAX callbacks (possibly NULL) * @depth: Used for loop detection, use 0 * @string: the input string in UTF8 or ISO-Latin (zero terminated) @@ -13770,8 +13698,8 @@ xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen, #ifdef LIBXML_SAX1_ENABLED /** * xmlParseBalancedChunkMemoryRecover: - * @doc: the document the chunk pertains to - * @sax: the SAX handler bloc (possibly NULL) + * @doc: the document the chunk pertains to (must not be NULL) + * @sax: the SAX handler block (possibly NULL) * @user_data: The user data returned on SAX callbacks (possibly NULL) * @depth: Used for loop detection, use 0 * @string: the input string in UTF8 or ISO-Latin (zero terminated) @@ -13842,6 +13770,7 @@ xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax, } else { xmlCtxtUseOptionsInternal(ctxt, XML_PARSE_NODICT, NULL); } + /* doc == NULL is only supported for historic reasons */ if (doc != NULL) { newDoc->intSubset = doc->intSubset; newDoc->extSubset = doc->extSubset; @@ -13858,6 +13787,7 @@ xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax, } xmlAddChild((xmlNodePtr) newDoc, newRoot); nodePush(ctxt, newRoot); + /* doc == NULL is only supported for historic reasons */ if (doc == NULL) { ctxt->myDoc = newDoc; } else { @@ -13927,8 +13857,8 @@ xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax, xmlFreeParserCtxt(ctxt); newDoc->intSubset = NULL; newDoc->extSubset = NULL; - if(doc != NULL) - newDoc->oldNs = NULL; + /* This leaks the namespace list if doc == NULL */ + newDoc->oldNs = NULL; xmlFreeDoc(newDoc); return(ret); @@ -14210,7 +14140,7 @@ xmlSAXParseFileWithData(xmlSAXHandlerPtr sax, const char *filename, if ((ctxt->wellFormed) || recovery) { ret = ctxt->myDoc; - if (ret != NULL) { + if ((ret != NULL) && (ctxt->input->buf != NULL)) { if (ctxt->input->buf->compressed > 0) ret->compression = 9; else @@ -14741,6 +14671,10 @@ xmlInitParser(void) { if (xmlParserInitialized != 0) return; +#if defined(_WIN32) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL)) + atexit(xmlCleanupParser); +#endif + #ifdef LIBXML_THREAD_ENABLED __xmlGlobalInitMutexLock(); if (xmlParserInitialized == 0) { @@ -14819,6 +14753,20 @@ xmlCleanupParser(void) { xmlParserInitialized = 0; } +#if defined(HAVE_ATTRIBUTE_DESTRUCTOR) && !defined(LIBXML_STATIC) && \ + !defined(_WIN32) +static void +ATTRIBUTE_DESTRUCTOR +xmlDestructor(void) { + /* + * Calling custom deallocation functions in a destructor can cause + * problems, for example with Nokogiri. + */ + if (xmlFree == free) + xmlCleanupParser(); +} +#endif + /************************************************************************ * * * New set (2.6.0) of simpler and more flexible APIs * @@ -14907,7 +14855,6 @@ xmlCtxtReset(xmlParserCtxtPtr ctxt) ctxt->vctxt.warning = xmlParserValidityWarning; #endif ctxt->record_info = 0; - ctxt->nbChars = 0; ctxt->checkIndex = 0; ctxt->inSubset = 0; ctxt->errNo = XML_ERR_OK; diff --git a/sdk/lib/3rdparty/libxml2/parserInternals.c b/sdk/lib/3rdparty/libxml2/parserInternals.c index b00cd08ec27..cbcfde0e6e7 100644 --- a/sdk/lib/3rdparty/libxml2/parserInternals.c +++ b/sdk/lib/3rdparty/libxml2/parserInternals.c @@ -105,7 +105,7 @@ xmlCheckVersion(int version) { /** * xmlErrMemory: * @ctxt: an XML parser context - * @extra: extra informations + * @extra: extra information * * Handle a redefinition of attribute error */ @@ -165,7 +165,7 @@ __xmlErrEncoding(xmlParserCtxtPtr ctxt, xmlParserErrors xmlerr, * xmlErrInternal: * @ctxt: an XML parser context * @msg: the error message - * @str: error informations + * @str: error information * * Handle an internal error */ @@ -519,8 +519,6 @@ xmlNextChar(xmlParserCtxtPtr ctxt) } else /* 1-byte code */ ctxt->input->cur++; - - ctxt->nbChars++; } else { /* * Assume it's a fixed length encoding (1) with @@ -533,7 +531,6 @@ xmlNextChar(xmlParserCtxtPtr ctxt) } else ctxt->input->col++; ctxt->input->cur++; - ctxt->nbChars++; } if (*ctxt->input->cur == 0) xmlParserInputGrow(ctxt->input, INPUT_CHUNK); @@ -677,7 +674,6 @@ xmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) { } if (*ctxt->input->cur == 0xD) { if (ctxt->input->cur[1] == 0xA) { - ctxt->nbChars++; ctxt->input->cur++; } return(0xA); @@ -693,7 +689,6 @@ xmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) { *len = 1; if (*ctxt->input->cur == 0xD) { if (ctxt->input->cur[1] == 0xA) { - ctxt->nbChars++; ctxt->input->cur++; } return(0xA); @@ -1158,6 +1153,11 @@ xmlSwitchInputEncodingInt(xmlParserCtxtPtr ctxt, xmlParserInputPtr input, * Note: this is a bit dangerous, but that's what it * takes to use nearly compatible signature for different * encodings. + * + * FIXME: Encoders might buffer partial byte sequences, so + * this probably can't work. We should return an error and + * make sure that callers never try to switch the encoding + * twice. */ xmlCharEncCloseFunc(input->buf->encoder); input->buf->encoder = handler; @@ -1748,7 +1748,6 @@ xmlInitParserCtxt(xmlParserCtxtPtr ctxt) ctxt->options |= XML_PARSE_NOENT; } ctxt->record_info = 0; - ctxt->nbChars = 0; ctxt->checkIndex = 0; ctxt->inSubset = 0; ctxt->errNo = XML_ERR_OK; @@ -1877,7 +1876,7 @@ xmlNewParserCtxt(void) /************************************************************************ * * - * Handling of node informations * + * Handling of node information * * * ************************************************************************/ diff --git a/sdk/lib/3rdparty/libxml2/relaxng.c b/sdk/lib/3rdparty/libxml2/relaxng.c index 13fd954c7dd..0ceecb58497 100644 --- a/sdk/lib/3rdparty/libxml2/relaxng.c +++ b/sdk/lib/3rdparty/libxml2/relaxng.c @@ -430,7 +430,7 @@ struct _xmlRelaxNGDocument { /** * xmlRngPErrMemory: * @ctxt: an Relax-NG parser context - * @extra: extra informations + * @extra: extra information * * Handle a redefinition of attribute error */ @@ -465,7 +465,7 @@ xmlRngPErrMemory(xmlRelaxNGParserCtxtPtr ctxt, const char *extra) /** * xmlRngVErrMemory: * @ctxt: a Relax-NG validation context - * @extra: extra informations + * @extra: extra information * * Handle a redefinition of attribute error */ @@ -1409,7 +1409,7 @@ xmlRelaxNGFreeValidState(xmlRelaxNGValidCtxtPtr ctxt, * @ctxt: a RelaxNG parser context * @flags: a set of flags values * - * Semi private function used to pass informations to a parser context + * Semi private function used to pass information to a parser context * which are a combination of xmlRelaxNGParserFlag . * * Returns 0 if success and -1 in case of error @@ -8165,7 +8165,7 @@ xmlRelaxNGElemPop(xmlRelaxNGValidCtxtPtr ctxt) @ @inputdata: callback data, the Relax NG validation context * * Handle the callback and if needed validate the element children. - * some of the in/out informations are passed via the context in @inputdata. + * some of the in/out information are passed via the context in @inputdata. */ static void xmlRelaxNGValidateProgressiveCallback(xmlRegExecCtxtPtr exec @@ -11000,7 +11000,7 @@ xmlRelaxNGFreeValidCtxt(xmlRelaxNGValidCtxtPtr ctxt) * @warn: the warning function * @ctx: the functions context * - * Set the error and warning callback informations + * Set the error and warning callback information */ void xmlRelaxNGSetValidErrors(xmlRelaxNGValidCtxtPtr ctxt, @@ -11042,7 +11042,7 @@ xmlRelaxNGSetValidStructuredErrors(xmlRelaxNGValidCtxtPtr ctxt, * @warn: the warning function result * @ctx: the functions context result * - * Get the error and warning callback informations + * Get the error and warning callback information * * Returns -1 in case of error and 0 otherwise */ diff --git a/sdk/lib/3rdparty/libxml2/schematron.c b/sdk/lib/3rdparty/libxml2/schematron.c index 258ce4091f0..ddbb069b129 100644 --- a/sdk/lib/3rdparty/libxml2/schematron.c +++ b/sdk/lib/3rdparty/libxml2/schematron.c @@ -220,7 +220,7 @@ struct _xmlSchematronParserCtxt { /** * xmlSchematronPErrMemory: * @node: a context node - * @extra: extra informations + * @extra: extra information * * Handle an out of memory condition */ @@ -268,7 +268,7 @@ xmlSchematronPErr(xmlSchematronParserCtxtPtr ctxt, xmlNodePtr node, int error, /** * xmlSchematronVTypeErrMemory: * @node: a context node - * @extra: extra informations + * @extra: extra information * * Handle an out of memory condition */ diff --git a/sdk/lib/3rdparty/libxml2/threads.c b/sdk/lib/3rdparty/libxml2/threads.c index 72df9ba9979..503d2bfbec0 100644 --- a/sdk/lib/3rdparty/libxml2/threads.c +++ b/sdk/lib/3rdparty/libxml2/threads.c @@ -885,8 +885,6 @@ xmlInitThreads(void) } } #endif /* XML_PTHREAD_WEAK */ -#elif defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL)) - InitializeCriticalSection(&cleanup_helpers_cs); #endif } @@ -958,6 +956,9 @@ xmlOnceInit(void) if (!run_once.done) { if (InterlockedIncrement(&run_once.control) == 1) { #if !defined(HAVE_COMPILER_TLS) +#if !defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL) + InitializeCriticalSection(&cleanup_helpers_cs); +#endif globalkey = TlsAlloc(); #endif mainthread = GetCurrentThreadId(); diff --git a/sdk/lib/3rdparty/libxml2/tree.c b/sdk/lib/3rdparty/libxml2/tree.c index 08b1a5004df..c707f598e8d 100644 --- a/sdk/lib/3rdparty/libxml2/tree.c +++ b/sdk/lib/3rdparty/libxml2/tree.c @@ -70,7 +70,7 @@ static xmlChar* xmlGetPropNodeValueInternal(const xmlAttr *prop); ************************************************************************/ /** * xmlTreeErrMemory: - * @extra: extra informations + * @extra: extra information * * Handle an out of memory condition */ @@ -83,7 +83,7 @@ xmlTreeErrMemory(const char *extra) /** * xmlTreeErr: * @code: the error number - * @extra: extra informations + * @extra: extra information * * Handle an out of memory condition */ @@ -1064,7 +1064,7 @@ xmlCreateIntSubset(xmlDocPtr doc, const xmlChar *name, * @str: a string * * Copy a string using a "dict" dictionary in the current scope, - * if availabe. + * if available. */ #define DICT_COPY(str, cpy) \ if (str) { \ @@ -1081,7 +1081,7 @@ xmlCreateIntSubset(xmlDocPtr doc, const xmlChar *name, * @str: a string * * Copy a string using a "dict" dictionary in the current scope, - * if availabe. + * if available. */ #define DICT_CONST_COPY(str, cpy) \ if (str) { \ @@ -1276,12 +1276,14 @@ xmlStringLenGetNodeList(const xmlDoc *doc, const xmlChar *value, int len) { xmlNodePtr ret = NULL, last = NULL; xmlNodePtr node; xmlChar *val; - const xmlChar *cur = value, *end = cur + len; + const xmlChar *cur, *end; const xmlChar *q; xmlEntityPtr ent; xmlBufPtr buf; if (value == NULL) return(NULL); + cur = value; + end = cur + len; buf = xmlBufCreateSize(0); if (buf == NULL) return(NULL); @@ -1308,6 +1310,16 @@ xmlStringLenGetNodeList(const xmlDoc *doc, const xmlChar *value, int len) { else tmp = 0; while (tmp != ';') { /* Non input consuming loop */ + /* + * If you find an integer overflow here when fuzzing, + * the bug is probably elsewhere. This function should + * only receive entities that were already validated by + * the parser, typically by xmlParseAttValueComplex + * calling xmlStringDecodeEntities. + * + * So it's better *not* to check for overflow to + * potentially discover new bugs. + */ if ((tmp >= '0') && (tmp <= '9')) charval = charval * 16 + (tmp - '0'); else if ((tmp >= 'a') && (tmp <= 'f')) @@ -1336,6 +1348,7 @@ xmlStringLenGetNodeList(const xmlDoc *doc, const xmlChar *value, int len) { else tmp = 0; while (tmp != ';') { /* Non input consuming loops */ + /* Don't check for integer overflow, see above. */ if ((tmp >= '0') && (tmp <= '9')) charval = charval * 10 + (tmp - '0'); else { @@ -1515,6 +1528,7 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) { cur += 3; tmp = *cur; while (tmp != ';') { /* Non input consuming loop */ + /* Don't check for integer overflow, see above. */ if ((tmp >= '0') && (tmp <= '9')) charval = charval * 16 + (tmp - '0'); else if ((tmp >= 'a') && (tmp <= 'f')) @@ -1537,6 +1551,7 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) { cur += 2; tmp = *cur; while (tmp != ';') { /* Non input consuming loops */ + /* Don't check for integer overflow, see above. */ if ((tmp >= '0') && (tmp <= '9')) charval = charval * 10 + (tmp - '0'); else { @@ -1647,6 +1662,10 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) { if (!xmlBufIsEmpty(buf)) { node = xmlNewDocText(doc, NULL); + if (node == NULL) { + xmlBufFree(buf); + return(NULL); + } node->content = xmlBufDetach(buf); if (last == NULL) { @@ -1882,12 +1901,6 @@ xmlNewPropInternal(xmlNodePtr node, xmlNsPtr ns, if (value != NULL) { xmlNodePtr tmp; - if(!xmlCheckUTF8(value)) { - xmlTreeErr(XML_TREE_NOT_UTF8, (xmlNodePtr) doc, - NULL); - if (doc != NULL) - doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1"); - } cur->children = xmlNewDocText(doc, value); cur->last = NULL; tmp = cur->children; @@ -2007,6 +2020,11 @@ xmlNewNsPropEatName(xmlNodePtr node, xmlNsPtr ns, xmlChar *name, * @value: the value of the attribute * * Create a new property carried by a document. + * NOTE: @value is supposed to be a piece of XML CDATA, so it allows entity + * references, but XML special chars need to be escaped first by using + * xmlEncodeEntitiesReentrant(). Use xmlNewProp() if you don't need + * entities support. + * * Returns a pointer to the attribute */ xmlAttrPtr @@ -3706,6 +3724,11 @@ xmlFreeNodeList(xmlNodePtr cur) { (cur->type != XML_XINCLUDE_START) && (cur->type != XML_XINCLUDE_END) && (cur->type != XML_ENTITY_REF_NODE) && + (cur->type != XML_DOCUMENT_NODE) && +#ifdef LIBXML_DOCB_ENABLED + (cur->type != XML_DOCB_DOCUMENT_NODE) && +#endif + (cur->type != XML_HTML_DOCUMENT_NODE) && (cur->content != (xmlChar *) &(cur->properties))) { DICT_FREE(cur->content) } @@ -4066,7 +4089,7 @@ xmlCopyPropInternal(xmlDocPtr doc, xmlNodePtr target, xmlAttrPtr cur) { } else { /* * we have to find something appropriate here since - * we cant be sure, that the namespace we found is identified + * we can't be sure, that the namespace we found is identified * by the prefix */ if (xmlStrEqual(ns->href, cur->ns->href)) { @@ -4547,6 +4570,7 @@ xmlCopyDoc(xmlDocPtr doc, int recursive) { if (doc == NULL) return(NULL); ret = xmlNewDoc(doc->version); if (ret == NULL) return(NULL); + ret->type = doc->type; if (doc->name != NULL) ret->name = xmlMemStrdup(doc->name); if (doc->encoding != NULL) @@ -4869,7 +4893,9 @@ xmlGetNodePath(const xmlNode *node) } next = ((xmlAttrPtr) cur)->parent; } else { - next = cur->parent; + xmlFree(buf); + xmlFree(buffer); + return (NULL); } /* @@ -6564,6 +6590,16 @@ xmlGetPropNodeInternal(const xmlNode *node, const xmlChar *name, attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, elemQName, name, NULL); } + } else if (xmlStrEqual(nsName, XML_XML_NAMESPACE)) { + /* + * The XML namespace must be bound to prefix 'xml'. + */ + attrDecl = xmlGetDtdQAttrDesc(doc->intSubset, + elemQName, name, BAD_CAST "xml"); + if ((attrDecl == NULL) && (doc->extSubset != NULL)) { + attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, + elemQName, name, BAD_CAST "xml"); + } } else { xmlNsPtr *nsList, *cur; @@ -6910,12 +6946,6 @@ xmlSetNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name, if (value != NULL) { xmlNodePtr tmp; - if(!xmlCheckUTF8(value)) { - xmlTreeErr(XML_TREE_NOT_UTF8, (xmlNodePtr) node->doc, - NULL); - if (node->doc != NULL) - node->doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1"); - } prop->children = xmlNewDocText(node->doc, value); prop->last = NULL; tmp = prop->children; @@ -7243,7 +7273,7 @@ xmlBufferShrink(xmlBufferPtr buf, unsigned int len) { ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL))) { /* * we just move the content pointer, but also make sure - * the perceived buffer size has shrinked accordingly + * the perceived buffer size has shrunk accordingly */ buf->content += len; buf->size -= len; @@ -7417,12 +7447,17 @@ xmlBufferResize(xmlBufferPtr buf, unsigned int size) if (size < buf->size) return 1; + if (size > UINT_MAX - 10) { + xmlTreeErrMemory("growing buffer"); + return 0; + } + /* figure out new size */ switch (buf->alloc){ case XML_BUFFER_ALLOC_IO: case XML_BUFFER_ALLOC_DOUBLEIT: /*take care of empty case*/ - newSize = (buf->size ? buf->size*2 : size + 10); + newSize = (buf->size ? buf->size : size + 10); while (size > newSize) { if (newSize > UINT_MAX / 2) { xmlTreeErrMemory("growing buffer"); @@ -7438,7 +7473,7 @@ xmlBufferResize(xmlBufferPtr buf, unsigned int size) if (buf->use < BASE_BUFFER_SIZE) newSize = size; else { - newSize = buf->size * 2; + newSize = buf->size; while (size > newSize) { if (newSize > UINT_MAX / 2) { xmlTreeErrMemory("growing buffer"); @@ -7595,7 +7630,7 @@ xmlBufferAddHead(xmlBufferPtr buf, const xmlChar *str, int len) { if (start_buf > (unsigned int) len) { /* - * We can add it in the space previously shrinked + * We can add it in the space previously shrunk */ buf->content -= len; memmove(&buf->content[0], str, len); diff --git a/sdk/lib/3rdparty/libxml2/trio.c b/sdk/lib/3rdparty/libxml2/trio.c index f7a0da66013..ee270bc668c 100644 --- a/sdk/lib/3rdparty/libxml2/trio.c +++ b/sdk/lib/3rdparty/libxml2/trio.c @@ -10,7 +10,7 @@ * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. * ************************************************************************* diff --git a/sdk/lib/3rdparty/libxml2/trio.h b/sdk/lib/3rdparty/libxml2/trio.h index 99d212734a6..dcf96b6311a 100644 --- a/sdk/lib/3rdparty/libxml2/trio.h +++ b/sdk/lib/3rdparty/libxml2/trio.h @@ -10,7 +10,7 @@ * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. * ************************************************************************* diff --git a/sdk/lib/3rdparty/libxml2/triodef.h b/sdk/lib/3rdparty/libxml2/triodef.h index 46772ee2aed..e101f6df560 100644 --- a/sdk/lib/3rdparty/libxml2/triodef.h +++ b/sdk/lib/3rdparty/libxml2/triodef.h @@ -10,7 +10,7 @@ * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. * ************************************************************************/ diff --git a/sdk/lib/3rdparty/libxml2/trionan.c b/sdk/lib/3rdparty/libxml2/trionan.c index f6358a3f97a..7c1770e88bd 100644 --- a/sdk/lib/3rdparty/libxml2/trionan.c +++ b/sdk/lib/3rdparty/libxml2/trionan.c @@ -10,7 +10,7 @@ * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. * ************************************************************************ @@ -123,8 +123,8 @@ static TRIO_CONST char rcsid[] = "@(#)$Id$"; * integer, becomes 0x0706050403020100 (we could have used a 64-bit * integer value instead of a double, but not all platforms supports * that type). The value is automatically encoded with the correct - * endianess by the compiler, which means that we can support any - * kind of endianess. The individual bytes are then used as an index + * endianness by the compiler, which means that we can support any + * kind of endianness. The individual bytes are then used as an index * for the IEEE 754 bit-patterns and masks. */ #define TRIO_DOUBLE_INDEX(x) (((unsigned char *)&internalEndianMagic)[7-(x)]) diff --git a/sdk/lib/3rdparty/libxml2/trionan.h b/sdk/lib/3rdparty/libxml2/trionan.h index be6e718ac22..eac0e6f1686 100644 --- a/sdk/lib/3rdparty/libxml2/trionan.h +++ b/sdk/lib/3rdparty/libxml2/trionan.h @@ -10,7 +10,7 @@ * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. * ************************************************************************/ diff --git a/sdk/lib/3rdparty/libxml2/triop.h b/sdk/lib/3rdparty/libxml2/triop.h index 8462c56f877..6d486f865c6 100644 --- a/sdk/lib/3rdparty/libxml2/triop.h +++ b/sdk/lib/3rdparty/libxml2/triop.h @@ -10,7 +10,7 @@ * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. * ************************************************************************ diff --git a/sdk/lib/3rdparty/libxml2/triostr.c b/sdk/lib/3rdparty/libxml2/triostr.c index 123bbebee24..5937a44cf1b 100644 --- a/sdk/lib/3rdparty/libxml2/triostr.c +++ b/sdk/lib/3rdparty/libxml2/triostr.c @@ -10,7 +10,7 @@ * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. * ************************************************************************/ diff --git a/sdk/lib/3rdparty/libxml2/triostr.h b/sdk/lib/3rdparty/libxml2/triostr.h index 27f4ace236d..0a0e71adbc2 100644 --- a/sdk/lib/3rdparty/libxml2/triostr.h +++ b/sdk/lib/3rdparty/libxml2/triostr.h @@ -10,7 +10,7 @@ * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. * ************************************************************************/ diff --git a/sdk/lib/3rdparty/libxml2/uri.c b/sdk/lib/3rdparty/libxml2/uri.c index 05d81e57633..8204825f18f 100644 --- a/sdk/lib/3rdparty/libxml2/uri.c +++ b/sdk/lib/3rdparty/libxml2/uri.c @@ -11,6 +11,7 @@ #define IN_LIBXML #include "libxml.h" +#include #include #include @@ -329,9 +330,14 @@ xmlParse3986Port(xmlURIPtr uri, const char **str) if (ISA_DIGIT(cur)) { while (ISA_DIGIT(cur)) { - port = port * 10 + (*cur - '0'); - if (port > 99999999) - port = 99999999; + int digit = *cur - '0'; + + if (port > INT_MAX / 10) + return(1); + port *= 10; + if (port > INT_MAX - digit) + return(1); + port += digit; cur++; } @@ -348,7 +354,7 @@ xmlParse3986Port(xmlURIPtr uri, const char **str) * @uri: pointer to an URI structure * @str: the string to analyze * - * Parse an user informations part and fills in the appropriate fields + * Parse an user information part and fills in the appropriate fields * of the @uri structure * * userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) @@ -1748,11 +1754,6 @@ xmlURIEscape(const xmlChar * str) xmlURIPtr uri; int ret2; -#define NULLCHK(p) if(!p) { \ - xmlURIErrMemory("escaping URI value\n"); \ - xmlFreeURI(uri); \ - return NULL; } \ - if (str == NULL) return (NULL); @@ -1774,6 +1775,12 @@ xmlURIEscape(const xmlChar * str) ret = NULL; +#define NULLCHK(p) if(!p) { \ + xmlURIErrMemory("escaping URI value\n"); \ + xmlFreeURI(uri); \ + xmlFree(ret); \ + return NULL; } \ + if (uri->scheme) { segment = xmlURIEscapeStr(BAD_CAST uri->scheme, BAD_CAST "+-."); NULLCHK(segment) @@ -1794,7 +1801,7 @@ xmlURIEscape(const xmlChar * str) if (uri->user) { segment = xmlURIEscapeStr(BAD_CAST uri->user, BAD_CAST ";:&=+$,"); NULLCHK(segment) - ret = xmlStrcat(ret,BAD_CAST "//"); + ret = xmlStrcat(ret,BAD_CAST "//"); ret = xmlStrcat(ret, segment); ret = xmlStrcat(ret, BAD_CAST "@"); xmlFree(segment); @@ -1803,8 +1810,8 @@ xmlURIEscape(const xmlChar * str) if (uri->server) { segment = xmlURIEscapeStr(BAD_CAST uri->server, BAD_CAST "/?;:@"); NULLCHK(segment) - if (uri->user == NULL) - ret = xmlStrcat(ret, BAD_CAST "//"); + if (uri->user == NULL) + ret = xmlStrcat(ret, BAD_CAST "//"); ret = xmlStrcat(ret, segment); xmlFree(segment); } diff --git a/sdk/lib/3rdparty/libxml2/valid.c b/sdk/lib/3rdparty/libxml2/valid.c index 07963e74510..5ee391c0418 100644 --- a/sdk/lib/3rdparty/libxml2/valid.c +++ b/sdk/lib/3rdparty/libxml2/valid.c @@ -50,7 +50,7 @@ xmlValidateAttributeValueInternal(xmlDocPtr doc, xmlAttributeType type, /** * xmlVErrMemory: * @ctxt: an XML validation parser context - * @extra: extra informations + * @extra: extra information * * Handle an out of memory error */ @@ -89,7 +89,7 @@ xmlVErrMemory(xmlValidCtxtPtr ctxt, const char *extra) * xmlErrValid: * @ctxt: an XML validation parser context * @error: the error number - * @extra: extra informations + * @extra: extra information * * Handle a validation error */ @@ -131,11 +131,11 @@ xmlErrValid(xmlValidCtxtPtr ctxt, xmlParserErrors error, * @ctxt: an XML validation parser context * @node: the node raising the error * @error: the error number - * @str1: extra informations - * @str2: extra informations - * @str3: extra informations + * @str1: extra information + * @str2: extra information + * @str3: extra information * - * Handle a validation error, provide contextual informations + * Handle a validation error, provide contextual information */ static void LIBXML_ATTR_FORMAT(4,0) xmlErrValidNode(xmlValidCtxtPtr ctxt, @@ -174,11 +174,11 @@ xmlErrValidNode(xmlValidCtxtPtr ctxt, * @ctxt: an XML validation parser context * @node: the node raising the error * @error: the error number - * @str1: extra informations - * @int2: extra informations - * @str3: extra informations + * @str1: extra information + * @int2: extra information + * @str3: extra information * - * Handle a validation error, provide contextual informations + * Handle a validation error, provide contextual information */ static void LIBXML_ATTR_FORMAT(4,0) xmlErrValidNodeNr(xmlValidCtxtPtr ctxt, @@ -1174,7 +1174,7 @@ xmlFreeElementContent(xmlElementContentPtr cur) { * @buf: An XML buffer * @cur: An element table * - * Dump the occurence operator of an element. + * Dump the occurrence operator of an element. */ static void xmlDumpElementOccur(xmlBufferPtr buf, xmlElementContentPtr cur) { @@ -5434,7 +5434,7 @@ fail: } else if (ret == -2) { /* * An entities reference appeared at this level. - * Buid a minimal representation of this node content + * Build a minimal representation of this node content * sufficient to run the validation process on it */ DEBUG_VALID_MSG("Found an entity reference, linearizing"); @@ -5919,28 +5919,27 @@ xmlValidatePushCData(xmlValidCtxtPtr ctxt, const xmlChar *data, int len) { break; case XML_ELEMENT_TYPE_MIXED: break; - case XML_ELEMENT_TYPE_ELEMENT: - if (len > 0) { - int i; + case XML_ELEMENT_TYPE_ELEMENT: { + int i; - for (i = 0;i < len;i++) { - if (!IS_BLANK_CH(data[i])) { - xmlErrValidNode(ctxt, state->node, - XML_DTD_CONTENT_MODEL, - "Element %s content does not follow the DTD, Text not allowed\n", - state->node->name, NULL, NULL); - ret = 0; - goto done; - } - } - /* - * TODO: - * VC: Standalone Document Declaration - * element types with element content, if white space - * occurs directly within any instance of those types. - */ - } - break; + for (i = 0;i < len;i++) { + if (!IS_BLANK_CH(data[i])) { + xmlErrValidNode(ctxt, state->node, + XML_DTD_CONTENT_MODEL, + "Element %s content does not follow the DTD, Text not allowed\n", + state->node->name, NULL, NULL); + ret = 0; + goto done; + } + } + /* + * TODO: + * VC: Standalone Document Declaration + * element types with element content, if white space + * occurs directly within any instance of those types. + */ + break; + } } } } diff --git a/sdk/lib/3rdparty/libxml2/xinclude.c b/sdk/lib/3rdparty/libxml2/xinclude.c index ba850fa538d..b2e6ea1344b 100644 --- a/sdk/lib/3rdparty/libxml2/xinclude.c +++ b/sdk/lib/3rdparty/libxml2/xinclude.c @@ -59,7 +59,7 @@ struct _xmlXIncludeRef { xmlNodePtr inc; /* the included copy */ int xml; /* xml or txt */ int count; /* how many refs use that specific doc */ - xmlXPathObjectPtr xptr; /* the xpointer if needed */ + int fallback; /* fallback was loaded */ int emptyFb; /* flag to show fallback empty */ }; @@ -72,7 +72,7 @@ struct _xmlXIncludeCtxt { int txtNr; /* number of unparsed documents */ int txtMax; /* size of unparsed documents tab */ - xmlNodePtr *txtTab; /* array of unparsed text nodes */ + xmlChar * *txtTab; /* array of unparsed text strings */ xmlURL *txturlTab; /* array of unparsed text URLs */ xmlChar * url; /* the current URL processed */ @@ -86,10 +86,13 @@ struct _xmlXIncludeCtxt { xmlChar * base; /* the current xml:base */ void *_private; /* application data */ + + unsigned long incTotal; /* total number of processed inclusions */ }; static int -xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr tree); +xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr tree, + int skipRoot); /************************************************************************ @@ -207,8 +210,6 @@ xmlXIncludeFreeRef(xmlXIncludeRefPtr ref) { xmlFree(ref->URI); if (ref->fragment != NULL) xmlFree(ref->fragment); - if (ref->xptr != NULL) - xmlXPathFreeObject(ref->xptr); xmlFree(ref); } @@ -392,18 +393,22 @@ xmlXIncludeFreeContext(xmlXIncludeCtxtPtr ctxt) { if (ctxt->incTab[i] != NULL) xmlXIncludeFreeRef(ctxt->incTab[i]); } + if (ctxt->incTab != NULL) + xmlFree(ctxt->incTab); + if (ctxt->txtTab != NULL) { + for (i = 0;i < ctxt->txtNr;i++) { + if (ctxt->txtTab[i] != NULL) + xmlFree(ctxt->txtTab[i]); + } + xmlFree(ctxt->txtTab); + } if (ctxt->txturlTab != NULL) { for (i = 0;i < ctxt->txtNr;i++) { if (ctxt->txturlTab[i] != NULL) xmlFree(ctxt->txturlTab[i]); } - } - if (ctxt->incTab != NULL) - xmlFree(ctxt->incTab); - if (ctxt->txtTab != NULL) - xmlFree(ctxt->txtTab); - if (ctxt->txturlTab != NULL) xmlFree(ctxt->txturlTab); + } if (ctxt->base != NULL) { xmlFree(ctxt->base); } @@ -626,8 +631,8 @@ xmlXIncludeAddNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur) { xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_RECURSION, "detected a local recursion with no xpointer in %s\n", URL); - if (fragment != NULL) - xmlFree(fragment); + xmlFree(URL); + xmlFree(fragment); return(-1); } @@ -639,12 +644,15 @@ xmlXIncludeAddNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur) { if (xmlStrEqual(URL, ctxt->urlTab[i])) { xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_RECURSION, "detected a recursion in %s\n", URL); + xmlFree(URL); + xmlFree(fragment); return(-1); } } } ref = xmlXIncludeNewRef(ctxt, URL, cur); + xmlFree(URL); if (ref == NULL) { return(-1); } @@ -652,7 +660,6 @@ xmlXIncludeAddNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur) { ref->doc = NULL; ref->xml = xml; ref->count = 1; - xmlFree(URL); return(0); } @@ -729,7 +736,9 @@ xmlXIncludeRecurseDoc(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, * (bug 132597) */ newctxt->parseFlags = ctxt->parseFlags; - xmlXIncludeDoProcess(newctxt, doc, xmlDocGetRootElement(doc)); + newctxt->incTotal = ctxt->incTotal; + xmlXIncludeDoProcess(newctxt, doc, xmlDocGetRootElement(doc), 0); + ctxt->incTotal = newctxt->incTotal; for (i = 0;i < ctxt->incNr;i++) { newctxt->incTab[i]->count--; newctxt->incTab[i] = NULL; @@ -759,13 +768,14 @@ xmlXIncludeRecurseDoc(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, * Add a new text node to the list */ static void -xmlXIncludeAddTxt(xmlXIncludeCtxtPtr ctxt, xmlNodePtr txt, const xmlURL url) { +xmlXIncludeAddTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *txt, + const xmlURL url) { #ifdef DEBUG_XINCLUDE xmlGenericError(xmlGenericErrorContext, "Adding text %s\n", url); #endif if (ctxt->txtMax == 0) { ctxt->txtMax = 4; - ctxt->txtTab = (xmlNodePtr *) xmlMalloc(ctxt->txtMax * + ctxt->txtTab = (xmlChar **) xmlMalloc(ctxt->txtMax * sizeof(ctxt->txtTab[0])); if (ctxt->txtTab == NULL) { xmlXIncludeErrMemory(ctxt, NULL, "processing text"); @@ -780,7 +790,7 @@ xmlXIncludeAddTxt(xmlXIncludeCtxtPtr ctxt, xmlNodePtr txt, const xmlURL url) { } if (ctxt->txtNr >= ctxt->txtMax) { ctxt->txtMax *= 2; - ctxt->txtTab = (xmlNodePtr *) xmlRealloc(ctxt->txtTab, + ctxt->txtTab = (xmlChar **) xmlRealloc(ctxt->txtTab, ctxt->txtMax * sizeof(ctxt->txtTab[0])); if (ctxt->txtTab == NULL) { xmlXIncludeErrMemory(ctxt, NULL, "processing text"); @@ -793,7 +803,7 @@ xmlXIncludeAddTxt(xmlXIncludeCtxtPtr ctxt, xmlNodePtr txt, const xmlURL url) { return; } } - ctxt->txtTab[ctxt->txtNr] = txt; + ctxt->txtTab[ctxt->txtNr] = xmlStrdup(txt); ctxt->txturlTab[ctxt->txtNr] = xmlStrdup(url); ctxt->txtNr++; } @@ -1071,7 +1081,7 @@ xmlXIncludeCopyRange(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target, case XML_ELEMENT_DECL: case XML_ATTRIBUTE_DECL: case XML_ENTITY_NODE: - /* Do not copy DTD informations */ + /* Do not copy DTD information */ break; case XML_ENTITY_DECL: /* handle crossing entities -> stack needed */ @@ -1459,7 +1469,7 @@ xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) { */ if ((URL[0] == 0) || (URL[0] == '#') || ((ctxt->doc != NULL) && (xmlStrEqual(URL, ctxt->doc->URL)))) { - doc = NULL; + doc = ctxt->doc; goto loaded; } @@ -1551,15 +1561,8 @@ loaded: /* * Add the top children list as the replacement copy. */ - if (doc == NULL) - { - /* Hopefully a DTD declaration won't be copied from - * the same document */ - ctxt->incTab[nr]->inc = xmlCopyNodeList(ctxt->doc->children); - } else { - ctxt->incTab[nr]->inc = xmlXIncludeCopyNodeList(ctxt, ctxt->doc, - doc, doc->children); - } + ctxt->incTab[nr]->inc = xmlXIncludeCopyNodeList(ctxt, ctxt->doc, + doc, doc->children); } #ifdef LIBXML_XPTR_ENABLED else { @@ -1571,12 +1574,7 @@ loaded: xmlXPathContextPtr xptrctxt; xmlNodeSetPtr set; - if (doc == NULL) { - xptrctxt = xmlXPtrNewContext(ctxt->doc, ctxt->incTab[nr]->ref, - NULL); - } else { - xptrctxt = xmlXPtrNewContext(doc, NULL, NULL); - } + xptrctxt = xmlXPtrNewContext(doc, NULL, NULL); if (xptrctxt == NULL) { xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_XPTR_FAILED, @@ -1608,6 +1606,7 @@ loaded: XML_XINCLUDE_XPTR_RESULT, "XPointer is not a range: #%s\n", fragment); + xmlXPathFreeObject(xptr); xmlXPathFreeContext(xptrctxt); xmlFree(URL); xmlFree(fragment); @@ -1615,6 +1614,7 @@ loaded: case XPATH_NODESET: if ((xptr->nodesetval == NULL) || (xptr->nodesetval->nodeNr <= 0)) { + xmlXPathFreeObject(xptr); xmlXPathFreeContext(xptrctxt); xmlFree(URL); xmlFree(fragment); @@ -1678,14 +1678,9 @@ loaded: } } } - if (doc == NULL) { - ctxt->incTab[nr]->xptr = xptr; - ctxt->incTab[nr]->inc = NULL; - } else { - ctxt->incTab[nr]->inc = - xmlXIncludeCopyXPointer(ctxt, ctxt->doc, doc, xptr); - xmlXPathFreeObject(xptr); - } + ctxt->incTab[nr]->inc = + xmlXIncludeCopyXPointer(ctxt, ctxt->doc, doc, xptr); + xmlXPathFreeObject(xptr); xmlXPathFreeContext(xptrctxt); xmlFree(fragment); } @@ -1855,7 +1850,7 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) { */ for (i = 0; i < ctxt->txtNr; i++) { if (xmlStrEqual(URL, ctxt->txturlTab[i])) { - node = xmlCopyNode(ctxt->txtTab[i], 1); + node = xmlNewText(ctxt->txtTab[i]); goto loaded; } } @@ -1945,7 +1940,7 @@ xinclude_multibyte_fallback: xmlBufShrink(buf->buffer, len); } xmlFreeParserCtxt(pctxt); - xmlXIncludeAddTxt(ctxt, node, URL); + xmlXIncludeAddTxt(ctxt, node->content, URL); xmlFreeInputStream(inputStream); loaded: @@ -1988,19 +1983,23 @@ xmlXIncludeLoadFallback(xmlXIncludeCtxtPtr ctxt, xmlNodePtr fallback, int nr) { newctxt->_private = ctxt->_private; newctxt->base = xmlStrdup(ctxt->base); /* Inherit the base from the existing context */ xmlXIncludeSetFlags(newctxt, ctxt->parseFlags); - ret = xmlXIncludeDoProcess(newctxt, ctxt->doc, fallback->children); + newctxt->incTotal = ctxt->incTotal; + if (xmlXIncludeDoProcess(newctxt, ctxt->doc, fallback, 1) < 0) + ret = -1; + ctxt->incTotal = newctxt->incTotal; if (ctxt->nbErrors > oldNbErrors) ret = -1; - else if (ret > 0) - ret = 0; /* xmlXIncludeDoProcess can return +ve number */ xmlXIncludeFreeContext(newctxt); ctxt->incTab[nr]->inc = xmlDocCopyNodeList(ctxt->doc, fallback->children); + if (ctxt->incTab[nr]->inc == NULL) + ctxt->incTab[nr]->emptyFb = 1; } else { ctxt->incTab[nr]->inc = NULL; ctxt->incTab[nr]->emptyFb = 1; /* flag empty callback */ } + ctxt->incTab[nr]->fallback = 1; return(ret); } @@ -2156,8 +2155,7 @@ xmlXIncludeLoadNode(xmlXIncludeCtxtPtr ctxt, int nr) { ((xmlStrEqual(children->ns->href, XINCLUDE_NS)) || (xmlStrEqual(children->ns->href, XINCLUDE_OLD_NS)))) { ret = xmlXIncludeLoadFallback(ctxt, children, nr); - if (ret == 0) - break; + break; } children = children->next; } @@ -2204,19 +2202,9 @@ xmlXIncludeIncludeNode(xmlXIncludeCtxtPtr ctxt, int nr) { if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL)) return(-1); - /* - * If we stored an XPointer a late computation may be needed - */ - if ((ctxt->incTab[nr]->inc == NULL) && - (ctxt->incTab[nr]->xptr != NULL)) { - ctxt->incTab[nr]->inc = - xmlXIncludeCopyXPointer(ctxt, ctxt->doc, ctxt->doc, - ctxt->incTab[nr]->xptr); - xmlXPathFreeObject(ctxt->incTab[nr]->xptr); - ctxt->incTab[nr]->xptr = NULL; - } list = ctxt->incTab[nr]->inc; ctxt->incTab[nr]->inc = NULL; + ctxt->incTab[nr]->emptyFb = 0; /* * Check against the risk of generating a multi-rooted document @@ -2236,6 +2224,7 @@ xmlXIncludeIncludeNode(xmlXIncludeCtxtPtr ctxt, int nr) { XML_XINCLUDE_MULTIPLE_ROOT, "XInclude error: would result in multiple root nodes\n", NULL); + xmlFreeNodeList(list); return(-1); } } @@ -2253,16 +2242,27 @@ xmlXIncludeIncludeNode(xmlXIncludeCtxtPtr ctxt, int nr) { xmlUnlinkNode(cur); xmlFreeNode(cur); } else { + xmlNodePtr child, next; + /* * Change the current node as an XInclude start one, and add an * XInclude end one */ + if (ctxt->incTab[nr]->fallback) + xmlUnsetProp(cur, BAD_CAST "href"); cur->type = XML_XINCLUDE_START; + /* Remove fallback children */ + for (child = cur->children; child != NULL; child = next) { + next = child->next; + xmlUnlinkNode(child); + xmlFreeNode(child); + } end = xmlNewDocNode(cur->doc, cur->ns, cur->name, NULL); if (end == NULL) { xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, XML_XINCLUDE_BUILD_FAILED, "failed to build node\n", NULL); + xmlFreeNodeList(list); return(-1); } end->type = XML_XINCLUDE_END; @@ -2364,6 +2364,7 @@ xmlXIncludeTestNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node) { * @ctxt: the XInclude processing context * @doc: an XML document * @tree: the top of the tree to process + * @skipRoot: don't process the root node of the tree * * Implement the XInclude substitution on the XML document @doc * @@ -2371,13 +2372,16 @@ xmlXIncludeTestNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node) { * or the number of substitutions done. */ static int -xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr tree) { +xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr tree, + int skipRoot) { xmlNodePtr cur; int ret = 0; int i, start; if ((doc == NULL) || (tree == NULL) || (tree->type == XML_NAMESPACE_DECL)) return(-1); + if ((skipRoot) && (tree->children == NULL)) + return(-1); if (ctxt == NULL) return(-1); @@ -2388,41 +2392,59 @@ xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr tree) { } start = ctxt->incNr; + /* + * TODO: The phases must run separately for recursive inclusions. + * + * - Phase 1 should start with top-level XInclude nodes, load documents, + * execute XPointer expressions, then process only the result nodes + * (not whole document, see bug #324081) and only for phase 1 + * recursively. We will need a backreference from xmlNodes to + * xmlIncludeRefs to detect references that were already visited. + * This can also be used for proper cycle detection, see bug #344240. + * + * - Phase 2 should visit all top-level XInclude nodes and expand + * possible subreferences in the replacement recursively. + * + * - Phase 3 should finally replace the top-level XInclude nodes. + * It could also be run together with phase 2. + */ + /* * First phase: lookup the elements in the document */ - cur = tree; - if (xmlXIncludeTestNode(ctxt, cur) == 1) - xmlXIncludePreProcessNode(ctxt, cur); - while ((cur != NULL) && (cur != tree->parent)) { + if (skipRoot) + cur = tree->children; + else + cur = tree; + do { /* TODO: need to work on entities -> stack */ - if ((cur->children != NULL) && - (cur->children->type != XML_ENTITY_DECL) && - (cur->children->type != XML_XINCLUDE_START) && - (cur->children->type != XML_XINCLUDE_END)) { - cur = cur->children; - if (xmlXIncludeTestNode(ctxt, cur)) - xmlXIncludePreProcessNode(ctxt, cur); - } else if (cur->next != NULL) { - cur = cur->next; - if (xmlXIncludeTestNode(ctxt, cur)) - xmlXIncludePreProcessNode(ctxt, cur); - } else { - if (cur == tree) - break; - do { - cur = cur->parent; - if ((cur == NULL) || (cur == tree->parent)) - break; /* do */ - if (cur->next != NULL) { - cur = cur->next; - if (xmlXIncludeTestNode(ctxt, cur)) - xmlXIncludePreProcessNode(ctxt, cur); - break; /* do */ - } - } while (cur != NULL); - } - } + if (xmlXIncludeTestNode(ctxt, cur) == 1) { +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + /* + * Avoid superlinear expansion by limiting the total number + * of replacements. + */ + if (ctxt->incTotal >= 20) + return(-1); +#endif + ctxt->incTotal++; + xmlXIncludePreProcessNode(ctxt, cur); + } else if ((cur->children != NULL) && + ((cur->type == XML_DOCUMENT_NODE) || + (cur->type == XML_ELEMENT_NODE))) { + cur = cur->children; + continue; + } + do { + if (cur == tree) + break; + if (cur->next != NULL) { + cur = cur->next; + break; + } + cur = cur->parent; + } while (cur != NULL); + } while ((cur != NULL) && (cur != tree)); /* * Second Phase : collect the infosets fragments @@ -2445,8 +2467,7 @@ xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr tree) { */ for (i = ctxt->incBase;i < ctxt->incNr; i++) { if ((ctxt->incTab[i]->inc != NULL) || - (ctxt->incTab[i]->xptr != NULL) || - (ctxt->incTab[i]->emptyFb != 0)) /* (empty fallback) */ + (ctxt->incTab[i]->emptyFb != 0)) /* (empty fallback) */ xmlXIncludeIncludeNode(ctxt, i); } @@ -2500,7 +2521,7 @@ xmlXIncludeProcessTreeFlagsData(xmlNodePtr tree, int flags, void *data) { ctxt->_private = data; ctxt->base = xmlStrdup((xmlChar *)tree->doc->URL); xmlXIncludeSetFlags(ctxt, flags); - ret = xmlXIncludeDoProcess(ctxt, tree->doc, tree); + ret = xmlXIncludeDoProcess(ctxt, tree->doc, tree, 0); if ((ret >= 0) && (ctxt->nbErrors > 0)) ret = -1; @@ -2584,7 +2605,7 @@ xmlXIncludeProcessTreeFlags(xmlNodePtr tree, int flags) { return(-1); ctxt->base = xmlNodeGetBase(tree->doc, tree); xmlXIncludeSetFlags(ctxt, flags); - ret = xmlXIncludeDoProcess(ctxt, tree->doc, tree); + ret = xmlXIncludeDoProcess(ctxt, tree->doc, tree, 0); if ((ret >= 0) && (ctxt->nbErrors > 0)) ret = -1; @@ -2612,7 +2633,7 @@ xmlXIncludeProcessTree(xmlNodePtr tree) { * @node: a node in an XML document * * Implement the XInclude substitution for the given subtree reusing - * the informations and data coming from the given context. + * the information and data coming from the given context. * * Returns 0 if no substitution were done, -1 if some processing failed * or the number of substitutions done. @@ -2624,7 +2645,7 @@ xmlXIncludeProcessNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node) { if ((node == NULL) || (node->type == XML_NAMESPACE_DECL) || (node->doc == NULL) || (ctxt == NULL)) return(-1); - ret = xmlXIncludeDoProcess(ctxt, node->doc, node); + ret = xmlXIncludeDoProcess(ctxt, node->doc, node, 0); if ((ret >= 0) && (ctxt->nbErrors > 0)) ret = -1; return(ret); diff --git a/sdk/lib/3rdparty/libxml2/xmlIO.c b/sdk/lib/3rdparty/libxml2/xmlIO.c index 9972e5664a5..b6e4c6180f0 100644 --- a/sdk/lib/3rdparty/libxml2/xmlIO.c +++ b/sdk/lib/3rdparty/libxml2/xmlIO.c @@ -228,7 +228,7 @@ __xmlIOWin32UTF8ToWChar(const char *u8String) /** * xmlIOErrMemory: - * @extra: extra informations + * @extra: extra information * * Handle an out of memory condition */ @@ -242,7 +242,7 @@ xmlIOErrMemory(const char *extra) * __xmlIOErr: * @code: the error number * @ - * @extra: extra informations + * @extra: extra information * * Handle an I/O error */ @@ -420,7 +420,7 @@ __xmlIOErr(int domain, int code, const char *extra) /** * xmlIOErr: * @code: the error number - * @extra: extra informations + * @extra: extra information * * Handle an I/O error */ @@ -433,7 +433,7 @@ xmlIOErr(int code, const char *extra) /** * __xmlLoaderErr: * @ctx: the parser context - * @extra: extra informations + * @extra: extra information * * Handle a resource access error */ @@ -564,6 +564,33 @@ xmlCleanupOutputCallbacks(void) xmlOutputCallbackNr = 0; xmlOutputCallbackInitialized = 0; } + +/** + * xmlPopOutputCallbacks: + * + * Remove the top output callbacks from the output stack. This includes the + * compiled-in I/O. + * + * Returns the number of output callback registered or -1 in case of error. + */ +int +xmlPopOutputCallbacks(void) +{ + if (!xmlOutputCallbackInitialized) + return(-1); + + if (xmlOutputCallbackNr <= 0) + return(-1); + + xmlOutputCallbackNr--; + xmlOutputCallbackTable[xmlOutputCallbackNr].matchcallback = NULL; + xmlOutputCallbackTable[xmlOutputCallbackNr].opencallback = NULL; + xmlOutputCallbackTable[xmlOutputCallbackNr].writecallback = NULL; + xmlOutputCallbackTable[xmlOutputCallbackNr].closecallback = NULL; + + return(xmlOutputCallbackNr); +} + #endif /* LIBXML_OUTPUT_ENABLED */ /************************************************************************ @@ -3378,18 +3405,12 @@ xmlOutputBufferWrite(xmlOutputBufferPtr out, int len, const char *buf) { out->error = XML_IO_ENCODER; return(-1); } - if (out->writecallback) - nbchars = xmlBufUse(out->conv); - else - nbchars = ret; + nbchars = ret >= 0 ? ret : 0; } else { ret = xmlBufAdd(out->buffer, (const xmlChar *) buf, chunk); if (ret != 0) return(-1); - if (out->writecallback) - nbchars = xmlBufUse(out->buffer); - else - nbchars = chunk; + nbchars = chunk; } buf += chunk; len -= chunk; @@ -3576,19 +3597,13 @@ xmlOutputBufferWriteEscape(xmlOutputBufferPtr out, const xmlChar *str, out->error = XML_IO_ENCODER; return(-1); } - if (out->writecallback) - nbchars = xmlBufUse(out->conv); - else - nbchars = ret; + nbchars = ret >= 0 ? ret : 0; } else { ret = escaping(xmlBufEnd(out->buffer), &chunk, str, &cons); if ((ret < 0) || (chunk == 0)) /* chunk==0 => nothing done */ return(-1); xmlBufAddLen(out->buffer, chunk); - if (out->writecallback) - nbchars = xmlBufUse(out->buffer); - else - nbchars = chunk; + nbchars = chunk; } str += cons; len -= cons; diff --git a/sdk/lib/3rdparty/libxml2/xmlcatalog.c b/sdk/lib/3rdparty/libxml2/xmlcatalog.c index c02b97f67b2..3f0e1b9cfc0 100644 --- a/sdk/lib/3rdparty/libxml2/xmlcatalog.c +++ b/sdk/lib/3rdparty/libxml2/xmlcatalog.c @@ -325,7 +325,7 @@ Usage : %s [options] catalogfile entities...\n\ \t used with --add or --del, it saves the catalog changes\n\ \t and with --sgml it automatically updates the super catalog\n\ \t--no-super-update: do not update the SGML super catalog\n\ -\t-v --verbose : provide debug informations\n"); +\t-v --verbose : provide debug information\n"); } int main(int argc, char **argv) { int i; diff --git a/sdk/lib/3rdparty/libxml2/xmllint.c b/sdk/lib/3rdparty/libxml2/xmllint.c index 735d951d2fd..a3fe10a2b2b 100644 --- a/sdk/lib/3rdparty/libxml2/xmllint.c +++ b/sdk/lib/3rdparty/libxml2/xmllint.c @@ -165,6 +165,7 @@ static int xinclude = 0; static int dtdattrs = 0; static int loaddtd = 0; static xmllintReturnCode progresult = XMLLINT_RETURN_OK; +static int quiet = 0; static int timing = 0; static int generate = 0; static int dropdtd = 0; @@ -528,6 +529,12 @@ static void xmlHTMLEncodeSend(void) { char *result; + /* + * xmlEncodeEntitiesReentrant assumes valid UTF-8, but the buffer might + * end with a truncated UTF-8 sequence. This is a hack to at least avoid + * an out-of-bounds read. + */ + memset(&buffer[sizeof(buffer)-4], 0, 4); result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer); if (result) { xmlGenericError(xmlGenericErrorContext, "%s", result); @@ -540,7 +547,7 @@ xmlHTMLEncodeSend(void) { * xmlHTMLPrintFileInfo: * @input: an xmlParserInputPtr input * - * Displays the associated file and line informations for the current input + * Displays the associated file and line information for the current input */ static void @@ -1659,7 +1666,9 @@ testSAX(const char *filename) { (void *)user_data); if (repeat == 0) { if (ret == 0) { - fprintf(stderr, "%s validates\n", filename); + if (!quiet) { + fprintf(stderr, "%s validates\n", filename); + } } else if (ret > 0) { fprintf(stderr, "%s fails to validate\n", filename); progresult = XMLLINT_ERR_VALID; @@ -1942,7 +1951,9 @@ static void streamFile(char *filename) { fprintf(stderr, "%s fails to validate\n", filename); progresult = XMLLINT_ERR_VALID; } else { - fprintf(stderr, "%s validates\n", filename); + if (!quiet) { + fprintf(stderr, "%s validates\n", filename); + } } } #endif @@ -2182,13 +2193,17 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) { else if ((html) && (push)) { FILE *f; + if ((filename[0] == '-') && (filename[1] == 0)) { + f = stdin; + } else { #if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__) - f = fopen(filename, "rb"); + f = fopen(filename, "rb"); #elif defined(__OS400__) - f = fopen(filename, "rb"); + f = fopen(filename, "rb"); #else - f = fopen(filename, "r"); + f = fopen(filename, "r"); #endif + } if (f != NULL) { int res; char chars[4096]; @@ -2198,7 +2213,7 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) { if (res > 0) { ctxt = htmlCreatePushParserCtxt(NULL, NULL, chars, res, filename, XML_CHAR_ENCODING_NONE); - xmlCtxtUseOptions(ctxt, options); + htmlCtxtUseOptions(ctxt, options); while ((res = fread(chars, 1, pushsize, f)) > 0) { htmlParseChunk(ctxt, chars, res, 0); } @@ -2277,7 +2292,7 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) { doc = ctxt->myDoc; ret = ctxt->wellFormed; xmlFreeParserCtxt(ctxt); - if (!ret) { + if ((!ret) && (!recovery)) { xmlFreeDoc(doc); doc = NULL; } @@ -2411,6 +2426,7 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) { dtd = xmlGetIntSubset(doc); if (dtd != NULL) { xmlUnlinkNode((xmlNodePtr)dtd); + doc->intSubset = NULL; xmlFreeDtd(dtd); } } @@ -2830,7 +2846,9 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) { #endif ret = xmlSchematronValidateDoc(ctxt, doc); if (ret == 0) { - fprintf(stderr, "%s validates\n", filename); + if (!quiet) { + fprintf(stderr, "%s validates\n", filename); + } } else if (ret > 0) { fprintf(stderr, "%s fails to validate\n", filename); progresult = XMLLINT_ERR_VALID; @@ -2858,7 +2876,9 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) { xmlRelaxNGSetValidErrors(ctxt, xmlGenericError, xmlGenericError, NULL); ret = xmlRelaxNGValidateDoc(ctxt, doc); if (ret == 0) { - fprintf(stderr, "%s validates\n", filename); + if (!quiet) { + fprintf(stderr, "%s validates\n", filename); + } } else if (ret > 0) { fprintf(stderr, "%s fails to validate\n", filename); progresult = XMLLINT_ERR_VALID; @@ -2883,7 +2903,9 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) { xmlSchemaSetValidErrors(ctxt, xmlGenericError, xmlGenericError, NULL); ret = xmlSchemaValidateDoc(ctxt, doc); if (ret == 0) { - fprintf(stderr, "%s validates\n", filename); + if (!quiet) { + fprintf(stderr, "%s validates\n", filename); + } } else if (ret > 0) { fprintf(stderr, "%s fails to validate\n", filename); progresult = XMLLINT_ERR_VALID; @@ -3000,6 +3022,7 @@ static void usage(FILE *f, const char *name) { fprintf(f, "\t--dtdvalid URL : do a posteriori validation against a given DTD\n"); fprintf(f, "\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n"); #endif /* LIBXML_VALID_ENABLED */ + fprintf(f, "\t--quiet : be quiet when succeeded\n"); fprintf(f, "\t--timing : print some timings\n"); fprintf(f, "\t--output file or -o file: save to a given file\n"); fprintf(f, "\t--repeat : repeat 100 times, for timing or profiling\n"); @@ -3234,6 +3257,9 @@ main(int argc, char **argv) { else if ((!strcmp(argv[i], "-insert")) || (!strcmp(argv[i], "--insert"))) insert++; + else if ((!strcmp(argv[i], "-quiet")) || + (!strcmp(argv[i], "--quiet"))) + quiet++; else if ((!strcmp(argv[i], "-timing")) || (!strcmp(argv[i], "--timing"))) timing++; diff --git a/sdk/lib/3rdparty/libxml2/xmlmemory.c b/sdk/lib/3rdparty/libxml2/xmlmemory.c index 6f16c4b3caf..c51f49ae67c 100644 --- a/sdk/lib/3rdparty/libxml2/xmlmemory.c +++ b/sdk/lib/3rdparty/libxml2/xmlmemory.c @@ -75,7 +75,7 @@ void xmlMallocBreakpoint(void); #endif /* - * Each of the blocks allocated begin with a header containing informations + * Each of the blocks allocated begin with a header containing information */ #define MEMTAG 0x5aa5 diff --git a/sdk/lib/3rdparty/libxml2/xmlreader.c b/sdk/lib/3rdparty/libxml2/xmlreader.c index f3891e43afe..72e40b03294 100644 --- a/sdk/lib/3rdparty/libxml2/xmlreader.c +++ b/sdk/lib/3rdparty/libxml2/xmlreader.c @@ -48,6 +48,13 @@ #define MAX_ERR_MSG_SIZE 64000 +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION +/* Keeping free objects can hide memory errors. */ +#define MAX_FREE_NODES 1 +#else +#define MAX_FREE_NODES 100 +#endif + /* * The following VA_COPY was coded following an example in * the Samba project. It may not be sufficient for some @@ -278,6 +285,59 @@ xmlTextReaderRemoveID(xmlDocPtr doc, xmlAttrPtr attr) { return(0); } +/** + * xmlTextReaderWalkRemoveRef: + * @data: Contents of current link + * @user: Value supplied by the user + * + * Returns 0 to abort the walk or 1 to continue + */ +static int +xmlTextReaderWalkRemoveRef(const void *data, void *user) +{ + xmlRefPtr ref = (xmlRefPtr)data; + xmlAttrPtr attr = (xmlAttrPtr)user; + + if (ref->attr == attr) { /* Matched: remove and terminate walk */ + ref->name = xmlStrdup(attr->name); + ref->attr = NULL; + return 0; + } + return 1; +} + +/** + * xmlTextReaderRemoveRef: + * @doc: the document + * @attr: the attribute + * + * Remove the given attribute from the Ref table maintained internally. + * + * Returns -1 if the lookup failed and 0 otherwise + */ +static int +xmlTextReaderRemoveRef(xmlDocPtr doc, xmlAttrPtr attr) { + xmlListPtr ref_list; + xmlRefTablePtr table; + xmlChar *ID; + + if (doc == NULL) return(-1); + if (attr == NULL) return(-1); + table = (xmlRefTablePtr) doc->refs; + if (table == NULL) + return(-1); + + ID = xmlNodeListGetString(doc, attr->children, 1); + if (ID == NULL) + return(-1); + ref_list = xmlHashLookup(table, ID); + xmlFree(ID); + if(ref_list == NULL) + return (-1); + xmlListWalk(ref_list, xmlTextReaderWalkRemoveRef, attr); + return(0); +} + /** * xmlTextReaderFreeProp: * @reader: the xmlTextReaderPtr used @@ -299,18 +359,20 @@ xmlTextReaderFreeProp(xmlTextReaderPtr reader, xmlAttrPtr cur) { xmlDeregisterNodeDefaultValue((xmlNodePtr) cur); /* Check for ID removal -> leading to invalid references ! */ - if ((cur->parent != NULL) && (cur->parent->doc != NULL) && - ((cur->parent->doc->intSubset != NULL) || - (cur->parent->doc->extSubset != NULL))) { + if ((cur->parent != NULL) && (cur->parent->doc != NULL)) { if (xmlIsID(cur->parent->doc, cur->parent, cur)) xmlTextReaderRemoveID(cur->parent->doc, cur); + if (((cur->parent->doc->intSubset != NULL) || + (cur->parent->doc->extSubset != NULL)) && + (xmlIsRef(cur->parent->doc, cur->parent, cur))) + xmlTextReaderRemoveRef(cur->parent->doc, cur); } if (cur->children != NULL) xmlTextReaderFreeNodeList(reader, cur->children); DICT_FREE(cur->name); if ((reader != NULL) && (reader->ctxt != NULL) && - (reader->ctxt->freeAttrsNr < 100)) { + (reader->ctxt->freeAttrsNr < MAX_FREE_NODES)) { cur->next = reader->ctxt->freeAttrs; reader->ctxt->freeAttrs = cur; reader->ctxt->freeAttrsNr++; @@ -411,7 +473,7 @@ xmlTextReaderFreeNodeList(xmlTextReaderPtr reader, xmlNodePtr cur) { if (((cur->type == XML_ELEMENT_NODE) || (cur->type == XML_TEXT_NODE)) && (reader != NULL) && (reader->ctxt != NULL) && - (reader->ctxt->freeElemsNr < 100)) { + (reader->ctxt->freeElemsNr < MAX_FREE_NODES)) { cur->next = reader->ctxt->freeElems; reader->ctxt->freeElems = cur; reader->ctxt->freeElemsNr++; @@ -499,7 +561,7 @@ xmlTextReaderFreeNode(xmlTextReaderPtr reader, xmlNodePtr cur) { if (((cur->type == XML_ELEMENT_NODE) || (cur->type == XML_TEXT_NODE)) && (reader != NULL) && (reader->ctxt != NULL) && - (reader->ctxt->freeElemsNr < 100)) { + (reader->ctxt->freeElemsNr < MAX_FREE_NODES)) { cur->next = reader->ctxt->freeElems; reader->ctxt->freeElems = cur; reader->ctxt->freeElemsNr++; @@ -1106,20 +1168,9 @@ static void xmlTextReaderValidateEntity(xmlTextReaderPtr reader) { xmlNodePtr oldnode = reader->node; xmlNodePtr node = reader->node; - xmlParserCtxtPtr ctxt = reader->ctxt; do { if (node->type == XML_ENTITY_REF_NODE) { - /* - * Case where the underlying tree is not available, lookup the entity - * and walk it. - */ - if ((node->children == NULL) && (ctxt->sax != NULL) && - (ctxt->sax->getEntity != NULL)) { - node->children = (xmlNodePtr) - ctxt->sax->getEntity(ctxt, node->name); - } - if ((node->children != NULL) && (node->children->type == XML_ENTITY_DECL) && (node->children->children != NULL)) { @@ -1447,6 +1498,8 @@ get_next_node: (reader->node->prev->type != XML_DTD_NODE)) { xmlNodePtr tmp = reader->node->prev; if ((tmp->extra & NODE_IS_PRESERVED) == 0) { + if (oldnode == tmp) + oldnode = NULL; xmlUnlinkNode(tmp); xmlTextReaderFreeNode(reader, tmp); } @@ -1532,7 +1585,8 @@ node_found: /* * Handle XInclude if asked for */ - if ((reader->xinclude) && (reader->node != NULL) && + if ((reader->xinclude) && (reader->in_xinclude == 0) && + (reader->node != NULL) && (reader->node->type == XML_ELEMENT_NODE) && (reader->node->ns != NULL) && ((xmlStrEqual(reader->node->ns->href, XINCLUDE_NS)) || @@ -1564,16 +1618,6 @@ node_found: if ((reader->node != NULL) && (reader->node->type == XML_ENTITY_REF_NODE) && (reader->ctxt != NULL) && (reader->ctxt->replaceEntities == 1)) { - /* - * Case where the underlying tree is not available, lookup the entity - * and walk it. - */ - if ((reader->node->children == NULL) && (reader->ctxt->sax != NULL) && - (reader->ctxt->sax->getEntity != NULL)) { - reader->node->children = (xmlNodePtr) - reader->ctxt->sax->getEntity(reader->ctxt, reader->node->name); - } - if ((reader->node->children != NULL) && (reader->node->children->type == XML_ENTITY_DECL) && (reader->node->children->children != NULL)) { @@ -2281,14 +2325,18 @@ xmlFreeTextReader(xmlTextReaderPtr reader) { if (reader->ctxt != NULL) { if (reader->dict == reader->ctxt->dict) reader->dict = NULL; +#ifdef LIBXML_VALID_ENABLED if ((reader->ctxt->vctxt.vstateTab != NULL) && (reader->ctxt->vctxt.vstateMax > 0)){ +#ifdef LIBXML_REGEXP_ENABLED while (reader->ctxt->vctxt.vstateNr > 0) xmlValidatePopElement(&reader->ctxt->vctxt, NULL, NULL, NULL); +#endif /* LIBXML_REGEXP_ENABLED */ xmlFree(reader->ctxt->vctxt.vstateTab); reader->ctxt->vctxt.vstateTab = NULL; reader->ctxt->vctxt.vstateMax = 0; } +#endif /* LIBXML_VALID_ENABLED */ if (reader->ctxt->myDoc != NULL) { if (reader->preserve == 0) xmlTextReaderFreeDoc(reader, reader->ctxt->myDoc); @@ -2971,7 +3019,7 @@ xmlTextReaderConstEncoding(xmlTextReaderPtr reader) { /************************************************************************ * * - * Acces API to the current node * + * Access API to the current node * * * ************************************************************************/ /** @@ -3786,7 +3834,7 @@ xmlTextReaderConstString(xmlTextReaderPtr reader, const xmlChar *str) { * * The value indicating whether to normalize white space and attribute values. * Since attribute value and end of line normalizations are a MUST in the XML - * specification only the value true is accepted. The broken bahaviour of + * specification only the value true is accepted. The broken behaviour of * accepting out of range character entities like � is of course not * supported either. * @@ -3848,16 +3896,20 @@ xmlTextReaderSetParserProp(xmlTextReaderPtr reader, int prop, int value) { return(0); case XML_PARSER_VALIDATE: if (value != 0) { + ctxt->options |= XML_PARSE_DTDVALID; ctxt->validate = 1; reader->validate = XML_TEXTREADER_VALIDATE_DTD; } else { + ctxt->options &= ~XML_PARSE_DTDVALID; ctxt->validate = 0; } return(0); case XML_PARSER_SUBST_ENTITIES: if (value != 0) { + ctxt->options |= XML_PARSE_NOENT; ctxt->replaceEntities = 1; } else { + ctxt->options &= ~XML_PARSE_NOENT; ctxt->replaceEntities = 0; } return(0); diff --git a/sdk/lib/3rdparty/libxml2/xmlregexp.c b/sdk/lib/3rdparty/libxml2/xmlregexp.c index c119ff1fb7f..40dabb2036f 100644 --- a/sdk/lib/3rdparty/libxml2/xmlregexp.c +++ b/sdk/lib/3rdparty/libxml2/xmlregexp.c @@ -26,6 +26,9 @@ #ifdef HAVE_LIMITS_H #include #endif +#ifdef HAVE_STDINT_H +#include +#endif #include #include @@ -36,6 +39,9 @@ #ifndef INT_MAX #define INT_MAX 123456789 /* easy to flag and big enough for our needs */ #endif +#ifndef SIZE_MAX +#define SIZE_MAX ((size_t) -1) +#endif /* #define DEBUG_REGEXP_GRAPH */ /* #define DEBUG_REGEXP_EXEC */ @@ -267,6 +273,8 @@ struct _xmlAutomata { int determinist; int negs; int flags; + + int depth; }; struct _xmlRegexp { @@ -418,6 +426,32 @@ xmlRegexpErrCompile(xmlRegParserCtxtPtr ctxt, const char *extra) ************************************************************************/ static int xmlFAComputesDeterminism(xmlRegParserCtxtPtr ctxt); + +/** + * xmlRegCalloc2: + * @dim1: size of first dimension + * @dim2: size of second dimension + * @elemSize: size of element + * + * Allocate a two-dimensional array and set all elements to zero. + * + * Returns the new array or NULL in case of error. + */ +static void* +xmlRegCalloc2(size_t dim1, size_t dim2, size_t elemSize) { + size_t totalSize; + void *ret; + + /* Check for overflow */ + if (dim1 > SIZE_MAX / dim2 / elemSize) + return (NULL); + totalSize = dim1 * dim2 * elemSize; + ret = xmlMalloc(totalSize); + if (ret != NULL) + memset(ret, 0, totalSize); + return (ret); +} + /** * xmlRegEpxFromParse: * @ctxt: the parser context used to build it @@ -540,8 +574,8 @@ xmlRegEpxFromParse(xmlRegParserCtxtPtr ctxt) { #ifdef DEBUG_COMPACTION printf("Final: %d atoms\n", nbatoms); #endif - transitions = (int *) xmlMalloc((nbstates + 1) * - (nbatoms + 1) * sizeof(int)); + transitions = (int *) xmlRegCalloc2(nbstates + 1, nbatoms + 1, + sizeof(int)); if (transitions == NULL) { xmlFree(stateRemap); xmlFree(stringRemap); @@ -551,7 +585,6 @@ xmlRegEpxFromParse(xmlRegParserCtxtPtr ctxt) { xmlFree(ret); return(NULL); } - memset(transitions, 0, (nbstates + 1) * (nbatoms + 1) * sizeof(int)); /* * Allocate the transition table. The first entry for each @@ -577,12 +610,9 @@ xmlRegEpxFromParse(xmlRegParserCtxtPtr ctxt) { continue; atomno = stringRemap[trans->atom->no]; if ((trans->atom->data != NULL) && (transdata == NULL)) { - transdata = (void **) xmlMalloc(nbstates * nbatoms * - sizeof(void *)); - if (transdata != NULL) - memset(transdata, 0, - nbstates * nbatoms * sizeof(void *)); - else { + transdata = (void **) xmlRegCalloc2(nbstates, nbatoms, + sizeof(void *)); + if (transdata == NULL) { xmlRegexpErrMemory(ctxt, "compiling regexp"); break; } @@ -2628,7 +2658,6 @@ xmlFARecurseDeterminism(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state, state->markd = XML_REGEXP_MARK_VISITED; res = xmlFARecurseDeterminism(ctxt, ctxt->states[t1->to], to, atom); - state->markd = 0; if (res == 0) { ret = 0; /* t1->nd = 1; */ @@ -2646,6 +2675,30 @@ xmlFARecurseDeterminism(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state, return(ret); } +/** + * xmlFAFinishRecurseDeterminism: + * @ctxt: a regexp parser context + * + * Reset flags after checking determinism. + */ +static void +xmlFAFinishRecurseDeterminism(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state) { + int transnr, nbTrans; + + if (state == NULL) + return; + if (state->markd != XML_REGEXP_MARK_VISITED) + return; + state->markd = 0; + + nbTrans = state->nbTrans; + for (transnr = 0; transnr < nbTrans; transnr++) { + xmlRegTransPtr t1 = &state->trans[transnr]; + if ((t1->atom == NULL) && (t1->to >= 0)) + xmlFAFinishRecurseDeterminism(ctxt, ctxt->states[t1->to]); + } +} + /** * xmlFAComputesDeterminism: * @ctxt: a regexp parser context @@ -2759,6 +2812,7 @@ xmlFAComputesDeterminism(xmlRegParserCtxtPtr ctxt) { */ ret = xmlFARecurseDeterminism(ctxt, ctxt->states[t1->to], t2->to, t2->atom); + xmlFAFinishRecurseDeterminism(ctxt, ctxt->states[t1->to]); /* don't shortcut the computation so all non deterministic transition get marked down if (ret == 0) @@ -4221,7 +4275,7 @@ xmlRegExecPushString2(xmlRegExecCtxtPtr exec, const xmlChar *value, * @values: pointer to the array of acceptable values * @terminal: return value if this was a terminal state * - * Extract informations from the regexp execution, internal routine to + * Extract information from the regexp execution, internal routine to * implement xmlRegExecNextValues() and xmlRegExecErrInfo() * * Returns: 0 in case of success or -1 in case of error. @@ -4380,7 +4434,7 @@ xmlRegExecGetValues(xmlRegExecCtxtPtr exec, int err, * @values: pointer to the array of acceptable values * @terminal: return value if this was a terminal state * - * Extract informations from the regexp execution, + * Extract information from the regexp execution, * the parameter @values must point to an array of @nbval string pointers * on return nbval will contain the number of possible strings in that * state and the @values array will be updated with them. The string values @@ -4404,7 +4458,7 @@ xmlRegExecNextValues(xmlRegExecCtxtPtr exec, int *nbval, int *nbneg, * @values: pointer to the array of acceptable values * @terminal: return value if this was a terminal state * - * Extract error informations from the regexp execution, the parameter + * Extract error information from the regexp execution, the parameter * @string will be updated with the value pushed and not accepted, * the parameter @values must point to an array of @nbval string pointers * on return nbval will contain the number of possible strings in that @@ -5101,7 +5155,7 @@ xmlFAParsePosCharGroup(xmlRegParserCtxtPtr ctxt) { } else { xmlFAParseCharRange(ctxt); } - } while ((CUR != ']') && (CUR != '^') && (CUR != '-') && + } while ((CUR != ']') && (CUR != '-') && (CUR != 0) && (ctxt->error == 0)); } @@ -5116,34 +5170,31 @@ xmlFAParsePosCharGroup(xmlRegParserCtxtPtr ctxt) { */ static void xmlFAParseCharGroup(xmlRegParserCtxtPtr ctxt) { - int n = ctxt->neg; - while ((CUR != ']') && (ctxt->error == 0)) { - if (CUR == '^') { - int neg = ctxt->neg; + int neg = ctxt->neg; - NEXT; - ctxt->neg = !ctxt->neg; - xmlFAParsePosCharGroup(ctxt); - ctxt->neg = neg; - } else if ((CUR == '-') && (NXT(1) == '[')) { - int neg = ctxt->neg; - ctxt->neg = 2; + if (CUR == '^') { + NEXT; + ctxt->neg = !ctxt->neg; + xmlFAParsePosCharGroup(ctxt); + ctxt->neg = neg; + } + while ((CUR != ']') && (ctxt->error == 0)) { + if ((CUR == '-') && (NXT(1) == '[')) { NEXT; /* eat the '-' */ NEXT; /* eat the '[' */ + ctxt->neg = 2; xmlFAParseCharGroup(ctxt); + ctxt->neg = neg; if (CUR == ']') { NEXT; } else { ERROR("charClassExpr: ']' expected"); - break; } - ctxt->neg = neg; break; - } else if (CUR != ']') { + } else { xmlFAParsePosCharGroup(ctxt); } } - ctxt->neg = n; } /** @@ -5183,13 +5234,24 @@ static int xmlFAParseQuantExact(xmlRegParserCtxtPtr ctxt) { int ret = 0; int ok = 0; + int overflow = 0; while ((CUR >= '0') && (CUR <= '9')) { - ret = ret * 10 + (CUR - '0'); + if (ret > INT_MAX / 10) { + overflow = 1; + } else { + int digit = CUR - '0'; + + ret *= 10; + if (ret > INT_MAX - digit) + overflow = 1; + else + ret += digit; + } ok = 1; NEXT; } - if (ok != 1) { + if ((ok != 1) || (overflow == 1)) { return(-1); } return(ret); @@ -5229,6 +5291,9 @@ xmlFAParseQuantifier(xmlRegParserCtxtPtr ctxt) { cur = xmlFAParseQuantExact(ctxt); if (cur >= 0) min = cur; + else { + ERROR("Improper quantifier"); + } if (CUR == ',') { NEXT; if (CUR == '}') @@ -5288,6 +5353,10 @@ xmlFAParseAtom(xmlRegParserCtxtPtr ctxt) { xmlRegStatePtr start, oldend, start0; NEXT; + if (ctxt->depth >= 50) { + ERROR("xmlFAParseAtom: maximum nesting depth exceeded"); + return(-1); + } /* * this extra Epsilon transition is needed if we count with 0 allowed * unfortunately this can't be known at that point @@ -5299,7 +5368,9 @@ xmlFAParseAtom(xmlRegParserCtxtPtr ctxt) { oldend = ctxt->end; ctxt->end = NULL; ctxt->atom = NULL; + ctxt->depth++; xmlFAParseRegExp(ctxt, 0); + ctxt->depth--; if (CUR == ')') { NEXT; } else { @@ -6055,7 +6126,7 @@ xmlAutomataNewOnceTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from, return(NULL); if (min < 1) return(NULL); - if ((max < min) || (max < 1)) + if (max < min) return(NULL); atom = xmlRegNewAtom(am, XML_REGEXP_STRING); if (atom == NULL) @@ -6134,7 +6205,7 @@ xmlAutomataNewOnceTrans(xmlAutomataPtr am, xmlAutomataStatePtr from, return(NULL); if (min < 1) return(NULL); - if ((max < min) || (max < 1)) + if (max < min) return(NULL); atom = xmlRegNewAtom(am, XML_REGEXP_STRING); if (atom == NULL) diff --git a/sdk/lib/3rdparty/libxml2/xmlsave.c b/sdk/lib/3rdparty/libxml2/xmlsave.c index fa009153718..61a40459bd2 100644 --- a/sdk/lib/3rdparty/libxml2/xmlsave.c +++ b/sdk/lib/3rdparty/libxml2/xmlsave.c @@ -100,7 +100,7 @@ struct _xmlSaveCtxt { ************************************************************************/ /** * xmlSaveErrMemory: - * @extra: extra informations + * @extra: extra information * * Handle an out of memory condition */ @@ -114,7 +114,7 @@ xmlSaveErrMemory(const char *extra) * xmlSaveErr: * @code: the error number * @node: the location of the error. - * @extra: extra informations + * @extra: extra information * * Handle an out of memory condition */ @@ -590,7 +590,6 @@ static int xmlSaveClearEncoding(xmlSaveCtxtPtr ctxt) { static void xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur); #endif -static void xmlNodeListDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur); static void xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur); void xmlNsListDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur); static int xmlDocContentDumpOutput(xmlSaveCtxtPtr ctxt, xmlDocPtr cur); @@ -705,6 +704,7 @@ xmlNsListDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur) { static void xmlDtdDumpOutput(xmlSaveCtxtPtr ctxt, xmlDtdPtr dtd) { xmlOutputBufferPtr buf; + xmlNodePtr cur; int format, level; if (dtd == NULL) return; @@ -742,7 +742,9 @@ xmlDtdDumpOutput(xmlSaveCtxtPtr ctxt, xmlDtdPtr dtd) { level = ctxt->level; ctxt->format = 0; ctxt->level = -1; - xmlNodeListDumpOutput(ctxt, dtd->children); + for (cur = dtd->children; cur != NULL; cur = cur->next) { + xmlNodeDumpOutputInternal(ctxt, cur); + } ctxt->format = format; ctxt->level = level; xmlOutputBufferWrite(buf, 2, "]>"); @@ -776,58 +778,9 @@ xmlAttrDumpOutput(xmlSaveCtxtPtr ctxt, xmlAttrPtr cur) { xmlOutputBufferWrite(buf, 1, "\""); } -/** - * xmlAttrListDumpOutput: - * @buf: the XML buffer output - * @doc: the document - * @cur: the first attribute pointer - * @encoding: an optional encoding string - * - * Dump a list of XML attributes - */ -static void -xmlAttrListDumpOutput(xmlSaveCtxtPtr ctxt, xmlAttrPtr cur) { - if (cur == NULL) return; - while (cur != NULL) { - xmlAttrDumpOutput(ctxt, cur); - cur = cur->next; - } -} - - - -/** - * xmlNodeListDumpOutput: - * @cur: the first node - * - * Dump an XML node list, recursive behaviour, children are printed too. - */ -static void -xmlNodeListDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) { - xmlOutputBufferPtr buf; - - if (cur == NULL) return; - buf = ctxt->buf; - while (cur != NULL) { - if ((ctxt->format == 1) && (xmlIndentTreeOutput) && - ((cur->type == XML_ELEMENT_NODE) || - (cur->type == XML_COMMENT_NODE) || - (cur->type == XML_PI_NODE))) - xmlOutputBufferWrite(buf, ctxt->indent_size * - (ctxt->level > ctxt->indent_nr ? - ctxt->indent_nr : ctxt->level), - ctxt->indent); - xmlNodeDumpOutputInternal(ctxt, cur); - if (ctxt->format == 1) { - xmlOutputBufferWrite(buf, 1, "\n"); - } - cur = cur->next; - } -} - #ifdef LIBXML_HTML_ENABLED /** - * xmlNodeDumpOutputInternal: + * htmlNodeDumpOutputInternal: * @cur: the current node * * Dump an HTML node, recursive behaviour, children are printed too. @@ -893,57 +846,111 @@ htmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) { */ static void xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) { - int format; - xmlNodePtr tmp; + int format = ctxt->format; + xmlNodePtr tmp, root, unformattedNode = NULL; + xmlAttrPtr attr; xmlChar *start, *end; xmlOutputBufferPtr buf; if (cur == NULL) return; buf = ctxt->buf; - if (cur->type == XML_XINCLUDE_START) - return; - if (cur->type == XML_XINCLUDE_END) - return; - if ((cur->type == XML_DOCUMENT_NODE) || - (cur->type == XML_HTML_DOCUMENT_NODE)) { - xmlDocContentDumpOutput(ctxt, (xmlDocPtr) cur); - return; - } -#ifdef LIBXML_HTML_ENABLED - if (ctxt->options & XML_SAVE_XHTML) { - xhtmlNodeDumpOutput(ctxt, cur); - return; - } - if (((cur->type != XML_NAMESPACE_DECL) && (cur->doc != NULL) && - (cur->doc->type == XML_HTML_DOCUMENT_NODE) && - ((ctxt->options & XML_SAVE_AS_XML) == 0)) || - (ctxt->options & XML_SAVE_AS_HTML)) { - htmlNodeDumpOutputInternal(ctxt, cur); - return; - } -#endif - if (cur->type == XML_DTD_NODE) { - xmlDtdDumpOutput(ctxt, (xmlDtdPtr) cur); - return; - } - if (cur->type == XML_DOCUMENT_FRAG_NODE) { - xmlNodeListDumpOutput(ctxt, cur->children); - return; - } - if (cur->type == XML_ELEMENT_DECL) { - xmlBufDumpElementDecl(buf->buffer, (xmlElementPtr) cur); - return; - } - if (cur->type == XML_ATTRIBUTE_DECL) { - xmlBufDumpAttributeDecl(buf->buffer, (xmlAttributePtr) cur); - return; - } - if (cur->type == XML_ENTITY_DECL) { - xmlBufDumpEntityDecl(buf->buffer, (xmlEntityPtr) cur); - return; - } - if (cur->type == XML_TEXT_NODE) { - if (cur->content != NULL) { + + root = cur; + while (1) { + switch (cur->type) { + case XML_DOCUMENT_NODE: + case XML_HTML_DOCUMENT_NODE: + xmlDocContentDumpOutput(ctxt, (xmlDocPtr) cur); + break; + + case XML_DTD_NODE: + xmlDtdDumpOutput(ctxt, (xmlDtdPtr) cur); + break; + + case XML_DOCUMENT_FRAG_NODE: + if (cur->children != NULL) { + cur = cur->children; + continue; + } + break; + + case XML_ELEMENT_DECL: + xmlBufDumpElementDecl(buf->buffer, (xmlElementPtr) cur); + break; + + case XML_ATTRIBUTE_DECL: + xmlBufDumpAttributeDecl(buf->buffer, (xmlAttributePtr) cur); + break; + + case XML_ENTITY_DECL: + xmlBufDumpEntityDecl(buf->buffer, (xmlEntityPtr) cur); + break; + + case XML_ELEMENT_NODE: + if ((cur != root) && (ctxt->format == 1) && (xmlIndentTreeOutput)) + xmlOutputBufferWrite(buf, ctxt->indent_size * + (ctxt->level > ctxt->indent_nr ? + ctxt->indent_nr : ctxt->level), + ctxt->indent); + + xmlOutputBufferWrite(buf, 1, "<"); + if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) { + xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix); + xmlOutputBufferWrite(buf, 1, ":"); + } + xmlOutputBufferWriteString(buf, (const char *)cur->name); + if (cur->nsDef) + xmlNsListDumpOutputCtxt(ctxt, cur->nsDef); + for (attr = cur->properties; attr != NULL; attr = attr->next) + xmlAttrDumpOutput(ctxt, attr); + + if (cur->children == NULL) { + if ((ctxt->options & XML_SAVE_NO_EMPTY) == 0) { + if (ctxt->format == 2) + xmlOutputBufferWriteWSNonSig(ctxt, 0); + xmlOutputBufferWrite(buf, 2, "/>"); + } else { + if (ctxt->format == 2) + xmlOutputBufferWriteWSNonSig(ctxt, 1); + xmlOutputBufferWrite(buf, 3, ">ns != NULL) && (cur->ns->prefix != NULL)) { + xmlOutputBufferWriteString(buf, + (const char *)cur->ns->prefix); + xmlOutputBufferWrite(buf, 1, ":"); + } + xmlOutputBufferWriteString(buf, (const char *)cur->name); + if (ctxt->format == 2) + xmlOutputBufferWriteWSNonSig(ctxt, 0); + xmlOutputBufferWrite(buf, 1, ">"); + } + } else { + if (ctxt->format == 1) { + tmp = cur->children; + while (tmp != NULL) { + if ((tmp->type == XML_TEXT_NODE) || + (tmp->type == XML_CDATA_SECTION_NODE) || + (tmp->type == XML_ENTITY_REF_NODE)) { + ctxt->format = 0; + unformattedNode = cur; + break; + } + tmp = tmp->next; + } + } + if (ctxt->format == 2) + xmlOutputBufferWriteWSNonSig(ctxt, 1); + xmlOutputBufferWrite(buf, 1, ">"); + if (ctxt->format == 1) xmlOutputBufferWrite(buf, 1, "\n"); + if (ctxt->level >= 0) ctxt->level++; + cur = cur->children; + continue; + } + + break; + + case XML_TEXT_NODE: + if (cur->content == NULL) + break; if (cur->name != xmlStringTextNoenc) { xmlOutputBufferWriteEscape(buf, cur->content, ctxt->escape); } else { @@ -952,139 +959,140 @@ xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) { */ xmlOutputBufferWriteString(buf, (const char *) cur->content); } - } + break; - return; - } - if (cur->type == XML_PI_NODE) { - if (cur->content != NULL) { - xmlOutputBufferWrite(buf, 2, "name); - if (cur->content != NULL) { - if (ctxt->format == 2) - xmlOutputBufferWriteWSNonSig(ctxt, 0); - else - xmlOutputBufferWrite(buf, 1, " "); - xmlOutputBufferWriteString(buf, (const char *)cur->content); - } - xmlOutputBufferWrite(buf, 2, "?>"); - } else { - xmlOutputBufferWrite(buf, 2, "name); - if (ctxt->format == 2) - xmlOutputBufferWriteWSNonSig(ctxt, 0); - xmlOutputBufferWrite(buf, 2, "?>"); - } - return; - } - if (cur->type == XML_COMMENT_NODE) { - if (cur->content != NULL) { - xmlOutputBufferWrite(buf, 4, ""); - } - return; - } - if (cur->type == XML_ENTITY_REF_NODE) { - xmlOutputBufferWrite(buf, 1, "&"); - xmlOutputBufferWriteString(buf, (const char *)cur->name); - xmlOutputBufferWrite(buf, 1, ";"); - return; - } - if (cur->type == XML_CDATA_SECTION_NODE) { - if (cur->content == NULL || *cur->content == '\0') { - xmlOutputBufferWrite(buf, 12, ""); - } else { - start = end = cur->content; - while (*end != '\0') { - if ((*end == ']') && (*(end + 1) == ']') && - (*(end + 2) == '>')) { - end = end + 2; - xmlOutputBufferWrite(buf, 9, ""); - start = end; - } - end++; - } - if (start != end) { - xmlOutputBufferWrite(buf, 9, ""); - } - } - return; - } - if (cur->type == XML_ATTRIBUTE_NODE) { - xmlAttrDumpOutput(ctxt, (xmlAttrPtr) cur); - return; - } - if (cur->type == XML_NAMESPACE_DECL) { - xmlNsDumpOutputCtxt(ctxt, (xmlNsPtr) cur); - return; - } + case XML_PI_NODE: + if ((cur != root) && (ctxt->format == 1) && (xmlIndentTreeOutput)) + xmlOutputBufferWrite(buf, ctxt->indent_size * + (ctxt->level > ctxt->indent_nr ? + ctxt->indent_nr : ctxt->level), + ctxt->indent); - format = ctxt->format; - if (format == 1) { - tmp = cur->children; - while (tmp != NULL) { - if ((tmp->type == XML_TEXT_NODE) || - (tmp->type == XML_CDATA_SECTION_NODE) || - (tmp->type == XML_ENTITY_REF_NODE)) { - ctxt->format = 0; - break; - } - tmp = tmp->next; - } - } - xmlOutputBufferWrite(buf, 1, "<"); - if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) { - xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix); - xmlOutputBufferWrite(buf, 1, ":"); - } + if (cur->content != NULL) { + xmlOutputBufferWrite(buf, 2, "name); + if (cur->content != NULL) { + if (ctxt->format == 2) + xmlOutputBufferWriteWSNonSig(ctxt, 0); + else + xmlOutputBufferWrite(buf, 1, " "); + xmlOutputBufferWriteString(buf, + (const char *)cur->content); + } + xmlOutputBufferWrite(buf, 2, "?>"); + } else { + xmlOutputBufferWrite(buf, 2, "name); + if (ctxt->format == 2) + xmlOutputBufferWriteWSNonSig(ctxt, 0); + xmlOutputBufferWrite(buf, 2, "?>"); + } + break; - xmlOutputBufferWriteString(buf, (const char *)cur->name); - if (cur->nsDef) - xmlNsListDumpOutputCtxt(ctxt, cur->nsDef); - if (cur->properties != NULL) - xmlAttrListDumpOutput(ctxt, cur->properties); + case XML_COMMENT_NODE: + if ((cur != root) && (ctxt->format == 1) && (xmlIndentTreeOutput)) + xmlOutputBufferWrite(buf, ctxt->indent_size * + (ctxt->level > ctxt->indent_nr ? + ctxt->indent_nr : ctxt->level), + ctxt->indent); - if (((cur->type == XML_ELEMENT_NODE) || (cur->content == NULL)) && - (cur->children == NULL) && ((ctxt->options & XML_SAVE_NO_EMPTY) == 0)) { - if (ctxt->format == 2) - xmlOutputBufferWriteWSNonSig(ctxt, 0); - xmlOutputBufferWrite(buf, 2, "/>"); - ctxt->format = format; - return; - } - if (ctxt->format == 2) - xmlOutputBufferWriteWSNonSig(ctxt, 1); - xmlOutputBufferWrite(buf, 1, ">"); - if ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL)) { - xmlOutputBufferWriteEscape(buf, cur->content, ctxt->escape); - } - if (cur->children != NULL) { - if (ctxt->format == 1) xmlOutputBufferWrite(buf, 1, "\n"); - if (ctxt->level >= 0) ctxt->level++; - xmlNodeListDumpOutput(ctxt, cur->children); - if (ctxt->level > 0) ctxt->level--; - if ((xmlIndentTreeOutput) && (ctxt->format == 1)) - xmlOutputBufferWrite(buf, ctxt->indent_size * - (ctxt->level > ctxt->indent_nr ? - ctxt->indent_nr : ctxt->level), - ctxt->indent); - } - xmlOutputBufferWrite(buf, 2, "ns != NULL) && (cur->ns->prefix != NULL)) { - xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix); - xmlOutputBufferWrite(buf, 1, ":"); - } + if (cur->content != NULL) { + xmlOutputBufferWrite(buf, 4, ""); + } + break; - xmlOutputBufferWriteString(buf, (const char *)cur->name); - if (ctxt->format == 2) - xmlOutputBufferWriteWSNonSig(ctxt, 0); - xmlOutputBufferWrite(buf, 1, ">"); - ctxt->format = format; + case XML_ENTITY_REF_NODE: + xmlOutputBufferWrite(buf, 1, "&"); + xmlOutputBufferWriteString(buf, (const char *)cur->name); + xmlOutputBufferWrite(buf, 1, ";"); + break; + + case XML_CDATA_SECTION_NODE: + if (cur->content == NULL || *cur->content == '\0') { + xmlOutputBufferWrite(buf, 12, ""); + } else { + start = end = cur->content; + while (*end != '\0') { + if ((*end == ']') && (*(end + 1) == ']') && + (*(end + 2) == '>')) { + end = end + 2; + xmlOutputBufferWrite(buf, 9, ""); + start = end; + } + end++; + } + if (start != end) { + xmlOutputBufferWrite(buf, 9, ""); + } + } + break; + + case XML_ATTRIBUTE_NODE: + xmlAttrDumpOutput(ctxt, (xmlAttrPtr) cur); + break; + + case XML_NAMESPACE_DECL: + xmlNsDumpOutputCtxt(ctxt, (xmlNsPtr) cur); + break; + + default: + break; + } + + while (1) { + if (cur == root) + return; + if ((ctxt->format == 1) && + (cur->type != XML_XINCLUDE_START) && + (cur->type != XML_XINCLUDE_END)) + xmlOutputBufferWrite(buf, 1, "\n"); + if (cur->next != NULL) { + cur = cur->next; + break; + } + + /* + * The parent should never be NULL here but we want to handle + * corrupted documents gracefully. + */ + if (cur->parent == NULL) + return; + cur = cur->parent; + + if (cur->type == XML_ELEMENT_NODE) { + if (ctxt->level > 0) ctxt->level--; + if ((xmlIndentTreeOutput) && (ctxt->format == 1)) + xmlOutputBufferWrite(buf, ctxt->indent_size * + (ctxt->level > ctxt->indent_nr ? + ctxt->indent_nr : ctxt->level), + ctxt->indent); + + xmlOutputBufferWrite(buf, 2, "ns != NULL) && (cur->ns->prefix != NULL)) { + xmlOutputBufferWriteString(buf, + (const char *)cur->ns->prefix); + xmlOutputBufferWrite(buf, 1, ":"); + } + + xmlOutputBufferWriteString(buf, (const char *)cur->name); + if (ctxt->format == 2) + xmlOutputBufferWriteWSNonSig(ctxt, 0); + xmlOutputBufferWrite(buf, 1, ">"); + + if (cur == unformattedNode) { + ctxt->format = format; + unformattedNode = NULL; + } + } + } + } } /** @@ -1224,7 +1232,9 @@ xmlDocContentDumpOutput(xmlSaveCtxtPtr ctxt, xmlDocPtr cur) { else #endif xmlNodeDumpOutputInternal(ctxt, child); - xmlOutputBufferWrite(buf, 1, "\n"); + if ((child->type != XML_XINCLUDE_START) && + (child->type != XML_XINCLUDE_END)) + xmlOutputBufferWrite(buf, 1, "\n"); child = child->next; } } @@ -1395,40 +1405,6 @@ xhtmlAttrListDumpOutput(xmlSaveCtxtPtr ctxt, xmlAttrPtr cur) { } } -/** - * xhtmlNodeListDumpOutput: - * @buf: the XML buffer output - * @doc: the XHTML document - * @cur: the first node - * @level: the imbrication level for indenting - * @format: is formatting allowed - * @encoding: an optional encoding string - * - * Dump an XML node list, recursive behaviour, children are printed too. - * Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1 - * or xmlKeepBlanksDefault(0) was called - */ -static void -xhtmlNodeListDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) { - xmlOutputBufferPtr buf; - - if (cur == NULL) return; - buf = ctxt->buf; - while (cur != NULL) { - if ((ctxt->format == 1) && (xmlIndentTreeOutput) && - (cur->type == XML_ELEMENT_NODE)) - xmlOutputBufferWrite(buf, ctxt->indent_size * - (ctxt->level > ctxt->indent_nr ? - ctxt->indent_nr : ctxt->level), - ctxt->indent); - xhtmlNodeDumpOutput(ctxt, cur); - if (ctxt->format == 1) { - xmlOutputBufferWrite(buf, 1, "\n"); - } - cur = cur->next; - } -} - /** * xhtmlNodeDumpOutput: * @buf: the XML buffer output @@ -1442,48 +1418,195 @@ xhtmlNodeListDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) { */ static void xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) { - int format, addmeta = 0; - xmlNodePtr tmp; + int format = ctxt->format, addmeta; + xmlNodePtr tmp, root, unformattedNode = NULL; xmlChar *start, *end; - xmlOutputBufferPtr buf; + xmlOutputBufferPtr buf = ctxt->buf; if (cur == NULL) return; - if ((cur->type == XML_DOCUMENT_NODE) || - (cur->type == XML_HTML_DOCUMENT_NODE)) { - xmlDocContentDumpOutput(ctxt, (xmlDocPtr) cur); - return; - } - if (cur->type == XML_XINCLUDE_START) - return; - if (cur->type == XML_XINCLUDE_END) - return; - if (cur->type == XML_NAMESPACE_DECL) { - xmlNsDumpOutputCtxt(ctxt, (xmlNsPtr) cur); - return; - } - if (cur->type == XML_DTD_NODE) { - xmlDtdDumpOutput(ctxt, (xmlDtdPtr) cur); - return; - } - if (cur->type == XML_DOCUMENT_FRAG_NODE) { - xhtmlNodeListDumpOutput(ctxt, cur->children); - return; - } - buf = ctxt->buf; - if (cur->type == XML_ELEMENT_DECL) { - xmlBufDumpElementDecl(buf->buffer, (xmlElementPtr) cur); - return; - } - if (cur->type == XML_ATTRIBUTE_DECL) { - xmlBufDumpAttributeDecl(buf->buffer, (xmlAttributePtr) cur); - return; - } - if (cur->type == XML_ENTITY_DECL) { - xmlBufDumpEntityDecl(buf->buffer, (xmlEntityPtr) cur); - return; - } - if (cur->type == XML_TEXT_NODE) { - if (cur->content != NULL) { + + root = cur; + while (1) { + switch (cur->type) { + case XML_DOCUMENT_NODE: + case XML_HTML_DOCUMENT_NODE: + xmlDocContentDumpOutput(ctxt, (xmlDocPtr) cur); + break; + + case XML_NAMESPACE_DECL: + xmlNsDumpOutputCtxt(ctxt, (xmlNsPtr) cur); + break; + + case XML_DTD_NODE: + xmlDtdDumpOutput(ctxt, (xmlDtdPtr) cur); + break; + + case XML_DOCUMENT_FRAG_NODE: + if (cur->children) { + cur = cur->children; + continue; + } + break; + + case XML_ELEMENT_DECL: + xmlBufDumpElementDecl(buf->buffer, (xmlElementPtr) cur); + break; + + case XML_ATTRIBUTE_DECL: + xmlBufDumpAttributeDecl(buf->buffer, (xmlAttributePtr) cur); + break; + + case XML_ENTITY_DECL: + xmlBufDumpEntityDecl(buf->buffer, (xmlEntityPtr) cur); + break; + + case XML_ELEMENT_NODE: + addmeta = 0; + + if ((cur != root) && (ctxt->format == 1) && (xmlIndentTreeOutput)) + xmlOutputBufferWrite(buf, ctxt->indent_size * + (ctxt->level > ctxt->indent_nr ? + ctxt->indent_nr : ctxt->level), + ctxt->indent); + + xmlOutputBufferWrite(buf, 1, "<"); + if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) { + xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix); + xmlOutputBufferWrite(buf, 1, ":"); + } + + xmlOutputBufferWriteString(buf, (const char *)cur->name); + if (cur->nsDef) + xmlNsListDumpOutputCtxt(ctxt, cur->nsDef); + if ((xmlStrEqual(cur->name, BAD_CAST "html") && + (cur->ns == NULL) && (cur->nsDef == NULL))) { + /* + * 3.1.1. Strictly Conforming Documents A.3.1.1 3/ + */ + xmlOutputBufferWriteString(buf, + " xmlns=\"http://www.w3.org/1999/xhtml\""); + } + if (cur->properties != NULL) + xhtmlAttrListDumpOutput(ctxt, cur->properties); + + if ((cur->parent != NULL) && + (cur->parent->parent == (xmlNodePtr) cur->doc) && + xmlStrEqual(cur->name, BAD_CAST"head") && + xmlStrEqual(cur->parent->name, BAD_CAST"html")) { + + tmp = cur->children; + while (tmp != NULL) { + if (xmlStrEqual(tmp->name, BAD_CAST"meta")) { + xmlChar *httpequiv; + + httpequiv = xmlGetProp(tmp, BAD_CAST"http-equiv"); + if (httpequiv != NULL) { + if (xmlStrcasecmp(httpequiv, + BAD_CAST"Content-Type") == 0) { + xmlFree(httpequiv); + break; + } + xmlFree(httpequiv); + } + } + tmp = tmp->next; + } + if (tmp == NULL) + addmeta = 1; + } + + if (cur->children == NULL) { + if (((cur->ns == NULL) || (cur->ns->prefix == NULL)) && + ((xhtmlIsEmpty(cur) == 1) && (addmeta == 0))) { + /* + * C.2. Empty Elements + */ + xmlOutputBufferWrite(buf, 3, " />"); + } else { + if (addmeta == 1) { + xmlOutputBufferWrite(buf, 1, ">"); + if (ctxt->format == 1) { + xmlOutputBufferWrite(buf, 1, "\n"); + if (xmlIndentTreeOutput) + xmlOutputBufferWrite(buf, ctxt->indent_size * + (ctxt->level + 1 > ctxt->indent_nr ? + ctxt->indent_nr : ctxt->level + 1), + ctxt->indent); + } + xmlOutputBufferWriteString(buf, + ""); + if (ctxt->format == 1) + xmlOutputBufferWrite(buf, 1, "\n"); + } else { + xmlOutputBufferWrite(buf, 1, ">"); + } + /* + * C.3. Element Minimization and Empty Element Content + */ + xmlOutputBufferWrite(buf, 2, "ns != NULL) && (cur->ns->prefix != NULL)) { + xmlOutputBufferWriteString(buf, + (const char *)cur->ns->prefix); + xmlOutputBufferWrite(buf, 1, ":"); + } + xmlOutputBufferWriteString(buf, (const char *)cur->name); + xmlOutputBufferWrite(buf, 1, ">"); + } + } else { + xmlOutputBufferWrite(buf, 1, ">"); + if (addmeta == 1) { + if (ctxt->format == 1) { + xmlOutputBufferWrite(buf, 1, "\n"); + if (xmlIndentTreeOutput) + xmlOutputBufferWrite(buf, ctxt->indent_size * + (ctxt->level + 1 > ctxt->indent_nr ? + ctxt->indent_nr : ctxt->level + 1), + ctxt->indent); + } + xmlOutputBufferWriteString(buf, + ""); + } + + if (ctxt->format == 1) { + tmp = cur->children; + while (tmp != NULL) { + if ((tmp->type == XML_TEXT_NODE) || + (tmp->type == XML_ENTITY_REF_NODE)) { + unformattedNode = cur; + ctxt->format = 0; + break; + } + tmp = tmp->next; + } + } + + if (ctxt->format == 1) xmlOutputBufferWrite(buf, 1, "\n"); + if (ctxt->level >= 0) ctxt->level++; + cur = cur->children; + continue; + } + + break; + + case XML_TEXT_NODE: + if (cur->content == NULL) + break; if ((cur->name == xmlStringText) || (cur->name != xmlStringTextNoenc)) { xmlOutputBufferWriteEscape(buf, cur->content, ctxt->escape); @@ -1493,286 +1616,115 @@ xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) { */ xmlOutputBufferWriteString(buf, (const char *) cur->content); } - } + break; - return; - } - if (cur->type == XML_PI_NODE) { - if (cur->content != NULL) { - xmlOutputBufferWrite(buf, 2, "name); - if (cur->content != NULL) { - xmlOutputBufferWrite(buf, 1, " "); - xmlOutputBufferWriteString(buf, (const char *)cur->content); - } - xmlOutputBufferWrite(buf, 2, "?>"); - } else { - xmlOutputBufferWrite(buf, 2, "name); - xmlOutputBufferWrite(buf, 2, "?>"); - } - return; - } - if (cur->type == XML_COMMENT_NODE) { - if (cur->content != NULL) { - xmlOutputBufferWrite(buf, 4, ""); - } - return; - } - if (cur->type == XML_ENTITY_REF_NODE) { - xmlOutputBufferWrite(buf, 1, "&"); - xmlOutputBufferWriteString(buf, (const char *)cur->name); - xmlOutputBufferWrite(buf, 1, ";"); - return; - } - if (cur->type == XML_CDATA_SECTION_NODE) { - if (cur->content == NULL || *cur->content == '\0') { - xmlOutputBufferWrite(buf, 12, ""); - } else { - start = end = cur->content; - while (*end != '\0') { - if (*end == ']' && *(end + 1) == ']' && *(end + 2) == '>') { - end = end + 2; - xmlOutputBufferWrite(buf, 9, ""); - start = end; - } - end++; - } - if (start != end) { - xmlOutputBufferWrite(buf, 9, ""); - } - } - return; - } - if (cur->type == XML_ATTRIBUTE_NODE) { - xmlAttrDumpOutput(ctxt, (xmlAttrPtr) cur); - return; - } + case XML_PI_NODE: + if (cur->content != NULL) { + xmlOutputBufferWrite(buf, 2, "name); + if (cur->content != NULL) { + xmlOutputBufferWrite(buf, 1, " "); + xmlOutputBufferWriteString(buf, + (const char *)cur->content); + } + xmlOutputBufferWrite(buf, 2, "?>"); + } else { + xmlOutputBufferWrite(buf, 2, "name); + xmlOutputBufferWrite(buf, 2, "?>"); + } + break; - format = ctxt->format; - if (format == 1) { - tmp = cur->children; - while (tmp != NULL) { - if ((tmp->type == XML_TEXT_NODE) || - (tmp->type == XML_ENTITY_REF_NODE)) { - format = 0; - break; - } - tmp = tmp->next; - } - } - xmlOutputBufferWrite(buf, 1, "<"); - if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) { - xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix); - xmlOutputBufferWrite(buf, 1, ":"); - } + case XML_COMMENT_NODE: + if (cur->content != NULL) { + xmlOutputBufferWrite(buf, 4, ""); + } + break; - xmlOutputBufferWriteString(buf, (const char *)cur->name); - if (cur->nsDef) - xmlNsListDumpOutputCtxt(ctxt, cur->nsDef); - if ((xmlStrEqual(cur->name, BAD_CAST "html") && - (cur->ns == NULL) && (cur->nsDef == NULL))) { - /* - * 3.1.1. Strictly Conforming Documents A.3.1.1 3/ - */ - xmlOutputBufferWriteString(buf, - " xmlns=\"http://www.w3.org/1999/xhtml\""); - } - if (cur->properties != NULL) - xhtmlAttrListDumpOutput(ctxt, cur->properties); + case XML_ENTITY_REF_NODE: + xmlOutputBufferWrite(buf, 1, "&"); + xmlOutputBufferWriteString(buf, (const char *)cur->name); + xmlOutputBufferWrite(buf, 1, ";"); + break; - if ((cur->type == XML_ELEMENT_NODE) && - (cur->parent != NULL) && - (cur->parent->parent == (xmlNodePtr) cur->doc) && - xmlStrEqual(cur->name, BAD_CAST"head") && - xmlStrEqual(cur->parent->name, BAD_CAST"html")) { - - tmp = cur->children; - while (tmp != NULL) { - if (xmlStrEqual(tmp->name, BAD_CAST"meta")) { - xmlChar *httpequiv; - - httpequiv = xmlGetProp(tmp, BAD_CAST"http-equiv"); - if (httpequiv != NULL) { - if (xmlStrcasecmp(httpequiv, BAD_CAST"Content-Type") == 0) { - xmlFree(httpequiv); - break; + case XML_CDATA_SECTION_NODE: + if (cur->content == NULL || *cur->content == '\0') { + xmlOutputBufferWrite(buf, 12, ""); + } else { + start = end = cur->content; + while (*end != '\0') { + if (*end == ']' && *(end + 1) == ']' && + *(end + 2) == '>') { + end = end + 2; + xmlOutputBufferWrite(buf, 9, ""); + start = end; } - xmlFree(httpequiv); + end++; + } + if (start != end) { + xmlOutputBufferWrite(buf, 9, ""); + } + } + break; + + case XML_ATTRIBUTE_NODE: + xmlAttrDumpOutput(ctxt, (xmlAttrPtr) cur); + break; + + default: + break; + } + + while (1) { + if (cur == root) + return; + if (ctxt->format == 1) + xmlOutputBufferWrite(buf, 1, "\n"); + if (cur->next != NULL) { + cur = cur->next; + break; + } + + /* + * The parent should never be NULL here but we want to handle + * corrupted documents gracefully. + */ + if (cur->parent == NULL) + return; + cur = cur->parent; + + if (cur->type == XML_ELEMENT_NODE) { + if (ctxt->level > 0) ctxt->level--; + if ((xmlIndentTreeOutput) && (ctxt->format == 1)) + xmlOutputBufferWrite(buf, ctxt->indent_size * + (ctxt->level > ctxt->indent_nr ? + ctxt->indent_nr : ctxt->level), + ctxt->indent); + + xmlOutputBufferWrite(buf, 2, "ns != NULL) && (cur->ns->prefix != NULL)) { + xmlOutputBufferWriteString(buf, + (const char *)cur->ns->prefix); + xmlOutputBufferWrite(buf, 1, ":"); + } + + xmlOutputBufferWriteString(buf, (const char *)cur->name); + xmlOutputBufferWrite(buf, 1, ">"); + + if (cur == unformattedNode) { + ctxt->format = format; + unformattedNode = NULL; } } - tmp = tmp->next; } - if (tmp == NULL) - addmeta = 1; } - - if ((cur->type == XML_ELEMENT_NODE) && (cur->children == NULL)) { - if (((cur->ns == NULL) || (cur->ns->prefix == NULL)) && - ((xhtmlIsEmpty(cur) == 1) && (addmeta == 0))) { - /* - * C.2. Empty Elements - */ - xmlOutputBufferWrite(buf, 3, " />"); - } else { - if (addmeta == 1) { - xmlOutputBufferWrite(buf, 1, ">"); - if (ctxt->format == 1) { - xmlOutputBufferWrite(buf, 1, "\n"); - if (xmlIndentTreeOutput) - xmlOutputBufferWrite(buf, ctxt->indent_size * - (ctxt->level + 1 > ctxt->indent_nr ? - ctxt->indent_nr : ctxt->level + 1), ctxt->indent); - } - xmlOutputBufferWriteString(buf, - ""); - if (ctxt->format == 1) - xmlOutputBufferWrite(buf, 1, "\n"); - } else { - xmlOutputBufferWrite(buf, 1, ">"); - } - /* - * C.3. Element Minimization and Empty Element Content - */ - xmlOutputBufferWrite(buf, 2, "ns != NULL) && (cur->ns->prefix != NULL)) { - xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix); - xmlOutputBufferWrite(buf, 1, ":"); - } - xmlOutputBufferWriteString(buf, (const char *)cur->name); - xmlOutputBufferWrite(buf, 1, ">"); - } - return; - } - xmlOutputBufferWrite(buf, 1, ">"); - if (addmeta == 1) { - if (ctxt->format == 1) { - xmlOutputBufferWrite(buf, 1, "\n"); - if (xmlIndentTreeOutput) - xmlOutputBufferWrite(buf, ctxt->indent_size * - (ctxt->level + 1 > ctxt->indent_nr ? - ctxt->indent_nr : ctxt->level + 1), ctxt->indent); - } - xmlOutputBufferWriteString(buf, - ""); - } - if ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL)) { - xmlOutputBufferWriteEscape(buf, cur->content, ctxt->escape); - } - -#if 0 - /* - * This was removed due to problems with HTML processors. - * See bug #345147. - */ - /* - * 4.8. Script and Style elements - */ - if ((cur->type == XML_ELEMENT_NODE) && - ((xmlStrEqual(cur->name, BAD_CAST "script")) || - (xmlStrEqual(cur->name, BAD_CAST "style"))) && - ((cur->ns == NULL) || - (xmlStrEqual(cur->ns->href, XHTML_NS_NAME)))) { - xmlNodePtr child = cur->children; - - while (child != NULL) { - if (child->type == XML_TEXT_NODE) { - if ((xmlStrchr(child->content, '<') == NULL) && - (xmlStrchr(child->content, '&') == NULL) && - (xmlStrstr(child->content, BAD_CAST "]]>") == NULL)) { - /* Nothing to escape, so just output as is... */ - /* FIXME: Should we do something about "--" also? */ - int level = ctxt->level; - int indent = ctxt->format; - - ctxt->level = 0; - ctxt->format = 0; - xmlOutputBufferWriteString(buf, (const char *) child->content); - /* (We cannot use xhtmlNodeDumpOutput() here because - * we wish to leave '>' unescaped!) */ - ctxt->level = level; - ctxt->format = indent; - } else { - /* We must use a CDATA section. Unfortunately, - * this will break CSS and JavaScript when read by - * a browser in HTML4-compliant mode. :-( */ - start = end = child->content; - while (*end != '\0') { - if (*end == ']' && - *(end + 1) == ']' && - *(end + 2) == '>') { - end = end + 2; - xmlOutputBufferWrite(buf, 9, ""); - start = end; - } - end++; - } - if (start != end) { - xmlOutputBufferWrite(buf, 9, ""); - } - } - } else { - int level = ctxt->level; - int indent = ctxt->format; - - ctxt->level = 0; - ctxt->format = 0; - xhtmlNodeDumpOutput(ctxt, child); - ctxt->level = level; - ctxt->format = indent; - } - child = child->next; - } - } -#endif - - if (cur->children != NULL) { - int indent = ctxt->format; - - if (format == 1) xmlOutputBufferWrite(buf, 1, "\n"); - if (ctxt->level >= 0) ctxt->level++; - ctxt->format = format; - xhtmlNodeListDumpOutput(ctxt, cur->children); - if (ctxt->level > 0) ctxt->level--; - ctxt->format = indent; - if ((xmlIndentTreeOutput) && (format == 1)) - xmlOutputBufferWrite(buf, ctxt->indent_size * - (ctxt->level > ctxt->indent_nr ? - ctxt->indent_nr : ctxt->level), - ctxt->indent); - } - xmlOutputBufferWrite(buf, 2, "ns != NULL) && (cur->ns->prefix != NULL)) { - xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix); - xmlOutputBufferWrite(buf, 1, ":"); - } - - xmlOutputBufferWriteString(buf, (const char *)cur->name); - xmlOutputBufferWrite(buf, 1, ">"); } #endif @@ -1802,6 +1754,7 @@ xmlSaveToFd(int fd, const char *encoding, int options) if (ret == NULL) return(NULL); ret->buf = xmlOutputBufferCreateFd(fd, ret->handler); if (ret->buf == NULL) { + xmlCharEncCloseFunc(ret->handler); xmlFreeSaveCtxt(ret); return(NULL); } @@ -1831,6 +1784,7 @@ xmlSaveToFilename(const char *filename, const char *encoding, int options) ret->buf = xmlOutputBufferCreateFilename(filename, ret->handler, compression); if (ret->buf == NULL) { + xmlCharEncCloseFunc(ret->handler); xmlFreeSaveCtxt(ret); return(NULL); } @@ -1853,28 +1807,15 @@ xmlSaveCtxtPtr xmlSaveToBuffer(xmlBufferPtr buffer, const char *encoding, int options) { xmlSaveCtxtPtr ret; - xmlOutputBufferPtr out_buff; - xmlCharEncodingHandlerPtr handler; ret = xmlNewSaveCtxt(encoding, options); if (ret == NULL) return(NULL); - - if (encoding != NULL) { - handler = xmlFindCharEncodingHandler(encoding); - if (handler == NULL) { - xmlFree(ret); - return(NULL); - } - } else - handler = NULL; - out_buff = xmlOutputBufferCreateBuffer(buffer, handler); - if (out_buff == NULL) { - xmlFree(ret); - if (handler) xmlCharEncCloseFunc(handler); - return(NULL); + ret->buf = xmlOutputBufferCreateBuffer(buffer, ret->handler); + if (ret->buf == NULL) { + xmlCharEncCloseFunc(ret->handler); + xmlFreeSaveCtxt(ret); + return(NULL); } - - ret->buf = out_buff; return(ret); } @@ -1902,6 +1843,7 @@ xmlSaveToIO(xmlOutputWriteCallback iowrite, if (ret == NULL) return(NULL); ret->buf = xmlOutputBufferCreateIO(iowrite, ioclose, ioctx, ret->handler); if (ret->buf == NULL) { + xmlCharEncCloseFunc(ret->handler); xmlFreeSaveCtxt(ret); return(NULL); } @@ -1942,12 +1884,25 @@ xmlSaveDoc(xmlSaveCtxtPtr ctxt, xmlDocPtr doc) * Returns the number of byte written or -1 in case of error */ long -xmlSaveTree(xmlSaveCtxtPtr ctxt, xmlNodePtr node) +xmlSaveTree(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) { long ret = 0; - if ((ctxt == NULL) || (node == NULL)) return(-1); - xmlNodeDumpOutputInternal(ctxt, node); + if ((ctxt == NULL) || (cur == NULL)) return(-1); +#ifdef LIBXML_HTML_ENABLED + if (ctxt->options & XML_SAVE_XHTML) { + xhtmlNodeDumpOutput(ctxt, cur); + return(ret); + } + if (((cur->type != XML_NAMESPACE_DECL) && (cur->doc != NULL) && + (cur->doc->type == XML_HTML_DOCUMENT_NODE) && + ((ctxt->options & XML_SAVE_AS_XML) == 0)) || + (ctxt->options & XML_SAVE_AS_HTML)) { + htmlNodeDumpOutputInternal(ctxt, cur); + return(ret); + } +#endif + xmlNodeDumpOutputInternal(ctxt, cur); return(ret); } @@ -2197,7 +2152,7 @@ xmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level, int format) { xmlBufPtr buffer; - int ret; + size_t ret; if ((buf == NULL) || (cur == NULL)) return(-1); diff --git a/sdk/lib/3rdparty/libxml2/xmlschemas.c b/sdk/lib/3rdparty/libxml2/xmlschemas.c index d19de6df5f5..1efd0962496 100644 --- a/sdk/lib/3rdparty/libxml2/xmlschemas.c +++ b/sdk/lib/3rdparty/libxml2/xmlschemas.c @@ -860,6 +860,7 @@ struct _xmlSchemaIDCMatcher { int sizeKeySeqs; xmlSchemaItemListPtr targets; /* list of target-node (xmlSchemaPSVIIDCNodePtr) entries */ + xmlHashTablePtr htab; }; /* @@ -1002,11 +1003,11 @@ struct _xmlSchemaValidCtxt { int xsiAssemble; int depth; - xmlSchemaNodeInfoPtr *elemInfos; /* array of element informations */ + xmlSchemaNodeInfoPtr *elemInfos; /* array of element information */ int sizeElemInfos; xmlSchemaNodeInfoPtr inode; /* the current element information */ - xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC informations */ + xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC information */ xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */ xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */ @@ -1055,6 +1056,18 @@ struct _xmlSchemaSubstGroup { xmlSchemaItemListPtr members; }; +/** + * xmlIDCHashEntry: + * + * an entry in hash tables to quickly look up keys/uniques + */ +typedef struct _xmlIDCHashEntry xmlIDCHashEntry; +typedef xmlIDCHashEntry *xmlIDCHashEntryPtr; +struct _xmlIDCHashEntry { + xmlIDCHashEntryPtr next; /* next item with same hash */ + int index; /* index into associated item list */ +}; + /************************************************************************ * * * Some predeclarations * @@ -1478,6 +1491,7 @@ xmlSchemaWildcardPCToString(int pc) * @val: the precomputed value * @retValue: the returned value * @ws: the whitespace type of the value + * @for_hash: non-zero if this is supposed to generate a string for hashing * * Get a the canonical representation of the value. * The caller has to free the returned retValue. @@ -1486,9 +1500,10 @@ xmlSchemaWildcardPCToString(int pc) * API errors or if the value type is not supported yet. */ static int -xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val, - xmlSchemaWhitespaceValueType ws, - xmlChar **retValue) +xmlSchemaGetCanonValueWhtspExt_1(xmlSchemaValPtr val, + xmlSchemaWhitespaceValueType ws, + xmlChar **retValue, + int for_hash) { int list; xmlSchemaValType valType; @@ -1522,6 +1537,20 @@ xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val, xmlFree((xmlChar *) value2); goto internal_error; } + if (for_hash && valType == XML_SCHEMAS_DECIMAL) { + /* We can mostly use the canonical value for hashing, + except in the case of decimal. There the canonical + representation requires a trailing '.0' even for + non-fractional numbers, but for the derived integer + types it forbids any decimal point. Nevertheless they + compare equal if the value is equal. We need to generate + the same hash value for this to work, and it's easiest + to just cut off the useless '.0' suffix for the + decimal type. */ + int len = xmlStrlen(value2); + if (len > 2 && value2[len-1] == '0' && value2[len-2] == '.') + ((xmlChar*)value2)[len-2] = 0; + } value = value2; } if (*retValue == NULL) @@ -1548,6 +1577,22 @@ internal_error: return (-1); } +static int +xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val, + xmlSchemaWhitespaceValueType ws, + xmlChar **retValue) +{ + return xmlSchemaGetCanonValueWhtspExt_1(val, ws, retValue, 0); +} + +static int +xmlSchemaGetCanonValueHash(xmlSchemaValPtr val, + xmlChar **retValue) +{ + return xmlSchemaGetCanonValueWhtspExt_1(val, XML_SCHEMA_WHITESPACE_COLLAPSE, + retValue, 1); +} + /** * xmlSchemaFormatItemForReport: * @buf: the string buffer @@ -1873,7 +1918,7 @@ xmlSchemaPSimpleErr(const char *msg) /** * xmlSchemaPErrMemory: * @node: a context node - * @extra: extra informations + * @extra: extra information * * Handle an out of memory condition */ @@ -1995,7 +2040,7 @@ xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error, /** * xmlSchemaVTypeErrMemory: * @node: a context node - * @extra: extra informations + * @extra: extra information * * Handle an out of memory condition */ @@ -6031,7 +6076,7 @@ xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt, /** * xmlGetMaxOccurs: * @ctxt: a schema validation context - * @node: a subtree containing XML Schema informations + * @node: a subtree containing XML Schema information * * Get the maxOccurs property * @@ -6074,7 +6119,16 @@ xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, return (def); } while ((*cur >= '0') && (*cur <= '9')) { - ret = ret * 10 + (*cur - '0'); + if (ret > INT_MAX / 10) { + ret = INT_MAX; + } else { + int digit = *cur - '0'; + ret *= 10; + if (ret > INT_MAX - digit) + ret = INT_MAX; + else + ret += digit; + } cur++; } while (IS_BLANK_CH(*cur)) @@ -6096,7 +6150,7 @@ xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, /** * xmlGetMinOccurs: * @ctxt: a schema validation context - * @node: a subtree containing XML Schema informations + * @node: a subtree containing XML Schema information * * Get the minOccurs property * @@ -6126,7 +6180,16 @@ xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, return (def); } while ((*cur >= '0') && (*cur <= '9')) { - ret = ret * 10 + (*cur - '0'); + if (ret > INT_MAX / 10) { + ret = INT_MAX; + } else { + int digit = *cur - '0'; + ret *= 10; + if (ret > INT_MAX - digit) + ret = INT_MAX; + else + ret += digit; + } cur++; } while (IS_BLANK_CH(*cur)) @@ -6193,7 +6256,7 @@ xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt, /** * xmlGetBooleanProp: * @ctxt: a schema validation context - * @node: a subtree containing XML Schema informations + * @node: a subtree containing XML Schema information * @name: the attribute name * @def: the default value * @@ -6481,7 +6544,7 @@ xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt, * xmlSchemaParseLocalAttributes: * @ctxt: a schema validation context * @schema: the schema being built - * @node: a subtree containing XML Schema informations + * @node: a subtree containing XML Schema information * @type: the hosting type where the attributes will be anchored * * Parses attribute uses and attribute declarations and @@ -6523,7 +6586,7 @@ xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, * xmlSchemaParseAnnotation: * @ctxt: a schema validation context * @schema: the schema being built - * @node: a subtree containing XML Schema informations + * @node: a subtree containing XML Schema information * * parse a XML schema Attribute declaration * *WARNING* this interface is highly subject to change @@ -6643,7 +6706,7 @@ xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int neede * xmlSchemaParseFacet: * @ctxt: a schema validation context * @schema: the schema being built - * @node: a subtree containing XML Schema informations + * @node: a subtree containing XML Schema information * * parse a XML schema Facet declaration * *WARNING* this interface is highly subject to change @@ -6734,7 +6797,7 @@ xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, * xmlSchemaParseWildcardNs: * @ctxt: a schema parser context * @wildc: the wildcard, already created - * @node: a subtree containing XML Schema informations + * @node: a subtree containing XML Schema information * * Parses the attribute "processContents" and "namespace" * of a xsd:anyAttribute and xsd:any. @@ -6901,7 +6964,7 @@ xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt, * xmlSchemaParseAny: * @ctxt: a schema validation context * @schema: the schema being built - * @node: a subtree containing XML Schema informations + * @node: a subtree containing XML Schema information * * Parsea a XML schema element. A particle and wildcard * will be created (except if minOccurs==maxOccurs==0, in this case @@ -6996,7 +7059,7 @@ xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, * xmlSchemaParseNotation: * @ctxt: a schema validation context * @schema: the schema being built - * @node: a subtree containing XML Schema informations + * @node: a subtree containing XML Schema information * * parse a XML schema Notation declaration * @@ -7043,7 +7106,7 @@ xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, * xmlSchemaParseAnyAttribute: * @ctxt: a schema validation context * @schema: the schema being built - * @node: a subtree containing XML Schema informations + * @node: a subtree containing XML Schema information * * parse a XML schema AnyAttribute declaration * *WARNING* this interface is highly subject to change @@ -7113,7 +7176,7 @@ xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt, * xmlSchemaParseAttribute: * @ctxt: a schema validation context * @schema: the schema being built - * @node: a subtree containing XML Schema informations + * @node: a subtree containing XML Schema information * * parse a XML schema Attribute declaration * *WARNING* this interface is highly subject to change @@ -7656,7 +7719,7 @@ xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt, * xmlSchemaParseAttributeGroupRef: * @ctxt: a schema validation context * @schema: the schema being built - * @node: a subtree containing XML Schema informations + * @node: a subtree containing XML Schema information * * Parse an attribute group definition reference. * Note that a reference to an attribute group does not @@ -7789,7 +7852,7 @@ xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt, * xmlSchemaParseAttributeGroupDefinition: * @pctxt: a schema validation context * @schema: the schema being built - * @node: a subtree containing XML Schema informations + * @node: a subtree containing XML Schema information * * parse a XML schema Attribute Group declaration * *WARNING* this interface is highly subject to change @@ -8220,7 +8283,7 @@ xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem, * xmlSchemaParseIDCSelectorAndField: * @ctxt: a schema validation context * @schema: the schema being built - * @node: a subtree containing XML Schema informations + * @node: a subtree containing XML Schema information * * Parses a XML Schema identity-constraint definition's * and elements. @@ -8318,7 +8381,7 @@ xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt, * xmlSchemaParseIDC: * @ctxt: a schema validation context * @schema: the schema being built - * @node: a subtree containing XML Schema informations + * @node: a subtree containing XML Schema information * * Parses a XML Schema identity-constraint definition. * @@ -8465,7 +8528,7 @@ xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt, * xmlSchemaParseElement: * @ctxt: a schema validation context * @schema: the schema being built - * @node: a subtree containing XML Schema informations + * @node: a subtree containing XML Schema information * @topLevel: indicates if this is global declaration * * Parses a XML schema element declaration. @@ -8864,7 +8927,7 @@ return_null: * xmlSchemaParseUnion: * @ctxt: a schema validation context * @schema: the schema being built - * @node: a subtree containing XML Schema informations + * @node: a subtree containing XML Schema information * * parse a XML schema Union definition * *WARNING* this interface is highly subject to change @@ -9033,7 +9096,7 @@ xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, * xmlSchemaParseList: * @ctxt: a schema validation context * @schema: the schema being built - * @node: a subtree containing XML Schema informations + * @node: a subtree containing XML Schema information * * parse a XML schema List definition * *WARNING* this interface is highly subject to change @@ -9144,7 +9207,7 @@ xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, * xmlSchemaParseSimpleType: * @ctxt: a schema validation context * @schema: the schema being built - * @node: a subtree containing XML Schema informations + * @node: a subtree containing XML Schema information * * parse a XML schema Simple Type definition * *WARNING* this interface is highly subject to change @@ -9455,7 +9518,7 @@ xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt, * xmlSchemaParseModelGroupDefinition: * @ctxt: a schema validation context * @schema: the schema being built - * @node: a subtree containing XML Schema informations + * @node: a subtree containing XML Schema information * * Parses a XML schema model group definition. * @@ -10293,7 +10356,7 @@ xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location, * xmlSchemaAddSchemaDoc: * @pctxt: a schema validation context * @schema: the schema being built - * @node: a subtree containing XML Schema informations + * @node: a subtree containing XML Schema information * * Parse an included (and to-be-redefined) XML schema document. * @@ -10717,7 +10780,7 @@ exit_failure: * xmlSchemaParseImport: * @ctxt: a schema validation context * @schema: the schema being built - * @node: a subtree containing XML Schema informations + * @node: a subtree containing XML Schema information * * parse a XML schema Import definition * *WARNING* this interface is highly subject to change @@ -11209,7 +11272,7 @@ xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema, * xmlSchemaParseModelGroup: * @ctxt: a schema validation context * @schema: the schema being built - * @node: a subtree containing XML Schema informations + * @node: a subtree containing XML Schema information * @type: the "compositor" type * @particleNeeded: if a a model group with a particle * @@ -11489,7 +11552,7 @@ xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, * xmlSchemaParseRestriction: * @ctxt: a schema validation context * @schema: the schema being built - * @node: a subtree containing XML Schema informations + * @node: a subtree containing XML Schema information * * parse a XML schema Restriction definition * *WARNING* this interface is highly subject to change @@ -11792,7 +11855,7 @@ xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, * xmlSchemaParseExtension: * @ctxt: a schema validation context * @schema: the schema being built - * @node: a subtree containing XML Schema informations + * @node: a subtree containing XML Schema information * * Parses an , which is found inside a * or . @@ -11928,7 +11991,7 @@ xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, * xmlSchemaParseSimpleContent: * @ctxt: a schema validation context * @schema: the schema being built - * @node: a subtree containing XML Schema informations + * @node: a subtree containing XML Schema information * * parse a XML schema SimpleContent definition * *WARNING* this interface is highly subject to change @@ -12018,7 +12081,7 @@ xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt, * xmlSchemaParseComplexContent: * @ctxt: a schema validation context * @schema: the schema being built - * @node: a subtree containing XML Schema informations + * @node: a subtree containing XML Schema information * * parse a XML schema ComplexContent definition * *WARNING* this interface is highly subject to change @@ -12113,7 +12176,7 @@ xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt, * xmlSchemaParseComplexType: * @ctxt: a schema validation context * @schema: the schema being built - * @node: a subtree containing XML Schema informations + * @node: a subtree containing XML Schema information * * parse a XML schema Complex Type definition * *WARNING* this interface is highly subject to change @@ -14658,6 +14721,7 @@ xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type) return (NULL); } +#if 0 /** * xmlSchemaGetParticleTotalRangeMin: * @particle: the particle @@ -14713,7 +14777,6 @@ xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle) } } -#if 0 /** * xmlSchemaGetParticleTotalRangeMax: * @particle: the particle @@ -14775,6 +14838,48 @@ xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle) } #endif +/** + * xmlSchemaGetParticleEmptiable: + * @particle: the particle + * + * Returns 1 if emptiable, 0 otherwise. + */ +static int +xmlSchemaGetParticleEmptiable(xmlSchemaParticlePtr particle) +{ + xmlSchemaParticlePtr part; + int emptiable; + + if ((particle->children == NULL) || (particle->minOccurs == 0)) + return (1); + + part = (xmlSchemaParticlePtr) particle->children->children; + if (part == NULL) + return (1); + + while (part != NULL) { + if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || + (part->children->type == XML_SCHEMA_TYPE_ANY)) + emptiable = (part->minOccurs == 0); + else + emptiable = xmlSchemaGetParticleEmptiable(part); + if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) { + if (emptiable) + return (1); + } else { + /* and */ + if (!emptiable) + return (0); + } + part = (xmlSchemaParticlePtr) part->next; + } + + if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) + return (0); + else + return (1); +} + /** * xmlSchemaIsParticleEmptiable: * @particle: the particle @@ -14797,10 +14902,8 @@ xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle) * SPEC (2) "Its {term} is a group and the minimum part of the * effective total range of that group, [...] is 0." */ - if (WXS_IS_MODEL_GROUP(particle->children)) { - if (xmlSchemaGetParticleTotalRangeMin(particle) == 0) - return (1); - } + if (WXS_IS_MODEL_GROUP(particle->children)) + return (xmlSchemaGetParticleEmptiable(particle)); return (0); } @@ -14938,7 +15041,7 @@ xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt, } if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) { /* - * Avoid inifinite recursion on circular types not yet checked. + * Avoid infinite recursion on circular types not yet checked. */ return (0); } @@ -20961,7 +21064,7 @@ xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt, break; case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB: /* - * Handle attribue prohibition which had a + * Handle attribute prohibition which had a * "ref" attribute. */ xmlSchemaResolveAttrUseProhibReferences( @@ -22293,6 +22396,17 @@ xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind) } } +static void +xmlFreeIDCHashEntry (void *payload, const xmlChar *name ATTRIBUTE_UNUSED) +{ + xmlIDCHashEntryPtr e = payload, n; + while (e) { + n = e->next; + xmlFree(e); + e = n; + } +} + /** * xmlSchemaIDCFreeMatcherList: * @matcher: the first IDC matcher in the list @@ -22331,6 +22445,8 @@ xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher) } xmlSchemaItemListFree(matcher->targets); } + if (matcher->htab != NULL) + xmlHashFree(matcher->htab, xmlFreeIDCHashEntry); xmlFree(matcher); matcher = next; } @@ -22381,6 +22497,10 @@ xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt, xmlSchemaItemListFree(matcher->targets); matcher->targets = NULL; } + if (matcher->htab != NULL) { + xmlHashFree(matcher->htab, xmlFreeIDCHashEntry); + matcher->htab = NULL; + } matcher->next = NULL; /* * Cache the matcher. @@ -22615,10 +22735,10 @@ next_sto: } static const xmlChar * -xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt, - xmlChar **buf, - xmlSchemaPSVIIDCKeyPtr *seq, - int count) +xmlSchemaFormatIDCKeySequence_1(xmlSchemaValidCtxtPtr vctxt, + xmlChar **buf, + xmlSchemaPSVIIDCKeyPtr *seq, + int count, int for_hash) { int i, res; xmlChar *value = NULL; @@ -22626,9 +22746,13 @@ xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt, *buf = xmlStrdup(BAD_CAST "["); for (i = 0; i < count; i++) { *buf = xmlStrcat(*buf, BAD_CAST "'"); - res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val, - xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type), - &value); + if (!for_hash) + res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val, + xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type), + &value); + else { + res = xmlSchemaGetCanonValueHash(seq[i]->val, &value); + } if (res == 0) *buf = xmlStrcat(*buf, BAD_CAST value); else { @@ -22650,6 +22774,24 @@ xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt, return (BAD_CAST *buf); } +static const xmlChar * +xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt, + xmlChar **buf, + xmlSchemaPSVIIDCKeyPtr *seq, + int count) +{ + return xmlSchemaFormatIDCKeySequence_1(vctxt, buf, seq, count, 0); +} + +static const xmlChar * +xmlSchemaHashKeySequence(xmlSchemaValidCtxtPtr vctxt, + xmlChar **buf, + xmlSchemaPSVIIDCKeyPtr *seq, + int count) +{ + return xmlSchemaFormatIDCKeySequence_1(vctxt, buf, seq, count, 1); +} + /** * xmlSchemaXPathPop: * @vctxt: the WXS validation context @@ -23011,15 +23153,25 @@ create_key: if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) && (targets->nbItems != 0)) { xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq; + xmlIDCHashEntryPtr e; - i = 0; res = 0; + + if (!matcher->htab) + e = NULL; + else { + xmlChar *value = NULL; + xmlSchemaHashKeySequence(vctxt, &value, *keySeq, nbKeys); + e = xmlHashLookup(matcher->htab, value); + FREE_AND_NULL(value); + } + /* * Compare the key-sequences, key by key. */ - do { + for (;e; e = e->next) { bkeySeq = - ((xmlSchemaPSVIIDCNodePtr) targets->items[i])->keys; + ((xmlSchemaPSVIIDCNodePtr) targets->items[e->index])->keys; for (j = 0; j < nbKeys; j++) { ckey = (*keySeq)[j]; bkey = bkeySeq[j]; @@ -23040,9 +23192,8 @@ create_key: */ break; } - i++; - } while (i < targets->nbItems); - if (i != targets->nbItems) { + } + if (e) { xmlChar *str = NULL, *strB = NULL; /* * TODO: Try to report the key-sequence. @@ -23120,6 +23271,24 @@ create_key: } return (-1); } + if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) { + xmlChar *value = NULL; + xmlIDCHashEntryPtr r, e; + if (!matcher->htab) + matcher->htab = xmlHashCreate(4); + xmlSchemaHashKeySequence(vctxt, &value, ntItem->keys, nbKeys); + e = xmlMalloc(sizeof *e); + e->index = targets->nbItems - 1; + r = xmlHashLookup(matcher->htab, value); + if (r) { + e->next = r->next; + r->next = e; + } else { + e->next = NULL; + xmlHashAddEntry(matcher->htab, value, e); + } + FREE_AND_NULL(value); + } goto selector_leave; selector_key_error: @@ -23376,6 +23545,10 @@ xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt, matcher->targets->items = NULL; matcher->targets->sizeItems = 0; matcher->targets->nbItems = 0; + if (matcher->htab) { + xmlHashFree(matcher->htab, xmlFreeIDCHashEntry); + matcher->htab = NULL; + } } else { /* * Compare the key-sequences and add to the IDC node-table. @@ -23823,6 +23996,7 @@ xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt) int i, j, k, res, nbFields, hasDupls; xmlSchemaPSVIIDCKeyPtr *refKeys, *keys; xmlSchemaPSVIIDCNodePtr refNode = NULL; + xmlHashTablePtr table = NULL; nbFields = matcher->aidc->def->nbFields; @@ -23840,26 +24014,52 @@ xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt) /* * Search for a matching key-sequences. */ + if (bind) { + table = xmlHashCreate(bind->nbNodes * 2); + for (j = 0; j < bind->nbNodes; j++) { + xmlChar *value; + xmlIDCHashEntryPtr r, e; + keys = bind->nodeTable[j]->keys; + xmlSchemaHashKeySequence(vctxt, &value, keys, nbFields); + e = xmlMalloc(sizeof *e); + e->index = j; + r = xmlHashLookup(table, value); + if (r) { + e->next = r->next; + r->next = e; + } else { + e->next = NULL; + xmlHashAddEntry(table, value, e); + } + FREE_AND_NULL(value); + } + } for (i = 0; i < matcher->targets->nbItems; i++) { res = 0; refNode = matcher->targets->items[i]; if (bind != NULL) { + xmlChar *value; + xmlIDCHashEntryPtr e; refKeys = refNode->keys; - for (j = 0; j < bind->nbNodes; j++) { - keys = bind->nodeTable[j]->keys; + xmlSchemaHashKeySequence(vctxt, &value, refKeys, nbFields); + e = xmlHashLookup(table, value); + FREE_AND_NULL(value); + res = 0; + for (;e; e = e->next) { + keys = bind->nodeTable[e->index]->keys; for (k = 0; k < nbFields; k++) { res = xmlSchemaAreValuesEqual(keys[k]->val, - refKeys[k]->val); + refKeys[k]->val); if (res == 0) - break; + break; else if (res == -1) { return (-1); } } if (res == 1) { /* - * Match found. - */ + * Match found. + */ break; } } @@ -23914,6 +24114,9 @@ xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt) FREE_AND_NULL(strB); } } + if (table) { + xmlHashFree(table, xmlFreeIDCHashEntry); + } } matcher = matcher->next; } @@ -24184,7 +24387,7 @@ xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt, unsigned long length, int fireErrors) { - int ret, error = 0; + int ret, error = 0, found; xmlSchemaTypePtr tmpType; xmlSchemaFacetLinkPtr facetLink; @@ -24308,103 +24511,98 @@ WXS_IS_LIST: } pattern_and_enum: - if (error >= 0) { - int found = 0; - /* - * Process enumerations. Facet values are in the value space - * of the defining type's base type. This seems to be a bug in the - * XML Schema 1.0 spec. Use the whitespace type of the base type. - * Only the first set of enumerations in the ancestor-or-self axis - * is used for validation. - */ - ret = 0; - tmpType = type; - do { - for (facet = tmpType->facets; facet != NULL; facet = facet->next) { - if (facet->type != XML_SCHEMA_FACET_ENUMERATION) - continue; - found = 1; - ret = xmlSchemaAreValuesEqual(facet->val, val); - if (ret == 1) - break; - else if (ret < 0) { - AERROR_INT("xmlSchemaValidateFacets", - "validating against an enumeration facet"); - return (-1); - } - } - if (ret != 0) - break; - /* - * Break on the first set of enumerations. Any additional - * enumerations which might be existent on the ancestors - * of the current type are restricted by this set; thus - * *must* *not* be taken into account. - */ - if (found) - break; - tmpType = tmpType->baseType; - } while ((tmpType != NULL) && - (tmpType->type != XML_SCHEMA_TYPE_BASIC)); - if (found && (ret == 0)) { - ret = XML_SCHEMAV_CVC_ENUMERATION_VALID; - if (fireErrors) { - xmlSchemaFacetErr(actxt, ret, node, - value, 0, type, NULL, NULL, NULL, NULL); - } else - return (ret); - if (error == 0) - error = ret; - } + found = 0; + /* + * Process enumerations. Facet values are in the value space + * of the defining type's base type. This seems to be a bug in the + * XML Schema 1.0 spec. Use the whitespace type of the base type. + * Only the first set of enumerations in the ancestor-or-self axis + * is used for validation. + */ + ret = 0; + tmpType = type; + do { + for (facet = tmpType->facets; facet != NULL; facet = facet->next) { + if (facet->type != XML_SCHEMA_FACET_ENUMERATION) + continue; + found = 1; + ret = xmlSchemaAreValuesEqual(facet->val, val); + if (ret == 1) + break; + else if (ret < 0) { + AERROR_INT("xmlSchemaValidateFacets", + "validating against an enumeration facet"); + return (-1); + } + } + if (ret != 0) + break; + /* + * Break on the first set of enumerations. Any additional + * enumerations which might be existent on the ancestors + * of the current type are restricted by this set; thus + * *must* *not* be taken into account. + */ + if (found) + break; + tmpType = tmpType->baseType; + } while ((tmpType != NULL) && + (tmpType->type != XML_SCHEMA_TYPE_BASIC)); + if (found && (ret == 0)) { + ret = XML_SCHEMAV_CVC_ENUMERATION_VALID; + if (fireErrors) { + xmlSchemaFacetErr(actxt, ret, node, + value, 0, type, NULL, NULL, NULL, NULL); + } else + return (ret); + if (error == 0) + error = ret; } - if (error >= 0) { - int found; - /* - * Process patters. Pattern facets are ORed at type level - * and ANDed if derived. Walk the base type axis. - */ - tmpType = type; - facet = NULL; - do { - found = 0; - for (facetLink = tmpType->facetSet; facetLink != NULL; - facetLink = facetLink->next) { - if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN) - continue; - found = 1; - /* - * NOTE that for patterns, @value needs to be the - * normalized value. - */ - ret = xmlRegexpExec(facetLink->facet->regexp, value); - if (ret == 1) - break; - else if (ret < 0) { - AERROR_INT("xmlSchemaValidateFacets", - "validating against a pattern facet"); - return (-1); - } else { - /* - * Save the last non-validating facet. - */ - facet = facetLink->facet; - } - } - if (found && (ret != 1)) { - ret = XML_SCHEMAV_CVC_PATTERN_VALID; - if (fireErrors) { - xmlSchemaFacetErr(actxt, ret, node, - value, 0, type, facet, NULL, NULL, NULL); - } else - return (ret); - if (error == 0) - error = ret; - break; - } - tmpType = tmpType->baseType; - } while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC)); - } + /* + * Process patters. Pattern facets are ORed at type level + * and ANDed if derived. Walk the base type axis. + */ + tmpType = type; + facet = NULL; + do { + found = 0; + for (facetLink = tmpType->facetSet; facetLink != NULL; + facetLink = facetLink->next) { + if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN) + continue; + found = 1; + /* + * NOTE that for patterns, @value needs to be the + * normalized value. + */ + ret = xmlRegexpExec(facetLink->facet->regexp, value); + if (ret == 1) + break; + else if (ret < 0) { + AERROR_INT("xmlSchemaValidateFacets", + "validating against a pattern facet"); + return (-1); + } else { + /* + * Save the last non-validating facet. + */ + facet = facetLink->facet; + } + } + if (found && (ret != 1)) { + ret = XML_SCHEMAV_CVC_PATTERN_VALID; + if (fireErrors) { + xmlSchemaFacetErr(actxt, ret, node, + value, 0, type, facet, NULL, NULL, NULL); + } else + return (ret); + if (error == 0) + error = ret; + break; + } + tmpType = tmpType->baseType; + } while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC)); return (error); } @@ -27802,7 +28000,7 @@ xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt) * @warn: the warning function * @ctx: the functions context * - * Set the error and warning callback informations + * Set the error and warning callback information */ void xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt, @@ -27847,7 +28045,7 @@ xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt, * @warn: the warning function result * @ctx: the functions context result * - * Get the error and warning callback informations + * Get the error and warning callback information * * Returns -1 in case of error and 0 otherwise */ @@ -27938,6 +28136,10 @@ xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt) VERROR(1, NULL, "The document has no document element"); return (1); } + for (node = valRoot->next; node != NULL; node = node->next) { + if (node->type == XML_ELEMENT_NODE) + VERROR(1, NULL, "The document has more than one top element"); + } vctxt->depth = -1; vctxt->validationRoot = valRoot; node = valRoot; @@ -28095,7 +28297,6 @@ xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) { vctxt->nberrors = 0; vctxt->depth = -1; vctxt->skipDepth = -1; - vctxt->xsiAssemble = 0; vctxt->hasKeyrefs = 0; #ifdef ENABLE_IDC_NODE_TABLES_TEST vctxt->createIDCNodeTables = 1; @@ -28273,13 +28474,13 @@ struct _xmlSchemaSplitSAXData { struct _xmlSchemaSAXPlug { unsigned int magic; - /* the original callbacks informations */ + /* the original callbacks information */ xmlSAXHandlerPtr *user_sax_ptr; xmlSAXHandlerPtr user_sax; void **user_data_ptr; void *user_data; - /* the block plugged back and validation informations */ + /* the block plugged back and validation information */ xmlSAXHandler schemas_sax; xmlSchemaValidCtxtPtr ctxt; }; diff --git a/sdk/lib/3rdparty/libxml2/xmlschemastypes.c b/sdk/lib/3rdparty/libxml2/xmlschemastypes.c index e7764d90581..9c2dff06b45 100644 --- a/sdk/lib/3rdparty/libxml2/xmlschemastypes.c +++ b/sdk/lib/3rdparty/libxml2/xmlschemastypes.c @@ -199,7 +199,7 @@ static xmlSchemaTypePtr xmlSchemaTypeNmtokensDef = NULL; ************************************************************************/ /** * xmlSchemaTypeErrMemory: - * @extra: extra informations + * @extra: extra information * * Handle an out of memory condition */ @@ -1160,9 +1160,12 @@ static const unsigned int daysInMonthLeap[12] = #define VALID_DATETIME(dt) \ (VALID_DATE(dt) && VALID_TIME(dt)) -#define SECS_PER_MIN (60) -#define SECS_PER_HOUR (60 * SECS_PER_MIN) -#define SECS_PER_DAY (24 * SECS_PER_HOUR) +#define SECS_PER_MIN 60 +#define MINS_PER_HOUR 60 +#define HOURS_PER_DAY 24 +#define SECS_PER_HOUR (MINS_PER_HOUR * SECS_PER_MIN) +#define SECS_PER_DAY (HOURS_PER_DAY * SECS_PER_HOUR) +#define MINS_PER_DAY (HOURS_PER_DAY * MINS_PER_HOUR) static const long dayInYearByMonth[12] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; @@ -1222,7 +1225,14 @@ _xmlSchemaParseGYear (xmlSchemaValDatePtr dt, const xmlChar **str) { firstChar = cur; while ((*cur >= '0') && (*cur <= '9')) { - dt->year = dt->year * 10 + (*cur - '0'); + int digit = *cur - '0'; + + if (dt->year > LONG_MAX / 10) + return 2; + dt->year *= 10; + if (dt->year > LONG_MAX - digit) + return 2; + dt->year += digit; cur++; digcnt++; } @@ -1791,10 +1801,8 @@ xmlSchemaValidateDuration (xmlSchemaTypePtr type ATTRIBUTE_UNUSED, xmlSchemaValPtr dur; int isneg = 0; unsigned int seq = 0; - double num; - int num_type = 0; /* -1 = invalid, 0 = int, 1 = floating */ - const xmlChar desig[] = {'Y', 'M', 'D', 'H', 'M', 'S'}; - const double multi[] = { 0.0, 0.0, 86400.0, 3600.0, 60.0, 1.0, 0.0}; + long days, secs = 0; + double sec_frac = 0.0; if (duration == NULL) return -1; @@ -1819,6 +1827,10 @@ xmlSchemaValidateDuration (xmlSchemaTypePtr type ATTRIBUTE_UNUSED, return -1; while (*cur != 0) { + long num = 0; + size_t has_digits = 0; + int has_frac = 0; + const xmlChar desig[] = {'Y', 'M', 'D', 'H', 'M', 'S'}; /* input string should be empty or invalid date/time item */ if (seq >= sizeof(desig)) @@ -1826,53 +1838,104 @@ xmlSchemaValidateDuration (xmlSchemaTypePtr type ATTRIBUTE_UNUSED, /* T designator must be present for time items */ if (*cur == 'T') { - if (seq <= 3) { - seq = 3; - cur++; - } else - return 1; + if (seq > 3) + goto error; + cur++; + seq = 3; } else if (seq == 3) goto error; - /* parse the number portion of the item */ - PARSE_NUM(num, cur, num_type); + /* Parse integral part. */ + while (*cur >= '0' && *cur <= '9') { + long digit = *cur - '0'; - if ((num_type == -1) || (*cur == 0)) - goto error; + if (num > LONG_MAX / 10) + goto error; + num *= 10; + if (num > LONG_MAX - digit) + goto error; + num += digit; - /* update duration based on item type */ - while (seq < sizeof(desig)) { - if (*cur == desig[seq]) { + has_digits = 1; + cur++; + } - /* verify numeric type; only seconds can be float */ - if ((num_type != 0) && (seq < (sizeof(desig)-1))) - goto error; - - switch (seq) { - case 0: - dur->value.dur.mon = (long)num * 12; - break; - case 1: - dur->value.dur.mon += (long)num; - break; - default: - /* convert to seconds using multiplier */ - dur->value.dur.sec += num * multi[seq]; - seq++; - break; - } - - break; /* exit loop */ + if (*cur == '.') { + /* Parse fractional part. */ + double mult = 1.0; + cur++; + has_frac = 1; + while (*cur >= '0' && *cur <= '9') { + mult /= 10.0; + sec_frac += (*cur - '0') * mult; + has_digits = 1; + cur++; } - /* no date designators found? */ - if ((++seq == 3) || (seq == 6)) + } + + while (*cur != desig[seq]) { + seq++; + /* No T designator or invalid char. */ + if (seq == 3 || seq == sizeof(desig)) goto error; } cur++; - if (collapse) - while IS_WSP_BLANK_CH(*cur) cur++; + + if (!has_digits || (has_frac && (seq != 5))) + goto error; + + switch (seq) { + case 0: + /* Year */ + if (num > LONG_MAX / 12) + goto error; + dur->value.dur.mon = num * 12; + break; + case 1: + /* Month */ + if (dur->value.dur.mon > LONG_MAX - num) + goto error; + dur->value.dur.mon += num; + break; + case 2: + /* Day */ + dur->value.dur.day = num; + break; + case 3: + /* Hour */ + days = num / HOURS_PER_DAY; + if (dur->value.dur.day > LONG_MAX - days) + goto error; + dur->value.dur.day += days; + secs = (num % HOURS_PER_DAY) * SECS_PER_HOUR; + break; + case 4: + /* Minute */ + days = num / MINS_PER_DAY; + if (dur->value.dur.day > LONG_MAX - days) + goto error; + dur->value.dur.day += days; + secs += (num % MINS_PER_DAY) * SECS_PER_MIN; + break; + case 5: + /* Second */ + days = num / SECS_PER_DAY; + if (dur->value.dur.day > LONG_MAX - days) + goto error; + dur->value.dur.day += days; + secs += num % SECS_PER_DAY; + break; + } + + seq++; } + days = secs / SECS_PER_DAY; + if (dur->value.dur.day > LONG_MAX - days) + goto error; + dur->value.dur.day += days; + dur->value.dur.sec = (secs % SECS_PER_DAY) + sec_frac; + if (isneg) { dur->value.dur.mon = -dur->value.dur.mon; dur->value.dur.day = -dur->value.dur.day; @@ -2124,6 +2187,44 @@ xmlSchemaParseUInt(const xmlChar **str, unsigned long *llo, return(ret); } +/* + * xmlSchemaCheckLanguageType + * @value: the value to check + * + * Check that a value conforms to the lexical space of the language datatype. + * Must conform to [a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})* + * + * Returns 1 if this validates, 0 otherwise. + */ +static int +xmlSchemaCheckLanguageType(const xmlChar* value) { + int first = 1, len = 0; + const xmlChar* cur = value; + + if (value == NULL) + return (0); + + while (cur[0] != 0) { + if (!( ((cur[0] >= 'a') && (cur[0] <= 'z')) || ((cur[0] >= 'A') && (cur[0] <= 'Z')) + || (cur[0] == '-') + || ((first == 0) && (xmlIsDigit_ch(cur[0]))) )) + return (0); + if (cur[0] == '-') { + if ((len < 1) || (len > 8)) + return (0); + len = 0; + first = 0; + } + else + len++; + cur++; + } + if ((len < 1) || (len > 8)) + return (0); + + return (1); +} + /** * xmlSchemaValAtomicType: * @type: the predefined type @@ -2636,12 +2737,13 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar * value, goto return0; } case XML_SCHEMAS_LANGUAGE: - if (normOnTheFly) { + if ((norm == NULL) && (normOnTheFly)) { norm = xmlSchemaCollapseString(value); if (norm != NULL) value = norm; } - if (xmlCheckLanguageID(value) == 1) { + + if (xmlSchemaCheckLanguageType(value) == 1) { if (val != NULL) { v = xmlSchemaNewValue(XML_SCHEMAS_LANGUAGE); if (v != NULL) { @@ -3628,6 +3730,8 @@ xmlSchemaCompareDurations(xmlSchemaValPtr x, xmlSchemaValPtr y) minday = 0; maxday = 0; } else { + if (myear > LONG_MAX / 366) + return -2; /* FIXME: This doesn't take leap year exceptions every 100/400 years into account. */ maxday = 365 * myear + (myear + 3) / 4; @@ -4016,6 +4120,14 @@ xmlSchemaCompareDates (xmlSchemaValPtr x, xmlSchemaValPtr y) if ((x == NULL) || (y == NULL)) return -2; + if ((x->value.date.year > LONG_MAX / 366) || + (x->value.date.year < LONG_MIN / 366) || + (y->value.date.year > LONG_MAX / 366) || + (y->value.date.year < LONG_MIN / 366)) { + /* Possible overflow when converting to days. */ + return -2; + } + if (x->value.date.tz_flag) { if (!y->value.date.tz_flag) { @@ -5069,7 +5181,7 @@ xmlSchemaGetFacetValueAsULong(xmlSchemaFacetPtr facet) /* * TODO: Check if this is a decimal. */ - if (facet == NULL) + if (facet == NULL || facet->val == NULL) return 0; return ((unsigned long) facet->val->value.decimal.lo); } @@ -6003,13 +6115,13 @@ xmlSchemaGetCanonValue(xmlSchemaValPtr val, const xmlChar **retValue) * recoverable timezone and not "Z". */ snprintf(buf, 30, - "%04ld:%02u:%02uZ", + "%04ld-%02u-%02uZ", norm->value.date.year, norm->value.date.mon, norm->value.date.day); xmlSchemaFreeValue(norm); } else { snprintf(buf, 30, - "%04ld:%02u:%02u", + "%04ld-%02u-%02u", val->value.date.year, val->value.date.mon, val->value.date.day); } @@ -6030,14 +6142,14 @@ xmlSchemaGetCanonValue(xmlSchemaValPtr val, const xmlChar **retValue) * TODO: Check if "%.14g" is portable. */ snprintf(buf, 50, - "%04ld:%02u:%02uT%02u:%02u:%02.14gZ", + "%04ld-%02u-%02uT%02u:%02u:%02.14gZ", norm->value.date.year, norm->value.date.mon, norm->value.date.day, norm->value.date.hour, norm->value.date.min, norm->value.date.sec); xmlSchemaFreeValue(norm); } else { snprintf(buf, 50, - "%04ld:%02u:%02uT%02u:%02u:%02.14g", + "%04ld-%02u-%02uT%02u:%02u:%02.14g", val->value.date.year, val->value.date.mon, val->value.date.day, val->value.date.hour, val->value.date.min, val->value.date.sec); diff --git a/sdk/lib/3rdparty/libxml2/xmlstring.c b/sdk/lib/3rdparty/libxml2/xmlstring.c index 8d2e06f66cd..e8a1e45d1b3 100644 --- a/sdk/lib/3rdparty/libxml2/xmlstring.c +++ b/sdk/lib/3rdparty/libxml2/xmlstring.c @@ -130,16 +130,18 @@ xmlCharStrdup(const char *cur) { int xmlStrcmp(const xmlChar *str1, const xmlChar *str2) { - register int tmp; - if (str1 == str2) return(0); if (str1 == NULL) return(-1); if (str2 == NULL) return(1); +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + return(strcmp((const char *)str1, (const char *)str2)); +#else do { - tmp = *str1++ - *str2; + int tmp = *str1++ - *str2; if (tmp != 0) return(tmp); } while (*str2++ != 0); return 0; +#endif } /** @@ -158,10 +160,14 @@ xmlStrEqual(const xmlChar *str1, const xmlChar *str2) { if (str1 == str2) return(1); if (str1 == NULL) return(0); if (str2 == NULL) return(0); +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + return(strcmp((const char *)str1, (const char *)str2) == 0); +#else do { if (*str1++ != *str2) return(0); } while (*str2++); return(1); +#endif } /** @@ -204,18 +210,15 @@ xmlStrQEqual(const xmlChar *pref, const xmlChar *name, const xmlChar *str) { int xmlStrncmp(const xmlChar *str1, const xmlChar *str2, int len) { - register int tmp; - if (len <= 0) return(0); if (str1 == str2) return(0); if (str1 == NULL) return(-1); if (str2 == NULL) return(1); -#ifdef __GNUC__ - tmp = strncmp((const char *)str1, (const char *)str2, len); - return tmp; +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + return(strncmp((const char *)str1, (const char *)str2, len)); #else do { - tmp = *str1++ - *str2; + int tmp = *str1++ - *str2; if (tmp != 0 || --len == 0) return(tmp); } while (*str2++ != 0); return 0; diff --git a/sdk/lib/3rdparty/libxml2/xpath.c b/sdk/lib/3rdparty/libxml2/xpath.c index 9f64ab9ab49..7497ba07d6f 100644 --- a/sdk/lib/3rdparty/libxml2/xpath.c +++ b/sdk/lib/3rdparty/libxml2/xpath.c @@ -135,6 +135,17 @@ */ #define XPATH_MAX_NODESET_LENGTH 10000000 +/* + * XPATH_MAX_RECRUSION_DEPTH: + * Maximum amount of nested functions calls when parsing or evaluating + * expressions + */ +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION +#define XPATH_MAX_RECURSION_DEPTH 500 +#else +#define XPATH_MAX_RECURSION_DEPTH 5000 +#endif + /* * TODO: * There are a few spots where some tests are done which depend upon ascii @@ -477,14 +488,6 @@ int wrap_cmp( xmlNodePtr x, xmlNodePtr y ); * * ************************************************************************/ -#ifndef INFINITY -#define INFINITY (DBL_MAX * DBL_MAX) -#endif - -#ifndef NAN -#define NAN (INFINITY / INFINITY) -#endif - double xmlXPathNAN; double xmlXPathPINF; double xmlXPathNINF; @@ -494,11 +497,14 @@ double xmlXPathNINF; * * Initialize the XPath environment */ +ATTRIBUTE_NO_SANITIZE("float-divide-by-zero") void xmlXPathInit(void) { - xmlXPathNAN = NAN; - xmlXPathPINF = INFINITY; - xmlXPathNINF = -INFINITY; + /* MSVC doesn't allow division by zero in constant expressions. */ + double zero = 0.0; + xmlXPathNAN = 0.0 / zero; + xmlXPathPINF = 1.0 / zero; + xmlXPathNINF = -xmlXPathPINF; } /** @@ -527,9 +533,9 @@ xmlXPathIsInf(double val) { #ifdef isinf return isinf(val) ? (val > 0 ? 1 : -1) : 0; #else - if (val >= INFINITY) + if (val >= xmlXPathPINF) return 1; - if (val <= -INFINITY) + if (val <= -xmlXPathPINF) return -1; return 0; #endif @@ -619,7 +625,7 @@ static const char *xmlXPathErrorMessages[] = { /** * xmlXPathErrMemory: * @ctxt: an XPath context - * @extra: extra informations + * @extra: extra information * * Handle a redefinition of attribute error */ @@ -662,7 +668,7 @@ xmlXPathErrMemory(xmlXPathContextPtr ctxt, const char *extra) /** * xmlXPathPErrMemory: * @ctxt: an XPath parser context - * @extra: extra informations + * @extra: extra information * * Handle a redefinition of attribute error */ @@ -1746,7 +1752,6 @@ static int xmlXPathDebugObjMaxUsers = 0; static int xmlXPathDebugObjMaxXSLTTree = 0; static int xmlXPathDebugObjMaxAll = 0; -/* REVISIT TODO: Make this static when committing */ static void xmlXPathDebugObjUsageReset(xmlXPathContextPtr ctxt) { @@ -2061,7 +2066,6 @@ xmlXPathDebugObjUsageReleased(xmlXPathContextPtr ctxt, xmlXPathDebugObjCounterAll--; } -/* REVISIT TODO: Make this static when committing */ static void xmlXPathDebugObjUsageDisplay(xmlXPathContextPtr ctxt) { @@ -5864,10 +5868,10 @@ xmlXPathCastNodeToNumber (xmlNodePtr node) { double ret; if (node == NULL) - return(NAN); + return(xmlXPathNAN); strval = xmlXPathCastNodeToString(node); if (strval == NULL) - return(NAN); + return(xmlXPathNAN); ret = xmlXPathCastStringToNumber(strval); xmlFree(strval); @@ -5888,7 +5892,7 @@ xmlXPathCastNodeSetToNumber (xmlNodeSetPtr ns) { double ret; if (ns == NULL) - return(NAN); + return(xmlXPathNAN); str = xmlXPathCastNodeSetToString(ns); ret = xmlXPathCastStringToNumber(str); xmlFree(str); @@ -5908,13 +5912,13 @@ xmlXPathCastToNumber(xmlXPathObjectPtr val) { double ret = 0.0; if (val == NULL) - return(NAN); + return(xmlXPathNAN); switch (val->type) { case XPATH_UNDEFINED: #ifdef DEBUG_EXPR xmlGenericError(xmlGenericErrorContext, "NUMBER: undefined\n"); #endif - ret = NAN; + ret = xmlXPathNAN; break; case XPATH_NODESET: case XPATH_XSLT_TREE: @@ -5934,7 +5938,7 @@ xmlXPathCastToNumber(xmlXPathObjectPtr val) { case XPATH_RANGE: case XPATH_LOCATIONSET: TODO; - ret = NAN; + ret = xmlXPathNAN; break; } return(ret); @@ -6120,9 +6124,6 @@ xmlXPathNewContext(xmlDocPtr doc) { ret->contextSize = -1; ret->proximityPosition = -1; - ret->maxDepth = INT_MAX; - ret->maxParserDepth = INT_MAX; - #ifdef XP_DEFAULT_CACHE_ON if (xmlXPathContextSetCache(ret, 1, -1, 0) == -1) { xmlXPathFreeContext(ret); @@ -7564,7 +7565,7 @@ xmlXPathModValues(xmlXPathParserContextPtr ctxt) { CHECK_TYPE(XPATH_NUMBER); arg1 = ctxt->value->floatval; if (arg2 == 0) - ctxt->value->floatval = NAN; + ctxt->value->floatval = xmlXPathNAN; else { ctxt->value->floatval = fmod(arg1, arg2); } @@ -9994,7 +9995,7 @@ xmlXPathStringEvalNumber(const xmlChar *str) { if (cur == NULL) return(0); while (IS_BLANK_CH(*cur)) cur++; if ((*cur != '.') && ((*cur < '0') || (*cur > '9')) && (*cur != '-')) { - return(NAN); + return(xmlXPathNAN); } if (*cur == '-') { isneg = 1; @@ -10030,7 +10031,7 @@ xmlXPathStringEvalNumber(const xmlChar *str) { cur++; if (((*cur < '0') || (*cur > '9')) && (!ok)) { - return(NAN); + return(xmlXPathNAN); } while (*cur == '0') { frac = frac + 1; @@ -10063,7 +10064,7 @@ xmlXPathStringEvalNumber(const xmlChar *str) { } } while (IS_BLANK_CH(*cur)) cur++; - if (*cur != 0) return(NAN); + if (*cur != 0) return(xmlXPathNAN); if (isneg) ret = -ret; if (is_exponent_negative) exponent = -exponent; ret *= pow(10.0, (double)exponent); @@ -10088,6 +10089,7 @@ xmlXPathCompNumber(xmlXPathParserContextPtr ctxt) int ok = 0; int exponent = 0; int is_exponent_negative = 0; + xmlXPathObjectPtr num; #ifdef __GNUC__ unsigned long tmp = 0; double temp; @@ -10160,8 +10162,13 @@ xmlXPathCompNumber(xmlXPathParserContextPtr ctxt) exponent = -exponent; ret *= pow(10.0, (double) exponent); } - PUSH_LONG_EXPR(XPATH_OP_VALUE, XPATH_NUMBER, 0, 0, - xmlXPathCacheNewFloat(ctxt->context, ret), NULL); + num = xmlXPathCacheNewFloat(ctxt->context, ret); + if (num == NULL) { + ctxt->error = XPATH_MEMORY_ERROR; + } else if (PUSH_LONG_EXPR(XPATH_OP_VALUE, XPATH_NUMBER, 0, 0, num, + NULL) == -1) { + xmlXPathReleaseObject(ctxt->context, num); + } } /** @@ -10223,6 +10230,7 @@ static void xmlXPathCompLiteral(xmlXPathParserContextPtr ctxt) { const xmlChar *q; xmlChar *ret = NULL; + xmlXPathObjectPtr lit; if (CUR == '"') { NEXT; @@ -10250,8 +10258,13 @@ xmlXPathCompLiteral(xmlXPathParserContextPtr ctxt) { XP_ERROR(XPATH_START_LITERAL_ERROR); } if (ret == NULL) return; - PUSH_LONG_EXPR(XPATH_OP_VALUE, XPATH_STRING, 0, 0, - xmlXPathCacheNewString(ctxt->context, ret), NULL); + lit = xmlXPathCacheNewString(ctxt->context, ret); + if (lit == NULL) { + ctxt->error = XPATH_MEMORY_ERROR; + } else if (PUSH_LONG_EXPR(XPATH_OP_VALUE, XPATH_STRING, 0, 0, lit, + NULL) == -1) { + xmlXPathReleaseObject(ctxt->context, lit); + } xmlFree(ret); } @@ -10288,8 +10301,10 @@ xmlXPathCompVariableReference(xmlXPathParserContextPtr ctxt) { XP_ERROR(XPATH_VARIABLE_REF_ERROR); } ctxt->comp->last = -1; - PUSH_LONG_EXPR(XPATH_OP_VARIABLE, 0, 0, 0, - name, prefix); + if (PUSH_LONG_EXPR(XPATH_OP_VARIABLE, 0, 0, 0, name, prefix) == -1) { + xmlFree(prefix); + xmlFree(name); + } SKIP_BLANKS; if ((ctxt->context != NULL) && (ctxt->context->flags & XML_XPATH_NOVAR)) { XP_ERROR(XPATH_FORBID_VARIABLE_ERROR); @@ -10396,8 +10411,10 @@ xmlXPathCompFunctionCall(xmlXPathParserContextPtr ctxt) { SKIP_BLANKS; } } - PUSH_LONG_EXPR(XPATH_OP_FUNCTION, nbargs, 0, 0, - name, prefix); + if (PUSH_LONG_EXPR(XPATH_OP_FUNCTION, nbargs, 0, 0, name, prefix) == -1) { + xmlFree(prefix); + xmlFree(name); + } NEXT; SKIP_BLANKS; } @@ -10934,9 +10951,13 @@ xmlXPathCompileExpr(xmlXPathParserContextPtr ctxt, int sort) { xmlXPathContextPtr xpctxt = ctxt->context; if (xpctxt != NULL) { - if (xpctxt->depth >= xpctxt->maxParserDepth) + if (xpctxt->depth >= XPATH_MAX_RECURSION_DEPTH) XP_ERROR(XPATH_RECURSION_LIMIT_EXCEEDED); - xpctxt->depth += 1; + /* + * Parsing a single '(' pushes about 10 functions on the call stack + * before recursing! + */ + xpctxt->depth += 10; } xmlXPathCompAndExpr(ctxt); @@ -11038,7 +11059,7 @@ xmlXPathCompPredicate(xmlXPathParserContextPtr ctxt, int filter) { */ static xmlChar * xmlXPathCompNodeTest(xmlXPathParserContextPtr ctxt, xmlXPathTestVal *test, - xmlXPathTypeVal *type, const xmlChar **prefix, + xmlXPathTypeVal *type, xmlChar **prefix, xmlChar *name) { int blanks; @@ -11269,7 +11290,7 @@ xmlXPathCompStep(xmlXPathParserContextPtr ctxt) { SKIP_BLANKS; } else { xmlChar *name = NULL; - const xmlChar *prefix = NULL; + xmlChar *prefix = NULL; xmlXPathTestVal test = (xmlXPathTestVal) 0; xmlXPathAxisVal axis = (xmlXPathAxisVal) 0; xmlXPathTypeVal type = (xmlXPathTypeVal) 0; @@ -11379,9 +11400,11 @@ eval_predicates: PUSH_BINARY_EXPR(XPATH_OP_RANGETO, op2, op1, 0, 0); } else #endif - PUSH_FULL_EXPR(XPATH_OP_COLLECT, op1, ctxt->comp->last, axis, - test, type, (void *)prefix, (void *)name); - + if (PUSH_FULL_EXPR(XPATH_OP_COLLECT, op1, ctxt->comp->last, axis, + test, type, (void *)prefix, (void *)name) == -1) { + xmlFree(prefix); + xmlFree(name); + } } #ifdef DEBUG_STEP xmlGenericError(xmlGenericErrorContext, "Step : "); @@ -11649,11 +11672,11 @@ xmlXPathNodeSetFilter(xmlXPathParserContextPtr ctxt, res = xmlXPathCompOpEvalToBoolean(ctxt, filterOp, 1); if (ctxt->error != XPATH_EXPRESSION_OK) - goto exit; + break; if (res < 0) { /* Shouldn't happen */ xmlXPathErr(ctxt, XPATH_EXPR_ERROR); - goto exit; + break; } if ((res != 0) && ((pos >= minPos) && (pos <= maxPos))) { @@ -11672,15 +11695,7 @@ xmlXPathNodeSetFilter(xmlXPathParserContextPtr ctxt, if (res != 0) { if (pos == maxPos) { - /* Clear remaining nodes and exit loop. */ - if (hasNsNodes) { - for (i++; i < set->nodeNr; i++) { - node = set->nodeTab[i]; - if ((node != NULL) && - (node->type == XML_NAMESPACE_DECL)) - xmlXPathNodeSetFreeNs((xmlNsPtr) node); - } - } + i += 1; break; } @@ -11688,6 +11703,15 @@ xmlXPathNodeSetFilter(xmlXPathParserContextPtr ctxt, } } + /* Free remaining nodes. */ + if (hasNsNodes) { + for (; i < set->nodeNr; i++) { + xmlNodePtr node = set->nodeTab[i]; + if ((node != NULL) && (node->type == XML_NAMESPACE_DECL)) + xmlXPathNodeSetFreeNs((xmlNsPtr) node); + } + } + set->nodeNr = j; /* If too many elements were removed, shrink table to preserve memory. */ @@ -11708,7 +11732,6 @@ xmlXPathNodeSetFilter(xmlXPathParserContextPtr ctxt, } } -exit: xpctxt->node = oldnode; xpctxt->doc = olddoc; xpctxt->contextSize = oldcs; @@ -11773,11 +11796,11 @@ xmlXPathLocationSetFilter(xmlXPathParserContextPtr ctxt, res = xmlXPathCompOpEvalToBoolean(ctxt, filterOp, 1); if (ctxt->error != XPATH_EXPRESSION_OK) - goto exit; + break; if (res < 0) { /* Shouldn't happen */ xmlXPathErr(ctxt, XPATH_EXPR_ERROR); - goto exit; + break; } if ((res != 0) && ((pos >= minPos) && (pos <= maxPos))) { @@ -11795,10 +11818,7 @@ xmlXPathLocationSetFilter(xmlXPathParserContextPtr ctxt, if (res != 0) { if (pos == maxPos) { - /* Clear remaining nodes and exit loop. */ - for (i++; i < locset->locNr; i++) { - xmlXPathFreeObject(locset->locTab[i]); - } + i += 1; break; } @@ -11806,6 +11826,10 @@ xmlXPathLocationSetFilter(xmlXPathParserContextPtr ctxt, } } + /* Free remaining nodes. */ + for (; i < locset->locNr; i++) + xmlXPathFreeObject(locset->locTab[i]); + locset->locNr = j; /* If too many elements were removed, shrink table to preserve memory. */ @@ -11826,7 +11850,6 @@ xmlXPathLocationSetFilter(xmlXPathParserContextPtr ctxt, } } -exit: xpctxt->node = oldnode; xpctxt->doc = olddoc; xpctxt->contextSize = oldcs; @@ -11864,7 +11887,7 @@ xmlXPathCompOpEvalPredicate(xmlXPathParserContextPtr ctxt, "xmlXPathCompOpEvalPredicate: Expected a predicate\n"); XP_ERROR(XPATH_INVALID_OPERAND); } - if (ctxt->context->depth >= ctxt->context->maxDepth) + if (ctxt->context->depth >= XPATH_MAX_RECURSION_DEPTH) XP_ERROR(XPATH_RECURSION_LIMIT_EXCEEDED); ctxt->context->depth += 1; xmlXPathCompOpEvalPredicate(ctxt, &comp->steps[op->ch1], set, @@ -12580,7 +12603,7 @@ xmlXPathCompOpEvalFirst(xmlXPathParserContextPtr ctxt, CHECK_ERROR0; if (OP_LIMIT_EXCEEDED(ctxt, 1)) return(0); - if (ctxt->context->depth >= ctxt->context->maxDepth) + if (ctxt->context->depth >= XPATH_MAX_RECURSION_DEPTH) XP_ERROR0(XPATH_RECURSION_LIMIT_EXCEEDED); ctxt->context->depth += 1; comp = ctxt->comp; @@ -12721,7 +12744,7 @@ xmlXPathCompOpEvalLast(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op, CHECK_ERROR0; if (OP_LIMIT_EXCEEDED(ctxt, 1)) return(0); - if (ctxt->context->depth >= ctxt->context->maxDepth) + if (ctxt->context->depth >= XPATH_MAX_RECURSION_DEPTH) XP_ERROR0(XPATH_RECURSION_LIMIT_EXCEEDED); ctxt->context->depth += 1; comp = ctxt->comp; @@ -12939,7 +12962,7 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) CHECK_ERROR0; if (OP_LIMIT_EXCEEDED(ctxt, 1)) return(0); - if (ctxt->context->depth >= ctxt->context->maxDepth) + if (ctxt->context->depth >= XPATH_MAX_RECURSION_DEPTH) XP_ERROR0(XPATH_RECURSION_LIMIT_EXCEEDED); ctxt->context->depth += 1; comp = ctxt->comp; @@ -13815,7 +13838,8 @@ scan_children: do { cur = cur->parent; depth--; - if ((cur == NULL) || (cur == limit)) + if ((cur == NULL) || (cur == limit) || + (cur->type == XML_DOCUMENT_NODE)) goto done; if (cur->type == XML_ELEMENT_NODE) { ret = xmlStreamPop(patstream); @@ -14086,8 +14110,7 @@ xmlXPathTryStreamCompile(xmlXPathContextPtr ctxt, const xmlChar *str) { } } - stream = xmlPatterncompile(str, dict, XML_PATTERN_XPATH, - &namespaces[0]); + stream = xmlPatterncompile(str, dict, XML_PATTERN_XPATH, namespaces); if (namespaces != NULL) { xmlFree((xmlChar **)namespaces); } @@ -14173,7 +14196,7 @@ xmlXPathOptimizeExpression(xmlXPathParserContextPtr pctxt, /* Recurse */ ctxt = pctxt->context; if (ctxt != NULL) { - if (ctxt->depth >= ctxt->maxDepth) + if (ctxt->depth >= XPATH_MAX_RECURSION_DEPTH) return; ctxt->depth += 1; } @@ -14206,7 +14229,7 @@ xmlXPathCtxtCompile(xmlXPathContextPtr ctxt, const xmlChar *str) { return(comp); #endif - xmlXPathInit(); + xmlInitParser(); pctxt = xmlXPathNewParserContext(str, ctxt); if (pctxt == NULL) @@ -14295,7 +14318,7 @@ xmlXPathCompiledEvalInternal(xmlXPathCompExprPtr comp, if (comp == NULL) return(-1); - xmlXPathInit(); + xmlInitParser(); #ifndef LIBXML_THREAD_ENABLED reentance++; @@ -14440,7 +14463,7 @@ xmlXPathEval(const xmlChar *str, xmlXPathContextPtr ctx) { CHECK_CTXT(ctx) - xmlXPathInit(); + xmlInitParser(); ctxt = xmlXPathNewParserContext(str, ctx); if (ctxt == NULL) diff --git a/sdk/lib/3rdparty/libxml2/xpointer.c b/sdk/lib/3rdparty/libxml2/xpointer.c index c1732a584a6..3e3c8b88c96 100644 --- a/sdk/lib/3rdparty/libxml2/xpointer.c +++ b/sdk/lib/3rdparty/libxml2/xpointer.c @@ -70,7 +70,7 @@ /** * xmlXPtrErrMemory: - * @extra: extra informations + * @extra: extra information * * Handle a redefinition of attribute error */ @@ -86,7 +86,7 @@ xmlXPtrErrMemory(const char *extra) /** * xmlXPtrErr: * @ctxt: an XPTR evaluation context - * @extra: extra informations + * @extra: extra information * * Handle a redefinition of attribute error */ @@ -1005,7 +1005,7 @@ xmlXPtrEvalXPtrPart(xmlXPathParserContextPtr ctxt, xmlChar *name) { /* * To evaluate an xpointer scheme element (4.3) we need: * context initialized to the root - * context position initalized to 1 + * context position initialized to 1 * context size initialized to 1 */ ctxt->context->node = (xmlNodePtr)ctxt->context->doc; @@ -1352,7 +1352,7 @@ xmlXPtrEval(const xmlChar *str, xmlXPathContextPtr ctx) { xmlXPathObjectPtr init = NULL; int stack = 0; - xmlXPathInit(); + xmlInitParser(); if ((ctx == NULL) || (str == NULL)) return(NULL); @@ -1536,7 +1536,7 @@ xmlXPtrBuildRangeNodeList(xmlXPathObjectPtr range) { case XML_ELEMENT_DECL: case XML_ATTRIBUTE_DECL: case XML_ENTITY_NODE: - /* Do not copy DTD informations */ + /* Do not copy DTD information */ break; case XML_ENTITY_DECL: TODO /* handle crossing entities -> stack needed */ @@ -2200,7 +2200,6 @@ xmlXPtrRangeInsideFunction(xmlXPathParserContextPtr ctxt, int nargs) { XP_ERROR(XPATH_MEMORY_ERROR) set = tmp; } - oldset = (xmlLocationSetPtr) set->user; /* * The loop is to compute the covering range for each item and add it @@ -2210,9 +2209,12 @@ xmlXPtrRangeInsideFunction(xmlXPathParserContextPtr ctxt, int nargs) { xmlXPathFreeObject(set); XP_ERROR(XPATH_MEMORY_ERROR); } - for (i = 0;i < oldset->locNr;i++) { - xmlXPtrLocationSetAdd(newset, - xmlXPtrInsideRange(ctxt, oldset->locTab[i])); + oldset = (xmlLocationSetPtr) set->user; + if (oldset != NULL) { + for (i = 0;i < oldset->locNr;i++) { + xmlXPtrLocationSetAdd(newset, + xmlXPtrInsideRange(ctxt, oldset->locTab[i])); + } } /* @@ -2706,10 +2708,10 @@ static void xmlXPtrStringRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) { int i, startindex, endindex = 0, fendindex; xmlNodePtr start, end = 0, fend; - xmlXPathObjectPtr set; + xmlXPathObjectPtr set = NULL; xmlLocationSetPtr oldset; - xmlLocationSetPtr newset; - xmlXPathObjectPtr string; + xmlLocationSetPtr newset = NULL; + xmlXPathObjectPtr string = NULL; xmlXPathObjectPtr position = NULL; xmlXPathObjectPtr number = NULL; int found, pos = 0, num = 0; @@ -2721,29 +2723,39 @@ xmlXPtrStringRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) { XP_ERROR(XPATH_INVALID_ARITY); if (nargs >= 4) { - CHECK_TYPE(XPATH_NUMBER); + if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_NUMBER)) { + xmlXPathErr(ctxt, XPATH_INVALID_TYPE); + goto error; + } number = valuePop(ctxt); if (number != NULL) num = (int) number->floatval; } if (nargs >= 3) { - CHECK_TYPE(XPATH_NUMBER); + if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_NUMBER)) { + xmlXPathErr(ctxt, XPATH_INVALID_TYPE); + goto error; + } position = valuePop(ctxt); if (position != NULL) pos = (int) position->floatval; } - CHECK_TYPE(XPATH_STRING); + if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { + xmlXPathErr(ctxt, XPATH_INVALID_TYPE); + goto error; + } string = valuePop(ctxt); if ((ctxt->value == NULL) || ((ctxt->value->type != XPATH_LOCATIONSET) && - (ctxt->value->type != XPATH_NODESET))) - XP_ERROR(XPATH_INVALID_TYPE) - + (ctxt->value->type != XPATH_NODESET))) { + xmlXPathErr(ctxt, XPATH_INVALID_TYPE); + goto error; + } set = valuePop(ctxt); newset = xmlXPtrLocationSetCreate(NULL); if (newset == NULL) { - xmlXPathFreeObject(set); - XP_ERROR(XPATH_MEMORY_ERROR); + xmlXPathErr(ctxt, XPATH_MEMORY_ERROR); + goto error; } if (set->nodesetval == NULL) { goto error; @@ -2756,8 +2768,10 @@ xmlXPtrStringRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) { */ tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval); xmlXPathFreeObject(set); - if (tmp == NULL) - XP_ERROR(XPATH_MEMORY_ERROR) + if (tmp == NULL) { + xmlXPathErr(ctxt, XPATH_MEMORY_ERROR); + goto error; + } set = tmp; } oldset = (xmlLocationSetPtr) set->user; @@ -2830,7 +2844,8 @@ xmlXPtrStringRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) { * Save the new value and cleanup */ error: - valuePush(ctxt, xmlXPtrWrapLocationSet(newset)); + if (newset != NULL) + valuePush(ctxt, xmlXPtrWrapLocationSet(newset)); xmlXPathFreeObject(set); xmlXPathFreeObject(string); if (position) xmlXPathFreeObject(position);