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 9.3.p1)


  1 /* 90815a2b2c80c03b2b889fe1d427bb2b9e3282aa065      1 
  2                             __  __                
  3                          ___\ \/ /_ __   __ _|    
  4                         / _ \\  /| '_ \ / _` |    
  5                        |  __//  \| |_) | (_| |    
  6                         \___/_/\_\ .__/ \__,_|    
  7                                  |_| XML parse    
  8                                                   
  9    Copyright (c) 1997-2000 Thai Open Source So    
 10    Copyright (c) 2000      Clark Cooper <coope    
 11    Copyright (c) 2000-2006 Fred L. Drake, Jr.     
 12    Copyright (c) 2001-2002 Greg Stein <gstein@    
 13    Copyright (c) 2002-2016 Karl Waclawek <karl    
 14    Copyright (c) 2005-2009 Steven Solie <steve    
 15    Copyright (c) 2016      Eric Rahm <erahm@mo    
 16    Copyright (c) 2016-2022 Sebastian Pipping <    
 17    Copyright (c) 2016      Gaurav <g.gupta@sam    
 18    Copyright (c) 2016      Thomas Beutlich <tc    
 19    Copyright (c) 2016      Gustavo Grieco <gus    
 20    Copyright (c) 2016      Pascal Cuoq <cuoq@t    
 21    Copyright (c) 2016      Ed Schouten <ed@nux    
 22    Copyright (c) 2017-2022 Rhodri James <rhodr    
 23    Copyright (c) 2017      Václav Slavík <va    
 24    Copyright (c) 2017      Viktor Szakats <com    
 25    Copyright (c) 2017      Chanho Park <chanho    
 26    Copyright (c) 2017      Rolf Eike Beer <eik    
 27    Copyright (c) 2017      Hans Wennborg <hans    
 28    Copyright (c) 2018      Anton Maklakov <ant    
 29    Copyright (c) 2018      Benjamin Peterson <    
 30    Copyright (c) 2018      Marco Maggi <marco.    
 31    Copyright (c) 2018      Mariusz Zaborski <o    
 32    Copyright (c) 2019      David Loffredo <lof    
 33    Copyright (c) 2019-2020 Ben Wagner <bungema    
 34    Copyright (c) 2019      Vadim Zeitlin <vadi    
 35    Copyright (c) 2021      Dong-hee Na <donghe    
 36    Copyright (c) 2022      Samanta Navarro <fe    
 37    Copyright (c) 2022      Jeffrey Walton <nol    
 38    Licensed under the MIT license:                
 39                                                   
 40    Permission is  hereby granted,  free of cha    
 41    a  copy  of  this  software   and  associat    
 42    "Software"),  to  deal in  the  Software  w    
 43    without  limitation the  rights  to use,  c    
 44    distribute, sublicense, and/or sell copies     
 45    persons  to whom  the Software  is  furnish    
 46    following conditions:                          
 47                                                   
 48    The above copyright  notice and this permis    
 49    in all copies or substantial portions of th    
 50                                                   
 51    THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WIT    
 52    EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT L    
 53    MERCHANTABILITY, FITNESS FOR A PARTICULAR P    
 54    NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HO    
 55    DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN    
 56    OTHERWISE, ARISING FROM, OUT OF OR IN CONNE    
 57    USE OR OTHER DEALINGS IN THE SOFTWARE.         
 58 */                                                
 59                                                   
 60 #define XML_BUILDING_EXPAT 1                      
 61                                                   
 62 #include <expat_config.h>                         
 63                                                   
 64 #if ! defined(_GNU_SOURCE)                        
 65 #  define _GNU_SOURCE 1 /* syscall prototype *    
 66 #endif                                            
 67                                                   
 68 #ifdef _WIN32                                     
 69 /* force stdlib to define rand_s() */             
 70 #  if ! defined(_CRT_RAND_S)                      
 71 #    define _CRT_RAND_S                           
 72 #  endif                                          
 73 #endif                                            
 74                                                   
 75 #include <stddef.h>                               
 76 #include <string.h> /* memset(), memcpy() */      
 77 #include <assert.h>                               
 78 #include <limits.h> /* UINT_MAX */                
 79 #include <stdio.h>  /* fprintf */                 
 80 #include <stdlib.h> /* getenv, rand_s */          
 81 #include <stdint.h> /* uintptr_t */               
 82 #include <math.h>   /* isnan */                   
 83                                                   
 84 #ifdef _WIN32                                     
 85 #  define getpid GetCurrentProcessId              
 86 #else                                             
 87 #  include <sys/time.h>  /* gettimeofday() */     
 88 #  include <sys/types.h> /* getpid() */           
 89 #  include <unistd.h>    /* getpid() */           
 90 #  include <fcntl.h>     /* O_RDONLY */           
 91 #  include <errno.h>                              
 92 #endif                                            
 93                                                   
 94 #ifdef _WIN32                                     
 95 #  include "winconfig.h"                          
 96 #endif                                            
 97                                                   
 98 #include "ascii.h"                                
 99 #include "expat.h"                                
100 #include "siphash.h"                              
101                                                   
102 #if defined(HAVE_GETRANDOM) || defined(HAVE_SY    
103 #  if defined(HAVE_GETRANDOM)                     
104 #    include <sys/random.h> /* getrandom */       
105 #  else                                           
106 #    include <unistd.h>      /* syscall */        
107 #    include <sys/syscall.h> /* SYS_getrandom     
108 #  endif                                          
109 #  if ! defined(GRND_NONBLOCK)                    
110 #    define GRND_NONBLOCK 0x0001                  
111 #  endif /* defined(GRND_NONBLOCK) */             
112 #endif   /* defined(HAVE_GETRANDOM) || defined    
113                                                   
114 #if defined(HAVE_LIBBSD)                          
115     && (defined(HAVE_ARC4RANDOM_BUF) || define    
116 #  include <bsd/stdlib.h>                         
117 #endif                                            
118                                                   
119 #if defined(_WIN32) && ! defined(LOAD_LIBRARY_    
120 #  define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000    
121 #endif                                            
122                                                   
123 #if ! defined(HAVE_GETRANDOM) && ! defined(HAV    
124     && ! defined(HAVE_ARC4RANDOM_BUF) && ! def    
125     && ! defined(XML_DEV_URANDOM) && ! defined    
126     && ! defined(XML_POOR_ENTROPY)                
127 #  error You do not have support for any sourc    
128     enabled.  For end user security, that is p    
129     \                                             
130     Your options include: \                       
131       * Linux >=3.17 + glibc >=2.25 (getrandom    
132       * Linux >=3.17 + glibc (including <2.25)    
133       * BSD / macOS >=10.7 (arc4random_buf): H    
134       * BSD / macOS (including <10.7) (arc4ran    
135       * libbsd (arc4random_buf): HAVE_ARC4RAND    
136       * libbsd (arc4random): HAVE_ARC4RANDOM +    
137       * Linux (including <3.17) / BSD / macOS     
138       * Windows >=Vista (rand_s): _WIN32. \       
139     \                                             
140     If insist on not using any of these, bypas    
141     XML_POOR_ENTROPY; you have been warned. \     
142     \                                             
143     If you have reasons to patch this detectio    
144     to the build system, please open a bug.  T    
145 #endif                                            
146                                                   
147 #ifdef XML_UNICODE                                
148 #  define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX     
149 #  define XmlConvert XmlUtf16Convert              
150 #  define XmlGetInternalEncoding XmlGetUtf16In    
151 #  define XmlGetInternalEncodingNS XmlGetUtf16    
152 #  define XmlEncode XmlUtf16Encode                
153 #  define MUST_CONVERT(enc, s) (! (enc)->isUtf    
154 typedef unsigned short ICHAR;                     
155 #else                                             
156 #  define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX      
157 #  define XmlConvert XmlUtf8Convert               
158 #  define XmlGetInternalEncoding XmlGetUtf8Int    
159 #  define XmlGetInternalEncodingNS XmlGetUtf8I    
160 #  define XmlEncode XmlUtf8Encode                 
161 #  define MUST_CONVERT(enc, s) (! (enc)->isUtf    
162 typedef char ICHAR;                               
163 #endif                                            
164                                                   
165 #ifndef XML_NS                                    
166                                                   
167 #  define XmlInitEncodingNS XmlInitEncoding       
168 #  define XmlInitUnknownEncodingNS XmlInitUnkn    
169 #  undef XmlGetInternalEncodingNS                 
170 #  define XmlGetInternalEncodingNS XmlGetInter    
171 #  define XmlParseXmlDeclNS XmlParseXmlDecl       
172                                                   
173 #endif                                            
174                                                   
175 #ifdef XML_UNICODE                                
176                                                   
177 #  ifdef XML_UNICODE_WCHAR_T                      
178 #    define XML_T(x) (const wchar_t) x            
179 #    define XML_L(x) L##x                         
180 #  else                                           
181 #    define XML_T(x) (const unsigned short)x      
182 #    define XML_L(x) x                            
183 #  endif                                          
184                                                   
185 #else                                             
186                                                   
187 #  define XML_T(x) x                              
188 #  define XML_L(x) x                              
189                                                   
190 #endif                                            
191                                                   
192 /* Round up n to be a multiple of sz, where sz    
193 #define ROUND_UP(n, sz) (((n) + ((sz)-1)) & ~(    
194                                                   
195 /* Do safe (NULL-aware) pointer arithmetic */     
196 #define EXPAT_SAFE_PTR_DIFF(p, q) (((p) && (q)    
197                                                   
198 #include "internal.h"                             
199 #include "xmltok.h"                               
200 #include "xmlrole.h"                              
201                                                   
202 typedef const XML_Char *KEY;                      
203                                                   
204 typedef struct {                                  
205   KEY name;                                       
206 } NAMED;                                          
207                                                   
208 typedef struct {                                  
209   NAMED **v;                                      
210   unsigned char power;                            
211   size_t size;                                    
212   size_t used;                                    
213   const XML_Memory_Handling_Suite *mem;           
214 } HASH_TABLE;                                     
215                                                   
216 static size_t keylen(KEY s);                      
217                                                   
218 static void copy_salt_to_sipkey(XML_Parser par    
219                                                   
220 /* For probing (after a collision) we need a s    
221    to the hash table size, which is a power of    
222    since we can calculate a second hash value     
223    of the first hash value that were discarded    
224    index was calculated: index = hash & mask,     
225    We limit the maximum step size to table->si    
226    it odd, since odd numbers are always relati    
227 */                                                
228 #define SECOND_HASH(hash, mask, power)            
229   ((((hash) & ~(mask)) >> ((power)-1)) & ((mas    
230 #define PROBE_STEP(hash, mask, power)             
231   ((unsigned char)((SECOND_HASH(hash, mask, po    
232                                                   
233 typedef struct {                                  
234   NAMED **p;                                      
235   NAMED **end;                                    
236 } HASH_TABLE_ITER;                                
237                                                   
238 #define INIT_TAG_BUF_SIZE 32 /* must be a mult    
239 #define INIT_DATA_BUF_SIZE 1024                   
240 #define INIT_ATTS_SIZE 16                         
241 #define INIT_ATTS_VERSION 0xFFFFFFFF              
242 #define INIT_BLOCK_SIZE 1024                      
243 #define INIT_BUFFER_SIZE 1024                     
244                                                   
245 #define EXPAND_SPARE 24                           
246                                                   
247 typedef struct binding {                          
248   struct prefix *prefix;                          
249   struct binding *nextTagBinding;                 
250   struct binding *prevPrefixBinding;              
251   const struct attribute_id *attId;               
252   XML_Char *uri;                                  
253   int uriLen;                                     
254   int uriAlloc;                                   
255 } BINDING;                                        
256                                                   
257 typedef struct prefix {                           
258   const XML_Char *name;                           
259   BINDING *binding;                               
260 } PREFIX;                                         
261                                                   
262 typedef struct {                                  
263   const XML_Char *str;                            
264   const XML_Char *localPart;                      
265   const XML_Char *prefix;                         
266   int strLen;                                     
267   int uriLen;                                     
268   int prefixLen;                                  
269 } TAG_NAME;                                       
270                                                   
271 /* TAG represents an open element.                
272    The name of the element is stored in both t    
273    encodings.  The memory buffer 'buf' is a se    
274    memory area which stores the name.  During     
275    XMLParseBuffer() when the element is open,     
276    version of the name (in the document encodi    
277    document buffer.  If the element is open ac    
278    XML_Parse()/XML_ParseBuffer(), the buffer i    
279    contain the 'raw' name as well.                
280                                                   
281    A parser re-uses these structures, maintain    
282    TAG objects in a free list.                    
283 */                                                
284 typedef struct tag {                              
285   struct tag *parent;  /* parent of this eleme    
286   const char *rawName; /* tagName in the origi    
287   int rawNameLength;                              
288   TAG_NAME name; /* tagName in the API encodin    
289   char *buf;     /* buffer for name components    
290   char *bufEnd;  /* end of the buffer */          
291   BINDING *bindings;                              
292 } TAG;                                            
293                                                   
294 typedef struct {                                  
295   const XML_Char *name;                           
296   const XML_Char *textPtr;                        
297   int textLen;   /* length in XML_Chars */        
298   int processed; /* # of processed bytes - whe    
299   const XML_Char *systemId;                       
300   const XML_Char *base;                           
301   const XML_Char *publicId;                       
302   const XML_Char *notation;                       
303   XML_Bool open;                                  
304   XML_Bool is_param;                              
305   XML_Bool is_internal; /* true if declared in    
306 } ENTITY;                                         
307                                                   
308 typedef struct {                                  
309   enum XML_Content_Type type;                     
310   enum XML_Content_Quant quant;                   
311   const XML_Char *name;                           
312   int firstchild;                                 
313   int lastchild;                                  
314   int childcnt;                                   
315   int nextsib;                                    
316 } CONTENT_SCAFFOLD;                               
317                                                   
318 #define INIT_SCAFFOLD_ELEMENTS 32                 
319                                                   
320 typedef struct block {                            
321   struct block *next;                             
322   int size;                                       
323   XML_Char s[1];                                  
324 } BLOCK;                                          
325                                                   
326 typedef struct {                                  
327   BLOCK *blocks;                                  
328   BLOCK *freeBlocks;                              
329   const XML_Char *end;                            
330   XML_Char *ptr;                                  
331   XML_Char *start;                                
332   const XML_Memory_Handling_Suite *mem;           
333 } STRING_POOL;                                    
334                                                   
335 /* The XML_Char before the name is used to det    
336    an attribute has been specified. */            
337 typedef struct attribute_id {                     
338   XML_Char *name;                                 
339   PREFIX *prefix;                                 
340   XML_Bool maybeTokenized;                        
341   XML_Bool xmlns;                                 
342 } ATTRIBUTE_ID;                                   
343                                                   
344 typedef struct {                                  
345   const ATTRIBUTE_ID *id;                         
346   XML_Bool isCdata;                               
347   const XML_Char *value;                          
348 } DEFAULT_ATTRIBUTE;                              
349                                                   
350 typedef struct {                                  
351   unsigned long version;                          
352   unsigned long hash;                             
353   const XML_Char *uriName;                        
354 } NS_ATT;                                         
355                                                   
356 typedef struct {                                  
357   const XML_Char *name;                           
358   PREFIX *prefix;                                 
359   const ATTRIBUTE_ID *idAtt;                      
360   int nDefaultAtts;                               
361   int allocDefaultAtts;                           
362   DEFAULT_ATTRIBUTE *defaultAtts;                 
363 } ELEMENT_TYPE;                                   
364                                                   
365 typedef struct {                                  
366   HASH_TABLE generalEntities;                     
367   HASH_TABLE elementTypes;                        
368   HASH_TABLE attributeIds;                        
369   HASH_TABLE prefixes;                            
370   STRING_POOL pool;                               
371   STRING_POOL entityValuePool;                    
372   /* false once a parameter entity reference h    
373   XML_Bool keepProcessing;                        
374   /* true once an internal or external PE refe    
375      this includes the reference to an externa    
376   XML_Bool hasParamEntityRefs;                    
377   XML_Bool standalone;                            
378 #ifdef XML_DTD                                    
379   /* indicates if external PE has been read */    
380   XML_Bool paramEntityRead;                       
381   HASH_TABLE paramEntities;                       
382 #endif /* XML_DTD */                              
383   PREFIX defaultPrefix;                           
384   /* === scaffolding for building content mode    
385   XML_Bool in_eldecl;                             
386   CONTENT_SCAFFOLD *scaffold;                     
387   unsigned contentStringLen;                      
388   unsigned scaffSize;                             
389   unsigned scaffCount;                            
390   int scaffLevel;                                 
391   int *scaffIndex;                                
392 } DTD;                                            
393                                                   
394 typedef struct open_internal_entity {             
395   const char *internalEventPtr;                   
396   const char *internalEventEndPtr;                
397   struct open_internal_entity *next;              
398   ENTITY *entity;                                 
399   int startTagLevel;                              
400   XML_Bool betweenDecl; /* WFC: PE Between Dec    
401 } OPEN_INTERNAL_ENTITY;                           
402                                                   
403 enum XML_Account {                                
404   XML_ACCOUNT_DIRECT,           /* bytes direc    
405   XML_ACCOUNT_ENTITY_EXPANSION, /* intermediat    
406                                    expansion *    
407   XML_ACCOUNT_NONE              /* i.e. do not    
408 };                                                
409                                                   
410 #ifdef XML_DTD                                    
411 typedef unsigned long long XmlBigCount;           
412 typedef struct accounting {                       
413   XmlBigCount countBytesDirect;                   
414   XmlBigCount countBytesIndirect;                 
415   int debugLevel;                                 
416   float maximumAmplificationFactor; // >=1.0      
417   unsigned long long activationThresholdBytes;    
418 } ACCOUNTING;                                     
419                                                   
420 typedef struct entity_stats {                     
421   unsigned int countEverOpened;                   
422   unsigned int currentDepth;                      
423   unsigned int maximumDepthSeen;                  
424   int debugLevel;                                 
425 } ENTITY_STATS;                                   
426 #endif /* XML_DTD */                              
427                                                   
428 typedef enum XML_Error PTRCALL Processor(XML_P    
429                                          const    
430                                                   
431 static Processor prologProcessor;                 
432 static Processor prologInitProcessor;             
433 static Processor contentProcessor;                
434 static Processor cdataSectionProcessor;           
435 #ifdef XML_DTD                                    
436 static Processor ignoreSectionProcessor;          
437 static Processor externalParEntProcessor;         
438 static Processor externalParEntInitProcessor;     
439 static Processor entityValueProcessor;            
440 static Processor entityValueInitProcessor;        
441 #endif /* XML_DTD */                              
442 static Processor epilogProcessor;                 
443 static Processor errorProcessor;                  
444 static Processor externalEntityInitProcessor;     
445 static Processor externalEntityInitProcessor2;    
446 static Processor externalEntityInitProcessor3;    
447 static Processor externalEntityContentProcesso    
448 static Processor internalEntityProcessor;         
449                                                   
450 static enum XML_Error handleUnknownEncoding(XM    
451                                             co    
452 static enum XML_Error processXmlDecl(XML_Parse    
453                                      const cha    
454 static enum XML_Error initializeEncoding(XML_P    
455 static enum XML_Error doProlog(XML_Parser pars    
456                                const char *s,     
457                                const char *nex    
458                                XML_Bool haveMo    
459                                enum XML_Accoun    
460 static enum XML_Error processInternalEntity(XM    
461                                             XM    
462 static enum XML_Error doContent(XML_Parser par    
463                                 const ENCODING    
464                                 const char *en    
465                                 XML_Bool haveM    
466 static enum XML_Error doCdataSection(XML_Parse    
467                                      const cha    
468                                      const cha    
469                                      enum XML_    
470 #ifdef XML_DTD                                    
471 static enum XML_Error doIgnoreSection(XML_Pars    
472                                       const ch    
473                                       const ch    
474 #endif /* XML_DTD */                              
475                                                   
476 static void freeBindings(XML_Parser parser, BI    
477 static enum XML_Error storeAtts(XML_Parser par    
478                                 const char *s,    
479                                 BINDING **bind    
480                                 enum XML_Accou    
481 static enum XML_Error addBinding(XML_Parser pa    
482                                  const ATTRIBU    
483                                  BINDING **bin    
484 static int defineAttribute(ELEMENT_TYPE *type,    
485                            XML_Bool isId, cons    
486                            XML_Parser parser);    
487 static enum XML_Error storeAttributeValue(XML_    
488                                           XML_    
489                                           cons    
490                                           enum    
491 static enum XML_Error appendAttributeValue(XML    
492                                            XML    
493                                            con    
494                                            enu    
495 static ATTRIBUTE_ID *getAttributeId(XML_Parser    
496                                     const char    
497 static int setElementTypePrefix(XML_Parser par    
498 static enum XML_Error storeEntityValue(XML_Par    
499                                        const c    
500                                        enum XM    
501 static int reportProcessingInstruction(XML_Par    
502                                        const c    
503 static int reportComment(XML_Parser parser, co    
504                          const char *start, co    
505 static void reportDefault(XML_Parser parser, c    
506                           const char *start, c    
507                                                   
508 static const XML_Char *getContext(XML_Parser p    
509 static XML_Bool setContext(XML_Parser parser,     
510                                                   
511 static void FASTCALL normalizePublicId(XML_Cha    
512                                                   
513 static DTD *dtdCreate(const XML_Memory_Handlin    
514 /* do not call if m_parentParser != NULL */       
515 static void dtdReset(DTD *p, const XML_Memory_    
516 static void dtdDestroy(DTD *p, XML_Bool isDocE    
517                        const XML_Memory_Handli    
518 static int dtdCopy(XML_Parser oldParser, DTD *    
519                    const XML_Memory_Handling_S    
520 static int copyEntityTable(XML_Parser oldParse    
521                            const HASH_TABLE *)    
522 static NAMED *lookup(XML_Parser parser, HASH_T    
523                      size_t createSize);          
524 static void FASTCALL hashTableInit(HASH_TABLE     
525                                    const XML_M    
526 static void FASTCALL hashTableClear(HASH_TABLE    
527 static void FASTCALL hashTableDestroy(HASH_TAB    
528 static void FASTCALL hashTableIterInit(HASH_TA    
529 static NAMED *FASTCALL hashTableIterNext(HASH_    
530                                                   
531 static void FASTCALL poolInit(STRING_POOL *,      
532                               const XML_Memory    
533 static void FASTCALL poolClear(STRING_POOL *);    
534 static void FASTCALL poolDestroy(STRING_POOL *    
535 static XML_Char *poolAppend(STRING_POOL *pool,    
536                             const char *ptr, c    
537 static XML_Char *poolStoreString(STRING_POOL *    
538                                  const char *p    
539 static XML_Bool FASTCALL poolGrow(STRING_POOL     
540 static const XML_Char *FASTCALL poolCopyString    
541                                                   
542 static const XML_Char *poolCopyStringN(STRING_    
543                                        int n);    
544 static const XML_Char *FASTCALL poolAppendStri    
545                                                   
546                                                   
547 static int FASTCALL nextScaffoldPart(XML_Parse    
548 static XML_Content *build_model(XML_Parser par    
549 static ELEMENT_TYPE *getElementType(XML_Parser    
550                                     const char    
551                                                   
552 static XML_Char *copyString(const XML_Char *s,    
553                             const XML_Memory_H    
554                                                   
555 static unsigned long generate_hash_secret_salt    
556 static XML_Bool startParsing(XML_Parser parser    
557                                                   
558 static XML_Parser parserCreate(const XML_Char     
559                                const XML_Memor    
560                                const XML_Char     
561                                                   
562 static void parserInit(XML_Parser parser, cons    
563                                                   
564 #ifdef XML_DTD                                    
565 static float accountingGetCurrentAmplification    
566 static void accountingReportStats(XML_Parser o    
567 static void accountingOnAbort(XML_Parser origi    
568 static void accountingReportDiff(XML_Parser ro    
569                                  unsigned int     
570                                  const char *b    
571                                  ptrdiff_t byt    
572                                  enum XML_Acco    
573 static XML_Bool accountingDiffTolerated(XML_Pa    
574                                         const     
575                                         int so    
576                                         enum X    
577                                                   
578 static void entityTrackingReportStats(XML_Pars    
579                                       const ch    
580 static void entityTrackingOnOpen(XML_Parser pa    
581                                  int sourceLin    
582 static void entityTrackingOnClose(XML_Parser p    
583                                   int sourceLi    
584                                                   
585 static XML_Parser getRootParserOf(XML_Parser p    
586                                   unsigned int    
587 #endif /* XML_DTD */                              
588                                                   
589 static unsigned long getDebugLevel(const char     
590                                    unsigned lo    
591                                                   
592 #define poolStart(pool) ((pool)->start)           
593 #define poolEnd(pool) ((pool)->ptr)               
594 #define poolLength(pool) ((pool)->ptr - (pool)    
595 #define poolChop(pool) ((void)--(pool->ptr))      
596 #define poolLastChar(pool) (((pool)->ptr)[-1])    
597 #define poolDiscard(pool) ((pool)->ptr = (pool    
598 #define poolFinish(pool) ((pool)->start = (poo    
599 #define poolAppendChar(pool, c)                   
600   (((pool)->ptr == (pool)->end && ! poolGrow(p    
601        ? 0                                        
602        : ((*((pool)->ptr)++ = c), 1))             
603                                                   
604 struct XML_ParserStruct {                         
605   /* The first member must be m_userData so th    
606      macro works. */                              
607   void *m_userData;                               
608   void *m_handlerArg;                             
609   char *m_buffer;                                 
610   const XML_Memory_Handling_Suite m_mem;          
611   /* first character to be parsed */              
612   const char *m_bufferPtr;                        
613   /* past last character to be parsed */          
614   char *m_bufferEnd;                              
615   /* allocated end of m_buffer */                 
616   const char *m_bufferLim;                        
617   XML_Index m_parseEndByteIndex;                  
618   const char *m_parseEndPtr;                      
619   XML_Char *m_dataBuf;                            
620   XML_Char *m_dataBufEnd;                         
621   XML_StartElementHandler m_startElementHandle    
622   XML_EndElementHandler m_endElementHandler;      
623   XML_CharacterDataHandler m_characterDataHand    
624   XML_ProcessingInstructionHandler m_processin    
625   XML_CommentHandler m_commentHandler;            
626   XML_StartCdataSectionHandler m_startCdataSec    
627   XML_EndCdataSectionHandler m_endCdataSection    
628   XML_DefaultHandler m_defaultHandler;            
629   XML_StartDoctypeDeclHandler m_startDoctypeDe    
630   XML_EndDoctypeDeclHandler m_endDoctypeDeclHa    
631   XML_UnparsedEntityDeclHandler m_unparsedEnti    
632   XML_NotationDeclHandler m_notationDeclHandle    
633   XML_StartNamespaceDeclHandler m_startNamespa    
634   XML_EndNamespaceDeclHandler m_endNamespaceDe    
635   XML_NotStandaloneHandler m_notStandaloneHand    
636   XML_ExternalEntityRefHandler m_externalEntit    
637   XML_Parser m_externalEntityRefHandlerArg;       
638   XML_SkippedEntityHandler m_skippedEntityHand    
639   XML_UnknownEncodingHandler m_unknownEncoding    
640   XML_ElementDeclHandler m_elementDeclHandler;    
641   XML_AttlistDeclHandler m_attlistDeclHandler;    
642   XML_EntityDeclHandler m_entityDeclHandler;      
643   XML_XmlDeclHandler m_xmlDeclHandler;            
644   const ENCODING *m_encoding;                     
645   INIT_ENCODING m_initEncoding;                   
646   const ENCODING *m_internalEncoding;             
647   const XML_Char *m_protocolEncodingName;         
648   XML_Bool m_ns;                                  
649   XML_Bool m_ns_triplets;                         
650   void *m_unknownEncodingMem;                     
651   void *m_unknownEncodingData;                    
652   void *m_unknownEncodingHandlerData;             
653   void(XMLCALL *m_unknownEncodingRelease)(void    
654   PROLOG_STATE m_prologState;                     
655   Processor *m_processor;                         
656   enum XML_Error m_errorCode;                     
657   const char *m_eventPtr;                         
658   const char *m_eventEndPtr;                      
659   const char *m_positionPtr;                      
660   OPEN_INTERNAL_ENTITY *m_openInternalEntities    
661   OPEN_INTERNAL_ENTITY *m_freeInternalEntities    
662   XML_Bool m_defaultExpandInternalEntities;       
663   int m_tagLevel;                                 
664   ENTITY *m_declEntity;                           
665   const XML_Char *m_doctypeName;                  
666   const XML_Char *m_doctypeSysid;                 
667   const XML_Char *m_doctypePubid;                 
668   const XML_Char *m_declAttributeType;            
669   const XML_Char *m_declNotationName;             
670   const XML_Char *m_declNotationPublicId;         
671   ELEMENT_TYPE *m_declElementType;                
672   ATTRIBUTE_ID *m_declAttributeId;                
673   XML_Bool m_declAttributeIsCdata;                
674   XML_Bool m_declAttributeIsId;                   
675   DTD *m_dtd;                                     
676   const XML_Char *m_curBase;                      
677   TAG *m_tagStack;                                
678   TAG *m_freeTagList;                             
679   BINDING *m_inheritedBindings;                   
680   BINDING *m_freeBindingList;                     
681   int m_attsSize;                                 
682   int m_nSpecifiedAtts;                           
683   int m_idAttIndex;                               
684   ATTRIBUTE *m_atts;                              
685   NS_ATT *m_nsAtts;                               
686   unsigned long m_nsAttsVersion;                  
687   unsigned char m_nsAttsPower;                    
688 #ifdef XML_ATTR_INFO                              
689   XML_AttrInfo *m_attInfo;                        
690 #endif                                            
691   POSITION m_position;                            
692   STRING_POOL m_tempPool;                         
693   STRING_POOL m_temp2Pool;                        
694   char *m_groupConnector;                         
695   unsigned int m_groupSize;                       
696   XML_Char m_namespaceSeparator;                  
697   XML_Parser m_parentParser;                      
698   XML_ParsingStatus m_parsingStatus;              
699 #ifdef XML_DTD                                    
700   XML_Bool m_isParamEntity;                       
701   XML_Bool m_useForeignDTD;                       
702   enum XML_ParamEntityParsing m_paramEntityPar    
703 #endif                                            
704   unsigned long m_hash_secret_salt;               
705 #ifdef XML_DTD                                    
706   ACCOUNTING m_accounting;                        
707   ENTITY_STATS m_entity_stats;                    
708 #endif                                            
709 };                                                
710                                                   
711 #define MALLOC(parser, s) (parser->m_mem.mallo    
712 #define REALLOC(parser, p, s) (parser->m_mem.r    
713 #define FREE(parser, p) (parser->m_mem.free_fc    
714                                                   
715 XML_Parser XMLCALL                                
716 XML_ParserCreate(const XML_Char *encodingName)    
717   return XML_ParserCreate_MM(encodingName, NUL    
718 }                                                 
719                                                   
720 XML_Parser XMLCALL                                
721 XML_ParserCreateNS(const XML_Char *encodingNam    
722   XML_Char tmp[2] = {nsSep, 0};                   
723   return XML_ParserCreate_MM(encodingName, NUL    
724 }                                                 
725                                                   
726 // "xml=http://www.w3.org/XML/1998/namespace"     
727 static const XML_Char implicitContext[]           
728     = {ASCII_x,     ASCII_m,     ASCII_l,         
729        ASCII_t,     ASCII_t,     ASCII_p,         
730        ASCII_SLASH, ASCII_w,     ASCII_w,         
731        ASCII_w,     ASCII_3,     ASCII_PERIOD,    
732        ASCII_g,     ASCII_SLASH, ASCII_X,         
733        ASCII_SLASH, ASCII_1,     ASCII_9,         
734        ASCII_SLASH, ASCII_n,     ASCII_a,         
735        ASCII_s,     ASCII_p,     ASCII_a,         
736        '\0'};                                     
737                                                   
738 /* To avoid warnings about unused functions: *    
739 #if ! defined(HAVE_ARC4RANDOM_BUF) && ! define    
740                                                   
741 #  if defined(HAVE_GETRANDOM) || defined(HAVE_    
742                                                   
743 /* Obtain entropy on Linux 3.17+ */               
744 static int                                        
745 writeRandomBytes_getrandom_nonblock(void *targ    
746   int success = 0; /* full count bytes written    
747   size_t bytesWrittenTotal = 0;                   
748   const unsigned int getrandomFlags = GRND_NON    
749                                                   
750   do {                                            
751     void *const currentTarget = (void *)((char    
752     const size_t bytesToWrite = count - bytesW    
753                                                   
754     const int bytesWrittenMore =                  
755 #    if defined(HAVE_GETRANDOM)                   
756         getrandom(currentTarget, bytesToWrite,    
757 #    else                                         
758         syscall(SYS_getrandom, currentTarget,     
759 #    endif                                        
760                                                   
761     if (bytesWrittenMore > 0) {                   
762       bytesWrittenTotal += bytesWrittenMore;      
763       if (bytesWrittenTotal >= count)             
764         success = 1;                              
765     }                                             
766   } while (! success && (errno == EINTR));        
767                                                   
768   return success;                                 
769 }                                                 
770                                                   
771 #  endif /* defined(HAVE_GETRANDOM) || defined    
772                                                   
773 #  if ! defined(_WIN32) && defined(XML_DEV_URA    
774                                                   
775 /* Extract entropy from /dev/urandom */           
776 static int                                        
777 writeRandomBytes_dev_urandom(void *target, siz    
778   int success = 0; /* full count bytes written    
779   size_t bytesWrittenTotal = 0;                   
780                                                   
781   const int fd = open("/dev/urandom", O_RDONLY    
782   if (fd < 0) {                                   
783     return 0;                                     
784   }                                               
785                                                   
786   do {                                            
787     void *const currentTarget = (void *)((char    
788     const size_t bytesToWrite = count - bytesW    
789                                                   
790     const ssize_t bytesWrittenMore = read(fd,     
791                                                   
792     if (bytesWrittenMore > 0) {                   
793       bytesWrittenTotal += bytesWrittenMore;      
794       if (bytesWrittenTotal >= count)             
795         success = 1;                              
796     }                                             
797   } while (! success && (errno == EINTR));        
798                                                   
799   close(fd);                                      
800   return success;                                 
801 }                                                 
802                                                   
803 #  endif /* ! defined(_WIN32) && defined(XML_D    
804                                                   
805 #endif /* ! defined(HAVE_ARC4RANDOM_BUF) && !     
806                                                   
807 #if defined(HAVE_ARC4RANDOM) && ! defined(HAVE    
808                                                   
809 static void                                       
810 writeRandomBytes_arc4random(void *target, size    
811   size_t bytesWrittenTotal = 0;                   
812                                                   
813   while (bytesWrittenTotal < count) {             
814     const uint32_t random32 = arc4random();       
815     size_t i = 0;                                 
816                                                   
817     for (; (i < sizeof(random32)) && (bytesWri    
818          i++, bytesWrittenTotal++) {              
819       const uint8_t random8 = (uint8_t)(random    
820       ((uint8_t *)target)[bytesWrittenTotal] =    
821     }                                             
822   }                                               
823 }                                                 
824                                                   
825 #endif /* defined(HAVE_ARC4RANDOM) && ! define    
826                                                   
827 #ifdef _WIN32                                     
828                                                   
829 /* Provide declaration of rand_s() for MinGW-3    
830    as it didn't declare it in its header prior    
831    runtime package (mingwrt, containing stdlib    
832    was introduced at https://osdn.net/projects    
833 #  if defined(__MINGW32__) && defined(__MINGW3    
834       && __MINGW32_VERSION < 5003000L && ! def    
835 __declspec(dllimport) int rand_s(unsigned int     
836 #  endif                                          
837                                                   
838 /* Obtain entropy on Windows using the rand_s(    
839  * generates cryptographically secure random n    
840  * uses RtlGenRandom API which is present in W    
841  */                                               
842 static int                                        
843 writeRandomBytes_rand_s(void *target, size_t c    
844   size_t bytesWrittenTotal = 0;                   
845                                                   
846   while (bytesWrittenTotal < count) {             
847     unsigned int random32 = 0;                    
848     size_t i = 0;                                 
849                                                   
850     if (rand_s(&random32))                        
851       return 0; /* failure */                     
852                                                   
853     for (; (i < sizeof(random32)) && (bytesWri    
854          i++, bytesWrittenTotal++) {              
855       const uint8_t random8 = (uint8_t)(random    
856       ((uint8_t *)target)[bytesWrittenTotal] =    
857     }                                             
858   }                                               
859   return 1; /* success */                         
860 }                                                 
861                                                   
862 #endif /* _WIN32 */                               
863                                                   
864 #if ! defined(HAVE_ARC4RANDOM_BUF) && ! define    
865                                                   
866 static unsigned long                              
867 gather_time_entropy(void) {                       
868 #  ifdef _WIN32                                   
869   FILETIME ft;                                    
870   GetSystemTimeAsFileTime(&ft); /* never fails    
871   return ft.dwHighDateTime ^ ft.dwLowDateTime;    
872 #  else                                           
873   struct timeval tv;                              
874   int gettimeofday_res;                           
875                                                   
876   gettimeofday_res = gettimeofday(&tv, NULL);     
877                                                   
878 #    if defined(NDEBUG)                           
879   (void)gettimeofday_res;                         
880 #    else                                         
881   assert(gettimeofday_res == 0);                  
882 #    endif /* defined(NDEBUG) */                  
883                                                   
884   /* Microseconds time is <20 bits entropy */     
885   return tv.tv_usec;                              
886 #  endif                                          
887 }                                                 
888                                                   
889 #endif /* ! defined(HAVE_ARC4RANDOM_BUF) && !     
890                                                   
891 static unsigned long                              
892 ENTROPY_DEBUG(const char *label, unsigned long    
893   if (getDebugLevel("EXPAT_ENTROPY_DEBUG", 0)     
894     fprintf(stderr, "expat: Entropy: %s --> 0x    
895             (int)sizeof(entropy) * 2, entropy,    
896   }                                               
897   return entropy;                                 
898 }                                                 
899                                                   
900 static unsigned long                              
901 generate_hash_secret_salt(XML_Parser parser) {    
902   unsigned long entropy;                          
903   (void)parser;                                   
904                                                   
905   /* "Failproof" high quality providers: */       
906 #if defined(HAVE_ARC4RANDOM_BUF)                  
907   arc4random_buf(&entropy, sizeof(entropy));      
908   return ENTROPY_DEBUG("arc4random_buf", entro    
909 #elif defined(HAVE_ARC4RANDOM)                    
910   writeRandomBytes_arc4random((void *)&entropy    
911   return ENTROPY_DEBUG("arc4random", entropy);    
912 #else                                             
913   /* Try high quality providers first .. */       
914 #  ifdef _WIN32                                   
915   if (writeRandomBytes_rand_s((void *)&entropy    
916     return ENTROPY_DEBUG("rand_s", entropy);      
917   }                                               
918 #  elif defined(HAVE_GETRANDOM) || defined(HAV    
919   if (writeRandomBytes_getrandom_nonblock((voi    
920     return ENTROPY_DEBUG("getrandom", entropy)    
921   }                                               
922 #  endif                                          
923 #  if ! defined(_WIN32) && defined(XML_DEV_URA    
924   if (writeRandomBytes_dev_urandom((void *)&en    
925     return ENTROPY_DEBUG("/dev/urandom", entro    
926   }                                               
927 #  endif /* ! defined(_WIN32) && defined(XML_D    
928   /* .. and self-made low quality for backup:     
929                                                   
930   /* Process ID is 0 bits entropy if attacker     
931   entropy = gather_time_entropy() ^ getpid();     
932                                                   
933   /* Factors are 2^31-1 and 2^61-1 (Mersenne p    
934   if (sizeof(unsigned long) == 4) {               
935     return ENTROPY_DEBUG("fallback(4)", entrop    
936   } else {                                        
937     return ENTROPY_DEBUG("fallback(8)",           
938                          entropy * (unsigned l    
939   }                                               
940 #endif                                            
941 }                                                 
942                                                   
943 static unsigned long                              
944 get_hash_secret_salt(XML_Parser parser) {         
945   if (parser->m_parentParser != NULL)             
946     return get_hash_secret_salt(parser->m_pare    
947   return parser->m_hash_secret_salt;              
948 }                                                 
949                                                   
950 static XML_Bool /* only valid for root parser     
951 startParsing(XML_Parser parser) {                 
952   /* hash functions must be initialized before    
953   if (parser->m_hash_secret_salt == 0)            
954     parser->m_hash_secret_salt = generate_hash    
955   if (parser->m_ns) {                             
956     /* implicit context only set for root pars    
957        parsers (i.e. external entity parsers)     
958     */                                            
959     return setContext(parser, implicitContext)    
960   }                                               
961   return XML_TRUE;                                
962 }                                                 
963                                                   
964 XML_Parser XMLCALL                                
965 XML_ParserCreate_MM(const XML_Char *encodingNa    
966                     const XML_Memory_Handling_    
967                     const XML_Char *nameSep) {    
968   return parserCreate(encodingName, memsuite,     
969 }                                                 
970                                                   
971 static XML_Parser                                 
972 parserCreate(const XML_Char *encodingName,        
973              const XML_Memory_Handling_Suite *    
974              DTD *dtd) {                          
975   XML_Parser parser;                              
976                                                   
977   if (memsuite) {                                 
978     XML_Memory_Handling_Suite *mtemp;             
979     parser = memsuite->malloc_fcn(sizeof(struc    
980     if (parser != NULL) {                         
981       mtemp = (XML_Memory_Handling_Suite *)&(p    
982       mtemp->malloc_fcn = memsuite->malloc_fcn    
983       mtemp->realloc_fcn = memsuite->realloc_f    
984       mtemp->free_fcn = memsuite->free_fcn;       
985     }                                             
986   } else {                                        
987     XML_Memory_Handling_Suite *mtemp;             
988     parser = (XML_Parser)malloc(sizeof(struct     
989     if (parser != NULL) {                         
990       mtemp = (XML_Memory_Handling_Suite *)&(p    
991       mtemp->malloc_fcn = malloc;                 
992       mtemp->realloc_fcn = realloc;               
993       mtemp->free_fcn = free;                     
994     }                                             
995   }                                               
996                                                   
997   if (! parser)                                   
998     return parser;                                
999                                                   
1000   parser->m_buffer = NULL;                       
1001   parser->m_bufferLim = NULL;                    
1002                                                  
1003   parser->m_attsSize = INIT_ATTS_SIZE;           
1004   parser->m_atts                                 
1005       = (ATTRIBUTE *)MALLOC(parser, parser->m    
1006   if (parser->m_atts == NULL) {                  
1007     FREE(parser, parser);                        
1008     return NULL;                                 
1009   }                                              
1010 #ifdef XML_ATTR_INFO                             
1011   parser->m_attInfo = (XML_AttrInfo *)MALLOC(    
1012       parser, parser->m_attsSize * sizeof(XML    
1013   if (parser->m_attInfo == NULL) {               
1014     FREE(parser, parser->m_atts);                
1015     FREE(parser, parser);                        
1016     return NULL;                                 
1017   }                                              
1018 #endif                                           
1019   parser->m_dataBuf                              
1020       = (XML_Char *)MALLOC(parser, INIT_DATA_    
1021   if (parser->m_dataBuf == NULL) {               
1022     FREE(parser, parser->m_atts);                
1023 #ifdef XML_ATTR_INFO                             
1024     FREE(parser, parser->m_attInfo);             
1025 #endif                                           
1026     FREE(parser, parser);                        
1027     return NULL;                                 
1028   }                                              
1029   parser->m_dataBufEnd = parser->m_dataBuf +     
1030                                                  
1031   if (dtd)                                       
1032     parser->m_dtd = dtd;                         
1033   else {                                         
1034     parser->m_dtd = dtdCreate(&parser->m_mem)    
1035     if (parser->m_dtd == NULL) {                 
1036       FREE(parser, parser->m_dataBuf);           
1037       FREE(parser, parser->m_atts);              
1038 #ifdef XML_ATTR_INFO                             
1039       FREE(parser, parser->m_attInfo);           
1040 #endif                                           
1041       FREE(parser, parser);                      
1042       return NULL;                               
1043     }                                            
1044   }                                              
1045                                                  
1046   parser->m_freeBindingList = NULL;              
1047   parser->m_freeTagList = NULL;                  
1048   parser->m_freeInternalEntities = NULL;         
1049                                                  
1050   parser->m_groupSize = 0;                       
1051   parser->m_groupConnector = NULL;               
1052                                                  
1053   parser->m_unknownEncodingHandler = NULL;       
1054   parser->m_unknownEncodingHandlerData = NULL    
1055                                                  
1056   parser->m_namespaceSeparator = ASCII_EXCL;     
1057   parser->m_ns = XML_FALSE;                      
1058   parser->m_ns_triplets = XML_FALSE;             
1059                                                  
1060   parser->m_nsAtts = NULL;                       
1061   parser->m_nsAttsVersion = 0;                   
1062   parser->m_nsAttsPower = 0;                     
1063                                                  
1064   parser->m_protocolEncodingName = NULL;         
1065                                                  
1066   poolInit(&parser->m_tempPool, &(parser->m_m    
1067   poolInit(&parser->m_temp2Pool, &(parser->m_    
1068   parserInit(parser, encodingName);              
1069                                                  
1070   if (encodingName && ! parser->m_protocolEnc    
1071     XML_ParserFree(parser);                      
1072     return NULL;                                 
1073   }                                              
1074                                                  
1075   if (nameSep) {                                 
1076     parser->m_ns = XML_TRUE;                     
1077     parser->m_internalEncoding = XmlGetIntern    
1078     parser->m_namespaceSeparator = *nameSep;     
1079   } else {                                       
1080     parser->m_internalEncoding = XmlGetIntern    
1081   }                                              
1082                                                  
1083   return parser;                                 
1084 }                                                
1085                                                  
1086 static void                                      
1087 parserInit(XML_Parser parser, const XML_Char     
1088   parser->m_processor = prologInitProcessor;     
1089   XmlPrologStateInit(&parser->m_prologState);    
1090   if (encodingName != NULL) {                    
1091     parser->m_protocolEncodingName = copyStri    
1092   }                                              
1093   parser->m_curBase = NULL;                      
1094   XmlInitEncoding(&parser->m_initEncoding, &p    
1095   parser->m_userData = NULL;                     
1096   parser->m_handlerArg = NULL;                   
1097   parser->m_startElementHandler = NULL;          
1098   parser->m_endElementHandler = NULL;            
1099   parser->m_characterDataHandler = NULL;         
1100   parser->m_processingInstructionHandler = NU    
1101   parser->m_commentHandler = NULL;               
1102   parser->m_startCdataSectionHandler = NULL;     
1103   parser->m_endCdataSectionHandler = NULL;       
1104   parser->m_defaultHandler = NULL;               
1105   parser->m_startDoctypeDeclHandler = NULL;      
1106   parser->m_endDoctypeDeclHandler = NULL;        
1107   parser->m_unparsedEntityDeclHandler = NULL;    
1108   parser->m_notationDeclHandler = NULL;          
1109   parser->m_startNamespaceDeclHandler = NULL;    
1110   parser->m_endNamespaceDeclHandler = NULL;      
1111   parser->m_notStandaloneHandler = NULL;         
1112   parser->m_externalEntityRefHandler = NULL;     
1113   parser->m_externalEntityRefHandlerArg = par    
1114   parser->m_skippedEntityHandler = NULL;         
1115   parser->m_elementDeclHandler = NULL;           
1116   parser->m_attlistDeclHandler = NULL;           
1117   parser->m_entityDeclHandler = NULL;            
1118   parser->m_xmlDeclHandler = NULL;               
1119   parser->m_bufferPtr = parser->m_buffer;        
1120   parser->m_bufferEnd = parser->m_buffer;        
1121   parser->m_parseEndByteIndex = 0;               
1122   parser->m_parseEndPtr = NULL;                  
1123   parser->m_declElementType = NULL;              
1124   parser->m_declAttributeId = NULL;              
1125   parser->m_declEntity = NULL;                   
1126   parser->m_doctypeName = NULL;                  
1127   parser->m_doctypeSysid = NULL;                 
1128   parser->m_doctypePubid = NULL;                 
1129   parser->m_declAttributeType = NULL;            
1130   parser->m_declNotationName = NULL;             
1131   parser->m_declNotationPublicId = NULL;         
1132   parser->m_declAttributeIsCdata = XML_FALSE;    
1133   parser->m_declAttributeIsId = XML_FALSE;       
1134   memset(&parser->m_position, 0, sizeof(POSIT    
1135   parser->m_errorCode = XML_ERROR_NONE;          
1136   parser->m_eventPtr = NULL;                     
1137   parser->m_eventEndPtr = NULL;                  
1138   parser->m_positionPtr = NULL;                  
1139   parser->m_openInternalEntities = NULL;         
1140   parser->m_defaultExpandInternalEntities = X    
1141   parser->m_tagLevel = 0;                        
1142   parser->m_tagStack = NULL;                     
1143   parser->m_inheritedBindings = NULL;            
1144   parser->m_nSpecifiedAtts = 0;                  
1145   parser->m_unknownEncodingMem = NULL;           
1146   parser->m_unknownEncodingRelease = NULL;       
1147   parser->m_unknownEncodingData = NULL;          
1148   parser->m_parentParser = NULL;                 
1149   parser->m_parsingStatus.parsing = XML_INITI    
1150 #ifdef XML_DTD                                   
1151   parser->m_isParamEntity = XML_FALSE;           
1152   parser->m_useForeignDTD = XML_FALSE;           
1153   parser->m_paramEntityParsing = XML_PARAM_EN    
1154 #endif                                           
1155   parser->m_hash_secret_salt = 0;                
1156                                                  
1157 #ifdef XML_DTD                                   
1158   memset(&parser->m_accounting, 0, sizeof(ACC    
1159   parser->m_accounting.debugLevel = getDebugL    
1160   parser->m_accounting.maximumAmplificationFa    
1161       = EXPAT_BILLION_LAUGHS_ATTACK_PROTECTIO    
1162   parser->m_accounting.activationThresholdByt    
1163       = EXPAT_BILLION_LAUGHS_ATTACK_PROTECTIO    
1164                                                  
1165   memset(&parser->m_entity_stats, 0, sizeof(E    
1166   parser->m_entity_stats.debugLevel = getDebu    
1167 #endif                                           
1168 }                                                
1169                                                  
1170 /* moves list of bindings to m_freeBindingLis    
1171 static void FASTCALL                             
1172 moveToFreeBindingList(XML_Parser parser, BIND    
1173   while (bindings) {                             
1174     BINDING *b = bindings;                       
1175     bindings = bindings->nextTagBinding;         
1176     b->nextTagBinding = parser->m_freeBinding    
1177     parser->m_freeBindingList = b;               
1178   }                                              
1179 }                                                
1180                                                  
1181 XML_Bool XMLCALL                                 
1182 XML_ParserReset(XML_Parser parser, const XML_    
1183   TAG *tStk;                                     
1184   OPEN_INTERNAL_ENTITY *openEntityList;          
1185                                                  
1186   if (parser == NULL)                            
1187     return XML_FALSE;                            
1188                                                  
1189   if (parser->m_parentParser)                    
1190     return XML_FALSE;                            
1191   /* move m_tagStack to m_freeTagList */         
1192   tStk = parser->m_tagStack;                     
1193   while (tStk) {                                 
1194     TAG *tag = tStk;                             
1195     tStk = tStk->parent;                         
1196     tag->parent = parser->m_freeTagList;         
1197     moveToFreeBindingList(parser, tag->bindin    
1198     tag->bindings = NULL;                        
1199     parser->m_freeTagList = tag;                 
1200   }                                              
1201   /* move m_openInternalEntities to m_freeInt    
1202   openEntityList = parser->m_openInternalEnti    
1203   while (openEntityList) {                       
1204     OPEN_INTERNAL_ENTITY *openEntity = openEn    
1205     openEntityList = openEntity->next;           
1206     openEntity->next = parser->m_freeInternal    
1207     parser->m_freeInternalEntities = openEnti    
1208   }                                              
1209   moveToFreeBindingList(parser, parser->m_inh    
1210   FREE(parser, parser->m_unknownEncodingMem);    
1211   if (parser->m_unknownEncodingRelease)          
1212     parser->m_unknownEncodingRelease(parser->    
1213   poolClear(&parser->m_tempPool);                
1214   poolClear(&parser->m_temp2Pool);               
1215   FREE(parser, (void *)parser->m_protocolEnco    
1216   parser->m_protocolEncodingName = NULL;         
1217   parserInit(parser, encodingName);              
1218   dtdReset(parser->m_dtd, &parser->m_mem);       
1219   return XML_TRUE;                               
1220 }                                                
1221                                                  
1222 enum XML_Status XMLCALL                          
1223 XML_SetEncoding(XML_Parser parser, const XML_    
1224   if (parser == NULL)                            
1225     return XML_STATUS_ERROR;                     
1226   /* Block after XML_Parse()/XML_ParseBuffer(    
1227      XXX There's no way for the caller to det    
1228      XXX possible error cases caused the XML_    
1229   */                                             
1230   if (parser->m_parsingStatus.parsing == XML_    
1231       || parser->m_parsingStatus.parsing == X    
1232     return XML_STATUS_ERROR;                     
1233                                                  
1234   /* Get rid of any previous encoding name */    
1235   FREE(parser, (void *)parser->m_protocolEnco    
1236                                                  
1237   if (encodingName == NULL)                      
1238     /* No new encoding name */                   
1239     parser->m_protocolEncodingName = NULL;       
1240   else {                                         
1241     /* Copy the new encoding name into alloca    
1242     parser->m_protocolEncodingName = copyStri    
1243     if (! parser->m_protocolEncodingName)        
1244       return XML_STATUS_ERROR;                   
1245   }                                              
1246   return XML_STATUS_OK;                          
1247 }                                                
1248                                                  
1249 XML_Parser XMLCALL                               
1250 XML_ExternalEntityParserCreate(XML_Parser old    
1251                                const XML_Char    
1252   XML_Parser parser = oldParser;                 
1253   DTD *newDtd = NULL;                            
1254   DTD *oldDtd;                                   
1255   XML_StartElementHandler oldStartElementHand    
1256   XML_EndElementHandler oldEndElementHandler;    
1257   XML_CharacterDataHandler oldCharacterDataHa    
1258   XML_ProcessingInstructionHandler oldProcess    
1259   XML_CommentHandler oldCommentHandler;          
1260   XML_StartCdataSectionHandler oldStartCdataS    
1261   XML_EndCdataSectionHandler oldEndCdataSecti    
1262   XML_DefaultHandler oldDefaultHandler;          
1263   XML_UnparsedEntityDeclHandler oldUnparsedEn    
1264   XML_NotationDeclHandler oldNotationDeclHand    
1265   XML_StartNamespaceDeclHandler oldStartNames    
1266   XML_EndNamespaceDeclHandler oldEndNamespace    
1267   XML_NotStandaloneHandler oldNotStandaloneHa    
1268   XML_ExternalEntityRefHandler oldExternalEnt    
1269   XML_SkippedEntityHandler oldSkippedEntityHa    
1270   XML_UnknownEncodingHandler oldUnknownEncodi    
1271   XML_ElementDeclHandler oldElementDeclHandle    
1272   XML_AttlistDeclHandler oldAttlistDeclHandle    
1273   XML_EntityDeclHandler oldEntityDeclHandler;    
1274   XML_XmlDeclHandler oldXmlDeclHandler;          
1275   ELEMENT_TYPE *oldDeclElementType;              
1276                                                  
1277   void *oldUserData;                             
1278   void *oldHandlerArg;                           
1279   XML_Bool oldDefaultExpandInternalEntities;     
1280   XML_Parser oldExternalEntityRefHandlerArg;     
1281 #ifdef XML_DTD                                   
1282   enum XML_ParamEntityParsing oldParamEntityP    
1283   int oldInEntityValue;                          
1284 #endif                                           
1285   XML_Bool oldns_triplets;                       
1286   /* Note that the new parser shares the same    
1287      parser, so that dtdCopy and copyEntityTa    
1288      from hash tables associated with either     
1289      to worry which hash secrets each table h    
1290   */                                             
1291   unsigned long oldhash_secret_salt;             
1292                                                  
1293   /* Validate the oldParser parameter before     
1294   if (oldParser == NULL)                         
1295     return NULL;                                 
1296                                                  
1297   /* Stash the original parser contents on th    
1298   oldDtd = parser->m_dtd;                        
1299   oldStartElementHandler = parser->m_startEle    
1300   oldEndElementHandler = parser->m_endElement    
1301   oldCharacterDataHandler = parser->m_charact    
1302   oldProcessingInstructionHandler = parser->m    
1303   oldCommentHandler = parser->m_commentHandle    
1304   oldStartCdataSectionHandler = parser->m_sta    
1305   oldEndCdataSectionHandler = parser->m_endCd    
1306   oldDefaultHandler = parser->m_defaultHandle    
1307   oldUnparsedEntityDeclHandler = parser->m_un    
1308   oldNotationDeclHandler = parser->m_notation    
1309   oldStartNamespaceDeclHandler = parser->m_st    
1310   oldEndNamespaceDeclHandler = parser->m_endN    
1311   oldNotStandaloneHandler = parser->m_notStan    
1312   oldExternalEntityRefHandler = parser->m_ext    
1313   oldSkippedEntityHandler = parser->m_skipped    
1314   oldUnknownEncodingHandler = parser->m_unkno    
1315   oldElementDeclHandler = parser->m_elementDe    
1316   oldAttlistDeclHandler = parser->m_attlistDe    
1317   oldEntityDeclHandler = parser->m_entityDecl    
1318   oldXmlDeclHandler = parser->m_xmlDeclHandle    
1319   oldDeclElementType = parser->m_declElementT    
1320                                                  
1321   oldUserData = parser->m_userData;              
1322   oldHandlerArg = parser->m_handlerArg;          
1323   oldDefaultExpandInternalEntities = parser->    
1324   oldExternalEntityRefHandlerArg = parser->m_    
1325 #ifdef XML_DTD                                   
1326   oldParamEntityParsing = parser->m_paramEnti    
1327   oldInEntityValue = parser->m_prologState.in    
1328 #endif                                           
1329   oldns_triplets = parser->m_ns_triplets;        
1330   /* Note that the new parser shares the same    
1331      parser, so that dtdCopy and copyEntityTa    
1332      from hash tables associated with either     
1333      to worry which hash secrets each table h    
1334   */                                             
1335   oldhash_secret_salt = parser->m_hash_secret    
1336                                                  
1337 #ifdef XML_DTD                                   
1338   if (! context)                                 
1339     newDtd = oldDtd;                             
1340 #endif /* XML_DTD */                             
1341                                                  
1342   /* Note that the magical uses of the pre-pr    
1343      access look more like C++ require that `    
1344      here.  This makes this function more pai    
1345      would be otherwise.                         
1346   */                                             
1347   if (parser->m_ns) {                            
1348     XML_Char tmp[2] = {parser->m_namespaceSep    
1349     parser = parserCreate(encodingName, &pars    
1350   } else {                                       
1351     parser = parserCreate(encodingName, &pars    
1352   }                                              
1353                                                  
1354   if (! parser)                                  
1355     return NULL;                                 
1356                                                  
1357   parser->m_startElementHandler = oldStartEle    
1358   parser->m_endElementHandler = oldEndElement    
1359   parser->m_characterDataHandler = oldCharact    
1360   parser->m_processingInstructionHandler = ol    
1361   parser->m_commentHandler = oldCommentHandle    
1362   parser->m_startCdataSectionHandler = oldSta    
1363   parser->m_endCdataSectionHandler = oldEndCd    
1364   parser->m_defaultHandler = oldDefaultHandle    
1365   parser->m_unparsedEntityDeclHandler = oldUn    
1366   parser->m_notationDeclHandler = oldNotation    
1367   parser->m_startNamespaceDeclHandler = oldSt    
1368   parser->m_endNamespaceDeclHandler = oldEndN    
1369   parser->m_notStandaloneHandler = oldNotStan    
1370   parser->m_externalEntityRefHandler = oldExt    
1371   parser->m_skippedEntityHandler = oldSkipped    
1372   parser->m_unknownEncodingHandler = oldUnkno    
1373   parser->m_elementDeclHandler = oldElementDe    
1374   parser->m_attlistDeclHandler = oldAttlistDe    
1375   parser->m_entityDeclHandler = oldEntityDecl    
1376   parser->m_xmlDeclHandler = oldXmlDeclHandle    
1377   parser->m_declElementType = oldDeclElementT    
1378   parser->m_userData = oldUserData;              
1379   if (oldUserData == oldHandlerArg)              
1380     parser->m_handlerArg = parser->m_userData    
1381   else                                           
1382     parser->m_handlerArg = parser;               
1383   if (oldExternalEntityRefHandlerArg != oldPa    
1384     parser->m_externalEntityRefHandlerArg = o    
1385   parser->m_defaultExpandInternalEntities = o    
1386   parser->m_ns_triplets = oldns_triplets;        
1387   parser->m_hash_secret_salt = oldhash_secret    
1388   parser->m_parentParser = oldParser;            
1389 #ifdef XML_DTD                                   
1390   parser->m_paramEntityParsing = oldParamEnti    
1391   parser->m_prologState.inEntityValue = oldIn    
1392   if (context) {                                 
1393 #endif /* XML_DTD */                             
1394     if (! dtdCopy(oldParser, parser->m_dtd, o    
1395         || ! setContext(parser, context)) {      
1396       XML_ParserFree(parser);                    
1397       return NULL;                               
1398     }                                            
1399     parser->m_processor = externalEntityInitP    
1400 #ifdef XML_DTD                                   
1401   } else {                                       
1402     /* The DTD instance referenced by parser-    
1403        document's root parser and external PE    
1404        need to call setContext. In addition,     
1405        setContext, because this would overwri    
1406        pointers in parser->m_dtd with ones th    
1407        PE parser. This would leave those pref    
1408     */                                           
1409     parser->m_isParamEntity = XML_TRUE;          
1410     XmlPrologStateInitExternalEntity(&parser-    
1411     parser->m_processor = externalParEntInitP    
1412   }                                              
1413 #endif /* XML_DTD */                             
1414   return parser;                                 
1415 }                                                
1416                                                  
1417 static void FASTCALL                             
1418 destroyBindings(BINDING *bindings, XML_Parser    
1419   for (;;) {                                     
1420     BINDING *b = bindings;                       
1421     if (! b)                                     
1422       break;                                     
1423     bindings = b->nextTagBinding;                
1424     FREE(parser, b->uri);                        
1425     FREE(parser, b);                             
1426   }                                              
1427 }                                                
1428                                                  
1429 void XMLCALL                                     
1430 XML_ParserFree(XML_Parser parser) {              
1431   TAG *tagList;                                  
1432   OPEN_INTERNAL_ENTITY *entityList;              
1433   if (parser == NULL)                            
1434     return;                                      
1435   /* free m_tagStack and m_freeTagList */        
1436   tagList = parser->m_tagStack;                  
1437   for (;;) {                                     
1438     TAG *p;                                      
1439     if (tagList == NULL) {                       
1440       if (parser->m_freeTagList == NULL)         
1441         break;                                   
1442       tagList = parser->m_freeTagList;           
1443       parser->m_freeTagList = NULL;              
1444     }                                            
1445     p = tagList;                                 
1446     tagList = tagList->parent;                   
1447     FREE(parser, p->buf);                        
1448     destroyBindings(p->bindings, parser);        
1449     FREE(parser, p);                             
1450   }                                              
1451   /* free m_openInternalEntities and m_freeIn    
1452   entityList = parser->m_openInternalEntities    
1453   for (;;) {                                     
1454     OPEN_INTERNAL_ENTITY *openEntity;            
1455     if (entityList == NULL) {                    
1456       if (parser->m_freeInternalEntities == N    
1457         break;                                   
1458       entityList = parser->m_freeInternalEnti    
1459       parser->m_freeInternalEntities = NULL;     
1460     }                                            
1461     openEntity = entityList;                     
1462     entityList = entityList->next;               
1463     FREE(parser, openEntity);                    
1464   }                                              
1465                                                  
1466   destroyBindings(parser->m_freeBindingList,     
1467   destroyBindings(parser->m_inheritedBindings    
1468   poolDestroy(&parser->m_tempPool);              
1469   poolDestroy(&parser->m_temp2Pool);             
1470   FREE(parser, (void *)parser->m_protocolEnco    
1471 #ifdef XML_DTD                                   
1472   /* external parameter entity parsers share     
1473      parser->m_dtd with the root parser, so w    
1474   */                                             
1475   if (! parser->m_isParamEntity && parser->m_    
1476 #else                                            
1477   if (parser->m_dtd)                             
1478 #endif /* XML_DTD */                             
1479     dtdDestroy(parser->m_dtd, (XML_Bool)! par    
1480                &parser->m_mem);                  
1481   FREE(parser, (void *)parser->m_atts);          
1482 #ifdef XML_ATTR_INFO                             
1483   FREE(parser, (void *)parser->m_attInfo);       
1484 #endif                                           
1485   FREE(parser, parser->m_groupConnector);        
1486   FREE(parser, parser->m_buffer);                
1487   FREE(parser, parser->m_dataBuf);               
1488   FREE(parser, parser->m_nsAtts);                
1489   FREE(parser, parser->m_unknownEncodingMem);    
1490   if (parser->m_unknownEncodingRelease)          
1491     parser->m_unknownEncodingRelease(parser->    
1492   FREE(parser, parser);                          
1493 }                                                
1494                                                  
1495 void XMLCALL                                     
1496 XML_UseParserAsHandlerArg(XML_Parser parser)     
1497   if (parser != NULL)                            
1498     parser->m_handlerArg = parser;               
1499 }                                                
1500                                                  
1501 enum XML_Error XMLCALL                           
1502 XML_UseForeignDTD(XML_Parser parser, XML_Bool    
1503   if (parser == NULL)                            
1504     return XML_ERROR_INVALID_ARGUMENT;           
1505 #ifdef XML_DTD                                   
1506   /* block after XML_Parse()/XML_ParseBuffer(    
1507   if (parser->m_parsingStatus.parsing == XML_    
1508       || parser->m_parsingStatus.parsing == X    
1509     return XML_ERROR_CANT_CHANGE_FEATURE_ONCE    
1510   parser->m_useForeignDTD = useDTD;              
1511   return XML_ERROR_NONE;                         
1512 #else                                            
1513   UNUSED_P(useDTD);                              
1514   return XML_ERROR_FEATURE_REQUIRES_XML_DTD;     
1515 #endif                                           
1516 }                                                
1517                                                  
1518 void XMLCALL                                     
1519 XML_SetReturnNSTriplet(XML_Parser parser, int    
1520   if (parser == NULL)                            
1521     return;                                      
1522   /* block after XML_Parse()/XML_ParseBuffer(    
1523   if (parser->m_parsingStatus.parsing == XML_    
1524       || parser->m_parsingStatus.parsing == X    
1525     return;                                      
1526   parser->m_ns_triplets = do_nst ? XML_TRUE :    
1527 }                                                
1528                                                  
1529 void XMLCALL                                     
1530 XML_SetUserData(XML_Parser parser, void *p) {    
1531   if (parser == NULL)                            
1532     return;                                      
1533   if (parser->m_handlerArg == parser->m_userD    
1534     parser->m_handlerArg = parser->m_userData    
1535   else                                           
1536     parser->m_userData = p;                      
1537 }                                                
1538                                                  
1539 enum XML_Status XMLCALL                          
1540 XML_SetBase(XML_Parser parser, const XML_Char    
1541   if (parser == NULL)                            
1542     return XML_STATUS_ERROR;                     
1543   if (p) {                                       
1544     p = poolCopyString(&parser->m_dtd->pool,     
1545     if (! p)                                     
1546       return XML_STATUS_ERROR;                   
1547     parser->m_curBase = p;                       
1548   } else                                         
1549     parser->m_curBase = NULL;                    
1550   return XML_STATUS_OK;                          
1551 }                                                
1552                                                  
1553 const XML_Char *XMLCALL                          
1554 XML_GetBase(XML_Parser parser) {                 
1555   if (parser == NULL)                            
1556     return NULL;                                 
1557   return parser->m_curBase;                      
1558 }                                                
1559                                                  
1560 int XMLCALL                                      
1561 XML_GetSpecifiedAttributeCount(XML_Parser par    
1562   if (parser == NULL)                            
1563     return -1;                                   
1564   return parser->m_nSpecifiedAtts;               
1565 }                                                
1566                                                  
1567 int XMLCALL                                      
1568 XML_GetIdAttributeIndex(XML_Parser parser) {     
1569   if (parser == NULL)                            
1570     return -1;                                   
1571   return parser->m_idAttIndex;                   
1572 }                                                
1573                                                  
1574 #ifdef XML_ATTR_INFO                             
1575 const XML_AttrInfo *XMLCALL                      
1576 XML_GetAttributeInfo(XML_Parser parser) {        
1577   if (parser == NULL)                            
1578     return NULL;                                 
1579   return parser->m_attInfo;                      
1580 }                                                
1581 #endif                                           
1582                                                  
1583 void XMLCALL                                     
1584 XML_SetElementHandler(XML_Parser parser, XML_    
1585                       XML_EndElementHandler e    
1586   if (parser == NULL)                            
1587     return;                                      
1588   parser->m_startElementHandler = start;         
1589   parser->m_endElementHandler = end;             
1590 }                                                
1591                                                  
1592 void XMLCALL                                     
1593 XML_SetStartElementHandler(XML_Parser parser,    
1594   if (parser != NULL)                            
1595     parser->m_startElementHandler = start;       
1596 }                                                
1597                                                  
1598 void XMLCALL                                     
1599 XML_SetEndElementHandler(XML_Parser parser, X    
1600   if (parser != NULL)                            
1601     parser->m_endElementHandler = end;           
1602 }                                                
1603                                                  
1604 void XMLCALL                                     
1605 XML_SetCharacterDataHandler(XML_Parser parser    
1606                             XML_CharacterData    
1607   if (parser != NULL)                            
1608     parser->m_characterDataHandler = handler;    
1609 }                                                
1610                                                  
1611 void XMLCALL                                     
1612 XML_SetProcessingInstructionHandler(XML_Parse    
1613                                     XML_Proce    
1614   if (parser != NULL)                            
1615     parser->m_processingInstructionHandler =     
1616 }                                                
1617                                                  
1618 void XMLCALL                                     
1619 XML_SetCommentHandler(XML_Parser parser, XML_    
1620   if (parser != NULL)                            
1621     parser->m_commentHandler = handler;          
1622 }                                                
1623                                                  
1624 void XMLCALL                                     
1625 XML_SetCdataSectionHandler(XML_Parser parser,    
1626                            XML_StartCdataSect    
1627                            XML_EndCdataSectio    
1628   if (parser == NULL)                            
1629     return;                                      
1630   parser->m_startCdataSectionHandler = start;    
1631   parser->m_endCdataSectionHandler = end;        
1632 }                                                
1633                                                  
1634 void XMLCALL                                     
1635 XML_SetStartCdataSectionHandler(XML_Parser pa    
1636                                 XML_StartCdat    
1637   if (parser != NULL)                            
1638     parser->m_startCdataSectionHandler = star    
1639 }                                                
1640                                                  
1641 void XMLCALL                                     
1642 XML_SetEndCdataSectionHandler(XML_Parser pars    
1643                               XML_EndCdataSec    
1644   if (parser != NULL)                            
1645     parser->m_endCdataSectionHandler = end;      
1646 }                                                
1647                                                  
1648 void XMLCALL                                     
1649 XML_SetDefaultHandler(XML_Parser parser, XML_    
1650   if (parser == NULL)                            
1651     return;                                      
1652   parser->m_defaultHandler = handler;            
1653   parser->m_defaultExpandInternalEntities = X    
1654 }                                                
1655                                                  
1656 void XMLCALL                                     
1657 XML_SetDefaultHandlerExpand(XML_Parser parser    
1658   if (parser == NULL)                            
1659     return;                                      
1660   parser->m_defaultHandler = handler;            
1661   parser->m_defaultExpandInternalEntities = X    
1662 }                                                
1663                                                  
1664 void XMLCALL                                     
1665 XML_SetDoctypeDeclHandler(XML_Parser parser,     
1666                           XML_EndDoctypeDeclH    
1667   if (parser == NULL)                            
1668     return;                                      
1669   parser->m_startDoctypeDeclHandler = start;     
1670   parser->m_endDoctypeDeclHandler = end;         
1671 }                                                
1672                                                  
1673 void XMLCALL                                     
1674 XML_SetStartDoctypeDeclHandler(XML_Parser par    
1675                                XML_StartDocty    
1676   if (parser != NULL)                            
1677     parser->m_startDoctypeDeclHandler = start    
1678 }                                                
1679                                                  
1680 void XMLCALL                                     
1681 XML_SetEndDoctypeDeclHandler(XML_Parser parse    
1682   if (parser != NULL)                            
1683     parser->m_endDoctypeDeclHandler = end;       
1684 }                                                
1685                                                  
1686 void XMLCALL                                     
1687 XML_SetUnparsedEntityDeclHandler(XML_Parser p    
1688                                  XML_Unparsed    
1689   if (parser != NULL)                            
1690     parser->m_unparsedEntityDeclHandler = han    
1691 }                                                
1692                                                  
1693 void XMLCALL                                     
1694 XML_SetNotationDeclHandler(XML_Parser parser,    
1695   if (parser != NULL)                            
1696     parser->m_notationDeclHandler = handler;     
1697 }                                                
1698                                                  
1699 void XMLCALL                                     
1700 XML_SetNamespaceDeclHandler(XML_Parser parser    
1701                             XML_StartNamespac    
1702                             XML_EndNamespaceD    
1703   if (parser == NULL)                            
1704     return;                                      
1705   parser->m_startNamespaceDeclHandler = start    
1706   parser->m_endNamespaceDeclHandler = end;       
1707 }                                                
1708                                                  
1709 void XMLCALL                                     
1710 XML_SetStartNamespaceDeclHandler(XML_Parser p    
1711                                  XML_StartNam    
1712   if (parser != NULL)                            
1713     parser->m_startNamespaceDeclHandler = sta    
1714 }                                                
1715                                                  
1716 void XMLCALL                                     
1717 XML_SetEndNamespaceDeclHandler(XML_Parser par    
1718                                XML_EndNamespa    
1719   if (parser != NULL)                            
1720     parser->m_endNamespaceDeclHandler = end;     
1721 }                                                
1722                                                  
1723 void XMLCALL                                     
1724 XML_SetNotStandaloneHandler(XML_Parser parser    
1725                             XML_NotStandalone    
1726   if (parser != NULL)                            
1727     parser->m_notStandaloneHandler = handler;    
1728 }                                                
1729                                                  
1730 void XMLCALL                                     
1731 XML_SetExternalEntityRefHandler(XML_Parser pa    
1732                                 XML_ExternalE    
1733   if (parser != NULL)                            
1734     parser->m_externalEntityRefHandler = hand    
1735 }                                                
1736                                                  
1737 void XMLCALL                                     
1738 XML_SetExternalEntityRefHandlerArg(XML_Parser    
1739   if (parser == NULL)                            
1740     return;                                      
1741   if (arg)                                       
1742     parser->m_externalEntityRefHandlerArg = (    
1743   else                                           
1744     parser->m_externalEntityRefHandlerArg = p    
1745 }                                                
1746                                                  
1747 void XMLCALL                                     
1748 XML_SetSkippedEntityHandler(XML_Parser parser    
1749                             XML_SkippedEntity    
1750   if (parser != NULL)                            
1751     parser->m_skippedEntityHandler = handler;    
1752 }                                                
1753                                                  
1754 void XMLCALL                                     
1755 XML_SetUnknownEncodingHandler(XML_Parser pars    
1756                               XML_UnknownEnco    
1757   if (parser == NULL)                            
1758     return;                                      
1759   parser->m_unknownEncodingHandler = handler;    
1760   parser->m_unknownEncodingHandlerData = data    
1761 }                                                
1762                                                  
1763 void XMLCALL                                     
1764 XML_SetElementDeclHandler(XML_Parser parser,     
1765   if (parser != NULL)                            
1766     parser->m_elementDeclHandler = eldecl;       
1767 }                                                
1768                                                  
1769 void XMLCALL                                     
1770 XML_SetAttlistDeclHandler(XML_Parser parser,     
1771   if (parser != NULL)                            
1772     parser->m_attlistDeclHandler = attdecl;      
1773 }                                                
1774                                                  
1775 void XMLCALL                                     
1776 XML_SetEntityDeclHandler(XML_Parser parser, X    
1777   if (parser != NULL)                            
1778     parser->m_entityDeclHandler = handler;       
1779 }                                                
1780                                                  
1781 void XMLCALL                                     
1782 XML_SetXmlDeclHandler(XML_Parser parser, XML_    
1783   if (parser != NULL)                            
1784     parser->m_xmlDeclHandler = handler;          
1785 }                                                
1786                                                  
1787 int XMLCALL                                      
1788 XML_SetParamEntityParsing(XML_Parser parser,     
1789                           enum XML_ParamEntit    
1790   if (parser == NULL)                            
1791     return 0;                                    
1792   /* block after XML_Parse()/XML_ParseBuffer(    
1793   if (parser->m_parsingStatus.parsing == XML_    
1794       || parser->m_parsingStatus.parsing == X    
1795     return 0;                                    
1796 #ifdef XML_DTD                                   
1797   parser->m_paramEntityParsing = peParsing;      
1798   return 1;                                      
1799 #else                                            
1800   return peParsing == XML_PARAM_ENTITY_PARSIN    
1801 #endif                                           
1802 }                                                
1803                                                  
1804 int XMLCALL                                      
1805 XML_SetHashSalt(XML_Parser parser, unsigned l    
1806   if (parser == NULL)                            
1807     return 0;                                    
1808   if (parser->m_parentParser)                    
1809     return XML_SetHashSalt(parser->m_parentPa    
1810   /* block after XML_Parse()/XML_ParseBuffer(    
1811   if (parser->m_parsingStatus.parsing == XML_    
1812       || parser->m_parsingStatus.parsing == X    
1813     return 0;                                    
1814   parser->m_hash_secret_salt = hash_salt;        
1815   return 1;                                      
1816 }                                                
1817                                                  
1818 enum XML_Status XMLCALL                          
1819 XML_Parse(XML_Parser parser, const char *s, i    
1820   if ((parser == NULL) || (len < 0) || ((s ==    
1821     if (parser != NULL)                          
1822       parser->m_errorCode = XML_ERROR_INVALID    
1823     return XML_STATUS_ERROR;                     
1824   }                                              
1825   switch (parser->m_parsingStatus.parsing) {     
1826   case XML_SUSPENDED:                            
1827     parser->m_errorCode = XML_ERROR_SUSPENDED    
1828     return XML_STATUS_ERROR;                     
1829   case XML_FINISHED:                             
1830     parser->m_errorCode = XML_ERROR_FINISHED;    
1831     return XML_STATUS_ERROR;                     
1832   case XML_INITIALIZED:                          
1833     if (parser->m_parentParser == NULL && ! s    
1834       parser->m_errorCode = XML_ERROR_NO_MEMO    
1835       return XML_STATUS_ERROR;                   
1836     }                                            
1837     /* fall through */                           
1838   default:                                       
1839     parser->m_parsingStatus.parsing = XML_PAR    
1840   }                                              
1841                                                  
1842   if (len == 0) {                                
1843     parser->m_parsingStatus.finalBuffer = (XM    
1844     if (! isFinal)                               
1845       return XML_STATUS_OK;                      
1846     parser->m_positionPtr = parser->m_bufferP    
1847     parser->m_parseEndPtr = parser->m_bufferE    
1848                                                  
1849     /* If data are left over from last buffer    
1850        data are the final chunk of input, the    
1851        to detect errors based on that fact.      
1852     */                                           
1853     parser->m_errorCode                          
1854         = parser->m_processor(parser, parser-    
1855                               parser->m_parse    
1856                                                  
1857     if (parser->m_errorCode == XML_ERROR_NONE    
1858       switch (parser->m_parsingStatus.parsing    
1859       case XML_SUSPENDED:                        
1860         /* It is hard to be certain, but it s    
1861          * cannot occur.  This code is cleani    
1862          * with no new data (since len == 0).    
1863          * state requires getting to execute     
1864          * there doesn't seem to be an opport    
1865          * this circumstance.                    
1866          *                                       
1867          * Given the uncertainty, we retain t    
1868          * from coverage tests.                  
1869          *                                       
1870          * LCOV_EXCL_START                       
1871          */                                      
1872         XmlUpdatePosition(parser->m_encoding,    
1873                           parser->m_bufferPtr    
1874         parser->m_positionPtr = parser->m_buf    
1875         return XML_STATUS_SUSPENDED;             
1876         /* LCOV_EXCL_STOP */                     
1877       case XML_INITIALIZED:                      
1878       case XML_PARSING:                          
1879         parser->m_parsingStatus.parsing = XML    
1880         /* fall through */                       
1881       default:                                   
1882         return XML_STATUS_OK;                    
1883       }                                          
1884     }                                            
1885     parser->m_eventEndPtr = parser->m_eventPt    
1886     parser->m_processor = errorProcessor;        
1887     return XML_STATUS_ERROR;                     
1888   }                                              
1889 #ifndef XML_CONTEXT_BYTES                        
1890   else if (parser->m_bufferPtr == parser->m_b    
1891     const char *end;                             
1892     int nLeftOver;                               
1893     enum XML_Status result;                      
1894     /* Detect overflow (a+b > MAX <==> b > MA    
1895     if ((XML_Size)len > ((XML_Size)-1) / 2 -     
1896       parser->m_errorCode = XML_ERROR_NO_MEMO    
1897       parser->m_eventPtr = parser->m_eventEnd    
1898       parser->m_processor = errorProcessor;      
1899       return XML_STATUS_ERROR;                   
1900     }                                            
1901     parser->m_parseEndByteIndex += len;          
1902     parser->m_positionPtr = s;                   
1903     parser->m_parsingStatus.finalBuffer = (XM    
1904                                                  
1905     parser->m_errorCode                          
1906         = parser->m_processor(parser, s, pars    
1907                                                  
1908     if (parser->m_errorCode != XML_ERROR_NONE    
1909       parser->m_eventEndPtr = parser->m_event    
1910       parser->m_processor = errorProcessor;      
1911       return XML_STATUS_ERROR;                   
1912     } else {                                     
1913       switch (parser->m_parsingStatus.parsing    
1914       case XML_SUSPENDED:                        
1915         result = XML_STATUS_SUSPENDED;           
1916         break;                                   
1917       case XML_INITIALIZED:                      
1918       case XML_PARSING:                          
1919         if (isFinal) {                           
1920           parser->m_parsingStatus.parsing = X    
1921           return XML_STATUS_OK;                  
1922         }                                        
1923       /* fall through */                         
1924       default:                                   
1925         result = XML_STATUS_OK;                  
1926       }                                          
1927     }                                            
1928                                                  
1929     XmlUpdatePosition(parser->m_encoding, par    
1930                       &parser->m_position);      
1931     nLeftOver = s + len - end;                   
1932     if (nLeftOver) {                             
1933       if (parser->m_buffer == NULL               
1934           || nLeftOver > parser->m_bufferLim     
1935         /* avoid _signed_ integer overflow */    
1936         char *temp = NULL;                       
1937         const int bytesToAllocate = (int)((un    
1938         if (bytesToAllocate > 0) {               
1939           temp = (char *)REALLOC(parser, pars    
1940         }                                        
1941         if (temp == NULL) {                      
1942           parser->m_errorCode = XML_ERROR_NO_    
1943           parser->m_eventPtr = parser->m_even    
1944           parser->m_processor = errorProcesso    
1945           return XML_STATUS_ERROR;               
1946         }                                        
1947         parser->m_buffer = temp;                 
1948         parser->m_bufferLim = parser->m_buffe    
1949       }                                          
1950       memcpy(parser->m_buffer, end, nLeftOver    
1951     }                                            
1952     parser->m_bufferPtr = parser->m_buffer;      
1953     parser->m_bufferEnd = parser->m_buffer +     
1954     parser->m_positionPtr = parser->m_bufferP    
1955     parser->m_parseEndPtr = parser->m_bufferE    
1956     parser->m_eventPtr = parser->m_bufferPtr;    
1957     parser->m_eventEndPtr = parser->m_bufferP    
1958     return result;                               
1959   }                                              
1960 #endif /* not defined XML_CONTEXT_BYTES */       
1961   else {                                         
1962     void *buff = XML_GetBuffer(parser, len);     
1963     if (buff == NULL)                            
1964       return XML_STATUS_ERROR;                   
1965     else {                                       
1966       memcpy(buff, s, len);                      
1967       return XML_ParseBuffer(parser, len, isF    
1968     }                                            
1969   }                                              
1970 }                                                
1971                                                  
1972 enum XML_Status XMLCALL                          
1973 XML_ParseBuffer(XML_Parser parser, int len, i    
1974   const char *start;                             
1975   enum XML_Status result = XML_STATUS_OK;        
1976                                                  
1977   if (parser == NULL)                            
1978     return XML_STATUS_ERROR;                     
1979   switch (parser->m_parsingStatus.parsing) {     
1980   case XML_SUSPENDED:                            
1981     parser->m_errorCode = XML_ERROR_SUSPENDED    
1982     return XML_STATUS_ERROR;                     
1983   case XML_FINISHED:                             
1984     parser->m_errorCode = XML_ERROR_FINISHED;    
1985     return XML_STATUS_ERROR;                     
1986   case XML_INITIALIZED:                          
1987     /* Has someone called XML_GetBuffer succe    
1988     if (! parser->m_bufferPtr) {                 
1989       parser->m_errorCode = XML_ERROR_NO_BUFF    
1990       return XML_STATUS_ERROR;                   
1991     }                                            
1992                                                  
1993     if (parser->m_parentParser == NULL && ! s    
1994       parser->m_errorCode = XML_ERROR_NO_MEMO    
1995       return XML_STATUS_ERROR;                   
1996     }                                            
1997     /* fall through */                           
1998   default:                                       
1999     parser->m_parsingStatus.parsing = XML_PAR    
2000   }                                              
2001                                                  
2002   start = parser->m_bufferPtr;                   
2003   parser->m_positionPtr = start;                 
2004   parser->m_bufferEnd += len;                    
2005   parser->m_parseEndPtr = parser->m_bufferEnd    
2006   parser->m_parseEndByteIndex += len;            
2007   parser->m_parsingStatus.finalBuffer = (XML_    
2008                                                  
2009   parser->m_errorCode = parser->m_processor(     
2010       parser, start, parser->m_parseEndPtr, &    
2011                                                  
2012   if (parser->m_errorCode != XML_ERROR_NONE)     
2013     parser->m_eventEndPtr = parser->m_eventPt    
2014     parser->m_processor = errorProcessor;        
2015     return XML_STATUS_ERROR;                     
2016   } else {                                       
2017     switch (parser->m_parsingStatus.parsing)     
2018     case XML_SUSPENDED:                          
2019       result = XML_STATUS_SUSPENDED;             
2020       break;                                     
2021     case XML_INITIALIZED:                        
2022     case XML_PARSING:                            
2023       if (isFinal) {                             
2024         parser->m_parsingStatus.parsing = XML    
2025         return result;                           
2026       }                                          
2027     default:; /* should not happen */            
2028     }                                            
2029   }                                              
2030                                                  
2031   XmlUpdatePosition(parser->m_encoding, parse    
2032                     parser->m_bufferPtr, &par    
2033   parser->m_positionPtr = parser->m_bufferPtr    
2034   return result;                                 
2035 }                                                
2036                                                  
2037 void *XMLCALL                                    
2038 XML_GetBuffer(XML_Parser parser, int len) {      
2039   if (parser == NULL)                            
2040     return NULL;                                 
2041   if (len < 0) {                                 
2042     parser->m_errorCode = XML_ERROR_NO_MEMORY    
2043     return NULL;                                 
2044   }                                              
2045   switch (parser->m_parsingStatus.parsing) {     
2046   case XML_SUSPENDED:                            
2047     parser->m_errorCode = XML_ERROR_SUSPENDED    
2048     return NULL;                                 
2049   case XML_FINISHED:                             
2050     parser->m_errorCode = XML_ERROR_FINISHED;    
2051     return NULL;                                 
2052   default:;                                      
2053   }                                              
2054                                                  
2055   if (len > EXPAT_SAFE_PTR_DIFF(parser->m_buf    
2056 #ifdef XML_CONTEXT_BYTES                         
2057     int keep;                                    
2058 #endif /* defined XML_CONTEXT_BYTES */           
2059     /* Do not invoke signed arithmetic overfl    
2060     int neededSize = (int)((unsigned)len         
2061                            + (unsigned)EXPAT_    
2062                                parser->m_buff    
2063     if (neededSize < 0) {                        
2064       parser->m_errorCode = XML_ERROR_NO_MEMO    
2065       return NULL;                               
2066     }                                            
2067 #ifdef XML_CONTEXT_BYTES                         
2068     keep = (int)EXPAT_SAFE_PTR_DIFF(parser->m    
2069     if (keep > XML_CONTEXT_BYTES)                
2070       keep = XML_CONTEXT_BYTES;                  
2071     /* Detect and prevent integer overflow */    
2072     if (keep > INT_MAX - neededSize) {           
2073       parser->m_errorCode = XML_ERROR_NO_MEMO    
2074       return NULL;                               
2075     }                                            
2076     neededSize += keep;                          
2077 #endif /* defined XML_CONTEXT_BYTES */           
2078     if (neededSize                               
2079         <= EXPAT_SAFE_PTR_DIFF(parser->m_buff    
2080 #ifdef XML_CONTEXT_BYTES                         
2081       if (keep < EXPAT_SAFE_PTR_DIFF(parser->    
2082         int offset                               
2083             = (int)EXPAT_SAFE_PTR_DIFF(parser    
2084               - keep;                            
2085         /* The buffer pointers cannot be NULL    
2086          * in the buffer */                      
2087         memmove(parser->m_buffer, &parser->m_    
2088                 parser->m_bufferEnd - parser-    
2089         parser->m_bufferEnd -= offset;           
2090         parser->m_bufferPtr -= offset;           
2091       }                                          
2092 #else                                            
2093       if (parser->m_buffer && parser->m_buffe    
2094         memmove(parser->m_buffer, parser->m_b    
2095                 EXPAT_SAFE_PTR_DIFF(parser->m    
2096         parser->m_bufferEnd                      
2097             = parser->m_buffer                   
2098               + EXPAT_SAFE_PTR_DIFF(parser->m    
2099         parser->m_bufferPtr = parser->m_buffe    
2100       }                                          
2101 #endif /* not defined XML_CONTEXT_BYTES */       
2102     } else {                                     
2103       char *newBuf;                              
2104       int bufferSize                             
2105           = (int)EXPAT_SAFE_PTR_DIFF(parser->    
2106       if (bufferSize == 0)                       
2107         bufferSize = INIT_BUFFER_SIZE;           
2108       do {                                       
2109         /* Do not invoke signed arithmetic ov    
2110         bufferSize = (int)(2U * (unsigned)buf    
2111       } while (bufferSize < neededSize && buf    
2112       if (bufferSize <= 0) {                     
2113         parser->m_errorCode = XML_ERROR_NO_ME    
2114         return NULL;                             
2115       }                                          
2116       newBuf = (char *)MALLOC(parser, bufferS    
2117       if (newBuf == 0) {                         
2118         parser->m_errorCode = XML_ERROR_NO_ME    
2119         return NULL;                             
2120       }                                          
2121       parser->m_bufferLim = newBuf + bufferSi    
2122 #ifdef XML_CONTEXT_BYTES                         
2123       if (parser->m_bufferPtr) {                 
2124         memcpy(newBuf, &parser->m_bufferPtr[-    
2125                EXPAT_SAFE_PTR_DIFF(parser->m_    
2126                    + keep);                      
2127         FREE(parser, parser->m_buffer);          
2128         parser->m_buffer = newBuf;               
2129         parser->m_bufferEnd                      
2130             = parser->m_buffer                   
2131               + EXPAT_SAFE_PTR_DIFF(parser->m    
2132               + keep;                            
2133         parser->m_bufferPtr = parser->m_buffe    
2134       } else {                                   
2135         /* This must be a brand new buffer wi    
2136         parser->m_bufferEnd = newBuf;            
2137         parser->m_bufferPtr = parser->m_buffe    
2138       }                                          
2139 #else                                            
2140       if (parser->m_bufferPtr) {                 
2141         memcpy(newBuf, parser->m_bufferPtr,      
2142                EXPAT_SAFE_PTR_DIFF(parser->m_    
2143         FREE(parser, parser->m_buffer);          
2144         parser->m_bufferEnd                      
2145             = newBuf                             
2146               + EXPAT_SAFE_PTR_DIFF(parser->m    
2147       } else {                                   
2148         /* This must be a brand new buffer wi    
2149         parser->m_bufferEnd = newBuf;            
2150       }                                          
2151       parser->m_bufferPtr = parser->m_buffer     
2152 #endif /* not defined XML_CONTEXT_BYTES */       
2153     }                                            
2154     parser->m_eventPtr = parser->m_eventEndPt    
2155     parser->m_positionPtr = NULL;                
2156   }                                              
2157   return parser->m_bufferEnd;                    
2158 }                                                
2159                                                  
2160 enum XML_Status XMLCALL                          
2161 XML_StopParser(XML_Parser parser, XML_Bool re    
2162   if (parser == NULL)                            
2163     return XML_STATUS_ERROR;                     
2164   switch (parser->m_parsingStatus.parsing) {     
2165   case XML_SUSPENDED:                            
2166     if (resumable) {                             
2167       parser->m_errorCode = XML_ERROR_SUSPEND    
2168       return XML_STATUS_ERROR;                   
2169     }                                            
2170     parser->m_parsingStatus.parsing = XML_FIN    
2171     break;                                       
2172   case XML_FINISHED:                             
2173     parser->m_errorCode = XML_ERROR_FINISHED;    
2174     return XML_STATUS_ERROR;                     
2175   default:                                       
2176     if (resumable) {                             
2177 #ifdef XML_DTD                                   
2178       if (parser->m_isParamEntity) {             
2179         parser->m_errorCode = XML_ERROR_SUSPE    
2180         return XML_STATUS_ERROR;                 
2181       }                                          
2182 #endif                                           
2183       parser->m_parsingStatus.parsing = XML_S    
2184     } else                                       
2185       parser->m_parsingStatus.parsing = XML_F    
2186   }                                              
2187   return XML_STATUS_OK;                          
2188 }                                                
2189                                                  
2190 enum XML_Status XMLCALL                          
2191 XML_ResumeParser(XML_Parser parser) {            
2192   enum XML_Status result = XML_STATUS_OK;        
2193                                                  
2194   if (parser == NULL)                            
2195     return XML_STATUS_ERROR;                     
2196   if (parser->m_parsingStatus.parsing != XML_    
2197     parser->m_errorCode = XML_ERROR_NOT_SUSPE    
2198     return XML_STATUS_ERROR;                     
2199   }                                              
2200   parser->m_parsingStatus.parsing = XML_PARSI    
2201                                                  
2202   parser->m_errorCode = parser->m_processor(     
2203       parser, parser->m_bufferPtr, parser->m_    
2204                                                  
2205   if (parser->m_errorCode != XML_ERROR_NONE)     
2206     parser->m_eventEndPtr = parser->m_eventPt    
2207     parser->m_processor = errorProcessor;        
2208     return XML_STATUS_ERROR;                     
2209   } else {                                       
2210     switch (parser->m_parsingStatus.parsing)     
2211     case XML_SUSPENDED:                          
2212       result = XML_STATUS_SUSPENDED;             
2213       break;                                     
2214     case XML_INITIALIZED:                        
2215     case XML_PARSING:                            
2216       if (parser->m_parsingStatus.finalBuffer    
2217         parser->m_parsingStatus.parsing = XML    
2218         return result;                           
2219       }                                          
2220     default:;                                    
2221     }                                            
2222   }                                              
2223                                                  
2224   XmlUpdatePosition(parser->m_encoding, parse    
2225                     parser->m_bufferPtr, &par    
2226   parser->m_positionPtr = parser->m_bufferPtr    
2227   return result;                                 
2228 }                                                
2229                                                  
2230 void XMLCALL                                     
2231 XML_GetParsingStatus(XML_Parser parser, XML_P    
2232   if (parser == NULL)                            
2233     return;                                      
2234   assert(status != NULL);                        
2235   *status = parser->m_parsingStatus;             
2236 }                                                
2237                                                  
2238 enum XML_Error XMLCALL                           
2239 XML_GetErrorCode(XML_Parser parser) {            
2240   if (parser == NULL)                            
2241     return XML_ERROR_INVALID_ARGUMENT;           
2242   return parser->m_errorCode;                    
2243 }                                                
2244                                                  
2245 XML_Index XMLCALL                                
2246 XML_GetCurrentByteIndex(XML_Parser parser) {     
2247   if (parser == NULL)                            
2248     return -1;                                   
2249   if (parser->m_eventPtr)                        
2250     return (XML_Index)(parser->m_parseEndByte    
2251                        - (parser->m_parseEndP    
2252   return -1;                                     
2253 }                                                
2254                                                  
2255 int XMLCALL                                      
2256 XML_GetCurrentByteCount(XML_Parser parser) {     
2257   if (parser == NULL)                            
2258     return 0;                                    
2259   if (parser->m_eventEndPtr && parser->m_even    
2260     return (int)(parser->m_eventEndPtr - pars    
2261   return 0;                                      
2262 }                                                
2263                                                  
2264 const char *XMLCALL                              
2265 XML_GetInputContext(XML_Parser parser, int *o    
2266 #ifdef XML_CONTEXT_BYTES                         
2267   if (parser == NULL)                            
2268     return NULL;                                 
2269   if (parser->m_eventPtr && parser->m_buffer)    
2270     if (offset != NULL)                          
2271       *offset = (int)(parser->m_eventPtr - pa    
2272     if (size != NULL)                            
2273       *size = (int)(parser->m_bufferEnd - par    
2274     return parser->m_buffer;                     
2275   }                                              
2276 #else                                            
2277   (void)parser;                                  
2278   (void)offset;                                  
2279   (void)size;                                    
2280 #endif /* defined XML_CONTEXT_BYTES */           
2281   return (const char *)0;                        
2282 }                                                
2283                                                  
2284 XML_Size XMLCALL                                 
2285 XML_GetCurrentLineNumber(XML_Parser parser) {    
2286   if (parser == NULL)                            
2287     return 0;                                    
2288   if (parser->m_eventPtr && parser->m_eventPt    
2289     XmlUpdatePosition(parser->m_encoding, par    
2290                       parser->m_eventPtr, &pa    
2291     parser->m_positionPtr = parser->m_eventPt    
2292   }                                              
2293   return parser->m_position.lineNumber + 1;      
2294 }                                                
2295                                                  
2296 XML_Size XMLCALL                                 
2297 XML_GetCurrentColumnNumber(XML_Parser parser)    
2298   if (parser == NULL)                            
2299     return 0;                                    
2300   if (parser->m_eventPtr && parser->m_eventPt    
2301     XmlUpdatePosition(parser->m_encoding, par    
2302                       parser->m_eventPtr, &pa    
2303     parser->m_positionPtr = parser->m_eventPt    
2304   }                                              
2305   return parser->m_position.columnNumber;        
2306 }                                                
2307                                                  
2308 void XMLCALL                                     
2309 XML_FreeContentModel(XML_Parser parser, XML_C    
2310   if (parser != NULL)                            
2311     FREE(parser, model);                         
2312 }                                                
2313                                                  
2314 void *XMLCALL                                    
2315 XML_MemMalloc(XML_Parser parser, size_t size)    
2316   if (parser == NULL)                            
2317     return NULL;                                 
2318   return MALLOC(parser, size);                   
2319 }                                                
2320                                                  
2321 void *XMLCALL                                    
2322 XML_MemRealloc(XML_Parser parser, void *ptr,     
2323   if (parser == NULL)                            
2324     return NULL;                                 
2325   return REALLOC(parser, ptr, size);             
2326 }                                                
2327                                                  
2328 void XMLCALL                                     
2329 XML_MemFree(XML_Parser parser, void *ptr) {      
2330   if (parser != NULL)                            
2331     FREE(parser, ptr);                           
2332 }                                                
2333                                                  
2334 void XMLCALL                                     
2335 XML_DefaultCurrent(XML_Parser parser) {          
2336   if (parser == NULL)                            
2337     return;                                      
2338   if (parser->m_defaultHandler) {                
2339     if (parser->m_openInternalEntities)          
2340       reportDefault(parser, parser->m_interna    
2341                     parser->m_openInternalEnt    
2342                     parser->m_openInternalEnt    
2343     else                                         
2344       reportDefault(parser, parser->m_encodin    
2345                     parser->m_eventEndPtr);      
2346   }                                              
2347 }                                                
2348                                                  
2349 const XML_LChar *XMLCALL                         
2350 XML_ErrorString(enum XML_Error code) {           
2351   switch (code) {                                
2352   case XML_ERROR_NONE:                           
2353     return NULL;                                 
2354   case XML_ERROR_NO_MEMORY:                      
2355     return XML_L("out of memory");               
2356   case XML_ERROR_SYNTAX:                         
2357     return XML_L("syntax error");                
2358   case XML_ERROR_NO_ELEMENTS:                    
2359     return XML_L("no element found");            
2360   case XML_ERROR_INVALID_TOKEN:                  
2361     return XML_L("not well-formed (invalid to    
2362   case XML_ERROR_UNCLOSED_TOKEN:                 
2363     return XML_L("unclosed token");              
2364   case XML_ERROR_PARTIAL_CHAR:                   
2365     return XML_L("partial character");           
2366   case XML_ERROR_TAG_MISMATCH:                   
2367     return XML_L("mismatched tag");              
2368   case XML_ERROR_DUPLICATE_ATTRIBUTE:            
2369     return XML_L("duplicate attribute");         
2370   case XML_ERROR_JUNK_AFTER_DOC_ELEMENT:         
2371     return XML_L("junk after document element    
2372   case XML_ERROR_PARAM_ENTITY_REF:               
2373     return XML_L("illegal parameter entity re    
2374   case XML_ERROR_UNDEFINED_ENTITY:               
2375     return XML_L("undefined entity");            
2376   case XML_ERROR_RECURSIVE_ENTITY_REF:           
2377     return XML_L("recursive entity reference"    
2378   case XML_ERROR_ASYNC_ENTITY:                   
2379     return XML_L("asynchronous entity");         
2380   case XML_ERROR_BAD_CHAR_REF:                   
2381     return XML_L("reference to invalid charac    
2382   case XML_ERROR_BINARY_ENTITY_REF:              
2383     return XML_L("reference to binary entity"    
2384   case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_RE    
2385     return XML_L("reference to external entit    
2386   case XML_ERROR_MISPLACED_XML_PI:               
2387     return XML_L("XML or text declaration not    
2388   case XML_ERROR_UNKNOWN_ENCODING:               
2389     return XML_L("unknown encoding");            
2390   case XML_ERROR_INCORRECT_ENCODING:             
2391     return XML_L("encoding specified in XML d    
2392   case XML_ERROR_UNCLOSED_CDATA_SECTION:         
2393     return XML_L("unclosed CDATA section");      
2394   case XML_ERROR_EXTERNAL_ENTITY_HANDLING:       
2395     return XML_L("error in processing externa    
2396   case XML_ERROR_NOT_STANDALONE:                 
2397     return XML_L("document is not standalone"    
2398   case XML_ERROR_UNEXPECTED_STATE:               
2399     return XML_L("unexpected parser state - p    
2400   case XML_ERROR_ENTITY_DECLARED_IN_PE:          
2401     return XML_L("entity declared in paramete    
2402   case XML_ERROR_FEATURE_REQUIRES_XML_DTD:       
2403     return XML_L("requested feature requires     
2404   case XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PAR    
2405     return XML_L("cannot change setting once     
2406   /* Added in 1.95.7. */                         
2407   case XML_ERROR_UNBOUND_PREFIX:                 
2408     return XML_L("unbound prefix");              
2409   /* Added in 1.95.8. */                         
2410   case XML_ERROR_UNDECLARING_PREFIX:             
2411     return XML_L("must not undeclare prefix")    
2412   case XML_ERROR_INCOMPLETE_PE:                  
2413     return XML_L("incomplete markup in parame    
2414   case XML_ERROR_XML_DECL:                       
2415     return XML_L("XML declaration not well-fo    
2416   case XML_ERROR_TEXT_DECL:                      
2417     return XML_L("text declaration not well-f    
2418   case XML_ERROR_PUBLICID:                       
2419     return XML_L("illegal character(s) in pub    
2420   case XML_ERROR_SUSPENDED:                      
2421     return XML_L("parser suspended");            
2422   case XML_ERROR_NOT_SUSPENDED:                  
2423     return XML_L("parser not suspended");        
2424   case XML_ERROR_ABORTED:                        
2425     return XML_L("parsing aborted");             
2426   case XML_ERROR_FINISHED:                       
2427     return XML_L("parsing finished");            
2428   case XML_ERROR_SUSPEND_PE:                     
2429     return XML_L("cannot suspend in external     
2430   /* Added in 2.0.0. */                          
2431   case XML_ERROR_RESERVED_PREFIX_XML:            
2432     return XML_L(                                
2433         "reserved prefix (xml) must not be un    
2434   case XML_ERROR_RESERVED_PREFIX_XMLNS:          
2435     return XML_L("reserved prefix (xmlns) mus    
2436   case XML_ERROR_RESERVED_NAMESPACE_URI:         
2437     return XML_L(                                
2438         "prefix must not be bound to one of t    
2439   /* Added in 2.2.5. */                          
2440   case XML_ERROR_INVALID_ARGUMENT: /* Constan    
2441     return XML_L("invalid argument");            
2442     /* Added in 2.3.0. */                        
2443   case XML_ERROR_NO_BUFFER:                      
2444     return XML_L(                                
2445         "a successful prior call to function     
2446   /* Added in 2.4.0. */                          
2447   case XML_ERROR_AMPLIFICATION_LIMIT_BREACH:     
2448     return XML_L(                                
2449         "limit on input amplification factor     
2450   }                                              
2451   return NULL;                                   
2452 }                                                
2453                                                  
2454 const XML_LChar *XMLCALL                         
2455 XML_ExpatVersion(void) {                         
2456   /* V1 is used to string-ize the version num    
2457      string-ize the actual version macro *nam    
2458      substituted before being passed to V1. C    
2459      a macro, then rescan for more expansions    
2460      the version macros, then CPP will expand    
2461      with the correct numerals. */               
2462   /* ### I'm assuming cpp is portable in this    
2463                                                  
2464 #define V1(a, b, c) XML_L(#a) XML_L(".") XML_    
2465 #define V2(a, b, c) XML_L("expat_") V1(a, b,     
2466                                                  
2467   return V2(XML_MAJOR_VERSION, XML_MINOR_VERS    
2468                                                  
2469 #undef V1                                        
2470 #undef V2                                        
2471 }                                                
2472                                                  
2473 XML_Expat_Version XMLCALL                        
2474 XML_ExpatVersionInfo(void) {                     
2475   XML_Expat_Version version;                     
2476                                                  
2477   version.major = XML_MAJOR_VERSION;             
2478   version.minor = XML_MINOR_VERSION;             
2479   version.micro = XML_MICRO_VERSION;             
2480                                                  
2481   return version;                                
2482 }                                                
2483                                                  
2484 const XML_Feature *XMLCALL                       
2485 XML_GetFeatureList(void) {                       
2486   static const XML_Feature features[] = {        
2487       {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("si    
2488        sizeof(XML_Char)},                        
2489       {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("s    
2490        sizeof(XML_LChar)},                       
2491 #ifdef XML_UNICODE                               
2492       {XML_FEATURE_UNICODE, XML_L("XML_UNICOD    
2493 #endif                                           
2494 #ifdef XML_UNICODE_WCHAR_T                       
2495       {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XM    
2496 #endif                                           
2497 #ifdef XML_DTD                                   
2498       {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},    
2499 #endif                                           
2500 #ifdef XML_CONTEXT_BYTES                         
2501       {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_    
2502        XML_CONTEXT_BYTES},                       
2503 #endif                                           
2504 #ifdef XML_MIN_SIZE                              
2505       {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_S    
2506 #endif                                           
2507 #ifdef XML_NS                                    
2508       {XML_FEATURE_NS, XML_L("XML_NS"), 0},      
2509 #endif                                           
2510 #ifdef XML_LARGE_SIZE                            
2511       {XML_FEATURE_LARGE_SIZE, XML_L("XML_LAR    
2512 #endif                                           
2513 #ifdef XML_ATTR_INFO                             
2514       {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR    
2515 #endif                                           
2516 #ifdef XML_DTD                                   
2517       /* Added in Expat 2.4.0. */                
2518       {XML_FEATURE_BILLION_LAUGHS_ATTACK_PROT    
2519        XML_L("XML_BLAP_MAX_AMP"),                
2520        (long int)                                
2521            EXPAT_BILLION_LAUGHS_ATTACK_PROTEC    
2522       {XML_FEATURE_BILLION_LAUGHS_ATTACK_PROT    
2523        XML_L("XML_BLAP_ACT_THRES"),              
2524        EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION    
2525 #endif                                           
2526       {XML_FEATURE_END, NULL, 0}};               
2527                                                  
2528   return features;                               
2529 }                                                
2530                                                  
2531 #ifdef XML_DTD                                   
2532 XML_Bool XMLCALL                                 
2533 XML_SetBillionLaughsAttackProtectionMaximumAm    
2534     XML_Parser parser, float maximumAmplifica    
2535   if ((parser == NULL) || (parser->m_parentPa    
2536       || isnan(maximumAmplificationFactor)       
2537       || (maximumAmplificationFactor < 1.0f))    
2538     return XML_FALSE;                            
2539   }                                              
2540   parser->m_accounting.maximumAmplificationFa    
2541   return XML_TRUE;                               
2542 }                                                
2543                                                  
2544 XML_Bool XMLCALL                                 
2545 XML_SetBillionLaughsAttackProtectionActivatio    
2546     XML_Parser parser, unsigned long long act    
2547   if ((parser == NULL) || (parser->m_parentPa    
2548     return XML_FALSE;                            
2549   }                                              
2550   parser->m_accounting.activationThresholdByt    
2551   return XML_TRUE;                               
2552 }                                                
2553 #endif /* XML_DTD */                             
2554                                                  
2555 /* Initially tag->rawName always points into     
2556    for those TAG instances opened while the c    
2557    processed, and not yet closed, we need to     
2558    permanent location, since the parse buffer    
2559 */                                               
2560 static XML_Bool                                  
2561 storeRawNames(XML_Parser parser) {               
2562   TAG *tag = parser->m_tagStack;                 
2563   while (tag) {                                  
2564     int bufSize;                                 
2565     int nameLen = sizeof(XML_Char) * (tag->na    
2566     size_t rawNameLen;                           
2567     char *rawNameBuf = tag->buf + nameLen;       
2568     /* Stop if already stored.  Since m_tagSt    
2569        at the first entry that has already be    
2570        below it in the stack is already been     
2571        previous call to this function.           
2572     */                                           
2573     if (tag->rawName == rawNameBuf)              
2574       break;                                     
2575     /* For re-use purposes we need to ensure     
2576        size of tag->buf is a multiple of size    
2577     */                                           
2578     rawNameLen = ROUND_UP(tag->rawNameLength,    
2579     /* Detect and prevent integer overflow. *    
2580     if (rawNameLen > (size_t)INT_MAX - nameLe    
2581       return XML_FALSE;                          
2582     bufSize = nameLen + (int)rawNameLen;         
2583     if (bufSize > tag->bufEnd - tag->buf) {      
2584       char *temp = (char *)REALLOC(parser, ta    
2585       if (temp == NULL)                          
2586         return XML_FALSE;                        
2587       /* if tag->name.str points to tag->buf     
2588          processing is off) then we have to u    
2589       */                                         
2590       if (tag->name.str == (XML_Char *)tag->b    
2591         tag->name.str = (XML_Char *)temp;        
2592       /* if tag->name.localPart is set (when     
2593          then update it as well, since it wil    
2594       */                                         
2595       if (tag->name.localPart)                   
2596         tag->name.localPart                      
2597             = (XML_Char *)temp + (tag->name.l    
2598       tag->buf = temp;                           
2599       tag->bufEnd = temp + bufSize;              
2600       rawNameBuf = temp + nameLen;               
2601     }                                            
2602     memcpy(rawNameBuf, tag->rawName, tag->raw    
2603     tag->rawName = rawNameBuf;                   
2604     tag = tag->parent;                           
2605   }                                              
2606   return XML_TRUE;                               
2607 }                                                
2608                                                  
2609 static enum XML_Error PTRCALL                    
2610 contentProcessor(XML_Parser parser, const cha    
2611                  const char **endPtr) {          
2612   enum XML_Error result = doContent(             
2613       parser, 0, parser->m_encoding, start, e    
2614       (XML_Bool)! parser->m_parsingStatus.fin    
2615   if (result == XML_ERROR_NONE) {                
2616     if (! storeRawNames(parser))                 
2617       return XML_ERROR_NO_MEMORY;                
2618   }                                              
2619   return result;                                 
2620 }                                                
2621                                                  
2622 static enum XML_Error PTRCALL                    
2623 externalEntityInitProcessor(XML_Parser parser    
2624                             const char *end,     
2625   enum XML_Error result = initializeEncoding(    
2626   if (result != XML_ERROR_NONE)                  
2627     return result;                               
2628   parser->m_processor = externalEntityInitPro    
2629   return externalEntityInitProcessor2(parser,    
2630 }                                                
2631                                                  
2632 static enum XML_Error PTRCALL                    
2633 externalEntityInitProcessor2(XML_Parser parse    
2634                              const char *end,    
2635   const char *next = start; /* XmlContentTok     
2636   int tok = XmlContentTok(parser->m_encoding,    
2637   switch (tok) {                                 
2638   case XML_TOK_BOM:                              
2639 #ifdef XML_DTD                                   
2640     if (! accountingDiffTolerated(parser, tok    
2641                                   XML_ACCOUNT    
2642       accountingOnAbort(parser);                 
2643       return XML_ERROR_AMPLIFICATION_LIMIT_BR    
2644     }                                            
2645 #endif /* XML_DTD */                             
2646                                                  
2647     /* If we are at the end of the buffer, th    
2648        i.e. externalEntityInitProcessor3, to     
2649        doContent (by detecting XML_TOK_NONE)     
2650        declaration - causing the error XML_ER    
2651     */                                           
2652     if (next == end && ! parser->m_parsingSta    
2653       *endPtr = next;                            
2654       return XML_ERROR_NONE;                     
2655     }                                            
2656     start = next;                                
2657     break;                                       
2658   case XML_TOK_PARTIAL:                          
2659     if (! parser->m_parsingStatus.finalBuffer    
2660       *endPtr = start;                           
2661       return XML_ERROR_NONE;                     
2662     }                                            
2663     parser->m_eventPtr = start;                  
2664     return XML_ERROR_UNCLOSED_TOKEN;             
2665   case XML_TOK_PARTIAL_CHAR:                     
2666     if (! parser->m_parsingStatus.finalBuffer    
2667       *endPtr = start;                           
2668       return XML_ERROR_NONE;                     
2669     }                                            
2670     parser->m_eventPtr = start;                  
2671     return XML_ERROR_PARTIAL_CHAR;               
2672   }                                              
2673   parser->m_processor = externalEntityInitPro    
2674   return externalEntityInitProcessor3(parser,    
2675 }                                                
2676                                                  
2677 static enum XML_Error PTRCALL                    
2678 externalEntityInitProcessor3(XML_Parser parse    
2679                              const char *end,    
2680   int tok;                                       
2681   const char *next = start; /* XmlContentTok     
2682   parser->m_eventPtr = start;                    
2683   tok = XmlContentTok(parser->m_encoding, sta    
2684   /* Note: These bytes are accounted later in    
2685            - processXmlDecl                      
2686            - externalEntityContentProcessor      
2687   */                                             
2688   parser->m_eventEndPtr = next;                  
2689                                                  
2690   switch (tok) {                                 
2691   case XML_TOK_XML_DECL: {                       
2692     enum XML_Error result;                       
2693     result = processXmlDecl(parser, 1, start,    
2694     if (result != XML_ERROR_NONE)                
2695       return result;                             
2696     switch (parser->m_parsingStatus.parsing)     
2697     case XML_SUSPENDED:                          
2698       *endPtr = next;                            
2699       return XML_ERROR_NONE;                     
2700     case XML_FINISHED:                           
2701       return XML_ERROR_ABORTED;                  
2702     default:                                     
2703       start = next;                              
2704     }                                            
2705   } break;                                       
2706   case XML_TOK_PARTIAL:                          
2707     if (! parser->m_parsingStatus.finalBuffer    
2708       *endPtr = start;                           
2709       return XML_ERROR_NONE;                     
2710     }                                            
2711     return XML_ERROR_UNCLOSED_TOKEN;             
2712   case XML_TOK_PARTIAL_CHAR:                     
2713     if (! parser->m_parsingStatus.finalBuffer    
2714       *endPtr = start;                           
2715       return XML_ERROR_NONE;                     
2716     }                                            
2717     return XML_ERROR_PARTIAL_CHAR;               
2718   }                                              
2719   parser->m_processor = externalEntityContent    
2720   parser->m_tagLevel = 1;                        
2721   return externalEntityContentProcessor(parse    
2722 }                                                
2723                                                  
2724 static enum XML_Error PTRCALL                    
2725 externalEntityContentProcessor(XML_Parser par    
2726                                const char *en    
2727   enum XML_Error result                          
2728       = doContent(parser, 1, parser->m_encodi    
2729                   (XML_Bool)! parser->m_parsi    
2730                   XML_ACCOUNT_ENTITY_EXPANSIO    
2731   if (result == XML_ERROR_NONE) {                
2732     if (! storeRawNames(parser))                 
2733       return XML_ERROR_NO_MEMORY;                
2734   }                                              
2735   return result;                                 
2736 }                                                
2737                                                  
2738 static enum XML_Error                            
2739 doContent(XML_Parser parser, int startTagLeve    
2740           const char *s, const char *end, con    
2741           XML_Bool haveMore, enum XML_Account    
2742   /* save one level of indirection */            
2743   DTD *const dtd = parser->m_dtd;                
2744                                                  
2745   const char **eventPP;                          
2746   const char **eventEndPP;                       
2747   if (enc == parser->m_encoding) {               
2748     eventPP = &parser->m_eventPtr;               
2749     eventEndPP = &parser->m_eventEndPtr;         
2750   } else {                                       
2751     eventPP = &(parser->m_openInternalEntitie    
2752     eventEndPP = &(parser->m_openInternalEnti    
2753   }                                              
2754   *eventPP = s;                                  
2755                                                  
2756   for (;;) {                                     
2757     const char *next = s; /* XmlContentTok do    
2758     int tok = XmlContentTok(enc, s, end, &nex    
2759 #ifdef XML_DTD                                   
2760     const char *accountAfter                     
2761         = ((tok == XML_TOK_TRAILING_RSQB) ||     
2762               ? (haveMore ? s /* i.e. 0 bytes    
2763               : next;                            
2764     if (! accountingDiffTolerated(parser, tok    
2765                                   account)) {    
2766       accountingOnAbort(parser);                 
2767       return XML_ERROR_AMPLIFICATION_LIMIT_BR    
2768     }                                            
2769 #endif                                           
2770     *eventEndPP = next;                          
2771     switch (tok) {                               
2772     case XML_TOK_TRAILING_CR:                    
2773       if (haveMore) {                            
2774         *nextPtr = s;                            
2775         return XML_ERROR_NONE;                   
2776       }                                          
2777       *eventEndPP = end;                         
2778       if (parser->m_characterDataHandler) {      
2779         XML_Char c = 0xA;                        
2780         parser->m_characterDataHandler(parser    
2781       } else if (parser->m_defaultHandler)       
2782         reportDefault(parser, enc, s, end);      
2783       /* We are at the end of the final buffe    
2784          XML_SUSPENDED, XML_FINISHED?            
2785       */                                         
2786       if (startTagLevel == 0)                    
2787         return XML_ERROR_NO_ELEMENTS;            
2788       if (parser->m_tagLevel != startTagLevel    
2789         return XML_ERROR_ASYNC_ENTITY;           
2790       *nextPtr = end;                            
2791       return XML_ERROR_NONE;                     
2792     case XML_TOK_NONE:                           
2793       if (haveMore) {                            
2794         *nextPtr = s;                            
2795         return XML_ERROR_NONE;                   
2796       }                                          
2797       if (startTagLevel > 0) {                   
2798         if (parser->m_tagLevel != startTagLev    
2799           return XML_ERROR_ASYNC_ENTITY;         
2800         *nextPtr = s;                            
2801         return XML_ERROR_NONE;                   
2802       }                                          
2803       return XML_ERROR_NO_ELEMENTS;              
2804     case XML_TOK_INVALID:                        
2805       *eventPP = next;                           
2806       return XML_ERROR_INVALID_TOKEN;            
2807     case XML_TOK_PARTIAL:                        
2808       if (haveMore) {                            
2809         *nextPtr = s;                            
2810         return XML_ERROR_NONE;                   
2811       }                                          
2812       return XML_ERROR_UNCLOSED_TOKEN;           
2813     case XML_TOK_PARTIAL_CHAR:                   
2814       if (haveMore) {                            
2815         *nextPtr = s;                            
2816         return XML_ERROR_NONE;                   
2817       }                                          
2818       return XML_ERROR_PARTIAL_CHAR;             
2819     case XML_TOK_ENTITY_REF: {                   
2820       const XML_Char *name;                      
2821       ENTITY *entity;                            
2822       XML_Char ch = (XML_Char)XmlPredefinedEn    
2823           enc, s + enc->minBytesPerChar, next    
2824       if (ch) {                                  
2825 #ifdef XML_DTD                                   
2826         /* NOTE: We are replacing 4-6 charact    
2827          *       so there is no amplification    
2828          *       protection. */                  
2829         accountingDiffTolerated(parser, tok,     
2830                                 ((char *)&ch)    
2831                                 XML_ACCOUNT_E    
2832 #endif /* XML_DTD */                             
2833         if (parser->m_characterDataHandler)      
2834           parser->m_characterDataHandler(pars    
2835         else if (parser->m_defaultHandler)       
2836           reportDefault(parser, enc, s, next)    
2837         break;                                   
2838       }                                          
2839       name = poolStoreString(&dtd->pool, enc,    
2840                              next - enc->minB    
2841       if (! name)                                
2842         return XML_ERROR_NO_MEMORY;              
2843       entity = (ENTITY *)lookup(parser, &dtd-    
2844       poolDiscard(&dtd->pool);                   
2845       /* First, determine if a check for an e    
2846          if yes, check that the entity exists    
2847          otherwise call the skipped entity or    
2848       */                                         
2849       if (! dtd->hasParamEntityRefs || dtd->s    
2850         if (! entity)                            
2851           return XML_ERROR_UNDEFINED_ENTITY;     
2852         else if (! entity->is_internal)          
2853           return XML_ERROR_ENTITY_DECLARED_IN    
2854       } else if (! entity) {                     
2855         if (parser->m_skippedEntityHandler)      
2856           parser->m_skippedEntityHandler(pars    
2857         else if (parser->m_defaultHandler)       
2858           reportDefault(parser, enc, s, next)    
2859         break;                                   
2860       }                                          
2861       if (entity->open)                          
2862         return XML_ERROR_RECURSIVE_ENTITY_REF    
2863       if (entity->notation)                      
2864         return XML_ERROR_BINARY_ENTITY_REF;      
2865       if (entity->textPtr) {                     
2866         enum XML_Error result;                   
2867         if (! parser->m_defaultExpandInternal    
2868           if (parser->m_skippedEntityHandler)    
2869             parser->m_skippedEntityHandler(pa    
2870                                            0)    
2871           else if (parser->m_defaultHandler)     
2872             reportDefault(parser, enc, s, nex    
2873           break;                                 
2874         }                                        
2875         result = processInternalEntity(parser    
2876         if (result != XML_ERROR_NONE)            
2877           return result;                         
2878       } else if (parser->m_externalEntityRefH    
2879         const XML_Char *context;                 
2880         entity->open = XML_TRUE;                 
2881         context = getContext(parser);            
2882         entity->open = XML_FALSE;                
2883         if (! context)                           
2884           return XML_ERROR_NO_MEMORY;            
2885         if (! parser->m_externalEntityRefHand    
2886                 parser->m_externalEntityRefHa    
2887                 entity->systemId, entity->pub    
2888           return XML_ERROR_EXTERNAL_ENTITY_HA    
2889         poolDiscard(&parser->m_tempPool);        
2890       } else if (parser->m_defaultHandler)       
2891         reportDefault(parser, enc, s, next);     
2892       break;                                     
2893     }                                            
2894     case XML_TOK_START_TAG_NO_ATTS:              
2895       /* fall through */                         
2896     case XML_TOK_START_TAG_WITH_ATTS: {          
2897       TAG *tag;                                  
2898       enum XML_Error result;                     
2899       XML_Char *toPtr;                           
2900       if (parser->m_freeTagList) {               
2901         tag = parser->m_freeTagList;             
2902         parser->m_freeTagList = parser->m_fre    
2903       } else {                                   
2904         tag = (TAG *)MALLOC(parser, sizeof(TA    
2905         if (! tag)                               
2906           return XML_ERROR_NO_MEMORY;            
2907         tag->buf = (char *)MALLOC(parser, INI    
2908         if (! tag->buf) {                        
2909           FREE(parser, tag);                     
2910           return XML_ERROR_NO_MEMORY;            
2911         }                                        
2912         tag->bufEnd = tag->buf + INIT_TAG_BUF    
2913       }                                          
2914       tag->bindings = NULL;                      
2915       tag->parent = parser->m_tagStack;          
2916       parser->m_tagStack = tag;                  
2917       tag->name.localPart = NULL;                
2918       tag->name.prefix = NULL;                   
2919       tag->rawName = s + enc->minBytesPerChar    
2920       tag->rawNameLength = XmlNameLength(enc,    
2921       ++parser->m_tagLevel;                      
2922       {                                          
2923         const char *rawNameEnd = tag->rawName    
2924         const char *fromPtr = tag->rawName;      
2925         toPtr = (XML_Char *)tag->buf;            
2926         for (;;) {                               
2927           int bufSize;                           
2928           int convLen;                           
2929           const enum XML_Convert_Result conve    
2930               = XmlConvert(enc, &fromPtr, raw    
2931                            (ICHAR *)tag->bufE    
2932           convLen = (int)(toPtr - (XML_Char *    
2933           if ((fromPtr >= rawNameEnd)            
2934               || (convert_res == XML_CONVERT_    
2935             tag->name.strLen = convLen;          
2936             break;                               
2937           }                                      
2938           bufSize = (int)(tag->bufEnd - tag->    
2939           {                                      
2940             char *temp = (char *)REALLOC(pars    
2941             if (temp == NULL)                    
2942               return XML_ERROR_NO_MEMORY;        
2943             tag->buf = temp;                     
2944             tag->bufEnd = temp + bufSize;        
2945             toPtr = (XML_Char *)temp + convLe    
2946           }                                      
2947         }                                        
2948       }                                          
2949       tag->name.str = (XML_Char *)tag->buf;      
2950       *toPtr = XML_T('\0');                      
2951       result                                     
2952           = storeAtts(parser, enc, s, &(tag->    
2953       if (result)                                
2954         return result;                           
2955       if (parser->m_startElementHandler)         
2956         parser->m_startElementHandler(parser-    
2957                                       (const     
2958       else if (parser->m_defaultHandler)         
2959         reportDefault(parser, enc, s, next);     
2960       poolClear(&parser->m_tempPool);            
2961       break;                                     
2962     }                                            
2963     case XML_TOK_EMPTY_ELEMENT_NO_ATTS:          
2964       /* fall through */                         
2965     case XML_TOK_EMPTY_ELEMENT_WITH_ATTS: {      
2966       const char *rawName = s + enc->minBytes    
2967       enum XML_Error result;                     
2968       BINDING *bindings = NULL;                  
2969       XML_Bool noElmHandlers = XML_TRUE;         
2970       TAG_NAME name;                             
2971       name.str = poolStoreString(&parser->m_t    
2972                                  rawName + Xm    
2973       if (! name.str)                            
2974         return XML_ERROR_NO_MEMORY;              
2975       poolFinish(&parser->m_tempPool);           
2976       result = storeAtts(parser, enc, s, &nam    
2977                          XML_ACCOUNT_NONE /*     
2978       if (result != XML_ERROR_NONE) {            
2979         freeBindings(parser, bindings);          
2980         return result;                           
2981       }                                          
2982       poolFinish(&parser->m_tempPool);           
2983       if (parser->m_startElementHandler) {       
2984         parser->m_startElementHandler(parser-    
2985                                       (const     
2986         noElmHandlers = XML_FALSE;               
2987       }                                          
2988       if (parser->m_endElementHandler) {         
2989         if (parser->m_startElementHandler)       
2990           *eventPP = *eventEndPP;                
2991         parser->m_endElementHandler(parser->m    
2992         noElmHandlers = XML_FALSE;               
2993       }                                          
2994       if (noElmHandlers && parser->m_defaultH    
2995         reportDefault(parser, enc, s, next);     
2996       poolClear(&parser->m_tempPool);            
2997       freeBindings(parser, bindings);            
2998     }                                            
2999       if ((parser->m_tagLevel == 0)              
3000           && (parser->m_parsingStatus.parsing    
3001         if (parser->m_parsingStatus.parsing =    
3002           parser->m_processor = epilogProcess    
3003         else                                     
3004           return epilogProcessor(parser, next    
3005       }                                          
3006       break;                                     
3007     case XML_TOK_END_TAG:                        
3008       if (parser->m_tagLevel == startTagLevel    
3009         return XML_ERROR_ASYNC_ENTITY;           
3010       else {                                     
3011         int len;                                 
3012         const char *rawName;                     
3013         TAG *tag = parser->m_tagStack;           
3014         parser->m_tagStack = tag->parent;        
3015         tag->parent = parser->m_freeTagList;     
3016         parser->m_freeTagList = tag;             
3017         rawName = s + enc->minBytesPerChar *     
3018         len = XmlNameLength(enc, rawName);       
3019         if (len != tag->rawNameLength            
3020             || memcmp(tag->rawName, rawName,     
3021           *eventPP = rawName;                    
3022           return XML_ERROR_TAG_MISMATCH;         
3023         }                                        
3024         --parser->m_tagLevel;                    
3025         if (parser->m_endElementHandler) {       
3026           const XML_Char *localPart;             
3027           const XML_Char *prefix;                
3028           XML_Char *uri;                         
3029           localPart = tag->name.localPart;       
3030           if (parser->m_ns && localPart) {       
3031             /* localPart and prefix may have     
3032                tag->name.str, since this poin    
3033                buffer which gets re-used; so     
3034             */                                   
3035             uri = (XML_Char *)tag->name.str +    
3036             /* don't need to check for space     
3037             while (*localPart)                   
3038               *uri++ = *localPart++;             
3039             prefix = (XML_Char *)tag->name.pr    
3040             if (parser->m_ns_triplets && pref    
3041               *uri++ = parser->m_namespaceSep    
3042               while (*prefix)                    
3043                 *uri++ = *prefix++;              
3044             }                                    
3045             *uri = XML_T('\0');                  
3046           }                                      
3047           parser->m_endElementHandler(parser-    
3048         } else if (parser->m_defaultHandler)     
3049           reportDefault(parser, enc, s, next)    
3050         while (tag->bindings) {                  
3051           BINDING *b = tag->bindings;            
3052           if (parser->m_endNamespaceDeclHandl    
3053             parser->m_endNamespaceDeclHandler    
3054                                                  
3055           tag->bindings = tag->bindings->next    
3056           b->nextTagBinding = parser->m_freeB    
3057           parser->m_freeBindingList = b;         
3058           b->prefix->binding = b->prevPrefixB    
3059         }                                        
3060         if ((parser->m_tagLevel == 0)            
3061             && (parser->m_parsingStatus.parsi    
3062           if (parser->m_parsingStatus.parsing    
3063             parser->m_processor = epilogProce    
3064           else                                   
3065             return epilogProcessor(parser, ne    
3066         }                                        
3067       }                                          
3068       break;                                     
3069     case XML_TOK_CHAR_REF: {                     
3070       int n = XmlCharRefNumber(enc, s);          
3071       if (n < 0)                                 
3072         return XML_ERROR_BAD_CHAR_REF;           
3073       if (parser->m_characterDataHandler) {      
3074         XML_Char buf[XML_ENCODE_MAX];            
3075         parser->m_characterDataHandler(parser    
3076                                        XmlEnc    
3077       } else if (parser->m_defaultHandler)       
3078         reportDefault(parser, enc, s, next);     
3079     } break;                                     
3080     case XML_TOK_XML_DECL:                       
3081       return XML_ERROR_MISPLACED_XML_PI;         
3082     case XML_TOK_DATA_NEWLINE:                   
3083       if (parser->m_characterDataHandler) {      
3084         XML_Char c = 0xA;                        
3085         parser->m_characterDataHandler(parser    
3086       } else if (parser->m_defaultHandler)       
3087         reportDefault(parser, enc, s, next);     
3088       break;                                     
3089     case XML_TOK_CDATA_SECT_OPEN: {              
3090       enum XML_Error result;                     
3091       if (parser->m_startCdataSectionHandler)    
3092         parser->m_startCdataSectionHandler(pa    
3093       /* BEGIN disabled code */                  
3094       /* Suppose you doing a transformation o    
3095          changing only the character data.  Y    
3096          and a characterDataHandler.  The def    
3097          characters through.  The characterDa    
3098          transformation and writes the charac    
3099          necessary.  This case will fail to w    
3100          following two lines (because & and <    
3101          be incorrectly escaped).                
3102                                                  
3103          However, now we have a start/endCdat    
3104          easier to let the user deal with thi    
3105       */                                         
3106       else if (0 && parser->m_characterDataHa    
3107         parser->m_characterDataHandler(parser    
3108                                        0);       
3109       /* END disabled code */                    
3110       else if (parser->m_defaultHandler)         
3111         reportDefault(parser, enc, s, next);     
3112       result                                     
3113           = doCdataSection(parser, enc, &next    
3114       if (result != XML_ERROR_NONE)              
3115         return result;                           
3116       else if (! next) {                         
3117         parser->m_processor = cdataSectionPro    
3118         return result;                           
3119       }                                          
3120     } break;                                     
3121     case XML_TOK_TRAILING_RSQB:                  
3122       if (haveMore) {                            
3123         *nextPtr = s;                            
3124         return XML_ERROR_NONE;                   
3125       }                                          
3126       if (parser->m_characterDataHandler) {      
3127         if (MUST_CONVERT(enc, s)) {              
3128           ICHAR *dataPtr = (ICHAR *)parser->m    
3129           XmlConvert(enc, &s, end, &dataPtr,     
3130           parser->m_characterDataHandler(        
3131               parser->m_handlerArg, parser->m    
3132               (int)(dataPtr - (ICHAR *)parser    
3133         } else                                   
3134           parser->m_characterDataHandler(        
3135               parser->m_handlerArg, (XML_Char    
3136               (int)((XML_Char *)end - (XML_Ch    
3137       } else if (parser->m_defaultHandler)       
3138         reportDefault(parser, enc, s, end);      
3139       /* We are at the end of the final buffe    
3140          XML_SUSPENDED, XML_FINISHED?            
3141       */                                         
3142       if (startTagLevel == 0) {                  
3143         *eventPP = end;                          
3144         return XML_ERROR_NO_ELEMENTS;            
3145       }                                          
3146       if (parser->m_tagLevel != startTagLevel    
3147         *eventPP = end;                          
3148         return XML_ERROR_ASYNC_ENTITY;           
3149       }                                          
3150       *nextPtr = end;                            
3151       return XML_ERROR_NONE;                     
3152     case XML_TOK_DATA_CHARS: {                   
3153       XML_CharacterDataHandler charDataHandle    
3154       if (charDataHandler) {                     
3155         if (MUST_CONVERT(enc, s)) {              
3156           for (;;) {                             
3157             ICHAR *dataPtr = (ICHAR *)parser-    
3158             const enum XML_Convert_Result con    
3159                 enc, &s, next, &dataPtr, (ICH    
3160             *eventEndPP = s;                     
3161             charDataHandler(parser->m_handler    
3162                             (int)(dataPtr - (    
3163             if ((convert_res == XML_CONVERT_C    
3164                 || (convert_res == XML_CONVER    
3165               break;                             
3166             *eventPP = s;                        
3167           }                                      
3168         } else                                   
3169           charDataHandler(parser->m_handlerAr    
3170                           (int)((XML_Char *)n    
3171       } else if (parser->m_defaultHandler)       
3172         reportDefault(parser, enc, s, next);     
3173     } break;                                     
3174     case XML_TOK_PI:                             
3175       if (! reportProcessingInstruction(parse    
3176         return XML_ERROR_NO_MEMORY;              
3177       break;                                     
3178     case XML_TOK_COMMENT:                        
3179       if (! reportComment(parser, enc, s, nex    
3180         return XML_ERROR_NO_MEMORY;              
3181       break;                                     
3182     default:                                     
3183       /* All of the tokens produced by XmlCon    
3184        * explicit cases, so this default is n    
3185        * However it is a useful safety net, s    
3186        * simply exclude it from the coverage     
3187        *                                         
3188        * LCOV_EXCL_START                         
3189        */                                        
3190       if (parser->m_defaultHandler)              
3191         reportDefault(parser, enc, s, next);     
3192       break;                                     
3193       /* LCOV_EXCL_STOP */                       
3194     }                                            
3195     *eventPP = s = next;                         
3196     switch (parser->m_parsingStatus.parsing)     
3197     case XML_SUSPENDED:                          
3198       *nextPtr = next;                           
3199       return XML_ERROR_NONE;                     
3200     case XML_FINISHED:                           
3201       return XML_ERROR_ABORTED;                  
3202     default:;                                    
3203     }                                            
3204   }                                              
3205   /* not reached */                              
3206 }                                                
3207                                                  
3208 /* This function does not call free() on the     
3209  * moving it to the parser's m_freeBindingLis    
3210  * reused as appropriate.                        
3211  */                                              
3212 static void                                      
3213 freeBindings(XML_Parser parser, BINDING *bind    
3214   while (bindings) {                             
3215     BINDING *b = bindings;                       
3216                                                  
3217     /* m_startNamespaceDeclHandler will have     
3218      * binding in addBindings(), so call the     
3219      */                                          
3220     if (parser->m_endNamespaceDeclHandler)       
3221       parser->m_endNamespaceDeclHandler(parse    
3222                                                  
3223     bindings = bindings->nextTagBinding;         
3224     b->nextTagBinding = parser->m_freeBinding    
3225     parser->m_freeBindingList = b;               
3226     b->prefix->binding = b->prevPrefixBinding    
3227   }                                              
3228 }                                                
3229                                                  
3230 /* Precondition: all arguments must be non-NU    
3231    Purpose:                                      
3232    - normalize attributes                        
3233    - check attributes for well-formedness        
3234    - generate namespace aware attribute names    
3235    - build list of attributes for startElemen    
3236    - default attributes                          
3237    - process namespace declarations (check an    
3238    - generate namespace aware element name (U    
3239 */                                               
3240 static enum XML_Error                            
3241 storeAtts(XML_Parser parser, const ENCODING *    
3242           TAG_NAME *tagNamePtr, BINDING **bin    
3243           enum XML_Account account) {            
3244   DTD *const dtd = parser->m_dtd; /* save one    
3245   ELEMENT_TYPE *elementType;                     
3246   int nDefaultAtts;                              
3247   const XML_Char **appAtts; /* the attribute     
3248   int attIndex = 0;                              
3249   int prefixLen;                                 
3250   int i;                                         
3251   int n;                                         
3252   XML_Char *uri;                                 
3253   int nPrefixes = 0;                             
3254   BINDING *binding;                              
3255   const XML_Char *localPart;                     
3256                                                  
3257   /* lookup the element type name */             
3258   elementType                                    
3259       = (ELEMENT_TYPE *)lookup(parser, &dtd->    
3260   if (! elementType) {                           
3261     const XML_Char *name = poolCopyString(&dt    
3262     if (! name)                                  
3263       return XML_ERROR_NO_MEMORY;                
3264     elementType = (ELEMENT_TYPE *)lookup(pars    
3265                                          size    
3266     if (! elementType)                           
3267       return XML_ERROR_NO_MEMORY;                
3268     if (parser->m_ns && ! setElementTypePrefi    
3269       return XML_ERROR_NO_MEMORY;                
3270   }                                              
3271   nDefaultAtts = elementType->nDefaultAtts;      
3272                                                  
3273   /* get the attributes from the tokenizer */    
3274   n = XmlGetAttributes(enc, attStr, parser->m    
3275                                                  
3276   /* Detect and prevent integer overflow */      
3277   if (n > INT_MAX - nDefaultAtts) {              
3278     return XML_ERROR_NO_MEMORY;                  
3279   }                                              
3280                                                  
3281   if (n + nDefaultAtts > parser->m_attsSize)     
3282     int oldAttsSize = parser->m_attsSize;        
3283     ATTRIBUTE *temp;                             
3284 #ifdef XML_ATTR_INFO                             
3285     XML_AttrInfo *temp2;                         
3286 #endif                                           
3287                                                  
3288     /* Detect and prevent integer overflow */    
3289     if ((nDefaultAtts > INT_MAX - INIT_ATTS_S    
3290         || (n > INT_MAX - (nDefaultAtts + INI    
3291       return XML_ERROR_NO_MEMORY;                
3292     }                                            
3293                                                  
3294     parser->m_attsSize = n + nDefaultAtts + I    
3295                                                  
3296     /* Detect and prevent integer overflow.      
3297      * The preprocessor guard addresses the "    
3298      * from -Wtype-limits on platforms where     
3299      * sizeof(unsigned int) < sizeof(size_t),    
3300 #if UINT_MAX >= SIZE_MAX                         
3301     if ((unsigned)parser->m_attsSize > (size_    
3302       parser->m_attsSize = oldAttsSize;          
3303       return XML_ERROR_NO_MEMORY;                
3304     }                                            
3305 #endif                                           
3306                                                  
3307     temp = (ATTRIBUTE *)REALLOC(parser, (void    
3308                                 parser->m_att    
3309     if (temp == NULL) {                          
3310       parser->m_attsSize = oldAttsSize;          
3311       return XML_ERROR_NO_MEMORY;                
3312     }                                            
3313     parser->m_atts = temp;                       
3314 #ifdef XML_ATTR_INFO                             
3315     /* Detect and prevent integer overflow.      
3316      * The preprocessor guard addresses the "    
3317      * from -Wtype-limits on platforms where     
3318      * sizeof(unsigned int) < sizeof(size_t),    
3319 #  if UINT_MAX >= SIZE_MAX                       
3320     if ((unsigned)parser->m_attsSize > (size_    
3321       parser->m_attsSize = oldAttsSize;          
3322       return XML_ERROR_NO_MEMORY;                
3323     }                                            
3324 #  endif                                         
3325                                                  
3326     temp2 = (XML_AttrInfo *)REALLOC(parser, (    
3327                                     parser->m    
3328     if (temp2 == NULL) {                         
3329       parser->m_attsSize = oldAttsSize;          
3330       return XML_ERROR_NO_MEMORY;                
3331     }                                            
3332     parser->m_attInfo = temp2;                   
3333 #endif                                           
3334     if (n > oldAttsSize)                         
3335       XmlGetAttributes(enc, attStr, n, parser    
3336   }                                              
3337                                                  
3338   appAtts = (const XML_Char **)parser->m_atts    
3339   for (i = 0; i < n; i++) {                      
3340     ATTRIBUTE *currAtt = &parser->m_atts[i];     
3341 #ifdef XML_ATTR_INFO                             
3342     XML_AttrInfo *currAttInfo = &parser->m_at    
3343 #endif                                           
3344     /* add the name and value to the attribut    
3345     ATTRIBUTE_ID *attId                          
3346         = getAttributeId(parser, enc, currAtt    
3347                          currAtt->name + XmlN    
3348     if (! attId)                                 
3349       return XML_ERROR_NO_MEMORY;                
3350 #ifdef XML_ATTR_INFO                             
3351     currAttInfo->nameStart                       
3352         = parser->m_parseEndByteIndex - (pars    
3353     currAttInfo->nameEnd                         
3354         = currAttInfo->nameStart + XmlNameLen    
3355     currAttInfo->valueStart = parser->m_parse    
3356                               - (parser->m_pa    
3357     currAttInfo->valueEnd = parser->m_parseEn    
3358                             - (parser->m_pars    
3359 #endif                                           
3360     /* Detect duplicate attributes by their Q    
3361        namespace processing is turned on and     
3362        namespace are used. For this case we h    
3363     */                                           
3364     if ((attId->name)[-1]) {                     
3365       if (enc == parser->m_encoding)             
3366         parser->m_eventPtr = parser->m_atts[i    
3367       return XML_ERROR_DUPLICATE_ATTRIBUTE;      
3368     }                                            
3369     (attId->name)[-1] = 1;                       
3370     appAtts[attIndex++] = attId->name;           
3371     if (! parser->m_atts[i].normalized) {        
3372       enum XML_Error result;                     
3373       XML_Bool isCdata = XML_TRUE;               
3374                                                  
3375       /* figure out whether declared as other    
3376       if (attId->maybeTokenized) {               
3377         int j;                                   
3378         for (j = 0; j < nDefaultAtts; j++) {     
3379           if (attId == elementType->defaultAt    
3380             isCdata = elementType->defaultAtt    
3381             break;                               
3382           }                                      
3383         }                                        
3384       }                                          
3385                                                  
3386       /* normalize the attribute value */        
3387       result = storeAttributeValue(              
3388           parser, enc, isCdata, parser->m_att    
3389           parser->m_atts[i].valueEnd, &parser    
3390       if (result)                                
3391         return result;                           
3392       appAtts[attIndex] = poolStart(&parser->    
3393       poolFinish(&parser->m_tempPool);           
3394     } else {                                     
3395       /* the value did not need normalizing *    
3396       appAtts[attIndex] = poolStoreString(&pa    
3397                                           par    
3398                                           par    
3399       if (appAtts[attIndex] == 0)                
3400         return XML_ERROR_NO_MEMORY;              
3401       poolFinish(&parser->m_tempPool);           
3402     }                                            
3403     /* handle prefixed attribute names */        
3404     if (attId->prefix) {                         
3405       if (attId->xmlns) {                        
3406         /* deal with namespace declarations h    
3407         enum XML_Error result = addBinding(pa    
3408                                            ap    
3409         if (result)                              
3410           return result;                         
3411         --attIndex;                              
3412       } else {                                   
3413         /* deal with other prefixed names lat    
3414         attIndex++;                              
3415         nPrefixes++;                             
3416         (attId->name)[-1] = 2;                   
3417       }                                          
3418     } else                                       
3419       attIndex++;                                
3420   }                                              
3421                                                  
3422   /* set-up for XML_GetSpecifiedAttributeCoun    
3423   parser->m_nSpecifiedAtts = attIndex;           
3424   if (elementType->idAtt && (elementType->idA    
3425     for (i = 0; i < attIndex; i += 2)            
3426       if (appAtts[i] == elementType->idAtt->n    
3427         parser->m_idAttIndex = i;                
3428         break;                                   
3429       }                                          
3430   } else                                         
3431     parser->m_idAttIndex = -1;                   
3432                                                  
3433   /* do attribute defaulting */                  
3434   for (i = 0; i < nDefaultAtts; i++) {           
3435     const DEFAULT_ATTRIBUTE *da = elementType    
3436     if (! (da->id->name)[-1] && da->value) {     
3437       if (da->id->prefix) {                      
3438         if (da->id->xmlns) {                     
3439           enum XML_Error result = addBinding(    
3440                                                  
3441           if (result)                            
3442             return result;                       
3443         } else {                                 
3444           (da->id->name)[-1] = 2;                
3445           nPrefixes++;                           
3446           appAtts[attIndex++] = da->id->name;    
3447           appAtts[attIndex++] = da->value;       
3448         }                                        
3449       } else {                                   
3450         (da->id->name)[-1] = 1;                  
3451         appAtts[attIndex++] = da->id->name;      
3452         appAtts[attIndex++] = da->value;         
3453       }                                          
3454     }                                            
3455   }                                              
3456   appAtts[attIndex] = 0;                         
3457                                                  
3458   /* expand prefixed attribute names, check f    
3459      and clear flags that say whether attribu    
3460   i = 0;                                         
3461   if (nPrefixes) {                               
3462     int j; /* hash table index */                
3463     unsigned long version = parser->m_nsAttsV    
3464                                                  
3465     /* Detect and prevent invalid shift */       
3466     if (parser->m_nsAttsPower >= sizeof(unsig    
3467       return XML_ERROR_NO_MEMORY;                
3468     }                                            
3469                                                  
3470     unsigned int nsAttsSize = 1u << parser->m    
3471     unsigned char oldNsAttsPower = parser->m_    
3472     /* size of hash table must be at least 2     
3473     if ((nPrefixes << 1)                         
3474         >> parser->m_nsAttsPower) { /* true f    
3475       NS_ATT *temp;                              
3476       /* hash table size must also be a power    
3477       while (nPrefixes >> parser->m_nsAttsPow    
3478         ;                                        
3479       if (parser->m_nsAttsPower < 3)             
3480         parser->m_nsAttsPower = 3;               
3481                                                  
3482       /* Detect and prevent invalid shift */     
3483       if (parser->m_nsAttsPower >= sizeof(nsA    
3484         /* Restore actual size of memory in m    
3485         parser->m_nsAttsPower = oldNsAttsPowe    
3486         return XML_ERROR_NO_MEMORY;              
3487       }                                          
3488                                                  
3489       nsAttsSize = 1u << parser->m_nsAttsPowe    
3490                                                  
3491       /* Detect and prevent integer overflow.    
3492        * The preprocessor guard addresses the    
3493        * from -Wtype-limits on platforms wher    
3494        * sizeof(unsigned int) < sizeof(size_t    
3495 #if UINT_MAX >= SIZE_MAX                         
3496       if (nsAttsSize > (size_t)(-1) / sizeof(    
3497         /* Restore actual size of memory in m    
3498         parser->m_nsAttsPower = oldNsAttsPowe    
3499         return XML_ERROR_NO_MEMORY;              
3500       }                                          
3501 #endif                                           
3502                                                  
3503       temp = (NS_ATT *)REALLOC(parser, parser    
3504                                nsAttsSize * s    
3505       if (! temp) {                              
3506         /* Restore actual size of memory in m    
3507         parser->m_nsAttsPower = oldNsAttsPowe    
3508         return XML_ERROR_NO_MEMORY;              
3509       }                                          
3510       parser->m_nsAtts = temp;                   
3511       version = 0; /* force re-initialization    
3512     }                                            
3513     /* using a version flag saves us from ini    
3514     if (! version) { /* initialize version fl    
3515       version = INIT_ATTS_VERSION;               
3516       for (j = nsAttsSize; j != 0;)              
3517         parser->m_nsAtts[--j].version = versi    
3518     }                                            
3519     parser->m_nsAttsVersion = --version;         
3520                                                  
3521     /* expand prefixed names and check for du    
3522     for (; i < attIndex; i += 2) {               
3523       const XML_Char *s = appAtts[i];            
3524       if (s[-1] == 2) { /* prefixed */           
3525         ATTRIBUTE_ID *id;                        
3526         const BINDING *b;                        
3527         unsigned long uriHash;                   
3528         struct siphash sip_state;                
3529         struct sipkey sip_key;                   
3530                                                  
3531         copy_salt_to_sipkey(parser, &sip_key)    
3532         sip24_init(&sip_state, &sip_key);        
3533                                                  
3534         ((XML_Char *)s)[-1] = 0; /* clear fla    
3535         id = (ATTRIBUTE_ID *)lookup(parser, &    
3536         if (! id || ! id->prefix) {              
3537           /* This code is walking through the    
3538            * with (in this case) a prefixed a    
3539            * the array, the attribute must ha    
3540            * has to have passed through the h    
3541            * already.  That implies that an e    
3542            * exists, so the lookup above will    
3543            * already allocated memory.  There    
3544            * the allocator to fail, so the co    
3545            * fulfilled.                          
3546            *                                     
3547            * Since it is difficult to be cert    
3548            * analysis is complete, we retain     
3549            * remove the code from coverage te    
3550            */                                    
3551           return XML_ERROR_NO_MEMORY; /* LCOV    
3552         }                                        
3553         b = id->prefix->binding;                 
3554         if (! b)                                 
3555           return XML_ERROR_UNBOUND_PREFIX;       
3556                                                  
3557         for (j = 0; j < b->uriLen; j++) {        
3558           const XML_Char c = b->uri[j];          
3559           if (! poolAppendChar(&parser->m_tem    
3560             return XML_ERROR_NO_MEMORY;          
3561         }                                        
3562                                                  
3563         sip24_update(&sip_state, b->uri, b->u    
3564                                                  
3565         while (*s++ != XML_T(ASCII_COLON))       
3566           ;                                      
3567                                                  
3568         sip24_update(&sip_state, s, keylen(s)    
3569                                                  
3570         do { /* copies null terminator */        
3571           if (! poolAppendChar(&parser->m_tem    
3572             return XML_ERROR_NO_MEMORY;          
3573         } while (*s++);                          
3574                                                  
3575         uriHash = (unsigned long)sip24_final(    
3576                                                  
3577         { /* Check hash table for duplicate o    
3578              Derived from code in lookup(pars    
3579           */                                     
3580           unsigned char step = 0;                
3581           unsigned long mask = nsAttsSize - 1    
3582           j = uriHash & mask; /* index into h    
3583           while (parser->m_nsAtts[j].version     
3584             /* for speed we compare stored ha    
3585             if (uriHash == parser->m_nsAtts[j    
3586               const XML_Char *s1 = poolStart(    
3587               const XML_Char *s2 = parser->m_    
3588               /* s1 is null terminated, but n    
3589               for (; *s1 == *s2 && *s1 != 0;     
3590                 ;                                
3591               if (*s1 == 0)                      
3592                 return XML_ERROR_DUPLICATE_AT    
3593             }                                    
3594             if (! step)                          
3595               step = PROBE_STEP(uriHash, mask    
3596             j < step ? (j += nsAttsSize - ste    
3597           }                                      
3598         }                                        
3599                                                  
3600         if (parser->m_ns_triplets) { /* appen    
3601           parser->m_tempPool.ptr[-1] = parser    
3602           s = b->prefix->name;                   
3603           do {                                   
3604             if (! poolAppendChar(&parser->m_t    
3605               return XML_ERROR_NO_MEMORY;        
3606           } while (*s++);                        
3607         }                                        
3608                                                  
3609         /* store expanded name in attribute l    
3610         s = poolStart(&parser->m_tempPool);      
3611         poolFinish(&parser->m_tempPool);         
3612         appAtts[i] = s;                          
3613                                                  
3614         /* fill empty slot with new version,     
3615         parser->m_nsAtts[j].version = version    
3616         parser->m_nsAtts[j].hash = uriHash;      
3617         parser->m_nsAtts[j].uriName = s;         
3618                                                  
3619         if (! --nPrefixes) {                     
3620           i += 2;                                
3621           break;                                 
3622         }                                        
3623       } else                     /* not prefi    
3624         ((XML_Char *)s)[-1] = 0; /* clear fla    
3625     }                                            
3626   }                                              
3627   /* clear flags for the remaining attributes    
3628   for (; i < attIndex; i += 2)                   
3629     ((XML_Char *)(appAtts[i]))[-1] = 0;          
3630   for (binding = *bindingsPtr; binding; bindi    
3631     binding->attId->name[-1] = 0;                
3632                                                  
3633   if (! parser->m_ns)                            
3634     return XML_ERROR_NONE;                       
3635                                                  
3636   /* expand the element type name */             
3637   if (elementType->prefix) {                     
3638     binding = elementType->prefix->binding;      
3639     if (! binding)                               
3640       return XML_ERROR_UNBOUND_PREFIX;           
3641     localPart = tagNamePtr->str;                 
3642     while (*localPart++ != XML_T(ASCII_COLON)    
3643       ;                                          
3644   } else if (dtd->defaultPrefix.binding) {       
3645     binding = dtd->defaultPrefix.binding;        
3646     localPart = tagNamePtr->str;                 
3647   } else                                         
3648     return XML_ERROR_NONE;                       
3649   prefixLen = 0;                                 
3650   if (parser->m_ns_triplets && binding->prefi    
3651     for (; binding->prefix->name[prefixLen++]    
3652       ; /* prefixLen includes null terminator    
3653   }                                              
3654   tagNamePtr->localPart = localPart;             
3655   tagNamePtr->uriLen = binding->uriLen;          
3656   tagNamePtr->prefix = binding->prefix->name;    
3657   tagNamePtr->prefixLen = prefixLen;             
3658   for (i = 0; localPart[i++];)                   
3659     ; /* i includes null terminator */           
3660                                                  
3661   /* Detect and prevent integer overflow */      
3662   if (binding->uriLen > INT_MAX - prefixLen      
3663       || i > INT_MAX - (binding->uriLen + pre    
3664     return XML_ERROR_NO_MEMORY;                  
3665   }                                              
3666                                                  
3667   n = i + binding->uriLen + prefixLen;           
3668   if (n > binding->uriAlloc) {                   
3669     TAG *p;                                      
3670                                                  
3671     /* Detect and prevent integer overflow */    
3672     if (n > INT_MAX - EXPAND_SPARE) {            
3673       return XML_ERROR_NO_MEMORY;                
3674     }                                            
3675     /* Detect and prevent integer overflow.      
3676      * The preprocessor guard addresses the "    
3677      * from -Wtype-limits on platforms where     
3678      * sizeof(unsigned int) < sizeof(size_t),    
3679 #if UINT_MAX >= SIZE_MAX                         
3680     if ((unsigned)(n + EXPAND_SPARE) > (size_    
3681       return XML_ERROR_NO_MEMORY;                
3682     }                                            
3683 #endif                                           
3684                                                  
3685     uri = (XML_Char *)MALLOC(parser, (n + EXP    
3686     if (! uri)                                   
3687       return XML_ERROR_NO_MEMORY;                
3688     binding->uriAlloc = n + EXPAND_SPARE;        
3689     memcpy(uri, binding->uri, binding->uriLen    
3690     for (p = parser->m_tagStack; p; p = p->pa    
3691       if (p->name.str == binding->uri)           
3692         p->name.str = uri;                       
3693     FREE(parser, binding->uri);                  
3694     binding->uri = uri;                          
3695   }                                              
3696   /* if m_namespaceSeparator != '\0' then uri    
3697   uri = binding->uri + binding->uriLen;          
3698   memcpy(uri, localPart, i * sizeof(XML_Char)    
3699   /* we always have a namespace separator bet    
3700   if (prefixLen) {                               
3701     uri += i - 1;                                
3702     *uri = parser->m_namespaceSeparator; /* r    
3703     memcpy(uri + 1, binding->prefix->name, pr    
3704   }                                              
3705   tagNamePtr->str = binding->uri;                
3706   return XML_ERROR_NONE;                         
3707 }                                                
3708                                                  
3709 static XML_Bool                                  
3710 is_rfc3986_uri_char(XML_Char candidate) {        
3711   // For the RFC 3986 ANBF grammar see           
3712   // https://datatracker.ietf.org/doc/html/rf    
3713                                                  
3714   switch (candidate) {                           
3715   // From rule "ALPHA" (uppercase half)          
3716   case 'A':                                      
3717   case 'B':                                      
3718   case 'C':                                      
3719   case 'D':                                      
3720   case 'E':                                      
3721   case 'F':                                      
3722   case 'G':                                      
3723   case 'H':                                      
3724   case 'I':                                      
3725   case 'J':                                      
3726   case 'K':                                      
3727   case 'L':                                      
3728   case 'M':                                      
3729   case 'N':                                      
3730   case 'O':                                      
3731   case 'P':                                      
3732   case 'Q':                                      
3733   case 'R':                                      
3734   case 'S':                                      
3735   case 'T':                                      
3736   case 'U':                                      
3737   case 'V':                                      
3738   case 'W':                                      
3739   case 'X':                                      
3740   case 'Y':                                      
3741   case 'Z':                                      
3742                                                  
3743   // From rule "ALPHA" (lowercase half)          
3744   case 'a':                                      
3745   case 'b':                                      
3746   case 'c':                                      
3747   case 'd':                                      
3748   case 'e':                                      
3749   case 'f':                                      
3750   case 'g':                                      
3751   case 'h':                                      
3752   case 'i':                                      
3753   case 'j':                                      
3754   case 'k':                                      
3755   case 'l':                                      
3756   case 'm':                                      
3757   case 'n':                                      
3758   case 'o':                                      
3759   case 'p':                                      
3760   case 'q':                                      
3761   case 'r':                                      
3762   case 's':                                      
3763   case 't':                                      
3764   case 'u':                                      
3765   case 'v':                                      
3766   case 'w':                                      
3767   case 'x':                                      
3768   case 'y':                                      
3769   case 'z':                                      
3770                                                  
3771   // From rule "DIGIT"                           
3772   case '0':                                      
3773   case '1':                                      
3774   case '2':                                      
3775   case '3':                                      
3776   case '4':                                      
3777   case '5':                                      
3778   case '6':                                      
3779   case '7':                                      
3780   case '8':                                      
3781   case '9':                                      
3782                                                  
3783   // From rule "pct-encoded"                     
3784   case '%':                                      
3785                                                  
3786   // From rule "unreserved"                      
3787   case '-':                                      
3788   case '.':                                      
3789   case '_':                                      
3790   case '~':                                      
3791                                                  
3792   // From rule "gen-delims"                      
3793   case ':':                                      
3794   case '/':                                      
3795   case '?':                                      
3796   case '#':                                      
3797   case '[':                                      
3798   case ']':                                      
3799   case '@':                                      
3800                                                  
3801   // From rule "sub-delims"                      
3802   case '!':                                      
3803   case '$':                                      
3804   case '&':                                      
3805   case '\'':                                     
3806   case '(':                                      
3807   case ')':                                      
3808   case '*':                                      
3809   case '+':                                      
3810   case ',':                                      
3811   case ';':                                      
3812   case '=':                                      
3813     return XML_TRUE;                             
3814                                                  
3815   default:                                       
3816     return XML_FALSE;                            
3817   }                                              
3818 }                                                
3819                                                  
3820 /* addBinding() overwrites the value of prefi    
3821    Therefore one must keep track of the old v    
3822 */                                               
3823 static enum XML_Error                            
3824 addBinding(XML_Parser parser, PREFIX *prefix,    
3825            const XML_Char *uri, BINDING **bin    
3826   // "http://www.w3.org/XML/1998/namespace"      
3827   static const XML_Char xmlNamespace[]           
3828       = {ASCII_h,      ASCII_t,     ASCII_t,     
3829          ASCII_SLASH,  ASCII_SLASH, ASCII_w,     
3830          ASCII_PERIOD, ASCII_w,     ASCII_3,     
3831          ASCII_r,      ASCII_g,     ASCII_SLA    
3832          ASCII_L,      ASCII_SLASH, ASCII_1,     
3833          ASCII_8,      ASCII_SLASH, ASCII_n,     
3834          ASCII_e,      ASCII_s,     ASCII_p,     
3835          ASCII_e,      '\0'};                    
3836   static const int xmlLen = (int)sizeof(xmlNa    
3837   // "http://www.w3.org/2000/xmlns/"             
3838   static const XML_Char xmlnsNamespace[]         
3839       = {ASCII_h,     ASCII_t,      ASCII_t,     
3840          ASCII_SLASH, ASCII_w,      ASCII_w,     
3841          ASCII_3,     ASCII_PERIOD, ASCII_o,     
3842          ASCII_2,     ASCII_0,      ASCII_0,     
3843          ASCII_m,     ASCII_l,      ASCII_n,     
3844   static const int xmlnsLen                      
3845       = (int)sizeof(xmlnsNamespace) / sizeof(    
3846                                                  
3847   XML_Bool mustBeXML = XML_FALSE;                
3848   XML_Bool isXML = XML_TRUE;                     
3849   XML_Bool isXMLNS = XML_TRUE;                   
3850                                                  
3851   BINDING *b;                                    
3852   int len;                                       
3853                                                  
3854   /* empty URI is only valid for default name    
3855   if (*uri == XML_T('\0') && prefix->name)       
3856     return XML_ERROR_UNDECLARING_PREFIX;         
3857                                                  
3858   if (prefix->name && prefix->name[0] == XML_    
3859       && prefix->name[1] == XML_T(ASCII_m)       
3860       && prefix->name[2] == XML_T(ASCII_l)) {    
3861     /* Not allowed to bind xmlns */              
3862     if (prefix->name[3] == XML_T(ASCII_n) &&     
3863         && prefix->name[5] == XML_T('\0'))       
3864       return XML_ERROR_RESERVED_PREFIX_XMLNS;    
3865                                                  
3866     if (prefix->name[3] == XML_T('\0'))          
3867       mustBeXML = XML_TRUE;                      
3868   }                                              
3869                                                  
3870   for (len = 0; uri[len]; len++) {               
3871     if (isXML && (len > xmlLen || uri[len] !=    
3872       isXML = XML_FALSE;                         
3873                                                  
3874     if (! mustBeXML && isXMLNS                   
3875         && (len > xmlnsLen || uri[len] != xml    
3876       isXMLNS = XML_FALSE;                       
3877                                                  
3878     // NOTE: While Expat does not validate na    
3879     //       today (and is not REQUIRED to do    
3880     //       namespaces specification) we hav    
3881     //       the application on top of Expat     
3882     //       element names ("qualified names"    
3883     //       "[uri sep] local [sep prefix] '\    
3884     //       in its element handler code) can    
3885     //       putting additional namespace sep    
3886     //       declarations.  That would be amb    
3887     //                                           
3888     //       While the HTML API docs of funct    
3889     //       advising against use of a namesp    
3890     //       appear in a URI for >20 years no    
3891     //       are using URI characters (':' (c    
3892     //       namespace separator, in practice    
3893     //       functional, we only reject names    
3894     //       application-chosen namespace sep    
3895     //       is a non-URI character with rega    
3896     if (parser->m_ns && (uri[len] == parser->    
3897         && ! is_rfc3986_uri_char(uri[len])) {    
3898       return XML_ERROR_SYNTAX;                   
3899     }                                            
3900   }                                              
3901   isXML = isXML && len == xmlLen;                
3902   isXMLNS = isXMLNS && len == xmlnsLen;          
3903                                                  
3904   if (mustBeXML != isXML)                        
3905     return mustBeXML ? XML_ERROR_RESERVED_PRE    
3906                      : XML_ERROR_RESERVED_NAM    
3907                                                  
3908   if (isXMLNS)                                   
3909     return XML_ERROR_RESERVED_NAMESPACE_URI;     
3910                                                  
3911   if (parser->m_namespaceSeparator)              
3912     len++;                                       
3913   if (parser->m_freeBindingList) {               
3914     b = parser->m_freeBindingList;               
3915     if (len > b->uriAlloc) {                     
3916       /* Detect and prevent integer overflow     
3917       if (len > INT_MAX - EXPAND_SPARE) {        
3918         return XML_ERROR_NO_MEMORY;              
3919       }                                          
3920                                                  
3921       /* Detect and prevent integer overflow.    
3922        * The preprocessor guard addresses the    
3923        * from -Wtype-limits on platforms wher    
3924        * sizeof(unsigned int) < sizeof(size_t    
3925 #if UINT_MAX >= SIZE_MAX                         
3926       if ((unsigned)(len + EXPAND_SPARE) > (s    
3927         return XML_ERROR_NO_MEMORY;              
3928       }                                          
3929 #endif                                           
3930                                                  
3931       XML_Char *temp = (XML_Char *)REALLOC(      
3932           parser, b->uri, sizeof(XML_Char) *     
3933       if (temp == NULL)                          
3934         return XML_ERROR_NO_MEMORY;              
3935       b->uri = temp;                             
3936       b->uriAlloc = len + EXPAND_SPARE;          
3937     }                                            
3938     parser->m_freeBindingList = b->nextTagBin    
3939   } else {                                       
3940     b = (BINDING *)MALLOC(parser, sizeof(BIND    
3941     if (! b)                                     
3942       return XML_ERROR_NO_MEMORY;                
3943                                                  
3944     /* Detect and prevent integer overflow */    
3945     if (len > INT_MAX - EXPAND_SPARE) {          
3946       return XML_ERROR_NO_MEMORY;                
3947     }                                            
3948     /* Detect and prevent integer overflow.      
3949      * The preprocessor guard addresses the "    
3950      * from -Wtype-limits on platforms where     
3951      * sizeof(unsigned int) < sizeof(size_t),    
3952 #if UINT_MAX >= SIZE_MAX                         
3953     if ((unsigned)(len + EXPAND_SPARE) > (siz    
3954       return XML_ERROR_NO_MEMORY;                
3955     }                                            
3956 #endif                                           
3957                                                  
3958     b->uri                                       
3959         = (XML_Char *)MALLOC(parser, sizeof(X    
3960     if (! b->uri) {                              
3961       FREE(parser, b);                           
3962       return XML_ERROR_NO_MEMORY;                
3963     }                                            
3964     b->uriAlloc = len + EXPAND_SPARE;            
3965   }                                              
3966   b->uriLen = len;                               
3967   memcpy(b->uri, uri, len * sizeof(XML_Char))    
3968   if (parser->m_namespaceSeparator)              
3969     b->uri[len - 1] = parser->m_namespaceSepa    
3970   b->prefix = prefix;                            
3971   b->attId = attId;                              
3972   b->prevPrefixBinding = prefix->binding;        
3973   /* NULL binding when default namespace unde    
3974   if (*uri == XML_T('\0') && prefix == &parse    
3975     prefix->binding = NULL;                      
3976   else                                           
3977     prefix->binding = b;                         
3978   b->nextTagBinding = *bindingsPtr;              
3979   *bindingsPtr = b;                              
3980   /* if attId == NULL then we are not startin    
3981   if (attId && parser->m_startNamespaceDeclHa    
3982     parser->m_startNamespaceDeclHandler(parse    
3983                                         prefi    
3984   return XML_ERROR_NONE;                         
3985 }                                                
3986                                                  
3987 /* The idea here is to avoid using stack for     
3988    the whole file is parsed with one call.       
3989 */                                               
3990 static enum XML_Error PTRCALL                    
3991 cdataSectionProcessor(XML_Parser parser, cons    
3992                       const char **endPtr) {     
3993   enum XML_Error result = doCdataSection(        
3994       parser, parser->m_encoding, &start, end    
3995       (XML_Bool)! parser->m_parsingStatus.fin    
3996   if (result != XML_ERROR_NONE)                  
3997     return result;                               
3998   if (start) {                                   
3999     if (parser->m_parentParser) { /* we are p    
4000       parser->m_processor = externalEntityCon    
4001       return externalEntityContentProcessor(p    
4002     } else {                                     
4003       parser->m_processor = contentProcessor;    
4004       return contentProcessor(parser, start,     
4005     }                                            
4006   }                                              
4007   return result;                                 
4008 }                                                
4009                                                  
4010 /* startPtr gets set to non-null if the secti    
4011    the section is not yet closed.                
4012 */                                               
4013 static enum XML_Error                            
4014 doCdataSection(XML_Parser parser, const ENCOD    
4015                const char *end, const char **    
4016                enum XML_Account account) {       
4017   const char *s = *startPtr;                     
4018   const char **eventPP;                          
4019   const char **eventEndPP;                       
4020   if (enc == parser->m_encoding) {               
4021     eventPP = &parser->m_eventPtr;               
4022     *eventPP = s;                                
4023     eventEndPP = &parser->m_eventEndPtr;         
4024   } else {                                       
4025     eventPP = &(parser->m_openInternalEntitie    
4026     eventEndPP = &(parser->m_openInternalEnti    
4027   }                                              
4028   *eventPP = s;                                  
4029   *startPtr = NULL;                              
4030                                                  
4031   for (;;) {                                     
4032     const char *next = s; /* in case of XML_T    
4033     int tok = XmlCdataSectionTok(enc, s, end,    
4034 #ifdef XML_DTD                                   
4035     if (! accountingDiffTolerated(parser, tok    
4036       accountingOnAbort(parser);                 
4037       return XML_ERROR_AMPLIFICATION_LIMIT_BR    
4038     }                                            
4039 #else                                            
4040     UNUSED_P(account);                           
4041 #endif                                           
4042     *eventEndPP = next;                          
4043     switch (tok) {                               
4044     case XML_TOK_CDATA_SECT_CLOSE:               
4045       if (parser->m_endCdataSectionHandler)      
4046         parser->m_endCdataSectionHandler(pars    
4047       /* BEGIN disabled code */                  
4048       /* see comment under XML_TOK_CDATA_SECT    
4049       else if (0 && parser->m_characterDataHa    
4050         parser->m_characterDataHandler(parser    
4051                                        0);       
4052       /* END disabled code */                    
4053       else if (parser->m_defaultHandler)         
4054         reportDefault(parser, enc, s, next);     
4055       *startPtr = next;                          
4056       *nextPtr = next;                           
4057       if (parser->m_parsingStatus.parsing ==     
4058         return XML_ERROR_ABORTED;                
4059       else                                       
4060         return XML_ERROR_NONE;                   
4061     case XML_TOK_DATA_NEWLINE:                   
4062       if (parser->m_characterDataHandler) {      
4063         XML_Char c = 0xA;                        
4064         parser->m_characterDataHandler(parser    
4065       } else if (parser->m_defaultHandler)       
4066         reportDefault(parser, enc, s, next);     
4067       break;                                     
4068     case XML_TOK_DATA_CHARS: {                   
4069       XML_CharacterDataHandler charDataHandle    
4070       if (charDataHandler) {                     
4071         if (MUST_CONVERT(enc, s)) {              
4072           for (;;) {                             
4073             ICHAR *dataPtr = (ICHAR *)parser-    
4074             const enum XML_Convert_Result con    
4075                 enc, &s, next, &dataPtr, (ICH    
4076             *eventEndPP = next;                  
4077             charDataHandler(parser->m_handler    
4078                             (int)(dataPtr - (    
4079             if ((convert_res == XML_CONVERT_C    
4080                 || (convert_res == XML_CONVER    
4081               break;                             
4082             *eventPP = s;                        
4083           }                                      
4084         } else                                   
4085           charDataHandler(parser->m_handlerAr    
4086                           (int)((XML_Char *)n    
4087       } else if (parser->m_defaultHandler)       
4088         reportDefault(parser, enc, s, next);     
4089     } break;                                     
4090     case XML_TOK_INVALID:                        
4091       *eventPP = next;                           
4092       return XML_ERROR_INVALID_TOKEN;            
4093     case XML_TOK_PARTIAL_CHAR:                   
4094       if (haveMore) {                            
4095         *nextPtr = s;                            
4096         return XML_ERROR_NONE;                   
4097       }                                          
4098       return XML_ERROR_PARTIAL_CHAR;             
4099     case XML_TOK_PARTIAL:                        
4100     case XML_TOK_NONE:                           
4101       if (haveMore) {                            
4102         *nextPtr = s;                            
4103         return XML_ERROR_NONE;                   
4104       }                                          
4105       return XML_ERROR_UNCLOSED_CDATA_SECTION    
4106     default:                                     
4107       /* Every token returned by XmlCdataSect    
4108        * explicit case, so this default case     
4109        * We retain it as a safety net and exc    
4110        * statistics.                             
4111        *                                         
4112        * LCOV_EXCL_START                         
4113        */                                        
4114       *eventPP = next;                           
4115       return XML_ERROR_UNEXPECTED_STATE;         
4116       /* LCOV_EXCL_STOP */                       
4117     }                                            
4118                                                  
4119     *eventPP = s = next;                         
4120     switch (parser->m_parsingStatus.parsing)     
4121     case XML_SUSPENDED:                          
4122       *nextPtr = next;                           
4123       return XML_ERROR_NONE;                     
4124     case XML_FINISHED:                           
4125       return XML_ERROR_ABORTED;                  
4126     default:;                                    
4127     }                                            
4128   }                                              
4129   /* not reached */                              
4130 }                                                
4131                                                  
4132 #ifdef XML_DTD                                   
4133                                                  
4134 /* The idea here is to avoid using stack for     
4135    the whole file is parsed with one call.       
4136 */                                               
4137 static enum XML_Error PTRCALL                    
4138 ignoreSectionProcessor(XML_Parser parser, con    
4139                        const char **endPtr) {    
4140   enum XML_Error result                          
4141       = doIgnoreSection(parser, parser->m_enc    
4142                         (XML_Bool)! parser->m    
4143   if (result != XML_ERROR_NONE)                  
4144     return result;                               
4145   if (start) {                                   
4146     parser->m_processor = prologProcessor;       
4147     return prologProcessor(parser, start, end    
4148   }                                              
4149   return result;                                 
4150 }                                                
4151                                                  
4152 /* startPtr gets set to non-null is the secti    
4153    if the section is not yet closed.             
4154 */                                               
4155 static enum XML_Error                            
4156 doIgnoreSection(XML_Parser parser, const ENCO    
4157                 const char *end, const char *    
4158   const char *next = *startPtr; /* in case of    
4159   int tok;                                       
4160   const char *s = *startPtr;                     
4161   const char **eventPP;                          
4162   const char **eventEndPP;                       
4163   if (enc == parser->m_encoding) {               
4164     eventPP = &parser->m_eventPtr;               
4165     *eventPP = s;                                
4166     eventEndPP = &parser->m_eventEndPtr;         
4167   } else {                                       
4168     /* It's not entirely clear, but it seems     
4169      * of code cannot be executed.  The only     
4170      * is not 'encoding' are when this functi    
4171      * from the internal entity processing, a    
4172      * error in internal entities.               
4173      *                                           
4174      * Since it really isn't clear that this     
4175      * and just remove it from our coverage t    
4176      *                                           
4177      * LCOV_EXCL_START                           
4178      */                                          
4179     eventPP = &(parser->m_openInternalEntitie    
4180     eventEndPP = &(parser->m_openInternalEnti    
4181     /* LCOV_EXCL_STOP */                         
4182   }                                              
4183   *eventPP = s;                                  
4184   *startPtr = NULL;                              
4185   tok = XmlIgnoreSectionTok(enc, s, end, &nex    
4186 #  ifdef XML_DTD                                 
4187   if (! accountingDiffTolerated(parser, tok,     
4188                                 XML_ACCOUNT_D    
4189     accountingOnAbort(parser);                   
4190     return XML_ERROR_AMPLIFICATION_LIMIT_BREA    
4191   }                                              
4192 #  endif                                         
4193   *eventEndPP = next;                            
4194   switch (tok) {                                 
4195   case XML_TOK_IGNORE_SECT:                      
4196     if (parser->m_defaultHandler)                
4197       reportDefault(parser, enc, s, next);       
4198     *startPtr = next;                            
4199     *nextPtr = next;                             
4200     if (parser->m_parsingStatus.parsing == XM    
4201       return XML_ERROR_ABORTED;                  
4202     else                                         
4203       return XML_ERROR_NONE;                     
4204   case XML_TOK_INVALID:                          
4205     *eventPP = next;                             
4206     return XML_ERROR_INVALID_TOKEN;              
4207   case XML_TOK_PARTIAL_CHAR:                     
4208     if (haveMore) {                              
4209       *nextPtr = s;                              
4210       return XML_ERROR_NONE;                     
4211     }                                            
4212     return XML_ERROR_PARTIAL_CHAR;               
4213   case XML_TOK_PARTIAL:                          
4214   case XML_TOK_NONE:                             
4215     if (haveMore) {                              
4216       *nextPtr = s;                              
4217       return XML_ERROR_NONE;                     
4218     }                                            
4219     return XML_ERROR_SYNTAX; /* XML_ERROR_UNC    
4220   default:                                       
4221     /* All of the tokens that XmlIgnoreSectio    
4222      * explicit cases to handle them, so this    
4223      * executed.  We keep it as a safety net     
4224      * from our test coverage statistics.        
4225      *                                           
4226      * LCOV_EXCL_START                           
4227      */                                          
4228     *eventPP = next;                             
4229     return XML_ERROR_UNEXPECTED_STATE;           
4230     /* LCOV_EXCL_STOP */                         
4231   }                                              
4232   /* not reached */                              
4233 }                                                
4234                                                  
4235 #endif /* XML_DTD */                             
4236                                                  
4237 static enum XML_Error                            
4238 initializeEncoding(XML_Parser parser) {          
4239   const char *s;                                 
4240 #ifdef XML_UNICODE                               
4241   char encodingBuf[128];                         
4242   /* See comments about `protocolEncodingName    
4243   if (! parser->m_protocolEncodingName)          
4244     s = NULL;                                    
4245   else {                                         
4246     int i;                                       
4247     for (i = 0; parser->m_protocolEncodingNam    
4248       if (i == sizeof(encodingBuf) - 1           
4249           || (parser->m_protocolEncodingName[    
4250         encodingBuf[0] = '\0';                   
4251         break;                                   
4252       }                                          
4253       encodingBuf[i] = (char)parser->m_protoc    
4254     }                                            
4255     encodingBuf[i] = '\0';                       
4256     s = encodingBuf;                             
4257   }                                              
4258 #else                                            
4259   s = parser->m_protocolEncodingName;            
4260 #endif                                           
4261   if ((parser->m_ns ? XmlInitEncodingNS : Xml    
4262           &parser->m_initEncoding, &parser->m    
4263     return XML_ERROR_NONE;                       
4264   return handleUnknownEncoding(parser, parser    
4265 }                                                
4266                                                  
4267 static enum XML_Error                            
4268 processXmlDecl(XML_Parser parser, int isGener    
4269                const char *next) {               
4270   const char *encodingName = NULL;               
4271   const XML_Char *storedEncName = NULL;          
4272   const ENCODING *newEncoding = NULL;            
4273   const char *version = NULL;                    
4274   const char *versionend = NULL;                 
4275   const XML_Char *storedversion = NULL;          
4276   int standalone = -1;                           
4277                                                  
4278 #ifdef XML_DTD                                   
4279   if (! accountingDiffTolerated(parser, XML_T    
4280                                 XML_ACCOUNT_D    
4281     accountingOnAbort(parser);                   
4282     return XML_ERROR_AMPLIFICATION_LIMIT_BREA    
4283   }                                              
4284 #endif                                           
4285                                                  
4286   if (! (parser->m_ns ? XmlParseXmlDeclNS : X    
4287           isGeneralTextEntity, parser->m_enco    
4288           &version, &versionend, &encodingNam    
4289     if (isGeneralTextEntity)                     
4290       return XML_ERROR_TEXT_DECL;                
4291     else                                         
4292       return XML_ERROR_XML_DECL;                 
4293   }                                              
4294   if (! isGeneralTextEntity && standalone ==     
4295     parser->m_dtd->standalone = XML_TRUE;        
4296 #ifdef XML_DTD                                   
4297     if (parser->m_paramEntityParsing             
4298         == XML_PARAM_ENTITY_PARSING_UNLESS_ST    
4299       parser->m_paramEntityParsing = XML_PARA    
4300 #endif /* XML_DTD */                             
4301   }                                              
4302   if (parser->m_xmlDeclHandler) {                
4303     if (encodingName != NULL) {                  
4304       storedEncName = poolStoreString(           
4305           &parser->m_temp2Pool, parser->m_enc    
4306           encodingName + XmlNameLength(parser    
4307       if (! storedEncName)                       
4308         return XML_ERROR_NO_MEMORY;              
4309       poolFinish(&parser->m_temp2Pool);          
4310     }                                            
4311     if (version) {                               
4312       storedversion                              
4313           = poolStoreString(&parser->m_temp2P    
4314                             versionend - pars    
4315       if (! storedversion)                       
4316         return XML_ERROR_NO_MEMORY;              
4317     }                                            
4318     parser->m_xmlDeclHandler(parser->m_handle    
4319                              standalone);        
4320   } else if (parser->m_defaultHandler)           
4321     reportDefault(parser, parser->m_encoding,    
4322   if (parser->m_protocolEncodingName == NULL)    
4323     if (newEncoding) {                           
4324       /* Check that the specified encoding do    
4325        * the parser has already deduced.  Do     
4326        * of bytes in the smallest representat    
4327        * this is UTF-16, is it the same endia    
4328        */                                        
4329       if (newEncoding->minBytesPerChar != par    
4330           || (newEncoding->minBytesPerChar ==    
4331               && newEncoding != parser->m_enc    
4332         parser->m_eventPtr = encodingName;       
4333         return XML_ERROR_INCORRECT_ENCODING;     
4334       }                                          
4335       parser->m_encoding = newEncoding;          
4336     } else if (encodingName) {                   
4337       enum XML_Error result;                     
4338       if (! storedEncName) {                     
4339         storedEncName = poolStoreString(         
4340             &parser->m_temp2Pool, parser->m_e    
4341             encodingName + XmlNameLength(pars    
4342         if (! storedEncName)                     
4343           return XML_ERROR_NO_MEMORY;            
4344       }                                          
4345       result = handleUnknownEncoding(parser,     
4346       poolClear(&parser->m_temp2Pool);           
4347       if (result == XML_ERROR_UNKNOWN_ENCODIN    
4348         parser->m_eventPtr = encodingName;       
4349       return result;                             
4350     }                                            
4351   }                                              
4352                                                  
4353   if (storedEncName || storedversion)            
4354     poolClear(&parser->m_temp2Pool);             
4355                                                  
4356   return XML_ERROR_NONE;                         
4357 }                                                
4358                                                  
4359 static enum XML_Error                            
4360 handleUnknownEncoding(XML_Parser parser, cons    
4361   if (parser->m_unknownEncodingHandler) {        
4362     XML_Encoding info;                           
4363     int i;                                       
4364     for (i = 0; i < 256; i++)                    
4365       info.map[i] = -1;                          
4366     info.convert = NULL;                         
4367     info.data = NULL;                            
4368     info.release = NULL;                         
4369     if (parser->m_unknownEncodingHandler(pars    
4370                                          enco    
4371       ENCODING *enc;                             
4372       parser->m_unknownEncodingMem = MALLOC(p    
4373       if (! parser->m_unknownEncodingMem) {      
4374         if (info.release)                        
4375           info.release(info.data);               
4376         return XML_ERROR_NO_MEMORY;              
4377       }                                          
4378       enc = (parser->m_ns ? XmlInitUnknownEnc    
4379           parser->m_unknownEncodingMem, info.    
4380       if (enc) {                                 
4381         parser->m_unknownEncodingData = info.    
4382         parser->m_unknownEncodingRelease = in    
4383         parser->m_encoding = enc;                
4384         return XML_ERROR_NONE;                   
4385       }                                          
4386     }                                            
4387     if (info.release != NULL)                    
4388       info.release(info.data);                   
4389   }                                              
4390   return XML_ERROR_UNKNOWN_ENCODING;             
4391 }                                                
4392                                                  
4393 static enum XML_Error PTRCALL                    
4394 prologInitProcessor(XML_Parser parser, const     
4395                     const char **nextPtr) {      
4396   enum XML_Error result = initializeEncoding(    
4397   if (result != XML_ERROR_NONE)                  
4398     return result;                               
4399   parser->m_processor = prologProcessor;         
4400   return prologProcessor(parser, s, end, next    
4401 }                                                
4402                                                  
4403 #ifdef XML_DTD                                   
4404                                                  
4405 static enum XML_Error PTRCALL                    
4406 externalParEntInitProcessor(XML_Parser parser    
4407                             const char **next    
4408   enum XML_Error result = initializeEncoding(    
4409   if (result != XML_ERROR_NONE)                  
4410     return result;                               
4411                                                  
4412   /* we know now that XML_Parse(Buffer) has b    
4413      so we consider the external parameter en    
4414   parser->m_dtd->paramEntityRead = XML_TRUE;     
4415                                                  
4416   if (parser->m_prologState.inEntityValue) {     
4417     parser->m_processor = entityValueInitProc    
4418     return entityValueInitProcessor(parser, s    
4419   } else {                                       
4420     parser->m_processor = externalParEntProce    
4421     return externalParEntProcessor(parser, s,    
4422   }                                              
4423 }                                                
4424                                                  
4425 static enum XML_Error PTRCALL                    
4426 entityValueInitProcessor(XML_Parser parser, c    
4427                          const char **nextPtr    
4428   int tok;                                       
4429   const char *start = s;                         
4430   const char *next = start;                      
4431   parser->m_eventPtr = start;                    
4432                                                  
4433   for (;;) {                                     
4434     tok = XmlPrologTok(parser->m_encoding, st    
4435     /* Note: Except for XML_TOK_BOM below, th    
4436              - storeEntityValue                  
4437              - processXmlDecl                    
4438     */                                           
4439     parser->m_eventEndPtr = next;                
4440     if (tok <= 0) {                              
4441       if (! parser->m_parsingStatus.finalBuff    
4442         *nextPtr = s;                            
4443         return XML_ERROR_NONE;                   
4444       }                                          
4445       switch (tok) {                             
4446       case XML_TOK_INVALID:                      
4447         return XML_ERROR_INVALID_TOKEN;          
4448       case XML_TOK_PARTIAL:                      
4449         return XML_ERROR_UNCLOSED_TOKEN;         
4450       case XML_TOK_PARTIAL_CHAR:                 
4451         return XML_ERROR_PARTIAL_CHAR;           
4452       case XML_TOK_NONE: /* start == end */      
4453       default:                                   
4454         break;                                   
4455       }                                          
4456       /* found end of entity value - can stor    
4457       return storeEntityValue(parser, parser-    
4458                               XML_ACCOUNT_DIR    
4459     } else if (tok == XML_TOK_XML_DECL) {        
4460       enum XML_Error result;                     
4461       result = processXmlDecl(parser, 0, star    
4462       if (result != XML_ERROR_NONE)              
4463         return result;                           
4464       /* At this point, m_parsingStatus.parsi    
4465        * that to happen, a parameter entity p    
4466        * to suspend the parser, which fails a    
4467        * be aborted, but can't be suspended.     
4468        */                                        
4469       if (parser->m_parsingStatus.parsing ==     
4470         return XML_ERROR_ABORTED;                
4471       *nextPtr = next;                           
4472       /* stop scanning for text declaration -    
4473       parser->m_processor = entityValueProces    
4474       return entityValueProcessor(parser, nex    
4475     }                                            
4476     /* If we are at the end of the buffer, th    
4477        return XML_TOK_NONE on the next call,     
4478        function to exit with *nextPtr set to     
4479        tokens, but not for the BOM - we would    
4480        then, when this routine is entered the    
4481        return XML_TOK_INVALID, since the BOM     
4482     */                                           
4483     else if (tok == XML_TOK_BOM && next == en    
4484              && ! parser->m_parsingStatus.fin    
4485 #  ifdef XML_DTD                                 
4486       if (! accountingDiffTolerated(parser, t    
4487                                     XML_ACCOU    
4488         accountingOnAbort(parser);               
4489         return XML_ERROR_AMPLIFICATION_LIMIT_    
4490       }                                          
4491 #  endif                                         
4492                                                  
4493       *nextPtr = next;                           
4494       return XML_ERROR_NONE;                     
4495     }                                            
4496     /* If we get this token, we have the star    
4497        normal tag, but not a declaration (i.e    
4498        "<!").  In a DTD context, that isn't l    
4499     */                                           
4500     else if (tok == XML_TOK_INSTANCE_START) {    
4501       *nextPtr = next;                           
4502       return XML_ERROR_SYNTAX;                   
4503     }                                            
4504     start = next;                                
4505     parser->m_eventPtr = start;                  
4506   }                                              
4507 }                                                
4508                                                  
4509 static enum XML_Error PTRCALL                    
4510 externalParEntProcessor(XML_Parser parser, co    
4511                         const char **nextPtr)    
4512   const char *next = s;                          
4513   int tok;                                       
4514                                                  
4515   tok = XmlPrologTok(parser->m_encoding, s, e    
4516   if (tok <= 0) {                                
4517     if (! parser->m_parsingStatus.finalBuffer    
4518       *nextPtr = s;                              
4519       return XML_ERROR_NONE;                     
4520     }                                            
4521     switch (tok) {                               
4522     case XML_TOK_INVALID:                        
4523       return XML_ERROR_INVALID_TOKEN;            
4524     case XML_TOK_PARTIAL:                        
4525       return XML_ERROR_UNCLOSED_TOKEN;           
4526     case XML_TOK_PARTIAL_CHAR:                   
4527       return XML_ERROR_PARTIAL_CHAR;             
4528     case XML_TOK_NONE: /* start == end */        
4529     default:                                     
4530       break;                                     
4531     }                                            
4532   }                                              
4533   /* This would cause the next stage, i.e. do    
4534      However, when parsing an external subset    
4535      as valid, and report a syntax error, so     
4536      account for the BOM bytes.                  
4537   */                                             
4538   else if (tok == XML_TOK_BOM) {                 
4539     if (! accountingDiffTolerated(parser, tok    
4540                                   XML_ACCOUNT    
4541       accountingOnAbort(parser);                 
4542       return XML_ERROR_AMPLIFICATION_LIMIT_BR    
4543     }                                            
4544                                                  
4545     s = next;                                    
4546     tok = XmlPrologTok(parser->m_encoding, s,    
4547   }                                              
4548                                                  
4549   parser->m_processor = prologProcessor;         
4550   return doProlog(parser, parser->m_encoding,    
4551                   (XML_Bool)! parser->m_parsi    
4552                   XML_ACCOUNT_DIRECT);           
4553 }                                                
4554                                                  
4555 static enum XML_Error PTRCALL                    
4556 entityValueProcessor(XML_Parser parser, const    
4557                      const char **nextPtr) {     
4558   const char *start = s;                         
4559   const char *next = s;                          
4560   const ENCODING *enc = parser->m_encoding;      
4561   int tok;                                       
4562                                                  
4563   for (;;) {                                     
4564     tok = XmlPrologTok(enc, start, end, &next    
4565     /* Note: These bytes are accounted later     
4566              - storeEntityValue                  
4567     */                                           
4568     if (tok <= 0) {                              
4569       if (! parser->m_parsingStatus.finalBuff    
4570         *nextPtr = s;                            
4571         return XML_ERROR_NONE;                   
4572       }                                          
4573       switch (tok) {                             
4574       case XML_TOK_INVALID:                      
4575         return XML_ERROR_INVALID_TOKEN;          
4576       case XML_TOK_PARTIAL:                      
4577         return XML_ERROR_UNCLOSED_TOKEN;         
4578       case XML_TOK_PARTIAL_CHAR:                 
4579         return XML_ERROR_PARTIAL_CHAR;           
4580       case XML_TOK_NONE: /* start == end */      
4581       default:                                   
4582         break;                                   
4583       }                                          
4584       /* found end of entity value - can stor    
4585       return storeEntityValue(parser, enc, s,    
4586     }                                            
4587     start = next;                                
4588   }                                              
4589 }                                                
4590                                                  
4591 #endif /* XML_DTD */                             
4592                                                  
4593 static enum XML_Error PTRCALL                    
4594 prologProcessor(XML_Parser parser, const char    
4595                 const char **nextPtr) {          
4596   const char *next = s;                          
4597   int tok = XmlPrologTok(parser->m_encoding,     
4598   return doProlog(parser, parser->m_encoding,    
4599                   (XML_Bool)! parser->m_parsi    
4600                   XML_ACCOUNT_DIRECT);           
4601 }                                                
4602                                                  
4603 static enum XML_Error                            
4604 doProlog(XML_Parser parser, const ENCODING *e    
4605          int tok, const char *next, const cha    
4606          XML_Bool allowClosingDoctype, enum X    
4607 #ifdef XML_DTD                                   
4608   static const XML_Char externalSubsetName[]     
4609 #endif /* XML_DTD */                             
4610   static const XML_Char atypeCDATA[]             
4611       = {ASCII_C, ASCII_D, ASCII_A, ASCII_T,     
4612   static const XML_Char atypeID[] = {ASCII_I,    
4613   static const XML_Char atypeIDREF[]             
4614       = {ASCII_I, ASCII_D, ASCII_R, ASCII_E,     
4615   static const XML_Char atypeIDREFS[]            
4616       = {ASCII_I, ASCII_D, ASCII_R, ASCII_E,     
4617   static const XML_Char atypeENTITY[]            
4618       = {ASCII_E, ASCII_N, ASCII_T, ASCII_I,     
4619   static const XML_Char atypeENTITIES[]          
4620       = {ASCII_E, ASCII_N, ASCII_T, ASCII_I,     
4621          ASCII_I, ASCII_E, ASCII_S, '\0'};       
4622   static const XML_Char atypeNMTOKEN[]           
4623       = {ASCII_N, ASCII_M, ASCII_T, ASCII_O,     
4624   static const XML_Char atypeNMTOKENS[]          
4625       = {ASCII_N, ASCII_M, ASCII_T, ASCII_O,     
4626          ASCII_E, ASCII_N, ASCII_S, '\0'};       
4627   static const XML_Char notationPrefix[]         
4628       = {ASCII_N, ASCII_O, ASCII_T, ASCII_A,     
4629          ASCII_I, ASCII_O, ASCII_N, ASCII_LPA    
4630   static const XML_Char enumValueSep[] = {ASC    
4631   static const XML_Char enumValueStart[] = {A    
4632                                                  
4633 #ifndef XML_DTD                                  
4634   UNUSED_P(account);                             
4635 #endif                                           
4636                                                  
4637   /* save one level of indirection */            
4638   DTD *const dtd = parser->m_dtd;                
4639                                                  
4640   const char **eventPP;                          
4641   const char **eventEndPP;                       
4642   enum XML_Content_Quant quant;                  
4643                                                  
4644   if (enc == parser->m_encoding) {               
4645     eventPP = &parser->m_eventPtr;               
4646     eventEndPP = &parser->m_eventEndPtr;         
4647   } else {                                       
4648     eventPP = &(parser->m_openInternalEntitie    
4649     eventEndPP = &(parser->m_openInternalEnti    
4650   }                                              
4651                                                  
4652   for (;;) {                                     
4653     int role;                                    
4654     XML_Bool handleDefault = XML_TRUE;           
4655     *eventPP = s;                                
4656     *eventEndPP = next;                          
4657     if (tok <= 0) {                              
4658       if (haveMore && tok != XML_TOK_INVALID)    
4659         *nextPtr = s;                            
4660         return XML_ERROR_NONE;                   
4661       }                                          
4662       switch (tok) {                             
4663       case XML_TOK_INVALID:                      
4664         *eventPP = next;                         
4665         return XML_ERROR_INVALID_TOKEN;          
4666       case XML_TOK_PARTIAL:                      
4667         return XML_ERROR_UNCLOSED_TOKEN;         
4668       case XML_TOK_PARTIAL_CHAR:                 
4669         return XML_ERROR_PARTIAL_CHAR;           
4670       case -XML_TOK_PROLOG_S:                    
4671         tok = -tok;                              
4672         break;                                   
4673       case XML_TOK_NONE:                         
4674 #ifdef XML_DTD                                   
4675         /* for internal PE NOT referenced bet    
4676         if (enc != parser->m_encoding            
4677             && ! parser->m_openInternalEntiti    
4678           *nextPtr = s;                          
4679           return XML_ERROR_NONE;                 
4680         }                                        
4681         /* WFC: PE Between Declarations - mus    
4682            complete markup, not only for exte    
4683            internal PEs if the reference occu    
4684         */                                       
4685         if (parser->m_isParamEntity || enc !=    
4686           if (XmlTokenRole(&parser->m_prologS    
4687               == XML_ROLE_ERROR)                 
4688             return XML_ERROR_INCOMPLETE_PE;      
4689           *nextPtr = s;                          
4690           return XML_ERROR_NONE;                 
4691         }                                        
4692 #endif /* XML_DTD */                             
4693         return XML_ERROR_NO_ELEMENTS;            
4694       default:                                   
4695         tok = -tok;                              
4696         next = end;                              
4697         break;                                   
4698       }                                          
4699     }                                            
4700     role = XmlTokenRole(&parser->m_prologStat    
4701 #ifdef XML_DTD                                   
4702     switch (role) {                              
4703     case XML_ROLE_INSTANCE_START: // bytes ac    
4704     case XML_ROLE_XML_DECL:       // bytes ac    
4705     case XML_ROLE_TEXT_DECL:      // bytes ac    
4706       break;                                     
4707     default:                                     
4708       if (! accountingDiffTolerated(parser, t    
4709         accountingOnAbort(parser);               
4710         return XML_ERROR_AMPLIFICATION_LIMIT_    
4711       }                                          
4712     }                                            
4713 #endif                                           
4714     switch (role) {                              
4715     case XML_ROLE_XML_DECL: {                    
4716       enum XML_Error result = processXmlDecl(    
4717       if (result != XML_ERROR_NONE)              
4718         return result;                           
4719       enc = parser->m_encoding;                  
4720       handleDefault = XML_FALSE;                 
4721     } break;                                     
4722     case XML_ROLE_DOCTYPE_NAME:                  
4723       if (parser->m_startDoctypeDeclHandler)     
4724         parser->m_doctypeName                    
4725             = poolStoreString(&parser->m_temp    
4726         if (! parser->m_doctypeName)             
4727           return XML_ERROR_NO_MEMORY;            
4728         poolFinish(&parser->m_tempPool);         
4729         parser->m_doctypePubid = NULL;           
4730         handleDefault = XML_FALSE;               
4731       }                                          
4732       parser->m_doctypeSysid = NULL; /* alway    
4733       break;                                     
4734     case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:       
4735       if (parser->m_startDoctypeDeclHandler)     
4736         parser->m_startDoctypeDeclHandler(       
4737             parser->m_handlerArg, parser->m_d    
4738             parser->m_doctypePubid, 1);          
4739         parser->m_doctypeName = NULL;            
4740         poolClear(&parser->m_tempPool);          
4741         handleDefault = XML_FALSE;               
4742       }                                          
4743       break;                                     
4744 #ifdef XML_DTD                                   
4745     case XML_ROLE_TEXT_DECL: {                   
4746       enum XML_Error result = processXmlDecl(    
4747       if (result != XML_ERROR_NONE)              
4748         return result;                           
4749       enc = parser->m_encoding;                  
4750       handleDefault = XML_FALSE;                 
4751     } break;                                     
4752 #endif /* XML_DTD */                             
4753     case XML_ROLE_DOCTYPE_PUBLIC_ID:             
4754 #ifdef XML_DTD                                   
4755       parser->m_useForeignDTD = XML_FALSE;       
4756       parser->m_declEntity = (ENTITY *)lookup    
4757           parser, &dtd->paramEntities, extern    
4758       if (! parser->m_declEntity)                
4759         return XML_ERROR_NO_MEMORY;              
4760 #endif /* XML_DTD */                             
4761       dtd->hasParamEntityRefs = XML_TRUE;        
4762       if (parser->m_startDoctypeDeclHandler)     
4763         XML_Char *pubId;                         
4764         if (! XmlIsPublicId(enc, s, next, eve    
4765           return XML_ERROR_PUBLICID;             
4766         pubId = poolStoreString(&parser->m_te    
4767                                 s + enc->minB    
4768                                 next - enc->m    
4769         if (! pubId)                             
4770           return XML_ERROR_NO_MEMORY;            
4771         normalizePublicId(pubId);                
4772         poolFinish(&parser->m_tempPool);         
4773         parser->m_doctypePubid = pubId;          
4774         handleDefault = XML_FALSE;               
4775         goto alreadyChecked;                     
4776       }                                          
4777       /* fall through */                         
4778     case XML_ROLE_ENTITY_PUBLIC_ID:              
4779       if (! XmlIsPublicId(enc, s, next, event    
4780         return XML_ERROR_PUBLICID;               
4781     alreadyChecked:                              
4782       if (dtd->keepProcessing && parser->m_de    
4783         XML_Char *tem                            
4784             = poolStoreString(&dtd->pool, enc    
4785                               next - enc->min    
4786         if (! tem)                               
4787           return XML_ERROR_NO_MEMORY;            
4788         normalizePublicId(tem);                  
4789         parser->m_declEntity->publicId = tem;    
4790         poolFinish(&dtd->pool);                  
4791         /* Don't suppress the default handler    
4792          * the XML_ROLE_DOCTYPE_PUBLIC_ID cas    
4793          */                                      
4794         if (parser->m_entityDeclHandler && ro    
4795           handleDefault = XML_FALSE;             
4796       }                                          
4797       break;                                     
4798     case XML_ROLE_DOCTYPE_CLOSE:                 
4799       if (allowClosingDoctype != XML_TRUE) {     
4800         /* Must not close doctype from within    
4801         return XML_ERROR_INVALID_TOKEN;          
4802       }                                          
4803                                                  
4804       if (parser->m_doctypeName) {               
4805         parser->m_startDoctypeDeclHandler(       
4806             parser->m_handlerArg, parser->m_d    
4807             parser->m_doctypePubid, 0);          
4808         poolClear(&parser->m_tempPool);          
4809         handleDefault = XML_FALSE;               
4810       }                                          
4811       /* parser->m_doctypeSysid will be non-N    
4812          XML_ROLE_DOCTYPE_SYSTEM_ID, even if     
4813          was not set, indicating an external     
4814       */                                         
4815 #ifdef XML_DTD                                   
4816       if (parser->m_doctypeSysid || parser->m    
4817         XML_Bool hadParamEntityRefs = dtd->ha    
4818         dtd->hasParamEntityRefs = XML_TRUE;      
4819         if (parser->m_paramEntityParsing         
4820             && parser->m_externalEntityRefHan    
4821           ENTITY *entity = (ENTITY *)lookup(p    
4822                                             e    
4823           if (! entity) {                        
4824             /* The external subset name "#" w    
4825              * inserted into the hash table a    
4826              * external entity parsing, so no    
4827              * and lookup() cannot fail.         
4828              */                                  
4829             return XML_ERROR_NO_MEMORY; /* LC    
4830           }                                      
4831           if (parser->m_useForeignDTD)           
4832             entity->base = parser->m_curBase;    
4833           dtd->paramEntityRead = XML_FALSE;      
4834           if (! parser->m_externalEntityRefHa    
4835                   parser->m_externalEntityRef    
4836                   entity->systemId, entity->p    
4837             return XML_ERROR_EXTERNAL_ENTITY_    
4838           if (dtd->paramEntityRead) {            
4839             if (! dtd->standalone && parser->    
4840                 && ! parser->m_notStandaloneH    
4841               return XML_ERROR_NOT_STANDALONE    
4842           }                                      
4843           /* if we didn't read the foreign DT    
4844              is no external subset and we mus    
4845           */                                     
4846           else if (! parser->m_doctypeSysid)     
4847             dtd->hasParamEntityRefs = hadPara    
4848           /* end of DTD - no need to update d    
4849         }                                        
4850         parser->m_useForeignDTD = XML_FALSE;     
4851       }                                          
4852 #endif /* XML_DTD */                             
4853       if (parser->m_endDoctypeDeclHandler) {     
4854         parser->m_endDoctypeDeclHandler(parse    
4855         handleDefault = XML_FALSE;               
4856       }                                          
4857       break;                                     
4858     case XML_ROLE_INSTANCE_START:                
4859 #ifdef XML_DTD                                   
4860       /* if there is no DOCTYPE declaration t    
4861          last chance to read the foreign DTD     
4862       */                                         
4863       if (parser->m_useForeignDTD) {             
4864         XML_Bool hadParamEntityRefs = dtd->ha    
4865         dtd->hasParamEntityRefs = XML_TRUE;      
4866         if (parser->m_paramEntityParsing         
4867             && parser->m_externalEntityRefHan    
4868           ENTITY *entity = (ENTITY *)lookup(p    
4869                                             e    
4870           if (! entity)                          
4871             return XML_ERROR_NO_MEMORY;          
4872           entity->base = parser->m_curBase;      
4873           dtd->paramEntityRead = XML_FALSE;      
4874           if (! parser->m_externalEntityRefHa    
4875                   parser->m_externalEntityRef    
4876                   entity->systemId, entity->p    
4877             return XML_ERROR_EXTERNAL_ENTITY_    
4878           if (dtd->paramEntityRead) {            
4879             if (! dtd->standalone && parser->    
4880                 && ! parser->m_notStandaloneH    
4881               return XML_ERROR_NOT_STANDALONE    
4882           }                                      
4883           /* if we didn't read the foreign DT    
4884              is no external subset and we mus    
4885           */                                     
4886           else                                   
4887             dtd->hasParamEntityRefs = hadPara    
4888           /* end of DTD - no need to update d    
4889         }                                        
4890       }                                          
4891 #endif /* XML_DTD */                             
4892       parser->m_processor = contentProcessor;    
4893       return contentProcessor(parser, s, end,    
4894     case XML_ROLE_ATTLIST_ELEMENT_NAME:          
4895       parser->m_declElementType = getElementT    
4896       if (! parser->m_declElementType)           
4897         return XML_ERROR_NO_MEMORY;              
4898       goto checkAttListDeclHandler;              
4899     case XML_ROLE_ATTRIBUTE_NAME:                
4900       parser->m_declAttributeId = getAttribut    
4901       if (! parser->m_declAttributeId)           
4902         return XML_ERROR_NO_MEMORY;              
4903       parser->m_declAttributeIsCdata = XML_FA    
4904       parser->m_declAttributeType = NULL;        
4905       parser->m_declAttributeIsId = XML_FALSE    
4906       goto checkAttListDeclHandler;              
4907     case XML_ROLE_ATTRIBUTE_TYPE_CDATA:          
4908       parser->m_declAttributeIsCdata = XML_TR    
4909       parser->m_declAttributeType = atypeCDAT    
4910       goto checkAttListDeclHandler;              
4911     case XML_ROLE_ATTRIBUTE_TYPE_ID:             
4912       parser->m_declAttributeIsId = XML_TRUE;    
4913       parser->m_declAttributeType = atypeID;     
4914       goto checkAttListDeclHandler;              
4915     case XML_ROLE_ATTRIBUTE_TYPE_IDREF:          
4916       parser->m_declAttributeType = atypeIDRE    
4917       goto checkAttListDeclHandler;              
4918     case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:         
4919       parser->m_declAttributeType = atypeIDRE    
4920       goto checkAttListDeclHandler;              
4921     case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:         
4922       parser->m_declAttributeType = atypeENTI    
4923       goto checkAttListDeclHandler;              
4924     case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:       
4925       parser->m_declAttributeType = atypeENTI    
4926       goto checkAttListDeclHandler;              
4927     case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:        
4928       parser->m_declAttributeType = atypeNMTO    
4929       goto checkAttListDeclHandler;              
4930     case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:       
4931       parser->m_declAttributeType = atypeNMTO    
4932     checkAttListDeclHandler:                     
4933       if (dtd->keepProcessing && parser->m_at    
4934         handleDefault = XML_FALSE;               
4935       break;                                     
4936     case XML_ROLE_ATTRIBUTE_ENUM_VALUE:          
4937     case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:      
4938       if (dtd->keepProcessing && parser->m_at    
4939         const XML_Char *prefix;                  
4940         if (parser->m_declAttributeType) {       
4941           prefix = enumValueSep;                 
4942         } else {                                 
4943           prefix = (role == XML_ROLE_ATTRIBUT    
4944                                                  
4945         }                                        
4946         if (! poolAppendString(&parser->m_tem    
4947           return XML_ERROR_NO_MEMORY;            
4948         if (! poolAppend(&parser->m_tempPool,    
4949           return XML_ERROR_NO_MEMORY;            
4950         parser->m_declAttributeType = parser-    
4951         handleDefault = XML_FALSE;               
4952       }                                          
4953       break;                                     
4954     case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:       
4955     case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:      
4956       if (dtd->keepProcessing) {                 
4957         if (! defineAttribute(parser->m_declE    
4958                               parser->m_declA    
4959                               parser->m_declA    
4960                               parser->m_declA    
4961           return XML_ERROR_NO_MEMORY;            
4962         if (parser->m_attlistDeclHandler && p    
4963           if (*parser->m_declAttributeType ==    
4964               || (*parser->m_declAttributeTyp    
4965                   && parser->m_declAttributeT    
4966             /* Enumerated or Notation type */    
4967             if (! poolAppendChar(&parser->m_t    
4968                 || ! poolAppendChar(&parser->    
4969               return XML_ERROR_NO_MEMORY;        
4970             parser->m_declAttributeType = par    
4971             poolFinish(&parser->m_tempPool);     
4972           }                                      
4973           *eventEndPP = s;                       
4974           parser->m_attlistDeclHandler(          
4975               parser->m_handlerArg, parser->m    
4976               parser->m_declAttributeId->name    
4977               role == XML_ROLE_REQUIRED_ATTRI    
4978           poolClear(&parser->m_tempPool);        
4979           handleDefault = XML_FALSE;             
4980         }                                        
4981       }                                          
4982       break;                                     
4983     case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:       
4984     case XML_ROLE_FIXED_ATTRIBUTE_VALUE:         
4985       if (dtd->keepProcessing) {                 
4986         const XML_Char *attVal;                  
4987         enum XML_Error result = storeAttribut    
4988             parser, enc, parser->m_declAttrib    
4989             s + enc->minBytesPerChar, next -     
4990             XML_ACCOUNT_NONE);                   
4991         if (result)                              
4992           return result;                         
4993         attVal = poolStart(&dtd->pool);          
4994         poolFinish(&dtd->pool);                  
4995         /* ID attributes aren't allowed to ha    
4996         if (! defineAttribute(                   
4997                 parser->m_declElementType, pa    
4998                 parser->m_declAttributeIsCdat    
4999           return XML_ERROR_NO_MEMORY;            
5000         if (parser->m_attlistDeclHandler && p    
5001           if (*parser->m_declAttributeType ==    
5002               || (*parser->m_declAttributeTyp    
5003                   && parser->m_declAttributeT    
5004             /* Enumerated or Notation type */    
5005             if (! poolAppendChar(&parser->m_t    
5006                 || ! poolAppendChar(&parser->    
5007               return XML_ERROR_NO_MEMORY;        
5008             parser->m_declAttributeType = par    
5009             poolFinish(&parser->m_tempPool);     
5010           }                                      
5011           *eventEndPP = s;                       
5012           parser->m_attlistDeclHandler(          
5013               parser->m_handlerArg, parser->m    
5014               parser->m_declAttributeId->name    
5015               attVal, role == XML_ROLE_FIXED_    
5016           poolClear(&parser->m_tempPool);        
5017           handleDefault = XML_FALSE;             
5018         }                                        
5019       }                                          
5020       break;                                     
5021     case XML_ROLE_ENTITY_VALUE:                  
5022       if (dtd->keepProcessing) {                 
5023         enum XML_Error result                    
5024             = storeEntityValue(parser, enc, s    
5025                                next - enc->mi    
5026         if (parser->m_declEntity) {              
5027           parser->m_declEntity->textPtr = poo    
5028           parser->m_declEntity->textLen          
5029               = (int)(poolLength(&dtd->entity    
5030           poolFinish(&dtd->entityValuePool);     
5031           if (parser->m_entityDeclHandler) {     
5032             *eventEndPP = s;                     
5033             parser->m_entityDeclHandler(         
5034                 parser->m_handlerArg, parser-    
5035                 parser->m_declEntity->is_para    
5036                 parser->m_declEntity->textLen    
5037             handleDefault = XML_FALSE;           
5038           }                                      
5039         } else                                   
5040           poolDiscard(&dtd->entityValuePool);    
5041         if (result != XML_ERROR_NONE)            
5042           return result;                         
5043       }                                          
5044       break;                                     
5045     case XML_ROLE_DOCTYPE_SYSTEM_ID:             
5046 #ifdef XML_DTD                                   
5047       parser->m_useForeignDTD = XML_FALSE;       
5048 #endif /* XML_DTD */                             
5049       dtd->hasParamEntityRefs = XML_TRUE;        
5050       if (parser->m_startDoctypeDeclHandler)     
5051         parser->m_doctypeSysid = poolStoreStr    
5052                                                  
5053                                                  
5054         if (parser->m_doctypeSysid == NULL)      
5055           return XML_ERROR_NO_MEMORY;            
5056         poolFinish(&parser->m_tempPool);         
5057         handleDefault = XML_FALSE;               
5058       }                                          
5059 #ifdef XML_DTD                                   
5060       else                                       
5061         /* use externalSubsetName to make par    
5062            for the case where no parser->m_st    
5063         parser->m_doctypeSysid = externalSubs    
5064 #endif /* XML_DTD */                             
5065       if (! dtd->standalone                      
5066 #ifdef XML_DTD                                   
5067           && ! parser->m_paramEntityParsing      
5068 #endif /* XML_DTD */                             
5069           && parser->m_notStandaloneHandler      
5070           && ! parser->m_notStandaloneHandler    
5071         return XML_ERROR_NOT_STANDALONE;         
5072 #ifndef XML_DTD                                  
5073       break;                                     
5074 #else  /* XML_DTD */                             
5075       if (! parser->m_declEntity) {              
5076         parser->m_declEntity = (ENTITY *)look    
5077             parser, &dtd->paramEntities, exte    
5078         if (! parser->m_declEntity)              
5079           return XML_ERROR_NO_MEMORY;            
5080         parser->m_declEntity->publicId = NULL    
5081       }                                          
5082 #endif /* XML_DTD */                             
5083       /* fall through */                         
5084     case XML_ROLE_ENTITY_SYSTEM_ID:              
5085       if (dtd->keepProcessing && parser->m_de    
5086         parser->m_declEntity->systemId           
5087             = poolStoreString(&dtd->pool, enc    
5088                               next - enc->min    
5089         if (! parser->m_declEntity->systemId)    
5090           return XML_ERROR_NO_MEMORY;            
5091         parser->m_declEntity->base = parser->    
5092         poolFinish(&dtd->pool);                  
5093         /* Don't suppress the default handler    
5094          * the XML_ROLE_DOCTYPE_SYSTEM_ID cas    
5095          */                                      
5096         if (parser->m_entityDeclHandler && ro    
5097           handleDefault = XML_FALSE;             
5098       }                                          
5099       break;                                     
5100     case XML_ROLE_ENTITY_COMPLETE:               
5101       if (dtd->keepProcessing && parser->m_de    
5102           && parser->m_entityDeclHandler) {      
5103         *eventEndPP = s;                         
5104         parser->m_entityDeclHandler(             
5105             parser->m_handlerArg, parser->m_d    
5106             parser->m_declEntity->is_param, 0    
5107             parser->m_declEntity->systemId, p    
5108         handleDefault = XML_FALSE;               
5109       }                                          
5110       break;                                     
5111     case XML_ROLE_ENTITY_NOTATION_NAME:          
5112       if (dtd->keepProcessing && parser->m_de    
5113         parser->m_declEntity->notation           
5114             = poolStoreString(&dtd->pool, enc    
5115         if (! parser->m_declEntity->notation)    
5116           return XML_ERROR_NO_MEMORY;            
5117         poolFinish(&dtd->pool);                  
5118         if (parser->m_unparsedEntityDeclHandl    
5119           *eventEndPP = s;                       
5120           parser->m_unparsedEntityDeclHandler    
5121               parser->m_handlerArg, parser->m    
5122               parser->m_declEntity->base, par    
5123               parser->m_declEntity->publicId,    
5124           handleDefault = XML_FALSE;             
5125         } else if (parser->m_entityDeclHandle    
5126           *eventEndPP = s;                       
5127           parser->m_entityDeclHandler(           
5128               parser->m_handlerArg, parser->m    
5129               parser->m_declEntity->base, par    
5130               parser->m_declEntity->publicId,    
5131           handleDefault = XML_FALSE;             
5132         }                                        
5133       }                                          
5134       break;                                     
5135     case XML_ROLE_GENERAL_ENTITY_NAME: {         
5136       if (XmlPredefinedEntityName(enc, s, nex    
5137         parser->m_declEntity = NULL;             
5138         break;                                   
5139       }                                          
5140       if (dtd->keepProcessing) {                 
5141         const XML_Char *name = poolStoreStrin    
5142         if (! name)                              
5143           return XML_ERROR_NO_MEMORY;            
5144         parser->m_declEntity = (ENTITY *)look    
5145                                                  
5146         if (! parser->m_declEntity)              
5147           return XML_ERROR_NO_MEMORY;            
5148         if (parser->m_declEntity->name != nam    
5149           poolDiscard(&dtd->pool);               
5150           parser->m_declEntity = NULL;           
5151         } else {                                 
5152           poolFinish(&dtd->pool);                
5153           parser->m_declEntity->publicId = NU    
5154           parser->m_declEntity->is_param = XM    
5155           /* if we have a parent parser or ar    
5156              entity, then the entity declarat    
5157           */                                     
5158           parser->m_declEntity->is_internal      
5159               = ! (parser->m_parentParser ||     
5160           if (parser->m_entityDeclHandler)       
5161             handleDefault = XML_FALSE;           
5162         }                                        
5163       } else {                                   
5164         poolDiscard(&dtd->pool);                 
5165         parser->m_declEntity = NULL;             
5166       }                                          
5167     } break;                                     
5168     case XML_ROLE_PARAM_ENTITY_NAME:             
5169 #ifdef XML_DTD                                   
5170       if (dtd->keepProcessing) {                 
5171         const XML_Char *name = poolStoreStrin    
5172         if (! name)                              
5173           return XML_ERROR_NO_MEMORY;            
5174         parser->m_declEntity = (ENTITY *)look    
5175                                                  
5176         if (! parser->m_declEntity)              
5177           return XML_ERROR_NO_MEMORY;            
5178         if (parser->m_declEntity->name != nam    
5179           poolDiscard(&dtd->pool);               
5180           parser->m_declEntity = NULL;           
5181         } else {                                 
5182           poolFinish(&dtd->pool);                
5183           parser->m_declEntity->publicId = NU    
5184           parser->m_declEntity->is_param = XM    
5185           /* if we have a parent parser or ar    
5186              entity, then the entity declarat    
5187           */                                     
5188           parser->m_declEntity->is_internal      
5189               = ! (parser->m_parentParser ||     
5190           if (parser->m_entityDeclHandler)       
5191             handleDefault = XML_FALSE;           
5192         }                                        
5193       } else {                                   
5194         poolDiscard(&dtd->pool);                 
5195         parser->m_declEntity = NULL;             
5196       }                                          
5197 #else  /* not XML_DTD */                         
5198       parser->m_declEntity = NULL;               
5199 #endif /* XML_DTD */                             
5200       break;                                     
5201     case XML_ROLE_NOTATION_NAME:                 
5202       parser->m_declNotationPublicId = NULL;     
5203       parser->m_declNotationName = NULL;         
5204       if (parser->m_notationDeclHandler) {       
5205         parser->m_declNotationName               
5206             = poolStoreString(&parser->m_temp    
5207         if (! parser->m_declNotationName)        
5208           return XML_ERROR_NO_MEMORY;            
5209         poolFinish(&parser->m_tempPool);         
5210         handleDefault = XML_FALSE;               
5211       }                                          
5212       break;                                     
5213     case XML_ROLE_NOTATION_PUBLIC_ID:            
5214       if (! XmlIsPublicId(enc, s, next, event    
5215         return XML_ERROR_PUBLICID;               
5216       if (parser                                 
5217               ->m_declNotationName) { /* mean    
5218         XML_Char *tem = poolStoreString(&pars    
5219                                         s + e    
5220                                         next     
5221         if (! tem)                               
5222           return XML_ERROR_NO_MEMORY;            
5223         normalizePublicId(tem);                  
5224         parser->m_declNotationPublicId = tem;    
5225         poolFinish(&parser->m_tempPool);         
5226         handleDefault = XML_FALSE;               
5227       }                                          
5228       break;                                     
5229     case XML_ROLE_NOTATION_SYSTEM_ID:            
5230       if (parser->m_declNotationName && parse    
5231         const XML_Char *systemId = poolStoreS    
5232                                                  
5233                                                  
5234         if (! systemId)                          
5235           return XML_ERROR_NO_MEMORY;            
5236         *eventEndPP = s;                         
5237         parser->m_notationDeclHandler(           
5238             parser->m_handlerArg, parser->m_d    
5239             systemId, parser->m_declNotationP    
5240         handleDefault = XML_FALSE;               
5241       }                                          
5242       poolClear(&parser->m_tempPool);            
5243       break;                                     
5244     case XML_ROLE_NOTATION_NO_SYSTEM_ID:         
5245       if (parser->m_declNotationPublicId && p    
5246         *eventEndPP = s;                         
5247         parser->m_notationDeclHandler(           
5248             parser->m_handlerArg, parser->m_d    
5249             0, parser->m_declNotationPublicId    
5250         handleDefault = XML_FALSE;               
5251       }                                          
5252       poolClear(&parser->m_tempPool);            
5253       break;                                     
5254     case XML_ROLE_ERROR:                         
5255       switch (tok) {                             
5256       case XML_TOK_PARAM_ENTITY_REF:             
5257         /* PE references in internal subset a    
5258            not allowed within declarations. *    
5259         return XML_ERROR_PARAM_ENTITY_REF;       
5260       case XML_TOK_XML_DECL:                     
5261         return XML_ERROR_MISPLACED_XML_PI;       
5262       default:                                   
5263         return XML_ERROR_SYNTAX;                 
5264       }                                          
5265 #ifdef XML_DTD                                   
5266     case XML_ROLE_IGNORE_SECT: {                 
5267       enum XML_Error result;                     
5268       if (parser->m_defaultHandler)              
5269         reportDefault(parser, enc, s, next);     
5270       handleDefault = XML_FALSE;                 
5271       result = doIgnoreSection(parser, enc, &    
5272       if (result != XML_ERROR_NONE)              
5273         return result;                           
5274       else if (! next) {                         
5275         parser->m_processor = ignoreSectionPr    
5276         return result;                           
5277       }                                          
5278     } break;                                     
5279 #endif /* XML_DTD */                             
5280     case XML_ROLE_GROUP_OPEN:                    
5281       if (parser->m_prologState.level >= pars    
5282         if (parser->m_groupSize) {               
5283           {                                      
5284             /* Detect and prevent integer ove    
5285             if (parser->m_groupSize > (unsign    
5286               return XML_ERROR_NO_MEMORY;        
5287             }                                    
5288                                                  
5289             char *const new_connector = (char    
5290                 parser, parser->m_groupConnec    
5291             if (new_connector == NULL) {         
5292               parser->m_groupSize /= 2;          
5293               return XML_ERROR_NO_MEMORY;        
5294             }                                    
5295             parser->m_groupConnector = new_co    
5296           }                                      
5297                                                  
5298           if (dtd->scaffIndex) {                 
5299             /* Detect and prevent integer ove    
5300              * The preprocessor guard address    
5301              * from -Wtype-limits on platform    
5302              * sizeof(unsigned int) < sizeof(    
5303 #if UINT_MAX >= SIZE_MAX                         
5304             if (parser->m_groupSize > (size_t    
5305               return XML_ERROR_NO_MEMORY;        
5306             }                                    
5307 #endif                                           
5308                                                  
5309             int *const new_scaff_index = (int    
5310                 parser, dtd->scaffIndex, pars    
5311             if (new_scaff_index == NULL)         
5312               return XML_ERROR_NO_MEMORY;        
5313             dtd->scaffIndex = new_scaff_index    
5314           }                                      
5315         } else {                                 
5316           parser->m_groupConnector               
5317               = (char *)MALLOC(parser, parser    
5318           if (! parser->m_groupConnector) {      
5319             parser->m_groupSize = 0;             
5320             return XML_ERROR_NO_MEMORY;          
5321           }                                      
5322         }                                        
5323       }                                          
5324       parser->m_groupConnector[parser->m_prol    
5325       if (dtd->in_eldecl) {                      
5326         int myindex = nextScaffoldPart(parser    
5327         if (myindex < 0)                         
5328           return XML_ERROR_NO_MEMORY;            
5329         assert(dtd->scaffIndex != NULL);         
5330         dtd->scaffIndex[dtd->scaffLevel] = my    
5331         dtd->scaffLevel++;                       
5332         dtd->scaffold[myindex].type = XML_CTY    
5333         if (parser->m_elementDeclHandler)        
5334           handleDefault = XML_FALSE;             
5335       }                                          
5336       break;                                     
5337     case XML_ROLE_GROUP_SEQUENCE:                
5338       if (parser->m_groupConnector[parser->m_    
5339         return XML_ERROR_SYNTAX;                 
5340       parser->m_groupConnector[parser->m_prol    
5341       if (dtd->in_eldecl && parser->m_element    
5342         handleDefault = XML_FALSE;               
5343       break;                                     
5344     case XML_ROLE_GROUP_CHOICE:                  
5345       if (parser->m_groupConnector[parser->m_    
5346         return XML_ERROR_SYNTAX;                 
5347       if (dtd->in_eldecl                         
5348           && ! parser->m_groupConnector[parse    
5349           && (dtd->scaffold[dtd->scaffIndex[d    
5350               != XML_CTYPE_MIXED)) {             
5351         dtd->scaffold[dtd->scaffIndex[dtd->sc    
5352             = XML_CTYPE_CHOICE;                  
5353         if (parser->m_elementDeclHandler)        
5354           handleDefault = XML_FALSE;             
5355       }                                          
5356       parser->m_groupConnector[parser->m_prol    
5357       break;                                     
5358     case XML_ROLE_PARAM_ENTITY_REF:              
5359 #ifdef XML_DTD                                   
5360     case XML_ROLE_INNER_PARAM_ENTITY_REF:        
5361       dtd->hasParamEntityRefs = XML_TRUE;        
5362       if (! parser->m_paramEntityParsing)        
5363         dtd->keepProcessing = dtd->standalone    
5364       else {                                     
5365         const XML_Char *name;                    
5366         ENTITY *entity;                          
5367         name = poolStoreString(&dtd->pool, en    
5368                                next - enc->mi    
5369         if (! name)                              
5370           return XML_ERROR_NO_MEMORY;            
5371         entity = (ENTITY *)lookup(parser, &dt    
5372         poolDiscard(&dtd->pool);                 
5373         /* first, determine if a check for an    
5374            if yes, check that the entity exis    
5375            otherwise call the skipped entity     
5376         */                                       
5377         if (parser->m_prologState.documentEnt    
5378             && (dtd->standalone ? ! parser->m    
5379                                 : ! dtd->hasP    
5380           if (! entity)                          
5381             return XML_ERROR_UNDEFINED_ENTITY    
5382           else if (! entity->is_internal) {      
5383             /* It's hard to exhaustively sear    
5384              * but there doesn't seem to be a    
5385              * following line.  There are two    
5386              *                                   
5387              * If 'standalone' is false, the     
5388              * parameter entities or we would    
5389              * 'if' statement.  That means th    
5390              * table is the external subset n    
5391              * given as a parameter entity na    
5392              * lookup must have returned NULL    
5393              * the test for an internal entit    
5394              *                                   
5395              * If 'standalone' is true, it do    
5396              * possible to create entities ta    
5397              * are not internal entities, so     
5398              *                                   
5399              * Because this analysis is very     
5400              * being left in place and merely    
5401              * coverage test statistics.         
5402              */                                  
5403             return XML_ERROR_ENTITY_DECLARED_    
5404           }                                      
5405         } else if (! entity) {                   
5406           dtd->keepProcessing = dtd->standalo    
5407           /* cannot report skipped entities i    
5408           if ((role == XML_ROLE_PARAM_ENTITY_    
5409               && parser->m_skippedEntityHandl    
5410             parser->m_skippedEntityHandler(pa    
5411             handleDefault = XML_FALSE;           
5412           }                                      
5413           break;                                 
5414         }                                        
5415         if (entity->open)                        
5416           return XML_ERROR_RECURSIVE_ENTITY_R    
5417         if (entity->textPtr) {                   
5418           enum XML_Error result;                 
5419           XML_Bool betweenDecl                   
5420               = (role == XML_ROLE_PARAM_ENTIT    
5421           result = processInternalEntity(pars    
5422           if (result != XML_ERROR_NONE)          
5423             return result;                       
5424           handleDefault = XML_FALSE;             
5425           break;                                 
5426         }                                        
5427         if (parser->m_externalEntityRefHandle    
5428           dtd->paramEntityRead = XML_FALSE;      
5429           entity->open = XML_TRUE;               
5430           entityTrackingOnOpen(parser, entity    
5431           if (! parser->m_externalEntityRefHa    
5432                   parser->m_externalEntityRef    
5433                   entity->systemId, entity->p    
5434             entityTrackingOnClose(parser, ent    
5435             entity->open = XML_FALSE;            
5436             return XML_ERROR_EXTERNAL_ENTITY_    
5437           }                                      
5438           entityTrackingOnClose(parser, entit    
5439           entity->open = XML_FALSE;              
5440           handleDefault = XML_FALSE;             
5441           if (! dtd->paramEntityRead) {          
5442             dtd->keepProcessing = dtd->standa    
5443             break;                               
5444           }                                      
5445         } else {                                 
5446           dtd->keepProcessing = dtd->standalo    
5447           break;                                 
5448         }                                        
5449       }                                          
5450 #endif /* XML_DTD */                             
5451       if (! dtd->standalone && parser->m_notS    
5452           && ! parser->m_notStandaloneHandler    
5453         return XML_ERROR_NOT_STANDALONE;         
5454       break;                                     
5455                                                  
5456       /* Element declaration stuff */            
5457                                                  
5458     case XML_ROLE_ELEMENT_NAME:                  
5459       if (parser->m_elementDeclHandler) {        
5460         parser->m_declElementType = getElemen    
5461         if (! parser->m_declElementType)         
5462           return XML_ERROR_NO_MEMORY;            
5463         dtd->scaffLevel = 0;                     
5464         dtd->scaffCount = 0;                     
5465         dtd->in_eldecl = XML_TRUE;               
5466         handleDefault = XML_FALSE;               
5467       }                                          
5468       break;                                     
5469                                                  
5470     case XML_ROLE_CONTENT_ANY:                   
5471     case XML_ROLE_CONTENT_EMPTY:                 
5472       if (dtd->in_eldecl) {                      
5473         if (parser->m_elementDeclHandler) {      
5474           XML_Content *content                   
5475               = (XML_Content *)MALLOC(parser,    
5476           if (! content)                         
5477             return XML_ERROR_NO_MEMORY;          
5478           content->quant = XML_CQUANT_NONE;      
5479           content->name = NULL;                  
5480           content->numchildren = 0;              
5481           content->children = NULL;              
5482           content->type = ((role == XML_ROLE_    
5483                                                  
5484           *eventEndPP = s;                       
5485           parser->m_elementDeclHandler(          
5486               parser->m_handlerArg, parser->m    
5487           handleDefault = XML_FALSE;             
5488         }                                        
5489         dtd->in_eldecl = XML_FALSE;              
5490       }                                          
5491       break;                                     
5492                                                  
5493     case XML_ROLE_CONTENT_PCDATA:                
5494       if (dtd->in_eldecl) {                      
5495         dtd->scaffold[dtd->scaffIndex[dtd->sc    
5496             = XML_CTYPE_MIXED;                   
5497         if (parser->m_elementDeclHandler)        
5498           handleDefault = XML_FALSE;             
5499       }                                          
5500       break;                                     
5501                                                  
5502     case XML_ROLE_CONTENT_ELEMENT:               
5503       quant = XML_CQUANT_NONE;                   
5504       goto elementContent;                       
5505     case XML_ROLE_CONTENT_ELEMENT_OPT:           
5506       quant = XML_CQUANT_OPT;                    
5507       goto elementContent;                       
5508     case XML_ROLE_CONTENT_ELEMENT_REP:           
5509       quant = XML_CQUANT_REP;                    
5510       goto elementContent;                       
5511     case XML_ROLE_CONTENT_ELEMENT_PLUS:          
5512       quant = XML_CQUANT_PLUS;                   
5513     elementContent:                              
5514       if (dtd->in_eldecl) {                      
5515         ELEMENT_TYPE *el;                        
5516         const XML_Char *name;                    
5517         size_t nameLen;                          
5518         const char *nxt                          
5519             = (quant == XML_CQUANT_NONE ? nex    
5520         int myindex = nextScaffoldPart(parser    
5521         if (myindex < 0)                         
5522           return XML_ERROR_NO_MEMORY;            
5523         dtd->scaffold[myindex].type = XML_CTY    
5524         dtd->scaffold[myindex].quant = quant;    
5525         el = getElementType(parser, enc, s, n    
5526         if (! el)                                
5527           return XML_ERROR_NO_MEMORY;            
5528         name = el->name;                         
5529         dtd->scaffold[myindex].name = name;      
5530         nameLen = 0;                             
5531         for (; name[nameLen++];)                 
5532           ;                                      
5533                                                  
5534         /* Detect and prevent integer overflo    
5535         if (nameLen > UINT_MAX - dtd->content    
5536           return XML_ERROR_NO_MEMORY;            
5537         }                                        
5538                                                  
5539         dtd->contentStringLen += (unsigned)na    
5540         if (parser->m_elementDeclHandler)        
5541           handleDefault = XML_FALSE;             
5542       }                                          
5543       break;                                     
5544                                                  
5545     case XML_ROLE_GROUP_CLOSE:                   
5546       quant = XML_CQUANT_NONE;                   
5547       goto closeGroup;                           
5548     case XML_ROLE_GROUP_CLOSE_OPT:               
5549       quant = XML_CQUANT_OPT;                    
5550       goto closeGroup;                           
5551     case XML_ROLE_GROUP_CLOSE_REP:               
5552       quant = XML_CQUANT_REP;                    
5553       goto closeGroup;                           
5554     case XML_ROLE_GROUP_CLOSE_PLUS:              
5555       quant = XML_CQUANT_PLUS;                   
5556     closeGroup:                                  
5557       if (dtd->in_eldecl) {                      
5558         if (parser->m_elementDeclHandler)        
5559           handleDefault = XML_FALSE;             
5560         dtd->scaffLevel--;                       
5561         dtd->scaffold[dtd->scaffIndex[dtd->sc    
5562         if (dtd->scaffLevel == 0) {              
5563           if (! handleDefault) {                 
5564             XML_Content *model = build_model(    
5565             if (! model)                         
5566               return XML_ERROR_NO_MEMORY;        
5567             *eventEndPP = s;                     
5568             parser->m_elementDeclHandler(        
5569                 parser->m_handlerArg, parser-    
5570           }                                      
5571           dtd->in_eldecl = XML_FALSE;            
5572           dtd->contentStringLen = 0;             
5573         }                                        
5574       }                                          
5575       break;                                     
5576       /* End element declaration stuff */        
5577                                                  
5578     case XML_ROLE_PI:                            
5579       if (! reportProcessingInstruction(parse    
5580         return XML_ERROR_NO_MEMORY;              
5581       handleDefault = XML_FALSE;                 
5582       break;                                     
5583     case XML_ROLE_COMMENT:                       
5584       if (! reportComment(parser, enc, s, nex    
5585         return XML_ERROR_NO_MEMORY;              
5586       handleDefault = XML_FALSE;                 
5587       break;                                     
5588     case XML_ROLE_NONE:                          
5589       switch (tok) {                             
5590       case XML_TOK_BOM:                          
5591         handleDefault = XML_FALSE;               
5592         break;                                   
5593       }                                          
5594       break;                                     
5595     case XML_ROLE_DOCTYPE_NONE:                  
5596       if (parser->m_startDoctypeDeclHandler)     
5597         handleDefault = XML_FALSE;               
5598       break;                                     
5599     case XML_ROLE_ENTITY_NONE:                   
5600       if (dtd->keepProcessing && parser->m_en    
5601         handleDefault = XML_FALSE;               
5602       break;                                     
5603     case XML_ROLE_NOTATION_NONE:                 
5604       if (parser->m_notationDeclHandler)         
5605         handleDefault = XML_FALSE;               
5606       break;                                     
5607     case XML_ROLE_ATTLIST_NONE:                  
5608       if (dtd->keepProcessing && parser->m_at    
5609         handleDefault = XML_FALSE;               
5610       break;                                     
5611     case XML_ROLE_ELEMENT_NONE:                  
5612       if (parser->m_elementDeclHandler)          
5613         handleDefault = XML_FALSE;               
5614       break;                                     
5615     } /* end of big switch */                    
5616                                                  
5617     if (handleDefault && parser->m_defaultHan    
5618       reportDefault(parser, enc, s, next);       
5619                                                  
5620     switch (parser->m_parsingStatus.parsing)     
5621     case XML_SUSPENDED:                          
5622       *nextPtr = next;                           
5623       return XML_ERROR_NONE;                     
5624     case XML_FINISHED:                           
5625       return XML_ERROR_ABORTED;                  
5626     default:                                     
5627       s = next;                                  
5628       tok = XmlPrologTok(enc, s, end, &next);    
5629     }                                            
5630   }                                              
5631   /* not reached */                              
5632 }                                                
5633                                                  
5634 static enum XML_Error PTRCALL                    
5635 epilogProcessor(XML_Parser parser, const char    
5636                 const char **nextPtr) {          
5637   parser->m_processor = epilogProcessor;         
5638   parser->m_eventPtr = s;                        
5639   for (;;) {                                     
5640     const char *next = NULL;                     
5641     int tok = XmlPrologTok(parser->m_encoding    
5642 #ifdef XML_DTD                                   
5643     if (! accountingDiffTolerated(parser, tok    
5644                                   XML_ACCOUNT    
5645       accountingOnAbort(parser);                 
5646       return XML_ERROR_AMPLIFICATION_LIMIT_BR    
5647     }                                            
5648 #endif                                           
5649     parser->m_eventEndPtr = next;                
5650     switch (tok) {                               
5651     /* report partial linebreak - it might be    
5652     case -XML_TOK_PROLOG_S:                      
5653       if (parser->m_defaultHandler) {            
5654         reportDefault(parser, parser->m_encod    
5655         if (parser->m_parsingStatus.parsing =    
5656           return XML_ERROR_ABORTED;              
5657       }                                          
5658       *nextPtr = next;                           
5659       return XML_ERROR_NONE;                     
5660     case XML_TOK_NONE:                           
5661       *nextPtr = s;                              
5662       return XML_ERROR_NONE;                     
5663     case XML_TOK_PROLOG_S:                       
5664       if (parser->m_defaultHandler)              
5665         reportDefault(parser, parser->m_encod    
5666       break;                                     
5667     case XML_TOK_PI:                             
5668       if (! reportProcessingInstruction(parse    
5669         return XML_ERROR_NO_MEMORY;              
5670       break;                                     
5671     case XML_TOK_COMMENT:                        
5672       if (! reportComment(parser, parser->m_e    
5673         return XML_ERROR_NO_MEMORY;              
5674       break;                                     
5675     case XML_TOK_INVALID:                        
5676       parser->m_eventPtr = next;                 
5677       return XML_ERROR_INVALID_TOKEN;            
5678     case XML_TOK_PARTIAL:                        
5679       if (! parser->m_parsingStatus.finalBuff    
5680         *nextPtr = s;                            
5681         return XML_ERROR_NONE;                   
5682       }                                          
5683       return XML_ERROR_UNCLOSED_TOKEN;           
5684     case XML_TOK_PARTIAL_CHAR:                   
5685       if (! parser->m_parsingStatus.finalBuff    
5686         *nextPtr = s;                            
5687         return XML_ERROR_NONE;                   
5688       }                                          
5689       return XML_ERROR_PARTIAL_CHAR;             
5690     default:                                     
5691       return XML_ERROR_JUNK_AFTER_DOC_ELEMENT    
5692     }                                            
5693     parser->m_eventPtr = s = next;               
5694     switch (parser->m_parsingStatus.parsing)     
5695     case XML_SUSPENDED:                          
5696       *nextPtr = next;                           
5697       return XML_ERROR_NONE;                     
5698     case XML_FINISHED:                           
5699       return XML_ERROR_ABORTED;                  
5700     default:;                                    
5701     }                                            
5702   }                                              
5703 }                                                
5704                                                  
5705 static enum XML_Error                            
5706 processInternalEntity(XML_Parser parser, ENTI    
5707   const char *textStart, *textEnd;               
5708   const char *next;                              
5709   enum XML_Error result;                         
5710   OPEN_INTERNAL_ENTITY *openEntity;              
5711                                                  
5712   if (parser->m_freeInternalEntities) {          
5713     openEntity = parser->m_freeInternalEntiti    
5714     parser->m_freeInternalEntities = openEnti    
5715   } else {                                       
5716     openEntity                                   
5717         = (OPEN_INTERNAL_ENTITY *)MALLOC(pars    
5718     if (! openEntity)                            
5719       return XML_ERROR_NO_MEMORY;                
5720   }                                              
5721   entity->open = XML_TRUE;                       
5722 #ifdef XML_DTD                                   
5723   entityTrackingOnOpen(parser, entity, __LINE    
5724 #endif                                           
5725   entity->processed = 0;                         
5726   openEntity->next = parser->m_openInternalEn    
5727   parser->m_openInternalEntities = openEntity    
5728   openEntity->entity = entity;                   
5729   openEntity->startTagLevel = parser->m_tagLe    
5730   openEntity->betweenDecl = betweenDecl;         
5731   openEntity->internalEventPtr = NULL;           
5732   openEntity->internalEventEndPtr = NULL;        
5733   textStart = (const char *)entity->textPtr;     
5734   textEnd = (const char *)(entity->textPtr +     
5735   /* Set a safe default value in case 'next'     
5736   next = textStart;                              
5737                                                  
5738 #ifdef XML_DTD                                   
5739   if (entity->is_param) {                        
5740     int tok                                      
5741         = XmlPrologTok(parser->m_internalEnco    
5742     result = doProlog(parser, parser->m_inter    
5743                       tok, next, &next, XML_F    
5744                       XML_ACCOUNT_ENTITY_EXPA    
5745   } else                                         
5746 #endif /* XML_DTD */                             
5747     result = doContent(parser, parser->m_tagL    
5748                        textStart, textEnd, &n    
5749                        XML_ACCOUNT_ENTITY_EXP    
5750                                                  
5751   if (result == XML_ERROR_NONE) {                
5752     if (textEnd != next && parser->m_parsingS    
5753       entity->processed = (int)(next - textSt    
5754       parser->m_processor = internalEntityPro    
5755     } else {                                     
5756 #ifdef XML_DTD                                   
5757       entityTrackingOnClose(parser, entity, _    
5758 #endif /* XML_DTD */                             
5759       entity->open = XML_FALSE;                  
5760       parser->m_openInternalEntities = openEn    
5761       /* put openEntity back in list of free     
5762       openEntity->next = parser->m_freeIntern    
5763       parser->m_freeInternalEntities = openEn    
5764     }                                            
5765   }                                              
5766   return result;                                 
5767 }                                                
5768                                                  
5769 static enum XML_Error PTRCALL                    
5770 internalEntityProcessor(XML_Parser parser, co    
5771                         const char **nextPtr)    
5772   ENTITY *entity;                                
5773   const char *textStart, *textEnd;               
5774   const char *next;                              
5775   enum XML_Error result;                         
5776   OPEN_INTERNAL_ENTITY *openEntity = parser->    
5777   if (! openEntity)                              
5778     return XML_ERROR_UNEXPECTED_STATE;           
5779                                                  
5780   entity = openEntity->entity;                   
5781   textStart = ((const char *)entity->textPtr)    
5782   textEnd = (const char *)(entity->textPtr +     
5783   /* Set a safe default value in case 'next'     
5784   next = textStart;                              
5785                                                  
5786 #ifdef XML_DTD                                   
5787   if (entity->is_param) {                        
5788     int tok                                      
5789         = XmlPrologTok(parser->m_internalEnco    
5790     result = doProlog(parser, parser->m_inter    
5791                       tok, next, &next, XML_F    
5792                       XML_ACCOUNT_ENTITY_EXPA    
5793   } else                                         
5794 #endif /* XML_DTD */                             
5795     result = doContent(parser, openEntity->st    
5796                        parser->m_internalEnco    
5797                        XML_FALSE, XML_ACCOUNT    
5798                                                  
5799   if (result != XML_ERROR_NONE)                  
5800     return result;                               
5801   else if (textEnd != next                       
5802            && parser->m_parsingStatus.parsing    
5803     entity->processed = (int)(next - (const c    
5804     return result;                               
5805   } else {                                       
5806 #ifdef XML_DTD                                   
5807     entityTrackingOnClose(parser, entity, __L    
5808 #endif                                           
5809     entity->open = XML_FALSE;                    
5810     parser->m_openInternalEntities = openEnti    
5811     /* put openEntity back in list of free in    
5812     openEntity->next = parser->m_freeInternal    
5813     parser->m_freeInternalEntities = openEnti    
5814   }                                              
5815                                                  
5816 #ifdef XML_DTD                                   
5817   if (entity->is_param) {                        
5818     int tok;                                     
5819     parser->m_processor = prologProcessor;       
5820     tok = XmlPrologTok(parser->m_encoding, s,    
5821     return doProlog(parser, parser->m_encodin    
5822                     (XML_Bool)! parser->m_par    
5823                     XML_ACCOUNT_DIRECT);         
5824   } else                                         
5825 #endif /* XML_DTD */                             
5826   {                                              
5827     parser->m_processor = contentProcessor;      
5828     /* see externalEntityContentProcessor vs     
5829     result = doContent(parser, parser->m_pare    
5830                        parser->m_encoding, s,    
5831                        (XML_Bool)! parser->m_    
5832                        XML_ACCOUNT_DIRECT);      
5833     if (result == XML_ERROR_NONE) {              
5834       if (! storeRawNames(parser))               
5835         return XML_ERROR_NO_MEMORY;              
5836     }                                            
5837     return result;                               
5838   }                                              
5839 }                                                
5840                                                  
5841 static enum XML_Error PTRCALL                    
5842 errorProcessor(XML_Parser parser, const char     
5843                const char **nextPtr) {           
5844   UNUSED_P(s);                                   
5845   UNUSED_P(end);                                 
5846   UNUSED_P(nextPtr);                             
5847   return parser->m_errorCode;                    
5848 }                                                
5849                                                  
5850 static enum XML_Error                            
5851 storeAttributeValue(XML_Parser parser, const     
5852                     const char *ptr, const ch    
5853                     enum XML_Account account)    
5854   enum XML_Error result                          
5855       = appendAttributeValue(parser, enc, isC    
5856   if (result)                                    
5857     return result;                               
5858   if (! isCdata && poolLength(pool) && poolLa    
5859     poolChop(pool);                              
5860   if (! poolAppendChar(pool, XML_T('\0')))       
5861     return XML_ERROR_NO_MEMORY;                  
5862   return XML_ERROR_NONE;                         
5863 }                                                
5864                                                  
5865 static enum XML_Error                            
5866 appendAttributeValue(XML_Parser parser, const    
5867                      const char *ptr, const c    
5868                      enum XML_Account account    
5869   DTD *const dtd = parser->m_dtd; /* save one    
5870 #ifndef XML_DTD                                  
5871   UNUSED_P(account);                             
5872 #endif                                           
5873                                                  
5874   for (;;) {                                     
5875     const char *next                             
5876         = ptr; /* XmlAttributeValueTok doesn'    
5877     int tok = XmlAttributeValueTok(enc, ptr,     
5878 #ifdef XML_DTD                                   
5879     if (! accountingDiffTolerated(parser, tok    
5880       accountingOnAbort(parser);                 
5881       return XML_ERROR_AMPLIFICATION_LIMIT_BR    
5882     }                                            
5883 #endif                                           
5884     switch (tok) {                               
5885     case XML_TOK_NONE:                           
5886       return XML_ERROR_NONE;                     
5887     case XML_TOK_INVALID:                        
5888       if (enc == parser->m_encoding)             
5889         parser->m_eventPtr = next;               
5890       return XML_ERROR_INVALID_TOKEN;            
5891     case XML_TOK_PARTIAL:                        
5892       if (enc == parser->m_encoding)             
5893         parser->m_eventPtr = ptr;                
5894       return XML_ERROR_INVALID_TOKEN;            
5895     case XML_TOK_CHAR_REF: {                     
5896       XML_Char buf[XML_ENCODE_MAX];              
5897       int i;                                     
5898       int n = XmlCharRefNumber(enc, ptr);        
5899       if (n < 0) {                               
5900         if (enc == parser->m_encoding)           
5901           parser->m_eventPtr = ptr;              
5902         return XML_ERROR_BAD_CHAR_REF;           
5903       }                                          
5904       if (! isCdata && n == 0x20 /* space */     
5905           && (poolLength(pool) == 0 || poolLa    
5906         break;                                   
5907       n = XmlEncode(n, (ICHAR *)buf);            
5908       /* The XmlEncode() functions can never     
5909        * error return happens if the code poi    
5910        * negative or greater than or equal to    
5911        * XmlCharRefNumber() functions will al    
5912        * strictly less than 0x110000 or a neg    
5913        * occurred.  The negative value is int    
5914        * XmlEncode() is never passed a value     
5915        * error for.                              
5916        */                                        
5917       for (i = 0; i < n; i++) {                  
5918         if (! poolAppendChar(pool, buf[i]))      
5919           return XML_ERROR_NO_MEMORY;            
5920       }                                          
5921     } break;                                     
5922     case XML_TOK_DATA_CHARS:                     
5923       if (! poolAppend(pool, enc, ptr, next))    
5924         return XML_ERROR_NO_MEMORY;              
5925       break;                                     
5926     case XML_TOK_TRAILING_CR:                    
5927       next = ptr + enc->minBytesPerChar;         
5928       /* fall through */                         
5929     case XML_TOK_ATTRIBUTE_VALUE_S:              
5930     case XML_TOK_DATA_NEWLINE:                   
5931       if (! isCdata && (poolLength(pool) == 0    
5932         break;                                   
5933       if (! poolAppendChar(pool, 0x20))          
5934         return XML_ERROR_NO_MEMORY;              
5935       break;                                     
5936     case XML_TOK_ENTITY_REF: {                   
5937       const XML_Char *name;                      
5938       ENTITY *entity;                            
5939       char checkEntityDecl;                      
5940       XML_Char ch = (XML_Char)XmlPredefinedEn    
5941           enc, ptr + enc->minBytesPerChar, ne    
5942       if (ch) {                                  
5943 #ifdef XML_DTD                                   
5944         /* NOTE: We are replacing 4-6 charact    
5945          *       so there is no amplification    
5946          *       protection. */                  
5947         accountingDiffTolerated(parser, tok,     
5948                                 ((char *)&ch)    
5949                                 XML_ACCOUNT_E    
5950 #endif /* XML_DTD */                             
5951         if (! poolAppendChar(pool, ch))          
5952           return XML_ERROR_NO_MEMORY;            
5953         break;                                   
5954       }                                          
5955       name = poolStoreString(&parser->m_temp2    
5956                              ptr + enc->minBy    
5957                              next - enc->minB    
5958       if (! name)                                
5959         return XML_ERROR_NO_MEMORY;              
5960       entity = (ENTITY *)lookup(parser, &dtd-    
5961       poolDiscard(&parser->m_temp2Pool);         
5962       /* First, determine if a check for an e    
5963          if yes, check that the entity exists    
5964       */                                         
5965       if (pool == &dtd->pool) /* are we calle    
5966         checkEntityDecl =                        
5967 #ifdef XML_DTD                                   
5968             parser->m_prologState.documentEnt    
5969 #endif /* XML_DTD */                             
5970             (dtd->standalone ? ! parser->m_op    
5971                              : ! dtd->hasPara    
5972       else /* if (pool == &parser->m_tempPool    
5973         checkEntityDecl = ! dtd->hasParamEnti    
5974       if (checkEntityDecl) {                     
5975         if (! entity)                            
5976           return XML_ERROR_UNDEFINED_ENTITY;     
5977         else if (! entity->is_internal)          
5978           return XML_ERROR_ENTITY_DECLARED_IN    
5979       } else if (! entity) {                     
5980         /* Cannot report skipped entity here     
5981            parser->m_skippedEntityHandler.       
5982         if (parser->m_skippedEntityHandler)      
5983           parser->m_skippedEntityHandler(pars    
5984         */                                       
5985         /* Cannot call the default handler be    
5986            out of sync with the call to the s    
5987         if ((pool == &parser->m_tempPool) &&     
5988           reportDefault(parser, enc, ptr, nex    
5989         */                                       
5990         break;                                   
5991       }                                          
5992       if (entity->open) {                        
5993         if (enc == parser->m_encoding) {         
5994           /* It does not appear that this lin    
5995            *                                     
5996            * The "if (entity->open)" check ca    
5997            * definitions.  In order to be cal    
5998            * entity, it must have gone throug    
5999            * been through the recursive call     
6000            * appendAttributeValue() some line    
6001            * sets the local encoding ("enc")     
6002            * internal encoding (internal_utf8    
6003            * which can never be the same as t    
6004            * It doesn't appear there is anoth    
6005            * here with entity->open being TRU    
6006            *                                     
6007            * Since it is not certain that thi    
6008            * we keep the line and merely excl    
6009            * tests.                              
6010            */                                    
6011           parser->m_eventPtr = ptr; /* LCOV_E    
6012         }                                        
6013         return XML_ERROR_RECURSIVE_ENTITY_REF    
6014       }                                          
6015       if (entity->notation) {                    
6016         if (enc == parser->m_encoding)           
6017           parser->m_eventPtr = ptr;              
6018         return XML_ERROR_BINARY_ENTITY_REF;      
6019       }                                          
6020       if (! entity->textPtr) {                   
6021         if (enc == parser->m_encoding)           
6022           parser->m_eventPtr = ptr;              
6023         return XML_ERROR_ATTRIBUTE_EXTERNAL_E    
6024       } else {                                   
6025         enum XML_Error result;                   
6026         const XML_Char *textEnd = entity->tex    
6027         entity->open = XML_TRUE;                 
6028 #ifdef XML_DTD                                   
6029         entityTrackingOnOpen(parser, entity,     
6030 #endif                                           
6031         result = appendAttributeValue(parser,    
6032                                       isCdata    
6033                                       (const     
6034                                       XML_ACC    
6035 #ifdef XML_DTD                                   
6036         entityTrackingOnClose(parser, entity,    
6037 #endif                                           
6038         entity->open = XML_FALSE;                
6039         if (result)                              
6040           return result;                         
6041       }                                          
6042     } break;                                     
6043     default:                                     
6044       /* The only token returned by XmlAttrib    
6045        * not have an explicit case here is XM    
6046        * Getting that would require an entity    
6047        * incomplete XML character (e.g. \xE2\    
6048        * tokenisers will have already recogni    
6049        * names before XmlAttributeValueTok()     
6050        * default case should be retained as a    
6051        * excluded from coverage tests.           
6052        *                                         
6053        * LCOV_EXCL_START                         
6054        */                                        
6055       if (enc == parser->m_encoding)             
6056         parser->m_eventPtr = ptr;                
6057       return XML_ERROR_UNEXPECTED_STATE;         
6058       /* LCOV_EXCL_STOP */                       
6059     }                                            
6060     ptr = next;                                  
6061   }                                              
6062   /* not reached */                              
6063 }                                                
6064                                                  
6065 static enum XML_Error                            
6066 storeEntityValue(XML_Parser parser, const ENC    
6067                  const char *entityTextPtr, c    
6068                  enum XML_Account account) {     
6069   DTD *const dtd = parser->m_dtd; /* save one    
6070   STRING_POOL *pool = &(dtd->entityValuePool)    
6071   enum XML_Error result = XML_ERROR_NONE;        
6072 #ifdef XML_DTD                                   
6073   int oldInEntityValue = parser->m_prologStat    
6074   parser->m_prologState.inEntityValue = 1;       
6075 #else                                            
6076   UNUSED_P(account);                             
6077 #endif /* XML_DTD */                             
6078   /* never return Null for the value argument    
6079      since this would indicate an external en    
6080      have to make sure that entityValuePool.s    
6081   if (! pool->blocks) {                          
6082     if (! poolGrow(pool))                        
6083       return XML_ERROR_NO_MEMORY;                
6084   }                                              
6085                                                  
6086   for (;;) {                                     
6087     const char *next                             
6088         = entityTextPtr; /* XmlEntityValueTok    
6089     int tok = XmlEntityValueTok(enc, entityTe    
6090                                                  
6091 #ifdef XML_DTD                                   
6092     if (! accountingDiffTolerated(parser, tok    
6093                                   account)) {    
6094       accountingOnAbort(parser);                 
6095       result = XML_ERROR_AMPLIFICATION_LIMIT_    
6096       goto endEntityValue;                       
6097     }                                            
6098 #endif                                           
6099                                                  
6100     switch (tok) {                               
6101     case XML_TOK_PARAM_ENTITY_REF:               
6102 #ifdef XML_DTD                                   
6103       if (parser->m_isParamEntity || enc != p    
6104         const XML_Char *name;                    
6105         ENTITY *entity;                          
6106         name = poolStoreString(&parser->m_tem    
6107                                entityTextPtr     
6108                                next - enc->mi    
6109         if (! name) {                            
6110           result = XML_ERROR_NO_MEMORY;          
6111           goto endEntityValue;                   
6112         }                                        
6113         entity = (ENTITY *)lookup(parser, &dt    
6114         poolDiscard(&parser->m_tempPool);        
6115         if (! entity) {                          
6116           /* not a well-formedness error - se    
6117           /* cannot report skipped entity her    
6118              parser->m_skippedEntityHandler      
6119           if (parser->m_skippedEntityHandler)    
6120             parser->m_skippedEntityHandler(pa    
6121           */                                     
6122           dtd->keepProcessing = dtd->standalo    
6123           goto endEntityValue;                   
6124         }                                        
6125         if (entity->open) {                      
6126           if (enc == parser->m_encoding)         
6127             parser->m_eventPtr = entityTextPt    
6128           result = XML_ERROR_RECURSIVE_ENTITY    
6129           goto endEntityValue;                   
6130         }                                        
6131         if (entity->systemId) {                  
6132           if (parser->m_externalEntityRefHand    
6133             dtd->paramEntityRead = XML_FALSE;    
6134             entity->open = XML_TRUE;             
6135             entityTrackingOnOpen(parser, enti    
6136             if (! parser->m_externalEntityRef    
6137                     parser->m_externalEntityR    
6138                     entity->systemId, entity-    
6139               entityTrackingOnClose(parser, e    
6140               entity->open = XML_FALSE;          
6141               result = XML_ERROR_EXTERNAL_ENT    
6142               goto endEntityValue;               
6143             }                                    
6144             entityTrackingOnClose(parser, ent    
6145             entity->open = XML_FALSE;            
6146             if (! dtd->paramEntityRead)          
6147               dtd->keepProcessing = dtd->stan    
6148           } else                                 
6149             dtd->keepProcessing = dtd->standa    
6150         } else {                                 
6151           entity->open = XML_TRUE;               
6152           entityTrackingOnOpen(parser, entity    
6153           result = storeEntityValue(             
6154               parser, parser->m_internalEncod    
6155               (const char *)(entity->textPtr     
6156               XML_ACCOUNT_ENTITY_EXPANSION);     
6157           entityTrackingOnClose(parser, entit    
6158           entity->open = XML_FALSE;              
6159           if (result)                            
6160             goto endEntityValue;                 
6161         }                                        
6162         break;                                   
6163       }                                          
6164 #endif /* XML_DTD */                             
6165       /* In the internal subset, PE reference    
6166          within markup declarations, e.g enti    
6167       parser->m_eventPtr = entityTextPtr;        
6168       result = XML_ERROR_PARAM_ENTITY_REF;       
6169       goto endEntityValue;                       
6170     case XML_TOK_NONE:                           
6171       result = XML_ERROR_NONE;                   
6172       goto endEntityValue;                       
6173     case XML_TOK_ENTITY_REF:                     
6174     case XML_TOK_DATA_CHARS:                     
6175       if (! poolAppend(pool, enc, entityTextP    
6176         result = XML_ERROR_NO_MEMORY;            
6177         goto endEntityValue;                     
6178       }                                          
6179       break;                                     
6180     case XML_TOK_TRAILING_CR:                    
6181       next = entityTextPtr + enc->minBytesPer    
6182       /* fall through */                         
6183     case XML_TOK_DATA_NEWLINE:                   
6184       if (pool->end == pool->ptr && ! poolGro    
6185         result = XML_ERROR_NO_MEMORY;            
6186         goto endEntityValue;                     
6187       }                                          
6188       *(pool->ptr)++ = 0xA;                      
6189       break;                                     
6190     case XML_TOK_CHAR_REF: {                     
6191       XML_Char buf[XML_ENCODE_MAX];              
6192       int i;                                     
6193       int n = XmlCharRefNumber(enc, entityTex    
6194       if (n < 0) {                               
6195         if (enc == parser->m_encoding)           
6196           parser->m_eventPtr = entityTextPtr;    
6197         result = XML_ERROR_BAD_CHAR_REF;         
6198         goto endEntityValue;                     
6199       }                                          
6200       n = XmlEncode(n, (ICHAR *)buf);            
6201       /* The XmlEncode() functions can never     
6202        * error return happens if the code poi    
6203        * negative or greater than or equal to    
6204        * XmlCharRefNumber() functions will al    
6205        * strictly less than 0x110000 or a neg    
6206        * occurred.  The negative value is int    
6207        * XmlEncode() is never passed a value     
6208        * error for.                              
6209        */                                        
6210       for (i = 0; i < n; i++) {                  
6211         if (pool->end == pool->ptr && ! poolG    
6212           result = XML_ERROR_NO_MEMORY;          
6213           goto endEntityValue;                   
6214         }                                        
6215         *(pool->ptr)++ = buf[i];                 
6216       }                                          
6217     } break;                                     
6218     case XML_TOK_PARTIAL:                        
6219       if (enc == parser->m_encoding)             
6220         parser->m_eventPtr = entityTextPtr;      
6221       result = XML_ERROR_INVALID_TOKEN;          
6222       goto endEntityValue;                       
6223     case XML_TOK_INVALID:                        
6224       if (enc == parser->m_encoding)             
6225         parser->m_eventPtr = next;               
6226       result = XML_ERROR_INVALID_TOKEN;          
6227       goto endEntityValue;                       
6228     default:                                     
6229       /* This default case should be unnecess    
6230        * that XmlEntityValueTok() can return     
6231        * cases -- but should be retained for     
6232        * exclude it from the coverage statist    
6233        *                                         
6234        * LCOV_EXCL_START                         
6235        */                                        
6236       if (enc == parser->m_encoding)             
6237         parser->m_eventPtr = entityTextPtr;      
6238       result = XML_ERROR_UNEXPECTED_STATE;       
6239       goto endEntityValue;                       
6240       /* LCOV_EXCL_STOP */                       
6241     }                                            
6242     entityTextPtr = next;                        
6243   }                                              
6244 endEntityValue:                                  
6245 #ifdef XML_DTD                                   
6246   parser->m_prologState.inEntityValue = oldIn    
6247 #endif /* XML_DTD */                             
6248   return result;                                 
6249 }                                                
6250                                                  
6251 static void FASTCALL                             
6252 normalizeLines(XML_Char *s) {                    
6253   XML_Char *p;                                   
6254   for (;; s++) {                                 
6255     if (*s == XML_T('\0'))                       
6256       return;                                    
6257     if (*s == 0xD)                               
6258       break;                                     
6259   }                                              
6260   p = s;                                         
6261   do {                                           
6262     if (*s == 0xD) {                             
6263       *p++ = 0xA;                                
6264       if (*++s == 0xA)                           
6265         s++;                                     
6266     } else                                       
6267       *p++ = *s++;                               
6268   } while (*s);                                  
6269   *p = XML_T('\0');                              
6270 }                                                
6271                                                  
6272 static int                                       
6273 reportProcessingInstruction(XML_Parser parser    
6274                             const char *start    
6275   const XML_Char *target;                        
6276   XML_Char *data;                                
6277   const char *tem;                               
6278   if (! parser->m_processingInstructionHandle    
6279     if (parser->m_defaultHandler)                
6280       reportDefault(parser, enc, start, end);    
6281     return 1;                                    
6282   }                                              
6283   start += enc->minBytesPerChar * 2;             
6284   tem = start + XmlNameLength(enc, start);       
6285   target = poolStoreString(&parser->m_tempPoo    
6286   if (! target)                                  
6287     return 0;                                    
6288   poolFinish(&parser->m_tempPool);               
6289   data = poolStoreString(&parser->m_tempPool,    
6290                          end - enc->minBytesP    
6291   if (! data)                                    
6292     return 0;                                    
6293   normalizeLines(data);                          
6294   parser->m_processingInstructionHandler(pars    
6295   poolClear(&parser->m_tempPool);                
6296   return 1;                                      
6297 }                                                
6298                                                  
6299 static int                                       
6300 reportComment(XML_Parser parser, const ENCODI    
6301               const char *end) {                 
6302   XML_Char *data;                                
6303   if (! parser->m_commentHandler) {              
6304     if (parser->m_defaultHandler)                
6305       reportDefault(parser, enc, start, end);    
6306     return 1;                                    
6307   }                                              
6308   data = poolStoreString(&parser->m_tempPool,    
6309                          start + enc->minByte    
6310                          end - enc->minBytesP    
6311   if (! data)                                    
6312     return 0;                                    
6313   normalizeLines(data);                          
6314   parser->m_commentHandler(parser->m_handlerA    
6315   poolClear(&parser->m_tempPool);                
6316   return 1;                                      
6317 }                                                
6318                                                  
6319 static void                                      
6320 reportDefault(XML_Parser parser, const ENCODI    
6321               const char *end) {                 
6322   if (MUST_CONVERT(enc, s)) {                    
6323     enum XML_Convert_Result convert_res;         
6324     const char **eventPP;                        
6325     const char **eventEndPP;                     
6326     if (enc == parser->m_encoding) {             
6327       eventPP = &parser->m_eventPtr;             
6328       eventEndPP = &parser->m_eventEndPtr;       
6329     } else {                                     
6330       /* To get here, two things must be true    
6331        * using a character encoding that is n    
6332        * encoding passed in, and the encoding    
6333        * conversion to the internal format (U    
6334        * is defined).  The only occasions on     
6335        * in is not the same as the parser's e    
6336        * the internal encoding (e.g. a previo    
6337        * entity, already converted to interna    
6338        * definition doesn't need conversion,     
6339        * gets executed.                          
6340        *                                         
6341        * For safety's sake we don't delete th    
6342        * exclude them from coverage statistic    
6343        *                                         
6344        * LCOV_EXCL_START                         
6345        */                                        
6346       eventPP = &(parser->m_openInternalEntit    
6347       eventEndPP = &(parser->m_openInternalEn    
6348       /* LCOV_EXCL_STOP */                       
6349     }                                            
6350     do {                                         
6351       ICHAR *dataPtr = (ICHAR *)parser->m_dat    
6352       convert_res                                
6353           = XmlConvert(enc, &s, end, &dataPtr    
6354       *eventEndPP = s;                           
6355       parser->m_defaultHandler(parser->m_hand    
6356                                (int)(dataPtr     
6357       *eventPP = s;                              
6358     } while ((convert_res != XML_CONVERT_COMP    
6359              && (convert_res != XML_CONVERT_I    
6360   } else                                         
6361     parser->m_defaultHandler(parser->m_handle    
6362                              (int)((XML_Char     
6363 }                                                
6364                                                  
6365 static int                                       
6366 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE    
6367                 XML_Bool isId, const XML_Char    
6368   DEFAULT_ATTRIBUTE *att;                        
6369   if (value || isId) {                           
6370     /* The handling of default attributes get    
6371        a default which duplicates a non-defau    
6372     int i;                                       
6373     for (i = 0; i < type->nDefaultAtts; i++)     
6374       if (attId == type->defaultAtts[i].id)      
6375         return 1;                                
6376     if (isId && ! type->idAtt && ! attId->xml    
6377       type->idAtt = attId;                       
6378   }                                              
6379   if (type->nDefaultAtts == type->allocDefaul    
6380     if (type->allocDefaultAtts == 0) {           
6381       type->allocDefaultAtts = 8;                
6382       type->defaultAtts = (DEFAULT_ATTRIBUTE     
6383           parser, type->allocDefaultAtts * si    
6384       if (! type->defaultAtts) {                 
6385         type->allocDefaultAtts = 0;              
6386         return 0;                                
6387       }                                          
6388     } else {                                     
6389       DEFAULT_ATTRIBUTE *temp;                   
6390                                                  
6391       /* Detect and prevent integer overflow     
6392       if (type->allocDefaultAtts > INT_MAX /     
6393         return 0;                                
6394       }                                          
6395                                                  
6396       int count = type->allocDefaultAtts * 2;    
6397                                                  
6398       /* Detect and prevent integer overflow.    
6399        * The preprocessor guard addresses the    
6400        * from -Wtype-limits on platforms wher    
6401        * sizeof(unsigned int) < sizeof(size_t    
6402 #if UINT_MAX >= SIZE_MAX                         
6403       if ((unsigned)count > (size_t)(-1) / si    
6404         return 0;                                
6405       }                                          
6406 #endif                                           
6407                                                  
6408       temp = (DEFAULT_ATTRIBUTE *)REALLOC(par    
6409                                           (co    
6410       if (temp == NULL)                          
6411         return 0;                                
6412       type->allocDefaultAtts = count;            
6413       type->defaultAtts = temp;                  
6414     }                                            
6415   }                                              
6416   att = type->defaultAtts + type->nDefaultAtt    
6417   att->id = attId;                               
6418   att->value = value;                            
6419   att->isCdata = isCdata;                        
6420   if (! isCdata)                                 
6421     attId->maybeTokenized = XML_TRUE;            
6422   type->nDefaultAtts += 1;                       
6423   return 1;                                      
6424 }                                                
6425                                                  
6426 static int                                       
6427 setElementTypePrefix(XML_Parser parser, ELEME    
6428   DTD *const dtd = parser->m_dtd; /* save one    
6429   const XML_Char *name;                          
6430   for (name = elementType->name; *name; name+    
6431     if (*name == XML_T(ASCII_COLON)) {           
6432       PREFIX *prefix;                            
6433       const XML_Char *s;                         
6434       for (s = elementType->name; s != name;     
6435         if (! poolAppendChar(&dtd->pool, *s))    
6436           return 0;                              
6437       }                                          
6438       if (! poolAppendChar(&dtd->pool, XML_T(    
6439         return 0;                                
6440       prefix = (PREFIX *)lookup(parser, &dtd-    
6441                                 sizeof(PREFIX    
6442       if (! prefix)                              
6443         return 0;                                
6444       if (prefix->name == poolStart(&dtd->poo    
6445         poolFinish(&dtd->pool);                  
6446       else                                       
6447         poolDiscard(&dtd->pool);                 
6448       elementType->prefix = prefix;              
6449       break;                                     
6450     }                                            
6451   }                                              
6452   return 1;                                      
6453 }                                                
6454                                                  
6455 static ATTRIBUTE_ID *                            
6456 getAttributeId(XML_Parser parser, const ENCOD    
6457                const char *end) {                
6458   DTD *const dtd = parser->m_dtd; /* save one    
6459   ATTRIBUTE_ID *id;                              
6460   const XML_Char *name;                          
6461   if (! poolAppendChar(&dtd->pool, XML_T('\0'    
6462     return NULL;                                 
6463   name = poolStoreString(&dtd->pool, enc, sta    
6464   if (! name)                                    
6465     return NULL;                                 
6466   /* skip quotation mark - its storage will b    
6467   ++name;                                        
6468   id = (ATTRIBUTE_ID *)lookup(parser, &dtd->a    
6469                               sizeof(ATTRIBUT    
6470   if (! id)                                      
6471     return NULL;                                 
6472   if (id->name != name)                          
6473     poolDiscard(&dtd->pool);                     
6474   else {                                         
6475     poolFinish(&dtd->pool);                      
6476     if (! parser->m_ns)                          
6477       ;                                          
6478     else if (name[0] == XML_T(ASCII_x) && nam    
6479              && name[2] == XML_T(ASCII_l) &&     
6480              && name[4] == XML_T(ASCII_s)        
6481              && (name[5] == XML_T('\0') || na    
6482       if (name[5] == XML_T('\0'))                
6483         id->prefix = &dtd->defaultPrefix;        
6484       else                                       
6485         id->prefix = (PREFIX *)lookup(parser,    
6486                                       sizeof(    
6487       id->xmlns = XML_TRUE;                      
6488     } else {                                     
6489       int i;                                     
6490       for (i = 0; name[i]; i++) {                
6491         /* attributes without prefix are *not    
6492         if (name[i] == XML_T(ASCII_COLON)) {     
6493           int j;                                 
6494           for (j = 0; j < i; j++) {              
6495             if (! poolAppendChar(&dtd->pool,     
6496               return NULL;                       
6497           }                                      
6498           if (! poolAppendChar(&dtd->pool, XM    
6499             return NULL;                         
6500           id->prefix = (PREFIX *)lookup(parse    
6501                                         poolS    
6502           if (! id->prefix)                      
6503             return NULL;                         
6504           if (id->prefix->name == poolStart(&    
6505             poolFinish(&dtd->pool);              
6506           else                                   
6507             poolDiscard(&dtd->pool);             
6508           break;                                 
6509         }                                        
6510       }                                          
6511     }                                            
6512   }                                              
6513   return id;                                     
6514 }                                                
6515                                                  
6516 #define CONTEXT_SEP XML_T(ASCII_FF)              
6517                                                  
6518 static const XML_Char *                          
6519 getContext(XML_Parser parser) {                  
6520   DTD *const dtd = parser->m_dtd; /* save one    
6521   HASH_TABLE_ITER iter;                          
6522   XML_Bool needSep = XML_FALSE;                  
6523                                                  
6524   if (dtd->defaultPrefix.binding) {              
6525     int i;                                       
6526     int len;                                     
6527     if (! poolAppendChar(&parser->m_tempPool,    
6528       return NULL;                               
6529     len = dtd->defaultPrefix.binding->uriLen;    
6530     if (parser->m_namespaceSeparator)            
6531       len--;                                     
6532     for (i = 0; i < len; i++) {                  
6533       if (! poolAppendChar(&parser->m_tempPoo    
6534                            dtd->defaultPrefix    
6535         /* Because of memory caching, I don't    
6536          * executed.                             
6537          *                                       
6538          * This is part of a loop copying the    
6539          * URI into the parser's temporary st    
6540          * that URI was copied into the same     
6541          * terminating NUL character, as part    
6542          * the pool was cleared, that leaves     
6543          * enough to hold the URI on the free    
6544          * The URI copy in getContext() there    
6545          * memory.                               
6546          *                                       
6547          * If the pool is used between the se    
6548          * getContext() calls, the worst it c    
6549          * block on the front of the free lis    
6550          * all somewhat inobvious and program    
6551          * don't delete the line but we do ex    
6552          * coverage statistics.                  
6553          */                                      
6554         return NULL; /* LCOV_EXCL_LINE */        
6555       }                                          
6556     }                                            
6557     needSep = XML_TRUE;                          
6558   }                                              
6559                                                  
6560   hashTableIterInit(&iter, &(dtd->prefixes));    
6561   for (;;) {                                     
6562     int i;                                       
6563     int len;                                     
6564     const XML_Char *s;                           
6565     PREFIX *prefix = (PREFIX *)hashTableIterN    
6566     if (! prefix)                                
6567       break;                                     
6568     if (! prefix->binding) {                     
6569       /* This test appears to be (justifiable    
6570        * not seem to be a way of injecting a     
6571        * that doesn't get errored long before    
6572        * The test should remain for safety's     
6573        * exclude the following line from the     
6574        */                                        
6575       continue; /* LCOV_EXCL_LINE */             
6576     }                                            
6577     if (needSep && ! poolAppendChar(&parser->    
6578       return NULL;                               
6579     for (s = prefix->name; *s; s++)              
6580       if (! poolAppendChar(&parser->m_tempPoo    
6581         return NULL;                             
6582     if (! poolAppendChar(&parser->m_tempPool,    
6583       return NULL;                               
6584     len = prefix->binding->uriLen;               
6585     if (parser->m_namespaceSeparator)            
6586       len--;                                     
6587     for (i = 0; i < len; i++)                    
6588       if (! poolAppendChar(&parser->m_tempPoo    
6589         return NULL;                             
6590     needSep = XML_TRUE;                          
6591   }                                              
6592                                                  
6593   hashTableIterInit(&iter, &(dtd->generalEnti    
6594   for (;;) {                                     
6595     const XML_Char *s;                           
6596     ENTITY *e = (ENTITY *)hashTableIterNext(&    
6597     if (! e)                                     
6598       break;                                     
6599     if (! e->open)                               
6600       continue;                                  
6601     if (needSep && ! poolAppendChar(&parser->    
6602       return NULL;                               
6603     for (s = e->name; *s; s++)                   
6604       if (! poolAppendChar(&parser->m_tempPoo    
6605         return 0;                                
6606     needSep = XML_TRUE;                          
6607   }                                              
6608                                                  
6609   if (! poolAppendChar(&parser->m_tempPool, X    
6610     return NULL;                                 
6611   return parser->m_tempPool.start;               
6612 }                                                
6613                                                  
6614 static XML_Bool                                  
6615 setContext(XML_Parser parser, const XML_Char     
6616   DTD *const dtd = parser->m_dtd; /* save one    
6617   const XML_Char *s = context;                   
6618                                                  
6619   while (*context != XML_T('\0')) {              
6620     if (*s == CONTEXT_SEP || *s == XML_T('\0'    
6621       ENTITY *e;                                 
6622       if (! poolAppendChar(&parser->m_tempPoo    
6623         return XML_FALSE;                        
6624       e = (ENTITY *)lookup(parser, &dtd->gene    
6625                            poolStart(&parser-    
6626       if (e)                                     
6627         e->open = XML_TRUE;                      
6628       if (*s != XML_T('\0'))                     
6629         s++;                                     
6630       context = s;                               
6631       poolDiscard(&parser->m_tempPool);          
6632     } else if (*s == XML_T(ASCII_EQUALS)) {      
6633       PREFIX *prefix;                            
6634       if (poolLength(&parser->m_tempPool) ==     
6635         prefix = &dtd->defaultPrefix;            
6636       else {                                     
6637         if (! poolAppendChar(&parser->m_tempP    
6638           return XML_FALSE;                      
6639         prefix                                   
6640             = (PREFIX *)lookup(parser, &dtd->    
6641                                poolStart(&par    
6642         if (! prefix)                            
6643           return XML_FALSE;                      
6644         if (prefix->name == poolStart(&parser    
6645           prefix->name = poolCopyString(&dtd-    
6646           if (! prefix->name)                    
6647             return XML_FALSE;                    
6648         }                                        
6649         poolDiscard(&parser->m_tempPool);        
6650       }                                          
6651       for (context = s + 1; *context != CONTE    
6652            context++)                            
6653         if (! poolAppendChar(&parser->m_tempP    
6654           return XML_FALSE;                      
6655       if (! poolAppendChar(&parser->m_tempPoo    
6656         return XML_FALSE;                        
6657       if (addBinding(parser, prefix, NULL, po    
6658                      &parser->m_inheritedBind    
6659           != XML_ERROR_NONE)                     
6660         return XML_FALSE;                        
6661       poolDiscard(&parser->m_tempPool);          
6662       if (*context != XML_T('\0'))               
6663         ++context;                               
6664       s = context;                               
6665     } else {                                     
6666       if (! poolAppendChar(&parser->m_tempPoo    
6667         return XML_FALSE;                        
6668       s++;                                       
6669     }                                            
6670   }                                              
6671   return XML_TRUE;                               
6672 }                                                
6673                                                  
6674 static void FASTCALL                             
6675 normalizePublicId(XML_Char *publicId) {          
6676   XML_Char *p = publicId;                        
6677   XML_Char *s;                                   
6678   for (s = publicId; *s; s++) {                  
6679     switch (*s) {                                
6680     case 0x20:                                   
6681     case 0xD:                                    
6682     case 0xA:                                    
6683       if (p != publicId && p[-1] != 0x20)        
6684         *p++ = 0x20;                             
6685       break;                                     
6686     default:                                     
6687       *p++ = *s;                                 
6688     }                                            
6689   }                                              
6690   if (p != publicId && p[-1] == 0x20)            
6691     --p;                                         
6692   *p = XML_T('\0');                              
6693 }                                                
6694                                                  
6695 static DTD *                                     
6696 dtdCreate(const XML_Memory_Handling_Suite *ms    
6697   DTD *p = ms->malloc_fcn(sizeof(DTD));          
6698   if (p == NULL)                                 
6699     return p;                                    
6700   poolInit(&(p->pool), ms);                      
6701   poolInit(&(p->entityValuePool), ms);           
6702   hashTableInit(&(p->generalEntities), ms);      
6703   hashTableInit(&(p->elementTypes), ms);         
6704   hashTableInit(&(p->attributeIds), ms);         
6705   hashTableInit(&(p->prefixes), ms);             
6706 #ifdef XML_DTD                                   
6707   p->paramEntityRead = XML_FALSE;                
6708   hashTableInit(&(p->paramEntities), ms);        
6709 #endif /* XML_DTD */                             
6710   p->defaultPrefix.name = NULL;                  
6711   p->defaultPrefix.binding = NULL;               
6712                                                  
6713   p->in_eldecl = XML_FALSE;                      
6714   p->scaffIndex = NULL;                          
6715   p->scaffold = NULL;                            
6716   p->scaffLevel = 0;                             
6717   p->scaffSize = 0;                              
6718   p->scaffCount = 0;                             
6719   p->contentStringLen = 0;                       
6720                                                  
6721   p->keepProcessing = XML_TRUE;                  
6722   p->hasParamEntityRefs = XML_FALSE;             
6723   p->standalone = XML_FALSE;                     
6724   return p;                                      
6725 }                                                
6726                                                  
6727 static void                                      
6728 dtdReset(DTD *p, const XML_Memory_Handling_Su    
6729   HASH_TABLE_ITER iter;                          
6730   hashTableIterInit(&iter, &(p->elementTypes)    
6731   for (;;) {                                     
6732     ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTab    
6733     if (! e)                                     
6734       break;                                     
6735     if (e->allocDefaultAtts != 0)                
6736       ms->free_fcn(e->defaultAtts);              
6737   }                                              
6738   hashTableClear(&(p->generalEntities));         
6739 #ifdef XML_DTD                                   
6740   p->paramEntityRead = XML_FALSE;                
6741   hashTableClear(&(p->paramEntities));           
6742 #endif /* XML_DTD */                             
6743   hashTableClear(&(p->elementTypes));            
6744   hashTableClear(&(p->attributeIds));            
6745   hashTableClear(&(p->prefixes));                
6746   poolClear(&(p->pool));                         
6747   poolClear(&(p->entityValuePool));              
6748   p->defaultPrefix.name = NULL;                  
6749   p->defaultPrefix.binding = NULL;               
6750                                                  
6751   p->in_eldecl = XML_FALSE;                      
6752                                                  
6753   ms->free_fcn(p->scaffIndex);                   
6754   p->scaffIndex = NULL;                          
6755   ms->free_fcn(p->scaffold);                     
6756   p->scaffold = NULL;                            
6757                                                  
6758   p->scaffLevel = 0;                             
6759   p->scaffSize = 0;                              
6760   p->scaffCount = 0;                             
6761   p->contentStringLen = 0;                       
6762                                                  
6763   p->keepProcessing = XML_TRUE;                  
6764   p->hasParamEntityRefs = XML_FALSE;             
6765   p->standalone = XML_FALSE;                     
6766 }                                                
6767                                                  
6768 static void                                      
6769 dtdDestroy(DTD *p, XML_Bool isDocEntity, cons    
6770   HASH_TABLE_ITER iter;                          
6771   hashTableIterInit(&iter, &(p->elementTypes)    
6772   for (;;) {                                     
6773     ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTab    
6774     if (! e)                                     
6775       break;                                     
6776     if (e->allocDefaultAtts != 0)                
6777       ms->free_fcn(e->defaultAtts);              
6778   }                                              
6779   hashTableDestroy(&(p->generalEntities));       
6780 #ifdef XML_DTD                                   
6781   hashTableDestroy(&(p->paramEntities));         
6782 #endif /* XML_DTD */                             
6783   hashTableDestroy(&(p->elementTypes));          
6784   hashTableDestroy(&(p->attributeIds));          
6785   hashTableDestroy(&(p->prefixes));              
6786   poolDestroy(&(p->pool));                       
6787   poolDestroy(&(p->entityValuePool));            
6788   if (isDocEntity) {                             
6789     ms->free_fcn(p->scaffIndex);                 
6790     ms->free_fcn(p->scaffold);                   
6791   }                                              
6792   ms->free_fcn(p);                               
6793 }                                                
6794                                                  
6795 /* Do a deep copy of the DTD. Return 0 for ou    
6796    The new DTD has already been initialized.     
6797 */                                               
6798 static int                                       
6799 dtdCopy(XML_Parser oldParser, DTD *newDtd, co    
6800         const XML_Memory_Handling_Suite *ms)     
6801   HASH_TABLE_ITER iter;                          
6802                                                  
6803   /* Copy the prefix table. */                   
6804                                                  
6805   hashTableIterInit(&iter, &(oldDtd->prefixes    
6806   for (;;) {                                     
6807     const XML_Char *name;                        
6808     const PREFIX *oldP = (PREFIX *)hashTableI    
6809     if (! oldP)                                  
6810       break;                                     
6811     name = poolCopyString(&(newDtd->pool), ol    
6812     if (! name)                                  
6813       return 0;                                  
6814     if (! lookup(oldParser, &(newDtd->prefixe    
6815       return 0;                                  
6816   }                                              
6817                                                  
6818   hashTableIterInit(&iter, &(oldDtd->attribut    
6819                                                  
6820   /* Copy the attribute id table. */             
6821                                                  
6822   for (;;) {                                     
6823     ATTRIBUTE_ID *newA;                          
6824     const XML_Char *name;                        
6825     const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID     
6826                                                  
6827     if (! oldA)                                  
6828       break;                                     
6829     /* Remember to allocate the scratch byte     
6830     if (! poolAppendChar(&(newDtd->pool), XML    
6831       return 0;                                  
6832     name = poolCopyString(&(newDtd->pool), ol    
6833     if (! name)                                  
6834       return 0;                                  
6835     ++name;                                      
6836     newA = (ATTRIBUTE_ID *)lookup(oldParser,     
6837                                   sizeof(ATTR    
6838     if (! newA)                                  
6839       return 0;                                  
6840     newA->maybeTokenized = oldA->maybeTokeniz    
6841     if (oldA->prefix) {                          
6842       newA->xmlns = oldA->xmlns;                 
6843       if (oldA->prefix == &oldDtd->defaultPre    
6844         newA->prefix = &newDtd->defaultPrefix    
6845       else                                       
6846         newA->prefix = (PREFIX *)lookup(oldPa    
6847                                         oldA-    
6848     }                                            
6849   }                                              
6850                                                  
6851   /* Copy the element type table. */             
6852                                                  
6853   hashTableIterInit(&iter, &(oldDtd->elementT    
6854                                                  
6855   for (;;) {                                     
6856     int i;                                       
6857     ELEMENT_TYPE *newE;                          
6858     const XML_Char *name;                        
6859     const ELEMENT_TYPE *oldE = (ELEMENT_TYPE     
6860     if (! oldE)                                  
6861       break;                                     
6862     name = poolCopyString(&(newDtd->pool), ol    
6863     if (! name)                                  
6864       return 0;                                  
6865     newE = (ELEMENT_TYPE *)lookup(oldParser,     
6866                                   sizeof(ELEM    
6867     if (! newE)                                  
6868       return 0;                                  
6869     if (oldE->nDefaultAtts) {                    
6870       newE->defaultAtts                          
6871           = ms->malloc_fcn(oldE->nDefaultAtts    
6872       if (! newE->defaultAtts) {                 
6873         return 0;                                
6874       }                                          
6875     }                                            
6876     if (oldE->idAtt)                             
6877       newE->idAtt = (ATTRIBUTE_ID *)lookup(ol    
6878                                            ol    
6879     newE->allocDefaultAtts = newE->nDefaultAt    
6880     if (oldE->prefix)                            
6881       newE->prefix = (PREFIX *)lookup(oldPars    
6882                                       oldE->p    
6883     for (i = 0; i < newE->nDefaultAtts; i++)     
6884       newE->defaultAtts[i].id = (ATTRIBUTE_ID    
6885           oldParser, &(newDtd->attributeIds),    
6886       newE->defaultAtts[i].isCdata = oldE->de    
6887       if (oldE->defaultAtts[i].value) {          
6888         newE->defaultAtts[i].value               
6889             = poolCopyString(&(newDtd->pool),    
6890         if (! newE->defaultAtts[i].value)        
6891           return 0;                              
6892       } else                                     
6893         newE->defaultAtts[i].value = NULL;       
6894     }                                            
6895   }                                              
6896                                                  
6897   /* Copy the entity tables. */                  
6898   if (! copyEntityTable(oldParser, &(newDtd->    
6899                         &(oldDtd->generalEnti    
6900     return 0;                                    
6901                                                  
6902 #ifdef XML_DTD                                   
6903   if (! copyEntityTable(oldParser, &(newDtd->    
6904                         &(oldDtd->paramEntiti    
6905     return 0;                                    
6906   newDtd->paramEntityRead = oldDtd->paramEnti    
6907 #endif /* XML_DTD */                             
6908                                                  
6909   newDtd->keepProcessing = oldDtd->keepProces    
6910   newDtd->hasParamEntityRefs = oldDtd->hasPar    
6911   newDtd->standalone = oldDtd->standalone;       
6912                                                  
6913   /* Don't want deep copying for scaffolding     
6914   newDtd->in_eldecl = oldDtd->in_eldecl;         
6915   newDtd->scaffold = oldDtd->scaffold;           
6916   newDtd->contentStringLen = oldDtd->contentS    
6917   newDtd->scaffSize = oldDtd->scaffSize;         
6918   newDtd->scaffLevel = oldDtd->scaffLevel;       
6919   newDtd->scaffIndex = oldDtd->scaffIndex;       
6920                                                  
6921   return 1;                                      
6922 } /* End dtdCopy */                              
6923                                                  
6924 static int                                       
6925 copyEntityTable(XML_Parser oldParser, HASH_TA    
6926                 STRING_POOL *newPool, const H    
6927   HASH_TABLE_ITER iter;                          
6928   const XML_Char *cachedOldBase = NULL;          
6929   const XML_Char *cachedNewBase = NULL;          
6930                                                  
6931   hashTableIterInit(&iter, oldTable);            
6932                                                  
6933   for (;;) {                                     
6934     ENTITY *newE;                                
6935     const XML_Char *name;                        
6936     const ENTITY *oldE = (ENTITY *)hashTableI    
6937     if (! oldE)                                  
6938       break;                                     
6939     name = poolCopyString(newPool, oldE->name    
6940     if (! name)                                  
6941       return 0;                                  
6942     newE = (ENTITY *)lookup(oldParser, newTab    
6943     if (! newE)                                  
6944       return 0;                                  
6945     if (oldE->systemId) {                        
6946       const XML_Char *tem = poolCopyString(ne    
6947       if (! tem)                                 
6948         return 0;                                
6949       newE->systemId = tem;                      
6950       if (oldE->base) {                          
6951         if (oldE->base == cachedOldBase)         
6952           newE->base = cachedNewBase;            
6953         else {                                   
6954           cachedOldBase = oldE->base;            
6955           tem = poolCopyString(newPool, cache    
6956           if (! tem)                             
6957             return 0;                            
6958           cachedNewBase = newE->base = tem;      
6959         }                                        
6960       }                                          
6961       if (oldE->publicId) {                      
6962         tem = poolCopyString(newPool, oldE->p    
6963         if (! tem)                               
6964           return 0;                              
6965         newE->publicId = tem;                    
6966       }                                          
6967     } else {                                     
6968       const XML_Char *tem                        
6969           = poolCopyStringN(newPool, oldE->te    
6970       if (! tem)                                 
6971         return 0;                                
6972       newE->textPtr = tem;                       
6973       newE->textLen = oldE->textLen;             
6974     }                                            
6975     if (oldE->notation) {                        
6976       const XML_Char *tem = poolCopyString(ne    
6977       if (! tem)                                 
6978         return 0;                                
6979       newE->notation = tem;                      
6980     }                                            
6981     newE->is_param = oldE->is_param;             
6982     newE->is_internal = oldE->is_internal;       
6983   }                                              
6984   return 1;                                      
6985 }                                                
6986                                                  
6987 #define INIT_POWER 6                             
6988                                                  
6989 static XML_Bool FASTCALL                         
6990 keyeq(KEY s1, KEY s2) {                          
6991   for (; *s1 == *s2; s1++, s2++)                 
6992     if (*s1 == 0)                                
6993       return XML_TRUE;                           
6994   return XML_FALSE;                              
6995 }                                                
6996                                                  
6997 static size_t                                    
6998 keylen(KEY s) {                                  
6999   size_t len = 0;                                
7000   for (; *s; s++, len++)                         
7001     ;                                            
7002   return len;                                    
7003 }                                                
7004                                                  
7005 static void                                      
7006 copy_salt_to_sipkey(XML_Parser parser, struct    
7007   key->k[0] = 0;                                 
7008   key->k[1] = get_hash_secret_salt(parser);      
7009 }                                                
7010                                                  
7011 static unsigned long FASTCALL                    
7012 hash(XML_Parser parser, KEY s) {                 
7013   struct siphash state;                          
7014   struct sipkey key;                             
7015   (void)sip24_valid;                             
7016   copy_salt_to_sipkey(parser, &key);             
7017   sip24_init(&state, &key);                      
7018   sip24_update(&state, s, keylen(s) * sizeof(    
7019   return (unsigned long)sip24_final(&state);     
7020 }                                                
7021                                                  
7022 static NAMED *                                   
7023 lookup(XML_Parser parser, HASH_TABLE *table,     
7024   size_t i;                                      
7025   if (table->size == 0) {                        
7026     size_t tsize;                                
7027     if (! createSize)                            
7028       return NULL;                               
7029     table->power = INIT_POWER;                   
7030     /* table->size is a power of 2 */            
7031     table->size = (size_t)1 << INIT_POWER;       
7032     tsize = table->size * sizeof(NAMED *);       
7033     table->v = table->mem->malloc_fcn(tsize);    
7034     if (! table->v) {                            
7035       table->size = 0;                           
7036       return NULL;                               
7037     }                                            
7038     memset(table->v, 0, tsize);                  
7039     i = hash(parser, name) & ((unsigned long)    
7040   } else {                                       
7041     unsigned long h = hash(parser, name);        
7042     unsigned long mask = (unsigned long)table    
7043     unsigned char step = 0;                      
7044     i = h & mask;                                
7045     while (table->v[i]) {                        
7046       if (keyeq(name, table->v[i]->name))        
7047         return table->v[i];                      
7048       if (! step)                                
7049         step = PROBE_STEP(h, mask, table->pow    
7050       i < step ? (i += table->size - step) :     
7051     }                                            
7052     if (! createSize)                            
7053       return NULL;                               
7054                                                  
7055     /* check for overflow (table is half full    
7056     if (table->used >> (table->power - 1)) {     
7057       unsigned char newPower = table->power +    
7058                                                  
7059       /* Detect and prevent invalid shift */     
7060       if (newPower >= sizeof(unsigned long) *    
7061         return NULL;                             
7062       }                                          
7063                                                  
7064       size_t newSize = (size_t)1 << newPower;    
7065       unsigned long newMask = (unsigned long)    
7066                                                  
7067       /* Detect and prevent integer overflow     
7068       if (newSize > (size_t)(-1) / sizeof(NAM    
7069         return NULL;                             
7070       }                                          
7071                                                  
7072       size_t tsize = newSize * sizeof(NAMED *    
7073       NAMED **newV = table->mem->malloc_fcn(t    
7074       if (! newV)                                
7075         return NULL;                             
7076       memset(newV, 0, tsize);                    
7077       for (i = 0; i < table->size; i++)          
7078         if (table->v[i]) {                       
7079           unsigned long newHash = hash(parser    
7080           size_t j = newHash & newMask;          
7081           step = 0;                              
7082           while (newV[j]) {                      
7083             if (! step)                          
7084               step = PROBE_STEP(newHash, newM    
7085             j < step ? (j += newSize - step)     
7086           }                                      
7087           newV[j] = table->v[i];                 
7088         }                                        
7089       table->mem->free_fcn(table->v);            
7090       table->v = newV;                           
7091       table->power = newPower;                   
7092       table->size = newSize;                     
7093       i = h & newMask;                           
7094       step = 0;                                  
7095       while (table->v[i]) {                      
7096         if (! step)                              
7097           step = PROBE_STEP(h, newMask, newPo    
7098         i < step ? (i += newSize - step) : (i    
7099       }                                          
7100     }                                            
7101   }                                              
7102   table->v[i] = table->mem->malloc_fcn(create    
7103   if (! table->v[i])                             
7104     return NULL;                                 
7105   memset(table->v[i], 0, createSize);            
7106   table->v[i]->name = name;                      
7107   (table->used)++;                               
7108   return table->v[i];                            
7109 }                                                
7110                                                  
7111 static void FASTCALL                             
7112 hashTableClear(HASH_TABLE *table) {              
7113   size_t i;                                      
7114   for (i = 0; i < table->size; i++) {            
7115     table->mem->free_fcn(table->v[i]);           
7116     table->v[i] = NULL;                          
7117   }                                              
7118   table->used = 0;                               
7119 }                                                
7120                                                  
7121 static void FASTCALL                             
7122 hashTableDestroy(HASH_TABLE *table) {            
7123   size_t i;                                      
7124   for (i = 0; i < table->size; i++)              
7125     table->mem->free_fcn(table->v[i]);           
7126   table->mem->free_fcn(table->v);                
7127 }                                                
7128                                                  
7129 static void FASTCALL                             
7130 hashTableInit(HASH_TABLE *p, const XML_Memory    
7131   p->power = 0;                                  
7132   p->size = 0;                                   
7133   p->used = 0;                                   
7134   p->v = NULL;                                   
7135   p->mem = ms;                                   
7136 }                                                
7137                                                  
7138 static void FASTCALL                             
7139 hashTableIterInit(HASH_TABLE_ITER *iter, cons    
7140   iter->p = table->v;                            
7141   iter->end = iter->p ? iter->p + table->size    
7142 }                                                
7143                                                  
7144 static NAMED *FASTCALL                           
7145 hashTableIterNext(HASH_TABLE_ITER *iter) {       
7146   while (iter->p != iter->end) {                 
7147     NAMED *tem = *(iter->p)++;                   
7148     if (tem)                                     
7149       return tem;                                
7150   }                                              
7151   return NULL;                                   
7152 }                                                
7153                                                  
7154 static void FASTCALL                             
7155 poolInit(STRING_POOL *pool, const XML_Memory_    
7156   pool->blocks = NULL;                           
7157   pool->freeBlocks = NULL;                       
7158   pool->start = NULL;                            
7159   pool->ptr = NULL;                              
7160   pool->end = NULL;                              
7161   pool->mem = ms;                                
7162 }                                                
7163                                                  
7164 static void FASTCALL                             
7165 poolClear(STRING_POOL *pool) {                   
7166   if (! pool->freeBlocks)                        
7167     pool->freeBlocks = pool->blocks;             
7168   else {                                         
7169     BLOCK *p = pool->blocks;                     
7170     while (p) {                                  
7171       BLOCK *tem = p->next;                      
7172       p->next = pool->freeBlocks;                
7173       pool->freeBlocks = p;                      
7174       p = tem;                                   
7175     }                                            
7176   }                                              
7177   pool->blocks = NULL;                           
7178   pool->start = NULL;                            
7179   pool->ptr = NULL;                              
7180   pool->end = NULL;                              
7181 }                                                
7182                                                  
7183 static void FASTCALL                             
7184 poolDestroy(STRING_POOL *pool) {                 
7185   BLOCK *p = pool->blocks;                       
7186   while (p) {                                    
7187     BLOCK *tem = p->next;                        
7188     pool->mem->free_fcn(p);                      
7189     p = tem;                                     
7190   }                                              
7191   p = pool->freeBlocks;                          
7192   while (p) {                                    
7193     BLOCK *tem = p->next;                        
7194     pool->mem->free_fcn(p);                      
7195     p = tem;                                     
7196   }                                              
7197 }                                                
7198                                                  
7199 static XML_Char *                                
7200 poolAppend(STRING_POOL *pool, const ENCODING     
7201            const char *end) {                    
7202   if (! pool->ptr && ! poolGrow(pool))           
7203     return NULL;                                 
7204   for (;;) {                                     
7205     const enum XML_Convert_Result convert_res    
7206         enc, &ptr, end, (ICHAR **)&(pool->ptr    
7207     if ((convert_res == XML_CONVERT_COMPLETED    
7208         || (convert_res == XML_CONVERT_INPUT_    
7209       break;                                     
7210     if (! poolGrow(pool))                        
7211       return NULL;                               
7212   }                                              
7213   return pool->start;                            
7214 }                                                
7215                                                  
7216 static const XML_Char *FASTCALL                  
7217 poolCopyString(STRING_POOL *pool, const XML_C    
7218   do {                                           
7219     if (! poolAppendChar(pool, *s))              
7220       return NULL;                               
7221   } while (*s++);                                
7222   s = pool->start;                               
7223   poolFinish(pool);                              
7224   return s;                                      
7225 }                                                
7226                                                  
7227 static const XML_Char *                          
7228 poolCopyStringN(STRING_POOL *pool, const XML_    
7229   if (! pool->ptr && ! poolGrow(pool)) {         
7230     /* The following line is unreachable give    
7231      * poolCopyStringN().  Currently it is ca    
7232      * place to copy the text of a simple gen    
7233      * point, the name of the entity is alrea    
7234      * pool->ptr cannot be NULL.                 
7235      *                                           
7236      * If poolCopyStringN() is used elsewhere    
7237      * this line may well become executable a    
7238      * sort of check shouldn't be removed lig    
7239      * it from the coverage statistics.          
7240      */                                          
7241     return NULL; /* LCOV_EXCL_LINE */            
7242   }                                              
7243   for (; n > 0; --n, s++) {                      
7244     if (! poolAppendChar(pool, *s))              
7245       return NULL;                               
7246   }                                              
7247   s = pool->start;                               
7248   poolFinish(pool);                              
7249   return s;                                      
7250 }                                                
7251                                                  
7252 static const XML_Char *FASTCALL                  
7253 poolAppendString(STRING_POOL *pool, const XML    
7254   while (*s) {                                   
7255     if (! poolAppendChar(pool, *s))              
7256       return NULL;                               
7257     s++;                                         
7258   }                                              
7259   return pool->start;                            
7260 }                                                
7261                                                  
7262 static XML_Char *                                
7263 poolStoreString(STRING_POOL *pool, const ENCO    
7264                 const char *end) {               
7265   if (! poolAppend(pool, enc, ptr, end))         
7266     return NULL;                                 
7267   if (pool->ptr == pool->end && ! poolGrow(po    
7268     return NULL;                                 
7269   *(pool->ptr)++ = 0;                            
7270   return pool->start;                            
7271 }                                                
7272                                                  
7273 static size_t                                    
7274 poolBytesToAllocateFor(int blockSize) {          
7275   /* Unprotected math would be:                  
7276   ** return offsetof(BLOCK, s) + blockSize *     
7277   **                                             
7278   ** Detect overflow, avoiding _signed_ overf    
7279   ** For a + b * c we check b * c in isolatio    
7280   ** on top has no chance of making us accept    
7281   */                                             
7282   const size_t stretch = sizeof(XML_Char); /*    
7283                                                  
7284   if (blockSize <= 0)                            
7285     return 0;                                    
7286                                                  
7287   if (blockSize > (int)(INT_MAX / stretch))      
7288     return 0;                                    
7289                                                  
7290   {                                              
7291     const int stretchedBlockSize = blockSize     
7292     const int bytesToAllocate                    
7293         = (int)(offsetof(BLOCK, s) + (unsigne    
7294     if (bytesToAllocate < 0)                     
7295       return 0;                                  
7296                                                  
7297     return (size_t)bytesToAllocate;              
7298   }                                              
7299 }                                                
7300                                                  
7301 static XML_Bool FASTCALL                         
7302 poolGrow(STRING_POOL *pool) {                    
7303   if (pool->freeBlocks) {                        
7304     if (pool->start == 0) {                      
7305       pool->blocks = pool->freeBlocks;           
7306       pool->freeBlocks = pool->freeBlocks->ne    
7307       pool->blocks->next = NULL;                 
7308       pool->start = pool->blocks->s;             
7309       pool->end = pool->start + pool->blocks-    
7310       pool->ptr = pool->start;                   
7311       return XML_TRUE;                           
7312     }                                            
7313     if (pool->end - pool->start < pool->freeB    
7314       BLOCK *tem = pool->freeBlocks->next;       
7315       pool->freeBlocks->next = pool->blocks;     
7316       pool->blocks = pool->freeBlocks;           
7317       pool->freeBlocks = tem;                    
7318       memcpy(pool->blocks->s, pool->start,       
7319              (pool->end - pool->start) * size    
7320       pool->ptr = pool->blocks->s + (pool->pt    
7321       pool->start = pool->blocks->s;             
7322       pool->end = pool->start + pool->blocks-    
7323       return XML_TRUE;                           
7324     }                                            
7325   }                                              
7326   if (pool->blocks && pool->start == pool->bl    
7327     BLOCK *temp;                                 
7328     int blockSize = (int)((unsigned)(pool->en    
7329     size_t bytesToAllocate;                      
7330                                                  
7331     /* NOTE: Needs to be calculated prior to     
7332              to avoid dangling pointers: */      
7333     const ptrdiff_t offsetInsideBlock = pool-    
7334                                                  
7335     if (blockSize < 0) {                         
7336       /* This condition traps a situation whe    
7337        * INT_MAX/2 bytes have already been al    
7338        * readily testable, since it is unlike    
7339        * machine will have that much memory,     
7340        * coverage statistics.                    
7341        */                                        
7342       return XML_FALSE; /* LCOV_EXCL_LINE */     
7343     }                                            
7344                                                  
7345     bytesToAllocate = poolBytesToAllocateFor(    
7346     if (bytesToAllocate == 0)                    
7347       return XML_FALSE;                          
7348                                                  
7349     temp = (BLOCK *)pool->mem->realloc_fcn(po    
7350                                            (u    
7351     if (temp == NULL)                            
7352       return XML_FALSE;                          
7353     pool->blocks = temp;                         
7354     pool->blocks->size = blockSize;              
7355     pool->ptr = pool->blocks->s + offsetInsid    
7356     pool->start = pool->blocks->s;               
7357     pool->end = pool->start + blockSize;         
7358   } else {                                       
7359     BLOCK *tem;                                  
7360     int blockSize = (int)(pool->end - pool->s    
7361     size_t bytesToAllocate;                      
7362                                                  
7363     if (blockSize < 0) {                         
7364       /* This condition traps a situation whe    
7365        * INT_MAX bytes have already been allo    
7366        * by various pieces of program logic,     
7367        * mind the unlikelihood of actually ha    
7368        * the pool control fields have been co    
7369        * conceivably happen in an extremely b    
7370        * function).  Either way it isn't read    
7371        * exclude it from the coverage statist    
7372        */                                        
7373       return XML_FALSE; /* LCOV_EXCL_LINE */     
7374     }                                            
7375                                                  
7376     if (blockSize < INIT_BLOCK_SIZE)             
7377       blockSize = INIT_BLOCK_SIZE;               
7378     else {                                       
7379       /* Detect overflow, avoiding _signed_ o    
7380       if ((int)((unsigned)blockSize * 2U) < 0    
7381         return XML_FALSE;                        
7382       }                                          
7383       blockSize *= 2;                            
7384     }                                            
7385                                                  
7386     bytesToAllocate = poolBytesToAllocateFor(    
7387     if (bytesToAllocate == 0)                    
7388       return XML_FALSE;                          
7389                                                  
7390     tem = pool->mem->malloc_fcn(bytesToAlloca    
7391     if (! tem)                                   
7392       return XML_FALSE;                          
7393     tem->size = blockSize;                       
7394     tem->next = pool->blocks;                    
7395     pool->blocks = tem;                          
7396     if (pool->ptr != pool->start)                
7397       memcpy(tem->s, pool->start, (pool->ptr     
7398     pool->ptr = tem->s + (pool->ptr - pool->s    
7399     pool->start = tem->s;                        
7400     pool->end = tem->s + blockSize;              
7401   }                                              
7402   return XML_TRUE;                               
7403 }                                                
7404                                                  
7405 static int FASTCALL                              
7406 nextScaffoldPart(XML_Parser parser) {            
7407   DTD *const dtd = parser->m_dtd; /* save one    
7408   CONTENT_SCAFFOLD *me;                          
7409   int next;                                      
7410                                                  
7411   if (! dtd->scaffIndex) {                       
7412     dtd->scaffIndex = (int *)MALLOC(parser, p    
7413     if (! dtd->scaffIndex)                       
7414       return -1;                                 
7415     dtd->scaffIndex[0] = 0;                      
7416   }                                              
7417                                                  
7418   if (dtd->scaffCount >= dtd->scaffSize) {       
7419     CONTENT_SCAFFOLD *temp;                      
7420     if (dtd->scaffold) {                         
7421       /* Detect and prevent integer overflow     
7422       if (dtd->scaffSize > UINT_MAX / 2u) {      
7423         return -1;                               
7424       }                                          
7425       /* Detect and prevent integer overflow.    
7426        * The preprocessor guard addresses the    
7427        * from -Wtype-limits on platforms wher    
7428        * sizeof(unsigned int) < sizeof(size_t    
7429 #if UINT_MAX >= SIZE_MAX                         
7430       if (dtd->scaffSize > (size_t)(-1) / 2u     
7431         return -1;                               
7432       }                                          
7433 #endif                                           
7434                                                  
7435       temp = (CONTENT_SCAFFOLD *)REALLOC(        
7436           parser, dtd->scaffold, dtd->scaffSi    
7437       if (temp == NULL)                          
7438         return -1;                               
7439       dtd->scaffSize *= 2;                       
7440     } else {                                     
7441       temp = (CONTENT_SCAFFOLD *)MALLOC(parse    
7442                                                  
7443       if (temp == NULL)                          
7444         return -1;                               
7445       dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS    
7446     }                                            
7447     dtd->scaffold = temp;                        
7448   }                                              
7449   next = dtd->scaffCount++;                      
7450   me = &dtd->scaffold[next];                     
7451   if (dtd->scaffLevel) {                         
7452     CONTENT_SCAFFOLD *parent                     
7453         = &dtd->scaffold[dtd->scaffIndex[dtd-    
7454     if (parent->lastchild) {                     
7455       dtd->scaffold[parent->lastchild].nextsi    
7456     }                                            
7457     if (! parent->childcnt)                      
7458       parent->firstchild = next;                 
7459     parent->lastchild = next;                    
7460     parent->childcnt++;                          
7461   }                                              
7462   me->firstchild = me->lastchild = me->childc    
7463   return next;                                   
7464 }                                                
7465                                                  
7466 static XML_Content *                             
7467 build_model(XML_Parser parser) {                 
7468   /* Function build_model transforms the exis    
7469    * array of CONTENT_SCAFFOLD tree nodes int    
7470    * XML_Content tree nodes followed by a gap    
7471    * strings. */                                 
7472   DTD *const dtd = parser->m_dtd; /* save one    
7473   XML_Content *ret;                              
7474   XML_Char *str; /* the current string writin    
7475                                                  
7476   /* Detect and prevent integer overflow.        
7477    * The preprocessor guard addresses the "al    
7478    * from -Wtype-limits on platforms where       
7479    * sizeof(unsigned int) < sizeof(size_t), e    
7480 #if UINT_MAX >= SIZE_MAX                         
7481   if (dtd->scaffCount > (size_t)(-1) / sizeof    
7482     return NULL;                                 
7483   }                                              
7484   if (dtd->contentStringLen > (size_t)(-1) /     
7485     return NULL;                                 
7486   }                                              
7487 #endif                                           
7488   if (dtd->scaffCount * sizeof(XML_Content)      
7489       > (size_t)(-1) - dtd->contentStringLen     
7490     return NULL;                                 
7491   }                                              
7492                                                  
7493   const size_t allocsize = (dtd->scaffCount *    
7494                             + (dtd->contentSt    
7495                                                  
7496   ret = (XML_Content *)MALLOC(parser, allocsi    
7497   if (! ret)                                     
7498     return NULL;                                 
7499                                                  
7500   /* What follows is an iterative implementat    
7501    * recursively in a dedicated function call    
7502    * build_node could be forced into stack ex    
7503    * few megabyte, and so that was a security    
7504    * stack is avoided now by resolving recurs    
7505    *                                             
7506    * The iterative approach works as follows:    
7507    *                                             
7508    * - We have two writing pointers, both wal    
7509    *   the work, the other creates "jobs" for    
7510    *   the way:                                  
7511    *                                             
7512    *   - The faster one, pointer jobDest, alw    
7513    *     to do" by the other, once they reach    
7514    *     array: leader "jobDest" stores the s    
7515    *     to array dtd->scaffold) in field "nu    
7516    *                                             
7517    *   - The slower one, pointer dest, looks     
7518    *     "numchildren" field (which actually     
7519    *     at that time) and puts the real data    
7520    *                                             
7521    * - Before the loop starts, jobDest writes    
7522    *   (where the root node is located) so th    
7523    *   when it starts operation.                 
7524    *                                             
7525    * - Whenever nodes with children are encou    
7526    *   them as new jobs, in order.  As a resu    
7527    *   adjacent in the resulting array, for e    
7528    *                                             
7529    *     [0] root, has two children              
7530    *       [1] first child of 0, has three ch    
7531    *         [3] first child of 1, does not h    
7532    *         [4] second child of 1, does not     
7533    *         [5] third child of 1, does not h    
7534    *       [2] second child of 0, does not ha    
7535    *                                             
7536    *   Or (the same data) presented in flat a    
7537    *                                             
7538    *     [0] root, has two children              
7539    *                                             
7540    *     [1] first child of 0, has three chil    
7541    *     [2] second child of 0, does not have    
7542    *                                             
7543    *     [3] first child of 1, does not have     
7544    *     [4] second child of 1, does not have    
7545    *     [5] third child of 1, does not have     
7546    *                                             
7547    * - The algorithm repeats until all target    
7548    */                                            
7549   XML_Content *dest = ret; /* tree node writi    
7550   XML_Content *const destLimit = &ret[dtd->sc    
7551   XML_Content *jobDest = ret; /* next free wr    
7552   str = (XML_Char *)&ret[dtd->scaffCount];       
7553                                                  
7554   /* Add the starting job, the root node (ind    
7555   (jobDest++)->numchildren = 0;                  
7556                                                  
7557   for (; dest < destLimit; dest++) {             
7558     /* Retrieve source tree array index from     
7559     const int src_node = (int)dest->numchildr    
7560                                                  
7561     /* Convert item */                           
7562     dest->type = dtd->scaffold[src_node].type    
7563     dest->quant = dtd->scaffold[src_node].qua    
7564     if (dest->type == XML_CTYPE_NAME) {          
7565       const XML_Char *src;                       
7566       dest->name = str;                          
7567       src = dtd->scaffold[src_node].name;        
7568       for (;;) {                                 
7569         *str++ = *src;                           
7570         if (! *src)                              
7571           break;                                 
7572         src++;                                   
7573       }                                          
7574       dest->numchildren = 0;                     
7575       dest->children = NULL;                     
7576     } else {                                     
7577       unsigned int i;                            
7578       int cn;                                    
7579       dest->name = NULL;                         
7580       dest->numchildren = dtd->scaffold[src_n    
7581       dest->children = jobDest;                  
7582                                                  
7583       /* Append scaffold indices of children     
7584       for (i = 0, cn = dtd->scaffold[src_node    
7585            i < dest->numchildren; i++, cn = d    
7586         (jobDest++)->numchildren = (unsigned     
7587     }                                            
7588   }                                              
7589                                                  
7590   return ret;                                    
7591 }                                                
7592                                                  
7593 static ELEMENT_TYPE *                            
7594 getElementType(XML_Parser parser, const ENCOD    
7595                const char *end) {                
7596   DTD *const dtd = parser->m_dtd; /* save one    
7597   const XML_Char *name = poolStoreString(&dtd    
7598   ELEMENT_TYPE *ret;                             
7599                                                  
7600   if (! name)                                    
7601     return NULL;                                 
7602   ret = (ELEMENT_TYPE *)lookup(parser, &dtd->    
7603                                sizeof(ELEMENT    
7604   if (! ret)                                     
7605     return NULL;                                 
7606   if (ret->name != name)                         
7607     poolDiscard(&dtd->pool);                     
7608   else {                                         
7609     poolFinish(&dtd->pool);                      
7610     if (! setElementTypePrefix(parser, ret))     
7611       return NULL;                               
7612   }                                              
7613   return ret;                                    
7614 }                                                
7615                                                  
7616 static XML_Char *                                
7617 copyString(const XML_Char *s, const XML_Memor    
7618   size_t charsRequired = 0;                      
7619   XML_Char *result;                              
7620                                                  
7621   /* First determine how long the string is *    
7622   while (s[charsRequired] != 0) {                
7623     charsRequired++;                             
7624   }                                              
7625   /* Include the terminator */                   
7626   charsRequired++;                               
7627                                                  
7628   /* Now allocate space for the copy */          
7629   result = memsuite->malloc_fcn(charsRequired    
7630   if (result == NULL)                            
7631     return NULL;                                 
7632   /* Copy the original into place */             
7633   memcpy(result, s, charsRequired * sizeof(XM    
7634   return result;                                 
7635 }                                                
7636                                                  
7637 #ifdef XML_DTD                                   
7638                                                  
7639 static float                                     
7640 accountingGetCurrentAmplification(XML_Parser     
7641   const XmlBigCount countBytesOutput             
7642       = rootParser->m_accounting.countBytesDi    
7643         + rootParser->m_accounting.countBytes    
7644   const float amplificationFactor                
7645       = rootParser->m_accounting.countBytesDi    
7646             ? (countBytesOutput                  
7647                / (float)(rootParser->m_accoun    
7648             : 1.0f;                              
7649   assert(! rootParser->m_parentParser);          
7650   return amplificationFactor;                    
7651 }                                                
7652                                                  
7653 static void                                      
7654 accountingReportStats(XML_Parser originParser    
7655   const XML_Parser rootParser = getRootParser    
7656   assert(! rootParser->m_parentParser);          
7657                                                  
7658   if (rootParser->m_accounting.debugLevel < 1    
7659     return;                                      
7660   }                                              
7661                                                  
7662   const float amplificationFactor                
7663       = accountingGetCurrentAmplification(roo    
7664   fprintf(stderr,                                
7665           "expat: Accounting(%p): Direct " EX    
7666               "10") ", indirect " EXPAT_FMT_U    
7667           (void *)rootParser, rootParser->m_a    
7668           rootParser->m_accounting.countBytes    
7669           (double)amplificationFactor, epilog    
7670 }                                                
7671                                                  
7672 static void                                      
7673 accountingOnAbort(XML_Parser originParser) {     
7674   accountingReportStats(originParser, " ABORT    
7675 }                                                
7676                                                  
7677 static void                                      
7678 accountingReportDiff(XML_Parser rootParser,      
7679                      unsigned int levelsAwayF    
7680                      const char *after, ptrdi    
7681                      enum XML_Account account    
7682   assert(! rootParser->m_parentParser);          
7683                                                  
7684   fprintf(stderr,                                
7685           " (+" EXPAT_FMT_PTRDIFF_T("6") " by    
7686           bytesMore, (account == XML_ACCOUNT_    
7687           levelsAwayFromRootParser, source_li    
7688                                                  
7689   const char ellipis[] = "[..]";                 
7690   const size_t ellipsisLength = sizeof(ellipi    
7691   const unsigned int contextLength = 10;         
7692                                                  
7693   /* Note: Performance is of no concern here     
7694   const char *walker = before;                   
7695   if ((rootParser->m_accounting.debugLevel >=    
7696       || (after - before)                        
7697              <= (ptrdiff_t)(contextLength + e    
7698     for (; walker < after; walker++) {           
7699       fprintf(stderr, "%s", unsignedCharToPri    
7700     }                                            
7701   } else {                                       
7702     for (; walker < before + contextLength; w    
7703       fprintf(stderr, "%s", unsignedCharToPri    
7704     }                                            
7705     fprintf(stderr, ellipis);                    
7706     walker = after - contextLength;              
7707     for (; walker < after; walker++) {           
7708       fprintf(stderr, "%s", unsignedCharToPri    
7709     }                                            
7710   }                                              
7711   fprintf(stderr, "\"\n");                       
7712 }                                                
7713                                                  
7714 static XML_Bool                                  
7715 accountingDiffTolerated(XML_Parser originPars    
7716                         const char *after, in    
7717                         enum XML_Account acco    
7718   /* Note: We need to check the token type *f    
7719    *       we can even access variable <after    
7720    *       E.g. for XML_TOK_NONE <after> may     
7721   switch (tok) {                                 
7722   case XML_TOK_INVALID:                          
7723   case XML_TOK_PARTIAL:                          
7724   case XML_TOK_PARTIAL_CHAR:                     
7725   case XML_TOK_NONE:                             
7726     return XML_TRUE;                             
7727   }                                              
7728                                                  
7729   if (account == XML_ACCOUNT_NONE)               
7730     return XML_TRUE; /* because these bytes h    
7731                                                  
7732   unsigned int levelsAwayFromRootParser;         
7733   const XML_Parser rootParser                    
7734       = getRootParserOf(originParser, &levels    
7735   assert(! rootParser->m_parentParser);          
7736                                                  
7737   const int isDirect                             
7738       = (account == XML_ACCOUNT_DIRECT) && (o    
7739   const ptrdiff_t bytesMore = after - before;    
7740                                                  
7741   XmlBigCount *const additionTarget              
7742       = isDirect ? &rootParser->m_accounting.    
7743                  : &rootParser->m_accounting.    
7744                                                  
7745   /* Detect and avoid integer overflow */        
7746   if (*additionTarget > (XmlBigCount)(-1) - (    
7747     return XML_FALSE;                            
7748   *additionTarget += bytesMore;                  
7749                                                  
7750   const XmlBigCount countBytesOutput             
7751       = rootParser->m_accounting.countBytesDi    
7752         + rootParser->m_accounting.countBytes    
7753   const float amplificationFactor                
7754       = accountingGetCurrentAmplification(roo    
7755   const XML_Bool tolerated                       
7756       = (countBytesOutput < rootParser->m_acc    
7757         || (amplificationFactor                  
7758             <= rootParser->m_accounting.maxim    
7759                                                  
7760   if (rootParser->m_accounting.debugLevel >=     
7761     accountingReportStats(rootParser, "");       
7762     accountingReportDiff(rootParser, levelsAw    
7763                          bytesMore, source_li    
7764   }                                              
7765                                                  
7766   return tolerated;                              
7767 }                                                
7768                                                  
7769 unsigned long long                               
7770 testingAccountingGetCountBytesDirect(XML_Pars    
7771   if (! parser)                                  
7772     return 0;                                    
7773   return parser->m_accounting.countBytesDirec    
7774 }                                                
7775                                                  
7776 unsigned long long                               
7777 testingAccountingGetCountBytesIndirect(XML_Pa    
7778   if (! parser)                                  
7779     return 0;                                    
7780   return parser->m_accounting.countBytesIndir    
7781 }                                                
7782                                                  
7783 static void                                      
7784 entityTrackingReportStats(XML_Parser rootPars    
7785                           const char *action,    
7786   assert(! rootParser->m_parentParser);          
7787   if (rootParser->m_entity_stats.debugLevel <    
7788     return;                                      
7789                                                  
7790 #  if defined(XML_UNICODE)                       
7791   const char *const entityName = "[..]";         
7792 #  else                                          
7793   const char *const entityName = entity->name    
7794 #  endif                                         
7795                                                  
7796   fprintf(                                       
7797       stderr,                                    
7798       "expat: Entities(%p): Count %9d, depth     
7799       (void *)rootParser, rootParser->m_entit    
7800       rootParser->m_entity_stats.currentDepth    
7801       rootParser->m_entity_stats.maximumDepth    
7802       (rootParser->m_entity_stats.currentDept    
7803       entity->is_param ? "%" : "&", entityNam    
7804       sourceLine);                               
7805 }                                                
7806                                                  
7807 static void                                      
7808 entityTrackingOnOpen(XML_Parser originParser,    
7809   const XML_Parser rootParser = getRootParser    
7810   assert(! rootParser->m_parentParser);          
7811                                                  
7812   rootParser->m_entity_stats.countEverOpened+    
7813   rootParser->m_entity_stats.currentDepth++;     
7814   if (rootParser->m_entity_stats.currentDepth    
7815       > rootParser->m_entity_stats.maximumDep    
7816     rootParser->m_entity_stats.maximumDepthSe    
7817   }                                              
7818                                                  
7819   entityTrackingReportStats(rootParser, entit    
7820 }                                                
7821                                                  
7822 static void                                      
7823 entityTrackingOnClose(XML_Parser originParser    
7824   const XML_Parser rootParser = getRootParser    
7825   assert(! rootParser->m_parentParser);          
7826                                                  
7827   entityTrackingReportStats(rootParser, entit    
7828   rootParser->m_entity_stats.currentDepth--;     
7829 }                                                
7830                                                  
7831 static XML_Parser                                
7832 getRootParserOf(XML_Parser parser, unsigned i    
7833   XML_Parser rootParser = parser;                
7834   unsigned int stepsTakenUpwards = 0;            
7835   while (rootParser->m_parentParser) {           
7836     rootParser = rootParser->m_parentParser;     
7837     stepsTakenUpwards++;                         
7838   }                                              
7839   assert(! rootParser->m_parentParser);          
7840   if (outLevelDiff != NULL) {                    
7841     *outLevelDiff = stepsTakenUpwards;           
7842   }                                              
7843   return rootParser;                             
7844 }                                                
7845                                                  
7846 const char *                                     
7847 unsignedCharToPrintable(unsigned char c) {       
7848   switch (c) {                                   
7849   case 0:                                        
7850     return "\\0";                                
7851   case 1:                                        
7852     return "\\x1";                               
7853   case 2:                                        
7854     return "\\x2";                               
7855   case 3:                                        
7856     return "\\x3";                               
7857   case 4:                                        
7858     return "\\x4";                               
7859   case 5:                                        
7860     return "\\x5";                               
7861   case 6:                                        
7862     return "\\x6";                               
7863   case 7:                                        
7864     return "\\x7";                               
7865   case 8:                                        
7866     return "\\x8";                               
7867   case 9:                                        
7868     return "\\t";                                
7869   case 10:                                       
7870     return "\\n";                                
7871   case 11:                                       
7872     return "\\xB";                               
7873   case 12:                                       
7874     return "\\xC";                               
7875   case 13:                                       
7876     return "\\r";                                
7877   case 14:                                       
7878     return "\\xE";                               
7879   case 15:                                       
7880     return "\\xF";                               
7881   case 16:                                       
7882     return "\\x10";                              
7883   case 17:                                       
7884     return "\\x11";                              
7885   case 18:                                       
7886     return "\\x12";                              
7887   case 19:                                       
7888     return "\\x13";                              
7889   case 20:                                       
7890     return "\\x14";                              
7891   case 21:                                       
7892     return "\\x15";                              
7893   case 22:                                       
7894     return "\\x16";                              
7895   case 23:                                       
7896     return "\\x17";                              
7897   case 24:                                       
7898     return "\\x18";                              
7899   case 25:                                       
7900     return "\\x19";                              
7901   case 26:                                       
7902     return "\\x1A";                              
7903   case 27:                                       
7904     return "\\x1B";                              
7905   case 28:                                       
7906     return "\\x1C";                              
7907   case 29:                                       
7908     return "\\x1D";                              
7909   case 30:                                       
7910     return "\\x1E";                              
7911   case 31:                                       
7912     return "\\x1F";                              
7913   case 32:                                       
7914     return " ";                                  
7915   case 33:                                       
7916     return "!";                                  
7917   case 34:                                       
7918     return "\\\"";                               
7919   case 35:                                       
7920     return "#";                                  
7921   case 36:                                       
7922     return "$";                                  
7923   case 37:                                       
7924     return "%";                                  
7925   case 38:                                       
7926     return "&";                                  
7927   case 39:                                       
7928     return "'";                                  
7929   case 40:                                       
7930     return "(";                                  
7931   case 41:                                       
7932     return ")";                                  
7933   case 42:                                       
7934     return "*";                                  
7935   case 43:                                       
7936     return "+";                                  
7937   case 44:                                       
7938     return ",";                                  
7939   case 45:                                       
7940     return "-";                                  
7941   case 46:                                       
7942     return ".";                                  
7943   case 47:                                       
7944     return "/";                                  
7945   case 48:                                       
7946     return "0";                                  
7947   case 49:                                       
7948     return "1";                                  
7949   case 50:                                       
7950     return "2";                                  
7951   case 51:                                       
7952     return "3";                                  
7953   case 52:                                       
7954     return "4";                                  
7955   case 53:                                       
7956     return "5";                                  
7957   case 54:                                       
7958     return "6";                                  
7959   case 55:                                       
7960     return "7";                                  
7961   case 56:                                       
7962     return "8";                                  
7963   case 57:                                       
7964     return "9";                                  
7965   case 58:                                       
7966     return ":";                                  
7967   case 59:                                       
7968     return ";";                                  
7969   case 60:                                       
7970     return "<";                                  
7971   case 61:                                       
7972     return "=";                                  
7973   case 62:                                       
7974     return ">";                                  
7975   case 63:                                       
7976     return "?";                                  
7977   case 64:                                       
7978     return "@";                                  
7979   case 65:                                       
7980     return "A";                                  
7981   case 66:                                       
7982     return "B";                                  
7983   case 67:                                       
7984     return "C";                                  
7985   case 68:                                       
7986     return "D";                                  
7987   case 69:                                       
7988     return "E";                                  
7989   case 70:                                       
7990     return "F";                                  
7991   case 71:                                       
7992     return "G";                                  
7993   case 72:                                       
7994     return "H";                                  
7995   case 73:                                       
7996     return "I";                                  
7997   case 74:                                       
7998     return "J";                                  
7999   case 75:                                       
8000     return "K";                                  
8001   case 76:                                       
8002     return "L";                                  
8003   case 77:                                       
8004     return "M";                                  
8005   case 78:                                       
8006     return "N";                                  
8007   case 79:                                       
8008     return "O";                                  
8009   case 80:                                       
8010     return "P";                                  
8011   case 81:                                       
8012     return "Q";                                  
8013   case 82:                                       
8014     return "R";                                  
8015   case 83:                                       
8016     return "S";                                  
8017   case 84:                                       
8018     return "T";                                  
8019   case 85:                                       
8020     return "U";                                  
8021   case 86:                                       
8022     return "V";                                  
8023   case 87:                                       
8024     return "W";                                  
8025   case 88:                                       
8026     return "X";                                  
8027   case 89:                                       
8028     return "Y";                                  
8029   case 90:                                       
8030     return "Z";                                  
8031   case 91:                                       
8032     return "[";                                  
8033   case 92:                                       
8034     return "\\\\";                               
8035   case 93:                                       
8036     return "]";                                  
8037   case 94:                                       
8038     return "^";                                  
8039   case 95:                                       
8040     return "_";                                  
8041   case 96:                                       
8042     return "`";                                  
8043   case 97:                                       
8044     return "a";                                  
8045   case 98:                                       
8046     return "b";                                  
8047   case 99:                                       
8048     return "c";                                  
8049   case 100:                                      
8050     return "d";                                  
8051   case 101:                                      
8052     return "e";                                  
8053   case 102:                                      
8054     return "f";                                  
8055   case 103:                                      
8056     return "g";                                  
8057   case 104:                                      
8058     return "h";                                  
8059   case 105:                                      
8060     return "i";                                  
8061   case 106:                                      
8062     return "j";                                  
8063   case 107:                                      
8064     return "k";                                  
8065   case 108:                                      
8066     return "l";                                  
8067   case 109:                                      
8068     return "m";                                  
8069   case 110:                                      
8070     return "n";                                  
8071   case 111:                                      
8072     return "o";                                  
8073   case 112:                                      
8074     return "p";                                  
8075   case 113:                                      
8076     return "q";                                  
8077   case 114:                                      
8078     return "r";                                  
8079   case 115:                                      
8080     return "s";                                  
8081   case 116:                                      
8082     return "t";                                  
8083   case 117:                                      
8084     return "u";                                  
8085   case 118:                                      
8086     return "v";                                  
8087   case 119:                                      
8088     return "w";                                  
8089   case 120:                                      
8090     return "x";                                  
8091   case 121:                                      
8092     return "y";                                  
8093   case 122:                                      
8094     return "z";                                  
8095   case 123:                                      
8096     return "{";                                  
8097   case 124:                                      
8098     return "|";                                  
8099   case 125:                                      
8100     return "}";                                  
8101   case 126:                                      
8102     return "~";                                  
8103   case 127:                                      
8104     return "\\x7F";                              
8105   case 128:                                      
8106     return "\\x80";                              
8107   case 129:                                      
8108     return "\\x81";                              
8109   case 130:                                      
8110     return "\\x82";                              
8111   case 131:                                      
8112     return "\\x83";                              
8113   case 132:                                      
8114     return "\\x84";                              
8115   case 133:                                      
8116     return "\\x85";                              
8117   case 134:                                      
8118     return "\\x86";                              
8119   case 135:                                      
8120     return "\\x87";                              
8121   case 136:                                      
8122     return "\\x88";                              
8123   case 137:                                      
8124     return "\\x89";                              
8125   case 138:                                      
8126     return "\\x8A";                              
8127   case 139:                                      
8128     return "\\x8B";                              
8129   case 140:                                      
8130     return "\\x8C";                              
8131   case 141:                                      
8132     return "\\x8D";                              
8133   case 142:                                      
8134     return "\\x8E";                              
8135   case 143:                                      
8136     return "\\x8F";                              
8137   case 144:                                      
8138     return "\\x90";                              
8139   case 145:                                      
8140     return "\\x91";                              
8141   case 146:                                      
8142     return "\\x92";                              
8143   case 147:                                      
8144     return "\\x93";                              
8145   case 148:                                      
8146     return "\\x94";                              
8147   case 149:                                      
8148     return "\\x95";                              
8149   case 150:                                      
8150     return "\\x96";                              
8151   case 151:                                      
8152     return "\\x97";                              
8153   case 152:                                      
8154     return "\\x98";                              
8155   case 153:                                      
8156     return "\\x99";                              
8157   case 154:                                      
8158     return "\\x9A";                              
8159   case 155:                                      
8160     return "\\x9B";                              
8161   case 156:                                      
8162     return "\\x9C";                              
8163   case 157:                                      
8164     return "\\x9D";                              
8165   case 158:                                      
8166     return "\\x9E";                              
8167   case 159:                                      
8168     return "\\x9F";                              
8169   case 160:                                      
8170     return "\\xA0";                              
8171   case 161:                                      
8172     return "\\xA1";                              
8173   case 162:                                      
8174     return "\\xA2";                              
8175   case 163:                                      
8176     return "\\xA3";                              
8177   case 164:                                      
8178     return "\\xA4";                              
8179   case 165:                                      
8180     return "\\xA5";                              
8181   case 166:                                      
8182     return "\\xA6";                              
8183   case 167:                                      
8184     return "\\xA7";                              
8185   case 168:                                      
8186     return "\\xA8";                              
8187   case 169:                                      
8188     return "\\xA9";                              
8189   case 170:                                      
8190     return "\\xAA";                              
8191   case 171:                                      
8192     return "\\xAB";                              
8193   case 172:                                      
8194     return "\\xAC";                              
8195   case 173:                                      
8196     return "\\xAD";                              
8197   case 174:                                      
8198     return "\\xAE";                              
8199   case 175:                                      
8200     return "\\xAF";                              
8201   case 176:                                      
8202     return "\\xB0";                              
8203   case 177:                                      
8204     return "\\xB1";                              
8205   case 178:                                      
8206     return "\\xB2";                              
8207   case 179:                                      
8208     return "\\xB3";                              
8209   case 180:                                      
8210     return "\\xB4";                              
8211   case 181:                                      
8212     return "\\xB5";                              
8213   case 182:                                      
8214     return "\\xB6";                              
8215   case 183:                                      
8216     return "\\xB7";                              
8217   case 184:                                      
8218     return "\\xB8";                              
8219   case 185:                                      
8220     return "\\xB9";                              
8221   case 186:                                      
8222     return "\\xBA";                              
8223   case 187:                                      
8224     return "\\xBB";                              
8225   case 188:                                      
8226     return "\\xBC";                              
8227   case 189:                                      
8228     return "\\xBD";                              
8229   case 190:                                      
8230     return "\\xBE";                              
8231   case 191:                                      
8232     return "\\xBF";                              
8233   case 192:                                      
8234     return "\\xC0";                              
8235   case 193:                                      
8236     return "\\xC1";                              
8237   case 194:                                      
8238     return "\\xC2";                              
8239   case 195:                                      
8240     return "\\xC3";                              
8241   case 196:                                      
8242     return "\\xC4";                              
8243   case 197:                                      
8244     return "\\xC5";                              
8245   case 198:                                      
8246     return "\\xC6";                              
8247   case 199:                                      
8248     return "\\xC7";                              
8249   case 200:                                      
8250     return "\\xC8";                              
8251   case 201:                                      
8252     return "\\xC9";                              
8253   case 202:                                      
8254     return "\\xCA";                              
8255   case 203:                                      
8256     return "\\xCB";                              
8257   case 204:                                      
8258     return "\\xCC";                              
8259   case 205:                                      
8260     return "\\xCD";                              
8261   case 206:                                      
8262     return "\\xCE";                              
8263   case 207:                                      
8264     return "\\xCF";                              
8265   case 208:                                      
8266     return "\\xD0";                              
8267   case 209:                                      
8268     return "\\xD1";                              
8269   case 210:                                      
8270     return "\\xD2";                              
8271   case 211:                                      
8272     return "\\xD3";                              
8273   case 212:                                      
8274     return "\\xD4";                              
8275   case 213:                                      
8276     return "\\xD5";                              
8277   case 214:                                      
8278     return "\\xD6";                              
8279   case 215:                                      
8280     return "\\xD7";                              
8281   case 216:                                      
8282     return "\\xD8";                              
8283   case 217:                                      
8284     return "\\xD9";                              
8285   case 218:                                      
8286     return "\\xDA";                              
8287   case 219:                                      
8288     return "\\xDB";                              
8289   case 220:                                      
8290     return "\\xDC";                              
8291   case 221:                                      
8292     return "\\xDD";                              
8293   case 222:                                      
8294     return "\\xDE";                              
8295   case 223:                                      
8296     return "\\xDF";                              
8297   case 224:                                      
8298     return "\\xE0";                              
8299   case 225:                                      
8300     return "\\xE1";                              
8301   case 226:                                      
8302     return "\\xE2";                              
8303   case 227:                                      
8304     return "\\xE3";                              
8305   case 228:                                      
8306     return "\\xE4";                              
8307   case 229:                                      
8308     return "\\xE5";                              
8309   case 230:                                      
8310     return "\\xE6";                              
8311   case 231:                                      
8312     return "\\xE7";                              
8313   case 232:                                      
8314     return "\\xE8";                              
8315   case 233:                                      
8316     return "\\xE9";                              
8317   case 234:                                      
8318     return "\\xEA";                              
8319   case 235:                                      
8320     return "\\xEB";                              
8321   case 236:                                      
8322     return "\\xEC";                              
8323   case 237:                                      
8324     return "\\xED";                              
8325   case 238:                                      
8326     return "\\xEE";                              
8327   case 239:                                      
8328     return "\\xEF";                              
8329   case 240:                                      
8330     return "\\xF0";                              
8331   case 241:                                      
8332     return "\\xF1";                              
8333   case 242:                                      
8334     return "\\xF2";                              
8335   case 243:                                      
8336     return "\\xF3";                              
8337   case 244:                                      
8338     return "\\xF4";                              
8339   case 245:                                      
8340     return "\\xF5";                              
8341   case 246:                                      
8342     return "\\xF6";                              
8343   case 247:                                      
8344     return "\\xF7";                              
8345   case 248:                                      
8346     return "\\xF8";                              
8347   case 249:                                      
8348     return "\\xF9";                              
8349   case 250:                                      
8350     return "\\xFA";                              
8351   case 251:                                      
8352     return "\\xFB";                              
8353   case 252:                                      
8354     return "\\xFC";                              
8355   case 253:                                      
8356     return "\\xFD";                              
8357   case 254:                                      
8358     return "\\xFE";                              
8359   case 255:                                      
8360     return "\\xFF";                              
8361   default:                                       
8362     assert(0); /* never gets here */             
8363     return "dead code";                          
8364   }                                              
8365   assert(0); /* never gets here */               
8366 }                                                
8367                                                  
8368 #endif /* XML_DTD */                             
8369                                                  
8370 static unsigned long                             
8371 getDebugLevel(const char *variableName, unsig    
8372   const char *const valueOrNull = getenv(vari    
8373   if (valueOrNull == NULL) {                     
8374     return defaultDebugLevel;                    
8375   }                                              
8376   const char *const value = valueOrNull;         
8377                                                  
8378   errno = 0;                                     
8379   char *afterValue = (char *)value;              
8380   unsigned long debugLevel = strtoul(value, &    
8381   if ((errno != 0) || (afterValue[0] != '\0')    
8382     errno = 0;                                   
8383     return defaultDebugLevel;                    
8384   }                                              
8385                                                  
8386   return debugLevel;                             
8387 }                                                
8388