Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/expat/src/xmlparse.c

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /externals/expat/src/xmlparse.c (Version 11.3.0) and /externals/expat/src/xmlparse.c (Version 11.1.3)


  1 /* 90815a2b2c80c03b2b889fe1d427bb2b9e3282aa065      1 /* 90815a2b2c80c03b2b889fe1d427bb2b9e3282aa065e42784e001db4f23de324 (2.4.9+)
  2                             __  __                  2                             __  __            _
  3                          ___\ \/ /_ __   __ _|      3                          ___\ \/ /_ __   __ _| |_
  4                         / _ \\  /| '_ \ / _` |      4                         / _ \\  /| '_ \ / _` | __|
  5                        |  __//  \| |_) | (_| |      5                        |  __//  \| |_) | (_| | |_
  6                         \___/_/\_\ .__/ \__,_|      6                         \___/_/\_\ .__/ \__,_|\__|
  7                                  |_| XML parse      7                                  |_| XML parser
  8                                                     8 
  9    Copyright (c) 1997-2000 Thai Open Source So      9    Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
 10    Copyright (c) 2000      Clark Cooper <coope     10    Copyright (c) 2000      Clark Cooper <coopercc@users.sourceforge.net>
 11    Copyright (c) 2000-2006 Fred L. Drake, Jr.      11    Copyright (c) 2000-2006 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
 12    Copyright (c) 2001-2002 Greg Stein <gstein@     12    Copyright (c) 2001-2002 Greg Stein <gstein@users.sourceforge.net>
 13    Copyright (c) 2002-2016 Karl Waclawek <karl     13    Copyright (c) 2002-2016 Karl Waclawek <karl@waclawek.net>
 14    Copyright (c) 2005-2009 Steven Solie <steve     14    Copyright (c) 2005-2009 Steven Solie <steven@solie.ca>
 15    Copyright (c) 2016      Eric Rahm <erahm@mo     15    Copyright (c) 2016      Eric Rahm <erahm@mozilla.com>
 16    Copyright (c) 2016-2022 Sebastian Pipping <     16    Copyright (c) 2016-2022 Sebastian Pipping <sebastian@pipping.org>
 17    Copyright (c) 2016      Gaurav <g.gupta@sam     17    Copyright (c) 2016      Gaurav <g.gupta@samsung.com>
 18    Copyright (c) 2016      Thomas Beutlich <tc     18    Copyright (c) 2016      Thomas Beutlich <tc@tbeu.de>
 19    Copyright (c) 2016      Gustavo Grieco <gus     19    Copyright (c) 2016      Gustavo Grieco <gustavo.grieco@imag.fr>
 20    Copyright (c) 2016      Pascal Cuoq <cuoq@t     20    Copyright (c) 2016      Pascal Cuoq <cuoq@trust-in-soft.com>
 21    Copyright (c) 2016      Ed Schouten <ed@nux     21    Copyright (c) 2016      Ed Schouten <ed@nuxi.nl>
 22    Copyright (c) 2017-2022 Rhodri James <rhodr     22    Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk>
 23    Copyright (c) 2017      Václav Slavík <va     23    Copyright (c) 2017      Václav Slavík <vaclav@slavik.io>
 24    Copyright (c) 2017      Viktor Szakats <com     24    Copyright (c) 2017      Viktor Szakats <commit@vsz.me>
 25    Copyright (c) 2017      Chanho Park <chanho     25    Copyright (c) 2017      Chanho Park <chanho61.park@samsung.com>
 26    Copyright (c) 2017      Rolf Eike Beer <eik     26    Copyright (c) 2017      Rolf Eike Beer <eike@sf-mail.de>
 27    Copyright (c) 2017      Hans Wennborg <hans     27    Copyright (c) 2017      Hans Wennborg <hans@chromium.org>
 28    Copyright (c) 2018      Anton Maklakov <ant     28    Copyright (c) 2018      Anton Maklakov <antmak.pub@gmail.com>
 29    Copyright (c) 2018      Benjamin Peterson <     29    Copyright (c) 2018      Benjamin Peterson <benjamin@python.org>
 30    Copyright (c) 2018      Marco Maggi <marco.     30    Copyright (c) 2018      Marco Maggi <marco.maggi-ipsu@poste.it>
 31    Copyright (c) 2018      Mariusz Zaborski <o     31    Copyright (c) 2018      Mariusz Zaborski <oshogbo@vexillium.org>
 32    Copyright (c) 2019      David Loffredo <lof     32    Copyright (c) 2019      David Loffredo <loffredo@steptools.com>
 33    Copyright (c) 2019-2020 Ben Wagner <bungema     33    Copyright (c) 2019-2020 Ben Wagner <bungeman@chromium.org>
 34    Copyright (c) 2019      Vadim Zeitlin <vadi     34    Copyright (c) 2019      Vadim Zeitlin <vadim@zeitlins.org>
 35    Copyright (c) 2021      Dong-hee Na <donghe     35    Copyright (c) 2021      Dong-hee Na <donghee.na@python.org>
 36    Copyright (c) 2022      Samanta Navarro <fe     36    Copyright (c) 2022      Samanta Navarro <ferivoz@riseup.net>
 37    Copyright (c) 2022      Jeffrey Walton <nol     37    Copyright (c) 2022      Jeffrey Walton <noloader@gmail.com>
 38    Licensed under the MIT license:                 38    Licensed under the MIT license:
 39                                                    39 
 40    Permission is  hereby granted,  free of cha     40    Permission is  hereby granted,  free of charge,  to any  person obtaining
 41    a  copy  of  this  software   and  associat     41    a  copy  of  this  software   and  associated  documentation  files  (the
 42    "Software"),  to  deal in  the  Software  w     42    "Software"),  to  deal in  the  Software  without restriction,  including
 43    without  limitation the  rights  to use,  c     43    without  limitation the  rights  to use,  copy,  modify, merge,  publish,
 44    distribute, sublicense, and/or sell copies      44    distribute, sublicense, and/or sell copies of the Software, and to permit
 45    persons  to whom  the Software  is  furnish     45    persons  to whom  the Software  is  furnished to  do so,  subject to  the
 46    following conditions:                           46    following conditions:
 47                                                    47 
 48    The above copyright  notice and this permis     48    The above copyright  notice and this permission notice  shall be included
 49    in all copies or substantial portions of th     49    in all copies or substantial portions of the Software.
 50                                                    50 
 51    THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WIT     51    THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
 52    EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT L     52    EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
 53    MERCHANTABILITY, FITNESS FOR A PARTICULAR P     53    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
 54    NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HO     54    NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 55    DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN     55    DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
 56    OTHERWISE, ARISING FROM, OUT OF OR IN CONNE     56    OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 57    USE OR OTHER DEALINGS IN THE SOFTWARE.          57    USE OR OTHER DEALINGS IN THE SOFTWARE.
 58 */                                                 58 */
 59                                                    59 
 60 #define XML_BUILDING_EXPAT 1                       60 #define XML_BUILDING_EXPAT 1
 61                                                    61 
 62 #include <expat_config.h>                          62 #include <expat_config.h>
 63                                                    63 
 64 #if ! defined(_GNU_SOURCE)                         64 #if ! defined(_GNU_SOURCE)
 65 #  define _GNU_SOURCE 1 /* syscall prototype *     65 #  define _GNU_SOURCE 1 /* syscall prototype */
 66 #endif                                             66 #endif
 67                                                    67 
 68 #ifdef _WIN32                                      68 #ifdef _WIN32
 69 /* force stdlib to define rand_s() */              69 /* force stdlib to define rand_s() */
 70 #  if ! defined(_CRT_RAND_S)                       70 #  if ! defined(_CRT_RAND_S)
 71 #    define _CRT_RAND_S                            71 #    define _CRT_RAND_S
 72 #  endif                                           72 #  endif
 73 #endif                                             73 #endif
 74                                                    74 
 75 #include <stddef.h>                                75 #include <stddef.h>
 76 #include <string.h> /* memset(), memcpy() */       76 #include <string.h> /* memset(), memcpy() */
 77 #include <assert.h>                                77 #include <assert.h>
 78 #include <limits.h> /* UINT_MAX */                 78 #include <limits.h> /* UINT_MAX */
 79 #include <stdio.h>  /* fprintf */                  79 #include <stdio.h>  /* fprintf */
 80 #include <stdlib.h> /* getenv, rand_s */           80 #include <stdlib.h> /* getenv, rand_s */
 81 #include <stdint.h> /* uintptr_t */                81 #include <stdint.h> /* uintptr_t */
 82 #include <math.h>   /* isnan */                    82 #include <math.h>   /* isnan */
 83                                                    83 
 84 #ifdef _WIN32                                      84 #ifdef _WIN32
 85 #  define getpid GetCurrentProcessId               85 #  define getpid GetCurrentProcessId
 86 #else                                              86 #else
 87 #  include <sys/time.h>  /* gettimeofday() */      87 #  include <sys/time.h>  /* gettimeofday() */
 88 #  include <sys/types.h> /* getpid() */            88 #  include <sys/types.h> /* getpid() */
 89 #  include <unistd.h>    /* getpid() */            89 #  include <unistd.h>    /* getpid() */
 90 #  include <fcntl.h>     /* O_RDONLY */            90 #  include <fcntl.h>     /* O_RDONLY */
 91 #  include <errno.h>                               91 #  include <errno.h>
 92 #endif                                             92 #endif
 93                                                    93 
 94 #ifdef _WIN32                                      94 #ifdef _WIN32
 95 #  include "winconfig.h"                           95 #  include "winconfig.h"
 96 #endif                                             96 #endif
 97                                                    97 
 98 #include "ascii.h"                                 98 #include "ascii.h"
 99 #include "expat.h"                                 99 #include "expat.h"
100 #include "siphash.h"                              100 #include "siphash.h"
101                                                   101 
102 #if defined(HAVE_GETRANDOM) || defined(HAVE_SY    102 #if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
103 #  if defined(HAVE_GETRANDOM)                     103 #  if defined(HAVE_GETRANDOM)
104 #    include <sys/random.h> /* getrandom */       104 #    include <sys/random.h> /* getrandom */
105 #  else                                           105 #  else
106 #    include <unistd.h>      /* syscall */        106 #    include <unistd.h>      /* syscall */
107 #    include <sys/syscall.h> /* SYS_getrandom     107 #    include <sys/syscall.h> /* SYS_getrandom */
108 #  endif                                          108 #  endif
109 #  if ! defined(GRND_NONBLOCK)                    109 #  if ! defined(GRND_NONBLOCK)
110 #    define GRND_NONBLOCK 0x0001                  110 #    define GRND_NONBLOCK 0x0001
111 #  endif /* defined(GRND_NONBLOCK) */             111 #  endif /* defined(GRND_NONBLOCK) */
112 #endif   /* defined(HAVE_GETRANDOM) || defined    112 #endif   /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */
113                                                   113 
114 #if defined(HAVE_LIBBSD)                          114 #if defined(HAVE_LIBBSD)                                                       \
115     && (defined(HAVE_ARC4RANDOM_BUF) || define    115     && (defined(HAVE_ARC4RANDOM_BUF) || defined(HAVE_ARC4RANDOM))
116 #  include <bsd/stdlib.h>                         116 #  include <bsd/stdlib.h>
117 #endif                                            117 #endif
118                                                   118 
119 #if defined(_WIN32) && ! defined(LOAD_LIBRARY_    119 #if defined(_WIN32) && ! defined(LOAD_LIBRARY_SEARCH_SYSTEM32)
120 #  define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000    120 #  define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800
121 #endif                                            121 #endif
122                                                   122 
123 #if ! defined(HAVE_GETRANDOM) && ! defined(HAV    123 #if ! defined(HAVE_GETRANDOM) && ! defined(HAVE_SYSCALL_GETRANDOM)             \
124     && ! defined(HAVE_ARC4RANDOM_BUF) && ! def    124     && ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM)            \
125     && ! defined(XML_DEV_URANDOM) && ! defined    125     && ! defined(XML_DEV_URANDOM) && ! defined(_WIN32)                         \
126     && ! defined(XML_POOR_ENTROPY)                126     && ! defined(XML_POOR_ENTROPY)
127 #  error You do not have support for any sourc    127 #  error You do not have support for any sources of high quality entropy \
128     enabled.  For end user security, that is p    128     enabled.  For end user security, that is probably not what you want. \
129     \                                             129     \
130     Your options include: \                       130     Your options include: \
131       * Linux >=3.17 + glibc >=2.25 (getrandom    131       * Linux >=3.17 + glibc >=2.25 (getrandom): HAVE_GETRANDOM, \
132       * Linux >=3.17 + glibc (including <2.25)    132       * Linux >=3.17 + glibc (including <2.25) (syscall SYS_getrandom): HAVE_SYSCALL_GETRANDOM, \
133       * BSD / macOS >=10.7 (arc4random_buf): H    133       * BSD / macOS >=10.7 (arc4random_buf): HAVE_ARC4RANDOM_BUF, \
134       * BSD / macOS (including <10.7) (arc4ran    134       * BSD / macOS (including <10.7) (arc4random): HAVE_ARC4RANDOM, \
135       * libbsd (arc4random_buf): HAVE_ARC4RAND    135       * libbsd (arc4random_buf): HAVE_ARC4RANDOM_BUF + HAVE_LIBBSD, \
136       * libbsd (arc4random): HAVE_ARC4RANDOM +    136       * libbsd (arc4random): HAVE_ARC4RANDOM + HAVE_LIBBSD, \
137       * Linux (including <3.17) / BSD / macOS     137       * Linux (including <3.17) / BSD / macOS (including <10.7) / Solaris >=8 (/dev/urandom): XML_DEV_URANDOM, \
138       * Windows >=Vista (rand_s): _WIN32. \       138       * Windows >=Vista (rand_s): _WIN32. \
139     \                                             139     \
140     If insist on not using any of these, bypas    140     If insist on not using any of these, bypass this error by defining \
141     XML_POOR_ENTROPY; you have been warned. \     141     XML_POOR_ENTROPY; you have been warned. \
142     \                                             142     \
143     If you have reasons to patch this detectio    143     If you have reasons to patch this detection code away or need changes \
144     to the build system, please open a bug.  T    144     to the build system, please open a bug.  Thank you!
145 #endif                                            145 #endif
146                                                   146 
147 #ifdef XML_UNICODE                                147 #ifdef XML_UNICODE
148 #  define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX     148 #  define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
149 #  define XmlConvert XmlUtf16Convert              149 #  define XmlConvert XmlUtf16Convert
150 #  define XmlGetInternalEncoding XmlGetUtf16In    150 #  define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
151 #  define XmlGetInternalEncodingNS XmlGetUtf16    151 #  define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
152 #  define XmlEncode XmlUtf16Encode                152 #  define XmlEncode XmlUtf16Encode
153 #  define MUST_CONVERT(enc, s) (! (enc)->isUtf    153 #  define MUST_CONVERT(enc, s) (! (enc)->isUtf16 || (((uintptr_t)(s)) & 1))
154 typedef unsigned short ICHAR;                     154 typedef unsigned short ICHAR;
155 #else                                             155 #else
156 #  define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX      156 #  define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
157 #  define XmlConvert XmlUtf8Convert               157 #  define XmlConvert XmlUtf8Convert
158 #  define XmlGetInternalEncoding XmlGetUtf8Int    158 #  define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
159 #  define XmlGetInternalEncodingNS XmlGetUtf8I    159 #  define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
160 #  define XmlEncode XmlUtf8Encode                 160 #  define XmlEncode XmlUtf8Encode
161 #  define MUST_CONVERT(enc, s) (! (enc)->isUtf    161 #  define MUST_CONVERT(enc, s) (! (enc)->isUtf8)
162 typedef char ICHAR;                               162 typedef char ICHAR;
163 #endif                                            163 #endif
164                                                   164 
165 #ifndef XML_NS                                    165 #ifndef XML_NS
166                                                   166 
167 #  define XmlInitEncodingNS XmlInitEncoding       167 #  define XmlInitEncodingNS XmlInitEncoding
168 #  define XmlInitUnknownEncodingNS XmlInitUnkn    168 #  define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
169 #  undef XmlGetInternalEncodingNS                 169 #  undef XmlGetInternalEncodingNS
170 #  define XmlGetInternalEncodingNS XmlGetInter    170 #  define XmlGetInternalEncodingNS XmlGetInternalEncoding
171 #  define XmlParseXmlDeclNS XmlParseXmlDecl       171 #  define XmlParseXmlDeclNS XmlParseXmlDecl
172                                                   172 
173 #endif                                            173 #endif
174                                                   174 
175 #ifdef XML_UNICODE                                175 #ifdef XML_UNICODE
176                                                   176 
177 #  ifdef XML_UNICODE_WCHAR_T                      177 #  ifdef XML_UNICODE_WCHAR_T
178 #    define XML_T(x) (const wchar_t) x            178 #    define XML_T(x) (const wchar_t) x
179 #    define XML_L(x) L##x                         179 #    define XML_L(x) L##x
180 #  else                                           180 #  else
181 #    define XML_T(x) (const unsigned short)x      181 #    define XML_T(x) (const unsigned short)x
182 #    define XML_L(x) x                            182 #    define XML_L(x) x
183 #  endif                                          183 #  endif
184                                                   184 
185 #else                                             185 #else
186                                                   186 
187 #  define XML_T(x) x                              187 #  define XML_T(x) x
188 #  define XML_L(x) x                              188 #  define XML_L(x) x
189                                                   189 
190 #endif                                            190 #endif
191                                                   191 
192 /* Round up n to be a multiple of sz, where sz    192 /* Round up n to be a multiple of sz, where sz is a power of 2. */
193 #define ROUND_UP(n, sz) (((n) + ((sz)-1)) & ~(    193 #define ROUND_UP(n, sz) (((n) + ((sz)-1)) & ~((sz)-1))
194                                                   194 
195 /* Do safe (NULL-aware) pointer arithmetic */     195 /* Do safe (NULL-aware) pointer arithmetic */
196 #define EXPAT_SAFE_PTR_DIFF(p, q) (((p) && (q)    196 #define EXPAT_SAFE_PTR_DIFF(p, q) (((p) && (q)) ? ((p) - (q)) : 0)
197                                                   197 
198 #include "internal.h"                             198 #include "internal.h"
199 #include "xmltok.h"                               199 #include "xmltok.h"
200 #include "xmlrole.h"                              200 #include "xmlrole.h"
201                                                   201 
202 typedef const XML_Char *KEY;                      202 typedef const XML_Char *KEY;
203                                                   203 
204 typedef struct {                                  204 typedef struct {
205   KEY name;                                       205   KEY name;
206 } NAMED;                                          206 } NAMED;
207                                                   207 
208 typedef struct {                                  208 typedef struct {
209   NAMED **v;                                      209   NAMED **v;
210   unsigned char power;                            210   unsigned char power;
211   size_t size;                                    211   size_t size;
212   size_t used;                                    212   size_t used;
213   const XML_Memory_Handling_Suite *mem;           213   const XML_Memory_Handling_Suite *mem;
214 } HASH_TABLE;                                     214 } HASH_TABLE;
215                                                   215 
216 static size_t keylen(KEY s);                      216 static size_t keylen(KEY s);
217                                                   217 
218 static void copy_salt_to_sipkey(XML_Parser par    218 static void copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key);
219                                                   219 
220 /* For probing (after a collision) we need a s    220 /* For probing (after a collision) we need a step size relative prime
221    to the hash table size, which is a power of    221    to the hash table size, which is a power of 2. We use double-hashing,
222    since we can calculate a second hash value     222    since we can calculate a second hash value cheaply by taking those bits
223    of the first hash value that were discarded    223    of the first hash value that were discarded (masked out) when the table
224    index was calculated: index = hash & mask,     224    index was calculated: index = hash & mask, where mask = table->size - 1.
225    We limit the maximum step size to table->si    225    We limit the maximum step size to table->size / 4 (mask >> 2) and make
226    it odd, since odd numbers are always relati    226    it odd, since odd numbers are always relative prime to a power of 2.
227 */                                                227 */
228 #define SECOND_HASH(hash, mask, power)            228 #define SECOND_HASH(hash, mask, power)                                         \
229   ((((hash) & ~(mask)) >> ((power)-1)) & ((mas    229   ((((hash) & ~(mask)) >> ((power)-1)) & ((mask) >> 2))
230 #define PROBE_STEP(hash, mask, power)             230 #define PROBE_STEP(hash, mask, power)                                          \
231   ((unsigned char)((SECOND_HASH(hash, mask, po    231   ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
232                                                   232 
233 typedef struct {                                  233 typedef struct {
234   NAMED **p;                                      234   NAMED **p;
235   NAMED **end;                                    235   NAMED **end;
236 } HASH_TABLE_ITER;                                236 } HASH_TABLE_ITER;
237                                                   237 
238 #define INIT_TAG_BUF_SIZE 32 /* must be a mult    238 #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
239 #define INIT_DATA_BUF_SIZE 1024                   239 #define INIT_DATA_BUF_SIZE 1024
240 #define INIT_ATTS_SIZE 16                         240 #define INIT_ATTS_SIZE 16
241 #define INIT_ATTS_VERSION 0xFFFFFFFF              241 #define INIT_ATTS_VERSION 0xFFFFFFFF
242 #define INIT_BLOCK_SIZE 1024                      242 #define INIT_BLOCK_SIZE 1024
243 #define INIT_BUFFER_SIZE 1024                     243 #define INIT_BUFFER_SIZE 1024
244                                                   244 
245 #define EXPAND_SPARE 24                           245 #define EXPAND_SPARE 24
246                                                   246 
247 typedef struct binding {                          247 typedef struct binding {
248   struct prefix *prefix;                          248   struct prefix *prefix;
249   struct binding *nextTagBinding;                 249   struct binding *nextTagBinding;
250   struct binding *prevPrefixBinding;              250   struct binding *prevPrefixBinding;
251   const struct attribute_id *attId;               251   const struct attribute_id *attId;
252   XML_Char *uri;                                  252   XML_Char *uri;
253   int uriLen;                                     253   int uriLen;
254   int uriAlloc;                                   254   int uriAlloc;
255 } BINDING;                                        255 } BINDING;
256                                                   256 
257 typedef struct prefix {                           257 typedef struct prefix {
258   const XML_Char *name;                           258   const XML_Char *name;
259   BINDING *binding;                               259   BINDING *binding;
260 } PREFIX;                                         260 } PREFIX;
261                                                   261 
262 typedef struct {                                  262 typedef struct {
263   const XML_Char *str;                            263   const XML_Char *str;
264   const XML_Char *localPart;                      264   const XML_Char *localPart;
265   const XML_Char *prefix;                         265   const XML_Char *prefix;
266   int strLen;                                     266   int strLen;
267   int uriLen;                                     267   int uriLen;
268   int prefixLen;                                  268   int prefixLen;
269 } TAG_NAME;                                       269 } TAG_NAME;
270                                                   270 
271 /* TAG represents an open element.                271 /* TAG represents an open element.
272    The name of the element is stored in both t    272    The name of the element is stored in both the document and API
273    encodings.  The memory buffer 'buf' is a se    273    encodings.  The memory buffer 'buf' is a separately-allocated
274    memory area which stores the name.  During     274    memory area which stores the name.  During the XML_Parse()/
275    XMLParseBuffer() when the element is open,     275    XMLParseBuffer() when the element is open, the memory for the 'raw'
276    version of the name (in the document encodi    276    version of the name (in the document encoding) is shared with the
277    document buffer.  If the element is open ac    277    document buffer.  If the element is open across calls to
278    XML_Parse()/XML_ParseBuffer(), the buffer i    278    XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
279    contain the 'raw' name as well.                279    contain the 'raw' name as well.
280                                                   280 
281    A parser re-uses these structures, maintain    281    A parser re-uses these structures, maintaining a list of allocated
282    TAG objects in a free list.                    282    TAG objects in a free list.
283 */                                                283 */
284 typedef struct tag {                              284 typedef struct tag {
285   struct tag *parent;  /* parent of this eleme    285   struct tag *parent;  /* parent of this element */
286   const char *rawName; /* tagName in the origi    286   const char *rawName; /* tagName in the original encoding */
287   int rawNameLength;                              287   int rawNameLength;
288   TAG_NAME name; /* tagName in the API encodin    288   TAG_NAME name; /* tagName in the API encoding */
289   char *buf;     /* buffer for name components    289   char *buf;     /* buffer for name components */
290   char *bufEnd;  /* end of the buffer */          290   char *bufEnd;  /* end of the buffer */
291   BINDING *bindings;                              291   BINDING *bindings;
292 } TAG;                                            292 } TAG;
293                                                   293 
294 typedef struct {                                  294 typedef struct {
295   const XML_Char *name;                           295   const XML_Char *name;
296   const XML_Char *textPtr;                        296   const XML_Char *textPtr;
297   int textLen;   /* length in XML_Chars */        297   int textLen;   /* length in XML_Chars */
298   int processed; /* # of processed bytes - whe    298   int processed; /* # of processed bytes - when suspended */
299   const XML_Char *systemId;                       299   const XML_Char *systemId;
300   const XML_Char *base;                           300   const XML_Char *base;
301   const XML_Char *publicId;                       301   const XML_Char *publicId;
302   const XML_Char *notation;                       302   const XML_Char *notation;
303   XML_Bool open;                                  303   XML_Bool open;
304   XML_Bool is_param;                              304   XML_Bool is_param;
305   XML_Bool is_internal; /* true if declared in    305   XML_Bool is_internal; /* true if declared in internal subset outside PE */
306 } ENTITY;                                         306 } ENTITY;
307                                                   307 
308 typedef struct {                                  308 typedef struct {
309   enum XML_Content_Type type;                     309   enum XML_Content_Type type;
310   enum XML_Content_Quant quant;                   310   enum XML_Content_Quant quant;
311   const XML_Char *name;                           311   const XML_Char *name;
312   int firstchild;                                 312   int firstchild;
313   int lastchild;                                  313   int lastchild;
314   int childcnt;                                   314   int childcnt;
315   int nextsib;                                    315   int nextsib;
316 } CONTENT_SCAFFOLD;                               316 } CONTENT_SCAFFOLD;
317                                                   317 
318 #define INIT_SCAFFOLD_ELEMENTS 32                 318 #define INIT_SCAFFOLD_ELEMENTS 32
319                                                   319 
320 typedef struct block {                            320 typedef struct block {
321   struct block *next;                             321   struct block *next;
322   int size;                                       322   int size;
323   XML_Char s[1];                                  323   XML_Char s[1];
324 } BLOCK;                                          324 } BLOCK;
325                                                   325 
326 typedef struct {                                  326 typedef struct {
327   BLOCK *blocks;                                  327   BLOCK *blocks;
328   BLOCK *freeBlocks;                              328   BLOCK *freeBlocks;
329   const XML_Char *end;                            329   const XML_Char *end;
330   XML_Char *ptr;                                  330   XML_Char *ptr;
331   XML_Char *start;                                331   XML_Char *start;
332   const XML_Memory_Handling_Suite *mem;           332   const XML_Memory_Handling_Suite *mem;
333 } STRING_POOL;                                    333 } STRING_POOL;
334                                                   334 
335 /* The XML_Char before the name is used to det    335 /* The XML_Char before the name is used to determine whether
336    an attribute has been specified. */            336    an attribute has been specified. */
337 typedef struct attribute_id {                     337 typedef struct attribute_id {
338   XML_Char *name;                                 338   XML_Char *name;
339   PREFIX *prefix;                                 339   PREFIX *prefix;
340   XML_Bool maybeTokenized;                        340   XML_Bool maybeTokenized;
341   XML_Bool xmlns;                                 341   XML_Bool xmlns;
342 } ATTRIBUTE_ID;                                   342 } ATTRIBUTE_ID;
343                                                   343 
344 typedef struct {                                  344 typedef struct {
345   const ATTRIBUTE_ID *id;                         345   const ATTRIBUTE_ID *id;
346   XML_Bool isCdata;                               346   XML_Bool isCdata;
347   const XML_Char *value;                          347   const XML_Char *value;
348 } DEFAULT_ATTRIBUTE;                              348 } DEFAULT_ATTRIBUTE;
349                                                   349 
350 typedef struct {                                  350 typedef struct {
351   unsigned long version;                          351   unsigned long version;
352   unsigned long hash;                             352   unsigned long hash;
353   const XML_Char *uriName;                        353   const XML_Char *uriName;
354 } NS_ATT;                                         354 } NS_ATT;
355                                                   355 
356 typedef struct {                                  356 typedef struct {
357   const XML_Char *name;                           357   const XML_Char *name;
358   PREFIX *prefix;                                 358   PREFIX *prefix;
359   const ATTRIBUTE_ID *idAtt;                      359   const ATTRIBUTE_ID *idAtt;
360   int nDefaultAtts;                               360   int nDefaultAtts;
361   int allocDefaultAtts;                           361   int allocDefaultAtts;
362   DEFAULT_ATTRIBUTE *defaultAtts;                 362   DEFAULT_ATTRIBUTE *defaultAtts;
363 } ELEMENT_TYPE;                                   363 } ELEMENT_TYPE;
364                                                   364 
365 typedef struct {                                  365 typedef struct {
366   HASH_TABLE generalEntities;                     366   HASH_TABLE generalEntities;
367   HASH_TABLE elementTypes;                        367   HASH_TABLE elementTypes;
368   HASH_TABLE attributeIds;                        368   HASH_TABLE attributeIds;
369   HASH_TABLE prefixes;                            369   HASH_TABLE prefixes;
370   STRING_POOL pool;                               370   STRING_POOL pool;
371   STRING_POOL entityValuePool;                    371   STRING_POOL entityValuePool;
372   /* false once a parameter entity reference h    372   /* false once a parameter entity reference has been skipped */
373   XML_Bool keepProcessing;                        373   XML_Bool keepProcessing;
374   /* true once an internal or external PE refe    374   /* true once an internal or external PE reference has been encountered;
375      this includes the reference to an externa    375      this includes the reference to an external subset */
376   XML_Bool hasParamEntityRefs;                    376   XML_Bool hasParamEntityRefs;
377   XML_Bool standalone;                            377   XML_Bool standalone;
378 #ifdef XML_DTD                                    378 #ifdef XML_DTD
379   /* indicates if external PE has been read */    379   /* indicates if external PE has been read */
380   XML_Bool paramEntityRead;                       380   XML_Bool paramEntityRead;
381   HASH_TABLE paramEntities;                       381   HASH_TABLE paramEntities;
382 #endif /* XML_DTD */                              382 #endif /* XML_DTD */
383   PREFIX defaultPrefix;                           383   PREFIX defaultPrefix;
384   /* === scaffolding for building content mode    384   /* === scaffolding for building content model === */
385   XML_Bool in_eldecl;                             385   XML_Bool in_eldecl;
386   CONTENT_SCAFFOLD *scaffold;                     386   CONTENT_SCAFFOLD *scaffold;
387   unsigned contentStringLen;                      387   unsigned contentStringLen;
388   unsigned scaffSize;                             388   unsigned scaffSize;
389   unsigned scaffCount;                            389   unsigned scaffCount;
390   int scaffLevel;                                 390   int scaffLevel;
391   int *scaffIndex;                                391   int *scaffIndex;
392 } DTD;                                            392 } DTD;
393                                                   393 
394 typedef struct open_internal_entity {             394 typedef struct open_internal_entity {
395   const char *internalEventPtr;                   395   const char *internalEventPtr;
396   const char *internalEventEndPtr;                396   const char *internalEventEndPtr;
397   struct open_internal_entity *next;              397   struct open_internal_entity *next;
398   ENTITY *entity;                                 398   ENTITY *entity;
399   int startTagLevel;                              399   int startTagLevel;
400   XML_Bool betweenDecl; /* WFC: PE Between Dec    400   XML_Bool betweenDecl; /* WFC: PE Between Declarations */
401 } OPEN_INTERNAL_ENTITY;                           401 } OPEN_INTERNAL_ENTITY;
402                                                   402 
403 enum XML_Account {                                403 enum XML_Account {
404   XML_ACCOUNT_DIRECT,           /* bytes direc    404   XML_ACCOUNT_DIRECT,           /* bytes directly passed to the Expat parser */
405   XML_ACCOUNT_ENTITY_EXPANSION, /* intermediat    405   XML_ACCOUNT_ENTITY_EXPANSION, /* intermediate bytes produced during entity
406                                    expansion *    406                                    expansion */
407   XML_ACCOUNT_NONE              /* i.e. do not    407   XML_ACCOUNT_NONE              /* i.e. do not account, was accounted already */
408 };                                                408 };
409                                                   409 
410 #ifdef XML_DTD                                    410 #ifdef XML_DTD
411 typedef unsigned long long XmlBigCount;           411 typedef unsigned long long XmlBigCount;
412 typedef struct accounting {                       412 typedef struct accounting {
413   XmlBigCount countBytesDirect;                   413   XmlBigCount countBytesDirect;
414   XmlBigCount countBytesIndirect;                 414   XmlBigCount countBytesIndirect;
415   int debugLevel;                                 415   int debugLevel;
416   float maximumAmplificationFactor; // >=1.0      416   float maximumAmplificationFactor; // >=1.0
417   unsigned long long activationThresholdBytes;    417   unsigned long long activationThresholdBytes;
418 } ACCOUNTING;                                     418 } ACCOUNTING;
419                                                   419 
420 typedef struct entity_stats {                     420 typedef struct entity_stats {
421   unsigned int countEverOpened;                   421   unsigned int countEverOpened;
422   unsigned int currentDepth;                      422   unsigned int currentDepth;
423   unsigned int maximumDepthSeen;                  423   unsigned int maximumDepthSeen;
424   int debugLevel;                                 424   int debugLevel;
425 } ENTITY_STATS;                                   425 } ENTITY_STATS;
426 #endif /* XML_DTD */                              426 #endif /* XML_DTD */
427                                                   427 
428 typedef enum XML_Error PTRCALL Processor(XML_P    428 typedef enum XML_Error PTRCALL Processor(XML_Parser parser, const char *start,
429                                          const    429                                          const char *end, const char **endPtr);
430                                                   430 
431 static Processor prologProcessor;                 431 static Processor prologProcessor;
432 static Processor prologInitProcessor;             432 static Processor prologInitProcessor;
433 static Processor contentProcessor;                433 static Processor contentProcessor;
434 static Processor cdataSectionProcessor;           434 static Processor cdataSectionProcessor;
435 #ifdef XML_DTD                                    435 #ifdef XML_DTD
436 static Processor ignoreSectionProcessor;          436 static Processor ignoreSectionProcessor;
437 static Processor externalParEntProcessor;         437 static Processor externalParEntProcessor;
438 static Processor externalParEntInitProcessor;     438 static Processor externalParEntInitProcessor;
439 static Processor entityValueProcessor;            439 static Processor entityValueProcessor;
440 static Processor entityValueInitProcessor;        440 static Processor entityValueInitProcessor;
441 #endif /* XML_DTD */                              441 #endif /* XML_DTD */
442 static Processor epilogProcessor;                 442 static Processor epilogProcessor;
443 static Processor errorProcessor;                  443 static Processor errorProcessor;
444 static Processor externalEntityInitProcessor;     444 static Processor externalEntityInitProcessor;
445 static Processor externalEntityInitProcessor2;    445 static Processor externalEntityInitProcessor2;
446 static Processor externalEntityInitProcessor3;    446 static Processor externalEntityInitProcessor3;
447 static Processor externalEntityContentProcesso    447 static Processor externalEntityContentProcessor;
448 static Processor internalEntityProcessor;         448 static Processor internalEntityProcessor;
449                                                   449 
450 static enum XML_Error handleUnknownEncoding(XM    450 static enum XML_Error handleUnknownEncoding(XML_Parser parser,
451                                             co    451                                             const XML_Char *encodingName);
452 static enum XML_Error processXmlDecl(XML_Parse    452 static enum XML_Error processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
453                                      const cha    453                                      const char *s, const char *next);
454 static enum XML_Error initializeEncoding(XML_P    454 static enum XML_Error initializeEncoding(XML_Parser parser);
455 static enum XML_Error doProlog(XML_Parser pars    455 static enum XML_Error doProlog(XML_Parser parser, const ENCODING *enc,
456                                const char *s,     456                                const char *s, const char *end, int tok,
457                                const char *nex    457                                const char *next, const char **nextPtr,
458                                XML_Bool haveMo    458                                XML_Bool haveMore, XML_Bool allowClosingDoctype,
459                                enum XML_Accoun    459                                enum XML_Account account);
460 static enum XML_Error processInternalEntity(XM    460 static enum XML_Error processInternalEntity(XML_Parser parser, ENTITY *entity,
461                                             XM    461                                             XML_Bool betweenDecl);
462 static enum XML_Error doContent(XML_Parser par    462 static enum XML_Error doContent(XML_Parser parser, int startTagLevel,
463                                 const ENCODING    463                                 const ENCODING *enc, const char *start,
464                                 const char *en    464                                 const char *end, const char **endPtr,
465                                 XML_Bool haveM    465                                 XML_Bool haveMore, enum XML_Account account);
466 static enum XML_Error doCdataSection(XML_Parse    466 static enum XML_Error doCdataSection(XML_Parser parser, const ENCODING *,
467                                      const cha    467                                      const char **startPtr, const char *end,
468                                      const cha    468                                      const char **nextPtr, XML_Bool haveMore,
469                                      enum XML_    469                                      enum XML_Account account);
470 #ifdef XML_DTD                                    470 #ifdef XML_DTD
471 static enum XML_Error doIgnoreSection(XML_Pars    471 static enum XML_Error doIgnoreSection(XML_Parser parser, const ENCODING *,
472                                       const ch    472                                       const char **startPtr, const char *end,
473                                       const ch    473                                       const char **nextPtr, XML_Bool haveMore);
474 #endif /* XML_DTD */                              474 #endif /* XML_DTD */
475                                                   475 
476 static void freeBindings(XML_Parser parser, BI    476 static void freeBindings(XML_Parser parser, BINDING *bindings);
477 static enum XML_Error storeAtts(XML_Parser par    477 static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *,
478                                 const char *s,    478                                 const char *s, TAG_NAME *tagNamePtr,
479                                 BINDING **bind    479                                 BINDING **bindingsPtr,
480                                 enum XML_Accou    480                                 enum XML_Account account);
481 static enum XML_Error addBinding(XML_Parser pa    481 static enum XML_Error addBinding(XML_Parser parser, PREFIX *prefix,
482                                  const ATTRIBU    482                                  const ATTRIBUTE_ID *attId, const XML_Char *uri,
483                                  BINDING **bin    483                                  BINDING **bindingsPtr);
484 static int defineAttribute(ELEMENT_TYPE *type,    484 static int defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
485                            XML_Bool isId, cons    485                            XML_Bool isId, const XML_Char *dfltValue,
486                            XML_Parser parser);    486                            XML_Parser parser);
487 static enum XML_Error storeAttributeValue(XML_    487 static enum XML_Error storeAttributeValue(XML_Parser parser, const ENCODING *,
488                                           XML_    488                                           XML_Bool isCdata, const char *,
489                                           cons    489                                           const char *, STRING_POOL *,
490                                           enum    490                                           enum XML_Account account);
491 static enum XML_Error appendAttributeValue(XML    491 static enum XML_Error appendAttributeValue(XML_Parser parser, const ENCODING *,
492                                            XML    492                                            XML_Bool isCdata, const char *,
493                                            con    493                                            const char *, STRING_POOL *,
494                                            enu    494                                            enum XML_Account account);
495 static ATTRIBUTE_ID *getAttributeId(XML_Parser    495 static ATTRIBUTE_ID *getAttributeId(XML_Parser parser, const ENCODING *enc,
496                                     const char    496                                     const char *start, const char *end);
497 static int setElementTypePrefix(XML_Parser par    497 static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
498 static enum XML_Error storeEntityValue(XML_Par    498 static enum XML_Error storeEntityValue(XML_Parser parser, const ENCODING *enc,
499                                        const c    499                                        const char *start, const char *end,
500                                        enum XM    500                                        enum XML_Account account);
501 static int reportProcessingInstruction(XML_Par    501 static int reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
502                                        const c    502                                        const char *start, const char *end);
503 static int reportComment(XML_Parser parser, co    503 static int reportComment(XML_Parser parser, const ENCODING *enc,
504                          const char *start, co    504                          const char *start, const char *end);
505 static void reportDefault(XML_Parser parser, c    505 static void reportDefault(XML_Parser parser, const ENCODING *enc,
506                           const char *start, c    506                           const char *start, const char *end);
507                                                   507 
508 static const XML_Char *getContext(XML_Parser p    508 static const XML_Char *getContext(XML_Parser parser);
509 static XML_Bool setContext(XML_Parser parser,     509 static XML_Bool setContext(XML_Parser parser, const XML_Char *context);
510                                                   510 
511 static void FASTCALL normalizePublicId(XML_Cha    511 static void FASTCALL normalizePublicId(XML_Char *s);
512                                                   512 
513 static DTD *dtdCreate(const XML_Memory_Handlin    513 static DTD *dtdCreate(const XML_Memory_Handling_Suite *ms);
514 /* do not call if m_parentParser != NULL */       514 /* do not call if m_parentParser != NULL */
515 static void dtdReset(DTD *p, const XML_Memory_    515 static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
516 static void dtdDestroy(DTD *p, XML_Bool isDocE    516 static void dtdDestroy(DTD *p, XML_Bool isDocEntity,
517                        const XML_Memory_Handli    517                        const XML_Memory_Handling_Suite *ms);
518 static int dtdCopy(XML_Parser oldParser, DTD *    518 static int dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
519                    const XML_Memory_Handling_S    519                    const XML_Memory_Handling_Suite *ms);
520 static int copyEntityTable(XML_Parser oldParse    520 static int copyEntityTable(XML_Parser oldParser, HASH_TABLE *, STRING_POOL *,
521                            const HASH_TABLE *)    521                            const HASH_TABLE *);
522 static NAMED *lookup(XML_Parser parser, HASH_T    522 static NAMED *lookup(XML_Parser parser, HASH_TABLE *table, KEY name,
523                      size_t createSize);          523                      size_t createSize);
524 static void FASTCALL hashTableInit(HASH_TABLE     524 static void FASTCALL hashTableInit(HASH_TABLE *,
525                                    const XML_M    525                                    const XML_Memory_Handling_Suite *ms);
526 static void FASTCALL hashTableClear(HASH_TABLE    526 static void FASTCALL hashTableClear(HASH_TABLE *);
527 static void FASTCALL hashTableDestroy(HASH_TAB    527 static void FASTCALL hashTableDestroy(HASH_TABLE *);
528 static void FASTCALL hashTableIterInit(HASH_TA    528 static void FASTCALL hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
529 static NAMED *FASTCALL hashTableIterNext(HASH_    529 static NAMED *FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
530                                                   530 
531 static void FASTCALL poolInit(STRING_POOL *,      531 static void FASTCALL poolInit(STRING_POOL *,
532                               const XML_Memory    532                               const XML_Memory_Handling_Suite *ms);
533 static void FASTCALL poolClear(STRING_POOL *);    533 static void FASTCALL poolClear(STRING_POOL *);
534 static void FASTCALL poolDestroy(STRING_POOL *    534 static void FASTCALL poolDestroy(STRING_POOL *);
535 static XML_Char *poolAppend(STRING_POOL *pool,    535 static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
536                             const char *ptr, c    536                             const char *ptr, const char *end);
537 static XML_Char *poolStoreString(STRING_POOL *    537 static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
538                                  const char *p    538                                  const char *ptr, const char *end);
539 static XML_Bool FASTCALL poolGrow(STRING_POOL     539 static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
540 static const XML_Char *FASTCALL poolCopyString    540 static const XML_Char *FASTCALL poolCopyString(STRING_POOL *pool,
541                                                   541                                                const XML_Char *s);
542 static const XML_Char *poolCopyStringN(STRING_    542 static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s,
543                                        int n);    543                                        int n);
544 static const XML_Char *FASTCALL poolAppendStri    544 static const XML_Char *FASTCALL poolAppendString(STRING_POOL *pool,
545                                                   545                                                  const XML_Char *s);
546                                                   546 
547 static int FASTCALL nextScaffoldPart(XML_Parse    547 static int FASTCALL nextScaffoldPart(XML_Parser parser);
548 static XML_Content *build_model(XML_Parser par    548 static XML_Content *build_model(XML_Parser parser);
549 static ELEMENT_TYPE *getElementType(XML_Parser    549 static ELEMENT_TYPE *getElementType(XML_Parser parser, const ENCODING *enc,
550                                     const char    550                                     const char *ptr, const char *end);
551                                                   551 
552 static XML_Char *copyString(const XML_Char *s,    552 static XML_Char *copyString(const XML_Char *s,
553                             const XML_Memory_H    553                             const XML_Memory_Handling_Suite *memsuite);
554                                                   554 
555 static unsigned long generate_hash_secret_salt    555 static unsigned long generate_hash_secret_salt(XML_Parser parser);
556 static XML_Bool startParsing(XML_Parser parser    556 static XML_Bool startParsing(XML_Parser parser);
557                                                   557 
558 static XML_Parser parserCreate(const XML_Char     558 static XML_Parser parserCreate(const XML_Char *encodingName,
559                                const XML_Memor    559                                const XML_Memory_Handling_Suite *memsuite,
560                                const XML_Char     560                                const XML_Char *nameSep, DTD *dtd);
561                                                   561 
562 static void parserInit(XML_Parser parser, cons    562 static void parserInit(XML_Parser parser, const XML_Char *encodingName);
563                                                   563 
564 #ifdef XML_DTD                                    564 #ifdef XML_DTD
565 static float accountingGetCurrentAmplification    565 static float accountingGetCurrentAmplification(XML_Parser rootParser);
566 static void accountingReportStats(XML_Parser o    566 static void accountingReportStats(XML_Parser originParser, const char *epilog);
567 static void accountingOnAbort(XML_Parser origi    567 static void accountingOnAbort(XML_Parser originParser);
568 static void accountingReportDiff(XML_Parser ro    568 static void accountingReportDiff(XML_Parser rootParser,
569                                  unsigned int     569                                  unsigned int levelsAwayFromRootParser,
570                                  const char *b    570                                  const char *before, const char *after,
571                                  ptrdiff_t byt    571                                  ptrdiff_t bytesMore, int source_line,
572                                  enum XML_Acco    572                                  enum XML_Account account);
573 static XML_Bool accountingDiffTolerated(XML_Pa    573 static XML_Bool accountingDiffTolerated(XML_Parser originParser, int tok,
574                                         const     574                                         const char *before, const char *after,
575                                         int so    575                                         int source_line,
576                                         enum X    576                                         enum XML_Account account);
577                                                   577 
578 static void entityTrackingReportStats(XML_Pars    578 static void entityTrackingReportStats(XML_Parser parser, ENTITY *entity,
579                                       const ch    579                                       const char *action, int sourceLine);
580 static void entityTrackingOnOpen(XML_Parser pa    580 static void entityTrackingOnOpen(XML_Parser parser, ENTITY *entity,
581                                  int sourceLin    581                                  int sourceLine);
582 static void entityTrackingOnClose(XML_Parser p    582 static void entityTrackingOnClose(XML_Parser parser, ENTITY *entity,
583                                   int sourceLi    583                                   int sourceLine);
584                                                   584 
585 static XML_Parser getRootParserOf(XML_Parser p    585 static XML_Parser getRootParserOf(XML_Parser parser,
586                                   unsigned int    586                                   unsigned int *outLevelDiff);
587 #endif /* XML_DTD */                              587 #endif /* XML_DTD */
588                                                   588 
589 static unsigned long getDebugLevel(const char     589 static unsigned long getDebugLevel(const char *variableName,
590                                    unsigned lo    590                                    unsigned long defaultDebugLevel);
591                                                   591 
592 #define poolStart(pool) ((pool)->start)           592 #define poolStart(pool) ((pool)->start)
593 #define poolEnd(pool) ((pool)->ptr)               593 #define poolEnd(pool) ((pool)->ptr)
594 #define poolLength(pool) ((pool)->ptr - (pool)    594 #define poolLength(pool) ((pool)->ptr - (pool)->start)
595 #define poolChop(pool) ((void)--(pool->ptr))      595 #define poolChop(pool) ((void)--(pool->ptr))
596 #define poolLastChar(pool) (((pool)->ptr)[-1])    596 #define poolLastChar(pool) (((pool)->ptr)[-1])
597 #define poolDiscard(pool) ((pool)->ptr = (pool    597 #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
598 #define poolFinish(pool) ((pool)->start = (poo    598 #define poolFinish(pool) ((pool)->start = (pool)->ptr)
599 #define poolAppendChar(pool, c)                   599 #define poolAppendChar(pool, c)                                                \
600   (((pool)->ptr == (pool)->end && ! poolGrow(p    600   (((pool)->ptr == (pool)->end && ! poolGrow(pool))                            \
601        ? 0                                        601        ? 0                                                                     \
602        : ((*((pool)->ptr)++ = c), 1))             602        : ((*((pool)->ptr)++ = c), 1))
603                                                   603 
604 struct XML_ParserStruct {                         604 struct XML_ParserStruct {
605   /* The first member must be m_userData so th    605   /* The first member must be m_userData so that the XML_GetUserData
606      macro works. */                              606      macro works. */
607   void *m_userData;                               607   void *m_userData;
608   void *m_handlerArg;                             608   void *m_handlerArg;
609   char *m_buffer;                                 609   char *m_buffer;
610   const XML_Memory_Handling_Suite m_mem;          610   const XML_Memory_Handling_Suite m_mem;
611   /* first character to be parsed */              611   /* first character to be parsed */
612   const char *m_bufferPtr;                        612   const char *m_bufferPtr;
613   /* past last character to be parsed */          613   /* past last character to be parsed */
614   char *m_bufferEnd;                              614   char *m_bufferEnd;
615   /* allocated end of m_buffer */                 615   /* allocated end of m_buffer */
616   const char *m_bufferLim;                        616   const char *m_bufferLim;
617   XML_Index m_parseEndByteIndex;                  617   XML_Index m_parseEndByteIndex;
618   const char *m_parseEndPtr;                      618   const char *m_parseEndPtr;
619   XML_Char *m_dataBuf;                            619   XML_Char *m_dataBuf;
620   XML_Char *m_dataBufEnd;                         620   XML_Char *m_dataBufEnd;
621   XML_StartElementHandler m_startElementHandle    621   XML_StartElementHandler m_startElementHandler;
622   XML_EndElementHandler m_endElementHandler;      622   XML_EndElementHandler m_endElementHandler;
623   XML_CharacterDataHandler m_characterDataHand    623   XML_CharacterDataHandler m_characterDataHandler;
624   XML_ProcessingInstructionHandler m_processin    624   XML_ProcessingInstructionHandler m_processingInstructionHandler;
625   XML_CommentHandler m_commentHandler;            625   XML_CommentHandler m_commentHandler;
626   XML_StartCdataSectionHandler m_startCdataSec    626   XML_StartCdataSectionHandler m_startCdataSectionHandler;
627   XML_EndCdataSectionHandler m_endCdataSection    627   XML_EndCdataSectionHandler m_endCdataSectionHandler;
628   XML_DefaultHandler m_defaultHandler;            628   XML_DefaultHandler m_defaultHandler;
629   XML_StartDoctypeDeclHandler m_startDoctypeDe    629   XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
630   XML_EndDoctypeDeclHandler m_endDoctypeDeclHa    630   XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
631   XML_UnparsedEntityDeclHandler m_unparsedEnti    631   XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
632   XML_NotationDeclHandler m_notationDeclHandle    632   XML_NotationDeclHandler m_notationDeclHandler;
633   XML_StartNamespaceDeclHandler m_startNamespa    633   XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
634   XML_EndNamespaceDeclHandler m_endNamespaceDe    634   XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
635   XML_NotStandaloneHandler m_notStandaloneHand    635   XML_NotStandaloneHandler m_notStandaloneHandler;
636   XML_ExternalEntityRefHandler m_externalEntit    636   XML_ExternalEntityRefHandler m_externalEntityRefHandler;
637   XML_Parser m_externalEntityRefHandlerArg;       637   XML_Parser m_externalEntityRefHandlerArg;
638   XML_SkippedEntityHandler m_skippedEntityHand    638   XML_SkippedEntityHandler m_skippedEntityHandler;
639   XML_UnknownEncodingHandler m_unknownEncoding    639   XML_UnknownEncodingHandler m_unknownEncodingHandler;
640   XML_ElementDeclHandler m_elementDeclHandler;    640   XML_ElementDeclHandler m_elementDeclHandler;
641   XML_AttlistDeclHandler m_attlistDeclHandler;    641   XML_AttlistDeclHandler m_attlistDeclHandler;
642   XML_EntityDeclHandler m_entityDeclHandler;      642   XML_EntityDeclHandler m_entityDeclHandler;
643   XML_XmlDeclHandler m_xmlDeclHandler;            643   XML_XmlDeclHandler m_xmlDeclHandler;
644   const ENCODING *m_encoding;                     644   const ENCODING *m_encoding;
645   INIT_ENCODING m_initEncoding;                   645   INIT_ENCODING m_initEncoding;
646   const ENCODING *m_internalEncoding;             646   const ENCODING *m_internalEncoding;
647   const XML_Char *m_protocolEncodingName;         647   const XML_Char *m_protocolEncodingName;
648   XML_Bool m_ns;                                  648   XML_Bool m_ns;
649   XML_Bool m_ns_triplets;                         649   XML_Bool m_ns_triplets;
650   void *m_unknownEncodingMem;                     650   void *m_unknownEncodingMem;
651   void *m_unknownEncodingData;                    651   void *m_unknownEncodingData;
652   void *m_unknownEncodingHandlerData;             652   void *m_unknownEncodingHandlerData;
653   void(XMLCALL *m_unknownEncodingRelease)(void    653   void(XMLCALL *m_unknownEncodingRelease)(void *);
654   PROLOG_STATE m_prologState;                     654   PROLOG_STATE m_prologState;
655   Processor *m_processor;                         655   Processor *m_processor;
656   enum XML_Error m_errorCode;                     656   enum XML_Error m_errorCode;
657   const char *m_eventPtr;                         657   const char *m_eventPtr;
658   const char *m_eventEndPtr;                      658   const char *m_eventEndPtr;
659   const char *m_positionPtr;                      659   const char *m_positionPtr;
660   OPEN_INTERNAL_ENTITY *m_openInternalEntities    660   OPEN_INTERNAL_ENTITY *m_openInternalEntities;
661   OPEN_INTERNAL_ENTITY *m_freeInternalEntities    661   OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
662   XML_Bool m_defaultExpandInternalEntities;       662   XML_Bool m_defaultExpandInternalEntities;
663   int m_tagLevel;                                 663   int m_tagLevel;
664   ENTITY *m_declEntity;                           664   ENTITY *m_declEntity;
665   const XML_Char *m_doctypeName;                  665   const XML_Char *m_doctypeName;
666   const XML_Char *m_doctypeSysid;                 666   const XML_Char *m_doctypeSysid;
667   const XML_Char *m_doctypePubid;                 667   const XML_Char *m_doctypePubid;
668   const XML_Char *m_declAttributeType;            668   const XML_Char *m_declAttributeType;
669   const XML_Char *m_declNotationName;             669   const XML_Char *m_declNotationName;
670   const XML_Char *m_declNotationPublicId;         670   const XML_Char *m_declNotationPublicId;
671   ELEMENT_TYPE *m_declElementType;                671   ELEMENT_TYPE *m_declElementType;
672   ATTRIBUTE_ID *m_declAttributeId;                672   ATTRIBUTE_ID *m_declAttributeId;
673   XML_Bool m_declAttributeIsCdata;                673   XML_Bool m_declAttributeIsCdata;
674   XML_Bool m_declAttributeIsId;                   674   XML_Bool m_declAttributeIsId;
675   DTD *m_dtd;                                     675   DTD *m_dtd;
676   const XML_Char *m_curBase;                      676   const XML_Char *m_curBase;
677   TAG *m_tagStack;                                677   TAG *m_tagStack;
678   TAG *m_freeTagList;                             678   TAG *m_freeTagList;
679   BINDING *m_inheritedBindings;                   679   BINDING *m_inheritedBindings;
680   BINDING *m_freeBindingList;                     680   BINDING *m_freeBindingList;
681   int m_attsSize;                                 681   int m_attsSize;
682   int m_nSpecifiedAtts;                           682   int m_nSpecifiedAtts;
683   int m_idAttIndex;                               683   int m_idAttIndex;
684   ATTRIBUTE *m_atts;                              684   ATTRIBUTE *m_atts;
685   NS_ATT *m_nsAtts;                               685   NS_ATT *m_nsAtts;
686   unsigned long m_nsAttsVersion;                  686   unsigned long m_nsAttsVersion;
687   unsigned char m_nsAttsPower;                    687   unsigned char m_nsAttsPower;
688 #ifdef XML_ATTR_INFO                              688 #ifdef XML_ATTR_INFO
689   XML_AttrInfo *m_attInfo;                        689   XML_AttrInfo *m_attInfo;
690 #endif                                            690 #endif
691   POSITION m_position;                            691   POSITION m_position;
692   STRING_POOL m_tempPool;                         692   STRING_POOL m_tempPool;
693   STRING_POOL m_temp2Pool;                        693   STRING_POOL m_temp2Pool;
694   char *m_groupConnector;                         694   char *m_groupConnector;
695   unsigned int m_groupSize;                       695   unsigned int m_groupSize;
696   XML_Char m_namespaceSeparator;                  696   XML_Char m_namespaceSeparator;
697   XML_Parser m_parentParser;                      697   XML_Parser m_parentParser;
698   XML_ParsingStatus m_parsingStatus;              698   XML_ParsingStatus m_parsingStatus;
699 #ifdef XML_DTD                                    699 #ifdef XML_DTD
700   XML_Bool m_isParamEntity;                       700   XML_Bool m_isParamEntity;
701   XML_Bool m_useForeignDTD;                       701   XML_Bool m_useForeignDTD;
702   enum XML_ParamEntityParsing m_paramEntityPar    702   enum XML_ParamEntityParsing m_paramEntityParsing;
703 #endif                                            703 #endif
704   unsigned long m_hash_secret_salt;               704   unsigned long m_hash_secret_salt;
705 #ifdef XML_DTD                                    705 #ifdef XML_DTD
706   ACCOUNTING m_accounting;                        706   ACCOUNTING m_accounting;
707   ENTITY_STATS m_entity_stats;                    707   ENTITY_STATS m_entity_stats;
708 #endif                                            708 #endif
709 };                                                709 };
710                                                   710 
711 #define MALLOC(parser, s) (parser->m_mem.mallo    711 #define MALLOC(parser, s) (parser->m_mem.malloc_fcn((s)))
712 #define REALLOC(parser, p, s) (parser->m_mem.r    712 #define REALLOC(parser, p, s) (parser->m_mem.realloc_fcn((p), (s)))
713 #define FREE(parser, p) (parser->m_mem.free_fc    713 #define FREE(parser, p) (parser->m_mem.free_fcn((p)))
714                                                   714 
715 XML_Parser XMLCALL                                715 XML_Parser XMLCALL
716 XML_ParserCreate(const XML_Char *encodingName)    716 XML_ParserCreate(const XML_Char *encodingName) {
717   return XML_ParserCreate_MM(encodingName, NUL    717   return XML_ParserCreate_MM(encodingName, NULL, NULL);
718 }                                                 718 }
719                                                   719 
720 XML_Parser XMLCALL                                720 XML_Parser XMLCALL
721 XML_ParserCreateNS(const XML_Char *encodingNam    721 XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) {
722   XML_Char tmp[2] = {nsSep, 0};                   722   XML_Char tmp[2] = {nsSep, 0};
723   return XML_ParserCreate_MM(encodingName, NUL    723   return XML_ParserCreate_MM(encodingName, NULL, tmp);
724 }                                                 724 }
725                                                   725 
726 // "xml=http://www.w3.org/XML/1998/namespace"     726 // "xml=http://www.w3.org/XML/1998/namespace"
727 static const XML_Char implicitContext[]           727 static const XML_Char implicitContext[]
728     = {ASCII_x,     ASCII_m,     ASCII_l,         728     = {ASCII_x,     ASCII_m,     ASCII_l,      ASCII_EQUALS, ASCII_h,
729        ASCII_t,     ASCII_t,     ASCII_p,         729        ASCII_t,     ASCII_t,     ASCII_p,      ASCII_COLON,  ASCII_SLASH,
730        ASCII_SLASH, ASCII_w,     ASCII_w,         730        ASCII_SLASH, ASCII_w,     ASCII_w,      ASCII_w,      ASCII_PERIOD,
731        ASCII_w,     ASCII_3,     ASCII_PERIOD,    731        ASCII_w,     ASCII_3,     ASCII_PERIOD, ASCII_o,      ASCII_r,
732        ASCII_g,     ASCII_SLASH, ASCII_X,         732        ASCII_g,     ASCII_SLASH, ASCII_X,      ASCII_M,      ASCII_L,
733        ASCII_SLASH, ASCII_1,     ASCII_9,         733        ASCII_SLASH, ASCII_1,     ASCII_9,      ASCII_9,      ASCII_8,
734        ASCII_SLASH, ASCII_n,     ASCII_a,         734        ASCII_SLASH, ASCII_n,     ASCII_a,      ASCII_m,      ASCII_e,
735        ASCII_s,     ASCII_p,     ASCII_a,         735        ASCII_s,     ASCII_p,     ASCII_a,      ASCII_c,      ASCII_e,
736        '\0'};                                     736        '\0'};
737                                                   737 
738 /* To avoid warnings about unused functions: *    738 /* To avoid warnings about unused functions: */
739 #if ! defined(HAVE_ARC4RANDOM_BUF) && ! define    739 #if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM)
740                                                   740 
741 #  if defined(HAVE_GETRANDOM) || defined(HAVE_    741 #  if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
742                                                   742 
743 /* Obtain entropy on Linux 3.17+ */               743 /* Obtain entropy on Linux 3.17+ */
744 static int                                        744 static int
745 writeRandomBytes_getrandom_nonblock(void *targ    745 writeRandomBytes_getrandom_nonblock(void *target, size_t count) {
746   int success = 0; /* full count bytes written    746   int success = 0; /* full count bytes written? */
747   size_t bytesWrittenTotal = 0;                   747   size_t bytesWrittenTotal = 0;
748   const unsigned int getrandomFlags = GRND_NON    748   const unsigned int getrandomFlags = GRND_NONBLOCK;
749                                                   749 
750   do {                                            750   do {
751     void *const currentTarget = (void *)((char    751     void *const currentTarget = (void *)((char *)target + bytesWrittenTotal);
752     const size_t bytesToWrite = count - bytesW    752     const size_t bytesToWrite = count - bytesWrittenTotal;
753                                                   753 
754     const int bytesWrittenMore =                  754     const int bytesWrittenMore =
755 #    if defined(HAVE_GETRANDOM)                   755 #    if defined(HAVE_GETRANDOM)
756         getrandom(currentTarget, bytesToWrite,    756         getrandom(currentTarget, bytesToWrite, getrandomFlags);
757 #    else                                         757 #    else
758         syscall(SYS_getrandom, currentTarget,     758         syscall(SYS_getrandom, currentTarget, bytesToWrite, getrandomFlags);
759 #    endif                                        759 #    endif
760                                                   760 
761     if (bytesWrittenMore > 0) {                   761     if (bytesWrittenMore > 0) {
762       bytesWrittenTotal += bytesWrittenMore;      762       bytesWrittenTotal += bytesWrittenMore;
763       if (bytesWrittenTotal >= count)             763       if (bytesWrittenTotal >= count)
764         success = 1;                              764         success = 1;
765     }                                             765     }
766   } while (! success && (errno == EINTR));        766   } while (! success && (errno == EINTR));
767                                                   767 
768   return success;                                 768   return success;
769 }                                                 769 }
770                                                   770 
771 #  endif /* defined(HAVE_GETRANDOM) || defined    771 #  endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */
772                                                   772 
773 #  if ! defined(_WIN32) && defined(XML_DEV_URA    773 #  if ! defined(_WIN32) && defined(XML_DEV_URANDOM)
774                                                   774 
775 /* Extract entropy from /dev/urandom */           775 /* Extract entropy from /dev/urandom */
776 static int                                        776 static int
777 writeRandomBytes_dev_urandom(void *target, siz    777 writeRandomBytes_dev_urandom(void *target, size_t count) {
778   int success = 0; /* full count bytes written    778   int success = 0; /* full count bytes written? */
779   size_t bytesWrittenTotal = 0;                   779   size_t bytesWrittenTotal = 0;
780                                                   780 
781   const int fd = open("/dev/urandom", O_RDONLY    781   const int fd = open("/dev/urandom", O_RDONLY);
782   if (fd < 0) {                                   782   if (fd < 0) {
783     return 0;                                     783     return 0;
784   }                                               784   }
785                                                   785 
786   do {                                            786   do {
787     void *const currentTarget = (void *)((char    787     void *const currentTarget = (void *)((char *)target + bytesWrittenTotal);
788     const size_t bytesToWrite = count - bytesW    788     const size_t bytesToWrite = count - bytesWrittenTotal;
789                                                   789 
790     const ssize_t bytesWrittenMore = read(fd,     790     const ssize_t bytesWrittenMore = read(fd, currentTarget, bytesToWrite);
791                                                   791 
792     if (bytesWrittenMore > 0) {                   792     if (bytesWrittenMore > 0) {
793       bytesWrittenTotal += bytesWrittenMore;      793       bytesWrittenTotal += bytesWrittenMore;
794       if (bytesWrittenTotal >= count)             794       if (bytesWrittenTotal >= count)
795         success = 1;                              795         success = 1;
796     }                                             796     }
797   } while (! success && (errno == EINTR));        797   } while (! success && (errno == EINTR));
798                                                   798 
799   close(fd);                                      799   close(fd);
800   return success;                                 800   return success;
801 }                                                 801 }
802                                                   802 
803 #  endif /* ! defined(_WIN32) && defined(XML_D    803 #  endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */
804                                                   804 
805 #endif /* ! defined(HAVE_ARC4RANDOM_BUF) && !     805 #endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */
806                                                   806 
807 #if defined(HAVE_ARC4RANDOM) && ! defined(HAVE    807 #if defined(HAVE_ARC4RANDOM) && ! defined(HAVE_ARC4RANDOM_BUF)
808                                                   808 
809 static void                                       809 static void
810 writeRandomBytes_arc4random(void *target, size    810 writeRandomBytes_arc4random(void *target, size_t count) {
811   size_t bytesWrittenTotal = 0;                   811   size_t bytesWrittenTotal = 0;
812                                                   812 
813   while (bytesWrittenTotal < count) {             813   while (bytesWrittenTotal < count) {
814     const uint32_t random32 = arc4random();       814     const uint32_t random32 = arc4random();
815     size_t i = 0;                                 815     size_t i = 0;
816                                                   816 
817     for (; (i < sizeof(random32)) && (bytesWri    817     for (; (i < sizeof(random32)) && (bytesWrittenTotal < count);
818          i++, bytesWrittenTotal++) {              818          i++, bytesWrittenTotal++) {
819       const uint8_t random8 = (uint8_t)(random    819       const uint8_t random8 = (uint8_t)(random32 >> (i * 8));
820       ((uint8_t *)target)[bytesWrittenTotal] =    820       ((uint8_t *)target)[bytesWrittenTotal] = random8;
821     }                                             821     }
822   }                                               822   }
823 }                                                 823 }
824                                                   824 
825 #endif /* defined(HAVE_ARC4RANDOM) && ! define    825 #endif /* defined(HAVE_ARC4RANDOM) && ! defined(HAVE_ARC4RANDOM_BUF) */
826                                                   826 
827 #ifdef _WIN32                                     827 #ifdef _WIN32
828                                                   828 
829 /* Provide declaration of rand_s() for MinGW-3    829 /* Provide declaration of rand_s() for MinGW-32 (not 64, which has it),
830    as it didn't declare it in its header prior    830    as it didn't declare it in its header prior to version 5.3.0 of its
831    runtime package (mingwrt, containing stdlib    831    runtime package (mingwrt, containing stdlib.h).  The upstream fix
832    was introduced at https://osdn.net/projects    832    was introduced at https://osdn.net/projects/mingw/ticket/39658 . */
833 #  if defined(__MINGW32__) && defined(__MINGW3    833 #  if defined(__MINGW32__) && defined(__MINGW32_VERSION)                       \
834       && __MINGW32_VERSION < 5003000L && ! def    834       && __MINGW32_VERSION < 5003000L && ! defined(__MINGW64_VERSION_MAJOR)
835 __declspec(dllimport) int rand_s(unsigned int     835 __declspec(dllimport) int rand_s(unsigned int *);
836 #  endif                                          836 #  endif
837                                                   837 
838 /* Obtain entropy on Windows using the rand_s(    838 /* Obtain entropy on Windows using the rand_s() function which
839  * generates cryptographically secure random n    839  * generates cryptographically secure random numbers.  Internally it
840  * uses RtlGenRandom API which is present in W    840  * uses RtlGenRandom API which is present in Windows XP and later.
841  */                                               841  */
842 static int                                        842 static int
843 writeRandomBytes_rand_s(void *target, size_t c    843 writeRandomBytes_rand_s(void *target, size_t count) {
844   size_t bytesWrittenTotal = 0;                   844   size_t bytesWrittenTotal = 0;
845                                                   845 
846   while (bytesWrittenTotal < count) {             846   while (bytesWrittenTotal < count) {
847     unsigned int random32 = 0;                    847     unsigned int random32 = 0;
848     size_t i = 0;                                 848     size_t i = 0;
849                                                   849 
850     if (rand_s(&random32))                        850     if (rand_s(&random32))
851       return 0; /* failure */                     851       return 0; /* failure */
852                                                   852 
853     for (; (i < sizeof(random32)) && (bytesWri    853     for (; (i < sizeof(random32)) && (bytesWrittenTotal < count);
854          i++, bytesWrittenTotal++) {              854          i++, bytesWrittenTotal++) {
855       const uint8_t random8 = (uint8_t)(random    855       const uint8_t random8 = (uint8_t)(random32 >> (i * 8));
856       ((uint8_t *)target)[bytesWrittenTotal] =    856       ((uint8_t *)target)[bytesWrittenTotal] = random8;
857     }                                             857     }
858   }                                               858   }
859   return 1; /* success */                         859   return 1; /* success */
860 }                                                 860 }
861                                                   861 
862 #endif /* _WIN32 */                               862 #endif /* _WIN32 */
863                                                   863 
864 #if ! defined(HAVE_ARC4RANDOM_BUF) && ! define    864 #if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM)
865                                                   865 
866 static unsigned long                              866 static unsigned long
867 gather_time_entropy(void) {                       867 gather_time_entropy(void) {
868 #  ifdef _WIN32                                   868 #  ifdef _WIN32
869   FILETIME ft;                                    869   FILETIME ft;
870   GetSystemTimeAsFileTime(&ft); /* never fails    870   GetSystemTimeAsFileTime(&ft); /* never fails */
871   return ft.dwHighDateTime ^ ft.dwLowDateTime;    871   return ft.dwHighDateTime ^ ft.dwLowDateTime;
872 #  else                                           872 #  else
873   struct timeval tv;                              873   struct timeval tv;
874   int gettimeofday_res;                           874   int gettimeofday_res;
875                                                   875 
876   gettimeofday_res = gettimeofday(&tv, NULL);     876   gettimeofday_res = gettimeofday(&tv, NULL);
877                                                   877 
878 #    if defined(NDEBUG)                           878 #    if defined(NDEBUG)
879   (void)gettimeofday_res;                         879   (void)gettimeofday_res;
880 #    else                                         880 #    else
881   assert(gettimeofday_res == 0);                  881   assert(gettimeofday_res == 0);
882 #    endif /* defined(NDEBUG) */                  882 #    endif /* defined(NDEBUG) */
883                                                   883 
884   /* Microseconds time is <20 bits entropy */     884   /* Microseconds time is <20 bits entropy */
885   return tv.tv_usec;                              885   return tv.tv_usec;
886 #  endif                                          886 #  endif
887 }                                                 887 }
888                                                   888 
889 #endif /* ! defined(HAVE_ARC4RANDOM_BUF) && !     889 #endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */
890                                                   890 
891 static unsigned long                              891 static unsigned long
892 ENTROPY_DEBUG(const char *label, unsigned long    892 ENTROPY_DEBUG(const char *label, unsigned long entropy) {
893   if (getDebugLevel("EXPAT_ENTROPY_DEBUG", 0)     893   if (getDebugLevel("EXPAT_ENTROPY_DEBUG", 0) >= 1u) {
894     fprintf(stderr, "expat: Entropy: %s --> 0x    894     fprintf(stderr, "expat: Entropy: %s --> 0x%0*lx (%lu bytes)\n", label,
895             (int)sizeof(entropy) * 2, entropy,    895             (int)sizeof(entropy) * 2, entropy, (unsigned long)sizeof(entropy));
896   }                                               896   }
897   return entropy;                                 897   return entropy;
898 }                                                 898 }
899                                                   899 
900 static unsigned long                              900 static unsigned long
901 generate_hash_secret_salt(XML_Parser parser) {    901 generate_hash_secret_salt(XML_Parser parser) {
902   unsigned long entropy;                          902   unsigned long entropy;
903   (void)parser;                                   903   (void)parser;
904                                                   904 
905   /* "Failproof" high quality providers: */       905   /* "Failproof" high quality providers: */
906 #if defined(HAVE_ARC4RANDOM_BUF)                  906 #if defined(HAVE_ARC4RANDOM_BUF)
907   arc4random_buf(&entropy, sizeof(entropy));      907   arc4random_buf(&entropy, sizeof(entropy));
908   return ENTROPY_DEBUG("arc4random_buf", entro    908   return ENTROPY_DEBUG("arc4random_buf", entropy);
909 #elif defined(HAVE_ARC4RANDOM)                    909 #elif defined(HAVE_ARC4RANDOM)
910   writeRandomBytes_arc4random((void *)&entropy    910   writeRandomBytes_arc4random((void *)&entropy, sizeof(entropy));
911   return ENTROPY_DEBUG("arc4random", entropy);    911   return ENTROPY_DEBUG("arc4random", entropy);
912 #else                                             912 #else
913   /* Try high quality providers first .. */       913   /* Try high quality providers first .. */
914 #  ifdef _WIN32                                   914 #  ifdef _WIN32
915   if (writeRandomBytes_rand_s((void *)&entropy    915   if (writeRandomBytes_rand_s((void *)&entropy, sizeof(entropy))) {
916     return ENTROPY_DEBUG("rand_s", entropy);      916     return ENTROPY_DEBUG("rand_s", entropy);
917   }                                               917   }
918 #  elif defined(HAVE_GETRANDOM) || defined(HAV    918 #  elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
919   if (writeRandomBytes_getrandom_nonblock((voi    919   if (writeRandomBytes_getrandom_nonblock((void *)&entropy, sizeof(entropy))) {
920     return ENTROPY_DEBUG("getrandom", entropy)    920     return ENTROPY_DEBUG("getrandom", entropy);
921   }                                               921   }
922 #  endif                                          922 #  endif
923 #  if ! defined(_WIN32) && defined(XML_DEV_URA    923 #  if ! defined(_WIN32) && defined(XML_DEV_URANDOM)
924   if (writeRandomBytes_dev_urandom((void *)&en    924   if (writeRandomBytes_dev_urandom((void *)&entropy, sizeof(entropy))) {
925     return ENTROPY_DEBUG("/dev/urandom", entro    925     return ENTROPY_DEBUG("/dev/urandom", entropy);
926   }                                               926   }
927 #  endif /* ! defined(_WIN32) && defined(XML_D    927 #  endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */
928   /* .. and self-made low quality for backup:     928   /* .. and self-made low quality for backup: */
929                                                   929 
930   /* Process ID is 0 bits entropy if attacker     930   /* Process ID is 0 bits entropy if attacker has local access */
931   entropy = gather_time_entropy() ^ getpid();     931   entropy = gather_time_entropy() ^ getpid();
932                                                   932 
933   /* Factors are 2^31-1 and 2^61-1 (Mersenne p    933   /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */
934   if (sizeof(unsigned long) == 4) {               934   if (sizeof(unsigned long) == 4) {
935     return ENTROPY_DEBUG("fallback(4)", entrop    935     return ENTROPY_DEBUG("fallback(4)", entropy * 2147483647);
936   } else {                                        936   } else {
937     return ENTROPY_DEBUG("fallback(8)",           937     return ENTROPY_DEBUG("fallback(8)",
938                          entropy * (unsigned l    938                          entropy * (unsigned long)2305843009213693951ULL);
939   }                                               939   }
940 #endif                                            940 #endif
941 }                                                 941 }
942                                                   942 
943 static unsigned long                              943 static unsigned long
944 get_hash_secret_salt(XML_Parser parser) {         944 get_hash_secret_salt(XML_Parser parser) {
945   if (parser->m_parentParser != NULL)             945   if (parser->m_parentParser != NULL)
946     return get_hash_secret_salt(parser->m_pare    946     return get_hash_secret_salt(parser->m_parentParser);
947   return parser->m_hash_secret_salt;              947   return parser->m_hash_secret_salt;
948 }                                                 948 }
949                                                   949 
950 static XML_Bool /* only valid for root parser     950 static XML_Bool /* only valid for root parser */
951 startParsing(XML_Parser parser) {                 951 startParsing(XML_Parser parser) {
952   /* hash functions must be initialized before    952   /* hash functions must be initialized before setContext() is called */
953   if (parser->m_hash_secret_salt == 0)            953   if (parser->m_hash_secret_salt == 0)
954     parser->m_hash_secret_salt = generate_hash    954     parser->m_hash_secret_salt = generate_hash_secret_salt(parser);
955   if (parser->m_ns) {                             955   if (parser->m_ns) {
956     /* implicit context only set for root pars    956     /* implicit context only set for root parser, since child
957        parsers (i.e. external entity parsers)     957        parsers (i.e. external entity parsers) will inherit it
958     */                                            958     */
959     return setContext(parser, implicitContext)    959     return setContext(parser, implicitContext);
960   }                                               960   }
961   return XML_TRUE;                                961   return XML_TRUE;
962 }                                                 962 }
963                                                   963 
964 XML_Parser XMLCALL                                964 XML_Parser XMLCALL
965 XML_ParserCreate_MM(const XML_Char *encodingNa    965 XML_ParserCreate_MM(const XML_Char *encodingName,
966                     const XML_Memory_Handling_    966                     const XML_Memory_Handling_Suite *memsuite,
967                     const XML_Char *nameSep) {    967                     const XML_Char *nameSep) {
968   return parserCreate(encodingName, memsuite,     968   return parserCreate(encodingName, memsuite, nameSep, NULL);
969 }                                                 969 }
970                                                   970 
971 static XML_Parser                                 971 static XML_Parser
972 parserCreate(const XML_Char *encodingName,        972 parserCreate(const XML_Char *encodingName,
973              const XML_Memory_Handling_Suite *    973              const XML_Memory_Handling_Suite *memsuite, const XML_Char *nameSep,
974              DTD *dtd) {                          974              DTD *dtd) {
975   XML_Parser parser;                              975   XML_Parser parser;
976                                                   976 
977   if (memsuite) {                                 977   if (memsuite) {
978     XML_Memory_Handling_Suite *mtemp;             978     XML_Memory_Handling_Suite *mtemp;
979     parser = memsuite->malloc_fcn(sizeof(struc    979     parser = memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
980     if (parser != NULL) {                         980     if (parser != NULL) {
981       mtemp = (XML_Memory_Handling_Suite *)&(p    981       mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
982       mtemp->malloc_fcn = memsuite->malloc_fcn    982       mtemp->malloc_fcn = memsuite->malloc_fcn;
983       mtemp->realloc_fcn = memsuite->realloc_f    983       mtemp->realloc_fcn = memsuite->realloc_fcn;
984       mtemp->free_fcn = memsuite->free_fcn;       984       mtemp->free_fcn = memsuite->free_fcn;
985     }                                             985     }
986   } else {                                        986   } else {
987     XML_Memory_Handling_Suite *mtemp;             987     XML_Memory_Handling_Suite *mtemp;
988     parser = (XML_Parser)malloc(sizeof(struct     988     parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
989     if (parser != NULL) {                         989     if (parser != NULL) {
990       mtemp = (XML_Memory_Handling_Suite *)&(p    990       mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
991       mtemp->malloc_fcn = malloc;                 991       mtemp->malloc_fcn = malloc;
992       mtemp->realloc_fcn = realloc;               992       mtemp->realloc_fcn = realloc;
993       mtemp->free_fcn = free;                     993       mtemp->free_fcn = free;
994     }                                             994     }
995   }                                               995   }
996                                                   996 
997   if (! parser)                                   997   if (! parser)
998     return parser;                                998     return parser;
999                                                   999 
1000   parser->m_buffer = NULL;                       1000   parser->m_buffer = NULL;
1001   parser->m_bufferLim = NULL;                    1001   parser->m_bufferLim = NULL;
1002                                                  1002 
1003   parser->m_attsSize = INIT_ATTS_SIZE;           1003   parser->m_attsSize = INIT_ATTS_SIZE;
1004   parser->m_atts                                 1004   parser->m_atts
1005       = (ATTRIBUTE *)MALLOC(parser, parser->m    1005       = (ATTRIBUTE *)MALLOC(parser, parser->m_attsSize * sizeof(ATTRIBUTE));
1006   if (parser->m_atts == NULL) {                  1006   if (parser->m_atts == NULL) {
1007     FREE(parser, parser);                        1007     FREE(parser, parser);
1008     return NULL;                                 1008     return NULL;
1009   }                                              1009   }
1010 #ifdef XML_ATTR_INFO                             1010 #ifdef XML_ATTR_INFO
1011   parser->m_attInfo = (XML_AttrInfo *)MALLOC(    1011   parser->m_attInfo = (XML_AttrInfo *)MALLOC(
1012       parser, parser->m_attsSize * sizeof(XML    1012       parser, parser->m_attsSize * sizeof(XML_AttrInfo));
1013   if (parser->m_attInfo == NULL) {               1013   if (parser->m_attInfo == NULL) {
1014     FREE(parser, parser->m_atts);                1014     FREE(parser, parser->m_atts);
1015     FREE(parser, parser);                        1015     FREE(parser, parser);
1016     return NULL;                                 1016     return NULL;
1017   }                                              1017   }
1018 #endif                                           1018 #endif
1019   parser->m_dataBuf                              1019   parser->m_dataBuf
1020       = (XML_Char *)MALLOC(parser, INIT_DATA_    1020       = (XML_Char *)MALLOC(parser, INIT_DATA_BUF_SIZE * sizeof(XML_Char));
1021   if (parser->m_dataBuf == NULL) {               1021   if (parser->m_dataBuf == NULL) {
1022     FREE(parser, parser->m_atts);                1022     FREE(parser, parser->m_atts);
1023 #ifdef XML_ATTR_INFO                             1023 #ifdef XML_ATTR_INFO
1024     FREE(parser, parser->m_attInfo);             1024     FREE(parser, parser->m_attInfo);
1025 #endif                                           1025 #endif
1026     FREE(parser, parser);                        1026     FREE(parser, parser);
1027     return NULL;                                 1027     return NULL;
1028   }                                              1028   }
1029   parser->m_dataBufEnd = parser->m_dataBuf +     1029   parser->m_dataBufEnd = parser->m_dataBuf + INIT_DATA_BUF_SIZE;
1030                                                  1030 
1031   if (dtd)                                       1031   if (dtd)
1032     parser->m_dtd = dtd;                         1032     parser->m_dtd = dtd;
1033   else {                                         1033   else {
1034     parser->m_dtd = dtdCreate(&parser->m_mem)    1034     parser->m_dtd = dtdCreate(&parser->m_mem);
1035     if (parser->m_dtd == NULL) {                 1035     if (parser->m_dtd == NULL) {
1036       FREE(parser, parser->m_dataBuf);           1036       FREE(parser, parser->m_dataBuf);
1037       FREE(parser, parser->m_atts);              1037       FREE(parser, parser->m_atts);
1038 #ifdef XML_ATTR_INFO                             1038 #ifdef XML_ATTR_INFO
1039       FREE(parser, parser->m_attInfo);           1039       FREE(parser, parser->m_attInfo);
1040 #endif                                           1040 #endif
1041       FREE(parser, parser);                      1041       FREE(parser, parser);
1042       return NULL;                               1042       return NULL;
1043     }                                            1043     }
1044   }                                              1044   }
1045                                                  1045 
1046   parser->m_freeBindingList = NULL;              1046   parser->m_freeBindingList = NULL;
1047   parser->m_freeTagList = NULL;                  1047   parser->m_freeTagList = NULL;
1048   parser->m_freeInternalEntities = NULL;         1048   parser->m_freeInternalEntities = NULL;
1049                                                  1049 
1050   parser->m_groupSize = 0;                       1050   parser->m_groupSize = 0;
1051   parser->m_groupConnector = NULL;               1051   parser->m_groupConnector = NULL;
1052                                                  1052 
1053   parser->m_unknownEncodingHandler = NULL;       1053   parser->m_unknownEncodingHandler = NULL;
1054   parser->m_unknownEncodingHandlerData = NULL    1054   parser->m_unknownEncodingHandlerData = NULL;
1055                                                  1055 
1056   parser->m_namespaceSeparator = ASCII_EXCL;     1056   parser->m_namespaceSeparator = ASCII_EXCL;
1057   parser->m_ns = XML_FALSE;                      1057   parser->m_ns = XML_FALSE;
1058   parser->m_ns_triplets = XML_FALSE;             1058   parser->m_ns_triplets = XML_FALSE;
1059                                                  1059 
1060   parser->m_nsAtts = NULL;                       1060   parser->m_nsAtts = NULL;
1061   parser->m_nsAttsVersion = 0;                   1061   parser->m_nsAttsVersion = 0;
1062   parser->m_nsAttsPower = 0;                     1062   parser->m_nsAttsPower = 0;
1063                                                  1063 
1064   parser->m_protocolEncodingName = NULL;         1064   parser->m_protocolEncodingName = NULL;
1065                                                  1065 
1066   poolInit(&parser->m_tempPool, &(parser->m_m    1066   poolInit(&parser->m_tempPool, &(parser->m_mem));
1067   poolInit(&parser->m_temp2Pool, &(parser->m_    1067   poolInit(&parser->m_temp2Pool, &(parser->m_mem));
1068   parserInit(parser, encodingName);              1068   parserInit(parser, encodingName);
1069                                                  1069 
1070   if (encodingName && ! parser->m_protocolEnc    1070   if (encodingName && ! parser->m_protocolEncodingName) {
1071     XML_ParserFree(parser);                      1071     XML_ParserFree(parser);
1072     return NULL;                                 1072     return NULL;
1073   }                                              1073   }
1074                                                  1074 
1075   if (nameSep) {                                 1075   if (nameSep) {
1076     parser->m_ns = XML_TRUE;                     1076     parser->m_ns = XML_TRUE;
1077     parser->m_internalEncoding = XmlGetIntern    1077     parser->m_internalEncoding = XmlGetInternalEncodingNS();
1078     parser->m_namespaceSeparator = *nameSep;     1078     parser->m_namespaceSeparator = *nameSep;
1079   } else {                                       1079   } else {
1080     parser->m_internalEncoding = XmlGetIntern    1080     parser->m_internalEncoding = XmlGetInternalEncoding();
1081   }                                              1081   }
1082                                                  1082 
1083   return parser;                                 1083   return parser;
1084 }                                                1084 }
1085                                                  1085 
1086 static void                                      1086 static void
1087 parserInit(XML_Parser parser, const XML_Char     1087 parserInit(XML_Parser parser, const XML_Char *encodingName) {
1088   parser->m_processor = prologInitProcessor;     1088   parser->m_processor = prologInitProcessor;
1089   XmlPrologStateInit(&parser->m_prologState);    1089   XmlPrologStateInit(&parser->m_prologState);
1090   if (encodingName != NULL) {                    1090   if (encodingName != NULL) {
1091     parser->m_protocolEncodingName = copyStri    1091     parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem));
1092   }                                              1092   }
1093   parser->m_curBase = NULL;                      1093   parser->m_curBase = NULL;
1094   XmlInitEncoding(&parser->m_initEncoding, &p    1094   XmlInitEncoding(&parser->m_initEncoding, &parser->m_encoding, 0);
1095   parser->m_userData = NULL;                     1095   parser->m_userData = NULL;
1096   parser->m_handlerArg = NULL;                   1096   parser->m_handlerArg = NULL;
1097   parser->m_startElementHandler = NULL;          1097   parser->m_startElementHandler = NULL;
1098   parser->m_endElementHandler = NULL;            1098   parser->m_endElementHandler = NULL;
1099   parser->m_characterDataHandler = NULL;         1099   parser->m_characterDataHandler = NULL;
1100   parser->m_processingInstructionHandler = NU    1100   parser->m_processingInstructionHandler = NULL;
1101   parser->m_commentHandler = NULL;               1101   parser->m_commentHandler = NULL;
1102   parser->m_startCdataSectionHandler = NULL;     1102   parser->m_startCdataSectionHandler = NULL;
1103   parser->m_endCdataSectionHandler = NULL;       1103   parser->m_endCdataSectionHandler = NULL;
1104   parser->m_defaultHandler = NULL;               1104   parser->m_defaultHandler = NULL;
1105   parser->m_startDoctypeDeclHandler = NULL;      1105   parser->m_startDoctypeDeclHandler = NULL;
1106   parser->m_endDoctypeDeclHandler = NULL;        1106   parser->m_endDoctypeDeclHandler = NULL;
1107   parser->m_unparsedEntityDeclHandler = NULL;    1107   parser->m_unparsedEntityDeclHandler = NULL;
1108   parser->m_notationDeclHandler = NULL;          1108   parser->m_notationDeclHandler = NULL;
1109   parser->m_startNamespaceDeclHandler = NULL;    1109   parser->m_startNamespaceDeclHandler = NULL;
1110   parser->m_endNamespaceDeclHandler = NULL;      1110   parser->m_endNamespaceDeclHandler = NULL;
1111   parser->m_notStandaloneHandler = NULL;         1111   parser->m_notStandaloneHandler = NULL;
1112   parser->m_externalEntityRefHandler = NULL;     1112   parser->m_externalEntityRefHandler = NULL;
1113   parser->m_externalEntityRefHandlerArg = par    1113   parser->m_externalEntityRefHandlerArg = parser;
1114   parser->m_skippedEntityHandler = NULL;         1114   parser->m_skippedEntityHandler = NULL;
1115   parser->m_elementDeclHandler = NULL;           1115   parser->m_elementDeclHandler = NULL;
1116   parser->m_attlistDeclHandler = NULL;           1116   parser->m_attlistDeclHandler = NULL;
1117   parser->m_entityDeclHandler = NULL;            1117   parser->m_entityDeclHandler = NULL;
1118   parser->m_xmlDeclHandler = NULL;               1118   parser->m_xmlDeclHandler = NULL;
1119   parser->m_bufferPtr = parser->m_buffer;        1119   parser->m_bufferPtr = parser->m_buffer;
1120   parser->m_bufferEnd = parser->m_buffer;        1120   parser->m_bufferEnd = parser->m_buffer;
1121   parser->m_parseEndByteIndex = 0;               1121   parser->m_parseEndByteIndex = 0;
1122   parser->m_parseEndPtr = NULL;                  1122   parser->m_parseEndPtr = NULL;
1123   parser->m_declElementType = NULL;              1123   parser->m_declElementType = NULL;
1124   parser->m_declAttributeId = NULL;              1124   parser->m_declAttributeId = NULL;
1125   parser->m_declEntity = NULL;                   1125   parser->m_declEntity = NULL;
1126   parser->m_doctypeName = NULL;                  1126   parser->m_doctypeName = NULL;
1127   parser->m_doctypeSysid = NULL;                 1127   parser->m_doctypeSysid = NULL;
1128   parser->m_doctypePubid = NULL;                 1128   parser->m_doctypePubid = NULL;
1129   parser->m_declAttributeType = NULL;            1129   parser->m_declAttributeType = NULL;
1130   parser->m_declNotationName = NULL;             1130   parser->m_declNotationName = NULL;
1131   parser->m_declNotationPublicId = NULL;         1131   parser->m_declNotationPublicId = NULL;
1132   parser->m_declAttributeIsCdata = XML_FALSE;    1132   parser->m_declAttributeIsCdata = XML_FALSE;
1133   parser->m_declAttributeIsId = XML_FALSE;       1133   parser->m_declAttributeIsId = XML_FALSE;
1134   memset(&parser->m_position, 0, sizeof(POSIT    1134   memset(&parser->m_position, 0, sizeof(POSITION));
1135   parser->m_errorCode = XML_ERROR_NONE;          1135   parser->m_errorCode = XML_ERROR_NONE;
1136   parser->m_eventPtr = NULL;                     1136   parser->m_eventPtr = NULL;
1137   parser->m_eventEndPtr = NULL;                  1137   parser->m_eventEndPtr = NULL;
1138   parser->m_positionPtr = NULL;                  1138   parser->m_positionPtr = NULL;
1139   parser->m_openInternalEntities = NULL;         1139   parser->m_openInternalEntities = NULL;
1140   parser->m_defaultExpandInternalEntities = X    1140   parser->m_defaultExpandInternalEntities = XML_TRUE;
1141   parser->m_tagLevel = 0;                        1141   parser->m_tagLevel = 0;
1142   parser->m_tagStack = NULL;                     1142   parser->m_tagStack = NULL;
1143   parser->m_inheritedBindings = NULL;            1143   parser->m_inheritedBindings = NULL;
1144   parser->m_nSpecifiedAtts = 0;                  1144   parser->m_nSpecifiedAtts = 0;
1145   parser->m_unknownEncodingMem = NULL;           1145   parser->m_unknownEncodingMem = NULL;
1146   parser->m_unknownEncodingRelease = NULL;       1146   parser->m_unknownEncodingRelease = NULL;
1147   parser->m_unknownEncodingData = NULL;          1147   parser->m_unknownEncodingData = NULL;
1148   parser->m_parentParser = NULL;                 1148   parser->m_parentParser = NULL;
1149   parser->m_parsingStatus.parsing = XML_INITI    1149   parser->m_parsingStatus.parsing = XML_INITIALIZED;
1150 #ifdef XML_DTD                                   1150 #ifdef XML_DTD
1151   parser->m_isParamEntity = XML_FALSE;           1151   parser->m_isParamEntity = XML_FALSE;
1152   parser->m_useForeignDTD = XML_FALSE;           1152   parser->m_useForeignDTD = XML_FALSE;
1153   parser->m_paramEntityParsing = XML_PARAM_EN    1153   parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
1154 #endif                                           1154 #endif
1155   parser->m_hash_secret_salt = 0;                1155   parser->m_hash_secret_salt = 0;
1156                                                  1156 
1157 #ifdef XML_DTD                                   1157 #ifdef XML_DTD
1158   memset(&parser->m_accounting, 0, sizeof(ACC    1158   memset(&parser->m_accounting, 0, sizeof(ACCOUNTING));
1159   parser->m_accounting.debugLevel = getDebugL    1159   parser->m_accounting.debugLevel = getDebugLevel("EXPAT_ACCOUNTING_DEBUG", 0u);
1160   parser->m_accounting.maximumAmplificationFa    1160   parser->m_accounting.maximumAmplificationFactor
1161       = EXPAT_BILLION_LAUGHS_ATTACK_PROTECTIO    1161       = EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT;
1162   parser->m_accounting.activationThresholdByt    1162   parser->m_accounting.activationThresholdBytes
1163       = EXPAT_BILLION_LAUGHS_ATTACK_PROTECTIO    1163       = EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT;
1164                                                  1164 
1165   memset(&parser->m_entity_stats, 0, sizeof(E    1165   memset(&parser->m_entity_stats, 0, sizeof(ENTITY_STATS));
1166   parser->m_entity_stats.debugLevel = getDebu    1166   parser->m_entity_stats.debugLevel = getDebugLevel("EXPAT_ENTITY_DEBUG", 0u);
1167 #endif                                           1167 #endif
1168 }                                                1168 }
1169                                                  1169 
1170 /* moves list of bindings to m_freeBindingLis    1170 /* moves list of bindings to m_freeBindingList */
1171 static void FASTCALL                             1171 static void FASTCALL
1172 moveToFreeBindingList(XML_Parser parser, BIND    1172 moveToFreeBindingList(XML_Parser parser, BINDING *bindings) {
1173   while (bindings) {                             1173   while (bindings) {
1174     BINDING *b = bindings;                       1174     BINDING *b = bindings;
1175     bindings = bindings->nextTagBinding;         1175     bindings = bindings->nextTagBinding;
1176     b->nextTagBinding = parser->m_freeBinding    1176     b->nextTagBinding = parser->m_freeBindingList;
1177     parser->m_freeBindingList = b;               1177     parser->m_freeBindingList = b;
1178   }                                              1178   }
1179 }                                                1179 }
1180                                                  1180 
1181 XML_Bool XMLCALL                                 1181 XML_Bool XMLCALL
1182 XML_ParserReset(XML_Parser parser, const XML_    1182 XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) {
1183   TAG *tStk;                                     1183   TAG *tStk;
1184   OPEN_INTERNAL_ENTITY *openEntityList;          1184   OPEN_INTERNAL_ENTITY *openEntityList;
1185                                                  1185 
1186   if (parser == NULL)                            1186   if (parser == NULL)
1187     return XML_FALSE;                            1187     return XML_FALSE;
1188                                                  1188 
1189   if (parser->m_parentParser)                    1189   if (parser->m_parentParser)
1190     return XML_FALSE;                            1190     return XML_FALSE;
1191   /* move m_tagStack to m_freeTagList */         1191   /* move m_tagStack to m_freeTagList */
1192   tStk = parser->m_tagStack;                     1192   tStk = parser->m_tagStack;
1193   while (tStk) {                                 1193   while (tStk) {
1194     TAG *tag = tStk;                             1194     TAG *tag = tStk;
1195     tStk = tStk->parent;                         1195     tStk = tStk->parent;
1196     tag->parent = parser->m_freeTagList;         1196     tag->parent = parser->m_freeTagList;
1197     moveToFreeBindingList(parser, tag->bindin    1197     moveToFreeBindingList(parser, tag->bindings);
1198     tag->bindings = NULL;                        1198     tag->bindings = NULL;
1199     parser->m_freeTagList = tag;                 1199     parser->m_freeTagList = tag;
1200   }                                              1200   }
1201   /* move m_openInternalEntities to m_freeInt    1201   /* move m_openInternalEntities to m_freeInternalEntities */
1202   openEntityList = parser->m_openInternalEnti    1202   openEntityList = parser->m_openInternalEntities;
1203   while (openEntityList) {                       1203   while (openEntityList) {
1204     OPEN_INTERNAL_ENTITY *openEntity = openEn    1204     OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
1205     openEntityList = openEntity->next;           1205     openEntityList = openEntity->next;
1206     openEntity->next = parser->m_freeInternal    1206     openEntity->next = parser->m_freeInternalEntities;
1207     parser->m_freeInternalEntities = openEnti    1207     parser->m_freeInternalEntities = openEntity;
1208   }                                              1208   }
1209   moveToFreeBindingList(parser, parser->m_inh    1209   moveToFreeBindingList(parser, parser->m_inheritedBindings);
1210   FREE(parser, parser->m_unknownEncodingMem);    1210   FREE(parser, parser->m_unknownEncodingMem);
1211   if (parser->m_unknownEncodingRelease)          1211   if (parser->m_unknownEncodingRelease)
1212     parser->m_unknownEncodingRelease(parser->    1212     parser->m_unknownEncodingRelease(parser->m_unknownEncodingData);
1213   poolClear(&parser->m_tempPool);                1213   poolClear(&parser->m_tempPool);
1214   poolClear(&parser->m_temp2Pool);               1214   poolClear(&parser->m_temp2Pool);
1215   FREE(parser, (void *)parser->m_protocolEnco    1215   FREE(parser, (void *)parser->m_protocolEncodingName);
1216   parser->m_protocolEncodingName = NULL;         1216   parser->m_protocolEncodingName = NULL;
1217   parserInit(parser, encodingName);              1217   parserInit(parser, encodingName);
1218   dtdReset(parser->m_dtd, &parser->m_mem);       1218   dtdReset(parser->m_dtd, &parser->m_mem);
1219   return XML_TRUE;                               1219   return XML_TRUE;
1220 }                                                1220 }
1221                                                  1221 
1222 enum XML_Status XMLCALL                          1222 enum XML_Status XMLCALL
1223 XML_SetEncoding(XML_Parser parser, const XML_    1223 XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) {
1224   if (parser == NULL)                            1224   if (parser == NULL)
1225     return XML_STATUS_ERROR;                     1225     return XML_STATUS_ERROR;
1226   /* Block after XML_Parse()/XML_ParseBuffer(    1226   /* Block after XML_Parse()/XML_ParseBuffer() has been called.
1227      XXX There's no way for the caller to det    1227      XXX There's no way for the caller to determine which of the
1228      XXX possible error cases caused the XML_    1228      XXX possible error cases caused the XML_STATUS_ERROR return.
1229   */                                             1229   */
1230   if (parser->m_parsingStatus.parsing == XML_    1230   if (parser->m_parsingStatus.parsing == XML_PARSING
1231       || parser->m_parsingStatus.parsing == X    1231       || parser->m_parsingStatus.parsing == XML_SUSPENDED)
1232     return XML_STATUS_ERROR;                     1232     return XML_STATUS_ERROR;
1233                                                  1233 
1234   /* Get rid of any previous encoding name */    1234   /* Get rid of any previous encoding name */
1235   FREE(parser, (void *)parser->m_protocolEnco    1235   FREE(parser, (void *)parser->m_protocolEncodingName);
1236                                                  1236 
1237   if (encodingName == NULL)                      1237   if (encodingName == NULL)
1238     /* No new encoding name */                   1238     /* No new encoding name */
1239     parser->m_protocolEncodingName = NULL;       1239     parser->m_protocolEncodingName = NULL;
1240   else {                                         1240   else {
1241     /* Copy the new encoding name into alloca    1241     /* Copy the new encoding name into allocated memory */
1242     parser->m_protocolEncodingName = copyStri    1242     parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem));
1243     if (! parser->m_protocolEncodingName)        1243     if (! parser->m_protocolEncodingName)
1244       return XML_STATUS_ERROR;                   1244       return XML_STATUS_ERROR;
1245   }                                              1245   }
1246   return XML_STATUS_OK;                          1246   return XML_STATUS_OK;
1247 }                                                1247 }
1248                                                  1248 
1249 XML_Parser XMLCALL                               1249 XML_Parser XMLCALL
1250 XML_ExternalEntityParserCreate(XML_Parser old    1250 XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context,
1251                                const XML_Char    1251                                const XML_Char *encodingName) {
1252   XML_Parser parser = oldParser;                 1252   XML_Parser parser = oldParser;
1253   DTD *newDtd = NULL;                            1253   DTD *newDtd = NULL;
1254   DTD *oldDtd;                                   1254   DTD *oldDtd;
1255   XML_StartElementHandler oldStartElementHand    1255   XML_StartElementHandler oldStartElementHandler;
1256   XML_EndElementHandler oldEndElementHandler;    1256   XML_EndElementHandler oldEndElementHandler;
1257   XML_CharacterDataHandler oldCharacterDataHa    1257   XML_CharacterDataHandler oldCharacterDataHandler;
1258   XML_ProcessingInstructionHandler oldProcess    1258   XML_ProcessingInstructionHandler oldProcessingInstructionHandler;
1259   XML_CommentHandler oldCommentHandler;          1259   XML_CommentHandler oldCommentHandler;
1260   XML_StartCdataSectionHandler oldStartCdataS    1260   XML_StartCdataSectionHandler oldStartCdataSectionHandler;
1261   XML_EndCdataSectionHandler oldEndCdataSecti    1261   XML_EndCdataSectionHandler oldEndCdataSectionHandler;
1262   XML_DefaultHandler oldDefaultHandler;          1262   XML_DefaultHandler oldDefaultHandler;
1263   XML_UnparsedEntityDeclHandler oldUnparsedEn    1263   XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler;
1264   XML_NotationDeclHandler oldNotationDeclHand    1264   XML_NotationDeclHandler oldNotationDeclHandler;
1265   XML_StartNamespaceDeclHandler oldStartNames    1265   XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler;
1266   XML_EndNamespaceDeclHandler oldEndNamespace    1266   XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler;
1267   XML_NotStandaloneHandler oldNotStandaloneHa    1267   XML_NotStandaloneHandler oldNotStandaloneHandler;
1268   XML_ExternalEntityRefHandler oldExternalEnt    1268   XML_ExternalEntityRefHandler oldExternalEntityRefHandler;
1269   XML_SkippedEntityHandler oldSkippedEntityHa    1269   XML_SkippedEntityHandler oldSkippedEntityHandler;
1270   XML_UnknownEncodingHandler oldUnknownEncodi    1270   XML_UnknownEncodingHandler oldUnknownEncodingHandler;
1271   XML_ElementDeclHandler oldElementDeclHandle    1271   XML_ElementDeclHandler oldElementDeclHandler;
1272   XML_AttlistDeclHandler oldAttlistDeclHandle    1272   XML_AttlistDeclHandler oldAttlistDeclHandler;
1273   XML_EntityDeclHandler oldEntityDeclHandler;    1273   XML_EntityDeclHandler oldEntityDeclHandler;
1274   XML_XmlDeclHandler oldXmlDeclHandler;          1274   XML_XmlDeclHandler oldXmlDeclHandler;
1275   ELEMENT_TYPE *oldDeclElementType;              1275   ELEMENT_TYPE *oldDeclElementType;
1276                                                  1276 
1277   void *oldUserData;                             1277   void *oldUserData;
1278   void *oldHandlerArg;                           1278   void *oldHandlerArg;
1279   XML_Bool oldDefaultExpandInternalEntities;     1279   XML_Bool oldDefaultExpandInternalEntities;
1280   XML_Parser oldExternalEntityRefHandlerArg;     1280   XML_Parser oldExternalEntityRefHandlerArg;
1281 #ifdef XML_DTD                                   1281 #ifdef XML_DTD
1282   enum XML_ParamEntityParsing oldParamEntityP    1282   enum XML_ParamEntityParsing oldParamEntityParsing;
1283   int oldInEntityValue;                          1283   int oldInEntityValue;
1284 #endif                                           1284 #endif
1285   XML_Bool oldns_triplets;                       1285   XML_Bool oldns_triplets;
1286   /* Note that the new parser shares the same    1286   /* Note that the new parser shares the same hash secret as the old
1287      parser, so that dtdCopy and copyEntityTa    1287      parser, so that dtdCopy and copyEntityTable can lookup values
1288      from hash tables associated with either     1288      from hash tables associated with either parser without us having
1289      to worry which hash secrets each table h    1289      to worry which hash secrets each table has.
1290   */                                             1290   */
1291   unsigned long oldhash_secret_salt;             1291   unsigned long oldhash_secret_salt;
1292                                                  1292 
1293   /* Validate the oldParser parameter before     1293   /* Validate the oldParser parameter before we pull everything out of it */
1294   if (oldParser == NULL)                         1294   if (oldParser == NULL)
1295     return NULL;                                 1295     return NULL;
1296                                                  1296 
1297   /* Stash the original parser contents on th    1297   /* Stash the original parser contents on the stack */
1298   oldDtd = parser->m_dtd;                        1298   oldDtd = parser->m_dtd;
1299   oldStartElementHandler = parser->m_startEle    1299   oldStartElementHandler = parser->m_startElementHandler;
1300   oldEndElementHandler = parser->m_endElement    1300   oldEndElementHandler = parser->m_endElementHandler;
1301   oldCharacterDataHandler = parser->m_charact    1301   oldCharacterDataHandler = parser->m_characterDataHandler;
1302   oldProcessingInstructionHandler = parser->m    1302   oldProcessingInstructionHandler = parser->m_processingInstructionHandler;
1303   oldCommentHandler = parser->m_commentHandle    1303   oldCommentHandler = parser->m_commentHandler;
1304   oldStartCdataSectionHandler = parser->m_sta    1304   oldStartCdataSectionHandler = parser->m_startCdataSectionHandler;
1305   oldEndCdataSectionHandler = parser->m_endCd    1305   oldEndCdataSectionHandler = parser->m_endCdataSectionHandler;
1306   oldDefaultHandler = parser->m_defaultHandle    1306   oldDefaultHandler = parser->m_defaultHandler;
1307   oldUnparsedEntityDeclHandler = parser->m_un    1307   oldUnparsedEntityDeclHandler = parser->m_unparsedEntityDeclHandler;
1308   oldNotationDeclHandler = parser->m_notation    1308   oldNotationDeclHandler = parser->m_notationDeclHandler;
1309   oldStartNamespaceDeclHandler = parser->m_st    1309   oldStartNamespaceDeclHandler = parser->m_startNamespaceDeclHandler;
1310   oldEndNamespaceDeclHandler = parser->m_endN    1310   oldEndNamespaceDeclHandler = parser->m_endNamespaceDeclHandler;
1311   oldNotStandaloneHandler = parser->m_notStan    1311   oldNotStandaloneHandler = parser->m_notStandaloneHandler;
1312   oldExternalEntityRefHandler = parser->m_ext    1312   oldExternalEntityRefHandler = parser->m_externalEntityRefHandler;
1313   oldSkippedEntityHandler = parser->m_skipped    1313   oldSkippedEntityHandler = parser->m_skippedEntityHandler;
1314   oldUnknownEncodingHandler = parser->m_unkno    1314   oldUnknownEncodingHandler = parser->m_unknownEncodingHandler;
1315   oldElementDeclHandler = parser->m_elementDe    1315   oldElementDeclHandler = parser->m_elementDeclHandler;
1316   oldAttlistDeclHandler = parser->m_attlistDe    1316   oldAttlistDeclHandler = parser->m_attlistDeclHandler;
1317   oldEntityDeclHandler = parser->m_entityDecl    1317   oldEntityDeclHandler = parser->m_entityDeclHandler;
1318   oldXmlDeclHandler = parser->m_xmlDeclHandle    1318   oldXmlDeclHandler = parser->m_xmlDeclHandler;
1319   oldDeclElementType = parser->m_declElementT    1319   oldDeclElementType = parser->m_declElementType;
1320                                                  1320 
1321   oldUserData = parser->m_userData;              1321   oldUserData = parser->m_userData;
1322   oldHandlerArg = parser->m_handlerArg;          1322   oldHandlerArg = parser->m_handlerArg;
1323   oldDefaultExpandInternalEntities = parser->    1323   oldDefaultExpandInternalEntities = parser->m_defaultExpandInternalEntities;
1324   oldExternalEntityRefHandlerArg = parser->m_    1324   oldExternalEntityRefHandlerArg = parser->m_externalEntityRefHandlerArg;
1325 #ifdef XML_DTD                                   1325 #ifdef XML_DTD
1326   oldParamEntityParsing = parser->m_paramEnti    1326   oldParamEntityParsing = parser->m_paramEntityParsing;
1327   oldInEntityValue = parser->m_prologState.in    1327   oldInEntityValue = parser->m_prologState.inEntityValue;
1328 #endif                                           1328 #endif
1329   oldns_triplets = parser->m_ns_triplets;        1329   oldns_triplets = parser->m_ns_triplets;
1330   /* Note that the new parser shares the same    1330   /* Note that the new parser shares the same hash secret as the old
1331      parser, so that dtdCopy and copyEntityTa    1331      parser, so that dtdCopy and copyEntityTable can lookup values
1332      from hash tables associated with either     1332      from hash tables associated with either parser without us having
1333      to worry which hash secrets each table h    1333      to worry which hash secrets each table has.
1334   */                                             1334   */
1335   oldhash_secret_salt = parser->m_hash_secret    1335   oldhash_secret_salt = parser->m_hash_secret_salt;
1336                                                  1336 
1337 #ifdef XML_DTD                                   1337 #ifdef XML_DTD
1338   if (! context)                                 1338   if (! context)
1339     newDtd = oldDtd;                             1339     newDtd = oldDtd;
1340 #endif /* XML_DTD */                             1340 #endif /* XML_DTD */
1341                                                  1341 
1342   /* Note that the magical uses of the pre-pr    1342   /* Note that the magical uses of the pre-processor to make field
1343      access look more like C++ require that `    1343      access look more like C++ require that `parser' be overwritten
1344      here.  This makes this function more pai    1344      here.  This makes this function more painful to follow than it
1345      would be otherwise.                         1345      would be otherwise.
1346   */                                             1346   */
1347   if (parser->m_ns) {                            1347   if (parser->m_ns) {
1348     XML_Char tmp[2] = {parser->m_namespaceSep    1348     XML_Char tmp[2] = {parser->m_namespaceSeparator, 0};
1349     parser = parserCreate(encodingName, &pars    1349     parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
1350   } else {                                       1350   } else {
1351     parser = parserCreate(encodingName, &pars    1351     parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
1352   }                                              1352   }
1353                                                  1353 
1354   if (! parser)                                  1354   if (! parser)
1355     return NULL;                                 1355     return NULL;
1356                                                  1356 
1357   parser->m_startElementHandler = oldStartEle    1357   parser->m_startElementHandler = oldStartElementHandler;
1358   parser->m_endElementHandler = oldEndElement    1358   parser->m_endElementHandler = oldEndElementHandler;
1359   parser->m_characterDataHandler = oldCharact    1359   parser->m_characterDataHandler = oldCharacterDataHandler;
1360   parser->m_processingInstructionHandler = ol    1360   parser->m_processingInstructionHandler = oldProcessingInstructionHandler;
1361   parser->m_commentHandler = oldCommentHandle    1361   parser->m_commentHandler = oldCommentHandler;
1362   parser->m_startCdataSectionHandler = oldSta    1362   parser->m_startCdataSectionHandler = oldStartCdataSectionHandler;
1363   parser->m_endCdataSectionHandler = oldEndCd    1363   parser->m_endCdataSectionHandler = oldEndCdataSectionHandler;
1364   parser->m_defaultHandler = oldDefaultHandle    1364   parser->m_defaultHandler = oldDefaultHandler;
1365   parser->m_unparsedEntityDeclHandler = oldUn    1365   parser->m_unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
1366   parser->m_notationDeclHandler = oldNotation    1366   parser->m_notationDeclHandler = oldNotationDeclHandler;
1367   parser->m_startNamespaceDeclHandler = oldSt    1367   parser->m_startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
1368   parser->m_endNamespaceDeclHandler = oldEndN    1368   parser->m_endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
1369   parser->m_notStandaloneHandler = oldNotStan    1369   parser->m_notStandaloneHandler = oldNotStandaloneHandler;
1370   parser->m_externalEntityRefHandler = oldExt    1370   parser->m_externalEntityRefHandler = oldExternalEntityRefHandler;
1371   parser->m_skippedEntityHandler = oldSkipped    1371   parser->m_skippedEntityHandler = oldSkippedEntityHandler;
1372   parser->m_unknownEncodingHandler = oldUnkno    1372   parser->m_unknownEncodingHandler = oldUnknownEncodingHandler;
1373   parser->m_elementDeclHandler = oldElementDe    1373   parser->m_elementDeclHandler = oldElementDeclHandler;
1374   parser->m_attlistDeclHandler = oldAttlistDe    1374   parser->m_attlistDeclHandler = oldAttlistDeclHandler;
1375   parser->m_entityDeclHandler = oldEntityDecl    1375   parser->m_entityDeclHandler = oldEntityDeclHandler;
1376   parser->m_xmlDeclHandler = oldXmlDeclHandle    1376   parser->m_xmlDeclHandler = oldXmlDeclHandler;
1377   parser->m_declElementType = oldDeclElementT    1377   parser->m_declElementType = oldDeclElementType;
1378   parser->m_userData = oldUserData;              1378   parser->m_userData = oldUserData;
1379   if (oldUserData == oldHandlerArg)              1379   if (oldUserData == oldHandlerArg)
1380     parser->m_handlerArg = parser->m_userData    1380     parser->m_handlerArg = parser->m_userData;
1381   else                                           1381   else
1382     parser->m_handlerArg = parser;               1382     parser->m_handlerArg = parser;
1383   if (oldExternalEntityRefHandlerArg != oldPa    1383   if (oldExternalEntityRefHandlerArg != oldParser)
1384     parser->m_externalEntityRefHandlerArg = o    1384     parser->m_externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
1385   parser->m_defaultExpandInternalEntities = o    1385   parser->m_defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
1386   parser->m_ns_triplets = oldns_triplets;        1386   parser->m_ns_triplets = oldns_triplets;
1387   parser->m_hash_secret_salt = oldhash_secret    1387   parser->m_hash_secret_salt = oldhash_secret_salt;
1388   parser->m_parentParser = oldParser;            1388   parser->m_parentParser = oldParser;
1389 #ifdef XML_DTD                                   1389 #ifdef XML_DTD
1390   parser->m_paramEntityParsing = oldParamEnti    1390   parser->m_paramEntityParsing = oldParamEntityParsing;
1391   parser->m_prologState.inEntityValue = oldIn    1391   parser->m_prologState.inEntityValue = oldInEntityValue;
1392   if (context) {                                 1392   if (context) {
1393 #endif /* XML_DTD */                             1393 #endif /* XML_DTD */
1394     if (! dtdCopy(oldParser, parser->m_dtd, o    1394     if (! dtdCopy(oldParser, parser->m_dtd, oldDtd, &parser->m_mem)
1395         || ! setContext(parser, context)) {      1395         || ! setContext(parser, context)) {
1396       XML_ParserFree(parser);                    1396       XML_ParserFree(parser);
1397       return NULL;                               1397       return NULL;
1398     }                                            1398     }
1399     parser->m_processor = externalEntityInitP    1399     parser->m_processor = externalEntityInitProcessor;
1400 #ifdef XML_DTD                                   1400 #ifdef XML_DTD
1401   } else {                                       1401   } else {
1402     /* The DTD instance referenced by parser-    1402     /* The DTD instance referenced by parser->m_dtd is shared between the
1403        document's root parser and external PE    1403        document's root parser and external PE parsers, therefore one does not
1404        need to call setContext. In addition,     1404        need to call setContext. In addition, one also *must* not call
1405        setContext, because this would overwri    1405        setContext, because this would overwrite existing prefix->binding
1406        pointers in parser->m_dtd with ones th    1406        pointers in parser->m_dtd with ones that get destroyed with the external
1407        PE parser. This would leave those pref    1407        PE parser. This would leave those prefixes with dangling pointers.
1408     */                                           1408     */
1409     parser->m_isParamEntity = XML_TRUE;          1409     parser->m_isParamEntity = XML_TRUE;
1410     XmlPrologStateInitExternalEntity(&parser-    1410     XmlPrologStateInitExternalEntity(&parser->m_prologState);
1411     parser->m_processor = externalParEntInitP    1411     parser->m_processor = externalParEntInitProcessor;
1412   }                                              1412   }
1413 #endif /* XML_DTD */                             1413 #endif /* XML_DTD */
1414   return parser;                                 1414   return parser;
1415 }                                                1415 }
1416                                                  1416 
1417 static void FASTCALL                             1417 static void FASTCALL
1418 destroyBindings(BINDING *bindings, XML_Parser    1418 destroyBindings(BINDING *bindings, XML_Parser parser) {
1419   for (;;) {                                     1419   for (;;) {
1420     BINDING *b = bindings;                       1420     BINDING *b = bindings;
1421     if (! b)                                     1421     if (! b)
1422       break;                                     1422       break;
1423     bindings = b->nextTagBinding;                1423     bindings = b->nextTagBinding;
1424     FREE(parser, b->uri);                        1424     FREE(parser, b->uri);
1425     FREE(parser, b);                             1425     FREE(parser, b);
1426   }                                              1426   }
1427 }                                                1427 }
1428                                                  1428 
1429 void XMLCALL                                     1429 void XMLCALL
1430 XML_ParserFree(XML_Parser parser) {              1430 XML_ParserFree(XML_Parser parser) {
1431   TAG *tagList;                                  1431   TAG *tagList;
1432   OPEN_INTERNAL_ENTITY *entityList;              1432   OPEN_INTERNAL_ENTITY *entityList;
1433   if (parser == NULL)                            1433   if (parser == NULL)
1434     return;                                      1434     return;
1435   /* free m_tagStack and m_freeTagList */        1435   /* free m_tagStack and m_freeTagList */
1436   tagList = parser->m_tagStack;                  1436   tagList = parser->m_tagStack;
1437   for (;;) {                                     1437   for (;;) {
1438     TAG *p;                                      1438     TAG *p;
1439     if (tagList == NULL) {                       1439     if (tagList == NULL) {
1440       if (parser->m_freeTagList == NULL)         1440       if (parser->m_freeTagList == NULL)
1441         break;                                   1441         break;
1442       tagList = parser->m_freeTagList;           1442       tagList = parser->m_freeTagList;
1443       parser->m_freeTagList = NULL;              1443       parser->m_freeTagList = NULL;
1444     }                                            1444     }
1445     p = tagList;                                 1445     p = tagList;
1446     tagList = tagList->parent;                   1446     tagList = tagList->parent;
1447     FREE(parser, p->buf);                        1447     FREE(parser, p->buf);
1448     destroyBindings(p->bindings, parser);        1448     destroyBindings(p->bindings, parser);
1449     FREE(parser, p);                             1449     FREE(parser, p);
1450   }                                              1450   }
1451   /* free m_openInternalEntities and m_freeIn    1451   /* free m_openInternalEntities and m_freeInternalEntities */
1452   entityList = parser->m_openInternalEntities    1452   entityList = parser->m_openInternalEntities;
1453   for (;;) {                                     1453   for (;;) {
1454     OPEN_INTERNAL_ENTITY *openEntity;            1454     OPEN_INTERNAL_ENTITY *openEntity;
1455     if (entityList == NULL) {                    1455     if (entityList == NULL) {
1456       if (parser->m_freeInternalEntities == N    1456       if (parser->m_freeInternalEntities == NULL)
1457         break;                                   1457         break;
1458       entityList = parser->m_freeInternalEnti    1458       entityList = parser->m_freeInternalEntities;
1459       parser->m_freeInternalEntities = NULL;     1459       parser->m_freeInternalEntities = NULL;
1460     }                                            1460     }
1461     openEntity = entityList;                     1461     openEntity = entityList;
1462     entityList = entityList->next;               1462     entityList = entityList->next;
1463     FREE(parser, openEntity);                    1463     FREE(parser, openEntity);
1464   }                                              1464   }
1465                                                  1465 
1466   destroyBindings(parser->m_freeBindingList,     1466   destroyBindings(parser->m_freeBindingList, parser);
1467   destroyBindings(parser->m_inheritedBindings    1467   destroyBindings(parser->m_inheritedBindings, parser);
1468   poolDestroy(&parser->m_tempPool);              1468   poolDestroy(&parser->m_tempPool);
1469   poolDestroy(&parser->m_temp2Pool);             1469   poolDestroy(&parser->m_temp2Pool);
1470   FREE(parser, (void *)parser->m_protocolEnco    1470   FREE(parser, (void *)parser->m_protocolEncodingName);
1471 #ifdef XML_DTD                                   1471 #ifdef XML_DTD
1472   /* external parameter entity parsers share     1472   /* external parameter entity parsers share the DTD structure
1473      parser->m_dtd with the root parser, so w    1473      parser->m_dtd with the root parser, so we must not destroy it
1474   */                                             1474   */
1475   if (! parser->m_isParamEntity && parser->m_    1475   if (! parser->m_isParamEntity && parser->m_dtd)
1476 #else                                            1476 #else
1477   if (parser->m_dtd)                             1477   if (parser->m_dtd)
1478 #endif /* XML_DTD */                             1478 #endif /* XML_DTD */
1479     dtdDestroy(parser->m_dtd, (XML_Bool)! par    1479     dtdDestroy(parser->m_dtd, (XML_Bool)! parser->m_parentParser,
1480                &parser->m_mem);                  1480                &parser->m_mem);
1481   FREE(parser, (void *)parser->m_atts);          1481   FREE(parser, (void *)parser->m_atts);
1482 #ifdef XML_ATTR_INFO                             1482 #ifdef XML_ATTR_INFO
1483   FREE(parser, (void *)parser->m_attInfo);       1483   FREE(parser, (void *)parser->m_attInfo);
1484 #endif                                           1484 #endif
1485   FREE(parser, parser->m_groupConnector);        1485   FREE(parser, parser->m_groupConnector);
1486   FREE(parser, parser->m_buffer);                1486   FREE(parser, parser->m_buffer);
1487   FREE(parser, parser->m_dataBuf);               1487   FREE(parser, parser->m_dataBuf);
1488   FREE(parser, parser->m_nsAtts);                1488   FREE(parser, parser->m_nsAtts);
1489   FREE(parser, parser->m_unknownEncodingMem);    1489   FREE(parser, parser->m_unknownEncodingMem);
1490   if (parser->m_unknownEncodingRelease)          1490   if (parser->m_unknownEncodingRelease)
1491     parser->m_unknownEncodingRelease(parser->    1491     parser->m_unknownEncodingRelease(parser->m_unknownEncodingData);
1492   FREE(parser, parser);                          1492   FREE(parser, parser);
1493 }                                                1493 }
1494                                                  1494 
1495 void XMLCALL                                     1495 void XMLCALL
1496 XML_UseParserAsHandlerArg(XML_Parser parser)     1496 XML_UseParserAsHandlerArg(XML_Parser parser) {
1497   if (parser != NULL)                            1497   if (parser != NULL)
1498     parser->m_handlerArg = parser;               1498     parser->m_handlerArg = parser;
1499 }                                                1499 }
1500                                                  1500 
1501 enum XML_Error XMLCALL                           1501 enum XML_Error XMLCALL
1502 XML_UseForeignDTD(XML_Parser parser, XML_Bool    1502 XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) {
1503   if (parser == NULL)                            1503   if (parser == NULL)
1504     return XML_ERROR_INVALID_ARGUMENT;           1504     return XML_ERROR_INVALID_ARGUMENT;
1505 #ifdef XML_DTD                                   1505 #ifdef XML_DTD
1506   /* block after XML_Parse()/XML_ParseBuffer(    1506   /* block after XML_Parse()/XML_ParseBuffer() has been called */
1507   if (parser->m_parsingStatus.parsing == XML_    1507   if (parser->m_parsingStatus.parsing == XML_PARSING
1508       || parser->m_parsingStatus.parsing == X    1508       || parser->m_parsingStatus.parsing == XML_SUSPENDED)
1509     return XML_ERROR_CANT_CHANGE_FEATURE_ONCE    1509     return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
1510   parser->m_useForeignDTD = useDTD;              1510   parser->m_useForeignDTD = useDTD;
1511   return XML_ERROR_NONE;                         1511   return XML_ERROR_NONE;
1512 #else                                            1512 #else
1513   UNUSED_P(useDTD);                              1513   UNUSED_P(useDTD);
1514   return XML_ERROR_FEATURE_REQUIRES_XML_DTD;     1514   return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
1515 #endif                                           1515 #endif
1516 }                                                1516 }
1517                                                  1517 
1518 void XMLCALL                                     1518 void XMLCALL
1519 XML_SetReturnNSTriplet(XML_Parser parser, int    1519 XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) {
1520   if (parser == NULL)                            1520   if (parser == NULL)
1521     return;                                      1521     return;
1522   /* block after XML_Parse()/XML_ParseBuffer(    1522   /* block after XML_Parse()/XML_ParseBuffer() has been called */
1523   if (parser->m_parsingStatus.parsing == XML_    1523   if (parser->m_parsingStatus.parsing == XML_PARSING
1524       || parser->m_parsingStatus.parsing == X    1524       || parser->m_parsingStatus.parsing == XML_SUSPENDED)
1525     return;                                      1525     return;
1526   parser->m_ns_triplets = do_nst ? XML_TRUE :    1526   parser->m_ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
1527 }                                                1527 }
1528                                                  1528 
1529 void XMLCALL                                     1529 void XMLCALL
1530 XML_SetUserData(XML_Parser parser, void *p) {    1530 XML_SetUserData(XML_Parser parser, void *p) {
1531   if (parser == NULL)                            1531   if (parser == NULL)
1532     return;                                      1532     return;
1533   if (parser->m_handlerArg == parser->m_userD    1533   if (parser->m_handlerArg == parser->m_userData)
1534     parser->m_handlerArg = parser->m_userData    1534     parser->m_handlerArg = parser->m_userData = p;
1535   else                                           1535   else
1536     parser->m_userData = p;                      1536     parser->m_userData = p;
1537 }                                                1537 }
1538                                                  1538 
1539 enum XML_Status XMLCALL                          1539 enum XML_Status XMLCALL
1540 XML_SetBase(XML_Parser parser, const XML_Char    1540 XML_SetBase(XML_Parser parser, const XML_Char *p) {
1541   if (parser == NULL)                            1541   if (parser == NULL)
1542     return XML_STATUS_ERROR;                     1542     return XML_STATUS_ERROR;
1543   if (p) {                                       1543   if (p) {
1544     p = poolCopyString(&parser->m_dtd->pool,     1544     p = poolCopyString(&parser->m_dtd->pool, p);
1545     if (! p)                                     1545     if (! p)
1546       return XML_STATUS_ERROR;                   1546       return XML_STATUS_ERROR;
1547     parser->m_curBase = p;                       1547     parser->m_curBase = p;
1548   } else                                         1548   } else
1549     parser->m_curBase = NULL;                    1549     parser->m_curBase = NULL;
1550   return XML_STATUS_OK;                          1550   return XML_STATUS_OK;
1551 }                                                1551 }
1552                                                  1552 
1553 const XML_Char *XMLCALL                          1553 const XML_Char *XMLCALL
1554 XML_GetBase(XML_Parser parser) {                 1554 XML_GetBase(XML_Parser parser) {
1555   if (parser == NULL)                            1555   if (parser == NULL)
1556     return NULL;                                 1556     return NULL;
1557   return parser->m_curBase;                      1557   return parser->m_curBase;
1558 }                                                1558 }
1559                                                  1559 
1560 int XMLCALL                                      1560 int XMLCALL
1561 XML_GetSpecifiedAttributeCount(XML_Parser par    1561 XML_GetSpecifiedAttributeCount(XML_Parser parser) {
1562   if (parser == NULL)                            1562   if (parser == NULL)
1563     return -1;                                   1563     return -1;
1564   return parser->m_nSpecifiedAtts;               1564   return parser->m_nSpecifiedAtts;
1565 }                                                1565 }
1566                                                  1566 
1567 int XMLCALL                                      1567 int XMLCALL
1568 XML_GetIdAttributeIndex(XML_Parser parser) {     1568 XML_GetIdAttributeIndex(XML_Parser parser) {
1569   if (parser == NULL)                            1569   if (parser == NULL)
1570     return -1;                                   1570     return -1;
1571   return parser->m_idAttIndex;                   1571   return parser->m_idAttIndex;
1572 }                                                1572 }
1573                                                  1573 
1574 #ifdef XML_ATTR_INFO                             1574 #ifdef XML_ATTR_INFO
1575 const XML_AttrInfo *XMLCALL                      1575 const XML_AttrInfo *XMLCALL
1576 XML_GetAttributeInfo(XML_Parser parser) {        1576 XML_GetAttributeInfo(XML_Parser parser) {
1577   if (parser == NULL)                            1577   if (parser == NULL)
1578     return NULL;                                 1578     return NULL;
1579   return parser->m_attInfo;                      1579   return parser->m_attInfo;
1580 }                                                1580 }
1581 #endif                                           1581 #endif
1582                                                  1582 
1583 void XMLCALL                                     1583 void XMLCALL
1584 XML_SetElementHandler(XML_Parser parser, XML_    1584 XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start,
1585                       XML_EndElementHandler e    1585                       XML_EndElementHandler end) {
1586   if (parser == NULL)                            1586   if (parser == NULL)
1587     return;                                      1587     return;
1588   parser->m_startElementHandler = start;         1588   parser->m_startElementHandler = start;
1589   parser->m_endElementHandler = end;             1589   parser->m_endElementHandler = end;
1590 }                                                1590 }
1591                                                  1591 
1592 void XMLCALL                                     1592 void XMLCALL
1593 XML_SetStartElementHandler(XML_Parser parser,    1593 XML_SetStartElementHandler(XML_Parser parser, XML_StartElementHandler start) {
1594   if (parser != NULL)                            1594   if (parser != NULL)
1595     parser->m_startElementHandler = start;       1595     parser->m_startElementHandler = start;
1596 }                                                1596 }
1597                                                  1597 
1598 void XMLCALL                                     1598 void XMLCALL
1599 XML_SetEndElementHandler(XML_Parser parser, X    1599 XML_SetEndElementHandler(XML_Parser parser, XML_EndElementHandler end) {
1600   if (parser != NULL)                            1600   if (parser != NULL)
1601     parser->m_endElementHandler = end;           1601     parser->m_endElementHandler = end;
1602 }                                                1602 }
1603                                                  1603 
1604 void XMLCALL                                     1604 void XMLCALL
1605 XML_SetCharacterDataHandler(XML_Parser parser    1605 XML_SetCharacterDataHandler(XML_Parser parser,
1606                             XML_CharacterData    1606                             XML_CharacterDataHandler handler) {
1607   if (parser != NULL)                            1607   if (parser != NULL)
1608     parser->m_characterDataHandler = handler;    1608     parser->m_characterDataHandler = handler;
1609 }                                                1609 }
1610                                                  1610 
1611 void XMLCALL                                     1611 void XMLCALL
1612 XML_SetProcessingInstructionHandler(XML_Parse    1612 XML_SetProcessingInstructionHandler(XML_Parser parser,
1613                                     XML_Proce    1613                                     XML_ProcessingInstructionHandler handler) {
1614   if (parser != NULL)                            1614   if (parser != NULL)
1615     parser->m_processingInstructionHandler =     1615     parser->m_processingInstructionHandler = handler;
1616 }                                                1616 }
1617                                                  1617 
1618 void XMLCALL                                     1618 void XMLCALL
1619 XML_SetCommentHandler(XML_Parser parser, XML_    1619 XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler) {
1620   if (parser != NULL)                            1620   if (parser != NULL)
1621     parser->m_commentHandler = handler;          1621     parser->m_commentHandler = handler;
1622 }                                                1622 }
1623                                                  1623 
1624 void XMLCALL                                     1624 void XMLCALL
1625 XML_SetCdataSectionHandler(XML_Parser parser,    1625 XML_SetCdataSectionHandler(XML_Parser parser,
1626                            XML_StartCdataSect    1626                            XML_StartCdataSectionHandler start,
1627                            XML_EndCdataSectio    1627                            XML_EndCdataSectionHandler end) {
1628   if (parser == NULL)                            1628   if (parser == NULL)
1629     return;                                      1629     return;
1630   parser->m_startCdataSectionHandler = start;    1630   parser->m_startCdataSectionHandler = start;
1631   parser->m_endCdataSectionHandler = end;        1631   parser->m_endCdataSectionHandler = end;
1632 }                                                1632 }
1633                                                  1633 
1634 void XMLCALL                                     1634 void XMLCALL
1635 XML_SetStartCdataSectionHandler(XML_Parser pa    1635 XML_SetStartCdataSectionHandler(XML_Parser parser,
1636                                 XML_StartCdat    1636                                 XML_StartCdataSectionHandler start) {
1637   if (parser != NULL)                            1637   if (parser != NULL)
1638     parser->m_startCdataSectionHandler = star    1638     parser->m_startCdataSectionHandler = start;
1639 }                                                1639 }
1640                                                  1640 
1641 void XMLCALL                                     1641 void XMLCALL
1642 XML_SetEndCdataSectionHandler(XML_Parser pars    1642 XML_SetEndCdataSectionHandler(XML_Parser parser,
1643                               XML_EndCdataSec    1643                               XML_EndCdataSectionHandler end) {
1644   if (parser != NULL)                            1644   if (parser != NULL)
1645     parser->m_endCdataSectionHandler = end;      1645     parser->m_endCdataSectionHandler = end;
1646 }                                                1646 }
1647                                                  1647 
1648 void XMLCALL                                     1648 void XMLCALL
1649 XML_SetDefaultHandler(XML_Parser parser, XML_    1649 XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler handler) {
1650   if (parser == NULL)                            1650   if (parser == NULL)
1651     return;                                      1651     return;
1652   parser->m_defaultHandler = handler;            1652   parser->m_defaultHandler = handler;
1653   parser->m_defaultExpandInternalEntities = X    1653   parser->m_defaultExpandInternalEntities = XML_FALSE;
1654 }                                                1654 }
1655                                                  1655 
1656 void XMLCALL                                     1656 void XMLCALL
1657 XML_SetDefaultHandlerExpand(XML_Parser parser    1657 XML_SetDefaultHandlerExpand(XML_Parser parser, XML_DefaultHandler handler) {
1658   if (parser == NULL)                            1658   if (parser == NULL)
1659     return;                                      1659     return;
1660   parser->m_defaultHandler = handler;            1660   parser->m_defaultHandler = handler;
1661   parser->m_defaultExpandInternalEntities = X    1661   parser->m_defaultExpandInternalEntities = XML_TRUE;
1662 }                                                1662 }
1663                                                  1663 
1664 void XMLCALL                                     1664 void XMLCALL
1665 XML_SetDoctypeDeclHandler(XML_Parser parser,     1665 XML_SetDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start,
1666                           XML_EndDoctypeDeclH    1666                           XML_EndDoctypeDeclHandler end) {
1667   if (parser == NULL)                            1667   if (parser == NULL)
1668     return;                                      1668     return;
1669   parser->m_startDoctypeDeclHandler = start;     1669   parser->m_startDoctypeDeclHandler = start;
1670   parser->m_endDoctypeDeclHandler = end;         1670   parser->m_endDoctypeDeclHandler = end;
1671 }                                                1671 }
1672                                                  1672 
1673 void XMLCALL                                     1673 void XMLCALL
1674 XML_SetStartDoctypeDeclHandler(XML_Parser par    1674 XML_SetStartDoctypeDeclHandler(XML_Parser parser,
1675                                XML_StartDocty    1675                                XML_StartDoctypeDeclHandler start) {
1676   if (parser != NULL)                            1676   if (parser != NULL)
1677     parser->m_startDoctypeDeclHandler = start    1677     parser->m_startDoctypeDeclHandler = start;
1678 }                                                1678 }
1679                                                  1679 
1680 void XMLCALL                                     1680 void XMLCALL
1681 XML_SetEndDoctypeDeclHandler(XML_Parser parse    1681 XML_SetEndDoctypeDeclHandler(XML_Parser parser, XML_EndDoctypeDeclHandler end) {
1682   if (parser != NULL)                            1682   if (parser != NULL)
1683     parser->m_endDoctypeDeclHandler = end;       1683     parser->m_endDoctypeDeclHandler = end;
1684 }                                                1684 }
1685                                                  1685 
1686 void XMLCALL                                     1686 void XMLCALL
1687 XML_SetUnparsedEntityDeclHandler(XML_Parser p    1687 XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
1688                                  XML_Unparsed    1688                                  XML_UnparsedEntityDeclHandler handler) {
1689   if (parser != NULL)                            1689   if (parser != NULL)
1690     parser->m_unparsedEntityDeclHandler = han    1690     parser->m_unparsedEntityDeclHandler = handler;
1691 }                                                1691 }
1692                                                  1692 
1693 void XMLCALL                                     1693 void XMLCALL
1694 XML_SetNotationDeclHandler(XML_Parser parser,    1694 XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler) {
1695   if (parser != NULL)                            1695   if (parser != NULL)
1696     parser->m_notationDeclHandler = handler;     1696     parser->m_notationDeclHandler = handler;
1697 }                                                1697 }
1698                                                  1698 
1699 void XMLCALL                                     1699 void XMLCALL
1700 XML_SetNamespaceDeclHandler(XML_Parser parser    1700 XML_SetNamespaceDeclHandler(XML_Parser parser,
1701                             XML_StartNamespac    1701                             XML_StartNamespaceDeclHandler start,
1702                             XML_EndNamespaceD    1702                             XML_EndNamespaceDeclHandler end) {
1703   if (parser == NULL)                            1703   if (parser == NULL)
1704     return;                                      1704     return;
1705   parser->m_startNamespaceDeclHandler = start    1705   parser->m_startNamespaceDeclHandler = start;
1706   parser->m_endNamespaceDeclHandler = end;       1706   parser->m_endNamespaceDeclHandler = end;
1707 }                                                1707 }
1708                                                  1708 
1709 void XMLCALL                                     1709 void XMLCALL
1710 XML_SetStartNamespaceDeclHandler(XML_Parser p    1710 XML_SetStartNamespaceDeclHandler(XML_Parser parser,
1711                                  XML_StartNam    1711                                  XML_StartNamespaceDeclHandler start) {
1712   if (parser != NULL)                            1712   if (parser != NULL)
1713     parser->m_startNamespaceDeclHandler = sta    1713     parser->m_startNamespaceDeclHandler = start;
1714 }                                                1714 }
1715                                                  1715 
1716 void XMLCALL                                     1716 void XMLCALL
1717 XML_SetEndNamespaceDeclHandler(XML_Parser par    1717 XML_SetEndNamespaceDeclHandler(XML_Parser parser,
1718                                XML_EndNamespa    1718                                XML_EndNamespaceDeclHandler end) {
1719   if (parser != NULL)                            1719   if (parser != NULL)
1720     parser->m_endNamespaceDeclHandler = end;     1720     parser->m_endNamespaceDeclHandler = end;
1721 }                                                1721 }
1722                                                  1722 
1723 void XMLCALL                                     1723 void XMLCALL
1724 XML_SetNotStandaloneHandler(XML_Parser parser    1724 XML_SetNotStandaloneHandler(XML_Parser parser,
1725                             XML_NotStandalone    1725                             XML_NotStandaloneHandler handler) {
1726   if (parser != NULL)                            1726   if (parser != NULL)
1727     parser->m_notStandaloneHandler = handler;    1727     parser->m_notStandaloneHandler = handler;
1728 }                                                1728 }
1729                                                  1729 
1730 void XMLCALL                                     1730 void XMLCALL
1731 XML_SetExternalEntityRefHandler(XML_Parser pa    1731 XML_SetExternalEntityRefHandler(XML_Parser parser,
1732                                 XML_ExternalE    1732                                 XML_ExternalEntityRefHandler handler) {
1733   if (parser != NULL)                            1733   if (parser != NULL)
1734     parser->m_externalEntityRefHandler = hand    1734     parser->m_externalEntityRefHandler = handler;
1735 }                                                1735 }
1736                                                  1736 
1737 void XMLCALL                                     1737 void XMLCALL
1738 XML_SetExternalEntityRefHandlerArg(XML_Parser    1738 XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) {
1739   if (parser == NULL)                            1739   if (parser == NULL)
1740     return;                                      1740     return;
1741   if (arg)                                       1741   if (arg)
1742     parser->m_externalEntityRefHandlerArg = (    1742     parser->m_externalEntityRefHandlerArg = (XML_Parser)arg;
1743   else                                           1743   else
1744     parser->m_externalEntityRefHandlerArg = p    1744     parser->m_externalEntityRefHandlerArg = parser;
1745 }                                                1745 }
1746                                                  1746 
1747 void XMLCALL                                     1747 void XMLCALL
1748 XML_SetSkippedEntityHandler(XML_Parser parser    1748 XML_SetSkippedEntityHandler(XML_Parser parser,
1749                             XML_SkippedEntity    1749                             XML_SkippedEntityHandler handler) {
1750   if (parser != NULL)                            1750   if (parser != NULL)
1751     parser->m_skippedEntityHandler = handler;    1751     parser->m_skippedEntityHandler = handler;
1752 }                                                1752 }
1753                                                  1753 
1754 void XMLCALL                                     1754 void XMLCALL
1755 XML_SetUnknownEncodingHandler(XML_Parser pars    1755 XML_SetUnknownEncodingHandler(XML_Parser parser,
1756                               XML_UnknownEnco    1756                               XML_UnknownEncodingHandler handler, void *data) {
1757   if (parser == NULL)                            1757   if (parser == NULL)
1758     return;                                      1758     return;
1759   parser->m_unknownEncodingHandler = handler;    1759   parser->m_unknownEncodingHandler = handler;
1760   parser->m_unknownEncodingHandlerData = data    1760   parser->m_unknownEncodingHandlerData = data;
1761 }                                                1761 }
1762                                                  1762 
1763 void XMLCALL                                     1763 void XMLCALL
1764 XML_SetElementDeclHandler(XML_Parser parser,     1764 XML_SetElementDeclHandler(XML_Parser parser, XML_ElementDeclHandler eldecl) {
1765   if (parser != NULL)                            1765   if (parser != NULL)
1766     parser->m_elementDeclHandler = eldecl;       1766     parser->m_elementDeclHandler = eldecl;
1767 }                                                1767 }
1768                                                  1768 
1769 void XMLCALL                                     1769 void XMLCALL
1770 XML_SetAttlistDeclHandler(XML_Parser parser,     1770 XML_SetAttlistDeclHandler(XML_Parser parser, XML_AttlistDeclHandler attdecl) {
1771   if (parser != NULL)                            1771   if (parser != NULL)
1772     parser->m_attlistDeclHandler = attdecl;      1772     parser->m_attlistDeclHandler = attdecl;
1773 }                                                1773 }
1774                                                  1774 
1775 void XMLCALL                                     1775 void XMLCALL
1776 XML_SetEntityDeclHandler(XML_Parser parser, X    1776 XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler) {
1777   if (parser != NULL)                            1777   if (parser != NULL)
1778     parser->m_entityDeclHandler = handler;       1778     parser->m_entityDeclHandler = handler;
1779 }                                                1779 }
1780                                                  1780 
1781 void XMLCALL                                     1781 void XMLCALL
1782 XML_SetXmlDeclHandler(XML_Parser parser, XML_    1782 XML_SetXmlDeclHandler(XML_Parser parser, XML_XmlDeclHandler handler) {
1783   if (parser != NULL)                            1783   if (parser != NULL)
1784     parser->m_xmlDeclHandler = handler;          1784     parser->m_xmlDeclHandler = handler;
1785 }                                                1785 }
1786                                                  1786 
1787 int XMLCALL                                      1787 int XMLCALL
1788 XML_SetParamEntityParsing(XML_Parser parser,     1788 XML_SetParamEntityParsing(XML_Parser parser,
1789                           enum XML_ParamEntit    1789                           enum XML_ParamEntityParsing peParsing) {
1790   if (parser == NULL)                            1790   if (parser == NULL)
1791     return 0;                                    1791     return 0;
1792   /* block after XML_Parse()/XML_ParseBuffer(    1792   /* block after XML_Parse()/XML_ParseBuffer() has been called */
1793   if (parser->m_parsingStatus.parsing == XML_    1793   if (parser->m_parsingStatus.parsing == XML_PARSING
1794       || parser->m_parsingStatus.parsing == X    1794       || parser->m_parsingStatus.parsing == XML_SUSPENDED)
1795     return 0;                                    1795     return 0;
1796 #ifdef XML_DTD                                   1796 #ifdef XML_DTD
1797   parser->m_paramEntityParsing = peParsing;      1797   parser->m_paramEntityParsing = peParsing;
1798   return 1;                                      1798   return 1;
1799 #else                                            1799 #else
1800   return peParsing == XML_PARAM_ENTITY_PARSIN    1800   return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
1801 #endif                                           1801 #endif
1802 }                                                1802 }
1803                                                  1803 
1804 int XMLCALL                                      1804 int XMLCALL
1805 XML_SetHashSalt(XML_Parser parser, unsigned l    1805 XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt) {
1806   if (parser == NULL)                            1806   if (parser == NULL)
1807     return 0;                                    1807     return 0;
1808   if (parser->m_parentParser)                    1808   if (parser->m_parentParser)
1809     return XML_SetHashSalt(parser->m_parentPa    1809     return XML_SetHashSalt(parser->m_parentParser, hash_salt);
1810   /* block after XML_Parse()/XML_ParseBuffer(    1810   /* block after XML_Parse()/XML_ParseBuffer() has been called */
1811   if (parser->m_parsingStatus.parsing == XML_    1811   if (parser->m_parsingStatus.parsing == XML_PARSING
1812       || parser->m_parsingStatus.parsing == X    1812       || parser->m_parsingStatus.parsing == XML_SUSPENDED)
1813     return 0;                                    1813     return 0;
1814   parser->m_hash_secret_salt = hash_salt;        1814   parser->m_hash_secret_salt = hash_salt;
1815   return 1;                                      1815   return 1;
1816 }                                                1816 }
1817                                                  1817 
1818 enum XML_Status XMLCALL                          1818 enum XML_Status XMLCALL
1819 XML_Parse(XML_Parser parser, const char *s, i    1819 XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) {
1820   if ((parser == NULL) || (len < 0) || ((s ==    1820   if ((parser == NULL) || (len < 0) || ((s == NULL) && (len != 0))) {
1821     if (parser != NULL)                          1821     if (parser != NULL)
1822       parser->m_errorCode = XML_ERROR_INVALID    1822       parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT;
1823     return XML_STATUS_ERROR;                     1823     return XML_STATUS_ERROR;
1824   }                                              1824   }
1825   switch (parser->m_parsingStatus.parsing) {     1825   switch (parser->m_parsingStatus.parsing) {
1826   case XML_SUSPENDED:                            1826   case XML_SUSPENDED:
1827     parser->m_errorCode = XML_ERROR_SUSPENDED    1827     parser->m_errorCode = XML_ERROR_SUSPENDED;
1828     return XML_STATUS_ERROR;                     1828     return XML_STATUS_ERROR;
1829   case XML_FINISHED:                             1829   case XML_FINISHED:
1830     parser->m_errorCode = XML_ERROR_FINISHED;    1830     parser->m_errorCode = XML_ERROR_FINISHED;
1831     return XML_STATUS_ERROR;                     1831     return XML_STATUS_ERROR;
1832   case XML_INITIALIZED:                          1832   case XML_INITIALIZED:
1833     if (parser->m_parentParser == NULL && ! s    1833     if (parser->m_parentParser == NULL && ! startParsing(parser)) {
1834       parser->m_errorCode = XML_ERROR_NO_MEMO    1834       parser->m_errorCode = XML_ERROR_NO_MEMORY;
1835       return XML_STATUS_ERROR;                   1835       return XML_STATUS_ERROR;
1836     }                                            1836     }
1837     /* fall through */                           1837     /* fall through */
1838   default:                                       1838   default:
1839     parser->m_parsingStatus.parsing = XML_PAR    1839     parser->m_parsingStatus.parsing = XML_PARSING;
1840   }                                              1840   }
1841                                                  1841 
1842   if (len == 0) {                                1842   if (len == 0) {
1843     parser->m_parsingStatus.finalBuffer = (XM    1843     parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
1844     if (! isFinal)                               1844     if (! isFinal)
1845       return XML_STATUS_OK;                      1845       return XML_STATUS_OK;
1846     parser->m_positionPtr = parser->m_bufferP    1846     parser->m_positionPtr = parser->m_bufferPtr;
1847     parser->m_parseEndPtr = parser->m_bufferE    1847     parser->m_parseEndPtr = parser->m_bufferEnd;
1848                                                  1848 
1849     /* If data are left over from last buffer    1849     /* If data are left over from last buffer, and we now know that these
1850        data are the final chunk of input, the    1850        data are the final chunk of input, then we have to check them again
1851        to detect errors based on that fact.      1851        to detect errors based on that fact.
1852     */                                           1852     */
1853     parser->m_errorCode                          1853     parser->m_errorCode
1854         = parser->m_processor(parser, parser-    1854         = parser->m_processor(parser, parser->m_bufferPtr,
1855                               parser->m_parse    1855                               parser->m_parseEndPtr, &parser->m_bufferPtr);
1856                                                  1856 
1857     if (parser->m_errorCode == XML_ERROR_NONE    1857     if (parser->m_errorCode == XML_ERROR_NONE) {
1858       switch (parser->m_parsingStatus.parsing    1858       switch (parser->m_parsingStatus.parsing) {
1859       case XML_SUSPENDED:                        1859       case XML_SUSPENDED:
1860         /* It is hard to be certain, but it s    1860         /* It is hard to be certain, but it seems that this case
1861          * cannot occur.  This code is cleani    1861          * cannot occur.  This code is cleaning up a previous parse
1862          * with no new data (since len == 0).    1862          * with no new data (since len == 0).  Changing the parsing
1863          * state requires getting to execute     1863          * state requires getting to execute a handler function, and
1864          * there doesn't seem to be an opport    1864          * there doesn't seem to be an opportunity for that while in
1865          * this circumstance.                    1865          * this circumstance.
1866          *                                       1866          *
1867          * Given the uncertainty, we retain t    1867          * Given the uncertainty, we retain the code but exclude it
1868          * from coverage tests.                  1868          * from coverage tests.
1869          *                                       1869          *
1870          * LCOV_EXCL_START                       1870          * LCOV_EXCL_START
1871          */                                      1871          */
1872         XmlUpdatePosition(parser->m_encoding,    1872         XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
1873                           parser->m_bufferPtr    1873                           parser->m_bufferPtr, &parser->m_position);
1874         parser->m_positionPtr = parser->m_buf    1874         parser->m_positionPtr = parser->m_bufferPtr;
1875         return XML_STATUS_SUSPENDED;             1875         return XML_STATUS_SUSPENDED;
1876         /* LCOV_EXCL_STOP */                     1876         /* LCOV_EXCL_STOP */
1877       case XML_INITIALIZED:                      1877       case XML_INITIALIZED:
1878       case XML_PARSING:                          1878       case XML_PARSING:
1879         parser->m_parsingStatus.parsing = XML    1879         parser->m_parsingStatus.parsing = XML_FINISHED;
1880         /* fall through */                       1880         /* fall through */
1881       default:                                   1881       default:
1882         return XML_STATUS_OK;                    1882         return XML_STATUS_OK;
1883       }                                          1883       }
1884     }                                            1884     }
1885     parser->m_eventEndPtr = parser->m_eventPt    1885     parser->m_eventEndPtr = parser->m_eventPtr;
1886     parser->m_processor = errorProcessor;        1886     parser->m_processor = errorProcessor;
1887     return XML_STATUS_ERROR;                     1887     return XML_STATUS_ERROR;
1888   }                                              1888   }
1889 #ifndef XML_CONTEXT_BYTES                        1889 #ifndef XML_CONTEXT_BYTES
1890   else if (parser->m_bufferPtr == parser->m_b    1890   else if (parser->m_bufferPtr == parser->m_bufferEnd) {
1891     const char *end;                             1891     const char *end;
1892     int nLeftOver;                               1892     int nLeftOver;
1893     enum XML_Status result;                      1893     enum XML_Status result;
1894     /* Detect overflow (a+b > MAX <==> b > MA    1894     /* Detect overflow (a+b > MAX <==> b > MAX-a) */
1895     if ((XML_Size)len > ((XML_Size)-1) / 2 -     1895     if ((XML_Size)len > ((XML_Size)-1) / 2 - parser->m_parseEndByteIndex) {
1896       parser->m_errorCode = XML_ERROR_NO_MEMO    1896       parser->m_errorCode = XML_ERROR_NO_MEMORY;
1897       parser->m_eventPtr = parser->m_eventEnd    1897       parser->m_eventPtr = parser->m_eventEndPtr = NULL;
1898       parser->m_processor = errorProcessor;      1898       parser->m_processor = errorProcessor;
1899       return XML_STATUS_ERROR;                   1899       return XML_STATUS_ERROR;
1900     }                                            1900     }
1901     parser->m_parseEndByteIndex += len;          1901     parser->m_parseEndByteIndex += len;
1902     parser->m_positionPtr = s;                   1902     parser->m_positionPtr = s;
1903     parser->m_parsingStatus.finalBuffer = (XM    1903     parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
1904                                                  1904 
1905     parser->m_errorCode                          1905     parser->m_errorCode
1906         = parser->m_processor(parser, s, pars    1906         = parser->m_processor(parser, s, parser->m_parseEndPtr = s + len, &end);
1907                                                  1907 
1908     if (parser->m_errorCode != XML_ERROR_NONE    1908     if (parser->m_errorCode != XML_ERROR_NONE) {
1909       parser->m_eventEndPtr = parser->m_event    1909       parser->m_eventEndPtr = parser->m_eventPtr;
1910       parser->m_processor = errorProcessor;      1910       parser->m_processor = errorProcessor;
1911       return XML_STATUS_ERROR;                   1911       return XML_STATUS_ERROR;
1912     } else {                                     1912     } else {
1913       switch (parser->m_parsingStatus.parsing    1913       switch (parser->m_parsingStatus.parsing) {
1914       case XML_SUSPENDED:                        1914       case XML_SUSPENDED:
1915         result = XML_STATUS_SUSPENDED;           1915         result = XML_STATUS_SUSPENDED;
1916         break;                                   1916         break;
1917       case XML_INITIALIZED:                      1917       case XML_INITIALIZED:
1918       case XML_PARSING:                          1918       case XML_PARSING:
1919         if (isFinal) {                           1919         if (isFinal) {
1920           parser->m_parsingStatus.parsing = X    1920           parser->m_parsingStatus.parsing = XML_FINISHED;
1921           return XML_STATUS_OK;                  1921           return XML_STATUS_OK;
1922         }                                        1922         }
1923       /* fall through */                         1923       /* fall through */
1924       default:                                   1924       default:
1925         result = XML_STATUS_OK;                  1925         result = XML_STATUS_OK;
1926       }                                          1926       }
1927     }                                            1927     }
1928                                                  1928 
1929     XmlUpdatePosition(parser->m_encoding, par    1929     XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, end,
1930                       &parser->m_position);      1930                       &parser->m_position);
1931     nLeftOver = s + len - end;                   1931     nLeftOver = s + len - end;
1932     if (nLeftOver) {                             1932     if (nLeftOver) {
1933       if (parser->m_buffer == NULL               1933       if (parser->m_buffer == NULL
1934           || nLeftOver > parser->m_bufferLim     1934           || nLeftOver > parser->m_bufferLim - parser->m_buffer) {
1935         /* avoid _signed_ integer overflow */    1935         /* avoid _signed_ integer overflow */
1936         char *temp = NULL;                       1936         char *temp = NULL;
1937         const int bytesToAllocate = (int)((un    1937         const int bytesToAllocate = (int)((unsigned)len * 2U);
1938         if (bytesToAllocate > 0) {               1938         if (bytesToAllocate > 0) {
1939           temp = (char *)REALLOC(parser, pars    1939           temp = (char *)REALLOC(parser, parser->m_buffer, bytesToAllocate);
1940         }                                        1940         }
1941         if (temp == NULL) {                      1941         if (temp == NULL) {
1942           parser->m_errorCode = XML_ERROR_NO_    1942           parser->m_errorCode = XML_ERROR_NO_MEMORY;
1943           parser->m_eventPtr = parser->m_even    1943           parser->m_eventPtr = parser->m_eventEndPtr = NULL;
1944           parser->m_processor = errorProcesso    1944           parser->m_processor = errorProcessor;
1945           return XML_STATUS_ERROR;               1945           return XML_STATUS_ERROR;
1946         }                                        1946         }
1947         parser->m_buffer = temp;                 1947         parser->m_buffer = temp;
1948         parser->m_bufferLim = parser->m_buffe    1948         parser->m_bufferLim = parser->m_buffer + bytesToAllocate;
1949       }                                          1949       }
1950       memcpy(parser->m_buffer, end, nLeftOver    1950       memcpy(parser->m_buffer, end, nLeftOver);
1951     }                                            1951     }
1952     parser->m_bufferPtr = parser->m_buffer;      1952     parser->m_bufferPtr = parser->m_buffer;
1953     parser->m_bufferEnd = parser->m_buffer +     1953     parser->m_bufferEnd = parser->m_buffer + nLeftOver;
1954     parser->m_positionPtr = parser->m_bufferP    1954     parser->m_positionPtr = parser->m_bufferPtr;
1955     parser->m_parseEndPtr = parser->m_bufferE    1955     parser->m_parseEndPtr = parser->m_bufferEnd;
1956     parser->m_eventPtr = parser->m_bufferPtr;    1956     parser->m_eventPtr = parser->m_bufferPtr;
1957     parser->m_eventEndPtr = parser->m_bufferP    1957     parser->m_eventEndPtr = parser->m_bufferPtr;
1958     return result;                               1958     return result;
1959   }                                              1959   }
1960 #endif /* not defined XML_CONTEXT_BYTES */       1960 #endif /* not defined XML_CONTEXT_BYTES */
1961   else {                                         1961   else {
1962     void *buff = XML_GetBuffer(parser, len);     1962     void *buff = XML_GetBuffer(parser, len);
1963     if (buff == NULL)                            1963     if (buff == NULL)
1964       return XML_STATUS_ERROR;                   1964       return XML_STATUS_ERROR;
1965     else {                                       1965     else {
1966       memcpy(buff, s, len);                      1966       memcpy(buff, s, len);
1967       return XML_ParseBuffer(parser, len, isF    1967       return XML_ParseBuffer(parser, len, isFinal);
1968     }                                            1968     }
1969   }                                              1969   }
1970 }                                                1970 }
1971                                                  1971 
1972 enum XML_Status XMLCALL                          1972 enum XML_Status XMLCALL
1973 XML_ParseBuffer(XML_Parser parser, int len, i    1973 XML_ParseBuffer(XML_Parser parser, int len, int isFinal) {
1974   const char *start;                             1974   const char *start;
1975   enum XML_Status result = XML_STATUS_OK;        1975   enum XML_Status result = XML_STATUS_OK;
1976                                                  1976 
1977   if (parser == NULL)                            1977   if (parser == NULL)
1978     return XML_STATUS_ERROR;                     1978     return XML_STATUS_ERROR;
1979   switch (parser->m_parsingStatus.parsing) {     1979   switch (parser->m_parsingStatus.parsing) {
1980   case XML_SUSPENDED:                            1980   case XML_SUSPENDED:
1981     parser->m_errorCode = XML_ERROR_SUSPENDED    1981     parser->m_errorCode = XML_ERROR_SUSPENDED;
1982     return XML_STATUS_ERROR;                     1982     return XML_STATUS_ERROR;
1983   case XML_FINISHED:                             1983   case XML_FINISHED:
1984     parser->m_errorCode = XML_ERROR_FINISHED;    1984     parser->m_errorCode = XML_ERROR_FINISHED;
1985     return XML_STATUS_ERROR;                     1985     return XML_STATUS_ERROR;
1986   case XML_INITIALIZED:                          1986   case XML_INITIALIZED:
1987     /* Has someone called XML_GetBuffer succe    1987     /* Has someone called XML_GetBuffer successfully before? */
1988     if (! parser->m_bufferPtr) {                 1988     if (! parser->m_bufferPtr) {
1989       parser->m_errorCode = XML_ERROR_NO_BUFF    1989       parser->m_errorCode = XML_ERROR_NO_BUFFER;
1990       return XML_STATUS_ERROR;                   1990       return XML_STATUS_ERROR;
1991     }                                            1991     }
1992                                                  1992 
1993     if (parser->m_parentParser == NULL && ! s    1993     if (parser->m_parentParser == NULL && ! startParsing(parser)) {
1994       parser->m_errorCode = XML_ERROR_NO_MEMO    1994       parser->m_errorCode = XML_ERROR_NO_MEMORY;
1995       return XML_STATUS_ERROR;                   1995       return XML_STATUS_ERROR;
1996     }                                            1996     }
1997     /* fall through */                           1997     /* fall through */
1998   default:                                       1998   default:
1999     parser->m_parsingStatus.parsing = XML_PAR    1999     parser->m_parsingStatus.parsing = XML_PARSING;
2000   }                                              2000   }
2001                                                  2001 
2002   start = parser->m_bufferPtr;                   2002   start = parser->m_bufferPtr;
2003   parser->m_positionPtr = start;                 2003   parser->m_positionPtr = start;
2004   parser->m_bufferEnd += len;                    2004   parser->m_bufferEnd += len;
2005   parser->m_parseEndPtr = parser->m_bufferEnd    2005   parser->m_parseEndPtr = parser->m_bufferEnd;
2006   parser->m_parseEndByteIndex += len;            2006   parser->m_parseEndByteIndex += len;
2007   parser->m_parsingStatus.finalBuffer = (XML_    2007   parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
2008                                                  2008 
2009   parser->m_errorCode = parser->m_processor(     2009   parser->m_errorCode = parser->m_processor(
2010       parser, start, parser->m_parseEndPtr, &    2010       parser, start, parser->m_parseEndPtr, &parser->m_bufferPtr);
2011                                                  2011 
2012   if (parser->m_errorCode != XML_ERROR_NONE)     2012   if (parser->m_errorCode != XML_ERROR_NONE) {
2013     parser->m_eventEndPtr = parser->m_eventPt    2013     parser->m_eventEndPtr = parser->m_eventPtr;
2014     parser->m_processor = errorProcessor;        2014     parser->m_processor = errorProcessor;
2015     return XML_STATUS_ERROR;                     2015     return XML_STATUS_ERROR;
2016   } else {                                       2016   } else {
2017     switch (parser->m_parsingStatus.parsing)     2017     switch (parser->m_parsingStatus.parsing) {
2018     case XML_SUSPENDED:                          2018     case XML_SUSPENDED:
2019       result = XML_STATUS_SUSPENDED;             2019       result = XML_STATUS_SUSPENDED;
2020       break;                                     2020       break;
2021     case XML_INITIALIZED:                        2021     case XML_INITIALIZED:
2022     case XML_PARSING:                            2022     case XML_PARSING:
2023       if (isFinal) {                             2023       if (isFinal) {
2024         parser->m_parsingStatus.parsing = XML    2024         parser->m_parsingStatus.parsing = XML_FINISHED;
2025         return result;                           2025         return result;
2026       }                                          2026       }
2027     default:; /* should not happen */            2027     default:; /* should not happen */
2028     }                                            2028     }
2029   }                                              2029   }
2030                                                  2030 
2031   XmlUpdatePosition(parser->m_encoding, parse    2031   XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
2032                     parser->m_bufferPtr, &par    2032                     parser->m_bufferPtr, &parser->m_position);
2033   parser->m_positionPtr = parser->m_bufferPtr    2033   parser->m_positionPtr = parser->m_bufferPtr;
2034   return result;                                 2034   return result;
2035 }                                                2035 }
2036                                                  2036 
2037 void *XMLCALL                                    2037 void *XMLCALL
2038 XML_GetBuffer(XML_Parser parser, int len) {      2038 XML_GetBuffer(XML_Parser parser, int len) {
2039   if (parser == NULL)                            2039   if (parser == NULL)
2040     return NULL;                                 2040     return NULL;
2041   if (len < 0) {                                 2041   if (len < 0) {
2042     parser->m_errorCode = XML_ERROR_NO_MEMORY    2042     parser->m_errorCode = XML_ERROR_NO_MEMORY;
2043     return NULL;                                 2043     return NULL;
2044   }                                              2044   }
2045   switch (parser->m_parsingStatus.parsing) {     2045   switch (parser->m_parsingStatus.parsing) {
2046   case XML_SUSPENDED:                            2046   case XML_SUSPENDED:
2047     parser->m_errorCode = XML_ERROR_SUSPENDED    2047     parser->m_errorCode = XML_ERROR_SUSPENDED;
2048     return NULL;                                 2048     return NULL;
2049   case XML_FINISHED:                             2049   case XML_FINISHED:
2050     parser->m_errorCode = XML_ERROR_FINISHED;    2050     parser->m_errorCode = XML_ERROR_FINISHED;
2051     return NULL;                                 2051     return NULL;
2052   default:;                                      2052   default:;
2053   }                                              2053   }
2054                                                  2054 
2055   if (len > EXPAT_SAFE_PTR_DIFF(parser->m_buf    2055   if (len > EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferEnd)) {
2056 #ifdef XML_CONTEXT_BYTES                         2056 #ifdef XML_CONTEXT_BYTES
2057     int keep;                                    2057     int keep;
2058 #endif /* defined XML_CONTEXT_BYTES */           2058 #endif /* defined XML_CONTEXT_BYTES */
2059     /* Do not invoke signed arithmetic overfl    2059     /* Do not invoke signed arithmetic overflow: */
2060     int neededSize = (int)((unsigned)len         2060     int neededSize = (int)((unsigned)len
2061                            + (unsigned)EXPAT_    2061                            + (unsigned)EXPAT_SAFE_PTR_DIFF(
2062                                parser->m_buff    2062                                parser->m_bufferEnd, parser->m_bufferPtr));
2063     if (neededSize < 0) {                        2063     if (neededSize < 0) {
2064       parser->m_errorCode = XML_ERROR_NO_MEMO    2064       parser->m_errorCode = XML_ERROR_NO_MEMORY;
2065       return NULL;                               2065       return NULL;
2066     }                                            2066     }
2067 #ifdef XML_CONTEXT_BYTES                         2067 #ifdef XML_CONTEXT_BYTES
2068     keep = (int)EXPAT_SAFE_PTR_DIFF(parser->m    2068     keep = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer);
2069     if (keep > XML_CONTEXT_BYTES)                2069     if (keep > XML_CONTEXT_BYTES)
2070       keep = XML_CONTEXT_BYTES;                  2070       keep = XML_CONTEXT_BYTES;
2071     /* Detect and prevent integer overflow */    2071     /* Detect and prevent integer overflow */
2072     if (keep > INT_MAX - neededSize) {           2072     if (keep > INT_MAX - neededSize) {
2073       parser->m_errorCode = XML_ERROR_NO_MEMO    2073       parser->m_errorCode = XML_ERROR_NO_MEMORY;
2074       return NULL;                               2074       return NULL;
2075     }                                            2075     }
2076     neededSize += keep;                          2076     neededSize += keep;
2077 #endif /* defined XML_CONTEXT_BYTES */           2077 #endif /* defined XML_CONTEXT_BYTES */
2078     if (neededSize                               2078     if (neededSize
2079         <= EXPAT_SAFE_PTR_DIFF(parser->m_buff    2079         <= EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_buffer)) {
2080 #ifdef XML_CONTEXT_BYTES                         2080 #ifdef XML_CONTEXT_BYTES
2081       if (keep < EXPAT_SAFE_PTR_DIFF(parser->    2081       if (keep < EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer)) {
2082         int offset                               2082         int offset
2083             = (int)EXPAT_SAFE_PTR_DIFF(parser    2083             = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer)
2084               - keep;                            2084               - keep;
2085         /* The buffer pointers cannot be NULL    2085         /* The buffer pointers cannot be NULL here; we have at least some bytes
2086          * in the buffer */                      2086          * in the buffer */
2087         memmove(parser->m_buffer, &parser->m_    2087         memmove(parser->m_buffer, &parser->m_buffer[offset],
2088                 parser->m_bufferEnd - parser-    2088                 parser->m_bufferEnd - parser->m_bufferPtr + keep);
2089         parser->m_bufferEnd -= offset;           2089         parser->m_bufferEnd -= offset;
2090         parser->m_bufferPtr -= offset;           2090         parser->m_bufferPtr -= offset;
2091       }                                          2091       }
2092 #else                                            2092 #else
2093       if (parser->m_buffer && parser->m_buffe    2093       if (parser->m_buffer && parser->m_bufferPtr) {
2094         memmove(parser->m_buffer, parser->m_b    2094         memmove(parser->m_buffer, parser->m_bufferPtr,
2095                 EXPAT_SAFE_PTR_DIFF(parser->m    2095                 EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr));
2096         parser->m_bufferEnd                      2096         parser->m_bufferEnd
2097             = parser->m_buffer                   2097             = parser->m_buffer
2098               + EXPAT_SAFE_PTR_DIFF(parser->m    2098               + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr);
2099         parser->m_bufferPtr = parser->m_buffe    2099         parser->m_bufferPtr = parser->m_buffer;
2100       }                                          2100       }
2101 #endif /* not defined XML_CONTEXT_BYTES */       2101 #endif /* not defined XML_CONTEXT_BYTES */
2102     } else {                                     2102     } else {
2103       char *newBuf;                              2103       char *newBuf;
2104       int bufferSize                             2104       int bufferSize
2105           = (int)EXPAT_SAFE_PTR_DIFF(parser->    2105           = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferPtr);
2106       if (bufferSize == 0)                       2106       if (bufferSize == 0)
2107         bufferSize = INIT_BUFFER_SIZE;           2107         bufferSize = INIT_BUFFER_SIZE;
2108       do {                                       2108       do {
2109         /* Do not invoke signed arithmetic ov    2109         /* Do not invoke signed arithmetic overflow: */
2110         bufferSize = (int)(2U * (unsigned)buf    2110         bufferSize = (int)(2U * (unsigned)bufferSize);
2111       } while (bufferSize < neededSize && buf    2111       } while (bufferSize < neededSize && bufferSize > 0);
2112       if (bufferSize <= 0) {                     2112       if (bufferSize <= 0) {
2113         parser->m_errorCode = XML_ERROR_NO_ME    2113         parser->m_errorCode = XML_ERROR_NO_MEMORY;
2114         return NULL;                             2114         return NULL;
2115       }                                          2115       }
2116       newBuf = (char *)MALLOC(parser, bufferS    2116       newBuf = (char *)MALLOC(parser, bufferSize);
2117       if (newBuf == 0) {                         2117       if (newBuf == 0) {
2118         parser->m_errorCode = XML_ERROR_NO_ME    2118         parser->m_errorCode = XML_ERROR_NO_MEMORY;
2119         return NULL;                             2119         return NULL;
2120       }                                          2120       }
2121       parser->m_bufferLim = newBuf + bufferSi    2121       parser->m_bufferLim = newBuf + bufferSize;
2122 #ifdef XML_CONTEXT_BYTES                         2122 #ifdef XML_CONTEXT_BYTES
2123       if (parser->m_bufferPtr) {                 2123       if (parser->m_bufferPtr) {
2124         memcpy(newBuf, &parser->m_bufferPtr[-    2124         memcpy(newBuf, &parser->m_bufferPtr[-keep],
2125                EXPAT_SAFE_PTR_DIFF(parser->m_    2125                EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)
2126                    + keep);                      2126                    + keep);
2127         FREE(parser, parser->m_buffer);          2127         FREE(parser, parser->m_buffer);
2128         parser->m_buffer = newBuf;               2128         parser->m_buffer = newBuf;
2129         parser->m_bufferEnd                      2129         parser->m_bufferEnd
2130             = parser->m_buffer                   2130             = parser->m_buffer
2131               + EXPAT_SAFE_PTR_DIFF(parser->m    2131               + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)
2132               + keep;                            2132               + keep;
2133         parser->m_bufferPtr = parser->m_buffe    2133         parser->m_bufferPtr = parser->m_buffer + keep;
2134       } else {                                   2134       } else {
2135         /* This must be a brand new buffer wi    2135         /* This must be a brand new buffer with no data in it yet */
2136         parser->m_bufferEnd = newBuf;            2136         parser->m_bufferEnd = newBuf;
2137         parser->m_bufferPtr = parser->m_buffe    2137         parser->m_bufferPtr = parser->m_buffer = newBuf;
2138       }                                          2138       }
2139 #else                                            2139 #else
2140       if (parser->m_bufferPtr) {                 2140       if (parser->m_bufferPtr) {
2141         memcpy(newBuf, parser->m_bufferPtr,      2141         memcpy(newBuf, parser->m_bufferPtr,
2142                EXPAT_SAFE_PTR_DIFF(parser->m_    2142                EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr));
2143         FREE(parser, parser->m_buffer);          2143         FREE(parser, parser->m_buffer);
2144         parser->m_bufferEnd                      2144         parser->m_bufferEnd
2145             = newBuf                             2145             = newBuf
2146               + EXPAT_SAFE_PTR_DIFF(parser->m    2146               + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr);
2147       } else {                                   2147       } else {
2148         /* This must be a brand new buffer wi    2148         /* This must be a brand new buffer with no data in it yet */
2149         parser->m_bufferEnd = newBuf;            2149         parser->m_bufferEnd = newBuf;
2150       }                                          2150       }
2151       parser->m_bufferPtr = parser->m_buffer     2151       parser->m_bufferPtr = parser->m_buffer = newBuf;
2152 #endif /* not defined XML_CONTEXT_BYTES */       2152 #endif /* not defined XML_CONTEXT_BYTES */
2153     }                                            2153     }
2154     parser->m_eventPtr = parser->m_eventEndPt    2154     parser->m_eventPtr = parser->m_eventEndPtr = NULL;
2155     parser->m_positionPtr = NULL;                2155     parser->m_positionPtr = NULL;
2156   }                                              2156   }
2157   return parser->m_bufferEnd;                    2157   return parser->m_bufferEnd;
2158 }                                                2158 }
2159                                                  2159 
2160 enum XML_Status XMLCALL                          2160 enum XML_Status XMLCALL
2161 XML_StopParser(XML_Parser parser, XML_Bool re    2161 XML_StopParser(XML_Parser parser, XML_Bool resumable) {
2162   if (parser == NULL)                            2162   if (parser == NULL)
2163     return XML_STATUS_ERROR;                     2163     return XML_STATUS_ERROR;
2164   switch (parser->m_parsingStatus.parsing) {     2164   switch (parser->m_parsingStatus.parsing) {
2165   case XML_SUSPENDED:                            2165   case XML_SUSPENDED:
2166     if (resumable) {                             2166     if (resumable) {
2167       parser->m_errorCode = XML_ERROR_SUSPEND    2167       parser->m_errorCode = XML_ERROR_SUSPENDED;
2168       return XML_STATUS_ERROR;                   2168       return XML_STATUS_ERROR;
2169     }                                            2169     }
2170     parser->m_parsingStatus.parsing = XML_FIN    2170     parser->m_parsingStatus.parsing = XML_FINISHED;
2171     break;                                       2171     break;
2172   case XML_FINISHED:                             2172   case XML_FINISHED:
2173     parser->m_errorCode = XML_ERROR_FINISHED;    2173     parser->m_errorCode = XML_ERROR_FINISHED;
2174     return XML_STATUS_ERROR;                     2174     return XML_STATUS_ERROR;
2175   default:                                       2175   default:
2176     if (resumable) {                             2176     if (resumable) {
2177 #ifdef XML_DTD                                   2177 #ifdef XML_DTD
2178       if (parser->m_isParamEntity) {             2178       if (parser->m_isParamEntity) {
2179         parser->m_errorCode = XML_ERROR_SUSPE    2179         parser->m_errorCode = XML_ERROR_SUSPEND_PE;
2180         return XML_STATUS_ERROR;                 2180         return XML_STATUS_ERROR;
2181       }                                          2181       }
2182 #endif                                           2182 #endif
2183       parser->m_parsingStatus.parsing = XML_S    2183       parser->m_parsingStatus.parsing = XML_SUSPENDED;
2184     } else                                       2184     } else
2185       parser->m_parsingStatus.parsing = XML_F    2185       parser->m_parsingStatus.parsing = XML_FINISHED;
2186   }                                              2186   }
2187   return XML_STATUS_OK;                          2187   return XML_STATUS_OK;
2188 }                                                2188 }
2189                                                  2189 
2190 enum XML_Status XMLCALL                          2190 enum XML_Status XMLCALL
2191 XML_ResumeParser(XML_Parser parser) {            2191 XML_ResumeParser(XML_Parser parser) {
2192   enum XML_Status result = XML_STATUS_OK;        2192   enum XML_Status result = XML_STATUS_OK;
2193                                                  2193 
2194   if (parser == NULL)                            2194   if (parser == NULL)
2195     return XML_STATUS_ERROR;                     2195     return XML_STATUS_ERROR;
2196   if (parser->m_parsingStatus.parsing != XML_    2196   if (parser->m_parsingStatus.parsing != XML_SUSPENDED) {
2197     parser->m_errorCode = XML_ERROR_NOT_SUSPE    2197     parser->m_errorCode = XML_ERROR_NOT_SUSPENDED;
2198     return XML_STATUS_ERROR;                     2198     return XML_STATUS_ERROR;
2199   }                                              2199   }
2200   parser->m_parsingStatus.parsing = XML_PARSI    2200   parser->m_parsingStatus.parsing = XML_PARSING;
2201                                                  2201 
2202   parser->m_errorCode = parser->m_processor(     2202   parser->m_errorCode = parser->m_processor(
2203       parser, parser->m_bufferPtr, parser->m_    2203       parser, parser->m_bufferPtr, parser->m_parseEndPtr, &parser->m_bufferPtr);
2204                                                  2204 
2205   if (parser->m_errorCode != XML_ERROR_NONE)     2205   if (parser->m_errorCode != XML_ERROR_NONE) {
2206     parser->m_eventEndPtr = parser->m_eventPt    2206     parser->m_eventEndPtr = parser->m_eventPtr;
2207     parser->m_processor = errorProcessor;        2207     parser->m_processor = errorProcessor;
2208     return XML_STATUS_ERROR;                     2208     return XML_STATUS_ERROR;
2209   } else {                                       2209   } else {
2210     switch (parser->m_parsingStatus.parsing)     2210     switch (parser->m_parsingStatus.parsing) {
2211     case XML_SUSPENDED:                          2211     case XML_SUSPENDED:
2212       result = XML_STATUS_SUSPENDED;             2212       result = XML_STATUS_SUSPENDED;
2213       break;                                     2213       break;
2214     case XML_INITIALIZED:                        2214     case XML_INITIALIZED:
2215     case XML_PARSING:                            2215     case XML_PARSING:
2216       if (parser->m_parsingStatus.finalBuffer    2216       if (parser->m_parsingStatus.finalBuffer) {
2217         parser->m_parsingStatus.parsing = XML    2217         parser->m_parsingStatus.parsing = XML_FINISHED;
2218         return result;                           2218         return result;
2219       }                                          2219       }
2220     default:;                                    2220     default:;
2221     }                                            2221     }
2222   }                                              2222   }
2223                                                  2223 
2224   XmlUpdatePosition(parser->m_encoding, parse    2224   XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
2225                     parser->m_bufferPtr, &par    2225                     parser->m_bufferPtr, &parser->m_position);
2226   parser->m_positionPtr = parser->m_bufferPtr    2226   parser->m_positionPtr = parser->m_bufferPtr;
2227   return result;                                 2227   return result;
2228 }                                                2228 }
2229                                                  2229 
2230 void XMLCALL                                     2230 void XMLCALL
2231 XML_GetParsingStatus(XML_Parser parser, XML_P    2231 XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status) {
2232   if (parser == NULL)                            2232   if (parser == NULL)
2233     return;                                      2233     return;
2234   assert(status != NULL);                        2234   assert(status != NULL);
2235   *status = parser->m_parsingStatus;             2235   *status = parser->m_parsingStatus;
2236 }                                                2236 }
2237                                                  2237 
2238 enum XML_Error XMLCALL                           2238 enum XML_Error XMLCALL
2239 XML_GetErrorCode(XML_Parser parser) {            2239 XML_GetErrorCode(XML_Parser parser) {
2240   if (parser == NULL)                            2240   if (parser == NULL)
2241     return XML_ERROR_INVALID_ARGUMENT;           2241     return XML_ERROR_INVALID_ARGUMENT;
2242   return parser->m_errorCode;                    2242   return parser->m_errorCode;
2243 }                                                2243 }
2244                                                  2244 
2245 XML_Index XMLCALL                                2245 XML_Index XMLCALL
2246 XML_GetCurrentByteIndex(XML_Parser parser) {     2246 XML_GetCurrentByteIndex(XML_Parser parser) {
2247   if (parser == NULL)                            2247   if (parser == NULL)
2248     return -1;                                   2248     return -1;
2249   if (parser->m_eventPtr)                        2249   if (parser->m_eventPtr)
2250     return (XML_Index)(parser->m_parseEndByte    2250     return (XML_Index)(parser->m_parseEndByteIndex
2251                        - (parser->m_parseEndP    2251                        - (parser->m_parseEndPtr - parser->m_eventPtr));
2252   return -1;                                     2252   return -1;
2253 }                                                2253 }
2254                                                  2254 
2255 int XMLCALL                                      2255 int XMLCALL
2256 XML_GetCurrentByteCount(XML_Parser parser) {     2256 XML_GetCurrentByteCount(XML_Parser parser) {
2257   if (parser == NULL)                            2257   if (parser == NULL)
2258     return 0;                                    2258     return 0;
2259   if (parser->m_eventEndPtr && parser->m_even    2259   if (parser->m_eventEndPtr && parser->m_eventPtr)
2260     return (int)(parser->m_eventEndPtr - pars    2260     return (int)(parser->m_eventEndPtr - parser->m_eventPtr);
2261   return 0;                                      2261   return 0;
2262 }                                                2262 }
2263                                                  2263 
2264 const char *XMLCALL                              2264 const char *XMLCALL
2265 XML_GetInputContext(XML_Parser parser, int *o    2265 XML_GetInputContext(XML_Parser parser, int *offset, int *size) {
2266 #ifdef XML_CONTEXT_BYTES                         2266 #ifdef XML_CONTEXT_BYTES
2267   if (parser == NULL)                            2267   if (parser == NULL)
2268     return NULL;                                 2268     return NULL;
2269   if (parser->m_eventPtr && parser->m_buffer)    2269   if (parser->m_eventPtr && parser->m_buffer) {
2270     if (offset != NULL)                          2270     if (offset != NULL)
2271       *offset = (int)(parser->m_eventPtr - pa    2271       *offset = (int)(parser->m_eventPtr - parser->m_buffer);
2272     if (size != NULL)                            2272     if (size != NULL)
2273       *size = (int)(parser->m_bufferEnd - par    2273       *size = (int)(parser->m_bufferEnd - parser->m_buffer);
2274     return parser->m_buffer;                     2274     return parser->m_buffer;
2275   }                                              2275   }
2276 #else                                            2276 #else
2277   (void)parser;                                  2277   (void)parser;
2278   (void)offset;                                  2278   (void)offset;
2279   (void)size;                                    2279   (void)size;
2280 #endif /* defined XML_CONTEXT_BYTES */           2280 #endif /* defined XML_CONTEXT_BYTES */
2281   return (const char *)0;                        2281   return (const char *)0;
2282 }                                                2282 }
2283                                                  2283 
2284 XML_Size XMLCALL                                 2284 XML_Size XMLCALL
2285 XML_GetCurrentLineNumber(XML_Parser parser) {    2285 XML_GetCurrentLineNumber(XML_Parser parser) {
2286   if (parser == NULL)                            2286   if (parser == NULL)
2287     return 0;                                    2287     return 0;
2288   if (parser->m_eventPtr && parser->m_eventPt    2288   if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) {
2289     XmlUpdatePosition(parser->m_encoding, par    2289     XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
2290                       parser->m_eventPtr, &pa    2290                       parser->m_eventPtr, &parser->m_position);
2291     parser->m_positionPtr = parser->m_eventPt    2291     parser->m_positionPtr = parser->m_eventPtr;
2292   }                                              2292   }
2293   return parser->m_position.lineNumber + 1;      2293   return parser->m_position.lineNumber + 1;
2294 }                                                2294 }
2295                                                  2295 
2296 XML_Size XMLCALL                                 2296 XML_Size XMLCALL
2297 XML_GetCurrentColumnNumber(XML_Parser parser)    2297 XML_GetCurrentColumnNumber(XML_Parser parser) {
2298   if (parser == NULL)                            2298   if (parser == NULL)
2299     return 0;                                    2299     return 0;
2300   if (parser->m_eventPtr && parser->m_eventPt    2300   if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) {
2301     XmlUpdatePosition(parser->m_encoding, par    2301     XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
2302                       parser->m_eventPtr, &pa    2302                       parser->m_eventPtr, &parser->m_position);
2303     parser->m_positionPtr = parser->m_eventPt    2303     parser->m_positionPtr = parser->m_eventPtr;
2304   }                                              2304   }
2305   return parser->m_position.columnNumber;        2305   return parser->m_position.columnNumber;
2306 }                                                2306 }
2307                                                  2307 
2308 void XMLCALL                                     2308 void XMLCALL
2309 XML_FreeContentModel(XML_Parser parser, XML_C    2309 XML_FreeContentModel(XML_Parser parser, XML_Content *model) {
2310   if (parser != NULL)                            2310   if (parser != NULL)
2311     FREE(parser, model);                         2311     FREE(parser, model);
2312 }                                                2312 }
2313                                                  2313 
2314 void *XMLCALL                                    2314 void *XMLCALL
2315 XML_MemMalloc(XML_Parser parser, size_t size)    2315 XML_MemMalloc(XML_Parser parser, size_t size) {
2316   if (parser == NULL)                            2316   if (parser == NULL)
2317     return NULL;                                 2317     return NULL;
2318   return MALLOC(parser, size);                   2318   return MALLOC(parser, size);
2319 }                                                2319 }
2320                                                  2320 
2321 void *XMLCALL                                    2321 void *XMLCALL
2322 XML_MemRealloc(XML_Parser parser, void *ptr,     2322 XML_MemRealloc(XML_Parser parser, void *ptr, size_t size) {
2323   if (parser == NULL)                            2323   if (parser == NULL)
2324     return NULL;                                 2324     return NULL;
2325   return REALLOC(parser, ptr, size);             2325   return REALLOC(parser, ptr, size);
2326 }                                                2326 }
2327                                                  2327 
2328 void XMLCALL                                     2328 void XMLCALL
2329 XML_MemFree(XML_Parser parser, void *ptr) {      2329 XML_MemFree(XML_Parser parser, void *ptr) {
2330   if (parser != NULL)                            2330   if (parser != NULL)
2331     FREE(parser, ptr);                           2331     FREE(parser, ptr);
2332 }                                                2332 }
2333                                                  2333 
2334 void XMLCALL                                     2334 void XMLCALL
2335 XML_DefaultCurrent(XML_Parser parser) {          2335 XML_DefaultCurrent(XML_Parser parser) {
2336   if (parser == NULL)                            2336   if (parser == NULL)
2337     return;                                      2337     return;
2338   if (parser->m_defaultHandler) {                2338   if (parser->m_defaultHandler) {
2339     if (parser->m_openInternalEntities)          2339     if (parser->m_openInternalEntities)
2340       reportDefault(parser, parser->m_interna    2340       reportDefault(parser, parser->m_internalEncoding,
2341                     parser->m_openInternalEnt    2341                     parser->m_openInternalEntities->internalEventPtr,
2342                     parser->m_openInternalEnt    2342                     parser->m_openInternalEntities->internalEventEndPtr);
2343     else                                         2343     else
2344       reportDefault(parser, parser->m_encodin    2344       reportDefault(parser, parser->m_encoding, parser->m_eventPtr,
2345                     parser->m_eventEndPtr);      2345                     parser->m_eventEndPtr);
2346   }                                              2346   }
2347 }                                                2347 }
2348                                                  2348 
2349 const XML_LChar *XMLCALL                         2349 const XML_LChar *XMLCALL
2350 XML_ErrorString(enum XML_Error code) {           2350 XML_ErrorString(enum XML_Error code) {
2351   switch (code) {                                2351   switch (code) {
2352   case XML_ERROR_NONE:                           2352   case XML_ERROR_NONE:
2353     return NULL;                                 2353     return NULL;
2354   case XML_ERROR_NO_MEMORY:                      2354   case XML_ERROR_NO_MEMORY:
2355     return XML_L("out of memory");               2355     return XML_L("out of memory");
2356   case XML_ERROR_SYNTAX:                         2356   case XML_ERROR_SYNTAX:
2357     return XML_L("syntax error");                2357     return XML_L("syntax error");
2358   case XML_ERROR_NO_ELEMENTS:                    2358   case XML_ERROR_NO_ELEMENTS:
2359     return XML_L("no element found");            2359     return XML_L("no element found");
2360   case XML_ERROR_INVALID_TOKEN:                  2360   case XML_ERROR_INVALID_TOKEN:
2361     return XML_L("not well-formed (invalid to    2361     return XML_L("not well-formed (invalid token)");
2362   case XML_ERROR_UNCLOSED_TOKEN:                 2362   case XML_ERROR_UNCLOSED_TOKEN:
2363     return XML_L("unclosed token");              2363     return XML_L("unclosed token");
2364   case XML_ERROR_PARTIAL_CHAR:                   2364   case XML_ERROR_PARTIAL_CHAR:
2365     return XML_L("partial character");           2365     return XML_L("partial character");
2366   case XML_ERROR_TAG_MISMATCH:                   2366   case XML_ERROR_TAG_MISMATCH:
2367     return XML_L("mismatched tag");              2367     return XML_L("mismatched tag");
2368   case XML_ERROR_DUPLICATE_ATTRIBUTE:            2368   case XML_ERROR_DUPLICATE_ATTRIBUTE:
2369     return XML_L("duplicate attribute");         2369     return XML_L("duplicate attribute");
2370   case XML_ERROR_JUNK_AFTER_DOC_ELEMENT:         2370   case XML_ERROR_JUNK_AFTER_DOC_ELEMENT:
2371     return XML_L("junk after document element    2371     return XML_L("junk after document element");
2372   case XML_ERROR_PARAM_ENTITY_REF:               2372   case XML_ERROR_PARAM_ENTITY_REF:
2373     return XML_L("illegal parameter entity re    2373     return XML_L("illegal parameter entity reference");
2374   case XML_ERROR_UNDEFINED_ENTITY:               2374   case XML_ERROR_UNDEFINED_ENTITY:
2375     return XML_L("undefined entity");            2375     return XML_L("undefined entity");
2376   case XML_ERROR_RECURSIVE_ENTITY_REF:           2376   case XML_ERROR_RECURSIVE_ENTITY_REF:
2377     return XML_L("recursive entity reference"    2377     return XML_L("recursive entity reference");
2378   case XML_ERROR_ASYNC_ENTITY:                   2378   case XML_ERROR_ASYNC_ENTITY:
2379     return XML_L("asynchronous entity");         2379     return XML_L("asynchronous entity");
2380   case XML_ERROR_BAD_CHAR_REF:                   2380   case XML_ERROR_BAD_CHAR_REF:
2381     return XML_L("reference to invalid charac    2381     return XML_L("reference to invalid character number");
2382   case XML_ERROR_BINARY_ENTITY_REF:              2382   case XML_ERROR_BINARY_ENTITY_REF:
2383     return XML_L("reference to binary entity"    2383     return XML_L("reference to binary entity");
2384   case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_RE    2384   case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF:
2385     return XML_L("reference to external entit    2385     return XML_L("reference to external entity in attribute");
2386   case XML_ERROR_MISPLACED_XML_PI:               2386   case XML_ERROR_MISPLACED_XML_PI:
2387     return XML_L("XML or text declaration not    2387     return XML_L("XML or text declaration not at start of entity");
2388   case XML_ERROR_UNKNOWN_ENCODING:               2388   case XML_ERROR_UNKNOWN_ENCODING:
2389     return XML_L("unknown encoding");            2389     return XML_L("unknown encoding");
2390   case XML_ERROR_INCORRECT_ENCODING:             2390   case XML_ERROR_INCORRECT_ENCODING:
2391     return XML_L("encoding specified in XML d    2391     return XML_L("encoding specified in XML declaration is incorrect");
2392   case XML_ERROR_UNCLOSED_CDATA_SECTION:         2392   case XML_ERROR_UNCLOSED_CDATA_SECTION:
2393     return XML_L("unclosed CDATA section");      2393     return XML_L("unclosed CDATA section");
2394   case XML_ERROR_EXTERNAL_ENTITY_HANDLING:       2394   case XML_ERROR_EXTERNAL_ENTITY_HANDLING:
2395     return XML_L("error in processing externa    2395     return XML_L("error in processing external entity reference");
2396   case XML_ERROR_NOT_STANDALONE:                 2396   case XML_ERROR_NOT_STANDALONE:
2397     return XML_L("document is not standalone"    2397     return XML_L("document is not standalone");
2398   case XML_ERROR_UNEXPECTED_STATE:               2398   case XML_ERROR_UNEXPECTED_STATE:
2399     return XML_L("unexpected parser state - p    2399     return XML_L("unexpected parser state - please send a bug report");
2400   case XML_ERROR_ENTITY_DECLARED_IN_PE:          2400   case XML_ERROR_ENTITY_DECLARED_IN_PE:
2401     return XML_L("entity declared in paramete    2401     return XML_L("entity declared in parameter entity");
2402   case XML_ERROR_FEATURE_REQUIRES_XML_DTD:       2402   case XML_ERROR_FEATURE_REQUIRES_XML_DTD:
2403     return XML_L("requested feature requires     2403     return XML_L("requested feature requires XML_DTD support in Expat");
2404   case XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PAR    2404   case XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING:
2405     return XML_L("cannot change setting once     2405     return XML_L("cannot change setting once parsing has begun");
2406   /* Added in 1.95.7. */                         2406   /* Added in 1.95.7. */
2407   case XML_ERROR_UNBOUND_PREFIX:                 2407   case XML_ERROR_UNBOUND_PREFIX:
2408     return XML_L("unbound prefix");              2408     return XML_L("unbound prefix");
2409   /* Added in 1.95.8. */                         2409   /* Added in 1.95.8. */
2410   case XML_ERROR_UNDECLARING_PREFIX:             2410   case XML_ERROR_UNDECLARING_PREFIX:
2411     return XML_L("must not undeclare prefix")    2411     return XML_L("must not undeclare prefix");
2412   case XML_ERROR_INCOMPLETE_PE:                  2412   case XML_ERROR_INCOMPLETE_PE:
2413     return XML_L("incomplete markup in parame    2413     return XML_L("incomplete markup in parameter entity");
2414   case XML_ERROR_XML_DECL:                       2414   case XML_ERROR_XML_DECL:
2415     return XML_L("XML declaration not well-fo    2415     return XML_L("XML declaration not well-formed");
2416   case XML_ERROR_TEXT_DECL:                      2416   case XML_ERROR_TEXT_DECL:
2417     return XML_L("text declaration not well-f    2417     return XML_L("text declaration not well-formed");
2418   case XML_ERROR_PUBLICID:                       2418   case XML_ERROR_PUBLICID:
2419     return XML_L("illegal character(s) in pub    2419     return XML_L("illegal character(s) in public id");
2420   case XML_ERROR_SUSPENDED:                      2420   case XML_ERROR_SUSPENDED:
2421     return XML_L("parser suspended");            2421     return XML_L("parser suspended");
2422   case XML_ERROR_NOT_SUSPENDED:                  2422   case XML_ERROR_NOT_SUSPENDED:
2423     return XML_L("parser not suspended");        2423     return XML_L("parser not suspended");
2424   case XML_ERROR_ABORTED:                        2424   case XML_ERROR_ABORTED:
2425     return XML_L("parsing aborted");             2425     return XML_L("parsing aborted");
2426   case XML_ERROR_FINISHED:                       2426   case XML_ERROR_FINISHED:
2427     return XML_L("parsing finished");            2427     return XML_L("parsing finished");
2428   case XML_ERROR_SUSPEND_PE:                     2428   case XML_ERROR_SUSPEND_PE:
2429     return XML_L("cannot suspend in external     2429     return XML_L("cannot suspend in external parameter entity");
2430   /* Added in 2.0.0. */                          2430   /* Added in 2.0.0. */
2431   case XML_ERROR_RESERVED_PREFIX_XML:            2431   case XML_ERROR_RESERVED_PREFIX_XML:
2432     return XML_L(                                2432     return XML_L(
2433         "reserved prefix (xml) must not be un    2433         "reserved prefix (xml) must not be undeclared or bound to another namespace name");
2434   case XML_ERROR_RESERVED_PREFIX_XMLNS:          2434   case XML_ERROR_RESERVED_PREFIX_XMLNS:
2435     return XML_L("reserved prefix (xmlns) mus    2435     return XML_L("reserved prefix (xmlns) must not be declared or undeclared");
2436   case XML_ERROR_RESERVED_NAMESPACE_URI:         2436   case XML_ERROR_RESERVED_NAMESPACE_URI:
2437     return XML_L(                                2437     return XML_L(
2438         "prefix must not be bound to one of t    2438         "prefix must not be bound to one of the reserved namespace names");
2439   /* Added in 2.2.5. */                          2439   /* Added in 2.2.5. */
2440   case XML_ERROR_INVALID_ARGUMENT: /* Constan    2440   case XML_ERROR_INVALID_ARGUMENT: /* Constant added in 2.2.1, already */
2441     return XML_L("invalid argument");            2441     return XML_L("invalid argument");
2442     /* Added in 2.3.0. */                        2442     /* Added in 2.3.0. */
2443   case XML_ERROR_NO_BUFFER:                      2443   case XML_ERROR_NO_BUFFER:
2444     return XML_L(                                2444     return XML_L(
2445         "a successful prior call to function     2445         "a successful prior call to function XML_GetBuffer is required");
2446   /* Added in 2.4.0. */                          2446   /* Added in 2.4.0. */
2447   case XML_ERROR_AMPLIFICATION_LIMIT_BREACH:     2447   case XML_ERROR_AMPLIFICATION_LIMIT_BREACH:
2448     return XML_L(                                2448     return XML_L(
2449         "limit on input amplification factor     2449         "limit on input amplification factor (from DTD and entities) breached");
2450   }                                              2450   }
2451   return NULL;                                   2451   return NULL;
2452 }                                                2452 }
2453                                                  2453 
2454 const XML_LChar *XMLCALL                         2454 const XML_LChar *XMLCALL
2455 XML_ExpatVersion(void) {                         2455 XML_ExpatVersion(void) {
2456   /* V1 is used to string-ize the version num    2456   /* V1 is used to string-ize the version number. However, it would
2457      string-ize the actual version macro *nam    2457      string-ize the actual version macro *names* unless we get them
2458      substituted before being passed to V1. C    2458      substituted before being passed to V1. CPP is defined to expand
2459      a macro, then rescan for more expansions    2459      a macro, then rescan for more expansions. Thus, we use V2 to expand
2460      the version macros, then CPP will expand    2460      the version macros, then CPP will expand the resulting V1() macro
2461      with the correct numerals. */               2461      with the correct numerals. */
2462   /* ### I'm assuming cpp is portable in this    2462   /* ### I'm assuming cpp is portable in this respect... */
2463                                                  2463 
2464 #define V1(a, b, c) XML_L(#a) XML_L(".") XML_    2464 #define V1(a, b, c) XML_L(#a) XML_L(".") XML_L(#b) XML_L(".") XML_L(#c)
2465 #define V2(a, b, c) XML_L("expat_") V1(a, b,     2465 #define V2(a, b, c) XML_L("expat_") V1(a, b, c)
2466                                                  2466 
2467   return V2(XML_MAJOR_VERSION, XML_MINOR_VERS    2467   return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
2468                                                  2468 
2469 #undef V1                                        2469 #undef V1
2470 #undef V2                                        2470 #undef V2
2471 }                                                2471 }
2472                                                  2472 
2473 XML_Expat_Version XMLCALL                        2473 XML_Expat_Version XMLCALL
2474 XML_ExpatVersionInfo(void) {                     2474 XML_ExpatVersionInfo(void) {
2475   XML_Expat_Version version;                     2475   XML_Expat_Version version;
2476                                                  2476 
2477   version.major = XML_MAJOR_VERSION;             2477   version.major = XML_MAJOR_VERSION;
2478   version.minor = XML_MINOR_VERSION;             2478   version.minor = XML_MINOR_VERSION;
2479   version.micro = XML_MICRO_VERSION;             2479   version.micro = XML_MICRO_VERSION;
2480                                                  2480 
2481   return version;                                2481   return version;
2482 }                                                2482 }
2483                                                  2483 
2484 const XML_Feature *XMLCALL                       2484 const XML_Feature *XMLCALL
2485 XML_GetFeatureList(void) {                       2485 XML_GetFeatureList(void) {
2486   static const XML_Feature features[] = {        2486   static const XML_Feature features[] = {
2487       {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("si    2487       {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"),
2488        sizeof(XML_Char)},                        2488        sizeof(XML_Char)},
2489       {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("s    2489       {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
2490        sizeof(XML_LChar)},                       2490        sizeof(XML_LChar)},
2491 #ifdef XML_UNICODE                               2491 #ifdef XML_UNICODE
2492       {XML_FEATURE_UNICODE, XML_L("XML_UNICOD    2492       {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},
2493 #endif                                           2493 #endif
2494 #ifdef XML_UNICODE_WCHAR_T                       2494 #ifdef XML_UNICODE_WCHAR_T
2495       {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XM    2495       {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},
2496 #endif                                           2496 #endif
2497 #ifdef XML_DTD                                   2497 #ifdef XML_DTD
2498       {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},    2498       {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},
2499 #endif                                           2499 #endif
2500 #ifdef XML_CONTEXT_BYTES                         2500 #ifdef XML_CONTEXT_BYTES
2501       {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_    2501       {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
2502        XML_CONTEXT_BYTES},                       2502        XML_CONTEXT_BYTES},
2503 #endif                                           2503 #endif
2504 #ifdef XML_MIN_SIZE                              2504 #ifdef XML_MIN_SIZE
2505       {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_S    2505       {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},
2506 #endif                                           2506 #endif
2507 #ifdef XML_NS                                    2507 #ifdef XML_NS
2508       {XML_FEATURE_NS, XML_L("XML_NS"), 0},      2508       {XML_FEATURE_NS, XML_L("XML_NS"), 0},
2509 #endif                                           2509 #endif
2510 #ifdef XML_LARGE_SIZE                            2510 #ifdef XML_LARGE_SIZE
2511       {XML_FEATURE_LARGE_SIZE, XML_L("XML_LAR    2511       {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0},
2512 #endif                                           2512 #endif
2513 #ifdef XML_ATTR_INFO                             2513 #ifdef XML_ATTR_INFO
2514       {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR    2514       {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0},
2515 #endif                                           2515 #endif
2516 #ifdef XML_DTD                                   2516 #ifdef XML_DTD
2517       /* Added in Expat 2.4.0. */                2517       /* Added in Expat 2.4.0. */
2518       {XML_FEATURE_BILLION_LAUGHS_ATTACK_PROT    2518       {XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT,
2519        XML_L("XML_BLAP_MAX_AMP"),                2519        XML_L("XML_BLAP_MAX_AMP"),
2520        (long int)                                2520        (long int)
2521            EXPAT_BILLION_LAUGHS_ATTACK_PROTEC    2521            EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT},
2522       {XML_FEATURE_BILLION_LAUGHS_ATTACK_PROT    2522       {XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT,
2523        XML_L("XML_BLAP_ACT_THRES"),              2523        XML_L("XML_BLAP_ACT_THRES"),
2524        EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION    2524        EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT},
2525 #endif                                           2525 #endif
2526       {XML_FEATURE_END, NULL, 0}};               2526       {XML_FEATURE_END, NULL, 0}};
2527                                                  2527 
2528   return features;                               2528   return features;
2529 }                                                2529 }
2530                                                  2530 
2531 #ifdef XML_DTD                                   2531 #ifdef XML_DTD
2532 XML_Bool XMLCALL                                 2532 XML_Bool XMLCALL
2533 XML_SetBillionLaughsAttackProtectionMaximumAm    2533 XML_SetBillionLaughsAttackProtectionMaximumAmplification(
2534     XML_Parser parser, float maximumAmplifica    2534     XML_Parser parser, float maximumAmplificationFactor) {
2535   if ((parser == NULL) || (parser->m_parentPa    2535   if ((parser == NULL) || (parser->m_parentParser != NULL)
2536       || isnan(maximumAmplificationFactor)       2536       || isnan(maximumAmplificationFactor)
2537       || (maximumAmplificationFactor < 1.0f))    2537       || (maximumAmplificationFactor < 1.0f)) {
2538     return XML_FALSE;                            2538     return XML_FALSE;
2539   }                                              2539   }
2540   parser->m_accounting.maximumAmplificationFa    2540   parser->m_accounting.maximumAmplificationFactor = maximumAmplificationFactor;
2541   return XML_TRUE;                               2541   return XML_TRUE;
2542 }                                                2542 }
2543                                                  2543 
2544 XML_Bool XMLCALL                                 2544 XML_Bool XMLCALL
2545 XML_SetBillionLaughsAttackProtectionActivatio    2545 XML_SetBillionLaughsAttackProtectionActivationThreshold(
2546     XML_Parser parser, unsigned long long act    2546     XML_Parser parser, unsigned long long activationThresholdBytes) {
2547   if ((parser == NULL) || (parser->m_parentPa    2547   if ((parser == NULL) || (parser->m_parentParser != NULL)) {
2548     return XML_FALSE;                            2548     return XML_FALSE;
2549   }                                              2549   }
2550   parser->m_accounting.activationThresholdByt    2550   parser->m_accounting.activationThresholdBytes = activationThresholdBytes;
2551   return XML_TRUE;                               2551   return XML_TRUE;
2552 }                                                2552 }
2553 #endif /* XML_DTD */                             2553 #endif /* XML_DTD */
2554                                                  2554 
2555 /* Initially tag->rawName always points into     2555 /* Initially tag->rawName always points into the parse buffer;
2556    for those TAG instances opened while the c    2556    for those TAG instances opened while the current parse buffer was
2557    processed, and not yet closed, we need to     2557    processed, and not yet closed, we need to store tag->rawName in a more
2558    permanent location, since the parse buffer    2558    permanent location, since the parse buffer is about to be discarded.
2559 */                                               2559 */
2560 static XML_Bool                                  2560 static XML_Bool
2561 storeRawNames(XML_Parser parser) {               2561 storeRawNames(XML_Parser parser) {
2562   TAG *tag = parser->m_tagStack;                 2562   TAG *tag = parser->m_tagStack;
2563   while (tag) {                                  2563   while (tag) {
2564     int bufSize;                                 2564     int bufSize;
2565     int nameLen = sizeof(XML_Char) * (tag->na    2565     int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
2566     size_t rawNameLen;                           2566     size_t rawNameLen;
2567     char *rawNameBuf = tag->buf + nameLen;       2567     char *rawNameBuf = tag->buf + nameLen;
2568     /* Stop if already stored.  Since m_tagSt    2568     /* Stop if already stored.  Since m_tagStack is a stack, we can stop
2569        at the first entry that has already be    2569        at the first entry that has already been copied; everything
2570        below it in the stack is already been     2570        below it in the stack is already been accounted for in a
2571        previous call to this function.           2571        previous call to this function.
2572     */                                           2572     */
2573     if (tag->rawName == rawNameBuf)              2573     if (tag->rawName == rawNameBuf)
2574       break;                                     2574       break;
2575     /* For re-use purposes we need to ensure     2575     /* For re-use purposes we need to ensure that the
2576        size of tag->buf is a multiple of size    2576        size of tag->buf is a multiple of sizeof(XML_Char).
2577     */                                           2577     */
2578     rawNameLen = ROUND_UP(tag->rawNameLength,    2578     rawNameLen = ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
2579     /* Detect and prevent integer overflow. *    2579     /* Detect and prevent integer overflow. */
2580     if (rawNameLen > (size_t)INT_MAX - nameLe    2580     if (rawNameLen > (size_t)INT_MAX - nameLen)
2581       return XML_FALSE;                          2581       return XML_FALSE;
2582     bufSize = nameLen + (int)rawNameLen;         2582     bufSize = nameLen + (int)rawNameLen;
2583     if (bufSize > tag->bufEnd - tag->buf) {      2583     if (bufSize > tag->bufEnd - tag->buf) {
2584       char *temp = (char *)REALLOC(parser, ta    2584       char *temp = (char *)REALLOC(parser, tag->buf, bufSize);
2585       if (temp == NULL)                          2585       if (temp == NULL)
2586         return XML_FALSE;                        2586         return XML_FALSE;
2587       /* if tag->name.str points to tag->buf     2587       /* if tag->name.str points to tag->buf (only when namespace
2588          processing is off) then we have to u    2588          processing is off) then we have to update it
2589       */                                         2589       */
2590       if (tag->name.str == (XML_Char *)tag->b    2590       if (tag->name.str == (XML_Char *)tag->buf)
2591         tag->name.str = (XML_Char *)temp;        2591         tag->name.str = (XML_Char *)temp;
2592       /* if tag->name.localPart is set (when     2592       /* if tag->name.localPart is set (when namespace processing is on)
2593          then update it as well, since it wil    2593          then update it as well, since it will always point into tag->buf
2594       */                                         2594       */
2595       if (tag->name.localPart)                   2595       if (tag->name.localPart)
2596         tag->name.localPart                      2596         tag->name.localPart
2597             = (XML_Char *)temp + (tag->name.l    2597             = (XML_Char *)temp + (tag->name.localPart - (XML_Char *)tag->buf);
2598       tag->buf = temp;                           2598       tag->buf = temp;
2599       tag->bufEnd = temp + bufSize;              2599       tag->bufEnd = temp + bufSize;
2600       rawNameBuf = temp + nameLen;               2600       rawNameBuf = temp + nameLen;
2601     }                                            2601     }
2602     memcpy(rawNameBuf, tag->rawName, tag->raw    2602     memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
2603     tag->rawName = rawNameBuf;                   2603     tag->rawName = rawNameBuf;
2604     tag = tag->parent;                           2604     tag = tag->parent;
2605   }                                              2605   }
2606   return XML_TRUE;                               2606   return XML_TRUE;
2607 }                                                2607 }
2608                                                  2608 
2609 static enum XML_Error PTRCALL                    2609 static enum XML_Error PTRCALL
2610 contentProcessor(XML_Parser parser, const cha    2610 contentProcessor(XML_Parser parser, const char *start, const char *end,
2611                  const char **endPtr) {          2611                  const char **endPtr) {
2612   enum XML_Error result = doContent(             2612   enum XML_Error result = doContent(
2613       parser, 0, parser->m_encoding, start, e    2613       parser, 0, parser->m_encoding, start, end, endPtr,
2614       (XML_Bool)! parser->m_parsingStatus.fin    2614       (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_ACCOUNT_DIRECT);
2615   if (result == XML_ERROR_NONE) {                2615   if (result == XML_ERROR_NONE) {
2616     if (! storeRawNames(parser))                 2616     if (! storeRawNames(parser))
2617       return XML_ERROR_NO_MEMORY;                2617       return XML_ERROR_NO_MEMORY;
2618   }                                              2618   }
2619   return result;                                 2619   return result;
2620 }                                                2620 }
2621                                                  2621 
2622 static enum XML_Error PTRCALL                    2622 static enum XML_Error PTRCALL
2623 externalEntityInitProcessor(XML_Parser parser    2623 externalEntityInitProcessor(XML_Parser parser, const char *start,
2624                             const char *end,     2624                             const char *end, const char **endPtr) {
2625   enum XML_Error result = initializeEncoding(    2625   enum XML_Error result = initializeEncoding(parser);
2626   if (result != XML_ERROR_NONE)                  2626   if (result != XML_ERROR_NONE)
2627     return result;                               2627     return result;
2628   parser->m_processor = externalEntityInitPro    2628   parser->m_processor = externalEntityInitProcessor2;
2629   return externalEntityInitProcessor2(parser,    2629   return externalEntityInitProcessor2(parser, start, end, endPtr);
2630 }                                                2630 }
2631                                                  2631 
2632 static enum XML_Error PTRCALL                    2632 static enum XML_Error PTRCALL
2633 externalEntityInitProcessor2(XML_Parser parse    2633 externalEntityInitProcessor2(XML_Parser parser, const char *start,
2634                              const char *end,    2634                              const char *end, const char **endPtr) {
2635   const char *next = start; /* XmlContentTok     2635   const char *next = start; /* XmlContentTok doesn't always set the last arg */
2636   int tok = XmlContentTok(parser->m_encoding,    2636   int tok = XmlContentTok(parser->m_encoding, start, end, &next);
2637   switch (tok) {                                 2637   switch (tok) {
2638   case XML_TOK_BOM:                              2638   case XML_TOK_BOM:
2639 #ifdef XML_DTD                                   2639 #ifdef XML_DTD
2640     if (! accountingDiffTolerated(parser, tok    2640     if (! accountingDiffTolerated(parser, tok, start, next, __LINE__,
2641                                   XML_ACCOUNT    2641                                   XML_ACCOUNT_DIRECT)) {
2642       accountingOnAbort(parser);                 2642       accountingOnAbort(parser);
2643       return XML_ERROR_AMPLIFICATION_LIMIT_BR    2643       return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
2644     }                                            2644     }
2645 #endif /* XML_DTD */                             2645 #endif /* XML_DTD */
2646                                                  2646 
2647     /* If we are at the end of the buffer, th    2647     /* If we are at the end of the buffer, this would cause the next stage,
2648        i.e. externalEntityInitProcessor3, to     2648        i.e. externalEntityInitProcessor3, to pass control directly to
2649        doContent (by detecting XML_TOK_NONE)     2649        doContent (by detecting XML_TOK_NONE) without processing any xml text
2650        declaration - causing the error XML_ER    2650        declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
2651     */                                           2651     */
2652     if (next == end && ! parser->m_parsingSta    2652     if (next == end && ! parser->m_parsingStatus.finalBuffer) {
2653       *endPtr = next;                            2653       *endPtr = next;
2654       return XML_ERROR_NONE;                     2654       return XML_ERROR_NONE;
2655     }                                            2655     }
2656     start = next;                                2656     start = next;
2657     break;                                       2657     break;
2658   case XML_TOK_PARTIAL:                          2658   case XML_TOK_PARTIAL:
2659     if (! parser->m_parsingStatus.finalBuffer    2659     if (! parser->m_parsingStatus.finalBuffer) {
2660       *endPtr = start;                           2660       *endPtr = start;
2661       return XML_ERROR_NONE;                     2661       return XML_ERROR_NONE;
2662     }                                            2662     }
2663     parser->m_eventPtr = start;                  2663     parser->m_eventPtr = start;
2664     return XML_ERROR_UNCLOSED_TOKEN;             2664     return XML_ERROR_UNCLOSED_TOKEN;
2665   case XML_TOK_PARTIAL_CHAR:                     2665   case XML_TOK_PARTIAL_CHAR:
2666     if (! parser->m_parsingStatus.finalBuffer    2666     if (! parser->m_parsingStatus.finalBuffer) {
2667       *endPtr = start;                           2667       *endPtr = start;
2668       return XML_ERROR_NONE;                     2668       return XML_ERROR_NONE;
2669     }                                            2669     }
2670     parser->m_eventPtr = start;                  2670     parser->m_eventPtr = start;
2671     return XML_ERROR_PARTIAL_CHAR;               2671     return XML_ERROR_PARTIAL_CHAR;
2672   }                                              2672   }
2673   parser->m_processor = externalEntityInitPro    2673   parser->m_processor = externalEntityInitProcessor3;
2674   return externalEntityInitProcessor3(parser,    2674   return externalEntityInitProcessor3(parser, start, end, endPtr);
2675 }                                                2675 }
2676                                                  2676 
2677 static enum XML_Error PTRCALL                    2677 static enum XML_Error PTRCALL
2678 externalEntityInitProcessor3(XML_Parser parse    2678 externalEntityInitProcessor3(XML_Parser parser, const char *start,
2679                              const char *end,    2679                              const char *end, const char **endPtr) {
2680   int tok;                                       2680   int tok;
2681   const char *next = start; /* XmlContentTok     2681   const char *next = start; /* XmlContentTok doesn't always set the last arg */
2682   parser->m_eventPtr = start;                    2682   parser->m_eventPtr = start;
2683   tok = XmlContentTok(parser->m_encoding, sta    2683   tok = XmlContentTok(parser->m_encoding, start, end, &next);
2684   /* Note: These bytes are accounted later in    2684   /* Note: These bytes are accounted later in:
2685            - processXmlDecl                      2685            - processXmlDecl
2686            - externalEntityContentProcessor      2686            - externalEntityContentProcessor
2687   */                                             2687   */
2688   parser->m_eventEndPtr = next;                  2688   parser->m_eventEndPtr = next;
2689                                                  2689 
2690   switch (tok) {                                 2690   switch (tok) {
2691   case XML_TOK_XML_DECL: {                       2691   case XML_TOK_XML_DECL: {
2692     enum XML_Error result;                       2692     enum XML_Error result;
2693     result = processXmlDecl(parser, 1, start,    2693     result = processXmlDecl(parser, 1, start, next);
2694     if (result != XML_ERROR_NONE)                2694     if (result != XML_ERROR_NONE)
2695       return result;                             2695       return result;
2696     switch (parser->m_parsingStatus.parsing)     2696     switch (parser->m_parsingStatus.parsing) {
2697     case XML_SUSPENDED:                          2697     case XML_SUSPENDED:
2698       *endPtr = next;                            2698       *endPtr = next;
2699       return XML_ERROR_NONE;                     2699       return XML_ERROR_NONE;
2700     case XML_FINISHED:                           2700     case XML_FINISHED:
2701       return XML_ERROR_ABORTED;                  2701       return XML_ERROR_ABORTED;
2702     default:                                     2702     default:
2703       start = next;                              2703       start = next;
2704     }                                            2704     }
2705   } break;                                       2705   } break;
2706   case XML_TOK_PARTIAL:                          2706   case XML_TOK_PARTIAL:
2707     if (! parser->m_parsingStatus.finalBuffer    2707     if (! parser->m_parsingStatus.finalBuffer) {
2708       *endPtr = start;                           2708       *endPtr = start;
2709       return XML_ERROR_NONE;                     2709       return XML_ERROR_NONE;
2710     }                                            2710     }
2711     return XML_ERROR_UNCLOSED_TOKEN;             2711     return XML_ERROR_UNCLOSED_TOKEN;
2712   case XML_TOK_PARTIAL_CHAR:                     2712   case XML_TOK_PARTIAL_CHAR:
2713     if (! parser->m_parsingStatus.finalBuffer    2713     if (! parser->m_parsingStatus.finalBuffer) {
2714       *endPtr = start;                           2714       *endPtr = start;
2715       return XML_ERROR_NONE;                     2715       return XML_ERROR_NONE;
2716     }                                            2716     }
2717     return XML_ERROR_PARTIAL_CHAR;               2717     return XML_ERROR_PARTIAL_CHAR;
2718   }                                              2718   }
2719   parser->m_processor = externalEntityContent    2719   parser->m_processor = externalEntityContentProcessor;
2720   parser->m_tagLevel = 1;                        2720   parser->m_tagLevel = 1;
2721   return externalEntityContentProcessor(parse    2721   return externalEntityContentProcessor(parser, start, end, endPtr);
2722 }                                                2722 }
2723                                                  2723 
2724 static enum XML_Error PTRCALL                    2724 static enum XML_Error PTRCALL
2725 externalEntityContentProcessor(XML_Parser par    2725 externalEntityContentProcessor(XML_Parser parser, const char *start,
2726                                const char *en    2726                                const char *end, const char **endPtr) {
2727   enum XML_Error result                          2727   enum XML_Error result
2728       = doContent(parser, 1, parser->m_encodi    2728       = doContent(parser, 1, parser->m_encoding, start, end, endPtr,
2729                   (XML_Bool)! parser->m_parsi    2729                   (XML_Bool)! parser->m_parsingStatus.finalBuffer,
2730                   XML_ACCOUNT_ENTITY_EXPANSIO    2730                   XML_ACCOUNT_ENTITY_EXPANSION);
2731   if (result == XML_ERROR_NONE) {                2731   if (result == XML_ERROR_NONE) {
2732     if (! storeRawNames(parser))                 2732     if (! storeRawNames(parser))
2733       return XML_ERROR_NO_MEMORY;                2733       return XML_ERROR_NO_MEMORY;
2734   }                                              2734   }
2735   return result;                                 2735   return result;
2736 }                                                2736 }
2737                                                  2737 
2738 static enum XML_Error                            2738 static enum XML_Error
2739 doContent(XML_Parser parser, int startTagLeve    2739 doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
2740           const char *s, const char *end, con    2740           const char *s, const char *end, const char **nextPtr,
2741           XML_Bool haveMore, enum XML_Account    2741           XML_Bool haveMore, enum XML_Account account) {
2742   /* save one level of indirection */            2742   /* save one level of indirection */
2743   DTD *const dtd = parser->m_dtd;                2743   DTD *const dtd = parser->m_dtd;
2744                                                  2744 
2745   const char **eventPP;                          2745   const char **eventPP;
2746   const char **eventEndPP;                       2746   const char **eventEndPP;
2747   if (enc == parser->m_encoding) {               2747   if (enc == parser->m_encoding) {
2748     eventPP = &parser->m_eventPtr;               2748     eventPP = &parser->m_eventPtr;
2749     eventEndPP = &parser->m_eventEndPtr;         2749     eventEndPP = &parser->m_eventEndPtr;
2750   } else {                                       2750   } else {
2751     eventPP = &(parser->m_openInternalEntitie    2751     eventPP = &(parser->m_openInternalEntities->internalEventPtr);
2752     eventEndPP = &(parser->m_openInternalEnti    2752     eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
2753   }                                              2753   }
2754   *eventPP = s;                                  2754   *eventPP = s;
2755                                                  2755 
2756   for (;;) {                                     2756   for (;;) {
2757     const char *next = s; /* XmlContentTok do    2757     const char *next = s; /* XmlContentTok doesn't always set the last arg */
2758     int tok = XmlContentTok(enc, s, end, &nex    2758     int tok = XmlContentTok(enc, s, end, &next);
2759 #ifdef XML_DTD                                   2759 #ifdef XML_DTD
2760     const char *accountAfter                     2760     const char *accountAfter
2761         = ((tok == XML_TOK_TRAILING_RSQB) ||     2761         = ((tok == XML_TOK_TRAILING_RSQB) || (tok == XML_TOK_TRAILING_CR))
2762               ? (haveMore ? s /* i.e. 0 bytes    2762               ? (haveMore ? s /* i.e. 0 bytes */ : end)
2763               : next;                            2763               : next;
2764     if (! accountingDiffTolerated(parser, tok    2764     if (! accountingDiffTolerated(parser, tok, s, accountAfter, __LINE__,
2765                                   account)) {    2765                                   account)) {
2766       accountingOnAbort(parser);                 2766       accountingOnAbort(parser);
2767       return XML_ERROR_AMPLIFICATION_LIMIT_BR    2767       return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
2768     }                                            2768     }
2769 #endif                                           2769 #endif
2770     *eventEndPP = next;                          2770     *eventEndPP = next;
2771     switch (tok) {                               2771     switch (tok) {
2772     case XML_TOK_TRAILING_CR:                    2772     case XML_TOK_TRAILING_CR:
2773       if (haveMore) {                            2773       if (haveMore) {
2774         *nextPtr = s;                            2774         *nextPtr = s;
2775         return XML_ERROR_NONE;                   2775         return XML_ERROR_NONE;
2776       }                                          2776       }
2777       *eventEndPP = end;                         2777       *eventEndPP = end;
2778       if (parser->m_characterDataHandler) {      2778       if (parser->m_characterDataHandler) {
2779         XML_Char c = 0xA;                        2779         XML_Char c = 0xA;
2780         parser->m_characterDataHandler(parser    2780         parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
2781       } else if (parser->m_defaultHandler)       2781       } else if (parser->m_defaultHandler)
2782         reportDefault(parser, enc, s, end);      2782         reportDefault(parser, enc, s, end);
2783       /* We are at the end of the final buffe    2783       /* We are at the end of the final buffer, should we check for
2784          XML_SUSPENDED, XML_FINISHED?            2784          XML_SUSPENDED, XML_FINISHED?
2785       */                                         2785       */
2786       if (startTagLevel == 0)                    2786       if (startTagLevel == 0)
2787         return XML_ERROR_NO_ELEMENTS;            2787         return XML_ERROR_NO_ELEMENTS;
2788       if (parser->m_tagLevel != startTagLevel    2788       if (parser->m_tagLevel != startTagLevel)
2789         return XML_ERROR_ASYNC_ENTITY;           2789         return XML_ERROR_ASYNC_ENTITY;
2790       *nextPtr = end;                            2790       *nextPtr = end;
2791       return XML_ERROR_NONE;                     2791       return XML_ERROR_NONE;
2792     case XML_TOK_NONE:                           2792     case XML_TOK_NONE:
2793       if (haveMore) {                            2793       if (haveMore) {
2794         *nextPtr = s;                            2794         *nextPtr = s;
2795         return XML_ERROR_NONE;                   2795         return XML_ERROR_NONE;
2796       }                                          2796       }
2797       if (startTagLevel > 0) {                   2797       if (startTagLevel > 0) {
2798         if (parser->m_tagLevel != startTagLev    2798         if (parser->m_tagLevel != startTagLevel)
2799           return XML_ERROR_ASYNC_ENTITY;         2799           return XML_ERROR_ASYNC_ENTITY;
2800         *nextPtr = s;                            2800         *nextPtr = s;
2801         return XML_ERROR_NONE;                   2801         return XML_ERROR_NONE;
2802       }                                          2802       }
2803       return XML_ERROR_NO_ELEMENTS;              2803       return XML_ERROR_NO_ELEMENTS;
2804     case XML_TOK_INVALID:                        2804     case XML_TOK_INVALID:
2805       *eventPP = next;                           2805       *eventPP = next;
2806       return XML_ERROR_INVALID_TOKEN;            2806       return XML_ERROR_INVALID_TOKEN;
2807     case XML_TOK_PARTIAL:                        2807     case XML_TOK_PARTIAL:
2808       if (haveMore) {                            2808       if (haveMore) {
2809         *nextPtr = s;                            2809         *nextPtr = s;
2810         return XML_ERROR_NONE;                   2810         return XML_ERROR_NONE;
2811       }                                          2811       }
2812       return XML_ERROR_UNCLOSED_TOKEN;           2812       return XML_ERROR_UNCLOSED_TOKEN;
2813     case XML_TOK_PARTIAL_CHAR:                   2813     case XML_TOK_PARTIAL_CHAR:
2814       if (haveMore) {                            2814       if (haveMore) {
2815         *nextPtr = s;                            2815         *nextPtr = s;
2816         return XML_ERROR_NONE;                   2816         return XML_ERROR_NONE;
2817       }                                          2817       }
2818       return XML_ERROR_PARTIAL_CHAR;             2818       return XML_ERROR_PARTIAL_CHAR;
2819     case XML_TOK_ENTITY_REF: {                   2819     case XML_TOK_ENTITY_REF: {
2820       const XML_Char *name;                      2820       const XML_Char *name;
2821       ENTITY *entity;                            2821       ENTITY *entity;
2822       XML_Char ch = (XML_Char)XmlPredefinedEn    2822       XML_Char ch = (XML_Char)XmlPredefinedEntityName(
2823           enc, s + enc->minBytesPerChar, next    2823           enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar);
2824       if (ch) {                                  2824       if (ch) {
2825 #ifdef XML_DTD                                   2825 #ifdef XML_DTD
2826         /* NOTE: We are replacing 4-6 charact    2826         /* NOTE: We are replacing 4-6 characters original input for 1 character
2827          *       so there is no amplification    2827          *       so there is no amplification and hence recording without
2828          *       protection. */                  2828          *       protection. */
2829         accountingDiffTolerated(parser, tok,     2829         accountingDiffTolerated(parser, tok, (char *)&ch,
2830                                 ((char *)&ch)    2830                                 ((char *)&ch) + sizeof(XML_Char), __LINE__,
2831                                 XML_ACCOUNT_E    2831                                 XML_ACCOUNT_ENTITY_EXPANSION);
2832 #endif /* XML_DTD */                             2832 #endif /* XML_DTD */
2833         if (parser->m_characterDataHandler)      2833         if (parser->m_characterDataHandler)
2834           parser->m_characterDataHandler(pars    2834           parser->m_characterDataHandler(parser->m_handlerArg, &ch, 1);
2835         else if (parser->m_defaultHandler)       2835         else if (parser->m_defaultHandler)
2836           reportDefault(parser, enc, s, next)    2836           reportDefault(parser, enc, s, next);
2837         break;                                   2837         break;
2838       }                                          2838       }
2839       name = poolStoreString(&dtd->pool, enc,    2839       name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
2840                              next - enc->minB    2840                              next - enc->minBytesPerChar);
2841       if (! name)                                2841       if (! name)
2842         return XML_ERROR_NO_MEMORY;              2842         return XML_ERROR_NO_MEMORY;
2843       entity = (ENTITY *)lookup(parser, &dtd-    2843       entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
2844       poolDiscard(&dtd->pool);                   2844       poolDiscard(&dtd->pool);
2845       /* First, determine if a check for an e    2845       /* First, determine if a check for an existing declaration is needed;
2846          if yes, check that the entity exists    2846          if yes, check that the entity exists, and that it is internal,
2847          otherwise call the skipped entity or    2847          otherwise call the skipped entity or default handler.
2848       */                                         2848       */
2849       if (! dtd->hasParamEntityRefs || dtd->s    2849       if (! dtd->hasParamEntityRefs || dtd->standalone) {
2850         if (! entity)                            2850         if (! entity)
2851           return XML_ERROR_UNDEFINED_ENTITY;     2851           return XML_ERROR_UNDEFINED_ENTITY;
2852         else if (! entity->is_internal)          2852         else if (! entity->is_internal)
2853           return XML_ERROR_ENTITY_DECLARED_IN    2853           return XML_ERROR_ENTITY_DECLARED_IN_PE;
2854       } else if (! entity) {                     2854       } else if (! entity) {
2855         if (parser->m_skippedEntityHandler)      2855         if (parser->m_skippedEntityHandler)
2856           parser->m_skippedEntityHandler(pars    2856           parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
2857         else if (parser->m_defaultHandler)       2857         else if (parser->m_defaultHandler)
2858           reportDefault(parser, enc, s, next)    2858           reportDefault(parser, enc, s, next);
2859         break;                                   2859         break;
2860       }                                          2860       }
2861       if (entity->open)                          2861       if (entity->open)
2862         return XML_ERROR_RECURSIVE_ENTITY_REF    2862         return XML_ERROR_RECURSIVE_ENTITY_REF;
2863       if (entity->notation)                      2863       if (entity->notation)
2864         return XML_ERROR_BINARY_ENTITY_REF;      2864         return XML_ERROR_BINARY_ENTITY_REF;
2865       if (entity->textPtr) {                     2865       if (entity->textPtr) {
2866         enum XML_Error result;                   2866         enum XML_Error result;
2867         if (! parser->m_defaultExpandInternal    2867         if (! parser->m_defaultExpandInternalEntities) {
2868           if (parser->m_skippedEntityHandler)    2868           if (parser->m_skippedEntityHandler)
2869             parser->m_skippedEntityHandler(pa    2869             parser->m_skippedEntityHandler(parser->m_handlerArg, entity->name,
2870                                            0)    2870                                            0);
2871           else if (parser->m_defaultHandler)     2871           else if (parser->m_defaultHandler)
2872             reportDefault(parser, enc, s, nex    2872             reportDefault(parser, enc, s, next);
2873           break;                                 2873           break;
2874         }                                        2874         }
2875         result = processInternalEntity(parser    2875         result = processInternalEntity(parser, entity, XML_FALSE);
2876         if (result != XML_ERROR_NONE)            2876         if (result != XML_ERROR_NONE)
2877           return result;                         2877           return result;
2878       } else if (parser->m_externalEntityRefH    2878       } else if (parser->m_externalEntityRefHandler) {
2879         const XML_Char *context;                 2879         const XML_Char *context;
2880         entity->open = XML_TRUE;                 2880         entity->open = XML_TRUE;
2881         context = getContext(parser);            2881         context = getContext(parser);
2882         entity->open = XML_FALSE;                2882         entity->open = XML_FALSE;
2883         if (! context)                           2883         if (! context)
2884           return XML_ERROR_NO_MEMORY;            2884           return XML_ERROR_NO_MEMORY;
2885         if (! parser->m_externalEntityRefHand    2885         if (! parser->m_externalEntityRefHandler(
2886                 parser->m_externalEntityRefHa    2886                 parser->m_externalEntityRefHandlerArg, context, entity->base,
2887                 entity->systemId, entity->pub    2887                 entity->systemId, entity->publicId))
2888           return XML_ERROR_EXTERNAL_ENTITY_HA    2888           return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
2889         poolDiscard(&parser->m_tempPool);        2889         poolDiscard(&parser->m_tempPool);
2890       } else if (parser->m_defaultHandler)       2890       } else if (parser->m_defaultHandler)
2891         reportDefault(parser, enc, s, next);     2891         reportDefault(parser, enc, s, next);
2892       break;                                     2892       break;
2893     }                                            2893     }
2894     case XML_TOK_START_TAG_NO_ATTS:              2894     case XML_TOK_START_TAG_NO_ATTS:
2895       /* fall through */                         2895       /* fall through */
2896     case XML_TOK_START_TAG_WITH_ATTS: {          2896     case XML_TOK_START_TAG_WITH_ATTS: {
2897       TAG *tag;                                  2897       TAG *tag;
2898       enum XML_Error result;                     2898       enum XML_Error result;
2899       XML_Char *toPtr;                           2899       XML_Char *toPtr;
2900       if (parser->m_freeTagList) {               2900       if (parser->m_freeTagList) {
2901         tag = parser->m_freeTagList;             2901         tag = parser->m_freeTagList;
2902         parser->m_freeTagList = parser->m_fre    2902         parser->m_freeTagList = parser->m_freeTagList->parent;
2903       } else {                                   2903       } else {
2904         tag = (TAG *)MALLOC(parser, sizeof(TA    2904         tag = (TAG *)MALLOC(parser, sizeof(TAG));
2905         if (! tag)                               2905         if (! tag)
2906           return XML_ERROR_NO_MEMORY;            2906           return XML_ERROR_NO_MEMORY;
2907         tag->buf = (char *)MALLOC(parser, INI    2907         tag->buf = (char *)MALLOC(parser, INIT_TAG_BUF_SIZE);
2908         if (! tag->buf) {                        2908         if (! tag->buf) {
2909           FREE(parser, tag);                     2909           FREE(parser, tag);
2910           return XML_ERROR_NO_MEMORY;            2910           return XML_ERROR_NO_MEMORY;
2911         }                                        2911         }
2912         tag->bufEnd = tag->buf + INIT_TAG_BUF    2912         tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
2913       }                                          2913       }
2914       tag->bindings = NULL;                      2914       tag->bindings = NULL;
2915       tag->parent = parser->m_tagStack;          2915       tag->parent = parser->m_tagStack;
2916       parser->m_tagStack = tag;                  2916       parser->m_tagStack = tag;
2917       tag->name.localPart = NULL;                2917       tag->name.localPart = NULL;
2918       tag->name.prefix = NULL;                   2918       tag->name.prefix = NULL;
2919       tag->rawName = s + enc->minBytesPerChar    2919       tag->rawName = s + enc->minBytesPerChar;
2920       tag->rawNameLength = XmlNameLength(enc,    2920       tag->rawNameLength = XmlNameLength(enc, tag->rawName);
2921       ++parser->m_tagLevel;                      2921       ++parser->m_tagLevel;
2922       {                                          2922       {
2923         const char *rawNameEnd = tag->rawName    2923         const char *rawNameEnd = tag->rawName + tag->rawNameLength;
2924         const char *fromPtr = tag->rawName;      2924         const char *fromPtr = tag->rawName;
2925         toPtr = (XML_Char *)tag->buf;            2925         toPtr = (XML_Char *)tag->buf;
2926         for (;;) {                               2926         for (;;) {
2927           int bufSize;                           2927           int bufSize;
2928           int convLen;                           2928           int convLen;
2929           const enum XML_Convert_Result conve    2929           const enum XML_Convert_Result convert_res
2930               = XmlConvert(enc, &fromPtr, raw    2930               = XmlConvert(enc, &fromPtr, rawNameEnd, (ICHAR **)&toPtr,
2931                            (ICHAR *)tag->bufE    2931                            (ICHAR *)tag->bufEnd - 1);
2932           convLen = (int)(toPtr - (XML_Char *    2932           convLen = (int)(toPtr - (XML_Char *)tag->buf);
2933           if ((fromPtr >= rawNameEnd)            2933           if ((fromPtr >= rawNameEnd)
2934               || (convert_res == XML_CONVERT_    2934               || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) {
2935             tag->name.strLen = convLen;          2935             tag->name.strLen = convLen;
2936             break;                               2936             break;
2937           }                                      2937           }
2938           bufSize = (int)(tag->bufEnd - tag->    2938           bufSize = (int)(tag->bufEnd - tag->buf) << 1;
2939           {                                      2939           {
2940             char *temp = (char *)REALLOC(pars    2940             char *temp = (char *)REALLOC(parser, tag->buf, bufSize);
2941             if (temp == NULL)                    2941             if (temp == NULL)
2942               return XML_ERROR_NO_MEMORY;        2942               return XML_ERROR_NO_MEMORY;
2943             tag->buf = temp;                     2943             tag->buf = temp;
2944             tag->bufEnd = temp + bufSize;        2944             tag->bufEnd = temp + bufSize;
2945             toPtr = (XML_Char *)temp + convLe    2945             toPtr = (XML_Char *)temp + convLen;
2946           }                                      2946           }
2947         }                                        2947         }
2948       }                                          2948       }
2949       tag->name.str = (XML_Char *)tag->buf;      2949       tag->name.str = (XML_Char *)tag->buf;
2950       *toPtr = XML_T('\0');                      2950       *toPtr = XML_T('\0');
2951       result                                     2951       result
2952           = storeAtts(parser, enc, s, &(tag->    2952           = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings), account);
2953       if (result)                                2953       if (result)
2954         return result;                           2954         return result;
2955       if (parser->m_startElementHandler)         2955       if (parser->m_startElementHandler)
2956         parser->m_startElementHandler(parser-    2956         parser->m_startElementHandler(parser->m_handlerArg, tag->name.str,
2957                                       (const     2957                                       (const XML_Char **)parser->m_atts);
2958       else if (parser->m_defaultHandler)         2958       else if (parser->m_defaultHandler)
2959         reportDefault(parser, enc, s, next);     2959         reportDefault(parser, enc, s, next);
2960       poolClear(&parser->m_tempPool);            2960       poolClear(&parser->m_tempPool);
2961       break;                                     2961       break;
2962     }                                            2962     }
2963     case XML_TOK_EMPTY_ELEMENT_NO_ATTS:          2963     case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
2964       /* fall through */                         2964       /* fall through */
2965     case XML_TOK_EMPTY_ELEMENT_WITH_ATTS: {      2965     case XML_TOK_EMPTY_ELEMENT_WITH_ATTS: {
2966       const char *rawName = s + enc->minBytes    2966       const char *rawName = s + enc->minBytesPerChar;
2967       enum XML_Error result;                     2967       enum XML_Error result;
2968       BINDING *bindings = NULL;                  2968       BINDING *bindings = NULL;
2969       XML_Bool noElmHandlers = XML_TRUE;         2969       XML_Bool noElmHandlers = XML_TRUE;
2970       TAG_NAME name;                             2970       TAG_NAME name;
2971       name.str = poolStoreString(&parser->m_t    2971       name.str = poolStoreString(&parser->m_tempPool, enc, rawName,
2972                                  rawName + Xm    2972                                  rawName + XmlNameLength(enc, rawName));
2973       if (! name.str)                            2973       if (! name.str)
2974         return XML_ERROR_NO_MEMORY;              2974         return XML_ERROR_NO_MEMORY;
2975       poolFinish(&parser->m_tempPool);           2975       poolFinish(&parser->m_tempPool);
2976       result = storeAtts(parser, enc, s, &nam    2976       result = storeAtts(parser, enc, s, &name, &bindings,
2977                          XML_ACCOUNT_NONE /*     2977                          XML_ACCOUNT_NONE /* token spans whole start tag */);
2978       if (result != XML_ERROR_NONE) {            2978       if (result != XML_ERROR_NONE) {
2979         freeBindings(parser, bindings);          2979         freeBindings(parser, bindings);
2980         return result;                           2980         return result;
2981       }                                          2981       }
2982       poolFinish(&parser->m_tempPool);           2982       poolFinish(&parser->m_tempPool);
2983       if (parser->m_startElementHandler) {       2983       if (parser->m_startElementHandler) {
2984         parser->m_startElementHandler(parser-    2984         parser->m_startElementHandler(parser->m_handlerArg, name.str,
2985                                       (const     2985                                       (const XML_Char **)parser->m_atts);
2986         noElmHandlers = XML_FALSE;               2986         noElmHandlers = XML_FALSE;
2987       }                                          2987       }
2988       if (parser->m_endElementHandler) {         2988       if (parser->m_endElementHandler) {
2989         if (parser->m_startElementHandler)       2989         if (parser->m_startElementHandler)
2990           *eventPP = *eventEndPP;                2990           *eventPP = *eventEndPP;
2991         parser->m_endElementHandler(parser->m    2991         parser->m_endElementHandler(parser->m_handlerArg, name.str);
2992         noElmHandlers = XML_FALSE;               2992         noElmHandlers = XML_FALSE;
2993       }                                          2993       }
2994       if (noElmHandlers && parser->m_defaultH    2994       if (noElmHandlers && parser->m_defaultHandler)
2995         reportDefault(parser, enc, s, next);     2995         reportDefault(parser, enc, s, next);
2996       poolClear(&parser->m_tempPool);            2996       poolClear(&parser->m_tempPool);
2997       freeBindings(parser, bindings);            2997       freeBindings(parser, bindings);
2998     }                                            2998     }
2999       if ((parser->m_tagLevel == 0)              2999       if ((parser->m_tagLevel == 0)
3000           && (parser->m_parsingStatus.parsing    3000           && (parser->m_parsingStatus.parsing != XML_FINISHED)) {
3001         if (parser->m_parsingStatus.parsing =    3001         if (parser->m_parsingStatus.parsing == XML_SUSPENDED)
3002           parser->m_processor = epilogProcess    3002           parser->m_processor = epilogProcessor;
3003         else                                     3003         else
3004           return epilogProcessor(parser, next    3004           return epilogProcessor(parser, next, end, nextPtr);
3005       }                                          3005       }
3006       break;                                     3006       break;
3007     case XML_TOK_END_TAG:                        3007     case XML_TOK_END_TAG:
3008       if (parser->m_tagLevel == startTagLevel    3008       if (parser->m_tagLevel == startTagLevel)
3009         return XML_ERROR_ASYNC_ENTITY;           3009         return XML_ERROR_ASYNC_ENTITY;
3010       else {                                     3010       else {
3011         int len;                                 3011         int len;
3012         const char *rawName;                     3012         const char *rawName;
3013         TAG *tag = parser->m_tagStack;           3013         TAG *tag = parser->m_tagStack;
3014         parser->m_tagStack = tag->parent;        3014         parser->m_tagStack = tag->parent;
3015         tag->parent = parser->m_freeTagList;     3015         tag->parent = parser->m_freeTagList;
3016         parser->m_freeTagList = tag;             3016         parser->m_freeTagList = tag;
3017         rawName = s + enc->minBytesPerChar *     3017         rawName = s + enc->minBytesPerChar * 2;
3018         len = XmlNameLength(enc, rawName);       3018         len = XmlNameLength(enc, rawName);
3019         if (len != tag->rawNameLength            3019         if (len != tag->rawNameLength
3020             || memcmp(tag->rawName, rawName,     3020             || memcmp(tag->rawName, rawName, len) != 0) {
3021           *eventPP = rawName;                    3021           *eventPP = rawName;
3022           return XML_ERROR_TAG_MISMATCH;         3022           return XML_ERROR_TAG_MISMATCH;
3023         }                                        3023         }
3024         --parser->m_tagLevel;                    3024         --parser->m_tagLevel;
3025         if (parser->m_endElementHandler) {       3025         if (parser->m_endElementHandler) {
3026           const XML_Char *localPart;             3026           const XML_Char *localPart;
3027           const XML_Char *prefix;                3027           const XML_Char *prefix;
3028           XML_Char *uri;                         3028           XML_Char *uri;
3029           localPart = tag->name.localPart;       3029           localPart = tag->name.localPart;
3030           if (parser->m_ns && localPart) {       3030           if (parser->m_ns && localPart) {
3031             /* localPart and prefix may have     3031             /* localPart and prefix may have been overwritten in
3032                tag->name.str, since this poin    3032                tag->name.str, since this points to the binding->uri
3033                buffer which gets re-used; so     3033                buffer which gets re-used; so we have to add them again
3034             */                                   3034             */
3035             uri = (XML_Char *)tag->name.str +    3035             uri = (XML_Char *)tag->name.str + tag->name.uriLen;
3036             /* don't need to check for space     3036             /* don't need to check for space - already done in storeAtts() */
3037             while (*localPart)                   3037             while (*localPart)
3038               *uri++ = *localPart++;             3038               *uri++ = *localPart++;
3039             prefix = (XML_Char *)tag->name.pr    3039             prefix = (XML_Char *)tag->name.prefix;
3040             if (parser->m_ns_triplets && pref    3040             if (parser->m_ns_triplets && prefix) {
3041               *uri++ = parser->m_namespaceSep    3041               *uri++ = parser->m_namespaceSeparator;
3042               while (*prefix)                    3042               while (*prefix)
3043                 *uri++ = *prefix++;              3043                 *uri++ = *prefix++;
3044             }                                    3044             }
3045             *uri = XML_T('\0');                  3045             *uri = XML_T('\0');
3046           }                                      3046           }
3047           parser->m_endElementHandler(parser-    3047           parser->m_endElementHandler(parser->m_handlerArg, tag->name.str);
3048         } else if (parser->m_defaultHandler)     3048         } else if (parser->m_defaultHandler)
3049           reportDefault(parser, enc, s, next)    3049           reportDefault(parser, enc, s, next);
3050         while (tag->bindings) {                  3050         while (tag->bindings) {
3051           BINDING *b = tag->bindings;            3051           BINDING *b = tag->bindings;
3052           if (parser->m_endNamespaceDeclHandl    3052           if (parser->m_endNamespaceDeclHandler)
3053             parser->m_endNamespaceDeclHandler    3053             parser->m_endNamespaceDeclHandler(parser->m_handlerArg,
3054                                                  3054                                               b->prefix->name);
3055           tag->bindings = tag->bindings->next    3055           tag->bindings = tag->bindings->nextTagBinding;
3056           b->nextTagBinding = parser->m_freeB    3056           b->nextTagBinding = parser->m_freeBindingList;
3057           parser->m_freeBindingList = b;         3057           parser->m_freeBindingList = b;
3058           b->prefix->binding = b->prevPrefixB    3058           b->prefix->binding = b->prevPrefixBinding;
3059         }                                        3059         }
3060         if ((parser->m_tagLevel == 0)            3060         if ((parser->m_tagLevel == 0)
3061             && (parser->m_parsingStatus.parsi    3061             && (parser->m_parsingStatus.parsing != XML_FINISHED)) {
3062           if (parser->m_parsingStatus.parsing    3062           if (parser->m_parsingStatus.parsing == XML_SUSPENDED)
3063             parser->m_processor = epilogProce    3063             parser->m_processor = epilogProcessor;
3064           else                                   3064           else
3065             return epilogProcessor(parser, ne    3065             return epilogProcessor(parser, next, end, nextPtr);
3066         }                                        3066         }
3067       }                                          3067       }
3068       break;                                     3068       break;
3069     case XML_TOK_CHAR_REF: {                     3069     case XML_TOK_CHAR_REF: {
3070       int n = XmlCharRefNumber(enc, s);          3070       int n = XmlCharRefNumber(enc, s);
3071       if (n < 0)                                 3071       if (n < 0)
3072         return XML_ERROR_BAD_CHAR_REF;           3072         return XML_ERROR_BAD_CHAR_REF;
3073       if (parser->m_characterDataHandler) {      3073       if (parser->m_characterDataHandler) {
3074         XML_Char buf[XML_ENCODE_MAX];            3074         XML_Char buf[XML_ENCODE_MAX];
3075         parser->m_characterDataHandler(parser    3075         parser->m_characterDataHandler(parser->m_handlerArg, buf,
3076                                        XmlEnc    3076                                        XmlEncode(n, (ICHAR *)buf));
3077       } else if (parser->m_defaultHandler)       3077       } else if (parser->m_defaultHandler)
3078         reportDefault(parser, enc, s, next);     3078         reportDefault(parser, enc, s, next);
3079     } break;                                     3079     } break;
3080     case XML_TOK_XML_DECL:                       3080     case XML_TOK_XML_DECL:
3081       return XML_ERROR_MISPLACED_XML_PI;         3081       return XML_ERROR_MISPLACED_XML_PI;
3082     case XML_TOK_DATA_NEWLINE:                   3082     case XML_TOK_DATA_NEWLINE:
3083       if (parser->m_characterDataHandler) {      3083       if (parser->m_characterDataHandler) {
3084         XML_Char c = 0xA;                        3084         XML_Char c = 0xA;
3085         parser->m_characterDataHandler(parser    3085         parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
3086       } else if (parser->m_defaultHandler)       3086       } else if (parser->m_defaultHandler)
3087         reportDefault(parser, enc, s, next);     3087         reportDefault(parser, enc, s, next);
3088       break;                                     3088       break;
3089     case XML_TOK_CDATA_SECT_OPEN: {              3089     case XML_TOK_CDATA_SECT_OPEN: {
3090       enum XML_Error result;                     3090       enum XML_Error result;
3091       if (parser->m_startCdataSectionHandler)    3091       if (parser->m_startCdataSectionHandler)
3092         parser->m_startCdataSectionHandler(pa    3092         parser->m_startCdataSectionHandler(parser->m_handlerArg);
3093       /* BEGIN disabled code */                  3093       /* BEGIN disabled code */
3094       /* Suppose you doing a transformation o    3094       /* Suppose you doing a transformation on a document that involves
3095          changing only the character data.  Y    3095          changing only the character data.  You set up a defaultHandler
3096          and a characterDataHandler.  The def    3096          and a characterDataHandler.  The defaultHandler simply copies
3097          characters through.  The characterDa    3097          characters through.  The characterDataHandler does the
3098          transformation and writes the charac    3098          transformation and writes the characters out escaping them as
3099          necessary.  This case will fail to w    3099          necessary.  This case will fail to work if we leave out the
3100          following two lines (because & and <    3100          following two lines (because & and < inside CDATA sections will
3101          be incorrectly escaped).                3101          be incorrectly escaped).
3102                                                  3102 
3103          However, now we have a start/endCdat    3103          However, now we have a start/endCdataSectionHandler, so it seems
3104          easier to let the user deal with thi    3104          easier to let the user deal with this.
3105       */                                         3105       */
3106       else if (0 && parser->m_characterDataHa    3106       else if (0 && parser->m_characterDataHandler)
3107         parser->m_characterDataHandler(parser    3107         parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf,
3108                                        0);       3108                                        0);
3109       /* END disabled code */                    3109       /* END disabled code */
3110       else if (parser->m_defaultHandler)         3110       else if (parser->m_defaultHandler)
3111         reportDefault(parser, enc, s, next);     3111         reportDefault(parser, enc, s, next);
3112       result                                     3112       result
3113           = doCdataSection(parser, enc, &next    3113           = doCdataSection(parser, enc, &next, end, nextPtr, haveMore, account);
3114       if (result != XML_ERROR_NONE)              3114       if (result != XML_ERROR_NONE)
3115         return result;                           3115         return result;
3116       else if (! next) {                         3116       else if (! next) {
3117         parser->m_processor = cdataSectionPro    3117         parser->m_processor = cdataSectionProcessor;
3118         return result;                           3118         return result;
3119       }                                          3119       }
3120     } break;                                     3120     } break;
3121     case XML_TOK_TRAILING_RSQB:                  3121     case XML_TOK_TRAILING_RSQB:
3122       if (haveMore) {                            3122       if (haveMore) {
3123         *nextPtr = s;                            3123         *nextPtr = s;
3124         return XML_ERROR_NONE;                   3124         return XML_ERROR_NONE;
3125       }                                          3125       }
3126       if (parser->m_characterDataHandler) {      3126       if (parser->m_characterDataHandler) {
3127         if (MUST_CONVERT(enc, s)) {              3127         if (MUST_CONVERT(enc, s)) {
3128           ICHAR *dataPtr = (ICHAR *)parser->m    3128           ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
3129           XmlConvert(enc, &s, end, &dataPtr,     3129           XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
3130           parser->m_characterDataHandler(        3130           parser->m_characterDataHandler(
3131               parser->m_handlerArg, parser->m    3131               parser->m_handlerArg, parser->m_dataBuf,
3132               (int)(dataPtr - (ICHAR *)parser    3132               (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
3133         } else                                   3133         } else
3134           parser->m_characterDataHandler(        3134           parser->m_characterDataHandler(
3135               parser->m_handlerArg, (XML_Char    3135               parser->m_handlerArg, (XML_Char *)s,
3136               (int)((XML_Char *)end - (XML_Ch    3136               (int)((XML_Char *)end - (XML_Char *)s));
3137       } else if (parser->m_defaultHandler)       3137       } else if (parser->m_defaultHandler)
3138         reportDefault(parser, enc, s, end);      3138         reportDefault(parser, enc, s, end);
3139       /* We are at the end of the final buffe    3139       /* We are at the end of the final buffer, should we check for
3140          XML_SUSPENDED, XML_FINISHED?            3140          XML_SUSPENDED, XML_FINISHED?
3141       */                                         3141       */
3142       if (startTagLevel == 0) {                  3142       if (startTagLevel == 0) {
3143         *eventPP = end;                          3143         *eventPP = end;
3144         return XML_ERROR_NO_ELEMENTS;            3144         return XML_ERROR_NO_ELEMENTS;
3145       }                                          3145       }
3146       if (parser->m_tagLevel != startTagLevel    3146       if (parser->m_tagLevel != startTagLevel) {
3147         *eventPP = end;                          3147         *eventPP = end;
3148         return XML_ERROR_ASYNC_ENTITY;           3148         return XML_ERROR_ASYNC_ENTITY;
3149       }                                          3149       }
3150       *nextPtr = end;                            3150       *nextPtr = end;
3151       return XML_ERROR_NONE;                     3151       return XML_ERROR_NONE;
3152     case XML_TOK_DATA_CHARS: {                   3152     case XML_TOK_DATA_CHARS: {
3153       XML_CharacterDataHandler charDataHandle    3153       XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler;
3154       if (charDataHandler) {                     3154       if (charDataHandler) {
3155         if (MUST_CONVERT(enc, s)) {              3155         if (MUST_CONVERT(enc, s)) {
3156           for (;;) {                             3156           for (;;) {
3157             ICHAR *dataPtr = (ICHAR *)parser-    3157             ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
3158             const enum XML_Convert_Result con    3158             const enum XML_Convert_Result convert_res = XmlConvert(
3159                 enc, &s, next, &dataPtr, (ICH    3159                 enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
3160             *eventEndPP = s;                     3160             *eventEndPP = s;
3161             charDataHandler(parser->m_handler    3161             charDataHandler(parser->m_handlerArg, parser->m_dataBuf,
3162                             (int)(dataPtr - (    3162                             (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
3163             if ((convert_res == XML_CONVERT_C    3163             if ((convert_res == XML_CONVERT_COMPLETED)
3164                 || (convert_res == XML_CONVER    3164                 || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
3165               break;                             3165               break;
3166             *eventPP = s;                        3166             *eventPP = s;
3167           }                                      3167           }
3168         } else                                   3168         } else
3169           charDataHandler(parser->m_handlerAr    3169           charDataHandler(parser->m_handlerArg, (XML_Char *)s,
3170                           (int)((XML_Char *)n    3170                           (int)((XML_Char *)next - (XML_Char *)s));
3171       } else if (parser->m_defaultHandler)       3171       } else if (parser->m_defaultHandler)
3172         reportDefault(parser, enc, s, next);     3172         reportDefault(parser, enc, s, next);
3173     } break;                                     3173     } break;
3174     case XML_TOK_PI:                             3174     case XML_TOK_PI:
3175       if (! reportProcessingInstruction(parse    3175       if (! reportProcessingInstruction(parser, enc, s, next))
3176         return XML_ERROR_NO_MEMORY;              3176         return XML_ERROR_NO_MEMORY;
3177       break;                                     3177       break;
3178     case XML_TOK_COMMENT:                        3178     case XML_TOK_COMMENT:
3179       if (! reportComment(parser, enc, s, nex    3179       if (! reportComment(parser, enc, s, next))
3180         return XML_ERROR_NO_MEMORY;              3180         return XML_ERROR_NO_MEMORY;
3181       break;                                     3181       break;
3182     default:                                     3182     default:
3183       /* All of the tokens produced by XmlCon    3183       /* All of the tokens produced by XmlContentTok() have their own
3184        * explicit cases, so this default is n    3184        * explicit cases, so this default is not strictly necessary.
3185        * However it is a useful safety net, s    3185        * However it is a useful safety net, so we retain the code and
3186        * simply exclude it from the coverage     3186        * simply exclude it from the coverage tests.
3187        *                                         3187        *
3188        * LCOV_EXCL_START                         3188        * LCOV_EXCL_START
3189        */                                        3189        */
3190       if (parser->m_defaultHandler)              3190       if (parser->m_defaultHandler)
3191         reportDefault(parser, enc, s, next);     3191         reportDefault(parser, enc, s, next);
3192       break;                                     3192       break;
3193       /* LCOV_EXCL_STOP */                       3193       /* LCOV_EXCL_STOP */
3194     }                                            3194     }
3195     *eventPP = s = next;                         3195     *eventPP = s = next;
3196     switch (parser->m_parsingStatus.parsing)     3196     switch (parser->m_parsingStatus.parsing) {
3197     case XML_SUSPENDED:                          3197     case XML_SUSPENDED:
3198       *nextPtr = next;                           3198       *nextPtr = next;
3199       return XML_ERROR_NONE;                     3199       return XML_ERROR_NONE;
3200     case XML_FINISHED:                           3200     case XML_FINISHED:
3201       return XML_ERROR_ABORTED;                  3201       return XML_ERROR_ABORTED;
3202     default:;                                    3202     default:;
3203     }                                            3203     }
3204   }                                              3204   }
3205   /* not reached */                              3205   /* not reached */
3206 }                                                3206 }
3207                                                  3207 
3208 /* This function does not call free() on the     3208 /* This function does not call free() on the allocated memory, merely
3209  * moving it to the parser's m_freeBindingLis    3209  * moving it to the parser's m_freeBindingList where it can be freed or
3210  * reused as appropriate.                        3210  * reused as appropriate.
3211  */                                              3211  */
3212 static void                                      3212 static void
3213 freeBindings(XML_Parser parser, BINDING *bind    3213 freeBindings(XML_Parser parser, BINDING *bindings) {
3214   while (bindings) {                             3214   while (bindings) {
3215     BINDING *b = bindings;                       3215     BINDING *b = bindings;
3216                                                  3216 
3217     /* m_startNamespaceDeclHandler will have     3217     /* m_startNamespaceDeclHandler will have been called for this
3218      * binding in addBindings(), so call the     3218      * binding in addBindings(), so call the end handler now.
3219      */                                          3219      */
3220     if (parser->m_endNamespaceDeclHandler)       3220     if (parser->m_endNamespaceDeclHandler)
3221       parser->m_endNamespaceDeclHandler(parse    3221       parser->m_endNamespaceDeclHandler(parser->m_handlerArg, b->prefix->name);
3222                                                  3222 
3223     bindings = bindings->nextTagBinding;         3223     bindings = bindings->nextTagBinding;
3224     b->nextTagBinding = parser->m_freeBinding    3224     b->nextTagBinding = parser->m_freeBindingList;
3225     parser->m_freeBindingList = b;               3225     parser->m_freeBindingList = b;
3226     b->prefix->binding = b->prevPrefixBinding    3226     b->prefix->binding = b->prevPrefixBinding;
3227   }                                              3227   }
3228 }                                                3228 }
3229                                                  3229 
3230 /* Precondition: all arguments must be non-NU    3230 /* Precondition: all arguments must be non-NULL;
3231    Purpose:                                      3231    Purpose:
3232    - normalize attributes                        3232    - normalize attributes
3233    - check attributes for well-formedness        3233    - check attributes for well-formedness
3234    - generate namespace aware attribute names    3234    - generate namespace aware attribute names (URI, prefix)
3235    - build list of attributes for startElemen    3235    - build list of attributes for startElementHandler
3236    - default attributes                          3236    - default attributes
3237    - process namespace declarations (check an    3237    - process namespace declarations (check and report them)
3238    - generate namespace aware element name (U    3238    - generate namespace aware element name (URI, prefix)
3239 */                                               3239 */
3240 static enum XML_Error                            3240 static enum XML_Error
3241 storeAtts(XML_Parser parser, const ENCODING *    3241 storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
3242           TAG_NAME *tagNamePtr, BINDING **bin    3242           TAG_NAME *tagNamePtr, BINDING **bindingsPtr,
3243           enum XML_Account account) {            3243           enum XML_Account account) {
3244   DTD *const dtd = parser->m_dtd; /* save one    3244   DTD *const dtd = parser->m_dtd; /* save one level of indirection */
3245   ELEMENT_TYPE *elementType;                     3245   ELEMENT_TYPE *elementType;
3246   int nDefaultAtts;                              3246   int nDefaultAtts;
3247   const XML_Char **appAtts; /* the attribute     3247   const XML_Char **appAtts; /* the attribute list for the application */
3248   int attIndex = 0;                              3248   int attIndex = 0;
3249   int prefixLen;                                 3249   int prefixLen;
3250   int i;                                         3250   int i;
3251   int n;                                         3251   int n;
3252   XML_Char *uri;                                 3252   XML_Char *uri;
3253   int nPrefixes = 0;                             3253   int nPrefixes = 0;
3254   BINDING *binding;                              3254   BINDING *binding;
3255   const XML_Char *localPart;                     3255   const XML_Char *localPart;
3256                                                  3256 
3257   /* lookup the element type name */             3257   /* lookup the element type name */
3258   elementType                                    3258   elementType
3259       = (ELEMENT_TYPE *)lookup(parser, &dtd->    3259       = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str, 0);
3260   if (! elementType) {                           3260   if (! elementType) {
3261     const XML_Char *name = poolCopyString(&dt    3261     const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
3262     if (! name)                                  3262     if (! name)
3263       return XML_ERROR_NO_MEMORY;                3263       return XML_ERROR_NO_MEMORY;
3264     elementType = (ELEMENT_TYPE *)lookup(pars    3264     elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
3265                                          size    3265                                          sizeof(ELEMENT_TYPE));
3266     if (! elementType)                           3266     if (! elementType)
3267       return XML_ERROR_NO_MEMORY;                3267       return XML_ERROR_NO_MEMORY;
3268     if (parser->m_ns && ! setElementTypePrefi    3268     if (parser->m_ns && ! setElementTypePrefix(parser, elementType))
3269       return XML_ERROR_NO_MEMORY;                3269       return XML_ERROR_NO_MEMORY;
3270   }                                              3270   }
3271   nDefaultAtts = elementType->nDefaultAtts;      3271   nDefaultAtts = elementType->nDefaultAtts;
3272                                                  3272 
3273   /* get the attributes from the tokenizer */    3273   /* get the attributes from the tokenizer */
3274   n = XmlGetAttributes(enc, attStr, parser->m    3274   n = XmlGetAttributes(enc, attStr, parser->m_attsSize, parser->m_atts);
3275                                                  3275 
3276   /* Detect and prevent integer overflow */      3276   /* Detect and prevent integer overflow */
3277   if (n > INT_MAX - nDefaultAtts) {              3277   if (n > INT_MAX - nDefaultAtts) {
3278     return XML_ERROR_NO_MEMORY;                  3278     return XML_ERROR_NO_MEMORY;
3279   }                                              3279   }
3280                                                  3280 
3281   if (n + nDefaultAtts > parser->m_attsSize)     3281   if (n + nDefaultAtts > parser->m_attsSize) {
3282     int oldAttsSize = parser->m_attsSize;        3282     int oldAttsSize = parser->m_attsSize;
3283     ATTRIBUTE *temp;                             3283     ATTRIBUTE *temp;
3284 #ifdef XML_ATTR_INFO                             3284 #ifdef XML_ATTR_INFO
3285     XML_AttrInfo *temp2;                         3285     XML_AttrInfo *temp2;
3286 #endif                                           3286 #endif
3287                                                  3287 
3288     /* Detect and prevent integer overflow */    3288     /* Detect and prevent integer overflow */
3289     if ((nDefaultAtts > INT_MAX - INIT_ATTS_S    3289     if ((nDefaultAtts > INT_MAX - INIT_ATTS_SIZE)
3290         || (n > INT_MAX - (nDefaultAtts + INI    3290         || (n > INT_MAX - (nDefaultAtts + INIT_ATTS_SIZE))) {
3291       return XML_ERROR_NO_MEMORY;                3291       return XML_ERROR_NO_MEMORY;
3292     }                                            3292     }
3293                                                  3293 
3294     parser->m_attsSize = n + nDefaultAtts + I    3294     parser->m_attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
3295                                                  3295 
3296     /* Detect and prevent integer overflow.      3296     /* Detect and prevent integer overflow.
3297      * The preprocessor guard addresses the "    3297      * The preprocessor guard addresses the "always false" warning
3298      * from -Wtype-limits on platforms where     3298      * from -Wtype-limits on platforms where
3299      * sizeof(unsigned int) < sizeof(size_t),    3299      * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
3300 #if UINT_MAX >= SIZE_MAX                         3300 #if UINT_MAX >= SIZE_MAX
3301     if ((unsigned)parser->m_attsSize > (size_    3301     if ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(ATTRIBUTE)) {
3302       parser->m_attsSize = oldAttsSize;          3302       parser->m_attsSize = oldAttsSize;
3303       return XML_ERROR_NO_MEMORY;                3303       return XML_ERROR_NO_MEMORY;
3304     }                                            3304     }
3305 #endif                                           3305 #endif
3306                                                  3306 
3307     temp = (ATTRIBUTE *)REALLOC(parser, (void    3307     temp = (ATTRIBUTE *)REALLOC(parser, (void *)parser->m_atts,
3308                                 parser->m_att    3308                                 parser->m_attsSize * sizeof(ATTRIBUTE));
3309     if (temp == NULL) {                          3309     if (temp == NULL) {
3310       parser->m_attsSize = oldAttsSize;          3310       parser->m_attsSize = oldAttsSize;
3311       return XML_ERROR_NO_MEMORY;                3311       return XML_ERROR_NO_MEMORY;
3312     }                                            3312     }
3313     parser->m_atts = temp;                       3313     parser->m_atts = temp;
3314 #ifdef XML_ATTR_INFO                             3314 #ifdef XML_ATTR_INFO
3315     /* Detect and prevent integer overflow.      3315     /* Detect and prevent integer overflow.
3316      * The preprocessor guard addresses the "    3316      * The preprocessor guard addresses the "always false" warning
3317      * from -Wtype-limits on platforms where     3317      * from -Wtype-limits on platforms where
3318      * sizeof(unsigned int) < sizeof(size_t),    3318      * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
3319 #  if UINT_MAX >= SIZE_MAX                       3319 #  if UINT_MAX >= SIZE_MAX
3320     if ((unsigned)parser->m_attsSize > (size_    3320     if ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(XML_AttrInfo)) {
3321       parser->m_attsSize = oldAttsSize;          3321       parser->m_attsSize = oldAttsSize;
3322       return XML_ERROR_NO_MEMORY;                3322       return XML_ERROR_NO_MEMORY;
3323     }                                            3323     }
3324 #  endif                                         3324 #  endif
3325                                                  3325 
3326     temp2 = (XML_AttrInfo *)REALLOC(parser, (    3326     temp2 = (XML_AttrInfo *)REALLOC(parser, (void *)parser->m_attInfo,
3327                                     parser->m    3327                                     parser->m_attsSize * sizeof(XML_AttrInfo));
3328     if (temp2 == NULL) {                         3328     if (temp2 == NULL) {
3329       parser->m_attsSize = oldAttsSize;          3329       parser->m_attsSize = oldAttsSize;
3330       return XML_ERROR_NO_MEMORY;                3330       return XML_ERROR_NO_MEMORY;
3331     }                                            3331     }
3332     parser->m_attInfo = temp2;                   3332     parser->m_attInfo = temp2;
3333 #endif                                           3333 #endif
3334     if (n > oldAttsSize)                         3334     if (n > oldAttsSize)
3335       XmlGetAttributes(enc, attStr, n, parser    3335       XmlGetAttributes(enc, attStr, n, parser->m_atts);
3336   }                                              3336   }
3337                                                  3337 
3338   appAtts = (const XML_Char **)parser->m_atts    3338   appAtts = (const XML_Char **)parser->m_atts;
3339   for (i = 0; i < n; i++) {                      3339   for (i = 0; i < n; i++) {
3340     ATTRIBUTE *currAtt = &parser->m_atts[i];     3340     ATTRIBUTE *currAtt = &parser->m_atts[i];
3341 #ifdef XML_ATTR_INFO                             3341 #ifdef XML_ATTR_INFO
3342     XML_AttrInfo *currAttInfo = &parser->m_at    3342     XML_AttrInfo *currAttInfo = &parser->m_attInfo[i];
3343 #endif                                           3343 #endif
3344     /* add the name and value to the attribut    3344     /* add the name and value to the attribute list */
3345     ATTRIBUTE_ID *attId                          3345     ATTRIBUTE_ID *attId
3346         = getAttributeId(parser, enc, currAtt    3346         = getAttributeId(parser, enc, currAtt->name,
3347                          currAtt->name + XmlN    3347                          currAtt->name + XmlNameLength(enc, currAtt->name));
3348     if (! attId)                                 3348     if (! attId)
3349       return XML_ERROR_NO_MEMORY;                3349       return XML_ERROR_NO_MEMORY;
3350 #ifdef XML_ATTR_INFO                             3350 #ifdef XML_ATTR_INFO
3351     currAttInfo->nameStart                       3351     currAttInfo->nameStart
3352         = parser->m_parseEndByteIndex - (pars    3352         = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->name);
3353     currAttInfo->nameEnd                         3353     currAttInfo->nameEnd
3354         = currAttInfo->nameStart + XmlNameLen    3354         = currAttInfo->nameStart + XmlNameLength(enc, currAtt->name);
3355     currAttInfo->valueStart = parser->m_parse    3355     currAttInfo->valueStart = parser->m_parseEndByteIndex
3356                               - (parser->m_pa    3356                               - (parser->m_parseEndPtr - currAtt->valuePtr);
3357     currAttInfo->valueEnd = parser->m_parseEn    3357     currAttInfo->valueEnd = parser->m_parseEndByteIndex
3358                             - (parser->m_pars    3358                             - (parser->m_parseEndPtr - currAtt->valueEnd);
3359 #endif                                           3359 #endif
3360     /* Detect duplicate attributes by their Q    3360     /* Detect duplicate attributes by their QNames. This does not work when
3361        namespace processing is turned on and     3361        namespace processing is turned on and different prefixes for the same
3362        namespace are used. For this case we h    3362        namespace are used. For this case we have a check further down.
3363     */                                           3363     */
3364     if ((attId->name)[-1]) {                     3364     if ((attId->name)[-1]) {
3365       if (enc == parser->m_encoding)             3365       if (enc == parser->m_encoding)
3366         parser->m_eventPtr = parser->m_atts[i    3366         parser->m_eventPtr = parser->m_atts[i].name;
3367       return XML_ERROR_DUPLICATE_ATTRIBUTE;      3367       return XML_ERROR_DUPLICATE_ATTRIBUTE;
3368     }                                            3368     }
3369     (attId->name)[-1] = 1;                       3369     (attId->name)[-1] = 1;
3370     appAtts[attIndex++] = attId->name;           3370     appAtts[attIndex++] = attId->name;
3371     if (! parser->m_atts[i].normalized) {        3371     if (! parser->m_atts[i].normalized) {
3372       enum XML_Error result;                     3372       enum XML_Error result;
3373       XML_Bool isCdata = XML_TRUE;               3373       XML_Bool isCdata = XML_TRUE;
3374                                                  3374 
3375       /* figure out whether declared as other    3375       /* figure out whether declared as other than CDATA */
3376       if (attId->maybeTokenized) {               3376       if (attId->maybeTokenized) {
3377         int j;                                   3377         int j;
3378         for (j = 0; j < nDefaultAtts; j++) {     3378         for (j = 0; j < nDefaultAtts; j++) {
3379           if (attId == elementType->defaultAt    3379           if (attId == elementType->defaultAtts[j].id) {
3380             isCdata = elementType->defaultAtt    3380             isCdata = elementType->defaultAtts[j].isCdata;
3381             break;                               3381             break;
3382           }                                      3382           }
3383         }                                        3383         }
3384       }                                          3384       }
3385                                                  3385 
3386       /* normalize the attribute value */        3386       /* normalize the attribute value */
3387       result = storeAttributeValue(              3387       result = storeAttributeValue(
3388           parser, enc, isCdata, parser->m_att    3388           parser, enc, isCdata, parser->m_atts[i].valuePtr,
3389           parser->m_atts[i].valueEnd, &parser    3389           parser->m_atts[i].valueEnd, &parser->m_tempPool, account);
3390       if (result)                                3390       if (result)
3391         return result;                           3391         return result;
3392       appAtts[attIndex] = poolStart(&parser->    3392       appAtts[attIndex] = poolStart(&parser->m_tempPool);
3393       poolFinish(&parser->m_tempPool);           3393       poolFinish(&parser->m_tempPool);
3394     } else {                                     3394     } else {
3395       /* the value did not need normalizing *    3395       /* the value did not need normalizing */
3396       appAtts[attIndex] = poolStoreString(&pa    3396       appAtts[attIndex] = poolStoreString(&parser->m_tempPool, enc,
3397                                           par    3397                                           parser->m_atts[i].valuePtr,
3398                                           par    3398                                           parser->m_atts[i].valueEnd);
3399       if (appAtts[attIndex] == 0)                3399       if (appAtts[attIndex] == 0)
3400         return XML_ERROR_NO_MEMORY;              3400         return XML_ERROR_NO_MEMORY;
3401       poolFinish(&parser->m_tempPool);           3401       poolFinish(&parser->m_tempPool);
3402     }                                            3402     }
3403     /* handle prefixed attribute names */        3403     /* handle prefixed attribute names */
3404     if (attId->prefix) {                         3404     if (attId->prefix) {
3405       if (attId->xmlns) {                        3405       if (attId->xmlns) {
3406         /* deal with namespace declarations h    3406         /* deal with namespace declarations here */
3407         enum XML_Error result = addBinding(pa    3407         enum XML_Error result = addBinding(parser, attId->prefix, attId,
3408                                            ap    3408                                            appAtts[attIndex], bindingsPtr);
3409         if (result)                              3409         if (result)
3410           return result;                         3410           return result;
3411         --attIndex;                              3411         --attIndex;
3412       } else {                                   3412       } else {
3413         /* deal with other prefixed names lat    3413         /* deal with other prefixed names later */
3414         attIndex++;                              3414         attIndex++;
3415         nPrefixes++;                             3415         nPrefixes++;
3416         (attId->name)[-1] = 2;                   3416         (attId->name)[-1] = 2;
3417       }                                          3417       }
3418     } else                                       3418     } else
3419       attIndex++;                                3419       attIndex++;
3420   }                                              3420   }
3421                                                  3421 
3422   /* set-up for XML_GetSpecifiedAttributeCoun    3422   /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
3423   parser->m_nSpecifiedAtts = attIndex;           3423   parser->m_nSpecifiedAtts = attIndex;
3424   if (elementType->idAtt && (elementType->idA    3424   if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
3425     for (i = 0; i < attIndex; i += 2)            3425     for (i = 0; i < attIndex; i += 2)
3426       if (appAtts[i] == elementType->idAtt->n    3426       if (appAtts[i] == elementType->idAtt->name) {
3427         parser->m_idAttIndex = i;                3427         parser->m_idAttIndex = i;
3428         break;                                   3428         break;
3429       }                                          3429       }
3430   } else                                         3430   } else
3431     parser->m_idAttIndex = -1;                   3431     parser->m_idAttIndex = -1;
3432                                                  3432 
3433   /* do attribute defaulting */                  3433   /* do attribute defaulting */
3434   for (i = 0; i < nDefaultAtts; i++) {           3434   for (i = 0; i < nDefaultAtts; i++) {
3435     const DEFAULT_ATTRIBUTE *da = elementType    3435     const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
3436     if (! (da->id->name)[-1] && da->value) {     3436     if (! (da->id->name)[-1] && da->value) {
3437       if (da->id->prefix) {                      3437       if (da->id->prefix) {
3438         if (da->id->xmlns) {                     3438         if (da->id->xmlns) {
3439           enum XML_Error result = addBinding(    3439           enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
3440                                                  3440                                              da->value, bindingsPtr);
3441           if (result)                            3441           if (result)
3442             return result;                       3442             return result;
3443         } else {                                 3443         } else {
3444           (da->id->name)[-1] = 2;                3444           (da->id->name)[-1] = 2;
3445           nPrefixes++;                           3445           nPrefixes++;
3446           appAtts[attIndex++] = da->id->name;    3446           appAtts[attIndex++] = da->id->name;
3447           appAtts[attIndex++] = da->value;       3447           appAtts[attIndex++] = da->value;
3448         }                                        3448         }
3449       } else {                                   3449       } else {
3450         (da->id->name)[-1] = 1;                  3450         (da->id->name)[-1] = 1;
3451         appAtts[attIndex++] = da->id->name;      3451         appAtts[attIndex++] = da->id->name;
3452         appAtts[attIndex++] = da->value;         3452         appAtts[attIndex++] = da->value;
3453       }                                          3453       }
3454     }                                            3454     }
3455   }                                              3455   }
3456   appAtts[attIndex] = 0;                         3456   appAtts[attIndex] = 0;
3457                                                  3457 
3458   /* expand prefixed attribute names, check f    3458   /* expand prefixed attribute names, check for duplicates,
3459      and clear flags that say whether attribu    3459      and clear flags that say whether attributes were specified */
3460   i = 0;                                         3460   i = 0;
3461   if (nPrefixes) {                               3461   if (nPrefixes) {
3462     int j; /* hash table index */                3462     int j; /* hash table index */
3463     unsigned long version = parser->m_nsAttsV    3463     unsigned long version = parser->m_nsAttsVersion;
3464                                                  3464 
3465     /* Detect and prevent invalid shift */       3465     /* Detect and prevent invalid shift */
3466     if (parser->m_nsAttsPower >= sizeof(unsig    3466     if (parser->m_nsAttsPower >= sizeof(unsigned int) * 8 /* bits per byte */) {
3467       return XML_ERROR_NO_MEMORY;                3467       return XML_ERROR_NO_MEMORY;
3468     }                                            3468     }
3469                                                  3469 
3470     unsigned int nsAttsSize = 1u << parser->m    3470     unsigned int nsAttsSize = 1u << parser->m_nsAttsPower;
3471     unsigned char oldNsAttsPower = parser->m_    3471     unsigned char oldNsAttsPower = parser->m_nsAttsPower;
3472     /* size of hash table must be at least 2     3472     /* size of hash table must be at least 2 * (# of prefixed attributes) */
3473     if ((nPrefixes << 1)                         3473     if ((nPrefixes << 1)
3474         >> parser->m_nsAttsPower) { /* true f    3474         >> parser->m_nsAttsPower) { /* true for m_nsAttsPower = 0 */
3475       NS_ATT *temp;                              3475       NS_ATT *temp;
3476       /* hash table size must also be a power    3476       /* hash table size must also be a power of 2 and >= 8 */
3477       while (nPrefixes >> parser->m_nsAttsPow    3477       while (nPrefixes >> parser->m_nsAttsPower++)
3478         ;                                        3478         ;
3479       if (parser->m_nsAttsPower < 3)             3479       if (parser->m_nsAttsPower < 3)
3480         parser->m_nsAttsPower = 3;               3480         parser->m_nsAttsPower = 3;
3481                                                  3481 
3482       /* Detect and prevent invalid shift */     3482       /* Detect and prevent invalid shift */
3483       if (parser->m_nsAttsPower >= sizeof(nsA    3483       if (parser->m_nsAttsPower >= sizeof(nsAttsSize) * 8 /* bits per byte */) {
3484         /* Restore actual size of memory in m    3484         /* Restore actual size of memory in m_nsAtts */
3485         parser->m_nsAttsPower = oldNsAttsPowe    3485         parser->m_nsAttsPower = oldNsAttsPower;
3486         return XML_ERROR_NO_MEMORY;              3486         return XML_ERROR_NO_MEMORY;
3487       }                                          3487       }
3488                                                  3488 
3489       nsAttsSize = 1u << parser->m_nsAttsPowe    3489       nsAttsSize = 1u << parser->m_nsAttsPower;
3490                                                  3490 
3491       /* Detect and prevent integer overflow.    3491       /* Detect and prevent integer overflow.
3492        * The preprocessor guard addresses the    3492        * The preprocessor guard addresses the "always false" warning
3493        * from -Wtype-limits on platforms wher    3493        * from -Wtype-limits on platforms where
3494        * sizeof(unsigned int) < sizeof(size_t    3494        * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
3495 #if UINT_MAX >= SIZE_MAX                         3495 #if UINT_MAX >= SIZE_MAX
3496       if (nsAttsSize > (size_t)(-1) / sizeof(    3496       if (nsAttsSize > (size_t)(-1) / sizeof(NS_ATT)) {
3497         /* Restore actual size of memory in m    3497         /* Restore actual size of memory in m_nsAtts */
3498         parser->m_nsAttsPower = oldNsAttsPowe    3498         parser->m_nsAttsPower = oldNsAttsPower;
3499         return XML_ERROR_NO_MEMORY;              3499         return XML_ERROR_NO_MEMORY;
3500       }                                          3500       }
3501 #endif                                           3501 #endif
3502                                                  3502 
3503       temp = (NS_ATT *)REALLOC(parser, parser    3503       temp = (NS_ATT *)REALLOC(parser, parser->m_nsAtts,
3504                                nsAttsSize * s    3504                                nsAttsSize * sizeof(NS_ATT));
3505       if (! temp) {                              3505       if (! temp) {
3506         /* Restore actual size of memory in m    3506         /* Restore actual size of memory in m_nsAtts */
3507         parser->m_nsAttsPower = oldNsAttsPowe    3507         parser->m_nsAttsPower = oldNsAttsPower;
3508         return XML_ERROR_NO_MEMORY;              3508         return XML_ERROR_NO_MEMORY;
3509       }                                          3509       }
3510       parser->m_nsAtts = temp;                   3510       parser->m_nsAtts = temp;
3511       version = 0; /* force re-initialization    3511       version = 0; /* force re-initialization of m_nsAtts hash table */
3512     }                                            3512     }
3513     /* using a version flag saves us from ini    3513     /* using a version flag saves us from initializing m_nsAtts every time */
3514     if (! version) { /* initialize version fl    3514     if (! version) { /* initialize version flags when version wraps around */
3515       version = INIT_ATTS_VERSION;               3515       version = INIT_ATTS_VERSION;
3516       for (j = nsAttsSize; j != 0;)              3516       for (j = nsAttsSize; j != 0;)
3517         parser->m_nsAtts[--j].version = versi    3517         parser->m_nsAtts[--j].version = version;
3518     }                                            3518     }
3519     parser->m_nsAttsVersion = --version;         3519     parser->m_nsAttsVersion = --version;
3520                                                  3520 
3521     /* expand prefixed names and check for du    3521     /* expand prefixed names and check for duplicates */
3522     for (; i < attIndex; i += 2) {               3522     for (; i < attIndex; i += 2) {
3523       const XML_Char *s = appAtts[i];            3523       const XML_Char *s = appAtts[i];
3524       if (s[-1] == 2) { /* prefixed */           3524       if (s[-1] == 2) { /* prefixed */
3525         ATTRIBUTE_ID *id;                        3525         ATTRIBUTE_ID *id;
3526         const BINDING *b;                        3526         const BINDING *b;
3527         unsigned long uriHash;                   3527         unsigned long uriHash;
3528         struct siphash sip_state;                3528         struct siphash sip_state;
3529         struct sipkey sip_key;                   3529         struct sipkey sip_key;
3530                                                  3530 
3531         copy_salt_to_sipkey(parser, &sip_key)    3531         copy_salt_to_sipkey(parser, &sip_key);
3532         sip24_init(&sip_state, &sip_key);        3532         sip24_init(&sip_state, &sip_key);
3533                                                  3533 
3534         ((XML_Char *)s)[-1] = 0; /* clear fla    3534         ((XML_Char *)s)[-1] = 0; /* clear flag */
3535         id = (ATTRIBUTE_ID *)lookup(parser, &    3535         id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);
3536         if (! id || ! id->prefix) {              3536         if (! id || ! id->prefix) {
3537           /* This code is walking through the    3537           /* This code is walking through the appAtts array, dealing
3538            * with (in this case) a prefixed a    3538            * with (in this case) a prefixed attribute name.  To be in
3539            * the array, the attribute must ha    3539            * the array, the attribute must have already been bound, so
3540            * has to have passed through the h    3540            * has to have passed through the hash table lookup once
3541            * already.  That implies that an e    3541            * already.  That implies that an entry for it already
3542            * exists, so the lookup above will    3542            * exists, so the lookup above will return a pointer to
3543            * already allocated memory.  There    3543            * already allocated memory.  There is no opportunaity for
3544            * the allocator to fail, so the co    3544            * the allocator to fail, so the condition above cannot be
3545            * fulfilled.                          3545            * fulfilled.
3546            *                                     3546            *
3547            * Since it is difficult to be cert    3547            * Since it is difficult to be certain that the above
3548            * analysis is complete, we retain     3548            * analysis is complete, we retain the test and merely
3549            * remove the code from coverage te    3549            * remove the code from coverage tests.
3550            */                                    3550            */
3551           return XML_ERROR_NO_MEMORY; /* LCOV    3551           return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */
3552         }                                        3552         }
3553         b = id->prefix->binding;                 3553         b = id->prefix->binding;
3554         if (! b)                                 3554         if (! b)
3555           return XML_ERROR_UNBOUND_PREFIX;       3555           return XML_ERROR_UNBOUND_PREFIX;
3556                                                  3556 
3557         for (j = 0; j < b->uriLen; j++) {        3557         for (j = 0; j < b->uriLen; j++) {
3558           const XML_Char c = b->uri[j];          3558           const XML_Char c = b->uri[j];
3559           if (! poolAppendChar(&parser->m_tem    3559           if (! poolAppendChar(&parser->m_tempPool, c))
3560             return XML_ERROR_NO_MEMORY;          3560             return XML_ERROR_NO_MEMORY;
3561         }                                        3561         }
3562                                                  3562 
3563         sip24_update(&sip_state, b->uri, b->u    3563         sip24_update(&sip_state, b->uri, b->uriLen * sizeof(XML_Char));
3564                                                  3564 
3565         while (*s++ != XML_T(ASCII_COLON))       3565         while (*s++ != XML_T(ASCII_COLON))
3566           ;                                      3566           ;
3567                                                  3567 
3568         sip24_update(&sip_state, s, keylen(s)    3568         sip24_update(&sip_state, s, keylen(s) * sizeof(XML_Char));
3569                                                  3569 
3570         do { /* copies null terminator */        3570         do { /* copies null terminator */
3571           if (! poolAppendChar(&parser->m_tem    3571           if (! poolAppendChar(&parser->m_tempPool, *s))
3572             return XML_ERROR_NO_MEMORY;          3572             return XML_ERROR_NO_MEMORY;
3573         } while (*s++);                          3573         } while (*s++);
3574                                                  3574 
3575         uriHash = (unsigned long)sip24_final(    3575         uriHash = (unsigned long)sip24_final(&sip_state);
3576                                                  3576 
3577         { /* Check hash table for duplicate o    3577         { /* Check hash table for duplicate of expanded name (uriName).
3578              Derived from code in lookup(pars    3578              Derived from code in lookup(parser, HASH_TABLE *table, ...).
3579           */                                     3579           */
3580           unsigned char step = 0;                3580           unsigned char step = 0;
3581           unsigned long mask = nsAttsSize - 1    3581           unsigned long mask = nsAttsSize - 1;
3582           j = uriHash & mask; /* index into h    3582           j = uriHash & mask; /* index into hash table */
3583           while (parser->m_nsAtts[j].version     3583           while (parser->m_nsAtts[j].version == version) {
3584             /* for speed we compare stored ha    3584             /* for speed we compare stored hash values first */
3585             if (uriHash == parser->m_nsAtts[j    3585             if (uriHash == parser->m_nsAtts[j].hash) {
3586               const XML_Char *s1 = poolStart(    3586               const XML_Char *s1 = poolStart(&parser->m_tempPool);
3587               const XML_Char *s2 = parser->m_    3587               const XML_Char *s2 = parser->m_nsAtts[j].uriName;
3588               /* s1 is null terminated, but n    3588               /* s1 is null terminated, but not s2 */
3589               for (; *s1 == *s2 && *s1 != 0;     3589               for (; *s1 == *s2 && *s1 != 0; s1++, s2++)
3590                 ;                                3590                 ;
3591               if (*s1 == 0)                      3591               if (*s1 == 0)
3592                 return XML_ERROR_DUPLICATE_AT    3592                 return XML_ERROR_DUPLICATE_ATTRIBUTE;
3593             }                                    3593             }
3594             if (! step)                          3594             if (! step)
3595               step = PROBE_STEP(uriHash, mask    3595               step = PROBE_STEP(uriHash, mask, parser->m_nsAttsPower);
3596             j < step ? (j += nsAttsSize - ste    3596             j < step ? (j += nsAttsSize - step) : (j -= step);
3597           }                                      3597           }
3598         }                                        3598         }
3599                                                  3599 
3600         if (parser->m_ns_triplets) { /* appen    3600         if (parser->m_ns_triplets) { /* append namespace separator and prefix */
3601           parser->m_tempPool.ptr[-1] = parser    3601           parser->m_tempPool.ptr[-1] = parser->m_namespaceSeparator;
3602           s = b->prefix->name;                   3602           s = b->prefix->name;
3603           do {                                   3603           do {
3604             if (! poolAppendChar(&parser->m_t    3604             if (! poolAppendChar(&parser->m_tempPool, *s))
3605               return XML_ERROR_NO_MEMORY;        3605               return XML_ERROR_NO_MEMORY;
3606           } while (*s++);                        3606           } while (*s++);
3607         }                                        3607         }
3608                                                  3608 
3609         /* store expanded name in attribute l    3609         /* store expanded name in attribute list */
3610         s = poolStart(&parser->m_tempPool);      3610         s = poolStart(&parser->m_tempPool);
3611         poolFinish(&parser->m_tempPool);         3611         poolFinish(&parser->m_tempPool);
3612         appAtts[i] = s;                          3612         appAtts[i] = s;
3613                                                  3613 
3614         /* fill empty slot with new version,     3614         /* fill empty slot with new version, uriName and hash value */
3615         parser->m_nsAtts[j].version = version    3615         parser->m_nsAtts[j].version = version;
3616         parser->m_nsAtts[j].hash = uriHash;      3616         parser->m_nsAtts[j].hash = uriHash;
3617         parser->m_nsAtts[j].uriName = s;         3617         parser->m_nsAtts[j].uriName = s;
3618                                                  3618 
3619         if (! --nPrefixes) {                     3619         if (! --nPrefixes) {
3620           i += 2;                                3620           i += 2;
3621           break;                                 3621           break;
3622         }                                        3622         }
3623       } else                     /* not prefi    3623       } else                     /* not prefixed */
3624         ((XML_Char *)s)[-1] = 0; /* clear fla    3624         ((XML_Char *)s)[-1] = 0; /* clear flag */
3625     }                                            3625     }
3626   }                                              3626   }
3627   /* clear flags for the remaining attributes    3627   /* clear flags for the remaining attributes */
3628   for (; i < attIndex; i += 2)                   3628   for (; i < attIndex; i += 2)
3629     ((XML_Char *)(appAtts[i]))[-1] = 0;          3629     ((XML_Char *)(appAtts[i]))[-1] = 0;
3630   for (binding = *bindingsPtr; binding; bindi    3630   for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
3631     binding->attId->name[-1] = 0;                3631     binding->attId->name[-1] = 0;
3632                                                  3632 
3633   if (! parser->m_ns)                            3633   if (! parser->m_ns)
3634     return XML_ERROR_NONE;                       3634     return XML_ERROR_NONE;
3635                                                  3635 
3636   /* expand the element type name */             3636   /* expand the element type name */
3637   if (elementType->prefix) {                     3637   if (elementType->prefix) {
3638     binding = elementType->prefix->binding;      3638     binding = elementType->prefix->binding;
3639     if (! binding)                               3639     if (! binding)
3640       return XML_ERROR_UNBOUND_PREFIX;           3640       return XML_ERROR_UNBOUND_PREFIX;
3641     localPart = tagNamePtr->str;                 3641     localPart = tagNamePtr->str;
3642     while (*localPart++ != XML_T(ASCII_COLON)    3642     while (*localPart++ != XML_T(ASCII_COLON))
3643       ;                                          3643       ;
3644   } else if (dtd->defaultPrefix.binding) {       3644   } else if (dtd->defaultPrefix.binding) {
3645     binding = dtd->defaultPrefix.binding;        3645     binding = dtd->defaultPrefix.binding;
3646     localPart = tagNamePtr->str;                 3646     localPart = tagNamePtr->str;
3647   } else                                         3647   } else
3648     return XML_ERROR_NONE;                       3648     return XML_ERROR_NONE;
3649   prefixLen = 0;                                 3649   prefixLen = 0;
3650   if (parser->m_ns_triplets && binding->prefi    3650   if (parser->m_ns_triplets && binding->prefix->name) {
3651     for (; binding->prefix->name[prefixLen++]    3651     for (; binding->prefix->name[prefixLen++];)
3652       ; /* prefixLen includes null terminator    3652       ; /* prefixLen includes null terminator */
3653   }                                              3653   }
3654   tagNamePtr->localPart = localPart;             3654   tagNamePtr->localPart = localPart;
3655   tagNamePtr->uriLen = binding->uriLen;          3655   tagNamePtr->uriLen = binding->uriLen;
3656   tagNamePtr->prefix = binding->prefix->name;    3656   tagNamePtr->prefix = binding->prefix->name;
3657   tagNamePtr->prefixLen = prefixLen;             3657   tagNamePtr->prefixLen = prefixLen;
3658   for (i = 0; localPart[i++];)                   3658   for (i = 0; localPart[i++];)
3659     ; /* i includes null terminator */           3659     ; /* i includes null terminator */
3660                                                  3660 
3661   /* Detect and prevent integer overflow */      3661   /* Detect and prevent integer overflow */
3662   if (binding->uriLen > INT_MAX - prefixLen      3662   if (binding->uriLen > INT_MAX - prefixLen
3663       || i > INT_MAX - (binding->uriLen + pre    3663       || i > INT_MAX - (binding->uriLen + prefixLen)) {
3664     return XML_ERROR_NO_MEMORY;                  3664     return XML_ERROR_NO_MEMORY;
3665   }                                              3665   }
3666                                                  3666 
3667   n = i + binding->uriLen + prefixLen;           3667   n = i + binding->uriLen + prefixLen;
3668   if (n > binding->uriAlloc) {                   3668   if (n > binding->uriAlloc) {
3669     TAG *p;                                      3669     TAG *p;
3670                                                  3670 
3671     /* Detect and prevent integer overflow */    3671     /* Detect and prevent integer overflow */
3672     if (n > INT_MAX - EXPAND_SPARE) {            3672     if (n > INT_MAX - EXPAND_SPARE) {
3673       return XML_ERROR_NO_MEMORY;                3673       return XML_ERROR_NO_MEMORY;
3674     }                                            3674     }
3675     /* Detect and prevent integer overflow.      3675     /* Detect and prevent integer overflow.
3676      * The preprocessor guard addresses the "    3676      * The preprocessor guard addresses the "always false" warning
3677      * from -Wtype-limits on platforms where     3677      * from -Wtype-limits on platforms where
3678      * sizeof(unsigned int) < sizeof(size_t),    3678      * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
3679 #if UINT_MAX >= SIZE_MAX                         3679 #if UINT_MAX >= SIZE_MAX
3680     if ((unsigned)(n + EXPAND_SPARE) > (size_    3680     if ((unsigned)(n + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) {
3681       return XML_ERROR_NO_MEMORY;                3681       return XML_ERROR_NO_MEMORY;
3682     }                                            3682     }
3683 #endif                                           3683 #endif
3684                                                  3684 
3685     uri = (XML_Char *)MALLOC(parser, (n + EXP    3685     uri = (XML_Char *)MALLOC(parser, (n + EXPAND_SPARE) * sizeof(XML_Char));
3686     if (! uri)                                   3686     if (! uri)
3687       return XML_ERROR_NO_MEMORY;                3687       return XML_ERROR_NO_MEMORY;
3688     binding->uriAlloc = n + EXPAND_SPARE;        3688     binding->uriAlloc = n + EXPAND_SPARE;
3689     memcpy(uri, binding->uri, binding->uriLen    3689     memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
3690     for (p = parser->m_tagStack; p; p = p->pa    3690     for (p = parser->m_tagStack; p; p = p->parent)
3691       if (p->name.str == binding->uri)           3691       if (p->name.str == binding->uri)
3692         p->name.str = uri;                       3692         p->name.str = uri;
3693     FREE(parser, binding->uri);                  3693     FREE(parser, binding->uri);
3694     binding->uri = uri;                          3694     binding->uri = uri;
3695   }                                              3695   }
3696   /* if m_namespaceSeparator != '\0' then uri    3696   /* if m_namespaceSeparator != '\0' then uri includes it already */
3697   uri = binding->uri + binding->uriLen;          3697   uri = binding->uri + binding->uriLen;
3698   memcpy(uri, localPart, i * sizeof(XML_Char)    3698   memcpy(uri, localPart, i * sizeof(XML_Char));
3699   /* we always have a namespace separator bet    3699   /* we always have a namespace separator between localPart and prefix */
3700   if (prefixLen) {                               3700   if (prefixLen) {
3701     uri += i - 1;                                3701     uri += i - 1;
3702     *uri = parser->m_namespaceSeparator; /* r    3702     *uri = parser->m_namespaceSeparator; /* replace null terminator */
3703     memcpy(uri + 1, binding->prefix->name, pr    3703     memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
3704   }                                              3704   }
3705   tagNamePtr->str = binding->uri;                3705   tagNamePtr->str = binding->uri;
3706   return XML_ERROR_NONE;                         3706   return XML_ERROR_NONE;
3707 }                                                3707 }
3708                                                  3708 
3709 static XML_Bool                                  3709 static XML_Bool
3710 is_rfc3986_uri_char(XML_Char candidate) {        3710 is_rfc3986_uri_char(XML_Char candidate) {
3711   // For the RFC 3986 ANBF grammar see           3711   // For the RFC 3986 ANBF grammar see
3712   // https://datatracker.ietf.org/doc/html/rf    3712   // https://datatracker.ietf.org/doc/html/rfc3986#appendix-A
3713                                                  3713 
3714   switch (candidate) {                           3714   switch (candidate) {
3715   // From rule "ALPHA" (uppercase half)          3715   // From rule "ALPHA" (uppercase half)
3716   case 'A':                                      3716   case 'A':
3717   case 'B':                                      3717   case 'B':
3718   case 'C':                                      3718   case 'C':
3719   case 'D':                                      3719   case 'D':
3720   case 'E':                                      3720   case 'E':
3721   case 'F':                                      3721   case 'F':
3722   case 'G':                                      3722   case 'G':
3723   case 'H':                                      3723   case 'H':
3724   case 'I':                                      3724   case 'I':
3725   case 'J':                                      3725   case 'J':
3726   case 'K':                                      3726   case 'K':
3727   case 'L':                                      3727   case 'L':
3728   case 'M':                                      3728   case 'M':
3729   case 'N':                                      3729   case 'N':
3730   case 'O':                                      3730   case 'O':
3731   case 'P':                                      3731   case 'P':
3732   case 'Q':                                      3732   case 'Q':
3733   case 'R':                                      3733   case 'R':
3734   case 'S':                                      3734   case 'S':
3735   case 'T':                                      3735   case 'T':
3736   case 'U':                                      3736   case 'U':
3737   case 'V':                                      3737   case 'V':
3738   case 'W':                                      3738   case 'W':
3739   case 'X':                                      3739   case 'X':
3740   case 'Y':                                      3740   case 'Y':
3741   case 'Z':                                      3741   case 'Z':
3742                                                  3742 
3743   // From rule "ALPHA" (lowercase half)          3743   // From rule "ALPHA" (lowercase half)
3744   case 'a':                                      3744   case 'a':
3745   case 'b':                                      3745   case 'b':
3746   case 'c':                                      3746   case 'c':
3747   case 'd':                                      3747   case 'd':
3748   case 'e':                                      3748   case 'e':
3749   case 'f':                                      3749   case 'f':
3750   case 'g':                                      3750   case 'g':
3751   case 'h':                                      3751   case 'h':
3752   case 'i':                                      3752   case 'i':
3753   case 'j':                                      3753   case 'j':
3754   case 'k':                                      3754   case 'k':
3755   case 'l':                                      3755   case 'l':
3756   case 'm':                                      3756   case 'm':
3757   case 'n':                                      3757   case 'n':
3758   case 'o':                                      3758   case 'o':
3759   case 'p':                                      3759   case 'p':
3760   case 'q':                                      3760   case 'q':
3761   case 'r':                                      3761   case 'r':
3762   case 's':                                      3762   case 's':
3763   case 't':                                      3763   case 't':
3764   case 'u':                                      3764   case 'u':
3765   case 'v':                                      3765   case 'v':
3766   case 'w':                                      3766   case 'w':
3767   case 'x':                                      3767   case 'x':
3768   case 'y':                                      3768   case 'y':
3769   case 'z':                                      3769   case 'z':
3770                                                  3770 
3771   // From rule "DIGIT"                           3771   // From rule "DIGIT"
3772   case '0':                                      3772   case '0':
3773   case '1':                                      3773   case '1':
3774   case '2':                                      3774   case '2':
3775   case '3':                                      3775   case '3':
3776   case '4':                                      3776   case '4':
3777   case '5':                                      3777   case '5':
3778   case '6':                                      3778   case '6':
3779   case '7':                                      3779   case '7':
3780   case '8':                                      3780   case '8':
3781   case '9':                                      3781   case '9':
3782                                                  3782 
3783   // From rule "pct-encoded"                     3783   // From rule "pct-encoded"
3784   case '%':                                      3784   case '%':
3785                                                  3785 
3786   // From rule "unreserved"                      3786   // From rule "unreserved"
3787   case '-':                                      3787   case '-':
3788   case '.':                                      3788   case '.':
3789   case '_':                                      3789   case '_':
3790   case '~':                                      3790   case '~':
3791                                                  3791 
3792   // From rule "gen-delims"                      3792   // From rule "gen-delims"
3793   case ':':                                      3793   case ':':
3794   case '/':                                      3794   case '/':
3795   case '?':                                      3795   case '?':
3796   case '#':                                      3796   case '#':
3797   case '[':                                      3797   case '[':
3798   case ']':                                      3798   case ']':
3799   case '@':                                      3799   case '@':
3800                                                  3800 
3801   // From rule "sub-delims"                      3801   // From rule "sub-delims"
3802   case '!':                                      3802   case '!':
3803   case '$':                                      3803   case '$':
3804   case '&':                                      3804   case '&':
3805   case '\'':                                     3805   case '\'':
3806   case '(':                                      3806   case '(':
3807   case ')':                                      3807   case ')':
3808   case '*':                                      3808   case '*':
3809   case '+':                                      3809   case '+':
3810   case ',':                                      3810   case ',':
3811   case ';':                                      3811   case ';':
3812   case '=':                                      3812   case '=':
3813     return XML_TRUE;                             3813     return XML_TRUE;
3814                                                  3814 
3815   default:                                       3815   default:
3816     return XML_FALSE;                            3816     return XML_FALSE;
3817   }                                              3817   }
3818 }                                                3818 }
3819                                                  3819 
3820 /* addBinding() overwrites the value of prefi    3820 /* addBinding() overwrites the value of prefix->binding without checking.
3821    Therefore one must keep track of the old v    3821    Therefore one must keep track of the old value outside of addBinding().
3822 */                                               3822 */
3823 static enum XML_Error                            3823 static enum XML_Error
3824 addBinding(XML_Parser parser, PREFIX *prefix,    3824 addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
3825            const XML_Char *uri, BINDING **bin    3825            const XML_Char *uri, BINDING **bindingsPtr) {
3826   // "http://www.w3.org/XML/1998/namespace"      3826   // "http://www.w3.org/XML/1998/namespace"
3827   static const XML_Char xmlNamespace[]           3827   static const XML_Char xmlNamespace[]
3828       = {ASCII_h,      ASCII_t,     ASCII_t,     3828       = {ASCII_h,      ASCII_t,     ASCII_t,     ASCII_p,      ASCII_COLON,
3829          ASCII_SLASH,  ASCII_SLASH, ASCII_w,     3829          ASCII_SLASH,  ASCII_SLASH, ASCII_w,     ASCII_w,      ASCII_w,
3830          ASCII_PERIOD, ASCII_w,     ASCII_3,     3830          ASCII_PERIOD, ASCII_w,     ASCII_3,     ASCII_PERIOD, ASCII_o,
3831          ASCII_r,      ASCII_g,     ASCII_SLA    3831          ASCII_r,      ASCII_g,     ASCII_SLASH, ASCII_X,      ASCII_M,
3832          ASCII_L,      ASCII_SLASH, ASCII_1,     3832          ASCII_L,      ASCII_SLASH, ASCII_1,     ASCII_9,      ASCII_9,
3833          ASCII_8,      ASCII_SLASH, ASCII_n,     3833          ASCII_8,      ASCII_SLASH, ASCII_n,     ASCII_a,      ASCII_m,
3834          ASCII_e,      ASCII_s,     ASCII_p,     3834          ASCII_e,      ASCII_s,     ASCII_p,     ASCII_a,      ASCII_c,
3835          ASCII_e,      '\0'};                    3835          ASCII_e,      '\0'};
3836   static const int xmlLen = (int)sizeof(xmlNa    3836   static const int xmlLen = (int)sizeof(xmlNamespace) / sizeof(XML_Char) - 1;
3837   // "http://www.w3.org/2000/xmlns/"             3837   // "http://www.w3.org/2000/xmlns/"
3838   static const XML_Char xmlnsNamespace[]         3838   static const XML_Char xmlnsNamespace[]
3839       = {ASCII_h,     ASCII_t,      ASCII_t,     3839       = {ASCII_h,     ASCII_t,      ASCII_t, ASCII_p, ASCII_COLON,  ASCII_SLASH,
3840          ASCII_SLASH, ASCII_w,      ASCII_w,     3840          ASCII_SLASH, ASCII_w,      ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w,
3841          ASCII_3,     ASCII_PERIOD, ASCII_o,     3841          ASCII_3,     ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g,      ASCII_SLASH,
3842          ASCII_2,     ASCII_0,      ASCII_0,     3842          ASCII_2,     ASCII_0,      ASCII_0, ASCII_0, ASCII_SLASH,  ASCII_x,
3843          ASCII_m,     ASCII_l,      ASCII_n,     3843          ASCII_m,     ASCII_l,      ASCII_n, ASCII_s, ASCII_SLASH,  '\0'};
3844   static const int xmlnsLen                      3844   static const int xmlnsLen
3845       = (int)sizeof(xmlnsNamespace) / sizeof(    3845       = (int)sizeof(xmlnsNamespace) / sizeof(XML_Char) - 1;
3846                                                  3846 
3847   XML_Bool mustBeXML = XML_FALSE;                3847   XML_Bool mustBeXML = XML_FALSE;
3848   XML_Bool isXML = XML_TRUE;                     3848   XML_Bool isXML = XML_TRUE;
3849   XML_Bool isXMLNS = XML_TRUE;                   3849   XML_Bool isXMLNS = XML_TRUE;
3850                                                  3850 
3851   BINDING *b;                                    3851   BINDING *b;
3852   int len;                                       3852   int len;
3853                                                  3853 
3854   /* empty URI is only valid for default name    3854   /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
3855   if (*uri == XML_T('\0') && prefix->name)       3855   if (*uri == XML_T('\0') && prefix->name)
3856     return XML_ERROR_UNDECLARING_PREFIX;         3856     return XML_ERROR_UNDECLARING_PREFIX;
3857                                                  3857 
3858   if (prefix->name && prefix->name[0] == XML_    3858   if (prefix->name && prefix->name[0] == XML_T(ASCII_x)
3859       && prefix->name[1] == XML_T(ASCII_m)       3859       && prefix->name[1] == XML_T(ASCII_m)
3860       && prefix->name[2] == XML_T(ASCII_l)) {    3860       && prefix->name[2] == XML_T(ASCII_l)) {
3861     /* Not allowed to bind xmlns */              3861     /* Not allowed to bind xmlns */
3862     if (prefix->name[3] == XML_T(ASCII_n) &&     3862     if (prefix->name[3] == XML_T(ASCII_n) && prefix->name[4] == XML_T(ASCII_s)
3863         && prefix->name[5] == XML_T('\0'))       3863         && prefix->name[5] == XML_T('\0'))
3864       return XML_ERROR_RESERVED_PREFIX_XMLNS;    3864       return XML_ERROR_RESERVED_PREFIX_XMLNS;
3865                                                  3865 
3866     if (prefix->name[3] == XML_T('\0'))          3866     if (prefix->name[3] == XML_T('\0'))
3867       mustBeXML = XML_TRUE;                      3867       mustBeXML = XML_TRUE;
3868   }                                              3868   }
3869                                                  3869 
3870   for (len = 0; uri[len]; len++) {               3870   for (len = 0; uri[len]; len++) {
3871     if (isXML && (len > xmlLen || uri[len] !=    3871     if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
3872       isXML = XML_FALSE;                         3872       isXML = XML_FALSE;
3873                                                  3873 
3874     if (! mustBeXML && isXMLNS                   3874     if (! mustBeXML && isXMLNS
3875         && (len > xmlnsLen || uri[len] != xml    3875         && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
3876       isXMLNS = XML_FALSE;                       3876       isXMLNS = XML_FALSE;
3877                                                  3877 
3878     // NOTE: While Expat does not validate na    3878     // NOTE: While Expat does not validate namespace URIs against RFC 3986
3879     //       today (and is not REQUIRED to do    3879     //       today (and is not REQUIRED to do so with regard to the XML 1.0
3880     //       namespaces specification) we hav    3880     //       namespaces specification) we have to at least make sure, that
3881     //       the application on top of Expat     3881     //       the application on top of Expat (that is likely splitting expanded
3882     //       element names ("qualified names"    3882     //       element names ("qualified names") of form
3883     //       "[uri sep] local [sep prefix] '\    3883     //       "[uri sep] local [sep prefix] '\0'" back into 1, 2 or 3 pieces
3884     //       in its element handler code) can    3884     //       in its element handler code) cannot be confused by an attacker
3885     //       putting additional namespace sep    3885     //       putting additional namespace separator characters into namespace
3886     //       declarations.  That would be amb    3886     //       declarations.  That would be ambiguous and not to be expected.
3887     //                                           3887     //
3888     //       While the HTML API docs of funct    3888     //       While the HTML API docs of function XML_ParserCreateNS have been
3889     //       advising against use of a namesp    3889     //       advising against use of a namespace separator character that can
3890     //       appear in a URI for >20 years no    3890     //       appear in a URI for >20 years now, some widespread applications
3891     //       are using URI characters (':' (c    3891     //       are using URI characters (':' (colon) in particular) for a
3892     //       namespace separator, in practice    3892     //       namespace separator, in practice.  To keep these applications
3893     //       functional, we only reject names    3893     //       functional, we only reject namespaces URIs containing the
3894     //       application-chosen namespace sep    3894     //       application-chosen namespace separator if the chosen separator
3895     //       is a non-URI character with rega    3895     //       is a non-URI character with regard to RFC 3986.
3896     if (parser->m_ns && (uri[len] == parser->    3896     if (parser->m_ns && (uri[len] == parser->m_namespaceSeparator)
3897         && ! is_rfc3986_uri_char(uri[len])) {    3897         && ! is_rfc3986_uri_char(uri[len])) {
3898       return XML_ERROR_SYNTAX;                   3898       return XML_ERROR_SYNTAX;
3899     }                                            3899     }
3900   }                                              3900   }
3901   isXML = isXML && len == xmlLen;                3901   isXML = isXML && len == xmlLen;
3902   isXMLNS = isXMLNS && len == xmlnsLen;          3902   isXMLNS = isXMLNS && len == xmlnsLen;
3903                                                  3903 
3904   if (mustBeXML != isXML)                        3904   if (mustBeXML != isXML)
3905     return mustBeXML ? XML_ERROR_RESERVED_PRE    3905     return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
3906                      : XML_ERROR_RESERVED_NAM    3906                      : XML_ERROR_RESERVED_NAMESPACE_URI;
3907                                                  3907 
3908   if (isXMLNS)                                   3908   if (isXMLNS)
3909     return XML_ERROR_RESERVED_NAMESPACE_URI;     3909     return XML_ERROR_RESERVED_NAMESPACE_URI;
3910                                                  3910 
3911   if (parser->m_namespaceSeparator)              3911   if (parser->m_namespaceSeparator)
3912     len++;                                       3912     len++;
3913   if (parser->m_freeBindingList) {               3913   if (parser->m_freeBindingList) {
3914     b = parser->m_freeBindingList;               3914     b = parser->m_freeBindingList;
3915     if (len > b->uriAlloc) {                     3915     if (len > b->uriAlloc) {
3916       /* Detect and prevent integer overflow     3916       /* Detect and prevent integer overflow */
3917       if (len > INT_MAX - EXPAND_SPARE) {        3917       if (len > INT_MAX - EXPAND_SPARE) {
3918         return XML_ERROR_NO_MEMORY;              3918         return XML_ERROR_NO_MEMORY;
3919       }                                          3919       }
3920                                                  3920 
3921       /* Detect and prevent integer overflow.    3921       /* Detect and prevent integer overflow.
3922        * The preprocessor guard addresses the    3922        * The preprocessor guard addresses the "always false" warning
3923        * from -Wtype-limits on platforms wher    3923        * from -Wtype-limits on platforms where
3924        * sizeof(unsigned int) < sizeof(size_t    3924        * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
3925 #if UINT_MAX >= SIZE_MAX                         3925 #if UINT_MAX >= SIZE_MAX
3926       if ((unsigned)(len + EXPAND_SPARE) > (s    3926       if ((unsigned)(len + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) {
3927         return XML_ERROR_NO_MEMORY;              3927         return XML_ERROR_NO_MEMORY;
3928       }                                          3928       }
3929 #endif                                           3929 #endif
3930                                                  3930 
3931       XML_Char *temp = (XML_Char *)REALLOC(      3931       XML_Char *temp = (XML_Char *)REALLOC(
3932           parser, b->uri, sizeof(XML_Char) *     3932           parser, b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE));
3933       if (temp == NULL)                          3933       if (temp == NULL)
3934         return XML_ERROR_NO_MEMORY;              3934         return XML_ERROR_NO_MEMORY;
3935       b->uri = temp;                             3935       b->uri = temp;
3936       b->uriAlloc = len + EXPAND_SPARE;          3936       b->uriAlloc = len + EXPAND_SPARE;
3937     }                                            3937     }
3938     parser->m_freeBindingList = b->nextTagBin    3938     parser->m_freeBindingList = b->nextTagBinding;
3939   } else {                                       3939   } else {
3940     b = (BINDING *)MALLOC(parser, sizeof(BIND    3940     b = (BINDING *)MALLOC(parser, sizeof(BINDING));
3941     if (! b)                                     3941     if (! b)
3942       return XML_ERROR_NO_MEMORY;                3942       return XML_ERROR_NO_MEMORY;
3943                                                  3943 
3944     /* Detect and prevent integer overflow */    3944     /* Detect and prevent integer overflow */
3945     if (len > INT_MAX - EXPAND_SPARE) {          3945     if (len > INT_MAX - EXPAND_SPARE) {
3946       return XML_ERROR_NO_MEMORY;                3946       return XML_ERROR_NO_MEMORY;
3947     }                                            3947     }
3948     /* Detect and prevent integer overflow.      3948     /* Detect and prevent integer overflow.
3949      * The preprocessor guard addresses the "    3949      * The preprocessor guard addresses the "always false" warning
3950      * from -Wtype-limits on platforms where     3950      * from -Wtype-limits on platforms where
3951      * sizeof(unsigned int) < sizeof(size_t),    3951      * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
3952 #if UINT_MAX >= SIZE_MAX                         3952 #if UINT_MAX >= SIZE_MAX
3953     if ((unsigned)(len + EXPAND_SPARE) > (siz    3953     if ((unsigned)(len + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) {
3954       return XML_ERROR_NO_MEMORY;                3954       return XML_ERROR_NO_MEMORY;
3955     }                                            3955     }
3956 #endif                                           3956 #endif
3957                                                  3957 
3958     b->uri                                       3958     b->uri
3959         = (XML_Char *)MALLOC(parser, sizeof(X    3959         = (XML_Char *)MALLOC(parser, sizeof(XML_Char) * (len + EXPAND_SPARE));
3960     if (! b->uri) {                              3960     if (! b->uri) {
3961       FREE(parser, b);                           3961       FREE(parser, b);
3962       return XML_ERROR_NO_MEMORY;                3962       return XML_ERROR_NO_MEMORY;
3963     }                                            3963     }
3964     b->uriAlloc = len + EXPAND_SPARE;            3964     b->uriAlloc = len + EXPAND_SPARE;
3965   }                                              3965   }
3966   b->uriLen = len;                               3966   b->uriLen = len;
3967   memcpy(b->uri, uri, len * sizeof(XML_Char))    3967   memcpy(b->uri, uri, len * sizeof(XML_Char));
3968   if (parser->m_namespaceSeparator)              3968   if (parser->m_namespaceSeparator)
3969     b->uri[len - 1] = parser->m_namespaceSepa    3969     b->uri[len - 1] = parser->m_namespaceSeparator;
3970   b->prefix = prefix;                            3970   b->prefix = prefix;
3971   b->attId = attId;                              3971   b->attId = attId;
3972   b->prevPrefixBinding = prefix->binding;        3972   b->prevPrefixBinding = prefix->binding;
3973   /* NULL binding when default namespace unde    3973   /* NULL binding when default namespace undeclared */
3974   if (*uri == XML_T('\0') && prefix == &parse    3974   if (*uri == XML_T('\0') && prefix == &parser->m_dtd->defaultPrefix)
3975     prefix->binding = NULL;                      3975     prefix->binding = NULL;
3976   else                                           3976   else
3977     prefix->binding = b;                         3977     prefix->binding = b;
3978   b->nextTagBinding = *bindingsPtr;              3978   b->nextTagBinding = *bindingsPtr;
3979   *bindingsPtr = b;                              3979   *bindingsPtr = b;
3980   /* if attId == NULL then we are not startin    3980   /* if attId == NULL then we are not starting a namespace scope */
3981   if (attId && parser->m_startNamespaceDeclHa    3981   if (attId && parser->m_startNamespaceDeclHandler)
3982     parser->m_startNamespaceDeclHandler(parse    3982     parser->m_startNamespaceDeclHandler(parser->m_handlerArg, prefix->name,
3983                                         prefi    3983                                         prefix->binding ? uri : 0);
3984   return XML_ERROR_NONE;                         3984   return XML_ERROR_NONE;
3985 }                                                3985 }
3986                                                  3986 
3987 /* The idea here is to avoid using stack for     3987 /* The idea here is to avoid using stack for each CDATA section when
3988    the whole file is parsed with one call.       3988    the whole file is parsed with one call.
3989 */                                               3989 */
3990 static enum XML_Error PTRCALL                    3990 static enum XML_Error PTRCALL
3991 cdataSectionProcessor(XML_Parser parser, cons    3991 cdataSectionProcessor(XML_Parser parser, const char *start, const char *end,
3992                       const char **endPtr) {     3992                       const char **endPtr) {
3993   enum XML_Error result = doCdataSection(        3993   enum XML_Error result = doCdataSection(
3994       parser, parser->m_encoding, &start, end    3994       parser, parser->m_encoding, &start, end, endPtr,
3995       (XML_Bool)! parser->m_parsingStatus.fin    3995       (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_ACCOUNT_DIRECT);
3996   if (result != XML_ERROR_NONE)                  3996   if (result != XML_ERROR_NONE)
3997     return result;                               3997     return result;
3998   if (start) {                                   3998   if (start) {
3999     if (parser->m_parentParser) { /* we are p    3999     if (parser->m_parentParser) { /* we are parsing an external entity */
4000       parser->m_processor = externalEntityCon    4000       parser->m_processor = externalEntityContentProcessor;
4001       return externalEntityContentProcessor(p    4001       return externalEntityContentProcessor(parser, start, end, endPtr);
4002     } else {                                     4002     } else {
4003       parser->m_processor = contentProcessor;    4003       parser->m_processor = contentProcessor;
4004       return contentProcessor(parser, start,     4004       return contentProcessor(parser, start, end, endPtr);
4005     }                                            4005     }
4006   }                                              4006   }
4007   return result;                                 4007   return result;
4008 }                                                4008 }
4009                                                  4009 
4010 /* startPtr gets set to non-null if the secti    4010 /* startPtr gets set to non-null if the section is closed, and to null if
4011    the section is not yet closed.                4011    the section is not yet closed.
4012 */                                               4012 */
4013 static enum XML_Error                            4013 static enum XML_Error
4014 doCdataSection(XML_Parser parser, const ENCOD    4014 doCdataSection(XML_Parser parser, const ENCODING *enc, const char **startPtr,
4015                const char *end, const char **    4015                const char *end, const char **nextPtr, XML_Bool haveMore,
4016                enum XML_Account account) {       4016                enum XML_Account account) {
4017   const char *s = *startPtr;                     4017   const char *s = *startPtr;
4018   const char **eventPP;                          4018   const char **eventPP;
4019   const char **eventEndPP;                       4019   const char **eventEndPP;
4020   if (enc == parser->m_encoding) {               4020   if (enc == parser->m_encoding) {
4021     eventPP = &parser->m_eventPtr;               4021     eventPP = &parser->m_eventPtr;
4022     *eventPP = s;                                4022     *eventPP = s;
4023     eventEndPP = &parser->m_eventEndPtr;         4023     eventEndPP = &parser->m_eventEndPtr;
4024   } else {                                       4024   } else {
4025     eventPP = &(parser->m_openInternalEntitie    4025     eventPP = &(parser->m_openInternalEntities->internalEventPtr);
4026     eventEndPP = &(parser->m_openInternalEnti    4026     eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
4027   }                                              4027   }
4028   *eventPP = s;                                  4028   *eventPP = s;
4029   *startPtr = NULL;                              4029   *startPtr = NULL;
4030                                                  4030 
4031   for (;;) {                                     4031   for (;;) {
4032     const char *next = s; /* in case of XML_T    4032     const char *next = s; /* in case of XML_TOK_NONE or XML_TOK_PARTIAL */
4033     int tok = XmlCdataSectionTok(enc, s, end,    4033     int tok = XmlCdataSectionTok(enc, s, end, &next);
4034 #ifdef XML_DTD                                   4034 #ifdef XML_DTD
4035     if (! accountingDiffTolerated(parser, tok    4035     if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, account)) {
4036       accountingOnAbort(parser);                 4036       accountingOnAbort(parser);
4037       return XML_ERROR_AMPLIFICATION_LIMIT_BR    4037       return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
4038     }                                            4038     }
4039 #else                                            4039 #else
4040     UNUSED_P(account);                           4040     UNUSED_P(account);
4041 #endif                                           4041 #endif
4042     *eventEndPP = next;                          4042     *eventEndPP = next;
4043     switch (tok) {                               4043     switch (tok) {
4044     case XML_TOK_CDATA_SECT_CLOSE:               4044     case XML_TOK_CDATA_SECT_CLOSE:
4045       if (parser->m_endCdataSectionHandler)      4045       if (parser->m_endCdataSectionHandler)
4046         parser->m_endCdataSectionHandler(pars    4046         parser->m_endCdataSectionHandler(parser->m_handlerArg);
4047       /* BEGIN disabled code */                  4047       /* BEGIN disabled code */
4048       /* see comment under XML_TOK_CDATA_SECT    4048       /* see comment under XML_TOK_CDATA_SECT_OPEN */
4049       else if (0 && parser->m_characterDataHa    4049       else if (0 && parser->m_characterDataHandler)
4050         parser->m_characterDataHandler(parser    4050         parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf,
4051                                        0);       4051                                        0);
4052       /* END disabled code */                    4052       /* END disabled code */
4053       else if (parser->m_defaultHandler)         4053       else if (parser->m_defaultHandler)
4054         reportDefault(parser, enc, s, next);     4054         reportDefault(parser, enc, s, next);
4055       *startPtr = next;                          4055       *startPtr = next;
4056       *nextPtr = next;                           4056       *nextPtr = next;
4057       if (parser->m_parsingStatus.parsing ==     4057       if (parser->m_parsingStatus.parsing == XML_FINISHED)
4058         return XML_ERROR_ABORTED;                4058         return XML_ERROR_ABORTED;
4059       else                                       4059       else
4060         return XML_ERROR_NONE;                   4060         return XML_ERROR_NONE;
4061     case XML_TOK_DATA_NEWLINE:                   4061     case XML_TOK_DATA_NEWLINE:
4062       if (parser->m_characterDataHandler) {      4062       if (parser->m_characterDataHandler) {
4063         XML_Char c = 0xA;                        4063         XML_Char c = 0xA;
4064         parser->m_characterDataHandler(parser    4064         parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
4065       } else if (parser->m_defaultHandler)       4065       } else if (parser->m_defaultHandler)
4066         reportDefault(parser, enc, s, next);     4066         reportDefault(parser, enc, s, next);
4067       break;                                     4067       break;
4068     case XML_TOK_DATA_CHARS: {                   4068     case XML_TOK_DATA_CHARS: {
4069       XML_CharacterDataHandler charDataHandle    4069       XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler;
4070       if (charDataHandler) {                     4070       if (charDataHandler) {
4071         if (MUST_CONVERT(enc, s)) {              4071         if (MUST_CONVERT(enc, s)) {
4072           for (;;) {                             4072           for (;;) {
4073             ICHAR *dataPtr = (ICHAR *)parser-    4073             ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
4074             const enum XML_Convert_Result con    4074             const enum XML_Convert_Result convert_res = XmlConvert(
4075                 enc, &s, next, &dataPtr, (ICH    4075                 enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
4076             *eventEndPP = next;                  4076             *eventEndPP = next;
4077             charDataHandler(parser->m_handler    4077             charDataHandler(parser->m_handlerArg, parser->m_dataBuf,
4078                             (int)(dataPtr - (    4078                             (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
4079             if ((convert_res == XML_CONVERT_C    4079             if ((convert_res == XML_CONVERT_COMPLETED)
4080                 || (convert_res == XML_CONVER    4080                 || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
4081               break;                             4081               break;
4082             *eventPP = s;                        4082             *eventPP = s;
4083           }                                      4083           }
4084         } else                                   4084         } else
4085           charDataHandler(parser->m_handlerAr    4085           charDataHandler(parser->m_handlerArg, (XML_Char *)s,
4086                           (int)((XML_Char *)n    4086                           (int)((XML_Char *)next - (XML_Char *)s));
4087       } else if (parser->m_defaultHandler)       4087       } else if (parser->m_defaultHandler)
4088         reportDefault(parser, enc, s, next);     4088         reportDefault(parser, enc, s, next);
4089     } break;                                     4089     } break;
4090     case XML_TOK_INVALID:                        4090     case XML_TOK_INVALID:
4091       *eventPP = next;                           4091       *eventPP = next;
4092       return XML_ERROR_INVALID_TOKEN;            4092       return XML_ERROR_INVALID_TOKEN;
4093     case XML_TOK_PARTIAL_CHAR:                   4093     case XML_TOK_PARTIAL_CHAR:
4094       if (haveMore) {                            4094       if (haveMore) {
4095         *nextPtr = s;                            4095         *nextPtr = s;
4096         return XML_ERROR_NONE;                   4096         return XML_ERROR_NONE;
4097       }                                          4097       }
4098       return XML_ERROR_PARTIAL_CHAR;             4098       return XML_ERROR_PARTIAL_CHAR;
4099     case XML_TOK_PARTIAL:                        4099     case XML_TOK_PARTIAL:
4100     case XML_TOK_NONE:                           4100     case XML_TOK_NONE:
4101       if (haveMore) {                            4101       if (haveMore) {
4102         *nextPtr = s;                            4102         *nextPtr = s;
4103         return XML_ERROR_NONE;                   4103         return XML_ERROR_NONE;
4104       }                                          4104       }
4105       return XML_ERROR_UNCLOSED_CDATA_SECTION    4105       return XML_ERROR_UNCLOSED_CDATA_SECTION;
4106     default:                                     4106     default:
4107       /* Every token returned by XmlCdataSect    4107       /* Every token returned by XmlCdataSectionTok() has its own
4108        * explicit case, so this default case     4108        * explicit case, so this default case will never be executed.
4109        * We retain it as a safety net and exc    4109        * We retain it as a safety net and exclude it from the coverage
4110        * statistics.                             4110        * statistics.
4111        *                                         4111        *
4112        * LCOV_EXCL_START                         4112        * LCOV_EXCL_START
4113        */                                        4113        */
4114       *eventPP = next;                           4114       *eventPP = next;
4115       return XML_ERROR_UNEXPECTED_STATE;         4115       return XML_ERROR_UNEXPECTED_STATE;
4116       /* LCOV_EXCL_STOP */                       4116       /* LCOV_EXCL_STOP */
4117     }                                            4117     }
4118                                                  4118 
4119     *eventPP = s = next;                         4119     *eventPP = s = next;
4120     switch (parser->m_parsingStatus.parsing)     4120     switch (parser->m_parsingStatus.parsing) {
4121     case XML_SUSPENDED:                          4121     case XML_SUSPENDED:
4122       *nextPtr = next;                           4122       *nextPtr = next;
4123       return XML_ERROR_NONE;                     4123       return XML_ERROR_NONE;
4124     case XML_FINISHED:                           4124     case XML_FINISHED:
4125       return XML_ERROR_ABORTED;                  4125       return XML_ERROR_ABORTED;
4126     default:;                                    4126     default:;
4127     }                                            4127     }
4128   }                                              4128   }
4129   /* not reached */                              4129   /* not reached */
4130 }                                                4130 }
4131                                                  4131 
4132 #ifdef XML_DTD                                   4132 #ifdef XML_DTD
4133                                                  4133 
4134 /* The idea here is to avoid using stack for     4134 /* The idea here is to avoid using stack for each IGNORE section when
4135    the whole file is parsed with one call.       4135    the whole file is parsed with one call.
4136 */                                               4136 */
4137 static enum XML_Error PTRCALL                    4137 static enum XML_Error PTRCALL
4138 ignoreSectionProcessor(XML_Parser parser, con    4138 ignoreSectionProcessor(XML_Parser parser, const char *start, const char *end,
4139                        const char **endPtr) {    4139                        const char **endPtr) {
4140   enum XML_Error result                          4140   enum XML_Error result
4141       = doIgnoreSection(parser, parser->m_enc    4141       = doIgnoreSection(parser, parser->m_encoding, &start, end, endPtr,
4142                         (XML_Bool)! parser->m    4142                         (XML_Bool)! parser->m_parsingStatus.finalBuffer);
4143   if (result != XML_ERROR_NONE)                  4143   if (result != XML_ERROR_NONE)
4144     return result;                               4144     return result;
4145   if (start) {                                   4145   if (start) {
4146     parser->m_processor = prologProcessor;       4146     parser->m_processor = prologProcessor;
4147     return prologProcessor(parser, start, end    4147     return prologProcessor(parser, start, end, endPtr);
4148   }                                              4148   }
4149   return result;                                 4149   return result;
4150 }                                                4150 }
4151                                                  4151 
4152 /* startPtr gets set to non-null is the secti    4152 /* startPtr gets set to non-null is the section is closed, and to null
4153    if the section is not yet closed.             4153    if the section is not yet closed.
4154 */                                               4154 */
4155 static enum XML_Error                            4155 static enum XML_Error
4156 doIgnoreSection(XML_Parser parser, const ENCO    4156 doIgnoreSection(XML_Parser parser, const ENCODING *enc, const char **startPtr,
4157                 const char *end, const char *    4157                 const char *end, const char **nextPtr, XML_Bool haveMore) {
4158   const char *next = *startPtr; /* in case of    4158   const char *next = *startPtr; /* in case of XML_TOK_NONE or XML_TOK_PARTIAL */
4159   int tok;                                       4159   int tok;
4160   const char *s = *startPtr;                     4160   const char *s = *startPtr;
4161   const char **eventPP;                          4161   const char **eventPP;
4162   const char **eventEndPP;                       4162   const char **eventEndPP;
4163   if (enc == parser->m_encoding) {               4163   if (enc == parser->m_encoding) {
4164     eventPP = &parser->m_eventPtr;               4164     eventPP = &parser->m_eventPtr;
4165     *eventPP = s;                                4165     *eventPP = s;
4166     eventEndPP = &parser->m_eventEndPtr;         4166     eventEndPP = &parser->m_eventEndPtr;
4167   } else {                                       4167   } else {
4168     /* It's not entirely clear, but it seems     4168     /* It's not entirely clear, but it seems the following two lines
4169      * of code cannot be executed.  The only     4169      * of code cannot be executed.  The only occasions on which 'enc'
4170      * is not 'encoding' are when this functi    4170      * is not 'encoding' are when this function is called
4171      * from the internal entity processing, a    4171      * from the internal entity processing, and IGNORE sections are an
4172      * error in internal entities.               4172      * error in internal entities.
4173      *                                           4173      *
4174      * Since it really isn't clear that this     4174      * Since it really isn't clear that this is true, we keep the code
4175      * and just remove it from our coverage t    4175      * and just remove it from our coverage tests.
4176      *                                           4176      *
4177      * LCOV_EXCL_START                           4177      * LCOV_EXCL_START
4178      */                                          4178      */
4179     eventPP = &(parser->m_openInternalEntitie    4179     eventPP = &(parser->m_openInternalEntities->internalEventPtr);
4180     eventEndPP = &(parser->m_openInternalEnti    4180     eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
4181     /* LCOV_EXCL_STOP */                         4181     /* LCOV_EXCL_STOP */
4182   }                                              4182   }
4183   *eventPP = s;                                  4183   *eventPP = s;
4184   *startPtr = NULL;                              4184   *startPtr = NULL;
4185   tok = XmlIgnoreSectionTok(enc, s, end, &nex    4185   tok = XmlIgnoreSectionTok(enc, s, end, &next);
4186 #  ifdef XML_DTD                                 4186 #  ifdef XML_DTD
4187   if (! accountingDiffTolerated(parser, tok,     4187   if (! accountingDiffTolerated(parser, tok, s, next, __LINE__,
4188                                 XML_ACCOUNT_D    4188                                 XML_ACCOUNT_DIRECT)) {
4189     accountingOnAbort(parser);                   4189     accountingOnAbort(parser);
4190     return XML_ERROR_AMPLIFICATION_LIMIT_BREA    4190     return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
4191   }                                              4191   }
4192 #  endif                                         4192 #  endif
4193   *eventEndPP = next;                            4193   *eventEndPP = next;
4194   switch (tok) {                                 4194   switch (tok) {
4195   case XML_TOK_IGNORE_SECT:                      4195   case XML_TOK_IGNORE_SECT:
4196     if (parser->m_defaultHandler)                4196     if (parser->m_defaultHandler)
4197       reportDefault(parser, enc, s, next);       4197       reportDefault(parser, enc, s, next);
4198     *startPtr = next;                            4198     *startPtr = next;
4199     *nextPtr = next;                             4199     *nextPtr = next;
4200     if (parser->m_parsingStatus.parsing == XM    4200     if (parser->m_parsingStatus.parsing == XML_FINISHED)
4201       return XML_ERROR_ABORTED;                  4201       return XML_ERROR_ABORTED;
4202     else                                         4202     else
4203       return XML_ERROR_NONE;                     4203       return XML_ERROR_NONE;
4204   case XML_TOK_INVALID:                          4204   case XML_TOK_INVALID:
4205     *eventPP = next;                             4205     *eventPP = next;
4206     return XML_ERROR_INVALID_TOKEN;              4206     return XML_ERROR_INVALID_TOKEN;
4207   case XML_TOK_PARTIAL_CHAR:                     4207   case XML_TOK_PARTIAL_CHAR:
4208     if (haveMore) {                              4208     if (haveMore) {
4209       *nextPtr = s;                              4209       *nextPtr = s;
4210       return XML_ERROR_NONE;                     4210       return XML_ERROR_NONE;
4211     }                                            4211     }
4212     return XML_ERROR_PARTIAL_CHAR;               4212     return XML_ERROR_PARTIAL_CHAR;
4213   case XML_TOK_PARTIAL:                          4213   case XML_TOK_PARTIAL:
4214   case XML_TOK_NONE:                             4214   case XML_TOK_NONE:
4215     if (haveMore) {                              4215     if (haveMore) {
4216       *nextPtr = s;                              4216       *nextPtr = s;
4217       return XML_ERROR_NONE;                     4217       return XML_ERROR_NONE;
4218     }                                            4218     }
4219     return XML_ERROR_SYNTAX; /* XML_ERROR_UNC    4219     return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
4220   default:                                       4220   default:
4221     /* All of the tokens that XmlIgnoreSectio    4221     /* All of the tokens that XmlIgnoreSectionTok() returns have
4222      * explicit cases to handle them, so this    4222      * explicit cases to handle them, so this default case is never
4223      * executed.  We keep it as a safety net     4223      * executed.  We keep it as a safety net anyway, and remove it
4224      * from our test coverage statistics.        4224      * from our test coverage statistics.
4225      *                                           4225      *
4226      * LCOV_EXCL_START                           4226      * LCOV_EXCL_START
4227      */                                          4227      */
4228     *eventPP = next;                             4228     *eventPP = next;
4229     return XML_ERROR_UNEXPECTED_STATE;           4229     return XML_ERROR_UNEXPECTED_STATE;
4230     /* LCOV_EXCL_STOP */                         4230     /* LCOV_EXCL_STOP */
4231   }                                              4231   }
4232   /* not reached */                              4232   /* not reached */
4233 }                                                4233 }
4234                                                  4234 
4235 #endif /* XML_DTD */                             4235 #endif /* XML_DTD */
4236                                                  4236 
4237 static enum XML_Error                            4237 static enum XML_Error
4238 initializeEncoding(XML_Parser parser) {          4238 initializeEncoding(XML_Parser parser) {
4239   const char *s;                                 4239   const char *s;
4240 #ifdef XML_UNICODE                               4240 #ifdef XML_UNICODE
4241   char encodingBuf[128];                         4241   char encodingBuf[128];
4242   /* See comments about `protocolEncodingName    4242   /* See comments about `protocolEncodingName` in parserInit() */
4243   if (! parser->m_protocolEncodingName)          4243   if (! parser->m_protocolEncodingName)
4244     s = NULL;                                    4244     s = NULL;
4245   else {                                         4245   else {
4246     int i;                                       4246     int i;
4247     for (i = 0; parser->m_protocolEncodingNam    4247     for (i = 0; parser->m_protocolEncodingName[i]; i++) {
4248       if (i == sizeof(encodingBuf) - 1           4248       if (i == sizeof(encodingBuf) - 1
4249           || (parser->m_protocolEncodingName[    4249           || (parser->m_protocolEncodingName[i] & ~0x7f) != 0) {
4250         encodingBuf[0] = '\0';                   4250         encodingBuf[0] = '\0';
4251         break;                                   4251         break;
4252       }                                          4252       }
4253       encodingBuf[i] = (char)parser->m_protoc    4253       encodingBuf[i] = (char)parser->m_protocolEncodingName[i];
4254     }                                            4254     }
4255     encodingBuf[i] = '\0';                       4255     encodingBuf[i] = '\0';
4256     s = encodingBuf;                             4256     s = encodingBuf;
4257   }                                              4257   }
4258 #else                                            4258 #else
4259   s = parser->m_protocolEncodingName;            4259   s = parser->m_protocolEncodingName;
4260 #endif                                           4260 #endif
4261   if ((parser->m_ns ? XmlInitEncodingNS : Xml    4261   if ((parser->m_ns ? XmlInitEncodingNS : XmlInitEncoding)(
4262           &parser->m_initEncoding, &parser->m    4262           &parser->m_initEncoding, &parser->m_encoding, s))
4263     return XML_ERROR_NONE;                       4263     return XML_ERROR_NONE;
4264   return handleUnknownEncoding(parser, parser    4264   return handleUnknownEncoding(parser, parser->m_protocolEncodingName);
4265 }                                                4265 }
4266                                                  4266 
4267 static enum XML_Error                            4267 static enum XML_Error
4268 processXmlDecl(XML_Parser parser, int isGener    4268 processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *s,
4269                const char *next) {               4269                const char *next) {
4270   const char *encodingName = NULL;               4270   const char *encodingName = NULL;
4271   const XML_Char *storedEncName = NULL;          4271   const XML_Char *storedEncName = NULL;
4272   const ENCODING *newEncoding = NULL;            4272   const ENCODING *newEncoding = NULL;
4273   const char *version = NULL;                    4273   const char *version = NULL;
4274   const char *versionend = NULL;                 4274   const char *versionend = NULL;
4275   const XML_Char *storedversion = NULL;          4275   const XML_Char *storedversion = NULL;
4276   int standalone = -1;                           4276   int standalone = -1;
4277                                                  4277 
4278 #ifdef XML_DTD                                   4278 #ifdef XML_DTD
4279   if (! accountingDiffTolerated(parser, XML_T    4279   if (! accountingDiffTolerated(parser, XML_TOK_XML_DECL, s, next, __LINE__,
4280                                 XML_ACCOUNT_D    4280                                 XML_ACCOUNT_DIRECT)) {
4281     accountingOnAbort(parser);                   4281     accountingOnAbort(parser);
4282     return XML_ERROR_AMPLIFICATION_LIMIT_BREA    4282     return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
4283   }                                              4283   }
4284 #endif                                           4284 #endif
4285                                                  4285 
4286   if (! (parser->m_ns ? XmlParseXmlDeclNS : X    4286   if (! (parser->m_ns ? XmlParseXmlDeclNS : XmlParseXmlDecl)(
4287           isGeneralTextEntity, parser->m_enco    4287           isGeneralTextEntity, parser->m_encoding, s, next, &parser->m_eventPtr,
4288           &version, &versionend, &encodingNam    4288           &version, &versionend, &encodingName, &newEncoding, &standalone)) {
4289     if (isGeneralTextEntity)                     4289     if (isGeneralTextEntity)
4290       return XML_ERROR_TEXT_DECL;                4290       return XML_ERROR_TEXT_DECL;
4291     else                                         4291     else
4292       return XML_ERROR_XML_DECL;                 4292       return XML_ERROR_XML_DECL;
4293   }                                              4293   }
4294   if (! isGeneralTextEntity && standalone ==     4294   if (! isGeneralTextEntity && standalone == 1) {
4295     parser->m_dtd->standalone = XML_TRUE;        4295     parser->m_dtd->standalone = XML_TRUE;
4296 #ifdef XML_DTD                                   4296 #ifdef XML_DTD
4297     if (parser->m_paramEntityParsing             4297     if (parser->m_paramEntityParsing
4298         == XML_PARAM_ENTITY_PARSING_UNLESS_ST    4298         == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
4299       parser->m_paramEntityParsing = XML_PARA    4299       parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
4300 #endif /* XML_DTD */                             4300 #endif /* XML_DTD */
4301   }                                              4301   }
4302   if (parser->m_xmlDeclHandler) {                4302   if (parser->m_xmlDeclHandler) {
4303     if (encodingName != NULL) {                  4303     if (encodingName != NULL) {
4304       storedEncName = poolStoreString(           4304       storedEncName = poolStoreString(
4305           &parser->m_temp2Pool, parser->m_enc    4305           &parser->m_temp2Pool, parser->m_encoding, encodingName,
4306           encodingName + XmlNameLength(parser    4306           encodingName + XmlNameLength(parser->m_encoding, encodingName));
4307       if (! storedEncName)                       4307       if (! storedEncName)
4308         return XML_ERROR_NO_MEMORY;              4308         return XML_ERROR_NO_MEMORY;
4309       poolFinish(&parser->m_temp2Pool);          4309       poolFinish(&parser->m_temp2Pool);
4310     }                                            4310     }
4311     if (version) {                               4311     if (version) {
4312       storedversion                              4312       storedversion
4313           = poolStoreString(&parser->m_temp2P    4313           = poolStoreString(&parser->m_temp2Pool, parser->m_encoding, version,
4314                             versionend - pars    4314                             versionend - parser->m_encoding->minBytesPerChar);
4315       if (! storedversion)                       4315       if (! storedversion)
4316         return XML_ERROR_NO_MEMORY;              4316         return XML_ERROR_NO_MEMORY;
4317     }                                            4317     }
4318     parser->m_xmlDeclHandler(parser->m_handle    4318     parser->m_xmlDeclHandler(parser->m_handlerArg, storedversion, storedEncName,
4319                              standalone);        4319                              standalone);
4320   } else if (parser->m_defaultHandler)           4320   } else if (parser->m_defaultHandler)
4321     reportDefault(parser, parser->m_encoding,    4321     reportDefault(parser, parser->m_encoding, s, next);
4322   if (parser->m_protocolEncodingName == NULL)    4322   if (parser->m_protocolEncodingName == NULL) {
4323     if (newEncoding) {                           4323     if (newEncoding) {
4324       /* Check that the specified encoding do    4324       /* Check that the specified encoding does not conflict with what
4325        * the parser has already deduced.  Do     4325        * the parser has already deduced.  Do we have the same number
4326        * of bytes in the smallest representat    4326        * of bytes in the smallest representation of a character?  If
4327        * this is UTF-16, is it the same endia    4327        * this is UTF-16, is it the same endianness?
4328        */                                        4328        */
4329       if (newEncoding->minBytesPerChar != par    4329       if (newEncoding->minBytesPerChar != parser->m_encoding->minBytesPerChar
4330           || (newEncoding->minBytesPerChar ==    4330           || (newEncoding->minBytesPerChar == 2
4331               && newEncoding != parser->m_enc    4331               && newEncoding != parser->m_encoding)) {
4332         parser->m_eventPtr = encodingName;       4332         parser->m_eventPtr = encodingName;
4333         return XML_ERROR_INCORRECT_ENCODING;     4333         return XML_ERROR_INCORRECT_ENCODING;
4334       }                                          4334       }
4335       parser->m_encoding = newEncoding;          4335       parser->m_encoding = newEncoding;
4336     } else if (encodingName) {                   4336     } else if (encodingName) {
4337       enum XML_Error result;                     4337       enum XML_Error result;
4338       if (! storedEncName) {                     4338       if (! storedEncName) {
4339         storedEncName = poolStoreString(         4339         storedEncName = poolStoreString(
4340             &parser->m_temp2Pool, parser->m_e    4340             &parser->m_temp2Pool, parser->m_encoding, encodingName,
4341             encodingName + XmlNameLength(pars    4341             encodingName + XmlNameLength(parser->m_encoding, encodingName));
4342         if (! storedEncName)                     4342         if (! storedEncName)
4343           return XML_ERROR_NO_MEMORY;            4343           return XML_ERROR_NO_MEMORY;
4344       }                                          4344       }
4345       result = handleUnknownEncoding(parser,     4345       result = handleUnknownEncoding(parser, storedEncName);
4346       poolClear(&parser->m_temp2Pool);           4346       poolClear(&parser->m_temp2Pool);
4347       if (result == XML_ERROR_UNKNOWN_ENCODIN    4347       if (result == XML_ERROR_UNKNOWN_ENCODING)
4348         parser->m_eventPtr = encodingName;       4348         parser->m_eventPtr = encodingName;
4349       return result;                             4349       return result;
4350     }                                            4350     }
4351   }                                              4351   }
4352                                                  4352 
4353   if (storedEncName || storedversion)            4353   if (storedEncName || storedversion)
4354     poolClear(&parser->m_temp2Pool);             4354     poolClear(&parser->m_temp2Pool);
4355                                                  4355 
4356   return XML_ERROR_NONE;                         4356   return XML_ERROR_NONE;
4357 }                                                4357 }
4358                                                  4358 
4359 static enum XML_Error                            4359 static enum XML_Error
4360 handleUnknownEncoding(XML_Parser parser, cons    4360 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) {
4361   if (parser->m_unknownEncodingHandler) {        4361   if (parser->m_unknownEncodingHandler) {
4362     XML_Encoding info;                           4362     XML_Encoding info;
4363     int i;                                       4363     int i;
4364     for (i = 0; i < 256; i++)                    4364     for (i = 0; i < 256; i++)
4365       info.map[i] = -1;                          4365       info.map[i] = -1;
4366     info.convert = NULL;                         4366     info.convert = NULL;
4367     info.data = NULL;                            4367     info.data = NULL;
4368     info.release = NULL;                         4368     info.release = NULL;
4369     if (parser->m_unknownEncodingHandler(pars    4369     if (parser->m_unknownEncodingHandler(parser->m_unknownEncodingHandlerData,
4370                                          enco    4370                                          encodingName, &info)) {
4371       ENCODING *enc;                             4371       ENCODING *enc;
4372       parser->m_unknownEncodingMem = MALLOC(p    4372       parser->m_unknownEncodingMem = MALLOC(parser, XmlSizeOfUnknownEncoding());
4373       if (! parser->m_unknownEncodingMem) {      4373       if (! parser->m_unknownEncodingMem) {
4374         if (info.release)                        4374         if (info.release)
4375           info.release(info.data);               4375           info.release(info.data);
4376         return XML_ERROR_NO_MEMORY;              4376         return XML_ERROR_NO_MEMORY;
4377       }                                          4377       }
4378       enc = (parser->m_ns ? XmlInitUnknownEnc    4378       enc = (parser->m_ns ? XmlInitUnknownEncodingNS : XmlInitUnknownEncoding)(
4379           parser->m_unknownEncodingMem, info.    4379           parser->m_unknownEncodingMem, info.map, info.convert, info.data);
4380       if (enc) {                                 4380       if (enc) {
4381         parser->m_unknownEncodingData = info.    4381         parser->m_unknownEncodingData = info.data;
4382         parser->m_unknownEncodingRelease = in    4382         parser->m_unknownEncodingRelease = info.release;
4383         parser->m_encoding = enc;                4383         parser->m_encoding = enc;
4384         return XML_ERROR_NONE;                   4384         return XML_ERROR_NONE;
4385       }                                          4385       }
4386     }                                            4386     }
4387     if (info.release != NULL)                    4387     if (info.release != NULL)
4388       info.release(info.data);                   4388       info.release(info.data);
4389   }                                              4389   }
4390   return XML_ERROR_UNKNOWN_ENCODING;             4390   return XML_ERROR_UNKNOWN_ENCODING;
4391 }                                                4391 }
4392                                                  4392 
4393 static enum XML_Error PTRCALL                    4393 static enum XML_Error PTRCALL
4394 prologInitProcessor(XML_Parser parser, const     4394 prologInitProcessor(XML_Parser parser, const char *s, const char *end,
4395                     const char **nextPtr) {      4395                     const char **nextPtr) {
4396   enum XML_Error result = initializeEncoding(    4396   enum XML_Error result = initializeEncoding(parser);
4397   if (result != XML_ERROR_NONE)                  4397   if (result != XML_ERROR_NONE)
4398     return result;                               4398     return result;
4399   parser->m_processor = prologProcessor;         4399   parser->m_processor = prologProcessor;
4400   return prologProcessor(parser, s, end, next    4400   return prologProcessor(parser, s, end, nextPtr);
4401 }                                                4401 }
4402                                                  4402 
4403 #ifdef XML_DTD                                   4403 #ifdef XML_DTD
4404                                                  4404 
4405 static enum XML_Error PTRCALL                    4405 static enum XML_Error PTRCALL
4406 externalParEntInitProcessor(XML_Parser parser    4406 externalParEntInitProcessor(XML_Parser parser, const char *s, const char *end,
4407                             const char **next    4407                             const char **nextPtr) {
4408   enum XML_Error result = initializeEncoding(    4408   enum XML_Error result = initializeEncoding(parser);
4409   if (result != XML_ERROR_NONE)                  4409   if (result != XML_ERROR_NONE)
4410     return result;                               4410     return result;
4411                                                  4411 
4412   /* we know now that XML_Parse(Buffer) has b    4412   /* we know now that XML_Parse(Buffer) has been called,
4413      so we consider the external parameter en    4413      so we consider the external parameter entity read */
4414   parser->m_dtd->paramEntityRead = XML_TRUE;     4414   parser->m_dtd->paramEntityRead = XML_TRUE;
4415                                                  4415 
4416   if (parser->m_prologState.inEntityValue) {     4416   if (parser->m_prologState.inEntityValue) {
4417     parser->m_processor = entityValueInitProc    4417     parser->m_processor = entityValueInitProcessor;
4418     return entityValueInitProcessor(parser, s    4418     return entityValueInitProcessor(parser, s, end, nextPtr);
4419   } else {                                       4419   } else {
4420     parser->m_processor = externalParEntProce    4420     parser->m_processor = externalParEntProcessor;
4421     return externalParEntProcessor(parser, s,    4421     return externalParEntProcessor(parser, s, end, nextPtr);
4422   }                                              4422   }
4423 }                                                4423 }
4424                                                  4424 
4425 static enum XML_Error PTRCALL                    4425 static enum XML_Error PTRCALL
4426 entityValueInitProcessor(XML_Parser parser, c    4426 entityValueInitProcessor(XML_Parser parser, const char *s, const char *end,
4427                          const char **nextPtr    4427                          const char **nextPtr) {
4428   int tok;                                       4428   int tok;
4429   const char *start = s;                         4429   const char *start = s;
4430   const char *next = start;                      4430   const char *next = start;
4431   parser->m_eventPtr = start;                    4431   parser->m_eventPtr = start;
4432                                                  4432 
4433   for (;;) {                                     4433   for (;;) {
4434     tok = XmlPrologTok(parser->m_encoding, st    4434     tok = XmlPrologTok(parser->m_encoding, start, end, &next);
4435     /* Note: Except for XML_TOK_BOM below, th    4435     /* Note: Except for XML_TOK_BOM below, these bytes are accounted later in:
4436              - storeEntityValue                  4436              - storeEntityValue
4437              - processXmlDecl                    4437              - processXmlDecl
4438     */                                           4438     */
4439     parser->m_eventEndPtr = next;                4439     parser->m_eventEndPtr = next;
4440     if (tok <= 0) {                              4440     if (tok <= 0) {
4441       if (! parser->m_parsingStatus.finalBuff    4441       if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
4442         *nextPtr = s;                            4442         *nextPtr = s;
4443         return XML_ERROR_NONE;                   4443         return XML_ERROR_NONE;
4444       }                                          4444       }
4445       switch (tok) {                             4445       switch (tok) {
4446       case XML_TOK_INVALID:                      4446       case XML_TOK_INVALID:
4447         return XML_ERROR_INVALID_TOKEN;          4447         return XML_ERROR_INVALID_TOKEN;
4448       case XML_TOK_PARTIAL:                      4448       case XML_TOK_PARTIAL:
4449         return XML_ERROR_UNCLOSED_TOKEN;         4449         return XML_ERROR_UNCLOSED_TOKEN;
4450       case XML_TOK_PARTIAL_CHAR:                 4450       case XML_TOK_PARTIAL_CHAR:
4451         return XML_ERROR_PARTIAL_CHAR;           4451         return XML_ERROR_PARTIAL_CHAR;
4452       case XML_TOK_NONE: /* start == end */      4452       case XML_TOK_NONE: /* start == end */
4453       default:                                   4453       default:
4454         break;                                   4454         break;
4455       }                                          4455       }
4456       /* found end of entity value - can stor    4456       /* found end of entity value - can store it now */
4457       return storeEntityValue(parser, parser-    4457       return storeEntityValue(parser, parser->m_encoding, s, end,
4458                               XML_ACCOUNT_DIR    4458                               XML_ACCOUNT_DIRECT);
4459     } else if (tok == XML_TOK_XML_DECL) {        4459     } else if (tok == XML_TOK_XML_DECL) {
4460       enum XML_Error result;                     4460       enum XML_Error result;
4461       result = processXmlDecl(parser, 0, star    4461       result = processXmlDecl(parser, 0, start, next);
4462       if (result != XML_ERROR_NONE)              4462       if (result != XML_ERROR_NONE)
4463         return result;                           4463         return result;
4464       /* At this point, m_parsingStatus.parsi    4464       /* At this point, m_parsingStatus.parsing cannot be XML_SUSPENDED.  For
4465        * that to happen, a parameter entity p    4465        * that to happen, a parameter entity parsing handler must have attempted
4466        * to suspend the parser, which fails a    4466        * to suspend the parser, which fails and raises an error.  The parser can
4467        * be aborted, but can't be suspended.     4467        * be aborted, but can't be suspended.
4468        */                                        4468        */
4469       if (parser->m_parsingStatus.parsing ==     4469       if (parser->m_parsingStatus.parsing == XML_FINISHED)
4470         return XML_ERROR_ABORTED;                4470         return XML_ERROR_ABORTED;
4471       *nextPtr = next;                           4471       *nextPtr = next;
4472       /* stop scanning for text declaration -    4472       /* stop scanning for text declaration - we found one */
4473       parser->m_processor = entityValueProces    4473       parser->m_processor = entityValueProcessor;
4474       return entityValueProcessor(parser, nex    4474       return entityValueProcessor(parser, next, end, nextPtr);
4475     }                                            4475     }
4476     /* If we are at the end of the buffer, th    4476     /* If we are at the end of the buffer, this would cause XmlPrologTok to
4477        return XML_TOK_NONE on the next call,     4477        return XML_TOK_NONE on the next call, which would then cause the
4478        function to exit with *nextPtr set to     4478        function to exit with *nextPtr set to s - that is what we want for other
4479        tokens, but not for the BOM - we would    4479        tokens, but not for the BOM - we would rather like to skip it;
4480        then, when this routine is entered the    4480        then, when this routine is entered the next time, XmlPrologTok will
4481        return XML_TOK_INVALID, since the BOM     4481        return XML_TOK_INVALID, since the BOM is still in the buffer
4482     */                                           4482     */
4483     else if (tok == XML_TOK_BOM && next == en    4483     else if (tok == XML_TOK_BOM && next == end
4484              && ! parser->m_parsingStatus.fin    4484              && ! parser->m_parsingStatus.finalBuffer) {
4485 #  ifdef XML_DTD                                 4485 #  ifdef XML_DTD
4486       if (! accountingDiffTolerated(parser, t    4486       if (! accountingDiffTolerated(parser, tok, s, next, __LINE__,
4487                                     XML_ACCOU    4487                                     XML_ACCOUNT_DIRECT)) {
4488         accountingOnAbort(parser);               4488         accountingOnAbort(parser);
4489         return XML_ERROR_AMPLIFICATION_LIMIT_    4489         return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
4490       }                                          4490       }
4491 #  endif                                         4491 #  endif
4492                                                  4492 
4493       *nextPtr = next;                           4493       *nextPtr = next;
4494       return XML_ERROR_NONE;                     4494       return XML_ERROR_NONE;
4495     }                                            4495     }
4496     /* If we get this token, we have the star    4496     /* If we get this token, we have the start of what might be a
4497        normal tag, but not a declaration (i.e    4497        normal tag, but not a declaration (i.e. it doesn't begin with
4498        "<!").  In a DTD context, that isn't l    4498        "<!").  In a DTD context, that isn't legal.
4499     */                                           4499     */
4500     else if (tok == XML_TOK_INSTANCE_START) {    4500     else if (tok == XML_TOK_INSTANCE_START) {
4501       *nextPtr = next;                           4501       *nextPtr = next;
4502       return XML_ERROR_SYNTAX;                   4502       return XML_ERROR_SYNTAX;
4503     }                                            4503     }
4504     start = next;                                4504     start = next;
4505     parser->m_eventPtr = start;                  4505     parser->m_eventPtr = start;
4506   }                                              4506   }
4507 }                                                4507 }
4508                                                  4508 
4509 static enum XML_Error PTRCALL                    4509 static enum XML_Error PTRCALL
4510 externalParEntProcessor(XML_Parser parser, co    4510 externalParEntProcessor(XML_Parser parser, const char *s, const char *end,
4511                         const char **nextPtr)    4511                         const char **nextPtr) {
4512   const char *next = s;                          4512   const char *next = s;
4513   int tok;                                       4513   int tok;
4514                                                  4514 
4515   tok = XmlPrologTok(parser->m_encoding, s, e    4515   tok = XmlPrologTok(parser->m_encoding, s, end, &next);
4516   if (tok <= 0) {                                4516   if (tok <= 0) {
4517     if (! parser->m_parsingStatus.finalBuffer    4517     if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
4518       *nextPtr = s;                              4518       *nextPtr = s;
4519       return XML_ERROR_NONE;                     4519       return XML_ERROR_NONE;
4520     }                                            4520     }
4521     switch (tok) {                               4521     switch (tok) {
4522     case XML_TOK_INVALID:                        4522     case XML_TOK_INVALID:
4523       return XML_ERROR_INVALID_TOKEN;            4523       return XML_ERROR_INVALID_TOKEN;
4524     case XML_TOK_PARTIAL:                        4524     case XML_TOK_PARTIAL:
4525       return XML_ERROR_UNCLOSED_TOKEN;           4525       return XML_ERROR_UNCLOSED_TOKEN;
4526     case XML_TOK_PARTIAL_CHAR:                   4526     case XML_TOK_PARTIAL_CHAR:
4527       return XML_ERROR_PARTIAL_CHAR;             4527       return XML_ERROR_PARTIAL_CHAR;
4528     case XML_TOK_NONE: /* start == end */        4528     case XML_TOK_NONE: /* start == end */
4529     default:                                     4529     default:
4530       break;                                     4530       break;
4531     }                                            4531     }
4532   }                                              4532   }
4533   /* This would cause the next stage, i.e. do    4533   /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
4534      However, when parsing an external subset    4534      However, when parsing an external subset, doProlog will not accept a BOM
4535      as valid, and report a syntax error, so     4535      as valid, and report a syntax error, so we have to skip the BOM, and
4536      account for the BOM bytes.                  4536      account for the BOM bytes.
4537   */                                             4537   */
4538   else if (tok == XML_TOK_BOM) {                 4538   else if (tok == XML_TOK_BOM) {
4539     if (! accountingDiffTolerated(parser, tok    4539     if (! accountingDiffTolerated(parser, tok, s, next, __LINE__,
4540                                   XML_ACCOUNT    4540                                   XML_ACCOUNT_DIRECT)) {
4541       accountingOnAbort(parser);                 4541       accountingOnAbort(parser);
4542       return XML_ERROR_AMPLIFICATION_LIMIT_BR    4542       return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
4543     }                                            4543     }
4544                                                  4544 
4545     s = next;                                    4545     s = next;
4546     tok = XmlPrologTok(parser->m_encoding, s,    4546     tok = XmlPrologTok(parser->m_encoding, s, end, &next);
4547   }                                              4547   }
4548                                                  4548 
4549   parser->m_processor = prologProcessor;         4549   parser->m_processor = prologProcessor;
4550   return doProlog(parser, parser->m_encoding,    4550   return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
4551                   (XML_Bool)! parser->m_parsi    4551                   (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE,
4552                   XML_ACCOUNT_DIRECT);           4552                   XML_ACCOUNT_DIRECT);
4553 }                                                4553 }
4554                                                  4554 
4555 static enum XML_Error PTRCALL                    4555 static enum XML_Error PTRCALL
4556 entityValueProcessor(XML_Parser parser, const    4556 entityValueProcessor(XML_Parser parser, const char *s, const char *end,
4557                      const char **nextPtr) {     4557                      const char **nextPtr) {
4558   const char *start = s;                         4558   const char *start = s;
4559   const char *next = s;                          4559   const char *next = s;
4560   const ENCODING *enc = parser->m_encoding;      4560   const ENCODING *enc = parser->m_encoding;
4561   int tok;                                       4561   int tok;
4562                                                  4562 
4563   for (;;) {                                     4563   for (;;) {
4564     tok = XmlPrologTok(enc, start, end, &next    4564     tok = XmlPrologTok(enc, start, end, &next);
4565     /* Note: These bytes are accounted later     4565     /* Note: These bytes are accounted later in:
4566              - storeEntityValue                  4566              - storeEntityValue
4567     */                                           4567     */
4568     if (tok <= 0) {                              4568     if (tok <= 0) {
4569       if (! parser->m_parsingStatus.finalBuff    4569       if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
4570         *nextPtr = s;                            4570         *nextPtr = s;
4571         return XML_ERROR_NONE;                   4571         return XML_ERROR_NONE;
4572       }                                          4572       }
4573       switch (tok) {                             4573       switch (tok) {
4574       case XML_TOK_INVALID:                      4574       case XML_TOK_INVALID:
4575         return XML_ERROR_INVALID_TOKEN;          4575         return XML_ERROR_INVALID_TOKEN;
4576       case XML_TOK_PARTIAL:                      4576       case XML_TOK_PARTIAL:
4577         return XML_ERROR_UNCLOSED_TOKEN;         4577         return XML_ERROR_UNCLOSED_TOKEN;
4578       case XML_TOK_PARTIAL_CHAR:                 4578       case XML_TOK_PARTIAL_CHAR:
4579         return XML_ERROR_PARTIAL_CHAR;           4579         return XML_ERROR_PARTIAL_CHAR;
4580       case XML_TOK_NONE: /* start == end */      4580       case XML_TOK_NONE: /* start == end */
4581       default:                                   4581       default:
4582         break;                                   4582         break;
4583       }                                          4583       }
4584       /* found end of entity value - can stor    4584       /* found end of entity value - can store it now */
4585       return storeEntityValue(parser, enc, s,    4585       return storeEntityValue(parser, enc, s, end, XML_ACCOUNT_DIRECT);
4586     }                                            4586     }
4587     start = next;                                4587     start = next;
4588   }                                              4588   }
4589 }                                                4589 }
4590                                                  4590 
4591 #endif /* XML_DTD */                             4591 #endif /* XML_DTD */
4592                                                  4592 
4593 static enum XML_Error PTRCALL                    4593 static enum XML_Error PTRCALL
4594 prologProcessor(XML_Parser parser, const char    4594 prologProcessor(XML_Parser parser, const char *s, const char *end,
4595                 const char **nextPtr) {          4595                 const char **nextPtr) {
4596   const char *next = s;                          4596   const char *next = s;
4597   int tok = XmlPrologTok(parser->m_encoding,     4597   int tok = XmlPrologTok(parser->m_encoding, s, end, &next);
4598   return doProlog(parser, parser->m_encoding,    4598   return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
4599                   (XML_Bool)! parser->m_parsi    4599                   (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE,
4600                   XML_ACCOUNT_DIRECT);           4600                   XML_ACCOUNT_DIRECT);
4601 }                                                4601 }
4602                                                  4602 
4603 static enum XML_Error                            4603 static enum XML_Error
4604 doProlog(XML_Parser parser, const ENCODING *e    4604 doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
4605          int tok, const char *next, const cha    4605          int tok, const char *next, const char **nextPtr, XML_Bool haveMore,
4606          XML_Bool allowClosingDoctype, enum X    4606          XML_Bool allowClosingDoctype, enum XML_Account account) {
4607 #ifdef XML_DTD                                   4607 #ifdef XML_DTD
4608   static const XML_Char externalSubsetName[]     4608   static const XML_Char externalSubsetName[] = {ASCII_HASH, '\0'};
4609 #endif /* XML_DTD */                             4609 #endif /* XML_DTD */
4610   static const XML_Char atypeCDATA[]             4610   static const XML_Char atypeCDATA[]
4611       = {ASCII_C, ASCII_D, ASCII_A, ASCII_T,     4611       = {ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'};
4612   static const XML_Char atypeID[] = {ASCII_I,    4612   static const XML_Char atypeID[] = {ASCII_I, ASCII_D, '\0'};
4613   static const XML_Char atypeIDREF[]             4613   static const XML_Char atypeIDREF[]
4614       = {ASCII_I, ASCII_D, ASCII_R, ASCII_E,     4614       = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0'};
4615   static const XML_Char atypeIDREFS[]            4615   static const XML_Char atypeIDREFS[]
4616       = {ASCII_I, ASCII_D, ASCII_R, ASCII_E,     4616       = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0'};
4617   static const XML_Char atypeENTITY[]            4617   static const XML_Char atypeENTITY[]
4618       = {ASCII_E, ASCII_N, ASCII_T, ASCII_I,     4618       = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0'};
4619   static const XML_Char atypeENTITIES[]          4619   static const XML_Char atypeENTITIES[]
4620       = {ASCII_E, ASCII_N, ASCII_T, ASCII_I,     4620       = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T,
4621          ASCII_I, ASCII_E, ASCII_S, '\0'};       4621          ASCII_I, ASCII_E, ASCII_S, '\0'};
4622   static const XML_Char atypeNMTOKEN[]           4622   static const XML_Char atypeNMTOKEN[]
4623       = {ASCII_N, ASCII_M, ASCII_T, ASCII_O,     4623       = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0'};
4624   static const XML_Char atypeNMTOKENS[]          4624   static const XML_Char atypeNMTOKENS[]
4625       = {ASCII_N, ASCII_M, ASCII_T, ASCII_O,     4625       = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K,
4626          ASCII_E, ASCII_N, ASCII_S, '\0'};       4626          ASCII_E, ASCII_N, ASCII_S, '\0'};
4627   static const XML_Char notationPrefix[]         4627   static const XML_Char notationPrefix[]
4628       = {ASCII_N, ASCII_O, ASCII_T, ASCII_A,     4628       = {ASCII_N, ASCII_O, ASCII_T, ASCII_A,      ASCII_T,
4629          ASCII_I, ASCII_O, ASCII_N, ASCII_LPA    4629          ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0'};
4630   static const XML_Char enumValueSep[] = {ASC    4630   static const XML_Char enumValueSep[] = {ASCII_PIPE, '\0'};
4631   static const XML_Char enumValueStart[] = {A    4631   static const XML_Char enumValueStart[] = {ASCII_LPAREN, '\0'};
4632                                                  4632 
4633 #ifndef XML_DTD                                  4633 #ifndef XML_DTD
4634   UNUSED_P(account);                             4634   UNUSED_P(account);
4635 #endif                                           4635 #endif
4636                                                  4636 
4637   /* save one level of indirection */            4637   /* save one level of indirection */
4638   DTD *const dtd = parser->m_dtd;                4638   DTD *const dtd = parser->m_dtd;
4639                                                  4639 
4640   const char **eventPP;                          4640   const char **eventPP;
4641   const char **eventEndPP;                       4641   const char **eventEndPP;
4642   enum XML_Content_Quant quant;                  4642   enum XML_Content_Quant quant;
4643                                                  4643 
4644   if (enc == parser->m_encoding) {               4644   if (enc == parser->m_encoding) {
4645     eventPP = &parser->m_eventPtr;               4645     eventPP = &parser->m_eventPtr;
4646     eventEndPP = &parser->m_eventEndPtr;         4646     eventEndPP = &parser->m_eventEndPtr;
4647   } else {                                       4647   } else {
4648     eventPP = &(parser->m_openInternalEntitie    4648     eventPP = &(parser->m_openInternalEntities->internalEventPtr);
4649     eventEndPP = &(parser->m_openInternalEnti    4649     eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
4650   }                                              4650   }
4651                                                  4651 
4652   for (;;) {                                     4652   for (;;) {
4653     int role;                                    4653     int role;
4654     XML_Bool handleDefault = XML_TRUE;           4654     XML_Bool handleDefault = XML_TRUE;
4655     *eventPP = s;                                4655     *eventPP = s;
4656     *eventEndPP = next;                          4656     *eventEndPP = next;
4657     if (tok <= 0) {                              4657     if (tok <= 0) {
4658       if (haveMore && tok != XML_TOK_INVALID)    4658       if (haveMore && tok != XML_TOK_INVALID) {
4659         *nextPtr = s;                            4659         *nextPtr = s;
4660         return XML_ERROR_NONE;                   4660         return XML_ERROR_NONE;
4661       }                                          4661       }
4662       switch (tok) {                             4662       switch (tok) {
4663       case XML_TOK_INVALID:                      4663       case XML_TOK_INVALID:
4664         *eventPP = next;                         4664         *eventPP = next;
4665         return XML_ERROR_INVALID_TOKEN;          4665         return XML_ERROR_INVALID_TOKEN;
4666       case XML_TOK_PARTIAL:                      4666       case XML_TOK_PARTIAL:
4667         return XML_ERROR_UNCLOSED_TOKEN;         4667         return XML_ERROR_UNCLOSED_TOKEN;
4668       case XML_TOK_PARTIAL_CHAR:                 4668       case XML_TOK_PARTIAL_CHAR:
4669         return XML_ERROR_PARTIAL_CHAR;           4669         return XML_ERROR_PARTIAL_CHAR;
4670       case -XML_TOK_PROLOG_S:                    4670       case -XML_TOK_PROLOG_S:
4671         tok = -tok;                              4671         tok = -tok;
4672         break;                                   4672         break;
4673       case XML_TOK_NONE:                         4673       case XML_TOK_NONE:
4674 #ifdef XML_DTD                                   4674 #ifdef XML_DTD
4675         /* for internal PE NOT referenced bet    4675         /* for internal PE NOT referenced between declarations */
4676         if (enc != parser->m_encoding            4676         if (enc != parser->m_encoding
4677             && ! parser->m_openInternalEntiti    4677             && ! parser->m_openInternalEntities->betweenDecl) {
4678           *nextPtr = s;                          4678           *nextPtr = s;
4679           return XML_ERROR_NONE;                 4679           return XML_ERROR_NONE;
4680         }                                        4680         }
4681         /* WFC: PE Between Declarations - mus    4681         /* WFC: PE Between Declarations - must check that PE contains
4682            complete markup, not only for exte    4682            complete markup, not only for external PEs, but also for
4683            internal PEs if the reference occu    4683            internal PEs if the reference occurs between declarations.
4684         */                                       4684         */
4685         if (parser->m_isParamEntity || enc !=    4685         if (parser->m_isParamEntity || enc != parser->m_encoding) {
4686           if (XmlTokenRole(&parser->m_prologS    4686           if (XmlTokenRole(&parser->m_prologState, XML_TOK_NONE, end, end, enc)
4687               == XML_ROLE_ERROR)                 4687               == XML_ROLE_ERROR)
4688             return XML_ERROR_INCOMPLETE_PE;      4688             return XML_ERROR_INCOMPLETE_PE;
4689           *nextPtr = s;                          4689           *nextPtr = s;
4690           return XML_ERROR_NONE;                 4690           return XML_ERROR_NONE;
4691         }                                        4691         }
4692 #endif /* XML_DTD */                             4692 #endif /* XML_DTD */
4693         return XML_ERROR_NO_ELEMENTS;            4693         return XML_ERROR_NO_ELEMENTS;
4694       default:                                   4694       default:
4695         tok = -tok;                              4695         tok = -tok;
4696         next = end;                              4696         next = end;
4697         break;                                   4697         break;
4698       }                                          4698       }
4699     }                                            4699     }
4700     role = XmlTokenRole(&parser->m_prologStat    4700     role = XmlTokenRole(&parser->m_prologState, tok, s, next, enc);
4701 #ifdef XML_DTD                                   4701 #ifdef XML_DTD
4702     switch (role) {                              4702     switch (role) {
4703     case XML_ROLE_INSTANCE_START: // bytes ac    4703     case XML_ROLE_INSTANCE_START: // bytes accounted in contentProcessor
4704     case XML_ROLE_XML_DECL:       // bytes ac    4704     case XML_ROLE_XML_DECL:       // bytes accounted in processXmlDecl
4705     case XML_ROLE_TEXT_DECL:      // bytes ac    4705     case XML_ROLE_TEXT_DECL:      // bytes accounted in processXmlDecl
4706       break;                                     4706       break;
4707     default:                                     4707     default:
4708       if (! accountingDiffTolerated(parser, t    4708       if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, account)) {
4709         accountingOnAbort(parser);               4709         accountingOnAbort(parser);
4710         return XML_ERROR_AMPLIFICATION_LIMIT_    4710         return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
4711       }                                          4711       }
4712     }                                            4712     }
4713 #endif                                           4713 #endif
4714     switch (role) {                              4714     switch (role) {
4715     case XML_ROLE_XML_DECL: {                    4715     case XML_ROLE_XML_DECL: {
4716       enum XML_Error result = processXmlDecl(    4716       enum XML_Error result = processXmlDecl(parser, 0, s, next);
4717       if (result != XML_ERROR_NONE)              4717       if (result != XML_ERROR_NONE)
4718         return result;                           4718         return result;
4719       enc = parser->m_encoding;                  4719       enc = parser->m_encoding;
4720       handleDefault = XML_FALSE;                 4720       handleDefault = XML_FALSE;
4721     } break;                                     4721     } break;
4722     case XML_ROLE_DOCTYPE_NAME:                  4722     case XML_ROLE_DOCTYPE_NAME:
4723       if (parser->m_startDoctypeDeclHandler)     4723       if (parser->m_startDoctypeDeclHandler) {
4724         parser->m_doctypeName                    4724         parser->m_doctypeName
4725             = poolStoreString(&parser->m_temp    4725             = poolStoreString(&parser->m_tempPool, enc, s, next);
4726         if (! parser->m_doctypeName)             4726         if (! parser->m_doctypeName)
4727           return XML_ERROR_NO_MEMORY;            4727           return XML_ERROR_NO_MEMORY;
4728         poolFinish(&parser->m_tempPool);         4728         poolFinish(&parser->m_tempPool);
4729         parser->m_doctypePubid = NULL;           4729         parser->m_doctypePubid = NULL;
4730         handleDefault = XML_FALSE;               4730         handleDefault = XML_FALSE;
4731       }                                          4731       }
4732       parser->m_doctypeSysid = NULL; /* alway    4732       parser->m_doctypeSysid = NULL; /* always initialize to NULL */
4733       break;                                     4733       break;
4734     case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:       4734     case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
4735       if (parser->m_startDoctypeDeclHandler)     4735       if (parser->m_startDoctypeDeclHandler) {
4736         parser->m_startDoctypeDeclHandler(       4736         parser->m_startDoctypeDeclHandler(
4737             parser->m_handlerArg, parser->m_d    4737             parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid,
4738             parser->m_doctypePubid, 1);          4738             parser->m_doctypePubid, 1);
4739         parser->m_doctypeName = NULL;            4739         parser->m_doctypeName = NULL;
4740         poolClear(&parser->m_tempPool);          4740         poolClear(&parser->m_tempPool);
4741         handleDefault = XML_FALSE;               4741         handleDefault = XML_FALSE;
4742       }                                          4742       }
4743       break;                                     4743       break;
4744 #ifdef XML_DTD                                   4744 #ifdef XML_DTD
4745     case XML_ROLE_TEXT_DECL: {                   4745     case XML_ROLE_TEXT_DECL: {
4746       enum XML_Error result = processXmlDecl(    4746       enum XML_Error result = processXmlDecl(parser, 1, s, next);
4747       if (result != XML_ERROR_NONE)              4747       if (result != XML_ERROR_NONE)
4748         return result;                           4748         return result;
4749       enc = parser->m_encoding;                  4749       enc = parser->m_encoding;
4750       handleDefault = XML_FALSE;                 4750       handleDefault = XML_FALSE;
4751     } break;                                     4751     } break;
4752 #endif /* XML_DTD */                             4752 #endif /* XML_DTD */
4753     case XML_ROLE_DOCTYPE_PUBLIC_ID:             4753     case XML_ROLE_DOCTYPE_PUBLIC_ID:
4754 #ifdef XML_DTD                                   4754 #ifdef XML_DTD
4755       parser->m_useForeignDTD = XML_FALSE;       4755       parser->m_useForeignDTD = XML_FALSE;
4756       parser->m_declEntity = (ENTITY *)lookup    4756       parser->m_declEntity = (ENTITY *)lookup(
4757           parser, &dtd->paramEntities, extern    4757           parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY));
4758       if (! parser->m_declEntity)                4758       if (! parser->m_declEntity)
4759         return XML_ERROR_NO_MEMORY;              4759         return XML_ERROR_NO_MEMORY;
4760 #endif /* XML_DTD */                             4760 #endif /* XML_DTD */
4761       dtd->hasParamEntityRefs = XML_TRUE;        4761       dtd->hasParamEntityRefs = XML_TRUE;
4762       if (parser->m_startDoctypeDeclHandler)     4762       if (parser->m_startDoctypeDeclHandler) {
4763         XML_Char *pubId;                         4763         XML_Char *pubId;
4764         if (! XmlIsPublicId(enc, s, next, eve    4764         if (! XmlIsPublicId(enc, s, next, eventPP))
4765           return XML_ERROR_PUBLICID;             4765           return XML_ERROR_PUBLICID;
4766         pubId = poolStoreString(&parser->m_te    4766         pubId = poolStoreString(&parser->m_tempPool, enc,
4767                                 s + enc->minB    4767                                 s + enc->minBytesPerChar,
4768                                 next - enc->m    4768                                 next - enc->minBytesPerChar);
4769         if (! pubId)                             4769         if (! pubId)
4770           return XML_ERROR_NO_MEMORY;            4770           return XML_ERROR_NO_MEMORY;
4771         normalizePublicId(pubId);                4771         normalizePublicId(pubId);
4772         poolFinish(&parser->m_tempPool);         4772         poolFinish(&parser->m_tempPool);
4773         parser->m_doctypePubid = pubId;          4773         parser->m_doctypePubid = pubId;
4774         handleDefault = XML_FALSE;               4774         handleDefault = XML_FALSE;
4775         goto alreadyChecked;                     4775         goto alreadyChecked;
4776       }                                          4776       }
4777       /* fall through */                         4777       /* fall through */
4778     case XML_ROLE_ENTITY_PUBLIC_ID:              4778     case XML_ROLE_ENTITY_PUBLIC_ID:
4779       if (! XmlIsPublicId(enc, s, next, event    4779       if (! XmlIsPublicId(enc, s, next, eventPP))
4780         return XML_ERROR_PUBLICID;               4780         return XML_ERROR_PUBLICID;
4781     alreadyChecked:                              4781     alreadyChecked:
4782       if (dtd->keepProcessing && parser->m_de    4782       if (dtd->keepProcessing && parser->m_declEntity) {
4783         XML_Char *tem                            4783         XML_Char *tem
4784             = poolStoreString(&dtd->pool, enc    4784             = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
4785                               next - enc->min    4785                               next - enc->minBytesPerChar);
4786         if (! tem)                               4786         if (! tem)
4787           return XML_ERROR_NO_MEMORY;            4787           return XML_ERROR_NO_MEMORY;
4788         normalizePublicId(tem);                  4788         normalizePublicId(tem);
4789         parser->m_declEntity->publicId = tem;    4789         parser->m_declEntity->publicId = tem;
4790         poolFinish(&dtd->pool);                  4790         poolFinish(&dtd->pool);
4791         /* Don't suppress the default handler    4791         /* Don't suppress the default handler if we fell through from
4792          * the XML_ROLE_DOCTYPE_PUBLIC_ID cas    4792          * the XML_ROLE_DOCTYPE_PUBLIC_ID case.
4793          */                                      4793          */
4794         if (parser->m_entityDeclHandler && ro    4794         if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_PUBLIC_ID)
4795           handleDefault = XML_FALSE;             4795           handleDefault = XML_FALSE;
4796       }                                          4796       }
4797       break;                                     4797       break;
4798     case XML_ROLE_DOCTYPE_CLOSE:                 4798     case XML_ROLE_DOCTYPE_CLOSE:
4799       if (allowClosingDoctype != XML_TRUE) {     4799       if (allowClosingDoctype != XML_TRUE) {
4800         /* Must not close doctype from within    4800         /* Must not close doctype from within expanded parameter entities */
4801         return XML_ERROR_INVALID_TOKEN;          4801         return XML_ERROR_INVALID_TOKEN;
4802       }                                          4802       }
4803                                                  4803 
4804       if (parser->m_doctypeName) {               4804       if (parser->m_doctypeName) {
4805         parser->m_startDoctypeDeclHandler(       4805         parser->m_startDoctypeDeclHandler(
4806             parser->m_handlerArg, parser->m_d    4806             parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid,
4807             parser->m_doctypePubid, 0);          4807             parser->m_doctypePubid, 0);
4808         poolClear(&parser->m_tempPool);          4808         poolClear(&parser->m_tempPool);
4809         handleDefault = XML_FALSE;               4809         handleDefault = XML_FALSE;
4810       }                                          4810       }
4811       /* parser->m_doctypeSysid will be non-N    4811       /* parser->m_doctypeSysid will be non-NULL in the case of a previous
4812          XML_ROLE_DOCTYPE_SYSTEM_ID, even if     4812          XML_ROLE_DOCTYPE_SYSTEM_ID, even if parser->m_startDoctypeDeclHandler
4813          was not set, indicating an external     4813          was not set, indicating an external subset
4814       */                                         4814       */
4815 #ifdef XML_DTD                                   4815 #ifdef XML_DTD
4816       if (parser->m_doctypeSysid || parser->m    4816       if (parser->m_doctypeSysid || parser->m_useForeignDTD) {
4817         XML_Bool hadParamEntityRefs = dtd->ha    4817         XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
4818         dtd->hasParamEntityRefs = XML_TRUE;      4818         dtd->hasParamEntityRefs = XML_TRUE;
4819         if (parser->m_paramEntityParsing         4819         if (parser->m_paramEntityParsing
4820             && parser->m_externalEntityRefHan    4820             && parser->m_externalEntityRefHandler) {
4821           ENTITY *entity = (ENTITY *)lookup(p    4821           ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
4822                                             e    4822                                             externalSubsetName, sizeof(ENTITY));
4823           if (! entity) {                        4823           if (! entity) {
4824             /* The external subset name "#" w    4824             /* The external subset name "#" will have already been
4825              * inserted into the hash table a    4825              * inserted into the hash table at the start of the
4826              * external entity parsing, so no    4826              * external entity parsing, so no allocation will happen
4827              * and lookup() cannot fail.         4827              * and lookup() cannot fail.
4828              */                                  4828              */
4829             return XML_ERROR_NO_MEMORY; /* LC    4829             return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */
4830           }                                      4830           }
4831           if (parser->m_useForeignDTD)           4831           if (parser->m_useForeignDTD)
4832             entity->base = parser->m_curBase;    4832             entity->base = parser->m_curBase;
4833           dtd->paramEntityRead = XML_FALSE;      4833           dtd->paramEntityRead = XML_FALSE;
4834           if (! parser->m_externalEntityRefHa    4834           if (! parser->m_externalEntityRefHandler(
4835                   parser->m_externalEntityRef    4835                   parser->m_externalEntityRefHandlerArg, 0, entity->base,
4836                   entity->systemId, entity->p    4836                   entity->systemId, entity->publicId))
4837             return XML_ERROR_EXTERNAL_ENTITY_    4837             return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4838           if (dtd->paramEntityRead) {            4838           if (dtd->paramEntityRead) {
4839             if (! dtd->standalone && parser->    4839             if (! dtd->standalone && parser->m_notStandaloneHandler
4840                 && ! parser->m_notStandaloneH    4840                 && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
4841               return XML_ERROR_NOT_STANDALONE    4841               return XML_ERROR_NOT_STANDALONE;
4842           }                                      4842           }
4843           /* if we didn't read the foreign DT    4843           /* if we didn't read the foreign DTD then this means that there
4844              is no external subset and we mus    4844              is no external subset and we must reset dtd->hasParamEntityRefs
4845           */                                     4845           */
4846           else if (! parser->m_doctypeSysid)     4846           else if (! parser->m_doctypeSysid)
4847             dtd->hasParamEntityRefs = hadPara    4847             dtd->hasParamEntityRefs = hadParamEntityRefs;
4848           /* end of DTD - no need to update d    4848           /* end of DTD - no need to update dtd->keepProcessing */
4849         }                                        4849         }
4850         parser->m_useForeignDTD = XML_FALSE;     4850         parser->m_useForeignDTD = XML_FALSE;
4851       }                                          4851       }
4852 #endif /* XML_DTD */                             4852 #endif /* XML_DTD */
4853       if (parser->m_endDoctypeDeclHandler) {     4853       if (parser->m_endDoctypeDeclHandler) {
4854         parser->m_endDoctypeDeclHandler(parse    4854         parser->m_endDoctypeDeclHandler(parser->m_handlerArg);
4855         handleDefault = XML_FALSE;               4855         handleDefault = XML_FALSE;
4856       }                                          4856       }
4857       break;                                     4857       break;
4858     case XML_ROLE_INSTANCE_START:                4858     case XML_ROLE_INSTANCE_START:
4859 #ifdef XML_DTD                                   4859 #ifdef XML_DTD
4860       /* if there is no DOCTYPE declaration t    4860       /* if there is no DOCTYPE declaration then now is the
4861          last chance to read the foreign DTD     4861          last chance to read the foreign DTD
4862       */                                         4862       */
4863       if (parser->m_useForeignDTD) {             4863       if (parser->m_useForeignDTD) {
4864         XML_Bool hadParamEntityRefs = dtd->ha    4864         XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
4865         dtd->hasParamEntityRefs = XML_TRUE;      4865         dtd->hasParamEntityRefs = XML_TRUE;
4866         if (parser->m_paramEntityParsing         4866         if (parser->m_paramEntityParsing
4867             && parser->m_externalEntityRefHan    4867             && parser->m_externalEntityRefHandler) {
4868           ENTITY *entity = (ENTITY *)lookup(p    4868           ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
4869                                             e    4869                                             externalSubsetName, sizeof(ENTITY));
4870           if (! entity)                          4870           if (! entity)
4871             return XML_ERROR_NO_MEMORY;          4871             return XML_ERROR_NO_MEMORY;
4872           entity->base = parser->m_curBase;      4872           entity->base = parser->m_curBase;
4873           dtd->paramEntityRead = XML_FALSE;      4873           dtd->paramEntityRead = XML_FALSE;
4874           if (! parser->m_externalEntityRefHa    4874           if (! parser->m_externalEntityRefHandler(
4875                   parser->m_externalEntityRef    4875                   parser->m_externalEntityRefHandlerArg, 0, entity->base,
4876                   entity->systemId, entity->p    4876                   entity->systemId, entity->publicId))
4877             return XML_ERROR_EXTERNAL_ENTITY_    4877             return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4878           if (dtd->paramEntityRead) {            4878           if (dtd->paramEntityRead) {
4879             if (! dtd->standalone && parser->    4879             if (! dtd->standalone && parser->m_notStandaloneHandler
4880                 && ! parser->m_notStandaloneH    4880                 && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
4881               return XML_ERROR_NOT_STANDALONE    4881               return XML_ERROR_NOT_STANDALONE;
4882           }                                      4882           }
4883           /* if we didn't read the foreign DT    4883           /* if we didn't read the foreign DTD then this means that there
4884              is no external subset and we mus    4884              is no external subset and we must reset dtd->hasParamEntityRefs
4885           */                                     4885           */
4886           else                                   4886           else
4887             dtd->hasParamEntityRefs = hadPara    4887             dtd->hasParamEntityRefs = hadParamEntityRefs;
4888           /* end of DTD - no need to update d    4888           /* end of DTD - no need to update dtd->keepProcessing */
4889         }                                        4889         }
4890       }                                          4890       }
4891 #endif /* XML_DTD */                             4891 #endif /* XML_DTD */
4892       parser->m_processor = contentProcessor;    4892       parser->m_processor = contentProcessor;
4893       return contentProcessor(parser, s, end,    4893       return contentProcessor(parser, s, end, nextPtr);
4894     case XML_ROLE_ATTLIST_ELEMENT_NAME:          4894     case XML_ROLE_ATTLIST_ELEMENT_NAME:
4895       parser->m_declElementType = getElementT    4895       parser->m_declElementType = getElementType(parser, enc, s, next);
4896       if (! parser->m_declElementType)           4896       if (! parser->m_declElementType)
4897         return XML_ERROR_NO_MEMORY;              4897         return XML_ERROR_NO_MEMORY;
4898       goto checkAttListDeclHandler;              4898       goto checkAttListDeclHandler;
4899     case XML_ROLE_ATTRIBUTE_NAME:                4899     case XML_ROLE_ATTRIBUTE_NAME:
4900       parser->m_declAttributeId = getAttribut    4900       parser->m_declAttributeId = getAttributeId(parser, enc, s, next);
4901       if (! parser->m_declAttributeId)           4901       if (! parser->m_declAttributeId)
4902         return XML_ERROR_NO_MEMORY;              4902         return XML_ERROR_NO_MEMORY;
4903       parser->m_declAttributeIsCdata = XML_FA    4903       parser->m_declAttributeIsCdata = XML_FALSE;
4904       parser->m_declAttributeType = NULL;        4904       parser->m_declAttributeType = NULL;
4905       parser->m_declAttributeIsId = XML_FALSE    4905       parser->m_declAttributeIsId = XML_FALSE;
4906       goto checkAttListDeclHandler;              4906       goto checkAttListDeclHandler;
4907     case XML_ROLE_ATTRIBUTE_TYPE_CDATA:          4907     case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
4908       parser->m_declAttributeIsCdata = XML_TR    4908       parser->m_declAttributeIsCdata = XML_TRUE;
4909       parser->m_declAttributeType = atypeCDAT    4909       parser->m_declAttributeType = atypeCDATA;
4910       goto checkAttListDeclHandler;              4910       goto checkAttListDeclHandler;
4911     case XML_ROLE_ATTRIBUTE_TYPE_ID:             4911     case XML_ROLE_ATTRIBUTE_TYPE_ID:
4912       parser->m_declAttributeIsId = XML_TRUE;    4912       parser->m_declAttributeIsId = XML_TRUE;
4913       parser->m_declAttributeType = atypeID;     4913       parser->m_declAttributeType = atypeID;
4914       goto checkAttListDeclHandler;              4914       goto checkAttListDeclHandler;
4915     case XML_ROLE_ATTRIBUTE_TYPE_IDREF:          4915     case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
4916       parser->m_declAttributeType = atypeIDRE    4916       parser->m_declAttributeType = atypeIDREF;
4917       goto checkAttListDeclHandler;              4917       goto checkAttListDeclHandler;
4918     case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:         4918     case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
4919       parser->m_declAttributeType = atypeIDRE    4919       parser->m_declAttributeType = atypeIDREFS;
4920       goto checkAttListDeclHandler;              4920       goto checkAttListDeclHandler;
4921     case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:         4921     case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
4922       parser->m_declAttributeType = atypeENTI    4922       parser->m_declAttributeType = atypeENTITY;
4923       goto checkAttListDeclHandler;              4923       goto checkAttListDeclHandler;
4924     case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:       4924     case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
4925       parser->m_declAttributeType = atypeENTI    4925       parser->m_declAttributeType = atypeENTITIES;
4926       goto checkAttListDeclHandler;              4926       goto checkAttListDeclHandler;
4927     case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:        4927     case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
4928       parser->m_declAttributeType = atypeNMTO    4928       parser->m_declAttributeType = atypeNMTOKEN;
4929       goto checkAttListDeclHandler;              4929       goto checkAttListDeclHandler;
4930     case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:       4930     case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
4931       parser->m_declAttributeType = atypeNMTO    4931       parser->m_declAttributeType = atypeNMTOKENS;
4932     checkAttListDeclHandler:                     4932     checkAttListDeclHandler:
4933       if (dtd->keepProcessing && parser->m_at    4933       if (dtd->keepProcessing && parser->m_attlistDeclHandler)
4934         handleDefault = XML_FALSE;               4934         handleDefault = XML_FALSE;
4935       break;                                     4935       break;
4936     case XML_ROLE_ATTRIBUTE_ENUM_VALUE:          4936     case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
4937     case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:      4937     case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
4938       if (dtd->keepProcessing && parser->m_at    4938       if (dtd->keepProcessing && parser->m_attlistDeclHandler) {
4939         const XML_Char *prefix;                  4939         const XML_Char *prefix;
4940         if (parser->m_declAttributeType) {       4940         if (parser->m_declAttributeType) {
4941           prefix = enumValueSep;                 4941           prefix = enumValueSep;
4942         } else {                                 4942         } else {
4943           prefix = (role == XML_ROLE_ATTRIBUT    4943           prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE ? notationPrefix
4944                                                  4944                                                               : enumValueStart);
4945         }                                        4945         }
4946         if (! poolAppendString(&parser->m_tem    4946         if (! poolAppendString(&parser->m_tempPool, prefix))
4947           return XML_ERROR_NO_MEMORY;            4947           return XML_ERROR_NO_MEMORY;
4948         if (! poolAppend(&parser->m_tempPool,    4948         if (! poolAppend(&parser->m_tempPool, enc, s, next))
4949           return XML_ERROR_NO_MEMORY;            4949           return XML_ERROR_NO_MEMORY;
4950         parser->m_declAttributeType = parser-    4950         parser->m_declAttributeType = parser->m_tempPool.start;
4951         handleDefault = XML_FALSE;               4951         handleDefault = XML_FALSE;
4952       }                                          4952       }
4953       break;                                     4953       break;
4954     case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:       4954     case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
4955     case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:      4955     case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
4956       if (dtd->keepProcessing) {                 4956       if (dtd->keepProcessing) {
4957         if (! defineAttribute(parser->m_declE    4957         if (! defineAttribute(parser->m_declElementType,
4958                               parser->m_declA    4958                               parser->m_declAttributeId,
4959                               parser->m_declA    4959                               parser->m_declAttributeIsCdata,
4960                               parser->m_declA    4960                               parser->m_declAttributeIsId, 0, parser))
4961           return XML_ERROR_NO_MEMORY;            4961           return XML_ERROR_NO_MEMORY;
4962         if (parser->m_attlistDeclHandler && p    4962         if (parser->m_attlistDeclHandler && parser->m_declAttributeType) {
4963           if (*parser->m_declAttributeType ==    4963           if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN)
4964               || (*parser->m_declAttributeTyp    4964               || (*parser->m_declAttributeType == XML_T(ASCII_N)
4965                   && parser->m_declAttributeT    4965                   && parser->m_declAttributeType[1] == XML_T(ASCII_O))) {
4966             /* Enumerated or Notation type */    4966             /* Enumerated or Notation type */
4967             if (! poolAppendChar(&parser->m_t    4967             if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN))
4968                 || ! poolAppendChar(&parser->    4968                 || ! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
4969               return XML_ERROR_NO_MEMORY;        4969               return XML_ERROR_NO_MEMORY;
4970             parser->m_declAttributeType = par    4970             parser->m_declAttributeType = parser->m_tempPool.start;
4971             poolFinish(&parser->m_tempPool);     4971             poolFinish(&parser->m_tempPool);
4972           }                                      4972           }
4973           *eventEndPP = s;                       4973           *eventEndPP = s;
4974           parser->m_attlistDeclHandler(          4974           parser->m_attlistDeclHandler(
4975               parser->m_handlerArg, parser->m    4975               parser->m_handlerArg, parser->m_declElementType->name,
4976               parser->m_declAttributeId->name    4976               parser->m_declAttributeId->name, parser->m_declAttributeType, 0,
4977               role == XML_ROLE_REQUIRED_ATTRI    4977               role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
4978           poolClear(&parser->m_tempPool);        4978           poolClear(&parser->m_tempPool);
4979           handleDefault = XML_FALSE;             4979           handleDefault = XML_FALSE;
4980         }                                        4980         }
4981       }                                          4981       }
4982       break;                                     4982       break;
4983     case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:       4983     case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
4984     case XML_ROLE_FIXED_ATTRIBUTE_VALUE:         4984     case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
4985       if (dtd->keepProcessing) {                 4985       if (dtd->keepProcessing) {
4986         const XML_Char *attVal;                  4986         const XML_Char *attVal;
4987         enum XML_Error result = storeAttribut    4987         enum XML_Error result = storeAttributeValue(
4988             parser, enc, parser->m_declAttrib    4988             parser, enc, parser->m_declAttributeIsCdata,
4989             s + enc->minBytesPerChar, next -     4989             s + enc->minBytesPerChar, next - enc->minBytesPerChar, &dtd->pool,
4990             XML_ACCOUNT_NONE);                   4990             XML_ACCOUNT_NONE);
4991         if (result)                              4991         if (result)
4992           return result;                         4992           return result;
4993         attVal = poolStart(&dtd->pool);          4993         attVal = poolStart(&dtd->pool);
4994         poolFinish(&dtd->pool);                  4994         poolFinish(&dtd->pool);
4995         /* ID attributes aren't allowed to ha    4995         /* ID attributes aren't allowed to have a default */
4996         if (! defineAttribute(                   4996         if (! defineAttribute(
4997                 parser->m_declElementType, pa    4997                 parser->m_declElementType, parser->m_declAttributeId,
4998                 parser->m_declAttributeIsCdat    4998                 parser->m_declAttributeIsCdata, XML_FALSE, attVal, parser))
4999           return XML_ERROR_NO_MEMORY;            4999           return XML_ERROR_NO_MEMORY;
5000         if (parser->m_attlistDeclHandler && p    5000         if (parser->m_attlistDeclHandler && parser->m_declAttributeType) {
5001           if (*parser->m_declAttributeType ==    5001           if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN)
5002               || (*parser->m_declAttributeTyp    5002               || (*parser->m_declAttributeType == XML_T(ASCII_N)
5003                   && parser->m_declAttributeT    5003                   && parser->m_declAttributeType[1] == XML_T(ASCII_O))) {
5004             /* Enumerated or Notation type */    5004             /* Enumerated or Notation type */
5005             if (! poolAppendChar(&parser->m_t    5005             if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN))
5006                 || ! poolAppendChar(&parser->    5006                 || ! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
5007               return XML_ERROR_NO_MEMORY;        5007               return XML_ERROR_NO_MEMORY;
5008             parser->m_declAttributeType = par    5008             parser->m_declAttributeType = parser->m_tempPool.start;
5009             poolFinish(&parser->m_tempPool);     5009             poolFinish(&parser->m_tempPool);
5010           }                                      5010           }
5011           *eventEndPP = s;                       5011           *eventEndPP = s;
5012           parser->m_attlistDeclHandler(          5012           parser->m_attlistDeclHandler(
5013               parser->m_handlerArg, parser->m    5013               parser->m_handlerArg, parser->m_declElementType->name,
5014               parser->m_declAttributeId->name    5014               parser->m_declAttributeId->name, parser->m_declAttributeType,
5015               attVal, role == XML_ROLE_FIXED_    5015               attVal, role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
5016           poolClear(&parser->m_tempPool);        5016           poolClear(&parser->m_tempPool);
5017           handleDefault = XML_FALSE;             5017           handleDefault = XML_FALSE;
5018         }                                        5018         }
5019       }                                          5019       }
5020       break;                                     5020       break;
5021     case XML_ROLE_ENTITY_VALUE:                  5021     case XML_ROLE_ENTITY_VALUE:
5022       if (dtd->keepProcessing) {                 5022       if (dtd->keepProcessing) {
5023         enum XML_Error result                    5023         enum XML_Error result
5024             = storeEntityValue(parser, enc, s    5024             = storeEntityValue(parser, enc, s + enc->minBytesPerChar,
5025                                next - enc->mi    5025                                next - enc->minBytesPerChar, XML_ACCOUNT_NONE);
5026         if (parser->m_declEntity) {              5026         if (parser->m_declEntity) {
5027           parser->m_declEntity->textPtr = poo    5027           parser->m_declEntity->textPtr = poolStart(&dtd->entityValuePool);
5028           parser->m_declEntity->textLen          5028           parser->m_declEntity->textLen
5029               = (int)(poolLength(&dtd->entity    5029               = (int)(poolLength(&dtd->entityValuePool));
5030           poolFinish(&dtd->entityValuePool);     5030           poolFinish(&dtd->entityValuePool);
5031           if (parser->m_entityDeclHandler) {     5031           if (parser->m_entityDeclHandler) {
5032             *eventEndPP = s;                     5032             *eventEndPP = s;
5033             parser->m_entityDeclHandler(         5033             parser->m_entityDeclHandler(
5034                 parser->m_handlerArg, parser-    5034                 parser->m_handlerArg, parser->m_declEntity->name,
5035                 parser->m_declEntity->is_para    5035                 parser->m_declEntity->is_param, parser->m_declEntity->textPtr,
5036                 parser->m_declEntity->textLen    5036                 parser->m_declEntity->textLen, parser->m_curBase, 0, 0, 0);
5037             handleDefault = XML_FALSE;           5037             handleDefault = XML_FALSE;
5038           }                                      5038           }
5039         } else                                   5039         } else
5040           poolDiscard(&dtd->entityValuePool);    5040           poolDiscard(&dtd->entityValuePool);
5041         if (result != XML_ERROR_NONE)            5041         if (result != XML_ERROR_NONE)
5042           return result;                         5042           return result;
5043       }                                          5043       }
5044       break;                                     5044       break;
5045     case XML_ROLE_DOCTYPE_SYSTEM_ID:             5045     case XML_ROLE_DOCTYPE_SYSTEM_ID:
5046 #ifdef XML_DTD                                   5046 #ifdef XML_DTD
5047       parser->m_useForeignDTD = XML_FALSE;       5047       parser->m_useForeignDTD = XML_FALSE;
5048 #endif /* XML_DTD */                             5048 #endif /* XML_DTD */
5049       dtd->hasParamEntityRefs = XML_TRUE;        5049       dtd->hasParamEntityRefs = XML_TRUE;
5050       if (parser->m_startDoctypeDeclHandler)     5050       if (parser->m_startDoctypeDeclHandler) {
5051         parser->m_doctypeSysid = poolStoreStr    5051         parser->m_doctypeSysid = poolStoreString(&parser->m_tempPool, enc,
5052                                                  5052                                                  s + enc->minBytesPerChar,
5053                                                  5053                                                  next - enc->minBytesPerChar);
5054         if (parser->m_doctypeSysid == NULL)      5054         if (parser->m_doctypeSysid == NULL)
5055           return XML_ERROR_NO_MEMORY;            5055           return XML_ERROR_NO_MEMORY;
5056         poolFinish(&parser->m_tempPool);         5056         poolFinish(&parser->m_tempPool);
5057         handleDefault = XML_FALSE;               5057         handleDefault = XML_FALSE;
5058       }                                          5058       }
5059 #ifdef XML_DTD                                   5059 #ifdef XML_DTD
5060       else                                       5060       else
5061         /* use externalSubsetName to make par    5061         /* use externalSubsetName to make parser->m_doctypeSysid non-NULL
5062            for the case where no parser->m_st    5062            for the case where no parser->m_startDoctypeDeclHandler is set */
5063         parser->m_doctypeSysid = externalSubs    5063         parser->m_doctypeSysid = externalSubsetName;
5064 #endif /* XML_DTD */                             5064 #endif /* XML_DTD */
5065       if (! dtd->standalone                      5065       if (! dtd->standalone
5066 #ifdef XML_DTD                                   5066 #ifdef XML_DTD
5067           && ! parser->m_paramEntityParsing      5067           && ! parser->m_paramEntityParsing
5068 #endif /* XML_DTD */                             5068 #endif /* XML_DTD */
5069           && parser->m_notStandaloneHandler      5069           && parser->m_notStandaloneHandler
5070           && ! parser->m_notStandaloneHandler    5070           && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
5071         return XML_ERROR_NOT_STANDALONE;         5071         return XML_ERROR_NOT_STANDALONE;
5072 #ifndef XML_DTD                                  5072 #ifndef XML_DTD
5073       break;                                     5073       break;
5074 #else  /* XML_DTD */                             5074 #else  /* XML_DTD */
5075       if (! parser->m_declEntity) {              5075       if (! parser->m_declEntity) {
5076         parser->m_declEntity = (ENTITY *)look    5076         parser->m_declEntity = (ENTITY *)lookup(
5077             parser, &dtd->paramEntities, exte    5077             parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY));
5078         if (! parser->m_declEntity)              5078         if (! parser->m_declEntity)
5079           return XML_ERROR_NO_MEMORY;            5079           return XML_ERROR_NO_MEMORY;
5080         parser->m_declEntity->publicId = NULL    5080         parser->m_declEntity->publicId = NULL;
5081       }                                          5081       }
5082 #endif /* XML_DTD */                             5082 #endif /* XML_DTD */
5083       /* fall through */                         5083       /* fall through */
5084     case XML_ROLE_ENTITY_SYSTEM_ID:              5084     case XML_ROLE_ENTITY_SYSTEM_ID:
5085       if (dtd->keepProcessing && parser->m_de    5085       if (dtd->keepProcessing && parser->m_declEntity) {
5086         parser->m_declEntity->systemId           5086         parser->m_declEntity->systemId
5087             = poolStoreString(&dtd->pool, enc    5087             = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
5088                               next - enc->min    5088                               next - enc->minBytesPerChar);
5089         if (! parser->m_declEntity->systemId)    5089         if (! parser->m_declEntity->systemId)
5090           return XML_ERROR_NO_MEMORY;            5090           return XML_ERROR_NO_MEMORY;
5091         parser->m_declEntity->base = parser->    5091         parser->m_declEntity->base = parser->m_curBase;
5092         poolFinish(&dtd->pool);                  5092         poolFinish(&dtd->pool);
5093         /* Don't suppress the default handler    5093         /* Don't suppress the default handler if we fell through from
5094          * the XML_ROLE_DOCTYPE_SYSTEM_ID cas    5094          * the XML_ROLE_DOCTYPE_SYSTEM_ID case.
5095          */                                      5095          */
5096         if (parser->m_entityDeclHandler && ro    5096         if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_SYSTEM_ID)
5097           handleDefault = XML_FALSE;             5097           handleDefault = XML_FALSE;
5098       }                                          5098       }
5099       break;                                     5099       break;
5100     case XML_ROLE_ENTITY_COMPLETE:               5100     case XML_ROLE_ENTITY_COMPLETE:
5101       if (dtd->keepProcessing && parser->m_de    5101       if (dtd->keepProcessing && parser->m_declEntity
5102           && parser->m_entityDeclHandler) {      5102           && parser->m_entityDeclHandler) {
5103         *eventEndPP = s;                         5103         *eventEndPP = s;
5104         parser->m_entityDeclHandler(             5104         parser->m_entityDeclHandler(
5105             parser->m_handlerArg, parser->m_d    5105             parser->m_handlerArg, parser->m_declEntity->name,
5106             parser->m_declEntity->is_param, 0    5106             parser->m_declEntity->is_param, 0, 0, parser->m_declEntity->base,
5107             parser->m_declEntity->systemId, p    5107             parser->m_declEntity->systemId, parser->m_declEntity->publicId, 0);
5108         handleDefault = XML_FALSE;               5108         handleDefault = XML_FALSE;
5109       }                                          5109       }
5110       break;                                     5110       break;
5111     case XML_ROLE_ENTITY_NOTATION_NAME:          5111     case XML_ROLE_ENTITY_NOTATION_NAME:
5112       if (dtd->keepProcessing && parser->m_de    5112       if (dtd->keepProcessing && parser->m_declEntity) {
5113         parser->m_declEntity->notation           5113         parser->m_declEntity->notation
5114             = poolStoreString(&dtd->pool, enc    5114             = poolStoreString(&dtd->pool, enc, s, next);
5115         if (! parser->m_declEntity->notation)    5115         if (! parser->m_declEntity->notation)
5116           return XML_ERROR_NO_MEMORY;            5116           return XML_ERROR_NO_MEMORY;
5117         poolFinish(&dtd->pool);                  5117         poolFinish(&dtd->pool);
5118         if (parser->m_unparsedEntityDeclHandl    5118         if (parser->m_unparsedEntityDeclHandler) {
5119           *eventEndPP = s;                       5119           *eventEndPP = s;
5120           parser->m_unparsedEntityDeclHandler    5120           parser->m_unparsedEntityDeclHandler(
5121               parser->m_handlerArg, parser->m    5121               parser->m_handlerArg, parser->m_declEntity->name,
5122               parser->m_declEntity->base, par    5122               parser->m_declEntity->base, parser->m_declEntity->systemId,
5123               parser->m_declEntity->publicId,    5123               parser->m_declEntity->publicId, parser->m_declEntity->notation);
5124           handleDefault = XML_FALSE;             5124           handleDefault = XML_FALSE;
5125         } else if (parser->m_entityDeclHandle    5125         } else if (parser->m_entityDeclHandler) {
5126           *eventEndPP = s;                       5126           *eventEndPP = s;
5127           parser->m_entityDeclHandler(           5127           parser->m_entityDeclHandler(
5128               parser->m_handlerArg, parser->m    5128               parser->m_handlerArg, parser->m_declEntity->name, 0, 0, 0,
5129               parser->m_declEntity->base, par    5129               parser->m_declEntity->base, parser->m_declEntity->systemId,
5130               parser->m_declEntity->publicId,    5130               parser->m_declEntity->publicId, parser->m_declEntity->notation);
5131           handleDefault = XML_FALSE;             5131           handleDefault = XML_FALSE;
5132         }                                        5132         }
5133       }                                          5133       }
5134       break;                                     5134       break;
5135     case XML_ROLE_GENERAL_ENTITY_NAME: {         5135     case XML_ROLE_GENERAL_ENTITY_NAME: {
5136       if (XmlPredefinedEntityName(enc, s, nex    5136       if (XmlPredefinedEntityName(enc, s, next)) {
5137         parser->m_declEntity = NULL;             5137         parser->m_declEntity = NULL;
5138         break;                                   5138         break;
5139       }                                          5139       }
5140       if (dtd->keepProcessing) {                 5140       if (dtd->keepProcessing) {
5141         const XML_Char *name = poolStoreStrin    5141         const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
5142         if (! name)                              5142         if (! name)
5143           return XML_ERROR_NO_MEMORY;            5143           return XML_ERROR_NO_MEMORY;
5144         parser->m_declEntity = (ENTITY *)look    5144         parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities,
5145                                                  5145                                                 name, sizeof(ENTITY));
5146         if (! parser->m_declEntity)              5146         if (! parser->m_declEntity)
5147           return XML_ERROR_NO_MEMORY;            5147           return XML_ERROR_NO_MEMORY;
5148         if (parser->m_declEntity->name != nam    5148         if (parser->m_declEntity->name != name) {
5149           poolDiscard(&dtd->pool);               5149           poolDiscard(&dtd->pool);
5150           parser->m_declEntity = NULL;           5150           parser->m_declEntity = NULL;
5151         } else {                                 5151         } else {
5152           poolFinish(&dtd->pool);                5152           poolFinish(&dtd->pool);
5153           parser->m_declEntity->publicId = NU    5153           parser->m_declEntity->publicId = NULL;
5154           parser->m_declEntity->is_param = XM    5154           parser->m_declEntity->is_param = XML_FALSE;
5155           /* if we have a parent parser or ar    5155           /* if we have a parent parser or are reading an internal parameter
5156              entity, then the entity declarat    5156              entity, then the entity declaration is not considered "internal"
5157           */                                     5157           */
5158           parser->m_declEntity->is_internal      5158           parser->m_declEntity->is_internal
5159               = ! (parser->m_parentParser ||     5159               = ! (parser->m_parentParser || parser->m_openInternalEntities);
5160           if (parser->m_entityDeclHandler)       5160           if (parser->m_entityDeclHandler)
5161             handleDefault = XML_FALSE;           5161             handleDefault = XML_FALSE;
5162         }                                        5162         }
5163       } else {                                   5163       } else {
5164         poolDiscard(&dtd->pool);                 5164         poolDiscard(&dtd->pool);
5165         parser->m_declEntity = NULL;             5165         parser->m_declEntity = NULL;
5166       }                                          5166       }
5167     } break;                                     5167     } break;
5168     case XML_ROLE_PARAM_ENTITY_NAME:             5168     case XML_ROLE_PARAM_ENTITY_NAME:
5169 #ifdef XML_DTD                                   5169 #ifdef XML_DTD
5170       if (dtd->keepProcessing) {                 5170       if (dtd->keepProcessing) {
5171         const XML_Char *name = poolStoreStrin    5171         const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
5172         if (! name)                              5172         if (! name)
5173           return XML_ERROR_NO_MEMORY;            5173           return XML_ERROR_NO_MEMORY;
5174         parser->m_declEntity = (ENTITY *)look    5174         parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities,
5175                                                  5175                                                 name, sizeof(ENTITY));
5176         if (! parser->m_declEntity)              5176         if (! parser->m_declEntity)
5177           return XML_ERROR_NO_MEMORY;            5177           return XML_ERROR_NO_MEMORY;
5178         if (parser->m_declEntity->name != nam    5178         if (parser->m_declEntity->name != name) {
5179           poolDiscard(&dtd->pool);               5179           poolDiscard(&dtd->pool);
5180           parser->m_declEntity = NULL;           5180           parser->m_declEntity = NULL;
5181         } else {                                 5181         } else {
5182           poolFinish(&dtd->pool);                5182           poolFinish(&dtd->pool);
5183           parser->m_declEntity->publicId = NU    5183           parser->m_declEntity->publicId = NULL;
5184           parser->m_declEntity->is_param = XM    5184           parser->m_declEntity->is_param = XML_TRUE;
5185           /* if we have a parent parser or ar    5185           /* if we have a parent parser or are reading an internal parameter
5186              entity, then the entity declarat    5186              entity, then the entity declaration is not considered "internal"
5187           */                                     5187           */
5188           parser->m_declEntity->is_internal      5188           parser->m_declEntity->is_internal
5189               = ! (parser->m_parentParser ||     5189               = ! (parser->m_parentParser || parser->m_openInternalEntities);
5190           if (parser->m_entityDeclHandler)       5190           if (parser->m_entityDeclHandler)
5191             handleDefault = XML_FALSE;           5191             handleDefault = XML_FALSE;
5192         }                                        5192         }
5193       } else {                                   5193       } else {
5194         poolDiscard(&dtd->pool);                 5194         poolDiscard(&dtd->pool);
5195         parser->m_declEntity = NULL;             5195         parser->m_declEntity = NULL;
5196       }                                          5196       }
5197 #else  /* not XML_DTD */                         5197 #else  /* not XML_DTD */
5198       parser->m_declEntity = NULL;               5198       parser->m_declEntity = NULL;
5199 #endif /* XML_DTD */                             5199 #endif /* XML_DTD */
5200       break;                                     5200       break;
5201     case XML_ROLE_NOTATION_NAME:                 5201     case XML_ROLE_NOTATION_NAME:
5202       parser->m_declNotationPublicId = NULL;     5202       parser->m_declNotationPublicId = NULL;
5203       parser->m_declNotationName = NULL;         5203       parser->m_declNotationName = NULL;
5204       if (parser->m_notationDeclHandler) {       5204       if (parser->m_notationDeclHandler) {
5205         parser->m_declNotationName               5205         parser->m_declNotationName
5206             = poolStoreString(&parser->m_temp    5206             = poolStoreString(&parser->m_tempPool, enc, s, next);
5207         if (! parser->m_declNotationName)        5207         if (! parser->m_declNotationName)
5208           return XML_ERROR_NO_MEMORY;            5208           return XML_ERROR_NO_MEMORY;
5209         poolFinish(&parser->m_tempPool);         5209         poolFinish(&parser->m_tempPool);
5210         handleDefault = XML_FALSE;               5210         handleDefault = XML_FALSE;
5211       }                                          5211       }
5212       break;                                     5212       break;
5213     case XML_ROLE_NOTATION_PUBLIC_ID:            5213     case XML_ROLE_NOTATION_PUBLIC_ID:
5214       if (! XmlIsPublicId(enc, s, next, event    5214       if (! XmlIsPublicId(enc, s, next, eventPP))
5215         return XML_ERROR_PUBLICID;               5215         return XML_ERROR_PUBLICID;
5216       if (parser                                 5216       if (parser
5217               ->m_declNotationName) { /* mean    5217               ->m_declNotationName) { /* means m_notationDeclHandler != NULL */
5218         XML_Char *tem = poolStoreString(&pars    5218         XML_Char *tem = poolStoreString(&parser->m_tempPool, enc,
5219                                         s + e    5219                                         s + enc->minBytesPerChar,
5220                                         next     5220                                         next - enc->minBytesPerChar);
5221         if (! tem)                               5221         if (! tem)
5222           return XML_ERROR_NO_MEMORY;            5222           return XML_ERROR_NO_MEMORY;
5223         normalizePublicId(tem);                  5223         normalizePublicId(tem);
5224         parser->m_declNotationPublicId = tem;    5224         parser->m_declNotationPublicId = tem;
5225         poolFinish(&parser->m_tempPool);         5225         poolFinish(&parser->m_tempPool);
5226         handleDefault = XML_FALSE;               5226         handleDefault = XML_FALSE;
5227       }                                          5227       }
5228       break;                                     5228       break;
5229     case XML_ROLE_NOTATION_SYSTEM_ID:            5229     case XML_ROLE_NOTATION_SYSTEM_ID:
5230       if (parser->m_declNotationName && parse    5230       if (parser->m_declNotationName && parser->m_notationDeclHandler) {
5231         const XML_Char *systemId = poolStoreS    5231         const XML_Char *systemId = poolStoreString(&parser->m_tempPool, enc,
5232                                                  5232                                                    s + enc->minBytesPerChar,
5233                                                  5233                                                    next - enc->minBytesPerChar);
5234         if (! systemId)                          5234         if (! systemId)
5235           return XML_ERROR_NO_MEMORY;            5235           return XML_ERROR_NO_MEMORY;
5236         *eventEndPP = s;                         5236         *eventEndPP = s;
5237         parser->m_notationDeclHandler(           5237         parser->m_notationDeclHandler(
5238             parser->m_handlerArg, parser->m_d    5238             parser->m_handlerArg, parser->m_declNotationName, parser->m_curBase,
5239             systemId, parser->m_declNotationP    5239             systemId, parser->m_declNotationPublicId);
5240         handleDefault = XML_FALSE;               5240         handleDefault = XML_FALSE;
5241       }                                          5241       }
5242       poolClear(&parser->m_tempPool);            5242       poolClear(&parser->m_tempPool);
5243       break;                                     5243       break;
5244     case XML_ROLE_NOTATION_NO_SYSTEM_ID:         5244     case XML_ROLE_NOTATION_NO_SYSTEM_ID:
5245       if (parser->m_declNotationPublicId && p    5245       if (parser->m_declNotationPublicId && parser->m_notationDeclHandler) {
5246         *eventEndPP = s;                         5246         *eventEndPP = s;
5247         parser->m_notationDeclHandler(           5247         parser->m_notationDeclHandler(
5248             parser->m_handlerArg, parser->m_d    5248             parser->m_handlerArg, parser->m_declNotationName, parser->m_curBase,
5249             0, parser->m_declNotationPublicId    5249             0, parser->m_declNotationPublicId);
5250         handleDefault = XML_FALSE;               5250         handleDefault = XML_FALSE;
5251       }                                          5251       }
5252       poolClear(&parser->m_tempPool);            5252       poolClear(&parser->m_tempPool);
5253       break;                                     5253       break;
5254     case XML_ROLE_ERROR:                         5254     case XML_ROLE_ERROR:
5255       switch (tok) {                             5255       switch (tok) {
5256       case XML_TOK_PARAM_ENTITY_REF:             5256       case XML_TOK_PARAM_ENTITY_REF:
5257         /* PE references in internal subset a    5257         /* PE references in internal subset are
5258            not allowed within declarations. *    5258            not allowed within declarations. */
5259         return XML_ERROR_PARAM_ENTITY_REF;       5259         return XML_ERROR_PARAM_ENTITY_REF;
5260       case XML_TOK_XML_DECL:                     5260       case XML_TOK_XML_DECL:
5261         return XML_ERROR_MISPLACED_XML_PI;       5261         return XML_ERROR_MISPLACED_XML_PI;
5262       default:                                   5262       default:
5263         return XML_ERROR_SYNTAX;                 5263         return XML_ERROR_SYNTAX;
5264       }                                          5264       }
5265 #ifdef XML_DTD                                   5265 #ifdef XML_DTD
5266     case XML_ROLE_IGNORE_SECT: {                 5266     case XML_ROLE_IGNORE_SECT: {
5267       enum XML_Error result;                     5267       enum XML_Error result;
5268       if (parser->m_defaultHandler)              5268       if (parser->m_defaultHandler)
5269         reportDefault(parser, enc, s, next);     5269         reportDefault(parser, enc, s, next);
5270       handleDefault = XML_FALSE;                 5270       handleDefault = XML_FALSE;
5271       result = doIgnoreSection(parser, enc, &    5271       result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
5272       if (result != XML_ERROR_NONE)              5272       if (result != XML_ERROR_NONE)
5273         return result;                           5273         return result;
5274       else if (! next) {                         5274       else if (! next) {
5275         parser->m_processor = ignoreSectionPr    5275         parser->m_processor = ignoreSectionProcessor;
5276         return result;                           5276         return result;
5277       }                                          5277       }
5278     } break;                                     5278     } break;
5279 #endif /* XML_DTD */                             5279 #endif /* XML_DTD */
5280     case XML_ROLE_GROUP_OPEN:                    5280     case XML_ROLE_GROUP_OPEN:
5281       if (parser->m_prologState.level >= pars    5281       if (parser->m_prologState.level >= parser->m_groupSize) {
5282         if (parser->m_groupSize) {               5282         if (parser->m_groupSize) {
5283           {                                      5283           {
5284             /* Detect and prevent integer ove    5284             /* Detect and prevent integer overflow */
5285             if (parser->m_groupSize > (unsign    5285             if (parser->m_groupSize > (unsigned int)(-1) / 2u) {
5286               return XML_ERROR_NO_MEMORY;        5286               return XML_ERROR_NO_MEMORY;
5287             }                                    5287             }
5288                                                  5288 
5289             char *const new_connector = (char    5289             char *const new_connector = (char *)REALLOC(
5290                 parser, parser->m_groupConnec    5290                 parser, parser->m_groupConnector, parser->m_groupSize *= 2);
5291             if (new_connector == NULL) {         5291             if (new_connector == NULL) {
5292               parser->m_groupSize /= 2;          5292               parser->m_groupSize /= 2;
5293               return XML_ERROR_NO_MEMORY;        5293               return XML_ERROR_NO_MEMORY;
5294             }                                    5294             }
5295             parser->m_groupConnector = new_co    5295             parser->m_groupConnector = new_connector;
5296           }                                      5296           }
5297                                                  5297 
5298           if (dtd->scaffIndex) {                 5298           if (dtd->scaffIndex) {
5299             /* Detect and prevent integer ove    5299             /* Detect and prevent integer overflow.
5300              * The preprocessor guard address    5300              * The preprocessor guard addresses the "always false" warning
5301              * from -Wtype-limits on platform    5301              * from -Wtype-limits on platforms where
5302              * sizeof(unsigned int) < sizeof(    5302              * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
5303 #if UINT_MAX >= SIZE_MAX                         5303 #if UINT_MAX >= SIZE_MAX
5304             if (parser->m_groupSize > (size_t    5304             if (parser->m_groupSize > (size_t)(-1) / sizeof(int)) {
5305               return XML_ERROR_NO_MEMORY;        5305               return XML_ERROR_NO_MEMORY;
5306             }                                    5306             }
5307 #endif                                           5307 #endif
5308                                                  5308 
5309             int *const new_scaff_index = (int    5309             int *const new_scaff_index = (int *)REALLOC(
5310                 parser, dtd->scaffIndex, pars    5310                 parser, dtd->scaffIndex, parser->m_groupSize * sizeof(int));
5311             if (new_scaff_index == NULL)         5311             if (new_scaff_index == NULL)
5312               return XML_ERROR_NO_MEMORY;        5312               return XML_ERROR_NO_MEMORY;
5313             dtd->scaffIndex = new_scaff_index    5313             dtd->scaffIndex = new_scaff_index;
5314           }                                      5314           }
5315         } else {                                 5315         } else {
5316           parser->m_groupConnector               5316           parser->m_groupConnector
5317               = (char *)MALLOC(parser, parser    5317               = (char *)MALLOC(parser, parser->m_groupSize = 32);
5318           if (! parser->m_groupConnector) {      5318           if (! parser->m_groupConnector) {
5319             parser->m_groupSize = 0;             5319             parser->m_groupSize = 0;
5320             return XML_ERROR_NO_MEMORY;          5320             return XML_ERROR_NO_MEMORY;
5321           }                                      5321           }
5322         }                                        5322         }
5323       }                                          5323       }
5324       parser->m_groupConnector[parser->m_prol    5324       parser->m_groupConnector[parser->m_prologState.level] = 0;
5325       if (dtd->in_eldecl) {                      5325       if (dtd->in_eldecl) {
5326         int myindex = nextScaffoldPart(parser    5326         int myindex = nextScaffoldPart(parser);
5327         if (myindex < 0)                         5327         if (myindex < 0)
5328           return XML_ERROR_NO_MEMORY;            5328           return XML_ERROR_NO_MEMORY;
5329         assert(dtd->scaffIndex != NULL);         5329         assert(dtd->scaffIndex != NULL);
5330         dtd->scaffIndex[dtd->scaffLevel] = my    5330         dtd->scaffIndex[dtd->scaffLevel] = myindex;
5331         dtd->scaffLevel++;                       5331         dtd->scaffLevel++;
5332         dtd->scaffold[myindex].type = XML_CTY    5332         dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
5333         if (parser->m_elementDeclHandler)        5333         if (parser->m_elementDeclHandler)
5334           handleDefault = XML_FALSE;             5334           handleDefault = XML_FALSE;
5335       }                                          5335       }
5336       break;                                     5336       break;
5337     case XML_ROLE_GROUP_SEQUENCE:                5337     case XML_ROLE_GROUP_SEQUENCE:
5338       if (parser->m_groupConnector[parser->m_    5338       if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_PIPE)
5339         return XML_ERROR_SYNTAX;                 5339         return XML_ERROR_SYNTAX;
5340       parser->m_groupConnector[parser->m_prol    5340       parser->m_groupConnector[parser->m_prologState.level] = ASCII_COMMA;
5341       if (dtd->in_eldecl && parser->m_element    5341       if (dtd->in_eldecl && parser->m_elementDeclHandler)
5342         handleDefault = XML_FALSE;               5342         handleDefault = XML_FALSE;
5343       break;                                     5343       break;
5344     case XML_ROLE_GROUP_CHOICE:                  5344     case XML_ROLE_GROUP_CHOICE:
5345       if (parser->m_groupConnector[parser->m_    5345       if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_COMMA)
5346         return XML_ERROR_SYNTAX;                 5346         return XML_ERROR_SYNTAX;
5347       if (dtd->in_eldecl                         5347       if (dtd->in_eldecl
5348           && ! parser->m_groupConnector[parse    5348           && ! parser->m_groupConnector[parser->m_prologState.level]
5349           && (dtd->scaffold[dtd->scaffIndex[d    5349           && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
5350               != XML_CTYPE_MIXED)) {             5350               != XML_CTYPE_MIXED)) {
5351         dtd->scaffold[dtd->scaffIndex[dtd->sc    5351         dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
5352             = XML_CTYPE_CHOICE;                  5352             = XML_CTYPE_CHOICE;
5353         if (parser->m_elementDeclHandler)        5353         if (parser->m_elementDeclHandler)
5354           handleDefault = XML_FALSE;             5354           handleDefault = XML_FALSE;
5355       }                                          5355       }
5356       parser->m_groupConnector[parser->m_prol    5356       parser->m_groupConnector[parser->m_prologState.level] = ASCII_PIPE;
5357       break;                                     5357       break;
5358     case XML_ROLE_PARAM_ENTITY_REF:              5358     case XML_ROLE_PARAM_ENTITY_REF:
5359 #ifdef XML_DTD                                   5359 #ifdef XML_DTD
5360     case XML_ROLE_INNER_PARAM_ENTITY_REF:        5360     case XML_ROLE_INNER_PARAM_ENTITY_REF:
5361       dtd->hasParamEntityRefs = XML_TRUE;        5361       dtd->hasParamEntityRefs = XML_TRUE;
5362       if (! parser->m_paramEntityParsing)        5362       if (! parser->m_paramEntityParsing)
5363         dtd->keepProcessing = dtd->standalone    5363         dtd->keepProcessing = dtd->standalone;
5364       else {                                     5364       else {
5365         const XML_Char *name;                    5365         const XML_Char *name;
5366         ENTITY *entity;                          5366         ENTITY *entity;
5367         name = poolStoreString(&dtd->pool, en    5367         name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
5368                                next - enc->mi    5368                                next - enc->minBytesPerChar);
5369         if (! name)                              5369         if (! name)
5370           return XML_ERROR_NO_MEMORY;            5370           return XML_ERROR_NO_MEMORY;
5371         entity = (ENTITY *)lookup(parser, &dt    5371         entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
5372         poolDiscard(&dtd->pool);                 5372         poolDiscard(&dtd->pool);
5373         /* first, determine if a check for an    5373         /* first, determine if a check for an existing declaration is needed;
5374            if yes, check that the entity exis    5374            if yes, check that the entity exists, and that it is internal,
5375            otherwise call the skipped entity     5375            otherwise call the skipped entity handler
5376         */                                       5376         */
5377         if (parser->m_prologState.documentEnt    5377         if (parser->m_prologState.documentEntity
5378             && (dtd->standalone ? ! parser->m    5378             && (dtd->standalone ? ! parser->m_openInternalEntities
5379                                 : ! dtd->hasP    5379                                 : ! dtd->hasParamEntityRefs)) {
5380           if (! entity)                          5380           if (! entity)
5381             return XML_ERROR_UNDEFINED_ENTITY    5381             return XML_ERROR_UNDEFINED_ENTITY;
5382           else if (! entity->is_internal) {      5382           else if (! entity->is_internal) {
5383             /* It's hard to exhaustively sear    5383             /* It's hard to exhaustively search the code to be sure,
5384              * but there doesn't seem to be a    5384              * but there doesn't seem to be a way of executing the
5385              * following line.  There are two    5385              * following line.  There are two cases:
5386              *                                   5386              *
5387              * If 'standalone' is false, the     5387              * If 'standalone' is false, the DTD must have no
5388              * parameter entities or we would    5388              * parameter entities or we wouldn't have passed the outer
5389              * 'if' statement.  That means th    5389              * 'if' statement.  That means the only entity in the hash
5390              * table is the external subset n    5390              * table is the external subset name "#" which cannot be
5391              * given as a parameter entity na    5391              * given as a parameter entity name in XML syntax, so the
5392              * lookup must have returned NULL    5392              * lookup must have returned NULL and we don't even reach
5393              * the test for an internal entit    5393              * the test for an internal entity.
5394              *                                   5394              *
5395              * If 'standalone' is true, it do    5395              * If 'standalone' is true, it does not seem to be
5396              * possible to create entities ta    5396              * possible to create entities taking this code path that
5397              * are not internal entities, so     5397              * are not internal entities, so fail the test above.
5398              *                                   5398              *
5399              * Because this analysis is very     5399              * Because this analysis is very uncertain, the code is
5400              * being left in place and merely    5400              * being left in place and merely removed from the
5401              * coverage test statistics.         5401              * coverage test statistics.
5402              */                                  5402              */
5403             return XML_ERROR_ENTITY_DECLARED_    5403             return XML_ERROR_ENTITY_DECLARED_IN_PE; /* LCOV_EXCL_LINE */
5404           }                                      5404           }
5405         } else if (! entity) {                   5405         } else if (! entity) {
5406           dtd->keepProcessing = dtd->standalo    5406           dtd->keepProcessing = dtd->standalone;
5407           /* cannot report skipped entities i    5407           /* cannot report skipped entities in declarations */
5408           if ((role == XML_ROLE_PARAM_ENTITY_    5408           if ((role == XML_ROLE_PARAM_ENTITY_REF)
5409               && parser->m_skippedEntityHandl    5409               && parser->m_skippedEntityHandler) {
5410             parser->m_skippedEntityHandler(pa    5410             parser->m_skippedEntityHandler(parser->m_handlerArg, name, 1);
5411             handleDefault = XML_FALSE;           5411             handleDefault = XML_FALSE;
5412           }                                      5412           }
5413           break;                                 5413           break;
5414         }                                        5414         }
5415         if (entity->open)                        5415         if (entity->open)
5416           return XML_ERROR_RECURSIVE_ENTITY_R    5416           return XML_ERROR_RECURSIVE_ENTITY_REF;
5417         if (entity->textPtr) {                   5417         if (entity->textPtr) {
5418           enum XML_Error result;                 5418           enum XML_Error result;
5419           XML_Bool betweenDecl                   5419           XML_Bool betweenDecl
5420               = (role == XML_ROLE_PARAM_ENTIT    5420               = (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
5421           result = processInternalEntity(pars    5421           result = processInternalEntity(parser, entity, betweenDecl);
5422           if (result != XML_ERROR_NONE)          5422           if (result != XML_ERROR_NONE)
5423             return result;                       5423             return result;
5424           handleDefault = XML_FALSE;             5424           handleDefault = XML_FALSE;
5425           break;                                 5425           break;
5426         }                                        5426         }
5427         if (parser->m_externalEntityRefHandle    5427         if (parser->m_externalEntityRefHandler) {
5428           dtd->paramEntityRead = XML_FALSE;      5428           dtd->paramEntityRead = XML_FALSE;
5429           entity->open = XML_TRUE;               5429           entity->open = XML_TRUE;
5430           entityTrackingOnOpen(parser, entity    5430           entityTrackingOnOpen(parser, entity, __LINE__);
5431           if (! parser->m_externalEntityRefHa    5431           if (! parser->m_externalEntityRefHandler(
5432                   parser->m_externalEntityRef    5432                   parser->m_externalEntityRefHandlerArg, 0, entity->base,
5433                   entity->systemId, entity->p    5433                   entity->systemId, entity->publicId)) {
5434             entityTrackingOnClose(parser, ent    5434             entityTrackingOnClose(parser, entity, __LINE__);
5435             entity->open = XML_FALSE;            5435             entity->open = XML_FALSE;
5436             return XML_ERROR_EXTERNAL_ENTITY_    5436             return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
5437           }                                      5437           }
5438           entityTrackingOnClose(parser, entit    5438           entityTrackingOnClose(parser, entity, __LINE__);
5439           entity->open = XML_FALSE;              5439           entity->open = XML_FALSE;
5440           handleDefault = XML_FALSE;             5440           handleDefault = XML_FALSE;
5441           if (! dtd->paramEntityRead) {          5441           if (! dtd->paramEntityRead) {
5442             dtd->keepProcessing = dtd->standa    5442             dtd->keepProcessing = dtd->standalone;
5443             break;                               5443             break;
5444           }                                      5444           }
5445         } else {                                 5445         } else {
5446           dtd->keepProcessing = dtd->standalo    5446           dtd->keepProcessing = dtd->standalone;
5447           break;                                 5447           break;
5448         }                                        5448         }
5449       }                                          5449       }
5450 #endif /* XML_DTD */                             5450 #endif /* XML_DTD */
5451       if (! dtd->standalone && parser->m_notS    5451       if (! dtd->standalone && parser->m_notStandaloneHandler
5452           && ! parser->m_notStandaloneHandler    5452           && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
5453         return XML_ERROR_NOT_STANDALONE;         5453         return XML_ERROR_NOT_STANDALONE;
5454       break;                                     5454       break;
5455                                                  5455 
5456       /* Element declaration stuff */            5456       /* Element declaration stuff */
5457                                                  5457 
5458     case XML_ROLE_ELEMENT_NAME:                  5458     case XML_ROLE_ELEMENT_NAME:
5459       if (parser->m_elementDeclHandler) {        5459       if (parser->m_elementDeclHandler) {
5460         parser->m_declElementType = getElemen    5460         parser->m_declElementType = getElementType(parser, enc, s, next);
5461         if (! parser->m_declElementType)         5461         if (! parser->m_declElementType)
5462           return XML_ERROR_NO_MEMORY;            5462           return XML_ERROR_NO_MEMORY;
5463         dtd->scaffLevel = 0;                     5463         dtd->scaffLevel = 0;
5464         dtd->scaffCount = 0;                     5464         dtd->scaffCount = 0;
5465         dtd->in_eldecl = XML_TRUE;               5465         dtd->in_eldecl = XML_TRUE;
5466         handleDefault = XML_FALSE;               5466         handleDefault = XML_FALSE;
5467       }                                          5467       }
5468       break;                                     5468       break;
5469                                                  5469 
5470     case XML_ROLE_CONTENT_ANY:                   5470     case XML_ROLE_CONTENT_ANY:
5471     case XML_ROLE_CONTENT_EMPTY:                 5471     case XML_ROLE_CONTENT_EMPTY:
5472       if (dtd->in_eldecl) {                      5472       if (dtd->in_eldecl) {
5473         if (parser->m_elementDeclHandler) {      5473         if (parser->m_elementDeclHandler) {
5474           XML_Content *content                   5474           XML_Content *content
5475               = (XML_Content *)MALLOC(parser,    5475               = (XML_Content *)MALLOC(parser, sizeof(XML_Content));
5476           if (! content)                         5476           if (! content)
5477             return XML_ERROR_NO_MEMORY;          5477             return XML_ERROR_NO_MEMORY;
5478           content->quant = XML_CQUANT_NONE;      5478           content->quant = XML_CQUANT_NONE;
5479           content->name = NULL;                  5479           content->name = NULL;
5480           content->numchildren = 0;              5480           content->numchildren = 0;
5481           content->children = NULL;              5481           content->children = NULL;
5482           content->type = ((role == XML_ROLE_    5482           content->type = ((role == XML_ROLE_CONTENT_ANY) ? XML_CTYPE_ANY
5483                                                  5483                                                           : XML_CTYPE_EMPTY);
5484           *eventEndPP = s;                       5484           *eventEndPP = s;
5485           parser->m_elementDeclHandler(          5485           parser->m_elementDeclHandler(
5486               parser->m_handlerArg, parser->m    5486               parser->m_handlerArg, parser->m_declElementType->name, content);
5487           handleDefault = XML_FALSE;             5487           handleDefault = XML_FALSE;
5488         }                                        5488         }
5489         dtd->in_eldecl = XML_FALSE;              5489         dtd->in_eldecl = XML_FALSE;
5490       }                                          5490       }
5491       break;                                     5491       break;
5492                                                  5492 
5493     case XML_ROLE_CONTENT_PCDATA:                5493     case XML_ROLE_CONTENT_PCDATA:
5494       if (dtd->in_eldecl) {                      5494       if (dtd->in_eldecl) {
5495         dtd->scaffold[dtd->scaffIndex[dtd->sc    5495         dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
5496             = XML_CTYPE_MIXED;                   5496             = XML_CTYPE_MIXED;
5497         if (parser->m_elementDeclHandler)        5497         if (parser->m_elementDeclHandler)
5498           handleDefault = XML_FALSE;             5498           handleDefault = XML_FALSE;
5499       }                                          5499       }
5500       break;                                     5500       break;
5501                                                  5501 
5502     case XML_ROLE_CONTENT_ELEMENT:               5502     case XML_ROLE_CONTENT_ELEMENT:
5503       quant = XML_CQUANT_NONE;                   5503       quant = XML_CQUANT_NONE;
5504       goto elementContent;                       5504       goto elementContent;
5505     case XML_ROLE_CONTENT_ELEMENT_OPT:           5505     case XML_ROLE_CONTENT_ELEMENT_OPT:
5506       quant = XML_CQUANT_OPT;                    5506       quant = XML_CQUANT_OPT;
5507       goto elementContent;                       5507       goto elementContent;
5508     case XML_ROLE_CONTENT_ELEMENT_REP:           5508     case XML_ROLE_CONTENT_ELEMENT_REP:
5509       quant = XML_CQUANT_REP;                    5509       quant = XML_CQUANT_REP;
5510       goto elementContent;                       5510       goto elementContent;
5511     case XML_ROLE_CONTENT_ELEMENT_PLUS:          5511     case XML_ROLE_CONTENT_ELEMENT_PLUS:
5512       quant = XML_CQUANT_PLUS;                   5512       quant = XML_CQUANT_PLUS;
5513     elementContent:                              5513     elementContent:
5514       if (dtd->in_eldecl) {                      5514       if (dtd->in_eldecl) {
5515         ELEMENT_TYPE *el;                        5515         ELEMENT_TYPE *el;
5516         const XML_Char *name;                    5516         const XML_Char *name;
5517         size_t nameLen;                          5517         size_t nameLen;
5518         const char *nxt                          5518         const char *nxt
5519             = (quant == XML_CQUANT_NONE ? nex    5519             = (quant == XML_CQUANT_NONE ? next : next - enc->minBytesPerChar);
5520         int myindex = nextScaffoldPart(parser    5520         int myindex = nextScaffoldPart(parser);
5521         if (myindex < 0)                         5521         if (myindex < 0)
5522           return XML_ERROR_NO_MEMORY;            5522           return XML_ERROR_NO_MEMORY;
5523         dtd->scaffold[myindex].type = XML_CTY    5523         dtd->scaffold[myindex].type = XML_CTYPE_NAME;
5524         dtd->scaffold[myindex].quant = quant;    5524         dtd->scaffold[myindex].quant = quant;
5525         el = getElementType(parser, enc, s, n    5525         el = getElementType(parser, enc, s, nxt);
5526         if (! el)                                5526         if (! el)
5527           return XML_ERROR_NO_MEMORY;            5527           return XML_ERROR_NO_MEMORY;
5528         name = el->name;                         5528         name = el->name;
5529         dtd->scaffold[myindex].name = name;      5529         dtd->scaffold[myindex].name = name;
5530         nameLen = 0;                             5530         nameLen = 0;
5531         for (; name[nameLen++];)                 5531         for (; name[nameLen++];)
5532           ;                                      5532           ;
5533                                                  5533 
5534         /* Detect and prevent integer overflo    5534         /* Detect and prevent integer overflow */
5535         if (nameLen > UINT_MAX - dtd->content    5535         if (nameLen > UINT_MAX - dtd->contentStringLen) {
5536           return XML_ERROR_NO_MEMORY;            5536           return XML_ERROR_NO_MEMORY;
5537         }                                        5537         }
5538                                                  5538 
5539         dtd->contentStringLen += (unsigned)na    5539         dtd->contentStringLen += (unsigned)nameLen;
5540         if (parser->m_elementDeclHandler)        5540         if (parser->m_elementDeclHandler)
5541           handleDefault = XML_FALSE;             5541           handleDefault = XML_FALSE;
5542       }                                          5542       }
5543       break;                                     5543       break;
5544                                                  5544 
5545     case XML_ROLE_GROUP_CLOSE:                   5545     case XML_ROLE_GROUP_CLOSE:
5546       quant = XML_CQUANT_NONE;                   5546       quant = XML_CQUANT_NONE;
5547       goto closeGroup;                           5547       goto closeGroup;
5548     case XML_ROLE_GROUP_CLOSE_OPT:               5548     case XML_ROLE_GROUP_CLOSE_OPT:
5549       quant = XML_CQUANT_OPT;                    5549       quant = XML_CQUANT_OPT;
5550       goto closeGroup;                           5550       goto closeGroup;
5551     case XML_ROLE_GROUP_CLOSE_REP:               5551     case XML_ROLE_GROUP_CLOSE_REP:
5552       quant = XML_CQUANT_REP;                    5552       quant = XML_CQUANT_REP;
5553       goto closeGroup;                           5553       goto closeGroup;
5554     case XML_ROLE_GROUP_CLOSE_PLUS:              5554     case XML_ROLE_GROUP_CLOSE_PLUS:
5555       quant = XML_CQUANT_PLUS;                   5555       quant = XML_CQUANT_PLUS;
5556     closeGroup:                                  5556     closeGroup:
5557       if (dtd->in_eldecl) {                      5557       if (dtd->in_eldecl) {
5558         if (parser->m_elementDeclHandler)        5558         if (parser->m_elementDeclHandler)
5559           handleDefault = XML_FALSE;             5559           handleDefault = XML_FALSE;
5560         dtd->scaffLevel--;                       5560         dtd->scaffLevel--;
5561         dtd->scaffold[dtd->scaffIndex[dtd->sc    5561         dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
5562         if (dtd->scaffLevel == 0) {              5562         if (dtd->scaffLevel == 0) {
5563           if (! handleDefault) {                 5563           if (! handleDefault) {
5564             XML_Content *model = build_model(    5564             XML_Content *model = build_model(parser);
5565             if (! model)                         5565             if (! model)
5566               return XML_ERROR_NO_MEMORY;        5566               return XML_ERROR_NO_MEMORY;
5567             *eventEndPP = s;                     5567             *eventEndPP = s;
5568             parser->m_elementDeclHandler(        5568             parser->m_elementDeclHandler(
5569                 parser->m_handlerArg, parser-    5569                 parser->m_handlerArg, parser->m_declElementType->name, model);
5570           }                                      5570           }
5571           dtd->in_eldecl = XML_FALSE;            5571           dtd->in_eldecl = XML_FALSE;
5572           dtd->contentStringLen = 0;             5572           dtd->contentStringLen = 0;
5573         }                                        5573         }
5574       }                                          5574       }
5575       break;                                     5575       break;
5576       /* End element declaration stuff */        5576       /* End element declaration stuff */
5577                                                  5577 
5578     case XML_ROLE_PI:                            5578     case XML_ROLE_PI:
5579       if (! reportProcessingInstruction(parse    5579       if (! reportProcessingInstruction(parser, enc, s, next))
5580         return XML_ERROR_NO_MEMORY;              5580         return XML_ERROR_NO_MEMORY;
5581       handleDefault = XML_FALSE;                 5581       handleDefault = XML_FALSE;
5582       break;                                     5582       break;
5583     case XML_ROLE_COMMENT:                       5583     case XML_ROLE_COMMENT:
5584       if (! reportComment(parser, enc, s, nex    5584       if (! reportComment(parser, enc, s, next))
5585         return XML_ERROR_NO_MEMORY;              5585         return XML_ERROR_NO_MEMORY;
5586       handleDefault = XML_FALSE;                 5586       handleDefault = XML_FALSE;
5587       break;                                     5587       break;
5588     case XML_ROLE_NONE:                          5588     case XML_ROLE_NONE:
5589       switch (tok) {                             5589       switch (tok) {
5590       case XML_TOK_BOM:                          5590       case XML_TOK_BOM:
5591         handleDefault = XML_FALSE;               5591         handleDefault = XML_FALSE;
5592         break;                                   5592         break;
5593       }                                          5593       }
5594       break;                                     5594       break;
5595     case XML_ROLE_DOCTYPE_NONE:                  5595     case XML_ROLE_DOCTYPE_NONE:
5596       if (parser->m_startDoctypeDeclHandler)     5596       if (parser->m_startDoctypeDeclHandler)
5597         handleDefault = XML_FALSE;               5597         handleDefault = XML_FALSE;
5598       break;                                     5598       break;
5599     case XML_ROLE_ENTITY_NONE:                   5599     case XML_ROLE_ENTITY_NONE:
5600       if (dtd->keepProcessing && parser->m_en    5600       if (dtd->keepProcessing && parser->m_entityDeclHandler)
5601         handleDefault = XML_FALSE;               5601         handleDefault = XML_FALSE;
5602       break;                                     5602       break;
5603     case XML_ROLE_NOTATION_NONE:                 5603     case XML_ROLE_NOTATION_NONE:
5604       if (parser->m_notationDeclHandler)         5604       if (parser->m_notationDeclHandler)
5605         handleDefault = XML_FALSE;               5605         handleDefault = XML_FALSE;
5606       break;                                     5606       break;
5607     case XML_ROLE_ATTLIST_NONE:                  5607     case XML_ROLE_ATTLIST_NONE:
5608       if (dtd->keepProcessing && parser->m_at    5608       if (dtd->keepProcessing && parser->m_attlistDeclHandler)
5609         handleDefault = XML_FALSE;               5609         handleDefault = XML_FALSE;
5610       break;                                     5610       break;
5611     case XML_ROLE_ELEMENT_NONE:                  5611     case XML_ROLE_ELEMENT_NONE:
5612       if (parser->m_elementDeclHandler)          5612       if (parser->m_elementDeclHandler)
5613         handleDefault = XML_FALSE;               5613         handleDefault = XML_FALSE;
5614       break;                                     5614       break;
5615     } /* end of big switch */                    5615     } /* end of big switch */
5616                                                  5616 
5617     if (handleDefault && parser->m_defaultHan    5617     if (handleDefault && parser->m_defaultHandler)
5618       reportDefault(parser, enc, s, next);       5618       reportDefault(parser, enc, s, next);
5619                                                  5619 
5620     switch (parser->m_parsingStatus.parsing)     5620     switch (parser->m_parsingStatus.parsing) {
5621     case XML_SUSPENDED:                          5621     case XML_SUSPENDED:
5622       *nextPtr = next;                           5622       *nextPtr = next;
5623       return XML_ERROR_NONE;                     5623       return XML_ERROR_NONE;
5624     case XML_FINISHED:                           5624     case XML_FINISHED:
5625       return XML_ERROR_ABORTED;                  5625       return XML_ERROR_ABORTED;
5626     default:                                     5626     default:
5627       s = next;                                  5627       s = next;
5628       tok = XmlPrologTok(enc, s, end, &next);    5628       tok = XmlPrologTok(enc, s, end, &next);
5629     }                                            5629     }
5630   }                                              5630   }
5631   /* not reached */                              5631   /* not reached */
5632 }                                                5632 }
5633                                                  5633 
5634 static enum XML_Error PTRCALL                    5634 static enum XML_Error PTRCALL
5635 epilogProcessor(XML_Parser parser, const char    5635 epilogProcessor(XML_Parser parser, const char *s, const char *end,
5636                 const char **nextPtr) {          5636                 const char **nextPtr) {
5637   parser->m_processor = epilogProcessor;         5637   parser->m_processor = epilogProcessor;
5638   parser->m_eventPtr = s;                        5638   parser->m_eventPtr = s;
5639   for (;;) {                                     5639   for (;;) {
5640     const char *next = NULL;                     5640     const char *next = NULL;
5641     int tok = XmlPrologTok(parser->m_encoding    5641     int tok = XmlPrologTok(parser->m_encoding, s, end, &next);
5642 #ifdef XML_DTD                                   5642 #ifdef XML_DTD
5643     if (! accountingDiffTolerated(parser, tok    5643     if (! accountingDiffTolerated(parser, tok, s, next, __LINE__,
5644                                   XML_ACCOUNT    5644                                   XML_ACCOUNT_DIRECT)) {
5645       accountingOnAbort(parser);                 5645       accountingOnAbort(parser);
5646       return XML_ERROR_AMPLIFICATION_LIMIT_BR    5646       return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
5647     }                                            5647     }
5648 #endif                                           5648 #endif
5649     parser->m_eventEndPtr = next;                5649     parser->m_eventEndPtr = next;
5650     switch (tok) {                               5650     switch (tok) {
5651     /* report partial linebreak - it might be    5651     /* report partial linebreak - it might be the last token */
5652     case -XML_TOK_PROLOG_S:                      5652     case -XML_TOK_PROLOG_S:
5653       if (parser->m_defaultHandler) {            5653       if (parser->m_defaultHandler) {
5654         reportDefault(parser, parser->m_encod    5654         reportDefault(parser, parser->m_encoding, s, next);
5655         if (parser->m_parsingStatus.parsing =    5655         if (parser->m_parsingStatus.parsing == XML_FINISHED)
5656           return XML_ERROR_ABORTED;              5656           return XML_ERROR_ABORTED;
5657       }                                          5657       }
5658       *nextPtr = next;                           5658       *nextPtr = next;
5659       return XML_ERROR_NONE;                     5659       return XML_ERROR_NONE;
5660     case XML_TOK_NONE:                           5660     case XML_TOK_NONE:
5661       *nextPtr = s;                              5661       *nextPtr = s;
5662       return XML_ERROR_NONE;                     5662       return XML_ERROR_NONE;
5663     case XML_TOK_PROLOG_S:                       5663     case XML_TOK_PROLOG_S:
5664       if (parser->m_defaultHandler)              5664       if (parser->m_defaultHandler)
5665         reportDefault(parser, parser->m_encod    5665         reportDefault(parser, parser->m_encoding, s, next);
5666       break;                                     5666       break;
5667     case XML_TOK_PI:                             5667     case XML_TOK_PI:
5668       if (! reportProcessingInstruction(parse    5668       if (! reportProcessingInstruction(parser, parser->m_encoding, s, next))
5669         return XML_ERROR_NO_MEMORY;              5669         return XML_ERROR_NO_MEMORY;
5670       break;                                     5670       break;
5671     case XML_TOK_COMMENT:                        5671     case XML_TOK_COMMENT:
5672       if (! reportComment(parser, parser->m_e    5672       if (! reportComment(parser, parser->m_encoding, s, next))
5673         return XML_ERROR_NO_MEMORY;              5673         return XML_ERROR_NO_MEMORY;
5674       break;                                     5674       break;
5675     case XML_TOK_INVALID:                        5675     case XML_TOK_INVALID:
5676       parser->m_eventPtr = next;                 5676       parser->m_eventPtr = next;
5677       return XML_ERROR_INVALID_TOKEN;            5677       return XML_ERROR_INVALID_TOKEN;
5678     case XML_TOK_PARTIAL:                        5678     case XML_TOK_PARTIAL:
5679       if (! parser->m_parsingStatus.finalBuff    5679       if (! parser->m_parsingStatus.finalBuffer) {
5680         *nextPtr = s;                            5680         *nextPtr = s;
5681         return XML_ERROR_NONE;                   5681         return XML_ERROR_NONE;
5682       }                                          5682       }
5683       return XML_ERROR_UNCLOSED_TOKEN;           5683       return XML_ERROR_UNCLOSED_TOKEN;
5684     case XML_TOK_PARTIAL_CHAR:                   5684     case XML_TOK_PARTIAL_CHAR:
5685       if (! parser->m_parsingStatus.finalBuff    5685       if (! parser->m_parsingStatus.finalBuffer) {
5686         *nextPtr = s;                            5686         *nextPtr = s;
5687         return XML_ERROR_NONE;                   5687         return XML_ERROR_NONE;
5688       }                                          5688       }
5689       return XML_ERROR_PARTIAL_CHAR;             5689       return XML_ERROR_PARTIAL_CHAR;
5690     default:                                     5690     default:
5691       return XML_ERROR_JUNK_AFTER_DOC_ELEMENT    5691       return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
5692     }                                            5692     }
5693     parser->m_eventPtr = s = next;               5693     parser->m_eventPtr = s = next;
5694     switch (parser->m_parsingStatus.parsing)     5694     switch (parser->m_parsingStatus.parsing) {
5695     case XML_SUSPENDED:                          5695     case XML_SUSPENDED:
5696       *nextPtr = next;                           5696       *nextPtr = next;
5697       return XML_ERROR_NONE;                     5697       return XML_ERROR_NONE;
5698     case XML_FINISHED:                           5698     case XML_FINISHED:
5699       return XML_ERROR_ABORTED;                  5699       return XML_ERROR_ABORTED;
5700     default:;                                    5700     default:;
5701     }                                            5701     }
5702   }                                              5702   }
5703 }                                                5703 }
5704                                                  5704 
5705 static enum XML_Error                            5705 static enum XML_Error
5706 processInternalEntity(XML_Parser parser, ENTI    5706 processInternalEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl) {
5707   const char *textStart, *textEnd;               5707   const char *textStart, *textEnd;
5708   const char *next;                              5708   const char *next;
5709   enum XML_Error result;                         5709   enum XML_Error result;
5710   OPEN_INTERNAL_ENTITY *openEntity;              5710   OPEN_INTERNAL_ENTITY *openEntity;
5711                                                  5711 
5712   if (parser->m_freeInternalEntities) {          5712   if (parser->m_freeInternalEntities) {
5713     openEntity = parser->m_freeInternalEntiti    5713     openEntity = parser->m_freeInternalEntities;
5714     parser->m_freeInternalEntities = openEnti    5714     parser->m_freeInternalEntities = openEntity->next;
5715   } else {                                       5715   } else {
5716     openEntity                                   5716     openEntity
5717         = (OPEN_INTERNAL_ENTITY *)MALLOC(pars    5717         = (OPEN_INTERNAL_ENTITY *)MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY));
5718     if (! openEntity)                            5718     if (! openEntity)
5719       return XML_ERROR_NO_MEMORY;                5719       return XML_ERROR_NO_MEMORY;
5720   }                                              5720   }
5721   entity->open = XML_TRUE;                       5721   entity->open = XML_TRUE;
5722 #ifdef XML_DTD                                   5722 #ifdef XML_DTD
5723   entityTrackingOnOpen(parser, entity, __LINE    5723   entityTrackingOnOpen(parser, entity, __LINE__);
5724 #endif                                           5724 #endif
5725   entity->processed = 0;                         5725   entity->processed = 0;
5726   openEntity->next = parser->m_openInternalEn    5726   openEntity->next = parser->m_openInternalEntities;
5727   parser->m_openInternalEntities = openEntity    5727   parser->m_openInternalEntities = openEntity;
5728   openEntity->entity = entity;                   5728   openEntity->entity = entity;
5729   openEntity->startTagLevel = parser->m_tagLe    5729   openEntity->startTagLevel = parser->m_tagLevel;
5730   openEntity->betweenDecl = betweenDecl;         5730   openEntity->betweenDecl = betweenDecl;
5731   openEntity->internalEventPtr = NULL;           5731   openEntity->internalEventPtr = NULL;
5732   openEntity->internalEventEndPtr = NULL;        5732   openEntity->internalEventEndPtr = NULL;
5733   textStart = (const char *)entity->textPtr;     5733   textStart = (const char *)entity->textPtr;
5734   textEnd = (const char *)(entity->textPtr +     5734   textEnd = (const char *)(entity->textPtr + entity->textLen);
5735   /* Set a safe default value in case 'next'     5735   /* Set a safe default value in case 'next' does not get set */
5736   next = textStart;                              5736   next = textStart;
5737                                                  5737 
5738 #ifdef XML_DTD                                   5738 #ifdef XML_DTD
5739   if (entity->is_param) {                        5739   if (entity->is_param) {
5740     int tok                                      5740     int tok
5741         = XmlPrologTok(parser->m_internalEnco    5741         = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
5742     result = doProlog(parser, parser->m_inter    5742     result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
5743                       tok, next, &next, XML_F    5743                       tok, next, &next, XML_FALSE, XML_FALSE,
5744                       XML_ACCOUNT_ENTITY_EXPA    5744                       XML_ACCOUNT_ENTITY_EXPANSION);
5745   } else                                         5745   } else
5746 #endif /* XML_DTD */                             5746 #endif /* XML_DTD */
5747     result = doContent(parser, parser->m_tagL    5747     result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding,
5748                        textStart, textEnd, &n    5748                        textStart, textEnd, &next, XML_FALSE,
5749                        XML_ACCOUNT_ENTITY_EXP    5749                        XML_ACCOUNT_ENTITY_EXPANSION);
5750                                                  5750 
5751   if (result == XML_ERROR_NONE) {                5751   if (result == XML_ERROR_NONE) {
5752     if (textEnd != next && parser->m_parsingS    5752     if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
5753       entity->processed = (int)(next - textSt    5753       entity->processed = (int)(next - textStart);
5754       parser->m_processor = internalEntityPro    5754       parser->m_processor = internalEntityProcessor;
5755     } else {                                     5755     } else {
5756 #ifdef XML_DTD                                   5756 #ifdef XML_DTD
5757       entityTrackingOnClose(parser, entity, _    5757       entityTrackingOnClose(parser, entity, __LINE__);
5758 #endif /* XML_DTD */                             5758 #endif /* XML_DTD */
5759       entity->open = XML_FALSE;                  5759       entity->open = XML_FALSE;
5760       parser->m_openInternalEntities = openEn    5760       parser->m_openInternalEntities = openEntity->next;
5761       /* put openEntity back in list of free     5761       /* put openEntity back in list of free instances */
5762       openEntity->next = parser->m_freeIntern    5762       openEntity->next = parser->m_freeInternalEntities;
5763       parser->m_freeInternalEntities = openEn    5763       parser->m_freeInternalEntities = openEntity;
5764     }                                            5764     }
5765   }                                              5765   }
5766   return result;                                 5766   return result;
5767 }                                                5767 }
5768                                                  5768 
5769 static enum XML_Error PTRCALL                    5769 static enum XML_Error PTRCALL
5770 internalEntityProcessor(XML_Parser parser, co    5770 internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
5771                         const char **nextPtr)    5771                         const char **nextPtr) {
5772   ENTITY *entity;                                5772   ENTITY *entity;
5773   const char *textStart, *textEnd;               5773   const char *textStart, *textEnd;
5774   const char *next;                              5774   const char *next;
5775   enum XML_Error result;                         5775   enum XML_Error result;
5776   OPEN_INTERNAL_ENTITY *openEntity = parser->    5776   OPEN_INTERNAL_ENTITY *openEntity = parser->m_openInternalEntities;
5777   if (! openEntity)                              5777   if (! openEntity)
5778     return XML_ERROR_UNEXPECTED_STATE;           5778     return XML_ERROR_UNEXPECTED_STATE;
5779                                                  5779 
5780   entity = openEntity->entity;                   5780   entity = openEntity->entity;
5781   textStart = ((const char *)entity->textPtr)    5781   textStart = ((const char *)entity->textPtr) + entity->processed;
5782   textEnd = (const char *)(entity->textPtr +     5782   textEnd = (const char *)(entity->textPtr + entity->textLen);
5783   /* Set a safe default value in case 'next'     5783   /* Set a safe default value in case 'next' does not get set */
5784   next = textStart;                              5784   next = textStart;
5785                                                  5785 
5786 #ifdef XML_DTD                                   5786 #ifdef XML_DTD
5787   if (entity->is_param) {                        5787   if (entity->is_param) {
5788     int tok                                      5788     int tok
5789         = XmlPrologTok(parser->m_internalEnco    5789         = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
5790     result = doProlog(parser, parser->m_inter    5790     result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
5791                       tok, next, &next, XML_F    5791                       tok, next, &next, XML_FALSE, XML_TRUE,
5792                       XML_ACCOUNT_ENTITY_EXPA    5792                       XML_ACCOUNT_ENTITY_EXPANSION);
5793   } else                                         5793   } else
5794 #endif /* XML_DTD */                             5794 #endif /* XML_DTD */
5795     result = doContent(parser, openEntity->st    5795     result = doContent(parser, openEntity->startTagLevel,
5796                        parser->m_internalEnco    5796                        parser->m_internalEncoding, textStart, textEnd, &next,
5797                        XML_FALSE, XML_ACCOUNT    5797                        XML_FALSE, XML_ACCOUNT_ENTITY_EXPANSION);
5798                                                  5798 
5799   if (result != XML_ERROR_NONE)                  5799   if (result != XML_ERROR_NONE)
5800     return result;                               5800     return result;
5801   else if (textEnd != next                       5801   else if (textEnd != next
5802            && parser->m_parsingStatus.parsing    5802            && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
5803     entity->processed = (int)(next - (const c    5803     entity->processed = (int)(next - (const char *)entity->textPtr);
5804     return result;                               5804     return result;
5805   } else {                                       5805   } else {
5806 #ifdef XML_DTD                                   5806 #ifdef XML_DTD
5807     entityTrackingOnClose(parser, entity, __L    5807     entityTrackingOnClose(parser, entity, __LINE__);
5808 #endif                                           5808 #endif
5809     entity->open = XML_FALSE;                    5809     entity->open = XML_FALSE;
5810     parser->m_openInternalEntities = openEnti    5810     parser->m_openInternalEntities = openEntity->next;
5811     /* put openEntity back in list of free in    5811     /* put openEntity back in list of free instances */
5812     openEntity->next = parser->m_freeInternal    5812     openEntity->next = parser->m_freeInternalEntities;
5813     parser->m_freeInternalEntities = openEnti    5813     parser->m_freeInternalEntities = openEntity;
5814   }                                              5814   }
5815                                                  5815 
5816 #ifdef XML_DTD                                   5816 #ifdef XML_DTD
5817   if (entity->is_param) {                        5817   if (entity->is_param) {
5818     int tok;                                     5818     int tok;
5819     parser->m_processor = prologProcessor;       5819     parser->m_processor = prologProcessor;
5820     tok = XmlPrologTok(parser->m_encoding, s,    5820     tok = XmlPrologTok(parser->m_encoding, s, end, &next);
5821     return doProlog(parser, parser->m_encodin    5821     return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
5822                     (XML_Bool)! parser->m_par    5822                     (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE,
5823                     XML_ACCOUNT_DIRECT);         5823                     XML_ACCOUNT_DIRECT);
5824   } else                                         5824   } else
5825 #endif /* XML_DTD */                             5825 #endif /* XML_DTD */
5826   {                                              5826   {
5827     parser->m_processor = contentProcessor;      5827     parser->m_processor = contentProcessor;
5828     /* see externalEntityContentProcessor vs     5828     /* see externalEntityContentProcessor vs contentProcessor */
5829     result = doContent(parser, parser->m_pare    5829     result = doContent(parser, parser->m_parentParser ? 1 : 0,
5830                        parser->m_encoding, s,    5830                        parser->m_encoding, s, end, nextPtr,
5831                        (XML_Bool)! parser->m_    5831                        (XML_Bool)! parser->m_parsingStatus.finalBuffer,
5832                        XML_ACCOUNT_DIRECT);      5832                        XML_ACCOUNT_DIRECT);
5833     if (result == XML_ERROR_NONE) {              5833     if (result == XML_ERROR_NONE) {
5834       if (! storeRawNames(parser))               5834       if (! storeRawNames(parser))
5835         return XML_ERROR_NO_MEMORY;              5835         return XML_ERROR_NO_MEMORY;
5836     }                                            5836     }
5837     return result;                               5837     return result;
5838   }                                              5838   }
5839 }                                                5839 }
5840                                                  5840 
5841 static enum XML_Error PTRCALL                    5841 static enum XML_Error PTRCALL
5842 errorProcessor(XML_Parser parser, const char     5842 errorProcessor(XML_Parser parser, const char *s, const char *end,
5843                const char **nextPtr) {           5843                const char **nextPtr) {
5844   UNUSED_P(s);                                   5844   UNUSED_P(s);
5845   UNUSED_P(end);                                 5845   UNUSED_P(end);
5846   UNUSED_P(nextPtr);                             5846   UNUSED_P(nextPtr);
5847   return parser->m_errorCode;                    5847   return parser->m_errorCode;
5848 }                                                5848 }
5849                                                  5849 
5850 static enum XML_Error                            5850 static enum XML_Error
5851 storeAttributeValue(XML_Parser parser, const     5851 storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
5852                     const char *ptr, const ch    5852                     const char *ptr, const char *end, STRING_POOL *pool,
5853                     enum XML_Account account)    5853                     enum XML_Account account) {
5854   enum XML_Error result                          5854   enum XML_Error result
5855       = appendAttributeValue(parser, enc, isC    5855       = appendAttributeValue(parser, enc, isCdata, ptr, end, pool, account);
5856   if (result)                                    5856   if (result)
5857     return result;                               5857     return result;
5858   if (! isCdata && poolLength(pool) && poolLa    5858   if (! isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
5859     poolChop(pool);                              5859     poolChop(pool);
5860   if (! poolAppendChar(pool, XML_T('\0')))       5860   if (! poolAppendChar(pool, XML_T('\0')))
5861     return XML_ERROR_NO_MEMORY;                  5861     return XML_ERROR_NO_MEMORY;
5862   return XML_ERROR_NONE;                         5862   return XML_ERROR_NONE;
5863 }                                                5863 }
5864                                                  5864 
5865 static enum XML_Error                            5865 static enum XML_Error
5866 appendAttributeValue(XML_Parser parser, const    5866 appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
5867                      const char *ptr, const c    5867                      const char *ptr, const char *end, STRING_POOL *pool,
5868                      enum XML_Account account    5868                      enum XML_Account account) {
5869   DTD *const dtd = parser->m_dtd; /* save one    5869   DTD *const dtd = parser->m_dtd; /* save one level of indirection */
5870 #ifndef XML_DTD                                  5870 #ifndef XML_DTD
5871   UNUSED_P(account);                             5871   UNUSED_P(account);
5872 #endif                                           5872 #endif
5873                                                  5873 
5874   for (;;) {                                     5874   for (;;) {
5875     const char *next                             5875     const char *next
5876         = ptr; /* XmlAttributeValueTok doesn'    5876         = ptr; /* XmlAttributeValueTok doesn't always set the last arg */
5877     int tok = XmlAttributeValueTok(enc, ptr,     5877     int tok = XmlAttributeValueTok(enc, ptr, end, &next);
5878 #ifdef XML_DTD                                   5878 #ifdef XML_DTD
5879     if (! accountingDiffTolerated(parser, tok    5879     if (! accountingDiffTolerated(parser, tok, ptr, next, __LINE__, account)) {
5880       accountingOnAbort(parser);                 5880       accountingOnAbort(parser);
5881       return XML_ERROR_AMPLIFICATION_LIMIT_BR    5881       return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
5882     }                                            5882     }
5883 #endif                                           5883 #endif
5884     switch (tok) {                               5884     switch (tok) {
5885     case XML_TOK_NONE:                           5885     case XML_TOK_NONE:
5886       return XML_ERROR_NONE;                     5886       return XML_ERROR_NONE;
5887     case XML_TOK_INVALID:                        5887     case XML_TOK_INVALID:
5888       if (enc == parser->m_encoding)             5888       if (enc == parser->m_encoding)
5889         parser->m_eventPtr = next;               5889         parser->m_eventPtr = next;
5890       return XML_ERROR_INVALID_TOKEN;            5890       return XML_ERROR_INVALID_TOKEN;
5891     case XML_TOK_PARTIAL:                        5891     case XML_TOK_PARTIAL:
5892       if (enc == parser->m_encoding)             5892       if (enc == parser->m_encoding)
5893         parser->m_eventPtr = ptr;                5893         parser->m_eventPtr = ptr;
5894       return XML_ERROR_INVALID_TOKEN;            5894       return XML_ERROR_INVALID_TOKEN;
5895     case XML_TOK_CHAR_REF: {                     5895     case XML_TOK_CHAR_REF: {
5896       XML_Char buf[XML_ENCODE_MAX];              5896       XML_Char buf[XML_ENCODE_MAX];
5897       int i;                                     5897       int i;
5898       int n = XmlCharRefNumber(enc, ptr);        5898       int n = XmlCharRefNumber(enc, ptr);
5899       if (n < 0) {                               5899       if (n < 0) {
5900         if (enc == parser->m_encoding)           5900         if (enc == parser->m_encoding)
5901           parser->m_eventPtr = ptr;              5901           parser->m_eventPtr = ptr;
5902         return XML_ERROR_BAD_CHAR_REF;           5902         return XML_ERROR_BAD_CHAR_REF;
5903       }                                          5903       }
5904       if (! isCdata && n == 0x20 /* space */     5904       if (! isCdata && n == 0x20 /* space */
5905           && (poolLength(pool) == 0 || poolLa    5905           && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
5906         break;                                   5906         break;
5907       n = XmlEncode(n, (ICHAR *)buf);            5907       n = XmlEncode(n, (ICHAR *)buf);
5908       /* The XmlEncode() functions can never     5908       /* The XmlEncode() functions can never return 0 here.  That
5909        * error return happens if the code poi    5909        * error return happens if the code point passed in is either
5910        * negative or greater than or equal to    5910        * negative or greater than or equal to 0x110000.  The
5911        * XmlCharRefNumber() functions will al    5911        * XmlCharRefNumber() functions will all return a number
5912        * strictly less than 0x110000 or a neg    5912        * strictly less than 0x110000 or a negative value if an error
5913        * occurred.  The negative value is int    5913        * occurred.  The negative value is intercepted above, so
5914        * XmlEncode() is never passed a value     5914        * XmlEncode() is never passed a value it might return an
5915        * error for.                              5915        * error for.
5916        */                                        5916        */
5917       for (i = 0; i < n; i++) {                  5917       for (i = 0; i < n; i++) {
5918         if (! poolAppendChar(pool, buf[i]))      5918         if (! poolAppendChar(pool, buf[i]))
5919           return XML_ERROR_NO_MEMORY;            5919           return XML_ERROR_NO_MEMORY;
5920       }                                          5920       }
5921     } break;                                     5921     } break;
5922     case XML_TOK_DATA_CHARS:                     5922     case XML_TOK_DATA_CHARS:
5923       if (! poolAppend(pool, enc, ptr, next))    5923       if (! poolAppend(pool, enc, ptr, next))
5924         return XML_ERROR_NO_MEMORY;              5924         return XML_ERROR_NO_MEMORY;
5925       break;                                     5925       break;
5926     case XML_TOK_TRAILING_CR:                    5926     case XML_TOK_TRAILING_CR:
5927       next = ptr + enc->minBytesPerChar;         5927       next = ptr + enc->minBytesPerChar;
5928       /* fall through */                         5928       /* fall through */
5929     case XML_TOK_ATTRIBUTE_VALUE_S:              5929     case XML_TOK_ATTRIBUTE_VALUE_S:
5930     case XML_TOK_DATA_NEWLINE:                   5930     case XML_TOK_DATA_NEWLINE:
5931       if (! isCdata && (poolLength(pool) == 0    5931       if (! isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
5932         break;                                   5932         break;
5933       if (! poolAppendChar(pool, 0x20))          5933       if (! poolAppendChar(pool, 0x20))
5934         return XML_ERROR_NO_MEMORY;              5934         return XML_ERROR_NO_MEMORY;
5935       break;                                     5935       break;
5936     case XML_TOK_ENTITY_REF: {                   5936     case XML_TOK_ENTITY_REF: {
5937       const XML_Char *name;                      5937       const XML_Char *name;
5938       ENTITY *entity;                            5938       ENTITY *entity;
5939       char checkEntityDecl;                      5939       char checkEntityDecl;
5940       XML_Char ch = (XML_Char)XmlPredefinedEn    5940       XML_Char ch = (XML_Char)XmlPredefinedEntityName(
5941           enc, ptr + enc->minBytesPerChar, ne    5941           enc, ptr + enc->minBytesPerChar, next - enc->minBytesPerChar);
5942       if (ch) {                                  5942       if (ch) {
5943 #ifdef XML_DTD                                   5943 #ifdef XML_DTD
5944         /* NOTE: We are replacing 4-6 charact    5944         /* NOTE: We are replacing 4-6 characters original input for 1 character
5945          *       so there is no amplification    5945          *       so there is no amplification and hence recording without
5946          *       protection. */                  5946          *       protection. */
5947         accountingDiffTolerated(parser, tok,     5947         accountingDiffTolerated(parser, tok, (char *)&ch,
5948                                 ((char *)&ch)    5948                                 ((char *)&ch) + sizeof(XML_Char), __LINE__,
5949                                 XML_ACCOUNT_E    5949                                 XML_ACCOUNT_ENTITY_EXPANSION);
5950 #endif /* XML_DTD */                             5950 #endif /* XML_DTD */
5951         if (! poolAppendChar(pool, ch))          5951         if (! poolAppendChar(pool, ch))
5952           return XML_ERROR_NO_MEMORY;            5952           return XML_ERROR_NO_MEMORY;
5953         break;                                   5953         break;
5954       }                                          5954       }
5955       name = poolStoreString(&parser->m_temp2    5955       name = poolStoreString(&parser->m_temp2Pool, enc,
5956                              ptr + enc->minBy    5956                              ptr + enc->minBytesPerChar,
5957                              next - enc->minB    5957                              next - enc->minBytesPerChar);
5958       if (! name)                                5958       if (! name)
5959         return XML_ERROR_NO_MEMORY;              5959         return XML_ERROR_NO_MEMORY;
5960       entity = (ENTITY *)lookup(parser, &dtd-    5960       entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
5961       poolDiscard(&parser->m_temp2Pool);         5961       poolDiscard(&parser->m_temp2Pool);
5962       /* First, determine if a check for an e    5962       /* First, determine if a check for an existing declaration is needed;
5963          if yes, check that the entity exists    5963          if yes, check that the entity exists, and that it is internal.
5964       */                                         5964       */
5965       if (pool == &dtd->pool) /* are we calle    5965       if (pool == &dtd->pool) /* are we called from prolog? */
5966         checkEntityDecl =                        5966         checkEntityDecl =
5967 #ifdef XML_DTD                                   5967 #ifdef XML_DTD
5968             parser->m_prologState.documentEnt    5968             parser->m_prologState.documentEntity &&
5969 #endif /* XML_DTD */                             5969 #endif /* XML_DTD */
5970             (dtd->standalone ? ! parser->m_op    5970             (dtd->standalone ? ! parser->m_openInternalEntities
5971                              : ! dtd->hasPara    5971                              : ! dtd->hasParamEntityRefs);
5972       else /* if (pool == &parser->m_tempPool    5972       else /* if (pool == &parser->m_tempPool): we are called from content */
5973         checkEntityDecl = ! dtd->hasParamEnti    5973         checkEntityDecl = ! dtd->hasParamEntityRefs || dtd->standalone;
5974       if (checkEntityDecl) {                     5974       if (checkEntityDecl) {
5975         if (! entity)                            5975         if (! entity)
5976           return XML_ERROR_UNDEFINED_ENTITY;     5976           return XML_ERROR_UNDEFINED_ENTITY;
5977         else if (! entity->is_internal)          5977         else if (! entity->is_internal)
5978           return XML_ERROR_ENTITY_DECLARED_IN    5978           return XML_ERROR_ENTITY_DECLARED_IN_PE;
5979       } else if (! entity) {                     5979       } else if (! entity) {
5980         /* Cannot report skipped entity here     5980         /* Cannot report skipped entity here - see comments on
5981            parser->m_skippedEntityHandler.       5981            parser->m_skippedEntityHandler.
5982         if (parser->m_skippedEntityHandler)      5982         if (parser->m_skippedEntityHandler)
5983           parser->m_skippedEntityHandler(pars    5983           parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
5984         */                                       5984         */
5985         /* Cannot call the default handler be    5985         /* Cannot call the default handler because this would be
5986            out of sync with the call to the s    5986            out of sync with the call to the startElementHandler.
5987         if ((pool == &parser->m_tempPool) &&     5987         if ((pool == &parser->m_tempPool) && parser->m_defaultHandler)
5988           reportDefault(parser, enc, ptr, nex    5988           reportDefault(parser, enc, ptr, next);
5989         */                                       5989         */
5990         break;                                   5990         break;
5991       }                                          5991       }
5992       if (entity->open) {                        5992       if (entity->open) {
5993         if (enc == parser->m_encoding) {         5993         if (enc == parser->m_encoding) {
5994           /* It does not appear that this lin    5994           /* It does not appear that this line can be executed.
5995            *                                     5995            *
5996            * The "if (entity->open)" check ca    5996            * The "if (entity->open)" check catches recursive entity
5997            * definitions.  In order to be cal    5997            * definitions.  In order to be called with an open
5998            * entity, it must have gone throug    5998            * entity, it must have gone through this code before and
5999            * been through the recursive call     5999            * been through the recursive call to
6000            * appendAttributeValue() some line    6000            * appendAttributeValue() some lines below.  That call
6001            * sets the local encoding ("enc")     6001            * sets the local encoding ("enc") to the parser's
6002            * internal encoding (internal_utf8    6002            * internal encoding (internal_utf8 or internal_utf16),
6003            * which can never be the same as t    6003            * which can never be the same as the principle encoding.
6004            * It doesn't appear there is anoth    6004            * It doesn't appear there is another code path that gets
6005            * here with entity->open being TRU    6005            * here with entity->open being TRUE.
6006            *                                     6006            *
6007            * Since it is not certain that thi    6007            * Since it is not certain that this logic is watertight,
6008            * we keep the line and merely excl    6008            * we keep the line and merely exclude it from coverage
6009            * tests.                              6009            * tests.
6010            */                                    6010            */
6011           parser->m_eventPtr = ptr; /* LCOV_E    6011           parser->m_eventPtr = ptr; /* LCOV_EXCL_LINE */
6012         }                                        6012         }
6013         return XML_ERROR_RECURSIVE_ENTITY_REF    6013         return XML_ERROR_RECURSIVE_ENTITY_REF;
6014       }                                          6014       }
6015       if (entity->notation) {                    6015       if (entity->notation) {
6016         if (enc == parser->m_encoding)           6016         if (enc == parser->m_encoding)
6017           parser->m_eventPtr = ptr;              6017           parser->m_eventPtr = ptr;
6018         return XML_ERROR_BINARY_ENTITY_REF;      6018         return XML_ERROR_BINARY_ENTITY_REF;
6019       }                                          6019       }
6020       if (! entity->textPtr) {                   6020       if (! entity->textPtr) {
6021         if (enc == parser->m_encoding)           6021         if (enc == parser->m_encoding)
6022           parser->m_eventPtr = ptr;              6022           parser->m_eventPtr = ptr;
6023         return XML_ERROR_ATTRIBUTE_EXTERNAL_E    6023         return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
6024       } else {                                   6024       } else {
6025         enum XML_Error result;                   6025         enum XML_Error result;
6026         const XML_Char *textEnd = entity->tex    6026         const XML_Char *textEnd = entity->textPtr + entity->textLen;
6027         entity->open = XML_TRUE;                 6027         entity->open = XML_TRUE;
6028 #ifdef XML_DTD                                   6028 #ifdef XML_DTD
6029         entityTrackingOnOpen(parser, entity,     6029         entityTrackingOnOpen(parser, entity, __LINE__);
6030 #endif                                           6030 #endif
6031         result = appendAttributeValue(parser,    6031         result = appendAttributeValue(parser, parser->m_internalEncoding,
6032                                       isCdata    6032                                       isCdata, (const char *)entity->textPtr,
6033                                       (const     6033                                       (const char *)textEnd, pool,
6034                                       XML_ACC    6034                                       XML_ACCOUNT_ENTITY_EXPANSION);
6035 #ifdef XML_DTD                                   6035 #ifdef XML_DTD
6036         entityTrackingOnClose(parser, entity,    6036         entityTrackingOnClose(parser, entity, __LINE__);
6037 #endif                                           6037 #endif
6038         entity->open = XML_FALSE;                6038         entity->open = XML_FALSE;
6039         if (result)                              6039         if (result)
6040           return result;                         6040           return result;
6041       }                                          6041       }
6042     } break;                                     6042     } break;
6043     default:                                     6043     default:
6044       /* The only token returned by XmlAttrib    6044       /* The only token returned by XmlAttributeValueTok() that does
6045        * not have an explicit case here is XM    6045        * not have an explicit case here is XML_TOK_PARTIAL_CHAR.
6046        * Getting that would require an entity    6046        * Getting that would require an entity name to contain an
6047        * incomplete XML character (e.g. \xE2\    6047        * incomplete XML character (e.g. \xE2\x82); however previous
6048        * tokenisers will have already recogni    6048        * tokenisers will have already recognised and rejected such
6049        * names before XmlAttributeValueTok()     6049        * names before XmlAttributeValueTok() gets a look-in.  This
6050        * default case should be retained as a    6050        * default case should be retained as a safety net, but the code
6051        * excluded from coverage tests.           6051        * excluded from coverage tests.
6052        *                                         6052        *
6053        * LCOV_EXCL_START                         6053        * LCOV_EXCL_START
6054        */                                        6054        */
6055       if (enc == parser->m_encoding)             6055       if (enc == parser->m_encoding)
6056         parser->m_eventPtr = ptr;                6056         parser->m_eventPtr = ptr;
6057       return XML_ERROR_UNEXPECTED_STATE;         6057       return XML_ERROR_UNEXPECTED_STATE;
6058       /* LCOV_EXCL_STOP */                       6058       /* LCOV_EXCL_STOP */
6059     }                                            6059     }
6060     ptr = next;                                  6060     ptr = next;
6061   }                                              6061   }
6062   /* not reached */                              6062   /* not reached */
6063 }                                                6063 }
6064                                                  6064 
6065 static enum XML_Error                            6065 static enum XML_Error
6066 storeEntityValue(XML_Parser parser, const ENC    6066 storeEntityValue(XML_Parser parser, const ENCODING *enc,
6067                  const char *entityTextPtr, c    6067                  const char *entityTextPtr, const char *entityTextEnd,
6068                  enum XML_Account account) {     6068                  enum XML_Account account) {
6069   DTD *const dtd = parser->m_dtd; /* save one    6069   DTD *const dtd = parser->m_dtd; /* save one level of indirection */
6070   STRING_POOL *pool = &(dtd->entityValuePool)    6070   STRING_POOL *pool = &(dtd->entityValuePool);
6071   enum XML_Error result = XML_ERROR_NONE;        6071   enum XML_Error result = XML_ERROR_NONE;
6072 #ifdef XML_DTD                                   6072 #ifdef XML_DTD
6073   int oldInEntityValue = parser->m_prologStat    6073   int oldInEntityValue = parser->m_prologState.inEntityValue;
6074   parser->m_prologState.inEntityValue = 1;       6074   parser->m_prologState.inEntityValue = 1;
6075 #else                                            6075 #else
6076   UNUSED_P(account);                             6076   UNUSED_P(account);
6077 #endif /* XML_DTD */                             6077 #endif /* XML_DTD */
6078   /* never return Null for the value argument    6078   /* never return Null for the value argument in EntityDeclHandler,
6079      since this would indicate an external en    6079      since this would indicate an external entity; therefore we
6080      have to make sure that entityValuePool.s    6080      have to make sure that entityValuePool.start is not null */
6081   if (! pool->blocks) {                          6081   if (! pool->blocks) {
6082     if (! poolGrow(pool))                        6082     if (! poolGrow(pool))
6083       return XML_ERROR_NO_MEMORY;                6083       return XML_ERROR_NO_MEMORY;
6084   }                                              6084   }
6085                                                  6085 
6086   for (;;) {                                     6086   for (;;) {
6087     const char *next                             6087     const char *next
6088         = entityTextPtr; /* XmlEntityValueTok    6088         = entityTextPtr; /* XmlEntityValueTok doesn't always set the last arg */
6089     int tok = XmlEntityValueTok(enc, entityTe    6089     int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
6090                                                  6090 
6091 #ifdef XML_DTD                                   6091 #ifdef XML_DTD
6092     if (! accountingDiffTolerated(parser, tok    6092     if (! accountingDiffTolerated(parser, tok, entityTextPtr, next, __LINE__,
6093                                   account)) {    6093                                   account)) {
6094       accountingOnAbort(parser);                 6094       accountingOnAbort(parser);
6095       result = XML_ERROR_AMPLIFICATION_LIMIT_    6095       result = XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
6096       goto endEntityValue;                       6096       goto endEntityValue;
6097     }                                            6097     }
6098 #endif                                           6098 #endif
6099                                                  6099 
6100     switch (tok) {                               6100     switch (tok) {
6101     case XML_TOK_PARAM_ENTITY_REF:               6101     case XML_TOK_PARAM_ENTITY_REF:
6102 #ifdef XML_DTD                                   6102 #ifdef XML_DTD
6103       if (parser->m_isParamEntity || enc != p    6103       if (parser->m_isParamEntity || enc != parser->m_encoding) {
6104         const XML_Char *name;                    6104         const XML_Char *name;
6105         ENTITY *entity;                          6105         ENTITY *entity;
6106         name = poolStoreString(&parser->m_tem    6106         name = poolStoreString(&parser->m_tempPool, enc,
6107                                entityTextPtr     6107                                entityTextPtr + enc->minBytesPerChar,
6108                                next - enc->mi    6108                                next - enc->minBytesPerChar);
6109         if (! name) {                            6109         if (! name) {
6110           result = XML_ERROR_NO_MEMORY;          6110           result = XML_ERROR_NO_MEMORY;
6111           goto endEntityValue;                   6111           goto endEntityValue;
6112         }                                        6112         }
6113         entity = (ENTITY *)lookup(parser, &dt    6113         entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
6114         poolDiscard(&parser->m_tempPool);        6114         poolDiscard(&parser->m_tempPool);
6115         if (! entity) {                          6115         if (! entity) {
6116           /* not a well-formedness error - se    6116           /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
6117           /* cannot report skipped entity her    6117           /* cannot report skipped entity here - see comments on
6118              parser->m_skippedEntityHandler      6118              parser->m_skippedEntityHandler
6119           if (parser->m_skippedEntityHandler)    6119           if (parser->m_skippedEntityHandler)
6120             parser->m_skippedEntityHandler(pa    6120             parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
6121           */                                     6121           */
6122           dtd->keepProcessing = dtd->standalo    6122           dtd->keepProcessing = dtd->standalone;
6123           goto endEntityValue;                   6123           goto endEntityValue;
6124         }                                        6124         }
6125         if (entity->open) {                      6125         if (entity->open) {
6126           if (enc == parser->m_encoding)         6126           if (enc == parser->m_encoding)
6127             parser->m_eventPtr = entityTextPt    6127             parser->m_eventPtr = entityTextPtr;
6128           result = XML_ERROR_RECURSIVE_ENTITY    6128           result = XML_ERROR_RECURSIVE_ENTITY_REF;
6129           goto endEntityValue;                   6129           goto endEntityValue;
6130         }                                        6130         }
6131         if (entity->systemId) {                  6131         if (entity->systemId) {
6132           if (parser->m_externalEntityRefHand    6132           if (parser->m_externalEntityRefHandler) {
6133             dtd->paramEntityRead = XML_FALSE;    6133             dtd->paramEntityRead = XML_FALSE;
6134             entity->open = XML_TRUE;             6134             entity->open = XML_TRUE;
6135             entityTrackingOnOpen(parser, enti    6135             entityTrackingOnOpen(parser, entity, __LINE__);
6136             if (! parser->m_externalEntityRef    6136             if (! parser->m_externalEntityRefHandler(
6137                     parser->m_externalEntityR    6137                     parser->m_externalEntityRefHandlerArg, 0, entity->base,
6138                     entity->systemId, entity-    6138                     entity->systemId, entity->publicId)) {
6139               entityTrackingOnClose(parser, e    6139               entityTrackingOnClose(parser, entity, __LINE__);
6140               entity->open = XML_FALSE;          6140               entity->open = XML_FALSE;
6141               result = XML_ERROR_EXTERNAL_ENT    6141               result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
6142               goto endEntityValue;               6142               goto endEntityValue;
6143             }                                    6143             }
6144             entityTrackingOnClose(parser, ent    6144             entityTrackingOnClose(parser, entity, __LINE__);
6145             entity->open = XML_FALSE;            6145             entity->open = XML_FALSE;
6146             if (! dtd->paramEntityRead)          6146             if (! dtd->paramEntityRead)
6147               dtd->keepProcessing = dtd->stan    6147               dtd->keepProcessing = dtd->standalone;
6148           } else                                 6148           } else
6149             dtd->keepProcessing = dtd->standa    6149             dtd->keepProcessing = dtd->standalone;
6150         } else {                                 6150         } else {
6151           entity->open = XML_TRUE;               6151           entity->open = XML_TRUE;
6152           entityTrackingOnOpen(parser, entity    6152           entityTrackingOnOpen(parser, entity, __LINE__);
6153           result = storeEntityValue(             6153           result = storeEntityValue(
6154               parser, parser->m_internalEncod    6154               parser, parser->m_internalEncoding, (const char *)entity->textPtr,
6155               (const char *)(entity->textPtr     6155               (const char *)(entity->textPtr + entity->textLen),
6156               XML_ACCOUNT_ENTITY_EXPANSION);     6156               XML_ACCOUNT_ENTITY_EXPANSION);
6157           entityTrackingOnClose(parser, entit    6157           entityTrackingOnClose(parser, entity, __LINE__);
6158           entity->open = XML_FALSE;              6158           entity->open = XML_FALSE;
6159           if (result)                            6159           if (result)
6160             goto endEntityValue;                 6160             goto endEntityValue;
6161         }                                        6161         }
6162         break;                                   6162         break;
6163       }                                          6163       }
6164 #endif /* XML_DTD */                             6164 #endif /* XML_DTD */
6165       /* In the internal subset, PE reference    6165       /* In the internal subset, PE references are not legal
6166          within markup declarations, e.g enti    6166          within markup declarations, e.g entity values in this case. */
6167       parser->m_eventPtr = entityTextPtr;        6167       parser->m_eventPtr = entityTextPtr;
6168       result = XML_ERROR_PARAM_ENTITY_REF;       6168       result = XML_ERROR_PARAM_ENTITY_REF;
6169       goto endEntityValue;                       6169       goto endEntityValue;
6170     case XML_TOK_NONE:                           6170     case XML_TOK_NONE:
6171       result = XML_ERROR_NONE;                   6171       result = XML_ERROR_NONE;
6172       goto endEntityValue;                       6172       goto endEntityValue;
6173     case XML_TOK_ENTITY_REF:                     6173     case XML_TOK_ENTITY_REF:
6174     case XML_TOK_DATA_CHARS:                     6174     case XML_TOK_DATA_CHARS:
6175       if (! poolAppend(pool, enc, entityTextP    6175       if (! poolAppend(pool, enc, entityTextPtr, next)) {
6176         result = XML_ERROR_NO_MEMORY;            6176         result = XML_ERROR_NO_MEMORY;
6177         goto endEntityValue;                     6177         goto endEntityValue;
6178       }                                          6178       }
6179       break;                                     6179       break;
6180     case XML_TOK_TRAILING_CR:                    6180     case XML_TOK_TRAILING_CR:
6181       next = entityTextPtr + enc->minBytesPer    6181       next = entityTextPtr + enc->minBytesPerChar;
6182       /* fall through */                         6182       /* fall through */
6183     case XML_TOK_DATA_NEWLINE:                   6183     case XML_TOK_DATA_NEWLINE:
6184       if (pool->end == pool->ptr && ! poolGro    6184       if (pool->end == pool->ptr && ! poolGrow(pool)) {
6185         result = XML_ERROR_NO_MEMORY;            6185         result = XML_ERROR_NO_MEMORY;
6186         goto endEntityValue;                     6186         goto endEntityValue;
6187       }                                          6187       }
6188       *(pool->ptr)++ = 0xA;                      6188       *(pool->ptr)++ = 0xA;
6189       break;                                     6189       break;
6190     case XML_TOK_CHAR_REF: {                     6190     case XML_TOK_CHAR_REF: {
6191       XML_Char buf[XML_ENCODE_MAX];              6191       XML_Char buf[XML_ENCODE_MAX];
6192       int i;                                     6192       int i;
6193       int n = XmlCharRefNumber(enc, entityTex    6193       int n = XmlCharRefNumber(enc, entityTextPtr);
6194       if (n < 0) {                               6194       if (n < 0) {
6195         if (enc == parser->m_encoding)           6195         if (enc == parser->m_encoding)
6196           parser->m_eventPtr = entityTextPtr;    6196           parser->m_eventPtr = entityTextPtr;
6197         result = XML_ERROR_BAD_CHAR_REF;         6197         result = XML_ERROR_BAD_CHAR_REF;
6198         goto endEntityValue;                     6198         goto endEntityValue;
6199       }                                          6199       }
6200       n = XmlEncode(n, (ICHAR *)buf);            6200       n = XmlEncode(n, (ICHAR *)buf);
6201       /* The XmlEncode() functions can never     6201       /* The XmlEncode() functions can never return 0 here.  That
6202        * error return happens if the code poi    6202        * error return happens if the code point passed in is either
6203        * negative or greater than or equal to    6203        * negative or greater than or equal to 0x110000.  The
6204        * XmlCharRefNumber() functions will al    6204        * XmlCharRefNumber() functions will all return a number
6205        * strictly less than 0x110000 or a neg    6205        * strictly less than 0x110000 or a negative value if an error
6206        * occurred.  The negative value is int    6206        * occurred.  The negative value is intercepted above, so
6207        * XmlEncode() is never passed a value     6207        * XmlEncode() is never passed a value it might return an
6208        * error for.                              6208        * error for.
6209        */                                        6209        */
6210       for (i = 0; i < n; i++) {                  6210       for (i = 0; i < n; i++) {
6211         if (pool->end == pool->ptr && ! poolG    6211         if (pool->end == pool->ptr && ! poolGrow(pool)) {
6212           result = XML_ERROR_NO_MEMORY;          6212           result = XML_ERROR_NO_MEMORY;
6213           goto endEntityValue;                   6213           goto endEntityValue;
6214         }                                        6214         }
6215         *(pool->ptr)++ = buf[i];                 6215         *(pool->ptr)++ = buf[i];
6216       }                                          6216       }
6217     } break;                                     6217     } break;
6218     case XML_TOK_PARTIAL:                        6218     case XML_TOK_PARTIAL:
6219       if (enc == parser->m_encoding)             6219       if (enc == parser->m_encoding)
6220         parser->m_eventPtr = entityTextPtr;      6220         parser->m_eventPtr = entityTextPtr;
6221       result = XML_ERROR_INVALID_TOKEN;          6221       result = XML_ERROR_INVALID_TOKEN;
6222       goto endEntityValue;                       6222       goto endEntityValue;
6223     case XML_TOK_INVALID:                        6223     case XML_TOK_INVALID:
6224       if (enc == parser->m_encoding)             6224       if (enc == parser->m_encoding)
6225         parser->m_eventPtr = next;               6225         parser->m_eventPtr = next;
6226       result = XML_ERROR_INVALID_TOKEN;          6226       result = XML_ERROR_INVALID_TOKEN;
6227       goto endEntityValue;                       6227       goto endEntityValue;
6228     default:                                     6228     default:
6229       /* This default case should be unnecess    6229       /* This default case should be unnecessary -- all the tokens
6230        * that XmlEntityValueTok() can return     6230        * that XmlEntityValueTok() can return have their own explicit
6231        * cases -- but should be retained for     6231        * cases -- but should be retained for safety.  We do however
6232        * exclude it from the coverage statist    6232        * exclude it from the coverage statistics.
6233        *                                         6233        *
6234        * LCOV_EXCL_START                         6234        * LCOV_EXCL_START
6235        */                                        6235        */
6236       if (enc == parser->m_encoding)             6236       if (enc == parser->m_encoding)
6237         parser->m_eventPtr = entityTextPtr;      6237         parser->m_eventPtr = entityTextPtr;
6238       result = XML_ERROR_UNEXPECTED_STATE;       6238       result = XML_ERROR_UNEXPECTED_STATE;
6239       goto endEntityValue;                       6239       goto endEntityValue;
6240       /* LCOV_EXCL_STOP */                       6240       /* LCOV_EXCL_STOP */
6241     }                                            6241     }
6242     entityTextPtr = next;                        6242     entityTextPtr = next;
6243   }                                              6243   }
6244 endEntityValue:                                  6244 endEntityValue:
6245 #ifdef XML_DTD                                   6245 #ifdef XML_DTD
6246   parser->m_prologState.inEntityValue = oldIn    6246   parser->m_prologState.inEntityValue = oldInEntityValue;
6247 #endif /* XML_DTD */                             6247 #endif /* XML_DTD */
6248   return result;                                 6248   return result;
6249 }                                                6249 }
6250                                                  6250 
6251 static void FASTCALL                             6251 static void FASTCALL
6252 normalizeLines(XML_Char *s) {                    6252 normalizeLines(XML_Char *s) {
6253   XML_Char *p;                                   6253   XML_Char *p;
6254   for (;; s++) {                                 6254   for (;; s++) {
6255     if (*s == XML_T('\0'))                       6255     if (*s == XML_T('\0'))
6256       return;                                    6256       return;
6257     if (*s == 0xD)                               6257     if (*s == 0xD)
6258       break;                                     6258       break;
6259   }                                              6259   }
6260   p = s;                                         6260   p = s;
6261   do {                                           6261   do {
6262     if (*s == 0xD) {                             6262     if (*s == 0xD) {
6263       *p++ = 0xA;                                6263       *p++ = 0xA;
6264       if (*++s == 0xA)                           6264       if (*++s == 0xA)
6265         s++;                                     6265         s++;
6266     } else                                       6266     } else
6267       *p++ = *s++;                               6267       *p++ = *s++;
6268   } while (*s);                                  6268   } while (*s);
6269   *p = XML_T('\0');                              6269   *p = XML_T('\0');
6270 }                                                6270 }
6271                                                  6271 
6272 static int                                       6272 static int
6273 reportProcessingInstruction(XML_Parser parser    6273 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
6274                             const char *start    6274                             const char *start, const char *end) {
6275   const XML_Char *target;                        6275   const XML_Char *target;
6276   XML_Char *data;                                6276   XML_Char *data;
6277   const char *tem;                               6277   const char *tem;
6278   if (! parser->m_processingInstructionHandle    6278   if (! parser->m_processingInstructionHandler) {
6279     if (parser->m_defaultHandler)                6279     if (parser->m_defaultHandler)
6280       reportDefault(parser, enc, start, end);    6280       reportDefault(parser, enc, start, end);
6281     return 1;                                    6281     return 1;
6282   }                                              6282   }
6283   start += enc->minBytesPerChar * 2;             6283   start += enc->minBytesPerChar * 2;
6284   tem = start + XmlNameLength(enc, start);       6284   tem = start + XmlNameLength(enc, start);
6285   target = poolStoreString(&parser->m_tempPoo    6285   target = poolStoreString(&parser->m_tempPool, enc, start, tem);
6286   if (! target)                                  6286   if (! target)
6287     return 0;                                    6287     return 0;
6288   poolFinish(&parser->m_tempPool);               6288   poolFinish(&parser->m_tempPool);
6289   data = poolStoreString(&parser->m_tempPool,    6289   data = poolStoreString(&parser->m_tempPool, enc, XmlSkipS(enc, tem),
6290                          end - enc->minBytesP    6290                          end - enc->minBytesPerChar * 2);
6291   if (! data)                                    6291   if (! data)
6292     return 0;                                    6292     return 0;
6293   normalizeLines(data);                          6293   normalizeLines(data);
6294   parser->m_processingInstructionHandler(pars    6294   parser->m_processingInstructionHandler(parser->m_handlerArg, target, data);
6295   poolClear(&parser->m_tempPool);                6295   poolClear(&parser->m_tempPool);
6296   return 1;                                      6296   return 1;
6297 }                                                6297 }
6298                                                  6298 
6299 static int                                       6299 static int
6300 reportComment(XML_Parser parser, const ENCODI    6300 reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
6301               const char *end) {                 6301               const char *end) {
6302   XML_Char *data;                                6302   XML_Char *data;
6303   if (! parser->m_commentHandler) {              6303   if (! parser->m_commentHandler) {
6304     if (parser->m_defaultHandler)                6304     if (parser->m_defaultHandler)
6305       reportDefault(parser, enc, start, end);    6305       reportDefault(parser, enc, start, end);
6306     return 1;                                    6306     return 1;
6307   }                                              6307   }
6308   data = poolStoreString(&parser->m_tempPool,    6308   data = poolStoreString(&parser->m_tempPool, enc,
6309                          start + enc->minByte    6309                          start + enc->minBytesPerChar * 4,
6310                          end - enc->minBytesP    6310                          end - enc->minBytesPerChar * 3);
6311   if (! data)                                    6311   if (! data)
6312     return 0;                                    6312     return 0;
6313   normalizeLines(data);                          6313   normalizeLines(data);
6314   parser->m_commentHandler(parser->m_handlerA    6314   parser->m_commentHandler(parser->m_handlerArg, data);
6315   poolClear(&parser->m_tempPool);                6315   poolClear(&parser->m_tempPool);
6316   return 1;                                      6316   return 1;
6317 }                                                6317 }
6318                                                  6318 
6319 static void                                      6319 static void
6320 reportDefault(XML_Parser parser, const ENCODI    6320 reportDefault(XML_Parser parser, const ENCODING *enc, const char *s,
6321               const char *end) {                 6321               const char *end) {
6322   if (MUST_CONVERT(enc, s)) {                    6322   if (MUST_CONVERT(enc, s)) {
6323     enum XML_Convert_Result convert_res;         6323     enum XML_Convert_Result convert_res;
6324     const char **eventPP;                        6324     const char **eventPP;
6325     const char **eventEndPP;                     6325     const char **eventEndPP;
6326     if (enc == parser->m_encoding) {             6326     if (enc == parser->m_encoding) {
6327       eventPP = &parser->m_eventPtr;             6327       eventPP = &parser->m_eventPtr;
6328       eventEndPP = &parser->m_eventEndPtr;       6328       eventEndPP = &parser->m_eventEndPtr;
6329     } else {                                     6329     } else {
6330       /* To get here, two things must be true    6330       /* To get here, two things must be true; the parser must be
6331        * using a character encoding that is n    6331        * using a character encoding that is not the same as the
6332        * encoding passed in, and the encoding    6332        * encoding passed in, and the encoding passed in must need
6333        * conversion to the internal format (U    6333        * conversion to the internal format (UTF-8 unless XML_UNICODE
6334        * is defined).  The only occasions on     6334        * is defined).  The only occasions on which the encoding passed
6335        * in is not the same as the parser's e    6335        * in is not the same as the parser's encoding are when it is
6336        * the internal encoding (e.g. a previo    6336        * the internal encoding (e.g. a previously defined parameter
6337        * entity, already converted to interna    6337        * entity, already converted to internal format).  This by
6338        * definition doesn't need conversion,     6338        * definition doesn't need conversion, so the whole branch never
6339        * gets executed.                          6339        * gets executed.
6340        *                                         6340        *
6341        * For safety's sake we don't delete th    6341        * For safety's sake we don't delete these lines and merely
6342        * exclude them from coverage statistic    6342        * exclude them from coverage statistics.
6343        *                                         6343        *
6344        * LCOV_EXCL_START                         6344        * LCOV_EXCL_START
6345        */                                        6345        */
6346       eventPP = &(parser->m_openInternalEntit    6346       eventPP = &(parser->m_openInternalEntities->internalEventPtr);
6347       eventEndPP = &(parser->m_openInternalEn    6347       eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
6348       /* LCOV_EXCL_STOP */                       6348       /* LCOV_EXCL_STOP */
6349     }                                            6349     }
6350     do {                                         6350     do {
6351       ICHAR *dataPtr = (ICHAR *)parser->m_dat    6351       ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
6352       convert_res                                6352       convert_res
6353           = XmlConvert(enc, &s, end, &dataPtr    6353           = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
6354       *eventEndPP = s;                           6354       *eventEndPP = s;
6355       parser->m_defaultHandler(parser->m_hand    6355       parser->m_defaultHandler(parser->m_handlerArg, parser->m_dataBuf,
6356                                (int)(dataPtr     6356                                (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
6357       *eventPP = s;                              6357       *eventPP = s;
6358     } while ((convert_res != XML_CONVERT_COMP    6358     } while ((convert_res != XML_CONVERT_COMPLETED)
6359              && (convert_res != XML_CONVERT_I    6359              && (convert_res != XML_CONVERT_INPUT_INCOMPLETE));
6360   } else                                         6360   } else
6361     parser->m_defaultHandler(parser->m_handle    6361     parser->m_defaultHandler(parser->m_handlerArg, (XML_Char *)s,
6362                              (int)((XML_Char     6362                              (int)((XML_Char *)end - (XML_Char *)s));
6363 }                                                6363 }
6364                                                  6364 
6365 static int                                       6365 static int
6366 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE    6366 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
6367                 XML_Bool isId, const XML_Char    6367                 XML_Bool isId, const XML_Char *value, XML_Parser parser) {
6368   DEFAULT_ATTRIBUTE *att;                        6368   DEFAULT_ATTRIBUTE *att;
6369   if (value || isId) {                           6369   if (value || isId) {
6370     /* The handling of default attributes get    6370     /* The handling of default attributes gets messed up if we have
6371        a default which duplicates a non-defau    6371        a default which duplicates a non-default. */
6372     int i;                                       6372     int i;
6373     for (i = 0; i < type->nDefaultAtts; i++)     6373     for (i = 0; i < type->nDefaultAtts; i++)
6374       if (attId == type->defaultAtts[i].id)      6374       if (attId == type->defaultAtts[i].id)
6375         return 1;                                6375         return 1;
6376     if (isId && ! type->idAtt && ! attId->xml    6376     if (isId && ! type->idAtt && ! attId->xmlns)
6377       type->idAtt = attId;                       6377       type->idAtt = attId;
6378   }                                              6378   }
6379   if (type->nDefaultAtts == type->allocDefaul    6379   if (type->nDefaultAtts == type->allocDefaultAtts) {
6380     if (type->allocDefaultAtts == 0) {           6380     if (type->allocDefaultAtts == 0) {
6381       type->allocDefaultAtts = 8;                6381       type->allocDefaultAtts = 8;
6382       type->defaultAtts = (DEFAULT_ATTRIBUTE     6382       type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(
6383           parser, type->allocDefaultAtts * si    6383           parser, type->allocDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
6384       if (! type->defaultAtts) {                 6384       if (! type->defaultAtts) {
6385         type->allocDefaultAtts = 0;              6385         type->allocDefaultAtts = 0;
6386         return 0;                                6386         return 0;
6387       }                                          6387       }
6388     } else {                                     6388     } else {
6389       DEFAULT_ATTRIBUTE *temp;                   6389       DEFAULT_ATTRIBUTE *temp;
6390                                                  6390 
6391       /* Detect and prevent integer overflow     6391       /* Detect and prevent integer overflow */
6392       if (type->allocDefaultAtts > INT_MAX /     6392       if (type->allocDefaultAtts > INT_MAX / 2) {
6393         return 0;                                6393         return 0;
6394       }                                          6394       }
6395                                                  6395 
6396       int count = type->allocDefaultAtts * 2;    6396       int count = type->allocDefaultAtts * 2;
6397                                                  6397 
6398       /* Detect and prevent integer overflow.    6398       /* Detect and prevent integer overflow.
6399        * The preprocessor guard addresses the    6399        * The preprocessor guard addresses the "always false" warning
6400        * from -Wtype-limits on platforms wher    6400        * from -Wtype-limits on platforms where
6401        * sizeof(unsigned int) < sizeof(size_t    6401        * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
6402 #if UINT_MAX >= SIZE_MAX                         6402 #if UINT_MAX >= SIZE_MAX
6403       if ((unsigned)count > (size_t)(-1) / si    6403       if ((unsigned)count > (size_t)(-1) / sizeof(DEFAULT_ATTRIBUTE)) {
6404         return 0;                                6404         return 0;
6405       }                                          6405       }
6406 #endif                                           6406 #endif
6407                                                  6407 
6408       temp = (DEFAULT_ATTRIBUTE *)REALLOC(par    6408       temp = (DEFAULT_ATTRIBUTE *)REALLOC(parser, type->defaultAtts,
6409                                           (co    6409                                           (count * sizeof(DEFAULT_ATTRIBUTE)));
6410       if (temp == NULL)                          6410       if (temp == NULL)
6411         return 0;                                6411         return 0;
6412       type->allocDefaultAtts = count;            6412       type->allocDefaultAtts = count;
6413       type->defaultAtts = temp;                  6413       type->defaultAtts = temp;
6414     }                                            6414     }
6415   }                                              6415   }
6416   att = type->defaultAtts + type->nDefaultAtt    6416   att = type->defaultAtts + type->nDefaultAtts;
6417   att->id = attId;                               6417   att->id = attId;
6418   att->value = value;                            6418   att->value = value;
6419   att->isCdata = isCdata;                        6419   att->isCdata = isCdata;
6420   if (! isCdata)                                 6420   if (! isCdata)
6421     attId->maybeTokenized = XML_TRUE;            6421     attId->maybeTokenized = XML_TRUE;
6422   type->nDefaultAtts += 1;                       6422   type->nDefaultAtts += 1;
6423   return 1;                                      6423   return 1;
6424 }                                                6424 }
6425                                                  6425 
6426 static int                                       6426 static int
6427 setElementTypePrefix(XML_Parser parser, ELEME    6427 setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType) {
6428   DTD *const dtd = parser->m_dtd; /* save one    6428   DTD *const dtd = parser->m_dtd; /* save one level of indirection */
6429   const XML_Char *name;                          6429   const XML_Char *name;
6430   for (name = elementType->name; *name; name+    6430   for (name = elementType->name; *name; name++) {
6431     if (*name == XML_T(ASCII_COLON)) {           6431     if (*name == XML_T(ASCII_COLON)) {
6432       PREFIX *prefix;                            6432       PREFIX *prefix;
6433       const XML_Char *s;                         6433       const XML_Char *s;
6434       for (s = elementType->name; s != name;     6434       for (s = elementType->name; s != name; s++) {
6435         if (! poolAppendChar(&dtd->pool, *s))    6435         if (! poolAppendChar(&dtd->pool, *s))
6436           return 0;                              6436           return 0;
6437       }                                          6437       }
6438       if (! poolAppendChar(&dtd->pool, XML_T(    6438       if (! poolAppendChar(&dtd->pool, XML_T('\0')))
6439         return 0;                                6439         return 0;
6440       prefix = (PREFIX *)lookup(parser, &dtd-    6440       prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
6441                                 sizeof(PREFIX    6441                                 sizeof(PREFIX));
6442       if (! prefix)                              6442       if (! prefix)
6443         return 0;                                6443         return 0;
6444       if (prefix->name == poolStart(&dtd->poo    6444       if (prefix->name == poolStart(&dtd->pool))
6445         poolFinish(&dtd->pool);                  6445         poolFinish(&dtd->pool);
6446       else                                       6446       else
6447         poolDiscard(&dtd->pool);                 6447         poolDiscard(&dtd->pool);
6448       elementType->prefix = prefix;              6448       elementType->prefix = prefix;
6449       break;                                     6449       break;
6450     }                                            6450     }
6451   }                                              6451   }
6452   return 1;                                      6452   return 1;
6453 }                                                6453 }
6454                                                  6454 
6455 static ATTRIBUTE_ID *                            6455 static ATTRIBUTE_ID *
6456 getAttributeId(XML_Parser parser, const ENCOD    6456 getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
6457                const char *end) {                6457                const char *end) {
6458   DTD *const dtd = parser->m_dtd; /* save one    6458   DTD *const dtd = parser->m_dtd; /* save one level of indirection */
6459   ATTRIBUTE_ID *id;                              6459   ATTRIBUTE_ID *id;
6460   const XML_Char *name;                          6460   const XML_Char *name;
6461   if (! poolAppendChar(&dtd->pool, XML_T('\0'    6461   if (! poolAppendChar(&dtd->pool, XML_T('\0')))
6462     return NULL;                                 6462     return NULL;
6463   name = poolStoreString(&dtd->pool, enc, sta    6463   name = poolStoreString(&dtd->pool, enc, start, end);
6464   if (! name)                                    6464   if (! name)
6465     return NULL;                                 6465     return NULL;
6466   /* skip quotation mark - its storage will b    6466   /* skip quotation mark - its storage will be re-used (like in name[-1]) */
6467   ++name;                                        6467   ++name;
6468   id = (ATTRIBUTE_ID *)lookup(parser, &dtd->a    6468   id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name,
6469                               sizeof(ATTRIBUT    6469                               sizeof(ATTRIBUTE_ID));
6470   if (! id)                                      6470   if (! id)
6471     return NULL;                                 6471     return NULL;
6472   if (id->name != name)                          6472   if (id->name != name)
6473     poolDiscard(&dtd->pool);                     6473     poolDiscard(&dtd->pool);
6474   else {                                         6474   else {
6475     poolFinish(&dtd->pool);                      6475     poolFinish(&dtd->pool);
6476     if (! parser->m_ns)                          6476     if (! parser->m_ns)
6477       ;                                          6477       ;
6478     else if (name[0] == XML_T(ASCII_x) && nam    6478     else if (name[0] == XML_T(ASCII_x) && name[1] == XML_T(ASCII_m)
6479              && name[2] == XML_T(ASCII_l) &&     6479              && name[2] == XML_T(ASCII_l) && name[3] == XML_T(ASCII_n)
6480              && name[4] == XML_T(ASCII_s)        6480              && name[4] == XML_T(ASCII_s)
6481              && (name[5] == XML_T('\0') || na    6481              && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) {
6482       if (name[5] == XML_T('\0'))                6482       if (name[5] == XML_T('\0'))
6483         id->prefix = &dtd->defaultPrefix;        6483         id->prefix = &dtd->defaultPrefix;
6484       else                                       6484       else
6485         id->prefix = (PREFIX *)lookup(parser,    6485         id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6,
6486                                       sizeof(    6486                                       sizeof(PREFIX));
6487       id->xmlns = XML_TRUE;                      6487       id->xmlns = XML_TRUE;
6488     } else {                                     6488     } else {
6489       int i;                                     6489       int i;
6490       for (i = 0; name[i]; i++) {                6490       for (i = 0; name[i]; i++) {
6491         /* attributes without prefix are *not    6491         /* attributes without prefix are *not* in the default namespace */
6492         if (name[i] == XML_T(ASCII_COLON)) {     6492         if (name[i] == XML_T(ASCII_COLON)) {
6493           int j;                                 6493           int j;
6494           for (j = 0; j < i; j++) {              6494           for (j = 0; j < i; j++) {
6495             if (! poolAppendChar(&dtd->pool,     6495             if (! poolAppendChar(&dtd->pool, name[j]))
6496               return NULL;                       6496               return NULL;
6497           }                                      6497           }
6498           if (! poolAppendChar(&dtd->pool, XM    6498           if (! poolAppendChar(&dtd->pool, XML_T('\0')))
6499             return NULL;                         6499             return NULL;
6500           id->prefix = (PREFIX *)lookup(parse    6500           id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes,
6501                                         poolS    6501                                         poolStart(&dtd->pool), sizeof(PREFIX));
6502           if (! id->prefix)                      6502           if (! id->prefix)
6503             return NULL;                         6503             return NULL;
6504           if (id->prefix->name == poolStart(&    6504           if (id->prefix->name == poolStart(&dtd->pool))
6505             poolFinish(&dtd->pool);              6505             poolFinish(&dtd->pool);
6506           else                                   6506           else
6507             poolDiscard(&dtd->pool);             6507             poolDiscard(&dtd->pool);
6508           break;                                 6508           break;
6509         }                                        6509         }
6510       }                                          6510       }
6511     }                                            6511     }
6512   }                                              6512   }
6513   return id;                                     6513   return id;
6514 }                                                6514 }
6515                                                  6515 
6516 #define CONTEXT_SEP XML_T(ASCII_FF)              6516 #define CONTEXT_SEP XML_T(ASCII_FF)
6517                                                  6517 
6518 static const XML_Char *                          6518 static const XML_Char *
6519 getContext(XML_Parser parser) {                  6519 getContext(XML_Parser parser) {
6520   DTD *const dtd = parser->m_dtd; /* save one    6520   DTD *const dtd = parser->m_dtd; /* save one level of indirection */
6521   HASH_TABLE_ITER iter;                          6521   HASH_TABLE_ITER iter;
6522   XML_Bool needSep = XML_FALSE;                  6522   XML_Bool needSep = XML_FALSE;
6523                                                  6523 
6524   if (dtd->defaultPrefix.binding) {              6524   if (dtd->defaultPrefix.binding) {
6525     int i;                                       6525     int i;
6526     int len;                                     6526     int len;
6527     if (! poolAppendChar(&parser->m_tempPool,    6527     if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS)))
6528       return NULL;                               6528       return NULL;
6529     len = dtd->defaultPrefix.binding->uriLen;    6529     len = dtd->defaultPrefix.binding->uriLen;
6530     if (parser->m_namespaceSeparator)            6530     if (parser->m_namespaceSeparator)
6531       len--;                                     6531       len--;
6532     for (i = 0; i < len; i++) {                  6532     for (i = 0; i < len; i++) {
6533       if (! poolAppendChar(&parser->m_tempPoo    6533       if (! poolAppendChar(&parser->m_tempPool,
6534                            dtd->defaultPrefix    6534                            dtd->defaultPrefix.binding->uri[i])) {
6535         /* Because of memory caching, I don't    6535         /* Because of memory caching, I don't believe this line can be
6536          * executed.                             6536          * executed.
6537          *                                       6537          *
6538          * This is part of a loop copying the    6538          * This is part of a loop copying the default prefix binding
6539          * URI into the parser's temporary st    6539          * URI into the parser's temporary string pool.  Previously,
6540          * that URI was copied into the same     6540          * that URI was copied into the same string pool, with a
6541          * terminating NUL character, as part    6541          * terminating NUL character, as part of setContext().  When
6542          * the pool was cleared, that leaves     6542          * the pool was cleared, that leaves a block definitely big
6543          * enough to hold the URI on the free    6543          * enough to hold the URI on the free block list of the pool.
6544          * The URI copy in getContext() there    6544          * The URI copy in getContext() therefore cannot run out of
6545          * memory.                               6545          * memory.
6546          *                                       6546          *
6547          * If the pool is used between the se    6547          * If the pool is used between the setContext() and
6548          * getContext() calls, the worst it c    6548          * getContext() calls, the worst it can do is leave a bigger
6549          * block on the front of the free lis    6549          * block on the front of the free list.  Given that this is
6550          * all somewhat inobvious and program    6550          * all somewhat inobvious and program logic can be changed, we
6551          * don't delete the line but we do ex    6551          * don't delete the line but we do exclude it from the test
6552          * coverage statistics.                  6552          * coverage statistics.
6553          */                                      6553          */
6554         return NULL; /* LCOV_EXCL_LINE */        6554         return NULL; /* LCOV_EXCL_LINE */
6555       }                                          6555       }
6556     }                                            6556     }
6557     needSep = XML_TRUE;                          6557     needSep = XML_TRUE;
6558   }                                              6558   }
6559                                                  6559 
6560   hashTableIterInit(&iter, &(dtd->prefixes));    6560   hashTableIterInit(&iter, &(dtd->prefixes));
6561   for (;;) {                                     6561   for (;;) {
6562     int i;                                       6562     int i;
6563     int len;                                     6563     int len;
6564     const XML_Char *s;                           6564     const XML_Char *s;
6565     PREFIX *prefix = (PREFIX *)hashTableIterN    6565     PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
6566     if (! prefix)                                6566     if (! prefix)
6567       break;                                     6567       break;
6568     if (! prefix->binding) {                     6568     if (! prefix->binding) {
6569       /* This test appears to be (justifiable    6569       /* This test appears to be (justifiable) paranoia.  There does
6570        * not seem to be a way of injecting a     6570        * not seem to be a way of injecting a prefix without a binding
6571        * that doesn't get errored long before    6571        * that doesn't get errored long before this function is called.
6572        * The test should remain for safety's     6572        * The test should remain for safety's sake, so we instead
6573        * exclude the following line from the     6573        * exclude the following line from the coverage statistics.
6574        */                                        6574        */
6575       continue; /* LCOV_EXCL_LINE */             6575       continue; /* LCOV_EXCL_LINE */
6576     }                                            6576     }
6577     if (needSep && ! poolAppendChar(&parser->    6577     if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP))
6578       return NULL;                               6578       return NULL;
6579     for (s = prefix->name; *s; s++)              6579     for (s = prefix->name; *s; s++)
6580       if (! poolAppendChar(&parser->m_tempPoo    6580       if (! poolAppendChar(&parser->m_tempPool, *s))
6581         return NULL;                             6581         return NULL;
6582     if (! poolAppendChar(&parser->m_tempPool,    6582     if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS)))
6583       return NULL;                               6583       return NULL;
6584     len = prefix->binding->uriLen;               6584     len = prefix->binding->uriLen;
6585     if (parser->m_namespaceSeparator)            6585     if (parser->m_namespaceSeparator)
6586       len--;                                     6586       len--;
6587     for (i = 0; i < len; i++)                    6587     for (i = 0; i < len; i++)
6588       if (! poolAppendChar(&parser->m_tempPoo    6588       if (! poolAppendChar(&parser->m_tempPool, prefix->binding->uri[i]))
6589         return NULL;                             6589         return NULL;
6590     needSep = XML_TRUE;                          6590     needSep = XML_TRUE;
6591   }                                              6591   }
6592                                                  6592 
6593   hashTableIterInit(&iter, &(dtd->generalEnti    6593   hashTableIterInit(&iter, &(dtd->generalEntities));
6594   for (;;) {                                     6594   for (;;) {
6595     const XML_Char *s;                           6595     const XML_Char *s;
6596     ENTITY *e = (ENTITY *)hashTableIterNext(&    6596     ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
6597     if (! e)                                     6597     if (! e)
6598       break;                                     6598       break;
6599     if (! e->open)                               6599     if (! e->open)
6600       continue;                                  6600       continue;
6601     if (needSep && ! poolAppendChar(&parser->    6601     if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP))
6602       return NULL;                               6602       return NULL;
6603     for (s = e->name; *s; s++)                   6603     for (s = e->name; *s; s++)
6604       if (! poolAppendChar(&parser->m_tempPoo    6604       if (! poolAppendChar(&parser->m_tempPool, *s))
6605         return 0;                                6605         return 0;
6606     needSep = XML_TRUE;                          6606     needSep = XML_TRUE;
6607   }                                              6607   }
6608                                                  6608 
6609   if (! poolAppendChar(&parser->m_tempPool, X    6609   if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
6610     return NULL;                                 6610     return NULL;
6611   return parser->m_tempPool.start;               6611   return parser->m_tempPool.start;
6612 }                                                6612 }
6613                                                  6613 
6614 static XML_Bool                                  6614 static XML_Bool
6615 setContext(XML_Parser parser, const XML_Char     6615 setContext(XML_Parser parser, const XML_Char *context) {
6616   DTD *const dtd = parser->m_dtd; /* save one    6616   DTD *const dtd = parser->m_dtd; /* save one level of indirection */
6617   const XML_Char *s = context;                   6617   const XML_Char *s = context;
6618                                                  6618 
6619   while (*context != XML_T('\0')) {              6619   while (*context != XML_T('\0')) {
6620     if (*s == CONTEXT_SEP || *s == XML_T('\0'    6620     if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
6621       ENTITY *e;                                 6621       ENTITY *e;
6622       if (! poolAppendChar(&parser->m_tempPoo    6622       if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
6623         return XML_FALSE;                        6623         return XML_FALSE;
6624       e = (ENTITY *)lookup(parser, &dtd->gene    6624       e = (ENTITY *)lookup(parser, &dtd->generalEntities,
6625                            poolStart(&parser-    6625                            poolStart(&parser->m_tempPool), 0);
6626       if (e)                                     6626       if (e)
6627         e->open = XML_TRUE;                      6627         e->open = XML_TRUE;
6628       if (*s != XML_T('\0'))                     6628       if (*s != XML_T('\0'))
6629         s++;                                     6629         s++;
6630       context = s;                               6630       context = s;
6631       poolDiscard(&parser->m_tempPool);          6631       poolDiscard(&parser->m_tempPool);
6632     } else if (*s == XML_T(ASCII_EQUALS)) {      6632     } else if (*s == XML_T(ASCII_EQUALS)) {
6633       PREFIX *prefix;                            6633       PREFIX *prefix;
6634       if (poolLength(&parser->m_tempPool) ==     6634       if (poolLength(&parser->m_tempPool) == 0)
6635         prefix = &dtd->defaultPrefix;            6635         prefix = &dtd->defaultPrefix;
6636       else {                                     6636       else {
6637         if (! poolAppendChar(&parser->m_tempP    6637         if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
6638           return XML_FALSE;                      6638           return XML_FALSE;
6639         prefix                                   6639         prefix
6640             = (PREFIX *)lookup(parser, &dtd->    6640             = (PREFIX *)lookup(parser, &dtd->prefixes,
6641                                poolStart(&par    6641                                poolStart(&parser->m_tempPool), sizeof(PREFIX));
6642         if (! prefix)                            6642         if (! prefix)
6643           return XML_FALSE;                      6643           return XML_FALSE;
6644         if (prefix->name == poolStart(&parser    6644         if (prefix->name == poolStart(&parser->m_tempPool)) {
6645           prefix->name = poolCopyString(&dtd-    6645           prefix->name = poolCopyString(&dtd->pool, prefix->name);
6646           if (! prefix->name)                    6646           if (! prefix->name)
6647             return XML_FALSE;                    6647             return XML_FALSE;
6648         }                                        6648         }
6649         poolDiscard(&parser->m_tempPool);        6649         poolDiscard(&parser->m_tempPool);
6650       }                                          6650       }
6651       for (context = s + 1; *context != CONTE    6651       for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0');
6652            context++)                            6652            context++)
6653         if (! poolAppendChar(&parser->m_tempP    6653         if (! poolAppendChar(&parser->m_tempPool, *context))
6654           return XML_FALSE;                      6654           return XML_FALSE;
6655       if (! poolAppendChar(&parser->m_tempPoo    6655       if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
6656         return XML_FALSE;                        6656         return XML_FALSE;
6657       if (addBinding(parser, prefix, NULL, po    6657       if (addBinding(parser, prefix, NULL, poolStart(&parser->m_tempPool),
6658                      &parser->m_inheritedBind    6658                      &parser->m_inheritedBindings)
6659           != XML_ERROR_NONE)                     6659           != XML_ERROR_NONE)
6660         return XML_FALSE;                        6660         return XML_FALSE;
6661       poolDiscard(&parser->m_tempPool);          6661       poolDiscard(&parser->m_tempPool);
6662       if (*context != XML_T('\0'))               6662       if (*context != XML_T('\0'))
6663         ++context;                               6663         ++context;
6664       s = context;                               6664       s = context;
6665     } else {                                     6665     } else {
6666       if (! poolAppendChar(&parser->m_tempPoo    6666       if (! poolAppendChar(&parser->m_tempPool, *s))
6667         return XML_FALSE;                        6667         return XML_FALSE;
6668       s++;                                       6668       s++;
6669     }                                            6669     }
6670   }                                              6670   }
6671   return XML_TRUE;                               6671   return XML_TRUE;
6672 }                                                6672 }
6673                                                  6673 
6674 static void FASTCALL                             6674 static void FASTCALL
6675 normalizePublicId(XML_Char *publicId) {          6675 normalizePublicId(XML_Char *publicId) {
6676   XML_Char *p = publicId;                        6676   XML_Char *p = publicId;
6677   XML_Char *s;                                   6677   XML_Char *s;
6678   for (s = publicId; *s; s++) {                  6678   for (s = publicId; *s; s++) {
6679     switch (*s) {                                6679     switch (*s) {
6680     case 0x20:                                   6680     case 0x20:
6681     case 0xD:                                    6681     case 0xD:
6682     case 0xA:                                    6682     case 0xA:
6683       if (p != publicId && p[-1] != 0x20)        6683       if (p != publicId && p[-1] != 0x20)
6684         *p++ = 0x20;                             6684         *p++ = 0x20;
6685       break;                                     6685       break;
6686     default:                                     6686     default:
6687       *p++ = *s;                                 6687       *p++ = *s;
6688     }                                            6688     }
6689   }                                              6689   }
6690   if (p != publicId && p[-1] == 0x20)            6690   if (p != publicId && p[-1] == 0x20)
6691     --p;                                         6691     --p;
6692   *p = XML_T('\0');                              6692   *p = XML_T('\0');
6693 }                                                6693 }
6694                                                  6694 
6695 static DTD *                                     6695 static DTD *
6696 dtdCreate(const XML_Memory_Handling_Suite *ms    6696 dtdCreate(const XML_Memory_Handling_Suite *ms) {
6697   DTD *p = ms->malloc_fcn(sizeof(DTD));          6697   DTD *p = ms->malloc_fcn(sizeof(DTD));
6698   if (p == NULL)                                 6698   if (p == NULL)
6699     return p;                                    6699     return p;
6700   poolInit(&(p->pool), ms);                      6700   poolInit(&(p->pool), ms);
6701   poolInit(&(p->entityValuePool), ms);           6701   poolInit(&(p->entityValuePool), ms);
6702   hashTableInit(&(p->generalEntities), ms);      6702   hashTableInit(&(p->generalEntities), ms);
6703   hashTableInit(&(p->elementTypes), ms);         6703   hashTableInit(&(p->elementTypes), ms);
6704   hashTableInit(&(p->attributeIds), ms);         6704   hashTableInit(&(p->attributeIds), ms);
6705   hashTableInit(&(p->prefixes), ms);             6705   hashTableInit(&(p->prefixes), ms);
6706 #ifdef XML_DTD                                   6706 #ifdef XML_DTD
6707   p->paramEntityRead = XML_FALSE;                6707   p->paramEntityRead = XML_FALSE;
6708   hashTableInit(&(p->paramEntities), ms);        6708   hashTableInit(&(p->paramEntities), ms);
6709 #endif /* XML_DTD */                             6709 #endif /* XML_DTD */
6710   p->defaultPrefix.name = NULL;                  6710   p->defaultPrefix.name = NULL;
6711   p->defaultPrefix.binding = NULL;               6711   p->defaultPrefix.binding = NULL;
6712                                                  6712 
6713   p->in_eldecl = XML_FALSE;                      6713   p->in_eldecl = XML_FALSE;
6714   p->scaffIndex = NULL;                          6714   p->scaffIndex = NULL;
6715   p->scaffold = NULL;                            6715   p->scaffold = NULL;
6716   p->scaffLevel = 0;                             6716   p->scaffLevel = 0;
6717   p->scaffSize = 0;                              6717   p->scaffSize = 0;
6718   p->scaffCount = 0;                             6718   p->scaffCount = 0;
6719   p->contentStringLen = 0;                       6719   p->contentStringLen = 0;
6720                                                  6720 
6721   p->keepProcessing = XML_TRUE;                  6721   p->keepProcessing = XML_TRUE;
6722   p->hasParamEntityRefs = XML_FALSE;             6722   p->hasParamEntityRefs = XML_FALSE;
6723   p->standalone = XML_FALSE;                     6723   p->standalone = XML_FALSE;
6724   return p;                                      6724   return p;
6725 }                                                6725 }
6726                                                  6726 
6727 static void                                      6727 static void
6728 dtdReset(DTD *p, const XML_Memory_Handling_Su    6728 dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms) {
6729   HASH_TABLE_ITER iter;                          6729   HASH_TABLE_ITER iter;
6730   hashTableIterInit(&iter, &(p->elementTypes)    6730   hashTableIterInit(&iter, &(p->elementTypes));
6731   for (;;) {                                     6731   for (;;) {
6732     ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTab    6732     ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
6733     if (! e)                                     6733     if (! e)
6734       break;                                     6734       break;
6735     if (e->allocDefaultAtts != 0)                6735     if (e->allocDefaultAtts != 0)
6736       ms->free_fcn(e->defaultAtts);              6736       ms->free_fcn(e->defaultAtts);
6737   }                                              6737   }
6738   hashTableClear(&(p->generalEntities));         6738   hashTableClear(&(p->generalEntities));
6739 #ifdef XML_DTD                                   6739 #ifdef XML_DTD
6740   p->paramEntityRead = XML_FALSE;                6740   p->paramEntityRead = XML_FALSE;
6741   hashTableClear(&(p->paramEntities));           6741   hashTableClear(&(p->paramEntities));
6742 #endif /* XML_DTD */                             6742 #endif /* XML_DTD */
6743   hashTableClear(&(p->elementTypes));            6743   hashTableClear(&(p->elementTypes));
6744   hashTableClear(&(p->attributeIds));            6744   hashTableClear(&(p->attributeIds));
6745   hashTableClear(&(p->prefixes));                6745   hashTableClear(&(p->prefixes));
6746   poolClear(&(p->pool));                         6746   poolClear(&(p->pool));
6747   poolClear(&(p->entityValuePool));              6747   poolClear(&(p->entityValuePool));
6748   p->defaultPrefix.name = NULL;                  6748   p->defaultPrefix.name = NULL;
6749   p->defaultPrefix.binding = NULL;               6749   p->defaultPrefix.binding = NULL;
6750                                                  6750 
6751   p->in_eldecl = XML_FALSE;                      6751   p->in_eldecl = XML_FALSE;
6752                                                  6752 
6753   ms->free_fcn(p->scaffIndex);                   6753   ms->free_fcn(p->scaffIndex);
6754   p->scaffIndex = NULL;                          6754   p->scaffIndex = NULL;
6755   ms->free_fcn(p->scaffold);                     6755   ms->free_fcn(p->scaffold);
6756   p->scaffold = NULL;                            6756   p->scaffold = NULL;
6757                                                  6757 
6758   p->scaffLevel = 0;                             6758   p->scaffLevel = 0;
6759   p->scaffSize = 0;                              6759   p->scaffSize = 0;
6760   p->scaffCount = 0;                             6760   p->scaffCount = 0;
6761   p->contentStringLen = 0;                       6761   p->contentStringLen = 0;
6762                                                  6762 
6763   p->keepProcessing = XML_TRUE;                  6763   p->keepProcessing = XML_TRUE;
6764   p->hasParamEntityRefs = XML_FALSE;             6764   p->hasParamEntityRefs = XML_FALSE;
6765   p->standalone = XML_FALSE;                     6765   p->standalone = XML_FALSE;
6766 }                                                6766 }
6767                                                  6767 
6768 static void                                      6768 static void
6769 dtdDestroy(DTD *p, XML_Bool isDocEntity, cons    6769 dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms) {
6770   HASH_TABLE_ITER iter;                          6770   HASH_TABLE_ITER iter;
6771   hashTableIterInit(&iter, &(p->elementTypes)    6771   hashTableIterInit(&iter, &(p->elementTypes));
6772   for (;;) {                                     6772   for (;;) {
6773     ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTab    6773     ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
6774     if (! e)                                     6774     if (! e)
6775       break;                                     6775       break;
6776     if (e->allocDefaultAtts != 0)                6776     if (e->allocDefaultAtts != 0)
6777       ms->free_fcn(e->defaultAtts);              6777       ms->free_fcn(e->defaultAtts);
6778   }                                              6778   }
6779   hashTableDestroy(&(p->generalEntities));       6779   hashTableDestroy(&(p->generalEntities));
6780 #ifdef XML_DTD                                   6780 #ifdef XML_DTD
6781   hashTableDestroy(&(p->paramEntities));         6781   hashTableDestroy(&(p->paramEntities));
6782 #endif /* XML_DTD */                             6782 #endif /* XML_DTD */
6783   hashTableDestroy(&(p->elementTypes));          6783   hashTableDestroy(&(p->elementTypes));
6784   hashTableDestroy(&(p->attributeIds));          6784   hashTableDestroy(&(p->attributeIds));
6785   hashTableDestroy(&(p->prefixes));              6785   hashTableDestroy(&(p->prefixes));
6786   poolDestroy(&(p->pool));                       6786   poolDestroy(&(p->pool));
6787   poolDestroy(&(p->entityValuePool));            6787   poolDestroy(&(p->entityValuePool));
6788   if (isDocEntity) {                             6788   if (isDocEntity) {
6789     ms->free_fcn(p->scaffIndex);                 6789     ms->free_fcn(p->scaffIndex);
6790     ms->free_fcn(p->scaffold);                   6790     ms->free_fcn(p->scaffold);
6791   }                                              6791   }
6792   ms->free_fcn(p);                               6792   ms->free_fcn(p);
6793 }                                                6793 }
6794                                                  6794 
6795 /* Do a deep copy of the DTD. Return 0 for ou    6795 /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
6796    The new DTD has already been initialized.     6796    The new DTD has already been initialized.
6797 */                                               6797 */
6798 static int                                       6798 static int
6799 dtdCopy(XML_Parser oldParser, DTD *newDtd, co    6799 dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
6800         const XML_Memory_Handling_Suite *ms)     6800         const XML_Memory_Handling_Suite *ms) {
6801   HASH_TABLE_ITER iter;                          6801   HASH_TABLE_ITER iter;
6802                                                  6802 
6803   /* Copy the prefix table. */                   6803   /* Copy the prefix table. */
6804                                                  6804 
6805   hashTableIterInit(&iter, &(oldDtd->prefixes    6805   hashTableIterInit(&iter, &(oldDtd->prefixes));
6806   for (;;) {                                     6806   for (;;) {
6807     const XML_Char *name;                        6807     const XML_Char *name;
6808     const PREFIX *oldP = (PREFIX *)hashTableI    6808     const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
6809     if (! oldP)                                  6809     if (! oldP)
6810       break;                                     6810       break;
6811     name = poolCopyString(&(newDtd->pool), ol    6811     name = poolCopyString(&(newDtd->pool), oldP->name);
6812     if (! name)                                  6812     if (! name)
6813       return 0;                                  6813       return 0;
6814     if (! lookup(oldParser, &(newDtd->prefixe    6814     if (! lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX)))
6815       return 0;                                  6815       return 0;
6816   }                                              6816   }
6817                                                  6817 
6818   hashTableIterInit(&iter, &(oldDtd->attribut    6818   hashTableIterInit(&iter, &(oldDtd->attributeIds));
6819                                                  6819 
6820   /* Copy the attribute id table. */             6820   /* Copy the attribute id table. */
6821                                                  6821 
6822   for (;;) {                                     6822   for (;;) {
6823     ATTRIBUTE_ID *newA;                          6823     ATTRIBUTE_ID *newA;
6824     const XML_Char *name;                        6824     const XML_Char *name;
6825     const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID     6825     const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
6826                                                  6826 
6827     if (! oldA)                                  6827     if (! oldA)
6828       break;                                     6828       break;
6829     /* Remember to allocate the scratch byte     6829     /* Remember to allocate the scratch byte before the name. */
6830     if (! poolAppendChar(&(newDtd->pool), XML    6830     if (! poolAppendChar(&(newDtd->pool), XML_T('\0')))
6831       return 0;                                  6831       return 0;
6832     name = poolCopyString(&(newDtd->pool), ol    6832     name = poolCopyString(&(newDtd->pool), oldA->name);
6833     if (! name)                                  6833     if (! name)
6834       return 0;                                  6834       return 0;
6835     ++name;                                      6835     ++name;
6836     newA = (ATTRIBUTE_ID *)lookup(oldParser,     6836     newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name,
6837                                   sizeof(ATTR    6837                                   sizeof(ATTRIBUTE_ID));
6838     if (! newA)                                  6838     if (! newA)
6839       return 0;                                  6839       return 0;
6840     newA->maybeTokenized = oldA->maybeTokeniz    6840     newA->maybeTokenized = oldA->maybeTokenized;
6841     if (oldA->prefix) {                          6841     if (oldA->prefix) {
6842       newA->xmlns = oldA->xmlns;                 6842       newA->xmlns = oldA->xmlns;
6843       if (oldA->prefix == &oldDtd->defaultPre    6843       if (oldA->prefix == &oldDtd->defaultPrefix)
6844         newA->prefix = &newDtd->defaultPrefix    6844         newA->prefix = &newDtd->defaultPrefix;
6845       else                                       6845       else
6846         newA->prefix = (PREFIX *)lookup(oldPa    6846         newA->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
6847                                         oldA-    6847                                         oldA->prefix->name, 0);
6848     }                                            6848     }
6849   }                                              6849   }
6850                                                  6850 
6851   /* Copy the element type table. */             6851   /* Copy the element type table. */
6852                                                  6852 
6853   hashTableIterInit(&iter, &(oldDtd->elementT    6853   hashTableIterInit(&iter, &(oldDtd->elementTypes));
6854                                                  6854 
6855   for (;;) {                                     6855   for (;;) {
6856     int i;                                       6856     int i;
6857     ELEMENT_TYPE *newE;                          6857     ELEMENT_TYPE *newE;
6858     const XML_Char *name;                        6858     const XML_Char *name;
6859     const ELEMENT_TYPE *oldE = (ELEMENT_TYPE     6859     const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
6860     if (! oldE)                                  6860     if (! oldE)
6861       break;                                     6861       break;
6862     name = poolCopyString(&(newDtd->pool), ol    6862     name = poolCopyString(&(newDtd->pool), oldE->name);
6863     if (! name)                                  6863     if (! name)
6864       return 0;                                  6864       return 0;
6865     newE = (ELEMENT_TYPE *)lookup(oldParser,     6865     newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name,
6866                                   sizeof(ELEM    6866                                   sizeof(ELEMENT_TYPE));
6867     if (! newE)                                  6867     if (! newE)
6868       return 0;                                  6868       return 0;
6869     if (oldE->nDefaultAtts) {                    6869     if (oldE->nDefaultAtts) {
6870       newE->defaultAtts                          6870       newE->defaultAtts
6871           = ms->malloc_fcn(oldE->nDefaultAtts    6871           = ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
6872       if (! newE->defaultAtts) {                 6872       if (! newE->defaultAtts) {
6873         return 0;                                6873         return 0;
6874       }                                          6874       }
6875     }                                            6875     }
6876     if (oldE->idAtt)                             6876     if (oldE->idAtt)
6877       newE->idAtt = (ATTRIBUTE_ID *)lookup(ol    6877       newE->idAtt = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds),
6878                                            ol    6878                                            oldE->idAtt->name, 0);
6879     newE->allocDefaultAtts = newE->nDefaultAt    6879     newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
6880     if (oldE->prefix)                            6880     if (oldE->prefix)
6881       newE->prefix = (PREFIX *)lookup(oldPars    6881       newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
6882                                       oldE->p    6882                                       oldE->prefix->name, 0);
6883     for (i = 0; i < newE->nDefaultAtts; i++)     6883     for (i = 0; i < newE->nDefaultAtts; i++) {
6884       newE->defaultAtts[i].id = (ATTRIBUTE_ID    6884       newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup(
6885           oldParser, &(newDtd->attributeIds),    6885           oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
6886       newE->defaultAtts[i].isCdata = oldE->de    6886       newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
6887       if (oldE->defaultAtts[i].value) {          6887       if (oldE->defaultAtts[i].value) {
6888         newE->defaultAtts[i].value               6888         newE->defaultAtts[i].value
6889             = poolCopyString(&(newDtd->pool),    6889             = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
6890         if (! newE->defaultAtts[i].value)        6890         if (! newE->defaultAtts[i].value)
6891           return 0;                              6891           return 0;
6892       } else                                     6892       } else
6893         newE->defaultAtts[i].value = NULL;       6893         newE->defaultAtts[i].value = NULL;
6894     }                                            6894     }
6895   }                                              6895   }
6896                                                  6896 
6897   /* Copy the entity tables. */                  6897   /* Copy the entity tables. */
6898   if (! copyEntityTable(oldParser, &(newDtd->    6898   if (! copyEntityTable(oldParser, &(newDtd->generalEntities), &(newDtd->pool),
6899                         &(oldDtd->generalEnti    6899                         &(oldDtd->generalEntities)))
6900     return 0;                                    6900     return 0;
6901                                                  6901 
6902 #ifdef XML_DTD                                   6902 #ifdef XML_DTD
6903   if (! copyEntityTable(oldParser, &(newDtd->    6903   if (! copyEntityTable(oldParser, &(newDtd->paramEntities), &(newDtd->pool),
6904                         &(oldDtd->paramEntiti    6904                         &(oldDtd->paramEntities)))
6905     return 0;                                    6905     return 0;
6906   newDtd->paramEntityRead = oldDtd->paramEnti    6906   newDtd->paramEntityRead = oldDtd->paramEntityRead;
6907 #endif /* XML_DTD */                             6907 #endif /* XML_DTD */
6908                                                  6908 
6909   newDtd->keepProcessing = oldDtd->keepProces    6909   newDtd->keepProcessing = oldDtd->keepProcessing;
6910   newDtd->hasParamEntityRefs = oldDtd->hasPar    6910   newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
6911   newDtd->standalone = oldDtd->standalone;       6911   newDtd->standalone = oldDtd->standalone;
6912                                                  6912 
6913   /* Don't want deep copying for scaffolding     6913   /* Don't want deep copying for scaffolding */
6914   newDtd->in_eldecl = oldDtd->in_eldecl;         6914   newDtd->in_eldecl = oldDtd->in_eldecl;
6915   newDtd->scaffold = oldDtd->scaffold;           6915   newDtd->scaffold = oldDtd->scaffold;
6916   newDtd->contentStringLen = oldDtd->contentS    6916   newDtd->contentStringLen = oldDtd->contentStringLen;
6917   newDtd->scaffSize = oldDtd->scaffSize;         6917   newDtd->scaffSize = oldDtd->scaffSize;
6918   newDtd->scaffLevel = oldDtd->scaffLevel;       6918   newDtd->scaffLevel = oldDtd->scaffLevel;
6919   newDtd->scaffIndex = oldDtd->scaffIndex;       6919   newDtd->scaffIndex = oldDtd->scaffIndex;
6920                                                  6920 
6921   return 1;                                      6921   return 1;
6922 } /* End dtdCopy */                              6922 } /* End dtdCopy */
6923                                                  6923 
6924 static int                                       6924 static int
6925 copyEntityTable(XML_Parser oldParser, HASH_TA    6925 copyEntityTable(XML_Parser oldParser, HASH_TABLE *newTable,
6926                 STRING_POOL *newPool, const H    6926                 STRING_POOL *newPool, const HASH_TABLE *oldTable) {
6927   HASH_TABLE_ITER iter;                          6927   HASH_TABLE_ITER iter;
6928   const XML_Char *cachedOldBase = NULL;          6928   const XML_Char *cachedOldBase = NULL;
6929   const XML_Char *cachedNewBase = NULL;          6929   const XML_Char *cachedNewBase = NULL;
6930                                                  6930 
6931   hashTableIterInit(&iter, oldTable);            6931   hashTableIterInit(&iter, oldTable);
6932                                                  6932 
6933   for (;;) {                                     6933   for (;;) {
6934     ENTITY *newE;                                6934     ENTITY *newE;
6935     const XML_Char *name;                        6935     const XML_Char *name;
6936     const ENTITY *oldE = (ENTITY *)hashTableI    6936     const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
6937     if (! oldE)                                  6937     if (! oldE)
6938       break;                                     6938       break;
6939     name = poolCopyString(newPool, oldE->name    6939     name = poolCopyString(newPool, oldE->name);
6940     if (! name)                                  6940     if (! name)
6941       return 0;                                  6941       return 0;
6942     newE = (ENTITY *)lookup(oldParser, newTab    6942     newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY));
6943     if (! newE)                                  6943     if (! newE)
6944       return 0;                                  6944       return 0;
6945     if (oldE->systemId) {                        6945     if (oldE->systemId) {
6946       const XML_Char *tem = poolCopyString(ne    6946       const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
6947       if (! tem)                                 6947       if (! tem)
6948         return 0;                                6948         return 0;
6949       newE->systemId = tem;                      6949       newE->systemId = tem;
6950       if (oldE->base) {                          6950       if (oldE->base) {
6951         if (oldE->base == cachedOldBase)         6951         if (oldE->base == cachedOldBase)
6952           newE->base = cachedNewBase;            6952           newE->base = cachedNewBase;
6953         else {                                   6953         else {
6954           cachedOldBase = oldE->base;            6954           cachedOldBase = oldE->base;
6955           tem = poolCopyString(newPool, cache    6955           tem = poolCopyString(newPool, cachedOldBase);
6956           if (! tem)                             6956           if (! tem)
6957             return 0;                            6957             return 0;
6958           cachedNewBase = newE->base = tem;      6958           cachedNewBase = newE->base = tem;
6959         }                                        6959         }
6960       }                                          6960       }
6961       if (oldE->publicId) {                      6961       if (oldE->publicId) {
6962         tem = poolCopyString(newPool, oldE->p    6962         tem = poolCopyString(newPool, oldE->publicId);
6963         if (! tem)                               6963         if (! tem)
6964           return 0;                              6964           return 0;
6965         newE->publicId = tem;                    6965         newE->publicId = tem;
6966       }                                          6966       }
6967     } else {                                     6967     } else {
6968       const XML_Char *tem                        6968       const XML_Char *tem
6969           = poolCopyStringN(newPool, oldE->te    6969           = poolCopyStringN(newPool, oldE->textPtr, oldE->textLen);
6970       if (! tem)                                 6970       if (! tem)
6971         return 0;                                6971         return 0;
6972       newE->textPtr = tem;                       6972       newE->textPtr = tem;
6973       newE->textLen = oldE->textLen;             6973       newE->textLen = oldE->textLen;
6974     }                                            6974     }
6975     if (oldE->notation) {                        6975     if (oldE->notation) {
6976       const XML_Char *tem = poolCopyString(ne    6976       const XML_Char *tem = poolCopyString(newPool, oldE->notation);
6977       if (! tem)                                 6977       if (! tem)
6978         return 0;                                6978         return 0;
6979       newE->notation = tem;                      6979       newE->notation = tem;
6980     }                                            6980     }
6981     newE->is_param = oldE->is_param;             6981     newE->is_param = oldE->is_param;
6982     newE->is_internal = oldE->is_internal;       6982     newE->is_internal = oldE->is_internal;
6983   }                                              6983   }
6984   return 1;                                      6984   return 1;
6985 }                                                6985 }
6986                                                  6986 
6987 #define INIT_POWER 6                             6987 #define INIT_POWER 6
6988                                                  6988 
6989 static XML_Bool FASTCALL                         6989 static XML_Bool FASTCALL
6990 keyeq(KEY s1, KEY s2) {                          6990 keyeq(KEY s1, KEY s2) {
6991   for (; *s1 == *s2; s1++, s2++)                 6991   for (; *s1 == *s2; s1++, s2++)
6992     if (*s1 == 0)                                6992     if (*s1 == 0)
6993       return XML_TRUE;                           6993       return XML_TRUE;
6994   return XML_FALSE;                              6994   return XML_FALSE;
6995 }                                                6995 }
6996                                                  6996 
6997 static size_t                                    6997 static size_t
6998 keylen(KEY s) {                                  6998 keylen(KEY s) {
6999   size_t len = 0;                                6999   size_t len = 0;
7000   for (; *s; s++, len++)                         7000   for (; *s; s++, len++)
7001     ;                                            7001     ;
7002   return len;                                    7002   return len;
7003 }                                                7003 }
7004                                                  7004 
7005 static void                                      7005 static void
7006 copy_salt_to_sipkey(XML_Parser parser, struct    7006 copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key) {
7007   key->k[0] = 0;                                 7007   key->k[0] = 0;
7008   key->k[1] = get_hash_secret_salt(parser);      7008   key->k[1] = get_hash_secret_salt(parser);
7009 }                                                7009 }
7010                                                  7010 
7011 static unsigned long FASTCALL                    7011 static unsigned long FASTCALL
7012 hash(XML_Parser parser, KEY s) {                 7012 hash(XML_Parser parser, KEY s) {
7013   struct siphash state;                          7013   struct siphash state;
7014   struct sipkey key;                             7014   struct sipkey key;
7015   (void)sip24_valid;                             7015   (void)sip24_valid;
7016   copy_salt_to_sipkey(parser, &key);             7016   copy_salt_to_sipkey(parser, &key);
7017   sip24_init(&state, &key);                      7017   sip24_init(&state, &key);
7018   sip24_update(&state, s, keylen(s) * sizeof(    7018   sip24_update(&state, s, keylen(s) * sizeof(XML_Char));
7019   return (unsigned long)sip24_final(&state);     7019   return (unsigned long)sip24_final(&state);
7020 }                                                7020 }
7021                                                  7021 
7022 static NAMED *                                   7022 static NAMED *
7023 lookup(XML_Parser parser, HASH_TABLE *table,     7023 lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) {
7024   size_t i;                                      7024   size_t i;
7025   if (table->size == 0) {                        7025   if (table->size == 0) {
7026     size_t tsize;                                7026     size_t tsize;
7027     if (! createSize)                            7027     if (! createSize)
7028       return NULL;                               7028       return NULL;
7029     table->power = INIT_POWER;                   7029     table->power = INIT_POWER;
7030     /* table->size is a power of 2 */            7030     /* table->size is a power of 2 */
7031     table->size = (size_t)1 << INIT_POWER;       7031     table->size = (size_t)1 << INIT_POWER;
7032     tsize = table->size * sizeof(NAMED *);       7032     tsize = table->size * sizeof(NAMED *);
7033     table->v = table->mem->malloc_fcn(tsize);    7033     table->v = table->mem->malloc_fcn(tsize);
7034     if (! table->v) {                            7034     if (! table->v) {
7035       table->size = 0;                           7035       table->size = 0;
7036       return NULL;                               7036       return NULL;
7037     }                                            7037     }
7038     memset(table->v, 0, tsize);                  7038     memset(table->v, 0, tsize);
7039     i = hash(parser, name) & ((unsigned long)    7039     i = hash(parser, name) & ((unsigned long)table->size - 1);
7040   } else {                                       7040   } else {
7041     unsigned long h = hash(parser, name);        7041     unsigned long h = hash(parser, name);
7042     unsigned long mask = (unsigned long)table    7042     unsigned long mask = (unsigned long)table->size - 1;
7043     unsigned char step = 0;                      7043     unsigned char step = 0;
7044     i = h & mask;                                7044     i = h & mask;
7045     while (table->v[i]) {                        7045     while (table->v[i]) {
7046       if (keyeq(name, table->v[i]->name))        7046       if (keyeq(name, table->v[i]->name))
7047         return table->v[i];                      7047         return table->v[i];
7048       if (! step)                                7048       if (! step)
7049         step = PROBE_STEP(h, mask, table->pow    7049         step = PROBE_STEP(h, mask, table->power);
7050       i < step ? (i += table->size - step) :     7050       i < step ? (i += table->size - step) : (i -= step);
7051     }                                            7051     }
7052     if (! createSize)                            7052     if (! createSize)
7053       return NULL;                               7053       return NULL;
7054                                                  7054 
7055     /* check for overflow (table is half full    7055     /* check for overflow (table is half full) */
7056     if (table->used >> (table->power - 1)) {     7056     if (table->used >> (table->power - 1)) {
7057       unsigned char newPower = table->power +    7057       unsigned char newPower = table->power + 1;
7058                                                  7058 
7059       /* Detect and prevent invalid shift */     7059       /* Detect and prevent invalid shift */
7060       if (newPower >= sizeof(unsigned long) *    7060       if (newPower >= sizeof(unsigned long) * 8 /* bits per byte */) {
7061         return NULL;                             7061         return NULL;
7062       }                                          7062       }
7063                                                  7063 
7064       size_t newSize = (size_t)1 << newPower;    7064       size_t newSize = (size_t)1 << newPower;
7065       unsigned long newMask = (unsigned long)    7065       unsigned long newMask = (unsigned long)newSize - 1;
7066                                                  7066 
7067       /* Detect and prevent integer overflow     7067       /* Detect and prevent integer overflow */
7068       if (newSize > (size_t)(-1) / sizeof(NAM    7068       if (newSize > (size_t)(-1) / sizeof(NAMED *)) {
7069         return NULL;                             7069         return NULL;
7070       }                                          7070       }
7071                                                  7071 
7072       size_t tsize = newSize * sizeof(NAMED *    7072       size_t tsize = newSize * sizeof(NAMED *);
7073       NAMED **newV = table->mem->malloc_fcn(t    7073       NAMED **newV = table->mem->malloc_fcn(tsize);
7074       if (! newV)                                7074       if (! newV)
7075         return NULL;                             7075         return NULL;
7076       memset(newV, 0, tsize);                    7076       memset(newV, 0, tsize);
7077       for (i = 0; i < table->size; i++)          7077       for (i = 0; i < table->size; i++)
7078         if (table->v[i]) {                       7078         if (table->v[i]) {
7079           unsigned long newHash = hash(parser    7079           unsigned long newHash = hash(parser, table->v[i]->name);
7080           size_t j = newHash & newMask;          7080           size_t j = newHash & newMask;
7081           step = 0;                              7081           step = 0;
7082           while (newV[j]) {                      7082           while (newV[j]) {
7083             if (! step)                          7083             if (! step)
7084               step = PROBE_STEP(newHash, newM    7084               step = PROBE_STEP(newHash, newMask, newPower);
7085             j < step ? (j += newSize - step)     7085             j < step ? (j += newSize - step) : (j -= step);
7086           }                                      7086           }
7087           newV[j] = table->v[i];                 7087           newV[j] = table->v[i];
7088         }                                        7088         }
7089       table->mem->free_fcn(table->v);            7089       table->mem->free_fcn(table->v);
7090       table->v = newV;                           7090       table->v = newV;
7091       table->power = newPower;                   7091       table->power = newPower;
7092       table->size = newSize;                     7092       table->size = newSize;
7093       i = h & newMask;                           7093       i = h & newMask;
7094       step = 0;                                  7094       step = 0;
7095       while (table->v[i]) {                      7095       while (table->v[i]) {
7096         if (! step)                              7096         if (! step)
7097           step = PROBE_STEP(h, newMask, newPo    7097           step = PROBE_STEP(h, newMask, newPower);
7098         i < step ? (i += newSize - step) : (i    7098         i < step ? (i += newSize - step) : (i -= step);
7099       }                                          7099       }
7100     }                                            7100     }
7101   }                                              7101   }
7102   table->v[i] = table->mem->malloc_fcn(create    7102   table->v[i] = table->mem->malloc_fcn(createSize);
7103   if (! table->v[i])                             7103   if (! table->v[i])
7104     return NULL;                                 7104     return NULL;
7105   memset(table->v[i], 0, createSize);            7105   memset(table->v[i], 0, createSize);
7106   table->v[i]->name = name;                      7106   table->v[i]->name = name;
7107   (table->used)++;                               7107   (table->used)++;
7108   return table->v[i];                            7108   return table->v[i];
7109 }                                                7109 }
7110                                                  7110 
7111 static void FASTCALL                             7111 static void FASTCALL
7112 hashTableClear(HASH_TABLE *table) {              7112 hashTableClear(HASH_TABLE *table) {
7113   size_t i;                                      7113   size_t i;
7114   for (i = 0; i < table->size; i++) {            7114   for (i = 0; i < table->size; i++) {
7115     table->mem->free_fcn(table->v[i]);           7115     table->mem->free_fcn(table->v[i]);
7116     table->v[i] = NULL;                          7116     table->v[i] = NULL;
7117   }                                              7117   }
7118   table->used = 0;                               7118   table->used = 0;
7119 }                                                7119 }
7120                                                  7120 
7121 static void FASTCALL                             7121 static void FASTCALL
7122 hashTableDestroy(HASH_TABLE *table) {            7122 hashTableDestroy(HASH_TABLE *table) {
7123   size_t i;                                      7123   size_t i;
7124   for (i = 0; i < table->size; i++)              7124   for (i = 0; i < table->size; i++)
7125     table->mem->free_fcn(table->v[i]);           7125     table->mem->free_fcn(table->v[i]);
7126   table->mem->free_fcn(table->v);                7126   table->mem->free_fcn(table->v);
7127 }                                                7127 }
7128                                                  7128 
7129 static void FASTCALL                             7129 static void FASTCALL
7130 hashTableInit(HASH_TABLE *p, const XML_Memory    7130 hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms) {
7131   p->power = 0;                                  7131   p->power = 0;
7132   p->size = 0;                                   7132   p->size = 0;
7133   p->used = 0;                                   7133   p->used = 0;
7134   p->v = NULL;                                   7134   p->v = NULL;
7135   p->mem = ms;                                   7135   p->mem = ms;
7136 }                                                7136 }
7137                                                  7137 
7138 static void FASTCALL                             7138 static void FASTCALL
7139 hashTableIterInit(HASH_TABLE_ITER *iter, cons    7139 hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table) {
7140   iter->p = table->v;                            7140   iter->p = table->v;
7141   iter->end = iter->p ? iter->p + table->size    7141   iter->end = iter->p ? iter->p + table->size : NULL;
7142 }                                                7142 }
7143                                                  7143 
7144 static NAMED *FASTCALL                           7144 static NAMED *FASTCALL
7145 hashTableIterNext(HASH_TABLE_ITER *iter) {       7145 hashTableIterNext(HASH_TABLE_ITER *iter) {
7146   while (iter->p != iter->end) {                 7146   while (iter->p != iter->end) {
7147     NAMED *tem = *(iter->p)++;                   7147     NAMED *tem = *(iter->p)++;
7148     if (tem)                                     7148     if (tem)
7149       return tem;                                7149       return tem;
7150   }                                              7150   }
7151   return NULL;                                   7151   return NULL;
7152 }                                                7152 }
7153                                                  7153 
7154 static void FASTCALL                             7154 static void FASTCALL
7155 poolInit(STRING_POOL *pool, const XML_Memory_    7155 poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms) {
7156   pool->blocks = NULL;                           7156   pool->blocks = NULL;
7157   pool->freeBlocks = NULL;                       7157   pool->freeBlocks = NULL;
7158   pool->start = NULL;                            7158   pool->start = NULL;
7159   pool->ptr = NULL;                              7159   pool->ptr = NULL;
7160   pool->end = NULL;                              7160   pool->end = NULL;
7161   pool->mem = ms;                                7161   pool->mem = ms;
7162 }                                                7162 }
7163                                                  7163 
7164 static void FASTCALL                             7164 static void FASTCALL
7165 poolClear(STRING_POOL *pool) {                   7165 poolClear(STRING_POOL *pool) {
7166   if (! pool->freeBlocks)                        7166   if (! pool->freeBlocks)
7167     pool->freeBlocks = pool->blocks;             7167     pool->freeBlocks = pool->blocks;
7168   else {                                         7168   else {
7169     BLOCK *p = pool->blocks;                     7169     BLOCK *p = pool->blocks;
7170     while (p) {                                  7170     while (p) {
7171       BLOCK *tem = p->next;                      7171       BLOCK *tem = p->next;
7172       p->next = pool->freeBlocks;                7172       p->next = pool->freeBlocks;
7173       pool->freeBlocks = p;                      7173       pool->freeBlocks = p;
7174       p = tem;                                   7174       p = tem;
7175     }                                            7175     }
7176   }                                              7176   }
7177   pool->blocks = NULL;                           7177   pool->blocks = NULL;
7178   pool->start = NULL;                            7178   pool->start = NULL;
7179   pool->ptr = NULL;                              7179   pool->ptr = NULL;
7180   pool->end = NULL;                              7180   pool->end = NULL;
7181 }                                                7181 }
7182                                                  7182 
7183 static void FASTCALL                             7183 static void FASTCALL
7184 poolDestroy(STRING_POOL *pool) {                 7184 poolDestroy(STRING_POOL *pool) {
7185   BLOCK *p = pool->blocks;                       7185   BLOCK *p = pool->blocks;
7186   while (p) {                                    7186   while (p) {
7187     BLOCK *tem = p->next;                        7187     BLOCK *tem = p->next;
7188     pool->mem->free_fcn(p);                      7188     pool->mem->free_fcn(p);
7189     p = tem;                                     7189     p = tem;
7190   }                                              7190   }
7191   p = pool->freeBlocks;                          7191   p = pool->freeBlocks;
7192   while (p) {                                    7192   while (p) {
7193     BLOCK *tem = p->next;                        7193     BLOCK *tem = p->next;
7194     pool->mem->free_fcn(p);                      7194     pool->mem->free_fcn(p);
7195     p = tem;                                     7195     p = tem;
7196   }                                              7196   }
7197 }                                                7197 }
7198                                                  7198 
7199 static XML_Char *                                7199 static XML_Char *
7200 poolAppend(STRING_POOL *pool, const ENCODING     7200 poolAppend(STRING_POOL *pool, const ENCODING *enc, const char *ptr,
7201            const char *end) {                    7201            const char *end) {
7202   if (! pool->ptr && ! poolGrow(pool))           7202   if (! pool->ptr && ! poolGrow(pool))
7203     return NULL;                                 7203     return NULL;
7204   for (;;) {                                     7204   for (;;) {
7205     const enum XML_Convert_Result convert_res    7205     const enum XML_Convert_Result convert_res = XmlConvert(
7206         enc, &ptr, end, (ICHAR **)&(pool->ptr    7206         enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
7207     if ((convert_res == XML_CONVERT_COMPLETED    7207     if ((convert_res == XML_CONVERT_COMPLETED)
7208         || (convert_res == XML_CONVERT_INPUT_    7208         || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
7209       break;                                     7209       break;
7210     if (! poolGrow(pool))                        7210     if (! poolGrow(pool))
7211       return NULL;                               7211       return NULL;
7212   }                                              7212   }
7213   return pool->start;                            7213   return pool->start;
7214 }                                                7214 }
7215                                                  7215 
7216 static const XML_Char *FASTCALL                  7216 static const XML_Char *FASTCALL
7217 poolCopyString(STRING_POOL *pool, const XML_C    7217 poolCopyString(STRING_POOL *pool, const XML_Char *s) {
7218   do {                                           7218   do {
7219     if (! poolAppendChar(pool, *s))              7219     if (! poolAppendChar(pool, *s))
7220       return NULL;                               7220       return NULL;
7221   } while (*s++);                                7221   } while (*s++);
7222   s = pool->start;                               7222   s = pool->start;
7223   poolFinish(pool);                              7223   poolFinish(pool);
7224   return s;                                      7224   return s;
7225 }                                                7225 }
7226                                                  7226 
7227 static const XML_Char *                          7227 static const XML_Char *
7228 poolCopyStringN(STRING_POOL *pool, const XML_    7228 poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) {
7229   if (! pool->ptr && ! poolGrow(pool)) {         7229   if (! pool->ptr && ! poolGrow(pool)) {
7230     /* The following line is unreachable give    7230     /* The following line is unreachable given the current usage of
7231      * poolCopyStringN().  Currently it is ca    7231      * poolCopyStringN().  Currently it is called from exactly one
7232      * place to copy the text of a simple gen    7232      * place to copy the text of a simple general entity.  By that
7233      * point, the name of the entity is alrea    7233      * point, the name of the entity is already stored in the pool, so
7234      * pool->ptr cannot be NULL.                 7234      * pool->ptr cannot be NULL.
7235      *                                           7235      *
7236      * If poolCopyStringN() is used elsewhere    7236      * If poolCopyStringN() is used elsewhere as it well might be,
7237      * this line may well become executable a    7237      * this line may well become executable again.  Regardless, this
7238      * sort of check shouldn't be removed lig    7238      * sort of check shouldn't be removed lightly, so we just exclude
7239      * it from the coverage statistics.          7239      * it from the coverage statistics.
7240      */                                          7240      */
7241     return NULL; /* LCOV_EXCL_LINE */            7241     return NULL; /* LCOV_EXCL_LINE */
7242   }                                              7242   }
7243   for (; n > 0; --n, s++) {                      7243   for (; n > 0; --n, s++) {
7244     if (! poolAppendChar(pool, *s))              7244     if (! poolAppendChar(pool, *s))
7245       return NULL;                               7245       return NULL;
7246   }                                              7246   }
7247   s = pool->start;                               7247   s = pool->start;
7248   poolFinish(pool);                              7248   poolFinish(pool);
7249   return s;                                      7249   return s;
7250 }                                                7250 }
7251                                                  7251 
7252 static const XML_Char *FASTCALL                  7252 static const XML_Char *FASTCALL
7253 poolAppendString(STRING_POOL *pool, const XML    7253 poolAppendString(STRING_POOL *pool, const XML_Char *s) {
7254   while (*s) {                                   7254   while (*s) {
7255     if (! poolAppendChar(pool, *s))              7255     if (! poolAppendChar(pool, *s))
7256       return NULL;                               7256       return NULL;
7257     s++;                                         7257     s++;
7258   }                                              7258   }
7259   return pool->start;                            7259   return pool->start;
7260 }                                                7260 }
7261                                                  7261 
7262 static XML_Char *                                7262 static XML_Char *
7263 poolStoreString(STRING_POOL *pool, const ENCO    7263 poolStoreString(STRING_POOL *pool, const ENCODING *enc, const char *ptr,
7264                 const char *end) {               7264                 const char *end) {
7265   if (! poolAppend(pool, enc, ptr, end))         7265   if (! poolAppend(pool, enc, ptr, end))
7266     return NULL;                                 7266     return NULL;
7267   if (pool->ptr == pool->end && ! poolGrow(po    7267   if (pool->ptr == pool->end && ! poolGrow(pool))
7268     return NULL;                                 7268     return NULL;
7269   *(pool->ptr)++ = 0;                            7269   *(pool->ptr)++ = 0;
7270   return pool->start;                            7270   return pool->start;
7271 }                                                7271 }
7272                                                  7272 
7273 static size_t                                    7273 static size_t
7274 poolBytesToAllocateFor(int blockSize) {          7274 poolBytesToAllocateFor(int blockSize) {
7275   /* Unprotected math would be:                  7275   /* Unprotected math would be:
7276   ** return offsetof(BLOCK, s) + blockSize *     7276   ** return offsetof(BLOCK, s) + blockSize * sizeof(XML_Char);
7277   **                                             7277   **
7278   ** Detect overflow, avoiding _signed_ overf    7278   ** Detect overflow, avoiding _signed_ overflow undefined behavior
7279   ** For a + b * c we check b * c in isolatio    7279   ** For a + b * c we check b * c in isolation first, so that addition of a
7280   ** on top has no chance of making us accept    7280   ** on top has no chance of making us accept a small non-negative number
7281   */                                             7281   */
7282   const size_t stretch = sizeof(XML_Char); /*    7282   const size_t stretch = sizeof(XML_Char); /* can be 4 bytes */
7283                                                  7283 
7284   if (blockSize <= 0)                            7284   if (blockSize <= 0)
7285     return 0;                                    7285     return 0;
7286                                                  7286 
7287   if (blockSize > (int)(INT_MAX / stretch))      7287   if (blockSize > (int)(INT_MAX / stretch))
7288     return 0;                                    7288     return 0;
7289                                                  7289 
7290   {                                              7290   {
7291     const int stretchedBlockSize = blockSize     7291     const int stretchedBlockSize = blockSize * (int)stretch;
7292     const int bytesToAllocate                    7292     const int bytesToAllocate
7293         = (int)(offsetof(BLOCK, s) + (unsigne    7293         = (int)(offsetof(BLOCK, s) + (unsigned)stretchedBlockSize);
7294     if (bytesToAllocate < 0)                     7294     if (bytesToAllocate < 0)
7295       return 0;                                  7295       return 0;
7296                                                  7296 
7297     return (size_t)bytesToAllocate;              7297     return (size_t)bytesToAllocate;
7298   }                                              7298   }
7299 }                                                7299 }
7300                                                  7300 
7301 static XML_Bool FASTCALL                         7301 static XML_Bool FASTCALL
7302 poolGrow(STRING_POOL *pool) {                    7302 poolGrow(STRING_POOL *pool) {
7303   if (pool->freeBlocks) {                        7303   if (pool->freeBlocks) {
7304     if (pool->start == 0) {                      7304     if (pool->start == 0) {
7305       pool->blocks = pool->freeBlocks;           7305       pool->blocks = pool->freeBlocks;
7306       pool->freeBlocks = pool->freeBlocks->ne    7306       pool->freeBlocks = pool->freeBlocks->next;
7307       pool->blocks->next = NULL;                 7307       pool->blocks->next = NULL;
7308       pool->start = pool->blocks->s;             7308       pool->start = pool->blocks->s;
7309       pool->end = pool->start + pool->blocks-    7309       pool->end = pool->start + pool->blocks->size;
7310       pool->ptr = pool->start;                   7310       pool->ptr = pool->start;
7311       return XML_TRUE;                           7311       return XML_TRUE;
7312     }                                            7312     }
7313     if (pool->end - pool->start < pool->freeB    7313     if (pool->end - pool->start < pool->freeBlocks->size) {
7314       BLOCK *tem = pool->freeBlocks->next;       7314       BLOCK *tem = pool->freeBlocks->next;
7315       pool->freeBlocks->next = pool->blocks;     7315       pool->freeBlocks->next = pool->blocks;
7316       pool->blocks = pool->freeBlocks;           7316       pool->blocks = pool->freeBlocks;
7317       pool->freeBlocks = tem;                    7317       pool->freeBlocks = tem;
7318       memcpy(pool->blocks->s, pool->start,       7318       memcpy(pool->blocks->s, pool->start,
7319              (pool->end - pool->start) * size    7319              (pool->end - pool->start) * sizeof(XML_Char));
7320       pool->ptr = pool->blocks->s + (pool->pt    7320       pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
7321       pool->start = pool->blocks->s;             7321       pool->start = pool->blocks->s;
7322       pool->end = pool->start + pool->blocks-    7322       pool->end = pool->start + pool->blocks->size;
7323       return XML_TRUE;                           7323       return XML_TRUE;
7324     }                                            7324     }
7325   }                                              7325   }
7326   if (pool->blocks && pool->start == pool->bl    7326   if (pool->blocks && pool->start == pool->blocks->s) {
7327     BLOCK *temp;                                 7327     BLOCK *temp;
7328     int blockSize = (int)((unsigned)(pool->en    7328     int blockSize = (int)((unsigned)(pool->end - pool->start) * 2U);
7329     size_t bytesToAllocate;                      7329     size_t bytesToAllocate;
7330                                                  7330 
7331     /* NOTE: Needs to be calculated prior to     7331     /* NOTE: Needs to be calculated prior to calling `realloc`
7332              to avoid dangling pointers: */      7332              to avoid dangling pointers: */
7333     const ptrdiff_t offsetInsideBlock = pool-    7333     const ptrdiff_t offsetInsideBlock = pool->ptr - pool->start;
7334                                                  7334 
7335     if (blockSize < 0) {                         7335     if (blockSize < 0) {
7336       /* This condition traps a situation whe    7336       /* This condition traps a situation where either more than
7337        * INT_MAX/2 bytes have already been al    7337        * INT_MAX/2 bytes have already been allocated.  This isn't
7338        * readily testable, since it is unlike    7338        * readily testable, since it is unlikely that an average
7339        * machine will have that much memory,     7339        * machine will have that much memory, so we exclude it from the
7340        * coverage statistics.                    7340        * coverage statistics.
7341        */                                        7341        */
7342       return XML_FALSE; /* LCOV_EXCL_LINE */     7342       return XML_FALSE; /* LCOV_EXCL_LINE */
7343     }                                            7343     }
7344                                                  7344 
7345     bytesToAllocate = poolBytesToAllocateFor(    7345     bytesToAllocate = poolBytesToAllocateFor(blockSize);
7346     if (bytesToAllocate == 0)                    7346     if (bytesToAllocate == 0)
7347       return XML_FALSE;                          7347       return XML_FALSE;
7348                                                  7348 
7349     temp = (BLOCK *)pool->mem->realloc_fcn(po    7349     temp = (BLOCK *)pool->mem->realloc_fcn(pool->blocks,
7350                                            (u    7350                                            (unsigned)bytesToAllocate);
7351     if (temp == NULL)                            7351     if (temp == NULL)
7352       return XML_FALSE;                          7352       return XML_FALSE;
7353     pool->blocks = temp;                         7353     pool->blocks = temp;
7354     pool->blocks->size = blockSize;              7354     pool->blocks->size = blockSize;
7355     pool->ptr = pool->blocks->s + offsetInsid    7355     pool->ptr = pool->blocks->s + offsetInsideBlock;
7356     pool->start = pool->blocks->s;               7356     pool->start = pool->blocks->s;
7357     pool->end = pool->start + blockSize;         7357     pool->end = pool->start + blockSize;
7358   } else {                                       7358   } else {
7359     BLOCK *tem;                                  7359     BLOCK *tem;
7360     int blockSize = (int)(pool->end - pool->s    7360     int blockSize = (int)(pool->end - pool->start);
7361     size_t bytesToAllocate;                      7361     size_t bytesToAllocate;
7362                                                  7362 
7363     if (blockSize < 0) {                         7363     if (blockSize < 0) {
7364       /* This condition traps a situation whe    7364       /* This condition traps a situation where either more than
7365        * INT_MAX bytes have already been allo    7365        * INT_MAX bytes have already been allocated (which is prevented
7366        * by various pieces of program logic,     7366        * by various pieces of program logic, not least this one, never
7367        * mind the unlikelihood of actually ha    7367        * mind the unlikelihood of actually having that much memory) or
7368        * the pool control fields have been co    7368        * the pool control fields have been corrupted (which could
7369        * conceivably happen in an extremely b    7369        * conceivably happen in an extremely buggy user handler
7370        * function).  Either way it isn't read    7370        * function).  Either way it isn't readily testable, so we
7371        * exclude it from the coverage statist    7371        * exclude it from the coverage statistics.
7372        */                                        7372        */
7373       return XML_FALSE; /* LCOV_EXCL_LINE */     7373       return XML_FALSE; /* LCOV_EXCL_LINE */
7374     }                                            7374     }
7375                                                  7375 
7376     if (blockSize < INIT_BLOCK_SIZE)             7376     if (blockSize < INIT_BLOCK_SIZE)
7377       blockSize = INIT_BLOCK_SIZE;               7377       blockSize = INIT_BLOCK_SIZE;
7378     else {                                       7378     else {
7379       /* Detect overflow, avoiding _signed_ o    7379       /* Detect overflow, avoiding _signed_ overflow undefined behavior */
7380       if ((int)((unsigned)blockSize * 2U) < 0    7380       if ((int)((unsigned)blockSize * 2U) < 0) {
7381         return XML_FALSE;                        7381         return XML_FALSE;
7382       }                                          7382       }
7383       blockSize *= 2;                            7383       blockSize *= 2;
7384     }                                            7384     }
7385                                                  7385 
7386     bytesToAllocate = poolBytesToAllocateFor(    7386     bytesToAllocate = poolBytesToAllocateFor(blockSize);
7387     if (bytesToAllocate == 0)                    7387     if (bytesToAllocate == 0)
7388       return XML_FALSE;                          7388       return XML_FALSE;
7389                                                  7389 
7390     tem = pool->mem->malloc_fcn(bytesToAlloca    7390     tem = pool->mem->malloc_fcn(bytesToAllocate);
7391     if (! tem)                                   7391     if (! tem)
7392       return XML_FALSE;                          7392       return XML_FALSE;
7393     tem->size = blockSize;                       7393     tem->size = blockSize;
7394     tem->next = pool->blocks;                    7394     tem->next = pool->blocks;
7395     pool->blocks = tem;                          7395     pool->blocks = tem;
7396     if (pool->ptr != pool->start)                7396     if (pool->ptr != pool->start)
7397       memcpy(tem->s, pool->start, (pool->ptr     7397       memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char));
7398     pool->ptr = tem->s + (pool->ptr - pool->s    7398     pool->ptr = tem->s + (pool->ptr - pool->start);
7399     pool->start = tem->s;                        7399     pool->start = tem->s;
7400     pool->end = tem->s + blockSize;              7400     pool->end = tem->s + blockSize;
7401   }                                              7401   }
7402   return XML_TRUE;                               7402   return XML_TRUE;
7403 }                                                7403 }
7404                                                  7404 
7405 static int FASTCALL                              7405 static int FASTCALL
7406 nextScaffoldPart(XML_Parser parser) {            7406 nextScaffoldPart(XML_Parser parser) {
7407   DTD *const dtd = parser->m_dtd; /* save one    7407   DTD *const dtd = parser->m_dtd; /* save one level of indirection */
7408   CONTENT_SCAFFOLD *me;                          7408   CONTENT_SCAFFOLD *me;
7409   int next;                                      7409   int next;
7410                                                  7410 
7411   if (! dtd->scaffIndex) {                       7411   if (! dtd->scaffIndex) {
7412     dtd->scaffIndex = (int *)MALLOC(parser, p    7412     dtd->scaffIndex = (int *)MALLOC(parser, parser->m_groupSize * sizeof(int));
7413     if (! dtd->scaffIndex)                       7413     if (! dtd->scaffIndex)
7414       return -1;                                 7414       return -1;
7415     dtd->scaffIndex[0] = 0;                      7415     dtd->scaffIndex[0] = 0;
7416   }                                              7416   }
7417                                                  7417 
7418   if (dtd->scaffCount >= dtd->scaffSize) {       7418   if (dtd->scaffCount >= dtd->scaffSize) {
7419     CONTENT_SCAFFOLD *temp;                      7419     CONTENT_SCAFFOLD *temp;
7420     if (dtd->scaffold) {                         7420     if (dtd->scaffold) {
7421       /* Detect and prevent integer overflow     7421       /* Detect and prevent integer overflow */
7422       if (dtd->scaffSize > UINT_MAX / 2u) {      7422       if (dtd->scaffSize > UINT_MAX / 2u) {
7423         return -1;                               7423         return -1;
7424       }                                          7424       }
7425       /* Detect and prevent integer overflow.    7425       /* Detect and prevent integer overflow.
7426        * The preprocessor guard addresses the    7426        * The preprocessor guard addresses the "always false" warning
7427        * from -Wtype-limits on platforms wher    7427        * from -Wtype-limits on platforms where
7428        * sizeof(unsigned int) < sizeof(size_t    7428        * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
7429 #if UINT_MAX >= SIZE_MAX                         7429 #if UINT_MAX >= SIZE_MAX
7430       if (dtd->scaffSize > (size_t)(-1) / 2u     7430       if (dtd->scaffSize > (size_t)(-1) / 2u / sizeof(CONTENT_SCAFFOLD)) {
7431         return -1;                               7431         return -1;
7432       }                                          7432       }
7433 #endif                                           7433 #endif
7434                                                  7434 
7435       temp = (CONTENT_SCAFFOLD *)REALLOC(        7435       temp = (CONTENT_SCAFFOLD *)REALLOC(
7436           parser, dtd->scaffold, dtd->scaffSi    7436           parser, dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
7437       if (temp == NULL)                          7437       if (temp == NULL)
7438         return -1;                               7438         return -1;
7439       dtd->scaffSize *= 2;                       7439       dtd->scaffSize *= 2;
7440     } else {                                     7440     } else {
7441       temp = (CONTENT_SCAFFOLD *)MALLOC(parse    7441       temp = (CONTENT_SCAFFOLD *)MALLOC(parser, INIT_SCAFFOLD_ELEMENTS
7442                                                  7442                                                     * sizeof(CONTENT_SCAFFOLD));
7443       if (temp == NULL)                          7443       if (temp == NULL)
7444         return -1;                               7444         return -1;
7445       dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS    7445       dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
7446     }                                            7446     }
7447     dtd->scaffold = temp;                        7447     dtd->scaffold = temp;
7448   }                                              7448   }
7449   next = dtd->scaffCount++;                      7449   next = dtd->scaffCount++;
7450   me = &dtd->scaffold[next];                     7450   me = &dtd->scaffold[next];
7451   if (dtd->scaffLevel) {                         7451   if (dtd->scaffLevel) {
7452     CONTENT_SCAFFOLD *parent                     7452     CONTENT_SCAFFOLD *parent
7453         = &dtd->scaffold[dtd->scaffIndex[dtd-    7453         = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]];
7454     if (parent->lastchild) {                     7454     if (parent->lastchild) {
7455       dtd->scaffold[parent->lastchild].nextsi    7455       dtd->scaffold[parent->lastchild].nextsib = next;
7456     }                                            7456     }
7457     if (! parent->childcnt)                      7457     if (! parent->childcnt)
7458       parent->firstchild = next;                 7458       parent->firstchild = next;
7459     parent->lastchild = next;                    7459     parent->lastchild = next;
7460     parent->childcnt++;                          7460     parent->childcnt++;
7461   }                                              7461   }
7462   me->firstchild = me->lastchild = me->childc    7462   me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
7463   return next;                                   7463   return next;
7464 }                                                7464 }
7465                                                  7465 
7466 static XML_Content *                             7466 static XML_Content *
7467 build_model(XML_Parser parser) {                 7467 build_model(XML_Parser parser) {
7468   /* Function build_model transforms the exis    7468   /* Function build_model transforms the existing parser->m_dtd->scaffold
7469    * array of CONTENT_SCAFFOLD tree nodes int    7469    * array of CONTENT_SCAFFOLD tree nodes into a new array of
7470    * XML_Content tree nodes followed by a gap    7470    * XML_Content tree nodes followed by a gapless list of zero-terminated
7471    * strings. */                                 7471    * strings. */
7472   DTD *const dtd = parser->m_dtd; /* save one    7472   DTD *const dtd = parser->m_dtd; /* save one level of indirection */
7473   XML_Content *ret;                              7473   XML_Content *ret;
7474   XML_Char *str; /* the current string writin    7474   XML_Char *str; /* the current string writing location */
7475                                                  7475 
7476   /* Detect and prevent integer overflow.        7476   /* Detect and prevent integer overflow.
7477    * The preprocessor guard addresses the "al    7477    * The preprocessor guard addresses the "always false" warning
7478    * from -Wtype-limits on platforms where       7478    * from -Wtype-limits on platforms where
7479    * sizeof(unsigned int) < sizeof(size_t), e    7479    * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
7480 #if UINT_MAX >= SIZE_MAX                         7480 #if UINT_MAX >= SIZE_MAX
7481   if (dtd->scaffCount > (size_t)(-1) / sizeof    7481   if (dtd->scaffCount > (size_t)(-1) / sizeof(XML_Content)) {
7482     return NULL;                                 7482     return NULL;
7483   }                                              7483   }
7484   if (dtd->contentStringLen > (size_t)(-1) /     7484   if (dtd->contentStringLen > (size_t)(-1) / sizeof(XML_Char)) {
7485     return NULL;                                 7485     return NULL;
7486   }                                              7486   }
7487 #endif                                           7487 #endif
7488   if (dtd->scaffCount * sizeof(XML_Content)      7488   if (dtd->scaffCount * sizeof(XML_Content)
7489       > (size_t)(-1) - dtd->contentStringLen     7489       > (size_t)(-1) - dtd->contentStringLen * sizeof(XML_Char)) {
7490     return NULL;                                 7490     return NULL;
7491   }                                              7491   }
7492                                                  7492 
7493   const size_t allocsize = (dtd->scaffCount *    7493   const size_t allocsize = (dtd->scaffCount * sizeof(XML_Content)
7494                             + (dtd->contentSt    7494                             + (dtd->contentStringLen * sizeof(XML_Char)));
7495                                                  7495 
7496   ret = (XML_Content *)MALLOC(parser, allocsi    7496   ret = (XML_Content *)MALLOC(parser, allocsize);
7497   if (! ret)                                     7497   if (! ret)
7498     return NULL;                                 7498     return NULL;
7499                                                  7499 
7500   /* What follows is an iterative implementat    7500   /* What follows is an iterative implementation (of what was previously done
7501    * recursively in a dedicated function call    7501    * recursively in a dedicated function called "build_node".  The old recursive
7502    * build_node could be forced into stack ex    7502    * build_node could be forced into stack exhaustion from input as small as a
7503    * few megabyte, and so that was a security    7503    * few megabyte, and so that was a security issue.  Hence, a function call
7504    * stack is avoided now by resolving recurs    7504    * stack is avoided now by resolving recursion.)
7505    *                                             7505    *
7506    * The iterative approach works as follows:    7506    * The iterative approach works as follows:
7507    *                                             7507    *
7508    * - We have two writing pointers, both wal    7508    * - We have two writing pointers, both walking up the result array; one does
7509    *   the work, the other creates "jobs" for    7509    *   the work, the other creates "jobs" for its colleague to do, and leads
7510    *   the way:                                  7510    *   the way:
7511    *                                             7511    *
7512    *   - The faster one, pointer jobDest, alw    7512    *   - The faster one, pointer jobDest, always leads and writes "what job
7513    *     to do" by the other, once they reach    7513    *     to do" by the other, once they reach that place in the
7514    *     array: leader "jobDest" stores the s    7514    *     array: leader "jobDest" stores the source node array index (relative
7515    *     to array dtd->scaffold) in field "nu    7515    *     to array dtd->scaffold) in field "numchildren".
7516    *                                             7516    *
7517    *   - The slower one, pointer dest, looks     7517    *   - The slower one, pointer dest, looks at the value stored in the
7518    *     "numchildren" field (which actually     7518    *     "numchildren" field (which actually holds a source node array index
7519    *     at that time) and puts the real data    7519    *     at that time) and puts the real data from dtd->scaffold in.
7520    *                                             7520    *
7521    * - Before the loop starts, jobDest writes    7521    * - Before the loop starts, jobDest writes source array index 0
7522    *   (where the root node is located) so th    7522    *   (where the root node is located) so that dest will have something to do
7523    *   when it starts operation.                 7523    *   when it starts operation.
7524    *                                             7524    *
7525    * - Whenever nodes with children are encou    7525    * - Whenever nodes with children are encountered, jobDest appends
7526    *   them as new jobs, in order.  As a resu    7526    *   them as new jobs, in order.  As a result, tree node siblings are
7527    *   adjacent in the resulting array, for e    7527    *   adjacent in the resulting array, for example:
7528    *                                             7528    *
7529    *     [0] root, has two children              7529    *     [0] root, has two children
7530    *       [1] first child of 0, has three ch    7530    *       [1] first child of 0, has three children
7531    *         [3] first child of 1, does not h    7531    *         [3] first child of 1, does not have children
7532    *         [4] second child of 1, does not     7532    *         [4] second child of 1, does not have children
7533    *         [5] third child of 1, does not h    7533    *         [5] third child of 1, does not have children
7534    *       [2] second child of 0, does not ha    7534    *       [2] second child of 0, does not have children
7535    *                                             7535    *
7536    *   Or (the same data) presented in flat a    7536    *   Or (the same data) presented in flat array view:
7537    *                                             7537    *
7538    *     [0] root, has two children              7538    *     [0] root, has two children
7539    *                                             7539    *
7540    *     [1] first child of 0, has three chil    7540    *     [1] first child of 0, has three children
7541    *     [2] second child of 0, does not have    7541    *     [2] second child of 0, does not have children
7542    *                                             7542    *
7543    *     [3] first child of 1, does not have     7543    *     [3] first child of 1, does not have children
7544    *     [4] second child of 1, does not have    7544    *     [4] second child of 1, does not have children
7545    *     [5] third child of 1, does not have     7545    *     [5] third child of 1, does not have children
7546    *                                             7546    *
7547    * - The algorithm repeats until all target    7547    * - The algorithm repeats until all target array indices have been processed.
7548    */                                            7548    */
7549   XML_Content *dest = ret; /* tree node writi    7549   XML_Content *dest = ret; /* tree node writing location, moves upwards */
7550   XML_Content *const destLimit = &ret[dtd->sc    7550   XML_Content *const destLimit = &ret[dtd->scaffCount];
7551   XML_Content *jobDest = ret; /* next free wr    7551   XML_Content *jobDest = ret; /* next free writing location in target array */
7552   str = (XML_Char *)&ret[dtd->scaffCount];       7552   str = (XML_Char *)&ret[dtd->scaffCount];
7553                                                  7553 
7554   /* Add the starting job, the root node (ind    7554   /* Add the starting job, the root node (index 0) of the source tree  */
7555   (jobDest++)->numchildren = 0;                  7555   (jobDest++)->numchildren = 0;
7556                                                  7556 
7557   for (; dest < destLimit; dest++) {             7557   for (; dest < destLimit; dest++) {
7558     /* Retrieve source tree array index from     7558     /* Retrieve source tree array index from job storage */
7559     const int src_node = (int)dest->numchildr    7559     const int src_node = (int)dest->numchildren;
7560                                                  7560 
7561     /* Convert item */                           7561     /* Convert item */
7562     dest->type = dtd->scaffold[src_node].type    7562     dest->type = dtd->scaffold[src_node].type;
7563     dest->quant = dtd->scaffold[src_node].qua    7563     dest->quant = dtd->scaffold[src_node].quant;
7564     if (dest->type == XML_CTYPE_NAME) {          7564     if (dest->type == XML_CTYPE_NAME) {
7565       const XML_Char *src;                       7565       const XML_Char *src;
7566       dest->name = str;                          7566       dest->name = str;
7567       src = dtd->scaffold[src_node].name;        7567       src = dtd->scaffold[src_node].name;
7568       for (;;) {                                 7568       for (;;) {
7569         *str++ = *src;                           7569         *str++ = *src;
7570         if (! *src)                              7570         if (! *src)
7571           break;                                 7571           break;
7572         src++;                                   7572         src++;
7573       }                                          7573       }
7574       dest->numchildren = 0;                     7574       dest->numchildren = 0;
7575       dest->children = NULL;                     7575       dest->children = NULL;
7576     } else {                                     7576     } else {
7577       unsigned int i;                            7577       unsigned int i;
7578       int cn;                                    7578       int cn;
7579       dest->name = NULL;                         7579       dest->name = NULL;
7580       dest->numchildren = dtd->scaffold[src_n    7580       dest->numchildren = dtd->scaffold[src_node].childcnt;
7581       dest->children = jobDest;                  7581       dest->children = jobDest;
7582                                                  7582 
7583       /* Append scaffold indices of children     7583       /* Append scaffold indices of children to array */
7584       for (i = 0, cn = dtd->scaffold[src_node    7584       for (i = 0, cn = dtd->scaffold[src_node].firstchild;
7585            i < dest->numchildren; i++, cn = d    7585            i < dest->numchildren; i++, cn = dtd->scaffold[cn].nextsib)
7586         (jobDest++)->numchildren = (unsigned     7586         (jobDest++)->numchildren = (unsigned int)cn;
7587     }                                            7587     }
7588   }                                              7588   }
7589                                                  7589 
7590   return ret;                                    7590   return ret;
7591 }                                                7591 }
7592                                                  7592 
7593 static ELEMENT_TYPE *                            7593 static ELEMENT_TYPE *
7594 getElementType(XML_Parser parser, const ENCOD    7594 getElementType(XML_Parser parser, const ENCODING *enc, const char *ptr,
7595                const char *end) {                7595                const char *end) {
7596   DTD *const dtd = parser->m_dtd; /* save one    7596   DTD *const dtd = parser->m_dtd; /* save one level of indirection */
7597   const XML_Char *name = poolStoreString(&dtd    7597   const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
7598   ELEMENT_TYPE *ret;                             7598   ELEMENT_TYPE *ret;
7599                                                  7599 
7600   if (! name)                                    7600   if (! name)
7601     return NULL;                                 7601     return NULL;
7602   ret = (ELEMENT_TYPE *)lookup(parser, &dtd->    7602   ret = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
7603                                sizeof(ELEMENT    7603                                sizeof(ELEMENT_TYPE));
7604   if (! ret)                                     7604   if (! ret)
7605     return NULL;                                 7605     return NULL;
7606   if (ret->name != name)                         7606   if (ret->name != name)
7607     poolDiscard(&dtd->pool);                     7607     poolDiscard(&dtd->pool);
7608   else {                                         7608   else {
7609     poolFinish(&dtd->pool);                      7609     poolFinish(&dtd->pool);
7610     if (! setElementTypePrefix(parser, ret))     7610     if (! setElementTypePrefix(parser, ret))
7611       return NULL;                               7611       return NULL;
7612   }                                              7612   }
7613   return ret;                                    7613   return ret;
7614 }                                                7614 }
7615                                                  7615 
7616 static XML_Char *                                7616 static XML_Char *
7617 copyString(const XML_Char *s, const XML_Memor    7617 copyString(const XML_Char *s, const XML_Memory_Handling_Suite *memsuite) {
7618   size_t charsRequired = 0;                      7618   size_t charsRequired = 0;
7619   XML_Char *result;                              7619   XML_Char *result;
7620                                                  7620 
7621   /* First determine how long the string is *    7621   /* First determine how long the string is */
7622   while (s[charsRequired] != 0) {                7622   while (s[charsRequired] != 0) {
7623     charsRequired++;                             7623     charsRequired++;
7624   }                                              7624   }
7625   /* Include the terminator */                   7625   /* Include the terminator */
7626   charsRequired++;                               7626   charsRequired++;
7627                                                  7627 
7628   /* Now allocate space for the copy */          7628   /* Now allocate space for the copy */
7629   result = memsuite->malloc_fcn(charsRequired    7629   result = memsuite->malloc_fcn(charsRequired * sizeof(XML_Char));
7630   if (result == NULL)                            7630   if (result == NULL)
7631     return NULL;                                 7631     return NULL;
7632   /* Copy the original into place */             7632   /* Copy the original into place */
7633   memcpy(result, s, charsRequired * sizeof(XM    7633   memcpy(result, s, charsRequired * sizeof(XML_Char));
7634   return result;                                 7634   return result;
7635 }                                                7635 }
7636                                                  7636 
7637 #ifdef XML_DTD                                   7637 #ifdef XML_DTD
7638                                                  7638 
7639 static float                                     7639 static float
7640 accountingGetCurrentAmplification(XML_Parser     7640 accountingGetCurrentAmplification(XML_Parser rootParser) {
7641   const XmlBigCount countBytesOutput             7641   const XmlBigCount countBytesOutput
7642       = rootParser->m_accounting.countBytesDi    7642       = rootParser->m_accounting.countBytesDirect
7643         + rootParser->m_accounting.countBytes    7643         + rootParser->m_accounting.countBytesIndirect;
7644   const float amplificationFactor                7644   const float amplificationFactor
7645       = rootParser->m_accounting.countBytesDi    7645       = rootParser->m_accounting.countBytesDirect
7646             ? (countBytesOutput                  7646             ? (countBytesOutput
7647                / (float)(rootParser->m_accoun    7647                / (float)(rootParser->m_accounting.countBytesDirect))
7648             : 1.0f;                              7648             : 1.0f;
7649   assert(! rootParser->m_parentParser);          7649   assert(! rootParser->m_parentParser);
7650   return amplificationFactor;                    7650   return amplificationFactor;
7651 }                                                7651 }
7652                                                  7652 
7653 static void                                      7653 static void
7654 accountingReportStats(XML_Parser originParser    7654 accountingReportStats(XML_Parser originParser, const char *epilog) {
7655   const XML_Parser rootParser = getRootParser    7655   const XML_Parser rootParser = getRootParserOf(originParser, NULL);
7656   assert(! rootParser->m_parentParser);          7656   assert(! rootParser->m_parentParser);
7657                                                  7657 
7658   if (rootParser->m_accounting.debugLevel < 1    7658   if (rootParser->m_accounting.debugLevel < 1) {
7659     return;                                      7659     return;
7660   }                                              7660   }
7661                                                  7661 
7662   const float amplificationFactor                7662   const float amplificationFactor
7663       = accountingGetCurrentAmplification(roo    7663       = accountingGetCurrentAmplification(rootParser);
7664   fprintf(stderr,                                7664   fprintf(stderr,
7665           "expat: Accounting(%p): Direct " EX    7665           "expat: Accounting(%p): Direct " EXPAT_FMT_ULL(
7666               "10") ", indirect " EXPAT_FMT_U    7666               "10") ", indirect " EXPAT_FMT_ULL("10") ", amplification %8.2f%s",
7667           (void *)rootParser, rootParser->m_a    7667           (void *)rootParser, rootParser->m_accounting.countBytesDirect,
7668           rootParser->m_accounting.countBytes    7668           rootParser->m_accounting.countBytesIndirect,
7669           (double)amplificationFactor, epilog    7669           (double)amplificationFactor, epilog);
7670 }                                                7670 }
7671                                                  7671 
7672 static void                                      7672 static void
7673 accountingOnAbort(XML_Parser originParser) {     7673 accountingOnAbort(XML_Parser originParser) {
7674   accountingReportStats(originParser, " ABORT    7674   accountingReportStats(originParser, " ABORTING\n");
7675 }                                                7675 }
7676                                                  7676 
7677 static void                                      7677 static void
7678 accountingReportDiff(XML_Parser rootParser,      7678 accountingReportDiff(XML_Parser rootParser,
7679                      unsigned int levelsAwayF    7679                      unsigned int levelsAwayFromRootParser, const char *before,
7680                      const char *after, ptrdi    7680                      const char *after, ptrdiff_t bytesMore, int source_line,
7681                      enum XML_Account account    7681                      enum XML_Account account) {
7682   assert(! rootParser->m_parentParser);          7682   assert(! rootParser->m_parentParser);
7683                                                  7683 
7684   fprintf(stderr,                                7684   fprintf(stderr,
7685           " (+" EXPAT_FMT_PTRDIFF_T("6") " by    7685           " (+" EXPAT_FMT_PTRDIFF_T("6") " bytes %s|%d, xmlparse.c:%d) %*s\"",
7686           bytesMore, (account == XML_ACCOUNT_    7686           bytesMore, (account == XML_ACCOUNT_DIRECT) ? "DIR" : "EXP",
7687           levelsAwayFromRootParser, source_li    7687           levelsAwayFromRootParser, source_line, 10, "");
7688                                                  7688 
7689   const char ellipis[] = "[..]";                 7689   const char ellipis[] = "[..]";
7690   const size_t ellipsisLength = sizeof(ellipi    7690   const size_t ellipsisLength = sizeof(ellipis) /* because compile-time */ - 1;
7691   const unsigned int contextLength = 10;         7691   const unsigned int contextLength = 10;
7692                                                  7692 
7693   /* Note: Performance is of no concern here     7693   /* Note: Performance is of no concern here */
7694   const char *walker = before;                   7694   const char *walker = before;
7695   if ((rootParser->m_accounting.debugLevel >=    7695   if ((rootParser->m_accounting.debugLevel >= 3)
7696       || (after - before)                        7696       || (after - before)
7697              <= (ptrdiff_t)(contextLength + e    7697              <= (ptrdiff_t)(contextLength + ellipsisLength + contextLength)) {
7698     for (; walker < after; walker++) {           7698     for (; walker < after; walker++) {
7699       fprintf(stderr, "%s", unsignedCharToPri    7699       fprintf(stderr, "%s", unsignedCharToPrintable(walker[0]));
7700     }                                            7700     }
7701   } else {                                       7701   } else {
7702     for (; walker < before + contextLength; w    7702     for (; walker < before + contextLength; walker++) {
7703       fprintf(stderr, "%s", unsignedCharToPri    7703       fprintf(stderr, "%s", unsignedCharToPrintable(walker[0]));
7704     }                                            7704     }
7705     fprintf(stderr, ellipis);                    7705     fprintf(stderr, ellipis);
7706     walker = after - contextLength;              7706     walker = after - contextLength;
7707     for (; walker < after; walker++) {           7707     for (; walker < after; walker++) {
7708       fprintf(stderr, "%s", unsignedCharToPri    7708       fprintf(stderr, "%s", unsignedCharToPrintable(walker[0]));
7709     }                                            7709     }
7710   }                                              7710   }
7711   fprintf(stderr, "\"\n");                       7711   fprintf(stderr, "\"\n");
7712 }                                                7712 }
7713                                                  7713 
7714 static XML_Bool                                  7714 static XML_Bool
7715 accountingDiffTolerated(XML_Parser originPars    7715 accountingDiffTolerated(XML_Parser originParser, int tok, const char *before,
7716                         const char *after, in    7716                         const char *after, int source_line,
7717                         enum XML_Account acco    7717                         enum XML_Account account) {
7718   /* Note: We need to check the token type *f    7718   /* Note: We need to check the token type *first* to be sure that
7719    *       we can even access variable <after    7719    *       we can even access variable <after>, safely.
7720    *       E.g. for XML_TOK_NONE <after> may     7720    *       E.g. for XML_TOK_NONE <after> may hold an invalid pointer. */
7721   switch (tok) {                                 7721   switch (tok) {
7722   case XML_TOK_INVALID:                          7722   case XML_TOK_INVALID:
7723   case XML_TOK_PARTIAL:                          7723   case XML_TOK_PARTIAL:
7724   case XML_TOK_PARTIAL_CHAR:                     7724   case XML_TOK_PARTIAL_CHAR:
7725   case XML_TOK_NONE:                             7725   case XML_TOK_NONE:
7726     return XML_TRUE;                             7726     return XML_TRUE;
7727   }                                              7727   }
7728                                                  7728 
7729   if (account == XML_ACCOUNT_NONE)               7729   if (account == XML_ACCOUNT_NONE)
7730     return XML_TRUE; /* because these bytes h    7730     return XML_TRUE; /* because these bytes have been accounted for, already */
7731                                                  7731 
7732   unsigned int levelsAwayFromRootParser;         7732   unsigned int levelsAwayFromRootParser;
7733   const XML_Parser rootParser                    7733   const XML_Parser rootParser
7734       = getRootParserOf(originParser, &levels    7734       = getRootParserOf(originParser, &levelsAwayFromRootParser);
7735   assert(! rootParser->m_parentParser);          7735   assert(! rootParser->m_parentParser);
7736                                                  7736 
7737   const int isDirect                             7737   const int isDirect
7738       = (account == XML_ACCOUNT_DIRECT) && (o    7738       = (account == XML_ACCOUNT_DIRECT) && (originParser == rootParser);
7739   const ptrdiff_t bytesMore = after - before;    7739   const ptrdiff_t bytesMore = after - before;
7740                                                  7740 
7741   XmlBigCount *const additionTarget              7741   XmlBigCount *const additionTarget
7742       = isDirect ? &rootParser->m_accounting.    7742       = isDirect ? &rootParser->m_accounting.countBytesDirect
7743                  : &rootParser->m_accounting.    7743                  : &rootParser->m_accounting.countBytesIndirect;
7744                                                  7744 
7745   /* Detect and avoid integer overflow */        7745   /* Detect and avoid integer overflow */
7746   if (*additionTarget > (XmlBigCount)(-1) - (    7746   if (*additionTarget > (XmlBigCount)(-1) - (XmlBigCount)bytesMore)
7747     return XML_FALSE;                            7747     return XML_FALSE;
7748   *additionTarget += bytesMore;                  7748   *additionTarget += bytesMore;
7749                                                  7749 
7750   const XmlBigCount countBytesOutput             7750   const XmlBigCount countBytesOutput
7751       = rootParser->m_accounting.countBytesDi    7751       = rootParser->m_accounting.countBytesDirect
7752         + rootParser->m_accounting.countBytes    7752         + rootParser->m_accounting.countBytesIndirect;
7753   const float amplificationFactor                7753   const float amplificationFactor
7754       = accountingGetCurrentAmplification(roo    7754       = accountingGetCurrentAmplification(rootParser);
7755   const XML_Bool tolerated                       7755   const XML_Bool tolerated
7756       = (countBytesOutput < rootParser->m_acc    7756       = (countBytesOutput < rootParser->m_accounting.activationThresholdBytes)
7757         || (amplificationFactor                  7757         || (amplificationFactor
7758             <= rootParser->m_accounting.maxim    7758             <= rootParser->m_accounting.maximumAmplificationFactor);
7759                                                  7759 
7760   if (rootParser->m_accounting.debugLevel >=     7760   if (rootParser->m_accounting.debugLevel >= 2) {
7761     accountingReportStats(rootParser, "");       7761     accountingReportStats(rootParser, "");
7762     accountingReportDiff(rootParser, levelsAw    7762     accountingReportDiff(rootParser, levelsAwayFromRootParser, before, after,
7763                          bytesMore, source_li    7763                          bytesMore, source_line, account);
7764   }                                              7764   }
7765                                                  7765 
7766   return tolerated;                              7766   return tolerated;
7767 }                                                7767 }
7768                                                  7768 
7769 unsigned long long                               7769 unsigned long long
7770 testingAccountingGetCountBytesDirect(XML_Pars    7770 testingAccountingGetCountBytesDirect(XML_Parser parser) {
7771   if (! parser)                                  7771   if (! parser)
7772     return 0;                                    7772     return 0;
7773   return parser->m_accounting.countBytesDirec    7773   return parser->m_accounting.countBytesDirect;
7774 }                                                7774 }
7775                                                  7775 
7776 unsigned long long                               7776 unsigned long long
7777 testingAccountingGetCountBytesIndirect(XML_Pa    7777 testingAccountingGetCountBytesIndirect(XML_Parser parser) {
7778   if (! parser)                                  7778   if (! parser)
7779     return 0;                                    7779     return 0;
7780   return parser->m_accounting.countBytesIndir    7780   return parser->m_accounting.countBytesIndirect;
7781 }                                                7781 }
7782                                                  7782 
7783 static void                                      7783 static void
7784 entityTrackingReportStats(XML_Parser rootPars    7784 entityTrackingReportStats(XML_Parser rootParser, ENTITY *entity,
7785                           const char *action,    7785                           const char *action, int sourceLine) {
7786   assert(! rootParser->m_parentParser);          7786   assert(! rootParser->m_parentParser);
7787   if (rootParser->m_entity_stats.debugLevel <    7787   if (rootParser->m_entity_stats.debugLevel < 1)
7788     return;                                      7788     return;
7789                                                  7789 
7790 #  if defined(XML_UNICODE)                       7790 #  if defined(XML_UNICODE)
7791   const char *const entityName = "[..]";         7791   const char *const entityName = "[..]";
7792 #  else                                          7792 #  else
7793   const char *const entityName = entity->name    7793   const char *const entityName = entity->name;
7794 #  endif                                         7794 #  endif
7795                                                  7795 
7796   fprintf(                                       7796   fprintf(
7797       stderr,                                    7797       stderr,
7798       "expat: Entities(%p): Count %9d, depth     7798       "expat: Entities(%p): Count %9d, depth %2d/%2d %*s%s%s; %s length %d (xmlparse.c:%d)\n",
7799       (void *)rootParser, rootParser->m_entit    7799       (void *)rootParser, rootParser->m_entity_stats.countEverOpened,
7800       rootParser->m_entity_stats.currentDepth    7800       rootParser->m_entity_stats.currentDepth,
7801       rootParser->m_entity_stats.maximumDepth    7801       rootParser->m_entity_stats.maximumDepthSeen,
7802       (rootParser->m_entity_stats.currentDept    7802       (rootParser->m_entity_stats.currentDepth - 1) * 2, "",
7803       entity->is_param ? "%" : "&", entityNam    7803       entity->is_param ? "%" : "&", entityName, action, entity->textLen,
7804       sourceLine);                               7804       sourceLine);
7805 }                                                7805 }
7806                                                  7806 
7807 static void                                      7807 static void
7808 entityTrackingOnOpen(XML_Parser originParser,    7808 entityTrackingOnOpen(XML_Parser originParser, ENTITY *entity, int sourceLine) {
7809   const XML_Parser rootParser = getRootParser    7809   const XML_Parser rootParser = getRootParserOf(originParser, NULL);
7810   assert(! rootParser->m_parentParser);          7810   assert(! rootParser->m_parentParser);
7811                                                  7811 
7812   rootParser->m_entity_stats.countEverOpened+    7812   rootParser->m_entity_stats.countEverOpened++;
7813   rootParser->m_entity_stats.currentDepth++;     7813   rootParser->m_entity_stats.currentDepth++;
7814   if (rootParser->m_entity_stats.currentDepth    7814   if (rootParser->m_entity_stats.currentDepth
7815       > rootParser->m_entity_stats.maximumDep    7815       > rootParser->m_entity_stats.maximumDepthSeen) {
7816     rootParser->m_entity_stats.maximumDepthSe    7816     rootParser->m_entity_stats.maximumDepthSeen++;
7817   }                                              7817   }
7818                                                  7818 
7819   entityTrackingReportStats(rootParser, entit    7819   entityTrackingReportStats(rootParser, entity, "OPEN ", sourceLine);
7820 }                                                7820 }
7821                                                  7821 
7822 static void                                      7822 static void
7823 entityTrackingOnClose(XML_Parser originParser    7823 entityTrackingOnClose(XML_Parser originParser, ENTITY *entity, int sourceLine) {
7824   const XML_Parser rootParser = getRootParser    7824   const XML_Parser rootParser = getRootParserOf(originParser, NULL);
7825   assert(! rootParser->m_parentParser);          7825   assert(! rootParser->m_parentParser);
7826                                                  7826 
7827   entityTrackingReportStats(rootParser, entit    7827   entityTrackingReportStats(rootParser, entity, "CLOSE", sourceLine);
7828   rootParser->m_entity_stats.currentDepth--;     7828   rootParser->m_entity_stats.currentDepth--;
7829 }                                                7829 }
7830                                                  7830 
7831 static XML_Parser                                7831 static XML_Parser
7832 getRootParserOf(XML_Parser parser, unsigned i    7832 getRootParserOf(XML_Parser parser, unsigned int *outLevelDiff) {
7833   XML_Parser rootParser = parser;                7833   XML_Parser rootParser = parser;
7834   unsigned int stepsTakenUpwards = 0;            7834   unsigned int stepsTakenUpwards = 0;
7835   while (rootParser->m_parentParser) {           7835   while (rootParser->m_parentParser) {
7836     rootParser = rootParser->m_parentParser;     7836     rootParser = rootParser->m_parentParser;
7837     stepsTakenUpwards++;                         7837     stepsTakenUpwards++;
7838   }                                              7838   }
7839   assert(! rootParser->m_parentParser);          7839   assert(! rootParser->m_parentParser);
7840   if (outLevelDiff != NULL) {                    7840   if (outLevelDiff != NULL) {
7841     *outLevelDiff = stepsTakenUpwards;           7841     *outLevelDiff = stepsTakenUpwards;
7842   }                                              7842   }
7843   return rootParser;                             7843   return rootParser;
7844 }                                                7844 }
7845                                                  7845 
7846 const char *                                     7846 const char *
7847 unsignedCharToPrintable(unsigned char c) {       7847 unsignedCharToPrintable(unsigned char c) {
7848   switch (c) {                                   7848   switch (c) {
7849   case 0:                                        7849   case 0:
7850     return "\\0";                                7850     return "\\0";
7851   case 1:                                        7851   case 1:
7852     return "\\x1";                               7852     return "\\x1";
7853   case 2:                                        7853   case 2:
7854     return "\\x2";                               7854     return "\\x2";
7855   case 3:                                        7855   case 3:
7856     return "\\x3";                               7856     return "\\x3";
7857   case 4:                                        7857   case 4:
7858     return "\\x4";                               7858     return "\\x4";
7859   case 5:                                        7859   case 5:
7860     return "\\x5";                               7860     return "\\x5";
7861   case 6:                                        7861   case 6:
7862     return "\\x6";                               7862     return "\\x6";
7863   case 7:                                        7863   case 7:
7864     return "\\x7";                               7864     return "\\x7";
7865   case 8:                                        7865   case 8:
7866     return "\\x8";                               7866     return "\\x8";
7867   case 9:                                        7867   case 9:
7868     return "\\t";                                7868     return "\\t";
7869   case 10:                                       7869   case 10:
7870     return "\\n";                                7870     return "\\n";
7871   case 11:                                       7871   case 11:
7872     return "\\xB";                               7872     return "\\xB";
7873   case 12:                                       7873   case 12:
7874     return "\\xC";                               7874     return "\\xC";
7875   case 13:                                       7875   case 13:
7876     return "\\r";                                7876     return "\\r";
7877   case 14:                                       7877   case 14:
7878     return "\\xE";                               7878     return "\\xE";
7879   case 15:                                       7879   case 15:
7880     return "\\xF";                               7880     return "\\xF";
7881   case 16:                                       7881   case 16:
7882     return "\\x10";                              7882     return "\\x10";
7883   case 17:                                       7883   case 17:
7884     return "\\x11";                              7884     return "\\x11";
7885   case 18:                                       7885   case 18:
7886     return "\\x12";                              7886     return "\\x12";
7887   case 19:                                       7887   case 19:
7888     return "\\x13";                              7888     return "\\x13";
7889   case 20:                                       7889   case 20:
7890     return "\\x14";                              7890     return "\\x14";
7891   case 21:                                       7891   case 21:
7892     return "\\x15";                              7892     return "\\x15";
7893   case 22:                                       7893   case 22:
7894     return "\\x16";                              7894     return "\\x16";
7895   case 23:                                       7895   case 23:
7896     return "\\x17";                              7896     return "\\x17";
7897   case 24:                                       7897   case 24:
7898     return "\\x18";                              7898     return "\\x18";
7899   case 25:                                       7899   case 25:
7900     return "\\x19";                              7900     return "\\x19";
7901   case 26:                                       7901   case 26:
7902     return "\\x1A";                              7902     return "\\x1A";
7903   case 27:                                       7903   case 27:
7904     return "\\x1B";                              7904     return "\\x1B";
7905   case 28:                                       7905   case 28:
7906     return "\\x1C";                              7906     return "\\x1C";
7907   case 29:                                       7907   case 29:
7908     return "\\x1D";                              7908     return "\\x1D";
7909   case 30:                                       7909   case 30:
7910     return "\\x1E";                              7910     return "\\x1E";
7911   case 31:                                       7911   case 31:
7912     return "\\x1F";                              7912     return "\\x1F";
7913   case 32:                                       7913   case 32:
7914     return " ";                                  7914     return " ";
7915   case 33:                                       7915   case 33:
7916     return "!";                                  7916     return "!";
7917   case 34:                                       7917   case 34:
7918     return "\\\"";                               7918     return "\\\"";
7919   case 35:                                       7919   case 35:
7920     return "#";                                  7920     return "#";
7921   case 36:                                       7921   case 36:
7922     return "$";                                  7922     return "$";
7923   case 37:                                       7923   case 37:
7924     return "%";                                  7924     return "%";
7925   case 38:                                       7925   case 38:
7926     return "&";                                  7926     return "&";
7927   case 39:                                       7927   case 39:
7928     return "'";                                  7928     return "'";
7929   case 40:                                       7929   case 40:
7930     return "(";                                  7930     return "(";
7931   case 41:                                       7931   case 41:
7932     return ")";                                  7932     return ")";
7933   case 42:                                       7933   case 42:
7934     return "*";                                  7934     return "*";
7935   case 43:                                       7935   case 43:
7936     return "+";                                  7936     return "+";
7937   case 44:                                       7937   case 44:
7938     return ",";                                  7938     return ",";
7939   case 45:                                       7939   case 45:
7940     return "-";                                  7940     return "-";
7941   case 46:                                       7941   case 46:
7942     return ".";                                  7942     return ".";
7943   case 47:                                       7943   case 47:
7944     return "/";                                  7944     return "/";
7945   case 48:                                       7945   case 48:
7946     return "0";                                  7946     return "0";
7947   case 49:                                       7947   case 49:
7948     return "1";                                  7948     return "1";
7949   case 50:                                       7949   case 50:
7950     return "2";                                  7950     return "2";
7951   case 51:                                       7951   case 51:
7952     return "3";                                  7952     return "3";
7953   case 52:                                       7953   case 52:
7954     return "4";                                  7954     return "4";
7955   case 53:                                       7955   case 53:
7956     return "5";                                  7956     return "5";
7957   case 54:                                       7957   case 54:
7958     return "6";                                  7958     return "6";
7959   case 55:                                       7959   case 55:
7960     return "7";                                  7960     return "7";
7961   case 56:                                       7961   case 56:
7962     return "8";                                  7962     return "8";
7963   case 57:                                       7963   case 57:
7964     return "9";                                  7964     return "9";
7965   case 58:                                       7965   case 58:
7966     return ":";                                  7966     return ":";
7967   case 59:                                       7967   case 59:
7968     return ";";                                  7968     return ";";
7969   case 60:                                       7969   case 60:
7970     return "<";                                  7970     return "<";
7971   case 61:                                       7971   case 61:
7972     return "=";                                  7972     return "=";
7973   case 62:                                       7973   case 62:
7974     return ">";                                  7974     return ">";
7975   case 63:                                       7975   case 63:
7976     return "?";                                  7976     return "?";
7977   case 64:                                       7977   case 64:
7978     return "@";                                  7978     return "@";
7979   case 65:                                       7979   case 65:
7980     return "A";                                  7980     return "A";
7981   case 66:                                       7981   case 66:
7982     return "B";                                  7982     return "B";
7983   case 67:                                       7983   case 67:
7984     return "C";                                  7984     return "C";
7985   case 68:                                       7985   case 68:
7986     return "D";                                  7986     return "D";
7987   case 69:                                       7987   case 69:
7988     return "E";                                  7988     return "E";
7989   case 70:                                       7989   case 70:
7990     return "F";                                  7990     return "F";
7991   case 71:                                       7991   case 71:
7992     return "G";                                  7992     return "G";
7993   case 72:                                       7993   case 72:
7994     return "H";                                  7994     return "H";
7995   case 73:                                       7995   case 73:
7996     return "I";                                  7996     return "I";
7997   case 74:                                       7997   case 74:
7998     return "J";                                  7998     return "J";
7999   case 75:                                       7999   case 75:
8000     return "K";                                  8000     return "K";
8001   case 76:                                       8001   case 76:
8002     return "L";                                  8002     return "L";
8003   case 77:                                       8003   case 77:
8004     return "M";                                  8004     return "M";
8005   case 78:                                       8005   case 78:
8006     return "N";                                  8006     return "N";
8007   case 79:                                       8007   case 79:
8008     return "O";                                  8008     return "O";
8009   case 80:                                       8009   case 80:
8010     return "P";                                  8010     return "P";
8011   case 81:                                       8011   case 81:
8012     return "Q";                                  8012     return "Q";
8013   case 82:                                       8013   case 82:
8014     return "R";                                  8014     return "R";
8015   case 83:                                       8015   case 83:
8016     return "S";                                  8016     return "S";
8017   case 84:                                       8017   case 84:
8018     return "T";                                  8018     return "T";
8019   case 85:                                       8019   case 85:
8020     return "U";                                  8020     return "U";
8021   case 86:                                       8021   case 86:
8022     return "V";                                  8022     return "V";
8023   case 87:                                       8023   case 87:
8024     return "W";                                  8024     return "W";
8025   case 88:                                       8025   case 88:
8026     return "X";                                  8026     return "X";
8027   case 89:                                       8027   case 89:
8028     return "Y";                                  8028     return "Y";
8029   case 90:                                       8029   case 90:
8030     return "Z";                                  8030     return "Z";
8031   case 91:                                       8031   case 91:
8032     return "[";                                  8032     return "[";
8033   case 92:                                       8033   case 92:
8034     return "\\\\";                               8034     return "\\\\";
8035   case 93:                                       8035   case 93:
8036     return "]";                                  8036     return "]";
8037   case 94:                                       8037   case 94:
8038     return "^";                                  8038     return "^";
8039   case 95:                                       8039   case 95:
8040     return "_";                                  8040     return "_";
8041   case 96:                                       8041   case 96:
8042     return "`";                                  8042     return "`";
8043   case 97:                                       8043   case 97:
8044     return "a";                                  8044     return "a";
8045   case 98:                                       8045   case 98:
8046     return "b";                                  8046     return "b";
8047   case 99:                                       8047   case 99:
8048     return "c";                                  8048     return "c";
8049   case 100:                                      8049   case 100:
8050     return "d";                                  8050     return "d";
8051   case 101:                                      8051   case 101:
8052     return "e";                                  8052     return "e";
8053   case 102:                                      8053   case 102:
8054     return "f";                                  8054     return "f";
8055   case 103:                                      8055   case 103:
8056     return "g";                                  8056     return "g";
8057   case 104:                                      8057   case 104:
8058     return "h";                                  8058     return "h";
8059   case 105:                                      8059   case 105:
8060     return "i";                                  8060     return "i";
8061   case 106:                                      8061   case 106:
8062     return "j";                                  8062     return "j";
8063   case 107:                                      8063   case 107:
8064     return "k";                                  8064     return "k";
8065   case 108:                                      8065   case 108:
8066     return "l";                                  8066     return "l";
8067   case 109:                                      8067   case 109:
8068     return "m";                                  8068     return "m";
8069   case 110:                                      8069   case 110:
8070     return "n";                                  8070     return "n";
8071   case 111:                                      8071   case 111:
8072     return "o";                                  8072     return "o";
8073   case 112:                                      8073   case 112:
8074     return "p";                                  8074     return "p";
8075   case 113:                                      8075   case 113:
8076     return "q";                                  8076     return "q";
8077   case 114:                                      8077   case 114:
8078     return "r";                                  8078     return "r";
8079   case 115:                                      8079   case 115:
8080     return "s";                                  8080     return "s";
8081   case 116:                                      8081   case 116:
8082     return "t";                                  8082     return "t";
8083   case 117:                                      8083   case 117:
8084     return "u";                                  8084     return "u";
8085   case 118:                                      8085   case 118:
8086     return "v";                                  8086     return "v";
8087   case 119:                                      8087   case 119:
8088     return "w";                                  8088     return "w";
8089   case 120:                                      8089   case 120:
8090     return "x";                                  8090     return "x";
8091   case 121:                                      8091   case 121:
8092     return "y";                                  8092     return "y";
8093   case 122:                                      8093   case 122:
8094     return "z";                                  8094     return "z";
8095   case 123:                                      8095   case 123:
8096     return "{";                                  8096     return "{";
8097   case 124:                                      8097   case 124:
8098     return "|";                                  8098     return "|";
8099   case 125:                                      8099   case 125:
8100     return "}";                                  8100     return "}";
8101   case 126:                                      8101   case 126:
8102     return "~";                                  8102     return "~";
8103   case 127:                                      8103   case 127:
8104     return "\\x7F";                              8104     return "\\x7F";
8105   case 128:                                      8105   case 128:
8106     return "\\x80";                              8106     return "\\x80";
8107   case 129:                                      8107   case 129:
8108     return "\\x81";                              8108     return "\\x81";
8109   case 130:                                      8109   case 130:
8110     return "\\x82";                              8110     return "\\x82";
8111   case 131:                                      8111   case 131:
8112     return "\\x83";                              8112     return "\\x83";
8113   case 132:                                      8113   case 132:
8114     return "\\x84";                              8114     return "\\x84";
8115   case 133:                                      8115   case 133:
8116     return "\\x85";                              8116     return "\\x85";
8117   case 134:                                      8117   case 134:
8118     return "\\x86";                              8118     return "\\x86";
8119   case 135:                                      8119   case 135:
8120     return "\\x87";                              8120     return "\\x87";
8121   case 136:                                      8121   case 136:
8122     return "\\x88";                              8122     return "\\x88";
8123   case 137:                                      8123   case 137:
8124     return "\\x89";                              8124     return "\\x89";
8125   case 138:                                      8125   case 138:
8126     return "\\x8A";                              8126     return "\\x8A";
8127   case 139:                                      8127   case 139:
8128     return "\\x8B";                              8128     return "\\x8B";
8129   case 140:                                      8129   case 140:
8130     return "\\x8C";                              8130     return "\\x8C";
8131   case 141:                                      8131   case 141:
8132     return "\\x8D";                              8132     return "\\x8D";
8133   case 142:                                      8133   case 142:
8134     return "\\x8E";                              8134     return "\\x8E";
8135   case 143:                                      8135   case 143:
8136     return "\\x8F";                              8136     return "\\x8F";
8137   case 144:                                      8137   case 144:
8138     return "\\x90";                              8138     return "\\x90";
8139   case 145:                                      8139   case 145:
8140     return "\\x91";                              8140     return "\\x91";
8141   case 146:                                      8141   case 146:
8142     return "\\x92";                              8142     return "\\x92";
8143   case 147:                                      8143   case 147:
8144     return "\\x93";                              8144     return "\\x93";
8145   case 148:                                      8145   case 148:
8146     return "\\x94";                              8146     return "\\x94";
8147   case 149:                                      8147   case 149:
8148     return "\\x95";                              8148     return "\\x95";
8149   case 150:                                      8149   case 150:
8150     return "\\x96";                              8150     return "\\x96";
8151   case 151:                                      8151   case 151:
8152     return "\\x97";                              8152     return "\\x97";
8153   case 152:                                      8153   case 152:
8154     return "\\x98";                              8154     return "\\x98";
8155   case 153:                                      8155   case 153:
8156     return "\\x99";                              8156     return "\\x99";
8157   case 154:                                      8157   case 154:
8158     return "\\x9A";                              8158     return "\\x9A";
8159   case 155:                                      8159   case 155:
8160     return "\\x9B";                              8160     return "\\x9B";
8161   case 156:                                      8161   case 156:
8162     return "\\x9C";                              8162     return "\\x9C";
8163   case 157:                                      8163   case 157:
8164     return "\\x9D";                              8164     return "\\x9D";
8165   case 158:                                      8165   case 158:
8166     return "\\x9E";                              8166     return "\\x9E";
8167   case 159:                                      8167   case 159:
8168     return "\\x9F";                              8168     return "\\x9F";
8169   case 160:                                      8169   case 160:
8170     return "\\xA0";                              8170     return "\\xA0";
8171   case 161:                                      8171   case 161:
8172     return "\\xA1";                              8172     return "\\xA1";
8173   case 162:                                      8173   case 162:
8174     return "\\xA2";                              8174     return "\\xA2";
8175   case 163:                                      8175   case 163:
8176     return "\\xA3";                              8176     return "\\xA3";
8177   case 164:                                      8177   case 164:
8178     return "\\xA4";                              8178     return "\\xA4";
8179   case 165:                                      8179   case 165:
8180     return "\\xA5";                              8180     return "\\xA5";
8181   case 166:                                      8181   case 166:
8182     return "\\xA6";                              8182     return "\\xA6";
8183   case 167:                                      8183   case 167:
8184     return "\\xA7";                              8184     return "\\xA7";
8185   case 168:                                      8185   case 168:
8186     return "\\xA8";                              8186     return "\\xA8";
8187   case 169:                                      8187   case 169:
8188     return "\\xA9";                              8188     return "\\xA9";
8189   case 170:                                      8189   case 170:
8190     return "\\xAA";                              8190     return "\\xAA";
8191   case 171:                                      8191   case 171:
8192     return "\\xAB";                              8192     return "\\xAB";
8193   case 172:                                      8193   case 172:
8194     return "\\xAC";                              8194     return "\\xAC";
8195   case 173:                                      8195   case 173:
8196     return "\\xAD";                              8196     return "\\xAD";
8197   case 174:                                      8197   case 174:
8198     return "\\xAE";                              8198     return "\\xAE";
8199   case 175:                                      8199   case 175:
8200     return "\\xAF";                              8200     return "\\xAF";
8201   case 176:                                      8201   case 176:
8202     return "\\xB0";                              8202     return "\\xB0";
8203   case 177:                                      8203   case 177:
8204     return "\\xB1";                              8204     return "\\xB1";
8205   case 178:                                      8205   case 178:
8206     return "\\xB2";                              8206     return "\\xB2";
8207   case 179:                                      8207   case 179:
8208     return "\\xB3";                              8208     return "\\xB3";
8209   case 180:                                      8209   case 180:
8210     return "\\xB4";                              8210     return "\\xB4";
8211   case 181:                                      8211   case 181:
8212     return "\\xB5";                              8212     return "\\xB5";
8213   case 182:                                      8213   case 182:
8214     return "\\xB6";                              8214     return "\\xB6";
8215   case 183:                                      8215   case 183:
8216     return "\\xB7";                              8216     return "\\xB7";
8217   case 184:                                      8217   case 184:
8218     return "\\xB8";                              8218     return "\\xB8";
8219   case 185:                                      8219   case 185:
8220     return "\\xB9";                              8220     return "\\xB9";
8221   case 186:                                      8221   case 186:
8222     return "\\xBA";                              8222     return "\\xBA";
8223   case 187:                                      8223   case 187:
8224     return "\\xBB";                              8224     return "\\xBB";
8225   case 188:                                      8225   case 188:
8226     return "\\xBC";                              8226     return "\\xBC";
8227   case 189:                                      8227   case 189:
8228     return "\\xBD";                              8228     return "\\xBD";
8229   case 190:                                      8229   case 190:
8230     return "\\xBE";                              8230     return "\\xBE";
8231   case 191:                                      8231   case 191:
8232     return "\\xBF";                              8232     return "\\xBF";
8233   case 192:                                      8233   case 192:
8234     return "\\xC0";                              8234     return "\\xC0";
8235   case 193:                                      8235   case 193:
8236     return "\\xC1";                              8236     return "\\xC1";
8237   case 194:                                      8237   case 194:
8238     return "\\xC2";                              8238     return "\\xC2";
8239   case 195:                                      8239   case 195:
8240     return "\\xC3";                              8240     return "\\xC3";
8241   case 196:                                      8241   case 196:
8242     return "\\xC4";                              8242     return "\\xC4";
8243   case 197:                                      8243   case 197:
8244     return "\\xC5";                              8244     return "\\xC5";
8245   case 198:                                      8245   case 198:
8246     return "\\xC6";                              8246     return "\\xC6";
8247   case 199:                                      8247   case 199:
8248     return "\\xC7";                              8248     return "\\xC7";
8249   case 200:                                      8249   case 200:
8250     return "\\xC8";                              8250     return "\\xC8";
8251   case 201:                                      8251   case 201:
8252     return "\\xC9";                              8252     return "\\xC9";
8253   case 202:                                      8253   case 202:
8254     return "\\xCA";                              8254     return "\\xCA";
8255   case 203:                                      8255   case 203:
8256     return "\\xCB";                              8256     return "\\xCB";
8257   case 204:                                      8257   case 204:
8258     return "\\xCC";                              8258     return "\\xCC";
8259   case 205:                                      8259   case 205:
8260     return "\\xCD";                              8260     return "\\xCD";
8261   case 206:                                      8261   case 206:
8262     return "\\xCE";                              8262     return "\\xCE";
8263   case 207:                                      8263   case 207:
8264     return "\\xCF";                              8264     return "\\xCF";
8265   case 208:                                      8265   case 208:
8266     return "\\xD0";                              8266     return "\\xD0";
8267   case 209:                                      8267   case 209:
8268     return "\\xD1";                              8268     return "\\xD1";
8269   case 210:                                      8269   case 210:
8270     return "\\xD2";                              8270     return "\\xD2";
8271   case 211:                                      8271   case 211:
8272     return "\\xD3";                              8272     return "\\xD3";
8273   case 212:                                      8273   case 212:
8274     return "\\xD4";                              8274     return "\\xD4";
8275   case 213:                                      8275   case 213:
8276     return "\\xD5";                              8276     return "\\xD5";
8277   case 214:                                      8277   case 214:
8278     return "\\xD6";                              8278     return "\\xD6";
8279   case 215:                                      8279   case 215:
8280     return "\\xD7";                              8280     return "\\xD7";
8281   case 216:                                      8281   case 216:
8282     return "\\xD8";                              8282     return "\\xD8";
8283   case 217:                                      8283   case 217:
8284     return "\\xD9";                              8284     return "\\xD9";
8285   case 218:                                      8285   case 218:
8286     return "\\xDA";                              8286     return "\\xDA";
8287   case 219:                                      8287   case 219:
8288     return "\\xDB";                              8288     return "\\xDB";
8289   case 220:                                      8289   case 220:
8290     return "\\xDC";                              8290     return "\\xDC";
8291   case 221:                                      8291   case 221:
8292     return "\\xDD";                              8292     return "\\xDD";
8293   case 222:                                      8293   case 222:
8294     return "\\xDE";                              8294     return "\\xDE";
8295   case 223:                                      8295   case 223:
8296     return "\\xDF";                              8296     return "\\xDF";
8297   case 224:                                      8297   case 224:
8298     return "\\xE0";                              8298     return "\\xE0";
8299   case 225:                                      8299   case 225:
8300     return "\\xE1";                              8300     return "\\xE1";
8301   case 226:                                      8301   case 226:
8302     return "\\xE2";                              8302     return "\\xE2";
8303   case 227:                                      8303   case 227:
8304     return "\\xE3";                              8304     return "\\xE3";
8305   case 228:                                      8305   case 228:
8306     return "\\xE4";                              8306     return "\\xE4";
8307   case 229:                                      8307   case 229:
8308     return "\\xE5";                              8308     return "\\xE5";
8309   case 230:                                      8309   case 230:
8310     return "\\xE6";                              8310     return "\\xE6";
8311   case 231:                                      8311   case 231:
8312     return "\\xE7";                              8312     return "\\xE7";
8313   case 232:                                      8313   case 232:
8314     return "\\xE8";                              8314     return "\\xE8";
8315   case 233:                                      8315   case 233:
8316     return "\\xE9";                              8316     return "\\xE9";
8317   case 234:                                      8317   case 234:
8318     return "\\xEA";                              8318     return "\\xEA";
8319   case 235:                                      8319   case 235:
8320     return "\\xEB";                              8320     return "\\xEB";
8321   case 236:                                      8321   case 236:
8322     return "\\xEC";                              8322     return "\\xEC";
8323   case 237:                                      8323   case 237:
8324     return "\\xED";                              8324     return "\\xED";
8325   case 238:                                      8325   case 238:
8326     return "\\xEE";                              8326     return "\\xEE";
8327   case 239:                                      8327   case 239:
8328     return "\\xEF";                              8328     return "\\xEF";
8329   case 240:                                      8329   case 240:
8330     return "\\xF0";                              8330     return "\\xF0";
8331   case 241:                                      8331   case 241:
8332     return "\\xF1";                              8332     return "\\xF1";
8333   case 242:                                      8333   case 242:
8334     return "\\xF2";                              8334     return "\\xF2";
8335   case 243:                                      8335   case 243:
8336     return "\\xF3";                              8336     return "\\xF3";
8337   case 244:                                      8337   case 244:
8338     return "\\xF4";                              8338     return "\\xF4";
8339   case 245:                                      8339   case 245:
8340     return "\\xF5";                              8340     return "\\xF5";
8341   case 246:                                      8341   case 246:
8342     return "\\xF6";                              8342     return "\\xF6";
8343   case 247:                                      8343   case 247:
8344     return "\\xF7";                              8344     return "\\xF7";
8345   case 248:                                      8345   case 248:
8346     return "\\xF8";                              8346     return "\\xF8";
8347   case 249:                                      8347   case 249:
8348     return "\\xF9";                              8348     return "\\xF9";
8349   case 250:                                      8349   case 250:
8350     return "\\xFA";                              8350     return "\\xFA";
8351   case 251:                                      8351   case 251:
8352     return "\\xFB";                              8352     return "\\xFB";
8353   case 252:                                      8353   case 252:
8354     return "\\xFC";                              8354     return "\\xFC";
8355   case 253:                                      8355   case 253:
8356     return "\\xFD";                              8356     return "\\xFD";
8357   case 254:                                      8357   case 254:
8358     return "\\xFE";                              8358     return "\\xFE";
8359   case 255:                                      8359   case 255:
8360     return "\\xFF";                              8360     return "\\xFF";
8361   default:                                       8361   default:
8362     assert(0); /* never gets here */             8362     assert(0); /* never gets here */
8363     return "dead code";                          8363     return "dead code";
8364   }                                              8364   }
8365   assert(0); /* never gets here */               8365   assert(0); /* never gets here */
8366 }                                                8366 }
8367                                                  8367 
8368 #endif /* XML_DTD */                             8368 #endif /* XML_DTD */
8369                                                  8369 
8370 static unsigned long                             8370 static unsigned long
8371 getDebugLevel(const char *variableName, unsig    8371 getDebugLevel(const char *variableName, unsigned long defaultDebugLevel) {
8372   const char *const valueOrNull = getenv(vari    8372   const char *const valueOrNull = getenv(variableName);
8373   if (valueOrNull == NULL) {                     8373   if (valueOrNull == NULL) {
8374     return defaultDebugLevel;                    8374     return defaultDebugLevel;
8375   }                                              8375   }
8376   const char *const value = valueOrNull;         8376   const char *const value = valueOrNull;
8377                                                  8377 
8378   errno = 0;                                     8378   errno = 0;
8379   char *afterValue = (char *)value;              8379   char *afterValue = (char *)value;
8380   unsigned long debugLevel = strtoul(value, &    8380   unsigned long debugLevel = strtoul(value, &afterValue, 10);
8381   if ((errno != 0) || (afterValue[0] != '\0')    8381   if ((errno != 0) || (afterValue[0] != '\0')) {
8382     errno = 0;                                   8382     errno = 0;
8383     return defaultDebugLevel;                    8383     return defaultDebugLevel;
8384   }                                              8384   }
8385                                                  8385 
8386   return debugLevel;                             8386   return debugLevel;
8387 }                                                8387 }
8388                                                  8388