1 /*
2 Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
3 See the file copying.txt for copying permission.
4 */
5 
6 /* In 2001, this was part of the Expat package.  We copied it into
7    Xmlrpc-c because it's easier on the user than making him get and
8    link Expat separately, and we don't expect to benefit from separate
9    maintenance of Expat.
10 
11    But we changed all the external symbols that in Expat are named
12    "XML_xxxx" to "xmlrpc_XML_xxxx" because people do link Xmlrpc-c
13    libraries into programs that also link Expat (a good example is
14    where an Apache module uses Xmlrpc-c).  We don't want our names to
15    collide with Expat's.
16 */
17 
18 #include <stddef.h>
19 #include <assert.h>
20 
21 #include "xmlrpc_config.h"
22 #include "c_util.h"
23 #include "girmath.h"
24 #include "mallocvar.h"
25 #include "xmlrpc-c/string_int.h"
26 #include "xmldef.h"
27 #include "xmlparse.h"
28 
29 static const char *
extractXmlSample(const char * const start,const char * const end,size_t const maximumLen)30 extractXmlSample(const char * const start,
31                  const char * const end,
32                  size_t       const maximumLen) {
33 
34     size_t const len = MIN(maximumLen, (size_t)(end - start));
35 
36     return xmlrpc_makePrintable_lp(start, len);
37 }
38 
39 
40 
41 #ifdef XML_UNICODE
42 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
43 #define XmlConvert XmlUtf16Convert
44 #define XmlGetInternalEncoding xmlrpc_XmlGetUtf16InternalEncoding
45 #define XmlGetInternalEncodingNS xmlrpc_XmlGetUtf16InternalEncodingNS
46 #define XmlEncode xmlrpc_XmlUtf16Encode
47 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
48 typedef unsigned short ICHAR;
49 #else
50 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
51 #define XmlConvert XmlUtf8Convert
52 #define XmlGetInternalEncoding xmlrpc_XmlGetUtf8InternalEncoding
53 #define XmlGetInternalEncodingNS xmlrpc_XmlGetUtf8InternalEncodingNS
54 #define XmlEncode xmlrpc_XmlUtf8Encode
55 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
56 typedef char ICHAR;
57 #endif
58 
59 
60 #ifndef XML_NS
61 
62 #define XmlInitEncodingNS XmlInitEncoding
63 #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
64 #undef XmlGetInternalEncodingNS
65 #define XmlGetInternalEncodingNS XmlGetInternalEncoding
66 #define XmlParseXmlDeclNS XmlParseXmlDecl
67 
68 #endif
69 
70 #ifdef XML_UNICODE_WCHAR_T
71 #define XML_T(x) L ## x
72 #else
73 #define XML_T(x) x
74 #endif
75 
76 /* Round up n to be a multiple of sz, where sz is a power of 2. */
77 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
78 
79 #include "xmltok.h"
80 #include "xmlrole.h"
81 
82 typedef const XML_Char *KEY;
83 
84 typedef struct {
85   KEY name;
86 } NAMED;
87 
88 typedef struct {
89   NAMED **v;
90   size_t size;
91   size_t used;
92   size_t usedLim;
93 } HASH_TABLE;
94 
95 typedef struct {
96   NAMED **p;
97   NAMED **end;
98 } HASH_TABLE_ITER;
99 
100 #define INIT_TAG_BUF_SIZE 32  /* must be a multiple of sizeof(XML_Char) */
101 #define INIT_DATA_BUF_SIZE 1024
102 #define INIT_ATTS_SIZE 16
103 #define INIT_BLOCK_SIZE 1024
104 #define INIT_BUFFER_SIZE 1024
105 
106 #define EXPAND_SPARE 24
107 
108 typedef struct binding {
109   struct prefix *prefix;
110   struct binding *nextTagBinding;
111   struct binding *prevPrefixBinding;
112   const struct attribute_id *attId;
113   XML_Char *uri;
114   int uriLen;
115   int uriAlloc;
116 } BINDING;
117 
118 typedef struct prefix {
119   const XML_Char *name;
120   BINDING *binding;
121 } PREFIX;
122 
123 typedef struct {
124   const XML_Char *str;
125   const XML_Char *localPart;
126   int uriLen;
127 } TAG_NAME;
128 
129 typedef struct tag {
130   struct tag *parent;
131   const char *rawName;
132   int rawNameLength;
133   TAG_NAME name;
134   char *buf;
135   char *bufEnd;
136   BINDING *bindings;
137 } TAG;
138 
139 typedef struct {
140   const XML_Char *name;
141   const XML_Char *textPtr;
142   size_t textLen;
143   const XML_Char *systemId;
144   const XML_Char *base;
145   const XML_Char *publicId;
146   const XML_Char *notation;
147   char open;
148 } ENTITY;
149 
150 typedef struct block {
151   struct block *next;
152   int size;
153   XML_Char s[1];
154 } BLOCK;
155 
156 typedef struct {
157   BLOCK *blocks;
158   BLOCK *freeBlocks;
159   const XML_Char *end;
160   XML_Char *ptr;
161   XML_Char *start;
162 } STRING_POOL;
163 
164 /* The XML_Char before the name is used to determine whether
165 an attribute has been specified. */
166 typedef struct attribute_id {
167   XML_Char *name;
168   PREFIX *prefix;
169   char maybeTokenized;
170   char xmlns;
171 } ATTRIBUTE_ID;
172 
173 typedef struct {
174   const ATTRIBUTE_ID *id;
175   char isCdata;
176   const XML_Char *value;
177 } DEFAULT_ATTRIBUTE;
178 
179 typedef struct {
180   const XML_Char *name;
181   PREFIX *prefix;
182   const ATTRIBUTE_ID *idAtt;
183   int nDefaultAtts;
184   int allocDefaultAtts;
185   DEFAULT_ATTRIBUTE *defaultAtts;
186 } ELEMENT_TYPE;
187 
188 typedef struct {
189   HASH_TABLE generalEntities;
190   HASH_TABLE elementTypes;
191   HASH_TABLE attributeIds;
192   HASH_TABLE prefixes;
193   STRING_POOL pool;
194   int complete;
195   int standalone;
196   HASH_TABLE paramEntities;
197   PREFIX defaultPrefix;
198 } DTD;
199 
200 typedef struct open_internal_entity {
201   const char *internalEventPtr;
202   const char *internalEventEndPtr;
203   struct open_internal_entity *next;
204   ENTITY *entity;
205 } OPEN_INTERNAL_ENTITY;
206 
207 typedef void Processor(XML_Parser             parser,
208                        const char *     const start,
209                        const char *     const end,
210                        const char **    const endPtr,
211                        enum XML_Error * const errorCodeP,
212                        const char **    const errorP);
213 
214 
215 #define poolStart(pool) ((pool)->start)
216 #define poolEnd(pool) ((pool)->ptr)
217 #define poolLength(pool) ((pool)->ptr - (pool)->start)
218 #define poolChop(pool) ((void)--(pool->ptr))
219 #define poolLastChar(pool) (((pool)->ptr)[-1])
220 #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
221 #define poolFinish(pool) ((pool)->start = (pool)->ptr)
222 #define poolAppendChar(pool, c) \
223   (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
224    ? 0 \
225    : ((*((pool)->ptr)++ = c), 1))
226 
227 typedef struct {
228   /* The first member must be userData so that the XML_GetUserData macro works. */
229   void *m_userData;
230   void *m_handlerArg;
231   char *m_buffer;
232   /* first character to be parsed */
233   const char *m_bufferPtr;
234   /* past last character to be parsed */
235   char *m_bufferEnd;
236   /* allocated end of buffer */
237   const char *m_bufferLim;
238   long m_parseEndByteIndex;
239   const char *m_parseEndPtr;
240   XML_Char *m_dataBuf;
241   XML_Char *m_dataBufEnd;
242   XML_StartElementHandler m_startElementHandler;
243   XML_EndElementHandler m_endElementHandler;
244   XML_CharacterDataHandler m_characterDataHandler;
245   XML_ProcessingInstructionHandler m_processingInstructionHandler;
246   XML_CommentHandler m_commentHandler;
247   XML_StartCdataSectionHandler m_startCdataSectionHandler;
248   XML_EndCdataSectionHandler m_endCdataSectionHandler;
249   XML_DefaultHandler m_defaultHandler;
250   XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
251   XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
252   XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
253   XML_NotationDeclHandler m_notationDeclHandler;
254   XML_ExternalParsedEntityDeclHandler m_externalParsedEntityDeclHandler;
255   XML_InternalParsedEntityDeclHandler m_internalParsedEntityDeclHandler;
256   XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
257   XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
258   XML_NotStandaloneHandler m_notStandaloneHandler;
259   XML_ExternalEntityRefHandler m_externalEntityRefHandler;
260   void *m_externalEntityRefHandlerArg;
261   XML_UnknownEncodingHandler m_unknownEncodingHandler;
262   const ENCODING *m_encoding;
263   INIT_ENCODING m_initEncoding;
264   const ENCODING *m_internalEncoding;
265   const XML_Char *m_protocolEncodingName;
266   int m_ns;
267   void *m_unknownEncodingMem;
268   void *m_unknownEncodingData;
269   void *m_unknownEncodingHandlerData;
270   void (*m_unknownEncodingRelease)(void *);
271   PROLOG_STATE m_prologState;
272   Processor *m_processor;
273     /* The next processor to run */
274   enum XML_Error m_errorCode;
275     /* Explanation of the failure of the most recent call to Expat.
276        XML_ERROR_NONE means it didn't fail.  This is redundant with
277        m_errorString if the latter is non-null.
278        The latter is newer and better.
279     */
280   const char * m_errorString;
281     /* malloc'ed string describing the failure of the most recent call
282        to Expat.  NULL means m_errorCode is the only error information
283        available.
284     */
285   const char *m_eventPtr;
286   const char *m_eventEndPtr;
287   const char *m_positionPtr;
288   OPEN_INTERNAL_ENTITY *m_openInternalEntities;
289   int m_defaultExpandInternalEntities;
290   int m_tagLevel;
291   ENTITY *m_declEntity;
292   const XML_Char *m_declNotationName;
293   const XML_Char *m_declNotationPublicId;
294   ELEMENT_TYPE *m_declElementType;
295   ATTRIBUTE_ID *m_declAttributeId;
296   char m_declAttributeIsCdata;
297   char m_declAttributeIsId;
298   DTD m_dtd;
299   const XML_Char *m_curBase;
300   TAG *m_tagStack;
301   TAG *m_freeTagList;
302   BINDING *m_inheritedBindings;
303   BINDING *m_freeBindingList;
304   int m_attsSize;
305   int m_nSpecifiedAtts;
306   int m_idAttIndex;
307   ATTRIBUTE *m_atts;
308   POSITION m_position;
309   STRING_POOL m_tempPool;
310   STRING_POOL m_temp2Pool;
311   char *m_groupConnector;
312   unsigned m_groupSize;
313   int m_hadExternalDoctype;
314   XML_Char m_namespaceSeparator;
315   enum XML_ParamEntityParsing m_paramEntityParsing;
316   XML_Parser m_parentParser;
317 } Parser;
318 
319 #define userData (((Parser *)parser)->m_userData)
320 #define handlerArg (((Parser *)parser)->m_handlerArg)
321 #define startElementHandler (((Parser *)parser)->m_startElementHandler)
322 #define endElementHandler (((Parser *)parser)->m_endElementHandler)
323 #define characterDataHandler (((Parser *)parser)->m_characterDataHandler)
324 #define processingInstructionHandler (((Parser *)parser)->m_processingInstructionHandler)
325 #define commentHandler (((Parser *)parser)->m_commentHandler)
326 #define startCdataSectionHandler (((Parser *)parser)->m_startCdataSectionHandler)
327 #define endCdataSectionHandler (((Parser *)parser)->m_endCdataSectionHandler)
328 #define defaultHandler (((Parser *)parser)->m_defaultHandler)
329 #define startDoctypeDeclHandler (((Parser *)parser)->m_startDoctypeDeclHandler)
330 #define endDoctypeDeclHandler (((Parser *)parser)->m_endDoctypeDeclHandler)
331 #define unparsedEntityDeclHandler (((Parser *)parser)->m_unparsedEntityDeclHandler)
332 #define notationDeclHandler (((Parser *)parser)->m_notationDeclHandler)
333 #define externalParsedEntityDeclHandler (((Parser *)parser)->m_externalParsedEntityDeclHandler)
334 #define internalParsedEntityDeclHandler (((Parser *)parser)->m_internalParsedEntityDeclHandler)
335 #define startNamespaceDeclHandler (((Parser *)parser)->m_startNamespaceDeclHandler)
336 #define endNamespaceDeclHandler (((Parser *)parser)->m_endNamespaceDeclHandler)
337 #define notStandaloneHandler (((Parser *)parser)->m_notStandaloneHandler)
338 #define externalEntityRefHandler (((Parser *)parser)->m_externalEntityRefHandler)
339 #define externalEntityRefHandlerArg (((Parser *)parser)->m_externalEntityRefHandlerArg)
340 #define unknownEncodingHandler (((Parser *)parser)->m_unknownEncodingHandler)
341 #define initEncoding (((Parser *)parser)->m_initEncoding)
342 #define internalEncoding (((Parser *)parser)->m_internalEncoding)
343 #define unknownEncodingMem (((Parser *)parser)->m_unknownEncodingMem)
344 #define unknownEncodingData (((Parser *)parser)->m_unknownEncodingData)
345 #define unknownEncodingHandlerData \
346   (((Parser *)parser)->m_unknownEncodingHandlerData)
347 #define unknownEncodingRelease (((Parser *)parser)->m_unknownEncodingRelease)
348 #define protocolEncodingName (((Parser *)parser)->m_protocolEncodingName)
349 #define ns (((Parser *)parser)->m_ns)
350 #define prologState (((Parser *)parser)->m_prologState)
351 #define processor (((Parser *)parser)->m_processor)
352 #define errorCode (((Parser *)parser)->m_errorCode)
353 #define errorString (((Parser *)parser)->m_errorString)
354 #define eventPtr (((Parser *)parser)->m_eventPtr)
355 #define eventEndPtr (((Parser *)parser)->m_eventEndPtr)
356 #define positionPtr (((Parser *)parser)->m_positionPtr)
357 #define position (((Parser *)parser)->m_position)
358 #define openInternalEntities (((Parser *)parser)->m_openInternalEntities)
359 #define defaultExpandInternalEntities (((Parser *)parser)->m_defaultExpandInternalEntities)
360 #define tagLevel (((Parser *)parser)->m_tagLevel)
361 #define buffer (((Parser *)parser)->m_buffer)
362 #define bufferPtr (((Parser *)parser)->m_bufferPtr)
363 #define bufferEnd (((Parser *)parser)->m_bufferEnd)
364 #define parseEndByteIndex (((Parser *)parser)->m_parseEndByteIndex)
365 #define parseEndPtr (((Parser *)parser)->m_parseEndPtr)
366 #define bufferLim (((Parser *)parser)->m_bufferLim)
367 #define dataBuf (((Parser *)parser)->m_dataBuf)
368 #define dataBufEnd (((Parser *)parser)->m_dataBufEnd)
369 #define dtd (((Parser *)parser)->m_dtd)
370 #define curBase (((Parser *)parser)->m_curBase)
371 #define declEntity (((Parser *)parser)->m_declEntity)
372 #define declNotationName (((Parser *)parser)->m_declNotationName)
373 #define declNotationPublicId (((Parser *)parser)->m_declNotationPublicId)
374 #define declElementType (((Parser *)parser)->m_declElementType)
375 #define declAttributeId (((Parser *)parser)->m_declAttributeId)
376 #define declAttributeIsCdata (((Parser *)parser)->m_declAttributeIsCdata)
377 #define declAttributeIsId (((Parser *)parser)->m_declAttributeIsId)
378 #define freeTagList (((Parser *)parser)->m_freeTagList)
379 #define freeBindingList (((Parser *)parser)->m_freeBindingList)
380 #define inheritedBindings (((Parser *)parser)->m_inheritedBindings)
381 #define tagStack (((Parser *)parser)->m_tagStack)
382 #define atts (((Parser *)parser)->m_atts)
383 #define attsSize (((Parser *)parser)->m_attsSize)
384 #define nSpecifiedAtts (((Parser *)parser)->m_nSpecifiedAtts)
385 #define idAttIndex (((Parser *)parser)->m_idAttIndex)
386 #define tempPool (((Parser *)parser)->m_tempPool)
387 #define temp2Pool (((Parser *)parser)->m_temp2Pool)
388 #define groupConnector (((Parser *)parser)->m_groupConnector)
389 #define groupSize (((Parser *)parser)->m_groupSize)
390 #define hadExternalDoctype (((Parser *)parser)->m_hadExternalDoctype)
391 #define namespaceSeparator (((Parser *)parser)->m_namespaceSeparator)
392 #define parentParser (((Parser *)parser)->m_parentParser)
393 #define paramEntityParsing (((Parser *)parser)->m_paramEntityParsing)
394 
395 
396 
397 static
poolInit(STRING_POOL * pool)398 void poolInit(STRING_POOL *pool)
399 {
400   pool->blocks = 0;
401   pool->freeBlocks = 0;
402   pool->start = 0;
403   pool->ptr = 0;
404   pool->end = 0;
405 }
406 
407 static
poolClear(STRING_POOL * pool)408 void poolClear(STRING_POOL *pool)
409 {
410   if (!pool->freeBlocks)
411     pool->freeBlocks = pool->blocks;
412   else {
413     BLOCK *p = pool->blocks;
414     while (p) {
415       BLOCK *tem = p->next;
416       p->next = pool->freeBlocks;
417       pool->freeBlocks = p;
418       p = tem;
419     }
420   }
421   pool->blocks = 0;
422   pool->start = 0;
423   pool->ptr = 0;
424   pool->end = 0;
425 }
426 
427 static
poolDestroy(STRING_POOL * pool)428 void poolDestroy(STRING_POOL *pool)
429 {
430   BLOCK *p = pool->blocks;
431   while (p) {
432     BLOCK *tem = p->next;
433     free(p);
434     p = tem;
435   }
436   pool->blocks = 0;
437   p = pool->freeBlocks;
438   while (p) {
439     BLOCK *tem = p->next;
440     free(p);
441     p = tem;
442   }
443   pool->freeBlocks = 0;
444   pool->ptr = 0;
445   pool->start = 0;
446   pool->end = 0;
447 }
448 
449 static
poolGrow(STRING_POOL * pool)450 int poolGrow(STRING_POOL *pool)
451 {
452   if (pool->freeBlocks) {
453     if (pool->start == 0) {
454       pool->blocks = pool->freeBlocks;
455       pool->freeBlocks = pool->freeBlocks->next;
456       pool->blocks->next = 0;
457       pool->start = pool->blocks->s;
458       pool->end = pool->start + pool->blocks->size;
459       pool->ptr = pool->start;
460       return 1;
461     }
462     if (pool->end - pool->start < pool->freeBlocks->size) {
463       BLOCK *tem = pool->freeBlocks->next;
464       pool->freeBlocks->next = pool->blocks;
465       pool->blocks = pool->freeBlocks;
466       pool->freeBlocks = tem;
467       memcpy(pool->blocks->s, pool->start,
468              (pool->end - pool->start) * sizeof(XML_Char));
469       pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
470       pool->start = pool->blocks->s;
471       pool->end = pool->start + pool->blocks->size;
472       return 1;
473     }
474   }
475   if (pool->blocks && pool->start == pool->blocks->s) {
476     size_t const blockSize = (pool->end - pool->start)*2;
477     pool->blocks = realloc(pool->blocks, offsetof(BLOCK, s) +
478                            blockSize * sizeof(XML_Char));
479     if (!pool->blocks)
480       return 0;
481     pool->blocks->size = blockSize;
482     pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
483     pool->start = pool->blocks->s;
484     pool->end = pool->start + blockSize;
485   }
486   else {
487     size_t const poolLen = pool->end - pool->start;
488     size_t const blockSize =
489         poolLen < INIT_BLOCK_SIZE ? INIT_BLOCK_SIZE : poolLen * 2;
490     BLOCK *tem;
491 
492     tem = malloc(offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
493     if (!tem)
494       return 0;
495     tem->size = blockSize;
496     tem->next = pool->blocks;
497     pool->blocks = tem;
498     if (pool->ptr != pool->start)
499       memcpy(tem->s, pool->start,
500              (pool->ptr - pool->start) * sizeof(XML_Char));
501     pool->ptr = tem->s + (pool->ptr - pool->start);
502     pool->start = tem->s;
503     pool->end = tem->s + blockSize;
504   }
505   return 1;
506 }
507 
508 
509 
510 static
poolAppend(STRING_POOL * pool,const ENCODING * enc,const char * ptr,const char * end)511 XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
512                      const char *ptr, const char *end)
513 {
514   if (!pool->ptr && !poolGrow(pool))
515     return 0;
516   for (;;) {
517     XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
518     if (ptr == end)
519       break;
520     if (!poolGrow(pool))
521       return 0;
522   }
523   return pool->start;
524 }
525 
poolCopyString(STRING_POOL * pool,const XML_Char * s)526 static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s)
527 {
528   do {
529     if (!poolAppendChar(pool, *s))
530       return 0;
531   } while (*s++);
532   s = pool->start;
533   poolFinish(pool);
534   return s;
535 }
536 
537 static const XML_Char *
poolCopyStringN(STRING_POOL * pool,const XML_Char * s,int n)538 poolCopyStringN(STRING_POOL *pool,
539                 const XML_Char *s,
540                 int n)
541 {
542   if (!pool->ptr && !poolGrow(pool))
543     return 0;
544   for (; n > 0; --n, s++) {
545     if (!poolAppendChar(pool, *s))
546       return 0;
547 
548   }
549   s = pool->start;
550   poolFinish(pool);
551   return s;
552 }
553 
554 static
poolStoreString(STRING_POOL * pool,const ENCODING * enc,const char * ptr,const char * end)555 XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
556                           const char *ptr, const char *end)
557 {
558   if (!poolAppend(pool, enc, ptr, end))
559     return 0;
560   if (pool->ptr == pool->end && !poolGrow(pool))
561     return 0;
562   *(pool->ptr)++ = 0;
563   return pool->start;
564 }
565 
566 #define INIT_SIZE 64
567 
568 static
keyeq(KEY s1,KEY s2)569 int keyeq(KEY s1, KEY s2)
570 {
571   for (; *s1 == *s2; s1++, s2++)
572     if (*s1 == 0)
573       return 1;
574   return 0;
575 }
576 
577 static
hash(KEY s)578 unsigned long hash(KEY s)
579 {
580   unsigned long h = 0;
581   while (*s)
582     h = (h << 5) + h + (unsigned char)*s++;
583   return h;
584 }
585 
586 static
lookup(HASH_TABLE * table,KEY name,size_t createSize)587 NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize)
588 {
589   size_t i;
590   if (table->size == 0) {
591     if (!createSize)
592       return 0;
593     table->v = calloc(INIT_SIZE, sizeof(NAMED *));
594     if (!table->v)
595       return 0;
596     table->size = INIT_SIZE;
597     table->usedLim = INIT_SIZE / 2;
598     i = hash(name) & (table->size - 1);
599   }
600   else {
601     unsigned long h = hash(name);
602     for (i = h & (table->size - 1);
603          table->v[i];
604          i == 0 ? i = table->size - 1 : --i) {
605       if (keyeq(name, table->v[i]->name))
606         return table->v[i];
607     }
608     if (!createSize)
609       return 0;
610     if (table->used == table->usedLim) {
611       /* check for overflow */
612       size_t newSize = table->size * 2;
613       NAMED **newV = calloc(newSize, sizeof(NAMED *));
614       if (!newV)
615         return 0;
616       for (i = 0; i < table->size; i++)
617         if (table->v[i]) {
618           size_t j;
619           for (j = hash(table->v[i]->name) & (newSize - 1);
620                newV[j];
621                j == 0 ? j = newSize - 1 : --j)
622             ;
623           newV[j] = table->v[i];
624         }
625       free(table->v);
626       table->v = newV;
627       table->size = newSize;
628       table->usedLim = newSize/2;
629       for (i = h & (table->size - 1);
630            table->v[i];
631            i == 0 ? i = table->size - 1 : --i)
632         ;
633     }
634   }
635   table->v[i] = calloc(1, createSize);
636   if (!table->v[i])
637     return 0;
638   table->v[i]->name = name;
639   (table->used)++;
640   return table->v[i];
641 }
642 
643 static
hashTableDestroy(HASH_TABLE * table)644 void hashTableDestroy(HASH_TABLE *table)
645 {
646   size_t i;
647   for (i = 0; i < table->size; i++) {
648     NAMED *p = table->v[i];
649     if (p)
650       free(p);
651   }
652   if (table->v)
653     free(table->v);
654 }
655 
656 static
hashTableInit(HASH_TABLE * p)657 void hashTableInit(HASH_TABLE *p)
658 {
659   p->size = 0;
660   p->usedLim = 0;
661   p->used = 0;
662   p->v = 0;
663 }
664 
665 static
hashTableIterInit(HASH_TABLE_ITER * iter,const HASH_TABLE * table)666 void hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
667 {
668   iter->p = table->v;
669   iter->end = iter->p + table->size;
670 }
671 
672 static
hashTableIterNext(HASH_TABLE_ITER * iter)673 NAMED *hashTableIterNext(HASH_TABLE_ITER *iter)
674 {
675   while (iter->p != iter->end) {
676     NAMED *tem = *(iter->p)++;
677     if (tem)
678       return tem;
679   }
680   return 0;
681 }
682 
683 
684 
dtdInit(DTD * p)685 static int dtdInit(DTD *p)
686 {
687   poolInit(&(p->pool));
688   hashTableInit(&(p->generalEntities));
689   hashTableInit(&(p->elementTypes));
690   hashTableInit(&(p->attributeIds));
691   hashTableInit(&(p->prefixes));
692   p->complete = 1;
693   p->standalone = 0;
694   hashTableInit(&(p->paramEntities));
695   p->defaultPrefix.name = 0;
696   p->defaultPrefix.binding = 0;
697   return 1;
698 }
699 
700 
701 
dtdSwap(DTD * p1,DTD * p2)702 static void dtdSwap(DTD *p1, DTD *p2)
703 {
704   DTD tem;
705   memcpy(&tem, p1, sizeof(DTD));
706   memcpy(p1, p2, sizeof(DTD));
707   memcpy(p2, &tem, sizeof(DTD));
708 }
709 
710 
711 
712 
dtdDestroy(DTD * p)713 static void dtdDestroy(DTD *p)
714 {
715   HASH_TABLE_ITER iter;
716   hashTableIterInit(&iter, &(p->elementTypes));
717   for (;;) {
718     ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
719     if (!e)
720       break;
721     if (e->allocDefaultAtts != 0)
722       free(e->defaultAtts);
723   }
724   hashTableDestroy(&(p->generalEntities));
725   hashTableDestroy(&(p->paramEntities));
726   hashTableDestroy(&(p->elementTypes));
727   hashTableDestroy(&(p->attributeIds));
728   hashTableDestroy(&(p->prefixes));
729   poolDestroy(&(p->pool));
730 }
731 
copyEntityTable(HASH_TABLE * newTable,STRING_POOL * newPool,const HASH_TABLE * oldTable)732 static int copyEntityTable(HASH_TABLE *newTable,
733                            STRING_POOL *newPool,
734                            const HASH_TABLE *oldTable)
735 {
736   HASH_TABLE_ITER iter;
737   const XML_Char *cachedOldBase = 0;
738   const XML_Char *cachedNewBase = 0;
739 
740   hashTableIterInit(&iter, oldTable);
741 
742   for (;;) {
743     ENTITY *newE;
744     const XML_Char *name;
745     const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
746     if (!oldE)
747       break;
748     name = poolCopyString(newPool, oldE->name);
749     if (!name)
750       return 0;
751     newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
752     if (!newE)
753       return 0;
754     if (oldE->systemId) {
755       const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
756       if (!tem)
757         return 0;
758       newE->systemId = tem;
759       if (oldE->base) {
760         if (oldE->base == cachedOldBase)
761           newE->base = cachedNewBase;
762         else {
763           cachedOldBase = oldE->base;
764           tem = poolCopyString(newPool, cachedOldBase);
765           if (!tem)
766             return 0;
767           cachedNewBase = newE->base = tem;
768         }
769       }
770     }
771     else {
772       const XML_Char *tem =
773           poolCopyStringN(newPool, oldE->textPtr, oldE->textLen);
774       if (!tem)
775         return 0;
776       newE->textPtr = tem;
777       newE->textLen = oldE->textLen;
778     }
779     if (oldE->notation) {
780       const XML_Char *tem = poolCopyString(newPool, oldE->notation);
781       if (!tem)
782         return 0;
783       newE->notation = tem;
784     }
785   }
786   return 1;
787 }
788 
789 
790 
791 /* Do a deep copy of the DTD.  Return 0 for out of memory; non-zero otherwise.
792 The new DTD has already been initialized. */
793 
dtdCopy(DTD * newDtd,const DTD * oldDtd)794 static int dtdCopy(DTD *newDtd, const DTD *oldDtd)
795 {
796   HASH_TABLE_ITER iter;
797 
798   /* Copy the prefix table. */
799 
800   hashTableIterInit(&iter, &(oldDtd->prefixes));
801   for (;;) {
802     const XML_Char *name;
803     const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
804     if (!oldP)
805       break;
806     name = poolCopyString(&(newDtd->pool), oldP->name);
807     if (!name)
808       return 0;
809     if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
810       return 0;
811   }
812 
813   hashTableIterInit(&iter, &(oldDtd->attributeIds));
814 
815   /* Copy the attribute id table. */
816 
817   for (;;) {
818     ATTRIBUTE_ID *newA;
819     const XML_Char *name;
820     const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
821 
822     if (!oldA)
823       break;
824     /* Remember to allocate the scratch byte before the name. */
825     if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
826       return 0;
827     name = poolCopyString(&(newDtd->pool), oldA->name);
828     if (!name)
829       return 0;
830     ++name;
831     newA = (ATTRIBUTE_ID *)
832         lookup(&(newDtd->attributeIds), name, sizeof(ATTRIBUTE_ID));
833     if (!newA)
834       return 0;
835     newA->maybeTokenized = oldA->maybeTokenized;
836     if (oldA->prefix) {
837       newA->xmlns = oldA->xmlns;
838       if (oldA->prefix == &oldDtd->defaultPrefix)
839         newA->prefix = &newDtd->defaultPrefix;
840       else
841         newA->prefix = (PREFIX *)
842             lookup(&(newDtd->prefixes), oldA->prefix->name, 0);
843     }
844   }
845 
846   /* Copy the element type table. */
847 
848   hashTableIterInit(&iter, &(oldDtd->elementTypes));
849 
850   for (;;) {
851     int i;
852     ELEMENT_TYPE *newE;
853     const XML_Char *name;
854     const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
855     if (!oldE)
856       break;
857     name = poolCopyString(&(newDtd->pool), oldE->name);
858     if (!name)
859       return 0;
860     newE = (ELEMENT_TYPE *)
861         lookup(&(newDtd->elementTypes), name, sizeof(ELEMENT_TYPE));
862     if (!newE)
863       return 0;
864     if (oldE->nDefaultAtts) {
865       newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
866           malloc(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
867       if (!newE->defaultAtts)
868         return 0;
869     }
870     if (oldE->idAtt)
871       newE->idAtt = (ATTRIBUTE_ID *)
872           lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
873     newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
874     if (oldE->prefix)
875       newE->prefix = (PREFIX *)
876           lookup(&(newDtd->prefixes), oldE->prefix->name, 0);
877     for (i = 0; i < newE->nDefaultAtts; i++) {
878       newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
879           lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
880       newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
881       if (oldE->defaultAtts[i].value) {
882         newE->defaultAtts[i].value =
883             poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
884         if (!newE->defaultAtts[i].value)
885           return 0;
886       }
887       else
888         newE->defaultAtts[i].value = 0;
889     }
890   }
891 
892   /* Copy the entity tables. */
893   if (!copyEntityTable(&(newDtd->generalEntities),
894                        &(newDtd->pool),
895                        &(oldDtd->generalEntities)))
896       return 0;
897 
898   if (!copyEntityTable(&(newDtd->paramEntities),
899                        &(newDtd->pool),
900                        &(oldDtd->paramEntities)))
901       return 0;
902 
903   newDtd->complete = oldDtd->complete;
904   newDtd->standalone = oldDtd->standalone;
905   return 1;
906 }
907 
908 
909 
910 static
addBinding(XML_Parser parser,PREFIX * prefix,const ATTRIBUTE_ID * attId,const XML_Char * uri,BINDING ** bindingsPtr)911 int addBinding(XML_Parser parser,
912                PREFIX *prefix,
913                const ATTRIBUTE_ID *attId,
914                const XML_Char *uri,
915                BINDING **bindingsPtr)
916 {
917   BINDING *b;
918   int len;
919   for (len = 0; uri[len]; len++)
920     ;
921   if (namespaceSeparator)
922     len++;
923   if (freeBindingList) {
924     b = freeBindingList;
925     if (len > b->uriAlloc) {
926       b->uri = realloc(b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE));
927       if (!b->uri)
928         return 0;
929       b->uriAlloc = len + EXPAND_SPARE;
930     }
931     freeBindingList = b->nextTagBinding;
932   }
933   else {
934     b = malloc(sizeof(BINDING));
935     if (!b)
936       return 0;
937     b->uri = malloc(sizeof(XML_Char) * (len + EXPAND_SPARE));
938     if (!b->uri) {
939       free(b);
940       return 0;
941     }
942     b->uriAlloc = len + EXPAND_SPARE;
943   }
944   b->uriLen = len;
945   memcpy(b->uri, uri, len * sizeof(XML_Char));
946   if (namespaceSeparator)
947     b->uri[len - 1] = namespaceSeparator;
948   b->prefix = prefix;
949   b->attId = attId;
950   b->prevPrefixBinding = prefix->binding;
951   if (*uri == XML_T('\0') && prefix == &dtd.defaultPrefix)
952     prefix->binding = 0;
953   else
954     prefix->binding = b;
955   b->nextTagBinding = *bindingsPtr;
956   *bindingsPtr = b;
957   if (startNamespaceDeclHandler)
958     startNamespaceDeclHandler(handlerArg, prefix->name,
959                               prefix->binding ? uri : 0);
960   return 1;
961 }
962 
963 
964 
965 #define CONTEXT_SEP XML_T('\f')
966 
967 static
getContext(XML_Parser parser)968 const XML_Char *getContext(XML_Parser parser)
969 {
970   HASH_TABLE_ITER iter;
971   int needSep = 0;
972 
973   if (dtd.defaultPrefix.binding) {
974     int i;
975     int len;
976     if (!poolAppendChar(&tempPool, XML_T('=')))
977       return 0;
978     len = dtd.defaultPrefix.binding->uriLen;
979     if (namespaceSeparator != XML_T('\0'))
980       len--;
981     for (i = 0; i < len; i++)
982       if (!poolAppendChar(&tempPool, dtd.defaultPrefix.binding->uri[i]))
983         return 0;
984     needSep = 1;
985   }
986 
987   hashTableIterInit(&iter, &(dtd.prefixes));
988   for (;;) {
989     int i;
990     int len;
991     const XML_Char *s;
992     PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
993     if (!prefix)
994       break;
995     if (!prefix->binding)
996       continue;
997     if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
998       return 0;
999     for (s = prefix->name; *s; s++)
1000       if (!poolAppendChar(&tempPool, *s))
1001         return 0;
1002     if (!poolAppendChar(&tempPool, XML_T('=')))
1003       return 0;
1004     len = prefix->binding->uriLen;
1005     if (namespaceSeparator != XML_T('\0'))
1006       len--;
1007     for (i = 0; i < len; i++)
1008       if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
1009         return 0;
1010     needSep = 1;
1011   }
1012 
1013 
1014   hashTableIterInit(&iter, &(dtd.generalEntities));
1015   for (;;) {
1016     const XML_Char *s;
1017     ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
1018     if (!e)
1019       break;
1020     if (!e->open)
1021       continue;
1022     if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
1023       return 0;
1024     for (s = e->name; *s; s++)
1025       if (!poolAppendChar(&tempPool, *s))
1026         return 0;
1027     needSep = 1;
1028   }
1029 
1030   if (!poolAppendChar(&tempPool, XML_T('\0')))
1031     return 0;
1032   return tempPool.start;
1033 }
1034 
1035 static
setContext(XML_Parser parser,const XML_Char * context)1036 int setContext(XML_Parser parser, const XML_Char *context)
1037 {
1038   const XML_Char *s = context;
1039 
1040   while (*context != XML_T('\0')) {
1041     if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
1042       ENTITY *e;
1043       if (!poolAppendChar(&tempPool, XML_T('\0')))
1044         return 0;
1045       e = (ENTITY *)lookup(&dtd.generalEntities, poolStart(&tempPool), 0);
1046       if (e)
1047         e->open = 1;
1048       if (*s != XML_T('\0'))
1049         s++;
1050       context = s;
1051       poolDiscard(&tempPool);
1052     }
1053     else if (*s == '=') {
1054       PREFIX *prefix;
1055       if (poolLength(&tempPool) == 0)
1056         prefix = &dtd.defaultPrefix;
1057       else {
1058         if (!poolAppendChar(&tempPool, XML_T('\0')))
1059           return 0;
1060         prefix = (PREFIX *)
1061             lookup(&dtd.prefixes, poolStart(&tempPool), sizeof(PREFIX));
1062         if (!prefix)
1063           return 0;
1064         if (prefix->name == poolStart(&tempPool)) {
1065           prefix->name = poolCopyString(&dtd.pool, prefix->name);
1066           if (!prefix->name)
1067             return 0;
1068         }
1069         poolDiscard(&tempPool);
1070       }
1071       for (context = s + 1;
1072            *context != CONTEXT_SEP && *context != XML_T('\0');
1073            ++context)
1074         if (!poolAppendChar(&tempPool, *context))
1075           return 0;
1076       if (!poolAppendChar(&tempPool, XML_T('\0')))
1077         return 0;
1078       if (!addBinding(parser, prefix, 0, poolStart(&tempPool),
1079                       &inheritedBindings))
1080         return 0;
1081       poolDiscard(&tempPool);
1082       if (*context != XML_T('\0'))
1083         ++context;
1084       s = context;
1085     }
1086     else {
1087       if (!poolAppendChar(&tempPool, *s))
1088         return 0;
1089       s++;
1090     }
1091   }
1092   return 1;
1093 }
1094 
1095 
1096 
1097 static void
normalizeLines(XML_Char * s)1098 normalizeLines(XML_Char *s)
1099 {
1100   XML_Char *p;
1101   for (;; s++) {
1102     if (*s == XML_T('\0'))
1103       return;
1104     if (*s == 0xD)
1105       break;
1106   }
1107   p = s;
1108   do {
1109     if (*s == 0xD) {
1110       *p++ = 0xA;
1111       if (*++s == 0xA)
1112         s++;
1113     }
1114     else
1115       *p++ = *s++;
1116   } while (*s);
1117   *p = XML_T('\0');
1118 }
1119 
1120 
1121 
1122 static void
reportDefault(XML_Parser const xmlParserP,const ENCODING * const enc,const char * const start,const char * const end)1123 reportDefault(XML_Parser       const xmlParserP,
1124               const ENCODING * const enc,
1125               const char *     const start,
1126               const char *     const end) {
1127 
1128     Parser * const parser = (Parser *)xmlParserP;
1129 
1130     if (MUST_CONVERT(enc, start)) {
1131         const char * s;
1132 
1133         const char **eventPP;
1134         const char **eventEndPP;
1135 
1136         if (enc == parser->m_encoding) {
1137             eventPP = &eventPtr;
1138             eventEndPP = &eventEndPtr;
1139         }
1140         else {
1141             eventPP = &(openInternalEntities->internalEventPtr);
1142             eventEndPP = &(openInternalEntities->internalEventEndPtr);
1143         }
1144         s = start;
1145         do {
1146             ICHAR *dataPtr = (ICHAR *)dataBuf;
1147             XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
1148             *eventEndPP = s;
1149             {
1150                 size_t const len = dataPtr - (ICHAR *)dataBuf;
1151                 assert((size_t)(int)len == len);   /* parser requirement */
1152                 defaultHandler(handlerArg, dataBuf, (int)len);
1153             }
1154             *eventPP = s;
1155         } while (s != end);
1156     } else {
1157         size_t const len = (XML_Char *)end - (XML_Char *)start;
1158         assert((size_t)(int)len == len);  /* parser requirement */
1159         defaultHandler(handlerArg, (XML_Char *)start, len);
1160     }
1161 }
1162 
1163 
1164 
1165 static int
reportProcessingInstruction(XML_Parser parser,const ENCODING * enc,const char * start,const char * end)1166 reportProcessingInstruction(XML_Parser parser,
1167                             const ENCODING *enc,
1168                             const char *start,
1169                             const char *end)
1170 {
1171   const XML_Char *target;
1172   XML_Char *data;
1173   const char *tem;
1174   if (!processingInstructionHandler) {
1175     if (defaultHandler)
1176       reportDefault(parser, enc, start, end);
1177     return 1;
1178   }
1179   start += enc->minBytesPerChar * 2;
1180   tem = start + XmlNameLength(enc, start);
1181   target = poolStoreString(&tempPool, enc, start, tem);
1182   if (!target)
1183     return 0;
1184   poolFinish(&tempPool);
1185   data = poolStoreString(&tempPool, enc,
1186                         XmlSkipS(enc, tem),
1187                         end - enc->minBytesPerChar*2);
1188   if (!data)
1189     return 0;
1190   normalizeLines(data);
1191   processingInstructionHandler(handlerArg, target, data);
1192   poolClear(&tempPool);
1193   return 1;
1194 }
1195 
1196 static int
reportComment(XML_Parser parser,const ENCODING * enc,const char * start,const char * end)1197 reportComment(XML_Parser parser,
1198               const ENCODING *enc,
1199               const char *start,
1200               const char *end)
1201 {
1202   XML_Char *data;
1203   if (!commentHandler) {
1204     if (defaultHandler)
1205       reportDefault(parser, enc, start, end);
1206     return 1;
1207   }
1208   data = poolStoreString(&tempPool,
1209                          enc,
1210                          start + enc->minBytesPerChar * 4,
1211                          end - enc->minBytesPerChar * 3);
1212   if (!data)
1213     return 0;
1214   normalizeLines(data);
1215   commentHandler(handlerArg, data);
1216   poolClear(&tempPool);
1217   return 1;
1218 }
1219 
1220 
1221 
1222 static enum XML_Error
handleUnknownEncoding(XML_Parser const xmlParserP,const XML_Char * const encodingName)1223 handleUnknownEncoding(XML_Parser const xmlParserP,
1224                       const XML_Char * const encodingName) {
1225 
1226     Parser * const parser = (Parser *) xmlParserP;
1227 
1228     if (unknownEncodingHandler) {
1229         XML_Encoding info;
1230         int i;
1231         for (i = 0; i < 256; i++)
1232             info.map[i] = -1;
1233         info.convert = 0;
1234         info.data = 0;
1235         info.release = 0;
1236         if (unknownEncodingHandler(unknownEncodingHandlerData,
1237                                    encodingName, &info)) {
1238             ENCODING *enc;
1239             unknownEncodingMem = malloc(xmlrpc_XmlSizeOfUnknownEncoding());
1240             if (!unknownEncodingMem) {
1241                 if (info.release)
1242                     info.release(info.data);
1243                 return XML_ERROR_NO_MEMORY;
1244             }
1245             enc = (ns
1246                    ? xmlrpc_XmlInitUnknownEncodingNS
1247                    : xmlrpc_XmlInitUnknownEncoding)(unknownEncodingMem,
1248                                              info.map,
1249                                              info.convert,
1250                                              info.data);
1251             if (enc) {
1252                 unknownEncodingData = info.data;
1253                 unknownEncodingRelease = info.release;
1254                 parser->m_encoding = enc;
1255                 return XML_ERROR_NONE;
1256             }
1257         }
1258         if (info.release)
1259             info.release(info.data);
1260     }
1261     return XML_ERROR_UNKNOWN_ENCODING;
1262 }
1263 
1264 
1265 
1266 static enum XML_Error
initializeEncoding(XML_Parser const xmlParserP)1267 initializeEncoding(XML_Parser const xmlParserP) {
1268 
1269     Parser * const parser = (Parser *) xmlParserP;
1270 
1271     const char *s;
1272 #ifdef XML_UNICODE
1273     char encodingBuf[128];
1274     if (!protocolEncodingName)
1275         s = 0;
1276     else {
1277         int i;
1278         for (i = 0; protocolEncodingName[i]; i++) {
1279             if (i == sizeof(encodingBuf) - 1
1280                 || (protocolEncodingName[i] & ~0x7f) != 0) {
1281                 encodingBuf[0] = '\0';
1282                 break;
1283             }
1284             encodingBuf[i] = (char)protocolEncodingName[i];
1285         }
1286         encodingBuf[i] = '\0';
1287         s = encodingBuf;
1288     }
1289 #else
1290     s = protocolEncodingName;
1291 #endif
1292     if ((ns ? xmlrpc_XmlInitEncodingNS : xmlrpc_XmlInitEncoding)(
1293         &parser->m_initEncoding, &parser->m_encoding, s))
1294         return XML_ERROR_NONE;
1295     return handleUnknownEncoding(xmlParserP, protocolEncodingName);
1296 }
1297 
1298 
1299 
1300 static enum XML_Error
processXmlDecl(XML_Parser const xmlParserP,int const isGeneralTextEntity,const char * const s,const char * const next)1301 processXmlDecl(XML_Parser   const xmlParserP,
1302                int          const isGeneralTextEntity,
1303                const char * const s,
1304                const char * const next) {
1305 
1306     Parser * const parser = (Parser *) xmlParserP;
1307 
1308     const char *encodingName = 0;
1309     const ENCODING *newEncoding = 0;
1310     const char *version;
1311     int standalone = -1;
1312     if (!(ns
1313           ? xmlrpc_XmlParseXmlDeclNS
1314           : xmlrpc_XmlParseXmlDecl)(isGeneralTextEntity,
1315                              parser->m_encoding,
1316                              s,
1317                              next,
1318                              &eventPtr,
1319                              &version,
1320                              &encodingName,
1321                              &newEncoding,
1322                              &standalone))
1323         return XML_ERROR_SYNTAX;
1324     if (!isGeneralTextEntity && standalone == 1) {
1325         dtd.standalone = 1;
1326         if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
1327             paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
1328     }
1329     if (defaultHandler)
1330         reportDefault(xmlParserP, parser->m_encoding, s, next);
1331     if (!protocolEncodingName) {
1332         if (newEncoding) {
1333             if (newEncoding->minBytesPerChar !=
1334                 parser->m_encoding->minBytesPerChar) {
1335                 eventPtr = encodingName;
1336                 return XML_ERROR_INCORRECT_ENCODING;
1337             }
1338             parser->m_encoding = newEncoding;
1339         }
1340         else if (encodingName) {
1341             enum XML_Error result;
1342             const XML_Char * s =
1343                 poolStoreString(&tempPool,
1344                                 parser->m_encoding,
1345                                 encodingName,
1346                                 encodingName
1347                                 + XmlNameLength(parser->m_encoding,
1348                                                 encodingName));
1349             if (!s)
1350                 return XML_ERROR_NO_MEMORY;
1351             result = handleUnknownEncoding(xmlParserP, s);
1352             poolDiscard(&tempPool);
1353             if (result == XML_ERROR_UNKNOWN_ENCODING)
1354                 eventPtr = encodingName;
1355             return result;
1356         }
1357     }
1358     return XML_ERROR_NONE;
1359 }
1360 
1361 
1362 
1363 static ATTRIBUTE_ID *
getAttributeId(XML_Parser parser,const ENCODING * enc,const char * start,const char * end)1364 getAttributeId(XML_Parser parser,
1365                const ENCODING *enc,
1366                const char *start,
1367                const char *end)
1368 {
1369   ATTRIBUTE_ID *id;
1370   const XML_Char *name;
1371   if (!poolAppendChar(&dtd.pool, XML_T('\0')))
1372     return 0;
1373   name = poolStoreString(&dtd.pool, enc, start, end);
1374   if (!name)
1375     return 0;
1376   ++name;
1377   id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, name, sizeof(ATTRIBUTE_ID));
1378   if (!id)
1379     return 0;
1380   if (id->name != name)
1381     poolDiscard(&dtd.pool);
1382   else {
1383     poolFinish(&dtd.pool);
1384     if (!ns)
1385       ;
1386     else if (name[0] == 'x'
1387         && name[1] == 'm'
1388         && name[2] == 'l'
1389         && name[3] == 'n'
1390         && name[4] == 's'
1391         && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
1392       if (name[5] == '\0')
1393         id->prefix = &dtd.defaultPrefix;
1394       else
1395         id->prefix = (PREFIX *)lookup(&dtd.prefixes, name + 6, sizeof(PREFIX));
1396       id->xmlns = 1;
1397     }
1398     else {
1399       int i;
1400       for (i = 0; name[i]; i++) {
1401         if (name[i] == XML_T(':')) {
1402           int j;
1403           for (j = 0; j < i; j++) {
1404             if (!poolAppendChar(&dtd.pool, name[j]))
1405               return 0;
1406           }
1407           if (!poolAppendChar(&dtd.pool, XML_T('\0')))
1408             return 0;
1409           id->prefix = (PREFIX *)
1410               lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX));
1411           if (id->prefix->name == poolStart(&dtd.pool))
1412             poolFinish(&dtd.pool);
1413           else
1414             poolDiscard(&dtd.pool);
1415           break;
1416         }
1417       }
1418     }
1419   }
1420   return id;
1421 }
1422 
1423 static
normalizePublicId(XML_Char * publicId)1424 void normalizePublicId(XML_Char *publicId)
1425 {
1426   XML_Char *p = publicId;
1427   XML_Char *s;
1428   for (s = publicId; *s; s++) {
1429     switch (*s) {
1430     case 0x20:
1431     case 0xD:
1432     case 0xA:
1433       if (p != publicId && p[-1] != 0x20)
1434         *p++ = 0x20;
1435       break;
1436     default:
1437       *p++ = *s;
1438     }
1439   }
1440   if (p != publicId && p[-1] == 0x20)
1441     --p;
1442   *p = XML_T('\0');
1443 }
1444 
1445 
1446 
setElementTypePrefix(XML_Parser parser,ELEMENT_TYPE * elementType)1447 static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
1448 {
1449   const XML_Char *name;
1450   for (name = elementType->name; *name; name++) {
1451     if (*name == XML_T(':')) {
1452       PREFIX *prefix;
1453       const XML_Char *s;
1454       for (s = elementType->name; s != name; s++) {
1455         if (!poolAppendChar(&dtd.pool, *s))
1456           return 0;
1457       }
1458       if (!poolAppendChar(&dtd.pool, XML_T('\0')))
1459         return 0;
1460       prefix = (PREFIX *)
1461           lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX));
1462       if (!prefix)
1463         return 0;
1464       if (prefix->name == poolStart(&dtd.pool))
1465         poolFinish(&dtd.pool);
1466       else
1467         poolDiscard(&dtd.pool);
1468       elementType->prefix = prefix;
1469 
1470     }
1471   }
1472   return 1;
1473 }
1474 
1475 
1476 
1477 static enum XML_Error
appendAttributeValue(XML_Parser const xmlParserP,const ENCODING * const enc,int const isCdata,const char * const ptrArg,const char * const end,STRING_POOL * const pool)1478 appendAttributeValue(XML_Parser       const xmlParserP,
1479                      const ENCODING * const enc,
1480                      int              const isCdata,
1481                      const char *     const ptrArg,
1482                      const char *     const end,
1483                      STRING_POOL *    const pool) {
1484 
1485   Parser * const parser = (Parser *) xmlParserP;
1486 
1487   const char * ptr;
1488 
1489   ptr = ptrArg;
1490 
1491   for (;;) {
1492     const char *next;
1493     int tok = XmlAttributeValueTok(enc, ptr, end, &next);
1494     switch (tok) {
1495     case XML_TOK_NONE:
1496       return XML_ERROR_NONE;
1497     case XML_TOK_INVALID:
1498       if (enc == parser->m_encoding)
1499         eventPtr = next;
1500       return XML_ERROR_INVALID_TOKEN;
1501     case XML_TOK_PARTIAL:
1502       if (enc == parser->m_encoding)
1503         eventPtr = ptr;
1504       return XML_ERROR_INVALID_TOKEN;
1505     case XML_TOK_CHAR_REF:
1506       {
1507         XML_Char buf[XML_ENCODE_MAX];
1508         int i;
1509         int n = XmlCharRefNumber(enc, ptr);
1510         if (n < 0) {
1511           if (enc == parser->m_encoding)
1512             eventPtr = ptr;
1513           return XML_ERROR_BAD_CHAR_REF;
1514         }
1515         if (!isCdata
1516             && n == 0x20 /* space */
1517             && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
1518           break;
1519         n = XmlEncode(n, (ICHAR *)buf);
1520         if (!n) {
1521           if (enc == parser->m_encoding)
1522             eventPtr = ptr;
1523           return XML_ERROR_BAD_CHAR_REF;
1524         }
1525         for (i = 0; i < n; i++) {
1526           if (!poolAppendChar(pool, buf[i]))
1527             return XML_ERROR_NO_MEMORY;
1528         }
1529       }
1530       break;
1531     case XML_TOK_DATA_CHARS:
1532       if (!poolAppend(pool, enc, ptr, next))
1533         return XML_ERROR_NO_MEMORY;
1534       break;
1535       break;
1536     case XML_TOK_TRAILING_CR:
1537       next = ptr + enc->minBytesPerChar;
1538       /* fall through */
1539     case XML_TOK_ATTRIBUTE_VALUE_S:
1540     case XML_TOK_DATA_NEWLINE:
1541       if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
1542         break;
1543       if (!poolAppendChar(pool, 0x20))
1544         return XML_ERROR_NO_MEMORY;
1545       break;
1546     case XML_TOK_ENTITY_REF:
1547       {
1548         const XML_Char *name;
1549         ENTITY *entity;
1550         XML_Char ch = XmlPredefinedEntityName(enc,
1551                                               ptr + enc->minBytesPerChar,
1552                                               next - enc->minBytesPerChar);
1553         if (ch) {
1554           if (!poolAppendChar(pool, ch))
1555             return XML_ERROR_NO_MEMORY;
1556           break;
1557         }
1558         name = poolStoreString(&temp2Pool, enc,
1559                                ptr + enc->minBytesPerChar,
1560                                next - enc->minBytesPerChar);
1561         if (!name)
1562           return XML_ERROR_NO_MEMORY;
1563         entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
1564         poolDiscard(&temp2Pool);
1565         if (!entity) {
1566           if (dtd.complete) {
1567             if (enc == parser->m_encoding)
1568               eventPtr = ptr;
1569             return XML_ERROR_UNDEFINED_ENTITY;
1570           }
1571         }
1572         else if (entity->open) {
1573           if (enc == parser->m_encoding)
1574             eventPtr = ptr;
1575           return XML_ERROR_RECURSIVE_ENTITY_REF;
1576         }
1577         else if (entity->notation) {
1578           if (enc == parser->m_encoding)
1579             eventPtr = ptr;
1580           return XML_ERROR_BINARY_ENTITY_REF;
1581         }
1582         else if (!entity->textPtr) {
1583           if (enc == parser->m_encoding)
1584             eventPtr = ptr;
1585           return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
1586         }
1587         else {
1588           enum XML_Error result;
1589           const XML_Char *textEnd = entity->textPtr + entity->textLen;
1590           entity->open = 1;
1591           result = appendAttributeValue(xmlParserP, internalEncoding,
1592                                         isCdata, (char *)entity->textPtr,
1593                                         (char *)textEnd, pool);
1594           entity->open = 0;
1595           if (result)
1596             return result;
1597         }
1598       }
1599       break;
1600     default:
1601       abort();
1602     }
1603     ptr = next;
1604   }
1605   /* not reached */
1606 }
1607 
1608 
1609 
1610 static enum XML_Error
storeAttributeValue(XML_Parser parser,const ENCODING * enc,int isCdata,const char * ptr,const char * end,STRING_POOL * pool)1611 storeAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
1612                     const char *ptr, const char *end,
1613                     STRING_POOL *pool)
1614 {
1615   enum XML_Error result =
1616       appendAttributeValue(parser, enc, isCdata, ptr, end, pool);
1617   if (result)
1618     return result;
1619   if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
1620     poolChop(pool);
1621   if (!poolAppendChar(pool, XML_T('\0')))
1622     return XML_ERROR_NO_MEMORY;
1623   return XML_ERROR_NONE;
1624 }
1625 
1626 
1627 
1628 static
1629 enum XML_Error
storeEntityValue(XML_Parser const xmlParserP,const ENCODING * const enc,const char * const entityTextPtrArg,const char * const entityTextEnd)1630 storeEntityValue(XML_Parser       const xmlParserP,
1631                  const ENCODING * const enc,
1632                  const char *     const entityTextPtrArg,
1633                  const char *     const entityTextEnd) {
1634 
1635   Parser * const parser = (Parser *) xmlParserP;
1636 
1637   STRING_POOL * const pool = &(dtd.pool);
1638   const char * entityTextPtr;
1639 
1640   entityTextPtr = entityTextPtrArg;
1641 
1642   for (;;) {
1643     const char * next;
1644     int tok;
1645 
1646     tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
1647     switch (tok) {
1648     case XML_TOK_PARAM_ENTITY_REF:
1649       if (parentParser || enc != parser->m_encoding) {
1650         enum XML_Error result;
1651         const XML_Char *name;
1652         ENTITY *entity;
1653         name = poolStoreString(&tempPool, enc,
1654                                entityTextPtr + enc->minBytesPerChar,
1655                                next - enc->minBytesPerChar);
1656         if (!name)
1657           return XML_ERROR_NO_MEMORY;
1658         entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0);
1659         poolDiscard(&tempPool);
1660         if (!entity) {
1661           if (enc == parser->m_encoding)
1662             eventPtr = entityTextPtr;
1663           return XML_ERROR_UNDEFINED_ENTITY;
1664         }
1665         if (entity->open) {
1666           if (enc == parser->m_encoding)
1667             eventPtr = entityTextPtr;
1668           return XML_ERROR_RECURSIVE_ENTITY_REF;
1669         }
1670         if (entity->systemId) {
1671           if (enc == parser->m_encoding)
1672             eventPtr = entityTextPtr;
1673           return XML_ERROR_PARAM_ENTITY_REF;
1674         }
1675         entity->open = 1;
1676         result = storeEntityValue(parser,
1677                                   internalEncoding,
1678                                   (char *)entity->textPtr,
1679                                   (char *)(entity->textPtr + entity->textLen));
1680         entity->open = 0;
1681         if (result)
1682           return result;
1683         break;
1684       }
1685       eventPtr = entityTextPtr;
1686       return XML_ERROR_SYNTAX;
1687     case XML_TOK_NONE:
1688       return XML_ERROR_NONE;
1689     case XML_TOK_ENTITY_REF:
1690     case XML_TOK_DATA_CHARS:
1691       if (!poolAppend(pool, enc, entityTextPtr, next))
1692         return XML_ERROR_NO_MEMORY;
1693       break;
1694     case XML_TOK_TRAILING_CR:
1695       next = entityTextPtr + enc->minBytesPerChar;
1696       /* fall through */
1697     case XML_TOK_DATA_NEWLINE:
1698       if (pool->end == pool->ptr && !poolGrow(pool))
1699         return XML_ERROR_NO_MEMORY;
1700       *(pool->ptr)++ = 0xA;
1701       break;
1702     case XML_TOK_CHAR_REF:
1703       {
1704         XML_Char buf[XML_ENCODE_MAX];
1705         int i;
1706         int n = XmlCharRefNumber(enc, entityTextPtr);
1707         if (n < 0) {
1708           if (enc == parser->m_encoding)
1709             eventPtr = entityTextPtr;
1710           return XML_ERROR_BAD_CHAR_REF;
1711         }
1712         n = XmlEncode(n, (ICHAR *)buf);
1713         if (!n) {
1714           if (enc == parser->m_encoding)
1715             eventPtr = entityTextPtr;
1716           return XML_ERROR_BAD_CHAR_REF;
1717         }
1718         for (i = 0; i < n; i++) {
1719           if (pool->end == pool->ptr && !poolGrow(pool))
1720             return XML_ERROR_NO_MEMORY;
1721           *(pool->ptr)++ = buf[i];
1722         }
1723       }
1724       break;
1725     case XML_TOK_PARTIAL:
1726       if (enc == parser->m_encoding)
1727         eventPtr = entityTextPtr;
1728       return XML_ERROR_INVALID_TOKEN;
1729     case XML_TOK_INVALID:
1730       if (enc == parser->m_encoding)
1731         eventPtr = next;
1732       return XML_ERROR_INVALID_TOKEN;
1733     default:
1734       abort();
1735     }
1736     entityTextPtr = next;
1737   }
1738   /* not reached */
1739 }
1740 
1741 
1742 
1743 static int
defineAttribute(ELEMENT_TYPE * type,ATTRIBUTE_ID * attId,int isCdata,int isId,const XML_Char * value)1744 defineAttribute(ELEMENT_TYPE *type,
1745                 ATTRIBUTE_ID *attId,
1746                 int isCdata,
1747                 int isId,
1748                 const XML_Char *value)
1749 {
1750   DEFAULT_ATTRIBUTE *att;
1751   if (value || isId) {
1752     /* The handling of default attributes gets messed up if we have
1753        a default which duplicates a non-default. */
1754     int i;
1755     for (i = 0; i < type->nDefaultAtts; i++)
1756       if (attId == type->defaultAtts[i].id)
1757         return 1;
1758     if (isId && !type->idAtt && !attId->xmlns)
1759       type->idAtt = attId;
1760   }
1761   if (type->nDefaultAtts == type->allocDefaultAtts) {
1762     if (type->allocDefaultAtts == 0) {
1763       type->allocDefaultAtts = 8;
1764       type->defaultAtts =
1765           malloc(type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
1766     }
1767     else {
1768       type->allocDefaultAtts *= 2;
1769       type->defaultAtts =
1770           realloc(type->defaultAtts,
1771                   type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
1772     }
1773     if (!type->defaultAtts)
1774       return 0;
1775   }
1776   att = type->defaultAtts + type->nDefaultAtts;
1777   att->id = attId;
1778   att->value = value;
1779   att->isCdata = isCdata;
1780   if (!isCdata)
1781     attId->maybeTokenized = 1;
1782   type->nDefaultAtts += 1;
1783   return 1;
1784 }
1785 
1786 
1787 
1788 /* If tagNamePtr is non-null, build a real list of attributes,
1789 otherwise just check the attributes for well-formedness. */
1790 
1791 static enum XML_Error
storeAtts(XML_Parser const xmlParserP,const ENCODING * const enc,const char * const attStr,TAG_NAME * const tagNamePtr,BINDING ** const bindingsPtr)1792 storeAtts(XML_Parser       const xmlParserP,
1793           const ENCODING * const enc,
1794           const char *     const attStr,
1795           TAG_NAME *       const tagNamePtr,
1796           BINDING **       const bindingsPtr) {
1797 
1798   Parser * const parser = (Parser *)xmlParserP;
1799 
1800   ELEMENT_TYPE *elementType = 0;
1801   int nDefaultAtts = 0;
1802   const XML_Char ** appAtts;
1803       /* the attribute list to pass to the application */
1804   int attIndex = 0;
1805   int i;
1806   int n;
1807   int nPrefixes = 0;
1808   BINDING *binding;
1809   const XML_Char *localPart;
1810 
1811   /* lookup the element type name */
1812   if (tagNamePtr) {
1813     elementType = (ELEMENT_TYPE *)
1814         lookup(&dtd.elementTypes, tagNamePtr->str, 0);
1815     if (!elementType) {
1816       tagNamePtr->str = poolCopyString(&dtd.pool, tagNamePtr->str);
1817       if (!tagNamePtr->str)
1818         return XML_ERROR_NO_MEMORY;
1819       elementType = (ELEMENT_TYPE *)
1820           lookup(&dtd.elementTypes, tagNamePtr->str, sizeof(ELEMENT_TYPE));
1821       if (!elementType)
1822         return XML_ERROR_NO_MEMORY;
1823       if (ns && !setElementTypePrefix(xmlParserP, elementType))
1824         return XML_ERROR_NO_MEMORY;
1825     }
1826     nDefaultAtts = elementType->nDefaultAtts;
1827   }
1828   /* get the attributes from the tokenizer */
1829   n = XmlGetAttributes(enc, attStr, attsSize, atts);
1830   if (n + nDefaultAtts > attsSize) {
1831     int oldAttsSize = attsSize;
1832     attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
1833     atts = realloc((void *)atts, attsSize * sizeof(ATTRIBUTE));
1834     if (!atts)
1835       return XML_ERROR_NO_MEMORY;
1836     if (n > oldAttsSize)
1837       XmlGetAttributes(enc, attStr, n, atts);
1838   }
1839   appAtts = (const XML_Char **)atts;
1840   for (i = 0; i < n; i++) {
1841     /* add the name and value to the attribute list */
1842     ATTRIBUTE_ID *attId = getAttributeId(xmlParserP, enc, atts[i].name,
1843                                          atts[i].name
1844                                          + XmlNameLength(enc, atts[i].name));
1845     if (!attId)
1846       return XML_ERROR_NO_MEMORY;
1847     /* detect duplicate attributes */
1848     if ((attId->name)[-1]) {
1849       if (enc == parser->m_encoding)
1850         eventPtr = atts[i].name;
1851       return XML_ERROR_DUPLICATE_ATTRIBUTE;
1852     }
1853     (attId->name)[-1] = 1;
1854     appAtts[attIndex++] = attId->name;
1855     if (!atts[i].normalized) {
1856       enum XML_Error result;
1857       int isCdata = 1;
1858 
1859       /* figure out whether declared as other than CDATA */
1860       if (attId->maybeTokenized) {
1861         int j;
1862         for (j = 0; j < nDefaultAtts; j++) {
1863           if (attId == elementType->defaultAtts[j].id) {
1864             isCdata = elementType->defaultAtts[j].isCdata;
1865             break;
1866           }
1867         }
1868       }
1869 
1870       /* normalize the attribute value */
1871       result = storeAttributeValue(xmlParserP, enc, isCdata,
1872                                    atts[i].valuePtr, atts[i].valueEnd,
1873                                    &tempPool);
1874       if (result)
1875         return result;
1876       if (tagNamePtr) {
1877         appAtts[attIndex] = poolStart(&tempPool);
1878         poolFinish(&tempPool);
1879       }
1880       else
1881         poolDiscard(&tempPool);
1882     }
1883     else if (tagNamePtr) {
1884       /* the value did not need normalizing */
1885       appAtts[attIndex] =
1886           poolStoreString(&tempPool, enc, atts[i].valuePtr, atts[i].valueEnd);
1887       if (appAtts[attIndex] == 0)
1888         return XML_ERROR_NO_MEMORY;
1889       poolFinish(&tempPool);
1890     }
1891     /* handle prefixed attribute names */
1892     if (attId->prefix && tagNamePtr) {
1893       if (attId->xmlns) {
1894         /* deal with namespace declarations here */
1895         if (!addBinding(xmlParserP, attId->prefix, attId, appAtts[attIndex],
1896                         bindingsPtr))
1897           return XML_ERROR_NO_MEMORY;
1898         --attIndex;
1899       }
1900       else {
1901         /* deal with other prefixed names later */
1902         attIndex++;
1903         nPrefixes++;
1904         (attId->name)[-1] = 2;
1905       }
1906     }
1907     else
1908       attIndex++;
1909   }
1910   if (tagNamePtr) {
1911     int j;
1912     nSpecifiedAtts = attIndex;
1913     if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
1914       for (i = 0; i < attIndex; i += 2)
1915         if (appAtts[i] == elementType->idAtt->name) {
1916           idAttIndex = i;
1917           break;
1918         }
1919     }
1920     else
1921       idAttIndex = -1;
1922     /* do attribute defaulting */
1923     for (j = 0; j < nDefaultAtts; j++) {
1924       const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j;
1925       if (!(da->id->name)[-1] && da->value) {
1926         if (da->id->prefix) {
1927           if (da->id->xmlns) {
1928             if (!addBinding(xmlParserP, da->id->prefix, da->id, da->value,
1929                             bindingsPtr))
1930               return XML_ERROR_NO_MEMORY;
1931           }
1932           else {
1933             (da->id->name)[-1] = 2;
1934             nPrefixes++;
1935             appAtts[attIndex++] = da->id->name;
1936             appAtts[attIndex++] = da->value;
1937           }
1938         }
1939         else {
1940           (da->id->name)[-1] = 1;
1941           appAtts[attIndex++] = da->id->name;
1942           appAtts[attIndex++] = da->value;
1943         }
1944       }
1945     }
1946     appAtts[attIndex] = 0;
1947   }
1948   i = 0;
1949   if (nPrefixes) {
1950     /* expand prefixed attribute names */
1951     for (; i < attIndex; i += 2) {
1952       if (appAtts[i][-1] == 2) {
1953         ATTRIBUTE_ID *id;
1954         ((XML_Char *)(appAtts[i]))[-1] = 0;
1955         id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, appAtts[i], 0);
1956         if (id->prefix->binding) {
1957           int j;
1958           const BINDING *b = id->prefix->binding;
1959           const XML_Char *s = appAtts[i];
1960           for (j = 0; j < b->uriLen; j++) {
1961             if (!poolAppendChar(&tempPool, b->uri[j]))
1962               return XML_ERROR_NO_MEMORY;
1963           }
1964           while (*s++ != ':')
1965             ;
1966           do {
1967             if (!poolAppendChar(&tempPool, *s))
1968               return XML_ERROR_NO_MEMORY;
1969           } while (*s++);
1970           appAtts[i] = poolStart(&tempPool);
1971           poolFinish(&tempPool);
1972         }
1973         if (!--nPrefixes)
1974           break;
1975       }
1976       else
1977         ((XML_Char *)(appAtts[i]))[-1] = 0;
1978     }
1979   }
1980   /* clear the flags that say whether attributes were specified */
1981   for (; i < attIndex; i += 2)
1982     ((XML_Char *)(appAtts[i]))[-1] = 0;
1983   if (!tagNamePtr)
1984     return XML_ERROR_NONE;
1985   for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
1986     binding->attId->name[-1] = 0;
1987   /* expand the element type name */
1988   if (elementType->prefix) {
1989     binding = elementType->prefix->binding;
1990     if (!binding)
1991       return XML_ERROR_NONE;
1992     localPart = tagNamePtr->str;
1993     while (*localPart++ != XML_T(':'))
1994       ;
1995   }
1996   else if (dtd.defaultPrefix.binding) {
1997     binding = dtd.defaultPrefix.binding;
1998     localPart = tagNamePtr->str;
1999   }
2000   else
2001     return XML_ERROR_NONE;
2002   tagNamePtr->localPart = localPart;
2003   tagNamePtr->uriLen = binding->uriLen;
2004   for (i = 0; localPart[i++];)
2005     ;
2006   n = i + binding->uriLen;
2007   if (n > binding->uriAlloc) {
2008     TAG *p;
2009     XML_Char *uri = malloc((n + EXPAND_SPARE) * sizeof(XML_Char));
2010     if (!uri)
2011       return XML_ERROR_NO_MEMORY;
2012     binding->uriAlloc = n + EXPAND_SPARE;
2013     memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
2014     for (p = tagStack; p; p = p->parent)
2015       if (p->name.str == binding->uri)
2016         p->name.str = uri;
2017     free(binding->uri);
2018     binding->uri = uri;
2019   }
2020   memcpy(binding->uri + binding->uriLen, localPart, i * sizeof(XML_Char));
2021   tagNamePtr->str = binding->uri;
2022   return XML_ERROR_NONE;
2023 }
2024 
2025 
2026 
2027 static Processor epilogProcessor;
2028 
2029 static void
epilogProcessor(XML_Parser const xmlParserP,const char * const startArg,const char * const end,const char ** const nextPtr,enum XML_Error * const errorCodeP,const char ** const errorP)2030 epilogProcessor(XML_Parser       const xmlParserP,
2031                 const char *     const startArg,
2032                 const char *     const end,
2033                 const char **    const nextPtr,
2034                 enum XML_Error * const errorCodeP,
2035                 const char **    const errorP) {
2036 
2037     Parser * const parser = (Parser *) xmlParserP;
2038 
2039     const char * s;
2040 
2041     *errorP = NULL;
2042 
2043     s = startArg;
2044 
2045     processor = epilogProcessor;
2046     eventPtr = s;
2047     for (;;) {
2048         const char *next;
2049         int tok = XmlPrologTok(parser->m_encoding, s, end, &next);
2050         eventEndPtr = next;
2051         switch (tok) {
2052         case -XML_TOK_PROLOG_S:
2053             if (defaultHandler) {
2054                 eventEndPtr = end;
2055                 reportDefault(xmlParserP, parser->m_encoding, s, end);
2056             }
2057             /* fall through */
2058         case XML_TOK_NONE:
2059             if (nextPtr)
2060                 *nextPtr = end;
2061             *errorCodeP = XML_ERROR_NONE;
2062             return;
2063         case XML_TOK_PROLOG_S:
2064             if (defaultHandler)
2065                 reportDefault(xmlParserP, parser->m_encoding, s, next);
2066             break;
2067         case XML_TOK_PI:
2068             if (!reportProcessingInstruction(xmlParserP, parser->m_encoding,
2069                                              s, next)) {
2070                 *errorCodeP = XML_ERROR_NO_MEMORY;
2071                 return;
2072             }
2073             break;
2074         case XML_TOK_COMMENT:
2075             if (!reportComment(xmlParserP, parser->m_encoding, s, next)) {
2076                 *errorCodeP = XML_ERROR_NO_MEMORY;
2077                 return;
2078             }
2079             break;
2080         case XML_TOK_INVALID:
2081             eventPtr = next;
2082             *errorCodeP = XML_ERROR_INVALID_TOKEN;
2083             return;
2084         case XML_TOK_PARTIAL:
2085             if (nextPtr) {
2086                 *nextPtr = s;
2087                 *errorCodeP = XML_ERROR_NONE;
2088             } else
2089                 *errorCodeP = XML_ERROR_UNCLOSED_TOKEN;
2090             return;
2091         case XML_TOK_PARTIAL_CHAR:
2092             if (nextPtr) {
2093                 *nextPtr = s;
2094                 *errorCodeP = XML_ERROR_NONE;
2095             } else
2096                 *errorCodeP = XML_ERROR_PARTIAL_CHAR;
2097             return;
2098         default:
2099             *errorCodeP = XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
2100             return;
2101         }
2102         eventPtr = s = next;
2103     }
2104 }
2105 
2106 
2107 
2108 static enum XML_Error
doCdataSection(XML_Parser const xmlParserP,const ENCODING * const enc,const char ** const startPtr,const char * const end,const char ** const nextPtr)2109 doCdataSection(XML_Parser       const xmlParserP,
2110                const ENCODING * const enc,
2111                const char **    const startPtr,
2112                const char *     const end,
2113                const char **    const nextPtr) {
2114 
2115   Parser * const parser = (Parser *) xmlParserP;
2116 
2117   const char *s = *startPtr;
2118   const char **eventPP;
2119   const char **eventEndPP;
2120   if (enc == parser->m_encoding) {
2121     eventPP = &eventPtr;
2122     *eventPP = s;
2123     eventEndPP = &eventEndPtr;
2124   }
2125   else {
2126     eventPP = &(openInternalEntities->internalEventPtr);
2127     eventEndPP = &(openInternalEntities->internalEventEndPtr);
2128   }
2129   *eventPP = s;
2130   *startPtr = 0;
2131   for (;;) {
2132     const char *next;
2133     int tok = XmlCdataSectionTok(enc, s, end, &next);
2134     *eventEndPP = next;
2135     switch (tok) {
2136     case XML_TOK_CDATA_SECT_CLOSE:
2137       if (endCdataSectionHandler)
2138         endCdataSectionHandler(handlerArg);
2139       else if (defaultHandler)
2140         reportDefault(xmlParserP, enc, s, next);
2141       *startPtr = next;
2142       return XML_ERROR_NONE;
2143     case XML_TOK_DATA_NEWLINE:
2144       if (characterDataHandler) {
2145         XML_Char c = 0xA;
2146         characterDataHandler(handlerArg, &c, 1);
2147       }
2148       else if (defaultHandler)
2149         reportDefault(xmlParserP, enc, s, next);
2150       break;
2151     case XML_TOK_DATA_CHARS:
2152       if (characterDataHandler) {
2153         if (MUST_CONVERT(enc, s)) {
2154           for (;;) {
2155             ICHAR *dataPtr = (ICHAR *)dataBuf;
2156             XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
2157             *eventEndPP = next;
2158             {
2159                 size_t const len = dataPtr - (ICHAR *)dataBuf;
2160                 assert((size_t)(int)len == len);   /* parser requirement */
2161                 characterDataHandler(handlerArg, dataBuf, (int)len);
2162             }
2163             if (s == next)
2164               break;
2165             *eventPP = s;
2166           }
2167         }
2168         else {
2169             size_t const len = (XML_Char *)next - (XML_Char *)s;
2170             assert((size_t)(int)len == len);   /* parser requirement */
2171             characterDataHandler(handlerArg, (XML_Char *)s, (int)len);
2172         }
2173       }
2174       else if (defaultHandler)
2175         reportDefault(xmlParserP, enc, s, next);
2176       break;
2177     case XML_TOK_INVALID:
2178       *eventPP = next;
2179       return XML_ERROR_INVALID_TOKEN;
2180     case XML_TOK_PARTIAL_CHAR:
2181       if (nextPtr) {
2182         *nextPtr = s;
2183         return XML_ERROR_NONE;
2184       }
2185       return XML_ERROR_PARTIAL_CHAR;
2186     case XML_TOK_PARTIAL:
2187     case XML_TOK_NONE:
2188       if (nextPtr) {
2189         *nextPtr = s;
2190         return XML_ERROR_NONE;
2191       }
2192       return XML_ERROR_UNCLOSED_CDATA_SECTION;
2193     default:
2194       abort();
2195     }
2196     *eventPP = s = next;
2197   }
2198   /* not reached */
2199 }
2200 
2201 
2202 
2203 /* Forward declaration for recursive reference: */
2204 static void
2205 doContent(XML_Parser       const xmlParserP,
2206           int              const startTagLevel,
2207           const ENCODING * const enc,
2208           const char *     const startArg,
2209           const char *     const end,
2210           const char **    const nextPtr,
2211           enum XML_Error * const errorCodeP,
2212           const char **    const errorP);
2213 
2214 
2215 static Processor contentProcessor;
2216 
2217 static void
contentProcessor(XML_Parser const xmlParserP,const char * const start,const char * const end,const char ** const endPtr,enum XML_Error * const errorCodeP,const char ** const errorP)2218 contentProcessor(XML_Parser       const xmlParserP,
2219                  const char *     const start,
2220                  const char *     const end,
2221                  const char **    const endPtr,
2222                  enum XML_Error * const errorCodeP,
2223                  const char **    const errorP) {
2224 
2225     Parser * const parser = (Parser *) xmlParserP;
2226 
2227     const char * error;
2228 
2229     parser->m_errorString = NULL;
2230 
2231     doContent(xmlParserP, 0, parser->m_encoding, start, end, endPtr,
2232               errorCodeP, &error);
2233 
2234     if (*errorCodeP != XML_ERROR_NONE) {
2235         if (error) {
2236             xmlrpc_asprintf(errorP, "Invalid XML \"content\".  %s", error);
2237 
2238             xmlrpc_strfree(error);
2239         } else {
2240             const char * const sampleXml = extractXmlSample(start, end, 40);
2241 
2242             xmlrpc_asprintf(errorP, "Invalid XML \"content\" starting "
2243                             "with '%s'.  %s",
2244                             sampleXml,
2245                             xmlrpc_XML_ErrorString(*errorCodeP));
2246 
2247             xmlrpc_strfree(sampleXml);
2248         }
2249     } else
2250         *errorP = NULL;
2251 }
2252 
2253 
2254 
2255 /* The idea here is to avoid using stack for each CDATA section when
2256 the whole file is parsed with one call. */
2257 
2258 
2259 
2260 static Processor cdataSectionProcessor;
2261 
2262 static void
cdataSectionProcessor(XML_Parser const xmlParserP,const char * const startArg,const char * const end,const char ** const endPtr,enum XML_Error * const errorCodeP,const char ** const errorP)2263 cdataSectionProcessor(XML_Parser       const xmlParserP,
2264                       const char *     const startArg,
2265                       const char *     const end,
2266                       const char **    const endPtr,
2267                       enum XML_Error * const errorCodeP,
2268                       const char **    const errorP) {
2269 
2270     Parser * const parser = (Parser *) xmlParserP;
2271 
2272     enum XML_Error result;
2273     const char * start;
2274 
2275     start = startArg;
2276 
2277     result =
2278         doCdataSection(xmlParserP, parser->m_encoding, &start, end, endPtr);
2279 
2280     if (start) {
2281         processor = contentProcessor;
2282         contentProcessor(xmlParserP, start, end, endPtr, errorCodeP, errorP);
2283     } else {
2284         *errorCodeP = result;
2285         *errorP = NULL;
2286     }
2287 }
2288 
2289 
2290 
2291 static void
doEntityRef(XML_Parser const xmlParserP,const ENCODING * const enc,const char * const s,const char * const next,enum XML_Error * const errorCodeP,const char ** const errorP)2292 doEntityRef(XML_Parser       const xmlParserP,
2293             const ENCODING * const enc,
2294             const char *     const s,
2295             const char *     const next,
2296             enum XML_Error * const errorCodeP,
2297             const char **    const errorP) {
2298 
2299     Parser * const parser = (Parser *) xmlParserP;
2300 
2301     XML_Char const ch = XmlPredefinedEntityName(enc,
2302                                                 s + enc->minBytesPerChar,
2303                                                 next - enc->minBytesPerChar);
2304     const XML_Char *name;
2305     ENTITY *entity;
2306     *errorP = NULL;
2307 
2308     if (ch) {
2309         if (characterDataHandler)
2310             characterDataHandler(handlerArg, &ch, 1);
2311         else if (defaultHandler)
2312             reportDefault(xmlParserP, enc, s, next);
2313         *errorCodeP = XML_ERROR_NONE;
2314         return;
2315     }
2316     name = poolStoreString(&dtd.pool, enc,
2317                            s + enc->minBytesPerChar,
2318                            next - enc->minBytesPerChar);
2319     if (!name) {
2320         *errorCodeP = XML_ERROR_NO_MEMORY;
2321         return;
2322     }
2323     entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
2324     poolDiscard(&dtd.pool);
2325     if (!entity) {
2326         if (dtd.complete || dtd.standalone)
2327             *errorCodeP = XML_ERROR_UNDEFINED_ENTITY;
2328         else {
2329             if (defaultHandler)
2330                 reportDefault(xmlParserP, enc, s, next);
2331             *errorCodeP = XML_ERROR_NONE;
2332         }
2333         return;
2334     }
2335     if (entity->open) {
2336         *errorCodeP = XML_ERROR_RECURSIVE_ENTITY_REF;
2337         return;
2338     }
2339     if (entity->notation) {
2340         *errorCodeP = XML_ERROR_BINARY_ENTITY_REF;
2341         return;
2342     }
2343     if (entity) {
2344         if (entity->textPtr) {
2345             OPEN_INTERNAL_ENTITY openEntity;
2346             if (defaultHandler && !defaultExpandInternalEntities) {
2347                 reportDefault(xmlParserP, enc, s, next);
2348                 *errorCodeP = XML_ERROR_NONE;
2349                 return;
2350             }
2351             entity->open = 1;
2352             openEntity.next = openInternalEntities;
2353             openInternalEntities = &openEntity;
2354             openEntity.entity = entity;
2355             openEntity.internalEventPtr = 0;
2356             openEntity.internalEventEndPtr = 0;
2357             doContent(xmlParserP,
2358                       tagLevel,
2359                       internalEncoding,
2360                       (char *)entity->textPtr,
2361                       (char *)(entity->textPtr + entity->textLen),
2362                       0, errorCodeP, errorP);
2363             entity->open = 0;
2364             openInternalEntities = openEntity.next;
2365             if (*errorCodeP != XML_ERROR_NONE)
2366                 return;
2367         } else if (externalEntityRefHandler) {
2368             const XML_Char *context;
2369             entity->open = 1;
2370             context = getContext(xmlParserP);
2371             entity->open = 0;
2372             if (!context) {
2373                 *errorCodeP = XML_ERROR_NO_MEMORY;
2374                 return;
2375             }
2376             if (!externalEntityRefHandler(externalEntityRefHandlerArg,
2377                                           context,
2378                                           entity->base,
2379                                           entity->systemId,
2380                                           entity->publicId)) {
2381                 *errorCodeP = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
2382                 return;
2383             }
2384             poolDiscard(&tempPool);
2385         } else if (defaultHandler)
2386             reportDefault(xmlParserP, enc, s, next);
2387     }
2388     *errorCodeP = XML_ERROR_NONE;
2389 }
2390 
2391 
2392 
2393 static void
doStartTagNoAtts(XML_Parser const xmlParserP,const ENCODING * const enc,const char * const s,const char * const next,const char ** const nextPtr,enum XML_Error * const errorCodeP,const char ** const errorP)2394 doStartTagNoAtts(XML_Parser       const xmlParserP,
2395                  const ENCODING * const enc,
2396                  const char *     const s,
2397                  const char *     const next,
2398                  const char **    const nextPtr,
2399                  enum XML_Error * const errorCodeP,
2400                  const char **    const errorP) {
2401 
2402     Parser * const parser = (Parser *) xmlParserP;
2403 
2404     TAG *tag;
2405 
2406     *errorP = NULL;
2407 
2408     if (freeTagList) {
2409         tag = freeTagList;
2410         freeTagList = freeTagList->parent;
2411     } else {
2412         tag = malloc(sizeof(TAG));
2413         if (!tag) {
2414             *errorCodeP = XML_ERROR_NO_MEMORY;
2415             return;
2416         }
2417         tag->buf = malloc(INIT_TAG_BUF_SIZE);
2418         if (!tag->buf) {
2419             *errorCodeP = XML_ERROR_NO_MEMORY;
2420             return;
2421         }
2422         tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
2423     }
2424     tag->bindings = NULL;
2425     tag->parent = tagStack;
2426     tagStack = tag;
2427     tag->name.localPart = 0;
2428     tag->rawName = s + enc->minBytesPerChar;
2429     tag->rawNameLength = XmlNameLength(enc, tag->rawName);
2430     if (nextPtr) {
2431         /* Need to guarantee that: tag->buf +
2432            ROUND_UP(tag->rawNameLength, sizeof(XML_Char)) <=
2433            tag->bufEnd - sizeof(XML_Char)
2434         */
2435 
2436         if (tag->rawNameLength +
2437             (int)(sizeof(XML_Char) - 1) +
2438             (int)sizeof(XML_Char) > tag->bufEnd - tag->buf) {
2439             int bufSize = tag->rawNameLength * 4;
2440             bufSize = ROUND_UP(bufSize, sizeof(XML_Char));
2441             tag->buf = realloc(tag->buf, bufSize);
2442             if (!tag->buf) {
2443                 *errorCodeP = XML_ERROR_NO_MEMORY;
2444                 return;
2445             }
2446             tag->bufEnd = tag->buf + bufSize;
2447         }
2448         memcpy(tag->buf, tag->rawName, tag->rawNameLength);
2449         tag->rawName = tag->buf;
2450     }
2451     ++tagLevel;
2452     if (startElementHandler) {
2453         enum XML_Error result;
2454         XML_Char *toPtr;
2455         for (;;) {
2456             const char *rawNameEnd = tag->rawName + tag->rawNameLength;
2457             const char *fromPtr = tag->rawName;
2458             if (nextPtr)
2459                 toPtr = (XML_Char *)
2460                     (tag->buf + ROUND_UP(tag->rawNameLength,
2461                                          sizeof(XML_Char)));
2462             else
2463                 toPtr = (XML_Char *)tag->buf;
2464             tag->name.str = toPtr;
2465             XmlConvert(enc,
2466                        &fromPtr, rawNameEnd,
2467                        (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
2468             if (fromPtr == rawNameEnd)
2469                 break;
2470             else {
2471                 size_t const bufSize = (tag->bufEnd - tag->buf) << 1;
2472                 tag->buf = realloc(tag->buf, bufSize);
2473                 if (!tag->buf) {
2474                     *errorCodeP = XML_ERROR_NO_MEMORY;
2475                     return;
2476                 }
2477                 tag->bufEnd = tag->buf + bufSize;
2478                 if (nextPtr)
2479                     tag->rawName = tag->buf;
2480             }
2481         }
2482         *toPtr = XML_T('\0');
2483         result = storeAtts(xmlParserP, enc, s,
2484                            &(tag->name), &(tag->bindings));
2485         if (result) {
2486             *errorCodeP = result;
2487             return;
2488         }
2489         startElementHandler(handlerArg, tag->name.str,
2490                             (const XML_Char **)atts);
2491         poolClear(&tempPool);
2492     } else {
2493         tag->name.str = 0;
2494         if (defaultHandler)
2495             reportDefault(xmlParserP, enc, s, next);
2496     }
2497 }
2498 
2499 
2500 
2501 static void
doEmptyElementNoAtts(XML_Parser const xmlParserP,const ENCODING * const enc,const char * const s,const char * const end,const char * const next,const char ** const nextPtr,const char ** const eventPP,const char ** const eventEndPP,bool * const doneP,enum XML_Error * const errorCodeP,const char ** const errorP)2502 doEmptyElementNoAtts(XML_Parser       const xmlParserP,
2503                      const ENCODING * const enc,
2504                      const char *     const s,
2505                      const char *     const end,
2506                      const char *     const next,
2507                      const char **    const nextPtr,
2508                      const char **    const eventPP,
2509                      const char **    const eventEndPP,
2510                      bool *           const doneP,
2511                      enum XML_Error * const errorCodeP,
2512                      const char **    const errorP) {
2513 
2514     Parser * const parser = (Parser *) xmlParserP;
2515 
2516     if (startElementHandler || endElementHandler) {
2517         const char * const rawName = s + enc->minBytesPerChar;
2518 
2519         enum XML_Error result;
2520         BINDING * bindings;
2521         TAG_NAME name;
2522 
2523         bindings = NULL;  /* initial value */
2524         name.str = poolStoreString(&tempPool, enc, rawName,
2525                                    rawName + XmlNameLength(enc, rawName));
2526         if (!name.str) {
2527             *errorCodeP = XML_ERROR_NO_MEMORY;
2528             return;
2529         }
2530         poolFinish(&tempPool);
2531         result = storeAtts(xmlParserP, enc, s, &name, &bindings);
2532         if (result) {
2533             *errorCodeP = result;
2534             return;
2535         }
2536         poolFinish(&tempPool);
2537         if (startElementHandler)
2538             startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
2539         if (endElementHandler) {
2540             if (startElementHandler)
2541                 *eventPP = *eventEndPP;
2542             endElementHandler(handlerArg, name.str);
2543         }
2544         poolClear(&tempPool);
2545         while (bindings) {
2546             BINDING * const b = bindings;
2547             if (endNamespaceDeclHandler)
2548                 endNamespaceDeclHandler(handlerArg, b->prefix->name);
2549             bindings = bindings->nextTagBinding;
2550             b->nextTagBinding = freeBindingList;
2551             freeBindingList = b;
2552             b->prefix->binding = b->prevPrefixBinding;
2553         }
2554     } else if (defaultHandler)
2555         reportDefault(xmlParserP, enc, s, next);
2556 
2557     if (tagLevel == 0) {
2558         epilogProcessor(xmlParserP, next, end, nextPtr, errorCodeP, errorP);
2559         *doneP = true;
2560     } else
2561         *doneP = false;
2562 }
2563 
2564 
2565 
2566 static void
doEndTag(XML_Parser const xmlParserP,const ENCODING * const enc,const char * const s,const char * const end,const char * const next,const char ** const nextPtr,int const startTagLevel,const char ** const eventPP,bool * const doneP,enum XML_Error * const errorCodeP,const char ** const errorP)2567 doEndTag(XML_Parser       const xmlParserP,
2568          const ENCODING * const enc,
2569          const char *     const s,
2570          const char *     const end,
2571          const char *     const next,
2572          const char **    const nextPtr,
2573          int              const startTagLevel,
2574          const char **    const eventPP,
2575          bool *           const doneP,
2576          enum XML_Error * const errorCodeP,
2577          const char **    const errorP) {
2578 
2579     Parser * const parser = (Parser *) xmlParserP;
2580 
2581     if (tagLevel == startTagLevel)
2582         *errorCodeP = XML_ERROR_ASYNC_ENTITY;
2583     else {
2584         TAG * const tag = tagStack;
2585 
2586         int len;
2587         const char * rawName;
2588 
2589         tagStack = tag->parent;
2590         tag->parent = freeTagList;
2591         freeTagList = tag;
2592         rawName = s + enc->minBytesPerChar*2;
2593         len = XmlNameLength(enc, rawName);
2594         if (len != tag->rawNameLength
2595             || memcmp(tag->rawName, rawName, len) != 0) {
2596             *eventPP = rawName;
2597             *errorCodeP = XML_ERROR_TAG_MISMATCH;
2598         } else {
2599             --tagLevel;
2600             if (endElementHandler && tag->name.str) {
2601                 if (tag->name.localPart) {
2602                     XML_Char * to;
2603                     const XML_Char * from;
2604                     to   = (XML_Char *)tag->name.str + tag->name.uriLen;
2605                     from = tag->name.localPart;
2606                     while ((*to++ = *from++) != 0)
2607                         ;
2608                 }
2609                 endElementHandler(handlerArg, tag->name.str);
2610             } else if (defaultHandler)
2611                 reportDefault(xmlParserP, enc, s, next);
2612 
2613             while (tag->bindings) {
2614                 BINDING * const b = tag->bindings;
2615                 if (endNamespaceDeclHandler)
2616                     endNamespaceDeclHandler(handlerArg, b->prefix->name);
2617                 tag->bindings = tag->bindings->nextTagBinding;
2618                 b->nextTagBinding = freeBindingList;
2619                 freeBindingList = b;
2620                 b->prefix->binding = b->prevPrefixBinding;
2621             }
2622             if (tagLevel == 0) {
2623                 epilogProcessor(xmlParserP, next, end, nextPtr,
2624                                 errorCodeP, errorP);
2625                 *doneP = true;
2626             } else {
2627                 *errorCodeP = XML_ERROR_NONE;
2628                 *doneP = false;
2629             }
2630         }
2631     }
2632 }
2633 
2634 
2635 
2636 static void
processContentToken(XML_Parser const xmlParserP,int const tok,const ENCODING * const enc,const char * const s,const char * const end,const char ** const nextP,const char ** const nextPtr,int const startTagLevel,const char ** const eventPP,const char ** const eventEndPP,bool * const doneP,enum XML_Error * const errorCodeP,const char ** const errorP)2637 processContentToken(XML_Parser       const xmlParserP,
2638                     int              const tok,
2639                     const ENCODING * const enc,
2640                     const char *     const s,
2641                     const char *     const end,
2642                     const char **    const nextP,
2643                     const char **    const nextPtr,
2644                     int              const startTagLevel,
2645                     const char **    const eventPP,
2646                     const char **    const eventEndPP,
2647                     bool *           const doneP,
2648                     enum XML_Error * const errorCodeP,
2649                     const char **    const errorP) {
2650 
2651     Parser * const parser = (Parser *) xmlParserP;
2652 
2653     *errorP = NULL;
2654     *errorCodeP = XML_ERROR_NONE;
2655 
2656     switch (tok) {
2657     case XML_TOK_TRAILING_CR:
2658       if (nextPtr) {
2659           *nextPtr = s;
2660           *doneP = true;
2661       } else {
2662           *eventEndPP = end;
2663 
2664           if (characterDataHandler) {
2665               XML_Char c = 0xA;
2666               characterDataHandler(handlerArg, &c, 1);
2667           } else if (defaultHandler)
2668               reportDefault(xmlParserP, enc, s, end);
2669 
2670           if (startTagLevel == 0)
2671               *errorCodeP = XML_ERROR_NO_ELEMENTS;
2672           else if (tagLevel != startTagLevel) {
2673               *errorCodeP = XML_ERROR_ASYNC_ENTITY;
2674           } else
2675               *doneP = true;
2676       }
2677       break;
2678     case XML_TOK_NONE:
2679         if (nextPtr) {
2680             *nextPtr = s;
2681             *doneP = true;
2682         } else if (startTagLevel > 0) {
2683             if (tagLevel != startTagLevel)
2684                 *errorCodeP = XML_ERROR_ASYNC_ENTITY;
2685             else
2686                 *doneP = true;
2687         } else
2688             *errorCodeP = XML_ERROR_NO_ELEMENTS;
2689         break;
2690     case XML_TOK_INVALID:
2691         *eventPP = *nextP;
2692         *errorCodeP = XML_ERROR_INVALID_TOKEN;
2693         xmlrpc_asprintf(errorP, "Invalid token, starting %ld bytes in",
2694                         (long)(*nextP - s));
2695         break;
2696     case XML_TOK_PARTIAL:
2697         if (nextPtr) {
2698             *nextPtr = s;
2699             *doneP = true;
2700         } else
2701             *errorCodeP = XML_ERROR_UNCLOSED_TOKEN;
2702         break;
2703     case XML_TOK_PARTIAL_CHAR:
2704         if (nextPtr) {
2705             *nextPtr = s;
2706             *doneP = true;
2707         } else
2708             *errorCodeP = XML_ERROR_PARTIAL_CHAR;
2709         break;
2710     case XML_TOK_ENTITY_REF:
2711         doEntityRef(xmlParserP, enc, s, *nextP, errorCodeP, errorP);
2712         break;
2713     case XML_TOK_START_TAG_WITH_ATTS:
2714         if (!startElementHandler)
2715             *errorCodeP = storeAtts(xmlParserP, enc, s, 0, 0);
2716         if (*errorCodeP == XML_ERROR_NONE)
2717             doStartTagNoAtts(xmlParserP, enc, s, *nextP, nextPtr,
2718                              errorCodeP, errorP);
2719         break;
2720     case XML_TOK_START_TAG_NO_ATTS:
2721         doStartTagNoAtts(xmlParserP, enc, s, *nextP, nextPtr,
2722                          errorCodeP, errorP);
2723         break;
2724     case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
2725         if (!startElementHandler)
2726             *errorCodeP = storeAtts(xmlParserP, enc, s, 0, 0);
2727 
2728         if (*errorCodeP == XML_ERROR_NONE)
2729             doEmptyElementNoAtts(xmlParserP, enc, s, end, *nextP, nextPtr,
2730                                  eventPP, eventEndPP,
2731                                  doneP, errorCodeP, errorP);
2732         break;
2733     case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
2734         doEmptyElementNoAtts(xmlParserP, enc, s, end, *nextP, nextPtr,
2735                              eventPP, eventEndPP,
2736                              doneP, errorCodeP, errorP);
2737         break;
2738     case XML_TOK_END_TAG:
2739         doEndTag(xmlParserP, enc, s, end, *nextP, nextPtr, startTagLevel,
2740                  eventPP, doneP, errorCodeP, errorP);
2741         break;
2742     case XML_TOK_CHAR_REF: {
2743         int const n = XmlCharRefNumber(enc, s);
2744         if (n < 0)
2745             *errorCodeP = XML_ERROR_BAD_CHAR_REF;
2746         else {
2747             if (characterDataHandler) {
2748                 XML_Char buf[XML_ENCODE_MAX];
2749                 characterDataHandler(handlerArg, buf,
2750                                      XmlEncode(n, (ICHAR *)buf));
2751             } else if (defaultHandler)
2752                 reportDefault(xmlParserP, enc, s, *nextP);
2753         }
2754     } break;
2755     case XML_TOK_XML_DECL:
2756         *errorCodeP = XML_ERROR_MISPLACED_XML_PI;
2757         break;
2758     case XML_TOK_DATA_NEWLINE:
2759         if (characterDataHandler) {
2760             XML_Char c = 0xA;
2761             characterDataHandler(handlerArg, &c, 1);
2762         } else if (defaultHandler)
2763             reportDefault(xmlParserP, enc, s, *nextP);
2764         break;
2765     case XML_TOK_CDATA_SECT_OPEN: {
2766         enum XML_Error result;
2767         if (startCdataSectionHandler)
2768             startCdataSectionHandler(handlerArg);
2769         else if (defaultHandler)
2770             reportDefault(xmlParserP, enc, s, *nextP);
2771         result = doCdataSection(xmlParserP, enc, nextP, end, nextPtr);
2772         if (!*nextP) {
2773             processor = cdataSectionProcessor;
2774             *errorCodeP = result;
2775         }
2776     } break;
2777     case XML_TOK_TRAILING_RSQB:
2778         if (nextPtr) {
2779             *nextPtr = s;
2780             *errorCodeP = XML_ERROR_NONE;
2781         } else {
2782             if (characterDataHandler) {
2783                 if (MUST_CONVERT(enc, s)) {
2784                     const char * from;
2785                     ICHAR * dataPtr;
2786                     from = s;
2787                     dataPtr = (ICHAR *)dataBuf;
2788                     XmlConvert(enc, &from, end, &dataPtr, (ICHAR *)dataBufEnd);
2789                     {
2790                         size_t const len = dataPtr - (ICHAR *)dataBuf;
2791                         assert((size_t)(int)len == len);   /* parser reqt */
2792                         characterDataHandler(handlerArg, dataBuf, (int)len);
2793                     }
2794                 } else {
2795                     size_t const len = (XML_Char *)end - (XML_Char *)s;
2796                     assert((size_t)(int)len == len);   /* parser reqt */
2797                     characterDataHandler(handlerArg, (XML_Char *)s, (int)len);
2798                 }
2799             } else if (defaultHandler)
2800                 reportDefault(xmlParserP, enc, s, end);
2801 
2802             if (startTagLevel == 0) {
2803                 *eventPP = end;
2804                 *errorCodeP = XML_ERROR_NO_ELEMENTS;
2805             } else if (tagLevel != startTagLevel) {
2806                 *eventPP = end;
2807                 *errorCodeP = XML_ERROR_ASYNC_ENTITY;
2808             } else
2809                 *doneP = true;
2810         }
2811         break;
2812     case XML_TOK_DATA_CHARS:
2813         if (characterDataHandler) {
2814             if (MUST_CONVERT(enc, s)) {
2815                 for (;;) {
2816                     const char * from;
2817                     ICHAR * dataPtr;
2818                     dataPtr = (ICHAR *)dataBuf;
2819                     from = s;
2820                     XmlConvert(enc, &from, *nextP, &dataPtr,
2821                                (ICHAR *)dataBufEnd);
2822                     *eventEndPP = from;
2823                     {
2824                         size_t const len = dataPtr - (ICHAR *)dataBuf;
2825                         assert((size_t)(int)len == len);   /* parser reqt */
2826                         characterDataHandler(handlerArg, dataBuf, (int)len);
2827                     }
2828                     if (from == *nextP)
2829                         break;
2830                     *eventPP = from;
2831                 }
2832             } else {
2833                 size_t const len = (XML_Char *)*nextP - (XML_Char *)s;
2834                 assert((size_t)(int)len == len);   /* parser reqt */
2835                 characterDataHandler(handlerArg, (XML_Char *)s, len);
2836             }
2837         } else if (defaultHandler)
2838             reportDefault(xmlParserP, enc, s, *nextP);
2839         break;
2840     case XML_TOK_PI:
2841         if (!reportProcessingInstruction(xmlParserP, enc, s, *nextP))
2842             *errorCodeP = XML_ERROR_NO_MEMORY;
2843         break;
2844     case XML_TOK_COMMENT:
2845         if (!reportComment(xmlParserP, enc, s, *nextP))
2846             *errorCodeP = XML_ERROR_NO_MEMORY;
2847         break;
2848     default:
2849         if (defaultHandler)
2850             reportDefault(xmlParserP, enc, s, *nextP);
2851         break;
2852     }
2853 }
2854 
2855 
2856 
2857 static void
doContent(XML_Parser const xmlParserP,int const startTagLevel,const ENCODING * const enc,const char * const startArg,const char * const end,const char ** const nextPtr,enum XML_Error * const errorCodeP,const char ** const errorP)2858 doContent(XML_Parser       const xmlParserP,
2859           int              const startTagLevel,
2860           const ENCODING * const enc,
2861           const char *     const startArg,
2862           const char *     const end,
2863           const char **    const nextPtr,
2864           enum XML_Error * const errorCodeP,
2865           const char **    const errorP) {
2866 
2867     Parser * const parser = (Parser *) xmlParserP;
2868 
2869     const char **eventPP;
2870     const char **eventEndPP;
2871     const char * s;
2872     bool done;
2873 
2874     if (enc == parser->m_encoding) {
2875         eventPP = &eventPtr;
2876         eventEndPP = &eventEndPtr;
2877     } else {
2878         eventPP = &(openInternalEntities->internalEventPtr);
2879         eventEndPP = &(openInternalEntities->internalEventEndPtr);
2880     }
2881 
2882     s = startArg;
2883     *eventPP = s;
2884     done = false;
2885     *errorCodeP = XML_ERROR_NONE;
2886     *errorP = NULL;
2887 
2888     while (*errorCodeP == XML_ERROR_NONE && !done) {
2889         int tok;
2890         const char * next;
2891         const char * error;
2892 
2893         next = s; /* XmlContentTok doesn't always set the last arg */
2894         /* XmlContentTok() is normally normal_contentTok(), aka
2895            PREFIX(contentTok)() in xmltok/xmltok_impl.c
2896         */
2897         tok = XmlContentTok(enc, s, end, &next);
2898         *eventEndPP = next;
2899 
2900         processContentToken(xmlParserP, tok, enc, s, end, &next, nextPtr,
2901                             startTagLevel, eventPP, eventEndPP, &done,
2902                             errorCodeP, &error);
2903 
2904         if (*errorCodeP != XML_ERROR_NONE) {
2905             const char * const xmlSample = extractXmlSample(s, end, 40);
2906 
2907             if (error) {
2908                 xmlrpc_asprintf(errorP, "Problem with token at '%s...': %s",
2909                                 xmlSample, error);
2910                 xmlrpc_strfree(error);
2911             } else
2912                 xmlrpc_asprintf(errorP, "Problem with token at '%s...': %s",
2913                                 xmlSample,
2914                                 xmlrpc_XML_ErrorString(*errorCodeP));
2915 
2916             xmlrpc_strfree(xmlSample);
2917         }
2918         *eventPP = s = next;
2919     }
2920 }
2921 
2922 
2923 
2924 static Processor externalEntityContentProcessor;
2925 
2926 static void
externalEntityContentProcessor(XML_Parser const xmlParserP,const char * const start,const char * const end,const char ** const endPtr,enum XML_Error * const errorCodeP,const char ** const errorP)2927 externalEntityContentProcessor(XML_Parser       const xmlParserP,
2928                                const char *     const start,
2929                                const char *     const end,
2930                                const char **    const endPtr,
2931                                enum XML_Error * const errorCodeP,
2932                                const char **    const errorP) {
2933 
2934     Parser * const parser = (Parser *) xmlParserP;
2935 
2936     *errorP = NULL;
2937 
2938     doContent(xmlParserP, 1, parser->m_encoding, start, end, endPtr,
2939               errorCodeP, errorP);
2940 }
2941 
2942 
2943 
2944 static Processor externalEntityInitProcessor3;
2945 
2946 static void
externalEntityInitProcessor3(XML_Parser const xmlParserP,const char * const startArg,const char * const end,const char ** const endPtr,enum XML_Error * const errorCodeP,const char ** const errorP)2947 externalEntityInitProcessor3(XML_Parser       const xmlParserP,
2948                              const char *     const startArg,
2949                              const char *     const end,
2950                              const char **    const endPtr,
2951                              enum XML_Error * const errorCodeP,
2952                              const char **    const errorP) {
2953 
2954     Parser * const parser = (Parser *) xmlParserP;
2955 
2956     const char * start;
2957     const char *next;
2958     int tok;
2959 
2960     tok = XmlContentTok(parser->m_encoding, startArg, end, &next);
2961 
2962     *errorP = NULL;
2963 
2964     start = startArg;
2965 
2966     switch (tok) {
2967     case XML_TOK_XML_DECL:
2968     {
2969         enum XML_Error result = processXmlDecl(xmlParserP, 1, start, next);
2970         if (result != XML_ERROR_NONE) {
2971             *errorCodeP = result;
2972             return;
2973         }
2974         start = next;
2975     }
2976     break;
2977     case XML_TOK_PARTIAL:
2978         if (endPtr) {
2979             *endPtr = start;
2980             *errorCodeP = XML_ERROR_NONE;
2981             return;
2982         }
2983         eventPtr = start;
2984         *errorCodeP = XML_ERROR_UNCLOSED_TOKEN;
2985         return;
2986     case XML_TOK_PARTIAL_CHAR:
2987         if (endPtr) {
2988             *endPtr = start;
2989             *errorCodeP = XML_ERROR_NONE;
2990             return;
2991         }
2992         eventPtr = start;
2993         *errorCodeP = XML_ERROR_PARTIAL_CHAR;
2994         return;
2995     }
2996     processor = externalEntityContentProcessor;
2997     tagLevel = 1;
2998     doContent(xmlParserP, 1, parser->m_encoding, start, end, endPtr,
2999               errorCodeP, errorP);
3000 }
3001 
3002 
3003 
3004 static Processor externalEntityInitProcessor2;
3005 
3006 static void
externalEntityInitProcessor2(XML_Parser const xmlParserP,const char * const startArg,const char * const end,const char ** const endPtr,enum XML_Error * const errorCodeP,const char ** const errorP)3007 externalEntityInitProcessor2(XML_Parser       const xmlParserP,
3008                              const char *     const startArg,
3009                              const char *     const end,
3010                              const char **    const endPtr,
3011                              enum XML_Error * const errorCodeP,
3012                              const char **    const errorP) {
3013 
3014     Parser * const parser = (Parser *)xmlParserP;
3015 
3016     const char * start;
3017     const char * next;
3018     int tok;
3019 
3020     tok = XmlContentTok(parser->m_encoding, startArg, end, &next);
3021 
3022     start = startArg;
3023 
3024     switch (tok) {
3025     case XML_TOK_BOM:
3026         start = next;
3027         break;
3028     case XML_TOK_PARTIAL:
3029         if (endPtr) {
3030             *endPtr = start;
3031             *errorCodeP = XML_ERROR_NONE;
3032             *errorP = NULL;
3033         } else {
3034             eventPtr = start;
3035             *errorCodeP = XML_ERROR_UNCLOSED_TOKEN;
3036             *errorP = NULL;
3037         }
3038         return;
3039     case XML_TOK_PARTIAL_CHAR:
3040         if (endPtr) {
3041             *endPtr = start;
3042             *errorCodeP = XML_ERROR_NONE;
3043             *errorP = NULL;
3044         } else {
3045             eventPtr = start;
3046             *errorCodeP = XML_ERROR_PARTIAL_CHAR;
3047             *errorP = NULL;
3048         }
3049         return;
3050     }
3051     processor = externalEntityInitProcessor3;
3052     externalEntityInitProcessor3(xmlParserP, start, end, endPtr,
3053                                  errorCodeP, errorP);
3054 }
3055 
3056 
3057 
3058 static Processor externalEntityInitProcessor;
3059 
3060 static void
externalEntityInitProcessor(XML_Parser const parser,const char * const start,const char * const end,const char ** const endPtr,enum XML_Error * const errorCodeP,const char ** const errorP)3061 externalEntityInitProcessor(XML_Parser       const parser,
3062                             const char *     const start,
3063                             const char *     const end,
3064                             const char **    const endPtr,
3065                             enum XML_Error * const errorCodeP,
3066                             const char **    const errorP) {
3067 
3068     enum XML_Error result;
3069 
3070     result = initializeEncoding(parser);
3071 
3072     if (result != XML_ERROR_NONE) {
3073         *errorCodeP = result;
3074         *errorP = NULL;
3075     } else {
3076         processor = externalEntityInitProcessor2;
3077 
3078         externalEntityInitProcessor2(parser, start, end, endPtr,
3079                                      errorCodeP, errorP);
3080     }
3081 }
3082 
3083 
3084 
3085 static enum XML_Error
doIgnoreSection(XML_Parser const xmlParserP,const ENCODING * const enc,const char ** const startPtr,const char * const end,const char ** const nextPtr)3086 doIgnoreSection(XML_Parser       const xmlParserP,
3087                 const ENCODING * const enc,
3088                 const char **    const startPtr,
3089                 const char *     const end,
3090                 const char **    const nextPtr) {
3091 /*----------------------------------------------------------------------------
3092 
3093   We set *startPtr to non-null is the section is closed, and to null if
3094   the section is not yet closed.
3095 -----------------------------------------------------------------------------*/
3096     Parser * const parser = (Parser *) xmlParserP;
3097     const char * const s = *startPtr;
3098 
3099     enum XML_Error retval;
3100     const char * next;
3101     int tok;
3102     const char ** eventPP;
3103     const char ** eventEndPP;
3104 
3105     if (enc == parser->m_encoding) {
3106         eventPP = &eventPtr;
3107         eventEndPP = &eventEndPtr;
3108     } else {
3109         eventPP = &(openInternalEntities->internalEventPtr);
3110         eventEndPP = &(openInternalEntities->internalEventEndPtr);
3111     }
3112     *eventPP = s;
3113     *startPtr = '\0';
3114     tok = XmlIgnoreSectionTok(enc, s, end, &next);
3115     *eventEndPP = next;
3116 
3117     switch (tok) {
3118     case XML_TOK_IGNORE_SECT:
3119         if (defaultHandler)
3120             reportDefault(xmlParserP, enc, s, next);
3121         *startPtr = next;
3122         retval = XML_ERROR_NONE;
3123         break;
3124     case XML_TOK_INVALID:
3125         *eventPP = next;
3126         retval = XML_ERROR_INVALID_TOKEN;
3127         break;
3128     case XML_TOK_PARTIAL_CHAR:
3129         if (nextPtr) {
3130             *nextPtr = s;
3131             retval = XML_ERROR_NONE;
3132         } else
3133             retval = XML_ERROR_PARTIAL_CHAR;
3134         break;
3135     case XML_TOK_PARTIAL:
3136     case XML_TOK_NONE:
3137         if (nextPtr) {
3138             *nextPtr = s;
3139             retval = XML_ERROR_NONE;
3140         } else
3141             retval = XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
3142         break;
3143     default:
3144         assert(false);  /* All possibilities are handled above */
3145         retval = 99; /* quiet compiler warning */
3146     }
3147 
3148     return retval;
3149 }
3150 
3151 
3152 
3153 static Processor prologProcessor;
3154 
3155 
3156 /* The idea here is to avoid using stack for each IGNORE section when
3157 the whole file is parsed with one call. */
3158 
3159 static Processor ignoreSectionProcessor;
3160 
3161 static void
ignoreSectionProcessor(XML_Parser const xmlParserP,const char * const startArg,const char * const end,const char ** const endPtr,enum XML_Error * const errorCodeP,const char ** const errorP)3162 ignoreSectionProcessor(XML_Parser       const xmlParserP,
3163                        const char *     const startArg,
3164                        const char *     const end,
3165                        const char **    const endPtr,
3166                        enum XML_Error * const errorCodeP,
3167                        const char **    const errorP) {
3168 
3169     Parser * const parser = (Parser *) xmlParserP;
3170 
3171     enum XML_Error result;
3172     const char * start;
3173 
3174     start = startArg;  /* initial value */
3175 
3176     result = doIgnoreSection(parser, parser->m_encoding, &start, end, endPtr);
3177 
3178     if (start) {
3179         processor = prologProcessor;
3180         prologProcessor(xmlParserP, start, end, endPtr, errorCodeP, errorP);
3181     } else {
3182         *errorCodeP = result;
3183         *errorP = NULL;
3184     }
3185 }
3186 
3187 
3188 
3189 /* Forward declaration for recursive reference: */
3190 static void
3191 processInternalParamEntity(XML_Parser       const parser,
3192                            ENTITY *         const entity,
3193                            enum XML_Error * const errorCodeP,
3194                            const char **    const errorP);
3195 
3196 static void
doProlog(XML_Parser const xmlParserP,const ENCODING * const encArg,const char * const startArg,const char * const end,int const tokArg,const char * const nextArg,const char ** const nextPtr,enum XML_Error * const errorCodeP,const char ** const errorP)3197 doProlog(XML_Parser       const xmlParserP,
3198          const ENCODING * const encArg,
3199          const char *     const startArg,
3200          const char *     const end,
3201          int              const tokArg,
3202          const char *     const nextArg,
3203          const char **    const nextPtr,
3204          enum XML_Error * const errorCodeP,
3205          const char **    const errorP) {
3206 
3207   Parser * const parser = (Parser *) xmlParserP;
3208 
3209   int tok;
3210   const char * next;
3211   const ENCODING * enc;
3212   const char * s;
3213 
3214   static const XML_Char externalSubsetName[] = { '#' , '\0' };
3215 
3216   const char **eventPP;
3217   const char **eventEndPP;
3218 
3219   *errorP = NULL;
3220 
3221   tok = tokArg;
3222   next = nextArg;
3223   enc = encArg;
3224   s = startArg;
3225 
3226   if (enc == parser->m_encoding) {
3227     eventPP = &eventPtr;
3228     eventEndPP = &eventEndPtr;
3229   }
3230   else {
3231     eventPP = &(openInternalEntities->internalEventPtr);
3232     eventEndPP = &(openInternalEntities->internalEventEndPtr);
3233   }
3234   for (;;) {
3235     int role;
3236     *eventPP = s;
3237     *eventEndPP = next;
3238     if (tok <= 0) {
3239       if (nextPtr != 0 && tok != XML_TOK_INVALID) {
3240         *nextPtr = s;
3241         *errorCodeP = XML_ERROR_NONE;
3242         return;
3243       }
3244       switch (tok) {
3245       case XML_TOK_INVALID:
3246         *eventPP = next;
3247         *errorCodeP = XML_ERROR_INVALID_TOKEN;
3248         return;
3249       case XML_TOK_PARTIAL:
3250         *errorCodeP = XML_ERROR_UNCLOSED_TOKEN;
3251         return;
3252       case XML_TOK_PARTIAL_CHAR:
3253         *errorCodeP = XML_ERROR_PARTIAL_CHAR;
3254         return;
3255       case XML_TOK_NONE:
3256         if (enc != parser->m_encoding)
3257           *errorCodeP = XML_ERROR_NONE;
3258         else {
3259             if (parentParser) {
3260                 if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
3261                     == XML_ROLE_ERROR) {
3262                     *errorCodeP = XML_ERROR_SYNTAX;
3263                 } else {
3264                     *errorCodeP = XML_ERROR_NONE;
3265                     hadExternalDoctype = 0;
3266                 }
3267             } else
3268                 *errorCodeP = XML_ERROR_NO_ELEMENTS;
3269         }
3270         return;
3271       default:
3272         tok = -tok;
3273         next = end;
3274         break;
3275       }
3276     }
3277     role = XmlTokenRole(&prologState, tok, s, next, enc);
3278     switch (role) {
3279     case XML_ROLE_XML_DECL: {
3280         enum XML_Error result = processXmlDecl(xmlParserP, 0, s, next);
3281         if (result != XML_ERROR_NONE) {
3282           *errorCodeP = result;
3283           return;
3284         }
3285         enc = parser->m_encoding;
3286       }
3287       break;
3288     case XML_ROLE_DOCTYPE_NAME:
3289       if (startDoctypeDeclHandler) {
3290         const XML_Char *name = poolStoreString(&tempPool, enc, s, next);
3291         if (!name) {
3292           *errorCodeP = XML_ERROR_NO_MEMORY;
3293           return;
3294         }
3295         startDoctypeDeclHandler(handlerArg, name);
3296         poolClear(&tempPool);
3297       }
3298       break;
3299     case XML_ROLE_TEXT_DECL: {
3300         enum XML_Error result = processXmlDecl(xmlParserP, 1, s, next);
3301         if (result != XML_ERROR_NONE) {
3302           *errorCodeP = result;
3303           return;
3304         }
3305         enc = parser->m_encoding;
3306       }
3307       break;
3308     case XML_ROLE_DOCTYPE_PUBLIC_ID:
3309       declEntity = (ENTITY *)lookup(&dtd.paramEntities,
3310                                     externalSubsetName,
3311                                     sizeof(ENTITY));
3312       if (!declEntity) {
3313         *errorCodeP = XML_ERROR_NO_MEMORY;
3314         return;
3315       }
3316       /* fall through */
3317     case XML_ROLE_ENTITY_PUBLIC_ID:
3318       if (!XmlIsPublicId(enc, s, next, eventPP)) {
3319         *errorCodeP = XML_ERROR_SYNTAX;
3320         return;
3321       }
3322       if (declEntity) {
3323         XML_Char *tem = poolStoreString(&dtd.pool,
3324                                         enc,
3325                                         s + enc->minBytesPerChar,
3326                                         next - enc->minBytesPerChar);
3327         if (!tem) {
3328           *errorCodeP = XML_ERROR_NO_MEMORY;
3329           return;
3330         }
3331         normalizePublicId(tem);
3332         declEntity->publicId = tem;
3333         poolFinish(&dtd.pool);
3334       }
3335       break;
3336     case XML_ROLE_DOCTYPE_CLOSE:
3337       if (dtd.complete && hadExternalDoctype) {
3338         dtd.complete = 0;
3339         if (paramEntityParsing && externalEntityRefHandler) {
3340           ENTITY *entity = (ENTITY *)lookup(&dtd.paramEntities,
3341                                             externalSubsetName,
3342                                             0);
3343           if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3344                                         0,
3345                                         entity->base,
3346                                         entity->systemId,
3347                                         entity->publicId)) {
3348            *errorCodeP = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
3349            return;
3350           }
3351         }
3352         if (!dtd.complete
3353             && !dtd.standalone
3354             && notStandaloneHandler
3355             && !notStandaloneHandler(handlerArg)) {
3356           *errorCodeP = XML_ERROR_NOT_STANDALONE;
3357           return;
3358         }
3359       }
3360       if (endDoctypeDeclHandler)
3361         endDoctypeDeclHandler(handlerArg);
3362       break;
3363     case XML_ROLE_INSTANCE_START: {
3364       processor = contentProcessor;
3365       contentProcessor(xmlParserP, s, end, nextPtr, errorCodeP, errorP);
3366       return;
3367     }
3368     case XML_ROLE_ATTLIST_ELEMENT_NAME:
3369       {
3370         const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next);
3371         if (!name) {
3372           *errorCodeP = XML_ERROR_NO_MEMORY;
3373           return;
3374         }
3375         declElementType = (ELEMENT_TYPE *)
3376             lookup(&dtd.elementTypes, name, sizeof(ELEMENT_TYPE));
3377         if (!declElementType) {
3378           *errorCodeP = XML_ERROR_NO_MEMORY;
3379           return;
3380         }
3381         if (declElementType->name != name)
3382           poolDiscard(&dtd.pool);
3383         else {
3384           poolFinish(&dtd.pool);
3385           if (!setElementTypePrefix(xmlParserP, declElementType)) {
3386             *errorCodeP = XML_ERROR_NO_MEMORY;
3387             return;
3388           }
3389         }
3390         break;
3391       }
3392     case XML_ROLE_ATTRIBUTE_NAME:
3393       declAttributeId = getAttributeId(xmlParserP, enc, s, next);
3394       if (!declAttributeId) {
3395         *errorCodeP = XML_ERROR_NO_MEMORY;
3396         return;
3397       }
3398       declAttributeIsCdata = 0;
3399       declAttributeIsId = 0;
3400       break;
3401     case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
3402       declAttributeIsCdata = 1;
3403       break;
3404     case XML_ROLE_ATTRIBUTE_TYPE_ID:
3405       declAttributeIsId = 1;
3406       break;
3407     case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
3408     case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
3409       if (dtd.complete
3410           && !defineAttribute(declElementType, declAttributeId,
3411                               declAttributeIsCdata,
3412                               declAttributeIsId, 0)) {
3413         *errorCodeP = XML_ERROR_NO_MEMORY;
3414         return;
3415       }
3416       break;
3417     case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
3418     case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
3419       {
3420         const XML_Char *attVal;
3421         enum XML_Error result
3422           = storeAttributeValue(xmlParserP, enc, declAttributeIsCdata,
3423                                 s + enc->minBytesPerChar,
3424                                 next - enc->minBytesPerChar,
3425                                 &dtd.pool);
3426         if (result) {
3427           *errorCodeP = result;
3428           return;
3429         }
3430         attVal = poolStart(&dtd.pool);
3431         poolFinish(&dtd.pool);
3432         if (dtd.complete
3433             /* ID attributes aren't allowed to have a default */
3434             && !defineAttribute(declElementType, declAttributeId,
3435                                 declAttributeIsCdata, 0, attVal)) {
3436           *errorCodeP = XML_ERROR_NO_MEMORY;
3437           return;
3438         }
3439         break;
3440       }
3441     case XML_ROLE_ENTITY_VALUE:
3442       {
3443         enum XML_Error result = storeEntityValue(xmlParserP, enc,
3444                                                  s + enc->minBytesPerChar,
3445                                                  next - enc->minBytesPerChar);
3446         if (declEntity) {
3447           declEntity->textPtr = poolStart(&dtd.pool);
3448           declEntity->textLen = poolLength(&dtd.pool);
3449           poolFinish(&dtd.pool);
3450           if (internalParsedEntityDeclHandler
3451               /* Check it's not a parameter entity */
3452               && ((ENTITY *)lookup(&dtd.generalEntities, declEntity->name, 0)
3453                   == declEntity)) {
3454             *eventEndPP = s;
3455             internalParsedEntityDeclHandler(handlerArg,
3456                                             declEntity->name,
3457                                             declEntity->textPtr,
3458                                             declEntity->textLen);
3459           }
3460         }
3461         else
3462           poolDiscard(&dtd.pool);
3463         if (result != XML_ERROR_NONE) {
3464           *errorCodeP = result;
3465           return;
3466         }
3467       }
3468       break;
3469     case XML_ROLE_DOCTYPE_SYSTEM_ID:
3470       if (!dtd.standalone
3471           && !paramEntityParsing
3472           && notStandaloneHandler
3473           && !notStandaloneHandler(handlerArg)) {
3474         *errorCodeP = XML_ERROR_NOT_STANDALONE;
3475         return;
3476       }
3477       hadExternalDoctype = 1;
3478       if (!declEntity) {
3479         declEntity = (ENTITY *)lookup(&dtd.paramEntities,
3480                                       externalSubsetName,
3481                                       sizeof(ENTITY));
3482         if (!declEntity) {
3483           *errorCodeP = XML_ERROR_NO_MEMORY;
3484           return;
3485         }
3486       }
3487       /* fall through */
3488     case XML_ROLE_ENTITY_SYSTEM_ID:
3489       if (declEntity) {
3490         declEntity->systemId = poolStoreString(&dtd.pool, enc,
3491                                                s + enc->minBytesPerChar,
3492                                                next - enc->minBytesPerChar);
3493         if (!declEntity->systemId) {
3494           *errorCodeP = XML_ERROR_NO_MEMORY;
3495           return;
3496         }
3497         declEntity->base = curBase;
3498         poolFinish(&dtd.pool);
3499       }
3500       break;
3501     case XML_ROLE_ENTITY_NOTATION_NAME:
3502       if (declEntity) {
3503         declEntity->notation = poolStoreString(&dtd.pool, enc, s, next);
3504         if (!declEntity->notation) {
3505           *errorCodeP = XML_ERROR_NO_MEMORY;
3506           return;
3507         }
3508         poolFinish(&dtd.pool);
3509         if (unparsedEntityDeclHandler) {
3510           *eventEndPP = s;
3511           unparsedEntityDeclHandler(handlerArg,
3512                                     declEntity->name,
3513                                     declEntity->base,
3514                                     declEntity->systemId,
3515                                     declEntity->publicId,
3516                                     declEntity->notation);
3517         }
3518 
3519       }
3520       break;
3521     case XML_ROLE_EXTERNAL_GENERAL_ENTITY_NO_NOTATION:
3522       if (declEntity && externalParsedEntityDeclHandler) {
3523         *eventEndPP = s;
3524         externalParsedEntityDeclHandler(handlerArg,
3525                                         declEntity->name,
3526                                         declEntity->base,
3527                                         declEntity->systemId,
3528                                         declEntity->publicId);
3529       }
3530       break;
3531     case XML_ROLE_GENERAL_ENTITY_NAME:
3532       {
3533         const XML_Char *name;
3534         if (XmlPredefinedEntityName(enc, s, next)) {
3535           declEntity = 0;
3536           break;
3537         }
3538         name = poolStoreString(&dtd.pool, enc, s, next);
3539         if (!name) {
3540           *errorCodeP = XML_ERROR_NO_MEMORY;
3541           return;
3542         }
3543         if (dtd.complete) {
3544             declEntity = (ENTITY *)
3545                 lookup(&dtd.generalEntities, name, sizeof(ENTITY));
3546           if (!declEntity) {
3547             *errorCodeP = XML_ERROR_NO_MEMORY;
3548             return;
3549           }
3550           if (declEntity->name != name) {
3551             poolDiscard(&dtd.pool);
3552             declEntity = 0;
3553           }
3554           else
3555             poolFinish(&dtd.pool);
3556         }
3557         else {
3558           poolDiscard(&dtd.pool);
3559           declEntity = 0;
3560         }
3561       }
3562       break;
3563     case XML_ROLE_PARAM_ENTITY_NAME:
3564       if (dtd.complete) {
3565         const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next);
3566         if (!name) {
3567           *errorCodeP = XML_ERROR_NO_MEMORY;
3568           return;
3569         }
3570         declEntity = (ENTITY *)
3571             lookup(&dtd.paramEntities, name, sizeof(ENTITY));
3572         if (!declEntity) {
3573           *errorCodeP = XML_ERROR_NO_MEMORY;
3574           return;
3575         }
3576         if (declEntity->name != name) {
3577           poolDiscard(&dtd.pool);
3578           declEntity = 0;
3579         }
3580         else
3581           poolFinish(&dtd.pool);
3582       }
3583       break;
3584     case XML_ROLE_NOTATION_NAME:
3585       declNotationPublicId = 0;
3586       declNotationName = 0;
3587       if (notationDeclHandler) {
3588         declNotationName = poolStoreString(&tempPool, enc, s, next);
3589         if (!declNotationName) {
3590           *errorCodeP = XML_ERROR_NO_MEMORY;
3591           return;
3592         }
3593         poolFinish(&tempPool);
3594       }
3595       break;
3596     case XML_ROLE_NOTATION_PUBLIC_ID:
3597       if (!XmlIsPublicId(enc, s, next, eventPP)) {
3598         *errorCodeP = XML_ERROR_SYNTAX;
3599         return;
3600       }
3601       if (declNotationName) {
3602         XML_Char *tem = poolStoreString(&tempPool,
3603                                         enc,
3604                                         s + enc->minBytesPerChar,
3605                                         next - enc->minBytesPerChar);
3606         if (!tem) {
3607           *errorCodeP = XML_ERROR_NO_MEMORY;
3608           return;
3609         }
3610         normalizePublicId(tem);
3611         declNotationPublicId = tem;
3612         poolFinish(&tempPool);
3613       }
3614       break;
3615     case XML_ROLE_NOTATION_SYSTEM_ID:
3616       if (declNotationName && notationDeclHandler) {
3617         const XML_Char *systemId
3618           = poolStoreString(&tempPool, enc,
3619                             s + enc->minBytesPerChar,
3620                             next - enc->minBytesPerChar);
3621         if (!systemId) {
3622           *errorCodeP = XML_ERROR_NO_MEMORY;
3623           return;
3624         }
3625         *eventEndPP = s;
3626         notationDeclHandler(handlerArg,
3627                             declNotationName,
3628                             curBase,
3629                             systemId,
3630                             declNotationPublicId);
3631       }
3632       poolClear(&tempPool);
3633       break;
3634     case XML_ROLE_NOTATION_NO_SYSTEM_ID:
3635       if (declNotationPublicId && notationDeclHandler) {
3636         *eventEndPP = s;
3637         notationDeclHandler(handlerArg,
3638                             declNotationName,
3639                             curBase,
3640                             0,
3641                             declNotationPublicId);
3642       }
3643       poolClear(&tempPool);
3644       break;
3645     case XML_ROLE_ERROR:
3646       switch (tok) {
3647       case XML_TOK_PARAM_ENTITY_REF:
3648         *errorCodeP = XML_ERROR_PARAM_ENTITY_REF;
3649       case XML_TOK_XML_DECL:
3650         *errorCodeP = XML_ERROR_MISPLACED_XML_PI;
3651       default:
3652         *errorCodeP = XML_ERROR_SYNTAX;
3653       }
3654       return;
3655     case XML_ROLE_IGNORE_SECT:
3656       {
3657         enum XML_Error result;
3658         if (defaultHandler)
3659           reportDefault(xmlParserP, enc, s, next);
3660         result = doIgnoreSection(xmlParserP, enc, &next, end, nextPtr);
3661         if (!next) {
3662           processor = ignoreSectionProcessor;
3663           *errorCodeP = result;
3664           return;
3665         }
3666       }
3667       break;
3668     case XML_ROLE_GROUP_OPEN:
3669       if (prologState.level >= groupSize) {
3670         if (groupSize)
3671           groupConnector = realloc(groupConnector, groupSize *= 2);
3672         else
3673           groupConnector = malloc(groupSize = 32);
3674         if (!groupConnector) {
3675           *errorCodeP = XML_ERROR_NO_MEMORY;
3676           return;
3677         }
3678       }
3679       groupConnector[prologState.level] = 0;
3680       break;
3681     case XML_ROLE_GROUP_SEQUENCE:
3682       if (groupConnector[prologState.level] == '|') {
3683         *errorCodeP = XML_ERROR_SYNTAX;
3684         return;
3685       }
3686       groupConnector[prologState.level] = ',';
3687       break;
3688     case XML_ROLE_GROUP_CHOICE:
3689       if (groupConnector[prologState.level] == ',') {
3690         *errorCodeP =  XML_ERROR_SYNTAX;
3691         return;
3692       }
3693       groupConnector[prologState.level] = '|';
3694       break;
3695     case XML_ROLE_PARAM_ENTITY_REF:
3696     case XML_ROLE_INNER_PARAM_ENTITY_REF:
3697       if (paramEntityParsing
3698           && (dtd.complete || role == XML_ROLE_INNER_PARAM_ENTITY_REF)) {
3699         const XML_Char *name;
3700         ENTITY *entity;
3701         name = poolStoreString(&dtd.pool, enc,
3702                                 s + enc->minBytesPerChar,
3703                                 next - enc->minBytesPerChar);
3704         if (!name) {
3705           *errorCodeP = XML_ERROR_NO_MEMORY;
3706           return;
3707         }
3708         entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0);
3709         poolDiscard(&dtd.pool);
3710         if (!entity) {
3711           /* FIXME what to do if !dtd.complete? */
3712           *errorCodeP = XML_ERROR_UNDEFINED_ENTITY;
3713           return;
3714         }
3715         if (entity->open) {
3716           *errorCodeP = XML_ERROR_RECURSIVE_ENTITY_REF;
3717           return;
3718         }
3719         if (entity->textPtr) {
3720             processInternalParamEntity(xmlParserP, entity, errorCodeP, errorP);
3721             if (*errorCodeP != XML_ERROR_NONE)
3722                 return;
3723             break;
3724         }
3725         if (role == XML_ROLE_INNER_PARAM_ENTITY_REF) {
3726           *errorCodeP = XML_ERROR_PARAM_ENTITY_REF;
3727           return;
3728         }
3729         if (externalEntityRefHandler) {
3730           dtd.complete = 0;
3731           entity->open = 1;
3732           if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3733                                         0,
3734                                         entity->base,
3735                                         entity->systemId,
3736                                         entity->publicId)) {
3737             entity->open = 0;
3738             *errorCodeP = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
3739             return;
3740           }
3741           entity->open = 0;
3742           if (dtd.complete)
3743             break;
3744         }
3745       }
3746       if (!dtd.standalone
3747           && notStandaloneHandler
3748           && !notStandaloneHandler(handlerArg)) {
3749         *errorCodeP = XML_ERROR_NOT_STANDALONE;
3750         return;
3751       }
3752       dtd.complete = 0;
3753       if (defaultHandler)
3754         reportDefault(xmlParserP, enc, s, next);
3755       break;
3756     case XML_ROLE_NONE:
3757       switch (tok) {
3758       case XML_TOK_PI:
3759         if (!reportProcessingInstruction(xmlParserP, enc, s, next)) {
3760           *errorCodeP = XML_ERROR_NO_MEMORY;
3761           return;
3762         }
3763         break;
3764       case XML_TOK_COMMENT:
3765         if (!reportComment(xmlParserP, enc, s, next)) {
3766           *errorCodeP = XML_ERROR_NO_MEMORY;
3767           return;
3768         }
3769         break;
3770       }
3771       break;
3772     }
3773     if (defaultHandler) {
3774       switch (tok) {
3775       case XML_TOK_PI:
3776       case XML_TOK_COMMENT:
3777       case XML_TOK_BOM:
3778       case XML_TOK_XML_DECL:
3779       case XML_TOK_IGNORE_SECT:
3780       case XML_TOK_PARAM_ENTITY_REF:
3781         break;
3782       default:
3783         if (role != XML_ROLE_IGNORE_SECT)
3784           reportDefault(xmlParserP, enc, s, next);
3785       }
3786     }
3787     s = next;
3788     tok = XmlPrologTok(enc, s, end, &next);
3789   }
3790   /* not reached */
3791 }
3792 
3793 
3794 
3795 static Processor prologProcessor;
3796 
3797 static void
prologProcessor(XML_Parser const xmlParserP,const char * const s,const char * const end,const char ** const nextPtr,enum XML_Error * const errorCodeP,const char ** const errorP)3798 prologProcessor(XML_Parser       const xmlParserP,
3799                 const char *     const s,
3800                 const char *     const end,
3801                 const char **    const nextPtr,
3802                 enum XML_Error * const errorCodeP,
3803                 const char **    const errorP) {
3804 
3805     Parser * const parser = (Parser *) xmlParserP;
3806 
3807     const char * next;
3808     int tok;
3809 
3810     *errorP = NULL;
3811 
3812     tok = XmlPrologTok(parser->m_encoding, s, end, &next);
3813 
3814     doProlog(xmlParserP, parser->m_encoding, s, end, tok, next, nextPtr,
3815              errorCodeP, errorP);
3816 }
3817 
3818 
3819 
3820 static Processor prologInitProcessor;
3821 
3822 static void
prologInitProcessor(XML_Parser const parser,const char * const s,const char * const end,const char ** const nextPtr,enum XML_Error * const errorCodeP,const char ** const errorP)3823 prologInitProcessor(XML_Parser       const parser,
3824                     const char *     const s,
3825                     const char *     const end,
3826                     const char **    const nextPtr,
3827                     enum XML_Error * const errorCodeP,
3828                     const char **    const errorP) {
3829 
3830     enum XML_Error result;
3831 
3832     *errorP = NULL;
3833 
3834     result = initializeEncoding(parser);
3835 
3836     if (result != XML_ERROR_NONE)
3837         *errorCodeP = result;
3838     else {
3839         processor = prologProcessor;
3840         prologProcessor(parser, s, end, nextPtr, errorCodeP, errorP);
3841     }
3842 }
3843 
3844 
3845 
3846 static void
processInternalParamEntity(XML_Parser const parser,ENTITY * const entity,enum XML_Error * const errorCodeP,const char ** const errorP)3847 processInternalParamEntity(XML_Parser       const parser,
3848                            ENTITY *         const entity,
3849                            enum XML_Error * const errorCodeP,
3850                            const char **    const errorP) {
3851 
3852     const char *s, *end, *next;
3853     int tok;
3854     OPEN_INTERNAL_ENTITY openEntity;
3855 
3856     entity->open = 1;
3857     openEntity.next = openInternalEntities;
3858     openInternalEntities = &openEntity;
3859     openEntity.entity = entity;
3860     openEntity.internalEventPtr = 0;
3861     openEntity.internalEventEndPtr = 0;
3862     s = (char *)entity->textPtr;
3863     end = (char *)(entity->textPtr + entity->textLen);
3864     tok = XmlPrologTok(internalEncoding, s, end, &next);
3865 
3866     doProlog(parser, internalEncoding, s, end, tok, next, 0,
3867              errorCodeP, errorP);
3868 
3869     entity->open = 0;
3870     openInternalEntities = openEntity.next;
3871 }
3872 
3873 
3874 
3875 XML_Parser
xmlrpc_XML_ParserCreate(const XML_Char * const encodingName)3876 xmlrpc_XML_ParserCreate(const XML_Char * const encodingName) {
3877 
3878     XML_Parser const xmlParserP = malloc(sizeof(Parser));
3879     Parser * const parser = (Parser *)xmlParserP;
3880     if (xmlParserP) {
3881         processor = prologInitProcessor;
3882         xmlrpc_XmlPrologStateInit(&prologState);
3883         userData = 0;
3884         handlerArg = 0;
3885         startElementHandler = 0;
3886         endElementHandler = 0;
3887         characterDataHandler = 0;
3888         processingInstructionHandler = 0;
3889         commentHandler = 0;
3890         startCdataSectionHandler = 0;
3891         endCdataSectionHandler = 0;
3892         defaultHandler = 0;
3893         startDoctypeDeclHandler = 0;
3894         endDoctypeDeclHandler = 0;
3895         unparsedEntityDeclHandler = 0;
3896         notationDeclHandler = 0;
3897         externalParsedEntityDeclHandler = 0;
3898         internalParsedEntityDeclHandler = 0;
3899         startNamespaceDeclHandler = 0;
3900         endNamespaceDeclHandler = 0;
3901         notStandaloneHandler = 0;
3902         externalEntityRefHandler = 0;
3903         externalEntityRefHandlerArg = parser;
3904         unknownEncodingHandler = 0;
3905         buffer = 0;
3906         bufferPtr = 0;
3907         bufferEnd = 0;
3908         parseEndByteIndex = 0;
3909         parseEndPtr = 0;
3910         bufferLim = 0;
3911         declElementType = 0;
3912         declAttributeId = 0;
3913         declEntity = 0;
3914         declNotationName = 0;
3915         declNotationPublicId = 0;
3916         memset(&position, 0, sizeof(POSITION));
3917         errorCode = XML_ERROR_NONE;
3918         errorString = NULL;
3919         eventPtr = 0;
3920         eventEndPtr = 0;
3921         positionPtr = 0;
3922         openInternalEntities = 0;
3923         tagLevel = 0;
3924         tagStack = 0;
3925         freeTagList = 0;
3926         freeBindingList = 0;
3927         inheritedBindings = 0;
3928         attsSize = INIT_ATTS_SIZE;
3929         atts = malloc(attsSize * sizeof(ATTRIBUTE));
3930         nSpecifiedAtts = 0;
3931         dataBuf = malloc(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
3932         groupSize = 0;
3933         groupConnector = 0;
3934         hadExternalDoctype = 0;
3935         unknownEncodingMem = 0;
3936         unknownEncodingRelease = 0;
3937         unknownEncodingData = 0;
3938         unknownEncodingHandlerData = 0;
3939         namespaceSeparator = '!';
3940         parentParser = 0;
3941         paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
3942         ns = 0;
3943         poolInit(&tempPool);
3944         poolInit(&temp2Pool);
3945         protocolEncodingName =
3946             encodingName ? poolCopyString(&tempPool, encodingName) : 0;
3947         curBase = 0;
3948         if (!dtdInit(&dtd) || !atts || !dataBuf
3949             || (encodingName && !protocolEncodingName)) {
3950             xmlrpc_XML_ParserFree(xmlParserP);
3951             return 0;
3952         }
3953         dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
3954         xmlrpc_XmlInitEncoding(&parser->m_initEncoding,
3955                                &parser->m_encoding,
3956                                0);
3957         internalEncoding = XmlGetInternalEncoding();
3958     }
3959     return xmlParserP;
3960 }
3961 
3962 XML_Parser
xmlrpc_XML_ParserCreateNS(const XML_Char * const encodingName,XML_Char const nsSep)3963 xmlrpc_XML_ParserCreateNS(const XML_Char * const encodingName,
3964                           XML_Char         const nsSep) {
3965 
3966     static
3967         const XML_Char implicitContext[] = {
3968             XML_T('x'), XML_T('m'), XML_T('l'), XML_T('='),
3969             XML_T('h'), XML_T('t'), XML_T('t'), XML_T('p'), XML_T(':'),
3970             XML_T('/'), XML_T('/'), XML_T('w'), XML_T('w'), XML_T('w'),
3971             XML_T('.'), XML_T('w'), XML_T('3'),
3972             XML_T('.'), XML_T('o'), XML_T('r'), XML_T('g'),
3973             XML_T('/'), XML_T('X'), XML_T('M'), XML_T('L'),
3974             XML_T('/'), XML_T('1'), XML_T('9'), XML_T('9'), XML_T('8'),
3975             XML_T('/'), XML_T('n'), XML_T('a'), XML_T('m'), XML_T('e'),
3976             XML_T('s'), XML_T('p'), XML_T('a'), XML_T('c'), XML_T('e'),
3977             XML_T('\0')
3978         };
3979 
3980     XML_Parser const xmlParserP = xmlrpc_XML_ParserCreate(encodingName);
3981     Parser * const parser = (Parser *)xmlParserP;
3982     XML_Parser retval;
3983 
3984     if (xmlParserP) {
3985         int succeeded;
3986         xmlrpc_XmlInitEncodingNS(&initEncoding, &parser->m_encoding, 0);
3987         ns = 1;
3988         internalEncoding = XmlGetInternalEncodingNS();
3989         namespaceSeparator = nsSep;
3990 
3991         succeeded = setContext(xmlParserP, implicitContext);
3992         if (succeeded)
3993             retval = xmlParserP;
3994         else {
3995             xmlrpc_XML_ParserFree(xmlParserP);
3996             retval = NULL;
3997         }
3998     } else
3999         retval = NULL;
4000 
4001     return retval;
4002 }
4003 
4004 
4005 
4006 int
xmlrpc_XML_SetEncoding(XML_Parser parser,const XML_Char * encodingName)4007 xmlrpc_XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
4008 {
4009   if (!encodingName)
4010     protocolEncodingName = 0;
4011   else {
4012     protocolEncodingName = poolCopyString(&tempPool, encodingName);
4013     if (!protocolEncodingName)
4014       return 0;
4015   }
4016   return 1;
4017 }
4018 
4019 
4020 
4021 XML_Parser
xmlrpc_XML_ExternalEntityParserCreate(XML_Parser oldParser,const XML_Char * context,const XML_Char * encodingName)4022 xmlrpc_XML_ExternalEntityParserCreate(XML_Parser oldParser,
4023                                       const XML_Char *context,
4024                                       const XML_Char *encodingName)
4025 {
4026   XML_Parser parser = oldParser;
4027   DTD *oldDtd = &dtd;
4028   XML_StartElementHandler oldStartElementHandler = startElementHandler;
4029   XML_EndElementHandler oldEndElementHandler = endElementHandler;
4030   XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
4031   XML_ProcessingInstructionHandler oldProcessingInstructionHandler = processingInstructionHandler;
4032   XML_CommentHandler oldCommentHandler = commentHandler;
4033   XML_StartCdataSectionHandler oldStartCdataSectionHandler = startCdataSectionHandler;
4034   XML_EndCdataSectionHandler oldEndCdataSectionHandler = endCdataSectionHandler;
4035   XML_DefaultHandler oldDefaultHandler = defaultHandler;
4036   XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler = unparsedEntityDeclHandler;
4037   XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
4038   XML_ExternalParsedEntityDeclHandler oldExternalParsedEntityDeclHandler = externalParsedEntityDeclHandler;
4039   XML_InternalParsedEntityDeclHandler oldInternalParsedEntityDeclHandler = internalParsedEntityDeclHandler;
4040   XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler = startNamespaceDeclHandler;
4041   XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler = endNamespaceDeclHandler;
4042   XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
4043   XML_ExternalEntityRefHandler oldExternalEntityRefHandler = externalEntityRefHandler;
4044   XML_UnknownEncodingHandler oldUnknownEncodingHandler = unknownEncodingHandler;
4045   void *oldUserData = userData;
4046   void *oldHandlerArg = handlerArg;
4047   int oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
4048   void *oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
4049   int oldParamEntityParsing = paramEntityParsing;
4050   parser = (ns
4051             ? xmlrpc_XML_ParserCreateNS(encodingName, namespaceSeparator)
4052             : xmlrpc_XML_ParserCreate(encodingName));
4053   if (!parser)
4054     return 0;
4055   startElementHandler = oldStartElementHandler;
4056   endElementHandler = oldEndElementHandler;
4057   characterDataHandler = oldCharacterDataHandler;
4058   processingInstructionHandler = oldProcessingInstructionHandler;
4059   commentHandler = oldCommentHandler;
4060   startCdataSectionHandler = oldStartCdataSectionHandler;
4061   endCdataSectionHandler = oldEndCdataSectionHandler;
4062   defaultHandler = oldDefaultHandler;
4063   unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
4064   notationDeclHandler = oldNotationDeclHandler;
4065   externalParsedEntityDeclHandler = oldExternalParsedEntityDeclHandler;
4066   internalParsedEntityDeclHandler = oldInternalParsedEntityDeclHandler;
4067   startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
4068   endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
4069   notStandaloneHandler = oldNotStandaloneHandler;
4070   externalEntityRefHandler = oldExternalEntityRefHandler;
4071   unknownEncodingHandler = oldUnknownEncodingHandler;
4072   userData = oldUserData;
4073   if (oldUserData == oldHandlerArg)
4074     handlerArg = userData;
4075   else
4076     handlerArg = parser;
4077   if (oldExternalEntityRefHandlerArg != oldParser)
4078     externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
4079   defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
4080   paramEntityParsing = oldParamEntityParsing;
4081   if (context) {
4082     if (!dtdCopy(&dtd, oldDtd) || !setContext(parser, context)) {
4083       xmlrpc_XML_ParserFree(parser);
4084       return 0;
4085     }
4086     processor = externalEntityInitProcessor;
4087   }
4088   else {
4089     dtdSwap(&dtd, oldDtd);
4090     parentParser = oldParser;
4091     xmlrpc_XmlPrologStateInitExternalEntity(&prologState);
4092     dtd.complete = 1;
4093     hadExternalDoctype = 1;
4094   }
4095   return parser;
4096 }
4097 
4098 static
destroyBindings(BINDING * bindings)4099 void destroyBindings(BINDING *bindings)
4100 {
4101   for (;;) {
4102     BINDING *b = bindings;
4103     if (!b)
4104       break;
4105     bindings = b->nextTagBinding;
4106     free(b->uri);
4107     free(b);
4108   }
4109 }
4110 
4111 void
xmlrpc_XML_ParserFree(XML_Parser parser)4112 xmlrpc_XML_ParserFree(XML_Parser parser)
4113 {
4114   for (;;) {
4115     TAG *p;
4116     if (tagStack == 0) {
4117       if (freeTagList == 0)
4118         break;
4119       tagStack = freeTagList;
4120       freeTagList = 0;
4121     }
4122     p = tagStack;
4123     tagStack = tagStack->parent;
4124     free(p->buf);
4125     destroyBindings(p->bindings);
4126     free(p);
4127   }
4128   destroyBindings(freeBindingList);
4129   destroyBindings(inheritedBindings);
4130   poolDestroy(&tempPool);
4131   poolDestroy(&temp2Pool);
4132   if (parentParser) {
4133     if (hadExternalDoctype)
4134       dtd.complete = 0;
4135     dtdSwap(&dtd, &((Parser *)parentParser)->m_dtd);
4136   }
4137   dtdDestroy(&dtd);
4138   free((void *)atts);
4139   free(groupConnector);
4140   free(buffer);
4141   free(dataBuf);
4142   free(unknownEncodingMem);
4143   if (unknownEncodingRelease)
4144     unknownEncodingRelease(unknownEncodingData);
4145   if (errorString)
4146     xmlrpc_strfree(errorString);
4147   free(parser);
4148 }
4149 
4150 void
xmlrpc_XML_UseParserAsHandlerArg(XML_Parser parser)4151 xmlrpc_XML_UseParserAsHandlerArg(XML_Parser parser)
4152 {
4153   handlerArg = parser;
4154 }
4155 
4156 void
xmlrpc_XML_SetUserData(XML_Parser parser,void * p)4157 xmlrpc_XML_SetUserData(XML_Parser parser, void *p)
4158 {
4159   if (handlerArg == userData)
4160     handlerArg = userData = p;
4161   else
4162     userData = p;
4163 }
4164 
4165 int
xmlrpc_XML_SetBase(XML_Parser parser,const XML_Char * p)4166 xmlrpc_XML_SetBase(XML_Parser parser, const XML_Char *p)
4167 {
4168   if (p) {
4169     p = poolCopyString(&dtd.pool, p);
4170     if (!p)
4171       return 0;
4172     curBase = p;
4173   }
4174   else
4175     curBase = 0;
4176   return 1;
4177 }
4178 
4179 const XML_Char *
xmlrpc_XML_GetBase(XML_Parser parser)4180 xmlrpc_XML_GetBase(XML_Parser parser)
4181 {
4182   return curBase;
4183 }
4184 
4185 int
xmlrpc_XML_GetSpecifiedAttributeCount(XML_Parser parser)4186 xmlrpc_XML_GetSpecifiedAttributeCount(XML_Parser parser)
4187 {
4188   return nSpecifiedAtts;
4189 }
4190 
4191 int
xmlrpc_XML_GetIdAttributeIndex(XML_Parser parser)4192 xmlrpc_XML_GetIdAttributeIndex(XML_Parser parser)
4193 {
4194   return idAttIndex;
4195 }
4196 
4197 void
xmlrpc_XML_SetElementHandler(XML_Parser parser,XML_StartElementHandler start,XML_EndElementHandler end)4198 xmlrpc_XML_SetElementHandler(XML_Parser parser,
4199                              XML_StartElementHandler start,
4200                              XML_EndElementHandler end)
4201 {
4202   startElementHandler = start;
4203   endElementHandler = end;
4204 }
4205 
4206 void
xmlrpc_XML_SetCharacterDataHandler(XML_Parser parser,XML_CharacterDataHandler handler)4207 xmlrpc_XML_SetCharacterDataHandler(XML_Parser parser,
4208                                    XML_CharacterDataHandler handler)
4209 {
4210   characterDataHandler = handler;
4211 }
4212 
4213 void
xmlrpc_XML_SetProcessingInstructionHandler(XML_Parser parser,XML_ProcessingInstructionHandler handler)4214 xmlrpc_XML_SetProcessingInstructionHandler(
4215     XML_Parser parser,
4216     XML_ProcessingInstructionHandler handler)
4217 {
4218   processingInstructionHandler = handler;
4219 }
4220 
4221 void
xmlrpc_XML_SetCommentHandler(XML_Parser parser,XML_CommentHandler handler)4222 xmlrpc_XML_SetCommentHandler(XML_Parser parser,
4223                              XML_CommentHandler handler)
4224 {
4225   commentHandler = handler;
4226 }
4227 
4228 void
xmlrpc_XML_SetCdataSectionHandler(XML_Parser parser,XML_StartCdataSectionHandler start,XML_EndCdataSectionHandler end)4229 xmlrpc_XML_SetCdataSectionHandler(XML_Parser parser,
4230                                   XML_StartCdataSectionHandler start,
4231                                   XML_EndCdataSectionHandler end)
4232 {
4233   startCdataSectionHandler = start;
4234   endCdataSectionHandler = end;
4235 }
4236 
4237 void
xmlrpc_XML_SetDefaultHandler(XML_Parser parser,XML_DefaultHandler handler)4238 xmlrpc_XML_SetDefaultHandler(XML_Parser parser,
4239                              XML_DefaultHandler handler)
4240 {
4241   defaultHandler = handler;
4242   defaultExpandInternalEntities = 0;
4243 }
4244 
4245 void
xmlrpc_XML_SetDefaultHandlerExpand(XML_Parser parser,XML_DefaultHandler handler)4246 xmlrpc_XML_SetDefaultHandlerExpand(XML_Parser parser,
4247                                    XML_DefaultHandler handler)
4248 {
4249   defaultHandler = handler;
4250   defaultExpandInternalEntities = 1;
4251 }
4252 
4253 void
xmlrpc_XML_SetDoctypeDeclHandler(XML_Parser parser,XML_StartDoctypeDeclHandler start,XML_EndDoctypeDeclHandler end)4254 xmlrpc_XML_SetDoctypeDeclHandler(XML_Parser parser,
4255                                  XML_StartDoctypeDeclHandler start,
4256                                  XML_EndDoctypeDeclHandler end)
4257 {
4258   startDoctypeDeclHandler = start;
4259   endDoctypeDeclHandler = end;
4260 }
4261 
4262 void
xmlrpc_XML_SetUnparsedEntityDeclHandler(XML_Parser parser,XML_UnparsedEntityDeclHandler handler)4263 xmlrpc_XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
4264                                         XML_UnparsedEntityDeclHandler handler)
4265 {
4266   unparsedEntityDeclHandler = handler;
4267 }
4268 
4269 void
xmlrpc_XML_SetExternalParsedEntityDeclHandler(XML_Parser parser,XML_ExternalParsedEntityDeclHandler handler)4270 xmlrpc_XML_SetExternalParsedEntityDeclHandler(
4271     XML_Parser parser,
4272     XML_ExternalParsedEntityDeclHandler handler)
4273 {
4274   externalParsedEntityDeclHandler = handler;
4275 }
4276 
4277 void
xmlrpc_XML_SetInternalParsedEntityDeclHandler(XML_Parser parser,XML_InternalParsedEntityDeclHandler handler)4278 xmlrpc_XML_SetInternalParsedEntityDeclHandler(
4279     XML_Parser parser,
4280     XML_InternalParsedEntityDeclHandler handler)
4281 {
4282   internalParsedEntityDeclHandler = handler;
4283 }
4284 
4285 void
xmlrpc_XML_SetNotationDeclHandler(XML_Parser parser,XML_NotationDeclHandler handler)4286 xmlrpc_XML_SetNotationDeclHandler(XML_Parser parser,
4287                                   XML_NotationDeclHandler handler)
4288 {
4289   notationDeclHandler = handler;
4290 }
4291 
4292 void
xmlrpc_XML_SetNamespaceDeclHandler(XML_Parser parser,XML_StartNamespaceDeclHandler start,XML_EndNamespaceDeclHandler end)4293 xmlrpc_XML_SetNamespaceDeclHandler(XML_Parser parser,
4294                                    XML_StartNamespaceDeclHandler start,
4295                                    XML_EndNamespaceDeclHandler end)
4296 {
4297   startNamespaceDeclHandler = start;
4298   endNamespaceDeclHandler = end;
4299 }
4300 
4301 void
xmlrpc_XML_SetNotStandaloneHandler(XML_Parser parser,XML_NotStandaloneHandler handler)4302 xmlrpc_XML_SetNotStandaloneHandler(XML_Parser parser,
4303                                    XML_NotStandaloneHandler handler)
4304 {
4305   notStandaloneHandler = handler;
4306 }
4307 
4308 void
xmlrpc_XML_SetExternalEntityRefHandler(XML_Parser parser,XML_ExternalEntityRefHandler handler)4309 xmlrpc_XML_SetExternalEntityRefHandler(XML_Parser parser,
4310                                        XML_ExternalEntityRefHandler handler)
4311 {
4312   externalEntityRefHandler = handler;
4313 }
4314 
4315 void
xmlrpc_XML_SetExternalEntityRefHandlerArg(XML_Parser parser,void * arg)4316 xmlrpc_XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
4317 {
4318   if (arg)
4319     externalEntityRefHandlerArg = arg;
4320   else
4321     externalEntityRefHandlerArg = parser;
4322 }
4323 
4324 void
xmlrpc_XML_SetUnknownEncodingHandler(XML_Parser parser,XML_UnknownEncodingHandler handler,void * data)4325 xmlrpc_XML_SetUnknownEncodingHandler(XML_Parser parser,
4326                                      XML_UnknownEncodingHandler handler,
4327                                      void *data)
4328 {
4329   unknownEncodingHandler = handler;
4330   unknownEncodingHandlerData = data;
4331 }
4332 
4333 
4334 
4335 int
xmlrpc_XML_SetParamEntityParsing(XML_Parser const parser ATTR_UNUSED,enum XML_ParamEntityParsing const parsing)4336 xmlrpc_XML_SetParamEntityParsing(
4337     XML_Parser                  const parser  ATTR_UNUSED,
4338     enum XML_ParamEntityParsing const parsing) {
4339 
4340     int retval;
4341 
4342     paramEntityParsing = parsing;
4343     retval = 1;
4344 
4345     return retval;
4346 }
4347 
4348 
4349 
4350 static Processor errorProcessor;
4351 
4352 static void
errorProcessor(XML_Parser const parser ATTR_UNUSED,const char * const s ATTR_UNUSED,const char * const end ATTR_UNUSED,const char ** const nextPtr ATTR_UNUSED,enum XML_Error * const errorCodeP,const char ** const errorP)4353 errorProcessor(XML_Parser       const parser      ATTR_UNUSED,
4354                const char *     const s           ATTR_UNUSED,
4355                const char *     const end         ATTR_UNUSED,
4356                const char **    const nextPtr     ATTR_UNUSED,
4357                enum XML_Error * const errorCodeP,
4358                const char **    const errorP) {
4359 
4360     *errorP     = errorString;
4361     *errorCodeP = errorCode;
4362 }
4363 
4364 
4365 
4366 static void
parseFinalLen0(Parser * const parser,int * const retvalP)4367 parseFinalLen0(Parser * const parser,
4368                int *    const retvalP) {
4369 
4370     positionPtr = bufferPtr;
4371     parseEndPtr = bufferEnd;
4372 
4373     processor(parser, bufferPtr, bufferEnd, 0, &errorCode, &errorString);
4374 
4375     if (errorCode == XML_ERROR_NONE)
4376         *retvalP = 1;
4377     else {
4378         eventEndPtr = eventPtr;
4379         processor   = errorProcessor;
4380         *retvalP    = 0;
4381     }
4382 }
4383 
4384 
4385 
4386 static void
parseNoBuffer(Parser * const parser,const char * const s,size_t const len,bool const isFinal,int * const succeededP)4387 parseNoBuffer(Parser *     const parser,
4388               const char * const s,
4389               size_t       const len,
4390               bool         const isFinal,
4391               int *        const succeededP) {
4392 
4393     parseEndByteIndex += len;
4394     positionPtr = s;
4395 
4396     if (isFinal) {
4397         parseEndPtr = s + len;
4398         processor(parser, s, parseEndPtr, 0, &errorCode, &errorString);
4399         if (errorCode == XML_ERROR_NONE)
4400             *succeededP = true;
4401         else {
4402             eventEndPtr = eventPtr;
4403             processor = errorProcessor;
4404             *succeededP = false;
4405         }
4406     } else {
4407         const char * end;
4408 
4409         parseEndPtr = s + len;
4410         processor(parser, s, s + len, &end, &errorCode, &errorString);
4411         if (errorCode != XML_ERROR_NONE) {
4412             eventEndPtr = eventPtr;
4413             processor = errorProcessor;
4414             *succeededP = false;
4415         } else {
4416             int const nLeftOver = s + len - end;
4417             XmlUpdatePosition(parser->m_encoding, positionPtr, end, &position);
4418             if (nLeftOver > 0) {
4419                 if (buffer == 0 || nLeftOver > bufferLim - buffer) {
4420                     REALLOCARRAY(buffer, len * 2);
4421                     if (buffer)
4422                         bufferLim = buffer + len * 2;
4423                 }
4424 
4425                 if (buffer) {
4426                     memcpy(buffer, end, nLeftOver);
4427                     bufferPtr = buffer;
4428                     bufferEnd = buffer + nLeftOver;
4429                     *succeededP = true;
4430                 } else {
4431                     errorCode = XML_ERROR_NO_MEMORY;
4432                     eventPtr = eventEndPtr = 0;
4433                     processor = errorProcessor;
4434                     *succeededP = false;
4435                 }
4436             } else
4437                 *succeededP = true;
4438         }
4439     }
4440 }
4441 
4442 
4443 
4444 int
xmlrpc_XML_Parse(XML_Parser const xmlParserP,const char * const s,size_t const len,int const isFinal)4445 xmlrpc_XML_Parse(XML_Parser   const xmlParserP,
4446                  const char * const s,
4447                  size_t       const len,
4448                  int          const isFinal) {
4449 
4450     Parser * const parser = (Parser *) xmlParserP;
4451 
4452     int retval;
4453 
4454     if (errorString) {
4455         xmlrpc_strfree(errorString);
4456         errorString = NULL;
4457     }
4458 
4459     if (len == 0) {
4460         if (!isFinal)
4461             retval = 1;
4462         else
4463             parseFinalLen0(parser, &retval);
4464     } else if (bufferPtr == bufferEnd)
4465         parseNoBuffer(parser, s, len, isFinal, &retval);
4466     else {
4467         memcpy(xmlrpc_XML_GetBuffer(parser, len), s, len);
4468         retval = xmlrpc_XML_ParseBuffer(parser, len, isFinal);
4469     }
4470     return retval;
4471 }
4472 
4473 
4474 
4475 int
xmlrpc_XML_ParseBuffer(XML_Parser const xmlParserP,int const len,int const isFinal)4476 xmlrpc_XML_ParseBuffer(XML_Parser const xmlParserP,
4477                        int        const len,
4478                        int        const isFinal) {
4479 
4480     Parser * const parser = (Parser *)xmlParserP;
4481 
4482     const char * const start = bufferPtr;
4483 
4484     if (errorString) {
4485         xmlrpc_strfree(errorString);
4486         errorString = NULL;
4487     }
4488 
4489     positionPtr = start;
4490     bufferEnd += len;
4491     parseEndByteIndex += len;
4492     processor(xmlParserP, start, parseEndPtr = bufferEnd,
4493               isFinal ? (const char **)0 : &bufferPtr,
4494               &errorCode, &errorString);
4495     if (errorCode == XML_ERROR_NONE) {
4496         if (!isFinal)
4497             XmlUpdatePosition(parser->m_encoding, positionPtr, bufferPtr,
4498                               &position);
4499         return 1;
4500     } else {
4501         eventEndPtr = eventPtr;
4502         processor = errorProcessor;
4503         return 0;
4504     }
4505 }
4506 
4507 
4508 
4509 void *
xmlrpc_XML_GetBuffer(XML_Parser const xmlParserP,size_t const len)4510 xmlrpc_XML_GetBuffer(XML_Parser const xmlParserP,
4511                      size_t     const len) {
4512 
4513     Parser * const parser = (Parser *)xmlParserP;
4514 
4515     assert(bufferLim >= bufferEnd);
4516 
4517     if (len > (size_t)(bufferLim - bufferEnd)) {
4518         /* FIXME avoid integer overflow */
4519         size_t neededSize = len + (bufferEnd - bufferPtr);
4520         assert(bufferLim >= buffer);
4521         if (neededSize  <= (size_t)(bufferLim - buffer)) {
4522             memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
4523             bufferEnd = buffer + (bufferEnd - bufferPtr);
4524             bufferPtr = buffer;
4525         } else {
4526             size_t bufferSize;
4527             char * newBuf;
4528 
4529             bufferSize = bufferLim > bufferPtr ?
4530                 bufferLim - bufferPtr : INIT_BUFFER_SIZE;
4531 
4532             do {
4533                 bufferSize *= 2;
4534             } while (bufferSize < neededSize);
4535             newBuf = malloc(bufferSize);
4536             if (newBuf == 0) {
4537                 errorCode = XML_ERROR_NO_MEMORY;
4538                 return 0;
4539             }
4540             bufferLim = newBuf + bufferSize;
4541             if (bufferPtr) {
4542                 memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
4543                 free(buffer);
4544             }
4545             bufferEnd = newBuf + (bufferEnd - bufferPtr);
4546             bufferPtr = buffer = newBuf;
4547         }
4548     }
4549     return bufferEnd;
4550 }
4551 
4552 
4553 
4554 enum XML_Error
xmlrpc_XML_GetErrorCode(XML_Parser const parser)4555 xmlrpc_XML_GetErrorCode(XML_Parser const parser) {
4556 
4557     return errorCode;
4558 }
4559 
4560 
4561 
4562 const char *
xmlrpc_XML_GetErrorString(XML_Parser const parser)4563 xmlrpc_XML_GetErrorString(XML_Parser const parser) {
4564 
4565     if (errorString)
4566         return errorString;
4567     else if (errorCode == XML_ERROR_NONE)
4568         return NULL;
4569     else
4570         return xmlrpc_XML_ErrorString(errorCode);
4571 }
4572 
4573 
4574 
4575 long
xmlrpc_XML_GetCurrentByteIndex(XML_Parser const parser)4576 xmlrpc_XML_GetCurrentByteIndex(XML_Parser const parser) {
4577 
4578     long retval;
4579 
4580     if (eventPtr) {
4581         size_t const bytesLeft = parseEndPtr - eventPtr;
4582 
4583         if ((size_t)(long)(bytesLeft) != bytesLeft)
4584             retval = -1;
4585         else
4586             retval = parseEndByteIndex - (long)bytesLeft;
4587     } else
4588         retval = -1;
4589 
4590     return retval;
4591 }
4592 
4593 
4594 
4595 int
xmlrpc_XML_GetCurrentByteCount(XML_Parser const parser)4596 xmlrpc_XML_GetCurrentByteCount(XML_Parser const parser) {
4597 
4598     int retval;
4599 
4600     if (eventEndPtr && eventPtr) {
4601         size_t const byteCount = eventEndPtr - eventPtr;
4602 
4603         assert((size_t)(int)byteCount == byteCount);
4604 
4605         retval = (int)byteCount;
4606     } else
4607         retval = 0;
4608 
4609     return retval;
4610 }
4611 
4612 
4613 
4614 int
xmlrpc_XML_GetCurrentLineNumber(XML_Parser const xmlParserP)4615 xmlrpc_XML_GetCurrentLineNumber(XML_Parser const xmlParserP) {
4616 
4617     Parser * const parser = (Parser *) xmlParserP;
4618 
4619     if (eventPtr) {
4620         XmlUpdatePosition(parser->m_encoding, positionPtr, eventPtr,
4621                           &position);
4622         positionPtr = eventPtr;
4623     }
4624     return position.lineNumber + 1;
4625 }
4626 
4627 
4628 
4629 int
xmlrpc_XML_GetCurrentColumnNumber(XML_Parser const xmlParserP)4630 xmlrpc_XML_GetCurrentColumnNumber(XML_Parser const xmlParserP) {
4631 
4632     Parser * const parser = (Parser *) xmlParserP;
4633 
4634     if (eventPtr) {
4635         XmlUpdatePosition(parser->m_encoding, positionPtr, eventPtr,
4636                           &position);
4637         positionPtr = eventPtr;
4638     }
4639     return position.columnNumber;
4640 }
4641 
4642 
4643 
4644 void
xmlrpc_XML_DefaultCurrent(XML_Parser const xmlParserP)4645 xmlrpc_XML_DefaultCurrent(XML_Parser const xmlParserP) {
4646 
4647     Parser * const parser = (Parser *) xmlParserP;
4648 
4649     if (defaultHandler) {
4650         if (openInternalEntities)
4651             reportDefault(xmlParserP,
4652                           internalEncoding,
4653                           openInternalEntities->internalEventPtr,
4654                           openInternalEntities->internalEventEndPtr);
4655         else
4656             reportDefault(xmlParserP, parser->m_encoding,
4657                           eventPtr, eventEndPtr);
4658     }
4659 }
4660 
4661 const XML_LChar *
xmlrpc_XML_ErrorString(int const code)4662 xmlrpc_XML_ErrorString(int const code) {
4663 
4664     static const XML_LChar * const message[] = {
4665         /* NONE */                    NULL,
4666         /* NO_MEMORY */               XML_T("out of memory"),
4667         /* SYNTAX */                  XML_T("syntax error"),
4668         /* NO_ELEMENTS */             XML_T("no element found"),
4669         /* INVALID_TOKEN */           XML_T("not well-formed"),
4670         /* UNCLOSED_TOKEN */          XML_T("unclosed token"),
4671         /* PARTIAL_CHAR */            XML_T("unclosed token"),
4672         /* TAG_MISMATCH */            XML_T("mismatched tag"),
4673         /* DUPLICATE_ATTRIBUTE */     XML_T("duplicate attribute"),
4674         /* JUNK_AFTER_DOC_ELEMENT */  XML_T("junk after document element"),
4675         /* PARAM_ENTITY_REF */
4676              XML_T("illegal parameter entity reference"),
4677         /* UNDEFINED_ENTITY */        XML_T("undefined entity"),
4678         /* RECURSIVE_ENTITY_REF */    XML_T("recursive entity reference"),
4679         /* ASYNC_ENTITY */            XML_T("asynchronous entity"),
4680         /* BAD_CHAR_REF */
4681              XML_T("reference to invalid character number"),
4682         /* BINARY_ENTITY_REF */       XML_T("reference to binary entity"),
4683         /* ATTRIBUTE_EXTERNAL_ENTITY_REF */
4684              XML_T("reference to external entity in attribute"),
4685         /* MISPLACED_XML_PI */
4686              XML_T("xml processing instruction not at start "
4687                    "of external entity"),
4688         /* UNKNOWN_ENCODING */        XML_T("unknown encoding"),
4689         /* INCORRECT_ENCODING */
4690              XML_T("encoding specified in XML declaration is incorrect"),
4691         /* UNCLOSED_CDATA_SECTION */  XML_T("unclosed CDATA section"),
4692         /* EXTERNAL_ENTITY_HANDLING */
4693              XML_T("error in processing external entity reference"),
4694         /* NOT_STANDALONE */          XML_T("document is not standalone")
4695     };
4696 
4697     const XML_LChar * retval;
4698 
4699     if (code > 0 && (unsigned)code < ARRAY_SIZE(message))
4700         retval = message[code];
4701     else
4702         retval = NULL;
4703 
4704     return retval;
4705 }
4706