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