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