blob: 381f3ef384ff27b2317b1c1b511321303fa11343 [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) {
Sadaf Ebrahimi500b2052022-11-16 16:31:05 +0000981 if (dtd) {
982 // We need to stop the upcoming call to XML_ParserFree from happily
983 // destroying parser->m_dtd because the DTD is shared with the parent
984 // parser and the only guard that keeps XML_ParserFree from destroying
985 // parser->m_dtd is parser->m_isParamEntity but it will be set to
986 // XML_TRUE only later in XML_ExternalEntityParserCreate (or not at all).
987 parser->m_dtd = NULL;
988 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800989 XML_ParserFree(parser);
990 return NULL;
991 }
992
993 if (nameSep) {
Elliott Hughes72472942018-01-10 08:36:10 -0800994 parser->m_ns = XML_TRUE;
995 parser->m_internalEncoding = XmlGetInternalEncodingNS();
996 parser->m_namespaceSeparator = *nameSep;
Haibo Huang40a71912019-10-11 11:13:39 -0700997 } else {
Elliott Hughes72472942018-01-10 08:36:10 -0800998 parser->m_internalEncoding = XmlGetInternalEncoding();
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800999 }
1000
1001 return parser;
1002}
1003
1004static void
Haibo Huang40a71912019-10-11 11:13:39 -07001005parserInit(XML_Parser parser, const XML_Char *encodingName) {
Elliott Hughes72472942018-01-10 08:36:10 -08001006 parser->m_processor = prologInitProcessor;
1007 XmlPrologStateInit(&parser->m_prologState);
1008 if (encodingName != NULL) {
1009 parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem));
1010 }
1011 parser->m_curBase = NULL;
1012 XmlInitEncoding(&parser->m_initEncoding, &parser->m_encoding, 0);
1013 parser->m_userData = NULL;
1014 parser->m_handlerArg = NULL;
1015 parser->m_startElementHandler = NULL;
1016 parser->m_endElementHandler = NULL;
1017 parser->m_characterDataHandler = NULL;
1018 parser->m_processingInstructionHandler = NULL;
1019 parser->m_commentHandler = NULL;
1020 parser->m_startCdataSectionHandler = NULL;
1021 parser->m_endCdataSectionHandler = NULL;
1022 parser->m_defaultHandler = NULL;
1023 parser->m_startDoctypeDeclHandler = NULL;
1024 parser->m_endDoctypeDeclHandler = NULL;
1025 parser->m_unparsedEntityDeclHandler = NULL;
1026 parser->m_notationDeclHandler = NULL;
1027 parser->m_startNamespaceDeclHandler = NULL;
1028 parser->m_endNamespaceDeclHandler = NULL;
1029 parser->m_notStandaloneHandler = NULL;
1030 parser->m_externalEntityRefHandler = NULL;
1031 parser->m_externalEntityRefHandlerArg = parser;
1032 parser->m_skippedEntityHandler = NULL;
1033 parser->m_elementDeclHandler = NULL;
1034 parser->m_attlistDeclHandler = NULL;
1035 parser->m_entityDeclHandler = NULL;
1036 parser->m_xmlDeclHandler = NULL;
1037 parser->m_bufferPtr = parser->m_buffer;
1038 parser->m_bufferEnd = parser->m_buffer;
1039 parser->m_parseEndByteIndex = 0;
1040 parser->m_parseEndPtr = NULL;
1041 parser->m_declElementType = NULL;
1042 parser->m_declAttributeId = NULL;
1043 parser->m_declEntity = NULL;
1044 parser->m_doctypeName = NULL;
1045 parser->m_doctypeSysid = NULL;
1046 parser->m_doctypePubid = NULL;
1047 parser->m_declAttributeType = NULL;
1048 parser->m_declNotationName = NULL;
1049 parser->m_declNotationPublicId = NULL;
1050 parser->m_declAttributeIsCdata = XML_FALSE;
1051 parser->m_declAttributeIsId = XML_FALSE;
1052 memset(&parser->m_position, 0, sizeof(POSITION));
1053 parser->m_errorCode = XML_ERROR_NONE;
1054 parser->m_eventPtr = NULL;
1055 parser->m_eventEndPtr = NULL;
1056 parser->m_positionPtr = NULL;
1057 parser->m_openInternalEntities = NULL;
1058 parser->m_defaultExpandInternalEntities = XML_TRUE;
1059 parser->m_tagLevel = 0;
1060 parser->m_tagStack = NULL;
1061 parser->m_inheritedBindings = NULL;
1062 parser->m_nSpecifiedAtts = 0;
1063 parser->m_unknownEncodingMem = NULL;
1064 parser->m_unknownEncodingRelease = NULL;
1065 parser->m_unknownEncodingData = NULL;
1066 parser->m_parentParser = NULL;
1067 parser->m_parsingStatus.parsing = XML_INITIALIZED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001068#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08001069 parser->m_isParamEntity = XML_FALSE;
1070 parser->m_useForeignDTD = XML_FALSE;
1071 parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001072#endif
Elliott Hughes72472942018-01-10 08:36:10 -08001073 parser->m_hash_secret_salt = 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001074}
1075
Elliott Hughes72472942018-01-10 08:36:10 -08001076/* moves list of bindings to m_freeBindingList */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001077static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001078moveToFreeBindingList(XML_Parser parser, BINDING *bindings) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001079 while (bindings) {
1080 BINDING *b = bindings;
1081 bindings = bindings->nextTagBinding;
Elliott Hughes72472942018-01-10 08:36:10 -08001082 b->nextTagBinding = parser->m_freeBindingList;
1083 parser->m_freeBindingList = b;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001084 }
1085}
1086
1087XML_Bool XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001088XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001089 TAG *tStk;
1090 OPEN_INTERNAL_ENTITY *openEntityList;
Elliott Hughes72472942018-01-10 08:36:10 -08001091
1092 if (parser == NULL)
Haibo Huang40a71912019-10-11 11:13:39 -07001093 return XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08001094
1095 if (parser->m_parentParser)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001096 return XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08001097 /* move m_tagStack to m_freeTagList */
1098 tStk = parser->m_tagStack;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001099 while (tStk) {
1100 TAG *tag = tStk;
1101 tStk = tStk->parent;
Elliott Hughes72472942018-01-10 08:36:10 -08001102 tag->parent = parser->m_freeTagList;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001103 moveToFreeBindingList(parser, tag->bindings);
1104 tag->bindings = NULL;
Elliott Hughes72472942018-01-10 08:36:10 -08001105 parser->m_freeTagList = tag;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001106 }
Elliott Hughes72472942018-01-10 08:36:10 -08001107 /* move m_openInternalEntities to m_freeInternalEntities */
1108 openEntityList = parser->m_openInternalEntities;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001109 while (openEntityList) {
1110 OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
1111 openEntityList = openEntity->next;
Elliott Hughes72472942018-01-10 08:36:10 -08001112 openEntity->next = parser->m_freeInternalEntities;
1113 parser->m_freeInternalEntities = openEntity;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001114 }
Elliott Hughes72472942018-01-10 08:36:10 -08001115 moveToFreeBindingList(parser, parser->m_inheritedBindings);
1116 FREE(parser, parser->m_unknownEncodingMem);
1117 if (parser->m_unknownEncodingRelease)
1118 parser->m_unknownEncodingRelease(parser->m_unknownEncodingData);
1119 poolClear(&parser->m_tempPool);
1120 poolClear(&parser->m_temp2Pool);
1121 FREE(parser, (void *)parser->m_protocolEncodingName);
1122 parser->m_protocolEncodingName = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001123 parserInit(parser, encodingName);
Elliott Hughes72472942018-01-10 08:36:10 -08001124 dtdReset(parser->m_dtd, &parser->m_mem);
Elliott Hughes35e432d2012-09-09 14:23:38 -07001125 return XML_TRUE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001126}
1127
1128enum XML_Status XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001129XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) {
Elliott Hughes72472942018-01-10 08:36:10 -08001130 if (parser == NULL)
Haibo Huang40a71912019-10-11 11:13:39 -07001131 return XML_STATUS_ERROR;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001132 /* Block after XML_Parse()/XML_ParseBuffer() has been called.
1133 XXX There's no way for the caller to determine which of the
1134 XXX possible error cases caused the XML_STATUS_ERROR return.
1135 */
Haibo Huang40a71912019-10-11 11:13:39 -07001136 if (parser->m_parsingStatus.parsing == XML_PARSING
1137 || parser->m_parsingStatus.parsing == XML_SUSPENDED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001138 return XML_STATUS_ERROR;
Elliott Hughes72472942018-01-10 08:36:10 -08001139
1140 /* Get rid of any previous encoding name */
1141 FREE(parser, (void *)parser->m_protocolEncodingName);
1142
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001143 if (encodingName == NULL)
Elliott Hughes72472942018-01-10 08:36:10 -08001144 /* No new encoding name */
1145 parser->m_protocolEncodingName = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001146 else {
Elliott Hughes72472942018-01-10 08:36:10 -08001147 /* Copy the new encoding name into allocated memory */
1148 parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem));
Haibo Huang40a71912019-10-11 11:13:39 -07001149 if (! parser->m_protocolEncodingName)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001150 return XML_STATUS_ERROR;
1151 }
1152 return XML_STATUS_OK;
1153}
1154
1155XML_Parser XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001156XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context,
1157 const XML_Char *encodingName) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001158 XML_Parser parser = oldParser;
1159 DTD *newDtd = NULL;
Elliott Hughes72472942018-01-10 08:36:10 -08001160 DTD *oldDtd;
1161 XML_StartElementHandler oldStartElementHandler;
1162 XML_EndElementHandler oldEndElementHandler;
1163 XML_CharacterDataHandler oldCharacterDataHandler;
1164 XML_ProcessingInstructionHandler oldProcessingInstructionHandler;
1165 XML_CommentHandler oldCommentHandler;
1166 XML_StartCdataSectionHandler oldStartCdataSectionHandler;
1167 XML_EndCdataSectionHandler oldEndCdataSectionHandler;
1168 XML_DefaultHandler oldDefaultHandler;
1169 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler;
1170 XML_NotationDeclHandler oldNotationDeclHandler;
1171 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler;
1172 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler;
1173 XML_NotStandaloneHandler oldNotStandaloneHandler;
1174 XML_ExternalEntityRefHandler oldExternalEntityRefHandler;
1175 XML_SkippedEntityHandler oldSkippedEntityHandler;
1176 XML_UnknownEncodingHandler oldUnknownEncodingHandler;
1177 XML_ElementDeclHandler oldElementDeclHandler;
1178 XML_AttlistDeclHandler oldAttlistDeclHandler;
1179 XML_EntityDeclHandler oldEntityDeclHandler;
1180 XML_XmlDeclHandler oldXmlDeclHandler;
Haibo Huang40a71912019-10-11 11:13:39 -07001181 ELEMENT_TYPE *oldDeclElementType;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001182
Elliott Hughes72472942018-01-10 08:36:10 -08001183 void *oldUserData;
1184 void *oldHandlerArg;
1185 XML_Bool oldDefaultExpandInternalEntities;
1186 XML_Parser oldExternalEntityRefHandlerArg;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001187#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08001188 enum XML_ParamEntityParsing oldParamEntityParsing;
1189 int oldInEntityValue;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001190#endif
Elliott Hughes72472942018-01-10 08:36:10 -08001191 XML_Bool oldns_triplets;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001192 /* Note that the new parser shares the same hash secret as the old
1193 parser, so that dtdCopy and copyEntityTable can lookup values
1194 from hash tables associated with either parser without us having
1195 to worry which hash secrets each table has.
1196 */
Elliott Hughes72472942018-01-10 08:36:10 -08001197 unsigned long oldhash_secret_salt;
1198
1199 /* Validate the oldParser parameter before we pull everything out of it */
1200 if (oldParser == NULL)
1201 return NULL;
1202
1203 /* Stash the original parser contents on the stack */
1204 oldDtd = parser->m_dtd;
1205 oldStartElementHandler = parser->m_startElementHandler;
1206 oldEndElementHandler = parser->m_endElementHandler;
1207 oldCharacterDataHandler = parser->m_characterDataHandler;
1208 oldProcessingInstructionHandler = parser->m_processingInstructionHandler;
1209 oldCommentHandler = parser->m_commentHandler;
1210 oldStartCdataSectionHandler = parser->m_startCdataSectionHandler;
1211 oldEndCdataSectionHandler = parser->m_endCdataSectionHandler;
1212 oldDefaultHandler = parser->m_defaultHandler;
1213 oldUnparsedEntityDeclHandler = parser->m_unparsedEntityDeclHandler;
1214 oldNotationDeclHandler = parser->m_notationDeclHandler;
1215 oldStartNamespaceDeclHandler = parser->m_startNamespaceDeclHandler;
1216 oldEndNamespaceDeclHandler = parser->m_endNamespaceDeclHandler;
1217 oldNotStandaloneHandler = parser->m_notStandaloneHandler;
1218 oldExternalEntityRefHandler = parser->m_externalEntityRefHandler;
1219 oldSkippedEntityHandler = parser->m_skippedEntityHandler;
1220 oldUnknownEncodingHandler = parser->m_unknownEncodingHandler;
1221 oldElementDeclHandler = parser->m_elementDeclHandler;
1222 oldAttlistDeclHandler = parser->m_attlistDeclHandler;
1223 oldEntityDeclHandler = parser->m_entityDeclHandler;
1224 oldXmlDeclHandler = parser->m_xmlDeclHandler;
1225 oldDeclElementType = parser->m_declElementType;
1226
1227 oldUserData = parser->m_userData;
1228 oldHandlerArg = parser->m_handlerArg;
1229 oldDefaultExpandInternalEntities = parser->m_defaultExpandInternalEntities;
1230 oldExternalEntityRefHandlerArg = parser->m_externalEntityRefHandlerArg;
1231#ifdef XML_DTD
1232 oldParamEntityParsing = parser->m_paramEntityParsing;
1233 oldInEntityValue = parser->m_prologState.inEntityValue;
1234#endif
1235 oldns_triplets = parser->m_ns_triplets;
1236 /* Note that the new parser shares the same hash secret as the old
1237 parser, so that dtdCopy and copyEntityTable can lookup values
1238 from hash tables associated with either parser without us having
1239 to worry which hash secrets each table has.
1240 */
1241 oldhash_secret_salt = parser->m_hash_secret_salt;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001242
1243#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07001244 if (! context)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001245 newDtd = oldDtd;
1246#endif /* XML_DTD */
1247
1248 /* Note that the magical uses of the pre-processor to make field
1249 access look more like C++ require that `parser' be overwritten
1250 here. This makes this function more painful to follow than it
1251 would be otherwise.
1252 */
Elliott Hughes72472942018-01-10 08:36:10 -08001253 if (parser->m_ns) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001254 XML_Char tmp[2];
Elliott Hughes72472942018-01-10 08:36:10 -08001255 *tmp = parser->m_namespaceSeparator;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001256 parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
Haibo Huang40a71912019-10-11 11:13:39 -07001257 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001258 parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
1259 }
1260
Haibo Huang40a71912019-10-11 11:13:39 -07001261 if (! parser)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001262 return NULL;
1263
Elliott Hughes72472942018-01-10 08:36:10 -08001264 parser->m_startElementHandler = oldStartElementHandler;
1265 parser->m_endElementHandler = oldEndElementHandler;
1266 parser->m_characterDataHandler = oldCharacterDataHandler;
1267 parser->m_processingInstructionHandler = oldProcessingInstructionHandler;
1268 parser->m_commentHandler = oldCommentHandler;
1269 parser->m_startCdataSectionHandler = oldStartCdataSectionHandler;
1270 parser->m_endCdataSectionHandler = oldEndCdataSectionHandler;
1271 parser->m_defaultHandler = oldDefaultHandler;
1272 parser->m_unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
1273 parser->m_notationDeclHandler = oldNotationDeclHandler;
1274 parser->m_startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
1275 parser->m_endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
1276 parser->m_notStandaloneHandler = oldNotStandaloneHandler;
1277 parser->m_externalEntityRefHandler = oldExternalEntityRefHandler;
1278 parser->m_skippedEntityHandler = oldSkippedEntityHandler;
1279 parser->m_unknownEncodingHandler = oldUnknownEncodingHandler;
1280 parser->m_elementDeclHandler = oldElementDeclHandler;
1281 parser->m_attlistDeclHandler = oldAttlistDeclHandler;
1282 parser->m_entityDeclHandler = oldEntityDeclHandler;
1283 parser->m_xmlDeclHandler = oldXmlDeclHandler;
1284 parser->m_declElementType = oldDeclElementType;
1285 parser->m_userData = oldUserData;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001286 if (oldUserData == oldHandlerArg)
Elliott Hughes72472942018-01-10 08:36:10 -08001287 parser->m_handlerArg = parser->m_userData;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001288 else
Elliott Hughes72472942018-01-10 08:36:10 -08001289 parser->m_handlerArg = parser;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001290 if (oldExternalEntityRefHandlerArg != oldParser)
Elliott Hughes72472942018-01-10 08:36:10 -08001291 parser->m_externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
1292 parser->m_defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
1293 parser->m_ns_triplets = oldns_triplets;
1294 parser->m_hash_secret_salt = oldhash_secret_salt;
1295 parser->m_parentParser = oldParser;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001296#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08001297 parser->m_paramEntityParsing = oldParamEntityParsing;
1298 parser->m_prologState.inEntityValue = oldInEntityValue;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001299 if (context) {
1300#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07001301 if (! dtdCopy(oldParser, parser->m_dtd, oldDtd, &parser->m_mem)
1302 || ! setContext(parser, context)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001303 XML_ParserFree(parser);
1304 return NULL;
1305 }
Elliott Hughes72472942018-01-10 08:36:10 -08001306 parser->m_processor = externalEntityInitProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001307#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07001308 } else {
1309 /* The DTD instance referenced by parser->m_dtd is shared between the
1310 document's root parser and external PE parsers, therefore one does not
1311 need to call setContext. In addition, one also *must* not call
1312 setContext, because this would overwrite existing prefix->binding
1313 pointers in parser->m_dtd with ones that get destroyed with the external
1314 PE parser. This would leave those prefixes with dangling pointers.
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001315 */
Elliott Hughes72472942018-01-10 08:36:10 -08001316 parser->m_isParamEntity = XML_TRUE;
1317 XmlPrologStateInitExternalEntity(&parser->m_prologState);
1318 parser->m_processor = externalParEntInitProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001319 }
1320#endif /* XML_DTD */
1321 return parser;
1322}
1323
1324static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001325destroyBindings(BINDING *bindings, XML_Parser parser) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001326 for (;;) {
1327 BINDING *b = bindings;
Haibo Huang40a71912019-10-11 11:13:39 -07001328 if (! b)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001329 break;
1330 bindings = b->nextTagBinding;
Elliott Hughes72472942018-01-10 08:36:10 -08001331 FREE(parser, b->uri);
1332 FREE(parser, b);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001333 }
1334}
1335
1336void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001337XML_ParserFree(XML_Parser parser) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001338 TAG *tagList;
1339 OPEN_INTERNAL_ENTITY *entityList;
1340 if (parser == NULL)
1341 return;
Elliott Hughes72472942018-01-10 08:36:10 -08001342 /* free m_tagStack and m_freeTagList */
1343 tagList = parser->m_tagStack;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001344 for (;;) {
1345 TAG *p;
1346 if (tagList == NULL) {
Elliott Hughes72472942018-01-10 08:36:10 -08001347 if (parser->m_freeTagList == NULL)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001348 break;
Elliott Hughes72472942018-01-10 08:36:10 -08001349 tagList = parser->m_freeTagList;
1350 parser->m_freeTagList = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001351 }
1352 p = tagList;
1353 tagList = tagList->parent;
Elliott Hughes72472942018-01-10 08:36:10 -08001354 FREE(parser, p->buf);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001355 destroyBindings(p->bindings, parser);
Elliott Hughes72472942018-01-10 08:36:10 -08001356 FREE(parser, p);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001357 }
Elliott Hughes72472942018-01-10 08:36:10 -08001358 /* free m_openInternalEntities and m_freeInternalEntities */
1359 entityList = parser->m_openInternalEntities;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001360 for (;;) {
1361 OPEN_INTERNAL_ENTITY *openEntity;
1362 if (entityList == NULL) {
Elliott Hughes72472942018-01-10 08:36:10 -08001363 if (parser->m_freeInternalEntities == NULL)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001364 break;
Elliott Hughes72472942018-01-10 08:36:10 -08001365 entityList = parser->m_freeInternalEntities;
1366 parser->m_freeInternalEntities = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001367 }
1368 openEntity = entityList;
1369 entityList = entityList->next;
Elliott Hughes72472942018-01-10 08:36:10 -08001370 FREE(parser, openEntity);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001371 }
1372
Elliott Hughes72472942018-01-10 08:36:10 -08001373 destroyBindings(parser->m_freeBindingList, parser);
1374 destroyBindings(parser->m_inheritedBindings, parser);
1375 poolDestroy(&parser->m_tempPool);
1376 poolDestroy(&parser->m_temp2Pool);
1377 FREE(parser, (void *)parser->m_protocolEncodingName);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001378#ifdef XML_DTD
1379 /* external parameter entity parsers share the DTD structure
1380 parser->m_dtd with the root parser, so we must not destroy it
1381 */
Haibo Huang40a71912019-10-11 11:13:39 -07001382 if (! parser->m_isParamEntity && parser->m_dtd)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001383#else
Elliott Hughes72472942018-01-10 08:36:10 -08001384 if (parser->m_dtd)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001385#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07001386 dtdDestroy(parser->m_dtd, (XML_Bool)! parser->m_parentParser,
1387 &parser->m_mem);
Elliott Hughes72472942018-01-10 08:36:10 -08001388 FREE(parser, (void *)parser->m_atts);
Elliott Hughes35e432d2012-09-09 14:23:38 -07001389#ifdef XML_ATTR_INFO
Elliott Hughes72472942018-01-10 08:36:10 -08001390 FREE(parser, (void *)parser->m_attInfo);
Elliott Hughes35e432d2012-09-09 14:23:38 -07001391#endif
Elliott Hughes72472942018-01-10 08:36:10 -08001392 FREE(parser, parser->m_groupConnector);
1393 FREE(parser, parser->m_buffer);
1394 FREE(parser, parser->m_dataBuf);
1395 FREE(parser, parser->m_nsAtts);
1396 FREE(parser, parser->m_unknownEncodingMem);
1397 if (parser->m_unknownEncodingRelease)
1398 parser->m_unknownEncodingRelease(parser->m_unknownEncodingData);
1399 FREE(parser, parser);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001400}
1401
1402void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001403XML_UseParserAsHandlerArg(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08001404 if (parser != NULL)
1405 parser->m_handlerArg = parser;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001406}
1407
1408enum XML_Error XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001409XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) {
Elliott Hughes72472942018-01-10 08:36:10 -08001410 if (parser == NULL)
1411 return XML_ERROR_INVALID_ARGUMENT;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001412#ifdef XML_DTD
1413 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Haibo Huang40a71912019-10-11 11:13:39 -07001414 if (parser->m_parsingStatus.parsing == XML_PARSING
1415 || parser->m_parsingStatus.parsing == XML_SUSPENDED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001416 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
Elliott Hughes72472942018-01-10 08:36:10 -08001417 parser->m_useForeignDTD = useDTD;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001418 return XML_ERROR_NONE;
1419#else
Haibo Huangd1a324a2020-10-28 22:19:36 -07001420 UNUSED_P(useDTD);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001421 return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
1422#endif
1423}
1424
1425void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001426XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) {
Elliott Hughes72472942018-01-10 08:36:10 -08001427 if (parser == NULL)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001428 return;
Elliott Hughes72472942018-01-10 08:36:10 -08001429 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Haibo Huang40a71912019-10-11 11:13:39 -07001430 if (parser->m_parsingStatus.parsing == XML_PARSING
1431 || parser->m_parsingStatus.parsing == XML_SUSPENDED)
Elliott Hughes72472942018-01-10 08:36:10 -08001432 return;
1433 parser->m_ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001434}
1435
1436void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001437XML_SetUserData(XML_Parser parser, void *p) {
Elliott Hughes72472942018-01-10 08:36:10 -08001438 if (parser == NULL)
1439 return;
1440 if (parser->m_handlerArg == parser->m_userData)
1441 parser->m_handlerArg = parser->m_userData = p;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001442 else
Elliott Hughes72472942018-01-10 08:36:10 -08001443 parser->m_userData = p;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001444}
1445
1446enum XML_Status XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001447XML_SetBase(XML_Parser parser, const XML_Char *p) {
Elliott Hughes72472942018-01-10 08:36:10 -08001448 if (parser == NULL)
1449 return XML_STATUS_ERROR;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001450 if (p) {
Elliott Hughes72472942018-01-10 08:36:10 -08001451 p = poolCopyString(&parser->m_dtd->pool, p);
Haibo Huang40a71912019-10-11 11:13:39 -07001452 if (! p)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001453 return XML_STATUS_ERROR;
Elliott Hughes72472942018-01-10 08:36:10 -08001454 parser->m_curBase = p;
Haibo Huang40a71912019-10-11 11:13:39 -07001455 } else
Elliott Hughes72472942018-01-10 08:36:10 -08001456 parser->m_curBase = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001457 return XML_STATUS_OK;
1458}
1459
Haibo Huang40a71912019-10-11 11:13:39 -07001460const XML_Char *XMLCALL
1461XML_GetBase(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08001462 if (parser == NULL)
1463 return NULL;
1464 return parser->m_curBase;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001465}
1466
1467int XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001468XML_GetSpecifiedAttributeCount(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08001469 if (parser == NULL)
1470 return -1;
1471 return parser->m_nSpecifiedAtts;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001472}
1473
1474int XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001475XML_GetIdAttributeIndex(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08001476 if (parser == NULL)
1477 return -1;
1478 return parser->m_idAttIndex;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001479}
1480
Elliott Hughes35e432d2012-09-09 14:23:38 -07001481#ifdef XML_ATTR_INFO
Haibo Huang40a71912019-10-11 11:13:39 -07001482const XML_AttrInfo *XMLCALL
1483XML_GetAttributeInfo(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08001484 if (parser == NULL)
1485 return NULL;
1486 return parser->m_attInfo;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001487}
1488#endif
1489
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001490void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001491XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start,
1492 XML_EndElementHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001493 if (parser == NULL)
1494 return;
1495 parser->m_startElementHandler = start;
1496 parser->m_endElementHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001497}
1498
1499void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001500XML_SetStartElementHandler(XML_Parser parser, XML_StartElementHandler start) {
Elliott Hughes72472942018-01-10 08:36:10 -08001501 if (parser != NULL)
1502 parser->m_startElementHandler = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001503}
1504
1505void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001506XML_SetEndElementHandler(XML_Parser parser, XML_EndElementHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001507 if (parser != NULL)
1508 parser->m_endElementHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001509}
1510
1511void XMLCALL
1512XML_SetCharacterDataHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001513 XML_CharacterDataHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001514 if (parser != NULL)
1515 parser->m_characterDataHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001516}
1517
1518void XMLCALL
1519XML_SetProcessingInstructionHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001520 XML_ProcessingInstructionHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001521 if (parser != NULL)
1522 parser->m_processingInstructionHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001523}
1524
1525void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001526XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001527 if (parser != NULL)
1528 parser->m_commentHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001529}
1530
1531void XMLCALL
1532XML_SetCdataSectionHandler(XML_Parser parser,
1533 XML_StartCdataSectionHandler start,
Haibo Huang40a71912019-10-11 11:13:39 -07001534 XML_EndCdataSectionHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001535 if (parser == NULL)
1536 return;
1537 parser->m_startCdataSectionHandler = start;
1538 parser->m_endCdataSectionHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001539}
1540
1541void XMLCALL
1542XML_SetStartCdataSectionHandler(XML_Parser parser,
1543 XML_StartCdataSectionHandler start) {
Elliott Hughes72472942018-01-10 08:36:10 -08001544 if (parser != NULL)
1545 parser->m_startCdataSectionHandler = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001546}
1547
1548void XMLCALL
1549XML_SetEndCdataSectionHandler(XML_Parser parser,
1550 XML_EndCdataSectionHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001551 if (parser != NULL)
1552 parser->m_endCdataSectionHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001553}
1554
1555void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001556XML_SetDefaultHandler(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_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001561}
1562
1563void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001564XML_SetDefaultHandlerExpand(XML_Parser parser, XML_DefaultHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001565 if (parser == NULL)
1566 return;
1567 parser->m_defaultHandler = handler;
1568 parser->m_defaultExpandInternalEntities = XML_TRUE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001569}
1570
1571void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001572XML_SetDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start,
1573 XML_EndDoctypeDeclHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001574 if (parser == NULL)
1575 return;
1576 parser->m_startDoctypeDeclHandler = start;
1577 parser->m_endDoctypeDeclHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001578}
1579
1580void XMLCALL
1581XML_SetStartDoctypeDeclHandler(XML_Parser parser,
1582 XML_StartDoctypeDeclHandler start) {
Elliott Hughes72472942018-01-10 08:36:10 -08001583 if (parser != NULL)
1584 parser->m_startDoctypeDeclHandler = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001585}
1586
1587void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001588XML_SetEndDoctypeDeclHandler(XML_Parser parser, XML_EndDoctypeDeclHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001589 if (parser != NULL)
1590 parser->m_endDoctypeDeclHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001591}
1592
1593void XMLCALL
1594XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001595 XML_UnparsedEntityDeclHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001596 if (parser != NULL)
1597 parser->m_unparsedEntityDeclHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001598}
1599
1600void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001601XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001602 if (parser != NULL)
1603 parser->m_notationDeclHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001604}
1605
1606void XMLCALL
1607XML_SetNamespaceDeclHandler(XML_Parser parser,
1608 XML_StartNamespaceDeclHandler start,
Haibo Huang40a71912019-10-11 11:13:39 -07001609 XML_EndNamespaceDeclHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001610 if (parser == NULL)
1611 return;
1612 parser->m_startNamespaceDeclHandler = start;
1613 parser->m_endNamespaceDeclHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001614}
1615
1616void XMLCALL
1617XML_SetStartNamespaceDeclHandler(XML_Parser parser,
1618 XML_StartNamespaceDeclHandler start) {
Elliott Hughes72472942018-01-10 08:36:10 -08001619 if (parser != NULL)
1620 parser->m_startNamespaceDeclHandler = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001621}
1622
1623void XMLCALL
1624XML_SetEndNamespaceDeclHandler(XML_Parser parser,
1625 XML_EndNamespaceDeclHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001626 if (parser != NULL)
1627 parser->m_endNamespaceDeclHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001628}
1629
1630void XMLCALL
1631XML_SetNotStandaloneHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001632 XML_NotStandaloneHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001633 if (parser != NULL)
1634 parser->m_notStandaloneHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001635}
1636
1637void XMLCALL
1638XML_SetExternalEntityRefHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001639 XML_ExternalEntityRefHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001640 if (parser != NULL)
1641 parser->m_externalEntityRefHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001642}
1643
1644void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001645XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) {
Elliott Hughes72472942018-01-10 08:36:10 -08001646 if (parser == NULL)
1647 return;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001648 if (arg)
Elliott Hughes72472942018-01-10 08:36:10 -08001649 parser->m_externalEntityRefHandlerArg = (XML_Parser)arg;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001650 else
Elliott Hughes72472942018-01-10 08:36:10 -08001651 parser->m_externalEntityRefHandlerArg = parser;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001652}
1653
1654void XMLCALL
1655XML_SetSkippedEntityHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001656 XML_SkippedEntityHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001657 if (parser != NULL)
1658 parser->m_skippedEntityHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001659}
1660
1661void XMLCALL
1662XML_SetUnknownEncodingHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001663 XML_UnknownEncodingHandler handler, void *data) {
Elliott Hughes72472942018-01-10 08:36:10 -08001664 if (parser == NULL)
1665 return;
1666 parser->m_unknownEncodingHandler = handler;
1667 parser->m_unknownEncodingHandlerData = data;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001668}
1669
1670void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001671XML_SetElementDeclHandler(XML_Parser parser, XML_ElementDeclHandler eldecl) {
Elliott Hughes72472942018-01-10 08:36:10 -08001672 if (parser != NULL)
1673 parser->m_elementDeclHandler = eldecl;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001674}
1675
1676void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001677XML_SetAttlistDeclHandler(XML_Parser parser, XML_AttlistDeclHandler attdecl) {
Elliott Hughes72472942018-01-10 08:36:10 -08001678 if (parser != NULL)
1679 parser->m_attlistDeclHandler = attdecl;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001680}
1681
1682void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001683XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001684 if (parser != NULL)
1685 parser->m_entityDeclHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001686}
1687
1688void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001689XML_SetXmlDeclHandler(XML_Parser parser, XML_XmlDeclHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001690 if (parser != NULL)
1691 parser->m_xmlDeclHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001692}
1693
1694int XMLCALL
1695XML_SetParamEntityParsing(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001696 enum XML_ParamEntityParsing peParsing) {
Elliott Hughes72472942018-01-10 08:36:10 -08001697 if (parser == NULL)
1698 return 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001699 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Haibo Huang40a71912019-10-11 11:13:39 -07001700 if (parser->m_parsingStatus.parsing == XML_PARSING
1701 || parser->m_parsingStatus.parsing == XML_SUSPENDED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001702 return 0;
1703#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08001704 parser->m_paramEntityParsing = peParsing;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001705 return 1;
1706#else
1707 return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
1708#endif
1709}
1710
Elliott Hughes35e432d2012-09-09 14:23:38 -07001711int XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001712XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt) {
Elliott Hughes72472942018-01-10 08:36:10 -08001713 if (parser == NULL)
Elliott Hughes35e432d2012-09-09 14:23:38 -07001714 return 0;
Elliott Hughes72472942018-01-10 08:36:10 -08001715 if (parser->m_parentParser)
1716 return XML_SetHashSalt(parser->m_parentParser, hash_salt);
1717 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Haibo Huang40a71912019-10-11 11:13:39 -07001718 if (parser->m_parsingStatus.parsing == XML_PARSING
1719 || parser->m_parsingStatus.parsing == XML_SUSPENDED)
Elliott Hughes72472942018-01-10 08:36:10 -08001720 return 0;
1721 parser->m_hash_secret_salt = hash_salt;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001722 return 1;
1723}
1724
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001725enum XML_Status XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001726XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) {
Elliott Hughes72472942018-01-10 08:36:10 -08001727 if ((parser == NULL) || (len < 0) || ((s == NULL) && (len != 0))) {
1728 if (parser != NULL)
1729 parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT;
1730 return XML_STATUS_ERROR;
1731 }
1732 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001733 case XML_SUSPENDED:
Elliott Hughes72472942018-01-10 08:36:10 -08001734 parser->m_errorCode = XML_ERROR_SUSPENDED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001735 return XML_STATUS_ERROR;
1736 case XML_FINISHED:
Elliott Hughes72472942018-01-10 08:36:10 -08001737 parser->m_errorCode = XML_ERROR_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001738 return XML_STATUS_ERROR;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001739 case XML_INITIALIZED:
Haibo Huang40a71912019-10-11 11:13:39 -07001740 if (parser->m_parentParser == NULL && ! startParsing(parser)) {
Elliott Hughes72472942018-01-10 08:36:10 -08001741 parser->m_errorCode = XML_ERROR_NO_MEMORY;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001742 return XML_STATUS_ERROR;
1743 }
Elliott Hughesaaec48e2018-08-16 16:29:01 -07001744 /* fall through */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001745 default:
Elliott Hughes72472942018-01-10 08:36:10 -08001746 parser->m_parsingStatus.parsing = XML_PARSING;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001747 }
1748
1749 if (len == 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08001750 parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
Haibo Huang40a71912019-10-11 11:13:39 -07001751 if (! isFinal)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001752 return XML_STATUS_OK;
Elliott Hughes72472942018-01-10 08:36:10 -08001753 parser->m_positionPtr = parser->m_bufferPtr;
1754 parser->m_parseEndPtr = parser->m_bufferEnd;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001755
1756 /* If data are left over from last buffer, and we now know that these
1757 data are the final chunk of input, then we have to check them again
1758 to detect errors based on that fact.
1759 */
Haibo Huang40a71912019-10-11 11:13:39 -07001760 parser->m_errorCode
1761 = parser->m_processor(parser, parser->m_bufferPtr,
1762 parser->m_parseEndPtr, &parser->m_bufferPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001763
Elliott Hughes72472942018-01-10 08:36:10 -08001764 if (parser->m_errorCode == XML_ERROR_NONE) {
1765 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001766 case XML_SUSPENDED:
Elliott Hughes72472942018-01-10 08:36:10 -08001767 /* It is hard to be certain, but it seems that this case
1768 * cannot occur. This code is cleaning up a previous parse
1769 * with no new data (since len == 0). Changing the parsing
1770 * state requires getting to execute a handler function, and
1771 * there doesn't seem to be an opportunity for that while in
1772 * this circumstance.
1773 *
1774 * Given the uncertainty, we retain the code but exclude it
1775 * from coverage tests.
1776 *
1777 * LCOV_EXCL_START
1778 */
Haibo Huang40a71912019-10-11 11:13:39 -07001779 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
1780 parser->m_bufferPtr, &parser->m_position);
Elliott Hughes72472942018-01-10 08:36:10 -08001781 parser->m_positionPtr = parser->m_bufferPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001782 return XML_STATUS_SUSPENDED;
Elliott Hughes72472942018-01-10 08:36:10 -08001783 /* LCOV_EXCL_STOP */
Elliott Hughes35e432d2012-09-09 14:23:38 -07001784 case XML_INITIALIZED:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001785 case XML_PARSING:
Elliott Hughes72472942018-01-10 08:36:10 -08001786 parser->m_parsingStatus.parsing = XML_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001787 /* fall through */
1788 default:
1789 return XML_STATUS_OK;
1790 }
1791 }
Elliott Hughes72472942018-01-10 08:36:10 -08001792 parser->m_eventEndPtr = parser->m_eventPtr;
1793 parser->m_processor = errorProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001794 return XML_STATUS_ERROR;
1795 }
1796#ifndef XML_CONTEXT_BYTES
Elliott Hughes72472942018-01-10 08:36:10 -08001797 else if (parser->m_bufferPtr == parser->m_bufferEnd) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001798 const char *end;
1799 int nLeftOver;
Paul Duffinc05e0322016-05-04 10:42:31 +01001800 enum XML_Status result;
Elliott Hughes72472942018-01-10 08:36:10 -08001801 /* Detect overflow (a+b > MAX <==> b > MAX-a) */
Haibo Huangd1a324a2020-10-28 22:19:36 -07001802 if ((XML_Size)len > ((XML_Size)-1) / 2 - parser->m_parseEndByteIndex) {
Haibo Huang40a71912019-10-11 11:13:39 -07001803 parser->m_errorCode = XML_ERROR_NO_MEMORY;
1804 parser->m_eventPtr = parser->m_eventEndPtr = NULL;
1805 parser->m_processor = errorProcessor;
1806 return XML_STATUS_ERROR;
Elliott Hughes72472942018-01-10 08:36:10 -08001807 }
1808 parser->m_parseEndByteIndex += len;
1809 parser->m_positionPtr = s;
1810 parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001811
Haibo Huang40a71912019-10-11 11:13:39 -07001812 parser->m_errorCode
1813 = parser->m_processor(parser, s, parser->m_parseEndPtr = s + len, &end);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001814
Elliott Hughes72472942018-01-10 08:36:10 -08001815 if (parser->m_errorCode != XML_ERROR_NONE) {
1816 parser->m_eventEndPtr = parser->m_eventPtr;
1817 parser->m_processor = errorProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001818 return XML_STATUS_ERROR;
Haibo Huang40a71912019-10-11 11:13:39 -07001819 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08001820 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001821 case XML_SUSPENDED:
1822 result = XML_STATUS_SUSPENDED;
1823 break;
1824 case XML_INITIALIZED:
1825 case XML_PARSING:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001826 if (isFinal) {
Elliott Hughes72472942018-01-10 08:36:10 -08001827 parser->m_parsingStatus.parsing = XML_FINISHED;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001828 return XML_STATUS_OK;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001829 }
Elliott Hughes35e432d2012-09-09 14:23:38 -07001830 /* fall through */
1831 default:
1832 result = XML_STATUS_OK;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001833 }
1834 }
1835
Haibo Huang40a71912019-10-11 11:13:39 -07001836 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, end,
1837 &parser->m_position);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001838 nLeftOver = s + len - end;
1839 if (nLeftOver) {
Haibo Huang40a71912019-10-11 11:13:39 -07001840 if (parser->m_buffer == NULL
1841 || nLeftOver > parser->m_bufferLim - parser->m_buffer) {
Elliott Hughes72472942018-01-10 08:36:10 -08001842 /* avoid _signed_ integer overflow */
1843 char *temp = NULL;
1844 const int bytesToAllocate = (int)((unsigned)len * 2U);
1845 if (bytesToAllocate > 0) {
1846 temp = (char *)REALLOC(parser, parser->m_buffer, bytesToAllocate);
1847 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001848 if (temp == NULL) {
Elliott Hughes72472942018-01-10 08:36:10 -08001849 parser->m_errorCode = XML_ERROR_NO_MEMORY;
1850 parser->m_eventPtr = parser->m_eventEndPtr = NULL;
1851 parser->m_processor = errorProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001852 return XML_STATUS_ERROR;
1853 }
Elliott Hughes72472942018-01-10 08:36:10 -08001854 parser->m_buffer = temp;
1855 parser->m_bufferLim = parser->m_buffer + bytesToAllocate;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001856 }
Elliott Hughes72472942018-01-10 08:36:10 -08001857 memcpy(parser->m_buffer, end, nLeftOver);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001858 }
Elliott Hughes72472942018-01-10 08:36:10 -08001859 parser->m_bufferPtr = parser->m_buffer;
1860 parser->m_bufferEnd = parser->m_buffer + nLeftOver;
1861 parser->m_positionPtr = parser->m_bufferPtr;
1862 parser->m_parseEndPtr = parser->m_bufferEnd;
1863 parser->m_eventPtr = parser->m_bufferPtr;
1864 parser->m_eventEndPtr = parser->m_bufferPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001865 return result;
1866 }
Haibo Huang40a71912019-10-11 11:13:39 -07001867#endif /* not defined XML_CONTEXT_BYTES */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001868 else {
1869 void *buff = XML_GetBuffer(parser, len);
1870 if (buff == NULL)
1871 return XML_STATUS_ERROR;
1872 else {
1873 memcpy(buff, s, len);
1874 return XML_ParseBuffer(parser, len, isFinal);
1875 }
1876 }
1877}
1878
1879enum XML_Status XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001880XML_ParseBuffer(XML_Parser parser, int len, int isFinal) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001881 const char *start;
1882 enum XML_Status result = XML_STATUS_OK;
1883
Elliott Hughes72472942018-01-10 08:36:10 -08001884 if (parser == NULL)
1885 return XML_STATUS_ERROR;
1886 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001887 case XML_SUSPENDED:
Elliott Hughes72472942018-01-10 08:36:10 -08001888 parser->m_errorCode = XML_ERROR_SUSPENDED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001889 return XML_STATUS_ERROR;
1890 case XML_FINISHED:
Elliott Hughes72472942018-01-10 08:36:10 -08001891 parser->m_errorCode = XML_ERROR_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001892 return XML_STATUS_ERROR;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001893 case XML_INITIALIZED:
Elliott Hughesf648a292021-04-01 15:10:13 -07001894 /* Has someone called XML_GetBuffer successfully before? */
1895 if (! parser->m_bufferPtr) {
1896 parser->m_errorCode = XML_ERROR_NO_BUFFER;
1897 return XML_STATUS_ERROR;
1898 }
1899
Haibo Huang40a71912019-10-11 11:13:39 -07001900 if (parser->m_parentParser == NULL && ! startParsing(parser)) {
Elliott Hughes72472942018-01-10 08:36:10 -08001901 parser->m_errorCode = XML_ERROR_NO_MEMORY;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001902 return XML_STATUS_ERROR;
1903 }
Elliott Hughesaaec48e2018-08-16 16:29:01 -07001904 /* fall through */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001905 default:
Elliott Hughes72472942018-01-10 08:36:10 -08001906 parser->m_parsingStatus.parsing = XML_PARSING;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001907 }
1908
Elliott Hughes72472942018-01-10 08:36:10 -08001909 start = parser->m_bufferPtr;
1910 parser->m_positionPtr = start;
1911 parser->m_bufferEnd += len;
1912 parser->m_parseEndPtr = parser->m_bufferEnd;
1913 parser->m_parseEndByteIndex += len;
1914 parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001915
Haibo Huang40a71912019-10-11 11:13:39 -07001916 parser->m_errorCode = parser->m_processor(
1917 parser, start, parser->m_parseEndPtr, &parser->m_bufferPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001918
Elliott Hughes72472942018-01-10 08:36:10 -08001919 if (parser->m_errorCode != XML_ERROR_NONE) {
1920 parser->m_eventEndPtr = parser->m_eventPtr;
1921 parser->m_processor = errorProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001922 return XML_STATUS_ERROR;
Haibo Huang40a71912019-10-11 11:13:39 -07001923 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08001924 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001925 case XML_SUSPENDED:
1926 result = XML_STATUS_SUSPENDED;
1927 break;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001928 case XML_INITIALIZED:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001929 case XML_PARSING:
1930 if (isFinal) {
Elliott Hughes72472942018-01-10 08:36:10 -08001931 parser->m_parsingStatus.parsing = XML_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001932 return result;
1933 }
Haibo Huang40a71912019-10-11 11:13:39 -07001934 default:; /* should not happen */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001935 }
1936 }
1937
Haibo Huang40a71912019-10-11 11:13:39 -07001938 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
1939 parser->m_bufferPtr, &parser->m_position);
Elliott Hughes72472942018-01-10 08:36:10 -08001940 parser->m_positionPtr = parser->m_bufferPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001941 return result;
1942}
1943
Haibo Huang40a71912019-10-11 11:13:39 -07001944void *XMLCALL
1945XML_GetBuffer(XML_Parser parser, int len) {
Elliott Hughes72472942018-01-10 08:36:10 -08001946 if (parser == NULL)
1947 return NULL;
Paul Duffinc05e0322016-05-04 10:42:31 +01001948 if (len < 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08001949 parser->m_errorCode = XML_ERROR_NO_MEMORY;
Paul Duffinc05e0322016-05-04 10:42:31 +01001950 return NULL;
1951 }
Elliott Hughes72472942018-01-10 08:36:10 -08001952 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001953 case XML_SUSPENDED:
Elliott Hughes72472942018-01-10 08:36:10 -08001954 parser->m_errorCode = XML_ERROR_SUSPENDED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001955 return NULL;
1956 case XML_FINISHED:
Elliott Hughes72472942018-01-10 08:36:10 -08001957 parser->m_errorCode = XML_ERROR_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001958 return NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07001959 default:;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001960 }
1961
Elliott Hughesaaec48e2018-08-16 16:29:01 -07001962 if (len > EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferEnd)) {
Paul Duffinba34a0c2017-02-27 14:40:16 +00001963#ifdef XML_CONTEXT_BYTES
1964 int keep;
Haibo Huang40a71912019-10-11 11:13:39 -07001965#endif /* defined XML_CONTEXT_BYTES */
Paul Duffinba34a0c2017-02-27 14:40:16 +00001966 /* Do not invoke signed arithmetic overflow: */
Haibo Huang40a71912019-10-11 11:13:39 -07001967 int neededSize = (int)((unsigned)len
1968 + (unsigned)EXPAT_SAFE_PTR_DIFF(
1969 parser->m_bufferEnd, parser->m_bufferPtr));
Paul Duffinc05e0322016-05-04 10:42:31 +01001970 if (neededSize < 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08001971 parser->m_errorCode = XML_ERROR_NO_MEMORY;
Paul Duffinc05e0322016-05-04 10:42:31 +01001972 return NULL;
1973 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001974#ifdef XML_CONTEXT_BYTES
Elliott Hughesaaec48e2018-08-16 16:29:01 -07001975 keep = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001976 if (keep > XML_CONTEXT_BYTES)
1977 keep = XML_CONTEXT_BYTES;
Sadaf Ebrahimi1cea5722022-06-02 19:32:22 +00001978 /* Detect and prevent integer overflow */
1979 if (keep > INT_MAX - neededSize) {
1980 parser->m_errorCode = XML_ERROR_NO_MEMORY;
1981 return NULL;
1982 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001983 neededSize += keep;
Haibo Huang40a71912019-10-11 11:13:39 -07001984#endif /* defined XML_CONTEXT_BYTES */
1985 if (neededSize
1986 <= EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_buffer)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001987#ifdef XML_CONTEXT_BYTES
Elliott Hughesaaec48e2018-08-16 16:29:01 -07001988 if (keep < EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer)) {
Haibo Huang40a71912019-10-11 11:13:39 -07001989 int offset
1990 = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer)
1991 - keep;
1992 /* The buffer pointers cannot be NULL here; we have at least some bytes
1993 * in the buffer */
1994 memmove(parser->m_buffer, &parser->m_buffer[offset],
1995 parser->m_bufferEnd - parser->m_bufferPtr + keep);
Elliott Hughes72472942018-01-10 08:36:10 -08001996 parser->m_bufferEnd -= offset;
1997 parser->m_bufferPtr -= offset;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001998 }
1999#else
Elliott Hughesaaec48e2018-08-16 16:29:01 -07002000 if (parser->m_buffer && parser->m_bufferPtr) {
2001 memmove(parser->m_buffer, parser->m_bufferPtr,
2002 EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr));
Haibo Huang40a71912019-10-11 11:13:39 -07002003 parser->m_bufferEnd
2004 = parser->m_buffer
2005 + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr);
Elliott Hughesaaec48e2018-08-16 16:29:01 -07002006 parser->m_bufferPtr = parser->m_buffer;
2007 }
Haibo Huang40a71912019-10-11 11:13:39 -07002008#endif /* not defined XML_CONTEXT_BYTES */
2009 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002010 char *newBuf;
Haibo Huang40a71912019-10-11 11:13:39 -07002011 int bufferSize
2012 = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002013 if (bufferSize == 0)
2014 bufferSize = INIT_BUFFER_SIZE;
2015 do {
Paul Duffinba34a0c2017-02-27 14:40:16 +00002016 /* Do not invoke signed arithmetic overflow: */
Haibo Huang40a71912019-10-11 11:13:39 -07002017 bufferSize = (int)(2U * (unsigned)bufferSize);
Paul Duffinc05e0322016-05-04 10:42:31 +01002018 } while (bufferSize < neededSize && bufferSize > 0);
2019 if (bufferSize <= 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08002020 parser->m_errorCode = XML_ERROR_NO_MEMORY;
Paul Duffinc05e0322016-05-04 10:42:31 +01002021 return NULL;
2022 }
Elliott Hughes72472942018-01-10 08:36:10 -08002023 newBuf = (char *)MALLOC(parser, bufferSize);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002024 if (newBuf == 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08002025 parser->m_errorCode = XML_ERROR_NO_MEMORY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002026 return NULL;
2027 }
Elliott Hughes72472942018-01-10 08:36:10 -08002028 parser->m_bufferLim = newBuf + bufferSize;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002029#ifdef XML_CONTEXT_BYTES
Elliott Hughes72472942018-01-10 08:36:10 -08002030 if (parser->m_bufferPtr) {
Elliott Hughesaaec48e2018-08-16 16:29:01 -07002031 memcpy(newBuf, &parser->m_bufferPtr[-keep],
Haibo Huang40a71912019-10-11 11:13:39 -07002032 EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)
2033 + keep);
Elliott Hughes72472942018-01-10 08:36:10 -08002034 FREE(parser, parser->m_buffer);
2035 parser->m_buffer = newBuf;
Haibo Huang40a71912019-10-11 11:13:39 -07002036 parser->m_bufferEnd
2037 = parser->m_buffer
2038 + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)
2039 + keep;
Elliott Hughes72472942018-01-10 08:36:10 -08002040 parser->m_bufferPtr = parser->m_buffer + keep;
Haibo Huang40a71912019-10-11 11:13:39 -07002041 } else {
Elliott Hughesaaec48e2018-08-16 16:29:01 -07002042 /* This must be a brand new buffer with no data in it yet */
2043 parser->m_bufferEnd = newBuf;
Elliott Hughes72472942018-01-10 08:36:10 -08002044 parser->m_bufferPtr = parser->m_buffer = newBuf;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002045 }
2046#else
Elliott Hughes72472942018-01-10 08:36:10 -08002047 if (parser->m_bufferPtr) {
Elliott Hughesaaec48e2018-08-16 16:29:01 -07002048 memcpy(newBuf, parser->m_bufferPtr,
2049 EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr));
Elliott Hughes72472942018-01-10 08:36:10 -08002050 FREE(parser, parser->m_buffer);
Haibo Huang40a71912019-10-11 11:13:39 -07002051 parser->m_bufferEnd
2052 = newBuf
2053 + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr);
2054 } else {
Elliott Hughesaaec48e2018-08-16 16:29:01 -07002055 /* This must be a brand new buffer with no data in it yet */
2056 parser->m_bufferEnd = newBuf;
2057 }
Elliott Hughes72472942018-01-10 08:36:10 -08002058 parser->m_bufferPtr = parser->m_buffer = newBuf;
Haibo Huang40a71912019-10-11 11:13:39 -07002059#endif /* not defined XML_CONTEXT_BYTES */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002060 }
Elliott Hughes72472942018-01-10 08:36:10 -08002061 parser->m_eventPtr = parser->m_eventEndPtr = NULL;
2062 parser->m_positionPtr = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002063 }
Elliott Hughes72472942018-01-10 08:36:10 -08002064 return parser->m_bufferEnd;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002065}
2066
2067enum XML_Status XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002068XML_StopParser(XML_Parser parser, XML_Bool resumable) {
Elliott Hughes72472942018-01-10 08:36:10 -08002069 if (parser == NULL)
2070 return XML_STATUS_ERROR;
2071 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002072 case XML_SUSPENDED:
2073 if (resumable) {
Elliott Hughes72472942018-01-10 08:36:10 -08002074 parser->m_errorCode = XML_ERROR_SUSPENDED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002075 return XML_STATUS_ERROR;
2076 }
Elliott Hughes72472942018-01-10 08:36:10 -08002077 parser->m_parsingStatus.parsing = XML_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002078 break;
2079 case XML_FINISHED:
Elliott Hughes72472942018-01-10 08:36:10 -08002080 parser->m_errorCode = XML_ERROR_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002081 return XML_STATUS_ERROR;
2082 default:
2083 if (resumable) {
2084#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08002085 if (parser->m_isParamEntity) {
2086 parser->m_errorCode = XML_ERROR_SUSPEND_PE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002087 return XML_STATUS_ERROR;
2088 }
2089#endif
Elliott Hughes72472942018-01-10 08:36:10 -08002090 parser->m_parsingStatus.parsing = XML_SUSPENDED;
Haibo Huang40a71912019-10-11 11:13:39 -07002091 } else
Elliott Hughes72472942018-01-10 08:36:10 -08002092 parser->m_parsingStatus.parsing = XML_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002093 }
2094 return XML_STATUS_OK;
2095}
2096
2097enum XML_Status XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002098XML_ResumeParser(XML_Parser parser) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002099 enum XML_Status result = XML_STATUS_OK;
2100
Elliott Hughes72472942018-01-10 08:36:10 -08002101 if (parser == NULL)
2102 return XML_STATUS_ERROR;
2103 if (parser->m_parsingStatus.parsing != XML_SUSPENDED) {
2104 parser->m_errorCode = XML_ERROR_NOT_SUSPENDED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002105 return XML_STATUS_ERROR;
2106 }
Elliott Hughes72472942018-01-10 08:36:10 -08002107 parser->m_parsingStatus.parsing = XML_PARSING;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002108
Haibo Huang40a71912019-10-11 11:13:39 -07002109 parser->m_errorCode = parser->m_processor(
2110 parser, parser->m_bufferPtr, parser->m_parseEndPtr, &parser->m_bufferPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002111
Elliott Hughes72472942018-01-10 08:36:10 -08002112 if (parser->m_errorCode != XML_ERROR_NONE) {
2113 parser->m_eventEndPtr = parser->m_eventPtr;
2114 parser->m_processor = errorProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002115 return XML_STATUS_ERROR;
Haibo Huang40a71912019-10-11 11:13:39 -07002116 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08002117 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002118 case XML_SUSPENDED:
2119 result = XML_STATUS_SUSPENDED;
2120 break;
Elliott Hughes35e432d2012-09-09 14:23:38 -07002121 case XML_INITIALIZED:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002122 case XML_PARSING:
Elliott Hughes72472942018-01-10 08:36:10 -08002123 if (parser->m_parsingStatus.finalBuffer) {
2124 parser->m_parsingStatus.parsing = XML_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002125 return result;
2126 }
Haibo Huang40a71912019-10-11 11:13:39 -07002127 default:;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002128 }
2129 }
2130
Haibo Huang40a71912019-10-11 11:13:39 -07002131 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
2132 parser->m_bufferPtr, &parser->m_position);
Elliott Hughes72472942018-01-10 08:36:10 -08002133 parser->m_positionPtr = parser->m_bufferPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002134 return result;
2135}
2136
2137void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002138XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status) {
Elliott Hughes72472942018-01-10 08:36:10 -08002139 if (parser == NULL)
2140 return;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002141 assert(status != NULL);
2142 *status = parser->m_parsingStatus;
2143}
2144
2145enum XML_Error XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002146XML_GetErrorCode(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002147 if (parser == NULL)
2148 return XML_ERROR_INVALID_ARGUMENT;
2149 return parser->m_errorCode;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002150}
2151
2152XML_Index XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002153XML_GetCurrentByteIndex(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002154 if (parser == NULL)
2155 return -1;
2156 if (parser->m_eventPtr)
Haibo Huang40a71912019-10-11 11:13:39 -07002157 return (XML_Index)(parser->m_parseEndByteIndex
2158 - (parser->m_parseEndPtr - parser->m_eventPtr));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002159 return -1;
2160}
2161
2162int XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002163XML_GetCurrentByteCount(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002164 if (parser == NULL)
2165 return 0;
2166 if (parser->m_eventEndPtr && parser->m_eventPtr)
2167 return (int)(parser->m_eventEndPtr - parser->m_eventPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002168 return 0;
2169}
2170
Haibo Huang40a71912019-10-11 11:13:39 -07002171const char *XMLCALL
2172XML_GetInputContext(XML_Parser parser, int *offset, int *size) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002173#ifdef XML_CONTEXT_BYTES
Elliott Hughes72472942018-01-10 08:36:10 -08002174 if (parser == NULL)
2175 return NULL;
2176 if (parser->m_eventPtr && parser->m_buffer) {
2177 if (offset != NULL)
2178 *offset = (int)(parser->m_eventPtr - parser->m_buffer);
2179 if (size != NULL)
Haibo Huang40a71912019-10-11 11:13:39 -07002180 *size = (int)(parser->m_bufferEnd - parser->m_buffer);
Elliott Hughes72472942018-01-10 08:36:10 -08002181 return parser->m_buffer;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002182 }
Elliott Hughes72472942018-01-10 08:36:10 -08002183#else
2184 (void)parser;
2185 (void)offset;
2186 (void)size;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002187#endif /* defined XML_CONTEXT_BYTES */
Haibo Huangd1a324a2020-10-28 22:19:36 -07002188 return (const char *)0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002189}
2190
2191XML_Size XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002192XML_GetCurrentLineNumber(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002193 if (parser == NULL)
2194 return 0;
2195 if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) {
Haibo Huang40a71912019-10-11 11:13:39 -07002196 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
2197 parser->m_eventPtr, &parser->m_position);
Elliott Hughes72472942018-01-10 08:36:10 -08002198 parser->m_positionPtr = parser->m_eventPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002199 }
Elliott Hughes72472942018-01-10 08:36:10 -08002200 return parser->m_position.lineNumber + 1;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002201}
2202
2203XML_Size XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002204XML_GetCurrentColumnNumber(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002205 if (parser == NULL)
2206 return 0;
2207 if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) {
Haibo Huang40a71912019-10-11 11:13:39 -07002208 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
2209 parser->m_eventPtr, &parser->m_position);
Elliott Hughes72472942018-01-10 08:36:10 -08002210 parser->m_positionPtr = parser->m_eventPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002211 }
Elliott Hughes72472942018-01-10 08:36:10 -08002212 return parser->m_position.columnNumber;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002213}
2214
2215void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002216XML_FreeContentModel(XML_Parser parser, XML_Content *model) {
Elliott Hughes72472942018-01-10 08:36:10 -08002217 if (parser != NULL)
2218 FREE(parser, model);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002219}
2220
Haibo Huang40a71912019-10-11 11:13:39 -07002221void *XMLCALL
2222XML_MemMalloc(XML_Parser parser, size_t size) {
Elliott Hughes72472942018-01-10 08:36:10 -08002223 if (parser == NULL)
2224 return NULL;
2225 return MALLOC(parser, size);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002226}
2227
Haibo Huang40a71912019-10-11 11:13:39 -07002228void *XMLCALL
2229XML_MemRealloc(XML_Parser parser, void *ptr, size_t size) {
Elliott Hughes72472942018-01-10 08:36:10 -08002230 if (parser == NULL)
2231 return NULL;
2232 return REALLOC(parser, ptr, size);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002233}
2234
2235void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002236XML_MemFree(XML_Parser parser, void *ptr) {
Elliott Hughes72472942018-01-10 08:36:10 -08002237 if (parser != NULL)
2238 FREE(parser, ptr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002239}
2240
2241void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002242XML_DefaultCurrent(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002243 if (parser == NULL)
2244 return;
2245 if (parser->m_defaultHandler) {
2246 if (parser->m_openInternalEntities)
Haibo Huang40a71912019-10-11 11:13:39 -07002247 reportDefault(parser, parser->m_internalEncoding,
Elliott Hughes72472942018-01-10 08:36:10 -08002248 parser->m_openInternalEntities->internalEventPtr,
2249 parser->m_openInternalEntities->internalEventEndPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002250 else
Haibo Huang40a71912019-10-11 11:13:39 -07002251 reportDefault(parser, parser->m_encoding, parser->m_eventPtr,
2252 parser->m_eventEndPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002253 }
2254}
2255
Haibo Huang40a71912019-10-11 11:13:39 -07002256const XML_LChar *XMLCALL
2257XML_ErrorString(enum XML_Error code) {
Elliott Hughes72472942018-01-10 08:36:10 -08002258 switch (code) {
2259 case XML_ERROR_NONE:
2260 return NULL;
2261 case XML_ERROR_NO_MEMORY:
2262 return XML_L("out of memory");
2263 case XML_ERROR_SYNTAX:
2264 return XML_L("syntax error");
2265 case XML_ERROR_NO_ELEMENTS:
2266 return XML_L("no element found");
2267 case XML_ERROR_INVALID_TOKEN:
2268 return XML_L("not well-formed (invalid token)");
2269 case XML_ERROR_UNCLOSED_TOKEN:
2270 return XML_L("unclosed token");
2271 case XML_ERROR_PARTIAL_CHAR:
2272 return XML_L("partial character");
2273 case XML_ERROR_TAG_MISMATCH:
2274 return XML_L("mismatched tag");
2275 case XML_ERROR_DUPLICATE_ATTRIBUTE:
2276 return XML_L("duplicate attribute");
2277 case XML_ERROR_JUNK_AFTER_DOC_ELEMENT:
2278 return XML_L("junk after document element");
2279 case XML_ERROR_PARAM_ENTITY_REF:
2280 return XML_L("illegal parameter entity reference");
2281 case XML_ERROR_UNDEFINED_ENTITY:
2282 return XML_L("undefined entity");
2283 case XML_ERROR_RECURSIVE_ENTITY_REF:
2284 return XML_L("recursive entity reference");
2285 case XML_ERROR_ASYNC_ENTITY:
2286 return XML_L("asynchronous entity");
2287 case XML_ERROR_BAD_CHAR_REF:
2288 return XML_L("reference to invalid character number");
2289 case XML_ERROR_BINARY_ENTITY_REF:
2290 return XML_L("reference to binary entity");
2291 case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF:
2292 return XML_L("reference to external entity in attribute");
2293 case XML_ERROR_MISPLACED_XML_PI:
2294 return XML_L("XML or text declaration not at start of entity");
2295 case XML_ERROR_UNKNOWN_ENCODING:
2296 return XML_L("unknown encoding");
2297 case XML_ERROR_INCORRECT_ENCODING:
2298 return XML_L("encoding specified in XML declaration is incorrect");
2299 case XML_ERROR_UNCLOSED_CDATA_SECTION:
2300 return XML_L("unclosed CDATA section");
2301 case XML_ERROR_EXTERNAL_ENTITY_HANDLING:
2302 return XML_L("error in processing external entity reference");
2303 case XML_ERROR_NOT_STANDALONE:
2304 return XML_L("document is not standalone");
2305 case XML_ERROR_UNEXPECTED_STATE:
2306 return XML_L("unexpected parser state - please send a bug report");
2307 case XML_ERROR_ENTITY_DECLARED_IN_PE:
2308 return XML_L("entity declared in parameter entity");
2309 case XML_ERROR_FEATURE_REQUIRES_XML_DTD:
2310 return XML_L("requested feature requires XML_DTD support in Expat");
2311 case XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING:
2312 return XML_L("cannot change setting once parsing has begun");
2313 /* Added in 1.95.7. */
2314 case XML_ERROR_UNBOUND_PREFIX:
2315 return XML_L("unbound prefix");
2316 /* Added in 1.95.8. */
2317 case XML_ERROR_UNDECLARING_PREFIX:
2318 return XML_L("must not undeclare prefix");
2319 case XML_ERROR_INCOMPLETE_PE:
2320 return XML_L("incomplete markup in parameter entity");
2321 case XML_ERROR_XML_DECL:
2322 return XML_L("XML declaration not well-formed");
2323 case XML_ERROR_TEXT_DECL:
2324 return XML_L("text declaration not well-formed");
2325 case XML_ERROR_PUBLICID:
2326 return XML_L("illegal character(s) in public id");
2327 case XML_ERROR_SUSPENDED:
2328 return XML_L("parser suspended");
2329 case XML_ERROR_NOT_SUSPENDED:
2330 return XML_L("parser not suspended");
2331 case XML_ERROR_ABORTED:
2332 return XML_L("parsing aborted");
2333 case XML_ERROR_FINISHED:
2334 return XML_L("parsing finished");
2335 case XML_ERROR_SUSPEND_PE:
2336 return XML_L("cannot suspend in external parameter entity");
2337 /* Added in 2.0.0. */
2338 case XML_ERROR_RESERVED_PREFIX_XML:
Haibo Huang40a71912019-10-11 11:13:39 -07002339 return XML_L(
2340 "reserved prefix (xml) must not be undeclared or bound to another namespace name");
Elliott Hughes72472942018-01-10 08:36:10 -08002341 case XML_ERROR_RESERVED_PREFIX_XMLNS:
2342 return XML_L("reserved prefix (xmlns) must not be declared or undeclared");
2343 case XML_ERROR_RESERVED_NAMESPACE_URI:
Haibo Huang40a71912019-10-11 11:13:39 -07002344 return XML_L(
2345 "prefix must not be bound to one of the reserved namespace names");
Elliott Hughes72472942018-01-10 08:36:10 -08002346 /* Added in 2.2.5. */
Haibo Huang40a71912019-10-11 11:13:39 -07002347 case XML_ERROR_INVALID_ARGUMENT: /* Constant added in 2.2.1, already */
Elliott Hughes72472942018-01-10 08:36:10 -08002348 return XML_L("invalid argument");
Elliott Hughesf648a292021-04-01 15:10:13 -07002349 /* Added in 2.3.0. */
2350 case XML_ERROR_NO_BUFFER:
2351 return XML_L(
2352 "a successful prior call to function XML_GetBuffer is required");
Elliott Hughes72472942018-01-10 08:36:10 -08002353 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002354 return NULL;
2355}
2356
Haibo Huang40a71912019-10-11 11:13:39 -07002357const XML_LChar *XMLCALL
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002358XML_ExpatVersion(void) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002359 /* V1 is used to string-ize the version number. However, it would
2360 string-ize the actual version macro *names* unless we get them
2361 substituted before being passed to V1. CPP is defined to expand
2362 a macro, then rescan for more expansions. Thus, we use V2 to expand
2363 the version macros, then CPP will expand the resulting V1() macro
2364 with the correct numerals. */
2365 /* ### I'm assuming cpp is portable in this respect... */
2366
Haibo Huang40a71912019-10-11 11:13:39 -07002367#define V1(a, b, c) XML_L(#a) XML_L(".") XML_L(#b) XML_L(".") XML_L(#c)
2368#define V2(a, b, c) XML_L("expat_") V1(a, b, c)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002369
2370 return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
2371
2372#undef V1
2373#undef V2
2374}
2375
2376XML_Expat_Version XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002377XML_ExpatVersionInfo(void) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002378 XML_Expat_Version version;
2379
2380 version.major = XML_MAJOR_VERSION;
2381 version.minor = XML_MINOR_VERSION;
2382 version.micro = XML_MICRO_VERSION;
2383
2384 return version;
2385}
2386
Haibo Huang40a71912019-10-11 11:13:39 -07002387const XML_Feature *XMLCALL
2388XML_GetFeatureList(void) {
2389 static const XML_Feature features[]
2390 = {{XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"),
2391 sizeof(XML_Char)},
2392 {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
2393 sizeof(XML_LChar)},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002394#ifdef XML_UNICODE
Haibo Huang40a71912019-10-11 11:13:39 -07002395 {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002396#endif
2397#ifdef XML_UNICODE_WCHAR_T
Haibo Huang40a71912019-10-11 11:13:39 -07002398 {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002399#endif
2400#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07002401 {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002402#endif
2403#ifdef XML_CONTEXT_BYTES
Haibo Huang40a71912019-10-11 11:13:39 -07002404 {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
2405 XML_CONTEXT_BYTES},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002406#endif
2407#ifdef XML_MIN_SIZE
Haibo Huang40a71912019-10-11 11:13:39 -07002408 {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002409#endif
2410#ifdef XML_NS
Haibo Huang40a71912019-10-11 11:13:39 -07002411 {XML_FEATURE_NS, XML_L("XML_NS"), 0},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002412#endif
Elliott Hughesd07d5a72009-09-25 16:04:37 -07002413#ifdef XML_LARGE_SIZE
Haibo Huang40a71912019-10-11 11:13:39 -07002414 {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0},
Elliott Hughes35e432d2012-09-09 14:23:38 -07002415#endif
2416#ifdef XML_ATTR_INFO
Haibo Huang40a71912019-10-11 11:13:39 -07002417 {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0},
Elliott Hughes35e432d2012-09-09 14:23:38 -07002418#endif
Haibo Huang40a71912019-10-11 11:13:39 -07002419 {XML_FEATURE_END, NULL, 0}};
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002420
2421 return features;
2422}
2423
2424/* Initially tag->rawName always points into the parse buffer;
2425 for those TAG instances opened while the current parse buffer was
2426 processed, and not yet closed, we need to store tag->rawName in a more
2427 permanent location, since the parse buffer is about to be discarded.
2428*/
2429static XML_Bool
Haibo Huang40a71912019-10-11 11:13:39 -07002430storeRawNames(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002431 TAG *tag = parser->m_tagStack;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002432 while (tag) {
2433 int bufSize;
2434 int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
2435 char *rawNameBuf = tag->buf + nameLen;
Elliott Hughes72472942018-01-10 08:36:10 -08002436 /* Stop if already stored. Since m_tagStack is a stack, we can stop
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002437 at the first entry that has already been copied; everything
2438 below it in the stack is already been accounted for in a
2439 previous call to this function.
2440 */
2441 if (tag->rawName == rawNameBuf)
2442 break;
2443 /* For re-use purposes we need to ensure that the
2444 size of tag->buf is a multiple of sizeof(XML_Char).
2445 */
2446 bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
2447 if (bufSize > tag->bufEnd - tag->buf) {
Elliott Hughes72472942018-01-10 08:36:10 -08002448 char *temp = (char *)REALLOC(parser, tag->buf, bufSize);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002449 if (temp == NULL)
2450 return XML_FALSE;
2451 /* if tag->name.str points to tag->buf (only when namespace
2452 processing is off) then we have to update it
2453 */
2454 if (tag->name.str == (XML_Char *)tag->buf)
2455 tag->name.str = (XML_Char *)temp;
2456 /* if tag->name.localPart is set (when namespace processing is on)
2457 then update it as well, since it will always point into tag->buf
2458 */
2459 if (tag->name.localPart)
Haibo Huang40a71912019-10-11 11:13:39 -07002460 tag->name.localPart
2461 = (XML_Char *)temp + (tag->name.localPart - (XML_Char *)tag->buf);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002462 tag->buf = temp;
2463 tag->bufEnd = temp + bufSize;
2464 rawNameBuf = temp + nameLen;
2465 }
2466 memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
2467 tag->rawName = rawNameBuf;
2468 tag = tag->parent;
2469 }
2470 return XML_TRUE;
2471}
2472
2473static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002474contentProcessor(XML_Parser parser, const char *start, const char *end,
2475 const char **endPtr) {
2476 enum XML_Error result
2477 = doContent(parser, 0, parser->m_encoding, start, end, endPtr,
2478 (XML_Bool)! parser->m_parsingStatus.finalBuffer);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002479 if (result == XML_ERROR_NONE) {
Haibo Huang40a71912019-10-11 11:13:39 -07002480 if (! storeRawNames(parser))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002481 return XML_ERROR_NO_MEMORY;
2482 }
2483 return result;
2484}
2485
2486static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002487externalEntityInitProcessor(XML_Parser parser, const char *start,
2488 const char *end, const char **endPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002489 enum XML_Error result = initializeEncoding(parser);
2490 if (result != XML_ERROR_NONE)
2491 return result;
Elliott Hughes72472942018-01-10 08:36:10 -08002492 parser->m_processor = externalEntityInitProcessor2;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002493 return externalEntityInitProcessor2(parser, start, end, endPtr);
2494}
2495
2496static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002497externalEntityInitProcessor2(XML_Parser parser, const char *start,
2498 const char *end, const char **endPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002499 const char *next = start; /* XmlContentTok doesn't always set the last arg */
Elliott Hughes72472942018-01-10 08:36:10 -08002500 int tok = XmlContentTok(parser->m_encoding, start, end, &next);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002501 switch (tok) {
2502 case XML_TOK_BOM:
2503 /* If we are at the end of the buffer, this would cause the next stage,
2504 i.e. externalEntityInitProcessor3, to pass control directly to
2505 doContent (by detecting XML_TOK_NONE) without processing any xml text
2506 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
2507 */
Haibo Huang40a71912019-10-11 11:13:39 -07002508 if (next == end && ! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002509 *endPtr = next;
2510 return XML_ERROR_NONE;
2511 }
2512 start = next;
2513 break;
2514 case XML_TOK_PARTIAL:
Haibo Huang40a71912019-10-11 11:13:39 -07002515 if (! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002516 *endPtr = start;
2517 return XML_ERROR_NONE;
2518 }
Elliott Hughes72472942018-01-10 08:36:10 -08002519 parser->m_eventPtr = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002520 return XML_ERROR_UNCLOSED_TOKEN;
2521 case XML_TOK_PARTIAL_CHAR:
Haibo Huang40a71912019-10-11 11:13:39 -07002522 if (! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002523 *endPtr = start;
2524 return XML_ERROR_NONE;
2525 }
Elliott Hughes72472942018-01-10 08:36:10 -08002526 parser->m_eventPtr = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002527 return XML_ERROR_PARTIAL_CHAR;
2528 }
Elliott Hughes72472942018-01-10 08:36:10 -08002529 parser->m_processor = externalEntityInitProcessor3;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002530 return externalEntityInitProcessor3(parser, start, end, endPtr);
2531}
2532
2533static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002534externalEntityInitProcessor3(XML_Parser parser, const char *start,
2535 const char *end, const char **endPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002536 int tok;
2537 const char *next = start; /* XmlContentTok doesn't always set the last arg */
Elliott Hughes72472942018-01-10 08:36:10 -08002538 parser->m_eventPtr = start;
2539 tok = XmlContentTok(parser->m_encoding, start, end, &next);
2540 parser->m_eventEndPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002541
2542 switch (tok) {
Haibo Huang40a71912019-10-11 11:13:39 -07002543 case XML_TOK_XML_DECL: {
2544 enum XML_Error result;
2545 result = processXmlDecl(parser, 1, start, next);
2546 if (result != XML_ERROR_NONE)
2547 return result;
2548 switch (parser->m_parsingStatus.parsing) {
2549 case XML_SUSPENDED:
2550 *endPtr = next;
2551 return XML_ERROR_NONE;
2552 case XML_FINISHED:
2553 return XML_ERROR_ABORTED;
2554 default:
2555 start = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002556 }
Haibo Huang40a71912019-10-11 11:13:39 -07002557 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002558 case XML_TOK_PARTIAL:
Haibo Huang40a71912019-10-11 11:13:39 -07002559 if (! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002560 *endPtr = start;
2561 return XML_ERROR_NONE;
2562 }
2563 return XML_ERROR_UNCLOSED_TOKEN;
2564 case XML_TOK_PARTIAL_CHAR:
Haibo Huang40a71912019-10-11 11:13:39 -07002565 if (! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002566 *endPtr = start;
2567 return XML_ERROR_NONE;
2568 }
2569 return XML_ERROR_PARTIAL_CHAR;
2570 }
Elliott Hughes72472942018-01-10 08:36:10 -08002571 parser->m_processor = externalEntityContentProcessor;
2572 parser->m_tagLevel = 1;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002573 return externalEntityContentProcessor(parser, start, end, endPtr);
2574}
2575
2576static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002577externalEntityContentProcessor(XML_Parser parser, const char *start,
2578 const char *end, const char **endPtr) {
2579 enum XML_Error result
2580 = doContent(parser, 1, parser->m_encoding, start, end, endPtr,
2581 (XML_Bool)! parser->m_parsingStatus.finalBuffer);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002582 if (result == XML_ERROR_NONE) {
Haibo Huang40a71912019-10-11 11:13:39 -07002583 if (! storeRawNames(parser))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002584 return XML_ERROR_NO_MEMORY;
2585 }
2586 return result;
2587}
2588
2589static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07002590doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
2591 const char *s, const char *end, const char **nextPtr,
2592 XML_Bool haveMore) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002593 /* save one level of indirection */
Haibo Huang40a71912019-10-11 11:13:39 -07002594 DTD *const dtd = parser->m_dtd;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002595
2596 const char **eventPP;
2597 const char **eventEndPP;
Elliott Hughes72472942018-01-10 08:36:10 -08002598 if (enc == parser->m_encoding) {
2599 eventPP = &parser->m_eventPtr;
2600 eventEndPP = &parser->m_eventEndPtr;
Haibo Huang40a71912019-10-11 11:13:39 -07002601 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08002602 eventPP = &(parser->m_openInternalEntities->internalEventPtr);
2603 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002604 }
2605 *eventPP = s;
2606
2607 for (;;) {
2608 const char *next = s; /* XmlContentTok doesn't always set the last arg */
2609 int tok = XmlContentTok(enc, s, end, &next);
2610 *eventEndPP = next;
2611 switch (tok) {
2612 case XML_TOK_TRAILING_CR:
2613 if (haveMore) {
2614 *nextPtr = s;
2615 return XML_ERROR_NONE;
2616 }
2617 *eventEndPP = end;
Elliott Hughes72472942018-01-10 08:36:10 -08002618 if (parser->m_characterDataHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002619 XML_Char c = 0xA;
Elliott Hughes72472942018-01-10 08:36:10 -08002620 parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
Haibo Huang40a71912019-10-11 11:13:39 -07002621 } else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002622 reportDefault(parser, enc, s, end);
Elliott Hughes35e432d2012-09-09 14:23:38 -07002623 /* We are at the end of the final buffer, should we check for
2624 XML_SUSPENDED, XML_FINISHED?
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002625 */
2626 if (startTagLevel == 0)
2627 return XML_ERROR_NO_ELEMENTS;
Elliott Hughes72472942018-01-10 08:36:10 -08002628 if (parser->m_tagLevel != startTagLevel)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002629 return XML_ERROR_ASYNC_ENTITY;
2630 *nextPtr = end;
2631 return XML_ERROR_NONE;
2632 case XML_TOK_NONE:
2633 if (haveMore) {
2634 *nextPtr = s;
2635 return XML_ERROR_NONE;
2636 }
2637 if (startTagLevel > 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08002638 if (parser->m_tagLevel != startTagLevel)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002639 return XML_ERROR_ASYNC_ENTITY;
2640 *nextPtr = s;
2641 return XML_ERROR_NONE;
2642 }
2643 return XML_ERROR_NO_ELEMENTS;
2644 case XML_TOK_INVALID:
2645 *eventPP = next;
2646 return XML_ERROR_INVALID_TOKEN;
2647 case XML_TOK_PARTIAL:
2648 if (haveMore) {
2649 *nextPtr = s;
2650 return XML_ERROR_NONE;
2651 }
2652 return XML_ERROR_UNCLOSED_TOKEN;
2653 case XML_TOK_PARTIAL_CHAR:
2654 if (haveMore) {
2655 *nextPtr = s;
2656 return XML_ERROR_NONE;
2657 }
2658 return XML_ERROR_PARTIAL_CHAR;
Haibo Huang40a71912019-10-11 11:13:39 -07002659 case XML_TOK_ENTITY_REF: {
2660 const XML_Char *name;
2661 ENTITY *entity;
2662 XML_Char ch = (XML_Char)XmlPredefinedEntityName(
2663 enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar);
2664 if (ch) {
2665 if (parser->m_characterDataHandler)
2666 parser->m_characterDataHandler(parser->m_handlerArg, &ch, 1);
Elliott Hughes72472942018-01-10 08:36:10 -08002667 else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002668 reportDefault(parser, enc, s, next);
2669 break;
2670 }
Haibo Huang40a71912019-10-11 11:13:39 -07002671 name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
2672 next - enc->minBytesPerChar);
2673 if (! name)
2674 return XML_ERROR_NO_MEMORY;
2675 entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
2676 poolDiscard(&dtd->pool);
2677 /* First, determine if a check for an existing declaration is needed;
2678 if yes, check that the entity exists, and that it is internal,
2679 otherwise call the skipped entity or default handler.
2680 */
2681 if (! dtd->hasParamEntityRefs || dtd->standalone) {
2682 if (! entity)
2683 return XML_ERROR_UNDEFINED_ENTITY;
2684 else if (! entity->is_internal)
2685 return XML_ERROR_ENTITY_DECLARED_IN_PE;
2686 } else if (! entity) {
2687 if (parser->m_skippedEntityHandler)
2688 parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
2689 else if (parser->m_defaultHandler)
2690 reportDefault(parser, enc, s, next);
2691 break;
2692 }
2693 if (entity->open)
2694 return XML_ERROR_RECURSIVE_ENTITY_REF;
2695 if (entity->notation)
2696 return XML_ERROR_BINARY_ENTITY_REF;
2697 if (entity->textPtr) {
2698 enum XML_Error result;
2699 if (! parser->m_defaultExpandInternalEntities) {
2700 if (parser->m_skippedEntityHandler)
2701 parser->m_skippedEntityHandler(parser->m_handlerArg, entity->name,
2702 0);
2703 else if (parser->m_defaultHandler)
2704 reportDefault(parser, enc, s, next);
2705 break;
2706 }
2707 result = processInternalEntity(parser, entity, XML_FALSE);
2708 if (result != XML_ERROR_NONE)
2709 return result;
2710 } else if (parser->m_externalEntityRefHandler) {
2711 const XML_Char *context;
2712 entity->open = XML_TRUE;
2713 context = getContext(parser);
2714 entity->open = XML_FALSE;
2715 if (! context)
2716 return XML_ERROR_NO_MEMORY;
2717 if (! parser->m_externalEntityRefHandler(
2718 parser->m_externalEntityRefHandlerArg, context, entity->base,
2719 entity->systemId, entity->publicId))
2720 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
2721 poolDiscard(&parser->m_tempPool);
2722 } else if (parser->m_defaultHandler)
2723 reportDefault(parser, enc, s, next);
2724 break;
2725 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002726 case XML_TOK_START_TAG_NO_ATTS:
2727 /* fall through */
Haibo Huang40a71912019-10-11 11:13:39 -07002728 case XML_TOK_START_TAG_WITH_ATTS: {
2729 TAG *tag;
2730 enum XML_Error result;
2731 XML_Char *toPtr;
2732 if (parser->m_freeTagList) {
2733 tag = parser->m_freeTagList;
2734 parser->m_freeTagList = parser->m_freeTagList->parent;
2735 } else {
2736 tag = (TAG *)MALLOC(parser, sizeof(TAG));
2737 if (! tag)
2738 return XML_ERROR_NO_MEMORY;
2739 tag->buf = (char *)MALLOC(parser, INIT_TAG_BUF_SIZE);
2740 if (! tag->buf) {
2741 FREE(parser, tag);
2742 return XML_ERROR_NO_MEMORY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002743 }
Haibo Huang40a71912019-10-11 11:13:39 -07002744 tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002745 }
Haibo Huang40a71912019-10-11 11:13:39 -07002746 tag->bindings = NULL;
2747 tag->parent = parser->m_tagStack;
2748 parser->m_tagStack = tag;
2749 tag->name.localPart = NULL;
2750 tag->name.prefix = NULL;
2751 tag->rawName = s + enc->minBytesPerChar;
2752 tag->rawNameLength = XmlNameLength(enc, tag->rawName);
2753 ++parser->m_tagLevel;
2754 {
2755 const char *rawNameEnd = tag->rawName + tag->rawNameLength;
2756 const char *fromPtr = tag->rawName;
2757 toPtr = (XML_Char *)tag->buf;
2758 for (;;) {
2759 int bufSize;
2760 int convLen;
2761 const enum XML_Convert_Result convert_res
2762 = XmlConvert(enc, &fromPtr, rawNameEnd, (ICHAR **)&toPtr,
2763 (ICHAR *)tag->bufEnd - 1);
2764 convLen = (int)(toPtr - (XML_Char *)tag->buf);
2765 if ((fromPtr >= rawNameEnd)
2766 || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) {
2767 tag->name.strLen = convLen;
2768 break;
2769 }
2770 bufSize = (int)(tag->bufEnd - tag->buf) << 1;
2771 {
2772 char *temp = (char *)REALLOC(parser, tag->buf, bufSize);
2773 if (temp == NULL)
2774 return XML_ERROR_NO_MEMORY;
2775 tag->buf = temp;
2776 tag->bufEnd = temp + bufSize;
2777 toPtr = (XML_Char *)temp + convLen;
2778 }
2779 }
2780 }
2781 tag->name.str = (XML_Char *)tag->buf;
2782 *toPtr = XML_T('\0');
2783 result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
2784 if (result)
2785 return result;
2786 if (parser->m_startElementHandler)
2787 parser->m_startElementHandler(parser->m_handlerArg, tag->name.str,
2788 (const XML_Char **)parser->m_atts);
2789 else if (parser->m_defaultHandler)
2790 reportDefault(parser, enc, s, next);
2791 poolClear(&parser->m_tempPool);
2792 break;
2793 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002794 case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
2795 /* fall through */
Haibo Huang40a71912019-10-11 11:13:39 -07002796 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS: {
2797 const char *rawName = s + enc->minBytesPerChar;
2798 enum XML_Error result;
2799 BINDING *bindings = NULL;
2800 XML_Bool noElmHandlers = XML_TRUE;
2801 TAG_NAME name;
2802 name.str = poolStoreString(&parser->m_tempPool, enc, rawName,
2803 rawName + XmlNameLength(enc, rawName));
2804 if (! name.str)
2805 return XML_ERROR_NO_MEMORY;
2806 poolFinish(&parser->m_tempPool);
2807 result = storeAtts(parser, enc, s, &name, &bindings);
2808 if (result != XML_ERROR_NONE) {
Elliott Hughes72472942018-01-10 08:36:10 -08002809 freeBindings(parser, bindings);
Haibo Huang40a71912019-10-11 11:13:39 -07002810 return result;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002811 }
Haibo Huang40a71912019-10-11 11:13:39 -07002812 poolFinish(&parser->m_tempPool);
2813 if (parser->m_startElementHandler) {
2814 parser->m_startElementHandler(parser->m_handlerArg, name.str,
2815 (const XML_Char **)parser->m_atts);
2816 noElmHandlers = XML_FALSE;
2817 }
2818 if (parser->m_endElementHandler) {
2819 if (parser->m_startElementHandler)
2820 *eventPP = *eventEndPP;
2821 parser->m_endElementHandler(parser->m_handlerArg, name.str);
2822 noElmHandlers = XML_FALSE;
2823 }
2824 if (noElmHandlers && parser->m_defaultHandler)
2825 reportDefault(parser, enc, s, next);
2826 poolClear(&parser->m_tempPool);
2827 freeBindings(parser, bindings);
2828 }
2829 if ((parser->m_tagLevel == 0)
2830 && (parser->m_parsingStatus.parsing != XML_FINISHED)) {
Elliott Hughesaaec48e2018-08-16 16:29:01 -07002831 if (parser->m_parsingStatus.parsing == XML_SUSPENDED)
2832 parser->m_processor = epilogProcessor;
2833 else
2834 return epilogProcessor(parser, next, end, nextPtr);
Elliott Hughes72472942018-01-10 08:36:10 -08002835 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002836 break;
2837 case XML_TOK_END_TAG:
Elliott Hughes72472942018-01-10 08:36:10 -08002838 if (parser->m_tagLevel == startTagLevel)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002839 return XML_ERROR_ASYNC_ENTITY;
2840 else {
2841 int len;
2842 const char *rawName;
Elliott Hughes72472942018-01-10 08:36:10 -08002843 TAG *tag = parser->m_tagStack;
2844 parser->m_tagStack = tag->parent;
2845 tag->parent = parser->m_freeTagList;
2846 parser->m_freeTagList = tag;
Haibo Huang40a71912019-10-11 11:13:39 -07002847 rawName = s + enc->minBytesPerChar * 2;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002848 len = XmlNameLength(enc, rawName);
2849 if (len != tag->rawNameLength
2850 || memcmp(tag->rawName, rawName, len) != 0) {
2851 *eventPP = rawName;
2852 return XML_ERROR_TAG_MISMATCH;
2853 }
Elliott Hughes72472942018-01-10 08:36:10 -08002854 --parser->m_tagLevel;
2855 if (parser->m_endElementHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002856 const XML_Char *localPart;
2857 const XML_Char *prefix;
2858 XML_Char *uri;
2859 localPart = tag->name.localPart;
Elliott Hughes72472942018-01-10 08:36:10 -08002860 if (parser->m_ns && localPart) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002861 /* localPart and prefix may have been overwritten in
2862 tag->name.str, since this points to the binding->uri
2863 buffer which gets re-used; so we have to add them again
2864 */
2865 uri = (XML_Char *)tag->name.str + tag->name.uriLen;
2866 /* don't need to check for space - already done in storeAtts() */
Haibo Huang40a71912019-10-11 11:13:39 -07002867 while (*localPart)
2868 *uri++ = *localPart++;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002869 prefix = (XML_Char *)tag->name.prefix;
Elliott Hughes72472942018-01-10 08:36:10 -08002870 if (parser->m_ns_triplets && prefix) {
2871 *uri++ = parser->m_namespaceSeparator;
Haibo Huang40a71912019-10-11 11:13:39 -07002872 while (*prefix)
2873 *uri++ = *prefix++;
2874 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002875 *uri = XML_T('\0');
2876 }
Elliott Hughes72472942018-01-10 08:36:10 -08002877 parser->m_endElementHandler(parser->m_handlerArg, tag->name.str);
Haibo Huang40a71912019-10-11 11:13:39 -07002878 } else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002879 reportDefault(parser, enc, s, next);
2880 while (tag->bindings) {
2881 BINDING *b = tag->bindings;
Elliott Hughes72472942018-01-10 08:36:10 -08002882 if (parser->m_endNamespaceDeclHandler)
Haibo Huang40a71912019-10-11 11:13:39 -07002883 parser->m_endNamespaceDeclHandler(parser->m_handlerArg,
2884 b->prefix->name);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002885 tag->bindings = tag->bindings->nextTagBinding;
Elliott Hughes72472942018-01-10 08:36:10 -08002886 b->nextTagBinding = parser->m_freeBindingList;
2887 parser->m_freeBindingList = b;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002888 b->prefix->binding = b->prevPrefixBinding;
2889 }
Haibo Huang40a71912019-10-11 11:13:39 -07002890 if ((parser->m_tagLevel == 0)
2891 && (parser->m_parsingStatus.parsing != XML_FINISHED)) {
2892 if (parser->m_parsingStatus.parsing == XML_SUSPENDED)
2893 parser->m_processor = epilogProcessor;
2894 else
2895 return epilogProcessor(parser, next, end, nextPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002896 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002897 }
2898 break;
Haibo Huang40a71912019-10-11 11:13:39 -07002899 case XML_TOK_CHAR_REF: {
2900 int n = XmlCharRefNumber(enc, s);
2901 if (n < 0)
2902 return XML_ERROR_BAD_CHAR_REF;
2903 if (parser->m_characterDataHandler) {
2904 XML_Char buf[XML_ENCODE_MAX];
2905 parser->m_characterDataHandler(parser->m_handlerArg, buf,
2906 XmlEncode(n, (ICHAR *)buf));
2907 } else if (parser->m_defaultHandler)
2908 reportDefault(parser, enc, s, next);
2909 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002910 case XML_TOK_XML_DECL:
2911 return XML_ERROR_MISPLACED_XML_PI;
2912 case XML_TOK_DATA_NEWLINE:
Elliott Hughes72472942018-01-10 08:36:10 -08002913 if (parser->m_characterDataHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002914 XML_Char c = 0xA;
Elliott Hughes72472942018-01-10 08:36:10 -08002915 parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
Haibo Huang40a71912019-10-11 11:13:39 -07002916 } else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002917 reportDefault(parser, enc, s, next);
2918 break;
Haibo Huang40a71912019-10-11 11:13:39 -07002919 case XML_TOK_CDATA_SECT_OPEN: {
2920 enum XML_Error result;
2921 if (parser->m_startCdataSectionHandler)
2922 parser->m_startCdataSectionHandler(parser->m_handlerArg);
2923 /* BEGIN disabled code */
2924 /* Suppose you doing a transformation on a document that involves
2925 changing only the character data. You set up a defaultHandler
2926 and a characterDataHandler. The defaultHandler simply copies
2927 characters through. The characterDataHandler does the
2928 transformation and writes the characters out escaping them as
2929 necessary. This case will fail to work if we leave out the
2930 following two lines (because & and < inside CDATA sections will
2931 be incorrectly escaped).
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002932
Haibo Huang40a71912019-10-11 11:13:39 -07002933 However, now we have a start/endCdataSectionHandler, so it seems
2934 easier to let the user deal with this.
2935 */
2936 else if (0 && parser->m_characterDataHandler)
2937 parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf,
2938 0);
2939 /* END disabled code */
2940 else if (parser->m_defaultHandler)
2941 reportDefault(parser, enc, s, next);
2942 result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
2943 if (result != XML_ERROR_NONE)
2944 return result;
2945 else if (! next) {
2946 parser->m_processor = cdataSectionProcessor;
2947 return result;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002948 }
Haibo Huang40a71912019-10-11 11:13:39 -07002949 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002950 case XML_TOK_TRAILING_RSQB:
2951 if (haveMore) {
2952 *nextPtr = s;
2953 return XML_ERROR_NONE;
2954 }
Elliott Hughes72472942018-01-10 08:36:10 -08002955 if (parser->m_characterDataHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002956 if (MUST_CONVERT(enc, s)) {
Elliott Hughes72472942018-01-10 08:36:10 -08002957 ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
2958 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
Haibo Huang40a71912019-10-11 11:13:39 -07002959 parser->m_characterDataHandler(
2960 parser->m_handlerArg, parser->m_dataBuf,
2961 (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
2962 } else
2963 parser->m_characterDataHandler(
2964 parser->m_handlerArg, (XML_Char *)s,
2965 (int)((XML_Char *)end - (XML_Char *)s));
2966 } else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002967 reportDefault(parser, enc, s, end);
Elliott Hughes35e432d2012-09-09 14:23:38 -07002968 /* We are at the end of the final buffer, should we check for
2969 XML_SUSPENDED, XML_FINISHED?
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002970 */
2971 if (startTagLevel == 0) {
2972 *eventPP = end;
2973 return XML_ERROR_NO_ELEMENTS;
2974 }
Elliott Hughes72472942018-01-10 08:36:10 -08002975 if (parser->m_tagLevel != startTagLevel) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002976 *eventPP = end;
2977 return XML_ERROR_ASYNC_ENTITY;
2978 }
2979 *nextPtr = end;
2980 return XML_ERROR_NONE;
Haibo Huang40a71912019-10-11 11:13:39 -07002981 case XML_TOK_DATA_CHARS: {
2982 XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler;
2983 if (charDataHandler) {
2984 if (MUST_CONVERT(enc, s)) {
2985 for (;;) {
2986 ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
2987 const enum XML_Convert_Result convert_res = XmlConvert(
2988 enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
2989 *eventEndPP = s;
2990 charDataHandler(parser->m_handlerArg, parser->m_dataBuf,
2991 (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
2992 if ((convert_res == XML_CONVERT_COMPLETED)
2993 || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
2994 break;
2995 *eventPP = s;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002996 }
Haibo Huang40a71912019-10-11 11:13:39 -07002997 } else
2998 charDataHandler(parser->m_handlerArg, (XML_Char *)s,
2999 (int)((XML_Char *)next - (XML_Char *)s));
3000 } else if (parser->m_defaultHandler)
3001 reportDefault(parser, enc, s, next);
3002 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003003 case XML_TOK_PI:
Haibo Huang40a71912019-10-11 11:13:39 -07003004 if (! reportProcessingInstruction(parser, enc, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003005 return XML_ERROR_NO_MEMORY;
3006 break;
3007 case XML_TOK_COMMENT:
Haibo Huang40a71912019-10-11 11:13:39 -07003008 if (! reportComment(parser, enc, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003009 return XML_ERROR_NO_MEMORY;
3010 break;
3011 default:
Elliott Hughes72472942018-01-10 08:36:10 -08003012 /* All of the tokens produced by XmlContentTok() have their own
3013 * explicit cases, so this default is not strictly necessary.
3014 * However it is a useful safety net, so we retain the code and
3015 * simply exclude it from the coverage tests.
3016 *
3017 * LCOV_EXCL_START
3018 */
3019 if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003020 reportDefault(parser, enc, s, next);
3021 break;
Elliott Hughes72472942018-01-10 08:36:10 -08003022 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003023 }
3024 *eventPP = s = next;
Elliott Hughes72472942018-01-10 08:36:10 -08003025 switch (parser->m_parsingStatus.parsing) {
Elliott Hughes35e432d2012-09-09 14:23:38 -07003026 case XML_SUSPENDED:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003027 *nextPtr = next;
3028 return XML_ERROR_NONE;
3029 case XML_FINISHED:
3030 return XML_ERROR_ABORTED;
Haibo Huang40a71912019-10-11 11:13:39 -07003031 default:;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003032 }
3033 }
3034 /* not reached */
3035}
3036
Elliott Hughes72472942018-01-10 08:36:10 -08003037/* This function does not call free() on the allocated memory, merely
3038 * moving it to the parser's m_freeBindingList where it can be freed or
3039 * reused as appropriate.
3040 */
3041static void
Haibo Huang40a71912019-10-11 11:13:39 -07003042freeBindings(XML_Parser parser, BINDING *bindings) {
Elliott Hughes72472942018-01-10 08:36:10 -08003043 while (bindings) {
3044 BINDING *b = bindings;
3045
3046 /* m_startNamespaceDeclHandler will have been called for this
3047 * binding in addBindings(), so call the end handler now.
3048 */
3049 if (parser->m_endNamespaceDeclHandler)
Haibo Huang40a71912019-10-11 11:13:39 -07003050 parser->m_endNamespaceDeclHandler(parser->m_handlerArg, b->prefix->name);
Elliott Hughes72472942018-01-10 08:36:10 -08003051
3052 bindings = bindings->nextTagBinding;
3053 b->nextTagBinding = parser->m_freeBindingList;
3054 parser->m_freeBindingList = b;
3055 b->prefix->binding = b->prevPrefixBinding;
3056 }
3057}
3058
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003059/* Precondition: all arguments must be non-NULL;
3060 Purpose:
3061 - normalize attributes
3062 - check attributes for well-formedness
3063 - generate namespace aware attribute names (URI, prefix)
3064 - build list of attributes for startElementHandler
3065 - default attributes
3066 - process namespace declarations (check and report them)
3067 - generate namespace aware element name (URI, prefix)
3068*/
3069static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07003070storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
3071 TAG_NAME *tagNamePtr, BINDING **bindingsPtr) {
3072 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003073 ELEMENT_TYPE *elementType;
3074 int nDefaultAtts;
Haibo Huang40a71912019-10-11 11:13:39 -07003075 const XML_Char **appAtts; /* the attribute list for the application */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003076 int attIndex = 0;
3077 int prefixLen;
3078 int i;
3079 int n;
3080 XML_Char *uri;
3081 int nPrefixes = 0;
3082 BINDING *binding;
3083 const XML_Char *localPart;
3084
3085 /* lookup the element type name */
Haibo Huang40a71912019-10-11 11:13:39 -07003086 elementType
3087 = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str, 0);
3088 if (! elementType) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003089 const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
Haibo Huang40a71912019-10-11 11:13:39 -07003090 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003091 return XML_ERROR_NO_MEMORY;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003092 elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003093 sizeof(ELEMENT_TYPE));
Haibo Huang40a71912019-10-11 11:13:39 -07003094 if (! elementType)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003095 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07003096 if (parser->m_ns && ! setElementTypePrefix(parser, elementType))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003097 return XML_ERROR_NO_MEMORY;
3098 }
3099 nDefaultAtts = elementType->nDefaultAtts;
3100
3101 /* get the attributes from the tokenizer */
Elliott Hughes72472942018-01-10 08:36:10 -08003102 n = XmlGetAttributes(enc, attStr, parser->m_attsSize, parser->m_atts);
Sadaf Ebrahimif68f6852022-06-15 04:14:33 +00003103
3104 /* Detect and prevent integer overflow */
3105 if (n > INT_MAX - nDefaultAtts) {
3106 return XML_ERROR_NO_MEMORY;
3107 }
3108
Elliott Hughes72472942018-01-10 08:36:10 -08003109 if (n + nDefaultAtts > parser->m_attsSize) {
3110 int oldAttsSize = parser->m_attsSize;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003111 ATTRIBUTE *temp;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003112#ifdef XML_ATTR_INFO
3113 XML_AttrInfo *temp2;
3114#endif
Sadaf Ebrahimif68f6852022-06-15 04:14:33 +00003115
3116 /* Detect and prevent integer overflow */
3117 if ((nDefaultAtts > INT_MAX - INIT_ATTS_SIZE)
3118 || (n > INT_MAX - (nDefaultAtts + INIT_ATTS_SIZE))) {
3119 return XML_ERROR_NO_MEMORY;
3120 }
3121
Elliott Hughes72472942018-01-10 08:36:10 -08003122 parser->m_attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
Sadaf Ebrahimif68f6852022-06-15 04:14:33 +00003123
3124 /* Detect and prevent integer overflow.
3125 * The preprocessor guard addresses the "always false" warning
3126 * from -Wtype-limits on platforms where
3127 * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
3128#if UINT_MAX >= SIZE_MAX
3129 if ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(ATTRIBUTE)) {
3130 parser->m_attsSize = oldAttsSize;
3131 return XML_ERROR_NO_MEMORY;
3132 }
3133#endif
3134
Haibo Huang40a71912019-10-11 11:13:39 -07003135 temp = (ATTRIBUTE *)REALLOC(parser, (void *)parser->m_atts,
3136 parser->m_attsSize * sizeof(ATTRIBUTE));
Elliott Hughes72472942018-01-10 08:36:10 -08003137 if (temp == NULL) {
3138 parser->m_attsSize = oldAttsSize;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003139 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08003140 }
3141 parser->m_atts = temp;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003142#ifdef XML_ATTR_INFO
Sadaf Ebrahimif68f6852022-06-15 04:14:33 +00003143 /* Detect and prevent integer overflow.
3144 * The preprocessor guard addresses the "always false" warning
3145 * from -Wtype-limits on platforms where
3146 * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
3147# if UINT_MAX >= SIZE_MAX
3148 if ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(XML_AttrInfo)) {
3149 parser->m_attsSize = oldAttsSize;
3150 return XML_ERROR_NO_MEMORY;
3151 }
3152# endif
3153
Haibo Huang40a71912019-10-11 11:13:39 -07003154 temp2 = (XML_AttrInfo *)REALLOC(parser, (void *)parser->m_attInfo,
3155 parser->m_attsSize * sizeof(XML_AttrInfo));
Elliott Hughes72472942018-01-10 08:36:10 -08003156 if (temp2 == NULL) {
3157 parser->m_attsSize = oldAttsSize;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003158 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08003159 }
3160 parser->m_attInfo = temp2;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003161#endif
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003162 if (n > oldAttsSize)
Elliott Hughes72472942018-01-10 08:36:10 -08003163 XmlGetAttributes(enc, attStr, n, parser->m_atts);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003164 }
3165
Elliott Hughes72472942018-01-10 08:36:10 -08003166 appAtts = (const XML_Char **)parser->m_atts;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003167 for (i = 0; i < n; i++) {
Elliott Hughes72472942018-01-10 08:36:10 -08003168 ATTRIBUTE *currAtt = &parser->m_atts[i];
Elliott Hughes35e432d2012-09-09 14:23:38 -07003169#ifdef XML_ATTR_INFO
Elliott Hughes72472942018-01-10 08:36:10 -08003170 XML_AttrInfo *currAttInfo = &parser->m_attInfo[i];
Elliott Hughes35e432d2012-09-09 14:23:38 -07003171#endif
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003172 /* add the name and value to the attribute list */
Haibo Huang40a71912019-10-11 11:13:39 -07003173 ATTRIBUTE_ID *attId
3174 = getAttributeId(parser, enc, currAtt->name,
3175 currAtt->name + XmlNameLength(enc, currAtt->name));
3176 if (! attId)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003177 return XML_ERROR_NO_MEMORY;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003178#ifdef XML_ATTR_INFO
Haibo Huang40a71912019-10-11 11:13:39 -07003179 currAttInfo->nameStart
3180 = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->name);
3181 currAttInfo->nameEnd
3182 = currAttInfo->nameStart + XmlNameLength(enc, currAtt->name);
3183 currAttInfo->valueStart = parser->m_parseEndByteIndex
3184 - (parser->m_parseEndPtr - currAtt->valuePtr);
3185 currAttInfo->valueEnd = parser->m_parseEndByteIndex
3186 - (parser->m_parseEndPtr - currAtt->valueEnd);
Elliott Hughes35e432d2012-09-09 14:23:38 -07003187#endif
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003188 /* Detect duplicate attributes by their QNames. This does not work when
3189 namespace processing is turned on and different prefixes for the same
3190 namespace are used. For this case we have a check further down.
3191 */
3192 if ((attId->name)[-1]) {
Elliott Hughes72472942018-01-10 08:36:10 -08003193 if (enc == parser->m_encoding)
3194 parser->m_eventPtr = parser->m_atts[i].name;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003195 return XML_ERROR_DUPLICATE_ATTRIBUTE;
3196 }
3197 (attId->name)[-1] = 1;
3198 appAtts[attIndex++] = attId->name;
Haibo Huang40a71912019-10-11 11:13:39 -07003199 if (! parser->m_atts[i].normalized) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003200 enum XML_Error result;
3201 XML_Bool isCdata = XML_TRUE;
3202
3203 /* figure out whether declared as other than CDATA */
3204 if (attId->maybeTokenized) {
3205 int j;
3206 for (j = 0; j < nDefaultAtts; j++) {
3207 if (attId == elementType->defaultAtts[j].id) {
3208 isCdata = elementType->defaultAtts[j].isCdata;
3209 break;
3210 }
3211 }
3212 }
3213
3214 /* normalize the attribute value */
Haibo Huang40a71912019-10-11 11:13:39 -07003215 result = storeAttributeValue(
3216 parser, enc, isCdata, parser->m_atts[i].valuePtr,
3217 parser->m_atts[i].valueEnd, &parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003218 if (result)
3219 return result;
Elliott Hughes72472942018-01-10 08:36:10 -08003220 appAtts[attIndex] = poolStart(&parser->m_tempPool);
3221 poolFinish(&parser->m_tempPool);
Haibo Huang40a71912019-10-11 11:13:39 -07003222 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003223 /* the value did not need normalizing */
Haibo Huang40a71912019-10-11 11:13:39 -07003224 appAtts[attIndex] = poolStoreString(&parser->m_tempPool, enc,
3225 parser->m_atts[i].valuePtr,
Elliott Hughes72472942018-01-10 08:36:10 -08003226 parser->m_atts[i].valueEnd);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003227 if (appAtts[attIndex] == 0)
3228 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08003229 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003230 }
3231 /* handle prefixed attribute names */
3232 if (attId->prefix) {
3233 if (attId->xmlns) {
3234 /* deal with namespace declarations here */
3235 enum XML_Error result = addBinding(parser, attId->prefix, attId,
3236 appAtts[attIndex], bindingsPtr);
3237 if (result)
3238 return result;
3239 --attIndex;
Haibo Huang40a71912019-10-11 11:13:39 -07003240 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003241 /* deal with other prefixed names later */
3242 attIndex++;
3243 nPrefixes++;
3244 (attId->name)[-1] = 2;
3245 }
Haibo Huang40a71912019-10-11 11:13:39 -07003246 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003247 attIndex++;
3248 }
3249
3250 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
Elliott Hughes72472942018-01-10 08:36:10 -08003251 parser->m_nSpecifiedAtts = attIndex;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003252 if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
3253 for (i = 0; i < attIndex; i += 2)
3254 if (appAtts[i] == elementType->idAtt->name) {
Elliott Hughes72472942018-01-10 08:36:10 -08003255 parser->m_idAttIndex = i;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003256 break;
3257 }
Haibo Huang40a71912019-10-11 11:13:39 -07003258 } else
Elliott Hughes72472942018-01-10 08:36:10 -08003259 parser->m_idAttIndex = -1;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003260
3261 /* do attribute defaulting */
3262 for (i = 0; i < nDefaultAtts; i++) {
3263 const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
Haibo Huang40a71912019-10-11 11:13:39 -07003264 if (! (da->id->name)[-1] && da->value) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003265 if (da->id->prefix) {
3266 if (da->id->xmlns) {
3267 enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
3268 da->value, bindingsPtr);
3269 if (result)
3270 return result;
Haibo Huang40a71912019-10-11 11:13:39 -07003271 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003272 (da->id->name)[-1] = 2;
3273 nPrefixes++;
3274 appAtts[attIndex++] = da->id->name;
3275 appAtts[attIndex++] = da->value;
3276 }
Haibo Huang40a71912019-10-11 11:13:39 -07003277 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003278 (da->id->name)[-1] = 1;
3279 appAtts[attIndex++] = da->id->name;
3280 appAtts[attIndex++] = da->value;
3281 }
3282 }
3283 }
3284 appAtts[attIndex] = 0;
3285
3286 /* expand prefixed attribute names, check for duplicates,
3287 and clear flags that say whether attributes were specified */
3288 i = 0;
3289 if (nPrefixes) {
Haibo Huang40a71912019-10-11 11:13:39 -07003290 int j; /* hash table index */
Elliott Hughes72472942018-01-10 08:36:10 -08003291 unsigned long version = parser->m_nsAttsVersion;
3292 int nsAttsSize = (int)1 << parser->m_nsAttsPower;
3293 unsigned char oldNsAttsPower = parser->m_nsAttsPower;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003294 /* size of hash table must be at least 2 * (# of prefixed attributes) */
Haibo Huang40a71912019-10-11 11:13:39 -07003295 if ((nPrefixes << 1)
3296 >> parser->m_nsAttsPower) { /* true for m_nsAttsPower = 0 */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003297 NS_ATT *temp;
3298 /* hash table size must also be a power of 2 and >= 8 */
Haibo Huang40a71912019-10-11 11:13:39 -07003299 while (nPrefixes >> parser->m_nsAttsPower++)
3300 ;
Elliott Hughes72472942018-01-10 08:36:10 -08003301 if (parser->m_nsAttsPower < 3)
3302 parser->m_nsAttsPower = 3;
3303 nsAttsSize = (int)1 << parser->m_nsAttsPower;
Haibo Huang40a71912019-10-11 11:13:39 -07003304 temp = (NS_ATT *)REALLOC(parser, parser->m_nsAtts,
3305 nsAttsSize * sizeof(NS_ATT));
3306 if (! temp) {
Elliott Hughes72472942018-01-10 08:36:10 -08003307 /* Restore actual size of memory in m_nsAtts */
3308 parser->m_nsAttsPower = oldNsAttsPower;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003309 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08003310 }
3311 parser->m_nsAtts = temp;
Haibo Huang40a71912019-10-11 11:13:39 -07003312 version = 0; /* force re-initialization of m_nsAtts hash table */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003313 }
Elliott Hughes72472942018-01-10 08:36:10 -08003314 /* using a version flag saves us from initializing m_nsAtts every time */
Haibo Huang40a71912019-10-11 11:13:39 -07003315 if (! version) { /* initialize version flags when version wraps around */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003316 version = INIT_ATTS_VERSION;
Haibo Huang40a71912019-10-11 11:13:39 -07003317 for (j = nsAttsSize; j != 0;)
Elliott Hughes72472942018-01-10 08:36:10 -08003318 parser->m_nsAtts[--j].version = version;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003319 }
Elliott Hughes72472942018-01-10 08:36:10 -08003320 parser->m_nsAttsVersion = --version;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003321
3322 /* expand prefixed names and check for duplicates */
3323 for (; i < attIndex; i += 2) {
3324 const XML_Char *s = appAtts[i];
Haibo Huang40a71912019-10-11 11:13:39 -07003325 if (s[-1] == 2) { /* prefixed */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003326 ATTRIBUTE_ID *id;
3327 const BINDING *b;
Elliott Hughes72472942018-01-10 08:36:10 -08003328 unsigned long uriHash;
3329 struct siphash sip_state;
3330 struct sipkey sip_key;
3331
3332 copy_salt_to_sipkey(parser, &sip_key);
3333 sip24_init(&sip_state, &sip_key);
3334
Haibo Huang40a71912019-10-11 11:13:39 -07003335 ((XML_Char *)s)[-1] = 0; /* clear flag */
Elliott Hughes35e432d2012-09-09 14:23:38 -07003336 id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);
Haibo Huang40a71912019-10-11 11:13:39 -07003337 if (! id || ! id->prefix) {
Elliott Hughes72472942018-01-10 08:36:10 -08003338 /* This code is walking through the appAtts array, dealing
3339 * with (in this case) a prefixed attribute name. To be in
3340 * the array, the attribute must have already been bound, so
3341 * has to have passed through the hash table lookup once
3342 * already. That implies that an entry for it already
3343 * exists, so the lookup above will return a pointer to
3344 * already allocated memory. There is no opportunaity for
3345 * the allocator to fail, so the condition above cannot be
3346 * fulfilled.
3347 *
3348 * Since it is difficult to be certain that the above
3349 * analysis is complete, we retain the test and merely
3350 * remove the code from coverage tests.
3351 */
3352 return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */
3353 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003354 b = id->prefix->binding;
Haibo Huang40a71912019-10-11 11:13:39 -07003355 if (! b)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003356 return XML_ERROR_UNBOUND_PREFIX;
3357
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003358 for (j = 0; j < b->uriLen; j++) {
3359 const XML_Char c = b->uri[j];
Haibo Huang40a71912019-10-11 11:13:39 -07003360 if (! poolAppendChar(&parser->m_tempPool, c))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003361 return XML_ERROR_NO_MEMORY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003362 }
Elliott Hughes72472942018-01-10 08:36:10 -08003363
3364 sip24_update(&sip_state, b->uri, b->uriLen * sizeof(XML_Char));
3365
Elliott Hughesd07d5a72009-09-25 16:04:37 -07003366 while (*s++ != XML_T(ASCII_COLON))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003367 ;
Elliott Hughes72472942018-01-10 08:36:10 -08003368
3369 sip24_update(&sip_state, s, keylen(s) * sizeof(XML_Char));
3370
Haibo Huang40a71912019-10-11 11:13:39 -07003371 do { /* copies null terminator */
3372 if (! poolAppendChar(&parser->m_tempPool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003373 return XML_ERROR_NO_MEMORY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003374 } while (*s++);
3375
Elliott Hughes72472942018-01-10 08:36:10 -08003376 uriHash = (unsigned long)sip24_final(&sip_state);
3377
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003378 { /* Check hash table for duplicate of expanded name (uriName).
Elliott Hughes35e432d2012-09-09 14:23:38 -07003379 Derived from code in lookup(parser, HASH_TABLE *table, ...).
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003380 */
3381 unsigned char step = 0;
3382 unsigned long mask = nsAttsSize - 1;
Haibo Huang40a71912019-10-11 11:13:39 -07003383 j = uriHash & mask; /* index into hash table */
Elliott Hughes72472942018-01-10 08:36:10 -08003384 while (parser->m_nsAtts[j].version == version) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003385 /* for speed we compare stored hash values first */
Elliott Hughes72472942018-01-10 08:36:10 -08003386 if (uriHash == parser->m_nsAtts[j].hash) {
3387 const XML_Char *s1 = poolStart(&parser->m_tempPool);
3388 const XML_Char *s2 = parser->m_nsAtts[j].uriName;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003389 /* s1 is null terminated, but not s2 */
Haibo Huang40a71912019-10-11 11:13:39 -07003390 for (; *s1 == *s2 && *s1 != 0; s1++, s2++)
3391 ;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003392 if (*s1 == 0)
3393 return XML_ERROR_DUPLICATE_ATTRIBUTE;
3394 }
Haibo Huang40a71912019-10-11 11:13:39 -07003395 if (! step)
Elliott Hughes72472942018-01-10 08:36:10 -08003396 step = PROBE_STEP(uriHash, mask, parser->m_nsAttsPower);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003397 j < step ? (j += nsAttsSize - step) : (j -= step);
3398 }
3399 }
3400
Haibo Huang40a71912019-10-11 11:13:39 -07003401 if (parser->m_ns_triplets) { /* append namespace separator and prefix */
Elliott Hughes72472942018-01-10 08:36:10 -08003402 parser->m_tempPool.ptr[-1] = parser->m_namespaceSeparator;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003403 s = b->prefix->name;
3404 do {
Haibo Huang40a71912019-10-11 11:13:39 -07003405 if (! poolAppendChar(&parser->m_tempPool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003406 return XML_ERROR_NO_MEMORY;
3407 } while (*s++);
3408 }
3409
3410 /* store expanded name in attribute list */
Elliott Hughes72472942018-01-10 08:36:10 -08003411 s = poolStart(&parser->m_tempPool);
3412 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003413 appAtts[i] = s;
3414
3415 /* fill empty slot with new version, uriName and hash value */
Elliott Hughes72472942018-01-10 08:36:10 -08003416 parser->m_nsAtts[j].version = version;
3417 parser->m_nsAtts[j].hash = uriHash;
3418 parser->m_nsAtts[j].uriName = s;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003419
Haibo Huang40a71912019-10-11 11:13:39 -07003420 if (! --nPrefixes) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003421 i += 2;
3422 break;
3423 }
Haibo Huang40a71912019-10-11 11:13:39 -07003424 } else /* not prefixed */
3425 ((XML_Char *)s)[-1] = 0; /* clear flag */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003426 }
3427 }
3428 /* clear flags for the remaining attributes */
3429 for (; i < attIndex; i += 2)
3430 ((XML_Char *)(appAtts[i]))[-1] = 0;
3431 for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
3432 binding->attId->name[-1] = 0;
3433
Haibo Huang40a71912019-10-11 11:13:39 -07003434 if (! parser->m_ns)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003435 return XML_ERROR_NONE;
3436
3437 /* expand the element type name */
3438 if (elementType->prefix) {
3439 binding = elementType->prefix->binding;
Haibo Huang40a71912019-10-11 11:13:39 -07003440 if (! binding)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003441 return XML_ERROR_UNBOUND_PREFIX;
3442 localPart = tagNamePtr->str;
Elliott Hughesd07d5a72009-09-25 16:04:37 -07003443 while (*localPart++ != XML_T(ASCII_COLON))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003444 ;
Haibo Huang40a71912019-10-11 11:13:39 -07003445 } else if (dtd->defaultPrefix.binding) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003446 binding = dtd->defaultPrefix.binding;
3447 localPart = tagNamePtr->str;
Haibo Huang40a71912019-10-11 11:13:39 -07003448 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003449 return XML_ERROR_NONE;
3450 prefixLen = 0;
Elliott Hughes72472942018-01-10 08:36:10 -08003451 if (parser->m_ns_triplets && binding->prefix->name) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003452 for (; binding->prefix->name[prefixLen++];)
Haibo Huang40a71912019-10-11 11:13:39 -07003453 ; /* prefixLen includes null terminator */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003454 }
3455 tagNamePtr->localPart = localPart;
3456 tagNamePtr->uriLen = binding->uriLen;
3457 tagNamePtr->prefix = binding->prefix->name;
3458 tagNamePtr->prefixLen = prefixLen;
3459 for (i = 0; localPart[i++];)
Haibo Huang40a71912019-10-11 11:13:39 -07003460 ; /* i includes null terminator */
Sadaf Ebrahimif68f6852022-06-15 04:14:33 +00003461
3462 /* Detect and prevent integer overflow */
3463 if (binding->uriLen > INT_MAX - prefixLen
3464 || i > INT_MAX - (binding->uriLen + prefixLen)) {
3465 return XML_ERROR_NO_MEMORY;
3466 }
3467
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003468 n = i + binding->uriLen + prefixLen;
3469 if (n > binding->uriAlloc) {
3470 TAG *p;
Sadaf Ebrahimif68f6852022-06-15 04:14:33 +00003471
3472 /* Detect and prevent integer overflow */
3473 if (n > INT_MAX - EXPAND_SPARE) {
3474 return XML_ERROR_NO_MEMORY;
3475 }
3476 /* Detect and prevent integer overflow.
3477 * The preprocessor guard addresses the "always false" warning
3478 * from -Wtype-limits on platforms where
3479 * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
3480#if UINT_MAX >= SIZE_MAX
3481 if ((unsigned)(n + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) {
3482 return XML_ERROR_NO_MEMORY;
3483 }
3484#endif
3485
Elliott Hughes72472942018-01-10 08:36:10 -08003486 uri = (XML_Char *)MALLOC(parser, (n + EXPAND_SPARE) * sizeof(XML_Char));
Haibo Huang40a71912019-10-11 11:13:39 -07003487 if (! uri)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003488 return XML_ERROR_NO_MEMORY;
3489 binding->uriAlloc = n + EXPAND_SPARE;
3490 memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
Elliott Hughes72472942018-01-10 08:36:10 -08003491 for (p = parser->m_tagStack; p; p = p->parent)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003492 if (p->name.str == binding->uri)
3493 p->name.str = uri;
Elliott Hughes72472942018-01-10 08:36:10 -08003494 FREE(parser, binding->uri);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003495 binding->uri = uri;
3496 }
Elliott Hughes72472942018-01-10 08:36:10 -08003497 /* if m_namespaceSeparator != '\0' then uri includes it already */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003498 uri = binding->uri + binding->uriLen;
3499 memcpy(uri, localPart, i * sizeof(XML_Char));
3500 /* we always have a namespace separator between localPart and prefix */
3501 if (prefixLen) {
3502 uri += i - 1;
Haibo Huang40a71912019-10-11 11:13:39 -07003503 *uri = parser->m_namespaceSeparator; /* replace null terminator */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003504 memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
3505 }
3506 tagNamePtr->str = binding->uri;
3507 return XML_ERROR_NONE;
3508}
3509
3510/* addBinding() overwrites the value of prefix->binding without checking.
3511 Therefore one must keep track of the old value outside of addBinding().
3512*/
3513static enum XML_Error
3514addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
Haibo Huang40a71912019-10-11 11:13:39 -07003515 const XML_Char *uri, BINDING **bindingsPtr) {
3516 static const XML_Char xmlNamespace[]
3517 = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON,
3518 ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w,
3519 ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o,
3520 ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M,
3521 ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9,
3522 ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m,
3523 ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c,
3524 ASCII_e, '\0'};
3525 static const int xmlLen = (int)sizeof(xmlNamespace) / sizeof(XML_Char) - 1;
3526 static const XML_Char xmlnsNamespace[]
3527 = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH,
3528 ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w,
3529 ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH,
3530 ASCII_2, ASCII_0, ASCII_0, ASCII_0, ASCII_SLASH, ASCII_x,
3531 ASCII_m, ASCII_l, ASCII_n, ASCII_s, ASCII_SLASH, '\0'};
3532 static const int xmlnsLen
3533 = (int)sizeof(xmlnsNamespace) / sizeof(XML_Char) - 1;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003534
3535 XML_Bool mustBeXML = XML_FALSE;
3536 XML_Bool isXML = XML_TRUE;
3537 XML_Bool isXMLNS = XML_TRUE;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003538
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003539 BINDING *b;
3540 int len;
3541
3542 /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
3543 if (*uri == XML_T('\0') && prefix->name)
3544 return XML_ERROR_UNDECLARING_PREFIX;
3545
Haibo Huang40a71912019-10-11 11:13:39 -07003546 if (prefix->name && prefix->name[0] == XML_T(ASCII_x)
Elliott Hughesd07d5a72009-09-25 16:04:37 -07003547 && prefix->name[1] == XML_T(ASCII_m)
3548 && prefix->name[2] == XML_T(ASCII_l)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003549 /* Not allowed to bind xmlns */
Haibo Huang40a71912019-10-11 11:13:39 -07003550 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 -08003551 && prefix->name[5] == XML_T('\0'))
3552 return XML_ERROR_RESERVED_PREFIX_XMLNS;
3553
3554 if (prefix->name[3] == XML_T('\0'))
3555 mustBeXML = XML_TRUE;
3556 }
3557
3558 for (len = 0; uri[len]; len++) {
3559 if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
3560 isXML = XML_FALSE;
3561
Haibo Huang40a71912019-10-11 11:13:39 -07003562 if (! mustBeXML && isXMLNS
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003563 && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
3564 isXMLNS = XML_FALSE;
3565 }
3566 isXML = isXML && len == xmlLen;
3567 isXMLNS = isXMLNS && len == xmlnsLen;
3568
3569 if (mustBeXML != isXML)
3570 return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
3571 : XML_ERROR_RESERVED_NAMESPACE_URI;
3572
3573 if (isXMLNS)
3574 return XML_ERROR_RESERVED_NAMESPACE_URI;
3575
Elliott Hughes72472942018-01-10 08:36:10 -08003576 if (parser->m_namespaceSeparator)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003577 len++;
Elliott Hughes72472942018-01-10 08:36:10 -08003578 if (parser->m_freeBindingList) {
3579 b = parser->m_freeBindingList;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003580 if (len > b->uriAlloc) {
Sadaf Ebrahimif68f6852022-06-15 04:14:33 +00003581 /* Detect and prevent integer overflow */
3582 if (len > INT_MAX - EXPAND_SPARE) {
3583 return XML_ERROR_NO_MEMORY;
3584 }
3585
3586 /* Detect and prevent integer overflow.
3587 * The preprocessor guard addresses the "always false" warning
3588 * from -Wtype-limits on platforms where
3589 * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
3590#if UINT_MAX >= SIZE_MAX
3591 if ((unsigned)(len + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) {
3592 return XML_ERROR_NO_MEMORY;
3593 }
3594#endif
3595
Haibo Huang40a71912019-10-11 11:13:39 -07003596 XML_Char *temp = (XML_Char *)REALLOC(
3597 parser, b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003598 if (temp == NULL)
3599 return XML_ERROR_NO_MEMORY;
3600 b->uri = temp;
3601 b->uriAlloc = len + EXPAND_SPARE;
3602 }
Elliott Hughes72472942018-01-10 08:36:10 -08003603 parser->m_freeBindingList = b->nextTagBinding;
Haibo Huang40a71912019-10-11 11:13:39 -07003604 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08003605 b = (BINDING *)MALLOC(parser, sizeof(BINDING));
Haibo Huang40a71912019-10-11 11:13:39 -07003606 if (! b)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003607 return XML_ERROR_NO_MEMORY;
Sadaf Ebrahimif68f6852022-06-15 04:14:33 +00003608
3609 /* Detect and prevent integer overflow */
3610 if (len > INT_MAX - EXPAND_SPARE) {
3611 return XML_ERROR_NO_MEMORY;
3612 }
3613 /* Detect and prevent integer overflow.
3614 * The preprocessor guard addresses the "always false" warning
3615 * from -Wtype-limits on platforms where
3616 * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
3617#if UINT_MAX >= SIZE_MAX
3618 if ((unsigned)(len + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) {
3619 return XML_ERROR_NO_MEMORY;
3620 }
3621#endif
3622
Haibo Huang40a71912019-10-11 11:13:39 -07003623 b->uri
3624 = (XML_Char *)MALLOC(parser, sizeof(XML_Char) * (len + EXPAND_SPARE));
3625 if (! b->uri) {
Elliott Hughes72472942018-01-10 08:36:10 -08003626 FREE(parser, b);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003627 return XML_ERROR_NO_MEMORY;
3628 }
3629 b->uriAlloc = len + EXPAND_SPARE;
3630 }
3631 b->uriLen = len;
3632 memcpy(b->uri, uri, len * sizeof(XML_Char));
Elliott Hughes72472942018-01-10 08:36:10 -08003633 if (parser->m_namespaceSeparator)
3634 b->uri[len - 1] = parser->m_namespaceSeparator;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003635 b->prefix = prefix;
3636 b->attId = attId;
3637 b->prevPrefixBinding = prefix->binding;
3638 /* NULL binding when default namespace undeclared */
Elliott Hughes72472942018-01-10 08:36:10 -08003639 if (*uri == XML_T('\0') && prefix == &parser->m_dtd->defaultPrefix)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003640 prefix->binding = NULL;
3641 else
3642 prefix->binding = b;
3643 b->nextTagBinding = *bindingsPtr;
3644 *bindingsPtr = b;
3645 /* if attId == NULL then we are not starting a namespace scope */
Elliott Hughes72472942018-01-10 08:36:10 -08003646 if (attId && parser->m_startNamespaceDeclHandler)
3647 parser->m_startNamespaceDeclHandler(parser->m_handlerArg, prefix->name,
Haibo Huang40a71912019-10-11 11:13:39 -07003648 prefix->binding ? uri : 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003649 return XML_ERROR_NONE;
3650}
3651
3652/* The idea here is to avoid using stack for each CDATA section when
3653 the whole file is parsed with one call.
3654*/
3655static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07003656cdataSectionProcessor(XML_Parser parser, const char *start, const char *end,
3657 const char **endPtr) {
3658 enum XML_Error result
3659 = doCdataSection(parser, parser->m_encoding, &start, end, endPtr,
3660 (XML_Bool)! parser->m_parsingStatus.finalBuffer);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003661 if (result != XML_ERROR_NONE)
3662 return result;
3663 if (start) {
Haibo Huang40a71912019-10-11 11:13:39 -07003664 if (parser->m_parentParser) { /* we are parsing an external entity */
Elliott Hughes72472942018-01-10 08:36:10 -08003665 parser->m_processor = externalEntityContentProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003666 return externalEntityContentProcessor(parser, start, end, endPtr);
Haibo Huang40a71912019-10-11 11:13:39 -07003667 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08003668 parser->m_processor = contentProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003669 return contentProcessor(parser, start, end, endPtr);
3670 }
3671 }
3672 return result;
3673}
3674
3675/* startPtr gets set to non-null if the section is closed, and to null if
3676 the section is not yet closed.
3677*/
3678static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07003679doCdataSection(XML_Parser parser, const ENCODING *enc, const char **startPtr,
3680 const char *end, const char **nextPtr, XML_Bool haveMore) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003681 const char *s = *startPtr;
3682 const char **eventPP;
3683 const char **eventEndPP;
Elliott Hughes72472942018-01-10 08:36:10 -08003684 if (enc == parser->m_encoding) {
3685 eventPP = &parser->m_eventPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003686 *eventPP = s;
Elliott Hughes72472942018-01-10 08:36:10 -08003687 eventEndPP = &parser->m_eventEndPtr;
Haibo Huang40a71912019-10-11 11:13:39 -07003688 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08003689 eventPP = &(parser->m_openInternalEntities->internalEventPtr);
3690 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003691 }
3692 *eventPP = s;
3693 *startPtr = NULL;
3694
3695 for (;;) {
Haibo Huangd1a324a2020-10-28 22:19:36 -07003696 const char *next = s; /* in case of XML_TOK_NONE or XML_TOK_PARTIAL */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003697 int tok = XmlCdataSectionTok(enc, s, end, &next);
3698 *eventEndPP = next;
3699 switch (tok) {
3700 case XML_TOK_CDATA_SECT_CLOSE:
Elliott Hughes72472942018-01-10 08:36:10 -08003701 if (parser->m_endCdataSectionHandler)
3702 parser->m_endCdataSectionHandler(parser->m_handlerArg);
Haibo Huang40a71912019-10-11 11:13:39 -07003703 /* BEGIN disabled code */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003704 /* see comment under XML_TOK_CDATA_SECT_OPEN */
Haibo Huangfd5e81a2019-06-20 12:09:36 -07003705 else if (0 && parser->m_characterDataHandler)
Haibo Huang40a71912019-10-11 11:13:39 -07003706 parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf,
3707 0);
3708 /* END disabled code */
Elliott Hughes72472942018-01-10 08:36:10 -08003709 else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003710 reportDefault(parser, enc, s, next);
3711 *startPtr = next;
3712 *nextPtr = next;
Elliott Hughes72472942018-01-10 08:36:10 -08003713 if (parser->m_parsingStatus.parsing == XML_FINISHED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003714 return XML_ERROR_ABORTED;
3715 else
3716 return XML_ERROR_NONE;
3717 case XML_TOK_DATA_NEWLINE:
Elliott Hughes72472942018-01-10 08:36:10 -08003718 if (parser->m_characterDataHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003719 XML_Char c = 0xA;
Elliott Hughes72472942018-01-10 08:36:10 -08003720 parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
Haibo Huang40a71912019-10-11 11:13:39 -07003721 } else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003722 reportDefault(parser, enc, s, next);
3723 break;
Haibo Huang40a71912019-10-11 11:13:39 -07003724 case XML_TOK_DATA_CHARS: {
3725 XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler;
3726 if (charDataHandler) {
3727 if (MUST_CONVERT(enc, s)) {
3728 for (;;) {
3729 ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
3730 const enum XML_Convert_Result convert_res = XmlConvert(
3731 enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
3732 *eventEndPP = next;
3733 charDataHandler(parser->m_handlerArg, parser->m_dataBuf,
3734 (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
3735 if ((convert_res == XML_CONVERT_COMPLETED)
3736 || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
3737 break;
3738 *eventPP = s;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003739 }
Haibo Huang40a71912019-10-11 11:13:39 -07003740 } else
3741 charDataHandler(parser->m_handlerArg, (XML_Char *)s,
3742 (int)((XML_Char *)next - (XML_Char *)s));
3743 } else if (parser->m_defaultHandler)
3744 reportDefault(parser, enc, s, next);
3745 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003746 case XML_TOK_INVALID:
3747 *eventPP = next;
3748 return XML_ERROR_INVALID_TOKEN;
3749 case XML_TOK_PARTIAL_CHAR:
3750 if (haveMore) {
3751 *nextPtr = s;
3752 return XML_ERROR_NONE;
3753 }
3754 return XML_ERROR_PARTIAL_CHAR;
3755 case XML_TOK_PARTIAL:
3756 case XML_TOK_NONE:
3757 if (haveMore) {
3758 *nextPtr = s;
3759 return XML_ERROR_NONE;
3760 }
3761 return XML_ERROR_UNCLOSED_CDATA_SECTION;
3762 default:
Elliott Hughes72472942018-01-10 08:36:10 -08003763 /* Every token returned by XmlCdataSectionTok() has its own
3764 * explicit case, so this default case will never be executed.
3765 * We retain it as a safety net and exclude it from the coverage
3766 * statistics.
3767 *
3768 * LCOV_EXCL_START
Haibo Huang40a71912019-10-11 11:13:39 -07003769 */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003770 *eventPP = next;
3771 return XML_ERROR_UNEXPECTED_STATE;
Elliott Hughes72472942018-01-10 08:36:10 -08003772 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003773 }
3774
3775 *eventPP = s = next;
Elliott Hughes72472942018-01-10 08:36:10 -08003776 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003777 case XML_SUSPENDED:
3778 *nextPtr = next;
3779 return XML_ERROR_NONE;
3780 case XML_FINISHED:
3781 return XML_ERROR_ABORTED;
Haibo Huang40a71912019-10-11 11:13:39 -07003782 default:;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003783 }
3784 }
3785 /* not reached */
3786}
3787
3788#ifdef XML_DTD
3789
3790/* The idea here is to avoid using stack for each IGNORE section when
3791 the whole file is parsed with one call.
3792*/
3793static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07003794ignoreSectionProcessor(XML_Parser parser, const char *start, const char *end,
3795 const char **endPtr) {
3796 enum XML_Error result
3797 = doIgnoreSection(parser, parser->m_encoding, &start, end, endPtr,
3798 (XML_Bool)! parser->m_parsingStatus.finalBuffer);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003799 if (result != XML_ERROR_NONE)
3800 return result;
3801 if (start) {
Elliott Hughes72472942018-01-10 08:36:10 -08003802 parser->m_processor = prologProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003803 return prologProcessor(parser, start, end, endPtr);
3804 }
3805 return result;
3806}
3807
3808/* startPtr gets set to non-null is the section is closed, and to null
3809 if the section is not yet closed.
3810*/
3811static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07003812doIgnoreSection(XML_Parser parser, const ENCODING *enc, const char **startPtr,
3813 const char *end, const char **nextPtr, XML_Bool haveMore) {
Haibo Huangd1a324a2020-10-28 22:19:36 -07003814 const char *next = *startPtr; /* in case of XML_TOK_NONE or XML_TOK_PARTIAL */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003815 int tok;
3816 const char *s = *startPtr;
3817 const char **eventPP;
3818 const char **eventEndPP;
Elliott Hughes72472942018-01-10 08:36:10 -08003819 if (enc == parser->m_encoding) {
3820 eventPP = &parser->m_eventPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003821 *eventPP = s;
Elliott Hughes72472942018-01-10 08:36:10 -08003822 eventEndPP = &parser->m_eventEndPtr;
Haibo Huang40a71912019-10-11 11:13:39 -07003823 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08003824 /* It's not entirely clear, but it seems the following two lines
3825 * of code cannot be executed. The only occasions on which 'enc'
3826 * is not 'encoding' are when this function is called
3827 * from the internal entity processing, and IGNORE sections are an
3828 * error in internal entities.
3829 *
3830 * Since it really isn't clear that this is true, we keep the code
3831 * and just remove it from our coverage tests.
3832 *
3833 * LCOV_EXCL_START
3834 */
3835 eventPP = &(parser->m_openInternalEntities->internalEventPtr);
3836 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
3837 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003838 }
3839 *eventPP = s;
3840 *startPtr = NULL;
3841 tok = XmlIgnoreSectionTok(enc, s, end, &next);
3842 *eventEndPP = next;
3843 switch (tok) {
3844 case XML_TOK_IGNORE_SECT:
Elliott Hughes72472942018-01-10 08:36:10 -08003845 if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003846 reportDefault(parser, enc, s, next);
3847 *startPtr = next;
3848 *nextPtr = next;
Elliott Hughes72472942018-01-10 08:36:10 -08003849 if (parser->m_parsingStatus.parsing == XML_FINISHED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003850 return XML_ERROR_ABORTED;
3851 else
3852 return XML_ERROR_NONE;
3853 case XML_TOK_INVALID:
3854 *eventPP = next;
3855 return XML_ERROR_INVALID_TOKEN;
3856 case XML_TOK_PARTIAL_CHAR:
3857 if (haveMore) {
3858 *nextPtr = s;
3859 return XML_ERROR_NONE;
3860 }
3861 return XML_ERROR_PARTIAL_CHAR;
3862 case XML_TOK_PARTIAL:
3863 case XML_TOK_NONE:
3864 if (haveMore) {
3865 *nextPtr = s;
3866 return XML_ERROR_NONE;
3867 }
3868 return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
3869 default:
Elliott Hughes72472942018-01-10 08:36:10 -08003870 /* All of the tokens that XmlIgnoreSectionTok() returns have
3871 * explicit cases to handle them, so this default case is never
3872 * executed. We keep it as a safety net anyway, and remove it
3873 * from our test coverage statistics.
3874 *
3875 * LCOV_EXCL_START
3876 */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003877 *eventPP = next;
3878 return XML_ERROR_UNEXPECTED_STATE;
Elliott Hughes72472942018-01-10 08:36:10 -08003879 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003880 }
3881 /* not reached */
3882}
3883
3884#endif /* XML_DTD */
3885
3886static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07003887initializeEncoding(XML_Parser parser) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003888 const char *s;
3889#ifdef XML_UNICODE
3890 char encodingBuf[128];
Elliott Hughes72472942018-01-10 08:36:10 -08003891 /* See comments abount `protoclEncodingName` in parserInit() */
Haibo Huang40a71912019-10-11 11:13:39 -07003892 if (! parser->m_protocolEncodingName)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003893 s = NULL;
3894 else {
3895 int i;
Elliott Hughes72472942018-01-10 08:36:10 -08003896 for (i = 0; parser->m_protocolEncodingName[i]; i++) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003897 if (i == sizeof(encodingBuf) - 1
Elliott Hughes72472942018-01-10 08:36:10 -08003898 || (parser->m_protocolEncodingName[i] & ~0x7f) != 0) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003899 encodingBuf[0] = '\0';
3900 break;
3901 }
Elliott Hughes72472942018-01-10 08:36:10 -08003902 encodingBuf[i] = (char)parser->m_protocolEncodingName[i];
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003903 }
3904 encodingBuf[i] = '\0';
3905 s = encodingBuf;
3906 }
3907#else
Elliott Hughes72472942018-01-10 08:36:10 -08003908 s = parser->m_protocolEncodingName;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003909#endif
Haibo Huang40a71912019-10-11 11:13:39 -07003910 if ((parser->m_ns ? XmlInitEncodingNS : XmlInitEncoding)(
3911 &parser->m_initEncoding, &parser->m_encoding, s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003912 return XML_ERROR_NONE;
Elliott Hughes72472942018-01-10 08:36:10 -08003913 return handleUnknownEncoding(parser, parser->m_protocolEncodingName);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003914}
3915
3916static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07003917processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *s,
3918 const char *next) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003919 const char *encodingName = NULL;
3920 const XML_Char *storedEncName = NULL;
3921 const ENCODING *newEncoding = NULL;
3922 const char *version = NULL;
3923 const char *versionend;
3924 const XML_Char *storedversion = NULL;
3925 int standalone = -1;
Haibo Huang40a71912019-10-11 11:13:39 -07003926 if (! (parser->m_ns ? XmlParseXmlDeclNS : XmlParseXmlDecl)(
3927 isGeneralTextEntity, parser->m_encoding, s, next, &parser->m_eventPtr,
3928 &version, &versionend, &encodingName, &newEncoding, &standalone)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003929 if (isGeneralTextEntity)
3930 return XML_ERROR_TEXT_DECL;
3931 else
3932 return XML_ERROR_XML_DECL;
3933 }
Haibo Huang40a71912019-10-11 11:13:39 -07003934 if (! isGeneralTextEntity && standalone == 1) {
Elliott Hughes72472942018-01-10 08:36:10 -08003935 parser->m_dtd->standalone = XML_TRUE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003936#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07003937 if (parser->m_paramEntityParsing
3938 == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
Elliott Hughes72472942018-01-10 08:36:10 -08003939 parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003940#endif /* XML_DTD */
3941 }
Elliott Hughes72472942018-01-10 08:36:10 -08003942 if (parser->m_xmlDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003943 if (encodingName != NULL) {
Haibo Huang40a71912019-10-11 11:13:39 -07003944 storedEncName = poolStoreString(
3945 &parser->m_temp2Pool, parser->m_encoding, encodingName,
3946 encodingName + XmlNameLength(parser->m_encoding, encodingName));
3947 if (! storedEncName)
3948 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08003949 poolFinish(&parser->m_temp2Pool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003950 }
3951 if (version) {
Haibo Huang40a71912019-10-11 11:13:39 -07003952 storedversion
3953 = poolStoreString(&parser->m_temp2Pool, parser->m_encoding, version,
3954 versionend - parser->m_encoding->minBytesPerChar);
3955 if (! storedversion)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003956 return XML_ERROR_NO_MEMORY;
3957 }
Haibo Huang40a71912019-10-11 11:13:39 -07003958 parser->m_xmlDeclHandler(parser->m_handlerArg, storedversion, storedEncName,
3959 standalone);
3960 } else if (parser->m_defaultHandler)
Elliott Hughes72472942018-01-10 08:36:10 -08003961 reportDefault(parser, parser->m_encoding, s, next);
3962 if (parser->m_protocolEncodingName == NULL) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003963 if (newEncoding) {
Elliott Hughes72472942018-01-10 08:36:10 -08003964 /* Check that the specified encoding does not conflict with what
3965 * the parser has already deduced. Do we have the same number
3966 * of bytes in the smallest representation of a character? If
3967 * this is UTF-16, is it the same endianness?
3968 */
3969 if (newEncoding->minBytesPerChar != parser->m_encoding->minBytesPerChar
Haibo Huang40a71912019-10-11 11:13:39 -07003970 || (newEncoding->minBytesPerChar == 2
3971 && newEncoding != parser->m_encoding)) {
Elliott Hughes72472942018-01-10 08:36:10 -08003972 parser->m_eventPtr = encodingName;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003973 return XML_ERROR_INCORRECT_ENCODING;
3974 }
Elliott Hughes72472942018-01-10 08:36:10 -08003975 parser->m_encoding = newEncoding;
Haibo Huang40a71912019-10-11 11:13:39 -07003976 } else if (encodingName) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003977 enum XML_Error result;
Haibo Huang40a71912019-10-11 11:13:39 -07003978 if (! storedEncName) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003979 storedEncName = poolStoreString(
Haibo Huang40a71912019-10-11 11:13:39 -07003980 &parser->m_temp2Pool, parser->m_encoding, encodingName,
3981 encodingName + XmlNameLength(parser->m_encoding, encodingName));
3982 if (! storedEncName)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003983 return XML_ERROR_NO_MEMORY;
3984 }
3985 result = handleUnknownEncoding(parser, storedEncName);
Elliott Hughes72472942018-01-10 08:36:10 -08003986 poolClear(&parser->m_temp2Pool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003987 if (result == XML_ERROR_UNKNOWN_ENCODING)
Elliott Hughes72472942018-01-10 08:36:10 -08003988 parser->m_eventPtr = encodingName;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003989 return result;
3990 }
3991 }
3992
3993 if (storedEncName || storedversion)
Elliott Hughes72472942018-01-10 08:36:10 -08003994 poolClear(&parser->m_temp2Pool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003995
3996 return XML_ERROR_NONE;
3997}
3998
3999static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07004000handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) {
Elliott Hughes72472942018-01-10 08:36:10 -08004001 if (parser->m_unknownEncodingHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004002 XML_Encoding info;
4003 int i;
4004 for (i = 0; i < 256; i++)
4005 info.map[i] = -1;
4006 info.convert = NULL;
4007 info.data = NULL;
4008 info.release = NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07004009 if (parser->m_unknownEncodingHandler(parser->m_unknownEncodingHandlerData,
4010 encodingName, &info)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004011 ENCODING *enc;
Elliott Hughes72472942018-01-10 08:36:10 -08004012 parser->m_unknownEncodingMem = MALLOC(parser, XmlSizeOfUnknownEncoding());
Haibo Huang40a71912019-10-11 11:13:39 -07004013 if (! parser->m_unknownEncodingMem) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004014 if (info.release)
4015 info.release(info.data);
4016 return XML_ERROR_NO_MEMORY;
4017 }
Haibo Huang40a71912019-10-11 11:13:39 -07004018 enc = (parser->m_ns ? XmlInitUnknownEncodingNS : XmlInitUnknownEncoding)(
4019 parser->m_unknownEncodingMem, info.map, info.convert, info.data);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004020 if (enc) {
Elliott Hughes72472942018-01-10 08:36:10 -08004021 parser->m_unknownEncodingData = info.data;
4022 parser->m_unknownEncodingRelease = info.release;
4023 parser->m_encoding = enc;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004024 return XML_ERROR_NONE;
4025 }
4026 }
4027 if (info.release != NULL)
4028 info.release(info.data);
4029 }
4030 return XML_ERROR_UNKNOWN_ENCODING;
4031}
4032
4033static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07004034prologInitProcessor(XML_Parser parser, const char *s, const char *end,
4035 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004036 enum XML_Error result = initializeEncoding(parser);
4037 if (result != XML_ERROR_NONE)
4038 return result;
Elliott Hughes72472942018-01-10 08:36:10 -08004039 parser->m_processor = prologProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004040 return prologProcessor(parser, s, end, nextPtr);
4041}
4042
4043#ifdef XML_DTD
4044
4045static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07004046externalParEntInitProcessor(XML_Parser parser, const char *s, const char *end,
4047 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004048 enum XML_Error result = initializeEncoding(parser);
4049 if (result != XML_ERROR_NONE)
4050 return result;
4051
4052 /* we know now that XML_Parse(Buffer) has been called,
4053 so we consider the external parameter entity read */
Elliott Hughes72472942018-01-10 08:36:10 -08004054 parser->m_dtd->paramEntityRead = XML_TRUE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004055
Elliott Hughes72472942018-01-10 08:36:10 -08004056 if (parser->m_prologState.inEntityValue) {
4057 parser->m_processor = entityValueInitProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004058 return entityValueInitProcessor(parser, s, end, nextPtr);
Haibo Huang40a71912019-10-11 11:13:39 -07004059 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08004060 parser->m_processor = externalParEntProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004061 return externalParEntProcessor(parser, s, end, nextPtr);
4062 }
4063}
4064
4065static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07004066entityValueInitProcessor(XML_Parser parser, const char *s, const char *end,
4067 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004068 int tok;
4069 const char *start = s;
4070 const char *next = start;
Elliott Hughes72472942018-01-10 08:36:10 -08004071 parser->m_eventPtr = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004072
Elliott Hughes35e432d2012-09-09 14:23:38 -07004073 for (;;) {
Elliott Hughes72472942018-01-10 08:36:10 -08004074 tok = XmlPrologTok(parser->m_encoding, start, end, &next);
4075 parser->m_eventEndPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004076 if (tok <= 0) {
Haibo Huang40a71912019-10-11 11:13:39 -07004077 if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004078 *nextPtr = s;
4079 return XML_ERROR_NONE;
4080 }
4081 switch (tok) {
4082 case XML_TOK_INVALID:
4083 return XML_ERROR_INVALID_TOKEN;
4084 case XML_TOK_PARTIAL:
4085 return XML_ERROR_UNCLOSED_TOKEN;
4086 case XML_TOK_PARTIAL_CHAR:
4087 return XML_ERROR_PARTIAL_CHAR;
Haibo Huang40a71912019-10-11 11:13:39 -07004088 case XML_TOK_NONE: /* start == end */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004089 default:
4090 break;
4091 }
4092 /* found end of entity value - can store it now */
Elliott Hughes72472942018-01-10 08:36:10 -08004093 return storeEntityValue(parser, parser->m_encoding, s, end);
Haibo Huang40a71912019-10-11 11:13:39 -07004094 } else if (tok == XML_TOK_XML_DECL) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004095 enum XML_Error result;
4096 result = processXmlDecl(parser, 0, start, next);
4097 if (result != XML_ERROR_NONE)
4098 return result;
Haibo Huang40a71912019-10-11 11:13:39 -07004099 /* At this point, m_parsingStatus.parsing cannot be XML_SUSPENDED. For
4100 * that to happen, a parameter entity parsing handler must have attempted
4101 * to suspend the parser, which fails and raises an error. The parser can
4102 * be aborted, but can't be suspended.
Elliott Hughes72472942018-01-10 08:36:10 -08004103 */
4104 if (parser->m_parsingStatus.parsing == XML_FINISHED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004105 return XML_ERROR_ABORTED;
Elliott Hughes72472942018-01-10 08:36:10 -08004106 *nextPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004107 /* stop scanning for text declaration - we found one */
Elliott Hughes72472942018-01-10 08:36:10 -08004108 parser->m_processor = entityValueProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004109 return entityValueProcessor(parser, next, end, nextPtr);
4110 }
4111 /* If we are at the end of the buffer, this would cause XmlPrologTok to
4112 return XML_TOK_NONE on the next call, which would then cause the
4113 function to exit with *nextPtr set to s - that is what we want for other
4114 tokens, but not for the BOM - we would rather like to skip it;
4115 then, when this routine is entered the next time, XmlPrologTok will
4116 return XML_TOK_INVALID, since the BOM is still in the buffer
4117 */
Haibo Huang40a71912019-10-11 11:13:39 -07004118 else if (tok == XML_TOK_BOM && next == end
4119 && ! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004120 *nextPtr = next;
4121 return XML_ERROR_NONE;
4122 }
Elliott Hughes72472942018-01-10 08:36:10 -08004123 /* If we get this token, we have the start of what might be a
4124 normal tag, but not a declaration (i.e. it doesn't begin with
4125 "<!"). In a DTD context, that isn't legal.
4126 */
4127 else if (tok == XML_TOK_INSTANCE_START) {
4128 *nextPtr = next;
4129 return XML_ERROR_SYNTAX;
4130 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004131 start = next;
Elliott Hughes72472942018-01-10 08:36:10 -08004132 parser->m_eventPtr = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004133 }
4134}
4135
4136static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07004137externalParEntProcessor(XML_Parser parser, const char *s, const char *end,
4138 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004139 const char *next = s;
4140 int tok;
4141
Elliott Hughes72472942018-01-10 08:36:10 -08004142 tok = XmlPrologTok(parser->m_encoding, s, end, &next);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004143 if (tok <= 0) {
Haibo Huang40a71912019-10-11 11:13:39 -07004144 if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004145 *nextPtr = s;
4146 return XML_ERROR_NONE;
4147 }
4148 switch (tok) {
4149 case XML_TOK_INVALID:
4150 return XML_ERROR_INVALID_TOKEN;
4151 case XML_TOK_PARTIAL:
4152 return XML_ERROR_UNCLOSED_TOKEN;
4153 case XML_TOK_PARTIAL_CHAR:
4154 return XML_ERROR_PARTIAL_CHAR;
Haibo Huang40a71912019-10-11 11:13:39 -07004155 case XML_TOK_NONE: /* start == end */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004156 default:
4157 break;
4158 }
4159 }
4160 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
4161 However, when parsing an external subset, doProlog will not accept a BOM
4162 as valid, and report a syntax error, so we have to skip the BOM
4163 */
4164 else if (tok == XML_TOK_BOM) {
4165 s = next;
Elliott Hughes72472942018-01-10 08:36:10 -08004166 tok = XmlPrologTok(parser->m_encoding, s, end, &next);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004167 }
4168
Elliott Hughes72472942018-01-10 08:36:10 -08004169 parser->m_processor = prologProcessor;
Haibo Huang40a71912019-10-11 11:13:39 -07004170 return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
4171 (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004172}
4173
4174static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07004175entityValueProcessor(XML_Parser parser, const char *s, const char *end,
4176 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004177 const char *start = s;
4178 const char *next = s;
Elliott Hughes72472942018-01-10 08:36:10 -08004179 const ENCODING *enc = parser->m_encoding;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004180 int tok;
4181
4182 for (;;) {
4183 tok = XmlPrologTok(enc, start, end, &next);
4184 if (tok <= 0) {
Haibo Huang40a71912019-10-11 11:13:39 -07004185 if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004186 *nextPtr = s;
4187 return XML_ERROR_NONE;
4188 }
4189 switch (tok) {
4190 case XML_TOK_INVALID:
4191 return XML_ERROR_INVALID_TOKEN;
4192 case XML_TOK_PARTIAL:
4193 return XML_ERROR_UNCLOSED_TOKEN;
4194 case XML_TOK_PARTIAL_CHAR:
4195 return XML_ERROR_PARTIAL_CHAR;
Haibo Huang40a71912019-10-11 11:13:39 -07004196 case XML_TOK_NONE: /* start == end */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004197 default:
4198 break;
4199 }
4200 /* found end of entity value - can store it now */
4201 return storeEntityValue(parser, enc, s, end);
4202 }
4203 start = next;
4204 }
4205}
4206
4207#endif /* XML_DTD */
4208
4209static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07004210prologProcessor(XML_Parser parser, const char *s, const char *end,
4211 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004212 const char *next = s;
Elliott Hughes72472942018-01-10 08:36:10 -08004213 int tok = XmlPrologTok(parser->m_encoding, s, end, &next);
Haibo Huang40a71912019-10-11 11:13:39 -07004214 return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
4215 (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004216}
4217
4218static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07004219doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
4220 int tok, const char *next, const char **nextPtr, XML_Bool haveMore,
4221 XML_Bool allowClosingDoctype) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004222#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07004223 static const XML_Char externalSubsetName[] = {ASCII_HASH, '\0'};
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004224#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07004225 static const XML_Char atypeCDATA[]
4226 = {ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'};
4227 static const XML_Char atypeID[] = {ASCII_I, ASCII_D, '\0'};
4228 static const XML_Char atypeIDREF[]
4229 = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0'};
4230 static const XML_Char atypeIDREFS[]
4231 = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0'};
4232 static const XML_Char atypeENTITY[]
4233 = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0'};
4234 static const XML_Char atypeENTITIES[]
4235 = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T,
4236 ASCII_I, ASCII_E, ASCII_S, '\0'};
4237 static const XML_Char atypeNMTOKEN[]
4238 = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0'};
4239 static const XML_Char atypeNMTOKENS[]
4240 = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K,
4241 ASCII_E, ASCII_N, ASCII_S, '\0'};
4242 static const XML_Char notationPrefix[]
4243 = {ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T,
4244 ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0'};
4245 static const XML_Char enumValueSep[] = {ASCII_PIPE, '\0'};
4246 static const XML_Char enumValueStart[] = {ASCII_LPAREN, '\0'};
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004247
4248 /* save one level of indirection */
Haibo Huang40a71912019-10-11 11:13:39 -07004249 DTD *const dtd = parser->m_dtd;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004250
4251 const char **eventPP;
4252 const char **eventEndPP;
4253 enum XML_Content_Quant quant;
4254
Elliott Hughes72472942018-01-10 08:36:10 -08004255 if (enc == parser->m_encoding) {
4256 eventPP = &parser->m_eventPtr;
4257 eventEndPP = &parser->m_eventEndPtr;
Haibo Huang40a71912019-10-11 11:13:39 -07004258 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08004259 eventPP = &(parser->m_openInternalEntities->internalEventPtr);
4260 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004261 }
4262
4263 for (;;) {
4264 int role;
4265 XML_Bool handleDefault = XML_TRUE;
4266 *eventPP = s;
4267 *eventEndPP = next;
4268 if (tok <= 0) {
4269 if (haveMore && tok != XML_TOK_INVALID) {
4270 *nextPtr = s;
4271 return XML_ERROR_NONE;
4272 }
4273 switch (tok) {
4274 case XML_TOK_INVALID:
4275 *eventPP = next;
4276 return XML_ERROR_INVALID_TOKEN;
4277 case XML_TOK_PARTIAL:
4278 return XML_ERROR_UNCLOSED_TOKEN;
4279 case XML_TOK_PARTIAL_CHAR:
4280 return XML_ERROR_PARTIAL_CHAR;
Elliott Hughes35e432d2012-09-09 14:23:38 -07004281 case -XML_TOK_PROLOG_S:
4282 tok = -tok;
4283 break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004284 case XML_TOK_NONE:
4285#ifdef XML_DTD
4286 /* for internal PE NOT referenced between declarations */
Haibo Huang40a71912019-10-11 11:13:39 -07004287 if (enc != parser->m_encoding
4288 && ! parser->m_openInternalEntities->betweenDecl) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004289 *nextPtr = s;
4290 return XML_ERROR_NONE;
4291 }
4292 /* WFC: PE Between Declarations - must check that PE contains
4293 complete markup, not only for external PEs, but also for
4294 internal PEs if the reference occurs between declarations.
4295 */
Elliott Hughes72472942018-01-10 08:36:10 -08004296 if (parser->m_isParamEntity || enc != parser->m_encoding) {
4297 if (XmlTokenRole(&parser->m_prologState, XML_TOK_NONE, end, end, enc)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004298 == XML_ROLE_ERROR)
4299 return XML_ERROR_INCOMPLETE_PE;
4300 *nextPtr = s;
4301 return XML_ERROR_NONE;
4302 }
4303#endif /* XML_DTD */
4304 return XML_ERROR_NO_ELEMENTS;
4305 default:
4306 tok = -tok;
4307 next = end;
4308 break;
4309 }
4310 }
Elliott Hughes72472942018-01-10 08:36:10 -08004311 role = XmlTokenRole(&parser->m_prologState, tok, s, next, enc);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004312 switch (role) {
Haibo Huang40a71912019-10-11 11:13:39 -07004313 case XML_ROLE_XML_DECL: {
4314 enum XML_Error result = processXmlDecl(parser, 0, s, next);
4315 if (result != XML_ERROR_NONE)
4316 return result;
4317 enc = parser->m_encoding;
4318 handleDefault = XML_FALSE;
4319 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004320 case XML_ROLE_DOCTYPE_NAME:
Elliott Hughes72472942018-01-10 08:36:10 -08004321 if (parser->m_startDoctypeDeclHandler) {
Haibo Huang40a71912019-10-11 11:13:39 -07004322 parser->m_doctypeName
4323 = poolStoreString(&parser->m_tempPool, enc, s, next);
4324 if (! parser->m_doctypeName)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004325 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004326 poolFinish(&parser->m_tempPool);
4327 parser->m_doctypePubid = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004328 handleDefault = XML_FALSE;
4329 }
Elliott Hughes72472942018-01-10 08:36:10 -08004330 parser->m_doctypeSysid = NULL; /* always initialize to NULL */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004331 break;
4332 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
Elliott Hughes72472942018-01-10 08:36:10 -08004333 if (parser->m_startDoctypeDeclHandler) {
Haibo Huang40a71912019-10-11 11:13:39 -07004334 parser->m_startDoctypeDeclHandler(
4335 parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid,
4336 parser->m_doctypePubid, 1);
Elliott Hughes72472942018-01-10 08:36:10 -08004337 parser->m_doctypeName = NULL;
4338 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004339 handleDefault = XML_FALSE;
4340 }
4341 break;
4342#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07004343 case XML_ROLE_TEXT_DECL: {
4344 enum XML_Error result = processXmlDecl(parser, 1, s, next);
4345 if (result != XML_ERROR_NONE)
4346 return result;
4347 enc = parser->m_encoding;
4348 handleDefault = XML_FALSE;
4349 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004350#endif /* XML_DTD */
4351 case XML_ROLE_DOCTYPE_PUBLIC_ID:
4352#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08004353 parser->m_useForeignDTD = XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07004354 parser->m_declEntity = (ENTITY *)lookup(
4355 parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY));
4356 if (! parser->m_declEntity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004357 return XML_ERROR_NO_MEMORY;
4358#endif /* XML_DTD */
4359 dtd->hasParamEntityRefs = XML_TRUE;
Elliott Hughes72472942018-01-10 08:36:10 -08004360 if (parser->m_startDoctypeDeclHandler) {
Elliott Hughes35e432d2012-09-09 14:23:38 -07004361 XML_Char *pubId;
Haibo Huang40a71912019-10-11 11:13:39 -07004362 if (! XmlIsPublicId(enc, s, next, eventPP))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004363 return XML_ERROR_PUBLICID;
Elliott Hughes72472942018-01-10 08:36:10 -08004364 pubId = poolStoreString(&parser->m_tempPool, enc,
Elliott Hughes35e432d2012-09-09 14:23:38 -07004365 s + enc->minBytesPerChar,
4366 next - enc->minBytesPerChar);
Haibo Huang40a71912019-10-11 11:13:39 -07004367 if (! pubId)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004368 return XML_ERROR_NO_MEMORY;
Elliott Hughes35e432d2012-09-09 14:23:38 -07004369 normalizePublicId(pubId);
Elliott Hughes72472942018-01-10 08:36:10 -08004370 poolFinish(&parser->m_tempPool);
4371 parser->m_doctypePubid = pubId;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004372 handleDefault = XML_FALSE;
4373 goto alreadyChecked;
4374 }
4375 /* fall through */
4376 case XML_ROLE_ENTITY_PUBLIC_ID:
Haibo Huang40a71912019-10-11 11:13:39 -07004377 if (! XmlIsPublicId(enc, s, next, eventPP))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004378 return XML_ERROR_PUBLICID;
4379 alreadyChecked:
Elliott Hughes72472942018-01-10 08:36:10 -08004380 if (dtd->keepProcessing && parser->m_declEntity) {
Haibo Huang40a71912019-10-11 11:13:39 -07004381 XML_Char *tem
4382 = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
4383 next - enc->minBytesPerChar);
4384 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004385 return XML_ERROR_NO_MEMORY;
4386 normalizePublicId(tem);
Elliott Hughes72472942018-01-10 08:36:10 -08004387 parser->m_declEntity->publicId = tem;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004388 poolFinish(&dtd->pool);
Elliott Hughes72472942018-01-10 08:36:10 -08004389 /* Don't suppress the default handler if we fell through from
4390 * the XML_ROLE_DOCTYPE_PUBLIC_ID case.
4391 */
4392 if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_PUBLIC_ID)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004393 handleDefault = XML_FALSE;
4394 }
4395 break;
4396 case XML_ROLE_DOCTYPE_CLOSE:
Haibo Huang40a71912019-10-11 11:13:39 -07004397 if (allowClosingDoctype != XML_TRUE) {
4398 /* Must not close doctype from within expanded parameter entities */
4399 return XML_ERROR_INVALID_TOKEN;
4400 }
4401
Elliott Hughes72472942018-01-10 08:36:10 -08004402 if (parser->m_doctypeName) {
Haibo Huang40a71912019-10-11 11:13:39 -07004403 parser->m_startDoctypeDeclHandler(
4404 parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid,
4405 parser->m_doctypePubid, 0);
Elliott Hughes72472942018-01-10 08:36:10 -08004406 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004407 handleDefault = XML_FALSE;
4408 }
Elliott Hughes72472942018-01-10 08:36:10 -08004409 /* parser->m_doctypeSysid will be non-NULL in the case of a previous
4410 XML_ROLE_DOCTYPE_SYSTEM_ID, even if parser->m_startDoctypeDeclHandler
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004411 was not set, indicating an external subset
4412 */
4413#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08004414 if (parser->m_doctypeSysid || parser->m_useForeignDTD) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004415 XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
4416 dtd->hasParamEntityRefs = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07004417 if (parser->m_paramEntityParsing
4418 && parser->m_externalEntityRefHandler) {
4419 ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
4420 externalSubsetName, sizeof(ENTITY));
4421 if (! entity) {
Elliott Hughes72472942018-01-10 08:36:10 -08004422 /* The external subset name "#" will have already been
4423 * inserted into the hash table at the start of the
4424 * external entity parsing, so no allocation will happen
4425 * and lookup() cannot fail.
4426 */
4427 return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */
4428 }
4429 if (parser->m_useForeignDTD)
4430 entity->base = parser->m_curBase;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004431 dtd->paramEntityRead = XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07004432 if (! parser->m_externalEntityRefHandler(
4433 parser->m_externalEntityRefHandlerArg, 0, entity->base,
4434 entity->systemId, entity->publicId))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004435 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4436 if (dtd->paramEntityRead) {
Haibo Huang40a71912019-10-11 11:13:39 -07004437 if (! dtd->standalone && parser->m_notStandaloneHandler
4438 && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004439 return XML_ERROR_NOT_STANDALONE;
4440 }
4441 /* if we didn't read the foreign DTD then this means that there
4442 is no external subset and we must reset dtd->hasParamEntityRefs
4443 */
Haibo Huang40a71912019-10-11 11:13:39 -07004444 else if (! parser->m_doctypeSysid)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004445 dtd->hasParamEntityRefs = hadParamEntityRefs;
4446 /* end of DTD - no need to update dtd->keepProcessing */
4447 }
Elliott Hughes72472942018-01-10 08:36:10 -08004448 parser->m_useForeignDTD = XML_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004449 }
4450#endif /* XML_DTD */
Elliott Hughes72472942018-01-10 08:36:10 -08004451 if (parser->m_endDoctypeDeclHandler) {
4452 parser->m_endDoctypeDeclHandler(parser->m_handlerArg);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004453 handleDefault = XML_FALSE;
4454 }
4455 break;
4456 case XML_ROLE_INSTANCE_START:
4457#ifdef XML_DTD
4458 /* if there is no DOCTYPE declaration then now is the
4459 last chance to read the foreign DTD
4460 */
Elliott Hughes72472942018-01-10 08:36:10 -08004461 if (parser->m_useForeignDTD) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004462 XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
4463 dtd->hasParamEntityRefs = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07004464 if (parser->m_paramEntityParsing
4465 && parser->m_externalEntityRefHandler) {
Elliott Hughes35e432d2012-09-09 14:23:38 -07004466 ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
Haibo Huang40a71912019-10-11 11:13:39 -07004467 externalSubsetName, sizeof(ENTITY));
4468 if (! entity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004469 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004470 entity->base = parser->m_curBase;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004471 dtd->paramEntityRead = XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07004472 if (! parser->m_externalEntityRefHandler(
4473 parser->m_externalEntityRefHandlerArg, 0, entity->base,
4474 entity->systemId, entity->publicId))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004475 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4476 if (dtd->paramEntityRead) {
Haibo Huang40a71912019-10-11 11:13:39 -07004477 if (! dtd->standalone && parser->m_notStandaloneHandler
4478 && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004479 return XML_ERROR_NOT_STANDALONE;
4480 }
4481 /* if we didn't read the foreign DTD then this means that there
4482 is no external subset and we must reset dtd->hasParamEntityRefs
4483 */
4484 else
4485 dtd->hasParamEntityRefs = hadParamEntityRefs;
4486 /* end of DTD - no need to update dtd->keepProcessing */
4487 }
4488 }
4489#endif /* XML_DTD */
Elliott Hughes72472942018-01-10 08:36:10 -08004490 parser->m_processor = contentProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004491 return contentProcessor(parser, s, end, nextPtr);
4492 case XML_ROLE_ATTLIST_ELEMENT_NAME:
Elliott Hughes72472942018-01-10 08:36:10 -08004493 parser->m_declElementType = getElementType(parser, enc, s, next);
Haibo Huang40a71912019-10-11 11:13:39 -07004494 if (! parser->m_declElementType)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004495 return XML_ERROR_NO_MEMORY;
4496 goto checkAttListDeclHandler;
4497 case XML_ROLE_ATTRIBUTE_NAME:
Elliott Hughes72472942018-01-10 08:36:10 -08004498 parser->m_declAttributeId = getAttributeId(parser, enc, s, next);
Haibo Huang40a71912019-10-11 11:13:39 -07004499 if (! parser->m_declAttributeId)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004500 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004501 parser->m_declAttributeIsCdata = XML_FALSE;
4502 parser->m_declAttributeType = NULL;
4503 parser->m_declAttributeIsId = XML_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004504 goto checkAttListDeclHandler;
4505 case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
Elliott Hughes72472942018-01-10 08:36:10 -08004506 parser->m_declAttributeIsCdata = XML_TRUE;
4507 parser->m_declAttributeType = atypeCDATA;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004508 goto checkAttListDeclHandler;
4509 case XML_ROLE_ATTRIBUTE_TYPE_ID:
Elliott Hughes72472942018-01-10 08:36:10 -08004510 parser->m_declAttributeIsId = XML_TRUE;
4511 parser->m_declAttributeType = atypeID;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004512 goto checkAttListDeclHandler;
4513 case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
Elliott Hughes72472942018-01-10 08:36:10 -08004514 parser->m_declAttributeType = atypeIDREF;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004515 goto checkAttListDeclHandler;
4516 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
Elliott Hughes72472942018-01-10 08:36:10 -08004517 parser->m_declAttributeType = atypeIDREFS;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004518 goto checkAttListDeclHandler;
4519 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
Elliott Hughes72472942018-01-10 08:36:10 -08004520 parser->m_declAttributeType = atypeENTITY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004521 goto checkAttListDeclHandler;
4522 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
Elliott Hughes72472942018-01-10 08:36:10 -08004523 parser->m_declAttributeType = atypeENTITIES;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004524 goto checkAttListDeclHandler;
4525 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
Elliott Hughes72472942018-01-10 08:36:10 -08004526 parser->m_declAttributeType = atypeNMTOKEN;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004527 goto checkAttListDeclHandler;
4528 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
Elliott Hughes72472942018-01-10 08:36:10 -08004529 parser->m_declAttributeType = atypeNMTOKENS;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004530 checkAttListDeclHandler:
Elliott Hughes72472942018-01-10 08:36:10 -08004531 if (dtd->keepProcessing && parser->m_attlistDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004532 handleDefault = XML_FALSE;
4533 break;
4534 case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
4535 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
Elliott Hughes72472942018-01-10 08:36:10 -08004536 if (dtd->keepProcessing && parser->m_attlistDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004537 const XML_Char *prefix;
Elliott Hughes72472942018-01-10 08:36:10 -08004538 if (parser->m_declAttributeType) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004539 prefix = enumValueSep;
Haibo Huang40a71912019-10-11 11:13:39 -07004540 } else {
4541 prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE ? notationPrefix
4542 : enumValueStart);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004543 }
Haibo Huang40a71912019-10-11 11:13:39 -07004544 if (! poolAppendString(&parser->m_tempPool, prefix))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004545 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07004546 if (! poolAppend(&parser->m_tempPool, enc, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004547 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004548 parser->m_declAttributeType = parser->m_tempPool.start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004549 handleDefault = XML_FALSE;
4550 }
4551 break;
4552 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
4553 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
4554 if (dtd->keepProcessing) {
Haibo Huang40a71912019-10-11 11:13:39 -07004555 if (! defineAttribute(parser->m_declElementType,
4556 parser->m_declAttributeId,
4557 parser->m_declAttributeIsCdata,
4558 parser->m_declAttributeIsId, 0, parser))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004559 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004560 if (parser->m_attlistDeclHandler && parser->m_declAttributeType) {
4561 if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN)
4562 || (*parser->m_declAttributeType == XML_T(ASCII_N)
4563 && parser->m_declAttributeType[1] == XML_T(ASCII_O))) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004564 /* Enumerated or Notation type */
Haibo Huang40a71912019-10-11 11:13:39 -07004565 if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN))
4566 || ! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004567 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004568 parser->m_declAttributeType = parser->m_tempPool.start;
4569 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004570 }
4571 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004572 parser->m_attlistDeclHandler(
4573 parser->m_handlerArg, parser->m_declElementType->name,
4574 parser->m_declAttributeId->name, parser->m_declAttributeType, 0,
4575 role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
Elliott Hughes72472942018-01-10 08:36:10 -08004576 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004577 handleDefault = XML_FALSE;
4578 }
4579 }
4580 break;
4581 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
4582 case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
4583 if (dtd->keepProcessing) {
4584 const XML_Char *attVal;
Haibo Huang40a71912019-10-11 11:13:39 -07004585 enum XML_Error result = storeAttributeValue(
4586 parser, enc, parser->m_declAttributeIsCdata,
4587 s + enc->minBytesPerChar, next - enc->minBytesPerChar, &dtd->pool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004588 if (result)
4589 return result;
4590 attVal = poolStart(&dtd->pool);
4591 poolFinish(&dtd->pool);
4592 /* ID attributes aren't allowed to have a default */
Haibo Huang40a71912019-10-11 11:13:39 -07004593 if (! defineAttribute(
4594 parser->m_declElementType, parser->m_declAttributeId,
4595 parser->m_declAttributeIsCdata, XML_FALSE, attVal, parser))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004596 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004597 if (parser->m_attlistDeclHandler && parser->m_declAttributeType) {
4598 if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN)
4599 || (*parser->m_declAttributeType == XML_T(ASCII_N)
4600 && parser->m_declAttributeType[1] == XML_T(ASCII_O))) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004601 /* Enumerated or Notation type */
Haibo Huang40a71912019-10-11 11:13:39 -07004602 if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN))
4603 || ! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004604 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004605 parser->m_declAttributeType = parser->m_tempPool.start;
4606 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004607 }
4608 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004609 parser->m_attlistDeclHandler(
4610 parser->m_handlerArg, parser->m_declElementType->name,
4611 parser->m_declAttributeId->name, parser->m_declAttributeType,
4612 attVal, role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
Elliott Hughes72472942018-01-10 08:36:10 -08004613 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004614 handleDefault = XML_FALSE;
4615 }
4616 }
4617 break;
4618 case XML_ROLE_ENTITY_VALUE:
4619 if (dtd->keepProcessing) {
Haibo Huang40a71912019-10-11 11:13:39 -07004620 enum XML_Error result = storeEntityValue(
4621 parser, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar);
Elliott Hughes72472942018-01-10 08:36:10 -08004622 if (parser->m_declEntity) {
4623 parser->m_declEntity->textPtr = poolStart(&dtd->entityValuePool);
Haibo Huang40a71912019-10-11 11:13:39 -07004624 parser->m_declEntity->textLen
4625 = (int)(poolLength(&dtd->entityValuePool));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004626 poolFinish(&dtd->entityValuePool);
Elliott Hughes72472942018-01-10 08:36:10 -08004627 if (parser->m_entityDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004628 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004629 parser->m_entityDeclHandler(
4630 parser->m_handlerArg, parser->m_declEntity->name,
4631 parser->m_declEntity->is_param, parser->m_declEntity->textPtr,
4632 parser->m_declEntity->textLen, parser->m_curBase, 0, 0, 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004633 handleDefault = XML_FALSE;
4634 }
Haibo Huang40a71912019-10-11 11:13:39 -07004635 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004636 poolDiscard(&dtd->entityValuePool);
4637 if (result != XML_ERROR_NONE)
4638 return result;
4639 }
4640 break;
4641 case XML_ROLE_DOCTYPE_SYSTEM_ID:
4642#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08004643 parser->m_useForeignDTD = XML_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004644#endif /* XML_DTD */
4645 dtd->hasParamEntityRefs = XML_TRUE;
Elliott Hughes72472942018-01-10 08:36:10 -08004646 if (parser->m_startDoctypeDeclHandler) {
4647 parser->m_doctypeSysid = poolStoreString(&parser->m_tempPool, enc,
Haibo Huang40a71912019-10-11 11:13:39 -07004648 s + enc->minBytesPerChar,
4649 next - enc->minBytesPerChar);
Elliott Hughes72472942018-01-10 08:36:10 -08004650 if (parser->m_doctypeSysid == NULL)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004651 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004652 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004653 handleDefault = XML_FALSE;
4654 }
4655#ifdef XML_DTD
4656 else
Elliott Hughes72472942018-01-10 08:36:10 -08004657 /* use externalSubsetName to make parser->m_doctypeSysid non-NULL
4658 for the case where no parser->m_startDoctypeDeclHandler is set */
4659 parser->m_doctypeSysid = externalSubsetName;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004660#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07004661 if (! dtd->standalone
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004662#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07004663 && ! parser->m_paramEntityParsing
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004664#endif /* XML_DTD */
Elliott Hughes72472942018-01-10 08:36:10 -08004665 && parser->m_notStandaloneHandler
Haibo Huang40a71912019-10-11 11:13:39 -07004666 && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004667 return XML_ERROR_NOT_STANDALONE;
4668#ifndef XML_DTD
4669 break;
Haibo Huang40a71912019-10-11 11:13:39 -07004670#else /* XML_DTD */
4671 if (! parser->m_declEntity) {
4672 parser->m_declEntity = (ENTITY *)lookup(
4673 parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY));
4674 if (! parser->m_declEntity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004675 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004676 parser->m_declEntity->publicId = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004677 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004678#endif /* XML_DTD */
Elliott Hughesaaec48e2018-08-16 16:29:01 -07004679 /* fall through */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004680 case XML_ROLE_ENTITY_SYSTEM_ID:
Elliott Hughes72472942018-01-10 08:36:10 -08004681 if (dtd->keepProcessing && parser->m_declEntity) {
Haibo Huang40a71912019-10-11 11:13:39 -07004682 parser->m_declEntity->systemId
4683 = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
4684 next - enc->minBytesPerChar);
4685 if (! parser->m_declEntity->systemId)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004686 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004687 parser->m_declEntity->base = parser->m_curBase;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004688 poolFinish(&dtd->pool);
Elliott Hughes72472942018-01-10 08:36:10 -08004689 /* Don't suppress the default handler if we fell through from
4690 * the XML_ROLE_DOCTYPE_SYSTEM_ID case.
4691 */
4692 if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_SYSTEM_ID)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004693 handleDefault = XML_FALSE;
4694 }
4695 break;
4696 case XML_ROLE_ENTITY_COMPLETE:
Haibo Huang40a71912019-10-11 11:13:39 -07004697 if (dtd->keepProcessing && parser->m_declEntity
4698 && parser->m_entityDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004699 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004700 parser->m_entityDeclHandler(
4701 parser->m_handlerArg, parser->m_declEntity->name,
4702 parser->m_declEntity->is_param, 0, 0, parser->m_declEntity->base,
4703 parser->m_declEntity->systemId, parser->m_declEntity->publicId, 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004704 handleDefault = XML_FALSE;
4705 }
4706 break;
4707 case XML_ROLE_ENTITY_NOTATION_NAME:
Elliott Hughes72472942018-01-10 08:36:10 -08004708 if (dtd->keepProcessing && parser->m_declEntity) {
Haibo Huang40a71912019-10-11 11:13:39 -07004709 parser->m_declEntity->notation
4710 = poolStoreString(&dtd->pool, enc, s, next);
4711 if (! parser->m_declEntity->notation)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004712 return XML_ERROR_NO_MEMORY;
4713 poolFinish(&dtd->pool);
Elliott Hughes72472942018-01-10 08:36:10 -08004714 if (parser->m_unparsedEntityDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004715 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004716 parser->m_unparsedEntityDeclHandler(
4717 parser->m_handlerArg, parser->m_declEntity->name,
4718 parser->m_declEntity->base, parser->m_declEntity->systemId,
4719 parser->m_declEntity->publicId, parser->m_declEntity->notation);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004720 handleDefault = XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07004721 } else if (parser->m_entityDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004722 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004723 parser->m_entityDeclHandler(
4724 parser->m_handlerArg, parser->m_declEntity->name, 0, 0, 0,
4725 parser->m_declEntity->base, parser->m_declEntity->systemId,
4726 parser->m_declEntity->publicId, parser->m_declEntity->notation);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004727 handleDefault = XML_FALSE;
4728 }
4729 }
4730 break;
Haibo Huang40a71912019-10-11 11:13:39 -07004731 case XML_ROLE_GENERAL_ENTITY_NAME: {
4732 if (XmlPredefinedEntityName(enc, s, next)) {
4733 parser->m_declEntity = NULL;
4734 break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004735 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004736 if (dtd->keepProcessing) {
4737 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
Haibo Huang40a71912019-10-11 11:13:39 -07004738 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004739 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07004740 parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities,
4741 name, sizeof(ENTITY));
4742 if (! parser->m_declEntity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004743 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004744 if (parser->m_declEntity->name != name) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004745 poolDiscard(&dtd->pool);
Elliott Hughes72472942018-01-10 08:36:10 -08004746 parser->m_declEntity = NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07004747 } else {
4748 poolFinish(&dtd->pool);
4749 parser->m_declEntity->publicId = NULL;
4750 parser->m_declEntity->is_param = XML_FALSE;
4751 /* if we have a parent parser or are reading an internal parameter
4752 entity, then the entity declaration is not considered "internal"
4753 */
4754 parser->m_declEntity->is_internal
4755 = ! (parser->m_parentParser || parser->m_openInternalEntities);
4756 if (parser->m_entityDeclHandler)
4757 handleDefault = XML_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004758 }
Haibo Huang40a71912019-10-11 11:13:39 -07004759 } else {
4760 poolDiscard(&dtd->pool);
4761 parser->m_declEntity = NULL;
4762 }
4763 } break;
4764 case XML_ROLE_PARAM_ENTITY_NAME:
4765#ifdef XML_DTD
4766 if (dtd->keepProcessing) {
4767 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
4768 if (! name)
4769 return XML_ERROR_NO_MEMORY;
4770 parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities,
4771 name, sizeof(ENTITY));
4772 if (! parser->m_declEntity)
4773 return XML_ERROR_NO_MEMORY;
4774 if (parser->m_declEntity->name != name) {
4775 poolDiscard(&dtd->pool);
4776 parser->m_declEntity = NULL;
4777 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004778 poolFinish(&dtd->pool);
Elliott Hughes72472942018-01-10 08:36:10 -08004779 parser->m_declEntity->publicId = NULL;
4780 parser->m_declEntity->is_param = XML_TRUE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004781 /* if we have a parent parser or are reading an internal parameter
4782 entity, then the entity declaration is not considered "internal"
4783 */
Haibo Huang40a71912019-10-11 11:13:39 -07004784 parser->m_declEntity->is_internal
4785 = ! (parser->m_parentParser || parser->m_openInternalEntities);
Elliott Hughes72472942018-01-10 08:36:10 -08004786 if (parser->m_entityDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004787 handleDefault = XML_FALSE;
4788 }
Haibo Huang40a71912019-10-11 11:13:39 -07004789 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004790 poolDiscard(&dtd->pool);
Elliott Hughes72472942018-01-10 08:36:10 -08004791 parser->m_declEntity = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004792 }
Haibo Huang40a71912019-10-11 11:13:39 -07004793#else /* not XML_DTD */
Elliott Hughes72472942018-01-10 08:36:10 -08004794 parser->m_declEntity = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004795#endif /* XML_DTD */
4796 break;
4797 case XML_ROLE_NOTATION_NAME:
Elliott Hughes72472942018-01-10 08:36:10 -08004798 parser->m_declNotationPublicId = NULL;
4799 parser->m_declNotationName = NULL;
4800 if (parser->m_notationDeclHandler) {
Haibo Huang40a71912019-10-11 11:13:39 -07004801 parser->m_declNotationName
4802 = poolStoreString(&parser->m_tempPool, enc, s, next);
4803 if (! parser->m_declNotationName)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004804 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004805 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004806 handleDefault = XML_FALSE;
4807 }
4808 break;
4809 case XML_ROLE_NOTATION_PUBLIC_ID:
Haibo Huang40a71912019-10-11 11:13:39 -07004810 if (! XmlIsPublicId(enc, s, next, eventPP))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004811 return XML_ERROR_PUBLICID;
Haibo Huang40a71912019-10-11 11:13:39 -07004812 if (parser
4813 ->m_declNotationName) { /* means m_notationDeclHandler != NULL */
4814 XML_Char *tem = poolStoreString(&parser->m_tempPool, enc,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004815 s + enc->minBytesPerChar,
4816 next - enc->minBytesPerChar);
Haibo Huang40a71912019-10-11 11:13:39 -07004817 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004818 return XML_ERROR_NO_MEMORY;
4819 normalizePublicId(tem);
Elliott Hughes72472942018-01-10 08:36:10 -08004820 parser->m_declNotationPublicId = tem;
4821 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004822 handleDefault = XML_FALSE;
4823 }
4824 break;
4825 case XML_ROLE_NOTATION_SYSTEM_ID:
Elliott Hughes72472942018-01-10 08:36:10 -08004826 if (parser->m_declNotationName && parser->m_notationDeclHandler) {
Haibo Huang40a71912019-10-11 11:13:39 -07004827 const XML_Char *systemId = poolStoreString(&parser->m_tempPool, enc,
4828 s + enc->minBytesPerChar,
4829 next - enc->minBytesPerChar);
4830 if (! systemId)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004831 return XML_ERROR_NO_MEMORY;
4832 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004833 parser->m_notationDeclHandler(
4834 parser->m_handlerArg, parser->m_declNotationName, parser->m_curBase,
4835 systemId, parser->m_declNotationPublicId);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004836 handleDefault = XML_FALSE;
4837 }
Elliott Hughes72472942018-01-10 08:36:10 -08004838 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004839 break;
4840 case XML_ROLE_NOTATION_NO_SYSTEM_ID:
Elliott Hughes72472942018-01-10 08:36:10 -08004841 if (parser->m_declNotationPublicId && parser->m_notationDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004842 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004843 parser->m_notationDeclHandler(
4844 parser->m_handlerArg, parser->m_declNotationName, parser->m_curBase,
4845 0, parser->m_declNotationPublicId);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004846 handleDefault = XML_FALSE;
4847 }
Elliott Hughes72472942018-01-10 08:36:10 -08004848 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004849 break;
4850 case XML_ROLE_ERROR:
4851 switch (tok) {
4852 case XML_TOK_PARAM_ENTITY_REF:
4853 /* PE references in internal subset are
Elliott Hughes35e432d2012-09-09 14:23:38 -07004854 not allowed within declarations. */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004855 return XML_ERROR_PARAM_ENTITY_REF;
4856 case XML_TOK_XML_DECL:
4857 return XML_ERROR_MISPLACED_XML_PI;
4858 default:
4859 return XML_ERROR_SYNTAX;
4860 }
4861#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07004862 case XML_ROLE_IGNORE_SECT: {
4863 enum XML_Error result;
4864 if (parser->m_defaultHandler)
4865 reportDefault(parser, enc, s, next);
4866 handleDefault = XML_FALSE;
4867 result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
4868 if (result != XML_ERROR_NONE)
4869 return result;
4870 else if (! next) {
4871 parser->m_processor = ignoreSectionProcessor;
4872 return result;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004873 }
Haibo Huang40a71912019-10-11 11:13:39 -07004874 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004875#endif /* XML_DTD */
4876 case XML_ROLE_GROUP_OPEN:
Elliott Hughes72472942018-01-10 08:36:10 -08004877 if (parser->m_prologState.level >= parser->m_groupSize) {
4878 if (parser->m_groupSize) {
Haibo Huang40a71912019-10-11 11:13:39 -07004879 {
4880 char *const new_connector = (char *)REALLOC(
4881 parser, parser->m_groupConnector, parser->m_groupSize *= 2);
4882 if (new_connector == NULL) {
4883 parser->m_groupSize /= 2;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004884 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07004885 }
4886 parser->m_groupConnector = new_connector;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004887 }
Haibo Huang40a71912019-10-11 11:13:39 -07004888
4889 if (dtd->scaffIndex) {
4890 int *const new_scaff_index = (int *)REALLOC(
4891 parser, dtd->scaffIndex, parser->m_groupSize * sizeof(int));
4892 if (new_scaff_index == NULL)
4893 return XML_ERROR_NO_MEMORY;
4894 dtd->scaffIndex = new_scaff_index;
4895 }
4896 } else {
4897 parser->m_groupConnector
4898 = (char *)MALLOC(parser, parser->m_groupSize = 32);
4899 if (! parser->m_groupConnector) {
Elliott Hughes72472942018-01-10 08:36:10 -08004900 parser->m_groupSize = 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004901 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004902 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004903 }
4904 }
Elliott Hughes72472942018-01-10 08:36:10 -08004905 parser->m_groupConnector[parser->m_prologState.level] = 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004906 if (dtd->in_eldecl) {
4907 int myindex = nextScaffoldPart(parser);
4908 if (myindex < 0)
4909 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07004910 assert(dtd->scaffIndex != NULL);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004911 dtd->scaffIndex[dtd->scaffLevel] = myindex;
4912 dtd->scaffLevel++;
4913 dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
Elliott Hughes72472942018-01-10 08:36:10 -08004914 if (parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004915 handleDefault = XML_FALSE;
4916 }
4917 break;
4918 case XML_ROLE_GROUP_SEQUENCE:
Elliott Hughes72472942018-01-10 08:36:10 -08004919 if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_PIPE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004920 return XML_ERROR_SYNTAX;
Elliott Hughes72472942018-01-10 08:36:10 -08004921 parser->m_groupConnector[parser->m_prologState.level] = ASCII_COMMA;
4922 if (dtd->in_eldecl && parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004923 handleDefault = XML_FALSE;
4924 break;
4925 case XML_ROLE_GROUP_CHOICE:
Elliott Hughes72472942018-01-10 08:36:10 -08004926 if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_COMMA)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004927 return XML_ERROR_SYNTAX;
4928 if (dtd->in_eldecl
Haibo Huang40a71912019-10-11 11:13:39 -07004929 && ! parser->m_groupConnector[parser->m_prologState.level]
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004930 && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
Haibo Huang40a71912019-10-11 11:13:39 -07004931 != XML_CTYPE_MIXED)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004932 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4933 = XML_CTYPE_CHOICE;
Elliott Hughes72472942018-01-10 08:36:10 -08004934 if (parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004935 handleDefault = XML_FALSE;
4936 }
Elliott Hughes72472942018-01-10 08:36:10 -08004937 parser->m_groupConnector[parser->m_prologState.level] = ASCII_PIPE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004938 break;
4939 case XML_ROLE_PARAM_ENTITY_REF:
4940#ifdef XML_DTD
4941 case XML_ROLE_INNER_PARAM_ENTITY_REF:
4942 dtd->hasParamEntityRefs = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07004943 if (! parser->m_paramEntityParsing)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004944 dtd->keepProcessing = dtd->standalone;
4945 else {
4946 const XML_Char *name;
4947 ENTITY *entity;
Haibo Huang40a71912019-10-11 11:13:39 -07004948 name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
4949 next - enc->minBytesPerChar);
4950 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004951 return XML_ERROR_NO_MEMORY;
Elliott Hughes35e432d2012-09-09 14:23:38 -07004952 entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004953 poolDiscard(&dtd->pool);
4954 /* first, determine if a check for an existing declaration is needed;
4955 if yes, check that the entity exists, and that it is internal,
4956 otherwise call the skipped entity handler
4957 */
Haibo Huang40a71912019-10-11 11:13:39 -07004958 if (parser->m_prologState.documentEntity
4959 && (dtd->standalone ? ! parser->m_openInternalEntities
4960 : ! dtd->hasParamEntityRefs)) {
4961 if (! entity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004962 return XML_ERROR_UNDEFINED_ENTITY;
Haibo Huang40a71912019-10-11 11:13:39 -07004963 else if (! entity->is_internal) {
Elliott Hughes72472942018-01-10 08:36:10 -08004964 /* It's hard to exhaustively search the code to be sure,
4965 * but there doesn't seem to be a way of executing the
4966 * following line. There are two cases:
4967 *
4968 * If 'standalone' is false, the DTD must have no
4969 * parameter entities or we wouldn't have passed the outer
4970 * 'if' statement. That measn the only entity in the hash
4971 * table is the external subset name "#" which cannot be
4972 * given as a parameter entity name in XML syntax, so the
4973 * lookup must have returned NULL and we don't even reach
4974 * the test for an internal entity.
4975 *
4976 * If 'standalone' is true, it does not seem to be
4977 * possible to create entities taking this code path that
4978 * are not internal entities, so fail the test above.
4979 *
4980 * Because this analysis is very uncertain, the code is
4981 * being left in place and merely removed from the
4982 * coverage test statistics.
4983 */
4984 return XML_ERROR_ENTITY_DECLARED_IN_PE; /* LCOV_EXCL_LINE */
4985 }
Haibo Huang40a71912019-10-11 11:13:39 -07004986 } else if (! entity) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004987 dtd->keepProcessing = dtd->standalone;
4988 /* cannot report skipped entities in declarations */
Haibo Huang40a71912019-10-11 11:13:39 -07004989 if ((role == XML_ROLE_PARAM_ENTITY_REF)
4990 && parser->m_skippedEntityHandler) {
Elliott Hughes72472942018-01-10 08:36:10 -08004991 parser->m_skippedEntityHandler(parser->m_handlerArg, name, 1);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004992 handleDefault = XML_FALSE;
4993 }
4994 break;
4995 }
4996 if (entity->open)
4997 return XML_ERROR_RECURSIVE_ENTITY_REF;
4998 if (entity->textPtr) {
4999 enum XML_Error result;
Haibo Huang40a71912019-10-11 11:13:39 -07005000 XML_Bool betweenDecl
5001 = (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005002 result = processInternalEntity(parser, entity, betweenDecl);
5003 if (result != XML_ERROR_NONE)
5004 return result;
5005 handleDefault = XML_FALSE;
5006 break;
5007 }
Elliott Hughes72472942018-01-10 08:36:10 -08005008 if (parser->m_externalEntityRefHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005009 dtd->paramEntityRead = XML_FALSE;
5010 entity->open = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07005011 if (! parser->m_externalEntityRefHandler(
5012 parser->m_externalEntityRefHandlerArg, 0, entity->base,
5013 entity->systemId, entity->publicId)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005014 entity->open = XML_FALSE;
5015 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
5016 }
5017 entity->open = XML_FALSE;
5018 handleDefault = XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07005019 if (! dtd->paramEntityRead) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005020 dtd->keepProcessing = dtd->standalone;
5021 break;
5022 }
Haibo Huang40a71912019-10-11 11:13:39 -07005023 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005024 dtd->keepProcessing = dtd->standalone;
5025 break;
5026 }
5027 }
5028#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07005029 if (! dtd->standalone && parser->m_notStandaloneHandler
5030 && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005031 return XML_ERROR_NOT_STANDALONE;
5032 break;
5033
Haibo Huang40a71912019-10-11 11:13:39 -07005034 /* Element declaration stuff */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005035
5036 case XML_ROLE_ELEMENT_NAME:
Elliott Hughes72472942018-01-10 08:36:10 -08005037 if (parser->m_elementDeclHandler) {
5038 parser->m_declElementType = getElementType(parser, enc, s, next);
Haibo Huang40a71912019-10-11 11:13:39 -07005039 if (! parser->m_declElementType)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005040 return XML_ERROR_NO_MEMORY;
5041 dtd->scaffLevel = 0;
5042 dtd->scaffCount = 0;
5043 dtd->in_eldecl = XML_TRUE;
5044 handleDefault = XML_FALSE;
5045 }
5046 break;
5047
5048 case XML_ROLE_CONTENT_ANY:
5049 case XML_ROLE_CONTENT_EMPTY:
5050 if (dtd->in_eldecl) {
Elliott Hughes72472942018-01-10 08:36:10 -08005051 if (parser->m_elementDeclHandler) {
Haibo Huang40a71912019-10-11 11:13:39 -07005052 XML_Content *content
5053 = (XML_Content *)MALLOC(parser, sizeof(XML_Content));
5054 if (! content)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005055 return XML_ERROR_NO_MEMORY;
5056 content->quant = XML_CQUANT_NONE;
5057 content->name = NULL;
5058 content->numchildren = 0;
5059 content->children = NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07005060 content->type = ((role == XML_ROLE_CONTENT_ANY) ? XML_CTYPE_ANY
5061 : XML_CTYPE_EMPTY);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005062 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07005063 parser->m_elementDeclHandler(
5064 parser->m_handlerArg, parser->m_declElementType->name, content);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005065 handleDefault = XML_FALSE;
5066 }
5067 dtd->in_eldecl = XML_FALSE;
5068 }
5069 break;
5070
5071 case XML_ROLE_CONTENT_PCDATA:
5072 if (dtd->in_eldecl) {
5073 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
5074 = XML_CTYPE_MIXED;
Elliott Hughes72472942018-01-10 08:36:10 -08005075 if (parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005076 handleDefault = XML_FALSE;
5077 }
5078 break;
5079
5080 case XML_ROLE_CONTENT_ELEMENT:
5081 quant = XML_CQUANT_NONE;
5082 goto elementContent;
5083 case XML_ROLE_CONTENT_ELEMENT_OPT:
5084 quant = XML_CQUANT_OPT;
5085 goto elementContent;
5086 case XML_ROLE_CONTENT_ELEMENT_REP:
5087 quant = XML_CQUANT_REP;
5088 goto elementContent;
5089 case XML_ROLE_CONTENT_ELEMENT_PLUS:
5090 quant = XML_CQUANT_PLUS;
5091 elementContent:
5092 if (dtd->in_eldecl) {
5093 ELEMENT_TYPE *el;
5094 const XML_Char *name;
Sadaf Ebrahimifcfab022022-06-03 03:40:21 +00005095 size_t nameLen;
Haibo Huang40a71912019-10-11 11:13:39 -07005096 const char *nxt
5097 = (quant == XML_CQUANT_NONE ? next : next - enc->minBytesPerChar);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005098 int myindex = nextScaffoldPart(parser);
5099 if (myindex < 0)
5100 return XML_ERROR_NO_MEMORY;
5101 dtd->scaffold[myindex].type = XML_CTYPE_NAME;
5102 dtd->scaffold[myindex].quant = quant;
5103 el = getElementType(parser, enc, s, nxt);
Haibo Huang40a71912019-10-11 11:13:39 -07005104 if (! el)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005105 return XML_ERROR_NO_MEMORY;
5106 name = el->name;
5107 dtd->scaffold[myindex].name = name;
5108 nameLen = 0;
Haibo Huang40a71912019-10-11 11:13:39 -07005109 for (; name[nameLen++];)
5110 ;
Sadaf Ebrahimifcfab022022-06-03 03:40:21 +00005111
5112 /* Detect and prevent integer overflow */
5113 if (nameLen > UINT_MAX - dtd->contentStringLen) {
5114 return XML_ERROR_NO_MEMORY;
5115 }
5116
5117 dtd->contentStringLen += (unsigned)nameLen;
Elliott Hughes72472942018-01-10 08:36:10 -08005118 if (parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005119 handleDefault = XML_FALSE;
5120 }
5121 break;
5122
5123 case XML_ROLE_GROUP_CLOSE:
5124 quant = XML_CQUANT_NONE;
5125 goto closeGroup;
5126 case XML_ROLE_GROUP_CLOSE_OPT:
5127 quant = XML_CQUANT_OPT;
5128 goto closeGroup;
5129 case XML_ROLE_GROUP_CLOSE_REP:
5130 quant = XML_CQUANT_REP;
5131 goto closeGroup;
5132 case XML_ROLE_GROUP_CLOSE_PLUS:
5133 quant = XML_CQUANT_PLUS;
5134 closeGroup:
5135 if (dtd->in_eldecl) {
Elliott Hughes72472942018-01-10 08:36:10 -08005136 if (parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005137 handleDefault = XML_FALSE;
5138 dtd->scaffLevel--;
5139 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
5140 if (dtd->scaffLevel == 0) {
Haibo Huang40a71912019-10-11 11:13:39 -07005141 if (! handleDefault) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005142 XML_Content *model = build_model(parser);
Haibo Huang40a71912019-10-11 11:13:39 -07005143 if (! model)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005144 return XML_ERROR_NO_MEMORY;
5145 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07005146 parser->m_elementDeclHandler(
5147 parser->m_handlerArg, parser->m_declElementType->name, model);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005148 }
5149 dtd->in_eldecl = XML_FALSE;
5150 dtd->contentStringLen = 0;
5151 }
5152 }
5153 break;
5154 /* End element declaration stuff */
5155
5156 case XML_ROLE_PI:
Haibo Huang40a71912019-10-11 11:13:39 -07005157 if (! reportProcessingInstruction(parser, enc, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005158 return XML_ERROR_NO_MEMORY;
5159 handleDefault = XML_FALSE;
5160 break;
5161 case XML_ROLE_COMMENT:
Haibo Huang40a71912019-10-11 11:13:39 -07005162 if (! reportComment(parser, enc, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005163 return XML_ERROR_NO_MEMORY;
5164 handleDefault = XML_FALSE;
5165 break;
5166 case XML_ROLE_NONE:
5167 switch (tok) {
5168 case XML_TOK_BOM:
5169 handleDefault = XML_FALSE;
5170 break;
5171 }
5172 break;
5173 case XML_ROLE_DOCTYPE_NONE:
Elliott Hughes72472942018-01-10 08:36:10 -08005174 if (parser->m_startDoctypeDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005175 handleDefault = XML_FALSE;
5176 break;
5177 case XML_ROLE_ENTITY_NONE:
Elliott Hughes72472942018-01-10 08:36:10 -08005178 if (dtd->keepProcessing && parser->m_entityDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005179 handleDefault = XML_FALSE;
5180 break;
5181 case XML_ROLE_NOTATION_NONE:
Elliott Hughes72472942018-01-10 08:36:10 -08005182 if (parser->m_notationDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005183 handleDefault = XML_FALSE;
5184 break;
5185 case XML_ROLE_ATTLIST_NONE:
Elliott Hughes72472942018-01-10 08:36:10 -08005186 if (dtd->keepProcessing && parser->m_attlistDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005187 handleDefault = XML_FALSE;
5188 break;
5189 case XML_ROLE_ELEMENT_NONE:
Elliott Hughes72472942018-01-10 08:36:10 -08005190 if (parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005191 handleDefault = XML_FALSE;
5192 break;
5193 } /* end of big switch */
5194
Elliott Hughes72472942018-01-10 08:36:10 -08005195 if (handleDefault && parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005196 reportDefault(parser, enc, s, next);
5197
Elliott Hughes72472942018-01-10 08:36:10 -08005198 switch (parser->m_parsingStatus.parsing) {
Elliott Hughes35e432d2012-09-09 14:23:38 -07005199 case XML_SUSPENDED:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005200 *nextPtr = next;
5201 return XML_ERROR_NONE;
5202 case XML_FINISHED:
5203 return XML_ERROR_ABORTED;
5204 default:
5205 s = next;
5206 tok = XmlPrologTok(enc, s, end, &next);
5207 }
5208 }
5209 /* not reached */
5210}
5211
5212static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07005213epilogProcessor(XML_Parser parser, const char *s, const char *end,
5214 const char **nextPtr) {
Elliott Hughes72472942018-01-10 08:36:10 -08005215 parser->m_processor = epilogProcessor;
5216 parser->m_eventPtr = s;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005217 for (;;) {
5218 const char *next = NULL;
Elliott Hughes72472942018-01-10 08:36:10 -08005219 int tok = XmlPrologTok(parser->m_encoding, s, end, &next);
5220 parser->m_eventEndPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005221 switch (tok) {
5222 /* report partial linebreak - it might be the last token */
5223 case -XML_TOK_PROLOG_S:
Elliott Hughes72472942018-01-10 08:36:10 -08005224 if (parser->m_defaultHandler) {
5225 reportDefault(parser, parser->m_encoding, s, next);
5226 if (parser->m_parsingStatus.parsing == XML_FINISHED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005227 return XML_ERROR_ABORTED;
5228 }
5229 *nextPtr = next;
5230 return XML_ERROR_NONE;
5231 case XML_TOK_NONE:
5232 *nextPtr = s;
5233 return XML_ERROR_NONE;
5234 case XML_TOK_PROLOG_S:
Elliott Hughes72472942018-01-10 08:36:10 -08005235 if (parser->m_defaultHandler)
5236 reportDefault(parser, parser->m_encoding, s, next);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005237 break;
5238 case XML_TOK_PI:
Haibo Huang40a71912019-10-11 11:13:39 -07005239 if (! reportProcessingInstruction(parser, parser->m_encoding, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005240 return XML_ERROR_NO_MEMORY;
5241 break;
5242 case XML_TOK_COMMENT:
Haibo Huang40a71912019-10-11 11:13:39 -07005243 if (! reportComment(parser, parser->m_encoding, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005244 return XML_ERROR_NO_MEMORY;
5245 break;
5246 case XML_TOK_INVALID:
Elliott Hughes72472942018-01-10 08:36:10 -08005247 parser->m_eventPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005248 return XML_ERROR_INVALID_TOKEN;
5249 case XML_TOK_PARTIAL:
Haibo Huang40a71912019-10-11 11:13:39 -07005250 if (! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005251 *nextPtr = s;
5252 return XML_ERROR_NONE;
5253 }
5254 return XML_ERROR_UNCLOSED_TOKEN;
5255 case XML_TOK_PARTIAL_CHAR:
Haibo Huang40a71912019-10-11 11:13:39 -07005256 if (! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005257 *nextPtr = s;
5258 return XML_ERROR_NONE;
5259 }
5260 return XML_ERROR_PARTIAL_CHAR;
5261 default:
5262 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
5263 }
Elliott Hughes72472942018-01-10 08:36:10 -08005264 parser->m_eventPtr = s = next;
5265 switch (parser->m_parsingStatus.parsing) {
Elliott Hughes35e432d2012-09-09 14:23:38 -07005266 case XML_SUSPENDED:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005267 *nextPtr = next;
5268 return XML_ERROR_NONE;
5269 case XML_FINISHED:
5270 return XML_ERROR_ABORTED;
Haibo Huang40a71912019-10-11 11:13:39 -07005271 default:;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005272 }
5273 }
5274}
5275
5276static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07005277processInternalEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005278 const char *textStart, *textEnd;
5279 const char *next;
5280 enum XML_Error result;
5281 OPEN_INTERNAL_ENTITY *openEntity;
5282
Elliott Hughes72472942018-01-10 08:36:10 -08005283 if (parser->m_freeInternalEntities) {
5284 openEntity = parser->m_freeInternalEntities;
5285 parser->m_freeInternalEntities = openEntity->next;
Haibo Huang40a71912019-10-11 11:13:39 -07005286 } else {
5287 openEntity
5288 = (OPEN_INTERNAL_ENTITY *)MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY));
5289 if (! openEntity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005290 return XML_ERROR_NO_MEMORY;
5291 }
5292 entity->open = XML_TRUE;
5293 entity->processed = 0;
Elliott Hughes72472942018-01-10 08:36:10 -08005294 openEntity->next = parser->m_openInternalEntities;
5295 parser->m_openInternalEntities = openEntity;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005296 openEntity->entity = entity;
Elliott Hughes72472942018-01-10 08:36:10 -08005297 openEntity->startTagLevel = parser->m_tagLevel;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005298 openEntity->betweenDecl = betweenDecl;
5299 openEntity->internalEventPtr = NULL;
5300 openEntity->internalEventEndPtr = NULL;
Haibo Huangd1a324a2020-10-28 22:19:36 -07005301 textStart = (const char *)entity->textPtr;
5302 textEnd = (const char *)(entity->textPtr + entity->textLen);
Elliott Hughes72472942018-01-10 08:36:10 -08005303 /* Set a safe default value in case 'next' does not get set */
5304 next = textStart;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005305
5306#ifdef XML_DTD
5307 if (entity->is_param) {
Haibo Huang40a71912019-10-11 11:13:39 -07005308 int tok
5309 = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
5310 result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
5311 tok, next, &next, XML_FALSE, XML_FALSE);
5312 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005313#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07005314 result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding,
5315 textStart, textEnd, &next, XML_FALSE);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005316
5317 if (result == XML_ERROR_NONE) {
Elliott Hughes72472942018-01-10 08:36:10 -08005318 if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005319 entity->processed = (int)(next - textStart);
Elliott Hughes72472942018-01-10 08:36:10 -08005320 parser->m_processor = internalEntityProcessor;
Haibo Huang40a71912019-10-11 11:13:39 -07005321 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005322 entity->open = XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08005323 parser->m_openInternalEntities = openEntity->next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005324 /* put openEntity back in list of free instances */
Elliott Hughes72472942018-01-10 08:36:10 -08005325 openEntity->next = parser->m_freeInternalEntities;
5326 parser->m_freeInternalEntities = openEntity;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005327 }
5328 }
5329 return result;
5330}
5331
5332static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07005333internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
5334 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005335 ENTITY *entity;
5336 const char *textStart, *textEnd;
5337 const char *next;
5338 enum XML_Error result;
Elliott Hughes72472942018-01-10 08:36:10 -08005339 OPEN_INTERNAL_ENTITY *openEntity = parser->m_openInternalEntities;
Haibo Huang40a71912019-10-11 11:13:39 -07005340 if (! openEntity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005341 return XML_ERROR_UNEXPECTED_STATE;
5342
5343 entity = openEntity->entity;
Haibo Huangd1a324a2020-10-28 22:19:36 -07005344 textStart = ((const char *)entity->textPtr) + entity->processed;
5345 textEnd = (const char *)(entity->textPtr + entity->textLen);
Elliott Hughes72472942018-01-10 08:36:10 -08005346 /* Set a safe default value in case 'next' does not get set */
5347 next = textStart;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005348
5349#ifdef XML_DTD
5350 if (entity->is_param) {
Haibo Huang40a71912019-10-11 11:13:39 -07005351 int tok
5352 = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
5353 result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
5354 tok, next, &next, XML_FALSE, XML_TRUE);
5355 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005356#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07005357 result = doContent(parser, openEntity->startTagLevel,
5358 parser->m_internalEncoding, textStart, textEnd, &next,
5359 XML_FALSE);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005360
5361 if (result != XML_ERROR_NONE)
5362 return result;
Haibo Huang40a71912019-10-11 11:13:39 -07005363 else if (textEnd != next
5364 && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
Haibo Huangd1a324a2020-10-28 22:19:36 -07005365 entity->processed = (int)(next - (const char *)entity->textPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005366 return result;
Haibo Huang40a71912019-10-11 11:13:39 -07005367 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005368 entity->open = XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08005369 parser->m_openInternalEntities = openEntity->next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005370 /* put openEntity back in list of free instances */
Elliott Hughes72472942018-01-10 08:36:10 -08005371 openEntity->next = parser->m_freeInternalEntities;
5372 parser->m_freeInternalEntities = openEntity;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005373 }
5374
5375#ifdef XML_DTD
5376 if (entity->is_param) {
5377 int tok;
Elliott Hughes72472942018-01-10 08:36:10 -08005378 parser->m_processor = prologProcessor;
5379 tok = XmlPrologTok(parser->m_encoding, s, end, &next);
5380 return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
Haibo Huang40a71912019-10-11 11:13:39 -07005381 (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE);
5382 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005383#endif /* XML_DTD */
5384 {
Elliott Hughes72472942018-01-10 08:36:10 -08005385 parser->m_processor = contentProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005386 /* see externalEntityContentProcessor vs contentProcessor */
Haibo Huang40a71912019-10-11 11:13:39 -07005387 return doContent(parser, parser->m_parentParser ? 1 : 0, parser->m_encoding,
5388 s, end, nextPtr,
5389 (XML_Bool)! parser->m_parsingStatus.finalBuffer);
Elliott Hughes35e432d2012-09-09 14:23:38 -07005390 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005391}
5392
5393static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07005394errorProcessor(XML_Parser parser, const char *s, const char *end,
5395 const char **nextPtr) {
5396 UNUSED_P(s);
5397 UNUSED_P(end);
5398 UNUSED_P(nextPtr);
Elliott Hughes72472942018-01-10 08:36:10 -08005399 return parser->m_errorCode;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005400}
5401
5402static enum XML_Error
5403storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
Haibo Huang40a71912019-10-11 11:13:39 -07005404 const char *ptr, const char *end, STRING_POOL *pool) {
5405 enum XML_Error result
5406 = appendAttributeValue(parser, enc, isCdata, ptr, end, pool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005407 if (result)
5408 return result;
Haibo Huang40a71912019-10-11 11:13:39 -07005409 if (! isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005410 poolChop(pool);
Haibo Huang40a71912019-10-11 11:13:39 -07005411 if (! poolAppendChar(pool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005412 return XML_ERROR_NO_MEMORY;
5413 return XML_ERROR_NONE;
5414}
5415
5416static enum XML_Error
5417appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
Haibo Huang40a71912019-10-11 11:13:39 -07005418 const char *ptr, const char *end, STRING_POOL *pool) {
5419 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005420 for (;;) {
5421 const char *next;
5422 int tok = XmlAttributeValueTok(enc, ptr, end, &next);
5423 switch (tok) {
5424 case XML_TOK_NONE:
5425 return XML_ERROR_NONE;
5426 case XML_TOK_INVALID:
Elliott Hughes72472942018-01-10 08:36:10 -08005427 if (enc == parser->m_encoding)
5428 parser->m_eventPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005429 return XML_ERROR_INVALID_TOKEN;
5430 case XML_TOK_PARTIAL:
Elliott Hughes72472942018-01-10 08:36:10 -08005431 if (enc == parser->m_encoding)
5432 parser->m_eventPtr = ptr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005433 return XML_ERROR_INVALID_TOKEN;
Haibo Huang40a71912019-10-11 11:13:39 -07005434 case XML_TOK_CHAR_REF: {
5435 XML_Char buf[XML_ENCODE_MAX];
5436 int i;
5437 int n = XmlCharRefNumber(enc, ptr);
5438 if (n < 0) {
5439 if (enc == parser->m_encoding)
5440 parser->m_eventPtr = ptr;
5441 return XML_ERROR_BAD_CHAR_REF;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005442 }
Haibo Huang40a71912019-10-11 11:13:39 -07005443 if (! isCdata && n == 0x20 /* space */
5444 && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
5445 break;
5446 n = XmlEncode(n, (ICHAR *)buf);
5447 /* The XmlEncode() functions can never return 0 here. That
5448 * error return happens if the code point passed in is either
5449 * negative or greater than or equal to 0x110000. The
5450 * XmlCharRefNumber() functions will all return a number
5451 * strictly less than 0x110000 or a negative value if an error
5452 * occurred. The negative value is intercepted above, so
5453 * XmlEncode() is never passed a value it might return an
5454 * error for.
5455 */
5456 for (i = 0; i < n; i++) {
5457 if (! poolAppendChar(pool, buf[i]))
5458 return XML_ERROR_NO_MEMORY;
5459 }
5460 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005461 case XML_TOK_DATA_CHARS:
Haibo Huang40a71912019-10-11 11:13:39 -07005462 if (! poolAppend(pool, enc, ptr, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005463 return XML_ERROR_NO_MEMORY;
5464 break;
5465 case XML_TOK_TRAILING_CR:
5466 next = ptr + enc->minBytesPerChar;
5467 /* fall through */
5468 case XML_TOK_ATTRIBUTE_VALUE_S:
5469 case XML_TOK_DATA_NEWLINE:
Haibo Huang40a71912019-10-11 11:13:39 -07005470 if (! isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005471 break;
Haibo Huang40a71912019-10-11 11:13:39 -07005472 if (! poolAppendChar(pool, 0x20))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005473 return XML_ERROR_NO_MEMORY;
5474 break;
Haibo Huang40a71912019-10-11 11:13:39 -07005475 case XML_TOK_ENTITY_REF: {
5476 const XML_Char *name;
5477 ENTITY *entity;
5478 char checkEntityDecl;
5479 XML_Char ch = (XML_Char)XmlPredefinedEntityName(
5480 enc, ptr + enc->minBytesPerChar, next - enc->minBytesPerChar);
5481 if (ch) {
5482 if (! poolAppendChar(pool, ch))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005483 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07005484 break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005485 }
Haibo Huang40a71912019-10-11 11:13:39 -07005486 name = poolStoreString(&parser->m_temp2Pool, enc,
5487 ptr + enc->minBytesPerChar,
5488 next - enc->minBytesPerChar);
5489 if (! name)
5490 return XML_ERROR_NO_MEMORY;
5491 entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
5492 poolDiscard(&parser->m_temp2Pool);
5493 /* First, determine if a check for an existing declaration is needed;
5494 if yes, check that the entity exists, and that it is internal.
5495 */
5496 if (pool == &dtd->pool) /* are we called from prolog? */
5497 checkEntityDecl =
5498#ifdef XML_DTD
5499 parser->m_prologState.documentEntity &&
5500#endif /* XML_DTD */
5501 (dtd->standalone ? ! parser->m_openInternalEntities
5502 : ! dtd->hasParamEntityRefs);
5503 else /* if (pool == &parser->m_tempPool): we are called from content */
5504 checkEntityDecl = ! dtd->hasParamEntityRefs || dtd->standalone;
5505 if (checkEntityDecl) {
5506 if (! entity)
5507 return XML_ERROR_UNDEFINED_ENTITY;
5508 else if (! entity->is_internal)
5509 return XML_ERROR_ENTITY_DECLARED_IN_PE;
5510 } else if (! entity) {
5511 /* Cannot report skipped entity here - see comments on
5512 parser->m_skippedEntityHandler.
5513 if (parser->m_skippedEntityHandler)
5514 parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
5515 */
5516 /* Cannot call the default handler because this would be
5517 out of sync with the call to the startElementHandler.
5518 if ((pool == &parser->m_tempPool) && parser->m_defaultHandler)
5519 reportDefault(parser, enc, ptr, next);
5520 */
5521 break;
5522 }
5523 if (entity->open) {
5524 if (enc == parser->m_encoding) {
5525 /* It does not appear that this line can be executed.
5526 *
5527 * The "if (entity->open)" check catches recursive entity
5528 * definitions. In order to be called with an open
5529 * entity, it must have gone through this code before and
5530 * been through the recursive call to
5531 * appendAttributeValue() some lines below. That call
5532 * sets the local encoding ("enc") to the parser's
5533 * internal encoding (internal_utf8 or internal_utf16),
5534 * which can never be the same as the principle encoding.
5535 * It doesn't appear there is another code path that gets
5536 * here with entity->open being TRUE.
5537 *
5538 * Since it is not certain that this logic is watertight,
5539 * we keep the line and merely exclude it from coverage
5540 * tests.
5541 */
5542 parser->m_eventPtr = ptr; /* LCOV_EXCL_LINE */
5543 }
5544 return XML_ERROR_RECURSIVE_ENTITY_REF;
5545 }
5546 if (entity->notation) {
5547 if (enc == parser->m_encoding)
5548 parser->m_eventPtr = ptr;
5549 return XML_ERROR_BINARY_ENTITY_REF;
5550 }
5551 if (! entity->textPtr) {
5552 if (enc == parser->m_encoding)
5553 parser->m_eventPtr = ptr;
5554 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
5555 } else {
5556 enum XML_Error result;
5557 const XML_Char *textEnd = entity->textPtr + entity->textLen;
5558 entity->open = XML_TRUE;
5559 result = appendAttributeValue(parser, parser->m_internalEncoding,
Haibo Huangd1a324a2020-10-28 22:19:36 -07005560 isCdata, (const char *)entity->textPtr,
5561 (const char *)textEnd, pool);
Haibo Huang40a71912019-10-11 11:13:39 -07005562 entity->open = XML_FALSE;
5563 if (result)
5564 return result;
5565 }
5566 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005567 default:
Elliott Hughes72472942018-01-10 08:36:10 -08005568 /* The only token returned by XmlAttributeValueTok() that does
5569 * not have an explicit case here is XML_TOK_PARTIAL_CHAR.
5570 * Getting that would require an entity name to contain an
5571 * incomplete XML character (e.g. \xE2\x82); however previous
5572 * tokenisers will have already recognised and rejected such
5573 * names before XmlAttributeValueTok() gets a look-in. This
5574 * default case should be retained as a safety net, but the code
5575 * excluded from coverage tests.
5576 *
5577 * LCOV_EXCL_START
5578 */
5579 if (enc == parser->m_encoding)
5580 parser->m_eventPtr = ptr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005581 return XML_ERROR_UNEXPECTED_STATE;
Elliott Hughes72472942018-01-10 08:36:10 -08005582 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005583 }
5584 ptr = next;
5585 }
5586 /* not reached */
5587}
5588
5589static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07005590storeEntityValue(XML_Parser parser, const ENCODING *enc,
5591 const char *entityTextPtr, const char *entityTextEnd) {
5592 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005593 STRING_POOL *pool = &(dtd->entityValuePool);
5594 enum XML_Error result = XML_ERROR_NONE;
5595#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08005596 int oldInEntityValue = parser->m_prologState.inEntityValue;
5597 parser->m_prologState.inEntityValue = 1;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005598#endif /* XML_DTD */
5599 /* never return Null for the value argument in EntityDeclHandler,
5600 since this would indicate an external entity; therefore we
5601 have to make sure that entityValuePool.start is not null */
Haibo Huang40a71912019-10-11 11:13:39 -07005602 if (! pool->blocks) {
5603 if (! poolGrow(pool))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005604 return XML_ERROR_NO_MEMORY;
5605 }
5606
5607 for (;;) {
5608 const char *next;
5609 int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
5610 switch (tok) {
5611 case XML_TOK_PARAM_ENTITY_REF:
5612#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08005613 if (parser->m_isParamEntity || enc != parser->m_encoding) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005614 const XML_Char *name;
5615 ENTITY *entity;
Elliott Hughes72472942018-01-10 08:36:10 -08005616 name = poolStoreString(&parser->m_tempPool, enc,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005617 entityTextPtr + enc->minBytesPerChar,
5618 next - enc->minBytesPerChar);
Haibo Huang40a71912019-10-11 11:13:39 -07005619 if (! name) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005620 result = XML_ERROR_NO_MEMORY;
5621 goto endEntityValue;
5622 }
Elliott Hughes35e432d2012-09-09 14:23:38 -07005623 entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
Elliott Hughes72472942018-01-10 08:36:10 -08005624 poolDiscard(&parser->m_tempPool);
Haibo Huang40a71912019-10-11 11:13:39 -07005625 if (! entity) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005626 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
5627 /* cannot report skipped entity here - see comments on
Elliott Hughes72472942018-01-10 08:36:10 -08005628 parser->m_skippedEntityHandler
5629 if (parser->m_skippedEntityHandler)
5630 parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005631 */
5632 dtd->keepProcessing = dtd->standalone;
5633 goto endEntityValue;
5634 }
5635 if (entity->open) {
Elliott Hughes72472942018-01-10 08:36:10 -08005636 if (enc == parser->m_encoding)
5637 parser->m_eventPtr = entityTextPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005638 result = XML_ERROR_RECURSIVE_ENTITY_REF;
5639 goto endEntityValue;
5640 }
5641 if (entity->systemId) {
Elliott Hughes72472942018-01-10 08:36:10 -08005642 if (parser->m_externalEntityRefHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005643 dtd->paramEntityRead = XML_FALSE;
5644 entity->open = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07005645 if (! parser->m_externalEntityRefHandler(
5646 parser->m_externalEntityRefHandlerArg, 0, entity->base,
5647 entity->systemId, entity->publicId)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005648 entity->open = XML_FALSE;
5649 result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
5650 goto endEntityValue;
5651 }
5652 entity->open = XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07005653 if (! dtd->paramEntityRead)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005654 dtd->keepProcessing = dtd->standalone;
Haibo Huang40a71912019-10-11 11:13:39 -07005655 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005656 dtd->keepProcessing = dtd->standalone;
Haibo Huang40a71912019-10-11 11:13:39 -07005657 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005658 entity->open = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07005659 result = storeEntityValue(
Haibo Huangd1a324a2020-10-28 22:19:36 -07005660 parser, parser->m_internalEncoding, (const char *)entity->textPtr,
5661 (const char *)(entity->textPtr + entity->textLen));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005662 entity->open = XML_FALSE;
5663 if (result)
5664 goto endEntityValue;
5665 }
5666 break;
5667 }
5668#endif /* XML_DTD */
5669 /* In the internal subset, PE references are not legal
5670 within markup declarations, e.g entity values in this case. */
Elliott Hughes72472942018-01-10 08:36:10 -08005671 parser->m_eventPtr = entityTextPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005672 result = XML_ERROR_PARAM_ENTITY_REF;
5673 goto endEntityValue;
5674 case XML_TOK_NONE:
5675 result = XML_ERROR_NONE;
5676 goto endEntityValue;
5677 case XML_TOK_ENTITY_REF:
5678 case XML_TOK_DATA_CHARS:
Haibo Huang40a71912019-10-11 11:13:39 -07005679 if (! poolAppend(pool, enc, entityTextPtr, next)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005680 result = XML_ERROR_NO_MEMORY;
5681 goto endEntityValue;
5682 }
5683 break;
5684 case XML_TOK_TRAILING_CR:
5685 next = entityTextPtr + enc->minBytesPerChar;
5686 /* fall through */
5687 case XML_TOK_DATA_NEWLINE:
Haibo Huang40a71912019-10-11 11:13:39 -07005688 if (pool->end == pool->ptr && ! poolGrow(pool)) {
5689 result = XML_ERROR_NO_MEMORY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005690 goto endEntityValue;
5691 }
5692 *(pool->ptr)++ = 0xA;
5693 break;
Haibo Huang40a71912019-10-11 11:13:39 -07005694 case XML_TOK_CHAR_REF: {
5695 XML_Char buf[XML_ENCODE_MAX];
5696 int i;
5697 int n = XmlCharRefNumber(enc, entityTextPtr);
5698 if (n < 0) {
5699 if (enc == parser->m_encoding)
5700 parser->m_eventPtr = entityTextPtr;
5701 result = XML_ERROR_BAD_CHAR_REF;
5702 goto endEntityValue;
5703 }
5704 n = XmlEncode(n, (ICHAR *)buf);
5705 /* The XmlEncode() functions can never return 0 here. That
5706 * error return happens if the code point passed in is either
5707 * negative or greater than or equal to 0x110000. The
5708 * XmlCharRefNumber() functions will all return a number
5709 * strictly less than 0x110000 or a negative value if an error
5710 * occurred. The negative value is intercepted above, so
5711 * XmlEncode() is never passed a value it might return an
5712 * error for.
5713 */
5714 for (i = 0; i < n; i++) {
5715 if (pool->end == pool->ptr && ! poolGrow(pool)) {
5716 result = XML_ERROR_NO_MEMORY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005717 goto endEntityValue;
5718 }
Haibo Huang40a71912019-10-11 11:13:39 -07005719 *(pool->ptr)++ = buf[i];
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005720 }
Haibo Huang40a71912019-10-11 11:13:39 -07005721 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005722 case XML_TOK_PARTIAL:
Elliott Hughes72472942018-01-10 08:36:10 -08005723 if (enc == parser->m_encoding)
5724 parser->m_eventPtr = entityTextPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005725 result = XML_ERROR_INVALID_TOKEN;
5726 goto endEntityValue;
5727 case XML_TOK_INVALID:
Elliott Hughes72472942018-01-10 08:36:10 -08005728 if (enc == parser->m_encoding)
5729 parser->m_eventPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005730 result = XML_ERROR_INVALID_TOKEN;
5731 goto endEntityValue;
5732 default:
Elliott Hughes72472942018-01-10 08:36:10 -08005733 /* This default case should be unnecessary -- all the tokens
5734 * that XmlEntityValueTok() can return have their own explicit
5735 * cases -- but should be retained for safety. We do however
5736 * exclude it from the coverage statistics.
5737 *
5738 * LCOV_EXCL_START
5739 */
5740 if (enc == parser->m_encoding)
5741 parser->m_eventPtr = entityTextPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005742 result = XML_ERROR_UNEXPECTED_STATE;
5743 goto endEntityValue;
Elliott Hughes72472942018-01-10 08:36:10 -08005744 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005745 }
5746 entityTextPtr = next;
5747 }
5748endEntityValue:
5749#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08005750 parser->m_prologState.inEntityValue = oldInEntityValue;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005751#endif /* XML_DTD */
5752 return result;
5753}
5754
5755static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07005756normalizeLines(XML_Char *s) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005757 XML_Char *p;
5758 for (;; s++) {
5759 if (*s == XML_T('\0'))
5760 return;
5761 if (*s == 0xD)
5762 break;
5763 }
5764 p = s;
5765 do {
5766 if (*s == 0xD) {
5767 *p++ = 0xA;
5768 if (*++s == 0xA)
5769 s++;
Haibo Huang40a71912019-10-11 11:13:39 -07005770 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005771 *p++ = *s++;
5772 } while (*s);
5773 *p = XML_T('\0');
5774}
5775
5776static int
5777reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
Haibo Huang40a71912019-10-11 11:13:39 -07005778 const char *start, const char *end) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005779 const XML_Char *target;
5780 XML_Char *data;
5781 const char *tem;
Haibo Huang40a71912019-10-11 11:13:39 -07005782 if (! parser->m_processingInstructionHandler) {
Elliott Hughes72472942018-01-10 08:36:10 -08005783 if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005784 reportDefault(parser, enc, start, end);
5785 return 1;
5786 }
5787 start += enc->minBytesPerChar * 2;
5788 tem = start + XmlNameLength(enc, start);
Elliott Hughes72472942018-01-10 08:36:10 -08005789 target = poolStoreString(&parser->m_tempPool, enc, start, tem);
Haibo Huang40a71912019-10-11 11:13:39 -07005790 if (! target)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005791 return 0;
Elliott Hughes72472942018-01-10 08:36:10 -08005792 poolFinish(&parser->m_tempPool);
Haibo Huang40a71912019-10-11 11:13:39 -07005793 data = poolStoreString(&parser->m_tempPool, enc, XmlSkipS(enc, tem),
5794 end - enc->minBytesPerChar * 2);
5795 if (! data)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005796 return 0;
5797 normalizeLines(data);
Elliott Hughes72472942018-01-10 08:36:10 -08005798 parser->m_processingInstructionHandler(parser->m_handlerArg, target, data);
5799 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005800 return 1;
5801}
5802
5803static int
Haibo Huang40a71912019-10-11 11:13:39 -07005804reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
5805 const char *end) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005806 XML_Char *data;
Haibo Huang40a71912019-10-11 11:13:39 -07005807 if (! parser->m_commentHandler) {
Elliott Hughes72472942018-01-10 08:36:10 -08005808 if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005809 reportDefault(parser, enc, start, end);
5810 return 1;
5811 }
Haibo Huang40a71912019-10-11 11:13:39 -07005812 data = poolStoreString(&parser->m_tempPool, enc,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005813 start + enc->minBytesPerChar * 4,
5814 end - enc->minBytesPerChar * 3);
Haibo Huang40a71912019-10-11 11:13:39 -07005815 if (! data)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005816 return 0;
5817 normalizeLines(data);
Elliott Hughes72472942018-01-10 08:36:10 -08005818 parser->m_commentHandler(parser->m_handlerArg, data);
5819 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005820 return 1;
5821}
5822
5823static void
Haibo Huang40a71912019-10-11 11:13:39 -07005824reportDefault(XML_Parser parser, const ENCODING *enc, const char *s,
5825 const char *end) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005826 if (MUST_CONVERT(enc, s)) {
Paul Duffin4bf8f122016-05-13 12:35:25 +01005827 enum XML_Convert_Result convert_res;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005828 const char **eventPP;
5829 const char **eventEndPP;
Elliott Hughes72472942018-01-10 08:36:10 -08005830 if (enc == parser->m_encoding) {
5831 eventPP = &parser->m_eventPtr;
5832 eventEndPP = &parser->m_eventEndPtr;
Haibo Huang40a71912019-10-11 11:13:39 -07005833 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08005834 /* To get here, two things must be true; the parser must be
5835 * using a character encoding that is not the same as the
5836 * encoding passed in, and the encoding passed in must need
5837 * conversion to the internal format (UTF-8 unless XML_UNICODE
5838 * is defined). The only occasions on which the encoding passed
5839 * in is not the same as the parser's encoding are when it is
5840 * the internal encoding (e.g. a previously defined parameter
5841 * entity, already converted to internal format). This by
5842 * definition doesn't need conversion, so the whole branch never
5843 * gets executed.
5844 *
5845 * For safety's sake we don't delete these lines and merely
5846 * exclude them from coverage statistics.
5847 *
5848 * LCOV_EXCL_START
5849 */
5850 eventPP = &(parser->m_openInternalEntities->internalEventPtr);
5851 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
5852 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005853 }
5854 do {
Elliott Hughes72472942018-01-10 08:36:10 -08005855 ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
Haibo Huang40a71912019-10-11 11:13:39 -07005856 convert_res
5857 = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005858 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07005859 parser->m_defaultHandler(parser->m_handlerArg, parser->m_dataBuf,
5860 (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005861 *eventPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07005862 } while ((convert_res != XML_CONVERT_COMPLETED)
5863 && (convert_res != XML_CONVERT_INPUT_INCOMPLETE));
5864 } else
5865 parser->m_defaultHandler(parser->m_handlerArg, (XML_Char *)s,
5866 (int)((XML_Char *)end - (XML_Char *)s));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005867}
5868
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005869static int
5870defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
Haibo Huang40a71912019-10-11 11:13:39 -07005871 XML_Bool isId, const XML_Char *value, XML_Parser parser) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005872 DEFAULT_ATTRIBUTE *att;
5873 if (value || isId) {
5874 /* The handling of default attributes gets messed up if we have
5875 a default which duplicates a non-default. */
5876 int i;
5877 for (i = 0; i < type->nDefaultAtts; i++)
5878 if (attId == type->defaultAtts[i].id)
5879 return 1;
Haibo Huang40a71912019-10-11 11:13:39 -07005880 if (isId && ! type->idAtt && ! attId->xmlns)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005881 type->idAtt = attId;
5882 }
5883 if (type->nDefaultAtts == type->allocDefaultAtts) {
5884 if (type->allocDefaultAtts == 0) {
5885 type->allocDefaultAtts = 8;
Haibo Huang40a71912019-10-11 11:13:39 -07005886 type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(
5887 parser, type->allocDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
5888 if (! type->defaultAtts) {
Elliott Hughes72472942018-01-10 08:36:10 -08005889 type->allocDefaultAtts = 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005890 return 0;
Elliott Hughes72472942018-01-10 08:36:10 -08005891 }
Haibo Huang40a71912019-10-11 11:13:39 -07005892 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005893 DEFAULT_ATTRIBUTE *temp;
Sadaf Ebrahimif68f6852022-06-15 04:14:33 +00005894
5895 /* Detect and prevent integer overflow */
5896 if (type->allocDefaultAtts > INT_MAX / 2) {
5897 return 0;
5898 }
5899
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005900 int count = type->allocDefaultAtts * 2;
Sadaf Ebrahimif68f6852022-06-15 04:14:33 +00005901
5902 /* Detect and prevent integer overflow.
5903 * The preprocessor guard addresses the "always false" warning
5904 * from -Wtype-limits on platforms where
5905 * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
5906#if UINT_MAX >= SIZE_MAX
5907 if ((unsigned)count > (size_t)(-1) / sizeof(DEFAULT_ATTRIBUTE)) {
5908 return 0;
5909 }
5910#endif
5911
Haibo Huang40a71912019-10-11 11:13:39 -07005912 temp = (DEFAULT_ATTRIBUTE *)REALLOC(parser, type->defaultAtts,
5913 (count * sizeof(DEFAULT_ATTRIBUTE)));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005914 if (temp == NULL)
5915 return 0;
5916 type->allocDefaultAtts = count;
5917 type->defaultAtts = temp;
5918 }
5919 }
5920 att = type->defaultAtts + type->nDefaultAtts;
5921 att->id = attId;
5922 att->value = value;
5923 att->isCdata = isCdata;
Haibo Huang40a71912019-10-11 11:13:39 -07005924 if (! isCdata)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005925 attId->maybeTokenized = XML_TRUE;
5926 type->nDefaultAtts += 1;
5927 return 1;
5928}
5929
5930static int
Haibo Huang40a71912019-10-11 11:13:39 -07005931setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType) {
5932 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005933 const XML_Char *name;
5934 for (name = elementType->name; *name; name++) {
Elliott Hughesd07d5a72009-09-25 16:04:37 -07005935 if (*name == XML_T(ASCII_COLON)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005936 PREFIX *prefix;
5937 const XML_Char *s;
5938 for (s = elementType->name; s != name; s++) {
Haibo Huang40a71912019-10-11 11:13:39 -07005939 if (! poolAppendChar(&dtd->pool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005940 return 0;
5941 }
Haibo Huang40a71912019-10-11 11:13:39 -07005942 if (! poolAppendChar(&dtd->pool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005943 return 0;
Elliott Hughes35e432d2012-09-09 14:23:38 -07005944 prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005945 sizeof(PREFIX));
Haibo Huang40a71912019-10-11 11:13:39 -07005946 if (! prefix)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005947 return 0;
5948 if (prefix->name == poolStart(&dtd->pool))
5949 poolFinish(&dtd->pool);
5950 else
5951 poolDiscard(&dtd->pool);
5952 elementType->prefix = prefix;
Haibo Huangfd5e81a2019-06-20 12:09:36 -07005953 break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005954 }
5955 }
5956 return 1;
5957}
5958
5959static ATTRIBUTE_ID *
Haibo Huang40a71912019-10-11 11:13:39 -07005960getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
5961 const char *end) {
5962 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005963 ATTRIBUTE_ID *id;
5964 const XML_Char *name;
Haibo Huang40a71912019-10-11 11:13:39 -07005965 if (! poolAppendChar(&dtd->pool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005966 return NULL;
5967 name = poolStoreString(&dtd->pool, enc, start, end);
Haibo Huang40a71912019-10-11 11:13:39 -07005968 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005969 return NULL;
5970 /* skip quotation mark - its storage will be re-used (like in name[-1]) */
5971 ++name;
Haibo Huang40a71912019-10-11 11:13:39 -07005972 id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name,
5973 sizeof(ATTRIBUTE_ID));
5974 if (! id)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005975 return NULL;
5976 if (id->name != name)
5977 poolDiscard(&dtd->pool);
5978 else {
5979 poolFinish(&dtd->pool);
Haibo Huang40a71912019-10-11 11:13:39 -07005980 if (! parser->m_ns)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005981 ;
Haibo Huang40a71912019-10-11 11:13:39 -07005982 else if (name[0] == XML_T(ASCII_x) && name[1] == XML_T(ASCII_m)
5983 && name[2] == XML_T(ASCII_l) && name[3] == XML_T(ASCII_n)
5984 && name[4] == XML_T(ASCII_s)
5985 && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005986 if (name[5] == XML_T('\0'))
5987 id->prefix = &dtd->defaultPrefix;
5988 else
Haibo Huang40a71912019-10-11 11:13:39 -07005989 id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6,
5990 sizeof(PREFIX));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005991 id->xmlns = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07005992 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005993 int i;
5994 for (i = 0; name[i]; i++) {
5995 /* attributes without prefix are *not* in the default namespace */
Elliott Hughesd07d5a72009-09-25 16:04:37 -07005996 if (name[i] == XML_T(ASCII_COLON)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005997 int j;
5998 for (j = 0; j < i; j++) {
Haibo Huang40a71912019-10-11 11:13:39 -07005999 if (! poolAppendChar(&dtd->pool, name[j]))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006000 return NULL;
6001 }
Haibo Huang40a71912019-10-11 11:13:39 -07006002 if (! poolAppendChar(&dtd->pool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006003 return NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07006004 id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes,
6005 poolStart(&dtd->pool), sizeof(PREFIX));
6006 if (! id->prefix)
Paul Duffinc05e0322016-05-04 10:42:31 +01006007 return NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006008 if (id->prefix->name == poolStart(&dtd->pool))
6009 poolFinish(&dtd->pool);
6010 else
6011 poolDiscard(&dtd->pool);
6012 break;
6013 }
6014 }
6015 }
6016 }
6017 return id;
6018}
6019
Elliott Hughesd07d5a72009-09-25 16:04:37 -07006020#define CONTEXT_SEP XML_T(ASCII_FF)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006021
6022static const XML_Char *
Haibo Huang40a71912019-10-11 11:13:39 -07006023getContext(XML_Parser parser) {
6024 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006025 HASH_TABLE_ITER iter;
6026 XML_Bool needSep = XML_FALSE;
6027
6028 if (dtd->defaultPrefix.binding) {
6029 int i;
6030 int len;
Haibo Huang40a71912019-10-11 11:13:39 -07006031 if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS)))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006032 return NULL;
6033 len = dtd->defaultPrefix.binding->uriLen;
Elliott Hughes72472942018-01-10 08:36:10 -08006034 if (parser->m_namespaceSeparator)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006035 len--;
Elliott Hughes72472942018-01-10 08:36:10 -08006036 for (i = 0; i < len; i++) {
Haibo Huang40a71912019-10-11 11:13:39 -07006037 if (! poolAppendChar(&parser->m_tempPool,
6038 dtd->defaultPrefix.binding->uri[i])) {
Elliott Hughes72472942018-01-10 08:36:10 -08006039 /* Because of memory caching, I don't believe this line can be
6040 * executed.
6041 *
6042 * This is part of a loop copying the default prefix binding
6043 * URI into the parser's temporary string pool. Previously,
6044 * that URI was copied into the same string pool, with a
6045 * terminating NUL character, as part of setContext(). When
6046 * the pool was cleared, that leaves a block definitely big
6047 * enough to hold the URI on the free block list of the pool.
6048 * The URI copy in getContext() therefore cannot run out of
6049 * memory.
6050 *
6051 * If the pool is used between the setContext() and
6052 * getContext() calls, the worst it can do is leave a bigger
6053 * block on the front of the free list. Given that this is
6054 * all somewhat inobvious and program logic can be changed, we
6055 * don't delete the line but we do exclude it from the test
6056 * coverage statistics.
6057 */
6058 return NULL; /* LCOV_EXCL_LINE */
6059 }
6060 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006061 needSep = XML_TRUE;
6062 }
6063
6064 hashTableIterInit(&iter, &(dtd->prefixes));
6065 for (;;) {
6066 int i;
6067 int len;
6068 const XML_Char *s;
6069 PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006070 if (! prefix)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006071 break;
Haibo Huang40a71912019-10-11 11:13:39 -07006072 if (! prefix->binding) {
Elliott Hughes72472942018-01-10 08:36:10 -08006073 /* This test appears to be (justifiable) paranoia. There does
6074 * not seem to be a way of injecting a prefix without a binding
6075 * that doesn't get errored long before this function is called.
6076 * The test should remain for safety's sake, so we instead
6077 * exclude the following line from the coverage statistics.
6078 */
6079 continue; /* LCOV_EXCL_LINE */
6080 }
Haibo Huang40a71912019-10-11 11:13:39 -07006081 if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006082 return NULL;
6083 for (s = prefix->name; *s; s++)
Haibo Huang40a71912019-10-11 11:13:39 -07006084 if (! poolAppendChar(&parser->m_tempPool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006085 return NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07006086 if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS)))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006087 return NULL;
6088 len = prefix->binding->uriLen;
Elliott Hughes72472942018-01-10 08:36:10 -08006089 if (parser->m_namespaceSeparator)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006090 len--;
6091 for (i = 0; i < len; i++)
Haibo Huang40a71912019-10-11 11:13:39 -07006092 if (! poolAppendChar(&parser->m_tempPool, prefix->binding->uri[i]))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006093 return NULL;
6094 needSep = XML_TRUE;
6095 }
6096
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006097 hashTableIterInit(&iter, &(dtd->generalEntities));
6098 for (;;) {
6099 const XML_Char *s;
6100 ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006101 if (! e)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006102 break;
Haibo Huang40a71912019-10-11 11:13:39 -07006103 if (! e->open)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006104 continue;
Haibo Huang40a71912019-10-11 11:13:39 -07006105 if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006106 return NULL;
6107 for (s = e->name; *s; s++)
Haibo Huang40a71912019-10-11 11:13:39 -07006108 if (! poolAppendChar(&parser->m_tempPool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006109 return 0;
6110 needSep = XML_TRUE;
6111 }
6112
Haibo Huang40a71912019-10-11 11:13:39 -07006113 if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006114 return NULL;
Elliott Hughes72472942018-01-10 08:36:10 -08006115 return parser->m_tempPool.start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006116}
6117
6118static XML_Bool
Haibo Huang40a71912019-10-11 11:13:39 -07006119setContext(XML_Parser parser, const XML_Char *context) {
6120 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006121 const XML_Char *s = context;
6122
6123 while (*context != XML_T('\0')) {
6124 if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
6125 ENTITY *e;
Haibo Huang40a71912019-10-11 11:13:39 -07006126 if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006127 return XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07006128 e = (ENTITY *)lookup(parser, &dtd->generalEntities,
6129 poolStart(&parser->m_tempPool), 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006130 if (e)
6131 e->open = XML_TRUE;
6132 if (*s != XML_T('\0'))
6133 s++;
6134 context = s;
Elliott Hughes72472942018-01-10 08:36:10 -08006135 poolDiscard(&parser->m_tempPool);
Haibo Huang40a71912019-10-11 11:13:39 -07006136 } else if (*s == XML_T(ASCII_EQUALS)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006137 PREFIX *prefix;
Elliott Hughes72472942018-01-10 08:36:10 -08006138 if (poolLength(&parser->m_tempPool) == 0)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006139 prefix = &dtd->defaultPrefix;
6140 else {
Haibo Huang40a71912019-10-11 11:13:39 -07006141 if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006142 return XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07006143 prefix
6144 = (PREFIX *)lookup(parser, &dtd->prefixes,
6145 poolStart(&parser->m_tempPool), sizeof(PREFIX));
6146 if (! prefix)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006147 return XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08006148 if (prefix->name == poolStart(&parser->m_tempPool)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006149 prefix->name = poolCopyString(&dtd->pool, prefix->name);
Haibo Huang40a71912019-10-11 11:13:39 -07006150 if (! prefix->name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006151 return XML_FALSE;
6152 }
Elliott Hughes72472942018-01-10 08:36:10 -08006153 poolDiscard(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006154 }
Haibo Huang40a71912019-10-11 11:13:39 -07006155 for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0');
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006156 context++)
Haibo Huang40a71912019-10-11 11:13:39 -07006157 if (! poolAppendChar(&parser->m_tempPool, *context))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006158 return XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07006159 if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006160 return XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08006161 if (addBinding(parser, prefix, NULL, poolStart(&parser->m_tempPool),
Haibo Huang40a71912019-10-11 11:13:39 -07006162 &parser->m_inheritedBindings)
6163 != XML_ERROR_NONE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006164 return XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08006165 poolDiscard(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006166 if (*context != XML_T('\0'))
6167 ++context;
6168 s = context;
Haibo Huang40a71912019-10-11 11:13:39 -07006169 } else {
6170 if (! poolAppendChar(&parser->m_tempPool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006171 return XML_FALSE;
6172 s++;
6173 }
6174 }
6175 return XML_TRUE;
6176}
6177
6178static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006179normalizePublicId(XML_Char *publicId) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006180 XML_Char *p = publicId;
6181 XML_Char *s;
6182 for (s = publicId; *s; s++) {
6183 switch (*s) {
6184 case 0x20:
6185 case 0xD:
6186 case 0xA:
6187 if (p != publicId && p[-1] != 0x20)
6188 *p++ = 0x20;
6189 break;
6190 default:
6191 *p++ = *s;
6192 }
6193 }
6194 if (p != publicId && p[-1] == 0x20)
6195 --p;
6196 *p = XML_T('\0');
6197}
6198
6199static DTD *
Haibo Huang40a71912019-10-11 11:13:39 -07006200dtdCreate(const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006201 DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
6202 if (p == NULL)
6203 return p;
6204 poolInit(&(p->pool), ms);
6205 poolInit(&(p->entityValuePool), ms);
6206 hashTableInit(&(p->generalEntities), ms);
6207 hashTableInit(&(p->elementTypes), ms);
6208 hashTableInit(&(p->attributeIds), ms);
6209 hashTableInit(&(p->prefixes), ms);
6210#ifdef XML_DTD
6211 p->paramEntityRead = XML_FALSE;
6212 hashTableInit(&(p->paramEntities), ms);
6213#endif /* XML_DTD */
6214 p->defaultPrefix.name = NULL;
6215 p->defaultPrefix.binding = NULL;
6216
6217 p->in_eldecl = XML_FALSE;
6218 p->scaffIndex = NULL;
6219 p->scaffold = NULL;
6220 p->scaffLevel = 0;
6221 p->scaffSize = 0;
6222 p->scaffCount = 0;
6223 p->contentStringLen = 0;
6224
6225 p->keepProcessing = XML_TRUE;
6226 p->hasParamEntityRefs = XML_FALSE;
6227 p->standalone = XML_FALSE;
6228 return p;
6229}
6230
6231static void
Haibo Huang40a71912019-10-11 11:13:39 -07006232dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006233 HASH_TABLE_ITER iter;
6234 hashTableIterInit(&iter, &(p->elementTypes));
6235 for (;;) {
6236 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006237 if (! e)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006238 break;
6239 if (e->allocDefaultAtts != 0)
6240 ms->free_fcn(e->defaultAtts);
6241 }
6242 hashTableClear(&(p->generalEntities));
6243#ifdef XML_DTD
6244 p->paramEntityRead = XML_FALSE;
6245 hashTableClear(&(p->paramEntities));
6246#endif /* XML_DTD */
6247 hashTableClear(&(p->elementTypes));
6248 hashTableClear(&(p->attributeIds));
6249 hashTableClear(&(p->prefixes));
6250 poolClear(&(p->pool));
6251 poolClear(&(p->entityValuePool));
6252 p->defaultPrefix.name = NULL;
6253 p->defaultPrefix.binding = NULL;
6254
6255 p->in_eldecl = XML_FALSE;
6256
6257 ms->free_fcn(p->scaffIndex);
6258 p->scaffIndex = NULL;
6259 ms->free_fcn(p->scaffold);
6260 p->scaffold = NULL;
6261
6262 p->scaffLevel = 0;
6263 p->scaffSize = 0;
6264 p->scaffCount = 0;
6265 p->contentStringLen = 0;
6266
6267 p->keepProcessing = XML_TRUE;
6268 p->hasParamEntityRefs = XML_FALSE;
6269 p->standalone = XML_FALSE;
6270}
6271
6272static void
Haibo Huang40a71912019-10-11 11:13:39 -07006273dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006274 HASH_TABLE_ITER iter;
6275 hashTableIterInit(&iter, &(p->elementTypes));
6276 for (;;) {
6277 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006278 if (! e)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006279 break;
6280 if (e->allocDefaultAtts != 0)
6281 ms->free_fcn(e->defaultAtts);
6282 }
6283 hashTableDestroy(&(p->generalEntities));
6284#ifdef XML_DTD
6285 hashTableDestroy(&(p->paramEntities));
6286#endif /* XML_DTD */
6287 hashTableDestroy(&(p->elementTypes));
6288 hashTableDestroy(&(p->attributeIds));
6289 hashTableDestroy(&(p->prefixes));
6290 poolDestroy(&(p->pool));
6291 poolDestroy(&(p->entityValuePool));
6292 if (isDocEntity) {
6293 ms->free_fcn(p->scaffIndex);
6294 ms->free_fcn(p->scaffold);
6295 }
6296 ms->free_fcn(p);
6297}
6298
6299/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
6300 The new DTD has already been initialized.
6301*/
6302static int
Haibo Huang40a71912019-10-11 11:13:39 -07006303dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
6304 const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006305 HASH_TABLE_ITER iter;
6306
6307 /* Copy the prefix table. */
6308
6309 hashTableIterInit(&iter, &(oldDtd->prefixes));
6310 for (;;) {
6311 const XML_Char *name;
6312 const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006313 if (! oldP)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006314 break;
6315 name = poolCopyString(&(newDtd->pool), oldP->name);
Haibo Huang40a71912019-10-11 11:13:39 -07006316 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006317 return 0;
Haibo Huang40a71912019-10-11 11:13:39 -07006318 if (! lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX)))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006319 return 0;
6320 }
6321
6322 hashTableIterInit(&iter, &(oldDtd->attributeIds));
6323
6324 /* Copy the attribute id table. */
6325
6326 for (;;) {
6327 ATTRIBUTE_ID *newA;
6328 const XML_Char *name;
6329 const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
6330
Haibo Huang40a71912019-10-11 11:13:39 -07006331 if (! oldA)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006332 break;
6333 /* Remember to allocate the scratch byte before the name. */
Haibo Huang40a71912019-10-11 11:13:39 -07006334 if (! poolAppendChar(&(newDtd->pool), XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006335 return 0;
6336 name = poolCopyString(&(newDtd->pool), oldA->name);
Haibo Huang40a71912019-10-11 11:13:39 -07006337 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006338 return 0;
6339 ++name;
Elliott Hughes35e432d2012-09-09 14:23:38 -07006340 newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006341 sizeof(ATTRIBUTE_ID));
Haibo Huang40a71912019-10-11 11:13:39 -07006342 if (! newA)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006343 return 0;
6344 newA->maybeTokenized = oldA->maybeTokenized;
6345 if (oldA->prefix) {
6346 newA->xmlns = oldA->xmlns;
6347 if (oldA->prefix == &oldDtd->defaultPrefix)
6348 newA->prefix = &newDtd->defaultPrefix;
6349 else
Elliott Hughes35e432d2012-09-09 14:23:38 -07006350 newA->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006351 oldA->prefix->name, 0);
6352 }
6353 }
6354
6355 /* Copy the element type table. */
6356
6357 hashTableIterInit(&iter, &(oldDtd->elementTypes));
6358
6359 for (;;) {
6360 int i;
6361 ELEMENT_TYPE *newE;
6362 const XML_Char *name;
6363 const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006364 if (! oldE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006365 break;
6366 name = poolCopyString(&(newDtd->pool), oldE->name);
Haibo Huang40a71912019-10-11 11:13:39 -07006367 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006368 return 0;
Elliott Hughes35e432d2012-09-09 14:23:38 -07006369 newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006370 sizeof(ELEMENT_TYPE));
Haibo Huang40a71912019-10-11 11:13:39 -07006371 if (! newE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006372 return 0;
6373 if (oldE->nDefaultAtts) {
Haibo Huang40a71912019-10-11 11:13:39 -07006374 newE->defaultAtts = (DEFAULT_ATTRIBUTE *)ms->malloc_fcn(
6375 oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
6376 if (! newE->defaultAtts) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006377 return 0;
6378 }
6379 }
6380 if (oldE->idAtt)
Haibo Huang40a71912019-10-11 11:13:39 -07006381 newE->idAtt = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds),
6382 oldE->idAtt->name, 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006383 newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
6384 if (oldE->prefix)
Elliott Hughes35e432d2012-09-09 14:23:38 -07006385 newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006386 oldE->prefix->name, 0);
6387 for (i = 0; i < newE->nDefaultAtts; i++) {
Haibo Huang40a71912019-10-11 11:13:39 -07006388 newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup(
6389 oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006390 newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
6391 if (oldE->defaultAtts[i].value) {
6392 newE->defaultAtts[i].value
6393 = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
Haibo Huang40a71912019-10-11 11:13:39 -07006394 if (! newE->defaultAtts[i].value)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006395 return 0;
Haibo Huang40a71912019-10-11 11:13:39 -07006396 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006397 newE->defaultAtts[i].value = NULL;
6398 }
6399 }
6400
6401 /* Copy the entity tables. */
Haibo Huang40a71912019-10-11 11:13:39 -07006402 if (! copyEntityTable(oldParser, &(newDtd->generalEntities), &(newDtd->pool),
6403 &(oldDtd->generalEntities)))
6404 return 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006405
6406#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07006407 if (! copyEntityTable(oldParser, &(newDtd->paramEntities), &(newDtd->pool),
6408 &(oldDtd->paramEntities)))
6409 return 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006410 newDtd->paramEntityRead = oldDtd->paramEntityRead;
6411#endif /* XML_DTD */
6412
6413 newDtd->keepProcessing = oldDtd->keepProcessing;
6414 newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
6415 newDtd->standalone = oldDtd->standalone;
6416
6417 /* Don't want deep copying for scaffolding */
6418 newDtd->in_eldecl = oldDtd->in_eldecl;
6419 newDtd->scaffold = oldDtd->scaffold;
6420 newDtd->contentStringLen = oldDtd->contentStringLen;
6421 newDtd->scaffSize = oldDtd->scaffSize;
6422 newDtd->scaffLevel = oldDtd->scaffLevel;
6423 newDtd->scaffIndex = oldDtd->scaffIndex;
6424
6425 return 1;
Haibo Huang40a71912019-10-11 11:13:39 -07006426} /* End dtdCopy */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006427
6428static int
Haibo Huang40a71912019-10-11 11:13:39 -07006429copyEntityTable(XML_Parser oldParser, HASH_TABLE *newTable,
6430 STRING_POOL *newPool, const HASH_TABLE *oldTable) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006431 HASH_TABLE_ITER iter;
6432 const XML_Char *cachedOldBase = NULL;
6433 const XML_Char *cachedNewBase = NULL;
6434
6435 hashTableIterInit(&iter, oldTable);
6436
6437 for (;;) {
6438 ENTITY *newE;
6439 const XML_Char *name;
6440 const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006441 if (! oldE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006442 break;
6443 name = poolCopyString(newPool, oldE->name);
Haibo Huang40a71912019-10-11 11:13:39 -07006444 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006445 return 0;
Elliott Hughes35e432d2012-09-09 14:23:38 -07006446 newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY));
Haibo Huang40a71912019-10-11 11:13:39 -07006447 if (! newE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006448 return 0;
6449 if (oldE->systemId) {
6450 const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
Haibo Huang40a71912019-10-11 11:13:39 -07006451 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006452 return 0;
6453 newE->systemId = tem;
6454 if (oldE->base) {
6455 if (oldE->base == cachedOldBase)
6456 newE->base = cachedNewBase;
6457 else {
6458 cachedOldBase = oldE->base;
6459 tem = poolCopyString(newPool, cachedOldBase);
Haibo Huang40a71912019-10-11 11:13:39 -07006460 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006461 return 0;
6462 cachedNewBase = newE->base = tem;
6463 }
6464 }
6465 if (oldE->publicId) {
6466 tem = poolCopyString(newPool, oldE->publicId);
Haibo Huang40a71912019-10-11 11:13:39 -07006467 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006468 return 0;
6469 newE->publicId = tem;
6470 }
Haibo Huang40a71912019-10-11 11:13:39 -07006471 } else {
6472 const XML_Char *tem
6473 = poolCopyStringN(newPool, oldE->textPtr, oldE->textLen);
6474 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006475 return 0;
6476 newE->textPtr = tem;
6477 newE->textLen = oldE->textLen;
6478 }
6479 if (oldE->notation) {
6480 const XML_Char *tem = poolCopyString(newPool, oldE->notation);
Haibo Huang40a71912019-10-11 11:13:39 -07006481 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006482 return 0;
6483 newE->notation = tem;
6484 }
6485 newE->is_param = oldE->is_param;
6486 newE->is_internal = oldE->is_internal;
6487 }
6488 return 1;
6489}
6490
6491#define INIT_POWER 6
6492
6493static XML_Bool FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006494keyeq(KEY s1, KEY s2) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006495 for (; *s1 == *s2; s1++, s2++)
6496 if (*s1 == 0)
6497 return XML_TRUE;
6498 return XML_FALSE;
6499}
6500
Elliott Hughes72472942018-01-10 08:36:10 -08006501static size_t
Haibo Huang40a71912019-10-11 11:13:39 -07006502keylen(KEY s) {
Elliott Hughes72472942018-01-10 08:36:10 -08006503 size_t len = 0;
Haibo Huang40a71912019-10-11 11:13:39 -07006504 for (; *s; s++, len++)
6505 ;
Elliott Hughes72472942018-01-10 08:36:10 -08006506 return len;
6507}
6508
6509static void
Haibo Huang40a71912019-10-11 11:13:39 -07006510copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key) {
Elliott Hughes72472942018-01-10 08:36:10 -08006511 key->k[0] = 0;
6512 key->k[1] = get_hash_secret_salt(parser);
6513}
6514
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006515static unsigned long FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006516hash(XML_Parser parser, KEY s) {
Elliott Hughes72472942018-01-10 08:36:10 -08006517 struct siphash state;
6518 struct sipkey key;
Elliott Hughes72472942018-01-10 08:36:10 -08006519 (void)sip24_valid;
6520 copy_salt_to_sipkey(parser, &key);
6521 sip24_init(&state, &key);
6522 sip24_update(&state, s, keylen(s) * sizeof(XML_Char));
6523 return (unsigned long)sip24_final(&state);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006524}
6525
6526static NAMED *
Haibo Huang40a71912019-10-11 11:13:39 -07006527lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006528 size_t i;
6529 if (table->size == 0) {
6530 size_t tsize;
Haibo Huang40a71912019-10-11 11:13:39 -07006531 if (! createSize)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006532 return NULL;
6533 table->power = INIT_POWER;
6534 /* table->size is a power of 2 */
6535 table->size = (size_t)1 << INIT_POWER;
6536 tsize = table->size * sizeof(NAMED *);
6537 table->v = (NAMED **)table->mem->malloc_fcn(tsize);
Haibo Huang40a71912019-10-11 11:13:39 -07006538 if (! table->v) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006539 table->size = 0;
6540 return NULL;
6541 }
6542 memset(table->v, 0, tsize);
Elliott Hughes35e432d2012-09-09 14:23:38 -07006543 i = hash(parser, name) & ((unsigned long)table->size - 1);
Haibo Huang40a71912019-10-11 11:13:39 -07006544 } else {
Elliott Hughes35e432d2012-09-09 14:23:38 -07006545 unsigned long h = hash(parser, name);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006546 unsigned long mask = (unsigned long)table->size - 1;
6547 unsigned char step = 0;
6548 i = h & mask;
6549 while (table->v[i]) {
6550 if (keyeq(name, table->v[i]->name))
6551 return table->v[i];
Haibo Huang40a71912019-10-11 11:13:39 -07006552 if (! step)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006553 step = PROBE_STEP(h, mask, table->power);
6554 i < step ? (i += table->size - step) : (i -= step);
6555 }
Haibo Huang40a71912019-10-11 11:13:39 -07006556 if (! createSize)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006557 return NULL;
6558
6559 /* check for overflow (table is half full) */
6560 if (table->used >> (table->power - 1)) {
6561 unsigned char newPower = table->power + 1;
Sadaf Ebrahimif68f6852022-06-15 04:14:33 +00006562
6563 /* Detect and prevent invalid shift */
6564 if (newPower >= sizeof(unsigned long) * 8 /* bits per byte */) {
6565 return NULL;
6566 }
6567
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006568 size_t newSize = (size_t)1 << newPower;
6569 unsigned long newMask = (unsigned long)newSize - 1;
Sadaf Ebrahimif68f6852022-06-15 04:14:33 +00006570
6571 /* Detect and prevent integer overflow */
6572 if (newSize > (size_t)(-1) / sizeof(NAMED *)) {
6573 return NULL;
6574 }
6575
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006576 size_t tsize = newSize * sizeof(NAMED *);
6577 NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
Haibo Huang40a71912019-10-11 11:13:39 -07006578 if (! newV)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006579 return NULL;
6580 memset(newV, 0, tsize);
6581 for (i = 0; i < table->size; i++)
6582 if (table->v[i]) {
Elliott Hughes35e432d2012-09-09 14:23:38 -07006583 unsigned long newHash = hash(parser, table->v[i]->name);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006584 size_t j = newHash & newMask;
6585 step = 0;
6586 while (newV[j]) {
Haibo Huang40a71912019-10-11 11:13:39 -07006587 if (! step)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006588 step = PROBE_STEP(newHash, newMask, newPower);
6589 j < step ? (j += newSize - step) : (j -= step);
6590 }
6591 newV[j] = table->v[i];
6592 }
6593 table->mem->free_fcn(table->v);
6594 table->v = newV;
6595 table->power = newPower;
6596 table->size = newSize;
6597 i = h & newMask;
6598 step = 0;
6599 while (table->v[i]) {
Haibo Huang40a71912019-10-11 11:13:39 -07006600 if (! step)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006601 step = PROBE_STEP(h, newMask, newPower);
6602 i < step ? (i += newSize - step) : (i -= step);
6603 }
6604 }
6605 }
6606 table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
Haibo Huang40a71912019-10-11 11:13:39 -07006607 if (! table->v[i])
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006608 return NULL;
6609 memset(table->v[i], 0, createSize);
6610 table->v[i]->name = name;
6611 (table->used)++;
6612 return table->v[i];
6613}
6614
6615static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006616hashTableClear(HASH_TABLE *table) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006617 size_t i;
6618 for (i = 0; i < table->size; i++) {
6619 table->mem->free_fcn(table->v[i]);
6620 table->v[i] = NULL;
6621 }
6622 table->used = 0;
6623}
6624
6625static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006626hashTableDestroy(HASH_TABLE *table) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006627 size_t i;
6628 for (i = 0; i < table->size; i++)
6629 table->mem->free_fcn(table->v[i]);
6630 table->mem->free_fcn(table->v);
6631}
6632
6633static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006634hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006635 p->power = 0;
6636 p->size = 0;
6637 p->used = 0;
6638 p->v = NULL;
6639 p->mem = ms;
6640}
6641
6642static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006643hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006644 iter->p = table->v;
Haibo Huangd1a324a2020-10-28 22:19:36 -07006645 iter->end = iter->p ? iter->p + table->size : NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006646}
6647
Haibo Huang40a71912019-10-11 11:13:39 -07006648static NAMED *FASTCALL
6649hashTableIterNext(HASH_TABLE_ITER *iter) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006650 while (iter->p != iter->end) {
6651 NAMED *tem = *(iter->p)++;
6652 if (tem)
6653 return tem;
6654 }
6655 return NULL;
6656}
6657
6658static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006659poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006660 pool->blocks = NULL;
6661 pool->freeBlocks = NULL;
6662 pool->start = NULL;
6663 pool->ptr = NULL;
6664 pool->end = NULL;
6665 pool->mem = ms;
6666}
6667
6668static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006669poolClear(STRING_POOL *pool) {
6670 if (! pool->freeBlocks)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006671 pool->freeBlocks = pool->blocks;
6672 else {
6673 BLOCK *p = pool->blocks;
6674 while (p) {
6675 BLOCK *tem = p->next;
6676 p->next = pool->freeBlocks;
6677 pool->freeBlocks = p;
6678 p = tem;
6679 }
6680 }
6681 pool->blocks = NULL;
6682 pool->start = NULL;
6683 pool->ptr = NULL;
6684 pool->end = NULL;
6685}
6686
6687static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006688poolDestroy(STRING_POOL *pool) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006689 BLOCK *p = pool->blocks;
6690 while (p) {
6691 BLOCK *tem = p->next;
6692 pool->mem->free_fcn(p);
6693 p = tem;
6694 }
6695 p = pool->freeBlocks;
6696 while (p) {
6697 BLOCK *tem = p->next;
6698 pool->mem->free_fcn(p);
6699 p = tem;
6700 }
6701}
6702
6703static XML_Char *
Haibo Huang40a71912019-10-11 11:13:39 -07006704poolAppend(STRING_POOL *pool, const ENCODING *enc, const char *ptr,
6705 const char *end) {
6706 if (! pool->ptr && ! poolGrow(pool))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006707 return NULL;
6708 for (;;) {
Haibo Huang40a71912019-10-11 11:13:39 -07006709 const enum XML_Convert_Result convert_res = XmlConvert(
6710 enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
6711 if ((convert_res == XML_CONVERT_COMPLETED)
6712 || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006713 break;
Haibo Huang40a71912019-10-11 11:13:39 -07006714 if (! poolGrow(pool))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006715 return NULL;
6716 }
6717 return pool->start;
6718}
6719
Haibo Huang40a71912019-10-11 11:13:39 -07006720static const XML_Char *FASTCALL
6721poolCopyString(STRING_POOL *pool, const XML_Char *s) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006722 do {
Haibo Huang40a71912019-10-11 11:13:39 -07006723 if (! poolAppendChar(pool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006724 return NULL;
6725 } while (*s++);
6726 s = pool->start;
6727 poolFinish(pool);
6728 return s;
6729}
6730
6731static const XML_Char *
Haibo Huang40a71912019-10-11 11:13:39 -07006732poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) {
6733 if (! pool->ptr && ! poolGrow(pool)) {
Elliott Hughes72472942018-01-10 08:36:10 -08006734 /* The following line is unreachable given the current usage of
6735 * poolCopyStringN(). Currently it is called from exactly one
6736 * place to copy the text of a simple general entity. By that
6737 * point, the name of the entity is already stored in the pool, so
6738 * pool->ptr cannot be NULL.
6739 *
6740 * If poolCopyStringN() is used elsewhere as it well might be,
6741 * this line may well become executable again. Regardless, this
6742 * sort of check shouldn't be removed lightly, so we just exclude
6743 * it from the coverage statistics.
6744 */
6745 return NULL; /* LCOV_EXCL_LINE */
6746 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006747 for (; n > 0; --n, s++) {
Haibo Huang40a71912019-10-11 11:13:39 -07006748 if (! poolAppendChar(pool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006749 return NULL;
6750 }
6751 s = pool->start;
6752 poolFinish(pool);
6753 return s;
6754}
6755
Haibo Huang40a71912019-10-11 11:13:39 -07006756static const XML_Char *FASTCALL
6757poolAppendString(STRING_POOL *pool, const XML_Char *s) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006758 while (*s) {
Haibo Huang40a71912019-10-11 11:13:39 -07006759 if (! poolAppendChar(pool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006760 return NULL;
6761 s++;
6762 }
6763 return pool->start;
6764}
6765
6766static XML_Char *
Haibo Huang40a71912019-10-11 11:13:39 -07006767poolStoreString(STRING_POOL *pool, const ENCODING *enc, const char *ptr,
6768 const char *end) {
6769 if (! poolAppend(pool, enc, ptr, end))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006770 return NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07006771 if (pool->ptr == pool->end && ! poolGrow(pool))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006772 return NULL;
6773 *(pool->ptr)++ = 0;
6774 return pool->start;
6775}
6776
Elliott Hughes72472942018-01-10 08:36:10 -08006777static size_t
Haibo Huang40a71912019-10-11 11:13:39 -07006778poolBytesToAllocateFor(int blockSize) {
Elliott Hughes72472942018-01-10 08:36:10 -08006779 /* Unprotected math would be:
6780 ** return offsetof(BLOCK, s) + blockSize * sizeof(XML_Char);
6781 **
6782 ** Detect overflow, avoiding _signed_ overflow undefined behavior
6783 ** For a + b * c we check b * c in isolation first, so that addition of a
6784 ** on top has no chance of making us accept a small non-negative number
6785 */
Haibo Huang40a71912019-10-11 11:13:39 -07006786 const size_t stretch = sizeof(XML_Char); /* can be 4 bytes */
Elliott Hughes72472942018-01-10 08:36:10 -08006787
6788 if (blockSize <= 0)
6789 return 0;
6790
6791 if (blockSize > (int)(INT_MAX / stretch))
6792 return 0;
6793
6794 {
6795 const int stretchedBlockSize = blockSize * (int)stretch;
Haibo Huang40a71912019-10-11 11:13:39 -07006796 const int bytesToAllocate
6797 = (int)(offsetof(BLOCK, s) + (unsigned)stretchedBlockSize);
Elliott Hughes72472942018-01-10 08:36:10 -08006798 if (bytesToAllocate < 0)
6799 return 0;
6800
6801 return (size_t)bytesToAllocate;
6802 }
6803}
6804
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006805static XML_Bool FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006806poolGrow(STRING_POOL *pool) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006807 if (pool->freeBlocks) {
6808 if (pool->start == 0) {
6809 pool->blocks = pool->freeBlocks;
6810 pool->freeBlocks = pool->freeBlocks->next;
6811 pool->blocks->next = NULL;
6812 pool->start = pool->blocks->s;
6813 pool->end = pool->start + pool->blocks->size;
6814 pool->ptr = pool->start;
6815 return XML_TRUE;
6816 }
6817 if (pool->end - pool->start < pool->freeBlocks->size) {
6818 BLOCK *tem = pool->freeBlocks->next;
6819 pool->freeBlocks->next = pool->blocks;
6820 pool->blocks = pool->freeBlocks;
6821 pool->freeBlocks = tem;
6822 memcpy(pool->blocks->s, pool->start,
6823 (pool->end - pool->start) * sizeof(XML_Char));
6824 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
6825 pool->start = pool->blocks->s;
6826 pool->end = pool->start + pool->blocks->size;
6827 return XML_TRUE;
6828 }
6829 }
6830 if (pool->blocks && pool->start == pool->blocks->s) {
Paul Duffin4bf8f122016-05-13 12:35:25 +01006831 BLOCK *temp;
Haibo Huang40a71912019-10-11 11:13:39 -07006832 int blockSize = (int)((unsigned)(pool->end - pool->start) * 2U);
Elliott Hughes72472942018-01-10 08:36:10 -08006833 size_t bytesToAllocate;
Paul Duffin4bf8f122016-05-13 12:35:25 +01006834
Elliott Hughes72472942018-01-10 08:36:10 -08006835 /* NOTE: Needs to be calculated prior to calling `realloc`
6836 to avoid dangling pointers: */
6837 const ptrdiff_t offsetInsideBlock = pool->ptr - pool->start;
6838
6839 if (blockSize < 0) {
6840 /* This condition traps a situation where either more than
6841 * INT_MAX/2 bytes have already been allocated. This isn't
6842 * readily testable, since it is unlikely that an average
6843 * machine will have that much memory, so we exclude it from the
6844 * coverage statistics.
6845 */
6846 return XML_FALSE; /* LCOV_EXCL_LINE */
6847 }
6848
6849 bytesToAllocate = poolBytesToAllocateFor(blockSize);
6850 if (bytesToAllocate == 0)
Paul Duffin4bf8f122016-05-13 12:35:25 +01006851 return XML_FALSE;
6852
Haibo Huang40a71912019-10-11 11:13:39 -07006853 temp = (BLOCK *)pool->mem->realloc_fcn(pool->blocks,
6854 (unsigned)bytesToAllocate);
Elliott Hughes35e432d2012-09-09 14:23:38 -07006855 if (temp == NULL)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006856 return XML_FALSE;
Elliott Hughes35e432d2012-09-09 14:23:38 -07006857 pool->blocks = temp;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006858 pool->blocks->size = blockSize;
Elliott Hughes72472942018-01-10 08:36:10 -08006859 pool->ptr = pool->blocks->s + offsetInsideBlock;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006860 pool->start = pool->blocks->s;
6861 pool->end = pool->start + blockSize;
Haibo Huang40a71912019-10-11 11:13:39 -07006862 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006863 BLOCK *tem;
6864 int blockSize = (int)(pool->end - pool->start);
Elliott Hughes72472942018-01-10 08:36:10 -08006865 size_t bytesToAllocate;
Paul Duffin4bf8f122016-05-13 12:35:25 +01006866
Elliott Hughes72472942018-01-10 08:36:10 -08006867 if (blockSize < 0) {
6868 /* This condition traps a situation where either more than
6869 * INT_MAX bytes have already been allocated (which is prevented
6870 * by various pieces of program logic, not least this one, never
6871 * mind the unlikelihood of actually having that much memory) or
6872 * the pool control fields have been corrupted (which could
6873 * conceivably happen in an extremely buggy user handler
6874 * function). Either way it isn't readily testable, so we
6875 * exclude it from the coverage statistics.
6876 */
Haibo Huang40a71912019-10-11 11:13:39 -07006877 return XML_FALSE; /* LCOV_EXCL_LINE */
Elliott Hughes72472942018-01-10 08:36:10 -08006878 }
Paul Duffin4bf8f122016-05-13 12:35:25 +01006879
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006880 if (blockSize < INIT_BLOCK_SIZE)
6881 blockSize = INIT_BLOCK_SIZE;
Elliott Hughes72472942018-01-10 08:36:10 -08006882 else {
6883 /* Detect overflow, avoiding _signed_ overflow undefined behavior */
6884 if ((int)((unsigned)blockSize * 2U) < 0) {
6885 return XML_FALSE;
6886 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006887 blockSize *= 2;
Elliott Hughes72472942018-01-10 08:36:10 -08006888 }
6889
6890 bytesToAllocate = poolBytesToAllocateFor(blockSize);
6891 if (bytesToAllocate == 0)
6892 return XML_FALSE;
6893
6894 tem = (BLOCK *)pool->mem->malloc_fcn(bytesToAllocate);
Haibo Huang40a71912019-10-11 11:13:39 -07006895 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006896 return XML_FALSE;
6897 tem->size = blockSize;
6898 tem->next = pool->blocks;
6899 pool->blocks = tem;
6900 if (pool->ptr != pool->start)
Haibo Huang40a71912019-10-11 11:13:39 -07006901 memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006902 pool->ptr = tem->s + (pool->ptr - pool->start);
6903 pool->start = tem->s;
6904 pool->end = tem->s + blockSize;
6905 }
6906 return XML_TRUE;
6907}
6908
6909static int FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006910nextScaffoldPart(XML_Parser parser) {
6911 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
6912 CONTENT_SCAFFOLD *me;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006913 int next;
6914
Haibo Huang40a71912019-10-11 11:13:39 -07006915 if (! dtd->scaffIndex) {
Elliott Hughes72472942018-01-10 08:36:10 -08006916 dtd->scaffIndex = (int *)MALLOC(parser, parser->m_groupSize * sizeof(int));
Haibo Huang40a71912019-10-11 11:13:39 -07006917 if (! dtd->scaffIndex)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006918 return -1;
6919 dtd->scaffIndex[0] = 0;
6920 }
6921
6922 if (dtd->scaffCount >= dtd->scaffSize) {
6923 CONTENT_SCAFFOLD *temp;
6924 if (dtd->scaffold) {
Sadaf Ebrahimif68f6852022-06-15 04:14:33 +00006925 /* Detect and prevent integer overflow */
6926 if (dtd->scaffSize > UINT_MAX / 2u) {
6927 return -1;
6928 }
6929 /* Detect and prevent integer overflow.
6930 * The preprocessor guard addresses the "always false" warning
6931 * from -Wtype-limits on platforms where
6932 * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
6933#if UINT_MAX >= SIZE_MAX
6934 if (dtd->scaffSize > (size_t)(-1) / 2u / sizeof(CONTENT_SCAFFOLD)) {
6935 return -1;
6936 }
6937#endif
6938
Haibo Huang40a71912019-10-11 11:13:39 -07006939 temp = (CONTENT_SCAFFOLD *)REALLOC(
6940 parser, dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006941 if (temp == NULL)
6942 return -1;
6943 dtd->scaffSize *= 2;
Haibo Huang40a71912019-10-11 11:13:39 -07006944 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08006945 temp = (CONTENT_SCAFFOLD *)MALLOC(parser, INIT_SCAFFOLD_ELEMENTS
Haibo Huang40a71912019-10-11 11:13:39 -07006946 * sizeof(CONTENT_SCAFFOLD));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006947 if (temp == NULL)
6948 return -1;
6949 dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
6950 }
6951 dtd->scaffold = temp;
6952 }
6953 next = dtd->scaffCount++;
6954 me = &dtd->scaffold[next];
6955 if (dtd->scaffLevel) {
Haibo Huang40a71912019-10-11 11:13:39 -07006956 CONTENT_SCAFFOLD *parent
6957 = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]];
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006958 if (parent->lastchild) {
6959 dtd->scaffold[parent->lastchild].nextsib = next;
6960 }
Haibo Huang40a71912019-10-11 11:13:39 -07006961 if (! parent->childcnt)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006962 parent->firstchild = next;
6963 parent->lastchild = next;
6964 parent->childcnt++;
6965 }
6966 me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
6967 return next;
6968}
6969
6970static void
Haibo Huang40a71912019-10-11 11:13:39 -07006971build_node(XML_Parser parser, int src_node, XML_Content *dest,
6972 XML_Content **contpos, XML_Char **strpos) {
6973 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006974 dest->type = dtd->scaffold[src_node].type;
6975 dest->quant = dtd->scaffold[src_node].quant;
6976 if (dest->type == XML_CTYPE_NAME) {
6977 const XML_Char *src;
6978 dest->name = *strpos;
6979 src = dtd->scaffold[src_node].name;
6980 for (;;) {
6981 *(*strpos)++ = *src;
Haibo Huang40a71912019-10-11 11:13:39 -07006982 if (! *src)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006983 break;
6984 src++;
6985 }
6986 dest->numchildren = 0;
6987 dest->children = NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07006988 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006989 unsigned int i;
6990 int cn;
6991 dest->numchildren = dtd->scaffold[src_node].childcnt;
6992 dest->children = *contpos;
6993 *contpos += dest->numchildren;
Haibo Huang40a71912019-10-11 11:13:39 -07006994 for (i = 0, cn = dtd->scaffold[src_node].firstchild; i < dest->numchildren;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006995 i++, cn = dtd->scaffold[cn].nextsib) {
6996 build_node(parser, cn, &(dest->children[i]), contpos, strpos);
6997 }
6998 dest->name = NULL;
6999 }
7000}
7001
7002static XML_Content *
Haibo Huang40a71912019-10-11 11:13:39 -07007003build_model(XML_Parser parser) {
7004 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08007005 XML_Content *ret;
7006 XML_Content *cpos;
Haibo Huang40a71912019-10-11 11:13:39 -07007007 XML_Char *str;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08007008
Sadaf Ebrahimif68f6852022-06-15 04:14:33 +00007009 /* Detect and prevent integer overflow.
7010 * The preprocessor guard addresses the "always false" warning
7011 * from -Wtype-limits on platforms where
7012 * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
7013#if UINT_MAX >= SIZE_MAX
7014 if (dtd->scaffCount > (size_t)(-1) / sizeof(XML_Content)) {
7015 return NULL;
7016 }
7017 if (dtd->contentStringLen > (size_t)(-1) / sizeof(XML_Char)) {
7018 return NULL;
7019 }
7020#endif
7021 if (dtd->scaffCount * sizeof(XML_Content)
7022 > (size_t)(-1) - dtd->contentStringLen * sizeof(XML_Char)) {
7023 return NULL;
7024 }
7025
7026 const size_t allocsize = (dtd->scaffCount * sizeof(XML_Content)
7027 + (dtd->contentStringLen * sizeof(XML_Char)));
Elliott Hughes72472942018-01-10 08:36:10 -08007028 ret = (XML_Content *)MALLOC(parser, allocsize);
Haibo Huang40a71912019-10-11 11:13:39 -07007029 if (! ret)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08007030 return NULL;
7031
Haibo Huang40a71912019-10-11 11:13:39 -07007032 str = (XML_Char *)(&ret[dtd->scaffCount]);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08007033 cpos = &ret[1];
7034
7035 build_node(parser, 0, ret, &cpos, &str);
7036 return ret;
7037}
7038
7039static ELEMENT_TYPE *
Haibo Huang40a71912019-10-11 11:13:39 -07007040getElementType(XML_Parser parser, const ENCODING *enc, const char *ptr,
7041 const char *end) {
7042 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08007043 const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
7044 ELEMENT_TYPE *ret;
7045
Haibo Huang40a71912019-10-11 11:13:39 -07007046 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08007047 return NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07007048 ret = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
7049 sizeof(ELEMENT_TYPE));
7050 if (! ret)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08007051 return NULL;
7052 if (ret->name != name)
7053 poolDiscard(&dtd->pool);
7054 else {
7055 poolFinish(&dtd->pool);
Haibo Huang40a71912019-10-11 11:13:39 -07007056 if (! setElementTypePrefix(parser, ret))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08007057 return NULL;
7058 }
7059 return ret;
7060}
Elliott Hughes72472942018-01-10 08:36:10 -08007061
7062static XML_Char *
Haibo Huang40a71912019-10-11 11:13:39 -07007063copyString(const XML_Char *s, const XML_Memory_Handling_Suite *memsuite) {
Sadaf Ebrahimi1adbf372022-05-23 22:34:43 +00007064 size_t charsRequired = 0;
Haibo Huang40a71912019-10-11 11:13:39 -07007065 XML_Char *result;
Elliott Hughes72472942018-01-10 08:36:10 -08007066
Haibo Huang40a71912019-10-11 11:13:39 -07007067 /* First determine how long the string is */
7068 while (s[charsRequired] != 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08007069 charsRequired++;
Haibo Huang40a71912019-10-11 11:13:39 -07007070 }
7071 /* Include the terminator */
7072 charsRequired++;
Elliott Hughes72472942018-01-10 08:36:10 -08007073
Haibo Huang40a71912019-10-11 11:13:39 -07007074 /* Now allocate space for the copy */
7075 result = memsuite->malloc_fcn(charsRequired * sizeof(XML_Char));
7076 if (result == NULL)
7077 return NULL;
7078 /* Copy the original into place */
7079 memcpy(result, s, charsRequired * sizeof(XML_Char));
7080 return result;
Elliott Hughes72472942018-01-10 08:36:10 -08007081}