Codebase list teckit / 55a74e9
Imported Upstream version 2.5.4~svn140+ds2 Daniel Glassey 7 years ago
4 changed file(s) with 0 addition(s) and 6665 deletion(s). Raw diff Collapse all Expand all
+0
-151
SFconv/expat/xmlparse/hashtable.c less more
0 /*
1 The contents of this file are subject to the Mozilla Public License
2 Version 1.1 (the "License"); you may not use this file except in
3 csompliance with the License. You may obtain a copy of the License at
4 http://www.mozilla.org/MPL/
5
6 Software distributed under the License is distributed on an "AS IS"
7 basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
8 License for the specific language governing rights and limitations
9 under the License.
10
11 The Original Code is expat.
12
13 The Initial Developer of the Original Code is James Clark.
14 Portions created by James Clark are Copyright (C) 1998, 1999
15 James Clark. All Rights Reserved.
16
17 Contributor(s):
18
19 Alternatively, the contents of this file may be used under the terms
20 of the GNU General Public License (the "GPL"), in which case the
21 provisions of the GPL are applicable instead of those above. If you
22 wish to allow use of your version of this file only under the terms of
23 the GPL and not to allow others to use your version of this file under
24 the MPL, indicate your decision by deleting the provisions above and
25 replace them with the notice and other provisions required by the
26 GPL. If you do not delete the provisions above, a recipient may use
27 your version of this file under either the MPL or the GPL.
28 */
29
30 #include "xmldef.h"
31
32 #ifdef XML_UNICODE_WCHAR_T
33 #ifndef XML_UNICODE
34 #define XML_UNICODE
35 #endif
36 #endif
37
38 #include "hashtable.h"
39
40 #define INIT_SIZE 64
41
42 static
43 int keyeq(KEY s1, KEY s2)
44 {
45 for (; *s1 == *s2; s1++, s2++)
46 if (*s1 == 0)
47 return 1;
48 return 0;
49 }
50
51 static
52 unsigned long hash(KEY s)
53 {
54 unsigned long h = 0;
55 while (*s)
56 h = (h << 5) + h + (unsigned char)*s++;
57 return h;
58 }
59
60 NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize)
61 {
62 size_t i;
63 if (table->size == 0) {
64 if (!createSize)
65 return 0;
66 table->v = calloc(INIT_SIZE, sizeof(NAMED *));
67 if (!table->v)
68 return 0;
69 table->size = INIT_SIZE;
70 table->usedLim = INIT_SIZE / 2;
71 i = hash(name) & (table->size - 1);
72 }
73 else {
74 unsigned long h = hash(name);
75 for (i = h & (table->size - 1);
76 table->v[i];
77 i == 0 ? i = table->size - 1 : --i) {
78 if (keyeq(name, table->v[i]->name))
79 return table->v[i];
80 }
81 if (!createSize)
82 return 0;
83 if (table->used == table->usedLim) {
84 /* check for overflow */
85 size_t newSize = table->size * 2;
86 NAMED **newV = calloc(newSize, sizeof(NAMED *));
87 if (!newV)
88 return 0;
89 for (i = 0; i < table->size; i++)
90 if (table->v[i]) {
91 size_t j;
92 for (j = hash(table->v[i]->name) & (newSize - 1);
93 newV[j];
94 j == 0 ? j = newSize - 1 : --j)
95 ;
96 newV[j] = table->v[i];
97 }
98 free(table->v);
99 table->v = newV;
100 table->size = newSize;
101 table->usedLim = newSize/2;
102 for (i = h & (table->size - 1);
103 table->v[i];
104 i == 0 ? i = table->size - 1 : --i)
105 ;
106 }
107 }
108 table->v[i] = calloc(1, createSize);
109 if (!table->v[i])
110 return 0;
111 table->v[i]->name = name;
112 (table->used)++;
113 return table->v[i];
114 }
115
116 void hashTableDestroy(HASH_TABLE *table)
117 {
118 size_t i;
119 for (i = 0; i < table->size; i++) {
120 NAMED *p = table->v[i];
121 if (p)
122 free(p);
123 }
124 free(table->v);
125 }
126
127 void hashTableInit(HASH_TABLE *p)
128 {
129 p->size = 0;
130 p->usedLim = 0;
131 p->used = 0;
132 p->v = 0;
133 }
134
135 void hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
136 {
137 iter->p = table->v;
138 iter->end = iter->p + table->size;
139 }
140
141 NAMED *hashTableIterNext(HASH_TABLE_ITER *iter)
142 {
143 while (iter->p != iter->end) {
144 NAMED *tem = *(iter->p)++;
145 if (tem)
146 return tem;
147 }
148 return 0;
149 }
150
+0
-3707
SFconv/expat/xmlparse/xmlparse.c less more
0 /*
1 The contents of this file are subject to the Mozilla Public License
2 Version 1.1 (the "License"); you may not use this file except in
3 compliance with the License. You may obtain a copy of the License at
4 http://www.mozilla.org/MPL/
5
6 Software distributed under the License is distributed on an "AS IS"
7 basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
8 License for the specific language governing rights and limitations
9 under the License.
10
11 The Original Code is expat.
12
13 The Initial Developer of the Original Code is James Clark.
14 Portions created by James Clark are Copyright (C) 1998, 1999
15 James Clark. All Rights Reserved.
16
17 Contributor(s):
18
19 Alternatively, the contents of this file may be used under the terms
20 of the GNU General Public License (the "GPL"), in which case the
21 provisions of the GPL are applicable instead of those above. If you
22 wish to allow use of your version of this file only under the terms of
23 the GPL and not to allow others to use your version of this file under
24 the MPL, indicate your decision by deleting the provisions above and
25 replace them with the notice and other provisions required by the
26 GPL. If you do not delete the provisions above, a recipient may use
27 your version of this file under either the MPL or the GPL.
28 */
29
30 #include "xmldef.h"
31 #include "xmlparse.h"
32
33 #ifdef XML_UNICODE
34 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
35 #define XmlConvert XmlUtf16Convert
36 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
37 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
38 #define XmlEncode XmlUtf16Encode
39 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
40 typedef unsigned short ICHAR;
41 #else
42 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
43 #define XmlConvert XmlUtf8Convert
44 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
45 #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
46 #define XmlEncode XmlUtf8Encode
47 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
48 typedef char ICHAR;
49 #endif
50
51
52 #ifndef XML_NS
53
54 #define XmlInitEncodingNS XmlInitEncoding
55 #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
56 #undef XmlGetInternalEncodingNS
57 #define XmlGetInternalEncodingNS XmlGetInternalEncoding
58 #define XmlParseXmlDeclNS XmlParseXmlDecl
59
60 #endif
61
62 #ifdef XML_UNICODE_WCHAR_T
63 #define XML_T(x) L ## x
64 #else
65 #define XML_T(x) x
66 #endif
67
68 /* Round up n to be a multiple of sz, where sz is a power of 2. */
69 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
70
71 #include "xmltok.h"
72 #include "xmlrole.h"
73 #include "hashtable.h"
74
75 #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
76 #define INIT_DATA_BUF_SIZE 1024
77 #define INIT_ATTS_SIZE 16
78 #define INIT_BLOCK_SIZE 1024
79 #define INIT_BUFFER_SIZE 1024
80
81 #define EXPAND_SPARE 24
82
83 typedef struct binding {
84 struct prefix *prefix;
85 struct binding *nextTagBinding;
86 struct binding *prevPrefixBinding;
87 const struct attribute_id *attId;
88 XML_Char *uri;
89 int uriLen;
90 int uriAlloc;
91 } BINDING;
92
93 typedef struct prefix {
94 const XML_Char *name;
95 BINDING *binding;
96 } PREFIX;
97
98 typedef struct {
99 const XML_Char *str;
100 const XML_Char *localPart;
101 int uriLen;
102 } TAG_NAME;
103
104 typedef struct tag {
105 struct tag *parent;
106 const char *rawName;
107 int rawNameLength;
108 TAG_NAME name;
109 char *buf;
110 char *bufEnd;
111 BINDING *bindings;
112 } TAG;
113
114 typedef struct {
115 const XML_Char *name;
116 const XML_Char *textPtr;
117 int textLen;
118 const XML_Char *systemId;
119 const XML_Char *base;
120 const XML_Char *publicId;
121 const XML_Char *notation;
122 char open;
123 } ENTITY;
124
125 typedef struct block {
126 struct block *next;
127 int size;
128 XML_Char s[1];
129 } BLOCK;
130
131 typedef struct {
132 BLOCK *blocks;
133 BLOCK *freeBlocks;
134 const XML_Char *end;
135 XML_Char *ptr;
136 XML_Char *start;
137 } STRING_POOL;
138
139 /* The XML_Char before the name is used to determine whether
140 an attribute has been specified. */
141 typedef struct attribute_id {
142 XML_Char *name;
143 PREFIX *prefix;
144 char maybeTokenized;
145 char xmlns;
146 } ATTRIBUTE_ID;
147
148 typedef struct {
149 const ATTRIBUTE_ID *id;
150 char isCdata;
151 const XML_Char *value;
152 } DEFAULT_ATTRIBUTE;
153
154 typedef struct {
155 const XML_Char *name;
156 PREFIX *prefix;
157 int nDefaultAtts;
158 int allocDefaultAtts;
159 DEFAULT_ATTRIBUTE *defaultAtts;
160 } ELEMENT_TYPE;
161
162 typedef struct {
163 HASH_TABLE generalEntities;
164 HASH_TABLE elementTypes;
165 HASH_TABLE attributeIds;
166 HASH_TABLE prefixes;
167 STRING_POOL pool;
168 int complete;
169 int standalone;
170 #ifdef XML_DTD
171 HASH_TABLE paramEntities;
172 #endif /* XML_DTD */
173 PREFIX defaultPrefix;
174 } DTD;
175
176 typedef struct open_internal_entity {
177 const char *internalEventPtr;
178 const char *internalEventEndPtr;
179 struct open_internal_entity *next;
180 ENTITY *entity;
181 } OPEN_INTERNAL_ENTITY;
182
183 typedef enum XML_Error Processor(XML_Parser parser,
184 const char *start,
185 const char *end,
186 const char **endPtr);
187
188 static Processor prologProcessor;
189 static Processor prologInitProcessor;
190 static Processor contentProcessor;
191 static Processor cdataSectionProcessor;
192 #ifdef XML_DTD
193 static Processor ignoreSectionProcessor;
194 #endif /* XML_DTD */
195 static Processor epilogProcessor;
196 static Processor errorProcessor;
197 static Processor externalEntityInitProcessor;
198 static Processor externalEntityInitProcessor2;
199 static Processor externalEntityInitProcessor3;
200 static Processor externalEntityContentProcessor;
201
202 static enum XML_Error
203 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
204 static enum XML_Error
205 processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *, const char *);
206 static enum XML_Error
207 initializeEncoding(XML_Parser parser);
208 static enum XML_Error
209 doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
210 const char *end, int tok, const char *next, const char **nextPtr);
211 static enum XML_Error
212 processInternalParamEntity(XML_Parser parser, ENTITY *entity);
213 static enum XML_Error
214 doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
215 const char *start, const char *end, const char **endPtr);
216 static enum XML_Error
217 doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr);
218 #ifdef XML_DTD
219 static enum XML_Error
220 doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr);
221 #endif /* XML_DTD */
222 static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *, const char *s,
223 TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
224 static
225 int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr);
226 static int
227 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, int isCdata, const XML_Char *dfltValue);
228 static enum XML_Error
229 storeAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
230 STRING_POOL *);
231 static enum XML_Error
232 appendAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
233 STRING_POOL *);
234 static ATTRIBUTE_ID *
235 getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
236 static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
237 static enum XML_Error
238 storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
239 static int
240 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
241 static int
242 reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
243 static void
244 reportDefault(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
245
246 static const XML_Char *getContext(XML_Parser parser);
247 static int setContext(XML_Parser parser, const XML_Char *context);
248 static void normalizePublicId(XML_Char *s);
249 static int dtdInit(DTD *);
250 static void dtdDestroy(DTD *);
251 static int dtdCopy(DTD *newDtd, const DTD *oldDtd);
252 static int copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
253 #ifdef XML_DTD
254 static void dtdSwap(DTD *, DTD *);
255 #endif /* XML_DTD */
256 static void poolInit(STRING_POOL *);
257 static void poolClear(STRING_POOL *);
258 static void poolDestroy(STRING_POOL *);
259 static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
260 const char *ptr, const char *end);
261 static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
262 const char *ptr, const char *end);
263 static int poolGrow(STRING_POOL *pool);
264 static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s);
265 static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
266
267 #define poolStart(pool) ((pool)->start)
268 #define poolEnd(pool) ((pool)->ptr)
269 #define poolLength(pool) ((pool)->ptr - (pool)->start)
270 #define poolChop(pool) ((void)--(pool->ptr))
271 #define poolLastChar(pool) (((pool)->ptr)[-1])
272 #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
273 #define poolFinish(pool) ((pool)->start = (pool)->ptr)
274 #define poolAppendChar(pool, c) \
275 (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
276 ? 0 \
277 : ((*((pool)->ptr)++ = c), 1))
278
279 typedef struct {
280 /* The first member must be userData so that the XML_GetUserData macro works. */
281 void *m_userData;
282 void *m_handlerArg;
283 char *m_buffer;
284 /* first character to be parsed */
285 const char *m_bufferPtr;
286 /* past last character to be parsed */
287 char *m_bufferEnd;
288 /* allocated end of buffer */
289 const char *m_bufferLim;
290 long m_parseEndByteIndex;
291 const char *m_parseEndPtr;
292 XML_Char *m_dataBuf;
293 XML_Char *m_dataBufEnd;
294 XML_StartElementHandler m_startElementHandler;
295 XML_EndElementHandler m_endElementHandler;
296 XML_CharacterDataHandler m_characterDataHandler;
297 XML_ProcessingInstructionHandler m_processingInstructionHandler;
298 XML_CommentHandler m_commentHandler;
299 XML_StartCdataSectionHandler m_startCdataSectionHandler;
300 XML_EndCdataSectionHandler m_endCdataSectionHandler;
301 XML_DefaultHandler m_defaultHandler;
302 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
303 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
304 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
305 XML_NotationDeclHandler m_notationDeclHandler;
306 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
307 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
308 XML_NotStandaloneHandler m_notStandaloneHandler;
309 XML_ExternalEntityRefHandler m_externalEntityRefHandler;
310 void *m_externalEntityRefHandlerArg;
311 XML_UnknownEncodingHandler m_unknownEncodingHandler;
312 const ENCODING *m_encoding;
313 INIT_ENCODING m_initEncoding;
314 const ENCODING *m_internalEncoding;
315 const XML_Char *m_protocolEncodingName;
316 int m_ns;
317 void *m_unknownEncodingMem;
318 void *m_unknownEncodingData;
319 void *m_unknownEncodingHandlerData;
320 void (*m_unknownEncodingRelease)(void *);
321 PROLOG_STATE m_prologState;
322 Processor *m_processor;
323 enum XML_Error m_errorCode;
324 const char *m_eventPtr;
325 const char *m_eventEndPtr;
326 const char *m_positionPtr;
327 OPEN_INTERNAL_ENTITY *m_openInternalEntities;
328 int m_defaultExpandInternalEntities;
329 int m_tagLevel;
330 ENTITY *m_declEntity;
331 const XML_Char *m_declNotationName;
332 const XML_Char *m_declNotationPublicId;
333 ELEMENT_TYPE *m_declElementType;
334 ATTRIBUTE_ID *m_declAttributeId;
335 char m_declAttributeIsCdata;
336 DTD m_dtd;
337 const XML_Char *m_curBase;
338 TAG *m_tagStack;
339 TAG *m_freeTagList;
340 BINDING *m_inheritedBindings;
341 BINDING *m_freeBindingList;
342 int m_attsSize;
343 int m_nSpecifiedAtts;
344 ATTRIBUTE *m_atts;
345 POSITION m_position;
346 STRING_POOL m_tempPool;
347 STRING_POOL m_temp2Pool;
348 char *m_groupConnector;
349 unsigned m_groupSize;
350 int m_hadExternalDoctype;
351 XML_Char m_namespaceSeparator;
352 #ifdef XML_DTD
353 enum XML_ParamEntityParsing m_paramEntityParsing;
354 XML_Parser m_parentParser;
355 #endif
356 } Parser;
357
358 #define userData (((Parser *)parser)->m_userData)
359 #define handlerArg (((Parser *)parser)->m_handlerArg)
360 #define startElementHandler (((Parser *)parser)->m_startElementHandler)
361 #define endElementHandler (((Parser *)parser)->m_endElementHandler)
362 #define characterDataHandler (((Parser *)parser)->m_characterDataHandler)
363 #define processingInstructionHandler (((Parser *)parser)->m_processingInstructionHandler)
364 #define commentHandler (((Parser *)parser)->m_commentHandler)
365 #define startCdataSectionHandler (((Parser *)parser)->m_startCdataSectionHandler)
366 #define endCdataSectionHandler (((Parser *)parser)->m_endCdataSectionHandler)
367 #define defaultHandler (((Parser *)parser)->m_defaultHandler)
368 #define startDoctypeDeclHandler (((Parser *)parser)->m_startDoctypeDeclHandler)
369 #define endDoctypeDeclHandler (((Parser *)parser)->m_endDoctypeDeclHandler)
370 #define unparsedEntityDeclHandler (((Parser *)parser)->m_unparsedEntityDeclHandler)
371 #define notationDeclHandler (((Parser *)parser)->m_notationDeclHandler)
372 #define startNamespaceDeclHandler (((Parser *)parser)->m_startNamespaceDeclHandler)
373 #define endNamespaceDeclHandler (((Parser *)parser)->m_endNamespaceDeclHandler)
374 #define notStandaloneHandler (((Parser *)parser)->m_notStandaloneHandler)
375 #define externalEntityRefHandler (((Parser *)parser)->m_externalEntityRefHandler)
376 #define externalEntityRefHandlerArg (((Parser *)parser)->m_externalEntityRefHandlerArg)
377 #define unknownEncodingHandler (((Parser *)parser)->m_unknownEncodingHandler)
378 #define encoding (((Parser *)parser)->m_encoding)
379 #define initEncoding (((Parser *)parser)->m_initEncoding)
380 #define internalEncoding (((Parser *)parser)->m_internalEncoding)
381 #define unknownEncodingMem (((Parser *)parser)->m_unknownEncodingMem)
382 #define unknownEncodingData (((Parser *)parser)->m_unknownEncodingData)
383 #define unknownEncodingHandlerData \
384 (((Parser *)parser)->m_unknownEncodingHandlerData)
385 #define unknownEncodingRelease (((Parser *)parser)->m_unknownEncodingRelease)
386 #define protocolEncodingName (((Parser *)parser)->m_protocolEncodingName)
387 #define ns (((Parser *)parser)->m_ns)
388 #define prologState (((Parser *)parser)->m_prologState)
389 #define processor (((Parser *)parser)->m_processor)
390 #define errorCode (((Parser *)parser)->m_errorCode)
391 #define eventPtr (((Parser *)parser)->m_eventPtr)
392 #define eventEndPtr (((Parser *)parser)->m_eventEndPtr)
393 #define positionPtr (((Parser *)parser)->m_positionPtr)
394 #define position (((Parser *)parser)->m_position)
395 #define openInternalEntities (((Parser *)parser)->m_openInternalEntities)
396 #define defaultExpandInternalEntities (((Parser *)parser)->m_defaultExpandInternalEntities)
397 #define tagLevel (((Parser *)parser)->m_tagLevel)
398 #define buffer (((Parser *)parser)->m_buffer)
399 #define bufferPtr (((Parser *)parser)->m_bufferPtr)
400 #define bufferEnd (((Parser *)parser)->m_bufferEnd)
401 #define parseEndByteIndex (((Parser *)parser)->m_parseEndByteIndex)
402 #define parseEndPtr (((Parser *)parser)->m_parseEndPtr)
403 #define bufferLim (((Parser *)parser)->m_bufferLim)
404 #define dataBuf (((Parser *)parser)->m_dataBuf)
405 #define dataBufEnd (((Parser *)parser)->m_dataBufEnd)
406 #define dtd (((Parser *)parser)->m_dtd)
407 #define curBase (((Parser *)parser)->m_curBase)
408 #define declEntity (((Parser *)parser)->m_declEntity)
409 #define declNotationName (((Parser *)parser)->m_declNotationName)
410 #define declNotationPublicId (((Parser *)parser)->m_declNotationPublicId)
411 #define declElementType (((Parser *)parser)->m_declElementType)
412 #define declAttributeId (((Parser *)parser)->m_declAttributeId)
413 #define declAttributeIsCdata (((Parser *)parser)->m_declAttributeIsCdata)
414 #define freeTagList (((Parser *)parser)->m_freeTagList)
415 #define freeBindingList (((Parser *)parser)->m_freeBindingList)
416 #define inheritedBindings (((Parser *)parser)->m_inheritedBindings)
417 #define tagStack (((Parser *)parser)->m_tagStack)
418 #define atts (((Parser *)parser)->m_atts)
419 #define attsSize (((Parser *)parser)->m_attsSize)
420 #define nSpecifiedAtts (((Parser *)parser)->m_nSpecifiedAtts)
421 #define tempPool (((Parser *)parser)->m_tempPool)
422 #define temp2Pool (((Parser *)parser)->m_temp2Pool)
423 #define groupConnector (((Parser *)parser)->m_groupConnector)
424 #define groupSize (((Parser *)parser)->m_groupSize)
425 #define hadExternalDoctype (((Parser *)parser)->m_hadExternalDoctype)
426 #define namespaceSeparator (((Parser *)parser)->m_namespaceSeparator)
427 #ifdef XML_DTD
428 #define parentParser (((Parser *)parser)->m_parentParser)
429 #define paramEntityParsing (((Parser *)parser)->m_paramEntityParsing)
430 #endif /* XML_DTD */
431
432 #ifdef _MSC_VER
433 #ifdef _DEBUG
434 Parser *asParser(XML_Parser parser)
435 {
436 return parser;
437 }
438 #endif
439 #endif
440
441 XML_Parser XML_ParserCreate(const XML_Char *encodingName)
442 {
443 XML_Parser parser = malloc(sizeof(Parser));
444 if (!parser)
445 return parser;
446 processor = prologInitProcessor;
447 XmlPrologStateInit(&prologState);
448 userData = 0;
449 handlerArg = 0;
450 startElementHandler = 0;
451 endElementHandler = 0;
452 characterDataHandler = 0;
453 processingInstructionHandler = 0;
454 commentHandler = 0;
455 startCdataSectionHandler = 0;
456 endCdataSectionHandler = 0;
457 defaultHandler = 0;
458 startDoctypeDeclHandler = 0;
459 endDoctypeDeclHandler = 0;
460 unparsedEntityDeclHandler = 0;
461 notationDeclHandler = 0;
462 startNamespaceDeclHandler = 0;
463 endNamespaceDeclHandler = 0;
464 notStandaloneHandler = 0;
465 externalEntityRefHandler = 0;
466 externalEntityRefHandlerArg = parser;
467 unknownEncodingHandler = 0;
468 buffer = 0;
469 bufferPtr = 0;
470 bufferEnd = 0;
471 parseEndByteIndex = 0;
472 parseEndPtr = 0;
473 bufferLim = 0;
474 declElementType = 0;
475 declAttributeId = 0;
476 declEntity = 0;
477 declNotationName = 0;
478 declNotationPublicId = 0;
479 memset(&position, 0, sizeof(POSITION));
480 errorCode = XML_ERROR_NONE;
481 eventPtr = 0;
482 eventEndPtr = 0;
483 positionPtr = 0;
484 openInternalEntities = 0;
485 tagLevel = 0;
486 tagStack = 0;
487 freeTagList = 0;
488 freeBindingList = 0;
489 inheritedBindings = 0;
490 attsSize = INIT_ATTS_SIZE;
491 atts = malloc(attsSize * sizeof(ATTRIBUTE));
492 nSpecifiedAtts = 0;
493 dataBuf = malloc(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
494 groupSize = 0;
495 groupConnector = 0;
496 hadExternalDoctype = 0;
497 unknownEncodingMem = 0;
498 unknownEncodingRelease = 0;
499 unknownEncodingData = 0;
500 unknownEncodingHandlerData = 0;
501 namespaceSeparator = '!';
502 #ifdef XML_DTD
503 parentParser = 0;
504 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
505 #endif
506 ns = 0;
507 poolInit(&tempPool);
508 poolInit(&temp2Pool);
509 protocolEncodingName = encodingName ? poolCopyString(&tempPool, encodingName) : 0;
510 curBase = 0;
511 if (!dtdInit(&dtd) || !atts || !dataBuf
512 || (encodingName && !protocolEncodingName)) {
513 XML_ParserFree(parser);
514 return 0;
515 }
516 dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
517 XmlInitEncoding(&initEncoding, &encoding, 0);
518 internalEncoding = XmlGetInternalEncoding();
519 return parser;
520 }
521
522 XML_Parser XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
523 {
524 static
525 const XML_Char implicitContext[] = {
526 XML_T('x'), XML_T('m'), XML_T('l'), XML_T('='),
527 XML_T('h'), XML_T('t'), XML_T('t'), XML_T('p'), XML_T(':'),
528 XML_T('/'), XML_T('/'), XML_T('w'), XML_T('w'), XML_T('w'),
529 XML_T('.'), XML_T('w'), XML_T('3'),
530 XML_T('.'), XML_T('o'), XML_T('r'), XML_T('g'),
531 XML_T('/'), XML_T('X'), XML_T('M'), XML_T('L'),
532 XML_T('/'), XML_T('1'), XML_T('9'), XML_T('9'), XML_T('8'),
533 XML_T('/'), XML_T('n'), XML_T('a'), XML_T('m'), XML_T('e'),
534 XML_T('s'), XML_T('p'), XML_T('a'), XML_T('c'), XML_T('e'),
535 XML_T('\0')
536 };
537
538 XML_Parser parser = XML_ParserCreate(encodingName);
539 if (parser) {
540 XmlInitEncodingNS(&initEncoding, &encoding, 0);
541 ns = 1;
542 internalEncoding = XmlGetInternalEncodingNS();
543 namespaceSeparator = nsSep;
544 }
545 if (!setContext(parser, implicitContext)) {
546 XML_ParserFree(parser);
547 return 0;
548 }
549 return parser;
550 }
551
552 int XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
553 {
554 if (!encodingName)
555 protocolEncodingName = 0;
556 else {
557 protocolEncodingName = poolCopyString(&tempPool, encodingName);
558 if (!protocolEncodingName)
559 return 0;
560 }
561 return 1;
562 }
563
564 XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser,
565 const XML_Char *context,
566 const XML_Char *encodingName)
567 {
568 XML_Parser parser = oldParser;
569 DTD *oldDtd = &dtd;
570 XML_StartElementHandler oldStartElementHandler = startElementHandler;
571 XML_EndElementHandler oldEndElementHandler = endElementHandler;
572 XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
573 XML_ProcessingInstructionHandler oldProcessingInstructionHandler = processingInstructionHandler;
574 XML_CommentHandler oldCommentHandler = commentHandler;
575 XML_StartCdataSectionHandler oldStartCdataSectionHandler = startCdataSectionHandler;
576 XML_EndCdataSectionHandler oldEndCdataSectionHandler = endCdataSectionHandler;
577 XML_DefaultHandler oldDefaultHandler = defaultHandler;
578 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler = startNamespaceDeclHandler;
579 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler = endNamespaceDeclHandler;
580 XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
581 XML_ExternalEntityRefHandler oldExternalEntityRefHandler = externalEntityRefHandler;
582 XML_UnknownEncodingHandler oldUnknownEncodingHandler = unknownEncodingHandler;
583 void *oldUserData = userData;
584 void *oldHandlerArg = handlerArg;
585 int oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
586 void *oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
587 #ifdef XML_DTD
588 int oldParamEntityParsing = paramEntityParsing;
589 #endif
590 parser = (ns
591 ? XML_ParserCreateNS(encodingName, namespaceSeparator)
592 : XML_ParserCreate(encodingName));
593 if (!parser)
594 return 0;
595 startElementHandler = oldStartElementHandler;
596 endElementHandler = oldEndElementHandler;
597 characterDataHandler = oldCharacterDataHandler;
598 processingInstructionHandler = oldProcessingInstructionHandler;
599 commentHandler = oldCommentHandler;
600 startCdataSectionHandler = oldStartCdataSectionHandler;
601 endCdataSectionHandler = oldEndCdataSectionHandler;
602 defaultHandler = oldDefaultHandler;
603 startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
604 endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
605 notStandaloneHandler = oldNotStandaloneHandler;
606 externalEntityRefHandler = oldExternalEntityRefHandler;
607 unknownEncodingHandler = oldUnknownEncodingHandler;
608 userData = oldUserData;
609 if (oldUserData == oldHandlerArg)
610 handlerArg = userData;
611 else
612 handlerArg = parser;
613 if (oldExternalEntityRefHandlerArg != oldParser)
614 externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
615 defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
616 #ifdef XML_DTD
617 paramEntityParsing = oldParamEntityParsing;
618 if (context) {
619 #endif /* XML_DTD */
620 if (!dtdCopy(&dtd, oldDtd) || !setContext(parser, context)) {
621 XML_ParserFree(parser);
622 return 0;
623 }
624 processor = externalEntityInitProcessor;
625 #ifdef XML_DTD
626 }
627 else {
628 dtdSwap(&dtd, oldDtd);
629 parentParser = oldParser;
630 XmlPrologStateInitExternalEntity(&prologState);
631 dtd.complete = 1;
632 hadExternalDoctype = 1;
633 }
634 #endif /* XML_DTD */
635 return parser;
636 }
637
638 static
639 void destroyBindings(BINDING *bindings)
640 {
641 for (;;) {
642 BINDING *b = bindings;
643 if (!b)
644 break;
645 bindings = b->nextTagBinding;
646 free(b->uri);
647 free(b);
648 }
649 }
650
651 void XML_ParserFree(XML_Parser parser)
652 {
653 for (;;) {
654 TAG *p;
655 if (tagStack == 0) {
656 if (freeTagList == 0)
657 break;
658 tagStack = freeTagList;
659 freeTagList = 0;
660 }
661 p = tagStack;
662 tagStack = tagStack->parent;
663 free(p->buf);
664 destroyBindings(p->bindings);
665 free(p);
666 }
667 destroyBindings(freeBindingList);
668 destroyBindings(inheritedBindings);
669 poolDestroy(&tempPool);
670 poolDestroy(&temp2Pool);
671 #ifdef XML_DTD
672 if (parentParser) {
673 if (hadExternalDoctype)
674 dtd.complete = 0;
675 dtdSwap(&dtd, &((Parser *)parentParser)->m_dtd);
676 }
677 #endif /* XML_DTD */
678 dtdDestroy(&dtd);
679 free((void *)atts);
680 free(groupConnector);
681 free(buffer);
682 free(dataBuf);
683 free(unknownEncodingMem);
684 if (unknownEncodingRelease)
685 unknownEncodingRelease(unknownEncodingData);
686 free(parser);
687 }
688
689 void XML_UseParserAsHandlerArg(XML_Parser parser)
690 {
691 handlerArg = parser;
692 }
693
694 void XML_SetUserData(XML_Parser parser, void *p)
695 {
696 if (handlerArg == userData)
697 handlerArg = userData = p;
698 else
699 userData = p;
700 }
701
702 int XML_SetBase(XML_Parser parser, const XML_Char *p)
703 {
704 if (p) {
705 p = poolCopyString(&dtd.pool, p);
706 if (!p)
707 return 0;
708 curBase = p;
709 }
710 else
711 curBase = 0;
712 return 1;
713 }
714
715 const XML_Char *XML_GetBase(XML_Parser parser)
716 {
717 return curBase;
718 }
719
720 int XML_GetSpecifiedAttributeCount(XML_Parser parser)
721 {
722 return nSpecifiedAtts;
723 }
724
725 void XML_SetElementHandler(XML_Parser parser,
726 XML_StartElementHandler start,
727 XML_EndElementHandler end)
728 {
729 startElementHandler = start;
730 endElementHandler = end;
731 }
732
733 void XML_SetCharacterDataHandler(XML_Parser parser,
734 XML_CharacterDataHandler handler)
735 {
736 characterDataHandler = handler;
737 }
738
739 void XML_SetProcessingInstructionHandler(XML_Parser parser,
740 XML_ProcessingInstructionHandler handler)
741 {
742 processingInstructionHandler = handler;
743 }
744
745 void XML_SetCommentHandler(XML_Parser parser,
746 XML_CommentHandler handler)
747 {
748 commentHandler = handler;
749 }
750
751 void XML_SetCdataSectionHandler(XML_Parser parser,
752 XML_StartCdataSectionHandler start,
753 XML_EndCdataSectionHandler end)
754 {
755 startCdataSectionHandler = start;
756 endCdataSectionHandler = end;
757 }
758
759 void XML_SetDefaultHandler(XML_Parser parser,
760 XML_DefaultHandler handler)
761 {
762 defaultHandler = handler;
763 defaultExpandInternalEntities = 0;
764 }
765
766 void XML_SetDefaultHandlerExpand(XML_Parser parser,
767 XML_DefaultHandler handler)
768 {
769 defaultHandler = handler;
770 defaultExpandInternalEntities = 1;
771 }
772
773 void XML_SetDoctypeDeclHandler(XML_Parser parser,
774 XML_StartDoctypeDeclHandler start,
775 XML_EndDoctypeDeclHandler end)
776 {
777 startDoctypeDeclHandler = start;
778 endDoctypeDeclHandler = end;
779 }
780
781 void XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
782 XML_UnparsedEntityDeclHandler handler)
783 {
784 unparsedEntityDeclHandler = handler;
785 }
786
787 void XML_SetNotationDeclHandler(XML_Parser parser,
788 XML_NotationDeclHandler handler)
789 {
790 notationDeclHandler = handler;
791 }
792
793 void XML_SetNamespaceDeclHandler(XML_Parser parser,
794 XML_StartNamespaceDeclHandler start,
795 XML_EndNamespaceDeclHandler end)
796 {
797 startNamespaceDeclHandler = start;
798 endNamespaceDeclHandler = end;
799 }
800
801 void XML_SetNotStandaloneHandler(XML_Parser parser,
802 XML_NotStandaloneHandler handler)
803 {
804 notStandaloneHandler = handler;
805 }
806
807 void XML_SetExternalEntityRefHandler(XML_Parser parser,
808 XML_ExternalEntityRefHandler handler)
809 {
810 externalEntityRefHandler = handler;
811 }
812
813 void XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
814 {
815 if (arg)
816 externalEntityRefHandlerArg = arg;
817 else
818 externalEntityRefHandlerArg = parser;
819 }
820
821 void XML_SetUnknownEncodingHandler(XML_Parser parser,
822 XML_UnknownEncodingHandler handler,
823 void *data)
824 {
825 unknownEncodingHandler = handler;
826 unknownEncodingHandlerData = data;
827 }
828
829 int XML_SetParamEntityParsing(XML_Parser parser,
830 enum XML_ParamEntityParsing parsing)
831 {
832 #ifdef XML_DTD
833 paramEntityParsing = parsing;
834 return 1;
835 #else
836 return parsing == XML_PARAM_ENTITY_PARSING_NEVER;
837 #endif
838 }
839
840 int XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
841 {
842 if (len == 0) {
843 if (!isFinal)
844 return 1;
845 positionPtr = bufferPtr;
846 errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0);
847 if (errorCode == XML_ERROR_NONE)
848 return 1;
849 eventEndPtr = eventPtr;
850 processor = errorProcessor;
851 return 0;
852 }
853 else if (bufferPtr == bufferEnd) {
854 const char *end;
855 int nLeftOver;
856 parseEndByteIndex += len;
857 positionPtr = s;
858 if (isFinal) {
859 errorCode = processor(parser, s, parseEndPtr = s + len, 0);
860 if (errorCode == XML_ERROR_NONE)
861 return 1;
862 eventEndPtr = eventPtr;
863 processor = errorProcessor;
864 return 0;
865 }
866 errorCode = processor(parser, s, parseEndPtr = s + len, &end);
867 if (errorCode != XML_ERROR_NONE) {
868 eventEndPtr = eventPtr;
869 processor = errorProcessor;
870 return 0;
871 }
872 XmlUpdatePosition(encoding, positionPtr, end, &position);
873 nLeftOver = s + len - end;
874 if (nLeftOver) {
875 if (buffer == 0 || nLeftOver > bufferLim - buffer) {
876 /* FIXME avoid integer overflow */
877 buffer = buffer == 0 ? malloc(len * 2) : realloc(buffer, len * 2);
878 /* FIXME storage leak if realloc fails */
879 if (!buffer) {
880 errorCode = XML_ERROR_NO_MEMORY;
881 eventPtr = eventEndPtr = 0;
882 processor = errorProcessor;
883 return 0;
884 }
885 bufferLim = buffer + len * 2;
886 }
887 memcpy(buffer, end, nLeftOver);
888 bufferPtr = buffer;
889 bufferEnd = buffer + nLeftOver;
890 }
891 return 1;
892 }
893 else {
894 memcpy(XML_GetBuffer(parser, len), s, len);
895 return XML_ParseBuffer(parser, len, isFinal);
896 }
897 }
898
899 int XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
900 {
901 const char *start = bufferPtr;
902 positionPtr = start;
903 bufferEnd += len;
904 parseEndByteIndex += len;
905 errorCode = processor(parser, start, parseEndPtr = bufferEnd,
906 isFinal ? (const char **)0 : &bufferPtr);
907 if (errorCode == XML_ERROR_NONE) {
908 if (!isFinal)
909 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
910 return 1;
911 }
912 else {
913 eventEndPtr = eventPtr;
914 processor = errorProcessor;
915 return 0;
916 }
917 }
918
919 void *XML_GetBuffer(XML_Parser parser, int len)
920 {
921 if (len > bufferLim - bufferEnd) {
922 /* FIXME avoid integer overflow */
923 int neededSize = len + (bufferEnd - bufferPtr);
924 if (neededSize <= bufferLim - buffer) {
925 memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
926 bufferEnd = buffer + (bufferEnd - bufferPtr);
927 bufferPtr = buffer;
928 }
929 else {
930 char *newBuf;
931 int bufferSize = bufferLim - bufferPtr;
932 if (bufferSize == 0)
933 bufferSize = INIT_BUFFER_SIZE;
934 do {
935 bufferSize *= 2;
936 } while (bufferSize < neededSize);
937 newBuf = malloc(bufferSize);
938 if (newBuf == 0) {
939 errorCode = XML_ERROR_NO_MEMORY;
940 return 0;
941 }
942 bufferLim = newBuf + bufferSize;
943 if (bufferPtr) {
944 memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
945 free(buffer);
946 }
947 bufferEnd = newBuf + (bufferEnd - bufferPtr);
948 bufferPtr = buffer = newBuf;
949 }
950 }
951 return bufferEnd;
952 }
953
954 enum XML_Error XML_GetErrorCode(XML_Parser parser)
955 {
956 return errorCode;
957 }
958
959 long XML_GetCurrentByteIndex(XML_Parser parser)
960 {
961 if (eventPtr)
962 return parseEndByteIndex - (parseEndPtr - eventPtr);
963 return -1;
964 }
965
966 int XML_GetCurrentByteCount(XML_Parser parser)
967 {
968 if (eventEndPtr && eventPtr)
969 return eventEndPtr - eventPtr;
970 return 0;
971 }
972
973 int XML_GetCurrentLineNumber(XML_Parser parser)
974 {
975 if (eventPtr) {
976 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
977 positionPtr = eventPtr;
978 }
979 return position.lineNumber + 1;
980 }
981
982 int XML_GetCurrentColumnNumber(XML_Parser parser)
983 {
984 if (eventPtr) {
985 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
986 positionPtr = eventPtr;
987 }
988 return position.columnNumber;
989 }
990
991 void XML_DefaultCurrent(XML_Parser parser)
992 {
993 if (defaultHandler) {
994 if (openInternalEntities)
995 reportDefault(parser,
996 internalEncoding,
997 openInternalEntities->internalEventPtr,
998 openInternalEntities->internalEventEndPtr);
999 else
1000 reportDefault(parser, encoding, eventPtr, eventEndPtr);
1001 }
1002 }
1003
1004 const XML_LChar *XML_ErrorString(int code)
1005 {
1006 static const XML_LChar *message[] = {
1007 0,
1008 XML_T("out of memory"),
1009 XML_T("syntax error"),
1010 XML_T("no element found"),
1011 XML_T("not well-formed"),
1012 XML_T("unclosed token"),
1013 XML_T("unclosed token"),
1014 XML_T("mismatched tag"),
1015 XML_T("duplicate attribute"),
1016 XML_T("junk after document element"),
1017 XML_T("illegal parameter entity reference"),
1018 XML_T("undefined entity"),
1019 XML_T("recursive entity reference"),
1020 XML_T("asynchronous entity"),
1021 XML_T("reference to invalid character number"),
1022 XML_T("reference to binary entity"),
1023 XML_T("reference to external entity in attribute"),
1024 XML_T("xml processing instruction not at start of external entity"),
1025 XML_T("unknown encoding"),
1026 XML_T("encoding specified in XML declaration is incorrect"),
1027 XML_T("unclosed CDATA section"),
1028 XML_T("error in processing external entity reference"),
1029 XML_T("document is not standalone")
1030 };
1031 if (code > 0 && code < sizeof(message)/sizeof(message[0]))
1032 return message[code];
1033 return 0;
1034 }
1035
1036 static
1037 enum XML_Error contentProcessor(XML_Parser parser,
1038 const char *start,
1039 const char *end,
1040 const char **endPtr)
1041 {
1042 return doContent(parser, 0, encoding, start, end, endPtr);
1043 }
1044
1045 static
1046 enum XML_Error externalEntityInitProcessor(XML_Parser parser,
1047 const char *start,
1048 const char *end,
1049 const char **endPtr)
1050 {
1051 enum XML_Error result = initializeEncoding(parser);
1052 if (result != XML_ERROR_NONE)
1053 return result;
1054 processor = externalEntityInitProcessor2;
1055 return externalEntityInitProcessor2(parser, start, end, endPtr);
1056 }
1057
1058 static
1059 enum XML_Error externalEntityInitProcessor2(XML_Parser parser,
1060 const char *start,
1061 const char *end,
1062 const char **endPtr)
1063 {
1064 const char *next;
1065 int tok = XmlContentTok(encoding, start, end, &next);
1066 switch (tok) {
1067 case XML_TOK_BOM:
1068 start = next;
1069 break;
1070 case XML_TOK_PARTIAL:
1071 if (endPtr) {
1072 *endPtr = start;
1073 return XML_ERROR_NONE;
1074 }
1075 eventPtr = start;
1076 return XML_ERROR_UNCLOSED_TOKEN;
1077 case XML_TOK_PARTIAL_CHAR:
1078 if (endPtr) {
1079 *endPtr = start;
1080 return XML_ERROR_NONE;
1081 }
1082 eventPtr = start;
1083 return XML_ERROR_PARTIAL_CHAR;
1084 }
1085 processor = externalEntityInitProcessor3;
1086 return externalEntityInitProcessor3(parser, start, end, endPtr);
1087 }
1088
1089 static
1090 enum XML_Error externalEntityInitProcessor3(XML_Parser parser,
1091 const char *start,
1092 const char *end,
1093 const char **endPtr)
1094 {
1095 const char *next;
1096 int tok = XmlContentTok(encoding, start, end, &next);
1097 switch (tok) {
1098 case XML_TOK_XML_DECL:
1099 {
1100 enum XML_Error result = processXmlDecl(parser, 1, start, next);
1101 if (result != XML_ERROR_NONE)
1102 return result;
1103 start = next;
1104 }
1105 break;
1106 case XML_TOK_PARTIAL:
1107 if (endPtr) {
1108 *endPtr = start;
1109 return XML_ERROR_NONE;
1110 }
1111 eventPtr = start;
1112 return XML_ERROR_UNCLOSED_TOKEN;
1113 case XML_TOK_PARTIAL_CHAR:
1114 if (endPtr) {
1115 *endPtr = start;
1116 return XML_ERROR_NONE;
1117 }
1118 eventPtr = start;
1119 return XML_ERROR_PARTIAL_CHAR;
1120 }
1121 processor = externalEntityContentProcessor;
1122 tagLevel = 1;
1123 return doContent(parser, 1, encoding, start, end, endPtr);
1124 }
1125
1126 static
1127 enum XML_Error externalEntityContentProcessor(XML_Parser parser,
1128 const char *start,
1129 const char *end,
1130 const char **endPtr)
1131 {
1132 return doContent(parser, 1, encoding, start, end, endPtr);
1133 }
1134
1135 static enum XML_Error
1136 doContent(XML_Parser parser,
1137 int startTagLevel,
1138 const ENCODING *enc,
1139 const char *s,
1140 const char *end,
1141 const char **nextPtr)
1142 {
1143 const char **eventPP;
1144 const char **eventEndPP;
1145 if (enc == encoding) {
1146 eventPP = &eventPtr;
1147 eventEndPP = &eventEndPtr;
1148 }
1149 else {
1150 eventPP = &(openInternalEntities->internalEventPtr);
1151 eventEndPP = &(openInternalEntities->internalEventEndPtr);
1152 }
1153 *eventPP = s;
1154 for (;;) {
1155 const char *next = s; /* XmlContentTok doesn't always set the last arg */
1156 int tok = XmlContentTok(enc, s, end, &next);
1157 *eventEndPP = next;
1158 switch (tok) {
1159 case XML_TOK_TRAILING_CR:
1160 if (nextPtr) {
1161 *nextPtr = s;
1162 return XML_ERROR_NONE;
1163 }
1164 *eventEndPP = end;
1165 if (characterDataHandler) {
1166 XML_Char c = 0xA;
1167 characterDataHandler(handlerArg, &c, 1);
1168 }
1169 else if (defaultHandler)
1170 reportDefault(parser, enc, s, end);
1171 if (startTagLevel == 0)
1172 return XML_ERROR_NO_ELEMENTS;
1173 if (tagLevel != startTagLevel)
1174 return XML_ERROR_ASYNC_ENTITY;
1175 return XML_ERROR_NONE;
1176 case XML_TOK_NONE:
1177 if (nextPtr) {
1178 *nextPtr = s;
1179 return XML_ERROR_NONE;
1180 }
1181 if (startTagLevel > 0) {
1182 if (tagLevel != startTagLevel)
1183 return XML_ERROR_ASYNC_ENTITY;
1184 return XML_ERROR_NONE;
1185 }
1186 return XML_ERROR_NO_ELEMENTS;
1187 case XML_TOK_INVALID:
1188 *eventPP = next;
1189 return XML_ERROR_INVALID_TOKEN;
1190 case XML_TOK_PARTIAL:
1191 if (nextPtr) {
1192 *nextPtr = s;
1193 return XML_ERROR_NONE;
1194 }
1195 return XML_ERROR_UNCLOSED_TOKEN;
1196 case XML_TOK_PARTIAL_CHAR:
1197 if (nextPtr) {
1198 *nextPtr = s;
1199 return XML_ERROR_NONE;
1200 }
1201 return XML_ERROR_PARTIAL_CHAR;
1202 case XML_TOK_ENTITY_REF:
1203 {
1204 const XML_Char *name;
1205 ENTITY *entity;
1206 XML_Char ch = XmlPredefinedEntityName(enc,
1207 s + enc->minBytesPerChar,
1208 next - enc->minBytesPerChar);
1209 if (ch) {
1210 if (characterDataHandler)
1211 characterDataHandler(handlerArg, &ch, 1);
1212 else if (defaultHandler)
1213 reportDefault(parser, enc, s, next);
1214 break;
1215 }
1216 name = poolStoreString(&dtd.pool, enc,
1217 s + enc->minBytesPerChar,
1218 next - enc->minBytesPerChar);
1219 if (!name)
1220 return XML_ERROR_NO_MEMORY;
1221 entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
1222 poolDiscard(&dtd.pool);
1223 if (!entity) {
1224 if (dtd.complete || dtd.standalone)
1225 return XML_ERROR_UNDEFINED_ENTITY;
1226 if (defaultHandler)
1227 reportDefault(parser, enc, s, next);
1228 break;
1229 }
1230 if (entity->open)
1231 return XML_ERROR_RECURSIVE_ENTITY_REF;
1232 if (entity->notation)
1233 return XML_ERROR_BINARY_ENTITY_REF;
1234 if (entity) {
1235 if (entity->textPtr) {
1236 enum XML_Error result;
1237 OPEN_INTERNAL_ENTITY openEntity;
1238 if (defaultHandler && !defaultExpandInternalEntities) {
1239 reportDefault(parser, enc, s, next);
1240 break;
1241 }
1242 entity->open = 1;
1243 openEntity.next = openInternalEntities;
1244 openInternalEntities = &openEntity;
1245 openEntity.entity = entity;
1246 openEntity.internalEventPtr = 0;
1247 openEntity.internalEventEndPtr = 0;
1248 result = doContent(parser,
1249 tagLevel,
1250 internalEncoding,
1251 (char *)entity->textPtr,
1252 (char *)(entity->textPtr + entity->textLen),
1253 0);
1254 entity->open = 0;
1255 openInternalEntities = openEntity.next;
1256 if (result)
1257 return result;
1258 }
1259 else if (externalEntityRefHandler) {
1260 const XML_Char *context;
1261 entity->open = 1;
1262 context = getContext(parser);
1263 entity->open = 0;
1264 if (!context)
1265 return XML_ERROR_NO_MEMORY;
1266 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
1267 context,
1268 entity->base,
1269 entity->systemId,
1270 entity->publicId))
1271 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
1272 poolDiscard(&tempPool);
1273 }
1274 else if (defaultHandler)
1275 reportDefault(parser, enc, s, next);
1276 }
1277 break;
1278 }
1279 case XML_TOK_START_TAG_WITH_ATTS:
1280 if (!startElementHandler) {
1281 enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
1282 if (result)
1283 return result;
1284 }
1285 /* fall through */
1286 case XML_TOK_START_TAG_NO_ATTS:
1287 {
1288 TAG *tag;
1289 if (freeTagList) {
1290 tag = freeTagList;
1291 freeTagList = freeTagList->parent;
1292 }
1293 else {
1294 tag = malloc(sizeof(TAG));
1295 if (!tag)
1296 return XML_ERROR_NO_MEMORY;
1297 tag->buf = malloc(INIT_TAG_BUF_SIZE);
1298 if (!tag->buf)
1299 return XML_ERROR_NO_MEMORY;
1300 tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
1301 }
1302 tag->bindings = 0;
1303 tag->parent = tagStack;
1304 tagStack = tag;
1305 tag->name.localPart = 0;
1306 tag->rawName = s + enc->minBytesPerChar;
1307 tag->rawNameLength = XmlNameLength(enc, tag->rawName);
1308 if (nextPtr) {
1309 /* Need to guarantee that:
1310 tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)) <= tag->bufEnd - sizeof(XML_Char) */
1311 if (tag->rawNameLength + (int)(sizeof(XML_Char) - 1) + (int)sizeof(XML_Char) > tag->bufEnd - tag->buf) {
1312 int bufSize = tag->rawNameLength * 4;
1313 bufSize = ROUND_UP(bufSize, sizeof(XML_Char));
1314 tag->buf = realloc(tag->buf, bufSize);
1315 if (!tag->buf)
1316 return XML_ERROR_NO_MEMORY;
1317 tag->bufEnd = tag->buf + bufSize;
1318 }
1319 memcpy(tag->buf, tag->rawName, tag->rawNameLength);
1320 tag->rawName = tag->buf;
1321 }
1322 ++tagLevel;
1323 if (startElementHandler) {
1324 enum XML_Error result;
1325 XML_Char *toPtr;
1326 for (;;) {
1327 const char *rawNameEnd = tag->rawName + tag->rawNameLength;
1328 const char *fromPtr = tag->rawName;
1329 int bufSize;
1330 if (nextPtr)
1331 toPtr = (XML_Char *)(tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)));
1332 else
1333 toPtr = (XML_Char *)tag->buf;
1334 tag->name.str = toPtr;
1335 XmlConvert(enc,
1336 &fromPtr, rawNameEnd,
1337 (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
1338 if (fromPtr == rawNameEnd)
1339 break;
1340 bufSize = (tag->bufEnd - tag->buf) << 1;
1341 tag->buf = realloc(tag->buf, bufSize);
1342 if (!tag->buf)
1343 return XML_ERROR_NO_MEMORY;
1344 tag->bufEnd = tag->buf + bufSize;
1345 if (nextPtr)
1346 tag->rawName = tag->buf;
1347 }
1348 *toPtr = XML_T('\0');
1349 result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
1350 if (result)
1351 return result;
1352 startElementHandler(handlerArg, tag->name.str, (const XML_Char **)atts);
1353 poolClear(&tempPool);
1354 }
1355 else {
1356 tag->name.str = 0;
1357 if (defaultHandler)
1358 reportDefault(parser, enc, s, next);
1359 }
1360 break;
1361 }
1362 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
1363 if (!startElementHandler) {
1364 enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
1365 if (result)
1366 return result;
1367 }
1368 /* fall through */
1369 case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
1370 if (startElementHandler || endElementHandler) {
1371 const char *rawName = s + enc->minBytesPerChar;
1372 enum XML_Error result;
1373 BINDING *bindings = 0;
1374 TAG_NAME name;
1375 name.str = poolStoreString(&tempPool, enc, rawName,
1376 rawName + XmlNameLength(enc, rawName));
1377 if (!name.str)
1378 return XML_ERROR_NO_MEMORY;
1379 poolFinish(&tempPool);
1380 result = storeAtts(parser, enc, s, &name, &bindings);
1381 if (result)
1382 return result;
1383 poolFinish(&tempPool);
1384 if (startElementHandler)
1385 startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
1386 if (endElementHandler) {
1387 if (startElementHandler)
1388 *eventPP = *eventEndPP;
1389 endElementHandler(handlerArg, name.str);
1390 }
1391 poolClear(&tempPool);
1392 while (bindings) {
1393 BINDING *b = bindings;
1394 if (endNamespaceDeclHandler)
1395 endNamespaceDeclHandler(handlerArg, b->prefix->name);
1396 bindings = bindings->nextTagBinding;
1397 b->nextTagBinding = freeBindingList;
1398 freeBindingList = b;
1399 b->prefix->binding = b->prevPrefixBinding;
1400 }
1401 }
1402 else if (defaultHandler)
1403 reportDefault(parser, enc, s, next);
1404 if (tagLevel == 0)
1405 return epilogProcessor(parser, next, end, nextPtr);
1406 break;
1407 case XML_TOK_END_TAG:
1408 if (tagLevel == startTagLevel)
1409 return XML_ERROR_ASYNC_ENTITY;
1410 else {
1411 int len;
1412 const char *rawName;
1413 TAG *tag = tagStack;
1414 tagStack = tag->parent;
1415 tag->parent = freeTagList;
1416 freeTagList = tag;
1417 rawName = s + enc->minBytesPerChar*2;
1418 len = XmlNameLength(enc, rawName);
1419 if (len != tag->rawNameLength
1420 || memcmp(tag->rawName, rawName, len) != 0) {
1421 *eventPP = rawName;
1422 return XML_ERROR_TAG_MISMATCH;
1423 }
1424 --tagLevel;
1425 if (endElementHandler && tag->name.str) {
1426 if (tag->name.localPart) {
1427 XML_Char *to = (XML_Char *)tag->name.str + tag->name.uriLen;
1428 const XML_Char *from = tag->name.localPart;
1429 while ((*to++ = *from++) != 0)
1430 ;
1431 }
1432 endElementHandler(handlerArg, tag->name.str);
1433 }
1434 else if (defaultHandler)
1435 reportDefault(parser, enc, s, next);
1436 while (tag->bindings) {
1437 BINDING *b = tag->bindings;
1438 if (endNamespaceDeclHandler)
1439 endNamespaceDeclHandler(handlerArg, b->prefix->name);
1440 tag->bindings = tag->bindings->nextTagBinding;
1441 b->nextTagBinding = freeBindingList;
1442 freeBindingList = b;
1443 b->prefix->binding = b->prevPrefixBinding;
1444 }
1445 if (tagLevel == 0)
1446 return epilogProcessor(parser, next, end, nextPtr);
1447 }
1448 break;
1449 case XML_TOK_CHAR_REF:
1450 {
1451 int n = XmlCharRefNumber(enc, s);
1452 if (n < 0)
1453 return XML_ERROR_BAD_CHAR_REF;
1454 if (characterDataHandler) {
1455 XML_Char buf[XML_ENCODE_MAX];
1456 characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
1457 }
1458 else if (defaultHandler)
1459 reportDefault(parser, enc, s, next);
1460 }
1461 break;
1462 case XML_TOK_XML_DECL:
1463 return XML_ERROR_MISPLACED_XML_PI;
1464 case XML_TOK_DATA_NEWLINE:
1465 if (characterDataHandler) {
1466 XML_Char c = 0xA;
1467 characterDataHandler(handlerArg, &c, 1);
1468 }
1469 else if (defaultHandler)
1470 reportDefault(parser, enc, s, next);
1471 break;
1472 case XML_TOK_CDATA_SECT_OPEN:
1473 {
1474 enum XML_Error result;
1475 if (startCdataSectionHandler)
1476 startCdataSectionHandler(handlerArg);
1477 #if 0
1478 /* Suppose you doing a transformation on a document that involves
1479 changing only the character data. You set up a defaultHandler
1480 and a characterDataHandler. The defaultHandler simply copies
1481 characters through. The characterDataHandler does the transformation
1482 and writes the characters out escaping them as necessary. This case
1483 will fail to work if we leave out the following two lines (because &
1484 and < inside CDATA sections will be incorrectly escaped).
1485
1486 However, now we have a start/endCdataSectionHandler, so it seems
1487 easier to let the user deal with this. */
1488
1489 else if (characterDataHandler)
1490 characterDataHandler(handlerArg, dataBuf, 0);
1491 #endif
1492 else if (defaultHandler)
1493 reportDefault(parser, enc, s, next);
1494 result = doCdataSection(parser, enc, &next, end, nextPtr);
1495 if (!next) {
1496 processor = cdataSectionProcessor;
1497 return result;
1498 }
1499 }
1500 break;
1501 case XML_TOK_TRAILING_RSQB:
1502 if (nextPtr) {
1503 *nextPtr = s;
1504 return XML_ERROR_NONE;
1505 }
1506 if (characterDataHandler) {
1507 if (MUST_CONVERT(enc, s)) {
1508 ICHAR *dataPtr = (ICHAR *)dataBuf;
1509 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
1510 characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
1511 }
1512 else
1513 characterDataHandler(handlerArg,
1514 (XML_Char *)s,
1515 (XML_Char *)end - (XML_Char *)s);
1516 }
1517 else if (defaultHandler)
1518 reportDefault(parser, enc, s, end);
1519 if (startTagLevel == 0) {
1520 *eventPP = end;
1521 return XML_ERROR_NO_ELEMENTS;
1522 }
1523 if (tagLevel != startTagLevel) {
1524 *eventPP = end;
1525 return XML_ERROR_ASYNC_ENTITY;
1526 }
1527 return XML_ERROR_NONE;
1528 case XML_TOK_DATA_CHARS:
1529 if (characterDataHandler) {
1530 if (MUST_CONVERT(enc, s)) {
1531 for (;;) {
1532 ICHAR *dataPtr = (ICHAR *)dataBuf;
1533 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
1534 *eventEndPP = s;
1535 characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
1536 if (s == next)
1537 break;
1538 *eventPP = s;
1539 }
1540 }
1541 else
1542 characterDataHandler(handlerArg,
1543 (XML_Char *)s,
1544 (XML_Char *)next - (XML_Char *)s);
1545 }
1546 else if (defaultHandler)
1547 reportDefault(parser, enc, s, next);
1548 break;
1549 case XML_TOK_PI:
1550 if (!reportProcessingInstruction(parser, enc, s, next))
1551 return XML_ERROR_NO_MEMORY;
1552 break;
1553 case XML_TOK_COMMENT:
1554 if (!reportComment(parser, enc, s, next))
1555 return XML_ERROR_NO_MEMORY;
1556 break;
1557 default:
1558 if (defaultHandler)
1559 reportDefault(parser, enc, s, next);
1560 break;
1561 }
1562 *eventPP = s = next;
1563 }
1564 /* not reached */
1565 }
1566
1567 /* If tagNamePtr is non-null, build a real list of attributes,
1568 otherwise just check the attributes for well-formedness. */
1569
1570 static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc,
1571 const char *attStr, TAG_NAME *tagNamePtr,
1572 BINDING **bindingsPtr)
1573 {
1574 ELEMENT_TYPE *elementType = 0;
1575 int nDefaultAtts = 0;
1576 const XML_Char **appAtts;
1577 int attIndex = 0;
1578 int i;
1579 int n;
1580 int nPrefixes = 0;
1581 BINDING *binding;
1582 const XML_Char *localPart;
1583
1584 if (tagNamePtr) {
1585 elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str, 0);
1586 if (!elementType) {
1587 tagNamePtr->str = poolCopyString(&dtd.pool, tagNamePtr->str);
1588 if (!tagNamePtr->str)
1589 return XML_ERROR_NO_MEMORY;
1590 elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str, sizeof(ELEMENT_TYPE));
1591 if (!elementType)
1592 return XML_ERROR_NO_MEMORY;
1593 if (ns && !setElementTypePrefix(parser, elementType))
1594 return XML_ERROR_NO_MEMORY;
1595 }
1596 nDefaultAtts = elementType->nDefaultAtts;
1597 }
1598 n = XmlGetAttributes(enc, attStr, attsSize, atts);
1599 if (n + nDefaultAtts > attsSize) {
1600 int oldAttsSize = attsSize;
1601 attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
1602 atts = realloc((void *)atts, attsSize * sizeof(ATTRIBUTE));
1603 if (!atts)
1604 return XML_ERROR_NO_MEMORY;
1605 if (n > oldAttsSize)
1606 XmlGetAttributes(enc, attStr, n, atts);
1607 }
1608 appAtts = (const XML_Char **)atts;
1609 for (i = 0; i < n; i++) {
1610 ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
1611 atts[i].name
1612 + XmlNameLength(enc, atts[i].name));
1613 if (!attId)
1614 return XML_ERROR_NO_MEMORY;
1615 if ((attId->name)[-1]) {
1616 if (enc == encoding)
1617 eventPtr = atts[i].name;
1618 return XML_ERROR_DUPLICATE_ATTRIBUTE;
1619 }
1620 (attId->name)[-1] = 1;
1621 appAtts[attIndex++] = attId->name;
1622 if (!atts[i].normalized) {
1623 enum XML_Error result;
1624 int isCdata = 1;
1625
1626 if (attId->maybeTokenized) {
1627 int j;
1628 for (j = 0; j < nDefaultAtts; j++) {
1629 if (attId == elementType->defaultAtts[j].id) {
1630 isCdata = elementType->defaultAtts[j].isCdata;
1631 break;
1632 }
1633 }
1634 }
1635
1636 result = storeAttributeValue(parser, enc, isCdata,
1637 atts[i].valuePtr, atts[i].valueEnd,
1638 &tempPool);
1639 if (result)
1640 return result;
1641 if (tagNamePtr) {
1642 appAtts[attIndex] = poolStart(&tempPool);
1643 poolFinish(&tempPool);
1644 }
1645 else
1646 poolDiscard(&tempPool);
1647 }
1648 else if (tagNamePtr) {
1649 appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr, atts[i].valueEnd);
1650 if (appAtts[attIndex] == 0)
1651 return XML_ERROR_NO_MEMORY;
1652 poolFinish(&tempPool);
1653 }
1654 if (attId->prefix && tagNamePtr) {
1655 if (attId->xmlns) {
1656 if (!addBinding(parser, attId->prefix, attId, appAtts[attIndex], bindingsPtr))
1657 return XML_ERROR_NO_MEMORY;
1658 --attIndex;
1659 }
1660 else {
1661 attIndex++;
1662 nPrefixes++;
1663 (attId->name)[-1] = 2;
1664 }
1665 }
1666 else
1667 attIndex++;
1668 }
1669 nSpecifiedAtts = attIndex;
1670 if (tagNamePtr) {
1671 int j;
1672 for (j = 0; j < nDefaultAtts; j++) {
1673 const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j;
1674 if (!(da->id->name)[-1] && da->value) {
1675 if (da->id->prefix) {
1676 if (da->id->xmlns) {
1677 if (!addBinding(parser, da->id->prefix, da->id, da->value, bindingsPtr))
1678 return XML_ERROR_NO_MEMORY;
1679 }
1680 else {
1681 (da->id->name)[-1] = 2;
1682 nPrefixes++;
1683 appAtts[attIndex++] = da->id->name;
1684 appAtts[attIndex++] = da->value;
1685 }
1686 }
1687 else {
1688 (da->id->name)[-1] = 1;
1689 appAtts[attIndex++] = da->id->name;
1690 appAtts[attIndex++] = da->value;
1691 }
1692 }
1693 }
1694 appAtts[attIndex] = 0;
1695 }
1696 i = 0;
1697 if (nPrefixes) {
1698 for (; i < attIndex; i += 2) {
1699 if (appAtts[i][-1] == 2) {
1700 ATTRIBUTE_ID *id;
1701 ((XML_Char *)(appAtts[i]))[-1] = 0;
1702 id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, appAtts[i], 0);
1703 if (id->prefix->binding) {
1704 int j;
1705 const BINDING *b = id->prefix->binding;
1706 const XML_Char *s = appAtts[i];
1707 for (j = 0; j < b->uriLen; j++) {
1708 if (!poolAppendChar(&tempPool, b->uri[j]))
1709 return XML_ERROR_NO_MEMORY;
1710 }
1711 while (*s++ != ':')
1712 ;
1713 do {
1714 if (!poolAppendChar(&tempPool, *s))
1715 return XML_ERROR_NO_MEMORY;
1716 } while (*s++);
1717 appAtts[i] = poolStart(&tempPool);
1718 poolFinish(&tempPool);
1719 }
1720 if (!--nPrefixes)
1721 break;
1722 }
1723 else
1724 ((XML_Char *)(appAtts[i]))[-1] = 0;
1725 }
1726 }
1727 for (; i < attIndex; i += 2)
1728 ((XML_Char *)(appAtts[i]))[-1] = 0;
1729 if (!tagNamePtr)
1730 return XML_ERROR_NONE;
1731 for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
1732 binding->attId->name[-1] = 0;
1733 if (elementType->prefix) {
1734 binding = elementType->prefix->binding;
1735 if (!binding)
1736 return XML_ERROR_NONE;
1737 localPart = tagNamePtr->str;
1738 while (*localPart++ != XML_T(':'))
1739 ;
1740 }
1741 else if (dtd.defaultPrefix.binding) {
1742 binding = dtd.defaultPrefix.binding;
1743 localPart = tagNamePtr->str;
1744 }
1745 else
1746 return XML_ERROR_NONE;
1747 tagNamePtr->localPart = localPart;
1748 tagNamePtr->uriLen = binding->uriLen;
1749 i = binding->uriLen;
1750 do {
1751 if (i == binding->uriAlloc) {
1752 binding->uri = realloc(binding->uri, binding->uriAlloc *= 2);
1753 if (!binding->uri)
1754 return XML_ERROR_NO_MEMORY;
1755 }
1756 binding->uri[i++] = *localPart;
1757 } while (*localPart++);
1758 tagNamePtr->str = binding->uri;
1759 return XML_ERROR_NONE;
1760 }
1761
1762 static
1763 int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr)
1764 {
1765 BINDING *b;
1766 int len;
1767 for (len = 0; uri[len]; len++)
1768 ;
1769 if (namespaceSeparator)
1770 len++;
1771 if (freeBindingList) {
1772 b = freeBindingList;
1773 if (len > b->uriAlloc) {
1774 b->uri = realloc(b->uri, len + EXPAND_SPARE);
1775 if (!b->uri)
1776 return 0;
1777 b->uriAlloc = len + EXPAND_SPARE;
1778 }
1779 freeBindingList = b->nextTagBinding;
1780 }
1781 else {
1782 b = malloc(sizeof(BINDING));
1783 if (!b)
1784 return 0;
1785 b->uri = malloc(sizeof(XML_Char) * len + EXPAND_SPARE);
1786 if (!b->uri) {
1787 free(b);
1788 return 0;
1789 }
1790 b->uriAlloc = len;
1791 }
1792 b->uriLen = len;
1793 memcpy(b->uri, uri, len * sizeof(XML_Char));
1794 if (namespaceSeparator)
1795 b->uri[len - 1] = namespaceSeparator;
1796 b->prefix = prefix;
1797 b->attId = attId;
1798 b->prevPrefixBinding = prefix->binding;
1799 if (*uri == XML_T('\0') && prefix == &dtd.defaultPrefix)
1800 prefix->binding = 0;
1801 else
1802 prefix->binding = b;
1803 b->nextTagBinding = *bindingsPtr;
1804 *bindingsPtr = b;
1805 if (startNamespaceDeclHandler)
1806 startNamespaceDeclHandler(handlerArg, prefix->name,
1807 prefix->binding ? uri : 0);
1808 return 1;
1809 }
1810
1811 /* The idea here is to avoid using stack for each CDATA section when
1812 the whole file is parsed with one call. */
1813
1814 static
1815 enum XML_Error cdataSectionProcessor(XML_Parser parser,
1816 const char *start,
1817 const char *end,
1818 const char **endPtr)
1819 {
1820 enum XML_Error result = doCdataSection(parser, encoding, &start, end, endPtr);
1821 if (start) {
1822 processor = contentProcessor;
1823 return contentProcessor(parser, start, end, endPtr);
1824 }
1825 return result;
1826 }
1827
1828 /* startPtr gets set to non-null is the section is closed, and to null if
1829 the section is not yet closed. */
1830
1831 static
1832 enum XML_Error doCdataSection(XML_Parser parser,
1833 const ENCODING *enc,
1834 const char **startPtr,
1835 const char *end,
1836 const char **nextPtr)
1837 {
1838 const char *s = *startPtr;
1839 const char **eventPP;
1840 const char **eventEndPP;
1841 if (enc == encoding) {
1842 eventPP = &eventPtr;
1843 *eventPP = s;
1844 eventEndPP = &eventEndPtr;
1845 }
1846 else {
1847 eventPP = &(openInternalEntities->internalEventPtr);
1848 eventEndPP = &(openInternalEntities->internalEventEndPtr);
1849 }
1850 *eventPP = s;
1851 *startPtr = 0;
1852 for (;;) {
1853 const char *next;
1854 int tok = XmlCdataSectionTok(enc, s, end, &next);
1855 *eventEndPP = next;
1856 switch (tok) {
1857 case XML_TOK_CDATA_SECT_CLOSE:
1858 if (endCdataSectionHandler)
1859 endCdataSectionHandler(handlerArg);
1860 #if 0
1861 /* see comment under XML_TOK_CDATA_SECT_OPEN */
1862 else if (characterDataHandler)
1863 characterDataHandler(handlerArg, dataBuf, 0);
1864 #endif
1865 else if (defaultHandler)
1866 reportDefault(parser, enc, s, next);
1867 *startPtr = next;
1868 return XML_ERROR_NONE;
1869 case XML_TOK_DATA_NEWLINE:
1870 if (characterDataHandler) {
1871 XML_Char c = 0xA;
1872 characterDataHandler(handlerArg, &c, 1);
1873 }
1874 else if (defaultHandler)
1875 reportDefault(parser, enc, s, next);
1876 break;
1877 case XML_TOK_DATA_CHARS:
1878 if (characterDataHandler) {
1879 if (MUST_CONVERT(enc, s)) {
1880 for (;;) {
1881 ICHAR *dataPtr = (ICHAR *)dataBuf;
1882 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
1883 *eventEndPP = next;
1884 characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
1885 if (s == next)
1886 break;
1887 *eventPP = s;
1888 }
1889 }
1890 else
1891 characterDataHandler(handlerArg,
1892 (XML_Char *)s,
1893 (XML_Char *)next - (XML_Char *)s);
1894 }
1895 else if (defaultHandler)
1896 reportDefault(parser, enc, s, next);
1897 break;
1898 case XML_TOK_INVALID:
1899 *eventPP = next;
1900 return XML_ERROR_INVALID_TOKEN;
1901 case XML_TOK_PARTIAL_CHAR:
1902 if (nextPtr) {
1903 *nextPtr = s;
1904 return XML_ERROR_NONE;
1905 }
1906 return XML_ERROR_PARTIAL_CHAR;
1907 case XML_TOK_PARTIAL:
1908 case XML_TOK_NONE:
1909 if (nextPtr) {
1910 *nextPtr = s;
1911 return XML_ERROR_NONE;
1912 }
1913 return XML_ERROR_UNCLOSED_CDATA_SECTION;
1914 default:
1915 abort();
1916 }
1917 *eventPP = s = next;
1918 }
1919 /* not reached */
1920 }
1921
1922 #ifdef XML_DTD
1923
1924 /* The idea here is to avoid using stack for each IGNORE section when
1925 the whole file is parsed with one call. */
1926
1927 static
1928 enum XML_Error ignoreSectionProcessor(XML_Parser parser,
1929 const char *start,
1930 const char *end,
1931 const char **endPtr)
1932 {
1933 enum XML_Error result = doIgnoreSection(parser, encoding, &start, end, endPtr);
1934 if (start) {
1935 processor = prologProcessor;
1936 return prologProcessor(parser, start, end, endPtr);
1937 }
1938 return result;
1939 }
1940
1941 /* startPtr gets set to non-null is the section is closed, and to null if
1942 the section is not yet closed. */
1943
1944 static
1945 enum XML_Error doIgnoreSection(XML_Parser parser,
1946 const ENCODING *enc,
1947 const char **startPtr,
1948 const char *end,
1949 const char **nextPtr)
1950 {
1951 const char *next;
1952 int tok;
1953 const char *s = *startPtr;
1954 const char **eventPP;
1955 const char **eventEndPP;
1956 if (enc == encoding) {
1957 eventPP = &eventPtr;
1958 *eventPP = s;
1959 eventEndPP = &eventEndPtr;
1960 }
1961 else {
1962 eventPP = &(openInternalEntities->internalEventPtr);
1963 eventEndPP = &(openInternalEntities->internalEventEndPtr);
1964 }
1965 *eventPP = s;
1966 *startPtr = 0;
1967 tok = XmlIgnoreSectionTok(enc, s, end, &next);
1968 *eventEndPP = next;
1969 switch (tok) {
1970 case XML_TOK_IGNORE_SECT:
1971 if (defaultHandler)
1972 reportDefault(parser, enc, s, next);
1973 *startPtr = next;
1974 return XML_ERROR_NONE;
1975 case XML_TOK_INVALID:
1976 *eventPP = next;
1977 return XML_ERROR_INVALID_TOKEN;
1978 case XML_TOK_PARTIAL_CHAR:
1979 if (nextPtr) {
1980 *nextPtr = s;
1981 return XML_ERROR_NONE;
1982 }
1983 return XML_ERROR_PARTIAL_CHAR;
1984 case XML_TOK_PARTIAL:
1985 case XML_TOK_NONE:
1986 if (nextPtr) {
1987 *nextPtr = s;
1988 return XML_ERROR_NONE;
1989 }
1990 return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
1991 default:
1992 abort();
1993 }
1994 /* not reached */
1995 }
1996
1997 #endif /* XML_DTD */
1998
1999 static enum XML_Error
2000 initializeEncoding(XML_Parser parser)
2001 {
2002 const char *s;
2003 #ifdef XML_UNICODE
2004 char encodingBuf[128];
2005 if (!protocolEncodingName)
2006 s = 0;
2007 else {
2008 int i;
2009 for (i = 0; protocolEncodingName[i]; i++) {
2010 if (i == sizeof(encodingBuf) - 1
2011 || (protocolEncodingName[i] & ~0x7f) != 0) {
2012 encodingBuf[0] = '\0';
2013 break;
2014 }
2015 encodingBuf[i] = (char)protocolEncodingName[i];
2016 }
2017 encodingBuf[i] = '\0';
2018 s = encodingBuf;
2019 }
2020 #else
2021 s = protocolEncodingName;
2022 #endif
2023 if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
2024 return XML_ERROR_NONE;
2025 return handleUnknownEncoding(parser, protocolEncodingName);
2026 }
2027
2028 static enum XML_Error
2029 processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
2030 const char *s, const char *next)
2031 {
2032 const char *encodingName = 0;
2033 const ENCODING *newEncoding = 0;
2034 const char *version;
2035 int standalone = -1;
2036 if (!(ns
2037 ? XmlParseXmlDeclNS
2038 : XmlParseXmlDecl)(isGeneralTextEntity,
2039 encoding,
2040 s,
2041 next,
2042 &eventPtr,
2043 &version,
2044 &encodingName,
2045 &newEncoding,
2046 &standalone))
2047 return XML_ERROR_SYNTAX;
2048 if (!isGeneralTextEntity && standalone == 1) {
2049 dtd.standalone = 1;
2050 #ifdef XML_DTD
2051 if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
2052 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
2053 #endif /* XML_DTD */
2054 }
2055 if (defaultHandler)
2056 reportDefault(parser, encoding, s, next);
2057 if (!protocolEncodingName) {
2058 if (newEncoding) {
2059 if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
2060 eventPtr = encodingName;
2061 return XML_ERROR_INCORRECT_ENCODING;
2062 }
2063 encoding = newEncoding;
2064 }
2065 else if (encodingName) {
2066 enum XML_Error result;
2067 const XML_Char *str = poolStoreString(&tempPool,
2068 encoding,
2069 encodingName,
2070 encodingName
2071 + XmlNameLength(encoding, encodingName));
2072 if (!str)
2073 return XML_ERROR_NO_MEMORY;
2074 result = handleUnknownEncoding(parser, str);
2075 poolDiscard(&tempPool);
2076 if (result == XML_ERROR_UNKNOWN_ENCODING)
2077 eventPtr = encodingName;
2078 return result;
2079 }
2080 }
2081 return XML_ERROR_NONE;
2082 }
2083
2084 static enum XML_Error
2085 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
2086 {
2087 if (unknownEncodingHandler) {
2088 XML_Encoding info;
2089 int i;
2090 for (i = 0; i < 256; i++)
2091 info.map[i] = -1;
2092 info.convert = 0;
2093 info.data = 0;
2094 info.release = 0;
2095 if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName, &info)) {
2096 ENCODING *enc;
2097 unknownEncodingMem = malloc(XmlSizeOfUnknownEncoding());
2098 if (!unknownEncodingMem) {
2099 if (info.release)
2100 info.release(info.data);
2101 return XML_ERROR_NO_MEMORY;
2102 }
2103 enc = (ns
2104 ? XmlInitUnknownEncodingNS
2105 : XmlInitUnknownEncoding)(unknownEncodingMem,
2106 info.map,
2107 info.convert,
2108 info.data);
2109 if (enc) {
2110 unknownEncodingData = info.data;
2111 unknownEncodingRelease = info.release;
2112 encoding = enc;
2113 return XML_ERROR_NONE;
2114 }
2115 }
2116 if (info.release)
2117 info.release(info.data);
2118 }
2119 return XML_ERROR_UNKNOWN_ENCODING;
2120 }
2121
2122 static enum XML_Error
2123 prologInitProcessor(XML_Parser parser,
2124 const char *s,
2125 const char *end,
2126 const char **nextPtr)
2127 {
2128 enum XML_Error result = initializeEncoding(parser);
2129 if (result != XML_ERROR_NONE)
2130 return result;
2131 processor = prologProcessor;
2132 return prologProcessor(parser, s, end, nextPtr);
2133 }
2134
2135 static enum XML_Error
2136 prologProcessor(XML_Parser parser,
2137 const char *s,
2138 const char *end,
2139 const char **nextPtr)
2140 {
2141 const char *next;
2142 int tok = XmlPrologTok(encoding, s, end, &next);
2143 return doProlog(parser, encoding, s, end, tok, next, nextPtr);
2144 }
2145
2146 static enum XML_Error
2147 doProlog(XML_Parser parser,
2148 const ENCODING *enc,
2149 const char *s,
2150 const char *end,
2151 int tok,
2152 const char *next,
2153 const char **nextPtr)
2154 {
2155 #ifdef XML_DTD
2156 static const XML_Char externalSubsetName[] = { '#' , '\0' };
2157 #endif /* XML_DTD */
2158
2159 const char **eventPP;
2160 const char **eventEndPP;
2161 if (enc == encoding) {
2162 eventPP = &eventPtr;
2163 eventEndPP = &eventEndPtr;
2164 }
2165 else {
2166 eventPP = &(openInternalEntities->internalEventPtr);
2167 eventEndPP = &(openInternalEntities->internalEventEndPtr);
2168 }
2169 for (;;) {
2170 int role;
2171 *eventPP = s;
2172 *eventEndPP = next;
2173 if (tok <= 0) {
2174 if (nextPtr != 0 && tok != XML_TOK_INVALID) {
2175 *nextPtr = s;
2176 return XML_ERROR_NONE;
2177 }
2178 switch (tok) {
2179 case XML_TOK_INVALID:
2180 *eventPP = next;
2181 return XML_ERROR_INVALID_TOKEN;
2182 case XML_TOK_PARTIAL:
2183 return XML_ERROR_UNCLOSED_TOKEN;
2184 case XML_TOK_PARTIAL_CHAR:
2185 return XML_ERROR_PARTIAL_CHAR;
2186 case XML_TOK_NONE:
2187 #ifdef XML_DTD
2188 if (enc != encoding)
2189 return XML_ERROR_NONE;
2190 if (parentParser) {
2191 if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
2192 == XML_ROLE_ERROR)
2193 return XML_ERROR_SYNTAX;
2194 hadExternalDoctype = 0;
2195 return XML_ERROR_NONE;
2196 }
2197 #endif /* XML_DTD */
2198 return XML_ERROR_NO_ELEMENTS;
2199 default:
2200 tok = -tok;
2201 next = end;
2202 break;
2203 }
2204 }
2205 role = XmlTokenRole(&prologState, tok, s, next, enc);
2206 switch (role) {
2207 case XML_ROLE_XML_DECL:
2208 {
2209 enum XML_Error result = processXmlDecl(parser, 0, s, next);
2210 if (result != XML_ERROR_NONE)
2211 return result;
2212 enc = encoding;
2213 }
2214 break;
2215 case XML_ROLE_DOCTYPE_NAME:
2216 if (startDoctypeDeclHandler) {
2217 const XML_Char *name = poolStoreString(&tempPool, enc, s, next);
2218 if (!name)
2219 return XML_ERROR_NO_MEMORY;
2220 startDoctypeDeclHandler(handlerArg, name);
2221 poolClear(&tempPool);
2222 }
2223 break;
2224 #ifdef XML_DTD
2225 case XML_ROLE_TEXT_DECL:
2226 {
2227 enum XML_Error result = processXmlDecl(parser, 1, s, next);
2228 if (result != XML_ERROR_NONE)
2229 return result;
2230 enc = encoding;
2231 }
2232 break;
2233 #endif /* XML_DTD */
2234 case XML_ROLE_DOCTYPE_PUBLIC_ID:
2235 #ifdef XML_DTD
2236 declEntity = (ENTITY *)lookup(&dtd.paramEntities,
2237 externalSubsetName,
2238 sizeof(ENTITY));
2239 if (!declEntity)
2240 return XML_ERROR_NO_MEMORY;
2241 #endif /* XML_DTD */
2242 /* fall through */
2243 case XML_ROLE_ENTITY_PUBLIC_ID:
2244 if (!XmlIsPublicId(enc, s, next, eventPP))
2245 return XML_ERROR_SYNTAX;
2246 if (declEntity) {
2247 XML_Char *tem = poolStoreString(&dtd.pool,
2248 enc,
2249 s + enc->minBytesPerChar,
2250 next - enc->minBytesPerChar);
2251 if (!tem)
2252 return XML_ERROR_NO_MEMORY;
2253 normalizePublicId(tem);
2254 declEntity->publicId = tem;
2255 poolFinish(&dtd.pool);
2256 }
2257 break;
2258 case XML_ROLE_DOCTYPE_CLOSE:
2259 if (dtd.complete && hadExternalDoctype) {
2260 dtd.complete = 0;
2261 #ifdef XML_DTD
2262 if (paramEntityParsing && externalEntityRefHandler) {
2263 ENTITY *entity = (ENTITY *)lookup(&dtd.paramEntities,
2264 externalSubsetName,
2265 0);
2266 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
2267 0,
2268 entity->base,
2269 entity->systemId,
2270 entity->publicId))
2271 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
2272 }
2273 #endif /* XML_DTD */
2274 if (!dtd.complete
2275 && !dtd.standalone
2276 && notStandaloneHandler
2277 && !notStandaloneHandler(handlerArg))
2278 return XML_ERROR_NOT_STANDALONE;
2279 }
2280 if (endDoctypeDeclHandler)
2281 endDoctypeDeclHandler(handlerArg);
2282 break;
2283 case XML_ROLE_INSTANCE_START:
2284 processor = contentProcessor;
2285 return contentProcessor(parser, s, end, nextPtr);
2286 case XML_ROLE_ATTLIST_ELEMENT_NAME:
2287 {
2288 const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next);
2289 if (!name)
2290 return XML_ERROR_NO_MEMORY;
2291 declElementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, name, sizeof(ELEMENT_TYPE));
2292 if (!declElementType)
2293 return XML_ERROR_NO_MEMORY;
2294 if (declElementType->name != name)
2295 poolDiscard(&dtd.pool);
2296 else {
2297 poolFinish(&dtd.pool);
2298 if (!setElementTypePrefix(parser, declElementType))
2299 return XML_ERROR_NO_MEMORY;
2300 }
2301 break;
2302 }
2303 case XML_ROLE_ATTRIBUTE_NAME:
2304 declAttributeId = getAttributeId(parser, enc, s, next);
2305 if (!declAttributeId)
2306 return XML_ERROR_NO_MEMORY;
2307 declAttributeIsCdata = 0;
2308 break;
2309 case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
2310 declAttributeIsCdata = 1;
2311 break;
2312 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
2313 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
2314 if (dtd.complete
2315 && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, 0))
2316 return XML_ERROR_NO_MEMORY;
2317 break;
2318 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
2319 case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
2320 {
2321 const XML_Char *attVal;
2322 enum XML_Error result
2323 = storeAttributeValue(parser, enc, declAttributeIsCdata,
2324 s + enc->minBytesPerChar,
2325 next - enc->minBytesPerChar,
2326 &dtd.pool);
2327 if (result)
2328 return result;
2329 attVal = poolStart(&dtd.pool);
2330 poolFinish(&dtd.pool);
2331 if (dtd.complete
2332 && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, attVal))
2333 return XML_ERROR_NO_MEMORY;
2334 break;
2335 }
2336 case XML_ROLE_ENTITY_VALUE:
2337 {
2338 enum XML_Error result = storeEntityValue(parser, enc,
2339 s + enc->minBytesPerChar,
2340 next - enc->minBytesPerChar);
2341 if (declEntity) {
2342 declEntity->textPtr = poolStart(&dtd.pool);
2343 declEntity->textLen = poolLength(&dtd.pool);
2344 poolFinish(&dtd.pool);
2345 }
2346 else
2347 poolDiscard(&dtd.pool);
2348 if (result != XML_ERROR_NONE)
2349 return result;
2350 }
2351 break;
2352 case XML_ROLE_DOCTYPE_SYSTEM_ID:
2353 if (!dtd.standalone
2354 #ifdef XML_DTD
2355 && !paramEntityParsing
2356 #endif /* XML_DTD */
2357 && notStandaloneHandler
2358 && !notStandaloneHandler(handlerArg))
2359 return XML_ERROR_NOT_STANDALONE;
2360 hadExternalDoctype = 1;
2361 #ifndef XML_DTD
2362 break;
2363 #else /* XML_DTD */
2364 if (!declEntity) {
2365 declEntity = (ENTITY *)lookup(&dtd.paramEntities,
2366 externalSubsetName,
2367 sizeof(ENTITY));
2368 if (!declEntity)
2369 return XML_ERROR_NO_MEMORY;
2370 }
2371 /* fall through */
2372 #endif /* XML_DTD */
2373 case XML_ROLE_ENTITY_SYSTEM_ID:
2374 if (declEntity) {
2375 declEntity->systemId = poolStoreString(&dtd.pool, enc,
2376 s + enc->minBytesPerChar,
2377 next - enc->minBytesPerChar);
2378 if (!declEntity->systemId)
2379 return XML_ERROR_NO_MEMORY;
2380 declEntity->base = curBase;
2381 poolFinish(&dtd.pool);
2382 }
2383 break;
2384 case XML_ROLE_ENTITY_NOTATION_NAME:
2385 if (declEntity) {
2386 declEntity->notation = poolStoreString(&dtd.pool, enc, s, next);
2387 if (!declEntity->notation)
2388 return XML_ERROR_NO_MEMORY;
2389 poolFinish(&dtd.pool);
2390 if (unparsedEntityDeclHandler) {
2391 *eventEndPP = s;
2392 unparsedEntityDeclHandler(handlerArg,
2393 declEntity->name,
2394 declEntity->base,
2395 declEntity->systemId,
2396 declEntity->publicId,
2397 declEntity->notation);
2398 }
2399
2400 }
2401 break;
2402 case XML_ROLE_GENERAL_ENTITY_NAME:
2403 {
2404 const XML_Char *name;
2405 if (XmlPredefinedEntityName(enc, s, next)) {
2406 declEntity = 0;
2407 break;
2408 }
2409 name = poolStoreString(&dtd.pool, enc, s, next);
2410 if (!name)
2411 return XML_ERROR_NO_MEMORY;
2412 if (dtd.complete) {
2413 declEntity = (ENTITY *)lookup(&dtd.generalEntities, name, sizeof(ENTITY));
2414 if (!declEntity)
2415 return XML_ERROR_NO_MEMORY;
2416 if (declEntity->name != name) {
2417 poolDiscard(&dtd.pool);
2418 declEntity = 0;
2419 }
2420 else
2421 poolFinish(&dtd.pool);
2422 }
2423 else {
2424 poolDiscard(&dtd.pool);
2425 declEntity = 0;
2426 }
2427 }
2428 break;
2429 case XML_ROLE_PARAM_ENTITY_NAME:
2430 #ifdef XML_DTD
2431 if (dtd.complete) {
2432 const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next);
2433 if (!name)
2434 return XML_ERROR_NO_MEMORY;
2435 declEntity = (ENTITY *)lookup(&dtd.paramEntities, name, sizeof(ENTITY));
2436 if (!declEntity)
2437 return XML_ERROR_NO_MEMORY;
2438 if (declEntity->name != name) {
2439 poolDiscard(&dtd.pool);
2440 declEntity = 0;
2441 }
2442 else
2443 poolFinish(&dtd.pool);
2444 }
2445 #else /* not XML_DTD */
2446 declEntity = 0;
2447 #endif /* not XML_DTD */
2448 break;
2449 case XML_ROLE_NOTATION_NAME:
2450 declNotationPublicId = 0;
2451 declNotationName = 0;
2452 if (notationDeclHandler) {
2453 declNotationName = poolStoreString(&tempPool, enc, s, next);
2454 if (!declNotationName)
2455 return XML_ERROR_NO_MEMORY;
2456 poolFinish(&tempPool);
2457 }
2458 break;
2459 case XML_ROLE_NOTATION_PUBLIC_ID:
2460 if (!XmlIsPublicId(enc, s, next, eventPP))
2461 return XML_ERROR_SYNTAX;
2462 if (declNotationName) {
2463 XML_Char *tem = poolStoreString(&tempPool,
2464 enc,
2465 s + enc->minBytesPerChar,
2466 next - enc->minBytesPerChar);
2467 if (!tem)
2468 return XML_ERROR_NO_MEMORY;
2469 normalizePublicId(tem);
2470 declNotationPublicId = tem;
2471 poolFinish(&tempPool);
2472 }
2473 break;
2474 case XML_ROLE_NOTATION_SYSTEM_ID:
2475 if (declNotationName && notationDeclHandler) {
2476 const XML_Char *systemId
2477 = poolStoreString(&tempPool, enc,
2478 s + enc->minBytesPerChar,
2479 next - enc->minBytesPerChar);
2480 if (!systemId)
2481 return XML_ERROR_NO_MEMORY;
2482 *eventEndPP = s;
2483 notationDeclHandler(handlerArg,
2484 declNotationName,
2485 curBase,
2486 systemId,
2487 declNotationPublicId);
2488 }
2489 poolClear(&tempPool);
2490 break;
2491 case XML_ROLE_NOTATION_NO_SYSTEM_ID:
2492 if (declNotationPublicId && notationDeclHandler) {
2493 *eventEndPP = s;
2494 notationDeclHandler(handlerArg,
2495 declNotationName,
2496 curBase,
2497 0,
2498 declNotationPublicId);
2499 }
2500 poolClear(&tempPool);
2501 break;
2502 case XML_ROLE_ERROR:
2503 switch (tok) {
2504 case XML_TOK_PARAM_ENTITY_REF:
2505 return XML_ERROR_PARAM_ENTITY_REF;
2506 case XML_TOK_XML_DECL:
2507 return XML_ERROR_MISPLACED_XML_PI;
2508 default:
2509 return XML_ERROR_SYNTAX;
2510 }
2511 #ifdef XML_DTD
2512 case XML_ROLE_IGNORE_SECT:
2513 {
2514 enum XML_Error result;
2515 if (defaultHandler)
2516 reportDefault(parser, enc, s, next);
2517 result = doIgnoreSection(parser, enc, &next, end, nextPtr);
2518 if (!next) {
2519 processor = ignoreSectionProcessor;
2520 return result;
2521 }
2522 }
2523 break;
2524 #endif /* XML_DTD */
2525 case XML_ROLE_GROUP_OPEN:
2526 if (prologState.level >= groupSize) {
2527 if (groupSize)
2528 groupConnector = realloc(groupConnector, groupSize *= 2);
2529 else
2530 groupConnector = malloc(groupSize = 32);
2531 if (!groupConnector)
2532 return XML_ERROR_NO_MEMORY;
2533 }
2534 groupConnector[prologState.level] = 0;
2535 break;
2536 case XML_ROLE_GROUP_SEQUENCE:
2537 if (groupConnector[prologState.level] == '|')
2538 return XML_ERROR_SYNTAX;
2539 groupConnector[prologState.level] = ',';
2540 break;
2541 case XML_ROLE_GROUP_CHOICE:
2542 if (groupConnector[prologState.level] == ',')
2543 return XML_ERROR_SYNTAX;
2544 groupConnector[prologState.level] = '|';
2545 break;
2546 case XML_ROLE_PARAM_ENTITY_REF:
2547 #ifdef XML_DTD
2548 case XML_ROLE_INNER_PARAM_ENTITY_REF:
2549 if (paramEntityParsing
2550 && (dtd.complete || role == XML_ROLE_INNER_PARAM_ENTITY_REF)) {
2551 const XML_Char *name;
2552 ENTITY *entity;
2553 name = poolStoreString(&dtd.pool, enc,
2554 s + enc->minBytesPerChar,
2555 next - enc->minBytesPerChar);
2556 if (!name)
2557 return XML_ERROR_NO_MEMORY;
2558 entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0);
2559 poolDiscard(&dtd.pool);
2560 if (!entity) {
2561 /* FIXME what to do if !dtd.complete? */
2562 return XML_ERROR_UNDEFINED_ENTITY;
2563 }
2564 if (entity->open)
2565 return XML_ERROR_RECURSIVE_ENTITY_REF;
2566 if (entity->textPtr) {
2567 enum XML_Error result;
2568 result = processInternalParamEntity(parser, entity);
2569 if (result != XML_ERROR_NONE)
2570 return result;
2571 break;
2572 }
2573 if (role == XML_ROLE_INNER_PARAM_ENTITY_REF)
2574 return XML_ERROR_PARAM_ENTITY_REF;
2575 if (externalEntityRefHandler) {
2576 dtd.complete = 0;
2577 entity->open = 1;
2578 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
2579 0,
2580 entity->base,
2581 entity->systemId,
2582 entity->publicId)) {
2583 entity->open = 0;
2584 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
2585 }
2586 entity->open = 0;
2587 if (dtd.complete)
2588 break;
2589 }
2590 }
2591 #endif /* XML_DTD */
2592 if (!dtd.standalone
2593 && notStandaloneHandler
2594 && !notStandaloneHandler(handlerArg))
2595 return XML_ERROR_NOT_STANDALONE;
2596 dtd.complete = 0;
2597 if (defaultHandler)
2598 reportDefault(parser, enc, s, next);
2599 break;
2600 case XML_ROLE_NONE:
2601 switch (tok) {
2602 case XML_TOK_PI:
2603 if (!reportProcessingInstruction(parser, enc, s, next))
2604 return XML_ERROR_NO_MEMORY;
2605 break;
2606 case XML_TOK_COMMENT:
2607 if (!reportComment(parser, enc, s, next))
2608 return XML_ERROR_NO_MEMORY;
2609 break;
2610 }
2611 break;
2612 }
2613 if (defaultHandler) {
2614 switch (tok) {
2615 case XML_TOK_PI:
2616 case XML_TOK_COMMENT:
2617 case XML_TOK_BOM:
2618 case XML_TOK_XML_DECL:
2619 #ifdef XML_DTD
2620 case XML_TOK_IGNORE_SECT:
2621 #endif /* XML_DTD */
2622 case XML_TOK_PARAM_ENTITY_REF:
2623 break;
2624 default:
2625 if (role != XML_ROLE_IGNORE_SECT)
2626 reportDefault(parser, enc, s, next);
2627 }
2628 }
2629 s = next;
2630 tok = XmlPrologTok(enc, s, end, &next);
2631 }
2632 /* not reached */
2633 }
2634
2635 static
2636 enum XML_Error epilogProcessor(XML_Parser parser,
2637 const char *s,
2638 const char *end,
2639 const char **nextPtr)
2640 {
2641 processor = epilogProcessor;
2642 eventPtr = s;
2643 for (;;) {
2644 const char *next;
2645 int tok = XmlPrologTok(encoding, s, end, &next);
2646 eventEndPtr = next;
2647 switch (tok) {
2648 case -XML_TOK_PROLOG_S:
2649 if (defaultHandler) {
2650 eventEndPtr = end;
2651 reportDefault(parser, encoding, s, end);
2652 }
2653 /* fall through */
2654 case XML_TOK_NONE:
2655 if (nextPtr)
2656 *nextPtr = end;
2657 return XML_ERROR_NONE;
2658 case XML_TOK_PROLOG_S:
2659 if (defaultHandler)
2660 reportDefault(parser, encoding, s, next);
2661 break;
2662 case XML_TOK_PI:
2663 if (!reportProcessingInstruction(parser, encoding, s, next))
2664 return XML_ERROR_NO_MEMORY;
2665 break;
2666 case XML_TOK_COMMENT:
2667 if (!reportComment(parser, encoding, s, next))
2668 return XML_ERROR_NO_MEMORY;
2669 break;
2670 case XML_TOK_INVALID:
2671 eventPtr = next;
2672 return XML_ERROR_INVALID_TOKEN;
2673 case XML_TOK_PARTIAL:
2674 if (nextPtr) {
2675 *nextPtr = s;
2676 return XML_ERROR_NONE;
2677 }
2678 return XML_ERROR_UNCLOSED_TOKEN;
2679 case XML_TOK_PARTIAL_CHAR:
2680 if (nextPtr) {
2681 *nextPtr = s;
2682 return XML_ERROR_NONE;
2683 }
2684 return XML_ERROR_PARTIAL_CHAR;
2685 default:
2686 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
2687 }
2688 eventPtr = s = next;
2689 }
2690 }
2691
2692 #ifdef XML_DTD
2693
2694 static enum XML_Error
2695 processInternalParamEntity(XML_Parser parser, ENTITY *entity)
2696 {
2697 const char *s, *end, *next;
2698 int tok;
2699 enum XML_Error result;
2700 OPEN_INTERNAL_ENTITY openEntity;
2701 entity->open = 1;
2702 openEntity.next = openInternalEntities;
2703 openInternalEntities = &openEntity;
2704 openEntity.entity = entity;
2705 openEntity.internalEventPtr = 0;
2706 openEntity.internalEventEndPtr = 0;
2707 s = (char *)entity->textPtr;
2708 end = (char *)(entity->textPtr + entity->textLen);
2709 tok = XmlPrologTok(internalEncoding, s, end, &next);
2710 result = doProlog(parser, internalEncoding, s, end, tok, next, 0);
2711 entity->open = 0;
2712 openInternalEntities = openEntity.next;
2713 return result;
2714 }
2715
2716 #endif /* XML_DTD */
2717
2718 static
2719 enum XML_Error errorProcessor(XML_Parser parser,
2720 const char *s,
2721 const char *end,
2722 const char **nextPtr)
2723 {
2724 return errorCode;
2725 }
2726
2727 static enum XML_Error
2728 storeAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
2729 const char *ptr, const char *end,
2730 STRING_POOL *pool)
2731 {
2732 enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr, end, pool);
2733 if (result)
2734 return result;
2735 if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
2736 poolChop(pool);
2737 if (!poolAppendChar(pool, XML_T('\0')))
2738 return XML_ERROR_NO_MEMORY;
2739 return XML_ERROR_NONE;
2740 }
2741
2742 static enum XML_Error
2743 appendAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
2744 const char *ptr, const char *end,
2745 STRING_POOL *pool)
2746 {
2747 for (;;) {
2748 const char *next;
2749 int tok = XmlAttributeValueTok(enc, ptr, end, &next);
2750 switch (tok) {
2751 case XML_TOK_NONE:
2752 return XML_ERROR_NONE;
2753 case XML_TOK_INVALID:
2754 if (enc == encoding)
2755 eventPtr = next;
2756 return XML_ERROR_INVALID_TOKEN;
2757 case XML_TOK_PARTIAL:
2758 if (enc == encoding)
2759 eventPtr = ptr;
2760 return XML_ERROR_INVALID_TOKEN;
2761 case XML_TOK_CHAR_REF:
2762 {
2763 XML_Char buf[XML_ENCODE_MAX];
2764 int i;
2765 int n = XmlCharRefNumber(enc, ptr);
2766 if (n < 0) {
2767 if (enc == encoding)
2768 eventPtr = ptr;
2769 return XML_ERROR_BAD_CHAR_REF;
2770 }
2771 if (!isCdata
2772 && n == 0x20 /* space */
2773 && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
2774 break;
2775 n = XmlEncode(n, (ICHAR *)buf);
2776 if (!n) {
2777 if (enc == encoding)
2778 eventPtr = ptr;
2779 return XML_ERROR_BAD_CHAR_REF;
2780 }
2781 for (i = 0; i < n; i++) {
2782 if (!poolAppendChar(pool, buf[i]))
2783 return XML_ERROR_NO_MEMORY;
2784 }
2785 }
2786 break;
2787 case XML_TOK_DATA_CHARS:
2788 if (!poolAppend(pool, enc, ptr, next))
2789 return XML_ERROR_NO_MEMORY;
2790 break;
2791 break;
2792 case XML_TOK_TRAILING_CR:
2793 next = ptr + enc->minBytesPerChar;
2794 /* fall through */
2795 case XML_TOK_ATTRIBUTE_VALUE_S:
2796 case XML_TOK_DATA_NEWLINE:
2797 if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
2798 break;
2799 if (!poolAppendChar(pool, 0x20))
2800 return XML_ERROR_NO_MEMORY;
2801 break;
2802 case XML_TOK_ENTITY_REF:
2803 {
2804 const XML_Char *name;
2805 ENTITY *entity;
2806 XML_Char ch = XmlPredefinedEntityName(enc,
2807 ptr + enc->minBytesPerChar,
2808 next - enc->minBytesPerChar);
2809 if (ch) {
2810 if (!poolAppendChar(pool, ch))
2811 return XML_ERROR_NO_MEMORY;
2812 break;
2813 }
2814 name = poolStoreString(&temp2Pool, enc,
2815 ptr + enc->minBytesPerChar,
2816 next - enc->minBytesPerChar);
2817 if (!name)
2818 return XML_ERROR_NO_MEMORY;
2819 entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
2820 poolDiscard(&temp2Pool);
2821 if (!entity) {
2822 if (dtd.complete) {
2823 if (enc == encoding)
2824 eventPtr = ptr;
2825 return XML_ERROR_UNDEFINED_ENTITY;
2826 }
2827 }
2828 else if (entity->open) {
2829 if (enc == encoding)
2830 eventPtr = ptr;
2831 return XML_ERROR_RECURSIVE_ENTITY_REF;
2832 }
2833 else if (entity->notation) {
2834 if (enc == encoding)
2835 eventPtr = ptr;
2836 return XML_ERROR_BINARY_ENTITY_REF;
2837 }
2838 else if (!entity->textPtr) {
2839 if (enc == encoding)
2840 eventPtr = ptr;
2841 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
2842 }
2843 else {
2844 enum XML_Error result;
2845 const XML_Char *textEnd = entity->textPtr + entity->textLen;
2846 entity->open = 1;
2847 result = appendAttributeValue(parser, internalEncoding, isCdata, (char *)entity->textPtr, (char *)textEnd, pool);
2848 entity->open = 0;
2849 if (result)
2850 return result;
2851 }
2852 }
2853 break;
2854 default:
2855 abort();
2856 }
2857 ptr = next;
2858 }
2859 /* not reached */
2860 }
2861
2862 static
2863 enum XML_Error storeEntityValue(XML_Parser parser,
2864 const ENCODING *enc,
2865 const char *entityTextPtr,
2866 const char *entityTextEnd)
2867 {
2868 STRING_POOL *pool = &(dtd.pool);
2869 for (;;) {
2870 const char *next;
2871 int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
2872 switch (tok) {
2873 case XML_TOK_PARAM_ENTITY_REF:
2874 #ifdef XML_DTD
2875 if (parentParser || enc != encoding) {
2876 enum XML_Error result;
2877 const XML_Char *name;
2878 ENTITY *entity;
2879 name = poolStoreString(&tempPool, enc,
2880 entityTextPtr + enc->minBytesPerChar,
2881 next - enc->minBytesPerChar);
2882 if (!name)
2883 return XML_ERROR_NO_MEMORY;
2884 entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0);
2885 poolDiscard(&tempPool);
2886 if (!entity) {
2887 if (enc == encoding)
2888 eventPtr = entityTextPtr;
2889 return XML_ERROR_UNDEFINED_ENTITY;
2890 }
2891 if (entity->open) {
2892 if (enc == encoding)
2893 eventPtr = entityTextPtr;
2894 return XML_ERROR_RECURSIVE_ENTITY_REF;
2895 }
2896 if (entity->systemId) {
2897 if (enc == encoding)
2898 eventPtr = entityTextPtr;
2899 return XML_ERROR_PARAM_ENTITY_REF;
2900 }
2901 entity->open = 1;
2902 result = storeEntityValue(parser,
2903 internalEncoding,
2904 (char *)entity->textPtr,
2905 (char *)(entity->textPtr + entity->textLen));
2906 entity->open = 0;
2907 if (result)
2908 return result;
2909 break;
2910 }
2911 #endif /* XML_DTD */
2912 eventPtr = entityTextPtr;
2913 return XML_ERROR_SYNTAX;
2914 case XML_TOK_NONE:
2915 return XML_ERROR_NONE;
2916 case XML_TOK_ENTITY_REF:
2917 case XML_TOK_DATA_CHARS:
2918 if (!poolAppend(pool, enc, entityTextPtr, next))
2919 return XML_ERROR_NO_MEMORY;
2920 break;
2921 case XML_TOK_TRAILING_CR:
2922 next = entityTextPtr + enc->minBytesPerChar;
2923 /* fall through */
2924 case XML_TOK_DATA_NEWLINE:
2925 if (pool->end == pool->ptr && !poolGrow(pool))
2926 return XML_ERROR_NO_MEMORY;
2927 *(pool->ptr)++ = 0xA;
2928 break;
2929 case XML_TOK_CHAR_REF:
2930 {
2931 XML_Char buf[XML_ENCODE_MAX];
2932 int i;
2933 int n = XmlCharRefNumber(enc, entityTextPtr);
2934 if (n < 0) {
2935 if (enc == encoding)
2936 eventPtr = entityTextPtr;
2937 return XML_ERROR_BAD_CHAR_REF;
2938 }
2939 n = XmlEncode(n, (ICHAR *)buf);
2940 if (!n) {
2941 if (enc == encoding)
2942 eventPtr = entityTextPtr;
2943 return XML_ERROR_BAD_CHAR_REF;
2944 }
2945 for (i = 0; i < n; i++) {
2946 if (pool->end == pool->ptr && !poolGrow(pool))
2947 return XML_ERROR_NO_MEMORY;
2948 *(pool->ptr)++ = buf[i];
2949 }
2950 }
2951 break;
2952 case XML_TOK_PARTIAL:
2953 if (enc == encoding)
2954 eventPtr = entityTextPtr;
2955 return XML_ERROR_INVALID_TOKEN;
2956 case XML_TOK_INVALID:
2957 if (enc == encoding)
2958 eventPtr = next;
2959 return XML_ERROR_INVALID_TOKEN;
2960 default:
2961 abort();
2962 }
2963 entityTextPtr = next;
2964 }
2965 /* not reached */
2966 }
2967
2968 static void
2969 normalizeLines(XML_Char *s)
2970 {
2971 XML_Char *p;
2972 for (;; s++) {
2973 if (*s == XML_T('\0'))
2974 return;
2975 if (*s == 0xD)
2976 break;
2977 }
2978 p = s;
2979 do {
2980 if (*s == 0xD) {
2981 *p++ = 0xA;
2982 if (*++s == 0xA)
2983 s++;
2984 }
2985 else
2986 *p++ = *s++;
2987 } while (*s);
2988 *p = XML_T('\0');
2989 }
2990
2991 static int
2992 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
2993 {
2994 const XML_Char *target;
2995 XML_Char *data;
2996 const char *tem;
2997 if (!processingInstructionHandler) {
2998 if (defaultHandler)
2999 reportDefault(parser, enc, start, end);
3000 return 1;
3001 }
3002 start += enc->minBytesPerChar * 2;
3003 tem = start + XmlNameLength(enc, start);
3004 target = poolStoreString(&tempPool, enc, start, tem);
3005 if (!target)
3006 return 0;
3007 poolFinish(&tempPool);
3008 data = poolStoreString(&tempPool, enc,
3009 XmlSkipS(enc, tem),
3010 end - enc->minBytesPerChar*2);
3011 if (!data)
3012 return 0;
3013 normalizeLines(data);
3014 processingInstructionHandler(handlerArg, target, data);
3015 poolClear(&tempPool);
3016 return 1;
3017 }
3018
3019 static int
3020 reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
3021 {
3022 XML_Char *data;
3023 if (!commentHandler) {
3024 if (defaultHandler)
3025 reportDefault(parser, enc, start, end);
3026 return 1;
3027 }
3028 data = poolStoreString(&tempPool,
3029 enc,
3030 start + enc->minBytesPerChar * 4,
3031 end - enc->minBytesPerChar * 3);
3032 if (!data)
3033 return 0;
3034 normalizeLines(data);
3035 commentHandler(handlerArg, data);
3036 poolClear(&tempPool);
3037 return 1;
3038 }
3039
3040 static void
3041 reportDefault(XML_Parser parser, const ENCODING *enc, const char *s, const char *end)
3042 {
3043 if (MUST_CONVERT(enc, s)) {
3044 const char **eventPP;
3045 const char **eventEndPP;
3046 if (enc == encoding) {
3047 eventPP = &eventPtr;
3048 eventEndPP = &eventEndPtr;
3049 }
3050 else {
3051 eventPP = &(openInternalEntities->internalEventPtr);
3052 eventEndPP = &(openInternalEntities->internalEventEndPtr);
3053 }
3054 do {
3055 ICHAR *dataPtr = (ICHAR *)dataBuf;
3056 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
3057 *eventEndPP = s;
3058 defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
3059 *eventPP = s;
3060 } while (s != end);
3061 }
3062 else
3063 defaultHandler(handlerArg, (XML_Char *)s, (XML_Char *)end - (XML_Char *)s);
3064 }
3065
3066
3067 static int
3068 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, int isCdata, const XML_Char *value)
3069 {
3070 DEFAULT_ATTRIBUTE *att;
3071 if (value) {
3072 /* The handling of default attributes gets messed up if we have
3073 a default which duplicates a non-default. */
3074 int i;
3075 for (i = 0; i < type->nDefaultAtts; i++)
3076 if (attId == type->defaultAtts[i].id)
3077 return 1;
3078 }
3079 if (type->nDefaultAtts == type->allocDefaultAtts) {
3080 if (type->allocDefaultAtts == 0) {
3081 type->allocDefaultAtts = 8;
3082 type->defaultAtts = malloc(type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
3083 }
3084 else {
3085 type->allocDefaultAtts *= 2;
3086 type->defaultAtts = realloc(type->defaultAtts,
3087 type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
3088 }
3089 if (!type->defaultAtts)
3090 return 0;
3091 }
3092 att = type->defaultAtts + type->nDefaultAtts;
3093 att->id = attId;
3094 att->value = value;
3095 att->isCdata = isCdata;
3096 if (!isCdata)
3097 attId->maybeTokenized = 1;
3098 type->nDefaultAtts += 1;
3099 return 1;
3100 }
3101
3102 static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
3103 {
3104 const XML_Char *name;
3105 for (name = elementType->name; *name; name++) {
3106 if (*name == XML_T(':')) {
3107 PREFIX *prefix;
3108 const XML_Char *s;
3109 for (s = elementType->name; s != name; s++) {
3110 if (!poolAppendChar(&dtd.pool, *s))
3111 return 0;
3112 }
3113 if (!poolAppendChar(&dtd.pool, XML_T('\0')))
3114 return 0;
3115 prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX));
3116 if (!prefix)
3117 return 0;
3118 if (prefix->name == poolStart(&dtd.pool))
3119 poolFinish(&dtd.pool);
3120 else
3121 poolDiscard(&dtd.pool);
3122 elementType->prefix = prefix;
3123
3124 }
3125 }
3126 return 1;
3127 }
3128
3129 static ATTRIBUTE_ID *
3130 getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
3131 {
3132 ATTRIBUTE_ID *id;
3133 const XML_Char *name;
3134 if (!poolAppendChar(&dtd.pool, XML_T('\0')))
3135 return 0;
3136 name = poolStoreString(&dtd.pool, enc, start, end);
3137 if (!name)
3138 return 0;
3139 ++name;
3140 id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, name, sizeof(ATTRIBUTE_ID));
3141 if (!id)
3142 return 0;
3143 if (id->name != name)
3144 poolDiscard(&dtd.pool);
3145 else {
3146 poolFinish(&dtd.pool);
3147 if (!ns)
3148 ;
3149 else if (name[0] == 'x'
3150 && name[1] == 'm'
3151 && name[2] == 'l'
3152 && name[3] == 'n'
3153 && name[4] == 's'
3154 && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
3155 if (name[5] == '\0')
3156 id->prefix = &dtd.defaultPrefix;
3157 else
3158 id->prefix = (PREFIX *)lookup(&dtd.prefixes, name + 6, sizeof(PREFIX));
3159 id->xmlns = 1;
3160 }
3161 else {
3162 int i;
3163 for (i = 0; name[i]; i++) {
3164 if (name[i] == XML_T(':')) {
3165 int j;
3166 for (j = 0; j < i; j++) {
3167 if (!poolAppendChar(&dtd.pool, name[j]))
3168 return 0;
3169 }
3170 if (!poolAppendChar(&dtd.pool, XML_T('\0')))
3171 return 0;
3172 id->prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX));
3173 if (id->prefix->name == poolStart(&dtd.pool))
3174 poolFinish(&dtd.pool);
3175 else
3176 poolDiscard(&dtd.pool);
3177 break;
3178 }
3179 }
3180 }
3181 }
3182 return id;
3183 }
3184
3185 #define CONTEXT_SEP XML_T('\f')
3186
3187 static
3188 const XML_Char *getContext(XML_Parser parser)
3189 {
3190 HASH_TABLE_ITER iter;
3191 int needSep = 0;
3192
3193 if (dtd.defaultPrefix.binding) {
3194 int i;
3195 int len;
3196 if (!poolAppendChar(&tempPool, XML_T('=')))
3197 return 0;
3198 len = dtd.defaultPrefix.binding->uriLen;
3199 if (namespaceSeparator != XML_T('\0'))
3200 len--;
3201 for (i = 0; i < len; i++)
3202 if (!poolAppendChar(&tempPool, dtd.defaultPrefix.binding->uri[i]))
3203 return 0;
3204 needSep = 1;
3205 }
3206
3207 hashTableIterInit(&iter, &(dtd.prefixes));
3208 for (;;) {
3209 int i;
3210 int len;
3211 const XML_Char *s;
3212 PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
3213 if (!prefix)
3214 break;
3215 if (!prefix->binding)
3216 continue;
3217 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
3218 return 0;
3219 for (s = prefix->name; *s; s++)
3220 if (!poolAppendChar(&tempPool, *s))
3221 return 0;
3222 if (!poolAppendChar(&tempPool, XML_T('=')))
3223 return 0;
3224 len = prefix->binding->uriLen;
3225 if (namespaceSeparator != XML_T('\0'))
3226 len--;
3227 for (i = 0; i < len; i++)
3228 if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
3229 return 0;
3230 needSep = 1;
3231 }
3232
3233
3234 hashTableIterInit(&iter, &(dtd.generalEntities));
3235 for (;;) {
3236 const XML_Char *s;
3237 ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
3238 if (!e)
3239 break;
3240 if (!e->open)
3241 continue;
3242 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
3243 return 0;
3244 for (s = e->name; *s; s++)
3245 if (!poolAppendChar(&tempPool, *s))
3246 return 0;
3247 needSep = 1;
3248 }
3249
3250 if (!poolAppendChar(&tempPool, XML_T('\0')))
3251 return 0;
3252 return tempPool.start;
3253 }
3254
3255 static
3256 int setContext(XML_Parser parser, const XML_Char *context)
3257 {
3258 const XML_Char *s = context;
3259
3260 while (*context != XML_T('\0')) {
3261 if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
3262 ENTITY *e;
3263 if (!poolAppendChar(&tempPool, XML_T('\0')))
3264 return 0;
3265 e = (ENTITY *)lookup(&dtd.generalEntities, poolStart(&tempPool), 0);
3266 if (e)
3267 e->open = 1;
3268 if (*s != XML_T('\0'))
3269 s++;
3270 context = s;
3271 poolDiscard(&tempPool);
3272 }
3273 else if (*s == '=') {
3274 PREFIX *prefix;
3275 if (poolLength(&tempPool) == 0)
3276 prefix = &dtd.defaultPrefix;
3277 else {
3278 if (!poolAppendChar(&tempPool, XML_T('\0')))
3279 return 0;
3280 prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&tempPool), sizeof(PREFIX));
3281 if (!prefix)
3282 return 0;
3283 if (prefix->name == poolStart(&tempPool))
3284 poolFinish(&tempPool);
3285 else
3286 poolDiscard(&tempPool);
3287 }
3288 for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0'); context++)
3289 if (!poolAppendChar(&tempPool, *context))
3290 return 0;
3291 if (!poolAppendChar(&tempPool, XML_T('\0')))
3292 return 0;
3293 if (!addBinding(parser, prefix, 0, poolStart(&tempPool), &inheritedBindings))
3294 return 0;
3295 poolDiscard(&tempPool);
3296 if (*context != XML_T('\0'))
3297 ++context;
3298 s = context;
3299 }
3300 else {
3301 if (!poolAppendChar(&tempPool, *s))
3302 return 0;
3303 s++;
3304 }
3305 }
3306 return 1;
3307 }
3308
3309
3310 static
3311 void normalizePublicId(XML_Char *publicId)
3312 {
3313 XML_Char *p = publicId;
3314 XML_Char *s;
3315 for (s = publicId; *s; s++) {
3316 switch (*s) {
3317 case 0x20:
3318 case 0xD:
3319 case 0xA:
3320 if (p != publicId && p[-1] != 0x20)
3321 *p++ = 0x20;
3322 break;
3323 default:
3324 *p++ = *s;
3325 }
3326 }
3327 if (p != publicId && p[-1] == 0x20)
3328 --p;
3329 *p = XML_T('\0');
3330 }
3331
3332 static int dtdInit(DTD *p)
3333 {
3334 poolInit(&(p->pool));
3335 hashTableInit(&(p->generalEntities));
3336 hashTableInit(&(p->elementTypes));
3337 hashTableInit(&(p->attributeIds));
3338 hashTableInit(&(p->prefixes));
3339 p->complete = 1;
3340 p->standalone = 0;
3341 #ifdef XML_DTD
3342 hashTableInit(&(p->paramEntities));
3343 #endif /* XML_DTD */
3344 p->defaultPrefix.name = 0;
3345 p->defaultPrefix.binding = 0;
3346 return 1;
3347 }
3348
3349 #ifdef XML_DTD
3350
3351 static void dtdSwap(DTD *p1, DTD *p2)
3352 {
3353 DTD tem;
3354 memcpy(&tem, p1, sizeof(DTD));
3355 memcpy(p1, p2, sizeof(DTD));
3356 memcpy(p2, &tem, sizeof(DTD));
3357 }
3358
3359 #endif /* XML_DTD */
3360
3361 static void dtdDestroy(DTD *p)
3362 {
3363 HASH_TABLE_ITER iter;
3364 hashTableIterInit(&iter, &(p->elementTypes));
3365 for (;;) {
3366 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
3367 if (!e)
3368 break;
3369 if (e->allocDefaultAtts != 0)
3370 free(e->defaultAtts);
3371 }
3372 hashTableDestroy(&(p->generalEntities));
3373 #ifdef XML_DTD
3374 hashTableDestroy(&(p->paramEntities));
3375 #endif /* XML_DTD */
3376 hashTableDestroy(&(p->elementTypes));
3377 hashTableDestroy(&(p->attributeIds));
3378 hashTableDestroy(&(p->prefixes));
3379 poolDestroy(&(p->pool));
3380 }
3381
3382 /* Do a deep copy of the DTD. Return 0 for out of memory; non-zero otherwise.
3383 The new DTD has already been initialized. */
3384
3385 static int dtdCopy(DTD *newDtd, const DTD *oldDtd)
3386 {
3387 HASH_TABLE_ITER iter;
3388
3389 /* Copy the prefix table. */
3390
3391 hashTableIterInit(&iter, &(oldDtd->prefixes));
3392 for (;;) {
3393 const XML_Char *name;
3394 const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
3395 if (!oldP)
3396 break;
3397 name = poolCopyString(&(newDtd->pool), oldP->name);
3398 if (!name)
3399 return 0;
3400 if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
3401 return 0;
3402 }
3403
3404 hashTableIterInit(&iter, &(oldDtd->attributeIds));
3405
3406 /* Copy the attribute id table. */
3407
3408 for (;;) {
3409 ATTRIBUTE_ID *newA;
3410 const XML_Char *name;
3411 const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
3412
3413 if (!oldA)
3414 break;
3415 /* Remember to allocate the scratch byte before the name. */
3416 if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
3417 return 0;
3418 name = poolCopyString(&(newDtd->pool), oldA->name);
3419 if (!name)
3420 return 0;
3421 ++name;
3422 newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name, sizeof(ATTRIBUTE_ID));
3423 if (!newA)
3424 return 0;
3425 newA->maybeTokenized = oldA->maybeTokenized;
3426 if (oldA->prefix) {
3427 newA->xmlns = oldA->xmlns;
3428 if (oldA->prefix == &oldDtd->defaultPrefix)
3429 newA->prefix = &newDtd->defaultPrefix;
3430 else
3431 newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes), oldA->prefix->name, 0);
3432 }
3433 }
3434
3435 /* Copy the element type table. */
3436
3437 hashTableIterInit(&iter, &(oldDtd->elementTypes));
3438
3439 for (;;) {
3440 int i;
3441 ELEMENT_TYPE *newE;
3442 const XML_Char *name;
3443 const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
3444 if (!oldE)
3445 break;
3446 name = poolCopyString(&(newDtd->pool), oldE->name);
3447 if (!name)
3448 return 0;
3449 newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name, sizeof(ELEMENT_TYPE));
3450 if (!newE)
3451 return 0;
3452 if (oldE->nDefaultAtts) {
3453 newE->defaultAtts = (DEFAULT_ATTRIBUTE *)malloc(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
3454 if (!newE->defaultAtts)
3455 return 0;
3456 }
3457 newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
3458 if (oldE->prefix)
3459 newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes), oldE->prefix->name, 0);
3460 for (i = 0; i < newE->nDefaultAtts; i++) {
3461 newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
3462 newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
3463 if (oldE->defaultAtts[i].value) {
3464 newE->defaultAtts[i].value = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
3465 if (!newE->defaultAtts[i].value)
3466 return 0;
3467 }
3468 else
3469 newE->defaultAtts[i].value = 0;
3470 }
3471 }
3472
3473 /* Copy the entity tables. */
3474 if (!copyEntityTable(&(newDtd->generalEntities),
3475 &(newDtd->pool),
3476 &(oldDtd->generalEntities)))
3477 return 0;
3478
3479 #ifdef XML_DTD
3480 if (!copyEntityTable(&(newDtd->paramEntities),
3481 &(newDtd->pool),
3482 &(oldDtd->paramEntities)))
3483 return 0;
3484 #endif /* XML_DTD */
3485
3486 newDtd->complete = oldDtd->complete;
3487 newDtd->standalone = oldDtd->standalone;
3488 return 1;
3489 }
3490
3491 static int copyEntityTable(HASH_TABLE *newTable,
3492 STRING_POOL *newPool,
3493 const HASH_TABLE *oldTable)
3494 {
3495 HASH_TABLE_ITER iter;
3496 const XML_Char *cachedOldBase = 0;
3497 const XML_Char *cachedNewBase = 0;
3498
3499 hashTableIterInit(&iter, oldTable);
3500
3501 for (;;) {
3502 ENTITY *newE;
3503 const XML_Char *name;
3504 const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
3505 if (!oldE)
3506 break;
3507 name = poolCopyString(newPool, oldE->name);
3508 if (!name)
3509 return 0;
3510 newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
3511 if (!newE)
3512 return 0;
3513 if (oldE->systemId) {
3514 const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
3515 if (!tem)
3516 return 0;
3517 newE->systemId = tem;
3518 if (oldE->base) {
3519 if (oldE->base == cachedOldBase)
3520 newE->base = cachedNewBase;
3521 else {
3522 cachedOldBase = oldE->base;
3523 tem = poolCopyString(newPool, cachedOldBase);
3524 if (!tem)
3525 return 0;
3526 cachedNewBase = newE->base = tem;
3527 }
3528 }
3529 }
3530 else {
3531 const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr, oldE->textLen);
3532 if (!tem)
3533 return 0;
3534 newE->textPtr = tem;
3535 newE->textLen = oldE->textLen;
3536 }
3537 if (oldE->notation) {
3538 const XML_Char *tem = poolCopyString(newPool, oldE->notation);
3539 if (!tem)
3540 return 0;
3541 newE->notation = tem;
3542 }
3543 }
3544 return 1;
3545 }
3546
3547 static
3548 void poolInit(STRING_POOL *pool)
3549 {
3550 pool->blocks = 0;
3551 pool->freeBlocks = 0;
3552 pool->start = 0;
3553 pool->ptr = 0;
3554 pool->end = 0;
3555 }
3556
3557 static
3558 void poolClear(STRING_POOL *pool)
3559 {
3560 if (!pool->freeBlocks)
3561 pool->freeBlocks = pool->blocks;
3562 else {
3563 BLOCK *p = pool->blocks;
3564 while (p) {
3565 BLOCK *tem = p->next;
3566 p->next = pool->freeBlocks;
3567 pool->freeBlocks = p;
3568 p = tem;
3569 }
3570 }
3571 pool->blocks = 0;
3572 pool->start = 0;
3573 pool->ptr = 0;
3574 pool->end = 0;
3575 }
3576
3577 static
3578 void poolDestroy(STRING_POOL *pool)
3579 {
3580 BLOCK *p = pool->blocks;
3581 while (p) {
3582 BLOCK *tem = p->next;
3583 free(p);
3584 p = tem;
3585 }
3586 pool->blocks = 0;
3587 p = pool->freeBlocks;
3588 while (p) {
3589 BLOCK *tem = p->next;
3590 free(p);
3591 p = tem;
3592 }
3593 pool->freeBlocks = 0;
3594 pool->ptr = 0;
3595 pool->start = 0;
3596 pool->end = 0;
3597 }
3598
3599 static
3600 XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
3601 const char *ptr, const char *end)
3602 {
3603 if (!pool->ptr && !poolGrow(pool))
3604 return 0;
3605 for (;;) {
3606 XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
3607 if (ptr == end)
3608 break;
3609 if (!poolGrow(pool))
3610 return 0;
3611 }
3612 return pool->start;
3613 }
3614
3615 static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s)
3616 {
3617 do {
3618 if (!poolAppendChar(pool, *s))
3619 return 0;
3620 } while (*s++);
3621 s = pool->start;
3622 poolFinish(pool);
3623 return s;
3624 }
3625
3626 static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
3627 {
3628 if (!pool->ptr && !poolGrow(pool))
3629 return 0;
3630 for (; n > 0; --n, s++) {
3631 if (!poolAppendChar(pool, *s))
3632 return 0;
3633
3634 }
3635 s = pool->start;
3636 poolFinish(pool);
3637 return s;
3638 }