blob: 586212833e3f57c4bbda82b79b82ea61ccf5abd7 [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;
Sadaf Ebrahimifcfab022022-06-03 03:40:21 +00004999 size_t 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 ;
Sadaf Ebrahimifcfab022022-06-03 03:40:21 +00005015
5016 /* Detect and prevent integer overflow */
5017 if (nameLen > UINT_MAX - dtd->contentStringLen) {
5018 return XML_ERROR_NO_MEMORY;
5019 }
5020
5021 dtd->contentStringLen += (unsigned)nameLen;
Elliott Hughes72472942018-01-10 08:36:10 -08005022 if (parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005023 handleDefault = XML_FALSE;
5024 }
5025 break;
5026
5027 case XML_ROLE_GROUP_CLOSE:
5028 quant = XML_CQUANT_NONE;
5029 goto closeGroup;
5030 case XML_ROLE_GROUP_CLOSE_OPT:
5031 quant = XML_CQUANT_OPT;
5032 goto closeGroup;
5033 case XML_ROLE_GROUP_CLOSE_REP:
5034 quant = XML_CQUANT_REP;
5035 goto closeGroup;
5036 case XML_ROLE_GROUP_CLOSE_PLUS:
5037 quant = XML_CQUANT_PLUS;
5038 closeGroup:
5039 if (dtd->in_eldecl) {
Elliott Hughes72472942018-01-10 08:36:10 -08005040 if (parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005041 handleDefault = XML_FALSE;
5042 dtd->scaffLevel--;
5043 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
5044 if (dtd->scaffLevel == 0) {
Haibo Huang40a71912019-10-11 11:13:39 -07005045 if (! handleDefault) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005046 XML_Content *model = build_model(parser);
Haibo Huang40a71912019-10-11 11:13:39 -07005047 if (! model)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005048 return XML_ERROR_NO_MEMORY;
5049 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07005050 parser->m_elementDeclHandler(
5051 parser->m_handlerArg, parser->m_declElementType->name, model);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005052 }
5053 dtd->in_eldecl = XML_FALSE;
5054 dtd->contentStringLen = 0;
5055 }
5056 }
5057 break;
5058 /* End element declaration stuff */
5059
5060 case XML_ROLE_PI:
Haibo Huang40a71912019-10-11 11:13:39 -07005061 if (! reportProcessingInstruction(parser, enc, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005062 return XML_ERROR_NO_MEMORY;
5063 handleDefault = XML_FALSE;
5064 break;
5065 case XML_ROLE_COMMENT:
Haibo Huang40a71912019-10-11 11:13:39 -07005066 if (! reportComment(parser, enc, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005067 return XML_ERROR_NO_MEMORY;
5068 handleDefault = XML_FALSE;
5069 break;
5070 case XML_ROLE_NONE:
5071 switch (tok) {
5072 case XML_TOK_BOM:
5073 handleDefault = XML_FALSE;
5074 break;
5075 }
5076 break;
5077 case XML_ROLE_DOCTYPE_NONE:
Elliott Hughes72472942018-01-10 08:36:10 -08005078 if (parser->m_startDoctypeDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005079 handleDefault = XML_FALSE;
5080 break;
5081 case XML_ROLE_ENTITY_NONE:
Elliott Hughes72472942018-01-10 08:36:10 -08005082 if (dtd->keepProcessing && parser->m_entityDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005083 handleDefault = XML_FALSE;
5084 break;
5085 case XML_ROLE_NOTATION_NONE:
Elliott Hughes72472942018-01-10 08:36:10 -08005086 if (parser->m_notationDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005087 handleDefault = XML_FALSE;
5088 break;
5089 case XML_ROLE_ATTLIST_NONE:
Elliott Hughes72472942018-01-10 08:36:10 -08005090 if (dtd->keepProcessing && parser->m_attlistDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005091 handleDefault = XML_FALSE;
5092 break;
5093 case XML_ROLE_ELEMENT_NONE:
Elliott Hughes72472942018-01-10 08:36:10 -08005094 if (parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005095 handleDefault = XML_FALSE;
5096 break;
5097 } /* end of big switch */
5098
Elliott Hughes72472942018-01-10 08:36:10 -08005099 if (handleDefault && parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005100 reportDefault(parser, enc, s, next);
5101
Elliott Hughes72472942018-01-10 08:36:10 -08005102 switch (parser->m_parsingStatus.parsing) {
Elliott Hughes35e432d2012-09-09 14:23:38 -07005103 case XML_SUSPENDED:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005104 *nextPtr = next;
5105 return XML_ERROR_NONE;
5106 case XML_FINISHED:
5107 return XML_ERROR_ABORTED;
5108 default:
5109 s = next;
5110 tok = XmlPrologTok(enc, s, end, &next);
5111 }
5112 }
5113 /* not reached */
5114}
5115
5116static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07005117epilogProcessor(XML_Parser parser, const char *s, const char *end,
5118 const char **nextPtr) {
Elliott Hughes72472942018-01-10 08:36:10 -08005119 parser->m_processor = epilogProcessor;
5120 parser->m_eventPtr = s;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005121 for (;;) {
5122 const char *next = NULL;
Elliott Hughes72472942018-01-10 08:36:10 -08005123 int tok = XmlPrologTok(parser->m_encoding, s, end, &next);
5124 parser->m_eventEndPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005125 switch (tok) {
5126 /* report partial linebreak - it might be the last token */
5127 case -XML_TOK_PROLOG_S:
Elliott Hughes72472942018-01-10 08:36:10 -08005128 if (parser->m_defaultHandler) {
5129 reportDefault(parser, parser->m_encoding, s, next);
5130 if (parser->m_parsingStatus.parsing == XML_FINISHED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005131 return XML_ERROR_ABORTED;
5132 }
5133 *nextPtr = next;
5134 return XML_ERROR_NONE;
5135 case XML_TOK_NONE:
5136 *nextPtr = s;
5137 return XML_ERROR_NONE;
5138 case XML_TOK_PROLOG_S:
Elliott Hughes72472942018-01-10 08:36:10 -08005139 if (parser->m_defaultHandler)
5140 reportDefault(parser, parser->m_encoding, s, next);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005141 break;
5142 case XML_TOK_PI:
Haibo Huang40a71912019-10-11 11:13:39 -07005143 if (! reportProcessingInstruction(parser, parser->m_encoding, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005144 return XML_ERROR_NO_MEMORY;
5145 break;
5146 case XML_TOK_COMMENT:
Haibo Huang40a71912019-10-11 11:13:39 -07005147 if (! reportComment(parser, parser->m_encoding, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005148 return XML_ERROR_NO_MEMORY;
5149 break;
5150 case XML_TOK_INVALID:
Elliott Hughes72472942018-01-10 08:36:10 -08005151 parser->m_eventPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005152 return XML_ERROR_INVALID_TOKEN;
5153 case XML_TOK_PARTIAL:
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_UNCLOSED_TOKEN;
5159 case XML_TOK_PARTIAL_CHAR:
Haibo Huang40a71912019-10-11 11:13:39 -07005160 if (! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005161 *nextPtr = s;
5162 return XML_ERROR_NONE;
5163 }
5164 return XML_ERROR_PARTIAL_CHAR;
5165 default:
5166 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
5167 }
Elliott Hughes72472942018-01-10 08:36:10 -08005168 parser->m_eventPtr = s = next;
5169 switch (parser->m_parsingStatus.parsing) {
Elliott Hughes35e432d2012-09-09 14:23:38 -07005170 case XML_SUSPENDED:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005171 *nextPtr = next;
5172 return XML_ERROR_NONE;
5173 case XML_FINISHED:
5174 return XML_ERROR_ABORTED;
Haibo Huang40a71912019-10-11 11:13:39 -07005175 default:;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005176 }
5177 }
5178}
5179
5180static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07005181processInternalEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005182 const char *textStart, *textEnd;
5183 const char *next;
5184 enum XML_Error result;
5185 OPEN_INTERNAL_ENTITY *openEntity;
5186
Elliott Hughes72472942018-01-10 08:36:10 -08005187 if (parser->m_freeInternalEntities) {
5188 openEntity = parser->m_freeInternalEntities;
5189 parser->m_freeInternalEntities = openEntity->next;
Haibo Huang40a71912019-10-11 11:13:39 -07005190 } else {
5191 openEntity
5192 = (OPEN_INTERNAL_ENTITY *)MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY));
5193 if (! openEntity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005194 return XML_ERROR_NO_MEMORY;
5195 }
5196 entity->open = XML_TRUE;
5197 entity->processed = 0;
Elliott Hughes72472942018-01-10 08:36:10 -08005198 openEntity->next = parser->m_openInternalEntities;
5199 parser->m_openInternalEntities = openEntity;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005200 openEntity->entity = entity;
Elliott Hughes72472942018-01-10 08:36:10 -08005201 openEntity->startTagLevel = parser->m_tagLevel;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005202 openEntity->betweenDecl = betweenDecl;
5203 openEntity->internalEventPtr = NULL;
5204 openEntity->internalEventEndPtr = NULL;
Haibo Huangd1a324a2020-10-28 22:19:36 -07005205 textStart = (const char *)entity->textPtr;
5206 textEnd = (const char *)(entity->textPtr + entity->textLen);
Elliott Hughes72472942018-01-10 08:36:10 -08005207 /* Set a safe default value in case 'next' does not get set */
5208 next = textStart;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005209
5210#ifdef XML_DTD
5211 if (entity->is_param) {
Haibo Huang40a71912019-10-11 11:13:39 -07005212 int tok
5213 = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
5214 result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
5215 tok, next, &next, XML_FALSE, XML_FALSE);
5216 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005217#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07005218 result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding,
5219 textStart, textEnd, &next, XML_FALSE);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005220
5221 if (result == XML_ERROR_NONE) {
Elliott Hughes72472942018-01-10 08:36:10 -08005222 if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005223 entity->processed = (int)(next - textStart);
Elliott Hughes72472942018-01-10 08:36:10 -08005224 parser->m_processor = internalEntityProcessor;
Haibo Huang40a71912019-10-11 11:13:39 -07005225 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005226 entity->open = XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08005227 parser->m_openInternalEntities = openEntity->next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005228 /* put openEntity back in list of free instances */
Elliott Hughes72472942018-01-10 08:36:10 -08005229 openEntity->next = parser->m_freeInternalEntities;
5230 parser->m_freeInternalEntities = openEntity;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005231 }
5232 }
5233 return result;
5234}
5235
5236static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07005237internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
5238 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005239 ENTITY *entity;
5240 const char *textStart, *textEnd;
5241 const char *next;
5242 enum XML_Error result;
Elliott Hughes72472942018-01-10 08:36:10 -08005243 OPEN_INTERNAL_ENTITY *openEntity = parser->m_openInternalEntities;
Haibo Huang40a71912019-10-11 11:13:39 -07005244 if (! openEntity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005245 return XML_ERROR_UNEXPECTED_STATE;
5246
5247 entity = openEntity->entity;
Haibo Huangd1a324a2020-10-28 22:19:36 -07005248 textStart = ((const char *)entity->textPtr) + entity->processed;
5249 textEnd = (const char *)(entity->textPtr + entity->textLen);
Elliott Hughes72472942018-01-10 08:36:10 -08005250 /* Set a safe default value in case 'next' does not get set */
5251 next = textStart;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005252
5253#ifdef XML_DTD
5254 if (entity->is_param) {
Haibo Huang40a71912019-10-11 11:13:39 -07005255 int tok
5256 = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
5257 result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
5258 tok, next, &next, XML_FALSE, XML_TRUE);
5259 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005260#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07005261 result = doContent(parser, openEntity->startTagLevel,
5262 parser->m_internalEncoding, textStart, textEnd, &next,
5263 XML_FALSE);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005264
5265 if (result != XML_ERROR_NONE)
5266 return result;
Haibo Huang40a71912019-10-11 11:13:39 -07005267 else if (textEnd != next
5268 && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
Haibo Huangd1a324a2020-10-28 22:19:36 -07005269 entity->processed = (int)(next - (const char *)entity->textPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005270 return result;
Haibo Huang40a71912019-10-11 11:13:39 -07005271 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005272 entity->open = XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08005273 parser->m_openInternalEntities = openEntity->next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005274 /* put openEntity back in list of free instances */
Elliott Hughes72472942018-01-10 08:36:10 -08005275 openEntity->next = parser->m_freeInternalEntities;
5276 parser->m_freeInternalEntities = openEntity;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005277 }
5278
5279#ifdef XML_DTD
5280 if (entity->is_param) {
5281 int tok;
Elliott Hughes72472942018-01-10 08:36:10 -08005282 parser->m_processor = prologProcessor;
5283 tok = XmlPrologTok(parser->m_encoding, s, end, &next);
5284 return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
Haibo Huang40a71912019-10-11 11:13:39 -07005285 (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE);
5286 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005287#endif /* XML_DTD */
5288 {
Elliott Hughes72472942018-01-10 08:36:10 -08005289 parser->m_processor = contentProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005290 /* see externalEntityContentProcessor vs contentProcessor */
Haibo Huang40a71912019-10-11 11:13:39 -07005291 return doContent(parser, parser->m_parentParser ? 1 : 0, parser->m_encoding,
5292 s, end, nextPtr,
5293 (XML_Bool)! parser->m_parsingStatus.finalBuffer);
Elliott Hughes35e432d2012-09-09 14:23:38 -07005294 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005295}
5296
5297static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07005298errorProcessor(XML_Parser parser, const char *s, const char *end,
5299 const char **nextPtr) {
5300 UNUSED_P(s);
5301 UNUSED_P(end);
5302 UNUSED_P(nextPtr);
Elliott Hughes72472942018-01-10 08:36:10 -08005303 return parser->m_errorCode;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005304}
5305
5306static enum XML_Error
5307storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
Haibo Huang40a71912019-10-11 11:13:39 -07005308 const char *ptr, const char *end, STRING_POOL *pool) {
5309 enum XML_Error result
5310 = appendAttributeValue(parser, enc, isCdata, ptr, end, pool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005311 if (result)
5312 return result;
Haibo Huang40a71912019-10-11 11:13:39 -07005313 if (! isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005314 poolChop(pool);
Haibo Huang40a71912019-10-11 11:13:39 -07005315 if (! poolAppendChar(pool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005316 return XML_ERROR_NO_MEMORY;
5317 return XML_ERROR_NONE;
5318}
5319
5320static enum XML_Error
5321appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
Haibo Huang40a71912019-10-11 11:13:39 -07005322 const char *ptr, const char *end, STRING_POOL *pool) {
5323 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005324 for (;;) {
5325 const char *next;
5326 int tok = XmlAttributeValueTok(enc, ptr, end, &next);
5327 switch (tok) {
5328 case XML_TOK_NONE:
5329 return XML_ERROR_NONE;
5330 case XML_TOK_INVALID:
Elliott Hughes72472942018-01-10 08:36:10 -08005331 if (enc == parser->m_encoding)
5332 parser->m_eventPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005333 return XML_ERROR_INVALID_TOKEN;
5334 case XML_TOK_PARTIAL:
Elliott Hughes72472942018-01-10 08:36:10 -08005335 if (enc == parser->m_encoding)
5336 parser->m_eventPtr = ptr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005337 return XML_ERROR_INVALID_TOKEN;
Haibo Huang40a71912019-10-11 11:13:39 -07005338 case XML_TOK_CHAR_REF: {
5339 XML_Char buf[XML_ENCODE_MAX];
5340 int i;
5341 int n = XmlCharRefNumber(enc, ptr);
5342 if (n < 0) {
5343 if (enc == parser->m_encoding)
5344 parser->m_eventPtr = ptr;
5345 return XML_ERROR_BAD_CHAR_REF;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005346 }
Haibo Huang40a71912019-10-11 11:13:39 -07005347 if (! isCdata && n == 0x20 /* space */
5348 && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
5349 break;
5350 n = XmlEncode(n, (ICHAR *)buf);
5351 /* The XmlEncode() functions can never return 0 here. That
5352 * error return happens if the code point passed in is either
5353 * negative or greater than or equal to 0x110000. The
5354 * XmlCharRefNumber() functions will all return a number
5355 * strictly less than 0x110000 or a negative value if an error
5356 * occurred. The negative value is intercepted above, so
5357 * XmlEncode() is never passed a value it might return an
5358 * error for.
5359 */
5360 for (i = 0; i < n; i++) {
5361 if (! poolAppendChar(pool, buf[i]))
5362 return XML_ERROR_NO_MEMORY;
5363 }
5364 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005365 case XML_TOK_DATA_CHARS:
Haibo Huang40a71912019-10-11 11:13:39 -07005366 if (! poolAppend(pool, enc, ptr, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005367 return XML_ERROR_NO_MEMORY;
5368 break;
5369 case XML_TOK_TRAILING_CR:
5370 next = ptr + enc->minBytesPerChar;
5371 /* fall through */
5372 case XML_TOK_ATTRIBUTE_VALUE_S:
5373 case XML_TOK_DATA_NEWLINE:
Haibo Huang40a71912019-10-11 11:13:39 -07005374 if (! isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005375 break;
Haibo Huang40a71912019-10-11 11:13:39 -07005376 if (! poolAppendChar(pool, 0x20))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005377 return XML_ERROR_NO_MEMORY;
5378 break;
Haibo Huang40a71912019-10-11 11:13:39 -07005379 case XML_TOK_ENTITY_REF: {
5380 const XML_Char *name;
5381 ENTITY *entity;
5382 char checkEntityDecl;
5383 XML_Char ch = (XML_Char)XmlPredefinedEntityName(
5384 enc, ptr + enc->minBytesPerChar, next - enc->minBytesPerChar);
5385 if (ch) {
5386 if (! poolAppendChar(pool, ch))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005387 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07005388 break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005389 }
Haibo Huang40a71912019-10-11 11:13:39 -07005390 name = poolStoreString(&parser->m_temp2Pool, enc,
5391 ptr + enc->minBytesPerChar,
5392 next - enc->minBytesPerChar);
5393 if (! name)
5394 return XML_ERROR_NO_MEMORY;
5395 entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
5396 poolDiscard(&parser->m_temp2Pool);
5397 /* First, determine if a check for an existing declaration is needed;
5398 if yes, check that the entity exists, and that it is internal.
5399 */
5400 if (pool == &dtd->pool) /* are we called from prolog? */
5401 checkEntityDecl =
5402#ifdef XML_DTD
5403 parser->m_prologState.documentEntity &&
5404#endif /* XML_DTD */
5405 (dtd->standalone ? ! parser->m_openInternalEntities
5406 : ! dtd->hasParamEntityRefs);
5407 else /* if (pool == &parser->m_tempPool): we are called from content */
5408 checkEntityDecl = ! dtd->hasParamEntityRefs || dtd->standalone;
5409 if (checkEntityDecl) {
5410 if (! entity)
5411 return XML_ERROR_UNDEFINED_ENTITY;
5412 else if (! entity->is_internal)
5413 return XML_ERROR_ENTITY_DECLARED_IN_PE;
5414 } else if (! entity) {
5415 /* Cannot report skipped entity here - see comments on
5416 parser->m_skippedEntityHandler.
5417 if (parser->m_skippedEntityHandler)
5418 parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
5419 */
5420 /* Cannot call the default handler because this would be
5421 out of sync with the call to the startElementHandler.
5422 if ((pool == &parser->m_tempPool) && parser->m_defaultHandler)
5423 reportDefault(parser, enc, ptr, next);
5424 */
5425 break;
5426 }
5427 if (entity->open) {
5428 if (enc == parser->m_encoding) {
5429 /* It does not appear that this line can be executed.
5430 *
5431 * The "if (entity->open)" check catches recursive entity
5432 * definitions. In order to be called with an open
5433 * entity, it must have gone through this code before and
5434 * been through the recursive call to
5435 * appendAttributeValue() some lines below. That call
5436 * sets the local encoding ("enc") to the parser's
5437 * internal encoding (internal_utf8 or internal_utf16),
5438 * which can never be the same as the principle encoding.
5439 * It doesn't appear there is another code path that gets
5440 * here with entity->open being TRUE.
5441 *
5442 * Since it is not certain that this logic is watertight,
5443 * we keep the line and merely exclude it from coverage
5444 * tests.
5445 */
5446 parser->m_eventPtr = ptr; /* LCOV_EXCL_LINE */
5447 }
5448 return XML_ERROR_RECURSIVE_ENTITY_REF;
5449 }
5450 if (entity->notation) {
5451 if (enc == parser->m_encoding)
5452 parser->m_eventPtr = ptr;
5453 return XML_ERROR_BINARY_ENTITY_REF;
5454 }
5455 if (! entity->textPtr) {
5456 if (enc == parser->m_encoding)
5457 parser->m_eventPtr = ptr;
5458 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
5459 } else {
5460 enum XML_Error result;
5461 const XML_Char *textEnd = entity->textPtr + entity->textLen;
5462 entity->open = XML_TRUE;
5463 result = appendAttributeValue(parser, parser->m_internalEncoding,
Haibo Huangd1a324a2020-10-28 22:19:36 -07005464 isCdata, (const char *)entity->textPtr,
5465 (const char *)textEnd, pool);
Haibo Huang40a71912019-10-11 11:13:39 -07005466 entity->open = XML_FALSE;
5467 if (result)
5468 return result;
5469 }
5470 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005471 default:
Elliott Hughes72472942018-01-10 08:36:10 -08005472 /* The only token returned by XmlAttributeValueTok() that does
5473 * not have an explicit case here is XML_TOK_PARTIAL_CHAR.
5474 * Getting that would require an entity name to contain an
5475 * incomplete XML character (e.g. \xE2\x82); however previous
5476 * tokenisers will have already recognised and rejected such
5477 * names before XmlAttributeValueTok() gets a look-in. This
5478 * default case should be retained as a safety net, but the code
5479 * excluded from coverage tests.
5480 *
5481 * LCOV_EXCL_START
5482 */
5483 if (enc == parser->m_encoding)
5484 parser->m_eventPtr = ptr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005485 return XML_ERROR_UNEXPECTED_STATE;
Elliott Hughes72472942018-01-10 08:36:10 -08005486 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005487 }
5488 ptr = next;
5489 }
5490 /* not reached */
5491}
5492
5493static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07005494storeEntityValue(XML_Parser parser, const ENCODING *enc,
5495 const char *entityTextPtr, const char *entityTextEnd) {
5496 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005497 STRING_POOL *pool = &(dtd->entityValuePool);
5498 enum XML_Error result = XML_ERROR_NONE;
5499#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08005500 int oldInEntityValue = parser->m_prologState.inEntityValue;
5501 parser->m_prologState.inEntityValue = 1;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005502#endif /* XML_DTD */
5503 /* never return Null for the value argument in EntityDeclHandler,
5504 since this would indicate an external entity; therefore we
5505 have to make sure that entityValuePool.start is not null */
Haibo Huang40a71912019-10-11 11:13:39 -07005506 if (! pool->blocks) {
5507 if (! poolGrow(pool))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005508 return XML_ERROR_NO_MEMORY;
5509 }
5510
5511 for (;;) {
5512 const char *next;
5513 int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
5514 switch (tok) {
5515 case XML_TOK_PARAM_ENTITY_REF:
5516#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08005517 if (parser->m_isParamEntity || enc != parser->m_encoding) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005518 const XML_Char *name;
5519 ENTITY *entity;
Elliott Hughes72472942018-01-10 08:36:10 -08005520 name = poolStoreString(&parser->m_tempPool, enc,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005521 entityTextPtr + enc->minBytesPerChar,
5522 next - enc->minBytesPerChar);
Haibo Huang40a71912019-10-11 11:13:39 -07005523 if (! name) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005524 result = XML_ERROR_NO_MEMORY;
5525 goto endEntityValue;
5526 }
Elliott Hughes35e432d2012-09-09 14:23:38 -07005527 entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
Elliott Hughes72472942018-01-10 08:36:10 -08005528 poolDiscard(&parser->m_tempPool);
Haibo Huang40a71912019-10-11 11:13:39 -07005529 if (! entity) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005530 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
5531 /* cannot report skipped entity here - see comments on
Elliott Hughes72472942018-01-10 08:36:10 -08005532 parser->m_skippedEntityHandler
5533 if (parser->m_skippedEntityHandler)
5534 parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005535 */
5536 dtd->keepProcessing = dtd->standalone;
5537 goto endEntityValue;
5538 }
5539 if (entity->open) {
Elliott Hughes72472942018-01-10 08:36:10 -08005540 if (enc == parser->m_encoding)
5541 parser->m_eventPtr = entityTextPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005542 result = XML_ERROR_RECURSIVE_ENTITY_REF;
5543 goto endEntityValue;
5544 }
5545 if (entity->systemId) {
Elliott Hughes72472942018-01-10 08:36:10 -08005546 if (parser->m_externalEntityRefHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005547 dtd->paramEntityRead = XML_FALSE;
5548 entity->open = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07005549 if (! parser->m_externalEntityRefHandler(
5550 parser->m_externalEntityRefHandlerArg, 0, entity->base,
5551 entity->systemId, entity->publicId)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005552 entity->open = XML_FALSE;
5553 result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
5554 goto endEntityValue;
5555 }
5556 entity->open = XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07005557 if (! dtd->paramEntityRead)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005558 dtd->keepProcessing = dtd->standalone;
Haibo Huang40a71912019-10-11 11:13:39 -07005559 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005560 dtd->keepProcessing = dtd->standalone;
Haibo Huang40a71912019-10-11 11:13:39 -07005561 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005562 entity->open = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07005563 result = storeEntityValue(
Haibo Huangd1a324a2020-10-28 22:19:36 -07005564 parser, parser->m_internalEncoding, (const char *)entity->textPtr,
5565 (const char *)(entity->textPtr + entity->textLen));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005566 entity->open = XML_FALSE;
5567 if (result)
5568 goto endEntityValue;
5569 }
5570 break;
5571 }
5572#endif /* XML_DTD */
5573 /* In the internal subset, PE references are not legal
5574 within markup declarations, e.g entity values in this case. */
Elliott Hughes72472942018-01-10 08:36:10 -08005575 parser->m_eventPtr = entityTextPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005576 result = XML_ERROR_PARAM_ENTITY_REF;
5577 goto endEntityValue;
5578 case XML_TOK_NONE:
5579 result = XML_ERROR_NONE;
5580 goto endEntityValue;
5581 case XML_TOK_ENTITY_REF:
5582 case XML_TOK_DATA_CHARS:
Haibo Huang40a71912019-10-11 11:13:39 -07005583 if (! poolAppend(pool, enc, entityTextPtr, next)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005584 result = XML_ERROR_NO_MEMORY;
5585 goto endEntityValue;
5586 }
5587 break;
5588 case XML_TOK_TRAILING_CR:
5589 next = entityTextPtr + enc->minBytesPerChar;
5590 /* fall through */
5591 case XML_TOK_DATA_NEWLINE:
Haibo Huang40a71912019-10-11 11:13:39 -07005592 if (pool->end == pool->ptr && ! poolGrow(pool)) {
5593 result = XML_ERROR_NO_MEMORY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005594 goto endEntityValue;
5595 }
5596 *(pool->ptr)++ = 0xA;
5597 break;
Haibo Huang40a71912019-10-11 11:13:39 -07005598 case XML_TOK_CHAR_REF: {
5599 XML_Char buf[XML_ENCODE_MAX];
5600 int i;
5601 int n = XmlCharRefNumber(enc, entityTextPtr);
5602 if (n < 0) {
5603 if (enc == parser->m_encoding)
5604 parser->m_eventPtr = entityTextPtr;
5605 result = XML_ERROR_BAD_CHAR_REF;
5606 goto endEntityValue;
5607 }
5608 n = XmlEncode(n, (ICHAR *)buf);
5609 /* The XmlEncode() functions can never return 0 here. That
5610 * error return happens if the code point passed in is either
5611 * negative or greater than or equal to 0x110000. The
5612 * XmlCharRefNumber() functions will all return a number
5613 * strictly less than 0x110000 or a negative value if an error
5614 * occurred. The negative value is intercepted above, so
5615 * XmlEncode() is never passed a value it might return an
5616 * error for.
5617 */
5618 for (i = 0; i < n; i++) {
5619 if (pool->end == pool->ptr && ! poolGrow(pool)) {
5620 result = XML_ERROR_NO_MEMORY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005621 goto endEntityValue;
5622 }
Haibo Huang40a71912019-10-11 11:13:39 -07005623 *(pool->ptr)++ = buf[i];
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005624 }
Haibo Huang40a71912019-10-11 11:13:39 -07005625 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005626 case XML_TOK_PARTIAL:
Elliott Hughes72472942018-01-10 08:36:10 -08005627 if (enc == parser->m_encoding)
5628 parser->m_eventPtr = entityTextPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005629 result = XML_ERROR_INVALID_TOKEN;
5630 goto endEntityValue;
5631 case XML_TOK_INVALID:
Elliott Hughes72472942018-01-10 08:36:10 -08005632 if (enc == parser->m_encoding)
5633 parser->m_eventPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005634 result = XML_ERROR_INVALID_TOKEN;
5635 goto endEntityValue;
5636 default:
Elliott Hughes72472942018-01-10 08:36:10 -08005637 /* This default case should be unnecessary -- all the tokens
5638 * that XmlEntityValueTok() can return have their own explicit
5639 * cases -- but should be retained for safety. We do however
5640 * exclude it from the coverage statistics.
5641 *
5642 * LCOV_EXCL_START
5643 */
5644 if (enc == parser->m_encoding)
5645 parser->m_eventPtr = entityTextPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005646 result = XML_ERROR_UNEXPECTED_STATE;
5647 goto endEntityValue;
Elliott Hughes72472942018-01-10 08:36:10 -08005648 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005649 }
5650 entityTextPtr = next;
5651 }
5652endEntityValue:
5653#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08005654 parser->m_prologState.inEntityValue = oldInEntityValue;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005655#endif /* XML_DTD */
5656 return result;
5657}
5658
5659static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07005660normalizeLines(XML_Char *s) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005661 XML_Char *p;
5662 for (;; s++) {
5663 if (*s == XML_T('\0'))
5664 return;
5665 if (*s == 0xD)
5666 break;
5667 }
5668 p = s;
5669 do {
5670 if (*s == 0xD) {
5671 *p++ = 0xA;
5672 if (*++s == 0xA)
5673 s++;
Haibo Huang40a71912019-10-11 11:13:39 -07005674 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005675 *p++ = *s++;
5676 } while (*s);
5677 *p = XML_T('\0');
5678}
5679
5680static int
5681reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
Haibo Huang40a71912019-10-11 11:13:39 -07005682 const char *start, const char *end) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005683 const XML_Char *target;
5684 XML_Char *data;
5685 const char *tem;
Haibo Huang40a71912019-10-11 11:13:39 -07005686 if (! parser->m_processingInstructionHandler) {
Elliott Hughes72472942018-01-10 08:36:10 -08005687 if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005688 reportDefault(parser, enc, start, end);
5689 return 1;
5690 }
5691 start += enc->minBytesPerChar * 2;
5692 tem = start + XmlNameLength(enc, start);
Elliott Hughes72472942018-01-10 08:36:10 -08005693 target = poolStoreString(&parser->m_tempPool, enc, start, tem);
Haibo Huang40a71912019-10-11 11:13:39 -07005694 if (! target)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005695 return 0;
Elliott Hughes72472942018-01-10 08:36:10 -08005696 poolFinish(&parser->m_tempPool);
Haibo Huang40a71912019-10-11 11:13:39 -07005697 data = poolStoreString(&parser->m_tempPool, enc, XmlSkipS(enc, tem),
5698 end - enc->minBytesPerChar * 2);
5699 if (! data)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005700 return 0;
5701 normalizeLines(data);
Elliott Hughes72472942018-01-10 08:36:10 -08005702 parser->m_processingInstructionHandler(parser->m_handlerArg, target, data);
5703 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005704 return 1;
5705}
5706
5707static int
Haibo Huang40a71912019-10-11 11:13:39 -07005708reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
5709 const char *end) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005710 XML_Char *data;
Haibo Huang40a71912019-10-11 11:13:39 -07005711 if (! parser->m_commentHandler) {
Elliott Hughes72472942018-01-10 08:36:10 -08005712 if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005713 reportDefault(parser, enc, start, end);
5714 return 1;
5715 }
Haibo Huang40a71912019-10-11 11:13:39 -07005716 data = poolStoreString(&parser->m_tempPool, enc,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005717 start + enc->minBytesPerChar * 4,
5718 end - enc->minBytesPerChar * 3);
Haibo Huang40a71912019-10-11 11:13:39 -07005719 if (! data)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005720 return 0;
5721 normalizeLines(data);
Elliott Hughes72472942018-01-10 08:36:10 -08005722 parser->m_commentHandler(parser->m_handlerArg, data);
5723 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005724 return 1;
5725}
5726
5727static void
Haibo Huang40a71912019-10-11 11:13:39 -07005728reportDefault(XML_Parser parser, const ENCODING *enc, const char *s,
5729 const char *end) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005730 if (MUST_CONVERT(enc, s)) {
Paul Duffin4bf8f122016-05-13 12:35:25 +01005731 enum XML_Convert_Result convert_res;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005732 const char **eventPP;
5733 const char **eventEndPP;
Elliott Hughes72472942018-01-10 08:36:10 -08005734 if (enc == parser->m_encoding) {
5735 eventPP = &parser->m_eventPtr;
5736 eventEndPP = &parser->m_eventEndPtr;
Haibo Huang40a71912019-10-11 11:13:39 -07005737 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08005738 /* To get here, two things must be true; the parser must be
5739 * using a character encoding that is not the same as the
5740 * encoding passed in, and the encoding passed in must need
5741 * conversion to the internal format (UTF-8 unless XML_UNICODE
5742 * is defined). The only occasions on which the encoding passed
5743 * in is not the same as the parser's encoding are when it is
5744 * the internal encoding (e.g. a previously defined parameter
5745 * entity, already converted to internal format). This by
5746 * definition doesn't need conversion, so the whole branch never
5747 * gets executed.
5748 *
5749 * For safety's sake we don't delete these lines and merely
5750 * exclude them from coverage statistics.
5751 *
5752 * LCOV_EXCL_START
5753 */
5754 eventPP = &(parser->m_openInternalEntities->internalEventPtr);
5755 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
5756 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005757 }
5758 do {
Elliott Hughes72472942018-01-10 08:36:10 -08005759 ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
Haibo Huang40a71912019-10-11 11:13:39 -07005760 convert_res
5761 = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005762 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07005763 parser->m_defaultHandler(parser->m_handlerArg, parser->m_dataBuf,
5764 (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005765 *eventPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07005766 } while ((convert_res != XML_CONVERT_COMPLETED)
5767 && (convert_res != XML_CONVERT_INPUT_INCOMPLETE));
5768 } else
5769 parser->m_defaultHandler(parser->m_handlerArg, (XML_Char *)s,
5770 (int)((XML_Char *)end - (XML_Char *)s));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005771}
5772
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005773static int
5774defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
Haibo Huang40a71912019-10-11 11:13:39 -07005775 XML_Bool isId, const XML_Char *value, XML_Parser parser) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005776 DEFAULT_ATTRIBUTE *att;
5777 if (value || isId) {
5778 /* The handling of default attributes gets messed up if we have
5779 a default which duplicates a non-default. */
5780 int i;
5781 for (i = 0; i < type->nDefaultAtts; i++)
5782 if (attId == type->defaultAtts[i].id)
5783 return 1;
Haibo Huang40a71912019-10-11 11:13:39 -07005784 if (isId && ! type->idAtt && ! attId->xmlns)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005785 type->idAtt = attId;
5786 }
5787 if (type->nDefaultAtts == type->allocDefaultAtts) {
5788 if (type->allocDefaultAtts == 0) {
5789 type->allocDefaultAtts = 8;
Haibo Huang40a71912019-10-11 11:13:39 -07005790 type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(
5791 parser, type->allocDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
5792 if (! type->defaultAtts) {
Elliott Hughes72472942018-01-10 08:36:10 -08005793 type->allocDefaultAtts = 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005794 return 0;
Elliott Hughes72472942018-01-10 08:36:10 -08005795 }
Haibo Huang40a71912019-10-11 11:13:39 -07005796 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005797 DEFAULT_ATTRIBUTE *temp;
5798 int count = type->allocDefaultAtts * 2;
Haibo Huang40a71912019-10-11 11:13:39 -07005799 temp = (DEFAULT_ATTRIBUTE *)REALLOC(parser, type->defaultAtts,
5800 (count * sizeof(DEFAULT_ATTRIBUTE)));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005801 if (temp == NULL)
5802 return 0;
5803 type->allocDefaultAtts = count;
5804 type->defaultAtts = temp;
5805 }
5806 }
5807 att = type->defaultAtts + type->nDefaultAtts;
5808 att->id = attId;
5809 att->value = value;
5810 att->isCdata = isCdata;
Haibo Huang40a71912019-10-11 11:13:39 -07005811 if (! isCdata)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005812 attId->maybeTokenized = XML_TRUE;
5813 type->nDefaultAtts += 1;
5814 return 1;
5815}
5816
5817static int
Haibo Huang40a71912019-10-11 11:13:39 -07005818setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType) {
5819 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005820 const XML_Char *name;
5821 for (name = elementType->name; *name; name++) {
Elliott Hughesd07d5a72009-09-25 16:04:37 -07005822 if (*name == XML_T(ASCII_COLON)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005823 PREFIX *prefix;
5824 const XML_Char *s;
5825 for (s = elementType->name; s != name; s++) {
Haibo Huang40a71912019-10-11 11:13:39 -07005826 if (! poolAppendChar(&dtd->pool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005827 return 0;
5828 }
Haibo Huang40a71912019-10-11 11:13:39 -07005829 if (! poolAppendChar(&dtd->pool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005830 return 0;
Elliott Hughes35e432d2012-09-09 14:23:38 -07005831 prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005832 sizeof(PREFIX));
Haibo Huang40a71912019-10-11 11:13:39 -07005833 if (! prefix)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005834 return 0;
5835 if (prefix->name == poolStart(&dtd->pool))
5836 poolFinish(&dtd->pool);
5837 else
5838 poolDiscard(&dtd->pool);
5839 elementType->prefix = prefix;
Haibo Huangfd5e81a2019-06-20 12:09:36 -07005840 break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005841 }
5842 }
5843 return 1;
5844}
5845
5846static ATTRIBUTE_ID *
Haibo Huang40a71912019-10-11 11:13:39 -07005847getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
5848 const char *end) {
5849 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005850 ATTRIBUTE_ID *id;
5851 const XML_Char *name;
Haibo Huang40a71912019-10-11 11:13:39 -07005852 if (! poolAppendChar(&dtd->pool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005853 return NULL;
5854 name = poolStoreString(&dtd->pool, enc, start, end);
Haibo Huang40a71912019-10-11 11:13:39 -07005855 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005856 return NULL;
5857 /* skip quotation mark - its storage will be re-used (like in name[-1]) */
5858 ++name;
Haibo Huang40a71912019-10-11 11:13:39 -07005859 id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name,
5860 sizeof(ATTRIBUTE_ID));
5861 if (! id)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005862 return NULL;
5863 if (id->name != name)
5864 poolDiscard(&dtd->pool);
5865 else {
5866 poolFinish(&dtd->pool);
Haibo Huang40a71912019-10-11 11:13:39 -07005867 if (! parser->m_ns)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005868 ;
Haibo Huang40a71912019-10-11 11:13:39 -07005869 else if (name[0] == XML_T(ASCII_x) && name[1] == XML_T(ASCII_m)
5870 && name[2] == XML_T(ASCII_l) && name[3] == XML_T(ASCII_n)
5871 && name[4] == XML_T(ASCII_s)
5872 && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005873 if (name[5] == XML_T('\0'))
5874 id->prefix = &dtd->defaultPrefix;
5875 else
Haibo Huang40a71912019-10-11 11:13:39 -07005876 id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6,
5877 sizeof(PREFIX));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005878 id->xmlns = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07005879 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005880 int i;
5881 for (i = 0; name[i]; i++) {
5882 /* attributes without prefix are *not* in the default namespace */
Elliott Hughesd07d5a72009-09-25 16:04:37 -07005883 if (name[i] == XML_T(ASCII_COLON)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005884 int j;
5885 for (j = 0; j < i; j++) {
Haibo Huang40a71912019-10-11 11:13:39 -07005886 if (! poolAppendChar(&dtd->pool, name[j]))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005887 return NULL;
5888 }
Haibo Huang40a71912019-10-11 11:13:39 -07005889 if (! poolAppendChar(&dtd->pool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005890 return NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07005891 id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes,
5892 poolStart(&dtd->pool), sizeof(PREFIX));
5893 if (! id->prefix)
Paul Duffinc05e0322016-05-04 10:42:31 +01005894 return NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005895 if (id->prefix->name == poolStart(&dtd->pool))
5896 poolFinish(&dtd->pool);
5897 else
5898 poolDiscard(&dtd->pool);
5899 break;
5900 }
5901 }
5902 }
5903 }
5904 return id;
5905}
5906
Elliott Hughesd07d5a72009-09-25 16:04:37 -07005907#define CONTEXT_SEP XML_T(ASCII_FF)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005908
5909static const XML_Char *
Haibo Huang40a71912019-10-11 11:13:39 -07005910getContext(XML_Parser parser) {
5911 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005912 HASH_TABLE_ITER iter;
5913 XML_Bool needSep = XML_FALSE;
5914
5915 if (dtd->defaultPrefix.binding) {
5916 int i;
5917 int len;
Haibo Huang40a71912019-10-11 11:13:39 -07005918 if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS)))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005919 return NULL;
5920 len = dtd->defaultPrefix.binding->uriLen;
Elliott Hughes72472942018-01-10 08:36:10 -08005921 if (parser->m_namespaceSeparator)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005922 len--;
Elliott Hughes72472942018-01-10 08:36:10 -08005923 for (i = 0; i < len; i++) {
Haibo Huang40a71912019-10-11 11:13:39 -07005924 if (! poolAppendChar(&parser->m_tempPool,
5925 dtd->defaultPrefix.binding->uri[i])) {
Elliott Hughes72472942018-01-10 08:36:10 -08005926 /* Because of memory caching, I don't believe this line can be
5927 * executed.
5928 *
5929 * This is part of a loop copying the default prefix binding
5930 * URI into the parser's temporary string pool. Previously,
5931 * that URI was copied into the same string pool, with a
5932 * terminating NUL character, as part of setContext(). When
5933 * the pool was cleared, that leaves a block definitely big
5934 * enough to hold the URI on the free block list of the pool.
5935 * The URI copy in getContext() therefore cannot run out of
5936 * memory.
5937 *
5938 * If the pool is used between the setContext() and
5939 * getContext() calls, the worst it can do is leave a bigger
5940 * block on the front of the free list. Given that this is
5941 * all somewhat inobvious and program logic can be changed, we
5942 * don't delete the line but we do exclude it from the test
5943 * coverage statistics.
5944 */
5945 return NULL; /* LCOV_EXCL_LINE */
5946 }
5947 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005948 needSep = XML_TRUE;
5949 }
5950
5951 hashTableIterInit(&iter, &(dtd->prefixes));
5952 for (;;) {
5953 int i;
5954 int len;
5955 const XML_Char *s;
5956 PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07005957 if (! prefix)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005958 break;
Haibo Huang40a71912019-10-11 11:13:39 -07005959 if (! prefix->binding) {
Elliott Hughes72472942018-01-10 08:36:10 -08005960 /* This test appears to be (justifiable) paranoia. There does
5961 * not seem to be a way of injecting a prefix without a binding
5962 * that doesn't get errored long before this function is called.
5963 * The test should remain for safety's sake, so we instead
5964 * exclude the following line from the coverage statistics.
5965 */
5966 continue; /* LCOV_EXCL_LINE */
5967 }
Haibo Huang40a71912019-10-11 11:13:39 -07005968 if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005969 return NULL;
5970 for (s = prefix->name; *s; s++)
Haibo Huang40a71912019-10-11 11:13:39 -07005971 if (! poolAppendChar(&parser->m_tempPool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005972 return NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07005973 if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS)))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005974 return NULL;
5975 len = prefix->binding->uriLen;
Elliott Hughes72472942018-01-10 08:36:10 -08005976 if (parser->m_namespaceSeparator)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005977 len--;
5978 for (i = 0; i < len; i++)
Haibo Huang40a71912019-10-11 11:13:39 -07005979 if (! poolAppendChar(&parser->m_tempPool, prefix->binding->uri[i]))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005980 return NULL;
5981 needSep = XML_TRUE;
5982 }
5983
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005984 hashTableIterInit(&iter, &(dtd->generalEntities));
5985 for (;;) {
5986 const XML_Char *s;
5987 ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07005988 if (! e)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005989 break;
Haibo Huang40a71912019-10-11 11:13:39 -07005990 if (! e->open)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005991 continue;
Haibo Huang40a71912019-10-11 11:13:39 -07005992 if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005993 return NULL;
5994 for (s = e->name; *s; s++)
Haibo Huang40a71912019-10-11 11:13:39 -07005995 if (! poolAppendChar(&parser->m_tempPool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005996 return 0;
5997 needSep = XML_TRUE;
5998 }
5999
Haibo Huang40a71912019-10-11 11:13:39 -07006000 if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006001 return NULL;
Elliott Hughes72472942018-01-10 08:36:10 -08006002 return parser->m_tempPool.start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006003}
6004
6005static XML_Bool
Haibo Huang40a71912019-10-11 11:13:39 -07006006setContext(XML_Parser parser, const XML_Char *context) {
6007 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006008 const XML_Char *s = context;
6009
6010 while (*context != XML_T('\0')) {
6011 if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
6012 ENTITY *e;
Haibo Huang40a71912019-10-11 11:13:39 -07006013 if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006014 return XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07006015 e = (ENTITY *)lookup(parser, &dtd->generalEntities,
6016 poolStart(&parser->m_tempPool), 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006017 if (e)
6018 e->open = XML_TRUE;
6019 if (*s != XML_T('\0'))
6020 s++;
6021 context = s;
Elliott Hughes72472942018-01-10 08:36:10 -08006022 poolDiscard(&parser->m_tempPool);
Haibo Huang40a71912019-10-11 11:13:39 -07006023 } else if (*s == XML_T(ASCII_EQUALS)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006024 PREFIX *prefix;
Elliott Hughes72472942018-01-10 08:36:10 -08006025 if (poolLength(&parser->m_tempPool) == 0)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006026 prefix = &dtd->defaultPrefix;
6027 else {
Haibo Huang40a71912019-10-11 11:13:39 -07006028 if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006029 return XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07006030 prefix
6031 = (PREFIX *)lookup(parser, &dtd->prefixes,
6032 poolStart(&parser->m_tempPool), sizeof(PREFIX));
6033 if (! prefix)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006034 return XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08006035 if (prefix->name == poolStart(&parser->m_tempPool)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006036 prefix->name = poolCopyString(&dtd->pool, prefix->name);
Haibo Huang40a71912019-10-11 11:13:39 -07006037 if (! prefix->name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006038 return XML_FALSE;
6039 }
Elliott Hughes72472942018-01-10 08:36:10 -08006040 poolDiscard(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006041 }
Haibo Huang40a71912019-10-11 11:13:39 -07006042 for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0');
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006043 context++)
Haibo Huang40a71912019-10-11 11:13:39 -07006044 if (! poolAppendChar(&parser->m_tempPool, *context))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006045 return XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07006046 if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006047 return XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08006048 if (addBinding(parser, prefix, NULL, poolStart(&parser->m_tempPool),
Haibo Huang40a71912019-10-11 11:13:39 -07006049 &parser->m_inheritedBindings)
6050 != XML_ERROR_NONE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006051 return XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08006052 poolDiscard(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006053 if (*context != XML_T('\0'))
6054 ++context;
6055 s = context;
Haibo Huang40a71912019-10-11 11:13:39 -07006056 } else {
6057 if (! poolAppendChar(&parser->m_tempPool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006058 return XML_FALSE;
6059 s++;
6060 }
6061 }
6062 return XML_TRUE;
6063}
6064
6065static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006066normalizePublicId(XML_Char *publicId) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006067 XML_Char *p = publicId;
6068 XML_Char *s;
6069 for (s = publicId; *s; s++) {
6070 switch (*s) {
6071 case 0x20:
6072 case 0xD:
6073 case 0xA:
6074 if (p != publicId && p[-1] != 0x20)
6075 *p++ = 0x20;
6076 break;
6077 default:
6078 *p++ = *s;
6079 }
6080 }
6081 if (p != publicId && p[-1] == 0x20)
6082 --p;
6083 *p = XML_T('\0');
6084}
6085
6086static DTD *
Haibo Huang40a71912019-10-11 11:13:39 -07006087dtdCreate(const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006088 DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
6089 if (p == NULL)
6090 return p;
6091 poolInit(&(p->pool), ms);
6092 poolInit(&(p->entityValuePool), ms);
6093 hashTableInit(&(p->generalEntities), ms);
6094 hashTableInit(&(p->elementTypes), ms);
6095 hashTableInit(&(p->attributeIds), ms);
6096 hashTableInit(&(p->prefixes), ms);
6097#ifdef XML_DTD
6098 p->paramEntityRead = XML_FALSE;
6099 hashTableInit(&(p->paramEntities), ms);
6100#endif /* XML_DTD */
6101 p->defaultPrefix.name = NULL;
6102 p->defaultPrefix.binding = NULL;
6103
6104 p->in_eldecl = XML_FALSE;
6105 p->scaffIndex = NULL;
6106 p->scaffold = NULL;
6107 p->scaffLevel = 0;
6108 p->scaffSize = 0;
6109 p->scaffCount = 0;
6110 p->contentStringLen = 0;
6111
6112 p->keepProcessing = XML_TRUE;
6113 p->hasParamEntityRefs = XML_FALSE;
6114 p->standalone = XML_FALSE;
6115 return p;
6116}
6117
6118static void
Haibo Huang40a71912019-10-11 11:13:39 -07006119dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006120 HASH_TABLE_ITER iter;
6121 hashTableIterInit(&iter, &(p->elementTypes));
6122 for (;;) {
6123 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006124 if (! e)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006125 break;
6126 if (e->allocDefaultAtts != 0)
6127 ms->free_fcn(e->defaultAtts);
6128 }
6129 hashTableClear(&(p->generalEntities));
6130#ifdef XML_DTD
6131 p->paramEntityRead = XML_FALSE;
6132 hashTableClear(&(p->paramEntities));
6133#endif /* XML_DTD */
6134 hashTableClear(&(p->elementTypes));
6135 hashTableClear(&(p->attributeIds));
6136 hashTableClear(&(p->prefixes));
6137 poolClear(&(p->pool));
6138 poolClear(&(p->entityValuePool));
6139 p->defaultPrefix.name = NULL;
6140 p->defaultPrefix.binding = NULL;
6141
6142 p->in_eldecl = XML_FALSE;
6143
6144 ms->free_fcn(p->scaffIndex);
6145 p->scaffIndex = NULL;
6146 ms->free_fcn(p->scaffold);
6147 p->scaffold = NULL;
6148
6149 p->scaffLevel = 0;
6150 p->scaffSize = 0;
6151 p->scaffCount = 0;
6152 p->contentStringLen = 0;
6153
6154 p->keepProcessing = XML_TRUE;
6155 p->hasParamEntityRefs = XML_FALSE;
6156 p->standalone = XML_FALSE;
6157}
6158
6159static void
Haibo Huang40a71912019-10-11 11:13:39 -07006160dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006161 HASH_TABLE_ITER iter;
6162 hashTableIterInit(&iter, &(p->elementTypes));
6163 for (;;) {
6164 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006165 if (! e)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006166 break;
6167 if (e->allocDefaultAtts != 0)
6168 ms->free_fcn(e->defaultAtts);
6169 }
6170 hashTableDestroy(&(p->generalEntities));
6171#ifdef XML_DTD
6172 hashTableDestroy(&(p->paramEntities));
6173#endif /* XML_DTD */
6174 hashTableDestroy(&(p->elementTypes));
6175 hashTableDestroy(&(p->attributeIds));
6176 hashTableDestroy(&(p->prefixes));
6177 poolDestroy(&(p->pool));
6178 poolDestroy(&(p->entityValuePool));
6179 if (isDocEntity) {
6180 ms->free_fcn(p->scaffIndex);
6181 ms->free_fcn(p->scaffold);
6182 }
6183 ms->free_fcn(p);
6184}
6185
6186/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
6187 The new DTD has already been initialized.
6188*/
6189static int
Haibo Huang40a71912019-10-11 11:13:39 -07006190dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
6191 const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006192 HASH_TABLE_ITER iter;
6193
6194 /* Copy the prefix table. */
6195
6196 hashTableIterInit(&iter, &(oldDtd->prefixes));
6197 for (;;) {
6198 const XML_Char *name;
6199 const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006200 if (! oldP)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006201 break;
6202 name = poolCopyString(&(newDtd->pool), oldP->name);
Haibo Huang40a71912019-10-11 11:13:39 -07006203 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006204 return 0;
Haibo Huang40a71912019-10-11 11:13:39 -07006205 if (! lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX)))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006206 return 0;
6207 }
6208
6209 hashTableIterInit(&iter, &(oldDtd->attributeIds));
6210
6211 /* Copy the attribute id table. */
6212
6213 for (;;) {
6214 ATTRIBUTE_ID *newA;
6215 const XML_Char *name;
6216 const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
6217
Haibo Huang40a71912019-10-11 11:13:39 -07006218 if (! oldA)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006219 break;
6220 /* Remember to allocate the scratch byte before the name. */
Haibo Huang40a71912019-10-11 11:13:39 -07006221 if (! poolAppendChar(&(newDtd->pool), XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006222 return 0;
6223 name = poolCopyString(&(newDtd->pool), oldA->name);
Haibo Huang40a71912019-10-11 11:13:39 -07006224 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006225 return 0;
6226 ++name;
Elliott Hughes35e432d2012-09-09 14:23:38 -07006227 newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006228 sizeof(ATTRIBUTE_ID));
Haibo Huang40a71912019-10-11 11:13:39 -07006229 if (! newA)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006230 return 0;
6231 newA->maybeTokenized = oldA->maybeTokenized;
6232 if (oldA->prefix) {
6233 newA->xmlns = oldA->xmlns;
6234 if (oldA->prefix == &oldDtd->defaultPrefix)
6235 newA->prefix = &newDtd->defaultPrefix;
6236 else
Elliott Hughes35e432d2012-09-09 14:23:38 -07006237 newA->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006238 oldA->prefix->name, 0);
6239 }
6240 }
6241
6242 /* Copy the element type table. */
6243
6244 hashTableIterInit(&iter, &(oldDtd->elementTypes));
6245
6246 for (;;) {
6247 int i;
6248 ELEMENT_TYPE *newE;
6249 const XML_Char *name;
6250 const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006251 if (! oldE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006252 break;
6253 name = poolCopyString(&(newDtd->pool), oldE->name);
Haibo Huang40a71912019-10-11 11:13:39 -07006254 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006255 return 0;
Elliott Hughes35e432d2012-09-09 14:23:38 -07006256 newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006257 sizeof(ELEMENT_TYPE));
Haibo Huang40a71912019-10-11 11:13:39 -07006258 if (! newE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006259 return 0;
6260 if (oldE->nDefaultAtts) {
Haibo Huang40a71912019-10-11 11:13:39 -07006261 newE->defaultAtts = (DEFAULT_ATTRIBUTE *)ms->malloc_fcn(
6262 oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
6263 if (! newE->defaultAtts) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006264 return 0;
6265 }
6266 }
6267 if (oldE->idAtt)
Haibo Huang40a71912019-10-11 11:13:39 -07006268 newE->idAtt = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds),
6269 oldE->idAtt->name, 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006270 newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
6271 if (oldE->prefix)
Elliott Hughes35e432d2012-09-09 14:23:38 -07006272 newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006273 oldE->prefix->name, 0);
6274 for (i = 0; i < newE->nDefaultAtts; i++) {
Haibo Huang40a71912019-10-11 11:13:39 -07006275 newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup(
6276 oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006277 newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
6278 if (oldE->defaultAtts[i].value) {
6279 newE->defaultAtts[i].value
6280 = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
Haibo Huang40a71912019-10-11 11:13:39 -07006281 if (! newE->defaultAtts[i].value)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006282 return 0;
Haibo Huang40a71912019-10-11 11:13:39 -07006283 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006284 newE->defaultAtts[i].value = NULL;
6285 }
6286 }
6287
6288 /* Copy the entity tables. */
Haibo Huang40a71912019-10-11 11:13:39 -07006289 if (! copyEntityTable(oldParser, &(newDtd->generalEntities), &(newDtd->pool),
6290 &(oldDtd->generalEntities)))
6291 return 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006292
6293#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07006294 if (! copyEntityTable(oldParser, &(newDtd->paramEntities), &(newDtd->pool),
6295 &(oldDtd->paramEntities)))
6296 return 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006297 newDtd->paramEntityRead = oldDtd->paramEntityRead;
6298#endif /* XML_DTD */
6299
6300 newDtd->keepProcessing = oldDtd->keepProcessing;
6301 newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
6302 newDtd->standalone = oldDtd->standalone;
6303
6304 /* Don't want deep copying for scaffolding */
6305 newDtd->in_eldecl = oldDtd->in_eldecl;
6306 newDtd->scaffold = oldDtd->scaffold;
6307 newDtd->contentStringLen = oldDtd->contentStringLen;
6308 newDtd->scaffSize = oldDtd->scaffSize;
6309 newDtd->scaffLevel = oldDtd->scaffLevel;
6310 newDtd->scaffIndex = oldDtd->scaffIndex;
6311
6312 return 1;
Haibo Huang40a71912019-10-11 11:13:39 -07006313} /* End dtdCopy */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006314
6315static int
Haibo Huang40a71912019-10-11 11:13:39 -07006316copyEntityTable(XML_Parser oldParser, HASH_TABLE *newTable,
6317 STRING_POOL *newPool, const HASH_TABLE *oldTable) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006318 HASH_TABLE_ITER iter;
6319 const XML_Char *cachedOldBase = NULL;
6320 const XML_Char *cachedNewBase = NULL;
6321
6322 hashTableIterInit(&iter, oldTable);
6323
6324 for (;;) {
6325 ENTITY *newE;
6326 const XML_Char *name;
6327 const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006328 if (! oldE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006329 break;
6330 name = poolCopyString(newPool, oldE->name);
Haibo Huang40a71912019-10-11 11:13:39 -07006331 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006332 return 0;
Elliott Hughes35e432d2012-09-09 14:23:38 -07006333 newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY));
Haibo Huang40a71912019-10-11 11:13:39 -07006334 if (! newE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006335 return 0;
6336 if (oldE->systemId) {
6337 const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
Haibo Huang40a71912019-10-11 11:13:39 -07006338 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006339 return 0;
6340 newE->systemId = tem;
6341 if (oldE->base) {
6342 if (oldE->base == cachedOldBase)
6343 newE->base = cachedNewBase;
6344 else {
6345 cachedOldBase = oldE->base;
6346 tem = poolCopyString(newPool, cachedOldBase);
Haibo Huang40a71912019-10-11 11:13:39 -07006347 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006348 return 0;
6349 cachedNewBase = newE->base = tem;
6350 }
6351 }
6352 if (oldE->publicId) {
6353 tem = poolCopyString(newPool, oldE->publicId);
Haibo Huang40a71912019-10-11 11:13:39 -07006354 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006355 return 0;
6356 newE->publicId = tem;
6357 }
Haibo Huang40a71912019-10-11 11:13:39 -07006358 } else {
6359 const XML_Char *tem
6360 = poolCopyStringN(newPool, oldE->textPtr, oldE->textLen);
6361 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006362 return 0;
6363 newE->textPtr = tem;
6364 newE->textLen = oldE->textLen;
6365 }
6366 if (oldE->notation) {
6367 const XML_Char *tem = poolCopyString(newPool, oldE->notation);
Haibo Huang40a71912019-10-11 11:13:39 -07006368 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006369 return 0;
6370 newE->notation = tem;
6371 }
6372 newE->is_param = oldE->is_param;
6373 newE->is_internal = oldE->is_internal;
6374 }
6375 return 1;
6376}
6377
6378#define INIT_POWER 6
6379
6380static XML_Bool FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006381keyeq(KEY s1, KEY s2) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006382 for (; *s1 == *s2; s1++, s2++)
6383 if (*s1 == 0)
6384 return XML_TRUE;
6385 return XML_FALSE;
6386}
6387
Elliott Hughes72472942018-01-10 08:36:10 -08006388static size_t
Haibo Huang40a71912019-10-11 11:13:39 -07006389keylen(KEY s) {
Elliott Hughes72472942018-01-10 08:36:10 -08006390 size_t len = 0;
Haibo Huang40a71912019-10-11 11:13:39 -07006391 for (; *s; s++, len++)
6392 ;
Elliott Hughes72472942018-01-10 08:36:10 -08006393 return len;
6394}
6395
6396static void
Haibo Huang40a71912019-10-11 11:13:39 -07006397copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key) {
Elliott Hughes72472942018-01-10 08:36:10 -08006398 key->k[0] = 0;
6399 key->k[1] = get_hash_secret_salt(parser);
6400}
6401
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006402static unsigned long FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006403hash(XML_Parser parser, KEY s) {
Elliott Hughes72472942018-01-10 08:36:10 -08006404 struct siphash state;
6405 struct sipkey key;
Elliott Hughes72472942018-01-10 08:36:10 -08006406 (void)sip24_valid;
6407 copy_salt_to_sipkey(parser, &key);
6408 sip24_init(&state, &key);
6409 sip24_update(&state, s, keylen(s) * sizeof(XML_Char));
6410 return (unsigned long)sip24_final(&state);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006411}
6412
6413static NAMED *
Haibo Huang40a71912019-10-11 11:13:39 -07006414lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006415 size_t i;
6416 if (table->size == 0) {
6417 size_t tsize;
Haibo Huang40a71912019-10-11 11:13:39 -07006418 if (! createSize)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006419 return NULL;
6420 table->power = INIT_POWER;
6421 /* table->size is a power of 2 */
6422 table->size = (size_t)1 << INIT_POWER;
6423 tsize = table->size * sizeof(NAMED *);
6424 table->v = (NAMED **)table->mem->malloc_fcn(tsize);
Haibo Huang40a71912019-10-11 11:13:39 -07006425 if (! table->v) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006426 table->size = 0;
6427 return NULL;
6428 }
6429 memset(table->v, 0, tsize);
Elliott Hughes35e432d2012-09-09 14:23:38 -07006430 i = hash(parser, name) & ((unsigned long)table->size - 1);
Haibo Huang40a71912019-10-11 11:13:39 -07006431 } else {
Elliott Hughes35e432d2012-09-09 14:23:38 -07006432 unsigned long h = hash(parser, name);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006433 unsigned long mask = (unsigned long)table->size - 1;
6434 unsigned char step = 0;
6435 i = h & mask;
6436 while (table->v[i]) {
6437 if (keyeq(name, table->v[i]->name))
6438 return table->v[i];
Haibo Huang40a71912019-10-11 11:13:39 -07006439 if (! step)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006440 step = PROBE_STEP(h, mask, table->power);
6441 i < step ? (i += table->size - step) : (i -= step);
6442 }
Haibo Huang40a71912019-10-11 11:13:39 -07006443 if (! createSize)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006444 return NULL;
6445
6446 /* check for overflow (table is half full) */
6447 if (table->used >> (table->power - 1)) {
6448 unsigned char newPower = table->power + 1;
6449 size_t newSize = (size_t)1 << newPower;
6450 unsigned long newMask = (unsigned long)newSize - 1;
6451 size_t tsize = newSize * sizeof(NAMED *);
6452 NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
Haibo Huang40a71912019-10-11 11:13:39 -07006453 if (! newV)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006454 return NULL;
6455 memset(newV, 0, tsize);
6456 for (i = 0; i < table->size; i++)
6457 if (table->v[i]) {
Elliott Hughes35e432d2012-09-09 14:23:38 -07006458 unsigned long newHash = hash(parser, table->v[i]->name);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006459 size_t j = newHash & newMask;
6460 step = 0;
6461 while (newV[j]) {
Haibo Huang40a71912019-10-11 11:13:39 -07006462 if (! step)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006463 step = PROBE_STEP(newHash, newMask, newPower);
6464 j < step ? (j += newSize - step) : (j -= step);
6465 }
6466 newV[j] = table->v[i];
6467 }
6468 table->mem->free_fcn(table->v);
6469 table->v = newV;
6470 table->power = newPower;
6471 table->size = newSize;
6472 i = h & newMask;
6473 step = 0;
6474 while (table->v[i]) {
Haibo Huang40a71912019-10-11 11:13:39 -07006475 if (! step)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006476 step = PROBE_STEP(h, newMask, newPower);
6477 i < step ? (i += newSize - step) : (i -= step);
6478 }
6479 }
6480 }
6481 table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
Haibo Huang40a71912019-10-11 11:13:39 -07006482 if (! table->v[i])
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006483 return NULL;
6484 memset(table->v[i], 0, createSize);
6485 table->v[i]->name = name;
6486 (table->used)++;
6487 return table->v[i];
6488}
6489
6490static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006491hashTableClear(HASH_TABLE *table) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006492 size_t i;
6493 for (i = 0; i < table->size; i++) {
6494 table->mem->free_fcn(table->v[i]);
6495 table->v[i] = NULL;
6496 }
6497 table->used = 0;
6498}
6499
6500static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006501hashTableDestroy(HASH_TABLE *table) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006502 size_t i;
6503 for (i = 0; i < table->size; i++)
6504 table->mem->free_fcn(table->v[i]);
6505 table->mem->free_fcn(table->v);
6506}
6507
6508static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006509hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006510 p->power = 0;
6511 p->size = 0;
6512 p->used = 0;
6513 p->v = NULL;
6514 p->mem = ms;
6515}
6516
6517static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006518hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006519 iter->p = table->v;
Haibo Huangd1a324a2020-10-28 22:19:36 -07006520 iter->end = iter->p ? iter->p + table->size : NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006521}
6522
Haibo Huang40a71912019-10-11 11:13:39 -07006523static NAMED *FASTCALL
6524hashTableIterNext(HASH_TABLE_ITER *iter) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006525 while (iter->p != iter->end) {
6526 NAMED *tem = *(iter->p)++;
6527 if (tem)
6528 return tem;
6529 }
6530 return NULL;
6531}
6532
6533static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006534poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006535 pool->blocks = NULL;
6536 pool->freeBlocks = NULL;
6537 pool->start = NULL;
6538 pool->ptr = NULL;
6539 pool->end = NULL;
6540 pool->mem = ms;
6541}
6542
6543static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006544poolClear(STRING_POOL *pool) {
6545 if (! pool->freeBlocks)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006546 pool->freeBlocks = pool->blocks;
6547 else {
6548 BLOCK *p = pool->blocks;
6549 while (p) {
6550 BLOCK *tem = p->next;
6551 p->next = pool->freeBlocks;
6552 pool->freeBlocks = p;
6553 p = tem;
6554 }
6555 }
6556 pool->blocks = NULL;
6557 pool->start = NULL;
6558 pool->ptr = NULL;
6559 pool->end = NULL;
6560}
6561
6562static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006563poolDestroy(STRING_POOL *pool) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006564 BLOCK *p = pool->blocks;
6565 while (p) {
6566 BLOCK *tem = p->next;
6567 pool->mem->free_fcn(p);
6568 p = tem;
6569 }
6570 p = pool->freeBlocks;
6571 while (p) {
6572 BLOCK *tem = p->next;
6573 pool->mem->free_fcn(p);
6574 p = tem;
6575 }
6576}
6577
6578static XML_Char *
Haibo Huang40a71912019-10-11 11:13:39 -07006579poolAppend(STRING_POOL *pool, const ENCODING *enc, const char *ptr,
6580 const char *end) {
6581 if (! pool->ptr && ! poolGrow(pool))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006582 return NULL;
6583 for (;;) {
Haibo Huang40a71912019-10-11 11:13:39 -07006584 const enum XML_Convert_Result convert_res = XmlConvert(
6585 enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
6586 if ((convert_res == XML_CONVERT_COMPLETED)
6587 || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006588 break;
Haibo Huang40a71912019-10-11 11:13:39 -07006589 if (! poolGrow(pool))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006590 return NULL;
6591 }
6592 return pool->start;
6593}
6594
Haibo Huang40a71912019-10-11 11:13:39 -07006595static const XML_Char *FASTCALL
6596poolCopyString(STRING_POOL *pool, const XML_Char *s) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006597 do {
Haibo Huang40a71912019-10-11 11:13:39 -07006598 if (! poolAppendChar(pool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006599 return NULL;
6600 } while (*s++);
6601 s = pool->start;
6602 poolFinish(pool);
6603 return s;
6604}
6605
6606static const XML_Char *
Haibo Huang40a71912019-10-11 11:13:39 -07006607poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) {
6608 if (! pool->ptr && ! poolGrow(pool)) {
Elliott Hughes72472942018-01-10 08:36:10 -08006609 /* The following line is unreachable given the current usage of
6610 * poolCopyStringN(). Currently it is called from exactly one
6611 * place to copy the text of a simple general entity. By that
6612 * point, the name of the entity is already stored in the pool, so
6613 * pool->ptr cannot be NULL.
6614 *
6615 * If poolCopyStringN() is used elsewhere as it well might be,
6616 * this line may well become executable again. Regardless, this
6617 * sort of check shouldn't be removed lightly, so we just exclude
6618 * it from the coverage statistics.
6619 */
6620 return NULL; /* LCOV_EXCL_LINE */
6621 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006622 for (; n > 0; --n, s++) {
Haibo Huang40a71912019-10-11 11:13:39 -07006623 if (! poolAppendChar(pool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006624 return NULL;
6625 }
6626 s = pool->start;
6627 poolFinish(pool);
6628 return s;
6629}
6630
Haibo Huang40a71912019-10-11 11:13:39 -07006631static const XML_Char *FASTCALL
6632poolAppendString(STRING_POOL *pool, const XML_Char *s) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006633 while (*s) {
Haibo Huang40a71912019-10-11 11:13:39 -07006634 if (! poolAppendChar(pool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006635 return NULL;
6636 s++;
6637 }
6638 return pool->start;
6639}
6640
6641static XML_Char *
Haibo Huang40a71912019-10-11 11:13:39 -07006642poolStoreString(STRING_POOL *pool, const ENCODING *enc, const char *ptr,
6643 const char *end) {
6644 if (! poolAppend(pool, enc, ptr, end))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006645 return NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07006646 if (pool->ptr == pool->end && ! poolGrow(pool))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006647 return NULL;
6648 *(pool->ptr)++ = 0;
6649 return pool->start;
6650}
6651
Elliott Hughes72472942018-01-10 08:36:10 -08006652static size_t
Haibo Huang40a71912019-10-11 11:13:39 -07006653poolBytesToAllocateFor(int blockSize) {
Elliott Hughes72472942018-01-10 08:36:10 -08006654 /* Unprotected math would be:
6655 ** return offsetof(BLOCK, s) + blockSize * sizeof(XML_Char);
6656 **
6657 ** Detect overflow, avoiding _signed_ overflow undefined behavior
6658 ** For a + b * c we check b * c in isolation first, so that addition of a
6659 ** on top has no chance of making us accept a small non-negative number
6660 */
Haibo Huang40a71912019-10-11 11:13:39 -07006661 const size_t stretch = sizeof(XML_Char); /* can be 4 bytes */
Elliott Hughes72472942018-01-10 08:36:10 -08006662
6663 if (blockSize <= 0)
6664 return 0;
6665
6666 if (blockSize > (int)(INT_MAX / stretch))
6667 return 0;
6668
6669 {
6670 const int stretchedBlockSize = blockSize * (int)stretch;
Haibo Huang40a71912019-10-11 11:13:39 -07006671 const int bytesToAllocate
6672 = (int)(offsetof(BLOCK, s) + (unsigned)stretchedBlockSize);
Elliott Hughes72472942018-01-10 08:36:10 -08006673 if (bytesToAllocate < 0)
6674 return 0;
6675
6676 return (size_t)bytesToAllocate;
6677 }
6678}
6679
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006680static XML_Bool FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006681poolGrow(STRING_POOL *pool) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006682 if (pool->freeBlocks) {
6683 if (pool->start == 0) {
6684 pool->blocks = pool->freeBlocks;
6685 pool->freeBlocks = pool->freeBlocks->next;
6686 pool->blocks->next = NULL;
6687 pool->start = pool->blocks->s;
6688 pool->end = pool->start + pool->blocks->size;
6689 pool->ptr = pool->start;
6690 return XML_TRUE;
6691 }
6692 if (pool->end - pool->start < pool->freeBlocks->size) {
6693 BLOCK *tem = pool->freeBlocks->next;
6694 pool->freeBlocks->next = pool->blocks;
6695 pool->blocks = pool->freeBlocks;
6696 pool->freeBlocks = tem;
6697 memcpy(pool->blocks->s, pool->start,
6698 (pool->end - pool->start) * sizeof(XML_Char));
6699 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
6700 pool->start = pool->blocks->s;
6701 pool->end = pool->start + pool->blocks->size;
6702 return XML_TRUE;
6703 }
6704 }
6705 if (pool->blocks && pool->start == pool->blocks->s) {
Paul Duffin4bf8f122016-05-13 12:35:25 +01006706 BLOCK *temp;
Haibo Huang40a71912019-10-11 11:13:39 -07006707 int blockSize = (int)((unsigned)(pool->end - pool->start) * 2U);
Elliott Hughes72472942018-01-10 08:36:10 -08006708 size_t bytesToAllocate;
Paul Duffin4bf8f122016-05-13 12:35:25 +01006709
Elliott Hughes72472942018-01-10 08:36:10 -08006710 /* NOTE: Needs to be calculated prior to calling `realloc`
6711 to avoid dangling pointers: */
6712 const ptrdiff_t offsetInsideBlock = pool->ptr - pool->start;
6713
6714 if (blockSize < 0) {
6715 /* This condition traps a situation where either more than
6716 * INT_MAX/2 bytes have already been allocated. This isn't
6717 * readily testable, since it is unlikely that an average
6718 * machine will have that much memory, so we exclude it from the
6719 * coverage statistics.
6720 */
6721 return XML_FALSE; /* LCOV_EXCL_LINE */
6722 }
6723
6724 bytesToAllocate = poolBytesToAllocateFor(blockSize);
6725 if (bytesToAllocate == 0)
Paul Duffin4bf8f122016-05-13 12:35:25 +01006726 return XML_FALSE;
6727
Haibo Huang40a71912019-10-11 11:13:39 -07006728 temp = (BLOCK *)pool->mem->realloc_fcn(pool->blocks,
6729 (unsigned)bytesToAllocate);
Elliott Hughes35e432d2012-09-09 14:23:38 -07006730 if (temp == NULL)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006731 return XML_FALSE;
Elliott Hughes35e432d2012-09-09 14:23:38 -07006732 pool->blocks = temp;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006733 pool->blocks->size = blockSize;
Elliott Hughes72472942018-01-10 08:36:10 -08006734 pool->ptr = pool->blocks->s + offsetInsideBlock;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006735 pool->start = pool->blocks->s;
6736 pool->end = pool->start + blockSize;
Haibo Huang40a71912019-10-11 11:13:39 -07006737 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006738 BLOCK *tem;
6739 int blockSize = (int)(pool->end - pool->start);
Elliott Hughes72472942018-01-10 08:36:10 -08006740 size_t bytesToAllocate;
Paul Duffin4bf8f122016-05-13 12:35:25 +01006741
Elliott Hughes72472942018-01-10 08:36:10 -08006742 if (blockSize < 0) {
6743 /* This condition traps a situation where either more than
6744 * INT_MAX bytes have already been allocated (which is prevented
6745 * by various pieces of program logic, not least this one, never
6746 * mind the unlikelihood of actually having that much memory) or
6747 * the pool control fields have been corrupted (which could
6748 * conceivably happen in an extremely buggy user handler
6749 * function). Either way it isn't readily testable, so we
6750 * exclude it from the coverage statistics.
6751 */
Haibo Huang40a71912019-10-11 11:13:39 -07006752 return XML_FALSE; /* LCOV_EXCL_LINE */
Elliott Hughes72472942018-01-10 08:36:10 -08006753 }
Paul Duffin4bf8f122016-05-13 12:35:25 +01006754
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006755 if (blockSize < INIT_BLOCK_SIZE)
6756 blockSize = INIT_BLOCK_SIZE;
Elliott Hughes72472942018-01-10 08:36:10 -08006757 else {
6758 /* Detect overflow, avoiding _signed_ overflow undefined behavior */
6759 if ((int)((unsigned)blockSize * 2U) < 0) {
6760 return XML_FALSE;
6761 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006762 blockSize *= 2;
Elliott Hughes72472942018-01-10 08:36:10 -08006763 }
6764
6765 bytesToAllocate = poolBytesToAllocateFor(blockSize);
6766 if (bytesToAllocate == 0)
6767 return XML_FALSE;
6768
6769 tem = (BLOCK *)pool->mem->malloc_fcn(bytesToAllocate);
Haibo Huang40a71912019-10-11 11:13:39 -07006770 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006771 return XML_FALSE;
6772 tem->size = blockSize;
6773 tem->next = pool->blocks;
6774 pool->blocks = tem;
6775 if (pool->ptr != pool->start)
Haibo Huang40a71912019-10-11 11:13:39 -07006776 memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006777 pool->ptr = tem->s + (pool->ptr - pool->start);
6778 pool->start = tem->s;
6779 pool->end = tem->s + blockSize;
6780 }
6781 return XML_TRUE;
6782}
6783
6784static int FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006785nextScaffoldPart(XML_Parser parser) {
6786 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
6787 CONTENT_SCAFFOLD *me;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006788 int next;
6789
Haibo Huang40a71912019-10-11 11:13:39 -07006790 if (! dtd->scaffIndex) {
Elliott Hughes72472942018-01-10 08:36:10 -08006791 dtd->scaffIndex = (int *)MALLOC(parser, parser->m_groupSize * sizeof(int));
Haibo Huang40a71912019-10-11 11:13:39 -07006792 if (! dtd->scaffIndex)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006793 return -1;
6794 dtd->scaffIndex[0] = 0;
6795 }
6796
6797 if (dtd->scaffCount >= dtd->scaffSize) {
6798 CONTENT_SCAFFOLD *temp;
6799 if (dtd->scaffold) {
Haibo Huang40a71912019-10-11 11:13:39 -07006800 temp = (CONTENT_SCAFFOLD *)REALLOC(
6801 parser, dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006802 if (temp == NULL)
6803 return -1;
6804 dtd->scaffSize *= 2;
Haibo Huang40a71912019-10-11 11:13:39 -07006805 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08006806 temp = (CONTENT_SCAFFOLD *)MALLOC(parser, INIT_SCAFFOLD_ELEMENTS
Haibo Huang40a71912019-10-11 11:13:39 -07006807 * sizeof(CONTENT_SCAFFOLD));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006808 if (temp == NULL)
6809 return -1;
6810 dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
6811 }
6812 dtd->scaffold = temp;
6813 }
6814 next = dtd->scaffCount++;
6815 me = &dtd->scaffold[next];
6816 if (dtd->scaffLevel) {
Haibo Huang40a71912019-10-11 11:13:39 -07006817 CONTENT_SCAFFOLD *parent
6818 = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]];
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006819 if (parent->lastchild) {
6820 dtd->scaffold[parent->lastchild].nextsib = next;
6821 }
Haibo Huang40a71912019-10-11 11:13:39 -07006822 if (! parent->childcnt)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006823 parent->firstchild = next;
6824 parent->lastchild = next;
6825 parent->childcnt++;
6826 }
6827 me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
6828 return next;
6829}
6830
6831static void
Haibo Huang40a71912019-10-11 11:13:39 -07006832build_node(XML_Parser parser, int src_node, XML_Content *dest,
6833 XML_Content **contpos, XML_Char **strpos) {
6834 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006835 dest->type = dtd->scaffold[src_node].type;
6836 dest->quant = dtd->scaffold[src_node].quant;
6837 if (dest->type == XML_CTYPE_NAME) {
6838 const XML_Char *src;
6839 dest->name = *strpos;
6840 src = dtd->scaffold[src_node].name;
6841 for (;;) {
6842 *(*strpos)++ = *src;
Haibo Huang40a71912019-10-11 11:13:39 -07006843 if (! *src)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006844 break;
6845 src++;
6846 }
6847 dest->numchildren = 0;
6848 dest->children = NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07006849 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006850 unsigned int i;
6851 int cn;
6852 dest->numchildren = dtd->scaffold[src_node].childcnt;
6853 dest->children = *contpos;
6854 *contpos += dest->numchildren;
Haibo Huang40a71912019-10-11 11:13:39 -07006855 for (i = 0, cn = dtd->scaffold[src_node].firstchild; i < dest->numchildren;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006856 i++, cn = dtd->scaffold[cn].nextsib) {
6857 build_node(parser, cn, &(dest->children[i]), contpos, strpos);
6858 }
6859 dest->name = NULL;
6860 }
6861}
6862
6863static XML_Content *
Haibo Huang40a71912019-10-11 11:13:39 -07006864build_model(XML_Parser parser) {
6865 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006866 XML_Content *ret;
6867 XML_Content *cpos;
Haibo Huang40a71912019-10-11 11:13:39 -07006868 XML_Char *str;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006869 int allocsize = (dtd->scaffCount * sizeof(XML_Content)
6870 + (dtd->contentStringLen * sizeof(XML_Char)));
6871
Elliott Hughes72472942018-01-10 08:36:10 -08006872 ret = (XML_Content *)MALLOC(parser, allocsize);
Haibo Huang40a71912019-10-11 11:13:39 -07006873 if (! ret)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006874 return NULL;
6875
Haibo Huang40a71912019-10-11 11:13:39 -07006876 str = (XML_Char *)(&ret[dtd->scaffCount]);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006877 cpos = &ret[1];
6878
6879 build_node(parser, 0, ret, &cpos, &str);
6880 return ret;
6881}
6882
6883static ELEMENT_TYPE *
Haibo Huang40a71912019-10-11 11:13:39 -07006884getElementType(XML_Parser parser, const ENCODING *enc, const char *ptr,
6885 const char *end) {
6886 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006887 const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
6888 ELEMENT_TYPE *ret;
6889
Haibo Huang40a71912019-10-11 11:13:39 -07006890 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006891 return NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07006892 ret = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
6893 sizeof(ELEMENT_TYPE));
6894 if (! ret)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006895 return NULL;
6896 if (ret->name != name)
6897 poolDiscard(&dtd->pool);
6898 else {
6899 poolFinish(&dtd->pool);
Haibo Huang40a71912019-10-11 11:13:39 -07006900 if (! setElementTypePrefix(parser, ret))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006901 return NULL;
6902 }
6903 return ret;
6904}
Elliott Hughes72472942018-01-10 08:36:10 -08006905
6906static XML_Char *
Haibo Huang40a71912019-10-11 11:13:39 -07006907copyString(const XML_Char *s, const XML_Memory_Handling_Suite *memsuite) {
Sadaf Ebrahimi1adbf372022-05-23 22:34:43 +00006908 size_t charsRequired = 0;
Haibo Huang40a71912019-10-11 11:13:39 -07006909 XML_Char *result;
Elliott Hughes72472942018-01-10 08:36:10 -08006910
Haibo Huang40a71912019-10-11 11:13:39 -07006911 /* First determine how long the string is */
6912 while (s[charsRequired] != 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08006913 charsRequired++;
Haibo Huang40a71912019-10-11 11:13:39 -07006914 }
6915 /* Include the terminator */
6916 charsRequired++;
Elliott Hughes72472942018-01-10 08:36:10 -08006917
Haibo Huang40a71912019-10-11 11:13:39 -07006918 /* Now allocate space for the copy */
6919 result = memsuite->malloc_fcn(charsRequired * sizeof(XML_Char));
6920 if (result == NULL)
6921 return NULL;
6922 /* Copy the original into place */
6923 memcpy(result, s, charsRequired * sizeof(XML_Char));
6924 return result;
Elliott Hughes72472942018-01-10 08:36:10 -08006925}