blob: 78ad787b28848a293d97fe8182eaffd4db728afe [file] [log] [blame]
Elliott Hughesf648a292021-04-01 15:10:13 -07001/* d667b5f8e56e24fdfaf5e38596d419d924a9fadceb987d81d5613ecb7ca51b0e (2.3.0+)
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 */
Elliott Hughesf648a292021-04-01 15:10:13 -070050#include <stdint.h> /* uintptr_t */
Haibo Huangd1a324a2020-10-28 22:19:36 -070051
Elliott Hughes72472942018-01-10 08:36:10 -080052#ifdef _WIN32
Haibo Huang40a71912019-10-11 11:13:39 -070053# define getpid GetCurrentProcessId
Paul Duffin3c2f09e2016-06-07 15:53:38 +010054#else
Haibo Huang40a71912019-10-11 11:13:39 -070055# include <sys/time.h> /* gettimeofday() */
56# include <sys/types.h> /* getpid() */
57# include <unistd.h> /* getpid() */
58# include <fcntl.h> /* O_RDONLY */
59# include <errno.h>
Paul Duffin3c2f09e2016-06-07 15:53:38 +010060#endif
The Android Open Source Projectb80e2872009-03-03 19:29:30 -080061
62#define XML_BUILDING_EXPAT 1
63
Elliott Hughes72472942018-01-10 08:36:10 -080064#ifdef _WIN32
Haibo Huang40a71912019-10-11 11:13:39 -070065# include "winconfig.h"
The Android Open Source Projectb80e2872009-03-03 19:29:30 -080066#elif defined(HAVE_EXPAT_CONFIG_H)
Haibo Huang40a71912019-10-11 11:13:39 -070067# include <expat_config.h>
Elliott Hughes72472942018-01-10 08:36:10 -080068#endif /* ndef _WIN32 */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -080069
Elliott Hughesd07d5a72009-09-25 16:04:37 -070070#include "ascii.h"
The Android Open Source Projectb80e2872009-03-03 19:29:30 -080071#include "expat.h"
Elliott Hughes72472942018-01-10 08:36:10 -080072#include "siphash.h"
73
74#if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
Haibo Huang40a71912019-10-11 11:13:39 -070075# if defined(HAVE_GETRANDOM)
76# include <sys/random.h> /* getrandom */
77# else
78# include <unistd.h> /* syscall */
79# include <sys/syscall.h> /* SYS_getrandom */
80# endif
81# if ! defined(GRND_NONBLOCK)
82# define GRND_NONBLOCK 0x0001
83# endif /* defined(GRND_NONBLOCK) */
84#endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */
Elliott Hughes72472942018-01-10 08:36:10 -080085
Haibo Huang40a71912019-10-11 11:13:39 -070086#if defined(HAVE_LIBBSD) \
Elliott Hughes72472942018-01-10 08:36:10 -080087 && (defined(HAVE_ARC4RANDOM_BUF) || defined(HAVE_ARC4RANDOM))
Haibo Huang40a71912019-10-11 11:13:39 -070088# include <bsd/stdlib.h>
Elliott Hughes72472942018-01-10 08:36:10 -080089#endif
90
Haibo Huang40a71912019-10-11 11:13:39 -070091#if defined(_WIN32) && ! defined(LOAD_LIBRARY_SEARCH_SYSTEM32)
92# define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800
Elliott Hughes72472942018-01-10 08:36:10 -080093#endif
94
Haibo Huang40a71912019-10-11 11:13:39 -070095#if ! defined(HAVE_GETRANDOM) && ! defined(HAVE_SYSCALL_GETRANDOM) \
96 && ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) \
97 && ! defined(XML_DEV_URANDOM) && ! defined(_WIN32) \
98 && ! defined(XML_POOR_ENTROPY)
99# error You do not have support for any sources of high quality entropy \
Elliott Hughes72472942018-01-10 08:36:10 -0800100 enabled. For end user security, that is probably not what you want. \
101 \
102 Your options include: \
Haibo Huangd1a324a2020-10-28 22:19:36 -0700103 * Linux >=3.17 + glibc >=2.25 (getrandom): HAVE_GETRANDOM, \
104 * Linux >=3.17 + glibc (including <2.25) (syscall SYS_getrandom): HAVE_SYSCALL_GETRANDOM, \
Elliott Hughes72472942018-01-10 08:36:10 -0800105 * BSD / macOS >=10.7 (arc4random_buf): HAVE_ARC4RANDOM_BUF, \
Haibo Huangd1a324a2020-10-28 22:19:36 -0700106 * BSD / macOS (including <10.7) (arc4random): HAVE_ARC4RANDOM, \
Elliott Hughes72472942018-01-10 08:36:10 -0800107 * libbsd (arc4random_buf): HAVE_ARC4RANDOM_BUF + HAVE_LIBBSD, \
108 * libbsd (arc4random): HAVE_ARC4RANDOM + HAVE_LIBBSD, \
Haibo Huangd1a324a2020-10-28 22:19:36 -0700109 * Linux (including <3.17) / BSD / macOS (including <10.7) (/dev/urandom): XML_DEV_URANDOM, \
110 * Windows >=Vista (rand_s): _WIN32. \
Elliott Hughes72472942018-01-10 08:36:10 -0800111 \
112 If insist on not using any of these, bypass this error by defining \
113 XML_POOR_ENTROPY; you have been warned. \
114 \
115 If you have reasons to patch this detection code away or need changes \
116 to the build system, please open a bug. Thank you!
117#endif
118
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800119#ifdef XML_UNICODE
Haibo Huang40a71912019-10-11 11:13:39 -0700120# define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
121# define XmlConvert XmlUtf16Convert
122# define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
123# define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
124# define XmlEncode XmlUtf16Encode
Haibo Huangd1a324a2020-10-28 22:19:36 -0700125# define MUST_CONVERT(enc, s) (! (enc)->isUtf16 || (((uintptr_t)(s)) & 1))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800126typedef unsigned short ICHAR;
127#else
Haibo Huang40a71912019-10-11 11:13:39 -0700128# define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
129# define XmlConvert XmlUtf8Convert
130# define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
131# define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
132# define XmlEncode XmlUtf8Encode
133# define MUST_CONVERT(enc, s) (! (enc)->isUtf8)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800134typedef char ICHAR;
135#endif
136
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800137#ifndef XML_NS
138
Haibo Huang40a71912019-10-11 11:13:39 -0700139# define XmlInitEncodingNS XmlInitEncoding
140# define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
141# undef XmlGetInternalEncodingNS
142# define XmlGetInternalEncodingNS XmlGetInternalEncoding
143# define XmlParseXmlDeclNS XmlParseXmlDecl
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800144
145#endif
146
147#ifdef XML_UNICODE
148
Haibo Huang40a71912019-10-11 11:13:39 -0700149# ifdef XML_UNICODE_WCHAR_T
150# define XML_T(x) (const wchar_t) x
151# define XML_L(x) L##x
152# else
153# define XML_T(x) (const unsigned short)x
154# define XML_L(x) x
155# endif
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800156
157#else
158
Haibo Huang40a71912019-10-11 11:13:39 -0700159# define XML_T(x) x
160# define XML_L(x) x
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800161
162#endif
163
164/* Round up n to be a multiple of sz, where sz is a power of 2. */
Haibo Huang40a71912019-10-11 11:13:39 -0700165#define ROUND_UP(n, sz) (((n) + ((sz)-1)) & ~((sz)-1))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800166
Elliott Hughesaaec48e2018-08-16 16:29:01 -0700167/* Do safe (NULL-aware) pointer arithmetic */
168#define EXPAT_SAFE_PTR_DIFF(p, q) (((p) && (q)) ? ((p) - (q)) : 0)
169
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800170#include "internal.h"
171#include "xmltok.h"
172#include "xmlrole.h"
173
174typedef const XML_Char *KEY;
175
176typedef struct {
177 KEY name;
178} NAMED;
179
180typedef struct {
181 NAMED **v;
182 unsigned char power;
183 size_t size;
184 size_t used;
185 const XML_Memory_Handling_Suite *mem;
186} HASH_TABLE;
187
Haibo Huang40a71912019-10-11 11:13:39 -0700188static size_t keylen(KEY s);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800189
Haibo Huang40a71912019-10-11 11:13:39 -0700190static void copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800191
192/* For probing (after a collision) we need a step size relative prime
193 to the hash table size, which is a power of 2. We use double-hashing,
194 since we can calculate a second hash value cheaply by taking those bits
195 of the first hash value that were discarded (masked out) when the table
196 index was calculated: index = hash & mask, where mask = table->size - 1.
197 We limit the maximum step size to table->size / 4 (mask >> 2) and make
198 it odd, since odd numbers are always relative prime to a power of 2.
199*/
Haibo Huang40a71912019-10-11 11:13:39 -0700200#define SECOND_HASH(hash, mask, power) \
201 ((((hash) & ~(mask)) >> ((power)-1)) & ((mask) >> 2))
202#define PROBE_STEP(hash, mask, power) \
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800203 ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
204
205typedef struct {
206 NAMED **p;
207 NAMED **end;
208} HASH_TABLE_ITER;
209
Haibo Huang40a71912019-10-11 11:13:39 -0700210#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800211#define INIT_DATA_BUF_SIZE 1024
212#define INIT_ATTS_SIZE 16
213#define INIT_ATTS_VERSION 0xFFFFFFFF
214#define INIT_BLOCK_SIZE 1024
215#define INIT_BUFFER_SIZE 1024
216
217#define EXPAND_SPARE 24
218
219typedef struct binding {
220 struct prefix *prefix;
221 struct binding *nextTagBinding;
222 struct binding *prevPrefixBinding;
223 const struct attribute_id *attId;
224 XML_Char *uri;
225 int uriLen;
226 int uriAlloc;
227} BINDING;
228
229typedef struct prefix {
230 const XML_Char *name;
231 BINDING *binding;
232} PREFIX;
233
234typedef struct {
235 const XML_Char *str;
236 const XML_Char *localPart;
237 const XML_Char *prefix;
238 int strLen;
239 int uriLen;
240 int prefixLen;
241} TAG_NAME;
242
243/* TAG represents an open element.
244 The name of the element is stored in both the document and API
245 encodings. The memory buffer 'buf' is a separately-allocated
246 memory area which stores the name. During the XML_Parse()/
247 XMLParseBuffer() when the element is open, the memory for the 'raw'
248 version of the name (in the document encoding) is shared with the
249 document buffer. If the element is open across calls to
250 XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
251 contain the 'raw' name as well.
252
253 A parser re-uses these structures, maintaining a list of allocated
254 TAG objects in a free list.
255*/
256typedef struct tag {
Haibo Huang40a71912019-10-11 11:13:39 -0700257 struct tag *parent; /* parent of this element */
258 const char *rawName; /* tagName in the original encoding */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800259 int rawNameLength;
Haibo Huang40a71912019-10-11 11:13:39 -0700260 TAG_NAME name; /* tagName in the API encoding */
261 char *buf; /* buffer for name components */
262 char *bufEnd; /* end of the buffer */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800263 BINDING *bindings;
264} TAG;
265
266typedef struct {
267 const XML_Char *name;
268 const XML_Char *textPtr;
Haibo Huang40a71912019-10-11 11:13:39 -0700269 int textLen; /* length in XML_Chars */
270 int processed; /* # of processed bytes - when suspended */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800271 const XML_Char *systemId;
272 const XML_Char *base;
273 const XML_Char *publicId;
274 const XML_Char *notation;
275 XML_Bool open;
276 XML_Bool is_param;
277 XML_Bool is_internal; /* true if declared in internal subset outside PE */
278} ENTITY;
279
280typedef struct {
Haibo Huang40a71912019-10-11 11:13:39 -0700281 enum XML_Content_Type type;
282 enum XML_Content_Quant quant;
283 const XML_Char *name;
284 int firstchild;
285 int lastchild;
286 int childcnt;
287 int nextsib;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800288} CONTENT_SCAFFOLD;
289
290#define INIT_SCAFFOLD_ELEMENTS 32
291
292typedef struct block {
293 struct block *next;
294 int size;
295 XML_Char s[1];
296} BLOCK;
297
298typedef struct {
299 BLOCK *blocks;
300 BLOCK *freeBlocks;
301 const XML_Char *end;
302 XML_Char *ptr;
303 XML_Char *start;
304 const XML_Memory_Handling_Suite *mem;
305} STRING_POOL;
306
307/* The XML_Char before the name is used to determine whether
308 an attribute has been specified. */
309typedef struct attribute_id {
310 XML_Char *name;
311 PREFIX *prefix;
312 XML_Bool maybeTokenized;
313 XML_Bool xmlns;
314} ATTRIBUTE_ID;
315
316typedef struct {
317 const ATTRIBUTE_ID *id;
318 XML_Bool isCdata;
319 const XML_Char *value;
320} DEFAULT_ATTRIBUTE;
321
322typedef struct {
323 unsigned long version;
324 unsigned long hash;
325 const XML_Char *uriName;
326} NS_ATT;
327
328typedef struct {
329 const XML_Char *name;
330 PREFIX *prefix;
331 const ATTRIBUTE_ID *idAtt;
332 int nDefaultAtts;
333 int allocDefaultAtts;
334 DEFAULT_ATTRIBUTE *defaultAtts;
335} ELEMENT_TYPE;
336
337typedef struct {
338 HASH_TABLE generalEntities;
339 HASH_TABLE elementTypes;
340 HASH_TABLE attributeIds;
341 HASH_TABLE prefixes;
342 STRING_POOL pool;
343 STRING_POOL entityValuePool;
344 /* false once a parameter entity reference has been skipped */
345 XML_Bool keepProcessing;
346 /* true once an internal or external PE reference has been encountered;
347 this includes the reference to an external subset */
348 XML_Bool hasParamEntityRefs;
349 XML_Bool standalone;
350#ifdef XML_DTD
351 /* indicates if external PE has been read */
352 XML_Bool paramEntityRead;
353 HASH_TABLE paramEntities;
354#endif /* XML_DTD */
355 PREFIX defaultPrefix;
356 /* === scaffolding for building content model === */
357 XML_Bool in_eldecl;
358 CONTENT_SCAFFOLD *scaffold;
359 unsigned contentStringLen;
360 unsigned scaffSize;
361 unsigned scaffCount;
362 int scaffLevel;
363 int *scaffIndex;
364} DTD;
365
366typedef struct open_internal_entity {
367 const char *internalEventPtr;
368 const char *internalEventEndPtr;
369 struct open_internal_entity *next;
370 ENTITY *entity;
371 int startTagLevel;
372 XML_Bool betweenDecl; /* WFC: PE Between Declarations */
373} OPEN_INTERNAL_ENTITY;
374
Haibo Huang40a71912019-10-11 11:13:39 -0700375typedef enum XML_Error PTRCALL Processor(XML_Parser parser, const char *start,
376 const char *end, const char **endPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800377
378static Processor prologProcessor;
379static Processor prologInitProcessor;
380static Processor contentProcessor;
381static Processor cdataSectionProcessor;
382#ifdef XML_DTD
383static Processor ignoreSectionProcessor;
384static Processor externalParEntProcessor;
385static Processor externalParEntInitProcessor;
386static Processor entityValueProcessor;
387static Processor entityValueInitProcessor;
388#endif /* XML_DTD */
389static Processor epilogProcessor;
390static Processor errorProcessor;
391static Processor externalEntityInitProcessor;
392static Processor externalEntityInitProcessor2;
393static Processor externalEntityInitProcessor3;
394static Processor externalEntityContentProcessor;
395static Processor internalEntityProcessor;
396
Haibo Huang40a71912019-10-11 11:13:39 -0700397static enum XML_Error handleUnknownEncoding(XML_Parser parser,
398 const XML_Char *encodingName);
399static enum XML_Error processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
400 const char *s, const char *next);
401static enum XML_Error initializeEncoding(XML_Parser parser);
402static enum XML_Error doProlog(XML_Parser parser, const ENCODING *enc,
403 const char *s, const char *end, int tok,
404 const char *next, const char **nextPtr,
405 XML_Bool haveMore, XML_Bool allowClosingDoctype);
406static enum XML_Error processInternalEntity(XML_Parser parser, ENTITY *entity,
407 XML_Bool betweenDecl);
408static enum XML_Error doContent(XML_Parser parser, int startTagLevel,
409 const ENCODING *enc, const char *start,
410 const char *end, const char **endPtr,
411 XML_Bool haveMore);
412static enum XML_Error doCdataSection(XML_Parser parser, const ENCODING *,
413 const char **startPtr, const char *end,
414 const char **nextPtr, XML_Bool haveMore);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800415#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -0700416static enum XML_Error doIgnoreSection(XML_Parser parser, const ENCODING *,
417 const char **startPtr, const char *end,
418 const char **nextPtr, XML_Bool haveMore);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800419#endif /* XML_DTD */
420
Haibo Huang40a71912019-10-11 11:13:39 -0700421static void freeBindings(XML_Parser parser, BINDING *bindings);
422static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *,
423 const char *s, TAG_NAME *tagNamePtr,
424 BINDING **bindingsPtr);
425static enum XML_Error addBinding(XML_Parser parser, PREFIX *prefix,
426 const ATTRIBUTE_ID *attId, const XML_Char *uri,
427 BINDING **bindingsPtr);
428static int defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
429 XML_Bool isId, const XML_Char *dfltValue,
430 XML_Parser parser);
431static enum XML_Error storeAttributeValue(XML_Parser parser, const ENCODING *,
432 XML_Bool isCdata, const char *,
433 const char *, STRING_POOL *);
434static enum XML_Error appendAttributeValue(XML_Parser parser, const ENCODING *,
435 XML_Bool isCdata, const char *,
436 const char *, STRING_POOL *);
437static ATTRIBUTE_ID *getAttributeId(XML_Parser parser, const ENCODING *enc,
438 const char *start, const char *end);
439static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
440static enum XML_Error storeEntityValue(XML_Parser parser, const ENCODING *enc,
441 const char *start, const char *end);
442static int reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
443 const char *start, const char *end);
444static int reportComment(XML_Parser parser, const ENCODING *enc,
445 const char *start, const char *end);
446static void reportDefault(XML_Parser parser, const ENCODING *enc,
447 const char *start, const char *end);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800448
Haibo Huang40a71912019-10-11 11:13:39 -0700449static const XML_Char *getContext(XML_Parser parser);
450static XML_Bool setContext(XML_Parser parser, const XML_Char *context);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800451
452static void FASTCALL normalizePublicId(XML_Char *s);
453
Haibo Huang40a71912019-10-11 11:13:39 -0700454static DTD *dtdCreate(const XML_Memory_Handling_Suite *ms);
Elliott Hughes72472942018-01-10 08:36:10 -0800455/* do not call if m_parentParser != NULL */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800456static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
Haibo Huang40a71912019-10-11 11:13:39 -0700457static void dtdDestroy(DTD *p, XML_Bool isDocEntity,
458 const XML_Memory_Handling_Suite *ms);
459static int dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
460 const XML_Memory_Handling_Suite *ms);
461static int copyEntityTable(XML_Parser oldParser, HASH_TABLE *, STRING_POOL *,
462 const HASH_TABLE *);
463static NAMED *lookup(XML_Parser parser, HASH_TABLE *table, KEY name,
464 size_t createSize);
465static void FASTCALL hashTableInit(HASH_TABLE *,
466 const XML_Memory_Handling_Suite *ms);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800467static void FASTCALL hashTableClear(HASH_TABLE *);
468static void FASTCALL hashTableDestroy(HASH_TABLE *);
Haibo Huang40a71912019-10-11 11:13:39 -0700469static void FASTCALL hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
470static NAMED *FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800471
Haibo Huang40a71912019-10-11 11:13:39 -0700472static void FASTCALL poolInit(STRING_POOL *,
473 const XML_Memory_Handling_Suite *ms);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800474static void FASTCALL poolClear(STRING_POOL *);
475static void FASTCALL poolDestroy(STRING_POOL *);
Haibo Huang40a71912019-10-11 11:13:39 -0700476static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
477 const char *ptr, const char *end);
478static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
479 const char *ptr, const char *end);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800480static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
Haibo Huang40a71912019-10-11 11:13:39 -0700481static const XML_Char *FASTCALL poolCopyString(STRING_POOL *pool,
482 const XML_Char *s);
483static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s,
484 int n);
485static const XML_Char *FASTCALL poolAppendString(STRING_POOL *pool,
486 const XML_Char *s);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800487
488static int FASTCALL nextScaffoldPart(XML_Parser parser);
Haibo Huang40a71912019-10-11 11:13:39 -0700489static XML_Content *build_model(XML_Parser parser);
490static ELEMENT_TYPE *getElementType(XML_Parser parser, const ENCODING *enc,
491 const char *ptr, const char *end);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800492
Elliott Hughes72472942018-01-10 08:36:10 -0800493static XML_Char *copyString(const XML_Char *s,
494 const XML_Memory_Handling_Suite *memsuite);
495
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100496static unsigned long generate_hash_secret_salt(XML_Parser parser);
Elliott Hughes35e432d2012-09-09 14:23:38 -0700497static XML_Bool startParsing(XML_Parser parser);
498
Haibo Huang40a71912019-10-11 11:13:39 -0700499static XML_Parser parserCreate(const XML_Char *encodingName,
500 const XML_Memory_Handling_Suite *memsuite,
501 const XML_Char *nameSep, DTD *dtd);
Elliott Hughes35e432d2012-09-09 14:23:38 -0700502
Haibo Huang40a71912019-10-11 11:13:39 -0700503static void parserInit(XML_Parser parser, const XML_Char *encodingName);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800504
505#define poolStart(pool) ((pool)->start)
506#define poolEnd(pool) ((pool)->ptr)
507#define poolLength(pool) ((pool)->ptr - (pool)->start)
508#define poolChop(pool) ((void)--(pool->ptr))
509#define poolLastChar(pool) (((pool)->ptr)[-1])
510#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
511#define poolFinish(pool) ((pool)->start = (pool)->ptr)
Haibo Huang40a71912019-10-11 11:13:39 -0700512#define poolAppendChar(pool, c) \
513 (((pool)->ptr == (pool)->end && ! poolGrow(pool)) \
514 ? 0 \
515 : ((*((pool)->ptr)++ = c), 1))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800516
517struct XML_ParserStruct {
Elliott Hughes72472942018-01-10 08:36:10 -0800518 /* The first member must be m_userData so that the XML_GetUserData
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800519 macro works. */
520 void *m_userData;
521 void *m_handlerArg;
522 char *m_buffer;
523 const XML_Memory_Handling_Suite m_mem;
524 /* first character to be parsed */
525 const char *m_bufferPtr;
526 /* past last character to be parsed */
527 char *m_bufferEnd;
Elliott Hughes72472942018-01-10 08:36:10 -0800528 /* allocated end of m_buffer */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800529 const char *m_bufferLim;
530 XML_Index m_parseEndByteIndex;
531 const char *m_parseEndPtr;
532 XML_Char *m_dataBuf;
533 XML_Char *m_dataBufEnd;
534 XML_StartElementHandler m_startElementHandler;
535 XML_EndElementHandler m_endElementHandler;
536 XML_CharacterDataHandler m_characterDataHandler;
537 XML_ProcessingInstructionHandler m_processingInstructionHandler;
538 XML_CommentHandler m_commentHandler;
539 XML_StartCdataSectionHandler m_startCdataSectionHandler;
540 XML_EndCdataSectionHandler m_endCdataSectionHandler;
541 XML_DefaultHandler m_defaultHandler;
542 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
543 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
544 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
545 XML_NotationDeclHandler m_notationDeclHandler;
546 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
547 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
548 XML_NotStandaloneHandler m_notStandaloneHandler;
549 XML_ExternalEntityRefHandler m_externalEntityRefHandler;
550 XML_Parser m_externalEntityRefHandlerArg;
551 XML_SkippedEntityHandler m_skippedEntityHandler;
552 XML_UnknownEncodingHandler m_unknownEncodingHandler;
553 XML_ElementDeclHandler m_elementDeclHandler;
554 XML_AttlistDeclHandler m_attlistDeclHandler;
555 XML_EntityDeclHandler m_entityDeclHandler;
556 XML_XmlDeclHandler m_xmlDeclHandler;
557 const ENCODING *m_encoding;
558 INIT_ENCODING m_initEncoding;
559 const ENCODING *m_internalEncoding;
560 const XML_Char *m_protocolEncodingName;
561 XML_Bool m_ns;
562 XML_Bool m_ns_triplets;
563 void *m_unknownEncodingMem;
564 void *m_unknownEncodingData;
565 void *m_unknownEncodingHandlerData;
Haibo Huang40a71912019-10-11 11:13:39 -0700566 void(XMLCALL *m_unknownEncodingRelease)(void *);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800567 PROLOG_STATE m_prologState;
568 Processor *m_processor;
569 enum XML_Error m_errorCode;
570 const char *m_eventPtr;
571 const char *m_eventEndPtr;
572 const char *m_positionPtr;
573 OPEN_INTERNAL_ENTITY *m_openInternalEntities;
574 OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
575 XML_Bool m_defaultExpandInternalEntities;
576 int m_tagLevel;
577 ENTITY *m_declEntity;
578 const XML_Char *m_doctypeName;
579 const XML_Char *m_doctypeSysid;
580 const XML_Char *m_doctypePubid;
581 const XML_Char *m_declAttributeType;
582 const XML_Char *m_declNotationName;
583 const XML_Char *m_declNotationPublicId;
584 ELEMENT_TYPE *m_declElementType;
585 ATTRIBUTE_ID *m_declAttributeId;
586 XML_Bool m_declAttributeIsCdata;
587 XML_Bool m_declAttributeIsId;
588 DTD *m_dtd;
589 const XML_Char *m_curBase;
590 TAG *m_tagStack;
591 TAG *m_freeTagList;
592 BINDING *m_inheritedBindings;
593 BINDING *m_freeBindingList;
594 int m_attsSize;
595 int m_nSpecifiedAtts;
596 int m_idAttIndex;
597 ATTRIBUTE *m_atts;
598 NS_ATT *m_nsAtts;
599 unsigned long m_nsAttsVersion;
600 unsigned char m_nsAttsPower;
Elliott Hughes35e432d2012-09-09 14:23:38 -0700601#ifdef XML_ATTR_INFO
602 XML_AttrInfo *m_attInfo;
603#endif
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800604 POSITION m_position;
605 STRING_POOL m_tempPool;
606 STRING_POOL m_temp2Pool;
607 char *m_groupConnector;
608 unsigned int m_groupSize;
609 XML_Char m_namespaceSeparator;
610 XML_Parser m_parentParser;
611 XML_ParsingStatus m_parsingStatus;
612#ifdef XML_DTD
613 XML_Bool m_isParamEntity;
614 XML_Bool m_useForeignDTD;
615 enum XML_ParamEntityParsing m_paramEntityParsing;
616#endif
Elliott Hughes35e432d2012-09-09 14:23:38 -0700617 unsigned long m_hash_secret_salt;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800618};
619
Haibo Huang40a71912019-10-11 11:13:39 -0700620#define MALLOC(parser, s) (parser->m_mem.malloc_fcn((s)))
621#define REALLOC(parser, p, s) (parser->m_mem.realloc_fcn((p), (s)))
622#define FREE(parser, p) (parser->m_mem.free_fcn((p)))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800623
624XML_Parser XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -0700625XML_ParserCreate(const XML_Char *encodingName) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800626 return XML_ParserCreate_MM(encodingName, NULL, NULL);
627}
628
629XML_Parser XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -0700630XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800631 XML_Char tmp[2];
632 *tmp = nsSep;
633 return XML_ParserCreate_MM(encodingName, NULL, tmp);
634}
635
Haibo Huang40a71912019-10-11 11:13:39 -0700636static const XML_Char implicitContext[]
637 = {ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h,
638 ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH,
639 ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD,
640 ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r,
641 ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L,
642 ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8,
643 ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e,
644 ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e,
645 '\0'};
Elliott Hughes72472942018-01-10 08:36:10 -0800646
647/* To avoid warnings about unused functions: */
648#if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM)
649
Haibo Huang40a71912019-10-11 11:13:39 -0700650# if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
Elliott Hughes72472942018-01-10 08:36:10 -0800651
652/* Obtain entropy on Linux 3.17+ */
653static int
Haibo Huang40a71912019-10-11 11:13:39 -0700654writeRandomBytes_getrandom_nonblock(void *target, size_t count) {
655 int success = 0; /* full count bytes written? */
Elliott Hughes72472942018-01-10 08:36:10 -0800656 size_t bytesWrittenTotal = 0;
657 const unsigned int getrandomFlags = GRND_NONBLOCK;
658
659 do {
Haibo Huang40a71912019-10-11 11:13:39 -0700660 void *const currentTarget = (void *)((char *)target + bytesWrittenTotal);
Elliott Hughes72472942018-01-10 08:36:10 -0800661 const size_t bytesToWrite = count - bytesWrittenTotal;
662
663 const int bytesWrittenMore =
Haibo Huang40a71912019-10-11 11:13:39 -0700664# if defined(HAVE_GETRANDOM)
Elliott Hughes72472942018-01-10 08:36:10 -0800665 getrandom(currentTarget, bytesToWrite, getrandomFlags);
Haibo Huang40a71912019-10-11 11:13:39 -0700666# else
Elliott Hughes72472942018-01-10 08:36:10 -0800667 syscall(SYS_getrandom, currentTarget, bytesToWrite, getrandomFlags);
Haibo Huang40a71912019-10-11 11:13:39 -0700668# endif
Elliott Hughes72472942018-01-10 08:36:10 -0800669
670 if (bytesWrittenMore > 0) {
671 bytesWrittenTotal += bytesWrittenMore;
672 if (bytesWrittenTotal >= count)
673 success = 1;
674 }
675 } while (! success && (errno == EINTR));
676
677 return success;
678}
679
Haibo Huang40a71912019-10-11 11:13:39 -0700680# endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */
Elliott Hughes72472942018-01-10 08:36:10 -0800681
Haibo Huang40a71912019-10-11 11:13:39 -0700682# if ! defined(_WIN32) && defined(XML_DEV_URANDOM)
Elliott Hughes72472942018-01-10 08:36:10 -0800683
684/* Extract entropy from /dev/urandom */
685static int
Haibo Huang40a71912019-10-11 11:13:39 -0700686writeRandomBytes_dev_urandom(void *target, size_t count) {
687 int success = 0; /* full count bytes written? */
Elliott Hughes72472942018-01-10 08:36:10 -0800688 size_t bytesWrittenTotal = 0;
689
690 const int fd = open("/dev/urandom", O_RDONLY);
691 if (fd < 0) {
692 return 0;
693 }
694
695 do {
Haibo Huang40a71912019-10-11 11:13:39 -0700696 void *const currentTarget = (void *)((char *)target + bytesWrittenTotal);
Elliott Hughes72472942018-01-10 08:36:10 -0800697 const size_t bytesToWrite = count - bytesWrittenTotal;
698
699 const ssize_t bytesWrittenMore = read(fd, currentTarget, bytesToWrite);
700
701 if (bytesWrittenMore > 0) {
702 bytesWrittenTotal += bytesWrittenMore;
703 if (bytesWrittenTotal >= count)
704 success = 1;
705 }
706 } while (! success && (errno == EINTR));
707
708 close(fd);
709 return success;
710}
711
Haibo Huang40a71912019-10-11 11:13:39 -0700712# endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */
Elliott Hughes72472942018-01-10 08:36:10 -0800713
Haibo Huang40a71912019-10-11 11:13:39 -0700714#endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */
Elliott Hughes72472942018-01-10 08:36:10 -0800715
Haibo Huangfd5e81a2019-06-20 12:09:36 -0700716#if defined(HAVE_ARC4RANDOM) && ! defined(HAVE_ARC4RANDOM_BUF)
Elliott Hughes72472942018-01-10 08:36:10 -0800717
718static void
Haibo Huang40a71912019-10-11 11:13:39 -0700719writeRandomBytes_arc4random(void *target, size_t count) {
Elliott Hughes72472942018-01-10 08:36:10 -0800720 size_t bytesWrittenTotal = 0;
721
722 while (bytesWrittenTotal < count) {
723 const uint32_t random32 = arc4random();
724 size_t i = 0;
725
726 for (; (i < sizeof(random32)) && (bytesWrittenTotal < count);
Haibo Huang40a71912019-10-11 11:13:39 -0700727 i++, bytesWrittenTotal++) {
Elliott Hughes72472942018-01-10 08:36:10 -0800728 const uint8_t random8 = (uint8_t)(random32 >> (i * 8));
729 ((uint8_t *)target)[bytesWrittenTotal] = random8;
730 }
731 }
732}
733
Haibo Huang40a71912019-10-11 11:13:39 -0700734#endif /* defined(HAVE_ARC4RANDOM) && ! defined(HAVE_ARC4RANDOM_BUF) */
Elliott Hughes72472942018-01-10 08:36:10 -0800735
736#ifdef _WIN32
737
Haibo Huangd1a324a2020-10-28 22:19:36 -0700738/* Provide declaration of rand_s() for MinGW-32 (not 64, which has it),
739 as it didn't declare it in its header prior to version 5.3.0 of its
740 runtime package (mingwrt, containing stdlib.h). The upstream fix
741 was introduced at https://osdn.net/projects/mingw/ticket/39658 . */
742# if defined(__MINGW32__) && defined(__MINGW32_VERSION) \
743 && __MINGW32_VERSION < 5003000L && ! defined(__MINGW64_VERSION_MAJOR)
744__declspec(dllimport) int rand_s(unsigned int *);
745# endif
746
Haibo Huang40a71912019-10-11 11:13:39 -0700747/* Obtain entropy on Windows using the rand_s() function which
748 * generates cryptographically secure random numbers. Internally it
749 * uses RtlGenRandom API which is present in Windows XP and later.
Elliott Hughes72472942018-01-10 08:36:10 -0800750 */
751static int
Haibo Huang40a71912019-10-11 11:13:39 -0700752writeRandomBytes_rand_s(void *target, size_t count) {
753 size_t bytesWrittenTotal = 0;
Elliott Hughes72472942018-01-10 08:36:10 -0800754
Haibo Huang40a71912019-10-11 11:13:39 -0700755 while (bytesWrittenTotal < count) {
756 unsigned int random32 = 0;
757 size_t i = 0;
758
759 if (rand_s(&random32))
760 return 0; /* failure */
761
762 for (; (i < sizeof(random32)) && (bytesWrittenTotal < count);
763 i++, bytesWrittenTotal++) {
764 const uint8_t random8 = (uint8_t)(random32 >> (i * 8));
765 ((uint8_t *)target)[bytesWrittenTotal] = random8;
Elliott Hughes72472942018-01-10 08:36:10 -0800766 }
Elliott Hughes72472942018-01-10 08:36:10 -0800767 }
Haibo Huang40a71912019-10-11 11:13:39 -0700768 return 1; /* success */
Elliott Hughes72472942018-01-10 08:36:10 -0800769}
770
771#endif /* _WIN32 */
772
Elliott Hughes72472942018-01-10 08:36:10 -0800773#if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM)
774
Elliott Hughes35e432d2012-09-09 14:23:38 -0700775static unsigned long
Haibo Huang40a71912019-10-11 11:13:39 -0700776gather_time_entropy(void) {
777# ifdef _WIN32
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100778 FILETIME ft;
779 GetSystemTimeAsFileTime(&ft); /* never fails */
780 return ft.dwHighDateTime ^ ft.dwLowDateTime;
Haibo Huang40a71912019-10-11 11:13:39 -0700781# else
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100782 struct timeval tv;
783 int gettimeofday_res;
784
785 gettimeofday_res = gettimeofday(&tv, NULL);
Elliott Hughes72472942018-01-10 08:36:10 -0800786
Haibo Huang40a71912019-10-11 11:13:39 -0700787# if defined(NDEBUG)
Elliott Hughes72472942018-01-10 08:36:10 -0800788 (void)gettimeofday_res;
Haibo Huang40a71912019-10-11 11:13:39 -0700789# else
790 assert(gettimeofday_res == 0);
791# endif /* defined(NDEBUG) */
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100792
793 /* Microseconds time is <20 bits entropy */
794 return tv.tv_usec;
Haibo Huang40a71912019-10-11 11:13:39 -0700795# endif
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100796}
797
Haibo Huang40a71912019-10-11 11:13:39 -0700798#endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */
Elliott Hughes72472942018-01-10 08:36:10 -0800799
800static unsigned long
Haibo Huang40a71912019-10-11 11:13:39 -0700801ENTROPY_DEBUG(const char *label, unsigned long entropy) {
802 const char *const EXPAT_ENTROPY_DEBUG = getenv("EXPAT_ENTROPY_DEBUG");
Elliott Hughes72472942018-01-10 08:36:10 -0800803 if (EXPAT_ENTROPY_DEBUG && ! strcmp(EXPAT_ENTROPY_DEBUG, "1")) {
Haibo Huang40a71912019-10-11 11:13:39 -0700804 fprintf(stderr, "Entropy: %s --> 0x%0*lx (%lu bytes)\n", label,
805 (int)sizeof(entropy) * 2, entropy, (unsigned long)sizeof(entropy));
Elliott Hughes72472942018-01-10 08:36:10 -0800806 }
807 return entropy;
808}
809
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100810static unsigned long
Haibo Huang40a71912019-10-11 11:13:39 -0700811generate_hash_secret_salt(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -0800812 unsigned long entropy;
813 (void)parser;
814
815 /* "Failproof" high quality providers: */
816#if defined(HAVE_ARC4RANDOM_BUF)
817 arc4random_buf(&entropy, sizeof(entropy));
818 return ENTROPY_DEBUG("arc4random_buf", entropy);
819#elif defined(HAVE_ARC4RANDOM)
820 writeRandomBytes_arc4random((void *)&entropy, sizeof(entropy));
821 return ENTROPY_DEBUG("arc4random", entropy);
822#else
823 /* Try high quality providers first .. */
Haibo Huang40a71912019-10-11 11:13:39 -0700824# ifdef _WIN32
825 if (writeRandomBytes_rand_s((void *)&entropy, sizeof(entropy))) {
826 return ENTROPY_DEBUG("rand_s", entropy);
Elliott Hughes72472942018-01-10 08:36:10 -0800827 }
Haibo Huang40a71912019-10-11 11:13:39 -0700828# elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
Elliott Hughes72472942018-01-10 08:36:10 -0800829 if (writeRandomBytes_getrandom_nonblock((void *)&entropy, sizeof(entropy))) {
830 return ENTROPY_DEBUG("getrandom", entropy);
831 }
Haibo Huang40a71912019-10-11 11:13:39 -0700832# endif
833# if ! defined(_WIN32) && defined(XML_DEV_URANDOM)
Elliott Hughes72472942018-01-10 08:36:10 -0800834 if (writeRandomBytes_dev_urandom((void *)&entropy, sizeof(entropy))) {
835 return ENTROPY_DEBUG("/dev/urandom", entropy);
836 }
Haibo Huang40a71912019-10-11 11:13:39 -0700837# endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */
Elliott Hughes72472942018-01-10 08:36:10 -0800838 /* .. and self-made low quality for backup: */
839
840 /* Process ID is 0 bits entropy if attacker has local access */
841 entropy = gather_time_entropy() ^ getpid();
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100842
843 /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */
844 if (sizeof(unsigned long) == 4) {
Elliott Hughes72472942018-01-10 08:36:10 -0800845 return ENTROPY_DEBUG("fallback(4)", entropy * 2147483647);
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100846 } else {
Elliott Hughes72472942018-01-10 08:36:10 -0800847 return ENTROPY_DEBUG("fallback(8)",
Haibo Huang40a71912019-10-11 11:13:39 -0700848 entropy * (unsigned long)2305843009213693951ULL);
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100849 }
Elliott Hughes72472942018-01-10 08:36:10 -0800850#endif
851}
852
853static unsigned long
854get_hash_secret_salt(XML_Parser parser) {
855 if (parser->m_parentParser != NULL)
856 return get_hash_secret_salt(parser->m_parentParser);
857 return parser->m_hash_secret_salt;
Elliott Hughes35e432d2012-09-09 14:23:38 -0700858}
859
Haibo Huang40a71912019-10-11 11:13:39 -0700860static XML_Bool /* only valid for root parser */
861startParsing(XML_Parser parser) {
862 /* hash functions must be initialized before setContext() is called */
863 if (parser->m_hash_secret_salt == 0)
864 parser->m_hash_secret_salt = generate_hash_secret_salt(parser);
865 if (parser->m_ns) {
866 /* implicit context only set for root parser, since child
867 parsers (i.e. external entity parsers) will inherit it
868 */
869 return setContext(parser, implicitContext);
870 }
871 return XML_TRUE;
Elliott Hughes35e432d2012-09-09 14:23:38 -0700872}
873
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800874XML_Parser XMLCALL
875XML_ParserCreate_MM(const XML_Char *encodingName,
876 const XML_Memory_Handling_Suite *memsuite,
Haibo Huang40a71912019-10-11 11:13:39 -0700877 const XML_Char *nameSep) {
Elliott Hughes35e432d2012-09-09 14:23:38 -0700878 return parserCreate(encodingName, memsuite, nameSep, NULL);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800879}
880
881static XML_Parser
882parserCreate(const XML_Char *encodingName,
Haibo Huang40a71912019-10-11 11:13:39 -0700883 const XML_Memory_Handling_Suite *memsuite, const XML_Char *nameSep,
884 DTD *dtd) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800885 XML_Parser parser;
886
887 if (memsuite) {
888 XML_Memory_Handling_Suite *mtemp;
Haibo Huang40a71912019-10-11 11:13:39 -0700889 parser = (XML_Parser)memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800890 if (parser != NULL) {
891 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
892 mtemp->malloc_fcn = memsuite->malloc_fcn;
893 mtemp->realloc_fcn = memsuite->realloc_fcn;
894 mtemp->free_fcn = memsuite->free_fcn;
895 }
Haibo Huang40a71912019-10-11 11:13:39 -0700896 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800897 XML_Memory_Handling_Suite *mtemp;
898 parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
899 if (parser != NULL) {
900 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
901 mtemp->malloc_fcn = malloc;
902 mtemp->realloc_fcn = realloc;
903 mtemp->free_fcn = free;
904 }
905 }
906
Haibo Huang40a71912019-10-11 11:13:39 -0700907 if (! parser)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800908 return parser;
909
Elliott Hughes72472942018-01-10 08:36:10 -0800910 parser->m_buffer = NULL;
911 parser->m_bufferLim = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800912
Elliott Hughes72472942018-01-10 08:36:10 -0800913 parser->m_attsSize = INIT_ATTS_SIZE;
Haibo Huang40a71912019-10-11 11:13:39 -0700914 parser->m_atts
915 = (ATTRIBUTE *)MALLOC(parser, parser->m_attsSize * sizeof(ATTRIBUTE));
Elliott Hughes72472942018-01-10 08:36:10 -0800916 if (parser->m_atts == NULL) {
917 FREE(parser, parser);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800918 return NULL;
919 }
Elliott Hughes35e432d2012-09-09 14:23:38 -0700920#ifdef XML_ATTR_INFO
Haibo Huang40a71912019-10-11 11:13:39 -0700921 parser->m_attInfo = (XML_AttrInfo *)MALLOC(
922 parser, parser->m_attsSize * sizeof(XML_AttrInfo));
Elliott Hughes72472942018-01-10 08:36:10 -0800923 if (parser->m_attInfo == NULL) {
924 FREE(parser, parser->m_atts);
925 FREE(parser, parser);
Elliott Hughes35e432d2012-09-09 14:23:38 -0700926 return NULL;
927 }
928#endif
Haibo Huang40a71912019-10-11 11:13:39 -0700929 parser->m_dataBuf
930 = (XML_Char *)MALLOC(parser, INIT_DATA_BUF_SIZE * sizeof(XML_Char));
Elliott Hughes72472942018-01-10 08:36:10 -0800931 if (parser->m_dataBuf == NULL) {
932 FREE(parser, parser->m_atts);
Elliott Hughes35e432d2012-09-09 14:23:38 -0700933#ifdef XML_ATTR_INFO
Elliott Hughes72472942018-01-10 08:36:10 -0800934 FREE(parser, parser->m_attInfo);
Elliott Hughes35e432d2012-09-09 14:23:38 -0700935#endif
Elliott Hughes72472942018-01-10 08:36:10 -0800936 FREE(parser, parser);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800937 return NULL;
938 }
Elliott Hughes72472942018-01-10 08:36:10 -0800939 parser->m_dataBufEnd = parser->m_dataBuf + INIT_DATA_BUF_SIZE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800940
941 if (dtd)
Elliott Hughes72472942018-01-10 08:36:10 -0800942 parser->m_dtd = dtd;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800943 else {
Elliott Hughes72472942018-01-10 08:36:10 -0800944 parser->m_dtd = dtdCreate(&parser->m_mem);
945 if (parser->m_dtd == NULL) {
946 FREE(parser, parser->m_dataBuf);
947 FREE(parser, parser->m_atts);
Elliott Hughes35e432d2012-09-09 14:23:38 -0700948#ifdef XML_ATTR_INFO
Elliott Hughes72472942018-01-10 08:36:10 -0800949 FREE(parser, parser->m_attInfo);
Elliott Hughes35e432d2012-09-09 14:23:38 -0700950#endif
Elliott Hughes72472942018-01-10 08:36:10 -0800951 FREE(parser, parser);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800952 return NULL;
953 }
954 }
955
Elliott Hughes72472942018-01-10 08:36:10 -0800956 parser->m_freeBindingList = NULL;
957 parser->m_freeTagList = NULL;
958 parser->m_freeInternalEntities = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800959
Elliott Hughes72472942018-01-10 08:36:10 -0800960 parser->m_groupSize = 0;
961 parser->m_groupConnector = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800962
Elliott Hughes72472942018-01-10 08:36:10 -0800963 parser->m_unknownEncodingHandler = NULL;
964 parser->m_unknownEncodingHandlerData = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800965
Elliott Hughes72472942018-01-10 08:36:10 -0800966 parser->m_namespaceSeparator = ASCII_EXCL;
967 parser->m_ns = XML_FALSE;
968 parser->m_ns_triplets = XML_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800969
Elliott Hughes72472942018-01-10 08:36:10 -0800970 parser->m_nsAtts = NULL;
971 parser->m_nsAttsVersion = 0;
972 parser->m_nsAttsPower = 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800973
Elliott Hughes72472942018-01-10 08:36:10 -0800974 parser->m_protocolEncodingName = NULL;
975
976 poolInit(&parser->m_tempPool, &(parser->m_mem));
977 poolInit(&parser->m_temp2Pool, &(parser->m_mem));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800978 parserInit(parser, encodingName);
979
Haibo Huang40a71912019-10-11 11:13:39 -0700980 if (encodingName && ! parser->m_protocolEncodingName) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800981 XML_ParserFree(parser);
982 return NULL;
983 }
984
985 if (nameSep) {
Elliott Hughes72472942018-01-10 08:36:10 -0800986 parser->m_ns = XML_TRUE;
987 parser->m_internalEncoding = XmlGetInternalEncodingNS();
988 parser->m_namespaceSeparator = *nameSep;
Haibo Huang40a71912019-10-11 11:13:39 -0700989 } else {
Elliott Hughes72472942018-01-10 08:36:10 -0800990 parser->m_internalEncoding = XmlGetInternalEncoding();
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800991 }
992
993 return parser;
994}
995
996static void
Haibo Huang40a71912019-10-11 11:13:39 -0700997parserInit(XML_Parser parser, const XML_Char *encodingName) {
Elliott Hughes72472942018-01-10 08:36:10 -0800998 parser->m_processor = prologInitProcessor;
999 XmlPrologStateInit(&parser->m_prologState);
1000 if (encodingName != NULL) {
1001 parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem));
1002 }
1003 parser->m_curBase = NULL;
1004 XmlInitEncoding(&parser->m_initEncoding, &parser->m_encoding, 0);
1005 parser->m_userData = NULL;
1006 parser->m_handlerArg = NULL;
1007 parser->m_startElementHandler = NULL;
1008 parser->m_endElementHandler = NULL;
1009 parser->m_characterDataHandler = NULL;
1010 parser->m_processingInstructionHandler = NULL;
1011 parser->m_commentHandler = NULL;
1012 parser->m_startCdataSectionHandler = NULL;
1013 parser->m_endCdataSectionHandler = NULL;
1014 parser->m_defaultHandler = NULL;
1015 parser->m_startDoctypeDeclHandler = NULL;
1016 parser->m_endDoctypeDeclHandler = NULL;
1017 parser->m_unparsedEntityDeclHandler = NULL;
1018 parser->m_notationDeclHandler = NULL;
1019 parser->m_startNamespaceDeclHandler = NULL;
1020 parser->m_endNamespaceDeclHandler = NULL;
1021 parser->m_notStandaloneHandler = NULL;
1022 parser->m_externalEntityRefHandler = NULL;
1023 parser->m_externalEntityRefHandlerArg = parser;
1024 parser->m_skippedEntityHandler = NULL;
1025 parser->m_elementDeclHandler = NULL;
1026 parser->m_attlistDeclHandler = NULL;
1027 parser->m_entityDeclHandler = NULL;
1028 parser->m_xmlDeclHandler = NULL;
1029 parser->m_bufferPtr = parser->m_buffer;
1030 parser->m_bufferEnd = parser->m_buffer;
1031 parser->m_parseEndByteIndex = 0;
1032 parser->m_parseEndPtr = NULL;
1033 parser->m_declElementType = NULL;
1034 parser->m_declAttributeId = NULL;
1035 parser->m_declEntity = NULL;
1036 parser->m_doctypeName = NULL;
1037 parser->m_doctypeSysid = NULL;
1038 parser->m_doctypePubid = NULL;
1039 parser->m_declAttributeType = NULL;
1040 parser->m_declNotationName = NULL;
1041 parser->m_declNotationPublicId = NULL;
1042 parser->m_declAttributeIsCdata = XML_FALSE;
1043 parser->m_declAttributeIsId = XML_FALSE;
1044 memset(&parser->m_position, 0, sizeof(POSITION));
1045 parser->m_errorCode = XML_ERROR_NONE;
1046 parser->m_eventPtr = NULL;
1047 parser->m_eventEndPtr = NULL;
1048 parser->m_positionPtr = NULL;
1049 parser->m_openInternalEntities = NULL;
1050 parser->m_defaultExpandInternalEntities = XML_TRUE;
1051 parser->m_tagLevel = 0;
1052 parser->m_tagStack = NULL;
1053 parser->m_inheritedBindings = NULL;
1054 parser->m_nSpecifiedAtts = 0;
1055 parser->m_unknownEncodingMem = NULL;
1056 parser->m_unknownEncodingRelease = NULL;
1057 parser->m_unknownEncodingData = NULL;
1058 parser->m_parentParser = NULL;
1059 parser->m_parsingStatus.parsing = XML_INITIALIZED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001060#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08001061 parser->m_isParamEntity = XML_FALSE;
1062 parser->m_useForeignDTD = XML_FALSE;
1063 parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001064#endif
Elliott Hughes72472942018-01-10 08:36:10 -08001065 parser->m_hash_secret_salt = 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001066}
1067
Elliott Hughes72472942018-01-10 08:36:10 -08001068/* moves list of bindings to m_freeBindingList */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001069static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001070moveToFreeBindingList(XML_Parser parser, BINDING *bindings) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001071 while (bindings) {
1072 BINDING *b = bindings;
1073 bindings = bindings->nextTagBinding;
Elliott Hughes72472942018-01-10 08:36:10 -08001074 b->nextTagBinding = parser->m_freeBindingList;
1075 parser->m_freeBindingList = b;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001076 }
1077}
1078
1079XML_Bool XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001080XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001081 TAG *tStk;
1082 OPEN_INTERNAL_ENTITY *openEntityList;
Elliott Hughes72472942018-01-10 08:36:10 -08001083
1084 if (parser == NULL)
Haibo Huang40a71912019-10-11 11:13:39 -07001085 return XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08001086
1087 if (parser->m_parentParser)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001088 return XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08001089 /* move m_tagStack to m_freeTagList */
1090 tStk = parser->m_tagStack;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001091 while (tStk) {
1092 TAG *tag = tStk;
1093 tStk = tStk->parent;
Elliott Hughes72472942018-01-10 08:36:10 -08001094 tag->parent = parser->m_freeTagList;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001095 moveToFreeBindingList(parser, tag->bindings);
1096 tag->bindings = NULL;
Elliott Hughes72472942018-01-10 08:36:10 -08001097 parser->m_freeTagList = tag;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001098 }
Elliott Hughes72472942018-01-10 08:36:10 -08001099 /* move m_openInternalEntities to m_freeInternalEntities */
1100 openEntityList = parser->m_openInternalEntities;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001101 while (openEntityList) {
1102 OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
1103 openEntityList = openEntity->next;
Elliott Hughes72472942018-01-10 08:36:10 -08001104 openEntity->next = parser->m_freeInternalEntities;
1105 parser->m_freeInternalEntities = openEntity;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001106 }
Elliott Hughes72472942018-01-10 08:36:10 -08001107 moveToFreeBindingList(parser, parser->m_inheritedBindings);
1108 FREE(parser, parser->m_unknownEncodingMem);
1109 if (parser->m_unknownEncodingRelease)
1110 parser->m_unknownEncodingRelease(parser->m_unknownEncodingData);
1111 poolClear(&parser->m_tempPool);
1112 poolClear(&parser->m_temp2Pool);
1113 FREE(parser, (void *)parser->m_protocolEncodingName);
1114 parser->m_protocolEncodingName = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001115 parserInit(parser, encodingName);
Elliott Hughes72472942018-01-10 08:36:10 -08001116 dtdReset(parser->m_dtd, &parser->m_mem);
Elliott Hughes35e432d2012-09-09 14:23:38 -07001117 return XML_TRUE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001118}
1119
1120enum XML_Status XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001121XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) {
Elliott Hughes72472942018-01-10 08:36:10 -08001122 if (parser == NULL)
Haibo Huang40a71912019-10-11 11:13:39 -07001123 return XML_STATUS_ERROR;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001124 /* Block after XML_Parse()/XML_ParseBuffer() has been called.
1125 XXX There's no way for the caller to determine which of the
1126 XXX possible error cases caused the XML_STATUS_ERROR return.
1127 */
Haibo Huang40a71912019-10-11 11:13:39 -07001128 if (parser->m_parsingStatus.parsing == XML_PARSING
1129 || parser->m_parsingStatus.parsing == XML_SUSPENDED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001130 return XML_STATUS_ERROR;
Elliott Hughes72472942018-01-10 08:36:10 -08001131
1132 /* Get rid of any previous encoding name */
1133 FREE(parser, (void *)parser->m_protocolEncodingName);
1134
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001135 if (encodingName == NULL)
Elliott Hughes72472942018-01-10 08:36:10 -08001136 /* No new encoding name */
1137 parser->m_protocolEncodingName = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001138 else {
Elliott Hughes72472942018-01-10 08:36:10 -08001139 /* Copy the new encoding name into allocated memory */
1140 parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem));
Haibo Huang40a71912019-10-11 11:13:39 -07001141 if (! parser->m_protocolEncodingName)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001142 return XML_STATUS_ERROR;
1143 }
1144 return XML_STATUS_OK;
1145}
1146
1147XML_Parser XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001148XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context,
1149 const XML_Char *encodingName) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001150 XML_Parser parser = oldParser;
1151 DTD *newDtd = NULL;
Elliott Hughes72472942018-01-10 08:36:10 -08001152 DTD *oldDtd;
1153 XML_StartElementHandler oldStartElementHandler;
1154 XML_EndElementHandler oldEndElementHandler;
1155 XML_CharacterDataHandler oldCharacterDataHandler;
1156 XML_ProcessingInstructionHandler oldProcessingInstructionHandler;
1157 XML_CommentHandler oldCommentHandler;
1158 XML_StartCdataSectionHandler oldStartCdataSectionHandler;
1159 XML_EndCdataSectionHandler oldEndCdataSectionHandler;
1160 XML_DefaultHandler oldDefaultHandler;
1161 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler;
1162 XML_NotationDeclHandler oldNotationDeclHandler;
1163 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler;
1164 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler;
1165 XML_NotStandaloneHandler oldNotStandaloneHandler;
1166 XML_ExternalEntityRefHandler oldExternalEntityRefHandler;
1167 XML_SkippedEntityHandler oldSkippedEntityHandler;
1168 XML_UnknownEncodingHandler oldUnknownEncodingHandler;
1169 XML_ElementDeclHandler oldElementDeclHandler;
1170 XML_AttlistDeclHandler oldAttlistDeclHandler;
1171 XML_EntityDeclHandler oldEntityDeclHandler;
1172 XML_XmlDeclHandler oldXmlDeclHandler;
Haibo Huang40a71912019-10-11 11:13:39 -07001173 ELEMENT_TYPE *oldDeclElementType;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001174
Elliott Hughes72472942018-01-10 08:36:10 -08001175 void *oldUserData;
1176 void *oldHandlerArg;
1177 XML_Bool oldDefaultExpandInternalEntities;
1178 XML_Parser oldExternalEntityRefHandlerArg;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001179#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08001180 enum XML_ParamEntityParsing oldParamEntityParsing;
1181 int oldInEntityValue;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001182#endif
Elliott Hughes72472942018-01-10 08:36:10 -08001183 XML_Bool oldns_triplets;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001184 /* Note that the new parser shares the same hash secret as the old
1185 parser, so that dtdCopy and copyEntityTable can lookup values
1186 from hash tables associated with either parser without us having
1187 to worry which hash secrets each table has.
1188 */
Elliott Hughes72472942018-01-10 08:36:10 -08001189 unsigned long oldhash_secret_salt;
1190
1191 /* Validate the oldParser parameter before we pull everything out of it */
1192 if (oldParser == NULL)
1193 return NULL;
1194
1195 /* Stash the original parser contents on the stack */
1196 oldDtd = parser->m_dtd;
1197 oldStartElementHandler = parser->m_startElementHandler;
1198 oldEndElementHandler = parser->m_endElementHandler;
1199 oldCharacterDataHandler = parser->m_characterDataHandler;
1200 oldProcessingInstructionHandler = parser->m_processingInstructionHandler;
1201 oldCommentHandler = parser->m_commentHandler;
1202 oldStartCdataSectionHandler = parser->m_startCdataSectionHandler;
1203 oldEndCdataSectionHandler = parser->m_endCdataSectionHandler;
1204 oldDefaultHandler = parser->m_defaultHandler;
1205 oldUnparsedEntityDeclHandler = parser->m_unparsedEntityDeclHandler;
1206 oldNotationDeclHandler = parser->m_notationDeclHandler;
1207 oldStartNamespaceDeclHandler = parser->m_startNamespaceDeclHandler;
1208 oldEndNamespaceDeclHandler = parser->m_endNamespaceDeclHandler;
1209 oldNotStandaloneHandler = parser->m_notStandaloneHandler;
1210 oldExternalEntityRefHandler = parser->m_externalEntityRefHandler;
1211 oldSkippedEntityHandler = parser->m_skippedEntityHandler;
1212 oldUnknownEncodingHandler = parser->m_unknownEncodingHandler;
1213 oldElementDeclHandler = parser->m_elementDeclHandler;
1214 oldAttlistDeclHandler = parser->m_attlistDeclHandler;
1215 oldEntityDeclHandler = parser->m_entityDeclHandler;
1216 oldXmlDeclHandler = parser->m_xmlDeclHandler;
1217 oldDeclElementType = parser->m_declElementType;
1218
1219 oldUserData = parser->m_userData;
1220 oldHandlerArg = parser->m_handlerArg;
1221 oldDefaultExpandInternalEntities = parser->m_defaultExpandInternalEntities;
1222 oldExternalEntityRefHandlerArg = parser->m_externalEntityRefHandlerArg;
1223#ifdef XML_DTD
1224 oldParamEntityParsing = parser->m_paramEntityParsing;
1225 oldInEntityValue = parser->m_prologState.inEntityValue;
1226#endif
1227 oldns_triplets = parser->m_ns_triplets;
1228 /* Note that the new parser shares the same hash secret as the old
1229 parser, so that dtdCopy and copyEntityTable can lookup values
1230 from hash tables associated with either parser without us having
1231 to worry which hash secrets each table has.
1232 */
1233 oldhash_secret_salt = parser->m_hash_secret_salt;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001234
1235#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07001236 if (! context)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001237 newDtd = oldDtd;
1238#endif /* XML_DTD */
1239
1240 /* Note that the magical uses of the pre-processor to make field
1241 access look more like C++ require that `parser' be overwritten
1242 here. This makes this function more painful to follow than it
1243 would be otherwise.
1244 */
Elliott Hughes72472942018-01-10 08:36:10 -08001245 if (parser->m_ns) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001246 XML_Char tmp[2];
Elliott Hughes72472942018-01-10 08:36:10 -08001247 *tmp = parser->m_namespaceSeparator;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001248 parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
Haibo Huang40a71912019-10-11 11:13:39 -07001249 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001250 parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
1251 }
1252
Haibo Huang40a71912019-10-11 11:13:39 -07001253 if (! parser)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001254 return NULL;
1255
Elliott Hughes72472942018-01-10 08:36:10 -08001256 parser->m_startElementHandler = oldStartElementHandler;
1257 parser->m_endElementHandler = oldEndElementHandler;
1258 parser->m_characterDataHandler = oldCharacterDataHandler;
1259 parser->m_processingInstructionHandler = oldProcessingInstructionHandler;
1260 parser->m_commentHandler = oldCommentHandler;
1261 parser->m_startCdataSectionHandler = oldStartCdataSectionHandler;
1262 parser->m_endCdataSectionHandler = oldEndCdataSectionHandler;
1263 parser->m_defaultHandler = oldDefaultHandler;
1264 parser->m_unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
1265 parser->m_notationDeclHandler = oldNotationDeclHandler;
1266 parser->m_startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
1267 parser->m_endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
1268 parser->m_notStandaloneHandler = oldNotStandaloneHandler;
1269 parser->m_externalEntityRefHandler = oldExternalEntityRefHandler;
1270 parser->m_skippedEntityHandler = oldSkippedEntityHandler;
1271 parser->m_unknownEncodingHandler = oldUnknownEncodingHandler;
1272 parser->m_elementDeclHandler = oldElementDeclHandler;
1273 parser->m_attlistDeclHandler = oldAttlistDeclHandler;
1274 parser->m_entityDeclHandler = oldEntityDeclHandler;
1275 parser->m_xmlDeclHandler = oldXmlDeclHandler;
1276 parser->m_declElementType = oldDeclElementType;
1277 parser->m_userData = oldUserData;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001278 if (oldUserData == oldHandlerArg)
Elliott Hughes72472942018-01-10 08:36:10 -08001279 parser->m_handlerArg = parser->m_userData;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001280 else
Elliott Hughes72472942018-01-10 08:36:10 -08001281 parser->m_handlerArg = parser;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001282 if (oldExternalEntityRefHandlerArg != oldParser)
Elliott Hughes72472942018-01-10 08:36:10 -08001283 parser->m_externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
1284 parser->m_defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
1285 parser->m_ns_triplets = oldns_triplets;
1286 parser->m_hash_secret_salt = oldhash_secret_salt;
1287 parser->m_parentParser = oldParser;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001288#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08001289 parser->m_paramEntityParsing = oldParamEntityParsing;
1290 parser->m_prologState.inEntityValue = oldInEntityValue;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001291 if (context) {
1292#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07001293 if (! dtdCopy(oldParser, parser->m_dtd, oldDtd, &parser->m_mem)
1294 || ! setContext(parser, context)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001295 XML_ParserFree(parser);
1296 return NULL;
1297 }
Elliott Hughes72472942018-01-10 08:36:10 -08001298 parser->m_processor = externalEntityInitProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001299#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07001300 } else {
1301 /* The DTD instance referenced by parser->m_dtd is shared between the
1302 document's root parser and external PE parsers, therefore one does not
1303 need to call setContext. In addition, one also *must* not call
1304 setContext, because this would overwrite existing prefix->binding
1305 pointers in parser->m_dtd with ones that get destroyed with the external
1306 PE parser. This would leave those prefixes with dangling pointers.
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001307 */
Elliott Hughes72472942018-01-10 08:36:10 -08001308 parser->m_isParamEntity = XML_TRUE;
1309 XmlPrologStateInitExternalEntity(&parser->m_prologState);
1310 parser->m_processor = externalParEntInitProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001311 }
1312#endif /* XML_DTD */
1313 return parser;
1314}
1315
1316static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001317destroyBindings(BINDING *bindings, XML_Parser parser) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001318 for (;;) {
1319 BINDING *b = bindings;
Haibo Huang40a71912019-10-11 11:13:39 -07001320 if (! b)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001321 break;
1322 bindings = b->nextTagBinding;
Elliott Hughes72472942018-01-10 08:36:10 -08001323 FREE(parser, b->uri);
1324 FREE(parser, b);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001325 }
1326}
1327
1328void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001329XML_ParserFree(XML_Parser parser) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001330 TAG *tagList;
1331 OPEN_INTERNAL_ENTITY *entityList;
1332 if (parser == NULL)
1333 return;
Elliott Hughes72472942018-01-10 08:36:10 -08001334 /* free m_tagStack and m_freeTagList */
1335 tagList = parser->m_tagStack;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001336 for (;;) {
1337 TAG *p;
1338 if (tagList == NULL) {
Elliott Hughes72472942018-01-10 08:36:10 -08001339 if (parser->m_freeTagList == NULL)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001340 break;
Elliott Hughes72472942018-01-10 08:36:10 -08001341 tagList = parser->m_freeTagList;
1342 parser->m_freeTagList = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001343 }
1344 p = tagList;
1345 tagList = tagList->parent;
Elliott Hughes72472942018-01-10 08:36:10 -08001346 FREE(parser, p->buf);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001347 destroyBindings(p->bindings, parser);
Elliott Hughes72472942018-01-10 08:36:10 -08001348 FREE(parser, p);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001349 }
Elliott Hughes72472942018-01-10 08:36:10 -08001350 /* free m_openInternalEntities and m_freeInternalEntities */
1351 entityList = parser->m_openInternalEntities;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001352 for (;;) {
1353 OPEN_INTERNAL_ENTITY *openEntity;
1354 if (entityList == NULL) {
Elliott Hughes72472942018-01-10 08:36:10 -08001355 if (parser->m_freeInternalEntities == NULL)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001356 break;
Elliott Hughes72472942018-01-10 08:36:10 -08001357 entityList = parser->m_freeInternalEntities;
1358 parser->m_freeInternalEntities = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001359 }
1360 openEntity = entityList;
1361 entityList = entityList->next;
Elliott Hughes72472942018-01-10 08:36:10 -08001362 FREE(parser, openEntity);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001363 }
1364
Elliott Hughes72472942018-01-10 08:36:10 -08001365 destroyBindings(parser->m_freeBindingList, parser);
1366 destroyBindings(parser->m_inheritedBindings, parser);
1367 poolDestroy(&parser->m_tempPool);
1368 poolDestroy(&parser->m_temp2Pool);
1369 FREE(parser, (void *)parser->m_protocolEncodingName);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001370#ifdef XML_DTD
1371 /* external parameter entity parsers share the DTD structure
1372 parser->m_dtd with the root parser, so we must not destroy it
1373 */
Haibo Huang40a71912019-10-11 11:13:39 -07001374 if (! parser->m_isParamEntity && parser->m_dtd)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001375#else
Elliott Hughes72472942018-01-10 08:36:10 -08001376 if (parser->m_dtd)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001377#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07001378 dtdDestroy(parser->m_dtd, (XML_Bool)! parser->m_parentParser,
1379 &parser->m_mem);
Elliott Hughes72472942018-01-10 08:36:10 -08001380 FREE(parser, (void *)parser->m_atts);
Elliott Hughes35e432d2012-09-09 14:23:38 -07001381#ifdef XML_ATTR_INFO
Elliott Hughes72472942018-01-10 08:36:10 -08001382 FREE(parser, (void *)parser->m_attInfo);
Elliott Hughes35e432d2012-09-09 14:23:38 -07001383#endif
Elliott Hughes72472942018-01-10 08:36:10 -08001384 FREE(parser, parser->m_groupConnector);
1385 FREE(parser, parser->m_buffer);
1386 FREE(parser, parser->m_dataBuf);
1387 FREE(parser, parser->m_nsAtts);
1388 FREE(parser, parser->m_unknownEncodingMem);
1389 if (parser->m_unknownEncodingRelease)
1390 parser->m_unknownEncodingRelease(parser->m_unknownEncodingData);
1391 FREE(parser, parser);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001392}
1393
1394void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001395XML_UseParserAsHandlerArg(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08001396 if (parser != NULL)
1397 parser->m_handlerArg = parser;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001398}
1399
1400enum XML_Error XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001401XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) {
Elliott Hughes72472942018-01-10 08:36:10 -08001402 if (parser == NULL)
1403 return XML_ERROR_INVALID_ARGUMENT;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001404#ifdef XML_DTD
1405 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Haibo Huang40a71912019-10-11 11:13:39 -07001406 if (parser->m_parsingStatus.parsing == XML_PARSING
1407 || parser->m_parsingStatus.parsing == XML_SUSPENDED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001408 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
Elliott Hughes72472942018-01-10 08:36:10 -08001409 parser->m_useForeignDTD = useDTD;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001410 return XML_ERROR_NONE;
1411#else
Haibo Huangd1a324a2020-10-28 22:19:36 -07001412 UNUSED_P(useDTD);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001413 return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
1414#endif
1415}
1416
1417void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001418XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) {
Elliott Hughes72472942018-01-10 08:36:10 -08001419 if (parser == NULL)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001420 return;
Elliott Hughes72472942018-01-10 08:36:10 -08001421 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Haibo Huang40a71912019-10-11 11:13:39 -07001422 if (parser->m_parsingStatus.parsing == XML_PARSING
1423 || parser->m_parsingStatus.parsing == XML_SUSPENDED)
Elliott Hughes72472942018-01-10 08:36:10 -08001424 return;
1425 parser->m_ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001426}
1427
1428void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001429XML_SetUserData(XML_Parser parser, void *p) {
Elliott Hughes72472942018-01-10 08:36:10 -08001430 if (parser == NULL)
1431 return;
1432 if (parser->m_handlerArg == parser->m_userData)
1433 parser->m_handlerArg = parser->m_userData = p;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001434 else
Elliott Hughes72472942018-01-10 08:36:10 -08001435 parser->m_userData = p;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001436}
1437
1438enum XML_Status XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001439XML_SetBase(XML_Parser parser, const XML_Char *p) {
Elliott Hughes72472942018-01-10 08:36:10 -08001440 if (parser == NULL)
1441 return XML_STATUS_ERROR;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001442 if (p) {
Elliott Hughes72472942018-01-10 08:36:10 -08001443 p = poolCopyString(&parser->m_dtd->pool, p);
Haibo Huang40a71912019-10-11 11:13:39 -07001444 if (! p)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001445 return XML_STATUS_ERROR;
Elliott Hughes72472942018-01-10 08:36:10 -08001446 parser->m_curBase = p;
Haibo Huang40a71912019-10-11 11:13:39 -07001447 } else
Elliott Hughes72472942018-01-10 08:36:10 -08001448 parser->m_curBase = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001449 return XML_STATUS_OK;
1450}
1451
Haibo Huang40a71912019-10-11 11:13:39 -07001452const XML_Char *XMLCALL
1453XML_GetBase(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08001454 if (parser == NULL)
1455 return NULL;
1456 return parser->m_curBase;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001457}
1458
1459int XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001460XML_GetSpecifiedAttributeCount(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08001461 if (parser == NULL)
1462 return -1;
1463 return parser->m_nSpecifiedAtts;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001464}
1465
1466int XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001467XML_GetIdAttributeIndex(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08001468 if (parser == NULL)
1469 return -1;
1470 return parser->m_idAttIndex;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001471}
1472
Elliott Hughes35e432d2012-09-09 14:23:38 -07001473#ifdef XML_ATTR_INFO
Haibo Huang40a71912019-10-11 11:13:39 -07001474const XML_AttrInfo *XMLCALL
1475XML_GetAttributeInfo(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08001476 if (parser == NULL)
1477 return NULL;
1478 return parser->m_attInfo;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001479}
1480#endif
1481
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001482void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001483XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start,
1484 XML_EndElementHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001485 if (parser == NULL)
1486 return;
1487 parser->m_startElementHandler = start;
1488 parser->m_endElementHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001489}
1490
1491void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001492XML_SetStartElementHandler(XML_Parser parser, XML_StartElementHandler start) {
Elliott Hughes72472942018-01-10 08:36:10 -08001493 if (parser != NULL)
1494 parser->m_startElementHandler = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001495}
1496
1497void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001498XML_SetEndElementHandler(XML_Parser parser, XML_EndElementHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001499 if (parser != NULL)
1500 parser->m_endElementHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001501}
1502
1503void XMLCALL
1504XML_SetCharacterDataHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001505 XML_CharacterDataHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001506 if (parser != NULL)
1507 parser->m_characterDataHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001508}
1509
1510void XMLCALL
1511XML_SetProcessingInstructionHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001512 XML_ProcessingInstructionHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001513 if (parser != NULL)
1514 parser->m_processingInstructionHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001515}
1516
1517void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001518XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001519 if (parser != NULL)
1520 parser->m_commentHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001521}
1522
1523void XMLCALL
1524XML_SetCdataSectionHandler(XML_Parser parser,
1525 XML_StartCdataSectionHandler start,
Haibo Huang40a71912019-10-11 11:13:39 -07001526 XML_EndCdataSectionHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001527 if (parser == NULL)
1528 return;
1529 parser->m_startCdataSectionHandler = start;
1530 parser->m_endCdataSectionHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001531}
1532
1533void XMLCALL
1534XML_SetStartCdataSectionHandler(XML_Parser parser,
1535 XML_StartCdataSectionHandler start) {
Elliott Hughes72472942018-01-10 08:36:10 -08001536 if (parser != NULL)
1537 parser->m_startCdataSectionHandler = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001538}
1539
1540void XMLCALL
1541XML_SetEndCdataSectionHandler(XML_Parser parser,
1542 XML_EndCdataSectionHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001543 if (parser != NULL)
1544 parser->m_endCdataSectionHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001545}
1546
1547void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001548XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001549 if (parser == NULL)
1550 return;
1551 parser->m_defaultHandler = handler;
1552 parser->m_defaultExpandInternalEntities = XML_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001553}
1554
1555void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001556XML_SetDefaultHandlerExpand(XML_Parser parser, XML_DefaultHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001557 if (parser == NULL)
1558 return;
1559 parser->m_defaultHandler = handler;
1560 parser->m_defaultExpandInternalEntities = XML_TRUE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001561}
1562
1563void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001564XML_SetDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start,
1565 XML_EndDoctypeDeclHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001566 if (parser == NULL)
1567 return;
1568 parser->m_startDoctypeDeclHandler = start;
1569 parser->m_endDoctypeDeclHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001570}
1571
1572void XMLCALL
1573XML_SetStartDoctypeDeclHandler(XML_Parser parser,
1574 XML_StartDoctypeDeclHandler start) {
Elliott Hughes72472942018-01-10 08:36:10 -08001575 if (parser != NULL)
1576 parser->m_startDoctypeDeclHandler = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001577}
1578
1579void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001580XML_SetEndDoctypeDeclHandler(XML_Parser parser, XML_EndDoctypeDeclHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001581 if (parser != NULL)
1582 parser->m_endDoctypeDeclHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001583}
1584
1585void XMLCALL
1586XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001587 XML_UnparsedEntityDeclHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001588 if (parser != NULL)
1589 parser->m_unparsedEntityDeclHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001590}
1591
1592void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001593XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001594 if (parser != NULL)
1595 parser->m_notationDeclHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001596}
1597
1598void XMLCALL
1599XML_SetNamespaceDeclHandler(XML_Parser parser,
1600 XML_StartNamespaceDeclHandler start,
Haibo Huang40a71912019-10-11 11:13:39 -07001601 XML_EndNamespaceDeclHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001602 if (parser == NULL)
1603 return;
1604 parser->m_startNamespaceDeclHandler = start;
1605 parser->m_endNamespaceDeclHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001606}
1607
1608void XMLCALL
1609XML_SetStartNamespaceDeclHandler(XML_Parser parser,
1610 XML_StartNamespaceDeclHandler start) {
Elliott Hughes72472942018-01-10 08:36:10 -08001611 if (parser != NULL)
1612 parser->m_startNamespaceDeclHandler = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001613}
1614
1615void XMLCALL
1616XML_SetEndNamespaceDeclHandler(XML_Parser parser,
1617 XML_EndNamespaceDeclHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001618 if (parser != NULL)
1619 parser->m_endNamespaceDeclHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001620}
1621
1622void XMLCALL
1623XML_SetNotStandaloneHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001624 XML_NotStandaloneHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001625 if (parser != NULL)
1626 parser->m_notStandaloneHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001627}
1628
1629void XMLCALL
1630XML_SetExternalEntityRefHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001631 XML_ExternalEntityRefHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001632 if (parser != NULL)
1633 parser->m_externalEntityRefHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001634}
1635
1636void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001637XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) {
Elliott Hughes72472942018-01-10 08:36:10 -08001638 if (parser == NULL)
1639 return;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001640 if (arg)
Elliott Hughes72472942018-01-10 08:36:10 -08001641 parser->m_externalEntityRefHandlerArg = (XML_Parser)arg;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001642 else
Elliott Hughes72472942018-01-10 08:36:10 -08001643 parser->m_externalEntityRefHandlerArg = parser;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001644}
1645
1646void XMLCALL
1647XML_SetSkippedEntityHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001648 XML_SkippedEntityHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001649 if (parser != NULL)
1650 parser->m_skippedEntityHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001651}
1652
1653void XMLCALL
1654XML_SetUnknownEncodingHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001655 XML_UnknownEncodingHandler handler, void *data) {
Elliott Hughes72472942018-01-10 08:36:10 -08001656 if (parser == NULL)
1657 return;
1658 parser->m_unknownEncodingHandler = handler;
1659 parser->m_unknownEncodingHandlerData = data;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001660}
1661
1662void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001663XML_SetElementDeclHandler(XML_Parser parser, XML_ElementDeclHandler eldecl) {
Elliott Hughes72472942018-01-10 08:36:10 -08001664 if (parser != NULL)
1665 parser->m_elementDeclHandler = eldecl;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001666}
1667
1668void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001669XML_SetAttlistDeclHandler(XML_Parser parser, XML_AttlistDeclHandler attdecl) {
Elliott Hughes72472942018-01-10 08:36:10 -08001670 if (parser != NULL)
1671 parser->m_attlistDeclHandler = attdecl;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001672}
1673
1674void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001675XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001676 if (parser != NULL)
1677 parser->m_entityDeclHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001678}
1679
1680void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001681XML_SetXmlDeclHandler(XML_Parser parser, XML_XmlDeclHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001682 if (parser != NULL)
1683 parser->m_xmlDeclHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001684}
1685
1686int XMLCALL
1687XML_SetParamEntityParsing(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001688 enum XML_ParamEntityParsing peParsing) {
Elliott Hughes72472942018-01-10 08:36:10 -08001689 if (parser == NULL)
1690 return 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001691 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Haibo Huang40a71912019-10-11 11:13:39 -07001692 if (parser->m_parsingStatus.parsing == XML_PARSING
1693 || parser->m_parsingStatus.parsing == XML_SUSPENDED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001694 return 0;
1695#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08001696 parser->m_paramEntityParsing = peParsing;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001697 return 1;
1698#else
1699 return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
1700#endif
1701}
1702
Elliott Hughes35e432d2012-09-09 14:23:38 -07001703int XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001704XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt) {
Elliott Hughes72472942018-01-10 08:36:10 -08001705 if (parser == NULL)
Elliott Hughes35e432d2012-09-09 14:23:38 -07001706 return 0;
Elliott Hughes72472942018-01-10 08:36:10 -08001707 if (parser->m_parentParser)
1708 return XML_SetHashSalt(parser->m_parentParser, hash_salt);
1709 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Haibo Huang40a71912019-10-11 11:13:39 -07001710 if (parser->m_parsingStatus.parsing == XML_PARSING
1711 || parser->m_parsingStatus.parsing == XML_SUSPENDED)
Elliott Hughes72472942018-01-10 08:36:10 -08001712 return 0;
1713 parser->m_hash_secret_salt = hash_salt;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001714 return 1;
1715}
1716
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001717enum XML_Status XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001718XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) {
Elliott Hughes72472942018-01-10 08:36:10 -08001719 if ((parser == NULL) || (len < 0) || ((s == NULL) && (len != 0))) {
1720 if (parser != NULL)
1721 parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT;
1722 return XML_STATUS_ERROR;
1723 }
1724 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001725 case XML_SUSPENDED:
Elliott Hughes72472942018-01-10 08:36:10 -08001726 parser->m_errorCode = XML_ERROR_SUSPENDED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001727 return XML_STATUS_ERROR;
1728 case XML_FINISHED:
Elliott Hughes72472942018-01-10 08:36:10 -08001729 parser->m_errorCode = XML_ERROR_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001730 return XML_STATUS_ERROR;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001731 case XML_INITIALIZED:
Haibo Huang40a71912019-10-11 11:13:39 -07001732 if (parser->m_parentParser == NULL && ! startParsing(parser)) {
Elliott Hughes72472942018-01-10 08:36:10 -08001733 parser->m_errorCode = XML_ERROR_NO_MEMORY;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001734 return XML_STATUS_ERROR;
1735 }
Elliott Hughesaaec48e2018-08-16 16:29:01 -07001736 /* fall through */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001737 default:
Elliott Hughes72472942018-01-10 08:36:10 -08001738 parser->m_parsingStatus.parsing = XML_PARSING;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001739 }
1740
1741 if (len == 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08001742 parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
Haibo Huang40a71912019-10-11 11:13:39 -07001743 if (! isFinal)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001744 return XML_STATUS_OK;
Elliott Hughes72472942018-01-10 08:36:10 -08001745 parser->m_positionPtr = parser->m_bufferPtr;
1746 parser->m_parseEndPtr = parser->m_bufferEnd;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001747
1748 /* If data are left over from last buffer, and we now know that these
1749 data are the final chunk of input, then we have to check them again
1750 to detect errors based on that fact.
1751 */
Haibo Huang40a71912019-10-11 11:13:39 -07001752 parser->m_errorCode
1753 = parser->m_processor(parser, parser->m_bufferPtr,
1754 parser->m_parseEndPtr, &parser->m_bufferPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001755
Elliott Hughes72472942018-01-10 08:36:10 -08001756 if (parser->m_errorCode == XML_ERROR_NONE) {
1757 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001758 case XML_SUSPENDED:
Elliott Hughes72472942018-01-10 08:36:10 -08001759 /* It is hard to be certain, but it seems that this case
1760 * cannot occur. This code is cleaning up a previous parse
1761 * with no new data (since len == 0). Changing the parsing
1762 * state requires getting to execute a handler function, and
1763 * there doesn't seem to be an opportunity for that while in
1764 * this circumstance.
1765 *
1766 * Given the uncertainty, we retain the code but exclude it
1767 * from coverage tests.
1768 *
1769 * LCOV_EXCL_START
1770 */
Haibo Huang40a71912019-10-11 11:13:39 -07001771 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
1772 parser->m_bufferPtr, &parser->m_position);
Elliott Hughes72472942018-01-10 08:36:10 -08001773 parser->m_positionPtr = parser->m_bufferPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001774 return XML_STATUS_SUSPENDED;
Elliott Hughes72472942018-01-10 08:36:10 -08001775 /* LCOV_EXCL_STOP */
Elliott Hughes35e432d2012-09-09 14:23:38 -07001776 case XML_INITIALIZED:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001777 case XML_PARSING:
Elliott Hughes72472942018-01-10 08:36:10 -08001778 parser->m_parsingStatus.parsing = XML_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001779 /* fall through */
1780 default:
1781 return XML_STATUS_OK;
1782 }
1783 }
Elliott Hughes72472942018-01-10 08:36:10 -08001784 parser->m_eventEndPtr = parser->m_eventPtr;
1785 parser->m_processor = errorProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001786 return XML_STATUS_ERROR;
1787 }
1788#ifndef XML_CONTEXT_BYTES
Elliott Hughes72472942018-01-10 08:36:10 -08001789 else if (parser->m_bufferPtr == parser->m_bufferEnd) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001790 const char *end;
1791 int nLeftOver;
Paul Duffinc05e0322016-05-04 10:42:31 +01001792 enum XML_Status result;
Elliott Hughes72472942018-01-10 08:36:10 -08001793 /* Detect overflow (a+b > MAX <==> b > MAX-a) */
Haibo Huangd1a324a2020-10-28 22:19:36 -07001794 if ((XML_Size)len > ((XML_Size)-1) / 2 - parser->m_parseEndByteIndex) {
Haibo Huang40a71912019-10-11 11:13:39 -07001795 parser->m_errorCode = XML_ERROR_NO_MEMORY;
1796 parser->m_eventPtr = parser->m_eventEndPtr = NULL;
1797 parser->m_processor = errorProcessor;
1798 return XML_STATUS_ERROR;
Elliott Hughes72472942018-01-10 08:36:10 -08001799 }
1800 parser->m_parseEndByteIndex += len;
1801 parser->m_positionPtr = s;
1802 parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001803
Haibo Huang40a71912019-10-11 11:13:39 -07001804 parser->m_errorCode
1805 = parser->m_processor(parser, s, parser->m_parseEndPtr = s + len, &end);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001806
Elliott Hughes72472942018-01-10 08:36:10 -08001807 if (parser->m_errorCode != XML_ERROR_NONE) {
1808 parser->m_eventEndPtr = parser->m_eventPtr;
1809 parser->m_processor = errorProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001810 return XML_STATUS_ERROR;
Haibo Huang40a71912019-10-11 11:13:39 -07001811 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08001812 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001813 case XML_SUSPENDED:
1814 result = XML_STATUS_SUSPENDED;
1815 break;
1816 case XML_INITIALIZED:
1817 case XML_PARSING:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001818 if (isFinal) {
Elliott Hughes72472942018-01-10 08:36:10 -08001819 parser->m_parsingStatus.parsing = XML_FINISHED;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001820 return XML_STATUS_OK;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001821 }
Elliott Hughes35e432d2012-09-09 14:23:38 -07001822 /* fall through */
1823 default:
1824 result = XML_STATUS_OK;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001825 }
1826 }
1827
Haibo Huang40a71912019-10-11 11:13:39 -07001828 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, end,
1829 &parser->m_position);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001830 nLeftOver = s + len - end;
1831 if (nLeftOver) {
Haibo Huang40a71912019-10-11 11:13:39 -07001832 if (parser->m_buffer == NULL
1833 || nLeftOver > parser->m_bufferLim - parser->m_buffer) {
Elliott Hughes72472942018-01-10 08:36:10 -08001834 /* avoid _signed_ integer overflow */
1835 char *temp = NULL;
1836 const int bytesToAllocate = (int)((unsigned)len * 2U);
1837 if (bytesToAllocate > 0) {
1838 temp = (char *)REALLOC(parser, parser->m_buffer, bytesToAllocate);
1839 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001840 if (temp == NULL) {
Elliott Hughes72472942018-01-10 08:36:10 -08001841 parser->m_errorCode = XML_ERROR_NO_MEMORY;
1842 parser->m_eventPtr = parser->m_eventEndPtr = NULL;
1843 parser->m_processor = errorProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001844 return XML_STATUS_ERROR;
1845 }
Elliott Hughes72472942018-01-10 08:36:10 -08001846 parser->m_buffer = temp;
1847 parser->m_bufferLim = parser->m_buffer + bytesToAllocate;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001848 }
Elliott Hughes72472942018-01-10 08:36:10 -08001849 memcpy(parser->m_buffer, end, nLeftOver);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001850 }
Elliott Hughes72472942018-01-10 08:36:10 -08001851 parser->m_bufferPtr = parser->m_buffer;
1852 parser->m_bufferEnd = parser->m_buffer + nLeftOver;
1853 parser->m_positionPtr = parser->m_bufferPtr;
1854 parser->m_parseEndPtr = parser->m_bufferEnd;
1855 parser->m_eventPtr = parser->m_bufferPtr;
1856 parser->m_eventEndPtr = parser->m_bufferPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001857 return result;
1858 }
Haibo Huang40a71912019-10-11 11:13:39 -07001859#endif /* not defined XML_CONTEXT_BYTES */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001860 else {
1861 void *buff = XML_GetBuffer(parser, len);
1862 if (buff == NULL)
1863 return XML_STATUS_ERROR;
1864 else {
1865 memcpy(buff, s, len);
1866 return XML_ParseBuffer(parser, len, isFinal);
1867 }
1868 }
1869}
1870
1871enum XML_Status XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001872XML_ParseBuffer(XML_Parser parser, int len, int isFinal) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001873 const char *start;
1874 enum XML_Status result = XML_STATUS_OK;
1875
Elliott Hughes72472942018-01-10 08:36:10 -08001876 if (parser == NULL)
1877 return XML_STATUS_ERROR;
1878 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001879 case XML_SUSPENDED:
Elliott Hughes72472942018-01-10 08:36:10 -08001880 parser->m_errorCode = XML_ERROR_SUSPENDED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001881 return XML_STATUS_ERROR;
1882 case XML_FINISHED:
Elliott Hughes72472942018-01-10 08:36:10 -08001883 parser->m_errorCode = XML_ERROR_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001884 return XML_STATUS_ERROR;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001885 case XML_INITIALIZED:
Elliott Hughesf648a292021-04-01 15:10:13 -07001886 /* Has someone called XML_GetBuffer successfully before? */
1887 if (! parser->m_bufferPtr) {
1888 parser->m_errorCode = XML_ERROR_NO_BUFFER;
1889 return XML_STATUS_ERROR;
1890 }
1891
Haibo Huang40a71912019-10-11 11:13:39 -07001892 if (parser->m_parentParser == NULL && ! startParsing(parser)) {
Elliott Hughes72472942018-01-10 08:36:10 -08001893 parser->m_errorCode = XML_ERROR_NO_MEMORY;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001894 return XML_STATUS_ERROR;
1895 }
Elliott Hughesaaec48e2018-08-16 16:29:01 -07001896 /* fall through */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001897 default:
Elliott Hughes72472942018-01-10 08:36:10 -08001898 parser->m_parsingStatus.parsing = XML_PARSING;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001899 }
1900
Elliott Hughes72472942018-01-10 08:36:10 -08001901 start = parser->m_bufferPtr;
1902 parser->m_positionPtr = start;
1903 parser->m_bufferEnd += len;
1904 parser->m_parseEndPtr = parser->m_bufferEnd;
1905 parser->m_parseEndByteIndex += len;
1906 parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001907
Haibo Huang40a71912019-10-11 11:13:39 -07001908 parser->m_errorCode = parser->m_processor(
1909 parser, start, parser->m_parseEndPtr, &parser->m_bufferPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001910
Elliott Hughes72472942018-01-10 08:36:10 -08001911 if (parser->m_errorCode != XML_ERROR_NONE) {
1912 parser->m_eventEndPtr = parser->m_eventPtr;
1913 parser->m_processor = errorProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001914 return XML_STATUS_ERROR;
Haibo Huang40a71912019-10-11 11:13:39 -07001915 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08001916 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001917 case XML_SUSPENDED:
1918 result = XML_STATUS_SUSPENDED;
1919 break;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001920 case XML_INITIALIZED:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001921 case XML_PARSING:
1922 if (isFinal) {
Elliott Hughes72472942018-01-10 08:36:10 -08001923 parser->m_parsingStatus.parsing = XML_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001924 return result;
1925 }
Haibo Huang40a71912019-10-11 11:13:39 -07001926 default:; /* should not happen */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001927 }
1928 }
1929
Haibo Huang40a71912019-10-11 11:13:39 -07001930 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
1931 parser->m_bufferPtr, &parser->m_position);
Elliott Hughes72472942018-01-10 08:36:10 -08001932 parser->m_positionPtr = parser->m_bufferPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001933 return result;
1934}
1935
Haibo Huang40a71912019-10-11 11:13:39 -07001936void *XMLCALL
1937XML_GetBuffer(XML_Parser parser, int len) {
Elliott Hughes72472942018-01-10 08:36:10 -08001938 if (parser == NULL)
1939 return NULL;
Paul Duffinc05e0322016-05-04 10:42:31 +01001940 if (len < 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08001941 parser->m_errorCode = XML_ERROR_NO_MEMORY;
Paul Duffinc05e0322016-05-04 10:42:31 +01001942 return NULL;
1943 }
Elliott Hughes72472942018-01-10 08:36:10 -08001944 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001945 case XML_SUSPENDED:
Elliott Hughes72472942018-01-10 08:36:10 -08001946 parser->m_errorCode = XML_ERROR_SUSPENDED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001947 return NULL;
1948 case XML_FINISHED:
Elliott Hughes72472942018-01-10 08:36:10 -08001949 parser->m_errorCode = XML_ERROR_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001950 return NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07001951 default:;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001952 }
1953
Elliott Hughesaaec48e2018-08-16 16:29:01 -07001954 if (len > EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferEnd)) {
Paul Duffinba34a0c2017-02-27 14:40:16 +00001955#ifdef XML_CONTEXT_BYTES
1956 int keep;
Haibo Huang40a71912019-10-11 11:13:39 -07001957#endif /* defined XML_CONTEXT_BYTES */
Paul Duffinba34a0c2017-02-27 14:40:16 +00001958 /* Do not invoke signed arithmetic overflow: */
Haibo Huang40a71912019-10-11 11:13:39 -07001959 int neededSize = (int)((unsigned)len
1960 + (unsigned)EXPAT_SAFE_PTR_DIFF(
1961 parser->m_bufferEnd, parser->m_bufferPtr));
Paul Duffinc05e0322016-05-04 10:42:31 +01001962 if (neededSize < 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08001963 parser->m_errorCode = XML_ERROR_NO_MEMORY;
Paul Duffinc05e0322016-05-04 10:42:31 +01001964 return NULL;
1965 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001966#ifdef XML_CONTEXT_BYTES
Elliott Hughesaaec48e2018-08-16 16:29:01 -07001967 keep = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001968 if (keep > XML_CONTEXT_BYTES)
1969 keep = XML_CONTEXT_BYTES;
Sadaf Ebrahimi1cea5722022-06-02 19:32:22 +00001970 /* Detect and prevent integer overflow */
1971 if (keep > INT_MAX - neededSize) {
1972 parser->m_errorCode = XML_ERROR_NO_MEMORY;
1973 return NULL;
1974 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001975 neededSize += keep;
Haibo Huang40a71912019-10-11 11:13:39 -07001976#endif /* defined XML_CONTEXT_BYTES */
1977 if (neededSize
1978 <= EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_buffer)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001979#ifdef XML_CONTEXT_BYTES
Elliott Hughesaaec48e2018-08-16 16:29:01 -07001980 if (keep < EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer)) {
Haibo Huang40a71912019-10-11 11:13:39 -07001981 int offset
1982 = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer)
1983 - keep;
1984 /* The buffer pointers cannot be NULL here; we have at least some bytes
1985 * in the buffer */
1986 memmove(parser->m_buffer, &parser->m_buffer[offset],
1987 parser->m_bufferEnd - parser->m_bufferPtr + keep);
Elliott Hughes72472942018-01-10 08:36:10 -08001988 parser->m_bufferEnd -= offset;
1989 parser->m_bufferPtr -= offset;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001990 }
1991#else
Elliott Hughesaaec48e2018-08-16 16:29:01 -07001992 if (parser->m_buffer && parser->m_bufferPtr) {
1993 memmove(parser->m_buffer, parser->m_bufferPtr,
1994 EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr));
Haibo Huang40a71912019-10-11 11:13:39 -07001995 parser->m_bufferEnd
1996 = parser->m_buffer
1997 + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr);
Elliott Hughesaaec48e2018-08-16 16:29:01 -07001998 parser->m_bufferPtr = parser->m_buffer;
1999 }
Haibo Huang40a71912019-10-11 11:13:39 -07002000#endif /* not defined XML_CONTEXT_BYTES */
2001 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002002 char *newBuf;
Haibo Huang40a71912019-10-11 11:13:39 -07002003 int bufferSize
2004 = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002005 if (bufferSize == 0)
2006 bufferSize = INIT_BUFFER_SIZE;
2007 do {
Paul Duffinba34a0c2017-02-27 14:40:16 +00002008 /* Do not invoke signed arithmetic overflow: */
Haibo Huang40a71912019-10-11 11:13:39 -07002009 bufferSize = (int)(2U * (unsigned)bufferSize);
Paul Duffinc05e0322016-05-04 10:42:31 +01002010 } while (bufferSize < neededSize && bufferSize > 0);
2011 if (bufferSize <= 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08002012 parser->m_errorCode = XML_ERROR_NO_MEMORY;
Paul Duffinc05e0322016-05-04 10:42:31 +01002013 return NULL;
2014 }
Elliott Hughes72472942018-01-10 08:36:10 -08002015 newBuf = (char *)MALLOC(parser, bufferSize);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002016 if (newBuf == 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08002017 parser->m_errorCode = XML_ERROR_NO_MEMORY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002018 return NULL;
2019 }
Elliott Hughes72472942018-01-10 08:36:10 -08002020 parser->m_bufferLim = newBuf + bufferSize;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002021#ifdef XML_CONTEXT_BYTES
Elliott Hughes72472942018-01-10 08:36:10 -08002022 if (parser->m_bufferPtr) {
Elliott Hughesaaec48e2018-08-16 16:29:01 -07002023 memcpy(newBuf, &parser->m_bufferPtr[-keep],
Haibo Huang40a71912019-10-11 11:13:39 -07002024 EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)
2025 + keep);
Elliott Hughes72472942018-01-10 08:36:10 -08002026 FREE(parser, parser->m_buffer);
2027 parser->m_buffer = newBuf;
Haibo Huang40a71912019-10-11 11:13:39 -07002028 parser->m_bufferEnd
2029 = parser->m_buffer
2030 + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)
2031 + keep;
Elliott Hughes72472942018-01-10 08:36:10 -08002032 parser->m_bufferPtr = parser->m_buffer + keep;
Haibo Huang40a71912019-10-11 11:13:39 -07002033 } else {
Elliott Hughesaaec48e2018-08-16 16:29:01 -07002034 /* This must be a brand new buffer with no data in it yet */
2035 parser->m_bufferEnd = newBuf;
Elliott Hughes72472942018-01-10 08:36:10 -08002036 parser->m_bufferPtr = parser->m_buffer = newBuf;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002037 }
2038#else
Elliott Hughes72472942018-01-10 08:36:10 -08002039 if (parser->m_bufferPtr) {
Elliott Hughesaaec48e2018-08-16 16:29:01 -07002040 memcpy(newBuf, parser->m_bufferPtr,
2041 EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr));
Elliott Hughes72472942018-01-10 08:36:10 -08002042 FREE(parser, parser->m_buffer);
Haibo Huang40a71912019-10-11 11:13:39 -07002043 parser->m_bufferEnd
2044 = newBuf
2045 + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr);
2046 } else {
Elliott Hughesaaec48e2018-08-16 16:29:01 -07002047 /* This must be a brand new buffer with no data in it yet */
2048 parser->m_bufferEnd = newBuf;
2049 }
Elliott Hughes72472942018-01-10 08:36:10 -08002050 parser->m_bufferPtr = parser->m_buffer = newBuf;
Haibo Huang40a71912019-10-11 11:13:39 -07002051#endif /* not defined XML_CONTEXT_BYTES */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002052 }
Elliott Hughes72472942018-01-10 08:36:10 -08002053 parser->m_eventPtr = parser->m_eventEndPtr = NULL;
2054 parser->m_positionPtr = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002055 }
Elliott Hughes72472942018-01-10 08:36:10 -08002056 return parser->m_bufferEnd;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002057}
2058
2059enum XML_Status XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002060XML_StopParser(XML_Parser parser, XML_Bool resumable) {
Elliott Hughes72472942018-01-10 08:36:10 -08002061 if (parser == NULL)
2062 return XML_STATUS_ERROR;
2063 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002064 case XML_SUSPENDED:
2065 if (resumable) {
Elliott Hughes72472942018-01-10 08:36:10 -08002066 parser->m_errorCode = XML_ERROR_SUSPENDED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002067 return XML_STATUS_ERROR;
2068 }
Elliott Hughes72472942018-01-10 08:36:10 -08002069 parser->m_parsingStatus.parsing = XML_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002070 break;
2071 case XML_FINISHED:
Elliott Hughes72472942018-01-10 08:36:10 -08002072 parser->m_errorCode = XML_ERROR_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002073 return XML_STATUS_ERROR;
2074 default:
2075 if (resumable) {
2076#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08002077 if (parser->m_isParamEntity) {
2078 parser->m_errorCode = XML_ERROR_SUSPEND_PE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002079 return XML_STATUS_ERROR;
2080 }
2081#endif
Elliott Hughes72472942018-01-10 08:36:10 -08002082 parser->m_parsingStatus.parsing = XML_SUSPENDED;
Haibo Huang40a71912019-10-11 11:13:39 -07002083 } else
Elliott Hughes72472942018-01-10 08:36:10 -08002084 parser->m_parsingStatus.parsing = XML_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002085 }
2086 return XML_STATUS_OK;
2087}
2088
2089enum XML_Status XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002090XML_ResumeParser(XML_Parser parser) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002091 enum XML_Status result = XML_STATUS_OK;
2092
Elliott Hughes72472942018-01-10 08:36:10 -08002093 if (parser == NULL)
2094 return XML_STATUS_ERROR;
2095 if (parser->m_parsingStatus.parsing != XML_SUSPENDED) {
2096 parser->m_errorCode = XML_ERROR_NOT_SUSPENDED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002097 return XML_STATUS_ERROR;
2098 }
Elliott Hughes72472942018-01-10 08:36:10 -08002099 parser->m_parsingStatus.parsing = XML_PARSING;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002100
Haibo Huang40a71912019-10-11 11:13:39 -07002101 parser->m_errorCode = parser->m_processor(
2102 parser, parser->m_bufferPtr, parser->m_parseEndPtr, &parser->m_bufferPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002103
Elliott Hughes72472942018-01-10 08:36:10 -08002104 if (parser->m_errorCode != XML_ERROR_NONE) {
2105 parser->m_eventEndPtr = parser->m_eventPtr;
2106 parser->m_processor = errorProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002107 return XML_STATUS_ERROR;
Haibo Huang40a71912019-10-11 11:13:39 -07002108 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08002109 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002110 case XML_SUSPENDED:
2111 result = XML_STATUS_SUSPENDED;
2112 break;
Elliott Hughes35e432d2012-09-09 14:23:38 -07002113 case XML_INITIALIZED:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002114 case XML_PARSING:
Elliott Hughes72472942018-01-10 08:36:10 -08002115 if (parser->m_parsingStatus.finalBuffer) {
2116 parser->m_parsingStatus.parsing = XML_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002117 return result;
2118 }
Haibo Huang40a71912019-10-11 11:13:39 -07002119 default:;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002120 }
2121 }
2122
Haibo Huang40a71912019-10-11 11:13:39 -07002123 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
2124 parser->m_bufferPtr, &parser->m_position);
Elliott Hughes72472942018-01-10 08:36:10 -08002125 parser->m_positionPtr = parser->m_bufferPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002126 return result;
2127}
2128
2129void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002130XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status) {
Elliott Hughes72472942018-01-10 08:36:10 -08002131 if (parser == NULL)
2132 return;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002133 assert(status != NULL);
2134 *status = parser->m_parsingStatus;
2135}
2136
2137enum XML_Error XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002138XML_GetErrorCode(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002139 if (parser == NULL)
2140 return XML_ERROR_INVALID_ARGUMENT;
2141 return parser->m_errorCode;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002142}
2143
2144XML_Index XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002145XML_GetCurrentByteIndex(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002146 if (parser == NULL)
2147 return -1;
2148 if (parser->m_eventPtr)
Haibo Huang40a71912019-10-11 11:13:39 -07002149 return (XML_Index)(parser->m_parseEndByteIndex
2150 - (parser->m_parseEndPtr - parser->m_eventPtr));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002151 return -1;
2152}
2153
2154int XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002155XML_GetCurrentByteCount(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002156 if (parser == NULL)
2157 return 0;
2158 if (parser->m_eventEndPtr && parser->m_eventPtr)
2159 return (int)(parser->m_eventEndPtr - parser->m_eventPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002160 return 0;
2161}
2162
Haibo Huang40a71912019-10-11 11:13:39 -07002163const char *XMLCALL
2164XML_GetInputContext(XML_Parser parser, int *offset, int *size) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002165#ifdef XML_CONTEXT_BYTES
Elliott Hughes72472942018-01-10 08:36:10 -08002166 if (parser == NULL)
2167 return NULL;
2168 if (parser->m_eventPtr && parser->m_buffer) {
2169 if (offset != NULL)
2170 *offset = (int)(parser->m_eventPtr - parser->m_buffer);
2171 if (size != NULL)
Haibo Huang40a71912019-10-11 11:13:39 -07002172 *size = (int)(parser->m_bufferEnd - parser->m_buffer);
Elliott Hughes72472942018-01-10 08:36:10 -08002173 return parser->m_buffer;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002174 }
Elliott Hughes72472942018-01-10 08:36:10 -08002175#else
2176 (void)parser;
2177 (void)offset;
2178 (void)size;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002179#endif /* defined XML_CONTEXT_BYTES */
Haibo Huangd1a324a2020-10-28 22:19:36 -07002180 return (const char *)0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002181}
2182
2183XML_Size XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002184XML_GetCurrentLineNumber(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002185 if (parser == NULL)
2186 return 0;
2187 if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) {
Haibo Huang40a71912019-10-11 11:13:39 -07002188 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
2189 parser->m_eventPtr, &parser->m_position);
Elliott Hughes72472942018-01-10 08:36:10 -08002190 parser->m_positionPtr = parser->m_eventPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002191 }
Elliott Hughes72472942018-01-10 08:36:10 -08002192 return parser->m_position.lineNumber + 1;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002193}
2194
2195XML_Size XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002196XML_GetCurrentColumnNumber(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002197 if (parser == NULL)
2198 return 0;
2199 if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) {
Haibo Huang40a71912019-10-11 11:13:39 -07002200 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
2201 parser->m_eventPtr, &parser->m_position);
Elliott Hughes72472942018-01-10 08:36:10 -08002202 parser->m_positionPtr = parser->m_eventPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002203 }
Elliott Hughes72472942018-01-10 08:36:10 -08002204 return parser->m_position.columnNumber;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002205}
2206
2207void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002208XML_FreeContentModel(XML_Parser parser, XML_Content *model) {
Elliott Hughes72472942018-01-10 08:36:10 -08002209 if (parser != NULL)
2210 FREE(parser, model);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002211}
2212
Haibo Huang40a71912019-10-11 11:13:39 -07002213void *XMLCALL
2214XML_MemMalloc(XML_Parser parser, size_t size) {
Elliott Hughes72472942018-01-10 08:36:10 -08002215 if (parser == NULL)
2216 return NULL;
2217 return MALLOC(parser, size);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002218}
2219
Haibo Huang40a71912019-10-11 11:13:39 -07002220void *XMLCALL
2221XML_MemRealloc(XML_Parser parser, void *ptr, size_t size) {
Elliott Hughes72472942018-01-10 08:36:10 -08002222 if (parser == NULL)
2223 return NULL;
2224 return REALLOC(parser, ptr, size);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002225}
2226
2227void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002228XML_MemFree(XML_Parser parser, void *ptr) {
Elliott Hughes72472942018-01-10 08:36:10 -08002229 if (parser != NULL)
2230 FREE(parser, ptr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002231}
2232
2233void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002234XML_DefaultCurrent(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002235 if (parser == NULL)
2236 return;
2237 if (parser->m_defaultHandler) {
2238 if (parser->m_openInternalEntities)
Haibo Huang40a71912019-10-11 11:13:39 -07002239 reportDefault(parser, parser->m_internalEncoding,
Elliott Hughes72472942018-01-10 08:36:10 -08002240 parser->m_openInternalEntities->internalEventPtr,
2241 parser->m_openInternalEntities->internalEventEndPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002242 else
Haibo Huang40a71912019-10-11 11:13:39 -07002243 reportDefault(parser, parser->m_encoding, parser->m_eventPtr,
2244 parser->m_eventEndPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002245 }
2246}
2247
Haibo Huang40a71912019-10-11 11:13:39 -07002248const XML_LChar *XMLCALL
2249XML_ErrorString(enum XML_Error code) {
Elliott Hughes72472942018-01-10 08:36:10 -08002250 switch (code) {
2251 case XML_ERROR_NONE:
2252 return NULL;
2253 case XML_ERROR_NO_MEMORY:
2254 return XML_L("out of memory");
2255 case XML_ERROR_SYNTAX:
2256 return XML_L("syntax error");
2257 case XML_ERROR_NO_ELEMENTS:
2258 return XML_L("no element found");
2259 case XML_ERROR_INVALID_TOKEN:
2260 return XML_L("not well-formed (invalid token)");
2261 case XML_ERROR_UNCLOSED_TOKEN:
2262 return XML_L("unclosed token");
2263 case XML_ERROR_PARTIAL_CHAR:
2264 return XML_L("partial character");
2265 case XML_ERROR_TAG_MISMATCH:
2266 return XML_L("mismatched tag");
2267 case XML_ERROR_DUPLICATE_ATTRIBUTE:
2268 return XML_L("duplicate attribute");
2269 case XML_ERROR_JUNK_AFTER_DOC_ELEMENT:
2270 return XML_L("junk after document element");
2271 case XML_ERROR_PARAM_ENTITY_REF:
2272 return XML_L("illegal parameter entity reference");
2273 case XML_ERROR_UNDEFINED_ENTITY:
2274 return XML_L("undefined entity");
2275 case XML_ERROR_RECURSIVE_ENTITY_REF:
2276 return XML_L("recursive entity reference");
2277 case XML_ERROR_ASYNC_ENTITY:
2278 return XML_L("asynchronous entity");
2279 case XML_ERROR_BAD_CHAR_REF:
2280 return XML_L("reference to invalid character number");
2281 case XML_ERROR_BINARY_ENTITY_REF:
2282 return XML_L("reference to binary entity");
2283 case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF:
2284 return XML_L("reference to external entity in attribute");
2285 case XML_ERROR_MISPLACED_XML_PI:
2286 return XML_L("XML or text declaration not at start of entity");
2287 case XML_ERROR_UNKNOWN_ENCODING:
2288 return XML_L("unknown encoding");
2289 case XML_ERROR_INCORRECT_ENCODING:
2290 return XML_L("encoding specified in XML declaration is incorrect");
2291 case XML_ERROR_UNCLOSED_CDATA_SECTION:
2292 return XML_L("unclosed CDATA section");
2293 case XML_ERROR_EXTERNAL_ENTITY_HANDLING:
2294 return XML_L("error in processing external entity reference");
2295 case XML_ERROR_NOT_STANDALONE:
2296 return XML_L("document is not standalone");
2297 case XML_ERROR_UNEXPECTED_STATE:
2298 return XML_L("unexpected parser state - please send a bug report");
2299 case XML_ERROR_ENTITY_DECLARED_IN_PE:
2300 return XML_L("entity declared in parameter entity");
2301 case XML_ERROR_FEATURE_REQUIRES_XML_DTD:
2302 return XML_L("requested feature requires XML_DTD support in Expat");
2303 case XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING:
2304 return XML_L("cannot change setting once parsing has begun");
2305 /* Added in 1.95.7. */
2306 case XML_ERROR_UNBOUND_PREFIX:
2307 return XML_L("unbound prefix");
2308 /* Added in 1.95.8. */
2309 case XML_ERROR_UNDECLARING_PREFIX:
2310 return XML_L("must not undeclare prefix");
2311 case XML_ERROR_INCOMPLETE_PE:
2312 return XML_L("incomplete markup in parameter entity");
2313 case XML_ERROR_XML_DECL:
2314 return XML_L("XML declaration not well-formed");
2315 case XML_ERROR_TEXT_DECL:
2316 return XML_L("text declaration not well-formed");
2317 case XML_ERROR_PUBLICID:
2318 return XML_L("illegal character(s) in public id");
2319 case XML_ERROR_SUSPENDED:
2320 return XML_L("parser suspended");
2321 case XML_ERROR_NOT_SUSPENDED:
2322 return XML_L("parser not suspended");
2323 case XML_ERROR_ABORTED:
2324 return XML_L("parsing aborted");
2325 case XML_ERROR_FINISHED:
2326 return XML_L("parsing finished");
2327 case XML_ERROR_SUSPEND_PE:
2328 return XML_L("cannot suspend in external parameter entity");
2329 /* Added in 2.0.0. */
2330 case XML_ERROR_RESERVED_PREFIX_XML:
Haibo Huang40a71912019-10-11 11:13:39 -07002331 return XML_L(
2332 "reserved prefix (xml) must not be undeclared or bound to another namespace name");
Elliott Hughes72472942018-01-10 08:36:10 -08002333 case XML_ERROR_RESERVED_PREFIX_XMLNS:
2334 return XML_L("reserved prefix (xmlns) must not be declared or undeclared");
2335 case XML_ERROR_RESERVED_NAMESPACE_URI:
Haibo Huang40a71912019-10-11 11:13:39 -07002336 return XML_L(
2337 "prefix must not be bound to one of the reserved namespace names");
Elliott Hughes72472942018-01-10 08:36:10 -08002338 /* Added in 2.2.5. */
Haibo Huang40a71912019-10-11 11:13:39 -07002339 case XML_ERROR_INVALID_ARGUMENT: /* Constant added in 2.2.1, already */
Elliott Hughes72472942018-01-10 08:36:10 -08002340 return XML_L("invalid argument");
Elliott Hughesf648a292021-04-01 15:10:13 -07002341 /* Added in 2.3.0. */
2342 case XML_ERROR_NO_BUFFER:
2343 return XML_L(
2344 "a successful prior call to function XML_GetBuffer is required");
Elliott Hughes72472942018-01-10 08:36:10 -08002345 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002346 return NULL;
2347}
2348
Haibo Huang40a71912019-10-11 11:13:39 -07002349const XML_LChar *XMLCALL
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002350XML_ExpatVersion(void) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002351 /* V1 is used to string-ize the version number. However, it would
2352 string-ize the actual version macro *names* unless we get them
2353 substituted before being passed to V1. CPP is defined to expand
2354 a macro, then rescan for more expansions. Thus, we use V2 to expand
2355 the version macros, then CPP will expand the resulting V1() macro
2356 with the correct numerals. */
2357 /* ### I'm assuming cpp is portable in this respect... */
2358
Haibo Huang40a71912019-10-11 11:13:39 -07002359#define V1(a, b, c) XML_L(#a) XML_L(".") XML_L(#b) XML_L(".") XML_L(#c)
2360#define V2(a, b, c) XML_L("expat_") V1(a, b, c)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002361
2362 return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
2363
2364#undef V1
2365#undef V2
2366}
2367
2368XML_Expat_Version XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002369XML_ExpatVersionInfo(void) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002370 XML_Expat_Version version;
2371
2372 version.major = XML_MAJOR_VERSION;
2373 version.minor = XML_MINOR_VERSION;
2374 version.micro = XML_MICRO_VERSION;
2375
2376 return version;
2377}
2378
Haibo Huang40a71912019-10-11 11:13:39 -07002379const XML_Feature *XMLCALL
2380XML_GetFeatureList(void) {
2381 static const XML_Feature features[]
2382 = {{XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"),
2383 sizeof(XML_Char)},
2384 {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
2385 sizeof(XML_LChar)},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002386#ifdef XML_UNICODE
Haibo Huang40a71912019-10-11 11:13:39 -07002387 {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002388#endif
2389#ifdef XML_UNICODE_WCHAR_T
Haibo Huang40a71912019-10-11 11:13:39 -07002390 {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002391#endif
2392#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07002393 {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002394#endif
2395#ifdef XML_CONTEXT_BYTES
Haibo Huang40a71912019-10-11 11:13:39 -07002396 {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
2397 XML_CONTEXT_BYTES},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002398#endif
2399#ifdef XML_MIN_SIZE
Haibo Huang40a71912019-10-11 11:13:39 -07002400 {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002401#endif
2402#ifdef XML_NS
Haibo Huang40a71912019-10-11 11:13:39 -07002403 {XML_FEATURE_NS, XML_L("XML_NS"), 0},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002404#endif
Elliott Hughesd07d5a72009-09-25 16:04:37 -07002405#ifdef XML_LARGE_SIZE
Haibo Huang40a71912019-10-11 11:13:39 -07002406 {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0},
Elliott Hughes35e432d2012-09-09 14:23:38 -07002407#endif
2408#ifdef XML_ATTR_INFO
Haibo Huang40a71912019-10-11 11:13:39 -07002409 {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0},
Elliott Hughes35e432d2012-09-09 14:23:38 -07002410#endif
Haibo Huang40a71912019-10-11 11:13:39 -07002411 {XML_FEATURE_END, NULL, 0}};
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002412
2413 return features;
2414}
2415
2416/* Initially tag->rawName always points into the parse buffer;
2417 for those TAG instances opened while the current parse buffer was
2418 processed, and not yet closed, we need to store tag->rawName in a more
2419 permanent location, since the parse buffer is about to be discarded.
2420*/
2421static XML_Bool
Haibo Huang40a71912019-10-11 11:13:39 -07002422storeRawNames(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002423 TAG *tag = parser->m_tagStack;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002424 while (tag) {
2425 int bufSize;
2426 int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
2427 char *rawNameBuf = tag->buf + nameLen;
Elliott Hughes72472942018-01-10 08:36:10 -08002428 /* Stop if already stored. Since m_tagStack is a stack, we can stop
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002429 at the first entry that has already been copied; everything
2430 below it in the stack is already been accounted for in a
2431 previous call to this function.
2432 */
2433 if (tag->rawName == rawNameBuf)
2434 break;
2435 /* For re-use purposes we need to ensure that the
2436 size of tag->buf is a multiple of sizeof(XML_Char).
2437 */
2438 bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
2439 if (bufSize > tag->bufEnd - tag->buf) {
Elliott Hughes72472942018-01-10 08:36:10 -08002440 char *temp = (char *)REALLOC(parser, tag->buf, bufSize);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002441 if (temp == NULL)
2442 return XML_FALSE;
2443 /* if tag->name.str points to tag->buf (only when namespace
2444 processing is off) then we have to update it
2445 */
2446 if (tag->name.str == (XML_Char *)tag->buf)
2447 tag->name.str = (XML_Char *)temp;
2448 /* if tag->name.localPart is set (when namespace processing is on)
2449 then update it as well, since it will always point into tag->buf
2450 */
2451 if (tag->name.localPart)
Haibo Huang40a71912019-10-11 11:13:39 -07002452 tag->name.localPart
2453 = (XML_Char *)temp + (tag->name.localPart - (XML_Char *)tag->buf);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002454 tag->buf = temp;
2455 tag->bufEnd = temp + bufSize;
2456 rawNameBuf = temp + nameLen;
2457 }
2458 memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
2459 tag->rawName = rawNameBuf;
2460 tag = tag->parent;
2461 }
2462 return XML_TRUE;
2463}
2464
2465static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002466contentProcessor(XML_Parser parser, const char *start, const char *end,
2467 const char **endPtr) {
2468 enum XML_Error result
2469 = doContent(parser, 0, parser->m_encoding, start, end, endPtr,
2470 (XML_Bool)! parser->m_parsingStatus.finalBuffer);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002471 if (result == XML_ERROR_NONE) {
Haibo Huang40a71912019-10-11 11:13:39 -07002472 if (! storeRawNames(parser))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002473 return XML_ERROR_NO_MEMORY;
2474 }
2475 return result;
2476}
2477
2478static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002479externalEntityInitProcessor(XML_Parser parser, const char *start,
2480 const char *end, const char **endPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002481 enum XML_Error result = initializeEncoding(parser);
2482 if (result != XML_ERROR_NONE)
2483 return result;
Elliott Hughes72472942018-01-10 08:36:10 -08002484 parser->m_processor = externalEntityInitProcessor2;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002485 return externalEntityInitProcessor2(parser, start, end, endPtr);
2486}
2487
2488static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002489externalEntityInitProcessor2(XML_Parser parser, const char *start,
2490 const char *end, const char **endPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002491 const char *next = start; /* XmlContentTok doesn't always set the last arg */
Elliott Hughes72472942018-01-10 08:36:10 -08002492 int tok = XmlContentTok(parser->m_encoding, start, end, &next);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002493 switch (tok) {
2494 case XML_TOK_BOM:
2495 /* If we are at the end of the buffer, this would cause the next stage,
2496 i.e. externalEntityInitProcessor3, to pass control directly to
2497 doContent (by detecting XML_TOK_NONE) without processing any xml text
2498 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
2499 */
Haibo Huang40a71912019-10-11 11:13:39 -07002500 if (next == end && ! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002501 *endPtr = next;
2502 return XML_ERROR_NONE;
2503 }
2504 start = next;
2505 break;
2506 case XML_TOK_PARTIAL:
Haibo Huang40a71912019-10-11 11:13:39 -07002507 if (! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002508 *endPtr = start;
2509 return XML_ERROR_NONE;
2510 }
Elliott Hughes72472942018-01-10 08:36:10 -08002511 parser->m_eventPtr = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002512 return XML_ERROR_UNCLOSED_TOKEN;
2513 case XML_TOK_PARTIAL_CHAR:
Haibo Huang40a71912019-10-11 11:13:39 -07002514 if (! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002515 *endPtr = start;
2516 return XML_ERROR_NONE;
2517 }
Elliott Hughes72472942018-01-10 08:36:10 -08002518 parser->m_eventPtr = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002519 return XML_ERROR_PARTIAL_CHAR;
2520 }
Elliott Hughes72472942018-01-10 08:36:10 -08002521 parser->m_processor = externalEntityInitProcessor3;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002522 return externalEntityInitProcessor3(parser, start, end, endPtr);
2523}
2524
2525static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002526externalEntityInitProcessor3(XML_Parser parser, const char *start,
2527 const char *end, const char **endPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002528 int tok;
2529 const char *next = start; /* XmlContentTok doesn't always set the last arg */
Elliott Hughes72472942018-01-10 08:36:10 -08002530 parser->m_eventPtr = start;
2531 tok = XmlContentTok(parser->m_encoding, start, end, &next);
2532 parser->m_eventEndPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002533
2534 switch (tok) {
Haibo Huang40a71912019-10-11 11:13:39 -07002535 case XML_TOK_XML_DECL: {
2536 enum XML_Error result;
2537 result = processXmlDecl(parser, 1, start, next);
2538 if (result != XML_ERROR_NONE)
2539 return result;
2540 switch (parser->m_parsingStatus.parsing) {
2541 case XML_SUSPENDED:
2542 *endPtr = next;
2543 return XML_ERROR_NONE;
2544 case XML_FINISHED:
2545 return XML_ERROR_ABORTED;
2546 default:
2547 start = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002548 }
Haibo Huang40a71912019-10-11 11:13:39 -07002549 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002550 case XML_TOK_PARTIAL:
Haibo Huang40a71912019-10-11 11:13:39 -07002551 if (! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002552 *endPtr = start;
2553 return XML_ERROR_NONE;
2554 }
2555 return XML_ERROR_UNCLOSED_TOKEN;
2556 case XML_TOK_PARTIAL_CHAR:
Haibo Huang40a71912019-10-11 11:13:39 -07002557 if (! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002558 *endPtr = start;
2559 return XML_ERROR_NONE;
2560 }
2561 return XML_ERROR_PARTIAL_CHAR;
2562 }
Elliott Hughes72472942018-01-10 08:36:10 -08002563 parser->m_processor = externalEntityContentProcessor;
2564 parser->m_tagLevel = 1;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002565 return externalEntityContentProcessor(parser, start, end, endPtr);
2566}
2567
2568static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002569externalEntityContentProcessor(XML_Parser parser, const char *start,
2570 const char *end, const char **endPtr) {
2571 enum XML_Error result
2572 = doContent(parser, 1, parser->m_encoding, start, end, endPtr,
2573 (XML_Bool)! parser->m_parsingStatus.finalBuffer);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002574 if (result == XML_ERROR_NONE) {
Haibo Huang40a71912019-10-11 11:13:39 -07002575 if (! storeRawNames(parser))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002576 return XML_ERROR_NO_MEMORY;
2577 }
2578 return result;
2579}
2580
2581static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07002582doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
2583 const char *s, const char *end, const char **nextPtr,
2584 XML_Bool haveMore) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002585 /* save one level of indirection */
Haibo Huang40a71912019-10-11 11:13:39 -07002586 DTD *const dtd = parser->m_dtd;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002587
2588 const char **eventPP;
2589 const char **eventEndPP;
Elliott Hughes72472942018-01-10 08:36:10 -08002590 if (enc == parser->m_encoding) {
2591 eventPP = &parser->m_eventPtr;
2592 eventEndPP = &parser->m_eventEndPtr;
Haibo Huang40a71912019-10-11 11:13:39 -07002593 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08002594 eventPP = &(parser->m_openInternalEntities->internalEventPtr);
2595 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002596 }
2597 *eventPP = s;
2598
2599 for (;;) {
2600 const char *next = s; /* XmlContentTok doesn't always set the last arg */
2601 int tok = XmlContentTok(enc, s, end, &next);
2602 *eventEndPP = next;
2603 switch (tok) {
2604 case XML_TOK_TRAILING_CR:
2605 if (haveMore) {
2606 *nextPtr = s;
2607 return XML_ERROR_NONE;
2608 }
2609 *eventEndPP = end;
Elliott Hughes72472942018-01-10 08:36:10 -08002610 if (parser->m_characterDataHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002611 XML_Char c = 0xA;
Elliott Hughes72472942018-01-10 08:36:10 -08002612 parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
Haibo Huang40a71912019-10-11 11:13:39 -07002613 } else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002614 reportDefault(parser, enc, s, end);
Elliott Hughes35e432d2012-09-09 14:23:38 -07002615 /* We are at the end of the final buffer, should we check for
2616 XML_SUSPENDED, XML_FINISHED?
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002617 */
2618 if (startTagLevel == 0)
2619 return XML_ERROR_NO_ELEMENTS;
Elliott Hughes72472942018-01-10 08:36:10 -08002620 if (parser->m_tagLevel != startTagLevel)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002621 return XML_ERROR_ASYNC_ENTITY;
2622 *nextPtr = end;
2623 return XML_ERROR_NONE;
2624 case XML_TOK_NONE:
2625 if (haveMore) {
2626 *nextPtr = s;
2627 return XML_ERROR_NONE;
2628 }
2629 if (startTagLevel > 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08002630 if (parser->m_tagLevel != startTagLevel)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002631 return XML_ERROR_ASYNC_ENTITY;
2632 *nextPtr = s;
2633 return XML_ERROR_NONE;
2634 }
2635 return XML_ERROR_NO_ELEMENTS;
2636 case XML_TOK_INVALID:
2637 *eventPP = next;
2638 return XML_ERROR_INVALID_TOKEN;
2639 case XML_TOK_PARTIAL:
2640 if (haveMore) {
2641 *nextPtr = s;
2642 return XML_ERROR_NONE;
2643 }
2644 return XML_ERROR_UNCLOSED_TOKEN;
2645 case XML_TOK_PARTIAL_CHAR:
2646 if (haveMore) {
2647 *nextPtr = s;
2648 return XML_ERROR_NONE;
2649 }
2650 return XML_ERROR_PARTIAL_CHAR;
Haibo Huang40a71912019-10-11 11:13:39 -07002651 case XML_TOK_ENTITY_REF: {
2652 const XML_Char *name;
2653 ENTITY *entity;
2654 XML_Char ch = (XML_Char)XmlPredefinedEntityName(
2655 enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar);
2656 if (ch) {
2657 if (parser->m_characterDataHandler)
2658 parser->m_characterDataHandler(parser->m_handlerArg, &ch, 1);
Elliott Hughes72472942018-01-10 08:36:10 -08002659 else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002660 reportDefault(parser, enc, s, next);
2661 break;
2662 }
Haibo Huang40a71912019-10-11 11:13:39 -07002663 name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
2664 next - enc->minBytesPerChar);
2665 if (! name)
2666 return XML_ERROR_NO_MEMORY;
2667 entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
2668 poolDiscard(&dtd->pool);
2669 /* First, determine if a check for an existing declaration is needed;
2670 if yes, check that the entity exists, and that it is internal,
2671 otherwise call the skipped entity or default handler.
2672 */
2673 if (! dtd->hasParamEntityRefs || dtd->standalone) {
2674 if (! entity)
2675 return XML_ERROR_UNDEFINED_ENTITY;
2676 else if (! entity->is_internal)
2677 return XML_ERROR_ENTITY_DECLARED_IN_PE;
2678 } else if (! entity) {
2679 if (parser->m_skippedEntityHandler)
2680 parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
2681 else if (parser->m_defaultHandler)
2682 reportDefault(parser, enc, s, next);
2683 break;
2684 }
2685 if (entity->open)
2686 return XML_ERROR_RECURSIVE_ENTITY_REF;
2687 if (entity->notation)
2688 return XML_ERROR_BINARY_ENTITY_REF;
2689 if (entity->textPtr) {
2690 enum XML_Error result;
2691 if (! parser->m_defaultExpandInternalEntities) {
2692 if (parser->m_skippedEntityHandler)
2693 parser->m_skippedEntityHandler(parser->m_handlerArg, entity->name,
2694 0);
2695 else if (parser->m_defaultHandler)
2696 reportDefault(parser, enc, s, next);
2697 break;
2698 }
2699 result = processInternalEntity(parser, entity, XML_FALSE);
2700 if (result != XML_ERROR_NONE)
2701 return result;
2702 } else if (parser->m_externalEntityRefHandler) {
2703 const XML_Char *context;
2704 entity->open = XML_TRUE;
2705 context = getContext(parser);
2706 entity->open = XML_FALSE;
2707 if (! context)
2708 return XML_ERROR_NO_MEMORY;
2709 if (! parser->m_externalEntityRefHandler(
2710 parser->m_externalEntityRefHandlerArg, context, entity->base,
2711 entity->systemId, entity->publicId))
2712 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
2713 poolDiscard(&parser->m_tempPool);
2714 } else if (parser->m_defaultHandler)
2715 reportDefault(parser, enc, s, next);
2716 break;
2717 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002718 case XML_TOK_START_TAG_NO_ATTS:
2719 /* fall through */
Haibo Huang40a71912019-10-11 11:13:39 -07002720 case XML_TOK_START_TAG_WITH_ATTS: {
2721 TAG *tag;
2722 enum XML_Error result;
2723 XML_Char *toPtr;
2724 if (parser->m_freeTagList) {
2725 tag = parser->m_freeTagList;
2726 parser->m_freeTagList = parser->m_freeTagList->parent;
2727 } else {
2728 tag = (TAG *)MALLOC(parser, sizeof(TAG));
2729 if (! tag)
2730 return XML_ERROR_NO_MEMORY;
2731 tag->buf = (char *)MALLOC(parser, INIT_TAG_BUF_SIZE);
2732 if (! tag->buf) {
2733 FREE(parser, tag);
2734 return XML_ERROR_NO_MEMORY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002735 }
Haibo Huang40a71912019-10-11 11:13:39 -07002736 tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002737 }
Haibo Huang40a71912019-10-11 11:13:39 -07002738 tag->bindings = NULL;
2739 tag->parent = parser->m_tagStack;
2740 parser->m_tagStack = tag;
2741 tag->name.localPart = NULL;
2742 tag->name.prefix = NULL;
2743 tag->rawName = s + enc->minBytesPerChar;
2744 tag->rawNameLength = XmlNameLength(enc, tag->rawName);
2745 ++parser->m_tagLevel;
2746 {
2747 const char *rawNameEnd = tag->rawName + tag->rawNameLength;
2748 const char *fromPtr = tag->rawName;
2749 toPtr = (XML_Char *)tag->buf;
2750 for (;;) {
2751 int bufSize;
2752 int convLen;
2753 const enum XML_Convert_Result convert_res
2754 = XmlConvert(enc, &fromPtr, rawNameEnd, (ICHAR **)&toPtr,
2755 (ICHAR *)tag->bufEnd - 1);
2756 convLen = (int)(toPtr - (XML_Char *)tag->buf);
2757 if ((fromPtr >= rawNameEnd)
2758 || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) {
2759 tag->name.strLen = convLen;
2760 break;
2761 }
2762 bufSize = (int)(tag->bufEnd - tag->buf) << 1;
2763 {
2764 char *temp = (char *)REALLOC(parser, tag->buf, bufSize);
2765 if (temp == NULL)
2766 return XML_ERROR_NO_MEMORY;
2767 tag->buf = temp;
2768 tag->bufEnd = temp + bufSize;
2769 toPtr = (XML_Char *)temp + convLen;
2770 }
2771 }
2772 }
2773 tag->name.str = (XML_Char *)tag->buf;
2774 *toPtr = XML_T('\0');
2775 result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
2776 if (result)
2777 return result;
2778 if (parser->m_startElementHandler)
2779 parser->m_startElementHandler(parser->m_handlerArg, tag->name.str,
2780 (const XML_Char **)parser->m_atts);
2781 else if (parser->m_defaultHandler)
2782 reportDefault(parser, enc, s, next);
2783 poolClear(&parser->m_tempPool);
2784 break;
2785 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002786 case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
2787 /* fall through */
Haibo Huang40a71912019-10-11 11:13:39 -07002788 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS: {
2789 const char *rawName = s + enc->minBytesPerChar;
2790 enum XML_Error result;
2791 BINDING *bindings = NULL;
2792 XML_Bool noElmHandlers = XML_TRUE;
2793 TAG_NAME name;
2794 name.str = poolStoreString(&parser->m_tempPool, enc, rawName,
2795 rawName + XmlNameLength(enc, rawName));
2796 if (! name.str)
2797 return XML_ERROR_NO_MEMORY;
2798 poolFinish(&parser->m_tempPool);
2799 result = storeAtts(parser, enc, s, &name, &bindings);
2800 if (result != XML_ERROR_NONE) {
Elliott Hughes72472942018-01-10 08:36:10 -08002801 freeBindings(parser, bindings);
Haibo Huang40a71912019-10-11 11:13:39 -07002802 return result;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002803 }
Haibo Huang40a71912019-10-11 11:13:39 -07002804 poolFinish(&parser->m_tempPool);
2805 if (parser->m_startElementHandler) {
2806 parser->m_startElementHandler(parser->m_handlerArg, name.str,
2807 (const XML_Char **)parser->m_atts);
2808 noElmHandlers = XML_FALSE;
2809 }
2810 if (parser->m_endElementHandler) {
2811 if (parser->m_startElementHandler)
2812 *eventPP = *eventEndPP;
2813 parser->m_endElementHandler(parser->m_handlerArg, name.str);
2814 noElmHandlers = XML_FALSE;
2815 }
2816 if (noElmHandlers && parser->m_defaultHandler)
2817 reportDefault(parser, enc, s, next);
2818 poolClear(&parser->m_tempPool);
2819 freeBindings(parser, bindings);
2820 }
2821 if ((parser->m_tagLevel == 0)
2822 && (parser->m_parsingStatus.parsing != XML_FINISHED)) {
Elliott Hughesaaec48e2018-08-16 16:29:01 -07002823 if (parser->m_parsingStatus.parsing == XML_SUSPENDED)
2824 parser->m_processor = epilogProcessor;
2825 else
2826 return epilogProcessor(parser, next, end, nextPtr);
Elliott Hughes72472942018-01-10 08:36:10 -08002827 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002828 break;
2829 case XML_TOK_END_TAG:
Elliott Hughes72472942018-01-10 08:36:10 -08002830 if (parser->m_tagLevel == startTagLevel)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002831 return XML_ERROR_ASYNC_ENTITY;
2832 else {
2833 int len;
2834 const char *rawName;
Elliott Hughes72472942018-01-10 08:36:10 -08002835 TAG *tag = parser->m_tagStack;
2836 parser->m_tagStack = tag->parent;
2837 tag->parent = parser->m_freeTagList;
2838 parser->m_freeTagList = tag;
Haibo Huang40a71912019-10-11 11:13:39 -07002839 rawName = s + enc->minBytesPerChar * 2;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002840 len = XmlNameLength(enc, rawName);
2841 if (len != tag->rawNameLength
2842 || memcmp(tag->rawName, rawName, len) != 0) {
2843 *eventPP = rawName;
2844 return XML_ERROR_TAG_MISMATCH;
2845 }
Elliott Hughes72472942018-01-10 08:36:10 -08002846 --parser->m_tagLevel;
2847 if (parser->m_endElementHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002848 const XML_Char *localPart;
2849 const XML_Char *prefix;
2850 XML_Char *uri;
2851 localPart = tag->name.localPart;
Elliott Hughes72472942018-01-10 08:36:10 -08002852 if (parser->m_ns && localPart) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002853 /* localPart and prefix may have been overwritten in
2854 tag->name.str, since this points to the binding->uri
2855 buffer which gets re-used; so we have to add them again
2856 */
2857 uri = (XML_Char *)tag->name.str + tag->name.uriLen;
2858 /* don't need to check for space - already done in storeAtts() */
Haibo Huang40a71912019-10-11 11:13:39 -07002859 while (*localPart)
2860 *uri++ = *localPart++;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002861 prefix = (XML_Char *)tag->name.prefix;
Elliott Hughes72472942018-01-10 08:36:10 -08002862 if (parser->m_ns_triplets && prefix) {
2863 *uri++ = parser->m_namespaceSeparator;
Haibo Huang40a71912019-10-11 11:13:39 -07002864 while (*prefix)
2865 *uri++ = *prefix++;
2866 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002867 *uri = XML_T('\0');
2868 }
Elliott Hughes72472942018-01-10 08:36:10 -08002869 parser->m_endElementHandler(parser->m_handlerArg, tag->name.str);
Haibo Huang40a71912019-10-11 11:13:39 -07002870 } else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002871 reportDefault(parser, enc, s, next);
2872 while (tag->bindings) {
2873 BINDING *b = tag->bindings;
Elliott Hughes72472942018-01-10 08:36:10 -08002874 if (parser->m_endNamespaceDeclHandler)
Haibo Huang40a71912019-10-11 11:13:39 -07002875 parser->m_endNamespaceDeclHandler(parser->m_handlerArg,
2876 b->prefix->name);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002877 tag->bindings = tag->bindings->nextTagBinding;
Elliott Hughes72472942018-01-10 08:36:10 -08002878 b->nextTagBinding = parser->m_freeBindingList;
2879 parser->m_freeBindingList = b;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002880 b->prefix->binding = b->prevPrefixBinding;
2881 }
Haibo Huang40a71912019-10-11 11:13:39 -07002882 if ((parser->m_tagLevel == 0)
2883 && (parser->m_parsingStatus.parsing != XML_FINISHED)) {
2884 if (parser->m_parsingStatus.parsing == XML_SUSPENDED)
2885 parser->m_processor = epilogProcessor;
2886 else
2887 return epilogProcessor(parser, next, end, nextPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002888 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002889 }
2890 break;
Haibo Huang40a71912019-10-11 11:13:39 -07002891 case XML_TOK_CHAR_REF: {
2892 int n = XmlCharRefNumber(enc, s);
2893 if (n < 0)
2894 return XML_ERROR_BAD_CHAR_REF;
2895 if (parser->m_characterDataHandler) {
2896 XML_Char buf[XML_ENCODE_MAX];
2897 parser->m_characterDataHandler(parser->m_handlerArg, buf,
2898 XmlEncode(n, (ICHAR *)buf));
2899 } else if (parser->m_defaultHandler)
2900 reportDefault(parser, enc, s, next);
2901 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002902 case XML_TOK_XML_DECL:
2903 return XML_ERROR_MISPLACED_XML_PI;
2904 case XML_TOK_DATA_NEWLINE:
Elliott Hughes72472942018-01-10 08:36:10 -08002905 if (parser->m_characterDataHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002906 XML_Char c = 0xA;
Elliott Hughes72472942018-01-10 08:36:10 -08002907 parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
Haibo Huang40a71912019-10-11 11:13:39 -07002908 } else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002909 reportDefault(parser, enc, s, next);
2910 break;
Haibo Huang40a71912019-10-11 11:13:39 -07002911 case XML_TOK_CDATA_SECT_OPEN: {
2912 enum XML_Error result;
2913 if (parser->m_startCdataSectionHandler)
2914 parser->m_startCdataSectionHandler(parser->m_handlerArg);
2915 /* BEGIN disabled code */
2916 /* Suppose you doing a transformation on a document that involves
2917 changing only the character data. You set up a defaultHandler
2918 and a characterDataHandler. The defaultHandler simply copies
2919 characters through. The characterDataHandler does the
2920 transformation and writes the characters out escaping them as
2921 necessary. This case will fail to work if we leave out the
2922 following two lines (because & and < inside CDATA sections will
2923 be incorrectly escaped).
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002924
Haibo Huang40a71912019-10-11 11:13:39 -07002925 However, now we have a start/endCdataSectionHandler, so it seems
2926 easier to let the user deal with this.
2927 */
2928 else if (0 && parser->m_characterDataHandler)
2929 parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf,
2930 0);
2931 /* END disabled code */
2932 else if (parser->m_defaultHandler)
2933 reportDefault(parser, enc, s, next);
2934 result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
2935 if (result != XML_ERROR_NONE)
2936 return result;
2937 else if (! next) {
2938 parser->m_processor = cdataSectionProcessor;
2939 return result;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002940 }
Haibo Huang40a71912019-10-11 11:13:39 -07002941 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002942 case XML_TOK_TRAILING_RSQB:
2943 if (haveMore) {
2944 *nextPtr = s;
2945 return XML_ERROR_NONE;
2946 }
Elliott Hughes72472942018-01-10 08:36:10 -08002947 if (parser->m_characterDataHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002948 if (MUST_CONVERT(enc, s)) {
Elliott Hughes72472942018-01-10 08:36:10 -08002949 ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
2950 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
Haibo Huang40a71912019-10-11 11:13:39 -07002951 parser->m_characterDataHandler(
2952 parser->m_handlerArg, parser->m_dataBuf,
2953 (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
2954 } else
2955 parser->m_characterDataHandler(
2956 parser->m_handlerArg, (XML_Char *)s,
2957 (int)((XML_Char *)end - (XML_Char *)s));
2958 } else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002959 reportDefault(parser, enc, s, end);
Elliott Hughes35e432d2012-09-09 14:23:38 -07002960 /* We are at the end of the final buffer, should we check for
2961 XML_SUSPENDED, XML_FINISHED?
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002962 */
2963 if (startTagLevel == 0) {
2964 *eventPP = end;
2965 return XML_ERROR_NO_ELEMENTS;
2966 }
Elliott Hughes72472942018-01-10 08:36:10 -08002967 if (parser->m_tagLevel != startTagLevel) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002968 *eventPP = end;
2969 return XML_ERROR_ASYNC_ENTITY;
2970 }
2971 *nextPtr = end;
2972 return XML_ERROR_NONE;
Haibo Huang40a71912019-10-11 11:13:39 -07002973 case XML_TOK_DATA_CHARS: {
2974 XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler;
2975 if (charDataHandler) {
2976 if (MUST_CONVERT(enc, s)) {
2977 for (;;) {
2978 ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
2979 const enum XML_Convert_Result convert_res = XmlConvert(
2980 enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
2981 *eventEndPP = s;
2982 charDataHandler(parser->m_handlerArg, parser->m_dataBuf,
2983 (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
2984 if ((convert_res == XML_CONVERT_COMPLETED)
2985 || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
2986 break;
2987 *eventPP = s;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002988 }
Haibo Huang40a71912019-10-11 11:13:39 -07002989 } else
2990 charDataHandler(parser->m_handlerArg, (XML_Char *)s,
2991 (int)((XML_Char *)next - (XML_Char *)s));
2992 } else if (parser->m_defaultHandler)
2993 reportDefault(parser, enc, s, next);
2994 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002995 case XML_TOK_PI:
Haibo Huang40a71912019-10-11 11:13:39 -07002996 if (! reportProcessingInstruction(parser, enc, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002997 return XML_ERROR_NO_MEMORY;
2998 break;
2999 case XML_TOK_COMMENT:
Haibo Huang40a71912019-10-11 11:13:39 -07003000 if (! reportComment(parser, enc, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003001 return XML_ERROR_NO_MEMORY;
3002 break;
3003 default:
Elliott Hughes72472942018-01-10 08:36:10 -08003004 /* All of the tokens produced by XmlContentTok() have their own
3005 * explicit cases, so this default is not strictly necessary.
3006 * However it is a useful safety net, so we retain the code and
3007 * simply exclude it from the coverage tests.
3008 *
3009 * LCOV_EXCL_START
3010 */
3011 if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003012 reportDefault(parser, enc, s, next);
3013 break;
Elliott Hughes72472942018-01-10 08:36:10 -08003014 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003015 }
3016 *eventPP = s = next;
Elliott Hughes72472942018-01-10 08:36:10 -08003017 switch (parser->m_parsingStatus.parsing) {
Elliott Hughes35e432d2012-09-09 14:23:38 -07003018 case XML_SUSPENDED:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003019 *nextPtr = next;
3020 return XML_ERROR_NONE;
3021 case XML_FINISHED:
3022 return XML_ERROR_ABORTED;
Haibo Huang40a71912019-10-11 11:13:39 -07003023 default:;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003024 }
3025 }
3026 /* not reached */
3027}
3028
Elliott Hughes72472942018-01-10 08:36:10 -08003029/* This function does not call free() on the allocated memory, merely
3030 * moving it to the parser's m_freeBindingList where it can be freed or
3031 * reused as appropriate.
3032 */
3033static void
Haibo Huang40a71912019-10-11 11:13:39 -07003034freeBindings(XML_Parser parser, BINDING *bindings) {
Elliott Hughes72472942018-01-10 08:36:10 -08003035 while (bindings) {
3036 BINDING *b = bindings;
3037
3038 /* m_startNamespaceDeclHandler will have been called for this
3039 * binding in addBindings(), so call the end handler now.
3040 */
3041 if (parser->m_endNamespaceDeclHandler)
Haibo Huang40a71912019-10-11 11:13:39 -07003042 parser->m_endNamespaceDeclHandler(parser->m_handlerArg, b->prefix->name);
Elliott Hughes72472942018-01-10 08:36:10 -08003043
3044 bindings = bindings->nextTagBinding;
3045 b->nextTagBinding = parser->m_freeBindingList;
3046 parser->m_freeBindingList = b;
3047 b->prefix->binding = b->prevPrefixBinding;
3048 }
3049}
3050
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003051/* Precondition: all arguments must be non-NULL;
3052 Purpose:
3053 - normalize attributes
3054 - check attributes for well-formedness
3055 - generate namespace aware attribute names (URI, prefix)
3056 - build list of attributes for startElementHandler
3057 - default attributes
3058 - process namespace declarations (check and report them)
3059 - generate namespace aware element name (URI, prefix)
3060*/
3061static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07003062storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
3063 TAG_NAME *tagNamePtr, BINDING **bindingsPtr) {
3064 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003065 ELEMENT_TYPE *elementType;
3066 int nDefaultAtts;
Haibo Huang40a71912019-10-11 11:13:39 -07003067 const XML_Char **appAtts; /* the attribute list for the application */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003068 int attIndex = 0;
3069 int prefixLen;
3070 int i;
3071 int n;
3072 XML_Char *uri;
3073 int nPrefixes = 0;
3074 BINDING *binding;
3075 const XML_Char *localPart;
3076
3077 /* lookup the element type name */
Haibo Huang40a71912019-10-11 11:13:39 -07003078 elementType
3079 = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str, 0);
3080 if (! elementType) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003081 const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
Haibo Huang40a71912019-10-11 11:13:39 -07003082 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003083 return XML_ERROR_NO_MEMORY;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003084 elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003085 sizeof(ELEMENT_TYPE));
Haibo Huang40a71912019-10-11 11:13:39 -07003086 if (! elementType)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003087 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07003088 if (parser->m_ns && ! setElementTypePrefix(parser, elementType))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003089 return XML_ERROR_NO_MEMORY;
3090 }
3091 nDefaultAtts = elementType->nDefaultAtts;
3092
3093 /* get the attributes from the tokenizer */
Elliott Hughes72472942018-01-10 08:36:10 -08003094 n = XmlGetAttributes(enc, attStr, parser->m_attsSize, parser->m_atts);
3095 if (n + nDefaultAtts > parser->m_attsSize) {
3096 int oldAttsSize = parser->m_attsSize;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003097 ATTRIBUTE *temp;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003098#ifdef XML_ATTR_INFO
3099 XML_AttrInfo *temp2;
3100#endif
Elliott Hughes72472942018-01-10 08:36:10 -08003101 parser->m_attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
Haibo Huang40a71912019-10-11 11:13:39 -07003102 temp = (ATTRIBUTE *)REALLOC(parser, (void *)parser->m_atts,
3103 parser->m_attsSize * sizeof(ATTRIBUTE));
Elliott Hughes72472942018-01-10 08:36:10 -08003104 if (temp == NULL) {
3105 parser->m_attsSize = oldAttsSize;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003106 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08003107 }
3108 parser->m_atts = temp;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003109#ifdef XML_ATTR_INFO
Haibo Huang40a71912019-10-11 11:13:39 -07003110 temp2 = (XML_AttrInfo *)REALLOC(parser, (void *)parser->m_attInfo,
3111 parser->m_attsSize * sizeof(XML_AttrInfo));
Elliott Hughes72472942018-01-10 08:36:10 -08003112 if (temp2 == NULL) {
3113 parser->m_attsSize = oldAttsSize;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003114 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08003115 }
3116 parser->m_attInfo = temp2;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003117#endif
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003118 if (n > oldAttsSize)
Elliott Hughes72472942018-01-10 08:36:10 -08003119 XmlGetAttributes(enc, attStr, n, parser->m_atts);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003120 }
3121
Elliott Hughes72472942018-01-10 08:36:10 -08003122 appAtts = (const XML_Char **)parser->m_atts;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003123 for (i = 0; i < n; i++) {
Elliott Hughes72472942018-01-10 08:36:10 -08003124 ATTRIBUTE *currAtt = &parser->m_atts[i];
Elliott Hughes35e432d2012-09-09 14:23:38 -07003125#ifdef XML_ATTR_INFO
Elliott Hughes72472942018-01-10 08:36:10 -08003126 XML_AttrInfo *currAttInfo = &parser->m_attInfo[i];
Elliott Hughes35e432d2012-09-09 14:23:38 -07003127#endif
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003128 /* add the name and value to the attribute list */
Haibo Huang40a71912019-10-11 11:13:39 -07003129 ATTRIBUTE_ID *attId
3130 = getAttributeId(parser, enc, currAtt->name,
3131 currAtt->name + XmlNameLength(enc, currAtt->name));
3132 if (! attId)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003133 return XML_ERROR_NO_MEMORY;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003134#ifdef XML_ATTR_INFO
Haibo Huang40a71912019-10-11 11:13:39 -07003135 currAttInfo->nameStart
3136 = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->name);
3137 currAttInfo->nameEnd
3138 = currAttInfo->nameStart + XmlNameLength(enc, currAtt->name);
3139 currAttInfo->valueStart = parser->m_parseEndByteIndex
3140 - (parser->m_parseEndPtr - currAtt->valuePtr);
3141 currAttInfo->valueEnd = parser->m_parseEndByteIndex
3142 - (parser->m_parseEndPtr - currAtt->valueEnd);
Elliott Hughes35e432d2012-09-09 14:23:38 -07003143#endif
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003144 /* Detect duplicate attributes by their QNames. This does not work when
3145 namespace processing is turned on and different prefixes for the same
3146 namespace are used. For this case we have a check further down.
3147 */
3148 if ((attId->name)[-1]) {
Elliott Hughes72472942018-01-10 08:36:10 -08003149 if (enc == parser->m_encoding)
3150 parser->m_eventPtr = parser->m_atts[i].name;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003151 return XML_ERROR_DUPLICATE_ATTRIBUTE;
3152 }
3153 (attId->name)[-1] = 1;
3154 appAtts[attIndex++] = attId->name;
Haibo Huang40a71912019-10-11 11:13:39 -07003155 if (! parser->m_atts[i].normalized) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003156 enum XML_Error result;
3157 XML_Bool isCdata = XML_TRUE;
3158
3159 /* figure out whether declared as other than CDATA */
3160 if (attId->maybeTokenized) {
3161 int j;
3162 for (j = 0; j < nDefaultAtts; j++) {
3163 if (attId == elementType->defaultAtts[j].id) {
3164 isCdata = elementType->defaultAtts[j].isCdata;
3165 break;
3166 }
3167 }
3168 }
3169
3170 /* normalize the attribute value */
Haibo Huang40a71912019-10-11 11:13:39 -07003171 result = storeAttributeValue(
3172 parser, enc, isCdata, parser->m_atts[i].valuePtr,
3173 parser->m_atts[i].valueEnd, &parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003174 if (result)
3175 return result;
Elliott Hughes72472942018-01-10 08:36:10 -08003176 appAtts[attIndex] = poolStart(&parser->m_tempPool);
3177 poolFinish(&parser->m_tempPool);
Haibo Huang40a71912019-10-11 11:13:39 -07003178 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003179 /* the value did not need normalizing */
Haibo Huang40a71912019-10-11 11:13:39 -07003180 appAtts[attIndex] = poolStoreString(&parser->m_tempPool, enc,
3181 parser->m_atts[i].valuePtr,
Elliott Hughes72472942018-01-10 08:36:10 -08003182 parser->m_atts[i].valueEnd);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003183 if (appAtts[attIndex] == 0)
3184 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08003185 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003186 }
3187 /* handle prefixed attribute names */
3188 if (attId->prefix) {
3189 if (attId->xmlns) {
3190 /* deal with namespace declarations here */
3191 enum XML_Error result = addBinding(parser, attId->prefix, attId,
3192 appAtts[attIndex], bindingsPtr);
3193 if (result)
3194 return result;
3195 --attIndex;
Haibo Huang40a71912019-10-11 11:13:39 -07003196 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003197 /* deal with other prefixed names later */
3198 attIndex++;
3199 nPrefixes++;
3200 (attId->name)[-1] = 2;
3201 }
Haibo Huang40a71912019-10-11 11:13:39 -07003202 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003203 attIndex++;
3204 }
3205
3206 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
Elliott Hughes72472942018-01-10 08:36:10 -08003207 parser->m_nSpecifiedAtts = attIndex;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003208 if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
3209 for (i = 0; i < attIndex; i += 2)
3210 if (appAtts[i] == elementType->idAtt->name) {
Elliott Hughes72472942018-01-10 08:36:10 -08003211 parser->m_idAttIndex = i;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003212 break;
3213 }
Haibo Huang40a71912019-10-11 11:13:39 -07003214 } else
Elliott Hughes72472942018-01-10 08:36:10 -08003215 parser->m_idAttIndex = -1;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003216
3217 /* do attribute defaulting */
3218 for (i = 0; i < nDefaultAtts; i++) {
3219 const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
Haibo Huang40a71912019-10-11 11:13:39 -07003220 if (! (da->id->name)[-1] && da->value) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003221 if (da->id->prefix) {
3222 if (da->id->xmlns) {
3223 enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
3224 da->value, bindingsPtr);
3225 if (result)
3226 return result;
Haibo Huang40a71912019-10-11 11:13:39 -07003227 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003228 (da->id->name)[-1] = 2;
3229 nPrefixes++;
3230 appAtts[attIndex++] = da->id->name;
3231 appAtts[attIndex++] = da->value;
3232 }
Haibo Huang40a71912019-10-11 11:13:39 -07003233 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003234 (da->id->name)[-1] = 1;
3235 appAtts[attIndex++] = da->id->name;
3236 appAtts[attIndex++] = da->value;
3237 }
3238 }
3239 }
3240 appAtts[attIndex] = 0;
3241
3242 /* expand prefixed attribute names, check for duplicates,
3243 and clear flags that say whether attributes were specified */
3244 i = 0;
3245 if (nPrefixes) {
Haibo Huang40a71912019-10-11 11:13:39 -07003246 int j; /* hash table index */
Elliott Hughes72472942018-01-10 08:36:10 -08003247 unsigned long version = parser->m_nsAttsVersion;
3248 int nsAttsSize = (int)1 << parser->m_nsAttsPower;
3249 unsigned char oldNsAttsPower = parser->m_nsAttsPower;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003250 /* size of hash table must be at least 2 * (# of prefixed attributes) */
Haibo Huang40a71912019-10-11 11:13:39 -07003251 if ((nPrefixes << 1)
3252 >> parser->m_nsAttsPower) { /* true for m_nsAttsPower = 0 */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003253 NS_ATT *temp;
3254 /* hash table size must also be a power of 2 and >= 8 */
Haibo Huang40a71912019-10-11 11:13:39 -07003255 while (nPrefixes >> parser->m_nsAttsPower++)
3256 ;
Elliott Hughes72472942018-01-10 08:36:10 -08003257 if (parser->m_nsAttsPower < 3)
3258 parser->m_nsAttsPower = 3;
3259 nsAttsSize = (int)1 << parser->m_nsAttsPower;
Haibo Huang40a71912019-10-11 11:13:39 -07003260 temp = (NS_ATT *)REALLOC(parser, parser->m_nsAtts,
3261 nsAttsSize * sizeof(NS_ATT));
3262 if (! temp) {
Elliott Hughes72472942018-01-10 08:36:10 -08003263 /* Restore actual size of memory in m_nsAtts */
3264 parser->m_nsAttsPower = oldNsAttsPower;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003265 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08003266 }
3267 parser->m_nsAtts = temp;
Haibo Huang40a71912019-10-11 11:13:39 -07003268 version = 0; /* force re-initialization of m_nsAtts hash table */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003269 }
Elliott Hughes72472942018-01-10 08:36:10 -08003270 /* using a version flag saves us from initializing m_nsAtts every time */
Haibo Huang40a71912019-10-11 11:13:39 -07003271 if (! version) { /* initialize version flags when version wraps around */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003272 version = INIT_ATTS_VERSION;
Haibo Huang40a71912019-10-11 11:13:39 -07003273 for (j = nsAttsSize; j != 0;)
Elliott Hughes72472942018-01-10 08:36:10 -08003274 parser->m_nsAtts[--j].version = version;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003275 }
Elliott Hughes72472942018-01-10 08:36:10 -08003276 parser->m_nsAttsVersion = --version;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003277
3278 /* expand prefixed names and check for duplicates */
3279 for (; i < attIndex; i += 2) {
3280 const XML_Char *s = appAtts[i];
Haibo Huang40a71912019-10-11 11:13:39 -07003281 if (s[-1] == 2) { /* prefixed */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003282 ATTRIBUTE_ID *id;
3283 const BINDING *b;
Elliott Hughes72472942018-01-10 08:36:10 -08003284 unsigned long uriHash;
3285 struct siphash sip_state;
3286 struct sipkey sip_key;
3287
3288 copy_salt_to_sipkey(parser, &sip_key);
3289 sip24_init(&sip_state, &sip_key);
3290
Haibo Huang40a71912019-10-11 11:13:39 -07003291 ((XML_Char *)s)[-1] = 0; /* clear flag */
Elliott Hughes35e432d2012-09-09 14:23:38 -07003292 id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);
Haibo Huang40a71912019-10-11 11:13:39 -07003293 if (! id || ! id->prefix) {
Elliott Hughes72472942018-01-10 08:36:10 -08003294 /* This code is walking through the appAtts array, dealing
3295 * with (in this case) a prefixed attribute name. To be in
3296 * the array, the attribute must have already been bound, so
3297 * has to have passed through the hash table lookup once
3298 * already. That implies that an entry for it already
3299 * exists, so the lookup above will return a pointer to
3300 * already allocated memory. There is no opportunaity for
3301 * the allocator to fail, so the condition above cannot be
3302 * fulfilled.
3303 *
3304 * Since it is difficult to be certain that the above
3305 * analysis is complete, we retain the test and merely
3306 * remove the code from coverage tests.
3307 */
3308 return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */
3309 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003310 b = id->prefix->binding;
Haibo Huang40a71912019-10-11 11:13:39 -07003311 if (! b)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003312 return XML_ERROR_UNBOUND_PREFIX;
3313
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003314 for (j = 0; j < b->uriLen; j++) {
3315 const XML_Char c = b->uri[j];
Haibo Huang40a71912019-10-11 11:13:39 -07003316 if (! poolAppendChar(&parser->m_tempPool, c))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003317 return XML_ERROR_NO_MEMORY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003318 }
Elliott Hughes72472942018-01-10 08:36:10 -08003319
3320 sip24_update(&sip_state, b->uri, b->uriLen * sizeof(XML_Char));
3321
Elliott Hughesd07d5a72009-09-25 16:04:37 -07003322 while (*s++ != XML_T(ASCII_COLON))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003323 ;
Elliott Hughes72472942018-01-10 08:36:10 -08003324
3325 sip24_update(&sip_state, s, keylen(s) * sizeof(XML_Char));
3326
Haibo Huang40a71912019-10-11 11:13:39 -07003327 do { /* copies null terminator */
3328 if (! poolAppendChar(&parser->m_tempPool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003329 return XML_ERROR_NO_MEMORY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003330 } while (*s++);
3331
Elliott Hughes72472942018-01-10 08:36:10 -08003332 uriHash = (unsigned long)sip24_final(&sip_state);
3333
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003334 { /* Check hash table for duplicate of expanded name (uriName).
Elliott Hughes35e432d2012-09-09 14:23:38 -07003335 Derived from code in lookup(parser, HASH_TABLE *table, ...).
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003336 */
3337 unsigned char step = 0;
3338 unsigned long mask = nsAttsSize - 1;
Haibo Huang40a71912019-10-11 11:13:39 -07003339 j = uriHash & mask; /* index into hash table */
Elliott Hughes72472942018-01-10 08:36:10 -08003340 while (parser->m_nsAtts[j].version == version) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003341 /* for speed we compare stored hash values first */
Elliott Hughes72472942018-01-10 08:36:10 -08003342 if (uriHash == parser->m_nsAtts[j].hash) {
3343 const XML_Char *s1 = poolStart(&parser->m_tempPool);
3344 const XML_Char *s2 = parser->m_nsAtts[j].uriName;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003345 /* s1 is null terminated, but not s2 */
Haibo Huang40a71912019-10-11 11:13:39 -07003346 for (; *s1 == *s2 && *s1 != 0; s1++, s2++)
3347 ;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003348 if (*s1 == 0)
3349 return XML_ERROR_DUPLICATE_ATTRIBUTE;
3350 }
Haibo Huang40a71912019-10-11 11:13:39 -07003351 if (! step)
Elliott Hughes72472942018-01-10 08:36:10 -08003352 step = PROBE_STEP(uriHash, mask, parser->m_nsAttsPower);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003353 j < step ? (j += nsAttsSize - step) : (j -= step);
3354 }
3355 }
3356
Haibo Huang40a71912019-10-11 11:13:39 -07003357 if (parser->m_ns_triplets) { /* append namespace separator and prefix */
Elliott Hughes72472942018-01-10 08:36:10 -08003358 parser->m_tempPool.ptr[-1] = parser->m_namespaceSeparator;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003359 s = b->prefix->name;
3360 do {
Haibo Huang40a71912019-10-11 11:13:39 -07003361 if (! poolAppendChar(&parser->m_tempPool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003362 return XML_ERROR_NO_MEMORY;
3363 } while (*s++);
3364 }
3365
3366 /* store expanded name in attribute list */
Elliott Hughes72472942018-01-10 08:36:10 -08003367 s = poolStart(&parser->m_tempPool);
3368 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003369 appAtts[i] = s;
3370
3371 /* fill empty slot with new version, uriName and hash value */
Elliott Hughes72472942018-01-10 08:36:10 -08003372 parser->m_nsAtts[j].version = version;
3373 parser->m_nsAtts[j].hash = uriHash;
3374 parser->m_nsAtts[j].uriName = s;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003375
Haibo Huang40a71912019-10-11 11:13:39 -07003376 if (! --nPrefixes) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003377 i += 2;
3378 break;
3379 }
Haibo Huang40a71912019-10-11 11:13:39 -07003380 } else /* not prefixed */
3381 ((XML_Char *)s)[-1] = 0; /* clear flag */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003382 }
3383 }
3384 /* clear flags for the remaining attributes */
3385 for (; i < attIndex; i += 2)
3386 ((XML_Char *)(appAtts[i]))[-1] = 0;
3387 for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
3388 binding->attId->name[-1] = 0;
3389
Haibo Huang40a71912019-10-11 11:13:39 -07003390 if (! parser->m_ns)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003391 return XML_ERROR_NONE;
3392
3393 /* expand the element type name */
3394 if (elementType->prefix) {
3395 binding = elementType->prefix->binding;
Haibo Huang40a71912019-10-11 11:13:39 -07003396 if (! binding)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003397 return XML_ERROR_UNBOUND_PREFIX;
3398 localPart = tagNamePtr->str;
Elliott Hughesd07d5a72009-09-25 16:04:37 -07003399 while (*localPart++ != XML_T(ASCII_COLON))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003400 ;
Haibo Huang40a71912019-10-11 11:13:39 -07003401 } else if (dtd->defaultPrefix.binding) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003402 binding = dtd->defaultPrefix.binding;
3403 localPart = tagNamePtr->str;
Haibo Huang40a71912019-10-11 11:13:39 -07003404 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003405 return XML_ERROR_NONE;
3406 prefixLen = 0;
Elliott Hughes72472942018-01-10 08:36:10 -08003407 if (parser->m_ns_triplets && binding->prefix->name) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003408 for (; binding->prefix->name[prefixLen++];)
Haibo Huang40a71912019-10-11 11:13:39 -07003409 ; /* prefixLen includes null terminator */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003410 }
3411 tagNamePtr->localPart = localPart;
3412 tagNamePtr->uriLen = binding->uriLen;
3413 tagNamePtr->prefix = binding->prefix->name;
3414 tagNamePtr->prefixLen = prefixLen;
3415 for (i = 0; localPart[i++];)
Haibo Huang40a71912019-10-11 11:13:39 -07003416 ; /* i includes null terminator */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003417 n = i + binding->uriLen + prefixLen;
3418 if (n > binding->uriAlloc) {
3419 TAG *p;
Elliott Hughes72472942018-01-10 08:36:10 -08003420 uri = (XML_Char *)MALLOC(parser, (n + EXPAND_SPARE) * sizeof(XML_Char));
Haibo Huang40a71912019-10-11 11:13:39 -07003421 if (! uri)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003422 return XML_ERROR_NO_MEMORY;
3423 binding->uriAlloc = n + EXPAND_SPARE;
3424 memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
Elliott Hughes72472942018-01-10 08:36:10 -08003425 for (p = parser->m_tagStack; p; p = p->parent)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003426 if (p->name.str == binding->uri)
3427 p->name.str = uri;
Elliott Hughes72472942018-01-10 08:36:10 -08003428 FREE(parser, binding->uri);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003429 binding->uri = uri;
3430 }
Elliott Hughes72472942018-01-10 08:36:10 -08003431 /* if m_namespaceSeparator != '\0' then uri includes it already */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003432 uri = binding->uri + binding->uriLen;
3433 memcpy(uri, localPart, i * sizeof(XML_Char));
3434 /* we always have a namespace separator between localPart and prefix */
3435 if (prefixLen) {
3436 uri += i - 1;
Haibo Huang40a71912019-10-11 11:13:39 -07003437 *uri = parser->m_namespaceSeparator; /* replace null terminator */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003438 memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
3439 }
3440 tagNamePtr->str = binding->uri;
3441 return XML_ERROR_NONE;
3442}
3443
3444/* addBinding() overwrites the value of prefix->binding without checking.
3445 Therefore one must keep track of the old value outside of addBinding().
3446*/
3447static enum XML_Error
3448addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
Haibo Huang40a71912019-10-11 11:13:39 -07003449 const XML_Char *uri, BINDING **bindingsPtr) {
3450 static const XML_Char xmlNamespace[]
3451 = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON,
3452 ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w,
3453 ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o,
3454 ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M,
3455 ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9,
3456 ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m,
3457 ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c,
3458 ASCII_e, '\0'};
3459 static const int xmlLen = (int)sizeof(xmlNamespace) / sizeof(XML_Char) - 1;
3460 static const XML_Char xmlnsNamespace[]
3461 = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH,
3462 ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w,
3463 ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH,
3464 ASCII_2, ASCII_0, ASCII_0, ASCII_0, ASCII_SLASH, ASCII_x,
3465 ASCII_m, ASCII_l, ASCII_n, ASCII_s, ASCII_SLASH, '\0'};
3466 static const int xmlnsLen
3467 = (int)sizeof(xmlnsNamespace) / sizeof(XML_Char) - 1;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003468
3469 XML_Bool mustBeXML = XML_FALSE;
3470 XML_Bool isXML = XML_TRUE;
3471 XML_Bool isXMLNS = XML_TRUE;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003472
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003473 BINDING *b;
3474 int len;
3475
3476 /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
3477 if (*uri == XML_T('\0') && prefix->name)
3478 return XML_ERROR_UNDECLARING_PREFIX;
3479
Haibo Huang40a71912019-10-11 11:13:39 -07003480 if (prefix->name && prefix->name[0] == XML_T(ASCII_x)
Elliott Hughesd07d5a72009-09-25 16:04:37 -07003481 && prefix->name[1] == XML_T(ASCII_m)
3482 && prefix->name[2] == XML_T(ASCII_l)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003483 /* Not allowed to bind xmlns */
Haibo Huang40a71912019-10-11 11:13:39 -07003484 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 -08003485 && prefix->name[5] == XML_T('\0'))
3486 return XML_ERROR_RESERVED_PREFIX_XMLNS;
3487
3488 if (prefix->name[3] == XML_T('\0'))
3489 mustBeXML = XML_TRUE;
3490 }
3491
3492 for (len = 0; uri[len]; len++) {
3493 if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
3494 isXML = XML_FALSE;
3495
Haibo Huang40a71912019-10-11 11:13:39 -07003496 if (! mustBeXML && isXMLNS
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003497 && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
3498 isXMLNS = XML_FALSE;
3499 }
3500 isXML = isXML && len == xmlLen;
3501 isXMLNS = isXMLNS && len == xmlnsLen;
3502
3503 if (mustBeXML != isXML)
3504 return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
3505 : XML_ERROR_RESERVED_NAMESPACE_URI;
3506
3507 if (isXMLNS)
3508 return XML_ERROR_RESERVED_NAMESPACE_URI;
3509
Elliott Hughes72472942018-01-10 08:36:10 -08003510 if (parser->m_namespaceSeparator)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003511 len++;
Elliott Hughes72472942018-01-10 08:36:10 -08003512 if (parser->m_freeBindingList) {
3513 b = parser->m_freeBindingList;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003514 if (len > b->uriAlloc) {
Haibo Huang40a71912019-10-11 11:13:39 -07003515 XML_Char *temp = (XML_Char *)REALLOC(
3516 parser, b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003517 if (temp == NULL)
3518 return XML_ERROR_NO_MEMORY;
3519 b->uri = temp;
3520 b->uriAlloc = len + EXPAND_SPARE;
3521 }
Elliott Hughes72472942018-01-10 08:36:10 -08003522 parser->m_freeBindingList = b->nextTagBinding;
Haibo Huang40a71912019-10-11 11:13:39 -07003523 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08003524 b = (BINDING *)MALLOC(parser, sizeof(BINDING));
Haibo Huang40a71912019-10-11 11:13:39 -07003525 if (! b)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003526 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07003527 b->uri
3528 = (XML_Char *)MALLOC(parser, sizeof(XML_Char) * (len + EXPAND_SPARE));
3529 if (! b->uri) {
Elliott Hughes72472942018-01-10 08:36:10 -08003530 FREE(parser, b);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003531 return XML_ERROR_NO_MEMORY;
3532 }
3533 b->uriAlloc = len + EXPAND_SPARE;
3534 }
3535 b->uriLen = len;
3536 memcpy(b->uri, uri, len * sizeof(XML_Char));
Elliott Hughes72472942018-01-10 08:36:10 -08003537 if (parser->m_namespaceSeparator)
3538 b->uri[len - 1] = parser->m_namespaceSeparator;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003539 b->prefix = prefix;
3540 b->attId = attId;
3541 b->prevPrefixBinding = prefix->binding;
3542 /* NULL binding when default namespace undeclared */
Elliott Hughes72472942018-01-10 08:36:10 -08003543 if (*uri == XML_T('\0') && prefix == &parser->m_dtd->defaultPrefix)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003544 prefix->binding = NULL;
3545 else
3546 prefix->binding = b;
3547 b->nextTagBinding = *bindingsPtr;
3548 *bindingsPtr = b;
3549 /* if attId == NULL then we are not starting a namespace scope */
Elliott Hughes72472942018-01-10 08:36:10 -08003550 if (attId && parser->m_startNamespaceDeclHandler)
3551 parser->m_startNamespaceDeclHandler(parser->m_handlerArg, prefix->name,
Haibo Huang40a71912019-10-11 11:13:39 -07003552 prefix->binding ? uri : 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003553 return XML_ERROR_NONE;
3554}
3555
3556/* The idea here is to avoid using stack for each CDATA section when
3557 the whole file is parsed with one call.
3558*/
3559static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07003560cdataSectionProcessor(XML_Parser parser, const char *start, const char *end,
3561 const char **endPtr) {
3562 enum XML_Error result
3563 = doCdataSection(parser, parser->m_encoding, &start, end, endPtr,
3564 (XML_Bool)! parser->m_parsingStatus.finalBuffer);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003565 if (result != XML_ERROR_NONE)
3566 return result;
3567 if (start) {
Haibo Huang40a71912019-10-11 11:13:39 -07003568 if (parser->m_parentParser) { /* we are parsing an external entity */
Elliott Hughes72472942018-01-10 08:36:10 -08003569 parser->m_processor = externalEntityContentProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003570 return externalEntityContentProcessor(parser, start, end, endPtr);
Haibo Huang40a71912019-10-11 11:13:39 -07003571 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08003572 parser->m_processor = contentProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003573 return contentProcessor(parser, start, end, endPtr);
3574 }
3575 }
3576 return result;
3577}
3578
3579/* startPtr gets set to non-null if the section is closed, and to null if
3580 the section is not yet closed.
3581*/
3582static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07003583doCdataSection(XML_Parser parser, const ENCODING *enc, const char **startPtr,
3584 const char *end, const char **nextPtr, XML_Bool haveMore) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003585 const char *s = *startPtr;
3586 const char **eventPP;
3587 const char **eventEndPP;
Elliott Hughes72472942018-01-10 08:36:10 -08003588 if (enc == parser->m_encoding) {
3589 eventPP = &parser->m_eventPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003590 *eventPP = s;
Elliott Hughes72472942018-01-10 08:36:10 -08003591 eventEndPP = &parser->m_eventEndPtr;
Haibo Huang40a71912019-10-11 11:13:39 -07003592 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08003593 eventPP = &(parser->m_openInternalEntities->internalEventPtr);
3594 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003595 }
3596 *eventPP = s;
3597 *startPtr = NULL;
3598
3599 for (;;) {
Haibo Huangd1a324a2020-10-28 22:19:36 -07003600 const char *next = s; /* in case of XML_TOK_NONE or XML_TOK_PARTIAL */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003601 int tok = XmlCdataSectionTok(enc, s, end, &next);
3602 *eventEndPP = next;
3603 switch (tok) {
3604 case XML_TOK_CDATA_SECT_CLOSE:
Elliott Hughes72472942018-01-10 08:36:10 -08003605 if (parser->m_endCdataSectionHandler)
3606 parser->m_endCdataSectionHandler(parser->m_handlerArg);
Haibo Huang40a71912019-10-11 11:13:39 -07003607 /* BEGIN disabled code */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003608 /* see comment under XML_TOK_CDATA_SECT_OPEN */
Haibo Huangfd5e81a2019-06-20 12:09:36 -07003609 else if (0 && parser->m_characterDataHandler)
Haibo Huang40a71912019-10-11 11:13:39 -07003610 parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf,
3611 0);
3612 /* END disabled code */
Elliott Hughes72472942018-01-10 08:36:10 -08003613 else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003614 reportDefault(parser, enc, s, next);
3615 *startPtr = next;
3616 *nextPtr = next;
Elliott Hughes72472942018-01-10 08:36:10 -08003617 if (parser->m_parsingStatus.parsing == XML_FINISHED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003618 return XML_ERROR_ABORTED;
3619 else
3620 return XML_ERROR_NONE;
3621 case XML_TOK_DATA_NEWLINE:
Elliott Hughes72472942018-01-10 08:36:10 -08003622 if (parser->m_characterDataHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003623 XML_Char c = 0xA;
Elliott Hughes72472942018-01-10 08:36:10 -08003624 parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
Haibo Huang40a71912019-10-11 11:13:39 -07003625 } else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003626 reportDefault(parser, enc, s, next);
3627 break;
Haibo Huang40a71912019-10-11 11:13:39 -07003628 case XML_TOK_DATA_CHARS: {
3629 XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler;
3630 if (charDataHandler) {
3631 if (MUST_CONVERT(enc, s)) {
3632 for (;;) {
3633 ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
3634 const enum XML_Convert_Result convert_res = XmlConvert(
3635 enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
3636 *eventEndPP = next;
3637 charDataHandler(parser->m_handlerArg, parser->m_dataBuf,
3638 (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
3639 if ((convert_res == XML_CONVERT_COMPLETED)
3640 || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
3641 break;
3642 *eventPP = s;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003643 }
Haibo Huang40a71912019-10-11 11:13:39 -07003644 } else
3645 charDataHandler(parser->m_handlerArg, (XML_Char *)s,
3646 (int)((XML_Char *)next - (XML_Char *)s));
3647 } else if (parser->m_defaultHandler)
3648 reportDefault(parser, enc, s, next);
3649 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003650 case XML_TOK_INVALID:
3651 *eventPP = next;
3652 return XML_ERROR_INVALID_TOKEN;
3653 case XML_TOK_PARTIAL_CHAR:
3654 if (haveMore) {
3655 *nextPtr = s;
3656 return XML_ERROR_NONE;
3657 }
3658 return XML_ERROR_PARTIAL_CHAR;
3659 case XML_TOK_PARTIAL:
3660 case XML_TOK_NONE:
3661 if (haveMore) {
3662 *nextPtr = s;
3663 return XML_ERROR_NONE;
3664 }
3665 return XML_ERROR_UNCLOSED_CDATA_SECTION;
3666 default:
Elliott Hughes72472942018-01-10 08:36:10 -08003667 /* Every token returned by XmlCdataSectionTok() has its own
3668 * explicit case, so this default case will never be executed.
3669 * We retain it as a safety net and exclude it from the coverage
3670 * statistics.
3671 *
3672 * LCOV_EXCL_START
Haibo Huang40a71912019-10-11 11:13:39 -07003673 */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003674 *eventPP = next;
3675 return XML_ERROR_UNEXPECTED_STATE;
Elliott Hughes72472942018-01-10 08:36:10 -08003676 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003677 }
3678
3679 *eventPP = s = next;
Elliott Hughes72472942018-01-10 08:36:10 -08003680 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003681 case XML_SUSPENDED:
3682 *nextPtr = next;
3683 return XML_ERROR_NONE;
3684 case XML_FINISHED:
3685 return XML_ERROR_ABORTED;
Haibo Huang40a71912019-10-11 11:13:39 -07003686 default:;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003687 }
3688 }
3689 /* not reached */
3690}
3691
3692#ifdef XML_DTD
3693
3694/* The idea here is to avoid using stack for each IGNORE section when
3695 the whole file is parsed with one call.
3696*/
3697static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07003698ignoreSectionProcessor(XML_Parser parser, const char *start, const char *end,
3699 const char **endPtr) {
3700 enum XML_Error result
3701 = doIgnoreSection(parser, parser->m_encoding, &start, end, endPtr,
3702 (XML_Bool)! parser->m_parsingStatus.finalBuffer);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003703 if (result != XML_ERROR_NONE)
3704 return result;
3705 if (start) {
Elliott Hughes72472942018-01-10 08:36:10 -08003706 parser->m_processor = prologProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003707 return prologProcessor(parser, start, end, endPtr);
3708 }
3709 return result;
3710}
3711
3712/* startPtr gets set to non-null is the section is closed, and to null
3713 if the section is not yet closed.
3714*/
3715static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07003716doIgnoreSection(XML_Parser parser, const ENCODING *enc, const char **startPtr,
3717 const char *end, const char **nextPtr, XML_Bool haveMore) {
Haibo Huangd1a324a2020-10-28 22:19:36 -07003718 const char *next = *startPtr; /* in case of XML_TOK_NONE or XML_TOK_PARTIAL */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003719 int tok;
3720 const char *s = *startPtr;
3721 const char **eventPP;
3722 const char **eventEndPP;
Elliott Hughes72472942018-01-10 08:36:10 -08003723 if (enc == parser->m_encoding) {
3724 eventPP = &parser->m_eventPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003725 *eventPP = s;
Elliott Hughes72472942018-01-10 08:36:10 -08003726 eventEndPP = &parser->m_eventEndPtr;
Haibo Huang40a71912019-10-11 11:13:39 -07003727 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08003728 /* It's not entirely clear, but it seems the following two lines
3729 * of code cannot be executed. The only occasions on which 'enc'
3730 * is not 'encoding' are when this function is called
3731 * from the internal entity processing, and IGNORE sections are an
3732 * error in internal entities.
3733 *
3734 * Since it really isn't clear that this is true, we keep the code
3735 * and just remove it from our coverage tests.
3736 *
3737 * LCOV_EXCL_START
3738 */
3739 eventPP = &(parser->m_openInternalEntities->internalEventPtr);
3740 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
3741 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003742 }
3743 *eventPP = s;
3744 *startPtr = NULL;
3745 tok = XmlIgnoreSectionTok(enc, s, end, &next);
3746 *eventEndPP = next;
3747 switch (tok) {
3748 case XML_TOK_IGNORE_SECT:
Elliott Hughes72472942018-01-10 08:36:10 -08003749 if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003750 reportDefault(parser, enc, s, next);
3751 *startPtr = next;
3752 *nextPtr = next;
Elliott Hughes72472942018-01-10 08:36:10 -08003753 if (parser->m_parsingStatus.parsing == XML_FINISHED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003754 return XML_ERROR_ABORTED;
3755 else
3756 return XML_ERROR_NONE;
3757 case XML_TOK_INVALID:
3758 *eventPP = next;
3759 return XML_ERROR_INVALID_TOKEN;
3760 case XML_TOK_PARTIAL_CHAR:
3761 if (haveMore) {
3762 *nextPtr = s;
3763 return XML_ERROR_NONE;
3764 }
3765 return XML_ERROR_PARTIAL_CHAR;
3766 case XML_TOK_PARTIAL:
3767 case XML_TOK_NONE:
3768 if (haveMore) {
3769 *nextPtr = s;
3770 return XML_ERROR_NONE;
3771 }
3772 return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
3773 default:
Elliott Hughes72472942018-01-10 08:36:10 -08003774 /* All of the tokens that XmlIgnoreSectionTok() returns have
3775 * explicit cases to handle them, so this default case is never
3776 * executed. We keep it as a safety net anyway, and remove it
3777 * from our test coverage statistics.
3778 *
3779 * LCOV_EXCL_START
3780 */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003781 *eventPP = next;
3782 return XML_ERROR_UNEXPECTED_STATE;
Elliott Hughes72472942018-01-10 08:36:10 -08003783 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003784 }
3785 /* not reached */
3786}
3787
3788#endif /* XML_DTD */
3789
3790static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07003791initializeEncoding(XML_Parser parser) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003792 const char *s;
3793#ifdef XML_UNICODE
3794 char encodingBuf[128];
Elliott Hughes72472942018-01-10 08:36:10 -08003795 /* See comments abount `protoclEncodingName` in parserInit() */
Haibo Huang40a71912019-10-11 11:13:39 -07003796 if (! parser->m_protocolEncodingName)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003797 s = NULL;
3798 else {
3799 int i;
Elliott Hughes72472942018-01-10 08:36:10 -08003800 for (i = 0; parser->m_protocolEncodingName[i]; i++) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003801 if (i == sizeof(encodingBuf) - 1
Elliott Hughes72472942018-01-10 08:36:10 -08003802 || (parser->m_protocolEncodingName[i] & ~0x7f) != 0) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003803 encodingBuf[0] = '\0';
3804 break;
3805 }
Elliott Hughes72472942018-01-10 08:36:10 -08003806 encodingBuf[i] = (char)parser->m_protocolEncodingName[i];
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003807 }
3808 encodingBuf[i] = '\0';
3809 s = encodingBuf;
3810 }
3811#else
Elliott Hughes72472942018-01-10 08:36:10 -08003812 s = parser->m_protocolEncodingName;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003813#endif
Haibo Huang40a71912019-10-11 11:13:39 -07003814 if ((parser->m_ns ? XmlInitEncodingNS : XmlInitEncoding)(
3815 &parser->m_initEncoding, &parser->m_encoding, s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003816 return XML_ERROR_NONE;
Elliott Hughes72472942018-01-10 08:36:10 -08003817 return handleUnknownEncoding(parser, parser->m_protocolEncodingName);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003818}
3819
3820static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07003821processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *s,
3822 const char *next) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003823 const char *encodingName = NULL;
3824 const XML_Char *storedEncName = NULL;
3825 const ENCODING *newEncoding = NULL;
3826 const char *version = NULL;
3827 const char *versionend;
3828 const XML_Char *storedversion = NULL;
3829 int standalone = -1;
Haibo Huang40a71912019-10-11 11:13:39 -07003830 if (! (parser->m_ns ? XmlParseXmlDeclNS : XmlParseXmlDecl)(
3831 isGeneralTextEntity, parser->m_encoding, s, next, &parser->m_eventPtr,
3832 &version, &versionend, &encodingName, &newEncoding, &standalone)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003833 if (isGeneralTextEntity)
3834 return XML_ERROR_TEXT_DECL;
3835 else
3836 return XML_ERROR_XML_DECL;
3837 }
Haibo Huang40a71912019-10-11 11:13:39 -07003838 if (! isGeneralTextEntity && standalone == 1) {
Elliott Hughes72472942018-01-10 08:36:10 -08003839 parser->m_dtd->standalone = XML_TRUE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003840#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07003841 if (parser->m_paramEntityParsing
3842 == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
Elliott Hughes72472942018-01-10 08:36:10 -08003843 parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003844#endif /* XML_DTD */
3845 }
Elliott Hughes72472942018-01-10 08:36:10 -08003846 if (parser->m_xmlDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003847 if (encodingName != NULL) {
Haibo Huang40a71912019-10-11 11:13:39 -07003848 storedEncName = poolStoreString(
3849 &parser->m_temp2Pool, parser->m_encoding, encodingName,
3850 encodingName + XmlNameLength(parser->m_encoding, encodingName));
3851 if (! storedEncName)
3852 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08003853 poolFinish(&parser->m_temp2Pool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003854 }
3855 if (version) {
Haibo Huang40a71912019-10-11 11:13:39 -07003856 storedversion
3857 = poolStoreString(&parser->m_temp2Pool, parser->m_encoding, version,
3858 versionend - parser->m_encoding->minBytesPerChar);
3859 if (! storedversion)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003860 return XML_ERROR_NO_MEMORY;
3861 }
Haibo Huang40a71912019-10-11 11:13:39 -07003862 parser->m_xmlDeclHandler(parser->m_handlerArg, storedversion, storedEncName,
3863 standalone);
3864 } else if (parser->m_defaultHandler)
Elliott Hughes72472942018-01-10 08:36:10 -08003865 reportDefault(parser, parser->m_encoding, s, next);
3866 if (parser->m_protocolEncodingName == NULL) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003867 if (newEncoding) {
Elliott Hughes72472942018-01-10 08:36:10 -08003868 /* Check that the specified encoding does not conflict with what
3869 * the parser has already deduced. Do we have the same number
3870 * of bytes in the smallest representation of a character? If
3871 * this is UTF-16, is it the same endianness?
3872 */
3873 if (newEncoding->minBytesPerChar != parser->m_encoding->minBytesPerChar
Haibo Huang40a71912019-10-11 11:13:39 -07003874 || (newEncoding->minBytesPerChar == 2
3875 && newEncoding != parser->m_encoding)) {
Elliott Hughes72472942018-01-10 08:36:10 -08003876 parser->m_eventPtr = encodingName;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003877 return XML_ERROR_INCORRECT_ENCODING;
3878 }
Elliott Hughes72472942018-01-10 08:36:10 -08003879 parser->m_encoding = newEncoding;
Haibo Huang40a71912019-10-11 11:13:39 -07003880 } else if (encodingName) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003881 enum XML_Error result;
Haibo Huang40a71912019-10-11 11:13:39 -07003882 if (! storedEncName) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003883 storedEncName = poolStoreString(
Haibo Huang40a71912019-10-11 11:13:39 -07003884 &parser->m_temp2Pool, parser->m_encoding, encodingName,
3885 encodingName + XmlNameLength(parser->m_encoding, encodingName));
3886 if (! storedEncName)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003887 return XML_ERROR_NO_MEMORY;
3888 }
3889 result = handleUnknownEncoding(parser, storedEncName);
Elliott Hughes72472942018-01-10 08:36:10 -08003890 poolClear(&parser->m_temp2Pool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003891 if (result == XML_ERROR_UNKNOWN_ENCODING)
Elliott Hughes72472942018-01-10 08:36:10 -08003892 parser->m_eventPtr = encodingName;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003893 return result;
3894 }
3895 }
3896
3897 if (storedEncName || storedversion)
Elliott Hughes72472942018-01-10 08:36:10 -08003898 poolClear(&parser->m_temp2Pool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003899
3900 return XML_ERROR_NONE;
3901}
3902
3903static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07003904handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) {
Elliott Hughes72472942018-01-10 08:36:10 -08003905 if (parser->m_unknownEncodingHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003906 XML_Encoding info;
3907 int i;
3908 for (i = 0; i < 256; i++)
3909 info.map[i] = -1;
3910 info.convert = NULL;
3911 info.data = NULL;
3912 info.release = NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07003913 if (parser->m_unknownEncodingHandler(parser->m_unknownEncodingHandlerData,
3914 encodingName, &info)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003915 ENCODING *enc;
Elliott Hughes72472942018-01-10 08:36:10 -08003916 parser->m_unknownEncodingMem = MALLOC(parser, XmlSizeOfUnknownEncoding());
Haibo Huang40a71912019-10-11 11:13:39 -07003917 if (! parser->m_unknownEncodingMem) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003918 if (info.release)
3919 info.release(info.data);
3920 return XML_ERROR_NO_MEMORY;
3921 }
Haibo Huang40a71912019-10-11 11:13:39 -07003922 enc = (parser->m_ns ? XmlInitUnknownEncodingNS : XmlInitUnknownEncoding)(
3923 parser->m_unknownEncodingMem, info.map, info.convert, info.data);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003924 if (enc) {
Elliott Hughes72472942018-01-10 08:36:10 -08003925 parser->m_unknownEncodingData = info.data;
3926 parser->m_unknownEncodingRelease = info.release;
3927 parser->m_encoding = enc;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003928 return XML_ERROR_NONE;
3929 }
3930 }
3931 if (info.release != NULL)
3932 info.release(info.data);
3933 }
3934 return XML_ERROR_UNKNOWN_ENCODING;
3935}
3936
3937static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07003938prologInitProcessor(XML_Parser parser, const char *s, const char *end,
3939 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003940 enum XML_Error result = initializeEncoding(parser);
3941 if (result != XML_ERROR_NONE)
3942 return result;
Elliott Hughes72472942018-01-10 08:36:10 -08003943 parser->m_processor = prologProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003944 return prologProcessor(parser, s, end, nextPtr);
3945}
3946
3947#ifdef XML_DTD
3948
3949static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07003950externalParEntInitProcessor(XML_Parser parser, const char *s, const char *end,
3951 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003952 enum XML_Error result = initializeEncoding(parser);
3953 if (result != XML_ERROR_NONE)
3954 return result;
3955
3956 /* we know now that XML_Parse(Buffer) has been called,
3957 so we consider the external parameter entity read */
Elliott Hughes72472942018-01-10 08:36:10 -08003958 parser->m_dtd->paramEntityRead = XML_TRUE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003959
Elliott Hughes72472942018-01-10 08:36:10 -08003960 if (parser->m_prologState.inEntityValue) {
3961 parser->m_processor = entityValueInitProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003962 return entityValueInitProcessor(parser, s, end, nextPtr);
Haibo Huang40a71912019-10-11 11:13:39 -07003963 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08003964 parser->m_processor = externalParEntProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003965 return externalParEntProcessor(parser, s, end, nextPtr);
3966 }
3967}
3968
3969static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07003970entityValueInitProcessor(XML_Parser parser, const char *s, const char *end,
3971 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003972 int tok;
3973 const char *start = s;
3974 const char *next = start;
Elliott Hughes72472942018-01-10 08:36:10 -08003975 parser->m_eventPtr = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003976
Elliott Hughes35e432d2012-09-09 14:23:38 -07003977 for (;;) {
Elliott Hughes72472942018-01-10 08:36:10 -08003978 tok = XmlPrologTok(parser->m_encoding, start, end, &next);
3979 parser->m_eventEndPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003980 if (tok <= 0) {
Haibo Huang40a71912019-10-11 11:13:39 -07003981 if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003982 *nextPtr = s;
3983 return XML_ERROR_NONE;
3984 }
3985 switch (tok) {
3986 case XML_TOK_INVALID:
3987 return XML_ERROR_INVALID_TOKEN;
3988 case XML_TOK_PARTIAL:
3989 return XML_ERROR_UNCLOSED_TOKEN;
3990 case XML_TOK_PARTIAL_CHAR:
3991 return XML_ERROR_PARTIAL_CHAR;
Haibo Huang40a71912019-10-11 11:13:39 -07003992 case XML_TOK_NONE: /* start == end */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003993 default:
3994 break;
3995 }
3996 /* found end of entity value - can store it now */
Elliott Hughes72472942018-01-10 08:36:10 -08003997 return storeEntityValue(parser, parser->m_encoding, s, end);
Haibo Huang40a71912019-10-11 11:13:39 -07003998 } else if (tok == XML_TOK_XML_DECL) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003999 enum XML_Error result;
4000 result = processXmlDecl(parser, 0, start, next);
4001 if (result != XML_ERROR_NONE)
4002 return result;
Haibo Huang40a71912019-10-11 11:13:39 -07004003 /* At this point, m_parsingStatus.parsing cannot be XML_SUSPENDED. For
4004 * that to happen, a parameter entity parsing handler must have attempted
4005 * to suspend the parser, which fails and raises an error. The parser can
4006 * be aborted, but can't be suspended.
Elliott Hughes72472942018-01-10 08:36:10 -08004007 */
4008 if (parser->m_parsingStatus.parsing == XML_FINISHED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004009 return XML_ERROR_ABORTED;
Elliott Hughes72472942018-01-10 08:36:10 -08004010 *nextPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004011 /* stop scanning for text declaration - we found one */
Elliott Hughes72472942018-01-10 08:36:10 -08004012 parser->m_processor = entityValueProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004013 return entityValueProcessor(parser, next, end, nextPtr);
4014 }
4015 /* If we are at the end of the buffer, this would cause XmlPrologTok to
4016 return XML_TOK_NONE on the next call, which would then cause the
4017 function to exit with *nextPtr set to s - that is what we want for other
4018 tokens, but not for the BOM - we would rather like to skip it;
4019 then, when this routine is entered the next time, XmlPrologTok will
4020 return XML_TOK_INVALID, since the BOM is still in the buffer
4021 */
Haibo Huang40a71912019-10-11 11:13:39 -07004022 else if (tok == XML_TOK_BOM && next == end
4023 && ! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004024 *nextPtr = next;
4025 return XML_ERROR_NONE;
4026 }
Elliott Hughes72472942018-01-10 08:36:10 -08004027 /* If we get this token, we have the start of what might be a
4028 normal tag, but not a declaration (i.e. it doesn't begin with
4029 "<!"). In a DTD context, that isn't legal.
4030 */
4031 else if (tok == XML_TOK_INSTANCE_START) {
4032 *nextPtr = next;
4033 return XML_ERROR_SYNTAX;
4034 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004035 start = next;
Elliott Hughes72472942018-01-10 08:36:10 -08004036 parser->m_eventPtr = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004037 }
4038}
4039
4040static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07004041externalParEntProcessor(XML_Parser parser, const char *s, const char *end,
4042 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004043 const char *next = s;
4044 int tok;
4045
Elliott Hughes72472942018-01-10 08:36:10 -08004046 tok = XmlPrologTok(parser->m_encoding, s, end, &next);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004047 if (tok <= 0) {
Haibo Huang40a71912019-10-11 11:13:39 -07004048 if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004049 *nextPtr = s;
4050 return XML_ERROR_NONE;
4051 }
4052 switch (tok) {
4053 case XML_TOK_INVALID:
4054 return XML_ERROR_INVALID_TOKEN;
4055 case XML_TOK_PARTIAL:
4056 return XML_ERROR_UNCLOSED_TOKEN;
4057 case XML_TOK_PARTIAL_CHAR:
4058 return XML_ERROR_PARTIAL_CHAR;
Haibo Huang40a71912019-10-11 11:13:39 -07004059 case XML_TOK_NONE: /* start == end */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004060 default:
4061 break;
4062 }
4063 }
4064 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
4065 However, when parsing an external subset, doProlog will not accept a BOM
4066 as valid, and report a syntax error, so we have to skip the BOM
4067 */
4068 else if (tok == XML_TOK_BOM) {
4069 s = next;
Elliott Hughes72472942018-01-10 08:36:10 -08004070 tok = XmlPrologTok(parser->m_encoding, s, end, &next);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004071 }
4072
Elliott Hughes72472942018-01-10 08:36:10 -08004073 parser->m_processor = prologProcessor;
Haibo Huang40a71912019-10-11 11:13:39 -07004074 return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
4075 (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004076}
4077
4078static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07004079entityValueProcessor(XML_Parser parser, const char *s, const char *end,
4080 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004081 const char *start = s;
4082 const char *next = s;
Elliott Hughes72472942018-01-10 08:36:10 -08004083 const ENCODING *enc = parser->m_encoding;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004084 int tok;
4085
4086 for (;;) {
4087 tok = XmlPrologTok(enc, start, end, &next);
4088 if (tok <= 0) {
Haibo Huang40a71912019-10-11 11:13:39 -07004089 if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004090 *nextPtr = s;
4091 return XML_ERROR_NONE;
4092 }
4093 switch (tok) {
4094 case XML_TOK_INVALID:
4095 return XML_ERROR_INVALID_TOKEN;
4096 case XML_TOK_PARTIAL:
4097 return XML_ERROR_UNCLOSED_TOKEN;
4098 case XML_TOK_PARTIAL_CHAR:
4099 return XML_ERROR_PARTIAL_CHAR;
Haibo Huang40a71912019-10-11 11:13:39 -07004100 case XML_TOK_NONE: /* start == end */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004101 default:
4102 break;
4103 }
4104 /* found end of entity value - can store it now */
4105 return storeEntityValue(parser, enc, s, end);
4106 }
4107 start = next;
4108 }
4109}
4110
4111#endif /* XML_DTD */
4112
4113static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07004114prologProcessor(XML_Parser parser, const char *s, const char *end,
4115 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004116 const char *next = s;
Elliott Hughes72472942018-01-10 08:36:10 -08004117 int tok = XmlPrologTok(parser->m_encoding, s, end, &next);
Haibo Huang40a71912019-10-11 11:13:39 -07004118 return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
4119 (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004120}
4121
4122static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07004123doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
4124 int tok, const char *next, const char **nextPtr, XML_Bool haveMore,
4125 XML_Bool allowClosingDoctype) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004126#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07004127 static const XML_Char externalSubsetName[] = {ASCII_HASH, '\0'};
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004128#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07004129 static const XML_Char atypeCDATA[]
4130 = {ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'};
4131 static const XML_Char atypeID[] = {ASCII_I, ASCII_D, '\0'};
4132 static const XML_Char atypeIDREF[]
4133 = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0'};
4134 static const XML_Char atypeIDREFS[]
4135 = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0'};
4136 static const XML_Char atypeENTITY[]
4137 = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0'};
4138 static const XML_Char atypeENTITIES[]
4139 = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T,
4140 ASCII_I, ASCII_E, ASCII_S, '\0'};
4141 static const XML_Char atypeNMTOKEN[]
4142 = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0'};
4143 static const XML_Char atypeNMTOKENS[]
4144 = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K,
4145 ASCII_E, ASCII_N, ASCII_S, '\0'};
4146 static const XML_Char notationPrefix[]
4147 = {ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T,
4148 ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0'};
4149 static const XML_Char enumValueSep[] = {ASCII_PIPE, '\0'};
4150 static const XML_Char enumValueStart[] = {ASCII_LPAREN, '\0'};
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004151
4152 /* save one level of indirection */
Haibo Huang40a71912019-10-11 11:13:39 -07004153 DTD *const dtd = parser->m_dtd;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004154
4155 const char **eventPP;
4156 const char **eventEndPP;
4157 enum XML_Content_Quant quant;
4158
Elliott Hughes72472942018-01-10 08:36:10 -08004159 if (enc == parser->m_encoding) {
4160 eventPP = &parser->m_eventPtr;
4161 eventEndPP = &parser->m_eventEndPtr;
Haibo Huang40a71912019-10-11 11:13:39 -07004162 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08004163 eventPP = &(parser->m_openInternalEntities->internalEventPtr);
4164 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004165 }
4166
4167 for (;;) {
4168 int role;
4169 XML_Bool handleDefault = XML_TRUE;
4170 *eventPP = s;
4171 *eventEndPP = next;
4172 if (tok <= 0) {
4173 if (haveMore && tok != XML_TOK_INVALID) {
4174 *nextPtr = s;
4175 return XML_ERROR_NONE;
4176 }
4177 switch (tok) {
4178 case XML_TOK_INVALID:
4179 *eventPP = next;
4180 return XML_ERROR_INVALID_TOKEN;
4181 case XML_TOK_PARTIAL:
4182 return XML_ERROR_UNCLOSED_TOKEN;
4183 case XML_TOK_PARTIAL_CHAR:
4184 return XML_ERROR_PARTIAL_CHAR;
Elliott Hughes35e432d2012-09-09 14:23:38 -07004185 case -XML_TOK_PROLOG_S:
4186 tok = -tok;
4187 break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004188 case XML_TOK_NONE:
4189#ifdef XML_DTD
4190 /* for internal PE NOT referenced between declarations */
Haibo Huang40a71912019-10-11 11:13:39 -07004191 if (enc != parser->m_encoding
4192 && ! parser->m_openInternalEntities->betweenDecl) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004193 *nextPtr = s;
4194 return XML_ERROR_NONE;
4195 }
4196 /* WFC: PE Between Declarations - must check that PE contains
4197 complete markup, not only for external PEs, but also for
4198 internal PEs if the reference occurs between declarations.
4199 */
Elliott Hughes72472942018-01-10 08:36:10 -08004200 if (parser->m_isParamEntity || enc != parser->m_encoding) {
4201 if (XmlTokenRole(&parser->m_prologState, XML_TOK_NONE, end, end, enc)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004202 == XML_ROLE_ERROR)
4203 return XML_ERROR_INCOMPLETE_PE;
4204 *nextPtr = s;
4205 return XML_ERROR_NONE;
4206 }
4207#endif /* XML_DTD */
4208 return XML_ERROR_NO_ELEMENTS;
4209 default:
4210 tok = -tok;
4211 next = end;
4212 break;
4213 }
4214 }
Elliott Hughes72472942018-01-10 08:36:10 -08004215 role = XmlTokenRole(&parser->m_prologState, tok, s, next, enc);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004216 switch (role) {
Haibo Huang40a71912019-10-11 11:13:39 -07004217 case XML_ROLE_XML_DECL: {
4218 enum XML_Error result = processXmlDecl(parser, 0, s, next);
4219 if (result != XML_ERROR_NONE)
4220 return result;
4221 enc = parser->m_encoding;
4222 handleDefault = XML_FALSE;
4223 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004224 case XML_ROLE_DOCTYPE_NAME:
Elliott Hughes72472942018-01-10 08:36:10 -08004225 if (parser->m_startDoctypeDeclHandler) {
Haibo Huang40a71912019-10-11 11:13:39 -07004226 parser->m_doctypeName
4227 = poolStoreString(&parser->m_tempPool, enc, s, next);
4228 if (! parser->m_doctypeName)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004229 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004230 poolFinish(&parser->m_tempPool);
4231 parser->m_doctypePubid = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004232 handleDefault = XML_FALSE;
4233 }
Elliott Hughes72472942018-01-10 08:36:10 -08004234 parser->m_doctypeSysid = NULL; /* always initialize to NULL */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004235 break;
4236 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
Elliott Hughes72472942018-01-10 08:36:10 -08004237 if (parser->m_startDoctypeDeclHandler) {
Haibo Huang40a71912019-10-11 11:13:39 -07004238 parser->m_startDoctypeDeclHandler(
4239 parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid,
4240 parser->m_doctypePubid, 1);
Elliott Hughes72472942018-01-10 08:36:10 -08004241 parser->m_doctypeName = NULL;
4242 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004243 handleDefault = XML_FALSE;
4244 }
4245 break;
4246#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07004247 case XML_ROLE_TEXT_DECL: {
4248 enum XML_Error result = processXmlDecl(parser, 1, s, next);
4249 if (result != XML_ERROR_NONE)
4250 return result;
4251 enc = parser->m_encoding;
4252 handleDefault = XML_FALSE;
4253 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004254#endif /* XML_DTD */
4255 case XML_ROLE_DOCTYPE_PUBLIC_ID:
4256#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08004257 parser->m_useForeignDTD = XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07004258 parser->m_declEntity = (ENTITY *)lookup(
4259 parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY));
4260 if (! parser->m_declEntity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004261 return XML_ERROR_NO_MEMORY;
4262#endif /* XML_DTD */
4263 dtd->hasParamEntityRefs = XML_TRUE;
Elliott Hughes72472942018-01-10 08:36:10 -08004264 if (parser->m_startDoctypeDeclHandler) {
Elliott Hughes35e432d2012-09-09 14:23:38 -07004265 XML_Char *pubId;
Haibo Huang40a71912019-10-11 11:13:39 -07004266 if (! XmlIsPublicId(enc, s, next, eventPP))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004267 return XML_ERROR_PUBLICID;
Elliott Hughes72472942018-01-10 08:36:10 -08004268 pubId = poolStoreString(&parser->m_tempPool, enc,
Elliott Hughes35e432d2012-09-09 14:23:38 -07004269 s + enc->minBytesPerChar,
4270 next - enc->minBytesPerChar);
Haibo Huang40a71912019-10-11 11:13:39 -07004271 if (! pubId)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004272 return XML_ERROR_NO_MEMORY;
Elliott Hughes35e432d2012-09-09 14:23:38 -07004273 normalizePublicId(pubId);
Elliott Hughes72472942018-01-10 08:36:10 -08004274 poolFinish(&parser->m_tempPool);
4275 parser->m_doctypePubid = pubId;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004276 handleDefault = XML_FALSE;
4277 goto alreadyChecked;
4278 }
4279 /* fall through */
4280 case XML_ROLE_ENTITY_PUBLIC_ID:
Haibo Huang40a71912019-10-11 11:13:39 -07004281 if (! XmlIsPublicId(enc, s, next, eventPP))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004282 return XML_ERROR_PUBLICID;
4283 alreadyChecked:
Elliott Hughes72472942018-01-10 08:36:10 -08004284 if (dtd->keepProcessing && parser->m_declEntity) {
Haibo Huang40a71912019-10-11 11:13:39 -07004285 XML_Char *tem
4286 = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
4287 next - enc->minBytesPerChar);
4288 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004289 return XML_ERROR_NO_MEMORY;
4290 normalizePublicId(tem);
Elliott Hughes72472942018-01-10 08:36:10 -08004291 parser->m_declEntity->publicId = tem;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004292 poolFinish(&dtd->pool);
Elliott Hughes72472942018-01-10 08:36:10 -08004293 /* Don't suppress the default handler if we fell through from
4294 * the XML_ROLE_DOCTYPE_PUBLIC_ID case.
4295 */
4296 if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_PUBLIC_ID)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004297 handleDefault = XML_FALSE;
4298 }
4299 break;
4300 case XML_ROLE_DOCTYPE_CLOSE:
Haibo Huang40a71912019-10-11 11:13:39 -07004301 if (allowClosingDoctype != XML_TRUE) {
4302 /* Must not close doctype from within expanded parameter entities */
4303 return XML_ERROR_INVALID_TOKEN;
4304 }
4305
Elliott Hughes72472942018-01-10 08:36:10 -08004306 if (parser->m_doctypeName) {
Haibo Huang40a71912019-10-11 11:13:39 -07004307 parser->m_startDoctypeDeclHandler(
4308 parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid,
4309 parser->m_doctypePubid, 0);
Elliott Hughes72472942018-01-10 08:36:10 -08004310 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004311 handleDefault = XML_FALSE;
4312 }
Elliott Hughes72472942018-01-10 08:36:10 -08004313 /* parser->m_doctypeSysid will be non-NULL in the case of a previous
4314 XML_ROLE_DOCTYPE_SYSTEM_ID, even if parser->m_startDoctypeDeclHandler
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004315 was not set, indicating an external subset
4316 */
4317#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08004318 if (parser->m_doctypeSysid || parser->m_useForeignDTD) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004319 XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
4320 dtd->hasParamEntityRefs = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07004321 if (parser->m_paramEntityParsing
4322 && parser->m_externalEntityRefHandler) {
4323 ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
4324 externalSubsetName, sizeof(ENTITY));
4325 if (! entity) {
Elliott Hughes72472942018-01-10 08:36:10 -08004326 /* The external subset name "#" will have already been
4327 * inserted into the hash table at the start of the
4328 * external entity parsing, so no allocation will happen
4329 * and lookup() cannot fail.
4330 */
4331 return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */
4332 }
4333 if (parser->m_useForeignDTD)
4334 entity->base = parser->m_curBase;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004335 dtd->paramEntityRead = XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07004336 if (! parser->m_externalEntityRefHandler(
4337 parser->m_externalEntityRefHandlerArg, 0, entity->base,
4338 entity->systemId, entity->publicId))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004339 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4340 if (dtd->paramEntityRead) {
Haibo Huang40a71912019-10-11 11:13:39 -07004341 if (! dtd->standalone && parser->m_notStandaloneHandler
4342 && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004343 return XML_ERROR_NOT_STANDALONE;
4344 }
4345 /* if we didn't read the foreign DTD then this means that there
4346 is no external subset and we must reset dtd->hasParamEntityRefs
4347 */
Haibo Huang40a71912019-10-11 11:13:39 -07004348 else if (! parser->m_doctypeSysid)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004349 dtd->hasParamEntityRefs = hadParamEntityRefs;
4350 /* end of DTD - no need to update dtd->keepProcessing */
4351 }
Elliott Hughes72472942018-01-10 08:36:10 -08004352 parser->m_useForeignDTD = XML_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004353 }
4354#endif /* XML_DTD */
Elliott Hughes72472942018-01-10 08:36:10 -08004355 if (parser->m_endDoctypeDeclHandler) {
4356 parser->m_endDoctypeDeclHandler(parser->m_handlerArg);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004357 handleDefault = XML_FALSE;
4358 }
4359 break;
4360 case XML_ROLE_INSTANCE_START:
4361#ifdef XML_DTD
4362 /* if there is no DOCTYPE declaration then now is the
4363 last chance to read the foreign DTD
4364 */
Elliott Hughes72472942018-01-10 08:36:10 -08004365 if (parser->m_useForeignDTD) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004366 XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
4367 dtd->hasParamEntityRefs = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07004368 if (parser->m_paramEntityParsing
4369 && parser->m_externalEntityRefHandler) {
Elliott Hughes35e432d2012-09-09 14:23:38 -07004370 ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
Haibo Huang40a71912019-10-11 11:13:39 -07004371 externalSubsetName, sizeof(ENTITY));
4372 if (! entity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004373 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004374 entity->base = parser->m_curBase;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004375 dtd->paramEntityRead = XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07004376 if (! parser->m_externalEntityRefHandler(
4377 parser->m_externalEntityRefHandlerArg, 0, entity->base,
4378 entity->systemId, entity->publicId))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004379 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4380 if (dtd->paramEntityRead) {
Haibo Huang40a71912019-10-11 11:13:39 -07004381 if (! dtd->standalone && parser->m_notStandaloneHandler
4382 && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004383 return XML_ERROR_NOT_STANDALONE;
4384 }
4385 /* if we didn't read the foreign DTD then this means that there
4386 is no external subset and we must reset dtd->hasParamEntityRefs
4387 */
4388 else
4389 dtd->hasParamEntityRefs = hadParamEntityRefs;
4390 /* end of DTD - no need to update dtd->keepProcessing */
4391 }
4392 }
4393#endif /* XML_DTD */
Elliott Hughes72472942018-01-10 08:36:10 -08004394 parser->m_processor = contentProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004395 return contentProcessor(parser, s, end, nextPtr);
4396 case XML_ROLE_ATTLIST_ELEMENT_NAME:
Elliott Hughes72472942018-01-10 08:36:10 -08004397 parser->m_declElementType = getElementType(parser, enc, s, next);
Haibo Huang40a71912019-10-11 11:13:39 -07004398 if (! parser->m_declElementType)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004399 return XML_ERROR_NO_MEMORY;
4400 goto checkAttListDeclHandler;
4401 case XML_ROLE_ATTRIBUTE_NAME:
Elliott Hughes72472942018-01-10 08:36:10 -08004402 parser->m_declAttributeId = getAttributeId(parser, enc, s, next);
Haibo Huang40a71912019-10-11 11:13:39 -07004403 if (! parser->m_declAttributeId)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004404 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004405 parser->m_declAttributeIsCdata = XML_FALSE;
4406 parser->m_declAttributeType = NULL;
4407 parser->m_declAttributeIsId = XML_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004408 goto checkAttListDeclHandler;
4409 case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
Elliott Hughes72472942018-01-10 08:36:10 -08004410 parser->m_declAttributeIsCdata = XML_TRUE;
4411 parser->m_declAttributeType = atypeCDATA;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004412 goto checkAttListDeclHandler;
4413 case XML_ROLE_ATTRIBUTE_TYPE_ID:
Elliott Hughes72472942018-01-10 08:36:10 -08004414 parser->m_declAttributeIsId = XML_TRUE;
4415 parser->m_declAttributeType = atypeID;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004416 goto checkAttListDeclHandler;
4417 case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
Elliott Hughes72472942018-01-10 08:36:10 -08004418 parser->m_declAttributeType = atypeIDREF;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004419 goto checkAttListDeclHandler;
4420 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
Elliott Hughes72472942018-01-10 08:36:10 -08004421 parser->m_declAttributeType = atypeIDREFS;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004422 goto checkAttListDeclHandler;
4423 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
Elliott Hughes72472942018-01-10 08:36:10 -08004424 parser->m_declAttributeType = atypeENTITY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004425 goto checkAttListDeclHandler;
4426 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
Elliott Hughes72472942018-01-10 08:36:10 -08004427 parser->m_declAttributeType = atypeENTITIES;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004428 goto checkAttListDeclHandler;
4429 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
Elliott Hughes72472942018-01-10 08:36:10 -08004430 parser->m_declAttributeType = atypeNMTOKEN;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004431 goto checkAttListDeclHandler;
4432 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
Elliott Hughes72472942018-01-10 08:36:10 -08004433 parser->m_declAttributeType = atypeNMTOKENS;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004434 checkAttListDeclHandler:
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 handleDefault = XML_FALSE;
4437 break;
4438 case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
4439 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
Elliott Hughes72472942018-01-10 08:36:10 -08004440 if (dtd->keepProcessing && parser->m_attlistDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004441 const XML_Char *prefix;
Elliott Hughes72472942018-01-10 08:36:10 -08004442 if (parser->m_declAttributeType) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004443 prefix = enumValueSep;
Haibo Huang40a71912019-10-11 11:13:39 -07004444 } else {
4445 prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE ? notationPrefix
4446 : enumValueStart);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004447 }
Haibo Huang40a71912019-10-11 11:13:39 -07004448 if (! poolAppendString(&parser->m_tempPool, prefix))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004449 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07004450 if (! poolAppend(&parser->m_tempPool, enc, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004451 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004452 parser->m_declAttributeType = parser->m_tempPool.start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004453 handleDefault = XML_FALSE;
4454 }
4455 break;
4456 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
4457 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
4458 if (dtd->keepProcessing) {
Haibo Huang40a71912019-10-11 11:13:39 -07004459 if (! defineAttribute(parser->m_declElementType,
4460 parser->m_declAttributeId,
4461 parser->m_declAttributeIsCdata,
4462 parser->m_declAttributeIsId, 0, parser))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004463 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004464 if (parser->m_attlistDeclHandler && parser->m_declAttributeType) {
4465 if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN)
4466 || (*parser->m_declAttributeType == XML_T(ASCII_N)
4467 && parser->m_declAttributeType[1] == XML_T(ASCII_O))) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004468 /* Enumerated or Notation type */
Haibo Huang40a71912019-10-11 11:13:39 -07004469 if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN))
4470 || ! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004471 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004472 parser->m_declAttributeType = parser->m_tempPool.start;
4473 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004474 }
4475 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004476 parser->m_attlistDeclHandler(
4477 parser->m_handlerArg, parser->m_declElementType->name,
4478 parser->m_declAttributeId->name, parser->m_declAttributeType, 0,
4479 role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
Elliott Hughes72472942018-01-10 08:36:10 -08004480 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004481 handleDefault = XML_FALSE;
4482 }
4483 }
4484 break;
4485 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
4486 case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
4487 if (dtd->keepProcessing) {
4488 const XML_Char *attVal;
Haibo Huang40a71912019-10-11 11:13:39 -07004489 enum XML_Error result = storeAttributeValue(
4490 parser, enc, parser->m_declAttributeIsCdata,
4491 s + enc->minBytesPerChar, next - enc->minBytesPerChar, &dtd->pool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004492 if (result)
4493 return result;
4494 attVal = poolStart(&dtd->pool);
4495 poolFinish(&dtd->pool);
4496 /* ID attributes aren't allowed to have a default */
Haibo Huang40a71912019-10-11 11:13:39 -07004497 if (! defineAttribute(
4498 parser->m_declElementType, parser->m_declAttributeId,
4499 parser->m_declAttributeIsCdata, XML_FALSE, attVal, parser))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004500 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004501 if (parser->m_attlistDeclHandler && parser->m_declAttributeType) {
4502 if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN)
4503 || (*parser->m_declAttributeType == XML_T(ASCII_N)
4504 && parser->m_declAttributeType[1] == XML_T(ASCII_O))) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004505 /* Enumerated or Notation type */
Haibo Huang40a71912019-10-11 11:13:39 -07004506 if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN))
4507 || ! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004508 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004509 parser->m_declAttributeType = parser->m_tempPool.start;
4510 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004511 }
4512 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004513 parser->m_attlistDeclHandler(
4514 parser->m_handlerArg, parser->m_declElementType->name,
4515 parser->m_declAttributeId->name, parser->m_declAttributeType,
4516 attVal, role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
Elliott Hughes72472942018-01-10 08:36:10 -08004517 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004518 handleDefault = XML_FALSE;
4519 }
4520 }
4521 break;
4522 case XML_ROLE_ENTITY_VALUE:
4523 if (dtd->keepProcessing) {
Haibo Huang40a71912019-10-11 11:13:39 -07004524 enum XML_Error result = storeEntityValue(
4525 parser, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar);
Elliott Hughes72472942018-01-10 08:36:10 -08004526 if (parser->m_declEntity) {
4527 parser->m_declEntity->textPtr = poolStart(&dtd->entityValuePool);
Haibo Huang40a71912019-10-11 11:13:39 -07004528 parser->m_declEntity->textLen
4529 = (int)(poolLength(&dtd->entityValuePool));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004530 poolFinish(&dtd->entityValuePool);
Elliott Hughes72472942018-01-10 08:36:10 -08004531 if (parser->m_entityDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004532 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004533 parser->m_entityDeclHandler(
4534 parser->m_handlerArg, parser->m_declEntity->name,
4535 parser->m_declEntity->is_param, parser->m_declEntity->textPtr,
4536 parser->m_declEntity->textLen, parser->m_curBase, 0, 0, 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004537 handleDefault = XML_FALSE;
4538 }
Haibo Huang40a71912019-10-11 11:13:39 -07004539 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004540 poolDiscard(&dtd->entityValuePool);
4541 if (result != XML_ERROR_NONE)
4542 return result;
4543 }
4544 break;
4545 case XML_ROLE_DOCTYPE_SYSTEM_ID:
4546#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08004547 parser->m_useForeignDTD = XML_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004548#endif /* XML_DTD */
4549 dtd->hasParamEntityRefs = XML_TRUE;
Elliott Hughes72472942018-01-10 08:36:10 -08004550 if (parser->m_startDoctypeDeclHandler) {
4551 parser->m_doctypeSysid = poolStoreString(&parser->m_tempPool, enc,
Haibo Huang40a71912019-10-11 11:13:39 -07004552 s + enc->minBytesPerChar,
4553 next - enc->minBytesPerChar);
Elliott Hughes72472942018-01-10 08:36:10 -08004554 if (parser->m_doctypeSysid == NULL)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004555 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004556 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004557 handleDefault = XML_FALSE;
4558 }
4559#ifdef XML_DTD
4560 else
Elliott Hughes72472942018-01-10 08:36:10 -08004561 /* use externalSubsetName to make parser->m_doctypeSysid non-NULL
4562 for the case where no parser->m_startDoctypeDeclHandler is set */
4563 parser->m_doctypeSysid = externalSubsetName;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004564#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07004565 if (! dtd->standalone
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004566#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07004567 && ! parser->m_paramEntityParsing
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004568#endif /* XML_DTD */
Elliott Hughes72472942018-01-10 08:36:10 -08004569 && parser->m_notStandaloneHandler
Haibo Huang40a71912019-10-11 11:13:39 -07004570 && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004571 return XML_ERROR_NOT_STANDALONE;
4572#ifndef XML_DTD
4573 break;
Haibo Huang40a71912019-10-11 11:13:39 -07004574#else /* XML_DTD */
4575 if (! parser->m_declEntity) {
4576 parser->m_declEntity = (ENTITY *)lookup(
4577 parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY));
4578 if (! parser->m_declEntity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004579 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004580 parser->m_declEntity->publicId = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004581 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004582#endif /* XML_DTD */
Elliott Hughesaaec48e2018-08-16 16:29:01 -07004583 /* fall through */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004584 case XML_ROLE_ENTITY_SYSTEM_ID:
Elliott Hughes72472942018-01-10 08:36:10 -08004585 if (dtd->keepProcessing && parser->m_declEntity) {
Haibo Huang40a71912019-10-11 11:13:39 -07004586 parser->m_declEntity->systemId
4587 = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
4588 next - enc->minBytesPerChar);
4589 if (! parser->m_declEntity->systemId)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004590 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004591 parser->m_declEntity->base = parser->m_curBase;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004592 poolFinish(&dtd->pool);
Elliott Hughes72472942018-01-10 08:36:10 -08004593 /* Don't suppress the default handler if we fell through from
4594 * the XML_ROLE_DOCTYPE_SYSTEM_ID case.
4595 */
4596 if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_SYSTEM_ID)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004597 handleDefault = XML_FALSE;
4598 }
4599 break;
4600 case XML_ROLE_ENTITY_COMPLETE:
Haibo Huang40a71912019-10-11 11:13:39 -07004601 if (dtd->keepProcessing && parser->m_declEntity
4602 && parser->m_entityDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004603 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004604 parser->m_entityDeclHandler(
4605 parser->m_handlerArg, parser->m_declEntity->name,
4606 parser->m_declEntity->is_param, 0, 0, parser->m_declEntity->base,
4607 parser->m_declEntity->systemId, parser->m_declEntity->publicId, 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004608 handleDefault = XML_FALSE;
4609 }
4610 break;
4611 case XML_ROLE_ENTITY_NOTATION_NAME:
Elliott Hughes72472942018-01-10 08:36:10 -08004612 if (dtd->keepProcessing && parser->m_declEntity) {
Haibo Huang40a71912019-10-11 11:13:39 -07004613 parser->m_declEntity->notation
4614 = poolStoreString(&dtd->pool, enc, s, next);
4615 if (! parser->m_declEntity->notation)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004616 return XML_ERROR_NO_MEMORY;
4617 poolFinish(&dtd->pool);
Elliott Hughes72472942018-01-10 08:36:10 -08004618 if (parser->m_unparsedEntityDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004619 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004620 parser->m_unparsedEntityDeclHandler(
4621 parser->m_handlerArg, parser->m_declEntity->name,
4622 parser->m_declEntity->base, parser->m_declEntity->systemId,
4623 parser->m_declEntity->publicId, parser->m_declEntity->notation);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004624 handleDefault = XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07004625 } else if (parser->m_entityDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004626 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004627 parser->m_entityDeclHandler(
4628 parser->m_handlerArg, parser->m_declEntity->name, 0, 0, 0,
4629 parser->m_declEntity->base, parser->m_declEntity->systemId,
4630 parser->m_declEntity->publicId, parser->m_declEntity->notation);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004631 handleDefault = XML_FALSE;
4632 }
4633 }
4634 break;
Haibo Huang40a71912019-10-11 11:13:39 -07004635 case XML_ROLE_GENERAL_ENTITY_NAME: {
4636 if (XmlPredefinedEntityName(enc, s, next)) {
4637 parser->m_declEntity = NULL;
4638 break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004639 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004640 if (dtd->keepProcessing) {
4641 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
Haibo Huang40a71912019-10-11 11:13:39 -07004642 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004643 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07004644 parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities,
4645 name, sizeof(ENTITY));
4646 if (! parser->m_declEntity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004647 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004648 if (parser->m_declEntity->name != name) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004649 poolDiscard(&dtd->pool);
Elliott Hughes72472942018-01-10 08:36:10 -08004650 parser->m_declEntity = NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07004651 } else {
4652 poolFinish(&dtd->pool);
4653 parser->m_declEntity->publicId = NULL;
4654 parser->m_declEntity->is_param = XML_FALSE;
4655 /* if we have a parent parser or are reading an internal parameter
4656 entity, then the entity declaration is not considered "internal"
4657 */
4658 parser->m_declEntity->is_internal
4659 = ! (parser->m_parentParser || parser->m_openInternalEntities);
4660 if (parser->m_entityDeclHandler)
4661 handleDefault = XML_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004662 }
Haibo Huang40a71912019-10-11 11:13:39 -07004663 } else {
4664 poolDiscard(&dtd->pool);
4665 parser->m_declEntity = NULL;
4666 }
4667 } break;
4668 case XML_ROLE_PARAM_ENTITY_NAME:
4669#ifdef XML_DTD
4670 if (dtd->keepProcessing) {
4671 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
4672 if (! name)
4673 return XML_ERROR_NO_MEMORY;
4674 parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities,
4675 name, sizeof(ENTITY));
4676 if (! parser->m_declEntity)
4677 return XML_ERROR_NO_MEMORY;
4678 if (parser->m_declEntity->name != name) {
4679 poolDiscard(&dtd->pool);
4680 parser->m_declEntity = NULL;
4681 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004682 poolFinish(&dtd->pool);
Elliott Hughes72472942018-01-10 08:36:10 -08004683 parser->m_declEntity->publicId = NULL;
4684 parser->m_declEntity->is_param = XML_TRUE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004685 /* if we have a parent parser or are reading an internal parameter
4686 entity, then the entity declaration is not considered "internal"
4687 */
Haibo Huang40a71912019-10-11 11:13:39 -07004688 parser->m_declEntity->is_internal
4689 = ! (parser->m_parentParser || parser->m_openInternalEntities);
Elliott Hughes72472942018-01-10 08:36:10 -08004690 if (parser->m_entityDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004691 handleDefault = XML_FALSE;
4692 }
Haibo Huang40a71912019-10-11 11:13:39 -07004693 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004694 poolDiscard(&dtd->pool);
Elliott Hughes72472942018-01-10 08:36:10 -08004695 parser->m_declEntity = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004696 }
Haibo Huang40a71912019-10-11 11:13:39 -07004697#else /* not XML_DTD */
Elliott Hughes72472942018-01-10 08:36:10 -08004698 parser->m_declEntity = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004699#endif /* XML_DTD */
4700 break;
4701 case XML_ROLE_NOTATION_NAME:
Elliott Hughes72472942018-01-10 08:36:10 -08004702 parser->m_declNotationPublicId = NULL;
4703 parser->m_declNotationName = NULL;
4704 if (parser->m_notationDeclHandler) {
Haibo Huang40a71912019-10-11 11:13:39 -07004705 parser->m_declNotationName
4706 = poolStoreString(&parser->m_tempPool, enc, s, next);
4707 if (! parser->m_declNotationName)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004708 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004709 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004710 handleDefault = XML_FALSE;
4711 }
4712 break;
4713 case XML_ROLE_NOTATION_PUBLIC_ID:
Haibo Huang40a71912019-10-11 11:13:39 -07004714 if (! XmlIsPublicId(enc, s, next, eventPP))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004715 return XML_ERROR_PUBLICID;
Haibo Huang40a71912019-10-11 11:13:39 -07004716 if (parser
4717 ->m_declNotationName) { /* means m_notationDeclHandler != NULL */
4718 XML_Char *tem = poolStoreString(&parser->m_tempPool, enc,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004719 s + enc->minBytesPerChar,
4720 next - enc->minBytesPerChar);
Haibo Huang40a71912019-10-11 11:13:39 -07004721 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004722 return XML_ERROR_NO_MEMORY;
4723 normalizePublicId(tem);
Elliott Hughes72472942018-01-10 08:36:10 -08004724 parser->m_declNotationPublicId = tem;
4725 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004726 handleDefault = XML_FALSE;
4727 }
4728 break;
4729 case XML_ROLE_NOTATION_SYSTEM_ID:
Elliott Hughes72472942018-01-10 08:36:10 -08004730 if (parser->m_declNotationName && parser->m_notationDeclHandler) {
Haibo Huang40a71912019-10-11 11:13:39 -07004731 const XML_Char *systemId = poolStoreString(&parser->m_tempPool, enc,
4732 s + enc->minBytesPerChar,
4733 next - enc->minBytesPerChar);
4734 if (! systemId)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004735 return XML_ERROR_NO_MEMORY;
4736 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004737 parser->m_notationDeclHandler(
4738 parser->m_handlerArg, parser->m_declNotationName, parser->m_curBase,
4739 systemId, parser->m_declNotationPublicId);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004740 handleDefault = XML_FALSE;
4741 }
Elliott Hughes72472942018-01-10 08:36:10 -08004742 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004743 break;
4744 case XML_ROLE_NOTATION_NO_SYSTEM_ID:
Elliott Hughes72472942018-01-10 08:36:10 -08004745 if (parser->m_declNotationPublicId && parser->m_notationDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004746 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004747 parser->m_notationDeclHandler(
4748 parser->m_handlerArg, parser->m_declNotationName, parser->m_curBase,
4749 0, parser->m_declNotationPublicId);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004750 handleDefault = XML_FALSE;
4751 }
Elliott Hughes72472942018-01-10 08:36:10 -08004752 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004753 break;
4754 case XML_ROLE_ERROR:
4755 switch (tok) {
4756 case XML_TOK_PARAM_ENTITY_REF:
4757 /* PE references in internal subset are
Elliott Hughes35e432d2012-09-09 14:23:38 -07004758 not allowed within declarations. */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004759 return XML_ERROR_PARAM_ENTITY_REF;
4760 case XML_TOK_XML_DECL:
4761 return XML_ERROR_MISPLACED_XML_PI;
4762 default:
4763 return XML_ERROR_SYNTAX;
4764 }
4765#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07004766 case XML_ROLE_IGNORE_SECT: {
4767 enum XML_Error result;
4768 if (parser->m_defaultHandler)
4769 reportDefault(parser, enc, s, next);
4770 handleDefault = XML_FALSE;
4771 result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
4772 if (result != XML_ERROR_NONE)
4773 return result;
4774 else if (! next) {
4775 parser->m_processor = ignoreSectionProcessor;
4776 return result;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004777 }
Haibo Huang40a71912019-10-11 11:13:39 -07004778 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004779#endif /* XML_DTD */
4780 case XML_ROLE_GROUP_OPEN:
Elliott Hughes72472942018-01-10 08:36:10 -08004781 if (parser->m_prologState.level >= parser->m_groupSize) {
4782 if (parser->m_groupSize) {
Haibo Huang40a71912019-10-11 11:13:39 -07004783 {
4784 char *const new_connector = (char *)REALLOC(
4785 parser, parser->m_groupConnector, parser->m_groupSize *= 2);
4786 if (new_connector == NULL) {
4787 parser->m_groupSize /= 2;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004788 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07004789 }
4790 parser->m_groupConnector = new_connector;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004791 }
Haibo Huang40a71912019-10-11 11:13:39 -07004792
4793 if (dtd->scaffIndex) {
4794 int *const new_scaff_index = (int *)REALLOC(
4795 parser, dtd->scaffIndex, parser->m_groupSize * sizeof(int));
4796 if (new_scaff_index == NULL)
4797 return XML_ERROR_NO_MEMORY;
4798 dtd->scaffIndex = new_scaff_index;
4799 }
4800 } else {
4801 parser->m_groupConnector
4802 = (char *)MALLOC(parser, parser->m_groupSize = 32);
4803 if (! parser->m_groupConnector) {
Elliott Hughes72472942018-01-10 08:36:10 -08004804 parser->m_groupSize = 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004805 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004806 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004807 }
4808 }
Elliott Hughes72472942018-01-10 08:36:10 -08004809 parser->m_groupConnector[parser->m_prologState.level] = 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004810 if (dtd->in_eldecl) {
4811 int myindex = nextScaffoldPart(parser);
4812 if (myindex < 0)
4813 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07004814 assert(dtd->scaffIndex != NULL);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004815 dtd->scaffIndex[dtd->scaffLevel] = myindex;
4816 dtd->scaffLevel++;
4817 dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
Elliott Hughes72472942018-01-10 08:36:10 -08004818 if (parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004819 handleDefault = XML_FALSE;
4820 }
4821 break;
4822 case XML_ROLE_GROUP_SEQUENCE:
Elliott Hughes72472942018-01-10 08:36:10 -08004823 if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_PIPE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004824 return XML_ERROR_SYNTAX;
Elliott Hughes72472942018-01-10 08:36:10 -08004825 parser->m_groupConnector[parser->m_prologState.level] = ASCII_COMMA;
4826 if (dtd->in_eldecl && parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004827 handleDefault = XML_FALSE;
4828 break;
4829 case XML_ROLE_GROUP_CHOICE:
Elliott Hughes72472942018-01-10 08:36:10 -08004830 if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_COMMA)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004831 return XML_ERROR_SYNTAX;
4832 if (dtd->in_eldecl
Haibo Huang40a71912019-10-11 11:13:39 -07004833 && ! parser->m_groupConnector[parser->m_prologState.level]
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004834 && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
Haibo Huang40a71912019-10-11 11:13:39 -07004835 != XML_CTYPE_MIXED)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004836 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4837 = XML_CTYPE_CHOICE;
Elliott Hughes72472942018-01-10 08:36:10 -08004838 if (parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004839 handleDefault = XML_FALSE;
4840 }
Elliott Hughes72472942018-01-10 08:36:10 -08004841 parser->m_groupConnector[parser->m_prologState.level] = ASCII_PIPE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004842 break;
4843 case XML_ROLE_PARAM_ENTITY_REF:
4844#ifdef XML_DTD
4845 case XML_ROLE_INNER_PARAM_ENTITY_REF:
4846 dtd->hasParamEntityRefs = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07004847 if (! parser->m_paramEntityParsing)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004848 dtd->keepProcessing = dtd->standalone;
4849 else {
4850 const XML_Char *name;
4851 ENTITY *entity;
Haibo Huang40a71912019-10-11 11:13:39 -07004852 name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
4853 next - enc->minBytesPerChar);
4854 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004855 return XML_ERROR_NO_MEMORY;
Elliott Hughes35e432d2012-09-09 14:23:38 -07004856 entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004857 poolDiscard(&dtd->pool);
4858 /* first, determine if a check for an existing declaration is needed;
4859 if yes, check that the entity exists, and that it is internal,
4860 otherwise call the skipped entity handler
4861 */
Haibo Huang40a71912019-10-11 11:13:39 -07004862 if (parser->m_prologState.documentEntity
4863 && (dtd->standalone ? ! parser->m_openInternalEntities
4864 : ! dtd->hasParamEntityRefs)) {
4865 if (! entity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004866 return XML_ERROR_UNDEFINED_ENTITY;
Haibo Huang40a71912019-10-11 11:13:39 -07004867 else if (! entity->is_internal) {
Elliott Hughes72472942018-01-10 08:36:10 -08004868 /* It's hard to exhaustively search the code to be sure,
4869 * but there doesn't seem to be a way of executing the
4870 * following line. There are two cases:
4871 *
4872 * If 'standalone' is false, the DTD must have no
4873 * parameter entities or we wouldn't have passed the outer
4874 * 'if' statement. That measn the only entity in the hash
4875 * table is the external subset name "#" which cannot be
4876 * given as a parameter entity name in XML syntax, so the
4877 * lookup must have returned NULL and we don't even reach
4878 * the test for an internal entity.
4879 *
4880 * If 'standalone' is true, it does not seem to be
4881 * possible to create entities taking this code path that
4882 * are not internal entities, so fail the test above.
4883 *
4884 * Because this analysis is very uncertain, the code is
4885 * being left in place and merely removed from the
4886 * coverage test statistics.
4887 */
4888 return XML_ERROR_ENTITY_DECLARED_IN_PE; /* LCOV_EXCL_LINE */
4889 }
Haibo Huang40a71912019-10-11 11:13:39 -07004890 } else if (! entity) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004891 dtd->keepProcessing = dtd->standalone;
4892 /* cannot report skipped entities in declarations */
Haibo Huang40a71912019-10-11 11:13:39 -07004893 if ((role == XML_ROLE_PARAM_ENTITY_REF)
4894 && parser->m_skippedEntityHandler) {
Elliott Hughes72472942018-01-10 08:36:10 -08004895 parser->m_skippedEntityHandler(parser->m_handlerArg, name, 1);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004896 handleDefault = XML_FALSE;
4897 }
4898 break;
4899 }
4900 if (entity->open)
4901 return XML_ERROR_RECURSIVE_ENTITY_REF;
4902 if (entity->textPtr) {
4903 enum XML_Error result;
Haibo Huang40a71912019-10-11 11:13:39 -07004904 XML_Bool betweenDecl
4905 = (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004906 result = processInternalEntity(parser, entity, betweenDecl);
4907 if (result != XML_ERROR_NONE)
4908 return result;
4909 handleDefault = XML_FALSE;
4910 break;
4911 }
Elliott Hughes72472942018-01-10 08:36:10 -08004912 if (parser->m_externalEntityRefHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004913 dtd->paramEntityRead = XML_FALSE;
4914 entity->open = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07004915 if (! parser->m_externalEntityRefHandler(
4916 parser->m_externalEntityRefHandlerArg, 0, entity->base,
4917 entity->systemId, entity->publicId)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004918 entity->open = XML_FALSE;
4919 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4920 }
4921 entity->open = XML_FALSE;
4922 handleDefault = XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07004923 if (! dtd->paramEntityRead) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004924 dtd->keepProcessing = dtd->standalone;
4925 break;
4926 }
Haibo Huang40a71912019-10-11 11:13:39 -07004927 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004928 dtd->keepProcessing = dtd->standalone;
4929 break;
4930 }
4931 }
4932#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07004933 if (! dtd->standalone && parser->m_notStandaloneHandler
4934 && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004935 return XML_ERROR_NOT_STANDALONE;
4936 break;
4937
Haibo Huang40a71912019-10-11 11:13:39 -07004938 /* Element declaration stuff */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004939
4940 case XML_ROLE_ELEMENT_NAME:
Elliott Hughes72472942018-01-10 08:36:10 -08004941 if (parser->m_elementDeclHandler) {
4942 parser->m_declElementType = getElementType(parser, enc, s, next);
Haibo Huang40a71912019-10-11 11:13:39 -07004943 if (! parser->m_declElementType)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004944 return XML_ERROR_NO_MEMORY;
4945 dtd->scaffLevel = 0;
4946 dtd->scaffCount = 0;
4947 dtd->in_eldecl = XML_TRUE;
4948 handleDefault = XML_FALSE;
4949 }
4950 break;
4951
4952 case XML_ROLE_CONTENT_ANY:
4953 case XML_ROLE_CONTENT_EMPTY:
4954 if (dtd->in_eldecl) {
Elliott Hughes72472942018-01-10 08:36:10 -08004955 if (parser->m_elementDeclHandler) {
Haibo Huang40a71912019-10-11 11:13:39 -07004956 XML_Content *content
4957 = (XML_Content *)MALLOC(parser, sizeof(XML_Content));
4958 if (! content)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004959 return XML_ERROR_NO_MEMORY;
4960 content->quant = XML_CQUANT_NONE;
4961 content->name = NULL;
4962 content->numchildren = 0;
4963 content->children = NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07004964 content->type = ((role == XML_ROLE_CONTENT_ANY) ? XML_CTYPE_ANY
4965 : XML_CTYPE_EMPTY);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004966 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004967 parser->m_elementDeclHandler(
4968 parser->m_handlerArg, parser->m_declElementType->name, content);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004969 handleDefault = XML_FALSE;
4970 }
4971 dtd->in_eldecl = XML_FALSE;
4972 }
4973 break;
4974
4975 case XML_ROLE_CONTENT_PCDATA:
4976 if (dtd->in_eldecl) {
4977 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4978 = XML_CTYPE_MIXED;
Elliott Hughes72472942018-01-10 08:36:10 -08004979 if (parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004980 handleDefault = XML_FALSE;
4981 }
4982 break;
4983
4984 case XML_ROLE_CONTENT_ELEMENT:
4985 quant = XML_CQUANT_NONE;
4986 goto elementContent;
4987 case XML_ROLE_CONTENT_ELEMENT_OPT:
4988 quant = XML_CQUANT_OPT;
4989 goto elementContent;
4990 case XML_ROLE_CONTENT_ELEMENT_REP:
4991 quant = XML_CQUANT_REP;
4992 goto elementContent;
4993 case XML_ROLE_CONTENT_ELEMENT_PLUS:
4994 quant = XML_CQUANT_PLUS;
4995 elementContent:
4996 if (dtd->in_eldecl) {
4997 ELEMENT_TYPE *el;
4998 const XML_Char *name;
4999 int nameLen;
Haibo Huang40a71912019-10-11 11:13:39 -07005000 const char *nxt
5001 = (quant == XML_CQUANT_NONE ? next : next - enc->minBytesPerChar);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005002 int myindex = nextScaffoldPart(parser);
5003 if (myindex < 0)
5004 return XML_ERROR_NO_MEMORY;
5005 dtd->scaffold[myindex].type = XML_CTYPE_NAME;
5006 dtd->scaffold[myindex].quant = quant;
5007 el = getElementType(parser, enc, s, nxt);
Haibo Huang40a71912019-10-11 11:13:39 -07005008 if (! el)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005009 return XML_ERROR_NO_MEMORY;
5010 name = el->name;
5011 dtd->scaffold[myindex].name = name;
5012 nameLen = 0;
Haibo Huang40a71912019-10-11 11:13:39 -07005013 for (; name[nameLen++];)
5014 ;
5015 dtd->contentStringLen += nameLen;
Elliott Hughes72472942018-01-10 08:36:10 -08005016 if (parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005017 handleDefault = XML_FALSE;
5018 }
5019 break;
5020
5021 case XML_ROLE_GROUP_CLOSE:
5022 quant = XML_CQUANT_NONE;
5023 goto closeGroup;
5024 case XML_ROLE_GROUP_CLOSE_OPT:
5025 quant = XML_CQUANT_OPT;
5026 goto closeGroup;
5027 case XML_ROLE_GROUP_CLOSE_REP:
5028 quant = XML_CQUANT_REP;
5029 goto closeGroup;
5030 case XML_ROLE_GROUP_CLOSE_PLUS:
5031 quant = XML_CQUANT_PLUS;
5032 closeGroup:
5033 if (dtd->in_eldecl) {
Elliott Hughes72472942018-01-10 08:36:10 -08005034 if (parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005035 handleDefault = XML_FALSE;
5036 dtd->scaffLevel--;
5037 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
5038 if (dtd->scaffLevel == 0) {
Haibo Huang40a71912019-10-11 11:13:39 -07005039 if (! handleDefault) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005040 XML_Content *model = build_model(parser);
Haibo Huang40a71912019-10-11 11:13:39 -07005041 if (! model)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005042 return XML_ERROR_NO_MEMORY;
5043 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07005044 parser->m_elementDeclHandler(
5045 parser->m_handlerArg, parser->m_declElementType->name, model);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005046 }
5047 dtd->in_eldecl = XML_FALSE;
5048 dtd->contentStringLen = 0;
5049 }
5050 }
5051 break;
5052 /* End element declaration stuff */
5053
5054 case XML_ROLE_PI:
Haibo Huang40a71912019-10-11 11:13:39 -07005055 if (! reportProcessingInstruction(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_COMMENT:
Haibo Huang40a71912019-10-11 11:13:39 -07005060 if (! reportComment(parser, enc, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005061 return XML_ERROR_NO_MEMORY;
5062 handleDefault = XML_FALSE;
5063 break;
5064 case XML_ROLE_NONE:
5065 switch (tok) {
5066 case XML_TOK_BOM:
5067 handleDefault = XML_FALSE;
5068 break;
5069 }
5070 break;
5071 case XML_ROLE_DOCTYPE_NONE:
Elliott Hughes72472942018-01-10 08:36:10 -08005072 if (parser->m_startDoctypeDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005073 handleDefault = XML_FALSE;
5074 break;
5075 case XML_ROLE_ENTITY_NONE:
Elliott Hughes72472942018-01-10 08:36:10 -08005076 if (dtd->keepProcessing && parser->m_entityDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005077 handleDefault = XML_FALSE;
5078 break;
5079 case XML_ROLE_NOTATION_NONE:
Elliott Hughes72472942018-01-10 08:36:10 -08005080 if (parser->m_notationDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005081 handleDefault = XML_FALSE;
5082 break;
5083 case XML_ROLE_ATTLIST_NONE:
Elliott Hughes72472942018-01-10 08:36:10 -08005084 if (dtd->keepProcessing && parser->m_attlistDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005085 handleDefault = XML_FALSE;
5086 break;
5087 case XML_ROLE_ELEMENT_NONE:
Elliott Hughes72472942018-01-10 08:36:10 -08005088 if (parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005089 handleDefault = XML_FALSE;
5090 break;
5091 } /* end of big switch */
5092
Elliott Hughes72472942018-01-10 08:36:10 -08005093 if (handleDefault && parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005094 reportDefault(parser, enc, s, next);
5095
Elliott Hughes72472942018-01-10 08:36:10 -08005096 switch (parser->m_parsingStatus.parsing) {
Elliott Hughes35e432d2012-09-09 14:23:38 -07005097 case XML_SUSPENDED:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005098 *nextPtr = next;
5099 return XML_ERROR_NONE;
5100 case XML_FINISHED:
5101 return XML_ERROR_ABORTED;
5102 default:
5103 s = next;
5104 tok = XmlPrologTok(enc, s, end, &next);
5105 }
5106 }
5107 /* not reached */
5108}
5109
5110static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07005111epilogProcessor(XML_Parser parser, const char *s, const char *end,
5112 const char **nextPtr) {
Elliott Hughes72472942018-01-10 08:36:10 -08005113 parser->m_processor = epilogProcessor;
5114 parser->m_eventPtr = s;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005115 for (;;) {
5116 const char *next = NULL;
Elliott Hughes72472942018-01-10 08:36:10 -08005117 int tok = XmlPrologTok(parser->m_encoding, s, end, &next);
5118 parser->m_eventEndPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005119 switch (tok) {
5120 /* report partial linebreak - it might be the last token */
5121 case -XML_TOK_PROLOG_S:
Elliott Hughes72472942018-01-10 08:36:10 -08005122 if (parser->m_defaultHandler) {
5123 reportDefault(parser, parser->m_encoding, s, next);
5124 if (parser->m_parsingStatus.parsing == XML_FINISHED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005125 return XML_ERROR_ABORTED;
5126 }
5127 *nextPtr = next;
5128 return XML_ERROR_NONE;
5129 case XML_TOK_NONE:
5130 *nextPtr = s;
5131 return XML_ERROR_NONE;
5132 case XML_TOK_PROLOG_S:
Elliott Hughes72472942018-01-10 08:36:10 -08005133 if (parser->m_defaultHandler)
5134 reportDefault(parser, parser->m_encoding, s, next);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005135 break;
5136 case XML_TOK_PI:
Haibo Huang40a71912019-10-11 11:13:39 -07005137 if (! reportProcessingInstruction(parser, parser->m_encoding, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005138 return XML_ERROR_NO_MEMORY;
5139 break;
5140 case XML_TOK_COMMENT:
Haibo Huang40a71912019-10-11 11:13:39 -07005141 if (! reportComment(parser, parser->m_encoding, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005142 return XML_ERROR_NO_MEMORY;
5143 break;
5144 case XML_TOK_INVALID:
Elliott Hughes72472942018-01-10 08:36:10 -08005145 parser->m_eventPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005146 return XML_ERROR_INVALID_TOKEN;
5147 case XML_TOK_PARTIAL:
Haibo Huang40a71912019-10-11 11:13:39 -07005148 if (! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005149 *nextPtr = s;
5150 return XML_ERROR_NONE;
5151 }
5152 return XML_ERROR_UNCLOSED_TOKEN;
5153 case XML_TOK_PARTIAL_CHAR:
Haibo Huang40a71912019-10-11 11:13:39 -07005154 if (! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005155 *nextPtr = s;
5156 return XML_ERROR_NONE;
5157 }
5158 return XML_ERROR_PARTIAL_CHAR;
5159 default:
5160 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
5161 }
Elliott Hughes72472942018-01-10 08:36:10 -08005162 parser->m_eventPtr = s = next;
5163 switch (parser->m_parsingStatus.parsing) {
Elliott Hughes35e432d2012-09-09 14:23:38 -07005164 case XML_SUSPENDED:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005165 *nextPtr = next;
5166 return XML_ERROR_NONE;
5167 case XML_FINISHED:
5168 return XML_ERROR_ABORTED;
Haibo Huang40a71912019-10-11 11:13:39 -07005169 default:;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005170 }
5171 }
5172}
5173
5174static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07005175processInternalEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005176 const char *textStart, *textEnd;
5177 const char *next;
5178 enum XML_Error result;
5179 OPEN_INTERNAL_ENTITY *openEntity;
5180
Elliott Hughes72472942018-01-10 08:36:10 -08005181 if (parser->m_freeInternalEntities) {
5182 openEntity = parser->m_freeInternalEntities;
5183 parser->m_freeInternalEntities = openEntity->next;
Haibo Huang40a71912019-10-11 11:13:39 -07005184 } else {
5185 openEntity
5186 = (OPEN_INTERNAL_ENTITY *)MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY));
5187 if (! openEntity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005188 return XML_ERROR_NO_MEMORY;
5189 }
5190 entity->open = XML_TRUE;
5191 entity->processed = 0;
Elliott Hughes72472942018-01-10 08:36:10 -08005192 openEntity->next = parser->m_openInternalEntities;
5193 parser->m_openInternalEntities = openEntity;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005194 openEntity->entity = entity;
Elliott Hughes72472942018-01-10 08:36:10 -08005195 openEntity->startTagLevel = parser->m_tagLevel;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005196 openEntity->betweenDecl = betweenDecl;
5197 openEntity->internalEventPtr = NULL;
5198 openEntity->internalEventEndPtr = NULL;
Haibo Huangd1a324a2020-10-28 22:19:36 -07005199 textStart = (const char *)entity->textPtr;
5200 textEnd = (const char *)(entity->textPtr + entity->textLen);
Elliott Hughes72472942018-01-10 08:36:10 -08005201 /* Set a safe default value in case 'next' does not get set */
5202 next = textStart;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005203
5204#ifdef XML_DTD
5205 if (entity->is_param) {
Haibo Huang40a71912019-10-11 11:13:39 -07005206 int tok
5207 = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
5208 result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
5209 tok, next, &next, XML_FALSE, XML_FALSE);
5210 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005211#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07005212 result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding,
5213 textStart, textEnd, &next, XML_FALSE);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005214
5215 if (result == XML_ERROR_NONE) {
Elliott Hughes72472942018-01-10 08:36:10 -08005216 if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005217 entity->processed = (int)(next - textStart);
Elliott Hughes72472942018-01-10 08:36:10 -08005218 parser->m_processor = internalEntityProcessor;
Haibo Huang40a71912019-10-11 11:13:39 -07005219 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005220 entity->open = XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08005221 parser->m_openInternalEntities = openEntity->next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005222 /* put openEntity back in list of free instances */
Elliott Hughes72472942018-01-10 08:36:10 -08005223 openEntity->next = parser->m_freeInternalEntities;
5224 parser->m_freeInternalEntities = openEntity;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005225 }
5226 }
5227 return result;
5228}
5229
5230static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07005231internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
5232 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005233 ENTITY *entity;
5234 const char *textStart, *textEnd;
5235 const char *next;
5236 enum XML_Error result;
Elliott Hughes72472942018-01-10 08:36:10 -08005237 OPEN_INTERNAL_ENTITY *openEntity = parser->m_openInternalEntities;
Haibo Huang40a71912019-10-11 11:13:39 -07005238 if (! openEntity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005239 return XML_ERROR_UNEXPECTED_STATE;
5240
5241 entity = openEntity->entity;
Haibo Huangd1a324a2020-10-28 22:19:36 -07005242 textStart = ((const char *)entity->textPtr) + entity->processed;
5243 textEnd = (const char *)(entity->textPtr + entity->textLen);
Elliott Hughes72472942018-01-10 08:36:10 -08005244 /* Set a safe default value in case 'next' does not get set */
5245 next = textStart;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005246
5247#ifdef XML_DTD
5248 if (entity->is_param) {
Haibo Huang40a71912019-10-11 11:13:39 -07005249 int tok
5250 = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
5251 result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
5252 tok, next, &next, XML_FALSE, XML_TRUE);
5253 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005254#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07005255 result = doContent(parser, openEntity->startTagLevel,
5256 parser->m_internalEncoding, textStart, textEnd, &next,
5257 XML_FALSE);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005258
5259 if (result != XML_ERROR_NONE)
5260 return result;
Haibo Huang40a71912019-10-11 11:13:39 -07005261 else if (textEnd != next
5262 && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
Haibo Huangd1a324a2020-10-28 22:19:36 -07005263 entity->processed = (int)(next - (const char *)entity->textPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005264 return result;
Haibo Huang40a71912019-10-11 11:13:39 -07005265 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005266 entity->open = XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08005267 parser->m_openInternalEntities = openEntity->next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005268 /* put openEntity back in list of free instances */
Elliott Hughes72472942018-01-10 08:36:10 -08005269 openEntity->next = parser->m_freeInternalEntities;
5270 parser->m_freeInternalEntities = openEntity;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005271 }
5272
5273#ifdef XML_DTD
5274 if (entity->is_param) {
5275 int tok;
Elliott Hughes72472942018-01-10 08:36:10 -08005276 parser->m_processor = prologProcessor;
5277 tok = XmlPrologTok(parser->m_encoding, s, end, &next);
5278 return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
Haibo Huang40a71912019-10-11 11:13:39 -07005279 (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE);
5280 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005281#endif /* XML_DTD */
5282 {
Elliott Hughes72472942018-01-10 08:36:10 -08005283 parser->m_processor = contentProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005284 /* see externalEntityContentProcessor vs contentProcessor */
Haibo Huang40a71912019-10-11 11:13:39 -07005285 return doContent(parser, parser->m_parentParser ? 1 : 0, parser->m_encoding,
5286 s, end, nextPtr,
5287 (XML_Bool)! parser->m_parsingStatus.finalBuffer);
Elliott Hughes35e432d2012-09-09 14:23:38 -07005288 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005289}
5290
5291static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07005292errorProcessor(XML_Parser parser, const char *s, const char *end,
5293 const char **nextPtr) {
5294 UNUSED_P(s);
5295 UNUSED_P(end);
5296 UNUSED_P(nextPtr);
Elliott Hughes72472942018-01-10 08:36:10 -08005297 return parser->m_errorCode;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005298}
5299
5300static enum XML_Error
5301storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
Haibo Huang40a71912019-10-11 11:13:39 -07005302 const char *ptr, const char *end, STRING_POOL *pool) {
5303 enum XML_Error result
5304 = appendAttributeValue(parser, enc, isCdata, ptr, end, pool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005305 if (result)
5306 return result;
Haibo Huang40a71912019-10-11 11:13:39 -07005307 if (! isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005308 poolChop(pool);
Haibo Huang40a71912019-10-11 11:13:39 -07005309 if (! poolAppendChar(pool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005310 return XML_ERROR_NO_MEMORY;
5311 return XML_ERROR_NONE;
5312}
5313
5314static enum XML_Error
5315appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
Haibo Huang40a71912019-10-11 11:13:39 -07005316 const char *ptr, const char *end, STRING_POOL *pool) {
5317 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005318 for (;;) {
5319 const char *next;
5320 int tok = XmlAttributeValueTok(enc, ptr, end, &next);
5321 switch (tok) {
5322 case XML_TOK_NONE:
5323 return XML_ERROR_NONE;
5324 case XML_TOK_INVALID:
Elliott Hughes72472942018-01-10 08:36:10 -08005325 if (enc == parser->m_encoding)
5326 parser->m_eventPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005327 return XML_ERROR_INVALID_TOKEN;
5328 case XML_TOK_PARTIAL:
Elliott Hughes72472942018-01-10 08:36:10 -08005329 if (enc == parser->m_encoding)
5330 parser->m_eventPtr = ptr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005331 return XML_ERROR_INVALID_TOKEN;
Haibo Huang40a71912019-10-11 11:13:39 -07005332 case XML_TOK_CHAR_REF: {
5333 XML_Char buf[XML_ENCODE_MAX];
5334 int i;
5335 int n = XmlCharRefNumber(enc, ptr);
5336 if (n < 0) {
5337 if (enc == parser->m_encoding)
5338 parser->m_eventPtr = ptr;
5339 return XML_ERROR_BAD_CHAR_REF;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005340 }
Haibo Huang40a71912019-10-11 11:13:39 -07005341 if (! isCdata && n == 0x20 /* space */
5342 && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
5343 break;
5344 n = XmlEncode(n, (ICHAR *)buf);
5345 /* The XmlEncode() functions can never return 0 here. That
5346 * error return happens if the code point passed in is either
5347 * negative or greater than or equal to 0x110000. The
5348 * XmlCharRefNumber() functions will all return a number
5349 * strictly less than 0x110000 or a negative value if an error
5350 * occurred. The negative value is intercepted above, so
5351 * XmlEncode() is never passed a value it might return an
5352 * error for.
5353 */
5354 for (i = 0; i < n; i++) {
5355 if (! poolAppendChar(pool, buf[i]))
5356 return XML_ERROR_NO_MEMORY;
5357 }
5358 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005359 case XML_TOK_DATA_CHARS:
Haibo Huang40a71912019-10-11 11:13:39 -07005360 if (! poolAppend(pool, enc, ptr, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005361 return XML_ERROR_NO_MEMORY;
5362 break;
5363 case XML_TOK_TRAILING_CR:
5364 next = ptr + enc->minBytesPerChar;
5365 /* fall through */
5366 case XML_TOK_ATTRIBUTE_VALUE_S:
5367 case XML_TOK_DATA_NEWLINE:
Haibo Huang40a71912019-10-11 11:13:39 -07005368 if (! isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005369 break;
Haibo Huang40a71912019-10-11 11:13:39 -07005370 if (! poolAppendChar(pool, 0x20))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005371 return XML_ERROR_NO_MEMORY;
5372 break;
Haibo Huang40a71912019-10-11 11:13:39 -07005373 case XML_TOK_ENTITY_REF: {
5374 const XML_Char *name;
5375 ENTITY *entity;
5376 char checkEntityDecl;
5377 XML_Char ch = (XML_Char)XmlPredefinedEntityName(
5378 enc, ptr + enc->minBytesPerChar, next - enc->minBytesPerChar);
5379 if (ch) {
5380 if (! poolAppendChar(pool, ch))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005381 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07005382 break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005383 }
Haibo Huang40a71912019-10-11 11:13:39 -07005384 name = poolStoreString(&parser->m_temp2Pool, enc,
5385 ptr + enc->minBytesPerChar,
5386 next - enc->minBytesPerChar);
5387 if (! name)
5388 return XML_ERROR_NO_MEMORY;
5389 entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
5390 poolDiscard(&parser->m_temp2Pool);
5391 /* First, determine if a check for an existing declaration is needed;
5392 if yes, check that the entity exists, and that it is internal.
5393 */
5394 if (pool == &dtd->pool) /* are we called from prolog? */
5395 checkEntityDecl =
5396#ifdef XML_DTD
5397 parser->m_prologState.documentEntity &&
5398#endif /* XML_DTD */
5399 (dtd->standalone ? ! parser->m_openInternalEntities
5400 : ! dtd->hasParamEntityRefs);
5401 else /* if (pool == &parser->m_tempPool): we are called from content */
5402 checkEntityDecl = ! dtd->hasParamEntityRefs || dtd->standalone;
5403 if (checkEntityDecl) {
5404 if (! entity)
5405 return XML_ERROR_UNDEFINED_ENTITY;
5406 else if (! entity->is_internal)
5407 return XML_ERROR_ENTITY_DECLARED_IN_PE;
5408 } else if (! entity) {
5409 /* Cannot report skipped entity here - see comments on
5410 parser->m_skippedEntityHandler.
5411 if (parser->m_skippedEntityHandler)
5412 parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
5413 */
5414 /* Cannot call the default handler because this would be
5415 out of sync with the call to the startElementHandler.
5416 if ((pool == &parser->m_tempPool) && parser->m_defaultHandler)
5417 reportDefault(parser, enc, ptr, next);
5418 */
5419 break;
5420 }
5421 if (entity->open) {
5422 if (enc == parser->m_encoding) {
5423 /* It does not appear that this line can be executed.
5424 *
5425 * The "if (entity->open)" check catches recursive entity
5426 * definitions. In order to be called with an open
5427 * entity, it must have gone through this code before and
5428 * been through the recursive call to
5429 * appendAttributeValue() some lines below. That call
5430 * sets the local encoding ("enc") to the parser's
5431 * internal encoding (internal_utf8 or internal_utf16),
5432 * which can never be the same as the principle encoding.
5433 * It doesn't appear there is another code path that gets
5434 * here with entity->open being TRUE.
5435 *
5436 * Since it is not certain that this logic is watertight,
5437 * we keep the line and merely exclude it from coverage
5438 * tests.
5439 */
5440 parser->m_eventPtr = ptr; /* LCOV_EXCL_LINE */
5441 }
5442 return XML_ERROR_RECURSIVE_ENTITY_REF;
5443 }
5444 if (entity->notation) {
5445 if (enc == parser->m_encoding)
5446 parser->m_eventPtr = ptr;
5447 return XML_ERROR_BINARY_ENTITY_REF;
5448 }
5449 if (! entity->textPtr) {
5450 if (enc == parser->m_encoding)
5451 parser->m_eventPtr = ptr;
5452 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
5453 } else {
5454 enum XML_Error result;
5455 const XML_Char *textEnd = entity->textPtr + entity->textLen;
5456 entity->open = XML_TRUE;
5457 result = appendAttributeValue(parser, parser->m_internalEncoding,
Haibo Huangd1a324a2020-10-28 22:19:36 -07005458 isCdata, (const char *)entity->textPtr,
5459 (const char *)textEnd, pool);
Haibo Huang40a71912019-10-11 11:13:39 -07005460 entity->open = XML_FALSE;
5461 if (result)
5462 return result;
5463 }
5464 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005465 default:
Elliott Hughes72472942018-01-10 08:36:10 -08005466 /* The only token returned by XmlAttributeValueTok() that does
5467 * not have an explicit case here is XML_TOK_PARTIAL_CHAR.
5468 * Getting that would require an entity name to contain an
5469 * incomplete XML character (e.g. \xE2\x82); however previous
5470 * tokenisers will have already recognised and rejected such
5471 * names before XmlAttributeValueTok() gets a look-in. This
5472 * default case should be retained as a safety net, but the code
5473 * excluded from coverage tests.
5474 *
5475 * LCOV_EXCL_START
5476 */
5477 if (enc == parser->m_encoding)
5478 parser->m_eventPtr = ptr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005479 return XML_ERROR_UNEXPECTED_STATE;
Elliott Hughes72472942018-01-10 08:36:10 -08005480 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005481 }
5482 ptr = next;
5483 }
5484 /* not reached */
5485}
5486
5487static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07005488storeEntityValue(XML_Parser parser, const ENCODING *enc,
5489 const char *entityTextPtr, const char *entityTextEnd) {
5490 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005491 STRING_POOL *pool = &(dtd->entityValuePool);
5492 enum XML_Error result = XML_ERROR_NONE;
5493#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08005494 int oldInEntityValue = parser->m_prologState.inEntityValue;
5495 parser->m_prologState.inEntityValue = 1;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005496#endif /* XML_DTD */
5497 /* never return Null for the value argument in EntityDeclHandler,
5498 since this would indicate an external entity; therefore we
5499 have to make sure that entityValuePool.start is not null */
Haibo Huang40a71912019-10-11 11:13:39 -07005500 if (! pool->blocks) {
5501 if (! poolGrow(pool))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005502 return XML_ERROR_NO_MEMORY;
5503 }
5504
5505 for (;;) {
5506 const char *next;
5507 int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
5508 switch (tok) {
5509 case XML_TOK_PARAM_ENTITY_REF:
5510#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08005511 if (parser->m_isParamEntity || enc != parser->m_encoding) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005512 const XML_Char *name;
5513 ENTITY *entity;
Elliott Hughes72472942018-01-10 08:36:10 -08005514 name = poolStoreString(&parser->m_tempPool, enc,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005515 entityTextPtr + enc->minBytesPerChar,
5516 next - enc->minBytesPerChar);
Haibo Huang40a71912019-10-11 11:13:39 -07005517 if (! name) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005518 result = XML_ERROR_NO_MEMORY;
5519 goto endEntityValue;
5520 }
Elliott Hughes35e432d2012-09-09 14:23:38 -07005521 entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
Elliott Hughes72472942018-01-10 08:36:10 -08005522 poolDiscard(&parser->m_tempPool);
Haibo Huang40a71912019-10-11 11:13:39 -07005523 if (! entity) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005524 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
5525 /* cannot report skipped entity here - see comments on
Elliott Hughes72472942018-01-10 08:36:10 -08005526 parser->m_skippedEntityHandler
5527 if (parser->m_skippedEntityHandler)
5528 parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005529 */
5530 dtd->keepProcessing = dtd->standalone;
5531 goto endEntityValue;
5532 }
5533 if (entity->open) {
Elliott Hughes72472942018-01-10 08:36:10 -08005534 if (enc == parser->m_encoding)
5535 parser->m_eventPtr = entityTextPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005536 result = XML_ERROR_RECURSIVE_ENTITY_REF;
5537 goto endEntityValue;
5538 }
5539 if (entity->systemId) {
Elliott Hughes72472942018-01-10 08:36:10 -08005540 if (parser->m_externalEntityRefHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005541 dtd->paramEntityRead = XML_FALSE;
5542 entity->open = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07005543 if (! parser->m_externalEntityRefHandler(
5544 parser->m_externalEntityRefHandlerArg, 0, entity->base,
5545 entity->systemId, entity->publicId)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005546 entity->open = XML_FALSE;
5547 result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
5548 goto endEntityValue;
5549 }
5550 entity->open = XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07005551 if (! dtd->paramEntityRead)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005552 dtd->keepProcessing = dtd->standalone;
Haibo Huang40a71912019-10-11 11:13:39 -07005553 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005554 dtd->keepProcessing = dtd->standalone;
Haibo Huang40a71912019-10-11 11:13:39 -07005555 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005556 entity->open = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07005557 result = storeEntityValue(
Haibo Huangd1a324a2020-10-28 22:19:36 -07005558 parser, parser->m_internalEncoding, (const char *)entity->textPtr,
5559 (const char *)(entity->textPtr + entity->textLen));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005560 entity->open = XML_FALSE;
5561 if (result)
5562 goto endEntityValue;
5563 }
5564 break;
5565 }
5566#endif /* XML_DTD */
5567 /* In the internal subset, PE references are not legal
5568 within markup declarations, e.g entity values in this case. */
Elliott Hughes72472942018-01-10 08:36:10 -08005569 parser->m_eventPtr = entityTextPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005570 result = XML_ERROR_PARAM_ENTITY_REF;
5571 goto endEntityValue;
5572 case XML_TOK_NONE:
5573 result = XML_ERROR_NONE;
5574 goto endEntityValue;
5575 case XML_TOK_ENTITY_REF:
5576 case XML_TOK_DATA_CHARS:
Haibo Huang40a71912019-10-11 11:13:39 -07005577 if (! poolAppend(pool, enc, entityTextPtr, next)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005578 result = XML_ERROR_NO_MEMORY;
5579 goto endEntityValue;
5580 }
5581 break;
5582 case XML_TOK_TRAILING_CR:
5583 next = entityTextPtr + enc->minBytesPerChar;
5584 /* fall through */
5585 case XML_TOK_DATA_NEWLINE:
Haibo Huang40a71912019-10-11 11:13:39 -07005586 if (pool->end == pool->ptr && ! poolGrow(pool)) {
5587 result = XML_ERROR_NO_MEMORY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005588 goto endEntityValue;
5589 }
5590 *(pool->ptr)++ = 0xA;
5591 break;
Haibo Huang40a71912019-10-11 11:13:39 -07005592 case XML_TOK_CHAR_REF: {
5593 XML_Char buf[XML_ENCODE_MAX];
5594 int i;
5595 int n = XmlCharRefNumber(enc, entityTextPtr);
5596 if (n < 0) {
5597 if (enc == parser->m_encoding)
5598 parser->m_eventPtr = entityTextPtr;
5599 result = XML_ERROR_BAD_CHAR_REF;
5600 goto endEntityValue;
5601 }
5602 n = XmlEncode(n, (ICHAR *)buf);
5603 /* The XmlEncode() functions can never return 0 here. That
5604 * error return happens if the code point passed in is either
5605 * negative or greater than or equal to 0x110000. The
5606 * XmlCharRefNumber() functions will all return a number
5607 * strictly less than 0x110000 or a negative value if an error
5608 * occurred. The negative value is intercepted above, so
5609 * XmlEncode() is never passed a value it might return an
5610 * error for.
5611 */
5612 for (i = 0; i < n; i++) {
5613 if (pool->end == pool->ptr && ! poolGrow(pool)) {
5614 result = XML_ERROR_NO_MEMORY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005615 goto endEntityValue;
5616 }
Haibo Huang40a71912019-10-11 11:13:39 -07005617 *(pool->ptr)++ = buf[i];
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005618 }
Haibo Huang40a71912019-10-11 11:13:39 -07005619 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005620 case XML_TOK_PARTIAL:
Elliott Hughes72472942018-01-10 08:36:10 -08005621 if (enc == parser->m_encoding)
5622 parser->m_eventPtr = entityTextPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005623 result = XML_ERROR_INVALID_TOKEN;
5624 goto endEntityValue;
5625 case XML_TOK_INVALID:
Elliott Hughes72472942018-01-10 08:36:10 -08005626 if (enc == parser->m_encoding)
5627 parser->m_eventPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005628 result = XML_ERROR_INVALID_TOKEN;
5629 goto endEntityValue;
5630 default:
Elliott Hughes72472942018-01-10 08:36:10 -08005631 /* This default case should be unnecessary -- all the tokens
5632 * that XmlEntityValueTok() can return have their own explicit
5633 * cases -- but should be retained for safety. We do however
5634 * exclude it from the coverage statistics.
5635 *
5636 * LCOV_EXCL_START
5637 */
5638 if (enc == parser->m_encoding)
5639 parser->m_eventPtr = entityTextPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005640 result = XML_ERROR_UNEXPECTED_STATE;
5641 goto endEntityValue;
Elliott Hughes72472942018-01-10 08:36:10 -08005642 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005643 }
5644 entityTextPtr = next;
5645 }
5646endEntityValue:
5647#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08005648 parser->m_prologState.inEntityValue = oldInEntityValue;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005649#endif /* XML_DTD */
5650 return result;
5651}
5652
5653static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07005654normalizeLines(XML_Char *s) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005655 XML_Char *p;
5656 for (;; s++) {
5657 if (*s == XML_T('\0'))
5658 return;
5659 if (*s == 0xD)
5660 break;
5661 }
5662 p = s;
5663 do {
5664 if (*s == 0xD) {
5665 *p++ = 0xA;
5666 if (*++s == 0xA)
5667 s++;
Haibo Huang40a71912019-10-11 11:13:39 -07005668 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005669 *p++ = *s++;
5670 } while (*s);
5671 *p = XML_T('\0');
5672}
5673
5674static int
5675reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
Haibo Huang40a71912019-10-11 11:13:39 -07005676 const char *start, const char *end) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005677 const XML_Char *target;
5678 XML_Char *data;
5679 const char *tem;
Haibo Huang40a71912019-10-11 11:13:39 -07005680 if (! parser->m_processingInstructionHandler) {
Elliott Hughes72472942018-01-10 08:36:10 -08005681 if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005682 reportDefault(parser, enc, start, end);
5683 return 1;
5684 }
5685 start += enc->minBytesPerChar * 2;
5686 tem = start + XmlNameLength(enc, start);
Elliott Hughes72472942018-01-10 08:36:10 -08005687 target = poolStoreString(&parser->m_tempPool, enc, start, tem);
Haibo Huang40a71912019-10-11 11:13:39 -07005688 if (! target)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005689 return 0;
Elliott Hughes72472942018-01-10 08:36:10 -08005690 poolFinish(&parser->m_tempPool);
Haibo Huang40a71912019-10-11 11:13:39 -07005691 data = poolStoreString(&parser->m_tempPool, enc, XmlSkipS(enc, tem),
5692 end - enc->minBytesPerChar * 2);
5693 if (! data)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005694 return 0;
5695 normalizeLines(data);
Elliott Hughes72472942018-01-10 08:36:10 -08005696 parser->m_processingInstructionHandler(parser->m_handlerArg, target, data);
5697 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005698 return 1;
5699}
5700
5701static int
Haibo Huang40a71912019-10-11 11:13:39 -07005702reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
5703 const char *end) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005704 XML_Char *data;
Haibo Huang40a71912019-10-11 11:13:39 -07005705 if (! parser->m_commentHandler) {
Elliott Hughes72472942018-01-10 08:36:10 -08005706 if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005707 reportDefault(parser, enc, start, end);
5708 return 1;
5709 }
Haibo Huang40a71912019-10-11 11:13:39 -07005710 data = poolStoreString(&parser->m_tempPool, enc,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005711 start + enc->minBytesPerChar * 4,
5712 end - enc->minBytesPerChar * 3);
Haibo Huang40a71912019-10-11 11:13:39 -07005713 if (! data)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005714 return 0;
5715 normalizeLines(data);
Elliott Hughes72472942018-01-10 08:36:10 -08005716 parser->m_commentHandler(parser->m_handlerArg, data);
5717 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005718 return 1;
5719}
5720
5721static void
Haibo Huang40a71912019-10-11 11:13:39 -07005722reportDefault(XML_Parser parser, const ENCODING *enc, const char *s,
5723 const char *end) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005724 if (MUST_CONVERT(enc, s)) {
Paul Duffin4bf8f122016-05-13 12:35:25 +01005725 enum XML_Convert_Result convert_res;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005726 const char **eventPP;
5727 const char **eventEndPP;
Elliott Hughes72472942018-01-10 08:36:10 -08005728 if (enc == parser->m_encoding) {
5729 eventPP = &parser->m_eventPtr;
5730 eventEndPP = &parser->m_eventEndPtr;
Haibo Huang40a71912019-10-11 11:13:39 -07005731 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08005732 /* To get here, two things must be true; the parser must be
5733 * using a character encoding that is not the same as the
5734 * encoding passed in, and the encoding passed in must need
5735 * conversion to the internal format (UTF-8 unless XML_UNICODE
5736 * is defined). The only occasions on which the encoding passed
5737 * in is not the same as the parser's encoding are when it is
5738 * the internal encoding (e.g. a previously defined parameter
5739 * entity, already converted to internal format). This by
5740 * definition doesn't need conversion, so the whole branch never
5741 * gets executed.
5742 *
5743 * For safety's sake we don't delete these lines and merely
5744 * exclude them from coverage statistics.
5745 *
5746 * LCOV_EXCL_START
5747 */
5748 eventPP = &(parser->m_openInternalEntities->internalEventPtr);
5749 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
5750 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005751 }
5752 do {
Elliott Hughes72472942018-01-10 08:36:10 -08005753 ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
Haibo Huang40a71912019-10-11 11:13:39 -07005754 convert_res
5755 = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005756 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07005757 parser->m_defaultHandler(parser->m_handlerArg, parser->m_dataBuf,
5758 (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005759 *eventPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07005760 } while ((convert_res != XML_CONVERT_COMPLETED)
5761 && (convert_res != XML_CONVERT_INPUT_INCOMPLETE));
5762 } else
5763 parser->m_defaultHandler(parser->m_handlerArg, (XML_Char *)s,
5764 (int)((XML_Char *)end - (XML_Char *)s));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005765}
5766
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005767static int
5768defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
Haibo Huang40a71912019-10-11 11:13:39 -07005769 XML_Bool isId, const XML_Char *value, XML_Parser parser) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005770 DEFAULT_ATTRIBUTE *att;
5771 if (value || isId) {
5772 /* The handling of default attributes gets messed up if we have
5773 a default which duplicates a non-default. */
5774 int i;
5775 for (i = 0; i < type->nDefaultAtts; i++)
5776 if (attId == type->defaultAtts[i].id)
5777 return 1;
Haibo Huang40a71912019-10-11 11:13:39 -07005778 if (isId && ! type->idAtt && ! attId->xmlns)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005779 type->idAtt = attId;
5780 }
5781 if (type->nDefaultAtts == type->allocDefaultAtts) {
5782 if (type->allocDefaultAtts == 0) {
5783 type->allocDefaultAtts = 8;
Haibo Huang40a71912019-10-11 11:13:39 -07005784 type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(
5785 parser, type->allocDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
5786 if (! type->defaultAtts) {
Elliott Hughes72472942018-01-10 08:36:10 -08005787 type->allocDefaultAtts = 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005788 return 0;
Elliott Hughes72472942018-01-10 08:36:10 -08005789 }
Haibo Huang40a71912019-10-11 11:13:39 -07005790 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005791 DEFAULT_ATTRIBUTE *temp;
5792 int count = type->allocDefaultAtts * 2;
Haibo Huang40a71912019-10-11 11:13:39 -07005793 temp = (DEFAULT_ATTRIBUTE *)REALLOC(parser, type->defaultAtts,
5794 (count * sizeof(DEFAULT_ATTRIBUTE)));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005795 if (temp == NULL)
5796 return 0;
5797 type->allocDefaultAtts = count;
5798 type->defaultAtts = temp;
5799 }
5800 }
5801 att = type->defaultAtts + type->nDefaultAtts;
5802 att->id = attId;
5803 att->value = value;
5804 att->isCdata = isCdata;
Haibo Huang40a71912019-10-11 11:13:39 -07005805 if (! isCdata)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005806 attId->maybeTokenized = XML_TRUE;
5807 type->nDefaultAtts += 1;
5808 return 1;
5809}
5810
5811static int
Haibo Huang40a71912019-10-11 11:13:39 -07005812setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType) {
5813 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005814 const XML_Char *name;
5815 for (name = elementType->name; *name; name++) {
Elliott Hughesd07d5a72009-09-25 16:04:37 -07005816 if (*name == XML_T(ASCII_COLON)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005817 PREFIX *prefix;
5818 const XML_Char *s;
5819 for (s = elementType->name; s != name; s++) {
Haibo Huang40a71912019-10-11 11:13:39 -07005820 if (! poolAppendChar(&dtd->pool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005821 return 0;
5822 }
Haibo Huang40a71912019-10-11 11:13:39 -07005823 if (! poolAppendChar(&dtd->pool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005824 return 0;
Elliott Hughes35e432d2012-09-09 14:23:38 -07005825 prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005826 sizeof(PREFIX));
Haibo Huang40a71912019-10-11 11:13:39 -07005827 if (! prefix)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005828 return 0;
5829 if (prefix->name == poolStart(&dtd->pool))
5830 poolFinish(&dtd->pool);
5831 else
5832 poolDiscard(&dtd->pool);
5833 elementType->prefix = prefix;
Haibo Huangfd5e81a2019-06-20 12:09:36 -07005834 break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005835 }
5836 }
5837 return 1;
5838}
5839
5840static ATTRIBUTE_ID *
Haibo Huang40a71912019-10-11 11:13:39 -07005841getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
5842 const char *end) {
5843 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005844 ATTRIBUTE_ID *id;
5845 const XML_Char *name;
Haibo Huang40a71912019-10-11 11:13:39 -07005846 if (! poolAppendChar(&dtd->pool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005847 return NULL;
5848 name = poolStoreString(&dtd->pool, enc, start, end);
Haibo Huang40a71912019-10-11 11:13:39 -07005849 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005850 return NULL;
5851 /* skip quotation mark - its storage will be re-used (like in name[-1]) */
5852 ++name;
Haibo Huang40a71912019-10-11 11:13:39 -07005853 id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name,
5854 sizeof(ATTRIBUTE_ID));
5855 if (! id)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005856 return NULL;
5857 if (id->name != name)
5858 poolDiscard(&dtd->pool);
5859 else {
5860 poolFinish(&dtd->pool);
Haibo Huang40a71912019-10-11 11:13:39 -07005861 if (! parser->m_ns)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005862 ;
Haibo Huang40a71912019-10-11 11:13:39 -07005863 else if (name[0] == XML_T(ASCII_x) && name[1] == XML_T(ASCII_m)
5864 && name[2] == XML_T(ASCII_l) && name[3] == XML_T(ASCII_n)
5865 && name[4] == XML_T(ASCII_s)
5866 && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005867 if (name[5] == XML_T('\0'))
5868 id->prefix = &dtd->defaultPrefix;
5869 else
Haibo Huang40a71912019-10-11 11:13:39 -07005870 id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6,
5871 sizeof(PREFIX));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005872 id->xmlns = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07005873 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005874 int i;
5875 for (i = 0; name[i]; i++) {
5876 /* attributes without prefix are *not* in the default namespace */
Elliott Hughesd07d5a72009-09-25 16:04:37 -07005877 if (name[i] == XML_T(ASCII_COLON)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005878 int j;
5879 for (j = 0; j < i; j++) {
Haibo Huang40a71912019-10-11 11:13:39 -07005880 if (! poolAppendChar(&dtd->pool, name[j]))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005881 return NULL;
5882 }
Haibo Huang40a71912019-10-11 11:13:39 -07005883 if (! poolAppendChar(&dtd->pool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005884 return NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07005885 id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes,
5886 poolStart(&dtd->pool), sizeof(PREFIX));
5887 if (! id->prefix)
Paul Duffinc05e0322016-05-04 10:42:31 +01005888 return NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005889 if (id->prefix->name == poolStart(&dtd->pool))
5890 poolFinish(&dtd->pool);
5891 else
5892 poolDiscard(&dtd->pool);
5893 break;
5894 }
5895 }
5896 }
5897 }
5898 return id;
5899}
5900
Elliott Hughesd07d5a72009-09-25 16:04:37 -07005901#define CONTEXT_SEP XML_T(ASCII_FF)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005902
5903static const XML_Char *
Haibo Huang40a71912019-10-11 11:13:39 -07005904getContext(XML_Parser parser) {
5905 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005906 HASH_TABLE_ITER iter;
5907 XML_Bool needSep = XML_FALSE;
5908
5909 if (dtd->defaultPrefix.binding) {
5910 int i;
5911 int len;
Haibo Huang40a71912019-10-11 11:13:39 -07005912 if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS)))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005913 return NULL;
5914 len = dtd->defaultPrefix.binding->uriLen;
Elliott Hughes72472942018-01-10 08:36:10 -08005915 if (parser->m_namespaceSeparator)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005916 len--;
Elliott Hughes72472942018-01-10 08:36:10 -08005917 for (i = 0; i < len; i++) {
Haibo Huang40a71912019-10-11 11:13:39 -07005918 if (! poolAppendChar(&parser->m_tempPool,
5919 dtd->defaultPrefix.binding->uri[i])) {
Elliott Hughes72472942018-01-10 08:36:10 -08005920 /* Because of memory caching, I don't believe this line can be
5921 * executed.
5922 *
5923 * This is part of a loop copying the default prefix binding
5924 * URI into the parser's temporary string pool. Previously,
5925 * that URI was copied into the same string pool, with a
5926 * terminating NUL character, as part of setContext(). When
5927 * the pool was cleared, that leaves a block definitely big
5928 * enough to hold the URI on the free block list of the pool.
5929 * The URI copy in getContext() therefore cannot run out of
5930 * memory.
5931 *
5932 * If the pool is used between the setContext() and
5933 * getContext() calls, the worst it can do is leave a bigger
5934 * block on the front of the free list. Given that this is
5935 * all somewhat inobvious and program logic can be changed, we
5936 * don't delete the line but we do exclude it from the test
5937 * coverage statistics.
5938 */
5939 return NULL; /* LCOV_EXCL_LINE */
5940 }
5941 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005942 needSep = XML_TRUE;
5943 }
5944
5945 hashTableIterInit(&iter, &(dtd->prefixes));
5946 for (;;) {
5947 int i;
5948 int len;
5949 const XML_Char *s;
5950 PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07005951 if (! prefix)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005952 break;
Haibo Huang40a71912019-10-11 11:13:39 -07005953 if (! prefix->binding) {
Elliott Hughes72472942018-01-10 08:36:10 -08005954 /* This test appears to be (justifiable) paranoia. There does
5955 * not seem to be a way of injecting a prefix without a binding
5956 * that doesn't get errored long before this function is called.
5957 * The test should remain for safety's sake, so we instead
5958 * exclude the following line from the coverage statistics.
5959 */
5960 continue; /* LCOV_EXCL_LINE */
5961 }
Haibo Huang40a71912019-10-11 11:13:39 -07005962 if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005963 return NULL;
5964 for (s = prefix->name; *s; s++)
Haibo Huang40a71912019-10-11 11:13:39 -07005965 if (! poolAppendChar(&parser->m_tempPool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005966 return NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07005967 if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS)))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005968 return NULL;
5969 len = prefix->binding->uriLen;
Elliott Hughes72472942018-01-10 08:36:10 -08005970 if (parser->m_namespaceSeparator)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005971 len--;
5972 for (i = 0; i < len; i++)
Haibo Huang40a71912019-10-11 11:13:39 -07005973 if (! poolAppendChar(&parser->m_tempPool, prefix->binding->uri[i]))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005974 return NULL;
5975 needSep = XML_TRUE;
5976 }
5977
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005978 hashTableIterInit(&iter, &(dtd->generalEntities));
5979 for (;;) {
5980 const XML_Char *s;
5981 ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07005982 if (! e)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005983 break;
Haibo Huang40a71912019-10-11 11:13:39 -07005984 if (! e->open)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005985 continue;
Haibo Huang40a71912019-10-11 11:13:39 -07005986 if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005987 return NULL;
5988 for (s = e->name; *s; s++)
Haibo Huang40a71912019-10-11 11:13:39 -07005989 if (! poolAppendChar(&parser->m_tempPool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005990 return 0;
5991 needSep = XML_TRUE;
5992 }
5993
Haibo Huang40a71912019-10-11 11:13:39 -07005994 if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005995 return NULL;
Elliott Hughes72472942018-01-10 08:36:10 -08005996 return parser->m_tempPool.start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005997}
5998
5999static XML_Bool
Haibo Huang40a71912019-10-11 11:13:39 -07006000setContext(XML_Parser parser, const XML_Char *context) {
6001 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006002 const XML_Char *s = context;
6003
6004 while (*context != XML_T('\0')) {
6005 if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
6006 ENTITY *e;
Haibo Huang40a71912019-10-11 11:13:39 -07006007 if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006008 return XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07006009 e = (ENTITY *)lookup(parser, &dtd->generalEntities,
6010 poolStart(&parser->m_tempPool), 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006011 if (e)
6012 e->open = XML_TRUE;
6013 if (*s != XML_T('\0'))
6014 s++;
6015 context = s;
Elliott Hughes72472942018-01-10 08:36:10 -08006016 poolDiscard(&parser->m_tempPool);
Haibo Huang40a71912019-10-11 11:13:39 -07006017 } else if (*s == XML_T(ASCII_EQUALS)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006018 PREFIX *prefix;
Elliott Hughes72472942018-01-10 08:36:10 -08006019 if (poolLength(&parser->m_tempPool) == 0)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006020 prefix = &dtd->defaultPrefix;
6021 else {
Haibo Huang40a71912019-10-11 11:13:39 -07006022 if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006023 return XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07006024 prefix
6025 = (PREFIX *)lookup(parser, &dtd->prefixes,
6026 poolStart(&parser->m_tempPool), sizeof(PREFIX));
6027 if (! prefix)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006028 return XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08006029 if (prefix->name == poolStart(&parser->m_tempPool)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006030 prefix->name = poolCopyString(&dtd->pool, prefix->name);
Haibo Huang40a71912019-10-11 11:13:39 -07006031 if (! prefix->name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006032 return XML_FALSE;
6033 }
Elliott Hughes72472942018-01-10 08:36:10 -08006034 poolDiscard(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006035 }
Haibo Huang40a71912019-10-11 11:13:39 -07006036 for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0');
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006037 context++)
Haibo Huang40a71912019-10-11 11:13:39 -07006038 if (! poolAppendChar(&parser->m_tempPool, *context))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006039 return XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07006040 if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006041 return XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08006042 if (addBinding(parser, prefix, NULL, poolStart(&parser->m_tempPool),
Haibo Huang40a71912019-10-11 11:13:39 -07006043 &parser->m_inheritedBindings)
6044 != XML_ERROR_NONE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006045 return XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08006046 poolDiscard(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006047 if (*context != XML_T('\0'))
6048 ++context;
6049 s = context;
Haibo Huang40a71912019-10-11 11:13:39 -07006050 } else {
6051 if (! poolAppendChar(&parser->m_tempPool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006052 return XML_FALSE;
6053 s++;
6054 }
6055 }
6056 return XML_TRUE;
6057}
6058
6059static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006060normalizePublicId(XML_Char *publicId) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006061 XML_Char *p = publicId;
6062 XML_Char *s;
6063 for (s = publicId; *s; s++) {
6064 switch (*s) {
6065 case 0x20:
6066 case 0xD:
6067 case 0xA:
6068 if (p != publicId && p[-1] != 0x20)
6069 *p++ = 0x20;
6070 break;
6071 default:
6072 *p++ = *s;
6073 }
6074 }
6075 if (p != publicId && p[-1] == 0x20)
6076 --p;
6077 *p = XML_T('\0');
6078}
6079
6080static DTD *
Haibo Huang40a71912019-10-11 11:13:39 -07006081dtdCreate(const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006082 DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
6083 if (p == NULL)
6084 return p;
6085 poolInit(&(p->pool), ms);
6086 poolInit(&(p->entityValuePool), ms);
6087 hashTableInit(&(p->generalEntities), ms);
6088 hashTableInit(&(p->elementTypes), ms);
6089 hashTableInit(&(p->attributeIds), ms);
6090 hashTableInit(&(p->prefixes), ms);
6091#ifdef XML_DTD
6092 p->paramEntityRead = XML_FALSE;
6093 hashTableInit(&(p->paramEntities), ms);
6094#endif /* XML_DTD */
6095 p->defaultPrefix.name = NULL;
6096 p->defaultPrefix.binding = NULL;
6097
6098 p->in_eldecl = XML_FALSE;
6099 p->scaffIndex = NULL;
6100 p->scaffold = NULL;
6101 p->scaffLevel = 0;
6102 p->scaffSize = 0;
6103 p->scaffCount = 0;
6104 p->contentStringLen = 0;
6105
6106 p->keepProcessing = XML_TRUE;
6107 p->hasParamEntityRefs = XML_FALSE;
6108 p->standalone = XML_FALSE;
6109 return p;
6110}
6111
6112static void
Haibo Huang40a71912019-10-11 11:13:39 -07006113dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006114 HASH_TABLE_ITER iter;
6115 hashTableIterInit(&iter, &(p->elementTypes));
6116 for (;;) {
6117 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006118 if (! e)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006119 break;
6120 if (e->allocDefaultAtts != 0)
6121 ms->free_fcn(e->defaultAtts);
6122 }
6123 hashTableClear(&(p->generalEntities));
6124#ifdef XML_DTD
6125 p->paramEntityRead = XML_FALSE;
6126 hashTableClear(&(p->paramEntities));
6127#endif /* XML_DTD */
6128 hashTableClear(&(p->elementTypes));
6129 hashTableClear(&(p->attributeIds));
6130 hashTableClear(&(p->prefixes));
6131 poolClear(&(p->pool));
6132 poolClear(&(p->entityValuePool));
6133 p->defaultPrefix.name = NULL;
6134 p->defaultPrefix.binding = NULL;
6135
6136 p->in_eldecl = XML_FALSE;
6137
6138 ms->free_fcn(p->scaffIndex);
6139 p->scaffIndex = NULL;
6140 ms->free_fcn(p->scaffold);
6141 p->scaffold = NULL;
6142
6143 p->scaffLevel = 0;
6144 p->scaffSize = 0;
6145 p->scaffCount = 0;
6146 p->contentStringLen = 0;
6147
6148 p->keepProcessing = XML_TRUE;
6149 p->hasParamEntityRefs = XML_FALSE;
6150 p->standalone = XML_FALSE;
6151}
6152
6153static void
Haibo Huang40a71912019-10-11 11:13:39 -07006154dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006155 HASH_TABLE_ITER iter;
6156 hashTableIterInit(&iter, &(p->elementTypes));
6157 for (;;) {
6158 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006159 if (! e)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006160 break;
6161 if (e->allocDefaultAtts != 0)
6162 ms->free_fcn(e->defaultAtts);
6163 }
6164 hashTableDestroy(&(p->generalEntities));
6165#ifdef XML_DTD
6166 hashTableDestroy(&(p->paramEntities));
6167#endif /* XML_DTD */
6168 hashTableDestroy(&(p->elementTypes));
6169 hashTableDestroy(&(p->attributeIds));
6170 hashTableDestroy(&(p->prefixes));
6171 poolDestroy(&(p->pool));
6172 poolDestroy(&(p->entityValuePool));
6173 if (isDocEntity) {
6174 ms->free_fcn(p->scaffIndex);
6175 ms->free_fcn(p->scaffold);
6176 }
6177 ms->free_fcn(p);
6178}
6179
6180/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
6181 The new DTD has already been initialized.
6182*/
6183static int
Haibo Huang40a71912019-10-11 11:13:39 -07006184dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
6185 const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006186 HASH_TABLE_ITER iter;
6187
6188 /* Copy the prefix table. */
6189
6190 hashTableIterInit(&iter, &(oldDtd->prefixes));
6191 for (;;) {
6192 const XML_Char *name;
6193 const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006194 if (! oldP)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006195 break;
6196 name = poolCopyString(&(newDtd->pool), oldP->name);
Haibo Huang40a71912019-10-11 11:13:39 -07006197 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006198 return 0;
Haibo Huang40a71912019-10-11 11:13:39 -07006199 if (! lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX)))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006200 return 0;
6201 }
6202
6203 hashTableIterInit(&iter, &(oldDtd->attributeIds));
6204
6205 /* Copy the attribute id table. */
6206
6207 for (;;) {
6208 ATTRIBUTE_ID *newA;
6209 const XML_Char *name;
6210 const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
6211
Haibo Huang40a71912019-10-11 11:13:39 -07006212 if (! oldA)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006213 break;
6214 /* Remember to allocate the scratch byte before the name. */
Haibo Huang40a71912019-10-11 11:13:39 -07006215 if (! poolAppendChar(&(newDtd->pool), XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006216 return 0;
6217 name = poolCopyString(&(newDtd->pool), oldA->name);
Haibo Huang40a71912019-10-11 11:13:39 -07006218 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006219 return 0;
6220 ++name;
Elliott Hughes35e432d2012-09-09 14:23:38 -07006221 newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006222 sizeof(ATTRIBUTE_ID));
Haibo Huang40a71912019-10-11 11:13:39 -07006223 if (! newA)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006224 return 0;
6225 newA->maybeTokenized = oldA->maybeTokenized;
6226 if (oldA->prefix) {
6227 newA->xmlns = oldA->xmlns;
6228 if (oldA->prefix == &oldDtd->defaultPrefix)
6229 newA->prefix = &newDtd->defaultPrefix;
6230 else
Elliott Hughes35e432d2012-09-09 14:23:38 -07006231 newA->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006232 oldA->prefix->name, 0);
6233 }
6234 }
6235
6236 /* Copy the element type table. */
6237
6238 hashTableIterInit(&iter, &(oldDtd->elementTypes));
6239
6240 for (;;) {
6241 int i;
6242 ELEMENT_TYPE *newE;
6243 const XML_Char *name;
6244 const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006245 if (! oldE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006246 break;
6247 name = poolCopyString(&(newDtd->pool), oldE->name);
Haibo Huang40a71912019-10-11 11:13:39 -07006248 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006249 return 0;
Elliott Hughes35e432d2012-09-09 14:23:38 -07006250 newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006251 sizeof(ELEMENT_TYPE));
Haibo Huang40a71912019-10-11 11:13:39 -07006252 if (! newE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006253 return 0;
6254 if (oldE->nDefaultAtts) {
Haibo Huang40a71912019-10-11 11:13:39 -07006255 newE->defaultAtts = (DEFAULT_ATTRIBUTE *)ms->malloc_fcn(
6256 oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
6257 if (! newE->defaultAtts) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006258 return 0;
6259 }
6260 }
6261 if (oldE->idAtt)
Haibo Huang40a71912019-10-11 11:13:39 -07006262 newE->idAtt = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds),
6263 oldE->idAtt->name, 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006264 newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
6265 if (oldE->prefix)
Elliott Hughes35e432d2012-09-09 14:23:38 -07006266 newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006267 oldE->prefix->name, 0);
6268 for (i = 0; i < newE->nDefaultAtts; i++) {
Haibo Huang40a71912019-10-11 11:13:39 -07006269 newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup(
6270 oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006271 newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
6272 if (oldE->defaultAtts[i].value) {
6273 newE->defaultAtts[i].value
6274 = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
Haibo Huang40a71912019-10-11 11:13:39 -07006275 if (! newE->defaultAtts[i].value)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006276 return 0;
Haibo Huang40a71912019-10-11 11:13:39 -07006277 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006278 newE->defaultAtts[i].value = NULL;
6279 }
6280 }
6281
6282 /* Copy the entity tables. */
Haibo Huang40a71912019-10-11 11:13:39 -07006283 if (! copyEntityTable(oldParser, &(newDtd->generalEntities), &(newDtd->pool),
6284 &(oldDtd->generalEntities)))
6285 return 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006286
6287#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07006288 if (! copyEntityTable(oldParser, &(newDtd->paramEntities), &(newDtd->pool),
6289 &(oldDtd->paramEntities)))
6290 return 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006291 newDtd->paramEntityRead = oldDtd->paramEntityRead;
6292#endif /* XML_DTD */
6293
6294 newDtd->keepProcessing = oldDtd->keepProcessing;
6295 newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
6296 newDtd->standalone = oldDtd->standalone;
6297
6298 /* Don't want deep copying for scaffolding */
6299 newDtd->in_eldecl = oldDtd->in_eldecl;
6300 newDtd->scaffold = oldDtd->scaffold;
6301 newDtd->contentStringLen = oldDtd->contentStringLen;
6302 newDtd->scaffSize = oldDtd->scaffSize;
6303 newDtd->scaffLevel = oldDtd->scaffLevel;
6304 newDtd->scaffIndex = oldDtd->scaffIndex;
6305
6306 return 1;
Haibo Huang40a71912019-10-11 11:13:39 -07006307} /* End dtdCopy */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006308
6309static int
Haibo Huang40a71912019-10-11 11:13:39 -07006310copyEntityTable(XML_Parser oldParser, HASH_TABLE *newTable,
6311 STRING_POOL *newPool, const HASH_TABLE *oldTable) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006312 HASH_TABLE_ITER iter;
6313 const XML_Char *cachedOldBase = NULL;
6314 const XML_Char *cachedNewBase = NULL;
6315
6316 hashTableIterInit(&iter, oldTable);
6317
6318 for (;;) {
6319 ENTITY *newE;
6320 const XML_Char *name;
6321 const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006322 if (! oldE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006323 break;
6324 name = poolCopyString(newPool, oldE->name);
Haibo Huang40a71912019-10-11 11:13:39 -07006325 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006326 return 0;
Elliott Hughes35e432d2012-09-09 14:23:38 -07006327 newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY));
Haibo Huang40a71912019-10-11 11:13:39 -07006328 if (! newE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006329 return 0;
6330 if (oldE->systemId) {
6331 const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
Haibo Huang40a71912019-10-11 11:13:39 -07006332 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006333 return 0;
6334 newE->systemId = tem;
6335 if (oldE->base) {
6336 if (oldE->base == cachedOldBase)
6337 newE->base = cachedNewBase;
6338 else {
6339 cachedOldBase = oldE->base;
6340 tem = poolCopyString(newPool, cachedOldBase);
Haibo Huang40a71912019-10-11 11:13:39 -07006341 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006342 return 0;
6343 cachedNewBase = newE->base = tem;
6344 }
6345 }
6346 if (oldE->publicId) {
6347 tem = poolCopyString(newPool, oldE->publicId);
Haibo Huang40a71912019-10-11 11:13:39 -07006348 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006349 return 0;
6350 newE->publicId = tem;
6351 }
Haibo Huang40a71912019-10-11 11:13:39 -07006352 } else {
6353 const XML_Char *tem
6354 = poolCopyStringN(newPool, oldE->textPtr, oldE->textLen);
6355 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006356 return 0;
6357 newE->textPtr = tem;
6358 newE->textLen = oldE->textLen;
6359 }
6360 if (oldE->notation) {
6361 const XML_Char *tem = poolCopyString(newPool, oldE->notation);
Haibo Huang40a71912019-10-11 11:13:39 -07006362 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006363 return 0;
6364 newE->notation = tem;
6365 }
6366 newE->is_param = oldE->is_param;
6367 newE->is_internal = oldE->is_internal;
6368 }
6369 return 1;
6370}
6371
6372#define INIT_POWER 6
6373
6374static XML_Bool FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006375keyeq(KEY s1, KEY s2) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006376 for (; *s1 == *s2; s1++, s2++)
6377 if (*s1 == 0)
6378 return XML_TRUE;
6379 return XML_FALSE;
6380}
6381
Elliott Hughes72472942018-01-10 08:36:10 -08006382static size_t
Haibo Huang40a71912019-10-11 11:13:39 -07006383keylen(KEY s) {
Elliott Hughes72472942018-01-10 08:36:10 -08006384 size_t len = 0;
Haibo Huang40a71912019-10-11 11:13:39 -07006385 for (; *s; s++, len++)
6386 ;
Elliott Hughes72472942018-01-10 08:36:10 -08006387 return len;
6388}
6389
6390static void
Haibo Huang40a71912019-10-11 11:13:39 -07006391copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key) {
Elliott Hughes72472942018-01-10 08:36:10 -08006392 key->k[0] = 0;
6393 key->k[1] = get_hash_secret_salt(parser);
6394}
6395
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006396static unsigned long FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006397hash(XML_Parser parser, KEY s) {
Elliott Hughes72472942018-01-10 08:36:10 -08006398 struct siphash state;
6399 struct sipkey key;
Elliott Hughes72472942018-01-10 08:36:10 -08006400 (void)sip24_valid;
6401 copy_salt_to_sipkey(parser, &key);
6402 sip24_init(&state, &key);
6403 sip24_update(&state, s, keylen(s) * sizeof(XML_Char));
6404 return (unsigned long)sip24_final(&state);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006405}
6406
6407static NAMED *
Haibo Huang40a71912019-10-11 11:13:39 -07006408lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006409 size_t i;
6410 if (table->size == 0) {
6411 size_t tsize;
Haibo Huang40a71912019-10-11 11:13:39 -07006412 if (! createSize)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006413 return NULL;
6414 table->power = INIT_POWER;
6415 /* table->size is a power of 2 */
6416 table->size = (size_t)1 << INIT_POWER;
6417 tsize = table->size * sizeof(NAMED *);
6418 table->v = (NAMED **)table->mem->malloc_fcn(tsize);
Haibo Huang40a71912019-10-11 11:13:39 -07006419 if (! table->v) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006420 table->size = 0;
6421 return NULL;
6422 }
6423 memset(table->v, 0, tsize);
Elliott Hughes35e432d2012-09-09 14:23:38 -07006424 i = hash(parser, name) & ((unsigned long)table->size - 1);
Haibo Huang40a71912019-10-11 11:13:39 -07006425 } else {
Elliott Hughes35e432d2012-09-09 14:23:38 -07006426 unsigned long h = hash(parser, name);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006427 unsigned long mask = (unsigned long)table->size - 1;
6428 unsigned char step = 0;
6429 i = h & mask;
6430 while (table->v[i]) {
6431 if (keyeq(name, table->v[i]->name))
6432 return table->v[i];
Haibo Huang40a71912019-10-11 11:13:39 -07006433 if (! step)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006434 step = PROBE_STEP(h, mask, table->power);
6435 i < step ? (i += table->size - step) : (i -= step);
6436 }
Haibo Huang40a71912019-10-11 11:13:39 -07006437 if (! createSize)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006438 return NULL;
6439
6440 /* check for overflow (table is half full) */
6441 if (table->used >> (table->power - 1)) {
6442 unsigned char newPower = table->power + 1;
6443 size_t newSize = (size_t)1 << newPower;
6444 unsigned long newMask = (unsigned long)newSize - 1;
6445 size_t tsize = newSize * sizeof(NAMED *);
6446 NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
Haibo Huang40a71912019-10-11 11:13:39 -07006447 if (! newV)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006448 return NULL;
6449 memset(newV, 0, tsize);
6450 for (i = 0; i < table->size; i++)
6451 if (table->v[i]) {
Elliott Hughes35e432d2012-09-09 14:23:38 -07006452 unsigned long newHash = hash(parser, table->v[i]->name);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006453 size_t j = newHash & newMask;
6454 step = 0;
6455 while (newV[j]) {
Haibo Huang40a71912019-10-11 11:13:39 -07006456 if (! step)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006457 step = PROBE_STEP(newHash, newMask, newPower);
6458 j < step ? (j += newSize - step) : (j -= step);
6459 }
6460 newV[j] = table->v[i];
6461 }
6462 table->mem->free_fcn(table->v);
6463 table->v = newV;
6464 table->power = newPower;
6465 table->size = newSize;
6466 i = h & newMask;
6467 step = 0;
6468 while (table->v[i]) {
Haibo Huang40a71912019-10-11 11:13:39 -07006469 if (! step)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006470 step = PROBE_STEP(h, newMask, newPower);
6471 i < step ? (i += newSize - step) : (i -= step);
6472 }
6473 }
6474 }
6475 table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
Haibo Huang40a71912019-10-11 11:13:39 -07006476 if (! table->v[i])
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006477 return NULL;
6478 memset(table->v[i], 0, createSize);
6479 table->v[i]->name = name;
6480 (table->used)++;
6481 return table->v[i];
6482}
6483
6484static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006485hashTableClear(HASH_TABLE *table) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006486 size_t i;
6487 for (i = 0; i < table->size; i++) {
6488 table->mem->free_fcn(table->v[i]);
6489 table->v[i] = NULL;
6490 }
6491 table->used = 0;
6492}
6493
6494static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006495hashTableDestroy(HASH_TABLE *table) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006496 size_t i;
6497 for (i = 0; i < table->size; i++)
6498 table->mem->free_fcn(table->v[i]);
6499 table->mem->free_fcn(table->v);
6500}
6501
6502static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006503hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006504 p->power = 0;
6505 p->size = 0;
6506 p->used = 0;
6507 p->v = NULL;
6508 p->mem = ms;
6509}
6510
6511static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006512hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006513 iter->p = table->v;
Haibo Huangd1a324a2020-10-28 22:19:36 -07006514 iter->end = iter->p ? iter->p + table->size : NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006515}
6516
Haibo Huang40a71912019-10-11 11:13:39 -07006517static NAMED *FASTCALL
6518hashTableIterNext(HASH_TABLE_ITER *iter) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006519 while (iter->p != iter->end) {
6520 NAMED *tem = *(iter->p)++;
6521 if (tem)
6522 return tem;
6523 }
6524 return NULL;
6525}
6526
6527static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006528poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006529 pool->blocks = NULL;
6530 pool->freeBlocks = NULL;
6531 pool->start = NULL;
6532 pool->ptr = NULL;
6533 pool->end = NULL;
6534 pool->mem = ms;
6535}
6536
6537static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006538poolClear(STRING_POOL *pool) {
6539 if (! pool->freeBlocks)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006540 pool->freeBlocks = pool->blocks;
6541 else {
6542 BLOCK *p = pool->blocks;
6543 while (p) {
6544 BLOCK *tem = p->next;
6545 p->next = pool->freeBlocks;
6546 pool->freeBlocks = p;
6547 p = tem;
6548 }
6549 }
6550 pool->blocks = NULL;
6551 pool->start = NULL;
6552 pool->ptr = NULL;
6553 pool->end = NULL;
6554}
6555
6556static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006557poolDestroy(STRING_POOL *pool) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006558 BLOCK *p = pool->blocks;
6559 while (p) {
6560 BLOCK *tem = p->next;
6561 pool->mem->free_fcn(p);
6562 p = tem;
6563 }
6564 p = pool->freeBlocks;
6565 while (p) {
6566 BLOCK *tem = p->next;
6567 pool->mem->free_fcn(p);
6568 p = tem;
6569 }
6570}
6571
6572static XML_Char *
Haibo Huang40a71912019-10-11 11:13:39 -07006573poolAppend(STRING_POOL *pool, const ENCODING *enc, const char *ptr,
6574 const char *end) {
6575 if (! pool->ptr && ! poolGrow(pool))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006576 return NULL;
6577 for (;;) {
Haibo Huang40a71912019-10-11 11:13:39 -07006578 const enum XML_Convert_Result convert_res = XmlConvert(
6579 enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
6580 if ((convert_res == XML_CONVERT_COMPLETED)
6581 || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006582 break;
Haibo Huang40a71912019-10-11 11:13:39 -07006583 if (! poolGrow(pool))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006584 return NULL;
6585 }
6586 return pool->start;
6587}
6588
Haibo Huang40a71912019-10-11 11:13:39 -07006589static const XML_Char *FASTCALL
6590poolCopyString(STRING_POOL *pool, const XML_Char *s) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006591 do {
Haibo Huang40a71912019-10-11 11:13:39 -07006592 if (! poolAppendChar(pool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006593 return NULL;
6594 } while (*s++);
6595 s = pool->start;
6596 poolFinish(pool);
6597 return s;
6598}
6599
6600static const XML_Char *
Haibo Huang40a71912019-10-11 11:13:39 -07006601poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) {
6602 if (! pool->ptr && ! poolGrow(pool)) {
Elliott Hughes72472942018-01-10 08:36:10 -08006603 /* The following line is unreachable given the current usage of
6604 * poolCopyStringN(). Currently it is called from exactly one
6605 * place to copy the text of a simple general entity. By that
6606 * point, the name of the entity is already stored in the pool, so
6607 * pool->ptr cannot be NULL.
6608 *
6609 * If poolCopyStringN() is used elsewhere as it well might be,
6610 * this line may well become executable again. Regardless, this
6611 * sort of check shouldn't be removed lightly, so we just exclude
6612 * it from the coverage statistics.
6613 */
6614 return NULL; /* LCOV_EXCL_LINE */
6615 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006616 for (; n > 0; --n, s++) {
Haibo Huang40a71912019-10-11 11:13:39 -07006617 if (! poolAppendChar(pool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006618 return NULL;
6619 }
6620 s = pool->start;
6621 poolFinish(pool);
6622 return s;
6623}
6624
Haibo Huang40a71912019-10-11 11:13:39 -07006625static const XML_Char *FASTCALL
6626poolAppendString(STRING_POOL *pool, const XML_Char *s) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006627 while (*s) {
Haibo Huang40a71912019-10-11 11:13:39 -07006628 if (! poolAppendChar(pool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006629 return NULL;
6630 s++;
6631 }
6632 return pool->start;
6633}
6634
6635static XML_Char *
Haibo Huang40a71912019-10-11 11:13:39 -07006636poolStoreString(STRING_POOL *pool, const ENCODING *enc, const char *ptr,
6637 const char *end) {
6638 if (! poolAppend(pool, enc, ptr, end))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006639 return NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07006640 if (pool->ptr == pool->end && ! poolGrow(pool))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006641 return NULL;
6642 *(pool->ptr)++ = 0;
6643 return pool->start;
6644}
6645
Elliott Hughes72472942018-01-10 08:36:10 -08006646static size_t
Haibo Huang40a71912019-10-11 11:13:39 -07006647poolBytesToAllocateFor(int blockSize) {
Elliott Hughes72472942018-01-10 08:36:10 -08006648 /* Unprotected math would be:
6649 ** return offsetof(BLOCK, s) + blockSize * sizeof(XML_Char);
6650 **
6651 ** Detect overflow, avoiding _signed_ overflow undefined behavior
6652 ** For a + b * c we check b * c in isolation first, so that addition of a
6653 ** on top has no chance of making us accept a small non-negative number
6654 */
Haibo Huang40a71912019-10-11 11:13:39 -07006655 const size_t stretch = sizeof(XML_Char); /* can be 4 bytes */
Elliott Hughes72472942018-01-10 08:36:10 -08006656
6657 if (blockSize <= 0)
6658 return 0;
6659
6660 if (blockSize > (int)(INT_MAX / stretch))
6661 return 0;
6662
6663 {
6664 const int stretchedBlockSize = blockSize * (int)stretch;
Haibo Huang40a71912019-10-11 11:13:39 -07006665 const int bytesToAllocate
6666 = (int)(offsetof(BLOCK, s) + (unsigned)stretchedBlockSize);
Elliott Hughes72472942018-01-10 08:36:10 -08006667 if (bytesToAllocate < 0)
6668 return 0;
6669
6670 return (size_t)bytesToAllocate;
6671 }
6672}
6673
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006674static XML_Bool FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006675poolGrow(STRING_POOL *pool) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006676 if (pool->freeBlocks) {
6677 if (pool->start == 0) {
6678 pool->blocks = pool->freeBlocks;
6679 pool->freeBlocks = pool->freeBlocks->next;
6680 pool->blocks->next = NULL;
6681 pool->start = pool->blocks->s;
6682 pool->end = pool->start + pool->blocks->size;
6683 pool->ptr = pool->start;
6684 return XML_TRUE;
6685 }
6686 if (pool->end - pool->start < pool->freeBlocks->size) {
6687 BLOCK *tem = pool->freeBlocks->next;
6688 pool->freeBlocks->next = pool->blocks;
6689 pool->blocks = pool->freeBlocks;
6690 pool->freeBlocks = tem;
6691 memcpy(pool->blocks->s, pool->start,
6692 (pool->end - pool->start) * sizeof(XML_Char));
6693 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
6694 pool->start = pool->blocks->s;
6695 pool->end = pool->start + pool->blocks->size;
6696 return XML_TRUE;
6697 }
6698 }
6699 if (pool->blocks && pool->start == pool->blocks->s) {
Paul Duffin4bf8f122016-05-13 12:35:25 +01006700 BLOCK *temp;
Haibo Huang40a71912019-10-11 11:13:39 -07006701 int blockSize = (int)((unsigned)(pool->end - pool->start) * 2U);
Elliott Hughes72472942018-01-10 08:36:10 -08006702 size_t bytesToAllocate;
Paul Duffin4bf8f122016-05-13 12:35:25 +01006703
Elliott Hughes72472942018-01-10 08:36:10 -08006704 /* NOTE: Needs to be calculated prior to calling `realloc`
6705 to avoid dangling pointers: */
6706 const ptrdiff_t offsetInsideBlock = pool->ptr - pool->start;
6707
6708 if (blockSize < 0) {
6709 /* This condition traps a situation where either more than
6710 * INT_MAX/2 bytes have already been allocated. This isn't
6711 * readily testable, since it is unlikely that an average
6712 * machine will have that much memory, so we exclude it from the
6713 * coverage statistics.
6714 */
6715 return XML_FALSE; /* LCOV_EXCL_LINE */
6716 }
6717
6718 bytesToAllocate = poolBytesToAllocateFor(blockSize);
6719 if (bytesToAllocate == 0)
Paul Duffin4bf8f122016-05-13 12:35:25 +01006720 return XML_FALSE;
6721
Haibo Huang40a71912019-10-11 11:13:39 -07006722 temp = (BLOCK *)pool->mem->realloc_fcn(pool->blocks,
6723 (unsigned)bytesToAllocate);
Elliott Hughes35e432d2012-09-09 14:23:38 -07006724 if (temp == NULL)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006725 return XML_FALSE;
Elliott Hughes35e432d2012-09-09 14:23:38 -07006726 pool->blocks = temp;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006727 pool->blocks->size = blockSize;
Elliott Hughes72472942018-01-10 08:36:10 -08006728 pool->ptr = pool->blocks->s + offsetInsideBlock;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006729 pool->start = pool->blocks->s;
6730 pool->end = pool->start + blockSize;
Haibo Huang40a71912019-10-11 11:13:39 -07006731 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006732 BLOCK *tem;
6733 int blockSize = (int)(pool->end - pool->start);
Elliott Hughes72472942018-01-10 08:36:10 -08006734 size_t bytesToAllocate;
Paul Duffin4bf8f122016-05-13 12:35:25 +01006735
Elliott Hughes72472942018-01-10 08:36:10 -08006736 if (blockSize < 0) {
6737 /* This condition traps a situation where either more than
6738 * INT_MAX bytes have already been allocated (which is prevented
6739 * by various pieces of program logic, not least this one, never
6740 * mind the unlikelihood of actually having that much memory) or
6741 * the pool control fields have been corrupted (which could
6742 * conceivably happen in an extremely buggy user handler
6743 * function). Either way it isn't readily testable, so we
6744 * exclude it from the coverage statistics.
6745 */
Haibo Huang40a71912019-10-11 11:13:39 -07006746 return XML_FALSE; /* LCOV_EXCL_LINE */
Elliott Hughes72472942018-01-10 08:36:10 -08006747 }
Paul Duffin4bf8f122016-05-13 12:35:25 +01006748
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006749 if (blockSize < INIT_BLOCK_SIZE)
6750 blockSize = INIT_BLOCK_SIZE;
Elliott Hughes72472942018-01-10 08:36:10 -08006751 else {
6752 /* Detect overflow, avoiding _signed_ overflow undefined behavior */
6753 if ((int)((unsigned)blockSize * 2U) < 0) {
6754 return XML_FALSE;
6755 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006756 blockSize *= 2;
Elliott Hughes72472942018-01-10 08:36:10 -08006757 }
6758
6759 bytesToAllocate = poolBytesToAllocateFor(blockSize);
6760 if (bytesToAllocate == 0)
6761 return XML_FALSE;
6762
6763 tem = (BLOCK *)pool->mem->malloc_fcn(bytesToAllocate);
Haibo Huang40a71912019-10-11 11:13:39 -07006764 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006765 return XML_FALSE;
6766 tem->size = blockSize;
6767 tem->next = pool->blocks;
6768 pool->blocks = tem;
6769 if (pool->ptr != pool->start)
Haibo Huang40a71912019-10-11 11:13:39 -07006770 memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006771 pool->ptr = tem->s + (pool->ptr - pool->start);
6772 pool->start = tem->s;
6773 pool->end = tem->s + blockSize;
6774 }
6775 return XML_TRUE;
6776}
6777
6778static int FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006779nextScaffoldPart(XML_Parser parser) {
6780 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
6781 CONTENT_SCAFFOLD *me;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006782 int next;
6783
Haibo Huang40a71912019-10-11 11:13:39 -07006784 if (! dtd->scaffIndex) {
Elliott Hughes72472942018-01-10 08:36:10 -08006785 dtd->scaffIndex = (int *)MALLOC(parser, parser->m_groupSize * sizeof(int));
Haibo Huang40a71912019-10-11 11:13:39 -07006786 if (! dtd->scaffIndex)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006787 return -1;
6788 dtd->scaffIndex[0] = 0;
6789 }
6790
6791 if (dtd->scaffCount >= dtd->scaffSize) {
6792 CONTENT_SCAFFOLD *temp;
6793 if (dtd->scaffold) {
Haibo Huang40a71912019-10-11 11:13:39 -07006794 temp = (CONTENT_SCAFFOLD *)REALLOC(
6795 parser, dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006796 if (temp == NULL)
6797 return -1;
6798 dtd->scaffSize *= 2;
Haibo Huang40a71912019-10-11 11:13:39 -07006799 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08006800 temp = (CONTENT_SCAFFOLD *)MALLOC(parser, INIT_SCAFFOLD_ELEMENTS
Haibo Huang40a71912019-10-11 11:13:39 -07006801 * sizeof(CONTENT_SCAFFOLD));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006802 if (temp == NULL)
6803 return -1;
6804 dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
6805 }
6806 dtd->scaffold = temp;
6807 }
6808 next = dtd->scaffCount++;
6809 me = &dtd->scaffold[next];
6810 if (dtd->scaffLevel) {
Haibo Huang40a71912019-10-11 11:13:39 -07006811 CONTENT_SCAFFOLD *parent
6812 = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]];
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006813 if (parent->lastchild) {
6814 dtd->scaffold[parent->lastchild].nextsib = next;
6815 }
Haibo Huang40a71912019-10-11 11:13:39 -07006816 if (! parent->childcnt)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006817 parent->firstchild = next;
6818 parent->lastchild = next;
6819 parent->childcnt++;
6820 }
6821 me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
6822 return next;
6823}
6824
6825static void
Haibo Huang40a71912019-10-11 11:13:39 -07006826build_node(XML_Parser parser, int src_node, XML_Content *dest,
6827 XML_Content **contpos, XML_Char **strpos) {
6828 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006829 dest->type = dtd->scaffold[src_node].type;
6830 dest->quant = dtd->scaffold[src_node].quant;
6831 if (dest->type == XML_CTYPE_NAME) {
6832 const XML_Char *src;
6833 dest->name = *strpos;
6834 src = dtd->scaffold[src_node].name;
6835 for (;;) {
6836 *(*strpos)++ = *src;
Haibo Huang40a71912019-10-11 11:13:39 -07006837 if (! *src)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006838 break;
6839 src++;
6840 }
6841 dest->numchildren = 0;
6842 dest->children = NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07006843 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006844 unsigned int i;
6845 int cn;
6846 dest->numchildren = dtd->scaffold[src_node].childcnt;
6847 dest->children = *contpos;
6848 *contpos += dest->numchildren;
Haibo Huang40a71912019-10-11 11:13:39 -07006849 for (i = 0, cn = dtd->scaffold[src_node].firstchild; i < dest->numchildren;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006850 i++, cn = dtd->scaffold[cn].nextsib) {
6851 build_node(parser, cn, &(dest->children[i]), contpos, strpos);
6852 }
6853 dest->name = NULL;
6854 }
6855}
6856
6857static XML_Content *
Haibo Huang40a71912019-10-11 11:13:39 -07006858build_model(XML_Parser parser) {
6859 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006860 XML_Content *ret;
6861 XML_Content *cpos;
Haibo Huang40a71912019-10-11 11:13:39 -07006862 XML_Char *str;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006863 int allocsize = (dtd->scaffCount * sizeof(XML_Content)
6864 + (dtd->contentStringLen * sizeof(XML_Char)));
6865
Elliott Hughes72472942018-01-10 08:36:10 -08006866 ret = (XML_Content *)MALLOC(parser, allocsize);
Haibo Huang40a71912019-10-11 11:13:39 -07006867 if (! ret)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006868 return NULL;
6869
Haibo Huang40a71912019-10-11 11:13:39 -07006870 str = (XML_Char *)(&ret[dtd->scaffCount]);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006871 cpos = &ret[1];
6872
6873 build_node(parser, 0, ret, &cpos, &str);
6874 return ret;
6875}
6876
6877static ELEMENT_TYPE *
Haibo Huang40a71912019-10-11 11:13:39 -07006878getElementType(XML_Parser parser, const ENCODING *enc, const char *ptr,
6879 const char *end) {
6880 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006881 const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
6882 ELEMENT_TYPE *ret;
6883
Haibo Huang40a71912019-10-11 11:13:39 -07006884 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006885 return NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07006886 ret = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
6887 sizeof(ELEMENT_TYPE));
6888 if (! ret)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006889 return NULL;
6890 if (ret->name != name)
6891 poolDiscard(&dtd->pool);
6892 else {
6893 poolFinish(&dtd->pool);
Haibo Huang40a71912019-10-11 11:13:39 -07006894 if (! setElementTypePrefix(parser, ret))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006895 return NULL;
6896 }
6897 return ret;
6898}
Elliott Hughes72472942018-01-10 08:36:10 -08006899
6900static XML_Char *
Haibo Huang40a71912019-10-11 11:13:39 -07006901copyString(const XML_Char *s, const XML_Memory_Handling_Suite *memsuite) {
Sadaf Ebrahimi1adbf372022-05-23 22:34:43 +00006902 size_t charsRequired = 0;
Haibo Huang40a71912019-10-11 11:13:39 -07006903 XML_Char *result;
Elliott Hughes72472942018-01-10 08:36:10 -08006904
Haibo Huang40a71912019-10-11 11:13:39 -07006905 /* First determine how long the string is */
6906 while (s[charsRequired] != 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08006907 charsRequired++;
Haibo Huang40a71912019-10-11 11:13:39 -07006908 }
6909 /* Include the terminator */
6910 charsRequired++;
Elliott Hughes72472942018-01-10 08:36:10 -08006911
Haibo Huang40a71912019-10-11 11:13:39 -07006912 /* Now allocate space for the copy */
6913 result = memsuite->malloc_fcn(charsRequired * sizeof(XML_Char));
6914 if (result == NULL)
6915 return NULL;
6916 /* Copy the original into place */
6917 memcpy(result, s, charsRequired * sizeof(XML_Char));
6918 return result;
Elliott Hughes72472942018-01-10 08:36:10 -08006919}