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