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