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