blob: 729f94b822f6b2192814fb12cafb263dc220db66 [file] [log] [blame]
Elliott Hughesf648a292021-04-01 15:10:13 -07001/* d667b5f8e56e24fdfaf5e38596d419d924a9fadceb987d81d5613ecb7ca51b0e (2.3.0+)
Elliott Hughes72472942018-01-10 08:36:10 -08002 __ __ _
3 ___\ \/ /_ __ __ _| |_
4 / _ \\ /| '_ \ / _` | __|
5 | __// \| |_) | (_| | |_
6 \___/_/\_\ .__/ \__,_|\__|
7 |_| XML parser
8
9 Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
10 Copyright (c) 2000-2017 Expat development team
11 Licensed under the MIT license:
12
13 Permission is hereby granted, free of charge, to any person obtaining
14 a copy of this software and associated documentation files (the
15 "Software"), to deal in the Software without restriction, including
16 without limitation the rights to use, copy, modify, merge, publish,
17 distribute, sublicense, and/or sell copies of the Software, and to permit
18 persons to whom the Software is furnished to do so, subject to the
19 following conditions:
20
21 The above copyright notice and this permission notice shall be included
22 in all copies or substantial portions of the Software.
23
24 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
27 NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
28 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
29 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
30 USE OR OTHER DEALINGS IN THE SOFTWARE.
The Android Open Source Projectb80e2872009-03-03 19:29:30 -080031*/
32
Haibo Huang40a71912019-10-11 11:13:39 -070033#if ! defined(_GNU_SOURCE)
34# define _GNU_SOURCE 1 /* syscall prototype */
35#endif
36
37#ifdef _WIN32
38/* force stdlib to define rand_s() */
39# if ! defined(_CRT_RAND_S)
40# define _CRT_RAND_S
41# endif
Elliott Hughes72472942018-01-10 08:36:10 -080042#endif
43
The Android Open Source Projectb80e2872009-03-03 19:29:30 -080044#include <stddef.h>
Haibo Huang40a71912019-10-11 11:13:39 -070045#include <string.h> /* memset(), memcpy() */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -080046#include <assert.h>
Haibo Huang40a71912019-10-11 11:13:39 -070047#include <limits.h> /* UINT_MAX */
48#include <stdio.h> /* fprintf */
49#include <stdlib.h> /* getenv, rand_s */
Elliott Hughesf648a292021-04-01 15:10:13 -070050#include <stdint.h> /* uintptr_t */
Haibo Huangd1a324a2020-10-28 22:19:36 -070051
Elliott Hughes72472942018-01-10 08:36:10 -080052#ifdef _WIN32
Haibo Huang40a71912019-10-11 11:13:39 -070053# define getpid GetCurrentProcessId
Paul Duffin3c2f09e2016-06-07 15:53:38 +010054#else
Haibo Huang40a71912019-10-11 11:13:39 -070055# include <sys/time.h> /* gettimeofday() */
56# include <sys/types.h> /* getpid() */
57# include <unistd.h> /* getpid() */
58# include <fcntl.h> /* O_RDONLY */
59# include <errno.h>
Paul Duffin3c2f09e2016-06-07 15:53:38 +010060#endif
The Android Open Source Projectb80e2872009-03-03 19:29:30 -080061
62#define XML_BUILDING_EXPAT 1
63
Elliott Hughes72472942018-01-10 08:36:10 -080064#ifdef _WIN32
Haibo Huang40a71912019-10-11 11:13:39 -070065# include "winconfig.h"
The Android Open Source Projectb80e2872009-03-03 19:29:30 -080066#elif defined(HAVE_EXPAT_CONFIG_H)
Haibo Huang40a71912019-10-11 11:13:39 -070067# include <expat_config.h>
Elliott Hughes72472942018-01-10 08:36:10 -080068#endif /* ndef _WIN32 */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -080069
Elliott Hughesd07d5a72009-09-25 16:04:37 -070070#include "ascii.h"
The Android Open Source Projectb80e2872009-03-03 19:29:30 -080071#include "expat.h"
Elliott Hughes72472942018-01-10 08:36:10 -080072#include "siphash.h"
73
74#if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
Haibo Huang40a71912019-10-11 11:13:39 -070075# if defined(HAVE_GETRANDOM)
76# include <sys/random.h> /* getrandom */
77# else
78# include <unistd.h> /* syscall */
79# include <sys/syscall.h> /* SYS_getrandom */
80# endif
81# if ! defined(GRND_NONBLOCK)
82# define GRND_NONBLOCK 0x0001
83# endif /* defined(GRND_NONBLOCK) */
84#endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */
Elliott Hughes72472942018-01-10 08:36:10 -080085
Haibo Huang40a71912019-10-11 11:13:39 -070086#if defined(HAVE_LIBBSD) \
Elliott Hughes72472942018-01-10 08:36:10 -080087 && (defined(HAVE_ARC4RANDOM_BUF) || defined(HAVE_ARC4RANDOM))
Haibo Huang40a71912019-10-11 11:13:39 -070088# include <bsd/stdlib.h>
Elliott Hughes72472942018-01-10 08:36:10 -080089#endif
90
Haibo Huang40a71912019-10-11 11:13:39 -070091#if defined(_WIN32) && ! defined(LOAD_LIBRARY_SEARCH_SYSTEM32)
92# define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800
Elliott Hughes72472942018-01-10 08:36:10 -080093#endif
94
Haibo Huang40a71912019-10-11 11:13:39 -070095#if ! defined(HAVE_GETRANDOM) && ! defined(HAVE_SYSCALL_GETRANDOM) \
96 && ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) \
97 && ! defined(XML_DEV_URANDOM) && ! defined(_WIN32) \
98 && ! defined(XML_POOR_ENTROPY)
99# error You do not have support for any sources of high quality entropy \
Elliott Hughes72472942018-01-10 08:36:10 -0800100 enabled. For end user security, that is probably not what you want. \
101 \
102 Your options include: \
Haibo Huangd1a324a2020-10-28 22:19:36 -0700103 * Linux >=3.17 + glibc >=2.25 (getrandom): HAVE_GETRANDOM, \
104 * Linux >=3.17 + glibc (including <2.25) (syscall SYS_getrandom): HAVE_SYSCALL_GETRANDOM, \
Elliott Hughes72472942018-01-10 08:36:10 -0800105 * BSD / macOS >=10.7 (arc4random_buf): HAVE_ARC4RANDOM_BUF, \
Haibo Huangd1a324a2020-10-28 22:19:36 -0700106 * BSD / macOS (including <10.7) (arc4random): HAVE_ARC4RANDOM, \
Elliott Hughes72472942018-01-10 08:36:10 -0800107 * libbsd (arc4random_buf): HAVE_ARC4RANDOM_BUF + HAVE_LIBBSD, \
108 * libbsd (arc4random): HAVE_ARC4RANDOM + HAVE_LIBBSD, \
Haibo Huangd1a324a2020-10-28 22:19:36 -0700109 * Linux (including <3.17) / BSD / macOS (including <10.7) (/dev/urandom): XML_DEV_URANDOM, \
110 * Windows >=Vista (rand_s): _WIN32. \
Elliott Hughes72472942018-01-10 08:36:10 -0800111 \
112 If insist on not using any of these, bypass this error by defining \
113 XML_POOR_ENTROPY; you have been warned. \
114 \
115 If you have reasons to patch this detection code away or need changes \
116 to the build system, please open a bug. Thank you!
117#endif
118
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800119#ifdef XML_UNICODE
Haibo Huang40a71912019-10-11 11:13:39 -0700120# define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
121# define XmlConvert XmlUtf16Convert
122# define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
123# define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
124# define XmlEncode XmlUtf16Encode
Haibo Huangd1a324a2020-10-28 22:19:36 -0700125# define MUST_CONVERT(enc, s) (! (enc)->isUtf16 || (((uintptr_t)(s)) & 1))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800126typedef unsigned short ICHAR;
127#else
Haibo Huang40a71912019-10-11 11:13:39 -0700128# define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
129# define XmlConvert XmlUtf8Convert
130# define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
131# define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
132# define XmlEncode XmlUtf8Encode
133# define MUST_CONVERT(enc, s) (! (enc)->isUtf8)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800134typedef char ICHAR;
135#endif
136
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800137#ifndef XML_NS
138
Haibo Huang40a71912019-10-11 11:13:39 -0700139# define XmlInitEncodingNS XmlInitEncoding
140# define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
141# undef XmlGetInternalEncodingNS
142# define XmlGetInternalEncodingNS XmlGetInternalEncoding
143# define XmlParseXmlDeclNS XmlParseXmlDecl
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800144
145#endif
146
147#ifdef XML_UNICODE
148
Haibo Huang40a71912019-10-11 11:13:39 -0700149# ifdef XML_UNICODE_WCHAR_T
150# define XML_T(x) (const wchar_t) x
151# define XML_L(x) L##x
152# else
153# define XML_T(x) (const unsigned short)x
154# define XML_L(x) x
155# endif
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800156
157#else
158
Haibo Huang40a71912019-10-11 11:13:39 -0700159# define XML_T(x) x
160# define XML_L(x) x
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800161
162#endif
163
164/* Round up n to be a multiple of sz, where sz is a power of 2. */
Haibo Huang40a71912019-10-11 11:13:39 -0700165#define ROUND_UP(n, sz) (((n) + ((sz)-1)) & ~((sz)-1))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800166
Elliott Hughesaaec48e2018-08-16 16:29:01 -0700167/* Do safe (NULL-aware) pointer arithmetic */
168#define EXPAT_SAFE_PTR_DIFF(p, q) (((p) && (q)) ? ((p) - (q)) : 0)
169
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800170#include "internal.h"
171#include "xmltok.h"
172#include "xmlrole.h"
173
174typedef const XML_Char *KEY;
175
176typedef struct {
177 KEY name;
178} NAMED;
179
180typedef struct {
181 NAMED **v;
182 unsigned char power;
183 size_t size;
184 size_t used;
185 const XML_Memory_Handling_Suite *mem;
186} HASH_TABLE;
187
Haibo Huang40a71912019-10-11 11:13:39 -0700188static size_t keylen(KEY s);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800189
Haibo Huang40a71912019-10-11 11:13:39 -0700190static void copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800191
192/* For probing (after a collision) we need a step size relative prime
193 to the hash table size, which is a power of 2. We use double-hashing,
194 since we can calculate a second hash value cheaply by taking those bits
195 of the first hash value that were discarded (masked out) when the table
196 index was calculated: index = hash & mask, where mask = table->size - 1.
197 We limit the maximum step size to table->size / 4 (mask >> 2) and make
198 it odd, since odd numbers are always relative prime to a power of 2.
199*/
Haibo Huang40a71912019-10-11 11:13:39 -0700200#define SECOND_HASH(hash, mask, power) \
201 ((((hash) & ~(mask)) >> ((power)-1)) & ((mask) >> 2))
202#define PROBE_STEP(hash, mask, power) \
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800203 ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
204
205typedef struct {
206 NAMED **p;
207 NAMED **end;
208} HASH_TABLE_ITER;
209
Haibo Huang40a71912019-10-11 11:13:39 -0700210#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800211#define INIT_DATA_BUF_SIZE 1024
212#define INIT_ATTS_SIZE 16
213#define INIT_ATTS_VERSION 0xFFFFFFFF
214#define INIT_BLOCK_SIZE 1024
215#define INIT_BUFFER_SIZE 1024
216
217#define EXPAND_SPARE 24
218
219typedef struct binding {
220 struct prefix *prefix;
221 struct binding *nextTagBinding;
222 struct binding *prevPrefixBinding;
223 const struct attribute_id *attId;
224 XML_Char *uri;
225 int uriLen;
226 int uriAlloc;
227} BINDING;
228
229typedef struct prefix {
230 const XML_Char *name;
231 BINDING *binding;
232} PREFIX;
233
234typedef struct {
235 const XML_Char *str;
236 const XML_Char *localPart;
237 const XML_Char *prefix;
238 int strLen;
239 int uriLen;
240 int prefixLen;
241} TAG_NAME;
242
243/* TAG represents an open element.
244 The name of the element is stored in both the document and API
245 encodings. The memory buffer 'buf' is a separately-allocated
246 memory area which stores the name. During the XML_Parse()/
247 XMLParseBuffer() when the element is open, the memory for the 'raw'
248 version of the name (in the document encoding) is shared with the
249 document buffer. If the element is open across calls to
250 XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
251 contain the 'raw' name as well.
252
253 A parser re-uses these structures, maintaining a list of allocated
254 TAG objects in a free list.
255*/
256typedef struct tag {
Haibo Huang40a71912019-10-11 11:13:39 -0700257 struct tag *parent; /* parent of this element */
258 const char *rawName; /* tagName in the original encoding */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800259 int rawNameLength;
Haibo Huang40a71912019-10-11 11:13:39 -0700260 TAG_NAME name; /* tagName in the API encoding */
261 char *buf; /* buffer for name components */
262 char *bufEnd; /* end of the buffer */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800263 BINDING *bindings;
264} TAG;
265
266typedef struct {
267 const XML_Char *name;
268 const XML_Char *textPtr;
Haibo Huang40a71912019-10-11 11:13:39 -0700269 int textLen; /* length in XML_Chars */
270 int processed; /* # of processed bytes - when suspended */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800271 const XML_Char *systemId;
272 const XML_Char *base;
273 const XML_Char *publicId;
274 const XML_Char *notation;
275 XML_Bool open;
276 XML_Bool is_param;
277 XML_Bool is_internal; /* true if declared in internal subset outside PE */
278} ENTITY;
279
280typedef struct {
Haibo Huang40a71912019-10-11 11:13:39 -0700281 enum XML_Content_Type type;
282 enum XML_Content_Quant quant;
283 const XML_Char *name;
284 int firstchild;
285 int lastchild;
286 int childcnt;
287 int nextsib;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800288} CONTENT_SCAFFOLD;
289
290#define INIT_SCAFFOLD_ELEMENTS 32
291
292typedef struct block {
293 struct block *next;
294 int size;
295 XML_Char s[1];
296} BLOCK;
297
298typedef struct {
299 BLOCK *blocks;
300 BLOCK *freeBlocks;
301 const XML_Char *end;
302 XML_Char *ptr;
303 XML_Char *start;
304 const XML_Memory_Handling_Suite *mem;
305} STRING_POOL;
306
307/* The XML_Char before the name is used to determine whether
308 an attribute has been specified. */
309typedef struct attribute_id {
310 XML_Char *name;
311 PREFIX *prefix;
312 XML_Bool maybeTokenized;
313 XML_Bool xmlns;
314} ATTRIBUTE_ID;
315
316typedef struct {
317 const ATTRIBUTE_ID *id;
318 XML_Bool isCdata;
319 const XML_Char *value;
320} DEFAULT_ATTRIBUTE;
321
322typedef struct {
323 unsigned long version;
324 unsigned long hash;
325 const XML_Char *uriName;
326} NS_ATT;
327
328typedef struct {
329 const XML_Char *name;
330 PREFIX *prefix;
331 const ATTRIBUTE_ID *idAtt;
332 int nDefaultAtts;
333 int allocDefaultAtts;
334 DEFAULT_ATTRIBUTE *defaultAtts;
335} ELEMENT_TYPE;
336
337typedef struct {
338 HASH_TABLE generalEntities;
339 HASH_TABLE elementTypes;
340 HASH_TABLE attributeIds;
341 HASH_TABLE prefixes;
342 STRING_POOL pool;
343 STRING_POOL entityValuePool;
344 /* false once a parameter entity reference has been skipped */
345 XML_Bool keepProcessing;
346 /* true once an internal or external PE reference has been encountered;
347 this includes the reference to an external subset */
348 XML_Bool hasParamEntityRefs;
349 XML_Bool standalone;
350#ifdef XML_DTD
351 /* indicates if external PE has been read */
352 XML_Bool paramEntityRead;
353 HASH_TABLE paramEntities;
354#endif /* XML_DTD */
355 PREFIX defaultPrefix;
356 /* === scaffolding for building content model === */
357 XML_Bool in_eldecl;
358 CONTENT_SCAFFOLD *scaffold;
359 unsigned contentStringLen;
360 unsigned scaffSize;
361 unsigned scaffCount;
362 int scaffLevel;
363 int *scaffIndex;
364} DTD;
365
366typedef struct open_internal_entity {
367 const char *internalEventPtr;
368 const char *internalEventEndPtr;
369 struct open_internal_entity *next;
370 ENTITY *entity;
371 int startTagLevel;
372 XML_Bool betweenDecl; /* WFC: PE Between Declarations */
373} OPEN_INTERNAL_ENTITY;
374
Haibo Huang40a71912019-10-11 11:13:39 -0700375typedef enum XML_Error PTRCALL Processor(XML_Parser parser, const char *start,
376 const char *end, const char **endPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800377
378static Processor prologProcessor;
379static Processor prologInitProcessor;
380static Processor contentProcessor;
381static Processor cdataSectionProcessor;
382#ifdef XML_DTD
383static Processor ignoreSectionProcessor;
384static Processor externalParEntProcessor;
385static Processor externalParEntInitProcessor;
386static Processor entityValueProcessor;
387static Processor entityValueInitProcessor;
388#endif /* XML_DTD */
389static Processor epilogProcessor;
390static Processor errorProcessor;
391static Processor externalEntityInitProcessor;
392static Processor externalEntityInitProcessor2;
393static Processor externalEntityInitProcessor3;
394static Processor externalEntityContentProcessor;
395static Processor internalEntityProcessor;
396
Haibo Huang40a71912019-10-11 11:13:39 -0700397static enum XML_Error handleUnknownEncoding(XML_Parser parser,
398 const XML_Char *encodingName);
399static enum XML_Error processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
400 const char *s, const char *next);
401static enum XML_Error initializeEncoding(XML_Parser parser);
402static enum XML_Error doProlog(XML_Parser parser, const ENCODING *enc,
403 const char *s, const char *end, int tok,
404 const char *next, const char **nextPtr,
405 XML_Bool haveMore, XML_Bool allowClosingDoctype);
406static enum XML_Error processInternalEntity(XML_Parser parser, ENTITY *entity,
407 XML_Bool betweenDecl);
408static enum XML_Error doContent(XML_Parser parser, int startTagLevel,
409 const ENCODING *enc, const char *start,
410 const char *end, const char **endPtr,
411 XML_Bool haveMore);
412static enum XML_Error doCdataSection(XML_Parser parser, const ENCODING *,
413 const char **startPtr, const char *end,
414 const char **nextPtr, XML_Bool haveMore);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800415#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -0700416static enum XML_Error doIgnoreSection(XML_Parser parser, const ENCODING *,
417 const char **startPtr, const char *end,
418 const char **nextPtr, XML_Bool haveMore);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800419#endif /* XML_DTD */
420
Haibo Huang40a71912019-10-11 11:13:39 -0700421static void freeBindings(XML_Parser parser, BINDING *bindings);
422static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *,
423 const char *s, TAG_NAME *tagNamePtr,
424 BINDING **bindingsPtr);
425static enum XML_Error addBinding(XML_Parser parser, PREFIX *prefix,
426 const ATTRIBUTE_ID *attId, const XML_Char *uri,
427 BINDING **bindingsPtr);
428static int defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
429 XML_Bool isId, const XML_Char *dfltValue,
430 XML_Parser parser);
431static enum XML_Error storeAttributeValue(XML_Parser parser, const ENCODING *,
432 XML_Bool isCdata, const char *,
433 const char *, STRING_POOL *);
434static enum XML_Error appendAttributeValue(XML_Parser parser, const ENCODING *,
435 XML_Bool isCdata, const char *,
436 const char *, STRING_POOL *);
437static ATTRIBUTE_ID *getAttributeId(XML_Parser parser, const ENCODING *enc,
438 const char *start, const char *end);
439static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
440static enum XML_Error storeEntityValue(XML_Parser parser, const ENCODING *enc,
441 const char *start, const char *end);
442static int reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
443 const char *start, const char *end);
444static int reportComment(XML_Parser parser, const ENCODING *enc,
445 const char *start, const char *end);
446static void reportDefault(XML_Parser parser, const ENCODING *enc,
447 const char *start, const char *end);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800448
Haibo Huang40a71912019-10-11 11:13:39 -0700449static const XML_Char *getContext(XML_Parser parser);
450static XML_Bool setContext(XML_Parser parser, const XML_Char *context);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800451
452static void FASTCALL normalizePublicId(XML_Char *s);
453
Haibo Huang40a71912019-10-11 11:13:39 -0700454static DTD *dtdCreate(const XML_Memory_Handling_Suite *ms);
Elliott Hughes72472942018-01-10 08:36:10 -0800455/* do not call if m_parentParser != NULL */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800456static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
Haibo Huang40a71912019-10-11 11:13:39 -0700457static void dtdDestroy(DTD *p, XML_Bool isDocEntity,
458 const XML_Memory_Handling_Suite *ms);
459static int dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
460 const XML_Memory_Handling_Suite *ms);
461static int copyEntityTable(XML_Parser oldParser, HASH_TABLE *, STRING_POOL *,
462 const HASH_TABLE *);
463static NAMED *lookup(XML_Parser parser, HASH_TABLE *table, KEY name,
464 size_t createSize);
465static void FASTCALL hashTableInit(HASH_TABLE *,
466 const XML_Memory_Handling_Suite *ms);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800467static void FASTCALL hashTableClear(HASH_TABLE *);
468static void FASTCALL hashTableDestroy(HASH_TABLE *);
Haibo Huang40a71912019-10-11 11:13:39 -0700469static void FASTCALL hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
470static NAMED *FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800471
Haibo Huang40a71912019-10-11 11:13:39 -0700472static void FASTCALL poolInit(STRING_POOL *,
473 const XML_Memory_Handling_Suite *ms);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800474static void FASTCALL poolClear(STRING_POOL *);
475static void FASTCALL poolDestroy(STRING_POOL *);
Haibo Huang40a71912019-10-11 11:13:39 -0700476static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
477 const char *ptr, const char *end);
478static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
479 const char *ptr, const char *end);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800480static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
Haibo Huang40a71912019-10-11 11:13:39 -0700481static const XML_Char *FASTCALL poolCopyString(STRING_POOL *pool,
482 const XML_Char *s);
483static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s,
484 int n);
485static const XML_Char *FASTCALL poolAppendString(STRING_POOL *pool,
486 const XML_Char *s);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800487
488static int FASTCALL nextScaffoldPart(XML_Parser parser);
Haibo Huang40a71912019-10-11 11:13:39 -0700489static XML_Content *build_model(XML_Parser parser);
490static ELEMENT_TYPE *getElementType(XML_Parser parser, const ENCODING *enc,
491 const char *ptr, const char *end);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800492
Elliott Hughes72472942018-01-10 08:36:10 -0800493static XML_Char *copyString(const XML_Char *s,
494 const XML_Memory_Handling_Suite *memsuite);
495
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100496static unsigned long generate_hash_secret_salt(XML_Parser parser);
Elliott Hughes35e432d2012-09-09 14:23:38 -0700497static XML_Bool startParsing(XML_Parser parser);
498
Haibo Huang40a71912019-10-11 11:13:39 -0700499static XML_Parser parserCreate(const XML_Char *encodingName,
500 const XML_Memory_Handling_Suite *memsuite,
501 const XML_Char *nameSep, DTD *dtd);
Elliott Hughes35e432d2012-09-09 14:23:38 -0700502
Haibo Huang40a71912019-10-11 11:13:39 -0700503static void parserInit(XML_Parser parser, const XML_Char *encodingName);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800504
505#define poolStart(pool) ((pool)->start)
506#define poolEnd(pool) ((pool)->ptr)
507#define poolLength(pool) ((pool)->ptr - (pool)->start)
508#define poolChop(pool) ((void)--(pool->ptr))
509#define poolLastChar(pool) (((pool)->ptr)[-1])
510#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
511#define poolFinish(pool) ((pool)->start = (pool)->ptr)
Haibo Huang40a71912019-10-11 11:13:39 -0700512#define poolAppendChar(pool, c) \
513 (((pool)->ptr == (pool)->end && ! poolGrow(pool)) \
514 ? 0 \
515 : ((*((pool)->ptr)++ = c), 1))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800516
517struct XML_ParserStruct {
Elliott Hughes72472942018-01-10 08:36:10 -0800518 /* The first member must be m_userData so that the XML_GetUserData
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800519 macro works. */
520 void *m_userData;
521 void *m_handlerArg;
522 char *m_buffer;
523 const XML_Memory_Handling_Suite m_mem;
524 /* first character to be parsed */
525 const char *m_bufferPtr;
526 /* past last character to be parsed */
527 char *m_bufferEnd;
Elliott Hughes72472942018-01-10 08:36:10 -0800528 /* allocated end of m_buffer */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800529 const char *m_bufferLim;
530 XML_Index m_parseEndByteIndex;
531 const char *m_parseEndPtr;
532 XML_Char *m_dataBuf;
533 XML_Char *m_dataBufEnd;
534 XML_StartElementHandler m_startElementHandler;
535 XML_EndElementHandler m_endElementHandler;
536 XML_CharacterDataHandler m_characterDataHandler;
537 XML_ProcessingInstructionHandler m_processingInstructionHandler;
538 XML_CommentHandler m_commentHandler;
539 XML_StartCdataSectionHandler m_startCdataSectionHandler;
540 XML_EndCdataSectionHandler m_endCdataSectionHandler;
541 XML_DefaultHandler m_defaultHandler;
542 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
543 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
544 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
545 XML_NotationDeclHandler m_notationDeclHandler;
546 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
547 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
548 XML_NotStandaloneHandler m_notStandaloneHandler;
549 XML_ExternalEntityRefHandler m_externalEntityRefHandler;
550 XML_Parser m_externalEntityRefHandlerArg;
551 XML_SkippedEntityHandler m_skippedEntityHandler;
552 XML_UnknownEncodingHandler m_unknownEncodingHandler;
553 XML_ElementDeclHandler m_elementDeclHandler;
554 XML_AttlistDeclHandler m_attlistDeclHandler;
555 XML_EntityDeclHandler m_entityDeclHandler;
556 XML_XmlDeclHandler m_xmlDeclHandler;
557 const ENCODING *m_encoding;
558 INIT_ENCODING m_initEncoding;
559 const ENCODING *m_internalEncoding;
560 const XML_Char *m_protocolEncodingName;
561 XML_Bool m_ns;
562 XML_Bool m_ns_triplets;
563 void *m_unknownEncodingMem;
564 void *m_unknownEncodingData;
565 void *m_unknownEncodingHandlerData;
Haibo Huang40a71912019-10-11 11:13:39 -0700566 void(XMLCALL *m_unknownEncodingRelease)(void *);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800567 PROLOG_STATE m_prologState;
568 Processor *m_processor;
569 enum XML_Error m_errorCode;
570 const char *m_eventPtr;
571 const char *m_eventEndPtr;
572 const char *m_positionPtr;
573 OPEN_INTERNAL_ENTITY *m_openInternalEntities;
574 OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
575 XML_Bool m_defaultExpandInternalEntities;
576 int m_tagLevel;
577 ENTITY *m_declEntity;
578 const XML_Char *m_doctypeName;
579 const XML_Char *m_doctypeSysid;
580 const XML_Char *m_doctypePubid;
581 const XML_Char *m_declAttributeType;
582 const XML_Char *m_declNotationName;
583 const XML_Char *m_declNotationPublicId;
584 ELEMENT_TYPE *m_declElementType;
585 ATTRIBUTE_ID *m_declAttributeId;
586 XML_Bool m_declAttributeIsCdata;
587 XML_Bool m_declAttributeIsId;
588 DTD *m_dtd;
589 const XML_Char *m_curBase;
590 TAG *m_tagStack;
591 TAG *m_freeTagList;
592 BINDING *m_inheritedBindings;
593 BINDING *m_freeBindingList;
594 int m_attsSize;
595 int m_nSpecifiedAtts;
596 int m_idAttIndex;
597 ATTRIBUTE *m_atts;
598 NS_ATT *m_nsAtts;
599 unsigned long m_nsAttsVersion;
600 unsigned char m_nsAttsPower;
Elliott Hughes35e432d2012-09-09 14:23:38 -0700601#ifdef XML_ATTR_INFO
602 XML_AttrInfo *m_attInfo;
603#endif
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800604 POSITION m_position;
605 STRING_POOL m_tempPool;
606 STRING_POOL m_temp2Pool;
607 char *m_groupConnector;
608 unsigned int m_groupSize;
609 XML_Char m_namespaceSeparator;
610 XML_Parser m_parentParser;
611 XML_ParsingStatus m_parsingStatus;
612#ifdef XML_DTD
613 XML_Bool m_isParamEntity;
614 XML_Bool m_useForeignDTD;
615 enum XML_ParamEntityParsing m_paramEntityParsing;
616#endif
Elliott Hughes35e432d2012-09-09 14:23:38 -0700617 unsigned long m_hash_secret_salt;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800618};
619
Haibo Huang40a71912019-10-11 11:13:39 -0700620#define MALLOC(parser, s) (parser->m_mem.malloc_fcn((s)))
621#define REALLOC(parser, p, s) (parser->m_mem.realloc_fcn((p), (s)))
622#define FREE(parser, p) (parser->m_mem.free_fcn((p)))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800623
624XML_Parser XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -0700625XML_ParserCreate(const XML_Char *encodingName) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800626 return XML_ParserCreate_MM(encodingName, NULL, NULL);
627}
628
629XML_Parser XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -0700630XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800631 XML_Char tmp[2];
632 *tmp = nsSep;
633 return XML_ParserCreate_MM(encodingName, NULL, tmp);
634}
635
Haibo Huang40a71912019-10-11 11:13:39 -0700636static const XML_Char implicitContext[]
637 = {ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h,
638 ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH,
639 ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD,
640 ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r,
641 ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L,
642 ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8,
643 ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e,
644 ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e,
645 '\0'};
Elliott Hughes72472942018-01-10 08:36:10 -0800646
647/* To avoid warnings about unused functions: */
648#if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM)
649
Haibo Huang40a71912019-10-11 11:13:39 -0700650# if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
Elliott Hughes72472942018-01-10 08:36:10 -0800651
652/* Obtain entropy on Linux 3.17+ */
653static int
Haibo Huang40a71912019-10-11 11:13:39 -0700654writeRandomBytes_getrandom_nonblock(void *target, size_t count) {
655 int success = 0; /* full count bytes written? */
Elliott Hughes72472942018-01-10 08:36:10 -0800656 size_t bytesWrittenTotal = 0;
657 const unsigned int getrandomFlags = GRND_NONBLOCK;
658
659 do {
Haibo Huang40a71912019-10-11 11:13:39 -0700660 void *const currentTarget = (void *)((char *)target + bytesWrittenTotal);
Elliott Hughes72472942018-01-10 08:36:10 -0800661 const size_t bytesToWrite = count - bytesWrittenTotal;
662
663 const int bytesWrittenMore =
Haibo Huang40a71912019-10-11 11:13:39 -0700664# if defined(HAVE_GETRANDOM)
Elliott Hughes72472942018-01-10 08:36:10 -0800665 getrandom(currentTarget, bytesToWrite, getrandomFlags);
Haibo Huang40a71912019-10-11 11:13:39 -0700666# else
Elliott Hughes72472942018-01-10 08:36:10 -0800667 syscall(SYS_getrandom, currentTarget, bytesToWrite, getrandomFlags);
Haibo Huang40a71912019-10-11 11:13:39 -0700668# endif
Elliott Hughes72472942018-01-10 08:36:10 -0800669
670 if (bytesWrittenMore > 0) {
671 bytesWrittenTotal += bytesWrittenMore;
672 if (bytesWrittenTotal >= count)
673 success = 1;
674 }
675 } while (! success && (errno == EINTR));
676
677 return success;
678}
679
Haibo Huang40a71912019-10-11 11:13:39 -0700680# endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */
Elliott Hughes72472942018-01-10 08:36:10 -0800681
Haibo Huang40a71912019-10-11 11:13:39 -0700682# if ! defined(_WIN32) && defined(XML_DEV_URANDOM)
Elliott Hughes72472942018-01-10 08:36:10 -0800683
684/* Extract entropy from /dev/urandom */
685static int
Haibo Huang40a71912019-10-11 11:13:39 -0700686writeRandomBytes_dev_urandom(void *target, size_t count) {
687 int success = 0; /* full count bytes written? */
Elliott Hughes72472942018-01-10 08:36:10 -0800688 size_t bytesWrittenTotal = 0;
689
690 const int fd = open("/dev/urandom", O_RDONLY);
691 if (fd < 0) {
692 return 0;
693 }
694
695 do {
Haibo Huang40a71912019-10-11 11:13:39 -0700696 void *const currentTarget = (void *)((char *)target + bytesWrittenTotal);
Elliott Hughes72472942018-01-10 08:36:10 -0800697 const size_t bytesToWrite = count - bytesWrittenTotal;
698
699 const ssize_t bytesWrittenMore = read(fd, currentTarget, bytesToWrite);
700
701 if (bytesWrittenMore > 0) {
702 bytesWrittenTotal += bytesWrittenMore;
703 if (bytesWrittenTotal >= count)
704 success = 1;
705 }
706 } while (! success && (errno == EINTR));
707
708 close(fd);
709 return success;
710}
711
Haibo Huang40a71912019-10-11 11:13:39 -0700712# endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */
Elliott Hughes72472942018-01-10 08:36:10 -0800713
Haibo Huang40a71912019-10-11 11:13:39 -0700714#endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */
Elliott Hughes72472942018-01-10 08:36:10 -0800715
Haibo Huangfd5e81a2019-06-20 12:09:36 -0700716#if defined(HAVE_ARC4RANDOM) && ! defined(HAVE_ARC4RANDOM_BUF)
Elliott Hughes72472942018-01-10 08:36:10 -0800717
718static void
Haibo Huang40a71912019-10-11 11:13:39 -0700719writeRandomBytes_arc4random(void *target, size_t count) {
Elliott Hughes72472942018-01-10 08:36:10 -0800720 size_t bytesWrittenTotal = 0;
721
722 while (bytesWrittenTotal < count) {
723 const uint32_t random32 = arc4random();
724 size_t i = 0;
725
726 for (; (i < sizeof(random32)) && (bytesWrittenTotal < count);
Haibo Huang40a71912019-10-11 11:13:39 -0700727 i++, bytesWrittenTotal++) {
Elliott Hughes72472942018-01-10 08:36:10 -0800728 const uint8_t random8 = (uint8_t)(random32 >> (i * 8));
729 ((uint8_t *)target)[bytesWrittenTotal] = random8;
730 }
731 }
732}
733
Haibo Huang40a71912019-10-11 11:13:39 -0700734#endif /* defined(HAVE_ARC4RANDOM) && ! defined(HAVE_ARC4RANDOM_BUF) */
Elliott Hughes72472942018-01-10 08:36:10 -0800735
736#ifdef _WIN32
737
Haibo Huangd1a324a2020-10-28 22:19:36 -0700738/* Provide declaration of rand_s() for MinGW-32 (not 64, which has it),
739 as it didn't declare it in its header prior to version 5.3.0 of its
740 runtime package (mingwrt, containing stdlib.h). The upstream fix
741 was introduced at https://osdn.net/projects/mingw/ticket/39658 . */
742# if defined(__MINGW32__) && defined(__MINGW32_VERSION) \
743 && __MINGW32_VERSION < 5003000L && ! defined(__MINGW64_VERSION_MAJOR)
744__declspec(dllimport) int rand_s(unsigned int *);
745# endif
746
Haibo Huang40a71912019-10-11 11:13:39 -0700747/* Obtain entropy on Windows using the rand_s() function which
748 * generates cryptographically secure random numbers. Internally it
749 * uses RtlGenRandom API which is present in Windows XP and later.
Elliott Hughes72472942018-01-10 08:36:10 -0800750 */
751static int
Haibo Huang40a71912019-10-11 11:13:39 -0700752writeRandomBytes_rand_s(void *target, size_t count) {
753 size_t bytesWrittenTotal = 0;
Elliott Hughes72472942018-01-10 08:36:10 -0800754
Haibo Huang40a71912019-10-11 11:13:39 -0700755 while (bytesWrittenTotal < count) {
756 unsigned int random32 = 0;
757 size_t i = 0;
758
759 if (rand_s(&random32))
760 return 0; /* failure */
761
762 for (; (i < sizeof(random32)) && (bytesWrittenTotal < count);
763 i++, bytesWrittenTotal++) {
764 const uint8_t random8 = (uint8_t)(random32 >> (i * 8));
765 ((uint8_t *)target)[bytesWrittenTotal] = random8;
Elliott Hughes72472942018-01-10 08:36:10 -0800766 }
Elliott Hughes72472942018-01-10 08:36:10 -0800767 }
Haibo Huang40a71912019-10-11 11:13:39 -0700768 return 1; /* success */
Elliott Hughes72472942018-01-10 08:36:10 -0800769}
770
771#endif /* _WIN32 */
772
Elliott Hughes72472942018-01-10 08:36:10 -0800773#if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM)
774
Elliott Hughes35e432d2012-09-09 14:23:38 -0700775static unsigned long
Haibo Huang40a71912019-10-11 11:13:39 -0700776gather_time_entropy(void) {
777# ifdef _WIN32
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100778 FILETIME ft;
779 GetSystemTimeAsFileTime(&ft); /* never fails */
780 return ft.dwHighDateTime ^ ft.dwLowDateTime;
Haibo Huang40a71912019-10-11 11:13:39 -0700781# else
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100782 struct timeval tv;
783 int gettimeofday_res;
784
785 gettimeofday_res = gettimeofday(&tv, NULL);
Elliott Hughes72472942018-01-10 08:36:10 -0800786
Haibo Huang40a71912019-10-11 11:13:39 -0700787# if defined(NDEBUG)
Elliott Hughes72472942018-01-10 08:36:10 -0800788 (void)gettimeofday_res;
Haibo Huang40a71912019-10-11 11:13:39 -0700789# else
790 assert(gettimeofday_res == 0);
791# endif /* defined(NDEBUG) */
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100792
793 /* Microseconds time is <20 bits entropy */
794 return tv.tv_usec;
Haibo Huang40a71912019-10-11 11:13:39 -0700795# endif
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100796}
797
Haibo Huang40a71912019-10-11 11:13:39 -0700798#endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */
Elliott Hughes72472942018-01-10 08:36:10 -0800799
800static unsigned long
Haibo Huang40a71912019-10-11 11:13:39 -0700801ENTROPY_DEBUG(const char *label, unsigned long entropy) {
802 const char *const EXPAT_ENTROPY_DEBUG = getenv("EXPAT_ENTROPY_DEBUG");
Elliott Hughes72472942018-01-10 08:36:10 -0800803 if (EXPAT_ENTROPY_DEBUG && ! strcmp(EXPAT_ENTROPY_DEBUG, "1")) {
Haibo Huang40a71912019-10-11 11:13:39 -0700804 fprintf(stderr, "Entropy: %s --> 0x%0*lx (%lu bytes)\n", label,
805 (int)sizeof(entropy) * 2, entropy, (unsigned long)sizeof(entropy));
Elliott Hughes72472942018-01-10 08:36:10 -0800806 }
807 return entropy;
808}
809
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100810static unsigned long
Haibo Huang40a71912019-10-11 11:13:39 -0700811generate_hash_secret_salt(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -0800812 unsigned long entropy;
813 (void)parser;
814
815 /* "Failproof" high quality providers: */
816#if defined(HAVE_ARC4RANDOM_BUF)
817 arc4random_buf(&entropy, sizeof(entropy));
818 return ENTROPY_DEBUG("arc4random_buf", entropy);
819#elif defined(HAVE_ARC4RANDOM)
820 writeRandomBytes_arc4random((void *)&entropy, sizeof(entropy));
821 return ENTROPY_DEBUG("arc4random", entropy);
822#else
823 /* Try high quality providers first .. */
Haibo Huang40a71912019-10-11 11:13:39 -0700824# ifdef _WIN32
825 if (writeRandomBytes_rand_s((void *)&entropy, sizeof(entropy))) {
826 return ENTROPY_DEBUG("rand_s", entropy);
Elliott Hughes72472942018-01-10 08:36:10 -0800827 }
Haibo Huang40a71912019-10-11 11:13:39 -0700828# elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
Elliott Hughes72472942018-01-10 08:36:10 -0800829 if (writeRandomBytes_getrandom_nonblock((void *)&entropy, sizeof(entropy))) {
830 return ENTROPY_DEBUG("getrandom", entropy);
831 }
Haibo Huang40a71912019-10-11 11:13:39 -0700832# endif
833# if ! defined(_WIN32) && defined(XML_DEV_URANDOM)
Elliott Hughes72472942018-01-10 08:36:10 -0800834 if (writeRandomBytes_dev_urandom((void *)&entropy, sizeof(entropy))) {
835 return ENTROPY_DEBUG("/dev/urandom", entropy);
836 }
Haibo Huang40a71912019-10-11 11:13:39 -0700837# endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */
Elliott Hughes72472942018-01-10 08:36:10 -0800838 /* .. and self-made low quality for backup: */
839
840 /* Process ID is 0 bits entropy if attacker has local access */
841 entropy = gather_time_entropy() ^ getpid();
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100842
843 /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */
844 if (sizeof(unsigned long) == 4) {
Elliott Hughes72472942018-01-10 08:36:10 -0800845 return ENTROPY_DEBUG("fallback(4)", entropy * 2147483647);
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100846 } else {
Elliott Hughes72472942018-01-10 08:36:10 -0800847 return ENTROPY_DEBUG("fallback(8)",
Haibo Huang40a71912019-10-11 11:13:39 -0700848 entropy * (unsigned long)2305843009213693951ULL);
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100849 }
Elliott Hughes72472942018-01-10 08:36:10 -0800850#endif
851}
852
853static unsigned long
854get_hash_secret_salt(XML_Parser parser) {
855 if (parser->m_parentParser != NULL)
856 return get_hash_secret_salt(parser->m_parentParser);
857 return parser->m_hash_secret_salt;
Elliott Hughes35e432d2012-09-09 14:23:38 -0700858}
859
Haibo Huang40a71912019-10-11 11:13:39 -0700860static XML_Bool /* only valid for root parser */
861startParsing(XML_Parser parser) {
862 /* hash functions must be initialized before setContext() is called */
863 if (parser->m_hash_secret_salt == 0)
864 parser->m_hash_secret_salt = generate_hash_secret_salt(parser);
865 if (parser->m_ns) {
866 /* implicit context only set for root parser, since child
867 parsers (i.e. external entity parsers) will inherit it
868 */
869 return setContext(parser, implicitContext);
870 }
871 return XML_TRUE;
Elliott Hughes35e432d2012-09-09 14:23:38 -0700872}
873
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800874XML_Parser XMLCALL
875XML_ParserCreate_MM(const XML_Char *encodingName,
876 const XML_Memory_Handling_Suite *memsuite,
Haibo Huang40a71912019-10-11 11:13:39 -0700877 const XML_Char *nameSep) {
Elliott Hughes35e432d2012-09-09 14:23:38 -0700878 return parserCreate(encodingName, memsuite, nameSep, NULL);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800879}
880
881static XML_Parser
882parserCreate(const XML_Char *encodingName,
Haibo Huang40a71912019-10-11 11:13:39 -0700883 const XML_Memory_Handling_Suite *memsuite, const XML_Char *nameSep,
884 DTD *dtd) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800885 XML_Parser parser;
886
887 if (memsuite) {
888 XML_Memory_Handling_Suite *mtemp;
Haibo Huang40a71912019-10-11 11:13:39 -0700889 parser = (XML_Parser)memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800890 if (parser != NULL) {
891 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
892 mtemp->malloc_fcn = memsuite->malloc_fcn;
893 mtemp->realloc_fcn = memsuite->realloc_fcn;
894 mtemp->free_fcn = memsuite->free_fcn;
895 }
Haibo Huang40a71912019-10-11 11:13:39 -0700896 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800897 XML_Memory_Handling_Suite *mtemp;
898 parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
899 if (parser != NULL) {
900 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
901 mtemp->malloc_fcn = malloc;
902 mtemp->realloc_fcn = realloc;
903 mtemp->free_fcn = free;
904 }
905 }
906
Haibo Huang40a71912019-10-11 11:13:39 -0700907 if (! parser)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800908 return parser;
909
Elliott Hughes72472942018-01-10 08:36:10 -0800910 parser->m_buffer = NULL;
911 parser->m_bufferLim = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800912
Elliott Hughes72472942018-01-10 08:36:10 -0800913 parser->m_attsSize = INIT_ATTS_SIZE;
Haibo Huang40a71912019-10-11 11:13:39 -0700914 parser->m_atts
915 = (ATTRIBUTE *)MALLOC(parser, parser->m_attsSize * sizeof(ATTRIBUTE));
Elliott Hughes72472942018-01-10 08:36:10 -0800916 if (parser->m_atts == NULL) {
917 FREE(parser, parser);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800918 return NULL;
919 }
Elliott Hughes35e432d2012-09-09 14:23:38 -0700920#ifdef XML_ATTR_INFO
Haibo Huang40a71912019-10-11 11:13:39 -0700921 parser->m_attInfo = (XML_AttrInfo *)MALLOC(
922 parser, parser->m_attsSize * sizeof(XML_AttrInfo));
Elliott Hughes72472942018-01-10 08:36:10 -0800923 if (parser->m_attInfo == NULL) {
924 FREE(parser, parser->m_atts);
925 FREE(parser, parser);
Elliott Hughes35e432d2012-09-09 14:23:38 -0700926 return NULL;
927 }
928#endif
Haibo Huang40a71912019-10-11 11:13:39 -0700929 parser->m_dataBuf
930 = (XML_Char *)MALLOC(parser, INIT_DATA_BUF_SIZE * sizeof(XML_Char));
Elliott Hughes72472942018-01-10 08:36:10 -0800931 if (parser->m_dataBuf == NULL) {
932 FREE(parser, parser->m_atts);
Elliott Hughes35e432d2012-09-09 14:23:38 -0700933#ifdef XML_ATTR_INFO
Elliott Hughes72472942018-01-10 08:36:10 -0800934 FREE(parser, parser->m_attInfo);
Elliott Hughes35e432d2012-09-09 14:23:38 -0700935#endif
Elliott Hughes72472942018-01-10 08:36:10 -0800936 FREE(parser, parser);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800937 return NULL;
938 }
Elliott Hughes72472942018-01-10 08:36:10 -0800939 parser->m_dataBufEnd = parser->m_dataBuf + INIT_DATA_BUF_SIZE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800940
941 if (dtd)
Elliott Hughes72472942018-01-10 08:36:10 -0800942 parser->m_dtd = dtd;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800943 else {
Elliott Hughes72472942018-01-10 08:36:10 -0800944 parser->m_dtd = dtdCreate(&parser->m_mem);
945 if (parser->m_dtd == NULL) {
946 FREE(parser, parser->m_dataBuf);
947 FREE(parser, parser->m_atts);
Elliott Hughes35e432d2012-09-09 14:23:38 -0700948#ifdef XML_ATTR_INFO
Elliott Hughes72472942018-01-10 08:36:10 -0800949 FREE(parser, parser->m_attInfo);
Elliott Hughes35e432d2012-09-09 14:23:38 -0700950#endif
Elliott Hughes72472942018-01-10 08:36:10 -0800951 FREE(parser, parser);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800952 return NULL;
953 }
954 }
955
Elliott Hughes72472942018-01-10 08:36:10 -0800956 parser->m_freeBindingList = NULL;
957 parser->m_freeTagList = NULL;
958 parser->m_freeInternalEntities = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800959
Elliott Hughes72472942018-01-10 08:36:10 -0800960 parser->m_groupSize = 0;
961 parser->m_groupConnector = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800962
Elliott Hughes72472942018-01-10 08:36:10 -0800963 parser->m_unknownEncodingHandler = NULL;
964 parser->m_unknownEncodingHandlerData = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800965
Elliott Hughes72472942018-01-10 08:36:10 -0800966 parser->m_namespaceSeparator = ASCII_EXCL;
967 parser->m_ns = XML_FALSE;
968 parser->m_ns_triplets = XML_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800969
Elliott Hughes72472942018-01-10 08:36:10 -0800970 parser->m_nsAtts = NULL;
971 parser->m_nsAttsVersion = 0;
972 parser->m_nsAttsPower = 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800973
Elliott Hughes72472942018-01-10 08:36:10 -0800974 parser->m_protocolEncodingName = NULL;
975
976 poolInit(&parser->m_tempPool, &(parser->m_mem));
977 poolInit(&parser->m_temp2Pool, &(parser->m_mem));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800978 parserInit(parser, encodingName);
979
Haibo Huang40a71912019-10-11 11:13:39 -0700980 if (encodingName && ! parser->m_protocolEncodingName) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800981 XML_ParserFree(parser);
982 return NULL;
983 }
984
985 if (nameSep) {
Elliott Hughes72472942018-01-10 08:36:10 -0800986 parser->m_ns = XML_TRUE;
987 parser->m_internalEncoding = XmlGetInternalEncodingNS();
988 parser->m_namespaceSeparator = *nameSep;
Haibo Huang40a71912019-10-11 11:13:39 -0700989 } else {
Elliott Hughes72472942018-01-10 08:36:10 -0800990 parser->m_internalEncoding = XmlGetInternalEncoding();
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800991 }
992
993 return parser;
994}
995
996static void
Haibo Huang40a71912019-10-11 11:13:39 -0700997parserInit(XML_Parser parser, const XML_Char *encodingName) {
Elliott Hughes72472942018-01-10 08:36:10 -0800998 parser->m_processor = prologInitProcessor;
999 XmlPrologStateInit(&parser->m_prologState);
1000 if (encodingName != NULL) {
1001 parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem));
1002 }
1003 parser->m_curBase = NULL;
1004 XmlInitEncoding(&parser->m_initEncoding, &parser->m_encoding, 0);
1005 parser->m_userData = NULL;
1006 parser->m_handlerArg = NULL;
1007 parser->m_startElementHandler = NULL;
1008 parser->m_endElementHandler = NULL;
1009 parser->m_characterDataHandler = NULL;
1010 parser->m_processingInstructionHandler = NULL;
1011 parser->m_commentHandler = NULL;
1012 parser->m_startCdataSectionHandler = NULL;
1013 parser->m_endCdataSectionHandler = NULL;
1014 parser->m_defaultHandler = NULL;
1015 parser->m_startDoctypeDeclHandler = NULL;
1016 parser->m_endDoctypeDeclHandler = NULL;
1017 parser->m_unparsedEntityDeclHandler = NULL;
1018 parser->m_notationDeclHandler = NULL;
1019 parser->m_startNamespaceDeclHandler = NULL;
1020 parser->m_endNamespaceDeclHandler = NULL;
1021 parser->m_notStandaloneHandler = NULL;
1022 parser->m_externalEntityRefHandler = NULL;
1023 parser->m_externalEntityRefHandlerArg = parser;
1024 parser->m_skippedEntityHandler = NULL;
1025 parser->m_elementDeclHandler = NULL;
1026 parser->m_attlistDeclHandler = NULL;
1027 parser->m_entityDeclHandler = NULL;
1028 parser->m_xmlDeclHandler = NULL;
1029 parser->m_bufferPtr = parser->m_buffer;
1030 parser->m_bufferEnd = parser->m_buffer;
1031 parser->m_parseEndByteIndex = 0;
1032 parser->m_parseEndPtr = NULL;
1033 parser->m_declElementType = NULL;
1034 parser->m_declAttributeId = NULL;
1035 parser->m_declEntity = NULL;
1036 parser->m_doctypeName = NULL;
1037 parser->m_doctypeSysid = NULL;
1038 parser->m_doctypePubid = NULL;
1039 parser->m_declAttributeType = NULL;
1040 parser->m_declNotationName = NULL;
1041 parser->m_declNotationPublicId = NULL;
1042 parser->m_declAttributeIsCdata = XML_FALSE;
1043 parser->m_declAttributeIsId = XML_FALSE;
1044 memset(&parser->m_position, 0, sizeof(POSITION));
1045 parser->m_errorCode = XML_ERROR_NONE;
1046 parser->m_eventPtr = NULL;
1047 parser->m_eventEndPtr = NULL;
1048 parser->m_positionPtr = NULL;
1049 parser->m_openInternalEntities = NULL;
1050 parser->m_defaultExpandInternalEntities = XML_TRUE;
1051 parser->m_tagLevel = 0;
1052 parser->m_tagStack = NULL;
1053 parser->m_inheritedBindings = NULL;
1054 parser->m_nSpecifiedAtts = 0;
1055 parser->m_unknownEncodingMem = NULL;
1056 parser->m_unknownEncodingRelease = NULL;
1057 parser->m_unknownEncodingData = NULL;
1058 parser->m_parentParser = NULL;
1059 parser->m_parsingStatus.parsing = XML_INITIALIZED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001060#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08001061 parser->m_isParamEntity = XML_FALSE;
1062 parser->m_useForeignDTD = XML_FALSE;
1063 parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001064#endif
Elliott Hughes72472942018-01-10 08:36:10 -08001065 parser->m_hash_secret_salt = 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001066}
1067
Elliott Hughes72472942018-01-10 08:36:10 -08001068/* moves list of bindings to m_freeBindingList */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001069static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001070moveToFreeBindingList(XML_Parser parser, BINDING *bindings) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001071 while (bindings) {
1072 BINDING *b = bindings;
1073 bindings = bindings->nextTagBinding;
Elliott Hughes72472942018-01-10 08:36:10 -08001074 b->nextTagBinding = parser->m_freeBindingList;
1075 parser->m_freeBindingList = b;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001076 }
1077}
1078
1079XML_Bool XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001080XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001081 TAG *tStk;
1082 OPEN_INTERNAL_ENTITY *openEntityList;
Elliott Hughes72472942018-01-10 08:36:10 -08001083
1084 if (parser == NULL)
Haibo Huang40a71912019-10-11 11:13:39 -07001085 return XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08001086
1087 if (parser->m_parentParser)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001088 return XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08001089 /* move m_tagStack to m_freeTagList */
1090 tStk = parser->m_tagStack;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001091 while (tStk) {
1092 TAG *tag = tStk;
1093 tStk = tStk->parent;
Elliott Hughes72472942018-01-10 08:36:10 -08001094 tag->parent = parser->m_freeTagList;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001095 moveToFreeBindingList(parser, tag->bindings);
1096 tag->bindings = NULL;
Elliott Hughes72472942018-01-10 08:36:10 -08001097 parser->m_freeTagList = tag;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001098 }
Elliott Hughes72472942018-01-10 08:36:10 -08001099 /* move m_openInternalEntities to m_freeInternalEntities */
1100 openEntityList = parser->m_openInternalEntities;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001101 while (openEntityList) {
1102 OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
1103 openEntityList = openEntity->next;
Elliott Hughes72472942018-01-10 08:36:10 -08001104 openEntity->next = parser->m_freeInternalEntities;
1105 parser->m_freeInternalEntities = openEntity;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001106 }
Elliott Hughes72472942018-01-10 08:36:10 -08001107 moveToFreeBindingList(parser, parser->m_inheritedBindings);
1108 FREE(parser, parser->m_unknownEncodingMem);
1109 if (parser->m_unknownEncodingRelease)
1110 parser->m_unknownEncodingRelease(parser->m_unknownEncodingData);
1111 poolClear(&parser->m_tempPool);
1112 poolClear(&parser->m_temp2Pool);
1113 FREE(parser, (void *)parser->m_protocolEncodingName);
1114 parser->m_protocolEncodingName = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001115 parserInit(parser, encodingName);
Elliott Hughes72472942018-01-10 08:36:10 -08001116 dtdReset(parser->m_dtd, &parser->m_mem);
Elliott Hughes35e432d2012-09-09 14:23:38 -07001117 return XML_TRUE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001118}
1119
1120enum XML_Status XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001121XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) {
Elliott Hughes72472942018-01-10 08:36:10 -08001122 if (parser == NULL)
Haibo Huang40a71912019-10-11 11:13:39 -07001123 return XML_STATUS_ERROR;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001124 /* Block after XML_Parse()/XML_ParseBuffer() has been called.
1125 XXX There's no way for the caller to determine which of the
1126 XXX possible error cases caused the XML_STATUS_ERROR return.
1127 */
Haibo Huang40a71912019-10-11 11:13:39 -07001128 if (parser->m_parsingStatus.parsing == XML_PARSING
1129 || parser->m_parsingStatus.parsing == XML_SUSPENDED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001130 return XML_STATUS_ERROR;
Elliott Hughes72472942018-01-10 08:36:10 -08001131
1132 /* Get rid of any previous encoding name */
1133 FREE(parser, (void *)parser->m_protocolEncodingName);
1134
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001135 if (encodingName == NULL)
Elliott Hughes72472942018-01-10 08:36:10 -08001136 /* No new encoding name */
1137 parser->m_protocolEncodingName = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001138 else {
Elliott Hughes72472942018-01-10 08:36:10 -08001139 /* Copy the new encoding name into allocated memory */
1140 parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem));
Haibo Huang40a71912019-10-11 11:13:39 -07001141 if (! parser->m_protocolEncodingName)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001142 return XML_STATUS_ERROR;
1143 }
1144 return XML_STATUS_OK;
1145}
1146
1147XML_Parser XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001148XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context,
1149 const XML_Char *encodingName) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001150 XML_Parser parser = oldParser;
1151 DTD *newDtd = NULL;
Elliott Hughes72472942018-01-10 08:36:10 -08001152 DTD *oldDtd;
1153 XML_StartElementHandler oldStartElementHandler;
1154 XML_EndElementHandler oldEndElementHandler;
1155 XML_CharacterDataHandler oldCharacterDataHandler;
1156 XML_ProcessingInstructionHandler oldProcessingInstructionHandler;
1157 XML_CommentHandler oldCommentHandler;
1158 XML_StartCdataSectionHandler oldStartCdataSectionHandler;
1159 XML_EndCdataSectionHandler oldEndCdataSectionHandler;
1160 XML_DefaultHandler oldDefaultHandler;
1161 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler;
1162 XML_NotationDeclHandler oldNotationDeclHandler;
1163 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler;
1164 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler;
1165 XML_NotStandaloneHandler oldNotStandaloneHandler;
1166 XML_ExternalEntityRefHandler oldExternalEntityRefHandler;
1167 XML_SkippedEntityHandler oldSkippedEntityHandler;
1168 XML_UnknownEncodingHandler oldUnknownEncodingHandler;
1169 XML_ElementDeclHandler oldElementDeclHandler;
1170 XML_AttlistDeclHandler oldAttlistDeclHandler;
1171 XML_EntityDeclHandler oldEntityDeclHandler;
1172 XML_XmlDeclHandler oldXmlDeclHandler;
Haibo Huang40a71912019-10-11 11:13:39 -07001173 ELEMENT_TYPE *oldDeclElementType;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001174
Elliott Hughes72472942018-01-10 08:36:10 -08001175 void *oldUserData;
1176 void *oldHandlerArg;
1177 XML_Bool oldDefaultExpandInternalEntities;
1178 XML_Parser oldExternalEntityRefHandlerArg;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001179#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08001180 enum XML_ParamEntityParsing oldParamEntityParsing;
1181 int oldInEntityValue;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001182#endif
Elliott Hughes72472942018-01-10 08:36:10 -08001183 XML_Bool oldns_triplets;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001184 /* Note that the new parser shares the same hash secret as the old
1185 parser, so that dtdCopy and copyEntityTable can lookup values
1186 from hash tables associated with either parser without us having
1187 to worry which hash secrets each table has.
1188 */
Elliott Hughes72472942018-01-10 08:36:10 -08001189 unsigned long oldhash_secret_salt;
1190
1191 /* Validate the oldParser parameter before we pull everything out of it */
1192 if (oldParser == NULL)
1193 return NULL;
1194
1195 /* Stash the original parser contents on the stack */
1196 oldDtd = parser->m_dtd;
1197 oldStartElementHandler = parser->m_startElementHandler;
1198 oldEndElementHandler = parser->m_endElementHandler;
1199 oldCharacterDataHandler = parser->m_characterDataHandler;
1200 oldProcessingInstructionHandler = parser->m_processingInstructionHandler;
1201 oldCommentHandler = parser->m_commentHandler;
1202 oldStartCdataSectionHandler = parser->m_startCdataSectionHandler;
1203 oldEndCdataSectionHandler = parser->m_endCdataSectionHandler;
1204 oldDefaultHandler = parser->m_defaultHandler;
1205 oldUnparsedEntityDeclHandler = parser->m_unparsedEntityDeclHandler;
1206 oldNotationDeclHandler = parser->m_notationDeclHandler;
1207 oldStartNamespaceDeclHandler = parser->m_startNamespaceDeclHandler;
1208 oldEndNamespaceDeclHandler = parser->m_endNamespaceDeclHandler;
1209 oldNotStandaloneHandler = parser->m_notStandaloneHandler;
1210 oldExternalEntityRefHandler = parser->m_externalEntityRefHandler;
1211 oldSkippedEntityHandler = parser->m_skippedEntityHandler;
1212 oldUnknownEncodingHandler = parser->m_unknownEncodingHandler;
1213 oldElementDeclHandler = parser->m_elementDeclHandler;
1214 oldAttlistDeclHandler = parser->m_attlistDeclHandler;
1215 oldEntityDeclHandler = parser->m_entityDeclHandler;
1216 oldXmlDeclHandler = parser->m_xmlDeclHandler;
1217 oldDeclElementType = parser->m_declElementType;
1218
1219 oldUserData = parser->m_userData;
1220 oldHandlerArg = parser->m_handlerArg;
1221 oldDefaultExpandInternalEntities = parser->m_defaultExpandInternalEntities;
1222 oldExternalEntityRefHandlerArg = parser->m_externalEntityRefHandlerArg;
1223#ifdef XML_DTD
1224 oldParamEntityParsing = parser->m_paramEntityParsing;
1225 oldInEntityValue = parser->m_prologState.inEntityValue;
1226#endif
1227 oldns_triplets = parser->m_ns_triplets;
1228 /* Note that the new parser shares the same hash secret as the old
1229 parser, so that dtdCopy and copyEntityTable can lookup values
1230 from hash tables associated with either parser without us having
1231 to worry which hash secrets each table has.
1232 */
1233 oldhash_secret_salt = parser->m_hash_secret_salt;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001234
1235#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07001236 if (! context)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001237 newDtd = oldDtd;
1238#endif /* XML_DTD */
1239
1240 /* Note that the magical uses of the pre-processor to make field
1241 access look more like C++ require that `parser' be overwritten
1242 here. This makes this function more painful to follow than it
1243 would be otherwise.
1244 */
Elliott Hughes72472942018-01-10 08:36:10 -08001245 if (parser->m_ns) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001246 XML_Char tmp[2];
Elliott Hughes72472942018-01-10 08:36:10 -08001247 *tmp = parser->m_namespaceSeparator;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001248 parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
Haibo Huang40a71912019-10-11 11:13:39 -07001249 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001250 parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
1251 }
1252
Haibo Huang40a71912019-10-11 11:13:39 -07001253 if (! parser)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001254 return NULL;
1255
Elliott Hughes72472942018-01-10 08:36:10 -08001256 parser->m_startElementHandler = oldStartElementHandler;
1257 parser->m_endElementHandler = oldEndElementHandler;
1258 parser->m_characterDataHandler = oldCharacterDataHandler;
1259 parser->m_processingInstructionHandler = oldProcessingInstructionHandler;
1260 parser->m_commentHandler = oldCommentHandler;
1261 parser->m_startCdataSectionHandler = oldStartCdataSectionHandler;
1262 parser->m_endCdataSectionHandler = oldEndCdataSectionHandler;
1263 parser->m_defaultHandler = oldDefaultHandler;
1264 parser->m_unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
1265 parser->m_notationDeclHandler = oldNotationDeclHandler;
1266 parser->m_startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
1267 parser->m_endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
1268 parser->m_notStandaloneHandler = oldNotStandaloneHandler;
1269 parser->m_externalEntityRefHandler = oldExternalEntityRefHandler;
1270 parser->m_skippedEntityHandler = oldSkippedEntityHandler;
1271 parser->m_unknownEncodingHandler = oldUnknownEncodingHandler;
1272 parser->m_elementDeclHandler = oldElementDeclHandler;
1273 parser->m_attlistDeclHandler = oldAttlistDeclHandler;
1274 parser->m_entityDeclHandler = oldEntityDeclHandler;
1275 parser->m_xmlDeclHandler = oldXmlDeclHandler;
1276 parser->m_declElementType = oldDeclElementType;
1277 parser->m_userData = oldUserData;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001278 if (oldUserData == oldHandlerArg)
Elliott Hughes72472942018-01-10 08:36:10 -08001279 parser->m_handlerArg = parser->m_userData;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001280 else
Elliott Hughes72472942018-01-10 08:36:10 -08001281 parser->m_handlerArg = parser;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001282 if (oldExternalEntityRefHandlerArg != oldParser)
Elliott Hughes72472942018-01-10 08:36:10 -08001283 parser->m_externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
1284 parser->m_defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
1285 parser->m_ns_triplets = oldns_triplets;
1286 parser->m_hash_secret_salt = oldhash_secret_salt;
1287 parser->m_parentParser = oldParser;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001288#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08001289 parser->m_paramEntityParsing = oldParamEntityParsing;
1290 parser->m_prologState.inEntityValue = oldInEntityValue;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001291 if (context) {
1292#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07001293 if (! dtdCopy(oldParser, parser->m_dtd, oldDtd, &parser->m_mem)
1294 || ! setContext(parser, context)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001295 XML_ParserFree(parser);
1296 return NULL;
1297 }
Elliott Hughes72472942018-01-10 08:36:10 -08001298 parser->m_processor = externalEntityInitProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001299#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07001300 } else {
1301 /* The DTD instance referenced by parser->m_dtd is shared between the
1302 document's root parser and external PE parsers, therefore one does not
1303 need to call setContext. In addition, one also *must* not call
1304 setContext, because this would overwrite existing prefix->binding
1305 pointers in parser->m_dtd with ones that get destroyed with the external
1306 PE parser. This would leave those prefixes with dangling pointers.
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001307 */
Elliott Hughes72472942018-01-10 08:36:10 -08001308 parser->m_isParamEntity = XML_TRUE;
1309 XmlPrologStateInitExternalEntity(&parser->m_prologState);
1310 parser->m_processor = externalParEntInitProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001311 }
1312#endif /* XML_DTD */
1313 return parser;
1314}
1315
1316static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001317destroyBindings(BINDING *bindings, XML_Parser parser) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001318 for (;;) {
1319 BINDING *b = bindings;
Haibo Huang40a71912019-10-11 11:13:39 -07001320 if (! b)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001321 break;
1322 bindings = b->nextTagBinding;
Elliott Hughes72472942018-01-10 08:36:10 -08001323 FREE(parser, b->uri);
1324 FREE(parser, b);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001325 }
1326}
1327
1328void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001329XML_ParserFree(XML_Parser parser) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001330 TAG *tagList;
1331 OPEN_INTERNAL_ENTITY *entityList;
1332 if (parser == NULL)
1333 return;
Elliott Hughes72472942018-01-10 08:36:10 -08001334 /* free m_tagStack and m_freeTagList */
1335 tagList = parser->m_tagStack;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001336 for (;;) {
1337 TAG *p;
1338 if (tagList == NULL) {
Elliott Hughes72472942018-01-10 08:36:10 -08001339 if (parser->m_freeTagList == NULL)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001340 break;
Elliott Hughes72472942018-01-10 08:36:10 -08001341 tagList = parser->m_freeTagList;
1342 parser->m_freeTagList = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001343 }
1344 p = tagList;
1345 tagList = tagList->parent;
Elliott Hughes72472942018-01-10 08:36:10 -08001346 FREE(parser, p->buf);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001347 destroyBindings(p->bindings, parser);
Elliott Hughes72472942018-01-10 08:36:10 -08001348 FREE(parser, p);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001349 }
Elliott Hughes72472942018-01-10 08:36:10 -08001350 /* free m_openInternalEntities and m_freeInternalEntities */
1351 entityList = parser->m_openInternalEntities;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001352 for (;;) {
1353 OPEN_INTERNAL_ENTITY *openEntity;
1354 if (entityList == NULL) {
Elliott Hughes72472942018-01-10 08:36:10 -08001355 if (parser->m_freeInternalEntities == NULL)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001356 break;
Elliott Hughes72472942018-01-10 08:36:10 -08001357 entityList = parser->m_freeInternalEntities;
1358 parser->m_freeInternalEntities = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001359 }
1360 openEntity = entityList;
1361 entityList = entityList->next;
Elliott Hughes72472942018-01-10 08:36:10 -08001362 FREE(parser, openEntity);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001363 }
1364
Elliott Hughes72472942018-01-10 08:36:10 -08001365 destroyBindings(parser->m_freeBindingList, parser);
1366 destroyBindings(parser->m_inheritedBindings, parser);
1367 poolDestroy(&parser->m_tempPool);
1368 poolDestroy(&parser->m_temp2Pool);
1369 FREE(parser, (void *)parser->m_protocolEncodingName);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001370#ifdef XML_DTD
1371 /* external parameter entity parsers share the DTD structure
1372 parser->m_dtd with the root parser, so we must not destroy it
1373 */
Haibo Huang40a71912019-10-11 11:13:39 -07001374 if (! parser->m_isParamEntity && parser->m_dtd)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001375#else
Elliott Hughes72472942018-01-10 08:36:10 -08001376 if (parser->m_dtd)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001377#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07001378 dtdDestroy(parser->m_dtd, (XML_Bool)! parser->m_parentParser,
1379 &parser->m_mem);
Elliott Hughes72472942018-01-10 08:36:10 -08001380 FREE(parser, (void *)parser->m_atts);
Elliott Hughes35e432d2012-09-09 14:23:38 -07001381#ifdef XML_ATTR_INFO
Elliott Hughes72472942018-01-10 08:36:10 -08001382 FREE(parser, (void *)parser->m_attInfo);
Elliott Hughes35e432d2012-09-09 14:23:38 -07001383#endif
Elliott Hughes72472942018-01-10 08:36:10 -08001384 FREE(parser, parser->m_groupConnector);
1385 FREE(parser, parser->m_buffer);
1386 FREE(parser, parser->m_dataBuf);
1387 FREE(parser, parser->m_nsAtts);
1388 FREE(parser, parser->m_unknownEncodingMem);
1389 if (parser->m_unknownEncodingRelease)
1390 parser->m_unknownEncodingRelease(parser->m_unknownEncodingData);
1391 FREE(parser, parser);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001392}
1393
1394void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001395XML_UseParserAsHandlerArg(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08001396 if (parser != NULL)
1397 parser->m_handlerArg = parser;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001398}
1399
1400enum XML_Error XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001401XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) {
Elliott Hughes72472942018-01-10 08:36:10 -08001402 if (parser == NULL)
1403 return XML_ERROR_INVALID_ARGUMENT;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001404#ifdef XML_DTD
1405 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Haibo Huang40a71912019-10-11 11:13:39 -07001406 if (parser->m_parsingStatus.parsing == XML_PARSING
1407 || parser->m_parsingStatus.parsing == XML_SUSPENDED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001408 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
Elliott Hughes72472942018-01-10 08:36:10 -08001409 parser->m_useForeignDTD = useDTD;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001410 return XML_ERROR_NONE;
1411#else
Haibo Huangd1a324a2020-10-28 22:19:36 -07001412 UNUSED_P(useDTD);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001413 return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
1414#endif
1415}
1416
1417void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001418XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) {
Elliott Hughes72472942018-01-10 08:36:10 -08001419 if (parser == NULL)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001420 return;
Elliott Hughes72472942018-01-10 08:36:10 -08001421 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Haibo Huang40a71912019-10-11 11:13:39 -07001422 if (parser->m_parsingStatus.parsing == XML_PARSING
1423 || parser->m_parsingStatus.parsing == XML_SUSPENDED)
Elliott Hughes72472942018-01-10 08:36:10 -08001424 return;
1425 parser->m_ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001426}
1427
1428void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001429XML_SetUserData(XML_Parser parser, void *p) {
Elliott Hughes72472942018-01-10 08:36:10 -08001430 if (parser == NULL)
1431 return;
1432 if (parser->m_handlerArg == parser->m_userData)
1433 parser->m_handlerArg = parser->m_userData = p;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001434 else
Elliott Hughes72472942018-01-10 08:36:10 -08001435 parser->m_userData = p;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001436}
1437
1438enum XML_Status XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001439XML_SetBase(XML_Parser parser, const XML_Char *p) {
Elliott Hughes72472942018-01-10 08:36:10 -08001440 if (parser == NULL)
1441 return XML_STATUS_ERROR;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001442 if (p) {
Elliott Hughes72472942018-01-10 08:36:10 -08001443 p = poolCopyString(&parser->m_dtd->pool, p);
Haibo Huang40a71912019-10-11 11:13:39 -07001444 if (! p)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001445 return XML_STATUS_ERROR;
Elliott Hughes72472942018-01-10 08:36:10 -08001446 parser->m_curBase = p;
Haibo Huang40a71912019-10-11 11:13:39 -07001447 } else
Elliott Hughes72472942018-01-10 08:36:10 -08001448 parser->m_curBase = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001449 return XML_STATUS_OK;
1450}
1451
Haibo Huang40a71912019-10-11 11:13:39 -07001452const XML_Char *XMLCALL
1453XML_GetBase(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08001454 if (parser == NULL)
1455 return NULL;
1456 return parser->m_curBase;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001457}
1458
1459int XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001460XML_GetSpecifiedAttributeCount(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08001461 if (parser == NULL)
1462 return -1;
1463 return parser->m_nSpecifiedAtts;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001464}
1465
1466int XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001467XML_GetIdAttributeIndex(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08001468 if (parser == NULL)
1469 return -1;
1470 return parser->m_idAttIndex;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001471}
1472
Elliott Hughes35e432d2012-09-09 14:23:38 -07001473#ifdef XML_ATTR_INFO
Haibo Huang40a71912019-10-11 11:13:39 -07001474const XML_AttrInfo *XMLCALL
1475XML_GetAttributeInfo(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08001476 if (parser == NULL)
1477 return NULL;
1478 return parser->m_attInfo;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001479}
1480#endif
1481
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001482void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001483XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start,
1484 XML_EndElementHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001485 if (parser == NULL)
1486 return;
1487 parser->m_startElementHandler = start;
1488 parser->m_endElementHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001489}
1490
1491void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001492XML_SetStartElementHandler(XML_Parser parser, XML_StartElementHandler start) {
Elliott Hughes72472942018-01-10 08:36:10 -08001493 if (parser != NULL)
1494 parser->m_startElementHandler = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001495}
1496
1497void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001498XML_SetEndElementHandler(XML_Parser parser, XML_EndElementHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001499 if (parser != NULL)
1500 parser->m_endElementHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001501}
1502
1503void XMLCALL
1504XML_SetCharacterDataHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001505 XML_CharacterDataHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001506 if (parser != NULL)
1507 parser->m_characterDataHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001508}
1509
1510void XMLCALL
1511XML_SetProcessingInstructionHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001512 XML_ProcessingInstructionHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001513 if (parser != NULL)
1514 parser->m_processingInstructionHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001515}
1516
1517void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001518XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001519 if (parser != NULL)
1520 parser->m_commentHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001521}
1522
1523void XMLCALL
1524XML_SetCdataSectionHandler(XML_Parser parser,
1525 XML_StartCdataSectionHandler start,
Haibo Huang40a71912019-10-11 11:13:39 -07001526 XML_EndCdataSectionHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001527 if (parser == NULL)
1528 return;
1529 parser->m_startCdataSectionHandler = start;
1530 parser->m_endCdataSectionHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001531}
1532
1533void XMLCALL
1534XML_SetStartCdataSectionHandler(XML_Parser parser,
1535 XML_StartCdataSectionHandler start) {
Elliott Hughes72472942018-01-10 08:36:10 -08001536 if (parser != NULL)
1537 parser->m_startCdataSectionHandler = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001538}
1539
1540void XMLCALL
1541XML_SetEndCdataSectionHandler(XML_Parser parser,
1542 XML_EndCdataSectionHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001543 if (parser != NULL)
1544 parser->m_endCdataSectionHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001545}
1546
1547void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001548XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001549 if (parser == NULL)
1550 return;
1551 parser->m_defaultHandler = handler;
1552 parser->m_defaultExpandInternalEntities = XML_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001553}
1554
1555void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001556XML_SetDefaultHandlerExpand(XML_Parser parser, XML_DefaultHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001557 if (parser == NULL)
1558 return;
1559 parser->m_defaultHandler = handler;
1560 parser->m_defaultExpandInternalEntities = XML_TRUE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001561}
1562
1563void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001564XML_SetDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start,
1565 XML_EndDoctypeDeclHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001566 if (parser == NULL)
1567 return;
1568 parser->m_startDoctypeDeclHandler = start;
1569 parser->m_endDoctypeDeclHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001570}
1571
1572void XMLCALL
1573XML_SetStartDoctypeDeclHandler(XML_Parser parser,
1574 XML_StartDoctypeDeclHandler start) {
Elliott Hughes72472942018-01-10 08:36:10 -08001575 if (parser != NULL)
1576 parser->m_startDoctypeDeclHandler = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001577}
1578
1579void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001580XML_SetEndDoctypeDeclHandler(XML_Parser parser, XML_EndDoctypeDeclHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001581 if (parser != NULL)
1582 parser->m_endDoctypeDeclHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001583}
1584
1585void XMLCALL
1586XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001587 XML_UnparsedEntityDeclHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001588 if (parser != NULL)
1589 parser->m_unparsedEntityDeclHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001590}
1591
1592void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001593XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001594 if (parser != NULL)
1595 parser->m_notationDeclHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001596}
1597
1598void XMLCALL
1599XML_SetNamespaceDeclHandler(XML_Parser parser,
1600 XML_StartNamespaceDeclHandler start,
Haibo Huang40a71912019-10-11 11:13:39 -07001601 XML_EndNamespaceDeclHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001602 if (parser == NULL)
1603 return;
1604 parser->m_startNamespaceDeclHandler = start;
1605 parser->m_endNamespaceDeclHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001606}
1607
1608void XMLCALL
1609XML_SetStartNamespaceDeclHandler(XML_Parser parser,
1610 XML_StartNamespaceDeclHandler start) {
Elliott Hughes72472942018-01-10 08:36:10 -08001611 if (parser != NULL)
1612 parser->m_startNamespaceDeclHandler = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001613}
1614
1615void XMLCALL
1616XML_SetEndNamespaceDeclHandler(XML_Parser parser,
1617 XML_EndNamespaceDeclHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001618 if (parser != NULL)
1619 parser->m_endNamespaceDeclHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001620}
1621
1622void XMLCALL
1623XML_SetNotStandaloneHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001624 XML_NotStandaloneHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001625 if (parser != NULL)
1626 parser->m_notStandaloneHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001627}
1628
1629void XMLCALL
1630XML_SetExternalEntityRefHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001631 XML_ExternalEntityRefHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001632 if (parser != NULL)
1633 parser->m_externalEntityRefHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001634}
1635
1636void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001637XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) {
Elliott Hughes72472942018-01-10 08:36:10 -08001638 if (parser == NULL)
1639 return;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001640 if (arg)
Elliott Hughes72472942018-01-10 08:36:10 -08001641 parser->m_externalEntityRefHandlerArg = (XML_Parser)arg;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001642 else
Elliott Hughes72472942018-01-10 08:36:10 -08001643 parser->m_externalEntityRefHandlerArg = parser;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001644}
1645
1646void XMLCALL
1647XML_SetSkippedEntityHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001648 XML_SkippedEntityHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001649 if (parser != NULL)
1650 parser->m_skippedEntityHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001651}
1652
1653void XMLCALL
1654XML_SetUnknownEncodingHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001655 XML_UnknownEncodingHandler handler, void *data) {
Elliott Hughes72472942018-01-10 08:36:10 -08001656 if (parser == NULL)
1657 return;
1658 parser->m_unknownEncodingHandler = handler;
1659 parser->m_unknownEncodingHandlerData = data;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001660}
1661
1662void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001663XML_SetElementDeclHandler(XML_Parser parser, XML_ElementDeclHandler eldecl) {
Elliott Hughes72472942018-01-10 08:36:10 -08001664 if (parser != NULL)
1665 parser->m_elementDeclHandler = eldecl;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001666}
1667
1668void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001669XML_SetAttlistDeclHandler(XML_Parser parser, XML_AttlistDeclHandler attdecl) {
Elliott Hughes72472942018-01-10 08:36:10 -08001670 if (parser != NULL)
1671 parser->m_attlistDeclHandler = attdecl;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001672}
1673
1674void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001675XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001676 if (parser != NULL)
1677 parser->m_entityDeclHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001678}
1679
1680void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001681XML_SetXmlDeclHandler(XML_Parser parser, XML_XmlDeclHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001682 if (parser != NULL)
1683 parser->m_xmlDeclHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001684}
1685
1686int XMLCALL
1687XML_SetParamEntityParsing(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001688 enum XML_ParamEntityParsing peParsing) {
Elliott Hughes72472942018-01-10 08:36:10 -08001689 if (parser == NULL)
1690 return 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001691 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Haibo Huang40a71912019-10-11 11:13:39 -07001692 if (parser->m_parsingStatus.parsing == XML_PARSING
1693 || parser->m_parsingStatus.parsing == XML_SUSPENDED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001694 return 0;
1695#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08001696 parser->m_paramEntityParsing = peParsing;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001697 return 1;
1698#else
1699 return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
1700#endif
1701}
1702
Elliott Hughes35e432d2012-09-09 14:23:38 -07001703int XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001704XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt) {
Elliott Hughes72472942018-01-10 08:36:10 -08001705 if (parser == NULL)
Elliott Hughes35e432d2012-09-09 14:23:38 -07001706 return 0;
Elliott Hughes72472942018-01-10 08:36:10 -08001707 if (parser->m_parentParser)
1708 return XML_SetHashSalt(parser->m_parentParser, hash_salt);
1709 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Haibo Huang40a71912019-10-11 11:13:39 -07001710 if (parser->m_parsingStatus.parsing == XML_PARSING
1711 || parser->m_parsingStatus.parsing == XML_SUSPENDED)
Elliott Hughes72472942018-01-10 08:36:10 -08001712 return 0;
1713 parser->m_hash_secret_salt = hash_salt;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001714 return 1;
1715}
1716
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001717enum XML_Status XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001718XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) {
Elliott Hughes72472942018-01-10 08:36:10 -08001719 if ((parser == NULL) || (len < 0) || ((s == NULL) && (len != 0))) {
1720 if (parser != NULL)
1721 parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT;
1722 return XML_STATUS_ERROR;
1723 }
1724 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001725 case XML_SUSPENDED:
Elliott Hughes72472942018-01-10 08:36:10 -08001726 parser->m_errorCode = XML_ERROR_SUSPENDED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001727 return XML_STATUS_ERROR;
1728 case XML_FINISHED:
Elliott Hughes72472942018-01-10 08:36:10 -08001729 parser->m_errorCode = XML_ERROR_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001730 return XML_STATUS_ERROR;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001731 case XML_INITIALIZED:
Haibo Huang40a71912019-10-11 11:13:39 -07001732 if (parser->m_parentParser == NULL && ! startParsing(parser)) {
Elliott Hughes72472942018-01-10 08:36:10 -08001733 parser->m_errorCode = XML_ERROR_NO_MEMORY;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001734 return XML_STATUS_ERROR;
1735 }
Elliott Hughesaaec48e2018-08-16 16:29:01 -07001736 /* fall through */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001737 default:
Elliott Hughes72472942018-01-10 08:36:10 -08001738 parser->m_parsingStatus.parsing = XML_PARSING;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001739 }
1740
1741 if (len == 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08001742 parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
Haibo Huang40a71912019-10-11 11:13:39 -07001743 if (! isFinal)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001744 return XML_STATUS_OK;
Elliott Hughes72472942018-01-10 08:36:10 -08001745 parser->m_positionPtr = parser->m_bufferPtr;
1746 parser->m_parseEndPtr = parser->m_bufferEnd;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001747
1748 /* If data are left over from last buffer, and we now know that these
1749 data are the final chunk of input, then we have to check them again
1750 to detect errors based on that fact.
1751 */
Haibo Huang40a71912019-10-11 11:13:39 -07001752 parser->m_errorCode
1753 = parser->m_processor(parser, parser->m_bufferPtr,
1754 parser->m_parseEndPtr, &parser->m_bufferPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001755
Elliott Hughes72472942018-01-10 08:36:10 -08001756 if (parser->m_errorCode == XML_ERROR_NONE) {
1757 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001758 case XML_SUSPENDED:
Elliott Hughes72472942018-01-10 08:36:10 -08001759 /* It is hard to be certain, but it seems that this case
1760 * cannot occur. This code is cleaning up a previous parse
1761 * with no new data (since len == 0). Changing the parsing
1762 * state requires getting to execute a handler function, and
1763 * there doesn't seem to be an opportunity for that while in
1764 * this circumstance.
1765 *
1766 * Given the uncertainty, we retain the code but exclude it
1767 * from coverage tests.
1768 *
1769 * LCOV_EXCL_START
1770 */
Haibo Huang40a71912019-10-11 11:13:39 -07001771 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
1772 parser->m_bufferPtr, &parser->m_position);
Elliott Hughes72472942018-01-10 08:36:10 -08001773 parser->m_positionPtr = parser->m_bufferPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001774 return XML_STATUS_SUSPENDED;
Elliott Hughes72472942018-01-10 08:36:10 -08001775 /* LCOV_EXCL_STOP */
Elliott Hughes35e432d2012-09-09 14:23:38 -07001776 case XML_INITIALIZED:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001777 case XML_PARSING:
Elliott Hughes72472942018-01-10 08:36:10 -08001778 parser->m_parsingStatus.parsing = XML_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001779 /* fall through */
1780 default:
1781 return XML_STATUS_OK;
1782 }
1783 }
Elliott Hughes72472942018-01-10 08:36:10 -08001784 parser->m_eventEndPtr = parser->m_eventPtr;
1785 parser->m_processor = errorProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001786 return XML_STATUS_ERROR;
1787 }
1788#ifndef XML_CONTEXT_BYTES
Elliott Hughes72472942018-01-10 08:36:10 -08001789 else if (parser->m_bufferPtr == parser->m_bufferEnd) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001790 const char *end;
1791 int nLeftOver;
Paul Duffinc05e0322016-05-04 10:42:31 +01001792 enum XML_Status result;
Elliott Hughes72472942018-01-10 08:36:10 -08001793 /* Detect overflow (a+b > MAX <==> b > MAX-a) */
Haibo Huangd1a324a2020-10-28 22:19:36 -07001794 if ((XML_Size)len > ((XML_Size)-1) / 2 - parser->m_parseEndByteIndex) {
Haibo Huang40a71912019-10-11 11:13:39 -07001795 parser->m_errorCode = XML_ERROR_NO_MEMORY;
1796 parser->m_eventPtr = parser->m_eventEndPtr = NULL;
1797 parser->m_processor = errorProcessor;
1798 return XML_STATUS_ERROR;
Elliott Hughes72472942018-01-10 08:36:10 -08001799 }
1800 parser->m_parseEndByteIndex += len;
1801 parser->m_positionPtr = s;
1802 parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001803
Haibo Huang40a71912019-10-11 11:13:39 -07001804 parser->m_errorCode
1805 = parser->m_processor(parser, s, parser->m_parseEndPtr = s + len, &end);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001806
Elliott Hughes72472942018-01-10 08:36:10 -08001807 if (parser->m_errorCode != XML_ERROR_NONE) {
1808 parser->m_eventEndPtr = parser->m_eventPtr;
1809 parser->m_processor = errorProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001810 return XML_STATUS_ERROR;
Haibo Huang40a71912019-10-11 11:13:39 -07001811 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08001812 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001813 case XML_SUSPENDED:
1814 result = XML_STATUS_SUSPENDED;
1815 break;
1816 case XML_INITIALIZED:
1817 case XML_PARSING:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001818 if (isFinal) {
Elliott Hughes72472942018-01-10 08:36:10 -08001819 parser->m_parsingStatus.parsing = XML_FINISHED;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001820 return XML_STATUS_OK;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001821 }
Elliott Hughes35e432d2012-09-09 14:23:38 -07001822 /* fall through */
1823 default:
1824 result = XML_STATUS_OK;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001825 }
1826 }
1827
Haibo Huang40a71912019-10-11 11:13:39 -07001828 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, end,
1829 &parser->m_position);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001830 nLeftOver = s + len - end;
1831 if (nLeftOver) {
Haibo Huang40a71912019-10-11 11:13:39 -07001832 if (parser->m_buffer == NULL
1833 || nLeftOver > parser->m_bufferLim - parser->m_buffer) {
Elliott Hughes72472942018-01-10 08:36:10 -08001834 /* avoid _signed_ integer overflow */
1835 char *temp = NULL;
1836 const int bytesToAllocate = (int)((unsigned)len * 2U);
1837 if (bytesToAllocate > 0) {
1838 temp = (char *)REALLOC(parser, parser->m_buffer, bytesToAllocate);
1839 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001840 if (temp == NULL) {
Elliott Hughes72472942018-01-10 08:36:10 -08001841 parser->m_errorCode = XML_ERROR_NO_MEMORY;
1842 parser->m_eventPtr = parser->m_eventEndPtr = NULL;
1843 parser->m_processor = errorProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001844 return XML_STATUS_ERROR;
1845 }
Elliott Hughes72472942018-01-10 08:36:10 -08001846 parser->m_buffer = temp;
1847 parser->m_bufferLim = parser->m_buffer + bytesToAllocate;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001848 }
Elliott Hughes72472942018-01-10 08:36:10 -08001849 memcpy(parser->m_buffer, end, nLeftOver);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001850 }
Elliott Hughes72472942018-01-10 08:36:10 -08001851 parser->m_bufferPtr = parser->m_buffer;
1852 parser->m_bufferEnd = parser->m_buffer + nLeftOver;
1853 parser->m_positionPtr = parser->m_bufferPtr;
1854 parser->m_parseEndPtr = parser->m_bufferEnd;
1855 parser->m_eventPtr = parser->m_bufferPtr;
1856 parser->m_eventEndPtr = parser->m_bufferPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001857 return result;
1858 }
Haibo Huang40a71912019-10-11 11:13:39 -07001859#endif /* not defined XML_CONTEXT_BYTES */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001860 else {
1861 void *buff = XML_GetBuffer(parser, len);
1862 if (buff == NULL)
1863 return XML_STATUS_ERROR;
1864 else {
1865 memcpy(buff, s, len);
1866 return XML_ParseBuffer(parser, len, isFinal);
1867 }
1868 }
1869}
1870
1871enum XML_Status XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001872XML_ParseBuffer(XML_Parser parser, int len, int isFinal) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001873 const char *start;
1874 enum XML_Status result = XML_STATUS_OK;
1875
Elliott Hughes72472942018-01-10 08:36:10 -08001876 if (parser == NULL)
1877 return XML_STATUS_ERROR;
1878 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001879 case XML_SUSPENDED:
Elliott Hughes72472942018-01-10 08:36:10 -08001880 parser->m_errorCode = XML_ERROR_SUSPENDED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001881 return XML_STATUS_ERROR;
1882 case XML_FINISHED:
Elliott Hughes72472942018-01-10 08:36:10 -08001883 parser->m_errorCode = XML_ERROR_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001884 return XML_STATUS_ERROR;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001885 case XML_INITIALIZED:
Elliott Hughesf648a292021-04-01 15:10:13 -07001886 /* Has someone called XML_GetBuffer successfully before? */
1887 if (! parser->m_bufferPtr) {
1888 parser->m_errorCode = XML_ERROR_NO_BUFFER;
1889 return XML_STATUS_ERROR;
1890 }
1891
Haibo Huang40a71912019-10-11 11:13:39 -07001892 if (parser->m_parentParser == NULL && ! startParsing(parser)) {
Elliott Hughes72472942018-01-10 08:36:10 -08001893 parser->m_errorCode = XML_ERROR_NO_MEMORY;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001894 return XML_STATUS_ERROR;
1895 }
Elliott Hughesaaec48e2018-08-16 16:29:01 -07001896 /* fall through */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001897 default:
Elliott Hughes72472942018-01-10 08:36:10 -08001898 parser->m_parsingStatus.parsing = XML_PARSING;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001899 }
1900
Elliott Hughes72472942018-01-10 08:36:10 -08001901 start = parser->m_bufferPtr;
1902 parser->m_positionPtr = start;
1903 parser->m_bufferEnd += len;
1904 parser->m_parseEndPtr = parser->m_bufferEnd;
1905 parser->m_parseEndByteIndex += len;
1906 parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001907
Haibo Huang40a71912019-10-11 11:13:39 -07001908 parser->m_errorCode = parser->m_processor(
1909 parser, start, parser->m_parseEndPtr, &parser->m_bufferPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001910
Elliott Hughes72472942018-01-10 08:36:10 -08001911 if (parser->m_errorCode != XML_ERROR_NONE) {
1912 parser->m_eventEndPtr = parser->m_eventPtr;
1913 parser->m_processor = errorProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001914 return XML_STATUS_ERROR;
Haibo Huang40a71912019-10-11 11:13:39 -07001915 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08001916 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001917 case XML_SUSPENDED:
1918 result = XML_STATUS_SUSPENDED;
1919 break;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001920 case XML_INITIALIZED:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001921 case XML_PARSING:
1922 if (isFinal) {
Elliott Hughes72472942018-01-10 08:36:10 -08001923 parser->m_parsingStatus.parsing = XML_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001924 return result;
1925 }
Haibo Huang40a71912019-10-11 11:13:39 -07001926 default:; /* should not happen */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001927 }
1928 }
1929
Haibo Huang40a71912019-10-11 11:13:39 -07001930 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
1931 parser->m_bufferPtr, &parser->m_position);
Elliott Hughes72472942018-01-10 08:36:10 -08001932 parser->m_positionPtr = parser->m_bufferPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001933 return result;
1934}
1935
Haibo Huang40a71912019-10-11 11:13:39 -07001936void *XMLCALL
1937XML_GetBuffer(XML_Parser parser, int len) {
Elliott Hughes72472942018-01-10 08:36:10 -08001938 if (parser == NULL)
1939 return NULL;
Paul Duffinc05e0322016-05-04 10:42:31 +01001940 if (len < 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08001941 parser->m_errorCode = XML_ERROR_NO_MEMORY;
Paul Duffinc05e0322016-05-04 10:42:31 +01001942 return NULL;
1943 }
Elliott Hughes72472942018-01-10 08:36:10 -08001944 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001945 case XML_SUSPENDED:
Elliott Hughes72472942018-01-10 08:36:10 -08001946 parser->m_errorCode = XML_ERROR_SUSPENDED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001947 return NULL;
1948 case XML_FINISHED:
Elliott Hughes72472942018-01-10 08:36:10 -08001949 parser->m_errorCode = XML_ERROR_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001950 return NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07001951 default:;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001952 }
1953
Elliott Hughesaaec48e2018-08-16 16:29:01 -07001954 if (len > EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferEnd)) {
Paul Duffinba34a0c2017-02-27 14:40:16 +00001955#ifdef XML_CONTEXT_BYTES
1956 int keep;
Haibo Huang40a71912019-10-11 11:13:39 -07001957#endif /* defined XML_CONTEXT_BYTES */
Paul Duffinba34a0c2017-02-27 14:40:16 +00001958 /* Do not invoke signed arithmetic overflow: */
Haibo Huang40a71912019-10-11 11:13:39 -07001959 int neededSize = (int)((unsigned)len
1960 + (unsigned)EXPAT_SAFE_PTR_DIFF(
1961 parser->m_bufferEnd, parser->m_bufferPtr));
Paul Duffinc05e0322016-05-04 10:42:31 +01001962 if (neededSize < 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08001963 parser->m_errorCode = XML_ERROR_NO_MEMORY;
Paul Duffinc05e0322016-05-04 10:42:31 +01001964 return NULL;
1965 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001966#ifdef XML_CONTEXT_BYTES
Elliott Hughesaaec48e2018-08-16 16:29:01 -07001967 keep = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001968 if (keep > XML_CONTEXT_BYTES)
1969 keep = XML_CONTEXT_BYTES;
Sadaf Ebrahimi1cea5722022-06-02 19:32:22 +00001970 /* Detect and prevent integer overflow */
1971 if (keep > INT_MAX - neededSize) {
1972 parser->m_errorCode = XML_ERROR_NO_MEMORY;
1973 return NULL;
1974 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001975 neededSize += keep;
Haibo Huang40a71912019-10-11 11:13:39 -07001976#endif /* defined XML_CONTEXT_BYTES */
1977 if (neededSize
1978 <= EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_buffer)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001979#ifdef XML_CONTEXT_BYTES
Elliott Hughesaaec48e2018-08-16 16:29:01 -07001980 if (keep < EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer)) {
Haibo Huang40a71912019-10-11 11:13:39 -07001981 int offset
1982 = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer)
1983 - keep;
1984 /* The buffer pointers cannot be NULL here; we have at least some bytes
1985 * in the buffer */
1986 memmove(parser->m_buffer, &parser->m_buffer[offset],
1987 parser->m_bufferEnd - parser->m_bufferPtr + keep);
Elliott Hughes72472942018-01-10 08:36:10 -08001988 parser->m_bufferEnd -= offset;
1989 parser->m_bufferPtr -= offset;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001990 }
1991#else
Elliott Hughesaaec48e2018-08-16 16:29:01 -07001992 if (parser->m_buffer && parser->m_bufferPtr) {
1993 memmove(parser->m_buffer, parser->m_bufferPtr,
1994 EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr));
Haibo Huang40a71912019-10-11 11:13:39 -07001995 parser->m_bufferEnd
1996 = parser->m_buffer
1997 + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr);
Elliott Hughesaaec48e2018-08-16 16:29:01 -07001998 parser->m_bufferPtr = parser->m_buffer;
1999 }
Haibo Huang40a71912019-10-11 11:13:39 -07002000#endif /* not defined XML_CONTEXT_BYTES */
2001 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002002 char *newBuf;
Haibo Huang40a71912019-10-11 11:13:39 -07002003 int bufferSize
2004 = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002005 if (bufferSize == 0)
2006 bufferSize = INIT_BUFFER_SIZE;
2007 do {
Paul Duffinba34a0c2017-02-27 14:40:16 +00002008 /* Do not invoke signed arithmetic overflow: */
Haibo Huang40a71912019-10-11 11:13:39 -07002009 bufferSize = (int)(2U * (unsigned)bufferSize);
Paul Duffinc05e0322016-05-04 10:42:31 +01002010 } while (bufferSize < neededSize && bufferSize > 0);
2011 if (bufferSize <= 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08002012 parser->m_errorCode = XML_ERROR_NO_MEMORY;
Paul Duffinc05e0322016-05-04 10:42:31 +01002013 return NULL;
2014 }
Elliott Hughes72472942018-01-10 08:36:10 -08002015 newBuf = (char *)MALLOC(parser, bufferSize);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002016 if (newBuf == 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08002017 parser->m_errorCode = XML_ERROR_NO_MEMORY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002018 return NULL;
2019 }
Elliott Hughes72472942018-01-10 08:36:10 -08002020 parser->m_bufferLim = newBuf + bufferSize;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002021#ifdef XML_CONTEXT_BYTES
Elliott Hughes72472942018-01-10 08:36:10 -08002022 if (parser->m_bufferPtr) {
Elliott Hughesaaec48e2018-08-16 16:29:01 -07002023 memcpy(newBuf, &parser->m_bufferPtr[-keep],
Haibo Huang40a71912019-10-11 11:13:39 -07002024 EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)
2025 + keep);
Elliott Hughes72472942018-01-10 08:36:10 -08002026 FREE(parser, parser->m_buffer);
2027 parser->m_buffer = newBuf;
Haibo Huang40a71912019-10-11 11:13:39 -07002028 parser->m_bufferEnd
2029 = parser->m_buffer
2030 + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)
2031 + keep;
Elliott Hughes72472942018-01-10 08:36:10 -08002032 parser->m_bufferPtr = parser->m_buffer + keep;
Haibo Huang40a71912019-10-11 11:13:39 -07002033 } else {
Elliott Hughesaaec48e2018-08-16 16:29:01 -07002034 /* This must be a brand new buffer with no data in it yet */
2035 parser->m_bufferEnd = newBuf;
Elliott Hughes72472942018-01-10 08:36:10 -08002036 parser->m_bufferPtr = parser->m_buffer = newBuf;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002037 }
2038#else
Elliott Hughes72472942018-01-10 08:36:10 -08002039 if (parser->m_bufferPtr) {
Elliott Hughesaaec48e2018-08-16 16:29:01 -07002040 memcpy(newBuf, parser->m_bufferPtr,
2041 EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr));
Elliott Hughes72472942018-01-10 08:36:10 -08002042 FREE(parser, parser->m_buffer);
Haibo Huang40a71912019-10-11 11:13:39 -07002043 parser->m_bufferEnd
2044 = newBuf
2045 + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr);
2046 } else {
Elliott Hughesaaec48e2018-08-16 16:29:01 -07002047 /* This must be a brand new buffer with no data in it yet */
2048 parser->m_bufferEnd = newBuf;
2049 }
Elliott Hughes72472942018-01-10 08:36:10 -08002050 parser->m_bufferPtr = parser->m_buffer = newBuf;
Haibo Huang40a71912019-10-11 11:13:39 -07002051#endif /* not defined XML_CONTEXT_BYTES */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002052 }
Elliott Hughes72472942018-01-10 08:36:10 -08002053 parser->m_eventPtr = parser->m_eventEndPtr = NULL;
2054 parser->m_positionPtr = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002055 }
Elliott Hughes72472942018-01-10 08:36:10 -08002056 return parser->m_bufferEnd;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002057}
2058
2059enum XML_Status XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002060XML_StopParser(XML_Parser parser, XML_Bool resumable) {
Elliott Hughes72472942018-01-10 08:36:10 -08002061 if (parser == NULL)
2062 return XML_STATUS_ERROR;
2063 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002064 case XML_SUSPENDED:
2065 if (resumable) {
Elliott Hughes72472942018-01-10 08:36:10 -08002066 parser->m_errorCode = XML_ERROR_SUSPENDED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002067 return XML_STATUS_ERROR;
2068 }
Elliott Hughes72472942018-01-10 08:36:10 -08002069 parser->m_parsingStatus.parsing = XML_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002070 break;
2071 case XML_FINISHED:
Elliott Hughes72472942018-01-10 08:36:10 -08002072 parser->m_errorCode = XML_ERROR_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002073 return XML_STATUS_ERROR;
2074 default:
2075 if (resumable) {
2076#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08002077 if (parser->m_isParamEntity) {
2078 parser->m_errorCode = XML_ERROR_SUSPEND_PE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002079 return XML_STATUS_ERROR;
2080 }
2081#endif
Elliott Hughes72472942018-01-10 08:36:10 -08002082 parser->m_parsingStatus.parsing = XML_SUSPENDED;
Haibo Huang40a71912019-10-11 11:13:39 -07002083 } else
Elliott Hughes72472942018-01-10 08:36:10 -08002084 parser->m_parsingStatus.parsing = XML_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002085 }
2086 return XML_STATUS_OK;
2087}
2088
2089enum XML_Status XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002090XML_ResumeParser(XML_Parser parser) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002091 enum XML_Status result = XML_STATUS_OK;
2092
Elliott Hughes72472942018-01-10 08:36:10 -08002093 if (parser == NULL)
2094 return XML_STATUS_ERROR;
2095 if (parser->m_parsingStatus.parsing != XML_SUSPENDED) {
2096 parser->m_errorCode = XML_ERROR_NOT_SUSPENDED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002097 return XML_STATUS_ERROR;
2098 }
Elliott Hughes72472942018-01-10 08:36:10 -08002099 parser->m_parsingStatus.parsing = XML_PARSING;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002100
Haibo Huang40a71912019-10-11 11:13:39 -07002101 parser->m_errorCode = parser->m_processor(
2102 parser, parser->m_bufferPtr, parser->m_parseEndPtr, &parser->m_bufferPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002103
Elliott Hughes72472942018-01-10 08:36:10 -08002104 if (parser->m_errorCode != XML_ERROR_NONE) {
2105 parser->m_eventEndPtr = parser->m_eventPtr;
2106 parser->m_processor = errorProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002107 return XML_STATUS_ERROR;
Haibo Huang40a71912019-10-11 11:13:39 -07002108 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08002109 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002110 case XML_SUSPENDED:
2111 result = XML_STATUS_SUSPENDED;
2112 break;
Elliott Hughes35e432d2012-09-09 14:23:38 -07002113 case XML_INITIALIZED:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002114 case XML_PARSING:
Elliott Hughes72472942018-01-10 08:36:10 -08002115 if (parser->m_parsingStatus.finalBuffer) {
2116 parser->m_parsingStatus.parsing = XML_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002117 return result;
2118 }
Haibo Huang40a71912019-10-11 11:13:39 -07002119 default:;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002120 }
2121 }
2122
Haibo Huang40a71912019-10-11 11:13:39 -07002123 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
2124 parser->m_bufferPtr, &parser->m_position);
Elliott Hughes72472942018-01-10 08:36:10 -08002125 parser->m_positionPtr = parser->m_bufferPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002126 return result;
2127}
2128
2129void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002130XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status) {
Elliott Hughes72472942018-01-10 08:36:10 -08002131 if (parser == NULL)
2132 return;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002133 assert(status != NULL);
2134 *status = parser->m_parsingStatus;
2135}
2136
2137enum XML_Error XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002138XML_GetErrorCode(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002139 if (parser == NULL)
2140 return XML_ERROR_INVALID_ARGUMENT;
2141 return parser->m_errorCode;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002142}
2143
2144XML_Index XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002145XML_GetCurrentByteIndex(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002146 if (parser == NULL)
2147 return -1;
2148 if (parser->m_eventPtr)
Haibo Huang40a71912019-10-11 11:13:39 -07002149 return (XML_Index)(parser->m_parseEndByteIndex
2150 - (parser->m_parseEndPtr - parser->m_eventPtr));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002151 return -1;
2152}
2153
2154int XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002155XML_GetCurrentByteCount(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002156 if (parser == NULL)
2157 return 0;
2158 if (parser->m_eventEndPtr && parser->m_eventPtr)
2159 return (int)(parser->m_eventEndPtr - parser->m_eventPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002160 return 0;
2161}
2162
Haibo Huang40a71912019-10-11 11:13:39 -07002163const char *XMLCALL
2164XML_GetInputContext(XML_Parser parser, int *offset, int *size) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002165#ifdef XML_CONTEXT_BYTES
Elliott Hughes72472942018-01-10 08:36:10 -08002166 if (parser == NULL)
2167 return NULL;
2168 if (parser->m_eventPtr && parser->m_buffer) {
2169 if (offset != NULL)
2170 *offset = (int)(parser->m_eventPtr - parser->m_buffer);
2171 if (size != NULL)
Haibo Huang40a71912019-10-11 11:13:39 -07002172 *size = (int)(parser->m_bufferEnd - parser->m_buffer);
Elliott Hughes72472942018-01-10 08:36:10 -08002173 return parser->m_buffer;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002174 }
Elliott Hughes72472942018-01-10 08:36:10 -08002175#else
2176 (void)parser;
2177 (void)offset;
2178 (void)size;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002179#endif /* defined XML_CONTEXT_BYTES */
Haibo Huangd1a324a2020-10-28 22:19:36 -07002180 return (const char *)0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002181}
2182
2183XML_Size XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002184XML_GetCurrentLineNumber(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002185 if (parser == NULL)
2186 return 0;
2187 if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) {
Haibo Huang40a71912019-10-11 11:13:39 -07002188 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
2189 parser->m_eventPtr, &parser->m_position);
Elliott Hughes72472942018-01-10 08:36:10 -08002190 parser->m_positionPtr = parser->m_eventPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002191 }
Elliott Hughes72472942018-01-10 08:36:10 -08002192 return parser->m_position.lineNumber + 1;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002193}
2194
2195XML_Size XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002196XML_GetCurrentColumnNumber(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002197 if (parser == NULL)
2198 return 0;
2199 if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) {
Haibo Huang40a71912019-10-11 11:13:39 -07002200 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
2201 parser->m_eventPtr, &parser->m_position);
Elliott Hughes72472942018-01-10 08:36:10 -08002202 parser->m_positionPtr = parser->m_eventPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002203 }
Elliott Hughes72472942018-01-10 08:36:10 -08002204 return parser->m_position.columnNumber;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002205}
2206
2207void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002208XML_FreeContentModel(XML_Parser parser, XML_Content *model) {
Elliott Hughes72472942018-01-10 08:36:10 -08002209 if (parser != NULL)
2210 FREE(parser, model);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002211}
2212
Haibo Huang40a71912019-10-11 11:13:39 -07002213void *XMLCALL
2214XML_MemMalloc(XML_Parser parser, size_t size) {
Elliott Hughes72472942018-01-10 08:36:10 -08002215 if (parser == NULL)
2216 return NULL;
2217 return MALLOC(parser, size);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002218}
2219
Haibo Huang40a71912019-10-11 11:13:39 -07002220void *XMLCALL
2221XML_MemRealloc(XML_Parser parser, void *ptr, size_t size) {
Elliott Hughes72472942018-01-10 08:36:10 -08002222 if (parser == NULL)
2223 return NULL;
2224 return REALLOC(parser, ptr, size);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002225}
2226
2227void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002228XML_MemFree(XML_Parser parser, void *ptr) {
Elliott Hughes72472942018-01-10 08:36:10 -08002229 if (parser != NULL)
2230 FREE(parser, ptr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002231}
2232
2233void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002234XML_DefaultCurrent(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002235 if (parser == NULL)
2236 return;
2237 if (parser->m_defaultHandler) {
2238 if (parser->m_openInternalEntities)
Haibo Huang40a71912019-10-11 11:13:39 -07002239 reportDefault(parser, parser->m_internalEncoding,
Elliott Hughes72472942018-01-10 08:36:10 -08002240 parser->m_openInternalEntities->internalEventPtr,
2241 parser->m_openInternalEntities->internalEventEndPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002242 else
Haibo Huang40a71912019-10-11 11:13:39 -07002243 reportDefault(parser, parser->m_encoding, parser->m_eventPtr,
2244 parser->m_eventEndPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002245 }
2246}
2247
Haibo Huang40a71912019-10-11 11:13:39 -07002248const XML_LChar *XMLCALL
2249XML_ErrorString(enum XML_Error code) {
Elliott Hughes72472942018-01-10 08:36:10 -08002250 switch (code) {
2251 case XML_ERROR_NONE:
2252 return NULL;
2253 case XML_ERROR_NO_MEMORY:
2254 return XML_L("out of memory");
2255 case XML_ERROR_SYNTAX:
2256 return XML_L("syntax error");
2257 case XML_ERROR_NO_ELEMENTS:
2258 return XML_L("no element found");
2259 case XML_ERROR_INVALID_TOKEN:
2260 return XML_L("not well-formed (invalid token)");
2261 case XML_ERROR_UNCLOSED_TOKEN:
2262 return XML_L("unclosed token");
2263 case XML_ERROR_PARTIAL_CHAR:
2264 return XML_L("partial character");
2265 case XML_ERROR_TAG_MISMATCH:
2266 return XML_L("mismatched tag");
2267 case XML_ERROR_DUPLICATE_ATTRIBUTE:
2268 return XML_L("duplicate attribute");
2269 case XML_ERROR_JUNK_AFTER_DOC_ELEMENT:
2270 return XML_L("junk after document element");
2271 case XML_ERROR_PARAM_ENTITY_REF:
2272 return XML_L("illegal parameter entity reference");
2273 case XML_ERROR_UNDEFINED_ENTITY:
2274 return XML_L("undefined entity");
2275 case XML_ERROR_RECURSIVE_ENTITY_REF:
2276 return XML_L("recursive entity reference");
2277 case XML_ERROR_ASYNC_ENTITY:
2278 return XML_L("asynchronous entity");
2279 case XML_ERROR_BAD_CHAR_REF:
2280 return XML_L("reference to invalid character number");
2281 case XML_ERROR_BINARY_ENTITY_REF:
2282 return XML_L("reference to binary entity");
2283 case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF:
2284 return XML_L("reference to external entity in attribute");
2285 case XML_ERROR_MISPLACED_XML_PI:
2286 return XML_L("XML or text declaration not at start of entity");
2287 case XML_ERROR_UNKNOWN_ENCODING:
2288 return XML_L("unknown encoding");
2289 case XML_ERROR_INCORRECT_ENCODING:
2290 return XML_L("encoding specified in XML declaration is incorrect");
2291 case XML_ERROR_UNCLOSED_CDATA_SECTION:
2292 return XML_L("unclosed CDATA section");
2293 case XML_ERROR_EXTERNAL_ENTITY_HANDLING:
2294 return XML_L("error in processing external entity reference");
2295 case XML_ERROR_NOT_STANDALONE:
2296 return XML_L("document is not standalone");
2297 case XML_ERROR_UNEXPECTED_STATE:
2298 return XML_L("unexpected parser state - please send a bug report");
2299 case XML_ERROR_ENTITY_DECLARED_IN_PE:
2300 return XML_L("entity declared in parameter entity");
2301 case XML_ERROR_FEATURE_REQUIRES_XML_DTD:
2302 return XML_L("requested feature requires XML_DTD support in Expat");
2303 case XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING:
2304 return XML_L("cannot change setting once parsing has begun");
2305 /* Added in 1.95.7. */
2306 case XML_ERROR_UNBOUND_PREFIX:
2307 return XML_L("unbound prefix");
2308 /* Added in 1.95.8. */
2309 case XML_ERROR_UNDECLARING_PREFIX:
2310 return XML_L("must not undeclare prefix");
2311 case XML_ERROR_INCOMPLETE_PE:
2312 return XML_L("incomplete markup in parameter entity");
2313 case XML_ERROR_XML_DECL:
2314 return XML_L("XML declaration not well-formed");
2315 case XML_ERROR_TEXT_DECL:
2316 return XML_L("text declaration not well-formed");
2317 case XML_ERROR_PUBLICID:
2318 return XML_L("illegal character(s) in public id");
2319 case XML_ERROR_SUSPENDED:
2320 return XML_L("parser suspended");
2321 case XML_ERROR_NOT_SUSPENDED:
2322 return XML_L("parser not suspended");
2323 case XML_ERROR_ABORTED:
2324 return XML_L("parsing aborted");
2325 case XML_ERROR_FINISHED:
2326 return XML_L("parsing finished");
2327 case XML_ERROR_SUSPEND_PE:
2328 return XML_L("cannot suspend in external parameter entity");
2329 /* Added in 2.0.0. */
2330 case XML_ERROR_RESERVED_PREFIX_XML:
Haibo Huang40a71912019-10-11 11:13:39 -07002331 return XML_L(
2332 "reserved prefix (xml) must not be undeclared or bound to another namespace name");
Elliott Hughes72472942018-01-10 08:36:10 -08002333 case XML_ERROR_RESERVED_PREFIX_XMLNS:
2334 return XML_L("reserved prefix (xmlns) must not be declared or undeclared");
2335 case XML_ERROR_RESERVED_NAMESPACE_URI:
Haibo Huang40a71912019-10-11 11:13:39 -07002336 return XML_L(
2337 "prefix must not be bound to one of the reserved namespace names");
Elliott Hughes72472942018-01-10 08:36:10 -08002338 /* Added in 2.2.5. */
Haibo Huang40a71912019-10-11 11:13:39 -07002339 case XML_ERROR_INVALID_ARGUMENT: /* Constant added in 2.2.1, already */
Elliott Hughes72472942018-01-10 08:36:10 -08002340 return XML_L("invalid argument");
Elliott Hughesf648a292021-04-01 15:10:13 -07002341 /* Added in 2.3.0. */
2342 case XML_ERROR_NO_BUFFER:
2343 return XML_L(
2344 "a successful prior call to function XML_GetBuffer is required");
Elliott Hughes72472942018-01-10 08:36:10 -08002345 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002346 return NULL;
2347}
2348
Haibo Huang40a71912019-10-11 11:13:39 -07002349const XML_LChar *XMLCALL
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002350XML_ExpatVersion(void) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002351 /* V1 is used to string-ize the version number. However, it would
2352 string-ize the actual version macro *names* unless we get them
2353 substituted before being passed to V1. CPP is defined to expand
2354 a macro, then rescan for more expansions. Thus, we use V2 to expand
2355 the version macros, then CPP will expand the resulting V1() macro
2356 with the correct numerals. */
2357 /* ### I'm assuming cpp is portable in this respect... */
2358
Haibo Huang40a71912019-10-11 11:13:39 -07002359#define V1(a, b, c) XML_L(#a) XML_L(".") XML_L(#b) XML_L(".") XML_L(#c)
2360#define V2(a, b, c) XML_L("expat_") V1(a, b, c)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002361
2362 return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
2363
2364#undef V1
2365#undef V2
2366}
2367
2368XML_Expat_Version XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002369XML_ExpatVersionInfo(void) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002370 XML_Expat_Version version;
2371
2372 version.major = XML_MAJOR_VERSION;
2373 version.minor = XML_MINOR_VERSION;
2374 version.micro = XML_MICRO_VERSION;
2375
2376 return version;
2377}
2378
Haibo Huang40a71912019-10-11 11:13:39 -07002379const XML_Feature *XMLCALL
2380XML_GetFeatureList(void) {
2381 static const XML_Feature features[]
2382 = {{XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"),
2383 sizeof(XML_Char)},
2384 {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
2385 sizeof(XML_LChar)},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002386#ifdef XML_UNICODE
Haibo Huang40a71912019-10-11 11:13:39 -07002387 {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002388#endif
2389#ifdef XML_UNICODE_WCHAR_T
Haibo Huang40a71912019-10-11 11:13:39 -07002390 {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002391#endif
2392#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07002393 {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002394#endif
2395#ifdef XML_CONTEXT_BYTES
Haibo Huang40a71912019-10-11 11:13:39 -07002396 {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
2397 XML_CONTEXT_BYTES},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002398#endif
2399#ifdef XML_MIN_SIZE
Haibo Huang40a71912019-10-11 11:13:39 -07002400 {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002401#endif
2402#ifdef XML_NS
Haibo Huang40a71912019-10-11 11:13:39 -07002403 {XML_FEATURE_NS, XML_L("XML_NS"), 0},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002404#endif
Elliott Hughesd07d5a72009-09-25 16:04:37 -07002405#ifdef XML_LARGE_SIZE
Haibo Huang40a71912019-10-11 11:13:39 -07002406 {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0},
Elliott Hughes35e432d2012-09-09 14:23:38 -07002407#endif
2408#ifdef XML_ATTR_INFO
Haibo Huang40a71912019-10-11 11:13:39 -07002409 {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0},
Elliott Hughes35e432d2012-09-09 14:23:38 -07002410#endif
Haibo Huang40a71912019-10-11 11:13:39 -07002411 {XML_FEATURE_END, NULL, 0}};
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002412
2413 return features;
2414}
2415
2416/* Initially tag->rawName always points into the parse buffer;
2417 for those TAG instances opened while the current parse buffer was
2418 processed, and not yet closed, we need to store tag->rawName in a more
2419 permanent location, since the parse buffer is about to be discarded.
2420*/
2421static XML_Bool
Haibo Huang40a71912019-10-11 11:13:39 -07002422storeRawNames(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002423 TAG *tag = parser->m_tagStack;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002424 while (tag) {
2425 int bufSize;
2426 int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
2427 char *rawNameBuf = tag->buf + nameLen;
Elliott Hughes72472942018-01-10 08:36:10 -08002428 /* Stop if already stored. Since m_tagStack is a stack, we can stop
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002429 at the first entry that has already been copied; everything
2430 below it in the stack is already been accounted for in a
2431 previous call to this function.
2432 */
2433 if (tag->rawName == rawNameBuf)
2434 break;
2435 /* For re-use purposes we need to ensure that the
2436 size of tag->buf is a multiple of sizeof(XML_Char).
2437 */
2438 bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
2439 if (bufSize > tag->bufEnd - tag->buf) {
Elliott Hughes72472942018-01-10 08:36:10 -08002440 char *temp = (char *)REALLOC(parser, tag->buf, bufSize);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002441 if (temp == NULL)
2442 return XML_FALSE;
2443 /* if tag->name.str points to tag->buf (only when namespace
2444 processing is off) then we have to update it
2445 */
2446 if (tag->name.str == (XML_Char *)tag->buf)
2447 tag->name.str = (XML_Char *)temp;
2448 /* if tag->name.localPart is set (when namespace processing is on)
2449 then update it as well, since it will always point into tag->buf
2450 */
2451 if (tag->name.localPart)
Haibo Huang40a71912019-10-11 11:13:39 -07002452 tag->name.localPart
2453 = (XML_Char *)temp + (tag->name.localPart - (XML_Char *)tag->buf);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002454 tag->buf = temp;
2455 tag->bufEnd = temp + bufSize;
2456 rawNameBuf = temp + nameLen;
2457 }
2458 memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
2459 tag->rawName = rawNameBuf;
2460 tag = tag->parent;
2461 }
2462 return XML_TRUE;
2463}
2464
2465static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002466contentProcessor(XML_Parser parser, const char *start, const char *end,
2467 const char **endPtr) {
2468 enum XML_Error result
2469 = doContent(parser, 0, parser->m_encoding, start, end, endPtr,
2470 (XML_Bool)! parser->m_parsingStatus.finalBuffer);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002471 if (result == XML_ERROR_NONE) {
Haibo Huang40a71912019-10-11 11:13:39 -07002472 if (! storeRawNames(parser))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002473 return XML_ERROR_NO_MEMORY;
2474 }
2475 return result;
2476}
2477
2478static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002479externalEntityInitProcessor(XML_Parser parser, const char *start,
2480 const char *end, const char **endPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002481 enum XML_Error result = initializeEncoding(parser);
2482 if (result != XML_ERROR_NONE)
2483 return result;
Elliott Hughes72472942018-01-10 08:36:10 -08002484 parser->m_processor = externalEntityInitProcessor2;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002485 return externalEntityInitProcessor2(parser, start, end, endPtr);
2486}
2487
2488static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002489externalEntityInitProcessor2(XML_Parser parser, const char *start,
2490 const char *end, const char **endPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002491 const char *next = start; /* XmlContentTok doesn't always set the last arg */
Elliott Hughes72472942018-01-10 08:36:10 -08002492 int tok = XmlContentTok(parser->m_encoding, start, end, &next);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002493 switch (tok) {
2494 case XML_TOK_BOM:
2495 /* If we are at the end of the buffer, this would cause the next stage,
2496 i.e. externalEntityInitProcessor3, to pass control directly to
2497 doContent (by detecting XML_TOK_NONE) without processing any xml text
2498 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
2499 */
Haibo Huang40a71912019-10-11 11:13:39 -07002500 if (next == end && ! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002501 *endPtr = next;
2502 return XML_ERROR_NONE;
2503 }
2504 start = next;
2505 break;
2506 case XML_TOK_PARTIAL:
Haibo Huang40a71912019-10-11 11:13:39 -07002507 if (! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002508 *endPtr = start;
2509 return XML_ERROR_NONE;
2510 }
Elliott Hughes72472942018-01-10 08:36:10 -08002511 parser->m_eventPtr = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002512 return XML_ERROR_UNCLOSED_TOKEN;
2513 case XML_TOK_PARTIAL_CHAR:
Haibo Huang40a71912019-10-11 11:13:39 -07002514 if (! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002515 *endPtr = start;
2516 return XML_ERROR_NONE;
2517 }
Elliott Hughes72472942018-01-10 08:36:10 -08002518 parser->m_eventPtr = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002519 return XML_ERROR_PARTIAL_CHAR;
2520 }
Elliott Hughes72472942018-01-10 08:36:10 -08002521 parser->m_processor = externalEntityInitProcessor3;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002522 return externalEntityInitProcessor3(parser, start, end, endPtr);
2523}
2524
2525static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002526externalEntityInitProcessor3(XML_Parser parser, const char *start,
2527 const char *end, const char **endPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002528 int tok;
2529 const char *next = start; /* XmlContentTok doesn't always set the last arg */
Elliott Hughes72472942018-01-10 08:36:10 -08002530 parser->m_eventPtr = start;
2531 tok = XmlContentTok(parser->m_encoding, start, end, &next);
2532 parser->m_eventEndPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002533
2534 switch (tok) {
Haibo Huang40a71912019-10-11 11:13:39 -07002535 case XML_TOK_XML_DECL: {
2536 enum XML_Error result;
2537 result = processXmlDecl(parser, 1, start, next);
2538 if (result != XML_ERROR_NONE)
2539 return result;
2540 switch (parser->m_parsingStatus.parsing) {
2541 case XML_SUSPENDED:
2542 *endPtr = next;
2543 return XML_ERROR_NONE;
2544 case XML_FINISHED:
2545 return XML_ERROR_ABORTED;
2546 default:
2547 start = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002548 }
Haibo Huang40a71912019-10-11 11:13:39 -07002549 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002550 case XML_TOK_PARTIAL:
Haibo Huang40a71912019-10-11 11:13:39 -07002551 if (! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002552 *endPtr = start;
2553 return XML_ERROR_NONE;
2554 }
2555 return XML_ERROR_UNCLOSED_TOKEN;
2556 case XML_TOK_PARTIAL_CHAR:
Haibo Huang40a71912019-10-11 11:13:39 -07002557 if (! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002558 *endPtr = start;
2559 return XML_ERROR_NONE;
2560 }
2561 return XML_ERROR_PARTIAL_CHAR;
2562 }
Elliott Hughes72472942018-01-10 08:36:10 -08002563 parser->m_processor = externalEntityContentProcessor;
2564 parser->m_tagLevel = 1;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002565 return externalEntityContentProcessor(parser, start, end, endPtr);
2566}
2567
2568static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002569externalEntityContentProcessor(XML_Parser parser, const char *start,
2570 const char *end, const char **endPtr) {
2571 enum XML_Error result
2572 = doContent(parser, 1, parser->m_encoding, start, end, endPtr,
2573 (XML_Bool)! parser->m_parsingStatus.finalBuffer);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002574 if (result == XML_ERROR_NONE) {
Haibo Huang40a71912019-10-11 11:13:39 -07002575 if (! storeRawNames(parser))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002576 return XML_ERROR_NO_MEMORY;
2577 }
2578 return result;
2579}
2580
2581static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07002582doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
2583 const char *s, const char *end, const char **nextPtr,
2584 XML_Bool haveMore) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002585 /* save one level of indirection */
Haibo Huang40a71912019-10-11 11:13:39 -07002586 DTD *const dtd = parser->m_dtd;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002587
2588 const char **eventPP;
2589 const char **eventEndPP;
Elliott Hughes72472942018-01-10 08:36:10 -08002590 if (enc == parser->m_encoding) {
2591 eventPP = &parser->m_eventPtr;
2592 eventEndPP = &parser->m_eventEndPtr;
Haibo Huang40a71912019-10-11 11:13:39 -07002593 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08002594 eventPP = &(parser->m_openInternalEntities->internalEventPtr);
2595 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002596 }
2597 *eventPP = s;
2598
2599 for (;;) {
2600 const char *next = s; /* XmlContentTok doesn't always set the last arg */
2601 int tok = XmlContentTok(enc, s, end, &next);
2602 *eventEndPP = next;
2603 switch (tok) {
2604 case XML_TOK_TRAILING_CR:
2605 if (haveMore) {
2606 *nextPtr = s;
2607 return XML_ERROR_NONE;
2608 }
2609 *eventEndPP = end;
Elliott Hughes72472942018-01-10 08:36:10 -08002610 if (parser->m_characterDataHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002611 XML_Char c = 0xA;
Elliott Hughes72472942018-01-10 08:36:10 -08002612 parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
Haibo Huang40a71912019-10-11 11:13:39 -07002613 } else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002614 reportDefault(parser, enc, s, end);
Elliott Hughes35e432d2012-09-09 14:23:38 -07002615 /* We are at the end of the final buffer, should we check for
2616 XML_SUSPENDED, XML_FINISHED?
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002617 */
2618 if (startTagLevel == 0)
2619 return XML_ERROR_NO_ELEMENTS;
Elliott Hughes72472942018-01-10 08:36:10 -08002620 if (parser->m_tagLevel != startTagLevel)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002621 return XML_ERROR_ASYNC_ENTITY;
2622 *nextPtr = end;
2623 return XML_ERROR_NONE;
2624 case XML_TOK_NONE:
2625 if (haveMore) {
2626 *nextPtr = s;
2627 return XML_ERROR_NONE;
2628 }
2629 if (startTagLevel > 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08002630 if (parser->m_tagLevel != startTagLevel)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002631 return XML_ERROR_ASYNC_ENTITY;
2632 *nextPtr = s;
2633 return XML_ERROR_NONE;
2634 }
2635 return XML_ERROR_NO_ELEMENTS;
2636 case XML_TOK_INVALID:
2637 *eventPP = next;
2638 return XML_ERROR_INVALID_TOKEN;
2639 case XML_TOK_PARTIAL:
2640 if (haveMore) {
2641 *nextPtr = s;
2642 return XML_ERROR_NONE;
2643 }
2644 return XML_ERROR_UNCLOSED_TOKEN;
2645 case XML_TOK_PARTIAL_CHAR:
2646 if (haveMore) {
2647 *nextPtr = s;
2648 return XML_ERROR_NONE;
2649 }
2650 return XML_ERROR_PARTIAL_CHAR;
Haibo Huang40a71912019-10-11 11:13:39 -07002651 case XML_TOK_ENTITY_REF: {
2652 const XML_Char *name;
2653 ENTITY *entity;
2654 XML_Char ch = (XML_Char)XmlPredefinedEntityName(
2655 enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar);
2656 if (ch) {
2657 if (parser->m_characterDataHandler)
2658 parser->m_characterDataHandler(parser->m_handlerArg, &ch, 1);
Elliott Hughes72472942018-01-10 08:36:10 -08002659 else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002660 reportDefault(parser, enc, s, next);
2661 break;
2662 }
Haibo Huang40a71912019-10-11 11:13:39 -07002663 name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
2664 next - enc->minBytesPerChar);
2665 if (! name)
2666 return XML_ERROR_NO_MEMORY;
2667 entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
2668 poolDiscard(&dtd->pool);
2669 /* First, determine if a check for an existing declaration is needed;
2670 if yes, check that the entity exists, and that it is internal,
2671 otherwise call the skipped entity or default handler.
2672 */
2673 if (! dtd->hasParamEntityRefs || dtd->standalone) {
2674 if (! entity)
2675 return XML_ERROR_UNDEFINED_ENTITY;
2676 else if (! entity->is_internal)
2677 return XML_ERROR_ENTITY_DECLARED_IN_PE;
2678 } else if (! entity) {
2679 if (parser->m_skippedEntityHandler)
2680 parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
2681 else if (parser->m_defaultHandler)
2682 reportDefault(parser, enc, s, next);
2683 break;
2684 }
2685 if (entity->open)
2686 return XML_ERROR_RECURSIVE_ENTITY_REF;
2687 if (entity->notation)
2688 return XML_ERROR_BINARY_ENTITY_REF;
2689 if (entity->textPtr) {
2690 enum XML_Error result;
2691 if (! parser->m_defaultExpandInternalEntities) {
2692 if (parser->m_skippedEntityHandler)
2693 parser->m_skippedEntityHandler(parser->m_handlerArg, entity->name,
2694 0);
2695 else if (parser->m_defaultHandler)
2696 reportDefault(parser, enc, s, next);
2697 break;
2698 }
2699 result = processInternalEntity(parser, entity, XML_FALSE);
2700 if (result != XML_ERROR_NONE)
2701 return result;
2702 } else if (parser->m_externalEntityRefHandler) {
2703 const XML_Char *context;
2704 entity->open = XML_TRUE;
2705 context = getContext(parser);
2706 entity->open = XML_FALSE;
2707 if (! context)
2708 return XML_ERROR_NO_MEMORY;
2709 if (! parser->m_externalEntityRefHandler(
2710 parser->m_externalEntityRefHandlerArg, context, entity->base,
2711 entity->systemId, entity->publicId))
2712 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
2713 poolDiscard(&parser->m_tempPool);
2714 } else if (parser->m_defaultHandler)
2715 reportDefault(parser, enc, s, next);
2716 break;
2717 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002718 case XML_TOK_START_TAG_NO_ATTS:
2719 /* fall through */
Haibo Huang40a71912019-10-11 11:13:39 -07002720 case XML_TOK_START_TAG_WITH_ATTS: {
2721 TAG *tag;
2722 enum XML_Error result;
2723 XML_Char *toPtr;
2724 if (parser->m_freeTagList) {
2725 tag = parser->m_freeTagList;
2726 parser->m_freeTagList = parser->m_freeTagList->parent;
2727 } else {
2728 tag = (TAG *)MALLOC(parser, sizeof(TAG));
2729 if (! tag)
2730 return XML_ERROR_NO_MEMORY;
2731 tag->buf = (char *)MALLOC(parser, INIT_TAG_BUF_SIZE);
2732 if (! tag->buf) {
2733 FREE(parser, tag);
2734 return XML_ERROR_NO_MEMORY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002735 }
Haibo Huang40a71912019-10-11 11:13:39 -07002736 tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002737 }
Haibo Huang40a71912019-10-11 11:13:39 -07002738 tag->bindings = NULL;
2739 tag->parent = parser->m_tagStack;
2740 parser->m_tagStack = tag;
2741 tag->name.localPart = NULL;
2742 tag->name.prefix = NULL;
2743 tag->rawName = s + enc->minBytesPerChar;
2744 tag->rawNameLength = XmlNameLength(enc, tag->rawName);
2745 ++parser->m_tagLevel;
2746 {
2747 const char *rawNameEnd = tag->rawName + tag->rawNameLength;
2748 const char *fromPtr = tag->rawName;
2749 toPtr = (XML_Char *)tag->buf;
2750 for (;;) {
2751 int bufSize;
2752 int convLen;
2753 const enum XML_Convert_Result convert_res
2754 = XmlConvert(enc, &fromPtr, rawNameEnd, (ICHAR **)&toPtr,
2755 (ICHAR *)tag->bufEnd - 1);
2756 convLen = (int)(toPtr - (XML_Char *)tag->buf);
2757 if ((fromPtr >= rawNameEnd)
2758 || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) {
2759 tag->name.strLen = convLen;
2760 break;
2761 }
2762 bufSize = (int)(tag->bufEnd - tag->buf) << 1;
2763 {
2764 char *temp = (char *)REALLOC(parser, tag->buf, bufSize);
2765 if (temp == NULL)
2766 return XML_ERROR_NO_MEMORY;
2767 tag->buf = temp;
2768 tag->bufEnd = temp + bufSize;
2769 toPtr = (XML_Char *)temp + convLen;
2770 }
2771 }
2772 }
2773 tag->name.str = (XML_Char *)tag->buf;
2774 *toPtr = XML_T('\0');
2775 result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
2776 if (result)
2777 return result;
2778 if (parser->m_startElementHandler)
2779 parser->m_startElementHandler(parser->m_handlerArg, tag->name.str,
2780 (const XML_Char **)parser->m_atts);
2781 else if (parser->m_defaultHandler)
2782 reportDefault(parser, enc, s, next);
2783 poolClear(&parser->m_tempPool);
2784 break;
2785 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002786 case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
2787 /* fall through */
Haibo Huang40a71912019-10-11 11:13:39 -07002788 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS: {
2789 const char *rawName = s + enc->minBytesPerChar;
2790 enum XML_Error result;
2791 BINDING *bindings = NULL;
2792 XML_Bool noElmHandlers = XML_TRUE;
2793 TAG_NAME name;
2794 name.str = poolStoreString(&parser->m_tempPool, enc, rawName,
2795 rawName + XmlNameLength(enc, rawName));
2796 if (! name.str)
2797 return XML_ERROR_NO_MEMORY;
2798 poolFinish(&parser->m_tempPool);
2799 result = storeAtts(parser, enc, s, &name, &bindings);
2800 if (result != XML_ERROR_NONE) {
Elliott Hughes72472942018-01-10 08:36:10 -08002801 freeBindings(parser, bindings);
Haibo Huang40a71912019-10-11 11:13:39 -07002802 return result;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002803 }
Haibo Huang40a71912019-10-11 11:13:39 -07002804 poolFinish(&parser->m_tempPool);
2805 if (parser->m_startElementHandler) {
2806 parser->m_startElementHandler(parser->m_handlerArg, name.str,
2807 (const XML_Char **)parser->m_atts);
2808 noElmHandlers = XML_FALSE;
2809 }
2810 if (parser->m_endElementHandler) {
2811 if (parser->m_startElementHandler)
2812 *eventPP = *eventEndPP;
2813 parser->m_endElementHandler(parser->m_handlerArg, name.str);
2814 noElmHandlers = XML_FALSE;
2815 }
2816 if (noElmHandlers && parser->m_defaultHandler)
2817 reportDefault(parser, enc, s, next);
2818 poolClear(&parser->m_tempPool);
2819 freeBindings(parser, bindings);
2820 }
2821 if ((parser->m_tagLevel == 0)
2822 && (parser->m_parsingStatus.parsing != XML_FINISHED)) {
Elliott Hughesaaec48e2018-08-16 16:29:01 -07002823 if (parser->m_parsingStatus.parsing == XML_SUSPENDED)
2824 parser->m_processor = epilogProcessor;
2825 else
2826 return epilogProcessor(parser, next, end, nextPtr);
Elliott Hughes72472942018-01-10 08:36:10 -08002827 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002828 break;
2829 case XML_TOK_END_TAG:
Elliott Hughes72472942018-01-10 08:36:10 -08002830 if (parser->m_tagLevel == startTagLevel)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002831 return XML_ERROR_ASYNC_ENTITY;
2832 else {
2833 int len;
2834 const char *rawName;
Elliott Hughes72472942018-01-10 08:36:10 -08002835 TAG *tag = parser->m_tagStack;
2836 parser->m_tagStack = tag->parent;
2837 tag->parent = parser->m_freeTagList;
2838 parser->m_freeTagList = tag;
Haibo Huang40a71912019-10-11 11:13:39 -07002839 rawName = s + enc->minBytesPerChar * 2;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002840 len = XmlNameLength(enc, rawName);
2841 if (len != tag->rawNameLength
2842 || memcmp(tag->rawName, rawName, len) != 0) {
2843 *eventPP = rawName;
2844 return XML_ERROR_TAG_MISMATCH;
2845 }
Elliott Hughes72472942018-01-10 08:36:10 -08002846 --parser->m_tagLevel;
2847 if (parser->m_endElementHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002848 const XML_Char *localPart;
2849 const XML_Char *prefix;
2850 XML_Char *uri;
2851 localPart = tag->name.localPart;
Elliott Hughes72472942018-01-10 08:36:10 -08002852 if (parser->m_ns && localPart) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002853 /* localPart and prefix may have been overwritten in
2854 tag->name.str, since this points to the binding->uri
2855 buffer which gets re-used; so we have to add them again
2856 */
2857 uri = (XML_Char *)tag->name.str + tag->name.uriLen;
2858 /* don't need to check for space - already done in storeAtts() */
Haibo Huang40a71912019-10-11 11:13:39 -07002859 while (*localPart)
2860 *uri++ = *localPart++;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002861 prefix = (XML_Char *)tag->name.prefix;
Elliott Hughes72472942018-01-10 08:36:10 -08002862 if (parser->m_ns_triplets && prefix) {
2863 *uri++ = parser->m_namespaceSeparator;
Haibo Huang40a71912019-10-11 11:13:39 -07002864 while (*prefix)
2865 *uri++ = *prefix++;
2866 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002867 *uri = XML_T('\0');
2868 }
Elliott Hughes72472942018-01-10 08:36:10 -08002869 parser->m_endElementHandler(parser->m_handlerArg, tag->name.str);
Haibo Huang40a71912019-10-11 11:13:39 -07002870 } else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002871 reportDefault(parser, enc, s, next);
2872 while (tag->bindings) {
2873 BINDING *b = tag->bindings;
Elliott Hughes72472942018-01-10 08:36:10 -08002874 if (parser->m_endNamespaceDeclHandler)
Haibo Huang40a71912019-10-11 11:13:39 -07002875 parser->m_endNamespaceDeclHandler(parser->m_handlerArg,
2876 b->prefix->name);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002877 tag->bindings = tag->bindings->nextTagBinding;
Elliott Hughes72472942018-01-10 08:36:10 -08002878 b->nextTagBinding = parser->m_freeBindingList;
2879 parser->m_freeBindingList = b;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002880 b->prefix->binding = b->prevPrefixBinding;
2881 }
Haibo Huang40a71912019-10-11 11:13:39 -07002882 if ((parser->m_tagLevel == 0)
2883 && (parser->m_parsingStatus.parsing != XML_FINISHED)) {
2884 if (parser->m_parsingStatus.parsing == XML_SUSPENDED)
2885 parser->m_processor = epilogProcessor;
2886 else
2887 return epilogProcessor(parser, next, end, nextPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002888 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002889 }
2890 break;
Haibo Huang40a71912019-10-11 11:13:39 -07002891 case XML_TOK_CHAR_REF: {
2892 int n = XmlCharRefNumber(enc, s);
2893 if (n < 0)
2894 return XML_ERROR_BAD_CHAR_REF;
2895 if (parser->m_characterDataHandler) {
2896 XML_Char buf[XML_ENCODE_MAX];
2897 parser->m_characterDataHandler(parser->m_handlerArg, buf,
2898 XmlEncode(n, (ICHAR *)buf));
2899 } else if (parser->m_defaultHandler)
2900 reportDefault(parser, enc, s, next);
2901 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002902 case XML_TOK_XML_DECL:
2903 return XML_ERROR_MISPLACED_XML_PI;
2904 case XML_TOK_DATA_NEWLINE:
Elliott Hughes72472942018-01-10 08:36:10 -08002905 if (parser->m_characterDataHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002906 XML_Char c = 0xA;
Elliott Hughes72472942018-01-10 08:36:10 -08002907 parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
Haibo Huang40a71912019-10-11 11:13:39 -07002908 } else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002909 reportDefault(parser, enc, s, next);
2910 break;
Haibo Huang40a71912019-10-11 11:13:39 -07002911 case XML_TOK_CDATA_SECT_OPEN: {
2912 enum XML_Error result;
2913 if (parser->m_startCdataSectionHandler)
2914 parser->m_startCdataSectionHandler(parser->m_handlerArg);
2915 /* BEGIN disabled code */
2916 /* Suppose you doing a transformation on a document that involves
2917 changing only the character data. You set up a defaultHandler
2918 and a characterDataHandler. The defaultHandler simply copies
2919 characters through. The characterDataHandler does the
2920 transformation and writes the characters out escaping them as
2921 necessary. This case will fail to work if we leave out the
2922 following two lines (because & and < inside CDATA sections will
2923 be incorrectly escaped).
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002924
Haibo Huang40a71912019-10-11 11:13:39 -07002925 However, now we have a start/endCdataSectionHandler, so it seems
2926 easier to let the user deal with this.
2927 */
2928 else if (0 && parser->m_characterDataHandler)
2929 parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf,
2930 0);
2931 /* END disabled code */
2932 else if (parser->m_defaultHandler)
2933 reportDefault(parser, enc, s, next);
2934 result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
2935 if (result != XML_ERROR_NONE)
2936 return result;
2937 else if (! next) {
2938 parser->m_processor = cdataSectionProcessor;
2939 return result;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002940 }
Haibo Huang40a71912019-10-11 11:13:39 -07002941 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002942 case XML_TOK_TRAILING_RSQB:
2943 if (haveMore) {
2944 *nextPtr = s;
2945 return XML_ERROR_NONE;
2946 }
Elliott Hughes72472942018-01-10 08:36:10 -08002947 if (parser->m_characterDataHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002948 if (MUST_CONVERT(enc, s)) {
Elliott Hughes72472942018-01-10 08:36:10 -08002949 ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
2950 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
Haibo Huang40a71912019-10-11 11:13:39 -07002951 parser->m_characterDataHandler(
2952 parser->m_handlerArg, parser->m_dataBuf,
2953 (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
2954 } else
2955 parser->m_characterDataHandler(
2956 parser->m_handlerArg, (XML_Char *)s,
2957 (int)((XML_Char *)end - (XML_Char *)s));
2958 } else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002959 reportDefault(parser, enc, s, end);
Elliott Hughes35e432d2012-09-09 14:23:38 -07002960 /* We are at the end of the final buffer, should we check for
2961 XML_SUSPENDED, XML_FINISHED?
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002962 */
2963 if (startTagLevel == 0) {
2964 *eventPP = end;
2965 return XML_ERROR_NO_ELEMENTS;
2966 }
Elliott Hughes72472942018-01-10 08:36:10 -08002967 if (parser->m_tagLevel != startTagLevel) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002968 *eventPP = end;
2969 return XML_ERROR_ASYNC_ENTITY;
2970 }
2971 *nextPtr = end;
2972 return XML_ERROR_NONE;
Haibo Huang40a71912019-10-11 11:13:39 -07002973 case XML_TOK_DATA_CHARS: {
2974 XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler;
2975 if (charDataHandler) {
2976 if (MUST_CONVERT(enc, s)) {
2977 for (;;) {
2978 ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
2979 const enum XML_Convert_Result convert_res = XmlConvert(
2980 enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
2981 *eventEndPP = s;
2982 charDataHandler(parser->m_handlerArg, parser->m_dataBuf,
2983 (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
2984 if ((convert_res == XML_CONVERT_COMPLETED)
2985 || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
2986 break;
2987 *eventPP = s;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002988 }
Haibo Huang40a71912019-10-11 11:13:39 -07002989 } else
2990 charDataHandler(parser->m_handlerArg, (XML_Char *)s,
2991 (int)((XML_Char *)next - (XML_Char *)s));
2992 } else if (parser->m_defaultHandler)
2993 reportDefault(parser, enc, s, next);
2994 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002995 case XML_TOK_PI:
Haibo Huang40a71912019-10-11 11:13:39 -07002996 if (! reportProcessingInstruction(parser, enc, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002997 return XML_ERROR_NO_MEMORY;
2998 break;
2999 case XML_TOK_COMMENT:
Haibo Huang40a71912019-10-11 11:13:39 -07003000 if (! reportComment(parser, enc, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003001 return XML_ERROR_NO_MEMORY;
3002 break;
3003 default:
Elliott Hughes72472942018-01-10 08:36:10 -08003004 /* All of the tokens produced by XmlContentTok() have their own
3005 * explicit cases, so this default is not strictly necessary.
3006 * However it is a useful safety net, so we retain the code and
3007 * simply exclude it from the coverage tests.
3008 *
3009 * LCOV_EXCL_START
3010 */
3011 if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003012 reportDefault(parser, enc, s, next);
3013 break;
Elliott Hughes72472942018-01-10 08:36:10 -08003014 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003015 }
3016 *eventPP = s = next;
Elliott Hughes72472942018-01-10 08:36:10 -08003017 switch (parser->m_parsingStatus.parsing) {
Elliott Hughes35e432d2012-09-09 14:23:38 -07003018 case XML_SUSPENDED:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003019 *nextPtr = next;
3020 return XML_ERROR_NONE;
3021 case XML_FINISHED:
3022 return XML_ERROR_ABORTED;
Haibo Huang40a71912019-10-11 11:13:39 -07003023 default:;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003024 }
3025 }
3026 /* not reached */
3027}
3028
Elliott Hughes72472942018-01-10 08:36:10 -08003029/* This function does not call free() on the allocated memory, merely
3030 * moving it to the parser's m_freeBindingList where it can be freed or
3031 * reused as appropriate.
3032 */
3033static void
Haibo Huang40a71912019-10-11 11:13:39 -07003034freeBindings(XML_Parser parser, BINDING *bindings) {
Elliott Hughes72472942018-01-10 08:36:10 -08003035 while (bindings) {
3036 BINDING *b = bindings;
3037
3038 /* m_startNamespaceDeclHandler will have been called for this
3039 * binding in addBindings(), so call the end handler now.
3040 */
3041 if (parser->m_endNamespaceDeclHandler)
Haibo Huang40a71912019-10-11 11:13:39 -07003042 parser->m_endNamespaceDeclHandler(parser->m_handlerArg, b->prefix->name);
Elliott Hughes72472942018-01-10 08:36:10 -08003043
3044 bindings = bindings->nextTagBinding;
3045 b->nextTagBinding = parser->m_freeBindingList;
3046 parser->m_freeBindingList = b;
3047 b->prefix->binding = b->prevPrefixBinding;
3048 }
3049}
3050
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003051/* Precondition: all arguments must be non-NULL;
3052 Purpose:
3053 - normalize attributes
3054 - check attributes for well-formedness
3055 - generate namespace aware attribute names (URI, prefix)
3056 - build list of attributes for startElementHandler
3057 - default attributes
3058 - process namespace declarations (check and report them)
3059 - generate namespace aware element name (URI, prefix)
3060*/
3061static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07003062storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
3063 TAG_NAME *tagNamePtr, BINDING **bindingsPtr) {
3064 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003065 ELEMENT_TYPE *elementType;
3066 int nDefaultAtts;
Haibo Huang40a71912019-10-11 11:13:39 -07003067 const XML_Char **appAtts; /* the attribute list for the application */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003068 int attIndex = 0;
3069 int prefixLen;
3070 int i;
3071 int n;
3072 XML_Char *uri;
3073 int nPrefixes = 0;
3074 BINDING *binding;
3075 const XML_Char *localPart;
3076
3077 /* lookup the element type name */
Haibo Huang40a71912019-10-11 11:13:39 -07003078 elementType
3079 = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str, 0);
3080 if (! elementType) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003081 const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
Haibo Huang40a71912019-10-11 11:13:39 -07003082 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003083 return XML_ERROR_NO_MEMORY;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003084 elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003085 sizeof(ELEMENT_TYPE));
Haibo Huang40a71912019-10-11 11:13:39 -07003086 if (! elementType)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003087 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07003088 if (parser->m_ns && ! setElementTypePrefix(parser, elementType))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003089 return XML_ERROR_NO_MEMORY;
3090 }
3091 nDefaultAtts = elementType->nDefaultAtts;
3092
3093 /* get the attributes from the tokenizer */
Elliott Hughes72472942018-01-10 08:36:10 -08003094 n = XmlGetAttributes(enc, attStr, parser->m_attsSize, parser->m_atts);
Sadaf Ebrahimif68f6852022-06-15 04:14:33 +00003095
3096 /* Detect and prevent integer overflow */
3097 if (n > INT_MAX - nDefaultAtts) {
3098 return XML_ERROR_NO_MEMORY;
3099 }
3100
Elliott Hughes72472942018-01-10 08:36:10 -08003101 if (n + nDefaultAtts > parser->m_attsSize) {
3102 int oldAttsSize = parser->m_attsSize;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003103 ATTRIBUTE *temp;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003104#ifdef XML_ATTR_INFO
3105 XML_AttrInfo *temp2;
3106#endif
Sadaf Ebrahimif68f6852022-06-15 04:14:33 +00003107
3108 /* Detect and prevent integer overflow */
3109 if ((nDefaultAtts > INT_MAX - INIT_ATTS_SIZE)
3110 || (n > INT_MAX - (nDefaultAtts + INIT_ATTS_SIZE))) {
3111 return XML_ERROR_NO_MEMORY;
3112 }
3113
Elliott Hughes72472942018-01-10 08:36:10 -08003114 parser->m_attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
Sadaf Ebrahimif68f6852022-06-15 04:14:33 +00003115
3116 /* Detect and prevent integer overflow.
3117 * The preprocessor guard addresses the "always false" warning
3118 * from -Wtype-limits on platforms where
3119 * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
3120#if UINT_MAX >= SIZE_MAX
3121 if ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(ATTRIBUTE)) {
3122 parser->m_attsSize = oldAttsSize;
3123 return XML_ERROR_NO_MEMORY;
3124 }
3125#endif
3126
Haibo Huang40a71912019-10-11 11:13:39 -07003127 temp = (ATTRIBUTE *)REALLOC(parser, (void *)parser->m_atts,
3128 parser->m_attsSize * sizeof(ATTRIBUTE));
Elliott Hughes72472942018-01-10 08:36:10 -08003129 if (temp == NULL) {
3130 parser->m_attsSize = oldAttsSize;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003131 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08003132 }
3133 parser->m_atts = temp;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003134#ifdef XML_ATTR_INFO
Sadaf Ebrahimif68f6852022-06-15 04:14:33 +00003135 /* Detect and prevent integer overflow.
3136 * The preprocessor guard addresses the "always false" warning
3137 * from -Wtype-limits on platforms where
3138 * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
3139# if UINT_MAX >= SIZE_MAX
3140 if ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(XML_AttrInfo)) {
3141 parser->m_attsSize = oldAttsSize;
3142 return XML_ERROR_NO_MEMORY;
3143 }
3144# endif
3145
Haibo Huang40a71912019-10-11 11:13:39 -07003146 temp2 = (XML_AttrInfo *)REALLOC(parser, (void *)parser->m_attInfo,
3147 parser->m_attsSize * sizeof(XML_AttrInfo));
Elliott Hughes72472942018-01-10 08:36:10 -08003148 if (temp2 == NULL) {
3149 parser->m_attsSize = oldAttsSize;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003150 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08003151 }
3152 parser->m_attInfo = temp2;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003153#endif
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003154 if (n > oldAttsSize)
Elliott Hughes72472942018-01-10 08:36:10 -08003155 XmlGetAttributes(enc, attStr, n, parser->m_atts);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003156 }
3157
Elliott Hughes72472942018-01-10 08:36:10 -08003158 appAtts = (const XML_Char **)parser->m_atts;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003159 for (i = 0; i < n; i++) {
Elliott Hughes72472942018-01-10 08:36:10 -08003160 ATTRIBUTE *currAtt = &parser->m_atts[i];
Elliott Hughes35e432d2012-09-09 14:23:38 -07003161#ifdef XML_ATTR_INFO
Elliott Hughes72472942018-01-10 08:36:10 -08003162 XML_AttrInfo *currAttInfo = &parser->m_attInfo[i];
Elliott Hughes35e432d2012-09-09 14:23:38 -07003163#endif
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003164 /* add the name and value to the attribute list */
Haibo Huang40a71912019-10-11 11:13:39 -07003165 ATTRIBUTE_ID *attId
3166 = getAttributeId(parser, enc, currAtt->name,
3167 currAtt->name + XmlNameLength(enc, currAtt->name));
3168 if (! attId)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003169 return XML_ERROR_NO_MEMORY;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003170#ifdef XML_ATTR_INFO
Haibo Huang40a71912019-10-11 11:13:39 -07003171 currAttInfo->nameStart
3172 = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->name);
3173 currAttInfo->nameEnd
3174 = currAttInfo->nameStart + XmlNameLength(enc, currAtt->name);
3175 currAttInfo->valueStart = parser->m_parseEndByteIndex
3176 - (parser->m_parseEndPtr - currAtt->valuePtr);
3177 currAttInfo->valueEnd = parser->m_parseEndByteIndex
3178 - (parser->m_parseEndPtr - currAtt->valueEnd);
Elliott Hughes35e432d2012-09-09 14:23:38 -07003179#endif
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003180 /* Detect duplicate attributes by their QNames. This does not work when
3181 namespace processing is turned on and different prefixes for the same
3182 namespace are used. For this case we have a check further down.
3183 */
3184 if ((attId->name)[-1]) {
Elliott Hughes72472942018-01-10 08:36:10 -08003185 if (enc == parser->m_encoding)
3186 parser->m_eventPtr = parser->m_atts[i].name;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003187 return XML_ERROR_DUPLICATE_ATTRIBUTE;
3188 }
3189 (attId->name)[-1] = 1;
3190 appAtts[attIndex++] = attId->name;
Haibo Huang40a71912019-10-11 11:13:39 -07003191 if (! parser->m_atts[i].normalized) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003192 enum XML_Error result;
3193 XML_Bool isCdata = XML_TRUE;
3194
3195 /* figure out whether declared as other than CDATA */
3196 if (attId->maybeTokenized) {
3197 int j;
3198 for (j = 0; j < nDefaultAtts; j++) {
3199 if (attId == elementType->defaultAtts[j].id) {
3200 isCdata = elementType->defaultAtts[j].isCdata;
3201 break;
3202 }
3203 }
3204 }
3205
3206 /* normalize the attribute value */
Haibo Huang40a71912019-10-11 11:13:39 -07003207 result = storeAttributeValue(
3208 parser, enc, isCdata, parser->m_atts[i].valuePtr,
3209 parser->m_atts[i].valueEnd, &parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003210 if (result)
3211 return result;
Elliott Hughes72472942018-01-10 08:36:10 -08003212 appAtts[attIndex] = poolStart(&parser->m_tempPool);
3213 poolFinish(&parser->m_tempPool);
Haibo Huang40a71912019-10-11 11:13:39 -07003214 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003215 /* the value did not need normalizing */
Haibo Huang40a71912019-10-11 11:13:39 -07003216 appAtts[attIndex] = poolStoreString(&parser->m_tempPool, enc,
3217 parser->m_atts[i].valuePtr,
Elliott Hughes72472942018-01-10 08:36:10 -08003218 parser->m_atts[i].valueEnd);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003219 if (appAtts[attIndex] == 0)
3220 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08003221 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003222 }
3223 /* handle prefixed attribute names */
3224 if (attId->prefix) {
3225 if (attId->xmlns) {
3226 /* deal with namespace declarations here */
3227 enum XML_Error result = addBinding(parser, attId->prefix, attId,
3228 appAtts[attIndex], bindingsPtr);
3229 if (result)
3230 return result;
3231 --attIndex;
Haibo Huang40a71912019-10-11 11:13:39 -07003232 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003233 /* deal with other prefixed names later */
3234 attIndex++;
3235 nPrefixes++;
3236 (attId->name)[-1] = 2;
3237 }
Haibo Huang40a71912019-10-11 11:13:39 -07003238 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003239 attIndex++;
3240 }
3241
3242 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
Elliott Hughes72472942018-01-10 08:36:10 -08003243 parser->m_nSpecifiedAtts = attIndex;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003244 if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
3245 for (i = 0; i < attIndex; i += 2)
3246 if (appAtts[i] == elementType->idAtt->name) {
Elliott Hughes72472942018-01-10 08:36:10 -08003247 parser->m_idAttIndex = i;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003248 break;
3249 }
Haibo Huang40a71912019-10-11 11:13:39 -07003250 } else
Elliott Hughes72472942018-01-10 08:36:10 -08003251 parser->m_idAttIndex = -1;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003252
3253 /* do attribute defaulting */
3254 for (i = 0; i < nDefaultAtts; i++) {
3255 const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
Haibo Huang40a71912019-10-11 11:13:39 -07003256 if (! (da->id->name)[-1] && da->value) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003257 if (da->id->prefix) {
3258 if (da->id->xmlns) {
3259 enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
3260 da->value, bindingsPtr);
3261 if (result)
3262 return result;
Haibo Huang40a71912019-10-11 11:13:39 -07003263 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003264 (da->id->name)[-1] = 2;
3265 nPrefixes++;
3266 appAtts[attIndex++] = da->id->name;
3267 appAtts[attIndex++] = da->value;
3268 }
Haibo Huang40a71912019-10-11 11:13:39 -07003269 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003270 (da->id->name)[-1] = 1;
3271 appAtts[attIndex++] = da->id->name;
3272 appAtts[attIndex++] = da->value;
3273 }
3274 }
3275 }
3276 appAtts[attIndex] = 0;
3277
3278 /* expand prefixed attribute names, check for duplicates,
3279 and clear flags that say whether attributes were specified */
3280 i = 0;
3281 if (nPrefixes) {
Haibo Huang40a71912019-10-11 11:13:39 -07003282 int j; /* hash table index */
Elliott Hughes72472942018-01-10 08:36:10 -08003283 unsigned long version = parser->m_nsAttsVersion;
3284 int nsAttsSize = (int)1 << parser->m_nsAttsPower;
3285 unsigned char oldNsAttsPower = parser->m_nsAttsPower;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003286 /* size of hash table must be at least 2 * (# of prefixed attributes) */
Haibo Huang40a71912019-10-11 11:13:39 -07003287 if ((nPrefixes << 1)
3288 >> parser->m_nsAttsPower) { /* true for m_nsAttsPower = 0 */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003289 NS_ATT *temp;
3290 /* hash table size must also be a power of 2 and >= 8 */
Haibo Huang40a71912019-10-11 11:13:39 -07003291 while (nPrefixes >> parser->m_nsAttsPower++)
3292 ;
Elliott Hughes72472942018-01-10 08:36:10 -08003293 if (parser->m_nsAttsPower < 3)
3294 parser->m_nsAttsPower = 3;
3295 nsAttsSize = (int)1 << parser->m_nsAttsPower;
Haibo Huang40a71912019-10-11 11:13:39 -07003296 temp = (NS_ATT *)REALLOC(parser, parser->m_nsAtts,
3297 nsAttsSize * sizeof(NS_ATT));
3298 if (! temp) {
Elliott Hughes72472942018-01-10 08:36:10 -08003299 /* Restore actual size of memory in m_nsAtts */
3300 parser->m_nsAttsPower = oldNsAttsPower;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003301 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08003302 }
3303 parser->m_nsAtts = temp;
Haibo Huang40a71912019-10-11 11:13:39 -07003304 version = 0; /* force re-initialization of m_nsAtts hash table */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003305 }
Elliott Hughes72472942018-01-10 08:36:10 -08003306 /* using a version flag saves us from initializing m_nsAtts every time */
Haibo Huang40a71912019-10-11 11:13:39 -07003307 if (! version) { /* initialize version flags when version wraps around */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003308 version = INIT_ATTS_VERSION;
Haibo Huang40a71912019-10-11 11:13:39 -07003309 for (j = nsAttsSize; j != 0;)
Elliott Hughes72472942018-01-10 08:36:10 -08003310 parser->m_nsAtts[--j].version = version;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003311 }
Elliott Hughes72472942018-01-10 08:36:10 -08003312 parser->m_nsAttsVersion = --version;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003313
3314 /* expand prefixed names and check for duplicates */
3315 for (; i < attIndex; i += 2) {
3316 const XML_Char *s = appAtts[i];
Haibo Huang40a71912019-10-11 11:13:39 -07003317 if (s[-1] == 2) { /* prefixed */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003318 ATTRIBUTE_ID *id;
3319 const BINDING *b;
Elliott Hughes72472942018-01-10 08:36:10 -08003320 unsigned long uriHash;
3321 struct siphash sip_state;
3322 struct sipkey sip_key;
3323
3324 copy_salt_to_sipkey(parser, &sip_key);
3325 sip24_init(&sip_state, &sip_key);
3326
Haibo Huang40a71912019-10-11 11:13:39 -07003327 ((XML_Char *)s)[-1] = 0; /* clear flag */
Elliott Hughes35e432d2012-09-09 14:23:38 -07003328 id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);
Haibo Huang40a71912019-10-11 11:13:39 -07003329 if (! id || ! id->prefix) {
Elliott Hughes72472942018-01-10 08:36:10 -08003330 /* This code is walking through the appAtts array, dealing
3331 * with (in this case) a prefixed attribute name. To be in
3332 * the array, the attribute must have already been bound, so
3333 * has to have passed through the hash table lookup once
3334 * already. That implies that an entry for it already
3335 * exists, so the lookup above will return a pointer to
3336 * already allocated memory. There is no opportunaity for
3337 * the allocator to fail, so the condition above cannot be
3338 * fulfilled.
3339 *
3340 * Since it is difficult to be certain that the above
3341 * analysis is complete, we retain the test and merely
3342 * remove the code from coverage tests.
3343 */
3344 return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */
3345 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003346 b = id->prefix->binding;
Haibo Huang40a71912019-10-11 11:13:39 -07003347 if (! b)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003348 return XML_ERROR_UNBOUND_PREFIX;
3349
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003350 for (j = 0; j < b->uriLen; j++) {
3351 const XML_Char c = b->uri[j];
Haibo Huang40a71912019-10-11 11:13:39 -07003352 if (! poolAppendChar(&parser->m_tempPool, c))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003353 return XML_ERROR_NO_MEMORY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003354 }
Elliott Hughes72472942018-01-10 08:36:10 -08003355
3356 sip24_update(&sip_state, b->uri, b->uriLen * sizeof(XML_Char));
3357
Elliott Hughesd07d5a72009-09-25 16:04:37 -07003358 while (*s++ != XML_T(ASCII_COLON))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003359 ;
Elliott Hughes72472942018-01-10 08:36:10 -08003360
3361 sip24_update(&sip_state, s, keylen(s) * sizeof(XML_Char));
3362
Haibo Huang40a71912019-10-11 11:13:39 -07003363 do { /* copies null terminator */
3364 if (! poolAppendChar(&parser->m_tempPool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003365 return XML_ERROR_NO_MEMORY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003366 } while (*s++);
3367
Elliott Hughes72472942018-01-10 08:36:10 -08003368 uriHash = (unsigned long)sip24_final(&sip_state);
3369
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003370 { /* Check hash table for duplicate of expanded name (uriName).
Elliott Hughes35e432d2012-09-09 14:23:38 -07003371 Derived from code in lookup(parser, HASH_TABLE *table, ...).
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003372 */
3373 unsigned char step = 0;
3374 unsigned long mask = nsAttsSize - 1;
Haibo Huang40a71912019-10-11 11:13:39 -07003375 j = uriHash & mask; /* index into hash table */
Elliott Hughes72472942018-01-10 08:36:10 -08003376 while (parser->m_nsAtts[j].version == version) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003377 /* for speed we compare stored hash values first */
Elliott Hughes72472942018-01-10 08:36:10 -08003378 if (uriHash == parser->m_nsAtts[j].hash) {
3379 const XML_Char *s1 = poolStart(&parser->m_tempPool);
3380 const XML_Char *s2 = parser->m_nsAtts[j].uriName;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003381 /* s1 is null terminated, but not s2 */
Haibo Huang40a71912019-10-11 11:13:39 -07003382 for (; *s1 == *s2 && *s1 != 0; s1++, s2++)
3383 ;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003384 if (*s1 == 0)
3385 return XML_ERROR_DUPLICATE_ATTRIBUTE;
3386 }
Haibo Huang40a71912019-10-11 11:13:39 -07003387 if (! step)
Elliott Hughes72472942018-01-10 08:36:10 -08003388 step = PROBE_STEP(uriHash, mask, parser->m_nsAttsPower);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003389 j < step ? (j += nsAttsSize - step) : (j -= step);
3390 }
3391 }
3392
Haibo Huang40a71912019-10-11 11:13:39 -07003393 if (parser->m_ns_triplets) { /* append namespace separator and prefix */
Elliott Hughes72472942018-01-10 08:36:10 -08003394 parser->m_tempPool.ptr[-1] = parser->m_namespaceSeparator;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003395 s = b->prefix->name;
3396 do {
Haibo Huang40a71912019-10-11 11:13:39 -07003397 if (! poolAppendChar(&parser->m_tempPool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003398 return XML_ERROR_NO_MEMORY;
3399 } while (*s++);
3400 }
3401
3402 /* store expanded name in attribute list */
Elliott Hughes72472942018-01-10 08:36:10 -08003403 s = poolStart(&parser->m_tempPool);
3404 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003405 appAtts[i] = s;
3406
3407 /* fill empty slot with new version, uriName and hash value */
Elliott Hughes72472942018-01-10 08:36:10 -08003408 parser->m_nsAtts[j].version = version;
3409 parser->m_nsAtts[j].hash = uriHash;
3410 parser->m_nsAtts[j].uriName = s;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003411
Haibo Huang40a71912019-10-11 11:13:39 -07003412 if (! --nPrefixes) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003413 i += 2;
3414 break;
3415 }
Haibo Huang40a71912019-10-11 11:13:39 -07003416 } else /* not prefixed */
3417 ((XML_Char *)s)[-1] = 0; /* clear flag */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003418 }
3419 }
3420 /* clear flags for the remaining attributes */
3421 for (; i < attIndex; i += 2)
3422 ((XML_Char *)(appAtts[i]))[-1] = 0;
3423 for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
3424 binding->attId->name[-1] = 0;
3425
Haibo Huang40a71912019-10-11 11:13:39 -07003426 if (! parser->m_ns)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003427 return XML_ERROR_NONE;
3428
3429 /* expand the element type name */
3430 if (elementType->prefix) {
3431 binding = elementType->prefix->binding;
Haibo Huang40a71912019-10-11 11:13:39 -07003432 if (! binding)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003433 return XML_ERROR_UNBOUND_PREFIX;
3434 localPart = tagNamePtr->str;
Elliott Hughesd07d5a72009-09-25 16:04:37 -07003435 while (*localPart++ != XML_T(ASCII_COLON))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003436 ;
Haibo Huang40a71912019-10-11 11:13:39 -07003437 } else if (dtd->defaultPrefix.binding) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003438 binding = dtd->defaultPrefix.binding;
3439 localPart = tagNamePtr->str;
Haibo Huang40a71912019-10-11 11:13:39 -07003440 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003441 return XML_ERROR_NONE;
3442 prefixLen = 0;
Elliott Hughes72472942018-01-10 08:36:10 -08003443 if (parser->m_ns_triplets && binding->prefix->name) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003444 for (; binding->prefix->name[prefixLen++];)
Haibo Huang40a71912019-10-11 11:13:39 -07003445 ; /* prefixLen includes null terminator */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003446 }
3447 tagNamePtr->localPart = localPart;
3448 tagNamePtr->uriLen = binding->uriLen;
3449 tagNamePtr->prefix = binding->prefix->name;
3450 tagNamePtr->prefixLen = prefixLen;
3451 for (i = 0; localPart[i++];)
Haibo Huang40a71912019-10-11 11:13:39 -07003452 ; /* i includes null terminator */
Sadaf Ebrahimif68f6852022-06-15 04:14:33 +00003453
3454 /* Detect and prevent integer overflow */
3455 if (binding->uriLen > INT_MAX - prefixLen
3456 || i > INT_MAX - (binding->uriLen + prefixLen)) {
3457 return XML_ERROR_NO_MEMORY;
3458 }
3459
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003460 n = i + binding->uriLen + prefixLen;
3461 if (n > binding->uriAlloc) {
3462 TAG *p;
Sadaf Ebrahimif68f6852022-06-15 04:14:33 +00003463
3464 /* Detect and prevent integer overflow */
3465 if (n > INT_MAX - EXPAND_SPARE) {
3466 return XML_ERROR_NO_MEMORY;
3467 }
3468 /* Detect and prevent integer overflow.
3469 * The preprocessor guard addresses the "always false" warning
3470 * from -Wtype-limits on platforms where
3471 * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
3472#if UINT_MAX >= SIZE_MAX
3473 if ((unsigned)(n + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) {
3474 return XML_ERROR_NO_MEMORY;
3475 }
3476#endif
3477
Elliott Hughes72472942018-01-10 08:36:10 -08003478 uri = (XML_Char *)MALLOC(parser, (n + EXPAND_SPARE) * sizeof(XML_Char));
Haibo Huang40a71912019-10-11 11:13:39 -07003479 if (! uri)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003480 return XML_ERROR_NO_MEMORY;
3481 binding->uriAlloc = n + EXPAND_SPARE;
3482 memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
Elliott Hughes72472942018-01-10 08:36:10 -08003483 for (p = parser->m_tagStack; p; p = p->parent)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003484 if (p->name.str == binding->uri)
3485 p->name.str = uri;
Elliott Hughes72472942018-01-10 08:36:10 -08003486 FREE(parser, binding->uri);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003487 binding->uri = uri;
3488 }
Elliott Hughes72472942018-01-10 08:36:10 -08003489 /* if m_namespaceSeparator != '\0' then uri includes it already */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003490 uri = binding->uri + binding->uriLen;
3491 memcpy(uri, localPart, i * sizeof(XML_Char));
3492 /* we always have a namespace separator between localPart and prefix */
3493 if (prefixLen) {
3494 uri += i - 1;
Haibo Huang40a71912019-10-11 11:13:39 -07003495 *uri = parser->m_namespaceSeparator; /* replace null terminator */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003496 memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
3497 }
3498 tagNamePtr->str = binding->uri;
3499 return XML_ERROR_NONE;
3500}
3501
3502/* addBinding() overwrites the value of prefix->binding without checking.
3503 Therefore one must keep track of the old value outside of addBinding().
3504*/
3505static enum XML_Error
3506addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
Haibo Huang40a71912019-10-11 11:13:39 -07003507 const XML_Char *uri, BINDING **bindingsPtr) {
3508 static const XML_Char xmlNamespace[]
3509 = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON,
3510 ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w,
3511 ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o,
3512 ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M,
3513 ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9,
3514 ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m,
3515 ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c,
3516 ASCII_e, '\0'};
3517 static const int xmlLen = (int)sizeof(xmlNamespace) / sizeof(XML_Char) - 1;
3518 static const XML_Char xmlnsNamespace[]
3519 = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH,
3520 ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w,
3521 ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH,
3522 ASCII_2, ASCII_0, ASCII_0, ASCII_0, ASCII_SLASH, ASCII_x,
3523 ASCII_m, ASCII_l, ASCII_n, ASCII_s, ASCII_SLASH, '\0'};
3524 static const int xmlnsLen
3525 = (int)sizeof(xmlnsNamespace) / sizeof(XML_Char) - 1;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003526
3527 XML_Bool mustBeXML = XML_FALSE;
3528 XML_Bool isXML = XML_TRUE;
3529 XML_Bool isXMLNS = XML_TRUE;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003530
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003531 BINDING *b;
3532 int len;
3533
3534 /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
3535 if (*uri == XML_T('\0') && prefix->name)
3536 return XML_ERROR_UNDECLARING_PREFIX;
3537
Haibo Huang40a71912019-10-11 11:13:39 -07003538 if (prefix->name && prefix->name[0] == XML_T(ASCII_x)
Elliott Hughesd07d5a72009-09-25 16:04:37 -07003539 && prefix->name[1] == XML_T(ASCII_m)
3540 && prefix->name[2] == XML_T(ASCII_l)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003541 /* Not allowed to bind xmlns */
Haibo Huang40a71912019-10-11 11:13:39 -07003542 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 -08003543 && prefix->name[5] == XML_T('\0'))
3544 return XML_ERROR_RESERVED_PREFIX_XMLNS;
3545
3546 if (prefix->name[3] == XML_T('\0'))
3547 mustBeXML = XML_TRUE;
3548 }
3549
3550 for (len = 0; uri[len]; len++) {
3551 if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
3552 isXML = XML_FALSE;
3553
Haibo Huang40a71912019-10-11 11:13:39 -07003554 if (! mustBeXML && isXMLNS
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003555 && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
3556 isXMLNS = XML_FALSE;
3557 }
3558 isXML = isXML && len == xmlLen;
3559 isXMLNS = isXMLNS && len == xmlnsLen;
3560
3561 if (mustBeXML != isXML)
3562 return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
3563 : XML_ERROR_RESERVED_NAMESPACE_URI;
3564
3565 if (isXMLNS)
3566 return XML_ERROR_RESERVED_NAMESPACE_URI;
3567
Elliott Hughes72472942018-01-10 08:36:10 -08003568 if (parser->m_namespaceSeparator)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003569 len++;
Elliott Hughes72472942018-01-10 08:36:10 -08003570 if (parser->m_freeBindingList) {
3571 b = parser->m_freeBindingList;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003572 if (len > b->uriAlloc) {
Sadaf Ebrahimif68f6852022-06-15 04:14:33 +00003573 /* Detect and prevent integer overflow */
3574 if (len > INT_MAX - EXPAND_SPARE) {
3575 return XML_ERROR_NO_MEMORY;
3576 }
3577
3578 /* Detect and prevent integer overflow.
3579 * The preprocessor guard addresses the "always false" warning
3580 * from -Wtype-limits on platforms where
3581 * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
3582#if UINT_MAX >= SIZE_MAX
3583 if ((unsigned)(len + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) {
3584 return XML_ERROR_NO_MEMORY;
3585 }
3586#endif
3587
Haibo Huang40a71912019-10-11 11:13:39 -07003588 XML_Char *temp = (XML_Char *)REALLOC(
3589 parser, b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003590 if (temp == NULL)
3591 return XML_ERROR_NO_MEMORY;
3592 b->uri = temp;
3593 b->uriAlloc = len + EXPAND_SPARE;
3594 }
Elliott Hughes72472942018-01-10 08:36:10 -08003595 parser->m_freeBindingList = b->nextTagBinding;
Haibo Huang40a71912019-10-11 11:13:39 -07003596 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08003597 b = (BINDING *)MALLOC(parser, sizeof(BINDING));
Haibo Huang40a71912019-10-11 11:13:39 -07003598 if (! b)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003599 return XML_ERROR_NO_MEMORY;
Sadaf Ebrahimif68f6852022-06-15 04:14:33 +00003600
3601 /* Detect and prevent integer overflow */
3602 if (len > INT_MAX - EXPAND_SPARE) {
3603 return XML_ERROR_NO_MEMORY;
3604 }
3605 /* Detect and prevent integer overflow.
3606 * The preprocessor guard addresses the "always false" warning
3607 * from -Wtype-limits on platforms where
3608 * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
3609#if UINT_MAX >= SIZE_MAX
3610 if ((unsigned)(len + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) {
3611 return XML_ERROR_NO_MEMORY;
3612 }
3613#endif
3614
Haibo Huang40a71912019-10-11 11:13:39 -07003615 b->uri
3616 = (XML_Char *)MALLOC(parser, sizeof(XML_Char) * (len + EXPAND_SPARE));
3617 if (! b->uri) {
Elliott Hughes72472942018-01-10 08:36:10 -08003618 FREE(parser, b);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003619 return XML_ERROR_NO_MEMORY;
3620 }
3621 b->uriAlloc = len + EXPAND_SPARE;
3622 }
3623 b->uriLen = len;
3624 memcpy(b->uri, uri, len * sizeof(XML_Char));
Elliott Hughes72472942018-01-10 08:36:10 -08003625 if (parser->m_namespaceSeparator)
3626 b->uri[len - 1] = parser->m_namespaceSeparator;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003627 b->prefix = prefix;
3628 b->attId = attId;
3629 b->prevPrefixBinding = prefix->binding;
3630 /* NULL binding when default namespace undeclared */
Elliott Hughes72472942018-01-10 08:36:10 -08003631 if (*uri == XML_T('\0') && prefix == &parser->m_dtd->defaultPrefix)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003632 prefix->binding = NULL;
3633 else
3634 prefix->binding = b;
3635 b->nextTagBinding = *bindingsPtr;
3636 *bindingsPtr = b;
3637 /* if attId == NULL then we are not starting a namespace scope */
Elliott Hughes72472942018-01-10 08:36:10 -08003638 if (attId && parser->m_startNamespaceDeclHandler)
3639 parser->m_startNamespaceDeclHandler(parser->m_handlerArg, prefix->name,
Haibo Huang40a71912019-10-11 11:13:39 -07003640 prefix->binding ? uri : 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003641 return XML_ERROR_NONE;
3642}
3643
3644/* The idea here is to avoid using stack for each CDATA section when
3645 the whole file is parsed with one call.
3646*/
3647static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07003648cdataSectionProcessor(XML_Parser parser, const char *start, const char *end,
3649 const char **endPtr) {
3650 enum XML_Error result
3651 = doCdataSection(parser, parser->m_encoding, &start, end, endPtr,
3652 (XML_Bool)! parser->m_parsingStatus.finalBuffer);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003653 if (result != XML_ERROR_NONE)
3654 return result;
3655 if (start) {
Haibo Huang40a71912019-10-11 11:13:39 -07003656 if (parser->m_parentParser) { /* we are parsing an external entity */
Elliott Hughes72472942018-01-10 08:36:10 -08003657 parser->m_processor = externalEntityContentProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003658 return externalEntityContentProcessor(parser, start, end, endPtr);
Haibo Huang40a71912019-10-11 11:13:39 -07003659 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08003660 parser->m_processor = contentProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003661 return contentProcessor(parser, start, end, endPtr);
3662 }
3663 }
3664 return result;
3665}
3666
3667/* startPtr gets set to non-null if the section is closed, and to null if
3668 the section is not yet closed.
3669*/
3670static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07003671doCdataSection(XML_Parser parser, const ENCODING *enc, const char **startPtr,
3672 const char *end, const char **nextPtr, XML_Bool haveMore) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003673 const char *s = *startPtr;
3674 const char **eventPP;
3675 const char **eventEndPP;
Elliott Hughes72472942018-01-10 08:36:10 -08003676 if (enc == parser->m_encoding) {
3677 eventPP = &parser->m_eventPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003678 *eventPP = s;
Elliott Hughes72472942018-01-10 08:36:10 -08003679 eventEndPP = &parser->m_eventEndPtr;
Haibo Huang40a71912019-10-11 11:13:39 -07003680 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08003681 eventPP = &(parser->m_openInternalEntities->internalEventPtr);
3682 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003683 }
3684 *eventPP = s;
3685 *startPtr = NULL;
3686
3687 for (;;) {
Haibo Huangd1a324a2020-10-28 22:19:36 -07003688 const char *next = s; /* in case of XML_TOK_NONE or XML_TOK_PARTIAL */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003689 int tok = XmlCdataSectionTok(enc, s, end, &next);
3690 *eventEndPP = next;
3691 switch (tok) {
3692 case XML_TOK_CDATA_SECT_CLOSE:
Elliott Hughes72472942018-01-10 08:36:10 -08003693 if (parser->m_endCdataSectionHandler)
3694 parser->m_endCdataSectionHandler(parser->m_handlerArg);
Haibo Huang40a71912019-10-11 11:13:39 -07003695 /* BEGIN disabled code */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003696 /* see comment under XML_TOK_CDATA_SECT_OPEN */
Haibo Huangfd5e81a2019-06-20 12:09:36 -07003697 else if (0 && parser->m_characterDataHandler)
Haibo Huang40a71912019-10-11 11:13:39 -07003698 parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf,
3699 0);
3700 /* END disabled code */
Elliott Hughes72472942018-01-10 08:36:10 -08003701 else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003702 reportDefault(parser, enc, s, next);
3703 *startPtr = next;
3704 *nextPtr = next;
Elliott Hughes72472942018-01-10 08:36:10 -08003705 if (parser->m_parsingStatus.parsing == XML_FINISHED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003706 return XML_ERROR_ABORTED;
3707 else
3708 return XML_ERROR_NONE;
3709 case XML_TOK_DATA_NEWLINE:
Elliott Hughes72472942018-01-10 08:36:10 -08003710 if (parser->m_characterDataHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003711 XML_Char c = 0xA;
Elliott Hughes72472942018-01-10 08:36:10 -08003712 parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
Haibo Huang40a71912019-10-11 11:13:39 -07003713 } else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003714 reportDefault(parser, enc, s, next);
3715 break;
Haibo Huang40a71912019-10-11 11:13:39 -07003716 case XML_TOK_DATA_CHARS: {
3717 XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler;
3718 if (charDataHandler) {
3719 if (MUST_CONVERT(enc, s)) {
3720 for (;;) {
3721 ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
3722 const enum XML_Convert_Result convert_res = XmlConvert(
3723 enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
3724 *eventEndPP = next;
3725 charDataHandler(parser->m_handlerArg, parser->m_dataBuf,
3726 (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
3727 if ((convert_res == XML_CONVERT_COMPLETED)
3728 || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
3729 break;
3730 *eventPP = s;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003731 }
Haibo Huang40a71912019-10-11 11:13:39 -07003732 } else
3733 charDataHandler(parser->m_handlerArg, (XML_Char *)s,
3734 (int)((XML_Char *)next - (XML_Char *)s));
3735 } else if (parser->m_defaultHandler)
3736 reportDefault(parser, enc, s, next);
3737 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003738 case XML_TOK_INVALID:
3739 *eventPP = next;
3740 return XML_ERROR_INVALID_TOKEN;
3741 case XML_TOK_PARTIAL_CHAR:
3742 if (haveMore) {
3743 *nextPtr = s;
3744 return XML_ERROR_NONE;
3745 }
3746 return XML_ERROR_PARTIAL_CHAR;
3747 case XML_TOK_PARTIAL:
3748 case XML_TOK_NONE:
3749 if (haveMore) {
3750 *nextPtr = s;
3751 return XML_ERROR_NONE;
3752 }
3753 return XML_ERROR_UNCLOSED_CDATA_SECTION;
3754 default:
Elliott Hughes72472942018-01-10 08:36:10 -08003755 /* Every token returned by XmlCdataSectionTok() has its own
3756 * explicit case, so this default case will never be executed.
3757 * We retain it as a safety net and exclude it from the coverage
3758 * statistics.
3759 *
3760 * LCOV_EXCL_START
Haibo Huang40a71912019-10-11 11:13:39 -07003761 */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003762 *eventPP = next;
3763 return XML_ERROR_UNEXPECTED_STATE;
Elliott Hughes72472942018-01-10 08:36:10 -08003764 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003765 }
3766
3767 *eventPP = s = next;
Elliott Hughes72472942018-01-10 08:36:10 -08003768 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003769 case XML_SUSPENDED:
3770 *nextPtr = next;
3771 return XML_ERROR_NONE;
3772 case XML_FINISHED:
3773 return XML_ERROR_ABORTED;
Haibo Huang40a71912019-10-11 11:13:39 -07003774 default:;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003775 }
3776 }
3777 /* not reached */
3778}
3779
3780#ifdef XML_DTD
3781
3782/* The idea here is to avoid using stack for each IGNORE section when
3783 the whole file is parsed with one call.
3784*/
3785static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07003786ignoreSectionProcessor(XML_Parser parser, const char *start, const char *end,
3787 const char **endPtr) {
3788 enum XML_Error result
3789 = doIgnoreSection(parser, parser->m_encoding, &start, end, endPtr,
3790 (XML_Bool)! parser->m_parsingStatus.finalBuffer);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003791 if (result != XML_ERROR_NONE)
3792 return result;
3793 if (start) {
Elliott Hughes72472942018-01-10 08:36:10 -08003794 parser->m_processor = prologProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003795 return prologProcessor(parser, start, end, endPtr);
3796 }
3797 return result;
3798}
3799
3800/* startPtr gets set to non-null is the section is closed, and to null
3801 if the section is not yet closed.
3802*/
3803static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07003804doIgnoreSection(XML_Parser parser, const ENCODING *enc, const char **startPtr,
3805 const char *end, const char **nextPtr, XML_Bool haveMore) {
Haibo Huangd1a324a2020-10-28 22:19:36 -07003806 const char *next = *startPtr; /* in case of XML_TOK_NONE or XML_TOK_PARTIAL */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003807 int tok;
3808 const char *s = *startPtr;
3809 const char **eventPP;
3810 const char **eventEndPP;
Elliott Hughes72472942018-01-10 08:36:10 -08003811 if (enc == parser->m_encoding) {
3812 eventPP = &parser->m_eventPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003813 *eventPP = s;
Elliott Hughes72472942018-01-10 08:36:10 -08003814 eventEndPP = &parser->m_eventEndPtr;
Haibo Huang40a71912019-10-11 11:13:39 -07003815 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08003816 /* It's not entirely clear, but it seems the following two lines
3817 * of code cannot be executed. The only occasions on which 'enc'
3818 * is not 'encoding' are when this function is called
3819 * from the internal entity processing, and IGNORE sections are an
3820 * error in internal entities.
3821 *
3822 * Since it really isn't clear that this is true, we keep the code
3823 * and just remove it from our coverage tests.
3824 *
3825 * LCOV_EXCL_START
3826 */
3827 eventPP = &(parser->m_openInternalEntities->internalEventPtr);
3828 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
3829 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003830 }
3831 *eventPP = s;
3832 *startPtr = NULL;
3833 tok = XmlIgnoreSectionTok(enc, s, end, &next);
3834 *eventEndPP = next;
3835 switch (tok) {
3836 case XML_TOK_IGNORE_SECT:
Elliott Hughes72472942018-01-10 08:36:10 -08003837 if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003838 reportDefault(parser, enc, s, next);
3839 *startPtr = next;
3840 *nextPtr = next;
Elliott Hughes72472942018-01-10 08:36:10 -08003841 if (parser->m_parsingStatus.parsing == XML_FINISHED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003842 return XML_ERROR_ABORTED;
3843 else
3844 return XML_ERROR_NONE;
3845 case XML_TOK_INVALID:
3846 *eventPP = next;
3847 return XML_ERROR_INVALID_TOKEN;
3848 case XML_TOK_PARTIAL_CHAR:
3849 if (haveMore) {
3850 *nextPtr = s;
3851 return XML_ERROR_NONE;
3852 }
3853 return XML_ERROR_PARTIAL_CHAR;
3854 case XML_TOK_PARTIAL:
3855 case XML_TOK_NONE:
3856 if (haveMore) {
3857 *nextPtr = s;
3858 return XML_ERROR_NONE;
3859 }
3860 return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
3861 default:
Elliott Hughes72472942018-01-10 08:36:10 -08003862 /* All of the tokens that XmlIgnoreSectionTok() returns have
3863 * explicit cases to handle them, so this default case is never
3864 * executed. We keep it as a safety net anyway, and remove it
3865 * from our test coverage statistics.
3866 *
3867 * LCOV_EXCL_START
3868 */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003869 *eventPP = next;
3870 return XML_ERROR_UNEXPECTED_STATE;
Elliott Hughes72472942018-01-10 08:36:10 -08003871 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003872 }
3873 /* not reached */
3874}
3875
3876#endif /* XML_DTD */
3877
3878static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07003879initializeEncoding(XML_Parser parser) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003880 const char *s;
3881#ifdef XML_UNICODE
3882 char encodingBuf[128];
Elliott Hughes72472942018-01-10 08:36:10 -08003883 /* See comments abount `protoclEncodingName` in parserInit() */
Haibo Huang40a71912019-10-11 11:13:39 -07003884 if (! parser->m_protocolEncodingName)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003885 s = NULL;
3886 else {
3887 int i;
Elliott Hughes72472942018-01-10 08:36:10 -08003888 for (i = 0; parser->m_protocolEncodingName[i]; i++) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003889 if (i == sizeof(encodingBuf) - 1
Elliott Hughes72472942018-01-10 08:36:10 -08003890 || (parser->m_protocolEncodingName[i] & ~0x7f) != 0) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003891 encodingBuf[0] = '\0';
3892 break;
3893 }
Elliott Hughes72472942018-01-10 08:36:10 -08003894 encodingBuf[i] = (char)parser->m_protocolEncodingName[i];
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003895 }
3896 encodingBuf[i] = '\0';
3897 s = encodingBuf;
3898 }
3899#else
Elliott Hughes72472942018-01-10 08:36:10 -08003900 s = parser->m_protocolEncodingName;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003901#endif
Haibo Huang40a71912019-10-11 11:13:39 -07003902 if ((parser->m_ns ? XmlInitEncodingNS : XmlInitEncoding)(
3903 &parser->m_initEncoding, &parser->m_encoding, s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003904 return XML_ERROR_NONE;
Elliott Hughes72472942018-01-10 08:36:10 -08003905 return handleUnknownEncoding(parser, parser->m_protocolEncodingName);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003906}
3907
3908static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07003909processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *s,
3910 const char *next) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003911 const char *encodingName = NULL;
3912 const XML_Char *storedEncName = NULL;
3913 const ENCODING *newEncoding = NULL;
3914 const char *version = NULL;
3915 const char *versionend;
3916 const XML_Char *storedversion = NULL;
3917 int standalone = -1;
Haibo Huang40a71912019-10-11 11:13:39 -07003918 if (! (parser->m_ns ? XmlParseXmlDeclNS : XmlParseXmlDecl)(
3919 isGeneralTextEntity, parser->m_encoding, s, next, &parser->m_eventPtr,
3920 &version, &versionend, &encodingName, &newEncoding, &standalone)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003921 if (isGeneralTextEntity)
3922 return XML_ERROR_TEXT_DECL;
3923 else
3924 return XML_ERROR_XML_DECL;
3925 }
Haibo Huang40a71912019-10-11 11:13:39 -07003926 if (! isGeneralTextEntity && standalone == 1) {
Elliott Hughes72472942018-01-10 08:36:10 -08003927 parser->m_dtd->standalone = XML_TRUE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003928#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07003929 if (parser->m_paramEntityParsing
3930 == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
Elliott Hughes72472942018-01-10 08:36:10 -08003931 parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003932#endif /* XML_DTD */
3933 }
Elliott Hughes72472942018-01-10 08:36:10 -08003934 if (parser->m_xmlDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003935 if (encodingName != NULL) {
Haibo Huang40a71912019-10-11 11:13:39 -07003936 storedEncName = poolStoreString(
3937 &parser->m_temp2Pool, parser->m_encoding, encodingName,
3938 encodingName + XmlNameLength(parser->m_encoding, encodingName));
3939 if (! storedEncName)
3940 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08003941 poolFinish(&parser->m_temp2Pool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003942 }
3943 if (version) {
Haibo Huang40a71912019-10-11 11:13:39 -07003944 storedversion
3945 = poolStoreString(&parser->m_temp2Pool, parser->m_encoding, version,
3946 versionend - parser->m_encoding->minBytesPerChar);
3947 if (! storedversion)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003948 return XML_ERROR_NO_MEMORY;
3949 }
Haibo Huang40a71912019-10-11 11:13:39 -07003950 parser->m_xmlDeclHandler(parser->m_handlerArg, storedversion, storedEncName,
3951 standalone);
3952 } else if (parser->m_defaultHandler)
Elliott Hughes72472942018-01-10 08:36:10 -08003953 reportDefault(parser, parser->m_encoding, s, next);
3954 if (parser->m_protocolEncodingName == NULL) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003955 if (newEncoding) {
Elliott Hughes72472942018-01-10 08:36:10 -08003956 /* Check that the specified encoding does not conflict with what
3957 * the parser has already deduced. Do we have the same number
3958 * of bytes in the smallest representation of a character? If
3959 * this is UTF-16, is it the same endianness?
3960 */
3961 if (newEncoding->minBytesPerChar != parser->m_encoding->minBytesPerChar
Haibo Huang40a71912019-10-11 11:13:39 -07003962 || (newEncoding->minBytesPerChar == 2
3963 && newEncoding != parser->m_encoding)) {
Elliott Hughes72472942018-01-10 08:36:10 -08003964 parser->m_eventPtr = encodingName;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003965 return XML_ERROR_INCORRECT_ENCODING;
3966 }
Elliott Hughes72472942018-01-10 08:36:10 -08003967 parser->m_encoding = newEncoding;
Haibo Huang40a71912019-10-11 11:13:39 -07003968 } else if (encodingName) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003969 enum XML_Error result;
Haibo Huang40a71912019-10-11 11:13:39 -07003970 if (! storedEncName) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003971 storedEncName = poolStoreString(
Haibo Huang40a71912019-10-11 11:13:39 -07003972 &parser->m_temp2Pool, parser->m_encoding, encodingName,
3973 encodingName + XmlNameLength(parser->m_encoding, encodingName));
3974 if (! storedEncName)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003975 return XML_ERROR_NO_MEMORY;
3976 }
3977 result = handleUnknownEncoding(parser, storedEncName);
Elliott Hughes72472942018-01-10 08:36:10 -08003978 poolClear(&parser->m_temp2Pool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003979 if (result == XML_ERROR_UNKNOWN_ENCODING)
Elliott Hughes72472942018-01-10 08:36:10 -08003980 parser->m_eventPtr = encodingName;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003981 return result;
3982 }
3983 }
3984
3985 if (storedEncName || storedversion)
Elliott Hughes72472942018-01-10 08:36:10 -08003986 poolClear(&parser->m_temp2Pool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003987
3988 return XML_ERROR_NONE;
3989}
3990
3991static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07003992handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) {
Elliott Hughes72472942018-01-10 08:36:10 -08003993 if (parser->m_unknownEncodingHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003994 XML_Encoding info;
3995 int i;
3996 for (i = 0; i < 256; i++)
3997 info.map[i] = -1;
3998 info.convert = NULL;
3999 info.data = NULL;
4000 info.release = NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07004001 if (parser->m_unknownEncodingHandler(parser->m_unknownEncodingHandlerData,
4002 encodingName, &info)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004003 ENCODING *enc;
Elliott Hughes72472942018-01-10 08:36:10 -08004004 parser->m_unknownEncodingMem = MALLOC(parser, XmlSizeOfUnknownEncoding());
Haibo Huang40a71912019-10-11 11:13:39 -07004005 if (! parser->m_unknownEncodingMem) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004006 if (info.release)
4007 info.release(info.data);
4008 return XML_ERROR_NO_MEMORY;
4009 }
Haibo Huang40a71912019-10-11 11:13:39 -07004010 enc = (parser->m_ns ? XmlInitUnknownEncodingNS : XmlInitUnknownEncoding)(
4011 parser->m_unknownEncodingMem, info.map, info.convert, info.data);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004012 if (enc) {
Elliott Hughes72472942018-01-10 08:36:10 -08004013 parser->m_unknownEncodingData = info.data;
4014 parser->m_unknownEncodingRelease = info.release;
4015 parser->m_encoding = enc;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004016 return XML_ERROR_NONE;
4017 }
4018 }
4019 if (info.release != NULL)
4020 info.release(info.data);
4021 }
4022 return XML_ERROR_UNKNOWN_ENCODING;
4023}
4024
4025static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07004026prologInitProcessor(XML_Parser parser, const char *s, const char *end,
4027 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004028 enum XML_Error result = initializeEncoding(parser);
4029 if (result != XML_ERROR_NONE)
4030 return result;
Elliott Hughes72472942018-01-10 08:36:10 -08004031 parser->m_processor = prologProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004032 return prologProcessor(parser, s, end, nextPtr);
4033}
4034
4035#ifdef XML_DTD
4036
4037static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07004038externalParEntInitProcessor(XML_Parser parser, const char *s, const char *end,
4039 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004040 enum XML_Error result = initializeEncoding(parser);
4041 if (result != XML_ERROR_NONE)
4042 return result;
4043
4044 /* we know now that XML_Parse(Buffer) has been called,
4045 so we consider the external parameter entity read */
Elliott Hughes72472942018-01-10 08:36:10 -08004046 parser->m_dtd->paramEntityRead = XML_TRUE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004047
Elliott Hughes72472942018-01-10 08:36:10 -08004048 if (parser->m_prologState.inEntityValue) {
4049 parser->m_processor = entityValueInitProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004050 return entityValueInitProcessor(parser, s, end, nextPtr);
Haibo Huang40a71912019-10-11 11:13:39 -07004051 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08004052 parser->m_processor = externalParEntProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004053 return externalParEntProcessor(parser, s, end, nextPtr);
4054 }
4055}
4056
4057static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07004058entityValueInitProcessor(XML_Parser parser, const char *s, const char *end,
4059 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004060 int tok;
4061 const char *start = s;
4062 const char *next = start;
Elliott Hughes72472942018-01-10 08:36:10 -08004063 parser->m_eventPtr = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004064
Elliott Hughes35e432d2012-09-09 14:23:38 -07004065 for (;;) {
Elliott Hughes72472942018-01-10 08:36:10 -08004066 tok = XmlPrologTok(parser->m_encoding, start, end, &next);
4067 parser->m_eventEndPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004068 if (tok <= 0) {
Haibo Huang40a71912019-10-11 11:13:39 -07004069 if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004070 *nextPtr = s;
4071 return XML_ERROR_NONE;
4072 }
4073 switch (tok) {
4074 case XML_TOK_INVALID:
4075 return XML_ERROR_INVALID_TOKEN;
4076 case XML_TOK_PARTIAL:
4077 return XML_ERROR_UNCLOSED_TOKEN;
4078 case XML_TOK_PARTIAL_CHAR:
4079 return XML_ERROR_PARTIAL_CHAR;
Haibo Huang40a71912019-10-11 11:13:39 -07004080 case XML_TOK_NONE: /* start == end */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004081 default:
4082 break;
4083 }
4084 /* found end of entity value - can store it now */
Elliott Hughes72472942018-01-10 08:36:10 -08004085 return storeEntityValue(parser, parser->m_encoding, s, end);
Haibo Huang40a71912019-10-11 11:13:39 -07004086 } else if (tok == XML_TOK_XML_DECL) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004087 enum XML_Error result;
4088 result = processXmlDecl(parser, 0, start, next);
4089 if (result != XML_ERROR_NONE)
4090 return result;
Haibo Huang40a71912019-10-11 11:13:39 -07004091 /* At this point, m_parsingStatus.parsing cannot be XML_SUSPENDED. For
4092 * that to happen, a parameter entity parsing handler must have attempted
4093 * to suspend the parser, which fails and raises an error. The parser can
4094 * be aborted, but can't be suspended.
Elliott Hughes72472942018-01-10 08:36:10 -08004095 */
4096 if (parser->m_parsingStatus.parsing == XML_FINISHED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004097 return XML_ERROR_ABORTED;
Elliott Hughes72472942018-01-10 08:36:10 -08004098 *nextPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004099 /* stop scanning for text declaration - we found one */
Elliott Hughes72472942018-01-10 08:36:10 -08004100 parser->m_processor = entityValueProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004101 return entityValueProcessor(parser, next, end, nextPtr);
4102 }
4103 /* If we are at the end of the buffer, this would cause XmlPrologTok to
4104 return XML_TOK_NONE on the next call, which would then cause the
4105 function to exit with *nextPtr set to s - that is what we want for other
4106 tokens, but not for the BOM - we would rather like to skip it;
4107 then, when this routine is entered the next time, XmlPrologTok will
4108 return XML_TOK_INVALID, since the BOM is still in the buffer
4109 */
Haibo Huang40a71912019-10-11 11:13:39 -07004110 else if (tok == XML_TOK_BOM && next == end
4111 && ! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004112 *nextPtr = next;
4113 return XML_ERROR_NONE;
4114 }
Elliott Hughes72472942018-01-10 08:36:10 -08004115 /* If we get this token, we have the start of what might be a
4116 normal tag, but not a declaration (i.e. it doesn't begin with
4117 "<!"). In a DTD context, that isn't legal.
4118 */
4119 else if (tok == XML_TOK_INSTANCE_START) {
4120 *nextPtr = next;
4121 return XML_ERROR_SYNTAX;
4122 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004123 start = next;
Elliott Hughes72472942018-01-10 08:36:10 -08004124 parser->m_eventPtr = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004125 }
4126}
4127
4128static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07004129externalParEntProcessor(XML_Parser parser, const char *s, const char *end,
4130 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004131 const char *next = s;
4132 int tok;
4133
Elliott Hughes72472942018-01-10 08:36:10 -08004134 tok = XmlPrologTok(parser->m_encoding, s, end, &next);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004135 if (tok <= 0) {
Haibo Huang40a71912019-10-11 11:13:39 -07004136 if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004137 *nextPtr = s;
4138 return XML_ERROR_NONE;
4139 }
4140 switch (tok) {
4141 case XML_TOK_INVALID:
4142 return XML_ERROR_INVALID_TOKEN;
4143 case XML_TOK_PARTIAL:
4144 return XML_ERROR_UNCLOSED_TOKEN;
4145 case XML_TOK_PARTIAL_CHAR:
4146 return XML_ERROR_PARTIAL_CHAR;
Haibo Huang40a71912019-10-11 11:13:39 -07004147 case XML_TOK_NONE: /* start == end */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004148 default:
4149 break;
4150 }
4151 }
4152 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
4153 However, when parsing an external subset, doProlog will not accept a BOM
4154 as valid, and report a syntax error, so we have to skip the BOM
4155 */
4156 else if (tok == XML_TOK_BOM) {
4157 s = next;
Elliott Hughes72472942018-01-10 08:36:10 -08004158 tok = XmlPrologTok(parser->m_encoding, s, end, &next);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004159 }
4160
Elliott Hughes72472942018-01-10 08:36:10 -08004161 parser->m_processor = prologProcessor;
Haibo Huang40a71912019-10-11 11:13:39 -07004162 return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
4163 (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004164}
4165
4166static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07004167entityValueProcessor(XML_Parser parser, const char *s, const char *end,
4168 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004169 const char *start = s;
4170 const char *next = s;
Elliott Hughes72472942018-01-10 08:36:10 -08004171 const ENCODING *enc = parser->m_encoding;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004172 int tok;
4173
4174 for (;;) {
4175 tok = XmlPrologTok(enc, start, end, &next);
4176 if (tok <= 0) {
Haibo Huang40a71912019-10-11 11:13:39 -07004177 if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004178 *nextPtr = s;
4179 return XML_ERROR_NONE;
4180 }
4181 switch (tok) {
4182 case XML_TOK_INVALID:
4183 return XML_ERROR_INVALID_TOKEN;
4184 case XML_TOK_PARTIAL:
4185 return XML_ERROR_UNCLOSED_TOKEN;
4186 case XML_TOK_PARTIAL_CHAR:
4187 return XML_ERROR_PARTIAL_CHAR;
Haibo Huang40a71912019-10-11 11:13:39 -07004188 case XML_TOK_NONE: /* start == end */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004189 default:
4190 break;
4191 }
4192 /* found end of entity value - can store it now */
4193 return storeEntityValue(parser, enc, s, end);
4194 }
4195 start = next;
4196 }
4197}
4198
4199#endif /* XML_DTD */
4200
4201static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07004202prologProcessor(XML_Parser parser, const char *s, const char *end,
4203 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004204 const char *next = s;
Elliott Hughes72472942018-01-10 08:36:10 -08004205 int tok = XmlPrologTok(parser->m_encoding, s, end, &next);
Haibo Huang40a71912019-10-11 11:13:39 -07004206 return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
4207 (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004208}
4209
4210static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07004211doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
4212 int tok, const char *next, const char **nextPtr, XML_Bool haveMore,
4213 XML_Bool allowClosingDoctype) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004214#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07004215 static const XML_Char externalSubsetName[] = {ASCII_HASH, '\0'};
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004216#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07004217 static const XML_Char atypeCDATA[]
4218 = {ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'};
4219 static const XML_Char atypeID[] = {ASCII_I, ASCII_D, '\0'};
4220 static const XML_Char atypeIDREF[]
4221 = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0'};
4222 static const XML_Char atypeIDREFS[]
4223 = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0'};
4224 static const XML_Char atypeENTITY[]
4225 = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0'};
4226 static const XML_Char atypeENTITIES[]
4227 = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T,
4228 ASCII_I, ASCII_E, ASCII_S, '\0'};
4229 static const XML_Char atypeNMTOKEN[]
4230 = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0'};
4231 static const XML_Char atypeNMTOKENS[]
4232 = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K,
4233 ASCII_E, ASCII_N, ASCII_S, '\0'};
4234 static const XML_Char notationPrefix[]
4235 = {ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T,
4236 ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0'};
4237 static const XML_Char enumValueSep[] = {ASCII_PIPE, '\0'};
4238 static const XML_Char enumValueStart[] = {ASCII_LPAREN, '\0'};
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004239
4240 /* save one level of indirection */
Haibo Huang40a71912019-10-11 11:13:39 -07004241 DTD *const dtd = parser->m_dtd;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004242
4243 const char **eventPP;
4244 const char **eventEndPP;
4245 enum XML_Content_Quant quant;
4246
Elliott Hughes72472942018-01-10 08:36:10 -08004247 if (enc == parser->m_encoding) {
4248 eventPP = &parser->m_eventPtr;
4249 eventEndPP = &parser->m_eventEndPtr;
Haibo Huang40a71912019-10-11 11:13:39 -07004250 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08004251 eventPP = &(parser->m_openInternalEntities->internalEventPtr);
4252 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004253 }
4254
4255 for (;;) {
4256 int role;
4257 XML_Bool handleDefault = XML_TRUE;
4258 *eventPP = s;
4259 *eventEndPP = next;
4260 if (tok <= 0) {
4261 if (haveMore && tok != XML_TOK_INVALID) {
4262 *nextPtr = s;
4263 return XML_ERROR_NONE;
4264 }
4265 switch (tok) {
4266 case XML_TOK_INVALID:
4267 *eventPP = next;
4268 return XML_ERROR_INVALID_TOKEN;
4269 case XML_TOK_PARTIAL:
4270 return XML_ERROR_UNCLOSED_TOKEN;
4271 case XML_TOK_PARTIAL_CHAR:
4272 return XML_ERROR_PARTIAL_CHAR;
Elliott Hughes35e432d2012-09-09 14:23:38 -07004273 case -XML_TOK_PROLOG_S:
4274 tok = -tok;
4275 break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004276 case XML_TOK_NONE:
4277#ifdef XML_DTD
4278 /* for internal PE NOT referenced between declarations */
Haibo Huang40a71912019-10-11 11:13:39 -07004279 if (enc != parser->m_encoding
4280 && ! parser->m_openInternalEntities->betweenDecl) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004281 *nextPtr = s;
4282 return XML_ERROR_NONE;
4283 }
4284 /* WFC: PE Between Declarations - must check that PE contains
4285 complete markup, not only for external PEs, but also for
4286 internal PEs if the reference occurs between declarations.
4287 */
Elliott Hughes72472942018-01-10 08:36:10 -08004288 if (parser->m_isParamEntity || enc != parser->m_encoding) {
4289 if (XmlTokenRole(&parser->m_prologState, XML_TOK_NONE, end, end, enc)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004290 == XML_ROLE_ERROR)
4291 return XML_ERROR_INCOMPLETE_PE;
4292 *nextPtr = s;
4293 return XML_ERROR_NONE;
4294 }
4295#endif /* XML_DTD */
4296 return XML_ERROR_NO_ELEMENTS;
4297 default:
4298 tok = -tok;
4299 next = end;
4300 break;
4301 }
4302 }
Elliott Hughes72472942018-01-10 08:36:10 -08004303 role = XmlTokenRole(&parser->m_prologState, tok, s, next, enc);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004304 switch (role) {
Haibo Huang40a71912019-10-11 11:13:39 -07004305 case XML_ROLE_XML_DECL: {
4306 enum XML_Error result = processXmlDecl(parser, 0, s, next);
4307 if (result != XML_ERROR_NONE)
4308 return result;
4309 enc = parser->m_encoding;
4310 handleDefault = XML_FALSE;
4311 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004312 case XML_ROLE_DOCTYPE_NAME:
Elliott Hughes72472942018-01-10 08:36:10 -08004313 if (parser->m_startDoctypeDeclHandler) {
Haibo Huang40a71912019-10-11 11:13:39 -07004314 parser->m_doctypeName
4315 = poolStoreString(&parser->m_tempPool, enc, s, next);
4316 if (! parser->m_doctypeName)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004317 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004318 poolFinish(&parser->m_tempPool);
4319 parser->m_doctypePubid = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004320 handleDefault = XML_FALSE;
4321 }
Elliott Hughes72472942018-01-10 08:36:10 -08004322 parser->m_doctypeSysid = NULL; /* always initialize to NULL */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004323 break;
4324 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
Elliott Hughes72472942018-01-10 08:36:10 -08004325 if (parser->m_startDoctypeDeclHandler) {
Haibo Huang40a71912019-10-11 11:13:39 -07004326 parser->m_startDoctypeDeclHandler(
4327 parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid,
4328 parser->m_doctypePubid, 1);
Elliott Hughes72472942018-01-10 08:36:10 -08004329 parser->m_doctypeName = NULL;
4330 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004331 handleDefault = XML_FALSE;
4332 }
4333 break;
4334#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07004335 case XML_ROLE_TEXT_DECL: {
4336 enum XML_Error result = processXmlDecl(parser, 1, s, next);
4337 if (result != XML_ERROR_NONE)
4338 return result;
4339 enc = parser->m_encoding;
4340 handleDefault = XML_FALSE;
4341 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004342#endif /* XML_DTD */
4343 case XML_ROLE_DOCTYPE_PUBLIC_ID:
4344#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08004345 parser->m_useForeignDTD = XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07004346 parser->m_declEntity = (ENTITY *)lookup(
4347 parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY));
4348 if (! parser->m_declEntity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004349 return XML_ERROR_NO_MEMORY;
4350#endif /* XML_DTD */
4351 dtd->hasParamEntityRefs = XML_TRUE;
Elliott Hughes72472942018-01-10 08:36:10 -08004352 if (parser->m_startDoctypeDeclHandler) {
Elliott Hughes35e432d2012-09-09 14:23:38 -07004353 XML_Char *pubId;
Haibo Huang40a71912019-10-11 11:13:39 -07004354 if (! XmlIsPublicId(enc, s, next, eventPP))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004355 return XML_ERROR_PUBLICID;
Elliott Hughes72472942018-01-10 08:36:10 -08004356 pubId = poolStoreString(&parser->m_tempPool, enc,
Elliott Hughes35e432d2012-09-09 14:23:38 -07004357 s + enc->minBytesPerChar,
4358 next - enc->minBytesPerChar);
Haibo Huang40a71912019-10-11 11:13:39 -07004359 if (! pubId)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004360 return XML_ERROR_NO_MEMORY;
Elliott Hughes35e432d2012-09-09 14:23:38 -07004361 normalizePublicId(pubId);
Elliott Hughes72472942018-01-10 08:36:10 -08004362 poolFinish(&parser->m_tempPool);
4363 parser->m_doctypePubid = pubId;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004364 handleDefault = XML_FALSE;
4365 goto alreadyChecked;
4366 }
4367 /* fall through */
4368 case XML_ROLE_ENTITY_PUBLIC_ID:
Haibo Huang40a71912019-10-11 11:13:39 -07004369 if (! XmlIsPublicId(enc, s, next, eventPP))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004370 return XML_ERROR_PUBLICID;
4371 alreadyChecked:
Elliott Hughes72472942018-01-10 08:36:10 -08004372 if (dtd->keepProcessing && parser->m_declEntity) {
Haibo Huang40a71912019-10-11 11:13:39 -07004373 XML_Char *tem
4374 = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
4375 next - enc->minBytesPerChar);
4376 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004377 return XML_ERROR_NO_MEMORY;
4378 normalizePublicId(tem);
Elliott Hughes72472942018-01-10 08:36:10 -08004379 parser->m_declEntity->publicId = tem;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004380 poolFinish(&dtd->pool);
Elliott Hughes72472942018-01-10 08:36:10 -08004381 /* Don't suppress the default handler if we fell through from
4382 * the XML_ROLE_DOCTYPE_PUBLIC_ID case.
4383 */
4384 if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_PUBLIC_ID)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004385 handleDefault = XML_FALSE;
4386 }
4387 break;
4388 case XML_ROLE_DOCTYPE_CLOSE:
Haibo Huang40a71912019-10-11 11:13:39 -07004389 if (allowClosingDoctype != XML_TRUE) {
4390 /* Must not close doctype from within expanded parameter entities */
4391 return XML_ERROR_INVALID_TOKEN;
4392 }
4393
Elliott Hughes72472942018-01-10 08:36:10 -08004394 if (parser->m_doctypeName) {
Haibo Huang40a71912019-10-11 11:13:39 -07004395 parser->m_startDoctypeDeclHandler(
4396 parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid,
4397 parser->m_doctypePubid, 0);
Elliott Hughes72472942018-01-10 08:36:10 -08004398 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004399 handleDefault = XML_FALSE;
4400 }
Elliott Hughes72472942018-01-10 08:36:10 -08004401 /* parser->m_doctypeSysid will be non-NULL in the case of a previous
4402 XML_ROLE_DOCTYPE_SYSTEM_ID, even if parser->m_startDoctypeDeclHandler
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004403 was not set, indicating an external subset
4404 */
4405#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08004406 if (parser->m_doctypeSysid || parser->m_useForeignDTD) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004407 XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
4408 dtd->hasParamEntityRefs = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07004409 if (parser->m_paramEntityParsing
4410 && parser->m_externalEntityRefHandler) {
4411 ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
4412 externalSubsetName, sizeof(ENTITY));
4413 if (! entity) {
Elliott Hughes72472942018-01-10 08:36:10 -08004414 /* The external subset name "#" will have already been
4415 * inserted into the hash table at the start of the
4416 * external entity parsing, so no allocation will happen
4417 * and lookup() cannot fail.
4418 */
4419 return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */
4420 }
4421 if (parser->m_useForeignDTD)
4422 entity->base = parser->m_curBase;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004423 dtd->paramEntityRead = XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07004424 if (! parser->m_externalEntityRefHandler(
4425 parser->m_externalEntityRefHandlerArg, 0, entity->base,
4426 entity->systemId, entity->publicId))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004427 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4428 if (dtd->paramEntityRead) {
Haibo Huang40a71912019-10-11 11:13:39 -07004429 if (! dtd->standalone && parser->m_notStandaloneHandler
4430 && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004431 return XML_ERROR_NOT_STANDALONE;
4432 }
4433 /* if we didn't read the foreign DTD then this means that there
4434 is no external subset and we must reset dtd->hasParamEntityRefs
4435 */
Haibo Huang40a71912019-10-11 11:13:39 -07004436 else if (! parser->m_doctypeSysid)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004437 dtd->hasParamEntityRefs = hadParamEntityRefs;
4438 /* end of DTD - no need to update dtd->keepProcessing */
4439 }
Elliott Hughes72472942018-01-10 08:36:10 -08004440 parser->m_useForeignDTD = XML_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004441 }
4442#endif /* XML_DTD */
Elliott Hughes72472942018-01-10 08:36:10 -08004443 if (parser->m_endDoctypeDeclHandler) {
4444 parser->m_endDoctypeDeclHandler(parser->m_handlerArg);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004445 handleDefault = XML_FALSE;
4446 }
4447 break;
4448 case XML_ROLE_INSTANCE_START:
4449#ifdef XML_DTD
4450 /* if there is no DOCTYPE declaration then now is the
4451 last chance to read the foreign DTD
4452 */
Elliott Hughes72472942018-01-10 08:36:10 -08004453 if (parser->m_useForeignDTD) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004454 XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
4455 dtd->hasParamEntityRefs = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07004456 if (parser->m_paramEntityParsing
4457 && parser->m_externalEntityRefHandler) {
Elliott Hughes35e432d2012-09-09 14:23:38 -07004458 ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
Haibo Huang40a71912019-10-11 11:13:39 -07004459 externalSubsetName, sizeof(ENTITY));
4460 if (! entity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004461 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004462 entity->base = parser->m_curBase;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004463 dtd->paramEntityRead = XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07004464 if (! parser->m_externalEntityRefHandler(
4465 parser->m_externalEntityRefHandlerArg, 0, entity->base,
4466 entity->systemId, entity->publicId))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004467 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4468 if (dtd->paramEntityRead) {
Haibo Huang40a71912019-10-11 11:13:39 -07004469 if (! dtd->standalone && parser->m_notStandaloneHandler
4470 && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004471 return XML_ERROR_NOT_STANDALONE;
4472 }
4473 /* if we didn't read the foreign DTD then this means that there
4474 is no external subset and we must reset dtd->hasParamEntityRefs
4475 */
4476 else
4477 dtd->hasParamEntityRefs = hadParamEntityRefs;
4478 /* end of DTD - no need to update dtd->keepProcessing */
4479 }
4480 }
4481#endif /* XML_DTD */
Elliott Hughes72472942018-01-10 08:36:10 -08004482 parser->m_processor = contentProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004483 return contentProcessor(parser, s, end, nextPtr);
4484 case XML_ROLE_ATTLIST_ELEMENT_NAME:
Elliott Hughes72472942018-01-10 08:36:10 -08004485 parser->m_declElementType = getElementType(parser, enc, s, next);
Haibo Huang40a71912019-10-11 11:13:39 -07004486 if (! parser->m_declElementType)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004487 return XML_ERROR_NO_MEMORY;
4488 goto checkAttListDeclHandler;
4489 case XML_ROLE_ATTRIBUTE_NAME:
Elliott Hughes72472942018-01-10 08:36:10 -08004490 parser->m_declAttributeId = getAttributeId(parser, enc, s, next);
Haibo Huang40a71912019-10-11 11:13:39 -07004491 if (! parser->m_declAttributeId)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004492 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004493 parser->m_declAttributeIsCdata = XML_FALSE;
4494 parser->m_declAttributeType = NULL;
4495 parser->m_declAttributeIsId = XML_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004496 goto checkAttListDeclHandler;
4497 case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
Elliott Hughes72472942018-01-10 08:36:10 -08004498 parser->m_declAttributeIsCdata = XML_TRUE;
4499 parser->m_declAttributeType = atypeCDATA;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004500 goto checkAttListDeclHandler;
4501 case XML_ROLE_ATTRIBUTE_TYPE_ID:
Elliott Hughes72472942018-01-10 08:36:10 -08004502 parser->m_declAttributeIsId = XML_TRUE;
4503 parser->m_declAttributeType = atypeID;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004504 goto checkAttListDeclHandler;
4505 case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
Elliott Hughes72472942018-01-10 08:36:10 -08004506 parser->m_declAttributeType = atypeIDREF;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004507 goto checkAttListDeclHandler;
4508 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
Elliott Hughes72472942018-01-10 08:36:10 -08004509 parser->m_declAttributeType = atypeIDREFS;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004510 goto checkAttListDeclHandler;
4511 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
Elliott Hughes72472942018-01-10 08:36:10 -08004512 parser->m_declAttributeType = atypeENTITY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004513 goto checkAttListDeclHandler;
4514 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
Elliott Hughes72472942018-01-10 08:36:10 -08004515 parser->m_declAttributeType = atypeENTITIES;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004516 goto checkAttListDeclHandler;
4517 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
Elliott Hughes72472942018-01-10 08:36:10 -08004518 parser->m_declAttributeType = atypeNMTOKEN;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004519 goto checkAttListDeclHandler;
4520 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
Elliott Hughes72472942018-01-10 08:36:10 -08004521 parser->m_declAttributeType = atypeNMTOKENS;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004522 checkAttListDeclHandler:
Elliott Hughes72472942018-01-10 08:36:10 -08004523 if (dtd->keepProcessing && parser->m_attlistDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004524 handleDefault = XML_FALSE;
4525 break;
4526 case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
4527 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
Elliott Hughes72472942018-01-10 08:36:10 -08004528 if (dtd->keepProcessing && parser->m_attlistDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004529 const XML_Char *prefix;
Elliott Hughes72472942018-01-10 08:36:10 -08004530 if (parser->m_declAttributeType) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004531 prefix = enumValueSep;
Haibo Huang40a71912019-10-11 11:13:39 -07004532 } else {
4533 prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE ? notationPrefix
4534 : enumValueStart);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004535 }
Haibo Huang40a71912019-10-11 11:13:39 -07004536 if (! poolAppendString(&parser->m_tempPool, prefix))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004537 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07004538 if (! poolAppend(&parser->m_tempPool, enc, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004539 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004540 parser->m_declAttributeType = parser->m_tempPool.start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004541 handleDefault = XML_FALSE;
4542 }
4543 break;
4544 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
4545 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
4546 if (dtd->keepProcessing) {
Haibo Huang40a71912019-10-11 11:13:39 -07004547 if (! defineAttribute(parser->m_declElementType,
4548 parser->m_declAttributeId,
4549 parser->m_declAttributeIsCdata,
4550 parser->m_declAttributeIsId, 0, parser))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004551 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004552 if (parser->m_attlistDeclHandler && parser->m_declAttributeType) {
4553 if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN)
4554 || (*parser->m_declAttributeType == XML_T(ASCII_N)
4555 && parser->m_declAttributeType[1] == XML_T(ASCII_O))) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004556 /* Enumerated or Notation type */
Haibo Huang40a71912019-10-11 11:13:39 -07004557 if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN))
4558 || ! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004559 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004560 parser->m_declAttributeType = parser->m_tempPool.start;
4561 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004562 }
4563 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004564 parser->m_attlistDeclHandler(
4565 parser->m_handlerArg, parser->m_declElementType->name,
4566 parser->m_declAttributeId->name, parser->m_declAttributeType, 0,
4567 role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
Elliott Hughes72472942018-01-10 08:36:10 -08004568 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004569 handleDefault = XML_FALSE;
4570 }
4571 }
4572 break;
4573 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
4574 case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
4575 if (dtd->keepProcessing) {
4576 const XML_Char *attVal;
Haibo Huang40a71912019-10-11 11:13:39 -07004577 enum XML_Error result = storeAttributeValue(
4578 parser, enc, parser->m_declAttributeIsCdata,
4579 s + enc->minBytesPerChar, next - enc->minBytesPerChar, &dtd->pool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004580 if (result)
4581 return result;
4582 attVal = poolStart(&dtd->pool);
4583 poolFinish(&dtd->pool);
4584 /* ID attributes aren't allowed to have a default */
Haibo Huang40a71912019-10-11 11:13:39 -07004585 if (! defineAttribute(
4586 parser->m_declElementType, parser->m_declAttributeId,
4587 parser->m_declAttributeIsCdata, XML_FALSE, attVal, parser))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004588 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004589 if (parser->m_attlistDeclHandler && parser->m_declAttributeType) {
4590 if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN)
4591 || (*parser->m_declAttributeType == XML_T(ASCII_N)
4592 && parser->m_declAttributeType[1] == XML_T(ASCII_O))) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004593 /* Enumerated or Notation type */
Haibo Huang40a71912019-10-11 11:13:39 -07004594 if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN))
4595 || ! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004596 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004597 parser->m_declAttributeType = parser->m_tempPool.start;
4598 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004599 }
4600 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004601 parser->m_attlistDeclHandler(
4602 parser->m_handlerArg, parser->m_declElementType->name,
4603 parser->m_declAttributeId->name, parser->m_declAttributeType,
4604 attVal, role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
Elliott Hughes72472942018-01-10 08:36:10 -08004605 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004606 handleDefault = XML_FALSE;
4607 }
4608 }
4609 break;
4610 case XML_ROLE_ENTITY_VALUE:
4611 if (dtd->keepProcessing) {
Haibo Huang40a71912019-10-11 11:13:39 -07004612 enum XML_Error result = storeEntityValue(
4613 parser, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar);
Elliott Hughes72472942018-01-10 08:36:10 -08004614 if (parser->m_declEntity) {
4615 parser->m_declEntity->textPtr = poolStart(&dtd->entityValuePool);
Haibo Huang40a71912019-10-11 11:13:39 -07004616 parser->m_declEntity->textLen
4617 = (int)(poolLength(&dtd->entityValuePool));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004618 poolFinish(&dtd->entityValuePool);
Elliott Hughes72472942018-01-10 08:36:10 -08004619 if (parser->m_entityDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004620 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004621 parser->m_entityDeclHandler(
4622 parser->m_handlerArg, parser->m_declEntity->name,
4623 parser->m_declEntity->is_param, parser->m_declEntity->textPtr,
4624 parser->m_declEntity->textLen, parser->m_curBase, 0, 0, 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004625 handleDefault = XML_FALSE;
4626 }
Haibo Huang40a71912019-10-11 11:13:39 -07004627 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004628 poolDiscard(&dtd->entityValuePool);
4629 if (result != XML_ERROR_NONE)
4630 return result;
4631 }
4632 break;
4633 case XML_ROLE_DOCTYPE_SYSTEM_ID:
4634#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08004635 parser->m_useForeignDTD = XML_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004636#endif /* XML_DTD */
4637 dtd->hasParamEntityRefs = XML_TRUE;
Elliott Hughes72472942018-01-10 08:36:10 -08004638 if (parser->m_startDoctypeDeclHandler) {
4639 parser->m_doctypeSysid = poolStoreString(&parser->m_tempPool, enc,
Haibo Huang40a71912019-10-11 11:13:39 -07004640 s + enc->minBytesPerChar,
4641 next - enc->minBytesPerChar);
Elliott Hughes72472942018-01-10 08:36:10 -08004642 if (parser->m_doctypeSysid == NULL)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004643 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004644 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004645 handleDefault = XML_FALSE;
4646 }
4647#ifdef XML_DTD
4648 else
Elliott Hughes72472942018-01-10 08:36:10 -08004649 /* use externalSubsetName to make parser->m_doctypeSysid non-NULL
4650 for the case where no parser->m_startDoctypeDeclHandler is set */
4651 parser->m_doctypeSysid = externalSubsetName;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004652#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07004653 if (! dtd->standalone
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004654#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07004655 && ! parser->m_paramEntityParsing
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004656#endif /* XML_DTD */
Elliott Hughes72472942018-01-10 08:36:10 -08004657 && parser->m_notStandaloneHandler
Haibo Huang40a71912019-10-11 11:13:39 -07004658 && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004659 return XML_ERROR_NOT_STANDALONE;
4660#ifndef XML_DTD
4661 break;
Haibo Huang40a71912019-10-11 11:13:39 -07004662#else /* XML_DTD */
4663 if (! parser->m_declEntity) {
4664 parser->m_declEntity = (ENTITY *)lookup(
4665 parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY));
4666 if (! parser->m_declEntity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004667 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004668 parser->m_declEntity->publicId = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004669 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004670#endif /* XML_DTD */
Elliott Hughesaaec48e2018-08-16 16:29:01 -07004671 /* fall through */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004672 case XML_ROLE_ENTITY_SYSTEM_ID:
Elliott Hughes72472942018-01-10 08:36:10 -08004673 if (dtd->keepProcessing && parser->m_declEntity) {
Haibo Huang40a71912019-10-11 11:13:39 -07004674 parser->m_declEntity->systemId
4675 = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
4676 next - enc->minBytesPerChar);
4677 if (! parser->m_declEntity->systemId)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004678 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004679 parser->m_declEntity->base = parser->m_curBase;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004680 poolFinish(&dtd->pool);
Elliott Hughes72472942018-01-10 08:36:10 -08004681 /* Don't suppress the default handler if we fell through from
4682 * the XML_ROLE_DOCTYPE_SYSTEM_ID case.
4683 */
4684 if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_SYSTEM_ID)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004685 handleDefault = XML_FALSE;
4686 }
4687 break;
4688 case XML_ROLE_ENTITY_COMPLETE:
Haibo Huang40a71912019-10-11 11:13:39 -07004689 if (dtd->keepProcessing && parser->m_declEntity
4690 && parser->m_entityDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004691 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004692 parser->m_entityDeclHandler(
4693 parser->m_handlerArg, parser->m_declEntity->name,
4694 parser->m_declEntity->is_param, 0, 0, parser->m_declEntity->base,
4695 parser->m_declEntity->systemId, parser->m_declEntity->publicId, 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004696 handleDefault = XML_FALSE;
4697 }
4698 break;
4699 case XML_ROLE_ENTITY_NOTATION_NAME:
Elliott Hughes72472942018-01-10 08:36:10 -08004700 if (dtd->keepProcessing && parser->m_declEntity) {
Haibo Huang40a71912019-10-11 11:13:39 -07004701 parser->m_declEntity->notation
4702 = poolStoreString(&dtd->pool, enc, s, next);
4703 if (! parser->m_declEntity->notation)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004704 return XML_ERROR_NO_MEMORY;
4705 poolFinish(&dtd->pool);
Elliott Hughes72472942018-01-10 08:36:10 -08004706 if (parser->m_unparsedEntityDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004707 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004708 parser->m_unparsedEntityDeclHandler(
4709 parser->m_handlerArg, parser->m_declEntity->name,
4710 parser->m_declEntity->base, parser->m_declEntity->systemId,
4711 parser->m_declEntity->publicId, parser->m_declEntity->notation);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004712 handleDefault = XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07004713 } else if (parser->m_entityDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004714 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004715 parser->m_entityDeclHandler(
4716 parser->m_handlerArg, parser->m_declEntity->name, 0, 0, 0,
4717 parser->m_declEntity->base, parser->m_declEntity->systemId,
4718 parser->m_declEntity->publicId, parser->m_declEntity->notation);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004719 handleDefault = XML_FALSE;
4720 }
4721 }
4722 break;
Haibo Huang40a71912019-10-11 11:13:39 -07004723 case XML_ROLE_GENERAL_ENTITY_NAME: {
4724 if (XmlPredefinedEntityName(enc, s, next)) {
4725 parser->m_declEntity = NULL;
4726 break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004727 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004728 if (dtd->keepProcessing) {
4729 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
Haibo Huang40a71912019-10-11 11:13:39 -07004730 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004731 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07004732 parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities,
4733 name, sizeof(ENTITY));
4734 if (! parser->m_declEntity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004735 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004736 if (parser->m_declEntity->name != name) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004737 poolDiscard(&dtd->pool);
Elliott Hughes72472942018-01-10 08:36:10 -08004738 parser->m_declEntity = NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07004739 } else {
4740 poolFinish(&dtd->pool);
4741 parser->m_declEntity->publicId = NULL;
4742 parser->m_declEntity->is_param = XML_FALSE;
4743 /* if we have a parent parser or are reading an internal parameter
4744 entity, then the entity declaration is not considered "internal"
4745 */
4746 parser->m_declEntity->is_internal
4747 = ! (parser->m_parentParser || parser->m_openInternalEntities);
4748 if (parser->m_entityDeclHandler)
4749 handleDefault = XML_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004750 }
Haibo Huang40a71912019-10-11 11:13:39 -07004751 } else {
4752 poolDiscard(&dtd->pool);
4753 parser->m_declEntity = NULL;
4754 }
4755 } break;
4756 case XML_ROLE_PARAM_ENTITY_NAME:
4757#ifdef XML_DTD
4758 if (dtd->keepProcessing) {
4759 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
4760 if (! name)
4761 return XML_ERROR_NO_MEMORY;
4762 parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities,
4763 name, sizeof(ENTITY));
4764 if (! parser->m_declEntity)
4765 return XML_ERROR_NO_MEMORY;
4766 if (parser->m_declEntity->name != name) {
4767 poolDiscard(&dtd->pool);
4768 parser->m_declEntity = NULL;
4769 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004770 poolFinish(&dtd->pool);
Elliott Hughes72472942018-01-10 08:36:10 -08004771 parser->m_declEntity->publicId = NULL;
4772 parser->m_declEntity->is_param = XML_TRUE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004773 /* if we have a parent parser or are reading an internal parameter
4774 entity, then the entity declaration is not considered "internal"
4775 */
Haibo Huang40a71912019-10-11 11:13:39 -07004776 parser->m_declEntity->is_internal
4777 = ! (parser->m_parentParser || parser->m_openInternalEntities);
Elliott Hughes72472942018-01-10 08:36:10 -08004778 if (parser->m_entityDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004779 handleDefault = XML_FALSE;
4780 }
Haibo Huang40a71912019-10-11 11:13:39 -07004781 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004782 poolDiscard(&dtd->pool);
Elliott Hughes72472942018-01-10 08:36:10 -08004783 parser->m_declEntity = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004784 }
Haibo Huang40a71912019-10-11 11:13:39 -07004785#else /* not XML_DTD */
Elliott Hughes72472942018-01-10 08:36:10 -08004786 parser->m_declEntity = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004787#endif /* XML_DTD */
4788 break;
4789 case XML_ROLE_NOTATION_NAME:
Elliott Hughes72472942018-01-10 08:36:10 -08004790 parser->m_declNotationPublicId = NULL;
4791 parser->m_declNotationName = NULL;
4792 if (parser->m_notationDeclHandler) {
Haibo Huang40a71912019-10-11 11:13:39 -07004793 parser->m_declNotationName
4794 = poolStoreString(&parser->m_tempPool, enc, s, next);
4795 if (! parser->m_declNotationName)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004796 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004797 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004798 handleDefault = XML_FALSE;
4799 }
4800 break;
4801 case XML_ROLE_NOTATION_PUBLIC_ID:
Haibo Huang40a71912019-10-11 11:13:39 -07004802 if (! XmlIsPublicId(enc, s, next, eventPP))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004803 return XML_ERROR_PUBLICID;
Haibo Huang40a71912019-10-11 11:13:39 -07004804 if (parser
4805 ->m_declNotationName) { /* means m_notationDeclHandler != NULL */
4806 XML_Char *tem = poolStoreString(&parser->m_tempPool, enc,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004807 s + enc->minBytesPerChar,
4808 next - enc->minBytesPerChar);
Haibo Huang40a71912019-10-11 11:13:39 -07004809 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004810 return XML_ERROR_NO_MEMORY;
4811 normalizePublicId(tem);
Elliott Hughes72472942018-01-10 08:36:10 -08004812 parser->m_declNotationPublicId = tem;
4813 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004814 handleDefault = XML_FALSE;
4815 }
4816 break;
4817 case XML_ROLE_NOTATION_SYSTEM_ID:
Elliott Hughes72472942018-01-10 08:36:10 -08004818 if (parser->m_declNotationName && parser->m_notationDeclHandler) {
Haibo Huang40a71912019-10-11 11:13:39 -07004819 const XML_Char *systemId = poolStoreString(&parser->m_tempPool, enc,
4820 s + enc->minBytesPerChar,
4821 next - enc->minBytesPerChar);
4822 if (! systemId)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004823 return XML_ERROR_NO_MEMORY;
4824 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004825 parser->m_notationDeclHandler(
4826 parser->m_handlerArg, parser->m_declNotationName, parser->m_curBase,
4827 systemId, parser->m_declNotationPublicId);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004828 handleDefault = XML_FALSE;
4829 }
Elliott Hughes72472942018-01-10 08:36:10 -08004830 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004831 break;
4832 case XML_ROLE_NOTATION_NO_SYSTEM_ID:
Elliott Hughes72472942018-01-10 08:36:10 -08004833 if (parser->m_declNotationPublicId && parser->m_notationDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004834 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004835 parser->m_notationDeclHandler(
4836 parser->m_handlerArg, parser->m_declNotationName, parser->m_curBase,
4837 0, parser->m_declNotationPublicId);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004838 handleDefault = XML_FALSE;
4839 }
Elliott Hughes72472942018-01-10 08:36:10 -08004840 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004841 break;
4842 case XML_ROLE_ERROR:
4843 switch (tok) {
4844 case XML_TOK_PARAM_ENTITY_REF:
4845 /* PE references in internal subset are
Elliott Hughes35e432d2012-09-09 14:23:38 -07004846 not allowed within declarations. */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004847 return XML_ERROR_PARAM_ENTITY_REF;
4848 case XML_TOK_XML_DECL:
4849 return XML_ERROR_MISPLACED_XML_PI;
4850 default:
4851 return XML_ERROR_SYNTAX;
4852 }
4853#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07004854 case XML_ROLE_IGNORE_SECT: {
4855 enum XML_Error result;
4856 if (parser->m_defaultHandler)
4857 reportDefault(parser, enc, s, next);
4858 handleDefault = XML_FALSE;
4859 result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
4860 if (result != XML_ERROR_NONE)
4861 return result;
4862 else if (! next) {
4863 parser->m_processor = ignoreSectionProcessor;
4864 return result;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004865 }
Haibo Huang40a71912019-10-11 11:13:39 -07004866 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004867#endif /* XML_DTD */
4868 case XML_ROLE_GROUP_OPEN:
Elliott Hughes72472942018-01-10 08:36:10 -08004869 if (parser->m_prologState.level >= parser->m_groupSize) {
4870 if (parser->m_groupSize) {
Haibo Huang40a71912019-10-11 11:13:39 -07004871 {
4872 char *const new_connector = (char *)REALLOC(
4873 parser, parser->m_groupConnector, parser->m_groupSize *= 2);
4874 if (new_connector == NULL) {
4875 parser->m_groupSize /= 2;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004876 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07004877 }
4878 parser->m_groupConnector = new_connector;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004879 }
Haibo Huang40a71912019-10-11 11:13:39 -07004880
4881 if (dtd->scaffIndex) {
4882 int *const new_scaff_index = (int *)REALLOC(
4883 parser, dtd->scaffIndex, parser->m_groupSize * sizeof(int));
4884 if (new_scaff_index == NULL)
4885 return XML_ERROR_NO_MEMORY;
4886 dtd->scaffIndex = new_scaff_index;
4887 }
4888 } else {
4889 parser->m_groupConnector
4890 = (char *)MALLOC(parser, parser->m_groupSize = 32);
4891 if (! parser->m_groupConnector) {
Elliott Hughes72472942018-01-10 08:36:10 -08004892 parser->m_groupSize = 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004893 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004894 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004895 }
4896 }
Elliott Hughes72472942018-01-10 08:36:10 -08004897 parser->m_groupConnector[parser->m_prologState.level] = 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004898 if (dtd->in_eldecl) {
4899 int myindex = nextScaffoldPart(parser);
4900 if (myindex < 0)
4901 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07004902 assert(dtd->scaffIndex != NULL);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004903 dtd->scaffIndex[dtd->scaffLevel] = myindex;
4904 dtd->scaffLevel++;
4905 dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
Elliott Hughes72472942018-01-10 08:36:10 -08004906 if (parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004907 handleDefault = XML_FALSE;
4908 }
4909 break;
4910 case XML_ROLE_GROUP_SEQUENCE:
Elliott Hughes72472942018-01-10 08:36:10 -08004911 if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_PIPE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004912 return XML_ERROR_SYNTAX;
Elliott Hughes72472942018-01-10 08:36:10 -08004913 parser->m_groupConnector[parser->m_prologState.level] = ASCII_COMMA;
4914 if (dtd->in_eldecl && parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004915 handleDefault = XML_FALSE;
4916 break;
4917 case XML_ROLE_GROUP_CHOICE:
Elliott Hughes72472942018-01-10 08:36:10 -08004918 if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_COMMA)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004919 return XML_ERROR_SYNTAX;
4920 if (dtd->in_eldecl
Haibo Huang40a71912019-10-11 11:13:39 -07004921 && ! parser->m_groupConnector[parser->m_prologState.level]
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004922 && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
Haibo Huang40a71912019-10-11 11:13:39 -07004923 != XML_CTYPE_MIXED)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004924 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4925 = XML_CTYPE_CHOICE;
Elliott Hughes72472942018-01-10 08:36:10 -08004926 if (parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004927 handleDefault = XML_FALSE;
4928 }
Elliott Hughes72472942018-01-10 08:36:10 -08004929 parser->m_groupConnector[parser->m_prologState.level] = ASCII_PIPE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004930 break;
4931 case XML_ROLE_PARAM_ENTITY_REF:
4932#ifdef XML_DTD
4933 case XML_ROLE_INNER_PARAM_ENTITY_REF:
4934 dtd->hasParamEntityRefs = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07004935 if (! parser->m_paramEntityParsing)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004936 dtd->keepProcessing = dtd->standalone;
4937 else {
4938 const XML_Char *name;
4939 ENTITY *entity;
Haibo Huang40a71912019-10-11 11:13:39 -07004940 name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
4941 next - enc->minBytesPerChar);
4942 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004943 return XML_ERROR_NO_MEMORY;
Elliott Hughes35e432d2012-09-09 14:23:38 -07004944 entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004945 poolDiscard(&dtd->pool);
4946 /* first, determine if a check for an existing declaration is needed;
4947 if yes, check that the entity exists, and that it is internal,
4948 otherwise call the skipped entity handler
4949 */
Haibo Huang40a71912019-10-11 11:13:39 -07004950 if (parser->m_prologState.documentEntity
4951 && (dtd->standalone ? ! parser->m_openInternalEntities
4952 : ! dtd->hasParamEntityRefs)) {
4953 if (! entity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004954 return XML_ERROR_UNDEFINED_ENTITY;
Haibo Huang40a71912019-10-11 11:13:39 -07004955 else if (! entity->is_internal) {
Elliott Hughes72472942018-01-10 08:36:10 -08004956 /* It's hard to exhaustively search the code to be sure,
4957 * but there doesn't seem to be a way of executing the
4958 * following line. There are two cases:
4959 *
4960 * If 'standalone' is false, the DTD must have no
4961 * parameter entities or we wouldn't have passed the outer
4962 * 'if' statement. That measn the only entity in the hash
4963 * table is the external subset name "#" which cannot be
4964 * given as a parameter entity name in XML syntax, so the
4965 * lookup must have returned NULL and we don't even reach
4966 * the test for an internal entity.
4967 *
4968 * If 'standalone' is true, it does not seem to be
4969 * possible to create entities taking this code path that
4970 * are not internal entities, so fail the test above.
4971 *
4972 * Because this analysis is very uncertain, the code is
4973 * being left in place and merely removed from the
4974 * coverage test statistics.
4975 */
4976 return XML_ERROR_ENTITY_DECLARED_IN_PE; /* LCOV_EXCL_LINE */
4977 }
Haibo Huang40a71912019-10-11 11:13:39 -07004978 } else if (! entity) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004979 dtd->keepProcessing = dtd->standalone;
4980 /* cannot report skipped entities in declarations */
Haibo Huang40a71912019-10-11 11:13:39 -07004981 if ((role == XML_ROLE_PARAM_ENTITY_REF)
4982 && parser->m_skippedEntityHandler) {
Elliott Hughes72472942018-01-10 08:36:10 -08004983 parser->m_skippedEntityHandler(parser->m_handlerArg, name, 1);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004984 handleDefault = XML_FALSE;
4985 }
4986 break;
4987 }
4988 if (entity->open)
4989 return XML_ERROR_RECURSIVE_ENTITY_REF;
4990 if (entity->textPtr) {
4991 enum XML_Error result;
Haibo Huang40a71912019-10-11 11:13:39 -07004992 XML_Bool betweenDecl
4993 = (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004994 result = processInternalEntity(parser, entity, betweenDecl);
4995 if (result != XML_ERROR_NONE)
4996 return result;
4997 handleDefault = XML_FALSE;
4998 break;
4999 }
Elliott Hughes72472942018-01-10 08:36:10 -08005000 if (parser->m_externalEntityRefHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005001 dtd->paramEntityRead = XML_FALSE;
5002 entity->open = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07005003 if (! parser->m_externalEntityRefHandler(
5004 parser->m_externalEntityRefHandlerArg, 0, entity->base,
5005 entity->systemId, entity->publicId)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005006 entity->open = XML_FALSE;
5007 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
5008 }
5009 entity->open = XML_FALSE;
5010 handleDefault = XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07005011 if (! dtd->paramEntityRead) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005012 dtd->keepProcessing = dtd->standalone;
5013 break;
5014 }
Haibo Huang40a71912019-10-11 11:13:39 -07005015 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005016 dtd->keepProcessing = dtd->standalone;
5017 break;
5018 }
5019 }
5020#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07005021 if (! dtd->standalone && parser->m_notStandaloneHandler
5022 && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005023 return XML_ERROR_NOT_STANDALONE;
5024 break;
5025
Haibo Huang40a71912019-10-11 11:13:39 -07005026 /* Element declaration stuff */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005027
5028 case XML_ROLE_ELEMENT_NAME:
Elliott Hughes72472942018-01-10 08:36:10 -08005029 if (parser->m_elementDeclHandler) {
5030 parser->m_declElementType = getElementType(parser, enc, s, next);
Haibo Huang40a71912019-10-11 11:13:39 -07005031 if (! parser->m_declElementType)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005032 return XML_ERROR_NO_MEMORY;
5033 dtd->scaffLevel = 0;
5034 dtd->scaffCount = 0;
5035 dtd->in_eldecl = XML_TRUE;
5036 handleDefault = XML_FALSE;
5037 }
5038 break;
5039
5040 case XML_ROLE_CONTENT_ANY:
5041 case XML_ROLE_CONTENT_EMPTY:
5042 if (dtd->in_eldecl) {
Elliott Hughes72472942018-01-10 08:36:10 -08005043 if (parser->m_elementDeclHandler) {
Haibo Huang40a71912019-10-11 11:13:39 -07005044 XML_Content *content
5045 = (XML_Content *)MALLOC(parser, sizeof(XML_Content));
5046 if (! content)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005047 return XML_ERROR_NO_MEMORY;
5048 content->quant = XML_CQUANT_NONE;
5049 content->name = NULL;
5050 content->numchildren = 0;
5051 content->children = NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07005052 content->type = ((role == XML_ROLE_CONTENT_ANY) ? XML_CTYPE_ANY
5053 : XML_CTYPE_EMPTY);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005054 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07005055 parser->m_elementDeclHandler(
5056 parser->m_handlerArg, parser->m_declElementType->name, content);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005057 handleDefault = XML_FALSE;
5058 }
5059 dtd->in_eldecl = XML_FALSE;
5060 }
5061 break;
5062
5063 case XML_ROLE_CONTENT_PCDATA:
5064 if (dtd->in_eldecl) {
5065 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
5066 = XML_CTYPE_MIXED;
Elliott Hughes72472942018-01-10 08:36:10 -08005067 if (parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005068 handleDefault = XML_FALSE;
5069 }
5070 break;
5071
5072 case XML_ROLE_CONTENT_ELEMENT:
5073 quant = XML_CQUANT_NONE;
5074 goto elementContent;
5075 case XML_ROLE_CONTENT_ELEMENT_OPT:
5076 quant = XML_CQUANT_OPT;
5077 goto elementContent;
5078 case XML_ROLE_CONTENT_ELEMENT_REP:
5079 quant = XML_CQUANT_REP;
5080 goto elementContent;
5081 case XML_ROLE_CONTENT_ELEMENT_PLUS:
5082 quant = XML_CQUANT_PLUS;
5083 elementContent:
5084 if (dtd->in_eldecl) {
5085 ELEMENT_TYPE *el;
5086 const XML_Char *name;
Sadaf Ebrahimifcfab022022-06-03 03:40:21 +00005087 size_t nameLen;
Haibo Huang40a71912019-10-11 11:13:39 -07005088 const char *nxt
5089 = (quant == XML_CQUANT_NONE ? next : next - enc->minBytesPerChar);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005090 int myindex = nextScaffoldPart(parser);
5091 if (myindex < 0)
5092 return XML_ERROR_NO_MEMORY;
5093 dtd->scaffold[myindex].type = XML_CTYPE_NAME;
5094 dtd->scaffold[myindex].quant = quant;
5095 el = getElementType(parser, enc, s, nxt);
Haibo Huang40a71912019-10-11 11:13:39 -07005096 if (! el)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005097 return XML_ERROR_NO_MEMORY;
5098 name = el->name;
5099 dtd->scaffold[myindex].name = name;
5100 nameLen = 0;
Haibo Huang40a71912019-10-11 11:13:39 -07005101 for (; name[nameLen++];)
5102 ;
Sadaf Ebrahimifcfab022022-06-03 03:40:21 +00005103
5104 /* Detect and prevent integer overflow */
5105 if (nameLen > UINT_MAX - dtd->contentStringLen) {
5106 return XML_ERROR_NO_MEMORY;
5107 }
5108
5109 dtd->contentStringLen += (unsigned)nameLen;
Elliott Hughes72472942018-01-10 08:36:10 -08005110 if (parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005111 handleDefault = XML_FALSE;
5112 }
5113 break;
5114
5115 case XML_ROLE_GROUP_CLOSE:
5116 quant = XML_CQUANT_NONE;
5117 goto closeGroup;
5118 case XML_ROLE_GROUP_CLOSE_OPT:
5119 quant = XML_CQUANT_OPT;
5120 goto closeGroup;
5121 case XML_ROLE_GROUP_CLOSE_REP:
5122 quant = XML_CQUANT_REP;
5123 goto closeGroup;
5124 case XML_ROLE_GROUP_CLOSE_PLUS:
5125 quant = XML_CQUANT_PLUS;
5126 closeGroup:
5127 if (dtd->in_eldecl) {
Elliott Hughes72472942018-01-10 08:36:10 -08005128 if (parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005129 handleDefault = XML_FALSE;
5130 dtd->scaffLevel--;
5131 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
5132 if (dtd->scaffLevel == 0) {
Haibo Huang40a71912019-10-11 11:13:39 -07005133 if (! handleDefault) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005134 XML_Content *model = build_model(parser);
Haibo Huang40a71912019-10-11 11:13:39 -07005135 if (! model)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005136 return XML_ERROR_NO_MEMORY;
5137 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07005138 parser->m_elementDeclHandler(
5139 parser->m_handlerArg, parser->m_declElementType->name, model);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005140 }
5141 dtd->in_eldecl = XML_FALSE;
5142 dtd->contentStringLen = 0;
5143 }
5144 }
5145 break;
5146 /* End element declaration stuff */
5147
5148 case XML_ROLE_PI:
Haibo Huang40a71912019-10-11 11:13:39 -07005149 if (! reportProcessingInstruction(parser, enc, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005150 return XML_ERROR_NO_MEMORY;
5151 handleDefault = XML_FALSE;
5152 break;
5153 case XML_ROLE_COMMENT:
Haibo Huang40a71912019-10-11 11:13:39 -07005154 if (! reportComment(parser, enc, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005155 return XML_ERROR_NO_MEMORY;
5156 handleDefault = XML_FALSE;
5157 break;
5158 case XML_ROLE_NONE:
5159 switch (tok) {
5160 case XML_TOK_BOM:
5161 handleDefault = XML_FALSE;
5162 break;
5163 }
5164 break;
5165 case XML_ROLE_DOCTYPE_NONE:
Elliott Hughes72472942018-01-10 08:36:10 -08005166 if (parser->m_startDoctypeDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005167 handleDefault = XML_FALSE;
5168 break;
5169 case XML_ROLE_ENTITY_NONE:
Elliott Hughes72472942018-01-10 08:36:10 -08005170 if (dtd->keepProcessing && parser->m_entityDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005171 handleDefault = XML_FALSE;
5172 break;
5173 case XML_ROLE_NOTATION_NONE:
Elliott Hughes72472942018-01-10 08:36:10 -08005174 if (parser->m_notationDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005175 handleDefault = XML_FALSE;
5176 break;
5177 case XML_ROLE_ATTLIST_NONE:
Elliott Hughes72472942018-01-10 08:36:10 -08005178 if (dtd->keepProcessing && parser->m_attlistDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005179 handleDefault = XML_FALSE;
5180 break;
5181 case XML_ROLE_ELEMENT_NONE:
Elliott Hughes72472942018-01-10 08:36:10 -08005182 if (parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005183 handleDefault = XML_FALSE;
5184 break;
5185 } /* end of big switch */
5186
Elliott Hughes72472942018-01-10 08:36:10 -08005187 if (handleDefault && parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005188 reportDefault(parser, enc, s, next);
5189
Elliott Hughes72472942018-01-10 08:36:10 -08005190 switch (parser->m_parsingStatus.parsing) {
Elliott Hughes35e432d2012-09-09 14:23:38 -07005191 case XML_SUSPENDED:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005192 *nextPtr = next;
5193 return XML_ERROR_NONE;
5194 case XML_FINISHED:
5195 return XML_ERROR_ABORTED;
5196 default:
5197 s = next;
5198 tok = XmlPrologTok(enc, s, end, &next);
5199 }
5200 }
5201 /* not reached */
5202}
5203
5204static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07005205epilogProcessor(XML_Parser parser, const char *s, const char *end,
5206 const char **nextPtr) {
Elliott Hughes72472942018-01-10 08:36:10 -08005207 parser->m_processor = epilogProcessor;
5208 parser->m_eventPtr = s;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005209 for (;;) {
5210 const char *next = NULL;
Elliott Hughes72472942018-01-10 08:36:10 -08005211 int tok = XmlPrologTok(parser->m_encoding, s, end, &next);
5212 parser->m_eventEndPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005213 switch (tok) {
5214 /* report partial linebreak - it might be the last token */
5215 case -XML_TOK_PROLOG_S:
Elliott Hughes72472942018-01-10 08:36:10 -08005216 if (parser->m_defaultHandler) {
5217 reportDefault(parser, parser->m_encoding, s, next);
5218 if (parser->m_parsingStatus.parsing == XML_FINISHED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005219 return XML_ERROR_ABORTED;
5220 }
5221 *nextPtr = next;
5222 return XML_ERROR_NONE;
5223 case XML_TOK_NONE:
5224 *nextPtr = s;
5225 return XML_ERROR_NONE;
5226 case XML_TOK_PROLOG_S:
Elliott Hughes72472942018-01-10 08:36:10 -08005227 if (parser->m_defaultHandler)
5228 reportDefault(parser, parser->m_encoding, s, next);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005229 break;
5230 case XML_TOK_PI:
Haibo Huang40a71912019-10-11 11:13:39 -07005231 if (! reportProcessingInstruction(parser, parser->m_encoding, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005232 return XML_ERROR_NO_MEMORY;
5233 break;
5234 case XML_TOK_COMMENT:
Haibo Huang40a71912019-10-11 11:13:39 -07005235 if (! reportComment(parser, parser->m_encoding, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005236 return XML_ERROR_NO_MEMORY;
5237 break;
5238 case XML_TOK_INVALID:
Elliott Hughes72472942018-01-10 08:36:10 -08005239 parser->m_eventPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005240 return XML_ERROR_INVALID_TOKEN;
5241 case XML_TOK_PARTIAL:
Haibo Huang40a71912019-10-11 11:13:39 -07005242 if (! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005243 *nextPtr = s;
5244 return XML_ERROR_NONE;
5245 }
5246 return XML_ERROR_UNCLOSED_TOKEN;
5247 case XML_TOK_PARTIAL_CHAR:
Haibo Huang40a71912019-10-11 11:13:39 -07005248 if (! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005249 *nextPtr = s;
5250 return XML_ERROR_NONE;
5251 }
5252 return XML_ERROR_PARTIAL_CHAR;
5253 default:
5254 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
5255 }
Elliott Hughes72472942018-01-10 08:36:10 -08005256 parser->m_eventPtr = s = next;
5257 switch (parser->m_parsingStatus.parsing) {
Elliott Hughes35e432d2012-09-09 14:23:38 -07005258 case XML_SUSPENDED:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005259 *nextPtr = next;
5260 return XML_ERROR_NONE;
5261 case XML_FINISHED:
5262 return XML_ERROR_ABORTED;
Haibo Huang40a71912019-10-11 11:13:39 -07005263 default:;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005264 }
5265 }
5266}
5267
5268static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07005269processInternalEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005270 const char *textStart, *textEnd;
5271 const char *next;
5272 enum XML_Error result;
5273 OPEN_INTERNAL_ENTITY *openEntity;
5274
Elliott Hughes72472942018-01-10 08:36:10 -08005275 if (parser->m_freeInternalEntities) {
5276 openEntity = parser->m_freeInternalEntities;
5277 parser->m_freeInternalEntities = openEntity->next;
Haibo Huang40a71912019-10-11 11:13:39 -07005278 } else {
5279 openEntity
5280 = (OPEN_INTERNAL_ENTITY *)MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY));
5281 if (! openEntity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005282 return XML_ERROR_NO_MEMORY;
5283 }
5284 entity->open = XML_TRUE;
5285 entity->processed = 0;
Elliott Hughes72472942018-01-10 08:36:10 -08005286 openEntity->next = parser->m_openInternalEntities;
5287 parser->m_openInternalEntities = openEntity;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005288 openEntity->entity = entity;
Elliott Hughes72472942018-01-10 08:36:10 -08005289 openEntity->startTagLevel = parser->m_tagLevel;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005290 openEntity->betweenDecl = betweenDecl;
5291 openEntity->internalEventPtr = NULL;
5292 openEntity->internalEventEndPtr = NULL;
Haibo Huangd1a324a2020-10-28 22:19:36 -07005293 textStart = (const char *)entity->textPtr;
5294 textEnd = (const char *)(entity->textPtr + entity->textLen);
Elliott Hughes72472942018-01-10 08:36:10 -08005295 /* Set a safe default value in case 'next' does not get set */
5296 next = textStart;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005297
5298#ifdef XML_DTD
5299 if (entity->is_param) {
Haibo Huang40a71912019-10-11 11:13:39 -07005300 int tok
5301 = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
5302 result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
5303 tok, next, &next, XML_FALSE, XML_FALSE);
5304 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005305#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07005306 result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding,
5307 textStart, textEnd, &next, XML_FALSE);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005308
5309 if (result == XML_ERROR_NONE) {
Elliott Hughes72472942018-01-10 08:36:10 -08005310 if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005311 entity->processed = (int)(next - textStart);
Elliott Hughes72472942018-01-10 08:36:10 -08005312 parser->m_processor = internalEntityProcessor;
Haibo Huang40a71912019-10-11 11:13:39 -07005313 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005314 entity->open = XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08005315 parser->m_openInternalEntities = openEntity->next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005316 /* put openEntity back in list of free instances */
Elliott Hughes72472942018-01-10 08:36:10 -08005317 openEntity->next = parser->m_freeInternalEntities;
5318 parser->m_freeInternalEntities = openEntity;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005319 }
5320 }
5321 return result;
5322}
5323
5324static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07005325internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
5326 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005327 ENTITY *entity;
5328 const char *textStart, *textEnd;
5329 const char *next;
5330 enum XML_Error result;
Elliott Hughes72472942018-01-10 08:36:10 -08005331 OPEN_INTERNAL_ENTITY *openEntity = parser->m_openInternalEntities;
Haibo Huang40a71912019-10-11 11:13:39 -07005332 if (! openEntity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005333 return XML_ERROR_UNEXPECTED_STATE;
5334
5335 entity = openEntity->entity;
Haibo Huangd1a324a2020-10-28 22:19:36 -07005336 textStart = ((const char *)entity->textPtr) + entity->processed;
5337 textEnd = (const char *)(entity->textPtr + entity->textLen);
Elliott Hughes72472942018-01-10 08:36:10 -08005338 /* Set a safe default value in case 'next' does not get set */
5339 next = textStart;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005340
5341#ifdef XML_DTD
5342 if (entity->is_param) {
Haibo Huang40a71912019-10-11 11:13:39 -07005343 int tok
5344 = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
5345 result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
5346 tok, next, &next, XML_FALSE, XML_TRUE);
5347 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005348#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07005349 result = doContent(parser, openEntity->startTagLevel,
5350 parser->m_internalEncoding, textStart, textEnd, &next,
5351 XML_FALSE);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005352
5353 if (result != XML_ERROR_NONE)
5354 return result;
Haibo Huang40a71912019-10-11 11:13:39 -07005355 else if (textEnd != next
5356 && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
Haibo Huangd1a324a2020-10-28 22:19:36 -07005357 entity->processed = (int)(next - (const char *)entity->textPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005358 return result;
Haibo Huang40a71912019-10-11 11:13:39 -07005359 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005360 entity->open = XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08005361 parser->m_openInternalEntities = openEntity->next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005362 /* put openEntity back in list of free instances */
Elliott Hughes72472942018-01-10 08:36:10 -08005363 openEntity->next = parser->m_freeInternalEntities;
5364 parser->m_freeInternalEntities = openEntity;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005365 }
5366
5367#ifdef XML_DTD
5368 if (entity->is_param) {
5369 int tok;
Elliott Hughes72472942018-01-10 08:36:10 -08005370 parser->m_processor = prologProcessor;
5371 tok = XmlPrologTok(parser->m_encoding, s, end, &next);
5372 return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
Haibo Huang40a71912019-10-11 11:13:39 -07005373 (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE);
5374 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005375#endif /* XML_DTD */
5376 {
Elliott Hughes72472942018-01-10 08:36:10 -08005377 parser->m_processor = contentProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005378 /* see externalEntityContentProcessor vs contentProcessor */
Haibo Huang40a71912019-10-11 11:13:39 -07005379 return doContent(parser, parser->m_parentParser ? 1 : 0, parser->m_encoding,
5380 s, end, nextPtr,
5381 (XML_Bool)! parser->m_parsingStatus.finalBuffer);
Elliott Hughes35e432d2012-09-09 14:23:38 -07005382 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005383}
5384
5385static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07005386errorProcessor(XML_Parser parser, const char *s, const char *end,
5387 const char **nextPtr) {
5388 UNUSED_P(s);
5389 UNUSED_P(end);
5390 UNUSED_P(nextPtr);
Elliott Hughes72472942018-01-10 08:36:10 -08005391 return parser->m_errorCode;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005392}
5393
5394static enum XML_Error
5395storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
Haibo Huang40a71912019-10-11 11:13:39 -07005396 const char *ptr, const char *end, STRING_POOL *pool) {
5397 enum XML_Error result
5398 = appendAttributeValue(parser, enc, isCdata, ptr, end, pool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005399 if (result)
5400 return result;
Haibo Huang40a71912019-10-11 11:13:39 -07005401 if (! isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005402 poolChop(pool);
Haibo Huang40a71912019-10-11 11:13:39 -07005403 if (! poolAppendChar(pool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005404 return XML_ERROR_NO_MEMORY;
5405 return XML_ERROR_NONE;
5406}
5407
5408static enum XML_Error
5409appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
Haibo Huang40a71912019-10-11 11:13:39 -07005410 const char *ptr, const char *end, STRING_POOL *pool) {
5411 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005412 for (;;) {
5413 const char *next;
5414 int tok = XmlAttributeValueTok(enc, ptr, end, &next);
5415 switch (tok) {
5416 case XML_TOK_NONE:
5417 return XML_ERROR_NONE;
5418 case XML_TOK_INVALID:
Elliott Hughes72472942018-01-10 08:36:10 -08005419 if (enc == parser->m_encoding)
5420 parser->m_eventPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005421 return XML_ERROR_INVALID_TOKEN;
5422 case XML_TOK_PARTIAL:
Elliott Hughes72472942018-01-10 08:36:10 -08005423 if (enc == parser->m_encoding)
5424 parser->m_eventPtr = ptr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005425 return XML_ERROR_INVALID_TOKEN;
Haibo Huang40a71912019-10-11 11:13:39 -07005426 case XML_TOK_CHAR_REF: {
5427 XML_Char buf[XML_ENCODE_MAX];
5428 int i;
5429 int n = XmlCharRefNumber(enc, ptr);
5430 if (n < 0) {
5431 if (enc == parser->m_encoding)
5432 parser->m_eventPtr = ptr;
5433 return XML_ERROR_BAD_CHAR_REF;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005434 }
Haibo Huang40a71912019-10-11 11:13:39 -07005435 if (! isCdata && n == 0x20 /* space */
5436 && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
5437 break;
5438 n = XmlEncode(n, (ICHAR *)buf);
5439 /* The XmlEncode() functions can never return 0 here. That
5440 * error return happens if the code point passed in is either
5441 * negative or greater than or equal to 0x110000. The
5442 * XmlCharRefNumber() functions will all return a number
5443 * strictly less than 0x110000 or a negative value if an error
5444 * occurred. The negative value is intercepted above, so
5445 * XmlEncode() is never passed a value it might return an
5446 * error for.
5447 */
5448 for (i = 0; i < n; i++) {
5449 if (! poolAppendChar(pool, buf[i]))
5450 return XML_ERROR_NO_MEMORY;
5451 }
5452 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005453 case XML_TOK_DATA_CHARS:
Haibo Huang40a71912019-10-11 11:13:39 -07005454 if (! poolAppend(pool, enc, ptr, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005455 return XML_ERROR_NO_MEMORY;
5456 break;
5457 case XML_TOK_TRAILING_CR:
5458 next = ptr + enc->minBytesPerChar;
5459 /* fall through */
5460 case XML_TOK_ATTRIBUTE_VALUE_S:
5461 case XML_TOK_DATA_NEWLINE:
Haibo Huang40a71912019-10-11 11:13:39 -07005462 if (! isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005463 break;
Haibo Huang40a71912019-10-11 11:13:39 -07005464 if (! poolAppendChar(pool, 0x20))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005465 return XML_ERROR_NO_MEMORY;
5466 break;
Haibo Huang40a71912019-10-11 11:13:39 -07005467 case XML_TOK_ENTITY_REF: {
5468 const XML_Char *name;
5469 ENTITY *entity;
5470 char checkEntityDecl;
5471 XML_Char ch = (XML_Char)XmlPredefinedEntityName(
5472 enc, ptr + enc->minBytesPerChar, next - enc->minBytesPerChar);
5473 if (ch) {
5474 if (! poolAppendChar(pool, ch))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005475 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07005476 break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005477 }
Haibo Huang40a71912019-10-11 11:13:39 -07005478 name = poolStoreString(&parser->m_temp2Pool, enc,
5479 ptr + enc->minBytesPerChar,
5480 next - enc->minBytesPerChar);
5481 if (! name)
5482 return XML_ERROR_NO_MEMORY;
5483 entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
5484 poolDiscard(&parser->m_temp2Pool);
5485 /* First, determine if a check for an existing declaration is needed;
5486 if yes, check that the entity exists, and that it is internal.
5487 */
5488 if (pool == &dtd->pool) /* are we called from prolog? */
5489 checkEntityDecl =
5490#ifdef XML_DTD
5491 parser->m_prologState.documentEntity &&
5492#endif /* XML_DTD */
5493 (dtd->standalone ? ! parser->m_openInternalEntities
5494 : ! dtd->hasParamEntityRefs);
5495 else /* if (pool == &parser->m_tempPool): we are called from content */
5496 checkEntityDecl = ! dtd->hasParamEntityRefs || dtd->standalone;
5497 if (checkEntityDecl) {
5498 if (! entity)
5499 return XML_ERROR_UNDEFINED_ENTITY;
5500 else if (! entity->is_internal)
5501 return XML_ERROR_ENTITY_DECLARED_IN_PE;
5502 } else if (! entity) {
5503 /* Cannot report skipped entity here - see comments on
5504 parser->m_skippedEntityHandler.
5505 if (parser->m_skippedEntityHandler)
5506 parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
5507 */
5508 /* Cannot call the default handler because this would be
5509 out of sync with the call to the startElementHandler.
5510 if ((pool == &parser->m_tempPool) && parser->m_defaultHandler)
5511 reportDefault(parser, enc, ptr, next);
5512 */
5513 break;
5514 }
5515 if (entity->open) {
5516 if (enc == parser->m_encoding) {
5517 /* It does not appear that this line can be executed.
5518 *
5519 * The "if (entity->open)" check catches recursive entity
5520 * definitions. In order to be called with an open
5521 * entity, it must have gone through this code before and
5522 * been through the recursive call to
5523 * appendAttributeValue() some lines below. That call
5524 * sets the local encoding ("enc") to the parser's
5525 * internal encoding (internal_utf8 or internal_utf16),
5526 * which can never be the same as the principle encoding.
5527 * It doesn't appear there is another code path that gets
5528 * here with entity->open being TRUE.
5529 *
5530 * Since it is not certain that this logic is watertight,
5531 * we keep the line and merely exclude it from coverage
5532 * tests.
5533 */
5534 parser->m_eventPtr = ptr; /* LCOV_EXCL_LINE */
5535 }
5536 return XML_ERROR_RECURSIVE_ENTITY_REF;
5537 }
5538 if (entity->notation) {
5539 if (enc == parser->m_encoding)
5540 parser->m_eventPtr = ptr;
5541 return XML_ERROR_BINARY_ENTITY_REF;
5542 }
5543 if (! entity->textPtr) {
5544 if (enc == parser->m_encoding)
5545 parser->m_eventPtr = ptr;
5546 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
5547 } else {
5548 enum XML_Error result;
5549 const XML_Char *textEnd = entity->textPtr + entity->textLen;
5550 entity->open = XML_TRUE;
5551 result = appendAttributeValue(parser, parser->m_internalEncoding,
Haibo Huangd1a324a2020-10-28 22:19:36 -07005552 isCdata, (const char *)entity->textPtr,
5553 (const char *)textEnd, pool);
Haibo Huang40a71912019-10-11 11:13:39 -07005554 entity->open = XML_FALSE;
5555 if (result)
5556 return result;
5557 }
5558 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005559 default:
Elliott Hughes72472942018-01-10 08:36:10 -08005560 /* The only token returned by XmlAttributeValueTok() that does
5561 * not have an explicit case here is XML_TOK_PARTIAL_CHAR.
5562 * Getting that would require an entity name to contain an
5563 * incomplete XML character (e.g. \xE2\x82); however previous
5564 * tokenisers will have already recognised and rejected such
5565 * names before XmlAttributeValueTok() gets a look-in. This
5566 * default case should be retained as a safety net, but the code
5567 * excluded from coverage tests.
5568 *
5569 * LCOV_EXCL_START
5570 */
5571 if (enc == parser->m_encoding)
5572 parser->m_eventPtr = ptr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005573 return XML_ERROR_UNEXPECTED_STATE;
Elliott Hughes72472942018-01-10 08:36:10 -08005574 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005575 }
5576 ptr = next;
5577 }
5578 /* not reached */
5579}
5580
5581static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07005582storeEntityValue(XML_Parser parser, const ENCODING *enc,
5583 const char *entityTextPtr, const char *entityTextEnd) {
5584 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005585 STRING_POOL *pool = &(dtd->entityValuePool);
5586 enum XML_Error result = XML_ERROR_NONE;
5587#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08005588 int oldInEntityValue = parser->m_prologState.inEntityValue;
5589 parser->m_prologState.inEntityValue = 1;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005590#endif /* XML_DTD */
5591 /* never return Null for the value argument in EntityDeclHandler,
5592 since this would indicate an external entity; therefore we
5593 have to make sure that entityValuePool.start is not null */
Haibo Huang40a71912019-10-11 11:13:39 -07005594 if (! pool->blocks) {
5595 if (! poolGrow(pool))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005596 return XML_ERROR_NO_MEMORY;
5597 }
5598
5599 for (;;) {
5600 const char *next;
5601 int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
5602 switch (tok) {
5603 case XML_TOK_PARAM_ENTITY_REF:
5604#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08005605 if (parser->m_isParamEntity || enc != parser->m_encoding) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005606 const XML_Char *name;
5607 ENTITY *entity;
Elliott Hughes72472942018-01-10 08:36:10 -08005608 name = poolStoreString(&parser->m_tempPool, enc,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005609 entityTextPtr + enc->minBytesPerChar,
5610 next - enc->minBytesPerChar);
Haibo Huang40a71912019-10-11 11:13:39 -07005611 if (! name) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005612 result = XML_ERROR_NO_MEMORY;
5613 goto endEntityValue;
5614 }
Elliott Hughes35e432d2012-09-09 14:23:38 -07005615 entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
Elliott Hughes72472942018-01-10 08:36:10 -08005616 poolDiscard(&parser->m_tempPool);
Haibo Huang40a71912019-10-11 11:13:39 -07005617 if (! entity) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005618 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
5619 /* cannot report skipped entity here - see comments on
Elliott Hughes72472942018-01-10 08:36:10 -08005620 parser->m_skippedEntityHandler
5621 if (parser->m_skippedEntityHandler)
5622 parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005623 */
5624 dtd->keepProcessing = dtd->standalone;
5625 goto endEntityValue;
5626 }
5627 if (entity->open) {
Elliott Hughes72472942018-01-10 08:36:10 -08005628 if (enc == parser->m_encoding)
5629 parser->m_eventPtr = entityTextPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005630 result = XML_ERROR_RECURSIVE_ENTITY_REF;
5631 goto endEntityValue;
5632 }
5633 if (entity->systemId) {
Elliott Hughes72472942018-01-10 08:36:10 -08005634 if (parser->m_externalEntityRefHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005635 dtd->paramEntityRead = XML_FALSE;
5636 entity->open = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07005637 if (! parser->m_externalEntityRefHandler(
5638 parser->m_externalEntityRefHandlerArg, 0, entity->base,
5639 entity->systemId, entity->publicId)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005640 entity->open = XML_FALSE;
5641 result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
5642 goto endEntityValue;
5643 }
5644 entity->open = XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07005645 if (! dtd->paramEntityRead)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005646 dtd->keepProcessing = dtd->standalone;
Haibo Huang40a71912019-10-11 11:13:39 -07005647 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005648 dtd->keepProcessing = dtd->standalone;
Haibo Huang40a71912019-10-11 11:13:39 -07005649 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005650 entity->open = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07005651 result = storeEntityValue(
Haibo Huangd1a324a2020-10-28 22:19:36 -07005652 parser, parser->m_internalEncoding, (const char *)entity->textPtr,
5653 (const char *)(entity->textPtr + entity->textLen));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005654 entity->open = XML_FALSE;
5655 if (result)
5656 goto endEntityValue;
5657 }
5658 break;
5659 }
5660#endif /* XML_DTD */
5661 /* In the internal subset, PE references are not legal
5662 within markup declarations, e.g entity values in this case. */
Elliott Hughes72472942018-01-10 08:36:10 -08005663 parser->m_eventPtr = entityTextPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005664 result = XML_ERROR_PARAM_ENTITY_REF;
5665 goto endEntityValue;
5666 case XML_TOK_NONE:
5667 result = XML_ERROR_NONE;
5668 goto endEntityValue;
5669 case XML_TOK_ENTITY_REF:
5670 case XML_TOK_DATA_CHARS:
Haibo Huang40a71912019-10-11 11:13:39 -07005671 if (! poolAppend(pool, enc, entityTextPtr, next)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005672 result = XML_ERROR_NO_MEMORY;
5673 goto endEntityValue;
5674 }
5675 break;
5676 case XML_TOK_TRAILING_CR:
5677 next = entityTextPtr + enc->minBytesPerChar;
5678 /* fall through */
5679 case XML_TOK_DATA_NEWLINE:
Haibo Huang40a71912019-10-11 11:13:39 -07005680 if (pool->end == pool->ptr && ! poolGrow(pool)) {
5681 result = XML_ERROR_NO_MEMORY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005682 goto endEntityValue;
5683 }
5684 *(pool->ptr)++ = 0xA;
5685 break;
Haibo Huang40a71912019-10-11 11:13:39 -07005686 case XML_TOK_CHAR_REF: {
5687 XML_Char buf[XML_ENCODE_MAX];
5688 int i;
5689 int n = XmlCharRefNumber(enc, entityTextPtr);
5690 if (n < 0) {
5691 if (enc == parser->m_encoding)
5692 parser->m_eventPtr = entityTextPtr;
5693 result = XML_ERROR_BAD_CHAR_REF;
5694 goto endEntityValue;
5695 }
5696 n = XmlEncode(n, (ICHAR *)buf);
5697 /* The XmlEncode() functions can never return 0 here. That
5698 * error return happens if the code point passed in is either
5699 * negative or greater than or equal to 0x110000. The
5700 * XmlCharRefNumber() functions will all return a number
5701 * strictly less than 0x110000 or a negative value if an error
5702 * occurred. The negative value is intercepted above, so
5703 * XmlEncode() is never passed a value it might return an
5704 * error for.
5705 */
5706 for (i = 0; i < n; i++) {
5707 if (pool->end == pool->ptr && ! poolGrow(pool)) {
5708 result = XML_ERROR_NO_MEMORY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005709 goto endEntityValue;
5710 }
Haibo Huang40a71912019-10-11 11:13:39 -07005711 *(pool->ptr)++ = buf[i];
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005712 }
Haibo Huang40a71912019-10-11 11:13:39 -07005713 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005714 case XML_TOK_PARTIAL:
Elliott Hughes72472942018-01-10 08:36:10 -08005715 if (enc == parser->m_encoding)
5716 parser->m_eventPtr = entityTextPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005717 result = XML_ERROR_INVALID_TOKEN;
5718 goto endEntityValue;
5719 case XML_TOK_INVALID:
Elliott Hughes72472942018-01-10 08:36:10 -08005720 if (enc == parser->m_encoding)
5721 parser->m_eventPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005722 result = XML_ERROR_INVALID_TOKEN;
5723 goto endEntityValue;
5724 default:
Elliott Hughes72472942018-01-10 08:36:10 -08005725 /* This default case should be unnecessary -- all the tokens
5726 * that XmlEntityValueTok() can return have their own explicit
5727 * cases -- but should be retained for safety. We do however
5728 * exclude it from the coverage statistics.
5729 *
5730 * LCOV_EXCL_START
5731 */
5732 if (enc == parser->m_encoding)
5733 parser->m_eventPtr = entityTextPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005734 result = XML_ERROR_UNEXPECTED_STATE;
5735 goto endEntityValue;
Elliott Hughes72472942018-01-10 08:36:10 -08005736 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005737 }
5738 entityTextPtr = next;
5739 }
5740endEntityValue:
5741#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08005742 parser->m_prologState.inEntityValue = oldInEntityValue;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005743#endif /* XML_DTD */
5744 return result;
5745}
5746
5747static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07005748normalizeLines(XML_Char *s) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005749 XML_Char *p;
5750 for (;; s++) {
5751 if (*s == XML_T('\0'))
5752 return;
5753 if (*s == 0xD)
5754 break;
5755 }
5756 p = s;
5757 do {
5758 if (*s == 0xD) {
5759 *p++ = 0xA;
5760 if (*++s == 0xA)
5761 s++;
Haibo Huang40a71912019-10-11 11:13:39 -07005762 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005763 *p++ = *s++;
5764 } while (*s);
5765 *p = XML_T('\0');
5766}
5767
5768static int
5769reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
Haibo Huang40a71912019-10-11 11:13:39 -07005770 const char *start, const char *end) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005771 const XML_Char *target;
5772 XML_Char *data;
5773 const char *tem;
Haibo Huang40a71912019-10-11 11:13:39 -07005774 if (! parser->m_processingInstructionHandler) {
Elliott Hughes72472942018-01-10 08:36:10 -08005775 if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005776 reportDefault(parser, enc, start, end);
5777 return 1;
5778 }
5779 start += enc->minBytesPerChar * 2;
5780 tem = start + XmlNameLength(enc, start);
Elliott Hughes72472942018-01-10 08:36:10 -08005781 target = poolStoreString(&parser->m_tempPool, enc, start, tem);
Haibo Huang40a71912019-10-11 11:13:39 -07005782 if (! target)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005783 return 0;
Elliott Hughes72472942018-01-10 08:36:10 -08005784 poolFinish(&parser->m_tempPool);
Haibo Huang40a71912019-10-11 11:13:39 -07005785 data = poolStoreString(&parser->m_tempPool, enc, XmlSkipS(enc, tem),
5786 end - enc->minBytesPerChar * 2);
5787 if (! data)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005788 return 0;
5789 normalizeLines(data);
Elliott Hughes72472942018-01-10 08:36:10 -08005790 parser->m_processingInstructionHandler(parser->m_handlerArg, target, data);
5791 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005792 return 1;
5793}
5794
5795static int
Haibo Huang40a71912019-10-11 11:13:39 -07005796reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
5797 const char *end) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005798 XML_Char *data;
Haibo Huang40a71912019-10-11 11:13:39 -07005799 if (! parser->m_commentHandler) {
Elliott Hughes72472942018-01-10 08:36:10 -08005800 if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005801 reportDefault(parser, enc, start, end);
5802 return 1;
5803 }
Haibo Huang40a71912019-10-11 11:13:39 -07005804 data = poolStoreString(&parser->m_tempPool, enc,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005805 start + enc->minBytesPerChar * 4,
5806 end - enc->minBytesPerChar * 3);
Haibo Huang40a71912019-10-11 11:13:39 -07005807 if (! data)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005808 return 0;
5809 normalizeLines(data);
Elliott Hughes72472942018-01-10 08:36:10 -08005810 parser->m_commentHandler(parser->m_handlerArg, data);
5811 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005812 return 1;
5813}
5814
5815static void
Haibo Huang40a71912019-10-11 11:13:39 -07005816reportDefault(XML_Parser parser, const ENCODING *enc, const char *s,
5817 const char *end) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005818 if (MUST_CONVERT(enc, s)) {
Paul Duffin4bf8f122016-05-13 12:35:25 +01005819 enum XML_Convert_Result convert_res;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005820 const char **eventPP;
5821 const char **eventEndPP;
Elliott Hughes72472942018-01-10 08:36:10 -08005822 if (enc == parser->m_encoding) {
5823 eventPP = &parser->m_eventPtr;
5824 eventEndPP = &parser->m_eventEndPtr;
Haibo Huang40a71912019-10-11 11:13:39 -07005825 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08005826 /* To get here, two things must be true; the parser must be
5827 * using a character encoding that is not the same as the
5828 * encoding passed in, and the encoding passed in must need
5829 * conversion to the internal format (UTF-8 unless XML_UNICODE
5830 * is defined). The only occasions on which the encoding passed
5831 * in is not the same as the parser's encoding are when it is
5832 * the internal encoding (e.g. a previously defined parameter
5833 * entity, already converted to internal format). This by
5834 * definition doesn't need conversion, so the whole branch never
5835 * gets executed.
5836 *
5837 * For safety's sake we don't delete these lines and merely
5838 * exclude them from coverage statistics.
5839 *
5840 * LCOV_EXCL_START
5841 */
5842 eventPP = &(parser->m_openInternalEntities->internalEventPtr);
5843 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
5844 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005845 }
5846 do {
Elliott Hughes72472942018-01-10 08:36:10 -08005847 ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
Haibo Huang40a71912019-10-11 11:13:39 -07005848 convert_res
5849 = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005850 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07005851 parser->m_defaultHandler(parser->m_handlerArg, parser->m_dataBuf,
5852 (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005853 *eventPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07005854 } while ((convert_res != XML_CONVERT_COMPLETED)
5855 && (convert_res != XML_CONVERT_INPUT_INCOMPLETE));
5856 } else
5857 parser->m_defaultHandler(parser->m_handlerArg, (XML_Char *)s,
5858 (int)((XML_Char *)end - (XML_Char *)s));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005859}
5860
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005861static int
5862defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
Haibo Huang40a71912019-10-11 11:13:39 -07005863 XML_Bool isId, const XML_Char *value, XML_Parser parser) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005864 DEFAULT_ATTRIBUTE *att;
5865 if (value || isId) {
5866 /* The handling of default attributes gets messed up if we have
5867 a default which duplicates a non-default. */
5868 int i;
5869 for (i = 0; i < type->nDefaultAtts; i++)
5870 if (attId == type->defaultAtts[i].id)
5871 return 1;
Haibo Huang40a71912019-10-11 11:13:39 -07005872 if (isId && ! type->idAtt && ! attId->xmlns)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005873 type->idAtt = attId;
5874 }
5875 if (type->nDefaultAtts == type->allocDefaultAtts) {
5876 if (type->allocDefaultAtts == 0) {
5877 type->allocDefaultAtts = 8;
Haibo Huang40a71912019-10-11 11:13:39 -07005878 type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(
5879 parser, type->allocDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
5880 if (! type->defaultAtts) {
Elliott Hughes72472942018-01-10 08:36:10 -08005881 type->allocDefaultAtts = 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005882 return 0;
Elliott Hughes72472942018-01-10 08:36:10 -08005883 }
Haibo Huang40a71912019-10-11 11:13:39 -07005884 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005885 DEFAULT_ATTRIBUTE *temp;
Sadaf Ebrahimif68f6852022-06-15 04:14:33 +00005886
5887 /* Detect and prevent integer overflow */
5888 if (type->allocDefaultAtts > INT_MAX / 2) {
5889 return 0;
5890 }
5891
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005892 int count = type->allocDefaultAtts * 2;
Sadaf Ebrahimif68f6852022-06-15 04:14:33 +00005893
5894 /* Detect and prevent integer overflow.
5895 * The preprocessor guard addresses the "always false" warning
5896 * from -Wtype-limits on platforms where
5897 * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
5898#if UINT_MAX >= SIZE_MAX
5899 if ((unsigned)count > (size_t)(-1) / sizeof(DEFAULT_ATTRIBUTE)) {
5900 return 0;
5901 }
5902#endif
5903
Haibo Huang40a71912019-10-11 11:13:39 -07005904 temp = (DEFAULT_ATTRIBUTE *)REALLOC(parser, type->defaultAtts,
5905 (count * sizeof(DEFAULT_ATTRIBUTE)));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005906 if (temp == NULL)
5907 return 0;
5908 type->allocDefaultAtts = count;
5909 type->defaultAtts = temp;
5910 }
5911 }
5912 att = type->defaultAtts + type->nDefaultAtts;
5913 att->id = attId;
5914 att->value = value;
5915 att->isCdata = isCdata;
Haibo Huang40a71912019-10-11 11:13:39 -07005916 if (! isCdata)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005917 attId->maybeTokenized = XML_TRUE;
5918 type->nDefaultAtts += 1;
5919 return 1;
5920}
5921
5922static int
Haibo Huang40a71912019-10-11 11:13:39 -07005923setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType) {
5924 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005925 const XML_Char *name;
5926 for (name = elementType->name; *name; name++) {
Elliott Hughesd07d5a72009-09-25 16:04:37 -07005927 if (*name == XML_T(ASCII_COLON)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005928 PREFIX *prefix;
5929 const XML_Char *s;
5930 for (s = elementType->name; s != name; s++) {
Haibo Huang40a71912019-10-11 11:13:39 -07005931 if (! poolAppendChar(&dtd->pool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005932 return 0;
5933 }
Haibo Huang40a71912019-10-11 11:13:39 -07005934 if (! poolAppendChar(&dtd->pool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005935 return 0;
Elliott Hughes35e432d2012-09-09 14:23:38 -07005936 prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005937 sizeof(PREFIX));
Haibo Huang40a71912019-10-11 11:13:39 -07005938 if (! prefix)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005939 return 0;
5940 if (prefix->name == poolStart(&dtd->pool))
5941 poolFinish(&dtd->pool);
5942 else
5943 poolDiscard(&dtd->pool);
5944 elementType->prefix = prefix;
Haibo Huangfd5e81a2019-06-20 12:09:36 -07005945 break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005946 }
5947 }
5948 return 1;
5949}
5950
5951static ATTRIBUTE_ID *
Haibo Huang40a71912019-10-11 11:13:39 -07005952getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
5953 const char *end) {
5954 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005955 ATTRIBUTE_ID *id;
5956 const XML_Char *name;
Haibo Huang40a71912019-10-11 11:13:39 -07005957 if (! poolAppendChar(&dtd->pool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005958 return NULL;
5959 name = poolStoreString(&dtd->pool, enc, start, end);
Haibo Huang40a71912019-10-11 11:13:39 -07005960 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005961 return NULL;
5962 /* skip quotation mark - its storage will be re-used (like in name[-1]) */
5963 ++name;
Haibo Huang40a71912019-10-11 11:13:39 -07005964 id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name,
5965 sizeof(ATTRIBUTE_ID));
5966 if (! id)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005967 return NULL;
5968 if (id->name != name)
5969 poolDiscard(&dtd->pool);
5970 else {
5971 poolFinish(&dtd->pool);
Haibo Huang40a71912019-10-11 11:13:39 -07005972 if (! parser->m_ns)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005973 ;
Haibo Huang40a71912019-10-11 11:13:39 -07005974 else if (name[0] == XML_T(ASCII_x) && name[1] == XML_T(ASCII_m)
5975 && name[2] == XML_T(ASCII_l) && name[3] == XML_T(ASCII_n)
5976 && name[4] == XML_T(ASCII_s)
5977 && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005978 if (name[5] == XML_T('\0'))
5979 id->prefix = &dtd->defaultPrefix;
5980 else
Haibo Huang40a71912019-10-11 11:13:39 -07005981 id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6,
5982 sizeof(PREFIX));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005983 id->xmlns = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07005984 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005985 int i;
5986 for (i = 0; name[i]; i++) {
5987 /* attributes without prefix are *not* in the default namespace */
Elliott Hughesd07d5a72009-09-25 16:04:37 -07005988 if (name[i] == XML_T(ASCII_COLON)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005989 int j;
5990 for (j = 0; j < i; j++) {
Haibo Huang40a71912019-10-11 11:13:39 -07005991 if (! poolAppendChar(&dtd->pool, name[j]))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005992 return NULL;
5993 }
Haibo Huang40a71912019-10-11 11:13:39 -07005994 if (! poolAppendChar(&dtd->pool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005995 return NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07005996 id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes,
5997 poolStart(&dtd->pool), sizeof(PREFIX));
5998 if (! id->prefix)
Paul Duffinc05e0322016-05-04 10:42:31 +01005999 return NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006000 if (id->prefix->name == poolStart(&dtd->pool))
6001 poolFinish(&dtd->pool);
6002 else
6003 poolDiscard(&dtd->pool);
6004 break;
6005 }
6006 }
6007 }
6008 }
6009 return id;
6010}
6011
Elliott Hughesd07d5a72009-09-25 16:04:37 -07006012#define CONTEXT_SEP XML_T(ASCII_FF)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006013
6014static const XML_Char *
Haibo Huang40a71912019-10-11 11:13:39 -07006015getContext(XML_Parser parser) {
6016 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006017 HASH_TABLE_ITER iter;
6018 XML_Bool needSep = XML_FALSE;
6019
6020 if (dtd->defaultPrefix.binding) {
6021 int i;
6022 int len;
Haibo Huang40a71912019-10-11 11:13:39 -07006023 if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS)))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006024 return NULL;
6025 len = dtd->defaultPrefix.binding->uriLen;
Elliott Hughes72472942018-01-10 08:36:10 -08006026 if (parser->m_namespaceSeparator)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006027 len--;
Elliott Hughes72472942018-01-10 08:36:10 -08006028 for (i = 0; i < len; i++) {
Haibo Huang40a71912019-10-11 11:13:39 -07006029 if (! poolAppendChar(&parser->m_tempPool,
6030 dtd->defaultPrefix.binding->uri[i])) {
Elliott Hughes72472942018-01-10 08:36:10 -08006031 /* Because of memory caching, I don't believe this line can be
6032 * executed.
6033 *
6034 * This is part of a loop copying the default prefix binding
6035 * URI into the parser's temporary string pool. Previously,
6036 * that URI was copied into the same string pool, with a
6037 * terminating NUL character, as part of setContext(). When
6038 * the pool was cleared, that leaves a block definitely big
6039 * enough to hold the URI on the free block list of the pool.
6040 * The URI copy in getContext() therefore cannot run out of
6041 * memory.
6042 *
6043 * If the pool is used between the setContext() and
6044 * getContext() calls, the worst it can do is leave a bigger
6045 * block on the front of the free list. Given that this is
6046 * all somewhat inobvious and program logic can be changed, we
6047 * don't delete the line but we do exclude it from the test
6048 * coverage statistics.
6049 */
6050 return NULL; /* LCOV_EXCL_LINE */
6051 }
6052 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006053 needSep = XML_TRUE;
6054 }
6055
6056 hashTableIterInit(&iter, &(dtd->prefixes));
6057 for (;;) {
6058 int i;
6059 int len;
6060 const XML_Char *s;
6061 PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006062 if (! prefix)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006063 break;
Haibo Huang40a71912019-10-11 11:13:39 -07006064 if (! prefix->binding) {
Elliott Hughes72472942018-01-10 08:36:10 -08006065 /* This test appears to be (justifiable) paranoia. There does
6066 * not seem to be a way of injecting a prefix without a binding
6067 * that doesn't get errored long before this function is called.
6068 * The test should remain for safety's sake, so we instead
6069 * exclude the following line from the coverage statistics.
6070 */
6071 continue; /* LCOV_EXCL_LINE */
6072 }
Haibo Huang40a71912019-10-11 11:13:39 -07006073 if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006074 return NULL;
6075 for (s = prefix->name; *s; s++)
Haibo Huang40a71912019-10-11 11:13:39 -07006076 if (! poolAppendChar(&parser->m_tempPool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006077 return NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07006078 if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS)))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006079 return NULL;
6080 len = prefix->binding->uriLen;
Elliott Hughes72472942018-01-10 08:36:10 -08006081 if (parser->m_namespaceSeparator)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006082 len--;
6083 for (i = 0; i < len; i++)
Haibo Huang40a71912019-10-11 11:13:39 -07006084 if (! poolAppendChar(&parser->m_tempPool, prefix->binding->uri[i]))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006085 return NULL;
6086 needSep = XML_TRUE;
6087 }
6088
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006089 hashTableIterInit(&iter, &(dtd->generalEntities));
6090 for (;;) {
6091 const XML_Char *s;
6092 ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006093 if (! e)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006094 break;
Haibo Huang40a71912019-10-11 11:13:39 -07006095 if (! e->open)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006096 continue;
Haibo Huang40a71912019-10-11 11:13:39 -07006097 if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006098 return NULL;
6099 for (s = e->name; *s; s++)
Haibo Huang40a71912019-10-11 11:13:39 -07006100 if (! poolAppendChar(&parser->m_tempPool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006101 return 0;
6102 needSep = XML_TRUE;
6103 }
6104
Haibo Huang40a71912019-10-11 11:13:39 -07006105 if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006106 return NULL;
Elliott Hughes72472942018-01-10 08:36:10 -08006107 return parser->m_tempPool.start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006108}
6109
6110static XML_Bool
Haibo Huang40a71912019-10-11 11:13:39 -07006111setContext(XML_Parser parser, const XML_Char *context) {
6112 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006113 const XML_Char *s = context;
6114
6115 while (*context != XML_T('\0')) {
6116 if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
6117 ENTITY *e;
Haibo Huang40a71912019-10-11 11:13:39 -07006118 if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006119 return XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07006120 e = (ENTITY *)lookup(parser, &dtd->generalEntities,
6121 poolStart(&parser->m_tempPool), 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006122 if (e)
6123 e->open = XML_TRUE;
6124 if (*s != XML_T('\0'))
6125 s++;
6126 context = s;
Elliott Hughes72472942018-01-10 08:36:10 -08006127 poolDiscard(&parser->m_tempPool);
Haibo Huang40a71912019-10-11 11:13:39 -07006128 } else if (*s == XML_T(ASCII_EQUALS)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006129 PREFIX *prefix;
Elliott Hughes72472942018-01-10 08:36:10 -08006130 if (poolLength(&parser->m_tempPool) == 0)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006131 prefix = &dtd->defaultPrefix;
6132 else {
Haibo Huang40a71912019-10-11 11:13:39 -07006133 if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006134 return XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07006135 prefix
6136 = (PREFIX *)lookup(parser, &dtd->prefixes,
6137 poolStart(&parser->m_tempPool), sizeof(PREFIX));
6138 if (! prefix)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006139 return XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08006140 if (prefix->name == poolStart(&parser->m_tempPool)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006141 prefix->name = poolCopyString(&dtd->pool, prefix->name);
Haibo Huang40a71912019-10-11 11:13:39 -07006142 if (! prefix->name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006143 return XML_FALSE;
6144 }
Elliott Hughes72472942018-01-10 08:36:10 -08006145 poolDiscard(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006146 }
Haibo Huang40a71912019-10-11 11:13:39 -07006147 for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0');
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006148 context++)
Haibo Huang40a71912019-10-11 11:13:39 -07006149 if (! poolAppendChar(&parser->m_tempPool, *context))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006150 return XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07006151 if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006152 return XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08006153 if (addBinding(parser, prefix, NULL, poolStart(&parser->m_tempPool),
Haibo Huang40a71912019-10-11 11:13:39 -07006154 &parser->m_inheritedBindings)
6155 != XML_ERROR_NONE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006156 return XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08006157 poolDiscard(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006158 if (*context != XML_T('\0'))
6159 ++context;
6160 s = context;
Haibo Huang40a71912019-10-11 11:13:39 -07006161 } else {
6162 if (! poolAppendChar(&parser->m_tempPool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006163 return XML_FALSE;
6164 s++;
6165 }
6166 }
6167 return XML_TRUE;
6168}
6169
6170static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006171normalizePublicId(XML_Char *publicId) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006172 XML_Char *p = publicId;
6173 XML_Char *s;
6174 for (s = publicId; *s; s++) {
6175 switch (*s) {
6176 case 0x20:
6177 case 0xD:
6178 case 0xA:
6179 if (p != publicId && p[-1] != 0x20)
6180 *p++ = 0x20;
6181 break;
6182 default:
6183 *p++ = *s;
6184 }
6185 }
6186 if (p != publicId && p[-1] == 0x20)
6187 --p;
6188 *p = XML_T('\0');
6189}
6190
6191static DTD *
Haibo Huang40a71912019-10-11 11:13:39 -07006192dtdCreate(const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006193 DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
6194 if (p == NULL)
6195 return p;
6196 poolInit(&(p->pool), ms);
6197 poolInit(&(p->entityValuePool), ms);
6198 hashTableInit(&(p->generalEntities), ms);
6199 hashTableInit(&(p->elementTypes), ms);
6200 hashTableInit(&(p->attributeIds), ms);
6201 hashTableInit(&(p->prefixes), ms);
6202#ifdef XML_DTD
6203 p->paramEntityRead = XML_FALSE;
6204 hashTableInit(&(p->paramEntities), ms);
6205#endif /* XML_DTD */
6206 p->defaultPrefix.name = NULL;
6207 p->defaultPrefix.binding = NULL;
6208
6209 p->in_eldecl = XML_FALSE;
6210 p->scaffIndex = NULL;
6211 p->scaffold = NULL;
6212 p->scaffLevel = 0;
6213 p->scaffSize = 0;
6214 p->scaffCount = 0;
6215 p->contentStringLen = 0;
6216
6217 p->keepProcessing = XML_TRUE;
6218 p->hasParamEntityRefs = XML_FALSE;
6219 p->standalone = XML_FALSE;
6220 return p;
6221}
6222
6223static void
Haibo Huang40a71912019-10-11 11:13:39 -07006224dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006225 HASH_TABLE_ITER iter;
6226 hashTableIterInit(&iter, &(p->elementTypes));
6227 for (;;) {
6228 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006229 if (! e)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006230 break;
6231 if (e->allocDefaultAtts != 0)
6232 ms->free_fcn(e->defaultAtts);
6233 }
6234 hashTableClear(&(p->generalEntities));
6235#ifdef XML_DTD
6236 p->paramEntityRead = XML_FALSE;
6237 hashTableClear(&(p->paramEntities));
6238#endif /* XML_DTD */
6239 hashTableClear(&(p->elementTypes));
6240 hashTableClear(&(p->attributeIds));
6241 hashTableClear(&(p->prefixes));
6242 poolClear(&(p->pool));
6243 poolClear(&(p->entityValuePool));
6244 p->defaultPrefix.name = NULL;
6245 p->defaultPrefix.binding = NULL;
6246
6247 p->in_eldecl = XML_FALSE;
6248
6249 ms->free_fcn(p->scaffIndex);
6250 p->scaffIndex = NULL;
6251 ms->free_fcn(p->scaffold);
6252 p->scaffold = NULL;
6253
6254 p->scaffLevel = 0;
6255 p->scaffSize = 0;
6256 p->scaffCount = 0;
6257 p->contentStringLen = 0;
6258
6259 p->keepProcessing = XML_TRUE;
6260 p->hasParamEntityRefs = XML_FALSE;
6261 p->standalone = XML_FALSE;
6262}
6263
6264static void
Haibo Huang40a71912019-10-11 11:13:39 -07006265dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006266 HASH_TABLE_ITER iter;
6267 hashTableIterInit(&iter, &(p->elementTypes));
6268 for (;;) {
6269 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006270 if (! e)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006271 break;
6272 if (e->allocDefaultAtts != 0)
6273 ms->free_fcn(e->defaultAtts);
6274 }
6275 hashTableDestroy(&(p->generalEntities));
6276#ifdef XML_DTD
6277 hashTableDestroy(&(p->paramEntities));
6278#endif /* XML_DTD */
6279 hashTableDestroy(&(p->elementTypes));
6280 hashTableDestroy(&(p->attributeIds));
6281 hashTableDestroy(&(p->prefixes));
6282 poolDestroy(&(p->pool));
6283 poolDestroy(&(p->entityValuePool));
6284 if (isDocEntity) {
6285 ms->free_fcn(p->scaffIndex);
6286 ms->free_fcn(p->scaffold);
6287 }
6288 ms->free_fcn(p);
6289}
6290
6291/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
6292 The new DTD has already been initialized.
6293*/
6294static int
Haibo Huang40a71912019-10-11 11:13:39 -07006295dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
6296 const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006297 HASH_TABLE_ITER iter;
6298
6299 /* Copy the prefix table. */
6300
6301 hashTableIterInit(&iter, &(oldDtd->prefixes));
6302 for (;;) {
6303 const XML_Char *name;
6304 const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006305 if (! oldP)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006306 break;
6307 name = poolCopyString(&(newDtd->pool), oldP->name);
Haibo Huang40a71912019-10-11 11:13:39 -07006308 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006309 return 0;
Haibo Huang40a71912019-10-11 11:13:39 -07006310 if (! lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX)))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006311 return 0;
6312 }
6313
6314 hashTableIterInit(&iter, &(oldDtd->attributeIds));
6315
6316 /* Copy the attribute id table. */
6317
6318 for (;;) {
6319 ATTRIBUTE_ID *newA;
6320 const XML_Char *name;
6321 const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
6322
Haibo Huang40a71912019-10-11 11:13:39 -07006323 if (! oldA)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006324 break;
6325 /* Remember to allocate the scratch byte before the name. */
Haibo Huang40a71912019-10-11 11:13:39 -07006326 if (! poolAppendChar(&(newDtd->pool), XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006327 return 0;
6328 name = poolCopyString(&(newDtd->pool), oldA->name);
Haibo Huang40a71912019-10-11 11:13:39 -07006329 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006330 return 0;
6331 ++name;
Elliott Hughes35e432d2012-09-09 14:23:38 -07006332 newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006333 sizeof(ATTRIBUTE_ID));
Haibo Huang40a71912019-10-11 11:13:39 -07006334 if (! newA)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006335 return 0;
6336 newA->maybeTokenized = oldA->maybeTokenized;
6337 if (oldA->prefix) {
6338 newA->xmlns = oldA->xmlns;
6339 if (oldA->prefix == &oldDtd->defaultPrefix)
6340 newA->prefix = &newDtd->defaultPrefix;
6341 else
Elliott Hughes35e432d2012-09-09 14:23:38 -07006342 newA->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006343 oldA->prefix->name, 0);
6344 }
6345 }
6346
6347 /* Copy the element type table. */
6348
6349 hashTableIterInit(&iter, &(oldDtd->elementTypes));
6350
6351 for (;;) {
6352 int i;
6353 ELEMENT_TYPE *newE;
6354 const XML_Char *name;
6355 const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006356 if (! oldE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006357 break;
6358 name = poolCopyString(&(newDtd->pool), oldE->name);
Haibo Huang40a71912019-10-11 11:13:39 -07006359 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006360 return 0;
Elliott Hughes35e432d2012-09-09 14:23:38 -07006361 newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006362 sizeof(ELEMENT_TYPE));
Haibo Huang40a71912019-10-11 11:13:39 -07006363 if (! newE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006364 return 0;
6365 if (oldE->nDefaultAtts) {
Haibo Huang40a71912019-10-11 11:13:39 -07006366 newE->defaultAtts = (DEFAULT_ATTRIBUTE *)ms->malloc_fcn(
6367 oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
6368 if (! newE->defaultAtts) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006369 return 0;
6370 }
6371 }
6372 if (oldE->idAtt)
Haibo Huang40a71912019-10-11 11:13:39 -07006373 newE->idAtt = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds),
6374 oldE->idAtt->name, 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006375 newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
6376 if (oldE->prefix)
Elliott Hughes35e432d2012-09-09 14:23:38 -07006377 newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006378 oldE->prefix->name, 0);
6379 for (i = 0; i < newE->nDefaultAtts; i++) {
Haibo Huang40a71912019-10-11 11:13:39 -07006380 newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup(
6381 oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006382 newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
6383 if (oldE->defaultAtts[i].value) {
6384 newE->defaultAtts[i].value
6385 = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
Haibo Huang40a71912019-10-11 11:13:39 -07006386 if (! newE->defaultAtts[i].value)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006387 return 0;
Haibo Huang40a71912019-10-11 11:13:39 -07006388 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006389 newE->defaultAtts[i].value = NULL;
6390 }
6391 }
6392
6393 /* Copy the entity tables. */
Haibo Huang40a71912019-10-11 11:13:39 -07006394 if (! copyEntityTable(oldParser, &(newDtd->generalEntities), &(newDtd->pool),
6395 &(oldDtd->generalEntities)))
6396 return 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006397
6398#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07006399 if (! copyEntityTable(oldParser, &(newDtd->paramEntities), &(newDtd->pool),
6400 &(oldDtd->paramEntities)))
6401 return 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006402 newDtd->paramEntityRead = oldDtd->paramEntityRead;
6403#endif /* XML_DTD */
6404
6405 newDtd->keepProcessing = oldDtd->keepProcessing;
6406 newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
6407 newDtd->standalone = oldDtd->standalone;
6408
6409 /* Don't want deep copying for scaffolding */
6410 newDtd->in_eldecl = oldDtd->in_eldecl;
6411 newDtd->scaffold = oldDtd->scaffold;
6412 newDtd->contentStringLen = oldDtd->contentStringLen;
6413 newDtd->scaffSize = oldDtd->scaffSize;
6414 newDtd->scaffLevel = oldDtd->scaffLevel;
6415 newDtd->scaffIndex = oldDtd->scaffIndex;
6416
6417 return 1;
Haibo Huang40a71912019-10-11 11:13:39 -07006418} /* End dtdCopy */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006419
6420static int
Haibo Huang40a71912019-10-11 11:13:39 -07006421copyEntityTable(XML_Parser oldParser, HASH_TABLE *newTable,
6422 STRING_POOL *newPool, const HASH_TABLE *oldTable) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006423 HASH_TABLE_ITER iter;
6424 const XML_Char *cachedOldBase = NULL;
6425 const XML_Char *cachedNewBase = NULL;
6426
6427 hashTableIterInit(&iter, oldTable);
6428
6429 for (;;) {
6430 ENTITY *newE;
6431 const XML_Char *name;
6432 const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006433 if (! oldE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006434 break;
6435 name = poolCopyString(newPool, oldE->name);
Haibo Huang40a71912019-10-11 11:13:39 -07006436 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006437 return 0;
Elliott Hughes35e432d2012-09-09 14:23:38 -07006438 newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY));
Haibo Huang40a71912019-10-11 11:13:39 -07006439 if (! newE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006440 return 0;
6441 if (oldE->systemId) {
6442 const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
Haibo Huang40a71912019-10-11 11:13:39 -07006443 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006444 return 0;
6445 newE->systemId = tem;
6446 if (oldE->base) {
6447 if (oldE->base == cachedOldBase)
6448 newE->base = cachedNewBase;
6449 else {
6450 cachedOldBase = oldE->base;
6451 tem = poolCopyString(newPool, cachedOldBase);
Haibo Huang40a71912019-10-11 11:13:39 -07006452 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006453 return 0;
6454 cachedNewBase = newE->base = tem;
6455 }
6456 }
6457 if (oldE->publicId) {
6458 tem = poolCopyString(newPool, oldE->publicId);
Haibo Huang40a71912019-10-11 11:13:39 -07006459 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006460 return 0;
6461 newE->publicId = tem;
6462 }
Haibo Huang40a71912019-10-11 11:13:39 -07006463 } else {
6464 const XML_Char *tem
6465 = poolCopyStringN(newPool, oldE->textPtr, oldE->textLen);
6466 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006467 return 0;
6468 newE->textPtr = tem;
6469 newE->textLen = oldE->textLen;
6470 }
6471 if (oldE->notation) {
6472 const XML_Char *tem = poolCopyString(newPool, oldE->notation);
Haibo Huang40a71912019-10-11 11:13:39 -07006473 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006474 return 0;
6475 newE->notation = tem;
6476 }
6477 newE->is_param = oldE->is_param;
6478 newE->is_internal = oldE->is_internal;
6479 }
6480 return 1;
6481}
6482
6483#define INIT_POWER 6
6484
6485static XML_Bool FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006486keyeq(KEY s1, KEY s2) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006487 for (; *s1 == *s2; s1++, s2++)
6488 if (*s1 == 0)
6489 return XML_TRUE;
6490 return XML_FALSE;
6491}
6492
Elliott Hughes72472942018-01-10 08:36:10 -08006493static size_t
Haibo Huang40a71912019-10-11 11:13:39 -07006494keylen(KEY s) {
Elliott Hughes72472942018-01-10 08:36:10 -08006495 size_t len = 0;
Haibo Huang40a71912019-10-11 11:13:39 -07006496 for (; *s; s++, len++)
6497 ;
Elliott Hughes72472942018-01-10 08:36:10 -08006498 return len;
6499}
6500
6501static void
Haibo Huang40a71912019-10-11 11:13:39 -07006502copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key) {
Elliott Hughes72472942018-01-10 08:36:10 -08006503 key->k[0] = 0;
6504 key->k[1] = get_hash_secret_salt(parser);
6505}
6506
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006507static unsigned long FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006508hash(XML_Parser parser, KEY s) {
Elliott Hughes72472942018-01-10 08:36:10 -08006509 struct siphash state;
6510 struct sipkey key;
Elliott Hughes72472942018-01-10 08:36:10 -08006511 (void)sip24_valid;
6512 copy_salt_to_sipkey(parser, &key);
6513 sip24_init(&state, &key);
6514 sip24_update(&state, s, keylen(s) * sizeof(XML_Char));
6515 return (unsigned long)sip24_final(&state);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006516}
6517
6518static NAMED *
Haibo Huang40a71912019-10-11 11:13:39 -07006519lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006520 size_t i;
6521 if (table->size == 0) {
6522 size_t tsize;
Haibo Huang40a71912019-10-11 11:13:39 -07006523 if (! createSize)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006524 return NULL;
6525 table->power = INIT_POWER;
6526 /* table->size is a power of 2 */
6527 table->size = (size_t)1 << INIT_POWER;
6528 tsize = table->size * sizeof(NAMED *);
6529 table->v = (NAMED **)table->mem->malloc_fcn(tsize);
Haibo Huang40a71912019-10-11 11:13:39 -07006530 if (! table->v) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006531 table->size = 0;
6532 return NULL;
6533 }
6534 memset(table->v, 0, tsize);
Elliott Hughes35e432d2012-09-09 14:23:38 -07006535 i = hash(parser, name) & ((unsigned long)table->size - 1);
Haibo Huang40a71912019-10-11 11:13:39 -07006536 } else {
Elliott Hughes35e432d2012-09-09 14:23:38 -07006537 unsigned long h = hash(parser, name);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006538 unsigned long mask = (unsigned long)table->size - 1;
6539 unsigned char step = 0;
6540 i = h & mask;
6541 while (table->v[i]) {
6542 if (keyeq(name, table->v[i]->name))
6543 return table->v[i];
Haibo Huang40a71912019-10-11 11:13:39 -07006544 if (! step)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006545 step = PROBE_STEP(h, mask, table->power);
6546 i < step ? (i += table->size - step) : (i -= step);
6547 }
Haibo Huang40a71912019-10-11 11:13:39 -07006548 if (! createSize)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006549 return NULL;
6550
6551 /* check for overflow (table is half full) */
6552 if (table->used >> (table->power - 1)) {
6553 unsigned char newPower = table->power + 1;
Sadaf Ebrahimif68f6852022-06-15 04:14:33 +00006554
6555 /* Detect and prevent invalid shift */
6556 if (newPower >= sizeof(unsigned long) * 8 /* bits per byte */) {
6557 return NULL;
6558 }
6559
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006560 size_t newSize = (size_t)1 << newPower;
6561 unsigned long newMask = (unsigned long)newSize - 1;
Sadaf Ebrahimif68f6852022-06-15 04:14:33 +00006562
6563 /* Detect and prevent integer overflow */
6564 if (newSize > (size_t)(-1) / sizeof(NAMED *)) {
6565 return NULL;
6566 }
6567
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006568 size_t tsize = newSize * sizeof(NAMED *);
6569 NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
Haibo Huang40a71912019-10-11 11:13:39 -07006570 if (! newV)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006571 return NULL;
6572 memset(newV, 0, tsize);
6573 for (i = 0; i < table->size; i++)
6574 if (table->v[i]) {
Elliott Hughes35e432d2012-09-09 14:23:38 -07006575 unsigned long newHash = hash(parser, table->v[i]->name);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006576 size_t j = newHash & newMask;
6577 step = 0;
6578 while (newV[j]) {
Haibo Huang40a71912019-10-11 11:13:39 -07006579 if (! step)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006580 step = PROBE_STEP(newHash, newMask, newPower);
6581 j < step ? (j += newSize - step) : (j -= step);
6582 }
6583 newV[j] = table->v[i];
6584 }
6585 table->mem->free_fcn(table->v);
6586 table->v = newV;
6587 table->power = newPower;
6588 table->size = newSize;
6589 i = h & newMask;
6590 step = 0;
6591 while (table->v[i]) {
Haibo Huang40a71912019-10-11 11:13:39 -07006592 if (! step)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006593 step = PROBE_STEP(h, newMask, newPower);
6594 i < step ? (i += newSize - step) : (i -= step);
6595 }
6596 }
6597 }
6598 table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
Haibo Huang40a71912019-10-11 11:13:39 -07006599 if (! table->v[i])
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006600 return NULL;
6601 memset(table->v[i], 0, createSize);
6602 table->v[i]->name = name;
6603 (table->used)++;
6604 return table->v[i];
6605}
6606
6607static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006608hashTableClear(HASH_TABLE *table) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006609 size_t i;
6610 for (i = 0; i < table->size; i++) {
6611 table->mem->free_fcn(table->v[i]);
6612 table->v[i] = NULL;
6613 }
6614 table->used = 0;
6615}
6616
6617static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006618hashTableDestroy(HASH_TABLE *table) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006619 size_t i;
6620 for (i = 0; i < table->size; i++)
6621 table->mem->free_fcn(table->v[i]);
6622 table->mem->free_fcn(table->v);
6623}
6624
6625static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006626hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006627 p->power = 0;
6628 p->size = 0;
6629 p->used = 0;
6630 p->v = NULL;
6631 p->mem = ms;
6632}
6633
6634static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006635hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006636 iter->p = table->v;
Haibo Huangd1a324a2020-10-28 22:19:36 -07006637 iter->end = iter->p ? iter->p + table->size : NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006638}
6639
Haibo Huang40a71912019-10-11 11:13:39 -07006640static NAMED *FASTCALL
6641hashTableIterNext(HASH_TABLE_ITER *iter) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006642 while (iter->p != iter->end) {
6643 NAMED *tem = *(iter->p)++;
6644 if (tem)
6645 return tem;
6646 }
6647 return NULL;
6648}
6649
6650static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006651poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006652 pool->blocks = NULL;
6653 pool->freeBlocks = NULL;
6654 pool->start = NULL;
6655 pool->ptr = NULL;
6656 pool->end = NULL;
6657 pool->mem = ms;
6658}
6659
6660static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006661poolClear(STRING_POOL *pool) {
6662 if (! pool->freeBlocks)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006663 pool->freeBlocks = pool->blocks;
6664 else {
6665 BLOCK *p = pool->blocks;
6666 while (p) {
6667 BLOCK *tem = p->next;
6668 p->next = pool->freeBlocks;
6669 pool->freeBlocks = p;
6670 p = tem;
6671 }
6672 }
6673 pool->blocks = NULL;
6674 pool->start = NULL;
6675 pool->ptr = NULL;
6676 pool->end = NULL;
6677}
6678
6679static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006680poolDestroy(STRING_POOL *pool) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006681 BLOCK *p = pool->blocks;
6682 while (p) {
6683 BLOCK *tem = p->next;
6684 pool->mem->free_fcn(p);
6685 p = tem;
6686 }
6687 p = pool->freeBlocks;
6688 while (p) {
6689 BLOCK *tem = p->next;
6690 pool->mem->free_fcn(p);
6691 p = tem;
6692 }
6693}
6694
6695static XML_Char *
Haibo Huang40a71912019-10-11 11:13:39 -07006696poolAppend(STRING_POOL *pool, const ENCODING *enc, const char *ptr,
6697 const char *end) {
6698 if (! pool->ptr && ! poolGrow(pool))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006699 return NULL;
6700 for (;;) {
Haibo Huang40a71912019-10-11 11:13:39 -07006701 const enum XML_Convert_Result convert_res = XmlConvert(
6702 enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
6703 if ((convert_res == XML_CONVERT_COMPLETED)
6704 || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006705 break;
Haibo Huang40a71912019-10-11 11:13:39 -07006706 if (! poolGrow(pool))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006707 return NULL;
6708 }
6709 return pool->start;
6710}
6711
Haibo Huang40a71912019-10-11 11:13:39 -07006712static const XML_Char *FASTCALL
6713poolCopyString(STRING_POOL *pool, const XML_Char *s) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006714 do {
Haibo Huang40a71912019-10-11 11:13:39 -07006715 if (! poolAppendChar(pool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006716 return NULL;
6717 } while (*s++);
6718 s = pool->start;
6719 poolFinish(pool);
6720 return s;
6721}
6722
6723static const XML_Char *
Haibo Huang40a71912019-10-11 11:13:39 -07006724poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) {
6725 if (! pool->ptr && ! poolGrow(pool)) {
Elliott Hughes72472942018-01-10 08:36:10 -08006726 /* The following line is unreachable given the current usage of
6727 * poolCopyStringN(). Currently it is called from exactly one
6728 * place to copy the text of a simple general entity. By that
6729 * point, the name of the entity is already stored in the pool, so
6730 * pool->ptr cannot be NULL.
6731 *
6732 * If poolCopyStringN() is used elsewhere as it well might be,
6733 * this line may well become executable again. Regardless, this
6734 * sort of check shouldn't be removed lightly, so we just exclude
6735 * it from the coverage statistics.
6736 */
6737 return NULL; /* LCOV_EXCL_LINE */
6738 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006739 for (; n > 0; --n, s++) {
Haibo Huang40a71912019-10-11 11:13:39 -07006740 if (! poolAppendChar(pool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006741 return NULL;
6742 }
6743 s = pool->start;
6744 poolFinish(pool);
6745 return s;
6746}
6747
Haibo Huang40a71912019-10-11 11:13:39 -07006748static const XML_Char *FASTCALL
6749poolAppendString(STRING_POOL *pool, const XML_Char *s) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006750 while (*s) {
Haibo Huang40a71912019-10-11 11:13:39 -07006751 if (! poolAppendChar(pool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006752 return NULL;
6753 s++;
6754 }
6755 return pool->start;
6756}
6757
6758static XML_Char *
Haibo Huang40a71912019-10-11 11:13:39 -07006759poolStoreString(STRING_POOL *pool, const ENCODING *enc, const char *ptr,
6760 const char *end) {
6761 if (! poolAppend(pool, enc, ptr, end))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006762 return NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07006763 if (pool->ptr == pool->end && ! poolGrow(pool))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006764 return NULL;
6765 *(pool->ptr)++ = 0;
6766 return pool->start;
6767}
6768
Elliott Hughes72472942018-01-10 08:36:10 -08006769static size_t
Haibo Huang40a71912019-10-11 11:13:39 -07006770poolBytesToAllocateFor(int blockSize) {
Elliott Hughes72472942018-01-10 08:36:10 -08006771 /* Unprotected math would be:
6772 ** return offsetof(BLOCK, s) + blockSize * sizeof(XML_Char);
6773 **
6774 ** Detect overflow, avoiding _signed_ overflow undefined behavior
6775 ** For a + b * c we check b * c in isolation first, so that addition of a
6776 ** on top has no chance of making us accept a small non-negative number
6777 */
Haibo Huang40a71912019-10-11 11:13:39 -07006778 const size_t stretch = sizeof(XML_Char); /* can be 4 bytes */
Elliott Hughes72472942018-01-10 08:36:10 -08006779
6780 if (blockSize <= 0)
6781 return 0;
6782
6783 if (blockSize > (int)(INT_MAX / stretch))
6784 return 0;
6785
6786 {
6787 const int stretchedBlockSize = blockSize * (int)stretch;
Haibo Huang40a71912019-10-11 11:13:39 -07006788 const int bytesToAllocate
6789 = (int)(offsetof(BLOCK, s) + (unsigned)stretchedBlockSize);
Elliott Hughes72472942018-01-10 08:36:10 -08006790 if (bytesToAllocate < 0)
6791 return 0;
6792
6793 return (size_t)bytesToAllocate;
6794 }
6795}
6796
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006797static XML_Bool FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006798poolGrow(STRING_POOL *pool) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006799 if (pool->freeBlocks) {
6800 if (pool->start == 0) {
6801 pool->blocks = pool->freeBlocks;
6802 pool->freeBlocks = pool->freeBlocks->next;
6803 pool->blocks->next = NULL;
6804 pool->start = pool->blocks->s;
6805 pool->end = pool->start + pool->blocks->size;
6806 pool->ptr = pool->start;
6807 return XML_TRUE;
6808 }
6809 if (pool->end - pool->start < pool->freeBlocks->size) {
6810 BLOCK *tem = pool->freeBlocks->next;
6811 pool->freeBlocks->next = pool->blocks;
6812 pool->blocks = pool->freeBlocks;
6813 pool->freeBlocks = tem;
6814 memcpy(pool->blocks->s, pool->start,
6815 (pool->end - pool->start) * sizeof(XML_Char));
6816 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
6817 pool->start = pool->blocks->s;
6818 pool->end = pool->start + pool->blocks->size;
6819 return XML_TRUE;
6820 }
6821 }
6822 if (pool->blocks && pool->start == pool->blocks->s) {
Paul Duffin4bf8f122016-05-13 12:35:25 +01006823 BLOCK *temp;
Haibo Huang40a71912019-10-11 11:13:39 -07006824 int blockSize = (int)((unsigned)(pool->end - pool->start) * 2U);
Elliott Hughes72472942018-01-10 08:36:10 -08006825 size_t bytesToAllocate;
Paul Duffin4bf8f122016-05-13 12:35:25 +01006826
Elliott Hughes72472942018-01-10 08:36:10 -08006827 /* NOTE: Needs to be calculated prior to calling `realloc`
6828 to avoid dangling pointers: */
6829 const ptrdiff_t offsetInsideBlock = pool->ptr - pool->start;
6830
6831 if (blockSize < 0) {
6832 /* This condition traps a situation where either more than
6833 * INT_MAX/2 bytes have already been allocated. This isn't
6834 * readily testable, since it is unlikely that an average
6835 * machine will have that much memory, so we exclude it from the
6836 * coverage statistics.
6837 */
6838 return XML_FALSE; /* LCOV_EXCL_LINE */
6839 }
6840
6841 bytesToAllocate = poolBytesToAllocateFor(blockSize);
6842 if (bytesToAllocate == 0)
Paul Duffin4bf8f122016-05-13 12:35:25 +01006843 return XML_FALSE;
6844
Haibo Huang40a71912019-10-11 11:13:39 -07006845 temp = (BLOCK *)pool->mem->realloc_fcn(pool->blocks,
6846 (unsigned)bytesToAllocate);
Elliott Hughes35e432d2012-09-09 14:23:38 -07006847 if (temp == NULL)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006848 return XML_FALSE;
Elliott Hughes35e432d2012-09-09 14:23:38 -07006849 pool->blocks = temp;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006850 pool->blocks->size = blockSize;
Elliott Hughes72472942018-01-10 08:36:10 -08006851 pool->ptr = pool->blocks->s + offsetInsideBlock;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006852 pool->start = pool->blocks->s;
6853 pool->end = pool->start + blockSize;
Haibo Huang40a71912019-10-11 11:13:39 -07006854 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006855 BLOCK *tem;
6856 int blockSize = (int)(pool->end - pool->start);
Elliott Hughes72472942018-01-10 08:36:10 -08006857 size_t bytesToAllocate;
Paul Duffin4bf8f122016-05-13 12:35:25 +01006858
Elliott Hughes72472942018-01-10 08:36:10 -08006859 if (blockSize < 0) {
6860 /* This condition traps a situation where either more than
6861 * INT_MAX bytes have already been allocated (which is prevented
6862 * by various pieces of program logic, not least this one, never
6863 * mind the unlikelihood of actually having that much memory) or
6864 * the pool control fields have been corrupted (which could
6865 * conceivably happen in an extremely buggy user handler
6866 * function). Either way it isn't readily testable, so we
6867 * exclude it from the coverage statistics.
6868 */
Haibo Huang40a71912019-10-11 11:13:39 -07006869 return XML_FALSE; /* LCOV_EXCL_LINE */
Elliott Hughes72472942018-01-10 08:36:10 -08006870 }
Paul Duffin4bf8f122016-05-13 12:35:25 +01006871
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006872 if (blockSize < INIT_BLOCK_SIZE)
6873 blockSize = INIT_BLOCK_SIZE;
Elliott Hughes72472942018-01-10 08:36:10 -08006874 else {
6875 /* Detect overflow, avoiding _signed_ overflow undefined behavior */
6876 if ((int)((unsigned)blockSize * 2U) < 0) {
6877 return XML_FALSE;
6878 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006879 blockSize *= 2;
Elliott Hughes72472942018-01-10 08:36:10 -08006880 }
6881
6882 bytesToAllocate = poolBytesToAllocateFor(blockSize);
6883 if (bytesToAllocate == 0)
6884 return XML_FALSE;
6885
6886 tem = (BLOCK *)pool->mem->malloc_fcn(bytesToAllocate);
Haibo Huang40a71912019-10-11 11:13:39 -07006887 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006888 return XML_FALSE;
6889 tem->size = blockSize;
6890 tem->next = pool->blocks;
6891 pool->blocks = tem;
6892 if (pool->ptr != pool->start)
Haibo Huang40a71912019-10-11 11:13:39 -07006893 memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006894 pool->ptr = tem->s + (pool->ptr - pool->start);
6895 pool->start = tem->s;
6896 pool->end = tem->s + blockSize;
6897 }
6898 return XML_TRUE;
6899}
6900
6901static int FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006902nextScaffoldPart(XML_Parser parser) {
6903 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
6904 CONTENT_SCAFFOLD *me;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006905 int next;
6906
Haibo Huang40a71912019-10-11 11:13:39 -07006907 if (! dtd->scaffIndex) {
Elliott Hughes72472942018-01-10 08:36:10 -08006908 dtd->scaffIndex = (int *)MALLOC(parser, parser->m_groupSize * sizeof(int));
Haibo Huang40a71912019-10-11 11:13:39 -07006909 if (! dtd->scaffIndex)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006910 return -1;
6911 dtd->scaffIndex[0] = 0;
6912 }
6913
6914 if (dtd->scaffCount >= dtd->scaffSize) {
6915 CONTENT_SCAFFOLD *temp;
6916 if (dtd->scaffold) {
Sadaf Ebrahimif68f6852022-06-15 04:14:33 +00006917 /* Detect and prevent integer overflow */
6918 if (dtd->scaffSize > UINT_MAX / 2u) {
6919 return -1;
6920 }
6921 /* Detect and prevent integer overflow.
6922 * The preprocessor guard addresses the "always false" warning
6923 * from -Wtype-limits on platforms where
6924 * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
6925#if UINT_MAX >= SIZE_MAX
6926 if (dtd->scaffSize > (size_t)(-1) / 2u / sizeof(CONTENT_SCAFFOLD)) {
6927 return -1;
6928 }
6929#endif
6930
Haibo Huang40a71912019-10-11 11:13:39 -07006931 temp = (CONTENT_SCAFFOLD *)REALLOC(
6932 parser, dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006933 if (temp == NULL)
6934 return -1;
6935 dtd->scaffSize *= 2;
Haibo Huang40a71912019-10-11 11:13:39 -07006936 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08006937 temp = (CONTENT_SCAFFOLD *)MALLOC(parser, INIT_SCAFFOLD_ELEMENTS
Haibo Huang40a71912019-10-11 11:13:39 -07006938 * sizeof(CONTENT_SCAFFOLD));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006939 if (temp == NULL)
6940 return -1;
6941 dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
6942 }
6943 dtd->scaffold = temp;
6944 }
6945 next = dtd->scaffCount++;
6946 me = &dtd->scaffold[next];
6947 if (dtd->scaffLevel) {
Haibo Huang40a71912019-10-11 11:13:39 -07006948 CONTENT_SCAFFOLD *parent
6949 = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]];
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006950 if (parent->lastchild) {
6951 dtd->scaffold[parent->lastchild].nextsib = next;
6952 }
Haibo Huang40a71912019-10-11 11:13:39 -07006953 if (! parent->childcnt)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006954 parent->firstchild = next;
6955 parent->lastchild = next;
6956 parent->childcnt++;
6957 }
6958 me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
6959 return next;
6960}
6961
6962static void
Haibo Huang40a71912019-10-11 11:13:39 -07006963build_node(XML_Parser parser, int src_node, XML_Content *dest,
6964 XML_Content **contpos, XML_Char **strpos) {
6965 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006966 dest->type = dtd->scaffold[src_node].type;
6967 dest->quant = dtd->scaffold[src_node].quant;
6968 if (dest->type == XML_CTYPE_NAME) {
6969 const XML_Char *src;
6970 dest->name = *strpos;
6971 src = dtd->scaffold[src_node].name;
6972 for (;;) {
6973 *(*strpos)++ = *src;
Haibo Huang40a71912019-10-11 11:13:39 -07006974 if (! *src)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006975 break;
6976 src++;
6977 }
6978 dest->numchildren = 0;
6979 dest->children = NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07006980 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006981 unsigned int i;
6982 int cn;
6983 dest->numchildren = dtd->scaffold[src_node].childcnt;
6984 dest->children = *contpos;
6985 *contpos += dest->numchildren;
Haibo Huang40a71912019-10-11 11:13:39 -07006986 for (i = 0, cn = dtd->scaffold[src_node].firstchild; i < dest->numchildren;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006987 i++, cn = dtd->scaffold[cn].nextsib) {
6988 build_node(parser, cn, &(dest->children[i]), contpos, strpos);
6989 }
6990 dest->name = NULL;
6991 }
6992}
6993
6994static XML_Content *
Haibo Huang40a71912019-10-11 11:13:39 -07006995build_model(XML_Parser parser) {
6996 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006997 XML_Content *ret;
6998 XML_Content *cpos;
Haibo Huang40a71912019-10-11 11:13:39 -07006999 XML_Char *str;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08007000
Sadaf Ebrahimif68f6852022-06-15 04:14:33 +00007001 /* Detect and prevent integer overflow.
7002 * The preprocessor guard addresses the "always false" warning
7003 * from -Wtype-limits on platforms where
7004 * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
7005#if UINT_MAX >= SIZE_MAX
7006 if (dtd->scaffCount > (size_t)(-1) / sizeof(XML_Content)) {
7007 return NULL;
7008 }
7009 if (dtd->contentStringLen > (size_t)(-1) / sizeof(XML_Char)) {
7010 return NULL;
7011 }
7012#endif
7013 if (dtd->scaffCount * sizeof(XML_Content)
7014 > (size_t)(-1) - dtd->contentStringLen * sizeof(XML_Char)) {
7015 return NULL;
7016 }
7017
7018 const size_t allocsize = (dtd->scaffCount * sizeof(XML_Content)
7019 + (dtd->contentStringLen * sizeof(XML_Char)));
Elliott Hughes72472942018-01-10 08:36:10 -08007020 ret = (XML_Content *)MALLOC(parser, allocsize);
Haibo Huang40a71912019-10-11 11:13:39 -07007021 if (! ret)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08007022 return NULL;
7023
Haibo Huang40a71912019-10-11 11:13:39 -07007024 str = (XML_Char *)(&ret[dtd->scaffCount]);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08007025 cpos = &ret[1];
7026
7027 build_node(parser, 0, ret, &cpos, &str);
7028 return ret;
7029}
7030
7031static ELEMENT_TYPE *
Haibo Huang40a71912019-10-11 11:13:39 -07007032getElementType(XML_Parser parser, const ENCODING *enc, const char *ptr,
7033 const char *end) {
7034 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08007035 const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
7036 ELEMENT_TYPE *ret;
7037
Haibo Huang40a71912019-10-11 11:13:39 -07007038 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08007039 return NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07007040 ret = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
7041 sizeof(ELEMENT_TYPE));
7042 if (! ret)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08007043 return NULL;
7044 if (ret->name != name)
7045 poolDiscard(&dtd->pool);
7046 else {
7047 poolFinish(&dtd->pool);
Haibo Huang40a71912019-10-11 11:13:39 -07007048 if (! setElementTypePrefix(parser, ret))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08007049 return NULL;
7050 }
7051 return ret;
7052}
Elliott Hughes72472942018-01-10 08:36:10 -08007053
7054static XML_Char *
Haibo Huang40a71912019-10-11 11:13:39 -07007055copyString(const XML_Char *s, const XML_Memory_Handling_Suite *memsuite) {
Sadaf Ebrahimi1adbf372022-05-23 22:34:43 +00007056 size_t charsRequired = 0;
Haibo Huang40a71912019-10-11 11:13:39 -07007057 XML_Char *result;
Elliott Hughes72472942018-01-10 08:36:10 -08007058
Haibo Huang40a71912019-10-11 11:13:39 -07007059 /* First determine how long the string is */
7060 while (s[charsRequired] != 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08007061 charsRequired++;
Haibo Huang40a71912019-10-11 11:13:39 -07007062 }
7063 /* Include the terminator */
7064 charsRequired++;
Elliott Hughes72472942018-01-10 08:36:10 -08007065
Haibo Huang40a71912019-10-11 11:13:39 -07007066 /* Now allocate space for the copy */
7067 result = memsuite->malloc_fcn(charsRequired * sizeof(XML_Char));
7068 if (result == NULL)
7069 return NULL;
7070 /* Copy the original into place */
7071 memcpy(result, s, charsRequired * sizeof(XML_Char));
7072 return result;
Elliott Hughes72472942018-01-10 08:36:10 -08007073}