1 /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
2 See the file COPYING for copying permission.
3 */
4
5 #include <stddef.h>
6 #include <string.h> /* memset(), memcpy() */
7 #include <assert.h>
8 #include <limits.h> /* UINT_MAX */
9
10 #define XML_BUILDING_EXPAT 1
11
12 #include <libstudxml/details/expat/config.h>
13
14 #ifdef COMPILED_FROM_DSP
15 #define getpid GetCurrentProcessId
16 #else
17 #include <sys/time.h> /* gettimeofday() */
18 #include <sys/types.h> /* getpid() */
19 #include <unistd.h> /* getpid() */
20 #endif
21
22 #include <libstudxml/details/expat/ascii.h>
23 #include <libstudxml/details/expat/expat.h>
24
25 #ifdef XML_UNICODE
26 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
27 #define XmlConvert XmlUtf16Convert
28 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
29 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
30 #define XmlEncode XmlUtf16Encode
31 /* Using pointer subtraction to convert to integer type. */
32 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))
33 typedef unsigned short ICHAR;
34 #else
35 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
36 #define XmlConvert XmlUtf8Convert
37 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
38 #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
39 #define XmlEncode XmlUtf8Encode
40 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
41 typedef char ICHAR;
42 #endif
43
44
45 #ifndef XML_NS
46
47 #define XmlInitEncodingNS XmlInitEncoding
48 #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
49 #undef XmlGetInternalEncodingNS
50 #define XmlGetInternalEncodingNS XmlGetInternalEncoding
51 #define XmlParseXmlDeclNS XmlParseXmlDecl
52
53 #endif
54
55 #ifdef XML_UNICODE
56
57 #ifdef XML_UNICODE_WCHAR_T
58 #define XML_T(x) (const wchar_t)x
59 #define XML_L(x) L ## x
60 #else
61 #define XML_T(x) (const unsigned short)x
62 #define XML_L(x) x
63 #endif
64
65 #else
66
67 #define XML_T(x) x
68 #define XML_L(x) x
69
70 #endif
71
72 /* Round up n to be a multiple of sz, where sz is a power of 2. */
73 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
74
75 /* Handle the case where memmove() doesn't exist. */
76 #ifndef HAVE_MEMMOVE
77 #ifdef HAVE_BCOPY
78 #define memmove(d,s,l) bcopy((s),(d),(l))
79 #else
80 #error memmove does not exist on this platform, nor is a substitute available
81 #endif /* HAVE_BCOPY */
82 #endif /* HAVE_MEMMOVE */
83
84 #include <libstudxml/details/expat/internal.h>
85 #include <libstudxml/details/expat/xmltok.h>
86 #include <libstudxml/details/expat/xmlrole.h>
87
88 typedef const XML_Char *KEY;
89
90 typedef struct {
91 KEY name;
92 } NAMED;
93
94 typedef struct {
95 NAMED **v;
96 unsigned char power;
97 size_t size;
98 size_t used;
99 const XML_Memory_Handling_Suite *mem;
100 } HASH_TABLE;
101
102 /* Basic character hash algorithm, taken from Python's string hash:
103 h = h * 1000003 ^ character, the constant being a prime number.
104
105 */
106 #ifdef XML_UNICODE
107 #define CHAR_HASH(h, c) \
108 (((h) * 0xF4243) ^ (unsigned short)(c))
109 #else
110 #define CHAR_HASH(h, c) \
111 (((h) * 0xF4243) ^ (unsigned char)(c))
112 #endif
113
114 /* For probing (after a collision) we need a step size relative prime
115 to the hash table size, which is a power of 2. We use double-hashing,
116 since we can calculate a second hash value cheaply by taking those bits
117 of the first hash value that were discarded (masked out) when the table
118 index was calculated: index = hash & mask, where mask = table->size - 1.
119 We limit the maximum step size to table->size / 4 (mask >> 2) and make
120 it odd, since odd numbers are always relative prime to a power of 2.
121 */
122 #define SECOND_HASH(hash, mask, power) \
123 ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
124 #define PROBE_STEP(hash, mask, power) \
125 ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
126
127 typedef struct {
128 NAMED **p;
129 NAMED **end;
130 } HASH_TABLE_ITER;
131
132 #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
133 #define INIT_DATA_BUF_SIZE 1024
134 #define INIT_ATTS_SIZE 16
135 #define INIT_ATTS_VERSION 0xFFFFFFFF
136 #define INIT_BLOCK_SIZE 1024
137 #define INIT_BUFFER_SIZE 1024
138
139 #define EXPAND_SPARE 24
140
141 typedef struct binding {
142 struct prefix *prefix;
143 struct binding *nextTagBinding;
144 struct binding *prevPrefixBinding;
145 const struct attribute_id *attId;
146 XML_Char *uri;
147 int uriLen;
148 int uriAlloc;
149 } BINDING;
150
151 typedef struct prefix {
152 const XML_Char *name;
153 BINDING *binding;
154 } PREFIX;
155
156 typedef struct {
157 const XML_Char *str;
158 const XML_Char *localPart;
159 const XML_Char *prefix;
160 int strLen;
161 int uriLen;
162 int prefixLen;
163 } TAG_NAME;
164
165 /* TAG represents an open element.
166 The name of the element is stored in both the document and API
167 encodings. The memory buffer 'buf' is a separately-allocated
168 memory area which stores the name. During the XML_Parse()/
169 XMLParseBuffer() when the element is open, the memory for the 'raw'
170 version of the name (in the document encoding) is shared with the
171 document buffer. If the element is open across calls to
172 XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
173 contain the 'raw' name as well.
174
175 A parser re-uses these structures, maintaining a list of allocated
176 TAG objects in a free list.
177 */
178 typedef struct tag {
179 struct tag *parent; /* parent of this element */
180 const char *rawName; /* tagName in the original encoding */
181 int rawNameLength;
182 TAG_NAME name; /* tagName in the API encoding */
183 char *buf; /* buffer for name components */
184 char *bufEnd; /* end of the buffer */
185 BINDING *bindings;
186 } TAG;
187
188 typedef struct {
189 const XML_Char *name;
190 const XML_Char *textPtr;
191 int textLen; /* length in XML_Chars */
192 int processed; /* # of processed bytes - when suspended */
193 const XML_Char *systemId;
194 const XML_Char *base;
195 const XML_Char *publicId;
196 const XML_Char *notation;
197 XML_Bool open;
198 XML_Bool is_param;
199 XML_Bool is_internal; /* true if declared in internal subset outside PE */
200 } ENTITY;
201
202 typedef struct {
203 enum XML_Content_Type type;
204 enum XML_Content_Quant quant;
205 const XML_Char * name;
206 int firstchild;
207 int lastchild;
208 int childcnt;
209 int nextsib;
210 } CONTENT_SCAFFOLD;
211
212 #define INIT_SCAFFOLD_ELEMENTS 32
213
214 typedef struct block {
215 struct block *next;
216 int size;
217 XML_Char s[1];
218 } BLOCK;
219
220 typedef struct {
221 BLOCK *blocks;
222 BLOCK *freeBlocks;
223 const XML_Char *end;
224 XML_Char *ptr;
225 XML_Char *start;
226 const XML_Memory_Handling_Suite *mem;
227 } STRING_POOL;
228
229 /* The XML_Char before the name is used to determine whether
230 an attribute has been specified. */
231 typedef struct attribute_id {
232 XML_Char *name;
233 PREFIX *prefix;
234 XML_Bool maybeTokenized;
235 XML_Bool xmlns;
236 } ATTRIBUTE_ID;
237
238 typedef struct {
239 const ATTRIBUTE_ID *id;
240 XML_Bool isCdata;
241 const XML_Char *value;
242 } DEFAULT_ATTRIBUTE;
243
244 typedef struct {
245 unsigned long version;
246 size_t hash;
247 const XML_Char *uriName;
248 } NS_ATT;
249
250 typedef struct {
251 const XML_Char *name;
252 PREFIX *prefix;
253 const ATTRIBUTE_ID *idAtt;
254 int nDefaultAtts;
255 int allocDefaultAtts;
256 DEFAULT_ATTRIBUTE *defaultAtts;
257 } ELEMENT_TYPE;
258
259 typedef struct {
260 HASH_TABLE generalEntities;
261 HASH_TABLE elementTypes;
262 HASH_TABLE attributeIds;
263 HASH_TABLE prefixes;
264 STRING_POOL pool;
265 STRING_POOL entityValuePool;
266 /* false once a parameter entity reference has been skipped */
267 XML_Bool keepProcessing;
268 /* true once an internal or external PE reference has been encountered;
269 this includes the reference to an external subset */
270 XML_Bool hasParamEntityRefs;
271 XML_Bool standalone;
272 #ifdef XML_DTD
273 /* indicates if external PE has been read */
274 XML_Bool paramEntityRead;
275 HASH_TABLE paramEntities;
276 #endif /* XML_DTD */
277 PREFIX defaultPrefix;
278 /* === scaffolding for building content model === */
279 XML_Bool in_eldecl;
280 CONTENT_SCAFFOLD *scaffold;
281 unsigned contentStringLen;
282 unsigned scaffSize;
283 unsigned scaffCount;
284 int scaffLevel;
285 int *scaffIndex;
286 } DTD;
287
288 typedef struct open_internal_entity {
289 const char *internalEventPtr;
290 const char *internalEventEndPtr;
291 struct open_internal_entity *next;
292 ENTITY *entity;
293 int startTagLevel;
294 XML_Bool betweenDecl; /* WFC: PE Between Declarations */
295 } OPEN_INTERNAL_ENTITY;
296
297 typedef enum XML_Error PTRCALL Processor(XML_Parser parser,
298 const char *start,
299 const char *end,
300 const char **endPtr);
301
302 static Processor prologProcessor;
303 static Processor prologInitProcessor;
304 static Processor contentProcessor;
305 static Processor cdataSectionProcessor;
306 #ifdef XML_DTD
307 static Processor ignoreSectionProcessor;
308 static Processor externalParEntProcessor;
309 static Processor externalParEntInitProcessor;
310 static Processor entityValueProcessor;
311 static Processor entityValueInitProcessor;
312 #endif /* XML_DTD */
313 static Processor epilogProcessor;
314 static Processor errorProcessor;
315 static Processor externalEntityInitProcessor;
316 static Processor externalEntityInitProcessor2;
317 static Processor externalEntityInitProcessor3;
318 static Processor externalEntityContentProcessor;
319 static Processor internalEntityProcessor;
320
321 static enum XML_Error
322 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
323 static enum XML_Error
324 processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
325 const char *s, const char *next);
326 static enum XML_Error
327 initializeEncoding(XML_Parser parser);
328 static enum XML_Error
329 doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
330 const char *end, int tok, const char *next, const char **nextPtr,
331 XML_Bool haveMore, XML_Bool allowClosingDoctype);
332 static enum XML_Error
333 processInternalEntity(XML_Parser parser, ENTITY *entity,
334 XML_Bool betweenDecl);
335 static enum XML_Error
336 doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
337 const char *start, const char *end, const char **endPtr,
338 XML_Bool haveMore);
339 static enum XML_Error
340 doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
341 const char *end, const char **nextPtr, XML_Bool haveMore);
342 #ifdef XML_DTD
343 static enum XML_Error
344 doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
345 const char *end, const char **nextPtr, XML_Bool haveMore);
346 #endif /* XML_DTD */
347
348 static enum XML_Error
349 storeAtts(XML_Parser parser, const ENCODING *, const char *s,
350 TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
351 static enum XML_Error
352 addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
353 const XML_Char *uri, BINDING **bindingsPtr);
354 static int
355 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
356 XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
357 static enum XML_Error
358 storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
359 const char *, const char *, STRING_POOL *);
360 static enum XML_Error
361 appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
362 const char *, const char *, STRING_POOL *);
363 static ATTRIBUTE_ID *
364 getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
365 const char *end);
366 static int
367 setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
368 static enum XML_Error
369 storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
370 const char *end);
371 static int
372 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
373 const char *start, const char *end);
374 static int
375 reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
376 const char *end);
377 static void
378 reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,
379 const char *end);
380
381 static const XML_Char * getContext(XML_Parser parser);
382 static XML_Bool
383 setContext(XML_Parser parser, const XML_Char *context);
384
385 static void FASTCALL normalizePublicId(XML_Char *s);
386
387 static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
388 /* do not call if parentParser != NULL */
389 static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
390 static void
391 dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
392 static int
393 dtdCopy(XML_Parser oldParser,
394 DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
395 static int
396 copyEntityTable(XML_Parser oldParser,
397 HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
398 static NAMED *
399 lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize);
400 static void FASTCALL
401 hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
402 static void FASTCALL hashTableClear(HASH_TABLE *);
403 static void FASTCALL hashTableDestroy(HASH_TABLE *);
404 static void FASTCALL
405 hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
406 static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
407
408 static void FASTCALL
409 poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);
410 static void FASTCALL poolClear(STRING_POOL *);
411 static void FASTCALL poolDestroy(STRING_POOL *);
412 static XML_Char *
413 poolAppend(STRING_POOL *pool, const ENCODING *enc,
414 const char *ptr, const char *end);
415 static XML_Char *
416 poolStoreString(STRING_POOL *pool, const ENCODING *enc,
417 const char *ptr, const char *end);
418 static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
419 static const XML_Char * FASTCALL
420 poolCopyString(STRING_POOL *pool, const XML_Char *s);
421 static const XML_Char *
422 poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
423 static const XML_Char * FASTCALL
424 poolAppendString(STRING_POOL *pool, const XML_Char *s);
425
426 static int FASTCALL nextScaffoldPart(XML_Parser parser);
427 static XML_Content * build_model(XML_Parser parser);
428 static ELEMENT_TYPE *
429 getElementType(XML_Parser parser, const ENCODING *enc,
430 const char *ptr, const char *end);
431
432 static size_t generate_hash_secret_salt(XML_Parser parser);
433 static XML_Bool startParsing(XML_Parser parser);
434
435 static XML_Parser
436 parserCreate(const XML_Char *encodingName,
437 const XML_Memory_Handling_Suite *memsuite,
438 const XML_Char *nameSep,
439 DTD *dtd);
440
441 static void
442 parserInit(XML_Parser parser, const XML_Char *encodingName);
443
444 #define poolStart(pool) ((pool)->start)
445 #define poolEnd(pool) ((pool)->ptr)
446 #define poolLength(pool) ((pool)->ptr - (pool)->start)
447 #define poolChop(pool) ((void)--(pool->ptr))
448 #define poolLastChar(pool) (((pool)->ptr)[-1])
449 #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
450 #define poolFinish(pool) ((pool)->start = (pool)->ptr)
451 #define poolAppendChar(pool, c) \
452 (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
453 ? 0 \
454 : ((*((pool)->ptr)++ = c), 1))
455
456 struct XML_ParserStruct {
457 /* The first member must be userData so that the XML_GetUserData
458 macro works. */
459 void *m_userData;
460 void *m_handlerArg;
461 char *m_buffer;
462 const XML_Memory_Handling_Suite m_mem;
463 /* first character to be parsed */
464 const char *m_bufferPtr;
465 /* past last character to be parsed */
466 char *m_bufferEnd;
467 /* allocated end of buffer */
468 const char *m_bufferLim;
469 XML_Index m_parseEndByteIndex;
470 const char *m_parseEndPtr;
471 XML_Char *m_dataBuf;
472 XML_Char *m_dataBufEnd;
473 XML_StartElementHandler m_startElementHandler;
474 XML_EndElementHandler m_endElementHandler;
475 XML_CharacterDataHandler m_characterDataHandler;
476 XML_ProcessingInstructionHandler m_processingInstructionHandler;
477 XML_CommentHandler m_commentHandler;
478 XML_StartCdataSectionHandler m_startCdataSectionHandler;
479 XML_EndCdataSectionHandler m_endCdataSectionHandler;
480 XML_DefaultHandler m_defaultHandler;
481 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
482 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
483 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
484 XML_NotationDeclHandler m_notationDeclHandler;
485 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
486 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
487 XML_NotStandaloneHandler m_notStandaloneHandler;
488 XML_ExternalEntityRefHandler m_externalEntityRefHandler;
489 XML_Parser m_externalEntityRefHandlerArg;
490 XML_SkippedEntityHandler m_skippedEntityHandler;
491 XML_UnknownEncodingHandler m_unknownEncodingHandler;
492 XML_ElementDeclHandler m_elementDeclHandler;
493 XML_AttlistDeclHandler m_attlistDeclHandler;
494 XML_EntityDeclHandler m_entityDeclHandler;
495 XML_XmlDeclHandler m_xmlDeclHandler;
496 const ENCODING *m_encoding;
497 INIT_ENCODING m_initEncoding;
498 const ENCODING *m_internalEncoding;
499 const XML_Char *m_protocolEncodingName;
500 XML_Bool m_ns;
501 XML_Bool m_ns_triplets;
502 void *m_unknownEncodingMem;
503 void *m_unknownEncodingData;
504 void *m_unknownEncodingHandlerData;
505 void (XMLCALL *m_unknownEncodingRelease)(void *);
506 PROLOG_STATE m_prologState;
507 Processor *m_processor;
508 enum XML_Error m_errorCode;
509 const char *m_eventPtr;
510 const char *m_eventEndPtr;
511 const char *m_positionPtr;
512 OPEN_INTERNAL_ENTITY *m_openInternalEntities;
513 OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
514 XML_Bool m_defaultExpandInternalEntities;
515 int m_tagLevel;
516 ENTITY *m_declEntity;
517 const XML_Char *m_doctypeName;
518 const XML_Char *m_doctypeSysid;
519 const XML_Char *m_doctypePubid;
520 const XML_Char *m_declAttributeType;
521 const XML_Char *m_declNotationName;
522 const XML_Char *m_declNotationPublicId;
523 ELEMENT_TYPE *m_declElementType;
524 ATTRIBUTE_ID *m_declAttributeId;
525 XML_Bool m_declAttributeIsCdata;
526 XML_Bool m_declAttributeIsId;
527 DTD *m_dtd;
528 const XML_Char *m_curBase;
529 TAG *m_tagStack;
530 TAG *m_freeTagList;
531 BINDING *m_inheritedBindings;
532 BINDING *m_freeBindingList;
533 int m_attsSize;
534 int m_nSpecifiedAtts;
535 int m_idAttIndex;
536 ATTRIBUTE *m_atts;
537 NS_ATT *m_nsAtts;
538 unsigned long m_nsAttsVersion;
539 unsigned char m_nsAttsPower;
540 #ifdef XML_ATTR_INFO
541 XML_AttrInfo *m_attInfo;
542 #endif
543 POSITION m_position;
544 STRING_POOL m_tempPool;
545 STRING_POOL m_temp2Pool;
546 char *m_groupConnector;
547 unsigned int m_groupSize;
548 XML_Char m_namespaceSeparator;
549 XML_Parser m_parentParser;
550 XML_ParsingStatus m_parsingStatus;
551 #ifdef XML_DTD
552 XML_Bool m_isParamEntity;
553 XML_Bool m_useForeignDTD;
554 enum XML_ParamEntityParsing m_paramEntityParsing;
555 #endif
556 size_t m_hash_secret_salt;
557 };
558
559 #define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
560 #define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
561 #define FREE(p) (parser->m_mem.free_fcn((p)))
562
563 #define userData (parser->m_userData)
564 #define handlerArg (parser->m_handlerArg)
565 #define startElementHandler (parser->m_startElementHandler)
566 #define endElementHandler (parser->m_endElementHandler)
567 #define characterDataHandler (parser->m_characterDataHandler)
568 #define processingInstructionHandler \
569 (parser->m_processingInstructionHandler)
570 #define commentHandler (parser->m_commentHandler)
571 #define startCdataSectionHandler \
572 (parser->m_startCdataSectionHandler)
573 #define endCdataSectionHandler (parser->m_endCdataSectionHandler)
574 #define defaultHandler (parser->m_defaultHandler)
575 #define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
576 #define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
577 #define unparsedEntityDeclHandler \
578 (parser->m_unparsedEntityDeclHandler)
579 #define notationDeclHandler (parser->m_notationDeclHandler)
580 #define startNamespaceDeclHandler \
581 (parser->m_startNamespaceDeclHandler)
582 #define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
583 #define notStandaloneHandler (parser->m_notStandaloneHandler)
584 #define externalEntityRefHandler \
585 (parser->m_externalEntityRefHandler)
586 #define externalEntityRefHandlerArg \
587 (parser->m_externalEntityRefHandlerArg)
588 #define internalEntityRefHandler \
589 (parser->m_internalEntityRefHandler)
590 #define skippedEntityHandler (parser->m_skippedEntityHandler)
591 #define unknownEncodingHandler (parser->m_unknownEncodingHandler)
592 #define elementDeclHandler (parser->m_elementDeclHandler)
593 #define attlistDeclHandler (parser->m_attlistDeclHandler)
594 #define entityDeclHandler (parser->m_entityDeclHandler)
595 #define xmlDeclHandler (parser->m_xmlDeclHandler)
596 #define encoding (parser->m_encoding)
597 #define initEncoding (parser->m_initEncoding)
598 #define internalEncoding (parser->m_internalEncoding)
599 #define unknownEncodingMem (parser->m_unknownEncodingMem)
600 #define unknownEncodingData (parser->m_unknownEncodingData)
601 #define unknownEncodingHandlerData \
602 (parser->m_unknownEncodingHandlerData)
603 #define unknownEncodingRelease (parser->m_unknownEncodingRelease)
604 #define protocolEncodingName (parser->m_protocolEncodingName)
605 #define ns (parser->m_ns)
606 #define ns_triplets (parser->m_ns_triplets)
607 #define prologState (parser->m_prologState)
608 #define processor (parser->m_processor)
609 #define errorCode (parser->m_errorCode)
610 #define eventPtr (parser->m_eventPtr)
611 #define eventEndPtr (parser->m_eventEndPtr)
612 #define positionPtr (parser->m_positionPtr)
613 #define position (parser->m_position)
614 #define openInternalEntities (parser->m_openInternalEntities)
615 #define freeInternalEntities (parser->m_freeInternalEntities)
616 #define defaultExpandInternalEntities \
617 (parser->m_defaultExpandInternalEntities)
618 #define tagLevel (parser->m_tagLevel)
619 #define buffer (parser->m_buffer)
620 #define bufferPtr (parser->m_bufferPtr)
621 #define bufferEnd (parser->m_bufferEnd)
622 #define parseEndByteIndex (parser->m_parseEndByteIndex)
623 #define parseEndPtr (parser->m_parseEndPtr)
624 #define bufferLim (parser->m_bufferLim)
625 #define dataBuf (parser->m_dataBuf)
626 #define dataBufEnd (parser->m_dataBufEnd)
627 #define _dtd (parser->m_dtd)
628 #define curBase (parser->m_curBase)
629 #define declEntity (parser->m_declEntity)
630 #define doctypeName (parser->m_doctypeName)
631 #define doctypeSysid (parser->m_doctypeSysid)
632 #define doctypePubid (parser->m_doctypePubid)
633 #define declAttributeType (parser->m_declAttributeType)
634 #define declNotationName (parser->m_declNotationName)
635 #define declNotationPublicId (parser->m_declNotationPublicId)
636 #define declElementType (parser->m_declElementType)
637 #define declAttributeId (parser->m_declAttributeId)
638 #define declAttributeIsCdata (parser->m_declAttributeIsCdata)
639 #define declAttributeIsId (parser->m_declAttributeIsId)
640 #define freeTagList (parser->m_freeTagList)
641 #define freeBindingList (parser->m_freeBindingList)
642 #define inheritedBindings (parser->m_inheritedBindings)
643 #define tagStack (parser->m_tagStack)
644 #define atts (parser->m_atts)
645 #define attsSize (parser->m_attsSize)
646 #define nSpecifiedAtts (parser->m_nSpecifiedAtts)
647 #define idAttIndex (parser->m_idAttIndex)
648 #define nsAtts (parser->m_nsAtts)
649 #define nsAttsVersion (parser->m_nsAttsVersion)
650 #define nsAttsPower (parser->m_nsAttsPower)
651 #define attInfo (parser->m_attInfo)
652 #define tempPool (parser->m_tempPool)
653 #define temp2Pool (parser->m_temp2Pool)
654 #define groupConnector (parser->m_groupConnector)
655 #define groupSize (parser->m_groupSize)
656 #define namespaceSeparator (parser->m_namespaceSeparator)
657 #define parentParser (parser->m_parentParser)
658 #define ps_parsing (parser->m_parsingStatus.parsing)
659 #define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)
660 #ifdef XML_DTD
661 #define isParamEntity (parser->m_isParamEntity)
662 #define useForeignDTD (parser->m_useForeignDTD)
663 #define paramEntityParsing (parser->m_paramEntityParsing)
664 #endif /* XML_DTD */
665 #define hash_secret_salt (parser->m_hash_secret_salt)
666
667 XML_Parser XMLCALL
XML_ParserCreate(const XML_Char * encodingName)668 XML_ParserCreate(const XML_Char *encodingName)
669 {
670 return XML_ParserCreate_MM(encodingName, NULL, NULL);
671 }
672
673 XML_Parser XMLCALL
XML_ParserCreateNS(const XML_Char * encodingName,XML_Char nsSep)674 XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
675 {
676 XML_Char tmp[2];
677 *tmp = nsSep;
678 return XML_ParserCreate_MM(encodingName, NULL, tmp);
679 }
680
681 static const XML_Char implicitContext[] = {
682 ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p,
683 ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w,
684 ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g,
685 ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9,
686 ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e,
687 ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'
688 };
689
690 static size_t
gather_time_entropy(void)691 gather_time_entropy(void)
692 {
693 #ifdef COMPILED_FROM_DSP
694 FILETIME ft;
695 GetSystemTimeAsFileTime(&ft); /* never fails */
696 return ft.dwHighDateTime ^ ft.dwLowDateTime;
697 #else
698 struct timeval tv;
699 int gettimeofday_res;
700
701 gettimeofday_res = gettimeofday(&tv, NULL);
702 assert (gettimeofday_res == 0);
703
704 /* Microseconds time is <20 bits entropy */
705 return tv.tv_usec;
706 #endif
707 }
708
709 static size_t
generate_hash_secret_salt(XML_Parser parser)710 generate_hash_secret_salt(XML_Parser parser)
711 {
712 /* Process ID is 0 bits entropy if attacker has local access
713 * XML_Parser address is few bits of entropy if attacker has local access */
714 const size_t entropy =
715 gather_time_entropy() ^ getpid() ^ (size_t)parser;
716
717 /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */
718 if (sizeof(size_t) == 4) {
719 return entropy * (size_t)2147483647;
720 } else {
721 return entropy * (size_t)2305843009213693951;
722 }
723 }
724
725 static XML_Bool /* only valid for root parser */
startParsing(XML_Parser parser)726 startParsing(XML_Parser parser)
727 {
728 /* hash functions must be initialized before setContext() is called */
729 if (hash_secret_salt == 0)
730 hash_secret_salt = generate_hash_secret_salt(parser);
731 if (ns) {
732 /* implicit context only set for root parser, since child
733 parsers (i.e. external entity parsers) will inherit it
734 */
735 return setContext(parser, implicitContext);
736 }
737 return XML_TRUE;
738 }
739
740 XML_Parser XMLCALL
XML_ParserCreate_MM(const XML_Char * encodingName,const XML_Memory_Handling_Suite * memsuite,const XML_Char * nameSep)741 XML_ParserCreate_MM(const XML_Char *encodingName,
742 const XML_Memory_Handling_Suite *memsuite,
743 const XML_Char *nameSep)
744 {
745 return parserCreate(encodingName, memsuite, nameSep, NULL);
746 }
747
748 static XML_Parser
parserCreate(const XML_Char * encodingName,const XML_Memory_Handling_Suite * memsuite,const XML_Char * nameSep,DTD * dtd)749 parserCreate(const XML_Char *encodingName,
750 const XML_Memory_Handling_Suite *memsuite,
751 const XML_Char *nameSep,
752 DTD *dtd)
753 {
754 XML_Parser parser;
755
756 if (memsuite) {
757 XML_Memory_Handling_Suite *mtemp;
758 parser = (XML_Parser)
759 memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
760 if (parser != NULL) {
761 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
762 mtemp->malloc_fcn = memsuite->malloc_fcn;
763 mtemp->realloc_fcn = memsuite->realloc_fcn;
764 mtemp->free_fcn = memsuite->free_fcn;
765 }
766 }
767 else {
768 XML_Memory_Handling_Suite *mtemp;
769 parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
770 if (parser != NULL) {
771 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
772 mtemp->malloc_fcn = malloc;
773 mtemp->realloc_fcn = realloc;
774 mtemp->free_fcn = free;
775 }
776 }
777
778 if (!parser)
779 return parser;
780
781 buffer = NULL;
782 bufferLim = NULL;
783
784 attsSize = INIT_ATTS_SIZE;
785 atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));
786 if (atts == NULL) {
787 FREE(parser);
788 return NULL;
789 }
790 #ifdef XML_ATTR_INFO
791 attInfo = (XML_AttrInfo*)MALLOC(attsSize * sizeof(XML_AttrInfo));
792 if (attInfo == NULL) {
793 FREE(atts);
794 FREE(parser);
795 return NULL;
796 }
797 #endif
798 dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
799 if (dataBuf == NULL) {
800 FREE(atts);
801 #ifdef XML_ATTR_INFO
802 FREE(attInfo);
803 #endif
804 FREE(parser);
805 return NULL;
806 }
807 dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
808
809 if (dtd)
810 _dtd = dtd;
811 else {
812 _dtd = dtdCreate(&parser->m_mem);
813 if (_dtd == NULL) {
814 FREE(dataBuf);
815 FREE(atts);
816 #ifdef XML_ATTR_INFO
817 FREE(attInfo);
818 #endif
819 FREE(parser);
820 return NULL;
821 }
822 }
823
824 freeBindingList = NULL;
825 freeTagList = NULL;
826 freeInternalEntities = NULL;
827
828 groupSize = 0;
829 groupConnector = NULL;
830
831 unknownEncodingHandler = NULL;
832 unknownEncodingHandlerData = NULL;
833
834 namespaceSeparator = ASCII_EXCL;
835 ns = XML_FALSE;
836 ns_triplets = XML_FALSE;
837
838 nsAtts = NULL;
839 nsAttsVersion = 0;
840 nsAttsPower = 0;
841
842 poolInit(&tempPool, &(parser->m_mem));
843 poolInit(&temp2Pool, &(parser->m_mem));
844 parserInit(parser, encodingName);
845
846 if (encodingName && !protocolEncodingName) {
847 XML_ParserFree(parser);
848 return NULL;
849 }
850
851 if (nameSep) {
852 ns = XML_TRUE;
853 internalEncoding = XmlGetInternalEncodingNS();
854 namespaceSeparator = *nameSep;
855 }
856 else {
857 internalEncoding = XmlGetInternalEncoding();
858 }
859
860 return parser;
861 }
862
863 static void
parserInit(XML_Parser parser,const XML_Char * encodingName)864 parserInit(XML_Parser parser, const XML_Char *encodingName)
865 {
866 processor = prologInitProcessor;
867 XmlPrologStateInit(&prologState);
868 protocolEncodingName = (encodingName != NULL
869 ? poolCopyString(&tempPool, encodingName)
870 : NULL);
871 curBase = NULL;
872 XmlInitEncoding(&initEncoding, &encoding, 0);
873 userData = NULL;
874 handlerArg = NULL;
875 startElementHandler = NULL;
876 endElementHandler = NULL;
877 characterDataHandler = NULL;
878 processingInstructionHandler = NULL;
879 commentHandler = NULL;
880 startCdataSectionHandler = NULL;
881 endCdataSectionHandler = NULL;
882 defaultHandler = NULL;
883 startDoctypeDeclHandler = NULL;
884 endDoctypeDeclHandler = NULL;
885 unparsedEntityDeclHandler = NULL;
886 notationDeclHandler = NULL;
887 startNamespaceDeclHandler = NULL;
888 endNamespaceDeclHandler = NULL;
889 notStandaloneHandler = NULL;
890 externalEntityRefHandler = NULL;
891 externalEntityRefHandlerArg = parser;
892 skippedEntityHandler = NULL;
893 elementDeclHandler = NULL;
894 attlistDeclHandler = NULL;
895 entityDeclHandler = NULL;
896 xmlDeclHandler = NULL;
897 bufferPtr = buffer;
898 bufferEnd = buffer;
899 parseEndByteIndex = 0;
900 parseEndPtr = NULL;
901 declElementType = NULL;
902 declAttributeId = NULL;
903 declEntity = NULL;
904 doctypeName = NULL;
905 doctypeSysid = NULL;
906 doctypePubid = NULL;
907 declAttributeType = NULL;
908 declNotationName = NULL;
909 declNotationPublicId = NULL;
910 declAttributeIsCdata = XML_FALSE;
911 declAttributeIsId = XML_FALSE;
912 memset(&position, 0, sizeof(POSITION));
913 errorCode = XML_ERROR_NONE;
914 eventPtr = NULL;
915 eventEndPtr = NULL;
916 positionPtr = NULL;
917 openInternalEntities = NULL;
918 defaultExpandInternalEntities = XML_TRUE;
919 tagLevel = 0;
920 tagStack = NULL;
921 inheritedBindings = NULL;
922 nSpecifiedAtts = 0;
923 unknownEncodingMem = NULL;
924 unknownEncodingRelease = NULL;
925 unknownEncodingData = NULL;
926 parentParser = NULL;
927 ps_parsing = XML_INITIALIZED;
928 #ifdef XML_DTD
929 isParamEntity = XML_FALSE;
930 useForeignDTD = XML_FALSE;
931 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
932 #endif
933 hash_secret_salt = 0;
934 }
935
936 /* moves list of bindings to freeBindingList */
937 static void FASTCALL
moveToFreeBindingList(XML_Parser parser,BINDING * bindings)938 moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
939 {
940 while (bindings) {
941 BINDING *b = bindings;
942 bindings = bindings->nextTagBinding;
943 b->nextTagBinding = freeBindingList;
944 freeBindingList = b;
945 }
946 }
947
948 XML_Bool XMLCALL
XML_ParserReset(XML_Parser parser,const XML_Char * encodingName)949 XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
950 {
951 TAG *tStk;
952 OPEN_INTERNAL_ENTITY *openEntityList;
953 if (parentParser)
954 return XML_FALSE;
955 /* move tagStack to freeTagList */
956 tStk = tagStack;
957 while (tStk) {
958 TAG *tag = tStk;
959 tStk = tStk->parent;
960 tag->parent = freeTagList;
961 moveToFreeBindingList(parser, tag->bindings);
962 tag->bindings = NULL;
963 freeTagList = tag;
964 }
965 /* move openInternalEntities to freeInternalEntities */
966 openEntityList = openInternalEntities;
967 while (openEntityList) {
968 OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
969 openEntityList = openEntity->next;
970 openEntity->next = freeInternalEntities;
971 freeInternalEntities = openEntity;
972 }
973 moveToFreeBindingList(parser, inheritedBindings);
974 FREE(unknownEncodingMem);
975 if (unknownEncodingRelease)
976 unknownEncodingRelease(unknownEncodingData);
977 poolClear(&tempPool);
978 poolClear(&temp2Pool);
979 parserInit(parser, encodingName);
980 dtdReset(_dtd, &parser->m_mem);
981 return XML_TRUE;
982 }
983
984 enum XML_Status XMLCALL
XML_SetEncoding(XML_Parser parser,const XML_Char * encodingName)985 XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
986 {
987 /* Block after XML_Parse()/XML_ParseBuffer() has been called.
988 XXX There's no way for the caller to determine which of the
989 XXX possible error cases caused the XML_STATUS_ERROR return.
990 */
991 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
992 return XML_STATUS_ERROR;
993 if (encodingName == NULL)
994 protocolEncodingName = NULL;
995 else {
996 protocolEncodingName = poolCopyString(&tempPool, encodingName);
997 if (!protocolEncodingName)
998 return XML_STATUS_ERROR;
999 }
1000 return XML_STATUS_OK;
1001 }
1002
1003 XML_Parser XMLCALL
XML_ExternalEntityParserCreate(XML_Parser oldParser,const XML_Char * context,const XML_Char * encodingName)1004 XML_ExternalEntityParserCreate(XML_Parser oldParser,
1005 const XML_Char *context,
1006 const XML_Char *encodingName)
1007 {
1008 XML_Parser parser = oldParser;
1009 DTD *newDtd = NULL;
1010 DTD *oldDtd = _dtd;
1011 XML_StartElementHandler oldStartElementHandler = startElementHandler;
1012 XML_EndElementHandler oldEndElementHandler = endElementHandler;
1013 XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
1014 XML_ProcessingInstructionHandler oldProcessingInstructionHandler
1015 = processingInstructionHandler;
1016 XML_CommentHandler oldCommentHandler = commentHandler;
1017 XML_StartCdataSectionHandler oldStartCdataSectionHandler
1018 = startCdataSectionHandler;
1019 XML_EndCdataSectionHandler oldEndCdataSectionHandler
1020 = endCdataSectionHandler;
1021 XML_DefaultHandler oldDefaultHandler = defaultHandler;
1022 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
1023 = unparsedEntityDeclHandler;
1024 XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
1025 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
1026 = startNamespaceDeclHandler;
1027 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
1028 = endNamespaceDeclHandler;
1029 XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
1030 XML_ExternalEntityRefHandler oldExternalEntityRefHandler
1031 = externalEntityRefHandler;
1032 XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
1033 XML_UnknownEncodingHandler oldUnknownEncodingHandler
1034 = unknownEncodingHandler;
1035 XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
1036 XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
1037 XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
1038 XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
1039 ELEMENT_TYPE * oldDeclElementType = declElementType;
1040
1041 void *oldUserData = userData;
1042 void *oldHandlerArg = handlerArg;
1043 XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
1044 XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
1045 #ifdef XML_DTD
1046 enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
1047 int oldInEntityValue = prologState.inEntityValue;
1048 #endif
1049 XML_Bool oldns_triplets = ns_triplets;
1050 /* Note that the new parser shares the same hash secret as the old
1051 parser, so that dtdCopy and copyEntityTable can lookup values
1052 from hash tables associated with either parser without us having
1053 to worry which hash secrets each table has.
1054 */
1055 size_t oldhash_secret_salt = hash_secret_salt;
1056
1057 #ifdef XML_DTD
1058 if (!context)
1059 newDtd = oldDtd;
1060 #endif /* XML_DTD */
1061
1062 /* Note that the magical uses of the pre-processor to make field
1063 access look more like C++ require that `parser' be overwritten
1064 here. This makes this function more painful to follow than it
1065 would be otherwise.
1066 */
1067 if (ns) {
1068 XML_Char tmp[2];
1069 *tmp = namespaceSeparator;
1070 parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
1071 }
1072 else {
1073 parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
1074 }
1075
1076 if (!parser)
1077 return NULL;
1078
1079 startElementHandler = oldStartElementHandler;
1080 endElementHandler = oldEndElementHandler;
1081 characterDataHandler = oldCharacterDataHandler;
1082 processingInstructionHandler = oldProcessingInstructionHandler;
1083 commentHandler = oldCommentHandler;
1084 startCdataSectionHandler = oldStartCdataSectionHandler;
1085 endCdataSectionHandler = oldEndCdataSectionHandler;
1086 defaultHandler = oldDefaultHandler;
1087 unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
1088 notationDeclHandler = oldNotationDeclHandler;
1089 startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
1090 endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
1091 notStandaloneHandler = oldNotStandaloneHandler;
1092 externalEntityRefHandler = oldExternalEntityRefHandler;
1093 skippedEntityHandler = oldSkippedEntityHandler;
1094 unknownEncodingHandler = oldUnknownEncodingHandler;
1095 elementDeclHandler = oldElementDeclHandler;
1096 attlistDeclHandler = oldAttlistDeclHandler;
1097 entityDeclHandler = oldEntityDeclHandler;
1098 xmlDeclHandler = oldXmlDeclHandler;
1099 declElementType = oldDeclElementType;
1100 userData = oldUserData;
1101 if (oldUserData == oldHandlerArg)
1102 handlerArg = userData;
1103 else
1104 handlerArg = parser;
1105 if (oldExternalEntityRefHandlerArg != oldParser)
1106 externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
1107 defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
1108 ns_triplets = oldns_triplets;
1109 hash_secret_salt = oldhash_secret_salt;
1110 parentParser = oldParser;
1111 #ifdef XML_DTD
1112 paramEntityParsing = oldParamEntityParsing;
1113 prologState.inEntityValue = oldInEntityValue;
1114 if (context) {
1115 #endif /* XML_DTD */
1116 if (!dtdCopy(oldParser, _dtd, oldDtd, &parser->m_mem)
1117 || !setContext(parser, context)) {
1118 XML_ParserFree(parser);
1119 return NULL;
1120 }
1121 processor = externalEntityInitProcessor;
1122 #ifdef XML_DTD
1123 }
1124 else {
1125 /* The DTD instance referenced by _dtd is shared between the document's
1126 root parser and external PE parsers, therefore one does not need to
1127 call setContext. In addition, one also *must* not call setContext,
1128 because this would overwrite existing prefix->binding pointers in
1129 _dtd with ones that get destroyed with the external PE parser.
1130 This would leave those prefixes with dangling pointers.
1131 */
1132 isParamEntity = XML_TRUE;
1133 XmlPrologStateInitExternalEntity(&prologState);
1134 processor = externalParEntInitProcessor;
1135 }
1136 #endif /* XML_DTD */
1137 return parser;
1138 }
1139
1140 static void FASTCALL
destroyBindings(BINDING * bindings,XML_Parser parser)1141 destroyBindings(BINDING *bindings, XML_Parser parser)
1142 {
1143 for (;;) {
1144 BINDING *b = bindings;
1145 if (!b)
1146 break;
1147 bindings = b->nextTagBinding;
1148 FREE(b->uri);
1149 FREE(b);
1150 }
1151 }
1152
1153 void XMLCALL
XML_ParserFree(XML_Parser parser)1154 XML_ParserFree(XML_Parser parser)
1155 {
1156 TAG *tagList;
1157 OPEN_INTERNAL_ENTITY *entityList;
1158 if (parser == NULL)
1159 return;
1160 /* free tagStack and freeTagList */
1161 tagList = tagStack;
1162 for (;;) {
1163 TAG *p;
1164 if (tagList == NULL) {
1165 if (freeTagList == NULL)
1166 break;
1167 tagList = freeTagList;
1168 freeTagList = NULL;
1169 }
1170 p = tagList;
1171 tagList = tagList->parent;
1172 FREE(p->buf);
1173 destroyBindings(p->bindings, parser);
1174 FREE(p);
1175 }
1176 /* free openInternalEntities and freeInternalEntities */
1177 entityList = openInternalEntities;
1178 for (;;) {
1179 OPEN_INTERNAL_ENTITY *openEntity;
1180 if (entityList == NULL) {
1181 if (freeInternalEntities == NULL)
1182 break;
1183 entityList = freeInternalEntities;
1184 freeInternalEntities = NULL;
1185 }
1186 openEntity = entityList;
1187 entityList = entityList->next;
1188 FREE(openEntity);
1189 }
1190
1191 destroyBindings(freeBindingList, parser);
1192 destroyBindings(inheritedBindings, parser);
1193 poolDestroy(&tempPool);
1194 poolDestroy(&temp2Pool);
1195 #ifdef XML_DTD
1196 /* external parameter entity parsers share the DTD structure
1197 parser->m_dtd with the root parser, so we must not destroy it
1198 */
1199 if (!isParamEntity && _dtd)
1200 #else
1201 if (_dtd)
1202 #endif /* XML_DTD */
1203 dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
1204 FREE((void *)atts);
1205 #ifdef XML_ATTR_INFO
1206 FREE((void *)attInfo);
1207 #endif
1208 FREE(groupConnector);
1209 FREE(buffer);
1210 FREE(dataBuf);
1211 FREE(nsAtts);
1212 FREE(unknownEncodingMem);
1213 if (unknownEncodingRelease)
1214 unknownEncodingRelease(unknownEncodingData);
1215 FREE(parser);
1216 }
1217
1218 void XMLCALL
XML_UseParserAsHandlerArg(XML_Parser parser)1219 XML_UseParserAsHandlerArg(XML_Parser parser)
1220 {
1221 handlerArg = parser;
1222 }
1223
1224 enum XML_Error XMLCALL
XML_UseForeignDTD(XML_Parser parser,XML_Bool useDTD)1225 XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
1226 {
1227 #ifdef XML_DTD
1228 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1229 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
1230 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
1231 useForeignDTD = useDTD;
1232 return XML_ERROR_NONE;
1233 #else
1234 return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
1235 #endif
1236 }
1237
1238 void XMLCALL
XML_SetReturnNSTriplet(XML_Parser parser,int do_nst)1239 XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
1240 {
1241 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1242 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
1243 return;
1244 ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
1245 }
1246
1247 void XMLCALL
XML_SetUserData(XML_Parser parser,void * p)1248 XML_SetUserData(XML_Parser parser, void *p)
1249 {
1250 if (handlerArg == userData)
1251 handlerArg = userData = p;
1252 else
1253 userData = p;
1254 }
1255
1256 enum XML_Status XMLCALL
XML_SetBase(XML_Parser parser,const XML_Char * p)1257 XML_SetBase(XML_Parser parser, const XML_Char *p)
1258 {
1259 if (p) {
1260 p = poolCopyString(&_dtd->pool, p);
1261 if (!p)
1262 return XML_STATUS_ERROR;
1263 curBase = p;
1264 }
1265 else
1266 curBase = NULL;
1267 return XML_STATUS_OK;
1268 }
1269
1270 const XML_Char * XMLCALL
XML_GetBase(XML_Parser parser)1271 XML_GetBase(XML_Parser parser)
1272 {
1273 return curBase;
1274 }
1275
1276 int XMLCALL
XML_GetSpecifiedAttributeCount(XML_Parser parser)1277 XML_GetSpecifiedAttributeCount(XML_Parser parser)
1278 {
1279 return nSpecifiedAtts;
1280 }
1281
1282 int XMLCALL
XML_GetIdAttributeIndex(XML_Parser parser)1283 XML_GetIdAttributeIndex(XML_Parser parser)
1284 {
1285 return idAttIndex;
1286 }
1287
1288 #ifdef XML_ATTR_INFO
1289 const XML_AttrInfo * XMLCALL
XML_GetAttributeInfo(XML_Parser parser)1290 XML_GetAttributeInfo(XML_Parser parser)
1291 {
1292 return attInfo;
1293 }
1294 #endif
1295
1296 void XMLCALL
XML_SetElementHandler(XML_Parser parser,XML_StartElementHandler start,XML_EndElementHandler end)1297 XML_SetElementHandler(XML_Parser parser,
1298 XML_StartElementHandler start,
1299 XML_EndElementHandler end)
1300 {
1301 startElementHandler = start;
1302 endElementHandler = end;
1303 }
1304
1305 void XMLCALL
XML_SetStartElementHandler(XML_Parser parser,XML_StartElementHandler start)1306 XML_SetStartElementHandler(XML_Parser parser,
1307 XML_StartElementHandler start) {
1308 startElementHandler = start;
1309 }
1310
1311 void XMLCALL
XML_SetEndElementHandler(XML_Parser parser,XML_EndElementHandler end)1312 XML_SetEndElementHandler(XML_Parser parser,
1313 XML_EndElementHandler end) {
1314 endElementHandler = end;
1315 }
1316
1317 void XMLCALL
XML_SetCharacterDataHandler(XML_Parser parser,XML_CharacterDataHandler handler)1318 XML_SetCharacterDataHandler(XML_Parser parser,
1319 XML_CharacterDataHandler handler)
1320 {
1321 characterDataHandler = handler;
1322 }
1323
1324 void XMLCALL
XML_SetProcessingInstructionHandler(XML_Parser parser,XML_ProcessingInstructionHandler handler)1325 XML_SetProcessingInstructionHandler(XML_Parser parser,
1326 XML_ProcessingInstructionHandler handler)
1327 {
1328 processingInstructionHandler = handler;
1329 }
1330
1331 void XMLCALL
XML_SetCommentHandler(XML_Parser parser,XML_CommentHandler handler)1332 XML_SetCommentHandler(XML_Parser parser,
1333 XML_CommentHandler handler)
1334 {
1335 commentHandler = handler;
1336 }
1337
1338 void XMLCALL
XML_SetCdataSectionHandler(XML_Parser parser,XML_StartCdataSectionHandler start,XML_EndCdataSectionHandler end)1339 XML_SetCdataSectionHandler(XML_Parser parser,
1340 XML_StartCdataSectionHandler start,
1341 XML_EndCdataSectionHandler end)
1342 {
1343 startCdataSectionHandler = start;
1344 endCdataSectionHandler = end;
1345 }
1346
1347 void XMLCALL
XML_SetStartCdataSectionHandler(XML_Parser parser,XML_StartCdataSectionHandler start)1348 XML_SetStartCdataSectionHandler(XML_Parser parser,
1349 XML_StartCdataSectionHandler start) {
1350 startCdataSectionHandler = start;
1351 }
1352
1353 void XMLCALL
XML_SetEndCdataSectionHandler(XML_Parser parser,XML_EndCdataSectionHandler end)1354 XML_SetEndCdataSectionHandler(XML_Parser parser,
1355 XML_EndCdataSectionHandler end) {
1356 endCdataSectionHandler = end;
1357 }
1358
1359 void XMLCALL
XML_SetDefaultHandler(XML_Parser parser,XML_DefaultHandler handler)1360 XML_SetDefaultHandler(XML_Parser parser,
1361 XML_DefaultHandler handler)
1362 {
1363 defaultHandler = handler;
1364 defaultExpandInternalEntities = XML_FALSE;
1365 }
1366
1367 void XMLCALL
XML_SetDefaultHandlerExpand(XML_Parser parser,XML_DefaultHandler handler)1368 XML_SetDefaultHandlerExpand(XML_Parser parser,
1369 XML_DefaultHandler handler)
1370 {
1371 defaultHandler = handler;
1372 defaultExpandInternalEntities = XML_TRUE;
1373 }
1374
1375 void XMLCALL
XML_SetDoctypeDeclHandler(XML_Parser parser,XML_StartDoctypeDeclHandler start,XML_EndDoctypeDeclHandler end)1376 XML_SetDoctypeDeclHandler(XML_Parser parser,
1377 XML_StartDoctypeDeclHandler start,
1378 XML_EndDoctypeDeclHandler end)
1379 {
1380 startDoctypeDeclHandler = start;
1381 endDoctypeDeclHandler = end;
1382 }
1383
1384 void XMLCALL
XML_SetStartDoctypeDeclHandler(XML_Parser parser,XML_StartDoctypeDeclHandler start)1385 XML_SetStartDoctypeDeclHandler(XML_Parser parser,
1386 XML_StartDoctypeDeclHandler start) {
1387 startDoctypeDeclHandler = start;
1388 }
1389
1390 void XMLCALL
XML_SetEndDoctypeDeclHandler(XML_Parser parser,XML_EndDoctypeDeclHandler end)1391 XML_SetEndDoctypeDeclHandler(XML_Parser parser,
1392 XML_EndDoctypeDeclHandler end) {
1393 endDoctypeDeclHandler = end;
1394 }
1395
1396 void XMLCALL
XML_SetUnparsedEntityDeclHandler(XML_Parser parser,XML_UnparsedEntityDeclHandler handler)1397 XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
1398 XML_UnparsedEntityDeclHandler handler)
1399 {
1400 unparsedEntityDeclHandler = handler;
1401 }
1402
1403 void XMLCALL
XML_SetNotationDeclHandler(XML_Parser parser,XML_NotationDeclHandler handler)1404 XML_SetNotationDeclHandler(XML_Parser parser,
1405 XML_NotationDeclHandler handler)
1406 {
1407 notationDeclHandler = handler;
1408 }
1409
1410 void XMLCALL
XML_SetNamespaceDeclHandler(XML_Parser parser,XML_StartNamespaceDeclHandler start,XML_EndNamespaceDeclHandler end)1411 XML_SetNamespaceDeclHandler(XML_Parser parser,
1412 XML_StartNamespaceDeclHandler start,
1413 XML_EndNamespaceDeclHandler end)
1414 {
1415 startNamespaceDeclHandler = start;
1416 endNamespaceDeclHandler = end;
1417 }
1418
1419 void XMLCALL
XML_SetStartNamespaceDeclHandler(XML_Parser parser,XML_StartNamespaceDeclHandler start)1420 XML_SetStartNamespaceDeclHandler(XML_Parser parser,
1421 XML_StartNamespaceDeclHandler start) {
1422 startNamespaceDeclHandler = start;
1423 }
1424
1425 void XMLCALL
XML_SetEndNamespaceDeclHandler(XML_Parser parser,XML_EndNamespaceDeclHandler end)1426 XML_SetEndNamespaceDeclHandler(XML_Parser parser,
1427 XML_EndNamespaceDeclHandler end) {
1428 endNamespaceDeclHandler = end;
1429 }
1430
1431 void XMLCALL
XML_SetNotStandaloneHandler(XML_Parser parser,XML_NotStandaloneHandler handler)1432 XML_SetNotStandaloneHandler(XML_Parser parser,
1433 XML_NotStandaloneHandler handler)
1434 {
1435 notStandaloneHandler = handler;
1436 }
1437
1438 void XMLCALL
XML_SetExternalEntityRefHandler(XML_Parser parser,XML_ExternalEntityRefHandler handler)1439 XML_SetExternalEntityRefHandler(XML_Parser parser,
1440 XML_ExternalEntityRefHandler handler)
1441 {
1442 externalEntityRefHandler = handler;
1443 }
1444
1445 void XMLCALL
XML_SetExternalEntityRefHandlerArg(XML_Parser parser,void * arg)1446 XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
1447 {
1448 if (arg)
1449 externalEntityRefHandlerArg = (XML_Parser)arg;
1450 else
1451 externalEntityRefHandlerArg = parser;
1452 }
1453
1454 void XMLCALL
XML_SetSkippedEntityHandler(XML_Parser parser,XML_SkippedEntityHandler handler)1455 XML_SetSkippedEntityHandler(XML_Parser parser,
1456 XML_SkippedEntityHandler handler)
1457 {
1458 skippedEntityHandler = handler;
1459 }
1460
1461 void XMLCALL
XML_SetUnknownEncodingHandler(XML_Parser parser,XML_UnknownEncodingHandler handler,void * data)1462 XML_SetUnknownEncodingHandler(XML_Parser parser,
1463 XML_UnknownEncodingHandler handler,
1464 void *data)
1465 {
1466 unknownEncodingHandler = handler;
1467 unknownEncodingHandlerData = data;
1468 }
1469
1470 void XMLCALL
XML_SetElementDeclHandler(XML_Parser parser,XML_ElementDeclHandler eldecl)1471 XML_SetElementDeclHandler(XML_Parser parser,
1472 XML_ElementDeclHandler eldecl)
1473 {
1474 elementDeclHandler = eldecl;
1475 }
1476
1477 void XMLCALL
XML_SetAttlistDeclHandler(XML_Parser parser,XML_AttlistDeclHandler attdecl)1478 XML_SetAttlistDeclHandler(XML_Parser parser,
1479 XML_AttlistDeclHandler attdecl)
1480 {
1481 attlistDeclHandler = attdecl;
1482 }
1483
1484 void XMLCALL
XML_SetEntityDeclHandler(XML_Parser parser,XML_EntityDeclHandler handler)1485 XML_SetEntityDeclHandler(XML_Parser parser,
1486 XML_EntityDeclHandler handler)
1487 {
1488 entityDeclHandler = handler;
1489 }
1490
1491 void XMLCALL
XML_SetXmlDeclHandler(XML_Parser parser,XML_XmlDeclHandler handler)1492 XML_SetXmlDeclHandler(XML_Parser parser,
1493 XML_XmlDeclHandler handler) {
1494 xmlDeclHandler = handler;
1495 }
1496
1497 int XMLCALL
XML_SetParamEntityParsing(XML_Parser parser,enum XML_ParamEntityParsing peParsing)1498 XML_SetParamEntityParsing(XML_Parser parser,
1499 enum XML_ParamEntityParsing peParsing)
1500 {
1501 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1502 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
1503 return 0;
1504 #ifdef XML_DTD
1505 paramEntityParsing = peParsing;
1506 return 1;
1507 #else
1508 return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
1509 #endif
1510 }
1511
1512 int XMLCALL
XML_SetHashSalt(XML_Parser parser,unsigned long hash_salt)1513 XML_SetHashSalt(XML_Parser parser,
1514 unsigned long hash_salt) /* should be size_t */
1515 {
1516 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1517 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
1518 return 0;
1519 hash_secret_salt = hash_salt;
1520 return 1;
1521 }
1522
1523 enum XML_Status XMLCALL
XML_Parse(XML_Parser parser,const char * s,int len,int isFinal)1524 XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
1525 {
1526 switch (ps_parsing) {
1527 case XML_SUSPENDED:
1528 errorCode = XML_ERROR_SUSPENDED;
1529 return XML_STATUS_ERROR;
1530 case XML_FINISHED:
1531 errorCode = XML_ERROR_FINISHED;
1532 return XML_STATUS_ERROR;
1533 case XML_INITIALIZED:
1534 if (parentParser == NULL && !startParsing(parser)) {
1535 errorCode = XML_ERROR_NO_MEMORY;
1536 return XML_STATUS_ERROR;
1537 }
1538 default:
1539 ps_parsing = XML_PARSING;
1540 }
1541
1542 if (len == 0) {
1543 ps_finalBuffer = (XML_Bool)isFinal;
1544 if (!isFinal)
1545 return XML_STATUS_OK;
1546 positionPtr = bufferPtr;
1547 parseEndPtr = bufferEnd;
1548
1549 /* If data are left over from last buffer, and we now know that these
1550 data are the final chunk of input, then we have to check them again
1551 to detect errors based on that fact.
1552 */
1553 errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
1554
1555 if (errorCode == XML_ERROR_NONE) {
1556 switch (ps_parsing) {
1557 case XML_SUSPENDED:
1558 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1559 positionPtr = bufferPtr;
1560 return XML_STATUS_SUSPENDED;
1561 case XML_INITIALIZED:
1562 case XML_PARSING:
1563 ps_parsing = XML_FINISHED;
1564 /* fall through */
1565 default:
1566 return XML_STATUS_OK;
1567 }
1568 }
1569 eventEndPtr = eventPtr;
1570 processor = errorProcessor;
1571 return XML_STATUS_ERROR;
1572 }
1573 #ifndef XML_CONTEXT_BYTES
1574 else if (bufferPtr == bufferEnd) {
1575 const char *end;
1576 int nLeftOver;
1577 enum XML_Error result;
1578 parseEndByteIndex += len;
1579 positionPtr = s;
1580 ps_finalBuffer = (XML_Bool)isFinal;
1581
1582 errorCode = processor(parser, s, parseEndPtr = s + len, &end);
1583
1584 if (errorCode != XML_ERROR_NONE) {
1585 eventEndPtr = eventPtr;
1586 processor = errorProcessor;
1587 return XML_STATUS_ERROR;
1588 }
1589 else {
1590 switch (ps_parsing) {
1591 case XML_SUSPENDED:
1592 result = XML_STATUS_SUSPENDED;
1593 break;
1594 case XML_INITIALIZED:
1595 case XML_PARSING:
1596 if (isFinal) {
1597 ps_parsing = XML_FINISHED;
1598 return XML_STATUS_OK;
1599 }
1600 /* fall through */
1601 default:
1602 result = XML_STATUS_OK;
1603 }
1604 }
1605
1606 XmlUpdatePosition(encoding, positionPtr, end, &position);
1607 nLeftOver = s + len - end;
1608 if (nLeftOver) {
1609 if (buffer == NULL || nLeftOver > bufferLim - buffer) {
1610 /* avoid _signed_ integer overflow */
1611 char *temp = NULL;
1612 const int bytesToAllocate = (int)((unsigned)len * 2U);
1613 if (bytesToAllocate > 0) {
1614 temp = (buffer == NULL
1615 ? (char *)MALLOC(bytesToAllocate)
1616 : (char *)REALLOC(buffer, bytesToAllocate));
1617 }
1618 if (temp == NULL) {
1619 errorCode = XML_ERROR_NO_MEMORY;
1620 eventPtr = eventEndPtr = NULL;
1621 processor = errorProcessor;
1622 return XML_STATUS_ERROR;
1623 }
1624 buffer = temp;
1625 bufferLim = buffer + bytesToAllocate;
1626 }
1627 memcpy(buffer, end, nLeftOver);
1628 }
1629 bufferPtr = buffer;
1630 bufferEnd = buffer + nLeftOver;
1631 positionPtr = bufferPtr;
1632 parseEndPtr = bufferEnd;
1633 eventPtr = bufferPtr;
1634 eventEndPtr = bufferPtr;
1635 return result;
1636 }
1637 #endif /* not defined XML_CONTEXT_BYTES */
1638 else {
1639 void *buff = XML_GetBuffer(parser, len);
1640 if (buff == NULL)
1641 return XML_STATUS_ERROR;
1642 else {
1643 memcpy(buff, s, len);
1644 return XML_ParseBuffer(parser, len, isFinal);
1645 }
1646 }
1647 }
1648
1649 enum XML_Status XMLCALL
XML_ParseBuffer(XML_Parser parser,int len,int isFinal)1650 XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
1651 {
1652 const char *start;
1653 enum XML_Status result = XML_STATUS_OK;
1654
1655 switch (ps_parsing) {
1656 case XML_SUSPENDED:
1657 errorCode = XML_ERROR_SUSPENDED;
1658 return XML_STATUS_ERROR;
1659 case XML_FINISHED:
1660 errorCode = XML_ERROR_FINISHED;
1661 return XML_STATUS_ERROR;
1662 case XML_INITIALIZED:
1663 if (parentParser == NULL && !startParsing(parser)) {
1664 errorCode = XML_ERROR_NO_MEMORY;
1665 return XML_STATUS_ERROR;
1666 }
1667 default:
1668 ps_parsing = XML_PARSING;
1669 }
1670
1671 start = bufferPtr;
1672 positionPtr = start;
1673 bufferEnd += len;
1674 parseEndPtr = bufferEnd;
1675 parseEndByteIndex += len;
1676 ps_finalBuffer = (XML_Bool)isFinal;
1677
1678 errorCode = processor(parser, start, parseEndPtr, &bufferPtr);
1679
1680 if (errorCode != XML_ERROR_NONE) {
1681 eventEndPtr = eventPtr;
1682 processor = errorProcessor;
1683 return XML_STATUS_ERROR;
1684 }
1685 else {
1686 switch (ps_parsing) {
1687 case XML_SUSPENDED:
1688 result = XML_STATUS_SUSPENDED;
1689 break;
1690 case XML_INITIALIZED:
1691 case XML_PARSING:
1692 if (isFinal) {
1693 ps_parsing = XML_FINISHED;
1694 return result;
1695 }
1696 default: ; /* should not happen */
1697 }
1698 }
1699
1700 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1701 positionPtr = bufferPtr;
1702 return result;
1703 }
1704
1705 void * XMLCALL
XML_GetBuffer(XML_Parser parser,int len)1706 XML_GetBuffer(XML_Parser parser, int len)
1707 {
1708 /* BEGIN MOZILLA CHANGE (sanity check len) */
1709 if (len < 0) {
1710 errorCode = XML_ERROR_NO_MEMORY;
1711 return NULL;
1712 }
1713 /* END MOZILLA CHANGE */
1714 switch (ps_parsing) {
1715 case XML_SUSPENDED:
1716 errorCode = XML_ERROR_SUSPENDED;
1717 return NULL;
1718 case XML_FINISHED:
1719 errorCode = XML_ERROR_FINISHED;
1720 return NULL;
1721 default: ;
1722 }
1723
1724 if (len > bufferLim - bufferEnd) {
1725 /* Do not invoke signed arithmetic overflow: */
1726 int neededSize = (int) ((unsigned)len + (unsigned)(bufferEnd - bufferPtr));
1727 /* BEGIN MOZILLA CHANGE (sanity check neededSize) */
1728 if (neededSize < 0) {
1729 errorCode = XML_ERROR_NO_MEMORY;
1730 return NULL;
1731 }
1732 /* END MOZILLA CHANGE */
1733 #ifdef XML_CONTEXT_BYTES
1734 int keep = (int)(bufferPtr - buffer);
1735
1736 if (keep > XML_CONTEXT_BYTES)
1737 keep = XML_CONTEXT_BYTES;
1738 neededSize += keep;
1739 #endif /* defined XML_CONTEXT_BYTES */
1740 if (neededSize <= bufferLim - buffer) {
1741 #ifdef XML_CONTEXT_BYTES
1742 if (keep < bufferPtr - buffer) {
1743 int offset = (int)(bufferPtr - buffer) - keep;
1744 memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
1745 bufferEnd -= offset;
1746 bufferPtr -= offset;
1747 }
1748 #else
1749 memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
1750 bufferEnd = buffer + (bufferEnd - bufferPtr);
1751 bufferPtr = buffer;
1752 #endif /* not defined XML_CONTEXT_BYTES */
1753 }
1754 else {
1755 char *newBuf;
1756 int bufferSize = (int)(bufferLim - bufferPtr);
1757 if (bufferSize == 0)
1758 bufferSize = INIT_BUFFER_SIZE;
1759 do {
1760 /* Do not invoke signed arithmetic overflow: */
1761 bufferSize = (int) (2U * (unsigned) bufferSize);
1762 /* BEGIN MOZILLA CHANGE (prevent infinite loop on overflow) */
1763 } while (bufferSize < neededSize && bufferSize > 0);
1764 /* END MOZILLA CHANGE */
1765 /* BEGIN MOZILLA CHANGE (sanity check bufferSize) */
1766 if (bufferSize <= 0) {
1767 errorCode = XML_ERROR_NO_MEMORY;
1768 return NULL;
1769 }
1770 /* END MOZILLA CHANGE */
1771 newBuf = (char *)MALLOC(bufferSize);
1772 if (newBuf == 0) {
1773 errorCode = XML_ERROR_NO_MEMORY;
1774 return NULL;
1775 }
1776 bufferLim = newBuf + bufferSize;
1777 #ifdef XML_CONTEXT_BYTES
1778 if (bufferPtr) {
1779 int keep = (int)(bufferPtr - buffer);
1780 if (keep > XML_CONTEXT_BYTES)
1781 keep = XML_CONTEXT_BYTES;
1782 memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
1783 FREE(buffer);
1784 buffer = newBuf;
1785 bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
1786 bufferPtr = buffer + keep;
1787 }
1788 else {
1789 bufferEnd = newBuf + (bufferEnd - bufferPtr);
1790 bufferPtr = buffer = newBuf;
1791 }
1792 #else
1793 if (bufferPtr) {
1794 memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
1795 FREE(buffer);
1796 }
1797 bufferEnd = newBuf + (bufferEnd - bufferPtr);
1798 bufferPtr = buffer = newBuf;
1799 #endif /* not defined XML_CONTEXT_BYTES */
1800 }
1801 eventPtr = eventEndPtr = NULL;
1802 positionPtr = NULL;
1803 }
1804 return bufferEnd;
1805 }
1806
1807 enum XML_Status XMLCALL
XML_StopParser(XML_Parser parser,XML_Bool resumable)1808 XML_StopParser(XML_Parser parser, XML_Bool resumable)
1809 {
1810 switch (ps_parsing) {
1811 case XML_SUSPENDED:
1812 if (resumable) {
1813 errorCode = XML_ERROR_SUSPENDED;
1814 return XML_STATUS_ERROR;
1815 }
1816 ps_parsing = XML_FINISHED;
1817 break;
1818 case XML_FINISHED:
1819 errorCode = XML_ERROR_FINISHED;
1820 return XML_STATUS_ERROR;
1821 default:
1822 if (resumable) {
1823 #ifdef XML_DTD
1824 if (isParamEntity) {
1825 errorCode = XML_ERROR_SUSPEND_PE;
1826 return XML_STATUS_ERROR;
1827 }
1828 #endif
1829 ps_parsing = XML_SUSPENDED;
1830 }
1831 else
1832 ps_parsing = XML_FINISHED;
1833 }
1834 return XML_STATUS_OK;
1835 }
1836
1837 enum XML_Status XMLCALL
XML_ResumeParser(XML_Parser parser)1838 XML_ResumeParser(XML_Parser parser)
1839 {
1840 enum XML_Status result = XML_STATUS_OK;
1841
1842 if (ps_parsing != XML_SUSPENDED) {
1843 errorCode = XML_ERROR_NOT_SUSPENDED;
1844 return XML_STATUS_ERROR;
1845 }
1846 ps_parsing = XML_PARSING;
1847
1848 errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
1849
1850 if (errorCode != XML_ERROR_NONE) {
1851 eventEndPtr = eventPtr;
1852 processor = errorProcessor;
1853 return XML_STATUS_ERROR;
1854 }
1855 else {
1856 switch (ps_parsing) {
1857 case XML_SUSPENDED:
1858 result = XML_STATUS_SUSPENDED;
1859 break;
1860 case XML_INITIALIZED:
1861 case XML_PARSING:
1862 if (ps_finalBuffer) {
1863 ps_parsing = XML_FINISHED;
1864 return result;
1865 }
1866 default: ;
1867 }
1868 }
1869
1870 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1871 positionPtr = bufferPtr;
1872 return result;
1873 }
1874
1875 void XMLCALL
XML_GetParsingStatus(XML_Parser parser,XML_ParsingStatus * status)1876 XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
1877 {
1878 assert(status != NULL);
1879 *status = parser->m_parsingStatus;
1880 }
1881
1882 enum XML_Error XMLCALL
XML_GetErrorCode(XML_Parser parser)1883 XML_GetErrorCode(XML_Parser parser)
1884 {
1885 return errorCode;
1886 }
1887
1888 XML_Index XMLCALL
XML_GetCurrentByteIndex(XML_Parser parser)1889 XML_GetCurrentByteIndex(XML_Parser parser)
1890 {
1891 if (eventPtr)
1892 return (XML_Index) (parseEndByteIndex - (parseEndPtr - eventPtr));
1893 return -1;
1894 }
1895
1896 int XMLCALL
XML_GetCurrentByteCount(XML_Parser parser)1897 XML_GetCurrentByteCount(XML_Parser parser)
1898 {
1899 if (eventEndPtr && eventPtr)
1900 return (int)(eventEndPtr - eventPtr);
1901 return 0;
1902 }
1903
1904 const char * XMLCALL
XML_GetInputContext(XML_Parser parser,int * offset,int * size)1905 XML_GetInputContext(XML_Parser parser, int *offset, int *size)
1906 {
1907 #ifdef XML_CONTEXT_BYTES
1908 if (eventPtr && buffer) {
1909 *offset = (int)(eventPtr - buffer);
1910 *size = (int)(bufferEnd - buffer);
1911 return buffer;
1912 }
1913 #endif /* defined XML_CONTEXT_BYTES */
1914 return (char *) 0;
1915 }
1916
1917 XML_Size XMLCALL
XML_GetCurrentLineNumber(XML_Parser parser)1918 XML_GetCurrentLineNumber(XML_Parser parser)
1919 {
1920 if (eventPtr && eventPtr >= positionPtr) {
1921 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1922 positionPtr = eventPtr;
1923 }
1924 return position.lineNumber + 1;
1925 }
1926
1927 XML_Size XMLCALL
XML_GetCurrentColumnNumber(XML_Parser parser)1928 XML_GetCurrentColumnNumber(XML_Parser parser)
1929 {
1930 if (eventPtr && eventPtr >= positionPtr) {
1931 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1932 positionPtr = eventPtr;
1933 }
1934 return position.columnNumber;
1935 }
1936
1937 void XMLCALL
XML_FreeContentModel(XML_Parser parser,XML_Content * model)1938 XML_FreeContentModel(XML_Parser parser, XML_Content *model)
1939 {
1940 FREE(model);
1941 }
1942
1943 void * XMLCALL
XML_MemMalloc(XML_Parser parser,size_t size)1944 XML_MemMalloc(XML_Parser parser, size_t size)
1945 {
1946 return MALLOC(size);
1947 }
1948
1949 void * XMLCALL
XML_MemRealloc(XML_Parser parser,void * ptr,size_t size)1950 XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
1951 {
1952 return REALLOC(ptr, size);
1953 }
1954
1955 void XMLCALL
XML_MemFree(XML_Parser parser,void * ptr)1956 XML_MemFree(XML_Parser parser, void *ptr)
1957 {
1958 FREE(ptr);
1959 }
1960
1961 void XMLCALL
XML_DefaultCurrent(XML_Parser parser)1962 XML_DefaultCurrent(XML_Parser parser)
1963 {
1964 if (defaultHandler) {
1965 if (openInternalEntities)
1966 reportDefault(parser,
1967 internalEncoding,
1968 openInternalEntities->internalEventPtr,
1969 openInternalEntities->internalEventEndPtr);
1970 else
1971 reportDefault(parser, encoding, eventPtr, eventEndPtr);
1972 }
1973 }
1974
1975 const XML_LChar * XMLCALL
XML_ErrorString(enum XML_Error code)1976 XML_ErrorString(enum XML_Error code)
1977 {
1978 static const XML_LChar* const message[] = {
1979 0,
1980 XML_L("out of memory"),
1981 XML_L("syntax error"),
1982 XML_L("no element found"),
1983 XML_L("not well-formed (invalid token)"),
1984 XML_L("unclosed token"),
1985 XML_L("partial character"),
1986 XML_L("mismatched tag"),
1987 XML_L("duplicate attribute"),
1988 XML_L("junk after document element"),
1989 XML_L("illegal parameter entity reference"),
1990 XML_L("undefined entity"),
1991 XML_L("recursive entity reference"),
1992 XML_L("asynchronous entity"),
1993 XML_L("reference to invalid character number"),
1994 XML_L("reference to binary entity"),
1995 XML_L("reference to external entity in attribute"),
1996 XML_L("XML or text declaration not at start of entity"),
1997 XML_L("unknown encoding"),
1998 XML_L("encoding specified in XML declaration is incorrect"),
1999 XML_L("unclosed CDATA section"),
2000 XML_L("error in processing external entity reference"),
2001 XML_L("document is not standalone"),
2002 XML_L("unexpected parser state - please send a bug report"),
2003 XML_L("entity declared in parameter entity"),
2004 XML_L("requested feature requires XML_DTD support in Expat"),
2005 XML_L("cannot change setting once parsing has begun"),
2006 XML_L("unbound prefix"),
2007 XML_L("must not undeclare prefix"),
2008 XML_L("incomplete markup in parameter entity"),
2009 XML_L("XML declaration not well-formed"),
2010 XML_L("text declaration not well-formed"),
2011 XML_L("illegal character(s) in public id"),
2012 XML_L("parser suspended"),
2013 XML_L("parser not suspended"),
2014 XML_L("parsing aborted"),
2015 XML_L("parsing finished"),
2016 XML_L("cannot suspend in external parameter entity"),
2017 XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
2018 XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
2019 XML_L("prefix must not be bound to one of the reserved namespace names")
2020 };
2021 if (code > 0 && code < sizeof(message)/sizeof(message[0]))
2022 return message[code];
2023 return NULL;
2024 }
2025
2026 const XML_LChar * XMLCALL
XML_ExpatVersion(void)2027 XML_ExpatVersion(void) {
2028
2029 /* V1 is used to string-ize the version number. However, it would
2030 string-ize the actual version macro *names* unless we get them
2031 substituted before being passed to V1. CPP is defined to expand
2032 a macro, then rescan for more expansions. Thus, we use V2 to expand
2033 the version macros, then CPP will expand the resulting V1() macro
2034 with the correct numerals. */
2035 /* ### I'm assuming cpp is portable in this respect... */
2036
2037 #define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
2038 #define V2(a,b,c) XML_L("expat_")V1(a,b,c)
2039
2040 return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
2041
2042 #undef V1
2043 #undef V2
2044 }
2045
2046 XML_Expat_Version XMLCALL
XML_ExpatVersionInfo(void)2047 XML_ExpatVersionInfo(void)
2048 {
2049 XML_Expat_Version version;
2050
2051 version.major = XML_MAJOR_VERSION;
2052 version.minor = XML_MINOR_VERSION;
2053 version.micro = XML_MICRO_VERSION;
2054
2055 return version;
2056 }
2057
2058 const XML_Feature * XMLCALL
XML_GetFeatureList(void)2059 XML_GetFeatureList(void)
2060 {
2061 static const XML_Feature features[] = {
2062 {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"),
2063 sizeof(XML_Char)},
2064 {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
2065 sizeof(XML_LChar)},
2066 #ifdef XML_UNICODE
2067 {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},
2068 #endif
2069 #ifdef XML_UNICODE_WCHAR_T
2070 {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},
2071 #endif
2072 #ifdef XML_DTD
2073 {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},
2074 #endif
2075 #ifdef XML_CONTEXT_BYTES
2076 {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
2077 XML_CONTEXT_BYTES},
2078 #endif
2079 #ifdef XML_MIN_SIZE
2080 {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},
2081 #endif
2082 #ifdef XML_NS
2083 {XML_FEATURE_NS, XML_L("XML_NS"), 0},
2084 #endif
2085 #ifdef XML_LARGE_SIZE
2086 {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0},
2087 #endif
2088 #ifdef XML_ATTR_INFO
2089 {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0},
2090 #endif
2091 {XML_FEATURE_END, NULL, 0}
2092 };
2093
2094 return features;
2095 }
2096
2097 /* Initially tag->rawName always points into the parse buffer;
2098 for those TAG instances opened while the current parse buffer was
2099 processed, and not yet closed, we need to store tag->rawName in a more
2100 permanent location, since the parse buffer is about to be discarded.
2101 */
2102 static XML_Bool
storeRawNames(XML_Parser parser)2103 storeRawNames(XML_Parser parser)
2104 {
2105 TAG *tag = tagStack;
2106 while (tag) {
2107 int bufSize;
2108 int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
2109 char *rawNameBuf = tag->buf + nameLen;
2110 /* Stop if already stored. Since tagStack is a stack, we can stop
2111 at the first entry that has already been copied; everything
2112 below it in the stack is already been accounted for in a
2113 previous call to this function.
2114 */
2115 if (tag->rawName == rawNameBuf)
2116 break;
2117 /* For re-use purposes we need to ensure that the
2118 size of tag->buf is a multiple of sizeof(XML_Char).
2119 */
2120 bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
2121 if (bufSize > tag->bufEnd - tag->buf) {
2122 char *temp = (char *)REALLOC(tag->buf, bufSize);
2123 if (temp == NULL)
2124 return XML_FALSE;
2125 /* if tag->name.str points to tag->buf (only when namespace
2126 processing is off) then we have to update it
2127 */
2128 if (tag->name.str == (XML_Char *)tag->buf)
2129 tag->name.str = (XML_Char *)temp;
2130 /* if tag->name.localPart is set (when namespace processing is on)
2131 then update it as well, since it will always point into tag->buf
2132 */
2133 if (tag->name.localPart)
2134 tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -
2135 (XML_Char *)tag->buf);
2136 tag->buf = temp;
2137 tag->bufEnd = temp + bufSize;
2138 rawNameBuf = temp + nameLen;
2139 }
2140 memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
2141 tag->rawName = rawNameBuf;
2142 tag = tag->parent;
2143 }
2144 return XML_TRUE;
2145 }
2146
2147 static enum XML_Error PTRCALL
contentProcessor(XML_Parser parser,const char * start,const char * end,const char ** endPtr)2148 contentProcessor(XML_Parser parser,
2149 const char *start,
2150 const char *end,
2151 const char **endPtr)
2152 {
2153 enum XML_Error result = doContent(parser, 0, encoding, start, end,
2154 endPtr, (XML_Bool)!ps_finalBuffer);
2155 if (result == XML_ERROR_NONE) {
2156 if (!storeRawNames(parser))
2157 return XML_ERROR_NO_MEMORY;
2158 }
2159 return result;
2160 }
2161
2162 static enum XML_Error PTRCALL
externalEntityInitProcessor(XML_Parser parser,const char * start,const char * end,const char ** endPtr)2163 externalEntityInitProcessor(XML_Parser parser,
2164 const char *start,
2165 const char *end,
2166 const char **endPtr)
2167 {
2168 enum XML_Error result = initializeEncoding(parser);
2169 if (result != XML_ERROR_NONE)
2170 return result;
2171 processor = externalEntityInitProcessor2;
2172 return externalEntityInitProcessor2(parser, start, end, endPtr);
2173 }
2174
2175 static enum XML_Error PTRCALL
externalEntityInitProcessor2(XML_Parser parser,const char * start,const char * end,const char ** endPtr)2176 externalEntityInitProcessor2(XML_Parser parser,
2177 const char *start,
2178 const char *end,
2179 const char **endPtr)
2180 {
2181 const char *next = start; /* XmlContentTok doesn't always set the last arg */
2182 int tok = XmlContentTok(encoding, start, end, &next);
2183 switch (tok) {
2184 case XML_TOK_BOM:
2185 /* If we are at the end of the buffer, this would cause the next stage,
2186 i.e. externalEntityInitProcessor3, to pass control directly to
2187 doContent (by detecting XML_TOK_NONE) without processing any xml text
2188 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
2189 */
2190 if (next == end && !ps_finalBuffer) {
2191 *endPtr = next;
2192 return XML_ERROR_NONE;
2193 }
2194 start = next;
2195 break;
2196 case XML_TOK_PARTIAL:
2197 if (!ps_finalBuffer) {
2198 *endPtr = start;
2199 return XML_ERROR_NONE;
2200 }
2201 eventPtr = start;
2202 return XML_ERROR_UNCLOSED_TOKEN;
2203 case XML_TOK_PARTIAL_CHAR:
2204 if (!ps_finalBuffer) {
2205 *endPtr = start;
2206 return XML_ERROR_NONE;
2207 }
2208 eventPtr = start;
2209 return XML_ERROR_PARTIAL_CHAR;
2210 }
2211 processor = externalEntityInitProcessor3;
2212 return externalEntityInitProcessor3(parser, start, end, endPtr);
2213 }
2214
2215 static enum XML_Error PTRCALL
externalEntityInitProcessor3(XML_Parser parser,const char * start,const char * end,const char ** endPtr)2216 externalEntityInitProcessor3(XML_Parser parser,
2217 const char *start,
2218 const char *end,
2219 const char **endPtr)
2220 {
2221 int tok;
2222 const char *next = start; /* XmlContentTok doesn't always set the last arg */
2223 eventPtr = start;
2224 tok = XmlContentTok(encoding, start, end, &next);
2225 eventEndPtr = next;
2226
2227 switch (tok) {
2228 case XML_TOK_XML_DECL:
2229 {
2230 enum XML_Error result;
2231 result = processXmlDecl(parser, 1, start, next);
2232 if (result != XML_ERROR_NONE)
2233 return result;
2234 switch (ps_parsing) {
2235 case XML_SUSPENDED:
2236 *endPtr = next;
2237 return XML_ERROR_NONE;
2238 case XML_FINISHED:
2239 return XML_ERROR_ABORTED;
2240 default:
2241 start = next;
2242 }
2243 }
2244 break;
2245 case XML_TOK_PARTIAL:
2246 if (!ps_finalBuffer) {
2247 *endPtr = start;
2248 return XML_ERROR_NONE;
2249 }
2250 return XML_ERROR_UNCLOSED_TOKEN;
2251 case XML_TOK_PARTIAL_CHAR:
2252 if (!ps_finalBuffer) {
2253 *endPtr = start;
2254 return XML_ERROR_NONE;
2255 }
2256 return XML_ERROR_PARTIAL_CHAR;
2257 }
2258 processor = externalEntityContentProcessor;
2259 tagLevel = 1;
2260 return externalEntityContentProcessor(parser, start, end, endPtr);
2261 }
2262
2263 static enum XML_Error PTRCALL
externalEntityContentProcessor(XML_Parser parser,const char * start,const char * end,const char ** endPtr)2264 externalEntityContentProcessor(XML_Parser parser,
2265 const char *start,
2266 const char *end,
2267 const char **endPtr)
2268 {
2269 enum XML_Error result = doContent(parser, 1, encoding, start, end,
2270 endPtr, (XML_Bool)!ps_finalBuffer);
2271 if (result == XML_ERROR_NONE) {
2272 if (!storeRawNames(parser))
2273 return XML_ERROR_NO_MEMORY;
2274 }
2275 return result;
2276 }
2277
2278 static enum XML_Error
doContent(XML_Parser parser,int startTagLevel,const ENCODING * enc,const char * s,const char * end,const char ** nextPtr,XML_Bool haveMore)2279 doContent(XML_Parser parser,
2280 int startTagLevel,
2281 const ENCODING *enc,
2282 const char *s,
2283 const char *end,
2284 const char **nextPtr,
2285 XML_Bool haveMore)
2286 {
2287 /* save one level of indirection */
2288 DTD * const dtd = _dtd;
2289
2290 const char **eventPP;
2291 const char **eventEndPP;
2292 if (enc == encoding) {
2293 eventPP = &eventPtr;
2294 eventEndPP = &eventEndPtr;
2295 }
2296 else {
2297 eventPP = &(openInternalEntities->internalEventPtr);
2298 eventEndPP = &(openInternalEntities->internalEventEndPtr);
2299 }
2300 *eventPP = s;
2301
2302 for (;;) {
2303 const char *next = s; /* XmlContentTok doesn't always set the last arg */
2304 int tok = XmlContentTok(enc, s, end, &next);
2305 *eventEndPP = next;
2306 switch (tok) {
2307 case XML_TOK_TRAILING_CR:
2308 if (haveMore) {
2309 *nextPtr = s;
2310 return XML_ERROR_NONE;
2311 }
2312 *eventEndPP = end;
2313 if (characterDataHandler) {
2314 XML_Char c = 0xA;
2315 characterDataHandler(handlerArg, &c, 1);
2316 }
2317 else if (defaultHandler)
2318 reportDefault(parser, enc, s, end);
2319 /* We are at the end of the final buffer, should we check for
2320 XML_SUSPENDED, XML_FINISHED?
2321 */
2322 if (startTagLevel == 0)
2323 return XML_ERROR_NO_ELEMENTS;
2324 if (tagLevel != startTagLevel)
2325 return XML_ERROR_ASYNC_ENTITY;
2326 *nextPtr = end;
2327 return XML_ERROR_NONE;
2328 case XML_TOK_NONE:
2329 if (haveMore) {
2330 *nextPtr = s;
2331 return XML_ERROR_NONE;
2332 }
2333 if (startTagLevel > 0) {
2334 if (tagLevel != startTagLevel)
2335 return XML_ERROR_ASYNC_ENTITY;
2336 *nextPtr = s;
2337 return XML_ERROR_NONE;
2338 }
2339 return XML_ERROR_NO_ELEMENTS;
2340 case XML_TOK_INVALID:
2341 *eventPP = next;
2342 return XML_ERROR_INVALID_TOKEN;
2343 case XML_TOK_PARTIAL:
2344 if (haveMore) {
2345 *nextPtr = s;
2346 return XML_ERROR_NONE;
2347 }
2348 return XML_ERROR_UNCLOSED_TOKEN;
2349 case XML_TOK_PARTIAL_CHAR:
2350 if (haveMore) {
2351 *nextPtr = s;
2352 return XML_ERROR_NONE;
2353 }
2354 return XML_ERROR_PARTIAL_CHAR;
2355 case XML_TOK_ENTITY_REF:
2356 {
2357 const XML_Char *name;
2358 ENTITY *entity;
2359 XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
2360 s + enc->minBytesPerChar,
2361 next - enc->minBytesPerChar);
2362 if (ch) {
2363 if (characterDataHandler)
2364 characterDataHandler(handlerArg, &ch, 1);
2365 else if (defaultHandler)
2366 reportDefault(parser, enc, s, next);
2367 break;
2368 }
2369 name = poolStoreString(&dtd->pool, enc,
2370 s + enc->minBytesPerChar,
2371 next - enc->minBytesPerChar);
2372 if (!name)
2373 return XML_ERROR_NO_MEMORY;
2374 entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
2375 poolDiscard(&dtd->pool);
2376 /* First, determine if a check for an existing declaration is needed;
2377 if yes, check that the entity exists, and that it is internal,
2378 otherwise call the skipped entity or default handler.
2379 */
2380 if (!dtd->hasParamEntityRefs || dtd->standalone) {
2381 if (!entity)
2382 return XML_ERROR_UNDEFINED_ENTITY;
2383 else if (!entity->is_internal)
2384 return XML_ERROR_ENTITY_DECLARED_IN_PE;
2385 }
2386 else if (!entity) {
2387 if (skippedEntityHandler)
2388 skippedEntityHandler(handlerArg, name, 0);
2389 else if (defaultHandler)
2390 reportDefault(parser, enc, s, next);
2391 break;
2392 }
2393 if (entity->open)
2394 return XML_ERROR_RECURSIVE_ENTITY_REF;
2395 if (entity->notation)
2396 return XML_ERROR_BINARY_ENTITY_REF;
2397 if (entity->textPtr) {
2398 enum XML_Error result;
2399 if (!defaultExpandInternalEntities) {
2400 if (skippedEntityHandler)
2401 skippedEntityHandler(handlerArg, entity->name, 0);
2402 else if (defaultHandler)
2403 reportDefault(parser, enc, s, next);
2404 break;
2405 }
2406 result = processInternalEntity(parser, entity, XML_FALSE);
2407 if (result != XML_ERROR_NONE)
2408 return result;
2409 }
2410 else if (externalEntityRefHandler) {
2411 const XML_Char *context;
2412 entity->open = XML_TRUE;
2413 context = getContext(parser);
2414 entity->open = XML_FALSE;
2415 if (!context)
2416 return XML_ERROR_NO_MEMORY;
2417 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
2418 context,
2419 entity->base,
2420 entity->systemId,
2421 entity->publicId))
2422 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
2423 poolDiscard(&tempPool);
2424 }
2425 else if (defaultHandler)
2426 reportDefault(parser, enc, s, next);
2427 break;
2428 }
2429 case XML_TOK_START_TAG_NO_ATTS:
2430 /* fall through */
2431 case XML_TOK_START_TAG_WITH_ATTS:
2432 {
2433 TAG *tag;
2434 enum XML_Error result;
2435 XML_Char *toPtr;
2436 if (freeTagList) {
2437 tag = freeTagList;
2438 freeTagList = freeTagList->parent;
2439 }
2440 else {
2441 tag = (TAG *)MALLOC(sizeof(TAG));
2442 if (!tag)
2443 return XML_ERROR_NO_MEMORY;
2444 tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);
2445 if (!tag->buf) {
2446 FREE(tag);
2447 return XML_ERROR_NO_MEMORY;
2448 }
2449 tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
2450 }
2451 tag->bindings = NULL;
2452 tag->parent = tagStack;
2453 tagStack = tag;
2454 tag->name.localPart = NULL;
2455 tag->name.prefix = NULL;
2456 tag->rawName = s + enc->minBytesPerChar;
2457 tag->rawNameLength = XmlNameLength(enc, tag->rawName);
2458 ++tagLevel;
2459 {
2460 const char *rawNameEnd = tag->rawName + tag->rawNameLength;
2461 const char *fromPtr = tag->rawName;
2462 toPtr = (XML_Char *)tag->buf;
2463 for (;;) {
2464 int bufSize;
2465 int convLen;
2466 const enum XML_Convert_Result convert_res = XmlConvert(enc,
2467 &fromPtr, rawNameEnd,
2468 (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
2469 convLen = (int)(toPtr - (XML_Char *)tag->buf);
2470 if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) {
2471 tag->name.strLen = convLen;
2472 break;
2473 }
2474 bufSize = (int)(tag->bufEnd - tag->buf) << 1;
2475 {
2476 char *temp = (char *)REALLOC(tag->buf, bufSize);
2477 if (temp == NULL)
2478 return XML_ERROR_NO_MEMORY;
2479 tag->buf = temp;
2480 tag->bufEnd = temp + bufSize;
2481 toPtr = (XML_Char *)temp + convLen;
2482 }
2483 }
2484 }
2485 tag->name.str = (XML_Char *)tag->buf;
2486 *toPtr = XML_T('\0');
2487 result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
2488 if (result)
2489 return result;
2490 if (startElementHandler)
2491 startElementHandler(handlerArg, tag->name.str,
2492 (const XML_Char **)atts);
2493 else if (defaultHandler)
2494 reportDefault(parser, enc, s, next);
2495 poolClear(&tempPool);
2496 break;
2497 }
2498 case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
2499 /* fall through */
2500 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
2501 {
2502 const char *rawName = s + enc->minBytesPerChar;
2503 enum XML_Error result;
2504 BINDING *bindings = NULL;
2505 XML_Bool noElmHandlers = XML_TRUE;
2506 TAG_NAME name;
2507 name.str = poolStoreString(&tempPool, enc, rawName,
2508 rawName + XmlNameLength(enc, rawName));
2509 if (!name.str)
2510 return XML_ERROR_NO_MEMORY;
2511 poolFinish(&tempPool);
2512 result = storeAtts(parser, enc, s, &name, &bindings);
2513 if (result)
2514 return result;
2515 poolFinish(&tempPool);
2516 if (startElementHandler) {
2517 startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
2518 noElmHandlers = XML_FALSE;
2519 }
2520 if (endElementHandler) {
2521 if (startElementHandler)
2522 *eventPP = *eventEndPP;
2523 endElementHandler(handlerArg, name.str);
2524 noElmHandlers = XML_FALSE;
2525 }
2526 if (noElmHandlers && defaultHandler)
2527 reportDefault(parser, enc, s, next);
2528 poolClear(&tempPool);
2529 while (bindings) {
2530 BINDING *b = bindings;
2531 if (endNamespaceDeclHandler)
2532 endNamespaceDeclHandler(handlerArg, b->prefix->name);
2533 bindings = bindings->nextTagBinding;
2534 b->nextTagBinding = freeBindingList;
2535 freeBindingList = b;
2536 b->prefix->binding = b->prevPrefixBinding;
2537 }
2538 }
2539 if (tagLevel == 0)
2540 return epilogProcessor(parser, next, end, nextPtr);
2541 break;
2542 case XML_TOK_END_TAG:
2543 if (tagLevel == startTagLevel)
2544 return XML_ERROR_ASYNC_ENTITY;
2545 else {
2546 int len;
2547 const char *rawName;
2548 TAG *tag = tagStack;
2549 tagStack = tag->parent;
2550 tag->parent = freeTagList;
2551 freeTagList = tag;
2552 rawName = s + enc->minBytesPerChar*2;
2553 len = XmlNameLength(enc, rawName);
2554 if (len != tag->rawNameLength
2555 || memcmp(tag->rawName, rawName, len) != 0) {
2556 *eventPP = rawName;
2557 return XML_ERROR_TAG_MISMATCH;
2558 }
2559 --tagLevel;
2560 if (endElementHandler) {
2561 const XML_Char *localPart;
2562 const XML_Char *prefix;
2563 XML_Char *uri;
2564 localPart = tag->name.localPart;
2565 if (ns && localPart) {
2566 /* localPart and prefix may have been overwritten in
2567 tag->name.str, since this points to the binding->uri
2568 buffer which gets re-used; so we have to add them again
2569 */
2570 uri = (XML_Char *)tag->name.str + tag->name.uriLen;
2571 /* don't need to check for space - already done in storeAtts() */
2572 while (*localPart) *uri++ = *localPart++;
2573 prefix = (XML_Char *)tag->name.prefix;
2574 if (ns_triplets && prefix) {
2575 *uri++ = namespaceSeparator;
2576 while (*prefix) *uri++ = *prefix++;
2577 }
2578 *uri = XML_T('\0');
2579 }
2580 endElementHandler(handlerArg, tag->name.str);
2581 }
2582 else if (defaultHandler)
2583 reportDefault(parser, enc, s, next);
2584 while (tag->bindings) {
2585 BINDING *b = tag->bindings;
2586 if (endNamespaceDeclHandler)
2587 endNamespaceDeclHandler(handlerArg, b->prefix->name);
2588 tag->bindings = tag->bindings->nextTagBinding;
2589 b->nextTagBinding = freeBindingList;
2590 freeBindingList = b;
2591 b->prefix->binding = b->prevPrefixBinding;
2592 }
2593 if (tagLevel == 0)
2594 return epilogProcessor(parser, next, end, nextPtr);
2595 }
2596 break;
2597 case XML_TOK_CHAR_REF:
2598 {
2599 int n = XmlCharRefNumber(enc, s);
2600 if (n < 0)
2601 return XML_ERROR_BAD_CHAR_REF;
2602 if (characterDataHandler) {
2603 XML_Char buf[XML_ENCODE_MAX];
2604 characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
2605 }
2606 else if (defaultHandler)
2607 reportDefault(parser, enc, s, next);
2608 }
2609 break;
2610 case XML_TOK_XML_DECL:
2611 return XML_ERROR_MISPLACED_XML_PI;
2612 case XML_TOK_DATA_NEWLINE:
2613 if (characterDataHandler) {
2614 XML_Char c = 0xA;
2615 characterDataHandler(handlerArg, &c, 1);
2616 }
2617 else if (defaultHandler)
2618 reportDefault(parser, enc, s, next);
2619 break;
2620 case XML_TOK_CDATA_SECT_OPEN:
2621 {
2622 enum XML_Error result;
2623 if (startCdataSectionHandler)
2624 startCdataSectionHandler(handlerArg);
2625 #if 0
2626 /* Suppose you doing a transformation on a document that involves
2627 changing only the character data. You set up a defaultHandler
2628 and a characterDataHandler. The defaultHandler simply copies
2629 characters through. The characterDataHandler does the
2630 transformation and writes the characters out escaping them as
2631 necessary. This case will fail to work if we leave out the
2632 following two lines (because & and < inside CDATA sections will
2633 be incorrectly escaped).
2634
2635 However, now we have a start/endCdataSectionHandler, so it seems
2636 easier to let the user deal with this.
2637 */
2638 else if (characterDataHandler)
2639 characterDataHandler(handlerArg, dataBuf, 0);
2640 #endif
2641 else if (defaultHandler)
2642 reportDefault(parser, enc, s, next);
2643 result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
2644 if (result != XML_ERROR_NONE)
2645 return result;
2646 else if (!next) {
2647 processor = cdataSectionProcessor;
2648 return result;
2649 }
2650 }
2651 break;
2652 case XML_TOK_TRAILING_RSQB:
2653 if (haveMore) {
2654 *nextPtr = s;
2655 return XML_ERROR_NONE;
2656 }
2657 if (characterDataHandler) {
2658 if (MUST_CONVERT(enc, s)) {
2659 ICHAR *dataPtr = (ICHAR *)dataBuf;
2660 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
2661 characterDataHandler(handlerArg, dataBuf,
2662 (int)(dataPtr - (ICHAR *)dataBuf));
2663 }
2664 else
2665 characterDataHandler(handlerArg,
2666 (XML_Char *)s,
2667 (int)((XML_Char *)end - (XML_Char *)s));
2668 }
2669 else if (defaultHandler)
2670 reportDefault(parser, enc, s, end);
2671 /* We are at the end of the final buffer, should we check for
2672 XML_SUSPENDED, XML_FINISHED?
2673 */
2674 if (startTagLevel == 0) {
2675 *eventPP = end;
2676 return XML_ERROR_NO_ELEMENTS;
2677 }
2678 if (tagLevel != startTagLevel) {
2679 *eventPP = end;
2680 return XML_ERROR_ASYNC_ENTITY;
2681 }
2682 *nextPtr = end;
2683 return XML_ERROR_NONE;
2684 case XML_TOK_DATA_CHARS:
2685 {
2686 XML_CharacterDataHandler charDataHandler = characterDataHandler;
2687 if (charDataHandler) {
2688 if (MUST_CONVERT(enc, s)) {
2689 for (;;) {
2690 ICHAR *dataPtr = (ICHAR *)dataBuf;
2691 const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
2692 *eventEndPP = s;
2693 charDataHandler(handlerArg, dataBuf,
2694 (int)(dataPtr - (ICHAR *)dataBuf));
2695 if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
2696 break;
2697 *eventPP = s;
2698 }
2699 }
2700 else
2701 charDataHandler(handlerArg,
2702 (XML_Char *)s,
2703 (int)((XML_Char *)next - (XML_Char *)s));
2704 }
2705 else if (defaultHandler)
2706 reportDefault(parser, enc, s, next);
2707 }
2708 break;
2709 case XML_TOK_PI:
2710 if (!reportProcessingInstruction(parser, enc, s, next))
2711 return XML_ERROR_NO_MEMORY;
2712 break;
2713 case XML_TOK_COMMENT:
2714 if (!reportComment(parser, enc, s, next))
2715 return XML_ERROR_NO_MEMORY;
2716 break;
2717 default:
2718 if (defaultHandler)
2719 reportDefault(parser, enc, s, next);
2720 break;
2721 }
2722 *eventPP = s = next;
2723 switch (ps_parsing) {
2724 case XML_SUSPENDED:
2725 *nextPtr = next;
2726 return XML_ERROR_NONE;
2727 case XML_FINISHED:
2728 return XML_ERROR_ABORTED;
2729 default: ;
2730 }
2731 }
2732 /* not reached */
2733 }
2734
2735 /* Precondition: all arguments must be non-NULL;
2736 Purpose:
2737 - normalize attributes
2738 - check attributes for well-formedness
2739 - generate namespace aware attribute names (URI, prefix)
2740 - build list of attributes for startElementHandler
2741 - default attributes
2742 - process namespace declarations (check and report them)
2743 - generate namespace aware element name (URI, prefix)
2744 */
2745 static enum XML_Error
storeAtts(XML_Parser parser,const ENCODING * enc,const char * attStr,TAG_NAME * tagNamePtr,BINDING ** bindingsPtr)2746 storeAtts(XML_Parser parser, const ENCODING *enc,
2747 const char *attStr, TAG_NAME *tagNamePtr,
2748 BINDING **bindingsPtr)
2749 {
2750 DTD * const dtd = _dtd; /* save one level of indirection */
2751 ELEMENT_TYPE *elementType;
2752 int nDefaultAtts;
2753 const XML_Char **appAtts; /* the attribute list for the application */
2754 int attIndex = 0;
2755 int prefixLen;
2756 int i;
2757 int n;
2758 XML_Char *uri;
2759 int nPrefixes = 0;
2760 BINDING *binding;
2761 const XML_Char *localPart;
2762
2763 /* lookup the element type name */
2764 elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str,0);
2765 if (!elementType) {
2766 const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
2767 if (!name)
2768 return XML_ERROR_NO_MEMORY;
2769 elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
2770 sizeof(ELEMENT_TYPE));
2771 if (!elementType)
2772 return XML_ERROR_NO_MEMORY;
2773 if (ns && !setElementTypePrefix(parser, elementType))
2774 return XML_ERROR_NO_MEMORY;
2775 }
2776 nDefaultAtts = elementType->nDefaultAtts;
2777
2778 /* get the attributes from the tokenizer */
2779 n = XmlGetAttributes(enc, attStr, attsSize, atts);
2780 if (n + nDefaultAtts > attsSize) {
2781 int oldAttsSize = attsSize;
2782 ATTRIBUTE *temp;
2783 #ifdef XML_ATTR_INFO
2784 XML_AttrInfo *temp2;
2785 #endif
2786 attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
2787 temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
2788 if (temp == NULL)
2789 return XML_ERROR_NO_MEMORY;
2790 atts = temp;
2791 #ifdef XML_ATTR_INFO
2792 temp2 = (XML_AttrInfo *)REALLOC((void *)attInfo, attsSize * sizeof(XML_AttrInfo));
2793 if (temp2 == NULL)
2794 return XML_ERROR_NO_MEMORY;
2795 attInfo = temp2;
2796 #endif
2797 if (n > oldAttsSize)
2798 XmlGetAttributes(enc, attStr, n, atts);
2799 }
2800
2801 appAtts = (const XML_Char **)atts;
2802 for (i = 0; i < n; i++) {
2803 ATTRIBUTE *currAtt = &atts[i];
2804 #ifdef XML_ATTR_INFO
2805 XML_AttrInfo *currAttInfo = &attInfo[i];
2806 #endif
2807 /* add the name and value to the attribute list */
2808 ATTRIBUTE_ID *attId = getAttributeId(parser, enc, currAtt->name,
2809 currAtt->name
2810 + XmlNameLength(enc, currAtt->name));
2811 if (!attId)
2812 return XML_ERROR_NO_MEMORY;
2813 #ifdef XML_ATTR_INFO
2814 currAttInfo->nameStart = parseEndByteIndex - (parseEndPtr - currAtt->name);
2815 currAttInfo->nameEnd = currAttInfo->nameStart +
2816 XmlNameLength(enc, currAtt->name);
2817 currAttInfo->valueStart = parseEndByteIndex -
2818 (parseEndPtr - currAtt->valuePtr);
2819 currAttInfo->valueEnd = parseEndByteIndex - (parseEndPtr - currAtt->valueEnd);
2820 #endif
2821 /* Detect duplicate attributes by their QNames. This does not work when
2822 namespace processing is turned on and different prefixes for the same
2823 namespace are used. For this case we have a check further down.
2824 */
2825 if ((attId->name)[-1]) {
2826 if (enc == encoding)
2827 eventPtr = atts[i].name;
2828 return XML_ERROR_DUPLICATE_ATTRIBUTE;
2829 }
2830 (attId->name)[-1] = 1;
2831 appAtts[attIndex++] = attId->name;
2832 if (!atts[i].normalized) {
2833 enum XML_Error result;
2834 XML_Bool isCdata = XML_TRUE;
2835
2836 /* figure out whether declared as other than CDATA */
2837 if (attId->maybeTokenized) {
2838 int j;
2839 for (j = 0; j < nDefaultAtts; j++) {
2840 if (attId == elementType->defaultAtts[j].id) {
2841 isCdata = elementType->defaultAtts[j].isCdata;
2842 break;
2843 }
2844 }
2845 }
2846
2847 /* normalize the attribute value */
2848 result = storeAttributeValue(parser, enc, isCdata,
2849 atts[i].valuePtr, atts[i].valueEnd,
2850 &tempPool);
2851 if (result)
2852 return result;
2853 appAtts[attIndex] = poolStart(&tempPool);
2854 poolFinish(&tempPool);
2855 }
2856 else {
2857 /* the value did not need normalizing */
2858 appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,
2859 atts[i].valueEnd);
2860 if (appAtts[attIndex] == 0)
2861 return XML_ERROR_NO_MEMORY;
2862 poolFinish(&tempPool);
2863 }
2864 /* handle prefixed attribute names */
2865 if (attId->prefix) {
2866 if (attId->xmlns) {
2867 /* deal with namespace declarations here */
2868 enum XML_Error result = addBinding(parser, attId->prefix, attId,
2869 appAtts[attIndex], bindingsPtr);
2870 if (result)
2871 return result;
2872 --attIndex;
2873 }
2874 else {
2875 /* deal with other prefixed names later */
2876 attIndex++;
2877 nPrefixes++;
2878 (attId->name)[-1] = 2;
2879 }
2880 }
2881 else
2882 attIndex++;
2883 }
2884
2885 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
2886 nSpecifiedAtts = attIndex;
2887 if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
2888 for (i = 0; i < attIndex; i += 2)
2889 if (appAtts[i] == elementType->idAtt->name) {
2890 idAttIndex = i;
2891 break;
2892 }
2893 }
2894 else
2895 idAttIndex = -1;
2896
2897 /* do attribute defaulting */
2898 for (i = 0; i < nDefaultAtts; i++) {
2899 const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
2900 if (!(da->id->name)[-1] && da->value) {
2901 if (da->id->prefix) {
2902 if (da->id->xmlns) {
2903 enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
2904 da->value, bindingsPtr);
2905 if (result)
2906 return result;
2907 }
2908 else {
2909 (da->id->name)[-1] = 2;
2910 nPrefixes++;
2911 appAtts[attIndex++] = da->id->name;
2912 appAtts[attIndex++] = da->value;
2913 }
2914 }
2915 else {
2916 (da->id->name)[-1] = 1;
2917 appAtts[attIndex++] = da->id->name;
2918 appAtts[attIndex++] = da->value;
2919 }
2920 }
2921 }
2922 appAtts[attIndex] = 0;
2923
2924 /* expand prefixed attribute names, check for duplicates,
2925 and clear flags that say whether attributes were specified */
2926 i = 0;
2927 if (nPrefixes) {
2928 size_t j; /* hash table index */
2929 unsigned long version = nsAttsVersion;
2930 int nsAttsSize = (int)1 << nsAttsPower;
2931 /* size of hash table must be at least 2 * (# of prefixed attributes) */
2932 if ((nPrefixes << 1) >> nsAttsPower) { /* true for nsAttsPower = 0 */
2933 NS_ATT *temp;
2934 /* hash table size must also be a power of 2 and >= 8 */
2935 while (nPrefixes >> nsAttsPower++);
2936 if (nsAttsPower < 3)
2937 nsAttsPower = 3;
2938 nsAttsSize = (int)1 << nsAttsPower;
2939 temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));
2940 if (!temp)
2941 return XML_ERROR_NO_MEMORY;
2942 nsAtts = temp;
2943 version = 0; /* force re-initialization of nsAtts hash table */
2944 }
2945 /* using a version flag saves us from initializing nsAtts every time */
2946 if (!version) { /* initialize version flags when version wraps around */
2947 version = INIT_ATTS_VERSION;
2948 for (j = nsAttsSize; j != 0; )
2949 nsAtts[--j].version = version;
2950 }
2951 nsAttsVersion = --version;
2952
2953 /* expand prefixed names and check for duplicates */
2954 for (; i < attIndex; i += 2) {
2955 const XML_Char *s = appAtts[i];
2956 if (s[-1] == 2) { /* prefixed */
2957 ATTRIBUTE_ID *id;
2958 const BINDING *b;
2959 size_t uriHash = hash_secret_salt;
2960 ((XML_Char *)s)[-1] = 0; /* clear flag */
2961 id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);
2962 b = id->prefix->binding;
2963 if (!b)
2964 return XML_ERROR_UNBOUND_PREFIX;
2965
2966 /* as we expand the name we also calculate its hash value */
2967 for (j = 0; j < (size_t)b->uriLen; j++) {
2968 const XML_Char c = b->uri[j];
2969 if (!poolAppendChar(&tempPool, c))
2970 return XML_ERROR_NO_MEMORY;
2971 uriHash = CHAR_HASH(uriHash, c);
2972 }
2973 while (*s++ != XML_T(ASCII_COLON))
2974 ;
2975 do { /* copies null terminator */
2976 const XML_Char c = *s;
2977 if (!poolAppendChar(&tempPool, *s))
2978 return XML_ERROR_NO_MEMORY;
2979 uriHash = CHAR_HASH(uriHash, c);
2980 } while (*s++);
2981
2982 { /* Check hash table for duplicate of expanded name (uriName).
2983 Derived from code in lookup(parser, HASH_TABLE *table, ...).
2984 */
2985 unsigned char step = 0;
2986 size_t mask = nsAttsSize - 1;
2987 j = uriHash & mask; /* index into hash table */
2988 while (nsAtts[j].version == version) {
2989 /* for speed we compare stored hash values first */
2990 if (uriHash == nsAtts[j].hash) {
2991 const XML_Char *s1 = poolStart(&tempPool);
2992 const XML_Char *s2 = nsAtts[j].uriName;
2993 /* s1 is null terminated, but not s2 */
2994 for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
2995 if (*s1 == 0)
2996 return XML_ERROR_DUPLICATE_ATTRIBUTE;
2997 }
2998 if (!step)
2999 step = PROBE_STEP(uriHash, mask, nsAttsPower);
3000 j < step ? (j += nsAttsSize - step) : (j -= step);
3001 }
3002 }
3003
3004 if (ns_triplets) { /* append namespace separator and prefix */
3005 tempPool.ptr[-1] = namespaceSeparator;
3006 s = b->prefix->name;
3007 do {
3008 if (!poolAppendChar(&tempPool, *s))
3009 return XML_ERROR_NO_MEMORY;
3010 } while (*s++);
3011 }
3012
3013 /* store expanded name in attribute list */
3014 s = poolStart(&tempPool);
3015 poolFinish(&tempPool);
3016 appAtts[i] = s;
3017
3018 /* fill empty slot with new version, uriName and hash value */
3019 nsAtts[j].version = version;
3020 nsAtts[j].hash = uriHash;
3021 nsAtts[j].uriName = s;
3022
3023 if (!--nPrefixes) {
3024 i += 2;
3025 break;
3026 }
3027 }
3028 else /* not prefixed */
3029 ((XML_Char *)s)[-1] = 0; /* clear flag */
3030 }
3031 }
3032 /* clear flags for the remaining attributes */
3033 for (; i < attIndex; i += 2)
3034 ((XML_Char *)(appAtts[i]))[-1] = 0;
3035 for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
3036 binding->attId->name[-1] = 0;
3037
3038 if (!ns)
3039 return XML_ERROR_NONE;
3040
3041 /* expand the element type name */
3042 if (elementType->prefix) {
3043 binding = elementType->prefix->binding;
3044 if (!binding)
3045 return XML_ERROR_UNBOUND_PREFIX;
3046 localPart = tagNamePtr->str;
3047 while (*localPart++ != XML_T(ASCII_COLON))
3048 ;
3049 }
3050 else if (dtd->defaultPrefix.binding) {
3051 binding = dtd->defaultPrefix.binding;
3052 localPart = tagNamePtr->str;
3053 }
3054 else
3055 return XML_ERROR_NONE;
3056 prefixLen = 0;
3057 if (ns_triplets && binding->prefix->name) {
3058 for (; binding->prefix->name[prefixLen++];)
3059 ; /* prefixLen includes null terminator */
3060 }
3061 tagNamePtr->localPart = localPart;
3062 tagNamePtr->uriLen = binding->uriLen;
3063 tagNamePtr->prefix = binding->prefix->name;
3064 tagNamePtr->prefixLen = prefixLen;
3065 for (i = 0; localPart[i++];)
3066 ; /* i includes null terminator */
3067 n = i + binding->uriLen + prefixLen;
3068 if (n > binding->uriAlloc) {
3069 TAG *p;
3070 uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
3071 if (!uri)
3072 return XML_ERROR_NO_MEMORY;
3073 binding->uriAlloc = n + EXPAND_SPARE;
3074 memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
3075 for (p = tagStack; p; p = p->parent)
3076 if (p->name.str == binding->uri)
3077 p->name.str = uri;
3078 FREE(binding->uri);
3079 binding->uri = uri;
3080 }
3081 /* if namespaceSeparator != '\0' then uri includes it already */
3082 uri = binding->uri + binding->uriLen;
3083 memcpy(uri, localPart, i * sizeof(XML_Char));
3084 /* we always have a namespace separator between localPart and prefix */
3085 if (prefixLen) {
3086 uri += i - 1;
3087 *uri = namespaceSeparator; /* replace null terminator */
3088 memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
3089 }
3090 tagNamePtr->str = binding->uri;
3091 return XML_ERROR_NONE;
3092 }
3093
3094 /* addBinding() overwrites the value of prefix->binding without checking.
3095 Therefore one must keep track of the old value outside of addBinding().
3096 */
3097 static enum XML_Error
addBinding(XML_Parser parser,PREFIX * prefix,const ATTRIBUTE_ID * attId,const XML_Char * uri,BINDING ** bindingsPtr)3098 addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
3099 const XML_Char *uri, BINDING **bindingsPtr)
3100 {
3101 static const XML_Char xmlNamespace[] = {
3102 ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
3103 ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
3104 ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L,
3105 ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH,
3106 ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c,
3107 ASCII_e, '\0'
3108 };
3109 static const int xmlLen =
3110 (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;
3111 static const XML_Char xmlnsNamespace[] = {
3112 ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
3113 ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
3114 ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0,
3115 ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s,
3116 ASCII_SLASH, '\0'
3117 };
3118 static const int xmlnsLen =
3119 (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;
3120
3121 XML_Bool mustBeXML = XML_FALSE;
3122 XML_Bool isXML = XML_TRUE;
3123 XML_Bool isXMLNS = XML_TRUE;
3124
3125 BINDING *b;
3126 int len;
3127
3128 /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
3129 if (*uri == XML_T('\0') && prefix->name)
3130 return XML_ERROR_UNDECLARING_PREFIX;
3131
3132 if (prefix->name
3133 && prefix->name[0] == XML_T(ASCII_x)
3134 && prefix->name[1] == XML_T(ASCII_m)
3135 && prefix->name[2] == XML_T(ASCII_l)) {
3136
3137 /* Not allowed to bind xmlns */
3138 if (prefix->name[3] == XML_T(ASCII_n)
3139 && prefix->name[4] == XML_T(ASCII_s)
3140 && prefix->name[5] == XML_T('\0'))
3141 return XML_ERROR_RESERVED_PREFIX_XMLNS;
3142
3143 if (prefix->name[3] == XML_T('\0'))
3144 mustBeXML = XML_TRUE;
3145 }
3146
3147 for (len = 0; uri[len]; len++) {
3148 if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
3149 isXML = XML_FALSE;
3150
3151 if (!mustBeXML && isXMLNS
3152 && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
3153 isXMLNS = XML_FALSE;
3154 }
3155 isXML = isXML && len == xmlLen;
3156 isXMLNS = isXMLNS && len == xmlnsLen;
3157
3158 if (mustBeXML != isXML)
3159 return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
3160 : XML_ERROR_RESERVED_NAMESPACE_URI;
3161
3162 if (isXMLNS)
3163 return XML_ERROR_RESERVED_NAMESPACE_URI;
3164
3165 if (namespaceSeparator)
3166 len++;
3167 if (freeBindingList) {
3168 b = freeBindingList;
3169 if (len > b->uriAlloc) {
3170 XML_Char *temp = (XML_Char *)REALLOC(b->uri,
3171 sizeof(XML_Char) * (len + EXPAND_SPARE));
3172 if (temp == NULL)
3173 return XML_ERROR_NO_MEMORY;
3174 b->uri = temp;
3175 b->uriAlloc = len + EXPAND_SPARE;
3176 }
3177 freeBindingList = b->nextTagBinding;
3178 }
3179 else {
3180 b = (BINDING *)MALLOC(sizeof(BINDING));
3181 if (!b)
3182 return XML_ERROR_NO_MEMORY;
3183 b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
3184 if (!b->uri) {
3185 FREE(b);
3186 return XML_ERROR_NO_MEMORY;
3187 }
3188 b->uriAlloc = len + EXPAND_SPARE;
3189 }
3190 b->uriLen = len;
3191 memcpy(b->uri, uri, len * sizeof(XML_Char));
3192 if (namespaceSeparator)
3193 b->uri[len - 1] = namespaceSeparator;
3194 b->prefix = prefix;
3195 b->attId = attId;
3196 b->prevPrefixBinding = prefix->binding;
3197 /* NULL binding when default namespace undeclared */
3198 if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)
3199 prefix->binding = NULL;
3200 else
3201 prefix->binding = b;
3202 b->nextTagBinding = *bindingsPtr;
3203 *bindingsPtr = b;
3204 /* if attId == NULL then we are not starting a namespace scope */
3205 if (attId && startNamespaceDeclHandler)
3206 startNamespaceDeclHandler(handlerArg, prefix->name,
3207 prefix->binding ? uri : 0);
3208 return XML_ERROR_NONE;
3209 }
3210
3211 /* The idea here is to avoid using stack for each CDATA section when
3212 the whole file is parsed with one call.
3213 */
3214 static enum XML_Error PTRCALL
cdataSectionProcessor(XML_Parser parser,const char * start,const char * end,const char ** endPtr)3215 cdataSectionProcessor(XML_Parser parser,
3216 const char *start,
3217 const char *end,
3218 const char **endPtr)
3219 {
3220 enum XML_Error result = doCdataSection(parser, encoding, &start, end,
3221 endPtr, (XML_Bool)!ps_finalBuffer);
3222 if (result != XML_ERROR_NONE)
3223 return result;
3224 if (start) {
3225 if (parentParser) { /* we are parsing an external entity */
3226 processor = externalEntityContentProcessor;
3227 return externalEntityContentProcessor(parser, start, end, endPtr);
3228 }
3229 else {
3230 processor = contentProcessor;
3231 return contentProcessor(parser, start, end, endPtr);
3232 }
3233 }
3234 return result;
3235 }
3236
3237 /* startPtr gets set to non-null if the section is closed, and to null if
3238 the section is not yet closed.
3239 */
3240 static enum XML_Error
doCdataSection(XML_Parser parser,const ENCODING * enc,const char ** startPtr,const char * end,const char ** nextPtr,XML_Bool haveMore)3241 doCdataSection(XML_Parser parser,
3242 const ENCODING *enc,
3243 const char **startPtr,
3244 const char *end,
3245 const char **nextPtr,
3246 XML_Bool haveMore)
3247 {
3248 const char *s = *startPtr;
3249 const char **eventPP;
3250 const char **eventEndPP;
3251 if (enc == encoding) {
3252 eventPP = &eventPtr;
3253 *eventPP = s;
3254 eventEndPP = &eventEndPtr;
3255 }
3256 else {
3257 eventPP = &(openInternalEntities->internalEventPtr);
3258 eventEndPP = &(openInternalEntities->internalEventEndPtr);
3259 }
3260 *eventPP = s;
3261 *startPtr = NULL;
3262
3263 for (;;) {
3264 const char *next;
3265 int tok = XmlCdataSectionTok(enc, s, end, &next);
3266 *eventEndPP = next;
3267 switch (tok) {
3268 case XML_TOK_CDATA_SECT_CLOSE:
3269 if (endCdataSectionHandler)
3270 endCdataSectionHandler(handlerArg);
3271 #if 0
3272 /* see comment under XML_TOK_CDATA_SECT_OPEN */
3273 else if (characterDataHandler)
3274 characterDataHandler(handlerArg, dataBuf, 0);
3275 #endif
3276 else if (defaultHandler)
3277 reportDefault(parser, enc, s, next);
3278 *startPtr = next;
3279 *nextPtr = next;
3280 if (ps_parsing == XML_FINISHED)
3281 return XML_ERROR_ABORTED;
3282 else
3283 return XML_ERROR_NONE;
3284 case XML_TOK_DATA_NEWLINE:
3285 if (characterDataHandler) {
3286 XML_Char c = 0xA;
3287 characterDataHandler(handlerArg, &c, 1);
3288 }
3289 else if (defaultHandler)
3290 reportDefault(parser, enc, s, next);
3291 break;
3292 case XML_TOK_DATA_CHARS:
3293 {
3294 XML_CharacterDataHandler charDataHandler = characterDataHandler;
3295 if (charDataHandler) {
3296 if (MUST_CONVERT(enc, s)) {
3297 for (;;) {
3298 ICHAR *dataPtr = (ICHAR *)dataBuf;
3299 const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
3300 *eventEndPP = next;
3301 charDataHandler(handlerArg, dataBuf,
3302 (int)(dataPtr - (ICHAR *)dataBuf));
3303 if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
3304 break;
3305 *eventPP = s;
3306 }
3307 }
3308 else
3309 charDataHandler(handlerArg,
3310 (XML_Char *)s,
3311 (int)((XML_Char *)next - (XML_Char *)s));
3312 }
3313 else if (defaultHandler)
3314 reportDefault(parser, enc, s, next);
3315 }
3316 break;
3317 case XML_TOK_INVALID:
3318 *eventPP = next;
3319 return XML_ERROR_INVALID_TOKEN;
3320 case XML_TOK_PARTIAL_CHAR:
3321 if (haveMore) {
3322 *nextPtr = s;
3323 return XML_ERROR_NONE;
3324 }
3325 return XML_ERROR_PARTIAL_CHAR;
3326 case XML_TOK_PARTIAL:
3327 case XML_TOK_NONE:
3328 if (haveMore) {
3329 *nextPtr = s;
3330 return XML_ERROR_NONE;
3331 }
3332 return XML_ERROR_UNCLOSED_CDATA_SECTION;
3333 default:
3334 *eventPP = next;
3335 return XML_ERROR_UNEXPECTED_STATE;
3336 }
3337
3338 *eventPP = s = next;
3339 switch (ps_parsing) {
3340 case XML_SUSPENDED:
3341 *nextPtr = next;
3342 return XML_ERROR_NONE;
3343 case XML_FINISHED:
3344 return XML_ERROR_ABORTED;
3345 default: ;
3346 }
3347 }
3348 /* not reached */
3349 }
3350
3351 #ifdef XML_DTD
3352
3353 /* The idea here is to avoid using stack for each IGNORE section when
3354 the whole file is parsed with one call.
3355 */
3356 static enum XML_Error PTRCALL
ignoreSectionProcessor(XML_Parser parser,const char * start,const char * end,const char ** endPtr)3357 ignoreSectionProcessor(XML_Parser parser,
3358 const char *start,
3359 const char *end,
3360 const char **endPtr)
3361 {
3362 enum XML_Error result = doIgnoreSection(parser, encoding, &start, end,
3363 endPtr, (XML_Bool)!ps_finalBuffer);
3364 if (result != XML_ERROR_NONE)
3365 return result;
3366 if (start) {
3367 processor = prologProcessor;
3368 return prologProcessor(parser, start, end, endPtr);
3369 }
3370 return result;
3371 }
3372
3373 /* startPtr gets set to non-null is the section is closed, and to null
3374 if the section is not yet closed.
3375 */
3376 static enum XML_Error
doIgnoreSection(XML_Parser parser,const ENCODING * enc,const char ** startPtr,const char * end,const char ** nextPtr,XML_Bool haveMore)3377 doIgnoreSection(XML_Parser parser,
3378 const ENCODING *enc,
3379 const char **startPtr,
3380 const char *end,
3381 const char **nextPtr,
3382 XML_Bool haveMore)
3383 {
3384 const char *next;
3385 int tok;
3386 const char *s = *startPtr;
3387 const char **eventPP;
3388 const char **eventEndPP;
3389 if (enc == encoding) {
3390 eventPP = &eventPtr;
3391 *eventPP = s;
3392 eventEndPP = &eventEndPtr;
3393 }
3394 else {
3395 eventPP = &(openInternalEntities->internalEventPtr);
3396 eventEndPP = &(openInternalEntities->internalEventEndPtr);
3397 }
3398 *eventPP = s;
3399 *startPtr = NULL;
3400 tok = XmlIgnoreSectionTok(enc, s, end, &next);
3401 *eventEndPP = next;
3402 switch (tok) {
3403 case XML_TOK_IGNORE_SECT:
3404 if (defaultHandler)
3405 reportDefault(parser, enc, s, next);
3406 *startPtr = next;
3407 *nextPtr = next;
3408 if (ps_parsing == XML_FINISHED)
3409 return XML_ERROR_ABORTED;
3410 else
3411 return XML_ERROR_NONE;
3412 case XML_TOK_INVALID:
3413 *eventPP = next;
3414 return XML_ERROR_INVALID_TOKEN;
3415 case XML_TOK_PARTIAL_CHAR:
3416 if (haveMore) {
3417 *nextPtr = s;
3418 return XML_ERROR_NONE;
3419 }
3420 return XML_ERROR_PARTIAL_CHAR;
3421 case XML_TOK_PARTIAL:
3422 case XML_TOK_NONE:
3423 if (haveMore) {
3424 *nextPtr = s;
3425 return XML_ERROR_NONE;
3426 }
3427 return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
3428 default:
3429 *eventPP = next;
3430 return XML_ERROR_UNEXPECTED_STATE;
3431 }
3432 /* not reached */
3433 }
3434
3435 #endif /* XML_DTD */
3436
3437 static enum XML_Error
initializeEncoding(XML_Parser parser)3438 initializeEncoding(XML_Parser parser)
3439 {
3440 const char *s;
3441 #ifdef XML_UNICODE
3442 char encodingBuf[128];
3443 if (!protocolEncodingName)
3444 s = NULL;
3445 else {
3446 int i;
3447 for (i = 0; protocolEncodingName[i]; i++) {
3448 if (i == sizeof(encodingBuf) - 1
3449 || (protocolEncodingName[i] & ~0x7f) != 0) {
3450 encodingBuf[0] = '\0';
3451 break;
3452 }
3453 encodingBuf[i] = (char)protocolEncodingName[i];
3454 }
3455 encodingBuf[i] = '\0';
3456 s = encodingBuf;
3457 }
3458 #else
3459 s = protocolEncodingName;
3460 #endif
3461 if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
3462 return XML_ERROR_NONE;
3463 return handleUnknownEncoding(parser, protocolEncodingName);
3464 }
3465
3466 static enum XML_Error
processXmlDecl(XML_Parser parser,int isGeneralTextEntity,const char * s,const char * next)3467 processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
3468 const char *s, const char *next)
3469 {
3470 const char *encodingName = NULL;
3471 const XML_Char *storedEncName = NULL;
3472 const ENCODING *newEncoding = NULL;
3473 const char *version = NULL;
3474 const char *versionend;
3475 const XML_Char *storedversion = NULL;
3476 int standalone = -1;
3477 if (!(ns
3478 ? XmlParseXmlDeclNS
3479 : XmlParseXmlDecl)(isGeneralTextEntity,
3480 encoding,
3481 s,
3482 next,
3483 &eventPtr,
3484 &version,
3485 &versionend,
3486 &encodingName,
3487 &newEncoding,
3488 &standalone)) {
3489 if (isGeneralTextEntity)
3490 return XML_ERROR_TEXT_DECL;
3491 else
3492 return XML_ERROR_XML_DECL;
3493 }
3494 if (!isGeneralTextEntity && standalone == 1) {
3495 _dtd->standalone = XML_TRUE;
3496 #ifdef XML_DTD
3497 if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
3498 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
3499 #endif /* XML_DTD */
3500 }
3501 if (xmlDeclHandler) {
3502 if (encodingName != NULL) {
3503 storedEncName = poolStoreString(&temp2Pool,
3504 encoding,
3505 encodingName,
3506 encodingName
3507 + XmlNameLength(encoding, encodingName));
3508 if (!storedEncName)
3509 return XML_ERROR_NO_MEMORY;
3510 poolFinish(&temp2Pool);
3511 }
3512 if (version) {
3513 storedversion = poolStoreString(&temp2Pool,
3514 encoding,
3515 version,
3516 versionend - encoding->minBytesPerChar);
3517 if (!storedversion)
3518 return XML_ERROR_NO_MEMORY;
3519 }
3520 xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
3521 }
3522 else if (defaultHandler)
3523 reportDefault(parser, encoding, s, next);
3524 if (protocolEncodingName == NULL) {
3525 if (newEncoding) {
3526 if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
3527 eventPtr = encodingName;
3528 return XML_ERROR_INCORRECT_ENCODING;
3529 }
3530 encoding = newEncoding;
3531 }
3532 else if (encodingName) {
3533 enum XML_Error result;
3534 if (!storedEncName) {
3535 storedEncName = poolStoreString(
3536 &temp2Pool, encoding, encodingName,
3537 encodingName + XmlNameLength(encoding, encodingName));
3538 if (!storedEncName)
3539 return XML_ERROR_NO_MEMORY;
3540 }
3541 result = handleUnknownEncoding(parser, storedEncName);
3542 poolClear(&temp2Pool);
3543 if (result == XML_ERROR_UNKNOWN_ENCODING)
3544 eventPtr = encodingName;
3545 return result;
3546 }
3547 }
3548
3549 if (storedEncName || storedversion)
3550 poolClear(&temp2Pool);
3551
3552 return XML_ERROR_NONE;
3553 }
3554
3555 static enum XML_Error
handleUnknownEncoding(XML_Parser parser,const XML_Char * encodingName)3556 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
3557 {
3558 if (unknownEncodingHandler) {
3559 XML_Encoding info;
3560 int i;
3561 for (i = 0; i < 256; i++)
3562 info.map[i] = -1;
3563 info.convert = NULL;
3564 info.data = NULL;
3565 info.release = NULL;
3566 if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,
3567 &info)) {
3568 ENCODING *enc;
3569 unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
3570 if (!unknownEncodingMem) {
3571 if (info.release)
3572 info.release(info.data);
3573 return XML_ERROR_NO_MEMORY;
3574 }
3575 enc = (ns
3576 ? XmlInitUnknownEncodingNS
3577 : XmlInitUnknownEncoding)(unknownEncodingMem,
3578 info.map,
3579 info.convert,
3580 info.data);
3581 if (enc) {
3582 unknownEncodingData = info.data;
3583 unknownEncodingRelease = info.release;
3584 encoding = enc;
3585 return XML_ERROR_NONE;
3586 }
3587 }
3588 if (info.release != NULL)
3589 info.release(info.data);
3590 }
3591 return XML_ERROR_UNKNOWN_ENCODING;
3592 }
3593
3594 static enum XML_Error PTRCALL
prologInitProcessor(XML_Parser parser,const char * s,const char * end,const char ** nextPtr)3595 prologInitProcessor(XML_Parser parser,
3596 const char *s,
3597 const char *end,
3598 const char **nextPtr)
3599 {
3600 enum XML_Error result = initializeEncoding(parser);
3601 if (result != XML_ERROR_NONE)
3602 return result;
3603 processor = prologProcessor;
3604 return prologProcessor(parser, s, end, nextPtr);
3605 }
3606
3607 #ifdef XML_DTD
3608
3609 static enum XML_Error PTRCALL
externalParEntInitProcessor(XML_Parser parser,const char * s,const char * end,const char ** nextPtr)3610 externalParEntInitProcessor(XML_Parser parser,
3611 const char *s,
3612 const char *end,
3613 const char **nextPtr)
3614 {
3615 enum XML_Error result = initializeEncoding(parser);
3616 if (result != XML_ERROR_NONE)
3617 return result;
3618
3619 /* we know now that XML_Parse(Buffer) has been called,
3620 so we consider the external parameter entity read */
3621 _dtd->paramEntityRead = XML_TRUE;
3622
3623 if (prologState.inEntityValue) {
3624 processor = entityValueInitProcessor;
3625 return entityValueInitProcessor(parser, s, end, nextPtr);
3626 }
3627 else {
3628 processor = externalParEntProcessor;
3629 return externalParEntProcessor(parser, s, end, nextPtr);
3630 }
3631 }
3632
3633 static enum XML_Error PTRCALL
entityValueInitProcessor(XML_Parser parser,const char * s,const char * end,const char ** nextPtr)3634 entityValueInitProcessor(XML_Parser parser,
3635 const char *s,
3636 const char *end,
3637 const char **nextPtr)
3638 {
3639 int tok;
3640 const char *start = s;
3641 const char *next = start;
3642 eventPtr = start;
3643
3644 for (;;) {
3645 tok = XmlPrologTok(encoding, start, end, &next);
3646 eventEndPtr = next;
3647 if (tok <= 0) {
3648 if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
3649 *nextPtr = s;
3650 return XML_ERROR_NONE;
3651 }
3652 switch (tok) {
3653 case XML_TOK_INVALID:
3654 return XML_ERROR_INVALID_TOKEN;
3655 case XML_TOK_PARTIAL:
3656 return XML_ERROR_UNCLOSED_TOKEN;
3657 case XML_TOK_PARTIAL_CHAR:
3658 return XML_ERROR_PARTIAL_CHAR;
3659 case XML_TOK_NONE: /* start == end */
3660 default:
3661 break;
3662 }
3663 /* found end of entity value - can store it now */
3664 return storeEntityValue(parser, encoding, s, end);
3665 }
3666 else if (tok == XML_TOK_XML_DECL) {
3667 enum XML_Error result;
3668 result = processXmlDecl(parser, 0, start, next);
3669 if (result != XML_ERROR_NONE)
3670 return result;
3671 switch (ps_parsing) {
3672 case XML_SUSPENDED:
3673 *nextPtr = next;
3674 return XML_ERROR_NONE;
3675 case XML_FINISHED:
3676 return XML_ERROR_ABORTED;
3677 default:
3678 *nextPtr = next;
3679 }
3680 /* stop scanning for text declaration - we found one */
3681 processor = entityValueProcessor;
3682 return entityValueProcessor(parser, next, end, nextPtr);
3683 }
3684 /* If we are at the end of the buffer, this would cause XmlPrologTok to
3685 return XML_TOK_NONE on the next call, which would then cause the
3686 function to exit with *nextPtr set to s - that is what we want for other
3687 tokens, but not for the BOM - we would rather like to skip it;
3688 then, when this routine is entered the next time, XmlPrologTok will
3689 return XML_TOK_INVALID, since the BOM is still in the buffer
3690 */
3691 else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {
3692 *nextPtr = next;
3693 return XML_ERROR_NONE;
3694 }
3695 /* If we get this token, we have the start of what might be a
3696 normal tag, but not a declaration (i.e. it doesn't begin with
3697 "<!"). In a DTD context, that isn't legal.
3698 */
3699 else if (tok == XML_TOK_INSTANCE_START) {
3700 *nextPtr = next;
3701 return XML_ERROR_SYNTAX;
3702 }
3703 start = next;
3704 eventPtr = start;
3705 }
3706 }
3707
3708 static enum XML_Error PTRCALL
externalParEntProcessor(XML_Parser parser,const char * s,const char * end,const char ** nextPtr)3709 externalParEntProcessor(XML_Parser parser,
3710 const char *s,
3711 const char *end,
3712 const char **nextPtr)
3713 {
3714 const char *next = s;
3715 int tok;
3716
3717 tok = XmlPrologTok(encoding, s, end, &next);
3718 if (tok <= 0) {
3719 if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
3720 *nextPtr = s;
3721 return XML_ERROR_NONE;
3722 }
3723 switch (tok) {
3724 case XML_TOK_INVALID:
3725 return XML_ERROR_INVALID_TOKEN;
3726 case XML_TOK_PARTIAL:
3727 return XML_ERROR_UNCLOSED_TOKEN;
3728 case XML_TOK_PARTIAL_CHAR:
3729 return XML_ERROR_PARTIAL_CHAR;
3730 case XML_TOK_NONE: /* start == end */
3731 default:
3732 break;
3733 }
3734 }
3735 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3736 However, when parsing an external subset, doProlog will not accept a BOM
3737 as valid, and report a syntax error, so we have to skip the BOM
3738 */
3739 else if (tok == XML_TOK_BOM) {
3740 s = next;
3741 tok = XmlPrologTok(encoding, s, end, &next);
3742 }
3743
3744 processor = prologProcessor;
3745 return doProlog(parser, encoding, s, end, tok, next,
3746 nextPtr, (XML_Bool)!ps_finalBuffer, XML_TRUE);
3747 }
3748
3749 static enum XML_Error PTRCALL
entityValueProcessor(XML_Parser parser,const char * s,const char * end,const char ** nextPtr)3750 entityValueProcessor(XML_Parser parser,
3751 const char *s,
3752 const char *end,
3753 const char **nextPtr)
3754 {
3755 const char *start = s;
3756 const char *next = s;
3757 const ENCODING *enc = encoding;
3758 int tok;
3759
3760 for (;;) {
3761 tok = XmlPrologTok(enc, start, end, &next);
3762 if (tok <= 0) {
3763 if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
3764 *nextPtr = s;
3765 return XML_ERROR_NONE;
3766 }
3767 switch (tok) {
3768 case XML_TOK_INVALID:
3769 return XML_ERROR_INVALID_TOKEN;
3770 case XML_TOK_PARTIAL:
3771 return XML_ERROR_UNCLOSED_TOKEN;
3772 case XML_TOK_PARTIAL_CHAR:
3773 return XML_ERROR_PARTIAL_CHAR;
3774 case XML_TOK_NONE: /* start == end */
3775 default:
3776 break;
3777 }
3778 /* found end of entity value - can store it now */
3779 return storeEntityValue(parser, enc, s, end);
3780 }
3781 start = next;
3782 }
3783 }
3784
3785 #endif /* XML_DTD */
3786
3787 static enum XML_Error PTRCALL
prologProcessor(XML_Parser parser,const char * s,const char * end,const char ** nextPtr)3788 prologProcessor(XML_Parser parser,
3789 const char *s,
3790 const char *end,
3791 const char **nextPtr)
3792 {
3793 const char *next = s;
3794 int tok = XmlPrologTok(encoding, s, end, &next);
3795 return doProlog(parser, encoding, s, end, tok, next,
3796 nextPtr, (XML_Bool)!ps_finalBuffer, XML_TRUE);
3797 }
3798
3799 static enum XML_Error
doProlog(XML_Parser parser,const ENCODING * enc,const char * s,const char * end,int tok,const char * next,const char ** nextPtr,XML_Bool haveMore,XML_Bool allowClosingDoctype)3800 doProlog(XML_Parser parser,
3801 const ENCODING *enc,
3802 const char *s,
3803 const char *end,
3804 int tok,
3805 const char *next,
3806 const char **nextPtr,
3807 XML_Bool haveMore,
3808 XML_Bool allowClosingDoctype)
3809 {
3810 #ifdef XML_DTD
3811 static const XML_Char externalSubsetName[] = { ASCII_HASH , '\0' };
3812 #endif /* XML_DTD */
3813 static const XML_Char atypeCDATA[] =
3814 { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
3815 static const XML_Char atypeID[] = { ASCII_I, ASCII_D, '\0' };
3816 static const XML_Char atypeIDREF[] =
3817 { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };
3818 static const XML_Char atypeIDREFS[] =
3819 { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };
3820 static const XML_Char atypeENTITY[] =
3821 { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };
3822 static const XML_Char atypeENTITIES[] = { ASCII_E, ASCII_N,
3823 ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0' };
3824 static const XML_Char atypeNMTOKEN[] = {
3825 ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' };
3826 static const XML_Char atypeNMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T,
3827 ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' };
3828 static const XML_Char notationPrefix[] = { ASCII_N, ASCII_O, ASCII_T,
3829 ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0' };
3830 static const XML_Char enumValueSep[] = { ASCII_PIPE, '\0' };
3831 static const XML_Char enumValueStart[] = { ASCII_LPAREN, '\0' };
3832
3833 /* save one level of indirection */
3834 DTD * const dtd = _dtd;
3835
3836 const char **eventPP;
3837 const char **eventEndPP;
3838 enum XML_Content_Quant quant;
3839
3840 if (enc == encoding) {
3841 eventPP = &eventPtr;
3842 eventEndPP = &eventEndPtr;
3843 }
3844 else {
3845 eventPP = &(openInternalEntities->internalEventPtr);
3846 eventEndPP = &(openInternalEntities->internalEventEndPtr);
3847 }
3848
3849 for (;;) {
3850 int role;
3851 XML_Bool handleDefault = XML_TRUE;
3852 *eventPP = s;
3853 *eventEndPP = next;
3854 if (tok <= 0) {
3855 if (haveMore && tok != XML_TOK_INVALID) {
3856 *nextPtr = s;
3857 return XML_ERROR_NONE;
3858 }
3859 switch (tok) {
3860 case XML_TOK_INVALID:
3861 *eventPP = next;
3862 return XML_ERROR_INVALID_TOKEN;
3863 case XML_TOK_PARTIAL:
3864 return XML_ERROR_UNCLOSED_TOKEN;
3865 case XML_TOK_PARTIAL_CHAR:
3866 return XML_ERROR_PARTIAL_CHAR;
3867 case -XML_TOK_PROLOG_S:
3868 tok = -tok;
3869 break;
3870 case XML_TOK_NONE:
3871 #ifdef XML_DTD
3872 /* for internal PE NOT referenced between declarations */
3873 if (enc != encoding && !openInternalEntities->betweenDecl) {
3874 *nextPtr = s;
3875 return XML_ERROR_NONE;
3876 }
3877 /* WFC: PE Between Declarations - must check that PE contains
3878 complete markup, not only for external PEs, but also for
3879 internal PEs if the reference occurs between declarations.
3880 */
3881 if (isParamEntity || enc != encoding) {
3882 if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
3883 == XML_ROLE_ERROR)
3884 return XML_ERROR_INCOMPLETE_PE;
3885 *nextPtr = s;
3886 return XML_ERROR_NONE;
3887 }
3888 #endif /* XML_DTD */
3889 return XML_ERROR_NO_ELEMENTS;
3890 default:
3891 tok = -tok;
3892 next = end;
3893 break;
3894 }
3895 }
3896 role = XmlTokenRole(&prologState, tok, s, next, enc);
3897 switch (role) {
3898 case XML_ROLE_XML_DECL:
3899 {
3900 enum XML_Error result = processXmlDecl(parser, 0, s, next);
3901 if (result != XML_ERROR_NONE)
3902 return result;
3903 enc = encoding;
3904 handleDefault = XML_FALSE;
3905 }
3906 break;
3907 case XML_ROLE_DOCTYPE_NAME:
3908 if (startDoctypeDeclHandler) {
3909 doctypeName = poolStoreString(&tempPool, enc, s, next);
3910 if (!doctypeName)
3911 return XML_ERROR_NO_MEMORY;
3912 poolFinish(&tempPool);
3913 doctypePubid = NULL;
3914 handleDefault = XML_FALSE;
3915 }
3916 doctypeSysid = NULL; /* always initialize to NULL */
3917 break;
3918 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
3919 if (startDoctypeDeclHandler) {
3920 startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
3921 doctypePubid, 1);
3922 doctypeName = NULL;
3923 poolClear(&tempPool);
3924 handleDefault = XML_FALSE;
3925 }
3926 break;
3927 #ifdef XML_DTD
3928 case XML_ROLE_TEXT_DECL:
3929 {
3930 enum XML_Error result = processXmlDecl(parser, 1, s, next);
3931 if (result != XML_ERROR_NONE)
3932 return result;
3933 enc = encoding;
3934 handleDefault = XML_FALSE;
3935 }
3936 break;
3937 #endif /* XML_DTD */
3938 case XML_ROLE_DOCTYPE_PUBLIC_ID:
3939 #ifdef XML_DTD
3940 useForeignDTD = XML_FALSE;
3941 declEntity = (ENTITY *)lookup(parser,
3942 &dtd->paramEntities,
3943 externalSubsetName,
3944 sizeof(ENTITY));
3945 if (!declEntity)
3946 return XML_ERROR_NO_MEMORY;
3947 #endif /* XML_DTD */
3948 dtd->hasParamEntityRefs = XML_TRUE;
3949 if (startDoctypeDeclHandler) {
3950 XML_Char *pubId;
3951 if (!XmlIsPublicId(enc, s, next, eventPP))
3952 return XML_ERROR_PUBLICID;
3953 pubId = poolStoreString(&tempPool, enc,
3954 s + enc->minBytesPerChar,
3955 next - enc->minBytesPerChar);
3956 if (!pubId)
3957 return XML_ERROR_NO_MEMORY;
3958 normalizePublicId(pubId);
3959 poolFinish(&tempPool);
3960 doctypePubid = pubId;
3961 handleDefault = XML_FALSE;
3962 goto alreadyChecked;
3963 }
3964 /* fall through */
3965 case XML_ROLE_ENTITY_PUBLIC_ID:
3966 if (!XmlIsPublicId(enc, s, next, eventPP))
3967 return XML_ERROR_PUBLICID;
3968 alreadyChecked:
3969 if (dtd->keepProcessing && declEntity) {
3970 XML_Char *tem = poolStoreString(&dtd->pool,
3971 enc,
3972 s + enc->minBytesPerChar,
3973 next - enc->minBytesPerChar);
3974 if (!tem)
3975 return XML_ERROR_NO_MEMORY;
3976 normalizePublicId(tem);
3977 declEntity->publicId = tem;
3978 poolFinish(&dtd->pool);
3979 if (entityDeclHandler)
3980 handleDefault = XML_FALSE;
3981 }
3982 break;
3983 case XML_ROLE_DOCTYPE_CLOSE:
3984 if (allowClosingDoctype != XML_TRUE) {
3985 /* Must not close doctype from within expanded parameter entities */
3986 return XML_ERROR_INVALID_TOKEN;
3987 }
3988
3989 if (doctypeName) {
3990 startDoctypeDeclHandler(handlerArg, doctypeName,
3991 doctypeSysid, doctypePubid, 0);
3992 poolClear(&tempPool);
3993 handleDefault = XML_FALSE;
3994 }
3995 /* doctypeSysid will be non-NULL in the case of a previous
3996 XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3997 was not set, indicating an external subset
3998 */
3999 #ifdef XML_DTD
4000 if (doctypeSysid || useForeignDTD) {
4001 XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
4002 dtd->hasParamEntityRefs = XML_TRUE;
4003 if (paramEntityParsing && externalEntityRefHandler) {
4004 ENTITY *entity = (ENTITY *)lookup(parser,
4005 &dtd->paramEntities,
4006 externalSubsetName,
4007 sizeof(ENTITY));
4008 if (!entity)
4009 return XML_ERROR_NO_MEMORY;
4010 if (useForeignDTD)
4011 entity->base = curBase;
4012 dtd->paramEntityRead = XML_FALSE;
4013 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
4014 0,
4015 entity->base,
4016 entity->systemId,
4017 entity->publicId))
4018 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4019 if (dtd->paramEntityRead) {
4020 if (!dtd->standalone &&
4021 notStandaloneHandler &&
4022 !notStandaloneHandler(handlerArg))
4023 return XML_ERROR_NOT_STANDALONE;
4024 }
4025 /* if we didn't read the foreign DTD then this means that there
4026 is no external subset and we must reset dtd->hasParamEntityRefs
4027 */
4028 else if (!doctypeSysid)
4029 dtd->hasParamEntityRefs = hadParamEntityRefs;
4030 /* end of DTD - no need to update dtd->keepProcessing */
4031 }
4032 useForeignDTD = XML_FALSE;
4033 }
4034 #endif /* XML_DTD */
4035 if (endDoctypeDeclHandler) {
4036 endDoctypeDeclHandler(handlerArg);
4037 handleDefault = XML_FALSE;
4038 }
4039 break;
4040 case XML_ROLE_INSTANCE_START:
4041 #ifdef XML_DTD
4042 /* if there is no DOCTYPE declaration then now is the
4043 last chance to read the foreign DTD
4044 */
4045 if (useForeignDTD) {
4046 XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
4047 dtd->hasParamEntityRefs = XML_TRUE;
4048 if (paramEntityParsing && externalEntityRefHandler) {
4049 ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
4050 externalSubsetName,
4051 sizeof(ENTITY));
4052 if (!entity)
4053 return XML_ERROR_NO_MEMORY;
4054 entity->base = curBase;
4055 dtd->paramEntityRead = XML_FALSE;
4056 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
4057 0,
4058 entity->base,
4059 entity->systemId,
4060 entity->publicId))
4061 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4062 if (dtd->paramEntityRead) {
4063 if (!dtd->standalone &&
4064 notStandaloneHandler &&
4065 !notStandaloneHandler(handlerArg))
4066 return XML_ERROR_NOT_STANDALONE;
4067 }
4068 /* if we didn't read the foreign DTD then this means that there
4069 is no external subset and we must reset dtd->hasParamEntityRefs
4070 */
4071 else
4072 dtd->hasParamEntityRefs = hadParamEntityRefs;
4073 /* end of DTD - no need to update dtd->keepProcessing */
4074 }
4075 }
4076 #endif /* XML_DTD */
4077 processor = contentProcessor;
4078 return contentProcessor(parser, s, end, nextPtr);
4079 case XML_ROLE_ATTLIST_ELEMENT_NAME:
4080 declElementType = getElementType(parser, enc, s, next);
4081 if (!declElementType)
4082 return XML_ERROR_NO_MEMORY;
4083 goto checkAttListDeclHandler;
4084 case XML_ROLE_ATTRIBUTE_NAME:
4085 declAttributeId = getAttributeId(parser, enc, s, next);
4086 if (!declAttributeId)
4087 return XML_ERROR_NO_MEMORY;
4088 declAttributeIsCdata = XML_FALSE;
4089 declAttributeType = NULL;
4090 declAttributeIsId = XML_FALSE;
4091 goto checkAttListDeclHandler;
4092 case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
4093 declAttributeIsCdata = XML_TRUE;
4094 declAttributeType = atypeCDATA;
4095 goto checkAttListDeclHandler;
4096 case XML_ROLE_ATTRIBUTE_TYPE_ID:
4097 declAttributeIsId = XML_TRUE;
4098 declAttributeType = atypeID;
4099 goto checkAttListDeclHandler;
4100 case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
4101 declAttributeType = atypeIDREF;
4102 goto checkAttListDeclHandler;
4103 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
4104 declAttributeType = atypeIDREFS;
4105 goto checkAttListDeclHandler;
4106 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
4107 declAttributeType = atypeENTITY;
4108 goto checkAttListDeclHandler;
4109 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
4110 declAttributeType = atypeENTITIES;
4111 goto checkAttListDeclHandler;
4112 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
4113 declAttributeType = atypeNMTOKEN;
4114 goto checkAttListDeclHandler;
4115 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
4116 declAttributeType = atypeNMTOKENS;
4117 checkAttListDeclHandler:
4118 if (dtd->keepProcessing && attlistDeclHandler)
4119 handleDefault = XML_FALSE;
4120 break;
4121 case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
4122 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
4123 if (dtd->keepProcessing && attlistDeclHandler) {
4124 const XML_Char *prefix;
4125 if (declAttributeType) {
4126 prefix = enumValueSep;
4127 }
4128 else {
4129 prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
4130 ? notationPrefix
4131 : enumValueStart);
4132 }
4133 if (!poolAppendString(&tempPool, prefix))
4134 return XML_ERROR_NO_MEMORY;
4135 if (!poolAppend(&tempPool, enc, s, next))
4136 return XML_ERROR_NO_MEMORY;
4137 declAttributeType = tempPool.start;
4138 handleDefault = XML_FALSE;
4139 }
4140 break;
4141 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
4142 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
4143 if (dtd->keepProcessing) {
4144 if (!defineAttribute(declElementType, declAttributeId,
4145 declAttributeIsCdata, declAttributeIsId,
4146 0, parser))
4147 return XML_ERROR_NO_MEMORY;
4148 if (attlistDeclHandler && declAttributeType) {
4149 if (*declAttributeType == XML_T(ASCII_LPAREN)
4150 || (*declAttributeType == XML_T(ASCII_N)
4151 && declAttributeType[1] == XML_T(ASCII_O))) {
4152 /* Enumerated or Notation type */
4153 if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
4154 || !poolAppendChar(&tempPool, XML_T('\0')))
4155 return XML_ERROR_NO_MEMORY;
4156 declAttributeType = tempPool.start;
4157 poolFinish(&tempPool);
4158 }
4159 *eventEndPP = s;
4160 attlistDeclHandler(handlerArg, declElementType->name,
4161 declAttributeId->name, declAttributeType,
4162 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
4163 poolClear(&tempPool);
4164 handleDefault = XML_FALSE;
4165 }
4166 }
4167 break;
4168 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
4169 case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
4170 if (dtd->keepProcessing) {
4171 const XML_Char *attVal;
4172 enum XML_Error result =
4173 storeAttributeValue(parser, enc, declAttributeIsCdata,
4174 s + enc->minBytesPerChar,
4175 next - enc->minBytesPerChar,
4176 &dtd->pool);
4177 if (result)
4178 return result;
4179 attVal = poolStart(&dtd->pool);
4180 poolFinish(&dtd->pool);
4181 /* ID attributes aren't allowed to have a default */
4182 if (!defineAttribute(declElementType, declAttributeId,
4183 declAttributeIsCdata, XML_FALSE, attVal, parser))
4184 return XML_ERROR_NO_MEMORY;
4185 if (attlistDeclHandler && declAttributeType) {
4186 if (*declAttributeType == XML_T(ASCII_LPAREN)
4187 || (*declAttributeType == XML_T(ASCII_N)
4188 && declAttributeType[1] == XML_T(ASCII_O))) {
4189 /* Enumerated or Notation type */
4190 if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
4191 || !poolAppendChar(&tempPool, XML_T('\0')))
4192 return XML_ERROR_NO_MEMORY;
4193 declAttributeType = tempPool.start;
4194 poolFinish(&tempPool);
4195 }
4196 *eventEndPP = s;
4197 attlistDeclHandler(handlerArg, declElementType->name,
4198 declAttributeId->name, declAttributeType,
4199 attVal,
4200 role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
4201 poolClear(&tempPool);
4202 handleDefault = XML_FALSE;
4203 }
4204 }
4205 break;
4206 case XML_ROLE_ENTITY_VALUE:
4207 if (dtd->keepProcessing) {
4208 enum XML_Error result = storeEntityValue(parser, enc,
4209 s + enc->minBytesPerChar,
4210 next - enc->minBytesPerChar);
4211 if (declEntity) {
4212 declEntity->textPtr = poolStart(&dtd->entityValuePool);
4213 declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));
4214 poolFinish(&dtd->entityValuePool);
4215 if (entityDeclHandler) {
4216 *eventEndPP = s;
4217 entityDeclHandler(handlerArg,
4218 declEntity->name,
4219 declEntity->is_param,
4220 declEntity->textPtr,
4221 declEntity->textLen,
4222 curBase, 0, 0, 0);
4223 handleDefault = XML_FALSE;
4224 }
4225 }
4226 else
4227 poolDiscard(&dtd->entityValuePool);
4228 if (result != XML_ERROR_NONE)
4229 return result;
4230 }
4231 break;
4232 case XML_ROLE_DOCTYPE_SYSTEM_ID:
4233 #ifdef XML_DTD
4234 useForeignDTD = XML_FALSE;
4235 #endif /* XML_DTD */
4236 dtd->hasParamEntityRefs = XML_TRUE;
4237 if (startDoctypeDeclHandler) {
4238 doctypeSysid = poolStoreString(&tempPool, enc,
4239 s + enc->minBytesPerChar,
4240 next - enc->minBytesPerChar);
4241 if (doctypeSysid == NULL)
4242 return XML_ERROR_NO_MEMORY;
4243 poolFinish(&tempPool);
4244 handleDefault = XML_FALSE;
4245 }
4246 #ifdef XML_DTD
4247 else
4248 /* use externalSubsetName to make doctypeSysid non-NULL
4249 for the case where no startDoctypeDeclHandler is set */
4250 doctypeSysid = externalSubsetName;
4251 #endif /* XML_DTD */
4252 if (!dtd->standalone
4253 #ifdef XML_DTD
4254 && !paramEntityParsing
4255 #endif /* XML_DTD */
4256 && notStandaloneHandler
4257 && !notStandaloneHandler(handlerArg))
4258 return XML_ERROR_NOT_STANDALONE;
4259 #ifndef XML_DTD
4260 break;
4261 #else /* XML_DTD */
4262 if (!declEntity) {
4263 declEntity = (ENTITY *)lookup(parser,
4264 &dtd->paramEntities,
4265 externalSubsetName,
4266 sizeof(ENTITY));
4267 if (!declEntity)
4268 return XML_ERROR_NO_MEMORY;
4269 declEntity->publicId = NULL;
4270 }
4271 /* fall through */
4272 #endif /* XML_DTD */
4273 case XML_ROLE_ENTITY_SYSTEM_ID:
4274 if (dtd->keepProcessing && declEntity) {
4275 declEntity->systemId = poolStoreString(&dtd->pool, enc,
4276 s + enc->minBytesPerChar,
4277 next - enc->minBytesPerChar);
4278 if (!declEntity->systemId)
4279 return XML_ERROR_NO_MEMORY;
4280 declEntity->base = curBase;
4281 poolFinish(&dtd->pool);
4282 if (entityDeclHandler)
4283 handleDefault = XML_FALSE;
4284 }
4285 break;
4286 case XML_ROLE_ENTITY_COMPLETE:
4287 if (dtd->keepProcessing && declEntity && entityDeclHandler) {
4288 *eventEndPP = s;
4289 entityDeclHandler(handlerArg,
4290 declEntity->name,
4291 declEntity->is_param,
4292 0,0,
4293 declEntity->base,
4294 declEntity->systemId,
4295 declEntity->publicId,
4296 0);
4297 handleDefault = XML_FALSE;
4298 }
4299 break;
4300 case XML_ROLE_ENTITY_NOTATION_NAME:
4301 if (dtd->keepProcessing && declEntity) {
4302 declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
4303 if (!declEntity->notation)
4304 return XML_ERROR_NO_MEMORY;
4305 poolFinish(&dtd->pool);
4306 if (unparsedEntityDeclHandler) {
4307 *eventEndPP = s;
4308 unparsedEntityDeclHandler(handlerArg,
4309 declEntity->name,
4310 declEntity->base,
4311 declEntity->systemId,
4312 declEntity->publicId,
4313 declEntity->notation);
4314 handleDefault = XML_FALSE;
4315 }
4316 else if (entityDeclHandler) {
4317 *eventEndPP = s;
4318 entityDeclHandler(handlerArg,
4319 declEntity->name,
4320 0,0,0,
4321 declEntity->base,
4322 declEntity->systemId,
4323 declEntity->publicId,
4324 declEntity->notation);
4325 handleDefault = XML_FALSE;
4326 }
4327 }
4328 break;
4329 case XML_ROLE_GENERAL_ENTITY_NAME:
4330 {
4331 if (XmlPredefinedEntityName(enc, s, next)) {
4332 declEntity = NULL;
4333 break;
4334 }
4335 if (dtd->keepProcessing) {
4336 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
4337 if (!name)
4338 return XML_ERROR_NO_MEMORY;
4339 declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, name,
4340 sizeof(ENTITY));
4341 if (!declEntity)
4342 return XML_ERROR_NO_MEMORY;
4343 if (declEntity->name != name) {
4344 poolDiscard(&dtd->pool);
4345 declEntity = NULL;
4346 }
4347 else {
4348 poolFinish(&dtd->pool);
4349 declEntity->publicId = NULL;
4350 declEntity->is_param = XML_FALSE;
4351 /* if we have a parent parser or are reading an internal parameter
4352 entity, then the entity declaration is not considered "internal"
4353 */
4354 declEntity->is_internal = !(parentParser || openInternalEntities);
4355 if (entityDeclHandler)
4356 handleDefault = XML_FALSE;
4357 }
4358 }
4359 else {
4360 poolDiscard(&dtd->pool);
4361 declEntity = NULL;
4362 }
4363 }
4364 break;
4365 case XML_ROLE_PARAM_ENTITY_NAME:
4366 #ifdef XML_DTD
4367 if (dtd->keepProcessing) {
4368 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
4369 if (!name)
4370 return XML_ERROR_NO_MEMORY;
4371 declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities,
4372 name, sizeof(ENTITY));
4373 if (!declEntity)
4374 return XML_ERROR_NO_MEMORY;
4375 if (declEntity->name != name) {
4376 poolDiscard(&dtd->pool);
4377 declEntity = NULL;
4378 }
4379 else {
4380 poolFinish(&dtd->pool);
4381 declEntity->publicId = NULL;
4382 declEntity->is_param = XML_TRUE;
4383 /* if we have a parent parser or are reading an internal parameter
4384 entity, then the entity declaration is not considered "internal"
4385 */
4386 declEntity->is_internal = !(parentParser || openInternalEntities);
4387 if (entityDeclHandler)
4388 handleDefault = XML_FALSE;
4389 }
4390 }
4391 else {
4392 poolDiscard(&dtd->pool);
4393 declEntity = NULL;
4394 }
4395 #else /* not XML_DTD */
4396 declEntity = NULL;
4397 #endif /* XML_DTD */
4398 break;
4399 case XML_ROLE_NOTATION_NAME:
4400 declNotationPublicId = NULL;
4401 declNotationName = NULL;
4402 if (notationDeclHandler) {
4403 declNotationName = poolStoreString(&tempPool, enc, s, next);
4404 if (!declNotationName)
4405 return XML_ERROR_NO_MEMORY;
4406 poolFinish(&tempPool);
4407 handleDefault = XML_FALSE;
4408 }
4409 break;
4410 case XML_ROLE_NOTATION_PUBLIC_ID:
4411 if (!XmlIsPublicId(enc, s, next, eventPP))
4412 return XML_ERROR_PUBLICID;
4413 if (declNotationName) { /* means notationDeclHandler != NULL */
4414 XML_Char *tem = poolStoreString(&tempPool,
4415 enc,
4416 s + enc->minBytesPerChar,
4417 next - enc->minBytesPerChar);
4418 if (!tem)
4419 return XML_ERROR_NO_MEMORY;
4420 normalizePublicId(tem);
4421 declNotationPublicId = tem;
4422 poolFinish(&tempPool);
4423 handleDefault = XML_FALSE;
4424 }
4425 break;
4426 case XML_ROLE_NOTATION_SYSTEM_ID:
4427 if (declNotationName && notationDeclHandler) {
4428 const XML_Char *systemId
4429 = poolStoreString(&tempPool, enc,
4430 s + enc->minBytesPerChar,
4431 next - enc->minBytesPerChar);
4432 if (!systemId)
4433 return XML_ERROR_NO_MEMORY;
4434 *eventEndPP = s;
4435 notationDeclHandler(handlerArg,
4436 declNotationName,
4437 curBase,
4438 systemId,
4439 declNotationPublicId);
4440 handleDefault = XML_FALSE;
4441 }
4442 poolClear(&tempPool);
4443 break;
4444 case XML_ROLE_NOTATION_NO_SYSTEM_ID:
4445 if (declNotationPublicId && notationDeclHandler) {
4446 *eventEndPP = s;
4447 notationDeclHandler(handlerArg,
4448 declNotationName,
4449 curBase,
4450 0,
4451 declNotationPublicId);
4452 handleDefault = XML_FALSE;
4453 }
4454 poolClear(&tempPool);
4455 break;
4456 case XML_ROLE_ERROR:
4457 switch (tok) {
4458 case XML_TOK_PARAM_ENTITY_REF:
4459 /* PE references in internal subset are
4460 not allowed within declarations. */
4461 return XML_ERROR_PARAM_ENTITY_REF;
4462 case XML_TOK_XML_DECL:
4463 return XML_ERROR_MISPLACED_XML_PI;
4464 default:
4465 return XML_ERROR_SYNTAX;
4466 }
4467 #ifdef XML_DTD
4468 case XML_ROLE_IGNORE_SECT:
4469 {
4470 enum XML_Error result;
4471 if (defaultHandler)
4472 reportDefault(parser, enc, s, next);
4473 handleDefault = XML_FALSE;
4474 result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
4475 if (result != XML_ERROR_NONE)
4476 return result;
4477 else if (!next) {
4478 processor = ignoreSectionProcessor;
4479 return result;
4480 }
4481 }
4482 break;
4483 #endif /* XML_DTD */
4484 case XML_ROLE_GROUP_OPEN:
4485 if (prologState.level >= groupSize) {
4486 if (groupSize) {
4487 char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
4488 if (temp == NULL)
4489 return XML_ERROR_NO_MEMORY;
4490 groupConnector = temp;
4491 if (dtd->scaffIndex) {
4492 int *temp = (int *)REALLOC(dtd->scaffIndex,
4493 groupSize * sizeof(int));
4494 if (temp == NULL)
4495 return XML_ERROR_NO_MEMORY;
4496 dtd->scaffIndex = temp;
4497 }
4498 }
4499 else {
4500 groupConnector = (char *)MALLOC(groupSize = 32);
4501 if (!groupConnector)
4502 return XML_ERROR_NO_MEMORY;
4503 }
4504 }
4505 groupConnector[prologState.level] = 0;
4506 if (dtd->in_eldecl) {
4507 int myindex = nextScaffoldPart(parser);
4508 if (myindex < 0)
4509 return XML_ERROR_NO_MEMORY;
4510 dtd->scaffIndex[dtd->scaffLevel] = myindex;
4511 dtd->scaffLevel++;
4512 dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
4513 if (elementDeclHandler)
4514 handleDefault = XML_FALSE;
4515 }
4516 break;
4517 case XML_ROLE_GROUP_SEQUENCE:
4518 if (groupConnector[prologState.level] == ASCII_PIPE)
4519 return XML_ERROR_SYNTAX;
4520 groupConnector[prologState.level] = ASCII_COMMA;
4521 if (dtd->in_eldecl && elementDeclHandler)
4522 handleDefault = XML_FALSE;
4523 break;
4524 case XML_ROLE_GROUP_CHOICE:
4525 if (groupConnector[prologState.level] == ASCII_COMMA)
4526 return XML_ERROR_SYNTAX;
4527 if (dtd->in_eldecl
4528 && !groupConnector[prologState.level]
4529 && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4530 != XML_CTYPE_MIXED)
4531 ) {
4532 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4533 = XML_CTYPE_CHOICE;
4534 if (elementDeclHandler)
4535 handleDefault = XML_FALSE;
4536 }
4537 groupConnector[prologState.level] = ASCII_PIPE;
4538 break;
4539 case XML_ROLE_PARAM_ENTITY_REF:
4540 #ifdef XML_DTD
4541 case XML_ROLE_INNER_PARAM_ENTITY_REF:
4542 dtd->hasParamEntityRefs = XML_TRUE;
4543 if (!paramEntityParsing)
4544 dtd->keepProcessing = dtd->standalone;
4545 else {
4546 const XML_Char *name;
4547 ENTITY *entity;
4548 name = poolStoreString(&dtd->pool, enc,
4549 s + enc->minBytesPerChar,
4550 next - enc->minBytesPerChar);
4551 if (!name)
4552 return XML_ERROR_NO_MEMORY;
4553 entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
4554 poolDiscard(&dtd->pool);
4555 /* first, determine if a check for an existing declaration is needed;
4556 if yes, check that the entity exists, and that it is internal,
4557 otherwise call the skipped entity handler
4558 */
4559 if (prologState.documentEntity &&
4560 (dtd->standalone
4561 ? !openInternalEntities
4562 : !dtd->hasParamEntityRefs)) {
4563 if (!entity)
4564 return XML_ERROR_UNDEFINED_ENTITY;
4565 else if (!entity->is_internal)
4566 return XML_ERROR_ENTITY_DECLARED_IN_PE;
4567 }
4568 else if (!entity) {
4569 dtd->keepProcessing = dtd->standalone;
4570 /* cannot report skipped entities in declarations */
4571 if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
4572 skippedEntityHandler(handlerArg, name, 1);
4573 handleDefault = XML_FALSE;
4574 }
4575 break;
4576 }
4577 if (entity->open)
4578 return XML_ERROR_RECURSIVE_ENTITY_REF;
4579 if (entity->textPtr) {
4580 enum XML_Error result;
4581 XML_Bool betweenDecl =
4582 (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
4583 result = processInternalEntity(parser, entity, betweenDecl);
4584 if (result != XML_ERROR_NONE)
4585 return result;
4586 handleDefault = XML_FALSE;
4587 break;
4588 }
4589 if (externalEntityRefHandler) {
4590 dtd->paramEntityRead = XML_FALSE;
4591 entity->open = XML_TRUE;
4592 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
4593 0,
4594 entity->base,
4595 entity->systemId,
4596 entity->publicId)) {
4597 entity->open = XML_FALSE;
4598 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4599 }
4600 entity->open = XML_FALSE;
4601 handleDefault = XML_FALSE;
4602 if (!dtd->paramEntityRead) {
4603 dtd->keepProcessing = dtd->standalone;
4604 break;
4605 }
4606 }
4607 else {
4608 dtd->keepProcessing = dtd->standalone;
4609 break;
4610 }
4611 }
4612 #endif /* XML_DTD */
4613 if (!dtd->standalone &&
4614 notStandaloneHandler &&
4615 !notStandaloneHandler(handlerArg))
4616 return XML_ERROR_NOT_STANDALONE;
4617 break;
4618
4619 /* Element declaration stuff */
4620
4621 case XML_ROLE_ELEMENT_NAME:
4622 if (elementDeclHandler) {
4623 declElementType = getElementType(parser, enc, s, next);
4624 if (!declElementType)
4625 return XML_ERROR_NO_MEMORY;
4626 dtd->scaffLevel = 0;
4627 dtd->scaffCount = 0;
4628 dtd->in_eldecl = XML_TRUE;
4629 handleDefault = XML_FALSE;
4630 }
4631 break;
4632
4633 case XML_ROLE_CONTENT_ANY:
4634 case XML_ROLE_CONTENT_EMPTY:
4635 if (dtd->in_eldecl) {
4636 if (elementDeclHandler) {
4637 XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
4638 if (!content)
4639 return XML_ERROR_NO_MEMORY;
4640 content->quant = XML_CQUANT_NONE;
4641 content->name = NULL;
4642 content->numchildren = 0;
4643 content->children = NULL;
4644 content->type = ((role == XML_ROLE_CONTENT_ANY) ?
4645 XML_CTYPE_ANY :
4646 XML_CTYPE_EMPTY);
4647 *eventEndPP = s;
4648 elementDeclHandler(handlerArg, declElementType->name, content);
4649 handleDefault = XML_FALSE;
4650 }
4651 dtd->in_eldecl = XML_FALSE;
4652 }
4653 break;
4654
4655 case XML_ROLE_CONTENT_PCDATA:
4656 if (dtd->in_eldecl) {
4657 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4658 = XML_CTYPE_MIXED;
4659 if (elementDeclHandler)
4660 handleDefault = XML_FALSE;
4661 }
4662 break;
4663
4664 case XML_ROLE_CONTENT_ELEMENT:
4665 quant = XML_CQUANT_NONE;
4666 goto elementContent;
4667 case XML_ROLE_CONTENT_ELEMENT_OPT:
4668 quant = XML_CQUANT_OPT;
4669 goto elementContent;
4670 case XML_ROLE_CONTENT_ELEMENT_REP:
4671 quant = XML_CQUANT_REP;
4672 goto elementContent;
4673 case XML_ROLE_CONTENT_ELEMENT_PLUS:
4674 quant = XML_CQUANT_PLUS;
4675 elementContent:
4676 if (dtd->in_eldecl) {
4677 ELEMENT_TYPE *el;
4678 const XML_Char *name;
4679 int nameLen;
4680 const char *nxt = (quant == XML_CQUANT_NONE
4681 ? next
4682 : next - enc->minBytesPerChar);
4683 int myindex = nextScaffoldPart(parser);
4684 if (myindex < 0)
4685 return XML_ERROR_NO_MEMORY;
4686 dtd->scaffold[myindex].type = XML_CTYPE_NAME;
4687 dtd->scaffold[myindex].quant = quant;
4688 el = getElementType(parser, enc, s, nxt);
4689 if (!el)
4690 return XML_ERROR_NO_MEMORY;
4691 name = el->name;
4692 dtd->scaffold[myindex].name = name;
4693 nameLen = 0;
4694 for (; name[nameLen++]; );
4695 dtd->contentStringLen += nameLen;
4696 if (elementDeclHandler)
4697 handleDefault = XML_FALSE;
4698 }
4699 break;
4700
4701 case XML_ROLE_GROUP_CLOSE:
4702 quant = XML_CQUANT_NONE;
4703 goto closeGroup;
4704 case XML_ROLE_GROUP_CLOSE_OPT:
4705 quant = XML_CQUANT_OPT;
4706 goto closeGroup;
4707 case XML_ROLE_GROUP_CLOSE_REP:
4708 quant = XML_CQUANT_REP;
4709 goto closeGroup;
4710 case XML_ROLE_GROUP_CLOSE_PLUS:
4711 quant = XML_CQUANT_PLUS;
4712 closeGroup:
4713 if (dtd->in_eldecl) {
4714 if (elementDeclHandler)
4715 handleDefault = XML_FALSE;
4716 dtd->scaffLevel--;
4717 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
4718 if (dtd->scaffLevel == 0) {
4719 if (!handleDefault) {
4720 XML_Content *model = build_model(parser);
4721 if (!model)
4722 return XML_ERROR_NO_MEMORY;
4723 *eventEndPP = s;
4724 elementDeclHandler(handlerArg, declElementType->name, model);
4725 }
4726 dtd->in_eldecl = XML_FALSE;
4727 dtd->contentStringLen = 0;
4728 }
4729 }
4730 break;
4731 /* End element declaration stuff */
4732
4733 case XML_ROLE_PI:
4734 if (!reportProcessingInstruction(parser, enc, s, next))
4735 return XML_ERROR_NO_MEMORY;
4736 handleDefault = XML_FALSE;
4737 break;
4738 case XML_ROLE_COMMENT:
4739 if (!reportComment(parser, enc, s, next))
4740 return XML_ERROR_NO_MEMORY;
4741 handleDefault = XML_FALSE;
4742 break;
4743 case XML_ROLE_NONE:
4744 switch (tok) {
4745 case XML_TOK_BOM:
4746 handleDefault = XML_FALSE;
4747 break;
4748 }
4749 break;
4750 case XML_ROLE_DOCTYPE_NONE:
4751 if (startDoctypeDeclHandler)
4752 handleDefault = XML_FALSE;
4753 break;
4754 case XML_ROLE_ENTITY_NONE:
4755 if (dtd->keepProcessing && entityDeclHandler)
4756 handleDefault = XML_FALSE;
4757 break;
4758 case XML_ROLE_NOTATION_NONE:
4759 if (notationDeclHandler)
4760 handleDefault = XML_FALSE;
4761 break;
4762 case XML_ROLE_ATTLIST_NONE:
4763 if (dtd->keepProcessing && attlistDeclHandler)
4764 handleDefault = XML_FALSE;
4765 break;
4766 case XML_ROLE_ELEMENT_NONE:
4767 if (elementDeclHandler)
4768 handleDefault = XML_FALSE;
4769 break;
4770 } /* end of big switch */
4771
4772 if (handleDefault && defaultHandler)
4773 reportDefault(parser, enc, s, next);
4774
4775 switch (ps_parsing) {
4776 case XML_SUSPENDED:
4777 *nextPtr = next;
4778 return XML_ERROR_NONE;
4779 case XML_FINISHED:
4780 return XML_ERROR_ABORTED;
4781 default:
4782 s = next;
4783 tok = XmlPrologTok(enc, s, end, &next);
4784 }
4785 }
4786 /* not reached */
4787 }
4788
4789 static enum XML_Error PTRCALL
epilogProcessor(XML_Parser parser,const char * s,const char * end,const char ** nextPtr)4790 epilogProcessor(XML_Parser parser,
4791 const char *s,
4792 const char *end,
4793 const char **nextPtr)
4794 {
4795 processor = epilogProcessor;
4796 eventPtr = s;
4797 for (;;) {
4798 const char *next = NULL;
4799 int tok = XmlPrologTok(encoding, s, end, &next);
4800 eventEndPtr = next;
4801 switch (tok) {
4802 /* report partial linebreak - it might be the last token */
4803 case -XML_TOK_PROLOG_S:
4804 if (defaultHandler) {
4805 reportDefault(parser, encoding, s, next);
4806 if (ps_parsing == XML_FINISHED)
4807 return XML_ERROR_ABORTED;
4808 }
4809 *nextPtr = next;
4810 return XML_ERROR_NONE;
4811 case XML_TOK_NONE:
4812 *nextPtr = s;
4813 return XML_ERROR_NONE;
4814 case XML_TOK_PROLOG_S:
4815 if (defaultHandler)
4816 reportDefault(parser, encoding, s, next);
4817 break;
4818 case XML_TOK_PI:
4819 if (!reportProcessingInstruction(parser, encoding, s, next))
4820 return XML_ERROR_NO_MEMORY;
4821 break;
4822 case XML_TOK_COMMENT:
4823 if (!reportComment(parser, encoding, s, next))
4824 return XML_ERROR_NO_MEMORY;
4825 break;
4826 case XML_TOK_INVALID:
4827 eventPtr = next;
4828 return XML_ERROR_INVALID_TOKEN;
4829 case XML_TOK_PARTIAL:
4830 if (!ps_finalBuffer) {
4831 *nextPtr = s;
4832 return XML_ERROR_NONE;
4833 }
4834 return XML_ERROR_UNCLOSED_TOKEN;
4835 case XML_TOK_PARTIAL_CHAR:
4836 if (!ps_finalBuffer) {
4837 *nextPtr = s;
4838 return XML_ERROR_NONE;
4839 }
4840 return XML_ERROR_PARTIAL_CHAR;
4841 default:
4842 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
4843 }
4844 eventPtr = s = next;
4845 switch (ps_parsing) {
4846 case XML_SUSPENDED:
4847 *nextPtr = next;
4848 return XML_ERROR_NONE;
4849 case XML_FINISHED:
4850 return XML_ERROR_ABORTED;
4851 default: ;
4852 }
4853 }
4854 }
4855
4856 static enum XML_Error
processInternalEntity(XML_Parser parser,ENTITY * entity,XML_Bool betweenDecl)4857 processInternalEntity(XML_Parser parser, ENTITY *entity,
4858 XML_Bool betweenDecl)
4859 {
4860 const char *textStart, *textEnd;
4861 const char *next;
4862 enum XML_Error result;
4863 OPEN_INTERNAL_ENTITY *openEntity;
4864
4865 if (freeInternalEntities) {
4866 openEntity = freeInternalEntities;
4867 freeInternalEntities = openEntity->next;
4868 }
4869 else {
4870 openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY));
4871 if (!openEntity)
4872 return XML_ERROR_NO_MEMORY;
4873 }
4874 entity->open = XML_TRUE;
4875 entity->processed = 0;
4876 openEntity->next = openInternalEntities;
4877 openInternalEntities = openEntity;
4878 openEntity->entity = entity;
4879 openEntity->startTagLevel = tagLevel;
4880 openEntity->betweenDecl = betweenDecl;
4881 openEntity->internalEventPtr = NULL;
4882 openEntity->internalEventEndPtr = NULL;
4883 textStart = (char *)entity->textPtr;
4884 textEnd = (char *)(entity->textPtr + entity->textLen);
4885
4886 #ifdef XML_DTD
4887 if (entity->is_param) {
4888 int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
4889 result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
4890 next, &next, XML_FALSE, XML_FALSE);
4891 }
4892 else
4893 #endif /* XML_DTD */
4894 result = doContent(parser, tagLevel, internalEncoding, textStart,
4895 textEnd, &next, XML_FALSE);
4896
4897 if (result == XML_ERROR_NONE) {
4898 if (textEnd != next && ps_parsing == XML_SUSPENDED) {
4899 entity->processed = (int)(next - textStart);
4900 processor = internalEntityProcessor;
4901 }
4902 else {
4903 entity->open = XML_FALSE;
4904 openInternalEntities = openEntity->next;
4905 /* put openEntity back in list of free instances */
4906 openEntity->next = freeInternalEntities;
4907 freeInternalEntities = openEntity;
4908 }
4909 }
4910 return result;
4911 }
4912
4913 static enum XML_Error PTRCALL
internalEntityProcessor(XML_Parser parser,const char * s,const char * end,const char ** nextPtr)4914 internalEntityProcessor(XML_Parser parser,
4915 const char *s,
4916 const char *end,
4917 const char **nextPtr)
4918 {
4919 ENTITY *entity;
4920 const char *textStart, *textEnd;
4921 const char *next;
4922 enum XML_Error result;
4923 OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities;
4924 if (!openEntity)
4925 return XML_ERROR_UNEXPECTED_STATE;
4926
4927 entity = openEntity->entity;
4928 textStart = ((char *)entity->textPtr) + entity->processed;
4929 textEnd = (char *)(entity->textPtr + entity->textLen);
4930
4931 #ifdef XML_DTD
4932 if (entity->is_param) {
4933 int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
4934 result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
4935 next, &next, XML_FALSE, XML_TRUE);
4936 }
4937 else
4938 #endif /* XML_DTD */
4939 result = doContent(parser, openEntity->startTagLevel, internalEncoding,
4940 textStart, textEnd, &next, XML_FALSE);
4941
4942 if (result != XML_ERROR_NONE)
4943 return result;
4944 else if (textEnd != next && ps_parsing == XML_SUSPENDED) {
4945 entity->processed = (int)(next - (char *)entity->textPtr);
4946 return result;
4947 }
4948 else {
4949 entity->open = XML_FALSE;
4950 openInternalEntities = openEntity->next;
4951 /* put openEntity back in list of free instances */
4952 openEntity->next = freeInternalEntities;
4953 freeInternalEntities = openEntity;
4954 }
4955
4956 #ifdef XML_DTD
4957 if (entity->is_param) {
4958 int tok;
4959 processor = prologProcessor;
4960 tok = XmlPrologTok(encoding, s, end, &next);
4961 return doProlog(parser, encoding, s, end, tok, next, nextPtr,
4962 (XML_Bool)!ps_finalBuffer, XML_TRUE);
4963 }
4964 else
4965 #endif /* XML_DTD */
4966 {
4967 processor = contentProcessor;
4968 /* see externalEntityContentProcessor vs contentProcessor */
4969 return doContent(parser, parentParser ? 1 : 0, encoding, s, end,
4970 nextPtr, (XML_Bool)!ps_finalBuffer);
4971 }
4972 }
4973
4974 static enum XML_Error PTRCALL
errorProcessor(XML_Parser parser,const char * s,const char * end,const char ** nextPtr)4975 errorProcessor(XML_Parser parser,
4976 const char *s,
4977 const char *end,
4978 const char **nextPtr)
4979 {
4980 UNUSED(s);
4981 UNUSED(end);
4982 UNUSED(nextPtr);
4983
4984 return errorCode;
4985 }
4986
4987 static enum XML_Error
storeAttributeValue(XML_Parser parser,const ENCODING * enc,XML_Bool isCdata,const char * ptr,const char * end,STRING_POOL * pool)4988 storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
4989 const char *ptr, const char *end,
4990 STRING_POOL *pool)
4991 {
4992 enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
4993 end, pool);
4994 if (result)
4995 return result;
4996 if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
4997 poolChop(pool);
4998 if (!poolAppendChar(pool, XML_T('\0')))
4999 return XML_ERROR_NO_MEMORY;
5000 return XML_ERROR_NONE;
5001 }
5002
5003 static enum XML_Error
appendAttributeValue(XML_Parser parser,const ENCODING * enc,XML_Bool isCdata,const char * ptr,const char * end,STRING_POOL * pool)5004 appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
5005 const char *ptr, const char *end,
5006 STRING_POOL *pool)
5007 {
5008 DTD * const dtd = _dtd; /* save one level of indirection */
5009 for (;;) {
5010 const char *next;
5011 int tok = XmlAttributeValueTok(enc, ptr, end, &next);
5012 switch (tok) {
5013 case XML_TOK_NONE:
5014 return XML_ERROR_NONE;
5015 case XML_TOK_INVALID:
5016 if (enc == encoding)
5017 eventPtr = next;
5018 return XML_ERROR_INVALID_TOKEN;
5019 case XML_TOK_PARTIAL:
5020 if (enc == encoding)
5021 eventPtr = ptr;
5022 return XML_ERROR_INVALID_TOKEN;
5023 case XML_TOK_CHAR_REF:
5024 {
5025 XML_Char buf[XML_ENCODE_MAX];
5026 int i;
5027 int n = XmlCharRefNumber(enc, ptr);
5028 if (n < 0) {
5029 if (enc == encoding)
5030 eventPtr = ptr;
5031 return XML_ERROR_BAD_CHAR_REF;
5032 }
5033 if (!isCdata
5034 && n == 0x20 /* space */
5035 && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
5036 break;
5037 n = XmlEncode(n, (ICHAR *)buf);
5038 if (!n) {
5039 if (enc == encoding)
5040 eventPtr = ptr;
5041 return XML_ERROR_BAD_CHAR_REF;
5042 }
5043 for (i = 0; i < n; i++) {
5044 if (!poolAppendChar(pool, buf[i]))
5045 return XML_ERROR_NO_MEMORY;
5046 }
5047 }
5048 break;
5049 case XML_TOK_DATA_CHARS:
5050 if (!poolAppend(pool, enc, ptr, next))
5051 return XML_ERROR_NO_MEMORY;
5052 break;
5053 case XML_TOK_TRAILING_CR:
5054 next = ptr + enc->minBytesPerChar;
5055 /* fall through */
5056 case XML_TOK_ATTRIBUTE_VALUE_S:
5057 case XML_TOK_DATA_NEWLINE:
5058 if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
5059 break;
5060 if (!poolAppendChar(pool, 0x20))
5061 return XML_ERROR_NO_MEMORY;
5062 break;
5063 case XML_TOK_ENTITY_REF:
5064 {
5065 const XML_Char *name;
5066 ENTITY *entity;
5067 char checkEntityDecl;
5068 XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
5069 ptr + enc->minBytesPerChar,
5070 next - enc->minBytesPerChar);
5071 if (ch) {
5072 if (!poolAppendChar(pool, ch))
5073 return XML_ERROR_NO_MEMORY;
5074 break;
5075 }
5076 name = poolStoreString(&temp2Pool, enc,
5077 ptr + enc->minBytesPerChar,
5078 next - enc->minBytesPerChar);
5079 if (!name)
5080 return XML_ERROR_NO_MEMORY;
5081 entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
5082 poolDiscard(&temp2Pool);
5083 /* First, determine if a check for an existing declaration is needed;
5084 if yes, check that the entity exists, and that it is internal.
5085 */
5086 if (pool == &dtd->pool) /* are we called from prolog? */
5087 checkEntityDecl =
5088 #ifdef XML_DTD
5089 prologState.documentEntity &&
5090 #endif /* XML_DTD */
5091 (dtd->standalone
5092 ? !openInternalEntities
5093 : !dtd->hasParamEntityRefs);
5094 else /* if (pool == &tempPool): we are called from content */
5095 checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
5096 if (checkEntityDecl) {
5097 if (!entity)
5098 return XML_ERROR_UNDEFINED_ENTITY;
5099 else if (!entity->is_internal)
5100 return XML_ERROR_ENTITY_DECLARED_IN_PE;
5101 }
5102 else if (!entity) {
5103 /* Cannot report skipped entity here - see comments on
5104 skippedEntityHandler.
5105 if (skippedEntityHandler)
5106 skippedEntityHandler(handlerArg, name, 0);
5107 */
5108 /* Cannot call the default handler because this would be
5109 out of sync with the call to the startElementHandler.
5110 if ((pool == &tempPool) && defaultHandler)
5111 reportDefault(parser, enc, ptr, next);
5112 */
5113 break;
5114 }
5115 if (entity->open) {
5116 if (enc == encoding)
5117 eventPtr = ptr;
5118 return XML_ERROR_RECURSIVE_ENTITY_REF;
5119 }
5120 if (entity->notation) {
5121 if (enc == encoding)
5122 eventPtr = ptr;
5123 return XML_ERROR_BINARY_ENTITY_REF;
5124 }
5125 if (!entity->textPtr) {
5126 if (enc == encoding)
5127 eventPtr = ptr;
5128 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
5129 }
5130 else {
5131 enum XML_Error result;
5132 const XML_Char *textEnd = entity->textPtr + entity->textLen;
5133 entity->open = XML_TRUE;
5134 result = appendAttributeValue(parser, internalEncoding, isCdata,
5135 (char *)entity->textPtr,
5136 (char *)textEnd, pool);
5137 entity->open = XML_FALSE;
5138 if (result)
5139 return result;
5140 }
5141 }
5142 break;
5143 default:
5144 if (enc == encoding)
5145 eventPtr = ptr;
5146 return XML_ERROR_UNEXPECTED_STATE;
5147 }
5148 ptr = next;
5149 }
5150 /* not reached */
5151 }
5152
5153 static enum XML_Error
storeEntityValue(XML_Parser parser,const ENCODING * enc,const char * entityTextPtr,const char * entityTextEnd)5154 storeEntityValue(XML_Parser parser,
5155 const ENCODING *enc,
5156 const char *entityTextPtr,
5157 const char *entityTextEnd)
5158 {
5159 DTD * const dtd = _dtd; /* save one level of indirection */
5160 STRING_POOL *pool = &(dtd->entityValuePool);
5161 enum XML_Error result = XML_ERROR_NONE;
5162 #ifdef XML_DTD
5163 int oldInEntityValue = prologState.inEntityValue;
5164 prologState.inEntityValue = 1;
5165 #endif /* XML_DTD */
5166 /* never return Null for the value argument in EntityDeclHandler,
5167 since this would indicate an external entity; therefore we
5168 have to make sure that entityValuePool.start is not null */
5169 if (!pool->blocks) {
5170 if (!poolGrow(pool))
5171 return XML_ERROR_NO_MEMORY;
5172 }
5173
5174 for (;;) {
5175 const char *next;
5176 int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
5177 switch (tok) {
5178 case XML_TOK_PARAM_ENTITY_REF:
5179 #ifdef XML_DTD
5180 if (isParamEntity || enc != encoding) {
5181 const XML_Char *name;
5182 ENTITY *entity;
5183 name = poolStoreString(&tempPool, enc,
5184 entityTextPtr + enc->minBytesPerChar,
5185 next - enc->minBytesPerChar);
5186 if (!name) {
5187 result = XML_ERROR_NO_MEMORY;
5188 goto endEntityValue;
5189 }
5190 entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
5191 poolDiscard(&tempPool);
5192 if (!entity) {
5193 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
5194 /* cannot report skipped entity here - see comments on
5195 skippedEntityHandler
5196 if (skippedEntityHandler)
5197 skippedEntityHandler(handlerArg, name, 0);
5198 */
5199 dtd->keepProcessing = dtd->standalone;
5200 goto endEntityValue;
5201 }
5202 if (entity->open) {
5203 if (enc == encoding)
5204 eventPtr = entityTextPtr;
5205 result = XML_ERROR_RECURSIVE_ENTITY_REF;
5206 goto endEntityValue;
5207 }
5208 if (entity->systemId) {
5209 if (externalEntityRefHandler) {
5210 dtd->paramEntityRead = XML_FALSE;
5211 entity->open = XML_TRUE;
5212 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
5213 0,
5214 entity->base,
5215 entity->systemId,
5216 entity->publicId)) {
5217 entity->open = XML_FALSE;
5218 result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
5219 goto endEntityValue;
5220 }
5221 entity->open = XML_FALSE;
5222 if (!dtd->paramEntityRead)
5223 dtd->keepProcessing = dtd->standalone;
5224 }
5225 else
5226 dtd->keepProcessing = dtd->standalone;
5227 }
5228 else {
5229 entity->open = XML_TRUE;
5230 result = storeEntityValue(parser,
5231 internalEncoding,
5232 (char *)entity->textPtr,
5233 (char *)(entity->textPtr
5234 + entity->textLen));
5235 entity->open = XML_FALSE;
5236 if (result)
5237 goto endEntityValue;
5238 }
5239 break;
5240 }
5241 #endif /* XML_DTD */
5242 /* In the internal subset, PE references are not legal
5243 within markup declarations, e.g entity values in this case. */
5244 eventPtr = entityTextPtr;
5245 result = XML_ERROR_PARAM_ENTITY_REF;
5246 goto endEntityValue;
5247 case XML_TOK_NONE:
5248 result = XML_ERROR_NONE;
5249 goto endEntityValue;
5250 case XML_TOK_ENTITY_REF:
5251 case XML_TOK_DATA_CHARS:
5252 if (!poolAppend(pool, enc, entityTextPtr, next)) {
5253 result = XML_ERROR_NO_MEMORY;
5254 goto endEntityValue;
5255 }
5256 break;
5257 case XML_TOK_TRAILING_CR:
5258 next = entityTextPtr + enc->minBytesPerChar;
5259 /* fall through */
5260 case XML_TOK_DATA_NEWLINE:
5261 if (pool->end == pool->ptr && !poolGrow(pool)) {
5262 result = XML_ERROR_NO_MEMORY;
5263 goto endEntityValue;
5264 }
5265 *(pool->ptr)++ = 0xA;
5266 break;
5267 case XML_TOK_CHAR_REF:
5268 {
5269 XML_Char buf[XML_ENCODE_MAX];
5270 int i;
5271 int n = XmlCharRefNumber(enc, entityTextPtr);
5272 if (n < 0) {
5273 if (enc == encoding)
5274 eventPtr = entityTextPtr;
5275 result = XML_ERROR_BAD_CHAR_REF;
5276 goto endEntityValue;
5277 }
5278 n = XmlEncode(n, (ICHAR *)buf);
5279 if (!n) {
5280 if (enc == encoding)
5281 eventPtr = entityTextPtr;
5282 result = XML_ERROR_BAD_CHAR_REF;
5283 goto endEntityValue;
5284 }
5285 for (i = 0; i < n; i++) {
5286 if (pool->end == pool->ptr && !poolGrow(pool)) {
5287 result = XML_ERROR_NO_MEMORY;
5288 goto endEntityValue;
5289 }
5290 *(pool->ptr)++ = buf[i];
5291 }
5292 }
5293 break;
5294 case XML_TOK_PARTIAL:
5295 if (enc == encoding)
5296 eventPtr = entityTextPtr;
5297 result = XML_ERROR_INVALID_TOKEN;
5298 goto endEntityValue;
5299 case XML_TOK_INVALID:
5300 if (enc == encoding)
5301 eventPtr = next;
5302 result = XML_ERROR_INVALID_TOKEN;
5303 goto endEntityValue;
5304 default:
5305 if (enc == encoding)
5306 eventPtr = entityTextPtr;
5307 result = XML_ERROR_UNEXPECTED_STATE;
5308 goto endEntityValue;
5309 }
5310 entityTextPtr = next;
5311 }
5312 endEntityValue:
5313 #ifdef XML_DTD
5314 prologState.inEntityValue = oldInEntityValue;
5315 #endif /* XML_DTD */
5316 return result;
5317 }
5318
5319 static void FASTCALL
normalizeLines(XML_Char * s)5320 normalizeLines(XML_Char *s)
5321 {
5322 XML_Char *p;
5323 for (;; s++) {
5324 if (*s == XML_T('\0'))
5325 return;
5326 if (*s == 0xD)
5327 break;
5328 }
5329 p = s;
5330 do {
5331 if (*s == 0xD) {
5332 *p++ = 0xA;
5333 if (*++s == 0xA)
5334 s++;
5335 }
5336 else
5337 *p++ = *s++;
5338 } while (*s);
5339 *p = XML_T('\0');
5340 }
5341
5342 static int
reportProcessingInstruction(XML_Parser parser,const ENCODING * enc,const char * start,const char * end)5343 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
5344 const char *start, const char *end)
5345 {
5346 const XML_Char *target;
5347 XML_Char *data;
5348 const char *tem;
5349 if (!processingInstructionHandler) {
5350 if (defaultHandler)
5351 reportDefault(parser, enc, start, end);
5352 return 1;
5353 }
5354 start += enc->minBytesPerChar * 2;
5355 tem = start + XmlNameLength(enc, start);
5356 target = poolStoreString(&tempPool, enc, start, tem);
5357 if (!target)
5358 return 0;
5359 poolFinish(&tempPool);
5360 data = poolStoreString(&tempPool, enc,
5361 XmlSkipS(enc, tem),
5362 end - enc->minBytesPerChar*2);
5363 if (!data)
5364 return 0;
5365 normalizeLines(data);
5366 processingInstructionHandler(handlerArg, target, data);
5367 poolClear(&tempPool);
5368 return 1;
5369 }
5370
5371 static int
reportComment(XML_Parser parser,const ENCODING * enc,const char * start,const char * end)5372 reportComment(XML_Parser parser, const ENCODING *enc,
5373 const char *start, const char *end)
5374 {
5375 XML_Char *data;
5376 if (!commentHandler) {
5377 if (defaultHandler)
5378 reportDefault(parser, enc, start, end);
5379 return 1;
5380 }
5381 data = poolStoreString(&tempPool,
5382 enc,
5383 start + enc->minBytesPerChar * 4,
5384 end - enc->minBytesPerChar * 3);
5385 if (!data)
5386 return 0;
5387 normalizeLines(data);
5388 commentHandler(handlerArg, data);
5389 poolClear(&tempPool);
5390 return 1;
5391 }
5392
5393 static void
reportDefault(XML_Parser parser,const ENCODING * enc,const char * s,const char * end)5394 reportDefault(XML_Parser parser, const ENCODING *enc,
5395 const char *s, const char *end)
5396 {
5397 if (MUST_CONVERT(enc, s)) {
5398 enum XML_Convert_Result convert_res;
5399 const char **eventPP;
5400 const char **eventEndPP;
5401 if (enc == encoding) {
5402 eventPP = &eventPtr;
5403 eventEndPP = &eventEndPtr;
5404 }
5405 else {
5406 eventPP = &(openInternalEntities->internalEventPtr);
5407 eventEndPP = &(openInternalEntities->internalEventEndPtr);
5408 }
5409 do {
5410 ICHAR *dataPtr = (ICHAR *)dataBuf;
5411 convert_res = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
5412 *eventEndPP = s;
5413 defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));
5414 *eventPP = s;
5415 } while ((convert_res != XML_CONVERT_COMPLETED) && (convert_res != XML_CONVERT_INPUT_INCOMPLETE));
5416 }
5417 else
5418 defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
5419 }
5420
5421
5422 static int
defineAttribute(ELEMENT_TYPE * type,ATTRIBUTE_ID * attId,XML_Bool isCdata,XML_Bool isId,const XML_Char * value,XML_Parser parser)5423 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
5424 XML_Bool isId, const XML_Char *value, XML_Parser parser)
5425 {
5426 DEFAULT_ATTRIBUTE *att;
5427 if (value || isId) {
5428 /* The handling of default attributes gets messed up if we have
5429 a default which duplicates a non-default. */
5430 int i;
5431 for (i = 0; i < type->nDefaultAtts; i++)
5432 if (attId == type->defaultAtts[i].id)
5433 return 1;
5434 if (isId && !type->idAtt && !attId->xmlns)
5435 type->idAtt = attId;
5436 }
5437 if (type->nDefaultAtts == type->allocDefaultAtts) {
5438 if (type->allocDefaultAtts == 0) {
5439 type->allocDefaultAtts = 8;
5440 type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
5441 * sizeof(DEFAULT_ATTRIBUTE));
5442 if (!type->defaultAtts)
5443 return 0;
5444 }
5445 else {
5446 DEFAULT_ATTRIBUTE *temp;
5447 int count = type->allocDefaultAtts * 2;
5448 temp = (DEFAULT_ATTRIBUTE *)
5449 REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
5450 if (temp == NULL)
5451 return 0;
5452 type->allocDefaultAtts = count;
5453 type->defaultAtts = temp;
5454 }
5455 }
5456 att = type->defaultAtts + type->nDefaultAtts;
5457 att->id = attId;
5458 att->value = value;
5459 att->isCdata = isCdata;
5460 if (!isCdata)
5461 attId->maybeTokenized = XML_TRUE;
5462 type->nDefaultAtts += 1;
5463 return 1;
5464 }
5465
5466 static int
setElementTypePrefix(XML_Parser parser,ELEMENT_TYPE * elementType)5467 setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
5468 {
5469 DTD * const dtd = _dtd; /* save one level of indirection */
5470 const XML_Char *name;
5471 for (name = elementType->name; *name; name++) {
5472 if (*name == XML_T(ASCII_COLON)) {
5473 PREFIX *prefix;
5474 const XML_Char *s;
5475 for (s = elementType->name; s != name; s++) {
5476 if (!poolAppendChar(&dtd->pool, *s))
5477 return 0;
5478 }
5479 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5480 return 0;
5481 prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
5482 sizeof(PREFIX));
5483 if (!prefix)
5484 return 0;
5485 if (prefix->name == poolStart(&dtd->pool))
5486 poolFinish(&dtd->pool);
5487 else
5488 poolDiscard(&dtd->pool);
5489 elementType->prefix = prefix;
5490 break;
5491
5492 }
5493 }
5494 return 1;
5495 }
5496
5497 static ATTRIBUTE_ID *
getAttributeId(XML_Parser parser,const ENCODING * enc,const char * start,const char * end)5498 getAttributeId(XML_Parser parser, const ENCODING *enc,
5499 const char *start, const char *end)
5500 {
5501 DTD * const dtd = _dtd; /* save one level of indirection */
5502 ATTRIBUTE_ID *id;
5503 const XML_Char *name;
5504 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5505 return NULL;
5506 name = poolStoreString(&dtd->pool, enc, start, end);
5507 if (!name)
5508 return NULL;
5509 /* skip quotation mark - its storage will be re-used (like in name[-1]) */
5510 ++name;
5511 id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
5512 if (!id)
5513 return NULL;
5514 if (id->name != name)
5515 poolDiscard(&dtd->pool);
5516 else {
5517 poolFinish(&dtd->pool);
5518 if (!ns)
5519 ;
5520 else if (name[0] == XML_T(ASCII_x)
5521 && name[1] == XML_T(ASCII_m)
5522 && name[2] == XML_T(ASCII_l)
5523 && name[3] == XML_T(ASCII_n)
5524 && name[4] == XML_T(ASCII_s)
5525 && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) {
5526 if (name[5] == XML_T('\0'))
5527 id->prefix = &dtd->defaultPrefix;
5528 else
5529 id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6, sizeof(PREFIX));
5530 id->xmlns = XML_TRUE;
5531 }
5532 else {
5533 int i;
5534 for (i = 0; name[i]; i++) {
5535 /* attributes without prefix are *not* in the default namespace */
5536 if (name[i] == XML_T(ASCII_COLON)) {
5537 int j;
5538 for (j = 0; j < i; j++) {
5539 if (!poolAppendChar(&dtd->pool, name[j]))
5540 return NULL;
5541 }
5542 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5543 return NULL;
5544 id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
5545 sizeof(PREFIX));
5546 if (id->prefix->name == poolStart(&dtd->pool))
5547 poolFinish(&dtd->pool);
5548 else
5549 poolDiscard(&dtd->pool);
5550 break;
5551 }
5552 }
5553 }
5554 }
5555 return id;
5556 }
5557
5558 #define CONTEXT_SEP XML_T(ASCII_FF)
5559
5560 static const XML_Char *
getContext(XML_Parser parser)5561 getContext(XML_Parser parser)
5562 {
5563 DTD * const dtd = _dtd; /* save one level of indirection */
5564 HASH_TABLE_ITER iter;
5565 XML_Bool needSep = XML_FALSE;
5566
5567 if (dtd->defaultPrefix.binding) {
5568 int i;
5569 int len;
5570 if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
5571 return NULL;
5572 len = dtd->defaultPrefix.binding->uriLen;
5573 if (namespaceSeparator)
5574 len--;
5575 for (i = 0; i < len; i++)
5576 if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
5577 return NULL;
5578 needSep = XML_TRUE;
5579 }
5580
5581 hashTableIterInit(&iter, &(dtd->prefixes));
5582 for (;;) {
5583 int i;
5584 int len;
5585 const XML_Char *s;
5586 PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
5587 if (!prefix)
5588 break;
5589 if (!prefix->binding)
5590 continue;
5591 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
5592 return NULL;
5593 for (s = prefix->name; *s; s++)
5594 if (!poolAppendChar(&tempPool, *s))
5595 return NULL;
5596 if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
5597 return NULL;
5598 len = prefix->binding->uriLen;
5599 if (namespaceSeparator)
5600 len--;
5601 for (i = 0; i < len; i++)
5602 if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
5603 return NULL;
5604 needSep = XML_TRUE;
5605 }
5606
5607
5608 hashTableIterInit(&iter, &(dtd->generalEntities));
5609 for (;;) {
5610 const XML_Char *s;
5611 ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
5612 if (!e)
5613 break;
5614 if (!e->open)
5615 continue;
5616 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
5617 return NULL;
5618 for (s = e->name; *s; s++)
5619 if (!poolAppendChar(&tempPool, *s))
5620 return 0;
5621 needSep = XML_TRUE;
5622 }
5623
5624 if (!poolAppendChar(&tempPool, XML_T('\0')))
5625 return NULL;
5626 return tempPool.start;
5627 }
5628
5629 static XML_Bool
setContext(XML_Parser parser,const XML_Char * context)5630 setContext(XML_Parser parser, const XML_Char *context)
5631 {
5632 DTD * const dtd = _dtd; /* save one level of indirection */
5633 const XML_Char *s = context;
5634
5635 while (*context != XML_T('\0')) {
5636 if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
5637 ENTITY *e;
5638 if (!poolAppendChar(&tempPool, XML_T('\0')))
5639 return XML_FALSE;
5640 e = (ENTITY *)lookup(parser, &dtd->generalEntities, poolStart(&tempPool), 0);
5641 if (e)
5642 e->open = XML_TRUE;
5643 if (*s != XML_T('\0'))
5644 s++;
5645 context = s;
5646 poolDiscard(&tempPool);
5647 }
5648 else if (*s == XML_T(ASCII_EQUALS)) {
5649 PREFIX *prefix;
5650 if (poolLength(&tempPool) == 0)
5651 prefix = &dtd->defaultPrefix;
5652 else {
5653 if (!poolAppendChar(&tempPool, XML_T('\0')))
5654 return XML_FALSE;
5655 prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&tempPool),
5656 sizeof(PREFIX));
5657 if (!prefix)
5658 return XML_FALSE;
5659 if (prefix->name == poolStart(&tempPool)) {
5660 prefix->name = poolCopyString(&dtd->pool, prefix->name);
5661 if (!prefix->name)
5662 return XML_FALSE;
5663 }
5664 poolDiscard(&tempPool);
5665 }
5666 for (context = s + 1;
5667 *context != CONTEXT_SEP && *context != XML_T('\0');
5668 context++)
5669 if (!poolAppendChar(&tempPool, *context))
5670 return XML_FALSE;
5671 if (!poolAppendChar(&tempPool, XML_T('\0')))
5672 return XML_FALSE;
5673 if (addBinding(parser, prefix, NULL, poolStart(&tempPool),
5674 &inheritedBindings) != XML_ERROR_NONE)
5675 return XML_FALSE;
5676 poolDiscard(&tempPool);
5677 if (*context != XML_T('\0'))
5678 ++context;
5679 s = context;
5680 }
5681 else {
5682 if (!poolAppendChar(&tempPool, *s))
5683 return XML_FALSE;
5684 s++;
5685 }
5686 }
5687 return XML_TRUE;
5688 }
5689
5690 static void FASTCALL
normalizePublicId(XML_Char * publicId)5691 normalizePublicId(XML_Char *publicId)
5692 {
5693 XML_Char *p = publicId;
5694 XML_Char *s;
5695 for (s = publicId; *s; s++) {
5696 switch (*s) {
5697 case 0x20:
5698 case 0xD:
5699 case 0xA:
5700 if (p != publicId && p[-1] != 0x20)
5701 *p++ = 0x20;
5702 break;
5703 default:
5704 *p++ = *s;
5705 }
5706 }
5707 if (p != publicId && p[-1] == 0x20)
5708 --p;
5709 *p = XML_T('\0');
5710 }
5711
5712 static DTD *
dtdCreate(const XML_Memory_Handling_Suite * ms)5713 dtdCreate(const XML_Memory_Handling_Suite *ms)
5714 {
5715 DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
5716 if (p == NULL)
5717 return p;
5718 poolInit(&(p->pool), ms);
5719 poolInit(&(p->entityValuePool), ms);
5720 hashTableInit(&(p->generalEntities), ms);
5721 hashTableInit(&(p->elementTypes), ms);
5722 hashTableInit(&(p->attributeIds), ms);
5723 hashTableInit(&(p->prefixes), ms);
5724 #ifdef XML_DTD
5725 p->paramEntityRead = XML_FALSE;
5726 hashTableInit(&(p->paramEntities), ms);
5727 #endif /* XML_DTD */
5728 p->defaultPrefix.name = NULL;
5729 p->defaultPrefix.binding = NULL;
5730
5731 p->in_eldecl = XML_FALSE;
5732 p->scaffIndex = NULL;
5733 p->scaffold = NULL;
5734 p->scaffLevel = 0;
5735 p->scaffSize = 0;
5736 p->scaffCount = 0;
5737 p->contentStringLen = 0;
5738
5739 p->keepProcessing = XML_TRUE;
5740 p->hasParamEntityRefs = XML_FALSE;
5741 p->standalone = XML_FALSE;
5742 return p;
5743 }
5744
5745 static void
dtdReset(DTD * p,const XML_Memory_Handling_Suite * ms)5746 dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
5747 {
5748 HASH_TABLE_ITER iter;
5749 hashTableIterInit(&iter, &(p->elementTypes));
5750 for (;;) {
5751 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5752 if (!e)
5753 break;
5754 if (e->allocDefaultAtts != 0)
5755 ms->free_fcn(e->defaultAtts);
5756 }
5757 hashTableClear(&(p->generalEntities));
5758 #ifdef XML_DTD
5759 p->paramEntityRead = XML_FALSE;
5760 hashTableClear(&(p->paramEntities));
5761 #endif /* XML_DTD */
5762 hashTableClear(&(p->elementTypes));
5763 hashTableClear(&(p->attributeIds));
5764 hashTableClear(&(p->prefixes));
5765 poolClear(&(p->pool));
5766 poolClear(&(p->entityValuePool));
5767 p->defaultPrefix.name = NULL;
5768 p->defaultPrefix.binding = NULL;
5769
5770 p->in_eldecl = XML_FALSE;
5771
5772 ms->free_fcn(p->scaffIndex);
5773 p->scaffIndex = NULL;
5774 ms->free_fcn(p->scaffold);
5775 p->scaffold = NULL;
5776
5777 p->scaffLevel = 0;
5778 p->scaffSize = 0;
5779 p->scaffCount = 0;
5780 p->contentStringLen = 0;
5781
5782 p->keepProcessing = XML_TRUE;
5783 p->hasParamEntityRefs = XML_FALSE;
5784 p->standalone = XML_FALSE;
5785 }
5786
5787 static void
dtdDestroy(DTD * p,XML_Bool isDocEntity,const XML_Memory_Handling_Suite * ms)5788 dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
5789 {
5790 HASH_TABLE_ITER iter;
5791 hashTableIterInit(&iter, &(p->elementTypes));
5792 for (;;) {
5793 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5794 if (!e)
5795 break;
5796 if (e->allocDefaultAtts != 0)
5797 ms->free_fcn(e->defaultAtts);
5798 }
5799 hashTableDestroy(&(p->generalEntities));
5800 #ifdef XML_DTD
5801 hashTableDestroy(&(p->paramEntities));
5802 #endif /* XML_DTD */
5803 hashTableDestroy(&(p->elementTypes));
5804 hashTableDestroy(&(p->attributeIds));
5805 hashTableDestroy(&(p->prefixes));
5806 poolDestroy(&(p->pool));
5807 poolDestroy(&(p->entityValuePool));
5808 if (isDocEntity) {
5809 ms->free_fcn(p->scaffIndex);
5810 ms->free_fcn(p->scaffold);
5811 }
5812 ms->free_fcn(p);
5813 }
5814
5815 /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
5816 The new DTD has already been initialized.
5817 */
5818 static int
dtdCopy(XML_Parser oldParser,DTD * newDtd,const DTD * oldDtd,const XML_Memory_Handling_Suite * ms)5819 dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
5820 {
5821 HASH_TABLE_ITER iter;
5822
5823 /* Copy the prefix table. */
5824
5825 hashTableIterInit(&iter, &(oldDtd->prefixes));
5826 for (;;) {
5827 const XML_Char *name;
5828 const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
5829 if (!oldP)
5830 break;
5831 name = poolCopyString(&(newDtd->pool), oldP->name);
5832 if (!name)
5833 return 0;
5834 if (!lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX)))
5835 return 0;
5836 }
5837
5838 hashTableIterInit(&iter, &(oldDtd->attributeIds));
5839
5840 /* Copy the attribute id table. */
5841
5842 for (;;) {
5843 ATTRIBUTE_ID *newA;
5844 const XML_Char *name;
5845 const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
5846
5847 if (!oldA)
5848 break;
5849 /* Remember to allocate the scratch byte before the name. */
5850 if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
5851 return 0;
5852 name = poolCopyString(&(newDtd->pool), oldA->name);
5853 if (!name)
5854 return 0;
5855 ++name;
5856 newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name,
5857 sizeof(ATTRIBUTE_ID));
5858 if (!newA)
5859 return 0;
5860 newA->maybeTokenized = oldA->maybeTokenized;
5861 if (oldA->prefix) {
5862 newA->xmlns = oldA->xmlns;
5863 if (oldA->prefix == &oldDtd->defaultPrefix)
5864 newA->prefix = &newDtd->defaultPrefix;
5865 else
5866 newA->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
5867 oldA->prefix->name, 0);
5868 }
5869 }
5870
5871 /* Copy the element type table. */
5872
5873 hashTableIterInit(&iter, &(oldDtd->elementTypes));
5874
5875 for (;;) {
5876 int i;
5877 ELEMENT_TYPE *newE;
5878 const XML_Char *name;
5879 const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5880 if (!oldE)
5881 break;
5882 name = poolCopyString(&(newDtd->pool), oldE->name);
5883 if (!name)
5884 return 0;
5885 newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name,
5886 sizeof(ELEMENT_TYPE));
5887 if (!newE)
5888 return 0;
5889 if (oldE->nDefaultAtts) {
5890 newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
5891 ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
5892 if (!newE->defaultAtts) {
5893 ms->free_fcn(newE);
5894 return 0;
5895 }
5896 }
5897 if (oldE->idAtt)
5898 newE->idAtt = (ATTRIBUTE_ID *)
5899 lookup(oldParser, &(newDtd->attributeIds), oldE->idAtt->name, 0);
5900 newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
5901 if (oldE->prefix)
5902 newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
5903 oldE->prefix->name, 0);
5904 for (i = 0; i < newE->nDefaultAtts; i++) {
5905 newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
5906 lookup(oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
5907 newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
5908 if (oldE->defaultAtts[i].value) {
5909 newE->defaultAtts[i].value
5910 = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
5911 if (!newE->defaultAtts[i].value)
5912 return 0;
5913 }
5914 else
5915 newE->defaultAtts[i].value = NULL;
5916 }
5917 }
5918
5919 /* Copy the entity tables. */
5920 if (!copyEntityTable(oldParser,
5921 &(newDtd->generalEntities),
5922 &(newDtd->pool),
5923 &(oldDtd->generalEntities)))
5924 return 0;
5925
5926 #ifdef XML_DTD
5927 if (!copyEntityTable(oldParser,
5928 &(newDtd->paramEntities),
5929 &(newDtd->pool),
5930 &(oldDtd->paramEntities)))
5931 return 0;
5932 newDtd->paramEntityRead = oldDtd->paramEntityRead;
5933 #endif /* XML_DTD */
5934
5935 newDtd->keepProcessing = oldDtd->keepProcessing;
5936 newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
5937 newDtd->standalone = oldDtd->standalone;
5938
5939 /* Don't want deep copying for scaffolding */
5940 newDtd->in_eldecl = oldDtd->in_eldecl;
5941 newDtd->scaffold = oldDtd->scaffold;
5942 newDtd->contentStringLen = oldDtd->contentStringLen;
5943 newDtd->scaffSize = oldDtd->scaffSize;
5944 newDtd->scaffLevel = oldDtd->scaffLevel;
5945 newDtd->scaffIndex = oldDtd->scaffIndex;
5946
5947 return 1;
5948 } /* End dtdCopy */
5949
5950 static int
copyEntityTable(XML_Parser oldParser,HASH_TABLE * newTable,STRING_POOL * newPool,const HASH_TABLE * oldTable)5951 copyEntityTable(XML_Parser oldParser,
5952 HASH_TABLE *newTable,
5953 STRING_POOL *newPool,
5954 const HASH_TABLE *oldTable)
5955 {
5956 HASH_TABLE_ITER iter;
5957 const XML_Char *cachedOldBase = NULL;
5958 const XML_Char *cachedNewBase = NULL;
5959
5960 hashTableIterInit(&iter, oldTable);
5961
5962 for (;;) {
5963 ENTITY *newE;
5964 const XML_Char *name;
5965 const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
5966 if (!oldE)
5967 break;
5968 name = poolCopyString(newPool, oldE->name);
5969 if (!name)
5970 return 0;
5971 newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY));
5972 if (!newE)
5973 return 0;
5974 if (oldE->systemId) {
5975 const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
5976 if (!tem)
5977 return 0;
5978 newE->systemId = tem;
5979 if (oldE->base) {
5980 if (oldE->base == cachedOldBase)
5981 newE->base = cachedNewBase;
5982 else {
5983 cachedOldBase = oldE->base;
5984 tem = poolCopyString(newPool, cachedOldBase);
5985 if (!tem)
5986 return 0;
5987 cachedNewBase = newE->base = tem;
5988 }
5989 }
5990 if (oldE->publicId) {
5991 tem = poolCopyString(newPool, oldE->publicId);
5992 if (!tem)
5993 return 0;
5994 newE->publicId = tem;
5995 }
5996 }
5997 else {
5998 const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
5999 oldE->textLen);
6000 if (!tem)
6001 return 0;
6002 newE->textPtr = tem;
6003 newE->textLen = oldE->textLen;
6004 }
6005 if (oldE->notation) {
6006 const XML_Char *tem = poolCopyString(newPool, oldE->notation);
6007 if (!tem)
6008 return 0;
6009 newE->notation = tem;
6010 }
6011 newE->is_param = oldE->is_param;
6012 newE->is_internal = oldE->is_internal;
6013 }
6014 return 1;
6015 }
6016
6017 #define INIT_POWER 6
6018
6019 static XML_Bool FASTCALL
keyeq(KEY s1,KEY s2)6020 keyeq(KEY s1, KEY s2)
6021 {
6022 for (; *s1 == *s2; s1++, s2++)
6023 if (*s1 == 0)
6024 return XML_TRUE;
6025 return XML_FALSE;
6026 }
6027
6028 static size_t FASTCALL
hash(XML_Parser parser,KEY s)6029 hash(XML_Parser parser, KEY s)
6030 {
6031 size_t h = hash_secret_salt;
6032 while (*s)
6033 h = CHAR_HASH(h, *s++);
6034 return h;
6035 }
6036
6037 static NAMED *
lookup(XML_Parser parser,HASH_TABLE * table,KEY name,size_t createSize)6038 lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize)
6039 {
6040 size_t i;
6041 if (table->size == 0) {
6042 size_t tsize;
6043 if (!createSize)
6044 return NULL;
6045 table->power = INIT_POWER;
6046 /* table->size is a power of 2 */
6047 table->size = (size_t)1 << INIT_POWER;
6048 tsize = table->size * sizeof(NAMED *);
6049 table->v = (NAMED **)table->mem->malloc_fcn(tsize);
6050 if (!table->v) {
6051 table->size = 0;
6052 return NULL;
6053 }
6054 memset(table->v, 0, tsize);
6055 i = hash(parser, name) & ((unsigned long)table->size - 1);
6056 }
6057 else {
6058 size_t h = hash(parser, name);
6059 size_t mask = table->size - 1;
6060 unsigned char step = 0;
6061 i = h & mask;
6062 while (table->v[i]) {
6063 if (keyeq(name, table->v[i]->name))
6064 return table->v[i];
6065 if (!step)
6066 step = PROBE_STEP(h, mask, table->power);
6067 i < step ? (i += table->size - step) : (i -= step);
6068 }
6069 if (!createSize)
6070 return NULL;
6071
6072 /* check for overflow (table is half full) */
6073 if (table->used >> (table->power - 1)) {
6074 unsigned char newPower = table->power + 1;
6075 size_t newSize = (size_t)1 << newPower;
6076 size_t newMask = newSize - 1;
6077 size_t tsize = newSize * sizeof(NAMED *);
6078 NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
6079 if (!newV)
6080 return NULL;
6081 memset(newV, 0, tsize);
6082 for (i = 0; i < table->size; i++)
6083 if (table->v[i]) {
6084 size_t newHash = hash(parser, table->v[i]->name);
6085 size_t j = newHash & newMask;
6086 step = 0;
6087 while (newV[j]) {
6088 if (!step)
6089 step = PROBE_STEP(newHash, newMask, newPower);
6090 j < step ? (j += newSize - step) : (j -= step);
6091 }
6092 newV[j] = table->v[i];
6093 }
6094 table->mem->free_fcn(table->v);
6095 table->v = newV;
6096 table->power = newPower;
6097 table->size = newSize;
6098 i = h & newMask;
6099 step = 0;
6100 while (table->v[i]) {
6101 if (!step)
6102 step = PROBE_STEP(h, newMask, newPower);
6103 i < step ? (i += newSize - step) : (i -= step);
6104 }
6105 }
6106 }
6107 table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
6108 if (!table->v[i])
6109 return NULL;
6110 memset(table->v[i], 0, createSize);
6111 table->v[i]->name = name;
6112 (table->used)++;
6113 return table->v[i];
6114 }
6115
6116 static void FASTCALL
hashTableClear(HASH_TABLE * table)6117 hashTableClear(HASH_TABLE *table)
6118 {
6119 size_t i;
6120 for (i = 0; i < table->size; i++) {
6121 table->mem->free_fcn(table->v[i]);
6122 table->v[i] = NULL;
6123 }
6124 table->used = 0;
6125 }
6126
6127 static void FASTCALL
hashTableDestroy(HASH_TABLE * table)6128 hashTableDestroy(HASH_TABLE *table)
6129 {
6130 size_t i;
6131 for (i = 0; i < table->size; i++)
6132 table->mem->free_fcn(table->v[i]);
6133 table->mem->free_fcn(table->v);
6134 }
6135
6136 static void FASTCALL
hashTableInit(HASH_TABLE * p,const XML_Memory_Handling_Suite * ms)6137 hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
6138 {
6139 p->power = 0;
6140 p->size = 0;
6141 p->used = 0;
6142 p->v = NULL;
6143 p->mem = ms;
6144 }
6145
6146 static void FASTCALL
hashTableIterInit(HASH_TABLE_ITER * iter,const HASH_TABLE * table)6147 hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
6148 {
6149 iter->p = table->v;
6150 iter->end = iter->p + table->size;
6151 }
6152
6153 static NAMED * FASTCALL
hashTableIterNext(HASH_TABLE_ITER * iter)6154 hashTableIterNext(HASH_TABLE_ITER *iter)
6155 {
6156 while (iter->p != iter->end) {
6157 NAMED *tem = *(iter->p)++;
6158 if (tem)
6159 return tem;
6160 }
6161 return NULL;
6162 }
6163
6164 static void FASTCALL
poolInit(STRING_POOL * pool,const XML_Memory_Handling_Suite * ms)6165 poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
6166 {
6167 pool->blocks = NULL;
6168 pool->freeBlocks = NULL;
6169 pool->start = NULL;
6170 pool->ptr = NULL;
6171 pool->end = NULL;
6172 pool->mem = ms;
6173 }
6174
6175 static void FASTCALL
poolClear(STRING_POOL * pool)6176 poolClear(STRING_POOL *pool)
6177 {
6178 if (!pool->freeBlocks)
6179 pool->freeBlocks = pool->blocks;
6180 else {
6181 BLOCK *p = pool->blocks;
6182 while (p) {
6183 BLOCK *tem = p->next;
6184 p->next = pool->freeBlocks;
6185 pool->freeBlocks = p;
6186 p = tem;
6187 }
6188 }
6189 pool->blocks = NULL;
6190 pool->start = NULL;
6191 pool->ptr = NULL;
6192 pool->end = NULL;
6193 }
6194
6195 static void FASTCALL
poolDestroy(STRING_POOL * pool)6196 poolDestroy(STRING_POOL *pool)
6197 {
6198 BLOCK *p = pool->blocks;
6199 while (p) {
6200 BLOCK *tem = p->next;
6201 pool->mem->free_fcn(p);
6202 p = tem;
6203 }
6204 p = pool->freeBlocks;
6205 while (p) {
6206 BLOCK *tem = p->next;
6207 pool->mem->free_fcn(p);
6208 p = tem;
6209 }
6210 }
6211
6212 static XML_Char *
poolAppend(STRING_POOL * pool,const ENCODING * enc,const char * ptr,const char * end)6213 poolAppend(STRING_POOL *pool, const ENCODING *enc,
6214 const char *ptr, const char *end)
6215 {
6216 if (!pool->ptr && !poolGrow(pool))
6217 return NULL;
6218 for (;;) {
6219 const enum XML_Convert_Result convert_res = XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
6220 if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
6221 break;
6222 if (!poolGrow(pool))
6223 return NULL;
6224 }
6225 return pool->start;
6226 }
6227
6228 static const XML_Char * FASTCALL
poolCopyString(STRING_POOL * pool,const XML_Char * s)6229 poolCopyString(STRING_POOL *pool, const XML_Char *s)
6230 {
6231 do {
6232 if (!poolAppendChar(pool, *s))
6233 return NULL;
6234 } while (*s++);
6235 s = pool->start;
6236 poolFinish(pool);
6237 return s;
6238 }
6239
6240 static const XML_Char *
poolCopyStringN(STRING_POOL * pool,const XML_Char * s,int n)6241 poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
6242 {
6243 if (!pool->ptr && !poolGrow(pool))
6244 return NULL;
6245 for (; n > 0; --n, s++) {
6246 if (!poolAppendChar(pool, *s))
6247 return NULL;
6248 }
6249 s = pool->start;
6250 poolFinish(pool);
6251 return s;
6252 }
6253
6254 static const XML_Char * FASTCALL
poolAppendString(STRING_POOL * pool,const XML_Char * s)6255 poolAppendString(STRING_POOL *pool, const XML_Char *s)
6256 {
6257 while (*s) {
6258 if (!poolAppendChar(pool, *s))
6259 return NULL;
6260 s++;
6261 }
6262 return pool->start;
6263 }
6264
6265 static XML_Char *
poolStoreString(STRING_POOL * pool,const ENCODING * enc,const char * ptr,const char * end)6266 poolStoreString(STRING_POOL *pool, const ENCODING *enc,
6267 const char *ptr, const char *end)
6268 {
6269 if (!poolAppend(pool, enc, ptr, end))
6270 return NULL;
6271 if (pool->ptr == pool->end && !poolGrow(pool))
6272 return NULL;
6273 *(pool->ptr)++ = 0;
6274 return pool->start;
6275 }
6276
6277 static XML_Bool FASTCALL
poolGrow(STRING_POOL * pool)6278 poolGrow(STRING_POOL *pool)
6279 {
6280 if (pool->freeBlocks) {
6281 if (pool->start == 0) {
6282 pool->blocks = pool->freeBlocks;
6283 pool->freeBlocks = pool->freeBlocks->next;
6284 pool->blocks->next = NULL;
6285 pool->start = pool->blocks->s;
6286 pool->end = pool->start + pool->blocks->size;
6287 pool->ptr = pool->start;
6288 return XML_TRUE;
6289 }
6290 if (pool->end - pool->start < pool->freeBlocks->size) {
6291 BLOCK *tem = pool->freeBlocks->next;
6292 pool->freeBlocks->next = pool->blocks;
6293 pool->blocks = pool->freeBlocks;
6294 pool->freeBlocks = tem;
6295 memcpy(pool->blocks->s, pool->start,
6296 (pool->end - pool->start) * sizeof(XML_Char));
6297 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
6298 pool->start = pool->blocks->s;
6299 pool->end = pool->start + pool->blocks->size;
6300 return XML_TRUE;
6301 }
6302 }
6303 if (pool->blocks && pool->start == pool->blocks->s) {
6304 BLOCK *temp;
6305 int blockSize = (int)((unsigned)(pool->end - pool->start)*2U);
6306
6307 if (blockSize < 0)
6308 return XML_FALSE;
6309
6310 temp = (BLOCK *)
6311 pool->mem->realloc_fcn(pool->blocks,
6312 (offsetof(BLOCK, s)
6313 + blockSize * sizeof(XML_Char)));
6314 if (temp == NULL)
6315 return XML_FALSE;
6316 pool->blocks = temp;
6317 pool->blocks->size = blockSize;
6318 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
6319 pool->start = pool->blocks->s;
6320 pool->end = pool->start + blockSize;
6321 }
6322 else {
6323 BLOCK *tem;
6324 int blockSize = (int)(pool->end - pool->start);
6325
6326 if (blockSize < 0)
6327 return XML_FALSE;
6328
6329 if (blockSize < INIT_BLOCK_SIZE)
6330 blockSize = INIT_BLOCK_SIZE;
6331 else
6332 blockSize *= 2;
6333 tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
6334 + blockSize * sizeof(XML_Char));
6335 if (!tem)
6336 return XML_FALSE;
6337 tem->size = blockSize;
6338 tem->next = pool->blocks;
6339 pool->blocks = tem;
6340 if (pool->ptr != pool->start)
6341 memcpy(tem->s, pool->start,
6342 (pool->ptr - pool->start) * sizeof(XML_Char));
6343 pool->ptr = tem->s + (pool->ptr - pool->start);
6344 pool->start = tem->s;
6345 pool->end = tem->s + blockSize;
6346 }
6347 return XML_TRUE;
6348 }
6349
6350 static int FASTCALL
nextScaffoldPart(XML_Parser parser)6351 nextScaffoldPart(XML_Parser parser)
6352 {
6353 DTD * const dtd = _dtd; /* save one level of indirection */
6354 CONTENT_SCAFFOLD * me;
6355 int next;
6356
6357 if (!dtd->scaffIndex) {
6358 dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
6359 if (!dtd->scaffIndex)
6360 return -1;
6361 dtd->scaffIndex[0] = 0;
6362 }
6363
6364 if (dtd->scaffCount >= dtd->scaffSize) {
6365 CONTENT_SCAFFOLD *temp;
6366 if (dtd->scaffold) {
6367 temp = (CONTENT_SCAFFOLD *)
6368 REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
6369 if (temp == NULL)
6370 return -1;
6371 dtd->scaffSize *= 2;
6372 }
6373 else {
6374 temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS
6375 * sizeof(CONTENT_SCAFFOLD));
6376 if (temp == NULL)
6377 return -1;
6378 dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
6379 }
6380 dtd->scaffold = temp;
6381 }
6382 next = dtd->scaffCount++;
6383 me = &dtd->scaffold[next];
6384 if (dtd->scaffLevel) {
6385 CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];
6386 if (parent->lastchild) {
6387 dtd->scaffold[parent->lastchild].nextsib = next;
6388 }
6389 if (!parent->childcnt)
6390 parent->firstchild = next;
6391 parent->lastchild = next;
6392 parent->childcnt++;
6393 }
6394 me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
6395 return next;
6396 }
6397
6398 static void
build_node(XML_Parser parser,int src_node,XML_Content * dest,XML_Content ** contpos,XML_Char ** strpos)6399 build_node(XML_Parser parser,
6400 int src_node,
6401 XML_Content *dest,
6402 XML_Content **contpos,
6403 XML_Char **strpos)
6404 {
6405 DTD * const dtd = _dtd; /* save one level of indirection */
6406 dest->type = dtd->scaffold[src_node].type;
6407 dest->quant = dtd->scaffold[src_node].quant;
6408 if (dest->type == XML_CTYPE_NAME) {
6409 const XML_Char *src;
6410 dest->name = *strpos;
6411 src = dtd->scaffold[src_node].name;
6412 for (;;) {
6413 *(*strpos)++ = *src;
6414 if (!*src)
6415 break;
6416 src++;
6417 }
6418 dest->numchildren = 0;
6419 dest->children = NULL;
6420 }
6421 else {
6422 unsigned int i;
6423 int cn;
6424 dest->numchildren = dtd->scaffold[src_node].childcnt;
6425 dest->children = *contpos;
6426 *contpos += dest->numchildren;
6427 for (i = 0, cn = dtd->scaffold[src_node].firstchild;
6428 i < dest->numchildren;
6429 i++, cn = dtd->scaffold[cn].nextsib) {
6430 build_node(parser, cn, &(dest->children[i]), contpos, strpos);
6431 }
6432 dest->name = NULL;
6433 }
6434 }
6435
6436 static XML_Content *
build_model(XML_Parser parser)6437 build_model (XML_Parser parser)
6438 {
6439 DTD * const dtd = _dtd; /* save one level of indirection */
6440 XML_Content *ret;
6441 XML_Content *cpos;
6442 XML_Char * str;
6443 int allocsize = (dtd->scaffCount * sizeof(XML_Content)
6444 + (dtd->contentStringLen * sizeof(XML_Char)));
6445
6446 ret = (XML_Content *)MALLOC(allocsize);
6447 if (!ret)
6448 return NULL;
6449
6450 str = (XML_Char *) (&ret[dtd->scaffCount]);
6451 cpos = &ret[1];
6452
6453 build_node(parser, 0, ret, &cpos, &str);
6454 return ret;
6455 }
6456
6457 static ELEMENT_TYPE *
getElementType(XML_Parser parser,const ENCODING * enc,const char * ptr,const char * end)6458 getElementType(XML_Parser parser,
6459 const ENCODING *enc,
6460 const char *ptr,
6461 const char *end)
6462 {
6463 DTD * const dtd = _dtd; /* save one level of indirection */
6464 const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
6465 ELEMENT_TYPE *ret;
6466
6467 if (!name)
6468 return NULL;
6469 ret = (ELEMENT_TYPE *) lookup(parser, &dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
6470 if (!ret)
6471 return NULL;
6472 if (ret->name != name)
6473 poolDiscard(&dtd->pool);
6474 else {
6475 poolFinish(&dtd->pool);
6476 if (!setElementTypePrefix(parser, ret))
6477 return NULL;
6478 }
6479 return ret;
6480 }
6481