blob: dfc316ca36cc8e0a00325a6ec149fe1ff2d0b91f [file] [log] [blame]
Haibo Huangd1a324a2020-10-28 22:19:36 -07001/* 5cd169f2942b85c05e0b1b96f9990f91ac3d07e470ad7ce906ac8590c8ed4f35 (2.2.10+)
Elliott Hughes72472942018-01-10 08:36:10 -08002 __ __ _
3 ___\ \/ /_ __ __ _| |_
4 / _ \\ /| '_ \ / _` | __|
5 | __// \| |_) | (_| | |_
6 \___/_/\_\ .__/ \__,_|\__|
7 |_| XML parser
8
9 Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
10 Copyright (c) 2000-2017 Expat development team
11 Licensed under the MIT license:
12
13 Permission is hereby granted, free of charge, to any person obtaining
14 a copy of this software and associated documentation files (the
15 "Software"), to deal in the Software without restriction, including
16 without limitation the rights to use, copy, modify, merge, publish,
17 distribute, sublicense, and/or sell copies of the Software, and to permit
18 persons to whom the Software is furnished to do so, subject to the
19 following conditions:
20
21 The above copyright notice and this permission notice shall be included
22 in all copies or substantial portions of the Software.
23
24 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
27 NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
28 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
29 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
30 USE OR OTHER DEALINGS IN THE SOFTWARE.
The Android Open Source Projectb80e2872009-03-03 19:29:30 -080031*/
32
Haibo Huang40a71912019-10-11 11:13:39 -070033#if ! defined(_GNU_SOURCE)
34# define _GNU_SOURCE 1 /* syscall prototype */
35#endif
36
37#ifdef _WIN32
38/* force stdlib to define rand_s() */
39# if ! defined(_CRT_RAND_S)
40# define _CRT_RAND_S
41# endif
Elliott Hughes72472942018-01-10 08:36:10 -080042#endif
43
The Android Open Source Projectb80e2872009-03-03 19:29:30 -080044#include <stddef.h>
Haibo Huang40a71912019-10-11 11:13:39 -070045#include <string.h> /* memset(), memcpy() */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -080046#include <assert.h>
Haibo Huang40a71912019-10-11 11:13:39 -070047#include <limits.h> /* UINT_MAX */
48#include <stdio.h> /* fprintf */
49#include <stdlib.h> /* getenv, rand_s */
Paul Duffin3c2f09e2016-06-07 15:53:38 +010050
Haibo Huangd1a324a2020-10-28 22:19:36 -070051#if defined(_WIN32) && defined(_MSC_VER) && (_MSC_VER < 1600)
52/* vs2008/9.0 and earlier lack stdint.h; _MSC_VER 1600 is vs2010/10.0 */
53# if defined(_WIN64)
54typedef unsigned __int64 uintptr_t;
55# else
56typedef unsigned __int32 uintptr_t;
57# endif
58#else
59# include <stdint.h> /* uintptr_t */
60#endif
61
Elliott Hughes72472942018-01-10 08:36:10 -080062#ifdef _WIN32
Haibo Huang40a71912019-10-11 11:13:39 -070063# define getpid GetCurrentProcessId
Paul Duffin3c2f09e2016-06-07 15:53:38 +010064#else
Haibo Huang40a71912019-10-11 11:13:39 -070065# include <sys/time.h> /* gettimeofday() */
66# include <sys/types.h> /* getpid() */
67# include <unistd.h> /* getpid() */
68# include <fcntl.h> /* O_RDONLY */
69# include <errno.h>
Paul Duffin3c2f09e2016-06-07 15:53:38 +010070#endif
The Android Open Source Projectb80e2872009-03-03 19:29:30 -080071
72#define XML_BUILDING_EXPAT 1
73
Elliott Hughes72472942018-01-10 08:36:10 -080074#ifdef _WIN32
Haibo Huang40a71912019-10-11 11:13:39 -070075# include "winconfig.h"
The Android Open Source Projectb80e2872009-03-03 19:29:30 -080076#elif defined(HAVE_EXPAT_CONFIG_H)
Haibo Huang40a71912019-10-11 11:13:39 -070077# include <expat_config.h>
Elliott Hughes72472942018-01-10 08:36:10 -080078#endif /* ndef _WIN32 */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -080079
Elliott Hughesd07d5a72009-09-25 16:04:37 -070080#include "ascii.h"
The Android Open Source Projectb80e2872009-03-03 19:29:30 -080081#include "expat.h"
Elliott Hughes72472942018-01-10 08:36:10 -080082#include "siphash.h"
83
84#if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
Haibo Huang40a71912019-10-11 11:13:39 -070085# if defined(HAVE_GETRANDOM)
86# include <sys/random.h> /* getrandom */
87# else
88# include <unistd.h> /* syscall */
89# include <sys/syscall.h> /* SYS_getrandom */
90# endif
91# if ! defined(GRND_NONBLOCK)
92# define GRND_NONBLOCK 0x0001
93# endif /* defined(GRND_NONBLOCK) */
94#endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */
Elliott Hughes72472942018-01-10 08:36:10 -080095
Haibo Huang40a71912019-10-11 11:13:39 -070096#if defined(HAVE_LIBBSD) \
Elliott Hughes72472942018-01-10 08:36:10 -080097 && (defined(HAVE_ARC4RANDOM_BUF) || defined(HAVE_ARC4RANDOM))
Haibo Huang40a71912019-10-11 11:13:39 -070098# include <bsd/stdlib.h>
Elliott Hughes72472942018-01-10 08:36:10 -080099#endif
100
Haibo Huang40a71912019-10-11 11:13:39 -0700101#if defined(_WIN32) && ! defined(LOAD_LIBRARY_SEARCH_SYSTEM32)
102# define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800
Elliott Hughes72472942018-01-10 08:36:10 -0800103#endif
104
Haibo Huang40a71912019-10-11 11:13:39 -0700105#if ! defined(HAVE_GETRANDOM) && ! defined(HAVE_SYSCALL_GETRANDOM) \
106 && ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) \
107 && ! defined(XML_DEV_URANDOM) && ! defined(_WIN32) \
108 && ! defined(XML_POOR_ENTROPY)
109# error You do not have support for any sources of high quality entropy \
Elliott Hughes72472942018-01-10 08:36:10 -0800110 enabled. For end user security, that is probably not what you want. \
111 \
112 Your options include: \
Haibo Huangd1a324a2020-10-28 22:19:36 -0700113 * Linux >=3.17 + glibc >=2.25 (getrandom): HAVE_GETRANDOM, \
114 * Linux >=3.17 + glibc (including <2.25) (syscall SYS_getrandom): HAVE_SYSCALL_GETRANDOM, \
Elliott Hughes72472942018-01-10 08:36:10 -0800115 * BSD / macOS >=10.7 (arc4random_buf): HAVE_ARC4RANDOM_BUF, \
Haibo Huangd1a324a2020-10-28 22:19:36 -0700116 * BSD / macOS (including <10.7) (arc4random): HAVE_ARC4RANDOM, \
Elliott Hughes72472942018-01-10 08:36:10 -0800117 * libbsd (arc4random_buf): HAVE_ARC4RANDOM_BUF + HAVE_LIBBSD, \
118 * libbsd (arc4random): HAVE_ARC4RANDOM + HAVE_LIBBSD, \
Haibo Huangd1a324a2020-10-28 22:19:36 -0700119 * Linux (including <3.17) / BSD / macOS (including <10.7) (/dev/urandom): XML_DEV_URANDOM, \
120 * Windows >=Vista (rand_s): _WIN32. \
Elliott Hughes72472942018-01-10 08:36:10 -0800121 \
122 If insist on not using any of these, bypass this error by defining \
123 XML_POOR_ENTROPY; you have been warned. \
124 \
125 If you have reasons to patch this detection code away or need changes \
126 to the build system, please open a bug. Thank you!
127#endif
128
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800129#ifdef XML_UNICODE
Haibo Huang40a71912019-10-11 11:13:39 -0700130# define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
131# define XmlConvert XmlUtf16Convert
132# define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
133# define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
134# define XmlEncode XmlUtf16Encode
Haibo Huangd1a324a2020-10-28 22:19:36 -0700135# define MUST_CONVERT(enc, s) (! (enc)->isUtf16 || (((uintptr_t)(s)) & 1))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800136typedef unsigned short ICHAR;
137#else
Haibo Huang40a71912019-10-11 11:13:39 -0700138# define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
139# define XmlConvert XmlUtf8Convert
140# define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
141# define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
142# define XmlEncode XmlUtf8Encode
143# define MUST_CONVERT(enc, s) (! (enc)->isUtf8)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800144typedef char ICHAR;
145#endif
146
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800147#ifndef XML_NS
148
Haibo Huang40a71912019-10-11 11:13:39 -0700149# define XmlInitEncodingNS XmlInitEncoding
150# define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
151# undef XmlGetInternalEncodingNS
152# define XmlGetInternalEncodingNS XmlGetInternalEncoding
153# define XmlParseXmlDeclNS XmlParseXmlDecl
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800154
155#endif
156
157#ifdef XML_UNICODE
158
Haibo Huang40a71912019-10-11 11:13:39 -0700159# ifdef XML_UNICODE_WCHAR_T
160# define XML_T(x) (const wchar_t) x
161# define XML_L(x) L##x
162# else
163# define XML_T(x) (const unsigned short)x
164# define XML_L(x) x
165# endif
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800166
167#else
168
Haibo Huang40a71912019-10-11 11:13:39 -0700169# define XML_T(x) x
170# define XML_L(x) x
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800171
172#endif
173
174/* Round up n to be a multiple of sz, where sz is a power of 2. */
Haibo Huang40a71912019-10-11 11:13:39 -0700175#define ROUND_UP(n, sz) (((n) + ((sz)-1)) & ~((sz)-1))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800176
Elliott Hughesaaec48e2018-08-16 16:29:01 -0700177/* Do safe (NULL-aware) pointer arithmetic */
178#define EXPAT_SAFE_PTR_DIFF(p, q) (((p) && (q)) ? ((p) - (q)) : 0)
179
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800180#include "internal.h"
181#include "xmltok.h"
182#include "xmlrole.h"
183
184typedef const XML_Char *KEY;
185
186typedef struct {
187 KEY name;
188} NAMED;
189
190typedef struct {
191 NAMED **v;
192 unsigned char power;
193 size_t size;
194 size_t used;
195 const XML_Memory_Handling_Suite *mem;
196} HASH_TABLE;
197
Haibo Huang40a71912019-10-11 11:13:39 -0700198static size_t keylen(KEY s);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800199
Haibo Huang40a71912019-10-11 11:13:39 -0700200static void copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800201
202/* For probing (after a collision) we need a step size relative prime
203 to the hash table size, which is a power of 2. We use double-hashing,
204 since we can calculate a second hash value cheaply by taking those bits
205 of the first hash value that were discarded (masked out) when the table
206 index was calculated: index = hash & mask, where mask = table->size - 1.
207 We limit the maximum step size to table->size / 4 (mask >> 2) and make
208 it odd, since odd numbers are always relative prime to a power of 2.
209*/
Haibo Huang40a71912019-10-11 11:13:39 -0700210#define SECOND_HASH(hash, mask, power) \
211 ((((hash) & ~(mask)) >> ((power)-1)) & ((mask) >> 2))
212#define PROBE_STEP(hash, mask, power) \
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800213 ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
214
215typedef struct {
216 NAMED **p;
217 NAMED **end;
218} HASH_TABLE_ITER;
219
Haibo Huang40a71912019-10-11 11:13:39 -0700220#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800221#define INIT_DATA_BUF_SIZE 1024
222#define INIT_ATTS_SIZE 16
223#define INIT_ATTS_VERSION 0xFFFFFFFF
224#define INIT_BLOCK_SIZE 1024
225#define INIT_BUFFER_SIZE 1024
226
227#define EXPAND_SPARE 24
228
229typedef struct binding {
230 struct prefix *prefix;
231 struct binding *nextTagBinding;
232 struct binding *prevPrefixBinding;
233 const struct attribute_id *attId;
234 XML_Char *uri;
235 int uriLen;
236 int uriAlloc;
237} BINDING;
238
239typedef struct prefix {
240 const XML_Char *name;
241 BINDING *binding;
242} PREFIX;
243
244typedef struct {
245 const XML_Char *str;
246 const XML_Char *localPart;
247 const XML_Char *prefix;
248 int strLen;
249 int uriLen;
250 int prefixLen;
251} TAG_NAME;
252
253/* TAG represents an open element.
254 The name of the element is stored in both the document and API
255 encodings. The memory buffer 'buf' is a separately-allocated
256 memory area which stores the name. During the XML_Parse()/
257 XMLParseBuffer() when the element is open, the memory for the 'raw'
258 version of the name (in the document encoding) is shared with the
259 document buffer. If the element is open across calls to
260 XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
261 contain the 'raw' name as well.
262
263 A parser re-uses these structures, maintaining a list of allocated
264 TAG objects in a free list.
265*/
266typedef struct tag {
Haibo Huang40a71912019-10-11 11:13:39 -0700267 struct tag *parent; /* parent of this element */
268 const char *rawName; /* tagName in the original encoding */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800269 int rawNameLength;
Haibo Huang40a71912019-10-11 11:13:39 -0700270 TAG_NAME name; /* tagName in the API encoding */
271 char *buf; /* buffer for name components */
272 char *bufEnd; /* end of the buffer */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800273 BINDING *bindings;
274} TAG;
275
276typedef struct {
277 const XML_Char *name;
278 const XML_Char *textPtr;
Haibo Huang40a71912019-10-11 11:13:39 -0700279 int textLen; /* length in XML_Chars */
280 int processed; /* # of processed bytes - when suspended */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800281 const XML_Char *systemId;
282 const XML_Char *base;
283 const XML_Char *publicId;
284 const XML_Char *notation;
285 XML_Bool open;
286 XML_Bool is_param;
287 XML_Bool is_internal; /* true if declared in internal subset outside PE */
288} ENTITY;
289
290typedef struct {
Haibo Huang40a71912019-10-11 11:13:39 -0700291 enum XML_Content_Type type;
292 enum XML_Content_Quant quant;
293 const XML_Char *name;
294 int firstchild;
295 int lastchild;
296 int childcnt;
297 int nextsib;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800298} CONTENT_SCAFFOLD;
299
300#define INIT_SCAFFOLD_ELEMENTS 32
301
302typedef struct block {
303 struct block *next;
304 int size;
305 XML_Char s[1];
306} BLOCK;
307
308typedef struct {
309 BLOCK *blocks;
310 BLOCK *freeBlocks;
311 const XML_Char *end;
312 XML_Char *ptr;
313 XML_Char *start;
314 const XML_Memory_Handling_Suite *mem;
315} STRING_POOL;
316
317/* The XML_Char before the name is used to determine whether
318 an attribute has been specified. */
319typedef struct attribute_id {
320 XML_Char *name;
321 PREFIX *prefix;
322 XML_Bool maybeTokenized;
323 XML_Bool xmlns;
324} ATTRIBUTE_ID;
325
326typedef struct {
327 const ATTRIBUTE_ID *id;
328 XML_Bool isCdata;
329 const XML_Char *value;
330} DEFAULT_ATTRIBUTE;
331
332typedef struct {
333 unsigned long version;
334 unsigned long hash;
335 const XML_Char *uriName;
336} NS_ATT;
337
338typedef struct {
339 const XML_Char *name;
340 PREFIX *prefix;
341 const ATTRIBUTE_ID *idAtt;
342 int nDefaultAtts;
343 int allocDefaultAtts;
344 DEFAULT_ATTRIBUTE *defaultAtts;
345} ELEMENT_TYPE;
346
347typedef struct {
348 HASH_TABLE generalEntities;
349 HASH_TABLE elementTypes;
350 HASH_TABLE attributeIds;
351 HASH_TABLE prefixes;
352 STRING_POOL pool;
353 STRING_POOL entityValuePool;
354 /* false once a parameter entity reference has been skipped */
355 XML_Bool keepProcessing;
356 /* true once an internal or external PE reference has been encountered;
357 this includes the reference to an external subset */
358 XML_Bool hasParamEntityRefs;
359 XML_Bool standalone;
360#ifdef XML_DTD
361 /* indicates if external PE has been read */
362 XML_Bool paramEntityRead;
363 HASH_TABLE paramEntities;
364#endif /* XML_DTD */
365 PREFIX defaultPrefix;
366 /* === scaffolding for building content model === */
367 XML_Bool in_eldecl;
368 CONTENT_SCAFFOLD *scaffold;
369 unsigned contentStringLen;
370 unsigned scaffSize;
371 unsigned scaffCount;
372 int scaffLevel;
373 int *scaffIndex;
374} DTD;
375
376typedef struct open_internal_entity {
377 const char *internalEventPtr;
378 const char *internalEventEndPtr;
379 struct open_internal_entity *next;
380 ENTITY *entity;
381 int startTagLevel;
382 XML_Bool betweenDecl; /* WFC: PE Between Declarations */
383} OPEN_INTERNAL_ENTITY;
384
Haibo Huang40a71912019-10-11 11:13:39 -0700385typedef enum XML_Error PTRCALL Processor(XML_Parser parser, const char *start,
386 const char *end, const char **endPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800387
388static Processor prologProcessor;
389static Processor prologInitProcessor;
390static Processor contentProcessor;
391static Processor cdataSectionProcessor;
392#ifdef XML_DTD
393static Processor ignoreSectionProcessor;
394static Processor externalParEntProcessor;
395static Processor externalParEntInitProcessor;
396static Processor entityValueProcessor;
397static Processor entityValueInitProcessor;
398#endif /* XML_DTD */
399static Processor epilogProcessor;
400static Processor errorProcessor;
401static Processor externalEntityInitProcessor;
402static Processor externalEntityInitProcessor2;
403static Processor externalEntityInitProcessor3;
404static Processor externalEntityContentProcessor;
405static Processor internalEntityProcessor;
406
Haibo Huang40a71912019-10-11 11:13:39 -0700407static enum XML_Error handleUnknownEncoding(XML_Parser parser,
408 const XML_Char *encodingName);
409static enum XML_Error processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
410 const char *s, const char *next);
411static enum XML_Error initializeEncoding(XML_Parser parser);
412static enum XML_Error doProlog(XML_Parser parser, const ENCODING *enc,
413 const char *s, const char *end, int tok,
414 const char *next, const char **nextPtr,
415 XML_Bool haveMore, XML_Bool allowClosingDoctype);
416static enum XML_Error processInternalEntity(XML_Parser parser, ENTITY *entity,
417 XML_Bool betweenDecl);
418static enum XML_Error doContent(XML_Parser parser, int startTagLevel,
419 const ENCODING *enc, const char *start,
420 const char *end, const char **endPtr,
421 XML_Bool haveMore);
422static enum XML_Error doCdataSection(XML_Parser parser, const ENCODING *,
423 const char **startPtr, const char *end,
424 const char **nextPtr, XML_Bool haveMore);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800425#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -0700426static enum XML_Error doIgnoreSection(XML_Parser parser, const ENCODING *,
427 const char **startPtr, const char *end,
428 const char **nextPtr, XML_Bool haveMore);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800429#endif /* XML_DTD */
430
Haibo Huang40a71912019-10-11 11:13:39 -0700431static void freeBindings(XML_Parser parser, BINDING *bindings);
432static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *,
433 const char *s, TAG_NAME *tagNamePtr,
434 BINDING **bindingsPtr);
435static enum XML_Error addBinding(XML_Parser parser, PREFIX *prefix,
436 const ATTRIBUTE_ID *attId, const XML_Char *uri,
437 BINDING **bindingsPtr);
438static int defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
439 XML_Bool isId, const XML_Char *dfltValue,
440 XML_Parser parser);
441static enum XML_Error storeAttributeValue(XML_Parser parser, const ENCODING *,
442 XML_Bool isCdata, const char *,
443 const char *, STRING_POOL *);
444static enum XML_Error appendAttributeValue(XML_Parser parser, const ENCODING *,
445 XML_Bool isCdata, const char *,
446 const char *, STRING_POOL *);
447static ATTRIBUTE_ID *getAttributeId(XML_Parser parser, const ENCODING *enc,
448 const char *start, const char *end);
449static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
450static enum XML_Error storeEntityValue(XML_Parser parser, const ENCODING *enc,
451 const char *start, const char *end);
452static int reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
453 const char *start, const char *end);
454static int reportComment(XML_Parser parser, const ENCODING *enc,
455 const char *start, const char *end);
456static void reportDefault(XML_Parser parser, const ENCODING *enc,
457 const char *start, const char *end);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800458
Haibo Huang40a71912019-10-11 11:13:39 -0700459static const XML_Char *getContext(XML_Parser parser);
460static XML_Bool setContext(XML_Parser parser, const XML_Char *context);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800461
462static void FASTCALL normalizePublicId(XML_Char *s);
463
Haibo Huang40a71912019-10-11 11:13:39 -0700464static DTD *dtdCreate(const XML_Memory_Handling_Suite *ms);
Elliott Hughes72472942018-01-10 08:36:10 -0800465/* do not call if m_parentParser != NULL */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800466static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
Haibo Huang40a71912019-10-11 11:13:39 -0700467static void dtdDestroy(DTD *p, XML_Bool isDocEntity,
468 const XML_Memory_Handling_Suite *ms);
469static int dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
470 const XML_Memory_Handling_Suite *ms);
471static int copyEntityTable(XML_Parser oldParser, HASH_TABLE *, STRING_POOL *,
472 const HASH_TABLE *);
473static NAMED *lookup(XML_Parser parser, HASH_TABLE *table, KEY name,
474 size_t createSize);
475static void FASTCALL hashTableInit(HASH_TABLE *,
476 const XML_Memory_Handling_Suite *ms);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800477static void FASTCALL hashTableClear(HASH_TABLE *);
478static void FASTCALL hashTableDestroy(HASH_TABLE *);
Haibo Huang40a71912019-10-11 11:13:39 -0700479static void FASTCALL hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
480static NAMED *FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800481
Haibo Huang40a71912019-10-11 11:13:39 -0700482static void FASTCALL poolInit(STRING_POOL *,
483 const XML_Memory_Handling_Suite *ms);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800484static void FASTCALL poolClear(STRING_POOL *);
485static void FASTCALL poolDestroy(STRING_POOL *);
Haibo Huang40a71912019-10-11 11:13:39 -0700486static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
487 const char *ptr, const char *end);
488static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
489 const char *ptr, const char *end);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800490static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
Haibo Huang40a71912019-10-11 11:13:39 -0700491static const XML_Char *FASTCALL poolCopyString(STRING_POOL *pool,
492 const XML_Char *s);
493static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s,
494 int n);
495static const XML_Char *FASTCALL poolAppendString(STRING_POOL *pool,
496 const XML_Char *s);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800497
498static int FASTCALL nextScaffoldPart(XML_Parser parser);
Haibo Huang40a71912019-10-11 11:13:39 -0700499static XML_Content *build_model(XML_Parser parser);
500static ELEMENT_TYPE *getElementType(XML_Parser parser, const ENCODING *enc,
501 const char *ptr, const char *end);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800502
Elliott Hughes72472942018-01-10 08:36:10 -0800503static XML_Char *copyString(const XML_Char *s,
504 const XML_Memory_Handling_Suite *memsuite);
505
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100506static unsigned long generate_hash_secret_salt(XML_Parser parser);
Elliott Hughes35e432d2012-09-09 14:23:38 -0700507static XML_Bool startParsing(XML_Parser parser);
508
Haibo Huang40a71912019-10-11 11:13:39 -0700509static XML_Parser parserCreate(const XML_Char *encodingName,
510 const XML_Memory_Handling_Suite *memsuite,
511 const XML_Char *nameSep, DTD *dtd);
Elliott Hughes35e432d2012-09-09 14:23:38 -0700512
Haibo Huang40a71912019-10-11 11:13:39 -0700513static void parserInit(XML_Parser parser, const XML_Char *encodingName);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800514
515#define poolStart(pool) ((pool)->start)
516#define poolEnd(pool) ((pool)->ptr)
517#define poolLength(pool) ((pool)->ptr - (pool)->start)
518#define poolChop(pool) ((void)--(pool->ptr))
519#define poolLastChar(pool) (((pool)->ptr)[-1])
520#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
521#define poolFinish(pool) ((pool)->start = (pool)->ptr)
Haibo Huang40a71912019-10-11 11:13:39 -0700522#define poolAppendChar(pool, c) \
523 (((pool)->ptr == (pool)->end && ! poolGrow(pool)) \
524 ? 0 \
525 : ((*((pool)->ptr)++ = c), 1))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800526
527struct XML_ParserStruct {
Elliott Hughes72472942018-01-10 08:36:10 -0800528 /* The first member must be m_userData so that the XML_GetUserData
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800529 macro works. */
530 void *m_userData;
531 void *m_handlerArg;
532 char *m_buffer;
533 const XML_Memory_Handling_Suite m_mem;
534 /* first character to be parsed */
535 const char *m_bufferPtr;
536 /* past last character to be parsed */
537 char *m_bufferEnd;
Elliott Hughes72472942018-01-10 08:36:10 -0800538 /* allocated end of m_buffer */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800539 const char *m_bufferLim;
540 XML_Index m_parseEndByteIndex;
541 const char *m_parseEndPtr;
542 XML_Char *m_dataBuf;
543 XML_Char *m_dataBufEnd;
544 XML_StartElementHandler m_startElementHandler;
545 XML_EndElementHandler m_endElementHandler;
546 XML_CharacterDataHandler m_characterDataHandler;
547 XML_ProcessingInstructionHandler m_processingInstructionHandler;
548 XML_CommentHandler m_commentHandler;
549 XML_StartCdataSectionHandler m_startCdataSectionHandler;
550 XML_EndCdataSectionHandler m_endCdataSectionHandler;
551 XML_DefaultHandler m_defaultHandler;
552 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
553 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
554 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
555 XML_NotationDeclHandler m_notationDeclHandler;
556 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
557 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
558 XML_NotStandaloneHandler m_notStandaloneHandler;
559 XML_ExternalEntityRefHandler m_externalEntityRefHandler;
560 XML_Parser m_externalEntityRefHandlerArg;
561 XML_SkippedEntityHandler m_skippedEntityHandler;
562 XML_UnknownEncodingHandler m_unknownEncodingHandler;
563 XML_ElementDeclHandler m_elementDeclHandler;
564 XML_AttlistDeclHandler m_attlistDeclHandler;
565 XML_EntityDeclHandler m_entityDeclHandler;
566 XML_XmlDeclHandler m_xmlDeclHandler;
567 const ENCODING *m_encoding;
568 INIT_ENCODING m_initEncoding;
569 const ENCODING *m_internalEncoding;
570 const XML_Char *m_protocolEncodingName;
571 XML_Bool m_ns;
572 XML_Bool m_ns_triplets;
573 void *m_unknownEncodingMem;
574 void *m_unknownEncodingData;
575 void *m_unknownEncodingHandlerData;
Haibo Huang40a71912019-10-11 11:13:39 -0700576 void(XMLCALL *m_unknownEncodingRelease)(void *);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800577 PROLOG_STATE m_prologState;
578 Processor *m_processor;
579 enum XML_Error m_errorCode;
580 const char *m_eventPtr;
581 const char *m_eventEndPtr;
582 const char *m_positionPtr;
583 OPEN_INTERNAL_ENTITY *m_openInternalEntities;
584 OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
585 XML_Bool m_defaultExpandInternalEntities;
586 int m_tagLevel;
587 ENTITY *m_declEntity;
588 const XML_Char *m_doctypeName;
589 const XML_Char *m_doctypeSysid;
590 const XML_Char *m_doctypePubid;
591 const XML_Char *m_declAttributeType;
592 const XML_Char *m_declNotationName;
593 const XML_Char *m_declNotationPublicId;
594 ELEMENT_TYPE *m_declElementType;
595 ATTRIBUTE_ID *m_declAttributeId;
596 XML_Bool m_declAttributeIsCdata;
597 XML_Bool m_declAttributeIsId;
598 DTD *m_dtd;
599 const XML_Char *m_curBase;
600 TAG *m_tagStack;
601 TAG *m_freeTagList;
602 BINDING *m_inheritedBindings;
603 BINDING *m_freeBindingList;
604 int m_attsSize;
605 int m_nSpecifiedAtts;
606 int m_idAttIndex;
607 ATTRIBUTE *m_atts;
608 NS_ATT *m_nsAtts;
609 unsigned long m_nsAttsVersion;
610 unsigned char m_nsAttsPower;
Elliott Hughes35e432d2012-09-09 14:23:38 -0700611#ifdef XML_ATTR_INFO
612 XML_AttrInfo *m_attInfo;
613#endif
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800614 POSITION m_position;
615 STRING_POOL m_tempPool;
616 STRING_POOL m_temp2Pool;
617 char *m_groupConnector;
618 unsigned int m_groupSize;
619 XML_Char m_namespaceSeparator;
620 XML_Parser m_parentParser;
621 XML_ParsingStatus m_parsingStatus;
622#ifdef XML_DTD
623 XML_Bool m_isParamEntity;
624 XML_Bool m_useForeignDTD;
625 enum XML_ParamEntityParsing m_paramEntityParsing;
626#endif
Elliott Hughes35e432d2012-09-09 14:23:38 -0700627 unsigned long m_hash_secret_salt;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800628};
629
Haibo Huang40a71912019-10-11 11:13:39 -0700630#define MALLOC(parser, s) (parser->m_mem.malloc_fcn((s)))
631#define REALLOC(parser, p, s) (parser->m_mem.realloc_fcn((p), (s)))
632#define FREE(parser, p) (parser->m_mem.free_fcn((p)))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800633
634XML_Parser XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -0700635XML_ParserCreate(const XML_Char *encodingName) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800636 return XML_ParserCreate_MM(encodingName, NULL, NULL);
637}
638
639XML_Parser XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -0700640XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800641 XML_Char tmp[2];
642 *tmp = nsSep;
643 return XML_ParserCreate_MM(encodingName, NULL, tmp);
644}
645
Haibo Huang40a71912019-10-11 11:13:39 -0700646static const XML_Char implicitContext[]
647 = {ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h,
648 ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH,
649 ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD,
650 ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r,
651 ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L,
652 ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8,
653 ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e,
654 ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e,
655 '\0'};
Elliott Hughes72472942018-01-10 08:36:10 -0800656
657/* To avoid warnings about unused functions: */
658#if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM)
659
Haibo Huang40a71912019-10-11 11:13:39 -0700660# if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
Elliott Hughes72472942018-01-10 08:36:10 -0800661
662/* Obtain entropy on Linux 3.17+ */
663static int
Haibo Huang40a71912019-10-11 11:13:39 -0700664writeRandomBytes_getrandom_nonblock(void *target, size_t count) {
665 int success = 0; /* full count bytes written? */
Elliott Hughes72472942018-01-10 08:36:10 -0800666 size_t bytesWrittenTotal = 0;
667 const unsigned int getrandomFlags = GRND_NONBLOCK;
668
669 do {
Haibo Huang40a71912019-10-11 11:13:39 -0700670 void *const currentTarget = (void *)((char *)target + bytesWrittenTotal);
Elliott Hughes72472942018-01-10 08:36:10 -0800671 const size_t bytesToWrite = count - bytesWrittenTotal;
672
673 const int bytesWrittenMore =
Haibo Huang40a71912019-10-11 11:13:39 -0700674# if defined(HAVE_GETRANDOM)
Elliott Hughes72472942018-01-10 08:36:10 -0800675 getrandom(currentTarget, bytesToWrite, getrandomFlags);
Haibo Huang40a71912019-10-11 11:13:39 -0700676# else
Elliott Hughes72472942018-01-10 08:36:10 -0800677 syscall(SYS_getrandom, currentTarget, bytesToWrite, getrandomFlags);
Haibo Huang40a71912019-10-11 11:13:39 -0700678# endif
Elliott Hughes72472942018-01-10 08:36:10 -0800679
680 if (bytesWrittenMore > 0) {
681 bytesWrittenTotal += bytesWrittenMore;
682 if (bytesWrittenTotal >= count)
683 success = 1;
684 }
685 } while (! success && (errno == EINTR));
686
687 return success;
688}
689
Haibo Huang40a71912019-10-11 11:13:39 -0700690# endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */
Elliott Hughes72472942018-01-10 08:36:10 -0800691
Haibo Huang40a71912019-10-11 11:13:39 -0700692# if ! defined(_WIN32) && defined(XML_DEV_URANDOM)
Elliott Hughes72472942018-01-10 08:36:10 -0800693
694/* Extract entropy from /dev/urandom */
695static int
Haibo Huang40a71912019-10-11 11:13:39 -0700696writeRandomBytes_dev_urandom(void *target, size_t count) {
697 int success = 0; /* full count bytes written? */
Elliott Hughes72472942018-01-10 08:36:10 -0800698 size_t bytesWrittenTotal = 0;
699
700 const int fd = open("/dev/urandom", O_RDONLY);
701 if (fd < 0) {
702 return 0;
703 }
704
705 do {
Haibo Huang40a71912019-10-11 11:13:39 -0700706 void *const currentTarget = (void *)((char *)target + bytesWrittenTotal);
Elliott Hughes72472942018-01-10 08:36:10 -0800707 const size_t bytesToWrite = count - bytesWrittenTotal;
708
709 const ssize_t bytesWrittenMore = read(fd, currentTarget, bytesToWrite);
710
711 if (bytesWrittenMore > 0) {
712 bytesWrittenTotal += bytesWrittenMore;
713 if (bytesWrittenTotal >= count)
714 success = 1;
715 }
716 } while (! success && (errno == EINTR));
717
718 close(fd);
719 return success;
720}
721
Haibo Huang40a71912019-10-11 11:13:39 -0700722# endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */
Elliott Hughes72472942018-01-10 08:36:10 -0800723
Haibo Huang40a71912019-10-11 11:13:39 -0700724#endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */
Elliott Hughes72472942018-01-10 08:36:10 -0800725
Haibo Huangfd5e81a2019-06-20 12:09:36 -0700726#if defined(HAVE_ARC4RANDOM) && ! defined(HAVE_ARC4RANDOM_BUF)
Elliott Hughes72472942018-01-10 08:36:10 -0800727
728static void
Haibo Huang40a71912019-10-11 11:13:39 -0700729writeRandomBytes_arc4random(void *target, size_t count) {
Elliott Hughes72472942018-01-10 08:36:10 -0800730 size_t bytesWrittenTotal = 0;
731
732 while (bytesWrittenTotal < count) {
733 const uint32_t random32 = arc4random();
734 size_t i = 0;
735
736 for (; (i < sizeof(random32)) && (bytesWrittenTotal < count);
Haibo Huang40a71912019-10-11 11:13:39 -0700737 i++, bytesWrittenTotal++) {
Elliott Hughes72472942018-01-10 08:36:10 -0800738 const uint8_t random8 = (uint8_t)(random32 >> (i * 8));
739 ((uint8_t *)target)[bytesWrittenTotal] = random8;
740 }
741 }
742}
743
Haibo Huang40a71912019-10-11 11:13:39 -0700744#endif /* defined(HAVE_ARC4RANDOM) && ! defined(HAVE_ARC4RANDOM_BUF) */
Elliott Hughes72472942018-01-10 08:36:10 -0800745
746#ifdef _WIN32
747
Haibo Huangd1a324a2020-10-28 22:19:36 -0700748/* Provide declaration of rand_s() for MinGW-32 (not 64, which has it),
749 as it didn't declare it in its header prior to version 5.3.0 of its
750 runtime package (mingwrt, containing stdlib.h). The upstream fix
751 was introduced at https://osdn.net/projects/mingw/ticket/39658 . */
752# if defined(__MINGW32__) && defined(__MINGW32_VERSION) \
753 && __MINGW32_VERSION < 5003000L && ! defined(__MINGW64_VERSION_MAJOR)
754__declspec(dllimport) int rand_s(unsigned int *);
755# endif
756
Haibo Huang40a71912019-10-11 11:13:39 -0700757/* Obtain entropy on Windows using the rand_s() function which
758 * generates cryptographically secure random numbers. Internally it
759 * uses RtlGenRandom API which is present in Windows XP and later.
Elliott Hughes72472942018-01-10 08:36:10 -0800760 */
761static int
Haibo Huang40a71912019-10-11 11:13:39 -0700762writeRandomBytes_rand_s(void *target, size_t count) {
763 size_t bytesWrittenTotal = 0;
Elliott Hughes72472942018-01-10 08:36:10 -0800764
Haibo Huang40a71912019-10-11 11:13:39 -0700765 while (bytesWrittenTotal < count) {
766 unsigned int random32 = 0;
767 size_t i = 0;
768
769 if (rand_s(&random32))
770 return 0; /* failure */
771
772 for (; (i < sizeof(random32)) && (bytesWrittenTotal < count);
773 i++, bytesWrittenTotal++) {
774 const uint8_t random8 = (uint8_t)(random32 >> (i * 8));
775 ((uint8_t *)target)[bytesWrittenTotal] = random8;
Elliott Hughes72472942018-01-10 08:36:10 -0800776 }
Elliott Hughes72472942018-01-10 08:36:10 -0800777 }
Haibo Huang40a71912019-10-11 11:13:39 -0700778 return 1; /* success */
Elliott Hughes72472942018-01-10 08:36:10 -0800779}
780
781#endif /* _WIN32 */
782
Elliott Hughes72472942018-01-10 08:36:10 -0800783#if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM)
784
Elliott Hughes35e432d2012-09-09 14:23:38 -0700785static unsigned long
Haibo Huang40a71912019-10-11 11:13:39 -0700786gather_time_entropy(void) {
787# ifdef _WIN32
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100788 FILETIME ft;
789 GetSystemTimeAsFileTime(&ft); /* never fails */
790 return ft.dwHighDateTime ^ ft.dwLowDateTime;
Haibo Huang40a71912019-10-11 11:13:39 -0700791# else
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100792 struct timeval tv;
793 int gettimeofday_res;
794
795 gettimeofday_res = gettimeofday(&tv, NULL);
Elliott Hughes72472942018-01-10 08:36:10 -0800796
Haibo Huang40a71912019-10-11 11:13:39 -0700797# if defined(NDEBUG)
Elliott Hughes72472942018-01-10 08:36:10 -0800798 (void)gettimeofday_res;
Haibo Huang40a71912019-10-11 11:13:39 -0700799# else
800 assert(gettimeofday_res == 0);
801# endif /* defined(NDEBUG) */
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100802
803 /* Microseconds time is <20 bits entropy */
804 return tv.tv_usec;
Haibo Huang40a71912019-10-11 11:13:39 -0700805# endif
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100806}
807
Haibo Huang40a71912019-10-11 11:13:39 -0700808#endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */
Elliott Hughes72472942018-01-10 08:36:10 -0800809
810static unsigned long
Haibo Huang40a71912019-10-11 11:13:39 -0700811ENTROPY_DEBUG(const char *label, unsigned long entropy) {
812 const char *const EXPAT_ENTROPY_DEBUG = getenv("EXPAT_ENTROPY_DEBUG");
Elliott Hughes72472942018-01-10 08:36:10 -0800813 if (EXPAT_ENTROPY_DEBUG && ! strcmp(EXPAT_ENTROPY_DEBUG, "1")) {
Haibo Huang40a71912019-10-11 11:13:39 -0700814 fprintf(stderr, "Entropy: %s --> 0x%0*lx (%lu bytes)\n", label,
815 (int)sizeof(entropy) * 2, entropy, (unsigned long)sizeof(entropy));
Elliott Hughes72472942018-01-10 08:36:10 -0800816 }
817 return entropy;
818}
819
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100820static unsigned long
Haibo Huang40a71912019-10-11 11:13:39 -0700821generate_hash_secret_salt(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -0800822 unsigned long entropy;
823 (void)parser;
824
825 /* "Failproof" high quality providers: */
826#if defined(HAVE_ARC4RANDOM_BUF)
827 arc4random_buf(&entropy, sizeof(entropy));
828 return ENTROPY_DEBUG("arc4random_buf", entropy);
829#elif defined(HAVE_ARC4RANDOM)
830 writeRandomBytes_arc4random((void *)&entropy, sizeof(entropy));
831 return ENTROPY_DEBUG("arc4random", entropy);
832#else
833 /* Try high quality providers first .. */
Haibo Huang40a71912019-10-11 11:13:39 -0700834# ifdef _WIN32
835 if (writeRandomBytes_rand_s((void *)&entropy, sizeof(entropy))) {
836 return ENTROPY_DEBUG("rand_s", entropy);
Elliott Hughes72472942018-01-10 08:36:10 -0800837 }
Haibo Huang40a71912019-10-11 11:13:39 -0700838# elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
Elliott Hughes72472942018-01-10 08:36:10 -0800839 if (writeRandomBytes_getrandom_nonblock((void *)&entropy, sizeof(entropy))) {
840 return ENTROPY_DEBUG("getrandom", entropy);
841 }
Haibo Huang40a71912019-10-11 11:13:39 -0700842# endif
843# if ! defined(_WIN32) && defined(XML_DEV_URANDOM)
Elliott Hughes72472942018-01-10 08:36:10 -0800844 if (writeRandomBytes_dev_urandom((void *)&entropy, sizeof(entropy))) {
845 return ENTROPY_DEBUG("/dev/urandom", entropy);
846 }
Haibo Huang40a71912019-10-11 11:13:39 -0700847# endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */
Elliott Hughes72472942018-01-10 08:36:10 -0800848 /* .. and self-made low quality for backup: */
849
850 /* Process ID is 0 bits entropy if attacker has local access */
851 entropy = gather_time_entropy() ^ getpid();
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100852
853 /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */
854 if (sizeof(unsigned long) == 4) {
Elliott Hughes72472942018-01-10 08:36:10 -0800855 return ENTROPY_DEBUG("fallback(4)", entropy * 2147483647);
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100856 } else {
Elliott Hughes72472942018-01-10 08:36:10 -0800857 return ENTROPY_DEBUG("fallback(8)",
Haibo Huang40a71912019-10-11 11:13:39 -0700858 entropy * (unsigned long)2305843009213693951ULL);
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100859 }
Elliott Hughes72472942018-01-10 08:36:10 -0800860#endif
861}
862
863static unsigned long
864get_hash_secret_salt(XML_Parser parser) {
865 if (parser->m_parentParser != NULL)
866 return get_hash_secret_salt(parser->m_parentParser);
867 return parser->m_hash_secret_salt;
Elliott Hughes35e432d2012-09-09 14:23:38 -0700868}
869
Haibo Huang40a71912019-10-11 11:13:39 -0700870static XML_Bool /* only valid for root parser */
871startParsing(XML_Parser parser) {
872 /* hash functions must be initialized before setContext() is called */
873 if (parser->m_hash_secret_salt == 0)
874 parser->m_hash_secret_salt = generate_hash_secret_salt(parser);
875 if (parser->m_ns) {
876 /* implicit context only set for root parser, since child
877 parsers (i.e. external entity parsers) will inherit it
878 */
879 return setContext(parser, implicitContext);
880 }
881 return XML_TRUE;
Elliott Hughes35e432d2012-09-09 14:23:38 -0700882}
883
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800884XML_Parser XMLCALL
885XML_ParserCreate_MM(const XML_Char *encodingName,
886 const XML_Memory_Handling_Suite *memsuite,
Haibo Huang40a71912019-10-11 11:13:39 -0700887 const XML_Char *nameSep) {
Elliott Hughes35e432d2012-09-09 14:23:38 -0700888 return parserCreate(encodingName, memsuite, nameSep, NULL);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800889}
890
891static XML_Parser
892parserCreate(const XML_Char *encodingName,
Haibo Huang40a71912019-10-11 11:13:39 -0700893 const XML_Memory_Handling_Suite *memsuite, const XML_Char *nameSep,
894 DTD *dtd) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800895 XML_Parser parser;
896
897 if (memsuite) {
898 XML_Memory_Handling_Suite *mtemp;
Haibo Huang40a71912019-10-11 11:13:39 -0700899 parser = (XML_Parser)memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800900 if (parser != NULL) {
901 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
902 mtemp->malloc_fcn = memsuite->malloc_fcn;
903 mtemp->realloc_fcn = memsuite->realloc_fcn;
904 mtemp->free_fcn = memsuite->free_fcn;
905 }
Haibo Huang40a71912019-10-11 11:13:39 -0700906 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800907 XML_Memory_Handling_Suite *mtemp;
908 parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
909 if (parser != NULL) {
910 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
911 mtemp->malloc_fcn = malloc;
912 mtemp->realloc_fcn = realloc;
913 mtemp->free_fcn = free;
914 }
915 }
916
Haibo Huang40a71912019-10-11 11:13:39 -0700917 if (! parser)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800918 return parser;
919
Elliott Hughes72472942018-01-10 08:36:10 -0800920 parser->m_buffer = NULL;
921 parser->m_bufferLim = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800922
Elliott Hughes72472942018-01-10 08:36:10 -0800923 parser->m_attsSize = INIT_ATTS_SIZE;
Haibo Huang40a71912019-10-11 11:13:39 -0700924 parser->m_atts
925 = (ATTRIBUTE *)MALLOC(parser, parser->m_attsSize * sizeof(ATTRIBUTE));
Elliott Hughes72472942018-01-10 08:36:10 -0800926 if (parser->m_atts == NULL) {
927 FREE(parser, parser);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800928 return NULL;
929 }
Elliott Hughes35e432d2012-09-09 14:23:38 -0700930#ifdef XML_ATTR_INFO
Haibo Huang40a71912019-10-11 11:13:39 -0700931 parser->m_attInfo = (XML_AttrInfo *)MALLOC(
932 parser, parser->m_attsSize * sizeof(XML_AttrInfo));
Elliott Hughes72472942018-01-10 08:36:10 -0800933 if (parser->m_attInfo == NULL) {
934 FREE(parser, parser->m_atts);
935 FREE(parser, parser);
Elliott Hughes35e432d2012-09-09 14:23:38 -0700936 return NULL;
937 }
938#endif
Haibo Huang40a71912019-10-11 11:13:39 -0700939 parser->m_dataBuf
940 = (XML_Char *)MALLOC(parser, INIT_DATA_BUF_SIZE * sizeof(XML_Char));
Elliott Hughes72472942018-01-10 08:36:10 -0800941 if (parser->m_dataBuf == NULL) {
942 FREE(parser, parser->m_atts);
Elliott Hughes35e432d2012-09-09 14:23:38 -0700943#ifdef XML_ATTR_INFO
Elliott Hughes72472942018-01-10 08:36:10 -0800944 FREE(parser, parser->m_attInfo);
Elliott Hughes35e432d2012-09-09 14:23:38 -0700945#endif
Elliott Hughes72472942018-01-10 08:36:10 -0800946 FREE(parser, parser);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800947 return NULL;
948 }
Elliott Hughes72472942018-01-10 08:36:10 -0800949 parser->m_dataBufEnd = parser->m_dataBuf + INIT_DATA_BUF_SIZE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800950
951 if (dtd)
Elliott Hughes72472942018-01-10 08:36:10 -0800952 parser->m_dtd = dtd;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800953 else {
Elliott Hughes72472942018-01-10 08:36:10 -0800954 parser->m_dtd = dtdCreate(&parser->m_mem);
955 if (parser->m_dtd == NULL) {
956 FREE(parser, parser->m_dataBuf);
957 FREE(parser, parser->m_atts);
Elliott Hughes35e432d2012-09-09 14:23:38 -0700958#ifdef XML_ATTR_INFO
Elliott Hughes72472942018-01-10 08:36:10 -0800959 FREE(parser, parser->m_attInfo);
Elliott Hughes35e432d2012-09-09 14:23:38 -0700960#endif
Elliott Hughes72472942018-01-10 08:36:10 -0800961 FREE(parser, parser);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800962 return NULL;
963 }
964 }
965
Elliott Hughes72472942018-01-10 08:36:10 -0800966 parser->m_freeBindingList = NULL;
967 parser->m_freeTagList = NULL;
968 parser->m_freeInternalEntities = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800969
Elliott Hughes72472942018-01-10 08:36:10 -0800970 parser->m_groupSize = 0;
971 parser->m_groupConnector = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800972
Elliott Hughes72472942018-01-10 08:36:10 -0800973 parser->m_unknownEncodingHandler = NULL;
974 parser->m_unknownEncodingHandlerData = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800975
Elliott Hughes72472942018-01-10 08:36:10 -0800976 parser->m_namespaceSeparator = ASCII_EXCL;
977 parser->m_ns = XML_FALSE;
978 parser->m_ns_triplets = XML_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800979
Elliott Hughes72472942018-01-10 08:36:10 -0800980 parser->m_nsAtts = NULL;
981 parser->m_nsAttsVersion = 0;
982 parser->m_nsAttsPower = 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800983
Elliott Hughes72472942018-01-10 08:36:10 -0800984 parser->m_protocolEncodingName = NULL;
985
986 poolInit(&parser->m_tempPool, &(parser->m_mem));
987 poolInit(&parser->m_temp2Pool, &(parser->m_mem));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800988 parserInit(parser, encodingName);
989
Haibo Huang40a71912019-10-11 11:13:39 -0700990 if (encodingName && ! parser->m_protocolEncodingName) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800991 XML_ParserFree(parser);
992 return NULL;
993 }
994
995 if (nameSep) {
Elliott Hughes72472942018-01-10 08:36:10 -0800996 parser->m_ns = XML_TRUE;
997 parser->m_internalEncoding = XmlGetInternalEncodingNS();
998 parser->m_namespaceSeparator = *nameSep;
Haibo Huang40a71912019-10-11 11:13:39 -0700999 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08001000 parser->m_internalEncoding = XmlGetInternalEncoding();
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001001 }
1002
1003 return parser;
1004}
1005
1006static void
Haibo Huang40a71912019-10-11 11:13:39 -07001007parserInit(XML_Parser parser, const XML_Char *encodingName) {
Elliott Hughes72472942018-01-10 08:36:10 -08001008 parser->m_processor = prologInitProcessor;
1009 XmlPrologStateInit(&parser->m_prologState);
1010 if (encodingName != NULL) {
1011 parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem));
1012 }
1013 parser->m_curBase = NULL;
1014 XmlInitEncoding(&parser->m_initEncoding, &parser->m_encoding, 0);
1015 parser->m_userData = NULL;
1016 parser->m_handlerArg = NULL;
1017 parser->m_startElementHandler = NULL;
1018 parser->m_endElementHandler = NULL;
1019 parser->m_characterDataHandler = NULL;
1020 parser->m_processingInstructionHandler = NULL;
1021 parser->m_commentHandler = NULL;
1022 parser->m_startCdataSectionHandler = NULL;
1023 parser->m_endCdataSectionHandler = NULL;
1024 parser->m_defaultHandler = NULL;
1025 parser->m_startDoctypeDeclHandler = NULL;
1026 parser->m_endDoctypeDeclHandler = NULL;
1027 parser->m_unparsedEntityDeclHandler = NULL;
1028 parser->m_notationDeclHandler = NULL;
1029 parser->m_startNamespaceDeclHandler = NULL;
1030 parser->m_endNamespaceDeclHandler = NULL;
1031 parser->m_notStandaloneHandler = NULL;
1032 parser->m_externalEntityRefHandler = NULL;
1033 parser->m_externalEntityRefHandlerArg = parser;
1034 parser->m_skippedEntityHandler = NULL;
1035 parser->m_elementDeclHandler = NULL;
1036 parser->m_attlistDeclHandler = NULL;
1037 parser->m_entityDeclHandler = NULL;
1038 parser->m_xmlDeclHandler = NULL;
1039 parser->m_bufferPtr = parser->m_buffer;
1040 parser->m_bufferEnd = parser->m_buffer;
1041 parser->m_parseEndByteIndex = 0;
1042 parser->m_parseEndPtr = NULL;
1043 parser->m_declElementType = NULL;
1044 parser->m_declAttributeId = NULL;
1045 parser->m_declEntity = NULL;
1046 parser->m_doctypeName = NULL;
1047 parser->m_doctypeSysid = NULL;
1048 parser->m_doctypePubid = NULL;
1049 parser->m_declAttributeType = NULL;
1050 parser->m_declNotationName = NULL;
1051 parser->m_declNotationPublicId = NULL;
1052 parser->m_declAttributeIsCdata = XML_FALSE;
1053 parser->m_declAttributeIsId = XML_FALSE;
1054 memset(&parser->m_position, 0, sizeof(POSITION));
1055 parser->m_errorCode = XML_ERROR_NONE;
1056 parser->m_eventPtr = NULL;
1057 parser->m_eventEndPtr = NULL;
1058 parser->m_positionPtr = NULL;
1059 parser->m_openInternalEntities = NULL;
1060 parser->m_defaultExpandInternalEntities = XML_TRUE;
1061 parser->m_tagLevel = 0;
1062 parser->m_tagStack = NULL;
1063 parser->m_inheritedBindings = NULL;
1064 parser->m_nSpecifiedAtts = 0;
1065 parser->m_unknownEncodingMem = NULL;
1066 parser->m_unknownEncodingRelease = NULL;
1067 parser->m_unknownEncodingData = NULL;
1068 parser->m_parentParser = NULL;
1069 parser->m_parsingStatus.parsing = XML_INITIALIZED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001070#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08001071 parser->m_isParamEntity = XML_FALSE;
1072 parser->m_useForeignDTD = XML_FALSE;
1073 parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001074#endif
Elliott Hughes72472942018-01-10 08:36:10 -08001075 parser->m_hash_secret_salt = 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001076}
1077
Elliott Hughes72472942018-01-10 08:36:10 -08001078/* moves list of bindings to m_freeBindingList */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001079static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001080moveToFreeBindingList(XML_Parser parser, BINDING *bindings) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001081 while (bindings) {
1082 BINDING *b = bindings;
1083 bindings = bindings->nextTagBinding;
Elliott Hughes72472942018-01-10 08:36:10 -08001084 b->nextTagBinding = parser->m_freeBindingList;
1085 parser->m_freeBindingList = b;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001086 }
1087}
1088
1089XML_Bool XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001090XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001091 TAG *tStk;
1092 OPEN_INTERNAL_ENTITY *openEntityList;
Elliott Hughes72472942018-01-10 08:36:10 -08001093
1094 if (parser == NULL)
Haibo Huang40a71912019-10-11 11:13:39 -07001095 return XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08001096
1097 if (parser->m_parentParser)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001098 return XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08001099 /* move m_tagStack to m_freeTagList */
1100 tStk = parser->m_tagStack;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001101 while (tStk) {
1102 TAG *tag = tStk;
1103 tStk = tStk->parent;
Elliott Hughes72472942018-01-10 08:36:10 -08001104 tag->parent = parser->m_freeTagList;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001105 moveToFreeBindingList(parser, tag->bindings);
1106 tag->bindings = NULL;
Elliott Hughes72472942018-01-10 08:36:10 -08001107 parser->m_freeTagList = tag;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001108 }
Elliott Hughes72472942018-01-10 08:36:10 -08001109 /* move m_openInternalEntities to m_freeInternalEntities */
1110 openEntityList = parser->m_openInternalEntities;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001111 while (openEntityList) {
1112 OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
1113 openEntityList = openEntity->next;
Elliott Hughes72472942018-01-10 08:36:10 -08001114 openEntity->next = parser->m_freeInternalEntities;
1115 parser->m_freeInternalEntities = openEntity;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001116 }
Elliott Hughes72472942018-01-10 08:36:10 -08001117 moveToFreeBindingList(parser, parser->m_inheritedBindings);
1118 FREE(parser, parser->m_unknownEncodingMem);
1119 if (parser->m_unknownEncodingRelease)
1120 parser->m_unknownEncodingRelease(parser->m_unknownEncodingData);
1121 poolClear(&parser->m_tempPool);
1122 poolClear(&parser->m_temp2Pool);
1123 FREE(parser, (void *)parser->m_protocolEncodingName);
1124 parser->m_protocolEncodingName = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001125 parserInit(parser, encodingName);
Elliott Hughes72472942018-01-10 08:36:10 -08001126 dtdReset(parser->m_dtd, &parser->m_mem);
Elliott Hughes35e432d2012-09-09 14:23:38 -07001127 return XML_TRUE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001128}
1129
1130enum XML_Status XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001131XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) {
Elliott Hughes72472942018-01-10 08:36:10 -08001132 if (parser == NULL)
Haibo Huang40a71912019-10-11 11:13:39 -07001133 return XML_STATUS_ERROR;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001134 /* Block after XML_Parse()/XML_ParseBuffer() has been called.
1135 XXX There's no way for the caller to determine which of the
1136 XXX possible error cases caused the XML_STATUS_ERROR return.
1137 */
Haibo Huang40a71912019-10-11 11:13:39 -07001138 if (parser->m_parsingStatus.parsing == XML_PARSING
1139 || parser->m_parsingStatus.parsing == XML_SUSPENDED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001140 return XML_STATUS_ERROR;
Elliott Hughes72472942018-01-10 08:36:10 -08001141
1142 /* Get rid of any previous encoding name */
1143 FREE(parser, (void *)parser->m_protocolEncodingName);
1144
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001145 if (encodingName == NULL)
Elliott Hughes72472942018-01-10 08:36:10 -08001146 /* No new encoding name */
1147 parser->m_protocolEncodingName = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001148 else {
Elliott Hughes72472942018-01-10 08:36:10 -08001149 /* Copy the new encoding name into allocated memory */
1150 parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem));
Haibo Huang40a71912019-10-11 11:13:39 -07001151 if (! parser->m_protocolEncodingName)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001152 return XML_STATUS_ERROR;
1153 }
1154 return XML_STATUS_OK;
1155}
1156
1157XML_Parser XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001158XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context,
1159 const XML_Char *encodingName) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001160 XML_Parser parser = oldParser;
1161 DTD *newDtd = NULL;
Elliott Hughes72472942018-01-10 08:36:10 -08001162 DTD *oldDtd;
1163 XML_StartElementHandler oldStartElementHandler;
1164 XML_EndElementHandler oldEndElementHandler;
1165 XML_CharacterDataHandler oldCharacterDataHandler;
1166 XML_ProcessingInstructionHandler oldProcessingInstructionHandler;
1167 XML_CommentHandler oldCommentHandler;
1168 XML_StartCdataSectionHandler oldStartCdataSectionHandler;
1169 XML_EndCdataSectionHandler oldEndCdataSectionHandler;
1170 XML_DefaultHandler oldDefaultHandler;
1171 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler;
1172 XML_NotationDeclHandler oldNotationDeclHandler;
1173 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler;
1174 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler;
1175 XML_NotStandaloneHandler oldNotStandaloneHandler;
1176 XML_ExternalEntityRefHandler oldExternalEntityRefHandler;
1177 XML_SkippedEntityHandler oldSkippedEntityHandler;
1178 XML_UnknownEncodingHandler oldUnknownEncodingHandler;
1179 XML_ElementDeclHandler oldElementDeclHandler;
1180 XML_AttlistDeclHandler oldAttlistDeclHandler;
1181 XML_EntityDeclHandler oldEntityDeclHandler;
1182 XML_XmlDeclHandler oldXmlDeclHandler;
Haibo Huang40a71912019-10-11 11:13:39 -07001183 ELEMENT_TYPE *oldDeclElementType;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001184
Elliott Hughes72472942018-01-10 08:36:10 -08001185 void *oldUserData;
1186 void *oldHandlerArg;
1187 XML_Bool oldDefaultExpandInternalEntities;
1188 XML_Parser oldExternalEntityRefHandlerArg;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001189#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08001190 enum XML_ParamEntityParsing oldParamEntityParsing;
1191 int oldInEntityValue;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001192#endif
Elliott Hughes72472942018-01-10 08:36:10 -08001193 XML_Bool oldns_triplets;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001194 /* Note that the new parser shares the same hash secret as the old
1195 parser, so that dtdCopy and copyEntityTable can lookup values
1196 from hash tables associated with either parser without us having
1197 to worry which hash secrets each table has.
1198 */
Elliott Hughes72472942018-01-10 08:36:10 -08001199 unsigned long oldhash_secret_salt;
1200
1201 /* Validate the oldParser parameter before we pull everything out of it */
1202 if (oldParser == NULL)
1203 return NULL;
1204
1205 /* Stash the original parser contents on the stack */
1206 oldDtd = parser->m_dtd;
1207 oldStartElementHandler = parser->m_startElementHandler;
1208 oldEndElementHandler = parser->m_endElementHandler;
1209 oldCharacterDataHandler = parser->m_characterDataHandler;
1210 oldProcessingInstructionHandler = parser->m_processingInstructionHandler;
1211 oldCommentHandler = parser->m_commentHandler;
1212 oldStartCdataSectionHandler = parser->m_startCdataSectionHandler;
1213 oldEndCdataSectionHandler = parser->m_endCdataSectionHandler;
1214 oldDefaultHandler = parser->m_defaultHandler;
1215 oldUnparsedEntityDeclHandler = parser->m_unparsedEntityDeclHandler;
1216 oldNotationDeclHandler = parser->m_notationDeclHandler;
1217 oldStartNamespaceDeclHandler = parser->m_startNamespaceDeclHandler;
1218 oldEndNamespaceDeclHandler = parser->m_endNamespaceDeclHandler;
1219 oldNotStandaloneHandler = parser->m_notStandaloneHandler;
1220 oldExternalEntityRefHandler = parser->m_externalEntityRefHandler;
1221 oldSkippedEntityHandler = parser->m_skippedEntityHandler;
1222 oldUnknownEncodingHandler = parser->m_unknownEncodingHandler;
1223 oldElementDeclHandler = parser->m_elementDeclHandler;
1224 oldAttlistDeclHandler = parser->m_attlistDeclHandler;
1225 oldEntityDeclHandler = parser->m_entityDeclHandler;
1226 oldXmlDeclHandler = parser->m_xmlDeclHandler;
1227 oldDeclElementType = parser->m_declElementType;
1228
1229 oldUserData = parser->m_userData;
1230 oldHandlerArg = parser->m_handlerArg;
1231 oldDefaultExpandInternalEntities = parser->m_defaultExpandInternalEntities;
1232 oldExternalEntityRefHandlerArg = parser->m_externalEntityRefHandlerArg;
1233#ifdef XML_DTD
1234 oldParamEntityParsing = parser->m_paramEntityParsing;
1235 oldInEntityValue = parser->m_prologState.inEntityValue;
1236#endif
1237 oldns_triplets = parser->m_ns_triplets;
1238 /* Note that the new parser shares the same hash secret as the old
1239 parser, so that dtdCopy and copyEntityTable can lookup values
1240 from hash tables associated with either parser without us having
1241 to worry which hash secrets each table has.
1242 */
1243 oldhash_secret_salt = parser->m_hash_secret_salt;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001244
1245#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07001246 if (! context)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001247 newDtd = oldDtd;
1248#endif /* XML_DTD */
1249
1250 /* Note that the magical uses of the pre-processor to make field
1251 access look more like C++ require that `parser' be overwritten
1252 here. This makes this function more painful to follow than it
1253 would be otherwise.
1254 */
Elliott Hughes72472942018-01-10 08:36:10 -08001255 if (parser->m_ns) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001256 XML_Char tmp[2];
Elliott Hughes72472942018-01-10 08:36:10 -08001257 *tmp = parser->m_namespaceSeparator;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001258 parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
Haibo Huang40a71912019-10-11 11:13:39 -07001259 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001260 parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
1261 }
1262
Haibo Huang40a71912019-10-11 11:13:39 -07001263 if (! parser)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001264 return NULL;
1265
Elliott Hughes72472942018-01-10 08:36:10 -08001266 parser->m_startElementHandler = oldStartElementHandler;
1267 parser->m_endElementHandler = oldEndElementHandler;
1268 parser->m_characterDataHandler = oldCharacterDataHandler;
1269 parser->m_processingInstructionHandler = oldProcessingInstructionHandler;
1270 parser->m_commentHandler = oldCommentHandler;
1271 parser->m_startCdataSectionHandler = oldStartCdataSectionHandler;
1272 parser->m_endCdataSectionHandler = oldEndCdataSectionHandler;
1273 parser->m_defaultHandler = oldDefaultHandler;
1274 parser->m_unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
1275 parser->m_notationDeclHandler = oldNotationDeclHandler;
1276 parser->m_startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
1277 parser->m_endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
1278 parser->m_notStandaloneHandler = oldNotStandaloneHandler;
1279 parser->m_externalEntityRefHandler = oldExternalEntityRefHandler;
1280 parser->m_skippedEntityHandler = oldSkippedEntityHandler;
1281 parser->m_unknownEncodingHandler = oldUnknownEncodingHandler;
1282 parser->m_elementDeclHandler = oldElementDeclHandler;
1283 parser->m_attlistDeclHandler = oldAttlistDeclHandler;
1284 parser->m_entityDeclHandler = oldEntityDeclHandler;
1285 parser->m_xmlDeclHandler = oldXmlDeclHandler;
1286 parser->m_declElementType = oldDeclElementType;
1287 parser->m_userData = oldUserData;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001288 if (oldUserData == oldHandlerArg)
Elliott Hughes72472942018-01-10 08:36:10 -08001289 parser->m_handlerArg = parser->m_userData;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001290 else
Elliott Hughes72472942018-01-10 08:36:10 -08001291 parser->m_handlerArg = parser;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001292 if (oldExternalEntityRefHandlerArg != oldParser)
Elliott Hughes72472942018-01-10 08:36:10 -08001293 parser->m_externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
1294 parser->m_defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
1295 parser->m_ns_triplets = oldns_triplets;
1296 parser->m_hash_secret_salt = oldhash_secret_salt;
1297 parser->m_parentParser = oldParser;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001298#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08001299 parser->m_paramEntityParsing = oldParamEntityParsing;
1300 parser->m_prologState.inEntityValue = oldInEntityValue;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001301 if (context) {
1302#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07001303 if (! dtdCopy(oldParser, parser->m_dtd, oldDtd, &parser->m_mem)
1304 || ! setContext(parser, context)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001305 XML_ParserFree(parser);
1306 return NULL;
1307 }
Elliott Hughes72472942018-01-10 08:36:10 -08001308 parser->m_processor = externalEntityInitProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001309#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07001310 } else {
1311 /* The DTD instance referenced by parser->m_dtd is shared between the
1312 document's root parser and external PE parsers, therefore one does not
1313 need to call setContext. In addition, one also *must* not call
1314 setContext, because this would overwrite existing prefix->binding
1315 pointers in parser->m_dtd with ones that get destroyed with the external
1316 PE parser. This would leave those prefixes with dangling pointers.
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001317 */
Elliott Hughes72472942018-01-10 08:36:10 -08001318 parser->m_isParamEntity = XML_TRUE;
1319 XmlPrologStateInitExternalEntity(&parser->m_prologState);
1320 parser->m_processor = externalParEntInitProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001321 }
1322#endif /* XML_DTD */
1323 return parser;
1324}
1325
1326static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001327destroyBindings(BINDING *bindings, XML_Parser parser) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001328 for (;;) {
1329 BINDING *b = bindings;
Haibo Huang40a71912019-10-11 11:13:39 -07001330 if (! b)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001331 break;
1332 bindings = b->nextTagBinding;
Elliott Hughes72472942018-01-10 08:36:10 -08001333 FREE(parser, b->uri);
1334 FREE(parser, b);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001335 }
1336}
1337
1338void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001339XML_ParserFree(XML_Parser parser) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001340 TAG *tagList;
1341 OPEN_INTERNAL_ENTITY *entityList;
1342 if (parser == NULL)
1343 return;
Elliott Hughes72472942018-01-10 08:36:10 -08001344 /* free m_tagStack and m_freeTagList */
1345 tagList = parser->m_tagStack;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001346 for (;;) {
1347 TAG *p;
1348 if (tagList == NULL) {
Elliott Hughes72472942018-01-10 08:36:10 -08001349 if (parser->m_freeTagList == NULL)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001350 break;
Elliott Hughes72472942018-01-10 08:36:10 -08001351 tagList = parser->m_freeTagList;
1352 parser->m_freeTagList = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001353 }
1354 p = tagList;
1355 tagList = tagList->parent;
Elliott Hughes72472942018-01-10 08:36:10 -08001356 FREE(parser, p->buf);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001357 destroyBindings(p->bindings, parser);
Elliott Hughes72472942018-01-10 08:36:10 -08001358 FREE(parser, p);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001359 }
Elliott Hughes72472942018-01-10 08:36:10 -08001360 /* free m_openInternalEntities and m_freeInternalEntities */
1361 entityList = parser->m_openInternalEntities;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001362 for (;;) {
1363 OPEN_INTERNAL_ENTITY *openEntity;
1364 if (entityList == NULL) {
Elliott Hughes72472942018-01-10 08:36:10 -08001365 if (parser->m_freeInternalEntities == NULL)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001366 break;
Elliott Hughes72472942018-01-10 08:36:10 -08001367 entityList = parser->m_freeInternalEntities;
1368 parser->m_freeInternalEntities = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001369 }
1370 openEntity = entityList;
1371 entityList = entityList->next;
Elliott Hughes72472942018-01-10 08:36:10 -08001372 FREE(parser, openEntity);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001373 }
1374
Elliott Hughes72472942018-01-10 08:36:10 -08001375 destroyBindings(parser->m_freeBindingList, parser);
1376 destroyBindings(parser->m_inheritedBindings, parser);
1377 poolDestroy(&parser->m_tempPool);
1378 poolDestroy(&parser->m_temp2Pool);
1379 FREE(parser, (void *)parser->m_protocolEncodingName);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001380#ifdef XML_DTD
1381 /* external parameter entity parsers share the DTD structure
1382 parser->m_dtd with the root parser, so we must not destroy it
1383 */
Haibo Huang40a71912019-10-11 11:13:39 -07001384 if (! parser->m_isParamEntity && parser->m_dtd)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001385#else
Elliott Hughes72472942018-01-10 08:36:10 -08001386 if (parser->m_dtd)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001387#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07001388 dtdDestroy(parser->m_dtd, (XML_Bool)! parser->m_parentParser,
1389 &parser->m_mem);
Elliott Hughes72472942018-01-10 08:36:10 -08001390 FREE(parser, (void *)parser->m_atts);
Elliott Hughes35e432d2012-09-09 14:23:38 -07001391#ifdef XML_ATTR_INFO
Elliott Hughes72472942018-01-10 08:36:10 -08001392 FREE(parser, (void *)parser->m_attInfo);
Elliott Hughes35e432d2012-09-09 14:23:38 -07001393#endif
Elliott Hughes72472942018-01-10 08:36:10 -08001394 FREE(parser, parser->m_groupConnector);
1395 FREE(parser, parser->m_buffer);
1396 FREE(parser, parser->m_dataBuf);
1397 FREE(parser, parser->m_nsAtts);
1398 FREE(parser, parser->m_unknownEncodingMem);
1399 if (parser->m_unknownEncodingRelease)
1400 parser->m_unknownEncodingRelease(parser->m_unknownEncodingData);
1401 FREE(parser, parser);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001402}
1403
1404void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001405XML_UseParserAsHandlerArg(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08001406 if (parser != NULL)
1407 parser->m_handlerArg = parser;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001408}
1409
1410enum XML_Error XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001411XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) {
Elliott Hughes72472942018-01-10 08:36:10 -08001412 if (parser == NULL)
1413 return XML_ERROR_INVALID_ARGUMENT;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001414#ifdef XML_DTD
1415 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Haibo Huang40a71912019-10-11 11:13:39 -07001416 if (parser->m_parsingStatus.parsing == XML_PARSING
1417 || parser->m_parsingStatus.parsing == XML_SUSPENDED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001418 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
Elliott Hughes72472942018-01-10 08:36:10 -08001419 parser->m_useForeignDTD = useDTD;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001420 return XML_ERROR_NONE;
1421#else
Haibo Huangd1a324a2020-10-28 22:19:36 -07001422 UNUSED_P(useDTD);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001423 return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
1424#endif
1425}
1426
1427void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001428XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) {
Elliott Hughes72472942018-01-10 08:36:10 -08001429 if (parser == NULL)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001430 return;
Elliott Hughes72472942018-01-10 08:36:10 -08001431 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Haibo Huang40a71912019-10-11 11:13:39 -07001432 if (parser->m_parsingStatus.parsing == XML_PARSING
1433 || parser->m_parsingStatus.parsing == XML_SUSPENDED)
Elliott Hughes72472942018-01-10 08:36:10 -08001434 return;
1435 parser->m_ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001436}
1437
1438void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001439XML_SetUserData(XML_Parser parser, void *p) {
Elliott Hughes72472942018-01-10 08:36:10 -08001440 if (parser == NULL)
1441 return;
1442 if (parser->m_handlerArg == parser->m_userData)
1443 parser->m_handlerArg = parser->m_userData = p;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001444 else
Elliott Hughes72472942018-01-10 08:36:10 -08001445 parser->m_userData = p;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001446}
1447
1448enum XML_Status XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001449XML_SetBase(XML_Parser parser, const XML_Char *p) {
Elliott Hughes72472942018-01-10 08:36:10 -08001450 if (parser == NULL)
1451 return XML_STATUS_ERROR;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001452 if (p) {
Elliott Hughes72472942018-01-10 08:36:10 -08001453 p = poolCopyString(&parser->m_dtd->pool, p);
Haibo Huang40a71912019-10-11 11:13:39 -07001454 if (! p)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001455 return XML_STATUS_ERROR;
Elliott Hughes72472942018-01-10 08:36:10 -08001456 parser->m_curBase = p;
Haibo Huang40a71912019-10-11 11:13:39 -07001457 } else
Elliott Hughes72472942018-01-10 08:36:10 -08001458 parser->m_curBase = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001459 return XML_STATUS_OK;
1460}
1461
Haibo Huang40a71912019-10-11 11:13:39 -07001462const XML_Char *XMLCALL
1463XML_GetBase(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08001464 if (parser == NULL)
1465 return NULL;
1466 return parser->m_curBase;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001467}
1468
1469int XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001470XML_GetSpecifiedAttributeCount(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08001471 if (parser == NULL)
1472 return -1;
1473 return parser->m_nSpecifiedAtts;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001474}
1475
1476int XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001477XML_GetIdAttributeIndex(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08001478 if (parser == NULL)
1479 return -1;
1480 return parser->m_idAttIndex;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001481}
1482
Elliott Hughes35e432d2012-09-09 14:23:38 -07001483#ifdef XML_ATTR_INFO
Haibo Huang40a71912019-10-11 11:13:39 -07001484const XML_AttrInfo *XMLCALL
1485XML_GetAttributeInfo(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08001486 if (parser == NULL)
1487 return NULL;
1488 return parser->m_attInfo;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001489}
1490#endif
1491
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001492void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001493XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start,
1494 XML_EndElementHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001495 if (parser == NULL)
1496 return;
1497 parser->m_startElementHandler = start;
1498 parser->m_endElementHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001499}
1500
1501void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001502XML_SetStartElementHandler(XML_Parser parser, XML_StartElementHandler start) {
Elliott Hughes72472942018-01-10 08:36:10 -08001503 if (parser != NULL)
1504 parser->m_startElementHandler = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001505}
1506
1507void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001508XML_SetEndElementHandler(XML_Parser parser, XML_EndElementHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001509 if (parser != NULL)
1510 parser->m_endElementHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001511}
1512
1513void XMLCALL
1514XML_SetCharacterDataHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001515 XML_CharacterDataHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001516 if (parser != NULL)
1517 parser->m_characterDataHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001518}
1519
1520void XMLCALL
1521XML_SetProcessingInstructionHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001522 XML_ProcessingInstructionHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001523 if (parser != NULL)
1524 parser->m_processingInstructionHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001525}
1526
1527void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001528XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001529 if (parser != NULL)
1530 parser->m_commentHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001531}
1532
1533void XMLCALL
1534XML_SetCdataSectionHandler(XML_Parser parser,
1535 XML_StartCdataSectionHandler start,
Haibo Huang40a71912019-10-11 11:13:39 -07001536 XML_EndCdataSectionHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001537 if (parser == NULL)
1538 return;
1539 parser->m_startCdataSectionHandler = start;
1540 parser->m_endCdataSectionHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001541}
1542
1543void XMLCALL
1544XML_SetStartCdataSectionHandler(XML_Parser parser,
1545 XML_StartCdataSectionHandler start) {
Elliott Hughes72472942018-01-10 08:36:10 -08001546 if (parser != NULL)
1547 parser->m_startCdataSectionHandler = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001548}
1549
1550void XMLCALL
1551XML_SetEndCdataSectionHandler(XML_Parser parser,
1552 XML_EndCdataSectionHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001553 if (parser != NULL)
1554 parser->m_endCdataSectionHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001555}
1556
1557void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001558XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001559 if (parser == NULL)
1560 return;
1561 parser->m_defaultHandler = handler;
1562 parser->m_defaultExpandInternalEntities = XML_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001563}
1564
1565void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001566XML_SetDefaultHandlerExpand(XML_Parser parser, XML_DefaultHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001567 if (parser == NULL)
1568 return;
1569 parser->m_defaultHandler = handler;
1570 parser->m_defaultExpandInternalEntities = XML_TRUE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001571}
1572
1573void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001574XML_SetDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start,
1575 XML_EndDoctypeDeclHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001576 if (parser == NULL)
1577 return;
1578 parser->m_startDoctypeDeclHandler = start;
1579 parser->m_endDoctypeDeclHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001580}
1581
1582void XMLCALL
1583XML_SetStartDoctypeDeclHandler(XML_Parser parser,
1584 XML_StartDoctypeDeclHandler start) {
Elliott Hughes72472942018-01-10 08:36:10 -08001585 if (parser != NULL)
1586 parser->m_startDoctypeDeclHandler = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001587}
1588
1589void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001590XML_SetEndDoctypeDeclHandler(XML_Parser parser, XML_EndDoctypeDeclHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001591 if (parser != NULL)
1592 parser->m_endDoctypeDeclHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001593}
1594
1595void XMLCALL
1596XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001597 XML_UnparsedEntityDeclHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001598 if (parser != NULL)
1599 parser->m_unparsedEntityDeclHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001600}
1601
1602void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001603XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001604 if (parser != NULL)
1605 parser->m_notationDeclHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001606}
1607
1608void XMLCALL
1609XML_SetNamespaceDeclHandler(XML_Parser parser,
1610 XML_StartNamespaceDeclHandler start,
Haibo Huang40a71912019-10-11 11:13:39 -07001611 XML_EndNamespaceDeclHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001612 if (parser == NULL)
1613 return;
1614 parser->m_startNamespaceDeclHandler = start;
1615 parser->m_endNamespaceDeclHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001616}
1617
1618void XMLCALL
1619XML_SetStartNamespaceDeclHandler(XML_Parser parser,
1620 XML_StartNamespaceDeclHandler start) {
Elliott Hughes72472942018-01-10 08:36:10 -08001621 if (parser != NULL)
1622 parser->m_startNamespaceDeclHandler = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001623}
1624
1625void XMLCALL
1626XML_SetEndNamespaceDeclHandler(XML_Parser parser,
1627 XML_EndNamespaceDeclHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001628 if (parser != NULL)
1629 parser->m_endNamespaceDeclHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001630}
1631
1632void XMLCALL
1633XML_SetNotStandaloneHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001634 XML_NotStandaloneHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001635 if (parser != NULL)
1636 parser->m_notStandaloneHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001637}
1638
1639void XMLCALL
1640XML_SetExternalEntityRefHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001641 XML_ExternalEntityRefHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001642 if (parser != NULL)
1643 parser->m_externalEntityRefHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001644}
1645
1646void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001647XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) {
Elliott Hughes72472942018-01-10 08:36:10 -08001648 if (parser == NULL)
1649 return;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001650 if (arg)
Elliott Hughes72472942018-01-10 08:36:10 -08001651 parser->m_externalEntityRefHandlerArg = (XML_Parser)arg;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001652 else
Elliott Hughes72472942018-01-10 08:36:10 -08001653 parser->m_externalEntityRefHandlerArg = parser;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001654}
1655
1656void XMLCALL
1657XML_SetSkippedEntityHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001658 XML_SkippedEntityHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001659 if (parser != NULL)
1660 parser->m_skippedEntityHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001661}
1662
1663void XMLCALL
1664XML_SetUnknownEncodingHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001665 XML_UnknownEncodingHandler handler, void *data) {
Elliott Hughes72472942018-01-10 08:36:10 -08001666 if (parser == NULL)
1667 return;
1668 parser->m_unknownEncodingHandler = handler;
1669 parser->m_unknownEncodingHandlerData = data;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001670}
1671
1672void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001673XML_SetElementDeclHandler(XML_Parser parser, XML_ElementDeclHandler eldecl) {
Elliott Hughes72472942018-01-10 08:36:10 -08001674 if (parser != NULL)
1675 parser->m_elementDeclHandler = eldecl;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001676}
1677
1678void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001679XML_SetAttlistDeclHandler(XML_Parser parser, XML_AttlistDeclHandler attdecl) {
Elliott Hughes72472942018-01-10 08:36:10 -08001680 if (parser != NULL)
1681 parser->m_attlistDeclHandler = attdecl;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001682}
1683
1684void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001685XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001686 if (parser != NULL)
1687 parser->m_entityDeclHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001688}
1689
1690void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001691XML_SetXmlDeclHandler(XML_Parser parser, XML_XmlDeclHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001692 if (parser != NULL)
1693 parser->m_xmlDeclHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001694}
1695
1696int XMLCALL
1697XML_SetParamEntityParsing(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001698 enum XML_ParamEntityParsing peParsing) {
Elliott Hughes72472942018-01-10 08:36:10 -08001699 if (parser == NULL)
1700 return 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001701 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Haibo Huang40a71912019-10-11 11:13:39 -07001702 if (parser->m_parsingStatus.parsing == XML_PARSING
1703 || parser->m_parsingStatus.parsing == XML_SUSPENDED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001704 return 0;
1705#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08001706 parser->m_paramEntityParsing = peParsing;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001707 return 1;
1708#else
1709 return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
1710#endif
1711}
1712
Elliott Hughes35e432d2012-09-09 14:23:38 -07001713int XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001714XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt) {
Elliott Hughes72472942018-01-10 08:36:10 -08001715 if (parser == NULL)
Elliott Hughes35e432d2012-09-09 14:23:38 -07001716 return 0;
Elliott Hughes72472942018-01-10 08:36:10 -08001717 if (parser->m_parentParser)
1718 return XML_SetHashSalt(parser->m_parentParser, hash_salt);
1719 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Haibo Huang40a71912019-10-11 11:13:39 -07001720 if (parser->m_parsingStatus.parsing == XML_PARSING
1721 || parser->m_parsingStatus.parsing == XML_SUSPENDED)
Elliott Hughes72472942018-01-10 08:36:10 -08001722 return 0;
1723 parser->m_hash_secret_salt = hash_salt;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001724 return 1;
1725}
1726
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001727enum XML_Status XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001728XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) {
Elliott Hughes72472942018-01-10 08:36:10 -08001729 if ((parser == NULL) || (len < 0) || ((s == NULL) && (len != 0))) {
1730 if (parser != NULL)
1731 parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT;
1732 return XML_STATUS_ERROR;
1733 }
1734 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001735 case XML_SUSPENDED:
Elliott Hughes72472942018-01-10 08:36:10 -08001736 parser->m_errorCode = XML_ERROR_SUSPENDED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001737 return XML_STATUS_ERROR;
1738 case XML_FINISHED:
Elliott Hughes72472942018-01-10 08:36:10 -08001739 parser->m_errorCode = XML_ERROR_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001740 return XML_STATUS_ERROR;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001741 case XML_INITIALIZED:
Haibo Huang40a71912019-10-11 11:13:39 -07001742 if (parser->m_parentParser == NULL && ! startParsing(parser)) {
Elliott Hughes72472942018-01-10 08:36:10 -08001743 parser->m_errorCode = XML_ERROR_NO_MEMORY;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001744 return XML_STATUS_ERROR;
1745 }
Elliott Hughesaaec48e2018-08-16 16:29:01 -07001746 /* fall through */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001747 default:
Elliott Hughes72472942018-01-10 08:36:10 -08001748 parser->m_parsingStatus.parsing = XML_PARSING;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001749 }
1750
1751 if (len == 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08001752 parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
Haibo Huang40a71912019-10-11 11:13:39 -07001753 if (! isFinal)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001754 return XML_STATUS_OK;
Elliott Hughes72472942018-01-10 08:36:10 -08001755 parser->m_positionPtr = parser->m_bufferPtr;
1756 parser->m_parseEndPtr = parser->m_bufferEnd;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001757
1758 /* If data are left over from last buffer, and we now know that these
1759 data are the final chunk of input, then we have to check them again
1760 to detect errors based on that fact.
1761 */
Haibo Huang40a71912019-10-11 11:13:39 -07001762 parser->m_errorCode
1763 = parser->m_processor(parser, parser->m_bufferPtr,
1764 parser->m_parseEndPtr, &parser->m_bufferPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001765
Elliott Hughes72472942018-01-10 08:36:10 -08001766 if (parser->m_errorCode == XML_ERROR_NONE) {
1767 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001768 case XML_SUSPENDED:
Elliott Hughes72472942018-01-10 08:36:10 -08001769 /* It is hard to be certain, but it seems that this case
1770 * cannot occur. This code is cleaning up a previous parse
1771 * with no new data (since len == 0). Changing the parsing
1772 * state requires getting to execute a handler function, and
1773 * there doesn't seem to be an opportunity for that while in
1774 * this circumstance.
1775 *
1776 * Given the uncertainty, we retain the code but exclude it
1777 * from coverage tests.
1778 *
1779 * LCOV_EXCL_START
1780 */
Haibo Huang40a71912019-10-11 11:13:39 -07001781 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
1782 parser->m_bufferPtr, &parser->m_position);
Elliott Hughes72472942018-01-10 08:36:10 -08001783 parser->m_positionPtr = parser->m_bufferPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001784 return XML_STATUS_SUSPENDED;
Elliott Hughes72472942018-01-10 08:36:10 -08001785 /* LCOV_EXCL_STOP */
Elliott Hughes35e432d2012-09-09 14:23:38 -07001786 case XML_INITIALIZED:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001787 case XML_PARSING:
Elliott Hughes72472942018-01-10 08:36:10 -08001788 parser->m_parsingStatus.parsing = XML_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001789 /* fall through */
1790 default:
1791 return XML_STATUS_OK;
1792 }
1793 }
Elliott Hughes72472942018-01-10 08:36:10 -08001794 parser->m_eventEndPtr = parser->m_eventPtr;
1795 parser->m_processor = errorProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001796 return XML_STATUS_ERROR;
1797 }
1798#ifndef XML_CONTEXT_BYTES
Elliott Hughes72472942018-01-10 08:36:10 -08001799 else if (parser->m_bufferPtr == parser->m_bufferEnd) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001800 const char *end;
1801 int nLeftOver;
Paul Duffinc05e0322016-05-04 10:42:31 +01001802 enum XML_Status result;
Elliott Hughes72472942018-01-10 08:36:10 -08001803 /* Detect overflow (a+b > MAX <==> b > MAX-a) */
Haibo Huangd1a324a2020-10-28 22:19:36 -07001804 if ((XML_Size)len > ((XML_Size)-1) / 2 - parser->m_parseEndByteIndex) {
Haibo Huang40a71912019-10-11 11:13:39 -07001805 parser->m_errorCode = XML_ERROR_NO_MEMORY;
1806 parser->m_eventPtr = parser->m_eventEndPtr = NULL;
1807 parser->m_processor = errorProcessor;
1808 return XML_STATUS_ERROR;
Elliott Hughes72472942018-01-10 08:36:10 -08001809 }
1810 parser->m_parseEndByteIndex += len;
1811 parser->m_positionPtr = s;
1812 parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001813
Haibo Huang40a71912019-10-11 11:13:39 -07001814 parser->m_errorCode
1815 = parser->m_processor(parser, s, parser->m_parseEndPtr = s + len, &end);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001816
Elliott Hughes72472942018-01-10 08:36:10 -08001817 if (parser->m_errorCode != XML_ERROR_NONE) {
1818 parser->m_eventEndPtr = parser->m_eventPtr;
1819 parser->m_processor = errorProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001820 return XML_STATUS_ERROR;
Haibo Huang40a71912019-10-11 11:13:39 -07001821 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08001822 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001823 case XML_SUSPENDED:
1824 result = XML_STATUS_SUSPENDED;
1825 break;
1826 case XML_INITIALIZED:
1827 case XML_PARSING:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001828 if (isFinal) {
Elliott Hughes72472942018-01-10 08:36:10 -08001829 parser->m_parsingStatus.parsing = XML_FINISHED;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001830 return XML_STATUS_OK;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001831 }
Elliott Hughes35e432d2012-09-09 14:23:38 -07001832 /* fall through */
1833 default:
1834 result = XML_STATUS_OK;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001835 }
1836 }
1837
Haibo Huang40a71912019-10-11 11:13:39 -07001838 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, end,
1839 &parser->m_position);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001840 nLeftOver = s + len - end;
1841 if (nLeftOver) {
Haibo Huang40a71912019-10-11 11:13:39 -07001842 if (parser->m_buffer == NULL
1843 || nLeftOver > parser->m_bufferLim - parser->m_buffer) {
Elliott Hughes72472942018-01-10 08:36:10 -08001844 /* avoid _signed_ integer overflow */
1845 char *temp = NULL;
1846 const int bytesToAllocate = (int)((unsigned)len * 2U);
1847 if (bytesToAllocate > 0) {
1848 temp = (char *)REALLOC(parser, parser->m_buffer, bytesToAllocate);
1849 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001850 if (temp == NULL) {
Elliott Hughes72472942018-01-10 08:36:10 -08001851 parser->m_errorCode = XML_ERROR_NO_MEMORY;
1852 parser->m_eventPtr = parser->m_eventEndPtr = NULL;
1853 parser->m_processor = errorProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001854 return XML_STATUS_ERROR;
1855 }
Elliott Hughes72472942018-01-10 08:36:10 -08001856 parser->m_buffer = temp;
1857 parser->m_bufferLim = parser->m_buffer + bytesToAllocate;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001858 }
Elliott Hughes72472942018-01-10 08:36:10 -08001859 memcpy(parser->m_buffer, end, nLeftOver);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001860 }
Elliott Hughes72472942018-01-10 08:36:10 -08001861 parser->m_bufferPtr = parser->m_buffer;
1862 parser->m_bufferEnd = parser->m_buffer + nLeftOver;
1863 parser->m_positionPtr = parser->m_bufferPtr;
1864 parser->m_parseEndPtr = parser->m_bufferEnd;
1865 parser->m_eventPtr = parser->m_bufferPtr;
1866 parser->m_eventEndPtr = parser->m_bufferPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001867 return result;
1868 }
Haibo Huang40a71912019-10-11 11:13:39 -07001869#endif /* not defined XML_CONTEXT_BYTES */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001870 else {
1871 void *buff = XML_GetBuffer(parser, len);
1872 if (buff == NULL)
1873 return XML_STATUS_ERROR;
1874 else {
1875 memcpy(buff, s, len);
1876 return XML_ParseBuffer(parser, len, isFinal);
1877 }
1878 }
1879}
1880
1881enum XML_Status XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001882XML_ParseBuffer(XML_Parser parser, int len, int isFinal) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001883 const char *start;
1884 enum XML_Status result = XML_STATUS_OK;
1885
Elliott Hughes72472942018-01-10 08:36:10 -08001886 if (parser == NULL)
1887 return XML_STATUS_ERROR;
1888 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001889 case XML_SUSPENDED:
Elliott Hughes72472942018-01-10 08:36:10 -08001890 parser->m_errorCode = XML_ERROR_SUSPENDED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001891 return XML_STATUS_ERROR;
1892 case XML_FINISHED:
Elliott Hughes72472942018-01-10 08:36:10 -08001893 parser->m_errorCode = XML_ERROR_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001894 return XML_STATUS_ERROR;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001895 case XML_INITIALIZED:
Haibo Huang40a71912019-10-11 11:13:39 -07001896 if (parser->m_parentParser == NULL && ! startParsing(parser)) {
Elliott Hughes72472942018-01-10 08:36:10 -08001897 parser->m_errorCode = XML_ERROR_NO_MEMORY;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001898 return XML_STATUS_ERROR;
1899 }
Elliott Hughesaaec48e2018-08-16 16:29:01 -07001900 /* fall through */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001901 default:
Elliott Hughes72472942018-01-10 08:36:10 -08001902 parser->m_parsingStatus.parsing = XML_PARSING;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001903 }
1904
Elliott Hughes72472942018-01-10 08:36:10 -08001905 start = parser->m_bufferPtr;
1906 parser->m_positionPtr = start;
1907 parser->m_bufferEnd += len;
1908 parser->m_parseEndPtr = parser->m_bufferEnd;
1909 parser->m_parseEndByteIndex += len;
1910 parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001911
Haibo Huang40a71912019-10-11 11:13:39 -07001912 parser->m_errorCode = parser->m_processor(
1913 parser, start, parser->m_parseEndPtr, &parser->m_bufferPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001914
Elliott Hughes72472942018-01-10 08:36:10 -08001915 if (parser->m_errorCode != XML_ERROR_NONE) {
1916 parser->m_eventEndPtr = parser->m_eventPtr;
1917 parser->m_processor = errorProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001918 return XML_STATUS_ERROR;
Haibo Huang40a71912019-10-11 11:13:39 -07001919 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08001920 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001921 case XML_SUSPENDED:
1922 result = XML_STATUS_SUSPENDED;
1923 break;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001924 case XML_INITIALIZED:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001925 case XML_PARSING:
1926 if (isFinal) {
Elliott Hughes72472942018-01-10 08:36:10 -08001927 parser->m_parsingStatus.parsing = XML_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001928 return result;
1929 }
Haibo Huang40a71912019-10-11 11:13:39 -07001930 default:; /* should not happen */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001931 }
1932 }
1933
Haibo Huang40a71912019-10-11 11:13:39 -07001934 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
1935 parser->m_bufferPtr, &parser->m_position);
Elliott Hughes72472942018-01-10 08:36:10 -08001936 parser->m_positionPtr = parser->m_bufferPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001937 return result;
1938}
1939
Haibo Huang40a71912019-10-11 11:13:39 -07001940void *XMLCALL
1941XML_GetBuffer(XML_Parser parser, int len) {
Elliott Hughes72472942018-01-10 08:36:10 -08001942 if (parser == NULL)
1943 return NULL;
Paul Duffinc05e0322016-05-04 10:42:31 +01001944 if (len < 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08001945 parser->m_errorCode = XML_ERROR_NO_MEMORY;
Paul Duffinc05e0322016-05-04 10:42:31 +01001946 return NULL;
1947 }
Elliott Hughes72472942018-01-10 08:36:10 -08001948 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001949 case XML_SUSPENDED:
Elliott Hughes72472942018-01-10 08:36:10 -08001950 parser->m_errorCode = XML_ERROR_SUSPENDED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001951 return NULL;
1952 case XML_FINISHED:
Elliott Hughes72472942018-01-10 08:36:10 -08001953 parser->m_errorCode = XML_ERROR_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001954 return NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07001955 default:;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001956 }
1957
Elliott Hughesaaec48e2018-08-16 16:29:01 -07001958 if (len > EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferEnd)) {
Paul Duffinba34a0c2017-02-27 14:40:16 +00001959#ifdef XML_CONTEXT_BYTES
1960 int keep;
Haibo Huang40a71912019-10-11 11:13:39 -07001961#endif /* defined XML_CONTEXT_BYTES */
Paul Duffinba34a0c2017-02-27 14:40:16 +00001962 /* Do not invoke signed arithmetic overflow: */
Haibo Huang40a71912019-10-11 11:13:39 -07001963 int neededSize = (int)((unsigned)len
1964 + (unsigned)EXPAT_SAFE_PTR_DIFF(
1965 parser->m_bufferEnd, parser->m_bufferPtr));
Paul Duffinc05e0322016-05-04 10:42:31 +01001966 if (neededSize < 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08001967 parser->m_errorCode = XML_ERROR_NO_MEMORY;
Paul Duffinc05e0322016-05-04 10:42:31 +01001968 return NULL;
1969 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001970#ifdef XML_CONTEXT_BYTES
Elliott Hughesaaec48e2018-08-16 16:29:01 -07001971 keep = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001972 if (keep > XML_CONTEXT_BYTES)
1973 keep = XML_CONTEXT_BYTES;
1974 neededSize += keep;
Haibo Huang40a71912019-10-11 11:13:39 -07001975#endif /* defined XML_CONTEXT_BYTES */
1976 if (neededSize
1977 <= EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_buffer)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001978#ifdef XML_CONTEXT_BYTES
Elliott Hughesaaec48e2018-08-16 16:29:01 -07001979 if (keep < EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer)) {
Haibo Huang40a71912019-10-11 11:13:39 -07001980 int offset
1981 = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer)
1982 - keep;
1983 /* The buffer pointers cannot be NULL here; we have at least some bytes
1984 * in the buffer */
1985 memmove(parser->m_buffer, &parser->m_buffer[offset],
1986 parser->m_bufferEnd - parser->m_bufferPtr + keep);
Elliott Hughes72472942018-01-10 08:36:10 -08001987 parser->m_bufferEnd -= offset;
1988 parser->m_bufferPtr -= offset;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001989 }
1990#else
Elliott Hughesaaec48e2018-08-16 16:29:01 -07001991 if (parser->m_buffer && parser->m_bufferPtr) {
1992 memmove(parser->m_buffer, parser->m_bufferPtr,
1993 EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr));
Haibo Huang40a71912019-10-11 11:13:39 -07001994 parser->m_bufferEnd
1995 = parser->m_buffer
1996 + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr);
Elliott Hughesaaec48e2018-08-16 16:29:01 -07001997 parser->m_bufferPtr = parser->m_buffer;
1998 }
Haibo Huang40a71912019-10-11 11:13:39 -07001999#endif /* not defined XML_CONTEXT_BYTES */
2000 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002001 char *newBuf;
Haibo Huang40a71912019-10-11 11:13:39 -07002002 int bufferSize
2003 = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002004 if (bufferSize == 0)
2005 bufferSize = INIT_BUFFER_SIZE;
2006 do {
Paul Duffinba34a0c2017-02-27 14:40:16 +00002007 /* Do not invoke signed arithmetic overflow: */
Haibo Huang40a71912019-10-11 11:13:39 -07002008 bufferSize = (int)(2U * (unsigned)bufferSize);
Paul Duffinc05e0322016-05-04 10:42:31 +01002009 } while (bufferSize < neededSize && bufferSize > 0);
2010 if (bufferSize <= 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08002011 parser->m_errorCode = XML_ERROR_NO_MEMORY;
Paul Duffinc05e0322016-05-04 10:42:31 +01002012 return NULL;
2013 }
Elliott Hughes72472942018-01-10 08:36:10 -08002014 newBuf = (char *)MALLOC(parser, bufferSize);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002015 if (newBuf == 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08002016 parser->m_errorCode = XML_ERROR_NO_MEMORY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002017 return NULL;
2018 }
Elliott Hughes72472942018-01-10 08:36:10 -08002019 parser->m_bufferLim = newBuf + bufferSize;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002020#ifdef XML_CONTEXT_BYTES
Elliott Hughes72472942018-01-10 08:36:10 -08002021 if (parser->m_bufferPtr) {
Elliott Hughesaaec48e2018-08-16 16:29:01 -07002022 memcpy(newBuf, &parser->m_bufferPtr[-keep],
Haibo Huang40a71912019-10-11 11:13:39 -07002023 EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)
2024 + keep);
Elliott Hughes72472942018-01-10 08:36:10 -08002025 FREE(parser, parser->m_buffer);
2026 parser->m_buffer = newBuf;
Haibo Huang40a71912019-10-11 11:13:39 -07002027 parser->m_bufferEnd
2028 = parser->m_buffer
2029 + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)
2030 + keep;
Elliott Hughes72472942018-01-10 08:36:10 -08002031 parser->m_bufferPtr = parser->m_buffer + keep;
Haibo Huang40a71912019-10-11 11:13:39 -07002032 } else {
Elliott Hughesaaec48e2018-08-16 16:29:01 -07002033 /* This must be a brand new buffer with no data in it yet */
2034 parser->m_bufferEnd = newBuf;
Elliott Hughes72472942018-01-10 08:36:10 -08002035 parser->m_bufferPtr = parser->m_buffer = newBuf;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002036 }
2037#else
Elliott Hughes72472942018-01-10 08:36:10 -08002038 if (parser->m_bufferPtr) {
Elliott Hughesaaec48e2018-08-16 16:29:01 -07002039 memcpy(newBuf, parser->m_bufferPtr,
2040 EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr));
Elliott Hughes72472942018-01-10 08:36:10 -08002041 FREE(parser, parser->m_buffer);
Haibo Huang40a71912019-10-11 11:13:39 -07002042 parser->m_bufferEnd
2043 = newBuf
2044 + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr);
2045 } else {
Elliott Hughesaaec48e2018-08-16 16:29:01 -07002046 /* This must be a brand new buffer with no data in it yet */
2047 parser->m_bufferEnd = newBuf;
2048 }
Elliott Hughes72472942018-01-10 08:36:10 -08002049 parser->m_bufferPtr = parser->m_buffer = newBuf;
Haibo Huang40a71912019-10-11 11:13:39 -07002050#endif /* not defined XML_CONTEXT_BYTES */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002051 }
Elliott Hughes72472942018-01-10 08:36:10 -08002052 parser->m_eventPtr = parser->m_eventEndPtr = NULL;
2053 parser->m_positionPtr = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002054 }
Elliott Hughes72472942018-01-10 08:36:10 -08002055 return parser->m_bufferEnd;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002056}
2057
2058enum XML_Status XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002059XML_StopParser(XML_Parser parser, XML_Bool resumable) {
Elliott Hughes72472942018-01-10 08:36:10 -08002060 if (parser == NULL)
2061 return XML_STATUS_ERROR;
2062 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002063 case XML_SUSPENDED:
2064 if (resumable) {
Elliott Hughes72472942018-01-10 08:36:10 -08002065 parser->m_errorCode = XML_ERROR_SUSPENDED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002066 return XML_STATUS_ERROR;
2067 }
Elliott Hughes72472942018-01-10 08:36:10 -08002068 parser->m_parsingStatus.parsing = XML_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002069 break;
2070 case XML_FINISHED:
Elliott Hughes72472942018-01-10 08:36:10 -08002071 parser->m_errorCode = XML_ERROR_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002072 return XML_STATUS_ERROR;
2073 default:
2074 if (resumable) {
2075#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08002076 if (parser->m_isParamEntity) {
2077 parser->m_errorCode = XML_ERROR_SUSPEND_PE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002078 return XML_STATUS_ERROR;
2079 }
2080#endif
Elliott Hughes72472942018-01-10 08:36:10 -08002081 parser->m_parsingStatus.parsing = XML_SUSPENDED;
Haibo Huang40a71912019-10-11 11:13:39 -07002082 } else
Elliott Hughes72472942018-01-10 08:36:10 -08002083 parser->m_parsingStatus.parsing = XML_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002084 }
2085 return XML_STATUS_OK;
2086}
2087
2088enum XML_Status XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002089XML_ResumeParser(XML_Parser parser) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002090 enum XML_Status result = XML_STATUS_OK;
2091
Elliott Hughes72472942018-01-10 08:36:10 -08002092 if (parser == NULL)
2093 return XML_STATUS_ERROR;
2094 if (parser->m_parsingStatus.parsing != XML_SUSPENDED) {
2095 parser->m_errorCode = XML_ERROR_NOT_SUSPENDED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002096 return XML_STATUS_ERROR;
2097 }
Elliott Hughes72472942018-01-10 08:36:10 -08002098 parser->m_parsingStatus.parsing = XML_PARSING;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002099
Haibo Huang40a71912019-10-11 11:13:39 -07002100 parser->m_errorCode = parser->m_processor(
2101 parser, parser->m_bufferPtr, parser->m_parseEndPtr, &parser->m_bufferPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002102
Elliott Hughes72472942018-01-10 08:36:10 -08002103 if (parser->m_errorCode != XML_ERROR_NONE) {
2104 parser->m_eventEndPtr = parser->m_eventPtr;
2105 parser->m_processor = errorProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002106 return XML_STATUS_ERROR;
Haibo Huang40a71912019-10-11 11:13:39 -07002107 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08002108 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002109 case XML_SUSPENDED:
2110 result = XML_STATUS_SUSPENDED;
2111 break;
Elliott Hughes35e432d2012-09-09 14:23:38 -07002112 case XML_INITIALIZED:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002113 case XML_PARSING:
Elliott Hughes72472942018-01-10 08:36:10 -08002114 if (parser->m_parsingStatus.finalBuffer) {
2115 parser->m_parsingStatus.parsing = XML_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002116 return result;
2117 }
Haibo Huang40a71912019-10-11 11:13:39 -07002118 default:;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002119 }
2120 }
2121
Haibo Huang40a71912019-10-11 11:13:39 -07002122 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
2123 parser->m_bufferPtr, &parser->m_position);
Elliott Hughes72472942018-01-10 08:36:10 -08002124 parser->m_positionPtr = parser->m_bufferPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002125 return result;
2126}
2127
2128void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002129XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status) {
Elliott Hughes72472942018-01-10 08:36:10 -08002130 if (parser == NULL)
2131 return;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002132 assert(status != NULL);
2133 *status = parser->m_parsingStatus;
2134}
2135
2136enum XML_Error XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002137XML_GetErrorCode(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002138 if (parser == NULL)
2139 return XML_ERROR_INVALID_ARGUMENT;
2140 return parser->m_errorCode;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002141}
2142
2143XML_Index XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002144XML_GetCurrentByteIndex(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002145 if (parser == NULL)
2146 return -1;
2147 if (parser->m_eventPtr)
Haibo Huang40a71912019-10-11 11:13:39 -07002148 return (XML_Index)(parser->m_parseEndByteIndex
2149 - (parser->m_parseEndPtr - parser->m_eventPtr));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002150 return -1;
2151}
2152
2153int XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002154XML_GetCurrentByteCount(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002155 if (parser == NULL)
2156 return 0;
2157 if (parser->m_eventEndPtr && parser->m_eventPtr)
2158 return (int)(parser->m_eventEndPtr - parser->m_eventPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002159 return 0;
2160}
2161
Haibo Huang40a71912019-10-11 11:13:39 -07002162const char *XMLCALL
2163XML_GetInputContext(XML_Parser parser, int *offset, int *size) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002164#ifdef XML_CONTEXT_BYTES
Elliott Hughes72472942018-01-10 08:36:10 -08002165 if (parser == NULL)
2166 return NULL;
2167 if (parser->m_eventPtr && parser->m_buffer) {
2168 if (offset != NULL)
2169 *offset = (int)(parser->m_eventPtr - parser->m_buffer);
2170 if (size != NULL)
Haibo Huang40a71912019-10-11 11:13:39 -07002171 *size = (int)(parser->m_bufferEnd - parser->m_buffer);
Elliott Hughes72472942018-01-10 08:36:10 -08002172 return parser->m_buffer;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002173 }
Elliott Hughes72472942018-01-10 08:36:10 -08002174#else
2175 (void)parser;
2176 (void)offset;
2177 (void)size;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002178#endif /* defined XML_CONTEXT_BYTES */
Haibo Huangd1a324a2020-10-28 22:19:36 -07002179 return (const char *)0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002180}
2181
2182XML_Size XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002183XML_GetCurrentLineNumber(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002184 if (parser == NULL)
2185 return 0;
2186 if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) {
Haibo Huang40a71912019-10-11 11:13:39 -07002187 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
2188 parser->m_eventPtr, &parser->m_position);
Elliott Hughes72472942018-01-10 08:36:10 -08002189 parser->m_positionPtr = parser->m_eventPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002190 }
Elliott Hughes72472942018-01-10 08:36:10 -08002191 return parser->m_position.lineNumber + 1;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002192}
2193
2194XML_Size XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002195XML_GetCurrentColumnNumber(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002196 if (parser == NULL)
2197 return 0;
2198 if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) {
Haibo Huang40a71912019-10-11 11:13:39 -07002199 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
2200 parser->m_eventPtr, &parser->m_position);
Elliott Hughes72472942018-01-10 08:36:10 -08002201 parser->m_positionPtr = parser->m_eventPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002202 }
Elliott Hughes72472942018-01-10 08:36:10 -08002203 return parser->m_position.columnNumber;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002204}
2205
2206void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002207XML_FreeContentModel(XML_Parser parser, XML_Content *model) {
Elliott Hughes72472942018-01-10 08:36:10 -08002208 if (parser != NULL)
2209 FREE(parser, model);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002210}
2211
Haibo Huang40a71912019-10-11 11:13:39 -07002212void *XMLCALL
2213XML_MemMalloc(XML_Parser parser, size_t size) {
Elliott Hughes72472942018-01-10 08:36:10 -08002214 if (parser == NULL)
2215 return NULL;
2216 return MALLOC(parser, size);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002217}
2218
Haibo Huang40a71912019-10-11 11:13:39 -07002219void *XMLCALL
2220XML_MemRealloc(XML_Parser parser, void *ptr, size_t size) {
Elliott Hughes72472942018-01-10 08:36:10 -08002221 if (parser == NULL)
2222 return NULL;
2223 return REALLOC(parser, ptr, size);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002224}
2225
2226void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002227XML_MemFree(XML_Parser parser, void *ptr) {
Elliott Hughes72472942018-01-10 08:36:10 -08002228 if (parser != NULL)
2229 FREE(parser, ptr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002230}
2231
2232void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002233XML_DefaultCurrent(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002234 if (parser == NULL)
2235 return;
2236 if (parser->m_defaultHandler) {
2237 if (parser->m_openInternalEntities)
Haibo Huang40a71912019-10-11 11:13:39 -07002238 reportDefault(parser, parser->m_internalEncoding,
Elliott Hughes72472942018-01-10 08:36:10 -08002239 parser->m_openInternalEntities->internalEventPtr,
2240 parser->m_openInternalEntities->internalEventEndPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002241 else
Haibo Huang40a71912019-10-11 11:13:39 -07002242 reportDefault(parser, parser->m_encoding, parser->m_eventPtr,
2243 parser->m_eventEndPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002244 }
2245}
2246
Haibo Huang40a71912019-10-11 11:13:39 -07002247const XML_LChar *XMLCALL
2248XML_ErrorString(enum XML_Error code) {
Elliott Hughes72472942018-01-10 08:36:10 -08002249 switch (code) {
2250 case XML_ERROR_NONE:
2251 return NULL;
2252 case XML_ERROR_NO_MEMORY:
2253 return XML_L("out of memory");
2254 case XML_ERROR_SYNTAX:
2255 return XML_L("syntax error");
2256 case XML_ERROR_NO_ELEMENTS:
2257 return XML_L("no element found");
2258 case XML_ERROR_INVALID_TOKEN:
2259 return XML_L("not well-formed (invalid token)");
2260 case XML_ERROR_UNCLOSED_TOKEN:
2261 return XML_L("unclosed token");
2262 case XML_ERROR_PARTIAL_CHAR:
2263 return XML_L("partial character");
2264 case XML_ERROR_TAG_MISMATCH:
2265 return XML_L("mismatched tag");
2266 case XML_ERROR_DUPLICATE_ATTRIBUTE:
2267 return XML_L("duplicate attribute");
2268 case XML_ERROR_JUNK_AFTER_DOC_ELEMENT:
2269 return XML_L("junk after document element");
2270 case XML_ERROR_PARAM_ENTITY_REF:
2271 return XML_L("illegal parameter entity reference");
2272 case XML_ERROR_UNDEFINED_ENTITY:
2273 return XML_L("undefined entity");
2274 case XML_ERROR_RECURSIVE_ENTITY_REF:
2275 return XML_L("recursive entity reference");
2276 case XML_ERROR_ASYNC_ENTITY:
2277 return XML_L("asynchronous entity");
2278 case XML_ERROR_BAD_CHAR_REF:
2279 return XML_L("reference to invalid character number");
2280 case XML_ERROR_BINARY_ENTITY_REF:
2281 return XML_L("reference to binary entity");
2282 case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF:
2283 return XML_L("reference to external entity in attribute");
2284 case XML_ERROR_MISPLACED_XML_PI:
2285 return XML_L("XML or text declaration not at start of entity");
2286 case XML_ERROR_UNKNOWN_ENCODING:
2287 return XML_L("unknown encoding");
2288 case XML_ERROR_INCORRECT_ENCODING:
2289 return XML_L("encoding specified in XML declaration is incorrect");
2290 case XML_ERROR_UNCLOSED_CDATA_SECTION:
2291 return XML_L("unclosed CDATA section");
2292 case XML_ERROR_EXTERNAL_ENTITY_HANDLING:
2293 return XML_L("error in processing external entity reference");
2294 case XML_ERROR_NOT_STANDALONE:
2295 return XML_L("document is not standalone");
2296 case XML_ERROR_UNEXPECTED_STATE:
2297 return XML_L("unexpected parser state - please send a bug report");
2298 case XML_ERROR_ENTITY_DECLARED_IN_PE:
2299 return XML_L("entity declared in parameter entity");
2300 case XML_ERROR_FEATURE_REQUIRES_XML_DTD:
2301 return XML_L("requested feature requires XML_DTD support in Expat");
2302 case XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING:
2303 return XML_L("cannot change setting once parsing has begun");
2304 /* Added in 1.95.7. */
2305 case XML_ERROR_UNBOUND_PREFIX:
2306 return XML_L("unbound prefix");
2307 /* Added in 1.95.8. */
2308 case XML_ERROR_UNDECLARING_PREFIX:
2309 return XML_L("must not undeclare prefix");
2310 case XML_ERROR_INCOMPLETE_PE:
2311 return XML_L("incomplete markup in parameter entity");
2312 case XML_ERROR_XML_DECL:
2313 return XML_L("XML declaration not well-formed");
2314 case XML_ERROR_TEXT_DECL:
2315 return XML_L("text declaration not well-formed");
2316 case XML_ERROR_PUBLICID:
2317 return XML_L("illegal character(s) in public id");
2318 case XML_ERROR_SUSPENDED:
2319 return XML_L("parser suspended");
2320 case XML_ERROR_NOT_SUSPENDED:
2321 return XML_L("parser not suspended");
2322 case XML_ERROR_ABORTED:
2323 return XML_L("parsing aborted");
2324 case XML_ERROR_FINISHED:
2325 return XML_L("parsing finished");
2326 case XML_ERROR_SUSPEND_PE:
2327 return XML_L("cannot suspend in external parameter entity");
2328 /* Added in 2.0.0. */
2329 case XML_ERROR_RESERVED_PREFIX_XML:
Haibo Huang40a71912019-10-11 11:13:39 -07002330 return XML_L(
2331 "reserved prefix (xml) must not be undeclared or bound to another namespace name");
Elliott Hughes72472942018-01-10 08:36:10 -08002332 case XML_ERROR_RESERVED_PREFIX_XMLNS:
2333 return XML_L("reserved prefix (xmlns) must not be declared or undeclared");
2334 case XML_ERROR_RESERVED_NAMESPACE_URI:
Haibo Huang40a71912019-10-11 11:13:39 -07002335 return XML_L(
2336 "prefix must not be bound to one of the reserved namespace names");
Elliott Hughes72472942018-01-10 08:36:10 -08002337 /* Added in 2.2.5. */
Haibo Huang40a71912019-10-11 11:13:39 -07002338 case XML_ERROR_INVALID_ARGUMENT: /* Constant added in 2.2.1, already */
Elliott Hughes72472942018-01-10 08:36:10 -08002339 return XML_L("invalid argument");
2340 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002341 return NULL;
2342}
2343
Haibo Huang40a71912019-10-11 11:13:39 -07002344const XML_LChar *XMLCALL
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002345XML_ExpatVersion(void) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002346 /* V1 is used to string-ize the version number. However, it would
2347 string-ize the actual version macro *names* unless we get them
2348 substituted before being passed to V1. CPP is defined to expand
2349 a macro, then rescan for more expansions. Thus, we use V2 to expand
2350 the version macros, then CPP will expand the resulting V1() macro
2351 with the correct numerals. */
2352 /* ### I'm assuming cpp is portable in this respect... */
2353
Haibo Huang40a71912019-10-11 11:13:39 -07002354#define V1(a, b, c) XML_L(#a) XML_L(".") XML_L(#b) XML_L(".") XML_L(#c)
2355#define V2(a, b, c) XML_L("expat_") V1(a, b, c)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002356
2357 return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
2358
2359#undef V1
2360#undef V2
2361}
2362
2363XML_Expat_Version XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002364XML_ExpatVersionInfo(void) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002365 XML_Expat_Version version;
2366
2367 version.major = XML_MAJOR_VERSION;
2368 version.minor = XML_MINOR_VERSION;
2369 version.micro = XML_MICRO_VERSION;
2370
2371 return version;
2372}
2373
Haibo Huang40a71912019-10-11 11:13:39 -07002374const XML_Feature *XMLCALL
2375XML_GetFeatureList(void) {
2376 static const XML_Feature features[]
2377 = {{XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"),
2378 sizeof(XML_Char)},
2379 {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
2380 sizeof(XML_LChar)},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002381#ifdef XML_UNICODE
Haibo Huang40a71912019-10-11 11:13:39 -07002382 {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002383#endif
2384#ifdef XML_UNICODE_WCHAR_T
Haibo Huang40a71912019-10-11 11:13:39 -07002385 {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002386#endif
2387#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07002388 {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002389#endif
2390#ifdef XML_CONTEXT_BYTES
Haibo Huang40a71912019-10-11 11:13:39 -07002391 {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
2392 XML_CONTEXT_BYTES},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002393#endif
2394#ifdef XML_MIN_SIZE
Haibo Huang40a71912019-10-11 11:13:39 -07002395 {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002396#endif
2397#ifdef XML_NS
Haibo Huang40a71912019-10-11 11:13:39 -07002398 {XML_FEATURE_NS, XML_L("XML_NS"), 0},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002399#endif
Elliott Hughesd07d5a72009-09-25 16:04:37 -07002400#ifdef XML_LARGE_SIZE
Haibo Huang40a71912019-10-11 11:13:39 -07002401 {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0},
Elliott Hughes35e432d2012-09-09 14:23:38 -07002402#endif
2403#ifdef XML_ATTR_INFO
Haibo Huang40a71912019-10-11 11:13:39 -07002404 {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0},
Elliott Hughes35e432d2012-09-09 14:23:38 -07002405#endif
Haibo Huang40a71912019-10-11 11:13:39 -07002406 {XML_FEATURE_END, NULL, 0}};
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002407
2408 return features;
2409}
2410
2411/* Initially tag->rawName always points into the parse buffer;
2412 for those TAG instances opened while the current parse buffer was
2413 processed, and not yet closed, we need to store tag->rawName in a more
2414 permanent location, since the parse buffer is about to be discarded.
2415*/
2416static XML_Bool
Haibo Huang40a71912019-10-11 11:13:39 -07002417storeRawNames(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002418 TAG *tag = parser->m_tagStack;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002419 while (tag) {
2420 int bufSize;
2421 int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
2422 char *rawNameBuf = tag->buf + nameLen;
Elliott Hughes72472942018-01-10 08:36:10 -08002423 /* Stop if already stored. Since m_tagStack is a stack, we can stop
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002424 at the first entry that has already been copied; everything
2425 below it in the stack is already been accounted for in a
2426 previous call to this function.
2427 */
2428 if (tag->rawName == rawNameBuf)
2429 break;
2430 /* For re-use purposes we need to ensure that the
2431 size of tag->buf is a multiple of sizeof(XML_Char).
2432 */
2433 bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
2434 if (bufSize > tag->bufEnd - tag->buf) {
Elliott Hughes72472942018-01-10 08:36:10 -08002435 char *temp = (char *)REALLOC(parser, tag->buf, bufSize);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002436 if (temp == NULL)
2437 return XML_FALSE;
2438 /* if tag->name.str points to tag->buf (only when namespace
2439 processing is off) then we have to update it
2440 */
2441 if (tag->name.str == (XML_Char *)tag->buf)
2442 tag->name.str = (XML_Char *)temp;
2443 /* if tag->name.localPart is set (when namespace processing is on)
2444 then update it as well, since it will always point into tag->buf
2445 */
2446 if (tag->name.localPart)
Haibo Huang40a71912019-10-11 11:13:39 -07002447 tag->name.localPart
2448 = (XML_Char *)temp + (tag->name.localPart - (XML_Char *)tag->buf);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002449 tag->buf = temp;
2450 tag->bufEnd = temp + bufSize;
2451 rawNameBuf = temp + nameLen;
2452 }
2453 memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
2454 tag->rawName = rawNameBuf;
2455 tag = tag->parent;
2456 }
2457 return XML_TRUE;
2458}
2459
2460static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002461contentProcessor(XML_Parser parser, const char *start, const char *end,
2462 const char **endPtr) {
2463 enum XML_Error result
2464 = doContent(parser, 0, parser->m_encoding, start, end, endPtr,
2465 (XML_Bool)! parser->m_parsingStatus.finalBuffer);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002466 if (result == XML_ERROR_NONE) {
Haibo Huang40a71912019-10-11 11:13:39 -07002467 if (! storeRawNames(parser))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002468 return XML_ERROR_NO_MEMORY;
2469 }
2470 return result;
2471}
2472
2473static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002474externalEntityInitProcessor(XML_Parser parser, const char *start,
2475 const char *end, const char **endPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002476 enum XML_Error result = initializeEncoding(parser);
2477 if (result != XML_ERROR_NONE)
2478 return result;
Elliott Hughes72472942018-01-10 08:36:10 -08002479 parser->m_processor = externalEntityInitProcessor2;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002480 return externalEntityInitProcessor2(parser, start, end, endPtr);
2481}
2482
2483static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002484externalEntityInitProcessor2(XML_Parser parser, const char *start,
2485 const char *end, const char **endPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002486 const char *next = start; /* XmlContentTok doesn't always set the last arg */
Elliott Hughes72472942018-01-10 08:36:10 -08002487 int tok = XmlContentTok(parser->m_encoding, start, end, &next);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002488 switch (tok) {
2489 case XML_TOK_BOM:
2490 /* If we are at the end of the buffer, this would cause the next stage,
2491 i.e. externalEntityInitProcessor3, to pass control directly to
2492 doContent (by detecting XML_TOK_NONE) without processing any xml text
2493 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
2494 */
Haibo Huang40a71912019-10-11 11:13:39 -07002495 if (next == end && ! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002496 *endPtr = next;
2497 return XML_ERROR_NONE;
2498 }
2499 start = next;
2500 break;
2501 case XML_TOK_PARTIAL:
Haibo Huang40a71912019-10-11 11:13:39 -07002502 if (! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002503 *endPtr = start;
2504 return XML_ERROR_NONE;
2505 }
Elliott Hughes72472942018-01-10 08:36:10 -08002506 parser->m_eventPtr = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002507 return XML_ERROR_UNCLOSED_TOKEN;
2508 case XML_TOK_PARTIAL_CHAR:
Haibo Huang40a71912019-10-11 11:13:39 -07002509 if (! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002510 *endPtr = start;
2511 return XML_ERROR_NONE;
2512 }
Elliott Hughes72472942018-01-10 08:36:10 -08002513 parser->m_eventPtr = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002514 return XML_ERROR_PARTIAL_CHAR;
2515 }
Elliott Hughes72472942018-01-10 08:36:10 -08002516 parser->m_processor = externalEntityInitProcessor3;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002517 return externalEntityInitProcessor3(parser, start, end, endPtr);
2518}
2519
2520static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002521externalEntityInitProcessor3(XML_Parser parser, const char *start,
2522 const char *end, const char **endPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002523 int tok;
2524 const char *next = start; /* XmlContentTok doesn't always set the last arg */
Elliott Hughes72472942018-01-10 08:36:10 -08002525 parser->m_eventPtr = start;
2526 tok = XmlContentTok(parser->m_encoding, start, end, &next);
2527 parser->m_eventEndPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002528
2529 switch (tok) {
Haibo Huang40a71912019-10-11 11:13:39 -07002530 case XML_TOK_XML_DECL: {
2531 enum XML_Error result;
2532 result = processXmlDecl(parser, 1, start, next);
2533 if (result != XML_ERROR_NONE)
2534 return result;
2535 switch (parser->m_parsingStatus.parsing) {
2536 case XML_SUSPENDED:
2537 *endPtr = next;
2538 return XML_ERROR_NONE;
2539 case XML_FINISHED:
2540 return XML_ERROR_ABORTED;
2541 default:
2542 start = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002543 }
Haibo Huang40a71912019-10-11 11:13:39 -07002544 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002545 case XML_TOK_PARTIAL:
Haibo Huang40a71912019-10-11 11:13:39 -07002546 if (! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002547 *endPtr = start;
2548 return XML_ERROR_NONE;
2549 }
2550 return XML_ERROR_UNCLOSED_TOKEN;
2551 case XML_TOK_PARTIAL_CHAR:
Haibo Huang40a71912019-10-11 11:13:39 -07002552 if (! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002553 *endPtr = start;
2554 return XML_ERROR_NONE;
2555 }
2556 return XML_ERROR_PARTIAL_CHAR;
2557 }
Elliott Hughes72472942018-01-10 08:36:10 -08002558 parser->m_processor = externalEntityContentProcessor;
2559 parser->m_tagLevel = 1;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002560 return externalEntityContentProcessor(parser, start, end, endPtr);
2561}
2562
2563static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002564externalEntityContentProcessor(XML_Parser parser, const char *start,
2565 const char *end, const char **endPtr) {
2566 enum XML_Error result
2567 = doContent(parser, 1, parser->m_encoding, start, end, endPtr,
2568 (XML_Bool)! parser->m_parsingStatus.finalBuffer);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002569 if (result == XML_ERROR_NONE) {
Haibo Huang40a71912019-10-11 11:13:39 -07002570 if (! storeRawNames(parser))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002571 return XML_ERROR_NO_MEMORY;
2572 }
2573 return result;
2574}
2575
2576static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07002577doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
2578 const char *s, const char *end, const char **nextPtr,
2579 XML_Bool haveMore) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002580 /* save one level of indirection */
Haibo Huang40a71912019-10-11 11:13:39 -07002581 DTD *const dtd = parser->m_dtd;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002582
2583 const char **eventPP;
2584 const char **eventEndPP;
Elliott Hughes72472942018-01-10 08:36:10 -08002585 if (enc == parser->m_encoding) {
2586 eventPP = &parser->m_eventPtr;
2587 eventEndPP = &parser->m_eventEndPtr;
Haibo Huang40a71912019-10-11 11:13:39 -07002588 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08002589 eventPP = &(parser->m_openInternalEntities->internalEventPtr);
2590 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002591 }
2592 *eventPP = s;
2593
2594 for (;;) {
2595 const char *next = s; /* XmlContentTok doesn't always set the last arg */
2596 int tok = XmlContentTok(enc, s, end, &next);
2597 *eventEndPP = next;
2598 switch (tok) {
2599 case XML_TOK_TRAILING_CR:
2600 if (haveMore) {
2601 *nextPtr = s;
2602 return XML_ERROR_NONE;
2603 }
2604 *eventEndPP = end;
Elliott Hughes72472942018-01-10 08:36:10 -08002605 if (parser->m_characterDataHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002606 XML_Char c = 0xA;
Elliott Hughes72472942018-01-10 08:36:10 -08002607 parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
Haibo Huang40a71912019-10-11 11:13:39 -07002608 } else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002609 reportDefault(parser, enc, s, end);
Elliott Hughes35e432d2012-09-09 14:23:38 -07002610 /* We are at the end of the final buffer, should we check for
2611 XML_SUSPENDED, XML_FINISHED?
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002612 */
2613 if (startTagLevel == 0)
2614 return XML_ERROR_NO_ELEMENTS;
Elliott Hughes72472942018-01-10 08:36:10 -08002615 if (parser->m_tagLevel != startTagLevel)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002616 return XML_ERROR_ASYNC_ENTITY;
2617 *nextPtr = end;
2618 return XML_ERROR_NONE;
2619 case XML_TOK_NONE:
2620 if (haveMore) {
2621 *nextPtr = s;
2622 return XML_ERROR_NONE;
2623 }
2624 if (startTagLevel > 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08002625 if (parser->m_tagLevel != startTagLevel)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002626 return XML_ERROR_ASYNC_ENTITY;
2627 *nextPtr = s;
2628 return XML_ERROR_NONE;
2629 }
2630 return XML_ERROR_NO_ELEMENTS;
2631 case XML_TOK_INVALID:
2632 *eventPP = next;
2633 return XML_ERROR_INVALID_TOKEN;
2634 case XML_TOK_PARTIAL:
2635 if (haveMore) {
2636 *nextPtr = s;
2637 return XML_ERROR_NONE;
2638 }
2639 return XML_ERROR_UNCLOSED_TOKEN;
2640 case XML_TOK_PARTIAL_CHAR:
2641 if (haveMore) {
2642 *nextPtr = s;
2643 return XML_ERROR_NONE;
2644 }
2645 return XML_ERROR_PARTIAL_CHAR;
Haibo Huang40a71912019-10-11 11:13:39 -07002646 case XML_TOK_ENTITY_REF: {
2647 const XML_Char *name;
2648 ENTITY *entity;
2649 XML_Char ch = (XML_Char)XmlPredefinedEntityName(
2650 enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar);
2651 if (ch) {
2652 if (parser->m_characterDataHandler)
2653 parser->m_characterDataHandler(parser->m_handlerArg, &ch, 1);
Elliott Hughes72472942018-01-10 08:36:10 -08002654 else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002655 reportDefault(parser, enc, s, next);
2656 break;
2657 }
Haibo Huang40a71912019-10-11 11:13:39 -07002658 name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
2659 next - enc->minBytesPerChar);
2660 if (! name)
2661 return XML_ERROR_NO_MEMORY;
2662 entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
2663 poolDiscard(&dtd->pool);
2664 /* First, determine if a check for an existing declaration is needed;
2665 if yes, check that the entity exists, and that it is internal,
2666 otherwise call the skipped entity or default handler.
2667 */
2668 if (! dtd->hasParamEntityRefs || dtd->standalone) {
2669 if (! entity)
2670 return XML_ERROR_UNDEFINED_ENTITY;
2671 else if (! entity->is_internal)
2672 return XML_ERROR_ENTITY_DECLARED_IN_PE;
2673 } else if (! entity) {
2674 if (parser->m_skippedEntityHandler)
2675 parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
2676 else if (parser->m_defaultHandler)
2677 reportDefault(parser, enc, s, next);
2678 break;
2679 }
2680 if (entity->open)
2681 return XML_ERROR_RECURSIVE_ENTITY_REF;
2682 if (entity->notation)
2683 return XML_ERROR_BINARY_ENTITY_REF;
2684 if (entity->textPtr) {
2685 enum XML_Error result;
2686 if (! parser->m_defaultExpandInternalEntities) {
2687 if (parser->m_skippedEntityHandler)
2688 parser->m_skippedEntityHandler(parser->m_handlerArg, entity->name,
2689 0);
2690 else if (parser->m_defaultHandler)
2691 reportDefault(parser, enc, s, next);
2692 break;
2693 }
2694 result = processInternalEntity(parser, entity, XML_FALSE);
2695 if (result != XML_ERROR_NONE)
2696 return result;
2697 } else if (parser->m_externalEntityRefHandler) {
2698 const XML_Char *context;
2699 entity->open = XML_TRUE;
2700 context = getContext(parser);
2701 entity->open = XML_FALSE;
2702 if (! context)
2703 return XML_ERROR_NO_MEMORY;
2704 if (! parser->m_externalEntityRefHandler(
2705 parser->m_externalEntityRefHandlerArg, context, entity->base,
2706 entity->systemId, entity->publicId))
2707 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
2708 poolDiscard(&parser->m_tempPool);
2709 } else if (parser->m_defaultHandler)
2710 reportDefault(parser, enc, s, next);
2711 break;
2712 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002713 case XML_TOK_START_TAG_NO_ATTS:
2714 /* fall through */
Haibo Huang40a71912019-10-11 11:13:39 -07002715 case XML_TOK_START_TAG_WITH_ATTS: {
2716 TAG *tag;
2717 enum XML_Error result;
2718 XML_Char *toPtr;
2719 if (parser->m_freeTagList) {
2720 tag = parser->m_freeTagList;
2721 parser->m_freeTagList = parser->m_freeTagList->parent;
2722 } else {
2723 tag = (TAG *)MALLOC(parser, sizeof(TAG));
2724 if (! tag)
2725 return XML_ERROR_NO_MEMORY;
2726 tag->buf = (char *)MALLOC(parser, INIT_TAG_BUF_SIZE);
2727 if (! tag->buf) {
2728 FREE(parser, tag);
2729 return XML_ERROR_NO_MEMORY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002730 }
Haibo Huang40a71912019-10-11 11:13:39 -07002731 tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002732 }
Haibo Huang40a71912019-10-11 11:13:39 -07002733 tag->bindings = NULL;
2734 tag->parent = parser->m_tagStack;
2735 parser->m_tagStack = tag;
2736 tag->name.localPart = NULL;
2737 tag->name.prefix = NULL;
2738 tag->rawName = s + enc->minBytesPerChar;
2739 tag->rawNameLength = XmlNameLength(enc, tag->rawName);
2740 ++parser->m_tagLevel;
2741 {
2742 const char *rawNameEnd = tag->rawName + tag->rawNameLength;
2743 const char *fromPtr = tag->rawName;
2744 toPtr = (XML_Char *)tag->buf;
2745 for (;;) {
2746 int bufSize;
2747 int convLen;
2748 const enum XML_Convert_Result convert_res
2749 = XmlConvert(enc, &fromPtr, rawNameEnd, (ICHAR **)&toPtr,
2750 (ICHAR *)tag->bufEnd - 1);
2751 convLen = (int)(toPtr - (XML_Char *)tag->buf);
2752 if ((fromPtr >= rawNameEnd)
2753 || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) {
2754 tag->name.strLen = convLen;
2755 break;
2756 }
2757 bufSize = (int)(tag->bufEnd - tag->buf) << 1;
2758 {
2759 char *temp = (char *)REALLOC(parser, tag->buf, bufSize);
2760 if (temp == NULL)
2761 return XML_ERROR_NO_MEMORY;
2762 tag->buf = temp;
2763 tag->bufEnd = temp + bufSize;
2764 toPtr = (XML_Char *)temp + convLen;
2765 }
2766 }
2767 }
2768 tag->name.str = (XML_Char *)tag->buf;
2769 *toPtr = XML_T('\0');
2770 result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
2771 if (result)
2772 return result;
2773 if (parser->m_startElementHandler)
2774 parser->m_startElementHandler(parser->m_handlerArg, tag->name.str,
2775 (const XML_Char **)parser->m_atts);
2776 else if (parser->m_defaultHandler)
2777 reportDefault(parser, enc, s, next);
2778 poolClear(&parser->m_tempPool);
2779 break;
2780 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002781 case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
2782 /* fall through */
Haibo Huang40a71912019-10-11 11:13:39 -07002783 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS: {
2784 const char *rawName = s + enc->minBytesPerChar;
2785 enum XML_Error result;
2786 BINDING *bindings = NULL;
2787 XML_Bool noElmHandlers = XML_TRUE;
2788 TAG_NAME name;
2789 name.str = poolStoreString(&parser->m_tempPool, enc, rawName,
2790 rawName + XmlNameLength(enc, rawName));
2791 if (! name.str)
2792 return XML_ERROR_NO_MEMORY;
2793 poolFinish(&parser->m_tempPool);
2794 result = storeAtts(parser, enc, s, &name, &bindings);
2795 if (result != XML_ERROR_NONE) {
Elliott Hughes72472942018-01-10 08:36:10 -08002796 freeBindings(parser, bindings);
Haibo Huang40a71912019-10-11 11:13:39 -07002797 return result;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002798 }
Haibo Huang40a71912019-10-11 11:13:39 -07002799 poolFinish(&parser->m_tempPool);
2800 if (parser->m_startElementHandler) {
2801 parser->m_startElementHandler(parser->m_handlerArg, name.str,
2802 (const XML_Char **)parser->m_atts);
2803 noElmHandlers = XML_FALSE;
2804 }
2805 if (parser->m_endElementHandler) {
2806 if (parser->m_startElementHandler)
2807 *eventPP = *eventEndPP;
2808 parser->m_endElementHandler(parser->m_handlerArg, name.str);
2809 noElmHandlers = XML_FALSE;
2810 }
2811 if (noElmHandlers && parser->m_defaultHandler)
2812 reportDefault(parser, enc, s, next);
2813 poolClear(&parser->m_tempPool);
2814 freeBindings(parser, bindings);
2815 }
2816 if ((parser->m_tagLevel == 0)
2817 && (parser->m_parsingStatus.parsing != XML_FINISHED)) {
Elliott Hughesaaec48e2018-08-16 16:29:01 -07002818 if (parser->m_parsingStatus.parsing == XML_SUSPENDED)
2819 parser->m_processor = epilogProcessor;
2820 else
2821 return epilogProcessor(parser, next, end, nextPtr);
Elliott Hughes72472942018-01-10 08:36:10 -08002822 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002823 break;
2824 case XML_TOK_END_TAG:
Elliott Hughes72472942018-01-10 08:36:10 -08002825 if (parser->m_tagLevel == startTagLevel)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002826 return XML_ERROR_ASYNC_ENTITY;
2827 else {
2828 int len;
2829 const char *rawName;
Elliott Hughes72472942018-01-10 08:36:10 -08002830 TAG *tag = parser->m_tagStack;
2831 parser->m_tagStack = tag->parent;
2832 tag->parent = parser->m_freeTagList;
2833 parser->m_freeTagList = tag;
Haibo Huang40a71912019-10-11 11:13:39 -07002834 rawName = s + enc->minBytesPerChar * 2;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002835 len = XmlNameLength(enc, rawName);
2836 if (len != tag->rawNameLength
2837 || memcmp(tag->rawName, rawName, len) != 0) {
2838 *eventPP = rawName;
2839 return XML_ERROR_TAG_MISMATCH;
2840 }
Elliott Hughes72472942018-01-10 08:36:10 -08002841 --parser->m_tagLevel;
2842 if (parser->m_endElementHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002843 const XML_Char *localPart;
2844 const XML_Char *prefix;
2845 XML_Char *uri;
2846 localPart = tag->name.localPart;
Elliott Hughes72472942018-01-10 08:36:10 -08002847 if (parser->m_ns && localPart) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002848 /* localPart and prefix may have been overwritten in
2849 tag->name.str, since this points to the binding->uri
2850 buffer which gets re-used; so we have to add them again
2851 */
2852 uri = (XML_Char *)tag->name.str + tag->name.uriLen;
2853 /* don't need to check for space - already done in storeAtts() */
Haibo Huang40a71912019-10-11 11:13:39 -07002854 while (*localPart)
2855 *uri++ = *localPart++;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002856 prefix = (XML_Char *)tag->name.prefix;
Elliott Hughes72472942018-01-10 08:36:10 -08002857 if (parser->m_ns_triplets && prefix) {
2858 *uri++ = parser->m_namespaceSeparator;
Haibo Huang40a71912019-10-11 11:13:39 -07002859 while (*prefix)
2860 *uri++ = *prefix++;
2861 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002862 *uri = XML_T('\0');
2863 }
Elliott Hughes72472942018-01-10 08:36:10 -08002864 parser->m_endElementHandler(parser->m_handlerArg, tag->name.str);
Haibo Huang40a71912019-10-11 11:13:39 -07002865 } else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002866 reportDefault(parser, enc, s, next);
2867 while (tag->bindings) {
2868 BINDING *b = tag->bindings;
Elliott Hughes72472942018-01-10 08:36:10 -08002869 if (parser->m_endNamespaceDeclHandler)
Haibo Huang40a71912019-10-11 11:13:39 -07002870 parser->m_endNamespaceDeclHandler(parser->m_handlerArg,
2871 b->prefix->name);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002872 tag->bindings = tag->bindings->nextTagBinding;
Elliott Hughes72472942018-01-10 08:36:10 -08002873 b->nextTagBinding = parser->m_freeBindingList;
2874 parser->m_freeBindingList = b;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002875 b->prefix->binding = b->prevPrefixBinding;
2876 }
Haibo Huang40a71912019-10-11 11:13:39 -07002877 if ((parser->m_tagLevel == 0)
2878 && (parser->m_parsingStatus.parsing != XML_FINISHED)) {
2879 if (parser->m_parsingStatus.parsing == XML_SUSPENDED)
2880 parser->m_processor = epilogProcessor;
2881 else
2882 return epilogProcessor(parser, next, end, nextPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002883 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002884 }
2885 break;
Haibo Huang40a71912019-10-11 11:13:39 -07002886 case XML_TOK_CHAR_REF: {
2887 int n = XmlCharRefNumber(enc, s);
2888 if (n < 0)
2889 return XML_ERROR_BAD_CHAR_REF;
2890 if (parser->m_characterDataHandler) {
2891 XML_Char buf[XML_ENCODE_MAX];
2892 parser->m_characterDataHandler(parser->m_handlerArg, buf,
2893 XmlEncode(n, (ICHAR *)buf));
2894 } else if (parser->m_defaultHandler)
2895 reportDefault(parser, enc, s, next);
2896 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002897 case XML_TOK_XML_DECL:
2898 return XML_ERROR_MISPLACED_XML_PI;
2899 case XML_TOK_DATA_NEWLINE:
Elliott Hughes72472942018-01-10 08:36:10 -08002900 if (parser->m_characterDataHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002901 XML_Char c = 0xA;
Elliott Hughes72472942018-01-10 08:36:10 -08002902 parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
Haibo Huang40a71912019-10-11 11:13:39 -07002903 } else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002904 reportDefault(parser, enc, s, next);
2905 break;
Haibo Huang40a71912019-10-11 11:13:39 -07002906 case XML_TOK_CDATA_SECT_OPEN: {
2907 enum XML_Error result;
2908 if (parser->m_startCdataSectionHandler)
2909 parser->m_startCdataSectionHandler(parser->m_handlerArg);
2910 /* BEGIN disabled code */
2911 /* Suppose you doing a transformation on a document that involves
2912 changing only the character data. You set up a defaultHandler
2913 and a characterDataHandler. The defaultHandler simply copies
2914 characters through. The characterDataHandler does the
2915 transformation and writes the characters out escaping them as
2916 necessary. This case will fail to work if we leave out the
2917 following two lines (because & and < inside CDATA sections will
2918 be incorrectly escaped).
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002919
Haibo Huang40a71912019-10-11 11:13:39 -07002920 However, now we have a start/endCdataSectionHandler, so it seems
2921 easier to let the user deal with this.
2922 */
2923 else if (0 && parser->m_characterDataHandler)
2924 parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf,
2925 0);
2926 /* END disabled code */
2927 else if (parser->m_defaultHandler)
2928 reportDefault(parser, enc, s, next);
2929 result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
2930 if (result != XML_ERROR_NONE)
2931 return result;
2932 else if (! next) {
2933 parser->m_processor = cdataSectionProcessor;
2934 return result;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002935 }
Haibo Huang40a71912019-10-11 11:13:39 -07002936 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002937 case XML_TOK_TRAILING_RSQB:
2938 if (haveMore) {
2939 *nextPtr = s;
2940 return XML_ERROR_NONE;
2941 }
Elliott Hughes72472942018-01-10 08:36:10 -08002942 if (parser->m_characterDataHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002943 if (MUST_CONVERT(enc, s)) {
Elliott Hughes72472942018-01-10 08:36:10 -08002944 ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
2945 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
Haibo Huang40a71912019-10-11 11:13:39 -07002946 parser->m_characterDataHandler(
2947 parser->m_handlerArg, parser->m_dataBuf,
2948 (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
2949 } else
2950 parser->m_characterDataHandler(
2951 parser->m_handlerArg, (XML_Char *)s,
2952 (int)((XML_Char *)end - (XML_Char *)s));
2953 } else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002954 reportDefault(parser, enc, s, end);
Elliott Hughes35e432d2012-09-09 14:23:38 -07002955 /* We are at the end of the final buffer, should we check for
2956 XML_SUSPENDED, XML_FINISHED?
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002957 */
2958 if (startTagLevel == 0) {
2959 *eventPP = end;
2960 return XML_ERROR_NO_ELEMENTS;
2961 }
Elliott Hughes72472942018-01-10 08:36:10 -08002962 if (parser->m_tagLevel != startTagLevel) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002963 *eventPP = end;
2964 return XML_ERROR_ASYNC_ENTITY;
2965 }
2966 *nextPtr = end;
2967 return XML_ERROR_NONE;
Haibo Huang40a71912019-10-11 11:13:39 -07002968 case XML_TOK_DATA_CHARS: {
2969 XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler;
2970 if (charDataHandler) {
2971 if (MUST_CONVERT(enc, s)) {
2972 for (;;) {
2973 ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
2974 const enum XML_Convert_Result convert_res = XmlConvert(
2975 enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
2976 *eventEndPP = s;
2977 charDataHandler(parser->m_handlerArg, parser->m_dataBuf,
2978 (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
2979 if ((convert_res == XML_CONVERT_COMPLETED)
2980 || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
2981 break;
2982 *eventPP = s;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002983 }
Haibo Huang40a71912019-10-11 11:13:39 -07002984 } else
2985 charDataHandler(parser->m_handlerArg, (XML_Char *)s,
2986 (int)((XML_Char *)next - (XML_Char *)s));
2987 } else if (parser->m_defaultHandler)
2988 reportDefault(parser, enc, s, next);
2989 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002990 case XML_TOK_PI:
Haibo Huang40a71912019-10-11 11:13:39 -07002991 if (! reportProcessingInstruction(parser, enc, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002992 return XML_ERROR_NO_MEMORY;
2993 break;
2994 case XML_TOK_COMMENT:
Haibo Huang40a71912019-10-11 11:13:39 -07002995 if (! reportComment(parser, enc, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002996 return XML_ERROR_NO_MEMORY;
2997 break;
2998 default:
Elliott Hughes72472942018-01-10 08:36:10 -08002999 /* All of the tokens produced by XmlContentTok() have their own
3000 * explicit cases, so this default is not strictly necessary.
3001 * However it is a useful safety net, so we retain the code and
3002 * simply exclude it from the coverage tests.
3003 *
3004 * LCOV_EXCL_START
3005 */
3006 if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003007 reportDefault(parser, enc, s, next);
3008 break;
Elliott Hughes72472942018-01-10 08:36:10 -08003009 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003010 }
3011 *eventPP = s = next;
Elliott Hughes72472942018-01-10 08:36:10 -08003012 switch (parser->m_parsingStatus.parsing) {
Elliott Hughes35e432d2012-09-09 14:23:38 -07003013 case XML_SUSPENDED:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003014 *nextPtr = next;
3015 return XML_ERROR_NONE;
3016 case XML_FINISHED:
3017 return XML_ERROR_ABORTED;
Haibo Huang40a71912019-10-11 11:13:39 -07003018 default:;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003019 }
3020 }
3021 /* not reached */
3022}
3023
Elliott Hughes72472942018-01-10 08:36:10 -08003024/* This function does not call free() on the allocated memory, merely
3025 * moving it to the parser's m_freeBindingList where it can be freed or
3026 * reused as appropriate.
3027 */
3028static void
Haibo Huang40a71912019-10-11 11:13:39 -07003029freeBindings(XML_Parser parser, BINDING *bindings) {
Elliott Hughes72472942018-01-10 08:36:10 -08003030 while (bindings) {
3031 BINDING *b = bindings;
3032
3033 /* m_startNamespaceDeclHandler will have been called for this
3034 * binding in addBindings(), so call the end handler now.
3035 */
3036 if (parser->m_endNamespaceDeclHandler)
Haibo Huang40a71912019-10-11 11:13:39 -07003037 parser->m_endNamespaceDeclHandler(parser->m_handlerArg, b->prefix->name);
Elliott Hughes72472942018-01-10 08:36:10 -08003038
3039 bindings = bindings->nextTagBinding;
3040 b->nextTagBinding = parser->m_freeBindingList;
3041 parser->m_freeBindingList = b;
3042 b->prefix->binding = b->prevPrefixBinding;
3043 }
3044}
3045
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003046/* Precondition: all arguments must be non-NULL;
3047 Purpose:
3048 - normalize attributes
3049 - check attributes for well-formedness
3050 - generate namespace aware attribute names (URI, prefix)
3051 - build list of attributes for startElementHandler
3052 - default attributes
3053 - process namespace declarations (check and report them)
3054 - generate namespace aware element name (URI, prefix)
3055*/
3056static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07003057storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
3058 TAG_NAME *tagNamePtr, BINDING **bindingsPtr) {
3059 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003060 ELEMENT_TYPE *elementType;
3061 int nDefaultAtts;
Haibo Huang40a71912019-10-11 11:13:39 -07003062 const XML_Char **appAtts; /* the attribute list for the application */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003063 int attIndex = 0;
3064 int prefixLen;
3065 int i;
3066 int n;
3067 XML_Char *uri;
3068 int nPrefixes = 0;
3069 BINDING *binding;
3070 const XML_Char *localPart;
3071
3072 /* lookup the element type name */
Haibo Huang40a71912019-10-11 11:13:39 -07003073 elementType
3074 = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str, 0);
3075 if (! elementType) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003076 const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
Haibo Huang40a71912019-10-11 11:13:39 -07003077 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003078 return XML_ERROR_NO_MEMORY;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003079 elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003080 sizeof(ELEMENT_TYPE));
Haibo Huang40a71912019-10-11 11:13:39 -07003081 if (! elementType)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003082 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07003083 if (parser->m_ns && ! setElementTypePrefix(parser, elementType))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003084 return XML_ERROR_NO_MEMORY;
3085 }
3086 nDefaultAtts = elementType->nDefaultAtts;
3087
3088 /* get the attributes from the tokenizer */
Elliott Hughes72472942018-01-10 08:36:10 -08003089 n = XmlGetAttributes(enc, attStr, parser->m_attsSize, parser->m_atts);
3090 if (n + nDefaultAtts > parser->m_attsSize) {
3091 int oldAttsSize = parser->m_attsSize;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003092 ATTRIBUTE *temp;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003093#ifdef XML_ATTR_INFO
3094 XML_AttrInfo *temp2;
3095#endif
Elliott Hughes72472942018-01-10 08:36:10 -08003096 parser->m_attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
Haibo Huang40a71912019-10-11 11:13:39 -07003097 temp = (ATTRIBUTE *)REALLOC(parser, (void *)parser->m_atts,
3098 parser->m_attsSize * sizeof(ATTRIBUTE));
Elliott Hughes72472942018-01-10 08:36:10 -08003099 if (temp == NULL) {
3100 parser->m_attsSize = oldAttsSize;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003101 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08003102 }
3103 parser->m_atts = temp;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003104#ifdef XML_ATTR_INFO
Haibo Huang40a71912019-10-11 11:13:39 -07003105 temp2 = (XML_AttrInfo *)REALLOC(parser, (void *)parser->m_attInfo,
3106 parser->m_attsSize * sizeof(XML_AttrInfo));
Elliott Hughes72472942018-01-10 08:36:10 -08003107 if (temp2 == NULL) {
3108 parser->m_attsSize = oldAttsSize;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003109 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08003110 }
3111 parser->m_attInfo = temp2;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003112#endif
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003113 if (n > oldAttsSize)
Elliott Hughes72472942018-01-10 08:36:10 -08003114 XmlGetAttributes(enc, attStr, n, parser->m_atts);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003115 }
3116
Elliott Hughes72472942018-01-10 08:36:10 -08003117 appAtts = (const XML_Char **)parser->m_atts;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003118 for (i = 0; i < n; i++) {
Elliott Hughes72472942018-01-10 08:36:10 -08003119 ATTRIBUTE *currAtt = &parser->m_atts[i];
Elliott Hughes35e432d2012-09-09 14:23:38 -07003120#ifdef XML_ATTR_INFO
Elliott Hughes72472942018-01-10 08:36:10 -08003121 XML_AttrInfo *currAttInfo = &parser->m_attInfo[i];
Elliott Hughes35e432d2012-09-09 14:23:38 -07003122#endif
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003123 /* add the name and value to the attribute list */
Haibo Huang40a71912019-10-11 11:13:39 -07003124 ATTRIBUTE_ID *attId
3125 = getAttributeId(parser, enc, currAtt->name,
3126 currAtt->name + XmlNameLength(enc, currAtt->name));
3127 if (! attId)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003128 return XML_ERROR_NO_MEMORY;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003129#ifdef XML_ATTR_INFO
Haibo Huang40a71912019-10-11 11:13:39 -07003130 currAttInfo->nameStart
3131 = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->name);
3132 currAttInfo->nameEnd
3133 = currAttInfo->nameStart + XmlNameLength(enc, currAtt->name);
3134 currAttInfo->valueStart = parser->m_parseEndByteIndex
3135 - (parser->m_parseEndPtr - currAtt->valuePtr);
3136 currAttInfo->valueEnd = parser->m_parseEndByteIndex
3137 - (parser->m_parseEndPtr - currAtt->valueEnd);
Elliott Hughes35e432d2012-09-09 14:23:38 -07003138#endif
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003139 /* Detect duplicate attributes by their QNames. This does not work when
3140 namespace processing is turned on and different prefixes for the same
3141 namespace are used. For this case we have a check further down.
3142 */
3143 if ((attId->name)[-1]) {
Elliott Hughes72472942018-01-10 08:36:10 -08003144 if (enc == parser->m_encoding)
3145 parser->m_eventPtr = parser->m_atts[i].name;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003146 return XML_ERROR_DUPLICATE_ATTRIBUTE;
3147 }
3148 (attId->name)[-1] = 1;
3149 appAtts[attIndex++] = attId->name;
Haibo Huang40a71912019-10-11 11:13:39 -07003150 if (! parser->m_atts[i].normalized) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003151 enum XML_Error result;
3152 XML_Bool isCdata = XML_TRUE;
3153
3154 /* figure out whether declared as other than CDATA */
3155 if (attId->maybeTokenized) {
3156 int j;
3157 for (j = 0; j < nDefaultAtts; j++) {
3158 if (attId == elementType->defaultAtts[j].id) {
3159 isCdata = elementType->defaultAtts[j].isCdata;
3160 break;
3161 }
3162 }
3163 }
3164
3165 /* normalize the attribute value */
Haibo Huang40a71912019-10-11 11:13:39 -07003166 result = storeAttributeValue(
3167 parser, enc, isCdata, parser->m_atts[i].valuePtr,
3168 parser->m_atts[i].valueEnd, &parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003169 if (result)
3170 return result;
Elliott Hughes72472942018-01-10 08:36:10 -08003171 appAtts[attIndex] = poolStart(&parser->m_tempPool);
3172 poolFinish(&parser->m_tempPool);
Haibo Huang40a71912019-10-11 11:13:39 -07003173 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003174 /* the value did not need normalizing */
Haibo Huang40a71912019-10-11 11:13:39 -07003175 appAtts[attIndex] = poolStoreString(&parser->m_tempPool, enc,
3176 parser->m_atts[i].valuePtr,
Elliott Hughes72472942018-01-10 08:36:10 -08003177 parser->m_atts[i].valueEnd);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003178 if (appAtts[attIndex] == 0)
3179 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08003180 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003181 }
3182 /* handle prefixed attribute names */
3183 if (attId->prefix) {
3184 if (attId->xmlns) {
3185 /* deal with namespace declarations here */
3186 enum XML_Error result = addBinding(parser, attId->prefix, attId,
3187 appAtts[attIndex], bindingsPtr);
3188 if (result)
3189 return result;
3190 --attIndex;
Haibo Huang40a71912019-10-11 11:13:39 -07003191 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003192 /* deal with other prefixed names later */
3193 attIndex++;
3194 nPrefixes++;
3195 (attId->name)[-1] = 2;
3196 }
Haibo Huang40a71912019-10-11 11:13:39 -07003197 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003198 attIndex++;
3199 }
3200
3201 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
Elliott Hughes72472942018-01-10 08:36:10 -08003202 parser->m_nSpecifiedAtts = attIndex;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003203 if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
3204 for (i = 0; i < attIndex; i += 2)
3205 if (appAtts[i] == elementType->idAtt->name) {
Elliott Hughes72472942018-01-10 08:36:10 -08003206 parser->m_idAttIndex = i;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003207 break;
3208 }
Haibo Huang40a71912019-10-11 11:13:39 -07003209 } else
Elliott Hughes72472942018-01-10 08:36:10 -08003210 parser->m_idAttIndex = -1;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003211
3212 /* do attribute defaulting */
3213 for (i = 0; i < nDefaultAtts; i++) {
3214 const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
Haibo Huang40a71912019-10-11 11:13:39 -07003215 if (! (da->id->name)[-1] && da->value) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003216 if (da->id->prefix) {
3217 if (da->id->xmlns) {
3218 enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
3219 da->value, bindingsPtr);
3220 if (result)
3221 return result;
Haibo Huang40a71912019-10-11 11:13:39 -07003222 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003223 (da->id->name)[-1] = 2;
3224 nPrefixes++;
3225 appAtts[attIndex++] = da->id->name;
3226 appAtts[attIndex++] = da->value;
3227 }
Haibo Huang40a71912019-10-11 11:13:39 -07003228 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003229 (da->id->name)[-1] = 1;
3230 appAtts[attIndex++] = da->id->name;
3231 appAtts[attIndex++] = da->value;
3232 }
3233 }
3234 }
3235 appAtts[attIndex] = 0;
3236
3237 /* expand prefixed attribute names, check for duplicates,
3238 and clear flags that say whether attributes were specified */
3239 i = 0;
3240 if (nPrefixes) {
Haibo Huang40a71912019-10-11 11:13:39 -07003241 int j; /* hash table index */
Elliott Hughes72472942018-01-10 08:36:10 -08003242 unsigned long version = parser->m_nsAttsVersion;
3243 int nsAttsSize = (int)1 << parser->m_nsAttsPower;
3244 unsigned char oldNsAttsPower = parser->m_nsAttsPower;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003245 /* size of hash table must be at least 2 * (# of prefixed attributes) */
Haibo Huang40a71912019-10-11 11:13:39 -07003246 if ((nPrefixes << 1)
3247 >> parser->m_nsAttsPower) { /* true for m_nsAttsPower = 0 */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003248 NS_ATT *temp;
3249 /* hash table size must also be a power of 2 and >= 8 */
Haibo Huang40a71912019-10-11 11:13:39 -07003250 while (nPrefixes >> parser->m_nsAttsPower++)
3251 ;
Elliott Hughes72472942018-01-10 08:36:10 -08003252 if (parser->m_nsAttsPower < 3)
3253 parser->m_nsAttsPower = 3;
3254 nsAttsSize = (int)1 << parser->m_nsAttsPower;
Haibo Huang40a71912019-10-11 11:13:39 -07003255 temp = (NS_ATT *)REALLOC(parser, parser->m_nsAtts,
3256 nsAttsSize * sizeof(NS_ATT));
3257 if (! temp) {
Elliott Hughes72472942018-01-10 08:36:10 -08003258 /* Restore actual size of memory in m_nsAtts */
3259 parser->m_nsAttsPower = oldNsAttsPower;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003260 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08003261 }
3262 parser->m_nsAtts = temp;
Haibo Huang40a71912019-10-11 11:13:39 -07003263 version = 0; /* force re-initialization of m_nsAtts hash table */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003264 }
Elliott Hughes72472942018-01-10 08:36:10 -08003265 /* using a version flag saves us from initializing m_nsAtts every time */
Haibo Huang40a71912019-10-11 11:13:39 -07003266 if (! version) { /* initialize version flags when version wraps around */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003267 version = INIT_ATTS_VERSION;
Haibo Huang40a71912019-10-11 11:13:39 -07003268 for (j = nsAttsSize; j != 0;)
Elliott Hughes72472942018-01-10 08:36:10 -08003269 parser->m_nsAtts[--j].version = version;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003270 }
Elliott Hughes72472942018-01-10 08:36:10 -08003271 parser->m_nsAttsVersion = --version;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003272
3273 /* expand prefixed names and check for duplicates */
3274 for (; i < attIndex; i += 2) {
3275 const XML_Char *s = appAtts[i];
Haibo Huang40a71912019-10-11 11:13:39 -07003276 if (s[-1] == 2) { /* prefixed */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003277 ATTRIBUTE_ID *id;
3278 const BINDING *b;
Elliott Hughes72472942018-01-10 08:36:10 -08003279 unsigned long uriHash;
3280 struct siphash sip_state;
3281 struct sipkey sip_key;
3282
3283 copy_salt_to_sipkey(parser, &sip_key);
3284 sip24_init(&sip_state, &sip_key);
3285
Haibo Huang40a71912019-10-11 11:13:39 -07003286 ((XML_Char *)s)[-1] = 0; /* clear flag */
Elliott Hughes35e432d2012-09-09 14:23:38 -07003287 id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);
Haibo Huang40a71912019-10-11 11:13:39 -07003288 if (! id || ! id->prefix) {
Elliott Hughes72472942018-01-10 08:36:10 -08003289 /* This code is walking through the appAtts array, dealing
3290 * with (in this case) a prefixed attribute name. To be in
3291 * the array, the attribute must have already been bound, so
3292 * has to have passed through the hash table lookup once
3293 * already. That implies that an entry for it already
3294 * exists, so the lookup above will return a pointer to
3295 * already allocated memory. There is no opportunaity for
3296 * the allocator to fail, so the condition above cannot be
3297 * fulfilled.
3298 *
3299 * Since it is difficult to be certain that the above
3300 * analysis is complete, we retain the test and merely
3301 * remove the code from coverage tests.
3302 */
3303 return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */
3304 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003305 b = id->prefix->binding;
Haibo Huang40a71912019-10-11 11:13:39 -07003306 if (! b)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003307 return XML_ERROR_UNBOUND_PREFIX;
3308
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003309 for (j = 0; j < b->uriLen; j++) {
3310 const XML_Char c = b->uri[j];
Haibo Huang40a71912019-10-11 11:13:39 -07003311 if (! poolAppendChar(&parser->m_tempPool, c))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003312 return XML_ERROR_NO_MEMORY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003313 }
Elliott Hughes72472942018-01-10 08:36:10 -08003314
3315 sip24_update(&sip_state, b->uri, b->uriLen * sizeof(XML_Char));
3316
Elliott Hughesd07d5a72009-09-25 16:04:37 -07003317 while (*s++ != XML_T(ASCII_COLON))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003318 ;
Elliott Hughes72472942018-01-10 08:36:10 -08003319
3320 sip24_update(&sip_state, s, keylen(s) * sizeof(XML_Char));
3321
Haibo Huang40a71912019-10-11 11:13:39 -07003322 do { /* copies null terminator */
3323 if (! poolAppendChar(&parser->m_tempPool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003324 return XML_ERROR_NO_MEMORY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003325 } while (*s++);
3326
Elliott Hughes72472942018-01-10 08:36:10 -08003327 uriHash = (unsigned long)sip24_final(&sip_state);
3328
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003329 { /* Check hash table for duplicate of expanded name (uriName).
Elliott Hughes35e432d2012-09-09 14:23:38 -07003330 Derived from code in lookup(parser, HASH_TABLE *table, ...).
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003331 */
3332 unsigned char step = 0;
3333 unsigned long mask = nsAttsSize - 1;
Haibo Huang40a71912019-10-11 11:13:39 -07003334 j = uriHash & mask; /* index into hash table */
Elliott Hughes72472942018-01-10 08:36:10 -08003335 while (parser->m_nsAtts[j].version == version) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003336 /* for speed we compare stored hash values first */
Elliott Hughes72472942018-01-10 08:36:10 -08003337 if (uriHash == parser->m_nsAtts[j].hash) {
3338 const XML_Char *s1 = poolStart(&parser->m_tempPool);
3339 const XML_Char *s2 = parser->m_nsAtts[j].uriName;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003340 /* s1 is null terminated, but not s2 */
Haibo Huang40a71912019-10-11 11:13:39 -07003341 for (; *s1 == *s2 && *s1 != 0; s1++, s2++)
3342 ;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003343 if (*s1 == 0)
3344 return XML_ERROR_DUPLICATE_ATTRIBUTE;
3345 }
Haibo Huang40a71912019-10-11 11:13:39 -07003346 if (! step)
Elliott Hughes72472942018-01-10 08:36:10 -08003347 step = PROBE_STEP(uriHash, mask, parser->m_nsAttsPower);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003348 j < step ? (j += nsAttsSize - step) : (j -= step);
3349 }
3350 }
3351
Haibo Huang40a71912019-10-11 11:13:39 -07003352 if (parser->m_ns_triplets) { /* append namespace separator and prefix */
Elliott Hughes72472942018-01-10 08:36:10 -08003353 parser->m_tempPool.ptr[-1] = parser->m_namespaceSeparator;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003354 s = b->prefix->name;
3355 do {
Haibo Huang40a71912019-10-11 11:13:39 -07003356 if (! poolAppendChar(&parser->m_tempPool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003357 return XML_ERROR_NO_MEMORY;
3358 } while (*s++);
3359 }
3360
3361 /* store expanded name in attribute list */
Elliott Hughes72472942018-01-10 08:36:10 -08003362 s = poolStart(&parser->m_tempPool);
3363 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003364 appAtts[i] = s;
3365
3366 /* fill empty slot with new version, uriName and hash value */
Elliott Hughes72472942018-01-10 08:36:10 -08003367 parser->m_nsAtts[j].version = version;
3368 parser->m_nsAtts[j].hash = uriHash;
3369 parser->m_nsAtts[j].uriName = s;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003370
Haibo Huang40a71912019-10-11 11:13:39 -07003371 if (! --nPrefixes) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003372 i += 2;
3373 break;
3374 }
Haibo Huang40a71912019-10-11 11:13:39 -07003375 } else /* not prefixed */
3376 ((XML_Char *)s)[-1] = 0; /* clear flag */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003377 }
3378 }
3379 /* clear flags for the remaining attributes */
3380 for (; i < attIndex; i += 2)
3381 ((XML_Char *)(appAtts[i]))[-1] = 0;
3382 for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
3383 binding->attId->name[-1] = 0;
3384
Haibo Huang40a71912019-10-11 11:13:39 -07003385 if (! parser->m_ns)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003386 return XML_ERROR_NONE;
3387
3388 /* expand the element type name */
3389 if (elementType->prefix) {
3390 binding = elementType->prefix->binding;
Haibo Huang40a71912019-10-11 11:13:39 -07003391 if (! binding)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003392 return XML_ERROR_UNBOUND_PREFIX;
3393 localPart = tagNamePtr->str;
Elliott Hughesd07d5a72009-09-25 16:04:37 -07003394 while (*localPart++ != XML_T(ASCII_COLON))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003395 ;
Haibo Huang40a71912019-10-11 11:13:39 -07003396 } else if (dtd->defaultPrefix.binding) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003397 binding = dtd->defaultPrefix.binding;
3398 localPart = tagNamePtr->str;
Haibo Huang40a71912019-10-11 11:13:39 -07003399 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003400 return XML_ERROR_NONE;
3401 prefixLen = 0;
Elliott Hughes72472942018-01-10 08:36:10 -08003402 if (parser->m_ns_triplets && binding->prefix->name) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003403 for (; binding->prefix->name[prefixLen++];)
Haibo Huang40a71912019-10-11 11:13:39 -07003404 ; /* prefixLen includes null terminator */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003405 }
3406 tagNamePtr->localPart = localPart;
3407 tagNamePtr->uriLen = binding->uriLen;
3408 tagNamePtr->prefix = binding->prefix->name;
3409 tagNamePtr->prefixLen = prefixLen;
3410 for (i = 0; localPart[i++];)
Haibo Huang40a71912019-10-11 11:13:39 -07003411 ; /* i includes null terminator */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003412 n = i + binding->uriLen + prefixLen;
3413 if (n > binding->uriAlloc) {
3414 TAG *p;
Elliott Hughes72472942018-01-10 08:36:10 -08003415 uri = (XML_Char *)MALLOC(parser, (n + EXPAND_SPARE) * sizeof(XML_Char));
Haibo Huang40a71912019-10-11 11:13:39 -07003416 if (! uri)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003417 return XML_ERROR_NO_MEMORY;
3418 binding->uriAlloc = n + EXPAND_SPARE;
3419 memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
Elliott Hughes72472942018-01-10 08:36:10 -08003420 for (p = parser->m_tagStack; p; p = p->parent)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003421 if (p->name.str == binding->uri)
3422 p->name.str = uri;
Elliott Hughes72472942018-01-10 08:36:10 -08003423 FREE(parser, binding->uri);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003424 binding->uri = uri;
3425 }
Elliott Hughes72472942018-01-10 08:36:10 -08003426 /* if m_namespaceSeparator != '\0' then uri includes it already */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003427 uri = binding->uri + binding->uriLen;
3428 memcpy(uri, localPart, i * sizeof(XML_Char));
3429 /* we always have a namespace separator between localPart and prefix */
3430 if (prefixLen) {
3431 uri += i - 1;
Haibo Huang40a71912019-10-11 11:13:39 -07003432 *uri = parser->m_namespaceSeparator; /* replace null terminator */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003433 memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
3434 }
3435 tagNamePtr->str = binding->uri;
3436 return XML_ERROR_NONE;
3437}
3438
3439/* addBinding() overwrites the value of prefix->binding without checking.
3440 Therefore one must keep track of the old value outside of addBinding().
3441*/
3442static enum XML_Error
3443addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
Haibo Huang40a71912019-10-11 11:13:39 -07003444 const XML_Char *uri, BINDING **bindingsPtr) {
3445 static const XML_Char xmlNamespace[]
3446 = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON,
3447 ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w,
3448 ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o,
3449 ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M,
3450 ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9,
3451 ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m,
3452 ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c,
3453 ASCII_e, '\0'};
3454 static const int xmlLen = (int)sizeof(xmlNamespace) / sizeof(XML_Char) - 1;
3455 static const XML_Char xmlnsNamespace[]
3456 = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH,
3457 ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w,
3458 ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH,
3459 ASCII_2, ASCII_0, ASCII_0, ASCII_0, ASCII_SLASH, ASCII_x,
3460 ASCII_m, ASCII_l, ASCII_n, ASCII_s, ASCII_SLASH, '\0'};
3461 static const int xmlnsLen
3462 = (int)sizeof(xmlnsNamespace) / sizeof(XML_Char) - 1;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003463
3464 XML_Bool mustBeXML = XML_FALSE;
3465 XML_Bool isXML = XML_TRUE;
3466 XML_Bool isXMLNS = XML_TRUE;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003467
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003468 BINDING *b;
3469 int len;
3470
3471 /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
3472 if (*uri == XML_T('\0') && prefix->name)
3473 return XML_ERROR_UNDECLARING_PREFIX;
3474
Haibo Huang40a71912019-10-11 11:13:39 -07003475 if (prefix->name && prefix->name[0] == XML_T(ASCII_x)
Elliott Hughesd07d5a72009-09-25 16:04:37 -07003476 && prefix->name[1] == XML_T(ASCII_m)
3477 && prefix->name[2] == XML_T(ASCII_l)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003478 /* Not allowed to bind xmlns */
Haibo Huang40a71912019-10-11 11:13:39 -07003479 if (prefix->name[3] == XML_T(ASCII_n) && prefix->name[4] == XML_T(ASCII_s)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003480 && prefix->name[5] == XML_T('\0'))
3481 return XML_ERROR_RESERVED_PREFIX_XMLNS;
3482
3483 if (prefix->name[3] == XML_T('\0'))
3484 mustBeXML = XML_TRUE;
3485 }
3486
3487 for (len = 0; uri[len]; len++) {
3488 if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
3489 isXML = XML_FALSE;
3490
Haibo Huang40a71912019-10-11 11:13:39 -07003491 if (! mustBeXML && isXMLNS
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003492 && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
3493 isXMLNS = XML_FALSE;
3494 }
3495 isXML = isXML && len == xmlLen;
3496 isXMLNS = isXMLNS && len == xmlnsLen;
3497
3498 if (mustBeXML != isXML)
3499 return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
3500 : XML_ERROR_RESERVED_NAMESPACE_URI;
3501
3502 if (isXMLNS)
3503 return XML_ERROR_RESERVED_NAMESPACE_URI;
3504
Elliott Hughes72472942018-01-10 08:36:10 -08003505 if (parser->m_namespaceSeparator)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003506 len++;
Elliott Hughes72472942018-01-10 08:36:10 -08003507 if (parser->m_freeBindingList) {
3508 b = parser->m_freeBindingList;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003509 if (len > b->uriAlloc) {
Haibo Huang40a71912019-10-11 11:13:39 -07003510 XML_Char *temp = (XML_Char *)REALLOC(
3511 parser, b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003512 if (temp == NULL)
3513 return XML_ERROR_NO_MEMORY;
3514 b->uri = temp;
3515 b->uriAlloc = len + EXPAND_SPARE;
3516 }
Elliott Hughes72472942018-01-10 08:36:10 -08003517 parser->m_freeBindingList = b->nextTagBinding;
Haibo Huang40a71912019-10-11 11:13:39 -07003518 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08003519 b = (BINDING *)MALLOC(parser, sizeof(BINDING));
Haibo Huang40a71912019-10-11 11:13:39 -07003520 if (! b)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003521 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07003522 b->uri
3523 = (XML_Char *)MALLOC(parser, sizeof(XML_Char) * (len + EXPAND_SPARE));
3524 if (! b->uri) {
Elliott Hughes72472942018-01-10 08:36:10 -08003525 FREE(parser, b);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003526 return XML_ERROR_NO_MEMORY;
3527 }
3528 b->uriAlloc = len + EXPAND_SPARE;
3529 }
3530 b->uriLen = len;
3531 memcpy(b->uri, uri, len * sizeof(XML_Char));
Elliott Hughes72472942018-01-10 08:36:10 -08003532 if (parser->m_namespaceSeparator)
3533 b->uri[len - 1] = parser->m_namespaceSeparator;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003534 b->prefix = prefix;
3535 b->attId = attId;
3536 b->prevPrefixBinding = prefix->binding;
3537 /* NULL binding when default namespace undeclared */
Elliott Hughes72472942018-01-10 08:36:10 -08003538 if (*uri == XML_T('\0') && prefix == &parser->m_dtd->defaultPrefix)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003539 prefix->binding = NULL;
3540 else
3541 prefix->binding = b;
3542 b->nextTagBinding = *bindingsPtr;
3543 *bindingsPtr = b;
3544 /* if attId == NULL then we are not starting a namespace scope */
Elliott Hughes72472942018-01-10 08:36:10 -08003545 if (attId && parser->m_startNamespaceDeclHandler)
3546 parser->m_startNamespaceDeclHandler(parser->m_handlerArg, prefix->name,
Haibo Huang40a71912019-10-11 11:13:39 -07003547 prefix->binding ? uri : 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003548 return XML_ERROR_NONE;
3549}
3550
3551/* The idea here is to avoid using stack for each CDATA section when
3552 the whole file is parsed with one call.
3553*/
3554static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07003555cdataSectionProcessor(XML_Parser parser, const char *start, const char *end,
3556 const char **endPtr) {
3557 enum XML_Error result
3558 = doCdataSection(parser, parser->m_encoding, &start, end, endPtr,
3559 (XML_Bool)! parser->m_parsingStatus.finalBuffer);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003560 if (result != XML_ERROR_NONE)
3561 return result;
3562 if (start) {
Haibo Huang40a71912019-10-11 11:13:39 -07003563 if (parser->m_parentParser) { /* we are parsing an external entity */
Elliott Hughes72472942018-01-10 08:36:10 -08003564 parser->m_processor = externalEntityContentProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003565 return externalEntityContentProcessor(parser, start, end, endPtr);
Haibo Huang40a71912019-10-11 11:13:39 -07003566 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08003567 parser->m_processor = contentProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003568 return contentProcessor(parser, start, end, endPtr);
3569 }
3570 }
3571 return result;
3572}
3573
3574/* startPtr gets set to non-null if the section is closed, and to null if
3575 the section is not yet closed.
3576*/
3577static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07003578doCdataSection(XML_Parser parser, const ENCODING *enc, const char **startPtr,
3579 const char *end, const char **nextPtr, XML_Bool haveMore) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003580 const char *s = *startPtr;
3581 const char **eventPP;
3582 const char **eventEndPP;
Elliott Hughes72472942018-01-10 08:36:10 -08003583 if (enc == parser->m_encoding) {
3584 eventPP = &parser->m_eventPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003585 *eventPP = s;
Elliott Hughes72472942018-01-10 08:36:10 -08003586 eventEndPP = &parser->m_eventEndPtr;
Haibo Huang40a71912019-10-11 11:13:39 -07003587 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08003588 eventPP = &(parser->m_openInternalEntities->internalEventPtr);
3589 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003590 }
3591 *eventPP = s;
3592 *startPtr = NULL;
3593
3594 for (;;) {
Haibo Huangd1a324a2020-10-28 22:19:36 -07003595 const char *next = s; /* in case of XML_TOK_NONE or XML_TOK_PARTIAL */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003596 int tok = XmlCdataSectionTok(enc, s, end, &next);
3597 *eventEndPP = next;
3598 switch (tok) {
3599 case XML_TOK_CDATA_SECT_CLOSE:
Elliott Hughes72472942018-01-10 08:36:10 -08003600 if (parser->m_endCdataSectionHandler)
3601 parser->m_endCdataSectionHandler(parser->m_handlerArg);
Haibo Huang40a71912019-10-11 11:13:39 -07003602 /* BEGIN disabled code */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003603 /* see comment under XML_TOK_CDATA_SECT_OPEN */
Haibo Huangfd5e81a2019-06-20 12:09:36 -07003604 else if (0 && parser->m_characterDataHandler)
Haibo Huang40a71912019-10-11 11:13:39 -07003605 parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf,
3606 0);
3607 /* END disabled code */
Elliott Hughes72472942018-01-10 08:36:10 -08003608 else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003609 reportDefault(parser, enc, s, next);
3610 *startPtr = next;
3611 *nextPtr = next;
Elliott Hughes72472942018-01-10 08:36:10 -08003612 if (parser->m_parsingStatus.parsing == XML_FINISHED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003613 return XML_ERROR_ABORTED;
3614 else
3615 return XML_ERROR_NONE;
3616 case XML_TOK_DATA_NEWLINE:
Elliott Hughes72472942018-01-10 08:36:10 -08003617 if (parser->m_characterDataHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003618 XML_Char c = 0xA;
Elliott Hughes72472942018-01-10 08:36:10 -08003619 parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
Haibo Huang40a71912019-10-11 11:13:39 -07003620 } else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003621 reportDefault(parser, enc, s, next);
3622 break;
Haibo Huang40a71912019-10-11 11:13:39 -07003623 case XML_TOK_DATA_CHARS: {
3624 XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler;
3625 if (charDataHandler) {
3626 if (MUST_CONVERT(enc, s)) {
3627 for (;;) {
3628 ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
3629 const enum XML_Convert_Result convert_res = XmlConvert(
3630 enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
3631 *eventEndPP = next;
3632 charDataHandler(parser->m_handlerArg, parser->m_dataBuf,
3633 (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
3634 if ((convert_res == XML_CONVERT_COMPLETED)
3635 || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
3636 break;
3637 *eventPP = s;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003638 }
Haibo Huang40a71912019-10-11 11:13:39 -07003639 } else
3640 charDataHandler(parser->m_handlerArg, (XML_Char *)s,
3641 (int)((XML_Char *)next - (XML_Char *)s));
3642 } else if (parser->m_defaultHandler)
3643 reportDefault(parser, enc, s, next);
3644 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003645 case XML_TOK_INVALID:
3646 *eventPP = next;
3647 return XML_ERROR_INVALID_TOKEN;
3648 case XML_TOK_PARTIAL_CHAR:
3649 if (haveMore) {
3650 *nextPtr = s;
3651 return XML_ERROR_NONE;
3652 }
3653 return XML_ERROR_PARTIAL_CHAR;
3654 case XML_TOK_PARTIAL:
3655 case XML_TOK_NONE:
3656 if (haveMore) {
3657 *nextPtr = s;
3658 return XML_ERROR_NONE;
3659 }
3660 return XML_ERROR_UNCLOSED_CDATA_SECTION;
3661 default:
Elliott Hughes72472942018-01-10 08:36:10 -08003662 /* Every token returned by XmlCdataSectionTok() has its own
3663 * explicit case, so this default case will never be executed.
3664 * We retain it as a safety net and exclude it from the coverage
3665 * statistics.
3666 *
3667 * LCOV_EXCL_START
Haibo Huang40a71912019-10-11 11:13:39 -07003668 */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003669 *eventPP = next;
3670 return XML_ERROR_UNEXPECTED_STATE;
Elliott Hughes72472942018-01-10 08:36:10 -08003671 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003672 }
3673
3674 *eventPP = s = next;
Elliott Hughes72472942018-01-10 08:36:10 -08003675 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003676 case XML_SUSPENDED:
3677 *nextPtr = next;
3678 return XML_ERROR_NONE;
3679 case XML_FINISHED:
3680 return XML_ERROR_ABORTED;
Haibo Huang40a71912019-10-11 11:13:39 -07003681 default:;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003682 }
3683 }
3684 /* not reached */
3685}
3686
3687#ifdef XML_DTD
3688
3689/* The idea here is to avoid using stack for each IGNORE section when
3690 the whole file is parsed with one call.
3691*/
3692static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07003693ignoreSectionProcessor(XML_Parser parser, const char *start, const char *end,
3694 const char **endPtr) {
3695 enum XML_Error result
3696 = doIgnoreSection(parser, parser->m_encoding, &start, end, endPtr,
3697 (XML_Bool)! parser->m_parsingStatus.finalBuffer);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003698 if (result != XML_ERROR_NONE)
3699 return result;
3700 if (start) {
Elliott Hughes72472942018-01-10 08:36:10 -08003701 parser->m_processor = prologProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003702 return prologProcessor(parser, start, end, endPtr);
3703 }
3704 return result;
3705}
3706
3707/* startPtr gets set to non-null is the section is closed, and to null
3708 if the section is not yet closed.
3709*/
3710static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07003711doIgnoreSection(XML_Parser parser, const ENCODING *enc, const char **startPtr,
3712 const char *end, const char **nextPtr, XML_Bool haveMore) {
Haibo Huangd1a324a2020-10-28 22:19:36 -07003713 const char *next = *startPtr; /* in case of XML_TOK_NONE or XML_TOK_PARTIAL */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003714 int tok;
3715 const char *s = *startPtr;
3716 const char **eventPP;
3717 const char **eventEndPP;
Elliott Hughes72472942018-01-10 08:36:10 -08003718 if (enc == parser->m_encoding) {
3719 eventPP = &parser->m_eventPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003720 *eventPP = s;
Elliott Hughes72472942018-01-10 08:36:10 -08003721 eventEndPP = &parser->m_eventEndPtr;
Haibo Huang40a71912019-10-11 11:13:39 -07003722 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08003723 /* It's not entirely clear, but it seems the following two lines
3724 * of code cannot be executed. The only occasions on which 'enc'
3725 * is not 'encoding' are when this function is called
3726 * from the internal entity processing, and IGNORE sections are an
3727 * error in internal entities.
3728 *
3729 * Since it really isn't clear that this is true, we keep the code
3730 * and just remove it from our coverage tests.
3731 *
3732 * LCOV_EXCL_START
3733 */
3734 eventPP = &(parser->m_openInternalEntities->internalEventPtr);
3735 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
3736 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003737 }
3738 *eventPP = s;
3739 *startPtr = NULL;
3740 tok = XmlIgnoreSectionTok(enc, s, end, &next);
3741 *eventEndPP = next;
3742 switch (tok) {
3743 case XML_TOK_IGNORE_SECT:
Elliott Hughes72472942018-01-10 08:36:10 -08003744 if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003745 reportDefault(parser, enc, s, next);
3746 *startPtr = next;
3747 *nextPtr = next;
Elliott Hughes72472942018-01-10 08:36:10 -08003748 if (parser->m_parsingStatus.parsing == XML_FINISHED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003749 return XML_ERROR_ABORTED;
3750 else
3751 return XML_ERROR_NONE;
3752 case XML_TOK_INVALID:
3753 *eventPP = next;
3754 return XML_ERROR_INVALID_TOKEN;
3755 case XML_TOK_PARTIAL_CHAR:
3756 if (haveMore) {
3757 *nextPtr = s;
3758 return XML_ERROR_NONE;
3759 }
3760 return XML_ERROR_PARTIAL_CHAR;
3761 case XML_TOK_PARTIAL:
3762 case XML_TOK_NONE:
3763 if (haveMore) {
3764 *nextPtr = s;
3765 return XML_ERROR_NONE;
3766 }
3767 return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
3768 default:
Elliott Hughes72472942018-01-10 08:36:10 -08003769 /* All of the tokens that XmlIgnoreSectionTok() returns have
3770 * explicit cases to handle them, so this default case is never
3771 * executed. We keep it as a safety net anyway, and remove it
3772 * from our test coverage statistics.
3773 *
3774 * LCOV_EXCL_START
3775 */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003776 *eventPP = next;
3777 return XML_ERROR_UNEXPECTED_STATE;
Elliott Hughes72472942018-01-10 08:36:10 -08003778 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003779 }
3780 /* not reached */
3781}
3782
3783#endif /* XML_DTD */
3784
3785static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07003786initializeEncoding(XML_Parser parser) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003787 const char *s;
3788#ifdef XML_UNICODE
3789 char encodingBuf[128];
Elliott Hughes72472942018-01-10 08:36:10 -08003790 /* See comments abount `protoclEncodingName` in parserInit() */
Haibo Huang40a71912019-10-11 11:13:39 -07003791 if (! parser->m_protocolEncodingName)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003792 s = NULL;
3793 else {
3794 int i;
Elliott Hughes72472942018-01-10 08:36:10 -08003795 for (i = 0; parser->m_protocolEncodingName[i]; i++) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003796 if (i == sizeof(encodingBuf) - 1
Elliott Hughes72472942018-01-10 08:36:10 -08003797 || (parser->m_protocolEncodingName[i] & ~0x7f) != 0) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003798 encodingBuf[0] = '\0';
3799 break;
3800 }
Elliott Hughes72472942018-01-10 08:36:10 -08003801 encodingBuf[i] = (char)parser->m_protocolEncodingName[i];
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003802 }
3803 encodingBuf[i] = '\0';
3804 s = encodingBuf;
3805 }
3806#else
Elliott Hughes72472942018-01-10 08:36:10 -08003807 s = parser->m_protocolEncodingName;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003808#endif
Haibo Huang40a71912019-10-11 11:13:39 -07003809 if ((parser->m_ns ? XmlInitEncodingNS : XmlInitEncoding)(
3810 &parser->m_initEncoding, &parser->m_encoding, s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003811 return XML_ERROR_NONE;
Elliott Hughes72472942018-01-10 08:36:10 -08003812 return handleUnknownEncoding(parser, parser->m_protocolEncodingName);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003813}
3814
3815static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07003816processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *s,
3817 const char *next) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003818 const char *encodingName = NULL;
3819 const XML_Char *storedEncName = NULL;
3820 const ENCODING *newEncoding = NULL;
3821 const char *version = NULL;
3822 const char *versionend;
3823 const XML_Char *storedversion = NULL;
3824 int standalone = -1;
Haibo Huang40a71912019-10-11 11:13:39 -07003825 if (! (parser->m_ns ? XmlParseXmlDeclNS : XmlParseXmlDecl)(
3826 isGeneralTextEntity, parser->m_encoding, s, next, &parser->m_eventPtr,
3827 &version, &versionend, &encodingName, &newEncoding, &standalone)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003828 if (isGeneralTextEntity)
3829 return XML_ERROR_TEXT_DECL;
3830 else
3831 return XML_ERROR_XML_DECL;
3832 }
Haibo Huang40a71912019-10-11 11:13:39 -07003833 if (! isGeneralTextEntity && standalone == 1) {
Elliott Hughes72472942018-01-10 08:36:10 -08003834 parser->m_dtd->standalone = XML_TRUE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003835#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07003836 if (parser->m_paramEntityParsing
3837 == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
Elliott Hughes72472942018-01-10 08:36:10 -08003838 parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003839#endif /* XML_DTD */
3840 }
Elliott Hughes72472942018-01-10 08:36:10 -08003841 if (parser->m_xmlDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003842 if (encodingName != NULL) {
Haibo Huang40a71912019-10-11 11:13:39 -07003843 storedEncName = poolStoreString(
3844 &parser->m_temp2Pool, parser->m_encoding, encodingName,
3845 encodingName + XmlNameLength(parser->m_encoding, encodingName));
3846 if (! storedEncName)
3847 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08003848 poolFinish(&parser->m_temp2Pool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003849 }
3850 if (version) {
Haibo Huang40a71912019-10-11 11:13:39 -07003851 storedversion
3852 = poolStoreString(&parser->m_temp2Pool, parser->m_encoding, version,
3853 versionend - parser->m_encoding->minBytesPerChar);
3854 if (! storedversion)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003855 return XML_ERROR_NO_MEMORY;
3856 }
Haibo Huang40a71912019-10-11 11:13:39 -07003857 parser->m_xmlDeclHandler(parser->m_handlerArg, storedversion, storedEncName,
3858 standalone);
3859 } else if (parser->m_defaultHandler)
Elliott Hughes72472942018-01-10 08:36:10 -08003860 reportDefault(parser, parser->m_encoding, s, next);
3861 if (parser->m_protocolEncodingName == NULL) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003862 if (newEncoding) {
Elliott Hughes72472942018-01-10 08:36:10 -08003863 /* Check that the specified encoding does not conflict with what
3864 * the parser has already deduced. Do we have the same number
3865 * of bytes in the smallest representation of a character? If
3866 * this is UTF-16, is it the same endianness?
3867 */
3868 if (newEncoding->minBytesPerChar != parser->m_encoding->minBytesPerChar
Haibo Huang40a71912019-10-11 11:13:39 -07003869 || (newEncoding->minBytesPerChar == 2
3870 && newEncoding != parser->m_encoding)) {
Elliott Hughes72472942018-01-10 08:36:10 -08003871 parser->m_eventPtr = encodingName;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003872 return XML_ERROR_INCORRECT_ENCODING;
3873 }
Elliott Hughes72472942018-01-10 08:36:10 -08003874 parser->m_encoding = newEncoding;
Haibo Huang40a71912019-10-11 11:13:39 -07003875 } else if (encodingName) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003876 enum XML_Error result;
Haibo Huang40a71912019-10-11 11:13:39 -07003877 if (! storedEncName) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003878 storedEncName = poolStoreString(
Haibo Huang40a71912019-10-11 11:13:39 -07003879 &parser->m_temp2Pool, parser->m_encoding, encodingName,
3880 encodingName + XmlNameLength(parser->m_encoding, encodingName));
3881 if (! storedEncName)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003882 return XML_ERROR_NO_MEMORY;
3883 }
3884 result = handleUnknownEncoding(parser, storedEncName);
Elliott Hughes72472942018-01-10 08:36:10 -08003885 poolClear(&parser->m_temp2Pool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003886 if (result == XML_ERROR_UNKNOWN_ENCODING)
Elliott Hughes72472942018-01-10 08:36:10 -08003887 parser->m_eventPtr = encodingName;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003888 return result;
3889 }
3890 }
3891
3892 if (storedEncName || storedversion)
Elliott Hughes72472942018-01-10 08:36:10 -08003893 poolClear(&parser->m_temp2Pool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003894
3895 return XML_ERROR_NONE;
3896}
3897
3898static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07003899handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) {
Elliott Hughes72472942018-01-10 08:36:10 -08003900 if (parser->m_unknownEncodingHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003901 XML_Encoding info;
3902 int i;
3903 for (i = 0; i < 256; i++)
3904 info.map[i] = -1;
3905 info.convert = NULL;
3906 info.data = NULL;
3907 info.release = NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07003908 if (parser->m_unknownEncodingHandler(parser->m_unknownEncodingHandlerData,
3909 encodingName, &info)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003910 ENCODING *enc;
Elliott Hughes72472942018-01-10 08:36:10 -08003911 parser->m_unknownEncodingMem = MALLOC(parser, XmlSizeOfUnknownEncoding());
Haibo Huang40a71912019-10-11 11:13:39 -07003912 if (! parser->m_unknownEncodingMem) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003913 if (info.release)
3914 info.release(info.data);
3915 return XML_ERROR_NO_MEMORY;
3916 }
Haibo Huang40a71912019-10-11 11:13:39 -07003917 enc = (parser->m_ns ? XmlInitUnknownEncodingNS : XmlInitUnknownEncoding)(
3918 parser->m_unknownEncodingMem, info.map, info.convert, info.data);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003919 if (enc) {
Elliott Hughes72472942018-01-10 08:36:10 -08003920 parser->m_unknownEncodingData = info.data;
3921 parser->m_unknownEncodingRelease = info.release;
3922 parser->m_encoding = enc;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003923 return XML_ERROR_NONE;
3924 }
3925 }
3926 if (info.release != NULL)
3927 info.release(info.data);
3928 }
3929 return XML_ERROR_UNKNOWN_ENCODING;
3930}
3931
3932static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07003933prologInitProcessor(XML_Parser parser, const char *s, const char *end,
3934 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003935 enum XML_Error result = initializeEncoding(parser);
3936 if (result != XML_ERROR_NONE)
3937 return result;
Elliott Hughes72472942018-01-10 08:36:10 -08003938 parser->m_processor = prologProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003939 return prologProcessor(parser, s, end, nextPtr);
3940}
3941
3942#ifdef XML_DTD
3943
3944static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07003945externalParEntInitProcessor(XML_Parser parser, const char *s, const char *end,
3946 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003947 enum XML_Error result = initializeEncoding(parser);
3948 if (result != XML_ERROR_NONE)
3949 return result;
3950
3951 /* we know now that XML_Parse(Buffer) has been called,
3952 so we consider the external parameter entity read */
Elliott Hughes72472942018-01-10 08:36:10 -08003953 parser->m_dtd->paramEntityRead = XML_TRUE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003954
Elliott Hughes72472942018-01-10 08:36:10 -08003955 if (parser->m_prologState.inEntityValue) {
3956 parser->m_processor = entityValueInitProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003957 return entityValueInitProcessor(parser, s, end, nextPtr);
Haibo Huang40a71912019-10-11 11:13:39 -07003958 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08003959 parser->m_processor = externalParEntProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003960 return externalParEntProcessor(parser, s, end, nextPtr);
3961 }
3962}
3963
3964static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07003965entityValueInitProcessor(XML_Parser parser, const char *s, const char *end,
3966 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003967 int tok;
3968 const char *start = s;
3969 const char *next = start;
Elliott Hughes72472942018-01-10 08:36:10 -08003970 parser->m_eventPtr = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003971
Elliott Hughes35e432d2012-09-09 14:23:38 -07003972 for (;;) {
Elliott Hughes72472942018-01-10 08:36:10 -08003973 tok = XmlPrologTok(parser->m_encoding, start, end, &next);
3974 parser->m_eventEndPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003975 if (tok <= 0) {
Haibo Huang40a71912019-10-11 11:13:39 -07003976 if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003977 *nextPtr = s;
3978 return XML_ERROR_NONE;
3979 }
3980 switch (tok) {
3981 case XML_TOK_INVALID:
3982 return XML_ERROR_INVALID_TOKEN;
3983 case XML_TOK_PARTIAL:
3984 return XML_ERROR_UNCLOSED_TOKEN;
3985 case XML_TOK_PARTIAL_CHAR:
3986 return XML_ERROR_PARTIAL_CHAR;
Haibo Huang40a71912019-10-11 11:13:39 -07003987 case XML_TOK_NONE: /* start == end */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003988 default:
3989 break;
3990 }
3991 /* found end of entity value - can store it now */
Elliott Hughes72472942018-01-10 08:36:10 -08003992 return storeEntityValue(parser, parser->m_encoding, s, end);
Haibo Huang40a71912019-10-11 11:13:39 -07003993 } else if (tok == XML_TOK_XML_DECL) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003994 enum XML_Error result;
3995 result = processXmlDecl(parser, 0, start, next);
3996 if (result != XML_ERROR_NONE)
3997 return result;
Haibo Huang40a71912019-10-11 11:13:39 -07003998 /* At this point, m_parsingStatus.parsing cannot be XML_SUSPENDED. For
3999 * that to happen, a parameter entity parsing handler must have attempted
4000 * to suspend the parser, which fails and raises an error. The parser can
4001 * be aborted, but can't be suspended.
Elliott Hughes72472942018-01-10 08:36:10 -08004002 */
4003 if (parser->m_parsingStatus.parsing == XML_FINISHED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004004 return XML_ERROR_ABORTED;
Elliott Hughes72472942018-01-10 08:36:10 -08004005 *nextPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004006 /* stop scanning for text declaration - we found one */
Elliott Hughes72472942018-01-10 08:36:10 -08004007 parser->m_processor = entityValueProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004008 return entityValueProcessor(parser, next, end, nextPtr);
4009 }
4010 /* If we are at the end of the buffer, this would cause XmlPrologTok to
4011 return XML_TOK_NONE on the next call, which would then cause the
4012 function to exit with *nextPtr set to s - that is what we want for other
4013 tokens, but not for the BOM - we would rather like to skip it;
4014 then, when this routine is entered the next time, XmlPrologTok will
4015 return XML_TOK_INVALID, since the BOM is still in the buffer
4016 */
Haibo Huang40a71912019-10-11 11:13:39 -07004017 else if (tok == XML_TOK_BOM && next == end
4018 && ! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004019 *nextPtr = next;
4020 return XML_ERROR_NONE;
4021 }
Elliott Hughes72472942018-01-10 08:36:10 -08004022 /* If we get this token, we have the start of what might be a
4023 normal tag, but not a declaration (i.e. it doesn't begin with
4024 "<!"). In a DTD context, that isn't legal.
4025 */
4026 else if (tok == XML_TOK_INSTANCE_START) {
4027 *nextPtr = next;
4028 return XML_ERROR_SYNTAX;
4029 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004030 start = next;
Elliott Hughes72472942018-01-10 08:36:10 -08004031 parser->m_eventPtr = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004032 }
4033}
4034
4035static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07004036externalParEntProcessor(XML_Parser parser, const char *s, const char *end,
4037 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004038 const char *next = s;
4039 int tok;
4040
Elliott Hughes72472942018-01-10 08:36:10 -08004041 tok = XmlPrologTok(parser->m_encoding, s, end, &next);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004042 if (tok <= 0) {
Haibo Huang40a71912019-10-11 11:13:39 -07004043 if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004044 *nextPtr = s;
4045 return XML_ERROR_NONE;
4046 }
4047 switch (tok) {
4048 case XML_TOK_INVALID:
4049 return XML_ERROR_INVALID_TOKEN;
4050 case XML_TOK_PARTIAL:
4051 return XML_ERROR_UNCLOSED_TOKEN;
4052 case XML_TOK_PARTIAL_CHAR:
4053 return XML_ERROR_PARTIAL_CHAR;
Haibo Huang40a71912019-10-11 11:13:39 -07004054 case XML_TOK_NONE: /* start == end */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004055 default:
4056 break;
4057 }
4058 }
4059 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
4060 However, when parsing an external subset, doProlog will not accept a BOM
4061 as valid, and report a syntax error, so we have to skip the BOM
4062 */
4063 else if (tok == XML_TOK_BOM) {
4064 s = next;
Elliott Hughes72472942018-01-10 08:36:10 -08004065 tok = XmlPrologTok(parser->m_encoding, s, end, &next);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004066 }
4067
Elliott Hughes72472942018-01-10 08:36:10 -08004068 parser->m_processor = prologProcessor;
Haibo Huang40a71912019-10-11 11:13:39 -07004069 return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
4070 (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004071}
4072
4073static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07004074entityValueProcessor(XML_Parser parser, const char *s, const char *end,
4075 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004076 const char *start = s;
4077 const char *next = s;
Elliott Hughes72472942018-01-10 08:36:10 -08004078 const ENCODING *enc = parser->m_encoding;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004079 int tok;
4080
4081 for (;;) {
4082 tok = XmlPrologTok(enc, start, end, &next);
4083 if (tok <= 0) {
Haibo Huang40a71912019-10-11 11:13:39 -07004084 if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004085 *nextPtr = s;
4086 return XML_ERROR_NONE;
4087 }
4088 switch (tok) {
4089 case XML_TOK_INVALID:
4090 return XML_ERROR_INVALID_TOKEN;
4091 case XML_TOK_PARTIAL:
4092 return XML_ERROR_UNCLOSED_TOKEN;
4093 case XML_TOK_PARTIAL_CHAR:
4094 return XML_ERROR_PARTIAL_CHAR;
Haibo Huang40a71912019-10-11 11:13:39 -07004095 case XML_TOK_NONE: /* start == end */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004096 default:
4097 break;
4098 }
4099 /* found end of entity value - can store it now */
4100 return storeEntityValue(parser, enc, s, end);
4101 }
4102 start = next;
4103 }
4104}
4105
4106#endif /* XML_DTD */
4107
4108static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07004109prologProcessor(XML_Parser parser, const char *s, const char *end,
4110 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004111 const char *next = s;
Elliott Hughes72472942018-01-10 08:36:10 -08004112 int tok = XmlPrologTok(parser->m_encoding, s, end, &next);
Haibo Huang40a71912019-10-11 11:13:39 -07004113 return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
4114 (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004115}
4116
4117static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07004118doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
4119 int tok, const char *next, const char **nextPtr, XML_Bool haveMore,
4120 XML_Bool allowClosingDoctype) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004121#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07004122 static const XML_Char externalSubsetName[] = {ASCII_HASH, '\0'};
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004123#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07004124 static const XML_Char atypeCDATA[]
4125 = {ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'};
4126 static const XML_Char atypeID[] = {ASCII_I, ASCII_D, '\0'};
4127 static const XML_Char atypeIDREF[]
4128 = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0'};
4129 static const XML_Char atypeIDREFS[]
4130 = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0'};
4131 static const XML_Char atypeENTITY[]
4132 = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0'};
4133 static const XML_Char atypeENTITIES[]
4134 = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T,
4135 ASCII_I, ASCII_E, ASCII_S, '\0'};
4136 static const XML_Char atypeNMTOKEN[]
4137 = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0'};
4138 static const XML_Char atypeNMTOKENS[]
4139 = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K,
4140 ASCII_E, ASCII_N, ASCII_S, '\0'};
4141 static const XML_Char notationPrefix[]
4142 = {ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T,
4143 ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0'};
4144 static const XML_Char enumValueSep[] = {ASCII_PIPE, '\0'};
4145 static const XML_Char enumValueStart[] = {ASCII_LPAREN, '\0'};
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004146
4147 /* save one level of indirection */
Haibo Huang40a71912019-10-11 11:13:39 -07004148 DTD *const dtd = parser->m_dtd;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004149
4150 const char **eventPP;
4151 const char **eventEndPP;
4152 enum XML_Content_Quant quant;
4153
Elliott Hughes72472942018-01-10 08:36:10 -08004154 if (enc == parser->m_encoding) {
4155 eventPP = &parser->m_eventPtr;
4156 eventEndPP = &parser->m_eventEndPtr;
Haibo Huang40a71912019-10-11 11:13:39 -07004157 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08004158 eventPP = &(parser->m_openInternalEntities->internalEventPtr);
4159 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004160 }
4161
4162 for (;;) {
4163 int role;
4164 XML_Bool handleDefault = XML_TRUE;
4165 *eventPP = s;
4166 *eventEndPP = next;
4167 if (tok <= 0) {
4168 if (haveMore && tok != XML_TOK_INVALID) {
4169 *nextPtr = s;
4170 return XML_ERROR_NONE;
4171 }
4172 switch (tok) {
4173 case XML_TOK_INVALID:
4174 *eventPP = next;
4175 return XML_ERROR_INVALID_TOKEN;
4176 case XML_TOK_PARTIAL:
4177 return XML_ERROR_UNCLOSED_TOKEN;
4178 case XML_TOK_PARTIAL_CHAR:
4179 return XML_ERROR_PARTIAL_CHAR;
Elliott Hughes35e432d2012-09-09 14:23:38 -07004180 case -XML_TOK_PROLOG_S:
4181 tok = -tok;
4182 break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004183 case XML_TOK_NONE:
4184#ifdef XML_DTD
4185 /* for internal PE NOT referenced between declarations */
Haibo Huang40a71912019-10-11 11:13:39 -07004186 if (enc != parser->m_encoding
4187 && ! parser->m_openInternalEntities->betweenDecl) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004188 *nextPtr = s;
4189 return XML_ERROR_NONE;
4190 }
4191 /* WFC: PE Between Declarations - must check that PE contains
4192 complete markup, not only for external PEs, but also for
4193 internal PEs if the reference occurs between declarations.
4194 */
Elliott Hughes72472942018-01-10 08:36:10 -08004195 if (parser->m_isParamEntity || enc != parser->m_encoding) {
4196 if (XmlTokenRole(&parser->m_prologState, XML_TOK_NONE, end, end, enc)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004197 == XML_ROLE_ERROR)
4198 return XML_ERROR_INCOMPLETE_PE;
4199 *nextPtr = s;
4200 return XML_ERROR_NONE;
4201 }
4202#endif /* XML_DTD */
4203 return XML_ERROR_NO_ELEMENTS;
4204 default:
4205 tok = -tok;
4206 next = end;
4207 break;
4208 }
4209 }
Elliott Hughes72472942018-01-10 08:36:10 -08004210 role = XmlTokenRole(&parser->m_prologState, tok, s, next, enc);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004211 switch (role) {
Haibo Huang40a71912019-10-11 11:13:39 -07004212 case XML_ROLE_XML_DECL: {
4213 enum XML_Error result = processXmlDecl(parser, 0, s, next);
4214 if (result != XML_ERROR_NONE)
4215 return result;
4216 enc = parser->m_encoding;
4217 handleDefault = XML_FALSE;
4218 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004219 case XML_ROLE_DOCTYPE_NAME:
Elliott Hughes72472942018-01-10 08:36:10 -08004220 if (parser->m_startDoctypeDeclHandler) {
Haibo Huang40a71912019-10-11 11:13:39 -07004221 parser->m_doctypeName
4222 = poolStoreString(&parser->m_tempPool, enc, s, next);
4223 if (! parser->m_doctypeName)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004224 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004225 poolFinish(&parser->m_tempPool);
4226 parser->m_doctypePubid = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004227 handleDefault = XML_FALSE;
4228 }
Elliott Hughes72472942018-01-10 08:36:10 -08004229 parser->m_doctypeSysid = NULL; /* always initialize to NULL */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004230 break;
4231 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
Elliott Hughes72472942018-01-10 08:36:10 -08004232 if (parser->m_startDoctypeDeclHandler) {
Haibo Huang40a71912019-10-11 11:13:39 -07004233 parser->m_startDoctypeDeclHandler(
4234 parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid,
4235 parser->m_doctypePubid, 1);
Elliott Hughes72472942018-01-10 08:36:10 -08004236 parser->m_doctypeName = NULL;
4237 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004238 handleDefault = XML_FALSE;
4239 }
4240 break;
4241#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07004242 case XML_ROLE_TEXT_DECL: {
4243 enum XML_Error result = processXmlDecl(parser, 1, s, next);
4244 if (result != XML_ERROR_NONE)
4245 return result;
4246 enc = parser->m_encoding;
4247 handleDefault = XML_FALSE;
4248 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004249#endif /* XML_DTD */
4250 case XML_ROLE_DOCTYPE_PUBLIC_ID:
4251#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08004252 parser->m_useForeignDTD = XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07004253 parser->m_declEntity = (ENTITY *)lookup(
4254 parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY));
4255 if (! parser->m_declEntity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004256 return XML_ERROR_NO_MEMORY;
4257#endif /* XML_DTD */
4258 dtd->hasParamEntityRefs = XML_TRUE;
Elliott Hughes72472942018-01-10 08:36:10 -08004259 if (parser->m_startDoctypeDeclHandler) {
Elliott Hughes35e432d2012-09-09 14:23:38 -07004260 XML_Char *pubId;
Haibo Huang40a71912019-10-11 11:13:39 -07004261 if (! XmlIsPublicId(enc, s, next, eventPP))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004262 return XML_ERROR_PUBLICID;
Elliott Hughes72472942018-01-10 08:36:10 -08004263 pubId = poolStoreString(&parser->m_tempPool, enc,
Elliott Hughes35e432d2012-09-09 14:23:38 -07004264 s + enc->minBytesPerChar,
4265 next - enc->minBytesPerChar);
Haibo Huang40a71912019-10-11 11:13:39 -07004266 if (! pubId)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004267 return XML_ERROR_NO_MEMORY;
Elliott Hughes35e432d2012-09-09 14:23:38 -07004268 normalizePublicId(pubId);
Elliott Hughes72472942018-01-10 08:36:10 -08004269 poolFinish(&parser->m_tempPool);
4270 parser->m_doctypePubid = pubId;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004271 handleDefault = XML_FALSE;
4272 goto alreadyChecked;
4273 }
4274 /* fall through */
4275 case XML_ROLE_ENTITY_PUBLIC_ID:
Haibo Huang40a71912019-10-11 11:13:39 -07004276 if (! XmlIsPublicId(enc, s, next, eventPP))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004277 return XML_ERROR_PUBLICID;
4278 alreadyChecked:
Elliott Hughes72472942018-01-10 08:36:10 -08004279 if (dtd->keepProcessing && parser->m_declEntity) {
Haibo Huang40a71912019-10-11 11:13:39 -07004280 XML_Char *tem
4281 = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
4282 next - enc->minBytesPerChar);
4283 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004284 return XML_ERROR_NO_MEMORY;
4285 normalizePublicId(tem);
Elliott Hughes72472942018-01-10 08:36:10 -08004286 parser->m_declEntity->publicId = tem;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004287 poolFinish(&dtd->pool);
Elliott Hughes72472942018-01-10 08:36:10 -08004288 /* Don't suppress the default handler if we fell through from
4289 * the XML_ROLE_DOCTYPE_PUBLIC_ID case.
4290 */
4291 if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_PUBLIC_ID)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004292 handleDefault = XML_FALSE;
4293 }
4294 break;
4295 case XML_ROLE_DOCTYPE_CLOSE:
Haibo Huang40a71912019-10-11 11:13:39 -07004296 if (allowClosingDoctype != XML_TRUE) {
4297 /* Must not close doctype from within expanded parameter entities */
4298 return XML_ERROR_INVALID_TOKEN;
4299 }
4300
Elliott Hughes72472942018-01-10 08:36:10 -08004301 if (parser->m_doctypeName) {
Haibo Huang40a71912019-10-11 11:13:39 -07004302 parser->m_startDoctypeDeclHandler(
4303 parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid,
4304 parser->m_doctypePubid, 0);
Elliott Hughes72472942018-01-10 08:36:10 -08004305 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004306 handleDefault = XML_FALSE;
4307 }
Elliott Hughes72472942018-01-10 08:36:10 -08004308 /* parser->m_doctypeSysid will be non-NULL in the case of a previous
4309 XML_ROLE_DOCTYPE_SYSTEM_ID, even if parser->m_startDoctypeDeclHandler
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004310 was not set, indicating an external subset
4311 */
4312#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08004313 if (parser->m_doctypeSysid || parser->m_useForeignDTD) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004314 XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
4315 dtd->hasParamEntityRefs = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07004316 if (parser->m_paramEntityParsing
4317 && parser->m_externalEntityRefHandler) {
4318 ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
4319 externalSubsetName, sizeof(ENTITY));
4320 if (! entity) {
Elliott Hughes72472942018-01-10 08:36:10 -08004321 /* The external subset name "#" will have already been
4322 * inserted into the hash table at the start of the
4323 * external entity parsing, so no allocation will happen
4324 * and lookup() cannot fail.
4325 */
4326 return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */
4327 }
4328 if (parser->m_useForeignDTD)
4329 entity->base = parser->m_curBase;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004330 dtd->paramEntityRead = XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07004331 if (! parser->m_externalEntityRefHandler(
4332 parser->m_externalEntityRefHandlerArg, 0, entity->base,
4333 entity->systemId, entity->publicId))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004334 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4335 if (dtd->paramEntityRead) {
Haibo Huang40a71912019-10-11 11:13:39 -07004336 if (! dtd->standalone && parser->m_notStandaloneHandler
4337 && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004338 return XML_ERROR_NOT_STANDALONE;
4339 }
4340 /* if we didn't read the foreign DTD then this means that there
4341 is no external subset and we must reset dtd->hasParamEntityRefs
4342 */
Haibo Huang40a71912019-10-11 11:13:39 -07004343 else if (! parser->m_doctypeSysid)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004344 dtd->hasParamEntityRefs = hadParamEntityRefs;
4345 /* end of DTD - no need to update dtd->keepProcessing */
4346 }
Elliott Hughes72472942018-01-10 08:36:10 -08004347 parser->m_useForeignDTD = XML_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004348 }
4349#endif /* XML_DTD */
Elliott Hughes72472942018-01-10 08:36:10 -08004350 if (parser->m_endDoctypeDeclHandler) {
4351 parser->m_endDoctypeDeclHandler(parser->m_handlerArg);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004352 handleDefault = XML_FALSE;
4353 }
4354 break;
4355 case XML_ROLE_INSTANCE_START:
4356#ifdef XML_DTD
4357 /* if there is no DOCTYPE declaration then now is the
4358 last chance to read the foreign DTD
4359 */
Elliott Hughes72472942018-01-10 08:36:10 -08004360 if (parser->m_useForeignDTD) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004361 XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
4362 dtd->hasParamEntityRefs = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07004363 if (parser->m_paramEntityParsing
4364 && parser->m_externalEntityRefHandler) {
Elliott Hughes35e432d2012-09-09 14:23:38 -07004365 ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
Haibo Huang40a71912019-10-11 11:13:39 -07004366 externalSubsetName, sizeof(ENTITY));
4367 if (! entity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004368 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004369 entity->base = parser->m_curBase;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004370 dtd->paramEntityRead = XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07004371 if (! parser->m_externalEntityRefHandler(
4372 parser->m_externalEntityRefHandlerArg, 0, entity->base,
4373 entity->systemId, entity->publicId))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004374 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4375 if (dtd->paramEntityRead) {
Haibo Huang40a71912019-10-11 11:13:39 -07004376 if (! dtd->standalone && parser->m_notStandaloneHandler
4377 && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004378 return XML_ERROR_NOT_STANDALONE;
4379 }
4380 /* if we didn't read the foreign DTD then this means that there
4381 is no external subset and we must reset dtd->hasParamEntityRefs
4382 */
4383 else
4384 dtd->hasParamEntityRefs = hadParamEntityRefs;
4385 /* end of DTD - no need to update dtd->keepProcessing */
4386 }
4387 }
4388#endif /* XML_DTD */
Elliott Hughes72472942018-01-10 08:36:10 -08004389 parser->m_processor = contentProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004390 return contentProcessor(parser, s, end, nextPtr);
4391 case XML_ROLE_ATTLIST_ELEMENT_NAME:
Elliott Hughes72472942018-01-10 08:36:10 -08004392 parser->m_declElementType = getElementType(parser, enc, s, next);
Haibo Huang40a71912019-10-11 11:13:39 -07004393 if (! parser->m_declElementType)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004394 return XML_ERROR_NO_MEMORY;
4395 goto checkAttListDeclHandler;
4396 case XML_ROLE_ATTRIBUTE_NAME:
Elliott Hughes72472942018-01-10 08:36:10 -08004397 parser->m_declAttributeId = getAttributeId(parser, enc, s, next);
Haibo Huang40a71912019-10-11 11:13:39 -07004398 if (! parser->m_declAttributeId)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004399 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004400 parser->m_declAttributeIsCdata = XML_FALSE;
4401 parser->m_declAttributeType = NULL;
4402 parser->m_declAttributeIsId = XML_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004403 goto checkAttListDeclHandler;
4404 case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
Elliott Hughes72472942018-01-10 08:36:10 -08004405 parser->m_declAttributeIsCdata = XML_TRUE;
4406 parser->m_declAttributeType = atypeCDATA;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004407 goto checkAttListDeclHandler;
4408 case XML_ROLE_ATTRIBUTE_TYPE_ID:
Elliott Hughes72472942018-01-10 08:36:10 -08004409 parser->m_declAttributeIsId = XML_TRUE;
4410 parser->m_declAttributeType = atypeID;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004411 goto checkAttListDeclHandler;
4412 case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
Elliott Hughes72472942018-01-10 08:36:10 -08004413 parser->m_declAttributeType = atypeIDREF;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004414 goto checkAttListDeclHandler;
4415 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
Elliott Hughes72472942018-01-10 08:36:10 -08004416 parser->m_declAttributeType = atypeIDREFS;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004417 goto checkAttListDeclHandler;
4418 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
Elliott Hughes72472942018-01-10 08:36:10 -08004419 parser->m_declAttributeType = atypeENTITY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004420 goto checkAttListDeclHandler;
4421 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
Elliott Hughes72472942018-01-10 08:36:10 -08004422 parser->m_declAttributeType = atypeENTITIES;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004423 goto checkAttListDeclHandler;
4424 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
Elliott Hughes72472942018-01-10 08:36:10 -08004425 parser->m_declAttributeType = atypeNMTOKEN;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004426 goto checkAttListDeclHandler;
4427 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
Elliott Hughes72472942018-01-10 08:36:10 -08004428 parser->m_declAttributeType = atypeNMTOKENS;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004429 checkAttListDeclHandler:
Elliott Hughes72472942018-01-10 08:36:10 -08004430 if (dtd->keepProcessing && parser->m_attlistDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004431 handleDefault = XML_FALSE;
4432 break;
4433 case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
4434 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
Elliott Hughes72472942018-01-10 08:36:10 -08004435 if (dtd->keepProcessing && parser->m_attlistDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004436 const XML_Char *prefix;
Elliott Hughes72472942018-01-10 08:36:10 -08004437 if (parser->m_declAttributeType) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004438 prefix = enumValueSep;
Haibo Huang40a71912019-10-11 11:13:39 -07004439 } else {
4440 prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE ? notationPrefix
4441 : enumValueStart);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004442 }
Haibo Huang40a71912019-10-11 11:13:39 -07004443 if (! poolAppendString(&parser->m_tempPool, prefix))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004444 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07004445 if (! poolAppend(&parser->m_tempPool, enc, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004446 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004447 parser->m_declAttributeType = parser->m_tempPool.start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004448 handleDefault = XML_FALSE;
4449 }
4450 break;
4451 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
4452 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
4453 if (dtd->keepProcessing) {
Haibo Huang40a71912019-10-11 11:13:39 -07004454 if (! defineAttribute(parser->m_declElementType,
4455 parser->m_declAttributeId,
4456 parser->m_declAttributeIsCdata,
4457 parser->m_declAttributeIsId, 0, parser))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004458 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004459 if (parser->m_attlistDeclHandler && parser->m_declAttributeType) {
4460 if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN)
4461 || (*parser->m_declAttributeType == XML_T(ASCII_N)
4462 && parser->m_declAttributeType[1] == XML_T(ASCII_O))) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004463 /* Enumerated or Notation type */
Haibo Huang40a71912019-10-11 11:13:39 -07004464 if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN))
4465 || ! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004466 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004467 parser->m_declAttributeType = parser->m_tempPool.start;
4468 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004469 }
4470 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004471 parser->m_attlistDeclHandler(
4472 parser->m_handlerArg, parser->m_declElementType->name,
4473 parser->m_declAttributeId->name, parser->m_declAttributeType, 0,
4474 role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
Elliott Hughes72472942018-01-10 08:36:10 -08004475 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004476 handleDefault = XML_FALSE;
4477 }
4478 }
4479 break;
4480 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
4481 case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
4482 if (dtd->keepProcessing) {
4483 const XML_Char *attVal;
Haibo Huang40a71912019-10-11 11:13:39 -07004484 enum XML_Error result = storeAttributeValue(
4485 parser, enc, parser->m_declAttributeIsCdata,
4486 s + enc->minBytesPerChar, next - enc->minBytesPerChar, &dtd->pool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004487 if (result)
4488 return result;
4489 attVal = poolStart(&dtd->pool);
4490 poolFinish(&dtd->pool);
4491 /* ID attributes aren't allowed to have a default */
Haibo Huang40a71912019-10-11 11:13:39 -07004492 if (! defineAttribute(
4493 parser->m_declElementType, parser->m_declAttributeId,
4494 parser->m_declAttributeIsCdata, XML_FALSE, attVal, parser))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004495 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004496 if (parser->m_attlistDeclHandler && parser->m_declAttributeType) {
4497 if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN)
4498 || (*parser->m_declAttributeType == XML_T(ASCII_N)
4499 && parser->m_declAttributeType[1] == XML_T(ASCII_O))) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004500 /* Enumerated or Notation type */
Haibo Huang40a71912019-10-11 11:13:39 -07004501 if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN))
4502 || ! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004503 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004504 parser->m_declAttributeType = parser->m_tempPool.start;
4505 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004506 }
4507 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004508 parser->m_attlistDeclHandler(
4509 parser->m_handlerArg, parser->m_declElementType->name,
4510 parser->m_declAttributeId->name, parser->m_declAttributeType,
4511 attVal, role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
Elliott Hughes72472942018-01-10 08:36:10 -08004512 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004513 handleDefault = XML_FALSE;
4514 }
4515 }
4516 break;
4517 case XML_ROLE_ENTITY_VALUE:
4518 if (dtd->keepProcessing) {
Haibo Huang40a71912019-10-11 11:13:39 -07004519 enum XML_Error result = storeEntityValue(
4520 parser, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar);
Elliott Hughes72472942018-01-10 08:36:10 -08004521 if (parser->m_declEntity) {
4522 parser->m_declEntity->textPtr = poolStart(&dtd->entityValuePool);
Haibo Huang40a71912019-10-11 11:13:39 -07004523 parser->m_declEntity->textLen
4524 = (int)(poolLength(&dtd->entityValuePool));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004525 poolFinish(&dtd->entityValuePool);
Elliott Hughes72472942018-01-10 08:36:10 -08004526 if (parser->m_entityDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004527 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004528 parser->m_entityDeclHandler(
4529 parser->m_handlerArg, parser->m_declEntity->name,
4530 parser->m_declEntity->is_param, parser->m_declEntity->textPtr,
4531 parser->m_declEntity->textLen, parser->m_curBase, 0, 0, 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004532 handleDefault = XML_FALSE;
4533 }
Haibo Huang40a71912019-10-11 11:13:39 -07004534 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004535 poolDiscard(&dtd->entityValuePool);
4536 if (result != XML_ERROR_NONE)
4537 return result;
4538 }
4539 break;
4540 case XML_ROLE_DOCTYPE_SYSTEM_ID:
4541#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08004542 parser->m_useForeignDTD = XML_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004543#endif /* XML_DTD */
4544 dtd->hasParamEntityRefs = XML_TRUE;
Elliott Hughes72472942018-01-10 08:36:10 -08004545 if (parser->m_startDoctypeDeclHandler) {
4546 parser->m_doctypeSysid = poolStoreString(&parser->m_tempPool, enc,
Haibo Huang40a71912019-10-11 11:13:39 -07004547 s + enc->minBytesPerChar,
4548 next - enc->minBytesPerChar);
Elliott Hughes72472942018-01-10 08:36:10 -08004549 if (parser->m_doctypeSysid == NULL)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004550 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004551 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004552 handleDefault = XML_FALSE;
4553 }
4554#ifdef XML_DTD
4555 else
Elliott Hughes72472942018-01-10 08:36:10 -08004556 /* use externalSubsetName to make parser->m_doctypeSysid non-NULL
4557 for the case where no parser->m_startDoctypeDeclHandler is set */
4558 parser->m_doctypeSysid = externalSubsetName;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004559#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07004560 if (! dtd->standalone
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004561#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07004562 && ! parser->m_paramEntityParsing
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004563#endif /* XML_DTD */
Elliott Hughes72472942018-01-10 08:36:10 -08004564 && parser->m_notStandaloneHandler
Haibo Huang40a71912019-10-11 11:13:39 -07004565 && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004566 return XML_ERROR_NOT_STANDALONE;
4567#ifndef XML_DTD
4568 break;
Haibo Huang40a71912019-10-11 11:13:39 -07004569#else /* XML_DTD */
4570 if (! parser->m_declEntity) {
4571 parser->m_declEntity = (ENTITY *)lookup(
4572 parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY));
4573 if (! parser->m_declEntity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004574 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004575 parser->m_declEntity->publicId = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004576 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004577#endif /* XML_DTD */
Elliott Hughesaaec48e2018-08-16 16:29:01 -07004578 /* fall through */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004579 case XML_ROLE_ENTITY_SYSTEM_ID:
Elliott Hughes72472942018-01-10 08:36:10 -08004580 if (dtd->keepProcessing && parser->m_declEntity) {
Haibo Huang40a71912019-10-11 11:13:39 -07004581 parser->m_declEntity->systemId
4582 = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
4583 next - enc->minBytesPerChar);
4584 if (! parser->m_declEntity->systemId)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004585 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004586 parser->m_declEntity->base = parser->m_curBase;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004587 poolFinish(&dtd->pool);
Elliott Hughes72472942018-01-10 08:36:10 -08004588 /* Don't suppress the default handler if we fell through from
4589 * the XML_ROLE_DOCTYPE_SYSTEM_ID case.
4590 */
4591 if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_SYSTEM_ID)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004592 handleDefault = XML_FALSE;
4593 }
4594 break;
4595 case XML_ROLE_ENTITY_COMPLETE:
Haibo Huang40a71912019-10-11 11:13:39 -07004596 if (dtd->keepProcessing && parser->m_declEntity
4597 && parser->m_entityDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004598 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004599 parser->m_entityDeclHandler(
4600 parser->m_handlerArg, parser->m_declEntity->name,
4601 parser->m_declEntity->is_param, 0, 0, parser->m_declEntity->base,
4602 parser->m_declEntity->systemId, parser->m_declEntity->publicId, 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004603 handleDefault = XML_FALSE;
4604 }
4605 break;
4606 case XML_ROLE_ENTITY_NOTATION_NAME:
Elliott Hughes72472942018-01-10 08:36:10 -08004607 if (dtd->keepProcessing && parser->m_declEntity) {
Haibo Huang40a71912019-10-11 11:13:39 -07004608 parser->m_declEntity->notation
4609 = poolStoreString(&dtd->pool, enc, s, next);
4610 if (! parser->m_declEntity->notation)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004611 return XML_ERROR_NO_MEMORY;
4612 poolFinish(&dtd->pool);
Elliott Hughes72472942018-01-10 08:36:10 -08004613 if (parser->m_unparsedEntityDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004614 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004615 parser->m_unparsedEntityDeclHandler(
4616 parser->m_handlerArg, parser->m_declEntity->name,
4617 parser->m_declEntity->base, parser->m_declEntity->systemId,
4618 parser->m_declEntity->publicId, parser->m_declEntity->notation);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004619 handleDefault = XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07004620 } else if (parser->m_entityDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004621 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004622 parser->m_entityDeclHandler(
4623 parser->m_handlerArg, parser->m_declEntity->name, 0, 0, 0,
4624 parser->m_declEntity->base, parser->m_declEntity->systemId,
4625 parser->m_declEntity->publicId, parser->m_declEntity->notation);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004626 handleDefault = XML_FALSE;
4627 }
4628 }
4629 break;
Haibo Huang40a71912019-10-11 11:13:39 -07004630 case XML_ROLE_GENERAL_ENTITY_NAME: {
4631 if (XmlPredefinedEntityName(enc, s, next)) {
4632 parser->m_declEntity = NULL;
4633 break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004634 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004635 if (dtd->keepProcessing) {
4636 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
Haibo Huang40a71912019-10-11 11:13:39 -07004637 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004638 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07004639 parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities,
4640 name, sizeof(ENTITY));
4641 if (! parser->m_declEntity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004642 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004643 if (parser->m_declEntity->name != name) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004644 poolDiscard(&dtd->pool);
Elliott Hughes72472942018-01-10 08:36:10 -08004645 parser->m_declEntity = NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07004646 } else {
4647 poolFinish(&dtd->pool);
4648 parser->m_declEntity->publicId = NULL;
4649 parser->m_declEntity->is_param = XML_FALSE;
4650 /* if we have a parent parser or are reading an internal parameter
4651 entity, then the entity declaration is not considered "internal"
4652 */
4653 parser->m_declEntity->is_internal
4654 = ! (parser->m_parentParser || parser->m_openInternalEntities);
4655 if (parser->m_entityDeclHandler)
4656 handleDefault = XML_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004657 }
Haibo Huang40a71912019-10-11 11:13:39 -07004658 } else {
4659 poolDiscard(&dtd->pool);
4660 parser->m_declEntity = NULL;
4661 }
4662 } break;
4663 case XML_ROLE_PARAM_ENTITY_NAME:
4664#ifdef XML_DTD
4665 if (dtd->keepProcessing) {
4666 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
4667 if (! name)
4668 return XML_ERROR_NO_MEMORY;
4669 parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities,
4670 name, sizeof(ENTITY));
4671 if (! parser->m_declEntity)
4672 return XML_ERROR_NO_MEMORY;
4673 if (parser->m_declEntity->name != name) {
4674 poolDiscard(&dtd->pool);
4675 parser->m_declEntity = NULL;
4676 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004677 poolFinish(&dtd->pool);
Elliott Hughes72472942018-01-10 08:36:10 -08004678 parser->m_declEntity->publicId = NULL;
4679 parser->m_declEntity->is_param = XML_TRUE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004680 /* if we have a parent parser or are reading an internal parameter
4681 entity, then the entity declaration is not considered "internal"
4682 */
Haibo Huang40a71912019-10-11 11:13:39 -07004683 parser->m_declEntity->is_internal
4684 = ! (parser->m_parentParser || parser->m_openInternalEntities);
Elliott Hughes72472942018-01-10 08:36:10 -08004685 if (parser->m_entityDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004686 handleDefault = XML_FALSE;
4687 }
Haibo Huang40a71912019-10-11 11:13:39 -07004688 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004689 poolDiscard(&dtd->pool);
Elliott Hughes72472942018-01-10 08:36:10 -08004690 parser->m_declEntity = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004691 }
Haibo Huang40a71912019-10-11 11:13:39 -07004692#else /* not XML_DTD */
Elliott Hughes72472942018-01-10 08:36:10 -08004693 parser->m_declEntity = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004694#endif /* XML_DTD */
4695 break;
4696 case XML_ROLE_NOTATION_NAME:
Elliott Hughes72472942018-01-10 08:36:10 -08004697 parser->m_declNotationPublicId = NULL;
4698 parser->m_declNotationName = NULL;
4699 if (parser->m_notationDeclHandler) {
Haibo Huang40a71912019-10-11 11:13:39 -07004700 parser->m_declNotationName
4701 = poolStoreString(&parser->m_tempPool, enc, s, next);
4702 if (! parser->m_declNotationName)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004703 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004704 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004705 handleDefault = XML_FALSE;
4706 }
4707 break;
4708 case XML_ROLE_NOTATION_PUBLIC_ID:
Haibo Huang40a71912019-10-11 11:13:39 -07004709 if (! XmlIsPublicId(enc, s, next, eventPP))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004710 return XML_ERROR_PUBLICID;
Haibo Huang40a71912019-10-11 11:13:39 -07004711 if (parser
4712 ->m_declNotationName) { /* means m_notationDeclHandler != NULL */
4713 XML_Char *tem = poolStoreString(&parser->m_tempPool, enc,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004714 s + enc->minBytesPerChar,
4715 next - enc->minBytesPerChar);
Haibo Huang40a71912019-10-11 11:13:39 -07004716 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004717 return XML_ERROR_NO_MEMORY;
4718 normalizePublicId(tem);
Elliott Hughes72472942018-01-10 08:36:10 -08004719 parser->m_declNotationPublicId = tem;
4720 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004721 handleDefault = XML_FALSE;
4722 }
4723 break;
4724 case XML_ROLE_NOTATION_SYSTEM_ID:
Elliott Hughes72472942018-01-10 08:36:10 -08004725 if (parser->m_declNotationName && parser->m_notationDeclHandler) {
Haibo Huang40a71912019-10-11 11:13:39 -07004726 const XML_Char *systemId = poolStoreString(&parser->m_tempPool, enc,
4727 s + enc->minBytesPerChar,
4728 next - enc->minBytesPerChar);
4729 if (! systemId)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004730 return XML_ERROR_NO_MEMORY;
4731 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004732 parser->m_notationDeclHandler(
4733 parser->m_handlerArg, parser->m_declNotationName, parser->m_curBase,
4734 systemId, parser->m_declNotationPublicId);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004735 handleDefault = XML_FALSE;
4736 }
Elliott Hughes72472942018-01-10 08:36:10 -08004737 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004738 break;
4739 case XML_ROLE_NOTATION_NO_SYSTEM_ID:
Elliott Hughes72472942018-01-10 08:36:10 -08004740 if (parser->m_declNotationPublicId && parser->m_notationDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004741 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004742 parser->m_notationDeclHandler(
4743 parser->m_handlerArg, parser->m_declNotationName, parser->m_curBase,
4744 0, parser->m_declNotationPublicId);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004745 handleDefault = XML_FALSE;
4746 }
Elliott Hughes72472942018-01-10 08:36:10 -08004747 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004748 break;
4749 case XML_ROLE_ERROR:
4750 switch (tok) {
4751 case XML_TOK_PARAM_ENTITY_REF:
4752 /* PE references in internal subset are
Elliott Hughes35e432d2012-09-09 14:23:38 -07004753 not allowed within declarations. */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004754 return XML_ERROR_PARAM_ENTITY_REF;
4755 case XML_TOK_XML_DECL:
4756 return XML_ERROR_MISPLACED_XML_PI;
4757 default:
4758 return XML_ERROR_SYNTAX;
4759 }
4760#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07004761 case XML_ROLE_IGNORE_SECT: {
4762 enum XML_Error result;
4763 if (parser->m_defaultHandler)
4764 reportDefault(parser, enc, s, next);
4765 handleDefault = XML_FALSE;
4766 result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
4767 if (result != XML_ERROR_NONE)
4768 return result;
4769 else if (! next) {
4770 parser->m_processor = ignoreSectionProcessor;
4771 return result;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004772 }
Haibo Huang40a71912019-10-11 11:13:39 -07004773 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004774#endif /* XML_DTD */
4775 case XML_ROLE_GROUP_OPEN:
Elliott Hughes72472942018-01-10 08:36:10 -08004776 if (parser->m_prologState.level >= parser->m_groupSize) {
4777 if (parser->m_groupSize) {
Haibo Huang40a71912019-10-11 11:13:39 -07004778 {
4779 char *const new_connector = (char *)REALLOC(
4780 parser, parser->m_groupConnector, parser->m_groupSize *= 2);
4781 if (new_connector == NULL) {
4782 parser->m_groupSize /= 2;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004783 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07004784 }
4785 parser->m_groupConnector = new_connector;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004786 }
Haibo Huang40a71912019-10-11 11:13:39 -07004787
4788 if (dtd->scaffIndex) {
4789 int *const new_scaff_index = (int *)REALLOC(
4790 parser, dtd->scaffIndex, parser->m_groupSize * sizeof(int));
4791 if (new_scaff_index == NULL)
4792 return XML_ERROR_NO_MEMORY;
4793 dtd->scaffIndex = new_scaff_index;
4794 }
4795 } else {
4796 parser->m_groupConnector
4797 = (char *)MALLOC(parser, parser->m_groupSize = 32);
4798 if (! parser->m_groupConnector) {
Elliott Hughes72472942018-01-10 08:36:10 -08004799 parser->m_groupSize = 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004800 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004801 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004802 }
4803 }
Elliott Hughes72472942018-01-10 08:36:10 -08004804 parser->m_groupConnector[parser->m_prologState.level] = 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004805 if (dtd->in_eldecl) {
4806 int myindex = nextScaffoldPart(parser);
4807 if (myindex < 0)
4808 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07004809 assert(dtd->scaffIndex != NULL);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004810 dtd->scaffIndex[dtd->scaffLevel] = myindex;
4811 dtd->scaffLevel++;
4812 dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
Elliott Hughes72472942018-01-10 08:36:10 -08004813 if (parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004814 handleDefault = XML_FALSE;
4815 }
4816 break;
4817 case XML_ROLE_GROUP_SEQUENCE:
Elliott Hughes72472942018-01-10 08:36:10 -08004818 if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_PIPE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004819 return XML_ERROR_SYNTAX;
Elliott Hughes72472942018-01-10 08:36:10 -08004820 parser->m_groupConnector[parser->m_prologState.level] = ASCII_COMMA;
4821 if (dtd->in_eldecl && parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004822 handleDefault = XML_FALSE;
4823 break;
4824 case XML_ROLE_GROUP_CHOICE:
Elliott Hughes72472942018-01-10 08:36:10 -08004825 if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_COMMA)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004826 return XML_ERROR_SYNTAX;
4827 if (dtd->in_eldecl
Haibo Huang40a71912019-10-11 11:13:39 -07004828 && ! parser->m_groupConnector[parser->m_prologState.level]
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004829 && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
Haibo Huang40a71912019-10-11 11:13:39 -07004830 != XML_CTYPE_MIXED)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004831 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4832 = XML_CTYPE_CHOICE;
Elliott Hughes72472942018-01-10 08:36:10 -08004833 if (parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004834 handleDefault = XML_FALSE;
4835 }
Elliott Hughes72472942018-01-10 08:36:10 -08004836 parser->m_groupConnector[parser->m_prologState.level] = ASCII_PIPE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004837 break;
4838 case XML_ROLE_PARAM_ENTITY_REF:
4839#ifdef XML_DTD
4840 case XML_ROLE_INNER_PARAM_ENTITY_REF:
4841 dtd->hasParamEntityRefs = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07004842 if (! parser->m_paramEntityParsing)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004843 dtd->keepProcessing = dtd->standalone;
4844 else {
4845 const XML_Char *name;
4846 ENTITY *entity;
Haibo Huang40a71912019-10-11 11:13:39 -07004847 name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
4848 next - enc->minBytesPerChar);
4849 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004850 return XML_ERROR_NO_MEMORY;
Elliott Hughes35e432d2012-09-09 14:23:38 -07004851 entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004852 poolDiscard(&dtd->pool);
4853 /* first, determine if a check for an existing declaration is needed;
4854 if yes, check that the entity exists, and that it is internal,
4855 otherwise call the skipped entity handler
4856 */
Haibo Huang40a71912019-10-11 11:13:39 -07004857 if (parser->m_prologState.documentEntity
4858 && (dtd->standalone ? ! parser->m_openInternalEntities
4859 : ! dtd->hasParamEntityRefs)) {
4860 if (! entity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004861 return XML_ERROR_UNDEFINED_ENTITY;
Haibo Huang40a71912019-10-11 11:13:39 -07004862 else if (! entity->is_internal) {
Elliott Hughes72472942018-01-10 08:36:10 -08004863 /* It's hard to exhaustively search the code to be sure,
4864 * but there doesn't seem to be a way of executing the
4865 * following line. There are two cases:
4866 *
4867 * If 'standalone' is false, the DTD must have no
4868 * parameter entities or we wouldn't have passed the outer
4869 * 'if' statement. That measn the only entity in the hash
4870 * table is the external subset name "#" which cannot be
4871 * given as a parameter entity name in XML syntax, so the
4872 * lookup must have returned NULL and we don't even reach
4873 * the test for an internal entity.
4874 *
4875 * If 'standalone' is true, it does not seem to be
4876 * possible to create entities taking this code path that
4877 * are not internal entities, so fail the test above.
4878 *
4879 * Because this analysis is very uncertain, the code is
4880 * being left in place and merely removed from the
4881 * coverage test statistics.
4882 */
4883 return XML_ERROR_ENTITY_DECLARED_IN_PE; /* LCOV_EXCL_LINE */
4884 }
Haibo Huang40a71912019-10-11 11:13:39 -07004885 } else if (! entity) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004886 dtd->keepProcessing = dtd->standalone;
4887 /* cannot report skipped entities in declarations */
Haibo Huang40a71912019-10-11 11:13:39 -07004888 if ((role == XML_ROLE_PARAM_ENTITY_REF)
4889 && parser->m_skippedEntityHandler) {
Elliott Hughes72472942018-01-10 08:36:10 -08004890 parser->m_skippedEntityHandler(parser->m_handlerArg, name, 1);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004891 handleDefault = XML_FALSE;
4892 }
4893 break;
4894 }
4895 if (entity->open)
4896 return XML_ERROR_RECURSIVE_ENTITY_REF;
4897 if (entity->textPtr) {
4898 enum XML_Error result;
Haibo Huang40a71912019-10-11 11:13:39 -07004899 XML_Bool betweenDecl
4900 = (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004901 result = processInternalEntity(parser, entity, betweenDecl);
4902 if (result != XML_ERROR_NONE)
4903 return result;
4904 handleDefault = XML_FALSE;
4905 break;
4906 }
Elliott Hughes72472942018-01-10 08:36:10 -08004907 if (parser->m_externalEntityRefHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004908 dtd->paramEntityRead = XML_FALSE;
4909 entity->open = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07004910 if (! parser->m_externalEntityRefHandler(
4911 parser->m_externalEntityRefHandlerArg, 0, entity->base,
4912 entity->systemId, entity->publicId)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004913 entity->open = XML_FALSE;
4914 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4915 }
4916 entity->open = XML_FALSE;
4917 handleDefault = XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07004918 if (! dtd->paramEntityRead) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004919 dtd->keepProcessing = dtd->standalone;
4920 break;
4921 }
Haibo Huang40a71912019-10-11 11:13:39 -07004922 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004923 dtd->keepProcessing = dtd->standalone;
4924 break;
4925 }
4926 }
4927#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07004928 if (! dtd->standalone && parser->m_notStandaloneHandler
4929 && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004930 return XML_ERROR_NOT_STANDALONE;
4931 break;
4932
Haibo Huang40a71912019-10-11 11:13:39 -07004933 /* Element declaration stuff */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004934
4935 case XML_ROLE_ELEMENT_NAME:
Elliott Hughes72472942018-01-10 08:36:10 -08004936 if (parser->m_elementDeclHandler) {
4937 parser->m_declElementType = getElementType(parser, enc, s, next);
Haibo Huang40a71912019-10-11 11:13:39 -07004938 if (! parser->m_declElementType)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004939 return XML_ERROR_NO_MEMORY;
4940 dtd->scaffLevel = 0;
4941 dtd->scaffCount = 0;
4942 dtd->in_eldecl = XML_TRUE;
4943 handleDefault = XML_FALSE;
4944 }
4945 break;
4946
4947 case XML_ROLE_CONTENT_ANY:
4948 case XML_ROLE_CONTENT_EMPTY:
4949 if (dtd->in_eldecl) {
Elliott Hughes72472942018-01-10 08:36:10 -08004950 if (parser->m_elementDeclHandler) {
Haibo Huang40a71912019-10-11 11:13:39 -07004951 XML_Content *content
4952 = (XML_Content *)MALLOC(parser, sizeof(XML_Content));
4953 if (! content)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004954 return XML_ERROR_NO_MEMORY;
4955 content->quant = XML_CQUANT_NONE;
4956 content->name = NULL;
4957 content->numchildren = 0;
4958 content->children = NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07004959 content->type = ((role == XML_ROLE_CONTENT_ANY) ? XML_CTYPE_ANY
4960 : XML_CTYPE_EMPTY);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004961 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004962 parser->m_elementDeclHandler(
4963 parser->m_handlerArg, parser->m_declElementType->name, content);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004964 handleDefault = XML_FALSE;
4965 }
4966 dtd->in_eldecl = XML_FALSE;
4967 }
4968 break;
4969
4970 case XML_ROLE_CONTENT_PCDATA:
4971 if (dtd->in_eldecl) {
4972 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4973 = XML_CTYPE_MIXED;
Elliott Hughes72472942018-01-10 08:36:10 -08004974 if (parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004975 handleDefault = XML_FALSE;
4976 }
4977 break;
4978
4979 case XML_ROLE_CONTENT_ELEMENT:
4980 quant = XML_CQUANT_NONE;
4981 goto elementContent;
4982 case XML_ROLE_CONTENT_ELEMENT_OPT:
4983 quant = XML_CQUANT_OPT;
4984 goto elementContent;
4985 case XML_ROLE_CONTENT_ELEMENT_REP:
4986 quant = XML_CQUANT_REP;
4987 goto elementContent;
4988 case XML_ROLE_CONTENT_ELEMENT_PLUS:
4989 quant = XML_CQUANT_PLUS;
4990 elementContent:
4991 if (dtd->in_eldecl) {
4992 ELEMENT_TYPE *el;
4993 const XML_Char *name;
4994 int nameLen;
Haibo Huang40a71912019-10-11 11:13:39 -07004995 const char *nxt
4996 = (quant == XML_CQUANT_NONE ? next : next - enc->minBytesPerChar);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004997 int myindex = nextScaffoldPart(parser);
4998 if (myindex < 0)
4999 return XML_ERROR_NO_MEMORY;
5000 dtd->scaffold[myindex].type = XML_CTYPE_NAME;
5001 dtd->scaffold[myindex].quant = quant;
5002 el = getElementType(parser, enc, s, nxt);
Haibo Huang40a71912019-10-11 11:13:39 -07005003 if (! el)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005004 return XML_ERROR_NO_MEMORY;
5005 name = el->name;
5006 dtd->scaffold[myindex].name = name;
5007 nameLen = 0;
Haibo Huang40a71912019-10-11 11:13:39 -07005008 for (; name[nameLen++];)
5009 ;
5010 dtd->contentStringLen += nameLen;
Elliott Hughes72472942018-01-10 08:36:10 -08005011 if (parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005012 handleDefault = XML_FALSE;
5013 }
5014 break;
5015
5016 case XML_ROLE_GROUP_CLOSE:
5017 quant = XML_CQUANT_NONE;
5018 goto closeGroup;
5019 case XML_ROLE_GROUP_CLOSE_OPT:
5020 quant = XML_CQUANT_OPT;
5021 goto closeGroup;
5022 case XML_ROLE_GROUP_CLOSE_REP:
5023 quant = XML_CQUANT_REP;
5024 goto closeGroup;
5025 case XML_ROLE_GROUP_CLOSE_PLUS:
5026 quant = XML_CQUANT_PLUS;
5027 closeGroup:
5028 if (dtd->in_eldecl) {
Elliott Hughes72472942018-01-10 08:36:10 -08005029 if (parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005030 handleDefault = XML_FALSE;
5031 dtd->scaffLevel--;
5032 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
5033 if (dtd->scaffLevel == 0) {
Haibo Huang40a71912019-10-11 11:13:39 -07005034 if (! handleDefault) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005035 XML_Content *model = build_model(parser);
Haibo Huang40a71912019-10-11 11:13:39 -07005036 if (! model)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005037 return XML_ERROR_NO_MEMORY;
5038 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07005039 parser->m_elementDeclHandler(
5040 parser->m_handlerArg, parser->m_declElementType->name, model);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005041 }
5042 dtd->in_eldecl = XML_FALSE;
5043 dtd->contentStringLen = 0;
5044 }
5045 }
5046 break;
5047 /* End element declaration stuff */
5048
5049 case XML_ROLE_PI:
Haibo Huang40a71912019-10-11 11:13:39 -07005050 if (! reportProcessingInstruction(parser, enc, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005051 return XML_ERROR_NO_MEMORY;
5052 handleDefault = XML_FALSE;
5053 break;
5054 case XML_ROLE_COMMENT:
Haibo Huang40a71912019-10-11 11:13:39 -07005055 if (! reportComment(parser, enc, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005056 return XML_ERROR_NO_MEMORY;
5057 handleDefault = XML_FALSE;
5058 break;
5059 case XML_ROLE_NONE:
5060 switch (tok) {
5061 case XML_TOK_BOM:
5062 handleDefault = XML_FALSE;
5063 break;
5064 }
5065 break;
5066 case XML_ROLE_DOCTYPE_NONE:
Elliott Hughes72472942018-01-10 08:36:10 -08005067 if (parser->m_startDoctypeDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005068 handleDefault = XML_FALSE;
5069 break;
5070 case XML_ROLE_ENTITY_NONE:
Elliott Hughes72472942018-01-10 08:36:10 -08005071 if (dtd->keepProcessing && parser->m_entityDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005072 handleDefault = XML_FALSE;
5073 break;
5074 case XML_ROLE_NOTATION_NONE:
Elliott Hughes72472942018-01-10 08:36:10 -08005075 if (parser->m_notationDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005076 handleDefault = XML_FALSE;
5077 break;
5078 case XML_ROLE_ATTLIST_NONE:
Elliott Hughes72472942018-01-10 08:36:10 -08005079 if (dtd->keepProcessing && parser->m_attlistDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005080 handleDefault = XML_FALSE;
5081 break;
5082 case XML_ROLE_ELEMENT_NONE:
Elliott Hughes72472942018-01-10 08:36:10 -08005083 if (parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005084 handleDefault = XML_FALSE;
5085 break;
5086 } /* end of big switch */
5087
Elliott Hughes72472942018-01-10 08:36:10 -08005088 if (handleDefault && parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005089 reportDefault(parser, enc, s, next);
5090
Elliott Hughes72472942018-01-10 08:36:10 -08005091 switch (parser->m_parsingStatus.parsing) {
Elliott Hughes35e432d2012-09-09 14:23:38 -07005092 case XML_SUSPENDED:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005093 *nextPtr = next;
5094 return XML_ERROR_NONE;
5095 case XML_FINISHED:
5096 return XML_ERROR_ABORTED;
5097 default:
5098 s = next;
5099 tok = XmlPrologTok(enc, s, end, &next);
5100 }
5101 }
5102 /* not reached */
5103}
5104
5105static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07005106epilogProcessor(XML_Parser parser, const char *s, const char *end,
5107 const char **nextPtr) {
Elliott Hughes72472942018-01-10 08:36:10 -08005108 parser->m_processor = epilogProcessor;
5109 parser->m_eventPtr = s;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005110 for (;;) {
5111 const char *next = NULL;
Elliott Hughes72472942018-01-10 08:36:10 -08005112 int tok = XmlPrologTok(parser->m_encoding, s, end, &next);
5113 parser->m_eventEndPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005114 switch (tok) {
5115 /* report partial linebreak - it might be the last token */
5116 case -XML_TOK_PROLOG_S:
Elliott Hughes72472942018-01-10 08:36:10 -08005117 if (parser->m_defaultHandler) {
5118 reportDefault(parser, parser->m_encoding, s, next);
5119 if (parser->m_parsingStatus.parsing == XML_FINISHED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005120 return XML_ERROR_ABORTED;
5121 }
5122 *nextPtr = next;
5123 return XML_ERROR_NONE;
5124 case XML_TOK_NONE:
5125 *nextPtr = s;
5126 return XML_ERROR_NONE;
5127 case XML_TOK_PROLOG_S:
Elliott Hughes72472942018-01-10 08:36:10 -08005128 if (parser->m_defaultHandler)
5129 reportDefault(parser, parser->m_encoding, s, next);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005130 break;
5131 case XML_TOK_PI:
Haibo Huang40a71912019-10-11 11:13:39 -07005132 if (! reportProcessingInstruction(parser, parser->m_encoding, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005133 return XML_ERROR_NO_MEMORY;
5134 break;
5135 case XML_TOK_COMMENT:
Haibo Huang40a71912019-10-11 11:13:39 -07005136 if (! reportComment(parser, parser->m_encoding, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005137 return XML_ERROR_NO_MEMORY;
5138 break;
5139 case XML_TOK_INVALID:
Elliott Hughes72472942018-01-10 08:36:10 -08005140 parser->m_eventPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005141 return XML_ERROR_INVALID_TOKEN;
5142 case XML_TOK_PARTIAL:
Haibo Huang40a71912019-10-11 11:13:39 -07005143 if (! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005144 *nextPtr = s;
5145 return XML_ERROR_NONE;
5146 }
5147 return XML_ERROR_UNCLOSED_TOKEN;
5148 case XML_TOK_PARTIAL_CHAR:
Haibo Huang40a71912019-10-11 11:13:39 -07005149 if (! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005150 *nextPtr = s;
5151 return XML_ERROR_NONE;
5152 }
5153 return XML_ERROR_PARTIAL_CHAR;
5154 default:
5155 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
5156 }
Elliott Hughes72472942018-01-10 08:36:10 -08005157 parser->m_eventPtr = s = next;
5158 switch (parser->m_parsingStatus.parsing) {
Elliott Hughes35e432d2012-09-09 14:23:38 -07005159 case XML_SUSPENDED:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005160 *nextPtr = next;
5161 return XML_ERROR_NONE;
5162 case XML_FINISHED:
5163 return XML_ERROR_ABORTED;
Haibo Huang40a71912019-10-11 11:13:39 -07005164 default:;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005165 }
5166 }
5167}
5168
5169static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07005170processInternalEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005171 const char *textStart, *textEnd;
5172 const char *next;
5173 enum XML_Error result;
5174 OPEN_INTERNAL_ENTITY *openEntity;
5175
Elliott Hughes72472942018-01-10 08:36:10 -08005176 if (parser->m_freeInternalEntities) {
5177 openEntity = parser->m_freeInternalEntities;
5178 parser->m_freeInternalEntities = openEntity->next;
Haibo Huang40a71912019-10-11 11:13:39 -07005179 } else {
5180 openEntity
5181 = (OPEN_INTERNAL_ENTITY *)MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY));
5182 if (! openEntity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005183 return XML_ERROR_NO_MEMORY;
5184 }
5185 entity->open = XML_TRUE;
5186 entity->processed = 0;
Elliott Hughes72472942018-01-10 08:36:10 -08005187 openEntity->next = parser->m_openInternalEntities;
5188 parser->m_openInternalEntities = openEntity;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005189 openEntity->entity = entity;
Elliott Hughes72472942018-01-10 08:36:10 -08005190 openEntity->startTagLevel = parser->m_tagLevel;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005191 openEntity->betweenDecl = betweenDecl;
5192 openEntity->internalEventPtr = NULL;
5193 openEntity->internalEventEndPtr = NULL;
Haibo Huangd1a324a2020-10-28 22:19:36 -07005194 textStart = (const char *)entity->textPtr;
5195 textEnd = (const char *)(entity->textPtr + entity->textLen);
Elliott Hughes72472942018-01-10 08:36:10 -08005196 /* Set a safe default value in case 'next' does not get set */
5197 next = textStart;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005198
5199#ifdef XML_DTD
5200 if (entity->is_param) {
Haibo Huang40a71912019-10-11 11:13:39 -07005201 int tok
5202 = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
5203 result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
5204 tok, next, &next, XML_FALSE, XML_FALSE);
5205 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005206#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07005207 result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding,
5208 textStart, textEnd, &next, XML_FALSE);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005209
5210 if (result == XML_ERROR_NONE) {
Elliott Hughes72472942018-01-10 08:36:10 -08005211 if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005212 entity->processed = (int)(next - textStart);
Elliott Hughes72472942018-01-10 08:36:10 -08005213 parser->m_processor = internalEntityProcessor;
Haibo Huang40a71912019-10-11 11:13:39 -07005214 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005215 entity->open = XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08005216 parser->m_openInternalEntities = openEntity->next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005217 /* put openEntity back in list of free instances */
Elliott Hughes72472942018-01-10 08:36:10 -08005218 openEntity->next = parser->m_freeInternalEntities;
5219 parser->m_freeInternalEntities = openEntity;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005220 }
5221 }
5222 return result;
5223}
5224
5225static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07005226internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
5227 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005228 ENTITY *entity;
5229 const char *textStart, *textEnd;
5230 const char *next;
5231 enum XML_Error result;
Elliott Hughes72472942018-01-10 08:36:10 -08005232 OPEN_INTERNAL_ENTITY *openEntity = parser->m_openInternalEntities;
Haibo Huang40a71912019-10-11 11:13:39 -07005233 if (! openEntity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005234 return XML_ERROR_UNEXPECTED_STATE;
5235
5236 entity = openEntity->entity;
Haibo Huangd1a324a2020-10-28 22:19:36 -07005237 textStart = ((const char *)entity->textPtr) + entity->processed;
5238 textEnd = (const char *)(entity->textPtr + entity->textLen);
Elliott Hughes72472942018-01-10 08:36:10 -08005239 /* Set a safe default value in case 'next' does not get set */
5240 next = textStart;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005241
5242#ifdef XML_DTD
5243 if (entity->is_param) {
Haibo Huang40a71912019-10-11 11:13:39 -07005244 int tok
5245 = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
5246 result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
5247 tok, next, &next, XML_FALSE, XML_TRUE);
5248 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005249#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07005250 result = doContent(parser, openEntity->startTagLevel,
5251 parser->m_internalEncoding, textStart, textEnd, &next,
5252 XML_FALSE);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005253
5254 if (result != XML_ERROR_NONE)
5255 return result;
Haibo Huang40a71912019-10-11 11:13:39 -07005256 else if (textEnd != next
5257 && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
Haibo Huangd1a324a2020-10-28 22:19:36 -07005258 entity->processed = (int)(next - (const char *)entity->textPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005259 return result;
Haibo Huang40a71912019-10-11 11:13:39 -07005260 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005261 entity->open = XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08005262 parser->m_openInternalEntities = openEntity->next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005263 /* put openEntity back in list of free instances */
Elliott Hughes72472942018-01-10 08:36:10 -08005264 openEntity->next = parser->m_freeInternalEntities;
5265 parser->m_freeInternalEntities = openEntity;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005266 }
5267
5268#ifdef XML_DTD
5269 if (entity->is_param) {
5270 int tok;
Elliott Hughes72472942018-01-10 08:36:10 -08005271 parser->m_processor = prologProcessor;
5272 tok = XmlPrologTok(parser->m_encoding, s, end, &next);
5273 return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
Haibo Huang40a71912019-10-11 11:13:39 -07005274 (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE);
5275 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005276#endif /* XML_DTD */
5277 {
Elliott Hughes72472942018-01-10 08:36:10 -08005278 parser->m_processor = contentProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005279 /* see externalEntityContentProcessor vs contentProcessor */
Haibo Huang40a71912019-10-11 11:13:39 -07005280 return doContent(parser, parser->m_parentParser ? 1 : 0, parser->m_encoding,
5281 s, end, nextPtr,
5282 (XML_Bool)! parser->m_parsingStatus.finalBuffer);
Elliott Hughes35e432d2012-09-09 14:23:38 -07005283 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005284}
5285
5286static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07005287errorProcessor(XML_Parser parser, const char *s, const char *end,
5288 const char **nextPtr) {
5289 UNUSED_P(s);
5290 UNUSED_P(end);
5291 UNUSED_P(nextPtr);
Elliott Hughes72472942018-01-10 08:36:10 -08005292 return parser->m_errorCode;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005293}
5294
5295static enum XML_Error
5296storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
Haibo Huang40a71912019-10-11 11:13:39 -07005297 const char *ptr, const char *end, STRING_POOL *pool) {
5298 enum XML_Error result
5299 = appendAttributeValue(parser, enc, isCdata, ptr, end, pool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005300 if (result)
5301 return result;
Haibo Huang40a71912019-10-11 11:13:39 -07005302 if (! isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005303 poolChop(pool);
Haibo Huang40a71912019-10-11 11:13:39 -07005304 if (! poolAppendChar(pool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005305 return XML_ERROR_NO_MEMORY;
5306 return XML_ERROR_NONE;
5307}
5308
5309static enum XML_Error
5310appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
Haibo Huang40a71912019-10-11 11:13:39 -07005311 const char *ptr, const char *end, STRING_POOL *pool) {
5312 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005313 for (;;) {
5314 const char *next;
5315 int tok = XmlAttributeValueTok(enc, ptr, end, &next);
5316 switch (tok) {
5317 case XML_TOK_NONE:
5318 return XML_ERROR_NONE;
5319 case XML_TOK_INVALID:
Elliott Hughes72472942018-01-10 08:36:10 -08005320 if (enc == parser->m_encoding)
5321 parser->m_eventPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005322 return XML_ERROR_INVALID_TOKEN;
5323 case XML_TOK_PARTIAL:
Elliott Hughes72472942018-01-10 08:36:10 -08005324 if (enc == parser->m_encoding)
5325 parser->m_eventPtr = ptr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005326 return XML_ERROR_INVALID_TOKEN;
Haibo Huang40a71912019-10-11 11:13:39 -07005327 case XML_TOK_CHAR_REF: {
5328 XML_Char buf[XML_ENCODE_MAX];
5329 int i;
5330 int n = XmlCharRefNumber(enc, ptr);
5331 if (n < 0) {
5332 if (enc == parser->m_encoding)
5333 parser->m_eventPtr = ptr;
5334 return XML_ERROR_BAD_CHAR_REF;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005335 }
Haibo Huang40a71912019-10-11 11:13:39 -07005336 if (! isCdata && n == 0x20 /* space */
5337 && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
5338 break;
5339 n = XmlEncode(n, (ICHAR *)buf);
5340 /* The XmlEncode() functions can never return 0 here. That
5341 * error return happens if the code point passed in is either
5342 * negative or greater than or equal to 0x110000. The
5343 * XmlCharRefNumber() functions will all return a number
5344 * strictly less than 0x110000 or a negative value if an error
5345 * occurred. The negative value is intercepted above, so
5346 * XmlEncode() is never passed a value it might return an
5347 * error for.
5348 */
5349 for (i = 0; i < n; i++) {
5350 if (! poolAppendChar(pool, buf[i]))
5351 return XML_ERROR_NO_MEMORY;
5352 }
5353 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005354 case XML_TOK_DATA_CHARS:
Haibo Huang40a71912019-10-11 11:13:39 -07005355 if (! poolAppend(pool, enc, ptr, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005356 return XML_ERROR_NO_MEMORY;
5357 break;
5358 case XML_TOK_TRAILING_CR:
5359 next = ptr + enc->minBytesPerChar;
5360 /* fall through */
5361 case XML_TOK_ATTRIBUTE_VALUE_S:
5362 case XML_TOK_DATA_NEWLINE:
Haibo Huang40a71912019-10-11 11:13:39 -07005363 if (! isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005364 break;
Haibo Huang40a71912019-10-11 11:13:39 -07005365 if (! poolAppendChar(pool, 0x20))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005366 return XML_ERROR_NO_MEMORY;
5367 break;
Haibo Huang40a71912019-10-11 11:13:39 -07005368 case XML_TOK_ENTITY_REF: {
5369 const XML_Char *name;
5370 ENTITY *entity;
5371 char checkEntityDecl;
5372 XML_Char ch = (XML_Char)XmlPredefinedEntityName(
5373 enc, ptr + enc->minBytesPerChar, next - enc->minBytesPerChar);
5374 if (ch) {
5375 if (! poolAppendChar(pool, ch))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005376 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07005377 break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005378 }
Haibo Huang40a71912019-10-11 11:13:39 -07005379 name = poolStoreString(&parser->m_temp2Pool, enc,
5380 ptr + enc->minBytesPerChar,
5381 next - enc->minBytesPerChar);
5382 if (! name)
5383 return XML_ERROR_NO_MEMORY;
5384 entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
5385 poolDiscard(&parser->m_temp2Pool);
5386 /* First, determine if a check for an existing declaration is needed;
5387 if yes, check that the entity exists, and that it is internal.
5388 */
5389 if (pool == &dtd->pool) /* are we called from prolog? */
5390 checkEntityDecl =
5391#ifdef XML_DTD
5392 parser->m_prologState.documentEntity &&
5393#endif /* XML_DTD */
5394 (dtd->standalone ? ! parser->m_openInternalEntities
5395 : ! dtd->hasParamEntityRefs);
5396 else /* if (pool == &parser->m_tempPool): we are called from content */
5397 checkEntityDecl = ! dtd->hasParamEntityRefs || dtd->standalone;
5398 if (checkEntityDecl) {
5399 if (! entity)
5400 return XML_ERROR_UNDEFINED_ENTITY;
5401 else if (! entity->is_internal)
5402 return XML_ERROR_ENTITY_DECLARED_IN_PE;
5403 } else if (! entity) {
5404 /* Cannot report skipped entity here - see comments on
5405 parser->m_skippedEntityHandler.
5406 if (parser->m_skippedEntityHandler)
5407 parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
5408 */
5409 /* Cannot call the default handler because this would be
5410 out of sync with the call to the startElementHandler.
5411 if ((pool == &parser->m_tempPool) && parser->m_defaultHandler)
5412 reportDefault(parser, enc, ptr, next);
5413 */
5414 break;
5415 }
5416 if (entity->open) {
5417 if (enc == parser->m_encoding) {
5418 /* It does not appear that this line can be executed.
5419 *
5420 * The "if (entity->open)" check catches recursive entity
5421 * definitions. In order to be called with an open
5422 * entity, it must have gone through this code before and
5423 * been through the recursive call to
5424 * appendAttributeValue() some lines below. That call
5425 * sets the local encoding ("enc") to the parser's
5426 * internal encoding (internal_utf8 or internal_utf16),
5427 * which can never be the same as the principle encoding.
5428 * It doesn't appear there is another code path that gets
5429 * here with entity->open being TRUE.
5430 *
5431 * Since it is not certain that this logic is watertight,
5432 * we keep the line and merely exclude it from coverage
5433 * tests.
5434 */
5435 parser->m_eventPtr = ptr; /* LCOV_EXCL_LINE */
5436 }
5437 return XML_ERROR_RECURSIVE_ENTITY_REF;
5438 }
5439 if (entity->notation) {
5440 if (enc == parser->m_encoding)
5441 parser->m_eventPtr = ptr;
5442 return XML_ERROR_BINARY_ENTITY_REF;
5443 }
5444 if (! entity->textPtr) {
5445 if (enc == parser->m_encoding)
5446 parser->m_eventPtr = ptr;
5447 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
5448 } else {
5449 enum XML_Error result;
5450 const XML_Char *textEnd = entity->textPtr + entity->textLen;
5451 entity->open = XML_TRUE;
5452 result = appendAttributeValue(parser, parser->m_internalEncoding,
Haibo Huangd1a324a2020-10-28 22:19:36 -07005453 isCdata, (const char *)entity->textPtr,
5454 (const char *)textEnd, pool);
Haibo Huang40a71912019-10-11 11:13:39 -07005455 entity->open = XML_FALSE;
5456 if (result)
5457 return result;
5458 }
5459 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005460 default:
Elliott Hughes72472942018-01-10 08:36:10 -08005461 /* The only token returned by XmlAttributeValueTok() that does
5462 * not have an explicit case here is XML_TOK_PARTIAL_CHAR.
5463 * Getting that would require an entity name to contain an
5464 * incomplete XML character (e.g. \xE2\x82); however previous
5465 * tokenisers will have already recognised and rejected such
5466 * names before XmlAttributeValueTok() gets a look-in. This
5467 * default case should be retained as a safety net, but the code
5468 * excluded from coverage tests.
5469 *
5470 * LCOV_EXCL_START
5471 */
5472 if (enc == parser->m_encoding)
5473 parser->m_eventPtr = ptr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005474 return XML_ERROR_UNEXPECTED_STATE;
Elliott Hughes72472942018-01-10 08:36:10 -08005475 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005476 }
5477 ptr = next;
5478 }
5479 /* not reached */
5480}
5481
5482static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07005483storeEntityValue(XML_Parser parser, const ENCODING *enc,
5484 const char *entityTextPtr, const char *entityTextEnd) {
5485 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005486 STRING_POOL *pool = &(dtd->entityValuePool);
5487 enum XML_Error result = XML_ERROR_NONE;
5488#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08005489 int oldInEntityValue = parser->m_prologState.inEntityValue;
5490 parser->m_prologState.inEntityValue = 1;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005491#endif /* XML_DTD */
5492 /* never return Null for the value argument in EntityDeclHandler,
5493 since this would indicate an external entity; therefore we
5494 have to make sure that entityValuePool.start is not null */
Haibo Huang40a71912019-10-11 11:13:39 -07005495 if (! pool->blocks) {
5496 if (! poolGrow(pool))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005497 return XML_ERROR_NO_MEMORY;
5498 }
5499
5500 for (;;) {
5501 const char *next;
5502 int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
5503 switch (tok) {
5504 case XML_TOK_PARAM_ENTITY_REF:
5505#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08005506 if (parser->m_isParamEntity || enc != parser->m_encoding) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005507 const XML_Char *name;
5508 ENTITY *entity;
Elliott Hughes72472942018-01-10 08:36:10 -08005509 name = poolStoreString(&parser->m_tempPool, enc,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005510 entityTextPtr + enc->minBytesPerChar,
5511 next - enc->minBytesPerChar);
Haibo Huang40a71912019-10-11 11:13:39 -07005512 if (! name) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005513 result = XML_ERROR_NO_MEMORY;
5514 goto endEntityValue;
5515 }
Elliott Hughes35e432d2012-09-09 14:23:38 -07005516 entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
Elliott Hughes72472942018-01-10 08:36:10 -08005517 poolDiscard(&parser->m_tempPool);
Haibo Huang40a71912019-10-11 11:13:39 -07005518 if (! entity) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005519 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
5520 /* cannot report skipped entity here - see comments on
Elliott Hughes72472942018-01-10 08:36:10 -08005521 parser->m_skippedEntityHandler
5522 if (parser->m_skippedEntityHandler)
5523 parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005524 */
5525 dtd->keepProcessing = dtd->standalone;
5526 goto endEntityValue;
5527 }
5528 if (entity->open) {
Elliott Hughes72472942018-01-10 08:36:10 -08005529 if (enc == parser->m_encoding)
5530 parser->m_eventPtr = entityTextPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005531 result = XML_ERROR_RECURSIVE_ENTITY_REF;
5532 goto endEntityValue;
5533 }
5534 if (entity->systemId) {
Elliott Hughes72472942018-01-10 08:36:10 -08005535 if (parser->m_externalEntityRefHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005536 dtd->paramEntityRead = XML_FALSE;
5537 entity->open = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07005538 if (! parser->m_externalEntityRefHandler(
5539 parser->m_externalEntityRefHandlerArg, 0, entity->base,
5540 entity->systemId, entity->publicId)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005541 entity->open = XML_FALSE;
5542 result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
5543 goto endEntityValue;
5544 }
5545 entity->open = XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07005546 if (! dtd->paramEntityRead)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005547 dtd->keepProcessing = dtd->standalone;
Haibo Huang40a71912019-10-11 11:13:39 -07005548 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005549 dtd->keepProcessing = dtd->standalone;
Haibo Huang40a71912019-10-11 11:13:39 -07005550 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005551 entity->open = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07005552 result = storeEntityValue(
Haibo Huangd1a324a2020-10-28 22:19:36 -07005553 parser, parser->m_internalEncoding, (const char *)entity->textPtr,
5554 (const char *)(entity->textPtr + entity->textLen));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005555 entity->open = XML_FALSE;
5556 if (result)
5557 goto endEntityValue;
5558 }
5559 break;
5560 }
5561#endif /* XML_DTD */
5562 /* In the internal subset, PE references are not legal
5563 within markup declarations, e.g entity values in this case. */
Elliott Hughes72472942018-01-10 08:36:10 -08005564 parser->m_eventPtr = entityTextPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005565 result = XML_ERROR_PARAM_ENTITY_REF;
5566 goto endEntityValue;
5567 case XML_TOK_NONE:
5568 result = XML_ERROR_NONE;
5569 goto endEntityValue;
5570 case XML_TOK_ENTITY_REF:
5571 case XML_TOK_DATA_CHARS:
Haibo Huang40a71912019-10-11 11:13:39 -07005572 if (! poolAppend(pool, enc, entityTextPtr, next)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005573 result = XML_ERROR_NO_MEMORY;
5574 goto endEntityValue;
5575 }
5576 break;
5577 case XML_TOK_TRAILING_CR:
5578 next = entityTextPtr + enc->minBytesPerChar;
5579 /* fall through */
5580 case XML_TOK_DATA_NEWLINE:
Haibo Huang40a71912019-10-11 11:13:39 -07005581 if (pool->end == pool->ptr && ! poolGrow(pool)) {
5582 result = XML_ERROR_NO_MEMORY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005583 goto endEntityValue;
5584 }
5585 *(pool->ptr)++ = 0xA;
5586 break;
Haibo Huang40a71912019-10-11 11:13:39 -07005587 case XML_TOK_CHAR_REF: {
5588 XML_Char buf[XML_ENCODE_MAX];
5589 int i;
5590 int n = XmlCharRefNumber(enc, entityTextPtr);
5591 if (n < 0) {
5592 if (enc == parser->m_encoding)
5593 parser->m_eventPtr = entityTextPtr;
5594 result = XML_ERROR_BAD_CHAR_REF;
5595 goto endEntityValue;
5596 }
5597 n = XmlEncode(n, (ICHAR *)buf);
5598 /* The XmlEncode() functions can never return 0 here. That
5599 * error return happens if the code point passed in is either
5600 * negative or greater than or equal to 0x110000. The
5601 * XmlCharRefNumber() functions will all return a number
5602 * strictly less than 0x110000 or a negative value if an error
5603 * occurred. The negative value is intercepted above, so
5604 * XmlEncode() is never passed a value it might return an
5605 * error for.
5606 */
5607 for (i = 0; i < n; i++) {
5608 if (pool->end == pool->ptr && ! poolGrow(pool)) {
5609 result = XML_ERROR_NO_MEMORY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005610 goto endEntityValue;
5611 }
Haibo Huang40a71912019-10-11 11:13:39 -07005612 *(pool->ptr)++ = buf[i];
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005613 }
Haibo Huang40a71912019-10-11 11:13:39 -07005614 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005615 case XML_TOK_PARTIAL:
Elliott Hughes72472942018-01-10 08:36:10 -08005616 if (enc == parser->m_encoding)
5617 parser->m_eventPtr = entityTextPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005618 result = XML_ERROR_INVALID_TOKEN;
5619 goto endEntityValue;
5620 case XML_TOK_INVALID:
Elliott Hughes72472942018-01-10 08:36:10 -08005621 if (enc == parser->m_encoding)
5622 parser->m_eventPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005623 result = XML_ERROR_INVALID_TOKEN;
5624 goto endEntityValue;
5625 default:
Elliott Hughes72472942018-01-10 08:36:10 -08005626 /* This default case should be unnecessary -- all the tokens
5627 * that XmlEntityValueTok() can return have their own explicit
5628 * cases -- but should be retained for safety. We do however
5629 * exclude it from the coverage statistics.
5630 *
5631 * LCOV_EXCL_START
5632 */
5633 if (enc == parser->m_encoding)
5634 parser->m_eventPtr = entityTextPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005635 result = XML_ERROR_UNEXPECTED_STATE;
5636 goto endEntityValue;
Elliott Hughes72472942018-01-10 08:36:10 -08005637 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005638 }
5639 entityTextPtr = next;
5640 }
5641endEntityValue:
5642#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08005643 parser->m_prologState.inEntityValue = oldInEntityValue;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005644#endif /* XML_DTD */
5645 return result;
5646}
5647
5648static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07005649normalizeLines(XML_Char *s) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005650 XML_Char *p;
5651 for (;; s++) {
5652 if (*s == XML_T('\0'))
5653 return;
5654 if (*s == 0xD)
5655 break;
5656 }
5657 p = s;
5658 do {
5659 if (*s == 0xD) {
5660 *p++ = 0xA;
5661 if (*++s == 0xA)
5662 s++;
Haibo Huang40a71912019-10-11 11:13:39 -07005663 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005664 *p++ = *s++;
5665 } while (*s);
5666 *p = XML_T('\0');
5667}
5668
5669static int
5670reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
Haibo Huang40a71912019-10-11 11:13:39 -07005671 const char *start, const char *end) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005672 const XML_Char *target;
5673 XML_Char *data;
5674 const char *tem;
Haibo Huang40a71912019-10-11 11:13:39 -07005675 if (! parser->m_processingInstructionHandler) {
Elliott Hughes72472942018-01-10 08:36:10 -08005676 if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005677 reportDefault(parser, enc, start, end);
5678 return 1;
5679 }
5680 start += enc->minBytesPerChar * 2;
5681 tem = start + XmlNameLength(enc, start);
Elliott Hughes72472942018-01-10 08:36:10 -08005682 target = poolStoreString(&parser->m_tempPool, enc, start, tem);
Haibo Huang40a71912019-10-11 11:13:39 -07005683 if (! target)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005684 return 0;
Elliott Hughes72472942018-01-10 08:36:10 -08005685 poolFinish(&parser->m_tempPool);
Haibo Huang40a71912019-10-11 11:13:39 -07005686 data = poolStoreString(&parser->m_tempPool, enc, XmlSkipS(enc, tem),
5687 end - enc->minBytesPerChar * 2);
5688 if (! data)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005689 return 0;
5690 normalizeLines(data);
Elliott Hughes72472942018-01-10 08:36:10 -08005691 parser->m_processingInstructionHandler(parser->m_handlerArg, target, data);
5692 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005693 return 1;
5694}
5695
5696static int
Haibo Huang40a71912019-10-11 11:13:39 -07005697reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
5698 const char *end) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005699 XML_Char *data;
Haibo Huang40a71912019-10-11 11:13:39 -07005700 if (! parser->m_commentHandler) {
Elliott Hughes72472942018-01-10 08:36:10 -08005701 if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005702 reportDefault(parser, enc, start, end);
5703 return 1;
5704 }
Haibo Huang40a71912019-10-11 11:13:39 -07005705 data = poolStoreString(&parser->m_tempPool, enc,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005706 start + enc->minBytesPerChar * 4,
5707 end - enc->minBytesPerChar * 3);
Haibo Huang40a71912019-10-11 11:13:39 -07005708 if (! data)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005709 return 0;
5710 normalizeLines(data);
Elliott Hughes72472942018-01-10 08:36:10 -08005711 parser->m_commentHandler(parser->m_handlerArg, data);
5712 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005713 return 1;
5714}
5715
5716static void
Haibo Huang40a71912019-10-11 11:13:39 -07005717reportDefault(XML_Parser parser, const ENCODING *enc, const char *s,
5718 const char *end) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005719 if (MUST_CONVERT(enc, s)) {
Paul Duffin4bf8f122016-05-13 12:35:25 +01005720 enum XML_Convert_Result convert_res;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005721 const char **eventPP;
5722 const char **eventEndPP;
Elliott Hughes72472942018-01-10 08:36:10 -08005723 if (enc == parser->m_encoding) {
5724 eventPP = &parser->m_eventPtr;
5725 eventEndPP = &parser->m_eventEndPtr;
Haibo Huang40a71912019-10-11 11:13:39 -07005726 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08005727 /* To get here, two things must be true; the parser must be
5728 * using a character encoding that is not the same as the
5729 * encoding passed in, and the encoding passed in must need
5730 * conversion to the internal format (UTF-8 unless XML_UNICODE
5731 * is defined). The only occasions on which the encoding passed
5732 * in is not the same as the parser's encoding are when it is
5733 * the internal encoding (e.g. a previously defined parameter
5734 * entity, already converted to internal format). This by
5735 * definition doesn't need conversion, so the whole branch never
5736 * gets executed.
5737 *
5738 * For safety's sake we don't delete these lines and merely
5739 * exclude them from coverage statistics.
5740 *
5741 * LCOV_EXCL_START
5742 */
5743 eventPP = &(parser->m_openInternalEntities->internalEventPtr);
5744 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
5745 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005746 }
5747 do {
Elliott Hughes72472942018-01-10 08:36:10 -08005748 ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
Haibo Huang40a71912019-10-11 11:13:39 -07005749 convert_res
5750 = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005751 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07005752 parser->m_defaultHandler(parser->m_handlerArg, parser->m_dataBuf,
5753 (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005754 *eventPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07005755 } while ((convert_res != XML_CONVERT_COMPLETED)
5756 && (convert_res != XML_CONVERT_INPUT_INCOMPLETE));
5757 } else
5758 parser->m_defaultHandler(parser->m_handlerArg, (XML_Char *)s,
5759 (int)((XML_Char *)end - (XML_Char *)s));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005760}
5761
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005762static int
5763defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
Haibo Huang40a71912019-10-11 11:13:39 -07005764 XML_Bool isId, const XML_Char *value, XML_Parser parser) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005765 DEFAULT_ATTRIBUTE *att;
5766 if (value || isId) {
5767 /* The handling of default attributes gets messed up if we have
5768 a default which duplicates a non-default. */
5769 int i;
5770 for (i = 0; i < type->nDefaultAtts; i++)
5771 if (attId == type->defaultAtts[i].id)
5772 return 1;
Haibo Huang40a71912019-10-11 11:13:39 -07005773 if (isId && ! type->idAtt && ! attId->xmlns)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005774 type->idAtt = attId;
5775 }
5776 if (type->nDefaultAtts == type->allocDefaultAtts) {
5777 if (type->allocDefaultAtts == 0) {
5778 type->allocDefaultAtts = 8;
Haibo Huang40a71912019-10-11 11:13:39 -07005779 type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(
5780 parser, type->allocDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
5781 if (! type->defaultAtts) {
Elliott Hughes72472942018-01-10 08:36:10 -08005782 type->allocDefaultAtts = 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005783 return 0;
Elliott Hughes72472942018-01-10 08:36:10 -08005784 }
Haibo Huang40a71912019-10-11 11:13:39 -07005785 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005786 DEFAULT_ATTRIBUTE *temp;
5787 int count = type->allocDefaultAtts * 2;
Haibo Huang40a71912019-10-11 11:13:39 -07005788 temp = (DEFAULT_ATTRIBUTE *)REALLOC(parser, type->defaultAtts,
5789 (count * sizeof(DEFAULT_ATTRIBUTE)));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005790 if (temp == NULL)
5791 return 0;
5792 type->allocDefaultAtts = count;
5793 type->defaultAtts = temp;
5794 }
5795 }
5796 att = type->defaultAtts + type->nDefaultAtts;
5797 att->id = attId;
5798 att->value = value;
5799 att->isCdata = isCdata;
Haibo Huang40a71912019-10-11 11:13:39 -07005800 if (! isCdata)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005801 attId->maybeTokenized = XML_TRUE;
5802 type->nDefaultAtts += 1;
5803 return 1;
5804}
5805
5806static int
Haibo Huang40a71912019-10-11 11:13:39 -07005807setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType) {
5808 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005809 const XML_Char *name;
5810 for (name = elementType->name; *name; name++) {
Elliott Hughesd07d5a72009-09-25 16:04:37 -07005811 if (*name == XML_T(ASCII_COLON)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005812 PREFIX *prefix;
5813 const XML_Char *s;
5814 for (s = elementType->name; s != name; s++) {
Haibo Huang40a71912019-10-11 11:13:39 -07005815 if (! poolAppendChar(&dtd->pool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005816 return 0;
5817 }
Haibo Huang40a71912019-10-11 11:13:39 -07005818 if (! poolAppendChar(&dtd->pool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005819 return 0;
Elliott Hughes35e432d2012-09-09 14:23:38 -07005820 prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005821 sizeof(PREFIX));
Haibo Huang40a71912019-10-11 11:13:39 -07005822 if (! prefix)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005823 return 0;
5824 if (prefix->name == poolStart(&dtd->pool))
5825 poolFinish(&dtd->pool);
5826 else
5827 poolDiscard(&dtd->pool);
5828 elementType->prefix = prefix;
Haibo Huangfd5e81a2019-06-20 12:09:36 -07005829 break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005830 }
5831 }
5832 return 1;
5833}
5834
5835static ATTRIBUTE_ID *
Haibo Huang40a71912019-10-11 11:13:39 -07005836getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
5837 const char *end) {
5838 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005839 ATTRIBUTE_ID *id;
5840 const XML_Char *name;
Haibo Huang40a71912019-10-11 11:13:39 -07005841 if (! poolAppendChar(&dtd->pool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005842 return NULL;
5843 name = poolStoreString(&dtd->pool, enc, start, end);
Haibo Huang40a71912019-10-11 11:13:39 -07005844 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005845 return NULL;
5846 /* skip quotation mark - its storage will be re-used (like in name[-1]) */
5847 ++name;
Haibo Huang40a71912019-10-11 11:13:39 -07005848 id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name,
5849 sizeof(ATTRIBUTE_ID));
5850 if (! id)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005851 return NULL;
5852 if (id->name != name)
5853 poolDiscard(&dtd->pool);
5854 else {
5855 poolFinish(&dtd->pool);
Haibo Huang40a71912019-10-11 11:13:39 -07005856 if (! parser->m_ns)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005857 ;
Haibo Huang40a71912019-10-11 11:13:39 -07005858 else if (name[0] == XML_T(ASCII_x) && name[1] == XML_T(ASCII_m)
5859 && name[2] == XML_T(ASCII_l) && name[3] == XML_T(ASCII_n)
5860 && name[4] == XML_T(ASCII_s)
5861 && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005862 if (name[5] == XML_T('\0'))
5863 id->prefix = &dtd->defaultPrefix;
5864 else
Haibo Huang40a71912019-10-11 11:13:39 -07005865 id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6,
5866 sizeof(PREFIX));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005867 id->xmlns = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07005868 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005869 int i;
5870 for (i = 0; name[i]; i++) {
5871 /* attributes without prefix are *not* in the default namespace */
Elliott Hughesd07d5a72009-09-25 16:04:37 -07005872 if (name[i] == XML_T(ASCII_COLON)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005873 int j;
5874 for (j = 0; j < i; j++) {
Haibo Huang40a71912019-10-11 11:13:39 -07005875 if (! poolAppendChar(&dtd->pool, name[j]))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005876 return NULL;
5877 }
Haibo Huang40a71912019-10-11 11:13:39 -07005878 if (! poolAppendChar(&dtd->pool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005879 return NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07005880 id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes,
5881 poolStart(&dtd->pool), sizeof(PREFIX));
5882 if (! id->prefix)
Paul Duffinc05e0322016-05-04 10:42:31 +01005883 return NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005884 if (id->prefix->name == poolStart(&dtd->pool))
5885 poolFinish(&dtd->pool);
5886 else
5887 poolDiscard(&dtd->pool);
5888 break;
5889 }
5890 }
5891 }
5892 }
5893 return id;
5894}
5895
Elliott Hughesd07d5a72009-09-25 16:04:37 -07005896#define CONTEXT_SEP XML_T(ASCII_FF)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005897
5898static const XML_Char *
Haibo Huang40a71912019-10-11 11:13:39 -07005899getContext(XML_Parser parser) {
5900 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005901 HASH_TABLE_ITER iter;
5902 XML_Bool needSep = XML_FALSE;
5903
5904 if (dtd->defaultPrefix.binding) {
5905 int i;
5906 int len;
Haibo Huang40a71912019-10-11 11:13:39 -07005907 if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS)))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005908 return NULL;
5909 len = dtd->defaultPrefix.binding->uriLen;
Elliott Hughes72472942018-01-10 08:36:10 -08005910 if (parser->m_namespaceSeparator)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005911 len--;
Elliott Hughes72472942018-01-10 08:36:10 -08005912 for (i = 0; i < len; i++) {
Haibo Huang40a71912019-10-11 11:13:39 -07005913 if (! poolAppendChar(&parser->m_tempPool,
5914 dtd->defaultPrefix.binding->uri[i])) {
Elliott Hughes72472942018-01-10 08:36:10 -08005915 /* Because of memory caching, I don't believe this line can be
5916 * executed.
5917 *
5918 * This is part of a loop copying the default prefix binding
5919 * URI into the parser's temporary string pool. Previously,
5920 * that URI was copied into the same string pool, with a
5921 * terminating NUL character, as part of setContext(). When
5922 * the pool was cleared, that leaves a block definitely big
5923 * enough to hold the URI on the free block list of the pool.
5924 * The URI copy in getContext() therefore cannot run out of
5925 * memory.
5926 *
5927 * If the pool is used between the setContext() and
5928 * getContext() calls, the worst it can do is leave a bigger
5929 * block on the front of the free list. Given that this is
5930 * all somewhat inobvious and program logic can be changed, we
5931 * don't delete the line but we do exclude it from the test
5932 * coverage statistics.
5933 */
5934 return NULL; /* LCOV_EXCL_LINE */
5935 }
5936 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005937 needSep = XML_TRUE;
5938 }
5939
5940 hashTableIterInit(&iter, &(dtd->prefixes));
5941 for (;;) {
5942 int i;
5943 int len;
5944 const XML_Char *s;
5945 PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07005946 if (! prefix)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005947 break;
Haibo Huang40a71912019-10-11 11:13:39 -07005948 if (! prefix->binding) {
Elliott Hughes72472942018-01-10 08:36:10 -08005949 /* This test appears to be (justifiable) paranoia. There does
5950 * not seem to be a way of injecting a prefix without a binding
5951 * that doesn't get errored long before this function is called.
5952 * The test should remain for safety's sake, so we instead
5953 * exclude the following line from the coverage statistics.
5954 */
5955 continue; /* LCOV_EXCL_LINE */
5956 }
Haibo Huang40a71912019-10-11 11:13:39 -07005957 if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005958 return NULL;
5959 for (s = prefix->name; *s; s++)
Haibo Huang40a71912019-10-11 11:13:39 -07005960 if (! poolAppendChar(&parser->m_tempPool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005961 return NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07005962 if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS)))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005963 return NULL;
5964 len = prefix->binding->uriLen;
Elliott Hughes72472942018-01-10 08:36:10 -08005965 if (parser->m_namespaceSeparator)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005966 len--;
5967 for (i = 0; i < len; i++)
Haibo Huang40a71912019-10-11 11:13:39 -07005968 if (! poolAppendChar(&parser->m_tempPool, prefix->binding->uri[i]))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005969 return NULL;
5970 needSep = XML_TRUE;
5971 }
5972
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005973 hashTableIterInit(&iter, &(dtd->generalEntities));
5974 for (;;) {
5975 const XML_Char *s;
5976 ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07005977 if (! e)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005978 break;
Haibo Huang40a71912019-10-11 11:13:39 -07005979 if (! e->open)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005980 continue;
Haibo Huang40a71912019-10-11 11:13:39 -07005981 if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005982 return NULL;
5983 for (s = e->name; *s; s++)
Haibo Huang40a71912019-10-11 11:13:39 -07005984 if (! poolAppendChar(&parser->m_tempPool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005985 return 0;
5986 needSep = XML_TRUE;
5987 }
5988
Haibo Huang40a71912019-10-11 11:13:39 -07005989 if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005990 return NULL;
Elliott Hughes72472942018-01-10 08:36:10 -08005991 return parser->m_tempPool.start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005992}
5993
5994static XML_Bool
Haibo Huang40a71912019-10-11 11:13:39 -07005995setContext(XML_Parser parser, const XML_Char *context) {
5996 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005997 const XML_Char *s = context;
5998
5999 while (*context != XML_T('\0')) {
6000 if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
6001 ENTITY *e;
Haibo Huang40a71912019-10-11 11:13:39 -07006002 if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006003 return XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07006004 e = (ENTITY *)lookup(parser, &dtd->generalEntities,
6005 poolStart(&parser->m_tempPool), 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006006 if (e)
6007 e->open = XML_TRUE;
6008 if (*s != XML_T('\0'))
6009 s++;
6010 context = s;
Elliott Hughes72472942018-01-10 08:36:10 -08006011 poolDiscard(&parser->m_tempPool);
Haibo Huang40a71912019-10-11 11:13:39 -07006012 } else if (*s == XML_T(ASCII_EQUALS)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006013 PREFIX *prefix;
Elliott Hughes72472942018-01-10 08:36:10 -08006014 if (poolLength(&parser->m_tempPool) == 0)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006015 prefix = &dtd->defaultPrefix;
6016 else {
Haibo Huang40a71912019-10-11 11:13:39 -07006017 if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006018 return XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07006019 prefix
6020 = (PREFIX *)lookup(parser, &dtd->prefixes,
6021 poolStart(&parser->m_tempPool), sizeof(PREFIX));
6022 if (! prefix)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006023 return XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08006024 if (prefix->name == poolStart(&parser->m_tempPool)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006025 prefix->name = poolCopyString(&dtd->pool, prefix->name);
Haibo Huang40a71912019-10-11 11:13:39 -07006026 if (! prefix->name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006027 return XML_FALSE;
6028 }
Elliott Hughes72472942018-01-10 08:36:10 -08006029 poolDiscard(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006030 }
Haibo Huang40a71912019-10-11 11:13:39 -07006031 for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0');
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006032 context++)
Haibo Huang40a71912019-10-11 11:13:39 -07006033 if (! poolAppendChar(&parser->m_tempPool, *context))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006034 return XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07006035 if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006036 return XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08006037 if (addBinding(parser, prefix, NULL, poolStart(&parser->m_tempPool),
Haibo Huang40a71912019-10-11 11:13:39 -07006038 &parser->m_inheritedBindings)
6039 != XML_ERROR_NONE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006040 return XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08006041 poolDiscard(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006042 if (*context != XML_T('\0'))
6043 ++context;
6044 s = context;
Haibo Huang40a71912019-10-11 11:13:39 -07006045 } else {
6046 if (! poolAppendChar(&parser->m_tempPool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006047 return XML_FALSE;
6048 s++;
6049 }
6050 }
6051 return XML_TRUE;
6052}
6053
6054static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006055normalizePublicId(XML_Char *publicId) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006056 XML_Char *p = publicId;
6057 XML_Char *s;
6058 for (s = publicId; *s; s++) {
6059 switch (*s) {
6060 case 0x20:
6061 case 0xD:
6062 case 0xA:
6063 if (p != publicId && p[-1] != 0x20)
6064 *p++ = 0x20;
6065 break;
6066 default:
6067 *p++ = *s;
6068 }
6069 }
6070 if (p != publicId && p[-1] == 0x20)
6071 --p;
6072 *p = XML_T('\0');
6073}
6074
6075static DTD *
Haibo Huang40a71912019-10-11 11:13:39 -07006076dtdCreate(const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006077 DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
6078 if (p == NULL)
6079 return p;
6080 poolInit(&(p->pool), ms);
6081 poolInit(&(p->entityValuePool), ms);
6082 hashTableInit(&(p->generalEntities), ms);
6083 hashTableInit(&(p->elementTypes), ms);
6084 hashTableInit(&(p->attributeIds), ms);
6085 hashTableInit(&(p->prefixes), ms);
6086#ifdef XML_DTD
6087 p->paramEntityRead = XML_FALSE;
6088 hashTableInit(&(p->paramEntities), ms);
6089#endif /* XML_DTD */
6090 p->defaultPrefix.name = NULL;
6091 p->defaultPrefix.binding = NULL;
6092
6093 p->in_eldecl = XML_FALSE;
6094 p->scaffIndex = NULL;
6095 p->scaffold = NULL;
6096 p->scaffLevel = 0;
6097 p->scaffSize = 0;
6098 p->scaffCount = 0;
6099 p->contentStringLen = 0;
6100
6101 p->keepProcessing = XML_TRUE;
6102 p->hasParamEntityRefs = XML_FALSE;
6103 p->standalone = XML_FALSE;
6104 return p;
6105}
6106
6107static void
Haibo Huang40a71912019-10-11 11:13:39 -07006108dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006109 HASH_TABLE_ITER iter;
6110 hashTableIterInit(&iter, &(p->elementTypes));
6111 for (;;) {
6112 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006113 if (! e)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006114 break;
6115 if (e->allocDefaultAtts != 0)
6116 ms->free_fcn(e->defaultAtts);
6117 }
6118 hashTableClear(&(p->generalEntities));
6119#ifdef XML_DTD
6120 p->paramEntityRead = XML_FALSE;
6121 hashTableClear(&(p->paramEntities));
6122#endif /* XML_DTD */
6123 hashTableClear(&(p->elementTypes));
6124 hashTableClear(&(p->attributeIds));
6125 hashTableClear(&(p->prefixes));
6126 poolClear(&(p->pool));
6127 poolClear(&(p->entityValuePool));
6128 p->defaultPrefix.name = NULL;
6129 p->defaultPrefix.binding = NULL;
6130
6131 p->in_eldecl = XML_FALSE;
6132
6133 ms->free_fcn(p->scaffIndex);
6134 p->scaffIndex = NULL;
6135 ms->free_fcn(p->scaffold);
6136 p->scaffold = NULL;
6137
6138 p->scaffLevel = 0;
6139 p->scaffSize = 0;
6140 p->scaffCount = 0;
6141 p->contentStringLen = 0;
6142
6143 p->keepProcessing = XML_TRUE;
6144 p->hasParamEntityRefs = XML_FALSE;
6145 p->standalone = XML_FALSE;
6146}
6147
6148static void
Haibo Huang40a71912019-10-11 11:13:39 -07006149dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006150 HASH_TABLE_ITER iter;
6151 hashTableIterInit(&iter, &(p->elementTypes));
6152 for (;;) {
6153 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006154 if (! e)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006155 break;
6156 if (e->allocDefaultAtts != 0)
6157 ms->free_fcn(e->defaultAtts);
6158 }
6159 hashTableDestroy(&(p->generalEntities));
6160#ifdef XML_DTD
6161 hashTableDestroy(&(p->paramEntities));
6162#endif /* XML_DTD */
6163 hashTableDestroy(&(p->elementTypes));
6164 hashTableDestroy(&(p->attributeIds));
6165 hashTableDestroy(&(p->prefixes));
6166 poolDestroy(&(p->pool));
6167 poolDestroy(&(p->entityValuePool));
6168 if (isDocEntity) {
6169 ms->free_fcn(p->scaffIndex);
6170 ms->free_fcn(p->scaffold);
6171 }
6172 ms->free_fcn(p);
6173}
6174
6175/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
6176 The new DTD has already been initialized.
6177*/
6178static int
Haibo Huang40a71912019-10-11 11:13:39 -07006179dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
6180 const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006181 HASH_TABLE_ITER iter;
6182
6183 /* Copy the prefix table. */
6184
6185 hashTableIterInit(&iter, &(oldDtd->prefixes));
6186 for (;;) {
6187 const XML_Char *name;
6188 const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006189 if (! oldP)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006190 break;
6191 name = poolCopyString(&(newDtd->pool), oldP->name);
Haibo Huang40a71912019-10-11 11:13:39 -07006192 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006193 return 0;
Haibo Huang40a71912019-10-11 11:13:39 -07006194 if (! lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX)))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006195 return 0;
6196 }
6197
6198 hashTableIterInit(&iter, &(oldDtd->attributeIds));
6199
6200 /* Copy the attribute id table. */
6201
6202 for (;;) {
6203 ATTRIBUTE_ID *newA;
6204 const XML_Char *name;
6205 const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
6206
Haibo Huang40a71912019-10-11 11:13:39 -07006207 if (! oldA)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006208 break;
6209 /* Remember to allocate the scratch byte before the name. */
Haibo Huang40a71912019-10-11 11:13:39 -07006210 if (! poolAppendChar(&(newDtd->pool), XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006211 return 0;
6212 name = poolCopyString(&(newDtd->pool), oldA->name);
Haibo Huang40a71912019-10-11 11:13:39 -07006213 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006214 return 0;
6215 ++name;
Elliott Hughes35e432d2012-09-09 14:23:38 -07006216 newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006217 sizeof(ATTRIBUTE_ID));
Haibo Huang40a71912019-10-11 11:13:39 -07006218 if (! newA)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006219 return 0;
6220 newA->maybeTokenized = oldA->maybeTokenized;
6221 if (oldA->prefix) {
6222 newA->xmlns = oldA->xmlns;
6223 if (oldA->prefix == &oldDtd->defaultPrefix)
6224 newA->prefix = &newDtd->defaultPrefix;
6225 else
Elliott Hughes35e432d2012-09-09 14:23:38 -07006226 newA->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006227 oldA->prefix->name, 0);
6228 }
6229 }
6230
6231 /* Copy the element type table. */
6232
6233 hashTableIterInit(&iter, &(oldDtd->elementTypes));
6234
6235 for (;;) {
6236 int i;
6237 ELEMENT_TYPE *newE;
6238 const XML_Char *name;
6239 const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006240 if (! oldE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006241 break;
6242 name = poolCopyString(&(newDtd->pool), oldE->name);
Haibo Huang40a71912019-10-11 11:13:39 -07006243 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006244 return 0;
Elliott Hughes35e432d2012-09-09 14:23:38 -07006245 newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006246 sizeof(ELEMENT_TYPE));
Haibo Huang40a71912019-10-11 11:13:39 -07006247 if (! newE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006248 return 0;
6249 if (oldE->nDefaultAtts) {
Haibo Huang40a71912019-10-11 11:13:39 -07006250 newE->defaultAtts = (DEFAULT_ATTRIBUTE *)ms->malloc_fcn(
6251 oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
6252 if (! newE->defaultAtts) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006253 return 0;
6254 }
6255 }
6256 if (oldE->idAtt)
Haibo Huang40a71912019-10-11 11:13:39 -07006257 newE->idAtt = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds),
6258 oldE->idAtt->name, 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006259 newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
6260 if (oldE->prefix)
Elliott Hughes35e432d2012-09-09 14:23:38 -07006261 newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006262 oldE->prefix->name, 0);
6263 for (i = 0; i < newE->nDefaultAtts; i++) {
Haibo Huang40a71912019-10-11 11:13:39 -07006264 newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup(
6265 oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006266 newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
6267 if (oldE->defaultAtts[i].value) {
6268 newE->defaultAtts[i].value
6269 = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
Haibo Huang40a71912019-10-11 11:13:39 -07006270 if (! newE->defaultAtts[i].value)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006271 return 0;
Haibo Huang40a71912019-10-11 11:13:39 -07006272 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006273 newE->defaultAtts[i].value = NULL;
6274 }
6275 }
6276
6277 /* Copy the entity tables. */
Haibo Huang40a71912019-10-11 11:13:39 -07006278 if (! copyEntityTable(oldParser, &(newDtd->generalEntities), &(newDtd->pool),
6279 &(oldDtd->generalEntities)))
6280 return 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006281
6282#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07006283 if (! copyEntityTable(oldParser, &(newDtd->paramEntities), &(newDtd->pool),
6284 &(oldDtd->paramEntities)))
6285 return 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006286 newDtd->paramEntityRead = oldDtd->paramEntityRead;
6287#endif /* XML_DTD */
6288
6289 newDtd->keepProcessing = oldDtd->keepProcessing;
6290 newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
6291 newDtd->standalone = oldDtd->standalone;
6292
6293 /* Don't want deep copying for scaffolding */
6294 newDtd->in_eldecl = oldDtd->in_eldecl;
6295 newDtd->scaffold = oldDtd->scaffold;
6296 newDtd->contentStringLen = oldDtd->contentStringLen;
6297 newDtd->scaffSize = oldDtd->scaffSize;
6298 newDtd->scaffLevel = oldDtd->scaffLevel;
6299 newDtd->scaffIndex = oldDtd->scaffIndex;
6300
6301 return 1;
Haibo Huang40a71912019-10-11 11:13:39 -07006302} /* End dtdCopy */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006303
6304static int
Haibo Huang40a71912019-10-11 11:13:39 -07006305copyEntityTable(XML_Parser oldParser, HASH_TABLE *newTable,
6306 STRING_POOL *newPool, const HASH_TABLE *oldTable) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006307 HASH_TABLE_ITER iter;
6308 const XML_Char *cachedOldBase = NULL;
6309 const XML_Char *cachedNewBase = NULL;
6310
6311 hashTableIterInit(&iter, oldTable);
6312
6313 for (;;) {
6314 ENTITY *newE;
6315 const XML_Char *name;
6316 const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006317 if (! oldE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006318 break;
6319 name = poolCopyString(newPool, oldE->name);
Haibo Huang40a71912019-10-11 11:13:39 -07006320 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006321 return 0;
Elliott Hughes35e432d2012-09-09 14:23:38 -07006322 newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY));
Haibo Huang40a71912019-10-11 11:13:39 -07006323 if (! newE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006324 return 0;
6325 if (oldE->systemId) {
6326 const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
Haibo Huang40a71912019-10-11 11:13:39 -07006327 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006328 return 0;
6329 newE->systemId = tem;
6330 if (oldE->base) {
6331 if (oldE->base == cachedOldBase)
6332 newE->base = cachedNewBase;
6333 else {
6334 cachedOldBase = oldE->base;
6335 tem = poolCopyString(newPool, cachedOldBase);
Haibo Huang40a71912019-10-11 11:13:39 -07006336 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006337 return 0;
6338 cachedNewBase = newE->base = tem;
6339 }
6340 }
6341 if (oldE->publicId) {
6342 tem = poolCopyString(newPool, oldE->publicId);
Haibo Huang40a71912019-10-11 11:13:39 -07006343 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006344 return 0;
6345 newE->publicId = tem;
6346 }
Haibo Huang40a71912019-10-11 11:13:39 -07006347 } else {
6348 const XML_Char *tem
6349 = poolCopyStringN(newPool, oldE->textPtr, oldE->textLen);
6350 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006351 return 0;
6352 newE->textPtr = tem;
6353 newE->textLen = oldE->textLen;
6354 }
6355 if (oldE->notation) {
6356 const XML_Char *tem = poolCopyString(newPool, oldE->notation);
Haibo Huang40a71912019-10-11 11:13:39 -07006357 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006358 return 0;
6359 newE->notation = tem;
6360 }
6361 newE->is_param = oldE->is_param;
6362 newE->is_internal = oldE->is_internal;
6363 }
6364 return 1;
6365}
6366
6367#define INIT_POWER 6
6368
6369static XML_Bool FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006370keyeq(KEY s1, KEY s2) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006371 for (; *s1 == *s2; s1++, s2++)
6372 if (*s1 == 0)
6373 return XML_TRUE;
6374 return XML_FALSE;
6375}
6376
Elliott Hughes72472942018-01-10 08:36:10 -08006377static size_t
Haibo Huang40a71912019-10-11 11:13:39 -07006378keylen(KEY s) {
Elliott Hughes72472942018-01-10 08:36:10 -08006379 size_t len = 0;
Haibo Huang40a71912019-10-11 11:13:39 -07006380 for (; *s; s++, len++)
6381 ;
Elliott Hughes72472942018-01-10 08:36:10 -08006382 return len;
6383}
6384
6385static void
Haibo Huang40a71912019-10-11 11:13:39 -07006386copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key) {
Elliott Hughes72472942018-01-10 08:36:10 -08006387 key->k[0] = 0;
6388 key->k[1] = get_hash_secret_salt(parser);
6389}
6390
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006391static unsigned long FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006392hash(XML_Parser parser, KEY s) {
Elliott Hughes72472942018-01-10 08:36:10 -08006393 struct siphash state;
6394 struct sipkey key;
Elliott Hughes72472942018-01-10 08:36:10 -08006395 (void)sip24_valid;
6396 copy_salt_to_sipkey(parser, &key);
6397 sip24_init(&state, &key);
6398 sip24_update(&state, s, keylen(s) * sizeof(XML_Char));
6399 return (unsigned long)sip24_final(&state);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006400}
6401
6402static NAMED *
Haibo Huang40a71912019-10-11 11:13:39 -07006403lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006404 size_t i;
6405 if (table->size == 0) {
6406 size_t tsize;
Haibo Huang40a71912019-10-11 11:13:39 -07006407 if (! createSize)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006408 return NULL;
6409 table->power = INIT_POWER;
6410 /* table->size is a power of 2 */
6411 table->size = (size_t)1 << INIT_POWER;
6412 tsize = table->size * sizeof(NAMED *);
6413 table->v = (NAMED **)table->mem->malloc_fcn(tsize);
Haibo Huang40a71912019-10-11 11:13:39 -07006414 if (! table->v) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006415 table->size = 0;
6416 return NULL;
6417 }
6418 memset(table->v, 0, tsize);
Elliott Hughes35e432d2012-09-09 14:23:38 -07006419 i = hash(parser, name) & ((unsigned long)table->size - 1);
Haibo Huang40a71912019-10-11 11:13:39 -07006420 } else {
Elliott Hughes35e432d2012-09-09 14:23:38 -07006421 unsigned long h = hash(parser, name);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006422 unsigned long mask = (unsigned long)table->size - 1;
6423 unsigned char step = 0;
6424 i = h & mask;
6425 while (table->v[i]) {
6426 if (keyeq(name, table->v[i]->name))
6427 return table->v[i];
Haibo Huang40a71912019-10-11 11:13:39 -07006428 if (! step)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006429 step = PROBE_STEP(h, mask, table->power);
6430 i < step ? (i += table->size - step) : (i -= step);
6431 }
Haibo Huang40a71912019-10-11 11:13:39 -07006432 if (! createSize)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006433 return NULL;
6434
6435 /* check for overflow (table is half full) */
6436 if (table->used >> (table->power - 1)) {
6437 unsigned char newPower = table->power + 1;
6438 size_t newSize = (size_t)1 << newPower;
6439 unsigned long newMask = (unsigned long)newSize - 1;
6440 size_t tsize = newSize * sizeof(NAMED *);
6441 NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
Haibo Huang40a71912019-10-11 11:13:39 -07006442 if (! newV)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006443 return NULL;
6444 memset(newV, 0, tsize);
6445 for (i = 0; i < table->size; i++)
6446 if (table->v[i]) {
Elliott Hughes35e432d2012-09-09 14:23:38 -07006447 unsigned long newHash = hash(parser, table->v[i]->name);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006448 size_t j = newHash & newMask;
6449 step = 0;
6450 while (newV[j]) {
Haibo Huang40a71912019-10-11 11:13:39 -07006451 if (! step)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006452 step = PROBE_STEP(newHash, newMask, newPower);
6453 j < step ? (j += newSize - step) : (j -= step);
6454 }
6455 newV[j] = table->v[i];
6456 }
6457 table->mem->free_fcn(table->v);
6458 table->v = newV;
6459 table->power = newPower;
6460 table->size = newSize;
6461 i = h & newMask;
6462 step = 0;
6463 while (table->v[i]) {
Haibo Huang40a71912019-10-11 11:13:39 -07006464 if (! step)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006465 step = PROBE_STEP(h, newMask, newPower);
6466 i < step ? (i += newSize - step) : (i -= step);
6467 }
6468 }
6469 }
6470 table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
Haibo Huang40a71912019-10-11 11:13:39 -07006471 if (! table->v[i])
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006472 return NULL;
6473 memset(table->v[i], 0, createSize);
6474 table->v[i]->name = name;
6475 (table->used)++;
6476 return table->v[i];
6477}
6478
6479static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006480hashTableClear(HASH_TABLE *table) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006481 size_t i;
6482 for (i = 0; i < table->size; i++) {
6483 table->mem->free_fcn(table->v[i]);
6484 table->v[i] = NULL;
6485 }
6486 table->used = 0;
6487}
6488
6489static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006490hashTableDestroy(HASH_TABLE *table) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006491 size_t i;
6492 for (i = 0; i < table->size; i++)
6493 table->mem->free_fcn(table->v[i]);
6494 table->mem->free_fcn(table->v);
6495}
6496
6497static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006498hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006499 p->power = 0;
6500 p->size = 0;
6501 p->used = 0;
6502 p->v = NULL;
6503 p->mem = ms;
6504}
6505
6506static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006507hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006508 iter->p = table->v;
Haibo Huangd1a324a2020-10-28 22:19:36 -07006509 iter->end = iter->p ? iter->p + table->size : NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006510}
6511
Haibo Huang40a71912019-10-11 11:13:39 -07006512static NAMED *FASTCALL
6513hashTableIterNext(HASH_TABLE_ITER *iter) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006514 while (iter->p != iter->end) {
6515 NAMED *tem = *(iter->p)++;
6516 if (tem)
6517 return tem;
6518 }
6519 return NULL;
6520}
6521
6522static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006523poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006524 pool->blocks = NULL;
6525 pool->freeBlocks = NULL;
6526 pool->start = NULL;
6527 pool->ptr = NULL;
6528 pool->end = NULL;
6529 pool->mem = ms;
6530}
6531
6532static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006533poolClear(STRING_POOL *pool) {
6534 if (! pool->freeBlocks)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006535 pool->freeBlocks = pool->blocks;
6536 else {
6537 BLOCK *p = pool->blocks;
6538 while (p) {
6539 BLOCK *tem = p->next;
6540 p->next = pool->freeBlocks;
6541 pool->freeBlocks = p;
6542 p = tem;
6543 }
6544 }
6545 pool->blocks = NULL;
6546 pool->start = NULL;
6547 pool->ptr = NULL;
6548 pool->end = NULL;
6549}
6550
6551static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006552poolDestroy(STRING_POOL *pool) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006553 BLOCK *p = pool->blocks;
6554 while (p) {
6555 BLOCK *tem = p->next;
6556 pool->mem->free_fcn(p);
6557 p = tem;
6558 }
6559 p = pool->freeBlocks;
6560 while (p) {
6561 BLOCK *tem = p->next;
6562 pool->mem->free_fcn(p);
6563 p = tem;
6564 }
6565}
6566
6567static XML_Char *
Haibo Huang40a71912019-10-11 11:13:39 -07006568poolAppend(STRING_POOL *pool, const ENCODING *enc, const char *ptr,
6569 const char *end) {
6570 if (! pool->ptr && ! poolGrow(pool))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006571 return NULL;
6572 for (;;) {
Haibo Huang40a71912019-10-11 11:13:39 -07006573 const enum XML_Convert_Result convert_res = XmlConvert(
6574 enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
6575 if ((convert_res == XML_CONVERT_COMPLETED)
6576 || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006577 break;
Haibo Huang40a71912019-10-11 11:13:39 -07006578 if (! poolGrow(pool))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006579 return NULL;
6580 }
6581 return pool->start;
6582}
6583
Haibo Huang40a71912019-10-11 11:13:39 -07006584static const XML_Char *FASTCALL
6585poolCopyString(STRING_POOL *pool, const XML_Char *s) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006586 do {
Haibo Huang40a71912019-10-11 11:13:39 -07006587 if (! poolAppendChar(pool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006588 return NULL;
6589 } while (*s++);
6590 s = pool->start;
6591 poolFinish(pool);
6592 return s;
6593}
6594
6595static const XML_Char *
Haibo Huang40a71912019-10-11 11:13:39 -07006596poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) {
6597 if (! pool->ptr && ! poolGrow(pool)) {
Elliott Hughes72472942018-01-10 08:36:10 -08006598 /* The following line is unreachable given the current usage of
6599 * poolCopyStringN(). Currently it is called from exactly one
6600 * place to copy the text of a simple general entity. By that
6601 * point, the name of the entity is already stored in the pool, so
6602 * pool->ptr cannot be NULL.
6603 *
6604 * If poolCopyStringN() is used elsewhere as it well might be,
6605 * this line may well become executable again. Regardless, this
6606 * sort of check shouldn't be removed lightly, so we just exclude
6607 * it from the coverage statistics.
6608 */
6609 return NULL; /* LCOV_EXCL_LINE */
6610 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006611 for (; n > 0; --n, s++) {
Haibo Huang40a71912019-10-11 11:13:39 -07006612 if (! poolAppendChar(pool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006613 return NULL;
6614 }
6615 s = pool->start;
6616 poolFinish(pool);
6617 return s;
6618}
6619
Haibo Huang40a71912019-10-11 11:13:39 -07006620static const XML_Char *FASTCALL
6621poolAppendString(STRING_POOL *pool, const XML_Char *s) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006622 while (*s) {
Haibo Huang40a71912019-10-11 11:13:39 -07006623 if (! poolAppendChar(pool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006624 return NULL;
6625 s++;
6626 }
6627 return pool->start;
6628}
6629
6630static XML_Char *
Haibo Huang40a71912019-10-11 11:13:39 -07006631poolStoreString(STRING_POOL *pool, const ENCODING *enc, const char *ptr,
6632 const char *end) {
6633 if (! poolAppend(pool, enc, ptr, end))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006634 return NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07006635 if (pool->ptr == pool->end && ! poolGrow(pool))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006636 return NULL;
6637 *(pool->ptr)++ = 0;
6638 return pool->start;
6639}
6640
Elliott Hughes72472942018-01-10 08:36:10 -08006641static size_t
Haibo Huang40a71912019-10-11 11:13:39 -07006642poolBytesToAllocateFor(int blockSize) {
Elliott Hughes72472942018-01-10 08:36:10 -08006643 /* Unprotected math would be:
6644 ** return offsetof(BLOCK, s) + blockSize * sizeof(XML_Char);
6645 **
6646 ** Detect overflow, avoiding _signed_ overflow undefined behavior
6647 ** For a + b * c we check b * c in isolation first, so that addition of a
6648 ** on top has no chance of making us accept a small non-negative number
6649 */
Haibo Huang40a71912019-10-11 11:13:39 -07006650 const size_t stretch = sizeof(XML_Char); /* can be 4 bytes */
Elliott Hughes72472942018-01-10 08:36:10 -08006651
6652 if (blockSize <= 0)
6653 return 0;
6654
6655 if (blockSize > (int)(INT_MAX / stretch))
6656 return 0;
6657
6658 {
6659 const int stretchedBlockSize = blockSize * (int)stretch;
Haibo Huang40a71912019-10-11 11:13:39 -07006660 const int bytesToAllocate
6661 = (int)(offsetof(BLOCK, s) + (unsigned)stretchedBlockSize);
Elliott Hughes72472942018-01-10 08:36:10 -08006662 if (bytesToAllocate < 0)
6663 return 0;
6664
6665 return (size_t)bytesToAllocate;
6666 }
6667}
6668
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006669static XML_Bool FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006670poolGrow(STRING_POOL *pool) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006671 if (pool->freeBlocks) {
6672 if (pool->start == 0) {
6673 pool->blocks = pool->freeBlocks;
6674 pool->freeBlocks = pool->freeBlocks->next;
6675 pool->blocks->next = NULL;
6676 pool->start = pool->blocks->s;
6677 pool->end = pool->start + pool->blocks->size;
6678 pool->ptr = pool->start;
6679 return XML_TRUE;
6680 }
6681 if (pool->end - pool->start < pool->freeBlocks->size) {
6682 BLOCK *tem = pool->freeBlocks->next;
6683 pool->freeBlocks->next = pool->blocks;
6684 pool->blocks = pool->freeBlocks;
6685 pool->freeBlocks = tem;
6686 memcpy(pool->blocks->s, pool->start,
6687 (pool->end - pool->start) * sizeof(XML_Char));
6688 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
6689 pool->start = pool->blocks->s;
6690 pool->end = pool->start + pool->blocks->size;
6691 return XML_TRUE;
6692 }
6693 }
6694 if (pool->blocks && pool->start == pool->blocks->s) {
Paul Duffin4bf8f122016-05-13 12:35:25 +01006695 BLOCK *temp;
Haibo Huang40a71912019-10-11 11:13:39 -07006696 int blockSize = (int)((unsigned)(pool->end - pool->start) * 2U);
Elliott Hughes72472942018-01-10 08:36:10 -08006697 size_t bytesToAllocate;
Paul Duffin4bf8f122016-05-13 12:35:25 +01006698
Elliott Hughes72472942018-01-10 08:36:10 -08006699 /* NOTE: Needs to be calculated prior to calling `realloc`
6700 to avoid dangling pointers: */
6701 const ptrdiff_t offsetInsideBlock = pool->ptr - pool->start;
6702
6703 if (blockSize < 0) {
6704 /* This condition traps a situation where either more than
6705 * INT_MAX/2 bytes have already been allocated. This isn't
6706 * readily testable, since it is unlikely that an average
6707 * machine will have that much memory, so we exclude it from the
6708 * coverage statistics.
6709 */
6710 return XML_FALSE; /* LCOV_EXCL_LINE */
6711 }
6712
6713 bytesToAllocate = poolBytesToAllocateFor(blockSize);
6714 if (bytesToAllocate == 0)
Paul Duffin4bf8f122016-05-13 12:35:25 +01006715 return XML_FALSE;
6716
Haibo Huang40a71912019-10-11 11:13:39 -07006717 temp = (BLOCK *)pool->mem->realloc_fcn(pool->blocks,
6718 (unsigned)bytesToAllocate);
Elliott Hughes35e432d2012-09-09 14:23:38 -07006719 if (temp == NULL)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006720 return XML_FALSE;
Elliott Hughes35e432d2012-09-09 14:23:38 -07006721 pool->blocks = temp;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006722 pool->blocks->size = blockSize;
Elliott Hughes72472942018-01-10 08:36:10 -08006723 pool->ptr = pool->blocks->s + offsetInsideBlock;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006724 pool->start = pool->blocks->s;
6725 pool->end = pool->start + blockSize;
Haibo Huang40a71912019-10-11 11:13:39 -07006726 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006727 BLOCK *tem;
6728 int blockSize = (int)(pool->end - pool->start);
Elliott Hughes72472942018-01-10 08:36:10 -08006729 size_t bytesToAllocate;
Paul Duffin4bf8f122016-05-13 12:35:25 +01006730
Elliott Hughes72472942018-01-10 08:36:10 -08006731 if (blockSize < 0) {
6732 /* This condition traps a situation where either more than
6733 * INT_MAX bytes have already been allocated (which is prevented
6734 * by various pieces of program logic, not least this one, never
6735 * mind the unlikelihood of actually having that much memory) or
6736 * the pool control fields have been corrupted (which could
6737 * conceivably happen in an extremely buggy user handler
6738 * function). Either way it isn't readily testable, so we
6739 * exclude it from the coverage statistics.
6740 */
Haibo Huang40a71912019-10-11 11:13:39 -07006741 return XML_FALSE; /* LCOV_EXCL_LINE */
Elliott Hughes72472942018-01-10 08:36:10 -08006742 }
Paul Duffin4bf8f122016-05-13 12:35:25 +01006743
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006744 if (blockSize < INIT_BLOCK_SIZE)
6745 blockSize = INIT_BLOCK_SIZE;
Elliott Hughes72472942018-01-10 08:36:10 -08006746 else {
6747 /* Detect overflow, avoiding _signed_ overflow undefined behavior */
6748 if ((int)((unsigned)blockSize * 2U) < 0) {
6749 return XML_FALSE;
6750 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006751 blockSize *= 2;
Elliott Hughes72472942018-01-10 08:36:10 -08006752 }
6753
6754 bytesToAllocate = poolBytesToAllocateFor(blockSize);
6755 if (bytesToAllocate == 0)
6756 return XML_FALSE;
6757
6758 tem = (BLOCK *)pool->mem->malloc_fcn(bytesToAllocate);
Haibo Huang40a71912019-10-11 11:13:39 -07006759 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006760 return XML_FALSE;
6761 tem->size = blockSize;
6762 tem->next = pool->blocks;
6763 pool->blocks = tem;
6764 if (pool->ptr != pool->start)
Haibo Huang40a71912019-10-11 11:13:39 -07006765 memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006766 pool->ptr = tem->s + (pool->ptr - pool->start);
6767 pool->start = tem->s;
6768 pool->end = tem->s + blockSize;
6769 }
6770 return XML_TRUE;
6771}
6772
6773static int FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006774nextScaffoldPart(XML_Parser parser) {
6775 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
6776 CONTENT_SCAFFOLD *me;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006777 int next;
6778
Haibo Huang40a71912019-10-11 11:13:39 -07006779 if (! dtd->scaffIndex) {
Elliott Hughes72472942018-01-10 08:36:10 -08006780 dtd->scaffIndex = (int *)MALLOC(parser, parser->m_groupSize * sizeof(int));
Haibo Huang40a71912019-10-11 11:13:39 -07006781 if (! dtd->scaffIndex)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006782 return -1;
6783 dtd->scaffIndex[0] = 0;
6784 }
6785
6786 if (dtd->scaffCount >= dtd->scaffSize) {
6787 CONTENT_SCAFFOLD *temp;
6788 if (dtd->scaffold) {
Haibo Huang40a71912019-10-11 11:13:39 -07006789 temp = (CONTENT_SCAFFOLD *)REALLOC(
6790 parser, dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006791 if (temp == NULL)
6792 return -1;
6793 dtd->scaffSize *= 2;
Haibo Huang40a71912019-10-11 11:13:39 -07006794 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08006795 temp = (CONTENT_SCAFFOLD *)MALLOC(parser, INIT_SCAFFOLD_ELEMENTS
Haibo Huang40a71912019-10-11 11:13:39 -07006796 * sizeof(CONTENT_SCAFFOLD));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006797 if (temp == NULL)
6798 return -1;
6799 dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
6800 }
6801 dtd->scaffold = temp;
6802 }
6803 next = dtd->scaffCount++;
6804 me = &dtd->scaffold[next];
6805 if (dtd->scaffLevel) {
Haibo Huang40a71912019-10-11 11:13:39 -07006806 CONTENT_SCAFFOLD *parent
6807 = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]];
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006808 if (parent->lastchild) {
6809 dtd->scaffold[parent->lastchild].nextsib = next;
6810 }
Haibo Huang40a71912019-10-11 11:13:39 -07006811 if (! parent->childcnt)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006812 parent->firstchild = next;
6813 parent->lastchild = next;
6814 parent->childcnt++;
6815 }
6816 me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
6817 return next;
6818}
6819
6820static void
Haibo Huang40a71912019-10-11 11:13:39 -07006821build_node(XML_Parser parser, int src_node, XML_Content *dest,
6822 XML_Content **contpos, XML_Char **strpos) {
6823 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006824 dest->type = dtd->scaffold[src_node].type;
6825 dest->quant = dtd->scaffold[src_node].quant;
6826 if (dest->type == XML_CTYPE_NAME) {
6827 const XML_Char *src;
6828 dest->name = *strpos;
6829 src = dtd->scaffold[src_node].name;
6830 for (;;) {
6831 *(*strpos)++ = *src;
Haibo Huang40a71912019-10-11 11:13:39 -07006832 if (! *src)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006833 break;
6834 src++;
6835 }
6836 dest->numchildren = 0;
6837 dest->children = NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07006838 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006839 unsigned int i;
6840 int cn;
6841 dest->numchildren = dtd->scaffold[src_node].childcnt;
6842 dest->children = *contpos;
6843 *contpos += dest->numchildren;
Haibo Huang40a71912019-10-11 11:13:39 -07006844 for (i = 0, cn = dtd->scaffold[src_node].firstchild; i < dest->numchildren;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006845 i++, cn = dtd->scaffold[cn].nextsib) {
6846 build_node(parser, cn, &(dest->children[i]), contpos, strpos);
6847 }
6848 dest->name = NULL;
6849 }
6850}
6851
6852static XML_Content *
Haibo Huang40a71912019-10-11 11:13:39 -07006853build_model(XML_Parser parser) {
6854 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006855 XML_Content *ret;
6856 XML_Content *cpos;
Haibo Huang40a71912019-10-11 11:13:39 -07006857 XML_Char *str;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006858 int allocsize = (dtd->scaffCount * sizeof(XML_Content)
6859 + (dtd->contentStringLen * sizeof(XML_Char)));
6860
Elliott Hughes72472942018-01-10 08:36:10 -08006861 ret = (XML_Content *)MALLOC(parser, allocsize);
Haibo Huang40a71912019-10-11 11:13:39 -07006862 if (! ret)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006863 return NULL;
6864
Haibo Huang40a71912019-10-11 11:13:39 -07006865 str = (XML_Char *)(&ret[dtd->scaffCount]);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006866 cpos = &ret[1];
6867
6868 build_node(parser, 0, ret, &cpos, &str);
6869 return ret;
6870}
6871
6872static ELEMENT_TYPE *
Haibo Huang40a71912019-10-11 11:13:39 -07006873getElementType(XML_Parser parser, const ENCODING *enc, const char *ptr,
6874 const char *end) {
6875 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006876 const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
6877 ELEMENT_TYPE *ret;
6878
Haibo Huang40a71912019-10-11 11:13:39 -07006879 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006880 return NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07006881 ret = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
6882 sizeof(ELEMENT_TYPE));
6883 if (! ret)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006884 return NULL;
6885 if (ret->name != name)
6886 poolDiscard(&dtd->pool);
6887 else {
6888 poolFinish(&dtd->pool);
Haibo Huang40a71912019-10-11 11:13:39 -07006889 if (! setElementTypePrefix(parser, ret))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006890 return NULL;
6891 }
6892 return ret;
6893}
Elliott Hughes72472942018-01-10 08:36:10 -08006894
6895static XML_Char *
Haibo Huang40a71912019-10-11 11:13:39 -07006896copyString(const XML_Char *s, const XML_Memory_Handling_Suite *memsuite) {
6897 int charsRequired = 0;
6898 XML_Char *result;
Elliott Hughes72472942018-01-10 08:36:10 -08006899
Haibo Huang40a71912019-10-11 11:13:39 -07006900 /* First determine how long the string is */
6901 while (s[charsRequired] != 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08006902 charsRequired++;
Haibo Huang40a71912019-10-11 11:13:39 -07006903 }
6904 /* Include the terminator */
6905 charsRequired++;
Elliott Hughes72472942018-01-10 08:36:10 -08006906
Haibo Huang40a71912019-10-11 11:13:39 -07006907 /* Now allocate space for the copy */
6908 result = memsuite->malloc_fcn(charsRequired * sizeof(XML_Char));
6909 if (result == NULL)
6910 return NULL;
6911 /* Copy the original into place */
6912 memcpy(result, s, charsRequired * sizeof(XML_Char));
6913 return result;
Elliott Hughes72472942018-01-10 08:36:10 -08006914}