-
Notifications
You must be signed in to change notification settings - Fork 0
/
xmlparse.c
6183 lines (5849 loc) · 185 KB
/
xmlparse.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
See the file COPYING for copying permission.
*/
#include <stddef.h>
#include <string.h> /* memset(), memcpy() */
#include <assert.h>
#define XML_BUILDING_EXPAT 1
#ifdef COMPILED_FROM_DSP
#include "winconfig.h"
#elif defined(MACOS_CLASSIC)
#include "macconfig.h"
#elif defined(HAVE_EXPAT_CONFIG_H)
#include "expat_config.h"
#endif /* ndef COMPILED_FROM_DSP */
#include "expat.h"
#ifdef XML_UNICODE
#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
#define XmlConvert XmlUtf16Convert
#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
#define XmlEncode XmlUtf16Encode
#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
typedef unsigned short ICHAR;
#else
#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
#define XmlConvert XmlUtf8Convert
#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
#define XmlEncode XmlUtf8Encode
#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
typedef char ICHAR;
#endif
#ifndef XML_NS
#define XmlInitEncodingNS XmlInitEncoding
#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
#undef XmlGetInternalEncodingNS
#define XmlGetInternalEncodingNS XmlGetInternalEncoding
#define XmlParseXmlDeclNS XmlParseXmlDecl
#endif
#ifdef XML_UNICODE
#ifdef XML_UNICODE_WCHAR_T
#define XML_T(x) (const wchar_t)x
#define XML_L(x) L ## x
#else
#define XML_T(x) (const unsigned short)x
#define XML_L(x) x
#endif
#else
#define XML_T(x) x
#define XML_L(x) x
#endif
/* Round up n to be a multiple of sz, where sz is a power of 2. */
#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
/* Handle the case where memmove() doesn't exist. */
#ifndef HAVE_MEMMOVE
#ifdef HAVE_BCOPY
#define memmove(d,s,l) bcopy((s),(d),(l))
#else
#error memmove does not exist on this platform, nor is a substitute available
#endif /* HAVE_BCOPY */
#endif /* HAVE_MEMMOVE */
#include "internal.h"
#include "xmltok.h"
#include "xmlrole.h"
typedef const XML_Char *KEY;
typedef struct {
KEY name;
} NAMED;
typedef struct {
NAMED **v;
unsigned char power;
size_t size;
size_t used;
const XML_Memory_Handling_Suite *mem;
} HASH_TABLE;
/* Basic character hash algorithm, taken from Python's string hash:
h = h * 1000003 ^ character, the constant being a prime number.
*/
#ifdef XML_UNICODE
#define CHAR_HASH(h, c) \
(((h) * 0xF4243) ^ (unsigned short)(c))
#else
#define CHAR_HASH(h, c) \
(((h) * 0xF4243) ^ (unsigned char)(c))
#endif
/* For probing (after a collision) we need a step size relative prime
to the hash table size, which is a power of 2. We use double-hashing,
since we can calculate a second hash value cheaply by taking those bits
of the first hash value that were discarded (masked out) when the table
index was calculated: index = hash & mask, where mask = table->size - 1.
We limit the maximum step size to table->size / 4 (mask >> 2) and make
it odd, since odd numbers are always relative prime to a power of 2.
*/
#define SECOND_HASH(hash, mask, power) \
((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
#define PROBE_STEP(hash, mask, power) \
((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
typedef struct {
NAMED **p;
NAMED **end;
} HASH_TABLE_ITER;
#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
#define INIT_DATA_BUF_SIZE 1024
#define INIT_ATTS_SIZE 16
#define INIT_ATTS_VERSION 0xFFFFFFFF
#define INIT_BLOCK_SIZE 1024
#define INIT_BUFFER_SIZE 1024
#define EXPAND_SPARE 24
typedef struct binding {
struct prefix *prefix;
struct binding *nextTagBinding;
struct binding *prevPrefixBinding;
const struct attribute_id *attId;
XML_Char *uri;
int uriLen;
int uriAlloc;
} BINDING;
typedef struct prefix {
const XML_Char *name;
BINDING *binding;
} PREFIX;
typedef struct {
const XML_Char *str;
const XML_Char *localPart;
const XML_Char *prefix;
int strLen;
int uriLen;
int prefixLen;
} TAG_NAME;
/* TAG represents an open element.
The name of the element is stored in both the document and API
encodings. The memory buffer 'buf' is a separately-allocated
memory area which stores the name. During the XML_Parse()/
XMLParseBuffer() when the element is open, the memory for the 'raw'
version of the name (in the document encoding) is shared with the
document buffer. If the element is open across calls to
XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
contain the 'raw' name as well.
A parser re-uses these structures, maintaining a list of allocated
TAG objects in a free list.
*/
typedef struct tag {
struct tag *parent; /* parent of this element */
const char *rawName; /* tagName in the original encoding */
int rawNameLength;
TAG_NAME name; /* tagName in the API encoding */
char *buf; /* buffer for name components */
char *bufEnd; /* end of the buffer */
BINDING *bindings;
} TAG;
typedef struct {
const XML_Char *name;
const XML_Char *textPtr;
int textLen; /* length in XML_Chars */
int processed; /* # of processed bytes - when suspended */
const XML_Char *systemId;
const XML_Char *base;
const XML_Char *publicId;
const XML_Char *notation;
XML_Bool open;
XML_Bool is_param;
XML_Bool is_internal; /* true if declared in internal subset outside PE */
} ENTITY;
typedef struct {
enum XML_Content_Type type;
enum XML_Content_Quant quant;
const XML_Char * name;
int firstchild;
int lastchild;
int childcnt;
int nextsib;
} CONTENT_SCAFFOLD;
#define INIT_SCAFFOLD_ELEMENTS 32
typedef struct block {
struct block *next;
int size;
XML_Char s[1];
} BLOCK;
typedef struct {
BLOCK *blocks;
BLOCK *freeBlocks;
const XML_Char *end;
XML_Char *ptr;
XML_Char *start;
const XML_Memory_Handling_Suite *mem;
} STRING_POOL;
/* The XML_Char before the name is used to determine whether
an attribute has been specified. */
typedef struct attribute_id {
XML_Char *name;
PREFIX *prefix;
XML_Bool maybeTokenized;
XML_Bool xmlns;
} ATTRIBUTE_ID;
typedef struct {
const ATTRIBUTE_ID *id;
XML_Bool isCdata;
const XML_Char *value;
} DEFAULT_ATTRIBUTE;
typedef struct {
unsigned long version;
unsigned long hash;
const XML_Char *uriName;
} NS_ATT;
typedef struct {
const XML_Char *name;
PREFIX *prefix;
const ATTRIBUTE_ID *idAtt;
int nDefaultAtts;
int allocDefaultAtts;
DEFAULT_ATTRIBUTE *defaultAtts;
} ELEMENT_TYPE;
typedef struct {
HASH_TABLE generalEntities;
HASH_TABLE elementTypes;
HASH_TABLE attributeIds;
HASH_TABLE prefixes;
STRING_POOL pool;
STRING_POOL entityValuePool;
/* false once a parameter entity reference has been skipped */
XML_Bool keepProcessing;
/* true once an internal or external PE reference has been encountered;
this includes the reference to an external subset */
XML_Bool hasParamEntityRefs;
XML_Bool standalone;
#ifdef XML_DTD
/* indicates if external PE has been read */
XML_Bool paramEntityRead;
HASH_TABLE paramEntities;
#endif /* XML_DTD */
PREFIX defaultPrefix;
/* === scaffolding for building content model === */
XML_Bool in_eldecl;
CONTENT_SCAFFOLD *scaffold;
unsigned contentStringLen;
unsigned scaffSize;
unsigned scaffCount;
int scaffLevel;
int *scaffIndex;
} DTD;
typedef struct open_internal_entity {
const char *internalEventPtr;
const char *internalEventEndPtr;
struct open_internal_entity *next;
ENTITY *entity;
int startTagLevel;
XML_Bool betweenDecl; /* WFC: PE Between Declarations */
} OPEN_INTERNAL_ENTITY;
typedef enum XML_Error PTRCALL Processor(XML_Parser parser,
const char *start,
const char *end,
const char **endPtr);
static Processor prologProcessor;
static Processor prologInitProcessor;
static Processor contentProcessor;
static Processor cdataSectionProcessor;
#ifdef XML_DTD
static Processor ignoreSectionProcessor;
static Processor externalParEntProcessor;
static Processor externalParEntInitProcessor;
static Processor entityValueProcessor;
static Processor entityValueInitProcessor;
#endif /* XML_DTD */
static Processor epilogProcessor;
static Processor errorProcessor;
static Processor externalEntityInitProcessor;
static Processor externalEntityInitProcessor2;
static Processor externalEntityInitProcessor3;
static Processor externalEntityContentProcessor;
static Processor internalEntityProcessor;
static enum XML_Error
handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
static enum XML_Error
processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
const char *s, const char *next);
static enum XML_Error
initializeEncoding(XML_Parser parser);
static enum XML_Error
doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
const char *end, int tok, const char *next, const char **nextPtr,
XML_Bool haveMore);
static enum XML_Error
processInternalEntity(XML_Parser parser, ENTITY *entity,
XML_Bool betweenDecl);
static enum XML_Error
doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
const char *start, const char *end, const char **endPtr,
XML_Bool haveMore);
static enum XML_Error
doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
const char *end, const char **nextPtr, XML_Bool haveMore);
#ifdef XML_DTD
static enum XML_Error
doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
const char *end, const char **nextPtr, XML_Bool haveMore);
#endif /* XML_DTD */
static enum XML_Error
storeAtts(XML_Parser parser, const ENCODING *, const char *s,
TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
static enum XML_Error
addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
const XML_Char *uri, BINDING **bindingsPtr);
static int
defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
static enum XML_Error
storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
const char *, const char *, STRING_POOL *);
static enum XML_Error
appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
const char *, const char *, STRING_POOL *);
static ATTRIBUTE_ID *
getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
const char *end);
static int
setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
static enum XML_Error
storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
const char *end);
static int
reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
const char *start, const char *end);
static int
reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
const char *end);
static void
reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,
const char *end);
static const XML_Char * getContext(XML_Parser parser);
static XML_Bool
setContext(XML_Parser parser, const XML_Char *context);
static void FASTCALL normalizePublicId(XML_Char *s);
static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
/* do not call if parentParser != NULL */
static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
static void
dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
static int
dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
static int
copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
static NAMED *
lookup(HASH_TABLE *table, KEY name, size_t createSize);
static void FASTCALL
hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
static void FASTCALL hashTableClear(HASH_TABLE *);
static void FASTCALL hashTableDestroy(HASH_TABLE *);
static void FASTCALL
hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
static void FASTCALL
poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);
static void FASTCALL poolClear(STRING_POOL *);
static void FASTCALL poolDestroy(STRING_POOL *);
static XML_Char *
poolAppend(STRING_POOL *pool, const ENCODING *enc,
const char *ptr, const char *end);
static XML_Char *
poolStoreString(STRING_POOL *pool, const ENCODING *enc,
const char *ptr, const char *end);
static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
static const XML_Char * FASTCALL
poolCopyString(STRING_POOL *pool, const XML_Char *s);
static const XML_Char *
poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
static const XML_Char * FASTCALL
poolAppendString(STRING_POOL *pool, const XML_Char *s);
static int FASTCALL nextScaffoldPart(XML_Parser parser);
static XML_Content * build_model(XML_Parser parser);
static ELEMENT_TYPE *
getElementType(XML_Parser parser, const ENCODING *enc,
const char *ptr, const char *end);
static XML_Parser
parserCreate(const XML_Char *encodingName,
const XML_Memory_Handling_Suite *memsuite,
const XML_Char *nameSep,
DTD *dtd);
static void
parserInit(XML_Parser parser, const XML_Char *encodingName);
#define poolStart(pool) ((pool)->start)
#define poolEnd(pool) ((pool)->ptr)
#define poolLength(pool) ((pool)->ptr - (pool)->start)
#define poolChop(pool) ((void)--(pool->ptr))
#define poolLastChar(pool) (((pool)->ptr)[-1])
#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
#define poolFinish(pool) ((pool)->start = (pool)->ptr)
#define poolAppendChar(pool, c) \
(((pool)->ptr == (pool)->end && !poolGrow(pool)) \
? 0 \
: ((*((pool)->ptr)++ = c), 1))
struct XML_ParserStruct {
/* The first member must be userData so that the XML_GetUserData
macro works. */
void *m_userData;
void *m_handlerArg;
char *m_buffer;
const XML_Memory_Handling_Suite m_mem;
/* first character to be parsed */
const char *m_bufferPtr;
/* past last character to be parsed */
char *m_bufferEnd;
/* allocated end of buffer */
const char *m_bufferLim;
long m_parseEndByteIndex;
const char *m_parseEndPtr;
XML_Char *m_dataBuf;
XML_Char *m_dataBufEnd;
XML_StartElementHandler m_startElementHandler;
XML_EndElementHandler m_endElementHandler;
XML_CharacterDataHandler m_characterDataHandler;
XML_ProcessingInstructionHandler m_processingInstructionHandler;
XML_CommentHandler m_commentHandler;
XML_StartCdataSectionHandler m_startCdataSectionHandler;
XML_EndCdataSectionHandler m_endCdataSectionHandler;
XML_DefaultHandler m_defaultHandler;
XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
XML_NotationDeclHandler m_notationDeclHandler;
XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
XML_NotStandaloneHandler m_notStandaloneHandler;
XML_ExternalEntityRefHandler m_externalEntityRefHandler;
XML_Parser m_externalEntityRefHandlerArg;
XML_SkippedEntityHandler m_skippedEntityHandler;
XML_UnknownEncodingHandler m_unknownEncodingHandler;
XML_ElementDeclHandler m_elementDeclHandler;
XML_AttlistDeclHandler m_attlistDeclHandler;
XML_EntityDeclHandler m_entityDeclHandler;
XML_XmlDeclHandler m_xmlDeclHandler;
const ENCODING *m_encoding;
INIT_ENCODING m_initEncoding;
const ENCODING *m_internalEncoding;
const XML_Char *m_protocolEncodingName;
XML_Bool m_ns;
XML_Bool m_ns_triplets;
void *m_unknownEncodingMem;
void *m_unknownEncodingData;
void *m_unknownEncodingHandlerData;
void (XMLCALL *m_unknownEncodingRelease)(void *);
PROLOG_STATE m_prologState;
Processor *m_processor;
enum XML_Error m_errorCode;
const char *m_eventPtr;
const char *m_eventEndPtr;
const char *m_positionPtr;
OPEN_INTERNAL_ENTITY *m_openInternalEntities;
OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
XML_Bool m_defaultExpandInternalEntities;
int m_tagLevel;
ENTITY *m_declEntity;
const XML_Char *m_doctypeName;
const XML_Char *m_doctypeSysid;
const XML_Char *m_doctypePubid;
const XML_Char *m_declAttributeType;
const XML_Char *m_declNotationName;
const XML_Char *m_declNotationPublicId;
ELEMENT_TYPE *m_declElementType;
ATTRIBUTE_ID *m_declAttributeId;
XML_Bool m_declAttributeIsCdata;
XML_Bool m_declAttributeIsId;
DTD *m_dtd;
const XML_Char *m_curBase;
TAG *m_tagStack;
TAG *m_freeTagList;
BINDING *m_inheritedBindings;
BINDING *m_freeBindingList;
int m_attsSize;
int m_nSpecifiedAtts;
int m_idAttIndex;
ATTRIBUTE *m_atts;
NS_ATT *m_nsAtts;
unsigned long m_nsAttsVersion;
unsigned char m_nsAttsPower;
POSITION m_position;
STRING_POOL m_tempPool;
STRING_POOL m_temp2Pool;
char *m_groupConnector;
unsigned int m_groupSize;
XML_Char m_namespaceSeparator;
XML_Parser m_parentParser;
XML_ParsingStatus m_parsingStatus;
#ifdef XML_DTD
XML_Bool m_isParamEntity;
XML_Bool m_useForeignDTD;
enum XML_ParamEntityParsing m_paramEntityParsing;
#endif
};
#define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
#define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
#define FREE(p) (parser->m_mem.free_fcn((p)))
#define userData (parser->m_userData)
#define handlerArg (parser->m_handlerArg)
#define startElementHandler (parser->m_startElementHandler)
#define endElementHandler (parser->m_endElementHandler)
#define characterDataHandler (parser->m_characterDataHandler)
#define processingInstructionHandler \
(parser->m_processingInstructionHandler)
#define commentHandler (parser->m_commentHandler)
#define startCdataSectionHandler \
(parser->m_startCdataSectionHandler)
#define endCdataSectionHandler (parser->m_endCdataSectionHandler)
#define defaultHandler (parser->m_defaultHandler)
#define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
#define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
#define unparsedEntityDeclHandler \
(parser->m_unparsedEntityDeclHandler)
#define notationDeclHandler (parser->m_notationDeclHandler)
#define startNamespaceDeclHandler \
(parser->m_startNamespaceDeclHandler)
#define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
#define notStandaloneHandler (parser->m_notStandaloneHandler)
#define externalEntityRefHandler \
(parser->m_externalEntityRefHandler)
#define externalEntityRefHandlerArg \
(parser->m_externalEntityRefHandlerArg)
#define internalEntityRefHandler \
(parser->m_internalEntityRefHandler)
#define skippedEntityHandler (parser->m_skippedEntityHandler)
#define unknownEncodingHandler (parser->m_unknownEncodingHandler)
#define elementDeclHandler (parser->m_elementDeclHandler)
#define attlistDeclHandler (parser->m_attlistDeclHandler)
#define entityDeclHandler (parser->m_entityDeclHandler)
#define xmlDeclHandler (parser->m_xmlDeclHandler)
#define encoding (parser->m_encoding)
#define initEncoding (parser->m_initEncoding)
#define internalEncoding (parser->m_internalEncoding)
#define unknownEncodingMem (parser->m_unknownEncodingMem)
#define unknownEncodingData (parser->m_unknownEncodingData)
#define unknownEncodingHandlerData \
(parser->m_unknownEncodingHandlerData)
#define unknownEncodingRelease (parser->m_unknownEncodingRelease)
#define protocolEncodingName (parser->m_protocolEncodingName)
#define ns (parser->m_ns)
#define ns_triplets (parser->m_ns_triplets)
#define prologState (parser->m_prologState)
#define processor (parser->m_processor)
#define errorCode (parser->m_errorCode)
#define eventPtr (parser->m_eventPtr)
#define eventEndPtr (parser->m_eventEndPtr)
#define positionPtr (parser->m_positionPtr)
#define position (parser->m_position)
#define openInternalEntities (parser->m_openInternalEntities)
#define freeInternalEntities (parser->m_freeInternalEntities)
#define defaultExpandInternalEntities \
(parser->m_defaultExpandInternalEntities)
#define tagLevel (parser->m_tagLevel)
#define buffer (parser->m_buffer)
#define bufferPtr (parser->m_bufferPtr)
#define bufferEnd (parser->m_bufferEnd)
#define parseEndByteIndex (parser->m_parseEndByteIndex)
#define parseEndPtr (parser->m_parseEndPtr)
#define bufferLim (parser->m_bufferLim)
#define dataBuf (parser->m_dataBuf)
#define dataBufEnd (parser->m_dataBufEnd)
#define _dtd (parser->m_dtd)
#define curBase (parser->m_curBase)
#define declEntity (parser->m_declEntity)
#define doctypeName (parser->m_doctypeName)
#define doctypeSysid (parser->m_doctypeSysid)
#define doctypePubid (parser->m_doctypePubid)
#define declAttributeType (parser->m_declAttributeType)
#define declNotationName (parser->m_declNotationName)
#define declNotationPublicId (parser->m_declNotationPublicId)
#define declElementType (parser->m_declElementType)
#define declAttributeId (parser->m_declAttributeId)
#define declAttributeIsCdata (parser->m_declAttributeIsCdata)
#define declAttributeIsId (parser->m_declAttributeIsId)
#define freeTagList (parser->m_freeTagList)
#define freeBindingList (parser->m_freeBindingList)
#define inheritedBindings (parser->m_inheritedBindings)
#define tagStack (parser->m_tagStack)
#define atts (parser->m_atts)
#define attsSize (parser->m_attsSize)
#define nSpecifiedAtts (parser->m_nSpecifiedAtts)
#define idAttIndex (parser->m_idAttIndex)
#define nsAtts (parser->m_nsAtts)
#define nsAttsVersion (parser->m_nsAttsVersion)
#define nsAttsPower (parser->m_nsAttsPower)
#define tempPool (parser->m_tempPool)
#define temp2Pool (parser->m_temp2Pool)
#define groupConnector (parser->m_groupConnector)
#define groupSize (parser->m_groupSize)
#define namespaceSeparator (parser->m_namespaceSeparator)
#define parentParser (parser->m_parentParser)
#define parsing (parser->m_parsingStatus.parsing)
#define finalBuffer (parser->m_parsingStatus.finalBuffer)
#ifdef XML_DTD
#define isParamEntity (parser->m_isParamEntity)
#define useForeignDTD (parser->m_useForeignDTD)
#define paramEntityParsing (parser->m_paramEntityParsing)
#endif /* XML_DTD */
XML_Parser XMLCALL
XML_ParserCreate(const XML_Char *encodingName)
{
return XML_ParserCreate_MM(encodingName, NULL, NULL);
}
XML_Parser XMLCALL
XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
{
XML_Char tmp[2];
*tmp = nsSep;
return XML_ParserCreate_MM(encodingName, NULL, tmp);
}
static const XML_Char implicitContext[] = {
'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/',
'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
};
XML_Parser XMLCALL
XML_ParserCreate_MM(const XML_Char *encodingName,
const XML_Memory_Handling_Suite *memsuite,
const XML_Char *nameSep)
{
XML_Parser parser = parserCreate(encodingName, memsuite, nameSep, NULL);
if (parser != NULL && ns) {
/* implicit context only set for root parser, since child
parsers (i.e. external entity parsers) will inherit it
*/
if (!setContext(parser, implicitContext)) {
XML_ParserFree(parser);
return NULL;
}
}
return parser;
}
static XML_Parser
parserCreate(const XML_Char *encodingName,
const XML_Memory_Handling_Suite *memsuite,
const XML_Char *nameSep,
DTD *dtd)
{
XML_Parser parser;
if (memsuite) {
XML_Memory_Handling_Suite *mtemp;
parser = (XML_Parser)
memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
if (parser != NULL) {
mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
mtemp->malloc_fcn = memsuite->malloc_fcn;
mtemp->realloc_fcn = memsuite->realloc_fcn;
mtemp->free_fcn = memsuite->free_fcn;
}
}
else {
XML_Memory_Handling_Suite *mtemp;
parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
if (parser != NULL) {
mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
mtemp->malloc_fcn = malloc;
mtemp->realloc_fcn = realloc;
mtemp->free_fcn = free;
}
}
if (!parser)
return parser;
buffer = NULL;
bufferLim = NULL;
attsSize = INIT_ATTS_SIZE;
atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));
if (atts == NULL) {
FREE(parser);
return NULL;
}
dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
if (dataBuf == NULL) {
FREE(atts);
FREE(parser);
return NULL;
}
dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
if (dtd)
_dtd = dtd;
else {
_dtd = dtdCreate(&parser->m_mem);
if (_dtd == NULL) {
FREE(dataBuf);
FREE(atts);
FREE(parser);
return NULL;
}
}
freeBindingList = NULL;
freeTagList = NULL;
freeInternalEntities = NULL;
groupSize = 0;
groupConnector = NULL;
unknownEncodingHandler = NULL;
unknownEncodingHandlerData = NULL;
namespaceSeparator = '!';
ns = XML_FALSE;
ns_triplets = XML_FALSE;
nsAtts = NULL;
nsAttsVersion = 0;
nsAttsPower = 0;
poolInit(&tempPool, &(parser->m_mem));
poolInit(&temp2Pool, &(parser->m_mem));
parserInit(parser, encodingName);
if (encodingName && !protocolEncodingName) {
XML_ParserFree(parser);
return NULL;
}
if (nameSep) {
ns = XML_TRUE;
internalEncoding = XmlGetInternalEncodingNS();
namespaceSeparator = *nameSep;
}
else {
internalEncoding = XmlGetInternalEncoding();
}
return parser;
}
static void
parserInit(XML_Parser parser, const XML_Char *encodingName)
{
processor = prologInitProcessor;
XmlPrologStateInit(&prologState);
protocolEncodingName = (encodingName != NULL
? poolCopyString(&tempPool, encodingName)
: NULL);
curBase = NULL;
XmlInitEncoding(&initEncoding, &encoding, 0);
userData = NULL;
handlerArg = NULL;
startElementHandler = NULL;
endElementHandler = NULL;
characterDataHandler = NULL;
processingInstructionHandler = NULL;
commentHandler = NULL;
startCdataSectionHandler = NULL;
endCdataSectionHandler = NULL;
defaultHandler = NULL;
startDoctypeDeclHandler = NULL;
endDoctypeDeclHandler = NULL;
unparsedEntityDeclHandler = NULL;
notationDeclHandler = NULL;
startNamespaceDeclHandler = NULL;
endNamespaceDeclHandler = NULL;
notStandaloneHandler = NULL;
externalEntityRefHandler = NULL;
externalEntityRefHandlerArg = parser;
skippedEntityHandler = NULL;
elementDeclHandler = NULL;
attlistDeclHandler = NULL;
entityDeclHandler = NULL;
xmlDeclHandler = NULL;
bufferPtr = buffer;
bufferEnd = buffer;
parseEndByteIndex = 0;
parseEndPtr = NULL;
declElementType = NULL;
declAttributeId = NULL;
declEntity = NULL;
doctypeName = NULL;
doctypeSysid = NULL;
doctypePubid = NULL;
declAttributeType = NULL;
declNotationName = NULL;
declNotationPublicId = NULL;
declAttributeIsCdata = XML_FALSE;
declAttributeIsId = XML_FALSE;
memset(&position, 0, sizeof(POSITION));
errorCode = XML_ERROR_NONE;
eventPtr = NULL;
eventEndPtr = NULL;
positionPtr = NULL;
openInternalEntities = NULL;
defaultExpandInternalEntities = XML_TRUE;
tagLevel = 0;
tagStack = NULL;
inheritedBindings = NULL;
nSpecifiedAtts = 0;
unknownEncodingMem = NULL;
unknownEncodingRelease = NULL;
unknownEncodingData = NULL;
parentParser = NULL;
parsing = XML_INITIALIZED;
#ifdef XML_DTD
isParamEntity = XML_FALSE;
useForeignDTD = XML_FALSE;
paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
#endif
}
/* moves list of bindings to freeBindingList */
static void FASTCALL
moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
{
while (bindings) {
BINDING *b = bindings;
bindings = bindings->nextTagBinding;
b->nextTagBinding = freeBindingList;
freeBindingList = b;
}
}
XML_Bool XMLCALL
XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
{
TAG *tStk;
OPEN_INTERNAL_ENTITY *openEntityList;
if (parentParser)
return XML_FALSE;
/* move tagStack to freeTagList */
tStk = tagStack;
while (tStk) {
TAG *tag = tStk;
tStk = tStk->parent;
tag->parent = freeTagList;
moveToFreeBindingList(parser, tag->bindings);
tag->bindings = NULL;
freeTagList = tag;
}
/* move openInternalEntities to freeInternalEntities */
openEntityList = openInternalEntities;
while (openEntityList) {
OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
openEntityList = openEntity->next;
openEntity->next = freeInternalEntities;
freeInternalEntities = openEntity;
}
moveToFreeBindingList(parser, inheritedBindings);
FREE(unknownEncodingMem);
if (unknownEncodingRelease)
unknownEncodingRelease(unknownEncodingData);
poolClear(&tempPool);
poolClear(&temp2Pool);
parserInit(parser, encodingName);
dtdReset(_dtd, &parser->m_mem);
return setContext(parser, implicitContext);
}
enum XML_Status XMLCALL
XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
{
/* Block after XML_Parse()/XML_ParseBuffer() has been called.
XXX There's no way for the caller to determine which of the
XXX possible error cases caused the XML_STATUS_ERROR return.
*/
if (parsing == XML_PARSING || parsing == XML_SUSPENDED)
return XML_STATUS_ERROR;
if (encodingName == NULL)
protocolEncodingName = NULL;
else {
protocolEncodingName = poolCopyString(&tempPool, encodingName);
if (!protocolEncodingName)
return XML_STATUS_ERROR;
}
return XML_STATUS_OK;
}
XML_Parser XMLCALL
XML_ExternalEntityParserCreate(XML_Parser oldParser,
const XML_Char *context,
const XML_Char *encodingName)
{
XML_Parser parser = oldParser;
DTD *newDtd = NULL;
DTD *oldDtd = _dtd;
XML_StartElementHandler oldStartElementHandler = startElementHandler;
XML_EndElementHandler oldEndElementHandler = endElementHandler;
XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
XML_ProcessingInstructionHandler oldProcessingInstructionHandler
= processingInstructionHandler;
XML_CommentHandler oldCommentHandler = commentHandler;
XML_StartCdataSectionHandler oldStartCdataSectionHandler
= startCdataSectionHandler;
XML_EndCdataSectionHandler oldEndCdataSectionHandler
= endCdataSectionHandler;
XML_DefaultHandler oldDefaultHandler = defaultHandler;
XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
= unparsedEntityDeclHandler;
XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
= startNamespaceDeclHandler;
XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
= endNamespaceDeclHandler;
XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
XML_ExternalEntityRefHandler oldExternalEntityRefHandler
= externalEntityRefHandler;
XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
XML_UnknownEncodingHandler oldUnknownEncodingHandler
= unknownEncodingHandler;
XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
ELEMENT_TYPE * oldDeclElementType = declElementType;
void *oldUserData = userData;
void *oldHandlerArg = handlerArg;
XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
#ifdef XML_DTD
enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
int oldInEntityValue = prologState.inEntityValue;
#endif
XML_Bool oldns_triplets = ns_triplets;
#ifdef XML_DTD
if (!context)
newDtd = oldDtd;
#endif /* XML_DTD */
/* Note that the magical uses of the pre-processor to make field
access look more like C++ require that `parser' be overwritten
here. This makes this function more painful to follow than it
would be otherwise.
*/
if (ns) {
XML_Char tmp[2];
*tmp = namespaceSeparator;
parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
}
else {
parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
}
if (!parser)
return NULL;
startElementHandler = oldStartElementHandler;