Coverage Report

Created: 2023-03-26 06:14

/src/libxml2/parser.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * parser.c : an XML 1.0 parser, namespaces and validity support are mostly
3
 *            implemented on top of the SAX interfaces
4
 *
5
 * References:
6
 *   The XML specification:
7
 *     http://www.w3.org/TR/REC-xml
8
 *   Original 1.0 version:
9
 *     http://www.w3.org/TR/1998/REC-xml-19980210
10
 *   XML second edition working draft
11
 *     http://www.w3.org/TR/2000/WD-xml-2e-20000814
12
 *
13
 * Okay this is a big file, the parser core is around 7000 lines, then it
14
 * is followed by the progressive parser top routines, then the various
15
 * high level APIs to call the parser and a few miscellaneous functions.
16
 * A number of helper functions and deprecated ones have been moved to
17
 * parserInternals.c to reduce this file size.
18
 * As much as possible the functions are associated with their relative
19
 * production in the XML specification. A few productions defining the
20
 * different ranges of character are actually implanted either in
21
 * parserInternals.h or parserInternals.c
22
 * The DOM tree build is realized from the default SAX callbacks in
23
 * the module SAX.c.
24
 * The routines doing the validation checks are in valid.c and called either
25
 * from the SAX callbacks or as standalone functions using a preparsed
26
 * document.
27
 *
28
 * See Copyright for the status of this software.
29
 *
30
 * daniel@veillard.com
31
 */
32
33
/* To avoid EBCDIC trouble when parsing on zOS */
34
#if defined(__MVS__)
35
#pragma convert("ISO8859-1")
36
#endif
37
38
#define IN_LIBXML
39
#include "libxml.h"
40
41
#if defined(_WIN32)
42
#define XML_DIR_SEP '\\'
43
#else
44
#define XML_DIR_SEP '/'
45
#endif
46
47
#include <stdlib.h>
48
#include <limits.h>
49
#include <string.h>
50
#include <stdarg.h>
51
#include <stddef.h>
52
#include <ctype.h>
53
#include <stdlib.h>
54
#include <libxml/xmlmemory.h>
55
#include <libxml/threads.h>
56
#include <libxml/globals.h>
57
#include <libxml/tree.h>
58
#include <libxml/parser.h>
59
#include <libxml/parserInternals.h>
60
#include <libxml/HTMLparser.h>
61
#include <libxml/valid.h>
62
#include <libxml/entities.h>
63
#include <libxml/xmlerror.h>
64
#include <libxml/encoding.h>
65
#include <libxml/xmlIO.h>
66
#include <libxml/uri.h>
67
#ifdef LIBXML_CATALOG_ENABLED
68
#include <libxml/catalog.h>
69
#endif
70
#ifdef LIBXML_SCHEMAS_ENABLED
71
#include <libxml/xmlschemastypes.h>
72
#include <libxml/relaxng.h>
73
#endif
74
#if defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
75
#include <libxml/xpath.h>
76
#endif
77
78
#include "private/buf.h"
79
#include "private/dict.h"
80
#include "private/enc.h"
81
#include "private/entities.h"
82
#include "private/error.h"
83
#include "private/globals.h"
84
#include "private/html.h"
85
#include "private/io.h"
86
#include "private/memory.h"
87
#include "private/parser.h"
88
#include "private/threads.h"
89
#include "private/xpath.h"
90
91
struct _xmlStartTag {
92
    const xmlChar *prefix;
93
    const xmlChar *URI;
94
    int line;
95
    int nsNr;
96
};
97
98
static xmlParserCtxtPtr
99
xmlCreateEntityParserCtxtInternal(xmlSAXHandlerPtr sax, void *userData,
100
        const xmlChar *URL, const xmlChar *ID, const xmlChar *base,
101
        xmlParserCtxtPtr pctx);
102
103
static int
104
xmlParseElementStart(xmlParserCtxtPtr ctxt);
105
106
static void
107
xmlParseElementEnd(xmlParserCtxtPtr ctxt);
108
109
/************************************************************************
110
 *                  *
111
 *  Arbitrary limits set in the parser. See XML_PARSE_HUGE    *
112
 *                  *
113
 ************************************************************************/
114
115
#define XML_PARSER_BIG_ENTITY 1000
116
#define XML_PARSER_LOT_ENTITY 5000
117
118
/*
119
 * Constants for protection against abusive entity expansion
120
 * ("billion laughs").
121
 */
122
123
/*
124
 * XML_PARSER_NON_LINEAR is roughly the maximum allowed amplification factor
125
 * of serialized output after entity expansion.
126
 */
127
1.08k
#define XML_PARSER_NON_LINEAR 5
128
129
/*
130
 * A certain amount is always allowed.
131
 */
132
172k
#define XML_PARSER_ALLOWED_EXPANSION 1000000
133
134
/*
135
 * Fixed cost for each entity reference. This crudely models processing time
136
 * as well to protect, for example, against exponential expansion of empty
137
 * or very short entities.
138
 */
139
172k
#define XML_ENT_FIXED_COST 20
140
141
/**
142
 * xmlParserMaxDepth:
143
 *
144
 * arbitrary depth limit for the XML documents that we allow to
145
 * process. This is not a limitation of the parser but a safety
146
 * boundary feature. It can be disabled with the XML_PARSE_HUGE
147
 * parser option.
148
 */
149
unsigned int xmlParserMaxDepth = 256;
150
151
152
153
#define SAX2 1
154
319M
#define XML_PARSER_BIG_BUFFER_SIZE 300
155
591M
#define XML_PARSER_BUFFER_SIZE 100
156
178k
#define SAX_COMPAT_MODE BAD_CAST "SAX compatibility mode document"
157
158
/**
159
 * XML_PARSER_CHUNK_SIZE
160
 *
161
 * When calling GROW that's the minimal amount of data
162
 * the parser expected to have received. It is not a hard
163
 * limit but an optimization when reading strings like Names
164
 * It is not strictly needed as long as inputs available characters
165
 * are followed by 0, which should be provided by the I/O level
166
 */
167
#define XML_PARSER_CHUNK_SIZE 100
168
169
/*
170
 * List of XML prefixed PI allowed by W3C specs
171
 */
172
173
static const char* const xmlW3CPIs[] = {
174
    "xml-stylesheet",
175
    "xml-model",
176
    NULL
177
};
178
179
180
/* DEPR void xmlParserHandleReference(xmlParserCtxtPtr ctxt); */
181
static xmlEntityPtr xmlParseStringPEReference(xmlParserCtxtPtr ctxt,
182
                                              const xmlChar **str);
183
184
static xmlParserErrors
185
xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
186
                xmlSAXHandlerPtr sax,
187
          void *user_data, int depth, const xmlChar *URL,
188
          const xmlChar *ID, xmlNodePtr *list);
189
190
static int
191
xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options,
192
                          const char *encoding);
193
#ifdef LIBXML_LEGACY_ENABLED
194
static void
195
xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
196
                      xmlNodePtr lastNode);
197
#endif /* LIBXML_LEGACY_ENABLED */
198
199
static xmlParserErrors
200
xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
201
          const xmlChar *string, void *user_data, xmlNodePtr *lst);
202
203
static int
204
xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity);
205
206
/************************************************************************
207
 *                  *
208
 *    Some factorized error routines        *
209
 *                  *
210
 ************************************************************************/
211
212
/**
213
 * xmlErrAttributeDup:
214
 * @ctxt:  an XML parser context
215
 * @prefix:  the attribute prefix
216
 * @localname:  the attribute localname
217
 *
218
 * Handle a redefinition of attribute error
219
 */
220
static void
221
xmlErrAttributeDup(xmlParserCtxtPtr ctxt, const xmlChar * prefix,
222
                   const xmlChar * localname)
223
10.2k
{
224
10.2k
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
225
10.2k
        (ctxt->instate == XML_PARSER_EOF))
226
241
  return;
227
10.0k
    if (ctxt != NULL)
228
10.0k
  ctxt->errNo = XML_ERR_ATTRIBUTE_REDEFINED;
229
230
10.0k
    if (prefix == NULL)
231
3.01k
        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
232
3.01k
                        XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL, NULL, 0,
233
3.01k
                        (const char *) localname, NULL, NULL, 0, 0,
234
3.01k
                        "Attribute %s redefined\n", localname);
235
7.04k
    else
236
7.04k
        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
237
7.04k
                        XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL, NULL, 0,
238
7.04k
                        (const char *) prefix, (const char *) localname,
239
7.04k
                        NULL, 0, 0, "Attribute %s:%s redefined\n", prefix,
240
7.04k
                        localname);
241
10.0k
    if (ctxt != NULL) {
242
10.0k
  ctxt->wellFormed = 0;
243
10.0k
  if (ctxt->recovery == 0)
244
8.78k
      ctxt->disableSAX = 1;
245
10.0k
    }
246
10.0k
}
247
248
/**
249
 * xmlFatalErr:
250
 * @ctxt:  an XML parser context
251
 * @error:  the error number
252
 * @extra:  extra information string
253
 *
254
 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
255
 */
256
static void
257
xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info)
258
670k
{
259
670k
    const char *errmsg;
260
261
670k
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
262
670k
        (ctxt->instate == XML_PARSER_EOF))
263
14.2k
  return;
264
656k
    switch (error) {
265
66.5k
        case XML_ERR_INVALID_HEX_CHARREF:
266
66.5k
            errmsg = "CharRef: invalid hexadecimal value";
267
66.5k
            break;
268
43.6k
        case XML_ERR_INVALID_DEC_CHARREF:
269
43.6k
            errmsg = "CharRef: invalid decimal value";
270
43.6k
            break;
271
0
        case XML_ERR_INVALID_CHARREF:
272
0
            errmsg = "CharRef: invalid value";
273
0
            break;
274
111k
        case XML_ERR_INTERNAL_ERROR:
275
111k
            errmsg = "internal error";
276
111k
            break;
277
0
        case XML_ERR_PEREF_AT_EOF:
278
0
            errmsg = "PEReference at end of document";
279
0
            break;
280
0
        case XML_ERR_PEREF_IN_PROLOG:
281
0
            errmsg = "PEReference in prolog";
282
0
            break;
283
0
        case XML_ERR_PEREF_IN_EPILOG:
284
0
            errmsg = "PEReference in epilog";
285
0
            break;
286
0
        case XML_ERR_PEREF_NO_NAME:
287
0
            errmsg = "PEReference: no name";
288
0
            break;
289
29.3k
        case XML_ERR_PEREF_SEMICOL_MISSING:
290
29.3k
            errmsg = "PEReference: expecting ';'";
291
29.3k
            break;
292
572
        case XML_ERR_ENTITY_LOOP:
293
572
            errmsg = "Detected an entity reference loop";
294
572
            break;
295
0
        case XML_ERR_ENTITY_NOT_STARTED:
296
0
            errmsg = "EntityValue: \" or ' expected";
297
0
            break;
298
307
        case XML_ERR_ENTITY_PE_INTERNAL:
299
307
            errmsg = "PEReferences forbidden in internal subset";
300
307
            break;
301
1.33k
        case XML_ERR_ENTITY_NOT_FINISHED:
302
1.33k
            errmsg = "EntityValue: \" or ' expected";
303
1.33k
            break;
304
19.6k
        case XML_ERR_ATTRIBUTE_NOT_STARTED:
305
19.6k
            errmsg = "AttValue: \" or ' expected";
306
19.6k
            break;
307
66.1k
        case XML_ERR_LT_IN_ATTRIBUTE:
308
66.1k
            errmsg = "Unescaped '<' not allowed in attributes values";
309
66.1k
            break;
310
3.36k
        case XML_ERR_LITERAL_NOT_STARTED:
311
3.36k
            errmsg = "SystemLiteral \" or ' expected";
312
3.36k
            break;
313
16.4k
        case XML_ERR_LITERAL_NOT_FINISHED:
314
16.4k
            errmsg = "Unfinished System or Public ID \" or ' expected";
315
16.4k
            break;
316
2.53k
        case XML_ERR_MISPLACED_CDATA_END:
317
2.53k
            errmsg = "Sequence ']]>' not allowed in content";
318
2.53k
            break;
319
2.99k
        case XML_ERR_URI_REQUIRED:
320
2.99k
            errmsg = "SYSTEM or PUBLIC, the URI is missing";
321
2.99k
            break;
322
1.19k
        case XML_ERR_PUBID_REQUIRED:
323
1.19k
            errmsg = "PUBLIC, the Public Identifier is missing";
324
1.19k
            break;
325
59.8k
        case XML_ERR_HYPHEN_IN_COMMENT:
326
59.8k
            errmsg = "Comment must not contain '--' (double-hyphen)";
327
59.8k
            break;
328
13.5k
        case XML_ERR_PI_NOT_STARTED:
329
13.5k
            errmsg = "xmlParsePI : no target name";
330
13.5k
            break;
331
2.81k
        case XML_ERR_RESERVED_XML_NAME:
332
2.81k
            errmsg = "Invalid PI name";
333
2.81k
            break;
334
1.06k
        case XML_ERR_NOTATION_NOT_STARTED:
335
1.06k
            errmsg = "NOTATION: Name expected here";
336
1.06k
            break;
337
18.2k
        case XML_ERR_NOTATION_NOT_FINISHED:
338
18.2k
            errmsg = "'>' required to close NOTATION declaration";
339
18.2k
            break;
340
1.72k
        case XML_ERR_VALUE_REQUIRED:
341
1.72k
            errmsg = "Entity value required";
342
1.72k
            break;
343
508
        case XML_ERR_URI_FRAGMENT:
344
508
            errmsg = "Fragment not allowed";
345
508
            break;
346
10.3k
        case XML_ERR_ATTLIST_NOT_STARTED:
347
10.3k
            errmsg = "'(' required to start ATTLIST enumeration";
348
10.3k
            break;
349
12.8k
        case XML_ERR_NMTOKEN_REQUIRED:
350
12.8k
            errmsg = "NmToken expected in ATTLIST enumeration";
351
12.8k
            break;
352
7.74k
        case XML_ERR_ATTLIST_NOT_FINISHED:
353
7.74k
            errmsg = "')' required to finish ATTLIST enumeration";
354
7.74k
            break;
355
3.10k
        case XML_ERR_MIXED_NOT_STARTED:
356
3.10k
            errmsg = "MixedContentDecl : '|' or ')*' expected";
357
3.10k
            break;
358
0
        case XML_ERR_PCDATA_REQUIRED:
359
0
            errmsg = "MixedContentDecl : '#PCDATA' expected";
360
0
            break;
361
2.67k
        case XML_ERR_ELEMCONTENT_NOT_STARTED:
362
2.67k
            errmsg = "ContentDecl : Name or '(' expected";
363
2.67k
            break;
364
14.7k
        case XML_ERR_ELEMCONTENT_NOT_FINISHED:
365
14.7k
            errmsg = "ContentDecl : ',' '|' or ')' expected";
366
14.7k
            break;
367
0
        case XML_ERR_PEREF_IN_INT_SUBSET:
368
0
            errmsg =
369
0
                "PEReference: forbidden within markup decl in internal subset";
370
0
            break;
371
19.6k
        case XML_ERR_GT_REQUIRED:
372
19.6k
            errmsg = "expected '>'";
373
19.6k
            break;
374
1
        case XML_ERR_CONDSEC_INVALID:
375
1
            errmsg = "XML conditional section '[' expected";
376
1
            break;
377
895
        case XML_ERR_EXT_SUBSET_NOT_FINISHED:
378
895
            errmsg = "Content error in the external subset";
379
895
            break;
380
262
        case XML_ERR_CONDSEC_INVALID_KEYWORD:
381
262
            errmsg =
382
262
                "conditional section INCLUDE or IGNORE keyword expected";
383
262
            break;
384
200
        case XML_ERR_CONDSEC_NOT_FINISHED:
385
200
            errmsg = "XML conditional section not closed";
386
200
            break;
387
55
        case XML_ERR_XMLDECL_NOT_STARTED:
388
55
            errmsg = "Text declaration '<?xml' required";
389
55
            break;
390
26.8k
        case XML_ERR_XMLDECL_NOT_FINISHED:
391
26.8k
            errmsg = "parsing XML declaration: '?>' expected";
392
26.8k
            break;
393
0
        case XML_ERR_EXT_ENTITY_STANDALONE:
394
0
            errmsg = "external parsed entities cannot be standalone";
395
0
            break;
396
40.6k
        case XML_ERR_ENTITYREF_SEMICOL_MISSING:
397
40.6k
            errmsg = "EntityRef: expecting ';'";
398
40.6k
            break;
399
7.46k
        case XML_ERR_DOCTYPE_NOT_FINISHED:
400
7.46k
            errmsg = "DOCTYPE improperly terminated";
401
7.46k
            break;
402
0
        case XML_ERR_LTSLASH_REQUIRED:
403
0
            errmsg = "EndTag: '</' not found";
404
0
            break;
405
2.07k
        case XML_ERR_EQUAL_REQUIRED:
406
2.07k
            errmsg = "expected '='";
407
2.07k
            break;
408
6.55k
        case XML_ERR_STRING_NOT_CLOSED:
409
6.55k
            errmsg = "String not closed expecting \" or '";
410
6.55k
            break;
411
1.03k
        case XML_ERR_STRING_NOT_STARTED:
412
1.03k
            errmsg = "String not started expecting ' or \"";
413
1.03k
            break;
414
697
        case XML_ERR_ENCODING_NAME:
415
697
            errmsg = "Invalid XML encoding name";
416
697
            break;
417
1.24k
        case XML_ERR_STANDALONE_VALUE:
418
1.24k
            errmsg = "standalone accepts only 'yes' or 'no'";
419
1.24k
            break;
420
620
        case XML_ERR_DOCUMENT_EMPTY:
421
620
            errmsg = "Document is empty";
422
620
            break;
423
14.6k
        case XML_ERR_DOCUMENT_END:
424
14.6k
            errmsg = "Extra content at the end of the document";
425
14.6k
            break;
426
2.20k
        case XML_ERR_NOT_WELL_BALANCED:
427
2.20k
            errmsg = "chunk is not well balanced";
428
2.20k
            break;
429
0
        case XML_ERR_EXTRA_CONTENT:
430
0
            errmsg = "extra content at the end of well balanced chunk";
431
0
            break;
432
9.47k
        case XML_ERR_VERSION_MISSING:
433
9.47k
            errmsg = "Malformed declaration expecting version";
434
9.47k
            break;
435
3.56k
        case XML_ERR_NAME_TOO_LONG:
436
3.56k
            errmsg = "Name too long";
437
3.56k
            break;
438
#if 0
439
        case:
440
            errmsg = "";
441
            break;
442
#endif
443
3.60k
        default:
444
3.60k
            errmsg = "Unregistered error message";
445
656k
    }
446
656k
    if (ctxt != NULL)
447
656k
  ctxt->errNo = error;
448
656k
    if (info == NULL) {
449
541k
        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
450
541k
                        XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, "%s\n",
451
541k
                        errmsg);
452
541k
    } else {
453
114k
        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
454
114k
                        XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, "%s: %s\n",
455
114k
                        errmsg, info);
456
114k
    }
457
656k
    if (ctxt != NULL) {
458
656k
  ctxt->wellFormed = 0;
459
656k
  if (ctxt->recovery == 0)
460
579k
      ctxt->disableSAX = 1;
461
656k
    }
462
656k
}
463
464
/**
465
 * xmlFatalErrMsg:
466
 * @ctxt:  an XML parser context
467
 * @error:  the error number
468
 * @msg:  the error message
469
 *
470
 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
471
 */
472
static void LIBXML_ATTR_FORMAT(3,0)
473
xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
474
               const char *msg)
475
616k
{
476
616k
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
477
616k
        (ctxt->instate == XML_PARSER_EOF))
478
3.91k
  return;
479
612k
    if (ctxt != NULL)
480
612k
  ctxt->errNo = error;
481
612k
    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
482
612k
                    XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg);
483
612k
    if (ctxt != NULL) {
484
612k
  ctxt->wellFormed = 0;
485
612k
  if (ctxt->recovery == 0)
486
578k
      ctxt->disableSAX = 1;
487
612k
    }
488
612k
}
489
490
/**
491
 * xmlWarningMsg:
492
 * @ctxt:  an XML parser context
493
 * @error:  the error number
494
 * @msg:  the error message
495
 * @str1:  extra data
496
 * @str2:  extra data
497
 *
498
 * Handle a warning.
499
 */
500
static void LIBXML_ATTR_FORMAT(3,0)
501
xmlWarningMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
502
              const char *msg, const xmlChar *str1, const xmlChar *str2)
503
54.5k
{
504
54.5k
    xmlStructuredErrorFunc schannel = NULL;
505
506
54.5k
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
507
54.5k
        (ctxt->instate == XML_PARSER_EOF))
508
0
  return;
509
54.5k
    if ((ctxt != NULL) && (ctxt->sax != NULL) &&
510
54.5k
        (ctxt->sax->initialized == XML_SAX2_MAGIC))
511
54.5k
        schannel = ctxt->sax->serror;
512
54.5k
    if (ctxt != NULL) {
513
54.5k
        __xmlRaiseError(schannel,
514
54.5k
                    (ctxt->sax) ? ctxt->sax->warning : NULL,
515
54.5k
                    ctxt->userData,
516
54.5k
                    ctxt, NULL, XML_FROM_PARSER, error,
517
54.5k
                    XML_ERR_WARNING, NULL, 0,
518
54.5k
        (const char *) str1, (const char *) str2, NULL, 0, 0,
519
54.5k
        msg, (const char *) str1, (const char *) str2);
520
54.5k
    } else {
521
0
        __xmlRaiseError(schannel, NULL, NULL,
522
0
                    ctxt, NULL, XML_FROM_PARSER, error,
523
0
                    XML_ERR_WARNING, NULL, 0,
524
0
        (const char *) str1, (const char *) str2, NULL, 0, 0,
525
0
        msg, (const char *) str1, (const char *) str2);
526
0
    }
527
54.5k
}
528
529
/**
530
 * xmlValidityError:
531
 * @ctxt:  an XML parser context
532
 * @error:  the error number
533
 * @msg:  the error message
534
 * @str1:  extra data
535
 *
536
 * Handle a validity error.
537
 */
538
static void LIBXML_ATTR_FORMAT(3,0)
539
xmlValidityError(xmlParserCtxtPtr ctxt, xmlParserErrors error,
540
              const char *msg, const xmlChar *str1, const xmlChar *str2)
541
39.4k
{
542
39.4k
    xmlStructuredErrorFunc schannel = NULL;
543
544
39.4k
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
545
39.4k
        (ctxt->instate == XML_PARSER_EOF))
546
0
  return;
547
39.4k
    if (ctxt != NULL) {
548
39.4k
  ctxt->errNo = error;
549
39.4k
  if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
550
39.4k
      schannel = ctxt->sax->serror;
551
39.4k
    }
552
39.4k
    if (ctxt != NULL) {
553
39.4k
        __xmlRaiseError(schannel,
554
39.4k
                    ctxt->vctxt.error, ctxt->vctxt.userData,
555
39.4k
                    ctxt, NULL, XML_FROM_DTD, error,
556
39.4k
                    XML_ERR_ERROR, NULL, 0, (const char *) str1,
557
39.4k
        (const char *) str2, NULL, 0, 0,
558
39.4k
        msg, (const char *) str1, (const char *) str2);
559
39.4k
  ctxt->valid = 0;
560
39.4k
    } else {
561
0
        __xmlRaiseError(schannel, NULL, NULL,
562
0
                    ctxt, NULL, XML_FROM_DTD, error,
563
0
                    XML_ERR_ERROR, NULL, 0, (const char *) str1,
564
0
        (const char *) str2, NULL, 0, 0,
565
0
        msg, (const char *) str1, (const char *) str2);
566
0
    }
567
39.4k
}
568
569
/**
570
 * xmlFatalErrMsgInt:
571
 * @ctxt:  an XML parser context
572
 * @error:  the error number
573
 * @msg:  the error message
574
 * @val:  an integer value
575
 *
576
 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
577
 */
578
static void LIBXML_ATTR_FORMAT(3,0)
579
xmlFatalErrMsgInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
580
                  const char *msg, int val)
581
497k
{
582
497k
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
583
497k
        (ctxt->instate == XML_PARSER_EOF))
584
278
  return;
585
496k
    if (ctxt != NULL)
586
496k
  ctxt->errNo = error;
587
496k
    __xmlRaiseError(NULL, NULL, NULL,
588
496k
                    ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
589
496k
                    NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
590
496k
    if (ctxt != NULL) {
591
496k
  ctxt->wellFormed = 0;
592
496k
  if (ctxt->recovery == 0)
593
359k
      ctxt->disableSAX = 1;
594
496k
    }
595
496k
}
596
597
/**
598
 * xmlFatalErrMsgStrIntStr:
599
 * @ctxt:  an XML parser context
600
 * @error:  the error number
601
 * @msg:  the error message
602
 * @str1:  an string info
603
 * @val:  an integer value
604
 * @str2:  an string info
605
 *
606
 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
607
 */
608
static void LIBXML_ATTR_FORMAT(3,0)
609
xmlFatalErrMsgStrIntStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
610
                  const char *msg, const xmlChar *str1, int val,
611
      const xmlChar *str2)
612
273k
{
613
273k
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
614
273k
        (ctxt->instate == XML_PARSER_EOF))
615
117
  return;
616
273k
    if (ctxt != NULL)
617
273k
  ctxt->errNo = error;
618
273k
    __xmlRaiseError(NULL, NULL, NULL,
619
273k
                    ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
620
273k
                    NULL, 0, (const char *) str1, (const char *) str2,
621
273k
        NULL, val, 0, msg, str1, val, str2);
622
273k
    if (ctxt != NULL) {
623
273k
  ctxt->wellFormed = 0;
624
273k
  if (ctxt->recovery == 0)
625
251k
      ctxt->disableSAX = 1;
626
273k
    }
627
273k
}
628
629
/**
630
 * xmlFatalErrMsgStr:
631
 * @ctxt:  an XML parser context
632
 * @error:  the error number
633
 * @msg:  the error message
634
 * @val:  a string value
635
 *
636
 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
637
 */
638
static void LIBXML_ATTR_FORMAT(3,0)
639
xmlFatalErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
640
                  const char *msg, const xmlChar * val)
641
206k
{
642
206k
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
643
206k
        (ctxt->instate == XML_PARSER_EOF))
644
547
  return;
645
206k
    if (ctxt != NULL)
646
206k
  ctxt->errNo = error;
647
206k
    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL,
648
206k
                    XML_FROM_PARSER, error, XML_ERR_FATAL,
649
206k
                    NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
650
206k
                    val);
651
206k
    if (ctxt != NULL) {
652
206k
  ctxt->wellFormed = 0;
653
206k
  if (ctxt->recovery == 0)
654
197k
      ctxt->disableSAX = 1;
655
206k
    }
656
206k
}
657
658
/**
659
 * xmlErrMsgStr:
660
 * @ctxt:  an XML parser context
661
 * @error:  the error number
662
 * @msg:  the error message
663
 * @val:  a string value
664
 *
665
 * Handle a non fatal parser error
666
 */
667
static void LIBXML_ATTR_FORMAT(3,0)
668
xmlErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
669
                  const char *msg, const xmlChar * val)
670
14.2k
{
671
14.2k
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
672
14.2k
        (ctxt->instate == XML_PARSER_EOF))
673
0
  return;
674
14.2k
    if (ctxt != NULL)
675
14.2k
  ctxt->errNo = error;
676
14.2k
    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL,
677
14.2k
                    XML_FROM_PARSER, error, XML_ERR_ERROR,
678
14.2k
                    NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
679
14.2k
                    val);
680
14.2k
}
681
682
/**
683
 * xmlNsErr:
684
 * @ctxt:  an XML parser context
685
 * @error:  the error number
686
 * @msg:  the message
687
 * @info1:  extra information string
688
 * @info2:  extra information string
689
 *
690
 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
691
 */
692
static void LIBXML_ATTR_FORMAT(3,0)
693
xmlNsErr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
694
         const char *msg,
695
         const xmlChar * info1, const xmlChar * info2,
696
         const xmlChar * info3)
697
596k
{
698
596k
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
699
596k
        (ctxt->instate == XML_PARSER_EOF))
700
4.29k
  return;
701
591k
    if (ctxt != NULL)
702
591k
  ctxt->errNo = error;
703
591k
    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
704
591k
                    XML_ERR_ERROR, NULL, 0, (const char *) info1,
705
591k
                    (const char *) info2, (const char *) info3, 0, 0, msg,
706
591k
                    info1, info2, info3);
707
591k
    if (ctxt != NULL)
708
591k
  ctxt->nsWellFormed = 0;
709
591k
}
710
711
/**
712
 * xmlNsWarn
713
 * @ctxt:  an XML parser context
714
 * @error:  the error number
715
 * @msg:  the message
716
 * @info1:  extra information string
717
 * @info2:  extra information string
718
 *
719
 * Handle a namespace warning error
720
 */
721
static void LIBXML_ATTR_FORMAT(3,0)
722
xmlNsWarn(xmlParserCtxtPtr ctxt, xmlParserErrors error,
723
         const char *msg,
724
         const xmlChar * info1, const xmlChar * info2,
725
         const xmlChar * info3)
726
26.2k
{
727
26.2k
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
728
26.2k
        (ctxt->instate == XML_PARSER_EOF))
729
0
  return;
730
26.2k
    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
731
26.2k
                    XML_ERR_WARNING, NULL, 0, (const char *) info1,
732
26.2k
                    (const char *) info2, (const char *) info3, 0, 0, msg,
733
26.2k
                    info1, info2, info3);
734
26.2k
}
735
736
static void
737
721k
xmlSaturatedAdd(unsigned long *dst, unsigned long val) {
738
721k
    if (val > ULONG_MAX - *dst)
739
0
        *dst = ULONG_MAX;
740
721k
    else
741
721k
        *dst += val;
742
721k
}
743
744
static void
745
249k
xmlSaturatedAddSizeT(unsigned long *dst, unsigned long val) {
746
249k
    if (val > ULONG_MAX - *dst)
747
0
        *dst = ULONG_MAX;
748
249k
    else
749
249k
        *dst += val;
750
249k
}
751
752
/**
753
 * xmlParserEntityCheck:
754
 * @ctxt:  parser context
755
 * @extra:  sum of unexpanded entity sizes
756
 *
757
 * Check for non-linear entity expansion behaviour.
758
 *
759
 * In some cases like xmlStringDecodeEntities, this function is called
760
 * for each, possibly nested entity and its unexpanded content length.
761
 *
762
 * In other cases like xmlParseReference, it's only called for each
763
 * top-level entity with its unexpanded content length plus the sum of
764
 * the unexpanded content lengths (plus fixed cost) of all nested
765
 * entities.
766
 *
767
 * Summing the unexpanded lengths also adds the length of the reference.
768
 * This is by design. Taking the length of the entity name into account
769
 * discourages attacks that try to waste CPU time with abusively long
770
 * entity names. See test/recurse/lol6.xml for example. Each call also
771
 * adds some fixed cost XML_ENT_FIXED_COST to discourage attacks with
772
 * short entities.
773
 *
774
 * Returns 1 on error, 0 on success.
775
 */
776
static int
777
xmlParserEntityCheck(xmlParserCtxtPtr ctxt, unsigned long extra)
778
172k
{
779
172k
    unsigned long consumed;
780
172k
    xmlParserInputPtr input = ctxt->input;
781
172k
    xmlEntityPtr entity = input->entity;
782
783
    /*
784
     * Compute total consumed bytes so far, including input streams of
785
     * external entities.
786
     */
787
172k
    consumed = input->parentConsumed;
788
172k
    if ((entity == NULL) ||
789
172k
        ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
790
110k
         ((entity->flags & XML_ENT_PARSED) == 0))) {
791
110k
        xmlSaturatedAdd(&consumed, input->consumed);
792
110k
        xmlSaturatedAddSizeT(&consumed, input->cur - input->base);
793
110k
    }
794
172k
    xmlSaturatedAdd(&consumed, ctxt->sizeentities);
795
796
    /*
797
     * Add extra cost and some fixed cost.
798
     */
799
172k
    xmlSaturatedAdd(&ctxt->sizeentcopy, extra);
800
172k
    xmlSaturatedAdd(&ctxt->sizeentcopy, XML_ENT_FIXED_COST);
801
802
    /*
803
     * It's important to always use saturation arithmetic when tracking
804
     * entity sizes to make the size checks reliable. If "sizeentcopy"
805
     * overflows, we have to abort.
806
     */
807
172k
    if ((ctxt->sizeentcopy > XML_PARSER_ALLOWED_EXPANSION) &&
808
172k
        ((ctxt->sizeentcopy >= ULONG_MAX) ||
809
1.08k
         (ctxt->sizeentcopy / XML_PARSER_NON_LINEAR > consumed))) {
810
89
        xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_LOOP,
811
89
                       "Maximum entity amplification factor exceeded");
812
89
        xmlHaltParser(ctxt);
813
89
        return(1);
814
89
    }
815
816
172k
    return(0);
817
172k
}
818
819
/************************************************************************
820
 *                  *
821
 *    Library wide options          *
822
 *                  *
823
 ************************************************************************/
824
825
/**
826
  * xmlHasFeature:
827
  * @feature: the feature to be examined
828
  *
829
  * Examines if the library has been compiled with a given feature.
830
  *
831
  * Returns a non-zero value if the feature exist, otherwise zero.
832
  * Returns zero (0) if the feature does not exist or an unknown
833
  * unknown feature is requested, non-zero otherwise.
834
  */
835
int
836
xmlHasFeature(xmlFeature feature)
837
0
{
838
0
    switch (feature) {
839
0
  case XML_WITH_THREAD:
840
0
#ifdef LIBXML_THREAD_ENABLED
841
0
      return(1);
842
#else
843
      return(0);
844
#endif
845
0
        case XML_WITH_TREE:
846
0
#ifdef LIBXML_TREE_ENABLED
847
0
            return(1);
848
#else
849
            return(0);
850
#endif
851
0
        case XML_WITH_OUTPUT:
852
0
#ifdef LIBXML_OUTPUT_ENABLED
853
0
            return(1);
854
#else
855
            return(0);
856
#endif
857
0
        case XML_WITH_PUSH:
858
#ifdef LIBXML_PUSH_ENABLED
859
            return(1);
860
#else
861
0
            return(0);
862
0
#endif
863
0
        case XML_WITH_READER:
864
#ifdef LIBXML_READER_ENABLED
865
            return(1);
866
#else
867
0
            return(0);
868
0
#endif
869
0
        case XML_WITH_PATTERN:
870
0
#ifdef LIBXML_PATTERN_ENABLED
871
0
            return(1);
872
#else
873
            return(0);
874
#endif
875
0
        case XML_WITH_WRITER:
876
#ifdef LIBXML_WRITER_ENABLED
877
            return(1);
878
#else
879
0
            return(0);
880
0
#endif
881
0
        case XML_WITH_SAX1:
882
#ifdef LIBXML_SAX1_ENABLED
883
            return(1);
884
#else
885
0
            return(0);
886
0
#endif
887
0
        case XML_WITH_FTP:
888
#ifdef LIBXML_FTP_ENABLED
889
            return(1);
890
#else
891
0
            return(0);
892
0
#endif
893
0
        case XML_WITH_HTTP:
894
0
#ifdef LIBXML_HTTP_ENABLED
895
0
            return(1);
896
#else
897
            return(0);
898
#endif
899
0
        case XML_WITH_VALID:
900
#ifdef LIBXML_VALID_ENABLED
901
            return(1);
902
#else
903
0
            return(0);
904
0
#endif
905
0
        case XML_WITH_HTML:
906
0
#ifdef LIBXML_HTML_ENABLED
907
0
            return(1);
908
#else
909
            return(0);
910
#endif
911
0
        case XML_WITH_LEGACY:
912
#ifdef LIBXML_LEGACY_ENABLED
913
            return(1);
914
#else
915
0
            return(0);
916
0
#endif
917
0
        case XML_WITH_C14N:
918
#ifdef LIBXML_C14N_ENABLED
919
            return(1);
920
#else
921
0
            return(0);
922
0
#endif
923
0
        case XML_WITH_CATALOG:
924
0
#ifdef LIBXML_CATALOG_ENABLED
925
0
            return(1);
926
#else
927
            return(0);
928
#endif
929
0
        case XML_WITH_XPATH:
930
0
#ifdef LIBXML_XPATH_ENABLED
931
0
            return(1);
932
#else
933
            return(0);
934
#endif
935
0
        case XML_WITH_XPTR:
936
0
#ifdef LIBXML_XPTR_ENABLED
937
0
            return(1);
938
#else
939
            return(0);
940
#endif
941
0
        case XML_WITH_XINCLUDE:
942
0
#ifdef LIBXML_XINCLUDE_ENABLED
943
0
            return(1);
944
#else
945
            return(0);
946
#endif
947
0
        case XML_WITH_ICONV:
948
0
#ifdef LIBXML_ICONV_ENABLED
949
0
            return(1);
950
#else
951
            return(0);
952
#endif
953
0
        case XML_WITH_ISO8859X:
954
0
#ifdef LIBXML_ISO8859X_ENABLED
955
0
            return(1);
956
#else
957
            return(0);
958
#endif
959
0
        case XML_WITH_UNICODE:
960
#ifdef LIBXML_UNICODE_ENABLED
961
            return(1);
962
#else
963
0
            return(0);
964
0
#endif
965
0
        case XML_WITH_REGEXP:
966
#ifdef LIBXML_REGEXP_ENABLED
967
            return(1);
968
#else
969
0
            return(0);
970
0
#endif
971
0
        case XML_WITH_AUTOMATA:
972
#ifdef LIBXML_AUTOMATA_ENABLED
973
            return(1);
974
#else
975
0
            return(0);
976
0
#endif
977
0
        case XML_WITH_EXPR:
978
#ifdef LIBXML_EXPR_ENABLED
979
            return(1);
980
#else
981
0
            return(0);
982
0
#endif
983
0
        case XML_WITH_SCHEMAS:
984
#ifdef LIBXML_SCHEMAS_ENABLED
985
            return(1);
986
#else
987
0
            return(0);
988
0
#endif
989
0
        case XML_WITH_SCHEMATRON:
990
#ifdef LIBXML_SCHEMATRON_ENABLED
991
            return(1);
992
#else
993
0
            return(0);
994
0
#endif
995
0
        case XML_WITH_MODULES:
996
0
#ifdef LIBXML_MODULES_ENABLED
997
0
            return(1);
998
#else
999
            return(0);
1000
#endif
1001
0
        case XML_WITH_DEBUG:
1002
0
#ifdef LIBXML_DEBUG_ENABLED
1003
0
            return(1);
1004
#else
1005
            return(0);
1006
#endif
1007
0
        case XML_WITH_DEBUG_MEM:
1008
#ifdef DEBUG_MEMORY_LOCATION
1009
            return(1);
1010
#else
1011
0
            return(0);
1012
0
#endif
1013
0
        case XML_WITH_DEBUG_RUN:
1014
0
            return(0);
1015
0
        case XML_WITH_ZLIB:
1016
#ifdef LIBXML_ZLIB_ENABLED
1017
            return(1);
1018
#else
1019
0
            return(0);
1020
0
#endif
1021
0
        case XML_WITH_LZMA:
1022
#ifdef LIBXML_LZMA_ENABLED
1023
            return(1);
1024
#else
1025
0
            return(0);
1026
0
#endif
1027
0
        case XML_WITH_ICU:
1028
#ifdef LIBXML_ICU_ENABLED
1029
            return(1);
1030
#else
1031
0
            return(0);
1032
0
#endif
1033
0
        default:
1034
0
      break;
1035
0
     }
1036
0
     return(0);
1037
0
}
1038
1039
/************************************************************************
1040
 *                  *
1041
 *    SAX2 defaulted attributes handling      *
1042
 *                  *
1043
 ************************************************************************/
1044
1045
/**
1046
 * xmlDetectSAX2:
1047
 * @ctxt:  an XML parser context
1048
 *
1049
 * Do the SAX2 detection and specific initialization
1050
 */
1051
static void
1052
197k
xmlDetectSAX2(xmlParserCtxtPtr ctxt) {
1053
197k
    xmlSAXHandlerPtr sax;
1054
1055
    /* Avoid unused variable warning if features are disabled. */
1056
197k
    (void) sax;
1057
1058
197k
    if (ctxt == NULL) return;
1059
197k
    sax = ctxt->sax;
1060
#ifdef LIBXML_SAX1_ENABLED
1061
    if ((sax) &&  (sax->initialized == XML_SAX2_MAGIC) &&
1062
        ((sax->startElementNs != NULL) ||
1063
         (sax->endElementNs != NULL) ||
1064
         ((sax->startElement == NULL) && (sax->endElement == NULL))))
1065
        ctxt->sax2 = 1;
1066
#else
1067
197k
    ctxt->sax2 = 1;
1068
197k
#endif /* LIBXML_SAX1_ENABLED */
1069
1070
197k
    ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
1071
197k
    ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
1072
197k
    ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
1073
197k
    if ((ctxt->str_xml==NULL) || (ctxt->str_xmlns==NULL) ||
1074
197k
    (ctxt->str_xml_ns == NULL)) {
1075
5
        xmlErrMemory(ctxt, NULL);
1076
5
    }
1077
197k
}
1078
1079
typedef struct _xmlDefAttrs xmlDefAttrs;
1080
typedef xmlDefAttrs *xmlDefAttrsPtr;
1081
struct _xmlDefAttrs {
1082
    int nbAttrs;  /* number of defaulted attributes on that element */
1083
    int maxAttrs;       /* the size of the array */
1084
#if __STDC_VERSION__ >= 199901L
1085
    /* Using a C99 flexible array member avoids UBSan errors. */
1086
    const xmlChar *values[]; /* array of localname/prefix/values/external */
1087
#else
1088
    const xmlChar *values[5];
1089
#endif
1090
};
1091
1092
/**
1093
 * xmlAttrNormalizeSpace:
1094
 * @src: the source string
1095
 * @dst: the target string
1096
 *
1097
 * Normalize the space in non CDATA attribute values:
1098
 * If the attribute type is not CDATA, then the XML processor MUST further
1099
 * process the normalized attribute value by discarding any leading and
1100
 * trailing space (#x20) characters, and by replacing sequences of space
1101
 * (#x20) characters by a single space (#x20) character.
1102
 * Note that the size of dst need to be at least src, and if one doesn't need
1103
 * to preserve dst (and it doesn't come from a dictionary or read-only) then
1104
 * passing src as dst is just fine.
1105
 *
1106
 * Returns a pointer to the normalized value (dst) or NULL if no conversion
1107
 *         is needed.
1108
 */
1109
static xmlChar *
1110
xmlAttrNormalizeSpace(const xmlChar *src, xmlChar *dst)
1111
194k
{
1112
194k
    if ((src == NULL) || (dst == NULL))
1113
0
        return(NULL);
1114
1115
214k
    while (*src == 0x20) src++;
1116
786k
    while (*src != 0) {
1117
591k
  if (*src == 0x20) {
1118
45.7k
      while (*src == 0x20) src++;
1119
11.8k
      if (*src != 0)
1120
8.81k
    *dst++ = 0x20;
1121
579k
  } else {
1122
579k
      *dst++ = *src++;
1123
579k
  }
1124
591k
    }
1125
194k
    *dst = 0;
1126
194k
    if (dst == src)
1127
176k
       return(NULL);
1128
18.0k
    return(dst);
1129
194k
}
1130
1131
/**
1132
 * xmlAttrNormalizeSpace2:
1133
 * @src: the source string
1134
 *
1135
 * Normalize the space in non CDATA attribute values, a slightly more complex
1136
 * front end to avoid allocation problems when running on attribute values
1137
 * coming from the input.
1138
 *
1139
 * Returns a pointer to the normalized value (dst) or NULL if no conversion
1140
 *         is needed.
1141
 */
1142
static const xmlChar *
1143
xmlAttrNormalizeSpace2(xmlParserCtxtPtr ctxt, xmlChar *src, int *len)
1144
12.5k
{
1145
12.5k
    int i;
1146
12.5k
    int remove_head = 0;
1147
12.5k
    int need_realloc = 0;
1148
12.5k
    const xmlChar *cur;
1149
1150
12.5k
    if ((ctxt == NULL) || (src == NULL) || (len == NULL))
1151
0
        return(NULL);
1152
12.5k
    i = *len;
1153
12.5k
    if (i <= 0)
1154
2.04k
        return(NULL);
1155
1156
10.4k
    cur = src;
1157
11.1k
    while (*cur == 0x20) {
1158
624
        cur++;
1159
624
  remove_head++;
1160
624
    }
1161
293k
    while (*cur != 0) {
1162
283k
  if (*cur == 0x20) {
1163
9.32k
      cur++;
1164
9.32k
      if ((*cur == 0x20) || (*cur == 0)) {
1165
1.07k
          need_realloc = 1;
1166
1.07k
    break;
1167
1.07k
      }
1168
9.32k
  } else
1169
274k
      cur++;
1170
283k
    }
1171
10.4k
    if (need_realloc) {
1172
1.07k
        xmlChar *ret;
1173
1174
1.07k
  ret = xmlStrndup(src + remove_head, i - remove_head + 1);
1175
1.07k
  if (ret == NULL) {
1176
2
      xmlErrMemory(ctxt, NULL);
1177
2
      return(NULL);
1178
2
  }
1179
1.07k
  xmlAttrNormalizeSpace(ret, ret);
1180
1.07k
  *len = strlen((const char *)ret);
1181
1.07k
        return(ret);
1182
9.41k
    } else if (remove_head) {
1183
412
        *len -= remove_head;
1184
412
        memmove(src, src + remove_head, 1 + *len);
1185
412
  return(src);
1186
412
    }
1187
8.99k
    return(NULL);
1188
10.4k
}
1189
1190
/**
1191
 * xmlAddDefAttrs:
1192
 * @ctxt:  an XML parser context
1193
 * @fullname:  the element fullname
1194
 * @fullattr:  the attribute fullname
1195
 * @value:  the attribute value
1196
 *
1197
 * Add a defaulted attribute for an element
1198
 */
1199
static void
1200
xmlAddDefAttrs(xmlParserCtxtPtr ctxt,
1201
               const xmlChar *fullname,
1202
               const xmlChar *fullattr,
1203
204k
               const xmlChar *value) {
1204
204k
    xmlDefAttrsPtr defaults;
1205
204k
    int len;
1206
204k
    const xmlChar *name;
1207
204k
    const xmlChar *prefix;
1208
1209
    /*
1210
     * Allows to detect attribute redefinitions
1211
     */
1212
204k
    if (ctxt->attsSpecial != NULL) {
1213
189k
        if (xmlHashLookup2(ctxt->attsSpecial, fullname, fullattr) != NULL)
1214
40.1k
      return;
1215
189k
    }
1216
1217
164k
    if (ctxt->attsDefault == NULL) {
1218
14.6k
        ctxt->attsDefault = xmlHashCreateDict(10, ctxt->dict);
1219
14.6k
  if (ctxt->attsDefault == NULL)
1220
18
      goto mem_error;
1221
14.6k
    }
1222
1223
    /*
1224
     * split the element name into prefix:localname , the string found
1225
     * are within the DTD and then not associated to namespace names.
1226
     */
1227
164k
    name = xmlSplitQName3(fullname, &len);
1228
164k
    if (name == NULL) {
1229
132k
        name = xmlDictLookup(ctxt->dict, fullname, -1);
1230
132k
  prefix = NULL;
1231
132k
    } else {
1232
31.8k
        name = xmlDictLookup(ctxt->dict, name, -1);
1233
31.8k
  prefix = xmlDictLookup(ctxt->dict, fullname, len);
1234
31.8k
    }
1235
1236
    /*
1237
     * make sure there is some storage
1238
     */
1239
164k
    defaults = xmlHashLookup2(ctxt->attsDefault, name, prefix);
1240
164k
    if (defaults == NULL) {
1241
33.6k
        defaults = (xmlDefAttrsPtr) xmlMalloc(sizeof(xmlDefAttrs) +
1242
33.6k
                     (4 * 5) * sizeof(const xmlChar *));
1243
33.6k
  if (defaults == NULL)
1244
4
      goto mem_error;
1245
33.6k
  defaults->nbAttrs = 0;
1246
33.6k
  defaults->maxAttrs = 4;
1247
33.6k
  if (xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix,
1248
33.6k
                          defaults, NULL) < 0) {
1249
1
      xmlFree(defaults);
1250
1
      goto mem_error;
1251
1
  }
1252
130k
    } else if (defaults->nbAttrs >= defaults->maxAttrs) {
1253
21.3k
        xmlDefAttrsPtr temp;
1254
1255
21.3k
        temp = (xmlDefAttrsPtr) xmlRealloc(defaults, sizeof(xmlDefAttrs) +
1256
21.3k
           (2 * defaults->maxAttrs * 5) * sizeof(const xmlChar *));
1257
21.3k
  if (temp == NULL)
1258
2
      goto mem_error;
1259
21.3k
  defaults = temp;
1260
21.3k
  defaults->maxAttrs *= 2;
1261
21.3k
  if (xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix,
1262
21.3k
                          defaults, NULL) < 0) {
1263
0
      xmlFree(defaults);
1264
0
      goto mem_error;
1265
0
  }
1266
21.3k
    }
1267
1268
    /*
1269
     * Split the element name into prefix:localname , the string found
1270
     * are within the DTD and hen not associated to namespace names.
1271
     */
1272
164k
    name = xmlSplitQName3(fullattr, &len);
1273
164k
    if (name == NULL) {
1274
118k
        name = xmlDictLookup(ctxt->dict, fullattr, -1);
1275
118k
  prefix = NULL;
1276
118k
    } else {
1277
45.4k
        name = xmlDictLookup(ctxt->dict, name, -1);
1278
45.4k
  prefix = xmlDictLookup(ctxt->dict, fullattr, len);
1279
45.4k
    }
1280
1281
164k
    defaults->values[5 * defaults->nbAttrs] = name;
1282
164k
    defaults->values[5 * defaults->nbAttrs + 1] = prefix;
1283
    /* intern the string and precompute the end */
1284
164k
    len = xmlStrlen(value);
1285
164k
    value = xmlDictLookup(ctxt->dict, value, len);
1286
164k
    if (value == NULL)
1287
1
        goto mem_error;
1288
164k
    defaults->values[5 * defaults->nbAttrs + 2] = value;
1289
164k
    defaults->values[5 * defaults->nbAttrs + 3] = value + len;
1290
164k
    if (ctxt->external)
1291
10
        defaults->values[5 * defaults->nbAttrs + 4] = BAD_CAST "external";
1292
164k
    else
1293
164k
        defaults->values[5 * defaults->nbAttrs + 4] = NULL;
1294
164k
    defaults->nbAttrs++;
1295
1296
164k
    return;
1297
1298
26
mem_error:
1299
26
    xmlErrMemory(ctxt, NULL);
1300
26
    return;
1301
164k
}
1302
1303
/**
1304
 * xmlAddSpecialAttr:
1305
 * @ctxt:  an XML parser context
1306
 * @fullname:  the element fullname
1307
 * @fullattr:  the attribute fullname
1308
 * @type:  the attribute type
1309
 *
1310
 * Register this attribute type
1311
 */
1312
static void
1313
xmlAddSpecialAttr(xmlParserCtxtPtr ctxt,
1314
      const xmlChar *fullname,
1315
      const xmlChar *fullattr,
1316
      int type)
1317
208k
{
1318
208k
    if (ctxt->attsSpecial == NULL) {
1319
15.3k
        ctxt->attsSpecial = xmlHashCreateDict(10, ctxt->dict);
1320
15.3k
  if (ctxt->attsSpecial == NULL)
1321
31
      goto mem_error;
1322
15.3k
    }
1323
1324
208k
    if (xmlHashLookup2(ctxt->attsSpecial, fullname, fullattr) != NULL)
1325
42.2k
        return;
1326
1327
166k
    xmlHashAddEntry2(ctxt->attsSpecial, fullname, fullattr,
1328
166k
                     (void *) (ptrdiff_t) type);
1329
166k
    return;
1330
1331
31
mem_error:
1332
31
    xmlErrMemory(ctxt, NULL);
1333
31
    return;
1334
208k
}
1335
1336
/**
1337
 * xmlCleanSpecialAttrCallback:
1338
 *
1339
 * Removes CDATA attributes from the special attribute table
1340
 */
1341
static void
1342
xmlCleanSpecialAttrCallback(void *payload, void *data,
1343
                            const xmlChar *fullname, const xmlChar *fullattr,
1344
33.5k
                            const xmlChar *unused ATTRIBUTE_UNUSED) {
1345
33.5k
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) data;
1346
1347
33.5k
    if (((ptrdiff_t) payload) == XML_ATTRIBUTE_CDATA) {
1348
3.33k
        xmlHashRemoveEntry2(ctxt->attsSpecial, fullname, fullattr, NULL);
1349
3.33k
    }
1350
33.5k
}
1351
1352
/**
1353
 * xmlCleanSpecialAttr:
1354
 * @ctxt:  an XML parser context
1355
 *
1356
 * Trim the list of attributes defined to remove all those of type
1357
 * CDATA as they are not special. This call should be done when finishing
1358
 * to parse the DTD and before starting to parse the document root.
1359
 */
1360
static void
1361
xmlCleanSpecialAttr(xmlParserCtxtPtr ctxt)
1362
24.5k
{
1363
24.5k
    if (ctxt->attsSpecial == NULL)
1364
15.9k
        return;
1365
1366
8.56k
    xmlHashScanFull(ctxt->attsSpecial, xmlCleanSpecialAttrCallback, ctxt);
1367
1368
8.56k
    if (xmlHashSize(ctxt->attsSpecial) == 0) {
1369
228
        xmlHashFree(ctxt->attsSpecial, NULL);
1370
228
        ctxt->attsSpecial = NULL;
1371
228
    }
1372
8.56k
    return;
1373
24.5k
}
1374
1375
/**
1376
 * xmlCheckLanguageID:
1377
 * @lang:  pointer to the string value
1378
 *
1379
 * Checks that the value conforms to the LanguageID production:
1380
 *
1381
 * NOTE: this is somewhat deprecated, those productions were removed from
1382
 *       the XML Second edition.
1383
 *
1384
 * [33] LanguageID ::= Langcode ('-' Subcode)*
1385
 * [34] Langcode ::= ISO639Code |  IanaCode |  UserCode
1386
 * [35] ISO639Code ::= ([a-z] | [A-Z]) ([a-z] | [A-Z])
1387
 * [36] IanaCode ::= ('i' | 'I') '-' ([a-z] | [A-Z])+
1388
 * [37] UserCode ::= ('x' | 'X') '-' ([a-z] | [A-Z])+
1389
 * [38] Subcode ::= ([a-z] | [A-Z])+
1390
 *
1391
 * The current REC reference the successors of RFC 1766, currently 5646
1392
 *
1393
 * http://www.rfc-editor.org/rfc/rfc5646.txt
1394
 * langtag       = language
1395
 *                 ["-" script]
1396
 *                 ["-" region]
1397
 *                 *("-" variant)
1398
 *                 *("-" extension)
1399
 *                 ["-" privateuse]
1400
 * language      = 2*3ALPHA            ; shortest ISO 639 code
1401
 *                 ["-" extlang]       ; sometimes followed by
1402
 *                                     ; extended language subtags
1403
 *               / 4ALPHA              ; or reserved for future use
1404
 *               / 5*8ALPHA            ; or registered language subtag
1405
 *
1406
 * extlang       = 3ALPHA              ; selected ISO 639 codes
1407
 *                 *2("-" 3ALPHA)      ; permanently reserved
1408
 *
1409
 * script        = 4ALPHA              ; ISO 15924 code
1410
 *
1411
 * region        = 2ALPHA              ; ISO 3166-1 code
1412
 *               / 3DIGIT              ; UN M.49 code
1413
 *
1414
 * variant       = 5*8alphanum         ; registered variants
1415
 *               / (DIGIT 3alphanum)
1416
 *
1417
 * extension     = singleton 1*("-" (2*8alphanum))
1418
 *
1419
 *                                     ; Single alphanumerics
1420
 *                                     ; "x" reserved for private use
1421
 * singleton     = DIGIT               ; 0 - 9
1422
 *               / %x41-57             ; A - W
1423
 *               / %x59-5A             ; Y - Z
1424
 *               / %x61-77             ; a - w
1425
 *               / %x79-7A             ; y - z
1426
 *
1427
 * it sounds right to still allow Irregular i-xxx IANA and user codes too
1428
 * The parser below doesn't try to cope with extension or privateuse
1429
 * that could be added but that's not interoperable anyway
1430
 *
1431
 * Returns 1 if correct 0 otherwise
1432
 **/
1433
int
1434
xmlCheckLanguageID(const xmlChar * lang)
1435
0
{
1436
0
    const xmlChar *cur = lang, *nxt;
1437
1438
0
    if (cur == NULL)
1439
0
        return (0);
1440
0
    if (((cur[0] == 'i') && (cur[1] == '-')) ||
1441
0
        ((cur[0] == 'I') && (cur[1] == '-')) ||
1442
0
        ((cur[0] == 'x') && (cur[1] == '-')) ||
1443
0
        ((cur[0] == 'X') && (cur[1] == '-'))) {
1444
        /*
1445
         * Still allow IANA code and user code which were coming
1446
         * from the previous version of the XML-1.0 specification
1447
         * it's deprecated but we should not fail
1448
         */
1449
0
        cur += 2;
1450
0
        while (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
1451
0
               ((cur[0] >= 'a') && (cur[0] <= 'z')))
1452
0
            cur++;
1453
0
        return(cur[0] == 0);
1454
0
    }
1455
0
    nxt = cur;
1456
0
    while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
1457
0
           ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
1458
0
           nxt++;
1459
0
    if (nxt - cur >= 4) {
1460
        /*
1461
         * Reserved
1462
         */
1463
0
        if ((nxt - cur > 8) || (nxt[0] != 0))
1464
0
            return(0);
1465
0
        return(1);
1466
0
    }
1467
0
    if (nxt - cur < 2)
1468
0
        return(0);
1469
    /* we got an ISO 639 code */
1470
0
    if (nxt[0] == 0)
1471
0
        return(1);
1472
0
    if (nxt[0] != '-')
1473
0
        return(0);
1474
1475
0
    nxt++;
1476
0
    cur = nxt;
1477
    /* now we can have extlang or script or region or variant */
1478
0
    if ((nxt[0] >= '0') && (nxt[0] <= '9'))
1479
0
        goto region_m49;
1480
1481
0
    while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
1482
0
           ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
1483
0
           nxt++;
1484
0
    if (nxt - cur == 4)
1485
0
        goto script;
1486
0
    if (nxt - cur == 2)
1487
0
        goto region;
1488
0
    if ((nxt - cur >= 5) && (nxt - cur <= 8))
1489
0
        goto variant;
1490
0
    if (nxt - cur != 3)
1491
0
        return(0);
1492
    /* we parsed an extlang */
1493
0
    if (nxt[0] == 0)
1494
0
        return(1);
1495
0
    if (nxt[0] != '-')
1496
0
        return(0);
1497
1498
0
    nxt++;
1499
0
    cur = nxt;
1500
    /* now we can have script or region or variant */
1501
0
    if ((nxt[0] >= '0') && (nxt[0] <= '9'))
1502
0
        goto region_m49;
1503
1504
0
    while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
1505
0
           ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
1506
0
           nxt++;
1507
0
    if (nxt - cur == 2)
1508
0
        goto region;
1509
0
    if ((nxt - cur >= 5) && (nxt - cur <= 8))
1510
0
        goto variant;
1511
0
    if (nxt - cur != 4)
1512
0
        return(0);
1513
    /* we parsed a script */
1514
0
script:
1515
0
    if (nxt[0] == 0)
1516
0
        return(1);
1517
0
    if (nxt[0] != '-')
1518
0
        return(0);
1519
1520
0
    nxt++;
1521
0
    cur = nxt;
1522
    /* now we can have region or variant */
1523
0
    if ((nxt[0] >= '0') && (nxt[0] <= '9'))
1524
0
        goto region_m49;
1525
1526
0
    while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
1527
0
           ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
1528
0
           nxt++;
1529
1530
0
    if ((nxt - cur >= 5) && (nxt - cur <= 8))
1531
0
        goto variant;
1532
0
    if (nxt - cur != 2)
1533
0
        return(0);
1534
    /* we parsed a region */
1535
0
region:
1536
0
    if (nxt[0] == 0)
1537
0
        return(1);
1538
0
    if (nxt[0] != '-')
1539
0
        return(0);
1540
1541
0
    nxt++;
1542
0
    cur = nxt;
1543
    /* now we can just have a variant */
1544
0
    while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
1545
0
           ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
1546
0
           nxt++;
1547
1548
0
    if ((nxt - cur < 5) || (nxt - cur > 8))
1549
0
        return(0);
1550
1551
    /* we parsed a variant */
1552
0
variant:
1553
0
    if (nxt[0] == 0)
1554
0
        return(1);
1555
0
    if (nxt[0] != '-')
1556
0
        return(0);
1557
    /* extensions and private use subtags not checked */
1558
0
    return (1);
1559
1560
0
region_m49:
1561
0
    if (((nxt[1] >= '0') && (nxt[1] <= '9')) &&
1562
0
        ((nxt[2] >= '0') && (nxt[2] <= '9'))) {
1563
0
        nxt += 3;
1564
0
        goto region;
1565
0
    }
1566
0
    return(0);
1567
0
}
1568
1569
/************************************************************************
1570
 *                  *
1571
 *    Parser stacks related functions and macros    *
1572
 *                  *
1573
 ************************************************************************/
1574
1575
static xmlEntityPtr xmlParseStringEntityRef(xmlParserCtxtPtr ctxt,
1576
                                            const xmlChar ** str);
1577
1578
#ifdef SAX2
1579
/**
1580
 * nsPush:
1581
 * @ctxt:  an XML parser context
1582
 * @prefix:  the namespace prefix or NULL
1583
 * @URL:  the namespace name
1584
 *
1585
 * Pushes a new parser namespace on top of the ns stack
1586
 *
1587
 * Returns -1 in case of error, -2 if the namespace should be discarded
1588
 *     and the index in the stack otherwise.
1589
 */
1590
static int
1591
nsPush(xmlParserCtxtPtr ctxt, const xmlChar *prefix, const xmlChar *URL)
1592
319k
{
1593
319k
    if (ctxt->options & XML_PARSE_NSCLEAN) {
1594
0
        int i;
1595
0
  for (i = ctxt->nsNr - 2;i >= 0;i -= 2) {
1596
0
      if (ctxt->nsTab[i] == prefix) {
1597
    /* in scope */
1598
0
          if (ctxt->nsTab[i + 1] == URL)
1599
0
        return(-2);
1600
    /* out of scope keep it */
1601
0
    break;
1602
0
      }
1603
0
  }
1604
0
    }
1605
319k
    if ((ctxt->nsMax == 0) || (ctxt->nsTab == NULL)) {
1606
81.0k
  ctxt->nsMax = 10;
1607
81.0k
  ctxt->nsNr = 0;
1608
81.0k
  ctxt->nsTab = (const xmlChar **)
1609
81.0k
                xmlMalloc(ctxt->nsMax * sizeof(xmlChar *));
1610
81.0k
  if (ctxt->nsTab == NULL) {
1611
27
      xmlErrMemory(ctxt, NULL);
1612
27
      ctxt->nsMax = 0;
1613
27
            return (-1);
1614
27
  }
1615
238k
    } else if (ctxt->nsNr >= ctxt->nsMax) {
1616
2.26k
        const xmlChar ** tmp;
1617
2.26k
        ctxt->nsMax *= 2;
1618
2.26k
        tmp = (const xmlChar **) xmlRealloc((char *) ctxt->nsTab,
1619
2.26k
            ctxt->nsMax * sizeof(ctxt->nsTab[0]));
1620
2.26k
        if (tmp == NULL) {
1621
9
            xmlErrMemory(ctxt, NULL);
1622
9
      ctxt->nsMax /= 2;
1623
9
            return (-1);
1624
9
        }
1625
2.25k
  ctxt->nsTab = tmp;
1626
2.25k
    }
1627
319k
    ctxt->nsTab[ctxt->nsNr++] = prefix;
1628
319k
    ctxt->nsTab[ctxt->nsNr++] = URL;
1629
319k
    return (ctxt->nsNr);
1630
319k
}
1631
/**
1632
 * nsPop:
1633
 * @ctxt: an XML parser context
1634
 * @nr:  the number to pop
1635
 *
1636
 * Pops the top @nr parser prefix/namespace from the ns stack
1637
 *
1638
 * Returns the number of namespaces removed
1639
 */
1640
static int
1641
nsPop(xmlParserCtxtPtr ctxt, int nr)
1642
206k
{
1643
206k
    int i;
1644
1645
206k
    if (ctxt->nsTab == NULL) return(0);
1646
206k
    if (ctxt->nsNr < nr) {
1647
0
        xmlGenericError(xmlGenericErrorContext, "Pbm popping %d NS\n", nr);
1648
0
        nr = ctxt->nsNr;
1649
0
    }
1650
206k
    if (ctxt->nsNr <= 0)
1651
0
        return (0);
1652
1653
774k
    for (i = 0;i < nr;i++) {
1654
567k
         ctxt->nsNr--;
1655
567k
   ctxt->nsTab[ctxt->nsNr] = NULL;
1656
567k
    }
1657
206k
    return(nr);
1658
206k
}
1659
#endif
1660
1661
static int
1662
94.3k
xmlCtxtGrowAttrs(xmlParserCtxtPtr ctxt, int nr) {
1663
94.3k
    const xmlChar **atts;
1664
94.3k
    int *attallocs;
1665
94.3k
    int maxatts;
1666
1667
94.3k
    if (nr + 5 > ctxt->maxatts) {
1668
94.3k
  maxatts = ctxt->maxatts == 0 ? 55 : (nr + 5) * 2;
1669
94.3k
  atts = (const xmlChar **) xmlMalloc(
1670
94.3k
             maxatts * sizeof(const xmlChar *));
1671
94.3k
  if (atts == NULL) goto mem_error;
1672
94.3k
  attallocs = (int *) xmlRealloc((void *) ctxt->attallocs,
1673
94.3k
                               (maxatts / 5) * sizeof(int));
1674
94.3k
  if (attallocs == NULL) {
1675
5
            xmlFree(atts);
1676
5
            goto mem_error;
1677
5
        }
1678
94.3k
        if (ctxt->maxatts > 0)
1679
419
            memcpy(atts, ctxt->atts, ctxt->maxatts * sizeof(const xmlChar *));
1680
94.3k
        xmlFree(ctxt->atts);
1681
94.3k
  ctxt->atts = atts;
1682
94.3k
  ctxt->attallocs = attallocs;
1683
94.3k
  ctxt->maxatts = maxatts;
1684
94.3k
    }
1685
94.3k
    return(ctxt->maxatts);
1686
23
mem_error:
1687
23
    xmlErrMemory(ctxt, NULL);
1688
23
    return(-1);
1689
94.3k
}
1690
1691
/**
1692
 * inputPush:
1693
 * @ctxt:  an XML parser context
1694
 * @value:  the parser input
1695
 *
1696
 * Pushes a new parser input on top of the input stack
1697
 *
1698
 * Returns -1 in case of error, the index in the stack otherwise
1699
 */
1700
int
1701
inputPush(xmlParserCtxtPtr ctxt, xmlParserInputPtr value)
1702
263k
{
1703
263k
    if ((ctxt == NULL) || (value == NULL))
1704
0
        return(-1);
1705
263k
    if (ctxt->inputNr >= ctxt->inputMax) {
1706
0
        size_t newSize = ctxt->inputMax * 2;
1707
0
        xmlParserInputPtr *tmp;
1708
1709
0
        tmp = (xmlParserInputPtr *) xmlRealloc(ctxt->inputTab,
1710
0
                                               newSize * sizeof(*tmp));
1711
0
        if (tmp == NULL) {
1712
0
            xmlErrMemory(ctxt, NULL);
1713
0
            return (-1);
1714
0
        }
1715
0
        ctxt->inputTab = tmp;
1716
0
        ctxt->inputMax = newSize;
1717
0
    }
1718
263k
    ctxt->inputTab[ctxt->inputNr] = value;
1719
263k
    ctxt->input = value;
1720
263k
    return (ctxt->inputNr++);
1721
263k
}
1722
/**
1723
 * inputPop:
1724
 * @ctxt: an XML parser context
1725
 *
1726
 * Pops the top parser input from the input stack
1727
 *
1728
 * Returns the input just removed
1729
 */
1730
xmlParserInputPtr
1731
inputPop(xmlParserCtxtPtr ctxt)
1732
1.00M
{
1733
1.00M
    xmlParserInputPtr ret;
1734
1735
1.00M
    if (ctxt == NULL)
1736
0
        return(NULL);
1737
1.00M
    if (ctxt->inputNr <= 0)
1738
739k
        return (NULL);
1739
261k
    ctxt->inputNr--;
1740
261k
    if (ctxt->inputNr > 0)
1741
65.8k
        ctxt->input = ctxt->inputTab[ctxt->inputNr - 1];
1742
195k
    else
1743
195k
        ctxt->input = NULL;
1744
261k
    ret = ctxt->inputTab[ctxt->inputNr];
1745
261k
    ctxt->inputTab[ctxt->inputNr] = NULL;
1746
261k
    return (ret);
1747
1.00M
}
1748
/**
1749
 * nodePush:
1750
 * @ctxt:  an XML parser context
1751
 * @value:  the element node
1752
 *
1753
 * Pushes a new element node on top of the node stack
1754
 *
1755
 * Returns -1 in case of error, the index in the stack otherwise
1756
 */
1757
int
1758
nodePush(xmlParserCtxtPtr ctxt, xmlNodePtr value)
1759
1.71M
{
1760
1.71M
    if (ctxt == NULL) return(0);
1761
1.71M
    if (ctxt->nodeNr >= ctxt->nodeMax) {
1762
2.49k
        xmlNodePtr *tmp;
1763
1764
2.49k
  tmp = (xmlNodePtr *) xmlRealloc(ctxt->nodeTab,
1765
2.49k
                                      ctxt->nodeMax * 2 *
1766
2.49k
                                      sizeof(ctxt->nodeTab[0]));
1767
2.49k
        if (tmp == NULL) {
1768
1
            xmlErrMemory(ctxt, NULL);
1769
1
            return (-1);
1770
1
        }
1771
2.49k
        ctxt->nodeTab = tmp;
1772
2.49k
  ctxt->nodeMax *= 2;
1773
2.49k
    }
1774
1.71M
    if ((((unsigned int) ctxt->nodeNr) > xmlParserMaxDepth) &&
1775
1.71M
        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
1776
0
  xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
1777
0
     "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
1778
0
        xmlParserMaxDepth);
1779
0
  xmlHaltParser(ctxt);
1780
0
  return(-1);
1781
0
    }
1782
1.71M
    ctxt->nodeTab[ctxt->nodeNr] = value;
1783
1.71M
    ctxt->node = value;
1784
1.71M
    return (ctxt->nodeNr++);
1785
1.71M
}
1786
1787
/**
1788
 * nodePop:
1789
 * @ctxt: an XML parser context
1790
 *
1791
 * Pops the top element node from the node stack
1792
 *
1793
 * Returns the node just removed
1794
 */
1795
xmlNodePtr
1796
nodePop(xmlParserCtxtPtr ctxt)
1797
1.84M
{
1798
1.84M
    xmlNodePtr ret;
1799
1800
1.84M
    if (ctxt == NULL) return(NULL);
1801
1.84M
    if (ctxt->nodeNr <= 0)
1802
191k
        return (NULL);
1803
1.65M
    ctxt->nodeNr--;
1804
1.65M
    if (ctxt->nodeNr > 0)
1805
1.56M
        ctxt->node = ctxt->nodeTab[ctxt->nodeNr - 1];
1806
91.2k
    else
1807
91.2k
        ctxt->node = NULL;
1808
1.65M
    ret = ctxt->nodeTab[ctxt->nodeNr];
1809
1.65M
    ctxt->nodeTab[ctxt->nodeNr] = NULL;
1810
1.65M
    return (ret);
1811
1.84M
}
1812
1813
/**
1814
 * nameNsPush:
1815
 * @ctxt:  an XML parser context
1816
 * @value:  the element name
1817
 * @prefix:  the element prefix
1818
 * @URI:  the element namespace name
1819
 * @line:  the current line number for error messages
1820
 * @nsNr:  the number of namespaces pushed on the namespace table
1821
 *
1822
 * Pushes a new element name/prefix/URL on top of the name stack
1823
 *
1824
 * Returns -1 in case of error, the index in the stack otherwise
1825
 */
1826
static int
1827
nameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value,
1828
           const xmlChar *prefix, const xmlChar *URI, int line, int nsNr)
1829
2.18M
{
1830
2.18M
    xmlStartTag *tag;
1831
1832
2.18M
    if (ctxt->nameNr >= ctxt->nameMax) {
1833
7.50k
        const xmlChar * *tmp;
1834
7.50k
        xmlStartTag *tmp2;
1835
7.50k
        ctxt->nameMax *= 2;
1836
7.50k
        tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,
1837
7.50k
                                    ctxt->nameMax *
1838
7.50k
                                    sizeof(ctxt->nameTab[0]));
1839
7.50k
        if (tmp == NULL) {
1840
5
      ctxt->nameMax /= 2;
1841
5
      goto mem_error;
1842
5
        }
1843
7.49k
  ctxt->nameTab = tmp;
1844
7.49k
        tmp2 = (xmlStartTag *) xmlRealloc((void * *)ctxt->pushTab,
1845
7.49k
                                    ctxt->nameMax *
1846
7.49k
                                    sizeof(ctxt->pushTab[0]));
1847
7.49k
        if (tmp2 == NULL) {
1848
2
      ctxt->nameMax /= 2;
1849
2
      goto mem_error;
1850
2
        }
1851
7.49k
  ctxt->pushTab = tmp2;
1852
2.17M
    } else if (ctxt->pushTab == NULL) {
1853
127k
        ctxt->pushTab = (xmlStartTag *) xmlMalloc(ctxt->nameMax *
1854
127k
                                            sizeof(ctxt->pushTab[0]));
1855
127k
        if (ctxt->pushTab == NULL)
1856
46
            goto mem_error;
1857
127k
    }
1858
2.18M
    ctxt->nameTab[ctxt->nameNr] = value;
1859
2.18M
    ctxt->name = value;
1860
2.18M
    tag = &ctxt->pushTab[ctxt->nameNr];
1861
2.18M
    tag->prefix = prefix;
1862
2.18M
    tag->URI = URI;
1863
2.18M
    tag->line = line;
1864
2.18M
    tag->nsNr = nsNr;
1865
2.18M
    return (ctxt->nameNr++);
1866
53
mem_error:
1867
53
    xmlErrMemory(ctxt, NULL);
1868
53
    return (-1);
1869
2.18M
}
1870
#ifdef LIBXML_PUSH_ENABLED
1871
/**
1872
 * nameNsPop:
1873
 * @ctxt: an XML parser context
1874
 *
1875
 * Pops the top element/prefix/URI name from the name stack
1876
 *
1877
 * Returns the name just removed
1878
 */
1879
static const xmlChar *
1880
nameNsPop(xmlParserCtxtPtr ctxt)
1881
{
1882
    const xmlChar *ret;
1883
1884
    if (ctxt->nameNr <= 0)
1885
        return (NULL);
1886
    ctxt->nameNr--;
1887
    if (ctxt->nameNr > 0)
1888
        ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
1889
    else
1890
        ctxt->name = NULL;
1891
    ret = ctxt->nameTab[ctxt->nameNr];
1892
    ctxt->nameTab[ctxt->nameNr] = NULL;
1893
    return (ret);
1894
}
1895
#endif /* LIBXML_PUSH_ENABLED */
1896
1897
/**
1898
 * namePush:
1899
 * @ctxt:  an XML parser context
1900
 * @value:  the element name
1901
 *
1902
 * Pushes a new element name on top of the name stack
1903
 *
1904
 * Returns -1 in case of error, the index in the stack otherwise
1905
 */
1906
int
1907
namePush(xmlParserCtxtPtr ctxt, const xmlChar * value)
1908
0
{
1909
0
    if (ctxt == NULL) return (-1);
1910
1911
0
    if (ctxt->nameNr >= ctxt->nameMax) {
1912
0
        const xmlChar * *tmp;
1913
0
        tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,
1914
0
                                    ctxt->nameMax * 2 *
1915
0
                                    sizeof(ctxt->nameTab[0]));
1916
0
        if (tmp == NULL) {
1917
0
      goto mem_error;
1918
0
        }
1919
0
  ctxt->nameTab = tmp;
1920
0
        ctxt->nameMax *= 2;
1921
0
    }
1922
0
    ctxt->nameTab[ctxt->nameNr] = value;
1923
0
    ctxt->name = value;
1924
0
    return (ctxt->nameNr++);
1925
0
mem_error:
1926
0
    xmlErrMemory(ctxt, NULL);
1927
0
    return (-1);
1928
0
}
1929
/**
1930
 * namePop:
1931
 * @ctxt: an XML parser context
1932
 *
1933
 * Pops the top element name from the name stack
1934
 *
1935
 * Returns the name just removed
1936
 */
1937
const xmlChar *
1938
namePop(xmlParserCtxtPtr ctxt)
1939
2.00M
{
1940
2.00M
    const xmlChar *ret;
1941
1942
2.00M
    if ((ctxt == NULL) || (ctxt->nameNr <= 0))
1943
25
        return (NULL);
1944
2.00M
    ctxt->nameNr--;
1945
2.00M
    if (ctxt->nameNr > 0)
1946
1.83M
        ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
1947
164k
    else
1948
164k
        ctxt->name = NULL;
1949
2.00M
    ret = ctxt->nameTab[ctxt->nameNr];
1950
2.00M
    ctxt->nameTab[ctxt->nameNr] = NULL;
1951
2.00M
    return (ret);
1952
2.00M
}
1953
1954
2.26M
static int spacePush(xmlParserCtxtPtr ctxt, int val) {
1955
2.26M
    if (ctxt->spaceNr >= ctxt->spaceMax) {
1956
8.02k
        int *tmp;
1957
1958
8.02k
  ctxt->spaceMax *= 2;
1959
8.02k
        tmp = (int *) xmlRealloc(ctxt->spaceTab,
1960
8.02k
                           ctxt->spaceMax * sizeof(ctxt->spaceTab[0]));
1961
8.02k
        if (tmp == NULL) {
1962
17
      xmlErrMemory(ctxt, NULL);
1963
17
      ctxt->spaceMax /=2;
1964
17
      return(-1);
1965
17
  }
1966
8.00k
  ctxt->spaceTab = tmp;
1967
8.00k
    }
1968
2.26M
    ctxt->spaceTab[ctxt->spaceNr] = val;
1969
2.26M
    ctxt->space = &ctxt->spaceTab[ctxt->spaceNr];
1970
2.26M
    return(ctxt->spaceNr++);
1971
2.26M
}
1972
1973
2.08M
static int spacePop(xmlParserCtxtPtr ctxt) {
1974
2.08M
    int ret;
1975
2.08M
    if (ctxt->spaceNr <= 0) return(0);
1976
2.08M
    ctxt->spaceNr--;
1977
2.08M
    if (ctxt->spaceNr > 0)
1978
2.08M
  ctxt->space = &ctxt->spaceTab[ctxt->spaceNr - 1];
1979
0
    else
1980
0
        ctxt->space = &ctxt->spaceTab[0];
1981
2.08M
    ret = ctxt->spaceTab[ctxt->spaceNr];
1982
2.08M
    ctxt->spaceTab[ctxt->spaceNr] = -1;
1983
2.08M
    return(ret);
1984
2.08M
}
1985
1986
/*
1987
 * Macros for accessing the content. Those should be used only by the parser,
1988
 * and not exported.
1989
 *
1990
 * Dirty macros, i.e. one often need to make assumption on the context to
1991
 * use them
1992
 *
1993
 *   CUR_PTR return the current pointer to the xmlChar to be parsed.
1994
 *           To be used with extreme caution since operations consuming
1995
 *           characters may move the input buffer to a different location !
1996
 *   CUR     returns the current xmlChar value, i.e. a 8 bit value if compiled
1997
 *           This should be used internally by the parser
1998
 *           only to compare to ASCII values otherwise it would break when
1999
 *           running with UTF-8 encoding.
2000
 *   RAW     same as CUR but in the input buffer, bypass any token
2001
 *           extraction that may have been done
2002
 *   NXT(n)  returns the n'th next xmlChar. Same as CUR is should be used only
2003
 *           to compare on ASCII based substring.
2004
 *   SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
2005
 *           strings without newlines within the parser.
2006
 *   NEXT1(l) Skip 1 xmlChar, and must also be used only to skip 1 non-newline ASCII
2007
 *           defined char within the parser.
2008
 * Clean macros, not dependent of an ASCII context, expect UTF-8 encoding
2009
 *
2010
 *   NEXT    Skip to the next character, this does the proper decoding
2011
 *           in UTF-8 mode. It also pop-up unfinished entities on the fly.
2012
 *   NEXTL(l) Skip the current unicode character of l xmlChars long.
2013
 *   CUR_CHAR(l) returns the current unicode character (int), set l
2014
 *           to the number of xmlChars used for the encoding [0-5].
2015
 *   CUR_SCHAR  same but operate on a string instead of the context
2016
 *   COPY_BUF  copy the current unicode char to the target buffer, increment
2017
 *            the index
2018
 *   GROW, SHRINK  handling of input buffers
2019
 */
2020
2021
47.8M
#define RAW (*ctxt->input->cur)
2022
27.5M
#define CUR (*ctxt->input->cur)
2023
132M
#define NXT(val) ctxt->input->cur[(val)]
2024
6.24M
#define CUR_PTR ctxt->input->cur
2025
448k
#define BASE_PTR ctxt->input->base
2026
2027
#define CMP4( s, c1, c2, c3, c4 ) \
2028
17.3M
  ( ((unsigned char *) s)[ 0 ] == c1 && ((unsigned char *) s)[ 1 ] == c2 && \
2029
8.82M
    ((unsigned char *) s)[ 2 ] == c3 && ((unsigned char *) s)[ 3 ] == c4 )
2030
#define CMP5( s, c1, c2, c3, c4, c5 ) \
2031
16.1M
  ( CMP4( s, c1, c2, c3, c4 ) && ((unsigned char *) s)[ 4 ] == c5 )
2032
#define CMP6( s, c1, c2, c3, c4, c5, c6 ) \
2033
14.6M
  ( CMP5( s, c1, c2, c3, c4, c5 ) && ((unsigned char *) s)[ 5 ] == c6 )
2034
#define CMP7( s, c1, c2, c3, c4, c5, c6, c7 ) \
2035
13.4M
  ( CMP6( s, c1, c2, c3, c4, c5, c6 ) && ((unsigned char *) s)[ 6 ] == c7 )
2036
#define CMP8( s, c1, c2, c3, c4, c5, c6, c7, c8 ) \
2037
12.5M
  ( CMP7( s, c1, c2, c3, c4, c5, c6, c7 ) && ((unsigned char *) s)[ 7 ] == c8 )
2038
#define CMP9( s, c1, c2, c3, c4, c5, c6, c7, c8, c9 ) \
2039
6.07M
  ( CMP8( s, c1, c2, c3, c4, c5, c6, c7, c8 ) && \
2040
6.07M
    ((unsigned char *) s)[ 8 ] == c9 )
2041
#define CMP10( s, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10 ) \
2042
23.6k
  ( CMP9( s, c1, c2, c3, c4, c5, c6, c7, c8, c9 ) && \
2043
23.6k
    ((unsigned char *) s)[ 9 ] == c10 )
2044
2045
4.19M
#define SKIP(val) do {             \
2046
4.19M
    ctxt->input->cur += (val),ctxt->input->col+=(val);      \
2047
4.19M
    if (*ctxt->input->cur == 0)           \
2048
4.19M
        xmlParserGrow(ctxt);           \
2049
4.19M
  } while (0)
2050
2051
#define SKIPL(val) do {             \
2052
    int skipl;                \
2053
    for(skipl=0; skipl<val; skipl++) {          \
2054
  if (*(ctxt->input->cur) == '\n') {        \
2055
  ctxt->input->line++; ctxt->input->col = 1;      \
2056
  } else ctxt->input->col++;          \
2057
  ctxt->input->cur++;           \
2058
    }                 \
2059
    if (*ctxt->input->cur == 0)           \
2060
        xmlParserGrow(ctxt);            \
2061
  } while (0)
2062
2063
9.55M
#define SHRINK if ((ctxt->progressive == 0) &&       \
2064
9.55M
       (ctxt->input->cur - ctxt->input->base > 2 * INPUT_CHUNK) && \
2065
9.55M
       (ctxt->input->end - ctxt->input->cur < 2 * INPUT_CHUNK)) \
2066
9.55M
  xmlParserShrink(ctxt);
2067
2068
404M
#define GROW if ((ctxt->progressive == 0) &&       \
2069
404M
     (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK))  \
2070
404M
  xmlParserGrow(ctxt);
2071
2072
14.3M
#define SKIP_BLANKS xmlSkipBlankChars(ctxt)
2073
2074
24.5M
#define NEXT xmlNextChar(ctxt)
2075
2076
3.54M
#define NEXT1 {               \
2077
3.54M
  ctxt->input->col++;           \
2078
3.54M
  ctxt->input->cur++;           \
2079
3.54M
  if (*ctxt->input->cur == 0)         \
2080
3.54M
      xmlParserGrow(ctxt);           \
2081
3.54M
    }
2082
2083
980M
#define NEXTL(l) do {             \
2084
980M
    if (*(ctxt->input->cur) == '\n') {         \
2085
77.8M
  ctxt->input->line++; ctxt->input->col = 1;      \
2086
902M
    } else ctxt->input->col++;           \
2087
980M
    ctxt->input->cur += l;        \
2088
980M
  } while (0)
2089
2090
983M
#define CUR_CHAR(l) xmlCurrentChar(ctxt, &l)
2091
419M
#define CUR_SCHAR(s, l) xmlStringCurrentChar(ctxt, s, &l)
2092
2093
#define COPY_BUF(l,b,i,v)           \
2094
1.29G
    if (l == 1) b[i++] = v;           \
2095
1.29G
    else i += xmlCopyCharMultiByte(&b[i],v)
2096
2097
/**
2098
 * xmlSkipBlankChars:
2099
 * @ctxt:  the XML parser context
2100
 *
2101
 * skip all blanks character found at that point in the input streams.
2102
 * It pops up finished entities in the process if allowable at that point.
2103
 *
2104
 * Returns the number of space chars skipped
2105
 */
2106
2107
int
2108
14.3M
xmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
2109
14.3M
    int res = 0;
2110
2111
    /*
2112
     * It's Okay to use CUR/NEXT here since all the blanks are on
2113
     * the ASCII range.
2114
     */
2115
14.3M
    if (((ctxt->inputNr == 1) && (ctxt->instate != XML_PARSER_DTD)) ||
2116
14.3M
        (ctxt->instate == XML_PARSER_START)) {
2117
11.7M
  const xmlChar *cur;
2118
  /*
2119
   * if we are in the document content, go really fast
2120
   */
2121
11.7M
  cur = ctxt->input->cur;
2122
11.7M
  while (IS_BLANK_CH(*cur)) {
2123
8.55M
      if (*cur == '\n') {
2124
4.12M
    ctxt->input->line++; ctxt->input->col = 1;
2125
4.42M
      } else {
2126
4.42M
    ctxt->input->col++;
2127
4.42M
      }
2128
8.55M
      cur++;
2129
8.55M
      if (res < INT_MAX)
2130
8.55M
    res++;
2131
8.55M
      if (*cur == 0) {
2132
82.6k
    ctxt->input->cur = cur;
2133
82.6k
    xmlParserGrow(ctxt);
2134
82.6k
    cur = ctxt->input->cur;
2135
82.6k
      }
2136
8.55M
  }
2137
11.7M
  ctxt->input->cur = cur;
2138
11.7M
    } else {
2139
2.68M
        int expandPE = ((ctxt->external != 0) || (ctxt->inputNr != 1));
2140
2141
4.81M
  while (ctxt->instate != XML_PARSER_EOF) {
2142
4.81M
            if (IS_BLANK_CH(CUR)) { /* CHECKED tstblanks.xml */
2143
1.97M
    NEXT;
2144
2.83M
      } else if (CUR == '%') {
2145
                /*
2146
                 * Need to handle support of entities branching here
2147
                 */
2148
207k
          if ((expandPE == 0) || (IS_BLANK_CH(NXT(1))) || (NXT(1) == 0))
2149
117k
                    break;
2150
89.1k
          xmlParsePEReference(ctxt);
2151
2.62M
            } else if (CUR == 0) {
2152
67.0k
                unsigned long consumed;
2153
67.0k
                xmlEntityPtr ent;
2154
2155
67.0k
                if (ctxt->inputNr <= 1)
2156
5.46k
                    break;
2157
2158
61.5k
                consumed = ctxt->input->consumed;
2159
61.5k
                xmlSaturatedAddSizeT(&consumed,
2160
61.5k
                                     ctxt->input->cur - ctxt->input->base);
2161
2162
                /*
2163
                 * Add to sizeentities when parsing an external entity
2164
                 * for the first time.
2165
                 */
2166
61.5k
                ent = ctxt->input->entity;
2167
61.5k
                if ((ent->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
2168
61.5k
                    ((ent->flags & XML_ENT_PARSED) == 0)) {
2169
711
                    ent->flags |= XML_ENT_PARSED;
2170
2171
711
                    xmlSaturatedAdd(&ctxt->sizeentities, consumed);
2172
711
                }
2173
2174
61.5k
                xmlParserEntityCheck(ctxt, consumed);
2175
2176
61.5k
                xmlPopInput(ctxt);
2177
2.55M
            } else {
2178
2.55M
                break;
2179
2.55M
            }
2180
2181
            /*
2182
             * Also increase the counter when entering or exiting a PERef.
2183
             * The spec says: "When a parameter-entity reference is recognized
2184
             * in the DTD and included, its replacement text MUST be enlarged
2185
             * by the attachment of one leading and one following space (#x20)
2186
             * character."
2187
             */
2188
2.13M
      if (res < INT_MAX)
2189
2.13M
    res++;
2190
2.13M
        }
2191
2.68M
    }
2192
14.3M
    return(res);
2193
14.3M
}
2194
2195
/************************************************************************
2196
 *                  *
2197
 *    Commodity functions to handle entities      *
2198
 *                  *
2199
 ************************************************************************/
2200
2201
/**
2202
 * xmlPopInput:
2203
 * @ctxt:  an XML parser context
2204
 *
2205
 * xmlPopInput: the current input pointed by ctxt->input came to an end
2206
 *          pop it and return the next char.
2207
 *
2208
 * Returns the current xmlChar in the parser context
2209
 */
2210
xmlChar
2211
61.6k
xmlPopInput(xmlParserCtxtPtr ctxt) {
2212
61.6k
    xmlParserInputPtr input;
2213
2214
61.6k
    if ((ctxt == NULL) || (ctxt->inputNr <= 1)) return(0);
2215
61.5k
    if (xmlParserDebugEntities)
2216
0
  xmlGenericError(xmlGenericErrorContext,
2217
0
    "Popping input %d\n", ctxt->inputNr);
2218
61.5k
    if ((ctxt->inputNr > 1) && (ctxt->inSubset == 0) &&
2219
61.5k
        (ctxt->instate != XML_PARSER_EOF))
2220
0
        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
2221
0
                    "Unfinished entity outside the DTD");
2222
61.5k
    input = inputPop(ctxt);
2223
61.5k
    if (input->entity != NULL)
2224
61.5k
        input->entity->flags &= ~XML_ENT_EXPANDING;
2225
61.5k
    xmlFreeInputStream(input);
2226
61.5k
    if (*ctxt->input->cur == 0)
2227
308
        xmlParserGrow(ctxt);
2228
61.5k
    return(CUR);
2229
61.6k
}
2230
2231
/**
2232
 * xmlPushInput:
2233
 * @ctxt:  an XML parser context
2234
 * @input:  an XML parser input fragment (entity, XML fragment ...).
2235
 *
2236
 * xmlPushInput: switch to a new input stream which is stacked on top
2237
 *               of the previous one(s).
2238
 * Returns -1 in case of error or the index in the input stack
2239
 */
2240
int
2241
71.8k
xmlPushInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr input) {
2242
71.8k
    int ret;
2243
71.8k
    if (input == NULL) return(-1);
2244
2245
68.0k
    if (xmlParserDebugEntities) {
2246
0
  if ((ctxt->input != NULL) && (ctxt->input->filename))
2247
0
      xmlGenericError(xmlGenericErrorContext,
2248
0
        "%s(%d): ", ctxt->input->filename,
2249
0
        ctxt->input->line);
2250
0
  xmlGenericError(xmlGenericErrorContext,
2251
0
    "Pushing input %d : %.30s\n", ctxt->inputNr+1, input->cur);
2252
0
    }
2253
68.0k
    if (((ctxt->inputNr > 40) && ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
2254
68.0k
        (ctxt->inputNr > 100)) {
2255
0
        xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
2256
0
        while (ctxt->inputNr > 1)
2257
0
            xmlFreeInputStream(inputPop(ctxt));
2258
0
  return(-1);
2259
0
    }
2260
68.0k
    ret = inputPush(ctxt, input);
2261
68.0k
    if (ctxt->instate == XML_PARSER_EOF)
2262
0
        return(-1);
2263
68.0k
    GROW;
2264
68.0k
    return(ret);
2265
68.0k
}
2266
2267
/**
2268
 * xmlParseCharRef:
2269
 * @ctxt:  an XML parser context
2270
 *
2271
 * DEPRECATED: Internal function, don't use.
2272
 *
2273
 * Parse a numeric character reference. Always consumes '&'.
2274
 *
2275
 * [66] CharRef ::= '&#' [0-9]+ ';' |
2276
 *                  '&#x' [0-9a-fA-F]+ ';'
2277
 *
2278
 * [ WFC: Legal Character ]
2279
 * Characters referred to using character references must match the
2280
 * production for Char.
2281
 *
2282
 * Returns the value parsed (as an int), 0 in case of error
2283
 */
2284
int
2285
533k
xmlParseCharRef(xmlParserCtxtPtr ctxt) {
2286
533k
    int val = 0;
2287
533k
    int count = 0;
2288
2289
    /*
2290
     * Using RAW/CUR/NEXT is okay since we are working on ASCII range here
2291
     */
2292
533k
    if ((RAW == '&') && (NXT(1) == '#') &&
2293
533k
        (NXT(2) == 'x')) {
2294
291k
  SKIP(3);
2295
291k
  GROW;
2296
1.28M
  while (RAW != ';') { /* loop blocked by count */
2297
1.06M
      if (count++ > 20) {
2298
1.60k
    count = 0;
2299
1.60k
    GROW;
2300
1.60k
                if (ctxt->instate == XML_PARSER_EOF)
2301
1
                    return(0);
2302
1.60k
      }
2303
1.06M
      if ((RAW >= '0') && (RAW <= '9'))
2304
249k
          val = val * 16 + (CUR - '0');
2305
810k
      else if ((RAW >= 'a') && (RAW <= 'f') && (count < 20))
2306
33.6k
          val = val * 16 + (CUR - 'a') + 10;
2307
777k
      else if ((RAW >= 'A') && (RAW <= 'F') && (count < 20))
2308
711k
          val = val * 16 + (CUR - 'A') + 10;
2309
65.7k
      else {
2310
65.7k
    xmlFatalErr(ctxt, XML_ERR_INVALID_HEX_CHARREF, NULL);
2311
65.7k
    val = 0;
2312
65.7k
    break;
2313
65.7k
      }
2314
994k
      if (val > 0x110000)
2315
35.9k
          val = 0x110000;
2316
2317
994k
      NEXT;
2318
994k
      count++;
2319
994k
  }
2320
291k
  if (RAW == ';') {
2321
      /* on purpose to avoid reentrancy problems with NEXT and SKIP */
2322
226k
      ctxt->input->col++;
2323
226k
      ctxt->input->cur++;
2324
226k
  }
2325
291k
    } else if  ((RAW == '&') && (NXT(1) == '#')) {
2326
241k
  SKIP(2);
2327
241k
  GROW;
2328
801k
  while (RAW != ';') { /* loop blocked by count */
2329
601k
      if (count++ > 20) {
2330
9.15k
    count = 0;
2331
9.15k
    GROW;
2332
9.15k
                if (ctxt->instate == XML_PARSER_EOF)
2333
77
                    return(0);
2334
9.15k
      }
2335
601k
      if ((RAW >= '0') && (RAW <= '9'))
2336
559k
          val = val * 10 + (CUR - '0');
2337
42.1k
      else {
2338
42.1k
    xmlFatalErr(ctxt, XML_ERR_INVALID_DEC_CHARREF, NULL);
2339
42.1k
    val = 0;
2340
42.1k
    break;
2341
42.1k
      }
2342
559k
      if (val > 0x110000)
2343
19.2k
          val = 0x110000;
2344
2345
559k
      NEXT;
2346
559k
      count++;
2347
559k
  }
2348
241k
  if (RAW == ';') {
2349
      /* on purpose to avoid reentrancy problems with NEXT and SKIP */
2350
199k
      ctxt->input->col++;
2351
199k
      ctxt->input->cur++;
2352
199k
  }
2353
241k
    } else {
2354
0
        if (RAW == '&')
2355
0
            SKIP(1);
2356
0
        xmlFatalErr(ctxt, XML_ERR_INVALID_CHARREF, NULL);
2357
0
    }
2358
2359
    /*
2360
     * [ WFC: Legal Character ]
2361
     * Characters referred to using character references must match the
2362
     * production for Char.
2363
     */
2364
533k
    if (val >= 0x110000) {
2365
15.9k
        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
2366
15.9k
                "xmlParseCharRef: character reference out of bounds\n",
2367
15.9k
          val);
2368
517k
    } else if (IS_CHAR(val)) {
2369
404k
        return(val);
2370
404k
    } else {
2371
112k
        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
2372
112k
                          "xmlParseCharRef: invalid xmlChar value %d\n",
2373
112k
                    val);
2374
112k
    }
2375
128k
    return(0);
2376
533k
}
2377
2378
/**
2379
 * xmlParseStringCharRef:
2380
 * @ctxt:  an XML parser context
2381
 * @str:  a pointer to an index in the string
2382
 *
2383
 * parse Reference declarations, variant parsing from a string rather
2384
 * than an an input flow.
2385
 *
2386
 * [66] CharRef ::= '&#' [0-9]+ ';' |
2387
 *                  '&#x' [0-9a-fA-F]+ ';'
2388
 *
2389
 * [ WFC: Legal Character ]
2390
 * Characters referred to using character references must match the
2391
 * production for Char.
2392
 *
2393
 * Returns the value parsed (as an int), 0 in case of error, str will be
2394
 *         updated to the current value of the index
2395
 */
2396
static int
2397
12.9k
xmlParseStringCharRef(xmlParserCtxtPtr ctxt, const xmlChar **str) {
2398
12.9k
    const xmlChar *ptr;
2399
12.9k
    xmlChar cur;
2400
12.9k
    int val = 0;
2401
2402
12.9k
    if ((str == NULL) || (*str == NULL)) return(0);
2403
12.9k
    ptr = *str;
2404
12.9k
    cur = *ptr;
2405
12.9k
    if ((cur == '&') && (ptr[1] == '#') && (ptr[2] == 'x')) {
2406
4.67k
  ptr += 3;
2407
4.67k
  cur = *ptr;
2408
21.1k
  while (cur != ';') { /* Non input consuming loop */
2409
17.3k
      if ((cur >= '0') && (cur <= '9'))
2410
6.29k
          val = val * 16 + (cur - '0');
2411
11.0k
      else if ((cur >= 'a') && (cur <= 'f'))
2412
2.71k
          val = val * 16 + (cur - 'a') + 10;
2413
8.30k
      else if ((cur >= 'A') && (cur <= 'F'))
2414
7.50k
          val = val * 16 + (cur - 'A') + 10;
2415
803
      else {
2416
803
    xmlFatalErr(ctxt, XML_ERR_INVALID_HEX_CHARREF, NULL);
2417
803
    val = 0;
2418
803
    break;
2419
803
      }
2420
16.5k
      if (val > 0x110000)
2421
1.64k
          val = 0x110000;
2422
2423
16.5k
      ptr++;
2424
16.5k
      cur = *ptr;
2425
16.5k
  }
2426
4.67k
  if (cur == ';')
2427
3.87k
      ptr++;
2428
8.24k
    } else if  ((cur == '&') && (ptr[1] == '#')){
2429
8.24k
  ptr += 2;
2430
8.24k
  cur = *ptr;
2431
27.7k
  while (cur != ';') { /* Non input consuming loops */
2432
21.2k
      if ((cur >= '0') && (cur <= '9'))
2433
19.4k
          val = val * 10 + (cur - '0');
2434
1.77k
      else {
2435
1.77k
    xmlFatalErr(ctxt, XML_ERR_INVALID_DEC_CHARREF, NULL);
2436
1.77k
    val = 0;
2437
1.77k
    break;
2438
1.77k
      }
2439
19.4k
      if (val > 0x110000)
2440
531
          val = 0x110000;
2441
2442
19.4k
      ptr++;
2443
19.4k
      cur = *ptr;
2444
19.4k
  }
2445
8.24k
  if (cur == ';')
2446
6.47k
      ptr++;
2447
8.24k
    } else {
2448
0
  xmlFatalErr(ctxt, XML_ERR_INVALID_CHARREF, NULL);
2449
0
  return(0);
2450
0
    }
2451
12.9k
    *str = ptr;
2452
2453
    /*
2454
     * [ WFC: Legal Character ]
2455
     * Characters referred to using character references must match the
2456
     * production for Char.
2457
     */
2458
12.9k
    if (val >= 0x110000) {
2459
177
        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
2460
177
                "xmlParseStringCharRef: character reference out of bounds\n",
2461
177
                val);
2462
12.7k
    } else if (IS_CHAR(val)) {
2463
9.50k
        return(val);
2464
9.50k
    } else {
2465
3.23k
        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
2466
3.23k
        "xmlParseStringCharRef: invalid xmlChar value %d\n",
2467
3.23k
        val);
2468
3.23k
    }
2469
3.41k
    return(0);
2470
12.9k
}
2471
2472
/**
2473
 * xmlParserHandlePEReference:
2474
 * @ctxt:  the parser context
2475
 *
2476
 * [69] PEReference ::= '%' Name ';'
2477
 *
2478
 * [ WFC: No Recursion ]
2479
 * A parsed entity must not contain a recursive
2480
 * reference to itself, either directly or indirectly.
2481
 *
2482
 * [ WFC: Entity Declared ]
2483
 * In a document without any DTD, a document with only an internal DTD
2484
 * subset which contains no parameter entity references, or a document
2485
 * with "standalone='yes'", ...  ... The declaration of a parameter
2486
 * entity must precede any reference to it...
2487
 *
2488
 * [ VC: Entity Declared ]
2489
 * In a document with an external subset or external parameter entities
2490
 * with "standalone='no'", ...  ... The declaration of a parameter entity
2491
 * must precede any reference to it...
2492
 *
2493
 * [ WFC: In DTD ]
2494
 * Parameter-entity references may only appear in the DTD.
2495
 * NOTE: misleading but this is handled.
2496
 *
2497
 * A PEReference may have been detected in the current input stream
2498
 * the handling is done accordingly to
2499
 *      http://www.w3.org/TR/REC-xml#entproc
2500
 * i.e.
2501
 *   - Included in literal in entity values
2502
 *   - Included as Parameter Entity reference within DTDs
2503
 */
2504
void
2505
0
xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) {
2506
0
    switch(ctxt->instate) {
2507
0
  case XML_PARSER_CDATA_SECTION:
2508
0
      return;
2509
0
        case XML_PARSER_COMMENT:
2510
0
      return;
2511
0
  case XML_PARSER_START_TAG:
2512
0
      return;
2513
0
  case XML_PARSER_END_TAG:
2514
0
      return;
2515
0
        case XML_PARSER_EOF:
2516
0
      xmlFatalErr(ctxt, XML_ERR_PEREF_AT_EOF, NULL);
2517
0
      return;
2518
0
        case XML_PARSER_PROLOG:
2519
0
  case XML_PARSER_START:
2520
0
  case XML_PARSER_MISC:
2521
0
      xmlFatalErr(ctxt, XML_ERR_PEREF_IN_PROLOG, NULL);
2522
0
      return;
2523
0
  case XML_PARSER_ENTITY_DECL:
2524
0
        case XML_PARSER_CONTENT:
2525
0
        case XML_PARSER_ATTRIBUTE_VALUE:
2526
0
        case XML_PARSER_PI:
2527
0
  case XML_PARSER_SYSTEM_LITERAL:
2528
0
  case XML_PARSER_PUBLIC_LITERAL:
2529
      /* we just ignore it there */
2530
0
      return;
2531
0
        case XML_PARSER_EPILOG:
2532
0
      xmlFatalErr(ctxt, XML_ERR_PEREF_IN_EPILOG, NULL);
2533
0
      return;
2534
0
  case XML_PARSER_ENTITY_VALUE:
2535
      /*
2536
       * NOTE: in the case of entity values, we don't do the
2537
       *       substitution here since we need the literal
2538
       *       entity value to be able to save the internal
2539
       *       subset of the document.
2540
       *       This will be handled by xmlStringDecodeEntities
2541
       */
2542
0
      return;
2543
0
        case XML_PARSER_DTD:
2544
      /*
2545
       * [WFC: Well-Formedness Constraint: PEs in Internal Subset]
2546
       * In the internal DTD subset, parameter-entity references
2547
       * can occur only where markup declarations can occur, not
2548
       * within markup declarations.
2549
       * In that case this is handled in xmlParseMarkupDecl
2550
       */
2551
0
      if ((ctxt->external == 0) && (ctxt->inputNr == 1))
2552
0
    return;
2553
0
      if (IS_BLANK_CH(NXT(1)) || NXT(1) == 0)
2554
0
    return;
2555
0
            break;
2556
0
        case XML_PARSER_IGNORE:
2557
0
            return;
2558
0
    }
2559
2560
0
    xmlParsePEReference(ctxt);
2561
0
}
2562
2563
/*
2564
 * Macro used to grow the current buffer.
2565
 * buffer##_size is expected to be a size_t
2566
 * mem_error: is expected to handle memory allocation failures
2567
 */
2568
321k
#define growBuffer(buffer, n) {           \
2569
321k
    xmlChar *tmp;             \
2570
321k
    size_t new_size = buffer##_size * 2 + n;                            \
2571
321k
    if (new_size < buffer##_size) goto mem_error;                       \
2572
321k
    tmp = (xmlChar *) xmlRealloc(buffer, new_size);                     \
2573
321k
    if (tmp == NULL) goto mem_error;         \
2574
321k
    buffer = tmp;             \
2575
321k
    buffer##_size = new_size;                                           \
2576
321k
}
2577
2578
/**
2579
 * xmlStringDecodeEntitiesInt:
2580
 * @ctxt:  the parser context
2581
 * @str:  the input string
2582
 * @len: the string length
2583
 * @what:  combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
2584
 * @end:  an end marker xmlChar, 0 if none
2585
 * @end2:  an end marker xmlChar, 0 if none
2586
 * @end3:  an end marker xmlChar, 0 if none
2587
 * @check:  whether to perform entity checks
2588
 */
2589
static xmlChar *
2590
xmlStringDecodeEntitiesInt(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
2591
               int what, xmlChar end, xmlChar  end2, xmlChar end3,
2592
127k
                           int check) {
2593
127k
    xmlChar *buffer = NULL;
2594
127k
    size_t buffer_size = 0;
2595
127k
    size_t nbchars = 0;
2596
2597
127k
    xmlChar *current = NULL;
2598
127k
    xmlChar *rep = NULL;
2599
127k
    const xmlChar *last;
2600
127k
    xmlEntityPtr ent;
2601
127k
    int c,l;
2602
2603
127k
    if (str == NULL)
2604
1.40k
        return(NULL);
2605
126k
    last = str + len;
2606
2607
126k
    if (((ctxt->depth > 40) &&
2608
126k
         ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
2609
126k
  (ctxt->depth > 100)) {
2610
0
  xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_LOOP,
2611
0
                       "Maximum entity nesting depth exceeded");
2612
0
  return(NULL);
2613
0
    }
2614
2615
    /*
2616
     * allocate a translation buffer.
2617
     */
2618
126k
    buffer_size = XML_PARSER_BIG_BUFFER_SIZE;
2619
126k
    buffer = (xmlChar *) xmlMallocAtomic(buffer_size);
2620
126k
    if (buffer == NULL) goto mem_error;
2621
2622
    /*
2623
     * OK loop until we reach one of the ending char or a size limit.
2624
     * we are operating on already parsed values.
2625
     */
2626
126k
    if (str < last)
2627
120k
  c = CUR_SCHAR(str, l);
2628
5.57k
    else
2629
5.57k
        c = 0;
2630
405M
    while ((c != 0) && (c != end) && /* non input consuming loop */
2631
405M
           (c != end2) && (c != end3) &&
2632
405M
           (ctxt->instate != XML_PARSER_EOF)) {
2633
2634
405M
  if (c == 0) break;
2635
405M
        if ((c == '&') && (str[1] == '#')) {
2636
12.9k
      int val = xmlParseStringCharRef(ctxt, &str);
2637
12.9k
      if (val == 0)
2638
3.41k
                goto int_error;
2639
9.50k
      COPY_BUF(0,buffer,nbchars,val);
2640
9.50k
      if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
2641
429
          growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2642
429
      }
2643
405M
  } else if ((c == '&') && (what & XML_SUBSTITUTE_REF)) {
2644
127k
      if (xmlParserDebugEntities)
2645
0
    xmlGenericError(xmlGenericErrorContext,
2646
0
      "String decoding Entity Reference: %.30s\n",
2647
0
      str);
2648
127k
      ent = xmlParseStringEntityRef(ctxt, &str);
2649
127k
      if ((ent != NULL) &&
2650
127k
    (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
2651
8.31k
    if (ent->content != NULL) {
2652
8.31k
        COPY_BUF(0,buffer,nbchars,ent->content[0]);
2653
8.31k
        if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
2654
443
      growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2655
443
        }
2656
8.31k
    } else {
2657
0
        xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
2658
0
          "predefined entity has no content\n");
2659
0
                    goto int_error;
2660
0
    }
2661
118k
      } else if ((ent != NULL) && (ent->content != NULL)) {
2662
69.7k
          if ((check) && (xmlParserEntityCheck(ctxt, ent->length)))
2663
27
                    goto int_error;
2664
2665
69.6k
                if (ent->flags & XML_ENT_EXPANDING) {
2666
402
              xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
2667
402
                    xmlHaltParser(ctxt);
2668
402
                    ent->content[0] = 0;
2669
402
                    goto int_error;
2670
402
                }
2671
2672
69.2k
                ent->flags |= XML_ENT_EXPANDING;
2673
69.2k
    ctxt->depth++;
2674
69.2k
    rep = xmlStringDecodeEntitiesInt(ctxt, ent->content,
2675
69.2k
                        ent->length, what, 0, 0, 0, check);
2676
69.2k
    ctxt->depth--;
2677
69.2k
                ent->flags &= ~XML_ENT_EXPANDING;
2678
2679
69.2k
    if (rep == NULL) {
2680
329
                    ent->content[0] = 0;
2681
329
                    goto int_error;
2682
329
                }
2683
2684
68.9k
                current = rep;
2685
185M
                while (*current != 0) { /* non input consuming loop */
2686
185M
                    buffer[nbchars++] = *current++;
2687
185M
                    if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
2688
103k
                        growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2689
103k
                    }
2690
185M
                }
2691
68.9k
                xmlFree(rep);
2692
68.9k
                rep = NULL;
2693
68.9k
      } else if (ent != NULL) {
2694
4.80k
    int i = xmlStrlen(ent->name);
2695
4.80k
    const xmlChar *cur = ent->name;
2696
2697
4.80k
    buffer[nbchars++] = '&';
2698
4.80k
    if (nbchars + i + XML_PARSER_BUFFER_SIZE > buffer_size) {
2699
472
        growBuffer(buffer, i + XML_PARSER_BUFFER_SIZE);
2700
472
    }
2701
32.3k
    for (;i > 0;i--)
2702
27.5k
        buffer[nbchars++] = *cur++;
2703
4.80k
    buffer[nbchars++] = ';';
2704
4.80k
      }
2705
405M
  } else if (c == '%' && (what & XML_SUBSTITUTE_PEREF)) {
2706
1.61k
      if (xmlParserDebugEntities)
2707
0
    xmlGenericError(xmlGenericErrorContext,
2708
0
      "String decoding PE Reference: %.30s\n", str);
2709
1.61k
      ent = xmlParseStringPEReference(ctxt, &str);
2710
1.61k
      if (ent != NULL) {
2711
127
                if (ent->content == NULL) {
2712
        /*
2713
         * Note: external parsed entities will not be loaded,
2714
         * it is not required for a non-validating parser to
2715
         * complete external PEReferences coming from the
2716
         * internal subset
2717
         */
2718
80
        if (((ctxt->options & XML_PARSE_NOENT) != 0) ||
2719
80
      ((ctxt->options & XML_PARSE_DTDVALID) != 0) ||
2720
80
      (ctxt->validate != 0)) {
2721
80
      xmlLoadEntityContent(ctxt, ent);
2722
80
        } else {
2723
0
      xmlWarningMsg(ctxt, XML_ERR_ENTITY_PROCESSING,
2724
0
      "not validating will not read content for PE entity %s\n",
2725
0
                          ent->name, NULL);
2726
0
        }
2727
80
    }
2728
2729
127
          if ((check) && (xmlParserEntityCheck(ctxt, ent->length)))
2730
3
                    goto int_error;
2731
2732
124
                if (ent->flags & XML_ENT_EXPANDING) {
2733
77
              xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
2734
77
                    xmlHaltParser(ctxt);
2735
77
                    if (ent->content != NULL)
2736
44
                        ent->content[0] = 0;
2737
77
                    goto int_error;
2738
77
                }
2739
2740
47
                ent->flags |= XML_ENT_EXPANDING;
2741
47
    ctxt->depth++;
2742
47
    rep = xmlStringDecodeEntitiesInt(ctxt, ent->content,
2743
47
                        ent->length, what, 0, 0, 0, check);
2744
47
    ctxt->depth--;
2745
47
                ent->flags &= ~XML_ENT_EXPANDING;
2746
2747
47
    if (rep == NULL) {
2748
47
                    if (ent->content != NULL)
2749
47
                        ent->content[0] = 0;
2750
47
                    goto int_error;
2751
47
                }
2752
0
                current = rep;
2753
0
                while (*current != 0) { /* non input consuming loop */
2754
0
                    buffer[nbchars++] = *current++;
2755
0
                    if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
2756
0
                        growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2757
0
                    }
2758
0
                }
2759
0
                xmlFree(rep);
2760
0
                rep = NULL;
2761
0
      }
2762
405M
  } else {
2763
405M
      COPY_BUF(l,buffer,nbchars,c);
2764
405M
      str += l;
2765
405M
      if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
2766
88.0k
          growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2767
88.0k
      }
2768
405M
  }
2769
405M
  if (str < last)
2770
405M
      c = CUR_SCHAR(str, l);
2771
115k
  else
2772
115k
      c = 0;
2773
405M
    }
2774
121k
    buffer[nbchars] = 0;
2775
121k
    return(buffer);
2776
2777
8
mem_error:
2778
8
    xmlErrMemory(ctxt, NULL);
2779
4.30k
int_error:
2780
4.30k
    if (rep != NULL)
2781
1
        xmlFree(rep);
2782
4.30k
    if (buffer != NULL)
2783
4.30k
        xmlFree(buffer);
2784
4.30k
    return(NULL);
2785
8
}
2786
2787
/**
2788
 * xmlStringLenDecodeEntities:
2789
 * @ctxt:  the parser context
2790
 * @str:  the input string
2791
 * @len: the string length
2792
 * @what:  combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
2793
 * @end:  an end marker xmlChar, 0 if none
2794
 * @end2:  an end marker xmlChar, 0 if none
2795
 * @end3:  an end marker xmlChar, 0 if none
2796
 *
2797
 * DEPRECATED: Internal function, don't use.
2798
 *
2799
 * Takes a entity string content and process to do the adequate substitutions.
2800
 *
2801
 * [67] Reference ::= EntityRef | CharRef
2802
 *
2803
 * [69] PEReference ::= '%' Name ';'
2804
 *
2805
 * Returns A newly allocated string with the substitution done. The caller
2806
 *      must deallocate it !
2807
 */
2808
xmlChar *
2809
xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
2810
                           int what, xmlChar end, xmlChar  end2,
2811
0
                           xmlChar end3) {
2812
0
    if ((ctxt == NULL) || (str == NULL) || (len < 0))
2813
0
        return(NULL);
2814
0
    return(xmlStringDecodeEntitiesInt(ctxt, str, len, what,
2815
0
                                      end, end2, end3, 0));
2816
0
}
2817
2818
/**
2819
 * xmlStringDecodeEntities:
2820
 * @ctxt:  the parser context
2821
 * @str:  the input string
2822
 * @what:  combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
2823
 * @end:  an end marker xmlChar, 0 if none
2824
 * @end2:  an end marker xmlChar, 0 if none
2825
 * @end3:  an end marker xmlChar, 0 if none
2826
 *
2827
 * DEPRECATED: Internal function, don't use.
2828
 *
2829
 * Takes a entity string content and process to do the adequate substitutions.
2830
 *
2831
 * [67] Reference ::= EntityRef | CharRef
2832
 *
2833
 * [69] PEReference ::= '%' Name ';'
2834
 *
2835
 * Returns A newly allocated string with the substitution done. The caller
2836
 *      must deallocate it !
2837
 */
2838
xmlChar *
2839
xmlStringDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int what,
2840
0
            xmlChar end, xmlChar  end2, xmlChar end3) {
2841
0
    if ((ctxt == NULL) || (str == NULL)) return(NULL);
2842
0
    return(xmlStringDecodeEntitiesInt(ctxt, str, xmlStrlen(str), what,
2843
0
                                      end, end2, end3, 0));
2844
0
}
2845
2846
/************************************************************************
2847
 *                  *
2848
 *    Commodity functions, cleanup needed ?     *
2849
 *                  *
2850
 ************************************************************************/
2851
2852
/**
2853
 * areBlanks:
2854
 * @ctxt:  an XML parser context
2855
 * @str:  a xmlChar *
2856
 * @len:  the size of @str
2857
 * @blank_chars: we know the chars are blanks
2858
 *
2859
 * Is this a sequence of blank chars that one can ignore ?
2860
 *
2861
 * Returns 1 if ignorable 0 otherwise.
2862
 */
2863
2864
static int areBlanks(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
2865
1.72M
                     int blank_chars) {
2866
1.72M
    int i, ret;
2867
1.72M
    xmlNodePtr lastChild;
2868
2869
    /*
2870
     * Don't spend time trying to differentiate them, the same callback is
2871
     * used !
2872
     */
2873
1.72M
    if (ctxt->sax->ignorableWhitespace == ctxt->sax->characters)
2874
1.72M
  return(0);
2875
2876
    /*
2877
     * Check for xml:space value.
2878
     */
2879
0
    if ((ctxt->space == NULL) || (*(ctxt->space) == 1) ||
2880
0
        (*(ctxt->space) == -2))
2881
0
  return(0);
2882
2883
    /*
2884
     * Check that the string is made of blanks
2885
     */
2886
0
    if (blank_chars == 0) {
2887
0
  for (i = 0;i < len;i++)
2888
0
      if (!(IS_BLANK_CH(str[i]))) return(0);
2889
0
    }
2890
2891
    /*
2892
     * Look if the element is mixed content in the DTD if available
2893
     */
2894
0
    if (ctxt->node == NULL) return(0);
2895
0
    if (ctxt->myDoc != NULL) {
2896
0
  ret = xmlIsMixedElement(ctxt->myDoc, ctxt->node->name);
2897
0
        if (ret == 0) return(1);
2898
0
        if (ret == 1) return(0);
2899
0
    }
2900
2901
    /*
2902
     * Otherwise, heuristic :-\
2903
     */
2904
0
    if ((RAW != '<') && (RAW != 0xD)) return(0);
2905
0
    if ((ctxt->node->children == NULL) &&
2906
0
  (RAW == '<') && (NXT(1) == '/')) return(0);
2907
2908
0
    lastChild = xmlGetLastChild(ctxt->node);
2909
0
    if (lastChild == NULL) {
2910
0
        if ((ctxt->node->type != XML_ELEMENT_NODE) &&
2911
0
            (ctxt->node->content != NULL)) return(0);
2912
0
    } else if (xmlNodeIsText(lastChild))
2913
0
        return(0);
2914
0
    else if ((ctxt->node->children != NULL) &&
2915
0
             (xmlNodeIsText(ctxt->node->children)))
2916
0
        return(0);
2917
0
    return(1);
2918
0
}
2919
2920
/************************************************************************
2921
 *                  *
2922
 *    Extra stuff for namespace support     *
2923
 *  Relates to http://www.w3.org/TR/WD-xml-names      *
2924
 *                  *
2925
 ************************************************************************/
2926
2927
/**
2928
 * xmlSplitQName:
2929
 * @ctxt:  an XML parser context
2930
 * @name:  an XML parser context
2931
 * @prefix:  a xmlChar **
2932
 *
2933
 * parse an UTF8 encoded XML qualified name string
2934
 *
2935
 * [NS 5] QName ::= (Prefix ':')? LocalPart
2936
 *
2937
 * [NS 6] Prefix ::= NCName
2938
 *
2939
 * [NS 7] LocalPart ::= NCName
2940
 *
2941
 * Returns the local part, and prefix is updated
2942
 *   to get the Prefix if any.
2943
 */
2944
2945
xmlChar *
2946
145k
xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) {
2947
145k
    xmlChar buf[XML_MAX_NAMELEN + 5];
2948
145k
    xmlChar *buffer = NULL;
2949
145k
    int len = 0;
2950
145k
    int max = XML_MAX_NAMELEN;
2951
145k
    xmlChar *ret = NULL;
2952
145k
    const xmlChar *cur = name;
2953
145k
    int c;
2954
2955
145k
    if (prefix == NULL) return(NULL);
2956
145k
    *prefix = NULL;
2957
2958
145k
    if (cur == NULL) return(NULL);
2959
2960
#ifndef XML_XML_NAMESPACE
2961
    /* xml: prefix is not really a namespace */
2962
    if ((cur[0] == 'x') && (cur[1] == 'm') &&
2963
        (cur[2] == 'l') && (cur[3] == ':'))
2964
  return(xmlStrdup(name));
2965
#endif
2966
2967
    /* nasty but well=formed */
2968
145k
    if (cur[0] == ':')
2969
2.27k
  return(xmlStrdup(name));
2970
2971
143k
    c = *cur++;
2972
2.25M
    while ((c != 0) && (c != ':') && (len < max)) { /* tested bigname.xml */
2973
2.10M
  buf[len++] = c;
2974
2.10M
  c = *cur++;
2975
2.10M
    }
2976
143k
    if (len >= max) {
2977
  /*
2978
   * Okay someone managed to make a huge name, so he's ready to pay
2979
   * for the processing speed.
2980
   */
2981
7.37k
  max = len * 2;
2982
2983
7.37k
  buffer = (xmlChar *) xmlMallocAtomic(max);
2984
7.37k
  if (buffer == NULL) {
2985
1
      xmlErrMemory(ctxt, NULL);
2986
1
      return(NULL);
2987
1
  }
2988
7.37k
  memcpy(buffer, buf, len);
2989
1.47M
  while ((c != 0) && (c != ':')) { /* tested bigname.xml */
2990
1.46M
      if (len + 10 > max) {
2991
6.53k
          xmlChar *tmp;
2992
2993
6.53k
    max *= 2;
2994
6.53k
    tmp = (xmlChar *) xmlRealloc(buffer, max);
2995
6.53k
    if (tmp == NULL) {
2996
1
        xmlFree(buffer);
2997
1
        xmlErrMemory(ctxt, NULL);
2998
1
        return(NULL);
2999
1
    }
3000
6.53k
    buffer = tmp;
3001
6.53k
      }
3002
1.46M
      buffer[len++] = c;
3003
1.46M
      c = *cur++;
3004
1.46M
  }
3005
7.37k
  buffer[len] = 0;
3006
7.37k
    }
3007
3008
143k
    if ((c == ':') && (*cur == 0)) {
3009
7.33k
        if (buffer != NULL)
3010
1.46k
      xmlFree(buffer);
3011
7.33k
  *prefix = NULL;
3012
7.33k
  return(xmlStrdup(name));
3013
7.33k
    }
3014
3015
135k
    if (buffer == NULL)
3016
129k
  ret = xmlStrndup(buf, len);
3017
5.91k
    else {
3018
5.91k
  ret = buffer;
3019
5.91k
  buffer = NULL;
3020
5.91k
  max = XML_MAX_NAMELEN;
3021
5.91k
    }
3022
3023
3024
135k
    if (c == ':') {
3025
43.0k
  c = *cur;
3026
43.0k
        *prefix = ret;
3027
43.0k
  if (c == 0) {
3028
0
      return(xmlStrndup(BAD_CAST "", 0));
3029
0
  }
3030
43.0k
  len = 0;
3031
3032
  /*
3033
   * Check that the first character is proper to start
3034
   * a new name
3035
   */
3036
43.0k
  if (!(((c >= 0x61) && (c <= 0x7A)) ||
3037
43.0k
        ((c >= 0x41) && (c <= 0x5A)) ||
3038
43.0k
        (c == '_') || (c == ':'))) {
3039
32.3k
      int l;
3040
32.3k
      int first = CUR_SCHAR(cur, l);
3041
3042
32.3k
      if (!IS_LETTER(first) && (first != '_')) {
3043
578
    xmlFatalErrMsgStr(ctxt, XML_NS_ERR_QNAME,
3044
578
          "Name %s is not XML Namespace compliant\n",
3045
578
          name);
3046
578
      }
3047
32.3k
  }
3048
43.0k
  cur++;
3049
3050
1.13M
  while ((c != 0) && (len < max)) { /* tested bigname2.xml */
3051
1.09M
      buf[len++] = c;
3052
1.09M
      c = *cur++;
3053
1.09M
  }
3054
43.0k
  if (len >= max) {
3055
      /*
3056
       * Okay someone managed to make a huge name, so he's ready to pay
3057
       * for the processing speed.
3058
       */
3059
7.45k
      max = len * 2;
3060
3061
7.45k
      buffer = (xmlChar *) xmlMallocAtomic(max);
3062
7.45k
      if (buffer == NULL) {
3063
1
          xmlErrMemory(ctxt, NULL);
3064
1
    return(NULL);
3065
1
      }
3066
7.45k
      memcpy(buffer, buf, len);
3067
1.13M
      while (c != 0) { /* tested bigname2.xml */
3068
1.13M
    if (len + 10 > max) {
3069
6.59k
        xmlChar *tmp;
3070
3071
6.59k
        max *= 2;
3072
6.59k
        tmp = (xmlChar *) xmlRealloc(buffer, max);
3073
6.59k
        if (tmp == NULL) {
3074
2
      xmlErrMemory(ctxt, NULL);
3075
2
      xmlFree(buffer);
3076
2
      return(NULL);
3077
2
        }
3078
6.59k
        buffer = tmp;
3079
6.59k
    }
3080
1.13M
    buffer[len++] = c;
3081
1.13M
    c = *cur++;
3082
1.13M
      }
3083
7.45k
      buffer[len] = 0;
3084
7.45k
  }
3085
3086
43.0k
  if (buffer == NULL)
3087
35.5k
      ret = xmlStrndup(buf, len);
3088
7.45k
  else {
3089
7.45k
      ret = buffer;
3090
7.45k
  }
3091
43.0k
    }
3092
3093
135k
    return(ret);
3094
135k
}
3095
3096
/************************************************************************
3097
 *                  *
3098
 *      The parser itself       *
3099
 *  Relates to http://www.w3.org/TR/REC-xml       *
3100
 *                  *
3101
 ************************************************************************/
3102
3103
/************************************************************************
3104
 *                  *
3105
 *  Routines to parse Name, NCName and NmToken      *
3106
 *                  *
3107
 ************************************************************************/
3108
#ifdef DEBUG
3109
static unsigned long nbParseName = 0;
3110
static unsigned long nbParseNmToken = 0;
3111
static unsigned long nbParseNCName = 0;
3112
static unsigned long nbParseNCNameComplex = 0;
3113
static unsigned long nbParseNameComplex = 0;
3114
static unsigned long nbParseStringName = 0;
3115
#endif
3116
3117
/*
3118
 * The two following functions are related to the change of accepted
3119
 * characters for Name and NmToken in the Revision 5 of XML-1.0
3120
 * They correspond to the modified production [4] and the new production [4a]
3121
 * changes in that revision. Also note that the macros used for the
3122
 * productions Letter, Digit, CombiningChar and Extender are not needed
3123
 * anymore.
3124
 * We still keep compatibility to pre-revision5 parsing semantic if the
3125
 * new XML_PARSE_OLD10 option is given to the parser.
3126
 */
3127
static int
3128
460k
xmlIsNameStartChar(xmlParserCtxtPtr ctxt, int c) {
3129
460k
    if ((ctxt->options & XML_PARSE_OLD10) == 0) {
3130
        /*
3131
   * Use the new checks of production [4] [4a] amd [5] of the
3132
   * Update 5 of XML-1.0
3133
   */
3134
460k
  if ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
3135
460k
      (((c >= 'a') && (c <= 'z')) ||
3136
446k
       ((c >= 'A') && (c <= 'Z')) ||
3137
446k
       (c == '_') || (c == ':') ||
3138
446k
       ((c >= 0xC0) && (c <= 0xD6)) ||
3139
446k
       ((c >= 0xD8) && (c <= 0xF6)) ||
3140
446k
       ((c >= 0xF8) && (c <= 0x2FF)) ||
3141
446k
       ((c >= 0x370) && (c <= 0x37D)) ||
3142
446k
       ((c >= 0x37F) && (c <= 0x1FFF)) ||
3143
446k
       ((c >= 0x200C) && (c <= 0x200D)) ||
3144
446k
       ((c >= 0x2070) && (c <= 0x218F)) ||
3145
446k
       ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3146
446k
       ((c >= 0x3001) && (c <= 0xD7FF)) ||
3147
446k
       ((c >= 0xF900) && (c <= 0xFDCF)) ||
3148
446k
       ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3149
446k
       ((c >= 0x10000) && (c <= 0xEFFFF))))
3150
298k
      return(1);
3151
460k
    } else {
3152
0
        if (IS_LETTER(c) || (c == '_') || (c == ':'))
3153
0
      return(1);
3154
0
    }
3155
162k
    return(0);
3156
460k
}
3157
3158
static int
3159
73.0M
xmlIsNameChar(xmlParserCtxtPtr ctxt, int c) {
3160
73.0M
    if ((ctxt->options & XML_PARSE_OLD10) == 0) {
3161
        /*
3162
   * Use the new checks of production [4] [4a] amd [5] of the
3163
   * Update 5 of XML-1.0
3164
   */
3165
73.0M
  if ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
3166
73.0M
      (((c >= 'a') && (c <= 'z')) ||
3167
73.0M
       ((c >= 'A') && (c <= 'Z')) ||
3168
73.0M
       ((c >= '0') && (c <= '9')) || /* !start */
3169
73.0M
       (c == '_') || (c == ':') ||
3170
73.0M
       (c == '-') || (c == '.') || (c == 0xB7) || /* !start */
3171
73.0M
       ((c >= 0xC0) && (c <= 0xD6)) ||
3172
73.0M
       ((c >= 0xD8) && (c <= 0xF6)) ||
3173
73.0M
       ((c >= 0xF8) && (c <= 0x2FF)) ||
3174
73.0M
       ((c >= 0x300) && (c <= 0x36F)) || /* !start */
3175
73.0M
       ((c >= 0x370) && (c <= 0x37D)) ||
3176
73.0M
       ((c >= 0x37F) && (c <= 0x1FFF)) ||
3177
73.0M
       ((c >= 0x200C) && (c <= 0x200D)) ||
3178
73.0M
       ((c >= 0x203F) && (c <= 0x2040)) || /* !start */
3179
73.0M
       ((c >= 0x2070) && (c <= 0x218F)) ||
3180
73.0M
       ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3181
73.0M
       ((c >= 0x3001) && (c <= 0xD7FF)) ||
3182
73.0M
       ((c >= 0xF900) && (c <= 0xFDCF)) ||
3183
73.0M
       ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3184
73.0M
       ((c >= 0x10000) && (c <= 0xEFFFF))))
3185
72.7M
       return(1);
3186
73.0M
    } else {
3187
0
        if ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
3188
0
            (c == '.') || (c == '-') ||
3189
0
      (c == '_') || (c == ':') ||
3190
0
      (IS_COMBINING(c)) ||
3191
0
      (IS_EXTENDER(c)))
3192
0
      return(1);
3193
0
    }
3194
319k
    return(0);
3195
73.0M
}
3196
3197
static xmlChar * xmlParseAttValueInternal(xmlParserCtxtPtr ctxt,
3198
                                          int *len, int *alloc, int normalize);
3199
3200
static const xmlChar *
3201
435k
xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
3202
435k
    int len = 0, l;
3203
435k
    int c;
3204
435k
    int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
3205
0
                    XML_MAX_TEXT_LENGTH :
3206
435k
                    XML_MAX_NAME_LENGTH;
3207
3208
#ifdef DEBUG
3209
    nbParseNameComplex++;
3210
#endif
3211
3212
    /*
3213
     * Handler for more complex cases
3214
     */
3215
435k
    c = CUR_CHAR(l);
3216
435k
    if ((ctxt->options & XML_PARSE_OLD10) == 0) {
3217
        /*
3218
   * Use the new checks of production [4] [4a] amd [5] of the
3219
   * Update 5 of XML-1.0
3220
   */
3221
435k
  if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
3222
435k
      (!(((c >= 'a') && (c <= 'z')) ||
3223
430k
         ((c >= 'A') && (c <= 'Z')) ||
3224
430k
         (c == '_') || (c == ':') ||
3225
430k
         ((c >= 0xC0) && (c <= 0xD6)) ||
3226
430k
         ((c >= 0xD8) && (c <= 0xF6)) ||
3227
430k
         ((c >= 0xF8) && (c <= 0x2FF)) ||
3228
430k
         ((c >= 0x370) && (c <= 0x37D)) ||
3229
430k
         ((c >= 0x37F) && (c <= 0x1FFF)) ||
3230
430k
         ((c >= 0x200C) && (c <= 0x200D)) ||
3231
430k
         ((c >= 0x2070) && (c <= 0x218F)) ||
3232
430k
         ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3233
430k
         ((c >= 0x3001) && (c <= 0xD7FF)) ||
3234
430k
         ((c >= 0xF900) && (c <= 0xFDCF)) ||
3235
430k
         ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3236
430k
         ((c >= 0x10000) && (c <= 0xEFFFF))))) {
3237
123k
      return(NULL);
3238
123k
  }
3239
311k
  len += l;
3240
311k
  NEXTL(l);
3241
311k
  c = CUR_CHAR(l);
3242
67.2M
  while ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
3243
67.2M
         (((c >= 'a') && (c <= 'z')) ||
3244
67.2M
          ((c >= 'A') && (c <= 'Z')) ||
3245
67.2M
          ((c >= '0') && (c <= '9')) || /* !start */
3246
67.2M
          (c == '_') || (c == ':') ||
3247
67.2M
          (c == '-') || (c == '.') || (c == 0xB7) || /* !start */
3248
67.2M
          ((c >= 0xC0) && (c <= 0xD6)) ||
3249
67.2M
          ((c >= 0xD8) && (c <= 0xF6)) ||
3250
67.2M
          ((c >= 0xF8) && (c <= 0x2FF)) ||
3251
67.2M
          ((c >= 0x300) && (c <= 0x36F)) || /* !start */
3252
67.2M
          ((c >= 0x370) && (c <= 0x37D)) ||
3253
67.2M
          ((c >= 0x37F) && (c <= 0x1FFF)) ||
3254
67.2M
          ((c >= 0x200C) && (c <= 0x200D)) ||
3255
67.2M
          ((c >= 0x203F) && (c <= 0x2040)) || /* !start */
3256
67.2M
          ((c >= 0x2070) && (c <= 0x218F)) ||
3257
67.2M
          ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3258
67.2M
          ((c >= 0x3001) && (c <= 0xD7FF)) ||
3259
67.2M
          ((c >= 0xF900) && (c <= 0xFDCF)) ||
3260
67.2M
          ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3261
67.2M
          ((c >= 0x10000) && (c <= 0xEFFFF))
3262
67.2M
    )) {
3263
66.9M
            if (len <= INT_MAX - l)
3264
66.9M
          len += l;
3265
66.9M
      NEXTL(l);
3266
66.9M
      c = CUR_CHAR(l);
3267
66.9M
  }
3268
311k
    } else {
3269
0
  if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
3270
0
      (!IS_LETTER(c) && (c != '_') &&
3271
0
       (c != ':'))) {
3272
0
      return(NULL);
3273
0
  }
3274
0
  len += l;
3275
0
  NEXTL(l);
3276
0
  c = CUR_CHAR(l);
3277
3278
0
  while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
3279
0
         ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
3280
0
    (c == '.') || (c == '-') ||
3281
0
    (c == '_') || (c == ':') ||
3282
0
    (IS_COMBINING(c)) ||
3283
0
    (IS_EXTENDER(c)))) {
3284
0
            if (len <= INT_MAX - l)
3285
0
          len += l;
3286
0
      NEXTL(l);
3287
0
      c = CUR_CHAR(l);
3288
0
  }
3289
0
    }
3290
311k
    if (ctxt->instate == XML_PARSER_EOF)
3291
1.06k
        return(NULL);
3292
310k
    if (len > maxLength) {
3293
360
        xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name");
3294
360
        return(NULL);
3295
360
    }
3296
310k
    if (ctxt->input->cur - ctxt->input->base < len) {
3297
        /*
3298
         * There were a couple of bugs where PERefs lead to to a change
3299
         * of the buffer. Check the buffer size to avoid passing an invalid
3300
         * pointer to xmlDictLookup.
3301
         */
3302
0
        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
3303
0
                    "unexpected change of input buffer");
3304
0
        return (NULL);
3305
0
    }
3306
310k
    if ((*ctxt->input->cur == '\n') && (ctxt->input->cur[-1] == '\r'))
3307
1.13k
        return(xmlDictLookup(ctxt->dict, ctxt->input->cur - (len + 1), len));
3308
308k
    return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
3309
310k
}
3310
3311
/**
3312
 * xmlParseName:
3313
 * @ctxt:  an XML parser context
3314
 *
3315
 * DEPRECATED: Internal function, don't use.
3316
 *
3317
 * parse an XML name.
3318
 *
3319
 * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
3320
 *                  CombiningChar | Extender
3321
 *
3322
 * [5] Name ::= (Letter | '_' | ':') (NameChar)*
3323
 *
3324
 * [6] Names ::= Name (#x20 Name)*
3325
 *
3326
 * Returns the Name parsed or NULL
3327
 */
3328
3329
const xmlChar *
3330
1.33M
xmlParseName(xmlParserCtxtPtr ctxt) {
3331
1.33M
    const xmlChar *in;
3332
1.33M
    const xmlChar *ret;
3333
1.33M
    size_t count = 0;
3334
1.33M
    size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
3335
0
                       XML_MAX_TEXT_LENGTH :
3336
1.33M
                       XML_MAX_NAME_LENGTH;
3337
3338
1.33M
    GROW;
3339
1.33M
    if (ctxt->instate == XML_PARSER_EOF)
3340
622
        return(NULL);
3341
3342
#ifdef DEBUG
3343
    nbParseName++;
3344
#endif
3345
3346
    /*
3347
     * Accelerator for simple ASCII names
3348
     */
3349
1.33M
    in = ctxt->input->cur;
3350
1.33M
    if (((*in >= 0x61) && (*in <= 0x7A)) ||
3351
1.33M
  ((*in >= 0x41) && (*in <= 0x5A)) ||
3352
1.33M
  (*in == '_') || (*in == ':')) {
3353
1.01M
  in++;
3354
13.4M
  while (((*in >= 0x61) && (*in <= 0x7A)) ||
3355
13.4M
         ((*in >= 0x41) && (*in <= 0x5A)) ||
3356
13.4M
         ((*in >= 0x30) && (*in <= 0x39)) ||
3357
13.4M
         (*in == '_') || (*in == '-') ||
3358
13.4M
         (*in == ':') || (*in == '.'))
3359
12.4M
      in++;
3360
1.01M
  if ((*in > 0) && (*in < 0x80)) {
3361
899k
      count = in - ctxt->input->cur;
3362
899k
            if (count > maxLength) {
3363
126
                xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name");
3364
126
                return(NULL);
3365
126
            }
3366
898k
      ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
3367
898k
      ctxt->input->cur = in;
3368
898k
      ctxt->input->col += count;
3369
898k
      if (ret == NULL)
3370
22
          xmlErrMemory(ctxt, NULL);
3371
898k
      return(ret);
3372
899k
  }
3373
1.01M
    }
3374
    /* accelerator for special cases */
3375
435k
    return(xmlParseNameComplex(ctxt));
3376
1.33M
}
3377
3378
static const xmlChar *
3379
333k
xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
3380
333k
    int len = 0, l;
3381
333k
    int c;
3382
333k
    int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
3383
0
                    XML_MAX_TEXT_LENGTH :
3384
333k
                    XML_MAX_NAME_LENGTH;
3385
333k
    size_t startPosition = 0;
3386
3387
#ifdef DEBUG
3388
    nbParseNCNameComplex++;
3389
#endif
3390
3391
    /*
3392
     * Handler for more complex cases
3393
     */
3394
333k
    startPosition = CUR_PTR - BASE_PTR;
3395
333k
    c = CUR_CHAR(l);
3396
333k
    if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
3397
333k
  (!xmlIsNameStartChar(ctxt, c) || (c == ':'))) {
3398
217k
  return(NULL);
3399
217k
    }
3400
3401
33.0M
    while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
3402
33.0M
     (xmlIsNameChar(ctxt, c) && (c != ':'))) {
3403
32.9M
        if (len <= INT_MAX - l)
3404
32.9M
      len += l;
3405
32.9M
  NEXTL(l);
3406
32.9M
  c = CUR_CHAR(l);
3407
32.9M
    }
3408
115k
    if (ctxt->instate == XML_PARSER_EOF)
3409
676
        return(NULL);
3410
115k
    if (len > maxLength) {
3411
567
        xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
3412
567
        return(NULL);
3413
567
    }
3414
114k
    return(xmlDictLookup(ctxt->dict, (BASE_PTR + startPosition), len));
3415
115k
}
3416
3417
/**
3418
 * xmlParseNCName:
3419
 * @ctxt:  an XML parser context
3420
 * @len:  length of the string parsed
3421
 *
3422
 * parse an XML name.
3423
 *
3424
 * [4NS] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
3425
 *                      CombiningChar | Extender
3426
 *
3427
 * [5NS] NCName ::= (Letter | '_') (NCNameChar)*
3428
 *
3429
 * Returns the Name parsed or NULL
3430
 */
3431
3432
static const xmlChar *
3433
7.59M
xmlParseNCName(xmlParserCtxtPtr ctxt) {
3434
7.59M
    const xmlChar *in, *e;
3435
7.59M
    const xmlChar *ret;
3436
7.59M
    size_t count = 0;
3437
7.59M
    size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
3438
0
                       XML_MAX_TEXT_LENGTH :
3439
7.59M
                       XML_MAX_NAME_LENGTH;
3440
3441
#ifdef DEBUG
3442
    nbParseNCName++;
3443
#endif
3444
3445
    /*
3446
     * Accelerator for simple ASCII names
3447
     */
3448
7.59M
    in = ctxt->input->cur;
3449
7.59M
    e = ctxt->input->end;
3450
7.59M
    if ((((*in >= 0x61) && (*in <= 0x7A)) ||
3451
7.59M
   ((*in >= 0x41) && (*in <= 0x5A)) ||
3452
7.59M
   (*in == '_')) && (in < e)) {
3453
7.33M
  in++;
3454
84.6M
  while ((((*in >= 0x61) && (*in <= 0x7A)) ||
3455
84.6M
          ((*in >= 0x41) && (*in <= 0x5A)) ||
3456
84.6M
          ((*in >= 0x30) && (*in <= 0x39)) ||
3457
84.6M
          (*in == '_') || (*in == '-') ||
3458
84.6M
          (*in == '.')) && (in < e))
3459
77.3M
      in++;
3460
7.33M
  if (in >= e)
3461
828
      goto complex;
3462
7.32M
  if ((*in > 0) && (*in < 0x80)) {
3463
7.26M
      count = in - ctxt->input->cur;
3464
7.26M
            if (count > maxLength) {
3465
542
                xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
3466
542
                return(NULL);
3467
542
            }
3468
7.26M
      ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
3469
7.26M
      ctxt->input->cur = in;
3470
7.26M
      ctxt->input->col += count;
3471
7.26M
      if (ret == NULL) {
3472
24
          xmlErrMemory(ctxt, NULL);
3473
24
      }
3474
7.26M
      return(ret);
3475
7.26M
  }
3476
7.32M
    }
3477
333k
complex:
3478
333k
    return(xmlParseNCNameComplex(ctxt));
3479
7.59M
}
3480
3481
/**
3482
 * xmlParseNameAndCompare:
3483
 * @ctxt:  an XML parser context
3484
 *
3485
 * parse an XML name and compares for match
3486
 * (specialized for endtag parsing)
3487
 *
3488
 * Returns NULL for an illegal name, (xmlChar*) 1 for success
3489
 * and the name for mismatch
3490
 */
3491
3492
static const xmlChar *
3493
200k
xmlParseNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *other) {
3494
200k
    register const xmlChar *cmp = other;
3495
200k
    register const xmlChar *in;
3496
200k
    const xmlChar *ret;
3497
3498
200k
    GROW;
3499
200k
    if (ctxt->instate == XML_PARSER_EOF)
3500
91
        return(NULL);
3501
3502
200k
    in = ctxt->input->cur;
3503
1.07M
    while (*in != 0 && *in == *cmp) {
3504
870k
  ++in;
3505
870k
  ++cmp;
3506
870k
    }
3507
200k
    if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) {
3508
  /* success */
3509
192k
  ctxt->input->col += in - ctxt->input->cur;
3510
192k
  ctxt->input->cur = in;
3511
192k
  return (const xmlChar*) 1;
3512
192k
    }
3513
    /* failure (or end of input buffer), check with full function */
3514
8.01k
    ret = xmlParseName (ctxt);
3515
    /* strings coming from the dictionary direct compare possible */
3516
8.01k
    if (ret == other) {
3517
668
  return (const xmlChar*) 1;
3518
668
    }
3519
7.35k
    return ret;
3520
8.01k
}
3521
3522
/**
3523
 * xmlParseStringName:
3524
 * @ctxt:  an XML parser context
3525
 * @str:  a pointer to the string pointer (IN/OUT)
3526
 *
3527
 * parse an XML name.
3528
 *
3529
 * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
3530
 *                  CombiningChar | Extender
3531
 *
3532
 * [5] Name ::= (Letter | '_' | ':') (NameChar)*
3533
 *
3534
 * [6] Names ::= Name (#x20 Name)*
3535
 *
3536
 * Returns the Name parsed or NULL. The @str pointer
3537
 * is updated to the current location in the string.
3538
 */
3539
3540
static xmlChar *
3541
151k
xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
3542
151k
    xmlChar buf[XML_MAX_NAMELEN + 5];
3543
151k
    const xmlChar *cur = *str;
3544
151k
    int len = 0, l;
3545
151k
    int c;
3546
151k
    int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
3547
0
                    XML_MAX_TEXT_LENGTH :
3548
151k
                    XML_MAX_NAME_LENGTH;
3549
3550
#ifdef DEBUG
3551
    nbParseStringName++;
3552
#endif
3553
3554
151k
    c = CUR_SCHAR(cur, l);
3555
151k
    if (!xmlIsNameStartChar(ctxt, c)) {
3556
16.2k
  return(NULL);
3557
16.2k
    }
3558
3559
134k
    COPY_BUF(l,buf,len,c);
3560
134k
    cur += l;
3561
134k
    c = CUR_SCHAR(cur, l);
3562
818k
    while (xmlIsNameChar(ctxt, c)) {
3563
687k
  COPY_BUF(l,buf,len,c);
3564
687k
  cur += l;
3565
687k
  c = CUR_SCHAR(cur, l);
3566
687k
  if (len >= XML_MAX_NAMELEN) { /* test bigentname.xml */
3567
      /*
3568
       * Okay someone managed to make a huge name, so he's ready to pay
3569
       * for the processing speed.
3570
       */
3571
3.47k
      xmlChar *buffer;
3572
3.47k
      int max = len * 2;
3573
3574
3.47k
      buffer = (xmlChar *) xmlMallocAtomic(max);
3575
3.47k
      if (buffer == NULL) {
3576
2
          xmlErrMemory(ctxt, NULL);
3577
2
    return(NULL);
3578
2
      }
3579
3.47k
      memcpy(buffer, buf, len);
3580
13.0M
      while (xmlIsNameChar(ctxt, c)) {
3581
13.0M
    if (len + 10 > max) {
3582
11.8k
        xmlChar *tmp;
3583
3584
11.8k
        max *= 2;
3585
11.8k
        tmp = (xmlChar *) xmlRealloc(buffer, max);
3586
11.8k
        if (tmp == NULL) {
3587
1
      xmlErrMemory(ctxt, NULL);
3588
1
      xmlFree(buffer);
3589
1
      return(NULL);
3590
1
        }
3591
11.8k
        buffer = tmp;
3592
11.8k
    }
3593
13.0M
    COPY_BUF(l,buffer,len,c);
3594
13.0M
    cur += l;
3595
13.0M
    c = CUR_SCHAR(cur, l);
3596
13.0M
                if (len > maxLength) {
3597
519
                    xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
3598
519
                    xmlFree(buffer);
3599
519
                    return(NULL);
3600
519
                }
3601
13.0M
      }
3602
2.95k
      buffer[len] = 0;
3603
2.95k
      *str = cur;
3604
2.95k
      return(buffer);
3605
3.47k
  }
3606
687k
    }
3607
131k
    if (len > maxLength) {
3608
0
        xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
3609
0
        return(NULL);
3610
0
    }
3611
131k
    *str = cur;
3612
131k
    return(xmlStrndup(buf, len));
3613
131k
}
3614
3615
/**
3616
 * xmlParseNmtoken:
3617
 * @ctxt:  an XML parser context
3618
 *
3619
 * DEPRECATED: Internal function, don't use.
3620
 *
3621
 * parse an XML Nmtoken.
3622
 *
3623
 * [7] Nmtoken ::= (NameChar)+
3624
 *
3625
 * [8] Nmtokens ::= Nmtoken (#x20 Nmtoken)*
3626
 *
3627
 * Returns the Nmtoken parsed or NULL
3628
 */
3629
3630
xmlChar *
3631
112k
xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
3632
112k
    xmlChar buf[XML_MAX_NAMELEN + 5];
3633
112k
    int len = 0, l;
3634
112k
    int c;
3635
112k
    int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
3636
0
                    XML_MAX_TEXT_LENGTH :
3637
112k
                    XML_MAX_NAME_LENGTH;
3638
3639
#ifdef DEBUG
3640
    nbParseNmToken++;
3641
#endif
3642
3643
112k
    c = CUR_CHAR(l);
3644
3645
434k
    while (xmlIsNameChar(ctxt, c)) {
3646
324k
  COPY_BUF(l,buf,len,c);
3647
324k
  NEXTL(l);
3648
324k
  c = CUR_CHAR(l);
3649
324k
  if (len >= XML_MAX_NAMELEN) {
3650
      /*
3651
       * Okay someone managed to make a huge token, so he's ready to pay
3652
       * for the processing speed.
3653
       */
3654
2.64k
      xmlChar *buffer;
3655
2.64k
      int max = len * 2;
3656
3657
2.64k
      buffer = (xmlChar *) xmlMallocAtomic(max);
3658
2.64k
      if (buffer == NULL) {
3659
4
          xmlErrMemory(ctxt, NULL);
3660
4
    return(NULL);
3661
4
      }
3662
2.64k
      memcpy(buffer, buf, len);
3663
25.6M
      while (xmlIsNameChar(ctxt, c)) {
3664
25.6M
    if (len + 10 > max) {
3665
13.0k
        xmlChar *tmp;
3666
3667
13.0k
        max *= 2;
3668
13.0k
        tmp = (xmlChar *) xmlRealloc(buffer, max);
3669
13.0k
        if (tmp == NULL) {
3670
1
      xmlErrMemory(ctxt, NULL);
3671
1
      xmlFree(buffer);
3672
1
      return(NULL);
3673
1
        }
3674
13.0k
        buffer = tmp;
3675
13.0k
    }
3676
25.6M
    COPY_BUF(l,buffer,len,c);
3677
25.6M
                if (len > maxLength) {
3678
623
                    xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken");
3679
623
                    xmlFree(buffer);
3680
623
                    return(NULL);
3681
623
                }
3682
25.6M
    NEXTL(l);
3683
25.6M
    c = CUR_CHAR(l);
3684
25.6M
      }
3685
2.01k
      buffer[len] = 0;
3686
2.01k
            if (ctxt->instate == XML_PARSER_EOF) {
3687
689
                xmlFree(buffer);
3688
689
                return(NULL);
3689
689
            }
3690
1.32k
      return(buffer);
3691
2.01k
  }
3692
324k
    }
3693
109k
    if (ctxt->instate == XML_PARSER_EOF)
3694
288
        return(NULL);
3695
109k
    if (len == 0)
3696
27.3k
        return(NULL);
3697
82.2k
    if (len > maxLength) {
3698
0
        xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken");
3699
0
        return(NULL);
3700
0
    }
3701
82.2k
    return(xmlStrndup(buf, len));
3702
82.2k
}
3703
3704
/**
3705
 * xmlParseEntityValue:
3706
 * @ctxt:  an XML parser context
3707
 * @orig:  if non-NULL store a copy of the original entity value
3708
 *
3709
 * DEPRECATED: Internal function, don't use.
3710
 *
3711
 * parse a value for ENTITY declarations
3712
 *
3713
 * [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"' |
3714
 *                 "'" ([^%&'] | PEReference | Reference)* "'"
3715
 *
3716
 * Returns the EntityValue parsed with reference substituted or NULL
3717
 */
3718
3719
xmlChar *
3720
44.5k
xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
3721
44.5k
    xmlChar *buf = NULL;
3722
44.5k
    int len = 0;
3723
44.5k
    int size = XML_PARSER_BUFFER_SIZE;
3724
44.5k
    int c, l;
3725
44.5k
    int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
3726
0
                    XML_MAX_HUGE_LENGTH :
3727
44.5k
                    XML_MAX_TEXT_LENGTH;
3728
44.5k
    xmlChar stop;
3729
44.5k
    xmlChar *ret = NULL;
3730
44.5k
    const xmlChar *cur = NULL;
3731
44.5k
    xmlParserInputPtr input;
3732
3733
44.5k
    if (RAW == '"') stop = '"';
3734
19.1k
    else if (RAW == '\'') stop = '\'';
3735
0
    else {
3736
0
  xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_STARTED, NULL);
3737
0
  return(NULL);
3738
0
    }
3739
44.5k
    buf = (xmlChar *) xmlMallocAtomic(size);
3740
44.5k
    if (buf == NULL) {
3741
14
  xmlErrMemory(ctxt, NULL);
3742
14
  return(NULL);
3743
14
    }
3744
3745
    /*
3746
     * The content of the entity definition is copied in a buffer.
3747
     */
3748
3749
44.5k
    ctxt->instate = XML_PARSER_ENTITY_VALUE;
3750
44.5k
    input = ctxt->input;
3751
44.5k
    GROW;
3752
44.5k
    if (ctxt->instate == XML_PARSER_EOF)
3753
69
        goto error;
3754
44.4k
    NEXT;
3755
44.4k
    c = CUR_CHAR(l);
3756
    /*
3757
     * NOTE: 4.4.5 Included in Literal
3758
     * When a parameter entity reference appears in a literal entity
3759
     * value, ... a single or double quote character in the replacement
3760
     * text is always treated as a normal data character and will not
3761
     * terminate the literal.
3762
     * In practice it means we stop the loop only when back at parsing
3763
     * the initial entity and the quote is found
3764
     */
3765
253M
    while (((IS_CHAR(c)) && ((c != stop) || /* checked */
3766
253M
      (ctxt->input != input))) && (ctxt->instate != XML_PARSER_EOF)) {
3767
253M
  if (len + 5 >= size) {
3768
25.3k
      xmlChar *tmp;
3769
3770
25.3k
      size *= 2;
3771
25.3k
      tmp = (xmlChar *) xmlRealloc(buf, size);
3772
25.3k
      if (tmp == NULL) {
3773
2
    xmlErrMemory(ctxt, NULL);
3774
2
                goto error;
3775
2
      }
3776
25.3k
      buf = tmp;
3777
25.3k
  }
3778
253M
  COPY_BUF(l,buf,len,c);
3779
253M
  NEXTL(l);
3780
3781
253M
  GROW;
3782
253M
  c = CUR_CHAR(l);
3783
253M
  if (c == 0) {
3784
1.12k
      GROW;
3785
1.12k
      c = CUR_CHAR(l);
3786
1.12k
  }
3787
3788
253M
        if (len > maxLength) {
3789
2
            xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_NOT_FINISHED,
3790
2
                           "entity value too long\n");
3791
2
            goto error;
3792
2
        }
3793
253M
    }
3794
44.4k
    buf[len] = 0;
3795
44.4k
    if (ctxt->instate == XML_PARSER_EOF)
3796
287
        goto error;
3797
44.1k
    if (c != stop) {
3798
1.33k
        xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_FINISHED, NULL);
3799
1.33k
        goto error;
3800
1.33k
    }
3801
42.8k
    NEXT;
3802
3803
    /*
3804
     * Raise problem w.r.t. '&' and '%' being used in non-entities
3805
     * reference constructs. Note Charref will be handled in
3806
     * xmlStringDecodeEntities()
3807
     */
3808
42.8k
    cur = buf;
3809
699M
    while (*cur != 0) { /* non input consuming */
3810
699M
  if ((*cur == '%') || ((*cur == '&') && (cur[1] != '#'))) {
3811
22.5k
      xmlChar *name;
3812
22.5k
      xmlChar tmp = *cur;
3813
22.5k
            int nameOk = 0;
3814
3815
22.5k
      cur++;
3816
22.5k
      name = xmlParseStringName(ctxt, &cur);
3817
22.5k
            if (name != NULL) {
3818
21.4k
                nameOk = 1;
3819
21.4k
                xmlFree(name);
3820
21.4k
            }
3821
22.5k
            if ((nameOk == 0) || (*cur != ';')) {
3822
4.25k
    xmlFatalErrMsgInt(ctxt, XML_ERR_ENTITY_CHAR_ERROR,
3823
4.25k
      "EntityValue: '%c' forbidden except for entities references\n",
3824
4.25k
                            tmp);
3825
4.25k
                goto error;
3826
4.25k
      }
3827
18.2k
      if ((tmp == '%') && (ctxt->inSubset == 1) &&
3828
18.2k
    (ctxt->inputNr == 1)) {
3829
307
    xmlFatalErr(ctxt, XML_ERR_ENTITY_PE_INTERNAL, NULL);
3830
307
                goto error;
3831
307
      }
3832
17.9k
      if (*cur == 0)
3833
0
          break;
3834
17.9k
  }
3835
699M
  cur++;
3836
699M
    }
3837
3838
    /*
3839
     * Then PEReference entities are substituted.
3840
     *
3841
     * NOTE: 4.4.7 Bypassed
3842
     * When a general entity reference appears in the EntityValue in
3843
     * an entity declaration, it is bypassed and left as is.
3844
     * so XML_SUBSTITUTE_REF is not set here.
3845
     */
3846
38.2k
    ++ctxt->depth;
3847
38.2k
    ret = xmlStringDecodeEntitiesInt(ctxt, buf, len, XML_SUBSTITUTE_PEREF,
3848
38.2k
                                     0, 0, 0, /* check */ 1);
3849
38.2k
    --ctxt->depth;
3850
3851
38.2k
    if (orig != NULL) {
3852
38.2k
        *orig = buf;
3853
38.2k
        buf = NULL;
3854
38.2k
    }
3855
3856
44.5k
error:
3857
44.5k
    if (buf != NULL)
3858
6.25k
        xmlFree(buf);
3859
44.5k
    return(ret);
3860
38.2k
}
3861
3862
/**
3863
 * xmlParseAttValueComplex:
3864
 * @ctxt:  an XML parser context
3865
 * @len:   the resulting attribute len
3866
 * @normalize:  whether to apply the inner normalization
3867
 *
3868
 * parse a value for an attribute, this is the fallback function
3869
 * of xmlParseAttValue() when the attribute parsing requires handling
3870
 * of non-ASCII characters, or normalization compaction.
3871
 *
3872
 * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
3873
 */
3874
static xmlChar *
3875
389k
xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
3876
389k
    xmlChar limit = 0;
3877
389k
    xmlChar *buf = NULL;
3878
389k
    xmlChar *rep = NULL;
3879
389k
    size_t len = 0;
3880
389k
    size_t buf_size = 0;
3881
389k
    size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
3882
0
                       XML_MAX_HUGE_LENGTH :
3883
389k
                       XML_MAX_TEXT_LENGTH;
3884
389k
    int c, l, in_space = 0;
3885
389k
    xmlChar *current = NULL;
3886
389k
    xmlEntityPtr ent;
3887
3888
389k
    if (NXT(0) == '"') {
3889
352k
  ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
3890
352k
  limit = '"';
3891
352k
        NEXT;
3892
352k
    } else if (NXT(0) == '\'') {
3893
37.0k
  limit = '\'';
3894
37.0k
  ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
3895
37.0k
        NEXT;
3896
37.0k
    } else {
3897
0
  xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
3898
0
  return(NULL);
3899
0
    }
3900
3901
    /*
3902
     * allocate a translation buffer.
3903
     */
3904
389k
    buf_size = XML_PARSER_BUFFER_SIZE;
3905
389k
    buf = (xmlChar *) xmlMallocAtomic(buf_size);
3906
389k
    if (buf == NULL) goto mem_error;
3907
3908
    /*
3909
     * OK loop until we reach one of the ending char or a size limit.
3910
     */
3911
389k
    c = CUR_CHAR(l);
3912
116M
    while (((NXT(0) != limit) && /* checked */
3913
116M
            (IS_CHAR(c)) && (c != '<')) &&
3914
116M
            (ctxt->instate != XML_PARSER_EOF)) {
3915
115M
  if (c == '&') {
3916
553k
      in_space = 0;
3917
553k
      if (NXT(1) == '#') {
3918
473k
    int val = xmlParseCharRef(ctxt);
3919
3920
473k
    if (val == '&') {
3921
56.8k
        if (ctxt->replaceEntities) {
3922
56.8k
      if (len + 10 > buf_size) {
3923
1.38k
          growBuffer(buf, 10);
3924
1.38k
      }
3925
56.8k
      buf[len++] = '&';
3926
56.8k
        } else {
3927
      /*
3928
       * The reparsing will be done in xmlStringGetNodeList()
3929
       * called by the attribute() function in SAX.c
3930
       */
3931
0
      if (len + 10 > buf_size) {
3932
0
          growBuffer(buf, 10);
3933
0
      }
3934
0
      buf[len++] = '&';
3935
0
      buf[len++] = '#';
3936
0
      buf[len++] = '3';
3937
0
      buf[len++] = '8';
3938
0
      buf[len++] = ';';
3939
0
        }
3940
416k
    } else if (val != 0) {
3941
304k
        if (len + 10 > buf_size) {
3942
3.94k
      growBuffer(buf, 10);
3943
3.94k
        }
3944
304k
        len += xmlCopyChar(0, &buf[len], val);
3945
304k
    }
3946
473k
      } else {
3947
80.1k
    ent = xmlParseEntityRef(ctxt);
3948
80.1k
    if ((ent != NULL) &&
3949
80.1k
        (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
3950
5.26k
        if (len + 10 > buf_size) {
3951
461
      growBuffer(buf, 10);
3952
461
        }
3953
5.26k
        if ((ctxt->replaceEntities == 0) &&
3954
5.26k
            (ent->content[0] == '&')) {
3955
3
      buf[len++] = '&';
3956
3
      buf[len++] = '#';
3957
3
      buf[len++] = '3';
3958
3
      buf[len++] = '8';
3959
3
      buf[len++] = ';';
3960
5.26k
        } else {
3961
5.26k
      buf[len++] = ent->content[0];
3962
5.26k
        }
3963
74.8k
    } else if ((ent != NULL) &&
3964
74.8k
               (ctxt->replaceEntities != 0)) {
3965
19.9k
        if (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) {
3966
19.9k
                        if (xmlParserEntityCheck(ctxt, ent->length))
3967
19
                            goto error;
3968
3969
19.9k
      ++ctxt->depth;
3970
19.9k
      rep = xmlStringDecodeEntitiesInt(ctxt, ent->content,
3971
19.9k
                                ent->length, XML_SUBSTITUTE_REF, 0, 0, 0,
3972
19.9k
                                /* check */ 1);
3973
19.9k
      --ctxt->depth;
3974
19.9k
      if (rep != NULL) {
3975
16.5k
          current = rep;
3976
330M
          while (*current != 0) { /* non input consuming */
3977
330M
                                if ((*current == 0xD) || (*current == 0xA) ||
3978
330M
                                    (*current == 0x9)) {
3979
100k
                                    buf[len++] = 0x20;
3980
100k
                                    current++;
3981
100k
                                } else
3982
330M
                                    buf[len++] = *current++;
3983
330M
        if (len + 10 > buf_size) {
3984
12.5k
            growBuffer(buf, 10);
3985
12.5k
        }
3986
330M
          }
3987
16.5k
          xmlFree(rep);
3988
16.5k
          rep = NULL;
3989
16.5k
      }
3990
19.9k
        } else {
3991
0
      if (len + 10 > buf_size) {
3992
0
          growBuffer(buf, 10);
3993
0
      }
3994
0
      if (ent->content != NULL)
3995
0
          buf[len++] = ent->content[0];
3996
0
        }
3997
54.9k
    } else if (ent != NULL) {
3998
0
        int i = xmlStrlen(ent->name);
3999
0
        const xmlChar *cur = ent->name;
4000
4001
        /*
4002
                     * We also check for recursion and amplification
4003
                     * when entities are not substituted. They're
4004
                     * often expanded later.
4005
         */
4006
0
        if ((ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
4007
0
      (ent->content != NULL)) {
4008
0
                        if ((ent->flags & XML_ENT_CHECKED) == 0) {
4009
0
                            unsigned long oldCopy = ctxt->sizeentcopy;
4010
4011
0
                            ctxt->sizeentcopy = ent->length;
4012
4013
0
                            ++ctxt->depth;
4014
0
                            rep = xmlStringDecodeEntitiesInt(ctxt,
4015
0
                                    ent->content, ent->length,
4016
0
                                    XML_SUBSTITUTE_REF, 0, 0, 0,
4017
0
                                    /* check */ 1);
4018
0
                            --ctxt->depth;
4019
4020
                            /*
4021
                             * If we're parsing DTD content, the entity
4022
                             * might reference other entities which
4023
                             * weren't defined yet, so the check isn't
4024
                             * reliable.
4025
                             */
4026
0
                            if (ctxt->inSubset == 0) {
4027
0
                                ent->flags |= XML_ENT_CHECKED;
4028
0
                                ent->expandedSize = ctxt->sizeentcopy;
4029
0
                            }
4030
4031
0
                            if (rep != NULL) {
4032
0
                                xmlFree(rep);
4033
0
                                rep = NULL;
4034
0
                            } else {
4035
0
                                ent->content[0] = 0;
4036
0
                            }
4037
4038
0
                            if (xmlParserEntityCheck(ctxt, oldCopy))
4039
0
                                goto error;
4040
0
                        } else {
4041
0
                            if (xmlParserEntityCheck(ctxt, ent->expandedSize))
4042
0
                                goto error;
4043
0
                        }
4044
0
        }
4045
4046
        /*
4047
         * Just output the reference
4048
         */
4049
0
        buf[len++] = '&';
4050
0
        while (len + i + 10 > buf_size) {
4051
0
      growBuffer(buf, i + 10);
4052
0
        }
4053
0
        for (;i > 0;i--)
4054
0
      buf[len++] = *cur++;
4055
0
        buf[len++] = ';';
4056
0
    }
4057
80.1k
      }
4058
115M
  } else {
4059
115M
      if ((c == 0x20) || (c == 0xD) || (c == 0xA) || (c == 0x9)) {
4060
38.9M
          if ((len != 0) || (!normalize)) {
4061
38.9M
        if ((!normalize) || (!in_space)) {
4062
38.9M
      COPY_BUF(l,buf,len,0x20);
4063
38.9M
      while (len + 10 > buf_size) {
4064
70.6k
          growBuffer(buf, 10);
4065
70.6k
      }
4066
38.9M
        }
4067
38.9M
        in_space = 1;
4068
38.9M
    }
4069
76.3M
      } else {
4070
76.3M
          in_space = 0;
4071
76.3M
    COPY_BUF(l,buf,len,c);
4072
76.3M
    if (len + 10 > buf_size) {
4073
360k
        growBuffer(buf, 10);
4074
360k
    }
4075
76.3M
      }
4076
115M
      NEXTL(l);
4077
115M
  }
4078
115M
  GROW;
4079
115M
  c = CUR_CHAR(l);
4080
115M
        if (len > maxLength) {
4081
5
            xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
4082
5
                           "AttValue length too long\n");
4083
5
            goto mem_error;
4084
5
        }
4085
115M
    }
4086
389k
    if (ctxt->instate == XML_PARSER_EOF)
4087
1.25k
        goto error;
4088
4089
387k
    if ((in_space) && (normalize)) {
4090
12.0k
        while ((len > 0) && (buf[len - 1] == 0x20)) len--;
4091
5.75k
    }
4092
387k
    buf[len] = 0;
4093
387k
    if (RAW == '<') {
4094
66.1k
  xmlFatalErr(ctxt, XML_ERR_LT_IN_ATTRIBUTE, NULL);
4095
321k
    } else if (RAW != limit) {
4096
19.0k
  if ((c != 0) && (!IS_CHAR(c))) {
4097
14.6k
      xmlFatalErrMsg(ctxt, XML_ERR_INVALID_CHAR,
4098
14.6k
         "invalid character in attribute value\n");
4099
14.6k
  } else {
4100
4.33k
      xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
4101
4.33k
         "AttValue: ' expected\n");
4102
4.33k
        }
4103
19.0k
    } else
4104
302k
  NEXT;
4105
4106
387k
    if (attlen != NULL) *attlen = len;
4107
387k
    return(buf);
4108
4109
123
mem_error:
4110
123
    xmlErrMemory(ctxt, NULL);
4111
1.39k
error:
4112
1.39k
    if (buf != NULL)
4113
1.29k
        xmlFree(buf);
4114
1.39k
    if (rep != NULL)
4115
2
        xmlFree(rep);
4116
1.39k
    return(NULL);
4117
123
}
4118
4119
/**
4120
 * xmlParseAttValue:
4121
 * @ctxt:  an XML parser context
4122
 *
4123
 * DEPRECATED: Internal function, don't use.
4124
 *
4125
 * parse a value for an attribute
4126
 * Note: the parser won't do substitution of entities here, this
4127
 * will be handled later in xmlStringGetNodeList
4128
 *
4129
 * [10] AttValue ::= '"' ([^<&"] | Reference)* '"' |
4130
 *                   "'" ([^<&'] | Reference)* "'"
4131
 *
4132
 * 3.3.3 Attribute-Value Normalization:
4133
 * Before the value of an attribute is passed to the application or
4134
 * checked for validity, the XML processor must normalize it as follows:
4135
 * - a character reference is processed by appending the referenced
4136
 *   character to the attribute value
4137
 * - an entity reference is processed by recursively processing the
4138
 *   replacement text of the entity
4139
 * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
4140
 *   appending #x20 to the normalized value, except that only a single
4141
 *   #x20 is appended for a "#xD#xA" sequence that is part of an external
4142
 *   parsed entity or the literal entity value of an internal parsed entity
4143
 * - other characters are processed by appending them to the normalized value
4144
 * If the declared value is not CDATA, then the XML processor must further
4145
 * process the normalized attribute value by discarding any leading and
4146
 * trailing space (#x20) characters, and by replacing sequences of space
4147
 * (#x20) characters by a single space (#x20) character.
4148
 * All attributes for which no declaration has been read should be treated
4149
 * by a non-validating parser as if declared CDATA.
4150
 *
4151
 * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
4152
 */
4153
4154
4155
xmlChar *
4156
221k
xmlParseAttValue(xmlParserCtxtPtr ctxt) {
4157
221k
    if ((ctxt == NULL) || (ctxt->input == NULL)) return(NULL);
4158
221k
    return(xmlParseAttValueInternal(ctxt, NULL, NULL, 0));
4159
221k
}
4160
4161
/**
4162
 * xmlParseSystemLiteral:
4163
 * @ctxt:  an XML parser context
4164
 *
4165
 * DEPRECATED: Internal function, don't use.
4166
 *
4167
 * parse an XML Literal
4168
 *
4169
 * [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
4170
 *
4171
 * Returns the SystemLiteral parsed or NULL
4172
 */
4173
4174
xmlChar *
4175
31.8k
xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
4176
31.8k
    xmlChar *buf = NULL;
4177
31.8k
    int len = 0;
4178
31.8k
    int size = XML_PARSER_BUFFER_SIZE;
4179
31.8k
    int cur, l;
4180
31.8k
    int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
4181
0
                    XML_MAX_TEXT_LENGTH :
4182
31.8k
                    XML_MAX_NAME_LENGTH;
4183
31.8k
    xmlChar stop;
4184
31.8k
    int state = ctxt->instate;
4185
4186
31.8k
    if (RAW == '"') {
4187
11.9k
        NEXT;
4188
11.9k
  stop = '"';
4189
19.8k
    } else if (RAW == '\'') {
4190
17.6k
        NEXT;
4191
17.6k
  stop = '\'';
4192
17.6k
    } else {
4193
2.25k
  xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, NULL);
4194
2.25k
  return(NULL);
4195
2.25k
    }
4196
4197
29.6k
    buf = (xmlChar *) xmlMallocAtomic(size);
4198
29.6k
    if (buf == NULL) {
4199
7
        xmlErrMemory(ctxt, NULL);
4200
7
  return(NULL);
4201
7
    }
4202
29.6k
    ctxt->instate = XML_PARSER_SYSTEM_LITERAL;
4203
29.6k
    cur = CUR_CHAR(l);
4204
40.7M
    while ((IS_CHAR(cur)) && (cur != stop)) { /* checked */
4205
40.7M
  if (len + 5 >= size) {
4206
21.7k
      xmlChar *tmp;
4207
4208
21.7k
      size *= 2;
4209
21.7k
      tmp = (xmlChar *) xmlRealloc(buf, size);
4210
21.7k
      if (tmp == NULL) {
4211
1
          xmlFree(buf);
4212
1
    xmlErrMemory(ctxt, NULL);
4213
1
    ctxt->instate = (xmlParserInputState) state;
4214
1
    return(NULL);
4215
1
      }
4216
21.7k
      buf = tmp;
4217
21.7k
  }
4218
40.7M
  COPY_BUF(l,buf,len,cur);
4219
40.7M
        if (len > maxLength) {
4220
827
            xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "SystemLiteral");
4221
827
            xmlFree(buf);
4222
827
            ctxt->instate = (xmlParserInputState) state;
4223
827
            return(NULL);
4224
827
        }
4225
40.7M
  NEXTL(l);
4226
40.7M
  cur = CUR_CHAR(l);
4227
40.7M
    }
4228
28.7k
    buf[len] = 0;
4229
28.7k
    if (ctxt->instate == XML_PARSER_EOF) {
4230
285
        xmlFree(buf);
4231
285
        return(NULL);
4232
285
    }
4233
28.4k
    ctxt->instate = (xmlParserInputState) state;
4234
28.4k
    if (!IS_CHAR(cur)) {
4235
1.21k
  xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
4236
27.2k
    } else {
4237
27.2k
  NEXT;
4238
27.2k
    }
4239
28.4k
    return(buf);
4240
28.7k
}
4241
4242
/**
4243
 * xmlParsePubidLiteral:
4244
 * @ctxt:  an XML parser context
4245
 *
4246
 * DEPRECATED: Internal function, don't use.
4247
 *
4248
 * parse an XML public literal
4249
 *
4250
 * [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
4251
 *
4252
 * Returns the PubidLiteral parsed or NULL.
4253
 */
4254
4255
xmlChar *
4256
31.5k
xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
4257
31.5k
    xmlChar *buf = NULL;
4258
31.5k
    int len = 0;
4259
31.5k
    int size = XML_PARSER_BUFFER_SIZE;
4260
31.5k
    int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
4261
0
                    XML_MAX_TEXT_LENGTH :
4262
31.5k
                    XML_MAX_NAME_LENGTH;
4263
31.5k
    xmlChar cur;
4264
31.5k
    xmlChar stop;
4265
31.5k
    xmlParserInputState oldstate = ctxt->instate;
4266
4267
31.5k
    if (RAW == '"') {
4268
19.4k
        NEXT;
4269
19.4k
  stop = '"';
4270
19.4k
    } else if (RAW == '\'') {
4271
10.9k
        NEXT;
4272
10.9k
  stop = '\'';
4273
10.9k
    } else {
4274
1.19k
  xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, NULL);
4275
1.19k
  return(NULL);
4276
1.19k
    }
4277
30.3k
    buf = (xmlChar *) xmlMallocAtomic(size);
4278
30.3k
    if (buf == NULL) {
4279
5
  xmlErrMemory(ctxt, NULL);
4280
5
  return(NULL);
4281
5
    }
4282
30.3k
    ctxt->instate = XML_PARSER_PUBLIC_LITERAL;
4283
30.3k
    cur = CUR;
4284
1.57M
    while ((IS_PUBIDCHAR_CH(cur)) && (cur != stop)) { /* checked */
4285
1.53M
  if (len + 1 >= size) {
4286
5.22k
      xmlChar *tmp;
4287
4288
5.22k
      size *= 2;
4289
5.22k
      tmp = (xmlChar *) xmlRealloc(buf, size);
4290
5.22k
      if (tmp == NULL) {
4291
1
    xmlErrMemory(ctxt, NULL);
4292
1
    xmlFree(buf);
4293
1
    return(NULL);
4294
1
      }
4295
5.22k
      buf = tmp;
4296
5.22k
  }
4297
1.53M
  buf[len++] = cur;
4298
1.53M
        if (len > maxLength) {
4299
3
            xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Public ID");
4300
3
            xmlFree(buf);
4301
3
            return(NULL);
4302
3
        }
4303
1.53M
  NEXT;
4304
1.53M
  cur = CUR;
4305
1.53M
    }
4306
30.3k
    buf[len] = 0;
4307
30.3k
    if (ctxt->instate == XML_PARSER_EOF) {
4308
72
        xmlFree(buf);
4309
72
        return(NULL);
4310
72
    }
4311
30.2k
    if (cur != stop) {
4312
15.2k
  xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
4313
15.2k
    } else {
4314
15.0k
  NEXTL(1);
4315
15.0k
    }
4316
30.2k
    ctxt->instate = oldstate;
4317
30.2k
    return(buf);
4318
30.3k
}
4319
4320
static void xmlParseCharDataComplex(xmlParserCtxtPtr ctxt);
4321
4322
/*
4323
 * used for the test in the inner loop of the char data testing
4324
 */
4325
static const unsigned char test_char_data[256] = {
4326
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4327
    0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9, CR/LF separated */
4328
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4329
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4330
    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x00, 0x27, /* & */
4331
    0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
4332
    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
4333
    0x38, 0x39, 0x3A, 0x3B, 0x00, 0x3D, 0x3E, 0x3F, /* < */
4334
    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
4335
    0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
4336
    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
4337
    0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x00, 0x5E, 0x5F, /* ] */
4338
    0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
4339
    0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
4340
    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
4341
    0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
4342
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* non-ascii */
4343
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4344
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4345
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4346
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4347
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4348
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4349
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4350
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4351
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4352
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4353
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4354
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4355
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4356
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4357
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
4358
};
4359
4360
/**
4361
 * xmlParseCharData:
4362
 * @ctxt:  an XML parser context
4363
 * @cdata:  unused
4364
 *
4365
 * DEPRECATED: Internal function, don't use.
4366
 *
4367
 * Parse character data. Always makes progress if the first char isn't
4368
 * '<' or '&'.
4369
 *
4370
 * if we are within a CDATA section ']]>' marks an end of section.
4371
 *
4372
 * The right angle bracket (>) may be represented using the string "&gt;",
4373
 * and must, for compatibility, be escaped using "&gt;" or a character
4374
 * reference when it appears in the string "]]>" in content, when that
4375
 * string is not marking the end of a CDATA section.
4376
 *
4377
 * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
4378
 */
4379
4380
void
4381
2.66M
xmlParseCharData(xmlParserCtxtPtr ctxt, ATTRIBUTE_UNUSED int cdata) {
4382
2.66M
    const xmlChar *in;
4383
2.66M
    int nbchar = 0;
4384
2.66M
    int line = ctxt->input->line;
4385
2.66M
    int col = ctxt->input->col;
4386
2.66M
    int ccol;
4387
4388
2.66M
    GROW;
4389
    /*
4390
     * Accelerated common case where input don't need to be
4391
     * modified before passing it to the handler.
4392
     */
4393
2.66M
    in = ctxt->input->cur;
4394
2.74M
    do {
4395
3.62M
get_more_space:
4396
5.80M
        while (*in == 0x20) { in++; ctxt->input->col++; }
4397
3.62M
        if (*in == 0xA) {
4398
5.62M
            do {
4399
5.62M
                ctxt->input->line++; ctxt->input->col = 1;
4400
5.62M
                in++;
4401
5.62M
            } while (*in == 0xA);
4402
871k
            goto get_more_space;
4403
871k
        }
4404
2.74M
        if (*in == '<') {
4405
788k
            nbchar = in - ctxt->input->cur;
4406
788k
            if (nbchar > 0) {
4407
787k
                const xmlChar *tmp = ctxt->input->cur;
4408
787k
                ctxt->input->cur = in;
4409
4410
787k
                if ((ctxt->sax != NULL) &&
4411
787k
                    (ctxt->sax->ignorableWhitespace !=
4412
787k
                     ctxt->sax->characters)) {
4413
0
                    if (areBlanks(ctxt, tmp, nbchar, 1)) {
4414
0
                        if (ctxt->sax->ignorableWhitespace != NULL)
4415
0
                            ctxt->sax->ignorableWhitespace(ctxt->userData,
4416
0
                                                   tmp, nbchar);
4417
0
                    } else {
4418
0
                        if (ctxt->sax->characters != NULL)
4419
0
                            ctxt->sax->characters(ctxt->userData,
4420
0
                                                  tmp, nbchar);
4421
0
                        if (*ctxt->space == -1)
4422
0
                            *ctxt->space = -2;
4423
0
                    }
4424
787k
                } else if ((ctxt->sax != NULL) &&
4425
787k
                           (ctxt->sax->characters != NULL)) {
4426
787k
                    ctxt->sax->characters(ctxt->userData,
4427
787k
                                          tmp, nbchar);
4428
787k
                }
4429
787k
            }
4430
788k
            return;
4431
788k
        }
4432
4433
2.27M
get_more:
4434
2.27M
        ccol = ctxt->input->col;
4435
35.4M
        while (test_char_data[*in]) {
4436
33.1M
            in++;
4437
33.1M
            ccol++;
4438
33.1M
        }
4439
2.27M
        ctxt->input->col = ccol;
4440
2.27M
        if (*in == 0xA) {
4441
4.06M
            do {
4442
4.06M
                ctxt->input->line++; ctxt->input->col = 1;
4443
4.06M
                in++;
4444
4.06M
            } while (*in == 0xA);
4445
228k
            goto get_more;
4446
228k
        }
4447
2.04M
        if (*in == ']') {
4448
87.2k
            if ((in[1] == ']') && (in[2] == '>')) {
4449
1.58k
                xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
4450
1.58k
                ctxt->input->cur = in + 1;
4451
1.58k
                return;
4452
1.58k
            }
4453
85.6k
            in++;
4454
85.6k
            ctxt->input->col++;
4455
85.6k
            goto get_more;
4456
87.2k
        }
4457
1.95M
        nbchar = in - ctxt->input->cur;
4458
1.95M
        if (nbchar > 0) {
4459
1.31M
            if ((ctxt->sax != NULL) &&
4460
1.31M
                (ctxt->sax->ignorableWhitespace !=
4461
1.31M
                 ctxt->sax->characters) &&
4462
1.31M
                (IS_BLANK_CH(*ctxt->input->cur))) {
4463
0
                const xmlChar *tmp = ctxt->input->cur;
4464
0
                ctxt->input->cur = in;
4465
4466
0
                if (areBlanks(ctxt, tmp, nbchar, 0)) {
4467
0
                    if (ctxt->sax->ignorableWhitespace != NULL)
4468
0
                        ctxt->sax->ignorableWhitespace(ctxt->userData,
4469
0
                                                       tmp, nbchar);
4470
0
                } else {
4471
0
                    if (ctxt->sax->characters != NULL)
4472
0
                        ctxt->sax->characters(ctxt->userData,
4473
0
                                              tmp, nbchar);
4474
0
                    if (*ctxt->space == -1)
4475
0
                        *ctxt->space = -2;
4476
0
                }
4477
0
                line = ctxt->input->line;
4478
0
                col = ctxt->input->col;
4479
1.31M
            } else if (ctxt->sax != NULL) {
4480
1.31M
                if (ctxt->sax->characters != NULL)
4481
1.31M
                    ctxt->sax->characters(ctxt->userData,
4482
1.31M
                                          ctxt->input->cur, nbchar);
4483
1.31M
                line = ctxt->input->line;
4484
1.31M
                col = ctxt->input->col;
4485
1.31M
            }
4486
1.31M
        }
4487
1.95M
        ctxt->input->cur = in;
4488
1.95M
        if (*in == 0xD) {
4489
122k
            in++;
4490
122k
            if (*in == 0xA) {
4491
93.7k
                ctxt->input->cur = in;
4492
93.7k
                in++;
4493
93.7k
                ctxt->input->line++; ctxt->input->col = 1;
4494
93.7k
                continue; /* while */
4495
93.7k
            }
4496
28.3k
            in--;
4497
28.3k
        }
4498
1.86M
        if (*in == '<') {
4499
616k
            return;
4500
616k
        }
4501
1.24M
        if (*in == '&') {
4502
60.4k
            return;
4503
60.4k
        }
4504
1.18M
        SHRINK;
4505
1.18M
        GROW;
4506
1.18M
        if (ctxt->instate == XML_PARSER_EOF)
4507
269
            return;
4508
1.18M
        in = ctxt->input->cur;
4509
1.28M
    } while (((*in >= 0x20) && (*in <= 0x7F)) ||
4510
1.28M
             (*in == 0x09) || (*in == 0x0a));
4511
1.19M
    ctxt->input->line = line;
4512
1.19M
    ctxt->input->col = col;
4513
1.19M
    xmlParseCharDataComplex(ctxt);
4514
1.19M
}
4515
4516
/**
4517
 * xmlParseCharDataComplex:
4518
 * @ctxt:  an XML parser context
4519
 * @cdata:  int indicating whether we are within a CDATA section
4520
 *
4521
 * Always makes progress if the first char isn't '<' or '&'.
4522
 *
4523
 * parse a CharData section.this is the fallback function
4524
 * of xmlParseCharData() when the parsing requires handling
4525
 * of non-ASCII characters.
4526
 */
4527
static void
4528
1.19M
xmlParseCharDataComplex(xmlParserCtxtPtr ctxt) {
4529
1.19M
    xmlChar buf[XML_PARSER_BIG_BUFFER_SIZE + 5];
4530
1.19M
    int nbchar = 0;
4531
1.19M
    int cur, l;
4532
4533
1.19M
    cur = CUR_CHAR(l);
4534
320M
    while ((cur != '<') && /* checked */
4535
320M
           (cur != '&') &&
4536
320M
     (IS_CHAR(cur))) /* test also done in xmlCurrentChar() */ {
4537
319M
  if ((cur == ']') && (NXT(1) == ']') && (NXT(2) == '>')) {
4538
948
      xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
4539
948
  }
4540
319M
  COPY_BUF(l,buf,nbchar,cur);
4541
  /* move current position before possible calling of ctxt->sax->characters */
4542
319M
  NEXTL(l);
4543
319M
  if (nbchar >= XML_PARSER_BIG_BUFFER_SIZE) {
4544
2.15M
      buf[nbchar] = 0;
4545
4546
      /*
4547
       * OK the segment is to be consumed as chars.
4548
       */
4549
2.15M
      if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
4550
1.05M
    if (areBlanks(ctxt, buf, nbchar, 0)) {
4551
0
        if (ctxt->sax->ignorableWhitespace != NULL)
4552
0
      ctxt->sax->ignorableWhitespace(ctxt->userData,
4553
0
                                     buf, nbchar);
4554
1.05M
    } else {
4555
1.05M
        if (ctxt->sax->characters != NULL)
4556
1.05M
      ctxt->sax->characters(ctxt->userData, buf, nbchar);
4557
1.05M
        if ((ctxt->sax->characters !=
4558
1.05M
             ctxt->sax->ignorableWhitespace) &&
4559
1.05M
      (*ctxt->space == -1))
4560
0
      *ctxt->space = -2;
4561
1.05M
    }
4562
1.05M
      }
4563
2.15M
      nbchar = 0;
4564
            /* something really bad happened in the SAX callback */
4565
2.15M
            if (ctxt->instate != XML_PARSER_CONTENT)
4566
7
                return;
4567
2.15M
            SHRINK;
4568
2.15M
  }
4569
319M
  cur = CUR_CHAR(l);
4570
319M
    }
4571
1.19M
    if (ctxt->instate == XML_PARSER_EOF)
4572
685
        return;
4573
1.19M
    if (nbchar != 0) {
4574
907k
        buf[nbchar] = 0;
4575
  /*
4576
   * OK the segment is to be consumed as chars.
4577
   */
4578
907k
  if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
4579
661k
      if (areBlanks(ctxt, buf, nbchar, 0)) {
4580
0
    if (ctxt->sax->ignorableWhitespace != NULL)
4581
0
        ctxt->sax->ignorableWhitespace(ctxt->userData, buf, nbchar);
4582
661k
      } else {
4583
661k
    if (ctxt->sax->characters != NULL)
4584
661k
        ctxt->sax->characters(ctxt->userData, buf, nbchar);
4585
661k
    if ((ctxt->sax->characters != ctxt->sax->ignorableWhitespace) &&
4586
661k
        (*ctxt->space == -1))
4587
0
        *ctxt->space = -2;
4588
661k
      }
4589
661k
  }
4590
907k
    }
4591
1.19M
    if ((ctxt->input->cur < ctxt->input->end) && (!IS_CHAR(cur))) {
4592
  /* Generate the error and skip the offending character */
4593
348k
        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
4594
348k
                          "PCDATA invalid Char value %d\n",
4595
348k
                    cur ? cur : CUR);
4596
348k
  NEXT;
4597
348k
    }
4598
1.19M
}
4599
4600
/**
4601
 * xmlParseExternalID:
4602
 * @ctxt:  an XML parser context
4603
 * @publicID:  a xmlChar** receiving PubidLiteral
4604
 * @strict: indicate whether we should restrict parsing to only
4605
 *          production [75], see NOTE below
4606
 *
4607
 * DEPRECATED: Internal function, don't use.
4608
 *
4609
 * Parse an External ID or a Public ID
4610
 *
4611
 * NOTE: Productions [75] and [83] interact badly since [75] can generate
4612
 *       'PUBLIC' S PubidLiteral S SystemLiteral
4613
 *
4614
 * [75] ExternalID ::= 'SYSTEM' S SystemLiteral
4615
 *                   | 'PUBLIC' S PubidLiteral S SystemLiteral
4616
 *
4617
 * [83] PublicID ::= 'PUBLIC' S PubidLiteral
4618
 *
4619
 * Returns the function returns SystemLiteral and in the second
4620
 *                case publicID receives PubidLiteral, is strict is off
4621
 *                it is possible to return NULL and have publicID set.
4622
 */
4623
4624
xmlChar *
4625
98.4k
xmlParseExternalID(xmlParserCtxtPtr ctxt, xmlChar **publicID, int strict) {
4626
98.4k
    xmlChar *URI = NULL;
4627
4628
98.4k
    *publicID = NULL;
4629
98.4k
    if (CMP6(CUR_PTR, 'S', 'Y', 'S', 'T', 'E', 'M')) {
4630
16.2k
        SKIP(6);
4631
16.2k
  if (SKIP_BLANKS == 0) {
4632
247
      xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4633
247
                     "Space required after 'SYSTEM'\n");
4634
247
  }
4635
16.2k
  URI = xmlParseSystemLiteral(ctxt);
4636
16.2k
  if (URI == NULL) {
4637
1.69k
      xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
4638
1.69k
        }
4639
82.1k
    } else if (CMP6(CUR_PTR, 'P', 'U', 'B', 'L', 'I', 'C')) {
4640
31.5k
        SKIP(6);
4641
31.5k
  if (SKIP_BLANKS == 0) {
4642
16.8k
      xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4643
16.8k
        "Space required after 'PUBLIC'\n");
4644
16.8k
  }
4645
31.5k
  *publicID = xmlParsePubidLiteral(ctxt);
4646
31.5k
  if (*publicID == NULL) {
4647
1.27k
      xmlFatalErr(ctxt, XML_ERR_PUBID_REQUIRED, NULL);
4648
1.27k
  }
4649
31.5k
  if (strict) {
4650
      /*
4651
       * We don't handle [83] so "S SystemLiteral" is required.
4652
       */
4653
13.4k
      if (SKIP_BLANKS == 0) {
4654
2.77k
    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4655
2.77k
      "Space required after the Public Identifier\n");
4656
2.77k
      }
4657
18.1k
  } else {
4658
      /*
4659
       * We handle [83] so we return immediately, if
4660
       * "S SystemLiteral" is not detected. We skip blanks if no
4661
             * system literal was found, but this is harmless since we must
4662
             * be at the end of a NotationDecl.
4663
       */
4664
18.1k
      if (SKIP_BLANKS == 0) return(NULL);
4665
8.02k
      if ((CUR != '\'') && (CUR != '"')) return(NULL);
4666
8.02k
  }
4667
15.5k
  URI = xmlParseSystemLiteral(ctxt);
4668
15.5k
  if (URI == NULL) {
4669
1.67k
      xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
4670
1.67k
        }
4671
15.5k
    }
4672
82.4k
    return(URI);
4673
98.4k
}
4674
4675
/**
4676
 * xmlParseCommentComplex:
4677
 * @ctxt:  an XML parser context
4678
 * @buf:  the already parsed part of the buffer
4679
 * @len:  number of bytes in the buffer
4680
 * @size:  allocated size of the buffer
4681
 *
4682
 * Skip an XML (SGML) comment <!-- .... -->
4683
 *  The spec says that "For compatibility, the string "--" (double-hyphen)
4684
 *  must not occur within comments. "
4685
 * This is the slow routine in case the accelerator for ascii didn't work
4686
 *
4687
 * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
4688
 */
4689
static void
4690
xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf,
4691
24.9k
                       size_t len, size_t size) {
4692
24.9k
    int q, ql;
4693
24.9k
    int r, rl;
4694
24.9k
    int cur, l;
4695
24.9k
    size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
4696
0
                       XML_MAX_HUGE_LENGTH :
4697
24.9k
                       XML_MAX_TEXT_LENGTH;
4698
24.9k
    int inputid;
4699
4700
24.9k
    inputid = ctxt->input->id;
4701
4702
24.9k
    if (buf == NULL) {
4703
4.65k
        len = 0;
4704
4.65k
  size = XML_PARSER_BUFFER_SIZE;
4705
4.65k
  buf = (xmlChar *) xmlMallocAtomic(size);
4706
4.65k
  if (buf == NULL) {
4707
253
      xmlErrMemory(ctxt, NULL);
4708
253
      return;
4709
253
  }
4710
4.65k
    }
4711
24.7k
    q = CUR_CHAR(ql);
4712
24.7k
    if (q == 0)
4713
1.05k
        goto not_terminated;
4714
23.6k
    if (!IS_CHAR(q)) {
4715
2.78k
        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
4716
2.78k
                          "xmlParseComment: invalid xmlChar value %d\n",
4717
2.78k
                    q);
4718
2.78k
  xmlFree (buf);
4719
2.78k
  return;
4720
2.78k
    }
4721
20.8k
    NEXTL(ql);
4722
20.8k
    r = CUR_CHAR(rl);
4723
20.8k
    if (r == 0)
4724
397
        goto not_terminated;
4725
20.5k
    if (!IS_CHAR(r)) {
4726
1.80k
        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
4727
1.80k
                          "xmlParseComment: invalid xmlChar value %d\n",
4728
1.80k
                    r);
4729
1.80k
  xmlFree (buf);
4730
1.80k
  return;
4731
1.80k
    }
4732
18.6k
    NEXTL(rl);
4733
18.6k
    cur = CUR_CHAR(l);
4734
18.6k
    if (cur == 0)
4735
274
        goto not_terminated;
4736
21.1M
    while (IS_CHAR(cur) && /* checked */
4737
21.1M
           ((cur != '>') ||
4738
21.1M
      (r != '-') || (q != '-'))) {
4739
21.1M
  if ((r == '-') && (q == '-')) {
4740
59.8k
      xmlFatalErr(ctxt, XML_ERR_HYPHEN_IN_COMMENT, NULL);
4741
59.8k
  }
4742
21.1M
  if (len + 5 >= size) {
4743
8.01k
      xmlChar *new_buf;
4744
8.01k
            size_t new_size;
4745
4746
8.01k
      new_size = size * 2;
4747
8.01k
      new_buf = (xmlChar *) xmlRealloc(buf, new_size);
4748
8.01k
      if (new_buf == NULL) {
4749
2
    xmlFree (buf);
4750
2
    xmlErrMemory(ctxt, NULL);
4751
2
    return;
4752
2
      }
4753
8.01k
      buf = new_buf;
4754
8.01k
            size = new_size;
4755
8.01k
  }
4756
21.1M
  COPY_BUF(ql,buf,len,q);
4757
21.1M
        if (len > maxLength) {
4758
1
            xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
4759
1
                         "Comment too big found", NULL);
4760
1
            xmlFree (buf);
4761
1
            return;
4762
1
        }
4763
4764
21.1M
  q = r;
4765
21.1M
  ql = rl;
4766
21.1M
  r = cur;
4767
21.1M
  rl = l;
4768
4769
21.1M
  NEXTL(l);
4770
21.1M
  cur = CUR_CHAR(l);
4771
4772
21.1M
    }
4773
18.4k
    buf[len] = 0;
4774
18.4k
    if (ctxt->instate == XML_PARSER_EOF) {
4775
208
        xmlFree(buf);
4776
208
        return;
4777
208
    }
4778
18.2k
    if (cur == 0) {
4779
2.56k
  xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
4780
2.56k
                       "Comment not terminated \n<!--%.50s\n", buf);
4781
15.6k
    } else if (!IS_CHAR(cur)) {
4782
6.65k
        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
4783
6.65k
                          "xmlParseComment: invalid xmlChar value %d\n",
4784
6.65k
                    cur);
4785
9.00k
    } else {
4786
9.00k
  if (inputid != ctxt->input->id) {
4787
0
      xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
4788
0
               "Comment doesn't start and stop in the same"
4789
0
                           " entity\n");
4790
0
  }
4791
9.00k
        NEXT;
4792
9.00k
  if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
4793
9.00k
      (!ctxt->disableSAX))
4794
6.97k
      ctxt->sax->comment(ctxt->userData, buf);
4795
9.00k
    }
4796
18.2k
    xmlFree(buf);
4797
18.2k
    return;
4798
1.72k
not_terminated:
4799
1.72k
    xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
4800
1.72k
       "Comment not terminated\n", NULL);
4801
1.72k
    xmlFree(buf);
4802
1.72k
    return;
4803
18.4k
}
4804
4805
/**
4806
 * xmlParseComment:
4807
 * @ctxt:  an XML parser context
4808
 *
4809
 * DEPRECATED: Internal function, don't use.
4810
 *
4811
 * Parse an XML (SGML) comment. Always consumes '<!'.
4812
 *
4813
 *  The spec says that "For compatibility, the string "--" (double-hyphen)
4814
 *  must not occur within comments. "
4815
 *
4816
 * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
4817
 */
4818
void
4819
99.5k
xmlParseComment(xmlParserCtxtPtr ctxt) {
4820
99.5k
    xmlChar *buf = NULL;
4821
99.5k
    size_t size = XML_PARSER_BUFFER_SIZE;
4822
99.5k
    size_t len = 0;
4823
99.5k
    size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
4824
0
                       XML_MAX_HUGE_LENGTH :
4825
99.5k
                       XML_MAX_TEXT_LENGTH;
4826
99.5k
    xmlParserInputState state;
4827
99.5k
    const xmlChar *in;
4828
99.5k
    size_t nbchar = 0;
4829
99.5k
    int ccol;
4830
99.5k
    int inputid;
4831
4832
    /*
4833
     * Check that there is a comment right here.
4834
     */
4835
99.5k
    if ((RAW != '<') || (NXT(1) != '!'))
4836
0
        return;
4837
99.5k
    SKIP(2);
4838
99.5k
    if ((RAW != '-') || (NXT(1) != '-'))
4839
245
        return;
4840
99.3k
    state = ctxt->instate;
4841
99.3k
    ctxt->instate = XML_PARSER_COMMENT;
4842
99.3k
    inputid = ctxt->input->id;
4843
99.3k
    SKIP(2);
4844
99.3k
    GROW;
4845
4846
    /*
4847
     * Accelerated common case where input don't need to be
4848
     * modified before passing it to the handler.
4849
     */
4850
99.3k
    in = ctxt->input->cur;
4851
100k
    do {
4852
100k
  if (*in == 0xA) {
4853
10.0k
      do {
4854
10.0k
    ctxt->input->line++; ctxt->input->col = 1;
4855
10.0k
    in++;
4856
10.0k
      } while (*in == 0xA);
4857
7.56k
  }
4858
151k
get_more:
4859
151k
        ccol = ctxt->input->col;
4860
4.01M
  while (((*in > '-') && (*in <= 0x7F)) ||
4861
4.01M
         ((*in >= 0x20) && (*in < '-')) ||
4862
4.01M
         (*in == 0x09)) {
4863
3.86M
        in++;
4864
3.86M
        ccol++;
4865
3.86M
  }
4866
151k
  ctxt->input->col = ccol;
4867
151k
  if (*in == 0xA) {
4868
52.6k
      do {
4869
52.6k
    ctxt->input->line++; ctxt->input->col = 1;
4870
52.6k
    in++;
4871
52.6k
      } while (*in == 0xA);
4872
17.2k
      goto get_more;
4873
17.2k
  }
4874
134k
  nbchar = in - ctxt->input->cur;
4875
  /*
4876
   * save current set of data
4877
   */
4878
134k
  if (nbchar > 0) {
4879
121k
      if ((ctxt->sax != NULL) &&
4880
121k
    (ctxt->sax->comment != NULL)) {
4881
121k
    if (buf == NULL) {
4882
91.4k
        if ((*in == '-') && (in[1] == '-'))
4883
64.7k
            size = nbchar + 1;
4884
26.6k
        else
4885
26.6k
            size = XML_PARSER_BUFFER_SIZE + nbchar;
4886
91.4k
        buf = (xmlChar *) xmlMallocAtomic(size);
4887
91.4k
        if (buf == NULL) {
4888
392
            xmlErrMemory(ctxt, NULL);
4889
392
      ctxt->instate = state;
4890
392
      return;
4891
392
        }
4892
91.0k
        len = 0;
4893
91.0k
    } else if (len + nbchar + 1 >= size) {
4894
5.54k
        xmlChar *new_buf;
4895
5.54k
        size  += len + nbchar + XML_PARSER_BUFFER_SIZE;
4896
5.54k
        new_buf = (xmlChar *) xmlRealloc(buf, size);
4897
5.54k
        if (new_buf == NULL) {
4898
1
            xmlFree (buf);
4899
1
      xmlErrMemory(ctxt, NULL);
4900
1
      ctxt->instate = state;
4901
1
      return;
4902
1
        }
4903
5.53k
        buf = new_buf;
4904
5.53k
    }
4905
121k
    memcpy(&buf[len], ctxt->input->cur, nbchar);
4906
121k
    len += nbchar;
4907
121k
    buf[len] = 0;
4908
121k
      }
4909
121k
  }
4910
133k
        if (len > maxLength) {
4911
0
            xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
4912
0
                         "Comment too big found", NULL);
4913
0
            xmlFree (buf);
4914
0
            return;
4915
0
        }
4916
133k
  ctxt->input->cur = in;
4917
133k
  if (*in == 0xA) {
4918
0
      in++;
4919
0
      ctxt->input->line++; ctxt->input->col = 1;
4920
0
  }
4921
133k
  if (*in == 0xD) {
4922
5.16k
      in++;
4923
5.16k
      if (*in == 0xA) {
4924
1.74k
    ctxt->input->cur = in;
4925
1.74k
    in++;
4926
1.74k
    ctxt->input->line++; ctxt->input->col = 1;
4927
1.74k
    goto get_more;
4928
1.74k
      }
4929
3.41k
      in--;
4930
3.41k
  }
4931
131k
  SHRINK;
4932
131k
  GROW;
4933
131k
        if (ctxt->instate == XML_PARSER_EOF) {
4934
205
            xmlFree(buf);
4935
205
            return;
4936
205
        }
4937
131k
  in = ctxt->input->cur;
4938
131k
  if (*in == '-') {
4939
105k
      if (in[1] == '-') {
4940
83.1k
          if (in[2] == '>') {
4941
73.7k
        if (ctxt->input->id != inputid) {
4942
0
      xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
4943
0
                     "comment doesn't start and stop in the"
4944
0
                                       " same entity\n");
4945
0
        }
4946
73.7k
        SKIP(3);
4947
73.7k
        if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
4948
73.7k
            (!ctxt->disableSAX)) {
4949
62.7k
      if (buf != NULL)
4950
60.0k
          ctxt->sax->comment(ctxt->userData, buf);
4951
2.72k
      else
4952
2.72k
          ctxt->sax->comment(ctxt->userData, BAD_CAST "");
4953
62.7k
        }
4954
73.7k
        if (buf != NULL)
4955
70.4k
            xmlFree(buf);
4956
73.7k
        if (ctxt->instate != XML_PARSER_EOF)
4957
73.7k
      ctxt->instate = state;
4958
73.7k
        return;
4959
73.7k
    }
4960
9.43k
    if (buf != NULL) {
4961
6.99k
        xmlFatalErrMsgStr(ctxt, XML_ERR_HYPHEN_IN_COMMENT,
4962
6.99k
                          "Double hyphen within comment: "
4963
6.99k
                                      "<!--%.50s\n",
4964
6.99k
              buf);
4965
6.99k
    } else
4966
2.43k
        xmlFatalErrMsgStr(ctxt, XML_ERR_HYPHEN_IN_COMMENT,
4967
2.43k
                          "Double hyphen within comment\n", NULL);
4968
9.43k
                if (ctxt->instate == XML_PARSER_EOF) {
4969
0
                    xmlFree(buf);
4970
0
                    return;
4971
0
                }
4972
9.43k
    in++;
4973
9.43k
    ctxt->input->col++;
4974
9.43k
      }
4975
31.3k
      in++;
4976
31.3k
      ctxt->input->col++;
4977
31.3k
      goto get_more;
4978
105k
  }
4979
131k
    } while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09) || (*in == 0x0a));
4980
24.9k
    xmlParseCommentComplex(ctxt, buf, len, size);
4981
24.9k
    ctxt->instate = state;
4982
24.9k
    return;
4983
99.3k
}
4984
4985
4986
/**
4987
 * xmlParsePITarget:
4988
 * @ctxt:  an XML parser context
4989
 *
4990
 * DEPRECATED: Internal function, don't use.
4991
 *
4992
 * parse the name of a PI
4993
 *
4994
 * [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
4995
 *
4996
 * Returns the PITarget name or NULL
4997
 */
4998
4999
const xmlChar *
5000
204k
xmlParsePITarget(xmlParserCtxtPtr ctxt) {
5001
204k
    const xmlChar *name;
5002
5003
204k
    name = xmlParseName(ctxt);
5004
204k
    if ((name != NULL) &&
5005
204k
        ((name[0] == 'x') || (name[0] == 'X')) &&
5006
204k
        ((name[1] == 'm') || (name[1] == 'M')) &&
5007
204k
        ((name[2] == 'l') || (name[2] == 'L'))) {
5008
11.3k
  int i;
5009
11.3k
  if ((name[0] == 'x') && (name[1] == 'm') &&
5010
11.3k
      (name[2] == 'l') && (name[3] == 0)) {
5011
3.92k
      xmlFatalErrMsg(ctxt, XML_ERR_RESERVED_XML_NAME,
5012
3.92k
     "XML declaration allowed only at the start of the document\n");
5013
3.92k
      return(name);
5014
7.40k
  } else if (name[3] == 0) {
5015
2.81k
      xmlFatalErr(ctxt, XML_ERR_RESERVED_XML_NAME, NULL);
5016
2.81k
      return(name);
5017
2.81k
  }
5018
10.0k
  for (i = 0;;i++) {
5019
10.0k
      if (xmlW3CPIs[i] == NULL) break;
5020
7.54k
      if (xmlStrEqual(name, (const xmlChar *)xmlW3CPIs[i]))
5021
2.04k
          return(name);
5022
7.54k
  }
5023
2.55k
  xmlWarningMsg(ctxt, XML_ERR_RESERVED_XML_NAME,
5024
2.55k
          "xmlParsePITarget: invalid name prefix 'xml'\n",
5025
2.55k
          NULL, NULL);
5026
2.55k
    }
5027
195k
    if ((name != NULL) && (xmlStrchr(name, ':') != NULL)) {
5028
28.7k
  xmlNsErr(ctxt, XML_NS_ERR_COLON,
5029
28.7k
     "colons are forbidden from PI names '%s'\n", name, NULL, NULL);
5030
28.7k
    }
5031
195k
    return(name);
5032
204k
}
5033
5034
#ifdef LIBXML_CATALOG_ENABLED
5035
/**
5036
 * xmlParseCatalogPI:
5037
 * @ctxt:  an XML parser context
5038
 * @catalog:  the PI value string
5039
 *
5040
 * parse an XML Catalog Processing Instruction.
5041
 *
5042
 * <?oasis-xml-catalog catalog="http://example.com/catalog.xml"?>
5043
 *
5044
 * Occurs only if allowed by the user and if happening in the Misc
5045
 * part of the document before any doctype information
5046
 * This will add the given catalog to the parsing context in order
5047
 * to be used if there is a resolution need further down in the document
5048
 */
5049
5050
static void
5051
6.49k
xmlParseCatalogPI(xmlParserCtxtPtr ctxt, const xmlChar *catalog) {
5052
6.49k
    xmlChar *URL = NULL;
5053
6.49k
    const xmlChar *tmp, *base;
5054
6.49k
    xmlChar marker;
5055
5056
6.49k
    tmp = catalog;
5057
6.49k
    while (IS_BLANK_CH(*tmp)) tmp++;
5058
6.49k
    if (xmlStrncmp(tmp, BAD_CAST"catalog", 7))
5059
1.46k
  goto error;
5060
5.02k
    tmp += 7;
5061
5.02k
    while (IS_BLANK_CH(*tmp)) tmp++;
5062
5.02k
    if (*tmp != '=') {
5063
298
  return;
5064
298
    }
5065
4.72k
    tmp++;
5066
6.91k
    while (IS_BLANK_CH(*tmp)) tmp++;
5067
4.72k
    marker = *tmp;
5068
4.72k
    if ((marker != '\'') && (marker != '"'))
5069
429
  goto error;
5070
4.30k
    tmp++;
5071
4.30k
    base = tmp;
5072
92.2k
    while ((*tmp != 0) && (*tmp != marker)) tmp++;
5073
4.30k
    if (*tmp == 0)
5074
697
  goto error;
5075
3.60k
    URL = xmlStrndup(base, tmp - base);
5076
3.60k
    tmp++;
5077
3.60k
    while (IS_BLANK_CH(*tmp)) tmp++;
5078
3.60k
    if (*tmp != 0)
5079
1.49k
  goto error;
5080
5081
2.11k
    if (URL != NULL) {
5082
2.11k
  ctxt->catalogs = xmlCatalogAddLocal(ctxt->catalogs, URL);
5083
2.11k
  xmlFree(URL);
5084
2.11k
    }
5085
2.11k
    return;
5086
5087
4.08k
error:
5088
4.08k
    xmlWarningMsg(ctxt, XML_WAR_CATALOG_PI,
5089
4.08k
            "Catalog PI syntax error: %s\n",
5090
4.08k
      catalog, NULL);
5091
4.08k
    if (URL != NULL)
5092
1.49k
  xmlFree(URL);
5093
4.08k
}
5094
#endif
5095
5096
/**
5097
 * xmlParsePI:
5098
 * @ctxt:  an XML parser context
5099
 *
5100
 * DEPRECATED: Internal function, don't use.
5101
 *
5102
 * parse an XML Processing Instruction.
5103
 *
5104
 * [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
5105
 *
5106
 * The processing is transferred to SAX once parsed.
5107
 */
5108
5109
void
5110
204k
xmlParsePI(xmlParserCtxtPtr ctxt) {
5111
204k
    xmlChar *buf = NULL;
5112
204k
    size_t len = 0;
5113
204k
    size_t size = XML_PARSER_BUFFER_SIZE;
5114
204k
    size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
5115
0
                       XML_MAX_HUGE_LENGTH :
5116
204k
                       XML_MAX_TEXT_LENGTH;
5117
204k
    int cur, l;
5118
204k
    const xmlChar *target;
5119
204k
    xmlParserInputState state;
5120
5121
204k
    if ((RAW == '<') && (NXT(1) == '?')) {
5122
204k
  int inputid = ctxt->input->id;
5123
204k
  state = ctxt->instate;
5124
204k
        ctxt->instate = XML_PARSER_PI;
5125
  /*
5126
   * this is a Processing Instruction.
5127
   */
5128
204k
  SKIP(2);
5129
5130
  /*
5131
   * Parse the target name and check for special support like
5132
   * namespace.
5133
   */
5134
204k
        target = xmlParsePITarget(ctxt);
5135
204k
  if (target != NULL) {
5136
190k
      if ((RAW == '?') && (NXT(1) == '>')) {
5137
91.4k
    if (inputid != ctxt->input->id) {
5138
0
        xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
5139
0
                             "PI declaration doesn't start and stop in"
5140
0
                                   " the same entity\n");
5141
0
    }
5142
91.4k
    SKIP(2);
5143
5144
    /*
5145
     * SAX: PI detected.
5146
     */
5147
91.4k
    if ((ctxt->sax) && (!ctxt->disableSAX) &&
5148
91.4k
        (ctxt->sax->processingInstruction != NULL))
5149
26.2k
        ctxt->sax->processingInstruction(ctxt->userData,
5150
26.2k
                                         target, NULL);
5151
91.4k
    if (ctxt->instate != XML_PARSER_EOF)
5152
91.2k
        ctxt->instate = state;
5153
91.4k
    return;
5154
91.4k
      }
5155
99.0k
      buf = (xmlChar *) xmlMallocAtomic(size);
5156
99.0k
      if (buf == NULL) {
5157
265
    xmlErrMemory(ctxt, NULL);
5158
265
    ctxt->instate = state;
5159
265
    return;
5160
265
      }
5161
98.7k
      if (SKIP_BLANKS == 0) {
5162
35.8k
    xmlFatalErrMsgStr(ctxt, XML_ERR_SPACE_REQUIRED,
5163
35.8k
        "ParsePI: PI %s space expected\n", target);
5164
35.8k
      }
5165
98.7k
      cur = CUR_CHAR(l);
5166
81.4M
      while (IS_CHAR(cur) && /* checked */
5167
81.4M
       ((cur != '?') || (NXT(1) != '>'))) {
5168
81.3M
    if (len + 5 >= size) {
5169
73.7k
        xmlChar *tmp;
5170
73.7k
                    size_t new_size = size * 2;
5171
73.7k
        tmp = (xmlChar *) xmlRealloc(buf, new_size);
5172
73.7k
        if (tmp == NULL) {
5173
2
      xmlErrMemory(ctxt, NULL);
5174
2
      xmlFree(buf);
5175
2
      ctxt->instate = state;
5176
2
      return;
5177
2
        }
5178
73.7k
        buf = tmp;
5179
73.7k
                    size = new_size;
5180
73.7k
    }
5181
81.3M
    COPY_BUF(l,buf,len,cur);
5182
81.3M
                if (len > maxLength) {
5183
2
                    xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
5184
2
                                      "PI %s too big found", target);
5185
2
                    xmlFree(buf);
5186
2
                    ctxt->instate = state;
5187
2
                    return;
5188
2
                }
5189
81.3M
    NEXTL(l);
5190
81.3M
    cur = CUR_CHAR(l);
5191
81.3M
      }
5192
98.7k
      buf[len] = 0;
5193
98.7k
            if (ctxt->instate == XML_PARSER_EOF) {
5194
584
                xmlFree(buf);
5195
584
                return;
5196
584
            }
5197
98.2k
      if (cur != '?') {
5198
20.5k
    xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
5199
20.5k
          "ParsePI: PI %s never end ...\n", target);
5200
77.6k
      } else {
5201
77.6k
    if (inputid != ctxt->input->id) {
5202
22.1k
        xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
5203
22.1k
                             "PI declaration doesn't start and stop in"
5204
22.1k
                                   " the same entity\n");
5205
22.1k
    }
5206
77.6k
    SKIP(2);
5207
5208
77.6k
#ifdef LIBXML_CATALOG_ENABLED
5209
77.6k
    if (((state == XML_PARSER_MISC) ||
5210
77.6k
               (state == XML_PARSER_START)) &&
5211
77.6k
        (xmlStrEqual(target, XML_CATALOG_PI))) {
5212
6.49k
        xmlCatalogAllow allow = xmlCatalogGetDefaults();
5213
6.49k
        if ((allow == XML_CATA_ALLOW_DOCUMENT) ||
5214
6.49k
      (allow == XML_CATA_ALLOW_ALL))
5215
6.49k
      xmlParseCatalogPI(ctxt, buf);
5216
6.49k
    }
5217
77.6k
#endif
5218
5219
5220
    /*
5221
     * SAX: PI detected.
5222
     */
5223
77.6k
    if ((ctxt->sax) && (!ctxt->disableSAX) &&
5224
77.6k
        (ctxt->sax->processingInstruction != NULL))
5225
17.5k
        ctxt->sax->processingInstruction(ctxt->userData,
5226
17.5k
                                         target, buf);
5227
77.6k
      }
5228
98.2k
      xmlFree(buf);
5229
98.2k
  } else {
5230
13.6k
      xmlFatalErr(ctxt, XML_ERR_PI_NOT_STARTED, NULL);
5231
13.6k
  }
5232
111k
  if (ctxt->instate != XML_PARSER_EOF)
5233
111k
      ctxt->instate = state;
5234
111k
    }
5235
204k
}
5236
5237
/**
5238
 * xmlParseNotationDecl:
5239
 * @ctxt:  an XML parser context
5240
 *
5241
 * DEPRECATED: Internal function, don't use.
5242
 *
5243
 * Parse a notation declaration. Always consumes '<!'.
5244
 *
5245
 * [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID |  PublicID) S? '>'
5246
 *
5247
 * Hence there is actually 3 choices:
5248
 *     'PUBLIC' S PubidLiteral
5249
 *     'PUBLIC' S PubidLiteral S SystemLiteral
5250
 * and 'SYSTEM' S SystemLiteral
5251
 *
5252
 * See the NOTE on xmlParseExternalID().
5253
 */
5254
5255
void
5256
24.9k
xmlParseNotationDecl(xmlParserCtxtPtr ctxt) {
5257
24.9k
    const xmlChar *name;
5258
24.9k
    xmlChar *Pubid;
5259
24.9k
    xmlChar *Systemid;
5260
5261
24.9k
    if ((CUR != '<') || (NXT(1) != '!'))
5262
0
        return;
5263
24.9k
    SKIP(2);
5264
5265
24.9k
    if (CMP8(CUR_PTR, 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
5266
23.4k
  int inputid = ctxt->input->id;
5267
23.4k
  SKIP(8);
5268
23.4k
  if (SKIP_BLANKS == 0) {
5269
225
      xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5270
225
         "Space required after '<!NOTATION'\n");
5271
225
      return;
5272
225
  }
5273
5274
23.1k
        name = xmlParseName(ctxt);
5275
23.1k
  if (name == NULL) {
5276
255
      xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
5277
255
      return;
5278
255
  }
5279
22.9k
  if (xmlStrchr(name, ':') != NULL) {
5280
229
      xmlNsErr(ctxt, XML_NS_ERR_COLON,
5281
229
         "colons are forbidden from notation names '%s'\n",
5282
229
         name, NULL, NULL);
5283
229
  }
5284
22.9k
  if (SKIP_BLANKS == 0) {
5285
747
      xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5286
747
         "Space required after the NOTATION name'\n");
5287
747
      return;
5288
747
  }
5289
5290
  /*
5291
   * Parse the IDs.
5292
   */
5293
22.1k
  Systemid = xmlParseExternalID(ctxt, &Pubid, 0);
5294
22.1k
  SKIP_BLANKS;
5295
5296
22.1k
  if (RAW == '>') {
5297
8.23k
      if (inputid != ctxt->input->id) {
5298
2.22k
    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
5299
2.22k
                         "Notation declaration doesn't start and stop"
5300
2.22k
                               " in the same entity\n");
5301
2.22k
      }
5302
8.23k
      NEXT;
5303
8.23k
      if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
5304
8.23k
    (ctxt->sax->notationDecl != NULL))
5305
4.62k
    ctxt->sax->notationDecl(ctxt->userData, name, Pubid, Systemid);
5306
13.9k
  } else {
5307
13.9k
      xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
5308
13.9k
  }
5309
22.1k
  if (Systemid != NULL) xmlFree(Systemid);
5310
22.1k
  if (Pubid != NULL) xmlFree(Pubid);
5311
22.1k
    }
5312
24.9k
}
5313
5314
/**
5315
 * xmlParseEntityDecl:
5316
 * @ctxt:  an XML parser context
5317
 *
5318
 * DEPRECATED: Internal function, don't use.
5319
 *
5320
 * Parse an entity declaration. Always consumes '<!'.
5321
 *
5322
 * [70] EntityDecl ::= GEDecl | PEDecl
5323
 *
5324
 * [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
5325
 *
5326
 * [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
5327
 *
5328
 * [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
5329
 *
5330
 * [74] PEDef ::= EntityValue | ExternalID
5331
 *
5332
 * [76] NDataDecl ::= S 'NDATA' S Name
5333
 *
5334
 * [ VC: Notation Declared ]
5335
 * The Name must match the declared name of a notation.
5336
 */
5337
5338
void
5339
62.5k
xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
5340
62.5k
    const xmlChar *name = NULL;
5341
62.5k
    xmlChar *value = NULL;
5342
62.5k
    xmlChar *URI = NULL, *literal = NULL;
5343
62.5k
    const xmlChar *ndata = NULL;
5344
62.5k
    int isParameter = 0;
5345
62.5k
    xmlChar *orig = NULL;
5346
5347
62.5k
    if ((CUR != '<') || (NXT(1) != '!'))
5348
0
        return;
5349
62.5k
    SKIP(2);
5350
5351
    /* GROW; done in the caller */
5352
62.5k
    if (CMP6(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'Y')) {
5353
61.3k
  int inputid = ctxt->input->id;
5354
61.3k
  SKIP(6);
5355
61.3k
  if (SKIP_BLANKS == 0) {
5356
1.44k
      xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5357
1.44k
         "Space required after '<!ENTITY'\n");
5358
1.44k
  }
5359
5360
61.3k
  if (RAW == '%') {
5361
13.4k
      NEXT;
5362
13.4k
      if (SKIP_BLANKS == 0) {
5363
2.31k
    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5364
2.31k
             "Space required after '%%'\n");
5365
2.31k
      }
5366
13.4k
      isParameter = 1;
5367
13.4k
  }
5368
5369
61.3k
        name = xmlParseName(ctxt);
5370
61.3k
  if (name == NULL) {
5371
464
      xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
5372
464
                     "xmlParseEntityDecl: no name\n");
5373
464
            return;
5374
464
  }
5375
60.8k
  if (xmlStrchr(name, ':') != NULL) {
5376
328
      xmlNsErr(ctxt, XML_NS_ERR_COLON,
5377
328
         "colons are forbidden from entities names '%s'\n",
5378
328
         name, NULL, NULL);
5379
328
  }
5380
60.8k
  if (SKIP_BLANKS == 0) {
5381
6.92k
      xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5382
6.92k
         "Space required after the entity name\n");
5383
6.92k
  }
5384
5385
60.8k
  ctxt->instate = XML_PARSER_ENTITY_DECL;
5386
  /*
5387
   * handle the various case of definitions...
5388
   */
5389
60.8k
  if (isParameter) {
5390
13.3k
      if ((RAW == '"') || (RAW == '\'')) {
5391
8.87k
          value = xmlParseEntityValue(ctxt, &orig);
5392
8.87k
    if (value) {
5393
6.82k
        if ((ctxt->sax != NULL) &&
5394
6.82k
      (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
5395
6.20k
      ctxt->sax->entityDecl(ctxt->userData, name,
5396
6.20k
                        XML_INTERNAL_PARAMETER_ENTITY,
5397
6.20k
            NULL, NULL, value);
5398
6.82k
    }
5399
8.87k
      } else {
5400
4.45k
          URI = xmlParseExternalID(ctxt, &literal, 1);
5401
4.45k
    if ((URI == NULL) && (literal == NULL)) {
5402
594
        xmlFatalErr(ctxt, XML_ERR_VALUE_REQUIRED, NULL);
5403
594
    }
5404
4.45k
    if (URI) {
5405
3.03k
        xmlURIPtr uri;
5406
5407
3.03k
        uri = xmlParseURI((const char *) URI);
5408
3.03k
        if (uri == NULL) {
5409
514
            xmlErrMsgStr(ctxt, XML_ERR_INVALID_URI,
5410
514
             "Invalid URI: %s\n", URI);
5411
      /*
5412
       * This really ought to be a well formedness error
5413
       * but the XML Core WG decided otherwise c.f. issue
5414
       * E26 of the XML erratas.
5415
       */
5416
2.51k
        } else {
5417
2.51k
      if (uri->fragment != NULL) {
5418
          /*
5419
           * Okay this is foolish to block those but not
5420
           * invalid URIs.
5421
           */
5422
398
          xmlFatalErr(ctxt, XML_ERR_URI_FRAGMENT, NULL);
5423
2.12k
      } else {
5424
2.12k
          if ((ctxt->sax != NULL) &&
5425
2.12k
        (!ctxt->disableSAX) &&
5426
2.12k
        (ctxt->sax->entityDecl != NULL))
5427
1.70k
        ctxt->sax->entityDecl(ctxt->userData, name,
5428
1.70k
              XML_EXTERNAL_PARAMETER_ENTITY,
5429
1.70k
              literal, URI, NULL);
5430
2.12k
      }
5431
2.51k
      xmlFreeURI(uri);
5432
2.51k
        }
5433
3.03k
    }
5434
4.45k
      }
5435
47.5k
  } else {
5436
47.5k
      if ((RAW == '"') || (RAW == '\'')) {
5437
35.6k
          value = xmlParseEntityValue(ctxt, &orig);
5438
35.6k
    if ((ctxt->sax != NULL) &&
5439
35.6k
        (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
5440
14.7k
        ctxt->sax->entityDecl(ctxt->userData, name,
5441
14.7k
        XML_INTERNAL_GENERAL_ENTITY,
5442
14.7k
        NULL, NULL, value);
5443
    /*
5444
     * For expat compatibility in SAX mode.
5445
     */
5446
35.6k
    if ((ctxt->myDoc == NULL) ||
5447
35.6k
        (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) {
5448
15.0k
        if (ctxt->myDoc == NULL) {
5449
3.04k
      ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
5450
3.04k
      if (ctxt->myDoc == NULL) {
5451
4
          xmlErrMemory(ctxt, "New Doc failed");
5452
4
          goto done;
5453
4
      }
5454
3.04k
      ctxt->myDoc->properties = XML_DOC_INTERNAL;
5455
3.04k
        }
5456
15.0k
        if (ctxt->myDoc->intSubset == NULL)
5457
3.04k
      ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
5458
3.04k
              BAD_CAST "fake", NULL, NULL);
5459
5460
15.0k
        xmlSAX2EntityDecl(ctxt, name, XML_INTERNAL_GENERAL_ENTITY,
5461
15.0k
                    NULL, NULL, value);
5462
15.0k
    }
5463
35.6k
      } else {
5464
11.8k
          URI = xmlParseExternalID(ctxt, &literal, 1);
5465
11.8k
    if ((URI == NULL) && (literal == NULL)) {
5466
1.20k
        xmlFatalErr(ctxt, XML_ERR_VALUE_REQUIRED, NULL);
5467
1.20k
    }
5468
11.8k
    if (URI) {
5469
10.2k
        xmlURIPtr uri;
5470
5471
10.2k
        uri = xmlParseURI((const char *)URI);
5472
10.2k
        if (uri == NULL) {
5473
1.31k
            xmlErrMsgStr(ctxt, XML_ERR_INVALID_URI,
5474
1.31k
             "Invalid URI: %s\n", URI);
5475
      /*
5476
       * This really ought to be a well formedness error
5477
       * but the XML Core WG decided otherwise c.f. issue
5478
       * E26 of the XML erratas.
5479
       */
5480
8.98k
        } else {
5481
8.98k
      if (uri->fragment != NULL) {
5482
          /*
5483
           * Okay this is foolish to block those but not
5484
           * invalid URIs.
5485
           */
5486
110
          xmlFatalErr(ctxt, XML_ERR_URI_FRAGMENT, NULL);
5487
110
      }
5488
8.98k
      xmlFreeURI(uri);
5489
8.98k
        }
5490
10.2k
    }
5491
11.8k
    if ((RAW != '>') && (SKIP_BLANKS == 0)) {
5492
2.30k
        xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5493
2.30k
           "Space required before 'NDATA'\n");
5494
2.30k
    }
5495
11.8k
    if (CMP5(CUR_PTR, 'N', 'D', 'A', 'T', 'A')) {
5496
4.14k
        SKIP(5);
5497
4.14k
        if (SKIP_BLANKS == 0) {
5498
201
      xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5499
201
               "Space required after 'NDATA'\n");
5500
201
        }
5501
4.14k
        ndata = xmlParseName(ctxt);
5502
4.14k
        if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
5503
4.14k
            (ctxt->sax->unparsedEntityDecl != NULL))
5504
1.54k
      ctxt->sax->unparsedEntityDecl(ctxt->userData, name,
5505
1.54k
            literal, URI, ndata);
5506
7.70k
    } else {
5507
7.70k
        if ((ctxt->sax != NULL) &&
5508
7.70k
            (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
5509
4.72k
      ctxt->sax->entityDecl(ctxt->userData, name,
5510
4.72k
            XML_EXTERNAL_GENERAL_PARSED_ENTITY,
5511
4.72k
            literal, URI, NULL);
5512
        /*
5513
         * For expat compatibility in SAX mode.
5514
         * assuming the entity replacement was asked for
5515
         */
5516
7.70k
        if ((ctxt->replaceEntities != 0) &&
5517
7.70k
      ((ctxt->myDoc == NULL) ||
5518
7.70k
      (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE)))) {
5519
889
      if (ctxt->myDoc == NULL) {
5520
360
          ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
5521
360
          if (ctxt->myDoc == NULL) {
5522
1
              xmlErrMemory(ctxt, "New Doc failed");
5523
1
        goto done;
5524
1
          }
5525
359
          ctxt->myDoc->properties = XML_DOC_INTERNAL;
5526
359
      }
5527
5528
888
      if (ctxt->myDoc->intSubset == NULL)
5529
360
          ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
5530
360
            BAD_CAST "fake", NULL, NULL);
5531
888
      xmlSAX2EntityDecl(ctxt, name,
5532
888
                  XML_EXTERNAL_GENERAL_PARSED_ENTITY,
5533
888
                  literal, URI, NULL);
5534
888
        }
5535
7.70k
    }
5536
11.8k
      }
5537
47.5k
  }
5538
60.8k
  if (ctxt->instate == XML_PARSER_EOF)
5539
536
      goto done;
5540
60.3k
  SKIP_BLANKS;
5541
60.3k
  if (RAW != '>') {
5542
4.75k
      xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_NOT_FINISHED,
5543
4.75k
              "xmlParseEntityDecl: entity %s not terminated\n", name);
5544
4.75k
      xmlHaltParser(ctxt);
5545
55.5k
  } else {
5546
55.5k
      if (inputid != ctxt->input->id) {
5547
23
    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
5548
23
                         "Entity declaration doesn't start and stop in"
5549
23
                               " the same entity\n");
5550
23
      }
5551
55.5k
      NEXT;
5552
55.5k
  }
5553
60.3k
  if (orig != NULL) {
5554
      /*
5555
       * Ugly mechanism to save the raw entity value.
5556
       */
5557
38.1k
      xmlEntityPtr cur = NULL;
5558
5559
38.1k
      if (isParameter) {
5560
7.03k
          if ((ctxt->sax != NULL) &&
5561
7.03k
        (ctxt->sax->getParameterEntity != NULL))
5562
7.03k
        cur = ctxt->sax->getParameterEntity(ctxt->userData, name);
5563
31.1k
      } else {
5564
31.1k
          if ((ctxt->sax != NULL) &&
5565
31.1k
        (ctxt->sax->getEntity != NULL))
5566
31.1k
        cur = ctxt->sax->getEntity(ctxt->userData, name);
5567
31.1k
    if ((cur == NULL) && (ctxt->userData==ctxt)) {
5568
3.92k
        cur = xmlSAX2GetEntity(ctxt, name);
5569
3.92k
    }
5570
31.1k
      }
5571
38.1k
            if ((cur != NULL) && (cur->orig == NULL)) {
5572
26.6k
    cur->orig = orig;
5573
26.6k
                orig = NULL;
5574
26.6k
      }
5575
38.1k
  }
5576
5577
60.8k
done:
5578
60.8k
  if (value != NULL) xmlFree(value);
5579
60.8k
  if (URI != NULL) xmlFree(URI);
5580
60.8k
  if (literal != NULL) xmlFree(literal);
5581
60.8k
        if (orig != NULL) xmlFree(orig);
5582
60.8k
    }
5583
62.5k
}
5584
5585
/**
5586
 * xmlParseDefaultDecl:
5587
 * @ctxt:  an XML parser context
5588
 * @value:  Receive a possible fixed default value for the attribute
5589
 *
5590
 * DEPRECATED: Internal function, don't use.
5591
 *
5592
 * Parse an attribute default declaration
5593
 *
5594
 * [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)
5595
 *
5596
 * [ VC: Required Attribute ]
5597
 * if the default declaration is the keyword #REQUIRED, then the
5598
 * attribute must be specified for all elements of the type in the
5599
 * attribute-list declaration.
5600
 *
5601
 * [ VC: Attribute Default Legal ]
5602
 * The declared default value must meet the lexical constraints of
5603
 * the declared attribute type c.f. xmlValidateAttributeDecl()
5604
 *
5605
 * [ VC: Fixed Attribute Default ]
5606
 * if an attribute has a default value declared with the #FIXED
5607
 * keyword, instances of that attribute must match the default value.
5608
 *
5609
 * [ WFC: No < in Attribute Values ]
5610
 * handled in xmlParseAttValue()
5611
 *
5612
 * returns: XML_ATTRIBUTE_NONE, XML_ATTRIBUTE_REQUIRED, XML_ATTRIBUTE_IMPLIED
5613
 *          or XML_ATTRIBUTE_FIXED.
5614
 */
5615
5616
int
5617
225k
xmlParseDefaultDecl(xmlParserCtxtPtr ctxt, xmlChar **value) {
5618
225k
    int val;
5619
225k
    xmlChar *ret;
5620
5621
225k
    *value = NULL;
5622
225k
    if (CMP9(CUR_PTR, '#', 'R', 'E', 'Q', 'U', 'I', 'R', 'E', 'D')) {
5623
835
  SKIP(9);
5624
835
  return(XML_ATTRIBUTE_REQUIRED);
5625
835
    }
5626
224k
    if (CMP8(CUR_PTR, '#', 'I', 'M', 'P', 'L', 'I', 'E', 'D')) {
5627
2.68k
  SKIP(8);
5628
2.68k
  return(XML_ATTRIBUTE_IMPLIED);
5629
2.68k
    }
5630
221k
    val = XML_ATTRIBUTE_NONE;
5631
221k
    if (CMP6(CUR_PTR, '#', 'F', 'I', 'X', 'E', 'D')) {
5632
828
  SKIP(6);
5633
828
  val = XML_ATTRIBUTE_FIXED;
5634
828
  if (SKIP_BLANKS == 0) {
5635
39
      xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5636
39
         "Space required after '#FIXED'\n");
5637
39
  }
5638
828
    }
5639
221k
    ret = xmlParseAttValue(ctxt);
5640
221k
    ctxt->instate = XML_PARSER_DTD;
5641
221k
    if (ret == NULL) {
5642
11.9k
  xmlFatalErrMsg(ctxt, (xmlParserErrors)ctxt->errNo,
5643
11.9k
           "Attribute default value declaration error\n");
5644
11.9k
    } else
5645
210k
        *value = ret;
5646
221k
    return(val);
5647
224k
}
5648
5649
/**
5650
 * xmlParseNotationType:
5651
 * @ctxt:  an XML parser context
5652
 *
5653
 * DEPRECATED: Internal function, don't use.
5654
 *
5655
 * parse an Notation attribute type.
5656
 *
5657
 * Note: the leading 'NOTATION' S part has already being parsed...
5658
 *
5659
 * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
5660
 *
5661
 * [ VC: Notation Attributes ]
5662
 * Values of this type must match one of the notation names included
5663
 * in the declaration; all notation names in the declaration must be declared.
5664
 *
5665
 * Returns: the notation attribute tree built while parsing
5666
 */
5667
5668
xmlEnumerationPtr
5669
9.26k
xmlParseNotationType(xmlParserCtxtPtr ctxt) {
5670
9.26k
    const xmlChar *name;
5671
9.26k
    xmlEnumerationPtr ret = NULL, last = NULL, cur, tmp;
5672
5673
9.26k
    if (RAW != '(') {
5674
816
  xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
5675
816
  return(NULL);
5676
816
    }
5677
12.9k
    do {
5678
12.9k
        NEXT;
5679
12.9k
  SKIP_BLANKS;
5680
12.9k
        name = xmlParseName(ctxt);
5681
12.9k
  if (name == NULL) {
5682
763
      xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
5683
763
         "Name expected in NOTATION declaration\n");
5684
763
            xmlFreeEnumeration(ret);
5685
763
      return(NULL);
5686
763
  }
5687
12.1k
  tmp = ret;
5688
19.4k
  while (tmp != NULL) {
5689
9.64k
      if (xmlStrEqual(name, tmp->name)) {
5690
2.37k
    xmlValidityError(ctxt, XML_DTD_DUP_TOKEN,
5691
2.37k
    "standalone: attribute notation value token %s duplicated\n",
5692
2.37k
         name, NULL);
5693
2.37k
    if (!xmlDictOwns(ctxt->dict, name))
5694
0
        xmlFree((xmlChar *) name);
5695
2.37k
    break;
5696
2.37k
      }
5697
7.27k
      tmp = tmp->next;
5698
7.27k
  }
5699
12.1k
  if (tmp == NULL) {
5700
9.77k
      cur = xmlCreateEnumeration(name);
5701
9.77k
      if (cur == NULL) {
5702
14
                xmlFreeEnumeration(ret);
5703
14
                return(NULL);
5704
14
            }
5705
9.75k
      if (last == NULL) ret = last = cur;
5706
1.82k
      else {
5707
1.82k
    last->next = cur;
5708
1.82k
    last = cur;
5709
1.82k
      }
5710
9.75k
  }
5711
12.1k
  SKIP_BLANKS;
5712
12.1k
    } while (RAW == '|');
5713
7.67k
    if (RAW != ')') {
5714
4.55k
  xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
5715
4.55k
        xmlFreeEnumeration(ret);
5716
4.55k
  return(NULL);
5717
4.55k
    }
5718
3.11k
    NEXT;
5719
3.11k
    return(ret);
5720
7.67k
}
5721
5722
/**
5723
 * xmlParseEnumerationType:
5724
 * @ctxt:  an XML parser context
5725
 *
5726
 * DEPRECATED: Internal function, don't use.
5727
 *
5728
 * parse an Enumeration attribute type.
5729
 *
5730
 * [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
5731
 *
5732
 * [ VC: Enumeration ]
5733
 * Values of this type must match one of the Nmtoken tokens in
5734
 * the declaration
5735
 *
5736
 * Returns: the enumeration attribute tree built while parsing
5737
 */
5738
5739
xmlEnumerationPtr
5740
39.8k
xmlParseEnumerationType(xmlParserCtxtPtr ctxt) {
5741
39.8k
    xmlChar *name;
5742
39.8k
    xmlEnumerationPtr ret = NULL, last = NULL, cur, tmp;
5743
5744
39.8k
    if (RAW != '(') {
5745
10.6k
  xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_STARTED, NULL);
5746
10.6k
  return(NULL);
5747
10.6k
    }
5748
88.0k
    do {
5749
88.0k
        NEXT;
5750
88.0k
  SKIP_BLANKS;
5751
88.0k
        name = xmlParseNmtoken(ctxt);
5752
88.0k
  if (name == NULL) {
5753
12.8k
      xmlFatalErr(ctxt, XML_ERR_NMTOKEN_REQUIRED, NULL);
5754
12.8k
      return(ret);
5755
12.8k
  }
5756
75.2k
  tmp = ret;
5757
154k
  while (tmp != NULL) {
5758
116k
      if (xmlStrEqual(name, tmp->name)) {
5759
37.1k
    xmlValidityError(ctxt, XML_DTD_DUP_TOKEN,
5760
37.1k
    "standalone: attribute enumeration value token %s duplicated\n",
5761
37.1k
         name, NULL);
5762
37.1k
    if (!xmlDictOwns(ctxt->dict, name))
5763
37.1k
        xmlFree(name);
5764
37.1k
    break;
5765
37.1k
      }
5766
78.8k
      tmp = tmp->next;
5767
78.8k
  }
5768
75.2k
  if (tmp == NULL) {
5769
38.1k
      cur = xmlCreateEnumeration(name);
5770
38.1k
      if (!xmlDictOwns(ctxt->dict, name))
5771
38.1k
    xmlFree(name);
5772
38.1k
      if (cur == NULL) {
5773
1
                xmlFreeEnumeration(ret);
5774
1
                return(NULL);
5775
1
            }
5776
38.1k
      if (last == NULL) ret = last = cur;
5777
21.5k
      else {
5778
21.5k
    last->next = cur;
5779
21.5k
    last = cur;
5780
21.5k
      }
5781
38.1k
  }
5782
75.2k
  SKIP_BLANKS;
5783
75.2k
    } while (RAW == '|');
5784
16.3k
    if (RAW != ')') {
5785
7.74k
  xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_FINISHED, NULL);
5786
7.74k
  return(ret);
5787
7.74k
    }
5788
8.58k
    NEXT;
5789
8.58k
    return(ret);
5790
16.3k
}
5791
5792
/**
5793
 * xmlParseEnumeratedType:
5794
 * @ctxt:  an XML parser context
5795
 * @tree:  the enumeration tree built while parsing
5796
 *
5797
 * DEPRECATED: Internal function, don't use.
5798
 *
5799
 * parse an Enumerated attribute type.
5800
 *
5801
 * [57] EnumeratedType ::= NotationType | Enumeration
5802
 *
5803
 * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
5804
 *
5805
 *
5806
 * Returns: XML_ATTRIBUTE_ENUMERATION or XML_ATTRIBUTE_NOTATION
5807
 */
5808
5809
int
5810
49.1k
xmlParseEnumeratedType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
5811
49.1k
    if (CMP8(CUR_PTR, 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
5812
9.35k
  SKIP(8);
5813
9.35k
  if (SKIP_BLANKS == 0) {
5814
91
      xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5815
91
         "Space required after 'NOTATION'\n");
5816
91
      return(0);
5817
91
  }
5818
9.26k
  *tree = xmlParseNotationType(ctxt);
5819
9.26k
  if (*tree == NULL) return(0);
5820
3.11k
  return(XML_ATTRIBUTE_NOTATION);
5821
9.26k
    }
5822
39.8k
    *tree = xmlParseEnumerationType(ctxt);
5823
39.8k
    if (*tree == NULL) return(0);
5824
16.6k
    return(XML_ATTRIBUTE_ENUMERATION);
5825
39.8k
}
5826
5827
/**
5828
 * xmlParseAttributeType:
5829
 * @ctxt:  an XML parser context
5830
 * @tree:  the enumeration tree built while parsing
5831
 *
5832
 * DEPRECATED: Internal function, don't use.
5833
 *
5834
 * parse the Attribute list def for an element
5835
 *
5836
 * [54] AttType ::= StringType | TokenizedType | EnumeratedType
5837
 *
5838
 * [55] StringType ::= 'CDATA'
5839
 *
5840
 * [56] TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' |
5841
 *                        'ENTITIES' | 'NMTOKEN' | 'NMTOKENS'
5842
 *
5843
 * Validity constraints for attribute values syntax are checked in
5844
 * xmlValidateAttributeValue()
5845
 *
5846
 * [ VC: ID ]
5847
 * Values of type ID must match the Name production. A name must not
5848
 * appear more than once in an XML document as a value of this type;
5849
 * i.e., ID values must uniquely identify the elements which bear them.
5850
 *
5851
 * [ VC: One ID per Element Type ]
5852
 * No element type may have more than one ID attribute specified.
5853
 *
5854
 * [ VC: ID Attribute Default ]
5855
 * An ID attribute must have a declared default of #IMPLIED or #REQUIRED.
5856
 *
5857
 * [ VC: IDREF ]
5858
 * Values of type IDREF must match the Name production, and values
5859
 * of type IDREFS must match Names; each IDREF Name must match the value
5860
 * of an ID attribute on some element in the XML document; i.e. IDREF
5861
 * values must match the value of some ID attribute.
5862
 *
5863
 * [ VC: Entity Name ]
5864
 * Values of type ENTITY must match the Name production, values
5865
 * of type ENTITIES must match Names; each Entity Name must match the
5866
 * name of an unparsed entity declared in the DTD.
5867
 *
5868
 * [ VC: Name Token ]
5869
 * Values of type NMTOKEN must match the Nmtoken production; values
5870
 * of type NMTOKENS must match Nmtokens.
5871
 *
5872
 * Returns the attribute type
5873
 */
5874
int
5875
263k
xmlParseAttributeType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
5876
263k
    if (CMP5(CUR_PTR, 'C', 'D', 'A', 'T', 'A')) {
5877
16.6k
  SKIP(5);
5878
16.6k
  return(XML_ATTRIBUTE_CDATA);
5879
247k
     } else if (CMP6(CUR_PTR, 'I', 'D', 'R', 'E', 'F', 'S')) {
5880
2.24k
  SKIP(6);
5881
2.24k
  return(XML_ATTRIBUTE_IDREFS);
5882
244k
     } else if (CMP5(CUR_PTR, 'I', 'D', 'R', 'E', 'F')) {
5883
6.22k
  SKIP(5);
5884
6.22k
  return(XML_ATTRIBUTE_IDREF);
5885
238k
     } else if ((RAW == 'I') && (NXT(1) == 'D')) {
5886
188k
        SKIP(2);
5887
188k
  return(XML_ATTRIBUTE_ID);
5888
188k
     } else if (CMP6(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'Y')) {
5889
247
  SKIP(6);
5890
247
  return(XML_ATTRIBUTE_ENTITY);
5891
50.3k
     } else if (CMP8(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S')) {
5892
706
  SKIP(8);
5893
706
  return(XML_ATTRIBUTE_ENTITIES);
5894
49.6k
     } else if (CMP8(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S')) {
5895
87
  SKIP(8);
5896
87
  return(XML_ATTRIBUTE_NMTOKENS);
5897
49.5k
     } else if (CMP7(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N')) {
5898
355
  SKIP(7);
5899
355
  return(XML_ATTRIBUTE_NMTOKEN);
5900
355
     }
5901
49.1k
     return(xmlParseEnumeratedType(ctxt, tree));
5902
263k
}
5903
5904
/**
5905
 * xmlParseAttributeListDecl:
5906
 * @ctxt:  an XML parser context
5907
 *
5908
 * DEPRECATED: Internal function, don't use.
5909
 *
5910
 * Parse an attribute list declaration for an element. Always consumes '<!'.
5911
 *
5912
 * [52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
5913
 *
5914
 * [53] AttDef ::= S Name S AttType S DefaultDecl
5915
 *
5916
 */
5917
void
5918
115k
xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) {
5919
115k
    const xmlChar *elemName;
5920
115k
    const xmlChar *attrName;
5921
115k
    xmlEnumerationPtr tree;
5922
5923
115k
    if ((CUR != '<') || (NXT(1) != '!'))
5924
0
        return;
5925
115k
    SKIP(2);
5926
5927
115k
    if (CMP7(CUR_PTR, 'A', 'T', 'T', 'L', 'I', 'S', 'T')) {
5928
113k
  int inputid = ctxt->input->id;
5929
5930
113k
  SKIP(7);
5931
113k
  if (SKIP_BLANKS == 0) {
5932
18.5k
      xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5933
18.5k
                     "Space required after '<!ATTLIST'\n");
5934
18.5k
  }
5935
113k
        elemName = xmlParseName(ctxt);
5936
113k
  if (elemName == NULL) {
5937
571
      xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
5938
571
         "ATTLIST: no name for Element\n");
5939
571
      return;
5940
571
  }
5941
112k
  SKIP_BLANKS;
5942
112k
  GROW;
5943
321k
  while ((RAW != '>') && (ctxt->instate != XML_PARSER_EOF)) {
5944
283k
      int type;
5945
283k
      int def;
5946
283k
      xmlChar *defaultValue = NULL;
5947
5948
283k
      GROW;
5949
283k
            tree = NULL;
5950
283k
      attrName = xmlParseName(ctxt);
5951
283k
      if (attrName == NULL) {
5952
9.13k
    xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
5953
9.13k
             "ATTLIST: no name for Attribute\n");
5954
9.13k
    break;
5955
9.13k
      }
5956
273k
      GROW;
5957
273k
      if (SKIP_BLANKS == 0) {
5958
10.1k
    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5959
10.1k
            "Space required after the attribute name\n");
5960
10.1k
    break;
5961
10.1k
      }
5962
5963
263k
      type = xmlParseAttributeType(ctxt, &tree);
5964
263k
      if (type <= 0) {
5965
29.4k
          break;
5966
29.4k
      }
5967
5968
234k
      GROW;
5969
234k
      if (SKIP_BLANKS == 0) {
5970
8.87k
    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5971
8.87k
             "Space required after the attribute type\n");
5972
8.87k
          if (tree != NULL)
5973
8.02k
        xmlFreeEnumeration(tree);
5974
8.87k
    break;
5975
8.87k
      }
5976
5977
225k
      def = xmlParseDefaultDecl(ctxt, &defaultValue);
5978
225k
      if (def <= 0) {
5979
0
                if (defaultValue != NULL)
5980
0
        xmlFree(defaultValue);
5981
0
          if (tree != NULL)
5982
0
        xmlFreeEnumeration(tree);
5983
0
          break;
5984
0
      }
5985
225k
      if ((type != XML_ATTRIBUTE_CDATA) && (defaultValue != NULL))
5986
193k
          xmlAttrNormalizeSpace(defaultValue, defaultValue);
5987
5988
225k
      GROW;
5989
225k
            if (RAW != '>') {
5990
199k
    if (SKIP_BLANKS == 0) {
5991
17.0k
        xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5992
17.0k
      "Space required after the attribute default value\n");
5993
17.0k
        if (defaultValue != NULL)
5994
5.41k
      xmlFree(defaultValue);
5995
17.0k
        if (tree != NULL)
5996
8.56k
      xmlFreeEnumeration(tree);
5997
17.0k
        break;
5998
17.0k
    }
5999
199k
      }
6000
208k
      if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
6001
208k
    (ctxt->sax->attributeDecl != NULL))
6002
145k
    ctxt->sax->attributeDecl(ctxt->userData, elemName, attrName,
6003
145k
                          type, def, defaultValue, tree);
6004
63.0k
      else if (tree != NULL)
6005
1.87k
    xmlFreeEnumeration(tree);
6006
6007
208k
      if ((ctxt->sax2) && (defaultValue != NULL) &&
6008
208k
          (def != XML_ATTRIBUTE_IMPLIED) &&
6009
208k
    (def != XML_ATTRIBUTE_REQUIRED)) {
6010
204k
    xmlAddDefAttrs(ctxt, elemName, attrName, defaultValue);
6011
204k
      }
6012
208k
      if (ctxt->sax2) {
6013
208k
    xmlAddSpecialAttr(ctxt, elemName, attrName, type);
6014
208k
      }
6015
208k
      if (defaultValue != NULL)
6016
204k
          xmlFree(defaultValue);
6017
208k
      GROW;
6018
208k
  }
6019
112k
  if (RAW == '>') {
6020
39.1k
      if (inputid != ctxt->input->id) {
6021
201
    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6022
201
                               "Attribute list declaration doesn't start and"
6023
201
                               " stop in the same entity\n");
6024
201
      }
6025
39.1k
      NEXT;
6026
39.1k
  }
6027
112k
    }
6028
115k
}
6029
6030
/**
6031
 * xmlParseElementMixedContentDecl:
6032
 * @ctxt:  an XML parser context
6033
 * @inputchk:  the input used for the current entity, needed for boundary checks
6034
 *
6035
 * DEPRECATED: Internal function, don't use.
6036
 *
6037
 * parse the declaration for a Mixed Element content
6038
 * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
6039
 *
6040
 * [51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' |
6041
 *                '(' S? '#PCDATA' S? ')'
6042
 *
6043
 * [ VC: Proper Group/PE Nesting ] applies to [51] too (see [49])
6044
 *
6045
 * [ VC: No Duplicate Types ]
6046
 * The same name must not appear more than once in a single
6047
 * mixed-content declaration.
6048
 *
6049
 * returns: the list of the xmlElementContentPtr describing the element choices
6050
 */
6051
xmlElementContentPtr
6052
6.82k
xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
6053
6.82k
    xmlElementContentPtr ret = NULL, cur = NULL, n;
6054
6.82k
    const xmlChar *elem = NULL;
6055
6056
6.82k
    GROW;
6057
6.82k
    if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
6058
6.82k
  SKIP(7);
6059
6.82k
  SKIP_BLANKS;
6060
6.82k
  if (RAW == ')') {
6061
866
      if (ctxt->input->id != inputchk) {
6062
386
    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6063
386
                               "Element content declaration doesn't start and"
6064
386
                               " stop in the same entity\n");
6065
386
      }
6066
866
      NEXT;
6067
866
      ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA);
6068
866
      if (ret == NULL)
6069
1
          return(NULL);
6070
865
      if (RAW == '*') {
6071
207
    ret->ocur = XML_ELEMENT_CONTENT_MULT;
6072
207
    NEXT;
6073
207
      }
6074
865
      return(ret);
6075
866
  }
6076
5.95k
  if ((RAW == '(') || (RAW == '|')) {
6077
3.54k
      ret = cur = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA);
6078
3.54k
      if (ret == NULL) return(NULL);
6079
3.54k
  }
6080
10.5k
  while ((RAW == '|') && (ctxt->instate != XML_PARSER_EOF)) {
6081
4.99k
      NEXT;
6082
4.99k
      if (elem == NULL) {
6083
3.46k
          ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
6084
3.46k
    if (ret == NULL) {
6085
1
        xmlFreeDocElementContent(ctxt->myDoc, cur);
6086
1
                    return(NULL);
6087
1
                }
6088
3.46k
    ret->c1 = cur;
6089
3.46k
    if (cur != NULL)
6090
3.46k
        cur->parent = ret;
6091
3.46k
    cur = ret;
6092
3.46k
      } else {
6093
1.53k
          n = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
6094
1.53k
    if (n == NULL) {
6095
1
        xmlFreeDocElementContent(ctxt->myDoc, ret);
6096
1
                    return(NULL);
6097
1
                }
6098
1.53k
    n->c1 = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
6099
1.53k
    if (n->c1 != NULL)
6100
1.53k
        n->c1->parent = n;
6101
1.53k
          cur->c2 = n;
6102
1.53k
    if (n != NULL)
6103
1.53k
        n->parent = cur;
6104
1.53k
    cur = n;
6105
1.53k
      }
6106
4.99k
      SKIP_BLANKS;
6107
4.99k
      elem = xmlParseName(ctxt);
6108
4.99k
      if (elem == NULL) {
6109
386
    xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
6110
386
      "xmlParseElementMixedContentDecl : Name expected\n");
6111
386
    xmlFreeDocElementContent(ctxt->myDoc, ret);
6112
386
    return(NULL);
6113
386
      }
6114
4.60k
      SKIP_BLANKS;
6115
4.60k
      GROW;
6116
4.60k
  }
6117
5.56k
  if ((RAW == ')') && (NXT(1) == '*')) {
6118
2.46k
      if (elem != NULL) {
6119
2.46k
    cur->c2 = xmlNewDocElementContent(ctxt->myDoc, elem,
6120
2.46k
                                   XML_ELEMENT_CONTENT_ELEMENT);
6121
2.46k
    if (cur->c2 != NULL)
6122
2.45k
        cur->c2->parent = cur;
6123
2.46k
            }
6124
2.46k
            if (ret != NULL)
6125
2.46k
                ret->ocur = XML_ELEMENT_CONTENT_MULT;
6126
2.46k
      if (ctxt->input->id != inputchk) {
6127
6
    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6128
6
                               "Element content declaration doesn't start and"
6129
6
                               " stop in the same entity\n");
6130
6
      }
6131
2.46k
      SKIP(2);
6132
3.10k
  } else {
6133
3.10k
      xmlFreeDocElementContent(ctxt->myDoc, ret);
6134
3.10k
      xmlFatalErr(ctxt, XML_ERR_MIXED_NOT_STARTED, NULL);
6135
3.10k
      return(NULL);
6136
3.10k
  }
6137
6138
5.56k
    } else {
6139
0
  xmlFatalErr(ctxt, XML_ERR_PCDATA_REQUIRED, NULL);
6140
0
    }
6141
2.46k
    return(ret);
6142
6.82k
}
6143
6144
/**
6145
 * xmlParseElementChildrenContentDeclPriv:
6146
 * @ctxt:  an XML parser context
6147
 * @inputchk:  the input used for the current entity, needed for boundary checks
6148
 * @depth: the level of recursion
6149
 *
6150
 * parse the declaration for a Mixed Element content
6151
 * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
6152
 *
6153
 *
6154
 * [47] children ::= (choice | seq) ('?' | '*' | '+')?
6155
 *
6156
 * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
6157
 *
6158
 * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
6159
 *
6160
 * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
6161
 *
6162
 * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
6163
 * TODO Parameter-entity replacement text must be properly nested
6164
 *  with parenthesized groups. That is to say, if either of the
6165
 *  opening or closing parentheses in a choice, seq, or Mixed
6166
 *  construct is contained in the replacement text for a parameter
6167
 *  entity, both must be contained in the same replacement text. For
6168
 *  interoperability, if a parameter-entity reference appears in a
6169
 *  choice, seq, or Mixed construct, its replacement text should not
6170
 *  be empty, and neither the first nor last non-blank character of
6171
 *  the replacement text should be a connector (| or ,).
6172
 *
6173
 * Returns the tree of xmlElementContentPtr describing the element
6174
 *          hierarchy.
6175
 */
6176
static xmlElementContentPtr
6177
xmlParseElementChildrenContentDeclPriv(xmlParserCtxtPtr ctxt, int inputchk,
6178
162k
                                       int depth) {
6179
162k
    xmlElementContentPtr ret = NULL, cur = NULL, last = NULL, op = NULL;
6180
162k
    const xmlChar *elem;
6181
162k
    xmlChar type = 0;
6182
6183
162k
    if (((depth > 128) && ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
6184
162k
        (depth >  2048)) {
6185
253
        xmlFatalErrMsgInt(ctxt, XML_ERR_ELEMCONTENT_NOT_FINISHED,
6186
253
"xmlParseElementChildrenContentDecl : depth %d too deep, use XML_PARSE_HUGE\n",
6187
253
                          depth);
6188
253
  return(NULL);
6189
253
    }
6190
162k
    SKIP_BLANKS;
6191
162k
    GROW;
6192
162k
    if (RAW == '(') {
6193
97.6k
  int inputid = ctxt->input->id;
6194
6195
        /* Recurse on first child */
6196
97.6k
  NEXT;
6197
97.6k
  SKIP_BLANKS;
6198
97.6k
        cur = ret = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
6199
97.6k
                                                           depth + 1);
6200
97.6k
        if (cur == NULL)
6201
87.4k
            return(NULL);
6202
10.1k
  SKIP_BLANKS;
6203
10.1k
  GROW;
6204
65.0k
    } else {
6205
65.0k
  elem = xmlParseName(ctxt);
6206
65.0k
  if (elem == NULL) {
6207
2.29k
      xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
6208
2.29k
      return(NULL);
6209
2.29k
  }
6210
62.7k
        cur = ret = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
6211
62.7k
  if (cur == NULL) {
6212
8
      xmlErrMemory(ctxt, NULL);
6213
8
      return(NULL);
6214
8
  }
6215
62.7k
  GROW;
6216
62.7k
  if (RAW == '?') {
6217
12.7k
      cur->ocur = XML_ELEMENT_CONTENT_OPT;
6218
12.7k
      NEXT;
6219
50.0k
  } else if (RAW == '*') {
6220
3.18k
      cur->ocur = XML_ELEMENT_CONTENT_MULT;
6221
3.18k
      NEXT;
6222
46.8k
  } else if (RAW == '+') {
6223
2.07k
      cur->ocur = XML_ELEMENT_CONTENT_PLUS;
6224
2.07k
      NEXT;
6225
44.7k
  } else {
6226
44.7k
      cur->ocur = XML_ELEMENT_CONTENT_ONCE;
6227
44.7k
  }
6228
62.7k
  GROW;
6229
62.7k
    }
6230
72.9k
    SKIP_BLANKS;
6231
108k
    while ((RAW != ')') && (ctxt->instate != XML_PARSER_EOF)) {
6232
        /*
6233
   * Each loop we parse one separator and one element.
6234
   */
6235
67.6k
        if (RAW == ',') {
6236
25.2k
      if (type == 0) type = CUR;
6237
6238
      /*
6239
       * Detect "Name | Name , Name" error
6240
       */
6241
12.5k
      else if (type != CUR) {
6242
45
    xmlFatalErrMsgInt(ctxt, XML_ERR_SEPARATOR_REQUIRED,
6243
45
        "xmlParseElementChildrenContentDecl : '%c' expected\n",
6244
45
                      type);
6245
45
    if ((last != NULL) && (last != ret))
6246
45
        xmlFreeDocElementContent(ctxt->myDoc, last);
6247
45
    if (ret != NULL)
6248
45
        xmlFreeDocElementContent(ctxt->myDoc, ret);
6249
45
    return(NULL);
6250
45
      }
6251
25.2k
      NEXT;
6252
6253
25.2k
      op = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_SEQ);
6254
25.2k
      if (op == NULL) {
6255
2
    if ((last != NULL) && (last != ret))
6256
1
        xmlFreeDocElementContent(ctxt->myDoc, last);
6257
2
          xmlFreeDocElementContent(ctxt->myDoc, ret);
6258
2
    return(NULL);
6259
2
      }
6260
25.2k
      if (last == NULL) {
6261
12.7k
    op->c1 = ret;
6262
12.7k
    if (ret != NULL)
6263
12.7k
        ret->parent = op;
6264
12.7k
    ret = cur = op;
6265
12.7k
      } else {
6266
12.4k
          cur->c2 = op;
6267
12.4k
    if (op != NULL)
6268
12.4k
        op->parent = cur;
6269
12.4k
    op->c1 = last;
6270
12.4k
    if (last != NULL)
6271
12.4k
        last->parent = op;
6272
12.4k
    cur =op;
6273
12.4k
    last = NULL;
6274
12.4k
      }
6275
42.3k
  } else if (RAW == '|') {
6276
27.6k
      if (type == 0) type = CUR;
6277
6278
      /*
6279
       * Detect "Name , Name | Name" error
6280
       */
6281
12.1k
      else if (type != CUR) {
6282
219
    xmlFatalErrMsgInt(ctxt, XML_ERR_SEPARATOR_REQUIRED,
6283
219
        "xmlParseElementChildrenContentDecl : '%c' expected\n",
6284
219
          type);
6285
219
    if ((last != NULL) && (last != ret))
6286
219
        xmlFreeDocElementContent(ctxt->myDoc, last);
6287
219
    if (ret != NULL)
6288
219
        xmlFreeDocElementContent(ctxt->myDoc, ret);
6289
219
    return(NULL);
6290
219
      }
6291
27.4k
      NEXT;
6292
6293
27.4k
      op = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
6294
27.4k
      if (op == NULL) {
6295
2
    if ((last != NULL) && (last != ret))
6296
1
        xmlFreeDocElementContent(ctxt->myDoc, last);
6297
2
    if (ret != NULL)
6298
2
        xmlFreeDocElementContent(ctxt->myDoc, ret);
6299
2
    return(NULL);
6300
2
      }
6301
27.4k
      if (last == NULL) {
6302
15.4k
    op->c1 = ret;
6303
15.4k
    if (ret != NULL)
6304
15.4k
        ret->parent = op;
6305
15.4k
    ret = cur = op;
6306
15.4k
      } else {
6307
11.9k
          cur->c2 = op;
6308
11.9k
    if (op != NULL)
6309
11.9k
        op->parent = cur;
6310
11.9k
    op->c1 = last;
6311
11.9k
    if (last != NULL)
6312
11.9k
        last->parent = op;
6313
11.9k
    cur =op;
6314
11.9k
    last = NULL;
6315
11.9k
      }
6316
27.4k
  } else {
6317
14.7k
      xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_FINISHED, NULL);
6318
14.7k
      if ((last != NULL) && (last != ret))
6319
513
          xmlFreeDocElementContent(ctxt->myDoc, last);
6320
14.7k
      if (ret != NULL)
6321
14.7k
    xmlFreeDocElementContent(ctxt->myDoc, ret);
6322
14.7k
      return(NULL);
6323
14.7k
  }
6324
52.6k
  GROW;
6325
52.6k
  SKIP_BLANKS;
6326
52.6k
  GROW;
6327
52.6k
  if (RAW == '(') {
6328
25.3k
      int inputid = ctxt->input->id;
6329
      /* Recurse on second child */
6330
25.3k
      NEXT;
6331
25.3k
      SKIP_BLANKS;
6332
25.3k
      last = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
6333
25.3k
                                                          depth + 1);
6334
25.3k
            if (last == NULL) {
6335
16.8k
    if (ret != NULL)
6336
16.8k
        xmlFreeDocElementContent(ctxt->myDoc, ret);
6337
16.8k
    return(NULL);
6338
16.8k
            }
6339
8.41k
      SKIP_BLANKS;
6340
27.3k
  } else {
6341
27.3k
      elem = xmlParseName(ctxt);
6342
27.3k
      if (elem == NULL) {
6343
472
    xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
6344
472
    if (ret != NULL)
6345
472
        xmlFreeDocElementContent(ctxt->myDoc, ret);
6346
472
    return(NULL);
6347
472
      }
6348
26.8k
      last = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
6349
26.8k
      if (last == NULL) {
6350
1
    if (ret != NULL)
6351
1
        xmlFreeDocElementContent(ctxt->myDoc, ret);
6352
1
    return(NULL);
6353
1
      }
6354
26.8k
      if (RAW == '?') {
6355
6.43k
    last->ocur = XML_ELEMENT_CONTENT_OPT;
6356
6.43k
    NEXT;
6357
20.3k
      } else if (RAW == '*') {
6358
1.76k
    last->ocur = XML_ELEMENT_CONTENT_MULT;
6359
1.76k
    NEXT;
6360
18.6k
      } else if (RAW == '+') {
6361
241
    last->ocur = XML_ELEMENT_CONTENT_PLUS;
6362
241
    NEXT;
6363
18.3k
      } else {
6364
18.3k
    last->ocur = XML_ELEMENT_CONTENT_ONCE;
6365
18.3k
      }
6366
26.8k
  }
6367
35.2k
  SKIP_BLANKS;
6368
35.2k
  GROW;
6369
35.2k
    }
6370
40.5k
    if ((cur != NULL) && (last != NULL)) {
6371
10.0k
        cur->c2 = last;
6372
10.0k
  if (last != NULL)
6373
10.0k
      last->parent = cur;
6374
10.0k
    }
6375
40.5k
    if (ctxt->input->id != inputchk) {
6376
352
  xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6377
352
                       "Element content declaration doesn't start and stop in"
6378
352
                       " the same entity\n");
6379
352
    }
6380
40.5k
    NEXT;
6381
40.5k
    if (RAW == '?') {
6382
2.17k
  if (ret != NULL) {
6383
2.17k
      if ((ret->ocur == XML_ELEMENT_CONTENT_PLUS) ||
6384
2.17k
          (ret->ocur == XML_ELEMENT_CONTENT_MULT))
6385
1.51k
          ret->ocur = XML_ELEMENT_CONTENT_MULT;
6386
665
      else
6387
665
          ret->ocur = XML_ELEMENT_CONTENT_OPT;
6388
2.17k
  }
6389
2.17k
  NEXT;
6390
38.3k
    } else if (RAW == '*') {
6391
13.2k
  if (ret != NULL) {
6392
13.2k
      ret->ocur = XML_ELEMENT_CONTENT_MULT;
6393
13.2k
      cur = ret;
6394
      /*
6395
       * Some normalization:
6396
       * (a | b* | c?)* == (a | b | c)*
6397
       */
6398
16.3k
      while ((cur != NULL) && (cur->type == XML_ELEMENT_CONTENT_OR)) {
6399
3.08k
    if ((cur->c1 != NULL) &&
6400
3.08k
              ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
6401
3.08k
         (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT)))
6402
2.10k
        cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
6403
3.08k
    if ((cur->c2 != NULL) &&
6404
3.08k
              ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
6405
3.08k
         (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT)))
6406
868
        cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
6407
3.08k
    cur = cur->c2;
6408
3.08k
      }
6409
13.2k
  }
6410
13.2k
  NEXT;
6411
25.1k
    } else if (RAW == '+') {
6412
8.38k
  if (ret != NULL) {
6413
8.38k
      int found = 0;
6414
6415
8.38k
      if ((ret->ocur == XML_ELEMENT_CONTENT_OPT) ||
6416
8.38k
          (ret->ocur == XML_ELEMENT_CONTENT_MULT))
6417
1.84k
          ret->ocur = XML_ELEMENT_CONTENT_MULT;
6418
6.53k
      else
6419
6.53k
          ret->ocur = XML_ELEMENT_CONTENT_PLUS;
6420
      /*
6421
       * Some normalization:
6422
       * (a | b*)+ == (a | b)*
6423
       * (a | b?)+ == (a | b)*
6424
       */
6425
23.2k
      while ((cur != NULL) && (cur->type == XML_ELEMENT_CONTENT_OR)) {
6426
14.8k
    if ((cur->c1 != NULL) &&
6427
14.8k
              ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
6428
14.8k
         (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT))) {
6429
6.63k
        cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
6430
6.63k
        found = 1;
6431
6.63k
    }
6432
14.8k
    if ((cur->c2 != NULL) &&
6433
14.8k
              ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
6434
14.8k
         (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT))) {
6435
5.14k
        cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
6436
5.14k
        found = 1;
6437
5.14k
    }
6438
14.8k
    cur = cur->c2;
6439
14.8k
      }
6440
8.38k
      if (found)
6441
6.30k
    ret->ocur = XML_ELEMENT_CONTENT_MULT;
6442
8.38k
  }
6443
8.38k
  NEXT;
6444
8.38k
    }
6445
40.5k
    return(ret);
6446
72.9k
}
6447
6448
/**
6449
 * xmlParseElementChildrenContentDecl:
6450
 * @ctxt:  an XML parser context
6451
 * @inputchk:  the input used for the current entity, needed for boundary checks
6452
 *
6453
 * DEPRECATED: Internal function, don't use.
6454
 *
6455
 * parse the declaration for a Mixed Element content
6456
 * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
6457
 *
6458
 * [47] children ::= (choice | seq) ('?' | '*' | '+')?
6459
 *
6460
 * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
6461
 *
6462
 * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
6463
 *
6464
 * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
6465
 *
6466
 * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
6467
 * TODO Parameter-entity replacement text must be properly nested
6468
 *  with parenthesized groups. That is to say, if either of the
6469
 *  opening or closing parentheses in a choice, seq, or Mixed
6470
 *  construct is contained in the replacement text for a parameter
6471
 *  entity, both must be contained in the same replacement text. For
6472
 *  interoperability, if a parameter-entity reference appears in a
6473
 *  choice, seq, or Mixed construct, its replacement text should not
6474
 *  be empty, and neither the first nor last non-blank character of
6475
 *  the replacement text should be a connector (| or ,).
6476
 *
6477
 * Returns the tree of xmlElementContentPtr describing the element
6478
 *          hierarchy.
6479
 */
6480
xmlElementContentPtr
6481
0
xmlParseElementChildrenContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
6482
    /* stub left for API/ABI compat */
6483
0
    return(xmlParseElementChildrenContentDeclPriv(ctxt, inputchk, 1));
6484
0
}
6485
6486
/**
6487
 * xmlParseElementContentDecl:
6488
 * @ctxt:  an XML parser context
6489
 * @name:  the name of the element being defined.
6490
 * @result:  the Element Content pointer will be stored here if any
6491
 *
6492
 * DEPRECATED: Internal function, don't use.
6493
 *
6494
 * parse the declaration for an Element content either Mixed or Children,
6495
 * the cases EMPTY and ANY are handled directly in xmlParseElementDecl
6496
 *
6497
 * [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
6498
 *
6499
 * returns: the type of element content XML_ELEMENT_TYPE_xxx
6500
 */
6501
6502
int
6503
xmlParseElementContentDecl(xmlParserCtxtPtr ctxt, const xmlChar *name,
6504
46.9k
                           xmlElementContentPtr *result) {
6505
6506
46.9k
    xmlElementContentPtr tree = NULL;
6507
46.9k
    int inputid = ctxt->input->id;
6508
46.9k
    int res;
6509
6510
46.9k
    *result = NULL;
6511
6512
46.9k
    if (RAW != '(') {
6513
0
  xmlFatalErrMsgStr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED,
6514
0
    "xmlParseElementContentDecl : %s '(' expected\n", name);
6515
0
  return(-1);
6516
0
    }
6517
46.9k
    NEXT;
6518
46.9k
    GROW;
6519
46.9k
    if (ctxt->instate == XML_PARSER_EOF)
6520
70
        return(-1);
6521
46.8k
    SKIP_BLANKS;
6522
46.8k
    if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
6523
6.82k
        tree = xmlParseElementMixedContentDecl(ctxt, inputid);
6524
6.82k
  res = XML_ELEMENT_TYPE_MIXED;
6525
40.0k
    } else {
6526
40.0k
        tree = xmlParseElementChildrenContentDeclPriv(ctxt, inputid, 1);
6527
40.0k
  res = XML_ELEMENT_TYPE_ELEMENT;
6528
40.0k
    }
6529
46.8k
    SKIP_BLANKS;
6530
46.8k
    *result = tree;
6531
46.8k
    return(res);
6532
46.9k
}
6533
6534
/**
6535
 * xmlParseElementDecl:
6536
 * @ctxt:  an XML parser context
6537
 *
6538
 * DEPRECATED: Internal function, don't use.
6539
 *
6540
 * Parse an element declaration. Always consumes '<!'.
6541
 *
6542
 * [45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
6543
 *
6544
 * [ VC: Unique Element Type Declaration ]
6545
 * No element type may be declared more than once
6546
 *
6547
 * Returns the type of the element, or -1 in case of error
6548
 */
6549
int
6550
53.9k
xmlParseElementDecl(xmlParserCtxtPtr ctxt) {
6551
53.9k
    const xmlChar *name;
6552
53.9k
    int ret = -1;
6553
53.9k
    xmlElementContentPtr content  = NULL;
6554
6555
53.9k
    if ((CUR != '<') || (NXT(1) != '!'))
6556
0
        return(ret);
6557
53.9k
    SKIP(2);
6558
6559
    /* GROW; done in the caller */
6560
53.9k
    if (CMP7(CUR_PTR, 'E', 'L', 'E', 'M', 'E', 'N', 'T')) {
6561
52.6k
  int inputid = ctxt->input->id;
6562
6563
52.6k
  SKIP(7);
6564
52.6k
  if (SKIP_BLANKS == 0) {
6565
760
      xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6566
760
               "Space required after 'ELEMENT'\n");
6567
760
      return(-1);
6568
760
  }
6569
51.8k
        name = xmlParseName(ctxt);
6570
51.8k
  if (name == NULL) {
6571
244
      xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
6572
244
         "xmlParseElementDecl: no name for Element\n");
6573
244
      return(-1);
6574
244
  }
6575
51.6k
  if (SKIP_BLANKS == 0) {
6576
13.0k
      xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6577
13.0k
         "Space required after the element name\n");
6578
13.0k
  }
6579
51.6k
  if (CMP5(CUR_PTR, 'E', 'M', 'P', 'T', 'Y')) {
6580
1.82k
      SKIP(5);
6581
      /*
6582
       * Element must always be empty.
6583
       */
6584
1.82k
      ret = XML_ELEMENT_TYPE_EMPTY;
6585
49.8k
  } else if ((RAW == 'A') && (NXT(1) == 'N') &&
6586
49.8k
             (NXT(2) == 'Y')) {
6587
801
      SKIP(3);
6588
      /*
6589
       * Element is a generic container.
6590
       */
6591
801
      ret = XML_ELEMENT_TYPE_ANY;
6592
49.0k
  } else if (RAW == '(') {
6593
46.9k
      ret = xmlParseElementContentDecl(ctxt, name, &content);
6594
46.9k
  } else {
6595
      /*
6596
       * [ WFC: PEs in Internal Subset ] error handling.
6597
       */
6598
2.11k
      if ((RAW == '%') && (ctxt->external == 0) &&
6599
2.11k
          (ctxt->inputNr == 1)) {
6600
1.19k
    xmlFatalErrMsg(ctxt, XML_ERR_PEREF_IN_INT_SUBSET,
6601
1.19k
    "PEReference: forbidden within markup decl in internal subset\n");
6602
1.19k
      } else {
6603
925
    xmlFatalErrMsg(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED,
6604
925
          "xmlParseElementDecl: 'EMPTY', 'ANY' or '(' expected\n");
6605
925
            }
6606
2.11k
      return(-1);
6607
2.11k
  }
6608
6609
49.5k
  SKIP_BLANKS;
6610
6611
49.5k
  if (RAW != '>') {
6612
9.30k
      xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
6613
9.30k
      if (content != NULL) {
6614
971
    xmlFreeDocElementContent(ctxt->myDoc, content);
6615
971
      }
6616
40.2k
  } else {
6617
40.2k
      if (inputid != ctxt->input->id) {
6618
1.32k
    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6619
1.32k
                               "Element declaration doesn't start and stop in"
6620
1.32k
                               " the same entity\n");
6621
1.32k
      }
6622
6623
40.2k
      NEXT;
6624
40.2k
      if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
6625
40.2k
    (ctxt->sax->elementDecl != NULL)) {
6626
22.2k
    if (content != NULL)
6627
21.1k
        content->parent = NULL;
6628
22.2k
          ctxt->sax->elementDecl(ctxt->userData, name, ret,
6629
22.2k
                           content);
6630
22.2k
    if ((content != NULL) && (content->parent == NULL)) {
6631
        /*
6632
         * this is a trick: if xmlAddElementDecl is called,
6633
         * instead of copying the full tree it is plugged directly
6634
         * if called from the parser. Avoid duplicating the
6635
         * interfaces or change the API/ABI
6636
         */
6637
13.5k
        xmlFreeDocElementContent(ctxt->myDoc, content);
6638
13.5k
    }
6639
22.2k
      } else if (content != NULL) {
6640
3.21k
    xmlFreeDocElementContent(ctxt->myDoc, content);
6641
3.21k
      }
6642
40.2k
  }
6643
49.5k
    }
6644
50.7k
    return(ret);
6645
53.9k
}
6646
6647
/**
6648
 * xmlParseConditionalSections
6649
 * @ctxt:  an XML parser context
6650
 *
6651
 * Parse a conditional section. Always consumes '<!['.
6652
 *
6653
 * [61] conditionalSect ::= includeSect | ignoreSect
6654
 * [62] includeSect ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>'
6655
 * [63] ignoreSect ::= '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>'
6656
 * [64] ignoreSectContents ::= Ignore ('<![' ignoreSectContents ']]>' Ignore)*
6657
 * [65] Ignore ::= Char* - (Char* ('<![' | ']]>') Char*)
6658
 */
6659
6660
static void
6661
564
xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
6662
564
    int *inputIds = NULL;
6663
564
    size_t inputIdsSize = 0;
6664
564
    size_t depth = 0;
6665
6666
564
    while (ctxt->instate != XML_PARSER_EOF) {
6667
564
        if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
6668
564
            int id = ctxt->input->id;
6669
6670
564
            SKIP(3);
6671
564
            SKIP_BLANKS;
6672
6673
564
            if (CMP7(CUR_PTR, 'I', 'N', 'C', 'L', 'U', 'D', 'E')) {
6674
0
                SKIP(7);
6675
0
                SKIP_BLANKS;
6676
0
                if (RAW != '[') {
6677
0
                    xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
6678
0
                    xmlHaltParser(ctxt);
6679
0
                    goto error;
6680
0
                }
6681
0
                if (ctxt->input->id != id) {
6682
0
                    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6683
0
                                   "All markup of the conditional section is"
6684
0
                                   " not in the same entity\n");
6685
0
                }
6686
0
                NEXT;
6687
6688
0
                if (inputIdsSize <= depth) {
6689
0
                    int *tmp;
6690
6691
0
                    inputIdsSize = (inputIdsSize == 0 ? 4 : inputIdsSize * 2);
6692
0
                    tmp = (int *) xmlRealloc(inputIds,
6693
0
                            inputIdsSize * sizeof(int));
6694
0
                    if (tmp == NULL) {
6695
0
                        xmlErrMemory(ctxt, NULL);
6696
0
                        goto error;
6697
0
                    }
6698
0
                    inputIds = tmp;
6699
0
                }
6700
0
                inputIds[depth] = id;
6701
0
                depth++;
6702
564
            } else if (CMP6(CUR_PTR, 'I', 'G', 'N', 'O', 'R', 'E')) {
6703
301
                size_t ignoreDepth = 0;
6704
6705
301
                SKIP(6);
6706
301
                SKIP_BLANKS;
6707
301
                if (RAW != '[') {
6708
1
                    xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
6709
1
                    xmlHaltParser(ctxt);
6710
1
                    goto error;
6711
1
                }
6712
300
                if (ctxt->input->id != id) {
6713
0
                    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6714
0
                                   "All markup of the conditional section is"
6715
0
                                   " not in the same entity\n");
6716
0
                }
6717
300
                NEXT;
6718
6719
1.17M
                while (RAW != 0) {
6720
1.17M
                    if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
6721
755
                        SKIP(3);
6722
755
                        ignoreDepth++;
6723
                        /* Check for integer overflow */
6724
755
                        if (ignoreDepth == 0) {
6725
0
                            xmlErrMemory(ctxt, NULL);
6726
0
                            goto error;
6727
0
                        }
6728
1.17M
                    } else if ((RAW == ']') && (NXT(1) == ']') &&
6729
1.17M
                               (NXT(2) == '>')) {
6730
417
                        if (ignoreDepth == 0)
6731
100
                            break;
6732
317
                        SKIP(3);
6733
317
                        ignoreDepth--;
6734
1.16M
                    } else {
6735
1.16M
                        NEXT;
6736
1.16M
                    }
6737
1.17M
                }
6738
6739
300
    if (RAW == 0) {
6740
200
        xmlFatalErr(ctxt, XML_ERR_CONDSEC_NOT_FINISHED, NULL);
6741
200
                    goto error;
6742
200
    }
6743
100
                if (ctxt->input->id != id) {
6744
0
                    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6745
0
                                   "All markup of the conditional section is"
6746
0
                                   " not in the same entity\n");
6747
0
                }
6748
100
                SKIP(3);
6749
263
            } else {
6750
263
                xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID_KEYWORD, NULL);
6751
263
                xmlHaltParser(ctxt);
6752
263
                goto error;
6753
263
            }
6754
564
        } else if ((depth > 0) &&
6755
0
                   (RAW == ']') && (NXT(1) == ']') && (NXT(2) == '>')) {
6756
0
            depth--;
6757
0
            if (ctxt->input->id != inputIds[depth]) {
6758
0
                xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6759
0
                               "All markup of the conditional section is not"
6760
0
                               " in the same entity\n");
6761
0
            }
6762
0
            SKIP(3);
6763
0
        } else if ((RAW == '<') && ((NXT(1) == '!') || (NXT(1) == '?'))) {
6764
0
            xmlParseMarkupDecl(ctxt);
6765
0
        } else {
6766
0
            xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
6767
0
            xmlHaltParser(ctxt);
6768
0
            goto error;
6769
0
        }
6770
6771
100
        if (depth == 0)
6772
100
            break;
6773
6774
0
        SKIP_BLANKS;
6775
0
        SHRINK;
6776
0
        GROW;
6777
0
    }
6778
6779
564
error:
6780
564
    xmlFree(inputIds);
6781
564
}
6782
6783
/**
6784
 * xmlParseMarkupDecl:
6785
 * @ctxt:  an XML parser context
6786
 *
6787
 * DEPRECATED: Internal function, don't use.
6788
 *
6789
 * Parse markup declarations. Always consumes '<!' or '<?'.
6790
 *
6791
 * [29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl |
6792
 *                     NotationDecl | PI | Comment
6793
 *
6794
 * [ VC: Proper Declaration/PE Nesting ]
6795
 * Parameter-entity replacement text must be properly nested with
6796
 * markup declarations. That is to say, if either the first character
6797
 * or the last character of a markup declaration (markupdecl above) is
6798
 * contained in the replacement text for a parameter-entity reference,
6799
 * both must be contained in the same replacement text.
6800
 *
6801
 * [ WFC: PEs in Internal Subset ]
6802
 * In the internal DTD subset, parameter-entity references can occur
6803
 * only where markup declarations can occur, not within markup declarations.
6804
 * (This does not apply to references that occur in external parameter
6805
 * entities or to the external subset.)
6806
 */
6807
void
6808
378k
xmlParseMarkupDecl(xmlParserCtxtPtr ctxt) {
6809
378k
    GROW;
6810
378k
    if (CUR == '<') {
6811
378k
        if (NXT(1) == '!') {
6812
280k
      switch (NXT(2)) {
6813
117k
          case 'E':
6814
117k
        if (NXT(3) == 'L')
6815
53.9k
      xmlParseElementDecl(ctxt);
6816
63.1k
        else if (NXT(3) == 'N')
6817
62.5k
      xmlParseEntityDecl(ctxt);
6818
598
                    else
6819
598
                        SKIP(2);
6820
117k
        break;
6821
115k
          case 'A':
6822
115k
        xmlParseAttributeListDecl(ctxt);
6823
115k
        break;
6824
24.9k
          case 'N':
6825
24.9k
        xmlParseNotationDecl(ctxt);
6826
24.9k
        break;
6827
19.7k
          case '-':
6828
19.7k
        xmlParseComment(ctxt);
6829
19.7k
        break;
6830
3.70k
    default:
6831
        /* there is an error but it will be detected later */
6832
3.70k
                    SKIP(2);
6833
3.70k
        break;
6834
280k
      }
6835
280k
  } else if (NXT(1) == '?') {
6836
97.5k
      xmlParsePI(ctxt);
6837
97.5k
  }
6838
378k
    }
6839
6840
    /*
6841
     * detect requirement to exit there and act accordingly
6842
     * and avoid having instate overridden later on
6843
     */
6844
378k
    if (ctxt->instate == XML_PARSER_EOF)
6845
6.97k
        return;
6846
6847
371k
    ctxt->instate = XML_PARSER_DTD;
6848
371k
}
6849
6850
/**
6851
 * xmlParseTextDecl:
6852
 * @ctxt:  an XML parser context
6853
 *
6854
 * DEPRECATED: Internal function, don't use.
6855
 *
6856
 * parse an XML declaration header for external entities
6857
 *
6858
 * [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
6859
 */
6860
6861
void
6862
10.6k
xmlParseTextDecl(xmlParserCtxtPtr ctxt) {
6863
10.6k
    xmlChar *version;
6864
10.6k
    const xmlChar *encoding;
6865
10.6k
    int oldstate;
6866
6867
    /*
6868
     * We know that '<?xml' is here.
6869
     */
6870
10.6k
    if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
6871
10.5k
  SKIP(5);
6872
10.5k
    } else {
6873
55
  xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_STARTED, NULL);
6874
55
  return;
6875
55
    }
6876
6877
    /* Avoid expansion of parameter entities when skipping blanks. */
6878
10.5k
    oldstate = ctxt->instate;
6879
10.5k
    ctxt->instate = XML_PARSER_START;
6880
6881
10.5k
    if (SKIP_BLANKS == 0) {
6882
0
  xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6883
0
           "Space needed after '<?xml'\n");
6884
0
    }
6885
6886
    /*
6887
     * We may have the VersionInfo here.
6888
     */
6889
10.5k
    version = xmlParseVersionInfo(ctxt);
6890
10.5k
    if (version == NULL)
6891
5.49k
  version = xmlCharStrdup(XML_DEFAULT_VERSION);
6892
5.05k
    else {
6893
5.05k
  if (SKIP_BLANKS == 0) {
6894
387
      xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6895
387
               "Space needed here\n");
6896
387
  }
6897
5.05k
    }
6898
10.5k
    ctxt->input->version = version;
6899
6900
    /*
6901
     * We must have the encoding declaration
6902
     */
6903
10.5k
    encoding = xmlParseEncodingDecl(ctxt);
6904
10.5k
    if (ctxt->instate == XML_PARSER_EOF)
6905
40
        return;
6906
10.5k
    if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
6907
  /*
6908
   * The XML REC instructs us to stop parsing right here
6909
   */
6910
505
        ctxt->instate = oldstate;
6911
505
        return;
6912
505
    }
6913
10.0k
    if ((encoding == NULL) && (ctxt->errNo == XML_ERR_OK)) {
6914
217
  xmlFatalErrMsg(ctxt, XML_ERR_MISSING_ENCODING,
6915
217
           "Missing encoding in text declaration\n");
6916
217
    }
6917
6918
10.0k
    SKIP_BLANKS;
6919
10.0k
    if ((RAW == '?') && (NXT(1) == '>')) {
6920
761
        SKIP(2);
6921
9.24k
    } else if (RAW == '>') {
6922
        /* Deprecated old WD ... */
6923
98
  xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
6924
98
  NEXT;
6925
9.15k
    } else {
6926
9.15k
        int c;
6927
6928
9.15k
  xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
6929
6.80M
        while ((c = CUR) != 0) {
6930
6.79M
            NEXT;
6931
6.79M
            if (c == '>')
6932
2.28k
                break;
6933
6.79M
        }
6934
9.15k
    }
6935
6936
10.0k
    ctxt->instate = oldstate;
6937
10.0k
}
6938
6939
/**
6940
 * xmlParseExternalSubset:
6941
 * @ctxt:  an XML parser context
6942
 * @ExternalID: the external identifier
6943
 * @SystemID: the system identifier (or URL)
6944
 *
6945
 * parse Markup declarations from an external subset
6946
 *
6947
 * [30] extSubset ::= textDecl? extSubsetDecl
6948
 *
6949
 * [31] extSubsetDecl ::= (markupdecl | conditionalSect | PEReference | S) *
6950
 */
6951
void
6952
xmlParseExternalSubset(xmlParserCtxtPtr ctxt, const xmlChar *ExternalID,
6953
2.25k
                       const xmlChar *SystemID) {
6954
2.25k
    xmlDetectSAX2(ctxt);
6955
2.25k
    GROW;
6956
6957
2.25k
    if ((ctxt->encoding == NULL) &&
6958
2.25k
        (ctxt->input->end - ctxt->input->cur >= 4)) {
6959
2.17k
        xmlChar start[4];
6960
2.17k
  xmlCharEncoding enc;
6961
6962
2.17k
  start[0] = RAW;
6963
2.17k
  start[1] = NXT(1);
6964
2.17k
  start[2] = NXT(2);
6965
2.17k
  start[3] = NXT(3);
6966
2.17k
  enc = xmlDetectCharEncoding(start, 4);
6967
2.17k
  if (enc != XML_CHAR_ENCODING_NONE)
6968
743
      xmlSwitchEncoding(ctxt, enc);
6969
2.17k
    }
6970
6971
2.25k
    if (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) {
6972
185
  xmlParseTextDecl(ctxt);
6973
185
  if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
6974
      /*
6975
       * The XML REC instructs us to stop parsing right here
6976
       */
6977
37
      xmlHaltParser(ctxt);
6978
37
      return;
6979
37
  }
6980
185
    }
6981
2.21k
    if (ctxt->myDoc == NULL) {
6982
0
        ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
6983
0
  if (ctxt->myDoc == NULL) {
6984
0
      xmlErrMemory(ctxt, "New Doc failed");
6985
0
      return;
6986
0
  }
6987
0
  ctxt->myDoc->properties = XML_DOC_INTERNAL;
6988
0
    }
6989
2.21k
    if ((ctxt->myDoc != NULL) && (ctxt->myDoc->intSubset == NULL))
6990
0
        xmlCreateIntSubset(ctxt->myDoc, NULL, ExternalID, SystemID);
6991
6992
2.21k
    ctxt->instate = XML_PARSER_DTD;
6993
2.21k
    ctxt->external = 1;
6994
2.21k
    SKIP_BLANKS;
6995
7.18k
    while ((ctxt->instate != XML_PARSER_EOF) && (RAW != 0)) {
6996
6.34k
  GROW;
6997
6.34k
        if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
6998
329
            xmlParseConditionalSections(ctxt);
6999
6.02k
        } else if ((RAW == '<') && ((NXT(1) == '!') || (NXT(1) == '?'))) {
7000
4.63k
            xmlParseMarkupDecl(ctxt);
7001
4.63k
        } else {
7002
1.38k
            xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
7003
1.38k
            xmlHaltParser(ctxt);
7004
1.38k
            return;
7005
1.38k
        }
7006
4.96k
        SKIP_BLANKS;
7007
4.96k
        SHRINK;
7008
4.96k
    }
7009
7010
837
    if (RAW != 0) {
7011
1
  xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
7012
1
    }
7013
7014
837
}
7015
7016
/**
7017
 * xmlParseReference:
7018
 * @ctxt:  an XML parser context
7019
 *
7020
 * DEPRECATED: Internal function, don't use.
7021
 *
7022
 * parse and handle entity references in content, depending on the SAX
7023
 * interface, this may end-up in a call to character() if this is a
7024
 * CharRef, a predefined entity, if there is no reference() callback.
7025
 * or if the parser was asked to switch to that mode.
7026
 *
7027
 * Always consumes '&'.
7028
 *
7029
 * [67] Reference ::= EntityRef | CharRef
7030
 */
7031
void
7032
171k
xmlParseReference(xmlParserCtxtPtr ctxt) {
7033
171k
    xmlEntityPtr ent;
7034
171k
    xmlChar *val;
7035
171k
    int was_checked;
7036
171k
    xmlNodePtr list = NULL;
7037
171k
    xmlParserErrors ret = XML_ERR_OK;
7038
7039
7040
171k
    if (RAW != '&')
7041
0
        return;
7042
7043
    /*
7044
     * Simple case of a CharRef
7045
     */
7046
171k
    if (NXT(1) == '#') {
7047
60.1k
  int i = 0;
7048
60.1k
  xmlChar out[16];
7049
60.1k
  int hex = NXT(2);
7050
60.1k
  int value = xmlParseCharRef(ctxt);
7051
7052
60.1k
  if (value == 0)
7053
16.9k
      return;
7054
43.2k
  if (ctxt->charset != XML_CHAR_ENCODING_UTF8) {
7055
      /*
7056
       * So we are using non-UTF-8 buffers
7057
       * Check that the char fit on 8bits, if not
7058
       * generate a CharRef.
7059
       */
7060
10.3k
      if (value <= 0xFF) {
7061
6.40k
    out[0] = value;
7062
6.40k
    out[1] = 0;
7063
6.40k
    if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
7064
6.40k
        (!ctxt->disableSAX))
7065
5
        ctxt->sax->characters(ctxt->userData, out, 1);
7066
6.40k
      } else {
7067
3.96k
    if ((hex == 'x') || (hex == 'X'))
7068
3.14k
        snprintf((char *)out, sizeof(out), "#x%X", value);
7069
828
    else
7070
828
        snprintf((char *)out, sizeof(out), "#%d", value);
7071
3.96k
    if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
7072
3.96k
        (!ctxt->disableSAX))
7073
7
        ctxt->sax->reference(ctxt->userData, out);
7074
3.96k
      }
7075
32.8k
  } else {
7076
      /*
7077
       * Just encode the value in UTF-8
7078
       */
7079
32.8k
      COPY_BUF(0 ,out, i, value);
7080
32.8k
      out[i] = 0;
7081
32.8k
      if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
7082
32.8k
    (!ctxt->disableSAX))
7083
19.0k
    ctxt->sax->characters(ctxt->userData, out, i);
7084
32.8k
  }
7085
43.2k
  return;
7086
60.1k
    }
7087
7088
    /*
7089
     * We are seeing an entity reference
7090
     */
7091
111k
    ent = xmlParseEntityRef(ctxt);
7092
111k
    if (ent == NULL) return;
7093
56.3k
    if (!ctxt->wellFormed)
7094
17.2k
  return;
7095
39.1k
    was_checked = ent->flags & XML_ENT_PARSED;
7096
7097
    /* special case of predefined entities */
7098
39.1k
    if ((ent->name == NULL) ||
7099
39.1k
        (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
7100
17.5k
  val = ent->content;
7101
17.5k
  if (val == NULL) return;
7102
  /*
7103
   * inline the entity.
7104
   */
7105
17.5k
  if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
7106
17.5k
      (!ctxt->disableSAX))
7107
17.5k
      ctxt->sax->characters(ctxt->userData, val, xmlStrlen(val));
7108
17.5k
  return;
7109
17.5k
    }
7110
7111
    /*
7112
     * The first reference to the entity trigger a parsing phase
7113
     * where the ent->children is filled with the result from
7114
     * the parsing.
7115
     * Note: external parsed entities will not be loaded, it is not
7116
     * required for a non-validating parser, unless the parsing option
7117
     * of validating, or substituting entities were given. Doing so is
7118
     * far more secure as the parser will only process data coming from
7119
     * the document entity by default.
7120
     */
7121
21.5k
    if (((ent->flags & XML_ENT_PARSED) == 0) &&
7122
21.5k
        ((ent->etype != XML_EXTERNAL_GENERAL_PARSED_ENTITY) ||
7123
6.45k
         (ctxt->options & (XML_PARSE_NOENT | XML_PARSE_DTDVALID)))) {
7124
6.45k
  unsigned long oldsizeentcopy = ctxt->sizeentcopy;
7125
7126
  /*
7127
   * This is a bit hackish but this seems the best
7128
   * way to make sure both SAX and DOM entity support
7129
   * behaves okay.
7130
   */
7131
6.45k
  void *user_data;
7132
6.45k
  if (ctxt->userData == ctxt)
7133
6.45k
      user_data = NULL;
7134
0
  else
7135
0
      user_data = ctxt->userData;
7136
7137
        /* Avoid overflow as much as possible */
7138
6.45k
        ctxt->sizeentcopy = 0;
7139
7140
6.45k
        if (ent->flags & XML_ENT_EXPANDING) {
7141
90
            xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
7142
90
            xmlHaltParser(ctxt);
7143
90
            return;
7144
90
        }
7145
7146
6.36k
        ent->flags |= XML_ENT_EXPANDING;
7147
7148
  /*
7149
   * Check that this entity is well formed
7150
   * 4.3.2: An internal general parsed entity is well-formed
7151
   * if its replacement text matches the production labeled
7152
   * content.
7153
   */
7154
6.36k
  if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
7155
3.11k
      ctxt->depth++;
7156
3.11k
      ret = xmlParseBalancedChunkMemoryInternal(ctxt, ent->content,
7157
3.11k
                                                user_data, &list);
7158
3.11k
      ctxt->depth--;
7159
7160
3.24k
  } else if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
7161
3.24k
      ctxt->depth++;
7162
3.24k
      ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt, ctxt->sax,
7163
3.24k
                                     user_data, ctxt->depth, ent->URI,
7164
3.24k
             ent->ExternalID, &list);
7165
3.24k
      ctxt->depth--;
7166
3.24k
  } else {
7167
0
      ret = XML_ERR_ENTITY_PE_INTERNAL;
7168
0
      xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
7169
0
       "invalid entity type found\n", NULL);
7170
0
  }
7171
7172
6.36k
        ent->flags &= ~XML_ENT_EXPANDING;
7173
6.36k
        ent->flags |= XML_ENT_PARSED | XML_ENT_CHECKED;
7174
6.36k
        ent->expandedSize = ctxt->sizeentcopy;
7175
6.36k
  if (ret == XML_ERR_ENTITY_LOOP) {
7176
291
            xmlHaltParser(ctxt);
7177
291
      xmlFreeNodeList(list);
7178
291
      return;
7179
291
  }
7180
6.06k
  if (xmlParserEntityCheck(ctxt, oldsizeentcopy)) {
7181
1
      xmlFreeNodeList(list);
7182
1
      return;
7183
1
  }
7184
7185
6.06k
  if ((ret == XML_ERR_OK) && (list != NULL)) {
7186
2.35k
            ent->children = list;
7187
            /*
7188
             * Prune it directly in the generated document
7189
             * except for single text nodes.
7190
             */
7191
2.35k
            if ((ctxt->replaceEntities == 0) ||
7192
2.35k
                (ctxt->parseMode == XML_PARSE_READER) ||
7193
2.35k
                ((list->type == XML_TEXT_NODE) &&
7194
2.35k
                 (list->next == NULL))) {
7195
973
                ent->owner = 1;
7196
1.94k
                while (list != NULL) {
7197
973
                    list->parent = (xmlNodePtr) ent;
7198
973
                    if (list->doc != ent->doc)
7199
0
                        xmlSetTreeDoc(list, ent->doc);
7200
973
                    if (list->next == NULL)
7201
973
                        ent->last = list;
7202
973
                    list = list->next;
7203
973
                }
7204
973
                list = NULL;
7205
1.38k
            } else {
7206
1.38k
                ent->owner = 0;
7207
12.8k
                while (list != NULL) {
7208
11.4k
                    list->parent = (xmlNodePtr) ctxt->node;
7209
11.4k
                    list->doc = ctxt->myDoc;
7210
11.4k
                    if (list->next == NULL)
7211
1.38k
                        ent->last = list;
7212
11.4k
                    list = list->next;
7213
11.4k
                }
7214
1.38k
                list = ent->children;
7215
#ifdef LIBXML_LEGACY_ENABLED
7216
                if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
7217
                    xmlAddEntityReference(ent, list, NULL);
7218
#endif /* LIBXML_LEGACY_ENABLED */
7219
1.38k
            }
7220
3.70k
  } else if ((ret != XML_ERR_OK) &&
7221
3.70k
       (ret != XML_WAR_UNDECLARED_ENTITY)) {
7222
2.92k
      xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
7223
2.92k
         "Entity '%s' failed to parse\n", ent->name);
7224
2.92k
            if (ent->content != NULL)
7225
881
                ent->content[0] = 0;
7226
2.92k
  } else if (list != NULL) {
7227
0
      xmlFreeNodeList(list);
7228
0
      list = NULL;
7229
0
  }
7230
7231
        /* Prevent entity from being parsed and expanded twice (Bug 760367). */
7232
6.06k
        was_checked = 0;
7233
6.06k
    }
7234
7235
    /*
7236
     * Now that the entity content has been gathered
7237
     * provide it to the application, this can take different forms based
7238
     * on the parsing modes.
7239
     */
7240
21.1k
    if (ent->children == NULL) {
7241
  /*
7242
   * Probably running in SAX mode and the callbacks don't
7243
   * build the entity content. So unless we already went
7244
   * though parsing for first checking go though the entity
7245
   * content to generate callbacks associated to the entity
7246
   */
7247
10.3k
  if (was_checked != 0) {
7248
6.64k
      void *user_data;
7249
      /*
7250
       * This is a bit hackish but this seems the best
7251
       * way to make sure both SAX and DOM entity support
7252
       * behaves okay.
7253
       */
7254
6.64k
      if (ctxt->userData == ctxt)
7255
6.64k
    user_data = NULL;
7256
0
      else
7257
0
    user_data = ctxt->userData;
7258
7259
6.64k
      if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
7260
89
    ctxt->depth++;
7261
89
    ret = xmlParseBalancedChunkMemoryInternal(ctxt,
7262
89
           ent->content, user_data, NULL);
7263
89
    ctxt->depth--;
7264
6.55k
      } else if (ent->etype ==
7265
6.55k
           XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
7266
6.55k
          unsigned long oldsizeentities = ctxt->sizeentities;
7267
7268
6.55k
    ctxt->depth++;
7269
6.55k
    ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt,
7270
6.55k
         ctxt->sax, user_data, ctxt->depth,
7271
6.55k
         ent->URI, ent->ExternalID, NULL);
7272
6.55k
    ctxt->depth--;
7273
7274
                /* Undo the change to sizeentities */
7275
6.55k
                ctxt->sizeentities = oldsizeentities;
7276
6.55k
      } else {
7277
0
    ret = XML_ERR_ENTITY_PE_INTERNAL;
7278
0
    xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
7279
0
           "invalid entity type found\n", NULL);
7280
0
      }
7281
6.64k
      if (ret == XML_ERR_ENTITY_LOOP) {
7282
0
    xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
7283
0
    return;
7284
0
      }
7285
6.64k
            if (xmlParserEntityCheck(ctxt, 0))
7286
0
                return;
7287
6.64k
  }
7288
10.3k
  if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
7289
10.3k
      (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
7290
      /*
7291
       * Entity reference callback comes second, it's somewhat
7292
       * superfluous but a compatibility to historical behaviour
7293
       */
7294
0
      ctxt->sax->reference(ctxt->userData, ent->name);
7295
0
  }
7296
10.3k
  return;
7297
10.3k
    }
7298
7299
    /*
7300
     * We also check for amplification if entities aren't substituted.
7301
     * They might be expanded later.
7302
     */
7303
10.8k
    if ((was_checked != 0) &&
7304
10.8k
        (xmlParserEntityCheck(ctxt, ent->expandedSize)))
7305
13
        return;
7306
7307
    /*
7308
     * If we didn't get any children for the entity being built
7309
     */
7310
10.8k
    if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
7311
10.8k
  (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
7312
  /*
7313
   * Create a node.
7314
   */
7315
0
  ctxt->sax->reference(ctxt->userData, ent->name);
7316
0
  return;
7317
0
    }
7318
7319
10.8k
    if (ctxt->replaceEntities)  {
7320
  /*
7321
   * There is a problem on the handling of _private for entities
7322
   * (bug 155816): Should we copy the content of the field from
7323
   * the entity (possibly overwriting some value set by the user
7324
   * when a copy is created), should we leave it alone, or should
7325
   * we try to take care of different situations?  The problem
7326
   * is exacerbated by the usage of this field by the xmlReader.
7327
   * To fix this bug, we look at _private on the created node
7328
   * and, if it's NULL, we copy in whatever was in the entity.
7329
   * If it's not NULL we leave it alone.  This is somewhat of a
7330
   * hack - maybe we should have further tests to determine
7331
   * what to do.
7332
   */
7333
10.8k
  if (ctxt->node != NULL) {
7334
      /*
7335
       * Seems we are generating the DOM content, do
7336
       * a simple tree copy for all references except the first
7337
       * In the first occurrence list contains the replacement.
7338
       */
7339
10.8k
      if (((list == NULL) && (ent->owner == 0)) ||
7340
10.8k
    (ctxt->parseMode == XML_PARSE_READER)) {
7341
0
    xmlNodePtr nw = NULL, cur, firstChild = NULL;
7342
7343
    /*
7344
     * when operating on a reader, the entities definitions
7345
     * are always owning the entities subtree.
7346
    if (ctxt->parseMode == XML_PARSE_READER)
7347
        ent->owner = 1;
7348
     */
7349
7350
0
    cur = ent->children;
7351
0
    while (cur != NULL) {
7352
0
        nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
7353
0
        if (nw != NULL) {
7354
0
      if (nw->_private == NULL)
7355
0
          nw->_private = cur->_private;
7356
0
      if (firstChild == NULL){
7357
0
          firstChild = nw;
7358
0
      }
7359
0
      nw = xmlAddChild(ctxt->node, nw);
7360
0
        }
7361
0
        if (cur == ent->last) {
7362
      /*
7363
       * needed to detect some strange empty
7364
       * node cases in the reader tests
7365
       */
7366
0
      if ((ctxt->parseMode == XML_PARSE_READER) &&
7367
0
          (nw != NULL) &&
7368
0
          (nw->type == XML_ELEMENT_NODE) &&
7369
0
          (nw->children == NULL))
7370
0
          nw->extra = 1;
7371
7372
0
      break;
7373
0
        }
7374
0
        cur = cur->next;
7375
0
    }
7376
#ifdef LIBXML_LEGACY_ENABLED
7377
    if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
7378
      xmlAddEntityReference(ent, firstChild, nw);
7379
#endif /* LIBXML_LEGACY_ENABLED */
7380
10.8k
      } else if ((list == NULL) || (ctxt->inputNr > 0)) {
7381
10.8k
    xmlNodePtr nw = NULL, cur, next, last,
7382
10.8k
         firstChild = NULL;
7383
7384
    /*
7385
     * Copy the entity child list and make it the new
7386
     * entity child list. The goal is to make sure any
7387
     * ID or REF referenced will be the one from the
7388
     * document content and not the entity copy.
7389
     */
7390
10.8k
    cur = ent->children;
7391
10.8k
    ent->children = NULL;
7392
10.8k
    last = ent->last;
7393
10.8k
    ent->last = NULL;
7394
38.4k
    while (cur != NULL) {
7395
38.4k
        next = cur->next;
7396
38.4k
        cur->next = NULL;
7397
38.4k
        cur->parent = NULL;
7398
38.4k
        nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
7399
38.4k
        if (nw != NULL) {
7400
38.1k
      if (nw->_private == NULL)
7401
38.1k
          nw->_private = cur->_private;
7402
38.1k
      if (firstChild == NULL){
7403
10.7k
          firstChild = cur;
7404
10.7k
      }
7405
38.1k
      xmlAddChild((xmlNodePtr) ent, nw);
7406
38.1k
        }
7407
38.4k
        xmlAddChild(ctxt->node, cur);
7408
38.4k
        if (cur == last)
7409
10.8k
      break;
7410
27.6k
        cur = next;
7411
27.6k
    }
7412
10.8k
    if (ent->owner == 0)
7413
1.38k
        ent->owner = 1;
7414
#ifdef LIBXML_LEGACY_ENABLED
7415
    if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
7416
      xmlAddEntityReference(ent, firstChild, nw);
7417
#endif /* LIBXML_LEGACY_ENABLED */
7418
10.8k
      } else {
7419
0
    const xmlChar *nbktext;
7420
7421
    /*
7422
     * the name change is to avoid coalescing of the
7423
     * node with a possible previous text one which
7424
     * would make ent->children a dangling pointer
7425
     */
7426
0
    nbktext = xmlDictLookup(ctxt->dict, BAD_CAST "nbktext",
7427
0
          -1);
7428
0
    if (ent->children->type == XML_TEXT_NODE)
7429
0
        ent->children->name = nbktext;
7430
0
    if ((ent->last != ent->children) &&
7431
0
        (ent->last->type == XML_TEXT_NODE))
7432
0
        ent->last->name = nbktext;
7433
0
    xmlAddChildList(ctxt->node, ent->children);
7434
0
      }
7435
7436
      /*
7437
       * This is to avoid a nasty side effect, see
7438
       * characters() in SAX.c
7439
       */
7440
10.8k
      ctxt->nodemem = 0;
7441
10.8k
      ctxt->nodelen = 0;
7442
10.8k
      return;
7443
10.8k
  }
7444
10.8k
    }
7445
10.8k
}
7446
7447
/**
7448
 * xmlParseEntityRef:
7449
 * @ctxt:  an XML parser context
7450
 *
7451
 * DEPRECATED: Internal function, don't use.
7452
 *
7453
 * Parse an entitiy reference. Always consumes '&'.
7454
 *
7455
 * [68] EntityRef ::= '&' Name ';'
7456
 *
7457
 * [ WFC: Entity Declared ]
7458
 * In a document without any DTD, a document with only an internal DTD
7459
 * subset which contains no parameter entity references, or a document
7460
 * with "standalone='yes'", the Name given in the entity reference
7461
 * must match that in an entity declaration, except that well-formed
7462
 * documents need not declare any of the following entities: amp, lt,
7463
 * gt, apos, quot.  The declaration of a parameter entity must precede
7464
 * any reference to it.  Similarly, the declaration of a general entity
7465
 * must precede any reference to it which appears in a default value in an
7466
 * attribute-list declaration. Note that if entities are declared in the
7467
 * external subset or in external parameter entities, a non-validating
7468
 * processor is not obligated to read and process their declarations;
7469
 * for such documents, the rule that an entity must be declared is a
7470
 * well-formedness constraint only if standalone='yes'.
7471
 *
7472
 * [ WFC: Parsed Entity ]
7473
 * An entity reference must not contain the name of an unparsed entity
7474
 *
7475
 * Returns the xmlEntityPtr if found, or NULL otherwise.
7476
 */
7477
xmlEntityPtr
7478
191k
xmlParseEntityRef(xmlParserCtxtPtr ctxt) {
7479
191k
    const xmlChar *name;
7480
191k
    xmlEntityPtr ent = NULL;
7481
7482
191k
    GROW;
7483
191k
    if (ctxt->instate == XML_PARSER_EOF)
7484
1
        return(NULL);
7485
7486
191k
    if (RAW != '&')
7487
0
        return(NULL);
7488
191k
    NEXT;
7489
191k
    name = xmlParseName(ctxt);
7490
191k
    if (name == NULL) {
7491
37.9k
  xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
7492
37.9k
           "xmlParseEntityRef: no name\n");
7493
37.9k
        return(NULL);
7494
37.9k
    }
7495
153k
    if (RAW != ';') {
7496
37.9k
  xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
7497
37.9k
  return(NULL);
7498
37.9k
    }
7499
115k
    NEXT;
7500
7501
    /*
7502
     * Predefined entities override any extra definition
7503
     */
7504
115k
    if ((ctxt->options & XML_PARSE_OLDSAX) == 0) {
7505
115k
        ent = xmlGetPredefinedEntity(name);
7506
115k
        if (ent != NULL)
7507
25.4k
            return(ent);
7508
115k
    }
7509
7510
    /*
7511
     * Ask first SAX for entity resolution, otherwise try the
7512
     * entities which may have stored in the parser context.
7513
     */
7514
89.8k
    if (ctxt->sax != NULL) {
7515
89.8k
  if (ctxt->sax->getEntity != NULL)
7516
89.8k
      ent = ctxt->sax->getEntity(ctxt->userData, name);
7517
89.8k
  if ((ctxt->wellFormed == 1 ) && (ent == NULL) &&
7518
89.8k
      (ctxt->options & XML_PARSE_OLDSAX))
7519
0
      ent = xmlGetPredefinedEntity(name);
7520
89.8k
  if ((ctxt->wellFormed == 1 ) && (ent == NULL) &&
7521
89.8k
      (ctxt->userData==ctxt)) {
7522
8.31k
      ent = xmlSAX2GetEntity(ctxt, name);
7523
8.31k
  }
7524
89.8k
    }
7525
89.8k
    if (ctxt->instate == XML_PARSER_EOF)
7526
72
  return(NULL);
7527
    /*
7528
     * [ WFC: Entity Declared ]
7529
     * In a document without any DTD, a document with only an
7530
     * internal DTD subset which contains no parameter entity
7531
     * references, or a document with "standalone='yes'", the
7532
     * Name given in the entity reference must match that in an
7533
     * entity declaration, except that well-formed documents
7534
     * need not declare any of the following entities: amp, lt,
7535
     * gt, apos, quot.
7536
     * The declaration of a parameter entity must precede any
7537
     * reference to it.
7538
     * Similarly, the declaration of a general entity must
7539
     * precede any reference to it which appears in a default
7540
     * value in an attribute-list declaration. Note that if
7541
     * entities are declared in the external subset or in
7542
     * external parameter entities, a non-validating processor
7543
     * is not obligated to read and process their declarations;
7544
     * for such documents, the rule that an entity must be
7545
     * declared is a well-formedness constraint only if
7546
     * standalone='yes'.
7547
     */
7548
89.8k
    if (ent == NULL) {
7549
33.6k
  if ((ctxt->standalone == 1) ||
7550
33.6k
      ((ctxt->hasExternalSubset == 0) &&
7551
33.4k
       (ctxt->hasPErefs == 0))) {
7552
22.1k
      xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
7553
22.1k
         "Entity '%s' not defined\n", name);
7554
22.1k
  } else {
7555
11.5k
      xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
7556
11.5k
         "Entity '%s' not defined\n", name);
7557
11.5k
      if ((ctxt->inSubset == 0) &&
7558
11.5k
    (ctxt->sax != NULL) &&
7559
11.5k
    (ctxt->sax->reference != NULL)) {
7560
11.0k
    ctxt->sax->reference(ctxt->userData, name);
7561
11.0k
      }
7562
11.5k
  }
7563
33.6k
  ctxt->valid = 0;
7564
33.6k
    }
7565
7566
    /*
7567
     * [ WFC: Parsed Entity ]
7568
     * An entity reference must not contain the name of an
7569
     * unparsed entity
7570
     */
7571
56.1k
    else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
7572
112
  xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
7573
112
     "Entity reference to unparsed entity %s\n", name);
7574
112
    }
7575
7576
    /*
7577
     * [ WFC: No External Entity References ]
7578
     * Attribute values cannot contain direct or indirect
7579
     * entity references to external entities.
7580
     */
7581
56.0k
    else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
7582
56.0k
       (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
7583
512
  xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
7584
512
       "Attribute references external entity '%s'\n", name);
7585
512
    }
7586
    /*
7587
     * [ WFC: No < in Attribute Values ]
7588
     * The replacement text of any entity referred to directly or
7589
     * indirectly in an attribute value (other than "&lt;") must
7590
     * not contain a <.
7591
     */
7592
55.5k
    else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
7593
55.5k
       (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY)) {
7594
19.3k
  if ((ent->flags & XML_ENT_CHECKED_LT) == 0) {
7595
8.12k
            if ((ent->content != NULL) && (xmlStrchr(ent->content, '<')))
7596
889
                ent->flags |= XML_ENT_CONTAINS_LT;
7597
8.12k
            ent->flags |= XML_ENT_CHECKED_LT;
7598
8.12k
        }
7599
19.3k
        if (ent->flags & XML_ENT_CONTAINS_LT)
7600
9.58k
            xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
7601
9.58k
                    "'<' in entity '%s' is not allowed in attributes "
7602
9.58k
                    "values\n", name);
7603
19.3k
    }
7604
7605
    /*
7606
     * Internal check, no parameter entities here ...
7607
     */
7608
36.1k
    else {
7609
36.1k
  switch (ent->etype) {
7610
0
      case XML_INTERNAL_PARAMETER_ENTITY:
7611
0
      case XML_EXTERNAL_PARAMETER_ENTITY:
7612
0
      xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
7613
0
       "Attempt to reference the parameter entity '%s'\n",
7614
0
            name);
7615
0
      break;
7616
36.1k
      default:
7617
36.1k
      break;
7618
36.1k
  }
7619
36.1k
    }
7620
7621
    /*
7622
     * [ WFC: No Recursion ]
7623
     * A parsed entity must not contain a recursive reference
7624
     * to itself, either directly or indirectly.
7625
     * Done somewhere else
7626
     */
7627
89.8k
    return(ent);
7628
89.8k
}
7629
7630
/**
7631
 * xmlParseStringEntityRef:
7632
 * @ctxt:  an XML parser context
7633
 * @str:  a pointer to an index in the string
7634
 *
7635
 * parse ENTITY references declarations, but this version parses it from
7636
 * a string value.
7637
 *
7638
 * [68] EntityRef ::= '&' Name ';'
7639
 *
7640
 * [ WFC: Entity Declared ]
7641
 * In a document without any DTD, a document with only an internal DTD
7642
 * subset which contains no parameter entity references, or a document
7643
 * with "standalone='yes'", the Name given in the entity reference
7644
 * must match that in an entity declaration, except that well-formed
7645
 * documents need not declare any of the following entities: amp, lt,
7646
 * gt, apos, quot.  The declaration of a parameter entity must precede
7647
 * any reference to it.  Similarly, the declaration of a general entity
7648
 * must precede any reference to it which appears in a default value in an
7649
 * attribute-list declaration. Note that if entities are declared in the
7650
 * external subset or in external parameter entities, a non-validating
7651
 * processor is not obligated to read and process their declarations;
7652
 * for such documents, the rule that an entity must be declared is a
7653
 * well-formedness constraint only if standalone='yes'.
7654
 *
7655
 * [ WFC: Parsed Entity ]
7656
 * An entity reference must not contain the name of an unparsed entity
7657
 *
7658
 * Returns the xmlEntityPtr if found, or NULL otherwise. The str pointer
7659
 * is updated to the current location in the string.
7660
 */
7661
static xmlEntityPtr
7662
127k
xmlParseStringEntityRef(xmlParserCtxtPtr ctxt, const xmlChar ** str) {
7663
127k
    xmlChar *name;
7664
127k
    const xmlChar *ptr;
7665
127k
    xmlChar cur;
7666
127k
    xmlEntityPtr ent = NULL;
7667
7668
127k
    if ((str == NULL) || (*str == NULL))
7669
0
        return(NULL);
7670
127k
    ptr = *str;
7671
127k
    cur = *ptr;
7672
127k
    if (cur != '&')
7673
0
  return(NULL);
7674
7675
127k
    ptr++;
7676
127k
    name = xmlParseStringName(ctxt, &ptr);
7677
127k
    if (name == NULL) {
7678
14.6k
  xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
7679
14.6k
           "xmlParseStringEntityRef: no name\n");
7680
14.6k
  *str = ptr;
7681
14.6k
  return(NULL);
7682
14.6k
    }
7683
112k
    if (*ptr != ';') {
7684
2.51k
  xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
7685
2.51k
        xmlFree(name);
7686
2.51k
  *str = ptr;
7687
2.51k
  return(NULL);
7688
2.51k
    }
7689
109k
    ptr++;
7690
7691
7692
    /*
7693
     * Predefined entities override any extra definition
7694
     */
7695
109k
    if ((ctxt->options & XML_PARSE_OLDSAX) == 0) {
7696
109k
        ent = xmlGetPredefinedEntity(name);
7697
109k
        if (ent != NULL) {
7698
8.31k
            xmlFree(name);
7699
8.31k
            *str = ptr;
7700
8.31k
            return(ent);
7701
8.31k
        }
7702
109k
    }
7703
7704
    /*
7705
     * Ask first SAX for entity resolution, otherwise try the
7706
     * entities which may have stored in the parser context.
7707
     */
7708
101k
    if (ctxt->sax != NULL) {
7709
101k
  if (ctxt->sax->getEntity != NULL)
7710
101k
      ent = ctxt->sax->getEntity(ctxt->userData, name);
7711
101k
  if ((ent == NULL) && (ctxt->options & XML_PARSE_OLDSAX))
7712
0
      ent = xmlGetPredefinedEntity(name);
7713
101k
  if ((ent == NULL) && (ctxt->userData==ctxt)) {
7714
26.9k
      ent = xmlSAX2GetEntity(ctxt, name);
7715
26.9k
  }
7716
101k
    }
7717
101k
    if (ctxt->instate == XML_PARSER_EOF) {
7718
0
  xmlFree(name);
7719
0
  return(NULL);
7720
0
    }
7721
7722
    /*
7723
     * [ WFC: Entity Declared ]
7724
     * In a document without any DTD, a document with only an
7725
     * internal DTD subset which contains no parameter entity
7726
     * references, or a document with "standalone='yes'", the
7727
     * Name given in the entity reference must match that in an
7728
     * entity declaration, except that well-formed documents
7729
     * need not declare any of the following entities: amp, lt,
7730
     * gt, apos, quot.
7731
     * The declaration of a parameter entity must precede any
7732
     * reference to it.
7733
     * Similarly, the declaration of a general entity must
7734
     * precede any reference to it which appears in a default
7735
     * value in an attribute-list declaration. Note that if
7736
     * entities are declared in the external subset or in
7737
     * external parameter entities, a non-validating processor
7738
     * is not obligated to read and process their declarations;
7739
     * for such documents, the rule that an entity must be
7740
     * declared is a well-formedness constraint only if
7741
     * standalone='yes'.
7742
     */
7743
101k
    if (ent == NULL) {
7744
26.9k
  if ((ctxt->standalone == 1) ||
7745
26.9k
      ((ctxt->hasExternalSubset == 0) &&
7746
26.4k
       (ctxt->hasPErefs == 0))) {
7747
26.0k
      xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
7748
26.0k
         "Entity '%s' not defined\n", name);
7749
26.0k
  } else {
7750
905
      xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
7751
905
        "Entity '%s' not defined\n",
7752
905
        name);
7753
905
  }
7754
  /* TODO ? check regressions ctxt->valid = 0; */
7755
26.9k
    }
7756
7757
    /*
7758
     * [ WFC: Parsed Entity ]
7759
     * An entity reference must not contain the name of an
7760
     * unparsed entity
7761
     */
7762
74.5k
    else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
7763
209
  xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
7764
209
     "Entity reference to unparsed entity %s\n", name);
7765
209
    }
7766
7767
    /*
7768
     * [ WFC: No External Entity References ]
7769
     * Attribute values cannot contain direct or indirect
7770
     * entity references to external entities.
7771
     */
7772
74.3k
    else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
7773
74.3k
       (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
7774
196
  xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
7775
196
   "Attribute references external entity '%s'\n", name);
7776
196
    }
7777
    /*
7778
     * [ WFC: No < in Attribute Values ]
7779
     * The replacement text of any entity referred to directly or
7780
     * indirectly in an attribute value (other than "&lt;") must
7781
     * not contain a <.
7782
     */
7783
74.1k
    else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
7784
74.1k
       (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY)) {
7785
74.1k
  if ((ent->flags & XML_ENT_CHECKED_LT) == 0) {
7786
1.08k
            if ((ent->content != NULL) && (xmlStrchr(ent->content, '<')))
7787
121
                ent->flags |= XML_ENT_CONTAINS_LT;
7788
1.08k
            ent->flags |= XML_ENT_CHECKED_LT;
7789
1.08k
        }
7790
74.1k
        if (ent->flags & XML_ENT_CONTAINS_LT)
7791
8.08k
            xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
7792
8.08k
                    "'<' in entity '%s' is not allowed in attributes "
7793
8.08k
                    "values\n", name);
7794
74.1k
    }
7795
7796
    /*
7797
     * Internal check, no parameter entities here ...
7798
     */
7799
0
    else {
7800
0
  switch (ent->etype) {
7801
0
      case XML_INTERNAL_PARAMETER_ENTITY:
7802
0
      case XML_EXTERNAL_PARAMETER_ENTITY:
7803
0
    xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
7804
0
       "Attempt to reference the parameter entity '%s'\n",
7805
0
          name);
7806
0
      break;
7807
0
      default:
7808
0
      break;
7809
0
  }
7810
0
    }
7811
7812
    /*
7813
     * [ WFC: No Recursion ]
7814
     * A parsed entity must not contain a recursive reference
7815
     * to itself, either directly or indirectly.
7816
     * Done somewhere else
7817
     */
7818
7819
101k
    xmlFree(name);
7820
101k
    *str = ptr;
7821
101k
    return(ent);
7822
101k
}
7823
7824
/**
7825
 * xmlParsePEReference:
7826
 * @ctxt:  an XML parser context
7827
 *
7828
 * DEPRECATED: Internal function, don't use.
7829
 *
7830
 * Parse a parameter entity reference. Always consumes '%'.
7831
 *
7832
 * The entity content is handled directly by pushing it's content as
7833
 * a new input stream.
7834
 *
7835
 * [69] PEReference ::= '%' Name ';'
7836
 *
7837
 * [ WFC: No Recursion ]
7838
 * A parsed entity must not contain a recursive
7839
 * reference to itself, either directly or indirectly.
7840
 *
7841
 * [ WFC: Entity Declared ]
7842
 * In a document without any DTD, a document with only an internal DTD
7843
 * subset which contains no parameter entity references, or a document
7844
 * with "standalone='yes'", ...  ... The declaration of a parameter
7845
 * entity must precede any reference to it...
7846
 *
7847
 * [ VC: Entity Declared ]
7848
 * In a document with an external subset or external parameter entities
7849
 * with "standalone='no'", ...  ... The declaration of a parameter entity
7850
 * must precede any reference to it...
7851
 *
7852
 * [ WFC: In DTD ]
7853
 * Parameter-entity references may only appear in the DTD.
7854
 * NOTE: misleading but this is handled.
7855
 */
7856
void
7857
xmlParsePEReference(xmlParserCtxtPtr ctxt)
7858
166k
{
7859
166k
    const xmlChar *name;
7860
166k
    xmlEntityPtr entity = NULL;
7861
166k
    xmlParserInputPtr input;
7862
7863
166k
    if (RAW != '%')
7864
0
        return;
7865
166k
    NEXT;
7866
166k
    name = xmlParseName(ctxt);
7867
166k
    if (name == NULL) {
7868
52.8k
  xmlFatalErrMsg(ctxt, XML_ERR_PEREF_NO_NAME, "PEReference: no name\n");
7869
52.8k
  return;
7870
52.8k
    }
7871
113k
    if (xmlParserDebugEntities)
7872
0
  xmlGenericError(xmlGenericErrorContext,
7873
0
    "PEReference: %s\n", name);
7874
113k
    if (RAW != ';') {
7875
29.3k
  xmlFatalErr(ctxt, XML_ERR_PEREF_SEMICOL_MISSING, NULL);
7876
29.3k
        return;
7877
29.3k
    }
7878
7879
84.5k
    NEXT;
7880
7881
    /*
7882
     * Request the entity from SAX
7883
     */
7884
84.5k
    if ((ctxt->sax != NULL) &&
7885
84.5k
  (ctxt->sax->getParameterEntity != NULL))
7886
84.5k
  entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
7887
84.5k
    if (ctxt->instate == XML_PARSER_EOF)
7888
10
  return;
7889
84.5k
    if (entity == NULL) {
7890
  /*
7891
   * [ WFC: Entity Declared ]
7892
   * In a document without any DTD, a document with only an
7893
   * internal DTD subset which contains no parameter entity
7894
   * references, or a document with "standalone='yes'", ...
7895
   * ... The declaration of a parameter entity must precede
7896
   * any reference to it...
7897
   */
7898
15.0k
  if ((ctxt->standalone == 1) ||
7899
15.0k
      ((ctxt->hasExternalSubset == 0) &&
7900
14.4k
       (ctxt->hasPErefs == 0))) {
7901
2.76k
      xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
7902
2.76k
            "PEReference: %%%s; not found\n",
7903
2.76k
            name);
7904
12.2k
  } else {
7905
      /*
7906
       * [ VC: Entity Declared ]
7907
       * In a document with an external subset or external
7908
       * parameter entities with "standalone='no'", ...
7909
       * ... The declaration of a parameter entity must
7910
       * precede any reference to it...
7911
       */
7912
12.2k
            if ((ctxt->validate) && (ctxt->vctxt.error != NULL)) {
7913
0
                xmlValidityError(ctxt, XML_WAR_UNDECLARED_ENTITY,
7914
0
                                 "PEReference: %%%s; not found\n",
7915
0
                                 name, NULL);
7916
0
            } else
7917
12.2k
                xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
7918
12.2k
                              "PEReference: %%%s; not found\n",
7919
12.2k
                              name, NULL);
7920
12.2k
            ctxt->valid = 0;
7921
12.2k
  }
7922
69.4k
    } else {
7923
  /*
7924
   * Internal checking in case the entity quest barfed
7925
   */
7926
69.4k
  if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
7927
69.4k
      (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
7928
0
      xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
7929
0
      "Internal: %%%s; is not a parameter entity\n",
7930
0
        name, NULL);
7931
69.4k
  } else {
7932
69.4k
            xmlChar start[4];
7933
69.4k
            xmlCharEncoding enc;
7934
69.4k
            unsigned long parentConsumed;
7935
69.4k
            xmlEntityPtr oldEnt;
7936
7937
69.4k
      if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
7938
69.4k
          ((ctxt->options & XML_PARSE_NOENT) == 0) &&
7939
69.4k
    ((ctxt->options & XML_PARSE_DTDVALID) == 0) &&
7940
69.4k
    ((ctxt->options & XML_PARSE_DTDLOAD) == 0) &&
7941
69.4k
    ((ctxt->options & XML_PARSE_DTDATTR) == 0) &&
7942
69.4k
    (ctxt->replaceEntities == 0) &&
7943
69.4k
    (ctxt->validate == 0))
7944
0
    return;
7945
7946
69.4k
            if (entity->flags & XML_ENT_EXPANDING) {
7947
3
                xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
7948
3
                xmlHaltParser(ctxt);
7949
3
                return;
7950
3
            }
7951
7952
            /* Must be computed from old input before pushing new input. */
7953
69.4k
            parentConsumed = ctxt->input->parentConsumed;
7954
69.4k
            oldEnt = ctxt->input->entity;
7955
69.4k
            if ((oldEnt == NULL) ||
7956
69.4k
                ((oldEnt->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
7957
69.4k
                 ((oldEnt->flags & XML_ENT_PARSED) == 0))) {
7958
69.4k
                xmlSaturatedAdd(&parentConsumed, ctxt->input->consumed);
7959
69.4k
                xmlSaturatedAddSizeT(&parentConsumed,
7960
69.4k
                                     ctxt->input->cur - ctxt->input->base);
7961
69.4k
            }
7962
7963
69.4k
      input = xmlNewEntityInputStream(ctxt, entity);
7964
69.4k
      if (xmlPushInput(ctxt, input) < 0) {
7965
3.75k
                xmlFreeInputStream(input);
7966
3.75k
    return;
7967
3.75k
            }
7968
7969
65.7k
            entity->flags |= XML_ENT_EXPANDING;
7970
7971
65.7k
            input->parentConsumed = parentConsumed;
7972
7973
65.7k
      if (entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) {
7974
                /*
7975
                 * Get the 4 first bytes and decode the charset
7976
                 * if enc != XML_CHAR_ENCODING_NONE
7977
                 * plug some encoding conversion routines.
7978
                 * Note that, since we may have some non-UTF8
7979
                 * encoding (like UTF16, bug 135229), the 'length'
7980
                 * is not known, but we can calculate based upon
7981
                 * the amount of data in the buffer.
7982
                 */
7983
17.7k
                GROW
7984
17.7k
                if (ctxt->instate == XML_PARSER_EOF)
7985
0
                    return;
7986
17.7k
                if ((ctxt->input->end - ctxt->input->cur)>=4) {
7987
17.5k
                    start[0] = RAW;
7988
17.5k
                    start[1] = NXT(1);
7989
17.5k
                    start[2] = NXT(2);
7990
17.5k
                    start[3] = NXT(3);
7991
17.5k
                    enc = xmlDetectCharEncoding(start, 4);
7992
17.5k
                    if (enc != XML_CHAR_ENCODING_NONE) {
7993
14.6k
                        xmlSwitchEncoding(ctxt, enc);
7994
14.6k
                    }
7995
17.5k
                }
7996
7997
17.7k
                if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) &&
7998
17.7k
                    (IS_BLANK_CH(NXT(5)))) {
7999
9.76k
                    xmlParseTextDecl(ctxt);
8000
9.76k
                }
8001
17.7k
            }
8002
65.7k
  }
8003
69.4k
    }
8004
80.7k
    ctxt->hasPErefs = 1;
8005
80.7k
}
8006
8007
/**
8008
 * xmlLoadEntityContent:
8009
 * @ctxt:  an XML parser context
8010
 * @entity: an unloaded system entity
8011
 *
8012
 * Load the original content of the given system entity from the
8013
 * ExternalID/SystemID given. This is to be used for Included in Literal
8014
 * http://www.w3.org/TR/REC-xml/#inliteral processing of entities references
8015
 *
8016
 * Returns 0 in case of success and -1 in case of failure
8017
 */
8018
static int
8019
80
xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
8020
80
    xmlParserInputPtr input;
8021
80
    xmlBufferPtr buf;
8022
80
    int l, c;
8023
8024
80
    if ((ctxt == NULL) || (entity == NULL) ||
8025
80
        ((entity->etype != XML_EXTERNAL_PARAMETER_ENTITY) &&
8026
80
   (entity->etype != XML_EXTERNAL_GENERAL_PARSED_ENTITY)) ||
8027
80
  (entity->content != NULL)) {
8028
0
  xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
8029
0
              "xmlLoadEntityContent parameter error");
8030
0
        return(-1);
8031
0
    }
8032
8033
80
    if (xmlParserDebugEntities)
8034
0
  xmlGenericError(xmlGenericErrorContext,
8035
0
    "Reading %s entity content input\n", entity->name);
8036
8037
80
    buf = xmlBufferCreate();
8038
80
    if (buf == NULL) {
8039
0
  xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
8040
0
              "xmlLoadEntityContent parameter error");
8041
0
        return(-1);
8042
0
    }
8043
80
    xmlBufferSetAllocationScheme(buf, XML_BUFFER_ALLOC_DOUBLEIT);
8044
8045
80
    input = xmlNewEntityInputStream(ctxt, entity);
8046
80
    if (input == NULL) {
8047
0
  xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
8048
0
              "xmlLoadEntityContent input error");
8049
0
  xmlBufferFree(buf);
8050
0
        return(-1);
8051
0
    }
8052
8053
    /*
8054
     * Push the entity as the current input, read char by char
8055
     * saving to the buffer until the end of the entity or an error
8056
     */
8057
80
    if (xmlPushInput(ctxt, input) < 0) {
8058
0
        xmlBufferFree(buf);
8059
0
  xmlFreeInputStream(input);
8060
0
  return(-1);
8061
0
    }
8062
8063
80
    GROW;
8064
80
    c = CUR_CHAR(l);
8065
2.40M
    while ((ctxt->input == input) && (ctxt->input->cur < ctxt->input->end) &&
8066
2.40M
           (IS_CHAR(c))) {
8067
2.40M
        xmlBufferAdd(buf, ctxt->input->cur, l);
8068
2.40M
  NEXTL(l);
8069
2.40M
  c = CUR_CHAR(l);
8070
2.40M
    }
8071
80
    if (ctxt->instate == XML_PARSER_EOF) {
8072
0
  xmlBufferFree(buf);
8073
0
  return(-1);
8074
0
    }
8075
8076
80
    if ((ctxt->input == input) && (ctxt->input->cur >= ctxt->input->end)) {
8077
47
        xmlSaturatedAdd(&ctxt->sizeentities, ctxt->input->consumed);
8078
47
        xmlPopInput(ctxt);
8079
47
    } else if (!IS_CHAR(c)) {
8080
33
        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
8081
33
                          "xmlLoadEntityContent: invalid char value %d\n",
8082
33
                    c);
8083
33
  xmlBufferFree(buf);
8084
33
  return(-1);
8085
33
    }
8086
47
    entity->content = buf->content;
8087
47
    entity->length = buf->use;
8088
47
    buf->content = NULL;
8089
47
    xmlBufferFree(buf);
8090
8091
47
    return(0);
8092
80
}
8093
8094
/**
8095
 * xmlParseStringPEReference:
8096
 * @ctxt:  an XML parser context
8097
 * @str:  a pointer to an index in the string
8098
 *
8099
 * parse PEReference declarations
8100
 *
8101
 * [69] PEReference ::= '%' Name ';'
8102
 *
8103
 * [ WFC: No Recursion ]
8104
 * A parsed entity must not contain a recursive
8105
 * reference to itself, either directly or indirectly.
8106
 *
8107
 * [ WFC: Entity Declared ]
8108
 * In a document without any DTD, a document with only an internal DTD
8109
 * subset which contains no parameter entity references, or a document
8110
 * with "standalone='yes'", ...  ... The declaration of a parameter
8111
 * entity must precede any reference to it...
8112
 *
8113
 * [ VC: Entity Declared ]
8114
 * In a document with an external subset or external parameter entities
8115
 * with "standalone='no'", ...  ... The declaration of a parameter entity
8116
 * must precede any reference to it...
8117
 *
8118
 * [ WFC: In DTD ]
8119
 * Parameter-entity references may only appear in the DTD.
8120
 * NOTE: misleading but this is handled.
8121
 *
8122
 * Returns the string of the entity content.
8123
 *         str is updated to the current value of the index
8124
 */
8125
static xmlEntityPtr
8126
1.61k
xmlParseStringPEReference(xmlParserCtxtPtr ctxt, const xmlChar **str) {
8127
1.61k
    const xmlChar *ptr;
8128
1.61k
    xmlChar cur;
8129
1.61k
    xmlChar *name;
8130
1.61k
    xmlEntityPtr entity = NULL;
8131
8132
1.61k
    if ((str == NULL) || (*str == NULL)) return(NULL);
8133
1.61k
    ptr = *str;
8134
1.61k
    cur = *ptr;
8135
1.61k
    if (cur != '%')
8136
0
        return(NULL);
8137
1.61k
    ptr++;
8138
1.61k
    name = xmlParseStringName(ctxt, &ptr);
8139
1.61k
    if (name == NULL) {
8140
968
  xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8141
968
           "xmlParseStringPEReference: no name\n");
8142
968
  *str = ptr;
8143
968
  return(NULL);
8144
968
    }
8145
643
    cur = *ptr;
8146
643
    if (cur != ';') {
8147
105
  xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
8148
105
  xmlFree(name);
8149
105
  *str = ptr;
8150
105
  return(NULL);
8151
105
    }
8152
538
    ptr++;
8153
8154
    /*
8155
     * Request the entity from SAX
8156
     */
8157
538
    if ((ctxt->sax != NULL) &&
8158
538
  (ctxt->sax->getParameterEntity != NULL))
8159
538
  entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
8160
538
    if (ctxt->instate == XML_PARSER_EOF) {
8161
0
  xmlFree(name);
8162
0
  *str = ptr;
8163
0
  return(NULL);
8164
0
    }
8165
538
    if (entity == NULL) {
8166
  /*
8167
   * [ WFC: Entity Declared ]
8168
   * In a document without any DTD, a document with only an
8169
   * internal DTD subset which contains no parameter entity
8170
   * references, or a document with "standalone='yes'", ...
8171
   * ... The declaration of a parameter entity must precede
8172
   * any reference to it...
8173
   */
8174
411
  if ((ctxt->standalone == 1) ||
8175
411
      ((ctxt->hasExternalSubset == 0) && (ctxt->hasPErefs == 0))) {
8176
0
      xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
8177
0
     "PEReference: %%%s; not found\n", name);
8178
411
  } else {
8179
      /*
8180
       * [ VC: Entity Declared ]
8181
       * In a document with an external subset or external
8182
       * parameter entities with "standalone='no'", ...
8183
       * ... The declaration of a parameter entity must
8184
       * precede any reference to it...
8185
       */
8186
411
      xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
8187
411
        "PEReference: %%%s; not found\n",
8188
411
        name, NULL);
8189
411
      ctxt->valid = 0;
8190
411
  }
8191
411
    } else {
8192
  /*
8193
   * Internal checking in case the entity quest barfed
8194
   */
8195
127
  if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
8196
127
      (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
8197
0
      xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
8198
0
        "%%%s; is not a parameter entity\n",
8199
0
        name, NULL);
8200
0
  }
8201
127
    }
8202
538
    ctxt->hasPErefs = 1;
8203
538
    xmlFree(name);
8204
538
    *str = ptr;
8205
538
    return(entity);
8206
538
}
8207
8208
/**
8209
 * xmlParseDocTypeDecl:
8210
 * @ctxt:  an XML parser context
8211
 *
8212
 * DEPRECATED: Internal function, don't use.
8213
 *
8214
 * parse a DOCTYPE declaration
8215
 *
8216
 * [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S?
8217
 *                      ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
8218
 *
8219
 * [ VC: Root Element Type ]
8220
 * The Name in the document type declaration must match the element
8221
 * type of the root element.
8222
 */
8223
8224
void
8225
59.9k
xmlParseDocTypeDecl(xmlParserCtxtPtr ctxt) {
8226
59.9k
    const xmlChar *name = NULL;
8227
59.9k
    xmlChar *ExternalID = NULL;
8228
59.9k
    xmlChar *URI = NULL;
8229
8230
    /*
8231
     * We know that '<!DOCTYPE' has been detected.
8232
     */
8233
59.9k
    SKIP(9);
8234
8235
59.9k
    SKIP_BLANKS;
8236
8237
    /*
8238
     * Parse the DOCTYPE name.
8239
     */
8240
59.9k
    name = xmlParseName(ctxt);
8241
59.9k
    if (name == NULL) {
8242
1.57k
  xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8243
1.57k
           "xmlParseDocTypeDecl : no DOCTYPE name !\n");
8244
1.57k
    }
8245
59.9k
    ctxt->intSubName = name;
8246
8247
59.9k
    SKIP_BLANKS;
8248
8249
    /*
8250
     * Check for SystemID and ExternalID
8251
     */
8252
59.9k
    URI = xmlParseExternalID(ctxt, &ExternalID, 1);
8253
8254
59.9k
    if ((URI != NULL) || (ExternalID != NULL)) {
8255
10.3k
        ctxt->hasExternalSubset = 1;
8256
10.3k
    }
8257
59.9k
    ctxt->extSubURI = URI;
8258
59.9k
    ctxt->extSubSystem = ExternalID;
8259
8260
59.9k
    SKIP_BLANKS;
8261
8262
    /*
8263
     * Create and update the internal subset.
8264
     */
8265
59.9k
    if ((ctxt->sax != NULL) && (ctxt->sax->internalSubset != NULL) &&
8266
59.9k
  (!ctxt->disableSAX))
8267
47.2k
  ctxt->sax->internalSubset(ctxt->userData, name, ExternalID, URI);
8268
59.9k
    if (ctxt->instate == XML_PARSER_EOF)
8269
258
  return;
8270
8271
    /*
8272
     * Is there any internal subset declarations ?
8273
     * they are handled separately in xmlParseInternalSubset()
8274
     */
8275
59.7k
    if (RAW == '[')
8276
49.8k
  return;
8277
8278
    /*
8279
     * We should be at the end of the DOCTYPE declaration.
8280
     */
8281
9.83k
    if (RAW != '>') {
8282
6.15k
  xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
8283
6.15k
    }
8284
9.83k
    NEXT;
8285
9.83k
}
8286
8287
/**
8288
 * xmlParseInternalSubset:
8289
 * @ctxt:  an XML parser context
8290
 *
8291
 * parse the internal subset declaration
8292
 *
8293
 * [28 end] ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
8294
 */
8295
8296
static void
8297
50.8k
xmlParseInternalSubset(xmlParserCtxtPtr ctxt) {
8298
    /*
8299
     * Is there any DTD definition ?
8300
     */
8301
50.8k
    if (RAW == '[') {
8302
50.8k
        int baseInputNr = ctxt->inputNr;
8303
50.8k
        ctxt->instate = XML_PARSER_DTD;
8304
50.8k
        NEXT;
8305
  /*
8306
   * Parse the succession of Markup declarations and
8307
   * PEReferences.
8308
   * Subsequence (markupdecl | PEReference | S)*
8309
   */
8310
50.8k
  SKIP_BLANKS;
8311
502k
  while (((RAW != ']') || (ctxt->inputNr > baseInputNr)) &&
8312
502k
               (ctxt->instate != XML_PARSER_EOF)) {
8313
8314
            /*
8315
             * Conditional sections are allowed from external entities included
8316
             * by PE References in the internal subset.
8317
             */
8318
477k
            if ((ctxt->inputNr > 1) && (ctxt->input->filename != NULL) &&
8319
477k
                (RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
8320
235
                xmlParseConditionalSections(ctxt);
8321
477k
            } else if ((RAW == '<') && ((NXT(1) == '!') || (NXT(1) == '?'))) {
8322
373k
          xmlParseMarkupDecl(ctxt);
8323
373k
            } else if (RAW == '%') {
8324
77.4k
          xmlParsePEReference(ctxt);
8325
77.4k
            } else {
8326
26.3k
    xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
8327
26.3k
                        "xmlParseInternalSubset: error detected in"
8328
26.3k
                        " Markup declaration\n");
8329
26.3k
                xmlHaltParser(ctxt);
8330
26.3k
                return;
8331
26.3k
            }
8332
451k
      SKIP_BLANKS;
8333
451k
            SHRINK;
8334
451k
            GROW;
8335
451k
  }
8336
24.4k
  if (RAW == ']') {
8337
17.4k
      NEXT;
8338
17.4k
      SKIP_BLANKS;
8339
17.4k
  }
8340
24.4k
    }
8341
8342
    /*
8343
     * We should be at the end of the DOCTYPE declaration.
8344
     */
8345
24.4k
    if (RAW != '>') {
8346
8.35k
  xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
8347
8.35k
  return;
8348
8.35k
    }
8349
16.1k
    NEXT;
8350
16.1k
}
8351
8352
#ifdef LIBXML_SAX1_ENABLED
8353
/**
8354
 * xmlParseAttribute:
8355
 * @ctxt:  an XML parser context
8356
 * @value:  a xmlChar ** used to store the value of the attribute
8357
 *
8358
 * DEPRECATED: Internal function, don't use.
8359
 *
8360
 * parse an attribute
8361
 *
8362
 * [41] Attribute ::= Name Eq AttValue
8363
 *
8364
 * [ WFC: No External Entity References ]
8365
 * Attribute values cannot contain direct or indirect entity references
8366
 * to external entities.
8367
 *
8368
 * [ WFC: No < in Attribute Values ]
8369
 * The replacement text of any entity referred to directly or indirectly in
8370
 * an attribute value (other than "&lt;") must not contain a <.
8371
 *
8372
 * [ VC: Attribute Value Type ]
8373
 * The attribute must have been declared; the value must be of the type
8374
 * declared for it.
8375
 *
8376
 * [25] Eq ::= S? '=' S?
8377
 *
8378
 * With namespace:
8379
 *
8380
 * [NS 11] Attribute ::= QName Eq AttValue
8381
 *
8382
 * Also the case QName == xmlns:??? is handled independently as a namespace
8383
 * definition.
8384
 *
8385
 * Returns the attribute name, and the value in *value.
8386
 */
8387
8388
const xmlChar *
8389
xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlChar **value) {
8390
    const xmlChar *name;
8391
    xmlChar *val;
8392
8393
    *value = NULL;
8394
    GROW;
8395
    name = xmlParseName(ctxt);
8396
    if (name == NULL) {
8397
  xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8398
                 "error parsing attribute name\n");
8399
        return(NULL);
8400
    }
8401
8402
    /*
8403
     * read the value
8404
     */
8405
    SKIP_BLANKS;
8406
    if (RAW == '=') {
8407
        NEXT;
8408
  SKIP_BLANKS;
8409
  val = xmlParseAttValue(ctxt);
8410
  ctxt->instate = XML_PARSER_CONTENT;
8411
    } else {
8412
  xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
8413
         "Specification mandates value for attribute %s\n", name);
8414
  return(name);
8415
    }
8416
8417
    /*
8418
     * Check that xml:lang conforms to the specification
8419
     * No more registered as an error, just generate a warning now
8420
     * since this was deprecated in XML second edition
8421
     */
8422
    if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "xml:lang"))) {
8423
  if (!xmlCheckLanguageID(val)) {
8424
      xmlWarningMsg(ctxt, XML_WAR_LANG_VALUE,
8425
              "Malformed value for xml:lang : %s\n",
8426
        val, NULL);
8427
  }
8428
    }
8429
8430
    /*
8431
     * Check that xml:space conforms to the specification
8432
     */
8433
    if (xmlStrEqual(name, BAD_CAST "xml:space")) {
8434
  if (xmlStrEqual(val, BAD_CAST "default"))
8435
      *(ctxt->space) = 0;
8436
  else if (xmlStrEqual(val, BAD_CAST "preserve"))
8437
      *(ctxt->space) = 1;
8438
  else {
8439
    xmlWarningMsg(ctxt, XML_WAR_SPACE_VALUE,
8440
"Invalid value \"%s\" for xml:space : \"default\" or \"preserve\" expected\n",
8441
                                 val, NULL);
8442
  }
8443
    }
8444
8445
    *value = val;
8446
    return(name);
8447
}
8448
8449
/**
8450
 * xmlParseStartTag:
8451
 * @ctxt:  an XML parser context
8452
 *
8453
 * DEPRECATED: Internal function, don't use.
8454
 *
8455
 * Parse a start tag. Always consumes '<'.
8456
 *
8457
 * [40] STag ::= '<' Name (S Attribute)* S? '>'
8458
 *
8459
 * [ WFC: Unique Att Spec ]
8460
 * No attribute name may appear more than once in the same start-tag or
8461
 * empty-element tag.
8462
 *
8463
 * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
8464
 *
8465
 * [ WFC: Unique Att Spec ]
8466
 * No attribute name may appear more than once in the same start-tag or
8467
 * empty-element tag.
8468
 *
8469
 * With namespace:
8470
 *
8471
 * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
8472
 *
8473
 * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
8474
 *
8475
 * Returns the element name parsed
8476
 */
8477
8478
const xmlChar *
8479
xmlParseStartTag(xmlParserCtxtPtr ctxt) {
8480
    const xmlChar *name;
8481
    const xmlChar *attname;
8482
    xmlChar *attvalue;
8483
    const xmlChar **atts = ctxt->atts;
8484
    int nbatts = 0;
8485
    int maxatts = ctxt->maxatts;
8486
    int i;
8487
8488
    if (RAW != '<') return(NULL);
8489
    NEXT1;
8490
8491
    name = xmlParseName(ctxt);
8492
    if (name == NULL) {
8493
  xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8494
       "xmlParseStartTag: invalid element name\n");
8495
        return(NULL);
8496
    }
8497
8498
    /*
8499
     * Now parse the attributes, it ends up with the ending
8500
     *
8501
     * (S Attribute)* S?
8502
     */
8503
    SKIP_BLANKS;
8504
    GROW;
8505
8506
    while (((RAW != '>') &&
8507
     ((RAW != '/') || (NXT(1) != '>')) &&
8508
     (IS_BYTE_CHAR(RAW))) && (ctxt->instate != XML_PARSER_EOF)) {
8509
  attname = xmlParseAttribute(ctxt, &attvalue);
8510
        if (attname == NULL) {
8511
      xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
8512
         "xmlParseStartTag: problem parsing attributes\n");
8513
      break;
8514
  }
8515
        if (attvalue != NULL) {
8516
      /*
8517
       * [ WFC: Unique Att Spec ]
8518
       * No attribute name may appear more than once in the same
8519
       * start-tag or empty-element tag.
8520
       */
8521
      for (i = 0; i < nbatts;i += 2) {
8522
          if (xmlStrEqual(atts[i], attname)) {
8523
        xmlErrAttributeDup(ctxt, NULL, attname);
8524
        xmlFree(attvalue);
8525
        goto failed;
8526
    }
8527
      }
8528
      /*
8529
       * Add the pair to atts
8530
       */
8531
      if (atts == NULL) {
8532
          maxatts = 22; /* allow for 10 attrs by default */
8533
          atts = (const xmlChar **)
8534
           xmlMalloc(maxatts * sizeof(xmlChar *));
8535
    if (atts == NULL) {
8536
        xmlErrMemory(ctxt, NULL);
8537
        if (attvalue != NULL)
8538
      xmlFree(attvalue);
8539
        goto failed;
8540
    }
8541
    ctxt->atts = atts;
8542
    ctxt->maxatts = maxatts;
8543
      } else if (nbatts + 4 > maxatts) {
8544
          const xmlChar **n;
8545
8546
          maxatts *= 2;
8547
          n = (const xmlChar **) xmlRealloc((void *) atts,
8548
               maxatts * sizeof(const xmlChar *));
8549
    if (n == NULL) {
8550
        xmlErrMemory(ctxt, NULL);
8551
        if (attvalue != NULL)
8552
      xmlFree(attvalue);
8553
        goto failed;
8554
    }
8555
    atts = n;
8556
    ctxt->atts = atts;
8557
    ctxt->maxatts = maxatts;
8558
      }
8559
      atts[nbatts++] = attname;
8560
      atts[nbatts++] = attvalue;
8561
      atts[nbatts] = NULL;
8562
      atts[nbatts + 1] = NULL;
8563
  } else {
8564
      if (attvalue != NULL)
8565
    xmlFree(attvalue);
8566
  }
8567
8568
failed:
8569
8570
  GROW
8571
  if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
8572
      break;
8573
  if (SKIP_BLANKS == 0) {
8574
      xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
8575
         "attributes construct error\n");
8576
  }
8577
  SHRINK;
8578
        GROW;
8579
    }
8580
8581
    /*
8582
     * SAX: Start of Element !
8583
     */
8584
    if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL) &&
8585
  (!ctxt->disableSAX)) {
8586
  if (nbatts > 0)
8587
      ctxt->sax->startElement(ctxt->userData, name, atts);
8588
  else
8589
      ctxt->sax->startElement(ctxt->userData, name, NULL);
8590
    }
8591
8592
    if (atts != NULL) {
8593
        /* Free only the content strings */
8594
        for (i = 1;i < nbatts;i+=2)
8595
      if (atts[i] != NULL)
8596
         xmlFree((xmlChar *) atts[i]);
8597
    }
8598
    return(name);
8599
}
8600
8601
/**
8602
 * xmlParseEndTag1:
8603
 * @ctxt:  an XML parser context
8604
 * @line:  line of the start tag
8605
 * @nsNr:  number of namespaces on the start tag
8606
 *
8607
 * Parse an end tag. Always consumes '</'.
8608
 *
8609
 * [42] ETag ::= '</' Name S? '>'
8610
 *
8611
 * With namespace
8612
 *
8613
 * [NS 9] ETag ::= '</' QName S? '>'
8614
 */
8615
8616
static void
8617
xmlParseEndTag1(xmlParserCtxtPtr ctxt, int line) {
8618
    const xmlChar *name;
8619
8620
    GROW;
8621
    if ((RAW != '<') || (NXT(1) != '/')) {
8622
  xmlFatalErrMsg(ctxt, XML_ERR_LTSLASH_REQUIRED,
8623
           "xmlParseEndTag: '</' not found\n");
8624
  return;
8625
    }
8626
    SKIP(2);
8627
8628
    name = xmlParseNameAndCompare(ctxt,ctxt->name);
8629
8630
    /*
8631
     * We should definitely be at the ending "S? '>'" part
8632
     */
8633
    GROW;
8634
    SKIP_BLANKS;
8635
    if ((!IS_BYTE_CHAR(RAW)) || (RAW != '>')) {
8636
  xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
8637
    } else
8638
  NEXT1;
8639
8640
    /*
8641
     * [ WFC: Element Type Match ]
8642
     * The Name in an element's end-tag must match the element type in the
8643
     * start-tag.
8644
     *
8645
     */
8646
    if (name != (xmlChar*)1) {
8647
        if (name == NULL) name = BAD_CAST "unparsable";
8648
        xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
8649
         "Opening and ending tag mismatch: %s line %d and %s\n",
8650
                    ctxt->name, line, name);
8651
    }
8652
8653
    /*
8654
     * SAX: End of Tag
8655
     */
8656
    if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
8657
  (!ctxt->disableSAX))
8658
        ctxt->sax->endElement(ctxt->userData, ctxt->name);
8659
8660
    namePop(ctxt);
8661
    spacePop(ctxt);
8662
    return;
8663
}
8664
8665
/**
8666
 * xmlParseEndTag:
8667
 * @ctxt:  an XML parser context
8668
 *
8669
 * DEPRECATED: Internal function, don't use.
8670
 *
8671
 * parse an end of tag
8672
 *
8673
 * [42] ETag ::= '</' Name S? '>'
8674
 *
8675
 * With namespace
8676
 *
8677
 * [NS 9] ETag ::= '</' QName S? '>'
8678
 */
8679
8680
void
8681
xmlParseEndTag(xmlParserCtxtPtr ctxt) {
8682
    xmlParseEndTag1(ctxt, 0);
8683
}
8684
#endif /* LIBXML_SAX1_ENABLED */
8685
8686
/************************************************************************
8687
 *                  *
8688
 *          SAX 2 specific operations       *
8689
 *                  *
8690
 ************************************************************************/
8691
8692
/*
8693
 * xmlGetNamespace:
8694
 * @ctxt:  an XML parser context
8695
 * @prefix:  the prefix to lookup
8696
 *
8697
 * Lookup the namespace name for the @prefix (which ca be NULL)
8698
 * The prefix must come from the @ctxt->dict dictionary
8699
 *
8700
 * Returns the namespace name or NULL if not bound
8701
 */
8702
static const xmlChar *
8703
2.81M
xmlGetNamespace(xmlParserCtxtPtr ctxt, const xmlChar *prefix) {
8704
2.81M
    int i;
8705
8706
2.81M
    if (prefix == ctxt->str_xml) return(ctxt->str_xml_ns);
8707
3.92M
    for (i = ctxt->nsNr - 2;i >= 0;i-=2)
8708
2.89M
        if (ctxt->nsTab[i] == prefix) {
8709
1.42M
      if ((prefix == NULL) && (*ctxt->nsTab[i + 1] == 0))
8710
16.9k
          return(NULL);
8711
1.41M
      return(ctxt->nsTab[i + 1]);
8712
1.42M
  }
8713
1.02M
    return(NULL);
8714
2.45M
}
8715
8716
/**
8717
 * xmlParseQName:
8718
 * @ctxt:  an XML parser context
8719
 * @prefix:  pointer to store the prefix part
8720
 *
8721
 * parse an XML Namespace QName
8722
 *
8723
 * [6]  QName  ::= (Prefix ':')? LocalPart
8724
 * [7]  Prefix  ::= NCName
8725
 * [8]  LocalPart  ::= NCName
8726
 *
8727
 * Returns the Name parsed or NULL
8728
 */
8729
8730
static const xmlChar *
8731
5.34M
xmlParseQName(xmlParserCtxtPtr ctxt, const xmlChar **prefix) {
8732
5.34M
    const xmlChar *l, *p;
8733
8734
5.34M
    GROW;
8735
5.34M
    if (ctxt->instate == XML_PARSER_EOF)
8736
234
        return(NULL);
8737
8738
5.34M
    l = xmlParseNCName(ctxt);
8739
5.34M
    if (l == NULL) {
8740
194k
        if (CUR == ':') {
8741
39.4k
      l = xmlParseName(ctxt);
8742
39.4k
      if (l != NULL) {
8743
39.1k
          xmlNsErr(ctxt, XML_NS_ERR_QNAME,
8744
39.1k
             "Failed to parse QName '%s'\n", l, NULL, NULL);
8745
39.1k
    *prefix = NULL;
8746
39.1k
    return(l);
8747
39.1k
      }
8748
39.4k
  }
8749
155k
        return(NULL);
8750
194k
    }
8751
5.14M
    if (CUR == ':') {
8752
2.25M
        NEXT;
8753
2.25M
  p = l;
8754
2.25M
  l = xmlParseNCName(ctxt);
8755
2.25M
  if (l == NULL) {
8756
24.7k
      xmlChar *tmp;
8757
8758
24.7k
            if (ctxt->instate == XML_PARSER_EOF)
8759
350
                return(NULL);
8760
24.4k
            xmlNsErr(ctxt, XML_NS_ERR_QNAME,
8761
24.4k
               "Failed to parse QName '%s:'\n", p, NULL, NULL);
8762
24.4k
      l = xmlParseNmtoken(ctxt);
8763
24.4k
      if (l == NULL) {
8764
16.2k
                if (ctxt->instate == XML_PARSER_EOF)
8765
954
                    return(NULL);
8766
15.2k
    tmp = xmlBuildQName(BAD_CAST "", p, NULL, 0);
8767
15.2k
            } else {
8768
8.20k
    tmp = xmlBuildQName(l, p, NULL, 0);
8769
8.20k
    xmlFree((char *)l);
8770
8.20k
      }
8771
23.4k
      p = xmlDictLookup(ctxt->dict, tmp, -1);
8772
23.4k
      if (tmp != NULL) xmlFree(tmp);
8773
23.4k
      *prefix = NULL;
8774
23.4k
      return(p);
8775
24.4k
  }
8776
2.23M
  if (CUR == ':') {
8777
18.1k
      xmlChar *tmp;
8778
8779
18.1k
            xmlNsErr(ctxt, XML_NS_ERR_QNAME,
8780
18.1k
               "Failed to parse QName '%s:%s:'\n", p, l, NULL);
8781
18.1k
      NEXT;
8782
18.1k
      tmp = (xmlChar *) xmlParseName(ctxt);
8783
18.1k
      if (tmp != NULL) {
8784
14.4k
          tmp = xmlBuildQName(tmp, l, NULL, 0);
8785
14.4k
    l = xmlDictLookup(ctxt->dict, tmp, -1);
8786
14.4k
    if (tmp != NULL) xmlFree(tmp);
8787
14.4k
    *prefix = p;
8788
14.4k
    return(l);
8789
14.4k
      }
8790
3.66k
            if (ctxt->instate == XML_PARSER_EOF)
8791
209
                return(NULL);
8792
3.45k
      tmp = xmlBuildQName(BAD_CAST "", l, NULL, 0);
8793
3.45k
      l = xmlDictLookup(ctxt->dict, tmp, -1);
8794
3.45k
      if (tmp != NULL) xmlFree(tmp);
8795
3.45k
      *prefix = p;
8796
3.45k
      return(l);
8797
3.66k
  }
8798
2.21M
  *prefix = p;
8799
2.21M
    } else
8800
2.89M
        *prefix = NULL;
8801
5.10M
    return(l);
8802
5.14M
}
8803
8804
/**
8805
 * xmlParseQNameAndCompare:
8806
 * @ctxt:  an XML parser context
8807
 * @name:  the localname
8808
 * @prefix:  the prefix, if any.
8809
 *
8810
 * parse an XML name and compares for match
8811
 * (specialized for endtag parsing)
8812
 *
8813
 * Returns NULL for an illegal name, (xmlChar*) 1 for success
8814
 * and the name for mismatch
8815
 */
8816
8817
static const xmlChar *
8818
xmlParseQNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *name,
8819
350k
                        xmlChar const *prefix) {
8820
350k
    const xmlChar *cmp;
8821
350k
    const xmlChar *in;
8822
350k
    const xmlChar *ret;
8823
350k
    const xmlChar *prefix2;
8824
8825
350k
    if (prefix == NULL) return(xmlParseNameAndCompare(ctxt, name));
8826
8827
350k
    GROW;
8828
350k
    in = ctxt->input->cur;
8829
8830
350k
    cmp = prefix;
8831
1.12M
    while (*in != 0 && *in == *cmp) {
8832
771k
  ++in;
8833
771k
  ++cmp;
8834
771k
    }
8835
350k
    if ((*cmp == 0) && (*in == ':')) {
8836
343k
        in++;
8837
343k
  cmp = name;
8838
3.10M
  while (*in != 0 && *in == *cmp) {
8839
2.75M
      ++in;
8840
2.75M
      ++cmp;
8841
2.75M
  }
8842
343k
  if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) {
8843
      /* success */
8844
338k
            ctxt->input->col += in - ctxt->input->cur;
8845
338k
      ctxt->input->cur = in;
8846
338k
      return((const xmlChar*) 1);
8847
338k
  }
8848
343k
    }
8849
    /*
8850
     * all strings coms from the dictionary, equality can be done directly
8851
     */
8852
11.8k
    ret = xmlParseQName (ctxt, &prefix2);
8853
11.8k
    if ((ret == name) && (prefix == prefix2))
8854
626
  return((const xmlChar*) 1);
8855
11.2k
    return ret;
8856
11.8k
}
8857
8858
/**
8859
 * xmlParseAttValueInternal:
8860
 * @ctxt:  an XML parser context
8861
 * @len:  attribute len result
8862
 * @alloc:  whether the attribute was reallocated as a new string
8863
 * @normalize:  if 1 then further non-CDATA normalization must be done
8864
 *
8865
 * parse a value for an attribute.
8866
 * NOTE: if no normalization is needed, the routine will return pointers
8867
 *       directly from the data buffer.
8868
 *
8869
 * 3.3.3 Attribute-Value Normalization:
8870
 * Before the value of an attribute is passed to the application or
8871
 * checked for validity, the XML processor must normalize it as follows:
8872
 * - a character reference is processed by appending the referenced
8873
 *   character to the attribute value
8874
 * - an entity reference is processed by recursively processing the
8875
 *   replacement text of the entity
8876
 * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
8877
 *   appending #x20 to the normalized value, except that only a single
8878
 *   #x20 is appended for a "#xD#xA" sequence that is part of an external
8879
 *   parsed entity or the literal entity value of an internal parsed entity
8880
 * - other characters are processed by appending them to the normalized value
8881
 * If the declared value is not CDATA, then the XML processor must further
8882
 * process the normalized attribute value by discarding any leading and
8883
 * trailing space (#x20) characters, and by replacing sequences of space
8884
 * (#x20) characters by a single space (#x20) character.
8885
 * All attributes for which no declaration has been read should be treated
8886
 * by a non-validating parser as if declared CDATA.
8887
 *
8888
 * Returns the AttValue parsed or NULL. The value has to be freed by the
8889
 *     caller if it was copied, this can be detected by val[*len] == 0.
8890
 */
8891
8892
#define GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end) \
8893
1.81k
    const xmlChar *oldbase = ctxt->input->base;\
8894
1.81k
    GROW;\
8895
1.81k
    if (ctxt->instate == XML_PARSER_EOF)\
8896
1.81k
        return(NULL);\
8897
1.81k
    if (oldbase != ctxt->input->base) {\
8898
0
        ptrdiff_t delta = ctxt->input->base - oldbase;\
8899
0
        start = start + delta;\
8900
0
        in = in + delta;\
8901
0
    }\
8902
1.81k
    end = ctxt->input->end;
8903
8904
static xmlChar *
8905
xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
8906
                         int normalize)
8907
3.15M
{
8908
3.15M
    xmlChar limit = 0;
8909
3.15M
    const xmlChar *in = NULL, *start, *end, *last;
8910
3.15M
    xmlChar *ret = NULL;
8911
3.15M
    int line, col;
8912
3.15M
    int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
8913
0
                    XML_MAX_HUGE_LENGTH :
8914
3.15M
                    XML_MAX_TEXT_LENGTH;
8915
8916
3.15M
    GROW;
8917
3.15M
    in = (xmlChar *) CUR_PTR;
8918
3.15M
    line = ctxt->input->line;
8919
3.15M
    col = ctxt->input->col;
8920
3.15M
    if (*in != '"' && *in != '\'') {
8921
20.0k
        xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
8922
20.0k
        return (NULL);
8923
20.0k
    }
8924
3.13M
    ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
8925
8926
    /*
8927
     * try to handle in this routine the most common case where no
8928
     * allocation of a new string is required and where content is
8929
     * pure ASCII.
8930
     */
8931
3.13M
    limit = *in++;
8932
3.13M
    col++;
8933
3.13M
    end = ctxt->input->end;
8934
3.13M
    start = in;
8935
3.13M
    if (in >= end) {
8936
763
        GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end)
8937
763
    }
8938
3.13M
    if (normalize) {
8939
        /*
8940
   * Skip any leading spaces
8941
   */
8942
17.3k
  while ((in < end) && (*in != limit) &&
8943
17.3k
         ((*in == 0x20) || (*in == 0x9) ||
8944
16.8k
          (*in == 0xA) || (*in == 0xD))) {
8945
2.90k
      if (*in == 0xA) {
8946
988
          line++; col = 1;
8947
1.92k
      } else {
8948
1.92k
          col++;
8949
1.92k
      }
8950
2.90k
      in++;
8951
2.90k
      start = in;
8952
2.90k
      if (in >= end) {
8953
12
                GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end)
8954
12
                if ((in - start) > maxLength) {
8955
0
                    xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
8956
0
                                   "AttValue length too long\n");
8957
0
                    return(NULL);
8958
0
                }
8959
12
      }
8960
2.90k
  }
8961
304k
  while ((in < end) && (*in != limit) && (*in >= 0x20) &&
8962
304k
         (*in <= 0x7f) && (*in != '&') && (*in != '<')) {
8963
292k
      col++;
8964
292k
      if ((*in++ == 0x20) && (*in == 0x20)) break;
8965
290k
      if (in >= end) {
8966
205
                GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end)
8967
205
                if ((in - start) > maxLength) {
8968
0
                    xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
8969
0
                                   "AttValue length too long\n");
8970
0
                    return(NULL);
8971
0
                }
8972
205
      }
8973
290k
  }
8974
14.4k
  last = in;
8975
  /*
8976
   * skip the trailing blanks
8977
   */
8978
17.6k
  while ((last[-1] == 0x20) && (last > start)) last--;
8979
19.3k
  while ((in < end) && (*in != limit) &&
8980
19.3k
         ((*in == 0x20) || (*in == 0x9) ||
8981
16.8k
          (*in == 0xA) || (*in == 0xD))) {
8982
4.90k
      if (*in == 0xA) {
8983
991
          line++, col = 1;
8984
3.91k
      } else {
8985
3.91k
          col++;
8986
3.91k
      }
8987
4.90k
      in++;
8988
4.90k
      if (in >= end) {
8989
285
    const xmlChar *oldbase = ctxt->input->base;
8990
285
    GROW;
8991
285
                if (ctxt->instate == XML_PARSER_EOF)
8992
0
                    return(NULL);
8993
285
    if (oldbase != ctxt->input->base) {
8994
0
        ptrdiff_t delta = ctxt->input->base - oldbase;
8995
0
        start = start + delta;
8996
0
        in = in + delta;
8997
0
        last = last + delta;
8998
0
    }
8999
285
    end = ctxt->input->end;
9000
285
                if ((in - start) > maxLength) {
9001
0
                    xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
9002
0
                                   "AttValue length too long\n");
9003
0
                    return(NULL);
9004
0
                }
9005
285
      }
9006
4.90k
  }
9007
14.4k
        if ((in - start) > maxLength) {
9008
0
            xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
9009
0
                           "AttValue length too long\n");
9010
0
            return(NULL);
9011
0
        }
9012
14.4k
  if (*in != limit) goto need_complex;
9013
3.12M
    } else {
9014
38.3M
  while ((in < end) && (*in != limit) && (*in >= 0x20) &&
9015
38.3M
         (*in <= 0x7f) && (*in != '&') && (*in != '<')) {
9016
35.2M
      in++;
9017
35.2M
      col++;
9018
35.2M
      if (in >= end) {
9019
836
                GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end)
9020
836
                if ((in - start) > maxLength) {
9021
0
                    xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
9022
0
                                   "AttValue length too long\n");
9023
0
                    return(NULL);
9024
0
                }
9025
836
      }
9026
35.2M
  }
9027
3.12M
  last = in;
9028
3.12M
        if ((in - start) > maxLength) {
9029
0
            xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
9030
0
                           "AttValue length too long\n");
9031
0
            return(NULL);
9032
0
        }
9033
3.12M
  if (*in != limit) goto need_complex;
9034
3.12M
    }
9035
2.74M
    in++;
9036
2.74M
    col++;
9037
2.74M
    if (len != NULL) {
9038
2.55M
        if (alloc) *alloc = 0;
9039
2.55M
        *len = last - start;
9040
2.55M
        ret = (xmlChar *) start;
9041
2.55M
    } else {
9042
190k
        if (alloc) *alloc = 1;
9043
190k
        ret = xmlStrndup(start, last - start);
9044
190k
    }
9045
2.74M
    CUR_PTR = in;
9046
2.74M
    ctxt->input->line = line;
9047
2.74M
    ctxt->input->col = col;
9048
2.74M
    return ret;
9049
389k
need_complex:
9050
389k
    if (alloc) *alloc = 1;
9051
389k
    return xmlParseAttValueComplex(ctxt, len, normalize);
9052
3.13M
}
9053
9054
/**
9055
 * xmlParseAttribute2:
9056
 * @ctxt:  an XML parser context
9057
 * @pref:  the element prefix
9058
 * @elem:  the element name
9059
 * @prefix:  a xmlChar ** used to store the value of the attribute prefix
9060
 * @value:  a xmlChar ** used to store the value of the attribute
9061
 * @len:  an int * to save the length of the attribute
9062
 * @alloc:  an int * to indicate if the attribute was allocated
9063
 *
9064
 * parse an attribute in the new SAX2 framework.
9065
 *
9066
 * Returns the attribute name, and the value in *value, .
9067
 */
9068
9069
static const xmlChar *
9070
xmlParseAttribute2(xmlParserCtxtPtr ctxt,
9071
                   const xmlChar * pref, const xmlChar * elem,
9072
                   const xmlChar ** prefix, xmlChar ** value,
9073
                   int *len, int *alloc)
9074
3.06M
{
9075
3.06M
    const xmlChar *name;
9076
3.06M
    xmlChar *val, *internal_val = NULL;
9077
3.06M
    int normalize = 0;
9078
9079
3.06M
    *value = NULL;
9080
3.06M
    GROW;
9081
3.06M
    name = xmlParseQName(ctxt, prefix);
9082
3.06M
    if (name == NULL) {
9083
77.9k
        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
9084
77.9k
                       "error parsing attribute name\n");
9085
77.9k
        return (NULL);
9086
77.9k
    }
9087
9088
    /*
9089
     * get the type if needed
9090
     */
9091
2.98M
    if (ctxt->attsSpecial != NULL) {
9092
40.6k
        int type;
9093
9094
40.6k
        type = (int) (ptrdiff_t) xmlHashQLookup2(ctxt->attsSpecial,
9095
40.6k
                                                 pref, elem, *prefix, name);
9096
40.6k
        if (type != 0)
9097
16.3k
            normalize = 1;
9098
40.6k
    }
9099
9100
    /*
9101
     * read the value
9102
     */
9103
2.98M
    SKIP_BLANKS;
9104
2.98M
    if (RAW == '=') {
9105
2.93M
        NEXT;
9106
2.93M
        SKIP_BLANKS;
9107
2.93M
        val = xmlParseAttValueInternal(ctxt, len, alloc, normalize);
9108
2.93M
        if (val == NULL)
9109
9.78k
            return (NULL);
9110
2.92M
  if (normalize) {
9111
      /*
9112
       * Sometimes a second normalisation pass for spaces is needed
9113
       * but that only happens if charrefs or entities references
9114
       * have been used in the attribute value, i.e. the attribute
9115
       * value have been extracted in an allocated string already.
9116
       */
9117
14.4k
      if (*alloc) {
9118
12.5k
          const xmlChar *val2;
9119
9120
12.5k
          val2 = xmlAttrNormalizeSpace2(ctxt, val, len);
9121
12.5k
    if ((val2 != NULL) && (val2 != val)) {
9122
1.07k
        xmlFree(val);
9123
1.07k
        val = (xmlChar *) val2;
9124
1.07k
    }
9125
12.5k
      }
9126
14.4k
  }
9127
2.92M
        ctxt->instate = XML_PARSER_CONTENT;
9128
2.92M
    } else {
9129
47.7k
        xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
9130
47.7k
                          "Specification mandates value for attribute %s\n",
9131
47.7k
                          name);
9132
47.7k
        return (name);
9133
47.7k
    }
9134
9135
2.92M
    if (*prefix == ctxt->str_xml) {
9136
        /*
9137
         * Check that xml:lang conforms to the specification
9138
         * No more registered as an error, just generate a warning now
9139
         * since this was deprecated in XML second edition
9140
         */
9141
352k
        if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "lang"))) {
9142
0
            internal_val = xmlStrndup(val, *len);
9143
0
            if (!xmlCheckLanguageID(internal_val)) {
9144
0
                xmlWarningMsg(ctxt, XML_WAR_LANG_VALUE,
9145
0
                              "Malformed value for xml:lang : %s\n",
9146
0
                              internal_val, NULL);
9147
0
            }
9148
0
        }
9149
9150
        /*
9151
         * Check that xml:space conforms to the specification
9152
         */
9153
352k
        if (xmlStrEqual(name, BAD_CAST "space")) {
9154
1.03k
            internal_val = xmlStrndup(val, *len);
9155
1.03k
            if (xmlStrEqual(internal_val, BAD_CAST "default"))
9156
151
                *(ctxt->space) = 0;
9157
883
            else if (xmlStrEqual(internal_val, BAD_CAST "preserve"))
9158
200
                *(ctxt->space) = 1;
9159
683
            else {
9160
683
                xmlWarningMsg(ctxt, XML_WAR_SPACE_VALUE,
9161
683
                              "Invalid value \"%s\" for xml:space : \"default\" or \"preserve\" expected\n",
9162
683
                              internal_val, NULL);
9163
683
            }
9164
1.03k
        }
9165
352k
        if (internal_val) {
9166
1.03k
            xmlFree(internal_val);
9167
1.03k
        }
9168
352k
    }
9169
9170
2.92M
    *value = val;
9171
2.92M
    return (name);
9172
2.98M
}
9173
/**
9174
 * xmlParseStartTag2:
9175
 * @ctxt:  an XML parser context
9176
 *
9177
 * Parse a start tag. Always consumes '<'.
9178
 *
9179
 * This routine is called when running SAX2 parsing
9180
 *
9181
 * [40] STag ::= '<' Name (S Attribute)* S? '>'
9182
 *
9183
 * [ WFC: Unique Att Spec ]
9184
 * No attribute name may appear more than once in the same start-tag or
9185
 * empty-element tag.
9186
 *
9187
 * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
9188
 *
9189
 * [ WFC: Unique Att Spec ]
9190
 * No attribute name may appear more than once in the same start-tag or
9191
 * empty-element tag.
9192
 *
9193
 * With namespace:
9194
 *
9195
 * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
9196
 *
9197
 * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
9198
 *
9199
 * Returns the element name parsed
9200
 */
9201
9202
static const xmlChar *
9203
xmlParseStartTag2(xmlParserCtxtPtr ctxt, const xmlChar **pref,
9204
2.26M
                  const xmlChar **URI, int *tlen) {
9205
2.26M
    const xmlChar *localname;
9206
2.26M
    const xmlChar *prefix;
9207
2.26M
    const xmlChar *attname;
9208
2.26M
    const xmlChar *aprefix;
9209
2.26M
    const xmlChar *nsname;
9210
2.26M
    xmlChar *attvalue;
9211
2.26M
    const xmlChar **atts = ctxt->atts;
9212
2.26M
    int maxatts = ctxt->maxatts;
9213
2.26M
    int nratts, nbatts, nbdef, inputid;
9214
2.26M
    int i, j, nbNs, attval;
9215
2.26M
    size_t cur;
9216
2.26M
    int nsNr = ctxt->nsNr;
9217
9218
2.26M
    if (RAW != '<') return(NULL);
9219
2.26M
    NEXT1;
9220
9221
2.26M
    cur = ctxt->input->cur - ctxt->input->base;
9222
2.26M
    inputid = ctxt->input->id;
9223
2.26M
    nbatts = 0;
9224
2.26M
    nratts = 0;
9225
2.26M
    nbdef = 0;
9226
2.26M
    nbNs = 0;
9227
2.26M
    attval = 0;
9228
    /* Forget any namespaces added during an earlier parse of this element. */
9229
2.26M
    ctxt->nsNr = nsNr;
9230
9231
2.26M
    localname = xmlParseQName(ctxt, &prefix);
9232
2.26M
    if (localname == NULL) {
9233
79.2k
  xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
9234
79.2k
           "StartTag: invalid element name\n");
9235
79.2k
        return(NULL);
9236
79.2k
    }
9237
2.19M
    *tlen = ctxt->input->cur - ctxt->input->base - cur;
9238
9239
    /*
9240
     * Now parse the attributes, it ends up with the ending
9241
     *
9242
     * (S Attribute)* S?
9243
     */
9244
2.19M
    SKIP_BLANKS;
9245
2.19M
    GROW;
9246
9247
3.68M
    while (((RAW != '>') &&
9248
3.68M
     ((RAW != '/') || (NXT(1) != '>')) &&
9249
3.68M
     (IS_BYTE_CHAR(RAW))) && (ctxt->instate != XML_PARSER_EOF)) {
9250
3.06M
  int len = -1, alloc = 0;
9251
9252
3.06M
  attname = xmlParseAttribute2(ctxt, prefix, localname,
9253
3.06M
                               &aprefix, &attvalue, &len, &alloc);
9254
3.06M
        if (attname == NULL) {
9255
87.7k
      xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
9256
87.7k
           "xmlParseStartTag: problem parsing attributes\n");
9257
87.7k
      break;
9258
87.7k
  }
9259
2.97M
        if (attvalue == NULL)
9260
47.7k
            goto next_attr;
9261
2.92M
  if (len < 0) len = xmlStrlen(attvalue);
9262
9263
2.92M
        if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
9264
98.8k
            const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
9265
98.8k
            xmlURIPtr uri;
9266
9267
98.8k
            if (URL == NULL) {
9268
4
                xmlErrMemory(ctxt, "dictionary allocation failure");
9269
4
                if ((attvalue != NULL) && (alloc != 0))
9270
1
                    xmlFree(attvalue);
9271
4
                localname = NULL;
9272
4
                goto done;
9273
4
            }
9274
98.8k
            if (*URL != 0) {
9275
96.9k
                uri = xmlParseURI((const char *) URL);
9276
96.9k
                if (uri == NULL) {
9277
60.8k
                    xmlNsErr(ctxt, XML_WAR_NS_URI,
9278
60.8k
                             "xmlns: '%s' is not a valid URI\n",
9279
60.8k
                                       URL, NULL, NULL);
9280
60.8k
                } else {
9281
36.1k
                    if (uri->scheme == NULL) {
9282
26.2k
                        xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
9283
26.2k
                                  "xmlns: URI %s is not absolute\n",
9284
26.2k
                                  URL, NULL, NULL);
9285
26.2k
                    }
9286
36.1k
                    xmlFreeURI(uri);
9287
36.1k
                }
9288
96.9k
                if (URL == ctxt->str_xml_ns) {
9289
197
                    if (attname != ctxt->str_xml) {
9290
197
                        xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9291
197
                     "xml namespace URI cannot be the default namespace\n",
9292
197
                                 NULL, NULL, NULL);
9293
197
                    }
9294
197
                    goto next_attr;
9295
197
                }
9296
96.7k
                if ((len == 29) &&
9297
96.7k
                    (xmlStrEqual(URL,
9298
1.13k
                             BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
9299
235
                    xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9300
235
                         "reuse of the xmlns namespace name is forbidden\n",
9301
235
                             NULL, NULL, NULL);
9302
235
                    goto next_attr;
9303
235
                }
9304
96.7k
            }
9305
            /*
9306
             * check that it's not a defined namespace
9307
             */
9308
113k
            for (j = 1;j <= nbNs;j++)
9309
17.2k
                if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
9310
2.22k
                    break;
9311
98.4k
            if (j <= nbNs)
9312
2.22k
                xmlErrAttributeDup(ctxt, NULL, attname);
9313
96.1k
            else
9314
96.1k
                if (nsPush(ctxt, NULL, URL) > 0) nbNs++;
9315
9316
2.82M
        } else if (aprefix == ctxt->str_xmlns) {
9317
208k
            const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
9318
208k
            xmlURIPtr uri;
9319
9320
208k
            if (attname == ctxt->str_xml) {
9321
1.87k
                if (URL != ctxt->str_xml_ns) {
9322
1.23k
                    xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9323
1.23k
                             "xml namespace prefix mapped to wrong URI\n",
9324
1.23k
                             NULL, NULL, NULL);
9325
1.23k
                }
9326
                /*
9327
                 * Do not keep a namespace definition node
9328
                 */
9329
1.87k
                goto next_attr;
9330
1.87k
            }
9331
206k
            if (URL == ctxt->str_xml_ns) {
9332
434
                if (attname != ctxt->str_xml) {
9333
434
                    xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9334
434
                             "xml namespace URI mapped to wrong prefix\n",
9335
434
                             NULL, NULL, NULL);
9336
434
                }
9337
434
                goto next_attr;
9338
434
            }
9339
205k
            if (attname == ctxt->str_xmlns) {
9340
563
                xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9341
563
                         "redefinition of the xmlns prefix is forbidden\n",
9342
563
                         NULL, NULL, NULL);
9343
563
                goto next_attr;
9344
563
            }
9345
205k
            if ((len == 29) &&
9346
205k
                (xmlStrEqual(URL,
9347
1.81k
                             BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
9348
705
                xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9349
705
                         "reuse of the xmlns namespace name is forbidden\n",
9350
705
                         NULL, NULL, NULL);
9351
705
                goto next_attr;
9352
705
            }
9353
204k
            if ((URL == NULL) || (URL[0] == 0)) {
9354
548
                xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9355
548
                         "xmlns:%s: Empty XML namespace is not allowed\n",
9356
548
                              attname, NULL, NULL);
9357
548
                goto next_attr;
9358
204k
            } else {
9359
204k
                uri = xmlParseURI((const char *) URL);
9360
204k
                if (uri == NULL) {
9361
16.2k
                    xmlNsErr(ctxt, XML_WAR_NS_URI,
9362
16.2k
                         "xmlns:%s: '%s' is not a valid URI\n",
9363
16.2k
                                       attname, URL, NULL);
9364
187k
                } else {
9365
187k
                    if ((ctxt->pedantic) && (uri->scheme == NULL)) {
9366
0
                        xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
9367
0
                                  "xmlns:%s: URI %s is not absolute\n",
9368
0
                                  attname, URL, NULL);
9369
0
                    }
9370
187k
                    xmlFreeURI(uri);
9371
187k
                }
9372
204k
            }
9373
9374
            /*
9375
             * check that it's not a defined namespace
9376
             */
9377
303k
            for (j = 1;j <= nbNs;j++)
9378
103k
                if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
9379
3.43k
                    break;
9380
204k
            if (j <= nbNs)
9381
3.43k
                xmlErrAttributeDup(ctxt, aprefix, attname);
9382
200k
            else
9383
200k
                if (nsPush(ctxt, attname, URL) > 0) nbNs++;
9384
9385
2.61M
        } else {
9386
            /*
9387
             * Add the pair to atts
9388
             */
9389
2.61M
            if ((atts == NULL) || (nbatts + 5 > maxatts)) {
9390
89.8k
                if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
9391
20
                    goto next_attr;
9392
20
                }
9393
89.8k
                maxatts = ctxt->maxatts;
9394
89.8k
                atts = ctxt->atts;
9395
89.8k
            }
9396
2.61M
            ctxt->attallocs[nratts++] = alloc;
9397
2.61M
            atts[nbatts++] = attname;
9398
2.61M
            atts[nbatts++] = aprefix;
9399
            /*
9400
             * The namespace URI field is used temporarily to point at the
9401
             * base of the current input buffer for non-alloced attributes.
9402
             * When the input buffer is reallocated, all the pointers become
9403
             * invalid, but they can be reconstructed later.
9404
             */
9405
2.61M
            if (alloc)
9406
281k
                atts[nbatts++] = NULL;
9407
2.33M
            else
9408
2.33M
                atts[nbatts++] = ctxt->input->base;
9409
2.61M
            atts[nbatts++] = attvalue;
9410
2.61M
            attvalue += len;
9411
2.61M
            atts[nbatts++] = attvalue;
9412
            /*
9413
             * tag if some deallocation is needed
9414
             */
9415
2.61M
            if (alloc != 0) attval = 1;
9416
2.61M
            attvalue = NULL; /* moved into atts */
9417
2.61M
        }
9418
9419
2.97M
next_attr:
9420
2.97M
        if ((attvalue != NULL) && (alloc != 0)) {
9421
87.0k
            xmlFree(attvalue);
9422
87.0k
            attvalue = NULL;
9423
87.0k
        }
9424
9425
2.97M
  GROW
9426
2.97M
        if (ctxt->instate == XML_PARSER_EOF)
9427
423
            break;
9428
2.97M
  if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
9429
1.34M
      break;
9430
1.63M
  if (SKIP_BLANKS == 0) {
9431
139k
      xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
9432
139k
         "attributes construct error\n");
9433
139k
      break;
9434
139k
  }
9435
1.49M
        GROW;
9436
1.49M
    }
9437
9438
2.19M
    if (ctxt->input->id != inputid) {
9439
0
        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
9440
0
                    "Unexpected change of input\n");
9441
0
        localname = NULL;
9442
0
        goto done;
9443
0
    }
9444
9445
    /* Reconstruct attribute value pointers. */
9446
4.81M
    for (i = 0, j = 0; j < nratts; i += 5, j++) {
9447
2.61M
        if (atts[i+2] != NULL) {
9448
            /*
9449
             * Arithmetic on dangling pointers is technically undefined
9450
             * behavior, but well...
9451
             */
9452
2.33M
            const xmlChar *old = atts[i+2];
9453
2.33M
            atts[i+2]  = NULL;    /* Reset repurposed namespace URI */
9454
2.33M
            atts[i+3] = ctxt->input->base + (atts[i+3] - old);  /* value */
9455
2.33M
            atts[i+4] = ctxt->input->base + (atts[i+4] - old);  /* valuend */
9456
2.33M
        }
9457
2.61M
    }
9458
9459
    /*
9460
     * The attributes defaulting
9461
     */
9462
2.19M
    if (ctxt->attsDefault != NULL) {
9463
76.9k
        xmlDefAttrsPtr defaults;
9464
9465
76.9k
  defaults = xmlHashLookup2(ctxt->attsDefault, localname, prefix);
9466
76.9k
  if (defaults != NULL) {
9467
127k
      for (i = 0;i < defaults->nbAttrs;i++) {
9468
84.7k
          attname = defaults->values[5 * i];
9469
84.7k
    aprefix = defaults->values[5 * i + 1];
9470
9471
                /*
9472
     * special work for namespaces defaulted defs
9473
     */
9474
84.7k
    if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
9475
        /*
9476
         * check that it's not a defined namespace
9477
         */
9478
23.1k
        for (j = 1;j <= nbNs;j++)
9479
10.0k
            if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
9480
8.73k
          break;
9481
21.7k
              if (j <= nbNs) continue;
9482
9483
13.0k
        nsname = xmlGetNamespace(ctxt, NULL);
9484
13.0k
        if (nsname != defaults->values[5 * i + 2]) {
9485
12.3k
      if (nsPush(ctxt, NULL,
9486
12.3k
                 defaults->values[5 * i + 2]) > 0)
9487
12.3k
          nbNs++;
9488
12.3k
        }
9489
62.9k
    } else if (aprefix == ctxt->str_xmlns) {
9490
        /*
9491
         * check that it's not a defined namespace
9492
         */
9493
10.8k
        for (j = 1;j <= nbNs;j++)
9494
5.22k
            if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
9495
839
          break;
9496
6.47k
              if (j <= nbNs) continue;
9497
9498
5.63k
        nsname = xmlGetNamespace(ctxt, attname);
9499
5.63k
        if (nsname != defaults->values[5 * i + 2]) {
9500
4.96k
      if (nsPush(ctxt, attname,
9501
4.96k
                 defaults->values[5 * i + 2]) > 0)
9502
4.96k
          nbNs++;
9503
4.96k
        }
9504
56.4k
    } else {
9505
        /*
9506
         * check that it's not a defined attribute
9507
         */
9508
162k
        for (j = 0;j < nbatts;j+=5) {
9509
110k
      if ((attname == atts[j]) && (aprefix == atts[j+1]))
9510
4.31k
          break;
9511
110k
        }
9512
56.4k
        if (j < nbatts) continue;
9513
9514
52.1k
        if ((atts == NULL) || (nbatts + 5 > maxatts)) {
9515
4.50k
      if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
9516
3
                            localname = NULL;
9517
3
                            goto done;
9518
3
      }
9519
4.50k
      maxatts = ctxt->maxatts;
9520
4.50k
      atts = ctxt->atts;
9521
4.50k
        }
9522
52.1k
        atts[nbatts++] = attname;
9523
52.1k
        atts[nbatts++] = aprefix;
9524
52.1k
        if (aprefix == NULL)
9525
18.8k
      atts[nbatts++] = NULL;
9526
33.2k
        else
9527
33.2k
            atts[nbatts++] = xmlGetNamespace(ctxt, aprefix);
9528
52.1k
        atts[nbatts++] = defaults->values[5 * i + 2];
9529
52.1k
        atts[nbatts++] = defaults->values[5 * i + 3];
9530
52.1k
        if ((ctxt->standalone == 1) &&
9531
52.1k
            (defaults->values[5 * i + 4] != NULL)) {
9532
0
      xmlValidityError(ctxt, XML_DTD_STANDALONE_DEFAULTED,
9533
0
    "standalone: attribute %s on %s defaulted from external subset\n",
9534
0
                                   attname, localname);
9535
0
        }
9536
52.1k
        nbdef++;
9537
52.1k
    }
9538
84.7k
      }
9539
42.6k
  }
9540
76.9k
    }
9541
9542
    /*
9543
     * The attributes checkings
9544
     */
9545
4.86M
    for (i = 0; i < nbatts;i += 5) {
9546
        /*
9547
  * The default namespace does not apply to attribute names.
9548
  */
9549
2.67M
  if (atts[i + 1] != NULL) {
9550
572k
      nsname = xmlGetNamespace(ctxt, atts[i + 1]);
9551
572k
      if (nsname == NULL) {
9552
210k
    xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
9553
210k
        "Namespace prefix %s for %s on %s is not defined\n",
9554
210k
        atts[i + 1], atts[i], localname);
9555
210k
      }
9556
572k
      atts[i + 2] = nsname;
9557
572k
  } else
9558
2.10M
      nsname = NULL;
9559
  /*
9560
   * [ WFC: Unique Att Spec ]
9561
   * No attribute name may appear more than once in the same
9562
   * start-tag or empty-element tag.
9563
   * As extended by the Namespace in XML REC.
9564
   */
9565
4.68M
        for (j = 0; j < i;j += 5) {
9566
2.01M
      if (atts[i] == atts[j]) {
9567
86.9k
          if (atts[i+1] == atts[j+1]) {
9568
4.63k
        xmlErrAttributeDup(ctxt, atts[i+1], atts[i]);
9569
4.63k
        break;
9570
4.63k
    }
9571
82.3k
    if ((nsname != NULL) && (atts[j + 2] == nsname)) {
9572
631
        xmlNsErr(ctxt, XML_NS_ERR_ATTRIBUTE_REDEFINED,
9573
631
           "Namespaced Attribute %s in '%s' redefined\n",
9574
631
           atts[i], nsname, NULL);
9575
631
        break;
9576
631
    }
9577
82.3k
      }
9578
2.01M
  }
9579
2.67M
    }
9580
9581
2.19M
    nsname = xmlGetNamespace(ctxt, prefix);
9582
2.19M
    if ((prefix != NULL) && (nsname == NULL)) {
9583
192k
  xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
9584
192k
           "Namespace prefix %s on %s is not defined\n",
9585
192k
     prefix, localname, NULL);
9586
192k
    }
9587
2.19M
    *pref = prefix;
9588
2.19M
    *URI = nsname;
9589
9590
    /*
9591
     * SAX: Start of Element !
9592
     */
9593
2.19M
    if ((ctxt->sax != NULL) && (ctxt->sax->startElementNs != NULL) &&
9594
2.19M
  (!ctxt->disableSAX)) {
9595
1.70M
  if (nbNs > 0)
9596
102k
      ctxt->sax->startElementNs(ctxt->userData, localname, prefix,
9597
102k
        nsname, nbNs, &ctxt->nsTab[ctxt->nsNr - 2 * nbNs],
9598
102k
        nbatts / 5, nbdef, atts);
9599
1.60M
  else
9600
1.60M
      ctxt->sax->startElementNs(ctxt->userData, localname, prefix,
9601
1.60M
                    nsname, 0, NULL, nbatts / 5, nbdef, atts);
9602
1.70M
    }
9603
9604
2.19M
done:
9605
    /*
9606
     * Free up attribute allocated strings if needed
9607
     */
9608
2.19M
    if (attval != 0) {
9609
786k
  for (i = 3,j = 0; j < nratts;i += 5,j++)
9610
516k
      if ((ctxt->attallocs[j] != 0) && (atts[i] != NULL))
9611
281k
          xmlFree((xmlChar *) atts[i]);
9612
269k
    }
9613
9614
2.19M
    return(localname);
9615
2.19M
}
9616
9617
/**
9618
 * xmlParseEndTag2:
9619
 * @ctxt:  an XML parser context
9620
 * @line:  line of the start tag
9621
 * @nsNr:  number of namespaces on the start tag
9622
 *
9623
 * Parse an end tag. Always consumes '</'.
9624
 *
9625
 * [42] ETag ::= '</' Name S? '>'
9626
 *
9627
 * With namespace
9628
 *
9629
 * [NS 9] ETag ::= '</' QName S? '>'
9630
 */
9631
9632
static void
9633
550k
xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlStartTag *tag) {
9634
550k
    const xmlChar *name;
9635
9636
550k
    GROW;
9637
550k
    if ((RAW != '<') || (NXT(1) != '/')) {
9638
0
  xmlFatalErr(ctxt, XML_ERR_LTSLASH_REQUIRED, NULL);
9639
0
  return;
9640
0
    }
9641
550k
    SKIP(2);
9642
9643
550k
    if (tag->prefix == NULL)
9644
200k
        name = xmlParseNameAndCompare(ctxt, ctxt->name);
9645
350k
    else
9646
350k
        name = xmlParseQNameAndCompare(ctxt, ctxt->name, tag->prefix);
9647
9648
    /*
9649
     * We should definitely be at the ending "S? '>'" part
9650
     */
9651
550k
    GROW;
9652
550k
    if (ctxt->instate == XML_PARSER_EOF)
9653
314
        return;
9654
550k
    SKIP_BLANKS;
9655
550k
    if ((!IS_BYTE_CHAR(RAW)) || (RAW != '>')) {
9656
10.6k
  xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
9657
10.6k
    } else
9658
539k
  NEXT1;
9659
9660
    /*
9661
     * [ WFC: Element Type Match ]
9662
     * The Name in an element's end-tag must match the element type in the
9663
     * start-tag.
9664
     *
9665
     */
9666
550k
    if (name != (xmlChar*)1) {
9667
18.4k
        if (name == NULL) name = BAD_CAST "unparsable";
9668
18.4k
        xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
9669
18.4k
         "Opening and ending tag mismatch: %s line %d and %s\n",
9670
18.4k
                    ctxt->name, tag->line, name);
9671
18.4k
    }
9672
9673
    /*
9674
     * SAX: End of Tag
9675
     */
9676
550k
    if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
9677
550k
  (!ctxt->disableSAX))
9678
484k
  ctxt->sax->endElementNs(ctxt->userData, ctxt->name, tag->prefix,
9679
484k
                                tag->URI);
9680
9681
550k
    spacePop(ctxt);
9682
550k
    if (tag->nsNr != 0)
9683
67.2k
  nsPop(ctxt, tag->nsNr);
9684
550k
}
9685
9686
/**
9687
 * xmlParseCDSect:
9688
 * @ctxt:  an XML parser context
9689
 *
9690
 * DEPRECATED: Internal function, don't use.
9691
 *
9692
 * Parse escaped pure raw content. Always consumes '<!['.
9693
 *
9694
 * [18] CDSect ::= CDStart CData CDEnd
9695
 *
9696
 * [19] CDStart ::= '<![CDATA['
9697
 *
9698
 * [20] Data ::= (Char* - (Char* ']]>' Char*))
9699
 *
9700
 * [21] CDEnd ::= ']]>'
9701
 */
9702
void
9703
17.0k
xmlParseCDSect(xmlParserCtxtPtr ctxt) {
9704
17.0k
    xmlChar *buf = NULL;
9705
17.0k
    int len = 0;
9706
17.0k
    int size = XML_PARSER_BUFFER_SIZE;
9707
17.0k
    int r, rl;
9708
17.0k
    int s, sl;
9709
17.0k
    int cur, l;
9710
17.0k
    int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
9711
0
                    XML_MAX_HUGE_LENGTH :
9712
17.0k
                    XML_MAX_TEXT_LENGTH;
9713
9714
17.0k
    if ((CUR != '<') || (NXT(1) != '!') || (NXT(2) != '['))
9715
0
        return;
9716
17.0k
    SKIP(3);
9717
9718
17.0k
    if (!CMP6(CUR_PTR, 'C', 'D', 'A', 'T', 'A', '['))
9719
0
        return;
9720
17.0k
    SKIP(6);
9721
9722
17.0k
    ctxt->instate = XML_PARSER_CDATA_SECTION;
9723
17.0k
    r = CUR_CHAR(rl);
9724
17.0k
    if (!IS_CHAR(r)) {
9725
2.61k
  xmlFatalErr(ctxt, XML_ERR_CDATA_NOT_FINISHED, NULL);
9726
2.61k
        goto out;
9727
2.61k
    }
9728
14.4k
    NEXTL(rl);
9729
14.4k
    s = CUR_CHAR(sl);
9730
14.4k
    if (!IS_CHAR(s)) {
9731
1.22k
  xmlFatalErr(ctxt, XML_ERR_CDATA_NOT_FINISHED, NULL);
9732
1.22k
        goto out;
9733
1.22k
    }
9734
13.2k
    NEXTL(sl);
9735
13.2k
    cur = CUR_CHAR(l);
9736
13.2k
    buf = (xmlChar *) xmlMallocAtomic(size);
9737
13.2k
    if (buf == NULL) {
9738
7
  xmlErrMemory(ctxt, NULL);
9739
7
        goto out;
9740
7
    }
9741
20.1M
    while (IS_CHAR(cur) &&
9742
20.1M
           ((r != ']') || (s != ']') || (cur != '>'))) {
9743
20.1M
  if (len + 5 >= size) {
9744
2.93k
      xmlChar *tmp;
9745
9746
2.93k
      tmp = (xmlChar *) xmlRealloc(buf, size * 2);
9747
2.93k
      if (tmp == NULL) {
9748
1
    xmlErrMemory(ctxt, NULL);
9749
1
                goto out;
9750
1
      }
9751
2.93k
      buf = tmp;
9752
2.93k
      size *= 2;
9753
2.93k
  }
9754
20.1M
  COPY_BUF(rl,buf,len,r);
9755
20.1M
        if (len > maxLength) {
9756
1
            xmlFatalErrMsg(ctxt, XML_ERR_CDATA_NOT_FINISHED,
9757
1
                           "CData section too big found\n");
9758
1
            goto out;
9759
1
        }
9760
20.1M
  r = s;
9761
20.1M
  rl = sl;
9762
20.1M
  s = cur;
9763
20.1M
  sl = l;
9764
20.1M
  NEXTL(l);
9765
20.1M
  cur = CUR_CHAR(l);
9766
20.1M
    }
9767
13.2k
    buf[len] = 0;
9768
13.2k
    if (ctxt->instate == XML_PARSER_EOF) {
9769
239
        xmlFree(buf);
9770
239
        return;
9771
239
    }
9772
12.9k
    if (cur != '>') {
9773
3.87k
  xmlFatalErrMsgStr(ctxt, XML_ERR_CDATA_NOT_FINISHED,
9774
3.87k
                       "CData section not finished\n%.50s\n", buf);
9775
3.87k
        goto out;
9776
3.87k
    }
9777
9.12k
    NEXTL(l);
9778
9779
    /*
9780
     * OK the buffer is to be consumed as cdata.
9781
     */
9782
9.12k
    if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
9783
7.58k
  if (ctxt->sax->cdataBlock != NULL)
9784
14
      ctxt->sax->cdataBlock(ctxt->userData, buf, len);
9785
7.57k
  else if (ctxt->sax->characters != NULL)
9786
7.57k
      ctxt->sax->characters(ctxt->userData, buf, len);
9787
7.58k
    }
9788
9789
16.8k
out:
9790
16.8k
    if (ctxt->instate != XML_PARSER_EOF)
9791
16.5k
        ctxt->instate = XML_PARSER_CONTENT;
9792
16.8k
    xmlFree(buf);
9793
16.8k
}
9794
9795
/**
9796
 * xmlParseContentInternal:
9797
 * @ctxt:  an XML parser context
9798
 *
9799
 * Parse a content sequence. Stops at EOF or '</'. Leaves checking of
9800
 * unexpected EOF to the caller.
9801
 */
9802
9803
static void
9804
114k
xmlParseContentInternal(xmlParserCtxtPtr ctxt) {
9805
114k
    int nameNr = ctxt->nameNr;
9806
9807
114k
    GROW;
9808
5.73M
    while ((RAW != 0) &&
9809
5.73M
     (ctxt->instate != XML_PARSER_EOF)) {
9810
5.69M
  const xmlChar *cur = ctxt->input->cur;
9811
9812
  /*
9813
   * First case : a Processing Instruction.
9814
   */
9815
5.69M
  if ((*cur == '<') && (cur[1] == '?')) {
9816
76.2k
      xmlParsePI(ctxt);
9817
76.2k
  }
9818
9819
  /*
9820
   * Second case : a CDSection
9821
   */
9822
  /* 2.6.0 test was *cur not RAW */
9823
5.61M
  else if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) {
9824
17.0k
      xmlParseCDSect(ctxt);
9825
17.0k
  }
9826
9827
  /*
9828
   * Third case :  a comment
9829
   */
9830
5.60M
  else if ((*cur == '<') && (NXT(1) == '!') &&
9831
5.60M
     (NXT(2) == '-') && (NXT(3) == '-')) {
9832
74.7k
      xmlParseComment(ctxt);
9833
74.7k
      ctxt->instate = XML_PARSER_CONTENT;
9834
74.7k
  }
9835
9836
  /*
9837
   * Fourth case :  a sub-element.
9838
   */
9839
5.52M
  else if (*cur == '<') {
9840
2.69M
            if (NXT(1) == '/') {
9841
551k
                if (ctxt->nameNr <= nameNr)
9842
80.2k
                    break;
9843
470k
          xmlParseElementEnd(ctxt);
9844
2.14M
            } else {
9845
2.14M
          xmlParseElementStart(ctxt);
9846
2.14M
            }
9847
2.69M
  }
9848
9849
  /*
9850
   * Fifth case : a reference. If if has not been resolved,
9851
   *    parsing returns it's Name, create the node
9852
   */
9853
9854
2.83M
  else if (*cur == '&') {
9855
171k
      xmlParseReference(ctxt);
9856
171k
  }
9857
9858
  /*
9859
   * Last case, text. Note that References are handled directly.
9860
   */
9861
2.66M
  else {
9862
2.66M
      xmlParseCharData(ctxt, 0);
9863
2.66M
  }
9864
9865
5.61M
  SHRINK;
9866
5.61M
  GROW;
9867
5.61M
    }
9868
114k
}
9869
9870
/**
9871
 * xmlParseContent:
9872
 * @ctxt:  an XML parser context
9873
 *
9874
 * Parse a content sequence. Stops at EOF or '</'.
9875
 *
9876
 * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
9877
 */
9878
9879
void
9880
7.28k
xmlParseContent(xmlParserCtxtPtr ctxt) {
9881
7.28k
    int nameNr = ctxt->nameNr;
9882
9883
7.28k
    xmlParseContentInternal(ctxt);
9884
9885
7.28k
    if ((ctxt->instate != XML_PARSER_EOF) && (ctxt->nameNr > nameNr)) {
9886
1.79k
        const xmlChar *name = ctxt->nameTab[ctxt->nameNr - 1];
9887
1.79k
        int line = ctxt->pushTab[ctxt->nameNr - 1].line;
9888
1.79k
        xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
9889
1.79k
                "Premature end of data in tag %s line %d\n",
9890
1.79k
    name, line, NULL);
9891
1.79k
    }
9892
7.28k
}
9893
9894
/**
9895
 * xmlParseElement:
9896
 * @ctxt:  an XML parser context
9897
 *
9898
 * DEPRECATED: Internal function, don't use.
9899
 *
9900
 * parse an XML element
9901
 *
9902
 * [39] element ::= EmptyElemTag | STag content ETag
9903
 *
9904
 * [ WFC: Element Type Match ]
9905
 * The Name in an element's end-tag must match the element type in the
9906
 * start-tag.
9907
 *
9908
 */
9909
9910
void
9911
128k
xmlParseElement(xmlParserCtxtPtr ctxt) {
9912
128k
    if (xmlParseElementStart(ctxt) != 0)
9913
20.7k
        return;
9914
9915
107k
    xmlParseContentInternal(ctxt);
9916
107k
    if (ctxt->instate == XML_PARSER_EOF)
9917
6.64k
  return;
9918
9919
100k
    if (CUR == 0) {
9920
21.1k
        const xmlChar *name = ctxt->nameTab[ctxt->nameNr - 1];
9921
21.1k
        int line = ctxt->pushTab[ctxt->nameNr - 1].line;
9922
21.1k
        xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
9923
21.1k
                "Premature end of data in tag %s line %d\n",
9924
21.1k
    name, line, NULL);
9925
21.1k
        return;
9926
21.1k
    }
9927
9928
79.7k
    xmlParseElementEnd(ctxt);
9929
79.7k
}
9930
9931
/**
9932
 * xmlParseElementStart:
9933
 * @ctxt:  an XML parser context
9934
 *
9935
 * Parse the start of an XML element. Returns -1 in case of error, 0 if an
9936
 * opening tag was parsed, 1 if an empty element was parsed.
9937
 *
9938
 * Always consumes '<'.
9939
 */
9940
static int
9941
2.26M
xmlParseElementStart(xmlParserCtxtPtr ctxt) {
9942
2.26M
    const xmlChar *name;
9943
2.26M
    const xmlChar *prefix = NULL;
9944
2.26M
    const xmlChar *URI = NULL;
9945
2.26M
    xmlParserNodeInfo node_info;
9946
2.26M
    int line, tlen = 0;
9947
2.26M
    xmlNodePtr ret;
9948
2.26M
    int nsNr = ctxt->nsNr;
9949
9950
2.26M
    if (((unsigned int) ctxt->nameNr > xmlParserMaxDepth) &&
9951
2.26M
        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
9952
108
  xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
9953
108
     "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
9954
108
        xmlParserMaxDepth);
9955
108
  xmlHaltParser(ctxt);
9956
108
  return(-1);
9957
108
    }
9958
9959
    /* Capture start position */
9960
2.26M
    if (ctxt->record_info) {
9961
0
        node_info.begin_pos = ctxt->input->consumed +
9962
0
                          (CUR_PTR - ctxt->input->base);
9963
0
  node_info.begin_line = ctxt->input->line;
9964
0
    }
9965
9966
2.26M
    if (ctxt->spaceNr == 0)
9967
0
  spacePush(ctxt, -1);
9968
2.26M
    else if (*ctxt->space == -2)
9969
0
  spacePush(ctxt, -1);
9970
2.26M
    else
9971
2.26M
  spacePush(ctxt, *ctxt->space);
9972
9973
2.26M
    line = ctxt->input->line;
9974
#ifdef LIBXML_SAX1_ENABLED
9975
    if (ctxt->sax2)
9976
#endif /* LIBXML_SAX1_ENABLED */
9977
2.26M
        name = xmlParseStartTag2(ctxt, &prefix, &URI, &tlen);
9978
#ifdef LIBXML_SAX1_ENABLED
9979
    else
9980
  name = xmlParseStartTag(ctxt);
9981
#endif /* LIBXML_SAX1_ENABLED */
9982
2.26M
    if (ctxt->instate == XML_PARSER_EOF)
9983
4.55k
  return(-1);
9984
2.26M
    if (name == NULL) {
9985
78.3k
  spacePop(ctxt);
9986
78.3k
        return(-1);
9987
78.3k
    }
9988
2.18M
    nameNsPush(ctxt, name, prefix, URI, line, ctxt->nsNr - nsNr);
9989
2.18M
    ret = ctxt->node;
9990
9991
#ifdef LIBXML_VALID_ENABLED
9992
    /*
9993
     * [ VC: Root Element Type ]
9994
     * The Name in the document type declaration must match the element
9995
     * type of the root element.
9996
     */
9997
    if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
9998
        ctxt->node && (ctxt->node == ctxt->myDoc->children))
9999
        ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
10000
#endif /* LIBXML_VALID_ENABLED */
10001
10002
    /*
10003
     * Check for an Empty Element.
10004
     */
10005
2.18M
    if ((RAW == '/') && (NXT(1) == '>')) {
10006
1.22M
        SKIP(2);
10007
1.22M
  if (ctxt->sax2) {
10008
1.22M
      if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
10009
1.22M
    (!ctxt->disableSAX))
10010
1.12M
    ctxt->sax->endElementNs(ctxt->userData, name, prefix, URI);
10011
#ifdef LIBXML_SAX1_ENABLED
10012
  } else {
10013
      if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
10014
    (!ctxt->disableSAX))
10015
    ctxt->sax->endElement(ctxt->userData, name);
10016
#endif /* LIBXML_SAX1_ENABLED */
10017
1.22M
  }
10018
1.22M
  namePop(ctxt);
10019
1.22M
  spacePop(ctxt);
10020
1.22M
  if (nsNr != ctxt->nsNr)
10021
48.2k
      nsPop(ctxt, ctxt->nsNr - nsNr);
10022
1.22M
  if ( ret != NULL && ctxt->record_info ) {
10023
0
     node_info.end_pos = ctxt->input->consumed +
10024
0
            (CUR_PTR - ctxt->input->base);
10025
0
     node_info.end_line = ctxt->input->line;
10026
0
     node_info.node = ret;
10027
0
     xmlParserAddNodeInfo(ctxt, &node_info);
10028
0
  }
10029
1.22M
  return(1);
10030
1.22M
    }
10031
964k
    if (RAW == '>') {
10032
732k
        NEXT1;
10033
732k
    } else {
10034
232k
        xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_GT_REQUIRED,
10035
232k
         "Couldn't find end of Start Tag %s line %d\n",
10036
232k
                    name, line, NULL);
10037
10038
  /*
10039
   * end of parsing of this node.
10040
   */
10041
232k
  nodePop(ctxt);
10042
232k
  namePop(ctxt);
10043
232k
  spacePop(ctxt);
10044
232k
  if (nsNr != ctxt->nsNr)
10045
91.5k
      nsPop(ctxt, ctxt->nsNr - nsNr);
10046
10047
  /*
10048
   * Capture end position and add node
10049
   */
10050
232k
  if ( ret != NULL && ctxt->record_info ) {
10051
0
     node_info.end_pos = ctxt->input->consumed +
10052
0
            (CUR_PTR - ctxt->input->base);
10053
0
     node_info.end_line = ctxt->input->line;
10054
0
     node_info.node = ret;
10055
0
     xmlParserAddNodeInfo(ctxt, &node_info);
10056
0
  }
10057
232k
  return(-1);
10058
232k
    }
10059
10060
732k
    return(0);
10061
964k
}
10062
10063
/**
10064
 * xmlParseElementEnd:
10065
 * @ctxt:  an XML parser context
10066
 *
10067
 * Parse the end of an XML element. Always consumes '</'.
10068
 */
10069
static void
10070
550k
xmlParseElementEnd(xmlParserCtxtPtr ctxt) {
10071
550k
    xmlParserNodeInfo node_info;
10072
550k
    xmlNodePtr ret = ctxt->node;
10073
10074
550k
    if (ctxt->nameNr <= 0) {
10075
0
        if ((RAW == '<') && (NXT(1) == '/'))
10076
0
            SKIP(2);
10077
0
        return;
10078
0
    }
10079
10080
    /*
10081
     * parse the end of tag: '</' should be here.
10082
     */
10083
550k
    if (ctxt->sax2) {
10084
550k
  xmlParseEndTag2(ctxt, &ctxt->pushTab[ctxt->nameNr - 1]);
10085
550k
  namePop(ctxt);
10086
550k
    }
10087
#ifdef LIBXML_SAX1_ENABLED
10088
    else
10089
  xmlParseEndTag1(ctxt, 0);
10090
#endif /* LIBXML_SAX1_ENABLED */
10091
10092
    /*
10093
     * Capture end position and add node
10094
     */
10095
550k
    if ( ret != NULL && ctxt->record_info ) {
10096
0
       node_info.end_pos = ctxt->input->consumed +
10097
0
                          (CUR_PTR - ctxt->input->base);
10098
0
       node_info.end_line = ctxt->input->line;
10099
0
       node_info.node = ret;
10100
0
       xmlParserAddNodeInfo(ctxt, &node_info);
10101
0
    }
10102
550k
}
10103
10104
/**
10105
 * xmlParseVersionNum:
10106
 * @ctxt:  an XML parser context
10107
 *
10108
 * DEPRECATED: Internal function, don't use.
10109
 *
10110
 * parse the XML version value.
10111
 *
10112
 * [26] VersionNum ::= '1.' [0-9]+
10113
 *
10114
 * In practice allow [0-9].[0-9]+ at that level
10115
 *
10116
 * Returns the string giving the XML version number, or NULL
10117
 */
10118
xmlChar *
10119
86.3k
xmlParseVersionNum(xmlParserCtxtPtr ctxt) {
10120
86.3k
    xmlChar *buf = NULL;
10121
86.3k
    int len = 0;
10122
86.3k
    int size = 10;
10123
86.3k
    xmlChar cur;
10124
10125
86.3k
    buf = (xmlChar *) xmlMallocAtomic(size);
10126
86.3k
    if (buf == NULL) {
10127
7
  xmlErrMemory(ctxt, NULL);
10128
7
  return(NULL);
10129
7
    }
10130
86.3k
    cur = CUR;
10131
86.3k
    if (!((cur >= '0') && (cur <= '9'))) {
10132
1.25k
  xmlFree(buf);
10133
1.25k
  return(NULL);
10134
1.25k
    }
10135
85.1k
    buf[len++] = cur;
10136
85.1k
    NEXT;
10137
85.1k
    cur=CUR;
10138
85.1k
    if (cur != '.') {
10139
310
  xmlFree(buf);
10140
310
  return(NULL);
10141
310
    }
10142
84.8k
    buf[len++] = cur;
10143
84.8k
    NEXT;
10144
84.8k
    cur=CUR;
10145
185k
    while ((cur >= '0') && (cur <= '9')) {
10146
100k
  if (len + 1 >= size) {
10147
1.84k
      xmlChar *tmp;
10148
10149
1.84k
      size *= 2;
10150
1.84k
      tmp = (xmlChar *) xmlRealloc(buf, size);
10151
1.84k
      if (tmp == NULL) {
10152
1
          xmlFree(buf);
10153
1
    xmlErrMemory(ctxt, NULL);
10154
1
    return(NULL);
10155
1
      }
10156
1.84k
      buf = tmp;
10157
1.84k
  }
10158
100k
  buf[len++] = cur;
10159
100k
  NEXT;
10160
100k
  cur=CUR;
10161
100k
    }
10162
84.8k
    buf[len] = 0;
10163
84.8k
    return(buf);
10164
84.8k
}
10165
10166
/**
10167
 * xmlParseVersionInfo:
10168
 * @ctxt:  an XML parser context
10169
 *
10170
 * DEPRECATED: Internal function, don't use.
10171
 *
10172
 * parse the XML version.
10173
 *
10174
 * [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
10175
 *
10176
 * [25] Eq ::= S? '=' S?
10177
 *
10178
 * Returns the version string, e.g. "1.0"
10179
 */
10180
10181
xmlChar *
10182
99.8k
xmlParseVersionInfo(xmlParserCtxtPtr ctxt) {
10183
99.8k
    xmlChar *version = NULL;
10184
10185
99.8k
    if (CMP7(CUR_PTR, 'v', 'e', 'r', 's', 'i', 'o', 'n')) {
10186
88.1k
  SKIP(7);
10187
88.1k
  SKIP_BLANKS;
10188
88.1k
  if (RAW != '=') {
10189
1.31k
      xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
10190
1.31k
      return(NULL);
10191
1.31k
        }
10192
86.7k
  NEXT;
10193
86.7k
  SKIP_BLANKS;
10194
86.7k
  if (RAW == '"') {
10195
79.3k
      NEXT;
10196
79.3k
      version = xmlParseVersionNum(ctxt);
10197
79.3k
      if (RAW != '"') {
10198
1.69k
    xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10199
1.69k
      } else
10200
77.6k
          NEXT;
10201
79.3k
  } else if (RAW == '\''){
10202
7.03k
      NEXT;
10203
7.03k
      version = xmlParseVersionNum(ctxt);
10204
7.03k
      if (RAW != '\'') {
10205
1.29k
    xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10206
1.29k
      } else
10207
5.74k
          NEXT;
10208
7.03k
  } else {
10209
388
      xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
10210
388
  }
10211
86.7k
    }
10212
98.4k
    return(version);
10213
99.8k
}
10214
10215
/**
10216
 * xmlParseEncName:
10217
 * @ctxt:  an XML parser context
10218
 *
10219
 * DEPRECATED: Internal function, don't use.
10220
 *
10221
 * parse the XML encoding name
10222
 *
10223
 * [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
10224
 *
10225
 * Returns the encoding name value or NULL
10226
 */
10227
xmlChar *
10228
71.3k
xmlParseEncName(xmlParserCtxtPtr ctxt) {
10229
71.3k
    xmlChar *buf = NULL;
10230
71.3k
    int len = 0;
10231
71.3k
    int size = 10;
10232
71.3k
    int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
10233
0
                    XML_MAX_TEXT_LENGTH :
10234
71.3k
                    XML_MAX_NAME_LENGTH;
10235
71.3k
    xmlChar cur;
10236
10237
71.3k
    cur = CUR;
10238
71.3k
    if (((cur >= 'a') && (cur <= 'z')) ||
10239
71.3k
        ((cur >= 'A') && (cur <= 'Z'))) {
10240
70.6k
  buf = (xmlChar *) xmlMallocAtomic(size);
10241
70.6k
  if (buf == NULL) {
10242
23
      xmlErrMemory(ctxt, NULL);
10243
23
      return(NULL);
10244
23
  }
10245
10246
70.5k
  buf[len++] = cur;
10247
70.5k
  NEXT;
10248
70.5k
  cur = CUR;
10249
643k
  while (((cur >= 'a') && (cur <= 'z')) ||
10250
643k
         ((cur >= 'A') && (cur <= 'Z')) ||
10251
643k
         ((cur >= '0') && (cur <= '9')) ||
10252
643k
         (cur == '.') || (cur == '_') ||
10253
643k
         (cur == '-')) {
10254
573k
      if (len + 1 >= size) {
10255
23.2k
          xmlChar *tmp;
10256
10257
23.2k
    size *= 2;
10258
23.2k
    tmp = (xmlChar *) xmlRealloc(buf, size);
10259
23.2k
    if (tmp == NULL) {
10260
1
        xmlErrMemory(ctxt, NULL);
10261
1
        xmlFree(buf);
10262
1
        return(NULL);
10263
1
    }
10264
23.2k
    buf = tmp;
10265
23.2k
      }
10266
573k
      buf[len++] = cur;
10267
573k
            if (len > maxLength) {
10268
1
                xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "EncName");
10269
1
                xmlFree(buf);
10270
1
                return(NULL);
10271
1
            }
10272
573k
      NEXT;
10273
573k
      cur = CUR;
10274
573k
        }
10275
70.5k
  buf[len] = 0;
10276
70.5k
    } else {
10277
697
  xmlFatalErr(ctxt, XML_ERR_ENCODING_NAME, NULL);
10278
697
    }
10279
71.2k
    return(buf);
10280
71.3k
}
10281
10282
/**
10283
 * xmlParseEncodingDecl:
10284
 * @ctxt:  an XML parser context
10285
 *
10286
 * DEPRECATED: Internal function, don't use.
10287
 *
10288
 * parse the XML encoding declaration
10289
 *
10290
 * [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' |  "'" EncName "'")
10291
 *
10292
 * this setups the conversion filters.
10293
 *
10294
 * Returns the encoding value or NULL
10295
 */
10296
10297
const xmlChar *
10298
88.1k
xmlParseEncodingDecl(xmlParserCtxtPtr ctxt) {
10299
88.1k
    xmlChar *encoding = NULL;
10300
10301
88.1k
    SKIP_BLANKS;
10302
88.1k
    if (CMP8(CUR_PTR, 'e', 'n', 'c', 'o', 'd', 'i', 'n', 'g')) {
10303
72.3k
  SKIP(8);
10304
72.3k
  SKIP_BLANKS;
10305
72.3k
  if (RAW != '=') {
10306
666
      xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
10307
666
      return(NULL);
10308
666
        }
10309
71.7k
  NEXT;
10310
71.7k
  SKIP_BLANKS;
10311
71.7k
  if (RAW == '"') {
10312
66.3k
      NEXT;
10313
66.3k
      encoding = xmlParseEncName(ctxt);
10314
66.3k
      if (RAW != '"') {
10315
1.50k
    xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10316
1.50k
    xmlFree((xmlChar *) encoding);
10317
1.50k
    return(NULL);
10318
1.50k
      } else
10319
64.8k
          NEXT;
10320
66.3k
  } else if (RAW == '\''){
10321
4.99k
      NEXT;
10322
4.99k
      encoding = xmlParseEncName(ctxt);
10323
4.99k
      if (RAW != '\'') {
10324
239
    xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10325
239
    xmlFree((xmlChar *) encoding);
10326
239
    return(NULL);
10327
239
      } else
10328
4.75k
          NEXT;
10329
4.99k
  } else {
10330
425
      xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
10331
425
  }
10332
10333
        /*
10334
         * Non standard parsing, allowing the user to ignore encoding
10335
         */
10336
69.9k
        if (ctxt->options & XML_PARSE_IGNORE_ENC) {
10337
0
      xmlFree((xmlChar *) encoding);
10338
0
            return(NULL);
10339
0
  }
10340
10341
  /*
10342
   * UTF-16 encoding switch has already taken place at this stage,
10343
   * more over the little-endian/big-endian selection is already done
10344
   */
10345
69.9k
        if ((encoding != NULL) &&
10346
69.9k
      ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-16")) ||
10347
69.5k
       (!xmlStrcasecmp(encoding, BAD_CAST "UTF16")))) {
10348
      /*
10349
       * If no encoding was passed to the parser, that we are
10350
       * using UTF-16 and no decoder is present i.e. the
10351
       * document is apparently UTF-8 compatible, then raise an
10352
       * encoding mismatch fatal error
10353
       */
10354
245
      if ((ctxt->encoding == NULL) &&
10355
245
          (ctxt->input->buf != NULL) &&
10356
245
          (ctxt->input->buf->encoder == NULL)) {
10357
100
    xmlFatalErrMsg(ctxt, XML_ERR_INVALID_ENCODING,
10358
100
      "Document labelled UTF-16 but has UTF-8 content\n");
10359
100
      }
10360
245
      if (ctxt->encoding != NULL)
10361
145
    xmlFree((xmlChar *) ctxt->encoding);
10362
245
      ctxt->encoding = encoding;
10363
245
  }
10364
  /*
10365
   * UTF-8 encoding is handled natively
10366
   */
10367
69.7k
        else if ((encoding != NULL) &&
10368
69.7k
      ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-8")) ||
10369
69.2k
       (!xmlStrcasecmp(encoding, BAD_CAST "UTF8")))) {
10370
            /* TODO: Check for encoding mismatch. */
10371
1.71k
      if (ctxt->encoding != NULL)
10372
88
    xmlFree((xmlChar *) ctxt->encoding);
10373
1.71k
      ctxt->encoding = encoding;
10374
1.71k
  }
10375
68.0k
  else if (encoding != NULL) {
10376
67.5k
      xmlCharEncodingHandlerPtr handler;
10377
10378
67.5k
      if (ctxt->input->encoding != NULL)
10379
0
    xmlFree((xmlChar *) ctxt->input->encoding);
10380
67.5k
      ctxt->input->encoding = encoding;
10381
10382
67.5k
            handler = xmlFindCharEncodingHandler((const char *) encoding);
10383
67.5k
      if (handler != NULL) {
10384
66.1k
    if (xmlSwitchToEncoding(ctxt, handler) < 0) {
10385
        /* failed to convert */
10386
429
        ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
10387
429
        return(NULL);
10388
429
    }
10389
66.1k
      } else {
10390
1.40k
    xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
10391
1.40k
      "Unsupported encoding %s\n", encoding);
10392
1.40k
    return(NULL);
10393
1.40k
      }
10394
67.5k
  }
10395
69.9k
    }
10396
83.9k
    return(encoding);
10397
88.1k
}
10398
10399
/**
10400
 * xmlParseSDDecl:
10401
 * @ctxt:  an XML parser context
10402
 *
10403
 * DEPRECATED: Internal function, don't use.
10404
 *
10405
 * parse the XML standalone declaration
10406
 *
10407
 * [32] SDDecl ::= S 'standalone' Eq
10408
 *                 (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no')'"'))
10409
 *
10410
 * [ VC: Standalone Document Declaration ]
10411
 * TODO The standalone document declaration must have the value "no"
10412
 * if any external markup declarations contain declarations of:
10413
 *  - attributes with default values, if elements to which these
10414
 *    attributes apply appear in the document without specifications
10415
 *    of values for these attributes, or
10416
 *  - entities (other than amp, lt, gt, apos, quot), if references
10417
 *    to those entities appear in the document, or
10418
 *  - attributes with values subject to normalization, where the
10419
 *    attribute appears in the document with a value which will change
10420
 *    as a result of normalization, or
10421
 *  - element types with element content, if white space occurs directly
10422
 *    within any instance of those types.
10423
 *
10424
 * Returns:
10425
 *   1 if standalone="yes"
10426
 *   0 if standalone="no"
10427
 *  -2 if standalone attribute is missing or invalid
10428
 *    (A standalone value of -2 means that the XML declaration was found,
10429
 *     but no value was specified for the standalone attribute).
10430
 */
10431
10432
int
10433
23.6k
xmlParseSDDecl(xmlParserCtxtPtr ctxt) {
10434
23.6k
    int standalone = -2;
10435
10436
23.6k
    SKIP_BLANKS;
10437
23.6k
    if (CMP10(CUR_PTR, 's', 't', 'a', 'n', 'd', 'a', 'l', 'o', 'n', 'e')) {
10438
6.63k
  SKIP(10);
10439
6.63k
        SKIP_BLANKS;
10440
6.63k
  if (RAW != '=') {
10441
90
      xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
10442
90
      return(standalone);
10443
90
        }
10444
6.54k
  NEXT;
10445
6.54k
  SKIP_BLANKS;
10446
6.54k
        if (RAW == '\''){
10447
3.00k
      NEXT;
10448
3.00k
      if ((RAW == 'n') && (NXT(1) == 'o')) {
10449
2.20k
          standalone = 0;
10450
2.20k
                SKIP(2);
10451
2.20k
      } else if ((RAW == 'y') && (NXT(1) == 'e') &&
10452
799
                 (NXT(2) == 's')) {
10453
109
          standalone = 1;
10454
109
    SKIP(3);
10455
690
            } else {
10456
690
    xmlFatalErr(ctxt, XML_ERR_STANDALONE_VALUE, NULL);
10457
690
      }
10458
3.00k
      if (RAW != '\'') {
10459
1.07k
    xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10460
1.07k
      } else
10461
1.93k
          NEXT;
10462
3.54k
  } else if (RAW == '"'){
10463
3.31k
      NEXT;
10464
3.31k
      if ((RAW == 'n') && (NXT(1) == 'o')) {
10465
2.41k
          standalone = 0;
10466
2.41k
    SKIP(2);
10467
2.41k
      } else if ((RAW == 'y') && (NXT(1) == 'e') &&
10468
905
                 (NXT(2) == 's')) {
10469
347
          standalone = 1;
10470
347
                SKIP(3);
10471
558
            } else {
10472
558
    xmlFatalErr(ctxt, XML_ERR_STANDALONE_VALUE, NULL);
10473
558
      }
10474
3.31k
      if (RAW != '"') {
10475
777
    xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10476
777
      } else
10477
2.53k
          NEXT;
10478
3.31k
  } else {
10479
224
      xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
10480
224
        }
10481
6.54k
    }
10482
23.5k
    return(standalone);
10483
23.6k
}
10484
10485
/**
10486
 * xmlParseXMLDecl:
10487
 * @ctxt:  an XML parser context
10488
 *
10489
 * DEPRECATED: Internal function, don't use.
10490
 *
10491
 * parse an XML declaration header
10492
 *
10493
 * [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
10494
 */
10495
10496
void
10497
89.2k
xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
10498
89.2k
    xmlChar *version;
10499
10500
    /*
10501
     * This value for standalone indicates that the document has an
10502
     * XML declaration but it does not have a standalone attribute.
10503
     * It will be overwritten later if a standalone attribute is found.
10504
     */
10505
89.2k
    ctxt->input->standalone = -2;
10506
10507
    /*
10508
     * We know that '<?xml' is here.
10509
     */
10510
89.2k
    SKIP(5);
10511
10512
89.2k
    if (!IS_BLANK_CH(RAW)) {
10513
0
  xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
10514
0
                 "Blank needed after '<?xml'\n");
10515
0
    }
10516
89.2k
    SKIP_BLANKS;
10517
10518
    /*
10519
     * We must have the VersionInfo here.
10520
     */
10521
89.2k
    version = xmlParseVersionInfo(ctxt);
10522
89.2k
    if (version == NULL) {
10523
9.48k
  xmlFatalErr(ctxt, XML_ERR_VERSION_MISSING, NULL);
10524
79.7k
    } else {
10525
79.7k
  if (!xmlStrEqual(version, (const xmlChar *) XML_DEFAULT_VERSION)) {
10526
      /*
10527
       * Changed here for XML-1.0 5th edition
10528
       */
10529
40.1k
      if (ctxt->options & XML_PARSE_OLD10) {
10530
0
    xmlFatalErrMsgStr(ctxt, XML_ERR_UNKNOWN_VERSION,
10531
0
                "Unsupported version '%s'\n",
10532
0
                version);
10533
40.1k
      } else {
10534
40.1k
          if ((version[0] == '1') && ((version[1] == '.'))) {
10535
34.5k
        xmlWarningMsg(ctxt, XML_WAR_UNKNOWN_VERSION,
10536
34.5k
                      "Unsupported version '%s'\n",
10537
34.5k
          version, NULL);
10538
34.5k
    } else {
10539
5.59k
        xmlFatalErrMsgStr(ctxt, XML_ERR_UNKNOWN_VERSION,
10540
5.59k
              "Unsupported version '%s'\n",
10541
5.59k
              version);
10542
5.59k
    }
10543
40.1k
      }
10544
40.1k
  }
10545
79.7k
  if (ctxt->version != NULL)
10546
0
      xmlFree((void *) ctxt->version);
10547
79.7k
  ctxt->version = version;
10548
79.7k
    }
10549
10550
    /*
10551
     * We may have the encoding declaration
10552
     */
10553
89.2k
    if (!IS_BLANK_CH(RAW)) {
10554
21.1k
        if ((RAW == '?') && (NXT(1) == '>')) {
10555
11.6k
      SKIP(2);
10556
11.6k
      return;
10557
11.6k
  }
10558
9.48k
  xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
10559
9.48k
    }
10560
77.6k
    xmlParseEncodingDecl(ctxt);
10561
77.6k
    if ((ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) ||
10562
77.6k
         (ctxt->instate == XML_PARSER_EOF)) {
10563
  /*
10564
   * The XML REC instructs us to stop parsing right here
10565
   */
10566
1.35k
        return;
10567
1.35k
    }
10568
10569
    /*
10570
     * We may have the standalone status.
10571
     */
10572
76.2k
    if ((ctxt->input->encoding != NULL) && (!IS_BLANK_CH(RAW))) {
10573
55.2k
        if ((RAW == '?') && (NXT(1) == '>')) {
10574
52.5k
      SKIP(2);
10575
52.5k
      return;
10576
52.5k
  }
10577
2.72k
  xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
10578
2.72k
    }
10579
10580
    /*
10581
     * We can grow the input buffer freely at that point
10582
     */
10583
23.6k
    GROW;
10584
10585
23.6k
    SKIP_BLANKS;
10586
23.6k
    ctxt->input->standalone = xmlParseSDDecl(ctxt);
10587
10588
23.6k
    SKIP_BLANKS;
10589
23.6k
    if ((RAW == '?') && (NXT(1) == '>')) {
10590
5.85k
        SKIP(2);
10591
17.8k
    } else if (RAW == '>') {
10592
        /* Deprecated old WD ... */
10593
1.12k
  xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
10594
1.12k
  NEXT;
10595
16.7k
    } else {
10596
16.7k
        int c;
10597
10598
16.7k
  xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
10599
2.47M
        while ((c = CUR) != 0) {
10600
2.46M
            NEXT;
10601
2.46M
            if (c == '>')
10602
12.1k
                break;
10603
2.46M
        }
10604
16.7k
    }
10605
23.6k
}
10606
10607
/**
10608
 * xmlParseMisc:
10609
 * @ctxt:  an XML parser context
10610
 *
10611
 * DEPRECATED: Internal function, don't use.
10612
 *
10613
 * parse an XML Misc* optional field.
10614
 *
10615
 * [27] Misc ::= Comment | PI |  S
10616
 */
10617
10618
void
10619
337k
xmlParseMisc(xmlParserCtxtPtr ctxt) {
10620
372k
    while (ctxt->instate != XML_PARSER_EOF) {
10621
372k
        SKIP_BLANKS;
10622
372k
        GROW;
10623
372k
        if ((RAW == '<') && (NXT(1) == '?')) {
10624
30.3k
      xmlParsePI(ctxt);
10625
342k
        } else if (CMP4(CUR_PTR, '<', '!', '-', '-')) {
10626
5.11k
      xmlParseComment(ctxt);
10627
336k
        } else {
10628
336k
            break;
10629
336k
        }
10630
372k
    }
10631
337k
}
10632
10633
/**
10634
 * xmlParseDocument:
10635
 * @ctxt:  an XML parser context
10636
 *
10637
 * parse an XML document (and build a tree if using the standard SAX
10638
 * interface).
10639
 *
10640
 * [1] document ::= prolog element Misc*
10641
 *
10642
 * [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
10643
 *
10644
 * Returns 0, -1 in case of error. the parser context is augmented
10645
 *                as a result of the parsing.
10646
 */
10647
10648
int
10649
188k
xmlParseDocument(xmlParserCtxtPtr ctxt) {
10650
188k
    xmlChar start[4];
10651
188k
    xmlCharEncoding enc;
10652
10653
188k
    xmlInitParser();
10654
10655
188k
    if ((ctxt == NULL) || (ctxt->input == NULL))
10656
0
        return(-1);
10657
10658
188k
    GROW;
10659
10660
    /*
10661
     * SAX: detecting the level.
10662
     */
10663
188k
    xmlDetectSAX2(ctxt);
10664
10665
    /*
10666
     * SAX: beginning of the document processing.
10667
     */
10668
188k
    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
10669
188k
        ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
10670
188k
    if (ctxt->instate == XML_PARSER_EOF)
10671
0
  return(-1);
10672
10673
188k
    if ((ctxt->encoding == NULL) &&
10674
188k
        ((ctxt->input->end - ctxt->input->cur) >= 4)) {
10675
  /*
10676
   * Get the 4 first bytes and decode the charset
10677
   * if enc != XML_CHAR_ENCODING_NONE
10678
   * plug some encoding conversion routines.
10679
   */
10680
186k
  start[0] = RAW;
10681
186k
  start[1] = NXT(1);
10682
186k
  start[2] = NXT(2);
10683
186k
  start[3] = NXT(3);
10684
186k
  enc = xmlDetectCharEncoding(&start[0], 4);
10685
186k
  if (enc != XML_CHAR_ENCODING_NONE) {
10686
99.5k
      xmlSwitchEncoding(ctxt, enc);
10687
99.5k
  }
10688
186k
    }
10689
10690
10691
188k
    if (CUR == 0) {
10692
1.22k
  xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
10693
1.22k
  return(-1);
10694
1.22k
    }
10695
10696
187k
    GROW;
10697
187k
    if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
10698
10699
  /*
10700
   * Note that we will switch encoding on the fly.
10701
   */
10702
89.2k
  xmlParseXMLDecl(ctxt);
10703
89.2k
  if ((ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) ||
10704
89.2k
      (ctxt->instate == XML_PARSER_EOF)) {
10705
      /*
10706
       * The XML REC instructs us to stop parsing right here
10707
       */
10708
1.74k
      return(-1);
10709
1.74k
  }
10710
87.5k
  ctxt->standalone = ctxt->input->standalone;
10711
87.5k
  SKIP_BLANKS;
10712
97.9k
    } else {
10713
97.9k
  ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
10714
97.9k
    }
10715
185k
    if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
10716
164k
        ctxt->sax->startDocument(ctxt->userData);
10717
185k
    if (ctxt->instate == XML_PARSER_EOF)
10718
833
  return(-1);
10719
184k
    if ((ctxt->myDoc != NULL) && (ctxt->input != NULL) &&
10720
184k
        (ctxt->input->buf != NULL) && (ctxt->input->buf->compressed >= 0)) {
10721
0
  ctxt->myDoc->compression = ctxt->input->buf->compressed;
10722
0
    }
10723
10724
    /*
10725
     * The Misc part of the Prolog
10726
     */
10727
184k
    xmlParseMisc(ctxt);
10728
10729
    /*
10730
     * Then possibly doc type declaration(s) and more Misc
10731
     * (doctypedecl Misc*)?
10732
     */
10733
184k
    GROW;
10734
184k
    if (CMP9(CUR_PTR, '<', '!', 'D', 'O', 'C', 'T', 'Y', 'P', 'E')) {
10735
10736
59.9k
  ctxt->inSubset = 1;
10737
59.9k
  xmlParseDocTypeDecl(ctxt);
10738
59.9k
  if (RAW == '[') {
10739
50.8k
      ctxt->instate = XML_PARSER_DTD;
10740
50.8k
      xmlParseInternalSubset(ctxt);
10741
50.8k
      if (ctxt->instate == XML_PARSER_EOF)
10742
33.3k
    return(-1);
10743
50.8k
  }
10744
10745
  /*
10746
   * Create and update the external subset.
10747
   */
10748
26.5k
  ctxt->inSubset = 2;
10749
26.5k
  if ((ctxt->sax != NULL) && (ctxt->sax->externalSubset != NULL) &&
10750
26.5k
      (!ctxt->disableSAX))
10751
16.5k
      ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
10752
16.5k
                                ctxt->extSubSystem, ctxt->extSubURI);
10753
26.5k
  if (ctxt->instate == XML_PARSER_EOF)
10754
2.00k
      return(-1);
10755
24.5k
  ctxt->inSubset = 0;
10756
10757
24.5k
        xmlCleanSpecialAttr(ctxt);
10758
10759
24.5k
  ctxt->instate = XML_PARSER_PROLOG;
10760
24.5k
  xmlParseMisc(ctxt);
10761
24.5k
    }
10762
10763
    /*
10764
     * Time to start parsing the tree itself
10765
     */
10766
149k
    GROW;
10767
149k
    if (RAW != '<') {
10768
20.9k
  xmlFatalErrMsg(ctxt, XML_ERR_DOCUMENT_EMPTY,
10769
20.9k
           "Start tag expected, '<' not found\n");
10770
128k
    } else {
10771
128k
  ctxt->instate = XML_PARSER_CONTENT;
10772
128k
  xmlParseElement(ctxt);
10773
128k
  ctxt->instate = XML_PARSER_EPILOG;
10774
10775
10776
  /*
10777
   * The Misc part at the end
10778
   */
10779
128k
  xmlParseMisc(ctxt);
10780
10781
128k
  if (RAW != 0) {
10782
14.6k
      xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
10783
14.6k
  }
10784
128k
  ctxt->instate = XML_PARSER_EOF;
10785
128k
    }
10786
10787
    /*
10788
     * SAX: end of the document processing.
10789
     */
10790
149k
    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
10791
149k
        ctxt->sax->endDocument(ctxt->userData);
10792
10793
    /*
10794
     * Remove locally kept entity definitions if the tree was not built
10795
     */
10796
149k
    if ((ctxt->myDoc != NULL) &&
10797
149k
  (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) {
10798
1.37k
  xmlFreeDoc(ctxt->myDoc);
10799
1.37k
  ctxt->myDoc = NULL;
10800
1.37k
    }
10801
10802
149k
    if ((ctxt->wellFormed) && (ctxt->myDoc != NULL)) {
10803
80.0k
        ctxt->myDoc->properties |= XML_DOC_WELLFORMED;
10804
80.0k
  if (ctxt->valid)
10805
80.0k
      ctxt->myDoc->properties |= XML_DOC_DTDVALID;
10806
80.0k
  if (ctxt->nsWellFormed)
10807
40.2k
      ctxt->myDoc->properties |= XML_DOC_NSVALID;
10808
80.0k
  if (ctxt->options & XML_PARSE_OLD10)
10809
0
      ctxt->myDoc->properties |= XML_DOC_OLD10;
10810
80.0k
    }
10811
149k
    if (! ctxt->wellFormed) {
10812
69.1k
  ctxt->valid = 0;
10813
69.1k
  return(-1);
10814
69.1k
    }
10815
80.0k
    return(0);
10816
149k
}
10817
10818
/**
10819
 * xmlParseExtParsedEnt:
10820
 * @ctxt:  an XML parser context
10821
 *
10822
 * parse a general parsed entity
10823
 * An external general parsed entity is well-formed if it matches the
10824
 * production labeled extParsedEnt.
10825
 *
10826
 * [78] extParsedEnt ::= TextDecl? content
10827
 *
10828
 * Returns 0, -1 in case of error. the parser context is augmented
10829
 *                as a result of the parsing.
10830
 */
10831
10832
int
10833
0
xmlParseExtParsedEnt(xmlParserCtxtPtr ctxt) {
10834
0
    xmlChar start[4];
10835
0
    xmlCharEncoding enc;
10836
10837
0
    if ((ctxt == NULL) || (ctxt->input == NULL))
10838
0
        return(-1);
10839
10840
0
    xmlDetectSAX2(ctxt);
10841
10842
0
    GROW;
10843
10844
    /*
10845
     * SAX: beginning of the document processing.
10846
     */
10847
0
    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
10848
0
        ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
10849
10850
    /*
10851
     * Get the 4 first bytes and decode the charset
10852
     * if enc != XML_CHAR_ENCODING_NONE
10853
     * plug some encoding conversion routines.
10854
     */
10855
0
    if ((ctxt->input->end - ctxt->input->cur) >= 4) {
10856
0
  start[0] = RAW;
10857
0
  start[1] = NXT(1);
10858
0
  start[2] = NXT(2);
10859
0
  start[3] = NXT(3);
10860
0
  enc = xmlDetectCharEncoding(start, 4);
10861
0
  if (enc != XML_CHAR_ENCODING_NONE) {
10862
0
      xmlSwitchEncoding(ctxt, enc);
10863
0
  }
10864
0
    }
10865
10866
10867
0
    if (CUR == 0) {
10868
0
  xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
10869
0
    }
10870
10871
    /*
10872
     * Check for the XMLDecl in the Prolog.
10873
     */
10874
0
    GROW;
10875
0
    if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
10876
10877
  /*
10878
   * Note that we will switch encoding on the fly.
10879
   */
10880
0
  xmlParseXMLDecl(ctxt);
10881
0
  if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
10882
      /*
10883
       * The XML REC instructs us to stop parsing right here
10884
       */
10885
0
      return(-1);
10886
0
  }
10887
0
  SKIP_BLANKS;
10888
0
    } else {
10889
0
  ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
10890
0
    }
10891
0
    if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
10892
0
        ctxt->sax->startDocument(ctxt->userData);
10893
0
    if (ctxt->instate == XML_PARSER_EOF)
10894
0
  return(-1);
10895
10896
    /*
10897
     * Doing validity checking on chunk doesn't make sense
10898
     */
10899
0
    ctxt->instate = XML_PARSER_CONTENT;
10900
0
    ctxt->validate = 0;
10901
0
    ctxt->loadsubset = 0;
10902
0
    ctxt->depth = 0;
10903
10904
0
    xmlParseContent(ctxt);
10905
0
    if (ctxt->instate == XML_PARSER_EOF)
10906
0
  return(-1);
10907
10908
0
    if ((RAW == '<') && (NXT(1) == '/')) {
10909
0
  xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
10910
0
    } else if (RAW != 0) {
10911
0
  xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
10912
0
    }
10913
10914
    /*
10915
     * SAX: end of the document processing.
10916
     */
10917
0
    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
10918
0
        ctxt->sax->endDocument(ctxt->userData);
10919
10920
0
    if (! ctxt->wellFormed) return(-1);
10921
0
    return(0);
10922
0
}
10923
10924
#ifdef LIBXML_PUSH_ENABLED
10925
/************************************************************************
10926
 *                  *
10927
 *    Progressive parsing interfaces        *
10928
 *                  *
10929
 ************************************************************************/
10930
10931
/**
10932
 * xmlParseLookupChar:
10933
 * @ctxt:  an XML parser context
10934
 * @c:  character
10935
 *
10936
 * Check whether the input buffer contains a character.
10937
 */
10938
static int
10939
xmlParseLookupChar(xmlParserCtxtPtr ctxt, int c) {
10940
    const xmlChar *cur;
10941
10942
    if (ctxt->checkIndex == 0) {
10943
        cur = ctxt->input->cur + 1;
10944
    } else {
10945
        cur = ctxt->input->cur + ctxt->checkIndex;
10946
    }
10947
10948
    if (memchr(cur, c, ctxt->input->end - cur) == NULL) {
10949
        size_t index = ctxt->input->end - ctxt->input->cur;
10950
10951
        if (index > LONG_MAX) {
10952
            ctxt->checkIndex = 0;
10953
            return(1);
10954
        }
10955
        ctxt->checkIndex = index;
10956
        return(0);
10957
    } else {
10958
        ctxt->checkIndex = 0;
10959
        return(1);
10960
    }
10961
}
10962
10963
/**
10964
 * xmlParseLookupString:
10965
 * @ctxt:  an XML parser context
10966
 * @startDelta: delta to apply at the start
10967
 * @str:  string
10968
 * @strLen:  length of string
10969
 *
10970
 * Check whether the input buffer contains a string.
10971
 */
10972
static const xmlChar *
10973
xmlParseLookupString(xmlParserCtxtPtr ctxt, size_t startDelta,
10974
                     const char *str, size_t strLen) {
10975
    const xmlChar *cur, *term;
10976
10977
    if (ctxt->checkIndex == 0) {
10978
        cur = ctxt->input->cur + startDelta;
10979
    } else {
10980
        cur = ctxt->input->cur + ctxt->checkIndex;
10981
    }
10982
10983
    term = BAD_CAST strstr((const char *) cur, str);
10984
    if (term == NULL) {
10985
        const xmlChar *end = ctxt->input->end;
10986
        size_t index;
10987
10988
        /* Rescan (strLen - 1) characters. */
10989
        if ((size_t) (end - cur) < strLen)
10990
            end = cur;
10991
        else
10992
            end -= strLen - 1;
10993
        index = end - ctxt->input->cur;
10994
        if (index > LONG_MAX) {
10995
            ctxt->checkIndex = 0;
10996
            return(ctxt->input->end - strLen);
10997
        }
10998
        ctxt->checkIndex = index;
10999
    } else {
11000
        ctxt->checkIndex = 0;
11001
    }
11002
11003
    return(term);
11004
}
11005
11006
/**
11007
 * xmlParseLookupCharData:
11008
 * @ctxt:  an XML parser context
11009
 *
11010
 * Check whether the input buffer contains terminated char data.
11011
 */
11012
static int
11013
xmlParseLookupCharData(xmlParserCtxtPtr ctxt) {
11014
    const xmlChar *cur = ctxt->input->cur + ctxt->checkIndex;
11015
    const xmlChar *end = ctxt->input->end;
11016
    size_t index;
11017
11018
    while (cur < end) {
11019
        if ((*cur == '<') || (*cur == '&')) {
11020
            ctxt->checkIndex = 0;
11021
            return(1);
11022
        }
11023
        cur++;
11024
    }
11025
11026
    index = cur - ctxt->input->cur;
11027
    if (index > LONG_MAX) {
11028
        ctxt->checkIndex = 0;
11029
        return(1);
11030
    }
11031
    ctxt->checkIndex = index;
11032
    return(0);
11033
}
11034
11035
/**
11036
 * xmlParseLookupGt:
11037
 * @ctxt:  an XML parser context
11038
 *
11039
 * Check whether there's enough data in the input buffer to finish parsing
11040
 * a start tag. This has to take quotes into account.
11041
 */
11042
static int
11043
xmlParseLookupGt(xmlParserCtxtPtr ctxt) {
11044
    const xmlChar *cur;
11045
    const xmlChar *end = ctxt->input->end;
11046
    int state = ctxt->endCheckState;
11047
    size_t index;
11048
11049
    if (ctxt->checkIndex == 0)
11050
        cur = ctxt->input->cur + 1;
11051
    else
11052
        cur = ctxt->input->cur + ctxt->checkIndex;
11053
11054
    while (cur < end) {
11055
        if (state) {
11056
            if (*cur == state)
11057
                state = 0;
11058
        } else if (*cur == '\'' || *cur == '"') {
11059
            state = *cur;
11060
        } else if (*cur == '>') {
11061
            ctxt->checkIndex = 0;
11062
            ctxt->endCheckState = 0;
11063
            return(1);
11064
        }
11065
        cur++;
11066
    }
11067
11068
    index = cur - ctxt->input->cur;
11069
    if (index > LONG_MAX) {
11070
        ctxt->checkIndex = 0;
11071
        ctxt->endCheckState = 0;
11072
        return(1);
11073
    }
11074
    ctxt->checkIndex = index;
11075
    ctxt->endCheckState = state;
11076
    return(0);
11077
}
11078
11079
/**
11080
 * xmlParseLookupInternalSubset:
11081
 * @ctxt:  an XML parser context
11082
 *
11083
 * Check whether there's enough data in the input buffer to finish parsing
11084
 * the internal subset.
11085
 */
11086
static int
11087
xmlParseLookupInternalSubset(xmlParserCtxtPtr ctxt) {
11088
    /*
11089
     * Sorry, but progressive parsing of the internal subset is not
11090
     * supported. We first check that the full content of the internal
11091
     * subset is available and parsing is launched only at that point.
11092
     * Internal subset ends with "']' S? '>'" in an unescaped section and
11093
     * not in a ']]>' sequence which are conditional sections.
11094
     */
11095
    const xmlChar *cur, *start;
11096
    const xmlChar *end = ctxt->input->end;
11097
    int state = ctxt->endCheckState;
11098
    size_t index;
11099
11100
    if (ctxt->checkIndex == 0) {
11101
        cur = ctxt->input->cur + 1;
11102
    } else {
11103
        cur = ctxt->input->cur + ctxt->checkIndex;
11104
    }
11105
    start = cur;
11106
11107
    while (cur < end) {
11108
        if (state == '-') {
11109
            if ((*cur == '-') &&
11110
                (cur[1] == '-') &&
11111
                (cur[2] == '>')) {
11112
                state = 0;
11113
                cur += 3;
11114
                start = cur;
11115
                continue;
11116
            }
11117
        }
11118
        else if (state == ']') {
11119
            if (*cur == '>') {
11120
                ctxt->checkIndex = 0;
11121
                ctxt->endCheckState = 0;
11122
                return(1);
11123
            }
11124
            if (IS_BLANK_CH(*cur)) {
11125
                state = ' ';
11126
            } else if (*cur != ']') {
11127
                state = 0;
11128
                start = cur;
11129
                continue;
11130
            }
11131
        }
11132
        else if (state == ' ') {
11133
            if (*cur == '>') {
11134
                ctxt->checkIndex = 0;
11135
                ctxt->endCheckState = 0;
11136
                return(1);
11137
            }
11138
            if (!IS_BLANK_CH(*cur)) {
11139
                state = 0;
11140
                start = cur;
11141
                continue;
11142
            }
11143
        }
11144
        else if (state != 0) {
11145
            if (*cur == state) {
11146
                state = 0;
11147
                start = cur + 1;
11148
            }
11149
        }
11150
        else if (*cur == '<') {
11151
            if ((cur[1] == '!') &&
11152
                (cur[2] == '-') &&
11153
                (cur[3] == '-')) {
11154
                state = '-';
11155
                cur += 4;
11156
                /* Don't treat <!--> as comment */
11157
                start = cur;
11158
                continue;
11159
            }
11160
        }
11161
        else if ((*cur == '"') || (*cur == '\'') || (*cur == ']')) {
11162
            state = *cur;
11163
        }
11164
11165
        cur++;
11166
    }
11167
11168
    /*
11169
     * Rescan the three last characters to detect "<!--" and "-->"
11170
     * split across chunks.
11171
     */
11172
    if ((state == 0) || (state == '-')) {
11173
        if (cur - start < 3)
11174
            cur = start;
11175
        else
11176
            cur -= 3;
11177
    }
11178
    index = cur - ctxt->input->cur;
11179
    if (index > LONG_MAX) {
11180
        ctxt->checkIndex = 0;
11181
        ctxt->endCheckState = 0;
11182
        return(1);
11183
    }
11184
    ctxt->checkIndex = index;
11185
    ctxt->endCheckState = state;
11186
    return(0);
11187
}
11188
11189
/**
11190
 * xmlCheckCdataPush:
11191
 * @cur: pointer to the block of characters
11192
 * @len: length of the block in bytes
11193
 * @complete: 1 if complete CDATA block is passed in, 0 if partial block
11194
 *
11195
 * Check that the block of characters is okay as SCdata content [20]
11196
 *
11197
 * Returns the number of bytes to pass if okay, a negative index where an
11198
 *         UTF-8 error occurred otherwise
11199
 */
11200
static int
11201
xmlCheckCdataPush(const xmlChar *utf, int len, int complete) {
11202
    int ix;
11203
    unsigned char c;
11204
    int codepoint;
11205
11206
    if ((utf == NULL) || (len <= 0))
11207
        return(0);
11208
11209
    for (ix = 0; ix < len;) {      /* string is 0-terminated */
11210
        c = utf[ix];
11211
        if ((c & 0x80) == 0x00) { /* 1-byte code, starts with 10 */
11212
      if (c >= 0x20)
11213
    ix++;
11214
      else if ((c == 0xA) || (c == 0xD) || (c == 0x9))
11215
          ix++;
11216
      else
11217
          return(-ix);
11218
  } else if ((c & 0xe0) == 0xc0) {/* 2-byte code, starts with 110 */
11219
      if (ix + 2 > len) return(complete ? -ix : ix);
11220
      if ((utf[ix+1] & 0xc0 ) != 0x80)
11221
          return(-ix);
11222
      codepoint = (utf[ix] & 0x1f) << 6;
11223
      codepoint |= utf[ix+1] & 0x3f;
11224
      if (!xmlIsCharQ(codepoint))
11225
          return(-ix);
11226
      ix += 2;
11227
  } else if ((c & 0xf0) == 0xe0) {/* 3-byte code, starts with 1110 */
11228
      if (ix + 3 > len) return(complete ? -ix : ix);
11229
      if (((utf[ix+1] & 0xc0) != 0x80) ||
11230
          ((utf[ix+2] & 0xc0) != 0x80))
11231
        return(-ix);
11232
      codepoint = (utf[ix] & 0xf) << 12;
11233
      codepoint |= (utf[ix+1] & 0x3f) << 6;
11234
      codepoint |= utf[ix+2] & 0x3f;
11235
      if (!xmlIsCharQ(codepoint))
11236
          return(-ix);
11237
      ix += 3;
11238
  } else if ((c & 0xf8) == 0xf0) {/* 4-byte code, starts with 11110 */
11239
      if (ix + 4 > len) return(complete ? -ix : ix);
11240
      if (((utf[ix+1] & 0xc0) != 0x80) ||
11241
          ((utf[ix+2] & 0xc0) != 0x80) ||
11242
    ((utf[ix+3] & 0xc0) != 0x80))
11243
        return(-ix);
11244
      codepoint = (utf[ix] & 0x7) << 18;
11245
      codepoint |= (utf[ix+1] & 0x3f) << 12;
11246
      codepoint |= (utf[ix+2] & 0x3f) << 6;
11247
      codepoint |= utf[ix+3] & 0x3f;
11248
      if (!xmlIsCharQ(codepoint))
11249
          return(-ix);
11250
      ix += 4;
11251
  } else        /* unknown encoding */
11252
      return(-ix);
11253
      }
11254
      return(ix);
11255
}
11256
11257
/**
11258
 * xmlParseTryOrFinish:
11259
 * @ctxt:  an XML parser context
11260
 * @terminate:  last chunk indicator
11261
 *
11262
 * Try to progress on parsing
11263
 *
11264
 * Returns zero if no parsing was possible
11265
 */
11266
static int
11267
xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
11268
    int ret = 0;
11269
    int tlen;
11270
    size_t avail;
11271
    xmlChar cur, next;
11272
11273
    if (ctxt->input == NULL)
11274
        return(0);
11275
11276
#ifdef DEBUG_PUSH
11277
    switch (ctxt->instate) {
11278
  case XML_PARSER_EOF:
11279
      xmlGenericError(xmlGenericErrorContext,
11280
        "PP: try EOF\n"); break;
11281
  case XML_PARSER_START:
11282
      xmlGenericError(xmlGenericErrorContext,
11283
        "PP: try START\n"); break;
11284
  case XML_PARSER_MISC:
11285
      xmlGenericError(xmlGenericErrorContext,
11286
        "PP: try MISC\n");break;
11287
  case XML_PARSER_COMMENT:
11288
      xmlGenericError(xmlGenericErrorContext,
11289
        "PP: try COMMENT\n");break;
11290
  case XML_PARSER_PROLOG:
11291
      xmlGenericError(xmlGenericErrorContext,
11292
        "PP: try PROLOG\n");break;
11293
  case XML_PARSER_START_TAG:
11294
      xmlGenericError(xmlGenericErrorContext,
11295
        "PP: try START_TAG\n");break;
11296
  case XML_PARSER_CONTENT:
11297
      xmlGenericError(xmlGenericErrorContext,
11298
        "PP: try CONTENT\n");break;
11299
  case XML_PARSER_CDATA_SECTION:
11300
      xmlGenericError(xmlGenericErrorContext,
11301
        "PP: try CDATA_SECTION\n");break;
11302
  case XML_PARSER_END_TAG:
11303
      xmlGenericError(xmlGenericErrorContext,
11304
        "PP: try END_TAG\n");break;
11305
  case XML_PARSER_ENTITY_DECL:
11306
      xmlGenericError(xmlGenericErrorContext,
11307
        "PP: try ENTITY_DECL\n");break;
11308
  case XML_PARSER_ENTITY_VALUE:
11309
      xmlGenericError(xmlGenericErrorContext,
11310
        "PP: try ENTITY_VALUE\n");break;
11311
  case XML_PARSER_ATTRIBUTE_VALUE:
11312
      xmlGenericError(xmlGenericErrorContext,
11313
        "PP: try ATTRIBUTE_VALUE\n");break;
11314
  case XML_PARSER_DTD:
11315
      xmlGenericError(xmlGenericErrorContext,
11316
        "PP: try DTD\n");break;
11317
  case XML_PARSER_EPILOG:
11318
      xmlGenericError(xmlGenericErrorContext,
11319
        "PP: try EPILOG\n");break;
11320
  case XML_PARSER_PI:
11321
      xmlGenericError(xmlGenericErrorContext,
11322
        "PP: try PI\n");break;
11323
        case XML_PARSER_IGNORE:
11324
            xmlGenericError(xmlGenericErrorContext,
11325
        "PP: try IGNORE\n");break;
11326
    }
11327
#endif
11328
11329
    if ((ctxt->input != NULL) &&
11330
        (ctxt->input->cur - ctxt->input->base > 4096)) {
11331
        xmlParserShrink(ctxt);
11332
    }
11333
11334
    while (ctxt->instate != XML_PARSER_EOF) {
11335
  if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
11336
      return(0);
11337
11338
  if (ctxt->input == NULL) break;
11339
  if (ctxt->input->buf != NULL) {
11340
      /*
11341
       * If we are operating on converted input, try to flush
11342
       * remaining chars to avoid them stalling in the non-converted
11343
       * buffer.
11344
       */
11345
      if ((ctxt->input->buf->raw != NULL) &&
11346
    (xmlBufIsEmpty(ctxt->input->buf->raw) == 0)) {
11347
                size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer,
11348
                                                 ctxt->input);
11349
    size_t current = ctxt->input->cur - ctxt->input->base;
11350
11351
    xmlParserInputBufferPush(ctxt->input->buf, 0, "");
11352
                xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input,
11353
                                      base, current);
11354
      }
11355
  }
11356
        avail = ctxt->input->end - ctxt->input->cur;
11357
        if (avail < 1)
11358
      goto done;
11359
        switch (ctxt->instate) {
11360
            case XML_PARSER_EOF:
11361
          /*
11362
     * Document parsing is done !
11363
     */
11364
          goto done;
11365
            case XML_PARSER_START:
11366
    if (ctxt->charset == XML_CHAR_ENCODING_NONE) {
11367
        xmlChar start[4];
11368
        xmlCharEncoding enc;
11369
11370
        /*
11371
         * Very first chars read from the document flow.
11372
         */
11373
        if (avail < 4)
11374
      goto done;
11375
11376
        /*
11377
         * Get the 4 first bytes and decode the charset
11378
         * if enc != XML_CHAR_ENCODING_NONE
11379
         * plug some encoding conversion routines,
11380
         * else xmlSwitchEncoding will set to (default)
11381
         * UTF8.
11382
         */
11383
        start[0] = RAW;
11384
        start[1] = NXT(1);
11385
        start[2] = NXT(2);
11386
        start[3] = NXT(3);
11387
        enc = xmlDetectCharEncoding(start, 4);
11388
                    /*
11389
                     * We need more bytes to detect EBCDIC code pages.
11390
                     * See xmlDetectEBCDIC.
11391
                     */
11392
                    if ((enc == XML_CHAR_ENCODING_EBCDIC) &&
11393
                        (!terminate) && (avail < 200))
11394
                        goto done;
11395
        xmlSwitchEncoding(ctxt, enc);
11396
        break;
11397
    }
11398
11399
    if (avail < 2)
11400
        goto done;
11401
    cur = ctxt->input->cur[0];
11402
    next = ctxt->input->cur[1];
11403
    if (cur == 0) {
11404
        if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
11405
      ctxt->sax->setDocumentLocator(ctxt->userData,
11406
                  &xmlDefaultSAXLocator);
11407
        xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
11408
        xmlHaltParser(ctxt);
11409
#ifdef DEBUG_PUSH
11410
        xmlGenericError(xmlGenericErrorContext,
11411
          "PP: entering EOF\n");
11412
#endif
11413
        if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
11414
      ctxt->sax->endDocument(ctxt->userData);
11415
        goto done;
11416
    }
11417
          if ((cur == '<') && (next == '?')) {
11418
        /* PI or XML decl */
11419
        if (avail < 5) goto done;
11420
        if ((!terminate) &&
11421
                        (!xmlParseLookupString(ctxt, 2, "?>", 2)))
11422
      goto done;
11423
        if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
11424
      ctxt->sax->setDocumentLocator(ctxt->userData,
11425
                  &xmlDefaultSAXLocator);
11426
        if ((ctxt->input->cur[2] == 'x') &&
11427
      (ctxt->input->cur[3] == 'm') &&
11428
      (ctxt->input->cur[4] == 'l') &&
11429
      (IS_BLANK_CH(ctxt->input->cur[5]))) {
11430
      ret += 5;
11431
#ifdef DEBUG_PUSH
11432
      xmlGenericError(xmlGenericErrorContext,
11433
        "PP: Parsing XML Decl\n");
11434
#endif
11435
      xmlParseXMLDecl(ctxt);
11436
      if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
11437
          /*
11438
           * The XML REC instructs us to stop parsing right
11439
           * here
11440
           */
11441
          xmlHaltParser(ctxt);
11442
          return(0);
11443
      }
11444
      ctxt->standalone = ctxt->input->standalone;
11445
      if ((ctxt->encoding == NULL) &&
11446
          (ctxt->input->encoding != NULL))
11447
          ctxt->encoding = xmlStrdup(ctxt->input->encoding);
11448
      if ((ctxt->sax) && (ctxt->sax->startDocument) &&
11449
          (!ctxt->disableSAX))
11450
          ctxt->sax->startDocument(ctxt->userData);
11451
      ctxt->instate = XML_PARSER_MISC;
11452
#ifdef DEBUG_PUSH
11453
      xmlGenericError(xmlGenericErrorContext,
11454
        "PP: entering MISC\n");
11455
#endif
11456
        } else {
11457
      ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
11458
      if ((ctxt->sax) && (ctxt->sax->startDocument) &&
11459
          (!ctxt->disableSAX))
11460
          ctxt->sax->startDocument(ctxt->userData);
11461
      ctxt->instate = XML_PARSER_MISC;
11462
#ifdef DEBUG_PUSH
11463
      xmlGenericError(xmlGenericErrorContext,
11464
        "PP: entering MISC\n");
11465
#endif
11466
        }
11467
    } else {
11468
        if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
11469
      ctxt->sax->setDocumentLocator(ctxt->userData,
11470
                  &xmlDefaultSAXLocator);
11471
        ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
11472
        if (ctxt->version == NULL) {
11473
            xmlErrMemory(ctxt, NULL);
11474
      break;
11475
        }
11476
        if ((ctxt->sax) && (ctxt->sax->startDocument) &&
11477
            (!ctxt->disableSAX))
11478
      ctxt->sax->startDocument(ctxt->userData);
11479
        ctxt->instate = XML_PARSER_MISC;
11480
#ifdef DEBUG_PUSH
11481
        xmlGenericError(xmlGenericErrorContext,
11482
          "PP: entering MISC\n");
11483
#endif
11484
    }
11485
    break;
11486
            case XML_PARSER_START_TAG: {
11487
          const xmlChar *name;
11488
    const xmlChar *prefix = NULL;
11489
    const xmlChar *URI = NULL;
11490
                int line = ctxt->input->line;
11491
    int nsNr = ctxt->nsNr;
11492
11493
    if ((avail < 2) && (ctxt->inputNr == 1))
11494
        goto done;
11495
    cur = ctxt->input->cur[0];
11496
          if (cur != '<') {
11497
        xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
11498
        xmlHaltParser(ctxt);
11499
        if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
11500
      ctxt->sax->endDocument(ctxt->userData);
11501
        goto done;
11502
    }
11503
    if ((!terminate) && (!xmlParseLookupGt(ctxt)))
11504
                    goto done;
11505
    if (ctxt->spaceNr == 0)
11506
        spacePush(ctxt, -1);
11507
    else if (*ctxt->space == -2)
11508
        spacePush(ctxt, -1);
11509
    else
11510
        spacePush(ctxt, *ctxt->space);
11511
#ifdef LIBXML_SAX1_ENABLED
11512
    if (ctxt->sax2)
11513
#endif /* LIBXML_SAX1_ENABLED */
11514
        name = xmlParseStartTag2(ctxt, &prefix, &URI, &tlen);
11515
#ifdef LIBXML_SAX1_ENABLED
11516
    else
11517
        name = xmlParseStartTag(ctxt);
11518
#endif /* LIBXML_SAX1_ENABLED */
11519
    if (ctxt->instate == XML_PARSER_EOF)
11520
        goto done;
11521
    if (name == NULL) {
11522
        spacePop(ctxt);
11523
        xmlHaltParser(ctxt);
11524
        if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
11525
      ctxt->sax->endDocument(ctxt->userData);
11526
        goto done;
11527
    }
11528
#ifdef LIBXML_VALID_ENABLED
11529
    /*
11530
     * [ VC: Root Element Type ]
11531
     * The Name in the document type declaration must match
11532
     * the element type of the root element.
11533
     */
11534
    if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
11535
        ctxt->node && (ctxt->node == ctxt->myDoc->children))
11536
        ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
11537
#endif /* LIBXML_VALID_ENABLED */
11538
11539
    /*
11540
     * Check for an Empty Element.
11541
     */
11542
    if ((RAW == '/') && (NXT(1) == '>')) {
11543
        SKIP(2);
11544
11545
        if (ctxt->sax2) {
11546
      if ((ctxt->sax != NULL) &&
11547
          (ctxt->sax->endElementNs != NULL) &&
11548
          (!ctxt->disableSAX))
11549
          ctxt->sax->endElementNs(ctxt->userData, name,
11550
                                  prefix, URI);
11551
      if (ctxt->nsNr - nsNr > 0)
11552
          nsPop(ctxt, ctxt->nsNr - nsNr);
11553
#ifdef LIBXML_SAX1_ENABLED
11554
        } else {
11555
      if ((ctxt->sax != NULL) &&
11556
          (ctxt->sax->endElement != NULL) &&
11557
          (!ctxt->disableSAX))
11558
          ctxt->sax->endElement(ctxt->userData, name);
11559
#endif /* LIBXML_SAX1_ENABLED */
11560
        }
11561
        if (ctxt->instate == XML_PARSER_EOF)
11562
      goto done;
11563
        spacePop(ctxt);
11564
        if (ctxt->nameNr == 0) {
11565
      ctxt->instate = XML_PARSER_EPILOG;
11566
        } else {
11567
      ctxt->instate = XML_PARSER_CONTENT;
11568
        }
11569
        break;
11570
    }
11571
    if (RAW == '>') {
11572
        NEXT;
11573
    } else {
11574
        xmlFatalErrMsgStr(ctxt, XML_ERR_GT_REQUIRED,
11575
           "Couldn't find end of Start Tag %s\n",
11576
           name);
11577
        nodePop(ctxt);
11578
        spacePop(ctxt);
11579
    }
11580
                nameNsPush(ctxt, name, prefix, URI, line, ctxt->nsNr - nsNr);
11581
11582
    ctxt->instate = XML_PARSER_CONTENT;
11583
                break;
11584
      }
11585
            case XML_PARSER_CONTENT: {
11586
    if ((avail < 2) && (ctxt->inputNr == 1))
11587
        goto done;
11588
    cur = ctxt->input->cur[0];
11589
    next = ctxt->input->cur[1];
11590
11591
    if ((cur == '<') && (next == '/')) {
11592
        ctxt->instate = XML_PARSER_END_TAG;
11593
        break;
11594
          } else if ((cur == '<') && (next == '?')) {
11595
        if ((!terminate) &&
11596
            (!xmlParseLookupString(ctxt, 2, "?>", 2)))
11597
      goto done;
11598
        xmlParsePI(ctxt);
11599
        ctxt->instate = XML_PARSER_CONTENT;
11600
    } else if ((cur == '<') && (next != '!')) {
11601
        ctxt->instate = XML_PARSER_START_TAG;
11602
        break;
11603
    } else if ((cur == '<') && (next == '!') &&
11604
               (ctxt->input->cur[2] == '-') &&
11605
         (ctxt->input->cur[3] == '-')) {
11606
        if ((!terminate) &&
11607
            (!xmlParseLookupString(ctxt, 4, "-->", 3)))
11608
      goto done;
11609
        xmlParseComment(ctxt);
11610
        ctxt->instate = XML_PARSER_CONTENT;
11611
    } else if ((cur == '<') && (ctxt->input->cur[1] == '!') &&
11612
        (ctxt->input->cur[2] == '[') &&
11613
        (ctxt->input->cur[3] == 'C') &&
11614
        (ctxt->input->cur[4] == 'D') &&
11615
        (ctxt->input->cur[5] == 'A') &&
11616
        (ctxt->input->cur[6] == 'T') &&
11617
        (ctxt->input->cur[7] == 'A') &&
11618
        (ctxt->input->cur[8] == '[')) {
11619
        SKIP(9);
11620
        ctxt->instate = XML_PARSER_CDATA_SECTION;
11621
        break;
11622
    } else if ((cur == '<') && (next == '!') &&
11623
               (avail < 9)) {
11624
        goto done;
11625
    } else if (cur == '<') {
11626
        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
11627
                    "detected an error in element content\n");
11628
                    SKIP(1);
11629
    } else if (cur == '&') {
11630
        if ((!terminate) && (!xmlParseLookupChar(ctxt, ';')))
11631
      goto done;
11632
        xmlParseReference(ctxt);
11633
    } else {
11634
        /* TODO Avoid the extra copy, handle directly !!! */
11635
        /*
11636
         * Goal of the following test is:
11637
         *  - minimize calls to the SAX 'character' callback
11638
         *    when they are mergeable
11639
         *  - handle an problem for isBlank when we only parse
11640
         *    a sequence of blank chars and the next one is
11641
         *    not available to check against '<' presence.
11642
         *  - tries to homogenize the differences in SAX
11643
         *    callbacks between the push and pull versions
11644
         *    of the parser.
11645
         */
11646
        if ((ctxt->inputNr == 1) &&
11647
            (avail < XML_PARSER_BIG_BUFFER_SIZE)) {
11648
      if ((!terminate) && (!xmlParseLookupCharData(ctxt)))
11649
          goto done;
11650
                    }
11651
                    ctxt->checkIndex = 0;
11652
        xmlParseCharData(ctxt, 0);
11653
    }
11654
    break;
11655
      }
11656
            case XML_PARSER_END_TAG:
11657
    if (avail < 2)
11658
        goto done;
11659
    if ((!terminate) && (!xmlParseLookupChar(ctxt, '>')))
11660
        goto done;
11661
    if (ctxt->sax2) {
11662
              xmlParseEndTag2(ctxt, &ctxt->pushTab[ctxt->nameNr - 1]);
11663
        nameNsPop(ctxt);
11664
    }
11665
#ifdef LIBXML_SAX1_ENABLED
11666
      else
11667
        xmlParseEndTag1(ctxt, 0);
11668
#endif /* LIBXML_SAX1_ENABLED */
11669
    if (ctxt->instate == XML_PARSER_EOF) {
11670
        /* Nothing */
11671
    } else if (ctxt->nameNr == 0) {
11672
        ctxt->instate = XML_PARSER_EPILOG;
11673
    } else {
11674
        ctxt->instate = XML_PARSER_CONTENT;
11675
    }
11676
    break;
11677
            case XML_PARSER_CDATA_SECTION: {
11678
          /*
11679
     * The Push mode need to have the SAX callback for
11680
     * cdataBlock merge back contiguous callbacks.
11681
     */
11682
    const xmlChar *term;
11683
11684
                if (terminate) {
11685
                    /*
11686
                     * Don't call xmlParseLookupString. If 'terminate'
11687
                     * is set, checkIndex is invalid.
11688
                     */
11689
                    term = BAD_CAST strstr((const char *) ctxt->input->cur,
11690
                                           "]]>");
11691
                } else {
11692
        term = xmlParseLookupString(ctxt, 0, "]]>", 3);
11693
                }
11694
11695
    if (term == NULL) {
11696
        int tmp, size;
11697
11698
                    if (terminate) {
11699
                        /* Unfinished CDATA section */
11700
                        size = ctxt->input->end - ctxt->input->cur;
11701
                    } else {
11702
                        if (avail < XML_PARSER_BIG_BUFFER_SIZE + 2)
11703
                            goto done;
11704
                        ctxt->checkIndex = 0;
11705
                        /* XXX: Why don't we pass the full buffer? */
11706
                        size = XML_PARSER_BIG_BUFFER_SIZE;
11707
                    }
11708
                    tmp = xmlCheckCdataPush(ctxt->input->cur, size, 0);
11709
                    if (tmp <= 0) {
11710
                        tmp = -tmp;
11711
                        ctxt->input->cur += tmp;
11712
                        goto encoding_error;
11713
                    }
11714
                    if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
11715
                        if (ctxt->sax->cdataBlock != NULL)
11716
                            ctxt->sax->cdataBlock(ctxt->userData,
11717
                                                  ctxt->input->cur, tmp);
11718
                        else if (ctxt->sax->characters != NULL)
11719
                            ctxt->sax->characters(ctxt->userData,
11720
                                                  ctxt->input->cur, tmp);
11721
                    }
11722
                    if (ctxt->instate == XML_PARSER_EOF)
11723
                        goto done;
11724
                    SKIPL(tmp);
11725
    } else {
11726
                    int base = term - CUR_PTR;
11727
        int tmp;
11728
11729
        tmp = xmlCheckCdataPush(ctxt->input->cur, base, 1);
11730
        if ((tmp < 0) || (tmp != base)) {
11731
      tmp = -tmp;
11732
      ctxt->input->cur += tmp;
11733
      goto encoding_error;
11734
        }
11735
        if ((ctxt->sax != NULL) && (base == 0) &&
11736
            (ctxt->sax->cdataBlock != NULL) &&
11737
            (!ctxt->disableSAX)) {
11738
      /*
11739
       * Special case to provide identical behaviour
11740
       * between pull and push parsers on enpty CDATA
11741
       * sections
11742
       */
11743
       if ((ctxt->input->cur - ctxt->input->base >= 9) &&
11744
           (!strncmp((const char *)&ctxt->input->cur[-9],
11745
                     "<![CDATA[", 9)))
11746
           ctxt->sax->cdataBlock(ctxt->userData,
11747
                                 BAD_CAST "", 0);
11748
        } else if ((ctxt->sax != NULL) && (base > 0) &&
11749
      (!ctxt->disableSAX)) {
11750
      if (ctxt->sax->cdataBlock != NULL)
11751
          ctxt->sax->cdataBlock(ctxt->userData,
11752
              ctxt->input->cur, base);
11753
      else if (ctxt->sax->characters != NULL)
11754
          ctxt->sax->characters(ctxt->userData,
11755
              ctxt->input->cur, base);
11756
        }
11757
        if (ctxt->instate == XML_PARSER_EOF)
11758
      goto done;
11759
        SKIPL(base + 3);
11760
        ctxt->instate = XML_PARSER_CONTENT;
11761
#ifdef DEBUG_PUSH
11762
        xmlGenericError(xmlGenericErrorContext,
11763
          "PP: entering CONTENT\n");
11764
#endif
11765
    }
11766
    break;
11767
      }
11768
            case XML_PARSER_MISC:
11769
            case XML_PARSER_PROLOG:
11770
            case XML_PARSER_EPILOG:
11771
    SKIP_BLANKS;
11772
                avail = ctxt->input->end - ctxt->input->cur;
11773
    if (avail < 2)
11774
        goto done;
11775
    cur = ctxt->input->cur[0];
11776
    next = ctxt->input->cur[1];
11777
          if ((cur == '<') && (next == '?')) {
11778
        if ((!terminate) &&
11779
                        (!xmlParseLookupString(ctxt, 2, "?>", 2)))
11780
      goto done;
11781
#ifdef DEBUG_PUSH
11782
        xmlGenericError(xmlGenericErrorContext,
11783
          "PP: Parsing PI\n");
11784
#endif
11785
        xmlParsePI(ctxt);
11786
        if (ctxt->instate == XML_PARSER_EOF)
11787
      goto done;
11788
    } else if ((cur == '<') && (next == '!') &&
11789
        (ctxt->input->cur[2] == '-') &&
11790
        (ctxt->input->cur[3] == '-')) {
11791
        if ((!terminate) &&
11792
                        (!xmlParseLookupString(ctxt, 4, "-->", 3)))
11793
      goto done;
11794
#ifdef DEBUG_PUSH
11795
        xmlGenericError(xmlGenericErrorContext,
11796
          "PP: Parsing Comment\n");
11797
#endif
11798
        xmlParseComment(ctxt);
11799
        if (ctxt->instate == XML_PARSER_EOF)
11800
      goto done;
11801
    } else if ((ctxt->instate == XML_PARSER_MISC) &&
11802
                    (cur == '<') && (next == '!') &&
11803
        (ctxt->input->cur[2] == 'D') &&
11804
        (ctxt->input->cur[3] == 'O') &&
11805
        (ctxt->input->cur[4] == 'C') &&
11806
        (ctxt->input->cur[5] == 'T') &&
11807
        (ctxt->input->cur[6] == 'Y') &&
11808
        (ctxt->input->cur[7] == 'P') &&
11809
        (ctxt->input->cur[8] == 'E')) {
11810
        if ((!terminate) && (!xmlParseLookupGt(ctxt)))
11811
                        goto done;
11812
#ifdef DEBUG_PUSH
11813
        xmlGenericError(xmlGenericErrorContext,
11814
          "PP: Parsing internal subset\n");
11815
#endif
11816
        ctxt->inSubset = 1;
11817
        xmlParseDocTypeDecl(ctxt);
11818
        if (ctxt->instate == XML_PARSER_EOF)
11819
      goto done;
11820
        if (RAW == '[') {
11821
      ctxt->instate = XML_PARSER_DTD;
11822
#ifdef DEBUG_PUSH
11823
      xmlGenericError(xmlGenericErrorContext,
11824
        "PP: entering DTD\n");
11825
#endif
11826
        } else {
11827
      /*
11828
       * Create and update the external subset.
11829
       */
11830
      ctxt->inSubset = 2;
11831
      if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
11832
          (ctxt->sax->externalSubset != NULL))
11833
          ctxt->sax->externalSubset(ctxt->userData,
11834
            ctxt->intSubName, ctxt->extSubSystem,
11835
            ctxt->extSubURI);
11836
      ctxt->inSubset = 0;
11837
      xmlCleanSpecialAttr(ctxt);
11838
      ctxt->instate = XML_PARSER_PROLOG;
11839
#ifdef DEBUG_PUSH
11840
      xmlGenericError(xmlGenericErrorContext,
11841
        "PP: entering PROLOG\n");
11842
#endif
11843
        }
11844
    } else if ((cur == '<') && (next == '!') &&
11845
               (avail <
11846
                            (ctxt->instate == XML_PARSER_MISC ? 9 : 4))) {
11847
        goto done;
11848
    } else if (ctxt->instate == XML_PARSER_EPILOG) {
11849
        xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
11850
        xmlHaltParser(ctxt);
11851
#ifdef DEBUG_PUSH
11852
        xmlGenericError(xmlGenericErrorContext,
11853
          "PP: entering EOF\n");
11854
#endif
11855
        if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
11856
      ctxt->sax->endDocument(ctxt->userData);
11857
        goto done;
11858
                } else {
11859
        ctxt->instate = XML_PARSER_START_TAG;
11860
#ifdef DEBUG_PUSH
11861
        xmlGenericError(xmlGenericErrorContext,
11862
          "PP: entering START_TAG\n");
11863
#endif
11864
    }
11865
    break;
11866
            case XML_PARSER_DTD: {
11867
                if ((!terminate) && (!xmlParseLookupInternalSubset(ctxt)))
11868
                    goto done;
11869
    xmlParseInternalSubset(ctxt);
11870
    if (ctxt->instate == XML_PARSER_EOF)
11871
        goto done;
11872
    ctxt->inSubset = 2;
11873
    if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
11874
        (ctxt->sax->externalSubset != NULL))
11875
        ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
11876
          ctxt->extSubSystem, ctxt->extSubURI);
11877
    ctxt->inSubset = 0;
11878
    xmlCleanSpecialAttr(ctxt);
11879
    if (ctxt->instate == XML_PARSER_EOF)
11880
        goto done;
11881
    ctxt->instate = XML_PARSER_PROLOG;
11882
#ifdef DEBUG_PUSH
11883
    xmlGenericError(xmlGenericErrorContext,
11884
      "PP: entering PROLOG\n");
11885
#endif
11886
                break;
11887
      }
11888
            case XML_PARSER_COMMENT:
11889
    xmlGenericError(xmlGenericErrorContext,
11890
      "PP: internal error, state == COMMENT\n");
11891
    ctxt->instate = XML_PARSER_CONTENT;
11892
#ifdef DEBUG_PUSH
11893
    xmlGenericError(xmlGenericErrorContext,
11894
      "PP: entering CONTENT\n");
11895
#endif
11896
    break;
11897
            case XML_PARSER_IGNORE:
11898
    xmlGenericError(xmlGenericErrorContext,
11899
      "PP: internal error, state == IGNORE");
11900
          ctxt->instate = XML_PARSER_DTD;
11901
#ifdef DEBUG_PUSH
11902
    xmlGenericError(xmlGenericErrorContext,
11903
      "PP: entering DTD\n");
11904
#endif
11905
          break;
11906
            case XML_PARSER_PI:
11907
    xmlGenericError(xmlGenericErrorContext,
11908
      "PP: internal error, state == PI\n");
11909
    ctxt->instate = XML_PARSER_CONTENT;
11910
#ifdef DEBUG_PUSH
11911
    xmlGenericError(xmlGenericErrorContext,
11912
      "PP: entering CONTENT\n");
11913
#endif
11914
    break;
11915
            case XML_PARSER_ENTITY_DECL:
11916
    xmlGenericError(xmlGenericErrorContext,
11917
      "PP: internal error, state == ENTITY_DECL\n");
11918
    ctxt->instate = XML_PARSER_DTD;
11919
#ifdef DEBUG_PUSH
11920
    xmlGenericError(xmlGenericErrorContext,
11921
      "PP: entering DTD\n");
11922
#endif
11923
    break;
11924
            case XML_PARSER_ENTITY_VALUE:
11925
    xmlGenericError(xmlGenericErrorContext,
11926
      "PP: internal error, state == ENTITY_VALUE\n");
11927
    ctxt->instate = XML_PARSER_CONTENT;
11928
#ifdef DEBUG_PUSH
11929
    xmlGenericError(xmlGenericErrorContext,
11930
      "PP: entering DTD\n");
11931
#endif
11932
    break;
11933
            case XML_PARSER_ATTRIBUTE_VALUE:
11934
    xmlGenericError(xmlGenericErrorContext,
11935
      "PP: internal error, state == ATTRIBUTE_VALUE\n");
11936
    ctxt->instate = XML_PARSER_START_TAG;
11937
#ifdef DEBUG_PUSH
11938
    xmlGenericError(xmlGenericErrorContext,
11939
      "PP: entering START_TAG\n");
11940
#endif
11941
    break;
11942
            case XML_PARSER_SYSTEM_LITERAL:
11943
    xmlGenericError(xmlGenericErrorContext,
11944
      "PP: internal error, state == SYSTEM_LITERAL\n");
11945
    ctxt->instate = XML_PARSER_START_TAG;
11946
#ifdef DEBUG_PUSH
11947
    xmlGenericError(xmlGenericErrorContext,
11948
      "PP: entering START_TAG\n");
11949
#endif
11950
    break;
11951
            case XML_PARSER_PUBLIC_LITERAL:
11952
    xmlGenericError(xmlGenericErrorContext,
11953
      "PP: internal error, state == PUBLIC_LITERAL\n");
11954
    ctxt->instate = XML_PARSER_START_TAG;
11955
#ifdef DEBUG_PUSH
11956
    xmlGenericError(xmlGenericErrorContext,
11957
      "PP: entering START_TAG\n");
11958
#endif
11959
    break;
11960
  }
11961
    }
11962
done:
11963
#ifdef DEBUG_PUSH
11964
    xmlGenericError(xmlGenericErrorContext, "PP: done %d\n", ret);
11965
#endif
11966
    return(ret);
11967
encoding_error:
11968
    if (ctxt->input->end - ctxt->input->cur < 4) {
11969
  __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
11970
         "Input is not proper UTF-8, indicate encoding !\n",
11971
         NULL, NULL);
11972
    } else {
11973
        char buffer[150];
11974
11975
  snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
11976
      ctxt->input->cur[0], ctxt->input->cur[1],
11977
      ctxt->input->cur[2], ctxt->input->cur[3]);
11978
  __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
11979
         "Input is not proper UTF-8, indicate encoding !\n%s",
11980
         BAD_CAST buffer, NULL);
11981
    }
11982
    return(0);
11983
}
11984
11985
/**
11986
 * xmlParseChunk:
11987
 * @ctxt:  an XML parser context
11988
 * @chunk:  an char array
11989
 * @size:  the size in byte of the chunk
11990
 * @terminate:  last chunk indicator
11991
 *
11992
 * Parse a Chunk of memory
11993
 *
11994
 * Returns zero if no error, the xmlParserErrors otherwise.
11995
 */
11996
int
11997
xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
11998
              int terminate) {
11999
    int end_in_lf = 0;
12000
    int remain = 0;
12001
12002
    if (ctxt == NULL)
12003
        return(XML_ERR_INTERNAL_ERROR);
12004
    if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
12005
        return(ctxt->errNo);
12006
    if (ctxt->instate == XML_PARSER_EOF)
12007
        return(-1);
12008
    if (ctxt->input == NULL)
12009
        return(-1);
12010
12011
    ctxt->progressive = 1;
12012
    if (ctxt->instate == XML_PARSER_START)
12013
        xmlDetectSAX2(ctxt);
12014
    if ((size > 0) && (chunk != NULL) && (!terminate) &&
12015
        (chunk[size - 1] == '\r')) {
12016
  end_in_lf = 1;
12017
  size--;
12018
    }
12019
12020
xmldecl_done:
12021
12022
    if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
12023
        (ctxt->input->buf != NULL) && (ctxt->instate != XML_PARSER_EOF))  {
12024
  size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer, ctxt->input);
12025
  size_t cur = ctxt->input->cur - ctxt->input->base;
12026
  int res;
12027
12028
        /*
12029
         * Specific handling if we autodetected an encoding, we should not
12030
         * push more than the first line ... which depend on the encoding
12031
         * And only push the rest once the final encoding was detected
12032
         */
12033
        if ((ctxt->instate == XML_PARSER_START) && (ctxt->input != NULL) &&
12034
            (ctxt->input->buf != NULL) && (ctxt->input->buf->encoder != NULL)) {
12035
            unsigned int len = 45;
12036
12037
            if ((xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
12038
                               BAD_CAST "UTF-16")) ||
12039
                (xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
12040
                               BAD_CAST "UTF16")))
12041
                len = 90;
12042
            else if ((xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
12043
                                    BAD_CAST "UCS-4")) ||
12044
                     (xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
12045
                                    BAD_CAST "UCS4")))
12046
                len = 180;
12047
12048
            if (ctxt->input->buf->rawconsumed < len)
12049
                len -= ctxt->input->buf->rawconsumed;
12050
12051
            /*
12052
             * Change size for reading the initial declaration only
12053
             * if size is greater than len. Otherwise, memmove in xmlBufferAdd
12054
             * will blindly copy extra bytes from memory.
12055
             */
12056
            if ((unsigned int) size > len) {
12057
                remain = size - len;
12058
                size = len;
12059
            } else {
12060
                remain = 0;
12061
            }
12062
        }
12063
  res = xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
12064
        xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur);
12065
  if (res < 0) {
12066
      ctxt->errNo = XML_PARSER_EOF;
12067
      xmlHaltParser(ctxt);
12068
      return (XML_PARSER_EOF);
12069
  }
12070
#ifdef DEBUG_PUSH
12071
  xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
12072
#endif
12073
12074
    } else if (ctxt->instate != XML_PARSER_EOF) {
12075
  if ((ctxt->input != NULL) && ctxt->input->buf != NULL) {
12076
      xmlParserInputBufferPtr in = ctxt->input->buf;
12077
      if ((in->encoder != NULL) && (in->buffer != NULL) &&
12078
        (in->raw != NULL)) {
12079
    int nbchars;
12080
    size_t base = xmlBufGetInputBase(in->buffer, ctxt->input);
12081
    size_t current = ctxt->input->cur - ctxt->input->base;
12082
12083
    nbchars = xmlCharEncInput(in, terminate);
12084
    xmlBufSetInputBaseCur(in->buffer, ctxt->input, base, current);
12085
    if (nbchars < 0) {
12086
        /* TODO 2.6.0 */
12087
        xmlGenericError(xmlGenericErrorContext,
12088
            "xmlParseChunk: encoder error\n");
12089
                    xmlHaltParser(ctxt);
12090
        return(XML_ERR_INVALID_ENCODING);
12091
    }
12092
      }
12093
  }
12094
    }
12095
12096
    if (remain != 0) {
12097
        xmlParseTryOrFinish(ctxt, 0);
12098
    } else {
12099
        xmlParseTryOrFinish(ctxt, terminate);
12100
    }
12101
    if (ctxt->instate == XML_PARSER_EOF)
12102
        return(ctxt->errNo);
12103
12104
    if ((ctxt->input != NULL) &&
12105
         (((ctxt->input->end - ctxt->input->cur) > XML_MAX_LOOKUP_LIMIT) ||
12106
         ((ctxt->input->cur - ctxt->input->base) > XML_MAX_LOOKUP_LIMIT)) &&
12107
        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
12108
        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "Huge input lookup");
12109
        xmlHaltParser(ctxt);
12110
    }
12111
    if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
12112
        return(ctxt->errNo);
12113
12114
    if (remain != 0) {
12115
        chunk += size;
12116
        size = remain;
12117
        remain = 0;
12118
        goto xmldecl_done;
12119
    }
12120
    if ((end_in_lf == 1) && (ctxt->input != NULL) &&
12121
        (ctxt->input->buf != NULL)) {
12122
  size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer,
12123
           ctxt->input);
12124
  size_t current = ctxt->input->cur - ctxt->input->base;
12125
12126
  xmlParserInputBufferPush(ctxt->input->buf, 1, "\r");
12127
12128
  xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input,
12129
            base, current);
12130
    }
12131
    if (terminate) {
12132
  /*
12133
   * Check for termination
12134
   */
12135
  if ((ctxt->instate != XML_PARSER_EOF) &&
12136
      (ctxt->instate != XML_PARSER_EPILOG)) {
12137
      xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
12138
  }
12139
  if ((ctxt->instate == XML_PARSER_EPILOG) &&
12140
            (ctxt->input->cur < ctxt->input->end)) {
12141
      xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
12142
  }
12143
  if (ctxt->instate != XML_PARSER_EOF) {
12144
      if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
12145
    ctxt->sax->endDocument(ctxt->userData);
12146
  }
12147
  ctxt->instate = XML_PARSER_EOF;
12148
    }
12149
    if (ctxt->wellFormed == 0)
12150
  return((xmlParserErrors) ctxt->errNo);
12151
    else
12152
        return(0);
12153
}
12154
12155
/************************************************************************
12156
 *                  *
12157
 *    I/O front end functions to the parser     *
12158
 *                  *
12159
 ************************************************************************/
12160
12161
/**
12162
 * xmlCreatePushParserCtxt:
12163
 * @sax:  a SAX handler
12164
 * @user_data:  The user data returned on SAX callbacks
12165
 * @chunk:  a pointer to an array of chars
12166
 * @size:  number of chars in the array
12167
 * @filename:  an optional file name or URI
12168
 *
12169
 * Create a parser context for using the XML parser in push mode.
12170
 * If @buffer and @size are non-NULL, the data is used to detect
12171
 * the encoding.  The remaining characters will be parsed so they
12172
 * don't need to be fed in again through xmlParseChunk.
12173
 * To allow content encoding detection, @size should be >= 4
12174
 * The value of @filename is used for fetching external entities
12175
 * and error/warning reports.
12176
 *
12177
 * Returns the new parser context or NULL
12178
 */
12179
12180
xmlParserCtxtPtr
12181
xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
12182
                        const char *chunk, int size, const char *filename) {
12183
    xmlParserCtxtPtr ctxt;
12184
    xmlParserInputPtr inputStream;
12185
    xmlParserInputBufferPtr buf;
12186
12187
    buf = xmlAllocParserInputBuffer(XML_CHAR_ENCODING_NONE);
12188
    if (buf == NULL) return(NULL);
12189
12190
    ctxt = xmlNewSAXParserCtxt(sax, user_data);
12191
    if (ctxt == NULL) {
12192
        xmlErrMemory(NULL, "creating parser: out of memory\n");
12193
  xmlFreeParserInputBuffer(buf);
12194
  return(NULL);
12195
    }
12196
    ctxt->dictNames = 1;
12197
    if (filename == NULL) {
12198
  ctxt->directory = NULL;
12199
    } else {
12200
        ctxt->directory = xmlParserGetDirectory(filename);
12201
    }
12202
12203
    inputStream = xmlNewInputStream(ctxt);
12204
    if (inputStream == NULL) {
12205
  xmlFreeParserCtxt(ctxt);
12206
  xmlFreeParserInputBuffer(buf);
12207
  return(NULL);
12208
    }
12209
12210
    if (filename == NULL)
12211
  inputStream->filename = NULL;
12212
    else {
12213
  inputStream->filename = (char *)
12214
      xmlCanonicPath((const xmlChar *) filename);
12215
  if (inputStream->filename == NULL) {
12216
            xmlFreeInputStream(inputStream);
12217
      xmlFreeParserCtxt(ctxt);
12218
      xmlFreeParserInputBuffer(buf);
12219
      return(NULL);
12220
  }
12221
    }
12222
    inputStream->buf = buf;
12223
    xmlBufResetInput(inputStream->buf->buffer, inputStream);
12224
    inputPush(ctxt, inputStream);
12225
12226
    /*
12227
     * If the caller didn't provide an initial 'chunk' for determining
12228
     * the encoding, we set the context to XML_CHAR_ENCODING_NONE so
12229
     * that it can be automatically determined later
12230
     */
12231
    ctxt->charset = XML_CHAR_ENCODING_NONE;
12232
12233
    if ((size != 0) && (chunk != NULL) &&
12234
        (ctxt->input != NULL) && (ctxt->input->buf != NULL)) {
12235
  size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer, ctxt->input);
12236
  size_t cur = ctxt->input->cur - ctxt->input->base;
12237
12238
  xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
12239
12240
        xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur);
12241
#ifdef DEBUG_PUSH
12242
  xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
12243
#endif
12244
    }
12245
12246
    return(ctxt);
12247
}
12248
#endif /* LIBXML_PUSH_ENABLED */
12249
12250
/**
12251
 * xmlStopParser:
12252
 * @ctxt:  an XML parser context
12253
 *
12254
 * Blocks further parser processing
12255
 */
12256
void
12257
8.58M
xmlStopParser(xmlParserCtxtPtr ctxt) {
12258
8.58M
    if (ctxt == NULL)
12259
8.58M
        return;
12260
607
    xmlHaltParser(ctxt);
12261
607
    ctxt->errNo = XML_ERR_USER_STOP;
12262
607
}
12263
12264
/**
12265
 * xmlCreateIOParserCtxt:
12266
 * @sax:  a SAX handler
12267
 * @user_data:  The user data returned on SAX callbacks
12268
 * @ioread:  an I/O read function
12269
 * @ioclose:  an I/O close function
12270
 * @ioctx:  an I/O handler
12271
 * @enc:  the charset encoding if known
12272
 *
12273
 * Create a parser context for using the XML parser with an existing
12274
 * I/O stream
12275
 *
12276
 * Returns the new parser context or NULL
12277
 */
12278
xmlParserCtxtPtr
12279
xmlCreateIOParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
12280
  xmlInputReadCallback   ioread, xmlInputCloseCallback  ioclose,
12281
0
  void *ioctx, xmlCharEncoding enc) {
12282
0
    xmlParserCtxtPtr ctxt;
12283
0
    xmlParserInputPtr inputStream;
12284
0
    xmlParserInputBufferPtr buf;
12285
12286
0
    if (ioread == NULL) return(NULL);
12287
12288
0
    buf = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx, enc);
12289
0
    if (buf == NULL) {
12290
0
        if (ioclose != NULL)
12291
0
            ioclose(ioctx);
12292
0
        return (NULL);
12293
0
    }
12294
12295
0
    ctxt = xmlNewSAXParserCtxt(sax, user_data);
12296
0
    if (ctxt == NULL) {
12297
0
  xmlFreeParserInputBuffer(buf);
12298
0
  return(NULL);
12299
0
    }
12300
12301
0
    inputStream = xmlNewIOInputStream(ctxt, buf, enc);
12302
0
    if (inputStream == NULL) {
12303
0
  xmlFreeParserCtxt(ctxt);
12304
0
  return(NULL);
12305
0
    }
12306
0
    inputPush(ctxt, inputStream);
12307
12308
0
    return(ctxt);
12309
0
}
12310
12311
#ifdef LIBXML_VALID_ENABLED
12312
/************************************************************************
12313
 *                  *
12314
 *    Front ends when parsing a DTD       *
12315
 *                  *
12316
 ************************************************************************/
12317
12318
/**
12319
 * xmlIOParseDTD:
12320
 * @sax:  the SAX handler block or NULL
12321
 * @input:  an Input Buffer
12322
 * @enc:  the charset encoding if known
12323
 *
12324
 * Load and parse a DTD
12325
 *
12326
 * Returns the resulting xmlDtdPtr or NULL in case of error.
12327
 * @input will be freed by the function in any case.
12328
 */
12329
12330
xmlDtdPtr
12331
xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input,
12332
        xmlCharEncoding enc) {
12333
    xmlDtdPtr ret = NULL;
12334
    xmlParserCtxtPtr ctxt;
12335
    xmlParserInputPtr pinput = NULL;
12336
    xmlChar start[4];
12337
12338
    if (input == NULL)
12339
  return(NULL);
12340
12341
    ctxt = xmlNewSAXParserCtxt(sax, NULL);
12342
    if (ctxt == NULL) {
12343
        xmlFreeParserInputBuffer(input);
12344
  return(NULL);
12345
    }
12346
12347
    /* We are loading a DTD */
12348
    ctxt->options |= XML_PARSE_DTDLOAD;
12349
12350
    xmlDetectSAX2(ctxt);
12351
12352
    /*
12353
     * generate a parser input from the I/O handler
12354
     */
12355
12356
    pinput = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
12357
    if (pinput == NULL) {
12358
        xmlFreeParserInputBuffer(input);
12359
  xmlFreeParserCtxt(ctxt);
12360
  return(NULL);
12361
    }
12362
12363
    /*
12364
     * plug some encoding conversion routines here.
12365
     */
12366
    if (xmlPushInput(ctxt, pinput) < 0) {
12367
  xmlFreeParserCtxt(ctxt);
12368
  return(NULL);
12369
    }
12370
    if (enc != XML_CHAR_ENCODING_NONE) {
12371
        xmlSwitchEncoding(ctxt, enc);
12372
    }
12373
12374
    pinput->filename = NULL;
12375
    pinput->line = 1;
12376
    pinput->col = 1;
12377
    pinput->base = ctxt->input->cur;
12378
    pinput->cur = ctxt->input->cur;
12379
    pinput->free = NULL;
12380
12381
    /*
12382
     * let's parse that entity knowing it's an external subset.
12383
     */
12384
    ctxt->inSubset = 2;
12385
    ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
12386
    if (ctxt->myDoc == NULL) {
12387
  xmlErrMemory(ctxt, "New Doc failed");
12388
  return(NULL);
12389
    }
12390
    ctxt->myDoc->properties = XML_DOC_INTERNAL;
12391
    ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
12392
                                 BAD_CAST "none", BAD_CAST "none");
12393
12394
    if ((enc == XML_CHAR_ENCODING_NONE) &&
12395
        ((ctxt->input->end - ctxt->input->cur) >= 4)) {
12396
  /*
12397
   * Get the 4 first bytes and decode the charset
12398
   * if enc != XML_CHAR_ENCODING_NONE
12399
   * plug some encoding conversion routines.
12400
   */
12401
  start[0] = RAW;
12402
  start[1] = NXT(1);
12403
  start[2] = NXT(2);
12404
  start[3] = NXT(3);
12405
  enc = xmlDetectCharEncoding(start, 4);
12406
  if (enc != XML_CHAR_ENCODING_NONE) {
12407
      xmlSwitchEncoding(ctxt, enc);
12408
  }
12409
    }
12410
12411
    xmlParseExternalSubset(ctxt, BAD_CAST "none", BAD_CAST "none");
12412
12413
    if (ctxt->myDoc != NULL) {
12414
  if (ctxt->wellFormed) {
12415
      ret = ctxt->myDoc->extSubset;
12416
      ctxt->myDoc->extSubset = NULL;
12417
      if (ret != NULL) {
12418
    xmlNodePtr tmp;
12419
12420
    ret->doc = NULL;
12421
    tmp = ret->children;
12422
    while (tmp != NULL) {
12423
        tmp->doc = NULL;
12424
        tmp = tmp->next;
12425
    }
12426
      }
12427
  } else {
12428
      ret = NULL;
12429
  }
12430
        xmlFreeDoc(ctxt->myDoc);
12431
        ctxt->myDoc = NULL;
12432
    }
12433
    xmlFreeParserCtxt(ctxt);
12434
12435
    return(ret);
12436
}
12437
12438
/**
12439
 * xmlSAXParseDTD:
12440
 * @sax:  the SAX handler block
12441
 * @ExternalID:  a NAME* containing the External ID of the DTD
12442
 * @SystemID:  a NAME* containing the URL to the DTD
12443
 *
12444
 * DEPRECATED: Don't use.
12445
 *
12446
 * Load and parse an external subset.
12447
 *
12448
 * Returns the resulting xmlDtdPtr or NULL in case of error.
12449
 */
12450
12451
xmlDtdPtr
12452
xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID,
12453
                          const xmlChar *SystemID) {
12454
    xmlDtdPtr ret = NULL;
12455
    xmlParserCtxtPtr ctxt;
12456
    xmlParserInputPtr input = NULL;
12457
    xmlCharEncoding enc;
12458
    xmlChar* systemIdCanonic;
12459
12460
    if ((ExternalID == NULL) && (SystemID == NULL)) return(NULL);
12461
12462
    ctxt = xmlNewSAXParserCtxt(sax, NULL);
12463
    if (ctxt == NULL) {
12464
  return(NULL);
12465
    }
12466
12467
    /* We are loading a DTD */
12468
    ctxt->options |= XML_PARSE_DTDLOAD;
12469
12470
    /*
12471
     * Canonicalise the system ID
12472
     */
12473
    systemIdCanonic = xmlCanonicPath(SystemID);
12474
    if ((SystemID != NULL) && (systemIdCanonic == NULL)) {
12475
  xmlFreeParserCtxt(ctxt);
12476
  return(NULL);
12477
    }
12478
12479
    /*
12480
     * Ask the Entity resolver to load the damn thing
12481
     */
12482
12483
    if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
12484
  input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID,
12485
                                   systemIdCanonic);
12486
    if (input == NULL) {
12487
  xmlFreeParserCtxt(ctxt);
12488
  if (systemIdCanonic != NULL)
12489
      xmlFree(systemIdCanonic);
12490
  return(NULL);
12491
    }
12492
12493
    /*
12494
     * plug some encoding conversion routines here.
12495
     */
12496
    if (xmlPushInput(ctxt, input) < 0) {
12497
  xmlFreeParserCtxt(ctxt);
12498
  if (systemIdCanonic != NULL)
12499
      xmlFree(systemIdCanonic);
12500
  return(NULL);
12501
    }
12502
    if ((ctxt->input->end - ctxt->input->cur) >= 4) {
12503
  enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
12504
  xmlSwitchEncoding(ctxt, enc);
12505
    }
12506
12507
    if (input->filename == NULL)
12508
  input->filename = (char *) systemIdCanonic;
12509
    else
12510
  xmlFree(systemIdCanonic);
12511
    input->line = 1;
12512
    input->col = 1;
12513
    input->base = ctxt->input->cur;
12514
    input->cur = ctxt->input->cur;
12515
    input->free = NULL;
12516
12517
    /*
12518
     * let's parse that entity knowing it's an external subset.
12519
     */
12520
    ctxt->inSubset = 2;
12521
    ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
12522
    if (ctxt->myDoc == NULL) {
12523
  xmlErrMemory(ctxt, "New Doc failed");
12524
  xmlFreeParserCtxt(ctxt);
12525
  return(NULL);
12526
    }
12527
    ctxt->myDoc->properties = XML_DOC_INTERNAL;
12528
    ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
12529
                                 ExternalID, SystemID);
12530
    xmlParseExternalSubset(ctxt, ExternalID, SystemID);
12531
12532
    if (ctxt->myDoc != NULL) {
12533
  if (ctxt->wellFormed) {
12534
      ret = ctxt->myDoc->extSubset;
12535
      ctxt->myDoc->extSubset = NULL;
12536
      if (ret != NULL) {
12537
    xmlNodePtr tmp;
12538
12539
    ret->doc = NULL;
12540
    tmp = ret->children;
12541
    while (tmp != NULL) {
12542
        tmp->doc = NULL;
12543
        tmp = tmp->next;
12544
    }
12545
      }
12546
  } else {
12547
      ret = NULL;
12548
  }
12549
        xmlFreeDoc(ctxt->myDoc);
12550
        ctxt->myDoc = NULL;
12551
    }
12552
    xmlFreeParserCtxt(ctxt);
12553
12554
    return(ret);
12555
}
12556
12557
12558
/**
12559
 * xmlParseDTD:
12560
 * @ExternalID:  a NAME* containing the External ID of the DTD
12561
 * @SystemID:  a NAME* containing the URL to the DTD
12562
 *
12563
 * Load and parse an external subset.
12564
 *
12565
 * Returns the resulting xmlDtdPtr or NULL in case of error.
12566
 */
12567
12568
xmlDtdPtr
12569
xmlParseDTD(const xmlChar *ExternalID, const xmlChar *SystemID) {
12570
    return(xmlSAXParseDTD(NULL, ExternalID, SystemID));
12571
}
12572
#endif /* LIBXML_VALID_ENABLED */
12573
12574
/************************************************************************
12575
 *                  *
12576
 *    Front ends when parsing an Entity     *
12577
 *                  *
12578
 ************************************************************************/
12579
12580
/**
12581
 * xmlParseCtxtExternalEntity:
12582
 * @ctx:  the existing parsing context
12583
 * @URL:  the URL for the entity to load
12584
 * @ID:  the System ID for the entity to load
12585
 * @lst:  the return value for the set of parsed nodes
12586
 *
12587
 * Parse an external general entity within an existing parsing context
12588
 * An external general parsed entity is well-formed if it matches the
12589
 * production labeled extParsedEnt.
12590
 *
12591
 * [78] extParsedEnt ::= TextDecl? content
12592
 *
12593
 * Returns 0 if the entity is well formed, -1 in case of args problem and
12594
 *    the parser error code otherwise
12595
 */
12596
12597
int
12598
xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx, const xmlChar *URL,
12599
0
                 const xmlChar *ID, xmlNodePtr *lst) {
12600
0
    void *userData;
12601
12602
0
    if (ctx == NULL) return(-1);
12603
    /*
12604
     * If the user provided their own SAX callbacks, then reuse the
12605
     * userData callback field, otherwise the expected setup in a
12606
     * DOM builder is to have userData == ctxt
12607
     */
12608
0
    if (ctx->userData == ctx)
12609
0
        userData = NULL;
12610
0
    else
12611
0
        userData = ctx->userData;
12612
0
    return xmlParseExternalEntityPrivate(ctx->myDoc, ctx, ctx->sax,
12613
0
                                         userData, ctx->depth + 1,
12614
0
                                         URL, ID, lst);
12615
0
}
12616
12617
/**
12618
 * xmlParseExternalEntityPrivate:
12619
 * @doc:  the document the chunk pertains to
12620
 * @oldctxt:  the previous parser context if available
12621
 * @sax:  the SAX handler block (possibly NULL)
12622
 * @user_data:  The user data returned on SAX callbacks (possibly NULL)
12623
 * @depth:  Used for loop detection, use 0
12624
 * @URL:  the URL for the entity to load
12625
 * @ID:  the System ID for the entity to load
12626
 * @list:  the return value for the set of parsed nodes
12627
 *
12628
 * Private version of xmlParseExternalEntity()
12629
 *
12630
 * Returns 0 if the entity is well formed, -1 in case of args problem and
12631
 *    the parser error code otherwise
12632
 */
12633
12634
static xmlParserErrors
12635
xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
12636
                xmlSAXHandlerPtr sax,
12637
          void *user_data, int depth, const xmlChar *URL,
12638
9.80k
          const xmlChar *ID, xmlNodePtr *list) {
12639
9.80k
    xmlParserCtxtPtr ctxt;
12640
9.80k
    xmlDocPtr newDoc;
12641
9.80k
    xmlNodePtr newRoot;
12642
9.80k
    xmlParserErrors ret = XML_ERR_OK;
12643
9.80k
    xmlChar start[4];
12644
9.80k
    xmlCharEncoding enc;
12645
12646
9.80k
    if (((depth > 40) &&
12647
9.80k
  ((oldctxt == NULL) || (oldctxt->options & XML_PARSE_HUGE) == 0)) ||
12648
9.80k
  (depth > 100)) {
12649
0
  xmlFatalErrMsg(oldctxt, XML_ERR_ENTITY_LOOP,
12650
0
                       "Maximum entity nesting depth exceeded");
12651
0
        return(XML_ERR_ENTITY_LOOP);
12652
0
    }
12653
12654
9.80k
    if (list != NULL)
12655
3.24k
        *list = NULL;
12656
9.80k
    if ((URL == NULL) && (ID == NULL))
12657
0
  return(XML_ERR_INTERNAL_ERROR);
12658
9.80k
    if (doc == NULL)
12659
0
  return(XML_ERR_INTERNAL_ERROR);
12660
12661
9.80k
    ctxt = xmlCreateEntityParserCtxtInternal(sax, user_data, URL, ID, NULL,
12662
9.80k
                                             oldctxt);
12663
9.80k
    if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
12664
4.20k
    if (oldctxt != NULL) {
12665
4.20k
        ctxt->nbErrors = oldctxt->nbErrors;
12666
4.20k
        ctxt->nbWarnings = oldctxt->nbWarnings;
12667
4.20k
    }
12668
4.20k
    xmlDetectSAX2(ctxt);
12669
12670
4.20k
    newDoc = xmlNewDoc(BAD_CAST "1.0");
12671
4.20k
    if (newDoc == NULL) {
12672
7
  xmlFreeParserCtxt(ctxt);
12673
7
  return(XML_ERR_INTERNAL_ERROR);
12674
7
    }
12675
4.19k
    newDoc->properties = XML_DOC_INTERNAL;
12676
4.19k
    if (doc) {
12677
4.19k
        newDoc->intSubset = doc->intSubset;
12678
4.19k
        newDoc->extSubset = doc->extSubset;
12679
4.19k
        if (doc->dict) {
12680
4.19k
            newDoc->dict = doc->dict;
12681
4.19k
            xmlDictReference(newDoc->dict);
12682
4.19k
        }
12683
4.19k
        if (doc->URL != NULL) {
12684
4.19k
            newDoc->URL = xmlStrdup(doc->URL);
12685
4.19k
        }
12686
4.19k
    }
12687
4.19k
    newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
12688
4.19k
    if (newRoot == NULL) {
12689
1
  if (sax != NULL)
12690
1
  xmlFreeParserCtxt(ctxt);
12691
1
  newDoc->intSubset = NULL;
12692
1
  newDoc->extSubset = NULL;
12693
1
        xmlFreeDoc(newDoc);
12694
1
  return(XML_ERR_INTERNAL_ERROR);
12695
1
    }
12696
4.19k
    xmlAddChild((xmlNodePtr) newDoc, newRoot);
12697
4.19k
    nodePush(ctxt, newDoc->children);
12698
4.19k
    if (doc == NULL) {
12699
0
        ctxt->myDoc = newDoc;
12700
4.19k
    } else {
12701
4.19k
        ctxt->myDoc = doc;
12702
4.19k
        newRoot->doc = doc;
12703
4.19k
    }
12704
12705
    /*
12706
     * Get the 4 first bytes and decode the charset
12707
     * if enc != XML_CHAR_ENCODING_NONE
12708
     * plug some encoding conversion routines.
12709
     */
12710
4.19k
    GROW;
12711
4.19k
    if ((ctxt->input->end - ctxt->input->cur) >= 4) {
12712
3.68k
  start[0] = RAW;
12713
3.68k
  start[1] = NXT(1);
12714
3.68k
  start[2] = NXT(2);
12715
3.68k
  start[3] = NXT(3);
12716
3.68k
  enc = xmlDetectCharEncoding(start, 4);
12717
3.68k
  if (enc != XML_CHAR_ENCODING_NONE) {
12718
943
      xmlSwitchEncoding(ctxt, enc);
12719
943
  }
12720
3.68k
    }
12721
12722
    /*
12723
     * Parse a possible text declaration first
12724
     */
12725
4.19k
    if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
12726
664
  xmlParseTextDecl(ctxt);
12727
        /*
12728
         * An XML-1.0 document can't reference an entity not XML-1.0
12729
         */
12730
664
        if ((xmlStrEqual(oldctxt->version, BAD_CAST "1.0")) &&
12731
664
            (!xmlStrEqual(ctxt->input->version, BAD_CAST "1.0"))) {
12732
81
            xmlFatalErrMsg(ctxt, XML_ERR_VERSION_MISMATCH,
12733
81
                           "Version mismatch between document and entity\n");
12734
81
        }
12735
664
    }
12736
12737
4.19k
    ctxt->instate = XML_PARSER_CONTENT;
12738
4.19k
    ctxt->depth = depth;
12739
4.19k
    if (oldctxt != NULL) {
12740
4.19k
  ctxt->_private = oldctxt->_private;
12741
4.19k
  ctxt->loadsubset = oldctxt->loadsubset;
12742
4.19k
  ctxt->validate = oldctxt->validate;
12743
4.19k
  ctxt->valid = oldctxt->valid;
12744
4.19k
  ctxt->replaceEntities = oldctxt->replaceEntities;
12745
4.19k
        if (oldctxt->validate) {
12746
0
            ctxt->vctxt.error = oldctxt->vctxt.error;
12747
0
            ctxt->vctxt.warning = oldctxt->vctxt.warning;
12748
0
            ctxt->vctxt.userData = oldctxt->vctxt.userData;
12749
0
            ctxt->vctxt.flags = oldctxt->vctxt.flags;
12750
0
        }
12751
4.19k
  ctxt->external = oldctxt->external;
12752
4.19k
        if (ctxt->dict) xmlDictFree(ctxt->dict);
12753
4.19k
        ctxt->dict = oldctxt->dict;
12754
4.19k
        ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
12755
4.19k
        ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
12756
4.19k
        ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
12757
4.19k
        ctxt->dictNames = oldctxt->dictNames;
12758
4.19k
        ctxt->attsDefault = oldctxt->attsDefault;
12759
4.19k
        ctxt->attsSpecial = oldctxt->attsSpecial;
12760
4.19k
        ctxt->linenumbers = oldctxt->linenumbers;
12761
4.19k
  ctxt->record_info = oldctxt->record_info;
12762
4.19k
  ctxt->node_seq.maximum = oldctxt->node_seq.maximum;
12763
4.19k
  ctxt->node_seq.length = oldctxt->node_seq.length;
12764
4.19k
  ctxt->node_seq.buffer = oldctxt->node_seq.buffer;
12765
4.19k
    } else {
12766
  /*
12767
   * Doing validity checking on chunk without context
12768
   * doesn't make sense
12769
   */
12770
0
  ctxt->_private = NULL;
12771
0
  ctxt->validate = 0;
12772
0
  ctxt->external = 2;
12773
0
  ctxt->loadsubset = 0;
12774
0
    }
12775
12776
4.19k
    xmlParseContent(ctxt);
12777
12778
4.19k
    if ((RAW == '<') && (NXT(1) == '/')) {
12779
138
  xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
12780
4.05k
    } else if (RAW != 0) {
12781
27
  xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
12782
27
    }
12783
4.19k
    if (ctxt->node != newDoc->children) {
12784
1.29k
  xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
12785
1.29k
    }
12786
12787
4.19k
    if (!ctxt->wellFormed) {
12788
2.09k
  ret = (xmlParserErrors)ctxt->errNo;
12789
2.09k
        if (oldctxt != NULL) {
12790
2.09k
            oldctxt->errNo = ctxt->errNo;
12791
2.09k
            oldctxt->wellFormed = 0;
12792
2.09k
            xmlCopyError(&ctxt->lastError, &oldctxt->lastError);
12793
2.09k
        }
12794
2.09k
    } else {
12795
2.09k
  if (list != NULL) {
12796
516
      xmlNodePtr cur;
12797
12798
      /*
12799
       * Return the newly created nodeset after unlinking it from
12800
       * they pseudo parent.
12801
       */
12802
516
      cur = newDoc->children->children;
12803
516
      *list = cur;
12804
1.69k
      while (cur != NULL) {
12805
1.18k
    cur->parent = NULL;
12806
1.18k
    cur = cur->next;
12807
1.18k
      }
12808
516
            newDoc->children->children = NULL;
12809
516
  }
12810
2.09k
  ret = XML_ERR_OK;
12811
2.09k
    }
12812
12813
    /*
12814
     * Also record the size of the entity parsed
12815
     */
12816
4.19k
    if (ctxt->input != NULL && oldctxt != NULL) {
12817
4.19k
        unsigned long consumed = ctxt->input->consumed;
12818
12819
4.19k
        xmlSaturatedAddSizeT(&consumed, ctxt->input->cur - ctxt->input->base);
12820
12821
4.19k
        xmlSaturatedAdd(&oldctxt->sizeentities, consumed);
12822
4.19k
        xmlSaturatedAdd(&oldctxt->sizeentities, ctxt->sizeentities);
12823
12824
4.19k
        xmlSaturatedAdd(&oldctxt->sizeentcopy, consumed);
12825
4.19k
        xmlSaturatedAdd(&oldctxt->sizeentcopy, ctxt->sizeentcopy);
12826
4.19k
    }
12827
12828
4.19k
    if (oldctxt != NULL) {
12829
4.19k
        ctxt->dict = NULL;
12830
4.19k
        ctxt->attsDefault = NULL;
12831
4.19k
        ctxt->attsSpecial = NULL;
12832
4.19k
        oldctxt->nbErrors = ctxt->nbErrors;
12833
4.19k
        oldctxt->nbWarnings = ctxt->nbWarnings;
12834
4.19k
        oldctxt->validate = ctxt->validate;
12835
4.19k
        oldctxt->valid = ctxt->valid;
12836
4.19k
        oldctxt->node_seq.maximum = ctxt->node_seq.maximum;
12837
4.19k
        oldctxt->node_seq.length = ctxt->node_seq.length;
12838
4.19k
        oldctxt->node_seq.buffer = ctxt->node_seq.buffer;
12839
4.19k
    }
12840
4.19k
    ctxt->node_seq.maximum = 0;
12841
4.19k
    ctxt->node_seq.length = 0;
12842
4.19k
    ctxt->node_seq.buffer = NULL;
12843
4.19k
    xmlFreeParserCtxt(ctxt);
12844
4.19k
    newDoc->intSubset = NULL;
12845
4.19k
    newDoc->extSubset = NULL;
12846
4.19k
    xmlFreeDoc(newDoc);
12847
12848
4.19k
    return(ret);
12849
4.19k
}
12850
12851
#ifdef LIBXML_SAX1_ENABLED
12852
/**
12853
 * xmlParseExternalEntity:
12854
 * @doc:  the document the chunk pertains to
12855
 * @sax:  the SAX handler block (possibly NULL)
12856
 * @user_data:  The user data returned on SAX callbacks (possibly NULL)
12857
 * @depth:  Used for loop detection, use 0
12858
 * @URL:  the URL for the entity to load
12859
 * @ID:  the System ID for the entity to load
12860
 * @lst:  the return value for the set of parsed nodes
12861
 *
12862
 * Parse an external general entity
12863
 * An external general parsed entity is well-formed if it matches the
12864
 * production labeled extParsedEnt.
12865
 *
12866
 * [78] extParsedEnt ::= TextDecl? content
12867
 *
12868
 * Returns 0 if the entity is well formed, -1 in case of args problem and
12869
 *    the parser error code otherwise
12870
 */
12871
12872
int
12873
xmlParseExternalEntity(xmlDocPtr doc, xmlSAXHandlerPtr sax, void *user_data,
12874
    int depth, const xmlChar *URL, const xmlChar *ID, xmlNodePtr *lst) {
12875
    return(xmlParseExternalEntityPrivate(doc, NULL, sax, user_data, depth, URL,
12876
                           ID, lst));
12877
}
12878
12879
/**
12880
 * xmlParseBalancedChunkMemory:
12881
 * @doc:  the document the chunk pertains to (must not be NULL)
12882
 * @sax:  the SAX handler block (possibly NULL)
12883
 * @user_data:  The user data returned on SAX callbacks (possibly NULL)
12884
 * @depth:  Used for loop detection, use 0
12885
 * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
12886
 * @lst:  the return value for the set of parsed nodes
12887
 *
12888
 * Parse a well-balanced chunk of an XML document
12889
 * called by the parser
12890
 * The allowed sequence for the Well Balanced Chunk is the one defined by
12891
 * the content production in the XML grammar:
12892
 *
12893
 * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
12894
 *
12895
 * Returns 0 if the chunk is well balanced, -1 in case of args problem and
12896
 *    the parser error code otherwise
12897
 */
12898
12899
int
12900
xmlParseBalancedChunkMemory(xmlDocPtr doc, xmlSAXHandlerPtr sax,
12901
     void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst) {
12902
    return xmlParseBalancedChunkMemoryRecover( doc, sax, user_data,
12903
                                                depth, string, lst, 0 );
12904
}
12905
#endif /* LIBXML_SAX1_ENABLED */
12906
12907
/**
12908
 * xmlParseBalancedChunkMemoryInternal:
12909
 * @oldctxt:  the existing parsing context
12910
 * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
12911
 * @user_data:  the user data field for the parser context
12912
 * @lst:  the return value for the set of parsed nodes
12913
 *
12914
 *
12915
 * Parse a well-balanced chunk of an XML document
12916
 * called by the parser
12917
 * The allowed sequence for the Well Balanced Chunk is the one defined by
12918
 * the content production in the XML grammar:
12919
 *
12920
 * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
12921
 *
12922
 * Returns XML_ERR_OK if the chunk is well balanced, and the parser
12923
 * error code otherwise
12924
 *
12925
 * In case recover is set to 1, the nodelist will not be empty even if
12926
 * the parsed chunk is not well balanced.
12927
 */
12928
static xmlParserErrors
12929
xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
12930
3.20k
  const xmlChar *string, void *user_data, xmlNodePtr *lst) {
12931
3.20k
    xmlParserCtxtPtr ctxt;
12932
3.20k
    xmlDocPtr newDoc = NULL;
12933
3.20k
    xmlNodePtr newRoot;
12934
3.20k
    xmlSAXHandlerPtr oldsax = NULL;
12935
3.20k
    xmlNodePtr content = NULL;
12936
3.20k
    xmlNodePtr last = NULL;
12937
3.20k
    int size;
12938
3.20k
    xmlParserErrors ret = XML_ERR_OK;
12939
3.20k
#ifdef SAX2
12940
3.20k
    int i;
12941
3.20k
#endif
12942
12943
3.20k
    if (((oldctxt->depth > 40) && ((oldctxt->options & XML_PARSE_HUGE) == 0)) ||
12944
3.20k
        (oldctxt->depth >  100)) {
12945
0
  xmlFatalErrMsg(oldctxt, XML_ERR_ENTITY_LOOP,
12946
0
                       "Maximum entity nesting depth exceeded");
12947
0
  return(XML_ERR_ENTITY_LOOP);
12948
0
    }
12949
12950
12951
3.20k
    if (lst != NULL)
12952
3.11k
        *lst = NULL;
12953
3.20k
    if (string == NULL)
12954
0
        return(XML_ERR_INTERNAL_ERROR);
12955
12956
3.20k
    size = xmlStrlen(string);
12957
12958
3.20k
    ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
12959
3.20k
    if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
12960
3.09k
    ctxt->nbErrors = oldctxt->nbErrors;
12961
3.09k
    ctxt->nbWarnings = oldctxt->nbWarnings;
12962
3.09k
    if (user_data != NULL)
12963
0
  ctxt->userData = user_data;
12964
3.09k
    else
12965
3.09k
  ctxt->userData = ctxt;
12966
3.09k
    if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
12967
3.09k
    ctxt->dict = oldctxt->dict;
12968
3.09k
    ctxt->input_id = oldctxt->input_id;
12969
3.09k
    ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
12970
3.09k
    ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
12971
3.09k
    ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
12972
12973
3.09k
#ifdef SAX2
12974
    /* propagate namespaces down the entity */
12975
8.47k
    for (i = 0;i < oldctxt->nsNr;i += 2) {
12976
5.38k
        nsPush(ctxt, oldctxt->nsTab[i], oldctxt->nsTab[i+1]);
12977
5.38k
    }
12978
3.09k
#endif
12979
12980
3.09k
    oldsax = ctxt->sax;
12981
3.09k
    ctxt->sax = oldctxt->sax;
12982
3.09k
    xmlDetectSAX2(ctxt);
12983
3.09k
    ctxt->replaceEntities = oldctxt->replaceEntities;
12984
3.09k
    ctxt->options = oldctxt->options;
12985
12986
3.09k
    ctxt->_private = oldctxt->_private;
12987
3.09k
    if (oldctxt->myDoc == NULL) {
12988
0
  newDoc = xmlNewDoc(BAD_CAST "1.0");
12989
0
  if (newDoc == NULL) {
12990
0
      ctxt->sax = oldsax;
12991
0
      ctxt->dict = NULL;
12992
0
      xmlFreeParserCtxt(ctxt);
12993
0
      return(XML_ERR_INTERNAL_ERROR);
12994
0
  }
12995
0
  newDoc->properties = XML_DOC_INTERNAL;
12996
0
  newDoc->dict = ctxt->dict;
12997
0
  xmlDictReference(newDoc->dict);
12998
0
  ctxt->myDoc = newDoc;
12999
3.09k
    } else {
13000
3.09k
  ctxt->myDoc = oldctxt->myDoc;
13001
3.09k
        content = ctxt->myDoc->children;
13002
3.09k
  last = ctxt->myDoc->last;
13003
3.09k
    }
13004
3.09k
    newRoot = xmlNewDocNode(ctxt->myDoc, NULL, BAD_CAST "pseudoroot", NULL);
13005
3.09k
    if (newRoot == NULL) {
13006
4
  ctxt->sax = oldsax;
13007
4
  ctxt->dict = NULL;
13008
4
  xmlFreeParserCtxt(ctxt);
13009
4
  if (newDoc != NULL) {
13010
0
      xmlFreeDoc(newDoc);
13011
0
  }
13012
4
  return(XML_ERR_INTERNAL_ERROR);
13013
4
    }
13014
3.08k
    ctxt->myDoc->children = NULL;
13015
3.08k
    ctxt->myDoc->last = NULL;
13016
3.08k
    xmlAddChild((xmlNodePtr) ctxt->myDoc, newRoot);
13017
3.08k
    nodePush(ctxt, ctxt->myDoc->children);
13018
3.08k
    ctxt->instate = XML_PARSER_CONTENT;
13019
3.08k
    ctxt->depth = oldctxt->depth;
13020
13021
3.08k
    ctxt->validate = 0;
13022
3.08k
    ctxt->loadsubset = oldctxt->loadsubset;
13023
3.08k
    if ((oldctxt->validate) || (oldctxt->replaceEntities != 0)) {
13024
  /*
13025
   * ID/IDREF registration will be done in xmlValidateElement below
13026
   */
13027
3.08k
  ctxt->loadsubset |= XML_SKIP_IDS;
13028
3.08k
    }
13029
3.08k
    ctxt->dictNames = oldctxt->dictNames;
13030
3.08k
    ctxt->attsDefault = oldctxt->attsDefault;
13031
3.08k
    ctxt->attsSpecial = oldctxt->attsSpecial;
13032
13033
3.08k
    xmlParseContent(ctxt);
13034
3.08k
    if ((RAW == '<') && (NXT(1) == '/')) {
13035
327
  xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13036
2.75k
    } else if (RAW != 0) {
13037
15
  xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
13038
15
    }
13039
3.08k
    if (ctxt->node != ctxt->myDoc->children) {
13040
757
  xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13041
757
    }
13042
13043
3.08k
    if (!ctxt->wellFormed) {
13044
1.10k
  ret = (xmlParserErrors)ctxt->errNo;
13045
1.10k
        oldctxt->errNo = ctxt->errNo;
13046
1.10k
        oldctxt->wellFormed = 0;
13047
1.10k
        xmlCopyError(&ctxt->lastError, &oldctxt->lastError);
13048
1.97k
    } else {
13049
1.97k
        ret = XML_ERR_OK;
13050
1.97k
    }
13051
13052
3.08k
    if ((lst != NULL) && (ret == XML_ERR_OK)) {
13053
1.97k
  xmlNodePtr cur;
13054
13055
  /*
13056
   * Return the newly created nodeset after unlinking it from
13057
   * they pseudo parent.
13058
   */
13059
1.97k
  cur = ctxt->myDoc->children->children;
13060
1.97k
  *lst = cur;
13061
13.2k
  while (cur != NULL) {
13062
#ifdef LIBXML_VALID_ENABLED
13063
      if ((oldctxt->validate) && (oldctxt->wellFormed) &&
13064
    (oldctxt->myDoc) && (oldctxt->myDoc->intSubset) &&
13065
    (cur->type == XML_ELEMENT_NODE)) {
13066
    oldctxt->valid &= xmlValidateElement(&oldctxt->vctxt,
13067
      oldctxt->myDoc, cur);
13068
      }
13069
#endif /* LIBXML_VALID_ENABLED */
13070
11.2k
      cur->parent = NULL;
13071
11.2k
      cur = cur->next;
13072
11.2k
  }
13073
1.97k
  ctxt->myDoc->children->children = NULL;
13074
1.97k
    }
13075
3.08k
    if (ctxt->myDoc != NULL) {
13076
3.08k
  xmlFreeNode(ctxt->myDoc->children);
13077
3.08k
        ctxt->myDoc->children = content;
13078
3.08k
        ctxt->myDoc->last = last;
13079
3.08k
    }
13080
13081
    /*
13082
     * Also record the size of the entity parsed
13083
     */
13084
3.08k
    if (ctxt->input != NULL && oldctxt != NULL) {
13085
3.08k
        unsigned long consumed = ctxt->input->consumed;
13086
13087
3.08k
        xmlSaturatedAddSizeT(&consumed, ctxt->input->cur - ctxt->input->base);
13088
13089
3.08k
        xmlSaturatedAdd(&oldctxt->sizeentcopy, consumed);
13090
3.08k
        xmlSaturatedAdd(&oldctxt->sizeentcopy, ctxt->sizeentcopy);
13091
3.08k
    }
13092
13093
3.08k
    oldctxt->nbErrors = ctxt->nbErrors;
13094
3.08k
    oldctxt->nbWarnings = ctxt->nbWarnings;
13095
3.08k
    ctxt->sax = oldsax;
13096
3.08k
    ctxt->dict = NULL;
13097
3.08k
    ctxt->attsDefault = NULL;
13098
3.08k
    ctxt->attsSpecial = NULL;
13099
3.08k
    xmlFreeParserCtxt(ctxt);
13100
3.08k
    if (newDoc != NULL) {
13101
0
  xmlFreeDoc(newDoc);
13102
0
    }
13103
13104
3.08k
    return(ret);
13105
3.09k
}
13106
13107
/**
13108
 * xmlParseInNodeContext:
13109
 * @node:  the context node
13110
 * @data:  the input string
13111
 * @datalen:  the input string length in bytes
13112
 * @options:  a combination of xmlParserOption
13113
 * @lst:  the return value for the set of parsed nodes
13114
 *
13115
 * Parse a well-balanced chunk of an XML document
13116
 * within the context (DTD, namespaces, etc ...) of the given node.
13117
 *
13118
 * The allowed sequence for the data is a Well Balanced Chunk defined by
13119
 * the content production in the XML grammar:
13120
 *
13121
 * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
13122
 *
13123
 * Returns XML_ERR_OK if the chunk is well balanced, and the parser
13124
 * error code otherwise
13125
 */
13126
xmlParserErrors
13127
xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen,
13128
0
                      int options, xmlNodePtr *lst) {
13129
0
#ifdef SAX2
13130
0
    xmlParserCtxtPtr ctxt;
13131
0
    xmlDocPtr doc = NULL;
13132
0
    xmlNodePtr fake, cur;
13133
0
    int nsnr = 0;
13134
13135
0
    xmlParserErrors ret = XML_ERR_OK;
13136
13137
    /*
13138
     * check all input parameters, grab the document
13139
     */
13140
0
    if ((lst == NULL) || (node == NULL) || (data == NULL) || (datalen < 0))
13141
0
        return(XML_ERR_INTERNAL_ERROR);
13142
0
    switch (node->type) {
13143
0
        case XML_ELEMENT_NODE:
13144
0
        case XML_ATTRIBUTE_NODE:
13145
0
        case XML_TEXT_NODE:
13146
0
        case XML_CDATA_SECTION_NODE:
13147
0
        case XML_ENTITY_REF_NODE:
13148
0
        case XML_PI_NODE:
13149
0
        case XML_COMMENT_NODE:
13150
0
        case XML_DOCUMENT_NODE:
13151
0
        case XML_HTML_DOCUMENT_NODE:
13152
0
      break;
13153
0
  default:
13154
0
      return(XML_ERR_INTERNAL_ERROR);
13155
13156
0
    }
13157
0
    while ((node != NULL) && (node->type != XML_ELEMENT_NODE) &&
13158
0
           (node->type != XML_DOCUMENT_NODE) &&
13159
0
     (node->type != XML_HTML_DOCUMENT_NODE))
13160
0
  node = node->parent;
13161
0
    if (node == NULL)
13162
0
  return(XML_ERR_INTERNAL_ERROR);
13163
0
    if (node->type == XML_ELEMENT_NODE)
13164
0
  doc = node->doc;
13165
0
    else
13166
0
        doc = (xmlDocPtr) node;
13167
0
    if (doc == NULL)
13168
0
  return(XML_ERR_INTERNAL_ERROR);
13169
13170
    /*
13171
     * allocate a context and set-up everything not related to the
13172
     * node position in the tree
13173
     */
13174
0
    if (doc->type == XML_DOCUMENT_NODE)
13175
0
  ctxt = xmlCreateMemoryParserCtxt((char *) data, datalen);
13176
0
#ifdef LIBXML_HTML_ENABLED
13177
0
    else if (doc->type == XML_HTML_DOCUMENT_NODE) {
13178
0
  ctxt = htmlCreateMemoryParserCtxt((char *) data, datalen);
13179
        /*
13180
         * When parsing in context, it makes no sense to add implied
13181
         * elements like html/body/etc...
13182
         */
13183
0
        options |= HTML_PARSE_NOIMPLIED;
13184
0
    }
13185
0
#endif
13186
0
    else
13187
0
        return(XML_ERR_INTERNAL_ERROR);
13188
13189
0
    if (ctxt == NULL)
13190
0
        return(XML_ERR_NO_MEMORY);
13191
13192
    /*
13193
     * Use input doc's dict if present, else assure XML_PARSE_NODICT is set.
13194
     * We need a dictionary for xmlDetectSAX2, so if there's no doc dict
13195
     * we must wait until the last moment to free the original one.
13196
     */
13197
0
    if (doc->dict != NULL) {
13198
0
        if (ctxt->dict != NULL)
13199
0
      xmlDictFree(ctxt->dict);
13200
0
  ctxt->dict = doc->dict;
13201
0
    } else
13202
0
        options |= XML_PARSE_NODICT;
13203
13204
0
    if (doc->encoding != NULL) {
13205
0
        xmlCharEncodingHandlerPtr hdlr;
13206
13207
0
        if (ctxt->encoding != NULL)
13208
0
      xmlFree((xmlChar *) ctxt->encoding);
13209
0
        ctxt->encoding = xmlStrdup((const xmlChar *) doc->encoding);
13210
13211
0
        hdlr = xmlFindCharEncodingHandler((const char *) doc->encoding);
13212
0
        if (hdlr != NULL) {
13213
0
            xmlSwitchToEncoding(ctxt, hdlr);
13214
0
  } else {
13215
0
            return(XML_ERR_UNSUPPORTED_ENCODING);
13216
0
        }
13217
0
    }
13218
13219
0
    xmlCtxtUseOptionsInternal(ctxt, options, NULL);
13220
0
    xmlDetectSAX2(ctxt);
13221
0
    ctxt->myDoc = doc;
13222
    /* parsing in context, i.e. as within existing content */
13223
0
    ctxt->input_id = 2;
13224
0
    ctxt->instate = XML_PARSER_CONTENT;
13225
13226
0
    fake = xmlNewDocComment(node->doc, NULL);
13227
0
    if (fake == NULL) {
13228
0
        xmlFreeParserCtxt(ctxt);
13229
0
  return(XML_ERR_NO_MEMORY);
13230
0
    }
13231
0
    xmlAddChild(node, fake);
13232
13233
0
    if (node->type == XML_ELEMENT_NODE) {
13234
0
  nodePush(ctxt, node);
13235
  /*
13236
   * initialize the SAX2 namespaces stack
13237
   */
13238
0
  cur = node;
13239
0
  while ((cur != NULL) && (cur->type == XML_ELEMENT_NODE)) {
13240
0
      xmlNsPtr ns = cur->nsDef;
13241
0
      const xmlChar *iprefix, *ihref;
13242
13243
0
      while (ns != NULL) {
13244
0
    if (ctxt->dict) {
13245
0
        iprefix = xmlDictLookup(ctxt->dict, ns->prefix, -1);
13246
0
        ihref = xmlDictLookup(ctxt->dict, ns->href, -1);
13247
0
    } else {
13248
0
        iprefix = ns->prefix;
13249
0
        ihref = ns->href;
13250
0
    }
13251
13252
0
          if (xmlGetNamespace(ctxt, iprefix) == NULL) {
13253
0
        nsPush(ctxt, iprefix, ihref);
13254
0
        nsnr++;
13255
0
    }
13256
0
    ns = ns->next;
13257
0
      }
13258
0
      cur = cur->parent;
13259
0
  }
13260
0
    }
13261
13262
0
    if ((ctxt->validate) || (ctxt->replaceEntities != 0)) {
13263
  /*
13264
   * ID/IDREF registration will be done in xmlValidateElement below
13265
   */
13266
0
  ctxt->loadsubset |= XML_SKIP_IDS;
13267
0
    }
13268
13269
0
#ifdef LIBXML_HTML_ENABLED
13270
0
    if (doc->type == XML_HTML_DOCUMENT_NODE)
13271
0
        __htmlParseContent(ctxt);
13272
0
    else
13273
0
#endif
13274
0
  xmlParseContent(ctxt);
13275
13276
0
    nsPop(ctxt, nsnr);
13277
0
    if ((RAW == '<') && (NXT(1) == '/')) {
13278
0
  xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13279
0
    } else if (RAW != 0) {
13280
0
  xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
13281
0
    }
13282
0
    if ((ctxt->node != NULL) && (ctxt->node != node)) {
13283
0
  xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13284
0
  ctxt->wellFormed = 0;
13285
0
    }
13286
13287
0
    if (!ctxt->wellFormed) {
13288
0
        if (ctxt->errNo == 0)
13289
0
      ret = XML_ERR_INTERNAL_ERROR;
13290
0
  else
13291
0
      ret = (xmlParserErrors)ctxt->errNo;
13292
0
    } else {
13293
0
        ret = XML_ERR_OK;
13294
0
    }
13295
13296
    /*
13297
     * Return the newly created nodeset after unlinking it from
13298
     * the pseudo sibling.
13299
     */
13300
13301
0
    cur = fake->next;
13302
0
    fake->next = NULL;
13303
0
    node->last = fake;
13304
13305
0
    if (cur != NULL) {
13306
0
  cur->prev = NULL;
13307
0
    }
13308
13309
0
    *lst = cur;
13310
13311
0
    while (cur != NULL) {
13312
0
  cur->parent = NULL;
13313
0
  cur = cur->next;
13314
0
    }
13315
13316
0
    xmlUnlinkNode(fake);
13317
0
    xmlFreeNode(fake);
13318
13319
13320
0
    if (ret != XML_ERR_OK) {
13321
0
        xmlFreeNodeList(*lst);
13322
0
  *lst = NULL;
13323
0
    }
13324
13325
0
    if (doc->dict != NULL)
13326
0
        ctxt->dict = NULL;
13327
0
    xmlFreeParserCtxt(ctxt);
13328
13329
0
    return(ret);
13330
#else /* !SAX2 */
13331
    return(XML_ERR_INTERNAL_ERROR);
13332
#endif
13333
0
}
13334
13335
#ifdef LIBXML_SAX1_ENABLED
13336
/**
13337
 * xmlParseBalancedChunkMemoryRecover:
13338
 * @doc:  the document the chunk pertains to (must not be NULL)
13339
 * @sax:  the SAX handler block (possibly NULL)
13340
 * @user_data:  The user data returned on SAX callbacks (possibly NULL)
13341
 * @depth:  Used for loop detection, use 0
13342
 * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
13343
 * @lst:  the return value for the set of parsed nodes
13344
 * @recover: return nodes even if the data is broken (use 0)
13345
 *
13346
 *
13347
 * Parse a well-balanced chunk of an XML document
13348
 * called by the parser
13349
 * The allowed sequence for the Well Balanced Chunk is the one defined by
13350
 * the content production in the XML grammar:
13351
 *
13352
 * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
13353
 *
13354
 * Returns 0 if the chunk is well balanced, -1 in case of args problem and
13355
 *    the parser error code otherwise
13356
 *
13357
 * In case recover is set to 1, the nodelist will not be empty even if
13358
 * the parsed chunk is not well balanced, assuming the parsing succeeded to
13359
 * some extent.
13360
 */
13361
int
13362
xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax,
13363
     void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst,
13364
     int recover) {
13365
    xmlParserCtxtPtr ctxt;
13366
    xmlDocPtr newDoc;
13367
    xmlSAXHandlerPtr oldsax = NULL;
13368
    xmlNodePtr content, newRoot;
13369
    int size;
13370
    int ret = 0;
13371
13372
    if (depth > 40) {
13373
  return(XML_ERR_ENTITY_LOOP);
13374
    }
13375
13376
13377
    if (lst != NULL)
13378
        *lst = NULL;
13379
    if (string == NULL)
13380
        return(-1);
13381
13382
    size = xmlStrlen(string);
13383
13384
    ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
13385
    if (ctxt == NULL) return(-1);
13386
    ctxt->userData = ctxt;
13387
    if (sax != NULL) {
13388
  oldsax = ctxt->sax;
13389
        ctxt->sax = sax;
13390
  if (user_data != NULL)
13391
      ctxt->userData = user_data;
13392
    }
13393
    newDoc = xmlNewDoc(BAD_CAST "1.0");
13394
    if (newDoc == NULL) {
13395
  xmlFreeParserCtxt(ctxt);
13396
  return(-1);
13397
    }
13398
    newDoc->properties = XML_DOC_INTERNAL;
13399
    if ((doc != NULL) && (doc->dict != NULL)) {
13400
        xmlDictFree(ctxt->dict);
13401
  ctxt->dict = doc->dict;
13402
  xmlDictReference(ctxt->dict);
13403
  ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
13404
  ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
13405
  ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
13406
  ctxt->dictNames = 1;
13407
    } else {
13408
  xmlCtxtUseOptionsInternal(ctxt, XML_PARSE_NODICT, NULL);
13409
    }
13410
    /* doc == NULL is only supported for historic reasons */
13411
    if (doc != NULL) {
13412
  newDoc->intSubset = doc->intSubset;
13413
  newDoc->extSubset = doc->extSubset;
13414
    }
13415
    newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
13416
    if (newRoot == NULL) {
13417
  if (sax != NULL)
13418
      ctxt->sax = oldsax;
13419
  xmlFreeParserCtxt(ctxt);
13420
  newDoc->intSubset = NULL;
13421
  newDoc->extSubset = NULL;
13422
        xmlFreeDoc(newDoc);
13423
  return(-1);
13424
    }
13425
    xmlAddChild((xmlNodePtr) newDoc, newRoot);
13426
    nodePush(ctxt, newRoot);
13427
    /* doc == NULL is only supported for historic reasons */
13428
    if (doc == NULL) {
13429
  ctxt->myDoc = newDoc;
13430
    } else {
13431
  ctxt->myDoc = newDoc;
13432
  newDoc->children->doc = doc;
13433
  /* Ensure that doc has XML spec namespace */
13434
  xmlSearchNsByHref(doc, (xmlNodePtr)doc, XML_XML_NAMESPACE);
13435
  newDoc->oldNs = doc->oldNs;
13436
    }
13437
    ctxt->instate = XML_PARSER_CONTENT;
13438
    ctxt->input_id = 2;
13439
    ctxt->depth = depth;
13440
13441
    /*
13442
     * Doing validity checking on chunk doesn't make sense
13443
     */
13444
    ctxt->validate = 0;
13445
    ctxt->loadsubset = 0;
13446
    xmlDetectSAX2(ctxt);
13447
13448
    if ( doc != NULL ){
13449
        content = doc->children;
13450
        doc->children = NULL;
13451
        xmlParseContent(ctxt);
13452
        doc->children = content;
13453
    }
13454
    else {
13455
        xmlParseContent(ctxt);
13456
    }
13457
    if ((RAW == '<') && (NXT(1) == '/')) {
13458
  xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13459
    } else if (RAW != 0) {
13460
  xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
13461
    }
13462
    if (ctxt->node != newDoc->children) {
13463
  xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13464
    }
13465
13466
    if (!ctxt->wellFormed) {
13467
        if (ctxt->errNo == 0)
13468
      ret = 1;
13469
  else
13470
      ret = ctxt->errNo;
13471
    } else {
13472
      ret = 0;
13473
    }
13474
13475
    if ((lst != NULL) && ((ret == 0) || (recover == 1))) {
13476
  xmlNodePtr cur;
13477
13478
  /*
13479
   * Return the newly created nodeset after unlinking it from
13480
   * they pseudo parent.
13481
   */
13482
  cur = newDoc->children->children;
13483
  *lst = cur;
13484
  while (cur != NULL) {
13485
      xmlSetTreeDoc(cur, doc);
13486
      cur->parent = NULL;
13487
      cur = cur->next;
13488
  }
13489
  newDoc->children->children = NULL;
13490
    }
13491
13492
    if (sax != NULL)
13493
  ctxt->sax = oldsax;
13494
    xmlFreeParserCtxt(ctxt);
13495
    newDoc->intSubset = NULL;
13496
    newDoc->extSubset = NULL;
13497
    /* This leaks the namespace list if doc == NULL */
13498
    newDoc->oldNs = NULL;
13499
    xmlFreeDoc(newDoc);
13500
13501
    return(ret);
13502
}
13503
13504
/**
13505
 * xmlSAXParseEntity:
13506
 * @sax:  the SAX handler block
13507
 * @filename:  the filename
13508
 *
13509
 * DEPRECATED: Don't use.
13510
 *
13511
 * parse an XML external entity out of context and build a tree.
13512
 * It use the given SAX function block to handle the parsing callback.
13513
 * If sax is NULL, fallback to the default DOM tree building routines.
13514
 *
13515
 * [78] extParsedEnt ::= TextDecl? content
13516
 *
13517
 * This correspond to a "Well Balanced" chunk
13518
 *
13519
 * Returns the resulting document tree
13520
 */
13521
13522
xmlDocPtr
13523
xmlSAXParseEntity(xmlSAXHandlerPtr sax, const char *filename) {
13524
    xmlDocPtr ret;
13525
    xmlParserCtxtPtr ctxt;
13526
13527
    ctxt = xmlCreateFileParserCtxt(filename);
13528
    if (ctxt == NULL) {
13529
  return(NULL);
13530
    }
13531
    if (sax != NULL) {
13532
  if (ctxt->sax != NULL)
13533
      xmlFree(ctxt->sax);
13534
        ctxt->sax = sax;
13535
        ctxt->userData = NULL;
13536
    }
13537
13538
    xmlParseExtParsedEnt(ctxt);
13539
13540
    if (ctxt->wellFormed)
13541
  ret = ctxt->myDoc;
13542
    else {
13543
        ret = NULL;
13544
        xmlFreeDoc(ctxt->myDoc);
13545
        ctxt->myDoc = NULL;
13546
    }
13547
    if (sax != NULL)
13548
        ctxt->sax = NULL;
13549
    xmlFreeParserCtxt(ctxt);
13550
13551
    return(ret);
13552
}
13553
13554
/**
13555
 * xmlParseEntity:
13556
 * @filename:  the filename
13557
 *
13558
 * parse an XML external entity out of context and build a tree.
13559
 *
13560
 * [78] extParsedEnt ::= TextDecl? content
13561
 *
13562
 * This correspond to a "Well Balanced" chunk
13563
 *
13564
 * Returns the resulting document tree
13565
 */
13566
13567
xmlDocPtr
13568
xmlParseEntity(const char *filename) {
13569
    return(xmlSAXParseEntity(NULL, filename));
13570
}
13571
#endif /* LIBXML_SAX1_ENABLED */
13572
13573
/**
13574
 * xmlCreateEntityParserCtxtInternal:
13575
 * @URL:  the entity URL
13576
 * @ID:  the entity PUBLIC ID
13577
 * @base:  a possible base for the target URI
13578
 * @pctx:  parser context used to set options on new context
13579
 *
13580
 * Create a parser context for an external entity
13581
 * Automatic support for ZLIB/Compress compressed document is provided
13582
 * by default if found at compile-time.
13583
 *
13584
 * Returns the new parser context or NULL
13585
 */
13586
static xmlParserCtxtPtr
13587
xmlCreateEntityParserCtxtInternal(xmlSAXHandlerPtr sax, void *userData,
13588
        const xmlChar *URL, const xmlChar *ID, const xmlChar *base,
13589
9.80k
        xmlParserCtxtPtr pctx) {
13590
9.80k
    xmlParserCtxtPtr ctxt;
13591
9.80k
    xmlParserInputPtr inputStream;
13592
9.80k
    char *directory = NULL;
13593
9.80k
    xmlChar *uri;
13594
13595
9.80k
    ctxt = xmlNewSAXParserCtxt(sax, userData);
13596
9.80k
    if (ctxt == NULL) {
13597
364
  return(NULL);
13598
364
    }
13599
13600
9.44k
    if (pctx != NULL) {
13601
9.44k
        ctxt->options = pctx->options;
13602
9.44k
        ctxt->_private = pctx->_private;
13603
9.44k
  ctxt->input_id = pctx->input_id;
13604
9.44k
    }
13605
13606
    /* Don't read from stdin. */
13607
9.44k
    if (xmlStrcmp(URL, BAD_CAST "-") == 0)
13608
401
        URL = BAD_CAST "./-";
13609
13610
9.44k
    uri = xmlBuildURI(URL, base);
13611
13612
9.44k
    if (uri == NULL) {
13613
4.49k
  inputStream = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt);
13614
4.49k
  if (inputStream == NULL) {
13615
1.27k
      xmlFreeParserCtxt(ctxt);
13616
1.27k
      return(NULL);
13617
1.27k
  }
13618
13619
3.21k
  inputPush(ctxt, inputStream);
13620
13621
3.21k
  if ((ctxt->directory == NULL) && (directory == NULL))
13622
3.21k
      directory = xmlParserGetDirectory((char *)URL);
13623
3.21k
  if ((ctxt->directory == NULL) && (directory != NULL))
13624
3.21k
      ctxt->directory = directory;
13625
4.94k
    } else {
13626
4.94k
  inputStream = xmlLoadExternalEntity((char *)uri, (char *)ID, ctxt);
13627
4.94k
  if (inputStream == NULL) {
13628
3.96k
      xmlFree(uri);
13629
3.96k
      xmlFreeParserCtxt(ctxt);
13630
3.96k
      return(NULL);
13631
3.96k
  }
13632
13633
985
  inputPush(ctxt, inputStream);
13634
13635
985
  if ((ctxt->directory == NULL) && (directory == NULL))
13636
985
      directory = xmlParserGetDirectory((char *)uri);
13637
985
  if ((ctxt->directory == NULL) && (directory != NULL))
13638
984
      ctxt->directory = directory;
13639
985
  xmlFree(uri);
13640
985
    }
13641
4.20k
    return(ctxt);
13642
9.44k
}
13643
13644
/**
13645
 * xmlCreateEntityParserCtxt:
13646
 * @URL:  the entity URL
13647
 * @ID:  the entity PUBLIC ID
13648
 * @base:  a possible base for the target URI
13649
 *
13650
 * Create a parser context for an external entity
13651
 * Automatic support for ZLIB/Compress compressed document is provided
13652
 * by default if found at compile-time.
13653
 *
13654
 * Returns the new parser context or NULL
13655
 */
13656
xmlParserCtxtPtr
13657
xmlCreateEntityParserCtxt(const xmlChar *URL, const xmlChar *ID,
13658
0
                    const xmlChar *base) {
13659
0
    return xmlCreateEntityParserCtxtInternal(NULL, NULL, URL, ID, base, NULL);
13660
13661
0
}
13662
13663
/************************************************************************
13664
 *                  *
13665
 *    Front ends when parsing from a file     *
13666
 *                  *
13667
 ************************************************************************/
13668
13669
/**
13670
 * xmlCreateURLParserCtxt:
13671
 * @filename:  the filename or URL
13672
 * @options:  a combination of xmlParserOption
13673
 *
13674
 * Create a parser context for a file or URL content.
13675
 * Automatic support for ZLIB/Compress compressed document is provided
13676
 * by default if found at compile-time and for file accesses
13677
 *
13678
 * Returns the new parser context or NULL
13679
 */
13680
xmlParserCtxtPtr
13681
xmlCreateURLParserCtxt(const char *filename, int options)
13682
0
{
13683
0
    xmlParserCtxtPtr ctxt;
13684
0
    xmlParserInputPtr inputStream;
13685
0
    char *directory = NULL;
13686
13687
0
    ctxt = xmlNewParserCtxt();
13688
0
    if (ctxt == NULL) {
13689
0
  xmlErrMemory(NULL, "cannot allocate parser context");
13690
0
  return(NULL);
13691
0
    }
13692
13693
0
    if (options)
13694
0
  xmlCtxtUseOptionsInternal(ctxt, options, NULL);
13695
0
    ctxt->linenumbers = 1;
13696
13697
0
    inputStream = xmlLoadExternalEntity(filename, NULL, ctxt);
13698
0
    if (inputStream == NULL) {
13699
0
  xmlFreeParserCtxt(ctxt);
13700
0
  return(NULL);
13701
0
    }
13702
13703
0
    inputPush(ctxt, inputStream);
13704
0
    if ((ctxt->directory == NULL) && (directory == NULL))
13705
0
        directory = xmlParserGetDirectory(filename);
13706
0
    if ((ctxt->directory == NULL) && (directory != NULL))
13707
0
        ctxt->directory = directory;
13708
13709
0
    return(ctxt);
13710
0
}
13711
13712
/**
13713
 * xmlCreateFileParserCtxt:
13714
 * @filename:  the filename
13715
 *
13716
 * Create a parser context for a file content.
13717
 * Automatic support for ZLIB/Compress compressed document is provided
13718
 * by default if found at compile-time.
13719
 *
13720
 * Returns the new parser context or NULL
13721
 */
13722
xmlParserCtxtPtr
13723
xmlCreateFileParserCtxt(const char *filename)
13724
0
{
13725
0
    return(xmlCreateURLParserCtxt(filename, 0));
13726
0
}
13727
13728
#ifdef LIBXML_SAX1_ENABLED
13729
/**
13730
 * xmlSAXParseFileWithData:
13731
 * @sax:  the SAX handler block
13732
 * @filename:  the filename
13733
 * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
13734
 *             documents
13735
 * @data:  the userdata
13736
 *
13737
 * DEPRECATED: Use xmlNewSAXParserCtxt and xmlCtxtReadFile.
13738
 *
13739
 * parse an XML file and build a tree. Automatic support for ZLIB/Compress
13740
 * compressed document is provided by default if found at compile-time.
13741
 * It use the given SAX function block to handle the parsing callback.
13742
 * If sax is NULL, fallback to the default DOM tree building routines.
13743
 *
13744
 * User data (void *) is stored within the parser context in the
13745
 * context's _private member, so it is available nearly everywhere in libxml
13746
 *
13747
 * Returns the resulting document tree
13748
 */
13749
13750
xmlDocPtr
13751
xmlSAXParseFileWithData(xmlSAXHandlerPtr sax, const char *filename,
13752
                        int recovery, void *data) {
13753
    xmlDocPtr ret;
13754
    xmlParserCtxtPtr ctxt;
13755
13756
    xmlInitParser();
13757
13758
    ctxt = xmlCreateFileParserCtxt(filename);
13759
    if (ctxt == NULL) {
13760
  return(NULL);
13761
    }
13762
    if (sax != NULL) {
13763
  if (ctxt->sax != NULL)
13764
      xmlFree(ctxt->sax);
13765
        ctxt->sax = sax;
13766
    }
13767
    xmlDetectSAX2(ctxt);
13768
    if (data!=NULL) {
13769
  ctxt->_private = data;
13770
    }
13771
13772
    if (ctxt->directory == NULL)
13773
        ctxt->directory = xmlParserGetDirectory(filename);
13774
13775
    ctxt->recovery = recovery;
13776
13777
    xmlParseDocument(ctxt);
13778
13779
    if ((ctxt->wellFormed) || recovery) {
13780
        ret = ctxt->myDoc;
13781
  if ((ret != NULL) && (ctxt->input->buf != NULL)) {
13782
      if (ctxt->input->buf->compressed > 0)
13783
    ret->compression = 9;
13784
      else
13785
    ret->compression = ctxt->input->buf->compressed;
13786
  }
13787
    }
13788
    else {
13789
       ret = NULL;
13790
       xmlFreeDoc(ctxt->myDoc);
13791
       ctxt->myDoc = NULL;
13792
    }
13793
    if (sax != NULL)
13794
        ctxt->sax = NULL;
13795
    xmlFreeParserCtxt(ctxt);
13796
13797
    return(ret);
13798
}
13799
13800
/**
13801
 * xmlSAXParseFile:
13802
 * @sax:  the SAX handler block
13803
 * @filename:  the filename
13804
 * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
13805
 *             documents
13806
 *
13807
 * DEPRECATED: Use xmlNewSAXParserCtxt and xmlCtxtReadFile.
13808
 *
13809
 * parse an XML file and build a tree. Automatic support for ZLIB/Compress
13810
 * compressed document is provided by default if found at compile-time.
13811
 * It use the given SAX function block to handle the parsing callback.
13812
 * If sax is NULL, fallback to the default DOM tree building routines.
13813
 *
13814
 * Returns the resulting document tree
13815
 */
13816
13817
xmlDocPtr
13818
xmlSAXParseFile(xmlSAXHandlerPtr sax, const char *filename,
13819
                          int recovery) {
13820
    return(xmlSAXParseFileWithData(sax,filename,recovery,NULL));
13821
}
13822
13823
/**
13824
 * xmlRecoverDoc:
13825
 * @cur:  a pointer to an array of xmlChar
13826
 *
13827
 * DEPRECATED: Use xmlReadDoc with XML_PARSE_RECOVER.
13828
 *
13829
 * parse an XML in-memory document and build a tree.
13830
 * In the case the document is not Well Formed, a attempt to build a
13831
 * tree is tried anyway
13832
 *
13833
 * Returns the resulting document tree or NULL in case of failure
13834
 */
13835
13836
xmlDocPtr
13837
xmlRecoverDoc(const xmlChar *cur) {
13838
    return(xmlSAXParseDoc(NULL, cur, 1));
13839
}
13840
13841
/**
13842
 * xmlParseFile:
13843
 * @filename:  the filename
13844
 *
13845
 * DEPRECATED: Use xmlReadFile.
13846
 *
13847
 * parse an XML file and build a tree. Automatic support for ZLIB/Compress
13848
 * compressed document is provided by default if found at compile-time.
13849
 *
13850
 * Returns the resulting document tree if the file was wellformed,
13851
 * NULL otherwise.
13852
 */
13853
13854
xmlDocPtr
13855
xmlParseFile(const char *filename) {
13856
    return(xmlSAXParseFile(NULL, filename, 0));
13857
}
13858
13859
/**
13860
 * xmlRecoverFile:
13861
 * @filename:  the filename
13862
 *
13863
 * DEPRECATED: Use xmlReadFile with XML_PARSE_RECOVER.
13864
 *
13865
 * parse an XML file and build a tree. Automatic support for ZLIB/Compress
13866
 * compressed document is provided by default if found at compile-time.
13867
 * In the case the document is not Well Formed, it attempts to build
13868
 * a tree anyway
13869
 *
13870
 * Returns the resulting document tree or NULL in case of failure
13871
 */
13872
13873
xmlDocPtr
13874
xmlRecoverFile(const char *filename) {
13875
    return(xmlSAXParseFile(NULL, filename, 1));
13876
}
13877
13878
13879
/**
13880
 * xmlSetupParserForBuffer:
13881
 * @ctxt:  an XML parser context
13882
 * @buffer:  a xmlChar * buffer
13883
 * @filename:  a file name
13884
 *
13885
 * DEPRECATED: Don't use.
13886
 *
13887
 * Setup the parser context to parse a new buffer; Clears any prior
13888
 * contents from the parser context. The buffer parameter must not be
13889
 * NULL, but the filename parameter can be
13890
 */
13891
void
13892
xmlSetupParserForBuffer(xmlParserCtxtPtr ctxt, const xmlChar* buffer,
13893
                             const char* filename)
13894
{
13895
    xmlParserInputPtr input;
13896
13897
    if ((ctxt == NULL) || (buffer == NULL))
13898
        return;
13899
13900
    input = xmlNewInputStream(ctxt);
13901
    if (input == NULL) {
13902
        xmlErrMemory(NULL, "parsing new buffer: out of memory\n");
13903
        xmlClearParserCtxt(ctxt);
13904
        return;
13905
    }
13906
13907
    xmlClearParserCtxt(ctxt);
13908
    if (filename != NULL)
13909
        input->filename = (char *) xmlCanonicPath((const xmlChar *)filename);
13910
    input->base = buffer;
13911
    input->cur = buffer;
13912
    input->end = &buffer[xmlStrlen(buffer)];
13913
    inputPush(ctxt, input);
13914
}
13915
13916
/**
13917
 * xmlSAXUserParseFile:
13918
 * @sax:  a SAX handler
13919
 * @user_data:  The user data returned on SAX callbacks
13920
 * @filename:  a file name
13921
 *
13922
 * DEPRECATED: Use xmlNewSAXParserCtxt and xmlCtxtReadFile.
13923
 *
13924
 * parse an XML file and call the given SAX handler routines.
13925
 * Automatic support for ZLIB/Compress compressed document is provided
13926
 *
13927
 * Returns 0 in case of success or a error number otherwise
13928
 */
13929
int
13930
xmlSAXUserParseFile(xmlSAXHandlerPtr sax, void *user_data,
13931
                    const char *filename) {
13932
    int ret = 0;
13933
    xmlParserCtxtPtr ctxt;
13934
13935
    ctxt = xmlCreateFileParserCtxt(filename);
13936
    if (ctxt == NULL) return -1;
13937
    if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
13938
  xmlFree(ctxt->sax);
13939
    ctxt->sax = sax;
13940
    xmlDetectSAX2(ctxt);
13941
13942
    if (user_data != NULL)
13943
  ctxt->userData = user_data;
13944
13945
    xmlParseDocument(ctxt);
13946
13947
    if (ctxt->wellFormed)
13948
  ret = 0;
13949
    else {
13950
        if (ctxt->errNo != 0)
13951
      ret = ctxt->errNo;
13952
  else
13953
      ret = -1;
13954
    }
13955
    if (sax != NULL)
13956
  ctxt->sax = NULL;
13957
    if (ctxt->myDoc != NULL) {
13958
        xmlFreeDoc(ctxt->myDoc);
13959
  ctxt->myDoc = NULL;
13960
    }
13961
    xmlFreeParserCtxt(ctxt);
13962
13963
    return ret;
13964
}
13965
#endif /* LIBXML_SAX1_ENABLED */
13966
13967
/************************************************************************
13968
 *                  *
13969
 *    Front ends when parsing from memory     *
13970
 *                  *
13971
 ************************************************************************/
13972
13973
/**
13974
 * xmlCreateMemoryParserCtxt:
13975
 * @buffer:  a pointer to a char array
13976
 * @size:  the size of the array
13977
 *
13978
 * Create a parser context for an XML in-memory document.
13979
 *
13980
 * Returns the new parser context or NULL
13981
 */
13982
xmlParserCtxtPtr
13983
58.3k
xmlCreateMemoryParserCtxt(const char *buffer, int size) {
13984
58.3k
    xmlParserCtxtPtr ctxt;
13985
58.3k
    xmlParserInputPtr input;
13986
58.3k
    xmlParserInputBufferPtr buf;
13987
13988
58.3k
    if (buffer == NULL)
13989
3
  return(NULL);
13990
58.3k
    if (size <= 0)
13991
94
  return(NULL);
13992
13993
58.2k
    ctxt = xmlNewParserCtxt();
13994
58.2k
    if (ctxt == NULL)
13995
29
  return(NULL);
13996
13997
58.2k
    buf = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
13998
58.2k
    if (buf == NULL) {
13999
2
  xmlFreeParserCtxt(ctxt);
14000
2
  return(NULL);
14001
2
    }
14002
14003
58.2k
    input = xmlNewInputStream(ctxt);
14004
58.2k
    if (input == NULL) {
14005
2
  xmlFreeParserInputBuffer(buf);
14006
2
  xmlFreeParserCtxt(ctxt);
14007
2
  return(NULL);
14008
2
    }
14009
14010
58.2k
    input->filename = NULL;
14011
58.2k
    input->buf = buf;
14012
58.2k
    xmlBufResetInput(input->buf->buffer, input);
14013
14014
58.2k
    inputPush(ctxt, input);
14015
58.2k
    return(ctxt);
14016
58.2k
}
14017
14018
#ifdef LIBXML_SAX1_ENABLED
14019
/**
14020
 * xmlSAXParseMemoryWithData:
14021
 * @sax:  the SAX handler block
14022
 * @buffer:  an pointer to a char array
14023
 * @size:  the size of the array
14024
 * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
14025
 *             documents
14026
 * @data:  the userdata
14027
 *
14028
 * DEPRECATED: Use xmlNewSAXParserCtxt and xmlCtxtReadMemory.
14029
 *
14030
 * parse an XML in-memory block and use the given SAX function block
14031
 * to handle the parsing callback. If sax is NULL, fallback to the default
14032
 * DOM tree building routines.
14033
 *
14034
 * User data (void *) is stored within the parser context in the
14035
 * context's _private member, so it is available nearly everywhere in libxml
14036
 *
14037
 * Returns the resulting document tree
14038
 */
14039
14040
xmlDocPtr
14041
xmlSAXParseMemoryWithData(xmlSAXHandlerPtr sax, const char *buffer,
14042
            int size, int recovery, void *data) {
14043
    xmlDocPtr ret;
14044
    xmlParserCtxtPtr ctxt;
14045
14046
    xmlInitParser();
14047
14048
    ctxt = xmlCreateMemoryParserCtxt(buffer, size);
14049
    if (ctxt == NULL) return(NULL);
14050
    if (sax != NULL) {
14051
  if (ctxt->sax != NULL)
14052
      xmlFree(ctxt->sax);
14053
        ctxt->sax = sax;
14054
    }
14055
    xmlDetectSAX2(ctxt);
14056
    if (data!=NULL) {
14057
  ctxt->_private=data;
14058
    }
14059
14060
    ctxt->recovery = recovery;
14061
14062
    xmlParseDocument(ctxt);
14063
14064
    if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
14065
    else {
14066
       ret = NULL;
14067
       xmlFreeDoc(ctxt->myDoc);
14068
       ctxt->myDoc = NULL;
14069
    }
14070
    if (sax != NULL)
14071
  ctxt->sax = NULL;
14072
    xmlFreeParserCtxt(ctxt);
14073
14074
    return(ret);
14075
}
14076
14077
/**
14078
 * xmlSAXParseMemory:
14079
 * @sax:  the SAX handler block
14080
 * @buffer:  an pointer to a char array
14081
 * @size:  the size of the array
14082
 * @recovery:  work in recovery mode, i.e. tries to read not Well Formed
14083
 *             documents
14084
 *
14085
 * DEPRECATED: Use xmlNewSAXParserCtxt and xmlCtxtReadMemory.
14086
 *
14087
 * parse an XML in-memory block and use the given SAX function block
14088
 * to handle the parsing callback. If sax is NULL, fallback to the default
14089
 * DOM tree building routines.
14090
 *
14091
 * Returns the resulting document tree
14092
 */
14093
xmlDocPtr
14094
xmlSAXParseMemory(xmlSAXHandlerPtr sax, const char *buffer,
14095
            int size, int recovery) {
14096
    return xmlSAXParseMemoryWithData(sax, buffer, size, recovery, NULL);
14097
}
14098
14099
/**
14100
 * xmlParseMemory:
14101
 * @buffer:  an pointer to a char array
14102
 * @size:  the size of the array
14103
 *
14104
 * DEPRECATED: Use xmlReadMemory.
14105
 *
14106
 * parse an XML in-memory block and build a tree.
14107
 *
14108
 * Returns the resulting document tree
14109
 */
14110
14111
xmlDocPtr xmlParseMemory(const char *buffer, int size) {
14112
   return(xmlSAXParseMemory(NULL, buffer, size, 0));
14113
}
14114
14115
/**
14116
 * xmlRecoverMemory:
14117
 * @buffer:  an pointer to a char array
14118
 * @size:  the size of the array
14119
 *
14120
 * DEPRECATED: Use xmlReadMemory with XML_PARSE_RECOVER.
14121
 *
14122
 * parse an XML in-memory block and build a tree.
14123
 * In the case the document is not Well Formed, an attempt to
14124
 * build a tree is tried anyway
14125
 *
14126
 * Returns the resulting document tree or NULL in case of error
14127
 */
14128
14129
xmlDocPtr xmlRecoverMemory(const char *buffer, int size) {
14130
   return(xmlSAXParseMemory(NULL, buffer, size, 1));
14131
}
14132
14133
/**
14134
 * xmlSAXUserParseMemory:
14135
 * @sax:  a SAX handler
14136
 * @user_data:  The user data returned on SAX callbacks
14137
 * @buffer:  an in-memory XML document input
14138
 * @size:  the length of the XML document in bytes
14139
 *
14140
 * DEPRECATED: Use xmlNewSAXParserCtxt and xmlCtxtReadMemory.
14141
 *
14142
 * parse an XML in-memory buffer and call the given SAX handler routines.
14143
 *
14144
 * Returns 0 in case of success or a error number otherwise
14145
 */
14146
int xmlSAXUserParseMemory(xmlSAXHandlerPtr sax, void *user_data,
14147
        const char *buffer, int size) {
14148
    int ret = 0;
14149
    xmlParserCtxtPtr ctxt;
14150
14151
    xmlInitParser();
14152
14153
    ctxt = xmlCreateMemoryParserCtxt(buffer, size);
14154
    if (ctxt == NULL) return -1;
14155
    if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
14156
        xmlFree(ctxt->sax);
14157
    ctxt->sax = sax;
14158
    xmlDetectSAX2(ctxt);
14159
14160
    if (user_data != NULL)
14161
  ctxt->userData = user_data;
14162
14163
    xmlParseDocument(ctxt);
14164
14165
    if (ctxt->wellFormed)
14166
  ret = 0;
14167
    else {
14168
        if (ctxt->errNo != 0)
14169
      ret = ctxt->errNo;
14170
  else
14171
      ret = -1;
14172
    }
14173
    if (sax != NULL)
14174
        ctxt->sax = NULL;
14175
    if (ctxt->myDoc != NULL) {
14176
        xmlFreeDoc(ctxt->myDoc);
14177
  ctxt->myDoc = NULL;
14178
    }
14179
    xmlFreeParserCtxt(ctxt);
14180
14181
    return ret;
14182
}
14183
#endif /* LIBXML_SAX1_ENABLED */
14184
14185
/**
14186
 * xmlCreateDocParserCtxt:
14187
 * @cur:  a pointer to an array of xmlChar
14188
 *
14189
 * Creates a parser context for an XML in-memory document.
14190
 *
14191
 * Returns the new parser context or NULL
14192
 */
14193
xmlParserCtxtPtr
14194
0
xmlCreateDocParserCtxt(const xmlChar *cur) {
14195
0
    int len;
14196
14197
0
    if (cur == NULL)
14198
0
  return(NULL);
14199
0
    len = xmlStrlen(cur);
14200
0
    return(xmlCreateMemoryParserCtxt((const char *)cur, len));
14201
0
}
14202
14203
#ifdef LIBXML_SAX1_ENABLED
14204
/**
14205
 * xmlSAXParseDoc:
14206
 * @sax:  the SAX handler block
14207
 * @cur:  a pointer to an array of xmlChar
14208
 * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
14209
 *             documents
14210
 *
14211
 * DEPRECATED: Use xmlNewSAXParserCtxt and xmlCtxtReadDoc.
14212
 *
14213
 * parse an XML in-memory document and build a tree.
14214
 * It use the given SAX function block to handle the parsing callback.
14215
 * If sax is NULL, fallback to the default DOM tree building routines.
14216
 *
14217
 * Returns the resulting document tree
14218
 */
14219
14220
xmlDocPtr
14221
xmlSAXParseDoc(xmlSAXHandlerPtr sax, const xmlChar *cur, int recovery) {
14222
    xmlDocPtr ret;
14223
    xmlParserCtxtPtr ctxt;
14224
    xmlSAXHandlerPtr oldsax = NULL;
14225
14226
    if (cur == NULL) return(NULL);
14227
14228
14229
    ctxt = xmlCreateDocParserCtxt(cur);
14230
    if (ctxt == NULL) return(NULL);
14231
    if (sax != NULL) {
14232
        oldsax = ctxt->sax;
14233
        ctxt->sax = sax;
14234
        ctxt->userData = NULL;
14235
    }
14236
    xmlDetectSAX2(ctxt);
14237
14238
    xmlParseDocument(ctxt);
14239
    if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
14240
    else {
14241
       ret = NULL;
14242
       xmlFreeDoc(ctxt->myDoc);
14243
       ctxt->myDoc = NULL;
14244
    }
14245
    if (sax != NULL)
14246
  ctxt->sax = oldsax;
14247
    xmlFreeParserCtxt(ctxt);
14248
14249
    return(ret);
14250
}
14251
14252
/**
14253
 * xmlParseDoc:
14254
 * @cur:  a pointer to an array of xmlChar
14255
 *
14256
 * DEPRECATED: Use xmlReadDoc.
14257
 *
14258
 * parse an XML in-memory document and build a tree.
14259
 *
14260
 * Returns the resulting document tree
14261
 */
14262
14263
xmlDocPtr
14264
xmlParseDoc(const xmlChar *cur) {
14265
    return(xmlSAXParseDoc(NULL, cur, 0));
14266
}
14267
#endif /* LIBXML_SAX1_ENABLED */
14268
14269
#ifdef LIBXML_LEGACY_ENABLED
14270
/************************************************************************
14271
 *                  *
14272
 *  Specific function to keep track of entities references    *
14273
 *  and used by the XSLT debugger         *
14274
 *                  *
14275
 ************************************************************************/
14276
14277
static xmlEntityReferenceFunc xmlEntityRefFunc = NULL;
14278
14279
/**
14280
 * xmlAddEntityReference:
14281
 * @ent : A valid entity
14282
 * @firstNode : A valid first node for children of entity
14283
 * @lastNode : A valid last node of children entity
14284
 *
14285
 * Notify of a reference to an entity of type XML_EXTERNAL_GENERAL_PARSED_ENTITY
14286
 */
14287
static void
14288
xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
14289
                      xmlNodePtr lastNode)
14290
{
14291
    if (xmlEntityRefFunc != NULL) {
14292
        (*xmlEntityRefFunc) (ent, firstNode, lastNode);
14293
    }
14294
}
14295
14296
14297
/**
14298
 * xmlSetEntityReferenceFunc:
14299
 * @func: A valid function
14300
 *
14301
 * Set the function to call call back when a xml reference has been made
14302
 */
14303
void
14304
xmlSetEntityReferenceFunc(xmlEntityReferenceFunc func)
14305
{
14306
    xmlEntityRefFunc = func;
14307
}
14308
#endif /* LIBXML_LEGACY_ENABLED */
14309
14310
/************************************************************************
14311
 *                  *
14312
 *        Miscellaneous       *
14313
 *                  *
14314
 ************************************************************************/
14315
14316
static int xmlParserInitialized = 0;
14317
14318
/**
14319
 * xmlInitParser:
14320
 *
14321
 * Initialization function for the XML parser.
14322
 * This is not reentrant. Call once before processing in case of
14323
 * use in multithreaded programs.
14324
 */
14325
14326
void
14327
35.0M
xmlInitParser(void) {
14328
    /*
14329
     * Note that the initialization code must not make memory allocations.
14330
     */
14331
35.0M
    if (xmlParserInitialized != 0)
14332
35.0M
  return;
14333
14334
4
#ifdef LIBXML_THREAD_ENABLED
14335
4
    __xmlGlobalInitMutexLock();
14336
4
    if (xmlParserInitialized == 0) {
14337
4
#endif
14338
#if defined(_WIN32) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
14339
        if (xmlFree == free)
14340
            atexit(xmlCleanupParser);
14341
#endif
14342
14343
4
  xmlInitThreadsInternal();
14344
4
  xmlInitGlobalsInternal();
14345
4
  xmlInitMemoryInternal();
14346
4
        __xmlInitializeDict();
14347
4
  xmlInitEncodingInternal();
14348
4
  xmlRegisterDefaultInputCallbacks();
14349
4
#ifdef LIBXML_OUTPUT_ENABLED
14350
4
  xmlRegisterDefaultOutputCallbacks();
14351
4
#endif /* LIBXML_OUTPUT_ENABLED */
14352
4
#if defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
14353
4
  xmlInitXPathInternal();
14354
4
#endif
14355
4
  xmlParserInitialized = 1;
14356
4
#ifdef LIBXML_THREAD_ENABLED
14357
4
    }
14358
4
    __xmlGlobalInitMutexUnlock();
14359
4
#endif
14360
4
}
14361
14362
/**
14363
 * xmlCleanupParser:
14364
 *
14365
 * This function name is somewhat misleading. It does not clean up
14366
 * parser state, it cleans up memory allocated by the library itself.
14367
 * It is a cleanup function for the XML library. It tries to reclaim all
14368
 * related global memory allocated for the library processing.
14369
 * It doesn't deallocate any document related memory. One should
14370
 * call xmlCleanupParser() only when the process has finished using
14371
 * the library and all XML/HTML documents built with it.
14372
 * See also xmlInitParser() which has the opposite function of preparing
14373
 * the library for operations.
14374
 *
14375
 * WARNING: if your application is multithreaded or has plugin support
14376
 *          calling this may crash the application if another thread or
14377
 *          a plugin is still using libxml2. It's sometimes very hard to
14378
 *          guess if libxml2 is in use in the application, some libraries
14379
 *          or plugins may use it without notice. In case of doubt abstain
14380
 *          from calling this function or do it just before calling exit()
14381
 *          to avoid leak reports from valgrind !
14382
 */
14383
14384
void
14385
0
xmlCleanupParser(void) {
14386
0
    if (!xmlParserInitialized)
14387
0
  return;
14388
14389
0
    xmlCleanupCharEncodingHandlers();
14390
0
#ifdef LIBXML_CATALOG_ENABLED
14391
0
    xmlCatalogCleanup();
14392
0
#endif
14393
0
    xmlCleanupDictInternal();
14394
0
    xmlCleanupInputCallbacks();
14395
0
#ifdef LIBXML_OUTPUT_ENABLED
14396
0
    xmlCleanupOutputCallbacks();
14397
0
#endif
14398
#ifdef LIBXML_SCHEMAS_ENABLED
14399
    xmlSchemaCleanupTypes();
14400
    xmlRelaxNGCleanupTypes();
14401
#endif
14402
0
    xmlCleanupGlobalsInternal();
14403
0
    xmlCleanupThreadsInternal();
14404
0
    xmlCleanupMemoryInternal();
14405
0
    xmlParserInitialized = 0;
14406
0
}
14407
14408
#if defined(HAVE_ATTRIBUTE_DESTRUCTOR) && !defined(LIBXML_STATIC) && \
14409
    !defined(_WIN32)
14410
static void
14411
ATTRIBUTE_DESTRUCTOR
14412
0
xmlDestructor(void) {
14413
    /*
14414
     * Calling custom deallocation functions in a destructor can cause
14415
     * problems, for example with Nokogiri.
14416
     */
14417
0
    if (xmlFree == free)
14418
0
        xmlCleanupParser();
14419
0
}
14420
#endif
14421
14422
/************************************************************************
14423
 *                  *
14424
 *  New set (2.6.0) of simpler and more flexible APIs   *
14425
 *                  *
14426
 ************************************************************************/
14427
14428
/**
14429
 * DICT_FREE:
14430
 * @str:  a string
14431
 *
14432
 * Free a string if it is not owned by the "dict" dictionary in the
14433
 * current scope
14434
 */
14435
#define DICT_FREE(str)            \
14436
0
  if ((str) && ((!dict) ||       \
14437
0
      (xmlDictOwns(dict, (const xmlChar *)(str)) == 0)))  \
14438
0
      xmlFree((char *)(str));
14439
14440
/**
14441
 * xmlCtxtReset:
14442
 * @ctxt: an XML parser context
14443
 *
14444
 * Reset a parser context
14445
 */
14446
void
14447
xmlCtxtReset(xmlParserCtxtPtr ctxt)
14448
0
{
14449
0
    xmlParserInputPtr input;
14450
0
    xmlDictPtr dict;
14451
14452
0
    if (ctxt == NULL)
14453
0
        return;
14454
14455
0
    dict = ctxt->dict;
14456
14457
0
    while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
14458
0
        xmlFreeInputStream(input);
14459
0
    }
14460
0
    ctxt->inputNr = 0;
14461
0
    ctxt->input = NULL;
14462
14463
0
    ctxt->spaceNr = 0;
14464
0
    if (ctxt->spaceTab != NULL) {
14465
0
  ctxt->spaceTab[0] = -1;
14466
0
  ctxt->space = &ctxt->spaceTab[0];
14467
0
    } else {
14468
0
        ctxt->space = NULL;
14469
0
    }
14470
14471
14472
0
    ctxt->nodeNr = 0;
14473
0
    ctxt->node = NULL;
14474
14475
0
    ctxt->nameNr = 0;
14476
0
    ctxt->name = NULL;
14477
14478
0
    ctxt->nsNr = 0;
14479
14480
0
    DICT_FREE(ctxt->version);
14481
0
    ctxt->version = NULL;
14482
0
    DICT_FREE(ctxt->encoding);
14483
0
    ctxt->encoding = NULL;
14484
0
    DICT_FREE(ctxt->directory);
14485
0
    ctxt->directory = NULL;
14486
0
    DICT_FREE(ctxt->extSubURI);
14487
0
    ctxt->extSubURI = NULL;
14488
0
    DICT_FREE(ctxt->extSubSystem);
14489
0
    ctxt->extSubSystem = NULL;
14490
0
    if (ctxt->myDoc != NULL)
14491
0
        xmlFreeDoc(ctxt->myDoc);
14492
0
    ctxt->myDoc = NULL;
14493
14494
0
    ctxt->standalone = -1;
14495
0
    ctxt->hasExternalSubset = 0;
14496
0
    ctxt->hasPErefs = 0;
14497
0
    ctxt->html = 0;
14498
0
    ctxt->external = 0;
14499
0
    ctxt->instate = XML_PARSER_START;
14500
0
    ctxt->token = 0;
14501
14502
0
    ctxt->wellFormed = 1;
14503
0
    ctxt->nsWellFormed = 1;
14504
0
    ctxt->disableSAX = 0;
14505
0
    ctxt->valid = 1;
14506
#if 0
14507
    ctxt->vctxt.userData = ctxt;
14508
    ctxt->vctxt.error = xmlParserValidityError;
14509
    ctxt->vctxt.warning = xmlParserValidityWarning;
14510
#endif
14511
0
    ctxt->record_info = 0;
14512
0
    ctxt->checkIndex = 0;
14513
0
    ctxt->endCheckState = 0;
14514
0
    ctxt->inSubset = 0;
14515
0
    ctxt->errNo = XML_ERR_OK;
14516
0
    ctxt->depth = 0;
14517
0
    ctxt->charset = XML_CHAR_ENCODING_UTF8;
14518
0
    ctxt->catalogs = NULL;
14519
0
    ctxt->sizeentities = 0;
14520
0
    ctxt->sizeentcopy = 0;
14521
0
    xmlInitNodeInfoSeq(&ctxt->node_seq);
14522
14523
0
    if (ctxt->attsDefault != NULL) {
14524
0
        xmlHashFree(ctxt->attsDefault, xmlHashDefaultDeallocator);
14525
0
        ctxt->attsDefault = NULL;
14526
0
    }
14527
0
    if (ctxt->attsSpecial != NULL) {
14528
0
        xmlHashFree(ctxt->attsSpecial, NULL);
14529
0
        ctxt->attsSpecial = NULL;
14530
0
    }
14531
14532
0
#ifdef LIBXML_CATALOG_ENABLED
14533
0
    if (ctxt->catalogs != NULL)
14534
0
  xmlCatalogFreeLocal(ctxt->catalogs);
14535
0
#endif
14536
0
    ctxt->nbErrors = 0;
14537
0
    ctxt->nbWarnings = 0;
14538
0
    if (ctxt->lastError.code != XML_ERR_OK)
14539
0
        xmlResetError(&ctxt->lastError);
14540
0
}
14541
14542
/**
14543
 * xmlCtxtResetPush:
14544
 * @ctxt: an XML parser context
14545
 * @chunk:  a pointer to an array of chars
14546
 * @size:  number of chars in the array
14547
 * @filename:  an optional file name or URI
14548
 * @encoding:  the document encoding, or NULL
14549
 *
14550
 * Reset a push parser context
14551
 *
14552
 * Returns 0 in case of success and 1 in case of error
14553
 */
14554
int
14555
xmlCtxtResetPush(xmlParserCtxtPtr ctxt, const char *chunk,
14556
                 int size, const char *filename, const char *encoding)
14557
0
{
14558
0
    xmlParserInputPtr inputStream;
14559
0
    xmlParserInputBufferPtr buf;
14560
0
    xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
14561
14562
0
    if (ctxt == NULL)
14563
0
        return(1);
14564
14565
0
    if ((encoding == NULL) && (chunk != NULL) && (size >= 4))
14566
0
        enc = xmlDetectCharEncoding((const xmlChar *) chunk, size);
14567
14568
0
    buf = xmlAllocParserInputBuffer(enc);
14569
0
    if (buf == NULL)
14570
0
        return(1);
14571
14572
0
    if (ctxt == NULL) {
14573
0
        xmlFreeParserInputBuffer(buf);
14574
0
        return(1);
14575
0
    }
14576
14577
0
    xmlCtxtReset(ctxt);
14578
14579
0
    if (filename == NULL) {
14580
0
        ctxt->directory = NULL;
14581
0
    } else {
14582
0
        ctxt->directory = xmlParserGetDirectory(filename);
14583
0
    }
14584
14585
0
    inputStream = xmlNewInputStream(ctxt);
14586
0
    if (inputStream == NULL) {
14587
0
        xmlFreeParserInputBuffer(buf);
14588
0
        return(1);
14589
0
    }
14590
14591
0
    if (filename == NULL)
14592
0
        inputStream->filename = NULL;
14593
0
    else
14594
0
        inputStream->filename = (char *)
14595
0
            xmlCanonicPath((const xmlChar *) filename);
14596
0
    inputStream->buf = buf;
14597
0
    xmlBufResetInput(buf->buffer, inputStream);
14598
14599
0
    inputPush(ctxt, inputStream);
14600
14601
0
    if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
14602
0
        (ctxt->input->buf != NULL)) {
14603
0
  size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer, ctxt->input);
14604
0
        size_t cur = ctxt->input->cur - ctxt->input->base;
14605
14606
0
        xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
14607
14608
0
        xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur);
14609
#ifdef DEBUG_PUSH
14610
        xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
14611
#endif
14612
0
    }
14613
14614
0
    if (encoding != NULL) {
14615
0
        xmlCharEncodingHandlerPtr hdlr;
14616
14617
0
        if (ctxt->encoding != NULL)
14618
0
      xmlFree((xmlChar *) ctxt->encoding);
14619
0
        ctxt->encoding = xmlStrdup((const xmlChar *) encoding);
14620
14621
0
        hdlr = xmlFindCharEncodingHandler(encoding);
14622
0
        if (hdlr != NULL) {
14623
0
            xmlSwitchToEncoding(ctxt, hdlr);
14624
0
  } else {
14625
0
      xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
14626
0
            "Unsupported encoding %s\n", BAD_CAST encoding);
14627
0
        }
14628
0
    } else if (enc != XML_CHAR_ENCODING_NONE) {
14629
0
        xmlSwitchEncoding(ctxt, enc);
14630
0
    }
14631
14632
0
    return(0);
14633
0
}
14634
14635
14636
/**
14637
 * xmlCtxtUseOptionsInternal:
14638
 * @ctxt: an XML parser context
14639
 * @options:  a combination of xmlParserOption
14640
 * @encoding:  the user provided encoding to use
14641
 *
14642
 * Applies the options to the parser context
14643
 *
14644
 * Returns 0 in case of success, the set of unknown or unimplemented options
14645
 *         in case of error.
14646
 */
14647
static int
14648
xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options, const char *encoding)
14649
357k
{
14650
357k
    if (ctxt == NULL)
14651
0
        return(-1);
14652
357k
    if (encoding != NULL) {
14653
0
        if (ctxt->encoding != NULL)
14654
0
      xmlFree((xmlChar *) ctxt->encoding);
14655
0
        ctxt->encoding = xmlStrdup((const xmlChar *) encoding);
14656
0
    }
14657
357k
    if (options & XML_PARSE_RECOVER) {
14658
157
        ctxt->recovery = 1;
14659
157
        options -= XML_PARSE_RECOVER;
14660
157
  ctxt->options |= XML_PARSE_RECOVER;
14661
157
    } else
14662
357k
        ctxt->recovery = 0;
14663
357k
    if (options & XML_PARSE_DTDLOAD) {
14664
357k
        ctxt->loadsubset = XML_DETECT_IDS;
14665
357k
        options -= XML_PARSE_DTDLOAD;
14666
357k
  ctxt->options |= XML_PARSE_DTDLOAD;
14667
357k
    } else
14668
157
        ctxt->loadsubset = 0;
14669
357k
    if (options & XML_PARSE_DTDATTR) {
14670
357k
        ctxt->loadsubset |= XML_COMPLETE_ATTRS;
14671
357k
        options -= XML_PARSE_DTDATTR;
14672
357k
  ctxt->options |= XML_PARSE_DTDATTR;
14673
357k
    }
14674
357k
    if (options & XML_PARSE_NOENT) {
14675
357k
        ctxt->replaceEntities = 1;
14676
        /* ctxt->loadsubset |= XML_DETECT_IDS; */
14677
357k
        options -= XML_PARSE_NOENT;
14678
357k
  ctxt->options |= XML_PARSE_NOENT;
14679
357k
    } else
14680
157
        ctxt->replaceEntities = 0;
14681
357k
    if (options & XML_PARSE_PEDANTIC) {
14682
0
        ctxt->pedantic = 1;
14683
0
        options -= XML_PARSE_PEDANTIC;
14684
0
  ctxt->options |= XML_PARSE_PEDANTIC;
14685
0
    } else
14686
357k
        ctxt->pedantic = 0;
14687
357k
    if (options & XML_PARSE_NOBLANKS) {
14688
0
        ctxt->keepBlanks = 0;
14689
0
        ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
14690
0
        options -= XML_PARSE_NOBLANKS;
14691
0
  ctxt->options |= XML_PARSE_NOBLANKS;
14692
0
    } else
14693
357k
        ctxt->keepBlanks = 1;
14694
357k
    if (options & XML_PARSE_DTDVALID) {
14695
0
        ctxt->validate = 1;
14696
0
        if (options & XML_PARSE_NOWARNING)
14697
0
            ctxt->vctxt.warning = NULL;
14698
0
        if (options & XML_PARSE_NOERROR)
14699
0
            ctxt->vctxt.error = NULL;
14700
0
        options -= XML_PARSE_DTDVALID;
14701
0
  ctxt->options |= XML_PARSE_DTDVALID;
14702
0
    } else
14703
357k
        ctxt->validate = 0;
14704
357k
    if (options & XML_PARSE_NOWARNING) {
14705
0
        ctxt->sax->warning = NULL;
14706
0
        options -= XML_PARSE_NOWARNING;
14707
0
    }
14708
357k
    if (options & XML_PARSE_NOERROR) {
14709
0
        ctxt->sax->error = NULL;
14710
0
        ctxt->sax->fatalError = NULL;
14711
0
        options -= XML_PARSE_NOERROR;
14712
0
    }
14713
#ifdef LIBXML_SAX1_ENABLED
14714
    if (options & XML_PARSE_SAX1) {
14715
        ctxt->sax->startElement = xmlSAX2StartElement;
14716
        ctxt->sax->endElement = xmlSAX2EndElement;
14717
        ctxt->sax->startElementNs = NULL;
14718
        ctxt->sax->endElementNs = NULL;
14719
        ctxt->sax->initialized = 1;
14720
        options -= XML_PARSE_SAX1;
14721
  ctxt->options |= XML_PARSE_SAX1;
14722
    }
14723
#endif /* LIBXML_SAX1_ENABLED */
14724
357k
    if (options & XML_PARSE_NODICT) {
14725
0
        ctxt->dictNames = 0;
14726
0
        options -= XML_PARSE_NODICT;
14727
0
  ctxt->options |= XML_PARSE_NODICT;
14728
357k
    } else {
14729
357k
        ctxt->dictNames = 1;
14730
357k
    }
14731
357k
    if (options & XML_PARSE_NOCDATA) {
14732
357k
        ctxt->sax->cdataBlock = NULL;
14733
357k
        options -= XML_PARSE_NOCDATA;
14734
357k
  ctxt->options |= XML_PARSE_NOCDATA;
14735
357k
    }
14736
357k
    if (options & XML_PARSE_NSCLEAN) {
14737
0
  ctxt->options |= XML_PARSE_NSCLEAN;
14738
0
        options -= XML_PARSE_NSCLEAN;
14739
0
    }
14740
357k
    if (options & XML_PARSE_NONET) {
14741
0
  ctxt->options |= XML_PARSE_NONET;
14742
0
        options -= XML_PARSE_NONET;
14743
0
    }
14744
357k
    if (options & XML_PARSE_COMPACT) {
14745
0
  ctxt->options |= XML_PARSE_COMPACT;
14746
0
        options -= XML_PARSE_COMPACT;
14747
0
    }
14748
357k
    if (options & XML_PARSE_OLD10) {
14749
0
  ctxt->options |= XML_PARSE_OLD10;
14750
0
        options -= XML_PARSE_OLD10;
14751
0
    }
14752
357k
    if (options & XML_PARSE_NOBASEFIX) {
14753
0
  ctxt->options |= XML_PARSE_NOBASEFIX;
14754
0
        options -= XML_PARSE_NOBASEFIX;
14755
0
    }
14756
357k
    if (options & XML_PARSE_HUGE) {
14757
0
  ctxt->options |= XML_PARSE_HUGE;
14758
0
        options -= XML_PARSE_HUGE;
14759
0
        if (ctxt->dict != NULL)
14760
0
            xmlDictSetLimit(ctxt->dict, 0);
14761
0
    }
14762
357k
    if (options & XML_PARSE_OLDSAX) {
14763
0
  ctxt->options |= XML_PARSE_OLDSAX;
14764
0
        options -= XML_PARSE_OLDSAX;
14765
0
    }
14766
357k
    if (options & XML_PARSE_IGNORE_ENC) {
14767
0
  ctxt->options |= XML_PARSE_IGNORE_ENC;
14768
0
        options -= XML_PARSE_IGNORE_ENC;
14769
0
    }
14770
357k
    if (options & XML_PARSE_BIG_LINES) {
14771
0
  ctxt->options |= XML_PARSE_BIG_LINES;
14772
0
        options -= XML_PARSE_BIG_LINES;
14773
0
    }
14774
357k
    ctxt->linenumbers = 1;
14775
357k
    return (options);
14776
357k
}
14777
14778
/**
14779
 * xmlCtxtUseOptions:
14780
 * @ctxt: an XML parser context
14781
 * @options:  a combination of xmlParserOption
14782
 *
14783
 * Applies the options to the parser context
14784
 *
14785
 * Returns 0 in case of success, the set of unknown or unimplemented options
14786
 *         in case of error.
14787
 */
14788
int
14789
xmlCtxtUseOptions(xmlParserCtxtPtr ctxt, int options)
14790
302k
{
14791
302k
   return(xmlCtxtUseOptionsInternal(ctxt, options, NULL));
14792
302k
}
14793
14794
/**
14795
 * xmlDoRead:
14796
 * @ctxt:  an XML parser context
14797
 * @URL:  the base URL to use for the document
14798
 * @encoding:  the document encoding, or NULL
14799
 * @options:  a combination of xmlParserOption
14800
 * @reuse:  keep the context for reuse
14801
 *
14802
 * Common front-end for the xmlRead functions
14803
 *
14804
 * Returns the resulting document tree or NULL
14805
 */
14806
static xmlDocPtr
14807
xmlDoRead(xmlParserCtxtPtr ctxt, const char *URL, const char *encoding,
14808
          int options, int reuse)
14809
55.1k
{
14810
55.1k
    xmlDocPtr ret;
14811
14812
55.1k
    xmlCtxtUseOptionsInternal(ctxt, options, encoding);
14813
55.1k
    if (encoding != NULL) {
14814
0
        xmlCharEncodingHandlerPtr hdlr;
14815
14816
0
  hdlr = xmlFindCharEncodingHandler(encoding);
14817
0
  if (hdlr != NULL)
14818
0
      xmlSwitchToEncoding(ctxt, hdlr);
14819
0
    }
14820
55.1k
    if ((URL != NULL) && (ctxt->input != NULL) &&
14821
55.1k
        (ctxt->input->filename == NULL))
14822
54.9k
        ctxt->input->filename = (char *) xmlStrdup((const xmlChar *) URL);
14823
55.1k
    xmlParseDocument(ctxt);
14824
55.1k
    if ((ctxt->wellFormed) || ctxt->recovery)
14825
42.2k
        ret = ctxt->myDoc;
14826
12.9k
    else {
14827
12.9k
        ret = NULL;
14828
12.9k
  if (ctxt->myDoc != NULL) {
14829
11.2k
      xmlFreeDoc(ctxt->myDoc);
14830
11.2k
  }
14831
12.9k
    }
14832
55.1k
    ctxt->myDoc = NULL;
14833
55.1k
    if (!reuse) {
14834
55.1k
  xmlFreeParserCtxt(ctxt);
14835
55.1k
    }
14836
14837
55.1k
    return (ret);
14838
55.1k
}
14839
14840
/**
14841
 * xmlReadDoc:
14842
 * @cur:  a pointer to a zero terminated string
14843
 * @URL:  the base URL to use for the document
14844
 * @encoding:  the document encoding, or NULL
14845
 * @options:  a combination of xmlParserOption
14846
 *
14847
 * parse an XML in-memory document and build a tree.
14848
 *
14849
 * Returns the resulting document tree
14850
 */
14851
xmlDocPtr
14852
xmlReadDoc(const xmlChar * cur, const char *URL, const char *encoding, int options)
14853
0
{
14854
0
    xmlParserCtxtPtr ctxt;
14855
14856
0
    if (cur == NULL)
14857
0
        return (NULL);
14858
0
    xmlInitParser();
14859
14860
0
    ctxt = xmlCreateDocParserCtxt(cur);
14861
0
    if (ctxt == NULL)
14862
0
        return (NULL);
14863
0
    return (xmlDoRead(ctxt, URL, encoding, options, 0));
14864
0
}
14865
14866
/**
14867
 * xmlReadFile:
14868
 * @filename:  a file or URL
14869
 * @encoding:  the document encoding, or NULL
14870
 * @options:  a combination of xmlParserOption
14871
 *
14872
 * parse an XML file from the filesystem or the network.
14873
 *
14874
 * Returns the resulting document tree
14875
 */
14876
xmlDocPtr
14877
xmlReadFile(const char *filename, const char *encoding, int options)
14878
0
{
14879
0
    xmlParserCtxtPtr ctxt;
14880
14881
0
    xmlInitParser();
14882
0
    ctxt = xmlCreateURLParserCtxt(filename, options);
14883
0
    if (ctxt == NULL)
14884
0
        return (NULL);
14885
0
    return (xmlDoRead(ctxt, NULL, encoding, options, 0));
14886
0
}
14887
14888
/**
14889
 * xmlReadMemory:
14890
 * @buffer:  a pointer to a char array
14891
 * @size:  the size of the array
14892
 * @URL:  the base URL to use for the document
14893
 * @encoding:  the document encoding, or NULL
14894
 * @options:  a combination of xmlParserOption
14895
 *
14896
 * parse an XML in-memory document and build a tree.
14897
 *
14898
 * Returns the resulting document tree
14899
 */
14900
xmlDocPtr
14901
xmlReadMemory(const char *buffer, int size, const char *URL, const char *encoding, int options)
14902
55.1k
{
14903
55.1k
    xmlParserCtxtPtr ctxt;
14904
14905
55.1k
    xmlInitParser();
14906
55.1k
    ctxt = xmlCreateMemoryParserCtxt(buffer, size);
14907
55.1k
    if (ctxt == NULL)
14908
20
        return (NULL);
14909
55.1k
    return (xmlDoRead(ctxt, URL, encoding, options, 0));
14910
55.1k
}
14911
14912
/**
14913
 * xmlReadFd:
14914
 * @fd:  an open file descriptor
14915
 * @URL:  the base URL to use for the document
14916
 * @encoding:  the document encoding, or NULL
14917
 * @options:  a combination of xmlParserOption
14918
 *
14919
 * parse an XML from a file descriptor and build a tree.
14920
 * NOTE that the file descriptor will not be closed when the
14921
 *      reader is closed or reset.
14922
 *
14923
 * Returns the resulting document tree
14924
 */
14925
xmlDocPtr
14926
xmlReadFd(int fd, const char *URL, const char *encoding, int options)
14927
0
{
14928
0
    xmlParserCtxtPtr ctxt;
14929
0
    xmlParserInputBufferPtr input;
14930
0
    xmlParserInputPtr stream;
14931
14932
0
    if (fd < 0)
14933
0
        return (NULL);
14934
0
    xmlInitParser();
14935
14936
0
    input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
14937
0
    if (input == NULL)
14938
0
        return (NULL);
14939
0
    input->closecallback = NULL;
14940
0
    ctxt = xmlNewParserCtxt();
14941
0
    if (ctxt == NULL) {
14942
0
        xmlFreeParserInputBuffer(input);
14943
0
        return (NULL);
14944
0
    }
14945
0
    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
14946
0
    if (stream == NULL) {
14947
0
        xmlFreeParserInputBuffer(input);
14948
0
  xmlFreeParserCtxt(ctxt);
14949
0
        return (NULL);
14950
0
    }
14951
0
    inputPush(ctxt, stream);
14952
0
    return (xmlDoRead(ctxt, URL, encoding, options, 0));
14953
0
}
14954
14955
/**
14956
 * xmlReadIO:
14957
 * @ioread:  an I/O read function
14958
 * @ioclose:  an I/O close function
14959
 * @ioctx:  an I/O handler
14960
 * @URL:  the base URL to use for the document
14961
 * @encoding:  the document encoding, or NULL
14962
 * @options:  a combination of xmlParserOption
14963
 *
14964
 * parse an XML document from I/O functions and source and build a tree.
14965
 *
14966
 * Returns the resulting document tree
14967
 */
14968
xmlDocPtr
14969
xmlReadIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
14970
          void *ioctx, const char *URL, const char *encoding, int options)
14971
0
{
14972
0
    xmlParserCtxtPtr ctxt;
14973
0
    xmlParserInputBufferPtr input;
14974
0
    xmlParserInputPtr stream;
14975
14976
0
    if (ioread == NULL)
14977
0
        return (NULL);
14978
0
    xmlInitParser();
14979
14980
0
    input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
14981
0
                                         XML_CHAR_ENCODING_NONE);
14982
0
    if (input == NULL) {
14983
0
        if (ioclose != NULL)
14984
0
            ioclose(ioctx);
14985
0
        return (NULL);
14986
0
    }
14987
0
    ctxt = xmlNewParserCtxt();
14988
0
    if (ctxt == NULL) {
14989
0
        xmlFreeParserInputBuffer(input);
14990
0
        return (NULL);
14991
0
    }
14992
0
    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
14993
0
    if (stream == NULL) {
14994
0
        xmlFreeParserInputBuffer(input);
14995
0
  xmlFreeParserCtxt(ctxt);
14996
0
        return (NULL);
14997
0
    }
14998
0
    inputPush(ctxt, stream);
14999
0
    return (xmlDoRead(ctxt, URL, encoding, options, 0));
15000
0
}
15001
15002
/**
15003
 * xmlCtxtReadDoc:
15004
 * @ctxt:  an XML parser context
15005
 * @cur:  a pointer to a zero terminated string
15006
 * @URL:  the base URL to use for the document
15007
 * @encoding:  the document encoding, or NULL
15008
 * @options:  a combination of xmlParserOption
15009
 *
15010
 * parse an XML in-memory document and build a tree.
15011
 * This reuses the existing @ctxt parser context
15012
 *
15013
 * Returns the resulting document tree
15014
 */
15015
xmlDocPtr
15016
xmlCtxtReadDoc(xmlParserCtxtPtr ctxt, const xmlChar * cur,
15017
               const char *URL, const char *encoding, int options)
15018
0
{
15019
0
    if (cur == NULL)
15020
0
        return (NULL);
15021
0
    return (xmlCtxtReadMemory(ctxt, (const char *) cur, xmlStrlen(cur), URL,
15022
0
                              encoding, options));
15023
0
}
15024
15025
/**
15026
 * xmlCtxtReadFile:
15027
 * @ctxt:  an XML parser context
15028
 * @filename:  a file or URL
15029
 * @encoding:  the document encoding, or NULL
15030
 * @options:  a combination of xmlParserOption
15031
 *
15032
 * parse an XML file from the filesystem or the network.
15033
 * This reuses the existing @ctxt parser context
15034
 *
15035
 * Returns the resulting document tree
15036
 */
15037
xmlDocPtr
15038
xmlCtxtReadFile(xmlParserCtxtPtr ctxt, const char *filename,
15039
                const char *encoding, int options)
15040
0
{
15041
0
    xmlParserInputPtr stream;
15042
15043
0
    if (filename == NULL)
15044
0
        return (NULL);
15045
0
    if (ctxt == NULL)
15046
0
        return (NULL);
15047
0
    xmlInitParser();
15048
15049
0
    xmlCtxtReset(ctxt);
15050
15051
0
    stream = xmlLoadExternalEntity(filename, NULL, ctxt);
15052
0
    if (stream == NULL) {
15053
0
        return (NULL);
15054
0
    }
15055
0
    inputPush(ctxt, stream);
15056
0
    return (xmlDoRead(ctxt, NULL, encoding, options, 1));
15057
0
}
15058
15059
/**
15060
 * xmlCtxtReadMemory:
15061
 * @ctxt:  an XML parser context
15062
 * @buffer:  a pointer to a char array
15063
 * @size:  the size of the array
15064
 * @URL:  the base URL to use for the document
15065
 * @encoding:  the document encoding, or NULL
15066
 * @options:  a combination of xmlParserOption
15067
 *
15068
 * parse an XML in-memory document and build a tree.
15069
 * This reuses the existing @ctxt parser context
15070
 *
15071
 * Returns the resulting document tree
15072
 */
15073
xmlDocPtr
15074
xmlCtxtReadMemory(xmlParserCtxtPtr ctxt, const char *buffer, int size,
15075
                  const char *URL, const char *encoding, int options)
15076
0
{
15077
0
    xmlParserInputBufferPtr input;
15078
0
    xmlParserInputPtr stream;
15079
15080
0
    if (ctxt == NULL)
15081
0
        return (NULL);
15082
0
    if (buffer == NULL)
15083
0
        return (NULL);
15084
0
    xmlInitParser();
15085
15086
0
    xmlCtxtReset(ctxt);
15087
15088
0
    input = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
15089
0
    if (input == NULL) {
15090
0
  return(NULL);
15091
0
    }
15092
15093
0
    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
15094
0
    if (stream == NULL) {
15095
0
  xmlFreeParserInputBuffer(input);
15096
0
  return(NULL);
15097
0
    }
15098
15099
0
    inputPush(ctxt, stream);
15100
0
    return (xmlDoRead(ctxt, URL, encoding, options, 1));
15101
0
}
15102
15103
/**
15104
 * xmlCtxtReadFd:
15105
 * @ctxt:  an XML parser context
15106
 * @fd:  an open file descriptor
15107
 * @URL:  the base URL to use for the document
15108
 * @encoding:  the document encoding, or NULL
15109
 * @options:  a combination of xmlParserOption
15110
 *
15111
 * parse an XML from a file descriptor and build a tree.
15112
 * This reuses the existing @ctxt parser context
15113
 * NOTE that the file descriptor will not be closed when the
15114
 *      reader is closed or reset.
15115
 *
15116
 * Returns the resulting document tree
15117
 */
15118
xmlDocPtr
15119
xmlCtxtReadFd(xmlParserCtxtPtr ctxt, int fd,
15120
              const char *URL, const char *encoding, int options)
15121
0
{
15122
0
    xmlParserInputBufferPtr input;
15123
0
    xmlParserInputPtr stream;
15124
15125
0
    if (fd < 0)
15126
0
        return (NULL);
15127
0
    if (ctxt == NULL)
15128
0
        return (NULL);
15129
0
    xmlInitParser();
15130
15131
0
    xmlCtxtReset(ctxt);
15132
15133
15134
0
    input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
15135
0
    if (input == NULL)
15136
0
        return (NULL);
15137
0
    input->closecallback = NULL;
15138
0
    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
15139
0
    if (stream == NULL) {
15140
0
        xmlFreeParserInputBuffer(input);
15141
0
        return (NULL);
15142
0
    }
15143
0
    inputPush(ctxt, stream);
15144
0
    return (xmlDoRead(ctxt, URL, encoding, options, 1));
15145
0
}
15146
15147
/**
15148
 * xmlCtxtReadIO:
15149
 * @ctxt:  an XML parser context
15150
 * @ioread:  an I/O read function
15151
 * @ioclose:  an I/O close function
15152
 * @ioctx:  an I/O handler
15153
 * @URL:  the base URL to use for the document
15154
 * @encoding:  the document encoding, or NULL
15155
 * @options:  a combination of xmlParserOption
15156
 *
15157
 * parse an XML document from I/O functions and source and build a tree.
15158
 * This reuses the existing @ctxt parser context
15159
 *
15160
 * Returns the resulting document tree
15161
 */
15162
xmlDocPtr
15163
xmlCtxtReadIO(xmlParserCtxtPtr ctxt, xmlInputReadCallback ioread,
15164
              xmlInputCloseCallback ioclose, void *ioctx,
15165
        const char *URL,
15166
              const char *encoding, int options)
15167
0
{
15168
0
    xmlParserInputBufferPtr input;
15169
0
    xmlParserInputPtr stream;
15170
15171
0
    if (ioread == NULL)
15172
0
        return (NULL);
15173
0
    if (ctxt == NULL)
15174
0
        return (NULL);
15175
0
    xmlInitParser();
15176
15177
0
    xmlCtxtReset(ctxt);
15178
15179
0
    input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
15180
0
                                         XML_CHAR_ENCODING_NONE);
15181
0
    if (input == NULL) {
15182
0
        if (ioclose != NULL)
15183
0
            ioclose(ioctx);
15184
0
        return (NULL);
15185
0
    }
15186
0
    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
15187
0
    if (stream == NULL) {
15188
0
        xmlFreeParserInputBuffer(input);
15189
0
        return (NULL);
15190
0
    }
15191
0
    inputPush(ctxt, stream);
15192
0
    return (xmlDoRead(ctxt, URL, encoding, options, 1));
15193
0
}
15194