blob: 3aaf35b94b1d151dd340a7bfc7937a115b6dff2b [file] [log] [blame]
Haibo Huang40a71912019-10-11 11:13:39 -07001/* f519f27c7c3b79fee55aeb8b1e53b7384b079d9118bf3a62eb3a60986a6742f2 (2.2.9+)
Elliott Hughes72472942018-01-10 08:36:10 -08002 __ __ _
3 ___\ \/ /_ __ __ _| |_
4 / _ \\ /| '_ \ / _` | __|
5 | __// \| |_) | (_| | |_
6 \___/_/\_\ .__/ \__,_|\__|
7 |_| XML parser
8
9 Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
10 Copyright (c) 2000-2017 Expat development team
11 Licensed under the MIT license:
12
13 Permission is hereby granted, free of charge, to any person obtaining
14 a copy of this software and associated documentation files (the
15 "Software"), to deal in the Software without restriction, including
16 without limitation the rights to use, copy, modify, merge, publish,
17 distribute, sublicense, and/or sell copies of the Software, and to permit
18 persons to whom the Software is furnished to do so, subject to the
19 following conditions:
20
21 The above copyright notice and this permission notice shall be included
22 in all copies or substantial portions of the Software.
23
24 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
27 NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
28 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
29 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
30 USE OR OTHER DEALINGS IN THE SOFTWARE.
The Android Open Source Projectb80e2872009-03-03 19:29:30 -080031*/
32
Haibo Huang40a71912019-10-11 11:13:39 -070033#if ! defined(_GNU_SOURCE)
34# define _GNU_SOURCE 1 /* syscall prototype */
35#endif
36
37#ifdef _WIN32
38/* force stdlib to define rand_s() */
39# if ! defined(_CRT_RAND_S)
40# define _CRT_RAND_S
41# endif
Elliott Hughes72472942018-01-10 08:36:10 -080042#endif
43
The Android Open Source Projectb80e2872009-03-03 19:29:30 -080044#include <stddef.h>
Haibo Huang40a71912019-10-11 11:13:39 -070045#include <string.h> /* memset(), memcpy() */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -080046#include <assert.h>
Haibo Huang40a71912019-10-11 11:13:39 -070047#include <limits.h> /* UINT_MAX */
48#include <stdio.h> /* fprintf */
49#include <stdlib.h> /* getenv, rand_s */
Paul Duffin3c2f09e2016-06-07 15:53:38 +010050
Elliott Hughes72472942018-01-10 08:36:10 -080051#ifdef _WIN32
Haibo Huang40a71912019-10-11 11:13:39 -070052# define getpid GetCurrentProcessId
Paul Duffin3c2f09e2016-06-07 15:53:38 +010053#else
Haibo Huang40a71912019-10-11 11:13:39 -070054# include <sys/time.h> /* gettimeofday() */
55# include <sys/types.h> /* getpid() */
56# include <unistd.h> /* getpid() */
57# include <fcntl.h> /* O_RDONLY */
58# include <errno.h>
Paul Duffin3c2f09e2016-06-07 15:53:38 +010059#endif
The Android Open Source Projectb80e2872009-03-03 19:29:30 -080060
61#define XML_BUILDING_EXPAT 1
62
Elliott Hughes72472942018-01-10 08:36:10 -080063#ifdef _WIN32
Haibo Huang40a71912019-10-11 11:13:39 -070064# include "winconfig.h"
The Android Open Source Projectb80e2872009-03-03 19:29:30 -080065#elif defined(HAVE_EXPAT_CONFIG_H)
Haibo Huang40a71912019-10-11 11:13:39 -070066# include <expat_config.h>
Elliott Hughes72472942018-01-10 08:36:10 -080067#endif /* ndef _WIN32 */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -080068
Elliott Hughesd07d5a72009-09-25 16:04:37 -070069#include "ascii.h"
The Android Open Source Projectb80e2872009-03-03 19:29:30 -080070#include "expat.h"
Elliott Hughes72472942018-01-10 08:36:10 -080071#include "siphash.h"
72
73#if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
Haibo Huang40a71912019-10-11 11:13:39 -070074# if defined(HAVE_GETRANDOM)
75# include <sys/random.h> /* getrandom */
76# else
77# include <unistd.h> /* syscall */
78# include <sys/syscall.h> /* SYS_getrandom */
79# endif
80# if ! defined(GRND_NONBLOCK)
81# define GRND_NONBLOCK 0x0001
82# endif /* defined(GRND_NONBLOCK) */
83#endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */
Elliott Hughes72472942018-01-10 08:36:10 -080084
Haibo Huang40a71912019-10-11 11:13:39 -070085#if defined(HAVE_LIBBSD) \
Elliott Hughes72472942018-01-10 08:36:10 -080086 && (defined(HAVE_ARC4RANDOM_BUF) || defined(HAVE_ARC4RANDOM))
Haibo Huang40a71912019-10-11 11:13:39 -070087# include <bsd/stdlib.h>
Elliott Hughes72472942018-01-10 08:36:10 -080088#endif
89
Haibo Huang40a71912019-10-11 11:13:39 -070090#if defined(_WIN32) && ! defined(LOAD_LIBRARY_SEARCH_SYSTEM32)
91# define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800
Elliott Hughes72472942018-01-10 08:36:10 -080092#endif
93
Haibo Huang40a71912019-10-11 11:13:39 -070094#if ! defined(HAVE_GETRANDOM) && ! defined(HAVE_SYSCALL_GETRANDOM) \
95 && ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) \
96 && ! defined(XML_DEV_URANDOM) && ! defined(_WIN32) \
97 && ! defined(XML_POOR_ENTROPY)
98# error You do not have support for any sources of high quality entropy \
Elliott Hughes72472942018-01-10 08:36:10 -080099 enabled. For end user security, that is probably not what you want. \
100 \
101 Your options include: \
102 * Linux + glibc >=2.25 (getrandom): HAVE_GETRANDOM, \
103 * Linux + glibc <2.25 (syscall SYS_getrandom): HAVE_SYSCALL_GETRANDOM, \
104 * BSD / macOS >=10.7 (arc4random_buf): HAVE_ARC4RANDOM_BUF, \
105 * BSD / macOS <10.7 (arc4random): HAVE_ARC4RANDOM, \
106 * libbsd (arc4random_buf): HAVE_ARC4RANDOM_BUF + HAVE_LIBBSD, \
107 * libbsd (arc4random): HAVE_ARC4RANDOM + HAVE_LIBBSD, \
108 * Linux / BSD / macOS (/dev/urandom): XML_DEV_URANDOM \
Haibo Huang40a71912019-10-11 11:13:39 -0700109 * Windows (rand_s): _WIN32. \
Elliott Hughes72472942018-01-10 08:36:10 -0800110 \
111 If insist on not using any of these, bypass this error by defining \
112 XML_POOR_ENTROPY; you have been warned. \
113 \
114 If you have reasons to patch this detection code away or need changes \
115 to the build system, please open a bug. Thank you!
116#endif
117
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800118#ifdef XML_UNICODE
Haibo Huang40a71912019-10-11 11:13:39 -0700119# define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
120# define XmlConvert XmlUtf16Convert
121# define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
122# define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
123# define XmlEncode XmlUtf16Encode
Elliott Hughesd07d5a72009-09-25 16:04:37 -0700124/* Using pointer subtraction to convert to integer type. */
Haibo Huang40a71912019-10-11 11:13:39 -0700125# define MUST_CONVERT(enc, s) \
126 (! (enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800127typedef unsigned short ICHAR;
128#else
Haibo Huang40a71912019-10-11 11:13:39 -0700129# define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
130# define XmlConvert XmlUtf8Convert
131# define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
132# define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
133# define XmlEncode XmlUtf8Encode
134# define MUST_CONVERT(enc, s) (! (enc)->isUtf8)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800135typedef char ICHAR;
136#endif
137
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800138#ifndef XML_NS
139
Haibo Huang40a71912019-10-11 11:13:39 -0700140# define XmlInitEncodingNS XmlInitEncoding
141# define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
142# undef XmlGetInternalEncodingNS
143# define XmlGetInternalEncodingNS XmlGetInternalEncoding
144# define XmlParseXmlDeclNS XmlParseXmlDecl
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800145
146#endif
147
148#ifdef XML_UNICODE
149
Haibo Huang40a71912019-10-11 11:13:39 -0700150# ifdef XML_UNICODE_WCHAR_T
151# define XML_T(x) (const wchar_t) x
152# define XML_L(x) L##x
153# else
154# define XML_T(x) (const unsigned short)x
155# define XML_L(x) x
156# endif
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800157
158#else
159
Haibo Huang40a71912019-10-11 11:13:39 -0700160# define XML_T(x) x
161# define XML_L(x) x
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800162
163#endif
164
165/* Round up n to be a multiple of sz, where sz is a power of 2. */
Haibo Huang40a71912019-10-11 11:13:39 -0700166#define ROUND_UP(n, sz) (((n) + ((sz)-1)) & ~((sz)-1))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800167
Elliott Hughesaaec48e2018-08-16 16:29:01 -0700168/* Do safe (NULL-aware) pointer arithmetic */
169#define EXPAT_SAFE_PTR_DIFF(p, q) (((p) && (q)) ? ((p) - (q)) : 0)
170
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800171#include "internal.h"
172#include "xmltok.h"
173#include "xmlrole.h"
174
175typedef const XML_Char *KEY;
176
177typedef struct {
178 KEY name;
179} NAMED;
180
181typedef struct {
182 NAMED **v;
183 unsigned char power;
184 size_t size;
185 size_t used;
186 const XML_Memory_Handling_Suite *mem;
187} HASH_TABLE;
188
Haibo Huang40a71912019-10-11 11:13:39 -0700189static size_t keylen(KEY s);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800190
Haibo Huang40a71912019-10-11 11:13:39 -0700191static void copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800192
193/* For probing (after a collision) we need a step size relative prime
194 to the hash table size, which is a power of 2. We use double-hashing,
195 since we can calculate a second hash value cheaply by taking those bits
196 of the first hash value that were discarded (masked out) when the table
197 index was calculated: index = hash & mask, where mask = table->size - 1.
198 We limit the maximum step size to table->size / 4 (mask >> 2) and make
199 it odd, since odd numbers are always relative prime to a power of 2.
200*/
Haibo Huang40a71912019-10-11 11:13:39 -0700201#define SECOND_HASH(hash, mask, power) \
202 ((((hash) & ~(mask)) >> ((power)-1)) & ((mask) >> 2))
203#define PROBE_STEP(hash, mask, power) \
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800204 ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
205
206typedef struct {
207 NAMED **p;
208 NAMED **end;
209} HASH_TABLE_ITER;
210
Haibo Huang40a71912019-10-11 11:13:39 -0700211#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800212#define INIT_DATA_BUF_SIZE 1024
213#define INIT_ATTS_SIZE 16
214#define INIT_ATTS_VERSION 0xFFFFFFFF
215#define INIT_BLOCK_SIZE 1024
216#define INIT_BUFFER_SIZE 1024
217
218#define EXPAND_SPARE 24
219
220typedef struct binding {
221 struct prefix *prefix;
222 struct binding *nextTagBinding;
223 struct binding *prevPrefixBinding;
224 const struct attribute_id *attId;
225 XML_Char *uri;
226 int uriLen;
227 int uriAlloc;
228} BINDING;
229
230typedef struct prefix {
231 const XML_Char *name;
232 BINDING *binding;
233} PREFIX;
234
235typedef struct {
236 const XML_Char *str;
237 const XML_Char *localPart;
238 const XML_Char *prefix;
239 int strLen;
240 int uriLen;
241 int prefixLen;
242} TAG_NAME;
243
244/* TAG represents an open element.
245 The name of the element is stored in both the document and API
246 encodings. The memory buffer 'buf' is a separately-allocated
247 memory area which stores the name. During the XML_Parse()/
248 XMLParseBuffer() when the element is open, the memory for the 'raw'
249 version of the name (in the document encoding) is shared with the
250 document buffer. If the element is open across calls to
251 XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
252 contain the 'raw' name as well.
253
254 A parser re-uses these structures, maintaining a list of allocated
255 TAG objects in a free list.
256*/
257typedef struct tag {
Haibo Huang40a71912019-10-11 11:13:39 -0700258 struct tag *parent; /* parent of this element */
259 const char *rawName; /* tagName in the original encoding */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800260 int rawNameLength;
Haibo Huang40a71912019-10-11 11:13:39 -0700261 TAG_NAME name; /* tagName in the API encoding */
262 char *buf; /* buffer for name components */
263 char *bufEnd; /* end of the buffer */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800264 BINDING *bindings;
265} TAG;
266
267typedef struct {
268 const XML_Char *name;
269 const XML_Char *textPtr;
Haibo Huang40a71912019-10-11 11:13:39 -0700270 int textLen; /* length in XML_Chars */
271 int processed; /* # of processed bytes - when suspended */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800272 const XML_Char *systemId;
273 const XML_Char *base;
274 const XML_Char *publicId;
275 const XML_Char *notation;
276 XML_Bool open;
277 XML_Bool is_param;
278 XML_Bool is_internal; /* true if declared in internal subset outside PE */
279} ENTITY;
280
281typedef struct {
Haibo Huang40a71912019-10-11 11:13:39 -0700282 enum XML_Content_Type type;
283 enum XML_Content_Quant quant;
284 const XML_Char *name;
285 int firstchild;
286 int lastchild;
287 int childcnt;
288 int nextsib;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800289} CONTENT_SCAFFOLD;
290
291#define INIT_SCAFFOLD_ELEMENTS 32
292
293typedef struct block {
294 struct block *next;
295 int size;
296 XML_Char s[1];
297} BLOCK;
298
299typedef struct {
300 BLOCK *blocks;
301 BLOCK *freeBlocks;
302 const XML_Char *end;
303 XML_Char *ptr;
304 XML_Char *start;
305 const XML_Memory_Handling_Suite *mem;
306} STRING_POOL;
307
308/* The XML_Char before the name is used to determine whether
309 an attribute has been specified. */
310typedef struct attribute_id {
311 XML_Char *name;
312 PREFIX *prefix;
313 XML_Bool maybeTokenized;
314 XML_Bool xmlns;
315} ATTRIBUTE_ID;
316
317typedef struct {
318 const ATTRIBUTE_ID *id;
319 XML_Bool isCdata;
320 const XML_Char *value;
321} DEFAULT_ATTRIBUTE;
322
323typedef struct {
324 unsigned long version;
325 unsigned long hash;
326 const XML_Char *uriName;
327} NS_ATT;
328
329typedef struct {
330 const XML_Char *name;
331 PREFIX *prefix;
332 const ATTRIBUTE_ID *idAtt;
333 int nDefaultAtts;
334 int allocDefaultAtts;
335 DEFAULT_ATTRIBUTE *defaultAtts;
336} ELEMENT_TYPE;
337
338typedef struct {
339 HASH_TABLE generalEntities;
340 HASH_TABLE elementTypes;
341 HASH_TABLE attributeIds;
342 HASH_TABLE prefixes;
343 STRING_POOL pool;
344 STRING_POOL entityValuePool;
345 /* false once a parameter entity reference has been skipped */
346 XML_Bool keepProcessing;
347 /* true once an internal or external PE reference has been encountered;
348 this includes the reference to an external subset */
349 XML_Bool hasParamEntityRefs;
350 XML_Bool standalone;
351#ifdef XML_DTD
352 /* indicates if external PE has been read */
353 XML_Bool paramEntityRead;
354 HASH_TABLE paramEntities;
355#endif /* XML_DTD */
356 PREFIX defaultPrefix;
357 /* === scaffolding for building content model === */
358 XML_Bool in_eldecl;
359 CONTENT_SCAFFOLD *scaffold;
360 unsigned contentStringLen;
361 unsigned scaffSize;
362 unsigned scaffCount;
363 int scaffLevel;
364 int *scaffIndex;
365} DTD;
366
367typedef struct open_internal_entity {
368 const char *internalEventPtr;
369 const char *internalEventEndPtr;
370 struct open_internal_entity *next;
371 ENTITY *entity;
372 int startTagLevel;
373 XML_Bool betweenDecl; /* WFC: PE Between Declarations */
374} OPEN_INTERNAL_ENTITY;
375
Haibo Huang40a71912019-10-11 11:13:39 -0700376typedef enum XML_Error PTRCALL Processor(XML_Parser parser, const char *start,
377 const char *end, const char **endPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800378
379static Processor prologProcessor;
380static Processor prologInitProcessor;
381static Processor contentProcessor;
382static Processor cdataSectionProcessor;
383#ifdef XML_DTD
384static Processor ignoreSectionProcessor;
385static Processor externalParEntProcessor;
386static Processor externalParEntInitProcessor;
387static Processor entityValueProcessor;
388static Processor entityValueInitProcessor;
389#endif /* XML_DTD */
390static Processor epilogProcessor;
391static Processor errorProcessor;
392static Processor externalEntityInitProcessor;
393static Processor externalEntityInitProcessor2;
394static Processor externalEntityInitProcessor3;
395static Processor externalEntityContentProcessor;
396static Processor internalEntityProcessor;
397
Haibo Huang40a71912019-10-11 11:13:39 -0700398static enum XML_Error handleUnknownEncoding(XML_Parser parser,
399 const XML_Char *encodingName);
400static enum XML_Error processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
401 const char *s, const char *next);
402static enum XML_Error initializeEncoding(XML_Parser parser);
403static enum XML_Error doProlog(XML_Parser parser, const ENCODING *enc,
404 const char *s, const char *end, int tok,
405 const char *next, const char **nextPtr,
406 XML_Bool haveMore, XML_Bool allowClosingDoctype);
407static enum XML_Error processInternalEntity(XML_Parser parser, ENTITY *entity,
408 XML_Bool betweenDecl);
409static enum XML_Error doContent(XML_Parser parser, int startTagLevel,
410 const ENCODING *enc, const char *start,
411 const char *end, const char **endPtr,
412 XML_Bool haveMore);
413static enum XML_Error doCdataSection(XML_Parser parser, const ENCODING *,
414 const char **startPtr, const char *end,
415 const char **nextPtr, XML_Bool haveMore);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800416#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -0700417static enum XML_Error doIgnoreSection(XML_Parser parser, const ENCODING *,
418 const char **startPtr, const char *end,
419 const char **nextPtr, XML_Bool haveMore);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800420#endif /* XML_DTD */
421
Haibo Huang40a71912019-10-11 11:13:39 -0700422static void freeBindings(XML_Parser parser, BINDING *bindings);
423static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *,
424 const char *s, TAG_NAME *tagNamePtr,
425 BINDING **bindingsPtr);
426static enum XML_Error addBinding(XML_Parser parser, PREFIX *prefix,
427 const ATTRIBUTE_ID *attId, const XML_Char *uri,
428 BINDING **bindingsPtr);
429static int defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
430 XML_Bool isId, const XML_Char *dfltValue,
431 XML_Parser parser);
432static enum XML_Error storeAttributeValue(XML_Parser parser, const ENCODING *,
433 XML_Bool isCdata, const char *,
434 const char *, STRING_POOL *);
435static enum XML_Error appendAttributeValue(XML_Parser parser, const ENCODING *,
436 XML_Bool isCdata, const char *,
437 const char *, STRING_POOL *);
438static ATTRIBUTE_ID *getAttributeId(XML_Parser parser, const ENCODING *enc,
439 const char *start, const char *end);
440static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
441static enum XML_Error storeEntityValue(XML_Parser parser, const ENCODING *enc,
442 const char *start, const char *end);
443static int reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
444 const char *start, const char *end);
445static int reportComment(XML_Parser parser, const ENCODING *enc,
446 const char *start, const char *end);
447static void reportDefault(XML_Parser parser, const ENCODING *enc,
448 const char *start, const char *end);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800449
Haibo Huang40a71912019-10-11 11:13:39 -0700450static const XML_Char *getContext(XML_Parser parser);
451static XML_Bool setContext(XML_Parser parser, const XML_Char *context);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800452
453static void FASTCALL normalizePublicId(XML_Char *s);
454
Haibo Huang40a71912019-10-11 11:13:39 -0700455static DTD *dtdCreate(const XML_Memory_Handling_Suite *ms);
Elliott Hughes72472942018-01-10 08:36:10 -0800456/* do not call if m_parentParser != NULL */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800457static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
Haibo Huang40a71912019-10-11 11:13:39 -0700458static void dtdDestroy(DTD *p, XML_Bool isDocEntity,
459 const XML_Memory_Handling_Suite *ms);
460static int dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
461 const XML_Memory_Handling_Suite *ms);
462static int copyEntityTable(XML_Parser oldParser, HASH_TABLE *, STRING_POOL *,
463 const HASH_TABLE *);
464static NAMED *lookup(XML_Parser parser, HASH_TABLE *table, KEY name,
465 size_t createSize);
466static void FASTCALL hashTableInit(HASH_TABLE *,
467 const XML_Memory_Handling_Suite *ms);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800468static void FASTCALL hashTableClear(HASH_TABLE *);
469static void FASTCALL hashTableDestroy(HASH_TABLE *);
Haibo Huang40a71912019-10-11 11:13:39 -0700470static void FASTCALL hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
471static NAMED *FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800472
Haibo Huang40a71912019-10-11 11:13:39 -0700473static void FASTCALL poolInit(STRING_POOL *,
474 const XML_Memory_Handling_Suite *ms);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800475static void FASTCALL poolClear(STRING_POOL *);
476static void FASTCALL poolDestroy(STRING_POOL *);
Haibo Huang40a71912019-10-11 11:13:39 -0700477static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
478 const char *ptr, const char *end);
479static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
480 const char *ptr, const char *end);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800481static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
Haibo Huang40a71912019-10-11 11:13:39 -0700482static const XML_Char *FASTCALL poolCopyString(STRING_POOL *pool,
483 const XML_Char *s);
484static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s,
485 int n);
486static const XML_Char *FASTCALL poolAppendString(STRING_POOL *pool,
487 const XML_Char *s);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800488
489static int FASTCALL nextScaffoldPart(XML_Parser parser);
Haibo Huang40a71912019-10-11 11:13:39 -0700490static XML_Content *build_model(XML_Parser parser);
491static ELEMENT_TYPE *getElementType(XML_Parser parser, const ENCODING *enc,
492 const char *ptr, const char *end);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800493
Elliott Hughes72472942018-01-10 08:36:10 -0800494static XML_Char *copyString(const XML_Char *s,
495 const XML_Memory_Handling_Suite *memsuite);
496
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100497static unsigned long generate_hash_secret_salt(XML_Parser parser);
Elliott Hughes35e432d2012-09-09 14:23:38 -0700498static XML_Bool startParsing(XML_Parser parser);
499
Haibo Huang40a71912019-10-11 11:13:39 -0700500static XML_Parser parserCreate(const XML_Char *encodingName,
501 const XML_Memory_Handling_Suite *memsuite,
502 const XML_Char *nameSep, DTD *dtd);
Elliott Hughes35e432d2012-09-09 14:23:38 -0700503
Haibo Huang40a71912019-10-11 11:13:39 -0700504static void parserInit(XML_Parser parser, const XML_Char *encodingName);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800505
506#define poolStart(pool) ((pool)->start)
507#define poolEnd(pool) ((pool)->ptr)
508#define poolLength(pool) ((pool)->ptr - (pool)->start)
509#define poolChop(pool) ((void)--(pool->ptr))
510#define poolLastChar(pool) (((pool)->ptr)[-1])
511#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
512#define poolFinish(pool) ((pool)->start = (pool)->ptr)
Haibo Huang40a71912019-10-11 11:13:39 -0700513#define poolAppendChar(pool, c) \
514 (((pool)->ptr == (pool)->end && ! poolGrow(pool)) \
515 ? 0 \
516 : ((*((pool)->ptr)++ = c), 1))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800517
518struct XML_ParserStruct {
Elliott Hughes72472942018-01-10 08:36:10 -0800519 /* The first member must be m_userData so that the XML_GetUserData
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800520 macro works. */
521 void *m_userData;
522 void *m_handlerArg;
523 char *m_buffer;
524 const XML_Memory_Handling_Suite m_mem;
525 /* first character to be parsed */
526 const char *m_bufferPtr;
527 /* past last character to be parsed */
528 char *m_bufferEnd;
Elliott Hughes72472942018-01-10 08:36:10 -0800529 /* allocated end of m_buffer */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800530 const char *m_bufferLim;
531 XML_Index m_parseEndByteIndex;
532 const char *m_parseEndPtr;
533 XML_Char *m_dataBuf;
534 XML_Char *m_dataBufEnd;
535 XML_StartElementHandler m_startElementHandler;
536 XML_EndElementHandler m_endElementHandler;
537 XML_CharacterDataHandler m_characterDataHandler;
538 XML_ProcessingInstructionHandler m_processingInstructionHandler;
539 XML_CommentHandler m_commentHandler;
540 XML_StartCdataSectionHandler m_startCdataSectionHandler;
541 XML_EndCdataSectionHandler m_endCdataSectionHandler;
542 XML_DefaultHandler m_defaultHandler;
543 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
544 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
545 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
546 XML_NotationDeclHandler m_notationDeclHandler;
547 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
548 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
549 XML_NotStandaloneHandler m_notStandaloneHandler;
550 XML_ExternalEntityRefHandler m_externalEntityRefHandler;
551 XML_Parser m_externalEntityRefHandlerArg;
552 XML_SkippedEntityHandler m_skippedEntityHandler;
553 XML_UnknownEncodingHandler m_unknownEncodingHandler;
554 XML_ElementDeclHandler m_elementDeclHandler;
555 XML_AttlistDeclHandler m_attlistDeclHandler;
556 XML_EntityDeclHandler m_entityDeclHandler;
557 XML_XmlDeclHandler m_xmlDeclHandler;
558 const ENCODING *m_encoding;
559 INIT_ENCODING m_initEncoding;
560 const ENCODING *m_internalEncoding;
561 const XML_Char *m_protocolEncodingName;
562 XML_Bool m_ns;
563 XML_Bool m_ns_triplets;
564 void *m_unknownEncodingMem;
565 void *m_unknownEncodingData;
566 void *m_unknownEncodingHandlerData;
Haibo Huang40a71912019-10-11 11:13:39 -0700567 void(XMLCALL *m_unknownEncodingRelease)(void *);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800568 PROLOG_STATE m_prologState;
569 Processor *m_processor;
570 enum XML_Error m_errorCode;
571 const char *m_eventPtr;
572 const char *m_eventEndPtr;
573 const char *m_positionPtr;
574 OPEN_INTERNAL_ENTITY *m_openInternalEntities;
575 OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
576 XML_Bool m_defaultExpandInternalEntities;
577 int m_tagLevel;
578 ENTITY *m_declEntity;
579 const XML_Char *m_doctypeName;
580 const XML_Char *m_doctypeSysid;
581 const XML_Char *m_doctypePubid;
582 const XML_Char *m_declAttributeType;
583 const XML_Char *m_declNotationName;
584 const XML_Char *m_declNotationPublicId;
585 ELEMENT_TYPE *m_declElementType;
586 ATTRIBUTE_ID *m_declAttributeId;
587 XML_Bool m_declAttributeIsCdata;
588 XML_Bool m_declAttributeIsId;
589 DTD *m_dtd;
590 const XML_Char *m_curBase;
591 TAG *m_tagStack;
592 TAG *m_freeTagList;
593 BINDING *m_inheritedBindings;
594 BINDING *m_freeBindingList;
595 int m_attsSize;
596 int m_nSpecifiedAtts;
597 int m_idAttIndex;
598 ATTRIBUTE *m_atts;
599 NS_ATT *m_nsAtts;
600 unsigned long m_nsAttsVersion;
601 unsigned char m_nsAttsPower;
Elliott Hughes35e432d2012-09-09 14:23:38 -0700602#ifdef XML_ATTR_INFO
603 XML_AttrInfo *m_attInfo;
604#endif
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800605 POSITION m_position;
606 STRING_POOL m_tempPool;
607 STRING_POOL m_temp2Pool;
608 char *m_groupConnector;
609 unsigned int m_groupSize;
610 XML_Char m_namespaceSeparator;
611 XML_Parser m_parentParser;
612 XML_ParsingStatus m_parsingStatus;
613#ifdef XML_DTD
614 XML_Bool m_isParamEntity;
615 XML_Bool m_useForeignDTD;
616 enum XML_ParamEntityParsing m_paramEntityParsing;
617#endif
Elliott Hughes35e432d2012-09-09 14:23:38 -0700618 unsigned long m_hash_secret_salt;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800619};
620
Haibo Huang40a71912019-10-11 11:13:39 -0700621#define MALLOC(parser, s) (parser->m_mem.malloc_fcn((s)))
622#define REALLOC(parser, p, s) (parser->m_mem.realloc_fcn((p), (s)))
623#define FREE(parser, p) (parser->m_mem.free_fcn((p)))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800624
625XML_Parser XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -0700626XML_ParserCreate(const XML_Char *encodingName) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800627 return XML_ParserCreate_MM(encodingName, NULL, NULL);
628}
629
630XML_Parser XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -0700631XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800632 XML_Char tmp[2];
633 *tmp = nsSep;
634 return XML_ParserCreate_MM(encodingName, NULL, tmp);
635}
636
Haibo Huang40a71912019-10-11 11:13:39 -0700637static const XML_Char implicitContext[]
638 = {ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h,
639 ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH,
640 ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD,
641 ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r,
642 ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L,
643 ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8,
644 ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e,
645 ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e,
646 '\0'};
Elliott Hughes72472942018-01-10 08:36:10 -0800647
648/* To avoid warnings about unused functions: */
649#if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM)
650
Haibo Huang40a71912019-10-11 11:13:39 -0700651# if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
Elliott Hughes72472942018-01-10 08:36:10 -0800652
653/* Obtain entropy on Linux 3.17+ */
654static int
Haibo Huang40a71912019-10-11 11:13:39 -0700655writeRandomBytes_getrandom_nonblock(void *target, size_t count) {
656 int success = 0; /* full count bytes written? */
Elliott Hughes72472942018-01-10 08:36:10 -0800657 size_t bytesWrittenTotal = 0;
658 const unsigned int getrandomFlags = GRND_NONBLOCK;
659
660 do {
Haibo Huang40a71912019-10-11 11:13:39 -0700661 void *const currentTarget = (void *)((char *)target + bytesWrittenTotal);
Elliott Hughes72472942018-01-10 08:36:10 -0800662 const size_t bytesToWrite = count - bytesWrittenTotal;
663
664 const int bytesWrittenMore =
Haibo Huang40a71912019-10-11 11:13:39 -0700665# if defined(HAVE_GETRANDOM)
Elliott Hughes72472942018-01-10 08:36:10 -0800666 getrandom(currentTarget, bytesToWrite, getrandomFlags);
Haibo Huang40a71912019-10-11 11:13:39 -0700667# else
Elliott Hughes72472942018-01-10 08:36:10 -0800668 syscall(SYS_getrandom, currentTarget, bytesToWrite, getrandomFlags);
Haibo Huang40a71912019-10-11 11:13:39 -0700669# endif
Elliott Hughes72472942018-01-10 08:36:10 -0800670
671 if (bytesWrittenMore > 0) {
672 bytesWrittenTotal += bytesWrittenMore;
673 if (bytesWrittenTotal >= count)
674 success = 1;
675 }
676 } while (! success && (errno == EINTR));
677
678 return success;
679}
680
Haibo Huang40a71912019-10-11 11:13:39 -0700681# endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */
Elliott Hughes72472942018-01-10 08:36:10 -0800682
Haibo Huang40a71912019-10-11 11:13:39 -0700683# if ! defined(_WIN32) && defined(XML_DEV_URANDOM)
Elliott Hughes72472942018-01-10 08:36:10 -0800684
685/* Extract entropy from /dev/urandom */
686static int
Haibo Huang40a71912019-10-11 11:13:39 -0700687writeRandomBytes_dev_urandom(void *target, size_t count) {
688 int success = 0; /* full count bytes written? */
Elliott Hughes72472942018-01-10 08:36:10 -0800689 size_t bytesWrittenTotal = 0;
690
691 const int fd = open("/dev/urandom", O_RDONLY);
692 if (fd < 0) {
693 return 0;
694 }
695
696 do {
Haibo Huang40a71912019-10-11 11:13:39 -0700697 void *const currentTarget = (void *)((char *)target + bytesWrittenTotal);
Elliott Hughes72472942018-01-10 08:36:10 -0800698 const size_t bytesToWrite = count - bytesWrittenTotal;
699
700 const ssize_t bytesWrittenMore = read(fd, currentTarget, bytesToWrite);
701
702 if (bytesWrittenMore > 0) {
703 bytesWrittenTotal += bytesWrittenMore;
704 if (bytesWrittenTotal >= count)
705 success = 1;
706 }
707 } while (! success && (errno == EINTR));
708
709 close(fd);
710 return success;
711}
712
Haibo Huang40a71912019-10-11 11:13:39 -0700713# endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */
Elliott Hughes72472942018-01-10 08:36:10 -0800714
Haibo Huang40a71912019-10-11 11:13:39 -0700715#endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */
Elliott Hughes72472942018-01-10 08:36:10 -0800716
Haibo Huangfd5e81a2019-06-20 12:09:36 -0700717#if defined(HAVE_ARC4RANDOM) && ! defined(HAVE_ARC4RANDOM_BUF)
Elliott Hughes72472942018-01-10 08:36:10 -0800718
719static void
Haibo Huang40a71912019-10-11 11:13:39 -0700720writeRandomBytes_arc4random(void *target, size_t count) {
Elliott Hughes72472942018-01-10 08:36:10 -0800721 size_t bytesWrittenTotal = 0;
722
723 while (bytesWrittenTotal < count) {
724 const uint32_t random32 = arc4random();
725 size_t i = 0;
726
727 for (; (i < sizeof(random32)) && (bytesWrittenTotal < count);
Haibo Huang40a71912019-10-11 11:13:39 -0700728 i++, bytesWrittenTotal++) {
Elliott Hughes72472942018-01-10 08:36:10 -0800729 const uint8_t random8 = (uint8_t)(random32 >> (i * 8));
730 ((uint8_t *)target)[bytesWrittenTotal] = random8;
731 }
732 }
733}
734
Haibo Huang40a71912019-10-11 11:13:39 -0700735#endif /* defined(HAVE_ARC4RANDOM) && ! defined(HAVE_ARC4RANDOM_BUF) */
Elliott Hughes72472942018-01-10 08:36:10 -0800736
737#ifdef _WIN32
738
Haibo Huang40a71912019-10-11 11:13:39 -0700739/* Obtain entropy on Windows using the rand_s() function which
740 * generates cryptographically secure random numbers. Internally it
741 * uses RtlGenRandom API which is present in Windows XP and later.
Elliott Hughes72472942018-01-10 08:36:10 -0800742 */
743static int
Haibo Huang40a71912019-10-11 11:13:39 -0700744writeRandomBytes_rand_s(void *target, size_t count) {
745 size_t bytesWrittenTotal = 0;
Elliott Hughes72472942018-01-10 08:36:10 -0800746
Haibo Huang40a71912019-10-11 11:13:39 -0700747 while (bytesWrittenTotal < count) {
748 unsigned int random32 = 0;
749 size_t i = 0;
750
751 if (rand_s(&random32))
752 return 0; /* failure */
753
754 for (; (i < sizeof(random32)) && (bytesWrittenTotal < count);
755 i++, bytesWrittenTotal++) {
756 const uint8_t random8 = (uint8_t)(random32 >> (i * 8));
757 ((uint8_t *)target)[bytesWrittenTotal] = random8;
Elliott Hughes72472942018-01-10 08:36:10 -0800758 }
Elliott Hughes72472942018-01-10 08:36:10 -0800759 }
Haibo Huang40a71912019-10-11 11:13:39 -0700760 return 1; /* success */
Elliott Hughes72472942018-01-10 08:36:10 -0800761}
762
763#endif /* _WIN32 */
764
Elliott Hughes72472942018-01-10 08:36:10 -0800765#if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM)
766
Elliott Hughes35e432d2012-09-09 14:23:38 -0700767static unsigned long
Haibo Huang40a71912019-10-11 11:13:39 -0700768gather_time_entropy(void) {
769# ifdef _WIN32
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100770 FILETIME ft;
771 GetSystemTimeAsFileTime(&ft); /* never fails */
772 return ft.dwHighDateTime ^ ft.dwLowDateTime;
Haibo Huang40a71912019-10-11 11:13:39 -0700773# else
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100774 struct timeval tv;
775 int gettimeofday_res;
776
777 gettimeofday_res = gettimeofday(&tv, NULL);
Elliott Hughes72472942018-01-10 08:36:10 -0800778
Haibo Huang40a71912019-10-11 11:13:39 -0700779# if defined(NDEBUG)
Elliott Hughes72472942018-01-10 08:36:10 -0800780 (void)gettimeofday_res;
Haibo Huang40a71912019-10-11 11:13:39 -0700781# else
782 assert(gettimeofday_res == 0);
783# endif /* defined(NDEBUG) */
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100784
785 /* Microseconds time is <20 bits entropy */
786 return tv.tv_usec;
Haibo Huang40a71912019-10-11 11:13:39 -0700787# endif
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100788}
789
Haibo Huang40a71912019-10-11 11:13:39 -0700790#endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */
Elliott Hughes72472942018-01-10 08:36:10 -0800791
792static unsigned long
Haibo Huang40a71912019-10-11 11:13:39 -0700793ENTROPY_DEBUG(const char *label, unsigned long entropy) {
794 const char *const EXPAT_ENTROPY_DEBUG = getenv("EXPAT_ENTROPY_DEBUG");
Elliott Hughes72472942018-01-10 08:36:10 -0800795 if (EXPAT_ENTROPY_DEBUG && ! strcmp(EXPAT_ENTROPY_DEBUG, "1")) {
Haibo Huang40a71912019-10-11 11:13:39 -0700796 fprintf(stderr, "Entropy: %s --> 0x%0*lx (%lu bytes)\n", label,
797 (int)sizeof(entropy) * 2, entropy, (unsigned long)sizeof(entropy));
Elliott Hughes72472942018-01-10 08:36:10 -0800798 }
799 return entropy;
800}
801
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100802static unsigned long
Haibo Huang40a71912019-10-11 11:13:39 -0700803generate_hash_secret_salt(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -0800804 unsigned long entropy;
805 (void)parser;
806
807 /* "Failproof" high quality providers: */
808#if defined(HAVE_ARC4RANDOM_BUF)
809 arc4random_buf(&entropy, sizeof(entropy));
810 return ENTROPY_DEBUG("arc4random_buf", entropy);
811#elif defined(HAVE_ARC4RANDOM)
812 writeRandomBytes_arc4random((void *)&entropy, sizeof(entropy));
813 return ENTROPY_DEBUG("arc4random", entropy);
814#else
815 /* Try high quality providers first .. */
Haibo Huang40a71912019-10-11 11:13:39 -0700816# ifdef _WIN32
817 if (writeRandomBytes_rand_s((void *)&entropy, sizeof(entropy))) {
818 return ENTROPY_DEBUG("rand_s", entropy);
Elliott Hughes72472942018-01-10 08:36:10 -0800819 }
Haibo Huang40a71912019-10-11 11:13:39 -0700820# elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
Elliott Hughes72472942018-01-10 08:36:10 -0800821 if (writeRandomBytes_getrandom_nonblock((void *)&entropy, sizeof(entropy))) {
822 return ENTROPY_DEBUG("getrandom", entropy);
823 }
Haibo Huang40a71912019-10-11 11:13:39 -0700824# endif
825# if ! defined(_WIN32) && defined(XML_DEV_URANDOM)
Elliott Hughes72472942018-01-10 08:36:10 -0800826 if (writeRandomBytes_dev_urandom((void *)&entropy, sizeof(entropy))) {
827 return ENTROPY_DEBUG("/dev/urandom", entropy);
828 }
Haibo Huang40a71912019-10-11 11:13:39 -0700829# endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */
Elliott Hughes72472942018-01-10 08:36:10 -0800830 /* .. and self-made low quality for backup: */
831
832 /* Process ID is 0 bits entropy if attacker has local access */
833 entropy = gather_time_entropy() ^ getpid();
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100834
835 /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */
836 if (sizeof(unsigned long) == 4) {
Elliott Hughes72472942018-01-10 08:36:10 -0800837 return ENTROPY_DEBUG("fallback(4)", entropy * 2147483647);
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100838 } else {
Elliott Hughes72472942018-01-10 08:36:10 -0800839 return ENTROPY_DEBUG("fallback(8)",
Haibo Huang40a71912019-10-11 11:13:39 -0700840 entropy * (unsigned long)2305843009213693951ULL);
Paul Duffin3c2f09e2016-06-07 15:53:38 +0100841 }
Elliott Hughes72472942018-01-10 08:36:10 -0800842#endif
843}
844
845static unsigned long
846get_hash_secret_salt(XML_Parser parser) {
847 if (parser->m_parentParser != NULL)
848 return get_hash_secret_salt(parser->m_parentParser);
849 return parser->m_hash_secret_salt;
Elliott Hughes35e432d2012-09-09 14:23:38 -0700850}
851
Haibo Huang40a71912019-10-11 11:13:39 -0700852static XML_Bool /* only valid for root parser */
853startParsing(XML_Parser parser) {
854 /* hash functions must be initialized before setContext() is called */
855 if (parser->m_hash_secret_salt == 0)
856 parser->m_hash_secret_salt = generate_hash_secret_salt(parser);
857 if (parser->m_ns) {
858 /* implicit context only set for root parser, since child
859 parsers (i.e. external entity parsers) will inherit it
860 */
861 return setContext(parser, implicitContext);
862 }
863 return XML_TRUE;
Elliott Hughes35e432d2012-09-09 14:23:38 -0700864}
865
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800866XML_Parser XMLCALL
867XML_ParserCreate_MM(const XML_Char *encodingName,
868 const XML_Memory_Handling_Suite *memsuite,
Haibo Huang40a71912019-10-11 11:13:39 -0700869 const XML_Char *nameSep) {
Elliott Hughes35e432d2012-09-09 14:23:38 -0700870 return parserCreate(encodingName, memsuite, nameSep, NULL);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800871}
872
873static XML_Parser
874parserCreate(const XML_Char *encodingName,
Haibo Huang40a71912019-10-11 11:13:39 -0700875 const XML_Memory_Handling_Suite *memsuite, const XML_Char *nameSep,
876 DTD *dtd) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800877 XML_Parser parser;
878
879 if (memsuite) {
880 XML_Memory_Handling_Suite *mtemp;
Haibo Huang40a71912019-10-11 11:13:39 -0700881 parser = (XML_Parser)memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800882 if (parser != NULL) {
883 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
884 mtemp->malloc_fcn = memsuite->malloc_fcn;
885 mtemp->realloc_fcn = memsuite->realloc_fcn;
886 mtemp->free_fcn = memsuite->free_fcn;
887 }
Haibo Huang40a71912019-10-11 11:13:39 -0700888 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800889 XML_Memory_Handling_Suite *mtemp;
890 parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
891 if (parser != NULL) {
892 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
893 mtemp->malloc_fcn = malloc;
894 mtemp->realloc_fcn = realloc;
895 mtemp->free_fcn = free;
896 }
897 }
898
Haibo Huang40a71912019-10-11 11:13:39 -0700899 if (! parser)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800900 return parser;
901
Elliott Hughes72472942018-01-10 08:36:10 -0800902 parser->m_buffer = NULL;
903 parser->m_bufferLim = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800904
Elliott Hughes72472942018-01-10 08:36:10 -0800905 parser->m_attsSize = INIT_ATTS_SIZE;
Haibo Huang40a71912019-10-11 11:13:39 -0700906 parser->m_atts
907 = (ATTRIBUTE *)MALLOC(parser, parser->m_attsSize * sizeof(ATTRIBUTE));
Elliott Hughes72472942018-01-10 08:36:10 -0800908 if (parser->m_atts == NULL) {
909 FREE(parser, parser);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800910 return NULL;
911 }
Elliott Hughes35e432d2012-09-09 14:23:38 -0700912#ifdef XML_ATTR_INFO
Haibo Huang40a71912019-10-11 11:13:39 -0700913 parser->m_attInfo = (XML_AttrInfo *)MALLOC(
914 parser, parser->m_attsSize * sizeof(XML_AttrInfo));
Elliott Hughes72472942018-01-10 08:36:10 -0800915 if (parser->m_attInfo == NULL) {
916 FREE(parser, parser->m_atts);
917 FREE(parser, parser);
Elliott Hughes35e432d2012-09-09 14:23:38 -0700918 return NULL;
919 }
920#endif
Haibo Huang40a71912019-10-11 11:13:39 -0700921 parser->m_dataBuf
922 = (XML_Char *)MALLOC(parser, INIT_DATA_BUF_SIZE * sizeof(XML_Char));
Elliott Hughes72472942018-01-10 08:36:10 -0800923 if (parser->m_dataBuf == NULL) {
924 FREE(parser, parser->m_atts);
Elliott Hughes35e432d2012-09-09 14:23:38 -0700925#ifdef XML_ATTR_INFO
Elliott Hughes72472942018-01-10 08:36:10 -0800926 FREE(parser, parser->m_attInfo);
Elliott Hughes35e432d2012-09-09 14:23:38 -0700927#endif
Elliott Hughes72472942018-01-10 08:36:10 -0800928 FREE(parser, parser);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800929 return NULL;
930 }
Elliott Hughes72472942018-01-10 08:36:10 -0800931 parser->m_dataBufEnd = parser->m_dataBuf + INIT_DATA_BUF_SIZE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800932
933 if (dtd)
Elliott Hughes72472942018-01-10 08:36:10 -0800934 parser->m_dtd = dtd;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800935 else {
Elliott Hughes72472942018-01-10 08:36:10 -0800936 parser->m_dtd = dtdCreate(&parser->m_mem);
937 if (parser->m_dtd == NULL) {
938 FREE(parser, parser->m_dataBuf);
939 FREE(parser, parser->m_atts);
Elliott Hughes35e432d2012-09-09 14:23:38 -0700940#ifdef XML_ATTR_INFO
Elliott Hughes72472942018-01-10 08:36:10 -0800941 FREE(parser, parser->m_attInfo);
Elliott Hughes35e432d2012-09-09 14:23:38 -0700942#endif
Elliott Hughes72472942018-01-10 08:36:10 -0800943 FREE(parser, parser);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800944 return NULL;
945 }
946 }
947
Elliott Hughes72472942018-01-10 08:36:10 -0800948 parser->m_freeBindingList = NULL;
949 parser->m_freeTagList = NULL;
950 parser->m_freeInternalEntities = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800951
Elliott Hughes72472942018-01-10 08:36:10 -0800952 parser->m_groupSize = 0;
953 parser->m_groupConnector = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800954
Elliott Hughes72472942018-01-10 08:36:10 -0800955 parser->m_unknownEncodingHandler = NULL;
956 parser->m_unknownEncodingHandlerData = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800957
Elliott Hughes72472942018-01-10 08:36:10 -0800958 parser->m_namespaceSeparator = ASCII_EXCL;
959 parser->m_ns = XML_FALSE;
960 parser->m_ns_triplets = XML_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800961
Elliott Hughes72472942018-01-10 08:36:10 -0800962 parser->m_nsAtts = NULL;
963 parser->m_nsAttsVersion = 0;
964 parser->m_nsAttsPower = 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800965
Elliott Hughes72472942018-01-10 08:36:10 -0800966 parser->m_protocolEncodingName = NULL;
967
968 poolInit(&parser->m_tempPool, &(parser->m_mem));
969 poolInit(&parser->m_temp2Pool, &(parser->m_mem));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800970 parserInit(parser, encodingName);
971
Haibo Huang40a71912019-10-11 11:13:39 -0700972 if (encodingName && ! parser->m_protocolEncodingName) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800973 XML_ParserFree(parser);
974 return NULL;
975 }
976
977 if (nameSep) {
Elliott Hughes72472942018-01-10 08:36:10 -0800978 parser->m_ns = XML_TRUE;
979 parser->m_internalEncoding = XmlGetInternalEncodingNS();
980 parser->m_namespaceSeparator = *nameSep;
Haibo Huang40a71912019-10-11 11:13:39 -0700981 } else {
Elliott Hughes72472942018-01-10 08:36:10 -0800982 parser->m_internalEncoding = XmlGetInternalEncoding();
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800983 }
984
985 return parser;
986}
987
988static void
Haibo Huang40a71912019-10-11 11:13:39 -0700989parserInit(XML_Parser parser, const XML_Char *encodingName) {
Elliott Hughes72472942018-01-10 08:36:10 -0800990 parser->m_processor = prologInitProcessor;
991 XmlPrologStateInit(&parser->m_prologState);
992 if (encodingName != NULL) {
993 parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem));
994 }
995 parser->m_curBase = NULL;
996 XmlInitEncoding(&parser->m_initEncoding, &parser->m_encoding, 0);
997 parser->m_userData = NULL;
998 parser->m_handlerArg = NULL;
999 parser->m_startElementHandler = NULL;
1000 parser->m_endElementHandler = NULL;
1001 parser->m_characterDataHandler = NULL;
1002 parser->m_processingInstructionHandler = NULL;
1003 parser->m_commentHandler = NULL;
1004 parser->m_startCdataSectionHandler = NULL;
1005 parser->m_endCdataSectionHandler = NULL;
1006 parser->m_defaultHandler = NULL;
1007 parser->m_startDoctypeDeclHandler = NULL;
1008 parser->m_endDoctypeDeclHandler = NULL;
1009 parser->m_unparsedEntityDeclHandler = NULL;
1010 parser->m_notationDeclHandler = NULL;
1011 parser->m_startNamespaceDeclHandler = NULL;
1012 parser->m_endNamespaceDeclHandler = NULL;
1013 parser->m_notStandaloneHandler = NULL;
1014 parser->m_externalEntityRefHandler = NULL;
1015 parser->m_externalEntityRefHandlerArg = parser;
1016 parser->m_skippedEntityHandler = NULL;
1017 parser->m_elementDeclHandler = NULL;
1018 parser->m_attlistDeclHandler = NULL;
1019 parser->m_entityDeclHandler = NULL;
1020 parser->m_xmlDeclHandler = NULL;
1021 parser->m_bufferPtr = parser->m_buffer;
1022 parser->m_bufferEnd = parser->m_buffer;
1023 parser->m_parseEndByteIndex = 0;
1024 parser->m_parseEndPtr = NULL;
1025 parser->m_declElementType = NULL;
1026 parser->m_declAttributeId = NULL;
1027 parser->m_declEntity = NULL;
1028 parser->m_doctypeName = NULL;
1029 parser->m_doctypeSysid = NULL;
1030 parser->m_doctypePubid = NULL;
1031 parser->m_declAttributeType = NULL;
1032 parser->m_declNotationName = NULL;
1033 parser->m_declNotationPublicId = NULL;
1034 parser->m_declAttributeIsCdata = XML_FALSE;
1035 parser->m_declAttributeIsId = XML_FALSE;
1036 memset(&parser->m_position, 0, sizeof(POSITION));
1037 parser->m_errorCode = XML_ERROR_NONE;
1038 parser->m_eventPtr = NULL;
1039 parser->m_eventEndPtr = NULL;
1040 parser->m_positionPtr = NULL;
1041 parser->m_openInternalEntities = NULL;
1042 parser->m_defaultExpandInternalEntities = XML_TRUE;
1043 parser->m_tagLevel = 0;
1044 parser->m_tagStack = NULL;
1045 parser->m_inheritedBindings = NULL;
1046 parser->m_nSpecifiedAtts = 0;
1047 parser->m_unknownEncodingMem = NULL;
1048 parser->m_unknownEncodingRelease = NULL;
1049 parser->m_unknownEncodingData = NULL;
1050 parser->m_parentParser = NULL;
1051 parser->m_parsingStatus.parsing = XML_INITIALIZED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001052#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08001053 parser->m_isParamEntity = XML_FALSE;
1054 parser->m_useForeignDTD = XML_FALSE;
1055 parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001056#endif
Elliott Hughes72472942018-01-10 08:36:10 -08001057 parser->m_hash_secret_salt = 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001058}
1059
Elliott Hughes72472942018-01-10 08:36:10 -08001060/* moves list of bindings to m_freeBindingList */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001061static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001062moveToFreeBindingList(XML_Parser parser, BINDING *bindings) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001063 while (bindings) {
1064 BINDING *b = bindings;
1065 bindings = bindings->nextTagBinding;
Elliott Hughes72472942018-01-10 08:36:10 -08001066 b->nextTagBinding = parser->m_freeBindingList;
1067 parser->m_freeBindingList = b;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001068 }
1069}
1070
1071XML_Bool XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001072XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001073 TAG *tStk;
1074 OPEN_INTERNAL_ENTITY *openEntityList;
Elliott Hughes72472942018-01-10 08:36:10 -08001075
1076 if (parser == NULL)
Haibo Huang40a71912019-10-11 11:13:39 -07001077 return XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08001078
1079 if (parser->m_parentParser)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001080 return XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08001081 /* move m_tagStack to m_freeTagList */
1082 tStk = parser->m_tagStack;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001083 while (tStk) {
1084 TAG *tag = tStk;
1085 tStk = tStk->parent;
Elliott Hughes72472942018-01-10 08:36:10 -08001086 tag->parent = parser->m_freeTagList;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001087 moveToFreeBindingList(parser, tag->bindings);
1088 tag->bindings = NULL;
Elliott Hughes72472942018-01-10 08:36:10 -08001089 parser->m_freeTagList = tag;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001090 }
Elliott Hughes72472942018-01-10 08:36:10 -08001091 /* move m_openInternalEntities to m_freeInternalEntities */
1092 openEntityList = parser->m_openInternalEntities;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001093 while (openEntityList) {
1094 OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
1095 openEntityList = openEntity->next;
Elliott Hughes72472942018-01-10 08:36:10 -08001096 openEntity->next = parser->m_freeInternalEntities;
1097 parser->m_freeInternalEntities = openEntity;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001098 }
Elliott Hughes72472942018-01-10 08:36:10 -08001099 moveToFreeBindingList(parser, parser->m_inheritedBindings);
1100 FREE(parser, parser->m_unknownEncodingMem);
1101 if (parser->m_unknownEncodingRelease)
1102 parser->m_unknownEncodingRelease(parser->m_unknownEncodingData);
1103 poolClear(&parser->m_tempPool);
1104 poolClear(&parser->m_temp2Pool);
1105 FREE(parser, (void *)parser->m_protocolEncodingName);
1106 parser->m_protocolEncodingName = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001107 parserInit(parser, encodingName);
Elliott Hughes72472942018-01-10 08:36:10 -08001108 dtdReset(parser->m_dtd, &parser->m_mem);
Elliott Hughes35e432d2012-09-09 14:23:38 -07001109 return XML_TRUE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001110}
1111
1112enum XML_Status XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001113XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) {
Elliott Hughes72472942018-01-10 08:36:10 -08001114 if (parser == NULL)
Haibo Huang40a71912019-10-11 11:13:39 -07001115 return XML_STATUS_ERROR;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001116 /* Block after XML_Parse()/XML_ParseBuffer() has been called.
1117 XXX There's no way for the caller to determine which of the
1118 XXX possible error cases caused the XML_STATUS_ERROR return.
1119 */
Haibo Huang40a71912019-10-11 11:13:39 -07001120 if (parser->m_parsingStatus.parsing == XML_PARSING
1121 || parser->m_parsingStatus.parsing == XML_SUSPENDED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001122 return XML_STATUS_ERROR;
Elliott Hughes72472942018-01-10 08:36:10 -08001123
1124 /* Get rid of any previous encoding name */
1125 FREE(parser, (void *)parser->m_protocolEncodingName);
1126
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001127 if (encodingName == NULL)
Elliott Hughes72472942018-01-10 08:36:10 -08001128 /* No new encoding name */
1129 parser->m_protocolEncodingName = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001130 else {
Elliott Hughes72472942018-01-10 08:36:10 -08001131 /* Copy the new encoding name into allocated memory */
1132 parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem));
Haibo Huang40a71912019-10-11 11:13:39 -07001133 if (! parser->m_protocolEncodingName)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001134 return XML_STATUS_ERROR;
1135 }
1136 return XML_STATUS_OK;
1137}
1138
1139XML_Parser XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001140XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context,
1141 const XML_Char *encodingName) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001142 XML_Parser parser = oldParser;
1143 DTD *newDtd = NULL;
Elliott Hughes72472942018-01-10 08:36:10 -08001144 DTD *oldDtd;
1145 XML_StartElementHandler oldStartElementHandler;
1146 XML_EndElementHandler oldEndElementHandler;
1147 XML_CharacterDataHandler oldCharacterDataHandler;
1148 XML_ProcessingInstructionHandler oldProcessingInstructionHandler;
1149 XML_CommentHandler oldCommentHandler;
1150 XML_StartCdataSectionHandler oldStartCdataSectionHandler;
1151 XML_EndCdataSectionHandler oldEndCdataSectionHandler;
1152 XML_DefaultHandler oldDefaultHandler;
1153 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler;
1154 XML_NotationDeclHandler oldNotationDeclHandler;
1155 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler;
1156 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler;
1157 XML_NotStandaloneHandler oldNotStandaloneHandler;
1158 XML_ExternalEntityRefHandler oldExternalEntityRefHandler;
1159 XML_SkippedEntityHandler oldSkippedEntityHandler;
1160 XML_UnknownEncodingHandler oldUnknownEncodingHandler;
1161 XML_ElementDeclHandler oldElementDeclHandler;
1162 XML_AttlistDeclHandler oldAttlistDeclHandler;
1163 XML_EntityDeclHandler oldEntityDeclHandler;
1164 XML_XmlDeclHandler oldXmlDeclHandler;
Haibo Huang40a71912019-10-11 11:13:39 -07001165 ELEMENT_TYPE *oldDeclElementType;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001166
Elliott Hughes72472942018-01-10 08:36:10 -08001167 void *oldUserData;
1168 void *oldHandlerArg;
1169 XML_Bool oldDefaultExpandInternalEntities;
1170 XML_Parser oldExternalEntityRefHandlerArg;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001171#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08001172 enum XML_ParamEntityParsing oldParamEntityParsing;
1173 int oldInEntityValue;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001174#endif
Elliott Hughes72472942018-01-10 08:36:10 -08001175 XML_Bool oldns_triplets;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001176 /* Note that the new parser shares the same hash secret as the old
1177 parser, so that dtdCopy and copyEntityTable can lookup values
1178 from hash tables associated with either parser without us having
1179 to worry which hash secrets each table has.
1180 */
Elliott Hughes72472942018-01-10 08:36:10 -08001181 unsigned long oldhash_secret_salt;
1182
1183 /* Validate the oldParser parameter before we pull everything out of it */
1184 if (oldParser == NULL)
1185 return NULL;
1186
1187 /* Stash the original parser contents on the stack */
1188 oldDtd = parser->m_dtd;
1189 oldStartElementHandler = parser->m_startElementHandler;
1190 oldEndElementHandler = parser->m_endElementHandler;
1191 oldCharacterDataHandler = parser->m_characterDataHandler;
1192 oldProcessingInstructionHandler = parser->m_processingInstructionHandler;
1193 oldCommentHandler = parser->m_commentHandler;
1194 oldStartCdataSectionHandler = parser->m_startCdataSectionHandler;
1195 oldEndCdataSectionHandler = parser->m_endCdataSectionHandler;
1196 oldDefaultHandler = parser->m_defaultHandler;
1197 oldUnparsedEntityDeclHandler = parser->m_unparsedEntityDeclHandler;
1198 oldNotationDeclHandler = parser->m_notationDeclHandler;
1199 oldStartNamespaceDeclHandler = parser->m_startNamespaceDeclHandler;
1200 oldEndNamespaceDeclHandler = parser->m_endNamespaceDeclHandler;
1201 oldNotStandaloneHandler = parser->m_notStandaloneHandler;
1202 oldExternalEntityRefHandler = parser->m_externalEntityRefHandler;
1203 oldSkippedEntityHandler = parser->m_skippedEntityHandler;
1204 oldUnknownEncodingHandler = parser->m_unknownEncodingHandler;
1205 oldElementDeclHandler = parser->m_elementDeclHandler;
1206 oldAttlistDeclHandler = parser->m_attlistDeclHandler;
1207 oldEntityDeclHandler = parser->m_entityDeclHandler;
1208 oldXmlDeclHandler = parser->m_xmlDeclHandler;
1209 oldDeclElementType = parser->m_declElementType;
1210
1211 oldUserData = parser->m_userData;
1212 oldHandlerArg = parser->m_handlerArg;
1213 oldDefaultExpandInternalEntities = parser->m_defaultExpandInternalEntities;
1214 oldExternalEntityRefHandlerArg = parser->m_externalEntityRefHandlerArg;
1215#ifdef XML_DTD
1216 oldParamEntityParsing = parser->m_paramEntityParsing;
1217 oldInEntityValue = parser->m_prologState.inEntityValue;
1218#endif
1219 oldns_triplets = parser->m_ns_triplets;
1220 /* Note that the new parser shares the same hash secret as the old
1221 parser, so that dtdCopy and copyEntityTable can lookup values
1222 from hash tables associated with either parser without us having
1223 to worry which hash secrets each table has.
1224 */
1225 oldhash_secret_salt = parser->m_hash_secret_salt;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001226
1227#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07001228 if (! context)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001229 newDtd = oldDtd;
1230#endif /* XML_DTD */
1231
1232 /* Note that the magical uses of the pre-processor to make field
1233 access look more like C++ require that `parser' be overwritten
1234 here. This makes this function more painful to follow than it
1235 would be otherwise.
1236 */
Elliott Hughes72472942018-01-10 08:36:10 -08001237 if (parser->m_ns) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001238 XML_Char tmp[2];
Elliott Hughes72472942018-01-10 08:36:10 -08001239 *tmp = parser->m_namespaceSeparator;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001240 parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
Haibo Huang40a71912019-10-11 11:13:39 -07001241 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001242 parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
1243 }
1244
Haibo Huang40a71912019-10-11 11:13:39 -07001245 if (! parser)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001246 return NULL;
1247
Elliott Hughes72472942018-01-10 08:36:10 -08001248 parser->m_startElementHandler = oldStartElementHandler;
1249 parser->m_endElementHandler = oldEndElementHandler;
1250 parser->m_characterDataHandler = oldCharacterDataHandler;
1251 parser->m_processingInstructionHandler = oldProcessingInstructionHandler;
1252 parser->m_commentHandler = oldCommentHandler;
1253 parser->m_startCdataSectionHandler = oldStartCdataSectionHandler;
1254 parser->m_endCdataSectionHandler = oldEndCdataSectionHandler;
1255 parser->m_defaultHandler = oldDefaultHandler;
1256 parser->m_unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
1257 parser->m_notationDeclHandler = oldNotationDeclHandler;
1258 parser->m_startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
1259 parser->m_endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
1260 parser->m_notStandaloneHandler = oldNotStandaloneHandler;
1261 parser->m_externalEntityRefHandler = oldExternalEntityRefHandler;
1262 parser->m_skippedEntityHandler = oldSkippedEntityHandler;
1263 parser->m_unknownEncodingHandler = oldUnknownEncodingHandler;
1264 parser->m_elementDeclHandler = oldElementDeclHandler;
1265 parser->m_attlistDeclHandler = oldAttlistDeclHandler;
1266 parser->m_entityDeclHandler = oldEntityDeclHandler;
1267 parser->m_xmlDeclHandler = oldXmlDeclHandler;
1268 parser->m_declElementType = oldDeclElementType;
1269 parser->m_userData = oldUserData;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001270 if (oldUserData == oldHandlerArg)
Elliott Hughes72472942018-01-10 08:36:10 -08001271 parser->m_handlerArg = parser->m_userData;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001272 else
Elliott Hughes72472942018-01-10 08:36:10 -08001273 parser->m_handlerArg = parser;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001274 if (oldExternalEntityRefHandlerArg != oldParser)
Elliott Hughes72472942018-01-10 08:36:10 -08001275 parser->m_externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
1276 parser->m_defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
1277 parser->m_ns_triplets = oldns_triplets;
1278 parser->m_hash_secret_salt = oldhash_secret_salt;
1279 parser->m_parentParser = oldParser;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001280#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08001281 parser->m_paramEntityParsing = oldParamEntityParsing;
1282 parser->m_prologState.inEntityValue = oldInEntityValue;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001283 if (context) {
1284#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07001285 if (! dtdCopy(oldParser, parser->m_dtd, oldDtd, &parser->m_mem)
1286 || ! setContext(parser, context)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001287 XML_ParserFree(parser);
1288 return NULL;
1289 }
Elliott Hughes72472942018-01-10 08:36:10 -08001290 parser->m_processor = externalEntityInitProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001291#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07001292 } else {
1293 /* The DTD instance referenced by parser->m_dtd is shared between the
1294 document's root parser and external PE parsers, therefore one does not
1295 need to call setContext. In addition, one also *must* not call
1296 setContext, because this would overwrite existing prefix->binding
1297 pointers in parser->m_dtd with ones that get destroyed with the external
1298 PE parser. This would leave those prefixes with dangling pointers.
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001299 */
Elliott Hughes72472942018-01-10 08:36:10 -08001300 parser->m_isParamEntity = XML_TRUE;
1301 XmlPrologStateInitExternalEntity(&parser->m_prologState);
1302 parser->m_processor = externalParEntInitProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001303 }
1304#endif /* XML_DTD */
1305 return parser;
1306}
1307
1308static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001309destroyBindings(BINDING *bindings, XML_Parser parser) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001310 for (;;) {
1311 BINDING *b = bindings;
Haibo Huang40a71912019-10-11 11:13:39 -07001312 if (! b)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001313 break;
1314 bindings = b->nextTagBinding;
Elliott Hughes72472942018-01-10 08:36:10 -08001315 FREE(parser, b->uri);
1316 FREE(parser, b);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001317 }
1318}
1319
1320void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001321XML_ParserFree(XML_Parser parser) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001322 TAG *tagList;
1323 OPEN_INTERNAL_ENTITY *entityList;
1324 if (parser == NULL)
1325 return;
Elliott Hughes72472942018-01-10 08:36:10 -08001326 /* free m_tagStack and m_freeTagList */
1327 tagList = parser->m_tagStack;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001328 for (;;) {
1329 TAG *p;
1330 if (tagList == NULL) {
Elliott Hughes72472942018-01-10 08:36:10 -08001331 if (parser->m_freeTagList == NULL)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001332 break;
Elliott Hughes72472942018-01-10 08:36:10 -08001333 tagList = parser->m_freeTagList;
1334 parser->m_freeTagList = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001335 }
1336 p = tagList;
1337 tagList = tagList->parent;
Elliott Hughes72472942018-01-10 08:36:10 -08001338 FREE(parser, p->buf);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001339 destroyBindings(p->bindings, parser);
Elliott Hughes72472942018-01-10 08:36:10 -08001340 FREE(parser, p);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001341 }
Elliott Hughes72472942018-01-10 08:36:10 -08001342 /* free m_openInternalEntities and m_freeInternalEntities */
1343 entityList = parser->m_openInternalEntities;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001344 for (;;) {
1345 OPEN_INTERNAL_ENTITY *openEntity;
1346 if (entityList == NULL) {
Elliott Hughes72472942018-01-10 08:36:10 -08001347 if (parser->m_freeInternalEntities == NULL)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001348 break;
Elliott Hughes72472942018-01-10 08:36:10 -08001349 entityList = parser->m_freeInternalEntities;
1350 parser->m_freeInternalEntities = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001351 }
1352 openEntity = entityList;
1353 entityList = entityList->next;
Elliott Hughes72472942018-01-10 08:36:10 -08001354 FREE(parser, openEntity);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001355 }
1356
Elliott Hughes72472942018-01-10 08:36:10 -08001357 destroyBindings(parser->m_freeBindingList, parser);
1358 destroyBindings(parser->m_inheritedBindings, parser);
1359 poolDestroy(&parser->m_tempPool);
1360 poolDestroy(&parser->m_temp2Pool);
1361 FREE(parser, (void *)parser->m_protocolEncodingName);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001362#ifdef XML_DTD
1363 /* external parameter entity parsers share the DTD structure
1364 parser->m_dtd with the root parser, so we must not destroy it
1365 */
Haibo Huang40a71912019-10-11 11:13:39 -07001366 if (! parser->m_isParamEntity && parser->m_dtd)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001367#else
Elliott Hughes72472942018-01-10 08:36:10 -08001368 if (parser->m_dtd)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001369#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07001370 dtdDestroy(parser->m_dtd, (XML_Bool)! parser->m_parentParser,
1371 &parser->m_mem);
Elliott Hughes72472942018-01-10 08:36:10 -08001372 FREE(parser, (void *)parser->m_atts);
Elliott Hughes35e432d2012-09-09 14:23:38 -07001373#ifdef XML_ATTR_INFO
Elliott Hughes72472942018-01-10 08:36:10 -08001374 FREE(parser, (void *)parser->m_attInfo);
Elliott Hughes35e432d2012-09-09 14:23:38 -07001375#endif
Elliott Hughes72472942018-01-10 08:36:10 -08001376 FREE(parser, parser->m_groupConnector);
1377 FREE(parser, parser->m_buffer);
1378 FREE(parser, parser->m_dataBuf);
1379 FREE(parser, parser->m_nsAtts);
1380 FREE(parser, parser->m_unknownEncodingMem);
1381 if (parser->m_unknownEncodingRelease)
1382 parser->m_unknownEncodingRelease(parser->m_unknownEncodingData);
1383 FREE(parser, parser);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001384}
1385
1386void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001387XML_UseParserAsHandlerArg(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08001388 if (parser != NULL)
1389 parser->m_handlerArg = parser;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001390}
1391
1392enum XML_Error XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001393XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) {
Elliott Hughes72472942018-01-10 08:36:10 -08001394 if (parser == NULL)
1395 return XML_ERROR_INVALID_ARGUMENT;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001396#ifdef XML_DTD
1397 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Haibo Huang40a71912019-10-11 11:13:39 -07001398 if (parser->m_parsingStatus.parsing == XML_PARSING
1399 || parser->m_parsingStatus.parsing == XML_SUSPENDED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001400 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
Elliott Hughes72472942018-01-10 08:36:10 -08001401 parser->m_useForeignDTD = useDTD;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001402 return XML_ERROR_NONE;
1403#else
1404 return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
1405#endif
1406}
1407
1408void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001409XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) {
Elliott Hughes72472942018-01-10 08:36:10 -08001410 if (parser == NULL)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001411 return;
Elliott Hughes72472942018-01-10 08:36:10 -08001412 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Haibo Huang40a71912019-10-11 11:13:39 -07001413 if (parser->m_parsingStatus.parsing == XML_PARSING
1414 || parser->m_parsingStatus.parsing == XML_SUSPENDED)
Elliott Hughes72472942018-01-10 08:36:10 -08001415 return;
1416 parser->m_ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001417}
1418
1419void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001420XML_SetUserData(XML_Parser parser, void *p) {
Elliott Hughes72472942018-01-10 08:36:10 -08001421 if (parser == NULL)
1422 return;
1423 if (parser->m_handlerArg == parser->m_userData)
1424 parser->m_handlerArg = parser->m_userData = p;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001425 else
Elliott Hughes72472942018-01-10 08:36:10 -08001426 parser->m_userData = p;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001427}
1428
1429enum XML_Status XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001430XML_SetBase(XML_Parser parser, const XML_Char *p) {
Elliott Hughes72472942018-01-10 08:36:10 -08001431 if (parser == NULL)
1432 return XML_STATUS_ERROR;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001433 if (p) {
Elliott Hughes72472942018-01-10 08:36:10 -08001434 p = poolCopyString(&parser->m_dtd->pool, p);
Haibo Huang40a71912019-10-11 11:13:39 -07001435 if (! p)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001436 return XML_STATUS_ERROR;
Elliott Hughes72472942018-01-10 08:36:10 -08001437 parser->m_curBase = p;
Haibo Huang40a71912019-10-11 11:13:39 -07001438 } else
Elliott Hughes72472942018-01-10 08:36:10 -08001439 parser->m_curBase = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001440 return XML_STATUS_OK;
1441}
1442
Haibo Huang40a71912019-10-11 11:13:39 -07001443const XML_Char *XMLCALL
1444XML_GetBase(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08001445 if (parser == NULL)
1446 return NULL;
1447 return parser->m_curBase;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001448}
1449
1450int XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001451XML_GetSpecifiedAttributeCount(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08001452 if (parser == NULL)
1453 return -1;
1454 return parser->m_nSpecifiedAtts;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001455}
1456
1457int XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001458XML_GetIdAttributeIndex(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08001459 if (parser == NULL)
1460 return -1;
1461 return parser->m_idAttIndex;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001462}
1463
Elliott Hughes35e432d2012-09-09 14:23:38 -07001464#ifdef XML_ATTR_INFO
Haibo Huang40a71912019-10-11 11:13:39 -07001465const XML_AttrInfo *XMLCALL
1466XML_GetAttributeInfo(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08001467 if (parser == NULL)
1468 return NULL;
1469 return parser->m_attInfo;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001470}
1471#endif
1472
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001473void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001474XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start,
1475 XML_EndElementHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001476 if (parser == NULL)
1477 return;
1478 parser->m_startElementHandler = start;
1479 parser->m_endElementHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001480}
1481
1482void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001483XML_SetStartElementHandler(XML_Parser parser, XML_StartElementHandler start) {
Elliott Hughes72472942018-01-10 08:36:10 -08001484 if (parser != NULL)
1485 parser->m_startElementHandler = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001486}
1487
1488void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001489XML_SetEndElementHandler(XML_Parser parser, XML_EndElementHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001490 if (parser != NULL)
1491 parser->m_endElementHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001492}
1493
1494void XMLCALL
1495XML_SetCharacterDataHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001496 XML_CharacterDataHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001497 if (parser != NULL)
1498 parser->m_characterDataHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001499}
1500
1501void XMLCALL
1502XML_SetProcessingInstructionHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001503 XML_ProcessingInstructionHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001504 if (parser != NULL)
1505 parser->m_processingInstructionHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001506}
1507
1508void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001509XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001510 if (parser != NULL)
1511 parser->m_commentHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001512}
1513
1514void XMLCALL
1515XML_SetCdataSectionHandler(XML_Parser parser,
1516 XML_StartCdataSectionHandler start,
Haibo Huang40a71912019-10-11 11:13:39 -07001517 XML_EndCdataSectionHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001518 if (parser == NULL)
1519 return;
1520 parser->m_startCdataSectionHandler = start;
1521 parser->m_endCdataSectionHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001522}
1523
1524void XMLCALL
1525XML_SetStartCdataSectionHandler(XML_Parser parser,
1526 XML_StartCdataSectionHandler start) {
Elliott Hughes72472942018-01-10 08:36:10 -08001527 if (parser != NULL)
1528 parser->m_startCdataSectionHandler = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001529}
1530
1531void XMLCALL
1532XML_SetEndCdataSectionHandler(XML_Parser parser,
1533 XML_EndCdataSectionHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001534 if (parser != NULL)
1535 parser->m_endCdataSectionHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001536}
1537
1538void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001539XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001540 if (parser == NULL)
1541 return;
1542 parser->m_defaultHandler = handler;
1543 parser->m_defaultExpandInternalEntities = XML_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001544}
1545
1546void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001547XML_SetDefaultHandlerExpand(XML_Parser parser, XML_DefaultHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001548 if (parser == NULL)
1549 return;
1550 parser->m_defaultHandler = handler;
1551 parser->m_defaultExpandInternalEntities = XML_TRUE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001552}
1553
1554void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001555XML_SetDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start,
1556 XML_EndDoctypeDeclHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001557 if (parser == NULL)
1558 return;
1559 parser->m_startDoctypeDeclHandler = start;
1560 parser->m_endDoctypeDeclHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001561}
1562
1563void XMLCALL
1564XML_SetStartDoctypeDeclHandler(XML_Parser parser,
1565 XML_StartDoctypeDeclHandler start) {
Elliott Hughes72472942018-01-10 08:36:10 -08001566 if (parser != NULL)
1567 parser->m_startDoctypeDeclHandler = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001568}
1569
1570void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001571XML_SetEndDoctypeDeclHandler(XML_Parser parser, XML_EndDoctypeDeclHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001572 if (parser != NULL)
1573 parser->m_endDoctypeDeclHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001574}
1575
1576void XMLCALL
1577XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001578 XML_UnparsedEntityDeclHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001579 if (parser != NULL)
1580 parser->m_unparsedEntityDeclHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001581}
1582
1583void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001584XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001585 if (parser != NULL)
1586 parser->m_notationDeclHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001587}
1588
1589void XMLCALL
1590XML_SetNamespaceDeclHandler(XML_Parser parser,
1591 XML_StartNamespaceDeclHandler start,
Haibo Huang40a71912019-10-11 11:13:39 -07001592 XML_EndNamespaceDeclHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001593 if (parser == NULL)
1594 return;
1595 parser->m_startNamespaceDeclHandler = start;
1596 parser->m_endNamespaceDeclHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001597}
1598
1599void XMLCALL
1600XML_SetStartNamespaceDeclHandler(XML_Parser parser,
1601 XML_StartNamespaceDeclHandler start) {
Elliott Hughes72472942018-01-10 08:36:10 -08001602 if (parser != NULL)
1603 parser->m_startNamespaceDeclHandler = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001604}
1605
1606void XMLCALL
1607XML_SetEndNamespaceDeclHandler(XML_Parser parser,
1608 XML_EndNamespaceDeclHandler end) {
Elliott Hughes72472942018-01-10 08:36:10 -08001609 if (parser != NULL)
1610 parser->m_endNamespaceDeclHandler = end;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001611}
1612
1613void XMLCALL
1614XML_SetNotStandaloneHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001615 XML_NotStandaloneHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001616 if (parser != NULL)
1617 parser->m_notStandaloneHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001618}
1619
1620void XMLCALL
1621XML_SetExternalEntityRefHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001622 XML_ExternalEntityRefHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001623 if (parser != NULL)
1624 parser->m_externalEntityRefHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001625}
1626
1627void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001628XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) {
Elliott Hughes72472942018-01-10 08:36:10 -08001629 if (parser == NULL)
1630 return;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001631 if (arg)
Elliott Hughes72472942018-01-10 08:36:10 -08001632 parser->m_externalEntityRefHandlerArg = (XML_Parser)arg;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001633 else
Elliott Hughes72472942018-01-10 08:36:10 -08001634 parser->m_externalEntityRefHandlerArg = parser;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001635}
1636
1637void XMLCALL
1638XML_SetSkippedEntityHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001639 XML_SkippedEntityHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001640 if (parser != NULL)
1641 parser->m_skippedEntityHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001642}
1643
1644void XMLCALL
1645XML_SetUnknownEncodingHandler(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001646 XML_UnknownEncodingHandler handler, void *data) {
Elliott Hughes72472942018-01-10 08:36:10 -08001647 if (parser == NULL)
1648 return;
1649 parser->m_unknownEncodingHandler = handler;
1650 parser->m_unknownEncodingHandlerData = data;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001651}
1652
1653void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001654XML_SetElementDeclHandler(XML_Parser parser, XML_ElementDeclHandler eldecl) {
Elliott Hughes72472942018-01-10 08:36:10 -08001655 if (parser != NULL)
1656 parser->m_elementDeclHandler = eldecl;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001657}
1658
1659void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001660XML_SetAttlistDeclHandler(XML_Parser parser, XML_AttlistDeclHandler attdecl) {
Elliott Hughes72472942018-01-10 08:36:10 -08001661 if (parser != NULL)
1662 parser->m_attlistDeclHandler = attdecl;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001663}
1664
1665void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001666XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001667 if (parser != NULL)
1668 parser->m_entityDeclHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001669}
1670
1671void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001672XML_SetXmlDeclHandler(XML_Parser parser, XML_XmlDeclHandler handler) {
Elliott Hughes72472942018-01-10 08:36:10 -08001673 if (parser != NULL)
1674 parser->m_xmlDeclHandler = handler;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001675}
1676
1677int XMLCALL
1678XML_SetParamEntityParsing(XML_Parser parser,
Haibo Huang40a71912019-10-11 11:13:39 -07001679 enum XML_ParamEntityParsing peParsing) {
Elliott Hughes72472942018-01-10 08:36:10 -08001680 if (parser == NULL)
1681 return 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001682 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Haibo Huang40a71912019-10-11 11:13:39 -07001683 if (parser->m_parsingStatus.parsing == XML_PARSING
1684 || parser->m_parsingStatus.parsing == XML_SUSPENDED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001685 return 0;
1686#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08001687 parser->m_paramEntityParsing = peParsing;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001688 return 1;
1689#else
1690 return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
1691#endif
1692}
1693
Elliott Hughes35e432d2012-09-09 14:23:38 -07001694int XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001695XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt) {
Elliott Hughes72472942018-01-10 08:36:10 -08001696 if (parser == NULL)
Elliott Hughes35e432d2012-09-09 14:23:38 -07001697 return 0;
Elliott Hughes72472942018-01-10 08:36:10 -08001698 if (parser->m_parentParser)
1699 return XML_SetHashSalt(parser->m_parentParser, hash_salt);
1700 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Haibo Huang40a71912019-10-11 11:13:39 -07001701 if (parser->m_parsingStatus.parsing == XML_PARSING
1702 || parser->m_parsingStatus.parsing == XML_SUSPENDED)
Elliott Hughes72472942018-01-10 08:36:10 -08001703 return 0;
1704 parser->m_hash_secret_salt = hash_salt;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001705 return 1;
1706}
1707
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001708enum XML_Status XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001709XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) {
Elliott Hughes72472942018-01-10 08:36:10 -08001710 if ((parser == NULL) || (len < 0) || ((s == NULL) && (len != 0))) {
1711 if (parser != NULL)
1712 parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT;
1713 return XML_STATUS_ERROR;
1714 }
1715 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001716 case XML_SUSPENDED:
Elliott Hughes72472942018-01-10 08:36:10 -08001717 parser->m_errorCode = XML_ERROR_SUSPENDED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001718 return XML_STATUS_ERROR;
1719 case XML_FINISHED:
Elliott Hughes72472942018-01-10 08:36:10 -08001720 parser->m_errorCode = XML_ERROR_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001721 return XML_STATUS_ERROR;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001722 case XML_INITIALIZED:
Haibo Huang40a71912019-10-11 11:13:39 -07001723 if (parser->m_parentParser == NULL && ! startParsing(parser)) {
Elliott Hughes72472942018-01-10 08:36:10 -08001724 parser->m_errorCode = XML_ERROR_NO_MEMORY;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001725 return XML_STATUS_ERROR;
1726 }
Elliott Hughesaaec48e2018-08-16 16:29:01 -07001727 /* fall through */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001728 default:
Elliott Hughes72472942018-01-10 08:36:10 -08001729 parser->m_parsingStatus.parsing = XML_PARSING;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001730 }
1731
1732 if (len == 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08001733 parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
Haibo Huang40a71912019-10-11 11:13:39 -07001734 if (! isFinal)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001735 return XML_STATUS_OK;
Elliott Hughes72472942018-01-10 08:36:10 -08001736 parser->m_positionPtr = parser->m_bufferPtr;
1737 parser->m_parseEndPtr = parser->m_bufferEnd;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001738
1739 /* If data are left over from last buffer, and we now know that these
1740 data are the final chunk of input, then we have to check them again
1741 to detect errors based on that fact.
1742 */
Haibo Huang40a71912019-10-11 11:13:39 -07001743 parser->m_errorCode
1744 = parser->m_processor(parser, parser->m_bufferPtr,
1745 parser->m_parseEndPtr, &parser->m_bufferPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001746
Elliott Hughes72472942018-01-10 08:36:10 -08001747 if (parser->m_errorCode == XML_ERROR_NONE) {
1748 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001749 case XML_SUSPENDED:
Elliott Hughes72472942018-01-10 08:36:10 -08001750 /* It is hard to be certain, but it seems that this case
1751 * cannot occur. This code is cleaning up a previous parse
1752 * with no new data (since len == 0). Changing the parsing
1753 * state requires getting to execute a handler function, and
1754 * there doesn't seem to be an opportunity for that while in
1755 * this circumstance.
1756 *
1757 * Given the uncertainty, we retain the code but exclude it
1758 * from coverage tests.
1759 *
1760 * LCOV_EXCL_START
1761 */
Haibo Huang40a71912019-10-11 11:13:39 -07001762 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
1763 parser->m_bufferPtr, &parser->m_position);
Elliott Hughes72472942018-01-10 08:36:10 -08001764 parser->m_positionPtr = parser->m_bufferPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001765 return XML_STATUS_SUSPENDED;
Elliott Hughes72472942018-01-10 08:36:10 -08001766 /* LCOV_EXCL_STOP */
Elliott Hughes35e432d2012-09-09 14:23:38 -07001767 case XML_INITIALIZED:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001768 case XML_PARSING:
Elliott Hughes72472942018-01-10 08:36:10 -08001769 parser->m_parsingStatus.parsing = XML_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001770 /* fall through */
1771 default:
1772 return XML_STATUS_OK;
1773 }
1774 }
Elliott Hughes72472942018-01-10 08:36:10 -08001775 parser->m_eventEndPtr = parser->m_eventPtr;
1776 parser->m_processor = errorProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001777 return XML_STATUS_ERROR;
1778 }
1779#ifndef XML_CONTEXT_BYTES
Elliott Hughes72472942018-01-10 08:36:10 -08001780 else if (parser->m_bufferPtr == parser->m_bufferEnd) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001781 const char *end;
1782 int nLeftOver;
Paul Duffinc05e0322016-05-04 10:42:31 +01001783 enum XML_Status result;
Elliott Hughes72472942018-01-10 08:36:10 -08001784 /* Detect overflow (a+b > MAX <==> b > MAX-a) */
1785 if (len > ((XML_Size)-1) / 2 - parser->m_parseEndByteIndex) {
Haibo Huang40a71912019-10-11 11:13:39 -07001786 parser->m_errorCode = XML_ERROR_NO_MEMORY;
1787 parser->m_eventPtr = parser->m_eventEndPtr = NULL;
1788 parser->m_processor = errorProcessor;
1789 return XML_STATUS_ERROR;
Elliott Hughes72472942018-01-10 08:36:10 -08001790 }
1791 parser->m_parseEndByteIndex += len;
1792 parser->m_positionPtr = s;
1793 parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001794
Haibo Huang40a71912019-10-11 11:13:39 -07001795 parser->m_errorCode
1796 = parser->m_processor(parser, s, parser->m_parseEndPtr = s + len, &end);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001797
Elliott Hughes72472942018-01-10 08:36:10 -08001798 if (parser->m_errorCode != XML_ERROR_NONE) {
1799 parser->m_eventEndPtr = parser->m_eventPtr;
1800 parser->m_processor = errorProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001801 return XML_STATUS_ERROR;
Haibo Huang40a71912019-10-11 11:13:39 -07001802 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08001803 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001804 case XML_SUSPENDED:
1805 result = XML_STATUS_SUSPENDED;
1806 break;
1807 case XML_INITIALIZED:
1808 case XML_PARSING:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001809 if (isFinal) {
Elliott Hughes72472942018-01-10 08:36:10 -08001810 parser->m_parsingStatus.parsing = XML_FINISHED;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001811 return XML_STATUS_OK;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001812 }
Elliott Hughes35e432d2012-09-09 14:23:38 -07001813 /* fall through */
1814 default:
1815 result = XML_STATUS_OK;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001816 }
1817 }
1818
Haibo Huang40a71912019-10-11 11:13:39 -07001819 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, end,
1820 &parser->m_position);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001821 nLeftOver = s + len - end;
1822 if (nLeftOver) {
Haibo Huang40a71912019-10-11 11:13:39 -07001823 if (parser->m_buffer == NULL
1824 || nLeftOver > parser->m_bufferLim - parser->m_buffer) {
Elliott Hughes72472942018-01-10 08:36:10 -08001825 /* avoid _signed_ integer overflow */
1826 char *temp = NULL;
1827 const int bytesToAllocate = (int)((unsigned)len * 2U);
1828 if (bytesToAllocate > 0) {
1829 temp = (char *)REALLOC(parser, parser->m_buffer, bytesToAllocate);
1830 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001831 if (temp == NULL) {
Elliott Hughes72472942018-01-10 08:36:10 -08001832 parser->m_errorCode = XML_ERROR_NO_MEMORY;
1833 parser->m_eventPtr = parser->m_eventEndPtr = NULL;
1834 parser->m_processor = errorProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001835 return XML_STATUS_ERROR;
1836 }
Elliott Hughes72472942018-01-10 08:36:10 -08001837 parser->m_buffer = temp;
1838 parser->m_bufferLim = parser->m_buffer + bytesToAllocate;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001839 }
Elliott Hughes72472942018-01-10 08:36:10 -08001840 memcpy(parser->m_buffer, end, nLeftOver);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001841 }
Elliott Hughes72472942018-01-10 08:36:10 -08001842 parser->m_bufferPtr = parser->m_buffer;
1843 parser->m_bufferEnd = parser->m_buffer + nLeftOver;
1844 parser->m_positionPtr = parser->m_bufferPtr;
1845 parser->m_parseEndPtr = parser->m_bufferEnd;
1846 parser->m_eventPtr = parser->m_bufferPtr;
1847 parser->m_eventEndPtr = parser->m_bufferPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001848 return result;
1849 }
Haibo Huang40a71912019-10-11 11:13:39 -07001850#endif /* not defined XML_CONTEXT_BYTES */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001851 else {
1852 void *buff = XML_GetBuffer(parser, len);
1853 if (buff == NULL)
1854 return XML_STATUS_ERROR;
1855 else {
1856 memcpy(buff, s, len);
1857 return XML_ParseBuffer(parser, len, isFinal);
1858 }
1859 }
1860}
1861
1862enum XML_Status XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07001863XML_ParseBuffer(XML_Parser parser, int len, int isFinal) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001864 const char *start;
1865 enum XML_Status result = XML_STATUS_OK;
1866
Elliott Hughes72472942018-01-10 08:36:10 -08001867 if (parser == NULL)
1868 return XML_STATUS_ERROR;
1869 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001870 case XML_SUSPENDED:
Elliott Hughes72472942018-01-10 08:36:10 -08001871 parser->m_errorCode = XML_ERROR_SUSPENDED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001872 return XML_STATUS_ERROR;
1873 case XML_FINISHED:
Elliott Hughes72472942018-01-10 08:36:10 -08001874 parser->m_errorCode = XML_ERROR_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001875 return XML_STATUS_ERROR;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001876 case XML_INITIALIZED:
Haibo Huang40a71912019-10-11 11:13:39 -07001877 if (parser->m_parentParser == NULL && ! startParsing(parser)) {
Elliott Hughes72472942018-01-10 08:36:10 -08001878 parser->m_errorCode = XML_ERROR_NO_MEMORY;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001879 return XML_STATUS_ERROR;
1880 }
Elliott Hughesaaec48e2018-08-16 16:29:01 -07001881 /* fall through */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001882 default:
Elliott Hughes72472942018-01-10 08:36:10 -08001883 parser->m_parsingStatus.parsing = XML_PARSING;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001884 }
1885
Elliott Hughes72472942018-01-10 08:36:10 -08001886 start = parser->m_bufferPtr;
1887 parser->m_positionPtr = start;
1888 parser->m_bufferEnd += len;
1889 parser->m_parseEndPtr = parser->m_bufferEnd;
1890 parser->m_parseEndByteIndex += len;
1891 parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001892
Haibo Huang40a71912019-10-11 11:13:39 -07001893 parser->m_errorCode = parser->m_processor(
1894 parser, start, parser->m_parseEndPtr, &parser->m_bufferPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001895
Elliott Hughes72472942018-01-10 08:36:10 -08001896 if (parser->m_errorCode != XML_ERROR_NONE) {
1897 parser->m_eventEndPtr = parser->m_eventPtr;
1898 parser->m_processor = errorProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001899 return XML_STATUS_ERROR;
Haibo Huang40a71912019-10-11 11:13:39 -07001900 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08001901 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001902 case XML_SUSPENDED:
1903 result = XML_STATUS_SUSPENDED;
1904 break;
Elliott Hughes35e432d2012-09-09 14:23:38 -07001905 case XML_INITIALIZED:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001906 case XML_PARSING:
1907 if (isFinal) {
Elliott Hughes72472942018-01-10 08:36:10 -08001908 parser->m_parsingStatus.parsing = XML_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001909 return result;
1910 }
Haibo Huang40a71912019-10-11 11:13:39 -07001911 default:; /* should not happen */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001912 }
1913 }
1914
Haibo Huang40a71912019-10-11 11:13:39 -07001915 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
1916 parser->m_bufferPtr, &parser->m_position);
Elliott Hughes72472942018-01-10 08:36:10 -08001917 parser->m_positionPtr = parser->m_bufferPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001918 return result;
1919}
1920
Haibo Huang40a71912019-10-11 11:13:39 -07001921void *XMLCALL
1922XML_GetBuffer(XML_Parser parser, int len) {
Elliott Hughes72472942018-01-10 08:36:10 -08001923 if (parser == NULL)
1924 return NULL;
Paul Duffinc05e0322016-05-04 10:42:31 +01001925 if (len < 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08001926 parser->m_errorCode = XML_ERROR_NO_MEMORY;
Paul Duffinc05e0322016-05-04 10:42:31 +01001927 return NULL;
1928 }
Elliott Hughes72472942018-01-10 08:36:10 -08001929 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001930 case XML_SUSPENDED:
Elliott Hughes72472942018-01-10 08:36:10 -08001931 parser->m_errorCode = XML_ERROR_SUSPENDED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001932 return NULL;
1933 case XML_FINISHED:
Elliott Hughes72472942018-01-10 08:36:10 -08001934 parser->m_errorCode = XML_ERROR_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001935 return NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07001936 default:;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001937 }
1938
Elliott Hughesaaec48e2018-08-16 16:29:01 -07001939 if (len > EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferEnd)) {
Paul Duffinba34a0c2017-02-27 14:40:16 +00001940#ifdef XML_CONTEXT_BYTES
1941 int keep;
Haibo Huang40a71912019-10-11 11:13:39 -07001942#endif /* defined XML_CONTEXT_BYTES */
Paul Duffinba34a0c2017-02-27 14:40:16 +00001943 /* Do not invoke signed arithmetic overflow: */
Haibo Huang40a71912019-10-11 11:13:39 -07001944 int neededSize = (int)((unsigned)len
1945 + (unsigned)EXPAT_SAFE_PTR_DIFF(
1946 parser->m_bufferEnd, parser->m_bufferPtr));
Paul Duffinc05e0322016-05-04 10:42:31 +01001947 if (neededSize < 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08001948 parser->m_errorCode = XML_ERROR_NO_MEMORY;
Paul Duffinc05e0322016-05-04 10:42:31 +01001949 return NULL;
1950 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001951#ifdef XML_CONTEXT_BYTES
Elliott Hughesaaec48e2018-08-16 16:29:01 -07001952 keep = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001953 if (keep > XML_CONTEXT_BYTES)
1954 keep = XML_CONTEXT_BYTES;
1955 neededSize += keep;
Haibo Huang40a71912019-10-11 11:13:39 -07001956#endif /* defined XML_CONTEXT_BYTES */
1957 if (neededSize
1958 <= EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_buffer)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001959#ifdef XML_CONTEXT_BYTES
Elliott Hughesaaec48e2018-08-16 16:29:01 -07001960 if (keep < EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer)) {
Haibo Huang40a71912019-10-11 11:13:39 -07001961 int offset
1962 = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer)
1963 - keep;
1964 /* The buffer pointers cannot be NULL here; we have at least some bytes
1965 * in the buffer */
1966 memmove(parser->m_buffer, &parser->m_buffer[offset],
1967 parser->m_bufferEnd - parser->m_bufferPtr + keep);
Elliott Hughes72472942018-01-10 08:36:10 -08001968 parser->m_bufferEnd -= offset;
1969 parser->m_bufferPtr -= offset;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001970 }
1971#else
Elliott Hughesaaec48e2018-08-16 16:29:01 -07001972 if (parser->m_buffer && parser->m_bufferPtr) {
1973 memmove(parser->m_buffer, parser->m_bufferPtr,
1974 EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr));
Haibo Huang40a71912019-10-11 11:13:39 -07001975 parser->m_bufferEnd
1976 = parser->m_buffer
1977 + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr);
Elliott Hughesaaec48e2018-08-16 16:29:01 -07001978 parser->m_bufferPtr = parser->m_buffer;
1979 }
Haibo Huang40a71912019-10-11 11:13:39 -07001980#endif /* not defined XML_CONTEXT_BYTES */
1981 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001982 char *newBuf;
Haibo Huang40a71912019-10-11 11:13:39 -07001983 int bufferSize
1984 = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001985 if (bufferSize == 0)
1986 bufferSize = INIT_BUFFER_SIZE;
1987 do {
Paul Duffinba34a0c2017-02-27 14:40:16 +00001988 /* Do not invoke signed arithmetic overflow: */
Haibo Huang40a71912019-10-11 11:13:39 -07001989 bufferSize = (int)(2U * (unsigned)bufferSize);
Paul Duffinc05e0322016-05-04 10:42:31 +01001990 } while (bufferSize < neededSize && bufferSize > 0);
1991 if (bufferSize <= 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08001992 parser->m_errorCode = XML_ERROR_NO_MEMORY;
Paul Duffinc05e0322016-05-04 10:42:31 +01001993 return NULL;
1994 }
Elliott Hughes72472942018-01-10 08:36:10 -08001995 newBuf = (char *)MALLOC(parser, bufferSize);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001996 if (newBuf == 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08001997 parser->m_errorCode = XML_ERROR_NO_MEMORY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001998 return NULL;
1999 }
Elliott Hughes72472942018-01-10 08:36:10 -08002000 parser->m_bufferLim = newBuf + bufferSize;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002001#ifdef XML_CONTEXT_BYTES
Elliott Hughes72472942018-01-10 08:36:10 -08002002 if (parser->m_bufferPtr) {
Elliott Hughesaaec48e2018-08-16 16:29:01 -07002003 memcpy(newBuf, &parser->m_bufferPtr[-keep],
Haibo Huang40a71912019-10-11 11:13:39 -07002004 EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)
2005 + keep);
Elliott Hughes72472942018-01-10 08:36:10 -08002006 FREE(parser, parser->m_buffer);
2007 parser->m_buffer = newBuf;
Haibo Huang40a71912019-10-11 11:13:39 -07002008 parser->m_bufferEnd
2009 = parser->m_buffer
2010 + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)
2011 + keep;
Elliott Hughes72472942018-01-10 08:36:10 -08002012 parser->m_bufferPtr = parser->m_buffer + keep;
Haibo Huang40a71912019-10-11 11:13:39 -07002013 } else {
Elliott Hughesaaec48e2018-08-16 16:29:01 -07002014 /* This must be a brand new buffer with no data in it yet */
2015 parser->m_bufferEnd = newBuf;
Elliott Hughes72472942018-01-10 08:36:10 -08002016 parser->m_bufferPtr = parser->m_buffer = newBuf;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002017 }
2018#else
Elliott Hughes72472942018-01-10 08:36:10 -08002019 if (parser->m_bufferPtr) {
Elliott Hughesaaec48e2018-08-16 16:29:01 -07002020 memcpy(newBuf, parser->m_bufferPtr,
2021 EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr));
Elliott Hughes72472942018-01-10 08:36:10 -08002022 FREE(parser, parser->m_buffer);
Haibo Huang40a71912019-10-11 11:13:39 -07002023 parser->m_bufferEnd
2024 = newBuf
2025 + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr);
2026 } else {
Elliott Hughesaaec48e2018-08-16 16:29:01 -07002027 /* This must be a brand new buffer with no data in it yet */
2028 parser->m_bufferEnd = newBuf;
2029 }
Elliott Hughes72472942018-01-10 08:36:10 -08002030 parser->m_bufferPtr = parser->m_buffer = newBuf;
Haibo Huang40a71912019-10-11 11:13:39 -07002031#endif /* not defined XML_CONTEXT_BYTES */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002032 }
Elliott Hughes72472942018-01-10 08:36:10 -08002033 parser->m_eventPtr = parser->m_eventEndPtr = NULL;
2034 parser->m_positionPtr = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002035 }
Elliott Hughes72472942018-01-10 08:36:10 -08002036 return parser->m_bufferEnd;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002037}
2038
2039enum XML_Status XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002040XML_StopParser(XML_Parser parser, XML_Bool resumable) {
Elliott Hughes72472942018-01-10 08:36:10 -08002041 if (parser == NULL)
2042 return XML_STATUS_ERROR;
2043 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002044 case XML_SUSPENDED:
2045 if (resumable) {
Elliott Hughes72472942018-01-10 08:36:10 -08002046 parser->m_errorCode = XML_ERROR_SUSPENDED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002047 return XML_STATUS_ERROR;
2048 }
Elliott Hughes72472942018-01-10 08:36:10 -08002049 parser->m_parsingStatus.parsing = XML_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002050 break;
2051 case XML_FINISHED:
Elliott Hughes72472942018-01-10 08:36:10 -08002052 parser->m_errorCode = XML_ERROR_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002053 return XML_STATUS_ERROR;
2054 default:
2055 if (resumable) {
2056#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08002057 if (parser->m_isParamEntity) {
2058 parser->m_errorCode = XML_ERROR_SUSPEND_PE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002059 return XML_STATUS_ERROR;
2060 }
2061#endif
Elliott Hughes72472942018-01-10 08:36:10 -08002062 parser->m_parsingStatus.parsing = XML_SUSPENDED;
Haibo Huang40a71912019-10-11 11:13:39 -07002063 } else
Elliott Hughes72472942018-01-10 08:36:10 -08002064 parser->m_parsingStatus.parsing = XML_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002065 }
2066 return XML_STATUS_OK;
2067}
2068
2069enum XML_Status XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002070XML_ResumeParser(XML_Parser parser) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002071 enum XML_Status result = XML_STATUS_OK;
2072
Elliott Hughes72472942018-01-10 08:36:10 -08002073 if (parser == NULL)
2074 return XML_STATUS_ERROR;
2075 if (parser->m_parsingStatus.parsing != XML_SUSPENDED) {
2076 parser->m_errorCode = XML_ERROR_NOT_SUSPENDED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002077 return XML_STATUS_ERROR;
2078 }
Elliott Hughes72472942018-01-10 08:36:10 -08002079 parser->m_parsingStatus.parsing = XML_PARSING;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002080
Haibo Huang40a71912019-10-11 11:13:39 -07002081 parser->m_errorCode = parser->m_processor(
2082 parser, parser->m_bufferPtr, parser->m_parseEndPtr, &parser->m_bufferPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002083
Elliott Hughes72472942018-01-10 08:36:10 -08002084 if (parser->m_errorCode != XML_ERROR_NONE) {
2085 parser->m_eventEndPtr = parser->m_eventPtr;
2086 parser->m_processor = errorProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002087 return XML_STATUS_ERROR;
Haibo Huang40a71912019-10-11 11:13:39 -07002088 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08002089 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002090 case XML_SUSPENDED:
2091 result = XML_STATUS_SUSPENDED;
2092 break;
Elliott Hughes35e432d2012-09-09 14:23:38 -07002093 case XML_INITIALIZED:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002094 case XML_PARSING:
Elliott Hughes72472942018-01-10 08:36:10 -08002095 if (parser->m_parsingStatus.finalBuffer) {
2096 parser->m_parsingStatus.parsing = XML_FINISHED;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002097 return result;
2098 }
Haibo Huang40a71912019-10-11 11:13:39 -07002099 default:;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002100 }
2101 }
2102
Haibo Huang40a71912019-10-11 11:13:39 -07002103 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
2104 parser->m_bufferPtr, &parser->m_position);
Elliott Hughes72472942018-01-10 08:36:10 -08002105 parser->m_positionPtr = parser->m_bufferPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002106 return result;
2107}
2108
2109void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002110XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status) {
Elliott Hughes72472942018-01-10 08:36:10 -08002111 if (parser == NULL)
2112 return;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002113 assert(status != NULL);
2114 *status = parser->m_parsingStatus;
2115}
2116
2117enum XML_Error XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002118XML_GetErrorCode(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002119 if (parser == NULL)
2120 return XML_ERROR_INVALID_ARGUMENT;
2121 return parser->m_errorCode;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002122}
2123
2124XML_Index XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002125XML_GetCurrentByteIndex(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002126 if (parser == NULL)
2127 return -1;
2128 if (parser->m_eventPtr)
Haibo Huang40a71912019-10-11 11:13:39 -07002129 return (XML_Index)(parser->m_parseEndByteIndex
2130 - (parser->m_parseEndPtr - parser->m_eventPtr));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002131 return -1;
2132}
2133
2134int XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002135XML_GetCurrentByteCount(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002136 if (parser == NULL)
2137 return 0;
2138 if (parser->m_eventEndPtr && parser->m_eventPtr)
2139 return (int)(parser->m_eventEndPtr - parser->m_eventPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002140 return 0;
2141}
2142
Haibo Huang40a71912019-10-11 11:13:39 -07002143const char *XMLCALL
2144XML_GetInputContext(XML_Parser parser, int *offset, int *size) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002145#ifdef XML_CONTEXT_BYTES
Elliott Hughes72472942018-01-10 08:36:10 -08002146 if (parser == NULL)
2147 return NULL;
2148 if (parser->m_eventPtr && parser->m_buffer) {
2149 if (offset != NULL)
2150 *offset = (int)(parser->m_eventPtr - parser->m_buffer);
2151 if (size != NULL)
Haibo Huang40a71912019-10-11 11:13:39 -07002152 *size = (int)(parser->m_bufferEnd - parser->m_buffer);
Elliott Hughes72472942018-01-10 08:36:10 -08002153 return parser->m_buffer;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002154 }
Elliott Hughes72472942018-01-10 08:36:10 -08002155#else
2156 (void)parser;
2157 (void)offset;
2158 (void)size;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002159#endif /* defined XML_CONTEXT_BYTES */
Haibo Huang40a71912019-10-11 11:13:39 -07002160 return (char *)0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002161}
2162
2163XML_Size XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002164XML_GetCurrentLineNumber(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002165 if (parser == NULL)
2166 return 0;
2167 if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) {
Haibo Huang40a71912019-10-11 11:13:39 -07002168 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
2169 parser->m_eventPtr, &parser->m_position);
Elliott Hughes72472942018-01-10 08:36:10 -08002170 parser->m_positionPtr = parser->m_eventPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002171 }
Elliott Hughes72472942018-01-10 08:36:10 -08002172 return parser->m_position.lineNumber + 1;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002173}
2174
2175XML_Size XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002176XML_GetCurrentColumnNumber(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002177 if (parser == NULL)
2178 return 0;
2179 if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) {
Haibo Huang40a71912019-10-11 11:13:39 -07002180 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
2181 parser->m_eventPtr, &parser->m_position);
Elliott Hughes72472942018-01-10 08:36:10 -08002182 parser->m_positionPtr = parser->m_eventPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002183 }
Elliott Hughes72472942018-01-10 08:36:10 -08002184 return parser->m_position.columnNumber;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002185}
2186
2187void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002188XML_FreeContentModel(XML_Parser parser, XML_Content *model) {
Elliott Hughes72472942018-01-10 08:36:10 -08002189 if (parser != NULL)
2190 FREE(parser, model);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002191}
2192
Haibo Huang40a71912019-10-11 11:13:39 -07002193void *XMLCALL
2194XML_MemMalloc(XML_Parser parser, size_t size) {
Elliott Hughes72472942018-01-10 08:36:10 -08002195 if (parser == NULL)
2196 return NULL;
2197 return MALLOC(parser, size);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002198}
2199
Haibo Huang40a71912019-10-11 11:13:39 -07002200void *XMLCALL
2201XML_MemRealloc(XML_Parser parser, void *ptr, size_t size) {
Elliott Hughes72472942018-01-10 08:36:10 -08002202 if (parser == NULL)
2203 return NULL;
2204 return REALLOC(parser, ptr, size);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002205}
2206
2207void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002208XML_MemFree(XML_Parser parser, void *ptr) {
Elliott Hughes72472942018-01-10 08:36:10 -08002209 if (parser != NULL)
2210 FREE(parser, ptr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002211}
2212
2213void XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002214XML_DefaultCurrent(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002215 if (parser == NULL)
2216 return;
2217 if (parser->m_defaultHandler) {
2218 if (parser->m_openInternalEntities)
Haibo Huang40a71912019-10-11 11:13:39 -07002219 reportDefault(parser, parser->m_internalEncoding,
Elliott Hughes72472942018-01-10 08:36:10 -08002220 parser->m_openInternalEntities->internalEventPtr,
2221 parser->m_openInternalEntities->internalEventEndPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002222 else
Haibo Huang40a71912019-10-11 11:13:39 -07002223 reportDefault(parser, parser->m_encoding, parser->m_eventPtr,
2224 parser->m_eventEndPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002225 }
2226}
2227
Haibo Huang40a71912019-10-11 11:13:39 -07002228const XML_LChar *XMLCALL
2229XML_ErrorString(enum XML_Error code) {
Elliott Hughes72472942018-01-10 08:36:10 -08002230 switch (code) {
2231 case XML_ERROR_NONE:
2232 return NULL;
2233 case XML_ERROR_NO_MEMORY:
2234 return XML_L("out of memory");
2235 case XML_ERROR_SYNTAX:
2236 return XML_L("syntax error");
2237 case XML_ERROR_NO_ELEMENTS:
2238 return XML_L("no element found");
2239 case XML_ERROR_INVALID_TOKEN:
2240 return XML_L("not well-formed (invalid token)");
2241 case XML_ERROR_UNCLOSED_TOKEN:
2242 return XML_L("unclosed token");
2243 case XML_ERROR_PARTIAL_CHAR:
2244 return XML_L("partial character");
2245 case XML_ERROR_TAG_MISMATCH:
2246 return XML_L("mismatched tag");
2247 case XML_ERROR_DUPLICATE_ATTRIBUTE:
2248 return XML_L("duplicate attribute");
2249 case XML_ERROR_JUNK_AFTER_DOC_ELEMENT:
2250 return XML_L("junk after document element");
2251 case XML_ERROR_PARAM_ENTITY_REF:
2252 return XML_L("illegal parameter entity reference");
2253 case XML_ERROR_UNDEFINED_ENTITY:
2254 return XML_L("undefined entity");
2255 case XML_ERROR_RECURSIVE_ENTITY_REF:
2256 return XML_L("recursive entity reference");
2257 case XML_ERROR_ASYNC_ENTITY:
2258 return XML_L("asynchronous entity");
2259 case XML_ERROR_BAD_CHAR_REF:
2260 return XML_L("reference to invalid character number");
2261 case XML_ERROR_BINARY_ENTITY_REF:
2262 return XML_L("reference to binary entity");
2263 case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF:
2264 return XML_L("reference to external entity in attribute");
2265 case XML_ERROR_MISPLACED_XML_PI:
2266 return XML_L("XML or text declaration not at start of entity");
2267 case XML_ERROR_UNKNOWN_ENCODING:
2268 return XML_L("unknown encoding");
2269 case XML_ERROR_INCORRECT_ENCODING:
2270 return XML_L("encoding specified in XML declaration is incorrect");
2271 case XML_ERROR_UNCLOSED_CDATA_SECTION:
2272 return XML_L("unclosed CDATA section");
2273 case XML_ERROR_EXTERNAL_ENTITY_HANDLING:
2274 return XML_L("error in processing external entity reference");
2275 case XML_ERROR_NOT_STANDALONE:
2276 return XML_L("document is not standalone");
2277 case XML_ERROR_UNEXPECTED_STATE:
2278 return XML_L("unexpected parser state - please send a bug report");
2279 case XML_ERROR_ENTITY_DECLARED_IN_PE:
2280 return XML_L("entity declared in parameter entity");
2281 case XML_ERROR_FEATURE_REQUIRES_XML_DTD:
2282 return XML_L("requested feature requires XML_DTD support in Expat");
2283 case XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING:
2284 return XML_L("cannot change setting once parsing has begun");
2285 /* Added in 1.95.7. */
2286 case XML_ERROR_UNBOUND_PREFIX:
2287 return XML_L("unbound prefix");
2288 /* Added in 1.95.8. */
2289 case XML_ERROR_UNDECLARING_PREFIX:
2290 return XML_L("must not undeclare prefix");
2291 case XML_ERROR_INCOMPLETE_PE:
2292 return XML_L("incomplete markup in parameter entity");
2293 case XML_ERROR_XML_DECL:
2294 return XML_L("XML declaration not well-formed");
2295 case XML_ERROR_TEXT_DECL:
2296 return XML_L("text declaration not well-formed");
2297 case XML_ERROR_PUBLICID:
2298 return XML_L("illegal character(s) in public id");
2299 case XML_ERROR_SUSPENDED:
2300 return XML_L("parser suspended");
2301 case XML_ERROR_NOT_SUSPENDED:
2302 return XML_L("parser not suspended");
2303 case XML_ERROR_ABORTED:
2304 return XML_L("parsing aborted");
2305 case XML_ERROR_FINISHED:
2306 return XML_L("parsing finished");
2307 case XML_ERROR_SUSPEND_PE:
2308 return XML_L("cannot suspend in external parameter entity");
2309 /* Added in 2.0.0. */
2310 case XML_ERROR_RESERVED_PREFIX_XML:
Haibo Huang40a71912019-10-11 11:13:39 -07002311 return XML_L(
2312 "reserved prefix (xml) must not be undeclared or bound to another namespace name");
Elliott Hughes72472942018-01-10 08:36:10 -08002313 case XML_ERROR_RESERVED_PREFIX_XMLNS:
2314 return XML_L("reserved prefix (xmlns) must not be declared or undeclared");
2315 case XML_ERROR_RESERVED_NAMESPACE_URI:
Haibo Huang40a71912019-10-11 11:13:39 -07002316 return XML_L(
2317 "prefix must not be bound to one of the reserved namespace names");
Elliott Hughes72472942018-01-10 08:36:10 -08002318 /* Added in 2.2.5. */
Haibo Huang40a71912019-10-11 11:13:39 -07002319 case XML_ERROR_INVALID_ARGUMENT: /* Constant added in 2.2.1, already */
Elliott Hughes72472942018-01-10 08:36:10 -08002320 return XML_L("invalid argument");
2321 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002322 return NULL;
2323}
2324
Haibo Huang40a71912019-10-11 11:13:39 -07002325const XML_LChar *XMLCALL
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002326XML_ExpatVersion(void) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002327 /* V1 is used to string-ize the version number. However, it would
2328 string-ize the actual version macro *names* unless we get them
2329 substituted before being passed to V1. CPP is defined to expand
2330 a macro, then rescan for more expansions. Thus, we use V2 to expand
2331 the version macros, then CPP will expand the resulting V1() macro
2332 with the correct numerals. */
2333 /* ### I'm assuming cpp is portable in this respect... */
2334
Haibo Huang40a71912019-10-11 11:13:39 -07002335#define V1(a, b, c) XML_L(#a) XML_L(".") XML_L(#b) XML_L(".") XML_L(#c)
2336#define V2(a, b, c) XML_L("expat_") V1(a, b, c)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002337
2338 return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
2339
2340#undef V1
2341#undef V2
2342}
2343
2344XML_Expat_Version XMLCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002345XML_ExpatVersionInfo(void) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002346 XML_Expat_Version version;
2347
2348 version.major = XML_MAJOR_VERSION;
2349 version.minor = XML_MINOR_VERSION;
2350 version.micro = XML_MICRO_VERSION;
2351
2352 return version;
2353}
2354
Haibo Huang40a71912019-10-11 11:13:39 -07002355const XML_Feature *XMLCALL
2356XML_GetFeatureList(void) {
2357 static const XML_Feature features[]
2358 = {{XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"),
2359 sizeof(XML_Char)},
2360 {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
2361 sizeof(XML_LChar)},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002362#ifdef XML_UNICODE
Haibo Huang40a71912019-10-11 11:13:39 -07002363 {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002364#endif
2365#ifdef XML_UNICODE_WCHAR_T
Haibo Huang40a71912019-10-11 11:13:39 -07002366 {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002367#endif
2368#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07002369 {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002370#endif
2371#ifdef XML_CONTEXT_BYTES
Haibo Huang40a71912019-10-11 11:13:39 -07002372 {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
2373 XML_CONTEXT_BYTES},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002374#endif
2375#ifdef XML_MIN_SIZE
Haibo Huang40a71912019-10-11 11:13:39 -07002376 {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002377#endif
2378#ifdef XML_NS
Haibo Huang40a71912019-10-11 11:13:39 -07002379 {XML_FEATURE_NS, XML_L("XML_NS"), 0},
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002380#endif
Elliott Hughesd07d5a72009-09-25 16:04:37 -07002381#ifdef XML_LARGE_SIZE
Haibo Huang40a71912019-10-11 11:13:39 -07002382 {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0},
Elliott Hughes35e432d2012-09-09 14:23:38 -07002383#endif
2384#ifdef XML_ATTR_INFO
Haibo Huang40a71912019-10-11 11:13:39 -07002385 {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0},
Elliott Hughes35e432d2012-09-09 14:23:38 -07002386#endif
Haibo Huang40a71912019-10-11 11:13:39 -07002387 {XML_FEATURE_END, NULL, 0}};
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002388
2389 return features;
2390}
2391
2392/* Initially tag->rawName always points into the parse buffer;
2393 for those TAG instances opened while the current parse buffer was
2394 processed, and not yet closed, we need to store tag->rawName in a more
2395 permanent location, since the parse buffer is about to be discarded.
2396*/
2397static XML_Bool
Haibo Huang40a71912019-10-11 11:13:39 -07002398storeRawNames(XML_Parser parser) {
Elliott Hughes72472942018-01-10 08:36:10 -08002399 TAG *tag = parser->m_tagStack;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002400 while (tag) {
2401 int bufSize;
2402 int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
2403 char *rawNameBuf = tag->buf + nameLen;
Elliott Hughes72472942018-01-10 08:36:10 -08002404 /* Stop if already stored. Since m_tagStack is a stack, we can stop
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002405 at the first entry that has already been copied; everything
2406 below it in the stack is already been accounted for in a
2407 previous call to this function.
2408 */
2409 if (tag->rawName == rawNameBuf)
2410 break;
2411 /* For re-use purposes we need to ensure that the
2412 size of tag->buf is a multiple of sizeof(XML_Char).
2413 */
2414 bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
2415 if (bufSize > tag->bufEnd - tag->buf) {
Elliott Hughes72472942018-01-10 08:36:10 -08002416 char *temp = (char *)REALLOC(parser, tag->buf, bufSize);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002417 if (temp == NULL)
2418 return XML_FALSE;
2419 /* if tag->name.str points to tag->buf (only when namespace
2420 processing is off) then we have to update it
2421 */
2422 if (tag->name.str == (XML_Char *)tag->buf)
2423 tag->name.str = (XML_Char *)temp;
2424 /* if tag->name.localPart is set (when namespace processing is on)
2425 then update it as well, since it will always point into tag->buf
2426 */
2427 if (tag->name.localPart)
Haibo Huang40a71912019-10-11 11:13:39 -07002428 tag->name.localPart
2429 = (XML_Char *)temp + (tag->name.localPart - (XML_Char *)tag->buf);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002430 tag->buf = temp;
2431 tag->bufEnd = temp + bufSize;
2432 rawNameBuf = temp + nameLen;
2433 }
2434 memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
2435 tag->rawName = rawNameBuf;
2436 tag = tag->parent;
2437 }
2438 return XML_TRUE;
2439}
2440
2441static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002442contentProcessor(XML_Parser parser, const char *start, const char *end,
2443 const char **endPtr) {
2444 enum XML_Error result
2445 = doContent(parser, 0, parser->m_encoding, start, end, endPtr,
2446 (XML_Bool)! parser->m_parsingStatus.finalBuffer);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002447 if (result == XML_ERROR_NONE) {
Haibo Huang40a71912019-10-11 11:13:39 -07002448 if (! storeRawNames(parser))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002449 return XML_ERROR_NO_MEMORY;
2450 }
2451 return result;
2452}
2453
2454static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002455externalEntityInitProcessor(XML_Parser parser, const char *start,
2456 const char *end, const char **endPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002457 enum XML_Error result = initializeEncoding(parser);
2458 if (result != XML_ERROR_NONE)
2459 return result;
Elliott Hughes72472942018-01-10 08:36:10 -08002460 parser->m_processor = externalEntityInitProcessor2;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002461 return externalEntityInitProcessor2(parser, start, end, endPtr);
2462}
2463
2464static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002465externalEntityInitProcessor2(XML_Parser parser, const char *start,
2466 const char *end, const char **endPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002467 const char *next = start; /* XmlContentTok doesn't always set the last arg */
Elliott Hughes72472942018-01-10 08:36:10 -08002468 int tok = XmlContentTok(parser->m_encoding, start, end, &next);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002469 switch (tok) {
2470 case XML_TOK_BOM:
2471 /* If we are at the end of the buffer, this would cause the next stage,
2472 i.e. externalEntityInitProcessor3, to pass control directly to
2473 doContent (by detecting XML_TOK_NONE) without processing any xml text
2474 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
2475 */
Haibo Huang40a71912019-10-11 11:13:39 -07002476 if (next == end && ! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002477 *endPtr = next;
2478 return XML_ERROR_NONE;
2479 }
2480 start = next;
2481 break;
2482 case XML_TOK_PARTIAL:
Haibo Huang40a71912019-10-11 11:13:39 -07002483 if (! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002484 *endPtr = start;
2485 return XML_ERROR_NONE;
2486 }
Elliott Hughes72472942018-01-10 08:36:10 -08002487 parser->m_eventPtr = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002488 return XML_ERROR_UNCLOSED_TOKEN;
2489 case XML_TOK_PARTIAL_CHAR:
Haibo Huang40a71912019-10-11 11:13:39 -07002490 if (! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002491 *endPtr = start;
2492 return XML_ERROR_NONE;
2493 }
Elliott Hughes72472942018-01-10 08:36:10 -08002494 parser->m_eventPtr = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002495 return XML_ERROR_PARTIAL_CHAR;
2496 }
Elliott Hughes72472942018-01-10 08:36:10 -08002497 parser->m_processor = externalEntityInitProcessor3;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002498 return externalEntityInitProcessor3(parser, start, end, endPtr);
2499}
2500
2501static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002502externalEntityInitProcessor3(XML_Parser parser, const char *start,
2503 const char *end, const char **endPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002504 int tok;
2505 const char *next = start; /* XmlContentTok doesn't always set the last arg */
Elliott Hughes72472942018-01-10 08:36:10 -08002506 parser->m_eventPtr = start;
2507 tok = XmlContentTok(parser->m_encoding, start, end, &next);
2508 parser->m_eventEndPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002509
2510 switch (tok) {
Haibo Huang40a71912019-10-11 11:13:39 -07002511 case XML_TOK_XML_DECL: {
2512 enum XML_Error result;
2513 result = processXmlDecl(parser, 1, start, next);
2514 if (result != XML_ERROR_NONE)
2515 return result;
2516 switch (parser->m_parsingStatus.parsing) {
2517 case XML_SUSPENDED:
2518 *endPtr = next;
2519 return XML_ERROR_NONE;
2520 case XML_FINISHED:
2521 return XML_ERROR_ABORTED;
2522 default:
2523 start = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002524 }
Haibo Huang40a71912019-10-11 11:13:39 -07002525 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002526 case XML_TOK_PARTIAL:
Haibo Huang40a71912019-10-11 11:13:39 -07002527 if (! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002528 *endPtr = start;
2529 return XML_ERROR_NONE;
2530 }
2531 return XML_ERROR_UNCLOSED_TOKEN;
2532 case XML_TOK_PARTIAL_CHAR:
Haibo Huang40a71912019-10-11 11:13:39 -07002533 if (! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002534 *endPtr = start;
2535 return XML_ERROR_NONE;
2536 }
2537 return XML_ERROR_PARTIAL_CHAR;
2538 }
Elliott Hughes72472942018-01-10 08:36:10 -08002539 parser->m_processor = externalEntityContentProcessor;
2540 parser->m_tagLevel = 1;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002541 return externalEntityContentProcessor(parser, start, end, endPtr);
2542}
2543
2544static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07002545externalEntityContentProcessor(XML_Parser parser, const char *start,
2546 const char *end, const char **endPtr) {
2547 enum XML_Error result
2548 = doContent(parser, 1, parser->m_encoding, start, end, endPtr,
2549 (XML_Bool)! parser->m_parsingStatus.finalBuffer);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002550 if (result == XML_ERROR_NONE) {
Haibo Huang40a71912019-10-11 11:13:39 -07002551 if (! storeRawNames(parser))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002552 return XML_ERROR_NO_MEMORY;
2553 }
2554 return result;
2555}
2556
2557static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07002558doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
2559 const char *s, const char *end, const char **nextPtr,
2560 XML_Bool haveMore) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002561 /* save one level of indirection */
Haibo Huang40a71912019-10-11 11:13:39 -07002562 DTD *const dtd = parser->m_dtd;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002563
2564 const char **eventPP;
2565 const char **eventEndPP;
Elliott Hughes72472942018-01-10 08:36:10 -08002566 if (enc == parser->m_encoding) {
2567 eventPP = &parser->m_eventPtr;
2568 eventEndPP = &parser->m_eventEndPtr;
Haibo Huang40a71912019-10-11 11:13:39 -07002569 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08002570 eventPP = &(parser->m_openInternalEntities->internalEventPtr);
2571 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002572 }
2573 *eventPP = s;
2574
2575 for (;;) {
2576 const char *next = s; /* XmlContentTok doesn't always set the last arg */
2577 int tok = XmlContentTok(enc, s, end, &next);
2578 *eventEndPP = next;
2579 switch (tok) {
2580 case XML_TOK_TRAILING_CR:
2581 if (haveMore) {
2582 *nextPtr = s;
2583 return XML_ERROR_NONE;
2584 }
2585 *eventEndPP = end;
Elliott Hughes72472942018-01-10 08:36:10 -08002586 if (parser->m_characterDataHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002587 XML_Char c = 0xA;
Elliott Hughes72472942018-01-10 08:36:10 -08002588 parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
Haibo Huang40a71912019-10-11 11:13:39 -07002589 } else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002590 reportDefault(parser, enc, s, end);
Elliott Hughes35e432d2012-09-09 14:23:38 -07002591 /* We are at the end of the final buffer, should we check for
2592 XML_SUSPENDED, XML_FINISHED?
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002593 */
2594 if (startTagLevel == 0)
2595 return XML_ERROR_NO_ELEMENTS;
Elliott Hughes72472942018-01-10 08:36:10 -08002596 if (parser->m_tagLevel != startTagLevel)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002597 return XML_ERROR_ASYNC_ENTITY;
2598 *nextPtr = end;
2599 return XML_ERROR_NONE;
2600 case XML_TOK_NONE:
2601 if (haveMore) {
2602 *nextPtr = s;
2603 return XML_ERROR_NONE;
2604 }
2605 if (startTagLevel > 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08002606 if (parser->m_tagLevel != startTagLevel)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002607 return XML_ERROR_ASYNC_ENTITY;
2608 *nextPtr = s;
2609 return XML_ERROR_NONE;
2610 }
2611 return XML_ERROR_NO_ELEMENTS;
2612 case XML_TOK_INVALID:
2613 *eventPP = next;
2614 return XML_ERROR_INVALID_TOKEN;
2615 case XML_TOK_PARTIAL:
2616 if (haveMore) {
2617 *nextPtr = s;
2618 return XML_ERROR_NONE;
2619 }
2620 return XML_ERROR_UNCLOSED_TOKEN;
2621 case XML_TOK_PARTIAL_CHAR:
2622 if (haveMore) {
2623 *nextPtr = s;
2624 return XML_ERROR_NONE;
2625 }
2626 return XML_ERROR_PARTIAL_CHAR;
Haibo Huang40a71912019-10-11 11:13:39 -07002627 case XML_TOK_ENTITY_REF: {
2628 const XML_Char *name;
2629 ENTITY *entity;
2630 XML_Char ch = (XML_Char)XmlPredefinedEntityName(
2631 enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar);
2632 if (ch) {
2633 if (parser->m_characterDataHandler)
2634 parser->m_characterDataHandler(parser->m_handlerArg, &ch, 1);
Elliott Hughes72472942018-01-10 08:36:10 -08002635 else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002636 reportDefault(parser, enc, s, next);
2637 break;
2638 }
Haibo Huang40a71912019-10-11 11:13:39 -07002639 name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
2640 next - enc->minBytesPerChar);
2641 if (! name)
2642 return XML_ERROR_NO_MEMORY;
2643 entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
2644 poolDiscard(&dtd->pool);
2645 /* First, determine if a check for an existing declaration is needed;
2646 if yes, check that the entity exists, and that it is internal,
2647 otherwise call the skipped entity or default handler.
2648 */
2649 if (! dtd->hasParamEntityRefs || dtd->standalone) {
2650 if (! entity)
2651 return XML_ERROR_UNDEFINED_ENTITY;
2652 else if (! entity->is_internal)
2653 return XML_ERROR_ENTITY_DECLARED_IN_PE;
2654 } else if (! entity) {
2655 if (parser->m_skippedEntityHandler)
2656 parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
2657 else if (parser->m_defaultHandler)
2658 reportDefault(parser, enc, s, next);
2659 break;
2660 }
2661 if (entity->open)
2662 return XML_ERROR_RECURSIVE_ENTITY_REF;
2663 if (entity->notation)
2664 return XML_ERROR_BINARY_ENTITY_REF;
2665 if (entity->textPtr) {
2666 enum XML_Error result;
2667 if (! parser->m_defaultExpandInternalEntities) {
2668 if (parser->m_skippedEntityHandler)
2669 parser->m_skippedEntityHandler(parser->m_handlerArg, entity->name,
2670 0);
2671 else if (parser->m_defaultHandler)
2672 reportDefault(parser, enc, s, next);
2673 break;
2674 }
2675 result = processInternalEntity(parser, entity, XML_FALSE);
2676 if (result != XML_ERROR_NONE)
2677 return result;
2678 } else if (parser->m_externalEntityRefHandler) {
2679 const XML_Char *context;
2680 entity->open = XML_TRUE;
2681 context = getContext(parser);
2682 entity->open = XML_FALSE;
2683 if (! context)
2684 return XML_ERROR_NO_MEMORY;
2685 if (! parser->m_externalEntityRefHandler(
2686 parser->m_externalEntityRefHandlerArg, context, entity->base,
2687 entity->systemId, entity->publicId))
2688 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
2689 poolDiscard(&parser->m_tempPool);
2690 } else if (parser->m_defaultHandler)
2691 reportDefault(parser, enc, s, next);
2692 break;
2693 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002694 case XML_TOK_START_TAG_NO_ATTS:
2695 /* fall through */
Haibo Huang40a71912019-10-11 11:13:39 -07002696 case XML_TOK_START_TAG_WITH_ATTS: {
2697 TAG *tag;
2698 enum XML_Error result;
2699 XML_Char *toPtr;
2700 if (parser->m_freeTagList) {
2701 tag = parser->m_freeTagList;
2702 parser->m_freeTagList = parser->m_freeTagList->parent;
2703 } else {
2704 tag = (TAG *)MALLOC(parser, sizeof(TAG));
2705 if (! tag)
2706 return XML_ERROR_NO_MEMORY;
2707 tag->buf = (char *)MALLOC(parser, INIT_TAG_BUF_SIZE);
2708 if (! tag->buf) {
2709 FREE(parser, tag);
2710 return XML_ERROR_NO_MEMORY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002711 }
Haibo Huang40a71912019-10-11 11:13:39 -07002712 tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002713 }
Haibo Huang40a71912019-10-11 11:13:39 -07002714 tag->bindings = NULL;
2715 tag->parent = parser->m_tagStack;
2716 parser->m_tagStack = tag;
2717 tag->name.localPart = NULL;
2718 tag->name.prefix = NULL;
2719 tag->rawName = s + enc->minBytesPerChar;
2720 tag->rawNameLength = XmlNameLength(enc, tag->rawName);
2721 ++parser->m_tagLevel;
2722 {
2723 const char *rawNameEnd = tag->rawName + tag->rawNameLength;
2724 const char *fromPtr = tag->rawName;
2725 toPtr = (XML_Char *)tag->buf;
2726 for (;;) {
2727 int bufSize;
2728 int convLen;
2729 const enum XML_Convert_Result convert_res
2730 = XmlConvert(enc, &fromPtr, rawNameEnd, (ICHAR **)&toPtr,
2731 (ICHAR *)tag->bufEnd - 1);
2732 convLen = (int)(toPtr - (XML_Char *)tag->buf);
2733 if ((fromPtr >= rawNameEnd)
2734 || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) {
2735 tag->name.strLen = convLen;
2736 break;
2737 }
2738 bufSize = (int)(tag->bufEnd - tag->buf) << 1;
2739 {
2740 char *temp = (char *)REALLOC(parser, tag->buf, bufSize);
2741 if (temp == NULL)
2742 return XML_ERROR_NO_MEMORY;
2743 tag->buf = temp;
2744 tag->bufEnd = temp + bufSize;
2745 toPtr = (XML_Char *)temp + convLen;
2746 }
2747 }
2748 }
2749 tag->name.str = (XML_Char *)tag->buf;
2750 *toPtr = XML_T('\0');
2751 result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
2752 if (result)
2753 return result;
2754 if (parser->m_startElementHandler)
2755 parser->m_startElementHandler(parser->m_handlerArg, tag->name.str,
2756 (const XML_Char **)parser->m_atts);
2757 else if (parser->m_defaultHandler)
2758 reportDefault(parser, enc, s, next);
2759 poolClear(&parser->m_tempPool);
2760 break;
2761 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002762 case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
2763 /* fall through */
Haibo Huang40a71912019-10-11 11:13:39 -07002764 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS: {
2765 const char *rawName = s + enc->minBytesPerChar;
2766 enum XML_Error result;
2767 BINDING *bindings = NULL;
2768 XML_Bool noElmHandlers = XML_TRUE;
2769 TAG_NAME name;
2770 name.str = poolStoreString(&parser->m_tempPool, enc, rawName,
2771 rawName + XmlNameLength(enc, rawName));
2772 if (! name.str)
2773 return XML_ERROR_NO_MEMORY;
2774 poolFinish(&parser->m_tempPool);
2775 result = storeAtts(parser, enc, s, &name, &bindings);
2776 if (result != XML_ERROR_NONE) {
Elliott Hughes72472942018-01-10 08:36:10 -08002777 freeBindings(parser, bindings);
Haibo Huang40a71912019-10-11 11:13:39 -07002778 return result;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002779 }
Haibo Huang40a71912019-10-11 11:13:39 -07002780 poolFinish(&parser->m_tempPool);
2781 if (parser->m_startElementHandler) {
2782 parser->m_startElementHandler(parser->m_handlerArg, name.str,
2783 (const XML_Char **)parser->m_atts);
2784 noElmHandlers = XML_FALSE;
2785 }
2786 if (parser->m_endElementHandler) {
2787 if (parser->m_startElementHandler)
2788 *eventPP = *eventEndPP;
2789 parser->m_endElementHandler(parser->m_handlerArg, name.str);
2790 noElmHandlers = XML_FALSE;
2791 }
2792 if (noElmHandlers && parser->m_defaultHandler)
2793 reportDefault(parser, enc, s, next);
2794 poolClear(&parser->m_tempPool);
2795 freeBindings(parser, bindings);
2796 }
2797 if ((parser->m_tagLevel == 0)
2798 && (parser->m_parsingStatus.parsing != XML_FINISHED)) {
Elliott Hughesaaec48e2018-08-16 16:29:01 -07002799 if (parser->m_parsingStatus.parsing == XML_SUSPENDED)
2800 parser->m_processor = epilogProcessor;
2801 else
2802 return epilogProcessor(parser, next, end, nextPtr);
Elliott Hughes72472942018-01-10 08:36:10 -08002803 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002804 break;
2805 case XML_TOK_END_TAG:
Elliott Hughes72472942018-01-10 08:36:10 -08002806 if (parser->m_tagLevel == startTagLevel)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002807 return XML_ERROR_ASYNC_ENTITY;
2808 else {
2809 int len;
2810 const char *rawName;
Elliott Hughes72472942018-01-10 08:36:10 -08002811 TAG *tag = parser->m_tagStack;
2812 parser->m_tagStack = tag->parent;
2813 tag->parent = parser->m_freeTagList;
2814 parser->m_freeTagList = tag;
Haibo Huang40a71912019-10-11 11:13:39 -07002815 rawName = s + enc->minBytesPerChar * 2;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002816 len = XmlNameLength(enc, rawName);
2817 if (len != tag->rawNameLength
2818 || memcmp(tag->rawName, rawName, len) != 0) {
2819 *eventPP = rawName;
2820 return XML_ERROR_TAG_MISMATCH;
2821 }
Elliott Hughes72472942018-01-10 08:36:10 -08002822 --parser->m_tagLevel;
2823 if (parser->m_endElementHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002824 const XML_Char *localPart;
2825 const XML_Char *prefix;
2826 XML_Char *uri;
2827 localPart = tag->name.localPart;
Elliott Hughes72472942018-01-10 08:36:10 -08002828 if (parser->m_ns && localPart) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002829 /* localPart and prefix may have been overwritten in
2830 tag->name.str, since this points to the binding->uri
2831 buffer which gets re-used; so we have to add them again
2832 */
2833 uri = (XML_Char *)tag->name.str + tag->name.uriLen;
2834 /* don't need to check for space - already done in storeAtts() */
Haibo Huang40a71912019-10-11 11:13:39 -07002835 while (*localPart)
2836 *uri++ = *localPart++;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002837 prefix = (XML_Char *)tag->name.prefix;
Elliott Hughes72472942018-01-10 08:36:10 -08002838 if (parser->m_ns_triplets && prefix) {
2839 *uri++ = parser->m_namespaceSeparator;
Haibo Huang40a71912019-10-11 11:13:39 -07002840 while (*prefix)
2841 *uri++ = *prefix++;
2842 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002843 *uri = XML_T('\0');
2844 }
Elliott Hughes72472942018-01-10 08:36:10 -08002845 parser->m_endElementHandler(parser->m_handlerArg, tag->name.str);
Haibo Huang40a71912019-10-11 11:13:39 -07002846 } else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002847 reportDefault(parser, enc, s, next);
2848 while (tag->bindings) {
2849 BINDING *b = tag->bindings;
Elliott Hughes72472942018-01-10 08:36:10 -08002850 if (parser->m_endNamespaceDeclHandler)
Haibo Huang40a71912019-10-11 11:13:39 -07002851 parser->m_endNamespaceDeclHandler(parser->m_handlerArg,
2852 b->prefix->name);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002853 tag->bindings = tag->bindings->nextTagBinding;
Elliott Hughes72472942018-01-10 08:36:10 -08002854 b->nextTagBinding = parser->m_freeBindingList;
2855 parser->m_freeBindingList = b;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002856 b->prefix->binding = b->prevPrefixBinding;
2857 }
Haibo Huang40a71912019-10-11 11:13:39 -07002858 if ((parser->m_tagLevel == 0)
2859 && (parser->m_parsingStatus.parsing != XML_FINISHED)) {
2860 if (parser->m_parsingStatus.parsing == XML_SUSPENDED)
2861 parser->m_processor = epilogProcessor;
2862 else
2863 return epilogProcessor(parser, next, end, nextPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002864 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002865 }
2866 break;
Haibo Huang40a71912019-10-11 11:13:39 -07002867 case XML_TOK_CHAR_REF: {
2868 int n = XmlCharRefNumber(enc, s);
2869 if (n < 0)
2870 return XML_ERROR_BAD_CHAR_REF;
2871 if (parser->m_characterDataHandler) {
2872 XML_Char buf[XML_ENCODE_MAX];
2873 parser->m_characterDataHandler(parser->m_handlerArg, buf,
2874 XmlEncode(n, (ICHAR *)buf));
2875 } else if (parser->m_defaultHandler)
2876 reportDefault(parser, enc, s, next);
2877 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002878 case XML_TOK_XML_DECL:
2879 return XML_ERROR_MISPLACED_XML_PI;
2880 case XML_TOK_DATA_NEWLINE:
Elliott Hughes72472942018-01-10 08:36:10 -08002881 if (parser->m_characterDataHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002882 XML_Char c = 0xA;
Elliott Hughes72472942018-01-10 08:36:10 -08002883 parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
Haibo Huang40a71912019-10-11 11:13:39 -07002884 } else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002885 reportDefault(parser, enc, s, next);
2886 break;
Haibo Huang40a71912019-10-11 11:13:39 -07002887 case XML_TOK_CDATA_SECT_OPEN: {
2888 enum XML_Error result;
2889 if (parser->m_startCdataSectionHandler)
2890 parser->m_startCdataSectionHandler(parser->m_handlerArg);
2891 /* BEGIN disabled code */
2892 /* Suppose you doing a transformation on a document that involves
2893 changing only the character data. You set up a defaultHandler
2894 and a characterDataHandler. The defaultHandler simply copies
2895 characters through. The characterDataHandler does the
2896 transformation and writes the characters out escaping them as
2897 necessary. This case will fail to work if we leave out the
2898 following two lines (because & and < inside CDATA sections will
2899 be incorrectly escaped).
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002900
Haibo Huang40a71912019-10-11 11:13:39 -07002901 However, now we have a start/endCdataSectionHandler, so it seems
2902 easier to let the user deal with this.
2903 */
2904 else if (0 && parser->m_characterDataHandler)
2905 parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf,
2906 0);
2907 /* END disabled code */
2908 else if (parser->m_defaultHandler)
2909 reportDefault(parser, enc, s, next);
2910 result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
2911 if (result != XML_ERROR_NONE)
2912 return result;
2913 else if (! next) {
2914 parser->m_processor = cdataSectionProcessor;
2915 return result;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002916 }
Haibo Huang40a71912019-10-11 11:13:39 -07002917 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002918 case XML_TOK_TRAILING_RSQB:
2919 if (haveMore) {
2920 *nextPtr = s;
2921 return XML_ERROR_NONE;
2922 }
Elliott Hughes72472942018-01-10 08:36:10 -08002923 if (parser->m_characterDataHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002924 if (MUST_CONVERT(enc, s)) {
Elliott Hughes72472942018-01-10 08:36:10 -08002925 ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
2926 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
Haibo Huang40a71912019-10-11 11:13:39 -07002927 parser->m_characterDataHandler(
2928 parser->m_handlerArg, parser->m_dataBuf,
2929 (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
2930 } else
2931 parser->m_characterDataHandler(
2932 parser->m_handlerArg, (XML_Char *)s,
2933 (int)((XML_Char *)end - (XML_Char *)s));
2934 } else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002935 reportDefault(parser, enc, s, end);
Elliott Hughes35e432d2012-09-09 14:23:38 -07002936 /* We are at the end of the final buffer, should we check for
2937 XML_SUSPENDED, XML_FINISHED?
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002938 */
2939 if (startTagLevel == 0) {
2940 *eventPP = end;
2941 return XML_ERROR_NO_ELEMENTS;
2942 }
Elliott Hughes72472942018-01-10 08:36:10 -08002943 if (parser->m_tagLevel != startTagLevel) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002944 *eventPP = end;
2945 return XML_ERROR_ASYNC_ENTITY;
2946 }
2947 *nextPtr = end;
2948 return XML_ERROR_NONE;
Haibo Huang40a71912019-10-11 11:13:39 -07002949 case XML_TOK_DATA_CHARS: {
2950 XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler;
2951 if (charDataHandler) {
2952 if (MUST_CONVERT(enc, s)) {
2953 for (;;) {
2954 ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
2955 const enum XML_Convert_Result convert_res = XmlConvert(
2956 enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
2957 *eventEndPP = s;
2958 charDataHandler(parser->m_handlerArg, parser->m_dataBuf,
2959 (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
2960 if ((convert_res == XML_CONVERT_COMPLETED)
2961 || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
2962 break;
2963 *eventPP = s;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002964 }
Haibo Huang40a71912019-10-11 11:13:39 -07002965 } else
2966 charDataHandler(parser->m_handlerArg, (XML_Char *)s,
2967 (int)((XML_Char *)next - (XML_Char *)s));
2968 } else if (parser->m_defaultHandler)
2969 reportDefault(parser, enc, s, next);
2970 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002971 case XML_TOK_PI:
Haibo Huang40a71912019-10-11 11:13:39 -07002972 if (! reportProcessingInstruction(parser, enc, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002973 return XML_ERROR_NO_MEMORY;
2974 break;
2975 case XML_TOK_COMMENT:
Haibo Huang40a71912019-10-11 11:13:39 -07002976 if (! reportComment(parser, enc, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002977 return XML_ERROR_NO_MEMORY;
2978 break;
2979 default:
Elliott Hughes72472942018-01-10 08:36:10 -08002980 /* All of the tokens produced by XmlContentTok() have their own
2981 * explicit cases, so this default is not strictly necessary.
2982 * However it is a useful safety net, so we retain the code and
2983 * simply exclude it from the coverage tests.
2984 *
2985 * LCOV_EXCL_START
2986 */
2987 if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002988 reportDefault(parser, enc, s, next);
2989 break;
Elliott Hughes72472942018-01-10 08:36:10 -08002990 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002991 }
2992 *eventPP = s = next;
Elliott Hughes72472942018-01-10 08:36:10 -08002993 switch (parser->m_parsingStatus.parsing) {
Elliott Hughes35e432d2012-09-09 14:23:38 -07002994 case XML_SUSPENDED:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08002995 *nextPtr = next;
2996 return XML_ERROR_NONE;
2997 case XML_FINISHED:
2998 return XML_ERROR_ABORTED;
Haibo Huang40a71912019-10-11 11:13:39 -07002999 default:;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003000 }
3001 }
3002 /* not reached */
3003}
3004
Elliott Hughes72472942018-01-10 08:36:10 -08003005/* This function does not call free() on the allocated memory, merely
3006 * moving it to the parser's m_freeBindingList where it can be freed or
3007 * reused as appropriate.
3008 */
3009static void
Haibo Huang40a71912019-10-11 11:13:39 -07003010freeBindings(XML_Parser parser, BINDING *bindings) {
Elliott Hughes72472942018-01-10 08:36:10 -08003011 while (bindings) {
3012 BINDING *b = bindings;
3013
3014 /* m_startNamespaceDeclHandler will have been called for this
3015 * binding in addBindings(), so call the end handler now.
3016 */
3017 if (parser->m_endNamespaceDeclHandler)
Haibo Huang40a71912019-10-11 11:13:39 -07003018 parser->m_endNamespaceDeclHandler(parser->m_handlerArg, b->prefix->name);
Elliott Hughes72472942018-01-10 08:36:10 -08003019
3020 bindings = bindings->nextTagBinding;
3021 b->nextTagBinding = parser->m_freeBindingList;
3022 parser->m_freeBindingList = b;
3023 b->prefix->binding = b->prevPrefixBinding;
3024 }
3025}
3026
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003027/* Precondition: all arguments must be non-NULL;
3028 Purpose:
3029 - normalize attributes
3030 - check attributes for well-formedness
3031 - generate namespace aware attribute names (URI, prefix)
3032 - build list of attributes for startElementHandler
3033 - default attributes
3034 - process namespace declarations (check and report them)
3035 - generate namespace aware element name (URI, prefix)
3036*/
3037static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07003038storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
3039 TAG_NAME *tagNamePtr, BINDING **bindingsPtr) {
3040 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003041 ELEMENT_TYPE *elementType;
3042 int nDefaultAtts;
Haibo Huang40a71912019-10-11 11:13:39 -07003043 const XML_Char **appAtts; /* the attribute list for the application */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003044 int attIndex = 0;
3045 int prefixLen;
3046 int i;
3047 int n;
3048 XML_Char *uri;
3049 int nPrefixes = 0;
3050 BINDING *binding;
3051 const XML_Char *localPart;
3052
3053 /* lookup the element type name */
Haibo Huang40a71912019-10-11 11:13:39 -07003054 elementType
3055 = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str, 0);
3056 if (! elementType) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003057 const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
Haibo Huang40a71912019-10-11 11:13:39 -07003058 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003059 return XML_ERROR_NO_MEMORY;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003060 elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003061 sizeof(ELEMENT_TYPE));
Haibo Huang40a71912019-10-11 11:13:39 -07003062 if (! elementType)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003063 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07003064 if (parser->m_ns && ! setElementTypePrefix(parser, elementType))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003065 return XML_ERROR_NO_MEMORY;
3066 }
3067 nDefaultAtts = elementType->nDefaultAtts;
3068
3069 /* get the attributes from the tokenizer */
Elliott Hughes72472942018-01-10 08:36:10 -08003070 n = XmlGetAttributes(enc, attStr, parser->m_attsSize, parser->m_atts);
3071 if (n + nDefaultAtts > parser->m_attsSize) {
3072 int oldAttsSize = parser->m_attsSize;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003073 ATTRIBUTE *temp;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003074#ifdef XML_ATTR_INFO
3075 XML_AttrInfo *temp2;
3076#endif
Elliott Hughes72472942018-01-10 08:36:10 -08003077 parser->m_attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
Haibo Huang40a71912019-10-11 11:13:39 -07003078 temp = (ATTRIBUTE *)REALLOC(parser, (void *)parser->m_atts,
3079 parser->m_attsSize * sizeof(ATTRIBUTE));
Elliott Hughes72472942018-01-10 08:36:10 -08003080 if (temp == NULL) {
3081 parser->m_attsSize = oldAttsSize;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003082 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08003083 }
3084 parser->m_atts = temp;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003085#ifdef XML_ATTR_INFO
Haibo Huang40a71912019-10-11 11:13:39 -07003086 temp2 = (XML_AttrInfo *)REALLOC(parser, (void *)parser->m_attInfo,
3087 parser->m_attsSize * sizeof(XML_AttrInfo));
Elliott Hughes72472942018-01-10 08:36:10 -08003088 if (temp2 == NULL) {
3089 parser->m_attsSize = oldAttsSize;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003090 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08003091 }
3092 parser->m_attInfo = temp2;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003093#endif
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003094 if (n > oldAttsSize)
Elliott Hughes72472942018-01-10 08:36:10 -08003095 XmlGetAttributes(enc, attStr, n, parser->m_atts);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003096 }
3097
Elliott Hughes72472942018-01-10 08:36:10 -08003098 appAtts = (const XML_Char **)parser->m_atts;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003099 for (i = 0; i < n; i++) {
Elliott Hughes72472942018-01-10 08:36:10 -08003100 ATTRIBUTE *currAtt = &parser->m_atts[i];
Elliott Hughes35e432d2012-09-09 14:23:38 -07003101#ifdef XML_ATTR_INFO
Elliott Hughes72472942018-01-10 08:36:10 -08003102 XML_AttrInfo *currAttInfo = &parser->m_attInfo[i];
Elliott Hughes35e432d2012-09-09 14:23:38 -07003103#endif
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003104 /* add the name and value to the attribute list */
Haibo Huang40a71912019-10-11 11:13:39 -07003105 ATTRIBUTE_ID *attId
3106 = getAttributeId(parser, enc, currAtt->name,
3107 currAtt->name + XmlNameLength(enc, currAtt->name));
3108 if (! attId)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003109 return XML_ERROR_NO_MEMORY;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003110#ifdef XML_ATTR_INFO
Haibo Huang40a71912019-10-11 11:13:39 -07003111 currAttInfo->nameStart
3112 = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->name);
3113 currAttInfo->nameEnd
3114 = currAttInfo->nameStart + XmlNameLength(enc, currAtt->name);
3115 currAttInfo->valueStart = parser->m_parseEndByteIndex
3116 - (parser->m_parseEndPtr - currAtt->valuePtr);
3117 currAttInfo->valueEnd = parser->m_parseEndByteIndex
3118 - (parser->m_parseEndPtr - currAtt->valueEnd);
Elliott Hughes35e432d2012-09-09 14:23:38 -07003119#endif
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003120 /* Detect duplicate attributes by their QNames. This does not work when
3121 namespace processing is turned on and different prefixes for the same
3122 namespace are used. For this case we have a check further down.
3123 */
3124 if ((attId->name)[-1]) {
Elliott Hughes72472942018-01-10 08:36:10 -08003125 if (enc == parser->m_encoding)
3126 parser->m_eventPtr = parser->m_atts[i].name;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003127 return XML_ERROR_DUPLICATE_ATTRIBUTE;
3128 }
3129 (attId->name)[-1] = 1;
3130 appAtts[attIndex++] = attId->name;
Haibo Huang40a71912019-10-11 11:13:39 -07003131 if (! parser->m_atts[i].normalized) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003132 enum XML_Error result;
3133 XML_Bool isCdata = XML_TRUE;
3134
3135 /* figure out whether declared as other than CDATA */
3136 if (attId->maybeTokenized) {
3137 int j;
3138 for (j = 0; j < nDefaultAtts; j++) {
3139 if (attId == elementType->defaultAtts[j].id) {
3140 isCdata = elementType->defaultAtts[j].isCdata;
3141 break;
3142 }
3143 }
3144 }
3145
3146 /* normalize the attribute value */
Haibo Huang40a71912019-10-11 11:13:39 -07003147 result = storeAttributeValue(
3148 parser, enc, isCdata, parser->m_atts[i].valuePtr,
3149 parser->m_atts[i].valueEnd, &parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003150 if (result)
3151 return result;
Elliott Hughes72472942018-01-10 08:36:10 -08003152 appAtts[attIndex] = poolStart(&parser->m_tempPool);
3153 poolFinish(&parser->m_tempPool);
Haibo Huang40a71912019-10-11 11:13:39 -07003154 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003155 /* the value did not need normalizing */
Haibo Huang40a71912019-10-11 11:13:39 -07003156 appAtts[attIndex] = poolStoreString(&parser->m_tempPool, enc,
3157 parser->m_atts[i].valuePtr,
Elliott Hughes72472942018-01-10 08:36:10 -08003158 parser->m_atts[i].valueEnd);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003159 if (appAtts[attIndex] == 0)
3160 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08003161 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003162 }
3163 /* handle prefixed attribute names */
3164 if (attId->prefix) {
3165 if (attId->xmlns) {
3166 /* deal with namespace declarations here */
3167 enum XML_Error result = addBinding(parser, attId->prefix, attId,
3168 appAtts[attIndex], bindingsPtr);
3169 if (result)
3170 return result;
3171 --attIndex;
Haibo Huang40a71912019-10-11 11:13:39 -07003172 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003173 /* deal with other prefixed names later */
3174 attIndex++;
3175 nPrefixes++;
3176 (attId->name)[-1] = 2;
3177 }
Haibo Huang40a71912019-10-11 11:13:39 -07003178 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003179 attIndex++;
3180 }
3181
3182 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
Elliott Hughes72472942018-01-10 08:36:10 -08003183 parser->m_nSpecifiedAtts = attIndex;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003184 if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
3185 for (i = 0; i < attIndex; i += 2)
3186 if (appAtts[i] == elementType->idAtt->name) {
Elliott Hughes72472942018-01-10 08:36:10 -08003187 parser->m_idAttIndex = i;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003188 break;
3189 }
Haibo Huang40a71912019-10-11 11:13:39 -07003190 } else
Elliott Hughes72472942018-01-10 08:36:10 -08003191 parser->m_idAttIndex = -1;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003192
3193 /* do attribute defaulting */
3194 for (i = 0; i < nDefaultAtts; i++) {
3195 const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
Haibo Huang40a71912019-10-11 11:13:39 -07003196 if (! (da->id->name)[-1] && da->value) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003197 if (da->id->prefix) {
3198 if (da->id->xmlns) {
3199 enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
3200 da->value, bindingsPtr);
3201 if (result)
3202 return result;
Haibo Huang40a71912019-10-11 11:13:39 -07003203 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003204 (da->id->name)[-1] = 2;
3205 nPrefixes++;
3206 appAtts[attIndex++] = da->id->name;
3207 appAtts[attIndex++] = da->value;
3208 }
Haibo Huang40a71912019-10-11 11:13:39 -07003209 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003210 (da->id->name)[-1] = 1;
3211 appAtts[attIndex++] = da->id->name;
3212 appAtts[attIndex++] = da->value;
3213 }
3214 }
3215 }
3216 appAtts[attIndex] = 0;
3217
3218 /* expand prefixed attribute names, check for duplicates,
3219 and clear flags that say whether attributes were specified */
3220 i = 0;
3221 if (nPrefixes) {
Haibo Huang40a71912019-10-11 11:13:39 -07003222 int j; /* hash table index */
Elliott Hughes72472942018-01-10 08:36:10 -08003223 unsigned long version = parser->m_nsAttsVersion;
3224 int nsAttsSize = (int)1 << parser->m_nsAttsPower;
3225 unsigned char oldNsAttsPower = parser->m_nsAttsPower;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003226 /* size of hash table must be at least 2 * (# of prefixed attributes) */
Haibo Huang40a71912019-10-11 11:13:39 -07003227 if ((nPrefixes << 1)
3228 >> parser->m_nsAttsPower) { /* true for m_nsAttsPower = 0 */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003229 NS_ATT *temp;
3230 /* hash table size must also be a power of 2 and >= 8 */
Haibo Huang40a71912019-10-11 11:13:39 -07003231 while (nPrefixes >> parser->m_nsAttsPower++)
3232 ;
Elliott Hughes72472942018-01-10 08:36:10 -08003233 if (parser->m_nsAttsPower < 3)
3234 parser->m_nsAttsPower = 3;
3235 nsAttsSize = (int)1 << parser->m_nsAttsPower;
Haibo Huang40a71912019-10-11 11:13:39 -07003236 temp = (NS_ATT *)REALLOC(parser, parser->m_nsAtts,
3237 nsAttsSize * sizeof(NS_ATT));
3238 if (! temp) {
Elliott Hughes72472942018-01-10 08:36:10 -08003239 /* Restore actual size of memory in m_nsAtts */
3240 parser->m_nsAttsPower = oldNsAttsPower;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003241 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08003242 }
3243 parser->m_nsAtts = temp;
Haibo Huang40a71912019-10-11 11:13:39 -07003244 version = 0; /* force re-initialization of m_nsAtts hash table */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003245 }
Elliott Hughes72472942018-01-10 08:36:10 -08003246 /* using a version flag saves us from initializing m_nsAtts every time */
Haibo Huang40a71912019-10-11 11:13:39 -07003247 if (! version) { /* initialize version flags when version wraps around */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003248 version = INIT_ATTS_VERSION;
Haibo Huang40a71912019-10-11 11:13:39 -07003249 for (j = nsAttsSize; j != 0;)
Elliott Hughes72472942018-01-10 08:36:10 -08003250 parser->m_nsAtts[--j].version = version;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003251 }
Elliott Hughes72472942018-01-10 08:36:10 -08003252 parser->m_nsAttsVersion = --version;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003253
3254 /* expand prefixed names and check for duplicates */
3255 for (; i < attIndex; i += 2) {
3256 const XML_Char *s = appAtts[i];
Haibo Huang40a71912019-10-11 11:13:39 -07003257 if (s[-1] == 2) { /* prefixed */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003258 ATTRIBUTE_ID *id;
3259 const BINDING *b;
Elliott Hughes72472942018-01-10 08:36:10 -08003260 unsigned long uriHash;
3261 struct siphash sip_state;
3262 struct sipkey sip_key;
3263
3264 copy_salt_to_sipkey(parser, &sip_key);
3265 sip24_init(&sip_state, &sip_key);
3266
Haibo Huang40a71912019-10-11 11:13:39 -07003267 ((XML_Char *)s)[-1] = 0; /* clear flag */
Elliott Hughes35e432d2012-09-09 14:23:38 -07003268 id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);
Haibo Huang40a71912019-10-11 11:13:39 -07003269 if (! id || ! id->prefix) {
Elliott Hughes72472942018-01-10 08:36:10 -08003270 /* This code is walking through the appAtts array, dealing
3271 * with (in this case) a prefixed attribute name. To be in
3272 * the array, the attribute must have already been bound, so
3273 * has to have passed through the hash table lookup once
3274 * already. That implies that an entry for it already
3275 * exists, so the lookup above will return a pointer to
3276 * already allocated memory. There is no opportunaity for
3277 * the allocator to fail, so the condition above cannot be
3278 * fulfilled.
3279 *
3280 * Since it is difficult to be certain that the above
3281 * analysis is complete, we retain the test and merely
3282 * remove the code from coverage tests.
3283 */
3284 return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */
3285 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003286 b = id->prefix->binding;
Haibo Huang40a71912019-10-11 11:13:39 -07003287 if (! b)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003288 return XML_ERROR_UNBOUND_PREFIX;
3289
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003290 for (j = 0; j < b->uriLen; j++) {
3291 const XML_Char c = b->uri[j];
Haibo Huang40a71912019-10-11 11:13:39 -07003292 if (! poolAppendChar(&parser->m_tempPool, c))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003293 return XML_ERROR_NO_MEMORY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003294 }
Elliott Hughes72472942018-01-10 08:36:10 -08003295
3296 sip24_update(&sip_state, b->uri, b->uriLen * sizeof(XML_Char));
3297
Elliott Hughesd07d5a72009-09-25 16:04:37 -07003298 while (*s++ != XML_T(ASCII_COLON))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003299 ;
Elliott Hughes72472942018-01-10 08:36:10 -08003300
3301 sip24_update(&sip_state, s, keylen(s) * sizeof(XML_Char));
3302
Haibo Huang40a71912019-10-11 11:13:39 -07003303 do { /* copies null terminator */
3304 if (! poolAppendChar(&parser->m_tempPool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003305 return XML_ERROR_NO_MEMORY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003306 } while (*s++);
3307
Elliott Hughes72472942018-01-10 08:36:10 -08003308 uriHash = (unsigned long)sip24_final(&sip_state);
3309
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003310 { /* Check hash table for duplicate of expanded name (uriName).
Elliott Hughes35e432d2012-09-09 14:23:38 -07003311 Derived from code in lookup(parser, HASH_TABLE *table, ...).
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003312 */
3313 unsigned char step = 0;
3314 unsigned long mask = nsAttsSize - 1;
Haibo Huang40a71912019-10-11 11:13:39 -07003315 j = uriHash & mask; /* index into hash table */
Elliott Hughes72472942018-01-10 08:36:10 -08003316 while (parser->m_nsAtts[j].version == version) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003317 /* for speed we compare stored hash values first */
Elliott Hughes72472942018-01-10 08:36:10 -08003318 if (uriHash == parser->m_nsAtts[j].hash) {
3319 const XML_Char *s1 = poolStart(&parser->m_tempPool);
3320 const XML_Char *s2 = parser->m_nsAtts[j].uriName;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003321 /* s1 is null terminated, but not s2 */
Haibo Huang40a71912019-10-11 11:13:39 -07003322 for (; *s1 == *s2 && *s1 != 0; s1++, s2++)
3323 ;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003324 if (*s1 == 0)
3325 return XML_ERROR_DUPLICATE_ATTRIBUTE;
3326 }
Haibo Huang40a71912019-10-11 11:13:39 -07003327 if (! step)
Elliott Hughes72472942018-01-10 08:36:10 -08003328 step = PROBE_STEP(uriHash, mask, parser->m_nsAttsPower);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003329 j < step ? (j += nsAttsSize - step) : (j -= step);
3330 }
3331 }
3332
Haibo Huang40a71912019-10-11 11:13:39 -07003333 if (parser->m_ns_triplets) { /* append namespace separator and prefix */
Elliott Hughes72472942018-01-10 08:36:10 -08003334 parser->m_tempPool.ptr[-1] = parser->m_namespaceSeparator;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003335 s = b->prefix->name;
3336 do {
Haibo Huang40a71912019-10-11 11:13:39 -07003337 if (! poolAppendChar(&parser->m_tempPool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003338 return XML_ERROR_NO_MEMORY;
3339 } while (*s++);
3340 }
3341
3342 /* store expanded name in attribute list */
Elliott Hughes72472942018-01-10 08:36:10 -08003343 s = poolStart(&parser->m_tempPool);
3344 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003345 appAtts[i] = s;
3346
3347 /* fill empty slot with new version, uriName and hash value */
Elliott Hughes72472942018-01-10 08:36:10 -08003348 parser->m_nsAtts[j].version = version;
3349 parser->m_nsAtts[j].hash = uriHash;
3350 parser->m_nsAtts[j].uriName = s;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003351
Haibo Huang40a71912019-10-11 11:13:39 -07003352 if (! --nPrefixes) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003353 i += 2;
3354 break;
3355 }
Haibo Huang40a71912019-10-11 11:13:39 -07003356 } else /* not prefixed */
3357 ((XML_Char *)s)[-1] = 0; /* clear flag */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003358 }
3359 }
3360 /* clear flags for the remaining attributes */
3361 for (; i < attIndex; i += 2)
3362 ((XML_Char *)(appAtts[i]))[-1] = 0;
3363 for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
3364 binding->attId->name[-1] = 0;
3365
Haibo Huang40a71912019-10-11 11:13:39 -07003366 if (! parser->m_ns)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003367 return XML_ERROR_NONE;
3368
3369 /* expand the element type name */
3370 if (elementType->prefix) {
3371 binding = elementType->prefix->binding;
Haibo Huang40a71912019-10-11 11:13:39 -07003372 if (! binding)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003373 return XML_ERROR_UNBOUND_PREFIX;
3374 localPart = tagNamePtr->str;
Elliott Hughesd07d5a72009-09-25 16:04:37 -07003375 while (*localPart++ != XML_T(ASCII_COLON))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003376 ;
Haibo Huang40a71912019-10-11 11:13:39 -07003377 } else if (dtd->defaultPrefix.binding) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003378 binding = dtd->defaultPrefix.binding;
3379 localPart = tagNamePtr->str;
Haibo Huang40a71912019-10-11 11:13:39 -07003380 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003381 return XML_ERROR_NONE;
3382 prefixLen = 0;
Elliott Hughes72472942018-01-10 08:36:10 -08003383 if (parser->m_ns_triplets && binding->prefix->name) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003384 for (; binding->prefix->name[prefixLen++];)
Haibo Huang40a71912019-10-11 11:13:39 -07003385 ; /* prefixLen includes null terminator */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003386 }
3387 tagNamePtr->localPart = localPart;
3388 tagNamePtr->uriLen = binding->uriLen;
3389 tagNamePtr->prefix = binding->prefix->name;
3390 tagNamePtr->prefixLen = prefixLen;
3391 for (i = 0; localPart[i++];)
Haibo Huang40a71912019-10-11 11:13:39 -07003392 ; /* i includes null terminator */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003393 n = i + binding->uriLen + prefixLen;
3394 if (n > binding->uriAlloc) {
3395 TAG *p;
Elliott Hughes72472942018-01-10 08:36:10 -08003396 uri = (XML_Char *)MALLOC(parser, (n + EXPAND_SPARE) * sizeof(XML_Char));
Haibo Huang40a71912019-10-11 11:13:39 -07003397 if (! uri)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003398 return XML_ERROR_NO_MEMORY;
3399 binding->uriAlloc = n + EXPAND_SPARE;
3400 memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
Elliott Hughes72472942018-01-10 08:36:10 -08003401 for (p = parser->m_tagStack; p; p = p->parent)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003402 if (p->name.str == binding->uri)
3403 p->name.str = uri;
Elliott Hughes72472942018-01-10 08:36:10 -08003404 FREE(parser, binding->uri);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003405 binding->uri = uri;
3406 }
Elliott Hughes72472942018-01-10 08:36:10 -08003407 /* if m_namespaceSeparator != '\0' then uri includes it already */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003408 uri = binding->uri + binding->uriLen;
3409 memcpy(uri, localPart, i * sizeof(XML_Char));
3410 /* we always have a namespace separator between localPart and prefix */
3411 if (prefixLen) {
3412 uri += i - 1;
Haibo Huang40a71912019-10-11 11:13:39 -07003413 *uri = parser->m_namespaceSeparator; /* replace null terminator */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003414 memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
3415 }
3416 tagNamePtr->str = binding->uri;
3417 return XML_ERROR_NONE;
3418}
3419
3420/* addBinding() overwrites the value of prefix->binding without checking.
3421 Therefore one must keep track of the old value outside of addBinding().
3422*/
3423static enum XML_Error
3424addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
Haibo Huang40a71912019-10-11 11:13:39 -07003425 const XML_Char *uri, BINDING **bindingsPtr) {
3426 static const XML_Char xmlNamespace[]
3427 = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON,
3428 ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w,
3429 ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o,
3430 ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M,
3431 ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9,
3432 ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m,
3433 ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c,
3434 ASCII_e, '\0'};
3435 static const int xmlLen = (int)sizeof(xmlNamespace) / sizeof(XML_Char) - 1;
3436 static const XML_Char xmlnsNamespace[]
3437 = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH,
3438 ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w,
3439 ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH,
3440 ASCII_2, ASCII_0, ASCII_0, ASCII_0, ASCII_SLASH, ASCII_x,
3441 ASCII_m, ASCII_l, ASCII_n, ASCII_s, ASCII_SLASH, '\0'};
3442 static const int xmlnsLen
3443 = (int)sizeof(xmlnsNamespace) / sizeof(XML_Char) - 1;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003444
3445 XML_Bool mustBeXML = XML_FALSE;
3446 XML_Bool isXML = XML_TRUE;
3447 XML_Bool isXMLNS = XML_TRUE;
Elliott Hughes35e432d2012-09-09 14:23:38 -07003448
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003449 BINDING *b;
3450 int len;
3451
3452 /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
3453 if (*uri == XML_T('\0') && prefix->name)
3454 return XML_ERROR_UNDECLARING_PREFIX;
3455
Haibo Huang40a71912019-10-11 11:13:39 -07003456 if (prefix->name && prefix->name[0] == XML_T(ASCII_x)
Elliott Hughesd07d5a72009-09-25 16:04:37 -07003457 && prefix->name[1] == XML_T(ASCII_m)
3458 && prefix->name[2] == XML_T(ASCII_l)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003459 /* Not allowed to bind xmlns */
Haibo Huang40a71912019-10-11 11:13:39 -07003460 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 -08003461 && prefix->name[5] == XML_T('\0'))
3462 return XML_ERROR_RESERVED_PREFIX_XMLNS;
3463
3464 if (prefix->name[3] == XML_T('\0'))
3465 mustBeXML = XML_TRUE;
3466 }
3467
3468 for (len = 0; uri[len]; len++) {
3469 if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
3470 isXML = XML_FALSE;
3471
Haibo Huang40a71912019-10-11 11:13:39 -07003472 if (! mustBeXML && isXMLNS
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003473 && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
3474 isXMLNS = XML_FALSE;
3475 }
3476 isXML = isXML && len == xmlLen;
3477 isXMLNS = isXMLNS && len == xmlnsLen;
3478
3479 if (mustBeXML != isXML)
3480 return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
3481 : XML_ERROR_RESERVED_NAMESPACE_URI;
3482
3483 if (isXMLNS)
3484 return XML_ERROR_RESERVED_NAMESPACE_URI;
3485
Elliott Hughes72472942018-01-10 08:36:10 -08003486 if (parser->m_namespaceSeparator)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003487 len++;
Elliott Hughes72472942018-01-10 08:36:10 -08003488 if (parser->m_freeBindingList) {
3489 b = parser->m_freeBindingList;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003490 if (len > b->uriAlloc) {
Haibo Huang40a71912019-10-11 11:13:39 -07003491 XML_Char *temp = (XML_Char *)REALLOC(
3492 parser, b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003493 if (temp == NULL)
3494 return XML_ERROR_NO_MEMORY;
3495 b->uri = temp;
3496 b->uriAlloc = len + EXPAND_SPARE;
3497 }
Elliott Hughes72472942018-01-10 08:36:10 -08003498 parser->m_freeBindingList = b->nextTagBinding;
Haibo Huang40a71912019-10-11 11:13:39 -07003499 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08003500 b = (BINDING *)MALLOC(parser, sizeof(BINDING));
Haibo Huang40a71912019-10-11 11:13:39 -07003501 if (! b)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003502 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07003503 b->uri
3504 = (XML_Char *)MALLOC(parser, sizeof(XML_Char) * (len + EXPAND_SPARE));
3505 if (! b->uri) {
Elliott Hughes72472942018-01-10 08:36:10 -08003506 FREE(parser, b);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003507 return XML_ERROR_NO_MEMORY;
3508 }
3509 b->uriAlloc = len + EXPAND_SPARE;
3510 }
3511 b->uriLen = len;
3512 memcpy(b->uri, uri, len * sizeof(XML_Char));
Elliott Hughes72472942018-01-10 08:36:10 -08003513 if (parser->m_namespaceSeparator)
3514 b->uri[len - 1] = parser->m_namespaceSeparator;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003515 b->prefix = prefix;
3516 b->attId = attId;
3517 b->prevPrefixBinding = prefix->binding;
3518 /* NULL binding when default namespace undeclared */
Elliott Hughes72472942018-01-10 08:36:10 -08003519 if (*uri == XML_T('\0') && prefix == &parser->m_dtd->defaultPrefix)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003520 prefix->binding = NULL;
3521 else
3522 prefix->binding = b;
3523 b->nextTagBinding = *bindingsPtr;
3524 *bindingsPtr = b;
3525 /* if attId == NULL then we are not starting a namespace scope */
Elliott Hughes72472942018-01-10 08:36:10 -08003526 if (attId && parser->m_startNamespaceDeclHandler)
3527 parser->m_startNamespaceDeclHandler(parser->m_handlerArg, prefix->name,
Haibo Huang40a71912019-10-11 11:13:39 -07003528 prefix->binding ? uri : 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003529 return XML_ERROR_NONE;
3530}
3531
3532/* The idea here is to avoid using stack for each CDATA section when
3533 the whole file is parsed with one call.
3534*/
3535static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07003536cdataSectionProcessor(XML_Parser parser, const char *start, const char *end,
3537 const char **endPtr) {
3538 enum XML_Error result
3539 = doCdataSection(parser, parser->m_encoding, &start, end, endPtr,
3540 (XML_Bool)! parser->m_parsingStatus.finalBuffer);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003541 if (result != XML_ERROR_NONE)
3542 return result;
3543 if (start) {
Haibo Huang40a71912019-10-11 11:13:39 -07003544 if (parser->m_parentParser) { /* we are parsing an external entity */
Elliott Hughes72472942018-01-10 08:36:10 -08003545 parser->m_processor = externalEntityContentProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003546 return externalEntityContentProcessor(parser, start, end, endPtr);
Haibo Huang40a71912019-10-11 11:13:39 -07003547 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08003548 parser->m_processor = contentProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003549 return contentProcessor(parser, start, end, endPtr);
3550 }
3551 }
3552 return result;
3553}
3554
3555/* startPtr gets set to non-null if the section is closed, and to null if
3556 the section is not yet closed.
3557*/
3558static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07003559doCdataSection(XML_Parser parser, const ENCODING *enc, const char **startPtr,
3560 const char *end, const char **nextPtr, XML_Bool haveMore) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003561 const char *s = *startPtr;
3562 const char **eventPP;
3563 const char **eventEndPP;
Elliott Hughes72472942018-01-10 08:36:10 -08003564 if (enc == parser->m_encoding) {
3565 eventPP = &parser->m_eventPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003566 *eventPP = s;
Elliott Hughes72472942018-01-10 08:36:10 -08003567 eventEndPP = &parser->m_eventEndPtr;
Haibo Huang40a71912019-10-11 11:13:39 -07003568 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08003569 eventPP = &(parser->m_openInternalEntities->internalEventPtr);
3570 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003571 }
3572 *eventPP = s;
3573 *startPtr = NULL;
3574
3575 for (;;) {
3576 const char *next;
3577 int tok = XmlCdataSectionTok(enc, s, end, &next);
3578 *eventEndPP = next;
3579 switch (tok) {
3580 case XML_TOK_CDATA_SECT_CLOSE:
Elliott Hughes72472942018-01-10 08:36:10 -08003581 if (parser->m_endCdataSectionHandler)
3582 parser->m_endCdataSectionHandler(parser->m_handlerArg);
Haibo Huang40a71912019-10-11 11:13:39 -07003583 /* BEGIN disabled code */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003584 /* see comment under XML_TOK_CDATA_SECT_OPEN */
Haibo Huangfd5e81a2019-06-20 12:09:36 -07003585 else if (0 && parser->m_characterDataHandler)
Haibo Huang40a71912019-10-11 11:13:39 -07003586 parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf,
3587 0);
3588 /* END disabled code */
Elliott Hughes72472942018-01-10 08:36:10 -08003589 else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003590 reportDefault(parser, enc, s, next);
3591 *startPtr = next;
3592 *nextPtr = next;
Elliott Hughes72472942018-01-10 08:36:10 -08003593 if (parser->m_parsingStatus.parsing == XML_FINISHED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003594 return XML_ERROR_ABORTED;
3595 else
3596 return XML_ERROR_NONE;
3597 case XML_TOK_DATA_NEWLINE:
Elliott Hughes72472942018-01-10 08:36:10 -08003598 if (parser->m_characterDataHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003599 XML_Char c = 0xA;
Elliott Hughes72472942018-01-10 08:36:10 -08003600 parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
Haibo Huang40a71912019-10-11 11:13:39 -07003601 } else if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003602 reportDefault(parser, enc, s, next);
3603 break;
Haibo Huang40a71912019-10-11 11:13:39 -07003604 case XML_TOK_DATA_CHARS: {
3605 XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler;
3606 if (charDataHandler) {
3607 if (MUST_CONVERT(enc, s)) {
3608 for (;;) {
3609 ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
3610 const enum XML_Convert_Result convert_res = XmlConvert(
3611 enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
3612 *eventEndPP = next;
3613 charDataHandler(parser->m_handlerArg, parser->m_dataBuf,
3614 (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
3615 if ((convert_res == XML_CONVERT_COMPLETED)
3616 || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
3617 break;
3618 *eventPP = s;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003619 }
Haibo Huang40a71912019-10-11 11:13:39 -07003620 } else
3621 charDataHandler(parser->m_handlerArg, (XML_Char *)s,
3622 (int)((XML_Char *)next - (XML_Char *)s));
3623 } else if (parser->m_defaultHandler)
3624 reportDefault(parser, enc, s, next);
3625 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003626 case XML_TOK_INVALID:
3627 *eventPP = next;
3628 return XML_ERROR_INVALID_TOKEN;
3629 case XML_TOK_PARTIAL_CHAR:
3630 if (haveMore) {
3631 *nextPtr = s;
3632 return XML_ERROR_NONE;
3633 }
3634 return XML_ERROR_PARTIAL_CHAR;
3635 case XML_TOK_PARTIAL:
3636 case XML_TOK_NONE:
3637 if (haveMore) {
3638 *nextPtr = s;
3639 return XML_ERROR_NONE;
3640 }
3641 return XML_ERROR_UNCLOSED_CDATA_SECTION;
3642 default:
Elliott Hughes72472942018-01-10 08:36:10 -08003643 /* Every token returned by XmlCdataSectionTok() has its own
3644 * explicit case, so this default case will never be executed.
3645 * We retain it as a safety net and exclude it from the coverage
3646 * statistics.
3647 *
3648 * LCOV_EXCL_START
Haibo Huang40a71912019-10-11 11:13:39 -07003649 */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003650 *eventPP = next;
3651 return XML_ERROR_UNEXPECTED_STATE;
Elliott Hughes72472942018-01-10 08:36:10 -08003652 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003653 }
3654
3655 *eventPP = s = next;
Elliott Hughes72472942018-01-10 08:36:10 -08003656 switch (parser->m_parsingStatus.parsing) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003657 case XML_SUSPENDED:
3658 *nextPtr = next;
3659 return XML_ERROR_NONE;
3660 case XML_FINISHED:
3661 return XML_ERROR_ABORTED;
Haibo Huang40a71912019-10-11 11:13:39 -07003662 default:;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003663 }
3664 }
3665 /* not reached */
3666}
3667
3668#ifdef XML_DTD
3669
3670/* The idea here is to avoid using stack for each IGNORE section when
3671 the whole file is parsed with one call.
3672*/
3673static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07003674ignoreSectionProcessor(XML_Parser parser, const char *start, const char *end,
3675 const char **endPtr) {
3676 enum XML_Error result
3677 = doIgnoreSection(parser, parser->m_encoding, &start, end, endPtr,
3678 (XML_Bool)! parser->m_parsingStatus.finalBuffer);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003679 if (result != XML_ERROR_NONE)
3680 return result;
3681 if (start) {
Elliott Hughes72472942018-01-10 08:36:10 -08003682 parser->m_processor = prologProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003683 return prologProcessor(parser, start, end, endPtr);
3684 }
3685 return result;
3686}
3687
3688/* startPtr gets set to non-null is the section is closed, and to null
3689 if the section is not yet closed.
3690*/
3691static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07003692doIgnoreSection(XML_Parser parser, const ENCODING *enc, const char **startPtr,
3693 const char *end, const char **nextPtr, XML_Bool haveMore) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003694 const char *next;
3695 int tok;
3696 const char *s = *startPtr;
3697 const char **eventPP;
3698 const char **eventEndPP;
Elliott Hughes72472942018-01-10 08:36:10 -08003699 if (enc == parser->m_encoding) {
3700 eventPP = &parser->m_eventPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003701 *eventPP = s;
Elliott Hughes72472942018-01-10 08:36:10 -08003702 eventEndPP = &parser->m_eventEndPtr;
Haibo Huang40a71912019-10-11 11:13:39 -07003703 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08003704 /* It's not entirely clear, but it seems the following two lines
3705 * of code cannot be executed. The only occasions on which 'enc'
3706 * is not 'encoding' are when this function is called
3707 * from the internal entity processing, and IGNORE sections are an
3708 * error in internal entities.
3709 *
3710 * Since it really isn't clear that this is true, we keep the code
3711 * and just remove it from our coverage tests.
3712 *
3713 * LCOV_EXCL_START
3714 */
3715 eventPP = &(parser->m_openInternalEntities->internalEventPtr);
3716 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
3717 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003718 }
3719 *eventPP = s;
3720 *startPtr = NULL;
3721 tok = XmlIgnoreSectionTok(enc, s, end, &next);
3722 *eventEndPP = next;
3723 switch (tok) {
3724 case XML_TOK_IGNORE_SECT:
Elliott Hughes72472942018-01-10 08:36:10 -08003725 if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003726 reportDefault(parser, enc, s, next);
3727 *startPtr = next;
3728 *nextPtr = next;
Elliott Hughes72472942018-01-10 08:36:10 -08003729 if (parser->m_parsingStatus.parsing == XML_FINISHED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003730 return XML_ERROR_ABORTED;
3731 else
3732 return XML_ERROR_NONE;
3733 case XML_TOK_INVALID:
3734 *eventPP = next;
3735 return XML_ERROR_INVALID_TOKEN;
3736 case XML_TOK_PARTIAL_CHAR:
3737 if (haveMore) {
3738 *nextPtr = s;
3739 return XML_ERROR_NONE;
3740 }
3741 return XML_ERROR_PARTIAL_CHAR;
3742 case XML_TOK_PARTIAL:
3743 case XML_TOK_NONE:
3744 if (haveMore) {
3745 *nextPtr = s;
3746 return XML_ERROR_NONE;
3747 }
3748 return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
3749 default:
Elliott Hughes72472942018-01-10 08:36:10 -08003750 /* All of the tokens that XmlIgnoreSectionTok() returns have
3751 * explicit cases to handle them, so this default case is never
3752 * executed. We keep it as a safety net anyway, and remove it
3753 * from our test coverage statistics.
3754 *
3755 * LCOV_EXCL_START
3756 */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003757 *eventPP = next;
3758 return XML_ERROR_UNEXPECTED_STATE;
Elliott Hughes72472942018-01-10 08:36:10 -08003759 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003760 }
3761 /* not reached */
3762}
3763
3764#endif /* XML_DTD */
3765
3766static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07003767initializeEncoding(XML_Parser parser) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003768 const char *s;
3769#ifdef XML_UNICODE
3770 char encodingBuf[128];
Elliott Hughes72472942018-01-10 08:36:10 -08003771 /* See comments abount `protoclEncodingName` in parserInit() */
Haibo Huang40a71912019-10-11 11:13:39 -07003772 if (! parser->m_protocolEncodingName)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003773 s = NULL;
3774 else {
3775 int i;
Elliott Hughes72472942018-01-10 08:36:10 -08003776 for (i = 0; parser->m_protocolEncodingName[i]; i++) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003777 if (i == sizeof(encodingBuf) - 1
Elliott Hughes72472942018-01-10 08:36:10 -08003778 || (parser->m_protocolEncodingName[i] & ~0x7f) != 0) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003779 encodingBuf[0] = '\0';
3780 break;
3781 }
Elliott Hughes72472942018-01-10 08:36:10 -08003782 encodingBuf[i] = (char)parser->m_protocolEncodingName[i];
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003783 }
3784 encodingBuf[i] = '\0';
3785 s = encodingBuf;
3786 }
3787#else
Elliott Hughes72472942018-01-10 08:36:10 -08003788 s = parser->m_protocolEncodingName;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003789#endif
Haibo Huang40a71912019-10-11 11:13:39 -07003790 if ((parser->m_ns ? XmlInitEncodingNS : XmlInitEncoding)(
3791 &parser->m_initEncoding, &parser->m_encoding, s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003792 return XML_ERROR_NONE;
Elliott Hughes72472942018-01-10 08:36:10 -08003793 return handleUnknownEncoding(parser, parser->m_protocolEncodingName);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003794}
3795
3796static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07003797processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *s,
3798 const char *next) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003799 const char *encodingName = NULL;
3800 const XML_Char *storedEncName = NULL;
3801 const ENCODING *newEncoding = NULL;
3802 const char *version = NULL;
3803 const char *versionend;
3804 const XML_Char *storedversion = NULL;
3805 int standalone = -1;
Haibo Huang40a71912019-10-11 11:13:39 -07003806 if (! (parser->m_ns ? XmlParseXmlDeclNS : XmlParseXmlDecl)(
3807 isGeneralTextEntity, parser->m_encoding, s, next, &parser->m_eventPtr,
3808 &version, &versionend, &encodingName, &newEncoding, &standalone)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003809 if (isGeneralTextEntity)
3810 return XML_ERROR_TEXT_DECL;
3811 else
3812 return XML_ERROR_XML_DECL;
3813 }
Haibo Huang40a71912019-10-11 11:13:39 -07003814 if (! isGeneralTextEntity && standalone == 1) {
Elliott Hughes72472942018-01-10 08:36:10 -08003815 parser->m_dtd->standalone = XML_TRUE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003816#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07003817 if (parser->m_paramEntityParsing
3818 == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
Elliott Hughes72472942018-01-10 08:36:10 -08003819 parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003820#endif /* XML_DTD */
3821 }
Elliott Hughes72472942018-01-10 08:36:10 -08003822 if (parser->m_xmlDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003823 if (encodingName != NULL) {
Haibo Huang40a71912019-10-11 11:13:39 -07003824 storedEncName = poolStoreString(
3825 &parser->m_temp2Pool, parser->m_encoding, encodingName,
3826 encodingName + XmlNameLength(parser->m_encoding, encodingName));
3827 if (! storedEncName)
3828 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08003829 poolFinish(&parser->m_temp2Pool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003830 }
3831 if (version) {
Haibo Huang40a71912019-10-11 11:13:39 -07003832 storedversion
3833 = poolStoreString(&parser->m_temp2Pool, parser->m_encoding, version,
3834 versionend - parser->m_encoding->minBytesPerChar);
3835 if (! storedversion)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003836 return XML_ERROR_NO_MEMORY;
3837 }
Haibo Huang40a71912019-10-11 11:13:39 -07003838 parser->m_xmlDeclHandler(parser->m_handlerArg, storedversion, storedEncName,
3839 standalone);
3840 } else if (parser->m_defaultHandler)
Elliott Hughes72472942018-01-10 08:36:10 -08003841 reportDefault(parser, parser->m_encoding, s, next);
3842 if (parser->m_protocolEncodingName == NULL) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003843 if (newEncoding) {
Elliott Hughes72472942018-01-10 08:36:10 -08003844 /* Check that the specified encoding does not conflict with what
3845 * the parser has already deduced. Do we have the same number
3846 * of bytes in the smallest representation of a character? If
3847 * this is UTF-16, is it the same endianness?
3848 */
3849 if (newEncoding->minBytesPerChar != parser->m_encoding->minBytesPerChar
Haibo Huang40a71912019-10-11 11:13:39 -07003850 || (newEncoding->minBytesPerChar == 2
3851 && newEncoding != parser->m_encoding)) {
Elliott Hughes72472942018-01-10 08:36:10 -08003852 parser->m_eventPtr = encodingName;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003853 return XML_ERROR_INCORRECT_ENCODING;
3854 }
Elliott Hughes72472942018-01-10 08:36:10 -08003855 parser->m_encoding = newEncoding;
Haibo Huang40a71912019-10-11 11:13:39 -07003856 } else if (encodingName) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003857 enum XML_Error result;
Haibo Huang40a71912019-10-11 11:13:39 -07003858 if (! storedEncName) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003859 storedEncName = poolStoreString(
Haibo Huang40a71912019-10-11 11:13:39 -07003860 &parser->m_temp2Pool, parser->m_encoding, encodingName,
3861 encodingName + XmlNameLength(parser->m_encoding, encodingName));
3862 if (! storedEncName)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003863 return XML_ERROR_NO_MEMORY;
3864 }
3865 result = handleUnknownEncoding(parser, storedEncName);
Elliott Hughes72472942018-01-10 08:36:10 -08003866 poolClear(&parser->m_temp2Pool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003867 if (result == XML_ERROR_UNKNOWN_ENCODING)
Elliott Hughes72472942018-01-10 08:36:10 -08003868 parser->m_eventPtr = encodingName;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003869 return result;
3870 }
3871 }
3872
3873 if (storedEncName || storedversion)
Elliott Hughes72472942018-01-10 08:36:10 -08003874 poolClear(&parser->m_temp2Pool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003875
3876 return XML_ERROR_NONE;
3877}
3878
3879static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07003880handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) {
Elliott Hughes72472942018-01-10 08:36:10 -08003881 if (parser->m_unknownEncodingHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003882 XML_Encoding info;
3883 int i;
3884 for (i = 0; i < 256; i++)
3885 info.map[i] = -1;
3886 info.convert = NULL;
3887 info.data = NULL;
3888 info.release = NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07003889 if (parser->m_unknownEncodingHandler(parser->m_unknownEncodingHandlerData,
3890 encodingName, &info)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003891 ENCODING *enc;
Elliott Hughes72472942018-01-10 08:36:10 -08003892 parser->m_unknownEncodingMem = MALLOC(parser, XmlSizeOfUnknownEncoding());
Haibo Huang40a71912019-10-11 11:13:39 -07003893 if (! parser->m_unknownEncodingMem) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003894 if (info.release)
3895 info.release(info.data);
3896 return XML_ERROR_NO_MEMORY;
3897 }
Haibo Huang40a71912019-10-11 11:13:39 -07003898 enc = (parser->m_ns ? XmlInitUnknownEncodingNS : XmlInitUnknownEncoding)(
3899 parser->m_unknownEncodingMem, info.map, info.convert, info.data);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003900 if (enc) {
Elliott Hughes72472942018-01-10 08:36:10 -08003901 parser->m_unknownEncodingData = info.data;
3902 parser->m_unknownEncodingRelease = info.release;
3903 parser->m_encoding = enc;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003904 return XML_ERROR_NONE;
3905 }
3906 }
3907 if (info.release != NULL)
3908 info.release(info.data);
3909 }
3910 return XML_ERROR_UNKNOWN_ENCODING;
3911}
3912
3913static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07003914prologInitProcessor(XML_Parser parser, const char *s, const char *end,
3915 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003916 enum XML_Error result = initializeEncoding(parser);
3917 if (result != XML_ERROR_NONE)
3918 return result;
Elliott Hughes72472942018-01-10 08:36:10 -08003919 parser->m_processor = prologProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003920 return prologProcessor(parser, s, end, nextPtr);
3921}
3922
3923#ifdef XML_DTD
3924
3925static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07003926externalParEntInitProcessor(XML_Parser parser, const char *s, const char *end,
3927 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003928 enum XML_Error result = initializeEncoding(parser);
3929 if (result != XML_ERROR_NONE)
3930 return result;
3931
3932 /* we know now that XML_Parse(Buffer) has been called,
3933 so we consider the external parameter entity read */
Elliott Hughes72472942018-01-10 08:36:10 -08003934 parser->m_dtd->paramEntityRead = XML_TRUE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003935
Elliott Hughes72472942018-01-10 08:36:10 -08003936 if (parser->m_prologState.inEntityValue) {
3937 parser->m_processor = entityValueInitProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003938 return entityValueInitProcessor(parser, s, end, nextPtr);
Haibo Huang40a71912019-10-11 11:13:39 -07003939 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08003940 parser->m_processor = externalParEntProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003941 return externalParEntProcessor(parser, s, end, nextPtr);
3942 }
3943}
3944
3945static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07003946entityValueInitProcessor(XML_Parser parser, const char *s, const char *end,
3947 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003948 int tok;
3949 const char *start = s;
3950 const char *next = start;
Elliott Hughes72472942018-01-10 08:36:10 -08003951 parser->m_eventPtr = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003952
Elliott Hughes35e432d2012-09-09 14:23:38 -07003953 for (;;) {
Elliott Hughes72472942018-01-10 08:36:10 -08003954 tok = XmlPrologTok(parser->m_encoding, start, end, &next);
3955 parser->m_eventEndPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003956 if (tok <= 0) {
Haibo Huang40a71912019-10-11 11:13:39 -07003957 if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003958 *nextPtr = s;
3959 return XML_ERROR_NONE;
3960 }
3961 switch (tok) {
3962 case XML_TOK_INVALID:
3963 return XML_ERROR_INVALID_TOKEN;
3964 case XML_TOK_PARTIAL:
3965 return XML_ERROR_UNCLOSED_TOKEN;
3966 case XML_TOK_PARTIAL_CHAR:
3967 return XML_ERROR_PARTIAL_CHAR;
Haibo Huang40a71912019-10-11 11:13:39 -07003968 case XML_TOK_NONE: /* start == end */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003969 default:
3970 break;
3971 }
3972 /* found end of entity value - can store it now */
Elliott Hughes72472942018-01-10 08:36:10 -08003973 return storeEntityValue(parser, parser->m_encoding, s, end);
Haibo Huang40a71912019-10-11 11:13:39 -07003974 } else if (tok == XML_TOK_XML_DECL) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003975 enum XML_Error result;
3976 result = processXmlDecl(parser, 0, start, next);
3977 if (result != XML_ERROR_NONE)
3978 return result;
Haibo Huang40a71912019-10-11 11:13:39 -07003979 /* At this point, m_parsingStatus.parsing cannot be XML_SUSPENDED. For
3980 * that to happen, a parameter entity parsing handler must have attempted
3981 * to suspend the parser, which fails and raises an error. The parser can
3982 * be aborted, but can't be suspended.
Elliott Hughes72472942018-01-10 08:36:10 -08003983 */
3984 if (parser->m_parsingStatus.parsing == XML_FINISHED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003985 return XML_ERROR_ABORTED;
Elliott Hughes72472942018-01-10 08:36:10 -08003986 *nextPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003987 /* stop scanning for text declaration - we found one */
Elliott Hughes72472942018-01-10 08:36:10 -08003988 parser->m_processor = entityValueProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08003989 return entityValueProcessor(parser, next, end, nextPtr);
3990 }
3991 /* If we are at the end of the buffer, this would cause XmlPrologTok to
3992 return XML_TOK_NONE on the next call, which would then cause the
3993 function to exit with *nextPtr set to s - that is what we want for other
3994 tokens, but not for the BOM - we would rather like to skip it;
3995 then, when this routine is entered the next time, XmlPrologTok will
3996 return XML_TOK_INVALID, since the BOM is still in the buffer
3997 */
Haibo Huang40a71912019-10-11 11:13:39 -07003998 else if (tok == XML_TOK_BOM && next == end
3999 && ! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004000 *nextPtr = next;
4001 return XML_ERROR_NONE;
4002 }
Elliott Hughes72472942018-01-10 08:36:10 -08004003 /* If we get this token, we have the start of what might be a
4004 normal tag, but not a declaration (i.e. it doesn't begin with
4005 "<!"). In a DTD context, that isn't legal.
4006 */
4007 else if (tok == XML_TOK_INSTANCE_START) {
4008 *nextPtr = next;
4009 return XML_ERROR_SYNTAX;
4010 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004011 start = next;
Elliott Hughes72472942018-01-10 08:36:10 -08004012 parser->m_eventPtr = start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004013 }
4014}
4015
4016static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07004017externalParEntProcessor(XML_Parser parser, const char *s, const char *end,
4018 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004019 const char *next = s;
4020 int tok;
4021
Elliott Hughes72472942018-01-10 08:36:10 -08004022 tok = XmlPrologTok(parser->m_encoding, s, end, &next);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004023 if (tok <= 0) {
Haibo Huang40a71912019-10-11 11:13:39 -07004024 if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004025 *nextPtr = s;
4026 return XML_ERROR_NONE;
4027 }
4028 switch (tok) {
4029 case XML_TOK_INVALID:
4030 return XML_ERROR_INVALID_TOKEN;
4031 case XML_TOK_PARTIAL:
4032 return XML_ERROR_UNCLOSED_TOKEN;
4033 case XML_TOK_PARTIAL_CHAR:
4034 return XML_ERROR_PARTIAL_CHAR;
Haibo Huang40a71912019-10-11 11:13:39 -07004035 case XML_TOK_NONE: /* start == end */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004036 default:
4037 break;
4038 }
4039 }
4040 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
4041 However, when parsing an external subset, doProlog will not accept a BOM
4042 as valid, and report a syntax error, so we have to skip the BOM
4043 */
4044 else if (tok == XML_TOK_BOM) {
4045 s = next;
Elliott Hughes72472942018-01-10 08:36:10 -08004046 tok = XmlPrologTok(parser->m_encoding, s, end, &next);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004047 }
4048
Elliott Hughes72472942018-01-10 08:36:10 -08004049 parser->m_processor = prologProcessor;
Haibo Huang40a71912019-10-11 11:13:39 -07004050 return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
4051 (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004052}
4053
4054static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07004055entityValueProcessor(XML_Parser parser, const char *s, const char *end,
4056 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004057 const char *start = s;
4058 const char *next = s;
Elliott Hughes72472942018-01-10 08:36:10 -08004059 const ENCODING *enc = parser->m_encoding;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004060 int tok;
4061
4062 for (;;) {
4063 tok = XmlPrologTok(enc, start, end, &next);
4064 if (tok <= 0) {
Haibo Huang40a71912019-10-11 11:13:39 -07004065 if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004066 *nextPtr = s;
4067 return XML_ERROR_NONE;
4068 }
4069 switch (tok) {
4070 case XML_TOK_INVALID:
4071 return XML_ERROR_INVALID_TOKEN;
4072 case XML_TOK_PARTIAL:
4073 return XML_ERROR_UNCLOSED_TOKEN;
4074 case XML_TOK_PARTIAL_CHAR:
4075 return XML_ERROR_PARTIAL_CHAR;
Haibo Huang40a71912019-10-11 11:13:39 -07004076 case XML_TOK_NONE: /* start == end */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004077 default:
4078 break;
4079 }
4080 /* found end of entity value - can store it now */
4081 return storeEntityValue(parser, enc, s, end);
4082 }
4083 start = next;
4084 }
4085}
4086
4087#endif /* XML_DTD */
4088
4089static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07004090prologProcessor(XML_Parser parser, const char *s, const char *end,
4091 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004092 const char *next = s;
Elliott Hughes72472942018-01-10 08:36:10 -08004093 int tok = XmlPrologTok(parser->m_encoding, s, end, &next);
Haibo Huang40a71912019-10-11 11:13:39 -07004094 return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
4095 (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004096}
4097
4098static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07004099doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
4100 int tok, const char *next, const char **nextPtr, XML_Bool haveMore,
4101 XML_Bool allowClosingDoctype) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004102#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07004103 static const XML_Char externalSubsetName[] = {ASCII_HASH, '\0'};
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004104#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07004105 static const XML_Char atypeCDATA[]
4106 = {ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'};
4107 static const XML_Char atypeID[] = {ASCII_I, ASCII_D, '\0'};
4108 static const XML_Char atypeIDREF[]
4109 = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0'};
4110 static const XML_Char atypeIDREFS[]
4111 = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0'};
4112 static const XML_Char atypeENTITY[]
4113 = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0'};
4114 static const XML_Char atypeENTITIES[]
4115 = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T,
4116 ASCII_I, ASCII_E, ASCII_S, '\0'};
4117 static const XML_Char atypeNMTOKEN[]
4118 = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0'};
4119 static const XML_Char atypeNMTOKENS[]
4120 = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K,
4121 ASCII_E, ASCII_N, ASCII_S, '\0'};
4122 static const XML_Char notationPrefix[]
4123 = {ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T,
4124 ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0'};
4125 static const XML_Char enumValueSep[] = {ASCII_PIPE, '\0'};
4126 static const XML_Char enumValueStart[] = {ASCII_LPAREN, '\0'};
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004127
4128 /* save one level of indirection */
Haibo Huang40a71912019-10-11 11:13:39 -07004129 DTD *const dtd = parser->m_dtd;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004130
4131 const char **eventPP;
4132 const char **eventEndPP;
4133 enum XML_Content_Quant quant;
4134
Elliott Hughes72472942018-01-10 08:36:10 -08004135 if (enc == parser->m_encoding) {
4136 eventPP = &parser->m_eventPtr;
4137 eventEndPP = &parser->m_eventEndPtr;
Haibo Huang40a71912019-10-11 11:13:39 -07004138 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08004139 eventPP = &(parser->m_openInternalEntities->internalEventPtr);
4140 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004141 }
4142
4143 for (;;) {
4144 int role;
4145 XML_Bool handleDefault = XML_TRUE;
4146 *eventPP = s;
4147 *eventEndPP = next;
4148 if (tok <= 0) {
4149 if (haveMore && tok != XML_TOK_INVALID) {
4150 *nextPtr = s;
4151 return XML_ERROR_NONE;
4152 }
4153 switch (tok) {
4154 case XML_TOK_INVALID:
4155 *eventPP = next;
4156 return XML_ERROR_INVALID_TOKEN;
4157 case XML_TOK_PARTIAL:
4158 return XML_ERROR_UNCLOSED_TOKEN;
4159 case XML_TOK_PARTIAL_CHAR:
4160 return XML_ERROR_PARTIAL_CHAR;
Elliott Hughes35e432d2012-09-09 14:23:38 -07004161 case -XML_TOK_PROLOG_S:
4162 tok = -tok;
4163 break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004164 case XML_TOK_NONE:
4165#ifdef XML_DTD
4166 /* for internal PE NOT referenced between declarations */
Haibo Huang40a71912019-10-11 11:13:39 -07004167 if (enc != parser->m_encoding
4168 && ! parser->m_openInternalEntities->betweenDecl) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004169 *nextPtr = s;
4170 return XML_ERROR_NONE;
4171 }
4172 /* WFC: PE Between Declarations - must check that PE contains
4173 complete markup, not only for external PEs, but also for
4174 internal PEs if the reference occurs between declarations.
4175 */
Elliott Hughes72472942018-01-10 08:36:10 -08004176 if (parser->m_isParamEntity || enc != parser->m_encoding) {
4177 if (XmlTokenRole(&parser->m_prologState, XML_TOK_NONE, end, end, enc)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004178 == XML_ROLE_ERROR)
4179 return XML_ERROR_INCOMPLETE_PE;
4180 *nextPtr = s;
4181 return XML_ERROR_NONE;
4182 }
4183#endif /* XML_DTD */
4184 return XML_ERROR_NO_ELEMENTS;
4185 default:
4186 tok = -tok;
4187 next = end;
4188 break;
4189 }
4190 }
Elliott Hughes72472942018-01-10 08:36:10 -08004191 role = XmlTokenRole(&parser->m_prologState, tok, s, next, enc);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004192 switch (role) {
Haibo Huang40a71912019-10-11 11:13:39 -07004193 case XML_ROLE_XML_DECL: {
4194 enum XML_Error result = processXmlDecl(parser, 0, s, next);
4195 if (result != XML_ERROR_NONE)
4196 return result;
4197 enc = parser->m_encoding;
4198 handleDefault = XML_FALSE;
4199 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004200 case XML_ROLE_DOCTYPE_NAME:
Elliott Hughes72472942018-01-10 08:36:10 -08004201 if (parser->m_startDoctypeDeclHandler) {
Haibo Huang40a71912019-10-11 11:13:39 -07004202 parser->m_doctypeName
4203 = poolStoreString(&parser->m_tempPool, enc, s, next);
4204 if (! parser->m_doctypeName)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004205 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004206 poolFinish(&parser->m_tempPool);
4207 parser->m_doctypePubid = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004208 handleDefault = XML_FALSE;
4209 }
Elliott Hughes72472942018-01-10 08:36:10 -08004210 parser->m_doctypeSysid = NULL; /* always initialize to NULL */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004211 break;
4212 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
Elliott Hughes72472942018-01-10 08:36:10 -08004213 if (parser->m_startDoctypeDeclHandler) {
Haibo Huang40a71912019-10-11 11:13:39 -07004214 parser->m_startDoctypeDeclHandler(
4215 parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid,
4216 parser->m_doctypePubid, 1);
Elliott Hughes72472942018-01-10 08:36:10 -08004217 parser->m_doctypeName = NULL;
4218 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004219 handleDefault = XML_FALSE;
4220 }
4221 break;
4222#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07004223 case XML_ROLE_TEXT_DECL: {
4224 enum XML_Error result = processXmlDecl(parser, 1, s, next);
4225 if (result != XML_ERROR_NONE)
4226 return result;
4227 enc = parser->m_encoding;
4228 handleDefault = XML_FALSE;
4229 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004230#endif /* XML_DTD */
4231 case XML_ROLE_DOCTYPE_PUBLIC_ID:
4232#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08004233 parser->m_useForeignDTD = XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07004234 parser->m_declEntity = (ENTITY *)lookup(
4235 parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY));
4236 if (! parser->m_declEntity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004237 return XML_ERROR_NO_MEMORY;
4238#endif /* XML_DTD */
4239 dtd->hasParamEntityRefs = XML_TRUE;
Elliott Hughes72472942018-01-10 08:36:10 -08004240 if (parser->m_startDoctypeDeclHandler) {
Elliott Hughes35e432d2012-09-09 14:23:38 -07004241 XML_Char *pubId;
Haibo Huang40a71912019-10-11 11:13:39 -07004242 if (! XmlIsPublicId(enc, s, next, eventPP))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004243 return XML_ERROR_PUBLICID;
Elliott Hughes72472942018-01-10 08:36:10 -08004244 pubId = poolStoreString(&parser->m_tempPool, enc,
Elliott Hughes35e432d2012-09-09 14:23:38 -07004245 s + enc->minBytesPerChar,
4246 next - enc->minBytesPerChar);
Haibo Huang40a71912019-10-11 11:13:39 -07004247 if (! pubId)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004248 return XML_ERROR_NO_MEMORY;
Elliott Hughes35e432d2012-09-09 14:23:38 -07004249 normalizePublicId(pubId);
Elliott Hughes72472942018-01-10 08:36:10 -08004250 poolFinish(&parser->m_tempPool);
4251 parser->m_doctypePubid = pubId;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004252 handleDefault = XML_FALSE;
4253 goto alreadyChecked;
4254 }
4255 /* fall through */
4256 case XML_ROLE_ENTITY_PUBLIC_ID:
Haibo Huang40a71912019-10-11 11:13:39 -07004257 if (! XmlIsPublicId(enc, s, next, eventPP))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004258 return XML_ERROR_PUBLICID;
4259 alreadyChecked:
Elliott Hughes72472942018-01-10 08:36:10 -08004260 if (dtd->keepProcessing && parser->m_declEntity) {
Haibo Huang40a71912019-10-11 11:13:39 -07004261 XML_Char *tem
4262 = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
4263 next - enc->minBytesPerChar);
4264 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004265 return XML_ERROR_NO_MEMORY;
4266 normalizePublicId(tem);
Elliott Hughes72472942018-01-10 08:36:10 -08004267 parser->m_declEntity->publicId = tem;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004268 poolFinish(&dtd->pool);
Elliott Hughes72472942018-01-10 08:36:10 -08004269 /* Don't suppress the default handler if we fell through from
4270 * the XML_ROLE_DOCTYPE_PUBLIC_ID case.
4271 */
4272 if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_PUBLIC_ID)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004273 handleDefault = XML_FALSE;
4274 }
4275 break;
4276 case XML_ROLE_DOCTYPE_CLOSE:
Haibo Huang40a71912019-10-11 11:13:39 -07004277 if (allowClosingDoctype != XML_TRUE) {
4278 /* Must not close doctype from within expanded parameter entities */
4279 return XML_ERROR_INVALID_TOKEN;
4280 }
4281
Elliott Hughes72472942018-01-10 08:36:10 -08004282 if (parser->m_doctypeName) {
Haibo Huang40a71912019-10-11 11:13:39 -07004283 parser->m_startDoctypeDeclHandler(
4284 parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid,
4285 parser->m_doctypePubid, 0);
Elliott Hughes72472942018-01-10 08:36:10 -08004286 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004287 handleDefault = XML_FALSE;
4288 }
Elliott Hughes72472942018-01-10 08:36:10 -08004289 /* parser->m_doctypeSysid will be non-NULL in the case of a previous
4290 XML_ROLE_DOCTYPE_SYSTEM_ID, even if parser->m_startDoctypeDeclHandler
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004291 was not set, indicating an external subset
4292 */
4293#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08004294 if (parser->m_doctypeSysid || parser->m_useForeignDTD) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004295 XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
4296 dtd->hasParamEntityRefs = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07004297 if (parser->m_paramEntityParsing
4298 && parser->m_externalEntityRefHandler) {
4299 ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
4300 externalSubsetName, sizeof(ENTITY));
4301 if (! entity) {
Elliott Hughes72472942018-01-10 08:36:10 -08004302 /* The external subset name "#" will have already been
4303 * inserted into the hash table at the start of the
4304 * external entity parsing, so no allocation will happen
4305 * and lookup() cannot fail.
4306 */
4307 return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */
4308 }
4309 if (parser->m_useForeignDTD)
4310 entity->base = parser->m_curBase;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004311 dtd->paramEntityRead = XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07004312 if (! parser->m_externalEntityRefHandler(
4313 parser->m_externalEntityRefHandlerArg, 0, entity->base,
4314 entity->systemId, entity->publicId))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004315 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4316 if (dtd->paramEntityRead) {
Haibo Huang40a71912019-10-11 11:13:39 -07004317 if (! dtd->standalone && parser->m_notStandaloneHandler
4318 && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004319 return XML_ERROR_NOT_STANDALONE;
4320 }
4321 /* if we didn't read the foreign DTD then this means that there
4322 is no external subset and we must reset dtd->hasParamEntityRefs
4323 */
Haibo Huang40a71912019-10-11 11:13:39 -07004324 else if (! parser->m_doctypeSysid)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004325 dtd->hasParamEntityRefs = hadParamEntityRefs;
4326 /* end of DTD - no need to update dtd->keepProcessing */
4327 }
Elliott Hughes72472942018-01-10 08:36:10 -08004328 parser->m_useForeignDTD = XML_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004329 }
4330#endif /* XML_DTD */
Elliott Hughes72472942018-01-10 08:36:10 -08004331 if (parser->m_endDoctypeDeclHandler) {
4332 parser->m_endDoctypeDeclHandler(parser->m_handlerArg);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004333 handleDefault = XML_FALSE;
4334 }
4335 break;
4336 case XML_ROLE_INSTANCE_START:
4337#ifdef XML_DTD
4338 /* if there is no DOCTYPE declaration then now is the
4339 last chance to read the foreign DTD
4340 */
Elliott Hughes72472942018-01-10 08:36:10 -08004341 if (parser->m_useForeignDTD) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004342 XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
4343 dtd->hasParamEntityRefs = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07004344 if (parser->m_paramEntityParsing
4345 && parser->m_externalEntityRefHandler) {
Elliott Hughes35e432d2012-09-09 14:23:38 -07004346 ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
Haibo Huang40a71912019-10-11 11:13:39 -07004347 externalSubsetName, sizeof(ENTITY));
4348 if (! entity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004349 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004350 entity->base = parser->m_curBase;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004351 dtd->paramEntityRead = XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07004352 if (! parser->m_externalEntityRefHandler(
4353 parser->m_externalEntityRefHandlerArg, 0, entity->base,
4354 entity->systemId, entity->publicId))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004355 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4356 if (dtd->paramEntityRead) {
Haibo Huang40a71912019-10-11 11:13:39 -07004357 if (! dtd->standalone && parser->m_notStandaloneHandler
4358 && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004359 return XML_ERROR_NOT_STANDALONE;
4360 }
4361 /* if we didn't read the foreign DTD then this means that there
4362 is no external subset and we must reset dtd->hasParamEntityRefs
4363 */
4364 else
4365 dtd->hasParamEntityRefs = hadParamEntityRefs;
4366 /* end of DTD - no need to update dtd->keepProcessing */
4367 }
4368 }
4369#endif /* XML_DTD */
Elliott Hughes72472942018-01-10 08:36:10 -08004370 parser->m_processor = contentProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004371 return contentProcessor(parser, s, end, nextPtr);
4372 case XML_ROLE_ATTLIST_ELEMENT_NAME:
Elliott Hughes72472942018-01-10 08:36:10 -08004373 parser->m_declElementType = getElementType(parser, enc, s, next);
Haibo Huang40a71912019-10-11 11:13:39 -07004374 if (! parser->m_declElementType)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004375 return XML_ERROR_NO_MEMORY;
4376 goto checkAttListDeclHandler;
4377 case XML_ROLE_ATTRIBUTE_NAME:
Elliott Hughes72472942018-01-10 08:36:10 -08004378 parser->m_declAttributeId = getAttributeId(parser, enc, s, next);
Haibo Huang40a71912019-10-11 11:13:39 -07004379 if (! parser->m_declAttributeId)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004380 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004381 parser->m_declAttributeIsCdata = XML_FALSE;
4382 parser->m_declAttributeType = NULL;
4383 parser->m_declAttributeIsId = XML_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004384 goto checkAttListDeclHandler;
4385 case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
Elliott Hughes72472942018-01-10 08:36:10 -08004386 parser->m_declAttributeIsCdata = XML_TRUE;
4387 parser->m_declAttributeType = atypeCDATA;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004388 goto checkAttListDeclHandler;
4389 case XML_ROLE_ATTRIBUTE_TYPE_ID:
Elliott Hughes72472942018-01-10 08:36:10 -08004390 parser->m_declAttributeIsId = XML_TRUE;
4391 parser->m_declAttributeType = atypeID;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004392 goto checkAttListDeclHandler;
4393 case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
Elliott Hughes72472942018-01-10 08:36:10 -08004394 parser->m_declAttributeType = atypeIDREF;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004395 goto checkAttListDeclHandler;
4396 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
Elliott Hughes72472942018-01-10 08:36:10 -08004397 parser->m_declAttributeType = atypeIDREFS;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004398 goto checkAttListDeclHandler;
4399 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
Elliott Hughes72472942018-01-10 08:36:10 -08004400 parser->m_declAttributeType = atypeENTITY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004401 goto checkAttListDeclHandler;
4402 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
Elliott Hughes72472942018-01-10 08:36:10 -08004403 parser->m_declAttributeType = atypeENTITIES;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004404 goto checkAttListDeclHandler;
4405 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
Elliott Hughes72472942018-01-10 08:36:10 -08004406 parser->m_declAttributeType = atypeNMTOKEN;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004407 goto checkAttListDeclHandler;
4408 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
Elliott Hughes72472942018-01-10 08:36:10 -08004409 parser->m_declAttributeType = atypeNMTOKENS;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004410 checkAttListDeclHandler:
Elliott Hughes72472942018-01-10 08:36:10 -08004411 if (dtd->keepProcessing && parser->m_attlistDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004412 handleDefault = XML_FALSE;
4413 break;
4414 case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
4415 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
Elliott Hughes72472942018-01-10 08:36:10 -08004416 if (dtd->keepProcessing && parser->m_attlistDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004417 const XML_Char *prefix;
Elliott Hughes72472942018-01-10 08:36:10 -08004418 if (parser->m_declAttributeType) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004419 prefix = enumValueSep;
Haibo Huang40a71912019-10-11 11:13:39 -07004420 } else {
4421 prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE ? notationPrefix
4422 : enumValueStart);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004423 }
Haibo Huang40a71912019-10-11 11:13:39 -07004424 if (! poolAppendString(&parser->m_tempPool, prefix))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004425 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07004426 if (! poolAppend(&parser->m_tempPool, enc, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004427 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004428 parser->m_declAttributeType = parser->m_tempPool.start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004429 handleDefault = XML_FALSE;
4430 }
4431 break;
4432 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
4433 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
4434 if (dtd->keepProcessing) {
Haibo Huang40a71912019-10-11 11:13:39 -07004435 if (! defineAttribute(parser->m_declElementType,
4436 parser->m_declAttributeId,
4437 parser->m_declAttributeIsCdata,
4438 parser->m_declAttributeIsId, 0, parser))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004439 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004440 if (parser->m_attlistDeclHandler && parser->m_declAttributeType) {
4441 if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN)
4442 || (*parser->m_declAttributeType == XML_T(ASCII_N)
4443 && parser->m_declAttributeType[1] == XML_T(ASCII_O))) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004444 /* Enumerated or Notation type */
Haibo Huang40a71912019-10-11 11:13:39 -07004445 if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN))
4446 || ! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004447 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004448 parser->m_declAttributeType = parser->m_tempPool.start;
4449 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004450 }
4451 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004452 parser->m_attlistDeclHandler(
4453 parser->m_handlerArg, parser->m_declElementType->name,
4454 parser->m_declAttributeId->name, parser->m_declAttributeType, 0,
4455 role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
Elliott Hughes72472942018-01-10 08:36:10 -08004456 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004457 handleDefault = XML_FALSE;
4458 }
4459 }
4460 break;
4461 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
4462 case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
4463 if (dtd->keepProcessing) {
4464 const XML_Char *attVal;
Haibo Huang40a71912019-10-11 11:13:39 -07004465 enum XML_Error result = storeAttributeValue(
4466 parser, enc, parser->m_declAttributeIsCdata,
4467 s + enc->minBytesPerChar, next - enc->minBytesPerChar, &dtd->pool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004468 if (result)
4469 return result;
4470 attVal = poolStart(&dtd->pool);
4471 poolFinish(&dtd->pool);
4472 /* ID attributes aren't allowed to have a default */
Haibo Huang40a71912019-10-11 11:13:39 -07004473 if (! defineAttribute(
4474 parser->m_declElementType, parser->m_declAttributeId,
4475 parser->m_declAttributeIsCdata, XML_FALSE, attVal, parser))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004476 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004477 if (parser->m_attlistDeclHandler && parser->m_declAttributeType) {
4478 if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN)
4479 || (*parser->m_declAttributeType == XML_T(ASCII_N)
4480 && parser->m_declAttributeType[1] == XML_T(ASCII_O))) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004481 /* Enumerated or Notation type */
Haibo Huang40a71912019-10-11 11:13:39 -07004482 if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN))
4483 || ! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004484 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004485 parser->m_declAttributeType = parser->m_tempPool.start;
4486 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004487 }
4488 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004489 parser->m_attlistDeclHandler(
4490 parser->m_handlerArg, parser->m_declElementType->name,
4491 parser->m_declAttributeId->name, parser->m_declAttributeType,
4492 attVal, role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
Elliott Hughes72472942018-01-10 08:36:10 -08004493 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004494 handleDefault = XML_FALSE;
4495 }
4496 }
4497 break;
4498 case XML_ROLE_ENTITY_VALUE:
4499 if (dtd->keepProcessing) {
Haibo Huang40a71912019-10-11 11:13:39 -07004500 enum XML_Error result = storeEntityValue(
4501 parser, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar);
Elliott Hughes72472942018-01-10 08:36:10 -08004502 if (parser->m_declEntity) {
4503 parser->m_declEntity->textPtr = poolStart(&dtd->entityValuePool);
Haibo Huang40a71912019-10-11 11:13:39 -07004504 parser->m_declEntity->textLen
4505 = (int)(poolLength(&dtd->entityValuePool));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004506 poolFinish(&dtd->entityValuePool);
Elliott Hughes72472942018-01-10 08:36:10 -08004507 if (parser->m_entityDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004508 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004509 parser->m_entityDeclHandler(
4510 parser->m_handlerArg, parser->m_declEntity->name,
4511 parser->m_declEntity->is_param, parser->m_declEntity->textPtr,
4512 parser->m_declEntity->textLen, parser->m_curBase, 0, 0, 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004513 handleDefault = XML_FALSE;
4514 }
Haibo Huang40a71912019-10-11 11:13:39 -07004515 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004516 poolDiscard(&dtd->entityValuePool);
4517 if (result != XML_ERROR_NONE)
4518 return result;
4519 }
4520 break;
4521 case XML_ROLE_DOCTYPE_SYSTEM_ID:
4522#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08004523 parser->m_useForeignDTD = XML_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004524#endif /* XML_DTD */
4525 dtd->hasParamEntityRefs = XML_TRUE;
Elliott Hughes72472942018-01-10 08:36:10 -08004526 if (parser->m_startDoctypeDeclHandler) {
4527 parser->m_doctypeSysid = poolStoreString(&parser->m_tempPool, enc,
Haibo Huang40a71912019-10-11 11:13:39 -07004528 s + enc->minBytesPerChar,
4529 next - enc->minBytesPerChar);
Elliott Hughes72472942018-01-10 08:36:10 -08004530 if (parser->m_doctypeSysid == NULL)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004531 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004532 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004533 handleDefault = XML_FALSE;
4534 }
4535#ifdef XML_DTD
4536 else
Elliott Hughes72472942018-01-10 08:36:10 -08004537 /* use externalSubsetName to make parser->m_doctypeSysid non-NULL
4538 for the case where no parser->m_startDoctypeDeclHandler is set */
4539 parser->m_doctypeSysid = externalSubsetName;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004540#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07004541 if (! dtd->standalone
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004542#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07004543 && ! parser->m_paramEntityParsing
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004544#endif /* XML_DTD */
Elliott Hughes72472942018-01-10 08:36:10 -08004545 && parser->m_notStandaloneHandler
Haibo Huang40a71912019-10-11 11:13:39 -07004546 && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004547 return XML_ERROR_NOT_STANDALONE;
4548#ifndef XML_DTD
4549 break;
Haibo Huang40a71912019-10-11 11:13:39 -07004550#else /* XML_DTD */
4551 if (! parser->m_declEntity) {
4552 parser->m_declEntity = (ENTITY *)lookup(
4553 parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY));
4554 if (! parser->m_declEntity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004555 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004556 parser->m_declEntity->publicId = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004557 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004558#endif /* XML_DTD */
Elliott Hughesaaec48e2018-08-16 16:29:01 -07004559 /* fall through */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004560 case XML_ROLE_ENTITY_SYSTEM_ID:
Elliott Hughes72472942018-01-10 08:36:10 -08004561 if (dtd->keepProcessing && parser->m_declEntity) {
Haibo Huang40a71912019-10-11 11:13:39 -07004562 parser->m_declEntity->systemId
4563 = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
4564 next - enc->minBytesPerChar);
4565 if (! parser->m_declEntity->systemId)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004566 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004567 parser->m_declEntity->base = parser->m_curBase;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004568 poolFinish(&dtd->pool);
Elliott Hughes72472942018-01-10 08:36:10 -08004569 /* Don't suppress the default handler if we fell through from
4570 * the XML_ROLE_DOCTYPE_SYSTEM_ID case.
4571 */
4572 if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_SYSTEM_ID)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004573 handleDefault = XML_FALSE;
4574 }
4575 break;
4576 case XML_ROLE_ENTITY_COMPLETE:
Haibo Huang40a71912019-10-11 11:13:39 -07004577 if (dtd->keepProcessing && parser->m_declEntity
4578 && parser->m_entityDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004579 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004580 parser->m_entityDeclHandler(
4581 parser->m_handlerArg, parser->m_declEntity->name,
4582 parser->m_declEntity->is_param, 0, 0, parser->m_declEntity->base,
4583 parser->m_declEntity->systemId, parser->m_declEntity->publicId, 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004584 handleDefault = XML_FALSE;
4585 }
4586 break;
4587 case XML_ROLE_ENTITY_NOTATION_NAME:
Elliott Hughes72472942018-01-10 08:36:10 -08004588 if (dtd->keepProcessing && parser->m_declEntity) {
Haibo Huang40a71912019-10-11 11:13:39 -07004589 parser->m_declEntity->notation
4590 = poolStoreString(&dtd->pool, enc, s, next);
4591 if (! parser->m_declEntity->notation)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004592 return XML_ERROR_NO_MEMORY;
4593 poolFinish(&dtd->pool);
Elliott Hughes72472942018-01-10 08:36:10 -08004594 if (parser->m_unparsedEntityDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004595 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004596 parser->m_unparsedEntityDeclHandler(
4597 parser->m_handlerArg, parser->m_declEntity->name,
4598 parser->m_declEntity->base, parser->m_declEntity->systemId,
4599 parser->m_declEntity->publicId, parser->m_declEntity->notation);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004600 handleDefault = XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07004601 } else if (parser->m_entityDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004602 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004603 parser->m_entityDeclHandler(
4604 parser->m_handlerArg, parser->m_declEntity->name, 0, 0, 0,
4605 parser->m_declEntity->base, parser->m_declEntity->systemId,
4606 parser->m_declEntity->publicId, parser->m_declEntity->notation);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004607 handleDefault = XML_FALSE;
4608 }
4609 }
4610 break;
Haibo Huang40a71912019-10-11 11:13:39 -07004611 case XML_ROLE_GENERAL_ENTITY_NAME: {
4612 if (XmlPredefinedEntityName(enc, s, next)) {
4613 parser->m_declEntity = NULL;
4614 break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004615 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004616 if (dtd->keepProcessing) {
4617 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
Haibo Huang40a71912019-10-11 11:13:39 -07004618 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004619 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07004620 parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities,
4621 name, sizeof(ENTITY));
4622 if (! parser->m_declEntity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004623 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004624 if (parser->m_declEntity->name != name) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004625 poolDiscard(&dtd->pool);
Elliott Hughes72472942018-01-10 08:36:10 -08004626 parser->m_declEntity = NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07004627 } else {
4628 poolFinish(&dtd->pool);
4629 parser->m_declEntity->publicId = NULL;
4630 parser->m_declEntity->is_param = XML_FALSE;
4631 /* if we have a parent parser or are reading an internal parameter
4632 entity, then the entity declaration is not considered "internal"
4633 */
4634 parser->m_declEntity->is_internal
4635 = ! (parser->m_parentParser || parser->m_openInternalEntities);
4636 if (parser->m_entityDeclHandler)
4637 handleDefault = XML_FALSE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004638 }
Haibo Huang40a71912019-10-11 11:13:39 -07004639 } else {
4640 poolDiscard(&dtd->pool);
4641 parser->m_declEntity = NULL;
4642 }
4643 } break;
4644 case XML_ROLE_PARAM_ENTITY_NAME:
4645#ifdef XML_DTD
4646 if (dtd->keepProcessing) {
4647 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
4648 if (! name)
4649 return XML_ERROR_NO_MEMORY;
4650 parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities,
4651 name, sizeof(ENTITY));
4652 if (! parser->m_declEntity)
4653 return XML_ERROR_NO_MEMORY;
4654 if (parser->m_declEntity->name != name) {
4655 poolDiscard(&dtd->pool);
4656 parser->m_declEntity = NULL;
4657 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004658 poolFinish(&dtd->pool);
Elliott Hughes72472942018-01-10 08:36:10 -08004659 parser->m_declEntity->publicId = NULL;
4660 parser->m_declEntity->is_param = XML_TRUE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004661 /* if we have a parent parser or are reading an internal parameter
4662 entity, then the entity declaration is not considered "internal"
4663 */
Haibo Huang40a71912019-10-11 11:13:39 -07004664 parser->m_declEntity->is_internal
4665 = ! (parser->m_parentParser || parser->m_openInternalEntities);
Elliott Hughes72472942018-01-10 08:36:10 -08004666 if (parser->m_entityDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004667 handleDefault = XML_FALSE;
4668 }
Haibo Huang40a71912019-10-11 11:13:39 -07004669 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004670 poolDiscard(&dtd->pool);
Elliott Hughes72472942018-01-10 08:36:10 -08004671 parser->m_declEntity = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004672 }
Haibo Huang40a71912019-10-11 11:13:39 -07004673#else /* not XML_DTD */
Elliott Hughes72472942018-01-10 08:36:10 -08004674 parser->m_declEntity = NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004675#endif /* XML_DTD */
4676 break;
4677 case XML_ROLE_NOTATION_NAME:
Elliott Hughes72472942018-01-10 08:36:10 -08004678 parser->m_declNotationPublicId = NULL;
4679 parser->m_declNotationName = NULL;
4680 if (parser->m_notationDeclHandler) {
Haibo Huang40a71912019-10-11 11:13:39 -07004681 parser->m_declNotationName
4682 = poolStoreString(&parser->m_tempPool, enc, s, next);
4683 if (! parser->m_declNotationName)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004684 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004685 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004686 handleDefault = XML_FALSE;
4687 }
4688 break;
4689 case XML_ROLE_NOTATION_PUBLIC_ID:
Haibo Huang40a71912019-10-11 11:13:39 -07004690 if (! XmlIsPublicId(enc, s, next, eventPP))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004691 return XML_ERROR_PUBLICID;
Haibo Huang40a71912019-10-11 11:13:39 -07004692 if (parser
4693 ->m_declNotationName) { /* means m_notationDeclHandler != NULL */
4694 XML_Char *tem = poolStoreString(&parser->m_tempPool, enc,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004695 s + enc->minBytesPerChar,
4696 next - enc->minBytesPerChar);
Haibo Huang40a71912019-10-11 11:13:39 -07004697 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004698 return XML_ERROR_NO_MEMORY;
4699 normalizePublicId(tem);
Elliott Hughes72472942018-01-10 08:36:10 -08004700 parser->m_declNotationPublicId = tem;
4701 poolFinish(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004702 handleDefault = XML_FALSE;
4703 }
4704 break;
4705 case XML_ROLE_NOTATION_SYSTEM_ID:
Elliott Hughes72472942018-01-10 08:36:10 -08004706 if (parser->m_declNotationName && parser->m_notationDeclHandler) {
Haibo Huang40a71912019-10-11 11:13:39 -07004707 const XML_Char *systemId = poolStoreString(&parser->m_tempPool, enc,
4708 s + enc->minBytesPerChar,
4709 next - enc->minBytesPerChar);
4710 if (! systemId)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004711 return XML_ERROR_NO_MEMORY;
4712 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004713 parser->m_notationDeclHandler(
4714 parser->m_handlerArg, parser->m_declNotationName, parser->m_curBase,
4715 systemId, parser->m_declNotationPublicId);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004716 handleDefault = XML_FALSE;
4717 }
Elliott Hughes72472942018-01-10 08:36:10 -08004718 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004719 break;
4720 case XML_ROLE_NOTATION_NO_SYSTEM_ID:
Elliott Hughes72472942018-01-10 08:36:10 -08004721 if (parser->m_declNotationPublicId && parser->m_notationDeclHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004722 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004723 parser->m_notationDeclHandler(
4724 parser->m_handlerArg, parser->m_declNotationName, parser->m_curBase,
4725 0, parser->m_declNotationPublicId);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004726 handleDefault = XML_FALSE;
4727 }
Elliott Hughes72472942018-01-10 08:36:10 -08004728 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004729 break;
4730 case XML_ROLE_ERROR:
4731 switch (tok) {
4732 case XML_TOK_PARAM_ENTITY_REF:
4733 /* PE references in internal subset are
Elliott Hughes35e432d2012-09-09 14:23:38 -07004734 not allowed within declarations. */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004735 return XML_ERROR_PARAM_ENTITY_REF;
4736 case XML_TOK_XML_DECL:
4737 return XML_ERROR_MISPLACED_XML_PI;
4738 default:
4739 return XML_ERROR_SYNTAX;
4740 }
4741#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07004742 case XML_ROLE_IGNORE_SECT: {
4743 enum XML_Error result;
4744 if (parser->m_defaultHandler)
4745 reportDefault(parser, enc, s, next);
4746 handleDefault = XML_FALSE;
4747 result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
4748 if (result != XML_ERROR_NONE)
4749 return result;
4750 else if (! next) {
4751 parser->m_processor = ignoreSectionProcessor;
4752 return result;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004753 }
Haibo Huang40a71912019-10-11 11:13:39 -07004754 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004755#endif /* XML_DTD */
4756 case XML_ROLE_GROUP_OPEN:
Elliott Hughes72472942018-01-10 08:36:10 -08004757 if (parser->m_prologState.level >= parser->m_groupSize) {
4758 if (parser->m_groupSize) {
Haibo Huang40a71912019-10-11 11:13:39 -07004759 {
4760 char *const new_connector = (char *)REALLOC(
4761 parser, parser->m_groupConnector, parser->m_groupSize *= 2);
4762 if (new_connector == NULL) {
4763 parser->m_groupSize /= 2;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004764 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07004765 }
4766 parser->m_groupConnector = new_connector;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004767 }
Haibo Huang40a71912019-10-11 11:13:39 -07004768
4769 if (dtd->scaffIndex) {
4770 int *const new_scaff_index = (int *)REALLOC(
4771 parser, dtd->scaffIndex, parser->m_groupSize * sizeof(int));
4772 if (new_scaff_index == NULL)
4773 return XML_ERROR_NO_MEMORY;
4774 dtd->scaffIndex = new_scaff_index;
4775 }
4776 } else {
4777 parser->m_groupConnector
4778 = (char *)MALLOC(parser, parser->m_groupSize = 32);
4779 if (! parser->m_groupConnector) {
Elliott Hughes72472942018-01-10 08:36:10 -08004780 parser->m_groupSize = 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004781 return XML_ERROR_NO_MEMORY;
Elliott Hughes72472942018-01-10 08:36:10 -08004782 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004783 }
4784 }
Elliott Hughes72472942018-01-10 08:36:10 -08004785 parser->m_groupConnector[parser->m_prologState.level] = 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004786 if (dtd->in_eldecl) {
4787 int myindex = nextScaffoldPart(parser);
4788 if (myindex < 0)
4789 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07004790 assert(dtd->scaffIndex != NULL);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004791 dtd->scaffIndex[dtd->scaffLevel] = myindex;
4792 dtd->scaffLevel++;
4793 dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
Elliott Hughes72472942018-01-10 08:36:10 -08004794 if (parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004795 handleDefault = XML_FALSE;
4796 }
4797 break;
4798 case XML_ROLE_GROUP_SEQUENCE:
Elliott Hughes72472942018-01-10 08:36:10 -08004799 if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_PIPE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004800 return XML_ERROR_SYNTAX;
Elliott Hughes72472942018-01-10 08:36:10 -08004801 parser->m_groupConnector[parser->m_prologState.level] = ASCII_COMMA;
4802 if (dtd->in_eldecl && parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004803 handleDefault = XML_FALSE;
4804 break;
4805 case XML_ROLE_GROUP_CHOICE:
Elliott Hughes72472942018-01-10 08:36:10 -08004806 if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_COMMA)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004807 return XML_ERROR_SYNTAX;
4808 if (dtd->in_eldecl
Haibo Huang40a71912019-10-11 11:13:39 -07004809 && ! parser->m_groupConnector[parser->m_prologState.level]
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004810 && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
Haibo Huang40a71912019-10-11 11:13:39 -07004811 != XML_CTYPE_MIXED)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004812 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4813 = XML_CTYPE_CHOICE;
Elliott Hughes72472942018-01-10 08:36:10 -08004814 if (parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004815 handleDefault = XML_FALSE;
4816 }
Elliott Hughes72472942018-01-10 08:36:10 -08004817 parser->m_groupConnector[parser->m_prologState.level] = ASCII_PIPE;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004818 break;
4819 case XML_ROLE_PARAM_ENTITY_REF:
4820#ifdef XML_DTD
4821 case XML_ROLE_INNER_PARAM_ENTITY_REF:
4822 dtd->hasParamEntityRefs = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07004823 if (! parser->m_paramEntityParsing)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004824 dtd->keepProcessing = dtd->standalone;
4825 else {
4826 const XML_Char *name;
4827 ENTITY *entity;
Haibo Huang40a71912019-10-11 11:13:39 -07004828 name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
4829 next - enc->minBytesPerChar);
4830 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004831 return XML_ERROR_NO_MEMORY;
Elliott Hughes35e432d2012-09-09 14:23:38 -07004832 entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004833 poolDiscard(&dtd->pool);
4834 /* first, determine if a check for an existing declaration is needed;
4835 if yes, check that the entity exists, and that it is internal,
4836 otherwise call the skipped entity handler
4837 */
Haibo Huang40a71912019-10-11 11:13:39 -07004838 if (parser->m_prologState.documentEntity
4839 && (dtd->standalone ? ! parser->m_openInternalEntities
4840 : ! dtd->hasParamEntityRefs)) {
4841 if (! entity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004842 return XML_ERROR_UNDEFINED_ENTITY;
Haibo Huang40a71912019-10-11 11:13:39 -07004843 else if (! entity->is_internal) {
Elliott Hughes72472942018-01-10 08:36:10 -08004844 /* It's hard to exhaustively search the code to be sure,
4845 * but there doesn't seem to be a way of executing the
4846 * following line. There are two cases:
4847 *
4848 * If 'standalone' is false, the DTD must have no
4849 * parameter entities or we wouldn't have passed the outer
4850 * 'if' statement. That measn the only entity in the hash
4851 * table is the external subset name "#" which cannot be
4852 * given as a parameter entity name in XML syntax, so the
4853 * lookup must have returned NULL and we don't even reach
4854 * the test for an internal entity.
4855 *
4856 * If 'standalone' is true, it does not seem to be
4857 * possible to create entities taking this code path that
4858 * are not internal entities, so fail the test above.
4859 *
4860 * Because this analysis is very uncertain, the code is
4861 * being left in place and merely removed from the
4862 * coverage test statistics.
4863 */
4864 return XML_ERROR_ENTITY_DECLARED_IN_PE; /* LCOV_EXCL_LINE */
4865 }
Haibo Huang40a71912019-10-11 11:13:39 -07004866 } else if (! entity) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004867 dtd->keepProcessing = dtd->standalone;
4868 /* cannot report skipped entities in declarations */
Haibo Huang40a71912019-10-11 11:13:39 -07004869 if ((role == XML_ROLE_PARAM_ENTITY_REF)
4870 && parser->m_skippedEntityHandler) {
Elliott Hughes72472942018-01-10 08:36:10 -08004871 parser->m_skippedEntityHandler(parser->m_handlerArg, name, 1);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004872 handleDefault = XML_FALSE;
4873 }
4874 break;
4875 }
4876 if (entity->open)
4877 return XML_ERROR_RECURSIVE_ENTITY_REF;
4878 if (entity->textPtr) {
4879 enum XML_Error result;
Haibo Huang40a71912019-10-11 11:13:39 -07004880 XML_Bool betweenDecl
4881 = (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004882 result = processInternalEntity(parser, entity, betweenDecl);
4883 if (result != XML_ERROR_NONE)
4884 return result;
4885 handleDefault = XML_FALSE;
4886 break;
4887 }
Elliott Hughes72472942018-01-10 08:36:10 -08004888 if (parser->m_externalEntityRefHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004889 dtd->paramEntityRead = XML_FALSE;
4890 entity->open = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07004891 if (! parser->m_externalEntityRefHandler(
4892 parser->m_externalEntityRefHandlerArg, 0, entity->base,
4893 entity->systemId, entity->publicId)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004894 entity->open = XML_FALSE;
4895 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4896 }
4897 entity->open = XML_FALSE;
4898 handleDefault = XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07004899 if (! dtd->paramEntityRead) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004900 dtd->keepProcessing = dtd->standalone;
4901 break;
4902 }
Haibo Huang40a71912019-10-11 11:13:39 -07004903 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004904 dtd->keepProcessing = dtd->standalone;
4905 break;
4906 }
4907 }
4908#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07004909 if (! dtd->standalone && parser->m_notStandaloneHandler
4910 && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004911 return XML_ERROR_NOT_STANDALONE;
4912 break;
4913
Haibo Huang40a71912019-10-11 11:13:39 -07004914 /* Element declaration stuff */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004915
4916 case XML_ROLE_ELEMENT_NAME:
Elliott Hughes72472942018-01-10 08:36:10 -08004917 if (parser->m_elementDeclHandler) {
4918 parser->m_declElementType = getElementType(parser, enc, s, next);
Haibo Huang40a71912019-10-11 11:13:39 -07004919 if (! parser->m_declElementType)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004920 return XML_ERROR_NO_MEMORY;
4921 dtd->scaffLevel = 0;
4922 dtd->scaffCount = 0;
4923 dtd->in_eldecl = XML_TRUE;
4924 handleDefault = XML_FALSE;
4925 }
4926 break;
4927
4928 case XML_ROLE_CONTENT_ANY:
4929 case XML_ROLE_CONTENT_EMPTY:
4930 if (dtd->in_eldecl) {
Elliott Hughes72472942018-01-10 08:36:10 -08004931 if (parser->m_elementDeclHandler) {
Haibo Huang40a71912019-10-11 11:13:39 -07004932 XML_Content *content
4933 = (XML_Content *)MALLOC(parser, sizeof(XML_Content));
4934 if (! content)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004935 return XML_ERROR_NO_MEMORY;
4936 content->quant = XML_CQUANT_NONE;
4937 content->name = NULL;
4938 content->numchildren = 0;
4939 content->children = NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07004940 content->type = ((role == XML_ROLE_CONTENT_ANY) ? XML_CTYPE_ANY
4941 : XML_CTYPE_EMPTY);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004942 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07004943 parser->m_elementDeclHandler(
4944 parser->m_handlerArg, parser->m_declElementType->name, content);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004945 handleDefault = XML_FALSE;
4946 }
4947 dtd->in_eldecl = XML_FALSE;
4948 }
4949 break;
4950
4951 case XML_ROLE_CONTENT_PCDATA:
4952 if (dtd->in_eldecl) {
4953 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4954 = XML_CTYPE_MIXED;
Elliott Hughes72472942018-01-10 08:36:10 -08004955 if (parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004956 handleDefault = XML_FALSE;
4957 }
4958 break;
4959
4960 case XML_ROLE_CONTENT_ELEMENT:
4961 quant = XML_CQUANT_NONE;
4962 goto elementContent;
4963 case XML_ROLE_CONTENT_ELEMENT_OPT:
4964 quant = XML_CQUANT_OPT;
4965 goto elementContent;
4966 case XML_ROLE_CONTENT_ELEMENT_REP:
4967 quant = XML_CQUANT_REP;
4968 goto elementContent;
4969 case XML_ROLE_CONTENT_ELEMENT_PLUS:
4970 quant = XML_CQUANT_PLUS;
4971 elementContent:
4972 if (dtd->in_eldecl) {
4973 ELEMENT_TYPE *el;
4974 const XML_Char *name;
4975 int nameLen;
Haibo Huang40a71912019-10-11 11:13:39 -07004976 const char *nxt
4977 = (quant == XML_CQUANT_NONE ? next : next - enc->minBytesPerChar);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004978 int myindex = nextScaffoldPart(parser);
4979 if (myindex < 0)
4980 return XML_ERROR_NO_MEMORY;
4981 dtd->scaffold[myindex].type = XML_CTYPE_NAME;
4982 dtd->scaffold[myindex].quant = quant;
4983 el = getElementType(parser, enc, s, nxt);
Haibo Huang40a71912019-10-11 11:13:39 -07004984 if (! el)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004985 return XML_ERROR_NO_MEMORY;
4986 name = el->name;
4987 dtd->scaffold[myindex].name = name;
4988 nameLen = 0;
Haibo Huang40a71912019-10-11 11:13:39 -07004989 for (; name[nameLen++];)
4990 ;
4991 dtd->contentStringLen += nameLen;
Elliott Hughes72472942018-01-10 08:36:10 -08004992 if (parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08004993 handleDefault = XML_FALSE;
4994 }
4995 break;
4996
4997 case XML_ROLE_GROUP_CLOSE:
4998 quant = XML_CQUANT_NONE;
4999 goto closeGroup;
5000 case XML_ROLE_GROUP_CLOSE_OPT:
5001 quant = XML_CQUANT_OPT;
5002 goto closeGroup;
5003 case XML_ROLE_GROUP_CLOSE_REP:
5004 quant = XML_CQUANT_REP;
5005 goto closeGroup;
5006 case XML_ROLE_GROUP_CLOSE_PLUS:
5007 quant = XML_CQUANT_PLUS;
5008 closeGroup:
5009 if (dtd->in_eldecl) {
Elliott Hughes72472942018-01-10 08:36:10 -08005010 if (parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005011 handleDefault = XML_FALSE;
5012 dtd->scaffLevel--;
5013 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
5014 if (dtd->scaffLevel == 0) {
Haibo Huang40a71912019-10-11 11:13:39 -07005015 if (! handleDefault) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005016 XML_Content *model = build_model(parser);
Haibo Huang40a71912019-10-11 11:13:39 -07005017 if (! model)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005018 return XML_ERROR_NO_MEMORY;
5019 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07005020 parser->m_elementDeclHandler(
5021 parser->m_handlerArg, parser->m_declElementType->name, model);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005022 }
5023 dtd->in_eldecl = XML_FALSE;
5024 dtd->contentStringLen = 0;
5025 }
5026 }
5027 break;
5028 /* End element declaration stuff */
5029
5030 case XML_ROLE_PI:
Haibo Huang40a71912019-10-11 11:13:39 -07005031 if (! reportProcessingInstruction(parser, enc, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005032 return XML_ERROR_NO_MEMORY;
5033 handleDefault = XML_FALSE;
5034 break;
5035 case XML_ROLE_COMMENT:
Haibo Huang40a71912019-10-11 11:13:39 -07005036 if (! reportComment(parser, enc, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005037 return XML_ERROR_NO_MEMORY;
5038 handleDefault = XML_FALSE;
5039 break;
5040 case XML_ROLE_NONE:
5041 switch (tok) {
5042 case XML_TOK_BOM:
5043 handleDefault = XML_FALSE;
5044 break;
5045 }
5046 break;
5047 case XML_ROLE_DOCTYPE_NONE:
Elliott Hughes72472942018-01-10 08:36:10 -08005048 if (parser->m_startDoctypeDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005049 handleDefault = XML_FALSE;
5050 break;
5051 case XML_ROLE_ENTITY_NONE:
Elliott Hughes72472942018-01-10 08:36:10 -08005052 if (dtd->keepProcessing && parser->m_entityDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005053 handleDefault = XML_FALSE;
5054 break;
5055 case XML_ROLE_NOTATION_NONE:
Elliott Hughes72472942018-01-10 08:36:10 -08005056 if (parser->m_notationDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005057 handleDefault = XML_FALSE;
5058 break;
5059 case XML_ROLE_ATTLIST_NONE:
Elliott Hughes72472942018-01-10 08:36:10 -08005060 if (dtd->keepProcessing && parser->m_attlistDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005061 handleDefault = XML_FALSE;
5062 break;
5063 case XML_ROLE_ELEMENT_NONE:
Elliott Hughes72472942018-01-10 08:36:10 -08005064 if (parser->m_elementDeclHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005065 handleDefault = XML_FALSE;
5066 break;
5067 } /* end of big switch */
5068
Elliott Hughes72472942018-01-10 08:36:10 -08005069 if (handleDefault && parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005070 reportDefault(parser, enc, s, next);
5071
Elliott Hughes72472942018-01-10 08:36:10 -08005072 switch (parser->m_parsingStatus.parsing) {
Elliott Hughes35e432d2012-09-09 14:23:38 -07005073 case XML_SUSPENDED:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005074 *nextPtr = next;
5075 return XML_ERROR_NONE;
5076 case XML_FINISHED:
5077 return XML_ERROR_ABORTED;
5078 default:
5079 s = next;
5080 tok = XmlPrologTok(enc, s, end, &next);
5081 }
5082 }
5083 /* not reached */
5084}
5085
5086static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07005087epilogProcessor(XML_Parser parser, const char *s, const char *end,
5088 const char **nextPtr) {
Elliott Hughes72472942018-01-10 08:36:10 -08005089 parser->m_processor = epilogProcessor;
5090 parser->m_eventPtr = s;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005091 for (;;) {
5092 const char *next = NULL;
Elliott Hughes72472942018-01-10 08:36:10 -08005093 int tok = XmlPrologTok(parser->m_encoding, s, end, &next);
5094 parser->m_eventEndPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005095 switch (tok) {
5096 /* report partial linebreak - it might be the last token */
5097 case -XML_TOK_PROLOG_S:
Elliott Hughes72472942018-01-10 08:36:10 -08005098 if (parser->m_defaultHandler) {
5099 reportDefault(parser, parser->m_encoding, s, next);
5100 if (parser->m_parsingStatus.parsing == XML_FINISHED)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005101 return XML_ERROR_ABORTED;
5102 }
5103 *nextPtr = next;
5104 return XML_ERROR_NONE;
5105 case XML_TOK_NONE:
5106 *nextPtr = s;
5107 return XML_ERROR_NONE;
5108 case XML_TOK_PROLOG_S:
Elliott Hughes72472942018-01-10 08:36:10 -08005109 if (parser->m_defaultHandler)
5110 reportDefault(parser, parser->m_encoding, s, next);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005111 break;
5112 case XML_TOK_PI:
Haibo Huang40a71912019-10-11 11:13:39 -07005113 if (! reportProcessingInstruction(parser, parser->m_encoding, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005114 return XML_ERROR_NO_MEMORY;
5115 break;
5116 case XML_TOK_COMMENT:
Haibo Huang40a71912019-10-11 11:13:39 -07005117 if (! reportComment(parser, parser->m_encoding, s, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005118 return XML_ERROR_NO_MEMORY;
5119 break;
5120 case XML_TOK_INVALID:
Elliott Hughes72472942018-01-10 08:36:10 -08005121 parser->m_eventPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005122 return XML_ERROR_INVALID_TOKEN;
5123 case XML_TOK_PARTIAL:
Haibo Huang40a71912019-10-11 11:13:39 -07005124 if (! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005125 *nextPtr = s;
5126 return XML_ERROR_NONE;
5127 }
5128 return XML_ERROR_UNCLOSED_TOKEN;
5129 case XML_TOK_PARTIAL_CHAR:
Haibo Huang40a71912019-10-11 11:13:39 -07005130 if (! parser->m_parsingStatus.finalBuffer) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005131 *nextPtr = s;
5132 return XML_ERROR_NONE;
5133 }
5134 return XML_ERROR_PARTIAL_CHAR;
5135 default:
5136 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
5137 }
Elliott Hughes72472942018-01-10 08:36:10 -08005138 parser->m_eventPtr = s = next;
5139 switch (parser->m_parsingStatus.parsing) {
Elliott Hughes35e432d2012-09-09 14:23:38 -07005140 case XML_SUSPENDED:
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005141 *nextPtr = next;
5142 return XML_ERROR_NONE;
5143 case XML_FINISHED:
5144 return XML_ERROR_ABORTED;
Haibo Huang40a71912019-10-11 11:13:39 -07005145 default:;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005146 }
5147 }
5148}
5149
5150static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07005151processInternalEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005152 const char *textStart, *textEnd;
5153 const char *next;
5154 enum XML_Error result;
5155 OPEN_INTERNAL_ENTITY *openEntity;
5156
Elliott Hughes72472942018-01-10 08:36:10 -08005157 if (parser->m_freeInternalEntities) {
5158 openEntity = parser->m_freeInternalEntities;
5159 parser->m_freeInternalEntities = openEntity->next;
Haibo Huang40a71912019-10-11 11:13:39 -07005160 } else {
5161 openEntity
5162 = (OPEN_INTERNAL_ENTITY *)MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY));
5163 if (! openEntity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005164 return XML_ERROR_NO_MEMORY;
5165 }
5166 entity->open = XML_TRUE;
5167 entity->processed = 0;
Elliott Hughes72472942018-01-10 08:36:10 -08005168 openEntity->next = parser->m_openInternalEntities;
5169 parser->m_openInternalEntities = openEntity;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005170 openEntity->entity = entity;
Elliott Hughes72472942018-01-10 08:36:10 -08005171 openEntity->startTagLevel = parser->m_tagLevel;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005172 openEntity->betweenDecl = betweenDecl;
5173 openEntity->internalEventPtr = NULL;
5174 openEntity->internalEventEndPtr = NULL;
5175 textStart = (char *)entity->textPtr;
5176 textEnd = (char *)(entity->textPtr + entity->textLen);
Elliott Hughes72472942018-01-10 08:36:10 -08005177 /* Set a safe default value in case 'next' does not get set */
5178 next = textStart;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005179
5180#ifdef XML_DTD
5181 if (entity->is_param) {
Haibo Huang40a71912019-10-11 11:13:39 -07005182 int tok
5183 = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
5184 result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
5185 tok, next, &next, XML_FALSE, XML_FALSE);
5186 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005187#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07005188 result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding,
5189 textStart, textEnd, &next, XML_FALSE);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005190
5191 if (result == XML_ERROR_NONE) {
Elliott Hughes72472942018-01-10 08:36:10 -08005192 if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005193 entity->processed = (int)(next - textStart);
Elliott Hughes72472942018-01-10 08:36:10 -08005194 parser->m_processor = internalEntityProcessor;
Haibo Huang40a71912019-10-11 11:13:39 -07005195 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005196 entity->open = XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08005197 parser->m_openInternalEntities = openEntity->next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005198 /* put openEntity back in list of free instances */
Elliott Hughes72472942018-01-10 08:36:10 -08005199 openEntity->next = parser->m_freeInternalEntities;
5200 parser->m_freeInternalEntities = openEntity;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005201 }
5202 }
5203 return result;
5204}
5205
5206static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07005207internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
5208 const char **nextPtr) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005209 ENTITY *entity;
5210 const char *textStart, *textEnd;
5211 const char *next;
5212 enum XML_Error result;
Elliott Hughes72472942018-01-10 08:36:10 -08005213 OPEN_INTERNAL_ENTITY *openEntity = parser->m_openInternalEntities;
Haibo Huang40a71912019-10-11 11:13:39 -07005214 if (! openEntity)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005215 return XML_ERROR_UNEXPECTED_STATE;
5216
5217 entity = openEntity->entity;
5218 textStart = ((char *)entity->textPtr) + entity->processed;
5219 textEnd = (char *)(entity->textPtr + entity->textLen);
Elliott Hughes72472942018-01-10 08:36:10 -08005220 /* Set a safe default value in case 'next' does not get set */
5221 next = textStart;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005222
5223#ifdef XML_DTD
5224 if (entity->is_param) {
Haibo Huang40a71912019-10-11 11:13:39 -07005225 int tok
5226 = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
5227 result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
5228 tok, next, &next, XML_FALSE, XML_TRUE);
5229 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005230#endif /* XML_DTD */
Haibo Huang40a71912019-10-11 11:13:39 -07005231 result = doContent(parser, openEntity->startTagLevel,
5232 parser->m_internalEncoding, textStart, textEnd, &next,
5233 XML_FALSE);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005234
5235 if (result != XML_ERROR_NONE)
5236 return result;
Haibo Huang40a71912019-10-11 11:13:39 -07005237 else if (textEnd != next
5238 && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005239 entity->processed = (int)(next - (char *)entity->textPtr);
5240 return result;
Haibo Huang40a71912019-10-11 11:13:39 -07005241 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005242 entity->open = XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08005243 parser->m_openInternalEntities = openEntity->next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005244 /* put openEntity back in list of free instances */
Elliott Hughes72472942018-01-10 08:36:10 -08005245 openEntity->next = parser->m_freeInternalEntities;
5246 parser->m_freeInternalEntities = openEntity;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005247 }
5248
5249#ifdef XML_DTD
5250 if (entity->is_param) {
5251 int tok;
Elliott Hughes72472942018-01-10 08:36:10 -08005252 parser->m_processor = prologProcessor;
5253 tok = XmlPrologTok(parser->m_encoding, s, end, &next);
5254 return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
Haibo Huang40a71912019-10-11 11:13:39 -07005255 (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE);
5256 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005257#endif /* XML_DTD */
5258 {
Elliott Hughes72472942018-01-10 08:36:10 -08005259 parser->m_processor = contentProcessor;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005260 /* see externalEntityContentProcessor vs contentProcessor */
Haibo Huang40a71912019-10-11 11:13:39 -07005261 return doContent(parser, parser->m_parentParser ? 1 : 0, parser->m_encoding,
5262 s, end, nextPtr,
5263 (XML_Bool)! parser->m_parsingStatus.finalBuffer);
Elliott Hughes35e432d2012-09-09 14:23:38 -07005264 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005265}
5266
5267static enum XML_Error PTRCALL
Haibo Huang40a71912019-10-11 11:13:39 -07005268errorProcessor(XML_Parser parser, const char *s, const char *end,
5269 const char **nextPtr) {
5270 UNUSED_P(s);
5271 UNUSED_P(end);
5272 UNUSED_P(nextPtr);
Elliott Hughes72472942018-01-10 08:36:10 -08005273 return parser->m_errorCode;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005274}
5275
5276static enum XML_Error
5277storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
Haibo Huang40a71912019-10-11 11:13:39 -07005278 const char *ptr, const char *end, STRING_POOL *pool) {
5279 enum XML_Error result
5280 = appendAttributeValue(parser, enc, isCdata, ptr, end, pool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005281 if (result)
5282 return result;
Haibo Huang40a71912019-10-11 11:13:39 -07005283 if (! isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005284 poolChop(pool);
Haibo Huang40a71912019-10-11 11:13:39 -07005285 if (! poolAppendChar(pool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005286 return XML_ERROR_NO_MEMORY;
5287 return XML_ERROR_NONE;
5288}
5289
5290static enum XML_Error
5291appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
Haibo Huang40a71912019-10-11 11:13:39 -07005292 const char *ptr, const char *end, STRING_POOL *pool) {
5293 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005294 for (;;) {
5295 const char *next;
5296 int tok = XmlAttributeValueTok(enc, ptr, end, &next);
5297 switch (tok) {
5298 case XML_TOK_NONE:
5299 return XML_ERROR_NONE;
5300 case XML_TOK_INVALID:
Elliott Hughes72472942018-01-10 08:36:10 -08005301 if (enc == parser->m_encoding)
5302 parser->m_eventPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005303 return XML_ERROR_INVALID_TOKEN;
5304 case XML_TOK_PARTIAL:
Elliott Hughes72472942018-01-10 08:36:10 -08005305 if (enc == parser->m_encoding)
5306 parser->m_eventPtr = ptr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005307 return XML_ERROR_INVALID_TOKEN;
Haibo Huang40a71912019-10-11 11:13:39 -07005308 case XML_TOK_CHAR_REF: {
5309 XML_Char buf[XML_ENCODE_MAX];
5310 int i;
5311 int n = XmlCharRefNumber(enc, ptr);
5312 if (n < 0) {
5313 if (enc == parser->m_encoding)
5314 parser->m_eventPtr = ptr;
5315 return XML_ERROR_BAD_CHAR_REF;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005316 }
Haibo Huang40a71912019-10-11 11:13:39 -07005317 if (! isCdata && n == 0x20 /* space */
5318 && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
5319 break;
5320 n = XmlEncode(n, (ICHAR *)buf);
5321 /* The XmlEncode() functions can never return 0 here. That
5322 * error return happens if the code point passed in is either
5323 * negative or greater than or equal to 0x110000. The
5324 * XmlCharRefNumber() functions will all return a number
5325 * strictly less than 0x110000 or a negative value if an error
5326 * occurred. The negative value is intercepted above, so
5327 * XmlEncode() is never passed a value it might return an
5328 * error for.
5329 */
5330 for (i = 0; i < n; i++) {
5331 if (! poolAppendChar(pool, buf[i]))
5332 return XML_ERROR_NO_MEMORY;
5333 }
5334 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005335 case XML_TOK_DATA_CHARS:
Haibo Huang40a71912019-10-11 11:13:39 -07005336 if (! poolAppend(pool, enc, ptr, next))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005337 return XML_ERROR_NO_MEMORY;
5338 break;
5339 case XML_TOK_TRAILING_CR:
5340 next = ptr + enc->minBytesPerChar;
5341 /* fall through */
5342 case XML_TOK_ATTRIBUTE_VALUE_S:
5343 case XML_TOK_DATA_NEWLINE:
Haibo Huang40a71912019-10-11 11:13:39 -07005344 if (! isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005345 break;
Haibo Huang40a71912019-10-11 11:13:39 -07005346 if (! poolAppendChar(pool, 0x20))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005347 return XML_ERROR_NO_MEMORY;
5348 break;
Haibo Huang40a71912019-10-11 11:13:39 -07005349 case XML_TOK_ENTITY_REF: {
5350 const XML_Char *name;
5351 ENTITY *entity;
5352 char checkEntityDecl;
5353 XML_Char ch = (XML_Char)XmlPredefinedEntityName(
5354 enc, ptr + enc->minBytesPerChar, next - enc->minBytesPerChar);
5355 if (ch) {
5356 if (! poolAppendChar(pool, ch))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005357 return XML_ERROR_NO_MEMORY;
Haibo Huang40a71912019-10-11 11:13:39 -07005358 break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005359 }
Haibo Huang40a71912019-10-11 11:13:39 -07005360 name = poolStoreString(&parser->m_temp2Pool, enc,
5361 ptr + enc->minBytesPerChar,
5362 next - enc->minBytesPerChar);
5363 if (! name)
5364 return XML_ERROR_NO_MEMORY;
5365 entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
5366 poolDiscard(&parser->m_temp2Pool);
5367 /* First, determine if a check for an existing declaration is needed;
5368 if yes, check that the entity exists, and that it is internal.
5369 */
5370 if (pool == &dtd->pool) /* are we called from prolog? */
5371 checkEntityDecl =
5372#ifdef XML_DTD
5373 parser->m_prologState.documentEntity &&
5374#endif /* XML_DTD */
5375 (dtd->standalone ? ! parser->m_openInternalEntities
5376 : ! dtd->hasParamEntityRefs);
5377 else /* if (pool == &parser->m_tempPool): we are called from content */
5378 checkEntityDecl = ! dtd->hasParamEntityRefs || dtd->standalone;
5379 if (checkEntityDecl) {
5380 if (! entity)
5381 return XML_ERROR_UNDEFINED_ENTITY;
5382 else if (! entity->is_internal)
5383 return XML_ERROR_ENTITY_DECLARED_IN_PE;
5384 } else if (! entity) {
5385 /* Cannot report skipped entity here - see comments on
5386 parser->m_skippedEntityHandler.
5387 if (parser->m_skippedEntityHandler)
5388 parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
5389 */
5390 /* Cannot call the default handler because this would be
5391 out of sync with the call to the startElementHandler.
5392 if ((pool == &parser->m_tempPool) && parser->m_defaultHandler)
5393 reportDefault(parser, enc, ptr, next);
5394 */
5395 break;
5396 }
5397 if (entity->open) {
5398 if (enc == parser->m_encoding) {
5399 /* It does not appear that this line can be executed.
5400 *
5401 * The "if (entity->open)" check catches recursive entity
5402 * definitions. In order to be called with an open
5403 * entity, it must have gone through this code before and
5404 * been through the recursive call to
5405 * appendAttributeValue() some lines below. That call
5406 * sets the local encoding ("enc") to the parser's
5407 * internal encoding (internal_utf8 or internal_utf16),
5408 * which can never be the same as the principle encoding.
5409 * It doesn't appear there is another code path that gets
5410 * here with entity->open being TRUE.
5411 *
5412 * Since it is not certain that this logic is watertight,
5413 * we keep the line and merely exclude it from coverage
5414 * tests.
5415 */
5416 parser->m_eventPtr = ptr; /* LCOV_EXCL_LINE */
5417 }
5418 return XML_ERROR_RECURSIVE_ENTITY_REF;
5419 }
5420 if (entity->notation) {
5421 if (enc == parser->m_encoding)
5422 parser->m_eventPtr = ptr;
5423 return XML_ERROR_BINARY_ENTITY_REF;
5424 }
5425 if (! entity->textPtr) {
5426 if (enc == parser->m_encoding)
5427 parser->m_eventPtr = ptr;
5428 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
5429 } else {
5430 enum XML_Error result;
5431 const XML_Char *textEnd = entity->textPtr + entity->textLen;
5432 entity->open = XML_TRUE;
5433 result = appendAttributeValue(parser, parser->m_internalEncoding,
5434 isCdata, (char *)entity->textPtr,
5435 (char *)textEnd, pool);
5436 entity->open = XML_FALSE;
5437 if (result)
5438 return result;
5439 }
5440 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005441 default:
Elliott Hughes72472942018-01-10 08:36:10 -08005442 /* The only token returned by XmlAttributeValueTok() that does
5443 * not have an explicit case here is XML_TOK_PARTIAL_CHAR.
5444 * Getting that would require an entity name to contain an
5445 * incomplete XML character (e.g. \xE2\x82); however previous
5446 * tokenisers will have already recognised and rejected such
5447 * names before XmlAttributeValueTok() gets a look-in. This
5448 * default case should be retained as a safety net, but the code
5449 * excluded from coverage tests.
5450 *
5451 * LCOV_EXCL_START
5452 */
5453 if (enc == parser->m_encoding)
5454 parser->m_eventPtr = ptr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005455 return XML_ERROR_UNEXPECTED_STATE;
Elliott Hughes72472942018-01-10 08:36:10 -08005456 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005457 }
5458 ptr = next;
5459 }
5460 /* not reached */
5461}
5462
5463static enum XML_Error
Haibo Huang40a71912019-10-11 11:13:39 -07005464storeEntityValue(XML_Parser parser, const ENCODING *enc,
5465 const char *entityTextPtr, const char *entityTextEnd) {
5466 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005467 STRING_POOL *pool = &(dtd->entityValuePool);
5468 enum XML_Error result = XML_ERROR_NONE;
5469#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08005470 int oldInEntityValue = parser->m_prologState.inEntityValue;
5471 parser->m_prologState.inEntityValue = 1;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005472#endif /* XML_DTD */
5473 /* never return Null for the value argument in EntityDeclHandler,
5474 since this would indicate an external entity; therefore we
5475 have to make sure that entityValuePool.start is not null */
Haibo Huang40a71912019-10-11 11:13:39 -07005476 if (! pool->blocks) {
5477 if (! poolGrow(pool))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005478 return XML_ERROR_NO_MEMORY;
5479 }
5480
5481 for (;;) {
5482 const char *next;
5483 int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
5484 switch (tok) {
5485 case XML_TOK_PARAM_ENTITY_REF:
5486#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08005487 if (parser->m_isParamEntity || enc != parser->m_encoding) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005488 const XML_Char *name;
5489 ENTITY *entity;
Elliott Hughes72472942018-01-10 08:36:10 -08005490 name = poolStoreString(&parser->m_tempPool, enc,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005491 entityTextPtr + enc->minBytesPerChar,
5492 next - enc->minBytesPerChar);
Haibo Huang40a71912019-10-11 11:13:39 -07005493 if (! name) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005494 result = XML_ERROR_NO_MEMORY;
5495 goto endEntityValue;
5496 }
Elliott Hughes35e432d2012-09-09 14:23:38 -07005497 entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
Elliott Hughes72472942018-01-10 08:36:10 -08005498 poolDiscard(&parser->m_tempPool);
Haibo Huang40a71912019-10-11 11:13:39 -07005499 if (! entity) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005500 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
5501 /* cannot report skipped entity here - see comments on
Elliott Hughes72472942018-01-10 08:36:10 -08005502 parser->m_skippedEntityHandler
5503 if (parser->m_skippedEntityHandler)
5504 parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005505 */
5506 dtd->keepProcessing = dtd->standalone;
5507 goto endEntityValue;
5508 }
5509 if (entity->open) {
Elliott Hughes72472942018-01-10 08:36:10 -08005510 if (enc == parser->m_encoding)
5511 parser->m_eventPtr = entityTextPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005512 result = XML_ERROR_RECURSIVE_ENTITY_REF;
5513 goto endEntityValue;
5514 }
5515 if (entity->systemId) {
Elliott Hughes72472942018-01-10 08:36:10 -08005516 if (parser->m_externalEntityRefHandler) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005517 dtd->paramEntityRead = XML_FALSE;
5518 entity->open = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07005519 if (! parser->m_externalEntityRefHandler(
5520 parser->m_externalEntityRefHandlerArg, 0, entity->base,
5521 entity->systemId, entity->publicId)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005522 entity->open = XML_FALSE;
5523 result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
5524 goto endEntityValue;
5525 }
5526 entity->open = XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07005527 if (! dtd->paramEntityRead)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005528 dtd->keepProcessing = dtd->standalone;
Haibo Huang40a71912019-10-11 11:13:39 -07005529 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005530 dtd->keepProcessing = dtd->standalone;
Haibo Huang40a71912019-10-11 11:13:39 -07005531 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005532 entity->open = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07005533 result = storeEntityValue(
5534 parser, parser->m_internalEncoding, (char *)entity->textPtr,
5535 (char *)(entity->textPtr + entity->textLen));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005536 entity->open = XML_FALSE;
5537 if (result)
5538 goto endEntityValue;
5539 }
5540 break;
5541 }
5542#endif /* XML_DTD */
5543 /* In the internal subset, PE references are not legal
5544 within markup declarations, e.g entity values in this case. */
Elliott Hughes72472942018-01-10 08:36:10 -08005545 parser->m_eventPtr = entityTextPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005546 result = XML_ERROR_PARAM_ENTITY_REF;
5547 goto endEntityValue;
5548 case XML_TOK_NONE:
5549 result = XML_ERROR_NONE;
5550 goto endEntityValue;
5551 case XML_TOK_ENTITY_REF:
5552 case XML_TOK_DATA_CHARS:
Haibo Huang40a71912019-10-11 11:13:39 -07005553 if (! poolAppend(pool, enc, entityTextPtr, next)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005554 result = XML_ERROR_NO_MEMORY;
5555 goto endEntityValue;
5556 }
5557 break;
5558 case XML_TOK_TRAILING_CR:
5559 next = entityTextPtr + enc->minBytesPerChar;
5560 /* fall through */
5561 case XML_TOK_DATA_NEWLINE:
Haibo Huang40a71912019-10-11 11:13:39 -07005562 if (pool->end == pool->ptr && ! poolGrow(pool)) {
5563 result = XML_ERROR_NO_MEMORY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005564 goto endEntityValue;
5565 }
5566 *(pool->ptr)++ = 0xA;
5567 break;
Haibo Huang40a71912019-10-11 11:13:39 -07005568 case XML_TOK_CHAR_REF: {
5569 XML_Char buf[XML_ENCODE_MAX];
5570 int i;
5571 int n = XmlCharRefNumber(enc, entityTextPtr);
5572 if (n < 0) {
5573 if (enc == parser->m_encoding)
5574 parser->m_eventPtr = entityTextPtr;
5575 result = XML_ERROR_BAD_CHAR_REF;
5576 goto endEntityValue;
5577 }
5578 n = XmlEncode(n, (ICHAR *)buf);
5579 /* The XmlEncode() functions can never return 0 here. That
5580 * error return happens if the code point passed in is either
5581 * negative or greater than or equal to 0x110000. The
5582 * XmlCharRefNumber() functions will all return a number
5583 * strictly less than 0x110000 or a negative value if an error
5584 * occurred. The negative value is intercepted above, so
5585 * XmlEncode() is never passed a value it might return an
5586 * error for.
5587 */
5588 for (i = 0; i < n; i++) {
5589 if (pool->end == pool->ptr && ! poolGrow(pool)) {
5590 result = XML_ERROR_NO_MEMORY;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005591 goto endEntityValue;
5592 }
Haibo Huang40a71912019-10-11 11:13:39 -07005593 *(pool->ptr)++ = buf[i];
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005594 }
Haibo Huang40a71912019-10-11 11:13:39 -07005595 } break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005596 case XML_TOK_PARTIAL:
Elliott Hughes72472942018-01-10 08:36:10 -08005597 if (enc == parser->m_encoding)
5598 parser->m_eventPtr = entityTextPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005599 result = XML_ERROR_INVALID_TOKEN;
5600 goto endEntityValue;
5601 case XML_TOK_INVALID:
Elliott Hughes72472942018-01-10 08:36:10 -08005602 if (enc == parser->m_encoding)
5603 parser->m_eventPtr = next;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005604 result = XML_ERROR_INVALID_TOKEN;
5605 goto endEntityValue;
5606 default:
Elliott Hughes72472942018-01-10 08:36:10 -08005607 /* This default case should be unnecessary -- all the tokens
5608 * that XmlEntityValueTok() can return have their own explicit
5609 * cases -- but should be retained for safety. We do however
5610 * exclude it from the coverage statistics.
5611 *
5612 * LCOV_EXCL_START
5613 */
5614 if (enc == parser->m_encoding)
5615 parser->m_eventPtr = entityTextPtr;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005616 result = XML_ERROR_UNEXPECTED_STATE;
5617 goto endEntityValue;
Elliott Hughes72472942018-01-10 08:36:10 -08005618 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005619 }
5620 entityTextPtr = next;
5621 }
5622endEntityValue:
5623#ifdef XML_DTD
Elliott Hughes72472942018-01-10 08:36:10 -08005624 parser->m_prologState.inEntityValue = oldInEntityValue;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005625#endif /* XML_DTD */
5626 return result;
5627}
5628
5629static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07005630normalizeLines(XML_Char *s) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005631 XML_Char *p;
5632 for (;; s++) {
5633 if (*s == XML_T('\0'))
5634 return;
5635 if (*s == 0xD)
5636 break;
5637 }
5638 p = s;
5639 do {
5640 if (*s == 0xD) {
5641 *p++ = 0xA;
5642 if (*++s == 0xA)
5643 s++;
Haibo Huang40a71912019-10-11 11:13:39 -07005644 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005645 *p++ = *s++;
5646 } while (*s);
5647 *p = XML_T('\0');
5648}
5649
5650static int
5651reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
Haibo Huang40a71912019-10-11 11:13:39 -07005652 const char *start, const char *end) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005653 const XML_Char *target;
5654 XML_Char *data;
5655 const char *tem;
Haibo Huang40a71912019-10-11 11:13:39 -07005656 if (! parser->m_processingInstructionHandler) {
Elliott Hughes72472942018-01-10 08:36:10 -08005657 if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005658 reportDefault(parser, enc, start, end);
5659 return 1;
5660 }
5661 start += enc->minBytesPerChar * 2;
5662 tem = start + XmlNameLength(enc, start);
Elliott Hughes72472942018-01-10 08:36:10 -08005663 target = poolStoreString(&parser->m_tempPool, enc, start, tem);
Haibo Huang40a71912019-10-11 11:13:39 -07005664 if (! target)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005665 return 0;
Elliott Hughes72472942018-01-10 08:36:10 -08005666 poolFinish(&parser->m_tempPool);
Haibo Huang40a71912019-10-11 11:13:39 -07005667 data = poolStoreString(&parser->m_tempPool, enc, XmlSkipS(enc, tem),
5668 end - enc->minBytesPerChar * 2);
5669 if (! data)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005670 return 0;
5671 normalizeLines(data);
Elliott Hughes72472942018-01-10 08:36:10 -08005672 parser->m_processingInstructionHandler(parser->m_handlerArg, target, data);
5673 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005674 return 1;
5675}
5676
5677static int
Haibo Huang40a71912019-10-11 11:13:39 -07005678reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
5679 const char *end) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005680 XML_Char *data;
Haibo Huang40a71912019-10-11 11:13:39 -07005681 if (! parser->m_commentHandler) {
Elliott Hughes72472942018-01-10 08:36:10 -08005682 if (parser->m_defaultHandler)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005683 reportDefault(parser, enc, start, end);
5684 return 1;
5685 }
Haibo Huang40a71912019-10-11 11:13:39 -07005686 data = poolStoreString(&parser->m_tempPool, enc,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005687 start + enc->minBytesPerChar * 4,
5688 end - enc->minBytesPerChar * 3);
Haibo Huang40a71912019-10-11 11:13:39 -07005689 if (! data)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005690 return 0;
5691 normalizeLines(data);
Elliott Hughes72472942018-01-10 08:36:10 -08005692 parser->m_commentHandler(parser->m_handlerArg, data);
5693 poolClear(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005694 return 1;
5695}
5696
5697static void
Haibo Huang40a71912019-10-11 11:13:39 -07005698reportDefault(XML_Parser parser, const ENCODING *enc, const char *s,
5699 const char *end) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005700 if (MUST_CONVERT(enc, s)) {
Paul Duffin4bf8f122016-05-13 12:35:25 +01005701 enum XML_Convert_Result convert_res;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005702 const char **eventPP;
5703 const char **eventEndPP;
Elliott Hughes72472942018-01-10 08:36:10 -08005704 if (enc == parser->m_encoding) {
5705 eventPP = &parser->m_eventPtr;
5706 eventEndPP = &parser->m_eventEndPtr;
Haibo Huang40a71912019-10-11 11:13:39 -07005707 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08005708 /* To get here, two things must be true; the parser must be
5709 * using a character encoding that is not the same as the
5710 * encoding passed in, and the encoding passed in must need
5711 * conversion to the internal format (UTF-8 unless XML_UNICODE
5712 * is defined). The only occasions on which the encoding passed
5713 * in is not the same as the parser's encoding are when it is
5714 * the internal encoding (e.g. a previously defined parameter
5715 * entity, already converted to internal format). This by
5716 * definition doesn't need conversion, so the whole branch never
5717 * gets executed.
5718 *
5719 * For safety's sake we don't delete these lines and merely
5720 * exclude them from coverage statistics.
5721 *
5722 * LCOV_EXCL_START
5723 */
5724 eventPP = &(parser->m_openInternalEntities->internalEventPtr);
5725 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
5726 /* LCOV_EXCL_STOP */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005727 }
5728 do {
Elliott Hughes72472942018-01-10 08:36:10 -08005729 ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
Haibo Huang40a71912019-10-11 11:13:39 -07005730 convert_res
5731 = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005732 *eventEndPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07005733 parser->m_defaultHandler(parser->m_handlerArg, parser->m_dataBuf,
5734 (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005735 *eventPP = s;
Haibo Huang40a71912019-10-11 11:13:39 -07005736 } while ((convert_res != XML_CONVERT_COMPLETED)
5737 && (convert_res != XML_CONVERT_INPUT_INCOMPLETE));
5738 } else
5739 parser->m_defaultHandler(parser->m_handlerArg, (XML_Char *)s,
5740 (int)((XML_Char *)end - (XML_Char *)s));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005741}
5742
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005743static int
5744defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
Haibo Huang40a71912019-10-11 11:13:39 -07005745 XML_Bool isId, const XML_Char *value, XML_Parser parser) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005746 DEFAULT_ATTRIBUTE *att;
5747 if (value || isId) {
5748 /* The handling of default attributes gets messed up if we have
5749 a default which duplicates a non-default. */
5750 int i;
5751 for (i = 0; i < type->nDefaultAtts; i++)
5752 if (attId == type->defaultAtts[i].id)
5753 return 1;
Haibo Huang40a71912019-10-11 11:13:39 -07005754 if (isId && ! type->idAtt && ! attId->xmlns)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005755 type->idAtt = attId;
5756 }
5757 if (type->nDefaultAtts == type->allocDefaultAtts) {
5758 if (type->allocDefaultAtts == 0) {
5759 type->allocDefaultAtts = 8;
Haibo Huang40a71912019-10-11 11:13:39 -07005760 type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(
5761 parser, type->allocDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
5762 if (! type->defaultAtts) {
Elliott Hughes72472942018-01-10 08:36:10 -08005763 type->allocDefaultAtts = 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005764 return 0;
Elliott Hughes72472942018-01-10 08:36:10 -08005765 }
Haibo Huang40a71912019-10-11 11:13:39 -07005766 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005767 DEFAULT_ATTRIBUTE *temp;
5768 int count = type->allocDefaultAtts * 2;
Haibo Huang40a71912019-10-11 11:13:39 -07005769 temp = (DEFAULT_ATTRIBUTE *)REALLOC(parser, type->defaultAtts,
5770 (count * sizeof(DEFAULT_ATTRIBUTE)));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005771 if (temp == NULL)
5772 return 0;
5773 type->allocDefaultAtts = count;
5774 type->defaultAtts = temp;
5775 }
5776 }
5777 att = type->defaultAtts + type->nDefaultAtts;
5778 att->id = attId;
5779 att->value = value;
5780 att->isCdata = isCdata;
Haibo Huang40a71912019-10-11 11:13:39 -07005781 if (! isCdata)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005782 attId->maybeTokenized = XML_TRUE;
5783 type->nDefaultAtts += 1;
5784 return 1;
5785}
5786
5787static int
Haibo Huang40a71912019-10-11 11:13:39 -07005788setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType) {
5789 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005790 const XML_Char *name;
5791 for (name = elementType->name; *name; name++) {
Elliott Hughesd07d5a72009-09-25 16:04:37 -07005792 if (*name == XML_T(ASCII_COLON)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005793 PREFIX *prefix;
5794 const XML_Char *s;
5795 for (s = elementType->name; s != name; s++) {
Haibo Huang40a71912019-10-11 11:13:39 -07005796 if (! poolAppendChar(&dtd->pool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005797 return 0;
5798 }
Haibo Huang40a71912019-10-11 11:13:39 -07005799 if (! poolAppendChar(&dtd->pool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005800 return 0;
Elliott Hughes35e432d2012-09-09 14:23:38 -07005801 prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005802 sizeof(PREFIX));
Haibo Huang40a71912019-10-11 11:13:39 -07005803 if (! prefix)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005804 return 0;
5805 if (prefix->name == poolStart(&dtd->pool))
5806 poolFinish(&dtd->pool);
5807 else
5808 poolDiscard(&dtd->pool);
5809 elementType->prefix = prefix;
Haibo Huangfd5e81a2019-06-20 12:09:36 -07005810 break;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005811 }
5812 }
5813 return 1;
5814}
5815
5816static ATTRIBUTE_ID *
Haibo Huang40a71912019-10-11 11:13:39 -07005817getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
5818 const char *end) {
5819 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005820 ATTRIBUTE_ID *id;
5821 const XML_Char *name;
Haibo Huang40a71912019-10-11 11:13:39 -07005822 if (! poolAppendChar(&dtd->pool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005823 return NULL;
5824 name = poolStoreString(&dtd->pool, enc, start, end);
Haibo Huang40a71912019-10-11 11:13:39 -07005825 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005826 return NULL;
5827 /* skip quotation mark - its storage will be re-used (like in name[-1]) */
5828 ++name;
Haibo Huang40a71912019-10-11 11:13:39 -07005829 id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name,
5830 sizeof(ATTRIBUTE_ID));
5831 if (! id)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005832 return NULL;
5833 if (id->name != name)
5834 poolDiscard(&dtd->pool);
5835 else {
5836 poolFinish(&dtd->pool);
Haibo Huang40a71912019-10-11 11:13:39 -07005837 if (! parser->m_ns)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005838 ;
Haibo Huang40a71912019-10-11 11:13:39 -07005839 else if (name[0] == XML_T(ASCII_x) && name[1] == XML_T(ASCII_m)
5840 && name[2] == XML_T(ASCII_l) && name[3] == XML_T(ASCII_n)
5841 && name[4] == XML_T(ASCII_s)
5842 && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005843 if (name[5] == XML_T('\0'))
5844 id->prefix = &dtd->defaultPrefix;
5845 else
Haibo Huang40a71912019-10-11 11:13:39 -07005846 id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6,
5847 sizeof(PREFIX));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005848 id->xmlns = XML_TRUE;
Haibo Huang40a71912019-10-11 11:13:39 -07005849 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005850 int i;
5851 for (i = 0; name[i]; i++) {
5852 /* attributes without prefix are *not* in the default namespace */
Elliott Hughesd07d5a72009-09-25 16:04:37 -07005853 if (name[i] == XML_T(ASCII_COLON)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005854 int j;
5855 for (j = 0; j < i; j++) {
Haibo Huang40a71912019-10-11 11:13:39 -07005856 if (! poolAppendChar(&dtd->pool, name[j]))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005857 return NULL;
5858 }
Haibo Huang40a71912019-10-11 11:13:39 -07005859 if (! poolAppendChar(&dtd->pool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005860 return NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07005861 id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes,
5862 poolStart(&dtd->pool), sizeof(PREFIX));
5863 if (! id->prefix)
Paul Duffinc05e0322016-05-04 10:42:31 +01005864 return NULL;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005865 if (id->prefix->name == poolStart(&dtd->pool))
5866 poolFinish(&dtd->pool);
5867 else
5868 poolDiscard(&dtd->pool);
5869 break;
5870 }
5871 }
5872 }
5873 }
5874 return id;
5875}
5876
Elliott Hughesd07d5a72009-09-25 16:04:37 -07005877#define CONTEXT_SEP XML_T(ASCII_FF)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005878
5879static const XML_Char *
Haibo Huang40a71912019-10-11 11:13:39 -07005880getContext(XML_Parser parser) {
5881 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005882 HASH_TABLE_ITER iter;
5883 XML_Bool needSep = XML_FALSE;
5884
5885 if (dtd->defaultPrefix.binding) {
5886 int i;
5887 int len;
Haibo Huang40a71912019-10-11 11:13:39 -07005888 if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS)))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005889 return NULL;
5890 len = dtd->defaultPrefix.binding->uriLen;
Elliott Hughes72472942018-01-10 08:36:10 -08005891 if (parser->m_namespaceSeparator)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005892 len--;
Elliott Hughes72472942018-01-10 08:36:10 -08005893 for (i = 0; i < len; i++) {
Haibo Huang40a71912019-10-11 11:13:39 -07005894 if (! poolAppendChar(&parser->m_tempPool,
5895 dtd->defaultPrefix.binding->uri[i])) {
Elliott Hughes72472942018-01-10 08:36:10 -08005896 /* Because of memory caching, I don't believe this line can be
5897 * executed.
5898 *
5899 * This is part of a loop copying the default prefix binding
5900 * URI into the parser's temporary string pool. Previously,
5901 * that URI was copied into the same string pool, with a
5902 * terminating NUL character, as part of setContext(). When
5903 * the pool was cleared, that leaves a block definitely big
5904 * enough to hold the URI on the free block list of the pool.
5905 * The URI copy in getContext() therefore cannot run out of
5906 * memory.
5907 *
5908 * If the pool is used between the setContext() and
5909 * getContext() calls, the worst it can do is leave a bigger
5910 * block on the front of the free list. Given that this is
5911 * all somewhat inobvious and program logic can be changed, we
5912 * don't delete the line but we do exclude it from the test
5913 * coverage statistics.
5914 */
5915 return NULL; /* LCOV_EXCL_LINE */
5916 }
5917 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005918 needSep = XML_TRUE;
5919 }
5920
5921 hashTableIterInit(&iter, &(dtd->prefixes));
5922 for (;;) {
5923 int i;
5924 int len;
5925 const XML_Char *s;
5926 PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07005927 if (! prefix)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005928 break;
Haibo Huang40a71912019-10-11 11:13:39 -07005929 if (! prefix->binding) {
Elliott Hughes72472942018-01-10 08:36:10 -08005930 /* This test appears to be (justifiable) paranoia. There does
5931 * not seem to be a way of injecting a prefix without a binding
5932 * that doesn't get errored long before this function is called.
5933 * The test should remain for safety's sake, so we instead
5934 * exclude the following line from the coverage statistics.
5935 */
5936 continue; /* LCOV_EXCL_LINE */
5937 }
Haibo Huang40a71912019-10-11 11:13:39 -07005938 if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005939 return NULL;
5940 for (s = prefix->name; *s; s++)
Haibo Huang40a71912019-10-11 11:13:39 -07005941 if (! poolAppendChar(&parser->m_tempPool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005942 return NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07005943 if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS)))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005944 return NULL;
5945 len = prefix->binding->uriLen;
Elliott Hughes72472942018-01-10 08:36:10 -08005946 if (parser->m_namespaceSeparator)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005947 len--;
5948 for (i = 0; i < len; i++)
Haibo Huang40a71912019-10-11 11:13:39 -07005949 if (! poolAppendChar(&parser->m_tempPool, prefix->binding->uri[i]))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005950 return NULL;
5951 needSep = XML_TRUE;
5952 }
5953
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005954 hashTableIterInit(&iter, &(dtd->generalEntities));
5955 for (;;) {
5956 const XML_Char *s;
5957 ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07005958 if (! e)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005959 break;
Haibo Huang40a71912019-10-11 11:13:39 -07005960 if (! e->open)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005961 continue;
Haibo Huang40a71912019-10-11 11:13:39 -07005962 if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005963 return NULL;
5964 for (s = e->name; *s; s++)
Haibo Huang40a71912019-10-11 11:13:39 -07005965 if (! poolAppendChar(&parser->m_tempPool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005966 return 0;
5967 needSep = XML_TRUE;
5968 }
5969
Haibo Huang40a71912019-10-11 11:13:39 -07005970 if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005971 return NULL;
Elliott Hughes72472942018-01-10 08:36:10 -08005972 return parser->m_tempPool.start;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005973}
5974
5975static XML_Bool
Haibo Huang40a71912019-10-11 11:13:39 -07005976setContext(XML_Parser parser, const XML_Char *context) {
5977 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005978 const XML_Char *s = context;
5979
5980 while (*context != XML_T('\0')) {
5981 if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
5982 ENTITY *e;
Haibo Huang40a71912019-10-11 11:13:39 -07005983 if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005984 return XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07005985 e = (ENTITY *)lookup(parser, &dtd->generalEntities,
5986 poolStart(&parser->m_tempPool), 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005987 if (e)
5988 e->open = XML_TRUE;
5989 if (*s != XML_T('\0'))
5990 s++;
5991 context = s;
Elliott Hughes72472942018-01-10 08:36:10 -08005992 poolDiscard(&parser->m_tempPool);
Haibo Huang40a71912019-10-11 11:13:39 -07005993 } else if (*s == XML_T(ASCII_EQUALS)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005994 PREFIX *prefix;
Elliott Hughes72472942018-01-10 08:36:10 -08005995 if (poolLength(&parser->m_tempPool) == 0)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005996 prefix = &dtd->defaultPrefix;
5997 else {
Haibo Huang40a71912019-10-11 11:13:39 -07005998 if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08005999 return XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07006000 prefix
6001 = (PREFIX *)lookup(parser, &dtd->prefixes,
6002 poolStart(&parser->m_tempPool), sizeof(PREFIX));
6003 if (! prefix)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006004 return XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08006005 if (prefix->name == poolStart(&parser->m_tempPool)) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006006 prefix->name = poolCopyString(&dtd->pool, prefix->name);
Haibo Huang40a71912019-10-11 11:13:39 -07006007 if (! prefix->name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006008 return XML_FALSE;
6009 }
Elliott Hughes72472942018-01-10 08:36:10 -08006010 poolDiscard(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006011 }
Haibo Huang40a71912019-10-11 11:13:39 -07006012 for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0');
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006013 context++)
Haibo Huang40a71912019-10-11 11:13:39 -07006014 if (! poolAppendChar(&parser->m_tempPool, *context))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006015 return XML_FALSE;
Haibo Huang40a71912019-10-11 11:13:39 -07006016 if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006017 return XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08006018 if (addBinding(parser, prefix, NULL, poolStart(&parser->m_tempPool),
Haibo Huang40a71912019-10-11 11:13:39 -07006019 &parser->m_inheritedBindings)
6020 != XML_ERROR_NONE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006021 return XML_FALSE;
Elliott Hughes72472942018-01-10 08:36:10 -08006022 poolDiscard(&parser->m_tempPool);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006023 if (*context != XML_T('\0'))
6024 ++context;
6025 s = context;
Haibo Huang40a71912019-10-11 11:13:39 -07006026 } else {
6027 if (! poolAppendChar(&parser->m_tempPool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006028 return XML_FALSE;
6029 s++;
6030 }
6031 }
6032 return XML_TRUE;
6033}
6034
6035static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006036normalizePublicId(XML_Char *publicId) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006037 XML_Char *p = publicId;
6038 XML_Char *s;
6039 for (s = publicId; *s; s++) {
6040 switch (*s) {
6041 case 0x20:
6042 case 0xD:
6043 case 0xA:
6044 if (p != publicId && p[-1] != 0x20)
6045 *p++ = 0x20;
6046 break;
6047 default:
6048 *p++ = *s;
6049 }
6050 }
6051 if (p != publicId && p[-1] == 0x20)
6052 --p;
6053 *p = XML_T('\0');
6054}
6055
6056static DTD *
Haibo Huang40a71912019-10-11 11:13:39 -07006057dtdCreate(const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006058 DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
6059 if (p == NULL)
6060 return p;
6061 poolInit(&(p->pool), ms);
6062 poolInit(&(p->entityValuePool), ms);
6063 hashTableInit(&(p->generalEntities), ms);
6064 hashTableInit(&(p->elementTypes), ms);
6065 hashTableInit(&(p->attributeIds), ms);
6066 hashTableInit(&(p->prefixes), ms);
6067#ifdef XML_DTD
6068 p->paramEntityRead = XML_FALSE;
6069 hashTableInit(&(p->paramEntities), ms);
6070#endif /* XML_DTD */
6071 p->defaultPrefix.name = NULL;
6072 p->defaultPrefix.binding = NULL;
6073
6074 p->in_eldecl = XML_FALSE;
6075 p->scaffIndex = NULL;
6076 p->scaffold = NULL;
6077 p->scaffLevel = 0;
6078 p->scaffSize = 0;
6079 p->scaffCount = 0;
6080 p->contentStringLen = 0;
6081
6082 p->keepProcessing = XML_TRUE;
6083 p->hasParamEntityRefs = XML_FALSE;
6084 p->standalone = XML_FALSE;
6085 return p;
6086}
6087
6088static void
Haibo Huang40a71912019-10-11 11:13:39 -07006089dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006090 HASH_TABLE_ITER iter;
6091 hashTableIterInit(&iter, &(p->elementTypes));
6092 for (;;) {
6093 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006094 if (! e)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006095 break;
6096 if (e->allocDefaultAtts != 0)
6097 ms->free_fcn(e->defaultAtts);
6098 }
6099 hashTableClear(&(p->generalEntities));
6100#ifdef XML_DTD
6101 p->paramEntityRead = XML_FALSE;
6102 hashTableClear(&(p->paramEntities));
6103#endif /* XML_DTD */
6104 hashTableClear(&(p->elementTypes));
6105 hashTableClear(&(p->attributeIds));
6106 hashTableClear(&(p->prefixes));
6107 poolClear(&(p->pool));
6108 poolClear(&(p->entityValuePool));
6109 p->defaultPrefix.name = NULL;
6110 p->defaultPrefix.binding = NULL;
6111
6112 p->in_eldecl = XML_FALSE;
6113
6114 ms->free_fcn(p->scaffIndex);
6115 p->scaffIndex = NULL;
6116 ms->free_fcn(p->scaffold);
6117 p->scaffold = NULL;
6118
6119 p->scaffLevel = 0;
6120 p->scaffSize = 0;
6121 p->scaffCount = 0;
6122 p->contentStringLen = 0;
6123
6124 p->keepProcessing = XML_TRUE;
6125 p->hasParamEntityRefs = XML_FALSE;
6126 p->standalone = XML_FALSE;
6127}
6128
6129static void
Haibo Huang40a71912019-10-11 11:13:39 -07006130dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006131 HASH_TABLE_ITER iter;
6132 hashTableIterInit(&iter, &(p->elementTypes));
6133 for (;;) {
6134 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006135 if (! e)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006136 break;
6137 if (e->allocDefaultAtts != 0)
6138 ms->free_fcn(e->defaultAtts);
6139 }
6140 hashTableDestroy(&(p->generalEntities));
6141#ifdef XML_DTD
6142 hashTableDestroy(&(p->paramEntities));
6143#endif /* XML_DTD */
6144 hashTableDestroy(&(p->elementTypes));
6145 hashTableDestroy(&(p->attributeIds));
6146 hashTableDestroy(&(p->prefixes));
6147 poolDestroy(&(p->pool));
6148 poolDestroy(&(p->entityValuePool));
6149 if (isDocEntity) {
6150 ms->free_fcn(p->scaffIndex);
6151 ms->free_fcn(p->scaffold);
6152 }
6153 ms->free_fcn(p);
6154}
6155
6156/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
6157 The new DTD has already been initialized.
6158*/
6159static int
Haibo Huang40a71912019-10-11 11:13:39 -07006160dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
6161 const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006162 HASH_TABLE_ITER iter;
6163
6164 /* Copy the prefix table. */
6165
6166 hashTableIterInit(&iter, &(oldDtd->prefixes));
6167 for (;;) {
6168 const XML_Char *name;
6169 const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006170 if (! oldP)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006171 break;
6172 name = poolCopyString(&(newDtd->pool), oldP->name);
Haibo Huang40a71912019-10-11 11:13:39 -07006173 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006174 return 0;
Haibo Huang40a71912019-10-11 11:13:39 -07006175 if (! lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX)))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006176 return 0;
6177 }
6178
6179 hashTableIterInit(&iter, &(oldDtd->attributeIds));
6180
6181 /* Copy the attribute id table. */
6182
6183 for (;;) {
6184 ATTRIBUTE_ID *newA;
6185 const XML_Char *name;
6186 const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
6187
Haibo Huang40a71912019-10-11 11:13:39 -07006188 if (! oldA)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006189 break;
6190 /* Remember to allocate the scratch byte before the name. */
Haibo Huang40a71912019-10-11 11:13:39 -07006191 if (! poolAppendChar(&(newDtd->pool), XML_T('\0')))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006192 return 0;
6193 name = poolCopyString(&(newDtd->pool), oldA->name);
Haibo Huang40a71912019-10-11 11:13:39 -07006194 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006195 return 0;
6196 ++name;
Elliott Hughes35e432d2012-09-09 14:23:38 -07006197 newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006198 sizeof(ATTRIBUTE_ID));
Haibo Huang40a71912019-10-11 11:13:39 -07006199 if (! newA)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006200 return 0;
6201 newA->maybeTokenized = oldA->maybeTokenized;
6202 if (oldA->prefix) {
6203 newA->xmlns = oldA->xmlns;
6204 if (oldA->prefix == &oldDtd->defaultPrefix)
6205 newA->prefix = &newDtd->defaultPrefix;
6206 else
Elliott Hughes35e432d2012-09-09 14:23:38 -07006207 newA->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006208 oldA->prefix->name, 0);
6209 }
6210 }
6211
6212 /* Copy the element type table. */
6213
6214 hashTableIterInit(&iter, &(oldDtd->elementTypes));
6215
6216 for (;;) {
6217 int i;
6218 ELEMENT_TYPE *newE;
6219 const XML_Char *name;
6220 const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006221 if (! oldE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006222 break;
6223 name = poolCopyString(&(newDtd->pool), oldE->name);
Haibo Huang40a71912019-10-11 11:13:39 -07006224 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006225 return 0;
Elliott Hughes35e432d2012-09-09 14:23:38 -07006226 newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name,
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006227 sizeof(ELEMENT_TYPE));
Haibo Huang40a71912019-10-11 11:13:39 -07006228 if (! newE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006229 return 0;
6230 if (oldE->nDefaultAtts) {
Haibo Huang40a71912019-10-11 11:13:39 -07006231 newE->defaultAtts = (DEFAULT_ATTRIBUTE *)ms->malloc_fcn(
6232 oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
6233 if (! newE->defaultAtts) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006234 return 0;
6235 }
6236 }
6237 if (oldE->idAtt)
Haibo Huang40a71912019-10-11 11:13:39 -07006238 newE->idAtt = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds),
6239 oldE->idAtt->name, 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006240 newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
6241 if (oldE->prefix)
Elliott Hughes35e432d2012-09-09 14:23:38 -07006242 newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006243 oldE->prefix->name, 0);
6244 for (i = 0; i < newE->nDefaultAtts; i++) {
Haibo Huang40a71912019-10-11 11:13:39 -07006245 newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup(
6246 oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006247 newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
6248 if (oldE->defaultAtts[i].value) {
6249 newE->defaultAtts[i].value
6250 = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
Haibo Huang40a71912019-10-11 11:13:39 -07006251 if (! newE->defaultAtts[i].value)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006252 return 0;
Haibo Huang40a71912019-10-11 11:13:39 -07006253 } else
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006254 newE->defaultAtts[i].value = NULL;
6255 }
6256 }
6257
6258 /* Copy the entity tables. */
Haibo Huang40a71912019-10-11 11:13:39 -07006259 if (! copyEntityTable(oldParser, &(newDtd->generalEntities), &(newDtd->pool),
6260 &(oldDtd->generalEntities)))
6261 return 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006262
6263#ifdef XML_DTD
Haibo Huang40a71912019-10-11 11:13:39 -07006264 if (! copyEntityTable(oldParser, &(newDtd->paramEntities), &(newDtd->pool),
6265 &(oldDtd->paramEntities)))
6266 return 0;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006267 newDtd->paramEntityRead = oldDtd->paramEntityRead;
6268#endif /* XML_DTD */
6269
6270 newDtd->keepProcessing = oldDtd->keepProcessing;
6271 newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
6272 newDtd->standalone = oldDtd->standalone;
6273
6274 /* Don't want deep copying for scaffolding */
6275 newDtd->in_eldecl = oldDtd->in_eldecl;
6276 newDtd->scaffold = oldDtd->scaffold;
6277 newDtd->contentStringLen = oldDtd->contentStringLen;
6278 newDtd->scaffSize = oldDtd->scaffSize;
6279 newDtd->scaffLevel = oldDtd->scaffLevel;
6280 newDtd->scaffIndex = oldDtd->scaffIndex;
6281
6282 return 1;
Haibo Huang40a71912019-10-11 11:13:39 -07006283} /* End dtdCopy */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006284
6285static int
Haibo Huang40a71912019-10-11 11:13:39 -07006286copyEntityTable(XML_Parser oldParser, HASH_TABLE *newTable,
6287 STRING_POOL *newPool, const HASH_TABLE *oldTable) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006288 HASH_TABLE_ITER iter;
6289 const XML_Char *cachedOldBase = NULL;
6290 const XML_Char *cachedNewBase = NULL;
6291
6292 hashTableIterInit(&iter, oldTable);
6293
6294 for (;;) {
6295 ENTITY *newE;
6296 const XML_Char *name;
6297 const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
Haibo Huang40a71912019-10-11 11:13:39 -07006298 if (! oldE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006299 break;
6300 name = poolCopyString(newPool, oldE->name);
Haibo Huang40a71912019-10-11 11:13:39 -07006301 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006302 return 0;
Elliott Hughes35e432d2012-09-09 14:23:38 -07006303 newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY));
Haibo Huang40a71912019-10-11 11:13:39 -07006304 if (! newE)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006305 return 0;
6306 if (oldE->systemId) {
6307 const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
Haibo Huang40a71912019-10-11 11:13:39 -07006308 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006309 return 0;
6310 newE->systemId = tem;
6311 if (oldE->base) {
6312 if (oldE->base == cachedOldBase)
6313 newE->base = cachedNewBase;
6314 else {
6315 cachedOldBase = oldE->base;
6316 tem = poolCopyString(newPool, cachedOldBase);
Haibo Huang40a71912019-10-11 11:13:39 -07006317 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006318 return 0;
6319 cachedNewBase = newE->base = tem;
6320 }
6321 }
6322 if (oldE->publicId) {
6323 tem = poolCopyString(newPool, oldE->publicId);
Haibo Huang40a71912019-10-11 11:13:39 -07006324 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006325 return 0;
6326 newE->publicId = tem;
6327 }
Haibo Huang40a71912019-10-11 11:13:39 -07006328 } else {
6329 const XML_Char *tem
6330 = poolCopyStringN(newPool, oldE->textPtr, oldE->textLen);
6331 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006332 return 0;
6333 newE->textPtr = tem;
6334 newE->textLen = oldE->textLen;
6335 }
6336 if (oldE->notation) {
6337 const XML_Char *tem = poolCopyString(newPool, oldE->notation);
Haibo Huang40a71912019-10-11 11:13:39 -07006338 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006339 return 0;
6340 newE->notation = tem;
6341 }
6342 newE->is_param = oldE->is_param;
6343 newE->is_internal = oldE->is_internal;
6344 }
6345 return 1;
6346}
6347
6348#define INIT_POWER 6
6349
6350static XML_Bool FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006351keyeq(KEY s1, KEY s2) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006352 for (; *s1 == *s2; s1++, s2++)
6353 if (*s1 == 0)
6354 return XML_TRUE;
6355 return XML_FALSE;
6356}
6357
Elliott Hughes72472942018-01-10 08:36:10 -08006358static size_t
Haibo Huang40a71912019-10-11 11:13:39 -07006359keylen(KEY s) {
Elliott Hughes72472942018-01-10 08:36:10 -08006360 size_t len = 0;
Haibo Huang40a71912019-10-11 11:13:39 -07006361 for (; *s; s++, len++)
6362 ;
Elliott Hughes72472942018-01-10 08:36:10 -08006363 return len;
6364}
6365
6366static void
Haibo Huang40a71912019-10-11 11:13:39 -07006367copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key) {
Elliott Hughes72472942018-01-10 08:36:10 -08006368 key->k[0] = 0;
6369 key->k[1] = get_hash_secret_salt(parser);
6370}
6371
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006372static unsigned long FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006373hash(XML_Parser parser, KEY s) {
Elliott Hughes72472942018-01-10 08:36:10 -08006374 struct siphash state;
6375 struct sipkey key;
Elliott Hughes72472942018-01-10 08:36:10 -08006376 (void)sip24_valid;
6377 copy_salt_to_sipkey(parser, &key);
6378 sip24_init(&state, &key);
6379 sip24_update(&state, s, keylen(s) * sizeof(XML_Char));
6380 return (unsigned long)sip24_final(&state);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006381}
6382
6383static NAMED *
Haibo Huang40a71912019-10-11 11:13:39 -07006384lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006385 size_t i;
6386 if (table->size == 0) {
6387 size_t tsize;
Haibo Huang40a71912019-10-11 11:13:39 -07006388 if (! createSize)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006389 return NULL;
6390 table->power = INIT_POWER;
6391 /* table->size is a power of 2 */
6392 table->size = (size_t)1 << INIT_POWER;
6393 tsize = table->size * sizeof(NAMED *);
6394 table->v = (NAMED **)table->mem->malloc_fcn(tsize);
Haibo Huang40a71912019-10-11 11:13:39 -07006395 if (! table->v) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006396 table->size = 0;
6397 return NULL;
6398 }
6399 memset(table->v, 0, tsize);
Elliott Hughes35e432d2012-09-09 14:23:38 -07006400 i = hash(parser, name) & ((unsigned long)table->size - 1);
Haibo Huang40a71912019-10-11 11:13:39 -07006401 } else {
Elliott Hughes35e432d2012-09-09 14:23:38 -07006402 unsigned long h = hash(parser, name);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006403 unsigned long mask = (unsigned long)table->size - 1;
6404 unsigned char step = 0;
6405 i = h & mask;
6406 while (table->v[i]) {
6407 if (keyeq(name, table->v[i]->name))
6408 return table->v[i];
Haibo Huang40a71912019-10-11 11:13:39 -07006409 if (! step)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006410 step = PROBE_STEP(h, mask, table->power);
6411 i < step ? (i += table->size - step) : (i -= step);
6412 }
Haibo Huang40a71912019-10-11 11:13:39 -07006413 if (! createSize)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006414 return NULL;
6415
6416 /* check for overflow (table is half full) */
6417 if (table->used >> (table->power - 1)) {
6418 unsigned char newPower = table->power + 1;
6419 size_t newSize = (size_t)1 << newPower;
6420 unsigned long newMask = (unsigned long)newSize - 1;
6421 size_t tsize = newSize * sizeof(NAMED *);
6422 NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
Haibo Huang40a71912019-10-11 11:13:39 -07006423 if (! newV)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006424 return NULL;
6425 memset(newV, 0, tsize);
6426 for (i = 0; i < table->size; i++)
6427 if (table->v[i]) {
Elliott Hughes35e432d2012-09-09 14:23:38 -07006428 unsigned long newHash = hash(parser, table->v[i]->name);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006429 size_t j = newHash & newMask;
6430 step = 0;
6431 while (newV[j]) {
Haibo Huang40a71912019-10-11 11:13:39 -07006432 if (! step)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006433 step = PROBE_STEP(newHash, newMask, newPower);
6434 j < step ? (j += newSize - step) : (j -= step);
6435 }
6436 newV[j] = table->v[i];
6437 }
6438 table->mem->free_fcn(table->v);
6439 table->v = newV;
6440 table->power = newPower;
6441 table->size = newSize;
6442 i = h & newMask;
6443 step = 0;
6444 while (table->v[i]) {
Haibo Huang40a71912019-10-11 11:13:39 -07006445 if (! step)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006446 step = PROBE_STEP(h, newMask, newPower);
6447 i < step ? (i += newSize - step) : (i -= step);
6448 }
6449 }
6450 }
6451 table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
Haibo Huang40a71912019-10-11 11:13:39 -07006452 if (! table->v[i])
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006453 return NULL;
6454 memset(table->v[i], 0, createSize);
6455 table->v[i]->name = name;
6456 (table->used)++;
6457 return table->v[i];
6458}
6459
6460static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006461hashTableClear(HASH_TABLE *table) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006462 size_t i;
6463 for (i = 0; i < table->size; i++) {
6464 table->mem->free_fcn(table->v[i]);
6465 table->v[i] = NULL;
6466 }
6467 table->used = 0;
6468}
6469
6470static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006471hashTableDestroy(HASH_TABLE *table) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006472 size_t i;
6473 for (i = 0; i < table->size; i++)
6474 table->mem->free_fcn(table->v[i]);
6475 table->mem->free_fcn(table->v);
6476}
6477
6478static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006479hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006480 p->power = 0;
6481 p->size = 0;
6482 p->used = 0;
6483 p->v = NULL;
6484 p->mem = ms;
6485}
6486
6487static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006488hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006489 iter->p = table->v;
6490 iter->end = iter->p + table->size;
6491}
6492
Haibo Huang40a71912019-10-11 11:13:39 -07006493static NAMED *FASTCALL
6494hashTableIterNext(HASH_TABLE_ITER *iter) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006495 while (iter->p != iter->end) {
6496 NAMED *tem = *(iter->p)++;
6497 if (tem)
6498 return tem;
6499 }
6500 return NULL;
6501}
6502
6503static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006504poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006505 pool->blocks = NULL;
6506 pool->freeBlocks = NULL;
6507 pool->start = NULL;
6508 pool->ptr = NULL;
6509 pool->end = NULL;
6510 pool->mem = ms;
6511}
6512
6513static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006514poolClear(STRING_POOL *pool) {
6515 if (! pool->freeBlocks)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006516 pool->freeBlocks = pool->blocks;
6517 else {
6518 BLOCK *p = pool->blocks;
6519 while (p) {
6520 BLOCK *tem = p->next;
6521 p->next = pool->freeBlocks;
6522 pool->freeBlocks = p;
6523 p = tem;
6524 }
6525 }
6526 pool->blocks = NULL;
6527 pool->start = NULL;
6528 pool->ptr = NULL;
6529 pool->end = NULL;
6530}
6531
6532static void FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006533poolDestroy(STRING_POOL *pool) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006534 BLOCK *p = pool->blocks;
6535 while (p) {
6536 BLOCK *tem = p->next;
6537 pool->mem->free_fcn(p);
6538 p = tem;
6539 }
6540 p = pool->freeBlocks;
6541 while (p) {
6542 BLOCK *tem = p->next;
6543 pool->mem->free_fcn(p);
6544 p = tem;
6545 }
6546}
6547
6548static XML_Char *
Haibo Huang40a71912019-10-11 11:13:39 -07006549poolAppend(STRING_POOL *pool, const ENCODING *enc, const char *ptr,
6550 const char *end) {
6551 if (! pool->ptr && ! poolGrow(pool))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006552 return NULL;
6553 for (;;) {
Haibo Huang40a71912019-10-11 11:13:39 -07006554 const enum XML_Convert_Result convert_res = XmlConvert(
6555 enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
6556 if ((convert_res == XML_CONVERT_COMPLETED)
6557 || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006558 break;
Haibo Huang40a71912019-10-11 11:13:39 -07006559 if (! poolGrow(pool))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006560 return NULL;
6561 }
6562 return pool->start;
6563}
6564
Haibo Huang40a71912019-10-11 11:13:39 -07006565static const XML_Char *FASTCALL
6566poolCopyString(STRING_POOL *pool, const XML_Char *s) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006567 do {
Haibo Huang40a71912019-10-11 11:13:39 -07006568 if (! poolAppendChar(pool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006569 return NULL;
6570 } while (*s++);
6571 s = pool->start;
6572 poolFinish(pool);
6573 return s;
6574}
6575
6576static const XML_Char *
Haibo Huang40a71912019-10-11 11:13:39 -07006577poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) {
6578 if (! pool->ptr && ! poolGrow(pool)) {
Elliott Hughes72472942018-01-10 08:36:10 -08006579 /* The following line is unreachable given the current usage of
6580 * poolCopyStringN(). Currently it is called from exactly one
6581 * place to copy the text of a simple general entity. By that
6582 * point, the name of the entity is already stored in the pool, so
6583 * pool->ptr cannot be NULL.
6584 *
6585 * If poolCopyStringN() is used elsewhere as it well might be,
6586 * this line may well become executable again. Regardless, this
6587 * sort of check shouldn't be removed lightly, so we just exclude
6588 * it from the coverage statistics.
6589 */
6590 return NULL; /* LCOV_EXCL_LINE */
6591 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006592 for (; n > 0; --n, s++) {
Haibo Huang40a71912019-10-11 11:13:39 -07006593 if (! poolAppendChar(pool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006594 return NULL;
6595 }
6596 s = pool->start;
6597 poolFinish(pool);
6598 return s;
6599}
6600
Haibo Huang40a71912019-10-11 11:13:39 -07006601static const XML_Char *FASTCALL
6602poolAppendString(STRING_POOL *pool, const XML_Char *s) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006603 while (*s) {
Haibo Huang40a71912019-10-11 11:13:39 -07006604 if (! poolAppendChar(pool, *s))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006605 return NULL;
6606 s++;
6607 }
6608 return pool->start;
6609}
6610
6611static XML_Char *
Haibo Huang40a71912019-10-11 11:13:39 -07006612poolStoreString(STRING_POOL *pool, const ENCODING *enc, const char *ptr,
6613 const char *end) {
6614 if (! poolAppend(pool, enc, ptr, end))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006615 return NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07006616 if (pool->ptr == pool->end && ! poolGrow(pool))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006617 return NULL;
6618 *(pool->ptr)++ = 0;
6619 return pool->start;
6620}
6621
Elliott Hughes72472942018-01-10 08:36:10 -08006622static size_t
Haibo Huang40a71912019-10-11 11:13:39 -07006623poolBytesToAllocateFor(int blockSize) {
Elliott Hughes72472942018-01-10 08:36:10 -08006624 /* Unprotected math would be:
6625 ** return offsetof(BLOCK, s) + blockSize * sizeof(XML_Char);
6626 **
6627 ** Detect overflow, avoiding _signed_ overflow undefined behavior
6628 ** For a + b * c we check b * c in isolation first, so that addition of a
6629 ** on top has no chance of making us accept a small non-negative number
6630 */
Haibo Huang40a71912019-10-11 11:13:39 -07006631 const size_t stretch = sizeof(XML_Char); /* can be 4 bytes */
Elliott Hughes72472942018-01-10 08:36:10 -08006632
6633 if (blockSize <= 0)
6634 return 0;
6635
6636 if (blockSize > (int)(INT_MAX / stretch))
6637 return 0;
6638
6639 {
6640 const int stretchedBlockSize = blockSize * (int)stretch;
Haibo Huang40a71912019-10-11 11:13:39 -07006641 const int bytesToAllocate
6642 = (int)(offsetof(BLOCK, s) + (unsigned)stretchedBlockSize);
Elliott Hughes72472942018-01-10 08:36:10 -08006643 if (bytesToAllocate < 0)
6644 return 0;
6645
6646 return (size_t)bytesToAllocate;
6647 }
6648}
6649
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006650static XML_Bool FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006651poolGrow(STRING_POOL *pool) {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006652 if (pool->freeBlocks) {
6653 if (pool->start == 0) {
6654 pool->blocks = pool->freeBlocks;
6655 pool->freeBlocks = pool->freeBlocks->next;
6656 pool->blocks->next = NULL;
6657 pool->start = pool->blocks->s;
6658 pool->end = pool->start + pool->blocks->size;
6659 pool->ptr = pool->start;
6660 return XML_TRUE;
6661 }
6662 if (pool->end - pool->start < pool->freeBlocks->size) {
6663 BLOCK *tem = pool->freeBlocks->next;
6664 pool->freeBlocks->next = pool->blocks;
6665 pool->blocks = pool->freeBlocks;
6666 pool->freeBlocks = tem;
6667 memcpy(pool->blocks->s, pool->start,
6668 (pool->end - pool->start) * sizeof(XML_Char));
6669 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
6670 pool->start = pool->blocks->s;
6671 pool->end = pool->start + pool->blocks->size;
6672 return XML_TRUE;
6673 }
6674 }
6675 if (pool->blocks && pool->start == pool->blocks->s) {
Paul Duffin4bf8f122016-05-13 12:35:25 +01006676 BLOCK *temp;
Haibo Huang40a71912019-10-11 11:13:39 -07006677 int blockSize = (int)((unsigned)(pool->end - pool->start) * 2U);
Elliott Hughes72472942018-01-10 08:36:10 -08006678 size_t bytesToAllocate;
Paul Duffin4bf8f122016-05-13 12:35:25 +01006679
Elliott Hughes72472942018-01-10 08:36:10 -08006680 /* NOTE: Needs to be calculated prior to calling `realloc`
6681 to avoid dangling pointers: */
6682 const ptrdiff_t offsetInsideBlock = pool->ptr - pool->start;
6683
6684 if (blockSize < 0) {
6685 /* This condition traps a situation where either more than
6686 * INT_MAX/2 bytes have already been allocated. This isn't
6687 * readily testable, since it is unlikely that an average
6688 * machine will have that much memory, so we exclude it from the
6689 * coverage statistics.
6690 */
6691 return XML_FALSE; /* LCOV_EXCL_LINE */
6692 }
6693
6694 bytesToAllocate = poolBytesToAllocateFor(blockSize);
6695 if (bytesToAllocate == 0)
Paul Duffin4bf8f122016-05-13 12:35:25 +01006696 return XML_FALSE;
6697
Haibo Huang40a71912019-10-11 11:13:39 -07006698 temp = (BLOCK *)pool->mem->realloc_fcn(pool->blocks,
6699 (unsigned)bytesToAllocate);
Elliott Hughes35e432d2012-09-09 14:23:38 -07006700 if (temp == NULL)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006701 return XML_FALSE;
Elliott Hughes35e432d2012-09-09 14:23:38 -07006702 pool->blocks = temp;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006703 pool->blocks->size = blockSize;
Elliott Hughes72472942018-01-10 08:36:10 -08006704 pool->ptr = pool->blocks->s + offsetInsideBlock;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006705 pool->start = pool->blocks->s;
6706 pool->end = pool->start + blockSize;
Haibo Huang40a71912019-10-11 11:13:39 -07006707 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006708 BLOCK *tem;
6709 int blockSize = (int)(pool->end - pool->start);
Elliott Hughes72472942018-01-10 08:36:10 -08006710 size_t bytesToAllocate;
Paul Duffin4bf8f122016-05-13 12:35:25 +01006711
Elliott Hughes72472942018-01-10 08:36:10 -08006712 if (blockSize < 0) {
6713 /* This condition traps a situation where either more than
6714 * INT_MAX bytes have already been allocated (which is prevented
6715 * by various pieces of program logic, not least this one, never
6716 * mind the unlikelihood of actually having that much memory) or
6717 * the pool control fields have been corrupted (which could
6718 * conceivably happen in an extremely buggy user handler
6719 * function). Either way it isn't readily testable, so we
6720 * exclude it from the coverage statistics.
6721 */
Haibo Huang40a71912019-10-11 11:13:39 -07006722 return XML_FALSE; /* LCOV_EXCL_LINE */
Elliott Hughes72472942018-01-10 08:36:10 -08006723 }
Paul Duffin4bf8f122016-05-13 12:35:25 +01006724
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006725 if (blockSize < INIT_BLOCK_SIZE)
6726 blockSize = INIT_BLOCK_SIZE;
Elliott Hughes72472942018-01-10 08:36:10 -08006727 else {
6728 /* Detect overflow, avoiding _signed_ overflow undefined behavior */
6729 if ((int)((unsigned)blockSize * 2U) < 0) {
6730 return XML_FALSE;
6731 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006732 blockSize *= 2;
Elliott Hughes72472942018-01-10 08:36:10 -08006733 }
6734
6735 bytesToAllocate = poolBytesToAllocateFor(blockSize);
6736 if (bytesToAllocate == 0)
6737 return XML_FALSE;
6738
6739 tem = (BLOCK *)pool->mem->malloc_fcn(bytesToAllocate);
Haibo Huang40a71912019-10-11 11:13:39 -07006740 if (! tem)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006741 return XML_FALSE;
6742 tem->size = blockSize;
6743 tem->next = pool->blocks;
6744 pool->blocks = tem;
6745 if (pool->ptr != pool->start)
Haibo Huang40a71912019-10-11 11:13:39 -07006746 memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006747 pool->ptr = tem->s + (pool->ptr - pool->start);
6748 pool->start = tem->s;
6749 pool->end = tem->s + blockSize;
6750 }
6751 return XML_TRUE;
6752}
6753
6754static int FASTCALL
Haibo Huang40a71912019-10-11 11:13:39 -07006755nextScaffoldPart(XML_Parser parser) {
6756 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
6757 CONTENT_SCAFFOLD *me;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006758 int next;
6759
Haibo Huang40a71912019-10-11 11:13:39 -07006760 if (! dtd->scaffIndex) {
Elliott Hughes72472942018-01-10 08:36:10 -08006761 dtd->scaffIndex = (int *)MALLOC(parser, parser->m_groupSize * sizeof(int));
Haibo Huang40a71912019-10-11 11:13:39 -07006762 if (! dtd->scaffIndex)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006763 return -1;
6764 dtd->scaffIndex[0] = 0;
6765 }
6766
6767 if (dtd->scaffCount >= dtd->scaffSize) {
6768 CONTENT_SCAFFOLD *temp;
6769 if (dtd->scaffold) {
Haibo Huang40a71912019-10-11 11:13:39 -07006770 temp = (CONTENT_SCAFFOLD *)REALLOC(
6771 parser, dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006772 if (temp == NULL)
6773 return -1;
6774 dtd->scaffSize *= 2;
Haibo Huang40a71912019-10-11 11:13:39 -07006775 } else {
Elliott Hughes72472942018-01-10 08:36:10 -08006776 temp = (CONTENT_SCAFFOLD *)MALLOC(parser, INIT_SCAFFOLD_ELEMENTS
Haibo Huang40a71912019-10-11 11:13:39 -07006777 * sizeof(CONTENT_SCAFFOLD));
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006778 if (temp == NULL)
6779 return -1;
6780 dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
6781 }
6782 dtd->scaffold = temp;
6783 }
6784 next = dtd->scaffCount++;
6785 me = &dtd->scaffold[next];
6786 if (dtd->scaffLevel) {
Haibo Huang40a71912019-10-11 11:13:39 -07006787 CONTENT_SCAFFOLD *parent
6788 = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]];
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006789 if (parent->lastchild) {
6790 dtd->scaffold[parent->lastchild].nextsib = next;
6791 }
Haibo Huang40a71912019-10-11 11:13:39 -07006792 if (! parent->childcnt)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006793 parent->firstchild = next;
6794 parent->lastchild = next;
6795 parent->childcnt++;
6796 }
6797 me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
6798 return next;
6799}
6800
6801static void
Haibo Huang40a71912019-10-11 11:13:39 -07006802build_node(XML_Parser parser, int src_node, XML_Content *dest,
6803 XML_Content **contpos, XML_Char **strpos) {
6804 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006805 dest->type = dtd->scaffold[src_node].type;
6806 dest->quant = dtd->scaffold[src_node].quant;
6807 if (dest->type == XML_CTYPE_NAME) {
6808 const XML_Char *src;
6809 dest->name = *strpos;
6810 src = dtd->scaffold[src_node].name;
6811 for (;;) {
6812 *(*strpos)++ = *src;
Haibo Huang40a71912019-10-11 11:13:39 -07006813 if (! *src)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006814 break;
6815 src++;
6816 }
6817 dest->numchildren = 0;
6818 dest->children = NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07006819 } else {
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006820 unsigned int i;
6821 int cn;
6822 dest->numchildren = dtd->scaffold[src_node].childcnt;
6823 dest->children = *contpos;
6824 *contpos += dest->numchildren;
Haibo Huang40a71912019-10-11 11:13:39 -07006825 for (i = 0, cn = dtd->scaffold[src_node].firstchild; i < dest->numchildren;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006826 i++, cn = dtd->scaffold[cn].nextsib) {
6827 build_node(parser, cn, &(dest->children[i]), contpos, strpos);
6828 }
6829 dest->name = NULL;
6830 }
6831}
6832
6833static XML_Content *
Haibo Huang40a71912019-10-11 11:13:39 -07006834build_model(XML_Parser parser) {
6835 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006836 XML_Content *ret;
6837 XML_Content *cpos;
Haibo Huang40a71912019-10-11 11:13:39 -07006838 XML_Char *str;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006839 int allocsize = (dtd->scaffCount * sizeof(XML_Content)
6840 + (dtd->contentStringLen * sizeof(XML_Char)));
6841
Elliott Hughes72472942018-01-10 08:36:10 -08006842 ret = (XML_Content *)MALLOC(parser, allocsize);
Haibo Huang40a71912019-10-11 11:13:39 -07006843 if (! ret)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006844 return NULL;
6845
Haibo Huang40a71912019-10-11 11:13:39 -07006846 str = (XML_Char *)(&ret[dtd->scaffCount]);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006847 cpos = &ret[1];
6848
6849 build_node(parser, 0, ret, &cpos, &str);
6850 return ret;
6851}
6852
6853static ELEMENT_TYPE *
Haibo Huang40a71912019-10-11 11:13:39 -07006854getElementType(XML_Parser parser, const ENCODING *enc, const char *ptr,
6855 const char *end) {
6856 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006857 const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
6858 ELEMENT_TYPE *ret;
6859
Haibo Huang40a71912019-10-11 11:13:39 -07006860 if (! name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006861 return NULL;
Haibo Huang40a71912019-10-11 11:13:39 -07006862 ret = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
6863 sizeof(ELEMENT_TYPE));
6864 if (! ret)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006865 return NULL;
6866 if (ret->name != name)
6867 poolDiscard(&dtd->pool);
6868 else {
6869 poolFinish(&dtd->pool);
Haibo Huang40a71912019-10-11 11:13:39 -07006870 if (! setElementTypePrefix(parser, ret))
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08006871 return NULL;
6872 }
6873 return ret;
6874}
Elliott Hughes72472942018-01-10 08:36:10 -08006875
6876static XML_Char *
Haibo Huang40a71912019-10-11 11:13:39 -07006877copyString(const XML_Char *s, const XML_Memory_Handling_Suite *memsuite) {
6878 int charsRequired = 0;
6879 XML_Char *result;
Elliott Hughes72472942018-01-10 08:36:10 -08006880
Haibo Huang40a71912019-10-11 11:13:39 -07006881 /* First determine how long the string is */
6882 while (s[charsRequired] != 0) {
Elliott Hughes72472942018-01-10 08:36:10 -08006883 charsRequired++;
Haibo Huang40a71912019-10-11 11:13:39 -07006884 }
6885 /* Include the terminator */
6886 charsRequired++;
Elliott Hughes72472942018-01-10 08:36:10 -08006887
Haibo Huang40a71912019-10-11 11:13:39 -07006888 /* Now allocate space for the copy */
6889 result = memsuite->malloc_fcn(charsRequired * sizeof(XML_Char));
6890 if (result == NULL)
6891 return NULL;
6892 /* Copy the original into place */
6893 memcpy(result, s, charsRequired * sizeof(XML_Char));
6894 return result;
Elliott Hughes72472942018-01-10 08:36:10 -08006895}