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