hexpat 0.20.10 → 0.20.11
raw patch · 14 files changed
+7832/−6698 lines, 14 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- cbits/README +139/−0
- cbits/amigaconfig.h +0/−32
- cbits/expat.h +56/−12
- cbits/expat_external.h +18/−1
- cbits/internal.h +22/−0
- cbits/macconfig.h +0/−53
- cbits/siphash.h +344/−0
- cbits/winconfig.h +10/−0
- cbits/xmlparse.c +6816/−6274
- cbits/xmlrole.c +112/−118
- cbits/xmltok.c +172/−76
- cbits/xmltok.h +8/−2
- cbits/xmltok_impl.c +111/−115
- hexpat.cabal +24/−15
+ cbits/README view
@@ -0,0 +1,139 @@++ Expat, Release 2.2.1++This is Expat, a C library for parsing XML, written by James Clark.+Expat is a stream-oriented XML parser. This means that you register+handlers with the parser before starting the parse. These handlers+are called when the parser discovers the associated structures in the+document being parsed. A start tag is an example of the kind of+structures for which you may register handlers.++Windows users should use the expat_win32bin package, which includes+both precompiled libraries and executables, and source code for+developers.++Expat is free software. You may copy, distribute, and modify it under+the terms of the License contained in the file COPYING distributed+with this package. This license is the same as the MIT/X Consortium+license.++Versions of Expat that have an odd minor version (the middle number in+the release above), are development releases and should be considered+as beta software. Releases with even minor version numbers are+intended to be production grade software.++If you are building Expat from a check-out from the CVS repository,+you need to run a script that generates the configure script using the+GNU autoconf and libtool tools. To do this, you need to have+autoconf 2.58 or newer. Run the script like this:++ ./buildconf.sh++Once this has been done, follow the same instructions as for building+from a source distribution.++To build Expat from a source distribution, you first run the+configuration shell script in the top level distribution directory:++ ./configure++There are many options which you may provide to configure (which you+can discover by running configure with the --help option). But the+one of most interest is the one that sets the installation directory.+By default, the configure script will set things up to install+libexpat into /usr/local/lib, expat.h into /usr/local/include, and+xmlwf into /usr/local/bin. If, for example, you'd prefer to install+into /home/me/mystuff/lib, /home/me/mystuff/include, and+/home/me/mystuff/bin, you can tell configure about that with:++ ./configure --prefix=/home/me/mystuff+ +Another interesting option is to enable 64-bit integer support for+line and column numbers and the over-all byte index:++ ./configure CPPFLAGS=-DXML_LARGE_SIZE+ +However, such a modification would be a breaking change to the ABI+and is therefore not recommended for general use - e.g. as part of+a Linux distribution - but rather for builds with special requirements.++After running the configure script, the "make" command will build+things and "make install" will install things into their proper+location. Have a look at the "Makefile" to learn about additional+"make" options. Note that you need to have write permission into+the directories into which things will be installed.++If you are interested in building Expat to provide document+information in UTF-16 encoding rather than the default UTF-8, follow+these instructions (after having run "make distclean"):++ 1. For UTF-16 output as unsigned short (and version/error+ strings as char), run:++ ./configure CPPFLAGS=-DXML_UNICODE++ For UTF-16 output as wchar_t (incl. version/error strings),+ run:++ ./configure CFLAGS="-g -O2 -fshort-wchar" \+ CPPFLAGS=-DXML_UNICODE_WCHAR_T++ 2. Edit the MakeFile, changing:++ LIBRARY = libexpat.la++ to:++ LIBRARY = libexpatw.la++ (Note the additional "w" in the library name.)++ 3. Run "make buildlib" (which builds the library only).+ Or, to save step 2, run "make buildlib LIBRARY=libexpatw.la".++ 4. Run "make installlib" (which installs the library only).+ Or, if step 2 was omitted, run "make installlib LIBRARY=libexpatw.la".+ +Using DESTDIR or INSTALL_ROOT is enabled, with INSTALL_ROOT being the default+value for DESTDIR, and the rest of the make file using only DESTDIR.+It works as follows:+ $ make install DESTDIR=/path/to/image+overrides the in-makefile set DESTDIR, while both+ $ INSTALL_ROOT=/path/to/image make install+ $ make install INSTALL_ROOT=/path/to/image+use DESTDIR=$(INSTALL_ROOT), even if DESTDIR eventually is defined in the+environment, because variable-setting priority is+1) commandline+2) in-makefile+3) environment ++Note: This only applies to the Expat library itself, building UTF-16 versions+of xmlwf and the tests is currently not supported. ++Note for Solaris users: The "ar" command is usually located in+"/usr/ccs/bin", which is not in the default PATH. You will need to+add this to your path for the "make" command, and probably also switch+to GNU make (the "make" found in /usr/ccs/bin does not seem to work+properly -- apparently it does not understand .PHONY directives). If+you're using ksh or bash, use this command to build:++ PATH=/usr/ccs/bin:$PATH make++When using Expat with a project using autoconf for configuration, you+can use the probing macro in conftools/expat.m4 to determine how to+include Expat. See the comments at the top of that file for more+information.++A reference manual is available in the file doc/reference.html in this+distribution.++The homepage for this project is http://www.libexpat.org/. There+are links there to connect you to the bug reports page. If you need+to report a bug when you don't have access to a browser, you may also+send a bug report by email to expat-bugs@mail.libexpat.org.++Discussion related to the direction of future expat development takes+place on expat-discuss@mail.libexpat.org. Archives of this list and+other Expat-related lists may be found at:++ http://mail.libexpat.org/mailman/listinfo/
− cbits/amigaconfig.h
@@ -1,32 +0,0 @@-#ifndef AMIGACONFIG_H-#define AMIGACONFIG_H--/* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */-#define BYTEORDER 4321--/* Define to 1 if you have the `bcopy' function. */-#define HAVE_BCOPY 1--/* Define to 1 if you have the <check.h> header file. */-#undef HAVE_CHECK_H--/* Define to 1 if you have the `memmove' function. */-#define HAVE_MEMMOVE 1--/* Define to 1 if you have the <unistd.h> header file. */-#define HAVE_UNISTD_H 1--/* whether byteorder is bigendian */-#define WORDS_BIGENDIAN--/* Define to specify how much context to retain around the current parse- point. */-#define XML_CONTEXT_BYTES 1024--/* Define to make parameter entity parsing functionality available. */-#define XML_DTD--/* Define to make XML Namespaces functionality available. */-#define XML_NS--#endif /* AMIGACONFIG_H */
cbits/expat.h view
@@ -95,7 +95,9 @@ /* Added in 2.0. */ XML_ERROR_RESERVED_PREFIX_XML, XML_ERROR_RESERVED_PREFIX_XMLNS,- XML_ERROR_RESERVED_NAMESPACE_URI+ XML_ERROR_RESERVED_NAMESPACE_URI,+ /* Added in 2.2.1. */+ XML_ERROR_INVALID_ARGUMENT }; enum XML_Content_Type {@@ -342,7 +344,7 @@ XML_EntityDeclHandler handler); /* OBSOLETE -- OBSOLETE -- OBSOLETE- This handler has been superceded by the EntityDeclHandler above.+ This handler has been superseded by the EntityDeclHandler above. It is provided here for backward compatibility. This is called for a declaration of an unparsed (NDATA) entity.@@ -706,6 +708,7 @@ be called, despite an external subset being parsed. Note: If XML_DTD is not defined when Expat is compiled, returns XML_ERROR_FEATURE_REQUIRES_XML_DTD.+ Note: If parser == NULL, returns XML_ERROR_INVALID_ARGUMENT. */ XMLPARSEAPI(enum XML_Error) XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD);@@ -729,19 +732,43 @@ to the XML_StartElementHandler that were specified in the start-tag rather than defaulted. Each attribute/value pair counts as 2; thus this correspondds to an index into the atts array passed to the- XML_StartElementHandler.+ XML_StartElementHandler. Returns -1 if parser == NULL. */ XMLPARSEAPI(int) XML_GetSpecifiedAttributeCount(XML_Parser parser); /* Returns the index of the ID attribute passed in the last call to- XML_StartElementHandler, or -1 if there is no ID attribute. Each- attribute/value pair counts as 2; thus this correspondds to an- index into the atts array passed to the XML_StartElementHandler.+ XML_StartElementHandler, or -1 if there is no ID attribute or+ parser == NULL. Each attribute/value pair counts as 2; thus this+ correspondds to an index into the atts array passed to the+ XML_StartElementHandler. */ XMLPARSEAPI(int) XML_GetIdAttributeIndex(XML_Parser parser); +#ifdef XML_ATTR_INFO+/* Source file byte offsets for the start and end of attribute names and values.+ The value indices are exclusive of surrounding quotes; thus in a UTF-8 source+ file an attribute value of "blah" will yield:+ info->valueEnd - info->valueStart = 4 bytes.+*/+typedef struct {+ XML_Index nameStart; /* Offset to beginning of the attribute name. */+ XML_Index nameEnd; /* Offset after the attribute name's last byte. */+ XML_Index valueStart; /* Offset to beginning of the attribute value. */+ XML_Index valueEnd; /* Offset after the attribute value's last byte. */+} XML_AttrInfo;++/* Returns an array of XML_AttrInfo structures for the attribute/value pairs+ passed in last call to the XML_StartElementHandler that were specified+ in the start-tag rather than defaulted. Each attribute/value pair counts+ as 1; thus the number of entries in the array is+ XML_GetSpecifiedAttributeCount(parser) / 2.+*/+XMLPARSEAPI(const XML_AttrInfo *)+XML_GetAttributeInfo(XML_Parser parser);+#endif+ /* Parses some input. Returns XML_STATUS_ERROR if a fatal error is detected. The last call to XML_Parse must have isFinal true; len may be zero for this call (or any other).@@ -878,11 +905,22 @@ entities is requested; otherwise it will return non-zero. Note: If XML_SetParamEntityParsing is called after XML_Parse or XML_ParseBuffer, then it has no effect and will always return 0.+ Note: If parser == NULL, the function will do nothing and return 0. */ XMLPARSEAPI(int) XML_SetParamEntityParsing(XML_Parser parser, enum XML_ParamEntityParsing parsing); +/* Sets the hash salt to use for internal hash calculations.+ Helps in preventing DoS attacks based on predicting hash+ function behavior. This must be called before parsing is started.+ Returns 1 if successful, 0 when called after parsing has started.+ Note: If parser == NULL, the function will do nothing and return 0.+*/+XMLPARSEAPI(int)+XML_SetHashSalt(XML_Parser parser,+ unsigned long hash_salt);+ /* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then XML_GetErrorCode returns information about the error. */@@ -904,6 +942,10 @@ the location is the location of the character at which the error was detected; otherwise the location is the location of the last parse event, as described above.++ Note: XML_GetCurrentLineNumber and XML_GetCurrentColumnNumber+ return 0 to indicate an error.+ Note: XML_GetCurrentByteIndex returns -1 to indicate an error. */ XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser); XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser);@@ -941,9 +983,12 @@ /* Exposing the memory handling functions used in Expat */ XMLPARSEAPI(void *)+XML_ATTR_MALLOC+XML_ATTR_ALLOC_SIZE(2) XML_MemMalloc(XML_Parser parser, size_t size); XMLPARSEAPI(void *)+XML_ATTR_ALLOC_SIZE(3) XML_MemRealloc(XML_Parser parser, void *ptr, size_t size); XMLPARSEAPI(void)@@ -984,7 +1029,8 @@ XML_FEATURE_SIZEOF_XML_CHAR, XML_FEATURE_SIZEOF_XML_LCHAR, XML_FEATURE_NS,- XML_FEATURE_LARGE_SIZE+ XML_FEATURE_LARGE_SIZE,+ XML_FEATURE_ATTR_INFO /* Additional features must be added to the end of this enum. */ }; @@ -998,13 +1044,11 @@ XML_GetFeatureList(void); -/* Expat follows the GNU/Linux convention of odd number minor version for- beta/development releases and even number minor version for stable- releases. Micro is bumped with each release, and set to 0 with each- change to major or minor version.+/* Expat follows the semantic versioning convention.+ See http://semver.org. */ #define XML_MAJOR_VERSION 2-#define XML_MINOR_VERSION 0+#define XML_MINOR_VERSION 2 #define XML_MICRO_VERSION 1 #ifdef __cplusplus
cbits/expat_external.h view
@@ -65,13 +65,27 @@ #endif #endif /* not defined XML_STATIC */ +#if !defined(XMLIMPORT) && defined(__GNUC__) && (__GNUC__ >= 4)+#define XMLIMPORT __attribute__ ((visibility ("default")))+#endif /* If we didn't define it above, define it away: */ #ifndef XMLIMPORT #define XMLIMPORT #endif +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96))+#define XML_ATTR_MALLOC __attribute__((__malloc__))+#else+#define XML_ATTR_MALLOC+#endif +#if defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))+#define XML_ATTR_ALLOC_SIZE(x) __attribute__((__alloc_size__(x)))+#else+#define XML_ATTR_ALLOC_SIZE(x)+#endif+ #define XMLPARSEAPI(type) XMLIMPORT type XMLCALL #ifdef __cplusplus@@ -79,7 +93,10 @@ #endif #ifdef XML_UNICODE_WCHAR_T-#define XML_UNICODE+# define XML_UNICODE+# if defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__ != 2)+# error "sizeof(wchar_t) != 2; Need -fshort-wchar for both Expat and libc"+# endif #endif #ifdef XML_UNICODE /* Information is UTF-16 encoded. */
cbits/internal.h view
@@ -71,3 +71,25 @@ #define inline #endif #endif++#ifndef UNUSED_P+# ifdef __GNUC__+# define UNUSED_P(p) UNUSED_ ## p __attribute__((__unused__))+# else+# define UNUSED_P(p) UNUSED_ ## p+# endif+#endif+++#ifdef __cplusplus+extern "C" {+#endif+++void+align_limit_to_full_utf8_characters(const char * from, const char ** fromLimRef);+++#ifdef __cplusplus+}+#endif
− cbits/macconfig.h
@@ -1,53 +0,0 @@-/*================================================================-** Copyright 2000, Clark Cooper-** All rights reserved.-**-** This is free software. You are permitted to copy, distribute, or modify-** it under the terms of the MIT/X license (contained in the COPYING file-** with this distribution.)-**-*/--#ifndef MACCONFIG_H-#define MACCONFIG_H---/* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */-#define BYTEORDER 4321--/* Define to 1 if you have the `bcopy' function. */-#undef HAVE_BCOPY--/* Define to 1 if you have the `memmove' function. */-#define HAVE_MEMMOVE--/* Define to 1 if you have a working `mmap' system call. */-#undef HAVE_MMAP--/* Define to 1 if you have the <unistd.h> header file. */-#undef HAVE_UNISTD_H--/* whether byteorder is bigendian */-#define WORDS_BIGENDIAN--/* Define to specify how much context to retain around the current parse- point. */-#undef XML_CONTEXT_BYTES--/* Define to make parameter entity parsing functionality available. */-#define XML_DTD--/* Define to make XML Namespaces functionality available. */-#define XML_NS--/* Define to empty if `const' does not conform to ANSI C. */-#undef const--/* Define to `long' if <sys/types.h> does not define. */-#define off_t long--/* Define to `unsigned' if <sys/types.h> does not define. */-#undef size_t---#endif /* ifndef MACCONFIG_H */
+ cbits/siphash.h view
@@ -0,0 +1,344 @@+/* ==========================================================================+ * siphash.h - SipHash-2-4 in a single header file+ * --------------------------------------------------------------------------+ * Derived by William Ahern from the reference implementation[1] published[2]+ * by Jean-Philippe Aumasson and Daniel J. Berstein. Licensed in kind.+ * by Jean-Philippe Aumasson and Daniel J. Berstein.+ * Minimal changes by Sebastian Pipping on top, details below.+ * Licensed under the CC0 Public Domain Dedication license.+ *+ * 1. https://www.131002.net/siphash/siphash24.c+ * 2. https://www.131002.net/siphash/+ * --------------------------------------------------------------------------+ * HISTORY:+ *+ * 2017-06-10 (Sebastian Pipping)+ * - Clarify license note in the header+ * - Address C89 issues:+ * - Stop using inline keyword (and let compiler decide)+ * - Turn integer suffix ULL to UL+ * - Replace _Bool by int+ * - Turn macro siphash24 into a function+ * - Address invalid conversion (void pointer) by explicit cast+ * - Always expose sip24_valid (for self-tests)+ *+ * 2012-11-04 - Born. (William Ahern)+ * --------------------------------------------------------------------------+ * USAGE:+ *+ * SipHash-2-4 takes as input two 64-bit words as the key, some number of+ * message bytes, and outputs a 64-bit word as the message digest. This+ * implementation employs two data structures: a struct sipkey for+ * representing the key, and a struct siphash for representing the hash+ * state.+ *+ * For converting a 16-byte unsigned char array to a key, use either the+ * macro sip_keyof or the routine sip_tokey. The former instantiates a+ * compound literal key, while the latter requires a key object as a+ * parameter.+ *+ * unsigned char secret[16];+ * arc4random_buf(secret, sizeof secret);+ * struct sipkey *key = sip_keyof(secret);+ *+ * For hashing a message, use either the convenience macro siphash24 or the+ * routines sip24_init, sip24_update, and sip24_final.+ *+ * struct siphash state;+ * void *msg;+ * size_t len;+ * uint64_t hash;+ *+ * sip24_init(&state, key);+ * sip24_update(&state, msg, len);+ * hash = sip24_final(&state);+ *+ * or+ *+ * hash = siphash24(msg, len, key);+ *+ * To convert the 64-bit hash value to a canonical 8-byte little-endian+ * binary representation, use either the macro sip_binof or the routine+ * sip_tobin. The former instantiates and returns a compound literal array,+ * while the latter requires an array object as a parameter.+ * --------------------------------------------------------------------------+ * NOTES:+ *+ * o Neither sip_keyof, sip_binof, nor siphash24 will work with compilers+ * lacking compound literal support. Instead, you must use the lower-level+ * interfaces which take as parameters the temporary state objects.+ *+ * o Uppercase macros may evaluate parameters more than once. Lowercase+ * macros should not exhibit any such side effects.+ * ==========================================================================+ */+#ifndef SIPHASH_H+#define SIPHASH_H++#include <stddef.h> /* size_t */+#include <stdint.h> /* uint64_t uint32_t uint8_t */+++#define SIP_ROTL(x, b) (uint64_t)(((x) << (b)) | ( (x) >> (64 - (b))))++#define SIP_U32TO8_LE(p, v) \+ (p)[0] = (uint8_t)((v) >> 0); (p)[1] = (uint8_t)((v) >> 8); \+ (p)[2] = (uint8_t)((v) >> 16); (p)[3] = (uint8_t)((v) >> 24);++#define SIP_U64TO8_LE(p, v) \+ SIP_U32TO8_LE((p) + 0, (uint32_t)((v) >> 0)); \+ SIP_U32TO8_LE((p) + 4, (uint32_t)((v) >> 32));++#define SIP_U8TO64_LE(p) \+ (((uint64_t)((p)[0]) << 0) | \+ ((uint64_t)((p)[1]) << 8) | \+ ((uint64_t)((p)[2]) << 16) | \+ ((uint64_t)((p)[3]) << 24) | \+ ((uint64_t)((p)[4]) << 32) | \+ ((uint64_t)((p)[5]) << 40) | \+ ((uint64_t)((p)[6]) << 48) | \+ ((uint64_t)((p)[7]) << 56))+++#define SIPHASH_INITIALIZER { 0, 0, 0, 0, { 0 }, 0, 0 }++struct siphash {+ uint64_t v0, v1, v2, v3;++ unsigned char buf[8], *p;+ uint64_t c;+}; /* struct siphash */+++#define SIP_KEYLEN 16++struct sipkey {+ uint64_t k[2];+}; /* struct sipkey */++#define sip_keyof(k) sip_tokey(&(struct sipkey){ { 0 } }, (k))++static struct sipkey *sip_tokey(struct sipkey *key, const void *src) {+ key->k[0] = SIP_U8TO64_LE((const unsigned char *)src);+ key->k[1] = SIP_U8TO64_LE((const unsigned char *)src + 8);+ return key;+} /* sip_tokey() */+++#define sip_binof(v) sip_tobin((unsigned char[8]){ 0 }, (v))++static void *sip_tobin(void *dst, uint64_t u64) {+ SIP_U64TO8_LE((unsigned char *)dst, u64);+ return dst;+} /* sip_tobin() */+++static void sip_round(struct siphash *H, const int rounds) {+ int i;++ for (i = 0; i < rounds; i++) {+ H->v0 += H->v1;+ H->v1 = SIP_ROTL(H->v1, 13);+ H->v1 ^= H->v0;+ H->v0 = SIP_ROTL(H->v0, 32);++ H->v2 += H->v3;+ H->v3 = SIP_ROTL(H->v3, 16);+ H->v3 ^= H->v2;++ H->v0 += H->v3;+ H->v3 = SIP_ROTL(H->v3, 21);+ H->v3 ^= H->v0;++ H->v2 += H->v1;+ H->v1 = SIP_ROTL(H->v1, 17);+ H->v1 ^= H->v2;+ H->v2 = SIP_ROTL(H->v2, 32);+ }+} /* sip_round() */+++static struct siphash *sip24_init(struct siphash *H, const struct sipkey *key) {+ H->v0 = 0x736f6d6570736575UL ^ key->k[0];+ H->v1 = 0x646f72616e646f6dUL ^ key->k[1];+ H->v2 = 0x6c7967656e657261UL ^ key->k[0];+ H->v3 = 0x7465646279746573UL ^ key->k[1];++ H->p = H->buf;+ H->c = 0;++ return H;+} /* sip24_init() */+++#define sip_endof(a) (&(a)[sizeof (a) / sizeof *(a)])++static struct siphash *sip24_update(struct siphash *H, const void *src, size_t len) {+ const unsigned char *p = (const unsigned char *)src, *pe = p + len;+ uint64_t m;++ do {+ while (p < pe && H->p < sip_endof(H->buf))+ *H->p++ = *p++;++ if (H->p < sip_endof(H->buf))+ break;++ m = SIP_U8TO64_LE(H->buf);+ H->v3 ^= m;+ sip_round(H, 2);+ H->v0 ^= m;++ H->p = H->buf;+ H->c += 8;+ } while (p < pe);++ return H;+} /* sip24_update() */+++static uint64_t sip24_final(struct siphash *H) {+ char left = H->p - H->buf;+ uint64_t b = (H->c + left) << 56;++ switch (left) {+ case 7: b |= (uint64_t)H->buf[6] << 48;+ case 6: b |= (uint64_t)H->buf[5] << 40;+ case 5: b |= (uint64_t)H->buf[4] << 32;+ case 4: b |= (uint64_t)H->buf[3] << 24;+ case 3: b |= (uint64_t)H->buf[2] << 16;+ case 2: b |= (uint64_t)H->buf[1] << 8;+ case 1: b |= (uint64_t)H->buf[0] << 0;+ case 0: break;+ }++ H->v3 ^= b;+ sip_round(H, 2);+ H->v0 ^= b;+ H->v2 ^= 0xff;+ sip_round(H, 4);++ return H->v0 ^ H->v1 ^ H->v2 ^ H->v3;+} /* sip24_final() */+++static uint64_t siphash24(const void *src, size_t len, const struct sipkey *key) {+ struct siphash state = SIPHASH_INITIALIZER;+ return sip24_final(sip24_update(sip24_init(&state, key), src, len));+} /* siphash24() */+++/*+ * SipHash-2-4 output with+ * k = 00 01 02 ...+ * and+ * in = (empty string)+ * in = 00 (1 byte)+ * in = 00 01 (2 bytes)+ * in = 00 01 02 (3 bytes)+ * ...+ * in = 00 01 02 ... 3e (63 bytes)+ */+static int sip24_valid(void) {+ static const unsigned char vectors[64][8] = {+ { 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, },+ { 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, },+ { 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, },+ { 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, },+ { 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, },+ { 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, },+ { 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, },+ { 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, },+ { 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, },+ { 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, },+ { 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, },+ { 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, },+ { 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, },+ { 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, },+ { 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, },+ { 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, },+ { 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, },+ { 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, },+ { 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, },+ { 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, },+ { 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, },+ { 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, },+ { 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, },+ { 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, },+ { 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, },+ { 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, },+ { 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, },+ { 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, },+ { 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, },+ { 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, },+ { 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, },+ { 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, },+ { 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, },+ { 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, },+ { 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, },+ { 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, },+ { 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, },+ { 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, },+ { 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, },+ { 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, },+ { 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, },+ { 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, },+ { 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, },+ { 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, },+ { 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, },+ { 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, },+ { 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, },+ { 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, },+ { 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, },+ { 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, },+ { 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, },+ { 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, },+ { 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, },+ { 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, },+ { 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, },+ { 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, },+ { 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, },+ { 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, },+ { 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, },+ { 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, },+ { 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, },+ { 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, },+ { 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, },+ { 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, }+ };+ unsigned char in[64];+ struct sipkey k;+ size_t i;++ sip_tokey(&k, "\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017");++ for (i = 0; i < sizeof in; ++i) {+ in[i] = i;++ if (siphash24(in, i, &k) != SIP_U8TO64_LE(vectors[i]))+ return 0;+ }++ return 1;+} /* sip24_valid() */+++#if SIPHASH_MAIN++#include <stdio.h>++int main(void) {+ int ok = sip24_valid();++ if (ok)+ puts("OK");+ else+ puts("FAIL");++ return !ok;+} /* main() */++#endif /* SIPHASH_MAIN */+++#endif /* SIPHASH_H */
cbits/winconfig.h view
@@ -17,6 +17,12 @@ #include <memory.h> #include <string.h> ++#if defined(HAVE_EXPAT_CONFIG_H) /* e.g. MinGW */+# include <expat_config.h>+#else /* !defined(HAVE_EXPAT_CONFIG_H) */++ #define XML_NS 1 #define XML_DTD 1 #define XML_CONTEXT_BYTES 1024@@ -26,5 +32,9 @@ /* Windows has memmove() available. */ #define HAVE_MEMMOVE+++#endif /* !defined(HAVE_EXPAT_CONFIG_H) */+ #endif /* ndef WINCONFIG_H */
cbits/xmlparse.c view
@@ -1,6279 +1,6821 @@ /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd See the file COPYING for copying permission.-*/--#include <stddef.h>-#include <string.h> /* memset(), memcpy() */-#include <assert.h>--#define XML_BUILDING_EXPAT 1--#ifdef COMPILED_FROM_DSP-#include "winconfig.h"-#elif defined(MACOS_CLASSIC)-#include "macconfig.h"-#elif defined(__amigaos4__)-#include "amigaconfig.h"-#elif defined(__WATCOMC__)-#include "watcomconfig.h"-#elif defined(HAVE_EXPAT_CONFIG_H)-#include <expat_config.h>-#endif /* ndef COMPILED_FROM_DSP */--#include "ascii.h"-#include "expat.h"--#ifdef XML_UNICODE-#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX-#define XmlConvert XmlUtf16Convert-#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding-#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS-#define XmlEncode XmlUtf16Encode-/* Using pointer subtraction to convert to integer type. */-#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))-typedef unsigned short ICHAR;-#else-#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX-#define XmlConvert XmlUtf8Convert-#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding-#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS-#define XmlEncode XmlUtf8Encode-#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)-typedef char ICHAR;-#endif---#ifndef XML_NS--#define XmlInitEncodingNS XmlInitEncoding-#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding-#undef XmlGetInternalEncodingNS-#define XmlGetInternalEncodingNS XmlGetInternalEncoding-#define XmlParseXmlDeclNS XmlParseXmlDecl--#endif--#ifdef XML_UNICODE--#ifdef XML_UNICODE_WCHAR_T-#define XML_T(x) (const wchar_t)x-#define XML_L(x) L ## x-#else-#define XML_T(x) (const unsigned short)x-#define XML_L(x) x-#endif--#else--#define XML_T(x) x-#define XML_L(x) x--#endif--/* Round up n to be a multiple of sz, where sz is a power of 2. */-#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))--/* Handle the case where memmove() doesn't exist. */-#ifndef HAVE_MEMMOVE-#ifdef HAVE_BCOPY-#define memmove(d,s,l) bcopy((s),(d),(l))-#else-#error memmove does not exist on this platform, nor is a substitute available-#endif /* HAVE_BCOPY */-#endif /* HAVE_MEMMOVE */--#include "internal.h"-#include "xmltok.h"-#include "xmlrole.h"--typedef const XML_Char *KEY;--typedef struct {- KEY name;-} NAMED;--typedef struct {- NAMED **v;- unsigned char power;- size_t size;- size_t used;- const XML_Memory_Handling_Suite *mem;-} HASH_TABLE;--/* Basic character hash algorithm, taken from Python's string hash:- h = h * 1000003 ^ character, the constant being a prime number.--*/-#ifdef XML_UNICODE-#define CHAR_HASH(h, c) \- (((h) * 0xF4243) ^ (unsigned short)(c))-#else-#define CHAR_HASH(h, c) \- (((h) * 0xF4243) ^ (unsigned char)(c))-#endif--/* For probing (after a collision) we need a step size relative prime- to the hash table size, which is a power of 2. We use double-hashing,- since we can calculate a second hash value cheaply by taking those bits- of the first hash value that were discarded (masked out) when the table- index was calculated: index = hash & mask, where mask = table->size - 1.- We limit the maximum step size to table->size / 4 (mask >> 2) and make- it odd, since odd numbers are always relative prime to a power of 2.-*/-#define SECOND_HASH(hash, mask, power) \- ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))-#define PROBE_STEP(hash, mask, power) \- ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))--typedef struct {- NAMED **p;- NAMED **end;-} HASH_TABLE_ITER;--#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */-#define INIT_DATA_BUF_SIZE 1024-#define INIT_ATTS_SIZE 16-#define INIT_ATTS_VERSION 0xFFFFFFFF-#define INIT_BLOCK_SIZE 1024-#define INIT_BUFFER_SIZE 1024--#define EXPAND_SPARE 24--typedef struct binding {- struct prefix *prefix;- struct binding *nextTagBinding;- struct binding *prevPrefixBinding;- const struct attribute_id *attId;- XML_Char *uri;- int uriLen;- int uriAlloc;-} BINDING;--typedef struct prefix {- const XML_Char *name;- BINDING *binding;-} PREFIX;--typedef struct {- const XML_Char *str;- const XML_Char *localPart;- const XML_Char *prefix;- int strLen;- int uriLen;- int prefixLen;-} TAG_NAME;--/* TAG represents an open element.- The name of the element is stored in both the document and API- encodings. The memory buffer 'buf' is a separately-allocated- memory area which stores the name. During the XML_Parse()/- XMLParseBuffer() when the element is open, the memory for the 'raw'- version of the name (in the document encoding) is shared with the- document buffer. If the element is open across calls to- XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to- contain the 'raw' name as well.-- A parser re-uses these structures, maintaining a list of allocated- TAG objects in a free list.-*/-typedef struct tag {- struct tag *parent; /* parent of this element */- const char *rawName; /* tagName in the original encoding */- int rawNameLength;- TAG_NAME name; /* tagName in the API encoding */- char *buf; /* buffer for name components */- char *bufEnd; /* end of the buffer */- BINDING *bindings;-} TAG;--typedef struct {- const XML_Char *name;- const XML_Char *textPtr;- int textLen; /* length in XML_Chars */- int processed; /* # of processed bytes - when suspended */- const XML_Char *systemId;- const XML_Char *base;- const XML_Char *publicId;- const XML_Char *notation;- XML_Bool open;- XML_Bool is_param;- XML_Bool is_internal; /* true if declared in internal subset outside PE */-} ENTITY;--typedef struct {- enum XML_Content_Type type;- enum XML_Content_Quant quant;- const XML_Char * name;- int firstchild;- int lastchild;- int childcnt;- int nextsib;-} CONTENT_SCAFFOLD;--#define INIT_SCAFFOLD_ELEMENTS 32--typedef struct block {- struct block *next;- int size;- XML_Char s[1];-} BLOCK;--typedef struct {- BLOCK *blocks;- BLOCK *freeBlocks;- const XML_Char *end;- XML_Char *ptr;- XML_Char *start;- const XML_Memory_Handling_Suite *mem;-} STRING_POOL;--/* The XML_Char before the name is used to determine whether- an attribute has been specified. */-typedef struct attribute_id {- XML_Char *name;- PREFIX *prefix;- XML_Bool maybeTokenized;- XML_Bool xmlns;-} ATTRIBUTE_ID;--typedef struct {- const ATTRIBUTE_ID *id;- XML_Bool isCdata;- const XML_Char *value;-} DEFAULT_ATTRIBUTE;--typedef struct {- unsigned long version;- unsigned long hash;- const XML_Char *uriName;-} NS_ATT;--typedef struct {- const XML_Char *name;- PREFIX *prefix;- const ATTRIBUTE_ID *idAtt;- int nDefaultAtts;- int allocDefaultAtts;- DEFAULT_ATTRIBUTE *defaultAtts;-} ELEMENT_TYPE;--typedef struct {- HASH_TABLE generalEntities;- HASH_TABLE elementTypes;- HASH_TABLE attributeIds;- HASH_TABLE prefixes;- STRING_POOL pool;- STRING_POOL entityValuePool;- /* false once a parameter entity reference has been skipped */- XML_Bool keepProcessing;- /* true once an internal or external PE reference has been encountered;- this includes the reference to an external subset */- XML_Bool hasParamEntityRefs;- XML_Bool standalone;-#ifdef XML_DTD- /* indicates if external PE has been read */- XML_Bool paramEntityRead;- HASH_TABLE paramEntities;-#endif /* XML_DTD */- PREFIX defaultPrefix;- /* === scaffolding for building content model === */- XML_Bool in_eldecl;- CONTENT_SCAFFOLD *scaffold;- unsigned contentStringLen;- unsigned scaffSize;- unsigned scaffCount;- int scaffLevel;- int *scaffIndex;-} DTD;--typedef struct open_internal_entity {- const char *internalEventPtr;- const char *internalEventEndPtr;- struct open_internal_entity *next;- ENTITY *entity;- int startTagLevel;- XML_Bool betweenDecl; /* WFC: PE Between Declarations */-} OPEN_INTERNAL_ENTITY;--typedef enum XML_Error PTRCALL Processor(XML_Parser parser,- const char *start,- const char *end,- const char **endPtr);--static Processor prologProcessor;-static Processor prologInitProcessor;-static Processor contentProcessor;-static Processor cdataSectionProcessor;-#ifdef XML_DTD-static Processor ignoreSectionProcessor;-static Processor externalParEntProcessor;-static Processor externalParEntInitProcessor;-static Processor entityValueProcessor;-static Processor entityValueInitProcessor;-#endif /* XML_DTD */-static Processor epilogProcessor;-static Processor errorProcessor;-static Processor externalEntityInitProcessor;-static Processor externalEntityInitProcessor2;-static Processor externalEntityInitProcessor3;-static Processor externalEntityContentProcessor;-static Processor internalEntityProcessor;--static enum XML_Error-handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);-static enum XML_Error-processXmlDecl(XML_Parser parser, int isGeneralTextEntity,- const char *s, const char *next);-static enum XML_Error-initializeEncoding(XML_Parser parser);-static enum XML_Error-doProlog(XML_Parser parser, const ENCODING *enc, const char *s, - const char *end, int tok, const char *next, const char **nextPtr, - XML_Bool haveMore);-static enum XML_Error-processInternalEntity(XML_Parser parser, ENTITY *entity, - XML_Bool betweenDecl);-static enum XML_Error-doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,- const char *start, const char *end, const char **endPtr, - XML_Bool haveMore);-static enum XML_Error-doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,- const char *end, const char **nextPtr, XML_Bool haveMore);-#ifdef XML_DTD-static enum XML_Error-doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,- const char *end, const char **nextPtr, XML_Bool haveMore);-#endif /* XML_DTD */--static enum XML_Error-storeAtts(XML_Parser parser, const ENCODING *, const char *s,- TAG_NAME *tagNamePtr, BINDING **bindingsPtr);-static enum XML_Error-addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,- const XML_Char *uri, BINDING **bindingsPtr);-static int-defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata, - XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);-static enum XML_Error-storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,- const char *, const char *, STRING_POOL *);-static enum XML_Error-appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,- const char *, const char *, STRING_POOL *);-static ATTRIBUTE_ID *-getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,- const char *end);-static int-setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);-static enum XML_Error-storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,- const char *end);-static int-reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,- const char *start, const char *end);-static int-reportComment(XML_Parser parser, const ENCODING *enc, const char *start,- const char *end);-static void-reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,- const char *end);--static const XML_Char * getContext(XML_Parser parser);-static XML_Bool-setContext(XML_Parser parser, const XML_Char *context);--static void FASTCALL normalizePublicId(XML_Char *s);--static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);-/* do not call if parentParser != NULL */-static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);-static void-dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);-static int-dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);-static int-copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);--static NAMED *-lookup(HASH_TABLE *table, KEY name, size_t createSize);-static void FASTCALL-hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);-static void FASTCALL hashTableClear(HASH_TABLE *);-static void FASTCALL hashTableDestroy(HASH_TABLE *);-static void FASTCALL-hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);-static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);--static void FASTCALL-poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);-static void FASTCALL poolClear(STRING_POOL *);-static void FASTCALL poolDestroy(STRING_POOL *);-static XML_Char *-poolAppend(STRING_POOL *pool, const ENCODING *enc,- const char *ptr, const char *end);-static XML_Char *-poolStoreString(STRING_POOL *pool, const ENCODING *enc,- const char *ptr, const char *end);-static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);-static const XML_Char * FASTCALL-poolCopyString(STRING_POOL *pool, const XML_Char *s);-static const XML_Char *-poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);-static const XML_Char * FASTCALL-poolAppendString(STRING_POOL *pool, const XML_Char *s);--static int FASTCALL nextScaffoldPart(XML_Parser parser);-static XML_Content * build_model(XML_Parser parser);-static ELEMENT_TYPE *-getElementType(XML_Parser parser, const ENCODING *enc,- const char *ptr, const char *end);--static XML_Parser-parserCreate(const XML_Char *encodingName,- const XML_Memory_Handling_Suite *memsuite,- const XML_Char *nameSep,- DTD *dtd);-static void-parserInit(XML_Parser parser, const XML_Char *encodingName);--#define poolStart(pool) ((pool)->start)-#define poolEnd(pool) ((pool)->ptr)-#define poolLength(pool) ((pool)->ptr - (pool)->start)-#define poolChop(pool) ((void)--(pool->ptr))-#define poolLastChar(pool) (((pool)->ptr)[-1])-#define poolDiscard(pool) ((pool)->ptr = (pool)->start)-#define poolFinish(pool) ((pool)->start = (pool)->ptr)-#define poolAppendChar(pool, c) \- (((pool)->ptr == (pool)->end && !poolGrow(pool)) \- ? 0 \- : ((*((pool)->ptr)++ = c), 1))--struct XML_ParserStruct {- /* The first member must be userData so that the XML_GetUserData- macro works. */- void *m_userData;- void *m_handlerArg;- char *m_buffer;- const XML_Memory_Handling_Suite m_mem;- /* first character to be parsed */- const char *m_bufferPtr;- /* past last character to be parsed */- char *m_bufferEnd;- /* allocated end of buffer */- const char *m_bufferLim;- XML_Index m_parseEndByteIndex;- const char *m_parseEndPtr;- XML_Char *m_dataBuf;- XML_Char *m_dataBufEnd;- XML_StartElementHandler m_startElementHandler;- XML_EndElementHandler m_endElementHandler;- XML_CharacterDataHandler m_characterDataHandler;- XML_ProcessingInstructionHandler m_processingInstructionHandler;- XML_CommentHandler m_commentHandler;- XML_StartCdataSectionHandler m_startCdataSectionHandler;- XML_EndCdataSectionHandler m_endCdataSectionHandler;- XML_DefaultHandler m_defaultHandler;- XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;- XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;- XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;- XML_NotationDeclHandler m_notationDeclHandler;- XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;- XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;- XML_NotStandaloneHandler m_notStandaloneHandler;- XML_ExternalEntityRefHandler m_externalEntityRefHandler;- XML_Parser m_externalEntityRefHandlerArg;- XML_SkippedEntityHandler m_skippedEntityHandler;- XML_UnknownEncodingHandler m_unknownEncodingHandler;- XML_ElementDeclHandler m_elementDeclHandler;- XML_AttlistDeclHandler m_attlistDeclHandler;- XML_EntityDeclHandler m_entityDeclHandler;- XML_XmlDeclHandler m_xmlDeclHandler;- const ENCODING *m_encoding;- INIT_ENCODING m_initEncoding;- const ENCODING *m_internalEncoding;- const XML_Char *m_protocolEncodingName;- XML_Bool m_ns;- XML_Bool m_ns_triplets;- void *m_unknownEncodingMem;- void *m_unknownEncodingData;- void *m_unknownEncodingHandlerData;- void (XMLCALL *m_unknownEncodingRelease)(void *);- PROLOG_STATE m_prologState;- Processor *m_processor;- enum XML_Error m_errorCode;- const char *m_eventPtr;- const char *m_eventEndPtr;- const char *m_positionPtr;- OPEN_INTERNAL_ENTITY *m_openInternalEntities;- OPEN_INTERNAL_ENTITY *m_freeInternalEntities;- XML_Bool m_defaultExpandInternalEntities;- int m_tagLevel;- ENTITY *m_declEntity;- const XML_Char *m_doctypeName;- const XML_Char *m_doctypeSysid;- const XML_Char *m_doctypePubid;- const XML_Char *m_declAttributeType;- const XML_Char *m_declNotationName;- const XML_Char *m_declNotationPublicId;- ELEMENT_TYPE *m_declElementType;- ATTRIBUTE_ID *m_declAttributeId;- XML_Bool m_declAttributeIsCdata;- XML_Bool m_declAttributeIsId;- DTD *m_dtd;- const XML_Char *m_curBase;- TAG *m_tagStack;- TAG *m_freeTagList;- BINDING *m_inheritedBindings;- BINDING *m_freeBindingList;- int m_attsSize;- int m_nSpecifiedAtts;- int m_idAttIndex;- ATTRIBUTE *m_atts;- NS_ATT *m_nsAtts;- unsigned long m_nsAttsVersion;- unsigned char m_nsAttsPower;- POSITION m_position;- STRING_POOL m_tempPool;- STRING_POOL m_temp2Pool;- char *m_groupConnector;- unsigned int m_groupSize;- XML_Char m_namespaceSeparator;- XML_Parser m_parentParser;- XML_ParsingStatus m_parsingStatus;-#ifdef XML_DTD- XML_Bool m_isParamEntity;- XML_Bool m_useForeignDTD;- enum XML_ParamEntityParsing m_paramEntityParsing;-#endif-};--#define MALLOC(s) (parser->m_mem.malloc_fcn((s)))-#define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))-#define FREE(p) (parser->m_mem.free_fcn((p)))--#define userData (parser->m_userData)-#define handlerArg (parser->m_handlerArg)-#define startElementHandler (parser->m_startElementHandler)-#define endElementHandler (parser->m_endElementHandler)-#define characterDataHandler (parser->m_characterDataHandler)-#define processingInstructionHandler \- (parser->m_processingInstructionHandler)-#define commentHandler (parser->m_commentHandler)-#define startCdataSectionHandler \- (parser->m_startCdataSectionHandler)-#define endCdataSectionHandler (parser->m_endCdataSectionHandler)-#define defaultHandler (parser->m_defaultHandler)-#define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)-#define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)-#define unparsedEntityDeclHandler \- (parser->m_unparsedEntityDeclHandler)-#define notationDeclHandler (parser->m_notationDeclHandler)-#define startNamespaceDeclHandler \- (parser->m_startNamespaceDeclHandler)-#define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)-#define notStandaloneHandler (parser->m_notStandaloneHandler)-#define externalEntityRefHandler \- (parser->m_externalEntityRefHandler)-#define externalEntityRefHandlerArg \- (parser->m_externalEntityRefHandlerArg)-#define internalEntityRefHandler \- (parser->m_internalEntityRefHandler)-#define skippedEntityHandler (parser->m_skippedEntityHandler)-#define unknownEncodingHandler (parser->m_unknownEncodingHandler)-#define elementDeclHandler (parser->m_elementDeclHandler)-#define attlistDeclHandler (parser->m_attlistDeclHandler)-#define entityDeclHandler (parser->m_entityDeclHandler)-#define xmlDeclHandler (parser->m_xmlDeclHandler)-#define encoding (parser->m_encoding)-#define initEncoding (parser->m_initEncoding)-#define internalEncoding (parser->m_internalEncoding)-#define unknownEncodingMem (parser->m_unknownEncodingMem)-#define unknownEncodingData (parser->m_unknownEncodingData)-#define unknownEncodingHandlerData \- (parser->m_unknownEncodingHandlerData)-#define unknownEncodingRelease (parser->m_unknownEncodingRelease)-#define protocolEncodingName (parser->m_protocolEncodingName)-#define ns (parser->m_ns)-#define ns_triplets (parser->m_ns_triplets)-#define prologState (parser->m_prologState)-#define processor (parser->m_processor)-#define errorCode (parser->m_errorCode)-#define eventPtr (parser->m_eventPtr)-#define eventEndPtr (parser->m_eventEndPtr)-#define positionPtr (parser->m_positionPtr)-#define position (parser->m_position)-#define openInternalEntities (parser->m_openInternalEntities)-#define freeInternalEntities (parser->m_freeInternalEntities)-#define defaultExpandInternalEntities \- (parser->m_defaultExpandInternalEntities)-#define tagLevel (parser->m_tagLevel)-#define buffer (parser->m_buffer)-#define bufferPtr (parser->m_bufferPtr)-#define bufferEnd (parser->m_bufferEnd)-#define parseEndByteIndex (parser->m_parseEndByteIndex)-#define parseEndPtr (parser->m_parseEndPtr)-#define bufferLim (parser->m_bufferLim)-#define dataBuf (parser->m_dataBuf)-#define dataBufEnd (parser->m_dataBufEnd)-#define _dtd (parser->m_dtd)-#define curBase (parser->m_curBase)-#define declEntity (parser->m_declEntity)-#define doctypeName (parser->m_doctypeName)-#define doctypeSysid (parser->m_doctypeSysid)-#define doctypePubid (parser->m_doctypePubid)-#define declAttributeType (parser->m_declAttributeType)-#define declNotationName (parser->m_declNotationName)-#define declNotationPublicId (parser->m_declNotationPublicId)-#define declElementType (parser->m_declElementType)-#define declAttributeId (parser->m_declAttributeId)-#define declAttributeIsCdata (parser->m_declAttributeIsCdata)-#define declAttributeIsId (parser->m_declAttributeIsId)-#define freeTagList (parser->m_freeTagList)-#define freeBindingList (parser->m_freeBindingList)-#define inheritedBindings (parser->m_inheritedBindings)-#define tagStack (parser->m_tagStack)-#define atts (parser->m_atts)-#define attsSize (parser->m_attsSize)-#define nSpecifiedAtts (parser->m_nSpecifiedAtts)-#define idAttIndex (parser->m_idAttIndex)-#define nsAtts (parser->m_nsAtts)-#define nsAttsVersion (parser->m_nsAttsVersion)-#define nsAttsPower (parser->m_nsAttsPower)-#define tempPool (parser->m_tempPool)-#define temp2Pool (parser->m_temp2Pool)-#define groupConnector (parser->m_groupConnector)-#define groupSize (parser->m_groupSize)-#define namespaceSeparator (parser->m_namespaceSeparator)-#define parentParser (parser->m_parentParser)-#define ps_parsing (parser->m_parsingStatus.parsing)-#define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)-#ifdef XML_DTD-#define isParamEntity (parser->m_isParamEntity)-#define useForeignDTD (parser->m_useForeignDTD)-#define paramEntityParsing (parser->m_paramEntityParsing)-#endif /* XML_DTD */--XML_Parser XMLCALL-XML_ParserCreate(const XML_Char *encodingName)-{- return XML_ParserCreate_MM(encodingName, NULL, NULL);-}--XML_Parser XMLCALL-XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)-{- XML_Char tmp[2];- *tmp = nsSep;- return XML_ParserCreate_MM(encodingName, NULL, tmp);-}--static const XML_Char implicitContext[] = {- ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p,- ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, - ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g,- ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9,- ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e,- ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'-};--XML_Parser XMLCALL-XML_ParserCreate_MM(const XML_Char *encodingName,- const XML_Memory_Handling_Suite *memsuite,- const XML_Char *nameSep)-{- XML_Parser parser = parserCreate(encodingName, memsuite, nameSep, NULL);- if (parser != NULL && ns) {- /* implicit context only set for root parser, since child- parsers (i.e. external entity parsers) will inherit it- */- if (!setContext(parser, implicitContext)) {- XML_ParserFree(parser);- return NULL;- }- }- return parser;-}--static XML_Parser-parserCreate(const XML_Char *encodingName,- const XML_Memory_Handling_Suite *memsuite,- const XML_Char *nameSep,- DTD *dtd)-{- XML_Parser parser;-- if (memsuite) {- XML_Memory_Handling_Suite *mtemp;- parser = (XML_Parser)- memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));- if (parser != NULL) {- mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);- mtemp->malloc_fcn = memsuite->malloc_fcn;- mtemp->realloc_fcn = memsuite->realloc_fcn;- mtemp->free_fcn = memsuite->free_fcn;- }- }- else {- XML_Memory_Handling_Suite *mtemp;- parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));- if (parser != NULL) {- mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);- mtemp->malloc_fcn = malloc;- mtemp->realloc_fcn = realloc;- mtemp->free_fcn = free;- }- }-- if (!parser)- return parser;-- buffer = NULL;- bufferLim = NULL;-- attsSize = INIT_ATTS_SIZE;- atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));- if (atts == NULL) {- FREE(parser);- return NULL;- }- dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));- if (dataBuf == NULL) {- FREE(atts);- FREE(parser);- return NULL;- }- dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;-- if (dtd)- _dtd = dtd;- else {- _dtd = dtdCreate(&parser->m_mem);- if (_dtd == NULL) {- FREE(dataBuf);- FREE(atts);- FREE(parser);- return NULL;- }- }-- freeBindingList = NULL;- freeTagList = NULL;- freeInternalEntities = NULL;-- groupSize = 0;- groupConnector = NULL;-- unknownEncodingHandler = NULL;- unknownEncodingHandlerData = NULL;-- namespaceSeparator = ASCII_EXCL;- ns = XML_FALSE;- ns_triplets = XML_FALSE;-- nsAtts = NULL;- nsAttsVersion = 0;- nsAttsPower = 0;-- poolInit(&tempPool, &(parser->m_mem));- poolInit(&temp2Pool, &(parser->m_mem));- parserInit(parser, encodingName);-- if (encodingName && !protocolEncodingName) {- XML_ParserFree(parser);- return NULL;- }-- if (nameSep) {- ns = XML_TRUE;- internalEncoding = XmlGetInternalEncodingNS();- namespaceSeparator = *nameSep;- }- else {- internalEncoding = XmlGetInternalEncoding();- }-- return parser;-}--static void-parserInit(XML_Parser parser, const XML_Char *encodingName)-{- processor = prologInitProcessor;- XmlPrologStateInit(&prologState);- protocolEncodingName = (encodingName != NULL- ? poolCopyString(&tempPool, encodingName)- : NULL);- curBase = NULL;- XmlInitEncoding(&initEncoding, &encoding, 0);- userData = NULL;- handlerArg = NULL;- startElementHandler = NULL;- endElementHandler = NULL;- characterDataHandler = NULL;- processingInstructionHandler = NULL;- commentHandler = NULL;- startCdataSectionHandler = NULL;- endCdataSectionHandler = NULL;- defaultHandler = NULL;- startDoctypeDeclHandler = NULL;- endDoctypeDeclHandler = NULL;- unparsedEntityDeclHandler = NULL;- notationDeclHandler = NULL;- startNamespaceDeclHandler = NULL;- endNamespaceDeclHandler = NULL;- notStandaloneHandler = NULL;- externalEntityRefHandler = NULL;- externalEntityRefHandlerArg = parser;- skippedEntityHandler = NULL;- elementDeclHandler = NULL;- attlistDeclHandler = NULL;- entityDeclHandler = NULL;- xmlDeclHandler = NULL;- bufferPtr = buffer;- bufferEnd = buffer;- parseEndByteIndex = 0;- parseEndPtr = NULL;- declElementType = NULL;- declAttributeId = NULL;- declEntity = NULL;- doctypeName = NULL;- doctypeSysid = NULL;- doctypePubid = NULL;- declAttributeType = NULL;- declNotationName = NULL;- declNotationPublicId = NULL;- declAttributeIsCdata = XML_FALSE;- declAttributeIsId = XML_FALSE;- memset(&position, 0, sizeof(POSITION));- errorCode = XML_ERROR_NONE;- eventPtr = NULL;- eventEndPtr = NULL;- positionPtr = NULL;- openInternalEntities = NULL;- defaultExpandInternalEntities = XML_TRUE;- tagLevel = 0;- tagStack = NULL;- inheritedBindings = NULL;- nSpecifiedAtts = 0;- unknownEncodingMem = NULL;- unknownEncodingRelease = NULL;- unknownEncodingData = NULL;- parentParser = NULL;- ps_parsing = XML_INITIALIZED;-#ifdef XML_DTD- isParamEntity = XML_FALSE;- useForeignDTD = XML_FALSE;- paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;-#endif-}--/* moves list of bindings to freeBindingList */-static void FASTCALL-moveToFreeBindingList(XML_Parser parser, BINDING *bindings)-{- while (bindings) {- BINDING *b = bindings;- bindings = bindings->nextTagBinding;- b->nextTagBinding = freeBindingList;- freeBindingList = b;- }-}--XML_Bool XMLCALL-XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)-{- TAG *tStk;- OPEN_INTERNAL_ENTITY *openEntityList;- if (parentParser)- return XML_FALSE;- /* move tagStack to freeTagList */- tStk = tagStack;- while (tStk) {- TAG *tag = tStk;- tStk = tStk->parent;- tag->parent = freeTagList;- moveToFreeBindingList(parser, tag->bindings);- tag->bindings = NULL;- freeTagList = tag;- }- /* move openInternalEntities to freeInternalEntities */- openEntityList = openInternalEntities;- while (openEntityList) {- OPEN_INTERNAL_ENTITY *openEntity = openEntityList;- openEntityList = openEntity->next;- openEntity->next = freeInternalEntities;- freeInternalEntities = openEntity;- }- moveToFreeBindingList(parser, inheritedBindings);- FREE(unknownEncodingMem);- if (unknownEncodingRelease)- unknownEncodingRelease(unknownEncodingData);- poolClear(&tempPool);- poolClear(&temp2Pool);- parserInit(parser, encodingName);- dtdReset(_dtd, &parser->m_mem);- return setContext(parser, implicitContext);-}--enum XML_Status XMLCALL-XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)-{- /* Block after XML_Parse()/XML_ParseBuffer() has been called.- XXX There's no way for the caller to determine which of the- XXX possible error cases caused the XML_STATUS_ERROR return.- */- if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)- return XML_STATUS_ERROR;- if (encodingName == NULL)- protocolEncodingName = NULL;- else {- protocolEncodingName = poolCopyString(&tempPool, encodingName);- if (!protocolEncodingName)- return XML_STATUS_ERROR;- }- return XML_STATUS_OK;-}--XML_Parser XMLCALL-XML_ExternalEntityParserCreate(XML_Parser oldParser,- const XML_Char *context,- const XML_Char *encodingName)-{- XML_Parser parser = oldParser;- DTD *newDtd = NULL;- DTD *oldDtd = _dtd;- XML_StartElementHandler oldStartElementHandler = startElementHandler;- XML_EndElementHandler oldEndElementHandler = endElementHandler;- XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;- XML_ProcessingInstructionHandler oldProcessingInstructionHandler- = processingInstructionHandler;- XML_CommentHandler oldCommentHandler = commentHandler;- XML_StartCdataSectionHandler oldStartCdataSectionHandler- = startCdataSectionHandler;- XML_EndCdataSectionHandler oldEndCdataSectionHandler- = endCdataSectionHandler;- XML_DefaultHandler oldDefaultHandler = defaultHandler;- XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler- = unparsedEntityDeclHandler;- XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;- XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler- = startNamespaceDeclHandler;- XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler- = endNamespaceDeclHandler;- XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;- XML_ExternalEntityRefHandler oldExternalEntityRefHandler- = externalEntityRefHandler;- XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;- XML_UnknownEncodingHandler oldUnknownEncodingHandler- = unknownEncodingHandler;- XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;- XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;- XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;- XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;- ELEMENT_TYPE * oldDeclElementType = declElementType;-- void *oldUserData = userData;- void *oldHandlerArg = handlerArg;- XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;- XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;-#ifdef XML_DTD- enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;- int oldInEntityValue = prologState.inEntityValue;-#endif- XML_Bool oldns_triplets = ns_triplets;--#ifdef XML_DTD- if (!context)- newDtd = oldDtd;-#endif /* XML_DTD */-- /* Note that the magical uses of the pre-processor to make field- access look more like C++ require that `parser' be overwritten- here. This makes this function more painful to follow than it- would be otherwise.- */- if (ns) {- XML_Char tmp[2];- *tmp = namespaceSeparator;- parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);- }- else {- parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);- }-- if (!parser)- return NULL;-- startElementHandler = oldStartElementHandler;- endElementHandler = oldEndElementHandler;- characterDataHandler = oldCharacterDataHandler;- processingInstructionHandler = oldProcessingInstructionHandler;- commentHandler = oldCommentHandler;- startCdataSectionHandler = oldStartCdataSectionHandler;- endCdataSectionHandler = oldEndCdataSectionHandler;- defaultHandler = oldDefaultHandler;- unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;- notationDeclHandler = oldNotationDeclHandler;- startNamespaceDeclHandler = oldStartNamespaceDeclHandler;- endNamespaceDeclHandler = oldEndNamespaceDeclHandler;- notStandaloneHandler = oldNotStandaloneHandler;- externalEntityRefHandler = oldExternalEntityRefHandler;- skippedEntityHandler = oldSkippedEntityHandler;- unknownEncodingHandler = oldUnknownEncodingHandler;- elementDeclHandler = oldElementDeclHandler;- attlistDeclHandler = oldAttlistDeclHandler;- entityDeclHandler = oldEntityDeclHandler;- xmlDeclHandler = oldXmlDeclHandler;- declElementType = oldDeclElementType;- userData = oldUserData;- if (oldUserData == oldHandlerArg)- handlerArg = userData;- else- handlerArg = parser;- if (oldExternalEntityRefHandlerArg != oldParser)- externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;- defaultExpandInternalEntities = oldDefaultExpandInternalEntities;- ns_triplets = oldns_triplets;- parentParser = oldParser;-#ifdef XML_DTD- paramEntityParsing = oldParamEntityParsing;- prologState.inEntityValue = oldInEntityValue;- if (context) {-#endif /* XML_DTD */- if (!dtdCopy(_dtd, oldDtd, &parser->m_mem)- || !setContext(parser, context)) {- XML_ParserFree(parser);- return NULL;- }- processor = externalEntityInitProcessor;-#ifdef XML_DTD- }- else {- /* The DTD instance referenced by _dtd is shared between the document's- root parser and external PE parsers, therefore one does not need to- call setContext. In addition, one also *must* not call setContext,- because this would overwrite existing prefix->binding pointers in- _dtd with ones that get destroyed with the external PE parser.- This would leave those prefixes with dangling pointers.- */- isParamEntity = XML_TRUE;- XmlPrologStateInitExternalEntity(&prologState);- processor = externalParEntInitProcessor;- }-#endif /* XML_DTD */- return parser;-}--static void FASTCALL-destroyBindings(BINDING *bindings, XML_Parser parser)-{- for (;;) {- BINDING *b = bindings;- if (!b)- break;- bindings = b->nextTagBinding;- FREE(b->uri);- FREE(b);- }-}--void XMLCALL-XML_ParserFree(XML_Parser parser)-{- TAG *tagList;- OPEN_INTERNAL_ENTITY *entityList;- if (parser == NULL)- return;- /* free tagStack and freeTagList */- tagList = tagStack;- for (;;) {- TAG *p;- if (tagList == NULL) {- if (freeTagList == NULL)- break;- tagList = freeTagList;- freeTagList = NULL;- }- p = tagList;- tagList = tagList->parent;- FREE(p->buf);- destroyBindings(p->bindings, parser);- FREE(p);- }- /* free openInternalEntities and freeInternalEntities */- entityList = openInternalEntities;- for (;;) {- OPEN_INTERNAL_ENTITY *openEntity;- if (entityList == NULL) {- if (freeInternalEntities == NULL)- break;- entityList = freeInternalEntities;- freeInternalEntities = NULL;- }- openEntity = entityList;- entityList = entityList->next;- FREE(openEntity);- }-- destroyBindings(freeBindingList, parser);- destroyBindings(inheritedBindings, parser);- poolDestroy(&tempPool);- poolDestroy(&temp2Pool);-#ifdef XML_DTD- /* external parameter entity parsers share the DTD structure- parser->m_dtd with the root parser, so we must not destroy it- */- if (!isParamEntity && _dtd)-#else- if (_dtd)-#endif /* XML_DTD */- dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);- FREE((void *)atts);- FREE(groupConnector);- FREE(buffer);- FREE(dataBuf);- FREE(nsAtts);- FREE(unknownEncodingMem);- if (unknownEncodingRelease)- unknownEncodingRelease(unknownEncodingData);- FREE(parser);-}--void XMLCALL-XML_UseParserAsHandlerArg(XML_Parser parser)-{- handlerArg = parser;-}--enum XML_Error XMLCALL-XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)-{-#ifdef XML_DTD- /* block after XML_Parse()/XML_ParseBuffer() has been called */- if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)- return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;- useForeignDTD = useDTD;- return XML_ERROR_NONE;-#else- return XML_ERROR_FEATURE_REQUIRES_XML_DTD;-#endif-}--void XMLCALL-XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)-{- /* block after XML_Parse()/XML_ParseBuffer() has been called */- if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)- return;- ns_triplets = do_nst ? XML_TRUE : XML_FALSE;-}--void XMLCALL-XML_SetUserData(XML_Parser parser, void *p)-{- if (handlerArg == userData)- handlerArg = userData = p;- else- userData = p;-}--enum XML_Status XMLCALL-XML_SetBase(XML_Parser parser, const XML_Char *p)-{- if (p) {- p = poolCopyString(&_dtd->pool, p);- if (!p)- return XML_STATUS_ERROR;- curBase = p;- }- else- curBase = NULL;- return XML_STATUS_OK;-}--const XML_Char * XMLCALL-XML_GetBase(XML_Parser parser)-{- return curBase;-}--int XMLCALL-XML_GetSpecifiedAttributeCount(XML_Parser parser)-{- return nSpecifiedAtts;-}--int XMLCALL-XML_GetIdAttributeIndex(XML_Parser parser)-{- return idAttIndex;-}--void XMLCALL-XML_SetElementHandler(XML_Parser parser,- XML_StartElementHandler start,- XML_EndElementHandler end)-{- startElementHandler = start;- endElementHandler = end;-}--void XMLCALL-XML_SetStartElementHandler(XML_Parser parser,- XML_StartElementHandler start) {- startElementHandler = start;-}--void XMLCALL-XML_SetEndElementHandler(XML_Parser parser,- XML_EndElementHandler end) {- endElementHandler = end;-}--void XMLCALL-XML_SetCharacterDataHandler(XML_Parser parser,- XML_CharacterDataHandler handler)-{- characterDataHandler = handler;-}--void XMLCALL-XML_SetProcessingInstructionHandler(XML_Parser parser,- XML_ProcessingInstructionHandler handler)-{- processingInstructionHandler = handler;-}--void XMLCALL-XML_SetCommentHandler(XML_Parser parser,- XML_CommentHandler handler)-{- commentHandler = handler;-}--void XMLCALL-XML_SetCdataSectionHandler(XML_Parser parser,- XML_StartCdataSectionHandler start,- XML_EndCdataSectionHandler end)-{- startCdataSectionHandler = start;- endCdataSectionHandler = end;-}--void XMLCALL-XML_SetStartCdataSectionHandler(XML_Parser parser,- XML_StartCdataSectionHandler start) {- startCdataSectionHandler = start;-}--void XMLCALL-XML_SetEndCdataSectionHandler(XML_Parser parser,- XML_EndCdataSectionHandler end) {- endCdataSectionHandler = end;-}--void XMLCALL-XML_SetDefaultHandler(XML_Parser parser,- XML_DefaultHandler handler)-{- defaultHandler = handler;- defaultExpandInternalEntities = XML_FALSE;-}--void XMLCALL-XML_SetDefaultHandlerExpand(XML_Parser parser,- XML_DefaultHandler handler)-{- defaultHandler = handler;- defaultExpandInternalEntities = XML_TRUE;-}--void XMLCALL-XML_SetDoctypeDeclHandler(XML_Parser parser,- XML_StartDoctypeDeclHandler start,- XML_EndDoctypeDeclHandler end)-{- startDoctypeDeclHandler = start;- endDoctypeDeclHandler = end;-}--void XMLCALL-XML_SetStartDoctypeDeclHandler(XML_Parser parser,- XML_StartDoctypeDeclHandler start) {- startDoctypeDeclHandler = start;-}--void XMLCALL-XML_SetEndDoctypeDeclHandler(XML_Parser parser,- XML_EndDoctypeDeclHandler end) {- endDoctypeDeclHandler = end;-}--void XMLCALL-XML_SetUnparsedEntityDeclHandler(XML_Parser parser,- XML_UnparsedEntityDeclHandler handler)-{- unparsedEntityDeclHandler = handler;-}--void XMLCALL-XML_SetNotationDeclHandler(XML_Parser parser,- XML_NotationDeclHandler handler)-{- notationDeclHandler = handler;-}--void XMLCALL-XML_SetNamespaceDeclHandler(XML_Parser parser,- XML_StartNamespaceDeclHandler start,- XML_EndNamespaceDeclHandler end)-{- startNamespaceDeclHandler = start;- endNamespaceDeclHandler = end;-}--void XMLCALL-XML_SetStartNamespaceDeclHandler(XML_Parser parser,- XML_StartNamespaceDeclHandler start) {- startNamespaceDeclHandler = start;-}--void XMLCALL-XML_SetEndNamespaceDeclHandler(XML_Parser parser,- XML_EndNamespaceDeclHandler end) {- endNamespaceDeclHandler = end;-}--void XMLCALL-XML_SetNotStandaloneHandler(XML_Parser parser,- XML_NotStandaloneHandler handler)-{- notStandaloneHandler = handler;-}--void XMLCALL-XML_SetExternalEntityRefHandler(XML_Parser parser,- XML_ExternalEntityRefHandler handler)-{- externalEntityRefHandler = handler;-}--void XMLCALL-XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)-{- if (arg)- externalEntityRefHandlerArg = (XML_Parser)arg;- else- externalEntityRefHandlerArg = parser;-}--void XMLCALL-XML_SetSkippedEntityHandler(XML_Parser parser,- XML_SkippedEntityHandler handler)-{- skippedEntityHandler = handler;-}--void XMLCALL-XML_SetUnknownEncodingHandler(XML_Parser parser,- XML_UnknownEncodingHandler handler,- void *data)-{- unknownEncodingHandler = handler;- unknownEncodingHandlerData = data;-}--void XMLCALL-XML_SetElementDeclHandler(XML_Parser parser,- XML_ElementDeclHandler eldecl)-{- elementDeclHandler = eldecl;-}--void XMLCALL-XML_SetAttlistDeclHandler(XML_Parser parser,- XML_AttlistDeclHandler attdecl)-{- attlistDeclHandler = attdecl;-}--void XMLCALL-XML_SetEntityDeclHandler(XML_Parser parser,- XML_EntityDeclHandler handler)-{- entityDeclHandler = handler;-}--void XMLCALL-XML_SetXmlDeclHandler(XML_Parser parser,- XML_XmlDeclHandler handler) {- xmlDeclHandler = handler;-}--int XMLCALL-XML_SetParamEntityParsing(XML_Parser parser,- enum XML_ParamEntityParsing peParsing)-{- /* block after XML_Parse()/XML_ParseBuffer() has been called */- if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)- return 0;-#ifdef XML_DTD- paramEntityParsing = peParsing;- return 1;-#else- return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;-#endif-}--enum XML_Status XMLCALL-XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)-{- switch (ps_parsing) {- case XML_SUSPENDED:- errorCode = XML_ERROR_SUSPENDED;- return XML_STATUS_ERROR;- case XML_FINISHED:- errorCode = XML_ERROR_FINISHED;- return XML_STATUS_ERROR;- default:- ps_parsing = XML_PARSING;- }-- if (len == 0) {- ps_finalBuffer = (XML_Bool)isFinal;- if (!isFinal)- return XML_STATUS_OK;- positionPtr = bufferPtr;- parseEndPtr = bufferEnd;-- /* If data are left over from last buffer, and we now know that these- data are the final chunk of input, then we have to check them again- to detect errors based on that fact.- */- errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);-- if (errorCode == XML_ERROR_NONE) {- switch (ps_parsing) {- case XML_SUSPENDED:- XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);- positionPtr = bufferPtr;- return XML_STATUS_SUSPENDED;- case XML_INITIALIZED: - case XML_PARSING:- ps_parsing = XML_FINISHED;- /* fall through */- default:- return XML_STATUS_OK;- }- }- eventEndPtr = eventPtr;- processor = errorProcessor;- return XML_STATUS_ERROR;- }-#ifndef XML_CONTEXT_BYTES- else if (bufferPtr == bufferEnd) {- const char *end;- int nLeftOver;- enum XML_Error result;- parseEndByteIndex += len;- positionPtr = s;- ps_finalBuffer = (XML_Bool)isFinal;-- errorCode = processor(parser, s, parseEndPtr = s + len, &end);-- if (errorCode != XML_ERROR_NONE) {- eventEndPtr = eventPtr;- processor = errorProcessor;- return XML_STATUS_ERROR;- }- else {- switch (ps_parsing) {- case XML_SUSPENDED:- result = XML_STATUS_SUSPENDED;- break;- case XML_INITIALIZED:- case XML_PARSING:- result = XML_STATUS_OK;- if (isFinal) {- ps_parsing = XML_FINISHED;- return result;- }- }- }-- XmlUpdatePosition(encoding, positionPtr, end, &position);- nLeftOver = s + len - end;- if (nLeftOver) {- if (buffer == NULL || nLeftOver > bufferLim - buffer) {- /* FIXME avoid integer overflow */- char *temp;- temp = (buffer == NULL- ? (char *)MALLOC(len * 2)- : (char *)REALLOC(buffer, len * 2));- if (temp == NULL) {- errorCode = XML_ERROR_NO_MEMORY;- return XML_STATUS_ERROR;- }- buffer = temp;- if (!buffer) {- errorCode = XML_ERROR_NO_MEMORY;- eventPtr = eventEndPtr = NULL;- processor = errorProcessor;- return XML_STATUS_ERROR;- }- bufferLim = buffer + len * 2;- }- memcpy(buffer, end, nLeftOver);- }- bufferPtr = buffer;- bufferEnd = buffer + nLeftOver;- positionPtr = bufferPtr;- parseEndPtr = bufferEnd;- eventPtr = bufferPtr;- eventEndPtr = bufferPtr;- return result;- }-#endif /* not defined XML_CONTEXT_BYTES */- else {- void *buff = XML_GetBuffer(parser, len);- if (buff == NULL)- return XML_STATUS_ERROR;- else {- memcpy(buff, s, len);- return XML_ParseBuffer(parser, len, isFinal);- }- }-}--enum XML_Status XMLCALL-XML_ParseBuffer(XML_Parser parser, int len, int isFinal)-{- const char *start;- enum XML_Status result = XML_STATUS_OK;-- switch (ps_parsing) {- case XML_SUSPENDED:- errorCode = XML_ERROR_SUSPENDED;- return XML_STATUS_ERROR;- case XML_FINISHED:- errorCode = XML_ERROR_FINISHED;- return XML_STATUS_ERROR;- default:- ps_parsing = XML_PARSING;- }-- start = bufferPtr;- positionPtr = start;- bufferEnd += len;- parseEndPtr = bufferEnd;- parseEndByteIndex += len;- ps_finalBuffer = (XML_Bool)isFinal;-- errorCode = processor(parser, start, parseEndPtr, &bufferPtr);-- if (errorCode != XML_ERROR_NONE) {- eventEndPtr = eventPtr;- processor = errorProcessor;- return XML_STATUS_ERROR;- }- else {- switch (ps_parsing) {- case XML_SUSPENDED:- result = XML_STATUS_SUSPENDED;- break;- case XML_INITIALIZED: - case XML_PARSING:- if (isFinal) {- ps_parsing = XML_FINISHED;- return result;- }- default: ; /* should not happen */- }- }-- XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);- positionPtr = bufferPtr;- return result;-}--void * XMLCALL-XML_GetBuffer(XML_Parser parser, int len)-{- switch (ps_parsing) {- case XML_SUSPENDED:- errorCode = XML_ERROR_SUSPENDED;- return NULL;- case XML_FINISHED:- errorCode = XML_ERROR_FINISHED;- return NULL;- default: ;- }-- if (len > bufferLim - bufferEnd) {- /* FIXME avoid integer overflow */- int neededSize = len + (int)(bufferEnd - bufferPtr);-#ifdef XML_CONTEXT_BYTES- int keep = (int)(bufferPtr - buffer);-- if (keep > XML_CONTEXT_BYTES)- keep = XML_CONTEXT_BYTES;- neededSize += keep;-#endif /* defined XML_CONTEXT_BYTES */- if (neededSize <= bufferLim - buffer) {-#ifdef XML_CONTEXT_BYTES- if (keep < bufferPtr - buffer) {- int offset = (int)(bufferPtr - buffer) - keep;- memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);- bufferEnd -= offset;- bufferPtr -= offset;- }-#else- memmove(buffer, bufferPtr, bufferEnd - bufferPtr);- bufferEnd = buffer + (bufferEnd - bufferPtr);- bufferPtr = buffer;-#endif /* not defined XML_CONTEXT_BYTES */- }- else {- char *newBuf;- int bufferSize = (int)(bufferLim - bufferPtr);- if (bufferSize == 0)- bufferSize = INIT_BUFFER_SIZE;- do {- bufferSize *= 2;- } while (bufferSize < neededSize);- newBuf = (char *)MALLOC(bufferSize);- if (newBuf == 0) {- errorCode = XML_ERROR_NO_MEMORY;- return NULL;- }- bufferLim = newBuf + bufferSize;-#ifdef XML_CONTEXT_BYTES- if (bufferPtr) {- int keep = (int)(bufferPtr - buffer);- if (keep > XML_CONTEXT_BYTES)- keep = XML_CONTEXT_BYTES;- memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);- FREE(buffer);- buffer = newBuf;- bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;- bufferPtr = buffer + keep;- }- else {- bufferEnd = newBuf + (bufferEnd - bufferPtr);- bufferPtr = buffer = newBuf;- }-#else- if (bufferPtr) {- memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);- FREE(buffer);- }- bufferEnd = newBuf + (bufferEnd - bufferPtr);- bufferPtr = buffer = newBuf;-#endif /* not defined XML_CONTEXT_BYTES */- }- }- return bufferEnd;-}--enum XML_Status XMLCALL-XML_StopParser(XML_Parser parser, XML_Bool resumable)-{- switch (ps_parsing) {- case XML_SUSPENDED:- if (resumable) {- errorCode = XML_ERROR_SUSPENDED;- return XML_STATUS_ERROR;- }- ps_parsing = XML_FINISHED;- break;- case XML_FINISHED:- errorCode = XML_ERROR_FINISHED;- return XML_STATUS_ERROR;- default:- if (resumable) {-#ifdef XML_DTD- if (isParamEntity) {- errorCode = XML_ERROR_SUSPEND_PE;- return XML_STATUS_ERROR;- }-#endif- ps_parsing = XML_SUSPENDED;- }- else- ps_parsing = XML_FINISHED;- }- return XML_STATUS_OK;-}--enum XML_Status XMLCALL-XML_ResumeParser(XML_Parser parser)-{- enum XML_Status result = XML_STATUS_OK;-- if (ps_parsing != XML_SUSPENDED) {- errorCode = XML_ERROR_NOT_SUSPENDED;- return XML_STATUS_ERROR;- }- ps_parsing = XML_PARSING;-- errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);-- if (errorCode != XML_ERROR_NONE) {- eventEndPtr = eventPtr;- processor = errorProcessor;- return XML_STATUS_ERROR;- }- else {- switch (ps_parsing) {- case XML_SUSPENDED:- result = XML_STATUS_SUSPENDED;- break;- case XML_INITIALIZED: - case XML_PARSING:- if (ps_finalBuffer) {- ps_parsing = XML_FINISHED;- return result;- }- default: ;- }- }-- XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);- positionPtr = bufferPtr;- return result;-}--void XMLCALL-XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)-{- assert(status != NULL);- *status = parser->m_parsingStatus;-}--enum XML_Error XMLCALL-XML_GetErrorCode(XML_Parser parser)-{- return errorCode;-}--XML_Index XMLCALL-XML_GetCurrentByteIndex(XML_Parser parser)-{- if (eventPtr)- return parseEndByteIndex - (parseEndPtr - eventPtr);- return -1;-}--int XMLCALL-XML_GetCurrentByteCount(XML_Parser parser)-{- if (eventEndPtr && eventPtr)- return (int)(eventEndPtr - eventPtr);- return 0;-}--const char * XMLCALL-XML_GetInputContext(XML_Parser parser, int *offset, int *size)-{-#ifdef XML_CONTEXT_BYTES- if (eventPtr && buffer) {- *offset = (int)(eventPtr - buffer);- *size = (int)(bufferEnd - buffer);- return buffer;- }-#endif /* defined XML_CONTEXT_BYTES */- return (char *) 0;-}--XML_Size XMLCALL-XML_GetCurrentLineNumber(XML_Parser parser)-{- if (eventPtr && eventPtr >= positionPtr) {- XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);- positionPtr = eventPtr;- }- return position.lineNumber + 1;-}--XML_Size XMLCALL-XML_GetCurrentColumnNumber(XML_Parser parser)-{- if (eventPtr && eventPtr >= positionPtr) {- XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);- positionPtr = eventPtr;- }- return position.columnNumber;-}--void XMLCALL-XML_FreeContentModel(XML_Parser parser, XML_Content *model)-{- FREE(model);-}--void * XMLCALL-XML_MemMalloc(XML_Parser parser, size_t size)-{- return MALLOC(size);-}--void * XMLCALL-XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)-{- return REALLOC(ptr, size);-}--void XMLCALL-XML_MemFree(XML_Parser parser, void *ptr)-{- FREE(ptr);-}--void XMLCALL-XML_DefaultCurrent(XML_Parser parser)-{- if (defaultHandler) {- if (openInternalEntities)- reportDefault(parser,- internalEncoding,- openInternalEntities->internalEventPtr,- openInternalEntities->internalEventEndPtr);- else- reportDefault(parser, encoding, eventPtr, eventEndPtr);- }-}--const XML_LChar * XMLCALL-XML_ErrorString(enum XML_Error code)-{- static const XML_LChar* const message[] = {- 0,- XML_L("out of memory"),- XML_L("syntax error"),- XML_L("no element found"),- XML_L("not well-formed (invalid token)"),- XML_L("unclosed token"),- XML_L("partial character"),- XML_L("mismatched tag"),- XML_L("duplicate attribute"),- XML_L("junk after document element"),- XML_L("illegal parameter entity reference"),- XML_L("undefined entity"),- XML_L("recursive entity reference"),- XML_L("asynchronous entity"),- XML_L("reference to invalid character number"),- XML_L("reference to binary entity"),- XML_L("reference to external entity in attribute"),- XML_L("XML or text declaration not at start of entity"),- XML_L("unknown encoding"),- XML_L("encoding specified in XML declaration is incorrect"),- XML_L("unclosed CDATA section"),- XML_L("error in processing external entity reference"),- XML_L("document is not standalone"),- XML_L("unexpected parser state - please send a bug report"),- XML_L("entity declared in parameter entity"),- XML_L("requested feature requires XML_DTD support in Expat"),- XML_L("cannot change setting once parsing has begun"),- XML_L("unbound prefix"),- XML_L("must not undeclare prefix"),- XML_L("incomplete markup in parameter entity"),- XML_L("XML declaration not well-formed"),- XML_L("text declaration not well-formed"),- XML_L("illegal character(s) in public id"),- XML_L("parser suspended"),- XML_L("parser not suspended"),- XML_L("parsing aborted"),- XML_L("parsing finished"),- XML_L("cannot suspend in external parameter entity"),- XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),- XML_L("reserved prefix (xmlns) must not be declared or undeclared"),- XML_L("prefix must not be bound to one of the reserved namespace names")- };- if (code > 0 && code < sizeof(message)/sizeof(message[0]))- return message[code];- return NULL;-}--const XML_LChar * XMLCALL-XML_ExpatVersion(void) {-- /* V1 is used to string-ize the version number. However, it would- string-ize the actual version macro *names* unless we get them- substituted before being passed to V1. CPP is defined to expand- a macro, then rescan for more expansions. Thus, we use V2 to expand- the version macros, then CPP will expand the resulting V1() macro- with the correct numerals. */- /* ### I'm assuming cpp is portable in this respect... */--#define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)-#define V2(a,b,c) XML_L("expat_")V1(a,b,c)-- return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);--#undef V1-#undef V2-}--XML_Expat_Version XMLCALL-XML_ExpatVersionInfo(void)-{- XML_Expat_Version version;-- version.major = XML_MAJOR_VERSION;- version.minor = XML_MINOR_VERSION;- version.micro = XML_MICRO_VERSION;-- return version;-}--const XML_Feature * XMLCALL-XML_GetFeatureList(void)-{- static const XML_Feature features[] = {- {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"),- sizeof(XML_Char)},- {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),- sizeof(XML_LChar)},-#ifdef XML_UNICODE- {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},-#endif-#ifdef XML_UNICODE_WCHAR_T- {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},-#endif-#ifdef XML_DTD- {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},-#endif-#ifdef XML_CONTEXT_BYTES- {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),- XML_CONTEXT_BYTES},-#endif-#ifdef XML_MIN_SIZE- {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},-#endif-#ifdef XML_NS- {XML_FEATURE_NS, XML_L("XML_NS"), 0},-#endif-#ifdef XML_LARGE_SIZE- {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0},-#endif - {XML_FEATURE_END, NULL, 0}- };-- return features;-}--/* Initially tag->rawName always points into the parse buffer;- for those TAG instances opened while the current parse buffer was- processed, and not yet closed, we need to store tag->rawName in a more- permanent location, since the parse buffer is about to be discarded.-*/-static XML_Bool-storeRawNames(XML_Parser parser)-{- TAG *tag = tagStack;- while (tag) {- int bufSize;- int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);- char *rawNameBuf = tag->buf + nameLen;- /* Stop if already stored. Since tagStack is a stack, we can stop- at the first entry that has already been copied; everything- below it in the stack is already been accounted for in a- previous call to this function.- */- if (tag->rawName == rawNameBuf)- break;- /* For re-use purposes we need to ensure that the- size of tag->buf is a multiple of sizeof(XML_Char).- */- bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));- if (bufSize > tag->bufEnd - tag->buf) {- char *temp = (char *)REALLOC(tag->buf, bufSize);- if (temp == NULL)- return XML_FALSE;- /* if tag->name.str points to tag->buf (only when namespace- processing is off) then we have to update it- */- if (tag->name.str == (XML_Char *)tag->buf)- tag->name.str = (XML_Char *)temp;- /* if tag->name.localPart is set (when namespace processing is on)- then update it as well, since it will always point into tag->buf- */- if (tag->name.localPart)- tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -- (XML_Char *)tag->buf);- tag->buf = temp;- tag->bufEnd = temp + bufSize;- rawNameBuf = temp + nameLen;- }- memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);- tag->rawName = rawNameBuf;- tag = tag->parent;- }- return XML_TRUE;-}--static enum XML_Error PTRCALL-contentProcessor(XML_Parser parser,- const char *start,- const char *end,- const char **endPtr)-{- enum XML_Error result = doContent(parser, 0, encoding, start, end, - endPtr, (XML_Bool)!ps_finalBuffer);- if (result == XML_ERROR_NONE) {- if (!storeRawNames(parser))- return XML_ERROR_NO_MEMORY;- }- return result;-}--static enum XML_Error PTRCALL-externalEntityInitProcessor(XML_Parser parser,- const char *start,- const char *end,- const char **endPtr)-{- enum XML_Error result = initializeEncoding(parser);- if (result != XML_ERROR_NONE)- return result;- processor = externalEntityInitProcessor2;- return externalEntityInitProcessor2(parser, start, end, endPtr);-}--static enum XML_Error PTRCALL-externalEntityInitProcessor2(XML_Parser parser,- const char *start,- const char *end,- const char **endPtr)-{- const char *next = start; /* XmlContentTok doesn't always set the last arg */- int tok = XmlContentTok(encoding, start, end, &next);- switch (tok) {- case XML_TOK_BOM:- /* If we are at the end of the buffer, this would cause the next stage,- i.e. externalEntityInitProcessor3, to pass control directly to- doContent (by detecting XML_TOK_NONE) without processing any xml text- declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.- */- if (next == end && !ps_finalBuffer) {- *endPtr = next;- return XML_ERROR_NONE;- }- start = next;- break;- case XML_TOK_PARTIAL:- if (!ps_finalBuffer) {- *endPtr = start;- return XML_ERROR_NONE;- }- eventPtr = start;- return XML_ERROR_UNCLOSED_TOKEN;- case XML_TOK_PARTIAL_CHAR:- if (!ps_finalBuffer) {- *endPtr = start;- return XML_ERROR_NONE;- }- eventPtr = start;- return XML_ERROR_PARTIAL_CHAR;- }- processor = externalEntityInitProcessor3;- return externalEntityInitProcessor3(parser, start, end, endPtr);-}--static enum XML_Error PTRCALL-externalEntityInitProcessor3(XML_Parser parser,- const char *start,- const char *end,- const char **endPtr)-{- int tok;- const char *next = start; /* XmlContentTok doesn't always set the last arg */- eventPtr = start;- tok = XmlContentTok(encoding, start, end, &next);- eventEndPtr = next;-- switch (tok) {- case XML_TOK_XML_DECL:- {- enum XML_Error result;- result = processXmlDecl(parser, 1, start, next);- if (result != XML_ERROR_NONE)- return result;- switch (ps_parsing) {- case XML_SUSPENDED: - *endPtr = next;- return XML_ERROR_NONE;- case XML_FINISHED:- return XML_ERROR_ABORTED;- default:- start = next;- }- }- break;- case XML_TOK_PARTIAL:- if (!ps_finalBuffer) {- *endPtr = start;- return XML_ERROR_NONE;- }- return XML_ERROR_UNCLOSED_TOKEN;- case XML_TOK_PARTIAL_CHAR:- if (!ps_finalBuffer) {- *endPtr = start;- return XML_ERROR_NONE;- }- return XML_ERROR_PARTIAL_CHAR;- }- processor = externalEntityContentProcessor;- tagLevel = 1;- return externalEntityContentProcessor(parser, start, end, endPtr);-}--static enum XML_Error PTRCALL-externalEntityContentProcessor(XML_Parser parser,- const char *start,- const char *end,- const char **endPtr)-{- enum XML_Error result = doContent(parser, 1, encoding, start, end, - endPtr, (XML_Bool)!ps_finalBuffer);- if (result == XML_ERROR_NONE) {- if (!storeRawNames(parser))- return XML_ERROR_NO_MEMORY;- }- return result;-}--static enum XML_Error-doContent(XML_Parser parser,- int startTagLevel,- const ENCODING *enc,- const char *s,- const char *end,- const char **nextPtr,- XML_Bool haveMore)-{- /* save one level of indirection */- DTD * const dtd = _dtd; -- const char **eventPP;- const char **eventEndPP;- if (enc == encoding) {- eventPP = &eventPtr;- eventEndPP = &eventEndPtr;- }- else {- eventPP = &(openInternalEntities->internalEventPtr);- eventEndPP = &(openInternalEntities->internalEventEndPtr);- }- *eventPP = s;-- for (;;) {- const char *next = s; /* XmlContentTok doesn't always set the last arg */- int tok = XmlContentTok(enc, s, end, &next);- *eventEndPP = next;- switch (tok) {- case XML_TOK_TRAILING_CR:- if (haveMore) {- *nextPtr = s;- return XML_ERROR_NONE;- }- *eventEndPP = end;- if (characterDataHandler) {- XML_Char c = 0xA;- characterDataHandler(handlerArg, &c, 1);- }- else if (defaultHandler)- reportDefault(parser, enc, s, end);- /* We are at the end of the final buffer, should we check for - XML_SUSPENDED, XML_FINISHED? - */- if (startTagLevel == 0)- return XML_ERROR_NO_ELEMENTS;- if (tagLevel != startTagLevel)- return XML_ERROR_ASYNC_ENTITY;- *nextPtr = end;- return XML_ERROR_NONE;- case XML_TOK_NONE:- if (haveMore) {- *nextPtr = s;- return XML_ERROR_NONE;- }- if (startTagLevel > 0) {- if (tagLevel != startTagLevel)- return XML_ERROR_ASYNC_ENTITY;- *nextPtr = s;- return XML_ERROR_NONE;- }- return XML_ERROR_NO_ELEMENTS;- case XML_TOK_INVALID:- *eventPP = next;- return XML_ERROR_INVALID_TOKEN;- case XML_TOK_PARTIAL:- if (haveMore) {- *nextPtr = s;- return XML_ERROR_NONE;- }- return XML_ERROR_UNCLOSED_TOKEN;- case XML_TOK_PARTIAL_CHAR:- if (haveMore) {- *nextPtr = s;- return XML_ERROR_NONE;- }- return XML_ERROR_PARTIAL_CHAR;- case XML_TOK_ENTITY_REF:- {- const XML_Char *name;- ENTITY *entity;- XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,- s + enc->minBytesPerChar,- next - enc->minBytesPerChar);- if (ch) {- if (characterDataHandler)- characterDataHandler(handlerArg, &ch, 1);- else if (defaultHandler)- reportDefault(parser, enc, s, next);- break;- }- name = poolStoreString(&dtd->pool, enc,- s + enc->minBytesPerChar,- next - enc->minBytesPerChar);- if (!name)- return XML_ERROR_NO_MEMORY;- entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);- poolDiscard(&dtd->pool);- /* First, determine if a check for an existing declaration is needed;- if yes, check that the entity exists, and that it is internal,- otherwise call the skipped entity or default handler.- */- if (!dtd->hasParamEntityRefs || dtd->standalone) {- if (!entity)- return XML_ERROR_UNDEFINED_ENTITY;- else if (!entity->is_internal)- return XML_ERROR_ENTITY_DECLARED_IN_PE;- }- else if (!entity) {- if (skippedEntityHandler)- skippedEntityHandler(handlerArg, name, 0);- else if (defaultHandler)- reportDefault(parser, enc, s, next);- break;- }- if (entity->open)- return XML_ERROR_RECURSIVE_ENTITY_REF;- if (entity->notation)- return XML_ERROR_BINARY_ENTITY_REF;- if (entity->textPtr) {- enum XML_Error result;- if (!defaultExpandInternalEntities) {- if (skippedEntityHandler)- skippedEntityHandler(handlerArg, entity->name, 0);- else if (defaultHandler)- reportDefault(parser, enc, s, next);- break;- }- result = processInternalEntity(parser, entity, XML_FALSE);- if (result != XML_ERROR_NONE)- return result;- }- else if (externalEntityRefHandler) {- const XML_Char *context;- entity->open = XML_TRUE;- context = getContext(parser);- entity->open = XML_FALSE;- if (!context)- return XML_ERROR_NO_MEMORY;- if (!externalEntityRefHandler(externalEntityRefHandlerArg,- context,- entity->base,- entity->systemId,- entity->publicId))- return XML_ERROR_EXTERNAL_ENTITY_HANDLING;- poolDiscard(&tempPool);- }- else if (defaultHandler)- reportDefault(parser, enc, s, next);- break;- }- case XML_TOK_START_TAG_NO_ATTS:- /* fall through */- case XML_TOK_START_TAG_WITH_ATTS:- {- TAG *tag;- enum XML_Error result;- XML_Char *toPtr;- if (freeTagList) {- tag = freeTagList;- freeTagList = freeTagList->parent;- }- else {- tag = (TAG *)MALLOC(sizeof(TAG));- if (!tag)- return XML_ERROR_NO_MEMORY;- tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);- if (!tag->buf) {- FREE(tag);- return XML_ERROR_NO_MEMORY;- }- tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;- }- tag->bindings = NULL;- tag->parent = tagStack;- tagStack = tag;- tag->name.localPart = NULL;- tag->name.prefix = NULL;- tag->rawName = s + enc->minBytesPerChar;- tag->rawNameLength = XmlNameLength(enc, tag->rawName);- ++tagLevel;- {- const char *rawNameEnd = tag->rawName + tag->rawNameLength;- const char *fromPtr = tag->rawName;- toPtr = (XML_Char *)tag->buf;- for (;;) {- int bufSize;- int convLen;- XmlConvert(enc,- &fromPtr, rawNameEnd,- (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);- convLen = (int)(toPtr - (XML_Char *)tag->buf);- if (fromPtr == rawNameEnd) {- tag->name.strLen = convLen;- break;- }- bufSize = (int)(tag->bufEnd - tag->buf) << 1;- {- char *temp = (char *)REALLOC(tag->buf, bufSize);- if (temp == NULL)- return XML_ERROR_NO_MEMORY;- tag->buf = temp;- tag->bufEnd = temp + bufSize;- toPtr = (XML_Char *)temp + convLen;- }- }- }- tag->name.str = (XML_Char *)tag->buf;- *toPtr = XML_T('\0');- result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));- if (result)- return result;- if (startElementHandler)- startElementHandler(handlerArg, tag->name.str,- (const XML_Char **)atts);- else if (defaultHandler)- reportDefault(parser, enc, s, next);- poolClear(&tempPool);- break;- }- case XML_TOK_EMPTY_ELEMENT_NO_ATTS:- /* fall through */- case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:- {- const char *rawName = s + enc->minBytesPerChar;- enum XML_Error result;- BINDING *bindings = NULL;- XML_Bool noElmHandlers = XML_TRUE;- TAG_NAME name;- name.str = poolStoreString(&tempPool, enc, rawName,- rawName + XmlNameLength(enc, rawName));- if (!name.str)- return XML_ERROR_NO_MEMORY;- poolFinish(&tempPool);- result = storeAtts(parser, enc, s, &name, &bindings);- if (result)- return result;- poolFinish(&tempPool);- if (startElementHandler) {- startElementHandler(handlerArg, name.str, (const XML_Char **)atts);- noElmHandlers = XML_FALSE;- }- if (endElementHandler) {- if (startElementHandler)- *eventPP = *eventEndPP;- endElementHandler(handlerArg, name.str);- noElmHandlers = XML_FALSE;- }- if (noElmHandlers && defaultHandler)- reportDefault(parser, enc, s, next);- poolClear(&tempPool);- while (bindings) {- BINDING *b = bindings;- if (endNamespaceDeclHandler)- endNamespaceDeclHandler(handlerArg, b->prefix->name);- bindings = bindings->nextTagBinding;- b->nextTagBinding = freeBindingList;- freeBindingList = b;- b->prefix->binding = b->prevPrefixBinding;- }- }- if (tagLevel == 0)- return epilogProcessor(parser, next, end, nextPtr);- break;- case XML_TOK_END_TAG:- if (tagLevel == startTagLevel)- return XML_ERROR_ASYNC_ENTITY;- else {- int len;- const char *rawName;- TAG *tag = tagStack;- tagStack = tag->parent;- tag->parent = freeTagList;- freeTagList = tag;- rawName = s + enc->minBytesPerChar*2;- len = XmlNameLength(enc, rawName);- if (len != tag->rawNameLength- || memcmp(tag->rawName, rawName, len) != 0) {- *eventPP = rawName;- return XML_ERROR_TAG_MISMATCH;- }- --tagLevel;- if (endElementHandler) {- const XML_Char *localPart;- const XML_Char *prefix;- XML_Char *uri;- localPart = tag->name.localPart;- if (ns && localPart) {- /* localPart and prefix may have been overwritten in- tag->name.str, since this points to the binding->uri- buffer which gets re-used; so we have to add them again- */- uri = (XML_Char *)tag->name.str + tag->name.uriLen;- /* don't need to check for space - already done in storeAtts() */- while (*localPart) *uri++ = *localPart++;- prefix = (XML_Char *)tag->name.prefix;- if (ns_triplets && prefix) {- *uri++ = namespaceSeparator;- while (*prefix) *uri++ = *prefix++;- }- *uri = XML_T('\0');- }- endElementHandler(handlerArg, tag->name.str);- }- else if (defaultHandler)- reportDefault(parser, enc, s, next);- while (tag->bindings) {- BINDING *b = tag->bindings;- if (endNamespaceDeclHandler)- endNamespaceDeclHandler(handlerArg, b->prefix->name);- tag->bindings = tag->bindings->nextTagBinding;- b->nextTagBinding = freeBindingList;- freeBindingList = b;- b->prefix->binding = b->prevPrefixBinding;- }- if (tagLevel == 0)- return epilogProcessor(parser, next, end, nextPtr);- }- break;- case XML_TOK_CHAR_REF:- {- int n = XmlCharRefNumber(enc, s);- if (n < 0)- return XML_ERROR_BAD_CHAR_REF;- if (characterDataHandler) {- XML_Char buf[XML_ENCODE_MAX];- characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));- }- else if (defaultHandler)- reportDefault(parser, enc, s, next);- }- break;- case XML_TOK_XML_DECL:- return XML_ERROR_MISPLACED_XML_PI;- case XML_TOK_DATA_NEWLINE:- if (characterDataHandler) {- XML_Char c = 0xA;- characterDataHandler(handlerArg, &c, 1);- }- else if (defaultHandler)- reportDefault(parser, enc, s, next);- break;- case XML_TOK_CDATA_SECT_OPEN:- {- enum XML_Error result;- if (startCdataSectionHandler)- startCdataSectionHandler(handlerArg);-#if 0- /* Suppose you doing a transformation on a document that involves- changing only the character data. You set up a defaultHandler- and a characterDataHandler. The defaultHandler simply copies- characters through. The characterDataHandler does the- transformation and writes the characters out escaping them as- necessary. This case will fail to work if we leave out the- following two lines (because & and < inside CDATA sections will- be incorrectly escaped).-- However, now we have a start/endCdataSectionHandler, so it seems- easier to let the user deal with this.- */- else if (characterDataHandler)- characterDataHandler(handlerArg, dataBuf, 0);-#endif- else if (defaultHandler)- reportDefault(parser, enc, s, next);- result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);- if (result != XML_ERROR_NONE)- return result;- else if (!next) {- processor = cdataSectionProcessor;- return result;- }- }- break;- case XML_TOK_TRAILING_RSQB:- if (haveMore) {- *nextPtr = s;- return XML_ERROR_NONE;- }- if (characterDataHandler) {- if (MUST_CONVERT(enc, s)) {- ICHAR *dataPtr = (ICHAR *)dataBuf;- XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);- characterDataHandler(handlerArg, dataBuf,- (int)(dataPtr - (ICHAR *)dataBuf));- }- else- characterDataHandler(handlerArg,- (XML_Char *)s,- (int)((XML_Char *)end - (XML_Char *)s));- }- else if (defaultHandler)- reportDefault(parser, enc, s, end);- /* We are at the end of the final buffer, should we check for - XML_SUSPENDED, XML_FINISHED? - */- if (startTagLevel == 0) {- *eventPP = end;- return XML_ERROR_NO_ELEMENTS;- }- if (tagLevel != startTagLevel) {- *eventPP = end;- return XML_ERROR_ASYNC_ENTITY;- }- *nextPtr = end;- return XML_ERROR_NONE;- case XML_TOK_DATA_CHARS: - {- XML_CharacterDataHandler charDataHandler = characterDataHandler;- if (charDataHandler) {- if (MUST_CONVERT(enc, s)) {- for (;;) {- ICHAR *dataPtr = (ICHAR *)dataBuf;- XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);- *eventEndPP = s;- charDataHandler(handlerArg, dataBuf,- (int)(dataPtr - (ICHAR *)dataBuf));- if (s == next)- break;- *eventPP = s;- }- }- else- charDataHandler(handlerArg,- (XML_Char *)s,- (int)((XML_Char *)next - (XML_Char *)s));- }- else if (defaultHandler)- reportDefault(parser, enc, s, next);- }- break;- case XML_TOK_PI:- if (!reportProcessingInstruction(parser, enc, s, next))- return XML_ERROR_NO_MEMORY;- break;- case XML_TOK_COMMENT:- if (!reportComment(parser, enc, s, next))- return XML_ERROR_NO_MEMORY;- break;- default:- if (defaultHandler)- reportDefault(parser, enc, s, next);- break;- }- *eventPP = s = next;- switch (ps_parsing) {- case XML_SUSPENDED: - *nextPtr = next;- return XML_ERROR_NONE;- case XML_FINISHED:- return XML_ERROR_ABORTED;- default: ;- }- }- /* not reached */-}--/* Precondition: all arguments must be non-NULL;- Purpose:- - normalize attributes- - check attributes for well-formedness- - generate namespace aware attribute names (URI, prefix)- - build list of attributes for startElementHandler- - default attributes- - process namespace declarations (check and report them)- - generate namespace aware element name (URI, prefix)-*/-static enum XML_Error-storeAtts(XML_Parser parser, const ENCODING *enc,- const char *attStr, TAG_NAME *tagNamePtr,- BINDING **bindingsPtr)-{- DTD * const dtd = _dtd; /* save one level of indirection */- ELEMENT_TYPE *elementType;- int nDefaultAtts;- const XML_Char **appAtts; /* the attribute list for the application */- int attIndex = 0;- int prefixLen;- int i;- int n;- XML_Char *uri;- int nPrefixes = 0;- BINDING *binding;- const XML_Char *localPart;-- /* lookup the element type name */- elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, tagNamePtr->str,0);- if (!elementType) {- const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);- if (!name)- return XML_ERROR_NO_MEMORY;- elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, name,- sizeof(ELEMENT_TYPE));- if (!elementType)- return XML_ERROR_NO_MEMORY;- if (ns && !setElementTypePrefix(parser, elementType))- return XML_ERROR_NO_MEMORY;- }- nDefaultAtts = elementType->nDefaultAtts;-- /* get the attributes from the tokenizer */- n = XmlGetAttributes(enc, attStr, attsSize, atts);- if (n + nDefaultAtts > attsSize) {- int oldAttsSize = attsSize;- ATTRIBUTE *temp;- attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;- temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));- if (temp == NULL)- return XML_ERROR_NO_MEMORY;- atts = temp;- if (n > oldAttsSize)- XmlGetAttributes(enc, attStr, n, atts);- }-- appAtts = (const XML_Char **)atts;- for (i = 0; i < n; i++) {- /* add the name and value to the attribute list */- ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,- atts[i].name- + XmlNameLength(enc, atts[i].name));- if (!attId)- return XML_ERROR_NO_MEMORY;- /* Detect duplicate attributes by their QNames. This does not work when- namespace processing is turned on and different prefixes for the same- namespace are used. For this case we have a check further down.- */- if ((attId->name)[-1]) {- if (enc == encoding)- eventPtr = atts[i].name;- return XML_ERROR_DUPLICATE_ATTRIBUTE;- }- (attId->name)[-1] = 1;- appAtts[attIndex++] = attId->name;- if (!atts[i].normalized) {- enum XML_Error result;- XML_Bool isCdata = XML_TRUE;-- /* figure out whether declared as other than CDATA */- if (attId->maybeTokenized) {- int j;- for (j = 0; j < nDefaultAtts; j++) {- if (attId == elementType->defaultAtts[j].id) {- isCdata = elementType->defaultAtts[j].isCdata;- break;- }- }- }-- /* normalize the attribute value */- result = storeAttributeValue(parser, enc, isCdata,- atts[i].valuePtr, atts[i].valueEnd,- &tempPool);- if (result)- return result;- appAtts[attIndex] = poolStart(&tempPool);- poolFinish(&tempPool);- }- else {- /* the value did not need normalizing */- appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,- atts[i].valueEnd);- if (appAtts[attIndex] == 0)- return XML_ERROR_NO_MEMORY;- poolFinish(&tempPool);- }- /* handle prefixed attribute names */- if (attId->prefix) {- if (attId->xmlns) {- /* deal with namespace declarations here */- enum XML_Error result = addBinding(parser, attId->prefix, attId,- appAtts[attIndex], bindingsPtr);- if (result)- return result;- --attIndex;- }- else {- /* deal with other prefixed names later */- attIndex++;- nPrefixes++;- (attId->name)[-1] = 2;- }- }- else- attIndex++;- }-- /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */- nSpecifiedAtts = attIndex;- if (elementType->idAtt && (elementType->idAtt->name)[-1]) {- for (i = 0; i < attIndex; i += 2)- if (appAtts[i] == elementType->idAtt->name) {- idAttIndex = i;- break;- }- }- else- idAttIndex = -1;-- /* do attribute defaulting */- for (i = 0; i < nDefaultAtts; i++) {- const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;- if (!(da->id->name)[-1] && da->value) {- if (da->id->prefix) {- if (da->id->xmlns) {- enum XML_Error result = addBinding(parser, da->id->prefix, da->id,- da->value, bindingsPtr);- if (result)- return result;- }- else {- (da->id->name)[-1] = 2;- nPrefixes++;- appAtts[attIndex++] = da->id->name;- appAtts[attIndex++] = da->value;- }- }- else {- (da->id->name)[-1] = 1;- appAtts[attIndex++] = da->id->name;- appAtts[attIndex++] = da->value;- }- }- }- appAtts[attIndex] = 0;-- /* expand prefixed attribute names, check for duplicates,- and clear flags that say whether attributes were specified */- i = 0;- if (nPrefixes) {- int j; /* hash table index */- unsigned long version = nsAttsVersion;- int nsAttsSize = (int)1 << nsAttsPower;- /* size of hash table must be at least 2 * (# of prefixed attributes) */- if ((nPrefixes << 1) >> nsAttsPower) { /* true for nsAttsPower = 0 */- NS_ATT *temp;- /* hash table size must also be a power of 2 and >= 8 */- while (nPrefixes >> nsAttsPower++);- if (nsAttsPower < 3)- nsAttsPower = 3;- nsAttsSize = (int)1 << nsAttsPower;- temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));- if (!temp)- return XML_ERROR_NO_MEMORY;- nsAtts = temp;- version = 0; /* force re-initialization of nsAtts hash table */- }- /* using a version flag saves us from initializing nsAtts every time */- if (!version) { /* initialize version flags when version wraps around */- version = INIT_ATTS_VERSION;- for (j = nsAttsSize; j != 0; )- nsAtts[--j].version = version;- }- nsAttsVersion = --version;-- /* expand prefixed names and check for duplicates */- for (; i < attIndex; i += 2) {- const XML_Char *s = appAtts[i];- if (s[-1] == 2) { /* prefixed */- ATTRIBUTE_ID *id;- const BINDING *b;- unsigned long uriHash = 0;- ((XML_Char *)s)[-1] = 0; /* clear flag */- id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, s, 0);- b = id->prefix->binding;- if (!b)- return XML_ERROR_UNBOUND_PREFIX;-- /* as we expand the name we also calculate its hash value */- for (j = 0; j < b->uriLen; j++) {- const XML_Char c = b->uri[j];- if (!poolAppendChar(&tempPool, c))- return XML_ERROR_NO_MEMORY;- uriHash = CHAR_HASH(uriHash, c);- }- while (*s++ != XML_T(ASCII_COLON))- ;- do { /* copies null terminator */- const XML_Char c = *s;- if (!poolAppendChar(&tempPool, *s))- return XML_ERROR_NO_MEMORY;- uriHash = CHAR_HASH(uriHash, c);- } while (*s++);-- { /* Check hash table for duplicate of expanded name (uriName).- Derived from code in lookup(HASH_TABLE *table, ...).- */- unsigned char step = 0;- unsigned long mask = nsAttsSize - 1;- j = uriHash & mask; /* index into hash table */- while (nsAtts[j].version == version) {- /* for speed we compare stored hash values first */- if (uriHash == nsAtts[j].hash) {- const XML_Char *s1 = poolStart(&tempPool);- const XML_Char *s2 = nsAtts[j].uriName;- /* s1 is null terminated, but not s2 */- for (; *s1 == *s2 && *s1 != 0; s1++, s2++);- if (*s1 == 0)- return XML_ERROR_DUPLICATE_ATTRIBUTE;- }- if (!step)- step = PROBE_STEP(uriHash, mask, nsAttsPower);- j < step ? (j += nsAttsSize - step) : (j -= step);- }- }-- if (ns_triplets) { /* append namespace separator and prefix */- tempPool.ptr[-1] = namespaceSeparator;- s = b->prefix->name;- do {- if (!poolAppendChar(&tempPool, *s))- return XML_ERROR_NO_MEMORY;- } while (*s++);- }-- /* store expanded name in attribute list */- s = poolStart(&tempPool);- poolFinish(&tempPool);- appAtts[i] = s;-- /* fill empty slot with new version, uriName and hash value */- nsAtts[j].version = version;- nsAtts[j].hash = uriHash;- nsAtts[j].uriName = s;-- if (!--nPrefixes) {- i += 2;- break;- }- }- else /* not prefixed */- ((XML_Char *)s)[-1] = 0; /* clear flag */- }- }- /* clear flags for the remaining attributes */- for (; i < attIndex; i += 2)- ((XML_Char *)(appAtts[i]))[-1] = 0;- for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)- binding->attId->name[-1] = 0;-- if (!ns)- return XML_ERROR_NONE;-- /* expand the element type name */- if (elementType->prefix) {- binding = elementType->prefix->binding;- if (!binding)- return XML_ERROR_UNBOUND_PREFIX;- localPart = tagNamePtr->str;- while (*localPart++ != XML_T(ASCII_COLON))- ;- }- else if (dtd->defaultPrefix.binding) {- binding = dtd->defaultPrefix.binding;- localPart = tagNamePtr->str;- }- else- return XML_ERROR_NONE;- prefixLen = 0;- if (ns_triplets && binding->prefix->name) {- for (; binding->prefix->name[prefixLen++];)- ; /* prefixLen includes null terminator */- }- tagNamePtr->localPart = localPart;- tagNamePtr->uriLen = binding->uriLen;- tagNamePtr->prefix = binding->prefix->name;- tagNamePtr->prefixLen = prefixLen;- for (i = 0; localPart[i++];)- ; /* i includes null terminator */- n = i + binding->uriLen + prefixLen;- if (n > binding->uriAlloc) {- TAG *p;- uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));- if (!uri)- return XML_ERROR_NO_MEMORY;- binding->uriAlloc = n + EXPAND_SPARE;- memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));- for (p = tagStack; p; p = p->parent)- if (p->name.str == binding->uri)- p->name.str = uri;- FREE(binding->uri);- binding->uri = uri;- }- /* if namespaceSeparator != '\0' then uri includes it already */- uri = binding->uri + binding->uriLen;- memcpy(uri, localPart, i * sizeof(XML_Char));- /* we always have a namespace separator between localPart and prefix */- if (prefixLen) {- uri += i - 1;- *uri = namespaceSeparator; /* replace null terminator */- memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));- }- tagNamePtr->str = binding->uri;- return XML_ERROR_NONE;-}--/* addBinding() overwrites the value of prefix->binding without checking.- Therefore one must keep track of the old value outside of addBinding().-*/-static enum XML_Error-addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,- const XML_Char *uri, BINDING **bindingsPtr)-{- static const XML_Char xmlNamespace[] = {- ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,- ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,- ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, - ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH,- ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c,- ASCII_e, '\0'- };- static const int xmlLen = - (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;- static const XML_Char xmlnsNamespace[] = {- ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,- ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,- ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0, - ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s, - ASCII_SLASH, '\0'- };- static const int xmlnsLen = - (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;-- XML_Bool mustBeXML = XML_FALSE;- XML_Bool isXML = XML_TRUE;- XML_Bool isXMLNS = XML_TRUE;- - BINDING *b;- int len;-- /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */- if (*uri == XML_T('\0') && prefix->name)- return XML_ERROR_UNDECLARING_PREFIX;-- if (prefix->name- && prefix->name[0] == XML_T(ASCII_x)- && prefix->name[1] == XML_T(ASCII_m)- && prefix->name[2] == XML_T(ASCII_l)) {-- /* Not allowed to bind xmlns */- if (prefix->name[3] == XML_T(ASCII_n)- && prefix->name[4] == XML_T(ASCII_s)- && prefix->name[5] == XML_T('\0'))- return XML_ERROR_RESERVED_PREFIX_XMLNS;-- if (prefix->name[3] == XML_T('\0'))- mustBeXML = XML_TRUE;- }-- for (len = 0; uri[len]; len++) {- if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))- isXML = XML_FALSE;-- if (!mustBeXML && isXMLNS - && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))- isXMLNS = XML_FALSE;- }- isXML = isXML && len == xmlLen;- isXMLNS = isXMLNS && len == xmlnsLen;-- if (mustBeXML != isXML)- return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML- : XML_ERROR_RESERVED_NAMESPACE_URI;-- if (isXMLNS)- return XML_ERROR_RESERVED_NAMESPACE_URI;-- if (namespaceSeparator)- len++;- if (freeBindingList) {- b = freeBindingList;- if (len > b->uriAlloc) {- XML_Char *temp = (XML_Char *)REALLOC(b->uri,- sizeof(XML_Char) * (len + EXPAND_SPARE));- if (temp == NULL)- return XML_ERROR_NO_MEMORY;- b->uri = temp;- b->uriAlloc = len + EXPAND_SPARE;- }- freeBindingList = b->nextTagBinding;- }- else {- b = (BINDING *)MALLOC(sizeof(BINDING));- if (!b)- return XML_ERROR_NO_MEMORY;- b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));- if (!b->uri) {- FREE(b);- return XML_ERROR_NO_MEMORY;- }- b->uriAlloc = len + EXPAND_SPARE;- }- b->uriLen = len;- memcpy(b->uri, uri, len * sizeof(XML_Char));- if (namespaceSeparator)- b->uri[len - 1] = namespaceSeparator;- b->prefix = prefix;- b->attId = attId;- b->prevPrefixBinding = prefix->binding;- /* NULL binding when default namespace undeclared */- if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)- prefix->binding = NULL;- else- prefix->binding = b;- b->nextTagBinding = *bindingsPtr;- *bindingsPtr = b;- /* if attId == NULL then we are not starting a namespace scope */- if (attId && startNamespaceDeclHandler)- startNamespaceDeclHandler(handlerArg, prefix->name,- prefix->binding ? uri : 0);- return XML_ERROR_NONE;-}--/* The idea here is to avoid using stack for each CDATA section when- the whole file is parsed with one call.-*/-static enum XML_Error PTRCALL-cdataSectionProcessor(XML_Parser parser,- const char *start,- const char *end,- const char **endPtr)-{- enum XML_Error result = doCdataSection(parser, encoding, &start, end,- endPtr, (XML_Bool)!ps_finalBuffer);- if (result != XML_ERROR_NONE)- return result;- if (start) {- if (parentParser) { /* we are parsing an external entity */- processor = externalEntityContentProcessor;- return externalEntityContentProcessor(parser, start, end, endPtr);- }- else {- processor = contentProcessor;- return contentProcessor(parser, start, end, endPtr);- }- }- return result;-}--/* startPtr gets set to non-null if the section is closed, and to null if- the section is not yet closed.-*/-static enum XML_Error-doCdataSection(XML_Parser parser,- const ENCODING *enc,- const char **startPtr,- const char *end,- const char **nextPtr,- XML_Bool haveMore)-{- const char *s = *startPtr;- const char **eventPP;- const char **eventEndPP;- if (enc == encoding) {- eventPP = &eventPtr;- *eventPP = s;- eventEndPP = &eventEndPtr;- }- else {- eventPP = &(openInternalEntities->internalEventPtr);- eventEndPP = &(openInternalEntities->internalEventEndPtr);- }- *eventPP = s;- *startPtr = NULL;-- for (;;) {- const char *next;- int tok = XmlCdataSectionTok(enc, s, end, &next);- *eventEndPP = next;- switch (tok) {- case XML_TOK_CDATA_SECT_CLOSE:- if (endCdataSectionHandler)- endCdataSectionHandler(handlerArg);-#if 0- /* see comment under XML_TOK_CDATA_SECT_OPEN */- else if (characterDataHandler)- characterDataHandler(handlerArg, dataBuf, 0);-#endif- else if (defaultHandler)- reportDefault(parser, enc, s, next);- *startPtr = next;- *nextPtr = next;- if (ps_parsing == XML_FINISHED)- return XML_ERROR_ABORTED;- else- return XML_ERROR_NONE;- case XML_TOK_DATA_NEWLINE:- if (characterDataHandler) {- XML_Char c = 0xA;- characterDataHandler(handlerArg, &c, 1);- }- else if (defaultHandler)- reportDefault(parser, enc, s, next);- break;- case XML_TOK_DATA_CHARS:- {- XML_CharacterDataHandler charDataHandler = characterDataHandler;- if (charDataHandler) {- if (MUST_CONVERT(enc, s)) {- for (;;) {- ICHAR *dataPtr = (ICHAR *)dataBuf;- XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);- *eventEndPP = next;- charDataHandler(handlerArg, dataBuf,- (int)(dataPtr - (ICHAR *)dataBuf));- if (s == next)- break;- *eventPP = s;- }- }- else- charDataHandler(handlerArg,- (XML_Char *)s,- (int)((XML_Char *)next - (XML_Char *)s));- }- else if (defaultHandler)- reportDefault(parser, enc, s, next);- }- break;- case XML_TOK_INVALID:- *eventPP = next;- return XML_ERROR_INVALID_TOKEN;- case XML_TOK_PARTIAL_CHAR:- if (haveMore) {- *nextPtr = s;- return XML_ERROR_NONE;- }- return XML_ERROR_PARTIAL_CHAR;- case XML_TOK_PARTIAL:- case XML_TOK_NONE:- if (haveMore) {- *nextPtr = s;- return XML_ERROR_NONE;- }- return XML_ERROR_UNCLOSED_CDATA_SECTION;- default:- *eventPP = next;- return XML_ERROR_UNEXPECTED_STATE;- }-- *eventPP = s = next;- switch (ps_parsing) {- case XML_SUSPENDED:- *nextPtr = next;- return XML_ERROR_NONE;- case XML_FINISHED:- return XML_ERROR_ABORTED;- default: ;- }- }- /* not reached */-}--#ifdef XML_DTD--/* The idea here is to avoid using stack for each IGNORE section when- the whole file is parsed with one call.-*/-static enum XML_Error PTRCALL-ignoreSectionProcessor(XML_Parser parser,- const char *start,- const char *end,- const char **endPtr)-{- enum XML_Error result = doIgnoreSection(parser, encoding, &start, end, - endPtr, (XML_Bool)!ps_finalBuffer);- if (result != XML_ERROR_NONE)- return result;- if (start) {- processor = prologProcessor;- return prologProcessor(parser, start, end, endPtr);- }- return result;-}--/* startPtr gets set to non-null is the section is closed, and to null- if the section is not yet closed.-*/-static enum XML_Error-doIgnoreSection(XML_Parser parser,- const ENCODING *enc,- const char **startPtr,- const char *end,- const char **nextPtr,- XML_Bool haveMore)-{- const char *next;- int tok;- const char *s = *startPtr;- const char **eventPP;- const char **eventEndPP;- if (enc == encoding) {- eventPP = &eventPtr;- *eventPP = s;- eventEndPP = &eventEndPtr;- }- else {- eventPP = &(openInternalEntities->internalEventPtr);- eventEndPP = &(openInternalEntities->internalEventEndPtr);- }- *eventPP = s;- *startPtr = NULL;- tok = XmlIgnoreSectionTok(enc, s, end, &next);- *eventEndPP = next;- switch (tok) {- case XML_TOK_IGNORE_SECT:- if (defaultHandler)- reportDefault(parser, enc, s, next);- *startPtr = next;- *nextPtr = next;- if (ps_parsing == XML_FINISHED)- return XML_ERROR_ABORTED;- else- return XML_ERROR_NONE;- case XML_TOK_INVALID:- *eventPP = next;- return XML_ERROR_INVALID_TOKEN;- case XML_TOK_PARTIAL_CHAR:- if (haveMore) {- *nextPtr = s;- return XML_ERROR_NONE;- }- return XML_ERROR_PARTIAL_CHAR;- case XML_TOK_PARTIAL:- case XML_TOK_NONE:- if (haveMore) {- *nextPtr = s;- return XML_ERROR_NONE;- }- return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */- default:- *eventPP = next;- return XML_ERROR_UNEXPECTED_STATE;- }- /* not reached */-}--#endif /* XML_DTD */--static enum XML_Error-initializeEncoding(XML_Parser parser)-{- const char *s;-#ifdef XML_UNICODE- char encodingBuf[128];- if (!protocolEncodingName)- s = NULL;- else {- int i;- for (i = 0; protocolEncodingName[i]; i++) {- if (i == sizeof(encodingBuf) - 1- || (protocolEncodingName[i] & ~0x7f) != 0) {- encodingBuf[0] = '\0';- break;- }- encodingBuf[i] = (char)protocolEncodingName[i];- }- encodingBuf[i] = '\0';- s = encodingBuf;- }-#else- s = protocolEncodingName;-#endif- if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))- return XML_ERROR_NONE;- return handleUnknownEncoding(parser, protocolEncodingName);-}--static enum XML_Error-processXmlDecl(XML_Parser parser, int isGeneralTextEntity,- const char *s, const char *next)-{- const char *encodingName = NULL;- const XML_Char *storedEncName = NULL;- const ENCODING *newEncoding = NULL;- const char *version = NULL;- const char *versionend;- const XML_Char *storedversion = NULL;- int standalone = -1;- if (!(ns- ? XmlParseXmlDeclNS- : XmlParseXmlDecl)(isGeneralTextEntity,- encoding,- s,- next,- &eventPtr,- &version,- &versionend,- &encodingName,- &newEncoding,- &standalone)) {- if (isGeneralTextEntity)- return XML_ERROR_TEXT_DECL;- else- return XML_ERROR_XML_DECL;- }- if (!isGeneralTextEntity && standalone == 1) {- _dtd->standalone = XML_TRUE;-#ifdef XML_DTD- if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)- paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;-#endif /* XML_DTD */- }- if (xmlDeclHandler) {- if (encodingName != NULL) {- storedEncName = poolStoreString(&temp2Pool,- encoding,- encodingName,- encodingName- + XmlNameLength(encoding, encodingName));- if (!storedEncName)- return XML_ERROR_NO_MEMORY;- poolFinish(&temp2Pool);- }- if (version) {- storedversion = poolStoreString(&temp2Pool,- encoding,- version,- versionend - encoding->minBytesPerChar);- if (!storedversion)- return XML_ERROR_NO_MEMORY;- }- xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);- }- else if (defaultHandler)- reportDefault(parser, encoding, s, next);- if (protocolEncodingName == NULL) {- if (newEncoding) {- if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {- eventPtr = encodingName;- return XML_ERROR_INCORRECT_ENCODING;- }- encoding = newEncoding;- }- else if (encodingName) {- enum XML_Error result;- if (!storedEncName) {- storedEncName = poolStoreString(- &temp2Pool, encoding, encodingName,- encodingName + XmlNameLength(encoding, encodingName));- if (!storedEncName)- return XML_ERROR_NO_MEMORY;- }- result = handleUnknownEncoding(parser, storedEncName);- poolClear(&temp2Pool);- if (result == XML_ERROR_UNKNOWN_ENCODING)- eventPtr = encodingName;- return result;- }- }-- if (storedEncName || storedversion)- poolClear(&temp2Pool);-- return XML_ERROR_NONE;-}--static enum XML_Error-handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)-{- if (unknownEncodingHandler) {- XML_Encoding info;- int i;- for (i = 0; i < 256; i++)- info.map[i] = -1;- info.convert = NULL;- info.data = NULL;- info.release = NULL;- if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,- &info)) {- ENCODING *enc;- unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());- if (!unknownEncodingMem) {- if (info.release)- info.release(info.data);- return XML_ERROR_NO_MEMORY;- }- enc = (ns- ? XmlInitUnknownEncodingNS- : XmlInitUnknownEncoding)(unknownEncodingMem,- info.map,- info.convert,- info.data);- if (enc) {- unknownEncodingData = info.data;- unknownEncodingRelease = info.release;- encoding = enc;- return XML_ERROR_NONE;- }- }- if (info.release != NULL)- info.release(info.data);- }- return XML_ERROR_UNKNOWN_ENCODING;-}--static enum XML_Error PTRCALL-prologInitProcessor(XML_Parser parser,- const char *s,- const char *end,- const char **nextPtr)-{- enum XML_Error result = initializeEncoding(parser);- if (result != XML_ERROR_NONE)- return result;- processor = prologProcessor;- return prologProcessor(parser, s, end, nextPtr);-}--#ifdef XML_DTD--static enum XML_Error PTRCALL-externalParEntInitProcessor(XML_Parser parser,- const char *s,- const char *end,- const char **nextPtr)-{- enum XML_Error result = initializeEncoding(parser);- if (result != XML_ERROR_NONE)- return result;-- /* we know now that XML_Parse(Buffer) has been called,- so we consider the external parameter entity read */- _dtd->paramEntityRead = XML_TRUE;-- if (prologState.inEntityValue) {- processor = entityValueInitProcessor;- return entityValueInitProcessor(parser, s, end, nextPtr);- }- else {- processor = externalParEntProcessor;- return externalParEntProcessor(parser, s, end, nextPtr);- }-}--static enum XML_Error PTRCALL-entityValueInitProcessor(XML_Parser parser,- const char *s,- const char *end,- const char **nextPtr)-{- int tok;- const char *start = s;- const char *next = start;- eventPtr = start;-- for (;;) { - tok = XmlPrologTok(encoding, start, end, &next);- eventEndPtr = next;- if (tok <= 0) {- if (!ps_finalBuffer && tok != XML_TOK_INVALID) {- *nextPtr = s;- return XML_ERROR_NONE;- }- switch (tok) {- case XML_TOK_INVALID:- return XML_ERROR_INVALID_TOKEN;- case XML_TOK_PARTIAL:- return XML_ERROR_UNCLOSED_TOKEN;- case XML_TOK_PARTIAL_CHAR:- return XML_ERROR_PARTIAL_CHAR;- case XML_TOK_NONE: /* start == end */- default:- break;- }- /* found end of entity value - can store it now */- return storeEntityValue(parser, encoding, s, end);- }- else if (tok == XML_TOK_XML_DECL) {- enum XML_Error result;- result = processXmlDecl(parser, 0, start, next);- if (result != XML_ERROR_NONE)- return result;- switch (ps_parsing) {- case XML_SUSPENDED: - *nextPtr = next;- return XML_ERROR_NONE;- case XML_FINISHED:- return XML_ERROR_ABORTED;- default:- *nextPtr = next;- }- /* stop scanning for text declaration - we found one */- processor = entityValueProcessor;- return entityValueProcessor(parser, next, end, nextPtr);- }- /* If we are at the end of the buffer, this would cause XmlPrologTok to- return XML_TOK_NONE on the next call, which would then cause the- function to exit with *nextPtr set to s - that is what we want for other- tokens, but not for the BOM - we would rather like to skip it;- then, when this routine is entered the next time, XmlPrologTok will- return XML_TOK_INVALID, since the BOM is still in the buffer- */- else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {- *nextPtr = next;- return XML_ERROR_NONE;- }- start = next;- eventPtr = start;- }-}--static enum XML_Error PTRCALL-externalParEntProcessor(XML_Parser parser,- const char *s,- const char *end,- const char **nextPtr)-{- const char *next = s;- int tok;-- tok = XmlPrologTok(encoding, s, end, &next);- if (tok <= 0) {- if (!ps_finalBuffer && tok != XML_TOK_INVALID) {- *nextPtr = s;- return XML_ERROR_NONE;- }- switch (tok) {- case XML_TOK_INVALID:- return XML_ERROR_INVALID_TOKEN;- case XML_TOK_PARTIAL:- return XML_ERROR_UNCLOSED_TOKEN;- case XML_TOK_PARTIAL_CHAR:- return XML_ERROR_PARTIAL_CHAR;- case XML_TOK_NONE: /* start == end */- default:- break;- }- }- /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.- However, when parsing an external subset, doProlog will not accept a BOM- as valid, and report a syntax error, so we have to skip the BOM- */- else if (tok == XML_TOK_BOM) {- s = next;- tok = XmlPrologTok(encoding, s, end, &next);- }-- processor = prologProcessor;- return doProlog(parser, encoding, s, end, tok, next, - nextPtr, (XML_Bool)!ps_finalBuffer);-}--static enum XML_Error PTRCALL-entityValueProcessor(XML_Parser parser,- const char *s,- const char *end,- const char **nextPtr)-{- const char *start = s;- const char *next = s;- const ENCODING *enc = encoding;- int tok;-- for (;;) {- tok = XmlPrologTok(enc, start, end, &next);- if (tok <= 0) {- if (!ps_finalBuffer && tok != XML_TOK_INVALID) {- *nextPtr = s;- return XML_ERROR_NONE;- }- switch (tok) {- case XML_TOK_INVALID:- return XML_ERROR_INVALID_TOKEN;- case XML_TOK_PARTIAL:- return XML_ERROR_UNCLOSED_TOKEN;- case XML_TOK_PARTIAL_CHAR:- return XML_ERROR_PARTIAL_CHAR;- case XML_TOK_NONE: /* start == end */- default:- break;- }- /* found end of entity value - can store it now */- return storeEntityValue(parser, enc, s, end);- }- start = next;- }-}--#endif /* XML_DTD */--static enum XML_Error PTRCALL-prologProcessor(XML_Parser parser,- const char *s,- const char *end,- const char **nextPtr)-{- const char *next = s;- int tok = XmlPrologTok(encoding, s, end, &next);- return doProlog(parser, encoding, s, end, tok, next, - nextPtr, (XML_Bool)!ps_finalBuffer);-}--static enum XML_Error-doProlog(XML_Parser parser,- const ENCODING *enc,- const char *s,- const char *end,- int tok,- const char *next,- const char **nextPtr,- XML_Bool haveMore)-{-#ifdef XML_DTD- static const XML_Char externalSubsetName[] = { ASCII_HASH , '\0' };-#endif /* XML_DTD */- static const XML_Char atypeCDATA[] = - { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };- static const XML_Char atypeID[] = { ASCII_I, ASCII_D, '\0' };- static const XML_Char atypeIDREF[] =- { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };- static const XML_Char atypeIDREFS[] =- { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };- static const XML_Char atypeENTITY[] =- { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };- static const XML_Char atypeENTITIES[] = { ASCII_E, ASCII_N,- ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0' };- static const XML_Char atypeNMTOKEN[] = {- ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' };- static const XML_Char atypeNMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T,- ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' };- static const XML_Char notationPrefix[] = { ASCII_N, ASCII_O, ASCII_T,- ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0' };- static const XML_Char enumValueSep[] = { ASCII_PIPE, '\0' };- static const XML_Char enumValueStart[] = { ASCII_LPAREN, '\0' };-- /* save one level of indirection */- DTD * const dtd = _dtd; -- const char **eventPP;- const char **eventEndPP;- enum XML_Content_Quant quant;-- if (enc == encoding) {- eventPP = &eventPtr;- eventEndPP = &eventEndPtr;- }- else {- eventPP = &(openInternalEntities->internalEventPtr);- eventEndPP = &(openInternalEntities->internalEventEndPtr);- }-- for (;;) {- int role;- XML_Bool handleDefault = XML_TRUE;- *eventPP = s;- *eventEndPP = next;- if (tok <= 0) {- if (haveMore && tok != XML_TOK_INVALID) {- *nextPtr = s;- return XML_ERROR_NONE;- }- switch (tok) {- case XML_TOK_INVALID:- *eventPP = next;- return XML_ERROR_INVALID_TOKEN;- case XML_TOK_PARTIAL:- return XML_ERROR_UNCLOSED_TOKEN;- case XML_TOK_PARTIAL_CHAR:- return XML_ERROR_PARTIAL_CHAR;- case XML_TOK_NONE:-#ifdef XML_DTD- /* for internal PE NOT referenced between declarations */- if (enc != encoding && !openInternalEntities->betweenDecl) {- *nextPtr = s;- return XML_ERROR_NONE;- }- /* WFC: PE Between Declarations - must check that PE contains- complete markup, not only for external PEs, but also for- internal PEs if the reference occurs between declarations.- */- if (isParamEntity || enc != encoding) {- if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)- == XML_ROLE_ERROR)- return XML_ERROR_INCOMPLETE_PE;- *nextPtr = s;- return XML_ERROR_NONE;- }-#endif /* XML_DTD */- return XML_ERROR_NO_ELEMENTS;- default:- tok = -tok;- next = end;- break;- }- }- role = XmlTokenRole(&prologState, tok, s, next, enc);- switch (role) {- case XML_ROLE_XML_DECL:- {- enum XML_Error result = processXmlDecl(parser, 0, s, next);- if (result != XML_ERROR_NONE)- return result;- enc = encoding;- handleDefault = XML_FALSE;- }- break;- case XML_ROLE_DOCTYPE_NAME:- if (startDoctypeDeclHandler) {- doctypeName = poolStoreString(&tempPool, enc, s, next);- if (!doctypeName)- return XML_ERROR_NO_MEMORY;- poolFinish(&tempPool);- doctypePubid = NULL;- handleDefault = XML_FALSE;- }- doctypeSysid = NULL; /* always initialize to NULL */- break;- case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:- if (startDoctypeDeclHandler) {- startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,- doctypePubid, 1);- doctypeName = NULL;- poolClear(&tempPool);- handleDefault = XML_FALSE;- }- break;-#ifdef XML_DTD- case XML_ROLE_TEXT_DECL:- {- enum XML_Error result = processXmlDecl(parser, 1, s, next);- if (result != XML_ERROR_NONE)- return result;- enc = encoding;- handleDefault = XML_FALSE;- }- break;-#endif /* XML_DTD */- case XML_ROLE_DOCTYPE_PUBLIC_ID:-#ifdef XML_DTD- useForeignDTD = XML_FALSE;- declEntity = (ENTITY *)lookup(&dtd->paramEntities,- externalSubsetName,- sizeof(ENTITY));- if (!declEntity)- return XML_ERROR_NO_MEMORY;-#endif /* XML_DTD */- dtd->hasParamEntityRefs = XML_TRUE;- if (startDoctypeDeclHandler) {- if (!XmlIsPublicId(enc, s, next, eventPP))- return XML_ERROR_PUBLICID;- doctypePubid = poolStoreString(&tempPool, enc,- s + enc->minBytesPerChar,- next - enc->minBytesPerChar);- if (!doctypePubid)- return XML_ERROR_NO_MEMORY;- normalizePublicId((XML_Char *)doctypePubid);- poolFinish(&tempPool);- handleDefault = XML_FALSE;- goto alreadyChecked;- }- /* fall through */- case XML_ROLE_ENTITY_PUBLIC_ID:- if (!XmlIsPublicId(enc, s, next, eventPP))- return XML_ERROR_PUBLICID;- alreadyChecked:- if (dtd->keepProcessing && declEntity) {- XML_Char *tem = poolStoreString(&dtd->pool,- enc,- s + enc->minBytesPerChar,- next - enc->minBytesPerChar);- if (!tem)- return XML_ERROR_NO_MEMORY;- normalizePublicId(tem);- declEntity->publicId = tem;- poolFinish(&dtd->pool);- if (entityDeclHandler)- handleDefault = XML_FALSE;- }- break;- case XML_ROLE_DOCTYPE_CLOSE:- if (doctypeName) {- startDoctypeDeclHandler(handlerArg, doctypeName,- doctypeSysid, doctypePubid, 0);- poolClear(&tempPool);- handleDefault = XML_FALSE;- }- /* doctypeSysid will be non-NULL in the case of a previous- XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler- was not set, indicating an external subset- */-#ifdef XML_DTD- if (doctypeSysid || useForeignDTD) {- XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;- dtd->hasParamEntityRefs = XML_TRUE;- if (paramEntityParsing && externalEntityRefHandler) {- ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,- externalSubsetName,- sizeof(ENTITY));- if (!entity)- return XML_ERROR_NO_MEMORY;- if (useForeignDTD)- entity->base = curBase;- dtd->paramEntityRead = XML_FALSE;- if (!externalEntityRefHandler(externalEntityRefHandlerArg,- 0,- entity->base,- entity->systemId,- entity->publicId))- return XML_ERROR_EXTERNAL_ENTITY_HANDLING;- if (dtd->paramEntityRead) {- if (!dtd->standalone && - notStandaloneHandler && - !notStandaloneHandler(handlerArg))- return XML_ERROR_NOT_STANDALONE;- }- /* if we didn't read the foreign DTD then this means that there- is no external subset and we must reset dtd->hasParamEntityRefs- */- else if (!doctypeSysid)- dtd->hasParamEntityRefs = hadParamEntityRefs;- /* end of DTD - no need to update dtd->keepProcessing */- }- useForeignDTD = XML_FALSE;- }-#endif /* XML_DTD */- if (endDoctypeDeclHandler) {- endDoctypeDeclHandler(handlerArg);- handleDefault = XML_FALSE;- }- break;- case XML_ROLE_INSTANCE_START:-#ifdef XML_DTD- /* if there is no DOCTYPE declaration then now is the- last chance to read the foreign DTD- */- if (useForeignDTD) {- XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;- dtd->hasParamEntityRefs = XML_TRUE;- if (paramEntityParsing && externalEntityRefHandler) {- ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,- externalSubsetName,- sizeof(ENTITY));- if (!entity)- return XML_ERROR_NO_MEMORY;- entity->base = curBase;- dtd->paramEntityRead = XML_FALSE;- if (!externalEntityRefHandler(externalEntityRefHandlerArg,- 0,- entity->base,- entity->systemId,- entity->publicId))- return XML_ERROR_EXTERNAL_ENTITY_HANDLING;- if (dtd->paramEntityRead) {- if (!dtd->standalone &&- notStandaloneHandler &&- !notStandaloneHandler(handlerArg))- return XML_ERROR_NOT_STANDALONE;- }- /* if we didn't read the foreign DTD then this means that there- is no external subset and we must reset dtd->hasParamEntityRefs- */- else- dtd->hasParamEntityRefs = hadParamEntityRefs;- /* end of DTD - no need to update dtd->keepProcessing */- }- }-#endif /* XML_DTD */- processor = contentProcessor;- return contentProcessor(parser, s, end, nextPtr);- case XML_ROLE_ATTLIST_ELEMENT_NAME:- declElementType = getElementType(parser, enc, s, next);- if (!declElementType)- return XML_ERROR_NO_MEMORY;- goto checkAttListDeclHandler;- case XML_ROLE_ATTRIBUTE_NAME:- declAttributeId = getAttributeId(parser, enc, s, next);- if (!declAttributeId)- return XML_ERROR_NO_MEMORY;- declAttributeIsCdata = XML_FALSE;- declAttributeType = NULL;- declAttributeIsId = XML_FALSE;- goto checkAttListDeclHandler;- case XML_ROLE_ATTRIBUTE_TYPE_CDATA:- declAttributeIsCdata = XML_TRUE;- declAttributeType = atypeCDATA;- goto checkAttListDeclHandler;- case XML_ROLE_ATTRIBUTE_TYPE_ID:- declAttributeIsId = XML_TRUE;- declAttributeType = atypeID;- goto checkAttListDeclHandler;- case XML_ROLE_ATTRIBUTE_TYPE_IDREF:- declAttributeType = atypeIDREF;- goto checkAttListDeclHandler;- case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:- declAttributeType = atypeIDREFS;- goto checkAttListDeclHandler;- case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:- declAttributeType = atypeENTITY;- goto checkAttListDeclHandler;- case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:- declAttributeType = atypeENTITIES;- goto checkAttListDeclHandler;- case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:- declAttributeType = atypeNMTOKEN;- goto checkAttListDeclHandler;- case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:- declAttributeType = atypeNMTOKENS;- checkAttListDeclHandler:- if (dtd->keepProcessing && attlistDeclHandler)- handleDefault = XML_FALSE;- break;- case XML_ROLE_ATTRIBUTE_ENUM_VALUE:- case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:- if (dtd->keepProcessing && attlistDeclHandler) {- const XML_Char *prefix;- if (declAttributeType) {- prefix = enumValueSep;- }- else {- prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE- ? notationPrefix- : enumValueStart);- }- if (!poolAppendString(&tempPool, prefix))- return XML_ERROR_NO_MEMORY;- if (!poolAppend(&tempPool, enc, s, next))- return XML_ERROR_NO_MEMORY;- declAttributeType = tempPool.start;- handleDefault = XML_FALSE;- }- break;- case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:- case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:- if (dtd->keepProcessing) {- if (!defineAttribute(declElementType, declAttributeId,- declAttributeIsCdata, declAttributeIsId,- 0, parser))- return XML_ERROR_NO_MEMORY;- if (attlistDeclHandler && declAttributeType) {- if (*declAttributeType == XML_T(ASCII_LPAREN)- || (*declAttributeType == XML_T(ASCII_N)- && declAttributeType[1] == XML_T(ASCII_O))) {- /* Enumerated or Notation type */- if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))- || !poolAppendChar(&tempPool, XML_T('\0')))- return XML_ERROR_NO_MEMORY;- declAttributeType = tempPool.start;- poolFinish(&tempPool);- }- *eventEndPP = s;- attlistDeclHandler(handlerArg, declElementType->name,- declAttributeId->name, declAttributeType,- 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);- poolClear(&tempPool);- handleDefault = XML_FALSE;- }- }- break;- case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:- case XML_ROLE_FIXED_ATTRIBUTE_VALUE:- if (dtd->keepProcessing) {- const XML_Char *attVal;- enum XML_Error result =- storeAttributeValue(parser, enc, declAttributeIsCdata,- s + enc->minBytesPerChar,- next - enc->minBytesPerChar,- &dtd->pool);- if (result)- return result;- attVal = poolStart(&dtd->pool);- poolFinish(&dtd->pool);- /* ID attributes aren't allowed to have a default */- if (!defineAttribute(declElementType, declAttributeId,- declAttributeIsCdata, XML_FALSE, attVal, parser))- return XML_ERROR_NO_MEMORY;- if (attlistDeclHandler && declAttributeType) {- if (*declAttributeType == XML_T(ASCII_LPAREN)- || (*declAttributeType == XML_T(ASCII_N)- && declAttributeType[1] == XML_T(ASCII_O))) {- /* Enumerated or Notation type */- if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))- || !poolAppendChar(&tempPool, XML_T('\0')))- return XML_ERROR_NO_MEMORY;- declAttributeType = tempPool.start;- poolFinish(&tempPool);- }- *eventEndPP = s;- attlistDeclHandler(handlerArg, declElementType->name,- declAttributeId->name, declAttributeType,- attVal,- role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);- poolClear(&tempPool);- handleDefault = XML_FALSE;- }- }- break;- case XML_ROLE_ENTITY_VALUE:- if (dtd->keepProcessing) {- enum XML_Error result = storeEntityValue(parser, enc,- s + enc->minBytesPerChar,- next - enc->minBytesPerChar);- if (declEntity) {- declEntity->textPtr = poolStart(&dtd->entityValuePool);- declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));- poolFinish(&dtd->entityValuePool);- if (entityDeclHandler) {- *eventEndPP = s;- entityDeclHandler(handlerArg,- declEntity->name,- declEntity->is_param,- declEntity->textPtr,- declEntity->textLen,- curBase, 0, 0, 0);- handleDefault = XML_FALSE;- }- }- else- poolDiscard(&dtd->entityValuePool);- if (result != XML_ERROR_NONE)- return result;- }- break;- case XML_ROLE_DOCTYPE_SYSTEM_ID:-#ifdef XML_DTD- useForeignDTD = XML_FALSE;-#endif /* XML_DTD */- dtd->hasParamEntityRefs = XML_TRUE;- if (startDoctypeDeclHandler) {- doctypeSysid = poolStoreString(&tempPool, enc,- s + enc->minBytesPerChar,- next - enc->minBytesPerChar);- if (doctypeSysid == NULL)- return XML_ERROR_NO_MEMORY;- poolFinish(&tempPool);- handleDefault = XML_FALSE;- }-#ifdef XML_DTD- else- /* use externalSubsetName to make doctypeSysid non-NULL- for the case where no startDoctypeDeclHandler is set */- doctypeSysid = externalSubsetName;-#endif /* XML_DTD */- if (!dtd->standalone-#ifdef XML_DTD- && !paramEntityParsing-#endif /* XML_DTD */- && notStandaloneHandler- && !notStandaloneHandler(handlerArg))- return XML_ERROR_NOT_STANDALONE;-#ifndef XML_DTD- break;-#else /* XML_DTD */- if (!declEntity) {- declEntity = (ENTITY *)lookup(&dtd->paramEntities,- externalSubsetName,- sizeof(ENTITY));- if (!declEntity)- return XML_ERROR_NO_MEMORY;- declEntity->publicId = NULL;- }- /* fall through */-#endif /* XML_DTD */- case XML_ROLE_ENTITY_SYSTEM_ID:- if (dtd->keepProcessing && declEntity) {- declEntity->systemId = poolStoreString(&dtd->pool, enc,- s + enc->minBytesPerChar,- next - enc->minBytesPerChar);- if (!declEntity->systemId)- return XML_ERROR_NO_MEMORY;- declEntity->base = curBase;- poolFinish(&dtd->pool);- if (entityDeclHandler)- handleDefault = XML_FALSE;- }- break;- case XML_ROLE_ENTITY_COMPLETE:- if (dtd->keepProcessing && declEntity && entityDeclHandler) {- *eventEndPP = s;- entityDeclHandler(handlerArg,- declEntity->name,- declEntity->is_param,- 0,0,- declEntity->base,- declEntity->systemId,- declEntity->publicId,- 0);- handleDefault = XML_FALSE;- }- break;- case XML_ROLE_ENTITY_NOTATION_NAME:- if (dtd->keepProcessing && declEntity) {- declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);- if (!declEntity->notation)- return XML_ERROR_NO_MEMORY;- poolFinish(&dtd->pool);- if (unparsedEntityDeclHandler) {- *eventEndPP = s;- unparsedEntityDeclHandler(handlerArg,- declEntity->name,- declEntity->base,- declEntity->systemId,- declEntity->publicId,- declEntity->notation);- handleDefault = XML_FALSE;- }- else if (entityDeclHandler) {- *eventEndPP = s;- entityDeclHandler(handlerArg,- declEntity->name,- 0,0,0,- declEntity->base,- declEntity->systemId,- declEntity->publicId,- declEntity->notation);- handleDefault = XML_FALSE;- }- }- break;- case XML_ROLE_GENERAL_ENTITY_NAME:- {- if (XmlPredefinedEntityName(enc, s, next)) {- declEntity = NULL;- break;- }- if (dtd->keepProcessing) {- const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);- if (!name)- return XML_ERROR_NO_MEMORY;- declEntity = (ENTITY *)lookup(&dtd->generalEntities, name,- sizeof(ENTITY));- if (!declEntity)- return XML_ERROR_NO_MEMORY;- if (declEntity->name != name) {- poolDiscard(&dtd->pool);- declEntity = NULL;- }- else {- poolFinish(&dtd->pool);- declEntity->publicId = NULL;- declEntity->is_param = XML_FALSE;- /* if we have a parent parser or are reading an internal parameter- entity, then the entity declaration is not considered "internal"- */- declEntity->is_internal = !(parentParser || openInternalEntities);- if (entityDeclHandler)- handleDefault = XML_FALSE;- }- }- else {- poolDiscard(&dtd->pool);- declEntity = NULL;- }- }- break;- case XML_ROLE_PARAM_ENTITY_NAME:-#ifdef XML_DTD- if (dtd->keepProcessing) {- const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);- if (!name)- return XML_ERROR_NO_MEMORY;- declEntity = (ENTITY *)lookup(&dtd->paramEntities,- name, sizeof(ENTITY));- if (!declEntity)- return XML_ERROR_NO_MEMORY;- if (declEntity->name != name) {- poolDiscard(&dtd->pool);- declEntity = NULL;- }- else {- poolFinish(&dtd->pool);- declEntity->publicId = NULL;- declEntity->is_param = XML_TRUE;- /* if we have a parent parser or are reading an internal parameter- entity, then the entity declaration is not considered "internal"- */- declEntity->is_internal = !(parentParser || openInternalEntities);- if (entityDeclHandler)- handleDefault = XML_FALSE;- }- }- else {- poolDiscard(&dtd->pool);- declEntity = NULL;- }-#else /* not XML_DTD */- declEntity = NULL;-#endif /* XML_DTD */- break;- case XML_ROLE_NOTATION_NAME:- declNotationPublicId = NULL;- declNotationName = NULL;- if (notationDeclHandler) {- declNotationName = poolStoreString(&tempPool, enc, s, next);- if (!declNotationName)- return XML_ERROR_NO_MEMORY;- poolFinish(&tempPool);- handleDefault = XML_FALSE;- }- break;- case XML_ROLE_NOTATION_PUBLIC_ID:- if (!XmlIsPublicId(enc, s, next, eventPP))- return XML_ERROR_PUBLICID;- if (declNotationName) { /* means notationDeclHandler != NULL */- XML_Char *tem = poolStoreString(&tempPool,- enc,- s + enc->minBytesPerChar,- next - enc->minBytesPerChar);- if (!tem)- return XML_ERROR_NO_MEMORY;- normalizePublicId(tem);- declNotationPublicId = tem;- poolFinish(&tempPool);- handleDefault = XML_FALSE;- }- break;- case XML_ROLE_NOTATION_SYSTEM_ID:- if (declNotationName && notationDeclHandler) {- const XML_Char *systemId- = poolStoreString(&tempPool, enc,- s + enc->minBytesPerChar,- next - enc->minBytesPerChar);- if (!systemId)- return XML_ERROR_NO_MEMORY;- *eventEndPP = s;- notationDeclHandler(handlerArg,- declNotationName,- curBase,- systemId,- declNotationPublicId);- handleDefault = XML_FALSE;- }- poolClear(&tempPool);- break;- case XML_ROLE_NOTATION_NO_SYSTEM_ID:- if (declNotationPublicId && notationDeclHandler) {- *eventEndPP = s;- notationDeclHandler(handlerArg,- declNotationName,- curBase,- 0,- declNotationPublicId);- handleDefault = XML_FALSE;- }- poolClear(&tempPool);- break;- case XML_ROLE_ERROR:- switch (tok) {- case XML_TOK_PARAM_ENTITY_REF:- /* PE references in internal subset are- not allowed within declarations. */ - return XML_ERROR_PARAM_ENTITY_REF;- case XML_TOK_XML_DECL:- return XML_ERROR_MISPLACED_XML_PI;- default:- return XML_ERROR_SYNTAX;- }-#ifdef XML_DTD- case XML_ROLE_IGNORE_SECT:- {- enum XML_Error result;- if (defaultHandler)- reportDefault(parser, enc, s, next);- handleDefault = XML_FALSE;- result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);- if (result != XML_ERROR_NONE)- return result;- else if (!next) {- processor = ignoreSectionProcessor;- return result;- }- }- break;-#endif /* XML_DTD */- case XML_ROLE_GROUP_OPEN:- if (prologState.level >= groupSize) {- if (groupSize) {- char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);- if (temp == NULL)- return XML_ERROR_NO_MEMORY;- groupConnector = temp;- if (dtd->scaffIndex) {- int *temp = (int *)REALLOC(dtd->scaffIndex,- groupSize * sizeof(int));- if (temp == NULL)- return XML_ERROR_NO_MEMORY;- dtd->scaffIndex = temp;- }- }- else {- groupConnector = (char *)MALLOC(groupSize = 32);- if (!groupConnector)- return XML_ERROR_NO_MEMORY;- }- }- groupConnector[prologState.level] = 0;- if (dtd->in_eldecl) {- int myindex = nextScaffoldPart(parser);- if (myindex < 0)- return XML_ERROR_NO_MEMORY;- dtd->scaffIndex[dtd->scaffLevel] = myindex;- dtd->scaffLevel++;- dtd->scaffold[myindex].type = XML_CTYPE_SEQ;- if (elementDeclHandler)- handleDefault = XML_FALSE;- }- break;- case XML_ROLE_GROUP_SEQUENCE:- if (groupConnector[prologState.level] == ASCII_PIPE)- return XML_ERROR_SYNTAX;- groupConnector[prologState.level] = ASCII_COMMA;- if (dtd->in_eldecl && elementDeclHandler)- handleDefault = XML_FALSE;- break;- case XML_ROLE_GROUP_CHOICE:- if (groupConnector[prologState.level] == ASCII_COMMA)- return XML_ERROR_SYNTAX;- if (dtd->in_eldecl- && !groupConnector[prologState.level]- && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type- != XML_CTYPE_MIXED)- ) {- dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type- = XML_CTYPE_CHOICE;- if (elementDeclHandler)- handleDefault = XML_FALSE;- }- groupConnector[prologState.level] = ASCII_PIPE;- break;- case XML_ROLE_PARAM_ENTITY_REF:-#ifdef XML_DTD- case XML_ROLE_INNER_PARAM_ENTITY_REF:- dtd->hasParamEntityRefs = XML_TRUE;- if (!paramEntityParsing)- dtd->keepProcessing = dtd->standalone;- else {- const XML_Char *name;- ENTITY *entity;- name = poolStoreString(&dtd->pool, enc,- s + enc->minBytesPerChar,- next - enc->minBytesPerChar);- if (!name)- return XML_ERROR_NO_MEMORY;- entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);- poolDiscard(&dtd->pool);- /* first, determine if a check for an existing declaration is needed;- if yes, check that the entity exists, and that it is internal,- otherwise call the skipped entity handler- */- if (prologState.documentEntity &&- (dtd->standalone- ? !openInternalEntities- : !dtd->hasParamEntityRefs)) {- if (!entity)- return XML_ERROR_UNDEFINED_ENTITY;- else if (!entity->is_internal)- return XML_ERROR_ENTITY_DECLARED_IN_PE;- }- else if (!entity) {- dtd->keepProcessing = dtd->standalone;- /* cannot report skipped entities in declarations */- if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {- skippedEntityHandler(handlerArg, name, 1);- handleDefault = XML_FALSE;- }- break;- }- if (entity->open)- return XML_ERROR_RECURSIVE_ENTITY_REF;- if (entity->textPtr) {- enum XML_Error result;- XML_Bool betweenDecl = - (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);- result = processInternalEntity(parser, entity, betweenDecl);- if (result != XML_ERROR_NONE)- return result;- handleDefault = XML_FALSE;- break;- }- if (externalEntityRefHandler) {- dtd->paramEntityRead = XML_FALSE;- entity->open = XML_TRUE;- if (!externalEntityRefHandler(externalEntityRefHandlerArg,- 0,- entity->base,- entity->systemId,- entity->publicId)) {- entity->open = XML_FALSE;- return XML_ERROR_EXTERNAL_ENTITY_HANDLING;- }- entity->open = XML_FALSE;- handleDefault = XML_FALSE;- if (!dtd->paramEntityRead) {- dtd->keepProcessing = dtd->standalone;- break;- }- }- else {- dtd->keepProcessing = dtd->standalone;- break;- }- }-#endif /* XML_DTD */- if (!dtd->standalone &&- notStandaloneHandler &&- !notStandaloneHandler(handlerArg))- return XML_ERROR_NOT_STANDALONE;- break;-- /* Element declaration stuff */-- case XML_ROLE_ELEMENT_NAME:- if (elementDeclHandler) {- declElementType = getElementType(parser, enc, s, next);- if (!declElementType)- return XML_ERROR_NO_MEMORY;- dtd->scaffLevel = 0;- dtd->scaffCount = 0;- dtd->in_eldecl = XML_TRUE;- handleDefault = XML_FALSE;- }- break;-- case XML_ROLE_CONTENT_ANY:- case XML_ROLE_CONTENT_EMPTY:- if (dtd->in_eldecl) {- if (elementDeclHandler) {- XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));- if (!content)- return XML_ERROR_NO_MEMORY;- content->quant = XML_CQUANT_NONE;- content->name = NULL;- content->numchildren = 0;- content->children = NULL;- content->type = ((role == XML_ROLE_CONTENT_ANY) ?- XML_CTYPE_ANY :- XML_CTYPE_EMPTY);- *eventEndPP = s;- elementDeclHandler(handlerArg, declElementType->name, content);- handleDefault = XML_FALSE;- }- dtd->in_eldecl = XML_FALSE;- }- break;-- case XML_ROLE_CONTENT_PCDATA:- if (dtd->in_eldecl) {- dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type- = XML_CTYPE_MIXED;- if (elementDeclHandler)- handleDefault = XML_FALSE;- }- break;-- case XML_ROLE_CONTENT_ELEMENT:- quant = XML_CQUANT_NONE;- goto elementContent;- case XML_ROLE_CONTENT_ELEMENT_OPT:- quant = XML_CQUANT_OPT;- goto elementContent;- case XML_ROLE_CONTENT_ELEMENT_REP:- quant = XML_CQUANT_REP;- goto elementContent;- case XML_ROLE_CONTENT_ELEMENT_PLUS:- quant = XML_CQUANT_PLUS;- elementContent:- if (dtd->in_eldecl) {- ELEMENT_TYPE *el;- const XML_Char *name;- int nameLen;- const char *nxt = (quant == XML_CQUANT_NONE- ? next- : next - enc->minBytesPerChar);- int myindex = nextScaffoldPart(parser);- if (myindex < 0)- return XML_ERROR_NO_MEMORY;- dtd->scaffold[myindex].type = XML_CTYPE_NAME;- dtd->scaffold[myindex].quant = quant;- el = getElementType(parser, enc, s, nxt);- if (!el)- return XML_ERROR_NO_MEMORY;- name = el->name;- dtd->scaffold[myindex].name = name;- nameLen = 0;- for (; name[nameLen++]; );- dtd->contentStringLen += nameLen;- if (elementDeclHandler)- handleDefault = XML_FALSE;- }- break;-- case XML_ROLE_GROUP_CLOSE:- quant = XML_CQUANT_NONE;- goto closeGroup;- case XML_ROLE_GROUP_CLOSE_OPT:- quant = XML_CQUANT_OPT;- goto closeGroup;- case XML_ROLE_GROUP_CLOSE_REP:- quant = XML_CQUANT_REP;- goto closeGroup;- case XML_ROLE_GROUP_CLOSE_PLUS:- quant = XML_CQUANT_PLUS;- closeGroup:- if (dtd->in_eldecl) {- if (elementDeclHandler)- handleDefault = XML_FALSE;- dtd->scaffLevel--;- dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;- if (dtd->scaffLevel == 0) {- if (!handleDefault) {- XML_Content *model = build_model(parser);- if (!model)- return XML_ERROR_NO_MEMORY;- *eventEndPP = s;- elementDeclHandler(handlerArg, declElementType->name, model);- }- dtd->in_eldecl = XML_FALSE;- dtd->contentStringLen = 0;- }- }- break;- /* End element declaration stuff */-- case XML_ROLE_PI:- if (!reportProcessingInstruction(parser, enc, s, next))- return XML_ERROR_NO_MEMORY;- handleDefault = XML_FALSE;- break;- case XML_ROLE_COMMENT:- if (!reportComment(parser, enc, s, next))- return XML_ERROR_NO_MEMORY;- handleDefault = XML_FALSE;- break;- case XML_ROLE_NONE:- switch (tok) {- case XML_TOK_BOM:- handleDefault = XML_FALSE;- break;- }- break;- case XML_ROLE_DOCTYPE_NONE:- if (startDoctypeDeclHandler)- handleDefault = XML_FALSE;- break;- case XML_ROLE_ENTITY_NONE:- if (dtd->keepProcessing && entityDeclHandler)- handleDefault = XML_FALSE;- break;- case XML_ROLE_NOTATION_NONE:- if (notationDeclHandler)- handleDefault = XML_FALSE;- break;- case XML_ROLE_ATTLIST_NONE:- if (dtd->keepProcessing && attlistDeclHandler)- handleDefault = XML_FALSE;- break;- case XML_ROLE_ELEMENT_NONE:- if (elementDeclHandler)- handleDefault = XML_FALSE;- break;- } /* end of big switch */-- if (handleDefault && defaultHandler)- reportDefault(parser, enc, s, next);-- switch (ps_parsing) {- case XML_SUSPENDED: - *nextPtr = next;- return XML_ERROR_NONE;- case XML_FINISHED:- return XML_ERROR_ABORTED;- default:- s = next;- tok = XmlPrologTok(enc, s, end, &next);- }- }- /* not reached */-}--static enum XML_Error PTRCALL-epilogProcessor(XML_Parser parser,- const char *s,- const char *end,- const char **nextPtr)-{- processor = epilogProcessor;- eventPtr = s;- for (;;) {- const char *next = NULL;- int tok = XmlPrologTok(encoding, s, end, &next);- eventEndPtr = next;- switch (tok) {- /* report partial linebreak - it might be the last token */- case -XML_TOK_PROLOG_S:- if (defaultHandler) {- reportDefault(parser, encoding, s, next);- if (ps_parsing == XML_FINISHED)- return XML_ERROR_ABORTED;- }- *nextPtr = next;- return XML_ERROR_NONE;- case XML_TOK_NONE:- *nextPtr = s;- return XML_ERROR_NONE;- case XML_TOK_PROLOG_S:- if (defaultHandler)- reportDefault(parser, encoding, s, next);- break;- case XML_TOK_PI:- if (!reportProcessingInstruction(parser, encoding, s, next))- return XML_ERROR_NO_MEMORY;- break;- case XML_TOK_COMMENT:- if (!reportComment(parser, encoding, s, next))- return XML_ERROR_NO_MEMORY;- break;- case XML_TOK_INVALID:- eventPtr = next;- return XML_ERROR_INVALID_TOKEN;- case XML_TOK_PARTIAL:- if (!ps_finalBuffer) {- *nextPtr = s;- return XML_ERROR_NONE;- }- return XML_ERROR_UNCLOSED_TOKEN;- case XML_TOK_PARTIAL_CHAR:- if (!ps_finalBuffer) {- *nextPtr = s;- return XML_ERROR_NONE;- }- return XML_ERROR_PARTIAL_CHAR;- default:- return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;- }- eventPtr = s = next;- switch (ps_parsing) {- case XML_SUSPENDED: - *nextPtr = next;- return XML_ERROR_NONE;- case XML_FINISHED:- return XML_ERROR_ABORTED;- default: ;- }- }-}--static enum XML_Error-processInternalEntity(XML_Parser parser, ENTITY *entity,- XML_Bool betweenDecl)-{- const char *textStart, *textEnd;- const char *next;- enum XML_Error result;- OPEN_INTERNAL_ENTITY *openEntity;-- if (freeInternalEntities) {- openEntity = freeInternalEntities;- freeInternalEntities = openEntity->next;- }- else {- openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY));- if (!openEntity)- return XML_ERROR_NO_MEMORY;- }- entity->open = XML_TRUE;- entity->processed = 0;- openEntity->next = openInternalEntities;- openInternalEntities = openEntity;- openEntity->entity = entity;- openEntity->startTagLevel = tagLevel;- openEntity->betweenDecl = betweenDecl;- openEntity->internalEventPtr = NULL;- openEntity->internalEventEndPtr = NULL;- textStart = (char *)entity->textPtr;- textEnd = (char *)(entity->textPtr + entity->textLen);--#ifdef XML_DTD- if (entity->is_param) {- int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);- result = doProlog(parser, internalEncoding, textStart, textEnd, tok, - next, &next, XML_FALSE);- }- else -#endif /* XML_DTD */- result = doContent(parser, tagLevel, internalEncoding, textStart, - textEnd, &next, XML_FALSE);-- if (result == XML_ERROR_NONE) {- if (textEnd != next && ps_parsing == XML_SUSPENDED) {- entity->processed = (int)(next - textStart);- processor = internalEntityProcessor;- }- else {- entity->open = XML_FALSE;- openInternalEntities = openEntity->next;- /* put openEntity back in list of free instances */- openEntity->next = freeInternalEntities;- freeInternalEntities = openEntity;- }- }- return result;-}--static enum XML_Error PTRCALL-internalEntityProcessor(XML_Parser parser,- const char *s,- const char *end,- const char **nextPtr)-{- ENTITY *entity;- const char *textStart, *textEnd;- const char *next;- enum XML_Error result;- OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities;- if (!openEntity)- return XML_ERROR_UNEXPECTED_STATE;-- entity = openEntity->entity;- textStart = ((char *)entity->textPtr) + entity->processed;- textEnd = (char *)(entity->textPtr + entity->textLen);--#ifdef XML_DTD- if (entity->is_param) {- int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);- result = doProlog(parser, internalEncoding, textStart, textEnd, tok, - next, &next, XML_FALSE);- }- else-#endif /* XML_DTD */- result = doContent(parser, openEntity->startTagLevel, internalEncoding, - textStart, textEnd, &next, XML_FALSE); -- if (result != XML_ERROR_NONE)- return result;- else if (textEnd != next && ps_parsing == XML_SUSPENDED) {- entity->processed = (int)(next - (char *)entity->textPtr);- return result;- }- else {- entity->open = XML_FALSE;- openInternalEntities = openEntity->next;- /* put openEntity back in list of free instances */- openEntity->next = freeInternalEntities;- freeInternalEntities = openEntity;- }--#ifdef XML_DTD- if (entity->is_param) {- int tok;- processor = prologProcessor;- tok = XmlPrologTok(encoding, s, end, &next);- return doProlog(parser, encoding, s, end, tok, next, nextPtr, - (XML_Bool)!ps_finalBuffer);- }- else-#endif /* XML_DTD */- {- processor = contentProcessor;- /* see externalEntityContentProcessor vs contentProcessor */- return doContent(parser, parentParser ? 1 : 0, encoding, s, end,- nextPtr, (XML_Bool)!ps_finalBuffer); - } -}--static enum XML_Error PTRCALL-errorProcessor(XML_Parser parser,- const char *s,- const char *end,- const char **nextPtr)-{- return errorCode;-}--static enum XML_Error-storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,- const char *ptr, const char *end,- STRING_POOL *pool)-{- enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,- end, pool);- if (result)- return result;- if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)- poolChop(pool);- if (!poolAppendChar(pool, XML_T('\0')))- return XML_ERROR_NO_MEMORY;- return XML_ERROR_NONE;-}--static enum XML_Error-appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,- const char *ptr, const char *end,- STRING_POOL *pool)-{- DTD * const dtd = _dtd; /* save one level of indirection */- for (;;) {- const char *next;- int tok = XmlAttributeValueTok(enc, ptr, end, &next);- switch (tok) {- case XML_TOK_NONE:- return XML_ERROR_NONE;- case XML_TOK_INVALID:- if (enc == encoding)- eventPtr = next;- return XML_ERROR_INVALID_TOKEN;- case XML_TOK_PARTIAL:- if (enc == encoding)- eventPtr = ptr;- return XML_ERROR_INVALID_TOKEN;- case XML_TOK_CHAR_REF:- {- XML_Char buf[XML_ENCODE_MAX];- int i;- int n = XmlCharRefNumber(enc, ptr);- if (n < 0) {- if (enc == encoding)- eventPtr = ptr;- return XML_ERROR_BAD_CHAR_REF;- }- if (!isCdata- && n == 0x20 /* space */- && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))- break;- n = XmlEncode(n, (ICHAR *)buf);- if (!n) {- if (enc == encoding)- eventPtr = ptr;- return XML_ERROR_BAD_CHAR_REF;- }- for (i = 0; i < n; i++) {- if (!poolAppendChar(pool, buf[i]))- return XML_ERROR_NO_MEMORY;- }- }- break;- case XML_TOK_DATA_CHARS:- if (!poolAppend(pool, enc, ptr, next))- return XML_ERROR_NO_MEMORY;- break;- case XML_TOK_TRAILING_CR:- next = ptr + enc->minBytesPerChar;- /* fall through */- case XML_TOK_ATTRIBUTE_VALUE_S:- case XML_TOK_DATA_NEWLINE:- if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))- break;- if (!poolAppendChar(pool, 0x20))- return XML_ERROR_NO_MEMORY;- break;- case XML_TOK_ENTITY_REF:- {- const XML_Char *name;- ENTITY *entity;- char checkEntityDecl;- XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,- ptr + enc->minBytesPerChar,- next - enc->minBytesPerChar);- if (ch) {- if (!poolAppendChar(pool, ch))- return XML_ERROR_NO_MEMORY;- break;- }- name = poolStoreString(&temp2Pool, enc,- ptr + enc->minBytesPerChar,- next - enc->minBytesPerChar);- if (!name)- return XML_ERROR_NO_MEMORY;- entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);- poolDiscard(&temp2Pool);- /* First, determine if a check for an existing declaration is needed;- if yes, check that the entity exists, and that it is internal.- */- if (pool == &dtd->pool) /* are we called from prolog? */- checkEntityDecl =-#ifdef XML_DTD- prologState.documentEntity &&-#endif /* XML_DTD */- (dtd->standalone- ? !openInternalEntities- : !dtd->hasParamEntityRefs);- else /* if (pool == &tempPool): we are called from content */- checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;- if (checkEntityDecl) {- if (!entity)- return XML_ERROR_UNDEFINED_ENTITY;- else if (!entity->is_internal)- return XML_ERROR_ENTITY_DECLARED_IN_PE;- }- else if (!entity) {- /* Cannot report skipped entity here - see comments on- skippedEntityHandler.- if (skippedEntityHandler)- skippedEntityHandler(handlerArg, name, 0);- */- /* Cannot call the default handler because this would be- out of sync with the call to the startElementHandler.- if ((pool == &tempPool) && defaultHandler)- reportDefault(parser, enc, ptr, next);- */- break;- }- if (entity->open) {- if (enc == encoding)- eventPtr = ptr;- return XML_ERROR_RECURSIVE_ENTITY_REF;- }- if (entity->notation) {- if (enc == encoding)- eventPtr = ptr;- return XML_ERROR_BINARY_ENTITY_REF;- }- if (!entity->textPtr) {- if (enc == encoding)- eventPtr = ptr;- return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;- }- else {- enum XML_Error result;- const XML_Char *textEnd = entity->textPtr + entity->textLen;- entity->open = XML_TRUE;- result = appendAttributeValue(parser, internalEncoding, isCdata,- (char *)entity->textPtr,- (char *)textEnd, pool);- entity->open = XML_FALSE;- if (result)- return result;- }- }- break;- default:- if (enc == encoding)- eventPtr = ptr;- return XML_ERROR_UNEXPECTED_STATE;- }- ptr = next;- }- /* not reached */-}--static enum XML_Error-storeEntityValue(XML_Parser parser,- const ENCODING *enc,- const char *entityTextPtr,- const char *entityTextEnd)-{- DTD * const dtd = _dtd; /* save one level of indirection */- STRING_POOL *pool = &(dtd->entityValuePool);- enum XML_Error result = XML_ERROR_NONE;-#ifdef XML_DTD- int oldInEntityValue = prologState.inEntityValue;- prologState.inEntityValue = 1;-#endif /* XML_DTD */- /* never return Null for the value argument in EntityDeclHandler,- since this would indicate an external entity; therefore we- have to make sure that entityValuePool.start is not null */- if (!pool->blocks) {- if (!poolGrow(pool))- return XML_ERROR_NO_MEMORY;- }-- for (;;) {- const char *next;- int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);- switch (tok) {- case XML_TOK_PARAM_ENTITY_REF:-#ifdef XML_DTD- if (isParamEntity || enc != encoding) {- const XML_Char *name;- ENTITY *entity;- name = poolStoreString(&tempPool, enc,- entityTextPtr + enc->minBytesPerChar,- next - enc->minBytesPerChar);- if (!name) {- result = XML_ERROR_NO_MEMORY;- goto endEntityValue;- }- entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);- poolDiscard(&tempPool);- if (!entity) {- /* not a well-formedness error - see XML 1.0: WFC Entity Declared */- /* cannot report skipped entity here - see comments on- skippedEntityHandler- if (skippedEntityHandler)- skippedEntityHandler(handlerArg, name, 0);- */- dtd->keepProcessing = dtd->standalone;- goto endEntityValue;- }- if (entity->open) {- if (enc == encoding)- eventPtr = entityTextPtr;- result = XML_ERROR_RECURSIVE_ENTITY_REF;- goto endEntityValue;- }- if (entity->systemId) {- if (externalEntityRefHandler) {- dtd->paramEntityRead = XML_FALSE;- entity->open = XML_TRUE;- if (!externalEntityRefHandler(externalEntityRefHandlerArg,- 0,- entity->base,- entity->systemId,- entity->publicId)) {- entity->open = XML_FALSE;- result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;- goto endEntityValue;- }- entity->open = XML_FALSE;- if (!dtd->paramEntityRead)- dtd->keepProcessing = dtd->standalone;- }- else- dtd->keepProcessing = dtd->standalone;- }- else {- entity->open = XML_TRUE;- result = storeEntityValue(parser,- internalEncoding,- (char *)entity->textPtr,- (char *)(entity->textPtr- + entity->textLen));- entity->open = XML_FALSE;- if (result)- goto endEntityValue;- }- break;- }-#endif /* XML_DTD */- /* In the internal subset, PE references are not legal- within markup declarations, e.g entity values in this case. */- eventPtr = entityTextPtr;- result = XML_ERROR_PARAM_ENTITY_REF;- goto endEntityValue;- case XML_TOK_NONE:- result = XML_ERROR_NONE;- goto endEntityValue;- case XML_TOK_ENTITY_REF:- case XML_TOK_DATA_CHARS:- if (!poolAppend(pool, enc, entityTextPtr, next)) {- result = XML_ERROR_NO_MEMORY;- goto endEntityValue;- }- break;- case XML_TOK_TRAILING_CR:- next = entityTextPtr + enc->minBytesPerChar;- /* fall through */- case XML_TOK_DATA_NEWLINE:- if (pool->end == pool->ptr && !poolGrow(pool)) {- result = XML_ERROR_NO_MEMORY;- goto endEntityValue;- }- *(pool->ptr)++ = 0xA;- break;- case XML_TOK_CHAR_REF:- {- XML_Char buf[XML_ENCODE_MAX];- int i;- int n = XmlCharRefNumber(enc, entityTextPtr);- if (n < 0) {- if (enc == encoding)- eventPtr = entityTextPtr;- result = XML_ERROR_BAD_CHAR_REF;- goto endEntityValue;- }- n = XmlEncode(n, (ICHAR *)buf);- if (!n) {- if (enc == encoding)- eventPtr = entityTextPtr;- result = XML_ERROR_BAD_CHAR_REF;- goto endEntityValue;- }- for (i = 0; i < n; i++) {- if (pool->end == pool->ptr && !poolGrow(pool)) {- result = XML_ERROR_NO_MEMORY;- goto endEntityValue;- }- *(pool->ptr)++ = buf[i];- }- }- break;- case XML_TOK_PARTIAL:- if (enc == encoding)- eventPtr = entityTextPtr;- result = XML_ERROR_INVALID_TOKEN;- goto endEntityValue;- case XML_TOK_INVALID:- if (enc == encoding)- eventPtr = next;- result = XML_ERROR_INVALID_TOKEN;- goto endEntityValue;- default:- if (enc == encoding)- eventPtr = entityTextPtr;- result = XML_ERROR_UNEXPECTED_STATE;- goto endEntityValue;- }- entityTextPtr = next;- }-endEntityValue:-#ifdef XML_DTD- prologState.inEntityValue = oldInEntityValue;-#endif /* XML_DTD */- return result;-}--static void FASTCALL-normalizeLines(XML_Char *s)-{- XML_Char *p;- for (;; s++) {- if (*s == XML_T('\0'))- return;- if (*s == 0xD)- break;- }- p = s;- do {- if (*s == 0xD) {- *p++ = 0xA;- if (*++s == 0xA)- s++;- }- else- *p++ = *s++;- } while (*s);- *p = XML_T('\0');-}--static int-reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,- const char *start, const char *end)-{- const XML_Char *target;- XML_Char *data;- const char *tem;- if (!processingInstructionHandler) {- if (defaultHandler)- reportDefault(parser, enc, start, end);- return 1;- }- start += enc->minBytesPerChar * 2;- tem = start + XmlNameLength(enc, start);- target = poolStoreString(&tempPool, enc, start, tem);- if (!target)- return 0;- poolFinish(&tempPool);- data = poolStoreString(&tempPool, enc,- XmlSkipS(enc, tem),- end - enc->minBytesPerChar*2);- if (!data)- return 0;- normalizeLines(data);- processingInstructionHandler(handlerArg, target, data);- poolClear(&tempPool);- return 1;-}--static int-reportComment(XML_Parser parser, const ENCODING *enc,- const char *start, const char *end)-{- XML_Char *data;- if (!commentHandler) {- if (defaultHandler)- reportDefault(parser, enc, start, end);- return 1;- }- data = poolStoreString(&tempPool,- enc,- start + enc->minBytesPerChar * 4,- end - enc->minBytesPerChar * 3);- if (!data)- return 0;- normalizeLines(data);- commentHandler(handlerArg, data);- poolClear(&tempPool);- return 1;-}--static void-reportDefault(XML_Parser parser, const ENCODING *enc,- const char *s, const char *end)-{- if (MUST_CONVERT(enc, s)) {- const char **eventPP;- const char **eventEndPP;- if (enc == encoding) {- eventPP = &eventPtr;- eventEndPP = &eventEndPtr;- }- else {- eventPP = &(openInternalEntities->internalEventPtr);- eventEndPP = &(openInternalEntities->internalEventEndPtr);- }- do {- ICHAR *dataPtr = (ICHAR *)dataBuf;- XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);- *eventEndPP = s;- defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));- *eventPP = s;- } while (s != end);- }- else- defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));-}---static int-defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,- XML_Bool isId, const XML_Char *value, XML_Parser parser)-{- DEFAULT_ATTRIBUTE *att;- if (value || isId) {- /* The handling of default attributes gets messed up if we have- a default which duplicates a non-default. */- int i;- for (i = 0; i < type->nDefaultAtts; i++)- if (attId == type->defaultAtts[i].id)- return 1;- if (isId && !type->idAtt && !attId->xmlns)- type->idAtt = attId;- }- if (type->nDefaultAtts == type->allocDefaultAtts) {- if (type->allocDefaultAtts == 0) {- type->allocDefaultAtts = 8;- type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts- * sizeof(DEFAULT_ATTRIBUTE));- if (!type->defaultAtts)- return 0;- }- else {- DEFAULT_ATTRIBUTE *temp;- int count = type->allocDefaultAtts * 2;- temp = (DEFAULT_ATTRIBUTE *)- REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));- if (temp == NULL)- return 0;- type->allocDefaultAtts = count;- type->defaultAtts = temp;- }- }- att = type->defaultAtts + type->nDefaultAtts;- att->id = attId;- att->value = value;- att->isCdata = isCdata;- if (!isCdata)- attId->maybeTokenized = XML_TRUE;- type->nDefaultAtts += 1;- return 1;-}--static int-setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)-{- DTD * const dtd = _dtd; /* save one level of indirection */- const XML_Char *name;- for (name = elementType->name; *name; name++) {- if (*name == XML_T(ASCII_COLON)) {- PREFIX *prefix;- const XML_Char *s;- for (s = elementType->name; s != name; s++) {- if (!poolAppendChar(&dtd->pool, *s))- return 0;- }- if (!poolAppendChar(&dtd->pool, XML_T('\0')))- return 0;- prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),- sizeof(PREFIX));- if (!prefix)- return 0;- if (prefix->name == poolStart(&dtd->pool))- poolFinish(&dtd->pool);- else- poolDiscard(&dtd->pool);- elementType->prefix = prefix;-- }- }- return 1;-}--static ATTRIBUTE_ID *-getAttributeId(XML_Parser parser, const ENCODING *enc,- const char *start, const char *end)-{- DTD * const dtd = _dtd; /* save one level of indirection */- ATTRIBUTE_ID *id;- const XML_Char *name;- if (!poolAppendChar(&dtd->pool, XML_T('\0')))- return NULL;- name = poolStoreString(&dtd->pool, enc, start, end);- if (!name)- return NULL;- /* skip quotation mark - its storage will be re-used (like in name[-1]) */- ++name;- id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));- if (!id)- return NULL;- if (id->name != name)- poolDiscard(&dtd->pool);- else {- poolFinish(&dtd->pool);- if (!ns)- ;- else if (name[0] == XML_T(ASCII_x)- && name[1] == XML_T(ASCII_m)- && name[2] == XML_T(ASCII_l)- && name[3] == XML_T(ASCII_n)- && name[4] == XML_T(ASCII_s)- && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) {- if (name[5] == XML_T('\0'))- id->prefix = &dtd->defaultPrefix;- else- id->prefix = (PREFIX *)lookup(&dtd->prefixes, name + 6, sizeof(PREFIX));- id->xmlns = XML_TRUE;- }- else {- int i;- for (i = 0; name[i]; i++) {- /* attributes without prefix are *not* in the default namespace */- if (name[i] == XML_T(ASCII_COLON)) {- int j;- for (j = 0; j < i; j++) {- if (!poolAppendChar(&dtd->pool, name[j]))- return NULL;- }- if (!poolAppendChar(&dtd->pool, XML_T('\0')))- return NULL;- id->prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),- sizeof(PREFIX));- if (id->prefix->name == poolStart(&dtd->pool))- poolFinish(&dtd->pool);- else- poolDiscard(&dtd->pool);- break;- }- }- }- }- return id;-}--#define CONTEXT_SEP XML_T(ASCII_FF)--static const XML_Char *-getContext(XML_Parser parser)-{- DTD * const dtd = _dtd; /* save one level of indirection */- HASH_TABLE_ITER iter;- XML_Bool needSep = XML_FALSE;-- if (dtd->defaultPrefix.binding) {- int i;- int len;- if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))- return NULL;- len = dtd->defaultPrefix.binding->uriLen;- if (namespaceSeparator)- len--;- for (i = 0; i < len; i++)- if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))- return NULL;- needSep = XML_TRUE;- }-- hashTableIterInit(&iter, &(dtd->prefixes));- for (;;) {- int i;- int len;- const XML_Char *s;- PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);- if (!prefix)- break;- if (!prefix->binding)- continue;- if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))- return NULL;- for (s = prefix->name; *s; s++)- if (!poolAppendChar(&tempPool, *s))- return NULL;- if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))- return NULL;- len = prefix->binding->uriLen;- if (namespaceSeparator)- len--;- for (i = 0; i < len; i++)- if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))- return NULL;- needSep = XML_TRUE;- }--- hashTableIterInit(&iter, &(dtd->generalEntities));- for (;;) {- const XML_Char *s;- ENTITY *e = (ENTITY *)hashTableIterNext(&iter);- if (!e)- break;- if (!e->open)- continue;- if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))- return NULL;- for (s = e->name; *s; s++)- if (!poolAppendChar(&tempPool, *s))- return 0;- needSep = XML_TRUE;- }-- if (!poolAppendChar(&tempPool, XML_T('\0')))- return NULL;- return tempPool.start;-}--static XML_Bool-setContext(XML_Parser parser, const XML_Char *context)-{- DTD * const dtd = _dtd; /* save one level of indirection */- const XML_Char *s = context;-- while (*context != XML_T('\0')) {- if (*s == CONTEXT_SEP || *s == XML_T('\0')) {- ENTITY *e;- if (!poolAppendChar(&tempPool, XML_T('\0')))- return XML_FALSE;- e = (ENTITY *)lookup(&dtd->generalEntities, poolStart(&tempPool), 0);- if (e)- e->open = XML_TRUE;- if (*s != XML_T('\0'))- s++;- context = s;- poolDiscard(&tempPool);- }- else if (*s == XML_T(ASCII_EQUALS)) {- PREFIX *prefix;- if (poolLength(&tempPool) == 0)- prefix = &dtd->defaultPrefix;- else {- if (!poolAppendChar(&tempPool, XML_T('\0')))- return XML_FALSE;- prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&tempPool),- sizeof(PREFIX));- if (!prefix)- return XML_FALSE;- if (prefix->name == poolStart(&tempPool)) {- prefix->name = poolCopyString(&dtd->pool, prefix->name);- if (!prefix->name)- return XML_FALSE;- }- poolDiscard(&tempPool);- }- for (context = s + 1;- *context != CONTEXT_SEP && *context != XML_T('\0');- context++)- if (!poolAppendChar(&tempPool, *context))- return XML_FALSE;- if (!poolAppendChar(&tempPool, XML_T('\0')))- return XML_FALSE;- if (addBinding(parser, prefix, NULL, poolStart(&tempPool),- &inheritedBindings) != XML_ERROR_NONE)- return XML_FALSE;- poolDiscard(&tempPool);- if (*context != XML_T('\0'))- ++context;- s = context;- }- else {- if (!poolAppendChar(&tempPool, *s))- return XML_FALSE;- s++;- }- }- return XML_TRUE;-}--static void FASTCALL-normalizePublicId(XML_Char *publicId)-{- XML_Char *p = publicId;- XML_Char *s;- for (s = publicId; *s; s++) {- switch (*s) {- case 0x20:- case 0xD:- case 0xA:- if (p != publicId && p[-1] != 0x20)- *p++ = 0x20;- break;- default:- *p++ = *s;- }- }- if (p != publicId && p[-1] == 0x20)- --p;- *p = XML_T('\0');-}--static DTD *-dtdCreate(const XML_Memory_Handling_Suite *ms)-{- DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));- if (p == NULL)- return p;- poolInit(&(p->pool), ms);- poolInit(&(p->entityValuePool), ms);- hashTableInit(&(p->generalEntities), ms);- hashTableInit(&(p->elementTypes), ms);- hashTableInit(&(p->attributeIds), ms);- hashTableInit(&(p->prefixes), ms);-#ifdef XML_DTD- p->paramEntityRead = XML_FALSE;- hashTableInit(&(p->paramEntities), ms);-#endif /* XML_DTD */- p->defaultPrefix.name = NULL;- p->defaultPrefix.binding = NULL;-- p->in_eldecl = XML_FALSE;- p->scaffIndex = NULL;- p->scaffold = NULL;- p->scaffLevel = 0;- p->scaffSize = 0;- p->scaffCount = 0;- p->contentStringLen = 0;-- p->keepProcessing = XML_TRUE;- p->hasParamEntityRefs = XML_FALSE;- p->standalone = XML_FALSE;- return p;-}--static void-dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)-{- HASH_TABLE_ITER iter;- hashTableIterInit(&iter, &(p->elementTypes));- for (;;) {- ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);- if (!e)- break;- if (e->allocDefaultAtts != 0)- ms->free_fcn(e->defaultAtts);- }- hashTableClear(&(p->generalEntities));-#ifdef XML_DTD- p->paramEntityRead = XML_FALSE;- hashTableClear(&(p->paramEntities));-#endif /* XML_DTD */- hashTableClear(&(p->elementTypes));- hashTableClear(&(p->attributeIds));- hashTableClear(&(p->prefixes));- poolClear(&(p->pool));- poolClear(&(p->entityValuePool));- p->defaultPrefix.name = NULL;- p->defaultPrefix.binding = NULL;-- p->in_eldecl = XML_FALSE;-- ms->free_fcn(p->scaffIndex);- p->scaffIndex = NULL;- ms->free_fcn(p->scaffold);- p->scaffold = NULL;-- p->scaffLevel = 0;- p->scaffSize = 0;- p->scaffCount = 0;- p->contentStringLen = 0;-- p->keepProcessing = XML_TRUE;- p->hasParamEntityRefs = XML_FALSE;- p->standalone = XML_FALSE;-}--static void-dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)-{- HASH_TABLE_ITER iter;- hashTableIterInit(&iter, &(p->elementTypes));- for (;;) {- ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);- if (!e)- break;- if (e->allocDefaultAtts != 0)- ms->free_fcn(e->defaultAtts);- }- hashTableDestroy(&(p->generalEntities));-#ifdef XML_DTD- hashTableDestroy(&(p->paramEntities));-#endif /* XML_DTD */- hashTableDestroy(&(p->elementTypes));- hashTableDestroy(&(p->attributeIds));- hashTableDestroy(&(p->prefixes));- poolDestroy(&(p->pool));- poolDestroy(&(p->entityValuePool));- if (isDocEntity) {- ms->free_fcn(p->scaffIndex);- ms->free_fcn(p->scaffold);- }- ms->free_fcn(p);-}--/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.- The new DTD has already been initialized.-*/-static int-dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)-{- HASH_TABLE_ITER iter;-- /* Copy the prefix table. */-- hashTableIterInit(&iter, &(oldDtd->prefixes));- for (;;) {- const XML_Char *name;- const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);- if (!oldP)- break;- name = poolCopyString(&(newDtd->pool), oldP->name);- if (!name)- return 0;- if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))- return 0;- }-- hashTableIterInit(&iter, &(oldDtd->attributeIds));-- /* Copy the attribute id table. */-- for (;;) {- ATTRIBUTE_ID *newA;- const XML_Char *name;- const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);-- if (!oldA)- break;- /* Remember to allocate the scratch byte before the name. */- if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))- return 0;- name = poolCopyString(&(newDtd->pool), oldA->name);- if (!name)- return 0;- ++name;- newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name,- sizeof(ATTRIBUTE_ID));- if (!newA)- return 0;- newA->maybeTokenized = oldA->maybeTokenized;- if (oldA->prefix) {- newA->xmlns = oldA->xmlns;- if (oldA->prefix == &oldDtd->defaultPrefix)- newA->prefix = &newDtd->defaultPrefix;- else- newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes),- oldA->prefix->name, 0);- }- }-- /* Copy the element type table. */-- hashTableIterInit(&iter, &(oldDtd->elementTypes));-- for (;;) {- int i;- ELEMENT_TYPE *newE;- const XML_Char *name;- const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);- if (!oldE)- break;- name = poolCopyString(&(newDtd->pool), oldE->name);- if (!name)- return 0;- newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name,- sizeof(ELEMENT_TYPE));- if (!newE)- return 0;- if (oldE->nDefaultAtts) {- newE->defaultAtts = (DEFAULT_ATTRIBUTE *)- ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));- if (!newE->defaultAtts) {- ms->free_fcn(newE);- return 0;- }- }- if (oldE->idAtt)- newE->idAtt = (ATTRIBUTE_ID *)- lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);- newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;- if (oldE->prefix)- newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes),- oldE->prefix->name, 0);- for (i = 0; i < newE->nDefaultAtts; i++) {- newE->defaultAtts[i].id = (ATTRIBUTE_ID *)- lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);- newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;- if (oldE->defaultAtts[i].value) {- newE->defaultAtts[i].value- = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);- if (!newE->defaultAtts[i].value)- return 0;- }- else- newE->defaultAtts[i].value = NULL;- }- }-- /* Copy the entity tables. */- if (!copyEntityTable(&(newDtd->generalEntities),- &(newDtd->pool),- &(oldDtd->generalEntities)))- return 0;--#ifdef XML_DTD- if (!copyEntityTable(&(newDtd->paramEntities),- &(newDtd->pool),- &(oldDtd->paramEntities)))- return 0;- newDtd->paramEntityRead = oldDtd->paramEntityRead;-#endif /* XML_DTD */-- newDtd->keepProcessing = oldDtd->keepProcessing;- newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;- newDtd->standalone = oldDtd->standalone;-- /* Don't want deep copying for scaffolding */- newDtd->in_eldecl = oldDtd->in_eldecl;- newDtd->scaffold = oldDtd->scaffold;- newDtd->contentStringLen = oldDtd->contentStringLen;- newDtd->scaffSize = oldDtd->scaffSize;- newDtd->scaffLevel = oldDtd->scaffLevel;- newDtd->scaffIndex = oldDtd->scaffIndex;-- return 1;-} /* End dtdCopy */--static int-copyEntityTable(HASH_TABLE *newTable,- STRING_POOL *newPool,- const HASH_TABLE *oldTable)-{- HASH_TABLE_ITER iter;- const XML_Char *cachedOldBase = NULL;- const XML_Char *cachedNewBase = NULL;-- hashTableIterInit(&iter, oldTable);-- for (;;) {- ENTITY *newE;- const XML_Char *name;- const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);- if (!oldE)- break;- name = poolCopyString(newPool, oldE->name);- if (!name)- return 0;- newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));- if (!newE)- return 0;- if (oldE->systemId) {- const XML_Char *tem = poolCopyString(newPool, oldE->systemId);- if (!tem)- return 0;- newE->systemId = tem;- if (oldE->base) {- if (oldE->base == cachedOldBase)- newE->base = cachedNewBase;- else {- cachedOldBase = oldE->base;- tem = poolCopyString(newPool, cachedOldBase);- if (!tem)- return 0;- cachedNewBase = newE->base = tem;- }- }- if (oldE->publicId) {- tem = poolCopyString(newPool, oldE->publicId);- if (!tem)- return 0;- newE->publicId = tem;- }- }- else {- const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,- oldE->textLen);- if (!tem)- return 0;- newE->textPtr = tem;- newE->textLen = oldE->textLen;- }- if (oldE->notation) {- const XML_Char *tem = poolCopyString(newPool, oldE->notation);- if (!tem)- return 0;- newE->notation = tem;- }- newE->is_param = oldE->is_param;- newE->is_internal = oldE->is_internal;- }- return 1;-}--#define INIT_POWER 6--static XML_Bool FASTCALL-keyeq(KEY s1, KEY s2)-{- for (; *s1 == *s2; s1++, s2++)- if (*s1 == 0)- return XML_TRUE;- return XML_FALSE;-}--static unsigned long FASTCALL-hash(KEY s)-{- unsigned long h = 0;- while (*s)- h = CHAR_HASH(h, *s++);- return h;-}--static NAMED *-lookup(HASH_TABLE *table, KEY name, size_t createSize)-{- size_t i;- if (table->size == 0) {- size_t tsize;- if (!createSize)- return NULL;- table->power = INIT_POWER;- /* table->size is a power of 2 */- table->size = (size_t)1 << INIT_POWER;- tsize = table->size * sizeof(NAMED *);- table->v = (NAMED **)table->mem->malloc_fcn(tsize);- if (!table->v) {- table->size = 0;- return NULL;- }- memset(table->v, 0, tsize);- i = hash(name) & ((unsigned long)table->size - 1);- }- else {- unsigned long h = hash(name);- unsigned long mask = (unsigned long)table->size - 1;- unsigned char step = 0;- i = h & mask;- while (table->v[i]) {- if (keyeq(name, table->v[i]->name))- return table->v[i];- if (!step)- step = PROBE_STEP(h, mask, table->power);- i < step ? (i += table->size - step) : (i -= step);- }- if (!createSize)- return NULL;-- /* check for overflow (table is half full) */- if (table->used >> (table->power - 1)) {- unsigned char newPower = table->power + 1;- size_t newSize = (size_t)1 << newPower;- unsigned long newMask = (unsigned long)newSize - 1;- size_t tsize = newSize * sizeof(NAMED *);- NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);- if (!newV)- return NULL;- memset(newV, 0, tsize);- for (i = 0; i < table->size; i++)- if (table->v[i]) {- unsigned long newHash = hash(table->v[i]->name);- size_t j = newHash & newMask;- step = 0;- while (newV[j]) {- if (!step)- step = PROBE_STEP(newHash, newMask, newPower);- j < step ? (j += newSize - step) : (j -= step);- }- newV[j] = table->v[i];- }- table->mem->free_fcn(table->v);- table->v = newV;- table->power = newPower;- table->size = newSize;- i = h & newMask;- step = 0;- while (table->v[i]) {- if (!step)- step = PROBE_STEP(h, newMask, newPower);- i < step ? (i += newSize - step) : (i -= step);- }- }- }- table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);- if (!table->v[i])- return NULL;- memset(table->v[i], 0, createSize);- table->v[i]->name = name;- (table->used)++;- return table->v[i];-}--static void FASTCALL-hashTableClear(HASH_TABLE *table)-{- size_t i;- for (i = 0; i < table->size; i++) {- table->mem->free_fcn(table->v[i]);- table->v[i] = NULL;- }- table->used = 0;-}--static void FASTCALL-hashTableDestroy(HASH_TABLE *table)-{- size_t i;- for (i = 0; i < table->size; i++)- table->mem->free_fcn(table->v[i]);- table->mem->free_fcn(table->v);-}--static void FASTCALL-hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)-{- p->power = 0;- p->size = 0;- p->used = 0;- p->v = NULL;- p->mem = ms;-}--static void FASTCALL-hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)-{- iter->p = table->v;- iter->end = iter->p + table->size;-}--static NAMED * FASTCALL-hashTableIterNext(HASH_TABLE_ITER *iter)-{- while (iter->p != iter->end) {- NAMED *tem = *(iter->p)++;- if (tem)- return tem;- }- return NULL;-}--static void FASTCALL-poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)-{- pool->blocks = NULL;- pool->freeBlocks = NULL;- pool->start = NULL;- pool->ptr = NULL;- pool->end = NULL;- pool->mem = ms;-}--static void FASTCALL-poolClear(STRING_POOL *pool)-{- if (!pool->freeBlocks)- pool->freeBlocks = pool->blocks;- else {- BLOCK *p = pool->blocks;- while (p) {- BLOCK *tem = p->next;- p->next = pool->freeBlocks;- pool->freeBlocks = p;- p = tem;- }- }- pool->blocks = NULL;- pool->start = NULL;- pool->ptr = NULL;- pool->end = NULL;-}--static void FASTCALL-poolDestroy(STRING_POOL *pool)-{- BLOCK *p = pool->blocks;- while (p) {- BLOCK *tem = p->next;- pool->mem->free_fcn(p);- p = tem;- }- p = pool->freeBlocks;- while (p) {- BLOCK *tem = p->next;- pool->mem->free_fcn(p);- p = tem;- }-}--static XML_Char *-poolAppend(STRING_POOL *pool, const ENCODING *enc,- const char *ptr, const char *end)-{- if (!pool->ptr && !poolGrow(pool))- return NULL;- for (;;) {- XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);- if (ptr == end)- break;- if (!poolGrow(pool))- return NULL;- }- return pool->start;-}--static const XML_Char * FASTCALL-poolCopyString(STRING_POOL *pool, const XML_Char *s)-{- do {- if (!poolAppendChar(pool, *s))- return NULL;- } while (*s++);- s = pool->start;- poolFinish(pool);- return s;-}--static const XML_Char *-poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)-{- if (!pool->ptr && !poolGrow(pool))- return NULL;- for (; n > 0; --n, s++) {- if (!poolAppendChar(pool, *s))- return NULL;- }- s = pool->start;- poolFinish(pool);- return s;-}--static const XML_Char * FASTCALL-poolAppendString(STRING_POOL *pool, const XML_Char *s)-{- while (*s) {- if (!poolAppendChar(pool, *s))- return NULL;- s++;- }- return pool->start;-}--static XML_Char *-poolStoreString(STRING_POOL *pool, const ENCODING *enc,- const char *ptr, const char *end)-{- if (!poolAppend(pool, enc, ptr, end))- return NULL;- if (pool->ptr == pool->end && !poolGrow(pool))- return NULL;- *(pool->ptr)++ = 0;- return pool->start;-}--static XML_Bool FASTCALL-poolGrow(STRING_POOL *pool)-{- if (pool->freeBlocks) {- if (pool->start == 0) {- pool->blocks = pool->freeBlocks;- pool->freeBlocks = pool->freeBlocks->next;- pool->blocks->next = NULL;- pool->start = pool->blocks->s;- pool->end = pool->start + pool->blocks->size;- pool->ptr = pool->start;- return XML_TRUE;- }- if (pool->end - pool->start < pool->freeBlocks->size) {- BLOCK *tem = pool->freeBlocks->next;- pool->freeBlocks->next = pool->blocks;- pool->blocks = pool->freeBlocks;- pool->freeBlocks = tem;- memcpy(pool->blocks->s, pool->start,- (pool->end - pool->start) * sizeof(XML_Char));- pool->ptr = pool->blocks->s + (pool->ptr - pool->start);- pool->start = pool->blocks->s;- pool->end = pool->start + pool->blocks->size;- return XML_TRUE;- }- }- if (pool->blocks && pool->start == pool->blocks->s) {- int blockSize = (int)(pool->end - pool->start)*2;- pool->blocks = (BLOCK *)- pool->mem->realloc_fcn(pool->blocks,- (offsetof(BLOCK, s)- + blockSize * sizeof(XML_Char)));- if (pool->blocks == NULL)- return XML_FALSE;- pool->blocks->size = blockSize;- pool->ptr = pool->blocks->s + (pool->ptr - pool->start);- pool->start = pool->blocks->s;- pool->end = pool->start + blockSize;- }- else {- BLOCK *tem;- int blockSize = (int)(pool->end - pool->start);- if (blockSize < INIT_BLOCK_SIZE)- blockSize = INIT_BLOCK_SIZE;- else- blockSize *= 2;- tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)- + blockSize * sizeof(XML_Char));- if (!tem)- return XML_FALSE;- tem->size = blockSize;- tem->next = pool->blocks;- pool->blocks = tem;- if (pool->ptr != pool->start)- memcpy(tem->s, pool->start,- (pool->ptr - pool->start) * sizeof(XML_Char));- pool->ptr = tem->s + (pool->ptr - pool->start);- pool->start = tem->s;- pool->end = tem->s + blockSize;- }- return XML_TRUE;-}--static int FASTCALL-nextScaffoldPart(XML_Parser parser)-{- DTD * const dtd = _dtd; /* save one level of indirection */- CONTENT_SCAFFOLD * me;- int next;-- if (!dtd->scaffIndex) {- dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));- if (!dtd->scaffIndex)- return -1;- dtd->scaffIndex[0] = 0;- }-- if (dtd->scaffCount >= dtd->scaffSize) {- CONTENT_SCAFFOLD *temp;- if (dtd->scaffold) {- temp = (CONTENT_SCAFFOLD *)- REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));- if (temp == NULL)- return -1;- dtd->scaffSize *= 2;- }- else {- temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS- * sizeof(CONTENT_SCAFFOLD));- if (temp == NULL)- return -1;- dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;- }- dtd->scaffold = temp;- }- next = dtd->scaffCount++;- me = &dtd->scaffold[next];- if (dtd->scaffLevel) {- CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];- if (parent->lastchild) {- dtd->scaffold[parent->lastchild].nextsib = next;- }- if (!parent->childcnt)- parent->firstchild = next;- parent->lastchild = next;- parent->childcnt++;- }- me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;- return next;-}--static void-build_node(XML_Parser parser,- int src_node,- XML_Content *dest,- XML_Content **contpos,- XML_Char **strpos)-{- DTD * const dtd = _dtd; /* save one level of indirection */- dest->type = dtd->scaffold[src_node].type;- dest->quant = dtd->scaffold[src_node].quant;- if (dest->type == XML_CTYPE_NAME) {- const XML_Char *src;- dest->name = *strpos;- src = dtd->scaffold[src_node].name;- for (;;) {- *(*strpos)++ = *src;- if (!*src)- break;- src++;- }- dest->numchildren = 0;- dest->children = NULL;- }- else {- unsigned int i;- int cn;- dest->numchildren = dtd->scaffold[src_node].childcnt;- dest->children = *contpos;- *contpos += dest->numchildren;- for (i = 0, cn = dtd->scaffold[src_node].firstchild;- i < dest->numchildren;- i++, cn = dtd->scaffold[cn].nextsib) {- build_node(parser, cn, &(dest->children[i]), contpos, strpos);- }- dest->name = NULL;- }-}--static XML_Content *-build_model (XML_Parser parser)-{- DTD * const dtd = _dtd; /* save one level of indirection */- XML_Content *ret;- XML_Content *cpos;- XML_Char * str;- int allocsize = (dtd->scaffCount * sizeof(XML_Content)- + (dtd->contentStringLen * sizeof(XML_Char)));-- ret = (XML_Content *)MALLOC(allocsize);- if (!ret)- return NULL;-- str = (XML_Char *) (&ret[dtd->scaffCount]);- cpos = &ret[1];-- build_node(parser, 0, ret, &cpos, &str);- return ret;-}--static ELEMENT_TYPE *-getElementType(XML_Parser parser,- const ENCODING *enc,- const char *ptr,- const char *end)-{- DTD * const dtd = _dtd; /* save one level of indirection */- const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);- ELEMENT_TYPE *ret;-- if (!name)- return NULL;- ret = (ELEMENT_TYPE *) lookup(&dtd->elementTypes, name, sizeof(ELEMENT_TYPE));++ 77fea421d361dca90041d0040ecf1dca651167fadf2af79e990e35168d70d933 (2.2.1+)+*/++#define _GNU_SOURCE /* syscall prototype */++#include <stddef.h>+#include <string.h> /* memset(), memcpy() */+#include <assert.h>+#include <limits.h> /* UINT_MAX */+#include <stdio.h> /* fprintf */+#include <stdlib.h> /* getenv */++#ifdef _WIN32+#define getpid GetCurrentProcessId+#else+#include <sys/time.h> /* gettimeofday() */+#include <sys/types.h> /* getpid() */+#include <unistd.h> /* getpid() */+#endif++#define XML_BUILDING_EXPAT 1++#ifdef _WIN32+#include "winconfig.h"+#elif defined(HAVE_EXPAT_CONFIG_H)+#include <expat_config.h>+#endif /* ndef _WIN32 */++#include "ascii.h"+#include "expat.h"+#include "siphash.h"++#ifdef XML_UNICODE+#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX+#define XmlConvert XmlUtf16Convert+#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding+#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS+#define XmlEncode XmlUtf16Encode+/* Using pointer subtraction to convert to integer type. */+#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))+typedef unsigned short ICHAR;+#else+#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX+#define XmlConvert XmlUtf8Convert+#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding+#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS+#define XmlEncode XmlUtf8Encode+#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)+typedef char ICHAR;+#endif+++#ifndef XML_NS++#define XmlInitEncodingNS XmlInitEncoding+#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding+#undef XmlGetInternalEncodingNS+#define XmlGetInternalEncodingNS XmlGetInternalEncoding+#define XmlParseXmlDeclNS XmlParseXmlDecl++#endif++#ifdef XML_UNICODE++#ifdef XML_UNICODE_WCHAR_T+#define XML_T(x) (const wchar_t)x+#define XML_L(x) L ## x+#else+#define XML_T(x) (const unsigned short)x+#define XML_L(x) x+#endif++#else++#define XML_T(x) x+#define XML_L(x) x++#endif++/* Round up n to be a multiple of sz, where sz is a power of 2. */+#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))++/* Handle the case where memmove() doesn't exist. */+#ifndef HAVE_MEMMOVE+#ifdef HAVE_BCOPY+#define memmove(d,s,l) bcopy((s),(d),(l))+#else+#error memmove does not exist on this platform, nor is a substitute available+#endif /* HAVE_BCOPY */+#endif /* HAVE_MEMMOVE */++#include "internal.h"+#include "xmltok.h"+#include "xmlrole.h"++typedef const XML_Char *KEY;++typedef struct {+ KEY name;+} NAMED;++typedef struct {+ NAMED **v;+ unsigned char power;+ size_t size;+ size_t used;+ const XML_Memory_Handling_Suite *mem;+} HASH_TABLE;++static size_t+keylen(KEY s);++static void+copy_salt_to_sipkey(XML_Parser parser, struct sipkey * key);++/* For probing (after a collision) we need a step size relative prime+ to the hash table size, which is a power of 2. We use double-hashing,+ since we can calculate a second hash value cheaply by taking those bits+ of the first hash value that were discarded (masked out) when the table+ index was calculated: index = hash & mask, where mask = table->size - 1.+ We limit the maximum step size to table->size / 4 (mask >> 2) and make+ it odd, since odd numbers are always relative prime to a power of 2.+*/+#define SECOND_HASH(hash, mask, power) \+ ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))+#define PROBE_STEP(hash, mask, power) \+ ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))++typedef struct {+ NAMED **p;+ NAMED **end;+} HASH_TABLE_ITER;++#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */+#define INIT_DATA_BUF_SIZE 1024+#define INIT_ATTS_SIZE 16+#define INIT_ATTS_VERSION 0xFFFFFFFF+#define INIT_BLOCK_SIZE 1024+#define INIT_BUFFER_SIZE 1024++#define EXPAND_SPARE 24++typedef struct binding {+ struct prefix *prefix;+ struct binding *nextTagBinding;+ struct binding *prevPrefixBinding;+ const struct attribute_id *attId;+ XML_Char *uri;+ int uriLen;+ int uriAlloc;+} BINDING;++typedef struct prefix {+ const XML_Char *name;+ BINDING *binding;+} PREFIX;++typedef struct {+ const XML_Char *str;+ const XML_Char *localPart;+ const XML_Char *prefix;+ int strLen;+ int uriLen;+ int prefixLen;+} TAG_NAME;++/* TAG represents an open element.+ The name of the element is stored in both the document and API+ encodings. The memory buffer 'buf' is a separately-allocated+ memory area which stores the name. During the XML_Parse()/+ XMLParseBuffer() when the element is open, the memory for the 'raw'+ version of the name (in the document encoding) is shared with the+ document buffer. If the element is open across calls to+ XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to+ contain the 'raw' name as well.++ A parser re-uses these structures, maintaining a list of allocated+ TAG objects in a free list.+*/+typedef struct tag {+ struct tag *parent; /* parent of this element */+ const char *rawName; /* tagName in the original encoding */+ int rawNameLength;+ TAG_NAME name; /* tagName in the API encoding */+ char *buf; /* buffer for name components */+ char *bufEnd; /* end of the buffer */+ BINDING *bindings;+} TAG;++typedef struct {+ const XML_Char *name;+ const XML_Char *textPtr;+ int textLen; /* length in XML_Chars */+ int processed; /* # of processed bytes - when suspended */+ const XML_Char *systemId;+ const XML_Char *base;+ const XML_Char *publicId;+ const XML_Char *notation;+ XML_Bool open;+ XML_Bool is_param;+ XML_Bool is_internal; /* true if declared in internal subset outside PE */+} ENTITY;++typedef struct {+ enum XML_Content_Type type;+ enum XML_Content_Quant quant;+ const XML_Char * name;+ int firstchild;+ int lastchild;+ int childcnt;+ int nextsib;+} CONTENT_SCAFFOLD;++#define INIT_SCAFFOLD_ELEMENTS 32++typedef struct block {+ struct block *next;+ int size;+ XML_Char s[1];+} BLOCK;++typedef struct {+ BLOCK *blocks;+ BLOCK *freeBlocks;+ const XML_Char *end;+ XML_Char *ptr;+ XML_Char *start;+ const XML_Memory_Handling_Suite *mem;+} STRING_POOL;++/* The XML_Char before the name is used to determine whether+ an attribute has been specified. */+typedef struct attribute_id {+ XML_Char *name;+ PREFIX *prefix;+ XML_Bool maybeTokenized;+ XML_Bool xmlns;+} ATTRIBUTE_ID;++typedef struct {+ const ATTRIBUTE_ID *id;+ XML_Bool isCdata;+ const XML_Char *value;+} DEFAULT_ATTRIBUTE;++typedef struct {+ unsigned long version;+ unsigned long hash;+ const XML_Char *uriName;+} NS_ATT;++typedef struct {+ const XML_Char *name;+ PREFIX *prefix;+ const ATTRIBUTE_ID *idAtt;+ int nDefaultAtts;+ int allocDefaultAtts;+ DEFAULT_ATTRIBUTE *defaultAtts;+} ELEMENT_TYPE;++typedef struct {+ HASH_TABLE generalEntities;+ HASH_TABLE elementTypes;+ HASH_TABLE attributeIds;+ HASH_TABLE prefixes;+ STRING_POOL pool;+ STRING_POOL entityValuePool;+ /* false once a parameter entity reference has been skipped */+ XML_Bool keepProcessing;+ /* true once an internal or external PE reference has been encountered;+ this includes the reference to an external subset */+ XML_Bool hasParamEntityRefs;+ XML_Bool standalone;+#ifdef XML_DTD+ /* indicates if external PE has been read */+ XML_Bool paramEntityRead;+ HASH_TABLE paramEntities;+#endif /* XML_DTD */+ PREFIX defaultPrefix;+ /* === scaffolding for building content model === */+ XML_Bool in_eldecl;+ CONTENT_SCAFFOLD *scaffold;+ unsigned contentStringLen;+ unsigned scaffSize;+ unsigned scaffCount;+ int scaffLevel;+ int *scaffIndex;+} DTD;++typedef struct open_internal_entity {+ const char *internalEventPtr;+ const char *internalEventEndPtr;+ struct open_internal_entity *next;+ ENTITY *entity;+ int startTagLevel;+ XML_Bool betweenDecl; /* WFC: PE Between Declarations */+} OPEN_INTERNAL_ENTITY;++typedef enum XML_Error PTRCALL Processor(XML_Parser parser,+ const char *start,+ const char *end,+ const char **endPtr);++static Processor prologProcessor;+static Processor prologInitProcessor;+static Processor contentProcessor;+static Processor cdataSectionProcessor;+#ifdef XML_DTD+static Processor ignoreSectionProcessor;+static Processor externalParEntProcessor;+static Processor externalParEntInitProcessor;+static Processor entityValueProcessor;+static Processor entityValueInitProcessor;+#endif /* XML_DTD */+static Processor epilogProcessor;+static Processor errorProcessor;+static Processor externalEntityInitProcessor;+static Processor externalEntityInitProcessor2;+static Processor externalEntityInitProcessor3;+static Processor externalEntityContentProcessor;+static Processor internalEntityProcessor;++static enum XML_Error+handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);+static enum XML_Error+processXmlDecl(XML_Parser parser, int isGeneralTextEntity,+ const char *s, const char *next);+static enum XML_Error+initializeEncoding(XML_Parser parser);+static enum XML_Error+doProlog(XML_Parser parser, const ENCODING *enc, const char *s,+ const char *end, int tok, const char *next, const char **nextPtr,+ XML_Bool haveMore);+static enum XML_Error+processInternalEntity(XML_Parser parser, ENTITY *entity,+ XML_Bool betweenDecl);+static enum XML_Error+doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,+ const char *start, const char *end, const char **endPtr,+ XML_Bool haveMore);+static enum XML_Error+doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,+ const char *end, const char **nextPtr, XML_Bool haveMore);+#ifdef XML_DTD+static enum XML_Error+doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,+ const char *end, const char **nextPtr, XML_Bool haveMore);+#endif /* XML_DTD */++static void+freeBindings(XML_Parser parser, BINDING *bindings);+static enum XML_Error+storeAtts(XML_Parser parser, const ENCODING *, const char *s,+ TAG_NAME *tagNamePtr, BINDING **bindingsPtr);+static enum XML_Error+addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,+ const XML_Char *uri, BINDING **bindingsPtr);+static int+defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,+ XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);+static enum XML_Error+storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,+ const char *, const char *, STRING_POOL *);+static enum XML_Error+appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,+ const char *, const char *, STRING_POOL *);+static ATTRIBUTE_ID *+getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,+ const char *end);+static int+setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);+static enum XML_Error+storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,+ const char *end);+static int+reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,+ const char *start, const char *end);+static int+reportComment(XML_Parser parser, const ENCODING *enc, const char *start,+ const char *end);+static void+reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,+ const char *end);++static const XML_Char * getContext(XML_Parser parser);+static XML_Bool+setContext(XML_Parser parser, const XML_Char *context);++static void FASTCALL normalizePublicId(XML_Char *s);++static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);+/* do not call if parentParser != NULL */+static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);+static void+dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);+static int+dtdCopy(XML_Parser oldParser,+ DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);+static int+copyEntityTable(XML_Parser oldParser,+ HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);+static NAMED *+lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize);+static void FASTCALL+hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);+static void FASTCALL hashTableClear(HASH_TABLE *);+static void FASTCALL hashTableDestroy(HASH_TABLE *);+static void FASTCALL+hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);+static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);++static void FASTCALL+poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);+static void FASTCALL poolClear(STRING_POOL *);+static void FASTCALL poolDestroy(STRING_POOL *);+static XML_Char *+poolAppend(STRING_POOL *pool, const ENCODING *enc,+ const char *ptr, const char *end);+static XML_Char *+poolStoreString(STRING_POOL *pool, const ENCODING *enc,+ const char *ptr, const char *end);+static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);+static const XML_Char * FASTCALL+poolCopyString(STRING_POOL *pool, const XML_Char *s);+static const XML_Char *+poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);+static const XML_Char * FASTCALL+poolAppendString(STRING_POOL *pool, const XML_Char *s);++static int FASTCALL nextScaffoldPart(XML_Parser parser);+static XML_Content * build_model(XML_Parser parser);+static ELEMENT_TYPE *+getElementType(XML_Parser parser, const ENCODING *enc,+ const char *ptr, const char *end);++static unsigned long generate_hash_secret_salt(XML_Parser parser);+static XML_Bool startParsing(XML_Parser parser);++static XML_Parser+parserCreate(const XML_Char *encodingName,+ const XML_Memory_Handling_Suite *memsuite,+ const XML_Char *nameSep,+ DTD *dtd);++static void+parserInit(XML_Parser parser, const XML_Char *encodingName);++#define poolStart(pool) ((pool)->start)+#define poolEnd(pool) ((pool)->ptr)+#define poolLength(pool) ((pool)->ptr - (pool)->start)+#define poolChop(pool) ((void)--(pool->ptr))+#define poolLastChar(pool) (((pool)->ptr)[-1])+#define poolDiscard(pool) ((pool)->ptr = (pool)->start)+#define poolFinish(pool) ((pool)->start = (pool)->ptr)+#define poolAppendChar(pool, c) \+ (((pool)->ptr == (pool)->end && !poolGrow(pool)) \+ ? 0 \+ : ((*((pool)->ptr)++ = c), 1))++struct XML_ParserStruct {+ /* The first member must be userData so that the XML_GetUserData+ macro works. */+ void *m_userData;+ void *m_handlerArg;+ char *m_buffer;+ const XML_Memory_Handling_Suite m_mem;+ /* first character to be parsed */+ const char *m_bufferPtr;+ /* past last character to be parsed */+ char *m_bufferEnd;+ /* allocated end of buffer */+ const char *m_bufferLim;+ XML_Index m_parseEndByteIndex;+ const char *m_parseEndPtr;+ XML_Char *m_dataBuf;+ XML_Char *m_dataBufEnd;+ XML_StartElementHandler m_startElementHandler;+ XML_EndElementHandler m_endElementHandler;+ XML_CharacterDataHandler m_characterDataHandler;+ XML_ProcessingInstructionHandler m_processingInstructionHandler;+ XML_CommentHandler m_commentHandler;+ XML_StartCdataSectionHandler m_startCdataSectionHandler;+ XML_EndCdataSectionHandler m_endCdataSectionHandler;+ XML_DefaultHandler m_defaultHandler;+ XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;+ XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;+ XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;+ XML_NotationDeclHandler m_notationDeclHandler;+ XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;+ XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;+ XML_NotStandaloneHandler m_notStandaloneHandler;+ XML_ExternalEntityRefHandler m_externalEntityRefHandler;+ XML_Parser m_externalEntityRefHandlerArg;+ XML_SkippedEntityHandler m_skippedEntityHandler;+ XML_UnknownEncodingHandler m_unknownEncodingHandler;+ XML_ElementDeclHandler m_elementDeclHandler;+ XML_AttlistDeclHandler m_attlistDeclHandler;+ XML_EntityDeclHandler m_entityDeclHandler;+ XML_XmlDeclHandler m_xmlDeclHandler;+ const ENCODING *m_encoding;+ INIT_ENCODING m_initEncoding;+ const ENCODING *m_internalEncoding;+ const XML_Char *m_protocolEncodingName;+ XML_Bool m_ns;+ XML_Bool m_ns_triplets;+ void *m_unknownEncodingMem;+ void *m_unknownEncodingData;+ void *m_unknownEncodingHandlerData;+ void (XMLCALL *m_unknownEncodingRelease)(void *);+ PROLOG_STATE m_prologState;+ Processor *m_processor;+ enum XML_Error m_errorCode;+ const char *m_eventPtr;+ const char *m_eventEndPtr;+ const char *m_positionPtr;+ OPEN_INTERNAL_ENTITY *m_openInternalEntities;+ OPEN_INTERNAL_ENTITY *m_freeInternalEntities;+ XML_Bool m_defaultExpandInternalEntities;+ int m_tagLevel;+ ENTITY *m_declEntity;+ const XML_Char *m_doctypeName;+ const XML_Char *m_doctypeSysid;+ const XML_Char *m_doctypePubid;+ const XML_Char *m_declAttributeType;+ const XML_Char *m_declNotationName;+ const XML_Char *m_declNotationPublicId;+ ELEMENT_TYPE *m_declElementType;+ ATTRIBUTE_ID *m_declAttributeId;+ XML_Bool m_declAttributeIsCdata;+ XML_Bool m_declAttributeIsId;+ DTD *m_dtd;+ const XML_Char *m_curBase;+ TAG *m_tagStack;+ TAG *m_freeTagList;+ BINDING *m_inheritedBindings;+ BINDING *m_freeBindingList;+ int m_attsSize;+ int m_nSpecifiedAtts;+ int m_idAttIndex;+ ATTRIBUTE *m_atts;+ NS_ATT *m_nsAtts;+ unsigned long m_nsAttsVersion;+ unsigned char m_nsAttsPower;+#ifdef XML_ATTR_INFO+ XML_AttrInfo *m_attInfo;+#endif+ POSITION m_position;+ STRING_POOL m_tempPool;+ STRING_POOL m_temp2Pool;+ char *m_groupConnector;+ unsigned int m_groupSize;+ XML_Char m_namespaceSeparator;+ XML_Parser m_parentParser;+ XML_ParsingStatus m_parsingStatus;+#ifdef XML_DTD+ XML_Bool m_isParamEntity;+ XML_Bool m_useForeignDTD;+ enum XML_ParamEntityParsing m_paramEntityParsing;+#endif+ unsigned long m_hash_secret_salt;+};++#define MALLOC(s) (parser->m_mem.malloc_fcn((s)))+#define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))+#define FREE(p) (parser->m_mem.free_fcn((p)))++#define userData (parser->m_userData)+#define handlerArg (parser->m_handlerArg)+#define startElementHandler (parser->m_startElementHandler)+#define endElementHandler (parser->m_endElementHandler)+#define characterDataHandler (parser->m_characterDataHandler)+#define processingInstructionHandler \+ (parser->m_processingInstructionHandler)+#define commentHandler (parser->m_commentHandler)+#define startCdataSectionHandler \+ (parser->m_startCdataSectionHandler)+#define endCdataSectionHandler (parser->m_endCdataSectionHandler)+#define defaultHandler (parser->m_defaultHandler)+#define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)+#define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)+#define unparsedEntityDeclHandler \+ (parser->m_unparsedEntityDeclHandler)+#define notationDeclHandler (parser->m_notationDeclHandler)+#define startNamespaceDeclHandler \+ (parser->m_startNamespaceDeclHandler)+#define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)+#define notStandaloneHandler (parser->m_notStandaloneHandler)+#define externalEntityRefHandler \+ (parser->m_externalEntityRefHandler)+#define externalEntityRefHandlerArg \+ (parser->m_externalEntityRefHandlerArg)+#define internalEntityRefHandler \+ (parser->m_internalEntityRefHandler)+#define skippedEntityHandler (parser->m_skippedEntityHandler)+#define unknownEncodingHandler (parser->m_unknownEncodingHandler)+#define elementDeclHandler (parser->m_elementDeclHandler)+#define attlistDeclHandler (parser->m_attlistDeclHandler)+#define entityDeclHandler (parser->m_entityDeclHandler)+#define xmlDeclHandler (parser->m_xmlDeclHandler)+#define encoding (parser->m_encoding)+#define initEncoding (parser->m_initEncoding)+#define internalEncoding (parser->m_internalEncoding)+#define unknownEncodingMem (parser->m_unknownEncodingMem)+#define unknownEncodingData (parser->m_unknownEncodingData)+#define unknownEncodingHandlerData \+ (parser->m_unknownEncodingHandlerData)+#define unknownEncodingRelease (parser->m_unknownEncodingRelease)+#define protocolEncodingName (parser->m_protocolEncodingName)+#define ns (parser->m_ns)+#define ns_triplets (parser->m_ns_triplets)+#define prologState (parser->m_prologState)+#define processor (parser->m_processor)+#define errorCode (parser->m_errorCode)+#define eventPtr (parser->m_eventPtr)+#define eventEndPtr (parser->m_eventEndPtr)+#define positionPtr (parser->m_positionPtr)+#define position (parser->m_position)+#define openInternalEntities (parser->m_openInternalEntities)+#define freeInternalEntities (parser->m_freeInternalEntities)+#define defaultExpandInternalEntities \+ (parser->m_defaultExpandInternalEntities)+#define tagLevel (parser->m_tagLevel)+#define buffer (parser->m_buffer)+#define bufferPtr (parser->m_bufferPtr)+#define bufferEnd (parser->m_bufferEnd)+#define parseEndByteIndex (parser->m_parseEndByteIndex)+#define parseEndPtr (parser->m_parseEndPtr)+#define bufferLim (parser->m_bufferLim)+#define dataBuf (parser->m_dataBuf)+#define dataBufEnd (parser->m_dataBufEnd)+#define _dtd (parser->m_dtd)+#define curBase (parser->m_curBase)+#define declEntity (parser->m_declEntity)+#define doctypeName (parser->m_doctypeName)+#define doctypeSysid (parser->m_doctypeSysid)+#define doctypePubid (parser->m_doctypePubid)+#define declAttributeType (parser->m_declAttributeType)+#define declNotationName (parser->m_declNotationName)+#define declNotationPublicId (parser->m_declNotationPublicId)+#define declElementType (parser->m_declElementType)+#define declAttributeId (parser->m_declAttributeId)+#define declAttributeIsCdata (parser->m_declAttributeIsCdata)+#define declAttributeIsId (parser->m_declAttributeIsId)+#define freeTagList (parser->m_freeTagList)+#define freeBindingList (parser->m_freeBindingList)+#define inheritedBindings (parser->m_inheritedBindings)+#define tagStack (parser->m_tagStack)+#define atts (parser->m_atts)+#define attsSize (parser->m_attsSize)+#define nSpecifiedAtts (parser->m_nSpecifiedAtts)+#define idAttIndex (parser->m_idAttIndex)+#define nsAtts (parser->m_nsAtts)+#define nsAttsVersion (parser->m_nsAttsVersion)+#define nsAttsPower (parser->m_nsAttsPower)+#define attInfo (parser->m_attInfo)+#define tempPool (parser->m_tempPool)+#define temp2Pool (parser->m_temp2Pool)+#define groupConnector (parser->m_groupConnector)+#define groupSize (parser->m_groupSize)+#define namespaceSeparator (parser->m_namespaceSeparator)+#define parentParser (parser->m_parentParser)+#define ps_parsing (parser->m_parsingStatus.parsing)+#define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)+#ifdef XML_DTD+#define isParamEntity (parser->m_isParamEntity)+#define useForeignDTD (parser->m_useForeignDTD)+#define paramEntityParsing (parser->m_paramEntityParsing)+#endif /* XML_DTD */+#define hash_secret_salt (parser->m_hash_secret_salt)++XML_Parser XMLCALL+XML_ParserCreate(const XML_Char *encodingName)+{+ return XML_ParserCreate_MM(encodingName, NULL, NULL);+}++XML_Parser XMLCALL+XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)+{+ XML_Char tmp[2];+ *tmp = nsSep;+ return XML_ParserCreate_MM(encodingName, NULL, tmp);+}++static const XML_Char implicitContext[] = {+ ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p,+ ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w,+ ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g,+ ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9,+ ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e,+ ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'+};+++#if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)+# include <errno.h>++# if defined(HAVE_GETRANDOM)+# include <sys/random.h> /* getrandom */+# else+# include <unistd.h> /* syscall */+# include <sys/syscall.h> /* SYS_getrandom */+# endif++/* Obtain entropy on Linux 3.17+ */+static int+writeRandomBytes_getrandom(void * target, size_t count) {+ int success = 0; /* full count bytes written? */+ size_t bytesWrittenTotal = 0;+ const unsigned int getrandomFlags = 0;++ do {+ void * const currentTarget = (void*)((char*)target + bytesWrittenTotal);+ const size_t bytesToWrite = count - bytesWrittenTotal;++ const int bytesWrittenMore =+#if defined(HAVE_GETRANDOM)+ getrandom(currentTarget, bytesToWrite, getrandomFlags);+#else+ syscall(SYS_getrandom, currentTarget, bytesToWrite, getrandomFlags);+#endif++ if (bytesWrittenMore > 0) {+ bytesWrittenTotal += bytesWrittenMore;+ if (bytesWrittenTotal >= count)+ success = 1;+ }+ } while (! success && (errno == EINTR || errno == EAGAIN));++ return success;+}++#endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */+++#ifdef _WIN32++typedef BOOLEAN (APIENTRY *RTLGENRANDOM_FUNC)(PVOID, ULONG);++/* Obtain entropy on Windows XP / Windows Server 2003 and later.+ * Hint on RtlGenRandom and the following article from libsodioum.+ *+ * Michael Howard: Cryptographically Secure Random number on Windows without using CryptoAPI+ * https://blogs.msdn.microsoft.com/michael_howard/2005/01/14/cryptographically-secure-random-number-on-windows-without-using-cryptoapi/+ */+static int+writeRandomBytes_RtlGenRandom(void * target, size_t count) {+ int success = 0; /* full count bytes written? */+ const HMODULE advapi32 = LoadLibrary("ADVAPI32.DLL");++ if (advapi32) {+ const RTLGENRANDOM_FUNC RtlGenRandom+ = (RTLGENRANDOM_FUNC)GetProcAddress(advapi32, "SystemFunction036");+ if (RtlGenRandom) {+ if (RtlGenRandom((PVOID)target, (ULONG)count) == TRUE) {+ success = 1;+ }+ }+ FreeLibrary(advapi32);+ }++ return success;+}++#endif /* _WIN32 */+++static unsigned long+gather_time_entropy(void)+{+#ifdef _WIN32+ FILETIME ft;+ GetSystemTimeAsFileTime(&ft); /* never fails */+ return ft.dwHighDateTime ^ ft.dwLowDateTime;+#else+ struct timeval tv;+ int gettimeofday_res;++ gettimeofday_res = gettimeofday(&tv, NULL);+ assert (gettimeofday_res == 0);++ /* Microseconds time is <20 bits entropy */+ return tv.tv_usec;+#endif+}++#if defined(HAVE_ARC4RANDOM_BUF) && defined(HAVE_LIBBSD)+# include <bsd/stdlib.h>+#endif++static unsigned long+ENTROPY_DEBUG(const char * label, unsigned long entropy) {+ const char * const EXPAT_ENTROPY_DEBUG = getenv("EXPAT_ENTROPY_DEBUG");+ if (EXPAT_ENTROPY_DEBUG && ! strcmp(EXPAT_ENTROPY_DEBUG, "1")) {+ fprintf(stderr, "Entropy: %s --> 0x%0*lx (%lu bytes)\n",+ label,+ (int)sizeof(entropy) * 2, entropy,+ (unsigned long)sizeof(entropy));+ }+ return entropy;+}++static unsigned long+generate_hash_secret_salt(XML_Parser parser)+{+ unsigned long entropy;+ (void)parser;+#if defined(HAVE_ARC4RANDOM_BUF) || defined(__CloudABI__)+ (void)gather_time_entropy;+ arc4random_buf(&entropy, sizeof(entropy));+ return ENTROPY_DEBUG("arc4random_buf", entropy);+#else+ /* Try high quality providers first .. */+#ifdef _WIN32+ if (writeRandomBytes_RtlGenRandom((void *)&entropy, sizeof(entropy))) {+ return ENTROPY_DEBUG("RtlGenRandom", entropy);+ }+#elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)+ if (writeRandomBytes_getrandom((void *)&entropy, sizeof(entropy))) {+ return ENTROPY_DEBUG("getrandom", entropy);+ }+#endif+ /* .. and self-made low quality for backup: */++ /* Process ID is 0 bits entropy if attacker has local access */+ entropy = gather_time_entropy() ^ getpid();++ /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */+ if (sizeof(unsigned long) == 4) {+ return ENTROPY_DEBUG("fallback(4)", entropy * 2147483647);+ } else {+ return ENTROPY_DEBUG("fallback(8)",+ entropy * (unsigned long)2305843009213693951);+ }+#endif+}++static unsigned long+get_hash_secret_salt(XML_Parser parser) {+ if (parser->m_parentParser != NULL)+ return get_hash_secret_salt(parser->m_parentParser);+ return parser->m_hash_secret_salt;+}++static XML_Bool /* only valid for root parser */+startParsing(XML_Parser parser)+{+ /* hash functions must be initialized before setContext() is called */+ if (hash_secret_salt == 0)+ hash_secret_salt = generate_hash_secret_salt(parser);+ if (ns) {+ /* implicit context only set for root parser, since child+ parsers (i.e. external entity parsers) will inherit it+ */+ return setContext(parser, implicitContext);+ }+ return XML_TRUE;+}++XML_Parser XMLCALL+XML_ParserCreate_MM(const XML_Char *encodingName,+ const XML_Memory_Handling_Suite *memsuite,+ const XML_Char *nameSep)+{+ return parserCreate(encodingName, memsuite, nameSep, NULL);+}++static XML_Parser+parserCreate(const XML_Char *encodingName,+ const XML_Memory_Handling_Suite *memsuite,+ const XML_Char *nameSep,+ DTD *dtd)+{+ XML_Parser parser;++ if (memsuite) {+ XML_Memory_Handling_Suite *mtemp;+ parser = (XML_Parser)+ memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));+ if (parser != NULL) {+ mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);+ mtemp->malloc_fcn = memsuite->malloc_fcn;+ mtemp->realloc_fcn = memsuite->realloc_fcn;+ mtemp->free_fcn = memsuite->free_fcn;+ }+ }+ else {+ XML_Memory_Handling_Suite *mtemp;+ parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));+ if (parser != NULL) {+ mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);+ mtemp->malloc_fcn = malloc;+ mtemp->realloc_fcn = realloc;+ mtemp->free_fcn = free;+ }+ }++ if (!parser)+ return parser;++ buffer = NULL;+ bufferLim = NULL;++ attsSize = INIT_ATTS_SIZE;+ atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));+ if (atts == NULL) {+ FREE(parser);+ return NULL;+ }+#ifdef XML_ATTR_INFO+ attInfo = (XML_AttrInfo*)MALLOC(attsSize * sizeof(XML_AttrInfo));+ if (attInfo == NULL) {+ FREE(atts);+ FREE(parser);+ return NULL;+ }+#endif+ dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));+ if (dataBuf == NULL) {+ FREE(atts);+#ifdef XML_ATTR_INFO+ FREE(attInfo);+#endif+ FREE(parser);+ return NULL;+ }+ dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;++ if (dtd)+ _dtd = dtd;+ else {+ _dtd = dtdCreate(&parser->m_mem);+ if (_dtd == NULL) {+ FREE(dataBuf);+ FREE(atts);+#ifdef XML_ATTR_INFO+ FREE(attInfo);+#endif+ FREE(parser);+ return NULL;+ }+ }++ freeBindingList = NULL;+ freeTagList = NULL;+ freeInternalEntities = NULL;++ groupSize = 0;+ groupConnector = NULL;++ unknownEncodingHandler = NULL;+ unknownEncodingHandlerData = NULL;++ namespaceSeparator = ASCII_EXCL;+ ns = XML_FALSE;+ ns_triplets = XML_FALSE;++ nsAtts = NULL;+ nsAttsVersion = 0;+ nsAttsPower = 0;++ poolInit(&tempPool, &(parser->m_mem));+ poolInit(&temp2Pool, &(parser->m_mem));+ parserInit(parser, encodingName);++ if (encodingName && !protocolEncodingName) {+ XML_ParserFree(parser);+ return NULL;+ }++ if (nameSep) {+ ns = XML_TRUE;+ internalEncoding = XmlGetInternalEncodingNS();+ namespaceSeparator = *nameSep;+ }+ else {+ internalEncoding = XmlGetInternalEncoding();+ }++ return parser;+}++static void+parserInit(XML_Parser parser, const XML_Char *encodingName)+{+ processor = prologInitProcessor;+ XmlPrologStateInit(&prologState);+ protocolEncodingName = (encodingName != NULL+ ? poolCopyString(&tempPool, encodingName)+ : NULL);+ curBase = NULL;+ XmlInitEncoding(&initEncoding, &encoding, 0);+ userData = NULL;+ handlerArg = NULL;+ startElementHandler = NULL;+ endElementHandler = NULL;+ characterDataHandler = NULL;+ processingInstructionHandler = NULL;+ commentHandler = NULL;+ startCdataSectionHandler = NULL;+ endCdataSectionHandler = NULL;+ defaultHandler = NULL;+ startDoctypeDeclHandler = NULL;+ endDoctypeDeclHandler = NULL;+ unparsedEntityDeclHandler = NULL;+ notationDeclHandler = NULL;+ startNamespaceDeclHandler = NULL;+ endNamespaceDeclHandler = NULL;+ notStandaloneHandler = NULL;+ externalEntityRefHandler = NULL;+ externalEntityRefHandlerArg = parser;+ skippedEntityHandler = NULL;+ elementDeclHandler = NULL;+ attlistDeclHandler = NULL;+ entityDeclHandler = NULL;+ xmlDeclHandler = NULL;+ bufferPtr = buffer;+ bufferEnd = buffer;+ parseEndByteIndex = 0;+ parseEndPtr = NULL;+ declElementType = NULL;+ declAttributeId = NULL;+ declEntity = NULL;+ doctypeName = NULL;+ doctypeSysid = NULL;+ doctypePubid = NULL;+ declAttributeType = NULL;+ declNotationName = NULL;+ declNotationPublicId = NULL;+ declAttributeIsCdata = XML_FALSE;+ declAttributeIsId = XML_FALSE;+ memset(&position, 0, sizeof(POSITION));+ errorCode = XML_ERROR_NONE;+ eventPtr = NULL;+ eventEndPtr = NULL;+ positionPtr = NULL;+ openInternalEntities = NULL;+ defaultExpandInternalEntities = XML_TRUE;+ tagLevel = 0;+ tagStack = NULL;+ inheritedBindings = NULL;+ nSpecifiedAtts = 0;+ unknownEncodingMem = NULL;+ unknownEncodingRelease = NULL;+ unknownEncodingData = NULL;+ parentParser = NULL;+ ps_parsing = XML_INITIALIZED;+#ifdef XML_DTD+ isParamEntity = XML_FALSE;+ useForeignDTD = XML_FALSE;+ paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;+#endif+ hash_secret_salt = 0;+}++/* moves list of bindings to freeBindingList */+static void FASTCALL+moveToFreeBindingList(XML_Parser parser, BINDING *bindings)+{+ while (bindings) {+ BINDING *b = bindings;+ bindings = bindings->nextTagBinding;+ b->nextTagBinding = freeBindingList;+ freeBindingList = b;+ }+}++XML_Bool XMLCALL+XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)+{+ TAG *tStk;+ OPEN_INTERNAL_ENTITY *openEntityList;++ if (parser == NULL)+ return XML_FALSE;++ if (parentParser)+ return XML_FALSE;+ /* move tagStack to freeTagList */+ tStk = tagStack;+ while (tStk) {+ TAG *tag = tStk;+ tStk = tStk->parent;+ tag->parent = freeTagList;+ moveToFreeBindingList(parser, tag->bindings);+ tag->bindings = NULL;+ freeTagList = tag;+ }+ /* move openInternalEntities to freeInternalEntities */+ openEntityList = openInternalEntities;+ while (openEntityList) {+ OPEN_INTERNAL_ENTITY *openEntity = openEntityList;+ openEntityList = openEntity->next;+ openEntity->next = freeInternalEntities;+ freeInternalEntities = openEntity;+ }+ moveToFreeBindingList(parser, inheritedBindings);+ FREE(unknownEncodingMem);+ if (unknownEncodingRelease)+ unknownEncodingRelease(unknownEncodingData);+ poolClear(&tempPool);+ poolClear(&temp2Pool);+ parserInit(parser, encodingName);+ dtdReset(_dtd, &parser->m_mem);+ return XML_TRUE;+}++enum XML_Status XMLCALL+XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)+{+ if (parser == NULL)+ return XML_STATUS_ERROR;+ /* Block after XML_Parse()/XML_ParseBuffer() has been called.+ XXX There's no way for the caller to determine which of the+ XXX possible error cases caused the XML_STATUS_ERROR return.+ */+ if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)+ return XML_STATUS_ERROR;+ if (encodingName == NULL)+ protocolEncodingName = NULL;+ else {+ protocolEncodingName = poolCopyString(&tempPool, encodingName);+ if (!protocolEncodingName)+ return XML_STATUS_ERROR;+ }+ return XML_STATUS_OK;+}++XML_Parser XMLCALL+XML_ExternalEntityParserCreate(XML_Parser oldParser,+ const XML_Char *context,+ const XML_Char *encodingName)+{+ XML_Parser parser = oldParser;+ DTD *newDtd = NULL;+ DTD *oldDtd;+ XML_StartElementHandler oldStartElementHandler;+ XML_EndElementHandler oldEndElementHandler;+ XML_CharacterDataHandler oldCharacterDataHandler;+ XML_ProcessingInstructionHandler oldProcessingInstructionHandler;+ XML_CommentHandler oldCommentHandler;+ XML_StartCdataSectionHandler oldStartCdataSectionHandler;+ XML_EndCdataSectionHandler oldEndCdataSectionHandler;+ XML_DefaultHandler oldDefaultHandler;+ XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler;+ XML_NotationDeclHandler oldNotationDeclHandler;+ XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler;+ XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler;+ XML_NotStandaloneHandler oldNotStandaloneHandler;+ XML_ExternalEntityRefHandler oldExternalEntityRefHandler;+ XML_SkippedEntityHandler oldSkippedEntityHandler;+ XML_UnknownEncodingHandler oldUnknownEncodingHandler;+ XML_ElementDeclHandler oldElementDeclHandler;+ XML_AttlistDeclHandler oldAttlistDeclHandler;+ XML_EntityDeclHandler oldEntityDeclHandler;+ XML_XmlDeclHandler oldXmlDeclHandler;+ ELEMENT_TYPE * oldDeclElementType;++ void *oldUserData;+ void *oldHandlerArg;+ XML_Bool oldDefaultExpandInternalEntities;+ XML_Parser oldExternalEntityRefHandlerArg;+#ifdef XML_DTD+ enum XML_ParamEntityParsing oldParamEntityParsing;+ int oldInEntityValue;+#endif+ XML_Bool oldns_triplets;+ /* Note that the new parser shares the same hash secret as the old+ parser, so that dtdCopy and copyEntityTable can lookup values+ from hash tables associated with either parser without us having+ to worry which hash secrets each table has.+ */+ unsigned long oldhash_secret_salt;++ /* Validate the oldParser parameter before we pull everything out of it */+ if (oldParser == NULL)+ return NULL;++ /* Stash the original parser contents on the stack */+ oldDtd = _dtd;+ oldStartElementHandler = startElementHandler;+ oldEndElementHandler = endElementHandler;+ oldCharacterDataHandler = characterDataHandler;+ oldProcessingInstructionHandler = processingInstructionHandler;+ oldCommentHandler = commentHandler;+ oldStartCdataSectionHandler = startCdataSectionHandler;+ oldEndCdataSectionHandler = endCdataSectionHandler;+ oldDefaultHandler = defaultHandler;+ oldUnparsedEntityDeclHandler = unparsedEntityDeclHandler;+ oldNotationDeclHandler = notationDeclHandler;+ oldStartNamespaceDeclHandler = startNamespaceDeclHandler;+ oldEndNamespaceDeclHandler = endNamespaceDeclHandler;+ oldNotStandaloneHandler = notStandaloneHandler;+ oldExternalEntityRefHandler = externalEntityRefHandler;+ oldSkippedEntityHandler = skippedEntityHandler;+ oldUnknownEncodingHandler = unknownEncodingHandler;+ oldElementDeclHandler = elementDeclHandler;+ oldAttlistDeclHandler = attlistDeclHandler;+ oldEntityDeclHandler = entityDeclHandler;+ oldXmlDeclHandler = xmlDeclHandler;+ oldDeclElementType = declElementType;++ oldUserData = userData;+ oldHandlerArg = handlerArg;+ oldDefaultExpandInternalEntities = defaultExpandInternalEntities;+ oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;+#ifdef XML_DTD+ oldParamEntityParsing = paramEntityParsing;+ oldInEntityValue = prologState.inEntityValue;+#endif+ oldns_triplets = ns_triplets;+ /* Note that the new parser shares the same hash secret as the old+ parser, so that dtdCopy and copyEntityTable can lookup values+ from hash tables associated with either parser without us having+ to worry which hash secrets each table has.+ */+ oldhash_secret_salt = hash_secret_salt;++#ifdef XML_DTD+ if (!context)+ newDtd = oldDtd;+#endif /* XML_DTD */++ /* Note that the magical uses of the pre-processor to make field+ access look more like C++ require that `parser' be overwritten+ here. This makes this function more painful to follow than it+ would be otherwise.+ */+ if (ns) {+ XML_Char tmp[2];+ *tmp = namespaceSeparator;+ parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);+ }+ else {+ parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);+ }++ if (!parser)+ return NULL;++ startElementHandler = oldStartElementHandler;+ endElementHandler = oldEndElementHandler;+ characterDataHandler = oldCharacterDataHandler;+ processingInstructionHandler = oldProcessingInstructionHandler;+ commentHandler = oldCommentHandler;+ startCdataSectionHandler = oldStartCdataSectionHandler;+ endCdataSectionHandler = oldEndCdataSectionHandler;+ defaultHandler = oldDefaultHandler;+ unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;+ notationDeclHandler = oldNotationDeclHandler;+ startNamespaceDeclHandler = oldStartNamespaceDeclHandler;+ endNamespaceDeclHandler = oldEndNamespaceDeclHandler;+ notStandaloneHandler = oldNotStandaloneHandler;+ externalEntityRefHandler = oldExternalEntityRefHandler;+ skippedEntityHandler = oldSkippedEntityHandler;+ unknownEncodingHandler = oldUnknownEncodingHandler;+ elementDeclHandler = oldElementDeclHandler;+ attlistDeclHandler = oldAttlistDeclHandler;+ entityDeclHandler = oldEntityDeclHandler;+ xmlDeclHandler = oldXmlDeclHandler;+ declElementType = oldDeclElementType;+ userData = oldUserData;+ if (oldUserData == oldHandlerArg)+ handlerArg = userData;+ else+ handlerArg = parser;+ if (oldExternalEntityRefHandlerArg != oldParser)+ externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;+ defaultExpandInternalEntities = oldDefaultExpandInternalEntities;+ ns_triplets = oldns_triplets;+ hash_secret_salt = oldhash_secret_salt;+ parentParser = oldParser;+#ifdef XML_DTD+ paramEntityParsing = oldParamEntityParsing;+ prologState.inEntityValue = oldInEntityValue;+ if (context) {+#endif /* XML_DTD */+ if (!dtdCopy(oldParser, _dtd, oldDtd, &parser->m_mem)+ || !setContext(parser, context)) {+ XML_ParserFree(parser);+ return NULL;+ }+ processor = externalEntityInitProcessor;+#ifdef XML_DTD+ }+ else {+ /* The DTD instance referenced by _dtd is shared between the document's+ root parser and external PE parsers, therefore one does not need to+ call setContext. In addition, one also *must* not call setContext,+ because this would overwrite existing prefix->binding pointers in+ _dtd with ones that get destroyed with the external PE parser.+ This would leave those prefixes with dangling pointers.+ */+ isParamEntity = XML_TRUE;+ XmlPrologStateInitExternalEntity(&prologState);+ processor = externalParEntInitProcessor;+ }+#endif /* XML_DTD */+ return parser;+}++static void FASTCALL+destroyBindings(BINDING *bindings, XML_Parser parser)+{+ for (;;) {+ BINDING *b = bindings;+ if (!b)+ break;+ bindings = b->nextTagBinding;+ FREE(b->uri);+ FREE(b);+ }+}++void XMLCALL+XML_ParserFree(XML_Parser parser)+{+ TAG *tagList;+ OPEN_INTERNAL_ENTITY *entityList;+ if (parser == NULL)+ return;+ /* free tagStack and freeTagList */+ tagList = tagStack;+ for (;;) {+ TAG *p;+ if (tagList == NULL) {+ if (freeTagList == NULL)+ break;+ tagList = freeTagList;+ freeTagList = NULL;+ }+ p = tagList;+ tagList = tagList->parent;+ FREE(p->buf);+ destroyBindings(p->bindings, parser);+ FREE(p);+ }+ /* free openInternalEntities and freeInternalEntities */+ entityList = openInternalEntities;+ for (;;) {+ OPEN_INTERNAL_ENTITY *openEntity;+ if (entityList == NULL) {+ if (freeInternalEntities == NULL)+ break;+ entityList = freeInternalEntities;+ freeInternalEntities = NULL;+ }+ openEntity = entityList;+ entityList = entityList->next;+ FREE(openEntity);+ }++ destroyBindings(freeBindingList, parser);+ destroyBindings(inheritedBindings, parser);+ poolDestroy(&tempPool);+ poolDestroy(&temp2Pool);+#ifdef XML_DTD+ /* external parameter entity parsers share the DTD structure+ parser->m_dtd with the root parser, so we must not destroy it+ */+ if (!isParamEntity && _dtd)+#else+ if (_dtd)+#endif /* XML_DTD */+ dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);+ FREE((void *)atts);+#ifdef XML_ATTR_INFO+ FREE((void *)attInfo);+#endif+ FREE(groupConnector);+ FREE(buffer);+ FREE(dataBuf);+ FREE(nsAtts);+ FREE(unknownEncodingMem);+ if (unknownEncodingRelease)+ unknownEncodingRelease(unknownEncodingData);+ FREE(parser);+}++void XMLCALL+XML_UseParserAsHandlerArg(XML_Parser parser)+{+ if (parser != NULL)+ handlerArg = parser;+}++enum XML_Error XMLCALL+XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)+{+ if (parser == NULL)+ return XML_ERROR_INVALID_ARGUMENT;+#ifdef XML_DTD+ /* block after XML_Parse()/XML_ParseBuffer() has been called */+ if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)+ return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;+ useForeignDTD = useDTD;+ return XML_ERROR_NONE;+#else+ return XML_ERROR_FEATURE_REQUIRES_XML_DTD;+#endif+}++void XMLCALL+XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)+{+ if (parser == NULL)+ return;+ /* block after XML_Parse()/XML_ParseBuffer() has been called */+ if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)+ return;+ ns_triplets = do_nst ? XML_TRUE : XML_FALSE;+}++void XMLCALL+XML_SetUserData(XML_Parser parser, void *p)+{+ if (parser == NULL)+ return;+ if (handlerArg == userData)+ handlerArg = userData = p;+ else+ userData = p;+}++enum XML_Status XMLCALL+XML_SetBase(XML_Parser parser, const XML_Char *p)+{+ if (parser == NULL)+ return XML_STATUS_ERROR;+ if (p) {+ p = poolCopyString(&_dtd->pool, p);+ if (!p)+ return XML_STATUS_ERROR;+ curBase = p;+ }+ else+ curBase = NULL;+ return XML_STATUS_OK;+}++const XML_Char * XMLCALL+XML_GetBase(XML_Parser parser)+{+ if (parser == NULL)+ return NULL;+ return curBase;+}++int XMLCALL+XML_GetSpecifiedAttributeCount(XML_Parser parser)+{+ if (parser == NULL)+ return -1;+ return nSpecifiedAtts;+}++int XMLCALL+XML_GetIdAttributeIndex(XML_Parser parser)+{+ if (parser == NULL)+ return -1;+ return idAttIndex;+}++#ifdef XML_ATTR_INFO+const XML_AttrInfo * XMLCALL+XML_GetAttributeInfo(XML_Parser parser)+{+ if (parser == NULL)+ return NULL;+ return attInfo;+}+#endif++void XMLCALL+XML_SetElementHandler(XML_Parser parser,+ XML_StartElementHandler start,+ XML_EndElementHandler end)+{+ if (parser == NULL)+ return;+ startElementHandler = start;+ endElementHandler = end;+}++void XMLCALL+XML_SetStartElementHandler(XML_Parser parser,+ XML_StartElementHandler start) {+ if (parser != NULL)+ startElementHandler = start;+}++void XMLCALL+XML_SetEndElementHandler(XML_Parser parser,+ XML_EndElementHandler end) {+ if (parser != NULL)+ endElementHandler = end;+}++void XMLCALL+XML_SetCharacterDataHandler(XML_Parser parser,+ XML_CharacterDataHandler handler)+{+ if (parser != NULL)+ characterDataHandler = handler;+}++void XMLCALL+XML_SetProcessingInstructionHandler(XML_Parser parser,+ XML_ProcessingInstructionHandler handler)+{+ if (parser != NULL)+ processingInstructionHandler = handler;+}++void XMLCALL+XML_SetCommentHandler(XML_Parser parser,+ XML_CommentHandler handler)+{+ if (parser != NULL)+ commentHandler = handler;+}++void XMLCALL+XML_SetCdataSectionHandler(XML_Parser parser,+ XML_StartCdataSectionHandler start,+ XML_EndCdataSectionHandler end)+{+ if (parser == NULL)+ return;+ startCdataSectionHandler = start;+ endCdataSectionHandler = end;+}++void XMLCALL+XML_SetStartCdataSectionHandler(XML_Parser parser,+ XML_StartCdataSectionHandler start) {+ if (parser != NULL)+ startCdataSectionHandler = start;+}++void XMLCALL+XML_SetEndCdataSectionHandler(XML_Parser parser,+ XML_EndCdataSectionHandler end) {+ if (parser != NULL)+ endCdataSectionHandler = end;+}++void XMLCALL+XML_SetDefaultHandler(XML_Parser parser,+ XML_DefaultHandler handler)+{+ if (parser == NULL)+ return;+ defaultHandler = handler;+ defaultExpandInternalEntities = XML_FALSE;+}++void XMLCALL+XML_SetDefaultHandlerExpand(XML_Parser parser,+ XML_DefaultHandler handler)+{+ if (parser == NULL)+ return;+ defaultHandler = handler;+ defaultExpandInternalEntities = XML_TRUE;+}++void XMLCALL+XML_SetDoctypeDeclHandler(XML_Parser parser,+ XML_StartDoctypeDeclHandler start,+ XML_EndDoctypeDeclHandler end)+{+ if (parser == NULL)+ return;+ startDoctypeDeclHandler = start;+ endDoctypeDeclHandler = end;+}++void XMLCALL+XML_SetStartDoctypeDeclHandler(XML_Parser parser,+ XML_StartDoctypeDeclHandler start) {+ if (parser != NULL)+ startDoctypeDeclHandler = start;+}++void XMLCALL+XML_SetEndDoctypeDeclHandler(XML_Parser parser,+ XML_EndDoctypeDeclHandler end) {+ if (parser != NULL)+ endDoctypeDeclHandler = end;+}++void XMLCALL+XML_SetUnparsedEntityDeclHandler(XML_Parser parser,+ XML_UnparsedEntityDeclHandler handler)+{+ if (parser != NULL)+ unparsedEntityDeclHandler = handler;+}++void XMLCALL+XML_SetNotationDeclHandler(XML_Parser parser,+ XML_NotationDeclHandler handler)+{+ if (parser != NULL)+ notationDeclHandler = handler;+}++void XMLCALL+XML_SetNamespaceDeclHandler(XML_Parser parser,+ XML_StartNamespaceDeclHandler start,+ XML_EndNamespaceDeclHandler end)+{+ if (parser == NULL)+ return;+ startNamespaceDeclHandler = start;+ endNamespaceDeclHandler = end;+}++void XMLCALL+XML_SetStartNamespaceDeclHandler(XML_Parser parser,+ XML_StartNamespaceDeclHandler start) {+ if (parser != NULL)+ startNamespaceDeclHandler = start;+}++void XMLCALL+XML_SetEndNamespaceDeclHandler(XML_Parser parser,+ XML_EndNamespaceDeclHandler end) {+ if (parser != NULL)+ endNamespaceDeclHandler = end;+}++void XMLCALL+XML_SetNotStandaloneHandler(XML_Parser parser,+ XML_NotStandaloneHandler handler)+{+ if (parser != NULL)+ notStandaloneHandler = handler;+}++void XMLCALL+XML_SetExternalEntityRefHandler(XML_Parser parser,+ XML_ExternalEntityRefHandler handler)+{+ if (parser != NULL)+ externalEntityRefHandler = handler;+}++void XMLCALL+XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)+{+ if (parser == NULL)+ return;+ if (arg)+ externalEntityRefHandlerArg = (XML_Parser)arg;+ else+ externalEntityRefHandlerArg = parser;+}++void XMLCALL+XML_SetSkippedEntityHandler(XML_Parser parser,+ XML_SkippedEntityHandler handler)+{+ if (parser != NULL)+ skippedEntityHandler = handler;+}++void XMLCALL+XML_SetUnknownEncodingHandler(XML_Parser parser,+ XML_UnknownEncodingHandler handler,+ void *data)+{+ if (parser == NULL)+ return;+ unknownEncodingHandler = handler;+ unknownEncodingHandlerData = data;+}++void XMLCALL+XML_SetElementDeclHandler(XML_Parser parser,+ XML_ElementDeclHandler eldecl)+{+ if (parser != NULL)+ elementDeclHandler = eldecl;+}++void XMLCALL+XML_SetAttlistDeclHandler(XML_Parser parser,+ XML_AttlistDeclHandler attdecl)+{+ if (parser != NULL)+ attlistDeclHandler = attdecl;+}++void XMLCALL+XML_SetEntityDeclHandler(XML_Parser parser,+ XML_EntityDeclHandler handler)+{+ if (parser != NULL)+ entityDeclHandler = handler;+}++void XMLCALL+XML_SetXmlDeclHandler(XML_Parser parser,+ XML_XmlDeclHandler handler) {+ if (parser != NULL)+ xmlDeclHandler = handler;+}++int XMLCALL+XML_SetParamEntityParsing(XML_Parser parser,+ enum XML_ParamEntityParsing peParsing)+{+ if (parser == NULL)+ return 0;+ /* block after XML_Parse()/XML_ParseBuffer() has been called */+ if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)+ return 0;+#ifdef XML_DTD+ paramEntityParsing = peParsing;+ return 1;+#else+ return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;+#endif+}++int XMLCALL+XML_SetHashSalt(XML_Parser parser,+ unsigned long hash_salt)+{+ if (parser == NULL)+ return 0;+ if (parser->m_parentParser)+ return XML_SetHashSalt(parser->m_parentParser, hash_salt);+ /* block after XML_Parse()/XML_ParseBuffer() has been called */+ if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)+ return 0;+ hash_secret_salt = hash_salt;+ return 1;+}++enum XML_Status XMLCALL+XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)+{+ if ((parser == NULL) || (len < 0) || ((s == NULL) && (len != 0))) {+ errorCode = XML_ERROR_INVALID_ARGUMENT;+ return XML_STATUS_ERROR;+ }+ switch (ps_parsing) {+ case XML_SUSPENDED:+ errorCode = XML_ERROR_SUSPENDED;+ return XML_STATUS_ERROR;+ case XML_FINISHED:+ errorCode = XML_ERROR_FINISHED;+ return XML_STATUS_ERROR;+ case XML_INITIALIZED:+ if (parentParser == NULL && !startParsing(parser)) {+ errorCode = XML_ERROR_NO_MEMORY;+ return XML_STATUS_ERROR;+ }+ default:+ ps_parsing = XML_PARSING;+ }++ if (len == 0) {+ ps_finalBuffer = (XML_Bool)isFinal;+ if (!isFinal)+ return XML_STATUS_OK;+ positionPtr = bufferPtr;+ parseEndPtr = bufferEnd;++ /* If data are left over from last buffer, and we now know that these+ data are the final chunk of input, then we have to check them again+ to detect errors based on that fact.+ */+ errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);++ if (errorCode == XML_ERROR_NONE) {+ switch (ps_parsing) {+ case XML_SUSPENDED:+ XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);+ positionPtr = bufferPtr;+ return XML_STATUS_SUSPENDED;+ case XML_INITIALIZED:+ case XML_PARSING:+ ps_parsing = XML_FINISHED;+ /* fall through */+ default:+ return XML_STATUS_OK;+ }+ }+ eventEndPtr = eventPtr;+ processor = errorProcessor;+ return XML_STATUS_ERROR;+ }+#ifndef XML_CONTEXT_BYTES+ else if (bufferPtr == bufferEnd) {+ const char *end;+ int nLeftOver;+ enum XML_Status result;+ /* Detect overflow (a+b > MAX <==> b > MAX-a) */+ if (len > ((XML_Size)-1) / 2 - parseEndByteIndex) {+ errorCode = XML_ERROR_NO_MEMORY;+ eventPtr = eventEndPtr = NULL;+ processor = errorProcessor;+ return XML_STATUS_ERROR;+ }+ parseEndByteIndex += len;+ positionPtr = s;+ ps_finalBuffer = (XML_Bool)isFinal;++ errorCode = processor(parser, s, parseEndPtr = s + len, &end);++ if (errorCode != XML_ERROR_NONE) {+ eventEndPtr = eventPtr;+ processor = errorProcessor;+ return XML_STATUS_ERROR;+ }+ else {+ switch (ps_parsing) {+ case XML_SUSPENDED:+ result = XML_STATUS_SUSPENDED;+ break;+ case XML_INITIALIZED:+ case XML_PARSING:+ if (isFinal) {+ ps_parsing = XML_FINISHED;+ return XML_STATUS_OK;+ }+ /* fall through */+ default:+ result = XML_STATUS_OK;+ }+ }++ XmlUpdatePosition(encoding, positionPtr, end, &position);+ nLeftOver = s + len - end;+ if (nLeftOver) {+ if (buffer == NULL || nLeftOver > bufferLim - buffer) {+ /* avoid _signed_ integer overflow */+ char *temp = NULL;+ const int bytesToAllocate = (int)((unsigned)len * 2U);+ if (bytesToAllocate > 0) {+ temp = (buffer == NULL+ ? (char *)MALLOC(bytesToAllocate)+ : (char *)REALLOC(buffer, bytesToAllocate));+ }+ if (temp == NULL) {+ errorCode = XML_ERROR_NO_MEMORY;+ eventPtr = eventEndPtr = NULL;+ processor = errorProcessor;+ return XML_STATUS_ERROR;+ }+ buffer = temp;+ bufferLim = buffer + bytesToAllocate;+ }+ memcpy(buffer, end, nLeftOver);+ }+ bufferPtr = buffer;+ bufferEnd = buffer + nLeftOver;+ positionPtr = bufferPtr;+ parseEndPtr = bufferEnd;+ eventPtr = bufferPtr;+ eventEndPtr = bufferPtr;+ return result;+ }+#endif /* not defined XML_CONTEXT_BYTES */+ else {+ void *buff = XML_GetBuffer(parser, len);+ if (buff == NULL)+ return XML_STATUS_ERROR;+ else {+ memcpy(buff, s, len);+ return XML_ParseBuffer(parser, len, isFinal);+ }+ }+}++enum XML_Status XMLCALL+XML_ParseBuffer(XML_Parser parser, int len, int isFinal)+{+ const char *start;+ enum XML_Status result = XML_STATUS_OK;++ if (parser == NULL)+ return XML_STATUS_ERROR;+ switch (ps_parsing) {+ case XML_SUSPENDED:+ errorCode = XML_ERROR_SUSPENDED;+ return XML_STATUS_ERROR;+ case XML_FINISHED:+ errorCode = XML_ERROR_FINISHED;+ return XML_STATUS_ERROR;+ case XML_INITIALIZED:+ if (parentParser == NULL && !startParsing(parser)) {+ errorCode = XML_ERROR_NO_MEMORY;+ return XML_STATUS_ERROR;+ }+ default:+ ps_parsing = XML_PARSING;+ }++ start = bufferPtr;+ positionPtr = start;+ bufferEnd += len;+ parseEndPtr = bufferEnd;+ parseEndByteIndex += len;+ ps_finalBuffer = (XML_Bool)isFinal;++ errorCode = processor(parser, start, parseEndPtr, &bufferPtr);++ if (errorCode != XML_ERROR_NONE) {+ eventEndPtr = eventPtr;+ processor = errorProcessor;+ return XML_STATUS_ERROR;+ }+ else {+ switch (ps_parsing) {+ case XML_SUSPENDED:+ result = XML_STATUS_SUSPENDED;+ break;+ case XML_INITIALIZED:+ case XML_PARSING:+ if (isFinal) {+ ps_parsing = XML_FINISHED;+ return result;+ }+ default: ; /* should not happen */+ }+ }++ XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);+ positionPtr = bufferPtr;+ return result;+}++void * XMLCALL+XML_GetBuffer(XML_Parser parser, int len)+{+ if (parser == NULL)+ return NULL;+ if (len < 0) {+ errorCode = XML_ERROR_NO_MEMORY;+ return NULL;+ }+ switch (ps_parsing) {+ case XML_SUSPENDED:+ errorCode = XML_ERROR_SUSPENDED;+ return NULL;+ case XML_FINISHED:+ errorCode = XML_ERROR_FINISHED;+ return NULL;+ default: ;+ }++ if (len > bufferLim - bufferEnd) {+#ifdef XML_CONTEXT_BYTES+ int keep;+#endif /* defined XML_CONTEXT_BYTES */+ /* Do not invoke signed arithmetic overflow: */+ int neededSize = (int) ((unsigned)len + (unsigned)(bufferEnd - bufferPtr));+ if (neededSize < 0) {+ errorCode = XML_ERROR_NO_MEMORY;+ return NULL;+ }+#ifdef XML_CONTEXT_BYTES+ keep = (int)(bufferPtr - buffer);+ if (keep > XML_CONTEXT_BYTES)+ keep = XML_CONTEXT_BYTES;+ neededSize += keep;+#endif /* defined XML_CONTEXT_BYTES */+ if (neededSize <= bufferLim - buffer) {+#ifdef XML_CONTEXT_BYTES+ if (keep < bufferPtr - buffer) {+ int offset = (int)(bufferPtr - buffer) - keep;+ memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);+ bufferEnd -= offset;+ bufferPtr -= offset;+ }+#else+ memmove(buffer, bufferPtr, bufferEnd - bufferPtr);+ bufferEnd = buffer + (bufferEnd - bufferPtr);+ bufferPtr = buffer;+#endif /* not defined XML_CONTEXT_BYTES */+ }+ else {+ char *newBuf;+ int bufferSize = (int)(bufferLim - bufferPtr);+ if (bufferSize == 0)+ bufferSize = INIT_BUFFER_SIZE;+ do {+ /* Do not invoke signed arithmetic overflow: */+ bufferSize = (int) (2U * (unsigned) bufferSize);+ } while (bufferSize < neededSize && bufferSize > 0);+ if (bufferSize <= 0) {+ errorCode = XML_ERROR_NO_MEMORY;+ return NULL;+ }+ newBuf = (char *)MALLOC(bufferSize);+ if (newBuf == 0) {+ errorCode = XML_ERROR_NO_MEMORY;+ return NULL;+ }+ bufferLim = newBuf + bufferSize;+#ifdef XML_CONTEXT_BYTES+ if (bufferPtr) {+ int keep = (int)(bufferPtr - buffer);+ if (keep > XML_CONTEXT_BYTES)+ keep = XML_CONTEXT_BYTES;+ memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);+ FREE(buffer);+ buffer = newBuf;+ bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;+ bufferPtr = buffer + keep;+ }+ else {+ bufferEnd = newBuf + (bufferEnd - bufferPtr);+ bufferPtr = buffer = newBuf;+ }+#else+ if (bufferPtr) {+ memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);+ FREE(buffer);+ }+ bufferEnd = newBuf + (bufferEnd - bufferPtr);+ bufferPtr = buffer = newBuf;+#endif /* not defined XML_CONTEXT_BYTES */+ }+ eventPtr = eventEndPtr = NULL;+ positionPtr = NULL;+ }+ return bufferEnd;+}++enum XML_Status XMLCALL+XML_StopParser(XML_Parser parser, XML_Bool resumable)+{+ if (parser == NULL)+ return XML_STATUS_ERROR;+ switch (ps_parsing) {+ case XML_SUSPENDED:+ if (resumable) {+ errorCode = XML_ERROR_SUSPENDED;+ return XML_STATUS_ERROR;+ }+ ps_parsing = XML_FINISHED;+ break;+ case XML_FINISHED:+ errorCode = XML_ERROR_FINISHED;+ return XML_STATUS_ERROR;+ default:+ if (resumable) {+#ifdef XML_DTD+ if (isParamEntity) {+ errorCode = XML_ERROR_SUSPEND_PE;+ return XML_STATUS_ERROR;+ }+#endif+ ps_parsing = XML_SUSPENDED;+ }+ else+ ps_parsing = XML_FINISHED;+ }+ return XML_STATUS_OK;+}++enum XML_Status XMLCALL+XML_ResumeParser(XML_Parser parser)+{+ enum XML_Status result = XML_STATUS_OK;++ if (parser == NULL)+ return XML_STATUS_ERROR;+ if (ps_parsing != XML_SUSPENDED) {+ errorCode = XML_ERROR_NOT_SUSPENDED;+ return XML_STATUS_ERROR;+ }+ ps_parsing = XML_PARSING;++ errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);++ if (errorCode != XML_ERROR_NONE) {+ eventEndPtr = eventPtr;+ processor = errorProcessor;+ return XML_STATUS_ERROR;+ }+ else {+ switch (ps_parsing) {+ case XML_SUSPENDED:+ result = XML_STATUS_SUSPENDED;+ break;+ case XML_INITIALIZED:+ case XML_PARSING:+ if (ps_finalBuffer) {+ ps_parsing = XML_FINISHED;+ return result;+ }+ default: ;+ }+ }++ XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);+ positionPtr = bufferPtr;+ return result;+}++void XMLCALL+XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)+{+ if (parser == NULL)+ return;+ assert(status != NULL);+ *status = parser->m_parsingStatus;+}++enum XML_Error XMLCALL+XML_GetErrorCode(XML_Parser parser)+{+ if (parser == NULL)+ return XML_ERROR_INVALID_ARGUMENT;+ return errorCode;+}++XML_Index XMLCALL+XML_GetCurrentByteIndex(XML_Parser parser)+{+ if (parser == NULL)+ return -1;+ if (eventPtr)+ return (XML_Index)(parseEndByteIndex - (parseEndPtr - eventPtr));+ return -1;+}++int XMLCALL+XML_GetCurrentByteCount(XML_Parser parser)+{+ if (parser == NULL)+ return 0;+ if (eventEndPtr && eventPtr)+ return (int)(eventEndPtr - eventPtr);+ return 0;+}++const char * XMLCALL+XML_GetInputContext(XML_Parser parser, int *offset, int *size)+{+#ifdef XML_CONTEXT_BYTES+ if (parser == NULL)+ return NULL;+ if (eventPtr && buffer) {+ if (offset != NULL)+ *offset = (int)(eventPtr - buffer);+ if (size != NULL)+ *size = (int)(bufferEnd - buffer);+ return buffer;+ }+#else+ (void)parser;+ (void)offset;+ (void)size;+#endif /* defined XML_CONTEXT_BYTES */+ return (char *) 0;+}++XML_Size XMLCALL+XML_GetCurrentLineNumber(XML_Parser parser)+{+ if (parser == NULL)+ return 0;+ if (eventPtr && eventPtr >= positionPtr) {+ XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);+ positionPtr = eventPtr;+ }+ return position.lineNumber + 1;+}++XML_Size XMLCALL+XML_GetCurrentColumnNumber(XML_Parser parser)+{+ if (parser == NULL)+ return 0;+ if (eventPtr && eventPtr >= positionPtr) {+ XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);+ positionPtr = eventPtr;+ }+ return position.columnNumber;+}++void XMLCALL+XML_FreeContentModel(XML_Parser parser, XML_Content *model)+{+ if (parser != NULL)+ FREE(model);+}++void * XMLCALL+XML_MemMalloc(XML_Parser parser, size_t size)+{+ if (parser == NULL)+ return NULL;+ return MALLOC(size);+}++void * XMLCALL+XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)+{+ if (parser == NULL)+ return NULL;+ return REALLOC(ptr, size);+}++void XMLCALL+XML_MemFree(XML_Parser parser, void *ptr)+{+ if (parser != NULL)+ FREE(ptr);+}++void XMLCALL+XML_DefaultCurrent(XML_Parser parser)+{+ if (parser == NULL)+ return;+ if (defaultHandler) {+ if (openInternalEntities)+ reportDefault(parser,+ internalEncoding,+ openInternalEntities->internalEventPtr,+ openInternalEntities->internalEventEndPtr);+ else+ reportDefault(parser, encoding, eventPtr, eventEndPtr);+ }+}++const XML_LChar * XMLCALL+XML_ErrorString(enum XML_Error code)+{+ static const XML_LChar* const message[] = {+ 0,+ XML_L("out of memory"),+ XML_L("syntax error"),+ XML_L("no element found"),+ XML_L("not well-formed (invalid token)"),+ XML_L("unclosed token"),+ XML_L("partial character"),+ XML_L("mismatched tag"),+ XML_L("duplicate attribute"),+ XML_L("junk after document element"),+ XML_L("illegal parameter entity reference"),+ XML_L("undefined entity"),+ XML_L("recursive entity reference"),+ XML_L("asynchronous entity"),+ XML_L("reference to invalid character number"),+ XML_L("reference to binary entity"),+ XML_L("reference to external entity in attribute"),+ XML_L("XML or text declaration not at start of entity"),+ XML_L("unknown encoding"),+ XML_L("encoding specified in XML declaration is incorrect"),+ XML_L("unclosed CDATA section"),+ XML_L("error in processing external entity reference"),+ XML_L("document is not standalone"),+ XML_L("unexpected parser state - please send a bug report"),+ XML_L("entity declared in parameter entity"),+ XML_L("requested feature requires XML_DTD support in Expat"),+ XML_L("cannot change setting once parsing has begun"),+ XML_L("unbound prefix"),+ XML_L("must not undeclare prefix"),+ XML_L("incomplete markup in parameter entity"),+ XML_L("XML declaration not well-formed"),+ XML_L("text declaration not well-formed"),+ XML_L("illegal character(s) in public id"),+ XML_L("parser suspended"),+ XML_L("parser not suspended"),+ XML_L("parsing aborted"),+ XML_L("parsing finished"),+ XML_L("cannot suspend in external parameter entity"),+ XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),+ XML_L("reserved prefix (xmlns) must not be declared or undeclared"),+ XML_L("prefix must not be bound to one of the reserved namespace names")+ };+ if (code > 0 && code < sizeof(message)/sizeof(message[0]))+ return message[code];+ return NULL;+}++const XML_LChar * XMLCALL+XML_ExpatVersion(void) {++ /* V1 is used to string-ize the version number. However, it would+ string-ize the actual version macro *names* unless we get them+ substituted before being passed to V1. CPP is defined to expand+ a macro, then rescan for more expansions. Thus, we use V2 to expand+ the version macros, then CPP will expand the resulting V1() macro+ with the correct numerals. */+ /* ### I'm assuming cpp is portable in this respect... */++#define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)+#define V2(a,b,c) XML_L("expat_")V1(a,b,c)++ return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);++#undef V1+#undef V2+}++XML_Expat_Version XMLCALL+XML_ExpatVersionInfo(void)+{+ XML_Expat_Version version;++ version.major = XML_MAJOR_VERSION;+ version.minor = XML_MINOR_VERSION;+ version.micro = XML_MICRO_VERSION;++ return version;+}++const XML_Feature * XMLCALL+XML_GetFeatureList(void)+{+ static const XML_Feature features[] = {+ {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"),+ sizeof(XML_Char)},+ {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),+ sizeof(XML_LChar)},+#ifdef XML_UNICODE+ {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},+#endif+#ifdef XML_UNICODE_WCHAR_T+ {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},+#endif+#ifdef XML_DTD+ {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},+#endif+#ifdef XML_CONTEXT_BYTES+ {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),+ XML_CONTEXT_BYTES},+#endif+#ifdef XML_MIN_SIZE+ {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},+#endif+#ifdef XML_NS+ {XML_FEATURE_NS, XML_L("XML_NS"), 0},+#endif+#ifdef XML_LARGE_SIZE+ {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0},+#endif+#ifdef XML_ATTR_INFO+ {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0},+#endif+ {XML_FEATURE_END, NULL, 0}+ };++ return features;+}++/* Initially tag->rawName always points into the parse buffer;+ for those TAG instances opened while the current parse buffer was+ processed, and not yet closed, we need to store tag->rawName in a more+ permanent location, since the parse buffer is about to be discarded.+*/+static XML_Bool+storeRawNames(XML_Parser parser)+{+ TAG *tag = tagStack;+ while (tag) {+ int bufSize;+ int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);+ char *rawNameBuf = tag->buf + nameLen;+ /* Stop if already stored. Since tagStack is a stack, we can stop+ at the first entry that has already been copied; everything+ below it in the stack is already been accounted for in a+ previous call to this function.+ */+ if (tag->rawName == rawNameBuf)+ break;+ /* For re-use purposes we need to ensure that the+ size of tag->buf is a multiple of sizeof(XML_Char).+ */+ bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));+ if (bufSize > tag->bufEnd - tag->buf) {+ char *temp = (char *)REALLOC(tag->buf, bufSize);+ if (temp == NULL)+ return XML_FALSE;+ /* if tag->name.str points to tag->buf (only when namespace+ processing is off) then we have to update it+ */+ if (tag->name.str == (XML_Char *)tag->buf)+ tag->name.str = (XML_Char *)temp;+ /* if tag->name.localPart is set (when namespace processing is on)+ then update it as well, since it will always point into tag->buf+ */+ if (tag->name.localPart)+ tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -+ (XML_Char *)tag->buf);+ tag->buf = temp;+ tag->bufEnd = temp + bufSize;+ rawNameBuf = temp + nameLen;+ }+ memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);+ tag->rawName = rawNameBuf;+ tag = tag->parent;+ }+ return XML_TRUE;+}++static enum XML_Error PTRCALL+contentProcessor(XML_Parser parser,+ const char *start,+ const char *end,+ const char **endPtr)+{+ enum XML_Error result = doContent(parser, 0, encoding, start, end,+ endPtr, (XML_Bool)!ps_finalBuffer);+ if (result == XML_ERROR_NONE) {+ if (!storeRawNames(parser))+ return XML_ERROR_NO_MEMORY;+ }+ return result;+}++static enum XML_Error PTRCALL+externalEntityInitProcessor(XML_Parser parser,+ const char *start,+ const char *end,+ const char **endPtr)+{+ enum XML_Error result = initializeEncoding(parser);+ if (result != XML_ERROR_NONE)+ return result;+ processor = externalEntityInitProcessor2;+ return externalEntityInitProcessor2(parser, start, end, endPtr);+}++static enum XML_Error PTRCALL+externalEntityInitProcessor2(XML_Parser parser,+ const char *start,+ const char *end,+ const char **endPtr)+{+ const char *next = start; /* XmlContentTok doesn't always set the last arg */+ int tok = XmlContentTok(encoding, start, end, &next);+ switch (tok) {+ case XML_TOK_BOM:+ /* If we are at the end of the buffer, this would cause the next stage,+ i.e. externalEntityInitProcessor3, to pass control directly to+ doContent (by detecting XML_TOK_NONE) without processing any xml text+ declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.+ */+ if (next == end && !ps_finalBuffer) {+ *endPtr = next;+ return XML_ERROR_NONE;+ }+ start = next;+ break;+ case XML_TOK_PARTIAL:+ if (!ps_finalBuffer) {+ *endPtr = start;+ return XML_ERROR_NONE;+ }+ eventPtr = start;+ return XML_ERROR_UNCLOSED_TOKEN;+ case XML_TOK_PARTIAL_CHAR:+ if (!ps_finalBuffer) {+ *endPtr = start;+ return XML_ERROR_NONE;+ }+ eventPtr = start;+ return XML_ERROR_PARTIAL_CHAR;+ }+ processor = externalEntityInitProcessor3;+ return externalEntityInitProcessor3(parser, start, end, endPtr);+}++static enum XML_Error PTRCALL+externalEntityInitProcessor3(XML_Parser parser,+ const char *start,+ const char *end,+ const char **endPtr)+{+ int tok;+ const char *next = start; /* XmlContentTok doesn't always set the last arg */+ eventPtr = start;+ tok = XmlContentTok(encoding, start, end, &next);+ eventEndPtr = next;++ switch (tok) {+ case XML_TOK_XML_DECL:+ {+ enum XML_Error result;+ result = processXmlDecl(parser, 1, start, next);+ if (result != XML_ERROR_NONE)+ return result;+ switch (ps_parsing) {+ case XML_SUSPENDED:+ *endPtr = next;+ return XML_ERROR_NONE;+ case XML_FINISHED:+ return XML_ERROR_ABORTED;+ default:+ start = next;+ }+ }+ break;+ case XML_TOK_PARTIAL:+ if (!ps_finalBuffer) {+ *endPtr = start;+ return XML_ERROR_NONE;+ }+ return XML_ERROR_UNCLOSED_TOKEN;+ case XML_TOK_PARTIAL_CHAR:+ if (!ps_finalBuffer) {+ *endPtr = start;+ return XML_ERROR_NONE;+ }+ return XML_ERROR_PARTIAL_CHAR;+ }+ processor = externalEntityContentProcessor;+ tagLevel = 1;+ return externalEntityContentProcessor(parser, start, end, endPtr);+}++static enum XML_Error PTRCALL+externalEntityContentProcessor(XML_Parser parser,+ const char *start,+ const char *end,+ const char **endPtr)+{+ enum XML_Error result = doContent(parser, 1, encoding, start, end,+ endPtr, (XML_Bool)!ps_finalBuffer);+ if (result == XML_ERROR_NONE) {+ if (!storeRawNames(parser))+ return XML_ERROR_NO_MEMORY;+ }+ return result;+}++static enum XML_Error+doContent(XML_Parser parser,+ int startTagLevel,+ const ENCODING *enc,+ const char *s,+ const char *end,+ const char **nextPtr,+ XML_Bool haveMore)+{+ /* save one level of indirection */+ DTD * const dtd = _dtd;++ const char **eventPP;+ const char **eventEndPP;+ if (enc == encoding) {+ eventPP = &eventPtr;+ eventEndPP = &eventEndPtr;+ }+ else {+ eventPP = &(openInternalEntities->internalEventPtr);+ eventEndPP = &(openInternalEntities->internalEventEndPtr);+ }+ *eventPP = s;++ for (;;) {+ const char *next = s; /* XmlContentTok doesn't always set the last arg */+ int tok = XmlContentTok(enc, s, end, &next);+ *eventEndPP = next;+ switch (tok) {+ case XML_TOK_TRAILING_CR:+ if (haveMore) {+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ *eventEndPP = end;+ if (characterDataHandler) {+ XML_Char c = 0xA;+ characterDataHandler(handlerArg, &c, 1);+ }+ else if (defaultHandler)+ reportDefault(parser, enc, s, end);+ /* We are at the end of the final buffer, should we check for+ XML_SUSPENDED, XML_FINISHED?+ */+ if (startTagLevel == 0)+ return XML_ERROR_NO_ELEMENTS;+ if (tagLevel != startTagLevel)+ return XML_ERROR_ASYNC_ENTITY;+ *nextPtr = end;+ return XML_ERROR_NONE;+ case XML_TOK_NONE:+ if (haveMore) {+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ if (startTagLevel > 0) {+ if (tagLevel != startTagLevel)+ return XML_ERROR_ASYNC_ENTITY;+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ return XML_ERROR_NO_ELEMENTS;+ case XML_TOK_INVALID:+ *eventPP = next;+ return XML_ERROR_INVALID_TOKEN;+ case XML_TOK_PARTIAL:+ if (haveMore) {+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ return XML_ERROR_UNCLOSED_TOKEN;+ case XML_TOK_PARTIAL_CHAR:+ if (haveMore) {+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ return XML_ERROR_PARTIAL_CHAR;+ case XML_TOK_ENTITY_REF:+ {+ const XML_Char *name;+ ENTITY *entity;+ XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,+ s + enc->minBytesPerChar,+ next - enc->minBytesPerChar);+ if (ch) {+ if (characterDataHandler)+ characterDataHandler(handlerArg, &ch, 1);+ else if (defaultHandler)+ reportDefault(parser, enc, s, next);+ break;+ }+ name = poolStoreString(&dtd->pool, enc,+ s + enc->minBytesPerChar,+ next - enc->minBytesPerChar);+ if (!name)+ return XML_ERROR_NO_MEMORY;+ entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);+ poolDiscard(&dtd->pool);+ /* First, determine if a check for an existing declaration is needed;+ if yes, check that the entity exists, and that it is internal,+ otherwise call the skipped entity or default handler.+ */+ if (!dtd->hasParamEntityRefs || dtd->standalone) {+ if (!entity)+ return XML_ERROR_UNDEFINED_ENTITY;+ else if (!entity->is_internal)+ return XML_ERROR_ENTITY_DECLARED_IN_PE;+ }+ else if (!entity) {+ if (skippedEntityHandler)+ skippedEntityHandler(handlerArg, name, 0);+ else if (defaultHandler)+ reportDefault(parser, enc, s, next);+ break;+ }+ if (entity->open)+ return XML_ERROR_RECURSIVE_ENTITY_REF;+ if (entity->notation)+ return XML_ERROR_BINARY_ENTITY_REF;+ if (entity->textPtr) {+ enum XML_Error result;+ if (!defaultExpandInternalEntities) {+ if (skippedEntityHandler)+ skippedEntityHandler(handlerArg, entity->name, 0);+ else if (defaultHandler)+ reportDefault(parser, enc, s, next);+ break;+ }+ result = processInternalEntity(parser, entity, XML_FALSE);+ if (result != XML_ERROR_NONE)+ return result;+ }+ else if (externalEntityRefHandler) {+ const XML_Char *context;+ entity->open = XML_TRUE;+ context = getContext(parser);+ entity->open = XML_FALSE;+ if (!context)+ return XML_ERROR_NO_MEMORY;+ if (!externalEntityRefHandler(externalEntityRefHandlerArg,+ context,+ entity->base,+ entity->systemId,+ entity->publicId))+ return XML_ERROR_EXTERNAL_ENTITY_HANDLING;+ poolDiscard(&tempPool);+ }+ else if (defaultHandler)+ reportDefault(parser, enc, s, next);+ break;+ }+ case XML_TOK_START_TAG_NO_ATTS:+ /* fall through */+ case XML_TOK_START_TAG_WITH_ATTS:+ {+ TAG *tag;+ enum XML_Error result;+ XML_Char *toPtr;+ if (freeTagList) {+ tag = freeTagList;+ freeTagList = freeTagList->parent;+ }+ else {+ tag = (TAG *)MALLOC(sizeof(TAG));+ if (!tag)+ return XML_ERROR_NO_MEMORY;+ tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);+ if (!tag->buf) {+ FREE(tag);+ return XML_ERROR_NO_MEMORY;+ }+ tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;+ }+ tag->bindings = NULL;+ tag->parent = tagStack;+ tagStack = tag;+ tag->name.localPart = NULL;+ tag->name.prefix = NULL;+ tag->rawName = s + enc->minBytesPerChar;+ tag->rawNameLength = XmlNameLength(enc, tag->rawName);+ ++tagLevel;+ {+ const char *rawNameEnd = tag->rawName + tag->rawNameLength;+ const char *fromPtr = tag->rawName;+ toPtr = (XML_Char *)tag->buf;+ for (;;) {+ int bufSize;+ int convLen;+ const enum XML_Convert_Result convert_res = XmlConvert(enc,+ &fromPtr, rawNameEnd,+ (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);+ convLen = (int)(toPtr - (XML_Char *)tag->buf);+ if ((fromPtr >= rawNameEnd) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) {+ tag->name.strLen = convLen;+ break;+ }+ bufSize = (int)(tag->bufEnd - tag->buf) << 1;+ {+ char *temp = (char *)REALLOC(tag->buf, bufSize);+ if (temp == NULL)+ return XML_ERROR_NO_MEMORY;+ tag->buf = temp;+ tag->bufEnd = temp + bufSize;+ toPtr = (XML_Char *)temp + convLen;+ }+ }+ }+ tag->name.str = (XML_Char *)tag->buf;+ *toPtr = XML_T('\0');+ result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));+ if (result)+ return result;+ if (startElementHandler)+ startElementHandler(handlerArg, tag->name.str,+ (const XML_Char **)atts);+ else if (defaultHandler)+ reportDefault(parser, enc, s, next);+ poolClear(&tempPool);+ break;+ }+ case XML_TOK_EMPTY_ELEMENT_NO_ATTS:+ /* fall through */+ case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:+ {+ const char *rawName = s + enc->minBytesPerChar;+ enum XML_Error result;+ BINDING *bindings = NULL;+ XML_Bool noElmHandlers = XML_TRUE;+ TAG_NAME name;+ name.str = poolStoreString(&tempPool, enc, rawName,+ rawName + XmlNameLength(enc, rawName));+ if (!name.str)+ return XML_ERROR_NO_MEMORY;+ poolFinish(&tempPool);+ result = storeAtts(parser, enc, s, &name, &bindings);+ if (result != XML_ERROR_NONE) {+ freeBindings(parser, bindings);+ return result;+ }+ poolFinish(&tempPool);+ if (startElementHandler) {+ startElementHandler(handlerArg, name.str, (const XML_Char **)atts);+ noElmHandlers = XML_FALSE;+ }+ if (endElementHandler) {+ if (startElementHandler)+ *eventPP = *eventEndPP;+ endElementHandler(handlerArg, name.str);+ noElmHandlers = XML_FALSE;+ }+ if (noElmHandlers && defaultHandler)+ reportDefault(parser, enc, s, next);+ poolClear(&tempPool);+ freeBindings(parser, bindings);+ }+ if (tagLevel == 0)+ return epilogProcessor(parser, next, end, nextPtr);+ break;+ case XML_TOK_END_TAG:+ if (tagLevel == startTagLevel)+ return XML_ERROR_ASYNC_ENTITY;+ else {+ int len;+ const char *rawName;+ TAG *tag = tagStack;+ tagStack = tag->parent;+ tag->parent = freeTagList;+ freeTagList = tag;+ rawName = s + enc->minBytesPerChar*2;+ len = XmlNameLength(enc, rawName);+ if (len != tag->rawNameLength+ || memcmp(tag->rawName, rawName, len) != 0) {+ *eventPP = rawName;+ return XML_ERROR_TAG_MISMATCH;+ }+ --tagLevel;+ if (endElementHandler) {+ const XML_Char *localPart;+ const XML_Char *prefix;+ XML_Char *uri;+ localPart = tag->name.localPart;+ if (ns && localPart) {+ /* localPart and prefix may have been overwritten in+ tag->name.str, since this points to the binding->uri+ buffer which gets re-used; so we have to add them again+ */+ uri = (XML_Char *)tag->name.str + tag->name.uriLen;+ /* don't need to check for space - already done in storeAtts() */+ while (*localPart) *uri++ = *localPart++;+ prefix = (XML_Char *)tag->name.prefix;+ if (ns_triplets && prefix) {+ *uri++ = namespaceSeparator;+ while (*prefix) *uri++ = *prefix++;+ }+ *uri = XML_T('\0');+ }+ endElementHandler(handlerArg, tag->name.str);+ }+ else if (defaultHandler)+ reportDefault(parser, enc, s, next);+ while (tag->bindings) {+ BINDING *b = tag->bindings;+ if (endNamespaceDeclHandler)+ endNamespaceDeclHandler(handlerArg, b->prefix->name);+ tag->bindings = tag->bindings->nextTagBinding;+ b->nextTagBinding = freeBindingList;+ freeBindingList = b;+ b->prefix->binding = b->prevPrefixBinding;+ }+ if (tagLevel == 0)+ return epilogProcessor(parser, next, end, nextPtr);+ }+ break;+ case XML_TOK_CHAR_REF:+ {+ int n = XmlCharRefNumber(enc, s);+ if (n < 0)+ return XML_ERROR_BAD_CHAR_REF;+ if (characterDataHandler) {+ XML_Char buf[XML_ENCODE_MAX];+ characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));+ }+ else if (defaultHandler)+ reportDefault(parser, enc, s, next);+ }+ break;+ case XML_TOK_XML_DECL:+ return XML_ERROR_MISPLACED_XML_PI;+ case XML_TOK_DATA_NEWLINE:+ if (characterDataHandler) {+ XML_Char c = 0xA;+ characterDataHandler(handlerArg, &c, 1);+ }+ else if (defaultHandler)+ reportDefault(parser, enc, s, next);+ break;+ case XML_TOK_CDATA_SECT_OPEN:+ {+ enum XML_Error result;+ if (startCdataSectionHandler)+ startCdataSectionHandler(handlerArg);+#if 0+ /* Suppose you doing a transformation on a document that involves+ changing only the character data. You set up a defaultHandler+ and a characterDataHandler. The defaultHandler simply copies+ characters through. The characterDataHandler does the+ transformation and writes the characters out escaping them as+ necessary. This case will fail to work if we leave out the+ following two lines (because & and < inside CDATA sections will+ be incorrectly escaped).++ However, now we have a start/endCdataSectionHandler, so it seems+ easier to let the user deal with this.+ */+ else if (characterDataHandler)+ characterDataHandler(handlerArg, dataBuf, 0);+#endif+ else if (defaultHandler)+ reportDefault(parser, enc, s, next);+ result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);+ if (result != XML_ERROR_NONE)+ return result;+ else if (!next) {+ processor = cdataSectionProcessor;+ return result;+ }+ }+ break;+ case XML_TOK_TRAILING_RSQB:+ if (haveMore) {+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ if (characterDataHandler) {+ if (MUST_CONVERT(enc, s)) {+ ICHAR *dataPtr = (ICHAR *)dataBuf;+ XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);+ characterDataHandler(handlerArg, dataBuf,+ (int)(dataPtr - (ICHAR *)dataBuf));+ }+ else+ characterDataHandler(handlerArg,+ (XML_Char *)s,+ (int)((XML_Char *)end - (XML_Char *)s));+ }+ else if (defaultHandler)+ reportDefault(parser, enc, s, end);+ /* We are at the end of the final buffer, should we check for+ XML_SUSPENDED, XML_FINISHED?+ */+ if (startTagLevel == 0) {+ *eventPP = end;+ return XML_ERROR_NO_ELEMENTS;+ }+ if (tagLevel != startTagLevel) {+ *eventPP = end;+ return XML_ERROR_ASYNC_ENTITY;+ }+ *nextPtr = end;+ return XML_ERROR_NONE;+ case XML_TOK_DATA_CHARS:+ {+ XML_CharacterDataHandler charDataHandler = characterDataHandler;+ if (charDataHandler) {+ if (MUST_CONVERT(enc, s)) {+ for (;;) {+ ICHAR *dataPtr = (ICHAR *)dataBuf;+ const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);+ *eventEndPP = s;+ charDataHandler(handlerArg, dataBuf,+ (int)(dataPtr - (ICHAR *)dataBuf));+ if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))+ break;+ *eventPP = s;+ }+ }+ else+ charDataHandler(handlerArg,+ (XML_Char *)s,+ (int)((XML_Char *)next - (XML_Char *)s));+ }+ else if (defaultHandler)+ reportDefault(parser, enc, s, next);+ }+ break;+ case XML_TOK_PI:+ if (!reportProcessingInstruction(parser, enc, s, next))+ return XML_ERROR_NO_MEMORY;+ break;+ case XML_TOK_COMMENT:+ if (!reportComment(parser, enc, s, next))+ return XML_ERROR_NO_MEMORY;+ break;+ default:+ if (defaultHandler)+ reportDefault(parser, enc, s, next);+ break;+ }+ *eventPP = s = next;+ switch (ps_parsing) {+ case XML_SUSPENDED:+ *nextPtr = next;+ return XML_ERROR_NONE;+ case XML_FINISHED:+ return XML_ERROR_ABORTED;+ default: ;+ }+ }+ /* not reached */+}++/* This function does not call free() on the allocated memory, merely+ * moving it to the parser's freeBindingList where it can be freed or+ * reused as appropriate.+ */+static void+freeBindings(XML_Parser parser, BINDING *bindings)+{+ while (bindings) {+ BINDING *b = bindings;++ /* startNamespaceDeclHandler will have been called for this+ * binding in addBindings(), so call the end handler now.+ */+ if (endNamespaceDeclHandler)+ endNamespaceDeclHandler(handlerArg, b->prefix->name);++ bindings = bindings->nextTagBinding;+ b->nextTagBinding = freeBindingList;+ freeBindingList = b;+ b->prefix->binding = b->prevPrefixBinding;+ }+}++/* Precondition: all arguments must be non-NULL;+ Purpose:+ - normalize attributes+ - check attributes for well-formedness+ - generate namespace aware attribute names (URI, prefix)+ - build list of attributes for startElementHandler+ - default attributes+ - process namespace declarations (check and report them)+ - generate namespace aware element name (URI, prefix)+*/+static enum XML_Error+storeAtts(XML_Parser parser, const ENCODING *enc,+ const char *attStr, TAG_NAME *tagNamePtr,+ BINDING **bindingsPtr)+{+ DTD * const dtd = _dtd; /* save one level of indirection */+ ELEMENT_TYPE *elementType;+ int nDefaultAtts;+ const XML_Char **appAtts; /* the attribute list for the application */+ int attIndex = 0;+ int prefixLen;+ int i;+ int n;+ XML_Char *uri;+ int nPrefixes = 0;+ BINDING *binding;+ const XML_Char *localPart;++ /* lookup the element type name */+ elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str,0);+ if (!elementType) {+ const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);+ if (!name)+ return XML_ERROR_NO_MEMORY;+ elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,+ sizeof(ELEMENT_TYPE));+ if (!elementType)+ return XML_ERROR_NO_MEMORY;+ if (ns && !setElementTypePrefix(parser, elementType))+ return XML_ERROR_NO_MEMORY;+ }+ nDefaultAtts = elementType->nDefaultAtts;++ /* get the attributes from the tokenizer */+ n = XmlGetAttributes(enc, attStr, attsSize, atts);+ if (n + nDefaultAtts > attsSize) {+ int oldAttsSize = attsSize;+ ATTRIBUTE *temp;+#ifdef XML_ATTR_INFO+ XML_AttrInfo *temp2;+#endif+ attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;+ temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));+ if (temp == NULL)+ return XML_ERROR_NO_MEMORY;+ atts = temp;+#ifdef XML_ATTR_INFO+ temp2 = (XML_AttrInfo *)REALLOC((void *)attInfo, attsSize * sizeof(XML_AttrInfo));+ if (temp2 == NULL)+ return XML_ERROR_NO_MEMORY;+ attInfo = temp2;+#endif+ if (n > oldAttsSize)+ XmlGetAttributes(enc, attStr, n, atts);+ }++ appAtts = (const XML_Char **)atts;+ for (i = 0; i < n; i++) {+ ATTRIBUTE *currAtt = &atts[i];+#ifdef XML_ATTR_INFO+ XML_AttrInfo *currAttInfo = &attInfo[i];+#endif+ /* add the name and value to the attribute list */+ ATTRIBUTE_ID *attId = getAttributeId(parser, enc, currAtt->name,+ currAtt->name+ + XmlNameLength(enc, currAtt->name));+ if (!attId)+ return XML_ERROR_NO_MEMORY;+#ifdef XML_ATTR_INFO+ currAttInfo->nameStart = parseEndByteIndex - (parseEndPtr - currAtt->name);+ currAttInfo->nameEnd = currAttInfo->nameStart ++ XmlNameLength(enc, currAtt->name);+ currAttInfo->valueStart = parseEndByteIndex -+ (parseEndPtr - currAtt->valuePtr);+ currAttInfo->valueEnd = parseEndByteIndex - (parseEndPtr - currAtt->valueEnd);+#endif+ /* Detect duplicate attributes by their QNames. This does not work when+ namespace processing is turned on and different prefixes for the same+ namespace are used. For this case we have a check further down.+ */+ if ((attId->name)[-1]) {+ if (enc == encoding)+ eventPtr = atts[i].name;+ return XML_ERROR_DUPLICATE_ATTRIBUTE;+ }+ (attId->name)[-1] = 1;+ appAtts[attIndex++] = attId->name;+ if (!atts[i].normalized) {+ enum XML_Error result;+ XML_Bool isCdata = XML_TRUE;++ /* figure out whether declared as other than CDATA */+ if (attId->maybeTokenized) {+ int j;+ for (j = 0; j < nDefaultAtts; j++) {+ if (attId == elementType->defaultAtts[j].id) {+ isCdata = elementType->defaultAtts[j].isCdata;+ break;+ }+ }+ }++ /* normalize the attribute value */+ result = storeAttributeValue(parser, enc, isCdata,+ atts[i].valuePtr, atts[i].valueEnd,+ &tempPool);+ if (result)+ return result;+ appAtts[attIndex] = poolStart(&tempPool);+ poolFinish(&tempPool);+ }+ else {+ /* the value did not need normalizing */+ appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,+ atts[i].valueEnd);+ if (appAtts[attIndex] == 0)+ return XML_ERROR_NO_MEMORY;+ poolFinish(&tempPool);+ }+ /* handle prefixed attribute names */+ if (attId->prefix) {+ if (attId->xmlns) {+ /* deal with namespace declarations here */+ enum XML_Error result = addBinding(parser, attId->prefix, attId,+ appAtts[attIndex], bindingsPtr);+ if (result)+ return result;+ --attIndex;+ }+ else {+ /* deal with other prefixed names later */+ attIndex++;+ nPrefixes++;+ (attId->name)[-1] = 2;+ }+ }+ else+ attIndex++;+ }++ /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */+ nSpecifiedAtts = attIndex;+ if (elementType->idAtt && (elementType->idAtt->name)[-1]) {+ for (i = 0; i < attIndex; i += 2)+ if (appAtts[i] == elementType->idAtt->name) {+ idAttIndex = i;+ break;+ }+ }+ else+ idAttIndex = -1;++ /* do attribute defaulting */+ for (i = 0; i < nDefaultAtts; i++) {+ const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;+ if (!(da->id->name)[-1] && da->value) {+ if (da->id->prefix) {+ if (da->id->xmlns) {+ enum XML_Error result = addBinding(parser, da->id->prefix, da->id,+ da->value, bindingsPtr);+ if (result)+ return result;+ }+ else {+ (da->id->name)[-1] = 2;+ nPrefixes++;+ appAtts[attIndex++] = da->id->name;+ appAtts[attIndex++] = da->value;+ }+ }+ else {+ (da->id->name)[-1] = 1;+ appAtts[attIndex++] = da->id->name;+ appAtts[attIndex++] = da->value;+ }+ }+ }+ appAtts[attIndex] = 0;++ /* expand prefixed attribute names, check for duplicates,+ and clear flags that say whether attributes were specified */+ i = 0;+ if (nPrefixes) {+ int j; /* hash table index */+ unsigned long version = nsAttsVersion;+ int nsAttsSize = (int)1 << nsAttsPower;+ /* size of hash table must be at least 2 * (# of prefixed attributes) */+ if ((nPrefixes << 1) >> nsAttsPower) { /* true for nsAttsPower = 0 */+ NS_ATT *temp;+ /* hash table size must also be a power of 2 and >= 8 */+ while (nPrefixes >> nsAttsPower++);+ if (nsAttsPower < 3)+ nsAttsPower = 3;+ nsAttsSize = (int)1 << nsAttsPower;+ temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));+ if (!temp)+ return XML_ERROR_NO_MEMORY;+ nsAtts = temp;+ version = 0; /* force re-initialization of nsAtts hash table */+ }+ /* using a version flag saves us from initializing nsAtts every time */+ if (!version) { /* initialize version flags when version wraps around */+ version = INIT_ATTS_VERSION;+ for (j = nsAttsSize; j != 0; )+ nsAtts[--j].version = version;+ }+ nsAttsVersion = --version;++ /* expand prefixed names and check for duplicates */+ for (; i < attIndex; i += 2) {+ const XML_Char *s = appAtts[i];+ if (s[-1] == 2) { /* prefixed */+ ATTRIBUTE_ID *id;+ const BINDING *b;+ unsigned long uriHash;+ struct siphash sip_state;+ struct sipkey sip_key;++ copy_salt_to_sipkey(parser, &sip_key);+ sip24_init(&sip_state, &sip_key);++ ((XML_Char *)s)[-1] = 0; /* clear flag */+ id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);+ if (!id || !id->prefix)+ return XML_ERROR_NO_MEMORY;+ b = id->prefix->binding;+ if (!b)+ return XML_ERROR_UNBOUND_PREFIX;++ for (j = 0; j < b->uriLen; j++) {+ const XML_Char c = b->uri[j];+ if (!poolAppendChar(&tempPool, c))+ return XML_ERROR_NO_MEMORY;+ }++ sip24_update(&sip_state, b->uri, b->uriLen * sizeof(XML_Char));++ while (*s++ != XML_T(ASCII_COLON))+ ;++ sip24_update(&sip_state, s, keylen(s) * sizeof(XML_Char));++ do { /* copies null terminator */+ if (!poolAppendChar(&tempPool, *s))+ return XML_ERROR_NO_MEMORY;+ } while (*s++);++ uriHash = (unsigned long)sip24_final(&sip_state);++ { /* Check hash table for duplicate of expanded name (uriName).+ Derived from code in lookup(parser, HASH_TABLE *table, ...).+ */+ unsigned char step = 0;+ unsigned long mask = nsAttsSize - 1;+ j = uriHash & mask; /* index into hash table */+ while (nsAtts[j].version == version) {+ /* for speed we compare stored hash values first */+ if (uriHash == nsAtts[j].hash) {+ const XML_Char *s1 = poolStart(&tempPool);+ const XML_Char *s2 = nsAtts[j].uriName;+ /* s1 is null terminated, but not s2 */+ for (; *s1 == *s2 && *s1 != 0; s1++, s2++);+ if (*s1 == 0)+ return XML_ERROR_DUPLICATE_ATTRIBUTE;+ }+ if (!step)+ step = PROBE_STEP(uriHash, mask, nsAttsPower);+ j < step ? (j += nsAttsSize - step) : (j -= step);+ }+ }++ if (ns_triplets) { /* append namespace separator and prefix */+ tempPool.ptr[-1] = namespaceSeparator;+ s = b->prefix->name;+ do {+ if (!poolAppendChar(&tempPool, *s))+ return XML_ERROR_NO_MEMORY;+ } while (*s++);+ }++ /* store expanded name in attribute list */+ s = poolStart(&tempPool);+ poolFinish(&tempPool);+ appAtts[i] = s;++ /* fill empty slot with new version, uriName and hash value */+ nsAtts[j].version = version;+ nsAtts[j].hash = uriHash;+ nsAtts[j].uriName = s;++ if (!--nPrefixes) {+ i += 2;+ break;+ }+ }+ else /* not prefixed */+ ((XML_Char *)s)[-1] = 0; /* clear flag */+ }+ }+ /* clear flags for the remaining attributes */+ for (; i < attIndex; i += 2)+ ((XML_Char *)(appAtts[i]))[-1] = 0;+ for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)+ binding->attId->name[-1] = 0;++ if (!ns)+ return XML_ERROR_NONE;++ /* expand the element type name */+ if (elementType->prefix) {+ binding = elementType->prefix->binding;+ if (!binding)+ return XML_ERROR_UNBOUND_PREFIX;+ localPart = tagNamePtr->str;+ while (*localPart++ != XML_T(ASCII_COLON))+ ;+ }+ else if (dtd->defaultPrefix.binding) {+ binding = dtd->defaultPrefix.binding;+ localPart = tagNamePtr->str;+ }+ else+ return XML_ERROR_NONE;+ prefixLen = 0;+ if (ns_triplets && binding->prefix->name) {+ for (; binding->prefix->name[prefixLen++];)+ ; /* prefixLen includes null terminator */+ }+ tagNamePtr->localPart = localPart;+ tagNamePtr->uriLen = binding->uriLen;+ tagNamePtr->prefix = binding->prefix->name;+ tagNamePtr->prefixLen = prefixLen;+ for (i = 0; localPart[i++];)+ ; /* i includes null terminator */+ n = i + binding->uriLen + prefixLen;+ if (n > binding->uriAlloc) {+ TAG *p;+ uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));+ if (!uri)+ return XML_ERROR_NO_MEMORY;+ binding->uriAlloc = n + EXPAND_SPARE;+ memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));+ for (p = tagStack; p; p = p->parent)+ if (p->name.str == binding->uri)+ p->name.str = uri;+ FREE(binding->uri);+ binding->uri = uri;+ }+ /* if namespaceSeparator != '\0' then uri includes it already */+ uri = binding->uri + binding->uriLen;+ memcpy(uri, localPart, i * sizeof(XML_Char));+ /* we always have a namespace separator between localPart and prefix */+ if (prefixLen) {+ uri += i - 1;+ *uri = namespaceSeparator; /* replace null terminator */+ memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));+ }+ tagNamePtr->str = binding->uri;+ return XML_ERROR_NONE;+}++/* addBinding() overwrites the value of prefix->binding without checking.+ Therefore one must keep track of the old value outside of addBinding().+*/+static enum XML_Error+addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,+ const XML_Char *uri, BINDING **bindingsPtr)+{+ static const XML_Char xmlNamespace[] = {+ ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,+ ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,+ ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L,+ ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH,+ ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c,+ ASCII_e, '\0'+ };+ static const int xmlLen =+ (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;+ static const XML_Char xmlnsNamespace[] = {+ ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,+ ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,+ ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0,+ ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s,+ ASCII_SLASH, '\0'+ };+ static const int xmlnsLen =+ (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;++ XML_Bool mustBeXML = XML_FALSE;+ XML_Bool isXML = XML_TRUE;+ XML_Bool isXMLNS = XML_TRUE;++ BINDING *b;+ int len;++ /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */+ if (*uri == XML_T('\0') && prefix->name)+ return XML_ERROR_UNDECLARING_PREFIX;++ if (prefix->name+ && prefix->name[0] == XML_T(ASCII_x)+ && prefix->name[1] == XML_T(ASCII_m)+ && prefix->name[2] == XML_T(ASCII_l)) {++ /* Not allowed to bind xmlns */+ if (prefix->name[3] == XML_T(ASCII_n)+ && prefix->name[4] == XML_T(ASCII_s)+ && prefix->name[5] == XML_T('\0'))+ return XML_ERROR_RESERVED_PREFIX_XMLNS;++ if (prefix->name[3] == XML_T('\0'))+ mustBeXML = XML_TRUE;+ }++ for (len = 0; uri[len]; len++) {+ if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))+ isXML = XML_FALSE;++ if (!mustBeXML && isXMLNS+ && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))+ isXMLNS = XML_FALSE;+ }+ isXML = isXML && len == xmlLen;+ isXMLNS = isXMLNS && len == xmlnsLen;++ if (mustBeXML != isXML)+ return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML+ : XML_ERROR_RESERVED_NAMESPACE_URI;++ if (isXMLNS)+ return XML_ERROR_RESERVED_NAMESPACE_URI;++ if (namespaceSeparator)+ len++;+ if (freeBindingList) {+ b = freeBindingList;+ if (len > b->uriAlloc) {+ XML_Char *temp = (XML_Char *)REALLOC(b->uri,+ sizeof(XML_Char) * (len + EXPAND_SPARE));+ if (temp == NULL)+ return XML_ERROR_NO_MEMORY;+ b->uri = temp;+ b->uriAlloc = len + EXPAND_SPARE;+ }+ freeBindingList = b->nextTagBinding;+ }+ else {+ b = (BINDING *)MALLOC(sizeof(BINDING));+ if (!b)+ return XML_ERROR_NO_MEMORY;+ b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));+ if (!b->uri) {+ FREE(b);+ return XML_ERROR_NO_MEMORY;+ }+ b->uriAlloc = len + EXPAND_SPARE;+ }+ b->uriLen = len;+ memcpy(b->uri, uri, len * sizeof(XML_Char));+ if (namespaceSeparator)+ b->uri[len - 1] = namespaceSeparator;+ b->prefix = prefix;+ b->attId = attId;+ b->prevPrefixBinding = prefix->binding;+ /* NULL binding when default namespace undeclared */+ if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)+ prefix->binding = NULL;+ else+ prefix->binding = b;+ b->nextTagBinding = *bindingsPtr;+ *bindingsPtr = b;+ /* if attId == NULL then we are not starting a namespace scope */+ if (attId && startNamespaceDeclHandler)+ startNamespaceDeclHandler(handlerArg, prefix->name,+ prefix->binding ? uri : 0);+ return XML_ERROR_NONE;+}++/* The idea here is to avoid using stack for each CDATA section when+ the whole file is parsed with one call.+*/+static enum XML_Error PTRCALL+cdataSectionProcessor(XML_Parser parser,+ const char *start,+ const char *end,+ const char **endPtr)+{+ enum XML_Error result = doCdataSection(parser, encoding, &start, end,+ endPtr, (XML_Bool)!ps_finalBuffer);+ if (result != XML_ERROR_NONE)+ return result;+ if (start) {+ if (parentParser) { /* we are parsing an external entity */+ processor = externalEntityContentProcessor;+ return externalEntityContentProcessor(parser, start, end, endPtr);+ }+ else {+ processor = contentProcessor;+ return contentProcessor(parser, start, end, endPtr);+ }+ }+ return result;+}++/* startPtr gets set to non-null if the section is closed, and to null if+ the section is not yet closed.+*/+static enum XML_Error+doCdataSection(XML_Parser parser,+ const ENCODING *enc,+ const char **startPtr,+ const char *end,+ const char **nextPtr,+ XML_Bool haveMore)+{+ const char *s = *startPtr;+ const char **eventPP;+ const char **eventEndPP;+ if (enc == encoding) {+ eventPP = &eventPtr;+ *eventPP = s;+ eventEndPP = &eventEndPtr;+ }+ else {+ eventPP = &(openInternalEntities->internalEventPtr);+ eventEndPP = &(openInternalEntities->internalEventEndPtr);+ }+ *eventPP = s;+ *startPtr = NULL;++ for (;;) {+ const char *next;+ int tok = XmlCdataSectionTok(enc, s, end, &next);+ *eventEndPP = next;+ switch (tok) {+ case XML_TOK_CDATA_SECT_CLOSE:+ if (endCdataSectionHandler)+ endCdataSectionHandler(handlerArg);+#if 0+ /* see comment under XML_TOK_CDATA_SECT_OPEN */+ else if (characterDataHandler)+ characterDataHandler(handlerArg, dataBuf, 0);+#endif+ else if (defaultHandler)+ reportDefault(parser, enc, s, next);+ *startPtr = next;+ *nextPtr = next;+ if (ps_parsing == XML_FINISHED)+ return XML_ERROR_ABORTED;+ else+ return XML_ERROR_NONE;+ case XML_TOK_DATA_NEWLINE:+ if (characterDataHandler) {+ XML_Char c = 0xA;+ characterDataHandler(handlerArg, &c, 1);+ }+ else if (defaultHandler)+ reportDefault(parser, enc, s, next);+ break;+ case XML_TOK_DATA_CHARS:+ {+ XML_CharacterDataHandler charDataHandler = characterDataHandler;+ if (charDataHandler) {+ if (MUST_CONVERT(enc, s)) {+ for (;;) {+ ICHAR *dataPtr = (ICHAR *)dataBuf;+ const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);+ *eventEndPP = next;+ charDataHandler(handlerArg, dataBuf,+ (int)(dataPtr - (ICHAR *)dataBuf));+ if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))+ break;+ *eventPP = s;+ }+ }+ else+ charDataHandler(handlerArg,+ (XML_Char *)s,+ (int)((XML_Char *)next - (XML_Char *)s));+ }+ else if (defaultHandler)+ reportDefault(parser, enc, s, next);+ }+ break;+ case XML_TOK_INVALID:+ *eventPP = next;+ return XML_ERROR_INVALID_TOKEN;+ case XML_TOK_PARTIAL_CHAR:+ if (haveMore) {+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ return XML_ERROR_PARTIAL_CHAR;+ case XML_TOK_PARTIAL:+ case XML_TOK_NONE:+ if (haveMore) {+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ return XML_ERROR_UNCLOSED_CDATA_SECTION;+ default:+ *eventPP = next;+ return XML_ERROR_UNEXPECTED_STATE;+ }++ *eventPP = s = next;+ switch (ps_parsing) {+ case XML_SUSPENDED:+ *nextPtr = next;+ return XML_ERROR_NONE;+ case XML_FINISHED:+ return XML_ERROR_ABORTED;+ default: ;+ }+ }+ /* not reached */+}++#ifdef XML_DTD++/* The idea here is to avoid using stack for each IGNORE section when+ the whole file is parsed with one call.+*/+static enum XML_Error PTRCALL+ignoreSectionProcessor(XML_Parser parser,+ const char *start,+ const char *end,+ const char **endPtr)+{+ enum XML_Error result = doIgnoreSection(parser, encoding, &start, end,+ endPtr, (XML_Bool)!ps_finalBuffer);+ if (result != XML_ERROR_NONE)+ return result;+ if (start) {+ processor = prologProcessor;+ return prologProcessor(parser, start, end, endPtr);+ }+ return result;+}++/* startPtr gets set to non-null is the section is closed, and to null+ if the section is not yet closed.+*/+static enum XML_Error+doIgnoreSection(XML_Parser parser,+ const ENCODING *enc,+ const char **startPtr,+ const char *end,+ const char **nextPtr,+ XML_Bool haveMore)+{+ const char *next;+ int tok;+ const char *s = *startPtr;+ const char **eventPP;+ const char **eventEndPP;+ if (enc == encoding) {+ eventPP = &eventPtr;+ *eventPP = s;+ eventEndPP = &eventEndPtr;+ }+ else {+ eventPP = &(openInternalEntities->internalEventPtr);+ eventEndPP = &(openInternalEntities->internalEventEndPtr);+ }+ *eventPP = s;+ *startPtr = NULL;+ tok = XmlIgnoreSectionTok(enc, s, end, &next);+ *eventEndPP = next;+ switch (tok) {+ case XML_TOK_IGNORE_SECT:+ if (defaultHandler)+ reportDefault(parser, enc, s, next);+ *startPtr = next;+ *nextPtr = next;+ if (ps_parsing == XML_FINISHED)+ return XML_ERROR_ABORTED;+ else+ return XML_ERROR_NONE;+ case XML_TOK_INVALID:+ *eventPP = next;+ return XML_ERROR_INVALID_TOKEN;+ case XML_TOK_PARTIAL_CHAR:+ if (haveMore) {+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ return XML_ERROR_PARTIAL_CHAR;+ case XML_TOK_PARTIAL:+ case XML_TOK_NONE:+ if (haveMore) {+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */+ default:+ *eventPP = next;+ return XML_ERROR_UNEXPECTED_STATE;+ }+ /* not reached */+}++#endif /* XML_DTD */++static enum XML_Error+initializeEncoding(XML_Parser parser)+{+ const char *s;+#ifdef XML_UNICODE+ char encodingBuf[128];+ if (!protocolEncodingName)+ s = NULL;+ else {+ int i;+ for (i = 0; protocolEncodingName[i]; i++) {+ if (i == sizeof(encodingBuf) - 1+ || (protocolEncodingName[i] & ~0x7f) != 0) {+ encodingBuf[0] = '\0';+ break;+ }+ encodingBuf[i] = (char)protocolEncodingName[i];+ }+ encodingBuf[i] = '\0';+ s = encodingBuf;+ }+#else+ s = protocolEncodingName;+#endif+ if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))+ return XML_ERROR_NONE;+ return handleUnknownEncoding(parser, protocolEncodingName);+}++static enum XML_Error+processXmlDecl(XML_Parser parser, int isGeneralTextEntity,+ const char *s, const char *next)+{+ const char *encodingName = NULL;+ const XML_Char *storedEncName = NULL;+ const ENCODING *newEncoding = NULL;+ const char *version = NULL;+ const char *versionend;+ const XML_Char *storedversion = NULL;+ int standalone = -1;+ if (!(ns+ ? XmlParseXmlDeclNS+ : XmlParseXmlDecl)(isGeneralTextEntity,+ encoding,+ s,+ next,+ &eventPtr,+ &version,+ &versionend,+ &encodingName,+ &newEncoding,+ &standalone)) {+ if (isGeneralTextEntity)+ return XML_ERROR_TEXT_DECL;+ else+ return XML_ERROR_XML_DECL;+ }+ if (!isGeneralTextEntity && standalone == 1) {+ _dtd->standalone = XML_TRUE;+#ifdef XML_DTD+ if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)+ paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;+#endif /* XML_DTD */+ }+ if (xmlDeclHandler) {+ if (encodingName != NULL) {+ storedEncName = poolStoreString(&temp2Pool,+ encoding,+ encodingName,+ encodingName+ + XmlNameLength(encoding, encodingName));+ if (!storedEncName)+ return XML_ERROR_NO_MEMORY;+ poolFinish(&temp2Pool);+ }+ if (version) {+ storedversion = poolStoreString(&temp2Pool,+ encoding,+ version,+ versionend - encoding->minBytesPerChar);+ if (!storedversion)+ return XML_ERROR_NO_MEMORY;+ }+ xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);+ }+ else if (defaultHandler)+ reportDefault(parser, encoding, s, next);+ if (protocolEncodingName == NULL) {+ if (newEncoding) {+ if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {+ eventPtr = encodingName;+ return XML_ERROR_INCORRECT_ENCODING;+ }+ encoding = newEncoding;+ }+ else if (encodingName) {+ enum XML_Error result;+ if (!storedEncName) {+ storedEncName = poolStoreString(+ &temp2Pool, encoding, encodingName,+ encodingName + XmlNameLength(encoding, encodingName));+ if (!storedEncName)+ return XML_ERROR_NO_MEMORY;+ }+ result = handleUnknownEncoding(parser, storedEncName);+ poolClear(&temp2Pool);+ if (result == XML_ERROR_UNKNOWN_ENCODING)+ eventPtr = encodingName;+ return result;+ }+ }++ if (storedEncName || storedversion)+ poolClear(&temp2Pool);++ return XML_ERROR_NONE;+}++static enum XML_Error+handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)+{+ if (unknownEncodingHandler) {+ XML_Encoding info;+ int i;+ for (i = 0; i < 256; i++)+ info.map[i] = -1;+ info.convert = NULL;+ info.data = NULL;+ info.release = NULL;+ if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,+ &info)) {+ ENCODING *enc;+ unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());+ if (!unknownEncodingMem) {+ if (info.release)+ info.release(info.data);+ return XML_ERROR_NO_MEMORY;+ }+ enc = (ns+ ? XmlInitUnknownEncodingNS+ : XmlInitUnknownEncoding)(unknownEncodingMem,+ info.map,+ info.convert,+ info.data);+ if (enc) {+ unknownEncodingData = info.data;+ unknownEncodingRelease = info.release;+ encoding = enc;+ return XML_ERROR_NONE;+ }+ }+ if (info.release != NULL)+ info.release(info.data);+ }+ return XML_ERROR_UNKNOWN_ENCODING;+}++static enum XML_Error PTRCALL+prologInitProcessor(XML_Parser parser,+ const char *s,+ const char *end,+ const char **nextPtr)+{+ enum XML_Error result = initializeEncoding(parser);+ if (result != XML_ERROR_NONE)+ return result;+ processor = prologProcessor;+ return prologProcessor(parser, s, end, nextPtr);+}++#ifdef XML_DTD++static enum XML_Error PTRCALL+externalParEntInitProcessor(XML_Parser parser,+ const char *s,+ const char *end,+ const char **nextPtr)+{+ enum XML_Error result = initializeEncoding(parser);+ if (result != XML_ERROR_NONE)+ return result;++ /* we know now that XML_Parse(Buffer) has been called,+ so we consider the external parameter entity read */+ _dtd->paramEntityRead = XML_TRUE;++ if (prologState.inEntityValue) {+ processor = entityValueInitProcessor;+ return entityValueInitProcessor(parser, s, end, nextPtr);+ }+ else {+ processor = externalParEntProcessor;+ return externalParEntProcessor(parser, s, end, nextPtr);+ }+}++static enum XML_Error PTRCALL+entityValueInitProcessor(XML_Parser parser,+ const char *s,+ const char *end,+ const char **nextPtr)+{+ int tok;+ const char *start = s;+ const char *next = start;+ eventPtr = start;++ for (;;) {+ tok = XmlPrologTok(encoding, start, end, &next);+ eventEndPtr = next;+ if (tok <= 0) {+ if (!ps_finalBuffer && tok != XML_TOK_INVALID) {+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ switch (tok) {+ case XML_TOK_INVALID:+ return XML_ERROR_INVALID_TOKEN;+ case XML_TOK_PARTIAL:+ return XML_ERROR_UNCLOSED_TOKEN;+ case XML_TOK_PARTIAL_CHAR:+ return XML_ERROR_PARTIAL_CHAR;+ case XML_TOK_NONE: /* start == end */+ default:+ break;+ }+ /* found end of entity value - can store it now */+ return storeEntityValue(parser, encoding, s, end);+ }+ else if (tok == XML_TOK_XML_DECL) {+ enum XML_Error result;+ result = processXmlDecl(parser, 0, start, next);+ if (result != XML_ERROR_NONE)+ return result;+ switch (ps_parsing) {+ case XML_SUSPENDED:+ *nextPtr = next;+ return XML_ERROR_NONE;+ case XML_FINISHED:+ return XML_ERROR_ABORTED;+ default:+ *nextPtr = next;+ }+ /* stop scanning for text declaration - we found one */+ processor = entityValueProcessor;+ return entityValueProcessor(parser, next, end, nextPtr);+ }+ /* If we are at the end of the buffer, this would cause XmlPrologTok to+ return XML_TOK_NONE on the next call, which would then cause the+ function to exit with *nextPtr set to s - that is what we want for other+ tokens, but not for the BOM - we would rather like to skip it;+ then, when this routine is entered the next time, XmlPrologTok will+ return XML_TOK_INVALID, since the BOM is still in the buffer+ */+ else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {+ *nextPtr = next;+ return XML_ERROR_NONE;+ }+ /* If we get this token, we have the start of what might be a+ normal tag, but not a declaration (i.e. it doesn't begin with+ "<!"). In a DTD context, that isn't legal.+ */+ else if (tok == XML_TOK_INSTANCE_START) {+ *nextPtr = next;+ return XML_ERROR_SYNTAX;+ }+ start = next;+ eventPtr = start;+ }+}++static enum XML_Error PTRCALL+externalParEntProcessor(XML_Parser parser,+ const char *s,+ const char *end,+ const char **nextPtr)+{+ const char *next = s;+ int tok;++ tok = XmlPrologTok(encoding, s, end, &next);+ if (tok <= 0) {+ if (!ps_finalBuffer && tok != XML_TOK_INVALID) {+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ switch (tok) {+ case XML_TOK_INVALID:+ return XML_ERROR_INVALID_TOKEN;+ case XML_TOK_PARTIAL:+ return XML_ERROR_UNCLOSED_TOKEN;+ case XML_TOK_PARTIAL_CHAR:+ return XML_ERROR_PARTIAL_CHAR;+ case XML_TOK_NONE: /* start == end */+ default:+ break;+ }+ }+ /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.+ However, when parsing an external subset, doProlog will not accept a BOM+ as valid, and report a syntax error, so we have to skip the BOM+ */+ else if (tok == XML_TOK_BOM) {+ s = next;+ tok = XmlPrologTok(encoding, s, end, &next);+ }++ processor = prologProcessor;+ return doProlog(parser, encoding, s, end, tok, next,+ nextPtr, (XML_Bool)!ps_finalBuffer);+}++static enum XML_Error PTRCALL+entityValueProcessor(XML_Parser parser,+ const char *s,+ const char *end,+ const char **nextPtr)+{+ const char *start = s;+ const char *next = s;+ const ENCODING *enc = encoding;+ int tok;++ for (;;) {+ tok = XmlPrologTok(enc, start, end, &next);+ if (tok <= 0) {+ if (!ps_finalBuffer && tok != XML_TOK_INVALID) {+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ switch (tok) {+ case XML_TOK_INVALID:+ return XML_ERROR_INVALID_TOKEN;+ case XML_TOK_PARTIAL:+ return XML_ERROR_UNCLOSED_TOKEN;+ case XML_TOK_PARTIAL_CHAR:+ return XML_ERROR_PARTIAL_CHAR;+ case XML_TOK_NONE: /* start == end */+ default:+ break;+ }+ /* found end of entity value - can store it now */+ return storeEntityValue(parser, enc, s, end);+ }+ start = next;+ }+}++#endif /* XML_DTD */++static enum XML_Error PTRCALL+prologProcessor(XML_Parser parser,+ const char *s,+ const char *end,+ const char **nextPtr)+{+ const char *next = s;+ int tok = XmlPrologTok(encoding, s, end, &next);+ return doProlog(parser, encoding, s, end, tok, next,+ nextPtr, (XML_Bool)!ps_finalBuffer);+}++static enum XML_Error+doProlog(XML_Parser parser,+ const ENCODING *enc,+ const char *s,+ const char *end,+ int tok,+ const char *next,+ const char **nextPtr,+ XML_Bool haveMore)+{+#ifdef XML_DTD+ static const XML_Char externalSubsetName[] = { ASCII_HASH , '\0' };+#endif /* XML_DTD */+ static const XML_Char atypeCDATA[] =+ { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };+ static const XML_Char atypeID[] = { ASCII_I, ASCII_D, '\0' };+ static const XML_Char atypeIDREF[] =+ { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };+ static const XML_Char atypeIDREFS[] =+ { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };+ static const XML_Char atypeENTITY[] =+ { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };+ static const XML_Char atypeENTITIES[] = { ASCII_E, ASCII_N,+ ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0' };+ static const XML_Char atypeNMTOKEN[] = {+ ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' };+ static const XML_Char atypeNMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T,+ ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' };+ static const XML_Char notationPrefix[] = { ASCII_N, ASCII_O, ASCII_T,+ ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0' };+ static const XML_Char enumValueSep[] = { ASCII_PIPE, '\0' };+ static const XML_Char enumValueStart[] = { ASCII_LPAREN, '\0' };++ /* save one level of indirection */+ DTD * const dtd = _dtd;++ const char **eventPP;+ const char **eventEndPP;+ enum XML_Content_Quant quant;++ if (enc == encoding) {+ eventPP = &eventPtr;+ eventEndPP = &eventEndPtr;+ }+ else {+ eventPP = &(openInternalEntities->internalEventPtr);+ eventEndPP = &(openInternalEntities->internalEventEndPtr);+ }++ for (;;) {+ int role;+ XML_Bool handleDefault = XML_TRUE;+ *eventPP = s;+ *eventEndPP = next;+ if (tok <= 0) {+ if (haveMore && tok != XML_TOK_INVALID) {+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ switch (tok) {+ case XML_TOK_INVALID:+ *eventPP = next;+ return XML_ERROR_INVALID_TOKEN;+ case XML_TOK_PARTIAL:+ return XML_ERROR_UNCLOSED_TOKEN;+ case XML_TOK_PARTIAL_CHAR:+ return XML_ERROR_PARTIAL_CHAR;+ case -XML_TOK_PROLOG_S:+ tok = -tok;+ break;+ case XML_TOK_NONE:+#ifdef XML_DTD+ /* for internal PE NOT referenced between declarations */+ if (enc != encoding && !openInternalEntities->betweenDecl) {+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ /* WFC: PE Between Declarations - must check that PE contains+ complete markup, not only for external PEs, but also for+ internal PEs if the reference occurs between declarations.+ */+ if (isParamEntity || enc != encoding) {+ if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)+ == XML_ROLE_ERROR)+ return XML_ERROR_INCOMPLETE_PE;+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+#endif /* XML_DTD */+ return XML_ERROR_NO_ELEMENTS;+ default:+ tok = -tok;+ next = end;+ break;+ }+ }+ role = XmlTokenRole(&prologState, tok, s, next, enc);+ switch (role) {+ case XML_ROLE_XML_DECL:+ {+ enum XML_Error result = processXmlDecl(parser, 0, s, next);+ if (result != XML_ERROR_NONE)+ return result;+ enc = encoding;+ handleDefault = XML_FALSE;+ }+ break;+ case XML_ROLE_DOCTYPE_NAME:+ if (startDoctypeDeclHandler) {+ doctypeName = poolStoreString(&tempPool, enc, s, next);+ if (!doctypeName)+ return XML_ERROR_NO_MEMORY;+ poolFinish(&tempPool);+ doctypePubid = NULL;+ handleDefault = XML_FALSE;+ }+ doctypeSysid = NULL; /* always initialize to NULL */+ break;+ case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:+ if (startDoctypeDeclHandler) {+ startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,+ doctypePubid, 1);+ doctypeName = NULL;+ poolClear(&tempPool);+ handleDefault = XML_FALSE;+ }+ break;+#ifdef XML_DTD+ case XML_ROLE_TEXT_DECL:+ {+ enum XML_Error result = processXmlDecl(parser, 1, s, next);+ if (result != XML_ERROR_NONE)+ return result;+ enc = encoding;+ handleDefault = XML_FALSE;+ }+ break;+#endif /* XML_DTD */+ case XML_ROLE_DOCTYPE_PUBLIC_ID:+#ifdef XML_DTD+ useForeignDTD = XML_FALSE;+ declEntity = (ENTITY *)lookup(parser,+ &dtd->paramEntities,+ externalSubsetName,+ sizeof(ENTITY));+ if (!declEntity)+ return XML_ERROR_NO_MEMORY;+#endif /* XML_DTD */+ dtd->hasParamEntityRefs = XML_TRUE;+ if (startDoctypeDeclHandler) {+ XML_Char *pubId;+ if (!XmlIsPublicId(enc, s, next, eventPP))+ return XML_ERROR_PUBLICID;+ pubId = poolStoreString(&tempPool, enc,+ s + enc->minBytesPerChar,+ next - enc->minBytesPerChar);+ if (!pubId)+ return XML_ERROR_NO_MEMORY;+ normalizePublicId(pubId);+ poolFinish(&tempPool);+ doctypePubid = pubId;+ handleDefault = XML_FALSE;+ goto alreadyChecked;+ }+ /* fall through */+ case XML_ROLE_ENTITY_PUBLIC_ID:+ if (!XmlIsPublicId(enc, s, next, eventPP))+ return XML_ERROR_PUBLICID;+ alreadyChecked:+ if (dtd->keepProcessing && declEntity) {+ XML_Char *tem = poolStoreString(&dtd->pool,+ enc,+ s + enc->minBytesPerChar,+ next - enc->minBytesPerChar);+ if (!tem)+ return XML_ERROR_NO_MEMORY;+ normalizePublicId(tem);+ declEntity->publicId = tem;+ poolFinish(&dtd->pool);+ if (entityDeclHandler)+ handleDefault = XML_FALSE;+ }+ break;+ case XML_ROLE_DOCTYPE_CLOSE:+ if (doctypeName) {+ startDoctypeDeclHandler(handlerArg, doctypeName,+ doctypeSysid, doctypePubid, 0);+ poolClear(&tempPool);+ handleDefault = XML_FALSE;+ }+ /* doctypeSysid will be non-NULL in the case of a previous+ XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler+ was not set, indicating an external subset+ */+#ifdef XML_DTD+ if (doctypeSysid || useForeignDTD) {+ XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;+ dtd->hasParamEntityRefs = XML_TRUE;+ if (paramEntityParsing && externalEntityRefHandler) {+ ENTITY *entity = (ENTITY *)lookup(parser,+ &dtd->paramEntities,+ externalSubsetName,+ sizeof(ENTITY));+ if (!entity)+ return XML_ERROR_NO_MEMORY;+ if (useForeignDTD)+ entity->base = curBase;+ dtd->paramEntityRead = XML_FALSE;+ if (!externalEntityRefHandler(externalEntityRefHandlerArg,+ 0,+ entity->base,+ entity->systemId,+ entity->publicId))+ return XML_ERROR_EXTERNAL_ENTITY_HANDLING;+ if (dtd->paramEntityRead) {+ if (!dtd->standalone &&+ notStandaloneHandler &&+ !notStandaloneHandler(handlerArg))+ return XML_ERROR_NOT_STANDALONE;+ }+ /* if we didn't read the foreign DTD then this means that there+ is no external subset and we must reset dtd->hasParamEntityRefs+ */+ else if (!doctypeSysid)+ dtd->hasParamEntityRefs = hadParamEntityRefs;+ /* end of DTD - no need to update dtd->keepProcessing */+ }+ useForeignDTD = XML_FALSE;+ }+#endif /* XML_DTD */+ if (endDoctypeDeclHandler) {+ endDoctypeDeclHandler(handlerArg);+ handleDefault = XML_FALSE;+ }+ break;+ case XML_ROLE_INSTANCE_START:+#ifdef XML_DTD+ /* if there is no DOCTYPE declaration then now is the+ last chance to read the foreign DTD+ */+ if (useForeignDTD) {+ XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;+ dtd->hasParamEntityRefs = XML_TRUE;+ if (paramEntityParsing && externalEntityRefHandler) {+ ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,+ externalSubsetName,+ sizeof(ENTITY));+ if (!entity)+ return XML_ERROR_NO_MEMORY;+ entity->base = curBase;+ dtd->paramEntityRead = XML_FALSE;+ if (!externalEntityRefHandler(externalEntityRefHandlerArg,+ 0,+ entity->base,+ entity->systemId,+ entity->publicId))+ return XML_ERROR_EXTERNAL_ENTITY_HANDLING;+ if (dtd->paramEntityRead) {+ if (!dtd->standalone &&+ notStandaloneHandler &&+ !notStandaloneHandler(handlerArg))+ return XML_ERROR_NOT_STANDALONE;+ }+ /* if we didn't read the foreign DTD then this means that there+ is no external subset and we must reset dtd->hasParamEntityRefs+ */+ else+ dtd->hasParamEntityRefs = hadParamEntityRefs;+ /* end of DTD - no need to update dtd->keepProcessing */+ }+ }+#endif /* XML_DTD */+ processor = contentProcessor;+ return contentProcessor(parser, s, end, nextPtr);+ case XML_ROLE_ATTLIST_ELEMENT_NAME:+ declElementType = getElementType(parser, enc, s, next);+ if (!declElementType)+ return XML_ERROR_NO_MEMORY;+ goto checkAttListDeclHandler;+ case XML_ROLE_ATTRIBUTE_NAME:+ declAttributeId = getAttributeId(parser, enc, s, next);+ if (!declAttributeId)+ return XML_ERROR_NO_MEMORY;+ declAttributeIsCdata = XML_FALSE;+ declAttributeType = NULL;+ declAttributeIsId = XML_FALSE;+ goto checkAttListDeclHandler;+ case XML_ROLE_ATTRIBUTE_TYPE_CDATA:+ declAttributeIsCdata = XML_TRUE;+ declAttributeType = atypeCDATA;+ goto checkAttListDeclHandler;+ case XML_ROLE_ATTRIBUTE_TYPE_ID:+ declAttributeIsId = XML_TRUE;+ declAttributeType = atypeID;+ goto checkAttListDeclHandler;+ case XML_ROLE_ATTRIBUTE_TYPE_IDREF:+ declAttributeType = atypeIDREF;+ goto checkAttListDeclHandler;+ case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:+ declAttributeType = atypeIDREFS;+ goto checkAttListDeclHandler;+ case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:+ declAttributeType = atypeENTITY;+ goto checkAttListDeclHandler;+ case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:+ declAttributeType = atypeENTITIES;+ goto checkAttListDeclHandler;+ case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:+ declAttributeType = atypeNMTOKEN;+ goto checkAttListDeclHandler;+ case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:+ declAttributeType = atypeNMTOKENS;+ checkAttListDeclHandler:+ if (dtd->keepProcessing && attlistDeclHandler)+ handleDefault = XML_FALSE;+ break;+ case XML_ROLE_ATTRIBUTE_ENUM_VALUE:+ case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:+ if (dtd->keepProcessing && attlistDeclHandler) {+ const XML_Char *prefix;+ if (declAttributeType) {+ prefix = enumValueSep;+ }+ else {+ prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE+ ? notationPrefix+ : enumValueStart);+ }+ if (!poolAppendString(&tempPool, prefix))+ return XML_ERROR_NO_MEMORY;+ if (!poolAppend(&tempPool, enc, s, next))+ return XML_ERROR_NO_MEMORY;+ declAttributeType = tempPool.start;+ handleDefault = XML_FALSE;+ }+ break;+ case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:+ case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:+ if (dtd->keepProcessing) {+ if (!defineAttribute(declElementType, declAttributeId,+ declAttributeIsCdata, declAttributeIsId,+ 0, parser))+ return XML_ERROR_NO_MEMORY;+ if (attlistDeclHandler && declAttributeType) {+ if (*declAttributeType == XML_T(ASCII_LPAREN)+ || (*declAttributeType == XML_T(ASCII_N)+ && declAttributeType[1] == XML_T(ASCII_O))) {+ /* Enumerated or Notation type */+ if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))+ || !poolAppendChar(&tempPool, XML_T('\0')))+ return XML_ERROR_NO_MEMORY;+ declAttributeType = tempPool.start;+ poolFinish(&tempPool);+ }+ *eventEndPP = s;+ attlistDeclHandler(handlerArg, declElementType->name,+ declAttributeId->name, declAttributeType,+ 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);+ poolClear(&tempPool);+ handleDefault = XML_FALSE;+ }+ }+ break;+ case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:+ case XML_ROLE_FIXED_ATTRIBUTE_VALUE:+ if (dtd->keepProcessing) {+ const XML_Char *attVal;+ enum XML_Error result =+ storeAttributeValue(parser, enc, declAttributeIsCdata,+ s + enc->minBytesPerChar,+ next - enc->minBytesPerChar,+ &dtd->pool);+ if (result)+ return result;+ attVal = poolStart(&dtd->pool);+ poolFinish(&dtd->pool);+ /* ID attributes aren't allowed to have a default */+ if (!defineAttribute(declElementType, declAttributeId,+ declAttributeIsCdata, XML_FALSE, attVal, parser))+ return XML_ERROR_NO_MEMORY;+ if (attlistDeclHandler && declAttributeType) {+ if (*declAttributeType == XML_T(ASCII_LPAREN)+ || (*declAttributeType == XML_T(ASCII_N)+ && declAttributeType[1] == XML_T(ASCII_O))) {+ /* Enumerated or Notation type */+ if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))+ || !poolAppendChar(&tempPool, XML_T('\0')))+ return XML_ERROR_NO_MEMORY;+ declAttributeType = tempPool.start;+ poolFinish(&tempPool);+ }+ *eventEndPP = s;+ attlistDeclHandler(handlerArg, declElementType->name,+ declAttributeId->name, declAttributeType,+ attVal,+ role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);+ poolClear(&tempPool);+ handleDefault = XML_FALSE;+ }+ }+ break;+ case XML_ROLE_ENTITY_VALUE:+ if (dtd->keepProcessing) {+ enum XML_Error result = storeEntityValue(parser, enc,+ s + enc->minBytesPerChar,+ next - enc->minBytesPerChar);+ if (declEntity) {+ declEntity->textPtr = poolStart(&dtd->entityValuePool);+ declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));+ poolFinish(&dtd->entityValuePool);+ if (entityDeclHandler) {+ *eventEndPP = s;+ entityDeclHandler(handlerArg,+ declEntity->name,+ declEntity->is_param,+ declEntity->textPtr,+ declEntity->textLen,+ curBase, 0, 0, 0);+ handleDefault = XML_FALSE;+ }+ }+ else+ poolDiscard(&dtd->entityValuePool);+ if (result != XML_ERROR_NONE)+ return result;+ }+ break;+ case XML_ROLE_DOCTYPE_SYSTEM_ID:+#ifdef XML_DTD+ useForeignDTD = XML_FALSE;+#endif /* XML_DTD */+ dtd->hasParamEntityRefs = XML_TRUE;+ if (startDoctypeDeclHandler) {+ doctypeSysid = poolStoreString(&tempPool, enc,+ s + enc->minBytesPerChar,+ next - enc->minBytesPerChar);+ if (doctypeSysid == NULL)+ return XML_ERROR_NO_MEMORY;+ poolFinish(&tempPool);+ handleDefault = XML_FALSE;+ }+#ifdef XML_DTD+ else+ /* use externalSubsetName to make doctypeSysid non-NULL+ for the case where no startDoctypeDeclHandler is set */+ doctypeSysid = externalSubsetName;+#endif /* XML_DTD */+ if (!dtd->standalone+#ifdef XML_DTD+ && !paramEntityParsing+#endif /* XML_DTD */+ && notStandaloneHandler+ && !notStandaloneHandler(handlerArg))+ return XML_ERROR_NOT_STANDALONE;+#ifndef XML_DTD+ break;+#else /* XML_DTD */+ if (!declEntity) {+ declEntity = (ENTITY *)lookup(parser,+ &dtd->paramEntities,+ externalSubsetName,+ sizeof(ENTITY));+ if (!declEntity)+ return XML_ERROR_NO_MEMORY;+ declEntity->publicId = NULL;+ }+ /* fall through */+#endif /* XML_DTD */+ case XML_ROLE_ENTITY_SYSTEM_ID:+ if (dtd->keepProcessing && declEntity) {+ declEntity->systemId = poolStoreString(&dtd->pool, enc,+ s + enc->minBytesPerChar,+ next - enc->minBytesPerChar);+ if (!declEntity->systemId)+ return XML_ERROR_NO_MEMORY;+ declEntity->base = curBase;+ poolFinish(&dtd->pool);+ if (entityDeclHandler)+ handleDefault = XML_FALSE;+ }+ break;+ case XML_ROLE_ENTITY_COMPLETE:+ if (dtd->keepProcessing && declEntity && entityDeclHandler) {+ *eventEndPP = s;+ entityDeclHandler(handlerArg,+ declEntity->name,+ declEntity->is_param,+ 0,0,+ declEntity->base,+ declEntity->systemId,+ declEntity->publicId,+ 0);+ handleDefault = XML_FALSE;+ }+ break;+ case XML_ROLE_ENTITY_NOTATION_NAME:+ if (dtd->keepProcessing && declEntity) {+ declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);+ if (!declEntity->notation)+ return XML_ERROR_NO_MEMORY;+ poolFinish(&dtd->pool);+ if (unparsedEntityDeclHandler) {+ *eventEndPP = s;+ unparsedEntityDeclHandler(handlerArg,+ declEntity->name,+ declEntity->base,+ declEntity->systemId,+ declEntity->publicId,+ declEntity->notation);+ handleDefault = XML_FALSE;+ }+ else if (entityDeclHandler) {+ *eventEndPP = s;+ entityDeclHandler(handlerArg,+ declEntity->name,+ 0,0,0,+ declEntity->base,+ declEntity->systemId,+ declEntity->publicId,+ declEntity->notation);+ handleDefault = XML_FALSE;+ }+ }+ break;+ case XML_ROLE_GENERAL_ENTITY_NAME:+ {+ if (XmlPredefinedEntityName(enc, s, next)) {+ declEntity = NULL;+ break;+ }+ if (dtd->keepProcessing) {+ const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);+ if (!name)+ return XML_ERROR_NO_MEMORY;+ declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, name,+ sizeof(ENTITY));+ if (!declEntity)+ return XML_ERROR_NO_MEMORY;+ if (declEntity->name != name) {+ poolDiscard(&dtd->pool);+ declEntity = NULL;+ }+ else {+ poolFinish(&dtd->pool);+ declEntity->publicId = NULL;+ declEntity->is_param = XML_FALSE;+ /* if we have a parent parser or are reading an internal parameter+ entity, then the entity declaration is not considered "internal"+ */+ declEntity->is_internal = !(parentParser || openInternalEntities);+ if (entityDeclHandler)+ handleDefault = XML_FALSE;+ }+ }+ else {+ poolDiscard(&dtd->pool);+ declEntity = NULL;+ }+ }+ break;+ case XML_ROLE_PARAM_ENTITY_NAME:+#ifdef XML_DTD+ if (dtd->keepProcessing) {+ const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);+ if (!name)+ return XML_ERROR_NO_MEMORY;+ declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities,+ name, sizeof(ENTITY));+ if (!declEntity)+ return XML_ERROR_NO_MEMORY;+ if (declEntity->name != name) {+ poolDiscard(&dtd->pool);+ declEntity = NULL;+ }+ else {+ poolFinish(&dtd->pool);+ declEntity->publicId = NULL;+ declEntity->is_param = XML_TRUE;+ /* if we have a parent parser or are reading an internal parameter+ entity, then the entity declaration is not considered "internal"+ */+ declEntity->is_internal = !(parentParser || openInternalEntities);+ if (entityDeclHandler)+ handleDefault = XML_FALSE;+ }+ }+ else {+ poolDiscard(&dtd->pool);+ declEntity = NULL;+ }+#else /* not XML_DTD */+ declEntity = NULL;+#endif /* XML_DTD */+ break;+ case XML_ROLE_NOTATION_NAME:+ declNotationPublicId = NULL;+ declNotationName = NULL;+ if (notationDeclHandler) {+ declNotationName = poolStoreString(&tempPool, enc, s, next);+ if (!declNotationName)+ return XML_ERROR_NO_MEMORY;+ poolFinish(&tempPool);+ handleDefault = XML_FALSE;+ }+ break;+ case XML_ROLE_NOTATION_PUBLIC_ID:+ if (!XmlIsPublicId(enc, s, next, eventPP))+ return XML_ERROR_PUBLICID;+ if (declNotationName) { /* means notationDeclHandler != NULL */+ XML_Char *tem = poolStoreString(&tempPool,+ enc,+ s + enc->minBytesPerChar,+ next - enc->minBytesPerChar);+ if (!tem)+ return XML_ERROR_NO_MEMORY;+ normalizePublicId(tem);+ declNotationPublicId = tem;+ poolFinish(&tempPool);+ handleDefault = XML_FALSE;+ }+ break;+ case XML_ROLE_NOTATION_SYSTEM_ID:+ if (declNotationName && notationDeclHandler) {+ const XML_Char *systemId+ = poolStoreString(&tempPool, enc,+ s + enc->minBytesPerChar,+ next - enc->minBytesPerChar);+ if (!systemId)+ return XML_ERROR_NO_MEMORY;+ *eventEndPP = s;+ notationDeclHandler(handlerArg,+ declNotationName,+ curBase,+ systemId,+ declNotationPublicId);+ handleDefault = XML_FALSE;+ }+ poolClear(&tempPool);+ break;+ case XML_ROLE_NOTATION_NO_SYSTEM_ID:+ if (declNotationPublicId && notationDeclHandler) {+ *eventEndPP = s;+ notationDeclHandler(handlerArg,+ declNotationName,+ curBase,+ 0,+ declNotationPublicId);+ handleDefault = XML_FALSE;+ }+ poolClear(&tempPool);+ break;+ case XML_ROLE_ERROR:+ switch (tok) {+ case XML_TOK_PARAM_ENTITY_REF:+ /* PE references in internal subset are+ not allowed within declarations. */+ return XML_ERROR_PARAM_ENTITY_REF;+ case XML_TOK_XML_DECL:+ return XML_ERROR_MISPLACED_XML_PI;+ default:+ return XML_ERROR_SYNTAX;+ }+#ifdef XML_DTD+ case XML_ROLE_IGNORE_SECT:+ {+ enum XML_Error result;+ if (defaultHandler)+ reportDefault(parser, enc, s, next);+ handleDefault = XML_FALSE;+ result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);+ if (result != XML_ERROR_NONE)+ return result;+ else if (!next) {+ processor = ignoreSectionProcessor;+ return result;+ }+ }+ break;+#endif /* XML_DTD */+ case XML_ROLE_GROUP_OPEN:+ if (prologState.level >= groupSize) {+ if (groupSize) {+ char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);+ if (temp == NULL)+ return XML_ERROR_NO_MEMORY;+ groupConnector = temp;+ if (dtd->scaffIndex) {+ int *temp = (int *)REALLOC(dtd->scaffIndex,+ groupSize * sizeof(int));+ if (temp == NULL)+ return XML_ERROR_NO_MEMORY;+ dtd->scaffIndex = temp;+ }+ }+ else {+ groupConnector = (char *)MALLOC(groupSize = 32);+ if (!groupConnector)+ return XML_ERROR_NO_MEMORY;+ }+ }+ groupConnector[prologState.level] = 0;+ if (dtd->in_eldecl) {+ int myindex = nextScaffoldPart(parser);+ if (myindex < 0)+ return XML_ERROR_NO_MEMORY;+ dtd->scaffIndex[dtd->scaffLevel] = myindex;+ dtd->scaffLevel++;+ dtd->scaffold[myindex].type = XML_CTYPE_SEQ;+ if (elementDeclHandler)+ handleDefault = XML_FALSE;+ }+ break;+ case XML_ROLE_GROUP_SEQUENCE:+ if (groupConnector[prologState.level] == ASCII_PIPE)+ return XML_ERROR_SYNTAX;+ groupConnector[prologState.level] = ASCII_COMMA;+ if (dtd->in_eldecl && elementDeclHandler)+ handleDefault = XML_FALSE;+ break;+ case XML_ROLE_GROUP_CHOICE:+ if (groupConnector[prologState.level] == ASCII_COMMA)+ return XML_ERROR_SYNTAX;+ if (dtd->in_eldecl+ && !groupConnector[prologState.level]+ && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type+ != XML_CTYPE_MIXED)+ ) {+ dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type+ = XML_CTYPE_CHOICE;+ if (elementDeclHandler)+ handleDefault = XML_FALSE;+ }+ groupConnector[prologState.level] = ASCII_PIPE;+ break;+ case XML_ROLE_PARAM_ENTITY_REF:+#ifdef XML_DTD+ case XML_ROLE_INNER_PARAM_ENTITY_REF:+ dtd->hasParamEntityRefs = XML_TRUE;+ if (!paramEntityParsing)+ dtd->keepProcessing = dtd->standalone;+ else {+ const XML_Char *name;+ ENTITY *entity;+ name = poolStoreString(&dtd->pool, enc,+ s + enc->minBytesPerChar,+ next - enc->minBytesPerChar);+ if (!name)+ return XML_ERROR_NO_MEMORY;+ entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);+ poolDiscard(&dtd->pool);+ /* first, determine if a check for an existing declaration is needed;+ if yes, check that the entity exists, and that it is internal,+ otherwise call the skipped entity handler+ */+ if (prologState.documentEntity &&+ (dtd->standalone+ ? !openInternalEntities+ : !dtd->hasParamEntityRefs)) {+ if (!entity)+ return XML_ERROR_UNDEFINED_ENTITY;+ else if (!entity->is_internal)+ return XML_ERROR_ENTITY_DECLARED_IN_PE;+ }+ else if (!entity) {+ dtd->keepProcessing = dtd->standalone;+ /* cannot report skipped entities in declarations */+ if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {+ skippedEntityHandler(handlerArg, name, 1);+ handleDefault = XML_FALSE;+ }+ break;+ }+ if (entity->open)+ return XML_ERROR_RECURSIVE_ENTITY_REF;+ if (entity->textPtr) {+ enum XML_Error result;+ XML_Bool betweenDecl =+ (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);+ result = processInternalEntity(parser, entity, betweenDecl);+ if (result != XML_ERROR_NONE)+ return result;+ handleDefault = XML_FALSE;+ break;+ }+ if (externalEntityRefHandler) {+ dtd->paramEntityRead = XML_FALSE;+ entity->open = XML_TRUE;+ if (!externalEntityRefHandler(externalEntityRefHandlerArg,+ 0,+ entity->base,+ entity->systemId,+ entity->publicId)) {+ entity->open = XML_FALSE;+ return XML_ERROR_EXTERNAL_ENTITY_HANDLING;+ }+ entity->open = XML_FALSE;+ handleDefault = XML_FALSE;+ if (!dtd->paramEntityRead) {+ dtd->keepProcessing = dtd->standalone;+ break;+ }+ }+ else {+ dtd->keepProcessing = dtd->standalone;+ break;+ }+ }+#endif /* XML_DTD */+ if (!dtd->standalone &&+ notStandaloneHandler &&+ !notStandaloneHandler(handlerArg))+ return XML_ERROR_NOT_STANDALONE;+ break;++ /* Element declaration stuff */++ case XML_ROLE_ELEMENT_NAME:+ if (elementDeclHandler) {+ declElementType = getElementType(parser, enc, s, next);+ if (!declElementType)+ return XML_ERROR_NO_MEMORY;+ dtd->scaffLevel = 0;+ dtd->scaffCount = 0;+ dtd->in_eldecl = XML_TRUE;+ handleDefault = XML_FALSE;+ }+ break;++ case XML_ROLE_CONTENT_ANY:+ case XML_ROLE_CONTENT_EMPTY:+ if (dtd->in_eldecl) {+ if (elementDeclHandler) {+ XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));+ if (!content)+ return XML_ERROR_NO_MEMORY;+ content->quant = XML_CQUANT_NONE;+ content->name = NULL;+ content->numchildren = 0;+ content->children = NULL;+ content->type = ((role == XML_ROLE_CONTENT_ANY) ?+ XML_CTYPE_ANY :+ XML_CTYPE_EMPTY);+ *eventEndPP = s;+ elementDeclHandler(handlerArg, declElementType->name, content);+ handleDefault = XML_FALSE;+ }+ dtd->in_eldecl = XML_FALSE;+ }+ break;++ case XML_ROLE_CONTENT_PCDATA:+ if (dtd->in_eldecl) {+ dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type+ = XML_CTYPE_MIXED;+ if (elementDeclHandler)+ handleDefault = XML_FALSE;+ }+ break;++ case XML_ROLE_CONTENT_ELEMENT:+ quant = XML_CQUANT_NONE;+ goto elementContent;+ case XML_ROLE_CONTENT_ELEMENT_OPT:+ quant = XML_CQUANT_OPT;+ goto elementContent;+ case XML_ROLE_CONTENT_ELEMENT_REP:+ quant = XML_CQUANT_REP;+ goto elementContent;+ case XML_ROLE_CONTENT_ELEMENT_PLUS:+ quant = XML_CQUANT_PLUS;+ elementContent:+ if (dtd->in_eldecl) {+ ELEMENT_TYPE *el;+ const XML_Char *name;+ int nameLen;+ const char *nxt = (quant == XML_CQUANT_NONE+ ? next+ : next - enc->minBytesPerChar);+ int myindex = nextScaffoldPart(parser);+ if (myindex < 0)+ return XML_ERROR_NO_MEMORY;+ dtd->scaffold[myindex].type = XML_CTYPE_NAME;+ dtd->scaffold[myindex].quant = quant;+ el = getElementType(parser, enc, s, nxt);+ if (!el)+ return XML_ERROR_NO_MEMORY;+ name = el->name;+ dtd->scaffold[myindex].name = name;+ nameLen = 0;+ for (; name[nameLen++]; );+ dtd->contentStringLen += nameLen;+ if (elementDeclHandler)+ handleDefault = XML_FALSE;+ }+ break;++ case XML_ROLE_GROUP_CLOSE:+ quant = XML_CQUANT_NONE;+ goto closeGroup;+ case XML_ROLE_GROUP_CLOSE_OPT:+ quant = XML_CQUANT_OPT;+ goto closeGroup;+ case XML_ROLE_GROUP_CLOSE_REP:+ quant = XML_CQUANT_REP;+ goto closeGroup;+ case XML_ROLE_GROUP_CLOSE_PLUS:+ quant = XML_CQUANT_PLUS;+ closeGroup:+ if (dtd->in_eldecl) {+ if (elementDeclHandler)+ handleDefault = XML_FALSE;+ dtd->scaffLevel--;+ dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;+ if (dtd->scaffLevel == 0) {+ if (!handleDefault) {+ XML_Content *model = build_model(parser);+ if (!model)+ return XML_ERROR_NO_MEMORY;+ *eventEndPP = s;+ elementDeclHandler(handlerArg, declElementType->name, model);+ }+ dtd->in_eldecl = XML_FALSE;+ dtd->contentStringLen = 0;+ }+ }+ break;+ /* End element declaration stuff */++ case XML_ROLE_PI:+ if (!reportProcessingInstruction(parser, enc, s, next))+ return XML_ERROR_NO_MEMORY;+ handleDefault = XML_FALSE;+ break;+ case XML_ROLE_COMMENT:+ if (!reportComment(parser, enc, s, next))+ return XML_ERROR_NO_MEMORY;+ handleDefault = XML_FALSE;+ break;+ case XML_ROLE_NONE:+ switch (tok) {+ case XML_TOK_BOM:+ handleDefault = XML_FALSE;+ break;+ }+ break;+ case XML_ROLE_DOCTYPE_NONE:+ if (startDoctypeDeclHandler)+ handleDefault = XML_FALSE;+ break;+ case XML_ROLE_ENTITY_NONE:+ if (dtd->keepProcessing && entityDeclHandler)+ handleDefault = XML_FALSE;+ break;+ case XML_ROLE_NOTATION_NONE:+ if (notationDeclHandler)+ handleDefault = XML_FALSE;+ break;+ case XML_ROLE_ATTLIST_NONE:+ if (dtd->keepProcessing && attlistDeclHandler)+ handleDefault = XML_FALSE;+ break;+ case XML_ROLE_ELEMENT_NONE:+ if (elementDeclHandler)+ handleDefault = XML_FALSE;+ break;+ } /* end of big switch */++ if (handleDefault && defaultHandler)+ reportDefault(parser, enc, s, next);++ switch (ps_parsing) {+ case XML_SUSPENDED:+ *nextPtr = next;+ return XML_ERROR_NONE;+ case XML_FINISHED:+ return XML_ERROR_ABORTED;+ default:+ s = next;+ tok = XmlPrologTok(enc, s, end, &next);+ }+ }+ /* not reached */+}++static enum XML_Error PTRCALL+epilogProcessor(XML_Parser parser,+ const char *s,+ const char *end,+ const char **nextPtr)+{+ processor = epilogProcessor;+ eventPtr = s;+ for (;;) {+ const char *next = NULL;+ int tok = XmlPrologTok(encoding, s, end, &next);+ eventEndPtr = next;+ switch (tok) {+ /* report partial linebreak - it might be the last token */+ case -XML_TOK_PROLOG_S:+ if (defaultHandler) {+ reportDefault(parser, encoding, s, next);+ if (ps_parsing == XML_FINISHED)+ return XML_ERROR_ABORTED;+ }+ *nextPtr = next;+ return XML_ERROR_NONE;+ case XML_TOK_NONE:+ *nextPtr = s;+ return XML_ERROR_NONE;+ case XML_TOK_PROLOG_S:+ if (defaultHandler)+ reportDefault(parser, encoding, s, next);+ break;+ case XML_TOK_PI:+ if (!reportProcessingInstruction(parser, encoding, s, next))+ return XML_ERROR_NO_MEMORY;+ break;+ case XML_TOK_COMMENT:+ if (!reportComment(parser, encoding, s, next))+ return XML_ERROR_NO_MEMORY;+ break;+ case XML_TOK_INVALID:+ eventPtr = next;+ return XML_ERROR_INVALID_TOKEN;+ case XML_TOK_PARTIAL:+ if (!ps_finalBuffer) {+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ return XML_ERROR_UNCLOSED_TOKEN;+ case XML_TOK_PARTIAL_CHAR:+ if (!ps_finalBuffer) {+ *nextPtr = s;+ return XML_ERROR_NONE;+ }+ return XML_ERROR_PARTIAL_CHAR;+ default:+ return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;+ }+ eventPtr = s = next;+ switch (ps_parsing) {+ case XML_SUSPENDED:+ *nextPtr = next;+ return XML_ERROR_NONE;+ case XML_FINISHED:+ return XML_ERROR_ABORTED;+ default: ;+ }+ }+}++static enum XML_Error+processInternalEntity(XML_Parser parser, ENTITY *entity,+ XML_Bool betweenDecl)+{+ const char *textStart, *textEnd;+ const char *next;+ enum XML_Error result;+ OPEN_INTERNAL_ENTITY *openEntity;++ if (freeInternalEntities) {+ openEntity = freeInternalEntities;+ freeInternalEntities = openEntity->next;+ }+ else {+ openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY));+ if (!openEntity)+ return XML_ERROR_NO_MEMORY;+ }+ entity->open = XML_TRUE;+ entity->processed = 0;+ openEntity->next = openInternalEntities;+ openInternalEntities = openEntity;+ openEntity->entity = entity;+ openEntity->startTagLevel = tagLevel;+ openEntity->betweenDecl = betweenDecl;+ openEntity->internalEventPtr = NULL;+ openEntity->internalEventEndPtr = NULL;+ textStart = (char *)entity->textPtr;+ textEnd = (char *)(entity->textPtr + entity->textLen);+ /* Set a safe default value in case 'next' does not get set */+ next = textStart;++#ifdef XML_DTD+ if (entity->is_param) {+ int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);+ result = doProlog(parser, internalEncoding, textStart, textEnd, tok,+ next, &next, XML_FALSE);+ }+ else+#endif /* XML_DTD */+ result = doContent(parser, tagLevel, internalEncoding, textStart,+ textEnd, &next, XML_FALSE);++ if (result == XML_ERROR_NONE) {+ if (textEnd != next && ps_parsing == XML_SUSPENDED) {+ entity->processed = (int)(next - textStart);+ processor = internalEntityProcessor;+ }+ else {+ entity->open = XML_FALSE;+ openInternalEntities = openEntity->next;+ /* put openEntity back in list of free instances */+ openEntity->next = freeInternalEntities;+ freeInternalEntities = openEntity;+ }+ }+ return result;+}++static enum XML_Error PTRCALL+internalEntityProcessor(XML_Parser parser,+ const char *s,+ const char *end,+ const char **nextPtr)+{+ ENTITY *entity;+ const char *textStart, *textEnd;+ const char *next;+ enum XML_Error result;+ OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities;+ if (!openEntity)+ return XML_ERROR_UNEXPECTED_STATE;++ entity = openEntity->entity;+ textStart = ((char *)entity->textPtr) + entity->processed;+ textEnd = (char *)(entity->textPtr + entity->textLen);+ /* Set a safe default value in case 'next' does not get set */+ next = textStart;++#ifdef XML_DTD+ if (entity->is_param) {+ int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);+ result = doProlog(parser, internalEncoding, textStart, textEnd, tok,+ next, &next, XML_FALSE);+ }+ else+#endif /* XML_DTD */+ result = doContent(parser, openEntity->startTagLevel, internalEncoding,+ textStart, textEnd, &next, XML_FALSE);++ if (result != XML_ERROR_NONE)+ return result;+ else if (textEnd != next && ps_parsing == XML_SUSPENDED) {+ entity->processed = (int)(next - (char *)entity->textPtr);+ return result;+ }+ else {+ entity->open = XML_FALSE;+ openInternalEntities = openEntity->next;+ /* put openEntity back in list of free instances */+ openEntity->next = freeInternalEntities;+ freeInternalEntities = openEntity;+ }++#ifdef XML_DTD+ if (entity->is_param) {+ int tok;+ processor = prologProcessor;+ tok = XmlPrologTok(encoding, s, end, &next);+ return doProlog(parser, encoding, s, end, tok, next, nextPtr,+ (XML_Bool)!ps_finalBuffer);+ }+ else+#endif /* XML_DTD */+ {+ processor = contentProcessor;+ /* see externalEntityContentProcessor vs contentProcessor */+ return doContent(parser, parentParser ? 1 : 0, encoding, s, end,+ nextPtr, (XML_Bool)!ps_finalBuffer);+ }+}++static enum XML_Error PTRCALL+errorProcessor(XML_Parser parser,+ const char *UNUSED_P(s),+ const char *UNUSED_P(end),+ const char **UNUSED_P(nextPtr))+{+ return errorCode;+}++static enum XML_Error+storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,+ const char *ptr, const char *end,+ STRING_POOL *pool)+{+ enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,+ end, pool);+ if (result)+ return result;+ if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)+ poolChop(pool);+ if (!poolAppendChar(pool, XML_T('\0')))+ return XML_ERROR_NO_MEMORY;+ return XML_ERROR_NONE;+}++static enum XML_Error+appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,+ const char *ptr, const char *end,+ STRING_POOL *pool)+{+ DTD * const dtd = _dtd; /* save one level of indirection */+ for (;;) {+ const char *next;+ int tok = XmlAttributeValueTok(enc, ptr, end, &next);+ switch (tok) {+ case XML_TOK_NONE:+ return XML_ERROR_NONE;+ case XML_TOK_INVALID:+ if (enc == encoding)+ eventPtr = next;+ return XML_ERROR_INVALID_TOKEN;+ case XML_TOK_PARTIAL:+ if (enc == encoding)+ eventPtr = ptr;+ return XML_ERROR_INVALID_TOKEN;+ case XML_TOK_CHAR_REF:+ {+ XML_Char buf[XML_ENCODE_MAX];+ int i;+ int n = XmlCharRefNumber(enc, ptr);+ if (n < 0) {+ if (enc == encoding)+ eventPtr = ptr;+ return XML_ERROR_BAD_CHAR_REF;+ }+ if (!isCdata+ && n == 0x20 /* space */+ && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))+ break;+ n = XmlEncode(n, (ICHAR *)buf);+ if (!n) {+ if (enc == encoding)+ eventPtr = ptr;+ return XML_ERROR_BAD_CHAR_REF;+ }+ for (i = 0; i < n; i++) {+ if (!poolAppendChar(pool, buf[i]))+ return XML_ERROR_NO_MEMORY;+ }+ }+ break;+ case XML_TOK_DATA_CHARS:+ if (!poolAppend(pool, enc, ptr, next))+ return XML_ERROR_NO_MEMORY;+ break;+ case XML_TOK_TRAILING_CR:+ next = ptr + enc->minBytesPerChar;+ /* fall through */+ case XML_TOK_ATTRIBUTE_VALUE_S:+ case XML_TOK_DATA_NEWLINE:+ if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))+ break;+ if (!poolAppendChar(pool, 0x20))+ return XML_ERROR_NO_MEMORY;+ break;+ case XML_TOK_ENTITY_REF:+ {+ const XML_Char *name;+ ENTITY *entity;+ char checkEntityDecl;+ XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,+ ptr + enc->minBytesPerChar,+ next - enc->minBytesPerChar);+ if (ch) {+ if (!poolAppendChar(pool, ch))+ return XML_ERROR_NO_MEMORY;+ break;+ }+ name = poolStoreString(&temp2Pool, enc,+ ptr + enc->minBytesPerChar,+ next - enc->minBytesPerChar);+ if (!name)+ return XML_ERROR_NO_MEMORY;+ entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);+ poolDiscard(&temp2Pool);+ /* First, determine if a check for an existing declaration is needed;+ if yes, check that the entity exists, and that it is internal.+ */+ if (pool == &dtd->pool) /* are we called from prolog? */+ checkEntityDecl =+#ifdef XML_DTD+ prologState.documentEntity &&+#endif /* XML_DTD */+ (dtd->standalone+ ? !openInternalEntities+ : !dtd->hasParamEntityRefs);+ else /* if (pool == &tempPool): we are called from content */+ checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;+ if (checkEntityDecl) {+ if (!entity)+ return XML_ERROR_UNDEFINED_ENTITY;+ else if (!entity->is_internal)+ return XML_ERROR_ENTITY_DECLARED_IN_PE;+ }+ else if (!entity) {+ /* Cannot report skipped entity here - see comments on+ skippedEntityHandler.+ if (skippedEntityHandler)+ skippedEntityHandler(handlerArg, name, 0);+ */+ /* Cannot call the default handler because this would be+ out of sync with the call to the startElementHandler.+ if ((pool == &tempPool) && defaultHandler)+ reportDefault(parser, enc, ptr, next);+ */+ break;+ }+ if (entity->open) {+ if (enc == encoding)+ eventPtr = ptr;+ return XML_ERROR_RECURSIVE_ENTITY_REF;+ }+ if (entity->notation) {+ if (enc == encoding)+ eventPtr = ptr;+ return XML_ERROR_BINARY_ENTITY_REF;+ }+ if (!entity->textPtr) {+ if (enc == encoding)+ eventPtr = ptr;+ return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;+ }+ else {+ enum XML_Error result;+ const XML_Char *textEnd = entity->textPtr + entity->textLen;+ entity->open = XML_TRUE;+ result = appendAttributeValue(parser, internalEncoding, isCdata,+ (char *)entity->textPtr,+ (char *)textEnd, pool);+ entity->open = XML_FALSE;+ if (result)+ return result;+ }+ }+ break;+ default:+ if (enc == encoding)+ eventPtr = ptr;+ return XML_ERROR_UNEXPECTED_STATE;+ }+ ptr = next;+ }+ /* not reached */+}++static enum XML_Error+storeEntityValue(XML_Parser parser,+ const ENCODING *enc,+ const char *entityTextPtr,+ const char *entityTextEnd)+{+ DTD * const dtd = _dtd; /* save one level of indirection */+ STRING_POOL *pool = &(dtd->entityValuePool);+ enum XML_Error result = XML_ERROR_NONE;+#ifdef XML_DTD+ int oldInEntityValue = prologState.inEntityValue;+ prologState.inEntityValue = 1;+#endif /* XML_DTD */+ /* never return Null for the value argument in EntityDeclHandler,+ since this would indicate an external entity; therefore we+ have to make sure that entityValuePool.start is not null */+ if (!pool->blocks) {+ if (!poolGrow(pool))+ return XML_ERROR_NO_MEMORY;+ }++ for (;;) {+ const char *next;+ int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);+ switch (tok) {+ case XML_TOK_PARAM_ENTITY_REF:+#ifdef XML_DTD+ if (isParamEntity || enc != encoding) {+ const XML_Char *name;+ ENTITY *entity;+ name = poolStoreString(&tempPool, enc,+ entityTextPtr + enc->minBytesPerChar,+ next - enc->minBytesPerChar);+ if (!name) {+ result = XML_ERROR_NO_MEMORY;+ goto endEntityValue;+ }+ entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);+ poolDiscard(&tempPool);+ if (!entity) {+ /* not a well-formedness error - see XML 1.0: WFC Entity Declared */+ /* cannot report skipped entity here - see comments on+ skippedEntityHandler+ if (skippedEntityHandler)+ skippedEntityHandler(handlerArg, name, 0);+ */+ dtd->keepProcessing = dtd->standalone;+ goto endEntityValue;+ }+ if (entity->open) {+ if (enc == encoding)+ eventPtr = entityTextPtr;+ result = XML_ERROR_RECURSIVE_ENTITY_REF;+ goto endEntityValue;+ }+ if (entity->systemId) {+ if (externalEntityRefHandler) {+ dtd->paramEntityRead = XML_FALSE;+ entity->open = XML_TRUE;+ if (!externalEntityRefHandler(externalEntityRefHandlerArg,+ 0,+ entity->base,+ entity->systemId,+ entity->publicId)) {+ entity->open = XML_FALSE;+ result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;+ goto endEntityValue;+ }+ entity->open = XML_FALSE;+ if (!dtd->paramEntityRead)+ dtd->keepProcessing = dtd->standalone;+ }+ else+ dtd->keepProcessing = dtd->standalone;+ }+ else {+ entity->open = XML_TRUE;+ result = storeEntityValue(parser,+ internalEncoding,+ (char *)entity->textPtr,+ (char *)(entity->textPtr+ + entity->textLen));+ entity->open = XML_FALSE;+ if (result)+ goto endEntityValue;+ }+ break;+ }+#endif /* XML_DTD */+ /* In the internal subset, PE references are not legal+ within markup declarations, e.g entity values in this case. */+ eventPtr = entityTextPtr;+ result = XML_ERROR_PARAM_ENTITY_REF;+ goto endEntityValue;+ case XML_TOK_NONE:+ result = XML_ERROR_NONE;+ goto endEntityValue;+ case XML_TOK_ENTITY_REF:+ case XML_TOK_DATA_CHARS:+ if (!poolAppend(pool, enc, entityTextPtr, next)) {+ result = XML_ERROR_NO_MEMORY;+ goto endEntityValue;+ }+ break;+ case XML_TOK_TRAILING_CR:+ next = entityTextPtr + enc->minBytesPerChar;+ /* fall through */+ case XML_TOK_DATA_NEWLINE:+ if (pool->end == pool->ptr && !poolGrow(pool)) {+ result = XML_ERROR_NO_MEMORY;+ goto endEntityValue;+ }+ *(pool->ptr)++ = 0xA;+ break;+ case XML_TOK_CHAR_REF:+ {+ XML_Char buf[XML_ENCODE_MAX];+ int i;+ int n = XmlCharRefNumber(enc, entityTextPtr);+ if (n < 0) {+ if (enc == encoding)+ eventPtr = entityTextPtr;+ result = XML_ERROR_BAD_CHAR_REF;+ goto endEntityValue;+ }+ n = XmlEncode(n, (ICHAR *)buf);+ if (!n) {+ if (enc == encoding)+ eventPtr = entityTextPtr;+ result = XML_ERROR_BAD_CHAR_REF;+ goto endEntityValue;+ }+ for (i = 0; i < n; i++) {+ if (pool->end == pool->ptr && !poolGrow(pool)) {+ result = XML_ERROR_NO_MEMORY;+ goto endEntityValue;+ }+ *(pool->ptr)++ = buf[i];+ }+ }+ break;+ case XML_TOK_PARTIAL:+ if (enc == encoding)+ eventPtr = entityTextPtr;+ result = XML_ERROR_INVALID_TOKEN;+ goto endEntityValue;+ case XML_TOK_INVALID:+ if (enc == encoding)+ eventPtr = next;+ result = XML_ERROR_INVALID_TOKEN;+ goto endEntityValue;+ default:+ if (enc == encoding)+ eventPtr = entityTextPtr;+ result = XML_ERROR_UNEXPECTED_STATE;+ goto endEntityValue;+ }+ entityTextPtr = next;+ }+endEntityValue:+#ifdef XML_DTD+ prologState.inEntityValue = oldInEntityValue;+#endif /* XML_DTD */+ return result;+}++static void FASTCALL+normalizeLines(XML_Char *s)+{+ XML_Char *p;+ for (;; s++) {+ if (*s == XML_T('\0'))+ return;+ if (*s == 0xD)+ break;+ }+ p = s;+ do {+ if (*s == 0xD) {+ *p++ = 0xA;+ if (*++s == 0xA)+ s++;+ }+ else+ *p++ = *s++;+ } while (*s);+ *p = XML_T('\0');+}++static int+reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,+ const char *start, const char *end)+{+ const XML_Char *target;+ XML_Char *data;+ const char *tem;+ if (!processingInstructionHandler) {+ if (defaultHandler)+ reportDefault(parser, enc, start, end);+ return 1;+ }+ start += enc->minBytesPerChar * 2;+ tem = start + XmlNameLength(enc, start);+ target = poolStoreString(&tempPool, enc, start, tem);+ if (!target)+ return 0;+ poolFinish(&tempPool);+ data = poolStoreString(&tempPool, enc,+ XmlSkipS(enc, tem),+ end - enc->minBytesPerChar*2);+ if (!data)+ return 0;+ normalizeLines(data);+ processingInstructionHandler(handlerArg, target, data);+ poolClear(&tempPool);+ return 1;+}++static int+reportComment(XML_Parser parser, const ENCODING *enc,+ const char *start, const char *end)+{+ XML_Char *data;+ if (!commentHandler) {+ if (defaultHandler)+ reportDefault(parser, enc, start, end);+ return 1;+ }+ data = poolStoreString(&tempPool,+ enc,+ start + enc->minBytesPerChar * 4,+ end - enc->minBytesPerChar * 3);+ if (!data)+ return 0;+ normalizeLines(data);+ commentHandler(handlerArg, data);+ poolClear(&tempPool);+ return 1;+}++static void+reportDefault(XML_Parser parser, const ENCODING *enc,+ const char *s, const char *end)+{+ if (MUST_CONVERT(enc, s)) {+ enum XML_Convert_Result convert_res;+ const char **eventPP;+ const char **eventEndPP;+ if (enc == encoding) {+ eventPP = &eventPtr;+ eventEndPP = &eventEndPtr;+ }+ else {+ eventPP = &(openInternalEntities->internalEventPtr);+ eventEndPP = &(openInternalEntities->internalEventEndPtr);+ }+ do {+ ICHAR *dataPtr = (ICHAR *)dataBuf;+ convert_res = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);+ *eventEndPP = s;+ defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));+ *eventPP = s;+ } while ((convert_res != XML_CONVERT_COMPLETED) && (convert_res != XML_CONVERT_INPUT_INCOMPLETE));+ }+ else+ defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));+}+++static int+defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,+ XML_Bool isId, const XML_Char *value, XML_Parser parser)+{+ DEFAULT_ATTRIBUTE *att;+ if (value || isId) {+ /* The handling of default attributes gets messed up if we have+ a default which duplicates a non-default. */+ int i;+ for (i = 0; i < type->nDefaultAtts; i++)+ if (attId == type->defaultAtts[i].id)+ return 1;+ if (isId && !type->idAtt && !attId->xmlns)+ type->idAtt = attId;+ }+ if (type->nDefaultAtts == type->allocDefaultAtts) {+ if (type->allocDefaultAtts == 0) {+ type->allocDefaultAtts = 8;+ type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts+ * sizeof(DEFAULT_ATTRIBUTE));+ if (!type->defaultAtts)+ return 0;+ }+ else {+ DEFAULT_ATTRIBUTE *temp;+ int count = type->allocDefaultAtts * 2;+ temp = (DEFAULT_ATTRIBUTE *)+ REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));+ if (temp == NULL)+ return 0;+ type->allocDefaultAtts = count;+ type->defaultAtts = temp;+ }+ }+ att = type->defaultAtts + type->nDefaultAtts;+ att->id = attId;+ att->value = value;+ att->isCdata = isCdata;+ if (!isCdata)+ attId->maybeTokenized = XML_TRUE;+ type->nDefaultAtts += 1;+ return 1;+}++static int+setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)+{+ DTD * const dtd = _dtd; /* save one level of indirection */+ const XML_Char *name;+ for (name = elementType->name; *name; name++) {+ if (*name == XML_T(ASCII_COLON)) {+ PREFIX *prefix;+ const XML_Char *s;+ for (s = elementType->name; s != name; s++) {+ if (!poolAppendChar(&dtd->pool, *s))+ return 0;+ }+ if (!poolAppendChar(&dtd->pool, XML_T('\0')))+ return 0;+ prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),+ sizeof(PREFIX));+ if (!prefix)+ return 0;+ if (prefix->name == poolStart(&dtd->pool))+ poolFinish(&dtd->pool);+ else+ poolDiscard(&dtd->pool);+ elementType->prefix = prefix;++ }+ }+ return 1;+}++static ATTRIBUTE_ID *+getAttributeId(XML_Parser parser, const ENCODING *enc,+ const char *start, const char *end)+{+ DTD * const dtd = _dtd; /* save one level of indirection */+ ATTRIBUTE_ID *id;+ const XML_Char *name;+ if (!poolAppendChar(&dtd->pool, XML_T('\0')))+ return NULL;+ name = poolStoreString(&dtd->pool, enc, start, end);+ if (!name)+ return NULL;+ /* skip quotation mark - its storage will be re-used (like in name[-1]) */+ ++name;+ id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));+ if (!id)+ return NULL;+ if (id->name != name)+ poolDiscard(&dtd->pool);+ else {+ poolFinish(&dtd->pool);+ if (!ns)+ ;+ else if (name[0] == XML_T(ASCII_x)+ && name[1] == XML_T(ASCII_m)+ && name[2] == XML_T(ASCII_l)+ && name[3] == XML_T(ASCII_n)+ && name[4] == XML_T(ASCII_s)+ && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) {+ if (name[5] == XML_T('\0'))+ id->prefix = &dtd->defaultPrefix;+ else+ id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6, sizeof(PREFIX));+ id->xmlns = XML_TRUE;+ }+ else {+ int i;+ for (i = 0; name[i]; i++) {+ /* attributes without prefix are *not* in the default namespace */+ if (name[i] == XML_T(ASCII_COLON)) {+ int j;+ for (j = 0; j < i; j++) {+ if (!poolAppendChar(&dtd->pool, name[j]))+ return NULL;+ }+ if (!poolAppendChar(&dtd->pool, XML_T('\0')))+ return NULL;+ id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),+ sizeof(PREFIX));+ if (!id->prefix)+ return NULL;+ if (id->prefix->name == poolStart(&dtd->pool))+ poolFinish(&dtd->pool);+ else+ poolDiscard(&dtd->pool);+ break;+ }+ }+ }+ }+ return id;+}++#define CONTEXT_SEP XML_T(ASCII_FF)++static const XML_Char *+getContext(XML_Parser parser)+{+ DTD * const dtd = _dtd; /* save one level of indirection */+ HASH_TABLE_ITER iter;+ XML_Bool needSep = XML_FALSE;++ if (dtd->defaultPrefix.binding) {+ int i;+ int len;+ if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))+ return NULL;+ len = dtd->defaultPrefix.binding->uriLen;+ if (namespaceSeparator)+ len--;+ for (i = 0; i < len; i++)+ if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))+ return NULL;+ needSep = XML_TRUE;+ }++ hashTableIterInit(&iter, &(dtd->prefixes));+ for (;;) {+ int i;+ int len;+ const XML_Char *s;+ PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);+ if (!prefix)+ break;+ if (!prefix->binding)+ continue;+ if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))+ return NULL;+ for (s = prefix->name; *s; s++)+ if (!poolAppendChar(&tempPool, *s))+ return NULL;+ if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))+ return NULL;+ len = prefix->binding->uriLen;+ if (namespaceSeparator)+ len--;+ for (i = 0; i < len; i++)+ if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))+ return NULL;+ needSep = XML_TRUE;+ }+++ hashTableIterInit(&iter, &(dtd->generalEntities));+ for (;;) {+ const XML_Char *s;+ ENTITY *e = (ENTITY *)hashTableIterNext(&iter);+ if (!e)+ break;+ if (!e->open)+ continue;+ if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))+ return NULL;+ for (s = e->name; *s; s++)+ if (!poolAppendChar(&tempPool, *s))+ return 0;+ needSep = XML_TRUE;+ }++ if (!poolAppendChar(&tempPool, XML_T('\0')))+ return NULL;+ return tempPool.start;+}++static XML_Bool+setContext(XML_Parser parser, const XML_Char *context)+{+ DTD * const dtd = _dtd; /* save one level of indirection */+ const XML_Char *s = context;++ while (*context != XML_T('\0')) {+ if (*s == CONTEXT_SEP || *s == XML_T('\0')) {+ ENTITY *e;+ if (!poolAppendChar(&tempPool, XML_T('\0')))+ return XML_FALSE;+ e = (ENTITY *)lookup(parser, &dtd->generalEntities, poolStart(&tempPool), 0);+ if (e)+ e->open = XML_TRUE;+ if (*s != XML_T('\0'))+ s++;+ context = s;+ poolDiscard(&tempPool);+ }+ else if (*s == XML_T(ASCII_EQUALS)) {+ PREFIX *prefix;+ if (poolLength(&tempPool) == 0)+ prefix = &dtd->defaultPrefix;+ else {+ if (!poolAppendChar(&tempPool, XML_T('\0')))+ return XML_FALSE;+ prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&tempPool),+ sizeof(PREFIX));+ if (!prefix)+ return XML_FALSE;+ if (prefix->name == poolStart(&tempPool)) {+ prefix->name = poolCopyString(&dtd->pool, prefix->name);+ if (!prefix->name)+ return XML_FALSE;+ }+ poolDiscard(&tempPool);+ }+ for (context = s + 1;+ *context != CONTEXT_SEP && *context != XML_T('\0');+ context++)+ if (!poolAppendChar(&tempPool, *context))+ return XML_FALSE;+ if (!poolAppendChar(&tempPool, XML_T('\0')))+ return XML_FALSE;+ if (addBinding(parser, prefix, NULL, poolStart(&tempPool),+ &inheritedBindings) != XML_ERROR_NONE)+ return XML_FALSE;+ poolDiscard(&tempPool);+ if (*context != XML_T('\0'))+ ++context;+ s = context;+ }+ else {+ if (!poolAppendChar(&tempPool, *s))+ return XML_FALSE;+ s++;+ }+ }+ return XML_TRUE;+}++static void FASTCALL+normalizePublicId(XML_Char *publicId)+{+ XML_Char *p = publicId;+ XML_Char *s;+ for (s = publicId; *s; s++) {+ switch (*s) {+ case 0x20:+ case 0xD:+ case 0xA:+ if (p != publicId && p[-1] != 0x20)+ *p++ = 0x20;+ break;+ default:+ *p++ = *s;+ }+ }+ if (p != publicId && p[-1] == 0x20)+ --p;+ *p = XML_T('\0');+}++static DTD *+dtdCreate(const XML_Memory_Handling_Suite *ms)+{+ DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));+ if (p == NULL)+ return p;+ poolInit(&(p->pool), ms);+ poolInit(&(p->entityValuePool), ms);+ hashTableInit(&(p->generalEntities), ms);+ hashTableInit(&(p->elementTypes), ms);+ hashTableInit(&(p->attributeIds), ms);+ hashTableInit(&(p->prefixes), ms);+#ifdef XML_DTD+ p->paramEntityRead = XML_FALSE;+ hashTableInit(&(p->paramEntities), ms);+#endif /* XML_DTD */+ p->defaultPrefix.name = NULL;+ p->defaultPrefix.binding = NULL;++ p->in_eldecl = XML_FALSE;+ p->scaffIndex = NULL;+ p->scaffold = NULL;+ p->scaffLevel = 0;+ p->scaffSize = 0;+ p->scaffCount = 0;+ p->contentStringLen = 0;++ p->keepProcessing = XML_TRUE;+ p->hasParamEntityRefs = XML_FALSE;+ p->standalone = XML_FALSE;+ return p;+}++static void+dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)+{+ HASH_TABLE_ITER iter;+ hashTableIterInit(&iter, &(p->elementTypes));+ for (;;) {+ ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);+ if (!e)+ break;+ if (e->allocDefaultAtts != 0)+ ms->free_fcn(e->defaultAtts);+ }+ hashTableClear(&(p->generalEntities));+#ifdef XML_DTD+ p->paramEntityRead = XML_FALSE;+ hashTableClear(&(p->paramEntities));+#endif /* XML_DTD */+ hashTableClear(&(p->elementTypes));+ hashTableClear(&(p->attributeIds));+ hashTableClear(&(p->prefixes));+ poolClear(&(p->pool));+ poolClear(&(p->entityValuePool));+ p->defaultPrefix.name = NULL;+ p->defaultPrefix.binding = NULL;++ p->in_eldecl = XML_FALSE;++ ms->free_fcn(p->scaffIndex);+ p->scaffIndex = NULL;+ ms->free_fcn(p->scaffold);+ p->scaffold = NULL;++ p->scaffLevel = 0;+ p->scaffSize = 0;+ p->scaffCount = 0;+ p->contentStringLen = 0;++ p->keepProcessing = XML_TRUE;+ p->hasParamEntityRefs = XML_FALSE;+ p->standalone = XML_FALSE;+}++static void+dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)+{+ HASH_TABLE_ITER iter;+ hashTableIterInit(&iter, &(p->elementTypes));+ for (;;) {+ ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);+ if (!e)+ break;+ if (e->allocDefaultAtts != 0)+ ms->free_fcn(e->defaultAtts);+ }+ hashTableDestroy(&(p->generalEntities));+#ifdef XML_DTD+ hashTableDestroy(&(p->paramEntities));+#endif /* XML_DTD */+ hashTableDestroy(&(p->elementTypes));+ hashTableDestroy(&(p->attributeIds));+ hashTableDestroy(&(p->prefixes));+ poolDestroy(&(p->pool));+ poolDestroy(&(p->entityValuePool));+ if (isDocEntity) {+ ms->free_fcn(p->scaffIndex);+ ms->free_fcn(p->scaffold);+ }+ ms->free_fcn(p);+}++/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.+ The new DTD has already been initialized.+*/+static int+dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)+{+ HASH_TABLE_ITER iter;++ /* Copy the prefix table. */++ hashTableIterInit(&iter, &(oldDtd->prefixes));+ for (;;) {+ const XML_Char *name;+ const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);+ if (!oldP)+ break;+ name = poolCopyString(&(newDtd->pool), oldP->name);+ if (!name)+ return 0;+ if (!lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX)))+ return 0;+ }++ hashTableIterInit(&iter, &(oldDtd->attributeIds));++ /* Copy the attribute id table. */++ for (;;) {+ ATTRIBUTE_ID *newA;+ const XML_Char *name;+ const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);++ if (!oldA)+ break;+ /* Remember to allocate the scratch byte before the name. */+ if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))+ return 0;+ name = poolCopyString(&(newDtd->pool), oldA->name);+ if (!name)+ return 0;+ ++name;+ newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name,+ sizeof(ATTRIBUTE_ID));+ if (!newA)+ return 0;+ newA->maybeTokenized = oldA->maybeTokenized;+ if (oldA->prefix) {+ newA->xmlns = oldA->xmlns;+ if (oldA->prefix == &oldDtd->defaultPrefix)+ newA->prefix = &newDtd->defaultPrefix;+ else+ newA->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),+ oldA->prefix->name, 0);+ }+ }++ /* Copy the element type table. */++ hashTableIterInit(&iter, &(oldDtd->elementTypes));++ for (;;) {+ int i;+ ELEMENT_TYPE *newE;+ const XML_Char *name;+ const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);+ if (!oldE)+ break;+ name = poolCopyString(&(newDtd->pool), oldE->name);+ if (!name)+ return 0;+ newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name,+ sizeof(ELEMENT_TYPE));+ if (!newE)+ return 0;+ if (oldE->nDefaultAtts) {+ newE->defaultAtts = (DEFAULT_ATTRIBUTE *)+ ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));+ if (!newE->defaultAtts) {+ return 0;+ }+ }+ if (oldE->idAtt)+ newE->idAtt = (ATTRIBUTE_ID *)+ lookup(oldParser, &(newDtd->attributeIds), oldE->idAtt->name, 0);+ newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;+ if (oldE->prefix)+ newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),+ oldE->prefix->name, 0);+ for (i = 0; i < newE->nDefaultAtts; i++) {+ newE->defaultAtts[i].id = (ATTRIBUTE_ID *)+ lookup(oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);+ newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;+ if (oldE->defaultAtts[i].value) {+ newE->defaultAtts[i].value+ = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);+ if (!newE->defaultAtts[i].value)+ return 0;+ }+ else+ newE->defaultAtts[i].value = NULL;+ }+ }++ /* Copy the entity tables. */+ if (!copyEntityTable(oldParser,+ &(newDtd->generalEntities),+ &(newDtd->pool),+ &(oldDtd->generalEntities)))+ return 0;++#ifdef XML_DTD+ if (!copyEntityTable(oldParser,+ &(newDtd->paramEntities),+ &(newDtd->pool),+ &(oldDtd->paramEntities)))+ return 0;+ newDtd->paramEntityRead = oldDtd->paramEntityRead;+#endif /* XML_DTD */++ newDtd->keepProcessing = oldDtd->keepProcessing;+ newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;+ newDtd->standalone = oldDtd->standalone;++ /* Don't want deep copying for scaffolding */+ newDtd->in_eldecl = oldDtd->in_eldecl;+ newDtd->scaffold = oldDtd->scaffold;+ newDtd->contentStringLen = oldDtd->contentStringLen;+ newDtd->scaffSize = oldDtd->scaffSize;+ newDtd->scaffLevel = oldDtd->scaffLevel;+ newDtd->scaffIndex = oldDtd->scaffIndex;++ return 1;+} /* End dtdCopy */++static int+copyEntityTable(XML_Parser oldParser,+ HASH_TABLE *newTable,+ STRING_POOL *newPool,+ const HASH_TABLE *oldTable)+{+ HASH_TABLE_ITER iter;+ const XML_Char *cachedOldBase = NULL;+ const XML_Char *cachedNewBase = NULL;++ hashTableIterInit(&iter, oldTable);++ for (;;) {+ ENTITY *newE;+ const XML_Char *name;+ const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);+ if (!oldE)+ break;+ name = poolCopyString(newPool, oldE->name);+ if (!name)+ return 0;+ newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY));+ if (!newE)+ return 0;+ if (oldE->systemId) {+ const XML_Char *tem = poolCopyString(newPool, oldE->systemId);+ if (!tem)+ return 0;+ newE->systemId = tem;+ if (oldE->base) {+ if (oldE->base == cachedOldBase)+ newE->base = cachedNewBase;+ else {+ cachedOldBase = oldE->base;+ tem = poolCopyString(newPool, cachedOldBase);+ if (!tem)+ return 0;+ cachedNewBase = newE->base = tem;+ }+ }+ if (oldE->publicId) {+ tem = poolCopyString(newPool, oldE->publicId);+ if (!tem)+ return 0;+ newE->publicId = tem;+ }+ }+ else {+ const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,+ oldE->textLen);+ if (!tem)+ return 0;+ newE->textPtr = tem;+ newE->textLen = oldE->textLen;+ }+ if (oldE->notation) {+ const XML_Char *tem = poolCopyString(newPool, oldE->notation);+ if (!tem)+ return 0;+ newE->notation = tem;+ }+ newE->is_param = oldE->is_param;+ newE->is_internal = oldE->is_internal;+ }+ return 1;+}++#define INIT_POWER 6++static XML_Bool FASTCALL+keyeq(KEY s1, KEY s2)+{+ for (; *s1 == *s2; s1++, s2++)+ if (*s1 == 0)+ return XML_TRUE;+ return XML_FALSE;+}++static size_t+keylen(KEY s)+{+ size_t len = 0;+ for (; *s; s++, len++);+ return len;+}++static void+copy_salt_to_sipkey(XML_Parser parser, struct sipkey * key)+{+ key->k[0] = 0;+ key->k[1] = get_hash_secret_salt(parser);+}++static unsigned long FASTCALL+hash(XML_Parser parser, KEY s)+{+ struct siphash state;+ struct sipkey key;+ (void)sip_tobin;+ (void)sip24_valid;+ copy_salt_to_sipkey(parser, &key);+ sip24_init(&state, &key);+ sip24_update(&state, s, keylen(s) * sizeof(XML_Char));+ return (unsigned long)sip24_final(&state);+}++static NAMED *+lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize)+{+ size_t i;+ if (table->size == 0) {+ size_t tsize;+ if (!createSize)+ return NULL;+ table->power = INIT_POWER;+ /* table->size is a power of 2 */+ table->size = (size_t)1 << INIT_POWER;+ tsize = table->size * sizeof(NAMED *);+ table->v = (NAMED **)table->mem->malloc_fcn(tsize);+ if (!table->v) {+ table->size = 0;+ return NULL;+ }+ memset(table->v, 0, tsize);+ i = hash(parser, name) & ((unsigned long)table->size - 1);+ }+ else {+ unsigned long h = hash(parser, name);+ unsigned long mask = (unsigned long)table->size - 1;+ unsigned char step = 0;+ i = h & mask;+ while (table->v[i]) {+ if (keyeq(name, table->v[i]->name))+ return table->v[i];+ if (!step)+ step = PROBE_STEP(h, mask, table->power);+ i < step ? (i += table->size - step) : (i -= step);+ }+ if (!createSize)+ return NULL;++ /* check for overflow (table is half full) */+ if (table->used >> (table->power - 1)) {+ unsigned char newPower = table->power + 1;+ size_t newSize = (size_t)1 << newPower;+ unsigned long newMask = (unsigned long)newSize - 1;+ size_t tsize = newSize * sizeof(NAMED *);+ NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);+ if (!newV)+ return NULL;+ memset(newV, 0, tsize);+ for (i = 0; i < table->size; i++)+ if (table->v[i]) {+ unsigned long newHash = hash(parser, table->v[i]->name);+ size_t j = newHash & newMask;+ step = 0;+ while (newV[j]) {+ if (!step)+ step = PROBE_STEP(newHash, newMask, newPower);+ j < step ? (j += newSize - step) : (j -= step);+ }+ newV[j] = table->v[i];+ }+ table->mem->free_fcn(table->v);+ table->v = newV;+ table->power = newPower;+ table->size = newSize;+ i = h & newMask;+ step = 0;+ while (table->v[i]) {+ if (!step)+ step = PROBE_STEP(h, newMask, newPower);+ i < step ? (i += newSize - step) : (i -= step);+ }+ }+ }+ table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);+ if (!table->v[i])+ return NULL;+ memset(table->v[i], 0, createSize);+ table->v[i]->name = name;+ (table->used)++;+ return table->v[i];+}++static void FASTCALL+hashTableClear(HASH_TABLE *table)+{+ size_t i;+ for (i = 0; i < table->size; i++) {+ table->mem->free_fcn(table->v[i]);+ table->v[i] = NULL;+ }+ table->used = 0;+}++static void FASTCALL+hashTableDestroy(HASH_TABLE *table)+{+ size_t i;+ for (i = 0; i < table->size; i++)+ table->mem->free_fcn(table->v[i]);+ table->mem->free_fcn(table->v);+}++static void FASTCALL+hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)+{+ p->power = 0;+ p->size = 0;+ p->used = 0;+ p->v = NULL;+ p->mem = ms;+}++static void FASTCALL+hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)+{+ iter->p = table->v;+ iter->end = iter->p + table->size;+}++static NAMED * FASTCALL+hashTableIterNext(HASH_TABLE_ITER *iter)+{+ while (iter->p != iter->end) {+ NAMED *tem = *(iter->p)++;+ if (tem)+ return tem;+ }+ return NULL;+}++static void FASTCALL+poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)+{+ pool->blocks = NULL;+ pool->freeBlocks = NULL;+ pool->start = NULL;+ pool->ptr = NULL;+ pool->end = NULL;+ pool->mem = ms;+}++static void FASTCALL+poolClear(STRING_POOL *pool)+{+ if (!pool->freeBlocks)+ pool->freeBlocks = pool->blocks;+ else {+ BLOCK *p = pool->blocks;+ while (p) {+ BLOCK *tem = p->next;+ p->next = pool->freeBlocks;+ pool->freeBlocks = p;+ p = tem;+ }+ }+ pool->blocks = NULL;+ pool->start = NULL;+ pool->ptr = NULL;+ pool->end = NULL;+}++static void FASTCALL+poolDestroy(STRING_POOL *pool)+{+ BLOCK *p = pool->blocks;+ while (p) {+ BLOCK *tem = p->next;+ pool->mem->free_fcn(p);+ p = tem;+ }+ p = pool->freeBlocks;+ while (p) {+ BLOCK *tem = p->next;+ pool->mem->free_fcn(p);+ p = tem;+ }+}++static XML_Char *+poolAppend(STRING_POOL *pool, const ENCODING *enc,+ const char *ptr, const char *end)+{+ if (!pool->ptr && !poolGrow(pool))+ return NULL;+ for (;;) {+ const enum XML_Convert_Result convert_res = XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);+ if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))+ break;+ if (!poolGrow(pool))+ return NULL;+ }+ return pool->start;+}++static const XML_Char * FASTCALL+poolCopyString(STRING_POOL *pool, const XML_Char *s)+{+ do {+ if (!poolAppendChar(pool, *s))+ return NULL;+ } while (*s++);+ s = pool->start;+ poolFinish(pool);+ return s;+}++static const XML_Char *+poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)+{+ if (!pool->ptr && !poolGrow(pool))+ return NULL;+ for (; n > 0; --n, s++) {+ if (!poolAppendChar(pool, *s))+ return NULL;+ }+ s = pool->start;+ poolFinish(pool);+ return s;+}++static const XML_Char * FASTCALL+poolAppendString(STRING_POOL *pool, const XML_Char *s)+{+ while (*s) {+ if (!poolAppendChar(pool, *s))+ return NULL;+ s++;+ }+ return pool->start;+}++static XML_Char *+poolStoreString(STRING_POOL *pool, const ENCODING *enc,+ const char *ptr, const char *end)+{+ if (!poolAppend(pool, enc, ptr, end))+ return NULL;+ if (pool->ptr == pool->end && !poolGrow(pool))+ return NULL;+ *(pool->ptr)++ = 0;+ return pool->start;+}++static size_t+poolBytesToAllocateFor(int blockSize)+{+ /* Unprotected math would be:+ ** return offsetof(BLOCK, s) + blockSize * sizeof(XML_Char);+ **+ ** Detect overflow, avoiding _signed_ overflow undefined behavior+ ** For a + b * c we check b * c in isolation first, so that addition of a+ ** on top has no chance of making us accept a small non-negative number+ */+ const size_t stretch = sizeof(XML_Char); /* can be 4 bytes */++ if (blockSize <= 0)+ return 0;++ if (blockSize > (int)(INT_MAX / stretch))+ return 0;++ {+ const int stretchedBlockSize = blockSize * (int)stretch;+ const int bytesToAllocate = (int)(+ offsetof(BLOCK, s) + (unsigned)stretchedBlockSize);+ if (bytesToAllocate < 0)+ return 0;++ return (size_t)bytesToAllocate;+ }+}++static XML_Bool FASTCALL+poolGrow(STRING_POOL *pool)+{+ if (pool->freeBlocks) {+ if (pool->start == 0) {+ pool->blocks = pool->freeBlocks;+ pool->freeBlocks = pool->freeBlocks->next;+ pool->blocks->next = NULL;+ pool->start = pool->blocks->s;+ pool->end = pool->start + pool->blocks->size;+ pool->ptr = pool->start;+ return XML_TRUE;+ }+ if (pool->end - pool->start < pool->freeBlocks->size) {+ BLOCK *tem = pool->freeBlocks->next;+ pool->freeBlocks->next = pool->blocks;+ pool->blocks = pool->freeBlocks;+ pool->freeBlocks = tem;+ memcpy(pool->blocks->s, pool->start,+ (pool->end - pool->start) * sizeof(XML_Char));+ pool->ptr = pool->blocks->s + (pool->ptr - pool->start);+ pool->start = pool->blocks->s;+ pool->end = pool->start + pool->blocks->size;+ return XML_TRUE;+ }+ }+ if (pool->blocks && pool->start == pool->blocks->s) {+ BLOCK *temp;+ int blockSize = (int)((unsigned)(pool->end - pool->start)*2U);+ size_t bytesToAllocate;++ if (blockSize < 0)+ return XML_FALSE;++ bytesToAllocate = poolBytesToAllocateFor(blockSize);+ if (bytesToAllocate == 0)+ return XML_FALSE;++ temp = (BLOCK *)+ pool->mem->realloc_fcn(pool->blocks, (unsigned)bytesToAllocate);+ if (temp == NULL)+ return XML_FALSE;+ pool->blocks = temp;+ pool->blocks->size = blockSize;+ pool->ptr = pool->blocks->s + (pool->ptr - pool->start);+ pool->start = pool->blocks->s;+ pool->end = pool->start + blockSize;+ }+ else {+ BLOCK *tem;+ int blockSize = (int)(pool->end - pool->start);+ size_t bytesToAllocate;++ if (blockSize < 0)+ return XML_FALSE;++ if (blockSize < INIT_BLOCK_SIZE)+ blockSize = INIT_BLOCK_SIZE;+ else {+ /* Detect overflow, avoiding _signed_ overflow undefined behavior */+ if ((int)((unsigned)blockSize * 2U) < 0) {+ return XML_FALSE;+ }+ blockSize *= 2;+ }++ bytesToAllocate = poolBytesToAllocateFor(blockSize);+ if (bytesToAllocate == 0)+ return XML_FALSE;++ tem = (BLOCK *)pool->mem->malloc_fcn(bytesToAllocate);+ if (!tem)+ return XML_FALSE;+ tem->size = blockSize;+ tem->next = pool->blocks;+ pool->blocks = tem;+ if (pool->ptr != pool->start)+ memcpy(tem->s, pool->start,+ (pool->ptr - pool->start) * sizeof(XML_Char));+ pool->ptr = tem->s + (pool->ptr - pool->start);+ pool->start = tem->s;+ pool->end = tem->s + blockSize;+ }+ return XML_TRUE;+}++static int FASTCALL+nextScaffoldPart(XML_Parser parser)+{+ DTD * const dtd = _dtd; /* save one level of indirection */+ CONTENT_SCAFFOLD * me;+ int next;++ if (!dtd->scaffIndex) {+ dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));+ if (!dtd->scaffIndex)+ return -1;+ dtd->scaffIndex[0] = 0;+ }++ if (dtd->scaffCount >= dtd->scaffSize) {+ CONTENT_SCAFFOLD *temp;+ if (dtd->scaffold) {+ temp = (CONTENT_SCAFFOLD *)+ REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));+ if (temp == NULL)+ return -1;+ dtd->scaffSize *= 2;+ }+ else {+ temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS+ * sizeof(CONTENT_SCAFFOLD));+ if (temp == NULL)+ return -1;+ dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;+ }+ dtd->scaffold = temp;+ }+ next = dtd->scaffCount++;+ me = &dtd->scaffold[next];+ if (dtd->scaffLevel) {+ CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];+ if (parent->lastchild) {+ dtd->scaffold[parent->lastchild].nextsib = next;+ }+ if (!parent->childcnt)+ parent->firstchild = next;+ parent->lastchild = next;+ parent->childcnt++;+ }+ me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;+ return next;+}++static void+build_node(XML_Parser parser,+ int src_node,+ XML_Content *dest,+ XML_Content **contpos,+ XML_Char **strpos)+{+ DTD * const dtd = _dtd; /* save one level of indirection */+ dest->type = dtd->scaffold[src_node].type;+ dest->quant = dtd->scaffold[src_node].quant;+ if (dest->type == XML_CTYPE_NAME) {+ const XML_Char *src;+ dest->name = *strpos;+ src = dtd->scaffold[src_node].name;+ for (;;) {+ *(*strpos)++ = *src;+ if (!*src)+ break;+ src++;+ }+ dest->numchildren = 0;+ dest->children = NULL;+ }+ else {+ unsigned int i;+ int cn;+ dest->numchildren = dtd->scaffold[src_node].childcnt;+ dest->children = *contpos;+ *contpos += dest->numchildren;+ for (i = 0, cn = dtd->scaffold[src_node].firstchild;+ i < dest->numchildren;+ i++, cn = dtd->scaffold[cn].nextsib) {+ build_node(parser, cn, &(dest->children[i]), contpos, strpos);+ }+ dest->name = NULL;+ }+}++static XML_Content *+build_model (XML_Parser parser)+{+ DTD * const dtd = _dtd; /* save one level of indirection */+ XML_Content *ret;+ XML_Content *cpos;+ XML_Char * str;+ int allocsize = (dtd->scaffCount * sizeof(XML_Content)+ + (dtd->contentStringLen * sizeof(XML_Char)));++ ret = (XML_Content *)MALLOC(allocsize);+ if (!ret)+ return NULL;++ str = (XML_Char *) (&ret[dtd->scaffCount]);+ cpos = &ret[1];++ build_node(parser, 0, ret, &cpos, &str);+ return ret;+}++static ELEMENT_TYPE *+getElementType(XML_Parser parser,+ const ENCODING *enc,+ const char *ptr,+ const char *end)+{+ DTD * const dtd = _dtd; /* save one level of indirection */+ const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);+ ELEMENT_TYPE *ret;++ if (!name)+ return NULL;+ ret = (ELEMENT_TYPE *) lookup(parser, &dtd->elementTypes, name, sizeof(ELEMENT_TYPE)); if (!ret) return NULL; if (ret->name != name)
cbits/xmlrole.c view
@@ -4,19 +4,13 @@ #include <stddef.h> -#ifdef COMPILED_FROM_DSP+#ifdef _WIN32 #include "winconfig.h"-#elif defined(MACOS_CLASSIC)-#include "macconfig.h"-#elif defined(__amigaos4__)-#include "amigaconfig.h"-#elif defined(__WATCOMC__)-#include "watcomconfig.h" #else #ifdef HAVE_EXPAT_CONFIG_H #include <expat_config.h> #endif-#endif /* ndef COMPILED_FROM_DSP */+#endif /* ndef _WIN32 */ #include "expat_external.h" #include "internal.h"@@ -195,9 +189,9 @@ static int PTRCALL prolog2(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -216,9 +210,9 @@ static int PTRCALL doctype0(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -264,9 +258,9 @@ static int PTRCALL doctype2(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -281,9 +275,9 @@ static int PTRCALL doctype3(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -298,9 +292,9 @@ static int PTRCALL doctype4(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -318,9 +312,9 @@ static int PTRCALL doctype5(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -437,9 +431,9 @@ static int PTRCALL entity0(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -457,9 +451,9 @@ static int PTRCALL entity1(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -502,9 +496,9 @@ static int PTRCALL entity3(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -519,9 +513,9 @@ static int PTRCALL entity4(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -559,9 +553,9 @@ static int PTRCALL entity6(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -605,9 +599,9 @@ static int PTRCALL entity8(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -622,9 +616,9 @@ static int PTRCALL entity9(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -639,9 +633,9 @@ static int PTRCALL entity10(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -656,9 +650,9 @@ static int PTRCALL notation0(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -697,9 +691,9 @@ static int PTRCALL notation2(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -714,9 +708,9 @@ static int PTRCALL notation3(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -732,9 +726,9 @@ static int PTRCALL notation4(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -753,9 +747,9 @@ static int PTRCALL attlist0(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -771,9 +765,9 @@ static int PTRCALL attlist1(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -833,9 +827,9 @@ static int PTRCALL attlist3(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -852,9 +846,9 @@ static int PTRCALL attlist4(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -872,9 +866,9 @@ static int PTRCALL attlist5(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -889,9 +883,9 @@ static int PTRCALL attlist6(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -906,9 +900,9 @@ static int PTRCALL attlist7(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -967,9 +961,9 @@ static int PTRCALL attlist9(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -984,9 +978,9 @@ static int PTRCALL element0(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -1072,9 +1066,9 @@ static int PTRCALL element3(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -1097,9 +1091,9 @@ static int PTRCALL element4(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -1115,9 +1109,9 @@ static int PTRCALL element5(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -1136,9 +1130,9 @@ static int PTRCALL element6(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -1166,9 +1160,9 @@ static int PTRCALL element7(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -1240,9 +1234,9 @@ static int PTRCALL condSect1(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -1258,9 +1252,9 @@ static int PTRCALL condSect2(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -1277,9 +1271,9 @@ static int PTRCALL declClose(PROLOG_STATE *state, int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S:@@ -1292,11 +1286,11 @@ } static int PTRCALL-error(PROLOG_STATE *state,- int tok,- const char *ptr,- const char *end,- const ENCODING *enc)+error(PROLOG_STATE *UNUSED_P(state),+ int UNUSED_P(tok),+ const char *UNUSED_P(ptr),+ const char *UNUSED_P(end),+ const ENCODING *UNUSED_P(enc)) { return XML_ROLE_NONE; }
cbits/xmltok.c view
@@ -4,19 +4,13 @@ #include <stddef.h> -#ifdef COMPILED_FROM_DSP+#ifdef _WIN32 #include "winconfig.h"-#elif defined(MACOS_CLASSIC)-#include "macconfig.h"-#elif defined(__amigaos4__)-#include "amigaconfig.h"-#elif defined(__WATCOMC__)-#include "watcomconfig.h" #else #ifdef HAVE_EXPAT_CONFIG_H #include <expat_config.h> #endif-#endif /* ndef COMPILED_FROM_DSP */+#endif /* ndef _WIN32 */ #include "expat_external.h" #include "internal.h"@@ -46,7 +40,7 @@ #define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16) #define UCS2_GET_NAMING(pages, hi, lo) \- (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1 << ((lo) & 0x1F)))+ (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1u << ((lo) & 0x1F))) /* A 2 byte UTF-8 representation splits the characters 11 bits between the bottom 5 and 6 bits of the bytes. We need 8 bits to index into@@ -56,7 +50,7 @@ (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \ + ((((byte)[0]) & 3) << 1) \ + ((((byte)[1]) >> 5) & 1)] \- & (1 << (((byte)[1]) & 0x1F)))+ & (1u << (((byte)[1]) & 0x1F))) /* A 3 byte UTF-8 representation splits the characters 16 bits between the bottom 4, 6 and 6 bits of the bytes. We need 8 bits to index@@ -69,7 +63,7 @@ << 3) \ + ((((byte)[1]) & 3) << 1) \ + ((((byte)[2]) >> 5) & 1)] \- & (1 << (((byte)[2]) & 0x1F)))+ & (1u << (((byte)[2]) & 0x1F))) #define UTF8_GET_NAMING(pages, p, n) \ ((n) == 2 \@@ -122,19 +116,19 @@ ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0))) static int PTRFASTCALL-isNever(const ENCODING *enc, const char *p)+isNever(const ENCODING *UNUSED_P(enc), const char *UNUSED_P(p)) { return 0; } static int PTRFASTCALL-utf8_isName2(const ENCODING *enc, const char *p)+utf8_isName2(const ENCODING *UNUSED_P(enc), const char *p) { return UTF8_GET_NAMING2(namePages, (const unsigned char *)p); } static int PTRFASTCALL-utf8_isName3(const ENCODING *enc, const char *p)+utf8_isName3(const ENCODING *UNUSED_P(enc), const char *p) { return UTF8_GET_NAMING3(namePages, (const unsigned char *)p); }@@ -142,13 +136,13 @@ #define utf8_isName4 isNever static int PTRFASTCALL-utf8_isNmstrt2(const ENCODING *enc, const char *p)+utf8_isNmstrt2(const ENCODING *UNUSED_P(enc), const char *p) { return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p); } static int PTRFASTCALL-utf8_isNmstrt3(const ENCODING *enc, const char *p)+utf8_isNmstrt3(const ENCODING *UNUSED_P(enc), const char *p) { return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p); }@@ -156,19 +150,19 @@ #define utf8_isNmstrt4 isNever static int PTRFASTCALL-utf8_isInvalid2(const ENCODING *enc, const char *p)+utf8_isInvalid2(const ENCODING *UNUSED_P(enc), const char *p) { return UTF8_INVALID2((const unsigned char *)p); } static int PTRFASTCALL-utf8_isInvalid3(const ENCODING *enc, const char *p)+utf8_isInvalid3(const ENCODING *UNUSED_P(enc), const char *p) { return UTF8_INVALID3((const unsigned char *)p); } static int PTRFASTCALL-utf8_isInvalid4(const ENCODING *enc, const char *p)+utf8_isInvalid4(const ENCODING *UNUSED_P(enc), const char *p) { return UTF8_INVALID4((const unsigned char *)p); }@@ -222,6 +216,17 @@ E ## isInvalid3, \ E ## isInvalid4 +#define NULL_VTABLE \+ /* isName2 */ NULL, \+ /* isName3 */ NULL, \+ /* isName4 */ NULL, \+ /* isNmstrt2 */ NULL, \+ /* isNmstrt3 */ NULL, \+ /* isNmstrt4 */ NULL, \+ /* isInvalid2 */ NULL, \+ /* isInvalid3 */ NULL, \+ /* isInvalid4 */ NULL+ static int FASTCALL checkCharRefNumber(int); #include "xmltok_impl.h"@@ -318,39 +323,89 @@ UTF8_cval4 = 0xf0 }; -static void PTRCALL-utf8_toUtf8(const ENCODING *enc,+void+align_limit_to_full_utf8_characters(const char * from, const char ** fromLimRef)+{+ const char * fromLim = *fromLimRef;+ size_t walked = 0;+ for (; fromLim > from; fromLim--, walked++) {+ const unsigned char prev = (unsigned char)fromLim[-1];+ if ((prev & 0xf8u) == 0xf0u) { /* 4-byte character, lead by 0b11110xxx byte */+ if (walked + 1 >= 4) {+ fromLim += 4 - 1;+ break;+ } else {+ walked = 0;+ }+ } else if ((prev & 0xf0u) == 0xe0u) { /* 3-byte character, lead by 0b1110xxxx byte */+ if (walked + 1 >= 3) {+ fromLim += 3 - 1;+ break;+ } else {+ walked = 0;+ }+ } else if ((prev & 0xe0u) == 0xc0u) { /* 2-byte character, lead by 0b110xxxxx byte */+ if (walked + 1 >= 2) {+ fromLim += 2 - 1;+ break;+ } else {+ walked = 0;+ }+ } else if ((prev & 0x80u) == 0x00u) { /* 1-byte character, matching 0b0xxxxxxx */+ break;+ }+ }+ *fromLimRef = fromLim;+}++static enum XML_Convert_Result PTRCALL+utf8_toUtf8(const ENCODING *UNUSED_P(enc), const char **fromP, const char *fromLim, char **toP, const char *toLim) { char *to; const char *from;- if (fromLim - *fromP > toLim - *toP) {- /* Avoid copying partial characters. */- for (fromLim = *fromP + (toLim - *toP); fromLim > *fromP; fromLim--)- if (((unsigned char)fromLim[-1] & 0xc0) != 0x80)- break;- }- for (to = *toP, from = *fromP; from != fromLim; from++, to++)+ const char *fromLimInitial = fromLim;++ /* Avoid copying partial characters. */+ align_limit_to_full_utf8_characters(*fromP, &fromLim);++ for (to = *toP, from = *fromP; (from < fromLim) && (to < toLim); from++, to++) *to = *from; *fromP = from; *toP = to;++ if (fromLim < fromLimInitial)+ return XML_CONVERT_INPUT_INCOMPLETE;+ else if ((to == toLim) && (from < fromLim))+ return XML_CONVERT_OUTPUT_EXHAUSTED;+ else+ return XML_CONVERT_COMPLETED; } -static void PTRCALL+static enum XML_Convert_Result PTRCALL utf8_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim, unsigned short **toP, const unsigned short *toLim) {+ enum XML_Convert_Result res = XML_CONVERT_COMPLETED; unsigned short *to = *toP; const char *from = *fromP;- while (from != fromLim && to != toLim) {+ while (from < fromLim && to < toLim) { switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) { case BT_LEAD2:+ if (fromLim - from < 2) {+ res = XML_CONVERT_INPUT_INCOMPLETE;+ goto after;+ } *to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f)); from += 2; break; case BT_LEAD3:+ if (fromLim - from < 3) {+ res = XML_CONVERT_INPUT_INCOMPLETE;+ goto after;+ } *to++ = (unsigned short)(((from[0] & 0xf) << 12) | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f)); from += 3;@@ -358,8 +413,14 @@ case BT_LEAD4: { unsigned long n;- if (to + 1 == toLim)+ if (toLim - to < 2) {+ res = XML_CONVERT_OUTPUT_EXHAUSTED; goto after;+ }+ if (fromLim - from < 4) {+ res = XML_CONVERT_INPUT_INCOMPLETE;+ goto after;+ } n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12) | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f); n -= 0x10000;@@ -374,9 +435,12 @@ break; } }+ if (from < fromLim)+ res = XML_CONVERT_OUTPUT_EXHAUSTED; after: *fromP = from; *toP = to;+ return res; } #ifdef XML_NS@@ -425,38 +489,43 @@ STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) }; -static void PTRCALL-latin1_toUtf8(const ENCODING *enc,+static enum XML_Convert_Result PTRCALL+latin1_toUtf8(const ENCODING *UNUSED_P(enc), const char **fromP, const char *fromLim, char **toP, const char *toLim) { for (;;) { unsigned char c; if (*fromP == fromLim)- break;+ return XML_CONVERT_COMPLETED; c = (unsigned char)**fromP; if (c & 0x80) { if (toLim - *toP < 2)- break;+ return XML_CONVERT_OUTPUT_EXHAUSTED; *(*toP)++ = (char)((c >> 6) | UTF8_cval2); *(*toP)++ = (char)((c & 0x3f) | 0x80); (*fromP)++; } else { if (*toP == toLim)- break;+ return XML_CONVERT_OUTPUT_EXHAUSTED; *(*toP)++ = *(*fromP)++; } } } -static void PTRCALL-latin1_toUtf16(const ENCODING *enc,+static enum XML_Convert_Result PTRCALL+latin1_toUtf16(const ENCODING *UNUSED_P(enc), const char **fromP, const char *fromLim, unsigned short **toP, const unsigned short *toLim) {- while (*fromP != fromLim && *toP != toLim)+ while (*fromP < fromLim && *toP < toLim) *(*toP)++ = (unsigned char)*(*fromP)++;++ if ((*toP == toLim) && (*fromP < fromLim))+ return XML_CONVERT_OUTPUT_EXHAUSTED;+ else+ return XML_CONVERT_COMPLETED; } #ifdef XML_NS@@ -467,7 +536,7 @@ #include "asciitab.h" #include "latin1tab.h" },- STANDARD_VTABLE(sb_)+ STANDARD_VTABLE(sb_) NULL_VTABLE }; #endif@@ -480,16 +549,21 @@ #undef BT_COLON #include "latin1tab.h" },- STANDARD_VTABLE(sb_)+ STANDARD_VTABLE(sb_) NULL_VTABLE }; -static void PTRCALL-ascii_toUtf8(const ENCODING *enc,+static enum XML_Convert_Result PTRCALL+ascii_toUtf8(const ENCODING *UNUSED_P(enc), const char **fromP, const char *fromLim, char **toP, const char *toLim) {- while (*fromP != fromLim && *toP != toLim)+ while (*fromP < fromLim && *toP < toLim) *(*toP)++ = *(*fromP)++;++ if ((*toP == toLim) && (*fromP < fromLim))+ return XML_CONVERT_OUTPUT_EXHAUSTED;+ else+ return XML_CONVERT_COMPLETED; } #ifdef XML_NS@@ -500,7 +574,7 @@ #include "asciitab.h" /* BT_NONXML == 0 */ },- STANDARD_VTABLE(sb_)+ STANDARD_VTABLE(sb_) NULL_VTABLE }; #endif@@ -513,7 +587,7 @@ #undef BT_COLON /* BT_NONXML == 0 */ },- STANDARD_VTABLE(sb_)+ STANDARD_VTABLE(sb_) NULL_VTABLE }; static int PTRFASTCALL@@ -536,13 +610,14 @@ } #define DEFINE_UTF16_TO_UTF8(E) \-static void PTRCALL \-E ## toUtf8(const ENCODING *enc, \+static enum XML_Convert_Result PTRCALL \+E ## toUtf8(const ENCODING *UNUSED_P(enc), \ const char **fromP, const char *fromLim, \ char **toP, const char *toLim) \ { \- const char *from; \- for (from = *fromP; from != fromLim; from += 2) { \+ const char *from = *fromP; \+ fromLim = from + (((fromLim - from) >> 1) << 1); /* shrink to even */ \+ for (; from < fromLim; from += 2) { \ int plane; \ unsigned char lo2; \ unsigned char lo = GET_LO(from); \@@ -552,7 +627,7 @@ if (lo < 0x80) { \ if (*toP == toLim) { \ *fromP = from; \- return; \+ return XML_CONVERT_OUTPUT_EXHAUSTED; \ } \ *(*toP)++ = lo; \ break; \@@ -562,7 +637,7 @@ case 0x4: case 0x5: case 0x6: case 0x7: \ if (toLim - *toP < 2) { \ *fromP = from; \- return; \+ return XML_CONVERT_OUTPUT_EXHAUSTED; \ } \ *(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2); \ *(*toP)++ = ((lo & 0x3f) | 0x80); \@@ -570,7 +645,7 @@ default: \ if (toLim - *toP < 3) { \ *fromP = from; \- return; \+ return XML_CONVERT_OUTPUT_EXHAUSTED; \ } \ /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \ *(*toP)++ = ((hi >> 4) | UTF8_cval3); \@@ -580,8 +655,12 @@ case 0xD8: case 0xD9: case 0xDA: case 0xDB: \ if (toLim - *toP < 4) { \ *fromP = from; \- return; \+ return XML_CONVERT_OUTPUT_EXHAUSTED; \ } \+ if (fromLim - from < 4) { \+ *fromP = from; \+ return XML_CONVERT_INPUT_INCOMPLETE; \+ } \ plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \ *(*toP)++ = ((plane >> 2) | UTF8_cval4); \ *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \@@ -596,20 +675,32 @@ } \ } \ *fromP = from; \+ if (from < fromLim) \+ return XML_CONVERT_INPUT_INCOMPLETE; \+ else \+ return XML_CONVERT_COMPLETED; \ } #define DEFINE_UTF16_TO_UTF16(E) \-static void PTRCALL \-E ## toUtf16(const ENCODING *enc, \+static enum XML_Convert_Result PTRCALL \+E ## toUtf16(const ENCODING *UNUSED_P(enc), \ const char **fromP, const char *fromLim, \ unsigned short **toP, const unsigned short *toLim) \ { \+ enum XML_Convert_Result res = XML_CONVERT_COMPLETED; \+ fromLim = *fromP + (((fromLim - *fromP) >> 1) << 1); /* shrink to even */ \ /* Avoid copying first half only of surrogate */ \ if (fromLim - *fromP > ((toLim - *toP) << 1) \- && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) \+ && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) { \ fromLim -= 2; \- for (; *fromP != fromLim && *toP != toLim; *fromP += 2) \+ res = XML_CONVERT_INPUT_INCOMPLETE; \+ } \+ for (; *fromP < fromLim && *toP < toLim; *fromP += 2) \ *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \+ if ((*toP == toLim) && (*fromP < fromLim)) \+ return XML_CONVERT_OUTPUT_EXHAUSTED; \+ else \+ return res; \ } #define SET2(ptr, ch) \@@ -726,7 +817,7 @@ #include "asciitab.h" #include "latin1tab.h" },- STANDARD_VTABLE(little2_)+ STANDARD_VTABLE(little2_) NULL_VTABLE }; #endif@@ -745,7 +836,7 @@ #undef BT_COLON #include "latin1tab.h" },- STANDARD_VTABLE(little2_)+ STANDARD_VTABLE(little2_) NULL_VTABLE }; #if BYTEORDER != 4321@@ -758,7 +849,7 @@ #include "iasciitab.h" #include "latin1tab.h" },- STANDARD_VTABLE(little2_)+ STANDARD_VTABLE(little2_) NULL_VTABLE }; #endif@@ -771,7 +862,7 @@ #undef BT_COLON #include "latin1tab.h" },- STANDARD_VTABLE(little2_)+ STANDARD_VTABLE(little2_) NULL_VTABLE }; #endif@@ -867,7 +958,7 @@ #include "asciitab.h" #include "latin1tab.h" },- STANDARD_VTABLE(big2_)+ STANDARD_VTABLE(big2_) NULL_VTABLE }; #endif@@ -886,7 +977,7 @@ #undef BT_COLON #include "latin1tab.h" },- STANDARD_VTABLE(big2_)+ STANDARD_VTABLE(big2_) NULL_VTABLE }; #if BYTEORDER != 1234@@ -899,7 +990,7 @@ #include "iasciitab.h" #include "latin1tab.h" },- STANDARD_VTABLE(big2_)+ STANDARD_VTABLE(big2_) NULL_VTABLE }; #endif@@ -912,7 +1003,7 @@ #undef BT_COLON #include "latin1tab.h" },- STANDARD_VTABLE(big2_)+ STANDARD_VTABLE(big2_) NULL_VTABLE }; #endif@@ -938,7 +1029,7 @@ } static void PTRCALL-initUpdatePosition(const ENCODING *enc, const char *ptr,+initUpdatePosition(const ENCODING *UNUSED_P(enc), const char *ptr, const char *end, POSITION *pos) { normal_updatePosition(&utf8_encoding.enc, ptr, end, pos);@@ -1288,7 +1379,7 @@ return (c & ~0xFFFF) || checkCharRefNumber(c) < 0; } -static void PTRCALL+static enum XML_Convert_Result PTRCALL unknown_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, char **toP, const char *toLim)@@ -1299,21 +1390,21 @@ const char *utf8; int n; if (*fromP == fromLim)- break;+ return XML_CONVERT_COMPLETED; utf8 = uenc->utf8[(unsigned char)**fromP]; n = *utf8++; if (n == 0) { int c = uenc->convert(uenc->userData, *fromP); n = XmlUtf8Encode(c, buf); if (n > toLim - *toP)- break;+ return XML_CONVERT_OUTPUT_EXHAUSTED; utf8 = buf; *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP] - (BT_LEAD2 - 2)); } else { if (n > toLim - *toP)- break;+ return XML_CONVERT_OUTPUT_EXHAUSTED; (*fromP)++; } do {@@ -1322,13 +1413,13 @@ } } -static void PTRCALL+static enum XML_Convert_Result PTRCALL unknown_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim, unsigned short **toP, const unsigned short *toLim) { const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);- while (*fromP != fromLim && *toP != toLim) {+ while (*fromP < fromLim && *toP < toLim) { unsigned short c = uenc->utf16[(unsigned char)**fromP]; if (c == 0) { c = (unsigned short)@@ -1340,12 +1431,17 @@ (*fromP)++; *(*toP)++ = c; }++ if ((*toP == toLim) && (*fromP < fromLim))+ return XML_CONVERT_OUTPUT_EXHAUSTED;+ else+ return XML_CONVERT_COMPLETED; } ENCODING * XmlInitUnknownEncoding(void *mem, int *table,- CONVERTER convert, + CONVERTER convert, void *userData) { int i;@@ -1503,7 +1599,7 @@ { const ENCODING **encPtr; - if (ptr == end)+ if (ptr >= end) return XML_TOK_NONE; encPtr = enc->encPtr; if (ptr + 1 == end) {@@ -1639,7 +1735,7 @@ ENCODING * XmlInitUnknownEncodingNS(void *mem, int *table,- CONVERTER convert, + CONVERTER convert, void *userData) { ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData);
cbits/xmltok.h view
@@ -130,6 +130,12 @@ const char *, const char **); +enum XML_Convert_Result {+ XML_CONVERT_COMPLETED = 0,+ XML_CONVERT_INPUT_INCOMPLETE = 1,+ XML_CONVERT_OUTPUT_EXHAUSTED = 2 /* and therefore potentially input remaining as well */+};+ struct encoding { SCANNER scanners[XML_N_STATES]; SCANNER literalScanners[XML_N_LITERAL_TYPES];@@ -158,12 +164,12 @@ const char *ptr, const char *end, const char **badPtr);- void (PTRCALL *utf8Convert)(const ENCODING *enc,+ enum XML_Convert_Result (PTRCALL *utf8Convert)(const ENCODING *enc, const char **fromP, const char *fromLim, char **toP, const char *toLim);- void (PTRCALL *utf16Convert)(const ENCODING *enc,+ enum XML_Convert_Result (PTRCALL *utf16Convert)(const ENCODING *enc, const char **fromP, const char *fromLim, unsigned short **toP,
cbits/xmltok_impl.c view
@@ -87,27 +87,45 @@ #define PREFIX(ident) ident #endif ++#define HAS_CHARS(enc, ptr, end, count) \+ (end - ptr >= count * MINBPC(enc))++#define HAS_CHAR(enc, ptr, end) \+ HAS_CHARS(enc, ptr, end, 1)++#define REQUIRE_CHARS(enc, ptr, end, count) \+ { \+ if (! HAS_CHARS(enc, ptr, end, count)) { \+ return XML_TOK_PARTIAL; \+ } \+ }++#define REQUIRE_CHAR(enc, ptr, end) \+ REQUIRE_CHARS(enc, ptr, end, 1)++ /* ptr points to character following "<!-" */ static int PTRCALL PREFIX(scanComment)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) {- if (ptr != end) {+ if (HAS_CHAR(enc, ptr, end)) { if (!CHAR_MATCHES(enc, ptr, ASCII_MINUS)) { *nextTokPtr = ptr; return XML_TOK_INVALID; } ptr += MINBPC(enc);- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { INVALID_CASES(ptr, nextTokPtr) case BT_MINUS:- if ((ptr += MINBPC(enc)) == end)- return XML_TOK_PARTIAL;+ ptr += MINBPC(enc);+ REQUIRE_CHAR(enc, ptr, end); if (CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {- if ((ptr += MINBPC(enc)) == end)- return XML_TOK_PARTIAL;+ ptr += MINBPC(enc);+ REQUIRE_CHAR(enc, ptr, end); if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { *nextTokPtr = ptr; return XML_TOK_INVALID;@@ -131,8 +149,7 @@ PREFIX(scanDecl)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) {- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { case BT_MINUS: return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);@@ -147,11 +164,10 @@ *nextTokPtr = ptr; return XML_TOK_INVALID; }- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { case BT_PERCNT:- if (ptr + MINBPC(enc) == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHARS(enc, ptr, end, 2); /* don't allow <!ENTITY% foo "whatever"> */ switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) { case BT_S: case BT_CR: case BT_LF: case BT_PERCNT:@@ -175,7 +191,7 @@ } static int PTRCALL-PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr,+PREFIX(checkPiTarget)(const ENCODING *UNUSED_P(enc), const char *ptr, const char *end, int *tokPtr) { int upper = 0;@@ -225,15 +241,14 @@ { int tok; const char *target = ptr;- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: *nextTokPtr = ptr; return XML_TOK_INVALID; }- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_S: case BT_CR: case BT_LF:@@ -242,13 +257,12 @@ return XML_TOK_INVALID; } ptr += MINBPC(enc);- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { INVALID_CASES(ptr, nextTokPtr) case BT_QUEST: ptr += MINBPC(enc);- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { *nextTokPtr = ptr + MINBPC(enc); return tok;@@ -266,8 +280,7 @@ return XML_TOK_INVALID; } ptr += MINBPC(enc);- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { *nextTokPtr = ptr + MINBPC(enc); return tok;@@ -282,15 +295,14 @@ } static int PTRCALL-PREFIX(scanCdataSection)(const ENCODING *enc, const char *ptr,+PREFIX(scanCdataSection)(const ENCODING *UNUSED_P(enc), const char *ptr, const char *end, const char **nextTokPtr) { static const char CDATA_LSQB[] = { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, ASCII_LSQB }; int i; /* CDATA[ */- if (end - ptr < 6 * MINBPC(enc))- return XML_TOK_PARTIAL;+ REQUIRE_CHARS(enc, ptr, end, 6); for (i = 0; i < 6; i++, ptr += MINBPC(enc)) { if (!CHAR_MATCHES(enc, ptr, CDATA_LSQB[i])) { *nextTokPtr = ptr;@@ -305,7 +317,7 @@ PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) {- if (ptr == end)+ if (ptr >= end) return XML_TOK_NONE; if (MINBPC(enc) > 1) { size_t n = end - ptr;@@ -319,13 +331,11 @@ switch (BYTE_TYPE(enc, ptr)) { case BT_RSQB: ptr += MINBPC(enc);- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB)) break; ptr += MINBPC(enc);- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { ptr -= MINBPC(enc); break;@@ -334,8 +344,7 @@ return XML_TOK_CDATA_SECT_CLOSE; case BT_CR: ptr += MINBPC(enc);- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); if (BYTE_TYPE(enc, ptr) == BT_LF) ptr += MINBPC(enc); *nextTokPtr = ptr;@@ -348,7 +357,7 @@ ptr += MINBPC(enc); break; }- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { #define LEAD_CASE(n) \ case BT_LEAD ## n: \@@ -383,19 +392,18 @@ PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) {- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: *nextTokPtr = ptr; return XML_TOK_INVALID; }- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_S: case BT_CR: case BT_LF:- for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {+ for (ptr += MINBPC(enc); HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) { switch (BYTE_TYPE(enc, ptr)) { case BT_S: case BT_CR: case BT_LF: break;@@ -432,7 +440,7 @@ PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) {- if (ptr != end) {+ if (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { case BT_DIGIT: case BT_HEX:@@ -441,7 +449,7 @@ *nextTokPtr = ptr; return XML_TOK_INVALID; }- for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {+ for (ptr += MINBPC(enc); HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) { switch (BYTE_TYPE(enc, ptr)) { case BT_DIGIT: case BT_HEX:@@ -464,7 +472,7 @@ PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) {- if (ptr != end) {+ if (HAS_CHAR(enc, ptr, end)) { if (CHAR_MATCHES(enc, ptr, ASCII_x)) return PREFIX(scanHexCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); switch (BYTE_TYPE(enc, ptr)) {@@ -474,7 +482,7 @@ *nextTokPtr = ptr; return XML_TOK_INVALID; }- for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {+ for (ptr += MINBPC(enc); HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) { switch (BYTE_TYPE(enc, ptr)) { case BT_DIGIT: break;@@ -496,8 +504,7 @@ PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) {- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) case BT_NUM:@@ -506,7 +513,7 @@ *nextTokPtr = ptr; return XML_TOK_INVALID; }- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_SEMI:@@ -529,7 +536,7 @@ #ifdef XML_NS int hadColon = 0; #endif- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) #ifdef XML_NS@@ -540,8 +547,7 @@ } hadColon = 1; ptr += MINBPC(enc);- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default:@@ -555,8 +561,7 @@ int t; ptr += MINBPC(enc);- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); t = BYTE_TYPE(enc, ptr); if (t == BT_EQUALS) break;@@ -579,8 +584,7 @@ #endif for (;;) { ptr += MINBPC(enc);- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); open = BYTE_TYPE(enc, ptr); if (open == BT_QUOT || open == BT_APOS) break;@@ -598,8 +602,7 @@ /* in attribute value */ for (;;) { int t;- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); t = BYTE_TYPE(enc, ptr); if (t == open) break;@@ -624,8 +627,7 @@ } } ptr += MINBPC(enc);- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { case BT_S: case BT_CR:@@ -642,8 +644,7 @@ /* ptr points to closing quote */ for (;;) { ptr += MINBPC(enc);- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) case BT_S: case BT_CR: case BT_LF:@@ -655,8 +656,7 @@ case BT_SOL: sol: ptr += MINBPC(enc);- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { *nextTokPtr = ptr; return XML_TOK_INVALID;@@ -688,13 +688,12 @@ #ifdef XML_NS int hadColon; #endif- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) case BT_EXCL:- if ((ptr += MINBPC(enc)) == end)- return XML_TOK_PARTIAL;+ ptr += MINBPC(enc);+ REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { case BT_MINUS: return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);@@ -716,7 +715,7 @@ hadColon = 0; #endif /* we have a start-tag */- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) #ifdef XML_NS@@ -727,8 +726,7 @@ } hadColon = 1; ptr += MINBPC(enc);- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default:@@ -740,7 +738,7 @@ case BT_S: case BT_CR: case BT_LF: { ptr += MINBPC(enc);- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) case BT_GT:@@ -765,8 +763,7 @@ case BT_SOL: sol: ptr += MINBPC(enc);- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { *nextTokPtr = ptr; return XML_TOK_INVALID;@@ -785,7 +782,7 @@ PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) {- if (ptr == end)+ if (ptr >= end) return XML_TOK_NONE; if (MINBPC(enc) > 1) { size_t n = end - ptr;@@ -803,7 +800,7 @@ return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); case BT_CR: ptr += MINBPC(enc);- if (ptr == end)+ if (! HAS_CHAR(enc, ptr, end)) return XML_TOK_TRAILING_CR; if (BYTE_TYPE(enc, ptr) == BT_LF) ptr += MINBPC(enc);@@ -814,12 +811,12 @@ return XML_TOK_DATA_NEWLINE; case BT_RSQB: ptr += MINBPC(enc);- if (ptr == end)+ if (! HAS_CHAR(enc, ptr, end)) return XML_TOK_TRAILING_RSQB; if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB)) break; ptr += MINBPC(enc);- if (ptr == end)+ if (! HAS_CHAR(enc, ptr, end)) return XML_TOK_TRAILING_RSQB; if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { ptr -= MINBPC(enc);@@ -832,7 +829,7 @@ ptr += MINBPC(enc); break; }- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { #define LEAD_CASE(n) \ case BT_LEAD ## n: \@@ -845,12 +842,12 @@ LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) #undef LEAD_CASE case BT_RSQB:- if (ptr + MINBPC(enc) != end) {+ if (HAS_CHARS(enc, ptr, end, 2)) { if (!CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) { ptr += MINBPC(enc); break; }- if (ptr + 2*MINBPC(enc) != end) {+ if (HAS_CHARS(enc, ptr, end, 3)) { if (!CHAR_MATCHES(enc, ptr + 2*MINBPC(enc), ASCII_GT)) { ptr += MINBPC(enc); break;@@ -884,8 +881,7 @@ PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) {- if (ptr == end)- return -XML_TOK_PERCENT;+ REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) case BT_S: case BT_LF: case BT_CR: case BT_PERCNT:@@ -895,7 +891,7 @@ *nextTokPtr = ptr; return XML_TOK_INVALID; }- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_SEMI:@@ -913,15 +909,14 @@ PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) {- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: *nextTokPtr = ptr; return XML_TOK_INVALID; }- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_CR: case BT_LF: case BT_S:@@ -941,7 +936,7 @@ const char *ptr, const char *end, const char **nextTokPtr) {- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { int t = BYTE_TYPE(enc, ptr); switch (t) { INVALID_CASES(ptr, nextTokPtr)@@ -950,7 +945,7 @@ ptr += MINBPC(enc); if (t != open) break;- if (ptr == end)+ if (! HAS_CHAR(enc, ptr, end)) return -XML_TOK_LITERAL; *nextTokPtr = ptr; switch (BYTE_TYPE(enc, ptr)) {@@ -973,7 +968,7 @@ const char **nextTokPtr) { int tok;- if (ptr == end)+ if (ptr >= end) return XML_TOK_NONE; if (MINBPC(enc) > 1) { size_t n = end - ptr;@@ -992,8 +987,7 @@ case BT_LT: { ptr += MINBPC(enc);- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { case BT_EXCL: return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr);@@ -1021,7 +1015,7 @@ case BT_S: case BT_LF: for (;;) { ptr += MINBPC(enc);- if (ptr == end)+ if (! HAS_CHAR(enc, ptr, end)) break; switch (BYTE_TYPE(enc, ptr)) { case BT_S: case BT_LF:@@ -1048,11 +1042,10 @@ return XML_TOK_OPEN_BRACKET; case BT_RSQB: ptr += MINBPC(enc);- if (ptr == end)+ if (! HAS_CHAR(enc, ptr, end)) return -XML_TOK_CLOSE_BRACKET; if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {- if (ptr + MINBPC(enc) == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHARS(enc, ptr, end, 2); if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) { *nextTokPtr = ptr + 2*MINBPC(enc); return XML_TOK_COND_SECT_CLOSE;@@ -1065,7 +1058,7 @@ return XML_TOK_OPEN_PAREN; case BT_RPAR: ptr += MINBPC(enc);- if (ptr == end)+ if (! HAS_CHAR(enc, ptr, end)) return -XML_TOK_CLOSE_PAREN; switch (BYTE_TYPE(enc, ptr)) { case BT_AST:@@ -1141,7 +1134,7 @@ *nextTokPtr = ptr; return XML_TOK_INVALID; }- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_GT: case BT_RPAR: case BT_COMMA:@@ -1154,8 +1147,7 @@ ptr += MINBPC(enc); switch (tok) { case XML_TOK_NAME:- if (ptr == end)- return XML_TOK_PARTIAL;+ REQUIRE_CHAR(enc, ptr, end); tok = XML_TOK_PREFIXED_NAME; switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)@@ -1204,10 +1196,12 @@ const char *end, const char **nextTokPtr) { const char *start;- if (ptr == end)+ if (ptr >= end) return XML_TOK_NONE;+ else if (! HAS_CHAR(enc, ptr, end))+ return XML_TOK_PARTIAL; start = ptr;- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { #define LEAD_CASE(n) \ case BT_LEAD ## n: ptr += n; break;@@ -1232,7 +1226,7 @@ case BT_CR: if (ptr == start) { ptr += MINBPC(enc);- if (ptr == end)+ if (! HAS_CHAR(enc, ptr, end)) return XML_TOK_TRAILING_CR; if (BYTE_TYPE(enc, ptr) == BT_LF) ptr += MINBPC(enc);@@ -1262,10 +1256,12 @@ const char *end, const char **nextTokPtr) { const char *start;- if (ptr == end)+ if (ptr >= end) return XML_TOK_NONE;+ else if (! HAS_CHAR(enc, ptr, end))+ return XML_TOK_PARTIAL; start = ptr;- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { #define LEAD_CASE(n) \ case BT_LEAD ## n: ptr += n; break;@@ -1294,7 +1290,7 @@ case BT_CR: if (ptr == start) { ptr += MINBPC(enc);- if (ptr == end)+ if (! HAS_CHAR(enc, ptr, end)) return XML_TOK_TRAILING_CR; if (BYTE_TYPE(enc, ptr) == BT_LF) ptr += MINBPC(enc);@@ -1326,15 +1322,15 @@ end = ptr + n; } }- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { INVALID_CASES(ptr, nextTokPtr) case BT_LT:- if ((ptr += MINBPC(enc)) == end)- return XML_TOK_PARTIAL;+ ptr += MINBPC(enc);+ REQUIRE_CHAR(enc, ptr, end); if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) {- if ((ptr += MINBPC(enc)) == end)- return XML_TOK_PARTIAL;+ ptr += MINBPC(enc);+ REQUIRE_CHAR(enc, ptr, end); if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) { ++level; ptr += MINBPC(enc);@@ -1342,11 +1338,11 @@ } break; case BT_RSQB:- if ((ptr += MINBPC(enc)) == end)- return XML_TOK_PARTIAL;+ ptr += MINBPC(enc);+ REQUIRE_CHAR(enc, ptr, end); if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {- if ((ptr += MINBPC(enc)) == end)- return XML_TOK_PARTIAL;+ ptr += MINBPC(enc);+ REQUIRE_CHAR(enc, ptr, end); if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { ptr += MINBPC(enc); if (level == 0) {@@ -1373,7 +1369,7 @@ { ptr += MINBPC(enc); end -= MINBPC(enc);- for (; ptr != end; ptr += MINBPC(enc)) {+ for (; HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) { switch (BYTE_TYPE(enc, ptr)) { case BT_DIGIT: case BT_HEX:@@ -1521,7 +1517,7 @@ } static int PTRFASTCALL-PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr)+PREFIX(charRefNumber)(const ENCODING *UNUSED_P(enc), const char *ptr) { int result = 0; /* skip &# */@@ -1565,7 +1561,7 @@ } static int PTRCALL-PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr,+PREFIX(predefinedEntityName)(const ENCODING *UNUSED_P(enc), const char *ptr, const char *end) { switch ((end - ptr)/MINBPC(enc)) {@@ -1683,11 +1679,11 @@ } static int PTRCALL-PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1,+PREFIX(nameMatchesAscii)(const ENCODING *UNUSED_P(enc), const char *ptr1, const char *end1, const char *ptr2) { for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) {- if (ptr1 == end1)+ if (end1 - ptr1 < MINBPC(enc)) return 0; if (!CHAR_MATCHES(enc, ptr1, *ptr2)) return 0;@@ -1744,7 +1740,7 @@ const char *end, POSITION *pos) {- while (ptr != end) {+ while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { #define LEAD_CASE(n) \ case BT_LEAD ## n: \@@ -1760,7 +1756,7 @@ case BT_CR: pos->lineNumber++; ptr += MINBPC(enc);- if (ptr != end && BYTE_TYPE(enc, ptr) == BT_LF)+ if (HAS_CHAR(enc, ptr, end) && BYTE_TYPE(enc, ptr) == BT_LF) ptr += MINBPC(enc); pos->columnNumber = (XML_Size)-1; break;
hexpat.cabal view
@@ -1,6 +1,6 @@ Cabal-Version: >= 1.6 Name: hexpat-Version: 0.20.10+Version: 0.20.11 Synopsis: XML parser/formatter based on expat Description: This package provides a general purpose Haskell XML library using Expat to@@ -50,7 +50,8 @@ performance; 0.20.2 make parseSaxG lazier; 0.20.3 minor build issues; 0.20.4 remove dependency on extensible-exceptions; 0.20.5 bump text upper bound; 0.20.6 bump text again to include 1.1.x.x; 0.20.7 bump text again for 1.2.x.x; 0.20.8 bump utf8-string dep;- 0.20.9 bump deepseq dep/ghc-7.10 compatibility.; 0.20.10 increase dependency upper bounds+ 0.20.9 bump deepseq dep/ghc-7.10 compatibility.; 0.20.10 increase dependency upper bounds;+ 0.20.11 update to libexpat-2.2.1 which includes several security fixes. Category: XML License: BSD3 License-File: LICENSE@@ -95,21 +96,29 @@ test/hexpat-leak/build.sh test/readRoads.hs, test/ROADS.xml,- cbits/amigaconfig.h,- cbits/asciitab.h,- cbits/expat.h,- cbits/internal.h,- cbits/macconfig.h,- cbits/utf8tab.h,- cbits/xmlrole.h,- cbits/xmltok_impl.h,- cbits/ascii.h,- cbits/expat_external.h,- cbits/iasciitab.h,- cbits/latin1tab.h,- cbits/nametab.h, cbits/winconfig.h, cbits/xmltok.h+ cbits/winconfig.h+ cbits/xmltok_ns.c+ cbits/internal.h+ cbits/utf8tab.h+ cbits/siphash.h+ cbits/latin1tab.h+ cbits/xmltok.h+ cbits/expat.h+ cbits/xmltok.c+ cbits/iasciitab.h+ cbits/asciitab.h+ cbits/README+ cbits/xmlparse.c+ cbits/xmltok_impl.h+ cbits/xmltok_impl.c+ cbits/xmlrole.c+ cbits/xmlrole.h+ cbits/expat_external.h+ cbits/ascii.h+ cbits/nametab.h+ Build-Type: Simple Stability: beta source-repository head