Coverage Report

Created: 2022-06-08 06:16

/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/valid.h>
61
#include <libxml/entities.h>
62
#include <libxml/xmlerror.h>
63
#include <libxml/encoding.h>
64
#include <libxml/xmlIO.h>
65
#include <libxml/uri.h>
66
#ifdef LIBXML_CATALOG_ENABLED
67
#include <libxml/catalog.h>
68
#endif
69
#ifdef LIBXML_SCHEMAS_ENABLED
70
#include <libxml/xmlschemastypes.h>
71
#include <libxml/relaxng.h>
72
#endif
73
74
#include "buf.h"
75
#include "enc.h"
76
77
struct _xmlStartTag {
78
    const xmlChar *prefix;
79
    const xmlChar *URI;
80
    int line;
81
    int nsNr;
82
};
83
84
static void
85
xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info);
86
87
static xmlParserCtxtPtr
88
xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
89
                    const xmlChar *base, xmlParserCtxtPtr pctx);
90
91
static void xmlHaltParser(xmlParserCtxtPtr ctxt);
92
93
static int
94
xmlParseElementStart(xmlParserCtxtPtr ctxt);
95
96
static void
97
xmlParseElementEnd(xmlParserCtxtPtr ctxt);
98
99
/************************************************************************
100
 *                  *
101
 *  Arbitrary limits set in the parser. See XML_PARSE_HUGE    *
102
 *                  *
103
 ************************************************************************/
104
105
0
#define XML_PARSER_BIG_ENTITY 1000
106
#define XML_PARSER_LOT_ENTITY 5000
107
108
/*
109
 * XML_PARSER_NON_LINEAR is the threshold where the ratio of parsed entity
110
 *    replacement over the size in byte of the input indicates that you have
111
 *    and exponential behaviour. A value of 10 correspond to at least 3 entity
112
 *    replacement per byte of input.
113
 */
114
0
#define XML_PARSER_NON_LINEAR 10
115
116
/*
117
 * xmlParserEntityCheck
118
 *
119
 * Function to check non-linear entity expansion behaviour
120
 * This is here to detect and stop exponential linear entity expansion
121
 * This is not a limitation of the parser but a safety
122
 * boundary feature. It can be disabled with the XML_PARSE_HUGE
123
 * parser option.
124
 */
125
static int
126
xmlParserEntityCheck(xmlParserCtxtPtr ctxt, size_t size,
127
                     xmlEntityPtr ent, size_t replacement)
128
8.14M
{
129
8.14M
    size_t consumed = 0;
130
8.14M
    int i;
131
132
8.14M
    if ((ctxt == NULL) || (ctxt->options & XML_PARSE_HUGE))
133
8.14M
        return (0);
134
0
    if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
135
0
        return (1);
136
137
    /*
138
     * This may look absurd but is needed to detect
139
     * entities problems
140
     */
141
0
    if ((ent != NULL) && (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
142
0
  (ent->content != NULL) && (ent->checked == 0) &&
143
0
  (ctxt->errNo != XML_ERR_ENTITY_LOOP)) {
144
0
  unsigned long oldnbent = ctxt->nbentities, diff;
145
0
  xmlChar *rep;
146
147
0
  ent->checked = 1;
148
149
0
        ++ctxt->depth;
150
0
  rep = xmlStringDecodeEntities(ctxt, ent->content,
151
0
          XML_SUBSTITUTE_REF, 0, 0, 0);
152
0
        --ctxt->depth;
153
0
  if ((rep == NULL) || (ctxt->errNo == XML_ERR_ENTITY_LOOP)) {
154
0
      ent->content[0] = 0;
155
0
  }
156
157
0
        diff = ctxt->nbentities - oldnbent + 1;
158
0
        if (diff > INT_MAX / 2)
159
0
            diff = INT_MAX / 2;
160
0
  ent->checked = diff * 2;
161
0
  if (rep != NULL) {
162
0
      if (xmlStrchr(rep, '<'))
163
0
    ent->checked |= 1;
164
0
      xmlFree(rep);
165
0
      rep = NULL;
166
0
  }
167
0
    }
168
169
    /*
170
     * Prevent entity exponential check, not just replacement while
171
     * parsing the DTD
172
     * The check is potentially costly so do that only once in a thousand
173
     */
174
0
    if ((ctxt->instate == XML_PARSER_DTD) && (ctxt->nbentities > 10000) &&
175
0
        (ctxt->nbentities % 1024 == 0)) {
176
0
  for (i = 0;i < ctxt->inputNr;i++) {
177
0
      consumed += ctxt->inputTab[i]->consumed +
178
0
                 (ctxt->inputTab[i]->cur - ctxt->inputTab[i]->base);
179
0
  }
180
0
  if (ctxt->nbentities > consumed * XML_PARSER_NON_LINEAR) {
181
0
      xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
182
0
      ctxt->instate = XML_PARSER_EOF;
183
0
      return (1);
184
0
  }
185
0
  consumed = 0;
186
0
    }
187
188
189
190
0
    if (replacement != 0) {
191
0
  if (replacement < XML_MAX_TEXT_LENGTH)
192
0
      return(0);
193
194
        /*
195
   * If the volume of entity copy reaches 10 times the
196
   * amount of parsed data and over the large text threshold
197
   * then that's very likely to be an abuse.
198
   */
199
0
        if (ctxt->input != NULL) {
200
0
      consumed = ctxt->input->consumed +
201
0
                 (ctxt->input->cur - ctxt->input->base);
202
0
  }
203
0
        consumed += ctxt->sizeentities;
204
205
0
        if (replacement < XML_PARSER_NON_LINEAR * consumed)
206
0
      return(0);
207
0
    } else if (size != 0) {
208
        /*
209
         * Do the check based on the replacement size of the entity
210
         */
211
0
        if (size < XML_PARSER_BIG_ENTITY)
212
0
      return(0);
213
214
        /*
215
         * A limit on the amount of text data reasonably used
216
         */
217
0
        if (ctxt->input != NULL) {
218
0
            consumed = ctxt->input->consumed +
219
0
                (ctxt->input->cur - ctxt->input->base);
220
0
        }
221
0
        consumed += ctxt->sizeentities;
222
223
0
        if ((size < XML_PARSER_NON_LINEAR * consumed) &&
224
0
      (ctxt->nbentities * 3 < XML_PARSER_NON_LINEAR * consumed))
225
0
            return (0);
226
0
    } else if (ent != NULL) {
227
        /*
228
         * use the number of parsed entities in the replacement
229
         */
230
0
        size = ent->checked / 2;
231
232
        /*
233
         * The amount of data parsed counting entities size only once
234
         */
235
0
        if (ctxt->input != NULL) {
236
0
            consumed = ctxt->input->consumed +
237
0
                (ctxt->input->cur - ctxt->input->base);
238
0
        }
239
0
        consumed += ctxt->sizeentities;
240
241
        /*
242
         * Check the density of entities for the amount of data
243
   * knowing an entity reference will take at least 3 bytes
244
         */
245
0
        if (size * 3 < consumed * XML_PARSER_NON_LINEAR)
246
0
            return (0);
247
0
    } else {
248
        /*
249
         * strange we got no data for checking
250
         */
251
0
  if (((ctxt->lastError.code != XML_ERR_UNDECLARED_ENTITY) &&
252
0
       (ctxt->lastError.code != XML_WAR_UNDECLARED_ENTITY)) ||
253
0
      (ctxt->nbentities <= 10000))
254
0
      return (0);
255
0
    }
256
0
    xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
257
0
    return (1);
258
0
}
259
260
/**
261
 * xmlParserMaxDepth:
262
 *
263
 * arbitrary depth limit for the XML documents that we allow to
264
 * process. This is not a limitation of the parser but a safety
265
 * boundary feature. It can be disabled with the XML_PARSE_HUGE
266
 * parser option.
267
 */
268
unsigned int xmlParserMaxDepth = 256;
269
270
271
272
#define SAX2 1
273
235M
#define XML_PARSER_BIG_BUFFER_SIZE 300
274
2.04G
#define XML_PARSER_BUFFER_SIZE 100
275
49.4k
#define SAX_COMPAT_MODE BAD_CAST "SAX compatibility mode document"
276
277
/**
278
 * XML_PARSER_CHUNK_SIZE
279
 *
280
 * When calling GROW that's the minimal amount of data
281
 * the parser expected to have received. It is not a hard
282
 * limit but an optimization when reading strings like Names
283
 * It is not strictly needed as long as inputs available characters
284
 * are followed by 0, which should be provided by the I/O level
285
 */
286
195M
#define XML_PARSER_CHUNK_SIZE 100
287
288
/*
289
 * List of XML prefixed PI allowed by W3C specs
290
 */
291
292
static const char* const xmlW3CPIs[] = {
293
    "xml-stylesheet",
294
    "xml-model",
295
    NULL
296
};
297
298
299
/* DEPR void xmlParserHandleReference(xmlParserCtxtPtr ctxt); */
300
static xmlEntityPtr xmlParseStringPEReference(xmlParserCtxtPtr ctxt,
301
                                              const xmlChar **str);
302
303
static xmlParserErrors
304
xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
305
                xmlSAXHandlerPtr sax,
306
          void *user_data, int depth, const xmlChar *URL,
307
          const xmlChar *ID, xmlNodePtr *list);
308
309
static int
310
xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options,
311
                          const char *encoding);
312
#ifdef LIBXML_LEGACY_ENABLED
313
static void
314
xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
315
                      xmlNodePtr lastNode);
316
#endif /* LIBXML_LEGACY_ENABLED */
317
318
static xmlParserErrors
319
xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
320
          const xmlChar *string, void *user_data, xmlNodePtr *lst);
321
322
static int
323
xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity);
324
325
/************************************************************************
326
 *                  *
327
 *    Some factorized error routines        *
328
 *                  *
329
 ************************************************************************/
330
331
/**
332
 * xmlErrAttributeDup:
333
 * @ctxt:  an XML parser context
334
 * @prefix:  the attribute prefix
335
 * @localname:  the attribute localname
336
 *
337
 * Handle a redefinition of attribute error
338
 */
339
static void
340
xmlErrAttributeDup(xmlParserCtxtPtr ctxt, const xmlChar * prefix,
341
                   const xmlChar * localname)
342
10.4k
{
343
10.4k
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
344
10.4k
        (ctxt->instate == XML_PARSER_EOF))
345
0
  return;
346
10.4k
    if (ctxt != NULL)
347
10.4k
  ctxt->errNo = XML_ERR_ATTRIBUTE_REDEFINED;
348
349
10.4k
    if (prefix == NULL)
350
8.67k
        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
351
8.67k
                        XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL, NULL, 0,
352
8.67k
                        (const char *) localname, NULL, NULL, 0, 0,
353
8.67k
                        "Attribute %s redefined\n", localname);
354
1.81k
    else
355
1.81k
        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
356
1.81k
                        XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL, NULL, 0,
357
1.81k
                        (const char *) prefix, (const char *) localname,
358
1.81k
                        NULL, 0, 0, "Attribute %s:%s redefined\n", prefix,
359
1.81k
                        localname);
360
10.4k
    if (ctxt != NULL) {
361
10.4k
  ctxt->wellFormed = 0;
362
10.4k
  if (ctxt->recovery == 0)
363
10.4k
      ctxt->disableSAX = 1;
364
10.4k
    }
365
10.4k
}
366
367
/**
368
 * xmlFatalErr:
369
 * @ctxt:  an XML parser context
370
 * @error:  the error number
371
 * @extra:  extra information string
372
 *
373
 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
374
 */
375
static void
376
xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info)
377
7.23M
{
378
7.23M
    const char *errmsg;
379
380
7.23M
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
381
7.23M
        (ctxt->instate == XML_PARSER_EOF))
382
132k
  return;
383
7.10M
    switch (error) {
384
7.97k
        case XML_ERR_INVALID_HEX_CHARREF:
385
7.97k
            errmsg = "CharRef: invalid hexadecimal value";
386
7.97k
            break;
387
29.5k
        case XML_ERR_INVALID_DEC_CHARREF:
388
29.5k
            errmsg = "CharRef: invalid decimal value";
389
29.5k
            break;
390
0
        case XML_ERR_INVALID_CHARREF:
391
0
            errmsg = "CharRef: invalid value";
392
0
            break;
393
1.32M
        case XML_ERR_INTERNAL_ERROR:
394
1.32M
            errmsg = "internal error";
395
1.32M
            break;
396
0
        case XML_ERR_PEREF_AT_EOF:
397
0
            errmsg = "PEReference at end of document";
398
0
            break;
399
0
        case XML_ERR_PEREF_IN_PROLOG:
400
0
            errmsg = "PEReference in prolog";
401
0
            break;
402
0
        case XML_ERR_PEREF_IN_EPILOG:
403
0
            errmsg = "PEReference in epilog";
404
0
            break;
405
0
        case XML_ERR_PEREF_NO_NAME:
406
0
            errmsg = "PEReference: no name";
407
0
            break;
408
4.56k
        case XML_ERR_PEREF_SEMICOL_MISSING:
409
4.56k
            errmsg = "PEReference: expecting ';'";
410
4.56k
            break;
411
237k
        case XML_ERR_ENTITY_LOOP:
412
237k
            errmsg = "Detected an entity reference loop";
413
237k
            break;
414
0
        case XML_ERR_ENTITY_NOT_STARTED:
415
0
            errmsg = "EntityValue: \" or ' expected";
416
0
            break;
417
1.02k
        case XML_ERR_ENTITY_PE_INTERNAL:
418
1.02k
            errmsg = "PEReferences forbidden in internal subset";
419
1.02k
            break;
420
175
        case XML_ERR_ENTITY_NOT_FINISHED:
421
175
            errmsg = "EntityValue: \" or ' expected";
422
175
            break;
423
764k
        case XML_ERR_ATTRIBUTE_NOT_STARTED:
424
764k
            errmsg = "AttValue: \" or ' expected";
425
764k
            break;
426
18.1k
        case XML_ERR_LT_IN_ATTRIBUTE:
427
18.1k
            errmsg = "Unescaped '<' not allowed in attributes values";
428
18.1k
            break;
429
5.00k
        case XML_ERR_LITERAL_NOT_STARTED:
430
5.00k
            errmsg = "SystemLiteral \" or ' expected";
431
5.00k
            break;
432
48.0k
        case XML_ERR_LITERAL_NOT_FINISHED:
433
48.0k
            errmsg = "Unfinished System or Public ID \" or ' expected";
434
48.0k
            break;
435
4.59k
        case XML_ERR_MISPLACED_CDATA_END:
436
4.59k
            errmsg = "Sequence ']]>' not allowed in content";
437
4.59k
            break;
438
2.86k
        case XML_ERR_URI_REQUIRED:
439
2.86k
            errmsg = "SYSTEM or PUBLIC, the URI is missing";
440
2.86k
            break;
441
2.14k
        case XML_ERR_PUBID_REQUIRED:
442
2.14k
            errmsg = "PUBLIC, the Public Identifier is missing";
443
2.14k
            break;
444
55.2k
        case XML_ERR_HYPHEN_IN_COMMENT:
445
55.2k
            errmsg = "Comment must not contain '--' (double-hyphen)";
446
55.2k
            break;
447
746k
        case XML_ERR_PI_NOT_STARTED:
448
746k
            errmsg = "xmlParsePI : no target name";
449
746k
            break;
450
2.61k
        case XML_ERR_RESERVED_XML_NAME:
451
2.61k
            errmsg = "Invalid PI name";
452
2.61k
            break;
453
5.59k
        case XML_ERR_NOTATION_NOT_STARTED:
454
5.59k
            errmsg = "NOTATION: Name expected here";
455
5.59k
            break;
456
66.1k
        case XML_ERR_NOTATION_NOT_FINISHED:
457
66.1k
            errmsg = "'>' required to close NOTATION declaration";
458
66.1k
            break;
459
1.71M
        case XML_ERR_VALUE_REQUIRED:
460
1.71M
            errmsg = "Entity value required";
461
1.71M
            break;
462
1.06k
        case XML_ERR_URI_FRAGMENT:
463
1.06k
            errmsg = "Fragment not allowed";
464
1.06k
            break;
465
36.1k
        case XML_ERR_ATTLIST_NOT_STARTED:
466
36.1k
            errmsg = "'(' required to start ATTLIST enumeration";
467
36.1k
            break;
468
781
        case XML_ERR_NMTOKEN_REQUIRED:
469
781
            errmsg = "NmToken expected in ATTLIST enumeration";
470
781
            break;
471
15.3k
        case XML_ERR_ATTLIST_NOT_FINISHED:
472
15.3k
            errmsg = "')' required to finish ATTLIST enumeration";
473
15.3k
            break;
474
17.2k
        case XML_ERR_MIXED_NOT_STARTED:
475
17.2k
            errmsg = "MixedContentDecl : '|' or ')*' expected";
476
17.2k
            break;
477
0
        case XML_ERR_PCDATA_REQUIRED:
478
0
            errmsg = "MixedContentDecl : '#PCDATA' expected";
479
0
            break;
480
15.8k
        case XML_ERR_ELEMCONTENT_NOT_STARTED:
481
15.8k
            errmsg = "ContentDecl : Name or '(' expected";
482
15.8k
            break;
483
911k
        case XML_ERR_ELEMCONTENT_NOT_FINISHED:
484
911k
            errmsg = "ContentDecl : ',' '|' or ')' expected";
485
911k
            break;
486
0
        case XML_ERR_PEREF_IN_INT_SUBSET:
487
0
            errmsg =
488
0
                "PEReference: forbidden within markup decl in internal subset";
489
0
            break;
490
960k
        case XML_ERR_GT_REQUIRED:
491
960k
            errmsg = "expected '>'";
492
960k
            break;
493
0
        case XML_ERR_CONDSEC_INVALID:
494
0
            errmsg = "XML conditional section '[' expected";
495
0
            break;
496
0
        case XML_ERR_EXT_SUBSET_NOT_FINISHED:
497
0
            errmsg = "Content error in the external subset";
498
0
            break;
499
0
        case XML_ERR_CONDSEC_INVALID_KEYWORD:
500
0
            errmsg =
501
0
                "conditional section INCLUDE or IGNORE keyword expected";
502
0
            break;
503
0
        case XML_ERR_CONDSEC_NOT_FINISHED:
504
0
            errmsg = "XML conditional section not closed";
505
0
            break;
506
0
        case XML_ERR_XMLDECL_NOT_STARTED:
507
0
            errmsg = "Text declaration '<?xml' required";
508
0
            break;
509
1.73k
        case XML_ERR_XMLDECL_NOT_FINISHED:
510
1.73k
            errmsg = "parsing XML declaration: '?>' expected";
511
1.73k
            break;
512
0
        case XML_ERR_EXT_ENTITY_STANDALONE:
513
0
            errmsg = "external parsed entities cannot be standalone";
514
0
            break;
515
38.2k
        case XML_ERR_ENTITYREF_SEMICOL_MISSING:
516
38.2k
            errmsg = "EntityRef: expecting ';'";
517
38.2k
            break;
518
6.37k
        case XML_ERR_DOCTYPE_NOT_FINISHED:
519
6.37k
            errmsg = "DOCTYPE improperly terminated";
520
6.37k
            break;
521
0
        case XML_ERR_LTSLASH_REQUIRED:
522
0
            errmsg = "EndTag: '</' not found";
523
0
            break;
524
23
        case XML_ERR_EQUAL_REQUIRED:
525
23
            errmsg = "expected '='";
526
23
            break;
527
190
        case XML_ERR_STRING_NOT_CLOSED:
528
190
            errmsg = "String not closed expecting \" or '";
529
190
            break;
530
47
        case XML_ERR_STRING_NOT_STARTED:
531
47
            errmsg = "String not started expecting ' or \"";
532
47
            break;
533
5
        case XML_ERR_ENCODING_NAME:
534
5
            errmsg = "Invalid XML encoding name";
535
5
            break;
536
22
        case XML_ERR_STANDALONE_VALUE:
537
22
            errmsg = "standalone accepts only 'yes' or 'no'";
538
22
            break;
539
44
        case XML_ERR_DOCUMENT_EMPTY:
540
44
            errmsg = "Document is empty";
541
44
            break;
542
1.27k
        case XML_ERR_DOCUMENT_END:
543
1.27k
            errmsg = "Extra content at the end of the document";
544
1.27k
            break;
545
48.9k
        case XML_ERR_NOT_WELL_BALANCED:
546
48.9k
            errmsg = "chunk is not well balanced";
547
48.9k
            break;
548
0
        case XML_ERR_EXTRA_CONTENT:
549
0
            errmsg = "extra content at the end of well balanced chunk";
550
0
            break;
551
2.09k
        case XML_ERR_VERSION_MISSING:
552
2.09k
            errmsg = "Malformed declaration expecting version";
553
2.09k
            break;
554
0
        case XML_ERR_NAME_TOO_LONG:
555
0
            errmsg = "Name too long use XML_PARSE_HUGE option";
556
0
            break;
557
#if 0
558
        case:
559
            errmsg = "";
560
            break;
561
#endif
562
3.44k
        default:
563
3.44k
            errmsg = "Unregistered error message";
564
7.10M
    }
565
7.10M
    if (ctxt != NULL)
566
7.10M
  ctxt->errNo = error;
567
7.10M
    if (info == NULL) {
568
5.78M
        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
569
5.78M
                        XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, "%s\n",
570
5.78M
                        errmsg);
571
5.78M
    } else {
572
1.32M
        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
573
1.32M
                        XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, "%s: %s\n",
574
1.32M
                        errmsg, info);
575
1.32M
    }
576
7.10M
    if (ctxt != NULL) {
577
7.10M
  ctxt->wellFormed = 0;
578
7.10M
  if (ctxt->recovery == 0)
579
7.10M
      ctxt->disableSAX = 1;
580
7.10M
    }
581
7.10M
}
582
583
/**
584
 * xmlFatalErrMsg:
585
 * @ctxt:  an XML parser context
586
 * @error:  the error number
587
 * @msg:  the error message
588
 *
589
 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
590
 */
591
static void LIBXML_ATTR_FORMAT(3,0)
592
xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
593
               const char *msg)
594
10.2M
{
595
10.2M
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
596
10.2M
        (ctxt->instate == XML_PARSER_EOF))
597
0
  return;
598
10.2M
    if (ctxt != NULL)
599
10.2M
  ctxt->errNo = error;
600
10.2M
    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
601
10.2M
                    XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg);
602
10.2M
    if (ctxt != NULL) {
603
10.2M
  ctxt->wellFormed = 0;
604
10.2M
  if (ctxt->recovery == 0)
605
10.2M
      ctxt->disableSAX = 1;
606
10.2M
    }
607
10.2M
}
608
609
/**
610
 * xmlWarningMsg:
611
 * @ctxt:  an XML parser context
612
 * @error:  the error number
613
 * @msg:  the error message
614
 * @str1:  extra data
615
 * @str2:  extra data
616
 *
617
 * Handle a warning.
618
 */
619
static void LIBXML_ATTR_FORMAT(3,0)
620
xmlWarningMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
621
              const char *msg, const xmlChar *str1, const xmlChar *str2)
622
19.9k
{
623
19.9k
    xmlStructuredErrorFunc schannel = NULL;
624
625
19.9k
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
626
19.9k
        (ctxt->instate == XML_PARSER_EOF))
627
0
  return;
628
19.9k
    if ((ctxt != NULL) && (ctxt->sax != NULL) &&
629
19.9k
        (ctxt->sax->initialized == XML_SAX2_MAGIC))
630
19.9k
        schannel = ctxt->sax->serror;
631
19.9k
    if (ctxt != NULL) {
632
19.9k
        __xmlRaiseError(schannel,
633
19.9k
                    (ctxt->sax) ? ctxt->sax->warning : NULL,
634
19.9k
                    ctxt->userData,
635
19.9k
                    ctxt, NULL, XML_FROM_PARSER, error,
636
19.9k
                    XML_ERR_WARNING, NULL, 0,
637
19.9k
        (const char *) str1, (const char *) str2, NULL, 0, 0,
638
19.9k
        msg, (const char *) str1, (const char *) str2);
639
19.9k
    } else {
640
0
        __xmlRaiseError(schannel, NULL, NULL,
641
0
                    ctxt, NULL, XML_FROM_PARSER, error,
642
0
                    XML_ERR_WARNING, NULL, 0,
643
0
        (const char *) str1, (const char *) str2, NULL, 0, 0,
644
0
        msg, (const char *) str1, (const char *) str2);
645
0
    }
646
19.9k
}
647
648
/**
649
 * xmlValidityError:
650
 * @ctxt:  an XML parser context
651
 * @error:  the error number
652
 * @msg:  the error message
653
 * @str1:  extra data
654
 *
655
 * Handle a validity error.
656
 */
657
static void LIBXML_ATTR_FORMAT(3,0)
658
xmlValidityError(xmlParserCtxtPtr ctxt, xmlParserErrors error,
659
              const char *msg, const xmlChar *str1, const xmlChar *str2)
660
1.36k
{
661
1.36k
    xmlStructuredErrorFunc schannel = NULL;
662
663
1.36k
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
664
1.36k
        (ctxt->instate == XML_PARSER_EOF))
665
0
  return;
666
1.36k
    if (ctxt != NULL) {
667
1.36k
  ctxt->errNo = error;
668
1.36k
  if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
669
1.36k
      schannel = ctxt->sax->serror;
670
1.36k
    }
671
1.36k
    if (ctxt != NULL) {
672
1.36k
        __xmlRaiseError(schannel,
673
1.36k
                    ctxt->vctxt.error, ctxt->vctxt.userData,
674
1.36k
                    ctxt, NULL, XML_FROM_DTD, error,
675
1.36k
                    XML_ERR_ERROR, NULL, 0, (const char *) str1,
676
1.36k
        (const char *) str2, NULL, 0, 0,
677
1.36k
        msg, (const char *) str1, (const char *) str2);
678
1.36k
  ctxt->valid = 0;
679
1.36k
    } else {
680
0
        __xmlRaiseError(schannel, NULL, NULL,
681
0
                    ctxt, NULL, XML_FROM_DTD, error,
682
0
                    XML_ERR_ERROR, NULL, 0, (const char *) str1,
683
0
        (const char *) str2, NULL, 0, 0,
684
0
        msg, (const char *) str1, (const char *) str2);
685
0
    }
686
1.36k
}
687
688
/**
689
 * xmlFatalErrMsgInt:
690
 * @ctxt:  an XML parser context
691
 * @error:  the error number
692
 * @msg:  the error message
693
 * @val:  an integer value
694
 *
695
 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
696
 */
697
static void LIBXML_ATTR_FORMAT(3,0)
698
xmlFatalErrMsgInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
699
                  const char *msg, int val)
700
145k
{
701
145k
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
702
145k
        (ctxt->instate == XML_PARSER_EOF))
703
0
  return;
704
145k
    if (ctxt != NULL)
705
145k
  ctxt->errNo = error;
706
145k
    __xmlRaiseError(NULL, NULL, NULL,
707
145k
                    ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
708
145k
                    NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
709
145k
    if (ctxt != NULL) {
710
145k
  ctxt->wellFormed = 0;
711
145k
  if (ctxt->recovery == 0)
712
145k
      ctxt->disableSAX = 1;
713
145k
    }
714
145k
}
715
716
/**
717
 * xmlFatalErrMsgStrIntStr:
718
 * @ctxt:  an XML parser context
719
 * @error:  the error number
720
 * @msg:  the error message
721
 * @str1:  an string info
722
 * @val:  an integer value
723
 * @str2:  an string info
724
 *
725
 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
726
 */
727
static void LIBXML_ATTR_FORMAT(3,0)
728
xmlFatalErrMsgStrIntStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
729
                  const char *msg, const xmlChar *str1, int val,
730
      const xmlChar *str2)
731
278k
{
732
278k
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
733
278k
        (ctxt->instate == XML_PARSER_EOF))
734
0
  return;
735
278k
    if (ctxt != NULL)
736
278k
  ctxt->errNo = error;
737
278k
    __xmlRaiseError(NULL, NULL, NULL,
738
278k
                    ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
739
278k
                    NULL, 0, (const char *) str1, (const char *) str2,
740
278k
        NULL, val, 0, msg, str1, val, str2);
741
278k
    if (ctxt != NULL) {
742
278k
  ctxt->wellFormed = 0;
743
278k
  if (ctxt->recovery == 0)
744
278k
      ctxt->disableSAX = 1;
745
278k
    }
746
278k
}
747
748
/**
749
 * xmlFatalErrMsgStr:
750
 * @ctxt:  an XML parser context
751
 * @error:  the error number
752
 * @msg:  the error message
753
 * @val:  a string value
754
 *
755
 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
756
 */
757
static void LIBXML_ATTR_FORMAT(3,0)
758
xmlFatalErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
759
                  const char *msg, const xmlChar * val)
760
920k
{
761
920k
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
762
920k
        (ctxt->instate == XML_PARSER_EOF))
763
0
  return;
764
920k
    if (ctxt != NULL)
765
920k
  ctxt->errNo = error;
766
920k
    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL,
767
920k
                    XML_FROM_PARSER, error, XML_ERR_FATAL,
768
920k
                    NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
769
920k
                    val);
770
920k
    if (ctxt != NULL) {
771
920k
  ctxt->wellFormed = 0;
772
920k
  if (ctxt->recovery == 0)
773
920k
      ctxt->disableSAX = 1;
774
920k
    }
775
920k
}
776
777
/**
778
 * xmlErrMsgStr:
779
 * @ctxt:  an XML parser context
780
 * @error:  the error number
781
 * @msg:  the error message
782
 * @val:  a string value
783
 *
784
 * Handle a non fatal parser error
785
 */
786
static void LIBXML_ATTR_FORMAT(3,0)
787
xmlErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
788
                  const char *msg, const xmlChar * val)
789
23.1k
{
790
23.1k
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
791
23.1k
        (ctxt->instate == XML_PARSER_EOF))
792
0
  return;
793
23.1k
    if (ctxt != NULL)
794
23.1k
  ctxt->errNo = error;
795
23.1k
    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL,
796
23.1k
                    XML_FROM_PARSER, error, XML_ERR_ERROR,
797
23.1k
                    NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
798
23.1k
                    val);
799
23.1k
}
800
801
/**
802
 * xmlNsErr:
803
 * @ctxt:  an XML parser context
804
 * @error:  the error number
805
 * @msg:  the message
806
 * @info1:  extra information string
807
 * @info2:  extra information string
808
 *
809
 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
810
 */
811
static void LIBXML_ATTR_FORMAT(3,0)
812
xmlNsErr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
813
         const char *msg,
814
         const xmlChar * info1, const xmlChar * info2,
815
         const xmlChar * info3)
816
195k
{
817
195k
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
818
195k
        (ctxt->instate == XML_PARSER_EOF))
819
0
  return;
820
195k
    if (ctxt != NULL)
821
195k
  ctxt->errNo = error;
822
195k
    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
823
195k
                    XML_ERR_ERROR, NULL, 0, (const char *) info1,
824
195k
                    (const char *) info2, (const char *) info3, 0, 0, msg,
825
195k
                    info1, info2, info3);
826
195k
    if (ctxt != NULL)
827
195k
  ctxt->nsWellFormed = 0;
828
195k
}
829
830
/**
831
 * xmlNsWarn
832
 * @ctxt:  an XML parser context
833
 * @error:  the error number
834
 * @msg:  the message
835
 * @info1:  extra information string
836
 * @info2:  extra information string
837
 *
838
 * Handle a namespace warning error
839
 */
840
static void LIBXML_ATTR_FORMAT(3,0)
841
xmlNsWarn(xmlParserCtxtPtr ctxt, xmlParserErrors error,
842
         const char *msg,
843
         const xmlChar * info1, const xmlChar * info2,
844
         const xmlChar * info3)
845
20.3k
{
846
20.3k
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
847
20.3k
        (ctxt->instate == XML_PARSER_EOF))
848
0
  return;
849
20.3k
    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
850
20.3k
                    XML_ERR_WARNING, NULL, 0, (const char *) info1,
851
20.3k
                    (const char *) info2, (const char *) info3, 0, 0, msg,
852
20.3k
                    info1, info2, info3);
853
20.3k
}
854
855
/************************************************************************
856
 *                  *
857
 *    Library wide options          *
858
 *                  *
859
 ************************************************************************/
860
861
/**
862
  * xmlHasFeature:
863
  * @feature: the feature to be examined
864
  *
865
  * Examines if the library has been compiled with a given feature.
866
  *
867
  * Returns a non-zero value if the feature exist, otherwise zero.
868
  * Returns zero (0) if the feature does not exist or an unknown
869
  * unknown feature is requested, non-zero otherwise.
870
  */
871
int
872
xmlHasFeature(xmlFeature feature)
873
0
{
874
0
    switch (feature) {
875
0
  case XML_WITH_THREAD:
876
0
#ifdef LIBXML_THREAD_ENABLED
877
0
      return(1);
878
#else
879
      return(0);
880
#endif
881
0
        case XML_WITH_TREE:
882
0
#ifdef LIBXML_TREE_ENABLED
883
0
            return(1);
884
#else
885
            return(0);
886
#endif
887
0
        case XML_WITH_OUTPUT:
888
0
#ifdef LIBXML_OUTPUT_ENABLED
889
0
            return(1);
890
#else
891
            return(0);
892
#endif
893
0
        case XML_WITH_PUSH:
894
0
#ifdef LIBXML_PUSH_ENABLED
895
0
            return(1);
896
#else
897
            return(0);
898
#endif
899
0
        case XML_WITH_READER:
900
0
#ifdef LIBXML_READER_ENABLED
901
0
            return(1);
902
#else
903
            return(0);
904
#endif
905
0
        case XML_WITH_PATTERN:
906
0
#ifdef LIBXML_PATTERN_ENABLED
907
0
            return(1);
908
#else
909
            return(0);
910
#endif
911
0
        case XML_WITH_WRITER:
912
0
#ifdef LIBXML_WRITER_ENABLED
913
0
            return(1);
914
#else
915
            return(0);
916
#endif
917
0
        case XML_WITH_SAX1:
918
0
#ifdef LIBXML_SAX1_ENABLED
919
0
            return(1);
920
#else
921
            return(0);
922
#endif
923
0
        case XML_WITH_FTP:
924
#ifdef LIBXML_FTP_ENABLED
925
            return(1);
926
#else
927
0
            return(0);
928
0
#endif
929
0
        case XML_WITH_HTTP:
930
0
#ifdef LIBXML_HTTP_ENABLED
931
0
            return(1);
932
#else
933
            return(0);
934
#endif
935
0
        case XML_WITH_VALID:
936
0
#ifdef LIBXML_VALID_ENABLED
937
0
            return(1);
938
#else
939
            return(0);
940
#endif
941
0
        case XML_WITH_HTML:
942
0
#ifdef LIBXML_HTML_ENABLED
943
0
            return(1);
944
#else
945
            return(0);
946
#endif
947
0
        case XML_WITH_LEGACY:
948
#ifdef LIBXML_LEGACY_ENABLED
949
            return(1);
950
#else
951
0
            return(0);
952
0
#endif
953
0
        case XML_WITH_C14N:
954
0
#ifdef LIBXML_C14N_ENABLED
955
0
            return(1);
956
#else
957
            return(0);
958
#endif
959
0
        case XML_WITH_CATALOG:
960
0
#ifdef LIBXML_CATALOG_ENABLED
961
0
            return(1);
962
#else
963
            return(0);
964
#endif
965
0
        case XML_WITH_XPATH:
966
0
#ifdef LIBXML_XPATH_ENABLED
967
0
            return(1);
968
#else
969
            return(0);
970
#endif
971
0
        case XML_WITH_XPTR:
972
0
#ifdef LIBXML_XPTR_ENABLED
973
0
            return(1);
974
#else
975
            return(0);
976
#endif
977
0
        case XML_WITH_XINCLUDE:
978
0
#ifdef LIBXML_XINCLUDE_ENABLED
979
0
            return(1);
980
#else
981
            return(0);
982
#endif
983
0
        case XML_WITH_ICONV:
984
0
#ifdef LIBXML_ICONV_ENABLED
985
0
            return(1);
986
#else
987
            return(0);
988
#endif
989
0
        case XML_WITH_ISO8859X:
990
0
#ifdef LIBXML_ISO8859X_ENABLED
991
0
            return(1);
992
#else
993
            return(0);
994
#endif
995
0
        case XML_WITH_UNICODE:
996
0
#ifdef LIBXML_UNICODE_ENABLED
997
0
            return(1);
998
#else
999
            return(0);
1000
#endif
1001
0
        case XML_WITH_REGEXP:
1002
0
#ifdef LIBXML_REGEXP_ENABLED
1003
0
            return(1);
1004
#else
1005
            return(0);
1006
#endif
1007
0
        case XML_WITH_AUTOMATA:
1008
0
#ifdef LIBXML_AUTOMATA_ENABLED
1009
0
            return(1);
1010
#else
1011
            return(0);
1012
#endif
1013
0
        case XML_WITH_EXPR:
1014
#ifdef LIBXML_EXPR_ENABLED
1015
            return(1);
1016
#else
1017
0
            return(0);
1018
0
#endif
1019
0
        case XML_WITH_SCHEMAS:
1020
0
#ifdef LIBXML_SCHEMAS_ENABLED
1021
0
            return(1);
1022
#else
1023
            return(0);
1024
#endif
1025
0
        case XML_WITH_SCHEMATRON:
1026
0
#ifdef LIBXML_SCHEMATRON_ENABLED
1027
0
            return(1);
1028
#else
1029
            return(0);
1030
#endif
1031
0
        case XML_WITH_MODULES:
1032
0
#ifdef LIBXML_MODULES_ENABLED
1033
0
            return(1);
1034
#else
1035
            return(0);
1036
#endif
1037
0
        case XML_WITH_DEBUG:
1038
0
#ifdef LIBXML_DEBUG_ENABLED
1039
0
            return(1);
1040
#else
1041
            return(0);
1042
#endif
1043
0
        case XML_WITH_DEBUG_MEM:
1044
#ifdef DEBUG_MEMORY_LOCATION
1045
            return(1);
1046
#else
1047
0
            return(0);
1048
0
#endif
1049
0
        case XML_WITH_DEBUG_RUN:
1050
#ifdef LIBXML_DEBUG_RUNTIME
1051
            return(1);
1052
#else
1053
0
            return(0);
1054
0
#endif
1055
0
        case XML_WITH_ZLIB:
1056
#ifdef LIBXML_ZLIB_ENABLED
1057
            return(1);
1058
#else
1059
0
            return(0);
1060
0
#endif
1061
0
        case XML_WITH_LZMA:
1062
#ifdef LIBXML_LZMA_ENABLED
1063
            return(1);
1064
#else
1065
0
            return(0);
1066
0
#endif
1067
0
        case XML_WITH_ICU:
1068
#ifdef LIBXML_ICU_ENABLED
1069
            return(1);
1070
#else
1071
0
            return(0);
1072
0
#endif
1073
0
        default:
1074
0
      break;
1075
0
     }
1076
0
     return(0);
1077
0
}
1078
1079
/************************************************************************
1080
 *                  *
1081
 *    SAX2 defaulted attributes handling      *
1082
 *                  *
1083
 ************************************************************************/
1084
1085
/**
1086
 * xmlDetectSAX2:
1087
 * @ctxt:  an XML parser context
1088
 *
1089
 * Do the SAX2 detection and specific initialization
1090
 */
1091
static void
1092
319k
xmlDetectSAX2(xmlParserCtxtPtr ctxt) {
1093
319k
    xmlSAXHandlerPtr sax;
1094
1095
    /* Avoid unused variable warning if features are disabled. */
1096
319k
    (void) sax;
1097
1098
319k
    if (ctxt == NULL) return;
1099
319k
    sax = ctxt->sax;
1100
319k
#ifdef LIBXML_SAX1_ENABLED
1101
319k
    if ((sax) &&  (sax->initialized == XML_SAX2_MAGIC) &&
1102
319k
        ((sax->startElementNs != NULL) ||
1103
319k
         (sax->endElementNs != NULL) ||
1104
319k
         ((sax->startElement == NULL) && (sax->endElement == NULL))))
1105
319k
        ctxt->sax2 = 1;
1106
#else
1107
    ctxt->sax2 = 1;
1108
#endif /* LIBXML_SAX1_ENABLED */
1109
1110
319k
    ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
1111
319k
    ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
1112
319k
    ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
1113
319k
    if ((ctxt->str_xml==NULL) || (ctxt->str_xmlns==NULL) ||
1114
319k
    (ctxt->str_xml_ns == NULL)) {
1115
0
        xmlErrMemory(ctxt, NULL);
1116
0
    }
1117
319k
}
1118
1119
typedef struct _xmlDefAttrs xmlDefAttrs;
1120
typedef xmlDefAttrs *xmlDefAttrsPtr;
1121
struct _xmlDefAttrs {
1122
    int nbAttrs;  /* number of defaulted attributes on that element */
1123
    int maxAttrs;       /* the size of the array */
1124
#if __STDC_VERSION__ >= 199901L
1125
    /* Using a C99 flexible array member avoids UBSan errors. */
1126
    const xmlChar *values[]; /* array of localname/prefix/values/external */
1127
#else
1128
    const xmlChar *values[5];
1129
#endif
1130
};
1131
1132
/**
1133
 * xmlAttrNormalizeSpace:
1134
 * @src: the source string
1135
 * @dst: the target string
1136
 *
1137
 * Normalize the space in non CDATA attribute values:
1138
 * If the attribute type is not CDATA, then the XML processor MUST further
1139
 * process the normalized attribute value by discarding any leading and
1140
 * trailing space (#x20) characters, and by replacing sequences of space
1141
 * (#x20) characters by a single space (#x20) character.
1142
 * Note that the size of dst need to be at least src, and if one doesn't need
1143
 * to preserve dst (and it doesn't come from a dictionary or read-only) then
1144
 * passing src as dst is just fine.
1145
 *
1146
 * Returns a pointer to the normalized value (dst) or NULL if no conversion
1147
 *         is needed.
1148
 */
1149
static xmlChar *
1150
xmlAttrNormalizeSpace(const xmlChar *src, xmlChar *dst)
1151
55.6k
{
1152
55.6k
    if ((src == NULL) || (dst == NULL))
1153
0
        return(NULL);
1154
1155
58.8k
    while (*src == 0x20) src++;
1156
621k
    while (*src != 0) {
1157
565k
  if (*src == 0x20) {
1158
52.4k
      while (*src == 0x20) src++;
1159
22.6k
      if (*src != 0)
1160
21.2k
    *dst++ = 0x20;
1161
543k
  } else {
1162
543k
      *dst++ = *src++;
1163
543k
  }
1164
565k
    }
1165
55.6k
    *dst = 0;
1166
55.6k
    if (dst == src)
1167
50.7k
       return(NULL);
1168
4.91k
    return(dst);
1169
55.6k
}
1170
1171
/**
1172
 * xmlAttrNormalizeSpace2:
1173
 * @src: the source string
1174
 *
1175
 * Normalize the space in non CDATA attribute values, a slightly more complex
1176
 * front end to avoid allocation problems when running on attribute values
1177
 * coming from the input.
1178
 *
1179
 * Returns a pointer to the normalized value (dst) or NULL if no conversion
1180
 *         is needed.
1181
 */
1182
static const xmlChar *
1183
xmlAttrNormalizeSpace2(xmlParserCtxtPtr ctxt, xmlChar *src, int *len)
1184
4.47k
{
1185
4.47k
    int i;
1186
4.47k
    int remove_head = 0;
1187
4.47k
    int need_realloc = 0;
1188
4.47k
    const xmlChar *cur;
1189
1190
4.47k
    if ((ctxt == NULL) || (src == NULL) || (len == NULL))
1191
0
        return(NULL);
1192
4.47k
    i = *len;
1193
4.47k
    if (i <= 0)
1194
739
        return(NULL);
1195
1196
3.74k
    cur = src;
1197
4.51k
    while (*cur == 0x20) {
1198
772
        cur++;
1199
772
  remove_head++;
1200
772
    }
1201
202M
    while (*cur != 0) {
1202
202M
  if (*cur == 0x20) {
1203
1.51k
      cur++;
1204
1.51k
      if ((*cur == 0x20) || (*cur == 0)) {
1205
441
          need_realloc = 1;
1206
441
    break;
1207
441
      }
1208
1.51k
  } else
1209
202M
      cur++;
1210
202M
    }
1211
3.74k
    if (need_realloc) {
1212
441
        xmlChar *ret;
1213
1214
441
  ret = xmlStrndup(src + remove_head, i - remove_head + 1);
1215
441
  if (ret == NULL) {
1216
0
      xmlErrMemory(ctxt, NULL);
1217
0
      return(NULL);
1218
0
  }
1219
441
  xmlAttrNormalizeSpace(ret, ret);
1220
441
  *len = (int) strlen((const char *)ret);
1221
441
        return(ret);
1222
3.29k
    } else if (remove_head) {
1223
565
        *len -= remove_head;
1224
565
        memmove(src, src + remove_head, 1 + *len);
1225
565
  return(src);
1226
565
    }
1227
2.73k
    return(NULL);
1228
3.74k
}
1229
1230
/**
1231
 * xmlAddDefAttrs:
1232
 * @ctxt:  an XML parser context
1233
 * @fullname:  the element fullname
1234
 * @fullattr:  the attribute fullname
1235
 * @value:  the attribute value
1236
 *
1237
 * Add a defaulted attribute for an element
1238
 */
1239
static void
1240
xmlAddDefAttrs(xmlParserCtxtPtr ctxt,
1241
               const xmlChar *fullname,
1242
               const xmlChar *fullattr,
1243
55.2k
               const xmlChar *value) {
1244
55.2k
    xmlDefAttrsPtr defaults;
1245
55.2k
    int len;
1246
55.2k
    const xmlChar *name;
1247
55.2k
    const xmlChar *prefix;
1248
1249
    /*
1250
     * Allows to detect attribute redefinitions
1251
     */
1252
55.2k
    if (ctxt->attsSpecial != NULL) {
1253
53.1k
        if (xmlHashLookup2(ctxt->attsSpecial, fullname, fullattr) != NULL)
1254
37.2k
      return;
1255
53.1k
    }
1256
1257
17.9k
    if (ctxt->attsDefault == NULL) {
1258
2.07k
        ctxt->attsDefault = xmlHashCreateDict(10, ctxt->dict);
1259
2.07k
  if (ctxt->attsDefault == NULL)
1260
0
      goto mem_error;
1261
2.07k
    }
1262
1263
    /*
1264
     * split the element name into prefix:localname , the string found
1265
     * are within the DTD and then not associated to namespace names.
1266
     */
1267
17.9k
    name = xmlSplitQName3(fullname, &len);
1268
17.9k
    if (name == NULL) {
1269
13.9k
        name = xmlDictLookup(ctxt->dict, fullname, -1);
1270
13.9k
  prefix = NULL;
1271
13.9k
    } else {
1272
4.07k
        name = xmlDictLookup(ctxt->dict, name, -1);
1273
4.07k
  prefix = xmlDictLookup(ctxt->dict, fullname, len);
1274
4.07k
    }
1275
1276
    /*
1277
     * make sure there is some storage
1278
     */
1279
17.9k
    defaults = xmlHashLookup2(ctxt->attsDefault, name, prefix);
1280
17.9k
    if (defaults == NULL) {
1281
3.45k
        defaults = (xmlDefAttrsPtr) xmlMalloc(sizeof(xmlDefAttrs) +
1282
3.45k
                     (4 * 5) * sizeof(const xmlChar *));
1283
3.45k
  if (defaults == NULL)
1284
0
      goto mem_error;
1285
3.45k
  defaults->nbAttrs = 0;
1286
3.45k
  defaults->maxAttrs = 4;
1287
3.45k
  if (xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix,
1288
3.45k
                          defaults, NULL) < 0) {
1289
0
      xmlFree(defaults);
1290
0
      goto mem_error;
1291
0
  }
1292
14.5k
    } else if (defaults->nbAttrs >= defaults->maxAttrs) {
1293
2.30k
        xmlDefAttrsPtr temp;
1294
1295
2.30k
        temp = (xmlDefAttrsPtr) xmlRealloc(defaults, sizeof(xmlDefAttrs) +
1296
2.30k
           (2 * defaults->maxAttrs * 5) * sizeof(const xmlChar *));
1297
2.30k
  if (temp == NULL)
1298
0
      goto mem_error;
1299
2.30k
  defaults = temp;
1300
2.30k
  defaults->maxAttrs *= 2;
1301
2.30k
  if (xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix,
1302
2.30k
                          defaults, NULL) < 0) {
1303
0
      xmlFree(defaults);
1304
0
      goto mem_error;
1305
0
  }
1306
2.30k
    }
1307
1308
    /*
1309
     * Split the element name into prefix:localname , the string found
1310
     * are within the DTD and hen not associated to namespace names.
1311
     */
1312
17.9k
    name = xmlSplitQName3(fullattr, &len);
1313
17.9k
    if (name == NULL) {
1314
14.4k
        name = xmlDictLookup(ctxt->dict, fullattr, -1);
1315
14.4k
  prefix = NULL;
1316
14.4k
    } else {
1317
3.51k
        name = xmlDictLookup(ctxt->dict, name, -1);
1318
3.51k
  prefix = xmlDictLookup(ctxt->dict, fullattr, len);
1319
3.51k
    }
1320
1321
17.9k
    defaults->values[5 * defaults->nbAttrs] = name;
1322
17.9k
    defaults->values[5 * defaults->nbAttrs + 1] = prefix;
1323
    /* intern the string and precompute the end */
1324
17.9k
    len = xmlStrlen(value);
1325
17.9k
    value = xmlDictLookup(ctxt->dict, value, len);
1326
17.9k
    defaults->values[5 * defaults->nbAttrs + 2] = value;
1327
17.9k
    defaults->values[5 * defaults->nbAttrs + 3] = value + len;
1328
17.9k
    if (ctxt->external)
1329
0
        defaults->values[5 * defaults->nbAttrs + 4] = BAD_CAST "external";
1330
17.9k
    else
1331
17.9k
        defaults->values[5 * defaults->nbAttrs + 4] = NULL;
1332
17.9k
    defaults->nbAttrs++;
1333
1334
17.9k
    return;
1335
1336
0
mem_error:
1337
0
    xmlErrMemory(ctxt, NULL);
1338
0
    return;
1339
17.9k
}
1340
1341
/**
1342
 * xmlAddSpecialAttr:
1343
 * @ctxt:  an XML parser context
1344
 * @fullname:  the element fullname
1345
 * @fullattr:  the attribute fullname
1346
 * @type:  the attribute type
1347
 *
1348
 * Register this attribute type
1349
 */
1350
static void
1351
xmlAddSpecialAttr(xmlParserCtxtPtr ctxt,
1352
      const xmlChar *fullname,
1353
      const xmlChar *fullattr,
1354
      int type)
1355
58.1k
{
1356
58.1k
    if (ctxt->attsSpecial == NULL) {
1357
2.33k
        ctxt->attsSpecial = xmlHashCreateDict(10, ctxt->dict);
1358
2.33k
  if (ctxt->attsSpecial == NULL)
1359
0
      goto mem_error;
1360
2.33k
    }
1361
1362
58.1k
    if (xmlHashLookup2(ctxt->attsSpecial, fullname, fullattr) != NULL)
1363
39.8k
        return;
1364
1365
18.3k
    xmlHashAddEntry2(ctxt->attsSpecial, fullname, fullattr,
1366
18.3k
                     (void *) (ptrdiff_t) type);
1367
18.3k
    return;
1368
1369
0
mem_error:
1370
0
    xmlErrMemory(ctxt, NULL);
1371
0
    return;
1372
58.1k
}
1373
1374
/**
1375
 * xmlCleanSpecialAttrCallback:
1376
 *
1377
 * Removes CDATA attributes from the special attribute table
1378
 */
1379
static void
1380
xmlCleanSpecialAttrCallback(void *payload, void *data,
1381
                            const xmlChar *fullname, const xmlChar *fullattr,
1382
18.2k
                            const xmlChar *unused ATTRIBUTE_UNUSED) {
1383
18.2k
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) data;
1384
1385
18.2k
    if (((ptrdiff_t) payload) == XML_ATTRIBUTE_CDATA) {
1386
760
        xmlHashRemoveEntry2(ctxt->attsSpecial, fullname, fullattr, NULL);
1387
760
    }
1388
18.2k
}
1389
1390
/**
1391
 * xmlCleanSpecialAttr:
1392
 * @ctxt:  an XML parser context
1393
 *
1394
 * Trim the list of attributes defined to remove all those of type
1395
 * CDATA as they are not special. This call should be done when finishing
1396
 * to parse the DTD and before starting to parse the document root.
1397
 */
1398
static void
1399
xmlCleanSpecialAttr(xmlParserCtxtPtr ctxt)
1400
8.59k
{
1401
8.59k
    if (ctxt->attsSpecial == NULL)
1402
6.26k
        return;
1403
1404
2.32k
    xmlHashScanFull(ctxt->attsSpecial, xmlCleanSpecialAttrCallback, ctxt);
1405
1406
2.32k
    if (xmlHashSize(ctxt->attsSpecial) == 0) {
1407
54
        xmlHashFree(ctxt->attsSpecial, NULL);
1408
54
        ctxt->attsSpecial = NULL;
1409
54
    }
1410
2.32k
    return;
1411
8.59k
}
1412
1413
/**
1414
 * xmlCheckLanguageID:
1415
 * @lang:  pointer to the string value
1416
 *
1417
 * Checks that the value conforms to the LanguageID production:
1418
 *
1419
 * NOTE: this is somewhat deprecated, those productions were removed from
1420
 *       the XML Second edition.
1421
 *
1422
 * [33] LanguageID ::= Langcode ('-' Subcode)*
1423
 * [34] Langcode ::= ISO639Code |  IanaCode |  UserCode
1424
 * [35] ISO639Code ::= ([a-z] | [A-Z]) ([a-z] | [A-Z])
1425
 * [36] IanaCode ::= ('i' | 'I') '-' ([a-z] | [A-Z])+
1426
 * [37] UserCode ::= ('x' | 'X') '-' ([a-z] | [A-Z])+
1427
 * [38] Subcode ::= ([a-z] | [A-Z])+
1428
 *
1429
 * The current REC reference the successors of RFC 1766, currently 5646
1430
 *
1431
 * http://www.rfc-editor.org/rfc/rfc5646.txt
1432
 * langtag       = language
1433
 *                 ["-" script]
1434
 *                 ["-" region]
1435
 *                 *("-" variant)
1436
 *                 *("-" extension)
1437
 *                 ["-" privateuse]
1438
 * language      = 2*3ALPHA            ; shortest ISO 639 code
1439
 *                 ["-" extlang]       ; sometimes followed by
1440
 *                                     ; extended language subtags
1441
 *               / 4ALPHA              ; or reserved for future use
1442
 *               / 5*8ALPHA            ; or registered language subtag
1443
 *
1444
 * extlang       = 3ALPHA              ; selected ISO 639 codes
1445
 *                 *2("-" 3ALPHA)      ; permanently reserved
1446
 *
1447
 * script        = 4ALPHA              ; ISO 15924 code
1448
 *
1449
 * region        = 2ALPHA              ; ISO 3166-1 code
1450
 *               / 3DIGIT              ; UN M.49 code
1451
 *
1452
 * variant       = 5*8alphanum         ; registered variants
1453
 *               / (DIGIT 3alphanum)
1454
 *
1455
 * extension     = singleton 1*("-" (2*8alphanum))
1456
 *
1457
 *                                     ; Single alphanumerics
1458
 *                                     ; "x" reserved for private use
1459
 * singleton     = DIGIT               ; 0 - 9
1460
 *               / %x41-57             ; A - W
1461
 *               / %x59-5A             ; Y - Z
1462
 *               / %x61-77             ; a - w
1463
 *               / %x79-7A             ; y - z
1464
 *
1465
 * it sounds right to still allow Irregular i-xxx IANA and user codes too
1466
 * The parser below doesn't try to cope with extension or privateuse
1467
 * that could be added but that's not interoperable anyway
1468
 *
1469
 * Returns 1 if correct 0 otherwise
1470
 **/
1471
int
1472
xmlCheckLanguageID(const xmlChar * lang)
1473
0
{
1474
0
    const xmlChar *cur = lang, *nxt;
1475
1476
0
    if (cur == NULL)
1477
0
        return (0);
1478
0
    if (((cur[0] == 'i') && (cur[1] == '-')) ||
1479
0
        ((cur[0] == 'I') && (cur[1] == '-')) ||
1480
0
        ((cur[0] == 'x') && (cur[1] == '-')) ||
1481
0
        ((cur[0] == 'X') && (cur[1] == '-'))) {
1482
        /*
1483
         * Still allow IANA code and user code which were coming
1484
         * from the previous version of the XML-1.0 specification
1485
         * it's deprecated but we should not fail
1486
         */
1487
0
        cur += 2;
1488
0
        while (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
1489
0
               ((cur[0] >= 'a') && (cur[0] <= 'z')))
1490
0
            cur++;
1491
0
        return(cur[0] == 0);
1492
0
    }
1493
0
    nxt = cur;
1494
0
    while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
1495
0
           ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
1496
0
           nxt++;
1497
0
    if (nxt - cur >= 4) {
1498
        /*
1499
         * Reserved
1500
         */
1501
0
        if ((nxt - cur > 8) || (nxt[0] != 0))
1502
0
            return(0);
1503
0
        return(1);
1504
0
    }
1505
0
    if (nxt - cur < 2)
1506
0
        return(0);
1507
    /* we got an ISO 639 code */
1508
0
    if (nxt[0] == 0)
1509
0
        return(1);
1510
0
    if (nxt[0] != '-')
1511
0
        return(0);
1512
1513
0
    nxt++;
1514
0
    cur = nxt;
1515
    /* now we can have extlang or script or region or variant */
1516
0
    if ((nxt[0] >= '0') && (nxt[0] <= '9'))
1517
0
        goto region_m49;
1518
1519
0
    while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
1520
0
           ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
1521
0
           nxt++;
1522
0
    if (nxt - cur == 4)
1523
0
        goto script;
1524
0
    if (nxt - cur == 2)
1525
0
        goto region;
1526
0
    if ((nxt - cur >= 5) && (nxt - cur <= 8))
1527
0
        goto variant;
1528
0
    if (nxt - cur != 3)
1529
0
        return(0);
1530
    /* we parsed an extlang */
1531
0
    if (nxt[0] == 0)
1532
0
        return(1);
1533
0
    if (nxt[0] != '-')
1534
0
        return(0);
1535
1536
0
    nxt++;
1537
0
    cur = nxt;
1538
    /* now we can have script or region or variant */
1539
0
    if ((nxt[0] >= '0') && (nxt[0] <= '9'))
1540
0
        goto region_m49;
1541
1542
0
    while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
1543
0
           ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
1544
0
           nxt++;
1545
0
    if (nxt - cur == 2)
1546
0
        goto region;
1547
0
    if ((nxt - cur >= 5) && (nxt - cur <= 8))
1548
0
        goto variant;
1549
0
    if (nxt - cur != 4)
1550
0
        return(0);
1551
    /* we parsed a script */
1552
0
script:
1553
0
    if (nxt[0] == 0)
1554
0
        return(1);
1555
0
    if (nxt[0] != '-')
1556
0
        return(0);
1557
1558
0
    nxt++;
1559
0
    cur = nxt;
1560
    /* now we can have region or variant */
1561
0
    if ((nxt[0] >= '0') && (nxt[0] <= '9'))
1562
0
        goto region_m49;
1563
1564
0
    while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
1565
0
           ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
1566
0
           nxt++;
1567
1568
0
    if ((nxt - cur >= 5) && (nxt - cur <= 8))
1569
0
        goto variant;
1570
0
    if (nxt - cur != 2)
1571
0
        return(0);
1572
    /* we parsed a region */
1573
0
region:
1574
0
    if (nxt[0] == 0)
1575
0
        return(1);
1576
0
    if (nxt[0] != '-')
1577
0
        return(0);
1578
1579
0
    nxt++;
1580
0
    cur = nxt;
1581
    /* now we can just have a variant */
1582
0
    while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
1583
0
           ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
1584
0
           nxt++;
1585
1586
0
    if ((nxt - cur < 5) || (nxt - cur > 8))
1587
0
        return(0);
1588
1589
    /* we parsed a variant */
1590
0
variant:
1591
0
    if (nxt[0] == 0)
1592
0
        return(1);
1593
0
    if (nxt[0] != '-')
1594
0
        return(0);
1595
    /* extensions and private use subtags not checked */
1596
0
    return (1);
1597
1598
0
region_m49:
1599
0
    if (((nxt[1] >= '0') && (nxt[1] <= '9')) &&
1600
0
        ((nxt[2] >= '0') && (nxt[2] <= '9'))) {
1601
0
        nxt += 3;
1602
0
        goto region;
1603
0
    }
1604
0
    return(0);
1605
0
}
1606
1607
/************************************************************************
1608
 *                  *
1609
 *    Parser stacks related functions and macros    *
1610
 *                  *
1611
 ************************************************************************/
1612
1613
static xmlEntityPtr xmlParseStringEntityRef(xmlParserCtxtPtr ctxt,
1614
                                            const xmlChar ** str);
1615
1616
#ifdef SAX2
1617
/**
1618
 * nsPush:
1619
 * @ctxt:  an XML parser context
1620
 * @prefix:  the namespace prefix or NULL
1621
 * @URL:  the namespace name
1622
 *
1623
 * Pushes a new parser namespace on top of the ns stack
1624
 *
1625
 * Returns -1 in case of error, -2 if the namespace should be discarded
1626
 *     and the index in the stack otherwise.
1627
 */
1628
static int
1629
nsPush(xmlParserCtxtPtr ctxt, const xmlChar *prefix, const xmlChar *URL)
1630
53.2M
{
1631
53.2M
    if (ctxt->options & XML_PARSE_NSCLEAN) {
1632
0
        int i;
1633
0
  for (i = ctxt->nsNr - 2;i >= 0;i -= 2) {
1634
0
      if (ctxt->nsTab[i] == prefix) {
1635
    /* in scope */
1636
0
          if (ctxt->nsTab[i + 1] == URL)
1637
0
        return(-2);
1638
    /* out of scope keep it */
1639
0
    break;
1640
0
      }
1641
0
  }
1642
0
    }
1643
53.2M
    if ((ctxt->nsMax == 0) || (ctxt->nsTab == NULL)) {
1644
153k
  ctxt->nsMax = 10;
1645
153k
  ctxt->nsNr = 0;
1646
153k
  ctxt->nsTab = (const xmlChar **)
1647
153k
                xmlMalloc(ctxt->nsMax * sizeof(xmlChar *));
1648
153k
  if (ctxt->nsTab == NULL) {
1649
0
      xmlErrMemory(ctxt, NULL);
1650
0
      ctxt->nsMax = 0;
1651
0
            return (-1);
1652
0
  }
1653
53.0M
    } else if (ctxt->nsNr >= ctxt->nsMax) {
1654
633k
        const xmlChar ** tmp;
1655
633k
        ctxt->nsMax *= 2;
1656
633k
        tmp = (const xmlChar **) xmlRealloc((char *) ctxt->nsTab,
1657
633k
            ctxt->nsMax * sizeof(ctxt->nsTab[0]));
1658
633k
        if (tmp == NULL) {
1659
0
            xmlErrMemory(ctxt, NULL);
1660
0
      ctxt->nsMax /= 2;
1661
0
            return (-1);
1662
0
        }
1663
633k
  ctxt->nsTab = tmp;
1664
633k
    }
1665
53.2M
    ctxt->nsTab[ctxt->nsNr++] = prefix;
1666
53.2M
    ctxt->nsTab[ctxt->nsNr++] = URL;
1667
53.2M
    return (ctxt->nsNr);
1668
53.2M
}
1669
/**
1670
 * nsPop:
1671
 * @ctxt: an XML parser context
1672
 * @nr:  the number to pop
1673
 *
1674
 * Pops the top @nr parser prefix/namespace from the ns stack
1675
 *
1676
 * Returns the number of namespaces removed
1677
 */
1678
static int
1679
nsPop(xmlParserCtxtPtr ctxt, int nr)
1680
117k
{
1681
117k
    int i;
1682
1683
117k
    if (ctxt->nsTab == NULL) return(0);
1684
117k
    if (ctxt->nsNr < nr) {
1685
0
        xmlGenericError(xmlGenericErrorContext, "Pbm popping %d NS\n", nr);
1686
0
        nr = ctxt->nsNr;
1687
0
    }
1688
117k
    if (ctxt->nsNr <= 0)
1689
0
        return (0);
1690
1691
1.20M
    for (i = 0;i < nr;i++) {
1692
1.08M
         ctxt->nsNr--;
1693
1.08M
   ctxt->nsTab[ctxt->nsNr] = NULL;
1694
1.08M
    }
1695
117k
    return(nr);
1696
117k
}
1697
#endif
1698
1699
static int
1700
56.2k
xmlCtxtGrowAttrs(xmlParserCtxtPtr ctxt, int nr) {
1701
56.2k
    const xmlChar **atts;
1702
56.2k
    int *attallocs;
1703
56.2k
    int maxatts;
1704
1705
56.2k
    if (ctxt->atts == NULL) {
1706
56.1k
  maxatts = 55; /* allow for 10 attrs by default */
1707
56.1k
  atts = (const xmlChar **)
1708
56.1k
         xmlMalloc(maxatts * sizeof(xmlChar *));
1709
56.1k
  if (atts == NULL) goto mem_error;
1710
56.1k
  ctxt->atts = atts;
1711
56.1k
  attallocs = (int *) xmlMalloc((maxatts / 5) * sizeof(int));
1712
56.1k
  if (attallocs == NULL) goto mem_error;
1713
56.1k
  ctxt->attallocs = attallocs;
1714
56.1k
  ctxt->maxatts = maxatts;
1715
56.1k
    } else if (nr + 5 > ctxt->maxatts) {
1716
64
  maxatts = (nr + 5) * 2;
1717
64
  atts = (const xmlChar **) xmlRealloc((void *) ctxt->atts,
1718
64
             maxatts * sizeof(const xmlChar *));
1719
64
  if (atts == NULL) goto mem_error;
1720
64
  ctxt->atts = atts;
1721
64
  attallocs = (int *) xmlRealloc((void *) ctxt->attallocs,
1722
64
                               (maxatts / 5) * sizeof(int));
1723
64
  if (attallocs == NULL) goto mem_error;
1724
64
  ctxt->attallocs = attallocs;
1725
64
  ctxt->maxatts = maxatts;
1726
64
    }
1727
56.2k
    return(ctxt->maxatts);
1728
0
mem_error:
1729
0
    xmlErrMemory(ctxt, NULL);
1730
0
    return(-1);
1731
56.2k
}
1732
1733
/**
1734
 * inputPush:
1735
 * @ctxt:  an XML parser context
1736
 * @value:  the parser input
1737
 *
1738
 * Pushes a new parser input on top of the input stack
1739
 *
1740
 * Returns -1 in case of error, the index in the stack otherwise
1741
 */
1742
int
1743
inputPush(xmlParserCtxtPtr ctxt, xmlParserInputPtr value)
1744
5.95M
{
1745
5.95M
    if ((ctxt == NULL) || (value == NULL))
1746
0
        return(-1);
1747
5.95M
    if (ctxt->inputNr >= ctxt->inputMax) {
1748
4.32k
        ctxt->inputMax *= 2;
1749
4.32k
        ctxt->inputTab =
1750
4.32k
            (xmlParserInputPtr *) xmlRealloc(ctxt->inputTab,
1751
4.32k
                                             ctxt->inputMax *
1752
4.32k
                                             sizeof(ctxt->inputTab[0]));
1753
4.32k
        if (ctxt->inputTab == NULL) {
1754
0
            xmlErrMemory(ctxt, NULL);
1755
0
      xmlFreeInputStream(value);
1756
0
      ctxt->inputMax /= 2;
1757
0
      value = NULL;
1758
0
            return (-1);
1759
0
        }
1760
4.32k
    }
1761
5.95M
    ctxt->inputTab[ctxt->inputNr] = value;
1762
5.95M
    ctxt->input = value;
1763
5.95M
    return (ctxt->inputNr++);
1764
5.95M
}
1765
/**
1766
 * inputPop:
1767
 * @ctxt: an XML parser context
1768
 *
1769
 * Pops the top parser input from the input stack
1770
 *
1771
 * Returns the input just removed
1772
 */
1773
xmlParserInputPtr
1774
inputPop(xmlParserCtxtPtr ctxt)
1775
6.59M
{
1776
6.59M
    xmlParserInputPtr ret;
1777
1778
6.59M
    if (ctxt == NULL)
1779
0
        return(NULL);
1780
6.59M
    if (ctxt->inputNr <= 0)
1781
639k
        return (NULL);
1782
5.95M
    ctxt->inputNr--;
1783
5.95M
    if (ctxt->inputNr > 0)
1784
5.63M
        ctxt->input = ctxt->inputTab[ctxt->inputNr - 1];
1785
319k
    else
1786
319k
        ctxt->input = NULL;
1787
5.95M
    ret = ctxt->inputTab[ctxt->inputNr];
1788
5.95M
    ctxt->inputTab[ctxt->inputNr] = NULL;
1789
5.95M
    return (ret);
1790
6.59M
}
1791
/**
1792
 * nodePush:
1793
 * @ctxt:  an XML parser context
1794
 * @value:  the element node
1795
 *
1796
 * Pushes a new element node on top of the node stack
1797
 *
1798
 * Returns -1 in case of error, the index in the stack otherwise
1799
 */
1800
int
1801
nodePush(xmlParserCtxtPtr ctxt, xmlNodePtr value)
1802
834k
{
1803
834k
    if (ctxt == NULL) return(0);
1804
834k
    if (ctxt->nodeNr >= ctxt->nodeMax) {
1805
3.50k
        xmlNodePtr *tmp;
1806
1807
3.50k
  tmp = (xmlNodePtr *) xmlRealloc(ctxt->nodeTab,
1808
3.50k
                                      ctxt->nodeMax * 2 *
1809
3.50k
                                      sizeof(ctxt->nodeTab[0]));
1810
3.50k
        if (tmp == NULL) {
1811
0
            xmlErrMemory(ctxt, NULL);
1812
0
            return (-1);
1813
0
        }
1814
3.50k
        ctxt->nodeTab = tmp;
1815
3.50k
  ctxt->nodeMax *= 2;
1816
3.50k
    }
1817
834k
    if ((((unsigned int) ctxt->nodeNr) > xmlParserMaxDepth) &&
1818
834k
        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
1819
0
  xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
1820
0
     "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
1821
0
        xmlParserMaxDepth);
1822
0
  xmlHaltParser(ctxt);
1823
0
  return(-1);
1824
0
    }
1825
834k
    ctxt->nodeTab[ctxt->nodeNr] = value;
1826
834k
    ctxt->node = value;
1827
834k
    return (ctxt->nodeNr++);
1828
834k
}
1829
1830
/**
1831
 * nodePop:
1832
 * @ctxt: an XML parser context
1833
 *
1834
 * Pops the top element node from the node stack
1835
 *
1836
 * Returns the node just removed
1837
 */
1838
xmlNodePtr
1839
nodePop(xmlParserCtxtPtr ctxt)
1840
401k
{
1841
401k
    xmlNodePtr ret;
1842
1843
401k
    if (ctxt == NULL) return(NULL);
1844
401k
    if (ctxt->nodeNr <= 0)
1845
171k
        return (NULL);
1846
229k
    ctxt->nodeNr--;
1847
229k
    if (ctxt->nodeNr > 0)
1848
202k
        ctxt->node = ctxt->nodeTab[ctxt->nodeNr - 1];
1849
27.1k
    else
1850
27.1k
        ctxt->node = NULL;
1851
229k
    ret = ctxt->nodeTab[ctxt->nodeNr];
1852
229k
    ctxt->nodeTab[ctxt->nodeNr] = NULL;
1853
229k
    return (ret);
1854
401k
}
1855
1856
/**
1857
 * nameNsPush:
1858
 * @ctxt:  an XML parser context
1859
 * @value:  the element name
1860
 * @prefix:  the element prefix
1861
 * @URI:  the element namespace name
1862
 * @line:  the current line number for error messages
1863
 * @nsNr:  the number of namespaces pushed on the namespace table
1864
 *
1865
 * Pushes a new element name/prefix/URL on top of the name stack
1866
 *
1867
 * Returns -1 in case of error, the index in the stack otherwise
1868
 */
1869
static int
1870
nameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value,
1871
           const xmlChar *prefix, const xmlChar *URI, int line, int nsNr)
1872
5.66M
{
1873
5.66M
    xmlStartTag *tag;
1874
1875
5.66M
    if (ctxt->nameNr >= ctxt->nameMax) {
1876
5.64k
        const xmlChar * *tmp;
1877
5.64k
        xmlStartTag *tmp2;
1878
5.64k
        ctxt->nameMax *= 2;
1879
5.64k
        tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,
1880
5.64k
                                    ctxt->nameMax *
1881
5.64k
                                    sizeof(ctxt->nameTab[0]));
1882
5.64k
        if (tmp == NULL) {
1883
0
      ctxt->nameMax /= 2;
1884
0
      goto mem_error;
1885
0
        }
1886
5.64k
  ctxt->nameTab = tmp;
1887
5.64k
        tmp2 = (xmlStartTag *) xmlRealloc((void * *)ctxt->pushTab,
1888
5.64k
                                    ctxt->nameMax *
1889
5.64k
                                    sizeof(ctxt->pushTab[0]));
1890
5.64k
        if (tmp2 == NULL) {
1891
0
      ctxt->nameMax /= 2;
1892
0
      goto mem_error;
1893
0
        }
1894
5.64k
  ctxt->pushTab = tmp2;
1895
5.65M
    } else if (ctxt->pushTab == NULL) {
1896
157k
        ctxt->pushTab = (xmlStartTag *) xmlMalloc(ctxt->nameMax *
1897
157k
                                            sizeof(ctxt->pushTab[0]));
1898
157k
        if (ctxt->pushTab == NULL)
1899
0
            goto mem_error;
1900
157k
    }
1901
5.66M
    ctxt->nameTab[ctxt->nameNr] = value;
1902
5.66M
    ctxt->name = value;
1903
5.66M
    tag = &ctxt->pushTab[ctxt->nameNr];
1904
5.66M
    tag->prefix = prefix;
1905
5.66M
    tag->URI = URI;
1906
5.66M
    tag->line = line;
1907
5.66M
    tag->nsNr = nsNr;
1908
5.66M
    return (ctxt->nameNr++);
1909
0
mem_error:
1910
0
    xmlErrMemory(ctxt, NULL);
1911
0
    return (-1);
1912
5.66M
}
1913
#ifdef LIBXML_PUSH_ENABLED
1914
/**
1915
 * nameNsPop:
1916
 * @ctxt: an XML parser context
1917
 *
1918
 * Pops the top element/prefix/URI name from the name stack
1919
 *
1920
 * Returns the name just removed
1921
 */
1922
static const xmlChar *
1923
nameNsPop(xmlParserCtxtPtr ctxt)
1924
0
{
1925
0
    const xmlChar *ret;
1926
1927
0
    if (ctxt->nameNr <= 0)
1928
0
        return (NULL);
1929
0
    ctxt->nameNr--;
1930
0
    if (ctxt->nameNr > 0)
1931
0
        ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
1932
0
    else
1933
0
        ctxt->name = NULL;
1934
0
    ret = ctxt->nameTab[ctxt->nameNr];
1935
0
    ctxt->nameTab[ctxt->nameNr] = NULL;
1936
0
    return (ret);
1937
0
}
1938
#endif /* LIBXML_PUSH_ENABLED */
1939
1940
/**
1941
 * namePush:
1942
 * @ctxt:  an XML parser context
1943
 * @value:  the element name
1944
 *
1945
 * Pushes a new element name on top of the name stack
1946
 *
1947
 * Returns -1 in case of error, the index in the stack otherwise
1948
 */
1949
int
1950
namePush(xmlParserCtxtPtr ctxt, const xmlChar * value)
1951
0
{
1952
0
    if (ctxt == NULL) return (-1);
1953
1954
0
    if (ctxt->nameNr >= ctxt->nameMax) {
1955
0
        const xmlChar * *tmp;
1956
0
        tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,
1957
0
                                    ctxt->nameMax * 2 *
1958
0
                                    sizeof(ctxt->nameTab[0]));
1959
0
        if (tmp == NULL) {
1960
0
      goto mem_error;
1961
0
        }
1962
0
  ctxt->nameTab = tmp;
1963
0
        ctxt->nameMax *= 2;
1964
0
    }
1965
0
    ctxt->nameTab[ctxt->nameNr] = value;
1966
0
    ctxt->name = value;
1967
0
    return (ctxt->nameNr++);
1968
0
mem_error:
1969
0
    xmlErrMemory(ctxt, NULL);
1970
0
    return (-1);
1971
0
}
1972
/**
1973
 * namePop:
1974
 * @ctxt: an XML parser context
1975
 *
1976
 * Pops the top element name from the name stack
1977
 *
1978
 * Returns the name just removed
1979
 */
1980
const xmlChar *
1981
namePop(xmlParserCtxtPtr ctxt)
1982
476k
{
1983
476k
    const xmlChar *ret;
1984
1985
476k
    if ((ctxt == NULL) || (ctxt->nameNr <= 0))
1986
0
        return (NULL);
1987
476k
    ctxt->nameNr--;
1988
476k
    if (ctxt->nameNr > 0)
1989
420k
        ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
1990
55.9k
    else
1991
55.9k
        ctxt->name = NULL;
1992
476k
    ret = ctxt->nameTab[ctxt->nameNr];
1993
476k
    ctxt->nameTab[ctxt->nameNr] = NULL;
1994
476k
    return (ret);
1995
476k
}
1996
1997
5.79M
static int spacePush(xmlParserCtxtPtr ctxt, int val) {
1998
5.79M
    if (ctxt->spaceNr >= ctxt->spaceMax) {
1999
5.73k
        int *tmp;
2000
2001
5.73k
  ctxt->spaceMax *= 2;
2002
5.73k
        tmp = (int *) xmlRealloc(ctxt->spaceTab,
2003
5.73k
                           ctxt->spaceMax * sizeof(ctxt->spaceTab[0]));
2004
5.73k
        if (tmp == NULL) {
2005
0
      xmlErrMemory(ctxt, NULL);
2006
0
      ctxt->spaceMax /=2;
2007
0
      return(-1);
2008
0
  }
2009
5.73k
  ctxt->spaceTab = tmp;
2010
5.73k
    }
2011
5.79M
    ctxt->spaceTab[ctxt->spaceNr] = val;
2012
5.79M
    ctxt->space = &ctxt->spaceTab[ctxt->spaceNr];
2013
5.79M
    return(ctxt->spaceNr++);
2014
5.79M
}
2015
2016
606k
static int spacePop(xmlParserCtxtPtr ctxt) {
2017
606k
    int ret;
2018
606k
    if (ctxt->spaceNr <= 0) return(0);
2019
606k
    ctxt->spaceNr--;
2020
606k
    if (ctxt->spaceNr > 0)
2021
606k
  ctxt->space = &ctxt->spaceTab[ctxt->spaceNr - 1];
2022
0
    else
2023
0
        ctxt->space = &ctxt->spaceTab[0];
2024
606k
    ret = ctxt->spaceTab[ctxt->spaceNr];
2025
606k
    ctxt->spaceTab[ctxt->spaceNr] = -1;
2026
606k
    return(ret);
2027
606k
}
2028
2029
/*
2030
 * Macros for accessing the content. Those should be used only by the parser,
2031
 * and not exported.
2032
 *
2033
 * Dirty macros, i.e. one often need to make assumption on the context to
2034
 * use them
2035
 *
2036
 *   CUR_PTR return the current pointer to the xmlChar to be parsed.
2037
 *           To be used with extreme caution since operations consuming
2038
 *           characters may move the input buffer to a different location !
2039
 *   CUR     returns the current xmlChar value, i.e. a 8 bit value if compiled
2040
 *           This should be used internally by the parser
2041
 *           only to compare to ASCII values otherwise it would break when
2042
 *           running with UTF-8 encoding.
2043
 *   RAW     same as CUR but in the input buffer, bypass any token
2044
 *           extraction that may have been done
2045
 *   NXT(n)  returns the n'th next xmlChar. Same as CUR is should be used only
2046
 *           to compare on ASCII based substring.
2047
 *   SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
2048
 *           strings without newlines within the parser.
2049
 *   NEXT1(l) Skip 1 xmlChar, and must also be used only to skip 1 non-newline ASCII
2050
 *           defined char within the parser.
2051
 * Clean macros, not dependent of an ASCII context, expect UTF-8 encoding
2052
 *
2053
 *   NEXT    Skip to the next character, this does the proper decoding
2054
 *           in UTF-8 mode. It also pop-up unfinished entities on the fly.
2055
 *   NEXTL(l) Skip the current unicode character of l xmlChars long.
2056
 *   CUR_CHAR(l) returns the current unicode character (int), set l
2057
 *           to the number of xmlChars used for the encoding [0-5].
2058
 *   CUR_SCHAR  same but operate on a string instead of the context
2059
 *   COPY_BUF  copy the current unicode char to the target buffer, increment
2060
 *            the index
2061
 *   GROW, SHRINK  handling of input buffers
2062
 */
2063
2064
104M
#define RAW (*ctxt->input->cur)
2065
123M
#define CUR (*ctxt->input->cur)
2066
351M
#define NXT(val) ctxt->input->cur[(val)]
2067
1.67M
#define CUR_PTR ctxt->input->cur
2068
447k
#define BASE_PTR ctxt->input->base
2069
2070
#define CMP4( s, c1, c2, c3, c4 ) \
2071
50.7M
  ( ((unsigned char *) s)[ 0 ] == c1 && ((unsigned char *) s)[ 1 ] == c2 && \
2072
25.4M
    ((unsigned char *) s)[ 2 ] == c3 && ((unsigned char *) s)[ 3 ] == c4 )
2073
#define CMP5( s, c1, c2, c3, c4, c5 ) \
2074
46.8M
  ( CMP4( s, c1, c2, c3, c4 ) && ((unsigned char *) s)[ 4 ] == c5 )
2075
#define CMP6( s, c1, c2, c3, c4, c5, c6 ) \
2076
38.3M
  ( CMP5( s, c1, c2, c3, c4, c5 ) && ((unsigned char *) s)[ 5 ] == c6 )
2077
#define CMP7( s, c1, c2, c3, c4, c5, c6, c7 ) \
2078
32.5M
  ( CMP6( s, c1, c2, c3, c4, c5, c6 ) && ((unsigned char *) s)[ 6 ] == c7 )
2079
#define CMP8( s, c1, c2, c3, c4, c5, c6, c7, c8 ) \
2080
26.1M
  ( CMP7( s, c1, c2, c3, c4, c5, c6, c7 ) && ((unsigned char *) s)[ 7 ] == c8 )
2081
#define CMP9( s, c1, c2, c3, c4, c5, c6, c7, c8, c9 ) \
2082
10.6M
  ( CMP8( s, c1, c2, c3, c4, c5, c6, c7, c8 ) && \
2083
10.6M
    ((unsigned char *) s)[ 8 ] == c9 )
2084
#define CMP10( s, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10 ) \
2085
195k
  ( CMP9( s, c1, c2, c3, c4, c5, c6, c7, c8, c9 ) && \
2086
195k
    ((unsigned char *) s)[ 9 ] == c10 )
2087
2088
8.94M
#define SKIP(val) do {             \
2089
8.94M
    ctxt->input->cur += (val),ctxt->input->col+=(val);      \
2090
8.94M
    if (*ctxt->input->cur == 0)           \
2091
8.94M
        xmlParserInputGrow(ctxt->input, INPUT_CHUNK);     \
2092
8.94M
  } while (0)
2093
2094
0
#define SKIPL(val) do {             \
2095
0
    int skipl;                \
2096
0
    for(skipl=0; skipl<val; skipl++) {         \
2097
0
  if (*(ctxt->input->cur) == '\n') {       \
2098
0
  ctxt->input->line++; ctxt->input->col = 1;      \
2099
0
  } else ctxt->input->col++;         \
2100
0
  ctxt->input->cur++;           \
2101
0
    }                 \
2102
0
    if (*ctxt->input->cur == 0)           \
2103
0
        xmlParserInputGrow(ctxt->input, INPUT_CHUNK);      \
2104
0
  } while (0)
2105
2106
36.7M
#define SHRINK if ((ctxt->progressive == 0) &&       \
2107
36.7M
       (ctxt->input->cur - ctxt->input->base > 2 * INPUT_CHUNK) && \
2108
36.7M
       (ctxt->input->end - ctxt->input->cur < 2 * INPUT_CHUNK)) \
2109
36.7M
  xmlSHRINK (ctxt);
2110
2111
96.7k
static void xmlSHRINK (xmlParserCtxtPtr ctxt) {
2112
96.7k
    xmlParserInputShrink(ctxt->input);
2113
96.7k
    if (*ctxt->input->cur == 0)
2114
18.6k
        xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
2115
96.7k
}
2116
2117
970M
#define GROW if ((ctxt->progressive == 0) &&       \
2118
970M
     (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK))  \
2119
970M
  xmlGROW (ctxt);
2120
2121
55.3M
static void xmlGROW (xmlParserCtxtPtr ctxt) {
2122
55.3M
    ptrdiff_t curEnd = ctxt->input->end - ctxt->input->cur;
2123
55.3M
    ptrdiff_t curBase = ctxt->input->cur - ctxt->input->base;
2124
2125
55.3M
    if (((curEnd > XML_MAX_LOOKUP_LIMIT) ||
2126
55.3M
         (curBase > XML_MAX_LOOKUP_LIMIT)) &&
2127
55.3M
         ((ctxt->input->buf) &&
2128
2.83k
          (ctxt->input->buf->readcallback != xmlInputReadCallbackNop)) &&
2129
55.3M
        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
2130
0
        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "Huge input lookup");
2131
0
        xmlHaltParser(ctxt);
2132
0
  return;
2133
0
    }
2134
55.3M
    xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
2135
55.3M
    if ((ctxt->input->cur > ctxt->input->end) ||
2136
55.3M
        (ctxt->input->cur < ctxt->input->base)) {
2137
0
        xmlHaltParser(ctxt);
2138
0
        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "cur index out of bound");
2139
0
  return;
2140
0
    }
2141
55.3M
    if ((ctxt->input->cur != NULL) && (*ctxt->input->cur == 0))
2142
509k
        xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
2143
55.3M
}
2144
2145
50.9M
#define SKIP_BLANKS xmlSkipBlankChars(ctxt)
2146
2147
42.8M
#define NEXT xmlNextChar(ctxt)
2148
2149
11.3M
#define NEXT1 {               \
2150
11.3M
  ctxt->input->col++;           \
2151
11.3M
  ctxt->input->cur++;           \
2152
11.3M
  if (*ctxt->input->cur == 0)         \
2153
11.3M
      xmlParserInputGrow(ctxt->input, INPUT_CHUNK);   \
2154
11.3M
    }
2155
2156
1.72G
#define NEXTL(l) do {             \
2157
1.72G
    if (*(ctxt->input->cur) == '\n') {         \
2158
7.75M
  ctxt->input->line++; ctxt->input->col = 1;      \
2159
1.72G
    } else ctxt->input->col++;           \
2160
1.72G
    ctxt->input->cur += l;        \
2161
1.72G
  } while (0)
2162
2163
1.73G
#define CUR_CHAR(l) xmlCurrentChar(ctxt, &l)
2164
931M
#define CUR_SCHAR(s, l) xmlStringCurrentChar(ctxt, s, &l)
2165
2166
#define COPY_BUF(l,b,i,v)           \
2167
2.54G
    if (l == 1) b[i++] = (xmlChar) v;         \
2168
2.54G
    else i += xmlCopyCharMultiByte(&b[i],v)
2169
2170
#define CUR_CONSUMED \
2171
27.9M
    (ctxt->input->consumed + (ctxt->input->cur - ctxt->input->base))
2172
2173
/**
2174
 * xmlSkipBlankChars:
2175
 * @ctxt:  the XML parser context
2176
 *
2177
 * skip all blanks character found at that point in the input streams.
2178
 * It pops up finished entities in the process if allowable at that point.
2179
 *
2180
 * Returns the number of space chars skipped
2181
 */
2182
2183
int
2184
50.9M
xmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
2185
50.9M
    int res = 0;
2186
2187
    /*
2188
     * It's Okay to use CUR/NEXT here since all the blanks are on
2189
     * the ASCII range.
2190
     */
2191
50.9M
    if (((ctxt->inputNr == 1) && (ctxt->instate != XML_PARSER_DTD)) ||
2192
50.9M
        (ctxt->instate == XML_PARSER_START)) {
2193
6.80M
  const xmlChar *cur;
2194
  /*
2195
   * if we are in the document content, go really fast
2196
   */
2197
6.80M
  cur = ctxt->input->cur;
2198
6.80M
  while (IS_BLANK_CH(*cur)) {
2199
389k
      if (*cur == '\n') {
2200
27.2k
    ctxt->input->line++; ctxt->input->col = 1;
2201
361k
      } else {
2202
361k
    ctxt->input->col++;
2203
361k
      }
2204
389k
      cur++;
2205
389k
      if (res < INT_MAX)
2206
389k
    res++;
2207
389k
      if (*cur == 0) {
2208
1.08k
    ctxt->input->cur = cur;
2209
1.08k
    xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
2210
1.08k
    cur = ctxt->input->cur;
2211
1.08k
      }
2212
389k
  }
2213
6.80M
  ctxt->input->cur = cur;
2214
44.0M
    } else {
2215
44.0M
        int expandPE = ((ctxt->external != 0) || (ctxt->inputNr != 1));
2216
2217
54.6M
  while (1) {
2218
54.6M
            if (IS_BLANK_CH(CUR)) { /* CHECKED tstblanks.xml */
2219
4.76M
    NEXT;
2220
49.8M
      } else if (CUR == '%') {
2221
                /*
2222
                 * Need to handle support of entities branching here
2223
                 */
2224
5.66M
          if ((expandPE == 0) || (IS_BLANK_CH(NXT(1))) || (NXT(1) == 0))
2225
34.3k
                    break;
2226
5.63M
          xmlParsePEReference(ctxt);
2227
44.2M
            } else if (CUR == 0) {
2228
154k
                if (ctxt->inputNr <= 1)
2229
4.92k
                    break;
2230
149k
                xmlPopInput(ctxt);
2231
44.0M
            } else {
2232
44.0M
                break;
2233
44.0M
            }
2234
2235
            /*
2236
             * Also increase the counter when entering or exiting a PERef.
2237
             * The spec says: "When a parameter-entity reference is recognized
2238
             * in the DTD and included, its replacement text MUST be enlarged
2239
             * by the attachment of one leading and one following space (#x20)
2240
             * character."
2241
             */
2242
10.5M
      if (res < INT_MAX)
2243
10.5M
    res++;
2244
10.5M
        }
2245
44.0M
    }
2246
50.9M
    return(res);
2247
50.9M
}
2248
2249
/************************************************************************
2250
 *                  *
2251
 *    Commodity functions to handle entities      *
2252
 *                  *
2253
 ************************************************************************/
2254
2255
/**
2256
 * xmlPopInput:
2257
 * @ctxt:  an XML parser context
2258
 *
2259
 * xmlPopInput: the current input pointed by ctxt->input came to an end
2260
 *          pop it and return the next char.
2261
 *
2262
 * Returns the current xmlChar in the parser context
2263
 */
2264
xmlChar
2265
1.46M
xmlPopInput(xmlParserCtxtPtr ctxt) {
2266
1.46M
    if ((ctxt == NULL) || (ctxt->inputNr <= 1)) return(0);
2267
1.46M
    if (xmlParserDebugEntities)
2268
0
  xmlGenericError(xmlGenericErrorContext,
2269
0
    "Popping input %d\n", ctxt->inputNr);
2270
1.46M
    if ((ctxt->inputNr > 1) && (ctxt->inSubset == 0) &&
2271
1.46M
        (ctxt->instate != XML_PARSER_EOF))
2272
0
        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
2273
0
                    "Unfinished entity outside the DTD");
2274
1.46M
    xmlFreeInputStream(inputPop(ctxt));
2275
1.46M
    if (*ctxt->input->cur == 0)
2276
5.72k
        xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
2277
1.46M
    return(CUR);
2278
1.46M
}
2279
2280
/**
2281
 * xmlPushInput:
2282
 * @ctxt:  an XML parser context
2283
 * @input:  an XML parser input fragment (entity, XML fragment ...).
2284
 *
2285
 * xmlPushInput: switch to a new input stream which is stacked on top
2286
 *               of the previous one(s).
2287
 * Returns -1 in case of error or the index in the input stack
2288
 */
2289
int
2290
5.64M
xmlPushInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr input) {
2291
5.64M
    int ret;
2292
5.64M
    if (input == NULL) return(-1);
2293
2294
5.64M
    if (xmlParserDebugEntities) {
2295
0
  if ((ctxt->input != NULL) && (ctxt->input->filename))
2296
0
      xmlGenericError(xmlGenericErrorContext,
2297
0
        "%s(%d): ", ctxt->input->filename,
2298
0
        ctxt->input->line);
2299
0
  xmlGenericError(xmlGenericErrorContext,
2300
0
    "Pushing input %d : %.30s\n", ctxt->inputNr+1, input->cur);
2301
0
    }
2302
5.64M
    if (((ctxt->inputNr > 40) && ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
2303
5.64M
        (ctxt->inputNr > 1024)) {
2304
4.07k
        xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
2305
4.17M
        while (ctxt->inputNr > 1)
2306
4.17M
            xmlFreeInputStream(inputPop(ctxt));
2307
4.07k
  return(-1);
2308
4.07k
    }
2309
5.63M
    ret = inputPush(ctxt, input);
2310
5.63M
    if (ctxt->instate == XML_PARSER_EOF)
2311
0
        return(-1);
2312
5.63M
    GROW;
2313
5.63M
    return(ret);
2314
5.63M
}
2315
2316
/**
2317
 * xmlParseCharRef:
2318
 * @ctxt:  an XML parser context
2319
 *
2320
 * parse Reference declarations
2321
 *
2322
 * [66] CharRef ::= '&#' [0-9]+ ';' |
2323
 *                  '&#x' [0-9a-fA-F]+ ';'
2324
 *
2325
 * [ WFC: Legal Character ]
2326
 * Characters referred to using character references must match the
2327
 * production for Char.
2328
 *
2329
 * Returns the value parsed (as an int), 0 in case of error
2330
 */
2331
int
2332
532k
xmlParseCharRef(xmlParserCtxtPtr ctxt) {
2333
532k
    int val = 0;
2334
532k
    int count = 0;
2335
2336
    /*
2337
     * Using RAW/CUR/NEXT is okay since we are working on ASCII range here
2338
     */
2339
532k
    if ((RAW == '&') && (NXT(1) == '#') &&
2340
532k
        (NXT(2) == 'x')) {
2341
45.1k
  SKIP(3);
2342
45.1k
  GROW;
2343
165k
  while (RAW != ';') { /* loop blocked by count */
2344
126k
      if (count++ > 20) {
2345
2.73k
    count = 0;
2346
2.73k
    GROW;
2347
2.73k
                if (ctxt->instate == XML_PARSER_EOF)
2348
0
                    return(0);
2349
2.73k
      }
2350
126k
      if ((RAW >= '0') && (RAW <= '9'))
2351
67.7k
          val = val * 16 + (CUR - '0');
2352
58.9k
      else if ((RAW >= 'a') && (RAW <= 'f') && (count < 20))
2353
37.6k
          val = val * 16 + (CUR - 'a') + 10;
2354
21.3k
      else if ((RAW >= 'A') && (RAW <= 'F') && (count < 20))
2355
15.2k
          val = val * 16 + (CUR - 'A') + 10;
2356
6.02k
      else {
2357
6.02k
    xmlFatalErr(ctxt, XML_ERR_INVALID_HEX_CHARREF, NULL);
2358
6.02k
    val = 0;
2359
6.02k
    break;
2360
6.02k
      }
2361
120k
      if (val > 0x110000)
2362
42.6k
          val = 0x110000;
2363
2364
120k
      NEXT;
2365
120k
      count++;
2366
120k
  }
2367
45.1k
  if (RAW == ';') {
2368
      /* on purpose to avoid reentrancy problems with NEXT and SKIP */
2369
39.1k
      ctxt->input->col++;
2370
39.1k
      ctxt->input->cur++;
2371
39.1k
  }
2372
487k
    } else if  ((RAW == '&') && (NXT(1) == '#')) {
2373
487k
  SKIP(2);
2374
487k
  GROW;
2375
1.78M
  while (RAW != ';') { /* loop blocked by count */
2376
1.32M
      if (count++ > 20) {
2377
25.9k
    count = 0;
2378
25.9k
    GROW;
2379
25.9k
                if (ctxt->instate == XML_PARSER_EOF)
2380
0
                    return(0);
2381
25.9k
      }
2382
1.32M
      if ((RAW >= '0') && (RAW <= '9'))
2383
1.29M
          val = val * 10 + (CUR - '0');
2384
25.2k
      else {
2385
25.2k
    xmlFatalErr(ctxt, XML_ERR_INVALID_DEC_CHARREF, NULL);
2386
25.2k
    val = 0;
2387
25.2k
    break;
2388
25.2k
      }
2389
1.29M
      if (val > 0x110000)
2390
278k
          val = 0x110000;
2391
2392
1.29M
      NEXT;
2393
1.29M
      count++;
2394
1.29M
  }
2395
487k
  if (RAW == ';') {
2396
      /* on purpose to avoid reentrancy problems with NEXT and SKIP */
2397
461k
      ctxt->input->col++;
2398
461k
      ctxt->input->cur++;
2399
461k
  }
2400
487k
    } else {
2401
0
        xmlFatalErr(ctxt, XML_ERR_INVALID_CHARREF, NULL);
2402
0
    }
2403
2404
    /*
2405
     * [ WFC: Legal Character ]
2406
     * Characters referred to using character references must match the
2407
     * production for Char.
2408
     */
2409
532k
    if (val >= 0x110000) {
2410
14.0k
        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
2411
14.0k
                "xmlParseCharRef: character reference out of bounds\n",
2412
14.0k
          val);
2413
518k
    } else if (IS_CHAR(val)) {
2414
477k
        return(val);
2415
477k
    } else {
2416
40.2k
        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
2417
40.2k
                          "xmlParseCharRef: invalid xmlChar value %d\n",
2418
40.2k
                    val);
2419
40.2k
    }
2420
54.3k
    return(0);
2421
532k
}
2422
2423
/**
2424
 * xmlParseStringCharRef:
2425
 * @ctxt:  an XML parser context
2426
 * @str:  a pointer to an index in the string
2427
 *
2428
 * parse Reference declarations, variant parsing from a string rather
2429
 * than an an input flow.
2430
 *
2431
 * [66] CharRef ::= '&#' [0-9]+ ';' |
2432
 *                  '&#x' [0-9a-fA-F]+ ';'
2433
 *
2434
 * [ WFC: Legal Character ]
2435
 * Characters referred to using character references must match the
2436
 * production for Char.
2437
 *
2438
 * Returns the value parsed (as an int), 0 in case of error, str will be
2439
 *         updated to the current value of the index
2440
 */
2441
static int
2442
34.2k
xmlParseStringCharRef(xmlParserCtxtPtr ctxt, const xmlChar **str) {
2443
34.2k
    const xmlChar *ptr;
2444
34.2k
    xmlChar cur;
2445
34.2k
    int val = 0;
2446
2447
34.2k
    if ((str == NULL) || (*str == NULL)) return(0);
2448
34.2k
    ptr = *str;
2449
34.2k
    cur = *ptr;
2450
34.2k
    if ((cur == '&') && (ptr[1] == '#') && (ptr[2] == 'x')) {
2451
15.3k
  ptr += 3;
2452
15.3k
  cur = *ptr;
2453
79.6k
  while (cur != ';') { /* Non input consuming loop */
2454
66.1k
      if ((cur >= '0') && (cur <= '9'))
2455
35.6k
          val = val * 16 + (cur - '0');
2456
30.5k
      else if ((cur >= 'a') && (cur <= 'f'))
2457
17.7k
          val = val * 16 + (cur - 'a') + 10;
2458
12.7k
      else if ((cur >= 'A') && (cur <= 'F'))
2459
10.8k
          val = val * 16 + (cur - 'A') + 10;
2460
1.94k
      else {
2461
1.94k
    xmlFatalErr(ctxt, XML_ERR_INVALID_HEX_CHARREF, NULL);
2462
1.94k
    val = 0;
2463
1.94k
    break;
2464
1.94k
      }
2465
64.2k
      if (val > 0x110000)
2466
3.23k
          val = 0x110000;
2467
2468
64.2k
      ptr++;
2469
64.2k
      cur = *ptr;
2470
64.2k
  }
2471
15.3k
  if (cur == ';')
2472
13.4k
      ptr++;
2473
18.8k
    } else if  ((cur == '&') && (ptr[1] == '#')){
2474
18.8k
  ptr += 2;
2475
18.8k
  cur = *ptr;
2476
48.1k
  while (cur != ';') { /* Non input consuming loops */
2477
33.5k
      if ((cur >= '0') && (cur <= '9'))
2478
29.3k
          val = val * 10 + (cur - '0');
2479
4.25k
      else {
2480
4.25k
    xmlFatalErr(ctxt, XML_ERR_INVALID_DEC_CHARREF, NULL);
2481
4.25k
    val = 0;
2482
4.25k
    break;
2483
4.25k
      }
2484
29.3k
      if (val > 0x110000)
2485
724
          val = 0x110000;
2486
2487
29.3k
      ptr++;
2488
29.3k
      cur = *ptr;
2489
29.3k
  }
2490
18.8k
  if (cur == ';')
2491
14.5k
      ptr++;
2492
18.8k
    } else {
2493
0
  xmlFatalErr(ctxt, XML_ERR_INVALID_CHARREF, NULL);
2494
0
  return(0);
2495
0
    }
2496
34.2k
    *str = ptr;
2497
2498
    /*
2499
     * [ WFC: Legal Character ]
2500
     * Characters referred to using character references must match the
2501
     * production for Char.
2502
     */
2503
34.2k
    if (val >= 0x110000) {
2504
291
        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
2505
291
                "xmlParseStringCharRef: character reference out of bounds\n",
2506
291
                val);
2507
33.9k
    } else if (IS_CHAR(val)) {
2508
25.8k
        return(val);
2509
25.8k
    } else {
2510
8.06k
        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
2511
8.06k
        "xmlParseStringCharRef: invalid xmlChar value %d\n",
2512
8.06k
        val);
2513
8.06k
    }
2514
8.35k
    return(0);
2515
34.2k
}
2516
2517
/**
2518
 * xmlParserHandlePEReference:
2519
 * @ctxt:  the parser context
2520
 *
2521
 * [69] PEReference ::= '%' Name ';'
2522
 *
2523
 * [ WFC: No Recursion ]
2524
 * A parsed entity must not contain a recursive
2525
 * reference to itself, either directly or indirectly.
2526
 *
2527
 * [ WFC: Entity Declared ]
2528
 * In a document without any DTD, a document with only an internal DTD
2529
 * subset which contains no parameter entity references, or a document
2530
 * with "standalone='yes'", ...  ... The declaration of a parameter
2531
 * entity must precede any reference to it...
2532
 *
2533
 * [ VC: Entity Declared ]
2534
 * In a document with an external subset or external parameter entities
2535
 * with "standalone='no'", ...  ... The declaration of a parameter entity
2536
 * must precede any reference to it...
2537
 *
2538
 * [ WFC: In DTD ]
2539
 * Parameter-entity references may only appear in the DTD.
2540
 * NOTE: misleading but this is handled.
2541
 *
2542
 * A PEReference may have been detected in the current input stream
2543
 * the handling is done accordingly to
2544
 *      http://www.w3.org/TR/REC-xml#entproc
2545
 * i.e.
2546
 *   - Included in literal in entity values
2547
 *   - Included as Parameter Entity reference within DTDs
2548
 */
2549
void
2550
0
xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) {
2551
0
    switch(ctxt->instate) {
2552
0
  case XML_PARSER_CDATA_SECTION:
2553
0
      return;
2554
0
        case XML_PARSER_COMMENT:
2555
0
      return;
2556
0
  case XML_PARSER_START_TAG:
2557
0
      return;
2558
0
  case XML_PARSER_END_TAG:
2559
0
      return;
2560
0
        case XML_PARSER_EOF:
2561
0
      xmlFatalErr(ctxt, XML_ERR_PEREF_AT_EOF, NULL);
2562
0
      return;
2563
0
        case XML_PARSER_PROLOG:
2564
0
  case XML_PARSER_START:
2565
0
  case XML_PARSER_MISC:
2566
0
      xmlFatalErr(ctxt, XML_ERR_PEREF_IN_PROLOG, NULL);
2567
0
      return;
2568
0
  case XML_PARSER_ENTITY_DECL:
2569
0
        case XML_PARSER_CONTENT:
2570
0
        case XML_PARSER_ATTRIBUTE_VALUE:
2571
0
        case XML_PARSER_PI:
2572
0
  case XML_PARSER_SYSTEM_LITERAL:
2573
0
  case XML_PARSER_PUBLIC_LITERAL:
2574
      /* we just ignore it there */
2575
0
      return;
2576
0
        case XML_PARSER_EPILOG:
2577
0
      xmlFatalErr(ctxt, XML_ERR_PEREF_IN_EPILOG, NULL);
2578
0
      return;
2579
0
  case XML_PARSER_ENTITY_VALUE:
2580
      /*
2581
       * NOTE: in the case of entity values, we don't do the
2582
       *       substitution here since we need the literal
2583
       *       entity value to be able to save the internal
2584
       *       subset of the document.
2585
       *       This will be handled by xmlStringDecodeEntities
2586
       */
2587
0
      return;
2588
0
        case XML_PARSER_DTD:
2589
      /*
2590
       * [WFC: Well-Formedness Constraint: PEs in Internal Subset]
2591
       * In the internal DTD subset, parameter-entity references
2592
       * can occur only where markup declarations can occur, not
2593
       * within markup declarations.
2594
       * In that case this is handled in xmlParseMarkupDecl
2595
       */
2596
0
      if ((ctxt->external == 0) && (ctxt->inputNr == 1))
2597
0
    return;
2598
0
      if (IS_BLANK_CH(NXT(1)) || NXT(1) == 0)
2599
0
    return;
2600
0
            break;
2601
0
        case XML_PARSER_IGNORE:
2602
0
            return;
2603
0
    }
2604
2605
0
    xmlParsePEReference(ctxt);
2606
0
}
2607
2608
/*
2609
 * Macro used to grow the current buffer.
2610
 * buffer##_size is expected to be a size_t
2611
 * mem_error: is expected to handle memory allocation failures
2612
 */
2613
175k
#define growBuffer(buffer, n) {           \
2614
175k
    xmlChar *tmp;             \
2615
175k
    size_t new_size = buffer##_size * 2 + n;                            \
2616
175k
    if (new_size < buffer##_size) goto mem_error;                       \
2617
175k
    tmp = (xmlChar *) xmlRealloc(buffer, new_size);                     \
2618
175k
    if (tmp == NULL) goto mem_error;         \
2619
175k
    buffer = tmp;             \
2620
175k
    buffer##_size = new_size;                                           \
2621
175k
}
2622
2623
/**
2624
 * xmlStringLenDecodeEntities:
2625
 * @ctxt:  the parser context
2626
 * @str:  the input string
2627
 * @len: the string length
2628
 * @what:  combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
2629
 * @end:  an end marker xmlChar, 0 if none
2630
 * @end2:  an end marker xmlChar, 0 if none
2631
 * @end3:  an end marker xmlChar, 0 if none
2632
 *
2633
 * Takes a entity string content and process to do the adequate substitutions.
2634
 *
2635
 * [67] Reference ::= EntityRef | CharRef
2636
 *
2637
 * [69] PEReference ::= '%' Name ';'
2638
 *
2639
 * Returns A newly allocated string with the substitution done. The caller
2640
 *      must deallocate it !
2641
 */
2642
xmlChar *
2643
xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
2644
1.80M
          int what, xmlChar end, xmlChar  end2, xmlChar end3) {
2645
1.80M
    xmlChar *buffer = NULL;
2646
1.80M
    size_t buffer_size = 0;
2647
1.80M
    size_t nbchars = 0;
2648
2649
1.80M
    xmlChar *current = NULL;
2650
1.80M
    xmlChar *rep = NULL;
2651
1.80M
    const xmlChar *last;
2652
1.80M
    xmlEntityPtr ent;
2653
1.80M
    int c,l;
2654
2655
1.80M
    if ((ctxt == NULL) || (str == NULL) || (len < 0))
2656
0
  return(NULL);
2657
1.80M
    last = str + len;
2658
2659
1.80M
    if (((ctxt->depth > 40) &&
2660
1.80M
         ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
2661
1.80M
  (ctxt->depth > 1024)) {
2662
161
  xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
2663
161
  return(NULL);
2664
161
    }
2665
2666
    /*
2667
     * allocate a translation buffer.
2668
     */
2669
1.80M
    buffer_size = XML_PARSER_BIG_BUFFER_SIZE;
2670
1.80M
    buffer = (xmlChar *) xmlMallocAtomic(buffer_size);
2671
1.80M
    if (buffer == NULL) goto mem_error;
2672
2673
    /*
2674
     * OK loop until we reach one of the ending char or a size limit.
2675
     * we are operating on already parsed values.
2676
     */
2677
1.80M
    if (str < last)
2678
302k
  c = CUR_SCHAR(str, l);
2679
1.50M
    else
2680
1.50M
        c = 0;
2681
923M
    while ((c != 0) && (c != end) && /* non input consuming loop */
2682
923M
           (c != end2) && (c != end3) &&
2683
923M
           (ctxt->instate != XML_PARSER_EOF)) {
2684
2685
922M
  if (c == 0) break;
2686
922M
        if ((c == '&') && (str[1] == '#')) {
2687
34.2k
      int val = xmlParseStringCharRef(ctxt, &str);
2688
34.2k
      if (val == 0)
2689
8.35k
                goto int_error;
2690
25.8k
      COPY_BUF(0,buffer,nbchars,val);
2691
25.8k
      if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
2692
2.98k
          growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2693
2.98k
      }
2694
922M
  } else if ((c == '&') && (what & XML_SUBSTITUTE_REF)) {
2695
2.01M
      if (xmlParserDebugEntities)
2696
0
    xmlGenericError(xmlGenericErrorContext,
2697
0
      "String decoding Entity Reference: %.30s\n",
2698
0
      str);
2699
2.01M
      ent = xmlParseStringEntityRef(ctxt, &str);
2700
2.01M
      xmlParserEntityCheck(ctxt, 0, ent, 0);
2701
2.01M
      if (ent != NULL)
2702
1.77M
          ctxt->nbentities += ent->checked / 2;
2703
2.01M
      if ((ent != NULL) &&
2704
2.01M
    (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
2705
15.2k
    if (ent->content != NULL) {
2706
15.2k
        COPY_BUF(0,buffer,nbchars,ent->content[0]);
2707
15.2k
        if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
2708
2.18k
      growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2709
2.18k
        }
2710
15.2k
    } else {
2711
0
        xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
2712
0
          "predefined entity has no content\n");
2713
0
                    goto int_error;
2714
0
    }
2715
1.99M
      } else if ((ent != NULL) && (ent->content != NULL)) {
2716
1.75M
    ctxt->depth++;
2717
1.75M
    rep = xmlStringDecodeEntities(ctxt, ent->content, what,
2718
1.75M
                            0, 0, 0);
2719
1.75M
    ctxt->depth--;
2720
1.75M
    if (rep == NULL) {
2721
147k
                    ent->content[0] = 0;
2722
147k
                    goto int_error;
2723
147k
                }
2724
2725
1.61M
                current = rep;
2726
1.11G
                while (*current != 0) { /* non input consuming loop */
2727
1.11G
                    buffer[nbchars++] = *current++;
2728
1.11G
                    if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
2729
32.4k
                        if (xmlParserEntityCheck(ctxt, nbchars, ent, 0))
2730
0
                            goto int_error;
2731
97.3k
                        growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2732
97.3k
                    }
2733
1.11G
                }
2734
1.61M
                xmlFree(rep);
2735
1.61M
                rep = NULL;
2736
1.61M
      } else if (ent != NULL) {
2737
3.51k
    int i = xmlStrlen(ent->name);
2738
3.51k
    const xmlChar *cur = ent->name;
2739
2740
3.51k
    buffer[nbchars++] = '&';
2741
3.51k
    if (nbchars + i + XML_PARSER_BUFFER_SIZE > buffer_size) {
2742
2.07k
        growBuffer(buffer, i + XML_PARSER_BUFFER_SIZE);
2743
2.07k
    }
2744
10.1k
    for (;i > 0;i--)
2745
6.65k
        buffer[nbchars++] = *cur++;
2746
3.51k
    buffer[nbchars++] = ';';
2747
3.51k
      }
2748
920M
  } else if (c == '%' && (what & XML_SUBSTITUTE_PEREF)) {
2749
37.8k
      if (xmlParserDebugEntities)
2750
0
    xmlGenericError(xmlGenericErrorContext,
2751
0
      "String decoding PE Reference: %.30s\n", str);
2752
37.8k
      ent = xmlParseStringPEReference(ctxt, &str);
2753
37.8k
      xmlParserEntityCheck(ctxt, 0, ent, 0);
2754
37.8k
      if (ent != NULL)
2755
14.8k
          ctxt->nbentities += ent->checked / 2;
2756
37.8k
      if (ent != NULL) {
2757
14.8k
                if (ent->content == NULL) {
2758
        /*
2759
         * Note: external parsed entities will not be loaded,
2760
         * it is not required for a non-validating parser to
2761
         * complete external PEReferences coming from the
2762
         * internal subset
2763
         */
2764
10
        if (((ctxt->options & XML_PARSE_NOENT) != 0) ||
2765
10
      ((ctxt->options & XML_PARSE_DTDVALID) != 0) ||
2766
10
      (ctxt->validate != 0)) {
2767
0
      xmlLoadEntityContent(ctxt, ent);
2768
10
        } else {
2769
10
      xmlWarningMsg(ctxt, XML_ERR_ENTITY_PROCESSING,
2770
10
      "not validating will not read content for PE entity %s\n",
2771
10
                          ent->name, NULL);
2772
10
        }
2773
10
    }
2774
14.8k
    ctxt->depth++;
2775
14.8k
    rep = xmlStringDecodeEntities(ctxt, ent->content, what,
2776
14.8k
                            0, 0, 0);
2777
14.8k
    ctxt->depth--;
2778
14.8k
    if (rep == NULL) {
2779
11.2k
                    if (ent->content != NULL)
2780
11.2k
                        ent->content[0] = 0;
2781
11.2k
                    goto int_error;
2782
11.2k
                }
2783
3.53k
                current = rep;
2784
7.23M
                while (*current != 0) { /* non input consuming loop */
2785
7.22M
                    buffer[nbchars++] = *current++;
2786
7.22M
                    if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
2787
1.23k
                        if (xmlParserEntityCheck(ctxt, nbchars, ent, 0))
2788
0
                            goto int_error;
2789
3.70k
                        growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2790
3.70k
                    }
2791
7.22M
                }
2792
3.53k
                xmlFree(rep);
2793
3.53k
                rep = NULL;
2794
3.53k
      }
2795
920M
  } else {
2796
920M
      COPY_BUF(l,buffer,nbchars,c);
2797
920M
      str += l;
2798
920M
      if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
2799
213k
          growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2800
213k
      }
2801
920M
  }
2802
922M
  if (str < last)
2803
921M
      c = CUR_SCHAR(str, l);
2804
135k
  else
2805
135k
      c = 0;
2806
922M
    }
2807
1.63M
    buffer[nbchars] = 0;
2808
1.63M
    return(buffer);
2809
2810
0
mem_error:
2811
0
    xmlErrMemory(ctxt, NULL);
2812
166k
int_error:
2813
166k
    if (rep != NULL)
2814
0
        xmlFree(rep);
2815
166k
    if (buffer != NULL)
2816
166k
        xmlFree(buffer);
2817
166k
    return(NULL);
2818
0
}
2819
2820
/**
2821
 * xmlStringDecodeEntities:
2822
 * @ctxt:  the parser context
2823
 * @str:  the input string
2824
 * @what:  combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
2825
 * @end:  an end marker xmlChar, 0 if none
2826
 * @end2:  an end marker xmlChar, 0 if none
2827
 * @end3:  an end marker xmlChar, 0 if none
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
1.80M
            xmlChar end, xmlChar  end2, xmlChar end3) {
2841
1.80M
    if ((ctxt == NULL) || (str == NULL)) return(NULL);
2842
1.80M
    return(xmlStringLenDecodeEntities(ctxt, str, xmlStrlen(str), what,
2843
1.80M
           end, end2, end3));
2844
1.80M
}
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.84M
                     int blank_chars) {
2866
1.84M
    int i, ret;
2867
1.84M
    xmlNodePtr lastChild;
2868
2869
    /*
2870
     * Don't spend time trying to differentiate them, the same callback is
2871
     * used !
2872
     */
2873
1.84M
    if (ctxt->sax->ignorableWhitespace == ctxt->sax->characters)
2874
1.84M
  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
29.7k
xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) {
2947
29.7k
    xmlChar buf[XML_MAX_NAMELEN + 5];
2948
29.7k
    xmlChar *buffer = NULL;
2949
29.7k
    int len = 0;
2950
29.7k
    int max = XML_MAX_NAMELEN;
2951
29.7k
    xmlChar *ret = NULL;
2952
29.7k
    const xmlChar *cur = name;
2953
29.7k
    int c;
2954
2955
29.7k
    if (prefix == NULL) return(NULL);
2956
29.7k
    *prefix = NULL;
2957
2958
29.7k
    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
29.7k
    if (cur[0] == ':')
2969
690
  return(xmlStrdup(name));
2970
2971
29.0k
    c = *cur++;
2972
759k
    while ((c != 0) && (c != ':') && (len < max)) { /* tested bigname.xml */
2973
730k
  buf[len++] = c;
2974
730k
  c = *cur++;
2975
730k
    }
2976
29.0k
    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
4.59k
  max = len * 2;
2982
2983
4.59k
  buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
2984
4.59k
  if (buffer == NULL) {
2985
0
      xmlErrMemory(ctxt, NULL);
2986
0
      return(NULL);
2987
0
  }
2988
4.59k
  memcpy(buffer, buf, len);
2989
1.47M
  while ((c != 0) && (c != ':')) { /* tested bigname.xml */
2990
1.47M
      if (len + 10 > max) {
2991
4.64k
          xmlChar *tmp;
2992
2993
4.64k
    max *= 2;
2994
4.64k
    tmp = (xmlChar *) xmlRealloc(buffer,
2995
4.64k
            max * sizeof(xmlChar));
2996
4.64k
    if (tmp == NULL) {
2997
0
        xmlFree(buffer);
2998
0
        xmlErrMemory(ctxt, NULL);
2999
0
        return(NULL);
3000
0
    }
3001
4.64k
    buffer = tmp;
3002
4.64k
      }
3003
1.47M
      buffer[len++] = c;
3004
1.47M
      c = *cur++;
3005
1.47M
  }
3006
4.59k
  buffer[len] = 0;
3007
4.59k
    }
3008
3009
29.0k
    if ((c == ':') && (*cur == 0)) {
3010
1.10k
        if (buffer != NULL)
3011
278
      xmlFree(buffer);
3012
1.10k
  *prefix = NULL;
3013
1.10k
  return(xmlStrdup(name));
3014
1.10k
    }
3015
3016
27.9k
    if (buffer == NULL)
3017
23.6k
  ret = xmlStrndup(buf, len);
3018
4.31k
    else {
3019
4.31k
  ret = buffer;
3020
4.31k
  buffer = NULL;
3021
4.31k
  max = XML_MAX_NAMELEN;
3022
4.31k
    }
3023
3024
3025
27.9k
    if (c == ':') {
3026
8.83k
  c = *cur;
3027
8.83k
        *prefix = ret;
3028
8.83k
  if (c == 0) {
3029
0
      return(xmlStrndup(BAD_CAST "", 0));
3030
0
  }
3031
8.83k
  len = 0;
3032
3033
  /*
3034
   * Check that the first character is proper to start
3035
   * a new name
3036
   */
3037
8.83k
  if (!(((c >= 0x61) && (c <= 0x7A)) ||
3038
8.83k
        ((c >= 0x41) && (c <= 0x5A)) ||
3039
8.83k
        (c == '_') || (c == ':'))) {
3040
1.95k
      int l;
3041
1.95k
      int first = CUR_SCHAR(cur, l);
3042
3043
1.95k
      if (!IS_LETTER(first) && (first != '_')) {
3044
31
    xmlFatalErrMsgStr(ctxt, XML_NS_ERR_QNAME,
3045
31
          "Name %s is not XML Namespace compliant\n",
3046
31
          name);
3047
31
      }
3048
1.95k
  }
3049
8.83k
  cur++;
3050
3051
502k
  while ((c != 0) && (len < max)) { /* tested bigname2.xml */
3052
493k
      buf[len++] = c;
3053
493k
      c = *cur++;
3054
493k
  }
3055
8.83k
  if (len >= max) {
3056
      /*
3057
       * Okay someone managed to make a huge name, so he's ready to pay
3058
       * for the processing speed.
3059
       */
3060
4.40k
      max = len * 2;
3061
3062
4.40k
      buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
3063
4.40k
      if (buffer == NULL) {
3064
0
          xmlErrMemory(ctxt, NULL);
3065
0
    return(NULL);
3066
0
      }
3067
4.40k
      memcpy(buffer, buf, len);
3068
25.7M
      while (c != 0) { /* tested bigname2.xml */
3069
25.7M
    if (len + 10 > max) {
3070
5.09k
        xmlChar *tmp;
3071
3072
5.09k
        max *= 2;
3073
5.09k
        tmp = (xmlChar *) xmlRealloc(buffer,
3074
5.09k
                max * sizeof(xmlChar));
3075
5.09k
        if (tmp == NULL) {
3076
0
      xmlErrMemory(ctxt, NULL);
3077
0
      xmlFree(buffer);
3078
0
      return(NULL);
3079
0
        }
3080
5.09k
        buffer = tmp;
3081
5.09k
    }
3082
25.7M
    buffer[len++] = c;
3083
25.7M
    c = *cur++;
3084
25.7M
      }
3085
4.40k
      buffer[len] = 0;
3086
4.40k
  }
3087
3088
8.83k
  if (buffer == NULL)
3089
4.42k
      ret = xmlStrndup(buf, len);
3090
4.40k
  else {
3091
4.40k
      ret = buffer;
3092
4.40k
  }
3093
8.83k
    }
3094
3095
27.9k
    return(ret);
3096
27.9k
}
3097
3098
/************************************************************************
3099
 *                  *
3100
 *      The parser itself       *
3101
 *  Relates to http://www.w3.org/TR/REC-xml       *
3102
 *                  *
3103
 ************************************************************************/
3104
3105
/************************************************************************
3106
 *                  *
3107
 *  Routines to parse Name, NCName and NmToken      *
3108
 *                  *
3109
 ************************************************************************/
3110
#ifdef DEBUG
3111
static unsigned long nbParseName = 0;
3112
static unsigned long nbParseNmToken = 0;
3113
static unsigned long nbParseNCName = 0;
3114
static unsigned long nbParseNCNameComplex = 0;
3115
static unsigned long nbParseNameComplex = 0;
3116
static unsigned long nbParseStringName = 0;
3117
#endif
3118
3119
/*
3120
 * The two following functions are related to the change of accepted
3121
 * characters for Name and NmToken in the Revision 5 of XML-1.0
3122
 * They correspond to the modified production [4] and the new production [4a]
3123
 * changes in that revision. Also note that the macros used for the
3124
 * productions Letter, Digit, CombiningChar and Extender are not needed
3125
 * anymore.
3126
 * We still keep compatibility to pre-revision5 parsing semantic if the
3127
 * new XML_PARSE_OLD10 option is given to the parser.
3128
 */
3129
static int
3130
2.43M
xmlIsNameStartChar(xmlParserCtxtPtr ctxt, int c) {
3131
2.43M
    if ((ctxt->options & XML_PARSE_OLD10) == 0) {
3132
        /*
3133
   * Use the new checks of production [4] [4a] amd [5] of the
3134
   * Update 5 of XML-1.0
3135
   */
3136
2.43M
  if ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
3137
2.43M
      (((c >= 'a') && (c <= 'z')) ||
3138
2.43M
       ((c >= 'A') && (c <= 'Z')) ||
3139
2.43M
       (c == '_') || (c == ':') ||
3140
2.43M
       ((c >= 0xC0) && (c <= 0xD6)) ||
3141
2.43M
       ((c >= 0xD8) && (c <= 0xF6)) ||
3142
2.43M
       ((c >= 0xF8) && (c <= 0x2FF)) ||
3143
2.43M
       ((c >= 0x370) && (c <= 0x37D)) ||
3144
2.43M
       ((c >= 0x37F) && (c <= 0x1FFF)) ||
3145
2.43M
       ((c >= 0x200C) && (c <= 0x200D)) ||
3146
2.43M
       ((c >= 0x2070) && (c <= 0x218F)) ||
3147
2.43M
       ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3148
2.43M
       ((c >= 0x3001) && (c <= 0xD7FF)) ||
3149
2.43M
       ((c >= 0xF900) && (c <= 0xFDCF)) ||
3150
2.43M
       ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3151
2.43M
       ((c >= 0x10000) && (c <= 0xEFFFF))))
3152
2.14M
      return(1);
3153
2.43M
    } else {
3154
0
        if (IS_LETTER(c) || (c == '_') || (c == ':'))
3155
0
      return(1);
3156
0
    }
3157
296k
    return(0);
3158
2.43M
}
3159
3160
static int
3161
139M
xmlIsNameChar(xmlParserCtxtPtr ctxt, int c) {
3162
139M
    if ((ctxt->options & XML_PARSE_OLD10) == 0) {
3163
        /*
3164
   * Use the new checks of production [4] [4a] amd [5] of the
3165
   * Update 5 of XML-1.0
3166
   */
3167
139M
  if ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
3168
139M
      (((c >= 'a') && (c <= 'z')) ||
3169
139M
       ((c >= 'A') && (c <= 'Z')) ||
3170
139M
       ((c >= '0') && (c <= '9')) || /* !start */
3171
139M
       (c == '_') || (c == ':') ||
3172
139M
       (c == '-') || (c == '.') || (c == 0xB7) || /* !start */
3173
139M
       ((c >= 0xC0) && (c <= 0xD6)) ||
3174
139M
       ((c >= 0xD8) && (c <= 0xF6)) ||
3175
139M
       ((c >= 0xF8) && (c <= 0x2FF)) ||
3176
139M
       ((c >= 0x300) && (c <= 0x36F)) || /* !start */
3177
139M
       ((c >= 0x370) && (c <= 0x37D)) ||
3178
139M
       ((c >= 0x37F) && (c <= 0x1FFF)) ||
3179
139M
       ((c >= 0x200C) && (c <= 0x200D)) ||
3180
139M
       ((c >= 0x203F) && (c <= 0x2040)) || /* !start */
3181
139M
       ((c >= 0x2070) && (c <= 0x218F)) ||
3182
139M
       ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3183
139M
       ((c >= 0x3001) && (c <= 0xD7FF)) ||
3184
139M
       ((c >= 0xF900) && (c <= 0xFDCF)) ||
3185
139M
       ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3186
139M
       ((c >= 0x10000) && (c <= 0xEFFFF))))
3187
137M
       return(1);
3188
139M
    } else {
3189
0
        if ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
3190
0
            (c == '.') || (c == '-') ||
3191
0
      (c == '_') || (c == ':') ||
3192
0
      (IS_COMBINING(c)) ||
3193
0
      (IS_EXTENDER(c)))
3194
0
      return(1);
3195
0
    }
3196
2.16M
    return(0);
3197
139M
}
3198
3199
static xmlChar * xmlParseAttValueInternal(xmlParserCtxtPtr ctxt,
3200
                                          int *len, int *alloc, int normalize);
3201
3202
static const xmlChar *
3203
3.76M
xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
3204
3.76M
    int len = 0, l;
3205
3.76M
    int c;
3206
3.76M
    int count = 0;
3207
3208
#ifdef DEBUG
3209
    nbParseNameComplex++;
3210
#endif
3211
3212
    /*
3213
     * Handler for more complex cases
3214
     */
3215
3.76M
    GROW;
3216
3.76M
    if (ctxt->instate == XML_PARSER_EOF)
3217
0
        return(NULL);
3218
3.76M
    c = CUR_CHAR(l);
3219
3.76M
    if ((ctxt->options & XML_PARSE_OLD10) == 0) {
3220
        /*
3221
   * Use the new checks of production [4] [4a] amd [5] of the
3222
   * Update 5 of XML-1.0
3223
   */
3224
3.76M
  if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
3225
3.76M
      (!(((c >= 'a') && (c <= 'z')) ||
3226
3.76M
         ((c >= 'A') && (c <= 'Z')) ||
3227
3.76M
         (c == '_') || (c == ':') ||
3228
3.76M
         ((c >= 0xC0) && (c <= 0xD6)) ||
3229
3.76M
         ((c >= 0xD8) && (c <= 0xF6)) ||
3230
3.76M
         ((c >= 0xF8) && (c <= 0x2FF)) ||
3231
3.76M
         ((c >= 0x370) && (c <= 0x37D)) ||
3232
3.76M
         ((c >= 0x37F) && (c <= 0x1FFF)) ||
3233
3.76M
         ((c >= 0x200C) && (c <= 0x200D)) ||
3234
3.76M
         ((c >= 0x2070) && (c <= 0x218F)) ||
3235
3.76M
         ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3236
3.76M
         ((c >= 0x3001) && (c <= 0xD7FF)) ||
3237
3.76M
         ((c >= 0xF900) && (c <= 0xFDCF)) ||
3238
3.76M
         ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3239
3.76M
         ((c >= 0x10000) && (c <= 0xEFFFF))))) {
3240
3.32M
      return(NULL);
3241
3.32M
  }
3242
449k
  len += l;
3243
449k
  NEXTL(l);
3244
449k
  c = CUR_CHAR(l);
3245
63.7M
  while ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
3246
63.7M
         (((c >= 'a') && (c <= 'z')) ||
3247
63.6M
          ((c >= 'A') && (c <= 'Z')) ||
3248
63.6M
          ((c >= '0') && (c <= '9')) || /* !start */
3249
63.6M
          (c == '_') || (c == ':') ||
3250
63.6M
          (c == '-') || (c == '.') || (c == 0xB7) || /* !start */
3251
63.6M
          ((c >= 0xC0) && (c <= 0xD6)) ||
3252
63.6M
          ((c >= 0xD8) && (c <= 0xF6)) ||
3253
63.6M
          ((c >= 0xF8) && (c <= 0x2FF)) ||
3254
63.6M
          ((c >= 0x300) && (c <= 0x36F)) || /* !start */
3255
63.6M
          ((c >= 0x370) && (c <= 0x37D)) ||
3256
63.6M
          ((c >= 0x37F) && (c <= 0x1FFF)) ||
3257
63.6M
          ((c >= 0x200C) && (c <= 0x200D)) ||
3258
63.6M
          ((c >= 0x203F) && (c <= 0x2040)) || /* !start */
3259
63.6M
          ((c >= 0x2070) && (c <= 0x218F)) ||
3260
63.6M
          ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3261
63.6M
          ((c >= 0x3001) && (c <= 0xD7FF)) ||
3262
63.6M
          ((c >= 0xF900) && (c <= 0xFDCF)) ||
3263
63.6M
          ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3264
63.6M
          ((c >= 0x10000) && (c <= 0xEFFFF))
3265
63.6M
    )) {
3266
63.2M
      if (count++ > XML_PARSER_CHUNK_SIZE) {
3267
552k
    count = 0;
3268
552k
    GROW;
3269
552k
                if (ctxt->instate == XML_PARSER_EOF)
3270
0
                    return(NULL);
3271
552k
      }
3272
63.2M
      len += l;
3273
63.2M
      NEXTL(l);
3274
63.2M
      c = CUR_CHAR(l);
3275
63.2M
  }
3276
449k
    } else {
3277
0
  if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
3278
0
      (!IS_LETTER(c) && (c != '_') &&
3279
0
       (c != ':'))) {
3280
0
      return(NULL);
3281
0
  }
3282
0
  len += l;
3283
0
  NEXTL(l);
3284
0
  c = CUR_CHAR(l);
3285
3286
0
  while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
3287
0
         ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
3288
0
    (c == '.') || (c == '-') ||
3289
0
    (c == '_') || (c == ':') ||
3290
0
    (IS_COMBINING(c)) ||
3291
0
    (IS_EXTENDER(c)))) {
3292
0
      if (count++ > XML_PARSER_CHUNK_SIZE) {
3293
0
    count = 0;
3294
0
    GROW;
3295
0
                if (ctxt->instate == XML_PARSER_EOF)
3296
0
                    return(NULL);
3297
0
      }
3298
0
      len += l;
3299
0
      NEXTL(l);
3300
0
      c = CUR_CHAR(l);
3301
0
  }
3302
0
    }
3303
449k
    if ((len > XML_MAX_NAME_LENGTH) &&
3304
449k
        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3305
0
        xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name");
3306
0
        return(NULL);
3307
0
    }
3308
449k
    if (ctxt->input->cur - ctxt->input->base < len) {
3309
        /*
3310
         * There were a couple of bugs where PERefs lead to to a change
3311
         * of the buffer. Check the buffer size to avoid passing an invalid
3312
         * pointer to xmlDictLookup.
3313
         */
3314
0
        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
3315
0
                    "unexpected change of input buffer");
3316
0
        return (NULL);
3317
0
    }
3318
449k
    if ((*ctxt->input->cur == '\n') && (ctxt->input->cur[-1] == '\r'))
3319
519
        return(xmlDictLookup(ctxt->dict, ctxt->input->cur - (len + 1), len));
3320
448k
    return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
3321
449k
}
3322
3323
/**
3324
 * xmlParseName:
3325
 * @ctxt:  an XML parser context
3326
 *
3327
 * parse an XML name.
3328
 *
3329
 * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
3330
 *                  CombiningChar | Extender
3331
 *
3332
 * [5] Name ::= (Letter | '_' | ':') (NameChar)*
3333
 *
3334
 * [6] Names ::= Name (#x20 Name)*
3335
 *
3336
 * Returns the Name parsed or NULL
3337
 */
3338
3339
const xmlChar *
3340
15.7M
xmlParseName(xmlParserCtxtPtr ctxt) {
3341
15.7M
    const xmlChar *in;
3342
15.7M
    const xmlChar *ret;
3343
15.7M
    int count = 0;
3344
3345
15.7M
    GROW;
3346
3347
#ifdef DEBUG
3348
    nbParseName++;
3349
#endif
3350
3351
    /*
3352
     * Accelerator for simple ASCII names
3353
     */
3354
15.7M
    in = ctxt->input->cur;
3355
15.7M
    if (((*in >= 0x61) && (*in <= 0x7A)) ||
3356
15.7M
  ((*in >= 0x41) && (*in <= 0x5A)) ||
3357
15.7M
  (*in == '_') || (*in == ':')) {
3358
12.1M
  in++;
3359
29.4M
  while (((*in >= 0x61) && (*in <= 0x7A)) ||
3360
29.4M
         ((*in >= 0x41) && (*in <= 0x5A)) ||
3361
29.4M
         ((*in >= 0x30) && (*in <= 0x39)) ||
3362
29.4M
         (*in == '_') || (*in == '-') ||
3363
29.4M
         (*in == ':') || (*in == '.'))
3364
17.3M
      in++;
3365
12.1M
  if ((*in > 0) && (*in < 0x80)) {
3366
11.9M
      count = in - ctxt->input->cur;
3367
11.9M
            if ((count > XML_MAX_NAME_LENGTH) &&
3368
11.9M
                ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3369
0
                xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name");
3370
0
                return(NULL);
3371
0
            }
3372
11.9M
      ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
3373
11.9M
      ctxt->input->cur = in;
3374
11.9M
      ctxt->input->col += count;
3375
11.9M
      if (ret == NULL)
3376
0
          xmlErrMemory(ctxt, NULL);
3377
11.9M
      return(ret);
3378
11.9M
  }
3379
12.1M
    }
3380
    /* accelerator for special cases */
3381
3.76M
    return(xmlParseNameComplex(ctxt));
3382
15.7M
}
3383
3384
static const xmlChar *
3385
379k
xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
3386
379k
    int len = 0, l;
3387
379k
    int c;
3388
379k
    int count = 0;
3389
379k
    size_t startPosition = 0;
3390
3391
#ifdef DEBUG
3392
    nbParseNCNameComplex++;
3393
#endif
3394
3395
    /*
3396
     * Handler for more complex cases
3397
     */
3398
379k
    GROW;
3399
379k
    startPosition = CUR_PTR - BASE_PTR;
3400
379k
    c = CUR_CHAR(l);
3401
379k
    if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
3402
379k
  (!xmlIsNameStartChar(ctxt, c) || (c == ':'))) {
3403
312k
  return(NULL);
3404
312k
    }
3405
3406
45.8M
    while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
3407
45.8M
     (xmlIsNameChar(ctxt, c) && (c != ':'))) {
3408
45.8M
  if (count++ > XML_PARSER_CHUNK_SIZE) {
3409
442k
            if ((len > XML_MAX_NAME_LENGTH) &&
3410
442k
                ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3411
0
                xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
3412
0
                return(NULL);
3413
0
            }
3414
442k
      count = 0;
3415
442k
      GROW;
3416
442k
            if (ctxt->instate == XML_PARSER_EOF)
3417
0
                return(NULL);
3418
442k
  }
3419
45.8M
  len += l;
3420
45.8M
  NEXTL(l);
3421
45.8M
  c = CUR_CHAR(l);
3422
45.8M
  if (c == 0) {
3423
3.03k
      count = 0;
3424
      /*
3425
       * when shrinking to extend the buffer we really need to preserve
3426
       * the part of the name we already parsed. Hence rolling back
3427
       * by current length.
3428
       */
3429
3.03k
      ctxt->input->cur -= l;
3430
3.03k
      GROW;
3431
3.03k
            if (ctxt->instate == XML_PARSER_EOF)
3432
0
                return(NULL);
3433
3.03k
      ctxt->input->cur += l;
3434
3.03k
      c = CUR_CHAR(l);
3435
3.03k
  }
3436
45.8M
    }
3437
67.5k
    if ((len > XML_MAX_NAME_LENGTH) &&
3438
67.5k
        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3439
0
        xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
3440
0
        return(NULL);
3441
0
    }
3442
67.5k
    return(xmlDictLookup(ctxt->dict, (BASE_PTR + startPosition), len));
3443
67.5k
}
3444
3445
/**
3446
 * xmlParseNCName:
3447
 * @ctxt:  an XML parser context
3448
 * @len:  length of the string parsed
3449
 *
3450
 * parse an XML name.
3451
 *
3452
 * [4NS] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
3453
 *                      CombiningChar | Extender
3454
 *
3455
 * [5NS] NCName ::= (Letter | '_') (NCNameChar)*
3456
 *
3457
 * Returns the Name parsed or NULL
3458
 */
3459
3460
static const xmlChar *
3461
6.40M
xmlParseNCName(xmlParserCtxtPtr ctxt) {
3462
6.40M
    const xmlChar *in, *e;
3463
6.40M
    const xmlChar *ret;
3464
6.40M
    int count = 0;
3465
3466
#ifdef DEBUG
3467
    nbParseNCName++;
3468
#endif
3469
3470
    /*
3471
     * Accelerator for simple ASCII names
3472
     */
3473
6.40M
    in = ctxt->input->cur;
3474
6.40M
    e = ctxt->input->end;
3475
6.40M
    if ((((*in >= 0x61) && (*in <= 0x7A)) ||
3476
6.40M
   ((*in >= 0x41) && (*in <= 0x5A)) ||
3477
6.40M
   (*in == '_')) && (in < e)) {
3478
6.06M
  in++;
3479
43.8M
  while ((((*in >= 0x61) && (*in <= 0x7A)) ||
3480
43.8M
          ((*in >= 0x41) && (*in <= 0x5A)) ||
3481
43.8M
          ((*in >= 0x30) && (*in <= 0x39)) ||
3482
43.8M
          (*in == '_') || (*in == '-') ||
3483
43.8M
          (*in == '.')) && (in < e))
3484
37.8M
      in++;
3485
6.06M
  if (in >= e)
3486
3.33k
      goto complex;
3487
6.05M
  if ((*in > 0) && (*in < 0x80)) {
3488
6.02M
      count = in - ctxt->input->cur;
3489
6.02M
            if ((count > XML_MAX_NAME_LENGTH) &&
3490
6.02M
                ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3491
0
                xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
3492
0
                return(NULL);
3493
0
            }
3494
6.02M
      ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
3495
6.02M
      ctxt->input->cur = in;
3496
6.02M
      ctxt->input->col += count;
3497
6.02M
      if (ret == NULL) {
3498
0
          xmlErrMemory(ctxt, NULL);
3499
0
      }
3500
6.02M
      return(ret);
3501
6.02M
  }
3502
6.05M
    }
3503
379k
complex:
3504
379k
    return(xmlParseNCNameComplex(ctxt));
3505
6.40M
}
3506
3507
/**
3508
 * xmlParseNameAndCompare:
3509
 * @ctxt:  an XML parser context
3510
 *
3511
 * parse an XML name and compares for match
3512
 * (specialized for endtag parsing)
3513
 *
3514
 * Returns NULL for an illegal name, (xmlChar*) 1 for success
3515
 * and the name for mismatch
3516
 */
3517
3518
static const xmlChar *
3519
191k
xmlParseNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *other) {
3520
191k
    register const xmlChar *cmp = other;
3521
191k
    register const xmlChar *in;
3522
191k
    const xmlChar *ret;
3523
3524
191k
    GROW;
3525
191k
    if (ctxt->instate == XML_PARSER_EOF)
3526
0
        return(NULL);
3527
3528
191k
    in = ctxt->input->cur;
3529
935k
    while (*in != 0 && *in == *cmp) {
3530
744k
  ++in;
3531
744k
  ++cmp;
3532
744k
    }
3533
191k
    if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) {
3534
  /* success */
3535
174k
  ctxt->input->col += in - ctxt->input->cur;
3536
174k
  ctxt->input->cur = in;
3537
174k
  return (const xmlChar*) 1;
3538
174k
    }
3539
    /* failure (or end of input buffer), check with full function */
3540
16.2k
    ret = xmlParseName (ctxt);
3541
    /* strings coming from the dictionary direct compare possible */
3542
16.2k
    if (ret == other) {
3543
740
  return (const xmlChar*) 1;
3544
740
    }
3545
15.4k
    return ret;
3546
16.2k
}
3547
3548
/**
3549
 * xmlParseStringName:
3550
 * @ctxt:  an XML parser context
3551
 * @str:  a pointer to the string pointer (IN/OUT)
3552
 *
3553
 * parse an XML name.
3554
 *
3555
 * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
3556
 *                  CombiningChar | Extender
3557
 *
3558
 * [5] Name ::= (Letter | '_' | ':') (NameChar)*
3559
 *
3560
 * [6] Names ::= Name (#x20 Name)*
3561
 *
3562
 * Returns the Name parsed or NULL. The @str pointer
3563
 * is updated to the current location in the string.
3564
 */
3565
3566
static xmlChar *
3567
2.08M
xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
3568
2.08M
    xmlChar buf[XML_MAX_NAMELEN + 5];
3569
2.08M
    const xmlChar *cur = *str;
3570
2.08M
    int len = 0, l;
3571
2.08M
    int c;
3572
3573
#ifdef DEBUG
3574
    nbParseStringName++;
3575
#endif
3576
3577
2.08M
    c = CUR_SCHAR(cur, l);
3578
2.08M
    if (!xmlIsNameStartChar(ctxt, c)) {
3579
28.3k
  return(NULL);
3580
28.3k
    }
3581
3582
2.06M
    COPY_BUF(l,buf,len,c);
3583
2.06M
    cur += l;
3584
2.06M
    c = CUR_SCHAR(cur, l);
3585
2.69M
    while (xmlIsNameChar(ctxt, c)) {
3586
642k
  COPY_BUF(l,buf,len,c);
3587
642k
  cur += l;
3588
642k
  c = CUR_SCHAR(cur, l);
3589
642k
  if (len >= XML_MAX_NAMELEN) { /* test bigentname.xml */
3590
      /*
3591
       * Okay someone managed to make a huge name, so he's ready to pay
3592
       * for the processing speed.
3593
       */
3594
5.76k
      xmlChar *buffer;
3595
5.76k
      int max = len * 2;
3596
3597
5.76k
      buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
3598
5.76k
      if (buffer == NULL) {
3599
0
          xmlErrMemory(ctxt, NULL);
3600
0
    return(NULL);
3601
0
      }
3602
5.76k
      memcpy(buffer, buf, len);
3603
4.26M
      while (xmlIsNameChar(ctxt, c)) {
3604
4.25M
    if (len + 10 > max) {
3605
5.13k
        xmlChar *tmp;
3606
3607
5.13k
                    if ((len > XML_MAX_NAME_LENGTH) &&
3608
5.13k
                        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3609
0
                        xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
3610
0
      xmlFree(buffer);
3611
0
                        return(NULL);
3612
0
                    }
3613
5.13k
        max *= 2;
3614
5.13k
        tmp = (xmlChar *) xmlRealloc(buffer,
3615
5.13k
                                  max * sizeof(xmlChar));
3616
5.13k
        if (tmp == NULL) {
3617
0
      xmlErrMemory(ctxt, NULL);
3618
0
      xmlFree(buffer);
3619
0
      return(NULL);
3620
0
        }
3621
5.13k
        buffer = tmp;
3622
5.13k
    }
3623
4.25M
    COPY_BUF(l,buffer,len,c);
3624
4.25M
    cur += l;
3625
4.25M
    c = CUR_SCHAR(cur, l);
3626
4.25M
      }
3627
5.76k
      buffer[len] = 0;
3628
5.76k
      *str = cur;
3629
5.76k
      return(buffer);
3630
5.76k
  }
3631
642k
    }
3632
2.05M
    if ((len > XML_MAX_NAME_LENGTH) &&
3633
2.05M
        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3634
0
        xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
3635
0
        return(NULL);
3636
0
    }
3637
2.05M
    *str = cur;
3638
2.05M
    return(xmlStrndup(buf, len));
3639
2.05M
}
3640
3641
/**
3642
 * xmlParseNmtoken:
3643
 * @ctxt:  an XML parser context
3644
 *
3645
 * parse an XML Nmtoken.
3646
 *
3647
 * [7] Nmtoken ::= (NameChar)+
3648
 *
3649
 * [8] Nmtokens ::= Nmtoken (#x20 Nmtoken)*
3650
 *
3651
 * Returns the Nmtoken parsed or NULL
3652
 */
3653
3654
xmlChar *
3655
67.5k
xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
3656
67.5k
    xmlChar buf[XML_MAX_NAMELEN + 5];
3657
67.5k
    int len = 0, l;
3658
67.5k
    int c;
3659
67.5k
    int count = 0;
3660
3661
#ifdef DEBUG
3662
    nbParseNmToken++;
3663
#endif
3664
3665
67.5k
    GROW;
3666
67.5k
    if (ctxt->instate == XML_PARSER_EOF)
3667
0
        return(NULL);
3668
67.5k
    c = CUR_CHAR(l);
3669
3670
1.21M
    while (xmlIsNameChar(ctxt, c)) {
3671
1.17M
  if (count++ > XML_PARSER_CHUNK_SIZE) {
3672
0
      count = 0;
3673
0
      GROW;
3674
0
  }
3675
1.17M
  COPY_BUF(l,buf,len,c);
3676
1.17M
  NEXTL(l);
3677
1.17M
  c = CUR_CHAR(l);
3678
1.17M
  if (c == 0) {
3679
1.85k
      count = 0;
3680
1.85k
      GROW;
3681
1.85k
      if (ctxt->instate == XML_PARSER_EOF)
3682
0
    return(NULL);
3683
1.85k
            c = CUR_CHAR(l);
3684
1.85k
  }
3685
1.17M
  if (len >= XML_MAX_NAMELEN) {
3686
      /*
3687
       * Okay someone managed to make a huge token, so he's ready to pay
3688
       * for the processing speed.
3689
       */
3690
27.5k
      xmlChar *buffer;
3691
27.5k
      int max = len * 2;
3692
3693
27.5k
      buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
3694
27.5k
      if (buffer == NULL) {
3695
0
          xmlErrMemory(ctxt, NULL);
3696
0
    return(NULL);
3697
0
      }
3698
27.5k
      memcpy(buffer, buf, len);
3699
85.2M
      while (xmlIsNameChar(ctxt, c)) {
3700
85.2M
    if (count++ > XML_PARSER_CHUNK_SIZE) {
3701
830k
        count = 0;
3702
830k
        GROW;
3703
830k
                    if (ctxt->instate == XML_PARSER_EOF) {
3704
0
                        xmlFree(buffer);
3705
0
                        return(NULL);
3706
0
                    }
3707
830k
    }
3708
85.2M
    if (len + 10 > max) {
3709
34.1k
        xmlChar *tmp;
3710
3711
34.1k
                    if ((max > XML_MAX_NAME_LENGTH) &&
3712
34.1k
                        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3713
0
                        xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken");
3714
0
                        xmlFree(buffer);
3715
0
                        return(NULL);
3716
0
                    }
3717
34.1k
        max *= 2;
3718
34.1k
        tmp = (xmlChar *) xmlRealloc(buffer,
3719
34.1k
                                  max * sizeof(xmlChar));
3720
34.1k
        if (tmp == NULL) {
3721
0
      xmlErrMemory(ctxt, NULL);
3722
0
      xmlFree(buffer);
3723
0
      return(NULL);
3724
0
        }
3725
34.1k
        buffer = tmp;
3726
34.1k
    }
3727
85.2M
    COPY_BUF(l,buffer,len,c);
3728
85.2M
    NEXTL(l);
3729
85.2M
    c = CUR_CHAR(l);
3730
85.2M
      }
3731
27.5k
      buffer[len] = 0;
3732
27.5k
      return(buffer);
3733
27.5k
  }
3734
1.17M
    }
3735
39.9k
    if (len == 0)
3736
15.1k
        return(NULL);
3737
24.8k
    if ((len > XML_MAX_NAME_LENGTH) &&
3738
24.8k
        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3739
0
        xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken");
3740
0
        return(NULL);
3741
0
    }
3742
24.8k
    return(xmlStrndup(buf, len));
3743
24.8k
}
3744
3745
/**
3746
 * xmlParseEntityValue:
3747
 * @ctxt:  an XML parser context
3748
 * @orig:  if non-NULL store a copy of the original entity value
3749
 *
3750
 * parse a value for ENTITY declarations
3751
 *
3752
 * [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"' |
3753
 *                 "'" ([^%&'] | PEReference | Reference)* "'"
3754
 *
3755
 * Returns the EntityValue parsed with reference substituted or NULL
3756
 */
3757
3758
xmlChar *
3759
39.3k
xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
3760
39.3k
    xmlChar *buf = NULL;
3761
39.3k
    int len = 0;
3762
39.3k
    int size = XML_PARSER_BUFFER_SIZE;
3763
39.3k
    int c, l;
3764
39.3k
    xmlChar stop;
3765
39.3k
    xmlChar *ret = NULL;
3766
39.3k
    const xmlChar *cur = NULL;
3767
39.3k
    xmlParserInputPtr input;
3768
3769
39.3k
    if (RAW == '"') stop = '"';
3770
12.0k
    else if (RAW == '\'') stop = '\'';
3771
0
    else {
3772
0
  xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_STARTED, NULL);
3773
0
  return(NULL);
3774
0
    }
3775
39.3k
    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
3776
39.3k
    if (buf == NULL) {
3777
0
  xmlErrMemory(ctxt, NULL);
3778
0
  return(NULL);
3779
0
    }
3780
3781
    /*
3782
     * The content of the entity definition is copied in a buffer.
3783
     */
3784
3785
39.3k
    ctxt->instate = XML_PARSER_ENTITY_VALUE;
3786
39.3k
    input = ctxt->input;
3787
39.3k
    GROW;
3788
39.3k
    if (ctxt->instate == XML_PARSER_EOF)
3789
0
        goto error;
3790
39.3k
    NEXT;
3791
39.3k
    c = CUR_CHAR(l);
3792
    /*
3793
     * NOTE: 4.4.5 Included in Literal
3794
     * When a parameter entity reference appears in a literal entity
3795
     * value, ... a single or double quote character in the replacement
3796
     * text is always treated as a normal data character and will not
3797
     * terminate the literal.
3798
     * In practice it means we stop the loop only when back at parsing
3799
     * the initial entity and the quote is found
3800
     */
3801
574M
    while (((IS_CHAR(c)) && ((c != stop) || /* checked */
3802
574M
      (ctxt->input != input))) && (ctxt->instate != XML_PARSER_EOF)) {
3803
574M
  if (len + 5 >= size) {
3804
17.2k
      xmlChar *tmp;
3805
3806
17.2k
      size *= 2;
3807
17.2k
      tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
3808
17.2k
      if (tmp == NULL) {
3809
0
    xmlErrMemory(ctxt, NULL);
3810
0
                goto error;
3811
0
      }
3812
17.2k
      buf = tmp;
3813
17.2k
  }
3814
574M
  COPY_BUF(l,buf,len,c);
3815
574M
  NEXTL(l);
3816
3817
574M
  GROW;
3818
574M
  c = CUR_CHAR(l);
3819
574M
  if (c == 0) {
3820
140
      GROW;
3821
140
      c = CUR_CHAR(l);
3822
140
  }
3823
574M
    }
3824
39.3k
    buf[len] = 0;
3825
39.3k
    if (ctxt->instate == XML_PARSER_EOF)
3826
0
        goto error;
3827
39.3k
    if (c != stop) {
3828
175
        xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_FINISHED, NULL);
3829
175
        goto error;
3830
175
    }
3831
39.1k
    NEXT;
3832
3833
    /*
3834
     * Raise problem w.r.t. '&' and '%' being used in non-entities
3835
     * reference constructs. Note Charref will be handled in
3836
     * xmlStringDecodeEntities()
3837
     */
3838
39.1k
    cur = buf;
3839
1.64G
    while (*cur != 0) { /* non input consuming */
3840
1.64G
  if ((*cur == '%') || ((*cur == '&') && (cur[1] != '#'))) {
3841
37.6k
      xmlChar *name;
3842
37.6k
      xmlChar tmp = *cur;
3843
37.6k
            int nameOk = 0;
3844
3845
37.6k
      cur++;
3846
37.6k
      name = xmlParseStringName(ctxt, &cur);
3847
37.6k
            if (name != NULL) {
3848
35.2k
                nameOk = 1;
3849
35.2k
                xmlFree(name);
3850
35.2k
            }
3851
37.6k
            if ((nameOk == 0) || (*cur != ';')) {
3852
6.14k
    xmlFatalErrMsgInt(ctxt, XML_ERR_ENTITY_CHAR_ERROR,
3853
6.14k
      "EntityValue: '%c' forbidden except for entities references\n",
3854
6.14k
                            tmp);
3855
6.14k
                goto error;
3856
6.14k
      }
3857
31.5k
      if ((tmp == '%') && (ctxt->inSubset == 1) &&
3858
31.5k
    (ctxt->inputNr == 1)) {
3859
1.02k
    xmlFatalErr(ctxt, XML_ERR_ENTITY_PE_INTERNAL, NULL);
3860
1.02k
                goto error;
3861
1.02k
      }
3862
30.4k
      if (*cur == 0)
3863
0
          break;
3864
30.4k
  }
3865
1.64G
  cur++;
3866
1.64G
    }
3867
3868
    /*
3869
     * Then PEReference entities are substituted.
3870
     *
3871
     * NOTE: 4.4.7 Bypassed
3872
     * When a general entity reference appears in the EntityValue in
3873
     * an entity declaration, it is bypassed and left as is.
3874
     * so XML_SUBSTITUTE_REF is not set here.
3875
     */
3876
31.9k
    ++ctxt->depth;
3877
31.9k
    ret = xmlStringDecodeEntities(ctxt, buf, XML_SUBSTITUTE_PEREF,
3878
31.9k
                                  0, 0, 0);
3879
31.9k
    --ctxt->depth;
3880
31.9k
    if (orig != NULL) {
3881
31.9k
        *orig = buf;
3882
31.9k
        buf = NULL;
3883
31.9k
    }
3884
3885
39.3k
error:
3886
39.3k
    if (buf != NULL)
3887
7.35k
        xmlFree(buf);
3888
39.3k
    return(ret);
3889
31.9k
}
3890
3891
/**
3892
 * xmlParseAttValueComplex:
3893
 * @ctxt:  an XML parser context
3894
 * @len:   the resulting attribute len
3895
 * @normalize:  whether to apply the inner normalization
3896
 *
3897
 * parse a value for an attribute, this is the fallback function
3898
 * of xmlParseAttValue() when the attribute parsing requires handling
3899
 * of non-ASCII characters, or normalization compaction.
3900
 *
3901
 * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
3902
 */
3903
static xmlChar *
3904
98.8k
xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
3905
98.8k
    xmlChar limit = 0;
3906
98.8k
    xmlChar *buf = NULL;
3907
98.8k
    xmlChar *rep = NULL;
3908
98.8k
    size_t len = 0;
3909
98.8k
    size_t buf_size = 0;
3910
98.8k
    int c, l, in_space = 0;
3911
98.8k
    xmlChar *current = NULL;
3912
98.8k
    xmlEntityPtr ent;
3913
3914
98.8k
    if (NXT(0) == '"') {
3915
96.7k
  ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
3916
96.7k
  limit = '"';
3917
96.7k
        NEXT;
3918
96.7k
    } else if (NXT(0) == '\'') {
3919
2.01k
  limit = '\'';
3920
2.01k
  ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
3921
2.01k
        NEXT;
3922
2.01k
    } else {
3923
0
  xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
3924
0
  return(NULL);
3925
0
    }
3926
3927
    /*
3928
     * allocate a translation buffer.
3929
     */
3930
98.8k
    buf_size = XML_PARSER_BUFFER_SIZE;
3931
98.8k
    buf = (xmlChar *) xmlMallocAtomic(buf_size);
3932
98.8k
    if (buf == NULL) goto mem_error;
3933
3934
    /*
3935
     * OK loop until we reach one of the ending char or a size limit.
3936
     */
3937
98.8k
    c = CUR_CHAR(l);
3938
305M
    while (((NXT(0) != limit) && /* checked */
3939
305M
            (IS_CHAR(c)) && (c != '<')) &&
3940
305M
            (ctxt->instate != XML_PARSER_EOF)) {
3941
        /*
3942
         * Impose a reasonable limit on attribute size, unless XML_PARSE_HUGE
3943
         * special option is given
3944
         */
3945
305M
        if ((len > XML_MAX_TEXT_LENGTH) &&
3946
305M
            ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3947
0
            xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
3948
0
                           "AttValue length too long\n");
3949
0
            goto mem_error;
3950
0
        }
3951
305M
  if (c == '&') {
3952
972k
      in_space = 0;
3953
972k
      if (NXT(1) == '#') {
3954
503k
    int val = xmlParseCharRef(ctxt);
3955
3956
503k
    if (val == '&') {
3957
413k
        if (ctxt->replaceEntities) {
3958
0
      if (len + 10 > buf_size) {
3959
0
          growBuffer(buf, 10);
3960
0
      }
3961
0
      buf[len++] = '&';
3962
413k
        } else {
3963
      /*
3964
       * The reparsing will be done in xmlStringGetNodeList()
3965
       * called by the attribute() function in SAX.c
3966
       */
3967
413k
      if (len + 10 > buf_size) {
3968
870
          growBuffer(buf, 10);
3969
870
      }
3970
413k
      buf[len++] = '&';
3971
413k
      buf[len++] = '#';
3972
413k
      buf[len++] = '3';
3973
413k
      buf[len++] = '8';
3974
413k
      buf[len++] = ';';
3975
413k
        }
3976
413k
    } else if (val != 0) {
3977
48.2k
        if (len + 10 > buf_size) {
3978
428
      growBuffer(buf, 10);
3979
428
        }
3980
48.2k
        len += xmlCopyChar(0, &buf[len], val);
3981
48.2k
    }
3982
503k
      } else {
3983
469k
    ent = xmlParseEntityRef(ctxt);
3984
469k
    ctxt->nbentities++;
3985
469k
    if (ent != NULL)
3986
335k
        ctxt->nbentities += ent->owner;
3987
469k
    if ((ent != NULL) &&
3988
469k
        (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
3989
3.43k
        if (len + 10 > buf_size) {
3990
478
      growBuffer(buf, 10);
3991
478
        }
3992
3.43k
        if ((ctxt->replaceEntities == 0) &&
3993
3.43k
            (ent->content[0] == '&')) {
3994
1.45k
      buf[len++] = '&';
3995
1.45k
      buf[len++] = '#';
3996
1.45k
      buf[len++] = '3';
3997
1.45k
      buf[len++] = '8';
3998
1.45k
      buf[len++] = ';';
3999
1.98k
        } else {
4000
1.98k
      buf[len++] = ent->content[0];
4001
1.98k
        }
4002
465k
    } else if ((ent != NULL) &&
4003
465k
               (ctxt->replaceEntities != 0)) {
4004
0
        if (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) {
4005
0
      ++ctxt->depth;
4006
0
      rep = xmlStringDecodeEntities(ctxt, ent->content,
4007
0
                  XML_SUBSTITUTE_REF,
4008
0
                  0, 0, 0);
4009
0
      --ctxt->depth;
4010
0
      if (rep != NULL) {
4011
0
          current = rep;
4012
0
          while (*current != 0) { /* non input consuming */
4013
0
                                if ((*current == 0xD) || (*current == 0xA) ||
4014
0
                                    (*current == 0x9)) {
4015
0
                                    buf[len++] = 0x20;
4016
0
                                    current++;
4017
0
                                } else
4018
0
                                    buf[len++] = *current++;
4019
0
        if (len + 10 > buf_size) {
4020
0
            growBuffer(buf, 10);
4021
0
        }
4022
0
          }
4023
0
          xmlFree(rep);
4024
0
          rep = NULL;
4025
0
      }
4026
0
        } else {
4027
0
      if (len + 10 > buf_size) {
4028
0
          growBuffer(buf, 10);
4029
0
      }
4030
0
      if (ent->content != NULL)
4031
0
          buf[len++] = ent->content[0];
4032
0
        }
4033
465k
    } else if (ent != NULL) {
4034
331k
        int i = xmlStrlen(ent->name);
4035
331k
        const xmlChar *cur = ent->name;
4036
4037
        /*
4038
         * This may look absurd but is needed to detect
4039
         * entities problems
4040
         */
4041
331k
        if ((ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
4042
331k
      (ent->content != NULL) && (ent->checked == 0)) {
4043
746
      unsigned long oldnbent = ctxt->nbentities, diff;
4044
4045
746
      ++ctxt->depth;
4046
746
      rep = xmlStringDecodeEntities(ctxt, ent->content,
4047
746
              XML_SUBSTITUTE_REF, 0, 0, 0);
4048
746
      --ctxt->depth;
4049
4050
746
                        diff = ctxt->nbentities - oldnbent + 1;
4051
746
                        if (diff > INT_MAX / 2)
4052
4
                            diff = INT_MAX / 2;
4053
746
                        ent->checked = diff * 2;
4054
746
      if (rep != NULL) {
4055
590
          if (xmlStrchr(rep, '<'))
4056
222
              ent->checked |= 1;
4057
590
          xmlFree(rep);
4058
590
          rep = NULL;
4059
590
      } else {
4060
156
                            ent->content[0] = 0;
4061
156
                        }
4062
746
        }
4063
4064
        /*
4065
         * Just output the reference
4066
         */
4067
331k
        buf[len++] = '&';
4068
332k
        while (len + i + 10 > buf_size) {
4069
1.36k
      growBuffer(buf, i + 10);
4070
1.36k
        }
4071
663k
        for (;i > 0;i--)
4072
332k
      buf[len++] = *cur++;
4073
331k
        buf[len++] = ';';
4074
331k
    }
4075
469k
      }
4076
304M
  } else {
4077
304M
      if ((c == 0x20) || (c == 0xD) || (c == 0xA) || (c == 0x9)) {
4078
3.65M
          if ((len != 0) || (!normalize)) {
4079
3.65M
        if ((!normalize) || (!in_space)) {
4080
3.65M
      COPY_BUF(l,buf,len,0x20);
4081
3.65M
      while (len + 10 > buf_size) {
4082
9.98k
          growBuffer(buf, 10);
4083
9.98k
      }
4084
3.65M
        }
4085
3.65M
        in_space = 1;
4086
3.65M
    }
4087
300M
      } else {
4088
300M
          in_space = 0;
4089
300M
    COPY_BUF(l,buf,len,c);
4090
300M
    if (len + 10 > buf_size) {
4091
50.2k
        growBuffer(buf, 10);
4092
50.2k
    }
4093
300M
      }
4094
304M
      NEXTL(l);
4095
304M
  }
4096
305M
  GROW;
4097
305M
  c = CUR_CHAR(l);
4098
305M
    }
4099
98.8k
    if (ctxt->instate == XML_PARSER_EOF)
4100
0
        goto error;
4101
4102
98.8k
    if ((in_space) && (normalize)) {
4103
1.90k
        while ((len > 0) && (buf[len - 1] == 0x20)) len--;
4104
758
    }
4105
98.8k
    buf[len] = 0;
4106
98.8k
    if (RAW == '<') {
4107
18.1k
  xmlFatalErr(ctxt, XML_ERR_LT_IN_ATTRIBUTE, NULL);
4108
80.6k
    } else if (RAW != limit) {
4109
9.57k
  if ((c != 0) && (!IS_CHAR(c))) {
4110
1.18k
      xmlFatalErrMsg(ctxt, XML_ERR_INVALID_CHAR,
4111
1.18k
         "invalid character in attribute value\n");
4112
8.39k
  } else {
4113
8.39k
      xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
4114
8.39k
         "AttValue: ' expected\n");
4115
8.39k
        }
4116
9.57k
    } else
4117
71.0k
  NEXT;
4118
4119
    /*
4120
     * There we potentially risk an overflow, don't allow attribute value of
4121
     * length more than INT_MAX it is a very reasonable assumption !
4122
     */
4123
98.8k
    if (len >= INT_MAX) {
4124
0
        xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
4125
0
                       "AttValue length too long\n");
4126
0
        goto mem_error;
4127
0
    }
4128
4129
98.8k
    if (attlen != NULL) *attlen = (int) len;
4130
98.8k
    return(buf);
4131
4132
0
mem_error:
4133
0
    xmlErrMemory(ctxt, NULL);
4134
0
error:
4135
0
    if (buf != NULL)
4136
0
        xmlFree(buf);
4137
0
    if (rep != NULL)
4138
0
        xmlFree(rep);
4139
0
    return(NULL);
4140
0
}
4141
4142
/**
4143
 * xmlParseAttValue:
4144
 * @ctxt:  an XML parser context
4145
 *
4146
 * parse a value for an attribute
4147
 * Note: the parser won't do substitution of entities here, this
4148
 * will be handled later in xmlStringGetNodeList
4149
 *
4150
 * [10] AttValue ::= '"' ([^<&"] | Reference)* '"' |
4151
 *                   "'" ([^<&'] | Reference)* "'"
4152
 *
4153
 * 3.3.3 Attribute-Value Normalization:
4154
 * Before the value of an attribute is passed to the application or
4155
 * checked for validity, the XML processor must normalize it as follows:
4156
 * - a character reference is processed by appending the referenced
4157
 *   character to the attribute value
4158
 * - an entity reference is processed by recursively processing the
4159
 *   replacement text of the entity
4160
 * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
4161
 *   appending #x20 to the normalized value, except that only a single
4162
 *   #x20 is appended for a "#xD#xA" sequence that is part of an external
4163
 *   parsed entity or the literal entity value of an internal parsed entity
4164
 * - other characters are processed by appending them to the normalized value
4165
 * If the declared value is not CDATA, then the XML processor must further
4166
 * process the normalized attribute value by discarding any leading and
4167
 * trailing space (#x20) characters, and by replacing sequences of space
4168
 * (#x20) characters by a single space (#x20) character.
4169
 * All attributes for which no declaration has been read should be treated
4170
 * by a non-validating parser as if declared CDATA.
4171
 *
4172
 * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
4173
 */
4174
4175
4176
xmlChar *
4177
817k
xmlParseAttValue(xmlParserCtxtPtr ctxt) {
4178
817k
    if ((ctxt == NULL) || (ctxt->input == NULL)) return(NULL);
4179
817k
    return(xmlParseAttValueInternal(ctxt, NULL, NULL, 0));
4180
817k
}
4181
4182
/**
4183
 * xmlParseSystemLiteral:
4184
 * @ctxt:  an XML parser context
4185
 *
4186
 * parse an XML Literal
4187
 *
4188
 * [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
4189
 *
4190
 * Returns the SystemLiteral parsed or NULL
4191
 */
4192
4193
xmlChar *
4194
23.7k
xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
4195
23.7k
    xmlChar *buf = NULL;
4196
23.7k
    int len = 0;
4197
23.7k
    int size = XML_PARSER_BUFFER_SIZE;
4198
23.7k
    int cur, l;
4199
23.7k
    xmlChar stop;
4200
23.7k
    int state = ctxt->instate;
4201
23.7k
    int count = 0;
4202
4203
23.7k
    SHRINK;
4204
23.7k
    if (RAW == '"') {
4205
16.2k
        NEXT;
4206
16.2k
  stop = '"';
4207
16.2k
    } else if (RAW == '\'') {
4208
4.62k
        NEXT;
4209
4.62k
  stop = '\'';
4210
4.62k
    } else {
4211
2.86k
  xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, NULL);
4212
2.86k
  return(NULL);
4213
2.86k
    }
4214
4215
20.8k
    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
4216
20.8k
    if (buf == NULL) {
4217
0
        xmlErrMemory(ctxt, NULL);
4218
0
  return(NULL);
4219
0
    }
4220
20.8k
    ctxt->instate = XML_PARSER_SYSTEM_LITERAL;
4221
20.8k
    cur = CUR_CHAR(l);
4222
30.1M
    while ((IS_CHAR(cur)) && (cur != stop)) { /* checked */
4223
30.1M
  if (len + 5 >= size) {
4224
16.3k
      xmlChar *tmp;
4225
4226
16.3k
            if ((size > XML_MAX_NAME_LENGTH) &&
4227
16.3k
                ((ctxt->options & XML_PARSE_HUGE) == 0)) {
4228
0
                xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "SystemLiteral");
4229
0
                xmlFree(buf);
4230
0
    ctxt->instate = (xmlParserInputState) state;
4231
0
                return(NULL);
4232
0
            }
4233
16.3k
      size *= 2;
4234
16.3k
      tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
4235
16.3k
      if (tmp == NULL) {
4236
0
          xmlFree(buf);
4237
0
    xmlErrMemory(ctxt, NULL);
4238
0
    ctxt->instate = (xmlParserInputState) state;
4239
0
    return(NULL);
4240
0
      }
4241
16.3k
      buf = tmp;
4242
16.3k
  }
4243
30.1M
  count++;
4244
30.1M
  if (count > 50) {
4245
587k
      SHRINK;
4246
587k
      GROW;
4247
587k
      count = 0;
4248
587k
            if (ctxt->instate == XML_PARSER_EOF) {
4249
0
          xmlFree(buf);
4250
0
    return(NULL);
4251
0
            }
4252
587k
  }
4253
30.1M
  COPY_BUF(l,buf,len,cur);
4254
30.1M
  NEXTL(l);
4255
30.1M
  cur = CUR_CHAR(l);
4256
30.1M
  if (cur == 0) {
4257
40.7k
      GROW;
4258
40.7k
      SHRINK;
4259
40.7k
      cur = CUR_CHAR(l);
4260
40.7k
  }
4261
30.1M
    }
4262
20.8k
    buf[len] = 0;
4263
20.8k
    ctxt->instate = (xmlParserInputState) state;
4264
20.8k
    if (!IS_CHAR(cur)) {
4265
7.12k
  xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
4266
13.7k
    } else {
4267
13.7k
  NEXT;
4268
13.7k
    }
4269
20.8k
    return(buf);
4270
20.8k
}
4271
4272
/**
4273
 * xmlParsePubidLiteral:
4274
 * @ctxt:  an XML parser context
4275
 *
4276
 * parse an XML public literal
4277
 *
4278
 * [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
4279
 *
4280
 * Returns the PubidLiteral parsed or NULL.
4281
 */
4282
4283
xmlChar *
4284
49.0k
xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
4285
49.0k
    xmlChar *buf = NULL;
4286
49.0k
    int len = 0;
4287
49.0k
    int size = XML_PARSER_BUFFER_SIZE;
4288
49.0k
    xmlChar cur;
4289
49.0k
    xmlChar stop;
4290
49.0k
    int count = 0;
4291
49.0k
    xmlParserInputState oldstate = ctxt->instate;
4292
4293
49.0k
    SHRINK;
4294
49.0k
    if (RAW == '"') {
4295
42.4k
        NEXT;
4296
42.4k
  stop = '"';
4297
42.4k
    } else if (RAW == '\'') {
4298
4.48k
        NEXT;
4299
4.48k
  stop = '\'';
4300
4.48k
    } else {
4301
2.14k
  xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, NULL);
4302
2.14k
  return(NULL);
4303
2.14k
    }
4304
46.9k
    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
4305
46.9k
    if (buf == NULL) {
4306
0
  xmlErrMemory(ctxt, NULL);
4307
0
  return(NULL);
4308
0
    }
4309
46.9k
    ctxt->instate = XML_PARSER_PUBLIC_LITERAL;
4310
46.9k
    cur = CUR;
4311
10.8M
    while ((IS_PUBIDCHAR_CH(cur)) && (cur != stop)) { /* checked */
4312
10.7M
  if (len + 1 >= size) {
4313
4.78k
      xmlChar *tmp;
4314
4315
4.78k
            if ((size > XML_MAX_NAME_LENGTH) &&
4316
4.78k
                ((ctxt->options & XML_PARSE_HUGE) == 0)) {
4317
0
                xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Public ID");
4318
0
                xmlFree(buf);
4319
0
                return(NULL);
4320
0
            }
4321
4.78k
      size *= 2;
4322
4.78k
      tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
4323
4.78k
      if (tmp == NULL) {
4324
0
    xmlErrMemory(ctxt, NULL);
4325
0
    xmlFree(buf);
4326
0
    return(NULL);
4327
0
      }
4328
4.78k
      buf = tmp;
4329
4.78k
  }
4330
10.7M
  buf[len++] = cur;
4331
10.7M
  count++;
4332
10.7M
  if (count > 50) {
4333
199k
      SHRINK;
4334
199k
      GROW;
4335
199k
      count = 0;
4336
199k
            if (ctxt->instate == XML_PARSER_EOF) {
4337
0
    xmlFree(buf);
4338
0
    return(NULL);
4339
0
            }
4340
199k
  }
4341
10.7M
  NEXT;
4342
10.7M
  cur = CUR;
4343
10.7M
  if (cur == 0) {
4344
8.27k
      GROW;
4345
8.27k
      SHRINK;
4346
8.27k
      cur = CUR;
4347
8.27k
  }
4348
10.7M
    }
4349
46.9k
    buf[len] = 0;
4350
46.9k
    if (cur != stop) {
4351
40.9k
  xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
4352
40.9k
    } else {
4353
6.02k
  NEXT;
4354
6.02k
    }
4355
46.9k
    ctxt->instate = oldstate;
4356
46.9k
    return(buf);
4357
46.9k
}
4358
4359
static void xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata);
4360
4361
/*
4362
 * used for the test in the inner loop of the char data testing
4363
 */
4364
static const unsigned char test_char_data[256] = {
4365
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4366
    0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9, CR/LF separated */
4367
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4368
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4369
    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x00, 0x27, /* & */
4370
    0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
4371
    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
4372
    0x38, 0x39, 0x3A, 0x3B, 0x00, 0x3D, 0x3E, 0x3F, /* < */
4373
    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
4374
    0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
4375
    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
4376
    0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x00, 0x5E, 0x5F, /* ] */
4377
    0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
4378
    0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
4379
    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
4380
    0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
4381
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* non-ascii */
4382
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4383
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4384
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4385
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4386
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4387
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4388
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4389
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4390
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4391
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4392
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4393
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4394
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4395
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4396
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
4397
};
4398
4399
/**
4400
 * xmlParseCharData:
4401
 * @ctxt:  an XML parser context
4402
 * @cdata:  int indicating whether we are within a CDATA section
4403
 *
4404
 * parse a CharData section.
4405
 * if we are within a CDATA section ']]>' marks an end of section.
4406
 *
4407
 * The right angle bracket (>) may be represented using the string "&gt;",
4408
 * and must, for compatibility, be escaped using "&gt;" or a character
4409
 * reference when it appears in the string "]]>" in content, when that
4410
 * string is not marking the end of a CDATA section.
4411
 *
4412
 * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
4413
 */
4414
4415
void
4416
830k
xmlParseCharData(xmlParserCtxtPtr ctxt, int cdata) {
4417
830k
    const xmlChar *in;
4418
830k
    int nbchar = 0;
4419
830k
    int line = ctxt->input->line;
4420
830k
    int col = ctxt->input->col;
4421
830k
    int ccol;
4422
4423
830k
    SHRINK;
4424
830k
    GROW;
4425
    /*
4426
     * Accelerated common case where input don't need to be
4427
     * modified before passing it to the handler.
4428
     */
4429
830k
    if (!cdata) {
4430
830k
  in = ctxt->input->cur;
4431
834k
  do {
4432
900k
get_more_space:
4433
1.04M
      while (*in == 0x20) { in++; ctxt->input->col++; }
4434
900k
      if (*in == 0xA) {
4435
258k
    do {
4436
258k
        ctxt->input->line++; ctxt->input->col = 1;
4437
258k
        in++;
4438
258k
    } while (*in == 0xA);
4439
65.7k
    goto get_more_space;
4440
65.7k
      }
4441
834k
      if (*in == '<') {
4442
60.6k
    nbchar = in - ctxt->input->cur;
4443
60.6k
    if (nbchar > 0) {
4444
59.9k
        const xmlChar *tmp = ctxt->input->cur;
4445
59.9k
        ctxt->input->cur = in;
4446
4447
59.9k
        if ((ctxt->sax != NULL) &&
4448
59.9k
            (ctxt->sax->ignorableWhitespace !=
4449
59.9k
             ctxt->sax->characters)) {
4450
0
      if (areBlanks(ctxt, tmp, nbchar, 1)) {
4451
0
          if (ctxt->sax->ignorableWhitespace != NULL)
4452
0
        ctxt->sax->ignorableWhitespace(ctxt->userData,
4453
0
                   tmp, nbchar);
4454
0
      } else {
4455
0
          if (ctxt->sax->characters != NULL)
4456
0
        ctxt->sax->characters(ctxt->userData,
4457
0
                  tmp, nbchar);
4458
0
          if (*ctxt->space == -1)
4459
0
              *ctxt->space = -2;
4460
0
      }
4461
59.9k
        } else if ((ctxt->sax != NULL) &&
4462
59.9k
                   (ctxt->sax->characters != NULL)) {
4463
59.9k
      ctxt->sax->characters(ctxt->userData,
4464
59.9k
                tmp, nbchar);
4465
59.9k
        }
4466
59.9k
    }
4467
60.6k
    return;
4468
60.6k
      }
4469
4470
849k
get_more:
4471
849k
            ccol = ctxt->input->col;
4472
4.88M
      while (test_char_data[*in]) {
4473
4.03M
    in++;
4474
4.03M
    ccol++;
4475
4.03M
      }
4476
849k
      ctxt->input->col = ccol;
4477
849k
      if (*in == 0xA) {
4478
192k
    do {
4479
192k
        ctxt->input->line++; ctxt->input->col = 1;
4480
192k
        in++;
4481
192k
    } while (*in == 0xA);
4482
29.4k
    goto get_more;
4483
29.4k
      }
4484
820k
      if (*in == ']') {
4485
48.6k
    if ((in[1] == ']') && (in[2] == '>')) {
4486
2.55k
        xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
4487
2.55k
        ctxt->input->cur = in + 1;
4488
2.55k
        return;
4489
2.55k
    }
4490
46.0k
    in++;
4491
46.0k
    ctxt->input->col++;
4492
46.0k
    goto get_more;
4493
48.6k
      }
4494
771k
      nbchar = in - ctxt->input->cur;
4495
771k
      if (nbchar > 0) {
4496
623k
    if ((ctxt->sax != NULL) &&
4497
623k
        (ctxt->sax->ignorableWhitespace !=
4498
623k
         ctxt->sax->characters) &&
4499
623k
        (IS_BLANK_CH(*ctxt->input->cur))) {
4500
0
        const xmlChar *tmp = ctxt->input->cur;
4501
0
        ctxt->input->cur = in;
4502
4503
0
        if (areBlanks(ctxt, tmp, nbchar, 0)) {
4504
0
            if (ctxt->sax->ignorableWhitespace != NULL)
4505
0
          ctxt->sax->ignorableWhitespace(ctxt->userData,
4506
0
                 tmp, nbchar);
4507
0
        } else {
4508
0
            if (ctxt->sax->characters != NULL)
4509
0
          ctxt->sax->characters(ctxt->userData,
4510
0
              tmp, nbchar);
4511
0
      if (*ctxt->space == -1)
4512
0
          *ctxt->space = -2;
4513
0
        }
4514
0
                    line = ctxt->input->line;
4515
0
                    col = ctxt->input->col;
4516
623k
    } else if (ctxt->sax != NULL) {
4517
623k
        if (ctxt->sax->characters != NULL)
4518
623k
      ctxt->sax->characters(ctxt->userData,
4519
623k
                ctxt->input->cur, nbchar);
4520
623k
                    line = ctxt->input->line;
4521
623k
                    col = ctxt->input->col;
4522
623k
    }
4523
                /* something really bad happened in the SAX callback */
4524
623k
                if (ctxt->instate != XML_PARSER_CONTENT)
4525
0
                    return;
4526
623k
      }
4527
771k
      ctxt->input->cur = in;
4528
771k
      if (*in == 0xD) {
4529
9.27k
    in++;
4530
9.27k
    if (*in == 0xA) {
4531
2.16k
        ctxt->input->cur = in;
4532
2.16k
        in++;
4533
2.16k
        ctxt->input->line++; ctxt->input->col = 1;
4534
2.16k
        continue; /* while */
4535
2.16k
    }
4536
7.10k
    in--;
4537
7.10k
      }
4538
769k
      if (*in == '<') {
4539
236k
    return;
4540
236k
      }
4541
532k
      if (*in == '&') {
4542
186k
    return;
4543
186k
      }
4544
345k
      SHRINK;
4545
345k
      GROW;
4546
345k
            if (ctxt->instate == XML_PARSER_EOF)
4547
0
    return;
4548
345k
      in = ctxt->input->cur;
4549
348k
  } while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09) || (*in == 0x0a));
4550
343k
  nbchar = 0;
4551
343k
    }
4552
343k
    ctxt->input->line = line;
4553
343k
    ctxt->input->col = col;
4554
343k
    xmlParseCharDataComplex(ctxt, cdata);
4555
343k
}
4556
4557
/**
4558
 * xmlParseCharDataComplex:
4559
 * @ctxt:  an XML parser context
4560
 * @cdata:  int indicating whether we are within a CDATA section
4561
 *
4562
 * parse a CharData section.this is the fallback function
4563
 * of xmlParseCharData() when the parsing requires handling
4564
 * of non-ASCII characters.
4565
 */
4566
static void
4567
343k
xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata) {
4568
343k
    xmlChar buf[XML_PARSER_BIG_BUFFER_SIZE + 5];
4569
343k
    int nbchar = 0;
4570
343k
    int cur, l;
4571
343k
    int count = 0;
4572
4573
343k
    SHRINK;
4574
343k
    GROW;
4575
343k
    cur = CUR_CHAR(l);
4576
234M
    while ((cur != '<') && /* checked */
4577
234M
           (cur != '&') &&
4578
234M
     (IS_CHAR(cur))) /* test also done in xmlCurrentChar() */ {
4579
233M
  if ((cur == ']') && (NXT(1) == ']') &&
4580
233M
      (NXT(2) == '>')) {
4581
2.03k
      if (cdata) break;
4582
2.03k
      else {
4583
2.03k
    xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
4584
2.03k
      }
4585
2.03k
  }
4586
233M
  COPY_BUF(l,buf,nbchar,cur);
4587
  /* move current position before possible calling of ctxt->sax->characters */
4588
233M
  NEXTL(l);
4589
233M
  cur = CUR_CHAR(l);
4590
233M
  if (nbchar >= XML_PARSER_BIG_BUFFER_SIZE) {
4591
2.16M
      buf[nbchar] = 0;
4592
4593
      /*
4594
       * OK the segment is to be consumed as chars.
4595
       */
4596
2.16M
      if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
4597
1.71M
    if (areBlanks(ctxt, buf, nbchar, 0)) {
4598
0
        if (ctxt->sax->ignorableWhitespace != NULL)
4599
0
      ctxt->sax->ignorableWhitespace(ctxt->userData,
4600
0
                                     buf, nbchar);
4601
1.71M
    } else {
4602
1.71M
        if (ctxt->sax->characters != NULL)
4603
1.71M
      ctxt->sax->characters(ctxt->userData, buf, nbchar);
4604
1.71M
        if ((ctxt->sax->characters !=
4605
1.71M
             ctxt->sax->ignorableWhitespace) &&
4606
1.71M
      (*ctxt->space == -1))
4607
0
      *ctxt->space = -2;
4608
1.71M
    }
4609
1.71M
      }
4610
2.16M
      nbchar = 0;
4611
            /* something really bad happened in the SAX callback */
4612
2.16M
            if (ctxt->instate != XML_PARSER_CONTENT)
4613
0
                return;
4614
2.16M
  }
4615
233M
  count++;
4616
233M
  if (count > 50) {
4617
4.52M
      SHRINK;
4618
4.52M
      GROW;
4619
4.52M
      count = 0;
4620
4.52M
            if (ctxt->instate == XML_PARSER_EOF)
4621
0
    return;
4622
4.52M
  }
4623
233M
    }
4624
343k
    if (nbchar != 0) {
4625
254k
        buf[nbchar] = 0;
4626
  /*
4627
   * OK the segment is to be consumed as chars.
4628
   */
4629
254k
  if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
4630
131k
      if (areBlanks(ctxt, buf, nbchar, 0)) {
4631
0
    if (ctxt->sax->ignorableWhitespace != NULL)
4632
0
        ctxt->sax->ignorableWhitespace(ctxt->userData, buf, nbchar);
4633
131k
      } else {
4634
131k
    if (ctxt->sax->characters != NULL)
4635
131k
        ctxt->sax->characters(ctxt->userData, buf, nbchar);
4636
131k
    if ((ctxt->sax->characters != ctxt->sax->ignorableWhitespace) &&
4637
131k
        (*ctxt->space == -1))
4638
0
        *ctxt->space = -2;
4639
131k
      }
4640
131k
  }
4641
254k
    }
4642
343k
    if ((cur != 0) && (!IS_CHAR(cur))) {
4643
  /* Generate the error and skip the offending character */
4644
70.7k
        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
4645
70.7k
                          "PCDATA invalid Char value %d\n",
4646
70.7k
                    cur);
4647
70.7k
  NEXTL(l);
4648
70.7k
    }
4649
343k
}
4650
4651
/**
4652
 * xmlParseExternalID:
4653
 * @ctxt:  an XML parser context
4654
 * @publicID:  a xmlChar** receiving PubidLiteral
4655
 * @strict: indicate whether we should restrict parsing to only
4656
 *          production [75], see NOTE below
4657
 *
4658
 * Parse an External ID or a Public ID
4659
 *
4660
 * NOTE: Productions [75] and [83] interact badly since [75] can generate
4661
 *       'PUBLIC' S PubidLiteral S SystemLiteral
4662
 *
4663
 * [75] ExternalID ::= 'SYSTEM' S SystemLiteral
4664
 *                   | 'PUBLIC' S PubidLiteral S SystemLiteral
4665
 *
4666
 * [83] PublicID ::= 'PUBLIC' S PubidLiteral
4667
 *
4668
 * Returns the function returns SystemLiteral and in the second
4669
 *                case publicID receives PubidLiteral, is strict is off
4670
 *                it is possible to return NULL and have publicID set.
4671
 */
4672
4673
xmlChar *
4674
1.80M
xmlParseExternalID(xmlParserCtxtPtr ctxt, xmlChar **publicID, int strict) {
4675
1.80M
    xmlChar *URI = NULL;
4676
4677
1.80M
    SHRINK;
4678
4679
1.80M
    *publicID = NULL;
4680
1.80M
    if (CMP6(CUR_PTR, 'S', 'Y', 'S', 'T', 'E', 'M')) {
4681
10.4k
        SKIP(6);
4682
10.4k
  if (SKIP_BLANKS == 0) {
4683
2.88k
      xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4684
2.88k
                     "Space required after 'SYSTEM'\n");
4685
2.88k
  }
4686
10.4k
  URI = xmlParseSystemLiteral(ctxt);
4687
10.4k
  if (URI == NULL) {
4688
1.46k
      xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
4689
1.46k
        }
4690
1.79M
    } else if (CMP6(CUR_PTR, 'P', 'U', 'B', 'L', 'I', 'C')) {
4691
49.0k
        SKIP(6);
4692
49.0k
  if (SKIP_BLANKS == 0) {
4693
47.7k
      xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4694
47.7k
        "Space required after 'PUBLIC'\n");
4695
47.7k
  }
4696
49.0k
  *publicID = xmlParsePubidLiteral(ctxt);
4697
49.0k
  if (*publicID == NULL) {
4698
2.14k
      xmlFatalErr(ctxt, XML_ERR_PUBID_REQUIRED, NULL);
4699
2.14k
  }
4700
49.0k
  if (strict) {
4701
      /*
4702
       * We don't handle [83] so "S SystemLiteral" is required.
4703
       */
4704
4.50k
      if (SKIP_BLANKS == 0) {
4705
4.36k
    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4706
4.36k
      "Space required after the Public Identifier\n");
4707
4.36k
      }
4708
44.5k
  } else {
4709
      /*
4710
       * We handle [83] so we return immediately, if
4711
       * "S SystemLiteral" is not detected. We skip blanks if no
4712
             * system literal was found, but this is harmless since we must
4713
             * be at the end of a NotationDecl.
4714
       */
4715
44.5k
      if (SKIP_BLANKS == 0) return(NULL);
4716
17.1k
      if ((CUR != '\'') && (CUR != '"')) return(NULL);
4717
17.1k
  }
4718
13.2k
  URI = xmlParseSystemLiteral(ctxt);
4719
13.2k
  if (URI == NULL) {
4720
1.39k
      xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
4721
1.39k
        }
4722
13.2k
    }
4723
1.76M
    return(URI);
4724
1.80M
}
4725
4726
/**
4727
 * xmlParseCommentComplex:
4728
 * @ctxt:  an XML parser context
4729
 * @buf:  the already parsed part of the buffer
4730
 * @len:  number of bytes in the buffer
4731
 * @size:  allocated size of the buffer
4732
 *
4733
 * Skip an XML (SGML) comment <!-- .... -->
4734
 *  The spec says that "For compatibility, the string "--" (double-hyphen)
4735
 *  must not occur within comments. "
4736
 * This is the slow routine in case the accelerator for ascii didn't work
4737
 *
4738
 * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
4739
 */
4740
static void
4741
xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf,
4742
42.6k
                       size_t len, size_t size) {
4743
42.6k
    int q, ql;
4744
42.6k
    int r, rl;
4745
42.6k
    int cur, l;
4746
42.6k
    size_t count = 0;
4747
42.6k
    int inputid;
4748
4749
42.6k
    inputid = ctxt->input->id;
4750
4751
42.6k
    if (buf == NULL) {
4752
8.79k
        len = 0;
4753
8.79k
  size = XML_PARSER_BUFFER_SIZE;
4754
8.79k
  buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
4755
8.79k
  if (buf == NULL) {
4756
0
      xmlErrMemory(ctxt, NULL);
4757
0
      return;
4758
0
  }
4759
8.79k
    }
4760
42.6k
    GROW; /* Assure there's enough input data */
4761
42.6k
    q = CUR_CHAR(ql);
4762
42.6k
    if (q == 0)
4763
7.52k
        goto not_terminated;
4764
35.1k
    if (!IS_CHAR(q)) {
4765
563
        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
4766
563
                          "xmlParseComment: invalid xmlChar value %d\n",
4767
563
                    q);
4768
563
  xmlFree (buf);
4769
563
  return;
4770
563
    }
4771
34.6k
    NEXTL(ql);
4772
34.6k
    r = CUR_CHAR(rl);
4773
34.6k
    if (r == 0)
4774
2.11k
        goto not_terminated;
4775
32.4k
    if (!IS_CHAR(r)) {
4776
616
        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
4777
616
                          "xmlParseComment: invalid xmlChar value %d\n",
4778
616
                    q);
4779
616
  xmlFree (buf);
4780
616
  return;
4781
616
    }
4782
31.8k
    NEXTL(rl);
4783
31.8k
    cur = CUR_CHAR(l);
4784
31.8k
    if (cur == 0)
4785
787
        goto not_terminated;
4786
147M
    while (IS_CHAR(cur) && /* checked */
4787
147M
           ((cur != '>') ||
4788
147M
      (r != '-') || (q != '-'))) {
4789
147M
  if ((r == '-') && (q == '-')) {
4790
55.2k
      xmlFatalErr(ctxt, XML_ERR_HYPHEN_IN_COMMENT, NULL);
4791
55.2k
  }
4792
147M
        if ((len > XML_MAX_TEXT_LENGTH) &&
4793
147M
            ((ctxt->options & XML_PARSE_HUGE) == 0)) {
4794
0
            xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
4795
0
                         "Comment too big found", NULL);
4796
0
            xmlFree (buf);
4797
0
            return;
4798
0
        }
4799
147M
  if (len + 5 >= size) {
4800
30.6k
      xmlChar *new_buf;
4801
30.6k
            size_t new_size;
4802
4803
30.6k
      new_size = size * 2;
4804
30.6k
      new_buf = (xmlChar *) xmlRealloc(buf, new_size);
4805
30.6k
      if (new_buf == NULL) {
4806
0
    xmlFree (buf);
4807
0
    xmlErrMemory(ctxt, NULL);
4808
0
    return;
4809
0
      }
4810
30.6k
      buf = new_buf;
4811
30.6k
            size = new_size;
4812
30.6k
  }
4813
147M
  COPY_BUF(ql,buf,len,q);
4814
147M
  q = r;
4815
147M
  ql = rl;
4816
147M
  r = cur;
4817
147M
  rl = l;
4818
4819
147M
  count++;
4820
147M
  if (count > 50) {
4821
2.88M
      SHRINK;
4822
2.88M
      GROW;
4823
2.88M
      count = 0;
4824
2.88M
            if (ctxt->instate == XML_PARSER_EOF) {
4825
0
    xmlFree(buf);
4826
0
    return;
4827
0
            }
4828
2.88M
  }
4829
147M
  NEXTL(l);
4830
147M
  cur = CUR_CHAR(l);
4831
147M
  if (cur == 0) {
4832
25.4k
      SHRINK;
4833
25.4k
      GROW;
4834
25.4k
      cur = CUR_CHAR(l);
4835
25.4k
  }
4836
147M
    }
4837
31.0k
    buf[len] = 0;
4838
31.0k
    if (cur == 0) {
4839
14.5k
  xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
4840
14.5k
                       "Comment not terminated \n<!--%.50s\n", buf);
4841
16.5k
    } else if (!IS_CHAR(cur)) {
4842
1.44k
        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
4843
1.44k
                          "xmlParseComment: invalid xmlChar value %d\n",
4844
1.44k
                    cur);
4845
15.1k
    } else {
4846
15.1k
  if (inputid != ctxt->input->id) {
4847
0
      xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
4848
0
               "Comment doesn't start and stop in the same"
4849
0
                           " entity\n");
4850
0
  }
4851
15.1k
        NEXT;
4852
15.1k
  if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
4853
15.1k
      (!ctxt->disableSAX))
4854
1.17k
      ctxt->sax->comment(ctxt->userData, buf);
4855
15.1k
    }
4856
31.0k
    xmlFree(buf);
4857
31.0k
    return;
4858
10.4k
not_terminated:
4859
10.4k
    xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
4860
10.4k
       "Comment not terminated\n", NULL);
4861
10.4k
    xmlFree(buf);
4862
10.4k
    return;
4863
31.0k
}
4864
4865
/**
4866
 * xmlParseComment:
4867
 * @ctxt:  an XML parser context
4868
 *
4869
 * Skip an XML (SGML) comment <!-- .... -->
4870
 *  The spec says that "For compatibility, the string "--" (double-hyphen)
4871
 *  must not occur within comments. "
4872
 *
4873
 * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
4874
 */
4875
void
4876
55.7k
xmlParseComment(xmlParserCtxtPtr ctxt) {
4877
55.7k
    xmlChar *buf = NULL;
4878
55.7k
    size_t size = XML_PARSER_BUFFER_SIZE;
4879
55.7k
    size_t len = 0;
4880
55.7k
    xmlParserInputState state;
4881
55.7k
    const xmlChar *in;
4882
55.7k
    size_t nbchar = 0;
4883
55.7k
    int ccol;
4884
55.7k
    int inputid;
4885
4886
    /*
4887
     * Check that there is a comment right here.
4888
     */
4889
55.7k
    if ((RAW != '<') || (NXT(1) != '!') ||
4890
55.7k
        (NXT(2) != '-') || (NXT(3) != '-')) return;
4891
54.0k
    state = ctxt->instate;
4892
54.0k
    ctxt->instate = XML_PARSER_COMMENT;
4893
54.0k
    inputid = ctxt->input->id;
4894
54.0k
    SKIP(4);
4895
54.0k
    SHRINK;
4896
54.0k
    GROW;
4897
4898
    /*
4899
     * Accelerated common case where input don't need to be
4900
     * modified before passing it to the handler.
4901
     */
4902
54.0k
    in = ctxt->input->cur;
4903
54.3k
    do {
4904
54.3k
  if (*in == 0xA) {
4905
24.5k
      do {
4906
24.5k
    ctxt->input->line++; ctxt->input->col = 1;
4907
24.5k
    in++;
4908
24.5k
      } while (*in == 0xA);
4909
18.7k
  }
4910
95.6k
get_more:
4911
95.6k
        ccol = ctxt->input->col;
4912
346k
  while (((*in > '-') && (*in <= 0x7F)) ||
4913
346k
         ((*in >= 0x20) && (*in < '-')) ||
4914
346k
         (*in == 0x09)) {
4915
250k
        in++;
4916
250k
        ccol++;
4917
250k
  }
4918
95.6k
  ctxt->input->col = ccol;
4919
95.6k
  if (*in == 0xA) {
4920
7.74k
      do {
4921
7.74k
    ctxt->input->line++; ctxt->input->col = 1;
4922
7.74k
    in++;
4923
7.74k
      } while (*in == 0xA);
4924
4.88k
      goto get_more;
4925
4.88k
  }
4926
90.7k
  nbchar = in - ctxt->input->cur;
4927
  /*
4928
   * save current set of data
4929
   */
4930
90.7k
  if (nbchar > 0) {
4931
74.2k
      if ((ctxt->sax != NULL) &&
4932
74.2k
    (ctxt->sax->comment != NULL)) {
4933
74.2k
    if (buf == NULL) {
4934
43.0k
        if ((*in == '-') && (in[1] == '-'))
4935
13.1k
            size = nbchar + 1;
4936
29.8k
        else
4937
29.8k
            size = XML_PARSER_BUFFER_SIZE + nbchar;
4938
43.0k
        buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
4939
43.0k
        if (buf == NULL) {
4940
0
            xmlErrMemory(ctxt, NULL);
4941
0
      ctxt->instate = state;
4942
0
      return;
4943
0
        }
4944
43.0k
        len = 0;
4945
43.0k
    } else if (len + nbchar + 1 >= size) {
4946
4.85k
        xmlChar *new_buf;
4947
4.85k
        size  += len + nbchar + XML_PARSER_BUFFER_SIZE;
4948
4.85k
        new_buf = (xmlChar *) xmlRealloc(buf,
4949
4.85k
                                         size * sizeof(xmlChar));
4950
4.85k
        if (new_buf == NULL) {
4951
0
            xmlFree (buf);
4952
0
      xmlErrMemory(ctxt, NULL);
4953
0
      ctxt->instate = state;
4954
0
      return;
4955
0
        }
4956
4.85k
        buf = new_buf;
4957
4.85k
    }
4958
74.2k
    memcpy(&buf[len], ctxt->input->cur, nbchar);
4959
74.2k
    len += nbchar;
4960
74.2k
    buf[len] = 0;
4961
74.2k
      }
4962
74.2k
  }
4963
90.7k
        if ((len > XML_MAX_TEXT_LENGTH) &&
4964
90.7k
            ((ctxt->options & XML_PARSE_HUGE) == 0)) {
4965
0
            xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
4966
0
                         "Comment too big found", NULL);
4967
0
            xmlFree (buf);
4968
0
            return;
4969
0
        }
4970
90.7k
  ctxt->input->cur = in;
4971
90.7k
  if (*in == 0xA) {
4972
0
      in++;
4973
0
      ctxt->input->line++; ctxt->input->col = 1;
4974
0
  }
4975
90.7k
  if (*in == 0xD) {
4976
2.14k
      in++;
4977
2.14k
      if (*in == 0xA) {
4978
794
    ctxt->input->cur = in;
4979
794
    in++;
4980
794
    ctxt->input->line++; ctxt->input->col = 1;
4981
794
    goto get_more;
4982
794
      }
4983
1.35k
      in--;
4984
1.35k
  }
4985
90.0k
  SHRINK;
4986
90.0k
  GROW;
4987
90.0k
        if (ctxt->instate == XML_PARSER_EOF) {
4988
0
            xmlFree(buf);
4989
0
            return;
4990
0
        }
4991
90.0k
  in = ctxt->input->cur;
4992
90.0k
  if (*in == '-') {
4993
46.9k
      if (in[1] == '-') {
4994
34.3k
          if (in[2] == '>') {
4995
11.3k
        if (ctxt->input->id != inputid) {
4996
0
      xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
4997
0
                     "comment doesn't start and stop in the"
4998
0
                                       " same entity\n");
4999
0
        }
5000
11.3k
        SKIP(3);
5001
11.3k
        if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
5002
11.3k
            (!ctxt->disableSAX)) {
5003
3.33k
      if (buf != NULL)
5004
1.17k
          ctxt->sax->comment(ctxt->userData, buf);
5005
2.16k
      else
5006
2.16k
          ctxt->sax->comment(ctxt->userData, BAD_CAST "");
5007
3.33k
        }
5008
11.3k
        if (buf != NULL)
5009
9.14k
            xmlFree(buf);
5010
11.3k
        if (ctxt->instate != XML_PARSER_EOF)
5011
11.3k
      ctxt->instate = state;
5012
11.3k
        return;
5013
11.3k
    }
5014
22.9k
    if (buf != NULL) {
5015
18.0k
        xmlFatalErrMsgStr(ctxt, XML_ERR_HYPHEN_IN_COMMENT,
5016
18.0k
                          "Double hyphen within comment: "
5017
18.0k
                                      "<!--%.50s\n",
5018
18.0k
              buf);
5019
18.0k
    } else
5020
4.84k
        xmlFatalErrMsgStr(ctxt, XML_ERR_HYPHEN_IN_COMMENT,
5021
4.84k
                          "Double hyphen within comment\n", NULL);
5022
22.9k
                if (ctxt->instate == XML_PARSER_EOF) {
5023
0
                    xmlFree(buf);
5024
0
                    return;
5025
0
                }
5026
22.9k
    in++;
5027
22.9k
    ctxt->input->col++;
5028
22.9k
      }
5029
35.6k
      in++;
5030
35.6k
      ctxt->input->col++;
5031
35.6k
      goto get_more;
5032
46.9k
  }
5033
90.0k
    } while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09) || (*in == 0x0a));
5034
42.6k
    xmlParseCommentComplex(ctxt, buf, len, size);
5035
42.6k
    ctxt->instate = state;
5036
42.6k
    return;
5037
54.0k
}
5038
5039
5040
/**
5041
 * xmlParsePITarget:
5042
 * @ctxt:  an XML parser context
5043
 *
5044
 * parse the name of a PI
5045
 *
5046
 * [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
5047
 *
5048
 * Returns the PITarget name or NULL
5049
 */
5050
5051
const xmlChar *
5052
842k
xmlParsePITarget(xmlParserCtxtPtr ctxt) {
5053
842k
    const xmlChar *name;
5054
5055
842k
    name = xmlParseName(ctxt);
5056
842k
    if ((name != NULL) &&
5057
842k
        ((name[0] == 'x') || (name[0] == 'X')) &&
5058
842k
        ((name[1] == 'm') || (name[1] == 'M')) &&
5059
842k
        ((name[2] == 'l') || (name[2] == 'L'))) {
5060
16.5k
  int i;
5061
16.5k
  if ((name[0] == 'x') && (name[1] == 'm') &&
5062
16.5k
      (name[2] == 'l') && (name[3] == 0)) {
5063
6.32k
      xmlFatalErrMsg(ctxt, XML_ERR_RESERVED_XML_NAME,
5064
6.32k
     "XML declaration allowed only at the start of the document\n");
5065
6.32k
      return(name);
5066
10.2k
  } else if (name[3] == 0) {
5067
2.61k
      xmlFatalErr(ctxt, XML_ERR_RESERVED_XML_NAME, NULL);
5068
2.61k
      return(name);
5069
2.61k
  }
5070
20.1k
  for (i = 0;;i++) {
5071
20.1k
      if (xmlW3CPIs[i] == NULL) break;
5072
15.3k
      if (xmlStrEqual(name, (const xmlChar *)xmlW3CPIs[i]))
5073
2.79k
          return(name);
5074
15.3k
  }
5075
4.86k
  xmlWarningMsg(ctxt, XML_ERR_RESERVED_XML_NAME,
5076
4.86k
          "xmlParsePITarget: invalid name prefix 'xml'\n",
5077
4.86k
          NULL, NULL);
5078
4.86k
    }
5079
830k
    if ((name != NULL) && (xmlStrchr(name, ':') != NULL)) {
5080
2.96k
  xmlNsErr(ctxt, XML_NS_ERR_COLON,
5081
2.96k
     "colons are forbidden from PI names '%s'\n", name, NULL, NULL);
5082
2.96k
    }
5083
830k
    return(name);
5084
842k
}
5085
5086
#ifdef LIBXML_CATALOG_ENABLED
5087
/**
5088
 * xmlParseCatalogPI:
5089
 * @ctxt:  an XML parser context
5090
 * @catalog:  the PI value string
5091
 *
5092
 * parse an XML Catalog Processing Instruction.
5093
 *
5094
 * <?oasis-xml-catalog catalog="http://example.com/catalog.xml"?>
5095
 *
5096
 * Occurs only if allowed by the user and if happening in the Misc
5097
 * part of the document before any doctype information
5098
 * This will add the given catalog to the parsing context in order
5099
 * to be used if there is a resolution need further down in the document
5100
 */
5101
5102
static void
5103
4.40k
xmlParseCatalogPI(xmlParserCtxtPtr ctxt, const xmlChar *catalog) {
5104
4.40k
    xmlChar *URL = NULL;
5105
4.40k
    const xmlChar *tmp, *base;
5106
4.40k
    xmlChar marker;
5107
5108
4.40k
    tmp = catalog;
5109
4.40k
    while (IS_BLANK_CH(*tmp)) tmp++;
5110
4.40k
    if (xmlStrncmp(tmp, BAD_CAST"catalog", 7))
5111
739
  goto error;
5112
3.66k
    tmp += 7;
5113
3.66k
    while (IS_BLANK_CH(*tmp)) tmp++;
5114
3.66k
    if (*tmp != '=') {
5115
2.25k
  return;
5116
2.25k
    }
5117
1.40k
    tmp++;
5118
1.40k
    while (IS_BLANK_CH(*tmp)) tmp++;
5119
1.40k
    marker = *tmp;
5120
1.40k
    if ((marker != '\'') && (marker != '"'))
5121
418
  goto error;
5122
989
    tmp++;
5123
989
    base = tmp;
5124
2.40k
    while ((*tmp != 0) && (*tmp != marker)) tmp++;
5125
989
    if (*tmp == 0)
5126
376
  goto error;
5127
613
    URL = xmlStrndup(base, tmp - base);
5128
613
    tmp++;
5129
829
    while (IS_BLANK_CH(*tmp)) tmp++;
5130
613
    if (*tmp != 0)
5131
229
  goto error;
5132
5133
384
    if (URL != NULL) {
5134
384
  ctxt->catalogs = xmlCatalogAddLocal(ctxt->catalogs, URL);
5135
384
  xmlFree(URL);
5136
384
    }
5137
384
    return;
5138
5139
1.76k
error:
5140
1.76k
    xmlWarningMsg(ctxt, XML_WAR_CATALOG_PI,
5141
1.76k
            "Catalog PI syntax error: %s\n",
5142
1.76k
      catalog, NULL);
5143
1.76k
    if (URL != NULL)
5144
229
  xmlFree(URL);
5145
1.76k
}
5146
#endif
5147
5148
/**
5149
 * xmlParsePI:
5150
 * @ctxt:  an XML parser context
5151
 *
5152
 * parse an XML Processing Instruction.
5153
 *
5154
 * [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
5155
 *
5156
 * The processing is transferred to SAX once parsed.
5157
 */
5158
5159
void
5160
842k
xmlParsePI(xmlParserCtxtPtr ctxt) {
5161
842k
    xmlChar *buf = NULL;
5162
842k
    size_t len = 0;
5163
842k
    size_t size = XML_PARSER_BUFFER_SIZE;
5164
842k
    int cur, l;
5165
842k
    const xmlChar *target;
5166
842k
    xmlParserInputState state;
5167
842k
    int count = 0;
5168
5169
842k
    if ((RAW == '<') && (NXT(1) == '?')) {
5170
842k
  int inputid = ctxt->input->id;
5171
842k
  state = ctxt->instate;
5172
842k
        ctxt->instate = XML_PARSER_PI;
5173
  /*
5174
   * this is a Processing Instruction.
5175
   */
5176
842k
  SKIP(2);
5177
842k
  SHRINK;
5178
5179
  /*
5180
   * Parse the target name and check for special support like
5181
   * namespace.
5182
   */
5183
842k
        target = xmlParsePITarget(ctxt);
5184
842k
  if (target != NULL) {
5185
96.1k
      if ((RAW == '?') && (NXT(1) == '>')) {
5186
8.46k
    if (inputid != ctxt->input->id) {
5187
0
        xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
5188
0
                             "PI declaration doesn't start and stop in"
5189
0
                                   " the same entity\n");
5190
0
    }
5191
8.46k
    SKIP(2);
5192
5193
    /*
5194
     * SAX: PI detected.
5195
     */
5196
8.46k
    if ((ctxt->sax) && (!ctxt->disableSAX) &&
5197
8.46k
        (ctxt->sax->processingInstruction != NULL))
5198
2.85k
        ctxt->sax->processingInstruction(ctxt->userData,
5199
2.85k
                                         target, NULL);
5200
8.46k
    if (ctxt->instate != XML_PARSER_EOF)
5201
8.46k
        ctxt->instate = state;
5202
8.46k
    return;
5203
8.46k
      }
5204
87.7k
      buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
5205
87.7k
      if (buf == NULL) {
5206
0
    xmlErrMemory(ctxt, NULL);
5207
0
    ctxt->instate = state;
5208
0
    return;
5209
0
      }
5210
87.7k
      if (SKIP_BLANKS == 0) {
5211
16.0k
    xmlFatalErrMsgStr(ctxt, XML_ERR_SPACE_REQUIRED,
5212
16.0k
        "ParsePI: PI %s space expected\n", target);
5213
16.0k
      }
5214
87.7k
      cur = CUR_CHAR(l);
5215
175M
      while (IS_CHAR(cur) && /* checked */
5216
175M
       ((cur != '?') || (NXT(1) != '>'))) {
5217
175M
    if (len + 5 >= size) {
5218
15.5k
        xmlChar *tmp;
5219
15.5k
                    size_t new_size = size * 2;
5220
15.5k
        tmp = (xmlChar *) xmlRealloc(buf, new_size);
5221
15.5k
        if (tmp == NULL) {
5222
0
      xmlErrMemory(ctxt, NULL);
5223
0
      xmlFree(buf);
5224
0
      ctxt->instate = state;
5225
0
      return;
5226
0
        }
5227
15.5k
        buf = tmp;
5228
15.5k
                    size = new_size;
5229
15.5k
    }
5230
175M
    count++;
5231
175M
    if (count > 50) {
5232
3.41M
        SHRINK;
5233
3.41M
        GROW;
5234
3.41M
                    if (ctxt->instate == XML_PARSER_EOF) {
5235
0
                        xmlFree(buf);
5236
0
                        return;
5237
0
                    }
5238
3.41M
        count = 0;
5239
3.41M
                    if ((len > XML_MAX_TEXT_LENGTH) &&
5240
3.41M
                        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
5241
0
                        xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
5242
0
                                          "PI %s too big found", target);
5243
0
                        xmlFree(buf);
5244
0
                        ctxt->instate = state;
5245
0
                        return;
5246
0
                    }
5247
3.41M
    }
5248
175M
    COPY_BUF(l,buf,len,cur);
5249
175M
    NEXTL(l);
5250
175M
    cur = CUR_CHAR(l);
5251
175M
    if (cur == 0) {
5252
39.3k
        SHRINK;
5253
39.3k
        GROW;
5254
39.3k
        cur = CUR_CHAR(l);
5255
39.3k
    }
5256
175M
      }
5257
87.7k
            if ((len > XML_MAX_TEXT_LENGTH) &&
5258
87.7k
                ((ctxt->options & XML_PARSE_HUGE) == 0)) {
5259
0
                xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
5260
0
                                  "PI %s too big found", target);
5261
0
                xmlFree(buf);
5262
0
                ctxt->instate = state;
5263
0
                return;
5264
0
            }
5265
87.7k
      buf[len] = 0;
5266
87.7k
      if (cur != '?') {
5267
26.9k
    xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
5268
26.9k
          "ParsePI: PI %s never end ...\n", target);
5269
60.7k
      } else {
5270
60.7k
    if (inputid != ctxt->input->id) {
5271
48.1k
        xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
5272
48.1k
                             "PI declaration doesn't start and stop in"
5273
48.1k
                                   " the same entity\n");
5274
48.1k
    }
5275
60.7k
    SKIP(2);
5276
5277
60.7k
#ifdef LIBXML_CATALOG_ENABLED
5278
60.7k
    if (((state == XML_PARSER_MISC) ||
5279
60.7k
               (state == XML_PARSER_START)) &&
5280
60.7k
        (xmlStrEqual(target, XML_CATALOG_PI))) {
5281
4.40k
        xmlCatalogAllow allow = xmlCatalogGetDefaults();
5282
4.40k
        if ((allow == XML_CATA_ALLOW_DOCUMENT) ||
5283
4.40k
      (allow == XML_CATA_ALLOW_ALL))
5284
4.40k
      xmlParseCatalogPI(ctxt, buf);
5285
4.40k
    }
5286
60.7k
#endif
5287
5288
5289
    /*
5290
     * SAX: PI detected.
5291
     */
5292
60.7k
    if ((ctxt->sax) && (!ctxt->disableSAX) &&
5293
60.7k
        (ctxt->sax->processingInstruction != NULL))
5294
2.31k
        ctxt->sax->processingInstruction(ctxt->userData,
5295
2.31k
                                         target, buf);
5296
60.7k
      }
5297
87.7k
      xmlFree(buf);
5298
746k
  } else {
5299
746k
      xmlFatalErr(ctxt, XML_ERR_PI_NOT_STARTED, NULL);
5300
746k
  }
5301
834k
  if (ctxt->instate != XML_PARSER_EOF)
5302
834k
      ctxt->instate = state;
5303
834k
    }
5304
842k
}
5305
5306
/**
5307
 * xmlParseNotationDecl:
5308
 * @ctxt:  an XML parser context
5309
 *
5310
 * parse a notation declaration
5311
 *
5312
 * [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID |  PublicID) S? '>'
5313
 *
5314
 * Hence there is actually 3 choices:
5315
 *     'PUBLIC' S PubidLiteral
5316
 *     'PUBLIC' S PubidLiteral S SystemLiteral
5317
 * and 'SYSTEM' S SystemLiteral
5318
 *
5319
 * See the NOTE on xmlParseExternalID().
5320
 */
5321
5322
void
5323
193k
xmlParseNotationDecl(xmlParserCtxtPtr ctxt) {
5324
193k
    const xmlChar *name;
5325
193k
    xmlChar *Pubid;
5326
193k
    xmlChar *Systemid;
5327
5328
193k
    if (CMP10(CUR_PTR, '<', '!', 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
5329
84.2k
  int inputid = ctxt->input->id;
5330
84.2k
  SHRINK;
5331
84.2k
  SKIP(10);
5332
84.2k
  if (SKIP_BLANKS == 0) {
5333
2.09k
      xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5334
2.09k
         "Space required after '<!NOTATION'\n");
5335
2.09k
      return;
5336
2.09k
  }
5337
5338
82.1k
        name = xmlParseName(ctxt);
5339
82.1k
  if (name == NULL) {
5340
3.46k
      xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
5341
3.46k
      return;
5342
3.46k
  }
5343
78.7k
  if (xmlStrchr(name, ':') != NULL) {
5344
3.74k
      xmlNsErr(ctxt, XML_NS_ERR_COLON,
5345
3.74k
         "colons are forbidden from notation names '%s'\n",
5346
3.74k
         name, NULL, NULL);
5347
3.74k
  }
5348
78.7k
  if (SKIP_BLANKS == 0) {
5349
13.8k
      xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5350
13.8k
         "Space required after the NOTATION name'\n");
5351
13.8k
      return;
5352
13.8k
  }
5353
5354
  /*
5355
   * Parse the IDs.
5356
   */
5357
64.8k
  Systemid = xmlParseExternalID(ctxt, &Pubid, 0);
5358
64.8k
  SKIP_BLANKS;
5359
5360
64.8k
  if (RAW == '>') {
5361
5.03k
      if (inputid != ctxt->input->id) {
5362
1.39k
    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
5363
1.39k
                         "Notation declaration doesn't start and stop"
5364
1.39k
                               " in the same entity\n");
5365
1.39k
      }
5366
5.03k
      NEXT;
5367
5.03k
      if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
5368
5.03k
    (ctxt->sax->notationDecl != NULL))
5369
109
    ctxt->sax->notationDecl(ctxt->userData, name, Pubid, Systemid);
5370
59.8k
  } else {
5371
59.8k
      xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
5372
59.8k
  }
5373
64.8k
  if (Systemid != NULL) xmlFree(Systemid);
5374
64.8k
  if (Pubid != NULL) xmlFree(Pubid);
5375
64.8k
    }
5376
193k
}
5377
5378
/**
5379
 * xmlParseEntityDecl:
5380
 * @ctxt:  an XML parser context
5381
 *
5382
 * parse <!ENTITY declarations
5383
 *
5384
 * [70] EntityDecl ::= GEDecl | PEDecl
5385
 *
5386
 * [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
5387
 *
5388
 * [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
5389
 *
5390
 * [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
5391
 *
5392
 * [74] PEDef ::= EntityValue | ExternalID
5393
 *
5394
 * [76] NDataDecl ::= S 'NDATA' S Name
5395
 *
5396
 * [ VC: Notation Declared ]
5397
 * The Name must match the declared name of a notation.
5398
 */
5399
5400
void
5401
4.17M
xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
5402
4.17M
    const xmlChar *name = NULL;
5403
4.17M
    xmlChar *value = NULL;
5404
4.17M
    xmlChar *URI = NULL, *literal = NULL;
5405
4.17M
    const xmlChar *ndata = NULL;
5406
4.17M
    int isParameter = 0;
5407
4.17M
    xmlChar *orig = NULL;
5408
5409
    /* GROW; done in the caller */
5410
4.17M
    if (CMP8(CUR_PTR, '<', '!', 'E', 'N', 'T', 'I', 'T', 'Y')) {
5411
4.16M
  int inputid = ctxt->input->id;
5412
4.16M
  SHRINK;
5413
4.16M
  SKIP(8);
5414
4.16M
  if (SKIP_BLANKS == 0) {
5415
1.73M
      xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5416
1.73M
         "Space required after '<!ENTITY'\n");
5417
1.73M
  }
5418
5419
4.16M
  if (RAW == '%') {
5420
10.4k
      NEXT;
5421
10.4k
      if (SKIP_BLANKS == 0) {
5422
4.46k
    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5423
4.46k
             "Space required after '%%'\n");
5424
4.46k
      }
5425
10.4k
      isParameter = 1;
5426
10.4k
  }
5427
5428
4.16M
        name = xmlParseName(ctxt);
5429
4.16M
  if (name == NULL) {
5430
2.39M
      xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
5431
2.39M
                     "xmlParseEntityDecl: no name\n");
5432
2.39M
            return;
5433
2.39M
  }
5434
1.76M
  if (xmlStrchr(name, ':') != NULL) {
5435
21.8k
      xmlNsErr(ctxt, XML_NS_ERR_COLON,
5436
21.8k
         "colons are forbidden from entities names '%s'\n",
5437
21.8k
         name, NULL, NULL);
5438
21.8k
  }
5439
1.76M
  if (SKIP_BLANKS == 0) {
5440
1.72M
      xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5441
1.72M
         "Space required after the entity name\n");
5442
1.72M
  }
5443
5444
1.76M
  ctxt->instate = XML_PARSER_ENTITY_DECL;
5445
  /*
5446
   * handle the various case of definitions...
5447
   */
5448
1.76M
  if (isParameter) {
5449
10.4k
      if ((RAW == '"') || (RAW == '\'')) {
5450
5.78k
          value = xmlParseEntityValue(ctxt, &orig);
5451
5.78k
    if (value) {
5452
5.12k
        if ((ctxt->sax != NULL) &&
5453
5.12k
      (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
5454
3.97k
      ctxt->sax->entityDecl(ctxt->userData, name,
5455
3.97k
                        XML_INTERNAL_PARAMETER_ENTITY,
5456
3.97k
            NULL, NULL, value);
5457
5.12k
    }
5458
5.78k
      } else {
5459
4.68k
          URI = xmlParseExternalID(ctxt, &literal, 1);
5460
4.68k
    if ((URI == NULL) && (literal == NULL)) {
5461
92
        xmlFatalErr(ctxt, XML_ERR_VALUE_REQUIRED, NULL);
5462
92
    }
5463
4.68k
    if (URI) {
5464
3.39k
        xmlURIPtr uri;
5465
5466
3.39k
        uri = xmlParseURI((const char *) URI);
5467
3.39k
        if (uri == NULL) {
5468
1.38k
            xmlErrMsgStr(ctxt, XML_ERR_INVALID_URI,
5469
1.38k
             "Invalid URI: %s\n", URI);
5470
      /*
5471
       * This really ought to be a well formedness error
5472
       * but the XML Core WG decided otherwise c.f. issue
5473
       * E26 of the XML erratas.
5474
       */
5475
2.00k
        } else {
5476
2.00k
      if (uri->fragment != NULL) {
5477
          /*
5478
           * Okay this is foolish to block those but not
5479
           * invalid URIs.
5480
           */
5481
862
          xmlFatalErr(ctxt, XML_ERR_URI_FRAGMENT, NULL);
5482
1.14k
      } else {
5483
1.14k
          if ((ctxt->sax != NULL) &&
5484
1.14k
        (!ctxt->disableSAX) &&
5485
1.14k
        (ctxt->sax->entityDecl != NULL))
5486
318
        ctxt->sax->entityDecl(ctxt->userData, name,
5487
318
              XML_EXTERNAL_PARAMETER_ENTITY,
5488
318
              literal, URI, NULL);
5489
1.14k
      }
5490
2.00k
      xmlFreeURI(uri);
5491
2.00k
        }
5492
3.39k
    }
5493
4.68k
      }
5494
1.75M
  } else {
5495
1.75M
      if ((RAW == '"') || (RAW == '\'')) {
5496
33.5k
          value = xmlParseEntityValue(ctxt, &orig);
5497
33.5k
    if ((ctxt->sax != NULL) &&
5498
33.5k
        (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
5499
5.17k
        ctxt->sax->entityDecl(ctxt->userData, name,
5500
5.17k
        XML_INTERNAL_GENERAL_ENTITY,
5501
5.17k
        NULL, NULL, value);
5502
    /*
5503
     * For expat compatibility in SAX mode.
5504
     */
5505
33.5k
    if ((ctxt->myDoc == NULL) ||
5506
33.5k
        (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) {
5507
1.58k
        if (ctxt->myDoc == NULL) {
5508
249
      ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
5509
249
      if (ctxt->myDoc == NULL) {
5510
0
          xmlErrMemory(ctxt, "New Doc failed");
5511
0
          return;
5512
0
      }
5513
249
      ctxt->myDoc->properties = XML_DOC_INTERNAL;
5514
249
        }
5515
1.58k
        if (ctxt->myDoc->intSubset == NULL)
5516
249
      ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
5517
249
              BAD_CAST "fake", NULL, NULL);
5518
5519
1.58k
        xmlSAX2EntityDecl(ctxt, name, XML_INTERNAL_GENERAL_ENTITY,
5520
1.58k
                    NULL, NULL, value);
5521
1.58k
    }
5522
1.72M
      } else {
5523
1.72M
          URI = xmlParseExternalID(ctxt, &literal, 1);
5524
1.72M
    if ((URI == NULL) && (literal == NULL)) {
5525
1.71M
        xmlFatalErr(ctxt, XML_ERR_VALUE_REQUIRED, NULL);
5526
1.71M
    }
5527
1.72M
    if (URI) {
5528
5.57k
        xmlURIPtr uri;
5529
5530
5.57k
        uri = xmlParseURI((const char *)URI);
5531
5.57k
        if (uri == NULL) {
5532
2.75k
            xmlErrMsgStr(ctxt, XML_ERR_INVALID_URI,
5533
2.75k
             "Invalid URI: %s\n", URI);
5534
      /*
5535
       * This really ought to be a well formedness error
5536
       * but the XML Core WG decided otherwise c.f. issue
5537
       * E26 of the XML erratas.
5538
       */
5539
2.82k
        } else {
5540
2.82k
      if (uri->fragment != NULL) {
5541
          /*
5542
           * Okay this is foolish to block those but not
5543
           * invalid URIs.
5544
           */
5545
202
          xmlFatalErr(ctxt, XML_ERR_URI_FRAGMENT, NULL);
5546
202
      }
5547
2.82k
      xmlFreeURI(uri);
5548
2.82k
        }
5549
5.57k
    }
5550
1.72M
    if ((RAW != '>') && (SKIP_BLANKS == 0)) {
5551
218
        xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5552
218
           "Space required before 'NDATA'\n");
5553
218
    }
5554
1.72M
    if (CMP5(CUR_PTR, 'N', 'D', 'A', 'T', 'A')) {
5555
657
        SKIP(5);
5556
657
        if (SKIP_BLANKS == 0) {
5557
73
      xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5558
73
               "Space required after 'NDATA'\n");
5559
73
        }
5560
657
        ndata = xmlParseName(ctxt);
5561
657
        if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
5562
657
            (ctxt->sax->unparsedEntityDecl != NULL))
5563
382
      ctxt->sax->unparsedEntityDecl(ctxt->userData, name,
5564
382
            literal, URI, ndata);
5565
1.72M
    } else {
5566
1.72M
        if ((ctxt->sax != NULL) &&
5567
1.72M
            (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
5568
1.67k
      ctxt->sax->entityDecl(ctxt->userData, name,
5569
1.67k
            XML_EXTERNAL_GENERAL_PARSED_ENTITY,
5570
1.67k
            literal, URI, NULL);
5571
        /*
5572
         * For expat compatibility in SAX mode.
5573
         * assuming the entity replacement was asked for
5574
         */
5575
1.72M
        if ((ctxt->replaceEntities != 0) &&
5576
1.72M
      ((ctxt->myDoc == NULL) ||
5577
0
      (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE)))) {
5578
0
      if (ctxt->myDoc == NULL) {
5579
0
          ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
5580
0
          if (ctxt->myDoc == NULL) {
5581
0
              xmlErrMemory(ctxt, "New Doc failed");
5582
0
        return;
5583
0
          }
5584
0
          ctxt->myDoc->properties = XML_DOC_INTERNAL;
5585
0
      }
5586
5587
0
      if (ctxt->myDoc->intSubset == NULL)
5588
0
          ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
5589
0
            BAD_CAST "fake", NULL, NULL);
5590
0
      xmlSAX2EntityDecl(ctxt, name,
5591
0
                  XML_EXTERNAL_GENERAL_PARSED_ENTITY,
5592
0
                  literal, URI, NULL);
5593
0
        }
5594
1.72M
    }
5595
1.72M
      }
5596
1.75M
  }
5597
1.76M
  if (ctxt->instate == XML_PARSER_EOF)
5598
0
      goto done;
5599
1.76M
  SKIP_BLANKS;
5600
1.76M
  if (RAW != '>') {
5601
984
      xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_NOT_FINISHED,
5602
984
              "xmlParseEntityDecl: entity %s not terminated\n", name);
5603
984
      xmlHaltParser(ctxt);
5604
1.76M
  } else {
5605
1.76M
      if (inputid != ctxt->input->id) {
5606
3.14k
    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
5607
3.14k
                         "Entity declaration doesn't start and stop in"
5608
3.14k
                               " the same entity\n");
5609
3.14k
      }
5610
1.76M
      NEXT;
5611
1.76M
  }
5612
1.76M
  if (orig != NULL) {
5613
      /*
5614
       * Ugly mechanism to save the raw entity value.
5615
       */
5616
31.9k
      xmlEntityPtr cur = NULL;
5617
5618
31.9k
      if (isParameter) {
5619
5.64k
          if ((ctxt->sax != NULL) &&
5620
5.64k
        (ctxt->sax->getParameterEntity != NULL))
5621
5.64k
        cur = ctxt->sax->getParameterEntity(ctxt->userData, name);
5622
26.3k
      } else {
5623
26.3k
          if ((ctxt->sax != NULL) &&
5624
26.3k
        (ctxt->sax->getEntity != NULL))
5625
26.3k
        cur = ctxt->sax->getEntity(ctxt->userData, name);
5626
26.3k
    if ((cur == NULL) && (ctxt->userData==ctxt)) {
5627
18.6k
        cur = xmlSAX2GetEntity(ctxt, name);
5628
18.6k
    }
5629
26.3k
      }
5630
31.9k
            if ((cur != NULL) && (cur->orig == NULL)) {
5631
7.64k
    cur->orig = orig;
5632
7.64k
                orig = NULL;
5633
7.64k
      }
5634
31.9k
  }
5635
5636
1.76M
done:
5637
1.76M
  if (value != NULL) xmlFree(value);
5638
1.76M
  if (URI != NULL) xmlFree(URI);
5639
1.76M
  if (literal != NULL) xmlFree(literal);
5640
1.76M
        if (orig != NULL) xmlFree(orig);
5641
1.76M
    }
5642
4.17M
}
5643
5644
/**
5645
 * xmlParseDefaultDecl:
5646
 * @ctxt:  an XML parser context
5647
 * @value:  Receive a possible fixed default value for the attribute
5648
 *
5649
 * Parse an attribute default declaration
5650
 *
5651
 * [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)
5652
 *
5653
 * [ VC: Required Attribute ]
5654
 * if the default declaration is the keyword #REQUIRED, then the
5655
 * attribute must be specified for all elements of the type in the
5656
 * attribute-list declaration.
5657
 *
5658
 * [ VC: Attribute Default Legal ]
5659
 * The declared default value must meet the lexical constraints of
5660
 * the declared attribute type c.f. xmlValidateAttributeDecl()
5661
 *
5662
 * [ VC: Fixed Attribute Default ]
5663
 * if an attribute has a default value declared with the #FIXED
5664
 * keyword, instances of that attribute must match the default value.
5665
 *
5666
 * [ WFC: No < in Attribute Values ]
5667
 * handled in xmlParseAttValue()
5668
 *
5669
 * returns: XML_ATTRIBUTE_NONE, XML_ATTRIBUTE_REQUIRED, XML_ATTRIBUTE_IMPLIED
5670
 *          or XML_ATTRIBUTE_FIXED.
5671
 */
5672
5673
int
5674
818k
xmlParseDefaultDecl(xmlParserCtxtPtr ctxt, xmlChar **value) {
5675
818k
    int val;
5676
818k
    xmlChar *ret;
5677
5678
818k
    *value = NULL;
5679
818k
    if (CMP9(CUR_PTR, '#', 'R', 'E', 'Q', 'U', 'I', 'R', 'E', 'D')) {
5680
544
  SKIP(9);
5681
544
  return(XML_ATTRIBUTE_REQUIRED);
5682
544
    }
5683
817k
    if (CMP8(CUR_PTR, '#', 'I', 'M', 'P', 'L', 'I', 'E', 'D')) {
5684
862
  SKIP(8);
5685
862
  return(XML_ATTRIBUTE_IMPLIED);
5686
862
    }
5687
817k
    val = XML_ATTRIBUTE_NONE;
5688
817k
    if (CMP6(CUR_PTR, '#', 'F', 'I', 'X', 'E', 'D')) {
5689
1.50k
  SKIP(6);
5690
1.50k
  val = XML_ATTRIBUTE_FIXED;
5691
1.50k
  if (SKIP_BLANKS == 0) {
5692
750
      xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5693
750
         "Space required after '#FIXED'\n");
5694
750
  }
5695
1.50k
    }
5696
817k
    ret = xmlParseAttValue(ctxt);
5697
817k
    ctxt->instate = XML_PARSER_DTD;
5698
817k
    if (ret == NULL) {
5699
759k
  xmlFatalErrMsg(ctxt, (xmlParserErrors)ctxt->errNo,
5700
759k
           "Attribute default value declaration error\n");
5701
759k
    } else
5702
57.8k
        *value = ret;
5703
817k
    return(val);
5704
817k
}
5705
5706
/**
5707
 * xmlParseNotationType:
5708
 * @ctxt:  an XML parser context
5709
 *
5710
 * parse an Notation attribute type.
5711
 *
5712
 * Note: the leading 'NOTATION' S part has already being parsed...
5713
 *
5714
 * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
5715
 *
5716
 * [ VC: Notation Attributes ]
5717
 * Values of this type must match one of the notation names included
5718
 * in the declaration; all notation names in the declaration must be declared.
5719
 *
5720
 * Returns: the notation attribute tree built while parsing
5721
 */
5722
5723
xmlEnumerationPtr
5724
13.5k
xmlParseNotationType(xmlParserCtxtPtr ctxt) {
5725
13.5k
    const xmlChar *name;
5726
13.5k
    xmlEnumerationPtr ret = NULL, last = NULL, cur, tmp;
5727
5728
13.5k
    if (RAW != '(') {
5729
2.13k
  xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
5730
2.13k
  return(NULL);
5731
2.13k
    }
5732
11.4k
    SHRINK;
5733
12.5k
    do {
5734
12.5k
        NEXT;
5735
12.5k
  SKIP_BLANKS;
5736
12.5k
        name = xmlParseName(ctxt);
5737
12.5k
  if (name == NULL) {
5738
2.13k
      xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
5739
2.13k
         "Name expected in NOTATION declaration\n");
5740
2.13k
            xmlFreeEnumeration(ret);
5741
2.13k
      return(NULL);
5742
2.13k
  }
5743
10.4k
  tmp = ret;
5744
13.3k
  while (tmp != NULL) {
5745
3.53k
      if (xmlStrEqual(name, tmp->name)) {
5746
593
    xmlValidityError(ctxt, XML_DTD_DUP_TOKEN,
5747
593
    "standalone: attribute notation value token %s duplicated\n",
5748
593
         name, NULL);
5749
593
    if (!xmlDictOwns(ctxt->dict, name))
5750
0
        xmlFree((xmlChar *) name);
5751
593
    break;
5752
593
      }
5753
2.93k
      tmp = tmp->next;
5754
2.93k
  }
5755
10.4k
  if (tmp == NULL) {
5756
9.81k
      cur = xmlCreateEnumeration(name);
5757
9.81k
      if (cur == NULL) {
5758
0
                xmlFreeEnumeration(ret);
5759
0
                return(NULL);
5760
0
            }
5761
9.81k
      if (last == NULL) ret = last = cur;
5762
456
      else {
5763
456
    last->next = cur;
5764
456
    last = cur;
5765
456
      }
5766
9.81k
  }
5767
10.4k
  SKIP_BLANKS;
5768
10.4k
    } while (RAW == '|');
5769
9.31k
    if (RAW != ')') {
5770
6.29k
  xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
5771
6.29k
        xmlFreeEnumeration(ret);
5772
6.29k
  return(NULL);
5773
6.29k
    }
5774
3.01k
    NEXT;
5775
3.01k
    return(ret);
5776
9.31k
}
5777
5778
/**
5779
 * xmlParseEnumerationType:
5780
 * @ctxt:  an XML parser context
5781
 *
5782
 * parse an Enumeration attribute type.
5783
 *
5784
 * [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
5785
 *
5786
 * [ VC: Enumeration ]
5787
 * Values of this type must match one of the Nmtoken tokens in
5788
 * the declaration
5789
 *
5790
 * Returns: the enumeration attribute tree built while parsing
5791
 */
5792
5793
xmlEnumerationPtr
5794
82.5k
xmlParseEnumerationType(xmlParserCtxtPtr ctxt) {
5795
82.5k
    xmlChar *name;
5796
82.5k
    xmlEnumerationPtr ret = NULL, last = NULL, cur, tmp;
5797
5798
82.5k
    if (RAW != '(') {
5799
36.1k
  xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_STARTED, NULL);
5800
36.1k
  return(NULL);
5801
36.1k
    }
5802
46.4k
    SHRINK;
5803
49.7k
    do {
5804
49.7k
        NEXT;
5805
49.7k
  SKIP_BLANKS;
5806
49.7k
        name = xmlParseNmtoken(ctxt);
5807
49.7k
  if (name == NULL) {
5808
781
      xmlFatalErr(ctxt, XML_ERR_NMTOKEN_REQUIRED, NULL);
5809
781
      return(ret);
5810
781
  }
5811
48.9k
  tmp = ret;
5812
54.7k
  while (tmp != NULL) {
5813
6.56k
      if (xmlStrEqual(name, tmp->name)) {
5814
769
    xmlValidityError(ctxt, XML_DTD_DUP_TOKEN,
5815
769
    "standalone: attribute enumeration value token %s duplicated\n",
5816
769
         name, NULL);
5817
769
    if (!xmlDictOwns(ctxt->dict, name))
5818
769
        xmlFree(name);
5819
769
    break;
5820
769
      }
5821
5.79k
      tmp = tmp->next;
5822
5.79k
  }
5823
48.9k
  if (tmp == NULL) {
5824
48.2k
      cur = xmlCreateEnumeration(name);
5825
48.2k
      if (!xmlDictOwns(ctxt->dict, name))
5826
48.2k
    xmlFree(name);
5827
48.2k
      if (cur == NULL) {
5828
0
                xmlFreeEnumeration(ret);
5829
0
                return(NULL);
5830
0
            }
5831
48.2k
      if (last == NULL) ret = last = cur;
5832
2.53k
      else {
5833
2.53k
    last->next = cur;
5834
2.53k
    last = cur;
5835
2.53k
      }
5836
48.2k
  }
5837
48.9k
  SKIP_BLANKS;
5838
48.9k
    } while (RAW == '|');
5839
45.6k
    if (RAW != ')') {
5840
15.3k
  xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_FINISHED, NULL);
5841
15.3k
  return(ret);
5842
15.3k
    }
5843
30.2k
    NEXT;
5844
30.2k
    return(ret);
5845
45.6k
}
5846
5847
/**
5848
 * xmlParseEnumeratedType:
5849
 * @ctxt:  an XML parser context
5850
 * @tree:  the enumeration tree built while parsing
5851
 *
5852
 * parse an Enumerated attribute type.
5853
 *
5854
 * [57] EnumeratedType ::= NotationType | Enumeration
5855
 *
5856
 * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
5857
 *
5858
 *
5859
 * Returns: XML_ATTRIBUTE_ENUMERATION or XML_ATTRIBUTE_NOTATION
5860
 */
5861
5862
int
5863
97.2k
xmlParseEnumeratedType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
5864
97.2k
    if (CMP8(CUR_PTR, 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
5865
14.6k
  SKIP(8);
5866
14.6k
  if (SKIP_BLANKS == 0) {
5867
1.05k
      xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5868
1.05k
         "Space required after 'NOTATION'\n");
5869
1.05k
      return(0);
5870
1.05k
  }
5871
13.5k
  *tree = xmlParseNotationType(ctxt);
5872
13.5k
  if (*tree == NULL) return(0);
5873
3.01k
  return(XML_ATTRIBUTE_NOTATION);
5874
13.5k
    }
5875
82.5k
    *tree = xmlParseEnumerationType(ctxt);
5876
82.5k
    if (*tree == NULL) return(0);
5877
45.6k
    return(XML_ATTRIBUTE_ENUMERATION);
5878
82.5k
}
5879
5880
/**
5881
 * xmlParseAttributeType:
5882
 * @ctxt:  an XML parser context
5883
 * @tree:  the enumeration tree built while parsing
5884
 *
5885
 * parse the Attribute list def for an element
5886
 *
5887
 * [54] AttType ::= StringType | TokenizedType | EnumeratedType
5888
 *
5889
 * [55] StringType ::= 'CDATA'
5890
 *
5891
 * [56] TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' |
5892
 *                        'ENTITIES' | 'NMTOKEN' | 'NMTOKENS'
5893
 *
5894
 * Validity constraints for attribute values syntax are checked in
5895
 * xmlValidateAttributeValue()
5896
 *
5897
 * [ VC: ID ]
5898
 * Values of type ID must match the Name production. A name must not
5899
 * appear more than once in an XML document as a value of this type;
5900
 * i.e., ID values must uniquely identify the elements which bear them.
5901
 *
5902
 * [ VC: One ID per Element Type ]
5903
 * No element type may have more than one ID attribute specified.
5904
 *
5905
 * [ VC: ID Attribute Default ]
5906
 * An ID attribute must have a declared default of #IMPLIED or #REQUIRED.
5907
 *
5908
 * [ VC: IDREF ]
5909
 * Values of type IDREF must match the Name production, and values
5910
 * of type IDREFS must match Names; each IDREF Name must match the value
5911
 * of an ID attribute on some element in the XML document; i.e. IDREF
5912
 * values must match the value of some ID attribute.
5913
 *
5914
 * [ VC: Entity Name ]
5915
 * Values of type ENTITY must match the Name production, values
5916
 * of type ENTITIES must match Names; each Entity Name must match the
5917
 * name of an unparsed entity declared in the DTD.
5918
 *
5919
 * [ VC: Name Token ]
5920
 * Values of type NMTOKEN must match the Nmtoken production; values
5921
 * of type NMTOKENS must match Nmtokens.
5922
 *
5923
 * Returns the attribute type
5924
 */
5925
int
5926
892k
xmlParseAttributeType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
5927
892k
    SHRINK;
5928
892k
    if (CMP5(CUR_PTR, 'C', 'D', 'A', 'T', 'A')) {
5929
738k
  SKIP(5);
5930
738k
  return(XML_ATTRIBUTE_CDATA);
5931
738k
     } else if (CMP6(CUR_PTR, 'I', 'D', 'R', 'E', 'F', 'S')) {
5932
5.35k
  SKIP(6);
5933
5.35k
  return(XML_ATTRIBUTE_IDREFS);
5934
148k
     } else if (CMP5(CUR_PTR, 'I', 'D', 'R', 'E', 'F')) {
5935
2.05k
  SKIP(5);
5936
2.05k
  return(XML_ATTRIBUTE_IDREF);
5937
146k
     } else if ((RAW == 'I') && (NXT(1) == 'D')) {
5938
31.8k
        SKIP(2);
5939
31.8k
  return(XML_ATTRIBUTE_ID);
5940
114k
     } else if (CMP6(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'Y')) {
5941
2.94k
  SKIP(6);
5942
2.94k
  return(XML_ATTRIBUTE_ENTITY);
5943
111k
     } else if (CMP8(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S')) {
5944
8.54k
  SKIP(8);
5945
8.54k
  return(XML_ATTRIBUTE_ENTITIES);
5946
102k
     } else if (CMP8(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S')) {
5947
3.10k
  SKIP(8);
5948
3.10k
  return(XML_ATTRIBUTE_NMTOKENS);
5949
99.6k
     } else if (CMP7(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N')) {
5950
2.42k
  SKIP(7);
5951
2.42k
  return(XML_ATTRIBUTE_NMTOKEN);
5952
2.42k
     }
5953
97.2k
     return(xmlParseEnumeratedType(ctxt, tree));
5954
892k
}
5955
5956
/**
5957
 * xmlParseAttributeListDecl:
5958
 * @ctxt:  an XML parser context
5959
 *
5960
 * : parse the Attribute list def for an element
5961
 *
5962
 * [52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
5963
 *
5964
 * [53] AttDef ::= S Name S AttType S DefaultDecl
5965
 *
5966
 */
5967
void
5968
888k
xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) {
5969
888k
    const xmlChar *elemName;
5970
888k
    const xmlChar *attrName;
5971
888k
    xmlEnumerationPtr tree;
5972
5973
888k
    if (CMP9(CUR_PTR, '<', '!', 'A', 'T', 'T', 'L', 'I', 'S', 'T')) {
5974
878k
  int inputid = ctxt->input->id;
5975
5976
878k
  SKIP(9);
5977
878k
  if (SKIP_BLANKS == 0) {
5978
836k
      xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5979
836k
                     "Space required after '<!ATTLIST'\n");
5980
836k
  }
5981
878k
        elemName = xmlParseName(ctxt);
5982
878k
  if (elemName == NULL) {
5983
2.23k
      xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
5984
2.23k
         "ATTLIST: no name for Element\n");
5985
2.23k
      return;
5986
2.23k
  }
5987
876k
  SKIP_BLANKS;
5988
876k
  GROW;
5989
934k
  while ((RAW != '>') && (ctxt->instate != XML_PARSER_EOF)) {
5990
920k
      int type;
5991
920k
      int def;
5992
920k
      xmlChar *defaultValue = NULL;
5993
5994
920k
      GROW;
5995
920k
            tree = NULL;
5996
920k
      attrName = xmlParseName(ctxt);
5997
920k
      if (attrName == NULL) {
5998
18.2k
    xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
5999
18.2k
             "ATTLIST: no name for Attribute\n");
6000
18.2k
    break;
6001
18.2k
      }
6002
901k
      GROW;
6003
901k
      if (SKIP_BLANKS == 0) {
6004
9.56k
    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6005
9.56k
            "Space required after the attribute name\n");
6006
9.56k
    break;
6007
9.56k
      }
6008
6009
892k
      type = xmlParseAttributeType(ctxt, &tree);
6010
892k
      if (type <= 0) {
6011
48.5k
          break;
6012
48.5k
      }
6013
6014
843k
      GROW;
6015
843k
      if (SKIP_BLANKS == 0) {
6016
25.3k
    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6017
25.3k
             "Space required after the attribute type\n");
6018
25.3k
          if (tree != NULL)
6019
20.4k
        xmlFreeEnumeration(tree);
6020
25.3k
    break;
6021
25.3k
      }
6022
6023
818k
      def = xmlParseDefaultDecl(ctxt, &defaultValue);
6024
818k
      if (def <= 0) {
6025
0
                if (defaultValue != NULL)
6026
0
        xmlFree(defaultValue);
6027
0
          if (tree != NULL)
6028
0
        xmlFreeEnumeration(tree);
6029
0
          break;
6030
0
      }
6031
818k
      if ((type != XML_ATTRIBUTE_CDATA) && (defaultValue != NULL))
6032
55.1k
          xmlAttrNormalizeSpace(defaultValue, defaultValue);
6033
6034
818k
      GROW;
6035
818k
            if (RAW != '>') {
6036
807k
    if (SKIP_BLANKS == 0) {
6037
760k
        xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6038
760k
      "Space required after the attribute default value\n");
6039
760k
        if (defaultValue != NULL)
6040
2.61k
      xmlFree(defaultValue);
6041
760k
        if (tree != NULL)
6042
2.18k
      xmlFreeEnumeration(tree);
6043
760k
        break;
6044
760k
    }
6045
807k
      }
6046
58.1k
      if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
6047
58.1k
    (ctxt->sax->attributeDecl != NULL))
6048
29.7k
    ctxt->sax->attributeDecl(ctxt->userData, elemName, attrName,
6049
29.7k
                          type, def, defaultValue, tree);
6050
28.3k
      else if (tree != NULL)
6051
18.3k
    xmlFreeEnumeration(tree);
6052
6053
58.1k
      if ((ctxt->sax2) && (defaultValue != NULL) &&
6054
58.1k
          (def != XML_ATTRIBUTE_IMPLIED) &&
6055
58.1k
    (def != XML_ATTRIBUTE_REQUIRED)) {
6056
55.2k
    xmlAddDefAttrs(ctxt, elemName, attrName, defaultValue);
6057
55.2k
      }
6058
58.1k
      if (ctxt->sax2) {
6059
58.1k
    xmlAddSpecialAttr(ctxt, elemName, attrName, type);
6060
58.1k
      }
6061
58.1k
      if (defaultValue != NULL)
6062
55.2k
          xmlFree(defaultValue);
6063
58.1k
      GROW;
6064
58.1k
  }
6065
876k
  if (RAW == '>') {
6066
20.5k
      if (inputid != ctxt->input->id) {
6067
621
    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6068
621
                               "Attribute list declaration doesn't start and"
6069
621
                               " stop in the same entity\n");
6070
621
      }
6071
20.5k
      NEXT;
6072
20.5k
  }
6073
876k
    }
6074
888k
}
6075
6076
/**
6077
 * xmlParseElementMixedContentDecl:
6078
 * @ctxt:  an XML parser context
6079
 * @inputchk:  the input used for the current entity, needed for boundary checks
6080
 *
6081
 * parse the declaration for a Mixed Element content
6082
 * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
6083
 *
6084
 * [51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' |
6085
 *                '(' S? '#PCDATA' S? ')'
6086
 *
6087
 * [ VC: Proper Group/PE Nesting ] applies to [51] too (see [49])
6088
 *
6089
 * [ VC: No Duplicate Types ]
6090
 * The same name must not appear more than once in a single
6091
 * mixed-content declaration.
6092
 *
6093
 * returns: the list of the xmlElementContentPtr describing the element choices
6094
 */
6095
xmlElementContentPtr
6096
21.3k
xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
6097
21.3k
    xmlElementContentPtr ret = NULL, cur = NULL, n;
6098
21.3k
    const xmlChar *elem = NULL;
6099
6100
21.3k
    GROW;
6101
21.3k
    if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
6102
21.3k
  SKIP(7);
6103
21.3k
  SKIP_BLANKS;
6104
21.3k
  SHRINK;
6105
21.3k
  if (RAW == ')') {
6106
486
      if (ctxt->input->id != inputchk) {
6107
280
    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6108
280
                               "Element content declaration doesn't start and"
6109
280
                               " stop in the same entity\n");
6110
280
      }
6111
486
      NEXT;
6112
486
      ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA);
6113
486
      if (ret == NULL)
6114
0
          return(NULL);
6115
486
      if (RAW == '*') {
6116
68
    ret->ocur = XML_ELEMENT_CONTENT_MULT;
6117
68
    NEXT;
6118
68
      }
6119
486
      return(ret);
6120
486
  }
6121
20.8k
  if ((RAW == '(') || (RAW == '|')) {
6122
18.4k
      ret = cur = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA);
6123
18.4k
      if (ret == NULL) return(NULL);
6124
18.4k
  }
6125
47.1k
  while ((RAW == '|') && (ctxt->instate != XML_PARSER_EOF)) {
6126
29.8k
      NEXT;
6127
29.8k
      if (elem == NULL) {
6128
17.6k
          ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
6129
17.6k
    if (ret == NULL) {
6130
0
        xmlFreeDocElementContent(ctxt->myDoc, cur);
6131
0
                    return(NULL);
6132
0
                }
6133
17.6k
    ret->c1 = cur;
6134
17.6k
    if (cur != NULL)
6135
17.6k
        cur->parent = ret;
6136
17.6k
    cur = ret;
6137
17.6k
      } else {
6138
12.1k
          n = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
6139
12.1k
    if (n == NULL) {
6140
0
        xmlFreeDocElementContent(ctxt->myDoc, ret);
6141
0
                    return(NULL);
6142
0
                }
6143
12.1k
    n->c1 = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
6144
12.1k
    if (n->c1 != NULL)
6145
12.1k
        n->c1->parent = n;
6146
12.1k
          cur->c2 = n;
6147
12.1k
    if (n != NULL)
6148
12.1k
        n->parent = cur;
6149
12.1k
    cur = n;
6150
12.1k
      }
6151
29.8k
      SKIP_BLANKS;
6152
29.8k
      elem = xmlParseName(ctxt);
6153
29.8k
      if (elem == NULL) {
6154
3.51k
    xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
6155
3.51k
      "xmlParseElementMixedContentDecl : Name expected\n");
6156
3.51k
    xmlFreeDocElementContent(ctxt->myDoc, ret);
6157
3.51k
    return(NULL);
6158
3.51k
      }
6159
26.3k
      SKIP_BLANKS;
6160
26.3k
      GROW;
6161
26.3k
  }
6162
17.3k
  if ((RAW == ')') && (NXT(1) == '*')) {
6163
57
      if (elem != NULL) {
6164
57
    cur->c2 = xmlNewDocElementContent(ctxt->myDoc, elem,
6165
57
                                   XML_ELEMENT_CONTENT_ELEMENT);
6166
57
    if (cur->c2 != NULL)
6167
57
        cur->c2->parent = cur;
6168
57
            }
6169
57
            if (ret != NULL)
6170
57
                ret->ocur = XML_ELEMENT_CONTENT_MULT;
6171
57
      if (ctxt->input->id != inputchk) {
6172
35
    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6173
35
                               "Element content declaration doesn't start and"
6174
35
                               " stop in the same entity\n");
6175
35
      }
6176
57
      SKIP(2);
6177
17.2k
  } else {
6178
17.2k
      xmlFreeDocElementContent(ctxt->myDoc, ret);
6179
17.2k
      xmlFatalErr(ctxt, XML_ERR_MIXED_NOT_STARTED, NULL);
6180
17.2k
      return(NULL);
6181
17.2k
  }
6182
6183
17.3k
    } else {
6184
0
  xmlFatalErr(ctxt, XML_ERR_PCDATA_REQUIRED, NULL);
6185
0
    }
6186
57
    return(ret);
6187
21.3k
}
6188
6189
/**
6190
 * xmlParseElementChildrenContentDeclPriv:
6191
 * @ctxt:  an XML parser context
6192
 * @inputchk:  the input used for the current entity, needed for boundary checks
6193
 * @depth: the level of recursion
6194
 *
6195
 * parse the declaration for a Mixed Element content
6196
 * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
6197
 *
6198
 *
6199
 * [47] children ::= (choice | seq) ('?' | '*' | '+')?
6200
 *
6201
 * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
6202
 *
6203
 * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
6204
 *
6205
 * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
6206
 *
6207
 * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
6208
 * TODO Parameter-entity replacement text must be properly nested
6209
 *  with parenthesized groups. That is to say, if either of the
6210
 *  opening or closing parentheses in a choice, seq, or Mixed
6211
 *  construct is contained in the replacement text for a parameter
6212
 *  entity, both must be contained in the same replacement text. For
6213
 *  interoperability, if a parameter-entity reference appears in a
6214
 *  choice, seq, or Mixed construct, its replacement text should not
6215
 *  be empty, and neither the first nor last non-blank character of
6216
 *  the replacement text should be a connector (| or ,).
6217
 *
6218
 * Returns the tree of xmlElementContentPtr describing the element
6219
 *          hierarchy.
6220
 */
6221
static xmlElementContentPtr
6222
xmlParseElementChildrenContentDeclPriv(xmlParserCtxtPtr ctxt, int inputchk,
6223
8.89M
                                       int depth) {
6224
8.89M
    xmlElementContentPtr ret = NULL, cur = NULL, last = NULL, op = NULL;
6225
8.89M
    const xmlChar *elem;
6226
8.89M
    xmlChar type = 0;
6227
6228
8.89M
    if (((depth > 128) && ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
6229
8.89M
        (depth >  2048)) {
6230
787
        xmlFatalErrMsgInt(ctxt, XML_ERR_ELEMCONTENT_NOT_FINISHED,
6231
787
"xmlParseElementChildrenContentDecl : depth %d too deep, use XML_PARSE_HUGE\n",
6232
787
                          depth);
6233
787
  return(NULL);
6234
787
    }
6235
8.89M
    SKIP_BLANKS;
6236
8.89M
    GROW;
6237
8.89M
    if (RAW == '(') {
6238
7.94M
  int inputid = ctxt->input->id;
6239
6240
        /* Recurse on first child */
6241
7.94M
  NEXT;
6242
7.94M
  SKIP_BLANKS;
6243
7.94M
        cur = ret = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
6244
7.94M
                                                           depth + 1);
6245
7.94M
        if (cur == NULL)
6246
7.90M
            return(NULL);
6247
43.0k
  SKIP_BLANKS;
6248
43.0k
  GROW;
6249
954k
    } else {
6250
954k
  elem = xmlParseName(ctxt);
6251
954k
  if (elem == NULL) {
6252
13.3k
      xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
6253
13.3k
      return(NULL);
6254
13.3k
  }
6255
941k
        cur = ret = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
6256
941k
  if (cur == NULL) {
6257
0
      xmlErrMemory(ctxt, NULL);
6258
0
      return(NULL);
6259
0
  }
6260
941k
  GROW;
6261
941k
  if (RAW == '?') {
6262
4.97k
      cur->ocur = XML_ELEMENT_CONTENT_OPT;
6263
4.97k
      NEXT;
6264
936k
  } else if (RAW == '*') {
6265
4.13k
      cur->ocur = XML_ELEMENT_CONTENT_MULT;
6266
4.13k
      NEXT;
6267
932k
  } else if (RAW == '+') {
6268
5.19k
      cur->ocur = XML_ELEMENT_CONTENT_PLUS;
6269
5.19k
      NEXT;
6270
927k
  } else {
6271
927k
      cur->ocur = XML_ELEMENT_CONTENT_ONCE;
6272
927k
  }
6273
941k
  GROW;
6274
941k
    }
6275
984k
    SKIP_BLANKS;
6276
984k
    SHRINK;
6277
1.00M
    while ((RAW != ')') && (ctxt->instate != XML_PARSER_EOF)) {
6278
        /*
6279
   * Each loop we parse one separator and one element.
6280
   */
6281
944k
        if (RAW == ',') {
6282
12.1k
      if (type == 0) type = CUR;
6283
6284
      /*
6285
       * Detect "Name | Name , Name" error
6286
       */
6287
3.35k
      else if (type != CUR) {
6288
2.09k
    xmlFatalErrMsgInt(ctxt, XML_ERR_SEPARATOR_REQUIRED,
6289
2.09k
        "xmlParseElementChildrenContentDecl : '%c' expected\n",
6290
2.09k
                      type);
6291
2.09k
    if ((last != NULL) && (last != ret))
6292
2.09k
        xmlFreeDocElementContent(ctxt->myDoc, last);
6293
2.09k
    if (ret != NULL)
6294
2.09k
        xmlFreeDocElementContent(ctxt->myDoc, ret);
6295
2.09k
    return(NULL);
6296
2.09k
      }
6297
10.0k
      NEXT;
6298
6299
10.0k
      op = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_SEQ);
6300
10.0k
      if (op == NULL) {
6301
0
    if ((last != NULL) && (last != ret))
6302
0
        xmlFreeDocElementContent(ctxt->myDoc, last);
6303
0
          xmlFreeDocElementContent(ctxt->myDoc, ret);
6304
0
    return(NULL);
6305
0
      }
6306
10.0k
      if (last == NULL) {
6307
8.75k
    op->c1 = ret;
6308
8.75k
    if (ret != NULL)
6309
8.75k
        ret->parent = op;
6310
8.75k
    ret = cur = op;
6311
8.75k
      } else {
6312
1.25k
          cur->c2 = op;
6313
1.25k
    if (op != NULL)
6314
1.25k
        op->parent = cur;
6315
1.25k
    op->c1 = last;
6316
1.25k
    if (last != NULL)
6317
1.25k
        last->parent = op;
6318
1.25k
    cur =op;
6319
1.25k
    last = NULL;
6320
1.25k
      }
6321
932k
  } else if (RAW == '|') {
6322
20.9k
      if (type == 0) type = CUR;
6323
6324
      /*
6325
       * Detect "Name , Name | Name" error
6326
       */
6327
3.61k
      else if (type != CUR) {
6328
786
    xmlFatalErrMsgInt(ctxt, XML_ERR_SEPARATOR_REQUIRED,
6329
786
        "xmlParseElementChildrenContentDecl : '%c' expected\n",
6330
786
          type);
6331
786
    if ((last != NULL) && (last != ret))
6332
786
        xmlFreeDocElementContent(ctxt->myDoc, last);
6333
786
    if (ret != NULL)
6334
786
        xmlFreeDocElementContent(ctxt->myDoc, ret);
6335
786
    return(NULL);
6336
786
      }
6337
20.1k
      NEXT;
6338
6339
20.1k
      op = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
6340
20.1k
      if (op == NULL) {
6341
0
    if ((last != NULL) && (last != ret))
6342
0
        xmlFreeDocElementContent(ctxt->myDoc, last);
6343
0
    if (ret != NULL)
6344
0
        xmlFreeDocElementContent(ctxt->myDoc, ret);
6345
0
    return(NULL);
6346
0
      }
6347
20.1k
      if (last == NULL) {
6348
17.3k
    op->c1 = ret;
6349
17.3k
    if (ret != NULL)
6350
17.3k
        ret->parent = op;
6351
17.3k
    ret = cur = op;
6352
17.3k
      } else {
6353
2.82k
          cur->c2 = op;
6354
2.82k
    if (op != NULL)
6355
2.82k
        op->parent = cur;
6356
2.82k
    op->c1 = last;
6357
2.82k
    if (last != NULL)
6358
2.82k
        last->parent = op;
6359
2.82k
    cur =op;
6360
2.82k
    last = NULL;
6361
2.82k
      }
6362
911k
  } else {
6363
911k
      xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_FINISHED, NULL);
6364
911k
      if ((last != NULL) && (last != ret))
6365
5.38k
          xmlFreeDocElementContent(ctxt->myDoc, last);
6366
911k
      if (ret != NULL)
6367
911k
    xmlFreeDocElementContent(ctxt->myDoc, ret);
6368
911k
      return(NULL);
6369
911k
  }
6370
30.1k
  GROW;
6371
30.1k
  SKIP_BLANKS;
6372
30.1k
  GROW;
6373
30.1k
  if (RAW == '(') {
6374
14.1k
      int inputid = ctxt->input->id;
6375
      /* Recurse on second child */
6376
14.1k
      NEXT;
6377
14.1k
      SKIP_BLANKS;
6378
14.1k
      last = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
6379
14.1k
                                                          depth + 1);
6380
14.1k
            if (last == NULL) {
6381
11.1k
    if (ret != NULL)
6382
11.1k
        xmlFreeDocElementContent(ctxt->myDoc, ret);
6383
11.1k
    return(NULL);
6384
11.1k
            }
6385
2.99k
      SKIP_BLANKS;
6386
15.9k
  } else {
6387
15.9k
      elem = xmlParseName(ctxt);
6388
15.9k
      if (elem == NULL) {
6389
2.53k
    xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
6390
2.53k
    if (ret != NULL)
6391
2.53k
        xmlFreeDocElementContent(ctxt->myDoc, ret);
6392
2.53k
    return(NULL);
6393
2.53k
      }
6394
13.4k
      last = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
6395
13.4k
      if (last == NULL) {
6396
0
    if (ret != NULL)
6397
0
        xmlFreeDocElementContent(ctxt->myDoc, ret);
6398
0
    return(NULL);
6399
0
      }
6400
13.4k
      if (RAW == '?') {
6401
1.15k
    last->ocur = XML_ELEMENT_CONTENT_OPT;
6402
1.15k
    NEXT;
6403
12.2k
      } else if (RAW == '*') {
6404
1.96k
    last->ocur = XML_ELEMENT_CONTENT_MULT;
6405
1.96k
    NEXT;
6406
10.3k
      } else if (RAW == '+') {
6407
756
    last->ocur = XML_ELEMENT_CONTENT_PLUS;
6408
756
    NEXT;
6409
9.56k
      } else {
6410
9.56k
    last->ocur = XML_ELEMENT_CONTENT_ONCE;
6411
9.56k
      }
6412
13.4k
  }
6413
16.4k
  SKIP_BLANKS;
6414
16.4k
  GROW;
6415
16.4k
    }
6416
56.7k
    if ((cur != NULL) && (last != NULL)) {
6417
4.09k
        cur->c2 = last;
6418
4.09k
  if (last != NULL)
6419
4.09k
      last->parent = cur;
6420
4.09k
    }
6421
56.7k
    if (ctxt->input->id != inputchk) {
6422
466
  xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6423
466
                       "Element content declaration doesn't start and stop in"
6424
466
                       " the same entity\n");
6425
466
    }
6426
56.7k
    NEXT;
6427
56.7k
    if (RAW == '?') {
6428
5.96k
  if (ret != NULL) {
6429
5.96k
      if ((ret->ocur == XML_ELEMENT_CONTENT_PLUS) ||
6430
5.96k
          (ret->ocur == XML_ELEMENT_CONTENT_MULT))
6431
4.86k
          ret->ocur = XML_ELEMENT_CONTENT_MULT;
6432
1.09k
      else
6433
1.09k
          ret->ocur = XML_ELEMENT_CONTENT_OPT;
6434
5.96k
  }
6435
5.96k
  NEXT;
6436
50.8k
    } else if (RAW == '*') {
6437
1.87k
  if (ret != NULL) {
6438
1.87k
      ret->ocur = XML_ELEMENT_CONTENT_MULT;
6439
1.87k
      cur = ret;
6440
      /*
6441
       * Some normalization:
6442
       * (a | b* | c?)* == (a | b | c)*
6443
       */
6444
5.11k
      while ((cur != NULL) && (cur->type == XML_ELEMENT_CONTENT_OR)) {
6445
3.24k
    if ((cur->c1 != NULL) &&
6446
3.24k
              ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
6447
3.24k
         (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT)))
6448
1.78k
        cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
6449
3.24k
    if ((cur->c2 != NULL) &&
6450
3.24k
              ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
6451
3.24k
         (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT)))
6452
800
        cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
6453
3.24k
    cur = cur->c2;
6454
3.24k
      }
6455
1.87k
  }
6456
1.87k
  NEXT;
6457
48.9k
    } else if (RAW == '+') {
6458
2.44k
  if (ret != NULL) {
6459
2.44k
      int found = 0;
6460
6461
2.44k
      if ((ret->ocur == XML_ELEMENT_CONTENT_OPT) ||
6462
2.44k
          (ret->ocur == XML_ELEMENT_CONTENT_MULT))
6463
581
          ret->ocur = XML_ELEMENT_CONTENT_MULT;
6464
1.86k
      else
6465
1.86k
          ret->ocur = XML_ELEMENT_CONTENT_PLUS;
6466
      /*
6467
       * Some normalization:
6468
       * (a | b*)+ == (a | b)*
6469
       * (a | b?)+ == (a | b)*
6470
       */
6471
4.55k
      while ((cur != NULL) && (cur->type == XML_ELEMENT_CONTENT_OR)) {
6472
2.10k
    if ((cur->c1 != NULL) &&
6473
2.10k
              ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
6474
2.10k
         (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT))) {
6475
1.68k
        cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
6476
1.68k
        found = 1;
6477
1.68k
    }
6478
2.10k
    if ((cur->c2 != NULL) &&
6479
2.10k
              ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
6480
2.10k
         (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT))) {
6481
1.42k
        cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
6482
1.42k
        found = 1;
6483
1.42k
    }
6484
2.10k
    cur = cur->c2;
6485
2.10k
      }
6486
2.44k
      if (found)
6487
1.42k
    ret->ocur = XML_ELEMENT_CONTENT_MULT;
6488
2.44k
  }
6489
2.44k
  NEXT;
6490
2.44k
    }
6491
56.7k
    return(ret);
6492
984k
}
6493
6494
/**
6495
 * xmlParseElementChildrenContentDecl:
6496
 * @ctxt:  an XML parser context
6497
 * @inputchk:  the input used for the current entity, needed for boundary checks
6498
 *
6499
 * parse the declaration for a Mixed Element content
6500
 * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
6501
 *
6502
 * [47] children ::= (choice | seq) ('?' | '*' | '+')?
6503
 *
6504
 * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
6505
 *
6506
 * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
6507
 *
6508
 * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
6509
 *
6510
 * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
6511
 * TODO Parameter-entity replacement text must be properly nested
6512
 *  with parenthesized groups. That is to say, if either of the
6513
 *  opening or closing parentheses in a choice, seq, or Mixed
6514
 *  construct is contained in the replacement text for a parameter
6515
 *  entity, both must be contained in the same replacement text. For
6516
 *  interoperability, if a parameter-entity reference appears in a
6517
 *  choice, seq, or Mixed construct, its replacement text should not
6518
 *  be empty, and neither the first nor last non-blank character of
6519
 *  the replacement text should be a connector (| or ,).
6520
 *
6521
 * Returns the tree of xmlElementContentPtr describing the element
6522
 *          hierarchy.
6523
 */
6524
xmlElementContentPtr
6525
0
xmlParseElementChildrenContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
6526
    /* stub left for API/ABI compat */
6527
0
    return(xmlParseElementChildrenContentDeclPriv(ctxt, inputchk, 1));
6528
0
}
6529
6530
/**
6531
 * xmlParseElementContentDecl:
6532
 * @ctxt:  an XML parser context
6533
 * @name:  the name of the element being defined.
6534
 * @result:  the Element Content pointer will be stored here if any
6535
 *
6536
 * parse the declaration for an Element content either Mixed or Children,
6537
 * the cases EMPTY and ANY are handled directly in xmlParseElementDecl
6538
 *
6539
 * [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
6540
 *
6541
 * returns: the type of element content XML_ELEMENT_TYPE_xxx
6542
 */
6543
6544
int
6545
xmlParseElementContentDecl(xmlParserCtxtPtr ctxt, const xmlChar *name,
6546
962k
                           xmlElementContentPtr *result) {
6547
6548
962k
    xmlElementContentPtr tree = NULL;
6549
962k
    int inputid = ctxt->input->id;
6550
962k
    int res;
6551
6552
962k
    *result = NULL;
6553
6554
962k
    if (RAW != '(') {
6555
0
  xmlFatalErrMsgStr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED,
6556
0
    "xmlParseElementContentDecl : %s '(' expected\n", name);
6557
0
  return(-1);
6558
0
    }
6559
962k
    NEXT;
6560
962k
    GROW;
6561
962k
    if (ctxt->instate == XML_PARSER_EOF)
6562
0
        return(-1);
6563
962k
    SKIP_BLANKS;
6564
962k
    if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
6565
21.3k
        tree = xmlParseElementMixedContentDecl(ctxt, inputid);
6566
21.3k
  res = XML_ELEMENT_TYPE_MIXED;
6567
941k
    } else {
6568
941k
        tree = xmlParseElementChildrenContentDeclPriv(ctxt, inputid, 1);
6569
941k
  res = XML_ELEMENT_TYPE_ELEMENT;
6570
941k
    }
6571
962k
    SKIP_BLANKS;
6572
962k
    *result = tree;
6573
962k
    return(res);
6574
962k
}
6575
6576
/**
6577
 * xmlParseElementDecl:
6578
 * @ctxt:  an XML parser context
6579
 *
6580
 * parse an Element declaration.
6581
 *
6582
 * [45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
6583
 *
6584
 * [ VC: Unique Element Type Declaration ]
6585
 * No element type may be declared more than once
6586
 *
6587
 * Returns the type of the element, or -1 in case of error
6588
 */
6589
int
6590
1.13M
xmlParseElementDecl(xmlParserCtxtPtr ctxt) {
6591
1.13M
    const xmlChar *name;
6592
1.13M
    int ret = -1;
6593
1.13M
    xmlElementContentPtr content  = NULL;
6594
6595
    /* GROW; done in the caller */
6596
1.13M
    if (CMP9(CUR_PTR, '<', '!', 'E', 'L', 'E', 'M', 'E', 'N', 'T')) {
6597
1.12M
  int inputid = ctxt->input->id;
6598
6599
1.12M
  SKIP(9);
6600
1.12M
  if (SKIP_BLANKS == 0) {
6601
3.14k
      xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6602
3.14k
               "Space required after 'ELEMENT'\n");
6603
3.14k
      return(-1);
6604
3.14k
  }
6605
1.11M
        name = xmlParseName(ctxt);
6606
1.11M
  if (name == NULL) {
6607
42.7k
      xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
6608
42.7k
         "xmlParseElementDecl: no name for Element\n");
6609
42.7k
      return(-1);
6610
42.7k
  }
6611
1.07M
  if (SKIP_BLANKS == 0) {
6612
1.03M
      xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6613
1.03M
         "Space required after the element name\n");
6614
1.03M
  }
6615
1.07M
  if (CMP5(CUR_PTR, 'E', 'M', 'P', 'T', 'Y')) {
6616
1.62k
      SKIP(5);
6617
      /*
6618
       * Element must always be empty.
6619
       */
6620
1.62k
      ret = XML_ELEMENT_TYPE_EMPTY;
6621
1.07M
  } else if ((RAW == 'A') && (NXT(1) == 'N') &&
6622
1.07M
             (NXT(2) == 'Y')) {
6623
1.01k
      SKIP(3);
6624
      /*
6625
       * Element is a generic container.
6626
       */
6627
1.01k
      ret = XML_ELEMENT_TYPE_ANY;
6628
1.07M
  } else if (RAW == '(') {
6629
962k
      ret = xmlParseElementContentDecl(ctxt, name, &content);
6630
962k
  } else {
6631
      /*
6632
       * [ WFC: PEs in Internal Subset ] error handling.
6633
       */
6634
108k
      if ((RAW == '%') && (ctxt->external == 0) &&
6635
108k
          (ctxt->inputNr == 1)) {
6636
93
    xmlFatalErrMsg(ctxt, XML_ERR_PEREF_IN_INT_SUBSET,
6637
93
    "PEReference: forbidden within markup decl in internal subset\n");
6638
108k
      } else {
6639
108k
    xmlFatalErrMsg(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED,
6640
108k
          "xmlParseElementDecl: 'EMPTY', 'ANY' or '(' expected\n");
6641
108k
            }
6642
108k
      return(-1);
6643
108k
  }
6644
6645
965k
  SKIP_BLANKS;
6646
6647
965k
  if (RAW != '>') {
6648
945k
      xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
6649
945k
      if (content != NULL) {
6650
5.07k
    xmlFreeDocElementContent(ctxt->myDoc, content);
6651
5.07k
      }
6652
945k
  } else {
6653
20.1k
      if (inputid != ctxt->input->id) {
6654
1.34k
    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6655
1.34k
                               "Element declaration doesn't start and stop in"
6656
1.34k
                               " the same entity\n");
6657
1.34k
      }
6658
6659
20.1k
      NEXT;
6660
20.1k
      if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
6661
20.1k
    (ctxt->sax->elementDecl != NULL)) {
6662
2.25k
    if (content != NULL)
6663
1.31k
        content->parent = NULL;
6664
2.25k
          ctxt->sax->elementDecl(ctxt->userData, name, ret,
6665
2.25k
                           content);
6666
2.25k
    if ((content != NULL) && (content->parent == NULL)) {
6667
        /*
6668
         * this is a trick: if xmlAddElementDecl is called,
6669
         * instead of copying the full tree it is plugged directly
6670
         * if called from the parser. Avoid duplicating the
6671
         * interfaces or change the API/ABI
6672
         */
6673
1.02k
        xmlFreeDocElementContent(ctxt->myDoc, content);
6674
1.02k
    }
6675
17.9k
      } else if (content != NULL) {
6676
4.90k
    xmlFreeDocElementContent(ctxt->myDoc, content);
6677
4.90k
      }
6678
20.1k
  }
6679
965k
    }
6680
975k
    return(ret);
6681
1.13M
}
6682
6683
/**
6684
 * xmlParseConditionalSections
6685
 * @ctxt:  an XML parser context
6686
 *
6687
 * [61] conditionalSect ::= includeSect | ignoreSect
6688
 * [62] includeSect ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>'
6689
 * [63] ignoreSect ::= '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>'
6690
 * [64] ignoreSectContents ::= Ignore ('<![' ignoreSectContents ']]>' Ignore)*
6691
 * [65] Ignore ::= Char* - (Char* ('<![' | ']]>') Char*)
6692
 */
6693
6694
static void
6695
0
xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
6696
0
    int *inputIds = NULL;
6697
0
    size_t inputIdsSize = 0;
6698
0
    size_t depth = 0;
6699
6700
0
    while (ctxt->instate != XML_PARSER_EOF) {
6701
0
        if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
6702
0
            int id = ctxt->input->id;
6703
6704
0
            SKIP(3);
6705
0
            SKIP_BLANKS;
6706
6707
0
            if (CMP7(CUR_PTR, 'I', 'N', 'C', 'L', 'U', 'D', 'E')) {
6708
0
                SKIP(7);
6709
0
                SKIP_BLANKS;
6710
0
                if (RAW != '[') {
6711
0
                    xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
6712
0
                    xmlHaltParser(ctxt);
6713
0
                    goto error;
6714
0
                }
6715
0
                if (ctxt->input->id != id) {
6716
0
                    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6717
0
                                   "All markup of the conditional section is"
6718
0
                                   " not in the same entity\n");
6719
0
                }
6720
0
                NEXT;
6721
6722
0
                if (inputIdsSize <= depth) {
6723
0
                    int *tmp;
6724
6725
0
                    inputIdsSize = (inputIdsSize == 0 ? 4 : inputIdsSize * 2);
6726
0
                    tmp = (int *) xmlRealloc(inputIds,
6727
0
                            inputIdsSize * sizeof(int));
6728
0
                    if (tmp == NULL) {
6729
0
                        xmlErrMemory(ctxt, NULL);
6730
0
                        goto error;
6731
0
                    }
6732
0
                    inputIds = tmp;
6733
0
                }
6734
0
                inputIds[depth] = id;
6735
0
                depth++;
6736
0
            } else if (CMP6(CUR_PTR, 'I', 'G', 'N', 'O', 'R', 'E')) {
6737
0
                int state;
6738
0
                xmlParserInputState instate;
6739
0
                size_t ignoreDepth = 0;
6740
6741
0
                SKIP(6);
6742
0
                SKIP_BLANKS;
6743
0
                if (RAW != '[') {
6744
0
                    xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
6745
0
                    xmlHaltParser(ctxt);
6746
0
                    goto error;
6747
0
                }
6748
0
                if (ctxt->input->id != id) {
6749
0
                    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6750
0
                                   "All markup of the conditional section is"
6751
0
                                   " not in the same entity\n");
6752
0
                }
6753
0
                NEXT;
6754
6755
                /*
6756
                 * Parse up to the end of the conditional section but disable
6757
                 * SAX event generating DTD building in the meantime
6758
                 */
6759
0
                state = ctxt->disableSAX;
6760
0
                instate = ctxt->instate;
6761
0
                if (ctxt->recovery == 0) ctxt->disableSAX = 1;
6762
0
                ctxt->instate = XML_PARSER_IGNORE;
6763
6764
0
                while (RAW != 0) {
6765
0
                    if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
6766
0
                        SKIP(3);
6767
0
                        ignoreDepth++;
6768
                        /* Check for integer overflow */
6769
0
                        if (ignoreDepth == 0) {
6770
0
                            xmlErrMemory(ctxt, NULL);
6771
0
                            goto error;
6772
0
                        }
6773
0
                    } else if ((RAW == ']') && (NXT(1) == ']') &&
6774
0
                               (NXT(2) == '>')) {
6775
0
                        if (ignoreDepth == 0)
6776
0
                            break;
6777
0
                        SKIP(3);
6778
0
                        ignoreDepth--;
6779
0
                    } else {
6780
0
                        NEXT;
6781
0
                    }
6782
0
                }
6783
6784
0
                ctxt->disableSAX = state;
6785
0
                ctxt->instate = instate;
6786
6787
0
    if (RAW == 0) {
6788
0
        xmlFatalErr(ctxt, XML_ERR_CONDSEC_NOT_FINISHED, NULL);
6789
0
                    goto error;
6790
0
    }
6791
0
                if (ctxt->input->id != id) {
6792
0
                    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6793
0
                                   "All markup of the conditional section is"
6794
0
                                   " not in the same entity\n");
6795
0
                }
6796
0
                SKIP(3);
6797
0
            } else {
6798
0
                xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID_KEYWORD, NULL);
6799
0
                xmlHaltParser(ctxt);
6800
0
                goto error;
6801
0
            }
6802
0
        } else if ((depth > 0) &&
6803
0
                   (RAW == ']') && (NXT(1) == ']') && (NXT(2) == '>')) {
6804
0
            depth--;
6805
0
            if (ctxt->input->id != inputIds[depth]) {
6806
0
                xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6807
0
                               "All markup of the conditional section is not"
6808
0
                               " in the same entity\n");
6809
0
            }
6810
0
            SKIP(3);
6811
0
        } else {
6812
0
            int id = ctxt->input->id;
6813
0
            unsigned long cons = CUR_CONSUMED;
6814
6815
0
            xmlParseMarkupDecl(ctxt);
6816
6817
0
            if ((id == ctxt->input->id) && (cons == CUR_CONSUMED)) {
6818
0
                xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
6819
0
                xmlHaltParser(ctxt);
6820
0
                goto error;
6821
0
            }
6822
0
        }
6823
6824
0
        if (depth == 0)
6825
0
            break;
6826
6827
0
        SKIP_BLANKS;
6828
0
        GROW;
6829
0
    }
6830
6831
0
error:
6832
0
    xmlFree(inputIds);
6833
0
}
6834
6835
/**
6836
 * xmlParseMarkupDecl:
6837
 * @ctxt:  an XML parser context
6838
 *
6839
 * parse Markup declarations
6840
 *
6841
 * [29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl |
6842
 *                     NotationDecl | PI | Comment
6843
 *
6844
 * [ VC: Proper Declaration/PE Nesting ]
6845
 * Parameter-entity replacement text must be properly nested with
6846
 * markup declarations. That is to say, if either the first character
6847
 * or the last character of a markup declaration (markupdecl above) is
6848
 * contained in the replacement text for a parameter-entity reference,
6849
 * both must be contained in the same replacement text.
6850
 *
6851
 * [ WFC: PEs in Internal Subset ]
6852
 * In the internal DTD subset, parameter-entity references can occur
6853
 * only where markup declarations can occur, not within markup declarations.
6854
 * (This does not apply to references that occur in external parameter
6855
 * entities or to the external subset.)
6856
 */
6857
void
6858
8.46M
xmlParseMarkupDecl(xmlParserCtxtPtr ctxt) {
6859
8.46M
    GROW;
6860
8.46M
    if (CUR == '<') {
6861
7.34M
        if (NXT(1) == '!') {
6862
6.48M
      switch (NXT(2)) {
6863
5.35M
          case 'E':
6864
5.35M
        if (NXT(3) == 'L')
6865
1.13M
      xmlParseElementDecl(ctxt);
6866
4.22M
        else if (NXT(3) == 'N')
6867
4.17M
      xmlParseEntityDecl(ctxt);
6868
5.35M
        break;
6869
888k
          case 'A':
6870
888k
        xmlParseAttributeListDecl(ctxt);
6871
888k
        break;
6872
193k
          case 'N':
6873
193k
        xmlParseNotationDecl(ctxt);
6874
193k
        break;
6875
46.9k
          case '-':
6876
46.9k
        xmlParseComment(ctxt);
6877
46.9k
        break;
6878
4.04k
    default:
6879
        /* there is an error but it will be detected later */
6880
4.04k
        break;
6881
6.48M
      }
6882
6.48M
  } else if (NXT(1) == '?') {
6883
829k
      xmlParsePI(ctxt);
6884
829k
  }
6885
7.34M
    }
6886
6887
    /*
6888
     * detect requirement to exit there and act accordingly
6889
     * and avoid having instate overridden later on
6890
     */
6891
8.46M
    if (ctxt->instate == XML_PARSER_EOF)
6892
984
        return;
6893
6894
8.46M
    ctxt->instate = XML_PARSER_DTD;
6895
8.46M
}
6896
6897
/**
6898
 * xmlParseTextDecl:
6899
 * @ctxt:  an XML parser context
6900
 *
6901
 * parse an XML declaration header for external entities
6902
 *
6903
 * [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
6904
 */
6905
6906
void
6907
0
xmlParseTextDecl(xmlParserCtxtPtr ctxt) {
6908
0
    xmlChar *version;
6909
0
    const xmlChar *encoding;
6910
0
    int oldstate;
6911
6912
    /*
6913
     * We know that '<?xml' is here.
6914
     */
6915
0
    if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
6916
0
  SKIP(5);
6917
0
    } else {
6918
0
  xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_STARTED, NULL);
6919
0
  return;
6920
0
    }
6921
6922
    /* Avoid expansion of parameter entities when skipping blanks. */
6923
0
    oldstate = ctxt->instate;
6924
0
    ctxt->instate = XML_PARSER_START;
6925
6926
0
    if (SKIP_BLANKS == 0) {
6927
0
  xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6928
0
           "Space needed after '<?xml'\n");
6929
0
    }
6930
6931
    /*
6932
     * We may have the VersionInfo here.
6933
     */
6934
0
    version = xmlParseVersionInfo(ctxt);
6935
0
    if (version == NULL)
6936
0
  version = xmlCharStrdup(XML_DEFAULT_VERSION);
6937
0
    else {
6938
0
  if (SKIP_BLANKS == 0) {
6939
0
      xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6940
0
               "Space needed here\n");
6941
0
  }
6942
0
    }
6943
0
    ctxt->input->version = version;
6944
6945
    /*
6946
     * We must have the encoding declaration
6947
     */
6948
0
    encoding = xmlParseEncodingDecl(ctxt);
6949
0
    if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
6950
  /*
6951
   * The XML REC instructs us to stop parsing right here
6952
   */
6953
0
        ctxt->instate = oldstate;
6954
0
        return;
6955
0
    }
6956
0
    if ((encoding == NULL) && (ctxt->errNo == XML_ERR_OK)) {
6957
0
  xmlFatalErrMsg(ctxt, XML_ERR_MISSING_ENCODING,
6958
0
           "Missing encoding in text declaration\n");
6959
0
    }
6960
6961
0
    SKIP_BLANKS;
6962
0
    if ((RAW == '?') && (NXT(1) == '>')) {
6963
0
        SKIP(2);
6964
0
    } else if (RAW == '>') {
6965
        /* Deprecated old WD ... */
6966
0
  xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
6967
0
  NEXT;
6968
0
    } else {
6969
0
  xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
6970
0
  MOVETO_ENDTAG(CUR_PTR);
6971
0
  NEXT;
6972
0
    }
6973
6974
0
    ctxt->instate = oldstate;
6975
0
}
6976
6977
/**
6978
 * xmlParseExternalSubset:
6979
 * @ctxt:  an XML parser context
6980
 * @ExternalID: the external identifier
6981
 * @SystemID: the system identifier (or URL)
6982
 *
6983
 * parse Markup declarations from an external subset
6984
 *
6985
 * [30] extSubset ::= textDecl? extSubsetDecl
6986
 *
6987
 * [31] extSubsetDecl ::= (markupdecl | conditionalSect | PEReference | S) *
6988
 */
6989
void
6990
xmlParseExternalSubset(xmlParserCtxtPtr ctxt, const xmlChar *ExternalID,
6991
0
                       const xmlChar *SystemID) {
6992
0
    xmlDetectSAX2(ctxt);
6993
0
    GROW;
6994
6995
0
    if ((ctxt->encoding == NULL) &&
6996
0
        (ctxt->input->end - ctxt->input->cur >= 4)) {
6997
0
        xmlChar start[4];
6998
0
  xmlCharEncoding enc;
6999
7000
0
  start[0] = RAW;
7001
0
  start[1] = NXT(1);
7002
0
  start[2] = NXT(2);
7003
0
  start[3] = NXT(3);
7004
0
  enc = xmlDetectCharEncoding(start, 4);
7005
0
  if (enc != XML_CHAR_ENCODING_NONE)
7006
0
      xmlSwitchEncoding(ctxt, enc);
7007
0
    }
7008
7009
0
    if (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) {
7010
0
  xmlParseTextDecl(ctxt);
7011
0
  if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
7012
      /*
7013
       * The XML REC instructs us to stop parsing right here
7014
       */
7015
0
      xmlHaltParser(ctxt);
7016
0
      return;
7017
0
  }
7018
0
    }
7019
0
    if (ctxt->myDoc == NULL) {
7020
0
        ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
7021
0
  if (ctxt->myDoc == NULL) {
7022
0
      xmlErrMemory(ctxt, "New Doc failed");
7023
0
      return;
7024
0
  }
7025
0
  ctxt->myDoc->properties = XML_DOC_INTERNAL;
7026
0
    }
7027
0
    if ((ctxt->myDoc != NULL) && (ctxt->myDoc->intSubset == NULL))
7028
0
        xmlCreateIntSubset(ctxt->myDoc, NULL, ExternalID, SystemID);
7029
7030
0
    ctxt->instate = XML_PARSER_DTD;
7031
0
    ctxt->external = 1;
7032
0
    SKIP_BLANKS;
7033
0
    while (((RAW == '<') && (NXT(1) == '?')) ||
7034
0
           ((RAW == '<') && (NXT(1) == '!')) ||
7035
0
     (RAW == '%')) {
7036
0
  int id = ctxt->input->id;
7037
0
  unsigned long cons = CUR_CONSUMED;
7038
7039
0
  GROW;
7040
0
        if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
7041
0
      xmlParseConditionalSections(ctxt);
7042
0
  } else
7043
0
      xmlParseMarkupDecl(ctxt);
7044
0
        SKIP_BLANKS;
7045
7046
0
  if ((id == ctxt->input->id) && (cons == CUR_CONSUMED)) {
7047
0
      xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
7048
0
      break;
7049
0
  }
7050
0
    }
7051
7052
0
    if (RAW != 0) {
7053
0
  xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
7054
0
    }
7055
7056
0
}
7057
7058
/**
7059
 * xmlParseReference:
7060
 * @ctxt:  an XML parser context
7061
 *
7062
 * parse and handle entity references in content, depending on the SAX
7063
 * interface, this may end-up in a call to character() if this is a
7064
 * CharRef, a predefined entity, if there is no reference() callback.
7065
 * or if the parser was asked to switch to that mode.
7066
 *
7067
 * [67] Reference ::= EntityRef | CharRef
7068
 */
7069
void
7070
534k
xmlParseReference(xmlParserCtxtPtr ctxt) {
7071
534k
    xmlEntityPtr ent;
7072
534k
    xmlChar *val;
7073
534k
    int was_checked;
7074
534k
    xmlNodePtr list = NULL;
7075
534k
    xmlParserErrors ret = XML_ERR_OK;
7076
7077
7078
534k
    if (RAW != '&')
7079
0
        return;
7080
7081
    /*
7082
     * Simple case of a CharRef
7083
     */
7084
534k
    if (NXT(1) == '#') {
7085
28.9k
  int i = 0;
7086
28.9k
  xmlChar out[16];
7087
28.9k
  int hex = NXT(2);
7088
28.9k
  int value = xmlParseCharRef(ctxt);
7089
7090
28.9k
  if (value == 0)
7091
12.9k
      return;
7092
15.9k
  if (ctxt->charset != XML_CHAR_ENCODING_UTF8) {
7093
      /*
7094
       * So we are using non-UTF-8 buffers
7095
       * Check that the char fit on 8bits, if not
7096
       * generate a CharRef.
7097
       */
7098
8.61k
      if (value <= 0xFF) {
7099
8.04k
    out[0] = value;
7100
8.04k
    out[1] = 0;
7101
8.04k
    if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
7102
8.04k
        (!ctxt->disableSAX))
7103
0
        ctxt->sax->characters(ctxt->userData, out, 1);
7104
8.04k
      } else {
7105
567
    if ((hex == 'x') || (hex == 'X'))
7106
224
        snprintf((char *)out, sizeof(out), "#x%X", value);
7107
343
    else
7108
343
        snprintf((char *)out, sizeof(out), "#%d", value);
7109
567
    if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
7110
567
        (!ctxt->disableSAX))
7111
0
        ctxt->sax->reference(ctxt->userData, out);
7112
567
      }
7113
8.61k
  } else {
7114
      /*
7115
       * Just encode the value in UTF-8
7116
       */
7117
7.36k
      COPY_BUF(0 ,out, i, value);
7118
7.36k
      out[i] = 0;
7119
7.36k
      if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
7120
7.36k
    (!ctxt->disableSAX))
7121
2.97k
    ctxt->sax->characters(ctxt->userData, out, i);
7122
7.36k
  }
7123
15.9k
  return;
7124
28.9k
    }
7125
7126
    /*
7127
     * We are seeing an entity reference
7128
     */
7129
505k
    ent = xmlParseEntityRef(ctxt);
7130
505k
    if (ent == NULL) return;
7131
481k
    if (!ctxt->wellFormed)
7132
29.5k
  return;
7133
451k
    was_checked = ent->checked;
7134
7135
    /* special case of predefined entities */
7136
451k
    if ((ent->name == NULL) ||
7137
451k
        (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
7138
4.94k
  val = ent->content;
7139
4.94k
  if (val == NULL) return;
7140
  /*
7141
   * inline the entity.
7142
   */
7143
4.94k
  if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
7144
4.94k
      (!ctxt->disableSAX))
7145
4.94k
      ctxt->sax->characters(ctxt->userData, val, xmlStrlen(val));
7146
4.94k
  return;
7147
4.94k
    }
7148
7149
    /*
7150
     * The first reference to the entity trigger a parsing phase
7151
     * where the ent->children is filled with the result from
7152
     * the parsing.
7153
     * Note: external parsed entities will not be loaded, it is not
7154
     * required for a non-validating parser, unless the parsing option
7155
     * of validating, or substituting entities were given. Doing so is
7156
     * far more secure as the parser will only process data coming from
7157
     * the document entity by default.
7158
     */
7159
446k
    if (((ent->checked == 0) ||
7160
446k
         ((ent->children == NULL) && (ctxt->options & XML_PARSE_NOENT))) &&
7161
446k
        ((ent->etype != XML_EXTERNAL_GENERAL_PARSED_ENTITY) ||
7162
299k
         (ctxt->options & (XML_PARSE_NOENT | XML_PARSE_DTDVALID)))) {
7163
299k
  unsigned long oldnbent = ctxt->nbentities, diff;
7164
7165
  /*
7166
   * This is a bit hackish but this seems the best
7167
   * way to make sure both SAX and DOM entity support
7168
   * behaves okay.
7169
   */
7170
299k
  void *user_data;
7171
299k
  if (ctxt->userData == ctxt)
7172
299k
      user_data = NULL;
7173
0
  else
7174
0
      user_data = ctxt->userData;
7175
7176
  /*
7177
   * Check that this entity is well formed
7178
   * 4.3.2: An internal general parsed entity is well-formed
7179
   * if its replacement text matches the production labeled
7180
   * content.
7181
   */
7182
299k
  if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
7183
299k
      ctxt->depth++;
7184
299k
      ret = xmlParseBalancedChunkMemoryInternal(ctxt, ent->content,
7185
299k
                                                user_data, &list);
7186
299k
      ctxt->depth--;
7187
7188
299k
  } else if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
7189
0
      ctxt->depth++;
7190
0
      ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt, ctxt->sax,
7191
0
                                     user_data, ctxt->depth, ent->URI,
7192
0
             ent->ExternalID, &list);
7193
0
      ctxt->depth--;
7194
0
  } else {
7195
0
      ret = XML_ERR_ENTITY_PE_INTERNAL;
7196
0
      xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
7197
0
       "invalid entity type found\n", NULL);
7198
0
  }
7199
7200
  /*
7201
   * Store the number of entities needing parsing for this entity
7202
   * content and do checkings
7203
   */
7204
299k
        diff = ctxt->nbentities - oldnbent + 1;
7205
299k
        if (diff > INT_MAX / 2)
7206
297
            diff = INT_MAX / 2;
7207
299k
        ent->checked = diff * 2;
7208
299k
  if ((ent->content != NULL) && (xmlStrchr(ent->content, '<')))
7209
105k
      ent->checked |= 1;
7210
299k
  if (ret == XML_ERR_ENTITY_LOOP) {
7211
232k
      xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
7212
232k
            xmlHaltParser(ctxt);
7213
232k
      xmlFreeNodeList(list);
7214
232k
      return;
7215
232k
  }
7216
66.6k
  if (xmlParserEntityCheck(ctxt, 0, ent, 0)) {
7217
0
      xmlFreeNodeList(list);
7218
0
      return;
7219
0
  }
7220
7221
66.6k
  if ((ret == XML_ERR_OK) && (list != NULL)) {
7222
255
      if (((ent->etype == XML_INTERNAL_GENERAL_ENTITY) ||
7223
255
       (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY))&&
7224
255
    (ent->children == NULL)) {
7225
109
    ent->children = list;
7226
                /*
7227
                 * Prune it directly in the generated document
7228
                 * except for single text nodes.
7229
                 */
7230
109
                if ((ctxt->replaceEntities == 0) ||
7231
109
                    (ctxt->parseMode == XML_PARSE_READER) ||
7232
109
                    ((list->type == XML_TEXT_NODE) &&
7233
109
                     (list->next == NULL))) {
7234
109
                    ent->owner = 1;
7235
578
                    while (list != NULL) {
7236
469
                        list->parent = (xmlNodePtr) ent;
7237
469
                        xmlSetTreeDoc(list, ent->doc);
7238
469
                        if (list->next == NULL)
7239
109
                            ent->last = list;
7240
469
                        list = list->next;
7241
469
                    }
7242
109
                    list = NULL;
7243
109
                } else {
7244
0
                    ent->owner = 0;
7245
0
                    while (list != NULL) {
7246
0
                        list->parent = (xmlNodePtr) ctxt->node;
7247
0
                        list->doc = ctxt->myDoc;
7248
0
                        if (list->next == NULL)
7249
0
                            ent->last = list;
7250
0
                        list = list->next;
7251
0
                    }
7252
0
                    list = ent->children;
7253
#ifdef LIBXML_LEGACY_ENABLED
7254
                    if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
7255
                        xmlAddEntityReference(ent, list, NULL);
7256
#endif /* LIBXML_LEGACY_ENABLED */
7257
0
                }
7258
146
      } else {
7259
146
    xmlFreeNodeList(list);
7260
146
    list = NULL;
7261
146
      }
7262
66.3k
  } else if ((ret != XML_ERR_OK) &&
7263
66.3k
       (ret != XML_WAR_UNDECLARED_ENTITY)) {
7264
66.1k
      xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
7265
66.1k
         "Entity '%s' failed to parse\n", ent->name);
7266
66.1k
            if (ent->content != NULL)
7267
66.1k
                ent->content[0] = 0;
7268
66.1k
      xmlParserEntityCheck(ctxt, 0, ent, 0);
7269
66.1k
  } else if (list != NULL) {
7270
0
      xmlFreeNodeList(list);
7271
0
      list = NULL;
7272
0
  }
7273
66.6k
  if (ent->checked == 0)
7274
0
      ent->checked = 2;
7275
7276
        /* Prevent entity from being parsed and expanded twice (Bug 760367). */
7277
66.6k
        was_checked = 0;
7278
147k
    } else if (ent->checked != 1) {
7279
147k
  ctxt->nbentities += ent->checked / 2;
7280
147k
    }
7281
7282
    /*
7283
     * Now that the entity content has been gathered
7284
     * provide it to the application, this can take different forms based
7285
     * on the parsing modes.
7286
     */
7287
213k
    if (ent->children == NULL) {
7288
  /*
7289
   * Probably running in SAX mode and the callbacks don't
7290
   * build the entity content. So unless we already went
7291
   * though parsing for first checking go though the entity
7292
   * content to generate callbacks associated to the entity
7293
   */
7294
200k
  if (was_checked != 0) {
7295
133k
      void *user_data;
7296
      /*
7297
       * This is a bit hackish but this seems the best
7298
       * way to make sure both SAX and DOM entity support
7299
       * behaves okay.
7300
       */
7301
133k
      if (ctxt->userData == ctxt)
7302
133k
    user_data = NULL;
7303
0
      else
7304
0
    user_data = ctxt->userData;
7305
7306
133k
      if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
7307
133k
    ctxt->depth++;
7308
133k
    ret = xmlParseBalancedChunkMemoryInternal(ctxt,
7309
133k
           ent->content, user_data, NULL);
7310
133k
    ctxt->depth--;
7311
133k
      } else if (ent->etype ==
7312
0
           XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
7313
0
    ctxt->depth++;
7314
0
    ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt,
7315
0
         ctxt->sax, user_data, ctxt->depth,
7316
0
         ent->URI, ent->ExternalID, NULL);
7317
0
    ctxt->depth--;
7318
0
      } else {
7319
0
    ret = XML_ERR_ENTITY_PE_INTERNAL;
7320
0
    xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
7321
0
           "invalid entity type found\n", NULL);
7322
0
      }
7323
133k
      if (ret == XML_ERR_ENTITY_LOOP) {
7324
131
    xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
7325
131
    return;
7326
131
      }
7327
133k
  }
7328
199k
  if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
7329
199k
      (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
7330
      /*
7331
       * Entity reference callback comes second, it's somewhat
7332
       * superfluous but a compatibility to historical behaviour
7333
       */
7334
133k
      ctxt->sax->reference(ctxt->userData, ent->name);
7335
133k
  }
7336
199k
  return;
7337
200k
    }
7338
7339
    /*
7340
     * If we didn't get any children for the entity being built
7341
     */
7342
13.6k
    if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
7343
13.6k
  (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
7344
  /*
7345
   * Create a node.
7346
   */
7347
13.6k
  ctxt->sax->reference(ctxt->userData, ent->name);
7348
13.6k
  return;
7349
13.6k
    }
7350
7351
4
    if ((ctxt->replaceEntities) || (ent->children == NULL))  {
7352
  /*
7353
   * There is a problem on the handling of _private for entities
7354
   * (bug 155816): Should we copy the content of the field from
7355
   * the entity (possibly overwriting some value set by the user
7356
   * when a copy is created), should we leave it alone, or should
7357
   * we try to take care of different situations?  The problem
7358
   * is exacerbated by the usage of this field by the xmlReader.
7359
   * To fix this bug, we look at _private on the created node
7360
   * and, if it's NULL, we copy in whatever was in the entity.
7361
   * If it's not NULL we leave it alone.  This is somewhat of a
7362
   * hack - maybe we should have further tests to determine
7363
   * what to do.
7364
   */
7365
0
  if ((ctxt->node != NULL) && (ent->children != NULL)) {
7366
      /*
7367
       * Seems we are generating the DOM content, do
7368
       * a simple tree copy for all references except the first
7369
       * In the first occurrence list contains the replacement.
7370
       */
7371
0
      if (((list == NULL) && (ent->owner == 0)) ||
7372
0
    (ctxt->parseMode == XML_PARSE_READER)) {
7373
0
    xmlNodePtr nw = NULL, cur, firstChild = NULL;
7374
7375
    /*
7376
     * We are copying here, make sure there is no abuse
7377
     */
7378
0
    ctxt->sizeentcopy += ent->length + 5;
7379
0
    if (xmlParserEntityCheck(ctxt, 0, ent, ctxt->sizeentcopy))
7380
0
        return;
7381
7382
    /*
7383
     * when operating on a reader, the entities definitions
7384
     * are always owning the entities subtree.
7385
    if (ctxt->parseMode == XML_PARSE_READER)
7386
        ent->owner = 1;
7387
     */
7388
7389
0
    cur = ent->children;
7390
0
    while (cur != NULL) {
7391
0
        nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
7392
0
        if (nw != NULL) {
7393
0
      if (nw->_private == NULL)
7394
0
          nw->_private = cur->_private;
7395
0
      if (firstChild == NULL){
7396
0
          firstChild = nw;
7397
0
      }
7398
0
      nw = xmlAddChild(ctxt->node, nw);
7399
0
        }
7400
0
        if (cur == ent->last) {
7401
      /*
7402
       * needed to detect some strange empty
7403
       * node cases in the reader tests
7404
       */
7405
0
      if ((ctxt->parseMode == XML_PARSE_READER) &&
7406
0
          (nw != NULL) &&
7407
0
          (nw->type == XML_ELEMENT_NODE) &&
7408
0
          (nw->children == NULL))
7409
0
          nw->extra = 1;
7410
7411
0
      break;
7412
0
        }
7413
0
        cur = cur->next;
7414
0
    }
7415
#ifdef LIBXML_LEGACY_ENABLED
7416
    if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
7417
      xmlAddEntityReference(ent, firstChild, nw);
7418
#endif /* LIBXML_LEGACY_ENABLED */
7419
0
      } else if ((list == NULL) || (ctxt->inputNr > 0)) {
7420
0
    xmlNodePtr nw = NULL, cur, next, last,
7421
0
         firstChild = NULL;
7422
7423
    /*
7424
     * We are copying here, make sure there is no abuse
7425
     */
7426
0
    ctxt->sizeentcopy += ent->length + 5;
7427
0
    if (xmlParserEntityCheck(ctxt, 0, ent, ctxt->sizeentcopy))
7428
0
        return;
7429
7430
    /*
7431
     * Copy the entity child list and make it the new
7432
     * entity child list. The goal is to make sure any
7433
     * ID or REF referenced will be the one from the
7434
     * document content and not the entity copy.
7435
     */
7436
0
    cur = ent->children;
7437
0
    ent->children = NULL;
7438
0
    last = ent->last;
7439
0
    ent->last = NULL;
7440
0
    while (cur != NULL) {
7441
0
        next = cur->next;
7442
0
        cur->next = NULL;
7443
0
        cur->parent = NULL;
7444
0
        nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
7445
0
        if (nw != NULL) {
7446
0
      if (nw->_private == NULL)
7447
0
          nw->_private = cur->_private;
7448
0
      if (firstChild == NULL){
7449
0
          firstChild = cur;
7450
0
      }
7451
0
      xmlAddChild((xmlNodePtr) ent, nw);
7452
0
      xmlAddChild(ctxt->node, cur);
7453
0
        }
7454
0
        if (cur == last)
7455
0
      break;
7456
0
        cur = next;
7457
0
    }
7458
0
    if (ent->owner == 0)
7459
0
        ent->owner = 1;
7460
#ifdef LIBXML_LEGACY_ENABLED
7461
    if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
7462
      xmlAddEntityReference(ent, firstChild, nw);
7463
#endif /* LIBXML_LEGACY_ENABLED */
7464
0
      } else {
7465
0
    const xmlChar *nbktext;
7466
7467
    /*
7468
     * the name change is to avoid coalescing of the
7469
     * node with a possible previous text one which
7470
     * would make ent->children a dangling pointer
7471
     */
7472
0
    nbktext = xmlDictLookup(ctxt->dict, BAD_CAST "nbktext",
7473
0
          -1);
7474
0
    if (ent->children->type == XML_TEXT_NODE)
7475
0
        ent->children->name = nbktext;
7476
0
    if ((ent->last != ent->children) &&
7477
0
        (ent->last->type == XML_TEXT_NODE))
7478
0
        ent->last->name = nbktext;
7479
0
    xmlAddChildList(ctxt->node, ent->children);
7480
0
      }
7481
7482
      /*
7483
       * This is to avoid a nasty side effect, see
7484
       * characters() in SAX.c
7485
       */
7486
0
      ctxt->nodemem = 0;
7487
0
      ctxt->nodelen = 0;
7488
0
      return;
7489
0
  }
7490
0
    }
7491
4
}
7492
7493
/**
7494
 * xmlParseEntityRef:
7495
 * @ctxt:  an XML parser context
7496
 *
7497
 * parse ENTITY references declarations
7498
 *
7499
 * [68] EntityRef ::= '&' Name ';'
7500
 *
7501
 * [ WFC: Entity Declared ]
7502
 * In a document without any DTD, a document with only an internal DTD
7503
 * subset which contains no parameter entity references, or a document
7504
 * with "standalone='yes'", the Name given in the entity reference
7505
 * must match that in an entity declaration, except that well-formed
7506
 * documents need not declare any of the following entities: amp, lt,
7507
 * gt, apos, quot.  The declaration of a parameter entity must precede
7508
 * any reference to it.  Similarly, the declaration of a general entity
7509
 * must precede any reference to it which appears in a default value in an
7510
 * attribute-list declaration. Note that if entities are declared in the
7511
 * external subset or in external parameter entities, a non-validating
7512
 * processor is not obligated to read and process their declarations;
7513
 * for such documents, the rule that an entity must be declared is a
7514
 * well-formedness constraint only if standalone='yes'.
7515
 *
7516
 * [ WFC: Parsed Entity ]
7517
 * An entity reference must not contain the name of an unparsed entity
7518
 *
7519
 * Returns the xmlEntityPtr if found, or NULL otherwise.
7520
 */
7521
xmlEntityPtr
7522
974k
xmlParseEntityRef(xmlParserCtxtPtr ctxt) {
7523
974k
    const xmlChar *name;
7524
974k
    xmlEntityPtr ent = NULL;
7525
7526
974k
    GROW;
7527
974k
    if (ctxt->instate == XML_PARSER_EOF)
7528
0
        return(NULL);
7529
7530
974k
    if (RAW != '&')
7531
0
        return(NULL);
7532
974k
    NEXT;
7533
974k
    name = xmlParseName(ctxt);
7534
974k
    if (name == NULL) {
7535
78.5k
  xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
7536
78.5k
           "xmlParseEntityRef: no name\n");
7537
78.5k
        return(NULL);
7538
78.5k
    }
7539
896k
    if (RAW != ';') {
7540
26.2k
  xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
7541
26.2k
  return(NULL);
7542
26.2k
    }
7543
870k
    NEXT;
7544
7545
    /*
7546
     * Predefined entities override any extra definition
7547
     */
7548
870k
    if ((ctxt->options & XML_PARSE_OLDSAX) == 0) {
7549
870k
        ent = xmlGetPredefinedEntity(name);
7550
870k
        if (ent != NULL)
7551
18.0k
            return(ent);
7552
870k
    }
7553
7554
    /*
7555
     * Increase the number of entity references parsed
7556
     */
7557
852k
    ctxt->nbentities++;
7558
7559
    /*
7560
     * Ask first SAX for entity resolution, otherwise try the
7561
     * entities which may have stored in the parser context.
7562
     */
7563
852k
    if (ctxt->sax != NULL) {
7564
852k
  if (ctxt->sax->getEntity != NULL)
7565
852k
      ent = ctxt->sax->getEntity(ctxt->userData, name);
7566
852k
  if ((ctxt->wellFormed == 1 ) && (ent == NULL) &&
7567
852k
      (ctxt->options & XML_PARSE_OLDSAX))
7568
0
      ent = xmlGetPredefinedEntity(name);
7569
852k
  if ((ctxt->wellFormed == 1 ) && (ent == NULL) &&
7570
852k
      (ctxt->userData==ctxt)) {
7571
11.9k
      ent = xmlSAX2GetEntity(ctxt, name);
7572
11.9k
  }
7573
852k
    }
7574
852k
    if (ctxt->instate == XML_PARSER_EOF)
7575
0
  return(NULL);
7576
    /*
7577
     * [ WFC: Entity Declared ]
7578
     * In a document without any DTD, a document with only an
7579
     * internal DTD subset which contains no parameter entity
7580
     * references, or a document with "standalone='yes'", the
7581
     * Name given in the entity reference must match that in an
7582
     * entity declaration, except that well-formed documents
7583
     * need not declare any of the following entities: amp, lt,
7584
     * gt, apos, quot.
7585
     * The declaration of a parameter entity must precede any
7586
     * reference to it.
7587
     * Similarly, the declaration of a general entity must
7588
     * precede any reference to it which appears in a default
7589
     * value in an attribute-list declaration. Note that if
7590
     * entities are declared in the external subset or in
7591
     * external parameter entities, a non-validating processor
7592
     * is not obligated to read and process their declarations;
7593
     * for such documents, the rule that an entity must be
7594
     * declared is a well-formedness constraint only if
7595
     * standalone='yes'.
7596
     */
7597
852k
    if (ent == NULL) {
7598
53.9k
  if ((ctxt->standalone == 1) ||
7599
53.9k
      ((ctxt->hasExternalSubset == 0) &&
7600
53.5k
       (ctxt->hasPErefs == 0))) {
7601
40.0k
      xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
7602
40.0k
         "Entity '%s' not defined\n", name);
7603
40.0k
  } else {
7604
13.8k
      xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
7605
13.8k
         "Entity '%s' not defined\n", name);
7606
13.8k
      if ((ctxt->inSubset == 0) &&
7607
13.8k
    (ctxt->sax != NULL) &&
7608
13.8k
    (ctxt->sax->reference != NULL)) {
7609
12.7k
    ctxt->sax->reference(ctxt->userData, name);
7610
12.7k
      }
7611
13.8k
  }
7612
53.9k
  xmlParserEntityCheck(ctxt, 0, ent, 0);
7613
53.9k
  ctxt->valid = 0;
7614
53.9k
    }
7615
7616
    /*
7617
     * [ WFC: Parsed Entity ]
7618
     * An entity reference must not contain the name of an
7619
     * unparsed entity
7620
     */
7621
798k
    else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
7622
194
  xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
7623
194
     "Entity reference to unparsed entity %s\n", name);
7624
194
    }
7625
7626
    /*
7627
     * [ WFC: No External Entity References ]
7628
     * Attribute values cannot contain direct or indirect
7629
     * entity references to external entities.
7630
     */
7631
797k
    else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
7632
797k
       (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
7633
312k
  xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
7634
312k
       "Attribute references external entity '%s'\n", name);
7635
312k
    }
7636
    /*
7637
     * [ WFC: No < in Attribute Values ]
7638
     * The replacement text of any entity referred to directly or
7639
     * indirectly in an attribute value (other than "&lt;") must
7640
     * not contain a <.
7641
     */
7642
485k
    else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
7643
485k
       (ent != NULL) && 
7644
485k
       (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY)) {
7645
19.4k
  if (((ent->checked & 1) || (ent->checked == 0)) &&
7646
19.4k
       (ent->content != NULL) && (xmlStrchr(ent->content, '<'))) {
7647
395
      xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
7648
395
  "'<' in entity '%s' is not allowed in attributes values\n", name);
7649
395
        }
7650
19.4k
    }
7651
7652
    /*
7653
     * Internal check, no parameter entities here ...
7654
     */
7655
466k
    else {
7656
466k
  switch (ent->etype) {
7657
0
      case XML_INTERNAL_PARAMETER_ENTITY:
7658
0
      case XML_EXTERNAL_PARAMETER_ENTITY:
7659
0
      xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
7660
0
       "Attempt to reference the parameter entity '%s'\n",
7661
0
            name);
7662
0
      break;
7663
466k
      default:
7664
466k
      break;
7665
466k
  }
7666
466k
    }
7667
7668
    /*
7669
     * [ WFC: No Recursion ]
7670
     * A parsed entity must not contain a recursive reference
7671
     * to itself, either directly or indirectly.
7672
     * Done somewhere else
7673
     */
7674
852k
    return(ent);
7675
852k
}
7676
7677
/**
7678
 * xmlParseStringEntityRef:
7679
 * @ctxt:  an XML parser context
7680
 * @str:  a pointer to an index in the string
7681
 *
7682
 * parse ENTITY references declarations, but this version parses it from
7683
 * a string value.
7684
 *
7685
 * [68] EntityRef ::= '&' Name ';'
7686
 *
7687
 * [ WFC: Entity Declared ]
7688
 * In a document without any DTD, a document with only an internal DTD
7689
 * subset which contains no parameter entity references, or a document
7690
 * with "standalone='yes'", the Name given in the entity reference
7691
 * must match that in an entity declaration, except that well-formed
7692
 * documents need not declare any of the following entities: amp, lt,
7693
 * gt, apos, quot.  The declaration of a parameter entity must precede
7694
 * any reference to it.  Similarly, the declaration of a general entity
7695
 * must precede any reference to it which appears in a default value in an
7696
 * attribute-list declaration. Note that if entities are declared in the
7697
 * external subset or in external parameter entities, a non-validating
7698
 * processor is not obligated to read and process their declarations;
7699
 * for such documents, the rule that an entity must be declared is a
7700
 * well-formedness constraint only if standalone='yes'.
7701
 *
7702
 * [ WFC: Parsed Entity ]
7703
 * An entity reference must not contain the name of an unparsed entity
7704
 *
7705
 * Returns the xmlEntityPtr if found, or NULL otherwise. The str pointer
7706
 * is updated to the current location in the string.
7707
 */
7708
static xmlEntityPtr
7709
2.01M
xmlParseStringEntityRef(xmlParserCtxtPtr ctxt, const xmlChar ** str) {
7710
2.01M
    xmlChar *name;
7711
2.01M
    const xmlChar *ptr;
7712
2.01M
    xmlChar cur;
7713
2.01M
    xmlEntityPtr ent = NULL;
7714
7715
2.01M
    if ((str == NULL) || (*str == NULL))
7716
0
        return(NULL);
7717
2.01M
    ptr = *str;
7718
2.01M
    cur = *ptr;
7719
2.01M
    if (cur != '&')
7720
0
  return(NULL);
7721
7722
2.01M
    ptr++;
7723
2.01M
    name = xmlParseStringName(ctxt, &ptr);
7724
2.01M
    if (name == NULL) {
7725
11.3k
  xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
7726
11.3k
           "xmlParseStringEntityRef: no name\n");
7727
11.3k
  *str = ptr;
7728
11.3k
  return(NULL);
7729
11.3k
    }
7730
2.00M
    if (*ptr != ';') {
7731
5.74k
  xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
7732
5.74k
        xmlFree(name);
7733
5.74k
  *str = ptr;
7734
5.74k
  return(NULL);
7735
5.74k
    }
7736
1.99M
    ptr++;
7737
7738
7739
    /*
7740
     * Predefined entities override any extra definition
7741
     */
7742
1.99M
    if ((ctxt->options & XML_PARSE_OLDSAX) == 0) {
7743
1.99M
        ent = xmlGetPredefinedEntity(name);
7744
1.99M
        if (ent != NULL) {
7745
15.2k
            xmlFree(name);
7746
15.2k
            *str = ptr;
7747
15.2k
            return(ent);
7748
15.2k
        }
7749
1.99M
    }
7750
7751
    /*
7752
     * Increase the number of entity references parsed
7753
     */
7754
1.98M
    ctxt->nbentities++;
7755
7756
    /*
7757
     * Ask first SAX for entity resolution, otherwise try the
7758
     * entities which may have stored in the parser context.
7759
     */
7760
1.98M
    if (ctxt->sax != NULL) {
7761
1.98M
  if (ctxt->sax->getEntity != NULL)
7762
1.98M
      ent = ctxt->sax->getEntity(ctxt->userData, name);
7763
1.98M
  if ((ent == NULL) && (ctxt->options & XML_PARSE_OLDSAX))
7764
0
      ent = xmlGetPredefinedEntity(name);
7765
1.98M
  if ((ent == NULL) && (ctxt->userData==ctxt)) {
7766
219k
      ent = xmlSAX2GetEntity(ctxt, name);
7767
219k
  }
7768
1.98M
    }
7769
1.98M
    if (ctxt->instate == XML_PARSER_EOF) {
7770
0
  xmlFree(name);
7771
0
  return(NULL);
7772
0
    }
7773
7774
    /*
7775
     * [ WFC: Entity Declared ]
7776
     * In a document without any DTD, a document with only an
7777
     * internal DTD subset which contains no parameter entity
7778
     * references, or a document with "standalone='yes'", the
7779
     * Name given in the entity reference must match that in an
7780
     * entity declaration, except that well-formed documents
7781
     * need not declare any of the following entities: amp, lt,
7782
     * gt, apos, quot.
7783
     * The declaration of a parameter entity must precede any
7784
     * reference to it.
7785
     * Similarly, the declaration of a general entity must
7786
     * precede any reference to it which appears in a default
7787
     * value in an attribute-list declaration. Note that if
7788
     * entities are declared in the external subset or in
7789
     * external parameter entities, a non-validating processor
7790
     * is not obligated to read and process their declarations;
7791
     * for such documents, the rule that an entity must be
7792
     * declared is a well-formedness constraint only if
7793
     * standalone='yes'.
7794
     */
7795
1.98M
    if (ent == NULL) {
7796
219k
  if ((ctxt->standalone == 1) ||
7797
219k
      ((ctxt->hasExternalSubset == 0) &&
7798
219k
       (ctxt->hasPErefs == 0))) {
7799
214k
      xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
7800
214k
         "Entity '%s' not defined\n", name);
7801
214k
  } else {
7802
5.15k
      xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
7803
5.15k
        "Entity '%s' not defined\n",
7804
5.15k
        name);
7805
5.15k
  }
7806
219k
  xmlParserEntityCheck(ctxt, 0, ent, 0);
7807
  /* TODO ? check regressions ctxt->valid = 0; */
7808
219k
    }
7809
7810
    /*
7811
     * [ WFC: Parsed Entity ]
7812
     * An entity reference must not contain the name of an
7813
     * unparsed entity
7814
     */
7815
1.76M
    else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
7816
0
  xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
7817
0
     "Entity reference to unparsed entity %s\n", name);
7818
0
    }
7819
7820
    /*
7821
     * [ WFC: No External Entity References ]
7822
     * Attribute values cannot contain direct or indirect
7823
     * entity references to external entities.
7824
     */
7825
1.76M
    else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
7826
1.76M
       (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
7827
0
  xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
7828
0
   "Attribute references external entity '%s'\n", name);
7829
0
    }
7830
    /*
7831
     * [ WFC: No < in Attribute Values ]
7832
     * The replacement text of any entity referred to directly or
7833
     * indirectly in an attribute value (other than "&lt;") must
7834
     * not contain a <.
7835
     */
7836
1.76M
    else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
7837
1.76M
       (ent != NULL) && (ent->content != NULL) &&
7838
1.76M
       (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
7839
1.76M
       (xmlStrchr(ent->content, '<'))) {
7840
173k
  xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
7841
173k
     "'<' in entity '%s' is not allowed in attributes values\n",
7842
173k
        name);
7843
173k
    }
7844
7845
    /*
7846
     * Internal check, no parameter entities here ...
7847
     */
7848
1.58M
    else {
7849
1.58M
  switch (ent->etype) {
7850
0
      case XML_INTERNAL_PARAMETER_ENTITY:
7851
0
      case XML_EXTERNAL_PARAMETER_ENTITY:
7852
0
    xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
7853
0
       "Attempt to reference the parameter entity '%s'\n",
7854
0
          name);
7855
0
      break;
7856
1.58M
      default:
7857
1.58M
      break;
7858
1.58M
  }
7859
1.58M
    }
7860
7861
    /*
7862
     * [ WFC: No Recursion ]
7863
     * A parsed entity must not contain a recursive reference
7864
     * to itself, either directly or indirectly.
7865
     * Done somewhere else
7866
     */
7867
7868
1.98M
    xmlFree(name);
7869
1.98M
    *str = ptr;
7870
1.98M
    return(ent);
7871
1.98M
}
7872
7873
/**
7874
 * xmlParsePEReference:
7875
 * @ctxt:  an XML parser context
7876
 *
7877
 * parse PEReference declarations
7878
 * The entity content is handled directly by pushing it's content as
7879
 * a new input stream.
7880
 *
7881
 * [69] PEReference ::= '%' Name ';'
7882
 *
7883
 * [ WFC: No Recursion ]
7884
 * A parsed entity must not contain a recursive
7885
 * reference to itself, either directly or indirectly.
7886
 *
7887
 * [ WFC: Entity Declared ]
7888
 * In a document without any DTD, a document with only an internal DTD
7889
 * subset which contains no parameter entity references, or a document
7890
 * with "standalone='yes'", ...  ... The declaration of a parameter
7891
 * entity must precede any reference to it...
7892
 *
7893
 * [ VC: Entity Declared ]
7894
 * In a document with an external subset or external parameter entities
7895
 * with "standalone='no'", ...  ... The declaration of a parameter entity
7896
 * must precede any reference to it...
7897
 *
7898
 * [ WFC: In DTD ]
7899
 * Parameter-entity references may only appear in the DTD.
7900
 * NOTE: misleading but this is handled.
7901
 */
7902
void
7903
xmlParsePEReference(xmlParserCtxtPtr ctxt)
7904
14.0M
{
7905
14.0M
    const xmlChar *name;
7906
14.0M
    xmlEntityPtr entity = NULL;
7907
14.0M
    xmlParserInputPtr input;
7908
7909
14.0M
    if (RAW != '%')
7910
8.43M
        return;
7911
5.66M
    NEXT;
7912
5.66M
    name = xmlParseName(ctxt);
7913
5.66M
    if (name == NULL) {
7914
9.00k
  xmlFatalErrMsg(ctxt, XML_ERR_PEREF_NO_NAME, "PEReference: no name\n");
7915
9.00k
  return;
7916
9.00k
    }
7917
5.65M
    if (xmlParserDebugEntities)
7918
0
  xmlGenericError(xmlGenericErrorContext,
7919
0
    "PEReference: %s\n", name);
7920
5.65M
    if (RAW != ';') {
7921
4.56k
  xmlFatalErr(ctxt, XML_ERR_PEREF_SEMICOL_MISSING, NULL);
7922
4.56k
        return;
7923
4.56k
    }
7924
7925
5.64M
    NEXT;
7926
7927
    /*
7928
     * Increase the number of entity references parsed
7929
     */
7930
5.64M
    ctxt->nbentities++;
7931
7932
    /*
7933
     * Request the entity from SAX
7934
     */
7935
5.64M
    if ((ctxt->sax != NULL) &&
7936
5.64M
  (ctxt->sax->getParameterEntity != NULL))
7937
5.64M
  entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
7938
5.64M
    if (ctxt->instate == XML_PARSER_EOF)
7939
0
  return;
7940
5.64M
    if (entity == NULL) {
7941
  /*
7942
   * [ WFC: Entity Declared ]
7943
   * In a document without any DTD, a document with only an
7944
   * internal DTD subset which contains no parameter entity
7945
   * references, or a document with "standalone='yes'", ...
7946
   * ... The declaration of a parameter entity must precede
7947
   * any reference to it...
7948
   */
7949
6.73k
  if ((ctxt->standalone == 1) ||
7950
6.73k
      ((ctxt->hasExternalSubset == 0) &&
7951
6.53k
       (ctxt->hasPErefs == 0))) {
7952
426
      xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
7953
426
            "PEReference: %%%s; not found\n",
7954
426
            name);
7955
6.30k
  } else {
7956
      /*
7957
       * [ VC: Entity Declared ]
7958
       * In a document with an external subset or external
7959
       * parameter entities with "standalone='no'", ...
7960
       * ... The declaration of a parameter entity must
7961
       * precede any reference to it...
7962
       */
7963
6.30k
            if ((ctxt->validate) && (ctxt->vctxt.error != NULL)) {
7964
0
                xmlValidityError(ctxt, XML_WAR_UNDECLARED_ENTITY,
7965
0
                                 "PEReference: %%%s; not found\n",
7966
0
                                 name, NULL);
7967
0
            } else
7968
6.30k
                xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
7969
6.30k
                              "PEReference: %%%s; not found\n",
7970
6.30k
                              name, NULL);
7971
6.30k
            ctxt->valid = 0;
7972
6.30k
  }
7973
6.73k
  xmlParserEntityCheck(ctxt, 0, NULL, 0);
7974
5.64M
    } else {
7975
  /*
7976
   * Internal checking in case the entity quest barfed
7977
   */
7978
5.64M
  if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
7979
5.64M
      (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
7980
0
      xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
7981
0
      "Internal: %%%s; is not a parameter entity\n",
7982
0
        name, NULL);
7983
5.64M
  } else {
7984
5.64M
            xmlChar start[4];
7985
5.64M
            xmlCharEncoding enc;
7986
7987
5.64M
      if (xmlParserEntityCheck(ctxt, 0, entity, 0))
7988
0
          return;
7989
7990
5.64M
      if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
7991
5.64M
          ((ctxt->options & XML_PARSE_NOENT) == 0) &&
7992
5.64M
    ((ctxt->options & XML_PARSE_DTDVALID) == 0) &&
7993
5.64M
    ((ctxt->options & XML_PARSE_DTDLOAD) == 0) &&
7994
5.64M
    ((ctxt->options & XML_PARSE_DTDATTR) == 0) &&
7995
5.64M
    (ctxt->replaceEntities == 0) &&
7996
5.64M
    (ctxt->validate == 0))
7997
67
    return;
7998
7999
5.64M
      input = xmlNewEntityInputStream(ctxt, entity);
8000
5.64M
      if (xmlPushInput(ctxt, input) < 0) {
8001
4.07k
                xmlFreeInputStream(input);
8002
4.07k
    return;
8003
4.07k
            }
8004
8005
5.63M
      if (entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) {
8006
                /*
8007
                 * Get the 4 first bytes and decode the charset
8008
                 * if enc != XML_CHAR_ENCODING_NONE
8009
                 * plug some encoding conversion routines.
8010
                 * Note that, since we may have some non-UTF8
8011
                 * encoding (like UTF16, bug 135229), the 'length'
8012
                 * is not known, but we can calculate based upon
8013
                 * the amount of data in the buffer.
8014
                 */
8015
0
                GROW
8016
0
                if (ctxt->instate == XML_PARSER_EOF)
8017
0
                    return;
8018
0
                if ((ctxt->input->end - ctxt->input->cur)>=4) {
8019
0
                    start[0] = RAW;
8020
0
                    start[1] = NXT(1);
8021
0
                    start[2] = NXT(2);
8022
0
                    start[3] = NXT(3);
8023
0
                    enc = xmlDetectCharEncoding(start, 4);
8024
0
                    if (enc != XML_CHAR_ENCODING_NONE) {
8025
0
                        xmlSwitchEncoding(ctxt, enc);
8026
0
                    }
8027
0
                }
8028
8029
0
                if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) &&
8030
0
                    (IS_BLANK_CH(NXT(5)))) {
8031
0
                    xmlParseTextDecl(ctxt);
8032
0
                }
8033
0
            }
8034
5.63M
  }
8035
5.64M
    }
8036
5.64M
    ctxt->hasPErefs = 1;
8037
5.64M
}
8038
8039
/**
8040
 * xmlLoadEntityContent:
8041
 * @ctxt:  an XML parser context
8042
 * @entity: an unloaded system entity
8043
 *
8044
 * Load the original content of the given system entity from the
8045
 * ExternalID/SystemID given. This is to be used for Included in Literal
8046
 * http://www.w3.org/TR/REC-xml/#inliteral processing of entities references
8047
 *
8048
 * Returns 0 in case of success and -1 in case of failure
8049
 */
8050
static int
8051
0
xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
8052
0
    xmlParserInputPtr input;
8053
0
    xmlBufferPtr buf;
8054
0
    int l, c;
8055
0
    int count = 0;
8056
8057
0
    if ((ctxt == NULL) || (entity == NULL) ||
8058
0
        ((entity->etype != XML_EXTERNAL_PARAMETER_ENTITY) &&
8059
0
   (entity->etype != XML_EXTERNAL_GENERAL_PARSED_ENTITY)) ||
8060
0
  (entity->content != NULL)) {
8061
0
  xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
8062
0
              "xmlLoadEntityContent parameter error");
8063
0
        return(-1);
8064
0
    }
8065
8066
0
    if (xmlParserDebugEntities)
8067
0
  xmlGenericError(xmlGenericErrorContext,
8068
0
    "Reading %s entity content input\n", entity->name);
8069
8070
0
    buf = xmlBufferCreate();
8071
0
    if (buf == NULL) {
8072
0
  xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
8073
0
              "xmlLoadEntityContent parameter error");
8074
0
        return(-1);
8075
0
    }
8076
0
    xmlBufferSetAllocationScheme(buf, XML_BUFFER_ALLOC_DOUBLEIT);
8077
8078
0
    input = xmlNewEntityInputStream(ctxt, entity);
8079
0
    if (input == NULL) {
8080
0
  xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
8081
0
              "xmlLoadEntityContent input error");
8082
0
  xmlBufferFree(buf);
8083
0
        return(-1);
8084
0
    }
8085
8086
    /*
8087
     * Push the entity as the current input, read char by char
8088
     * saving to the buffer until the end of the entity or an error
8089
     */
8090
0
    if (xmlPushInput(ctxt, input) < 0) {
8091
0
        xmlBufferFree(buf);
8092
0
  return(-1);
8093
0
    }
8094
8095
0
    GROW;
8096
0
    c = CUR_CHAR(l);
8097
0
    while ((ctxt->input == input) && (ctxt->input->cur < ctxt->input->end) &&
8098
0
           (IS_CHAR(c))) {
8099
0
        xmlBufferAdd(buf, ctxt->input->cur, l);
8100
0
  if (count++ > XML_PARSER_CHUNK_SIZE) {
8101
0
      count = 0;
8102
0
      GROW;
8103
0
            if (ctxt->instate == XML_PARSER_EOF) {
8104
0
                xmlBufferFree(buf);
8105
0
                return(-1);
8106
0
            }
8107
0
  }
8108
0
  NEXTL(l);
8109
0
  c = CUR_CHAR(l);
8110
0
  if (c == 0) {
8111
0
      count = 0;
8112
0
      GROW;
8113
0
            if (ctxt->instate == XML_PARSER_EOF) {
8114
0
                xmlBufferFree(buf);
8115
0
                return(-1);
8116
0
            }
8117
0
      c = CUR_CHAR(l);
8118
0
  }
8119
0
    }
8120
8121
0
    if ((ctxt->input == input) && (ctxt->input->cur >= ctxt->input->end)) {
8122
0
        xmlPopInput(ctxt);
8123
0
    } else if (!IS_CHAR(c)) {
8124
0
        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
8125
0
                          "xmlLoadEntityContent: invalid char value %d\n",
8126
0
                    c);
8127
0
  xmlBufferFree(buf);
8128
0
  return(-1);
8129
0
    }
8130
0
    entity->content = buf->content;
8131
0
    buf->content = NULL;
8132
0
    xmlBufferFree(buf);
8133
8134
0
    return(0);
8135
0
}
8136
8137
/**
8138
 * xmlParseStringPEReference:
8139
 * @ctxt:  an XML parser context
8140
 * @str:  a pointer to an index in the string
8141
 *
8142
 * parse PEReference declarations
8143
 *
8144
 * [69] PEReference ::= '%' Name ';'
8145
 *
8146
 * [ WFC: No Recursion ]
8147
 * A parsed entity must not contain a recursive
8148
 * reference to itself, either directly or indirectly.
8149
 *
8150
 * [ WFC: Entity Declared ]
8151
 * In a document without any DTD, a document with only an internal DTD
8152
 * subset which contains no parameter entity references, or a document
8153
 * with "standalone='yes'", ...  ... The declaration of a parameter
8154
 * entity must precede any reference to it...
8155
 *
8156
 * [ VC: Entity Declared ]
8157
 * In a document with an external subset or external parameter entities
8158
 * with "standalone='no'", ...  ... The declaration of a parameter entity
8159
 * must precede any reference to it...
8160
 *
8161
 * [ WFC: In DTD ]
8162
 * Parameter-entity references may only appear in the DTD.
8163
 * NOTE: misleading but this is handled.
8164
 *
8165
 * Returns the string of the entity content.
8166
 *         str is updated to the current value of the index
8167
 */
8168
static xmlEntityPtr
8169
37.8k
xmlParseStringPEReference(xmlParserCtxtPtr ctxt, const xmlChar **str) {
8170
37.8k
    const xmlChar *ptr;
8171
37.8k
    xmlChar cur;
8172
37.8k
    xmlChar *name;
8173
37.8k
    xmlEntityPtr entity = NULL;
8174
8175
37.8k
    if ((str == NULL) || (*str == NULL)) return(NULL);
8176
37.8k
    ptr = *str;
8177
37.8k
    cur = *ptr;
8178
37.8k
    if (cur != '%')
8179
0
        return(NULL);
8180
37.8k
    ptr++;
8181
37.8k
    name = xmlParseStringName(ctxt, &ptr);
8182
37.8k
    if (name == NULL) {
8183
14.5k
  xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8184
14.5k
           "xmlParseStringPEReference: no name\n");
8185
14.5k
  *str = ptr;
8186
14.5k
  return(NULL);
8187
14.5k
    }
8188
23.2k
    cur = *ptr;
8189
23.2k
    if (cur != ';') {
8190
6.26k
  xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
8191
6.26k
  xmlFree(name);
8192
6.26k
  *str = ptr;
8193
6.26k
  return(NULL);
8194
6.26k
    }
8195
16.9k
    ptr++;
8196
8197
    /*
8198
     * Increase the number of entity references parsed
8199
     */
8200
16.9k
    ctxt->nbentities++;
8201
8202
    /*
8203
     * Request the entity from SAX
8204
     */
8205
16.9k
    if ((ctxt->sax != NULL) &&
8206
16.9k
  (ctxt->sax->getParameterEntity != NULL))
8207
16.9k
  entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
8208
16.9k
    if (ctxt->instate == XML_PARSER_EOF) {
8209
0
  xmlFree(name);
8210
0
  *str = ptr;
8211
0
  return(NULL);
8212
0
    }
8213
16.9k
    if (entity == NULL) {
8214
  /*
8215
   * [ WFC: Entity Declared ]
8216
   * In a document without any DTD, a document with only an
8217
   * internal DTD subset which contains no parameter entity
8218
   * references, or a document with "standalone='yes'", ...
8219
   * ... The declaration of a parameter entity must precede
8220
   * any reference to it...
8221
   */
8222
2.16k
  if ((ctxt->standalone == 1) ||
8223
2.16k
      ((ctxt->hasExternalSubset == 0) && (ctxt->hasPErefs == 0))) {
8224
10
      xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
8225
10
     "PEReference: %%%s; not found\n", name);
8226
2.15k
  } else {
8227
      /*
8228
       * [ VC: Entity Declared ]
8229
       * In a document with an external subset or external
8230
       * parameter entities with "standalone='no'", ...
8231
       * ... The declaration of a parameter entity must
8232
       * precede any reference to it...
8233
       */
8234
2.15k
      xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
8235
2.15k
        "PEReference: %%%s; not found\n",
8236
2.15k
        name, NULL);
8237
2.15k
      ctxt->valid = 0;
8238
2.15k
  }
8239
2.16k
  xmlParserEntityCheck(ctxt, 0, NULL, 0);
8240
14.8k
    } else {
8241
  /*
8242
   * Internal checking in case the entity quest barfed
8243
   */
8244
14.8k
  if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
8245
14.8k
      (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
8246
0
      xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
8247
0
        "%%%s; is not a parameter entity\n",
8248
0
        name, NULL);
8249
0
  }
8250
14.8k
    }
8251
16.9k
    ctxt->hasPErefs = 1;
8252
16.9k
    xmlFree(name);
8253
16.9k
    *str = ptr;
8254
16.9k
    return(entity);
8255
16.9k
}
8256
8257
/**
8258
 * xmlParseDocTypeDecl:
8259
 * @ctxt:  an XML parser context
8260
 *
8261
 * parse a DOCTYPE declaration
8262
 *
8263
 * [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S?
8264
 *                      ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
8265
 *
8266
 * [ VC: Root Element Type ]
8267
 * The Name in the document type declaration must match the element
8268
 * type of the root element.
8269
 */
8270
8271
void
8272
9.57k
xmlParseDocTypeDecl(xmlParserCtxtPtr ctxt) {
8273
9.57k
    const xmlChar *name = NULL;
8274
9.57k
    xmlChar *ExternalID = NULL;
8275
9.57k
    xmlChar *URI = NULL;
8276
8277
    /*
8278
     * We know that '<!DOCTYPE' has been detected.
8279
     */
8280
9.57k
    SKIP(9);
8281
8282
9.57k
    SKIP_BLANKS;
8283
8284
    /*
8285
     * Parse the DOCTYPE name.
8286
     */
8287
9.57k
    name = xmlParseName(ctxt);
8288
9.57k
    if (name == NULL) {
8289
1.59k
  xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8290
1.59k
           "xmlParseDocTypeDecl : no DOCTYPE name !\n");
8291
1.59k
    }
8292
9.57k
    ctxt->intSubName = name;
8293
8294
9.57k
    SKIP_BLANKS;
8295
8296
    /*
8297
     * Check for SystemID and ExternalID
8298
     */
8299
9.57k
    URI = xmlParseExternalID(ctxt, &ExternalID, 1);
8300
8301
9.57k
    if ((URI != NULL) || (ExternalID != NULL)) {
8302
334
        ctxt->hasExternalSubset = 1;
8303
334
    }
8304
9.57k
    ctxt->extSubURI = URI;
8305
9.57k
    ctxt->extSubSystem = ExternalID;
8306
8307
9.57k
    SKIP_BLANKS;
8308
8309
    /*
8310
     * Create and update the internal subset.
8311
     */
8312
9.57k
    if ((ctxt->sax != NULL) && (ctxt->sax->internalSubset != NULL) &&
8313
9.57k
  (!ctxt->disableSAX))
8314
7.50k
  ctxt->sax->internalSubset(ctxt->userData, name, ExternalID, URI);
8315
9.57k
    if (ctxt->instate == XML_PARSER_EOF)
8316
0
  return;
8317
8318
    /*
8319
     * Is there any internal subset declarations ?
8320
     * they are handled separately in xmlParseInternalSubset()
8321
     */
8322
9.57k
    if (RAW == '[')
8323
9.06k
  return;
8324
8325
    /*
8326
     * We should be at the end of the DOCTYPE declaration.
8327
     */
8328
512
    if (RAW != '>') {
8329
316
  xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
8330
316
    }
8331
512
    NEXT;
8332
512
}
8333
8334
/**
8335
 * xmlParseInternalSubset:
8336
 * @ctxt:  an XML parser context
8337
 *
8338
 * parse the internal subset declaration
8339
 *
8340
 * [28 end] ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
8341
 */
8342
8343
static void
8344
9.13k
xmlParseInternalSubset(xmlParserCtxtPtr ctxt) {
8345
    /*
8346
     * Is there any DTD definition ?
8347
     */
8348
9.13k
    if (RAW == '[') {
8349
9.13k
        int baseInputNr = ctxt->inputNr;
8350
9.13k
        ctxt->instate = XML_PARSER_DTD;
8351
9.13k
        NEXT;
8352
  /*
8353
   * Parse the succession of Markup declarations and
8354
   * PEReferences.
8355
   * Subsequence (markupdecl | PEReference | S)*
8356
   */
8357
8.46M
  while (((RAW != ']') || (ctxt->inputNr > baseInputNr)) &&
8358
8.46M
               (ctxt->instate != XML_PARSER_EOF)) {
8359
8.46M
      int id = ctxt->input->id;
8360
8.46M
      unsigned long cons = CUR_CONSUMED;
8361
8362
8.46M
      SKIP_BLANKS;
8363
8.46M
      xmlParseMarkupDecl(ctxt);
8364
8.46M
      xmlParsePEReference(ctxt);
8365
8366
            /*
8367
             * Conditional sections are allowed from external entities included
8368
             * by PE References in the internal subset.
8369
             */
8370
8.46M
            if ((ctxt->inputNr > 1) && (ctxt->input->filename != NULL) &&
8371
8.46M
                (RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
8372
0
                xmlParseConditionalSections(ctxt);
8373
0
            }
8374
8375
8.46M
      if ((id == ctxt->input->id) && (cons == CUR_CONSUMED)) {
8376
1.32M
    xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
8377
1.32M
       "xmlParseInternalSubset: error detected in Markup declaration\n");
8378
1.32M
                if (ctxt->inputNr > baseInputNr)
8379
1.31M
                    xmlPopInput(ctxt);
8380
6.23k
                else
8381
6.23k
        break;
8382
1.32M
      }
8383
8.46M
  }
8384
9.13k
  if (RAW == ']') {
8385
1.91k
      NEXT;
8386
1.91k
      SKIP_BLANKS;
8387
1.91k
  }
8388
9.13k
    }
8389
8390
    /*
8391
     * We should be at the end of the DOCTYPE declaration.
8392
     */
8393
9.13k
    if (RAW != '>') {
8394
7.04k
  xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
8395
7.04k
  return;
8396
7.04k
    }
8397
2.09k
    NEXT;
8398
2.09k
}
8399
8400
#ifdef LIBXML_SAX1_ENABLED
8401
/**
8402
 * xmlParseAttribute:
8403
 * @ctxt:  an XML parser context
8404
 * @value:  a xmlChar ** used to store the value of the attribute
8405
 *
8406
 * parse an attribute
8407
 *
8408
 * [41] Attribute ::= Name Eq AttValue
8409
 *
8410
 * [ WFC: No External Entity References ]
8411
 * Attribute values cannot contain direct or indirect entity references
8412
 * to external entities.
8413
 *
8414
 * [ WFC: No < in Attribute Values ]
8415
 * The replacement text of any entity referred to directly or indirectly in
8416
 * an attribute value (other than "&lt;") must not contain a <.
8417
 *
8418
 * [ VC: Attribute Value Type ]
8419
 * The attribute must have been declared; the value must be of the type
8420
 * declared for it.
8421
 *
8422
 * [25] Eq ::= S? '=' S?
8423
 *
8424
 * With namespace:
8425
 *
8426
 * [NS 11] Attribute ::= QName Eq AttValue
8427
 *
8428
 * Also the case QName == xmlns:??? is handled independently as a namespace
8429
 * definition.
8430
 *
8431
 * Returns the attribute name, and the value in *value.
8432
 */
8433
8434
const xmlChar *
8435
0
xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlChar **value) {
8436
0
    const xmlChar *name;
8437
0
    xmlChar *val;
8438
8439
0
    *value = NULL;
8440
0
    GROW;
8441
0
    name = xmlParseName(ctxt);
8442
0
    if (name == NULL) {
8443
0
  xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8444
0
                 "error parsing attribute name\n");
8445
0
        return(NULL);
8446
0
    }
8447
8448
    /*
8449
     * read the value
8450
     */
8451
0
    SKIP_BLANKS;
8452
0
    if (RAW == '=') {
8453
0
        NEXT;
8454
0
  SKIP_BLANKS;
8455
0
  val = xmlParseAttValue(ctxt);
8456
0
  ctxt->instate = XML_PARSER_CONTENT;
8457
0
    } else {
8458
0
  xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
8459
0
         "Specification mandates value for attribute %s\n", name);
8460
0
  return(NULL);
8461
0
    }
8462
8463
    /*
8464
     * Check that xml:lang conforms to the specification
8465
     * No more registered as an error, just generate a warning now
8466
     * since this was deprecated in XML second edition
8467
     */
8468
0
    if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "xml:lang"))) {
8469
0
  if (!xmlCheckLanguageID(val)) {
8470
0
      xmlWarningMsg(ctxt, XML_WAR_LANG_VALUE,
8471
0
              "Malformed value for xml:lang : %s\n",
8472
0
        val, NULL);
8473
0
  }
8474
0
    }
8475
8476
    /*
8477
     * Check that xml:space conforms to the specification
8478
     */
8479
0
    if (xmlStrEqual(name, BAD_CAST "xml:space")) {
8480
0
  if (xmlStrEqual(val, BAD_CAST "default"))
8481
0
      *(ctxt->space) = 0;
8482
0
  else if (xmlStrEqual(val, BAD_CAST "preserve"))
8483
0
      *(ctxt->space) = 1;
8484
0
  else {
8485
0
    xmlWarningMsg(ctxt, XML_WAR_SPACE_VALUE,
8486
0
"Invalid value \"%s\" for xml:space : \"default\" or \"preserve\" expected\n",
8487
0
                                 val, NULL);
8488
0
  }
8489
0
    }
8490
8491
0
    *value = val;
8492
0
    return(name);
8493
0
}
8494
8495
/**
8496
 * xmlParseStartTag:
8497
 * @ctxt:  an XML parser context
8498
 *
8499
 * parse a start of tag either for rule element or
8500
 * EmptyElement. In both case we don't parse the tag closing chars.
8501
 *
8502
 * [40] STag ::= '<' Name (S Attribute)* S? '>'
8503
 *
8504
 * [ WFC: Unique Att Spec ]
8505
 * No attribute name may appear more than once in the same start-tag or
8506
 * empty-element tag.
8507
 *
8508
 * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
8509
 *
8510
 * [ WFC: Unique Att Spec ]
8511
 * No attribute name may appear more than once in the same start-tag or
8512
 * empty-element tag.
8513
 *
8514
 * With namespace:
8515
 *
8516
 * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
8517
 *
8518
 * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
8519
 *
8520
 * Returns the element name parsed
8521
 */
8522
8523
const xmlChar *
8524
0
xmlParseStartTag(xmlParserCtxtPtr ctxt) {
8525
0
    const xmlChar *name;
8526
0
    const xmlChar *attname;
8527
0
    xmlChar *attvalue;
8528
0
    const xmlChar **atts = ctxt->atts;
8529
0
    int nbatts = 0;
8530
0
    int maxatts = ctxt->maxatts;
8531
0
    int i;
8532
8533
0
    if (RAW != '<') return(NULL);
8534
0
    NEXT1;
8535
8536
0
    name = xmlParseName(ctxt);
8537
0
    if (name == NULL) {
8538
0
  xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8539
0
       "xmlParseStartTag: invalid element name\n");
8540
0
        return(NULL);
8541
0
    }
8542
8543
    /*
8544
     * Now parse the attributes, it ends up with the ending
8545
     *
8546
     * (S Attribute)* S?
8547
     */
8548
0
    SKIP_BLANKS;
8549
0
    GROW;
8550
8551
0
    while (((RAW != '>') &&
8552
0
     ((RAW != '/') || (NXT(1) != '>')) &&
8553
0
     (IS_BYTE_CHAR(RAW))) && (ctxt->instate != XML_PARSER_EOF)) {
8554
0
        int id = ctxt->input->id;
8555
0
  unsigned long cons = CUR_CONSUMED;
8556
8557
0
  attname = xmlParseAttribute(ctxt, &attvalue);
8558
0
        if ((attname != NULL) && (attvalue != NULL)) {
8559
      /*
8560
       * [ WFC: Unique Att Spec ]
8561
       * No attribute name may appear more than once in the same
8562
       * start-tag or empty-element tag.
8563
       */
8564
0
      for (i = 0; i < nbatts;i += 2) {
8565
0
          if (xmlStrEqual(atts[i], attname)) {
8566
0
        xmlErrAttributeDup(ctxt, NULL, attname);
8567
0
        xmlFree(attvalue);
8568
0
        goto failed;
8569
0
    }
8570
0
      }
8571
      /*
8572
       * Add the pair to atts
8573
       */
8574
0
      if (atts == NULL) {
8575
0
          maxatts = 22; /* allow for 10 attrs by default */
8576
0
          atts = (const xmlChar **)
8577
0
           xmlMalloc(maxatts * sizeof(xmlChar *));
8578
0
    if (atts == NULL) {
8579
0
        xmlErrMemory(ctxt, NULL);
8580
0
        if (attvalue != NULL)
8581
0
      xmlFree(attvalue);
8582
0
        goto failed;
8583
0
    }
8584
0
    ctxt->atts = atts;
8585
0
    ctxt->maxatts = maxatts;
8586
0
      } else if (nbatts + 4 > maxatts) {
8587
0
          const xmlChar **n;
8588
8589
0
          maxatts *= 2;
8590
0
          n = (const xmlChar **) xmlRealloc((void *) atts,
8591
0
               maxatts * sizeof(const xmlChar *));
8592
0
    if (n == NULL) {
8593
0
        xmlErrMemory(ctxt, NULL);
8594
0
        if (attvalue != NULL)
8595
0
      xmlFree(attvalue);
8596
0
        goto failed;
8597
0
    }
8598
0
    atts = n;
8599
0
    ctxt->atts = atts;
8600
0
    ctxt->maxatts = maxatts;
8601
0
      }
8602
0
      atts[nbatts++] = attname;
8603
0
      atts[nbatts++] = attvalue;
8604
0
      atts[nbatts] = NULL;
8605
0
      atts[nbatts + 1] = NULL;
8606
0
  } else {
8607
0
      if (attvalue != NULL)
8608
0
    xmlFree(attvalue);
8609
0
  }
8610
8611
0
failed:
8612
8613
0
  GROW
8614
0
  if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
8615
0
      break;
8616
0
  if (SKIP_BLANKS == 0) {
8617
0
      xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
8618
0
         "attributes construct error\n");
8619
0
  }
8620
0
        if ((cons == CUR_CONSUMED) && (id == ctxt->input->id) &&
8621
0
            (attname == NULL) && (attvalue == NULL)) {
8622
0
      xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
8623
0
         "xmlParseStartTag: problem parsing attributes\n");
8624
0
      break;
8625
0
  }
8626
0
  SHRINK;
8627
0
        GROW;
8628
0
    }
8629
8630
    /*
8631
     * SAX: Start of Element !
8632
     */
8633
0
    if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL) &&
8634
0
  (!ctxt->disableSAX)) {
8635
0
  if (nbatts > 0)
8636
0
      ctxt->sax->startElement(ctxt->userData, name, atts);
8637
0
  else
8638
0
      ctxt->sax->startElement(ctxt->userData, name, NULL);
8639
0
    }
8640
8641
0
    if (atts != NULL) {
8642
        /* Free only the content strings */
8643
0
        for (i = 1;i < nbatts;i+=2)
8644
0
      if (atts[i] != NULL)
8645
0
         xmlFree((xmlChar *) atts[i]);
8646
0
    }
8647
0
    return(name);
8648
0
}
8649
8650
/**
8651
 * xmlParseEndTag1:
8652
 * @ctxt:  an XML parser context
8653
 * @line:  line of the start tag
8654
 * @nsNr:  number of namespaces on the start tag
8655
 *
8656
 * parse an end of tag
8657
 *
8658
 * [42] ETag ::= '</' Name S? '>'
8659
 *
8660
 * With namespace
8661
 *
8662
 * [NS 9] ETag ::= '</' QName S? '>'
8663
 */
8664
8665
static void
8666
0
xmlParseEndTag1(xmlParserCtxtPtr ctxt, int line) {
8667
0
    const xmlChar *name;
8668
8669
0
    GROW;
8670
0
    if ((RAW != '<') || (NXT(1) != '/')) {
8671
0
  xmlFatalErrMsg(ctxt, XML_ERR_LTSLASH_REQUIRED,
8672
0
           "xmlParseEndTag: '</' not found\n");
8673
0
  return;
8674
0
    }
8675
0
    SKIP(2);
8676
8677
0
    name = xmlParseNameAndCompare(ctxt,ctxt->name);
8678
8679
    /*
8680
     * We should definitely be at the ending "S? '>'" part
8681
     */
8682
0
    GROW;
8683
0
    SKIP_BLANKS;
8684
0
    if ((!IS_BYTE_CHAR(RAW)) || (RAW != '>')) {
8685
0
  xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
8686
0
    } else
8687
0
  NEXT1;
8688
8689
    /*
8690
     * [ WFC: Element Type Match ]
8691
     * The Name in an element's end-tag must match the element type in the
8692
     * start-tag.
8693
     *
8694
     */
8695
0
    if (name != (xmlChar*)1) {
8696
0
        if (name == NULL) name = BAD_CAST "unparsable";
8697
0
        xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
8698
0
         "Opening and ending tag mismatch: %s line %d and %s\n",
8699
0
                    ctxt->name, line, name);
8700
0
    }
8701
8702
    /*
8703
     * SAX: End of Tag
8704
     */
8705
0
    if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
8706
0
  (!ctxt->disableSAX))
8707
0
        ctxt->sax->endElement(ctxt->userData, ctxt->name);
8708
8709
0
    namePop(ctxt);
8710
0
    spacePop(ctxt);
8711
0
    return;
8712
0
}
8713
8714
/**
8715
 * xmlParseEndTag:
8716
 * @ctxt:  an XML parser context
8717
 *
8718
 * parse an end of tag
8719
 *
8720
 * [42] ETag ::= '</' Name S? '>'
8721
 *
8722
 * With namespace
8723
 *
8724
 * [NS 9] ETag ::= '</' QName S? '>'
8725
 */
8726
8727
void
8728
0
xmlParseEndTag(xmlParserCtxtPtr ctxt) {
8729
0
    xmlParseEndTag1(ctxt, 0);
8730
0
}
8731
#endif /* LIBXML_SAX1_ENABLED */
8732
8733
/************************************************************************
8734
 *                  *
8735
 *          SAX 2 specific operations       *
8736
 *                  *
8737
 ************************************************************************/
8738
8739
/*
8740
 * xmlGetNamespace:
8741
 * @ctxt:  an XML parser context
8742
 * @prefix:  the prefix to lookup
8743
 *
8744
 * Lookup the namespace name for the @prefix (which ca be NULL)
8745
 * The prefix must come from the @ctxt->dict dictionary
8746
 *
8747
 * Returns the namespace name or NULL if not bound
8748
 */
8749
static const xmlChar *
8750
29.9M
xmlGetNamespace(xmlParserCtxtPtr ctxt, const xmlChar *prefix) {
8751
29.9M
    int i;
8752
8753
29.9M
    if (prefix == ctxt->str_xml) return(ctxt->str_xml_ns);
8754
307M
    for (i = ctxt->nsNr - 2;i >= 0;i-=2)
8755
306M
        if (ctxt->nsTab[i] == prefix) {
8756
28.9M
      if ((prefix == NULL) && (*ctxt->nsTab[i + 1] == 0))
8757
8.26M
          return(NULL);
8758
20.6M
      return(ctxt->nsTab[i + 1]);
8759
28.9M
  }
8760
992k
    return(NULL);
8761
29.8M
}
8762
8763
/**
8764
 * xmlParseQName:
8765
 * @ctxt:  an XML parser context
8766
 * @prefix:  pointer to store the prefix part
8767
 *
8768
 * parse an XML Namespace QName
8769
 *
8770
 * [6]  QName  ::= (Prefix ':')? LocalPart
8771
 * [7]  Prefix  ::= NCName
8772
 * [8]  LocalPart  ::= NCName
8773
 *
8774
 * Returns the Name parsed or NULL
8775
 */
8776
8777
static const xmlChar *
8778
6.22M
xmlParseQName(xmlParserCtxtPtr ctxt, const xmlChar **prefix) {
8779
6.22M
    const xmlChar *l, *p;
8780
8781
6.22M
    GROW;
8782
8783
6.22M
    l = xmlParseNCName(ctxt);
8784
6.22M
    if (l == NULL) {
8785
294k
        if (CUR == ':') {
8786
9.58k
      l = xmlParseName(ctxt);
8787
9.58k
      if (l != NULL) {
8788
9.58k
          xmlNsErr(ctxt, XML_NS_ERR_QNAME,
8789
9.58k
             "Failed to parse QName '%s'\n", l, NULL, NULL);
8790
9.58k
    *prefix = NULL;
8791
9.58k
    return(l);
8792
9.58k
      }
8793
9.58k
  }
8794
284k
        return(NULL);
8795
294k
    }
8796
5.93M
    if (CUR == ':') {
8797
177k
        NEXT;
8798
177k
  p = l;
8799
177k
  l = xmlParseNCName(ctxt);
8800
177k
  if (l == NULL) {
8801
17.7k
      xmlChar *tmp;
8802
8803
17.7k
            if (ctxt->instate == XML_PARSER_EOF)
8804
0
                return(NULL);
8805
17.7k
            xmlNsErr(ctxt, XML_NS_ERR_QNAME,
8806
17.7k
               "Failed to parse QName '%s:'\n", p, NULL, NULL);
8807
17.7k
      l = xmlParseNmtoken(ctxt);
8808
17.7k
      if (l == NULL) {
8809
14.3k
                if (ctxt->instate == XML_PARSER_EOF)
8810
0
                    return(NULL);
8811
14.3k
    tmp = xmlBuildQName(BAD_CAST "", p, NULL, 0);
8812
14.3k
            } else {
8813
3.40k
    tmp = xmlBuildQName(l, p, NULL, 0);
8814
3.40k
    xmlFree((char *)l);
8815
3.40k
      }
8816
17.7k
      p = xmlDictLookup(ctxt->dict, tmp, -1);
8817
17.7k
      if (tmp != NULL) xmlFree(tmp);
8818
17.7k
      *prefix = NULL;
8819
17.7k
      return(p);
8820
17.7k
  }
8821
159k
  if (CUR == ':') {
8822
16.1k
      xmlChar *tmp;
8823
8824
16.1k
            xmlNsErr(ctxt, XML_NS_ERR_QNAME,
8825
16.1k
               "Failed to parse QName '%s:%s:'\n", p, l, NULL);
8826
16.1k
      NEXT;
8827
16.1k
      tmp = (xmlChar *) xmlParseName(ctxt);
8828
16.1k
      if (tmp != NULL) {
8829
13.8k
          tmp = xmlBuildQName(tmp, l, NULL, 0);
8830
13.8k
    l = xmlDictLookup(ctxt->dict, tmp, -1);
8831
13.8k
    if (tmp != NULL) xmlFree(tmp);
8832
13.8k
    *prefix = p;
8833
13.8k
    return(l);
8834
13.8k
      }
8835
2.24k
            if (ctxt->instate == XML_PARSER_EOF)
8836
0
                return(NULL);
8837
2.24k
      tmp = xmlBuildQName(BAD_CAST "", l, NULL, 0);
8838
2.24k
      l = xmlDictLookup(ctxt->dict, tmp, -1);
8839
2.24k
      if (tmp != NULL) xmlFree(tmp);
8840
2.24k
      *prefix = p;
8841
2.24k
      return(l);
8842
2.24k
  }
8843
143k
  *prefix = p;
8844
143k
    } else
8845
5.75M
        *prefix = NULL;
8846
5.90M
    return(l);
8847
5.93M
}
8848
8849
/**
8850
 * xmlParseQNameAndCompare:
8851
 * @ctxt:  an XML parser context
8852
 * @name:  the localname
8853
 * @prefix:  the prefix, if any.
8854
 *
8855
 * parse an XML name and compares for match
8856
 * (specialized for endtag parsing)
8857
 *
8858
 * Returns NULL for an illegal name, (xmlChar*) 1 for success
8859
 * and the name for mismatch
8860
 */
8861
8862
static const xmlChar *
8863
xmlParseQNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *name,
8864
9.87k
                        xmlChar const *prefix) {
8865
9.87k
    const xmlChar *cmp;
8866
9.87k
    const xmlChar *in;
8867
9.87k
    const xmlChar *ret;
8868
9.87k
    const xmlChar *prefix2;
8869
8870
9.87k
    if (prefix == NULL) return(xmlParseNameAndCompare(ctxt, name));
8871
8872
9.87k
    GROW;
8873
9.87k
    in = ctxt->input->cur;
8874
8875
9.87k
    cmp = prefix;
8876
26.3k
    while (*in != 0 && *in == *cmp) {
8877
16.5k
  ++in;
8878
16.5k
  ++cmp;
8879
16.5k
    }
8880
9.87k
    if ((*cmp == 0) && (*in == ':')) {
8881
6.44k
        in++;
8882
6.44k
  cmp = name;
8883
16.9k
  while (*in != 0 && *in == *cmp) {
8884
10.4k
      ++in;
8885
10.4k
      ++cmp;
8886
10.4k
  }
8887
6.44k
  if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) {
8888
      /* success */
8889
4.71k
            ctxt->input->col += in - ctxt->input->cur;
8890
4.71k
      ctxt->input->cur = in;
8891
4.71k
      return((const xmlChar*) 1);
8892
4.71k
  }
8893
6.44k
    }
8894
    /*
8895
     * all strings coms from the dictionary, equality can be done directly
8896
     */
8897
5.16k
    ret = xmlParseQName (ctxt, &prefix2);
8898
5.16k
    if ((ret == name) && (prefix == prefix2))
8899
952
  return((const xmlChar*) 1);
8900
4.21k
    return ret;
8901
5.16k
}
8902
8903
/**
8904
 * xmlParseAttValueInternal:
8905
 * @ctxt:  an XML parser context
8906
 * @len:  attribute len result
8907
 * @alloc:  whether the attribute was reallocated as a new string
8908
 * @normalize:  if 1 then further non-CDATA normalization must be done
8909
 *
8910
 * parse a value for an attribute.
8911
 * NOTE: if no normalization is needed, the routine will return pointers
8912
 *       directly from the data buffer.
8913
 *
8914
 * 3.3.3 Attribute-Value Normalization:
8915
 * Before the value of an attribute is passed to the application or
8916
 * checked for validity, the XML processor must normalize it as follows:
8917
 * - a character reference is processed by appending the referenced
8918
 *   character to the attribute value
8919
 * - an entity reference is processed by recursively processing the
8920
 *   replacement text of the entity
8921
 * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
8922
 *   appending #x20 to the normalized value, except that only a single
8923
 *   #x20 is appended for a "#xD#xA" sequence that is part of an external
8924
 *   parsed entity or the literal entity value of an internal parsed entity
8925
 * - other characters are processed by appending them to the normalized value
8926
 * If the declared value is not CDATA, then the XML processor must further
8927
 * process the normalized attribute value by discarding any leading and
8928
 * trailing space (#x20) characters, and by replacing sequences of space
8929
 * (#x20) characters by a single space (#x20) character.
8930
 * All attributes for which no declaration has been read should be treated
8931
 * by a non-validating parser as if declared CDATA.
8932
 *
8933
 * Returns the AttValue parsed or NULL. The value has to be freed by the
8934
 *     caller if it was copied, this can be detected by val[*len] == 0.
8935
 */
8936
8937
#define GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end) \
8938
4.04k
    const xmlChar *oldbase = ctxt->input->base;\
8939
4.04k
    GROW;\
8940
4.04k
    if (ctxt->instate == XML_PARSER_EOF)\
8941
4.04k
        return(NULL);\
8942
4.04k
    if (oldbase != ctxt->input->base) {\
8943
1
        ptrdiff_t delta = ctxt->input->base - oldbase;\
8944
1
        start = start + delta;\
8945
1
        in = in + delta;\
8946
1
    }\
8947
4.04k
    end = ctxt->input->end;
8948
8949
static xmlChar *
8950
xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
8951
                         int normalize)
8952
1.07M
{
8953
1.07M
    xmlChar limit = 0;
8954
1.07M
    const xmlChar *in = NULL, *start, *end, *last;
8955
1.07M
    xmlChar *ret = NULL;
8956
1.07M
    int line, col;
8957
8958
1.07M
    GROW;
8959
1.07M
    in = (xmlChar *) CUR_PTR;
8960
1.07M
    line = ctxt->input->line;
8961
1.07M
    col = ctxt->input->col;
8962
1.07M
    if (*in != '"' && *in != '\'') {
8963
764k
        xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
8964
764k
        return (NULL);
8965
764k
    }
8966
315k
    ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
8967
8968
    /*
8969
     * try to handle in this routine the most common case where no
8970
     * allocation of a new string is required and where content is
8971
     * pure ASCII.
8972
     */
8973
315k
    limit = *in++;
8974
315k
    col++;
8975
315k
    end = ctxt->input->end;
8976
315k
    start = in;
8977
315k
    if (in >= end) {
8978
183
        GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end)
8979
183
    }
8980
315k
    if (normalize) {
8981
        /*
8982
   * Skip any leading spaces
8983
   */
8984
7.67k
  while ((in < end) && (*in != limit) &&
8985
7.67k
         ((*in == 0x20) || (*in == 0x9) ||
8986
7.02k
          (*in == 0xA) || (*in == 0xD))) {
8987
1.90k
      if (*in == 0xA) {
8988
615
          line++; col = 1;
8989
1.29k
      } else {
8990
1.29k
          col++;
8991
1.29k
      }
8992
1.90k
      in++;
8993
1.90k
      start = in;
8994
1.90k
      if (in >= end) {
8995
17
                GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end)
8996
17
                if (((in - start) > XML_MAX_TEXT_LENGTH) &&
8997
17
                    ((ctxt->options & XML_PARSE_HUGE) == 0)) {
8998
0
                    xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
8999
0
                                   "AttValue length too long\n");
9000
0
                    return(NULL);
9001
0
                }
9002
17
      }
9003
1.90k
  }
9004
14.2k
  while ((in < end) && (*in != limit) && (*in >= 0x20) &&
9005
14.2k
         (*in <= 0x7f) && (*in != '&') && (*in != '<')) {
9006
8.78k
      col++;
9007
8.78k
      if ((*in++ == 0x20) && (*in == 0x20)) break;
9008
8.50k
      if (in >= end) {
9009
30
                GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end)
9010
30
                if (((in - start) > XML_MAX_TEXT_LENGTH) &&
9011
30
                    ((ctxt->options & XML_PARSE_HUGE) == 0)) {
9012
0
                    xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
9013
0
                                   "AttValue length too long\n");
9014
0
                    return(NULL);
9015
0
                }
9016
30
      }
9017
8.50k
  }
9018
5.76k
  last = in;
9019
  /*
9020
   * skip the trailing blanks
9021
   */
9022
6.08k
  while ((last[-1] == 0x20) && (last > start)) last--;
9023
8.15k
  while ((in < end) && (*in != limit) &&
9024
8.15k
         ((*in == 0x20) || (*in == 0x9) ||
9025
6.77k
          (*in == 0xA) || (*in == 0xD))) {
9026
2.38k
      if (*in == 0xA) {
9027
467
          line++, col = 1;
9028
1.91k
      } else {
9029
1.91k
          col++;
9030
1.91k
      }
9031
2.38k
      in++;
9032
2.38k
      if (in >= end) {
9033
31
    const xmlChar *oldbase = ctxt->input->base;
9034
31
    GROW;
9035
31
                if (ctxt->instate == XML_PARSER_EOF)
9036
0
                    return(NULL);
9037
31
    if (oldbase != ctxt->input->base) {
9038
0
        ptrdiff_t delta = ctxt->input->base - oldbase;
9039
0
        start = start + delta;
9040
0
        in = in + delta;
9041
0
        last = last + delta;
9042
0
    }
9043
31
    end = ctxt->input->end;
9044
31
                if (((in - start) > XML_MAX_TEXT_LENGTH) &&
9045
31
                    ((ctxt->options & XML_PARSE_HUGE) == 0)) {
9046
0
                    xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
9047
0
                                   "AttValue length too long\n");
9048
0
                    return(NULL);
9049
0
                }
9050
31
      }
9051
2.38k
  }
9052
5.76k
        if (((in - start) > XML_MAX_TEXT_LENGTH) &&
9053
5.76k
            ((ctxt->options & XML_PARSE_HUGE) == 0)) {
9054
0
            xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
9055
0
                           "AttValue length too long\n");
9056
0
            return(NULL);
9057
0
        }
9058
5.76k
  if (*in != limit) goto need_complex;
9059
309k
    } else {
9060
1.93M
  while ((in < end) && (*in != limit) && (*in >= 0x20) &&
9061
1.93M
         (*in <= 0x7f) && (*in != '&') && (*in != '<')) {
9062
1.63M
      in++;
9063
1.63M
      col++;
9064
1.63M
      if (in >= end) {
9065
3.81k
                GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end)
9066
3.81k
                if (((in - start) > XML_MAX_TEXT_LENGTH) &&
9067
3.81k
                    ((ctxt->options & XML_PARSE_HUGE) == 0)) {
9068
0
                    xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
9069
0
                                   "AttValue length too long\n");
9070
0
                    return(NULL);
9071
0
                }
9072
3.81k
      }
9073
1.63M
  }
9074
309k
  last = in;
9075
309k
        if (((in - start) > XML_MAX_TEXT_LENGTH) &&
9076
309k
            ((ctxt->options & XML_PARSE_HUGE) == 0)) {
9077
0
            xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
9078
0
                           "AttValue length too long\n");
9079
0
            return(NULL);
9080
0
        }
9081
309k
  if (*in != limit) goto need_complex;
9082
309k
    }
9083
216k
    in++;
9084
216k
    col++;
9085
216k
    if (len != NULL) {
9086
171k
        *len = last - start;
9087
171k
        ret = (xmlChar *) start;
9088
171k
    } else {
9089
44.6k
        if (alloc) *alloc = 1;
9090
44.6k
        ret = xmlStrndup(start, last - start);
9091
44.6k
    }
9092
216k
    CUR_PTR = in;
9093
216k
    ctxt->input->line = line;
9094
216k
    ctxt->input->col = col;
9095
216k
    if (alloc) *alloc = 0;
9096
216k
    return ret;
9097
98.8k
need_complex:
9098
98.8k
    if (alloc) *alloc = 1;
9099
98.8k
    return xmlParseAttValueComplex(ctxt, len, normalize);
9100
315k
}
9101
9102
/**
9103
 * xmlParseAttribute2:
9104
 * @ctxt:  an XML parser context
9105
 * @pref:  the element prefix
9106
 * @elem:  the element name
9107
 * @prefix:  a xmlChar ** used to store the value of the attribute prefix
9108
 * @value:  a xmlChar ** used to store the value of the attribute
9109
 * @len:  an int * to save the length of the attribute
9110
 * @alloc:  an int * to indicate if the attribute was allocated
9111
 *
9112
 * parse an attribute in the new SAX2 framework.
9113
 *
9114
 * Returns the attribute name, and the value in *value, .
9115
 */
9116
9117
static const xmlChar *
9118
xmlParseAttribute2(xmlParserCtxtPtr ctxt,
9119
                   const xmlChar * pref, const xmlChar * elem,
9120
                   const xmlChar ** prefix, xmlChar ** value,
9121
                   int *len, int *alloc)
9122
431k
{
9123
431k
    const xmlChar *name;
9124
431k
    xmlChar *val, *internal_val = NULL;
9125
431k
    int normalize = 0;
9126
9127
431k
    *value = NULL;
9128
431k
    GROW;
9129
431k
    name = xmlParseQName(ctxt, prefix);
9130
431k
    if (name == NULL) {
9131
154k
        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
9132
154k
                       "error parsing attribute name\n");
9133
154k
        return (NULL);
9134
154k
    }
9135
9136
    /*
9137
     * get the type if needed
9138
     */
9139
276k
    if (ctxt->attsSpecial != NULL) {
9140
31.3k
        int type;
9141
9142
31.3k
        type = (int) (ptrdiff_t) xmlHashQLookup2(ctxt->attsSpecial,
9143
31.3k
                                                 pref, elem, *prefix, name);
9144
31.3k
        if (type != 0)
9145
6.20k
            normalize = 1;
9146
31.3k
    }
9147
9148
    /*
9149
     * read the value
9150
     */
9151
276k
    SKIP_BLANKS;
9152
276k
    if (RAW == '=') {
9153
262k
        NEXT;
9154
262k
        SKIP_BLANKS;
9155
262k
        val = xmlParseAttValueInternal(ctxt, len, alloc, normalize);
9156
262k
  if (normalize) {
9157
      /*
9158
       * Sometimes a second normalisation pass for spaces is needed
9159
       * but that only happens if charrefs or entities references
9160
       * have been used in the attribute value, i.e. the attribute
9161
       * value have been extracted in an allocated string already.
9162
       */
9163
5.90k
      if (*alloc) {
9164
4.47k
          const xmlChar *val2;
9165
9166
4.47k
          val2 = xmlAttrNormalizeSpace2(ctxt, val, len);
9167
4.47k
    if ((val2 != NULL) && (val2 != val)) {
9168
441
        xmlFree(val);
9169
441
        val = (xmlChar *) val2;
9170
441
    }
9171
4.47k
      }
9172
5.90k
  }
9173
262k
        ctxt->instate = XML_PARSER_CONTENT;
9174
262k
    } else {
9175
13.9k
        xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
9176
13.9k
                          "Specification mandates value for attribute %s\n",
9177
13.9k
                          name);
9178
13.9k
        return (NULL);
9179
13.9k
    }
9180
9181
262k
    if (*prefix == ctxt->str_xml) {
9182
        /*
9183
         * Check that xml:lang conforms to the specification
9184
         * No more registered as an error, just generate a warning now
9185
         * since this was deprecated in XML second edition
9186
         */
9187
50.4k
        if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "lang"))) {
9188
0
            internal_val = xmlStrndup(val, *len);
9189
0
            if (!xmlCheckLanguageID(internal_val)) {
9190
0
                xmlWarningMsg(ctxt, XML_WAR_LANG_VALUE,
9191
0
                              "Malformed value for xml:lang : %s\n",
9192
0
                              internal_val, NULL);
9193
0
            }
9194
0
        }
9195
9196
        /*
9197
         * Check that xml:space conforms to the specification
9198
         */
9199
50.4k
        if (xmlStrEqual(name, BAD_CAST "space")) {
9200
3.70k
            internal_val = xmlStrndup(val, *len);
9201
3.70k
            if (xmlStrEqual(internal_val, BAD_CAST "default"))
9202
195
                *(ctxt->space) = 0;
9203
3.50k
            else if (xmlStrEqual(internal_val, BAD_CAST "preserve"))
9204
577
                *(ctxt->space) = 1;
9205
2.92k
            else {
9206
2.92k
                xmlWarningMsg(ctxt, XML_WAR_SPACE_VALUE,
9207
2.92k
                              "Invalid value \"%s\" for xml:space : \"default\" or \"preserve\" expected\n",
9208
2.92k
                              internal_val, NULL);
9209
2.92k
            }
9210
3.70k
        }
9211
50.4k
        if (internal_val) {
9212
3.11k
            xmlFree(internal_val);
9213
3.11k
        }
9214
50.4k
    }
9215
9216
262k
    *value = val;
9217
262k
    return (name);
9218
276k
}
9219
/**
9220
 * xmlParseStartTag2:
9221
 * @ctxt:  an XML parser context
9222
 *
9223
 * parse a start of tag either for rule element or
9224
 * EmptyElement. In both case we don't parse the tag closing chars.
9225
 * This routine is called when running SAX2 parsing
9226
 *
9227
 * [40] STag ::= '<' Name (S Attribute)* S? '>'
9228
 *
9229
 * [ WFC: Unique Att Spec ]
9230
 * No attribute name may appear more than once in the same start-tag or
9231
 * empty-element tag.
9232
 *
9233
 * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
9234
 *
9235
 * [ WFC: Unique Att Spec ]
9236
 * No attribute name may appear more than once in the same start-tag or
9237
 * empty-element tag.
9238
 *
9239
 * With namespace:
9240
 *
9241
 * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
9242
 *
9243
 * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
9244
 *
9245
 * Returns the element name parsed
9246
 */
9247
9248
static const xmlChar *
9249
xmlParseStartTag2(xmlParserCtxtPtr ctxt, const xmlChar **pref,
9250
5.79M
                  const xmlChar **URI, int *tlen) {
9251
5.79M
    const xmlChar *localname;
9252
5.79M
    const xmlChar *prefix;
9253
5.79M
    const xmlChar *attname;
9254
5.79M
    const xmlChar *aprefix;
9255
5.79M
    const xmlChar *nsname;
9256
5.79M
    xmlChar *attvalue;
9257
5.79M
    const xmlChar **atts = ctxt->atts;
9258
5.79M
    int maxatts = ctxt->maxatts;
9259
5.79M
    int nratts, nbatts, nbdef, inputid;
9260
5.79M
    int i, j, nbNs, attval;
9261
5.79M
    unsigned long cur;
9262
5.79M
    int nsNr = ctxt->nsNr;
9263
9264
5.79M
    if (RAW != '<') return(NULL);
9265
5.79M
    NEXT1;
9266
9267
    /*
9268
     * NOTE: it is crucial with the SAX2 API to never call SHRINK beyond that
9269
     *       point since the attribute values may be stored as pointers to
9270
     *       the buffer and calling SHRINK would destroy them !
9271
     *       The Shrinking is only possible once the full set of attribute
9272
     *       callbacks have been done.
9273
     */
9274
5.79M
    SHRINK;
9275
5.79M
    cur = ctxt->input->cur - ctxt->input->base;
9276
5.79M
    inputid = ctxt->input->id;
9277
5.79M
    nbatts = 0;
9278
5.79M
    nratts = 0;
9279
5.79M
    nbdef = 0;
9280
5.79M
    nbNs = 0;
9281
5.79M
    attval = 0;
9282
    /* Forget any namespaces added during an earlier parse of this element. */
9283
5.79M
    ctxt->nsNr = nsNr;
9284
9285
5.79M
    localname = xmlParseQName(ctxt, &prefix);
9286
5.79M
    if (localname == NULL) {
9287
129k
  xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
9288
129k
           "StartTag: invalid element name\n");
9289
129k
        return(NULL);
9290
129k
    }
9291
5.66M
    *tlen = ctxt->input->cur - ctxt->input->base - cur;
9292
9293
    /*
9294
     * Now parse the attributes, it ends up with the ending
9295
     *
9296
     * (S Attribute)* S?
9297
     */
9298
5.66M
    SKIP_BLANKS;
9299
5.66M
    GROW;
9300
9301
5.71M
    while (((RAW != '>') &&
9302
5.71M
     ((RAW != '/') || (NXT(1) != '>')) &&
9303
5.71M
     (IS_BYTE_CHAR(RAW))) && (ctxt->instate != XML_PARSER_EOF)) {
9304
431k
  int id = ctxt->input->id;
9305
431k
  unsigned long cons = CUR_CONSUMED;
9306
431k
  int len = -1, alloc = 0;
9307
9308
431k
  attname = xmlParseAttribute2(ctxt, prefix, localname,
9309
431k
                               &aprefix, &attvalue, &len, &alloc);
9310
431k
        if ((attname == NULL) || (attvalue == NULL))
9311
173k
            goto next_attr;
9312
257k
  if (len < 0) len = xmlStrlen(attvalue);
9313
9314
257k
        if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
9315
93.2k
            const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
9316
93.2k
            xmlURIPtr uri;
9317
9318
93.2k
            if (URL == NULL) {
9319
0
                xmlErrMemory(ctxt, "dictionary allocation failure");
9320
0
                if ((attvalue != NULL) && (alloc != 0))
9321
0
                    xmlFree(attvalue);
9322
0
                localname = NULL;
9323
0
                goto done;
9324
0
            }
9325
93.2k
            if (*URL != 0) {
9326
91.8k
                uri = xmlParseURI((const char *) URL);
9327
91.8k
                if (uri == NULL) {
9328
56.6k
                    xmlNsErr(ctxt, XML_WAR_NS_URI,
9329
56.6k
                             "xmlns: '%s' is not a valid URI\n",
9330
56.6k
                                       URL, NULL, NULL);
9331
56.6k
                } else {
9332
35.2k
                    if (uri->scheme == NULL) {
9333
20.3k
                        xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
9334
20.3k
                                  "xmlns: URI %s is not absolute\n",
9335
20.3k
                                  URL, NULL, NULL);
9336
20.3k
                    }
9337
35.2k
                    xmlFreeURI(uri);
9338
35.2k
                }
9339
91.8k
                if (URL == ctxt->str_xml_ns) {
9340
577
                    if (attname != ctxt->str_xml) {
9341
577
                        xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9342
577
                     "xml namespace URI cannot be the default namespace\n",
9343
577
                                 NULL, NULL, NULL);
9344
577
                    }
9345
577
                    goto next_attr;
9346
577
                }
9347
91.2k
                if ((len == 29) &&
9348
91.2k
                    (xmlStrEqual(URL,
9349
2.83k
                             BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
9350
896
                    xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9351
896
                         "reuse of the xmlns namespace name is forbidden\n",
9352
896
                             NULL, NULL, NULL);
9353
896
                    goto next_attr;
9354
896
                }
9355
91.2k
            }
9356
            /*
9357
             * check that it's not a defined namespace
9358
             */
9359
96.0k
            for (j = 1;j <= nbNs;j++)
9360
6.88k
                if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
9361
2.64k
                    break;
9362
91.7k
            if (j <= nbNs)
9363
2.64k
                xmlErrAttributeDup(ctxt, NULL, attname);
9364
89.1k
            else
9365
89.1k
                if (nsPush(ctxt, NULL, URL) > 0) nbNs++;
9366
9367
164k
        } else if (aprefix == ctxt->str_xmlns) {
9368
44.3k
            const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
9369
44.3k
            xmlURIPtr uri;
9370
9371
44.3k
            if (attname == ctxt->str_xml) {
9372
1.37k
                if (URL != ctxt->str_xml_ns) {
9373
1.18k
                    xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9374
1.18k
                             "xml namespace prefix mapped to wrong URI\n",
9375
1.18k
                             NULL, NULL, NULL);
9376
1.18k
                }
9377
                /*
9378
                 * Do not keep a namespace definition node
9379
                 */
9380
1.37k
                goto next_attr;
9381
1.37k
            }
9382
43.0k
            if (URL == ctxt->str_xml_ns) {
9383
676
                if (attname != ctxt->str_xml) {
9384
676
                    xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9385
676
                             "xml namespace URI mapped to wrong prefix\n",
9386
676
                             NULL, NULL, NULL);
9387
676
                }
9388
676
                goto next_attr;
9389
676
            }
9390
42.3k
            if (attname == ctxt->str_xmlns) {
9391
1.14k
                xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9392
1.14k
                         "redefinition of the xmlns prefix is forbidden\n",
9393
1.14k
                         NULL, NULL, NULL);
9394
1.14k
                goto next_attr;
9395
1.14k
            }
9396
41.1k
            if ((len == 29) &&
9397
41.1k
                (xmlStrEqual(URL,
9398
1.32k
                             BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
9399
579
                xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9400
579
                         "reuse of the xmlns namespace name is forbidden\n",
9401
579
                         NULL, NULL, NULL);
9402
579
                goto next_attr;
9403
579
            }
9404
40.6k
            if ((URL == NULL) || (URL[0] == 0)) {
9405
1.21k
                xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9406
1.21k
                         "xmlns:%s: Empty XML namespace is not allowed\n",
9407
1.21k
                              attname, NULL, NULL);
9408
1.21k
                goto next_attr;
9409
39.3k
            } else {
9410
39.3k
                uri = xmlParseURI((const char *) URL);
9411
39.3k
                if (uri == NULL) {
9412
16.7k
                    xmlNsErr(ctxt, XML_WAR_NS_URI,
9413
16.7k
                         "xmlns:%s: '%s' is not a valid URI\n",
9414
16.7k
                                       attname, URL, NULL);
9415
22.6k
                } else {
9416
22.6k
                    if ((ctxt->pedantic) && (uri->scheme == NULL)) {
9417
0
                        xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
9418
0
                                  "xmlns:%s: URI %s is not absolute\n",
9419
0
                                  attname, URL, NULL);
9420
0
                    }
9421
22.6k
                    xmlFreeURI(uri);
9422
22.6k
                }
9423
39.3k
            }
9424
9425
            /*
9426
             * check that it's not a defined namespace
9427
             */
9428
46.9k
            for (j = 1;j <= nbNs;j++)
9429
8.78k
                if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
9430
1.25k
                    break;
9431
39.3k
            if (j <= nbNs)
9432
1.25k
                xmlErrAttributeDup(ctxt, aprefix, attname);
9433
38.1k
            else
9434
38.1k
                if (nsPush(ctxt, attname, URL) > 0) nbNs++;
9435
9436
119k
        } else {
9437
            /*
9438
             * Add the pair to atts
9439
             */
9440
119k
            if ((atts == NULL) || (nbatts + 5 > maxatts)) {
9441
55.1k
                if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
9442
0
                    goto next_attr;
9443
0
                }
9444
55.1k
                maxatts = ctxt->maxatts;
9445
55.1k
                atts = ctxt->atts;
9446
55.1k
            }
9447
119k
            ctxt->attallocs[nratts++] = alloc;
9448
119k
            atts[nbatts++] = attname;
9449
119k
            atts[nbatts++] = aprefix;
9450
            /*
9451
             * The namespace URI field is used temporarily to point at the
9452
             * base of the current input buffer for non-alloced attributes.
9453
             * When the input buffer is reallocated, all the pointers become
9454
             * invalid, but they can be reconstructed later.
9455
             */
9456
119k
            if (alloc)
9457
51.8k
                atts[nbatts++] = NULL;
9458
67.9k
            else
9459
67.9k
                atts[nbatts++] = ctxt->input->base;
9460
119k
            atts[nbatts++] = attvalue;
9461
119k
            attvalue += len;
9462
119k
            atts[nbatts++] = attvalue;
9463
            /*
9464
             * tag if some deallocation is needed
9465
             */
9466
119k
            if (alloc != 0) attval = 1;
9467
119k
            attvalue = NULL; /* moved into atts */
9468
119k
        }
9469
9470
431k
next_attr:
9471
431k
        if ((attvalue != NULL) && (alloc != 0)) {
9472
33.7k
            xmlFree(attvalue);
9473
33.7k
            attvalue = NULL;
9474
33.7k
        }
9475
9476
431k
  GROW
9477
431k
        if (ctxt->instate == XML_PARSER_EOF)
9478
0
            break;
9479
431k
  if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
9480
177k
      break;
9481
253k
  if (SKIP_BLANKS == 0) {
9482
202k
      xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
9483
202k
         "attributes construct error\n");
9484
202k
      break;
9485
202k
  }
9486
50.6k
        if ((cons == CUR_CONSUMED) && (id == ctxt->input->id) &&
9487
50.6k
            (attname == NULL) && (attvalue == NULL)) {
9488
0
      xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
9489
0
           "xmlParseStartTag: problem parsing attributes\n");
9490
0
      break;
9491
0
  }
9492
50.6k
        GROW;
9493
50.6k
    }
9494
9495
5.66M
    if (ctxt->input->id != inputid) {
9496
0
        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
9497
0
                    "Unexpected change of input\n");
9498
0
        localname = NULL;
9499
0
        goto done;
9500
0
    }
9501
9502
    /* Reconstruct attribute value pointers. */
9503
5.78M
    for (i = 0, j = 0; j < nratts; i += 5, j++) {
9504
119k
        if (atts[i+2] != NULL) {
9505
            /*
9506
             * Arithmetic on dangling pointers is technically undefined
9507
             * behavior, but well...
9508
             */
9509
67.9k
            ptrdiff_t offset = ctxt->input->base - atts[i+2];
9510
67.9k
            atts[i+2]  = NULL;    /* Reset repurposed namespace URI */
9511
67.9k
            atts[i+3] += offset;  /* value */
9512
67.9k
            atts[i+4] += offset;  /* valuend */
9513
67.9k
        }
9514
119k
    }
9515
9516
    /*
9517
     * The attributes defaulting
9518
     */
9519
5.66M
    if (ctxt->attsDefault != NULL) {
9520
4.20M
        xmlDefAttrsPtr defaults;
9521
9522
4.20M
  defaults = xmlHashLookup2(ctxt->attsDefault, localname, prefix);
9523
4.20M
  if (defaults != NULL) {
9524
32.3M
      for (i = 0;i < defaults->nbAttrs;i++) {
9525
28.3M
          attname = defaults->values[5 * i];
9526
28.3M
    aprefix = defaults->values[5 * i + 1];
9527
9528
                /*
9529
     * special work for namespaces defaulted defs
9530
     */
9531
28.3M
    if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
9532
        /*
9533
         * check that it's not a defined namespace
9534
         */
9535
24.2M
        for (j = 1;j <= nbNs;j++)
9536
20.1M
            if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
9537
2.37k
          break;
9538
4.08M
              if (j <= nbNs) continue;
9539
9540
4.08M
        nsname = xmlGetNamespace(ctxt, NULL);
9541
4.08M
        if (nsname != defaults->values[5 * i + 2]) {
9542
4.08M
      if (nsPush(ctxt, NULL,
9543
4.08M
                 defaults->values[5 * i + 2]) > 0)
9544
4.08M
          nbNs++;
9545
4.08M
        }
9546
24.2M
    } else if (aprefix == ctxt->str_xmlns) {
9547
        /*
9548
         * check that it's not a defined namespace
9549
         */
9550
60.3M
        for (j = 1;j <= nbNs;j++)
9551
40.2M
            if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
9552
517
          break;
9553
20.1M
              if (j <= nbNs) continue;
9554
9555
20.1M
        nsname = xmlGetNamespace(ctxt, attname);
9556
20.1M
        if (nsname != defaults->values[2]) {
9557
20.1M
      if (nsPush(ctxt, attname,
9558
20.1M
                 defaults->values[5 * i + 2]) > 0)
9559
20.1M
          nbNs++;
9560
20.1M
        }
9561
20.1M
    } else {
9562
        /*
9563
         * check that it's not a defined attribute
9564
         */
9565
4.12M
        for (j = 0;j < nbatts;j+=5) {
9566
38.2k
      if ((attname == atts[j]) && (aprefix == atts[j+1]))
9567
1.17k
          break;
9568
38.2k
        }
9569
4.08M
        if (j < nbatts) continue;
9570
9571
4.08M
        if ((atts == NULL) || (nbatts + 5 > maxatts)) {
9572
1.12k
      if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
9573
0
                            localname = NULL;
9574
0
                            goto done;
9575
0
      }
9576
1.12k
      maxatts = ctxt->maxatts;
9577
1.12k
      atts = ctxt->atts;
9578
1.12k
        }
9579
4.08M
        atts[nbatts++] = attname;
9580
4.08M
        atts[nbatts++] = aprefix;
9581
4.08M
        if (aprefix == NULL)
9582
4.08M
      atts[nbatts++] = NULL;
9583
3.69k
        else
9584
3.69k
            atts[nbatts++] = xmlGetNamespace(ctxt, aprefix);
9585
4.08M
        atts[nbatts++] = defaults->values[5 * i + 2];
9586
4.08M
        atts[nbatts++] = defaults->values[5 * i + 3];
9587
4.08M
        if ((ctxt->standalone == 1) &&
9588
4.08M
            (defaults->values[5 * i + 4] != NULL)) {
9589
0
      xmlValidityError(ctxt, XML_DTD_STANDALONE_DEFAULTED,
9590
0
    "standalone: attribute %s on %s defaulted from external subset\n",
9591
0
                                   attname, localname);
9592
0
        }
9593
4.08M
        nbdef++;
9594
4.08M
    }
9595
28.3M
      }
9596
4.09M
  }
9597
4.20M
    }
9598
9599
    /*
9600
     * The attributes checkings
9601
     */
9602
9.86M
    for (i = 0; i < nbatts;i += 5) {
9603
        /*
9604
  * The default namespace does not apply to attribute names.
9605
  */
9606
4.20M
  if (atts[i + 1] != NULL) {
9607
70.5k
      nsname = xmlGetNamespace(ctxt, atts[i + 1]);
9608
70.5k
      if (nsname == NULL) {
9609
16.5k
    xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
9610
16.5k
        "Namespace prefix %s for %s on %s is not defined\n",
9611
16.5k
        atts[i + 1], atts[i], localname);
9612
16.5k
      }
9613
70.5k
      atts[i + 2] = nsname;
9614
70.5k
  } else
9615
4.13M
      nsname = NULL;
9616
  /*
9617
   * [ WFC: Unique Att Spec ]
9618
   * No attribute name may appear more than once in the same
9619
   * start-tag or empty-element tag.
9620
   * As extended by the Namespace in XML REC.
9621
   */
9622
4.27M
        for (j = 0; j < i;j += 5) {
9623
77.2k
      if (atts[i] == atts[j]) {
9624
9.72k
          if (atts[i+1] == atts[j+1]) {
9625
6.59k
        xmlErrAttributeDup(ctxt, atts[i+1], atts[i]);
9626
6.59k
        break;
9627
6.59k
    }
9628
3.12k
    if ((nsname != NULL) && (atts[j + 2] == nsname)) {
9629
315
        xmlNsErr(ctxt, XML_NS_ERR_ATTRIBUTE_REDEFINED,
9630
315
           "Namespaced Attribute %s in '%s' redefined\n",
9631
315
           atts[i], nsname, NULL);
9632
315
        break;
9633
315
    }
9634
3.12k
      }
9635
77.2k
  }
9636
4.20M
    }
9637
9638
5.66M
    nsname = xmlGetNamespace(ctxt, prefix);
9639
5.66M
    if ((prefix != NULL) && (nsname == NULL)) {
9640
27.1k
  xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
9641
27.1k
           "Namespace prefix %s on %s is not defined\n",
9642
27.1k
     prefix, localname, NULL);
9643
27.1k
    }
9644
5.66M
    *pref = prefix;
9645
5.66M
    *URI = nsname;
9646
9647
    /*
9648
     * SAX: Start of Element !
9649
     */
9650
5.66M
    if ((ctxt->sax != NULL) && (ctxt->sax->startElementNs != NULL) &&
9651
5.66M
  (!ctxt->disableSAX)) {
9652
533k
  if (nbNs > 0)
9653
124k
      ctxt->sax->startElementNs(ctxt->userData, localname, prefix,
9654
124k
        nsname, nbNs, &ctxt->nsTab[ctxt->nsNr - 2 * nbNs],
9655
124k
        nbatts / 5, nbdef, atts);
9656
409k
  else
9657
409k
      ctxt->sax->startElementNs(ctxt->userData, localname, prefix,
9658
409k
                    nsname, 0, NULL, nbatts / 5, nbdef, atts);
9659
533k
    }
9660
9661
5.66M
done:
9662
    /*
9663
     * Free up attribute allocated strings if needed
9664
     */
9665
5.66M
    if (attval != 0) {
9666
105k
  for (i = 3,j = 0; j < nratts;i += 5,j++)
9667
54.7k
      if ((ctxt->attallocs[j] != 0) && (atts[i] != NULL))
9668
51.8k
          xmlFree((xmlChar *) atts[i]);
9669
50.8k
    }
9670
9671
5.66M
    return(localname);
9672
5.66M
}
9673
9674
/**
9675
 * xmlParseEndTag2:
9676
 * @ctxt:  an XML parser context
9677
 * @line:  line of the start tag
9678
 * @nsNr:  number of namespaces on the start tag
9679
 *
9680
 * parse an end of tag
9681
 *
9682
 * [42] ETag ::= '</' Name S? '>'
9683
 *
9684
 * With namespace
9685
 *
9686
 * [NS 9] ETag ::= '</' QName S? '>'
9687
 */
9688
9689
static void
9690
201k
xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlStartTag *tag) {
9691
201k
    const xmlChar *name;
9692
9693
201k
    GROW;
9694
201k
    if ((RAW != '<') || (NXT(1) != '/')) {
9695
0
  xmlFatalErr(ctxt, XML_ERR_LTSLASH_REQUIRED, NULL);
9696
0
  return;
9697
0
    }
9698
201k
    SKIP(2);
9699
9700
201k
    if (tag->prefix == NULL)
9701
191k
        name = xmlParseNameAndCompare(ctxt, ctxt->name);
9702
9.87k
    else
9703
9.87k
        name = xmlParseQNameAndCompare(ctxt, ctxt->name, tag->prefix);
9704
9705
    /*
9706
     * We should definitely be at the ending "S? '>'" part
9707
     */
9708
201k
    GROW;
9709
201k
    if (ctxt->instate == XML_PARSER_EOF)
9710
0
        return;
9711
201k
    SKIP_BLANKS;
9712
201k
    if ((!IS_BYTE_CHAR(RAW)) || (RAW != '>')) {
9713
15.6k
  xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
9714
15.6k
    } else
9715
185k
  NEXT1;
9716
9717
    /*
9718
     * [ WFC: Element Type Match ]
9719
     * The Name in an element's end-tag must match the element type in the
9720
     * start-tag.
9721
     *
9722
     */
9723
201k
    if (name != (xmlChar*)1) {
9724
19.6k
        if (name == NULL) name = BAD_CAST "unparsable";
9725
19.6k
        xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
9726
19.6k
         "Opening and ending tag mismatch: %s line %d and %s\n",
9727
19.6k
                    ctxt->name, tag->line, name);
9728
19.6k
    }
9729
9730
    /*
9731
     * SAX: End of Tag
9732
     */
9733
201k
    if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
9734
201k
  (!ctxt->disableSAX))
9735
150k
  ctxt->sax->endElementNs(ctxt->userData, ctxt->name, tag->prefix,
9736
150k
                                tag->URI);
9737
9738
201k
    spacePop(ctxt);
9739
201k
    if (tag->nsNr != 0)
9740
9.97k
  nsPop(ctxt, tag->nsNr);
9741
201k
}
9742
9743
/**
9744
 * xmlParseCDSect:
9745
 * @ctxt:  an XML parser context
9746
 *
9747
 * Parse escaped pure raw content.
9748
 *
9749
 * [18] CDSect ::= CDStart CData CDEnd
9750
 *
9751
 * [19] CDStart ::= '<![CDATA['
9752
 *
9753
 * [20] Data ::= (Char* - (Char* ']]>' Char*))
9754
 *
9755
 * [21] CDEnd ::= ']]>'
9756
 */
9757
void
9758
13.7k
xmlParseCDSect(xmlParserCtxtPtr ctxt) {
9759
13.7k
    xmlChar *buf = NULL;
9760
13.7k
    int len = 0;
9761
13.7k
    int size = XML_PARSER_BUFFER_SIZE;
9762
13.7k
    int r, rl;
9763
13.7k
    int s, sl;
9764
13.7k
    int cur, l;
9765
13.7k
    int count = 0;
9766
9767
    /* Check 2.6.0 was NXT(0) not RAW */
9768
13.7k
    if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) {
9769
13.7k
  SKIP(9);
9770
13.7k
    } else
9771
0
        return;
9772
9773
13.7k
    ctxt->instate = XML_PARSER_CDATA_SECTION;
9774
13.7k
    r = CUR_CHAR(rl);
9775
13.7k
    if (!IS_CHAR(r)) {
9776
1.00k
  xmlFatalErr(ctxt, XML_ERR_CDATA_NOT_FINISHED, NULL);
9777
1.00k
  ctxt->instate = XML_PARSER_CONTENT;
9778
1.00k
        return;
9779
1.00k
    }
9780
12.6k
    NEXTL(rl);
9781
12.6k
    s = CUR_CHAR(sl);
9782
12.6k
    if (!IS_CHAR(s)) {
9783
2.44k
  xmlFatalErr(ctxt, XML_ERR_CDATA_NOT_FINISHED, NULL);
9784
2.44k
  ctxt->instate = XML_PARSER_CONTENT;
9785
2.44k
        return;
9786
2.44k
    }
9787
10.2k
    NEXTL(sl);
9788
10.2k
    cur = CUR_CHAR(l);
9789
10.2k
    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
9790
10.2k
    if (buf == NULL) {
9791
0
  xmlErrMemory(ctxt, NULL);
9792
0
  return;
9793
0
    }
9794
67.6M
    while (IS_CHAR(cur) &&
9795
67.6M
           ((r != ']') || (s != ']') || (cur != '>'))) {
9796
67.6M
  if (len + 5 >= size) {
9797
7.95k
      xmlChar *tmp;
9798
9799
7.95k
            if ((size > XML_MAX_TEXT_LENGTH) &&
9800
7.95k
                ((ctxt->options & XML_PARSE_HUGE) == 0)) {
9801
0
                xmlFatalErrMsgStr(ctxt, XML_ERR_CDATA_NOT_FINISHED,
9802
0
                             "CData section too big found", NULL);
9803
0
                xmlFree (buf);
9804
0
                return;
9805
0
            }
9806
7.95k
      tmp = (xmlChar *) xmlRealloc(buf, size * 2 * sizeof(xmlChar));
9807
7.95k
      if (tmp == NULL) {
9808
0
          xmlFree(buf);
9809
0
    xmlErrMemory(ctxt, NULL);
9810
0
    return;
9811
0
      }
9812
7.95k
      buf = tmp;
9813
7.95k
      size *= 2;
9814
7.95k
  }
9815
67.6M
  COPY_BUF(rl,buf,len,r);
9816
67.6M
  r = s;
9817
67.6M
  rl = sl;
9818
67.6M
  s = cur;
9819
67.6M
  sl = l;
9820
67.6M
  count++;
9821
67.6M
  if (count > 50) {
9822
1.32M
      SHRINK;
9823
1.32M
      GROW;
9824
1.32M
            if (ctxt->instate == XML_PARSER_EOF) {
9825
0
    xmlFree(buf);
9826
0
    return;
9827
0
            }
9828
1.32M
      count = 0;
9829
1.32M
  }
9830
67.6M
  NEXTL(l);
9831
67.6M
  cur = CUR_CHAR(l);
9832
67.6M
    }
9833
10.2k
    buf[len] = 0;
9834
10.2k
    ctxt->instate = XML_PARSER_CONTENT;
9835
10.2k
    if (cur != '>') {
9836
6.00k
  xmlFatalErrMsgStr(ctxt, XML_ERR_CDATA_NOT_FINISHED,
9837
6.00k
                       "CData section not finished\n%.50s\n", buf);
9838
6.00k
  xmlFree(buf);
9839
6.00k
        return;
9840
6.00k
    }
9841
4.24k
    NEXTL(l);
9842
9843
    /*
9844
     * OK the buffer is to be consumed as cdata.
9845
     */
9846
4.24k
    if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
9847
942
  if (ctxt->sax->cdataBlock != NULL)
9848
942
      ctxt->sax->cdataBlock(ctxt->userData, buf, len);
9849
0
  else if (ctxt->sax->characters != NULL)
9850
0
      ctxt->sax->characters(ctxt->userData, buf, len);
9851
942
    }
9852
4.24k
    xmlFree(buf);
9853
4.24k
}
9854
9855
/**
9856
 * xmlParseContentInternal:
9857
 * @ctxt:  an XML parser context
9858
 *
9859
 * Parse a content sequence. Stops at EOF or '</'. Leaves checking of
9860
 * unexpected EOF to the caller.
9861
 */
9862
9863
static void
9864
307k
xmlParseContentInternal(xmlParserCtxtPtr ctxt) {
9865
307k
    int nameNr = ctxt->nameNr;
9866
9867
307k
    GROW;
9868
7.62M
    while ((RAW != 0) &&
9869
7.62M
     (ctxt->instate != XML_PARSER_EOF)) {
9870
7.37M
        int id = ctxt->input->id;
9871
7.37M
  unsigned long cons = CUR_CONSUMED;
9872
7.37M
  const xmlChar *cur = ctxt->input->cur;
9873
9874
  /*
9875
   * First case : a Processing Instruction.
9876
   */
9877
7.37M
  if ((*cur == '<') && (cur[1] == '?')) {
9878
6.16k
      xmlParsePI(ctxt);
9879
6.16k
  }
9880
9881
  /*
9882
   * Second case : a CDSection
9883
   */
9884
  /* 2.6.0 test was *cur not RAW */
9885
7.37M
  else if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) {
9886
13.7k
      xmlParseCDSect(ctxt);
9887
13.7k
  }
9888
9889
  /*
9890
   * Third case :  a comment
9891
   */
9892
7.35M
  else if ((*cur == '<') && (NXT(1) == '!') &&
9893
7.35M
     (NXT(2) == '-') && (NXT(3) == '-')) {
9894
7.66k
      xmlParseComment(ctxt);
9895
7.66k
      ctxt->instate = XML_PARSER_CONTENT;
9896
7.66k
  }
9897
9898
  /*
9899
   * Fourth case :  a sub-element.
9900
   */
9901
7.34M
  else if (*cur == '<') {
9902
5.98M
            if (NXT(1) == '/') {
9903
202k
                if (ctxt->nameNr <= nameNr)
9904
1.71k
                    break;
9905
200k
          xmlParseElementEnd(ctxt);
9906
5.78M
            } else {
9907
5.78M
          xmlParseElementStart(ctxt);
9908
5.78M
            }
9909
5.98M
  }
9910
9911
  /*
9912
   * Fifth case : a reference. If if has not been resolved,
9913
   *    parsing returns it's Name, create the node
9914
   */
9915
9916
1.36M
  else if (*cur == '&') {
9917
534k
      xmlParseReference(ctxt);
9918
534k
  }
9919
9920
  /*
9921
   * Last case, text. Note that References are handled directly.
9922
   */
9923
830k
  else {
9924
830k
      xmlParseCharData(ctxt, 0);
9925
830k
  }
9926
9927
7.37M
  GROW;
9928
7.37M
  SHRINK;
9929
9930
7.37M
  if ((cons == CUR_CONSUMED) && (id == ctxt->input->id)) {
9931
53.4k
      xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
9932
53.4k
                  "detected an error in element content\n");
9933
53.4k
      xmlHaltParser(ctxt);
9934
53.4k
            break;
9935
53.4k
  }
9936
7.37M
    }
9937
307k
}
9938
9939
/**
9940
 * xmlParseContent:
9941
 * @ctxt:  an XML parser context
9942
 *
9943
 * Parse a content sequence. Stops at EOF or '</'.
9944
 *
9945
 * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
9946
 */
9947
9948
void
9949
300k
xmlParseContent(xmlParserCtxtPtr ctxt) {
9950
300k
    int nameNr = ctxt->nameNr;
9951
9952
300k
    xmlParseContentInternal(ctxt);
9953
9954
300k
    if ((ctxt->instate != XML_PARSER_EOF) && (ctxt->nameNr > nameNr)) {
9955
38.1k
        const xmlChar *name = ctxt->nameTab[ctxt->nameNr - 1];
9956
38.1k
        int line = ctxt->pushTab[ctxt->nameNr - 1].line;
9957
38.1k
        xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
9958
38.1k
                "Premature end of data in tag %s line %d\n",
9959
38.1k
    name, line, NULL);
9960
38.1k
    }
9961
300k
}
9962
9963
/**
9964
 * xmlParseElement:
9965
 * @ctxt:  an XML parser context
9966
 *
9967
 * parse an XML element
9968
 *
9969
 * [39] element ::= EmptyElemTag | STag content ETag
9970
 *
9971
 * [ WFC: Element Type Match ]
9972
 * The Name in an element's end-tag must match the element type in the
9973
 * start-tag.
9974
 *
9975
 */
9976
9977
void
9978
10.2k
xmlParseElement(xmlParserCtxtPtr ctxt) {
9979
10.2k
    if (xmlParseElementStart(ctxt) != 0)
9980
3.73k
        return;
9981
9982
6.54k
    xmlParseContentInternal(ctxt);
9983
6.54k
    if (ctxt->instate == XML_PARSER_EOF)
9984
653
  return;
9985
9986
5.88k
    if (CUR == 0) {
9987
5.73k
        const xmlChar *name = ctxt->nameTab[ctxt->nameNr - 1];
9988
5.73k
        int line = ctxt->pushTab[ctxt->nameNr - 1].line;
9989
5.73k
        xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
9990
5.73k
                "Premature end of data in tag %s line %d\n",
9991
5.73k
    name, line, NULL);
9992
5.73k
        return;
9993
5.73k
    }
9994
9995
154
    xmlParseElementEnd(ctxt);
9996
154
}
9997
9998
/**
9999
 * xmlParseElementStart:
10000
 * @ctxt:  an XML parser context
10001
 *
10002
 * Parse the start of an XML element. Returns -1 in case of error, 0 if an
10003
 * opening tag was parsed, 1 if an empty element was parsed.
10004
 */
10005
static int
10006
5.79M
xmlParseElementStart(xmlParserCtxtPtr ctxt) {
10007
5.79M
    const xmlChar *name;
10008
5.79M
    const xmlChar *prefix = NULL;
10009
5.79M
    const xmlChar *URI = NULL;
10010
5.79M
    xmlParserNodeInfo node_info;
10011
5.79M
    int line, tlen = 0;
10012
5.79M
    xmlNodePtr ret;
10013
5.79M
    int nsNr = ctxt->nsNr;
10014
10015
5.79M
    if (((unsigned int) ctxt->nameNr > xmlParserMaxDepth) &&
10016
5.79M
        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
10017
0
  xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
10018
0
     "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
10019
0
        xmlParserMaxDepth);
10020
0
  xmlHaltParser(ctxt);
10021
0
  return(-1);
10022
0
    }
10023
10024
    /* Capture start position */
10025
5.79M
    if (ctxt->record_info) {
10026
0
        node_info.begin_pos = ctxt->input->consumed +
10027
0
                          (CUR_PTR - ctxt->input->base);
10028
0
  node_info.begin_line = ctxt->input->line;
10029
0
    }
10030
10031
5.79M
    if (ctxt->spaceNr == 0)
10032
0
  spacePush(ctxt, -1);
10033
5.79M
    else if (*ctxt->space == -2)
10034
0
  spacePush(ctxt, -1);
10035
5.79M
    else
10036
5.79M
  spacePush(ctxt, *ctxt->space);
10037
10038
5.79M
    line = ctxt->input->line;
10039
5.79M
#ifdef LIBXML_SAX1_ENABLED
10040
5.79M
    if (ctxt->sax2)
10041
5.79M
#endif /* LIBXML_SAX1_ENABLED */
10042
5.79M
        name = xmlParseStartTag2(ctxt, &prefix, &URI, &tlen);
10043
0
#ifdef LIBXML_SAX1_ENABLED
10044
0
    else
10045
0
  name = xmlParseStartTag(ctxt);
10046
5.79M
#endif /* LIBXML_SAX1_ENABLED */
10047
5.79M
    if (ctxt->instate == XML_PARSER_EOF)
10048
0
  return(-1);
10049
5.79M
    if (name == NULL) {
10050
129k
  spacePop(ctxt);
10051
129k
        return(-1);
10052
129k
    }
10053
5.66M
    nameNsPush(ctxt, name, prefix, URI, line, ctxt->nsNr - nsNr);
10054
5.66M
    ret = ctxt->node;
10055
10056
5.66M
#ifdef LIBXML_VALID_ENABLED
10057
    /*
10058
     * [ VC: Root Element Type ]
10059
     * The Name in the document type declaration must match the element
10060
     * type of the root element.
10061
     */
10062
5.66M
    if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
10063
5.66M
        ctxt->node && (ctxt->node == ctxt->myDoc->children))
10064
0
        ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
10065
5.66M
#endif /* LIBXML_VALID_ENABLED */
10066
10067
    /*
10068
     * Check for an Empty Element.
10069
     */
10070
5.66M
    if ((RAW == '/') && (NXT(1) == '>')) {
10071
60.3k
        SKIP(2);
10072
60.3k
  if (ctxt->sax2) {
10073
60.3k
      if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
10074
60.3k
    (!ctxt->disableSAX))
10075
36.0k
    ctxt->sax->endElementNs(ctxt->userData, name, prefix, URI);
10076
60.3k
#ifdef LIBXML_SAX1_ENABLED
10077
60.3k
  } else {
10078
0
      if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
10079
0
    (!ctxt->disableSAX))
10080
0
    ctxt->sax->endElement(ctxt->userData, name);
10081
0
#endif /* LIBXML_SAX1_ENABLED */
10082
0
  }
10083
60.3k
  namePop(ctxt);
10084
60.3k
  spacePop(ctxt);
10085
60.3k
  if (nsNr != ctxt->nsNr)
10086
14.3k
      nsPop(ctxt, ctxt->nsNr - nsNr);
10087
60.3k
  if ( ret != NULL && ctxt->record_info ) {
10088
0
     node_info.end_pos = ctxt->input->consumed +
10089
0
            (CUR_PTR - ctxt->input->base);
10090
0
     node_info.end_line = ctxt->input->line;
10091
0
     node_info.node = ret;
10092
0
     xmlParserAddNodeInfo(ctxt, &node_info);
10093
0
  }
10094
60.3k
  return(1);
10095
60.3k
    }
10096
5.60M
    if (RAW == '>') {
10097
5.38M
        NEXT1;
10098
5.38M
    } else {
10099
215k
        xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_GT_REQUIRED,
10100
215k
         "Couldn't find end of Start Tag %s line %d\n",
10101
215k
                    name, line, NULL);
10102
10103
  /*
10104
   * end of parsing of this node.
10105
   */
10106
215k
  nodePop(ctxt);
10107
215k
  namePop(ctxt);
10108
215k
  spacePop(ctxt);
10109
215k
  if (nsNr != ctxt->nsNr)
10110
92.6k
      nsPop(ctxt, ctxt->nsNr - nsNr);
10111
10112
  /*
10113
   * Capture end position and add node
10114
   */
10115
215k
  if ( ret != NULL && ctxt->record_info ) {
10116
0
     node_info.end_pos = ctxt->input->consumed +
10117
0
            (CUR_PTR - ctxt->input->base);
10118
0
     node_info.end_line = ctxt->input->line;
10119
0
     node_info.node = ret;
10120
0
     xmlParserAddNodeInfo(ctxt, &node_info);
10121
0
  }
10122
215k
  return(-1);
10123
215k
    }
10124
10125
5.38M
    return(0);
10126
5.60M
}
10127
10128
/**
10129
 * xmlParseElementEnd:
10130
 * @ctxt:  an XML parser context
10131
 *
10132
 * Parse the end of an XML element.
10133
 */
10134
static void
10135
201k
xmlParseElementEnd(xmlParserCtxtPtr ctxt) {
10136
201k
    xmlParserNodeInfo node_info;
10137
201k
    xmlNodePtr ret = ctxt->node;
10138
10139
201k
    if (ctxt->nameNr <= 0)
10140
0
        return;
10141
10142
    /*
10143
     * parse the end of tag: '</' should be here.
10144
     */
10145
201k
    if (ctxt->sax2) {
10146
201k
  xmlParseEndTag2(ctxt, &ctxt->pushTab[ctxt->nameNr - 1]);
10147
201k
  namePop(ctxt);
10148
201k
    }
10149
0
#ifdef LIBXML_SAX1_ENABLED
10150
0
    else
10151
0
  xmlParseEndTag1(ctxt, 0);
10152
201k
#endif /* LIBXML_SAX1_ENABLED */
10153
10154
    /*
10155
     * Capture end position and add node
10156
     */
10157
201k
    if ( ret != NULL && ctxt->record_info ) {
10158
0
       node_info.end_pos = ctxt->input->consumed +
10159
0
                          (CUR_PTR - ctxt->input->base);
10160
0
       node_info.end_line = ctxt->input->line;
10161
0
       node_info.node = ret;
10162
0
       xmlParserAddNodeInfo(ctxt, &node_info);
10163
0
    }
10164
201k
}
10165
10166
/**
10167
 * xmlParseVersionNum:
10168
 * @ctxt:  an XML parser context
10169
 *
10170
 * parse the XML version value.
10171
 *
10172
 * [26] VersionNum ::= '1.' [0-9]+
10173
 *
10174
 * In practice allow [0-9].[0-9]+ at that level
10175
 *
10176
 * Returns the string giving the XML version number, or NULL
10177
 */
10178
xmlChar *
10179
2.58k
xmlParseVersionNum(xmlParserCtxtPtr ctxt) {
10180
2.58k
    xmlChar *buf = NULL;
10181
2.58k
    int len = 0;
10182
2.58k
    int size = 10;
10183
2.58k
    xmlChar cur;
10184
10185
2.58k
    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
10186
2.58k
    if (buf == NULL) {
10187
0
  xmlErrMemory(ctxt, NULL);
10188
0
  return(NULL);
10189
0
    }
10190
2.58k
    cur = CUR;
10191
2.58k
    if (!((cur >= '0') && (cur <= '9'))) {
10192
19
  xmlFree(buf);
10193
19
  return(NULL);
10194
19
    }
10195
2.56k
    buf[len++] = cur;
10196
2.56k
    NEXT;
10197
2.56k
    cur=CUR;
10198
2.56k
    if (cur != '.') {
10199
5
  xmlFree(buf);
10200
5
  return(NULL);
10201
5
    }
10202
2.55k
    buf[len++] = cur;
10203
2.55k
    NEXT;
10204
2.55k
    cur=CUR;
10205
159k
    while ((cur >= '0') && (cur <= '9')) {
10206
157k
  if (len + 1 >= size) {
10207
163
      xmlChar *tmp;
10208
10209
163
      size *= 2;
10210
163
      tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
10211
163
      if (tmp == NULL) {
10212
0
          xmlFree(buf);
10213
0
    xmlErrMemory(ctxt, NULL);
10214
0
    return(NULL);
10215
0
      }
10216
163
      buf = tmp;
10217
163
  }
10218
157k
  buf[len++] = cur;
10219
157k
  NEXT;
10220
157k
  cur=CUR;
10221
157k
    }
10222
2.55k
    buf[len] = 0;
10223
2.55k
    return(buf);
10224
2.55k
}
10225
10226
/**
10227
 * xmlParseVersionInfo:
10228
 * @ctxt:  an XML parser context
10229
 *
10230
 * parse the XML version.
10231
 *
10232
 * [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
10233
 *
10234
 * [25] Eq ::= S? '=' S?
10235
 *
10236
 * Returns the version string, e.g. "1.0"
10237
 */
10238
10239
xmlChar *
10240
4.65k
xmlParseVersionInfo(xmlParserCtxtPtr ctxt) {
10241
4.65k
    xmlChar *version = NULL;
10242
10243
4.65k
    if (CMP7(CUR_PTR, 'v', 'e', 'r', 's', 'i', 'o', 'n')) {
10244
2.62k
  SKIP(7);
10245
2.62k
  SKIP_BLANKS;
10246
2.62k
  if (RAW != '=') {
10247
13
      xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
10248
13
      return(NULL);
10249
13
        }
10250
2.61k
  NEXT;
10251
2.61k
  SKIP_BLANKS;
10252
2.61k
  if (RAW == '"') {
10253
2.11k
      NEXT;
10254
2.11k
      version = xmlParseVersionNum(ctxt);
10255
2.11k
      if (RAW != '"') {
10256
47
    xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10257
47
      } else
10258
2.07k
          NEXT;
10259
2.11k
  } else if (RAW == '\''){
10260
464
      NEXT;
10261
464
      version = xmlParseVersionNum(ctxt);
10262
464
      if (RAW != '\'') {
10263
6
    xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10264
6
      } else
10265
458
          NEXT;
10266
464
  } else {
10267
33
      xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
10268
33
  }
10269
2.61k
    }
10270
4.63k
    return(version);
10271
4.65k
}
10272
10273
/**
10274
 * xmlParseEncName:
10275
 * @ctxt:  an XML parser context
10276
 *
10277
 * parse the XML encoding name
10278
 *
10279
 * [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
10280
 *
10281
 * Returns the encoding name value or NULL
10282
 */
10283
xmlChar *
10284
4.16k
xmlParseEncName(xmlParserCtxtPtr ctxt) {
10285
4.16k
    xmlChar *buf = NULL;
10286
4.16k
    int len = 0;
10287
4.16k
    int size = 10;
10288
4.16k
    xmlChar cur;
10289
10290
4.16k
    cur = CUR;
10291
4.16k
    if (((cur >= 'a') && (cur <= 'z')) ||
10292
4.16k
        ((cur >= 'A') && (cur <= 'Z'))) {
10293
4.15k
  buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
10294
4.15k
  if (buf == NULL) {
10295
0
      xmlErrMemory(ctxt, NULL);
10296
0
      return(NULL);
10297
0
  }
10298
10299
4.15k
  buf[len++] = cur;
10300
4.15k
  NEXT;
10301
4.15k
  cur = CUR;
10302
696k
  while (((cur >= 'a') && (cur <= 'z')) ||
10303
696k
         ((cur >= 'A') && (cur <= 'Z')) ||
10304
696k
         ((cur >= '0') && (cur <= '9')) ||
10305
696k
         (cur == '.') || (cur == '_') ||
10306
696k
         (cur == '-')) {
10307
692k
      if (len + 1 >= size) {
10308
575
          xmlChar *tmp;
10309
10310
575
    size *= 2;
10311
575
    tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
10312
575
    if (tmp == NULL) {
10313
0
        xmlErrMemory(ctxt, NULL);
10314
0
        xmlFree(buf);
10315
0
        return(NULL);
10316
0
    }
10317
575
    buf = tmp;
10318
575
      }
10319
692k
      buf[len++] = cur;
10320
692k
      NEXT;
10321
692k
      cur = CUR;
10322
692k
      if (cur == 0) {
10323
64
          SHRINK;
10324
64
    GROW;
10325
64
    cur = CUR;
10326
64
      }
10327
692k
        }
10328
4.15k
  buf[len] = 0;
10329
4.15k
    } else {
10330
5
  xmlFatalErr(ctxt, XML_ERR_ENCODING_NAME, NULL);
10331
5
    }
10332
4.16k
    return(buf);
10333
4.16k
}
10334
10335
/**
10336
 * xmlParseEncodingDecl:
10337
 * @ctxt:  an XML parser context
10338
 *
10339
 * parse the XML encoding declaration
10340
 *
10341
 * [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' |  "'" EncName "'")
10342
 *
10343
 * this setups the conversion filters.
10344
 *
10345
 * Returns the encoding value or NULL
10346
 */
10347
10348
const xmlChar *
10349
4.63k
xmlParseEncodingDecl(xmlParserCtxtPtr ctxt) {
10350
4.63k
    xmlChar *encoding = NULL;
10351
10352
4.63k
    SKIP_BLANKS;
10353
4.63k
    if (CMP8(CUR_PTR, 'e', 'n', 'c', 'o', 'd', 'i', 'n', 'g')) {
10354
4.18k
  SKIP(8);
10355
4.18k
  SKIP_BLANKS;
10356
4.18k
  if (RAW != '=') {
10357
9
      xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
10358
9
      return(NULL);
10359
9
        }
10360
4.17k
  NEXT;
10361
4.17k
  SKIP_BLANKS;
10362
4.17k
  if (RAW == '"') {
10363
3.93k
      NEXT;
10364
3.93k
      encoding = xmlParseEncName(ctxt);
10365
3.93k
      if (RAW != '"') {
10366
86
    xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10367
86
    xmlFree((xmlChar *) encoding);
10368
86
    return(NULL);
10369
86
      } else
10370
3.84k
          NEXT;
10371
3.93k
  } else if (RAW == '\''){
10372
233
      NEXT;
10373
233
      encoding = xmlParseEncName(ctxt);
10374
233
      if (RAW != '\'') {
10375
6
    xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10376
6
    xmlFree((xmlChar *) encoding);
10377
6
    return(NULL);
10378
6
      } else
10379
227
          NEXT;
10380
233
  } else {
10381
13
      xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
10382
13
  }
10383
10384
        /*
10385
         * Non standard parsing, allowing the user to ignore encoding
10386
         */
10387
4.08k
        if (ctxt->options & XML_PARSE_IGNORE_ENC) {
10388
0
      xmlFree((xmlChar *) encoding);
10389
0
            return(NULL);
10390
0
  }
10391
10392
  /*
10393
   * UTF-16 encoding switch has already taken place at this stage,
10394
   * more over the little-endian/big-endian selection is already done
10395
   */
10396
4.08k
        if ((encoding != NULL) &&
10397
4.08k
      ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-16")) ||
10398
4.07k
       (!xmlStrcasecmp(encoding, BAD_CAST "UTF16")))) {
10399
      /*
10400
       * If no encoding was passed to the parser, that we are
10401
       * using UTF-16 and no decoder is present i.e. the
10402
       * document is apparently UTF-8 compatible, then raise an
10403
       * encoding mismatch fatal error
10404
       */
10405
2
      if ((ctxt->encoding == NULL) &&
10406
2
          (ctxt->input->buf != NULL) &&
10407
2
          (ctxt->input->buf->encoder == NULL)) {
10408
2
    xmlFatalErrMsg(ctxt, XML_ERR_INVALID_ENCODING,
10409
2
      "Document labelled UTF-16 but has UTF-8 content\n");
10410
2
      }
10411
2
      if (ctxt->encoding != NULL)
10412
0
    xmlFree((xmlChar *) ctxt->encoding);
10413
2
      ctxt->encoding = encoding;
10414
2
  }
10415
  /*
10416
   * UTF-8 encoding is handled natively
10417
   */
10418
4.08k
        else if ((encoding != NULL) &&
10419
4.08k
      ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-8")) ||
10420
4.06k
       (!xmlStrcasecmp(encoding, BAD_CAST "UTF8")))) {
10421
6
      if (ctxt->encoding != NULL)
10422
0
    xmlFree((xmlChar *) ctxt->encoding);
10423
6
      ctxt->encoding = encoding;
10424
6
  }
10425
4.07k
  else if (encoding != NULL) {
10426
4.06k
      xmlCharEncodingHandlerPtr handler;
10427
10428
4.06k
      if (ctxt->input->encoding != NULL)
10429
0
    xmlFree((xmlChar *) ctxt->input->encoding);
10430
4.06k
      ctxt->input->encoding = encoding;
10431
10432
4.06k
            handler = xmlFindCharEncodingHandler((const char *) encoding);
10433
4.06k
      if (handler != NULL) {
10434
3.65k
    if (xmlSwitchToEncoding(ctxt, handler) < 0) {
10435
        /* failed to convert */
10436
1
        ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
10437
1
        return(NULL);
10438
1
    }
10439
3.65k
      } else {
10440
412
    xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
10441
412
      "Unsupported encoding %s\n", encoding);
10442
412
    return(NULL);
10443
412
      }
10444
4.06k
  }
10445
4.08k
    }
10446
4.11k
    return(encoding);
10447
4.63k
}
10448
10449
/**
10450
 * xmlParseSDDecl:
10451
 * @ctxt:  an XML parser context
10452
 *
10453
 * parse the XML standalone declaration
10454
 *
10455
 * [32] SDDecl ::= S 'standalone' Eq
10456
 *                 (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no')'"'))
10457
 *
10458
 * [ VC: Standalone Document Declaration ]
10459
 * TODO The standalone document declaration must have the value "no"
10460
 * if any external markup declarations contain declarations of:
10461
 *  - attributes with default values, if elements to which these
10462
 *    attributes apply appear in the document without specifications
10463
 *    of values for these attributes, or
10464
 *  - entities (other than amp, lt, gt, apos, quot), if references
10465
 *    to those entities appear in the document, or
10466
 *  - attributes with values subject to normalization, where the
10467
 *    attribute appears in the document with a value which will change
10468
 *    as a result of normalization, or
10469
 *  - element types with element content, if white space occurs directly
10470
 *    within any instance of those types.
10471
 *
10472
 * Returns:
10473
 *   1 if standalone="yes"
10474
 *   0 if standalone="no"
10475
 *  -2 if standalone attribute is missing or invalid
10476
 *    (A standalone value of -2 means that the XML declaration was found,
10477
 *     but no value was specified for the standalone attribute).
10478
 */
10479
10480
int
10481
1.90k
xmlParseSDDecl(xmlParserCtxtPtr ctxt) {
10482
1.90k
    int standalone = -2;
10483
10484
1.90k
    SKIP_BLANKS;
10485
1.90k
    if (CMP10(CUR_PTR, 's', 't', 'a', 'n', 'd', 'a', 'l', 'o', 'n', 'e')) {
10486
210
  SKIP(10);
10487
210
        SKIP_BLANKS;
10488
210
  if (RAW != '=') {
10489
1
      xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
10490
1
      return(standalone);
10491
1
        }
10492
209
  NEXT;
10493
209
  SKIP_BLANKS;
10494
209
        if (RAW == '\''){
10495
164
      NEXT;
10496
164
      if ((RAW == 'n') && (NXT(1) == 'o')) {
10497
138
          standalone = 0;
10498
138
                SKIP(2);
10499
138
      } else if ((RAW == 'y') && (NXT(1) == 'e') &&
10500
26
                 (NXT(2) == 's')) {
10501
16
          standalone = 1;
10502
16
    SKIP(3);
10503
16
            } else {
10504
10
    xmlFatalErr(ctxt, XML_ERR_STANDALONE_VALUE, NULL);
10505
10
      }
10506
164
      if (RAW != '\'') {
10507
27
    xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10508
27
      } else
10509
137
          NEXT;
10510
164
  } else if (RAW == '"'){
10511
44
      NEXT;
10512
44
      if ((RAW == 'n') && (NXT(1) == 'o')) {
10513
2
          standalone = 0;
10514
2
    SKIP(2);
10515
42
      } else if ((RAW == 'y') && (NXT(1) == 'e') &&
10516
42
                 (NXT(2) == 's')) {
10517
30
          standalone = 1;
10518
30
                SKIP(3);
10519
30
            } else {
10520
12
    xmlFatalErr(ctxt, XML_ERR_STANDALONE_VALUE, NULL);
10521
12
      }
10522
44
      if (RAW != '"') {
10523
18
    xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10524
18
      } else
10525
26
          NEXT;
10526
44
  } else {
10527
1
      xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
10528
1
        }
10529
209
    }
10530
1.89k
    return(standalone);
10531
1.90k
}
10532
10533
/**
10534
 * xmlParseXMLDecl:
10535
 * @ctxt:  an XML parser context
10536
 *
10537
 * parse an XML declaration header
10538
 *
10539
 * [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
10540
 */
10541
10542
void
10543
4.65k
xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
10544
4.65k
    xmlChar *version;
10545
10546
    /*
10547
     * This value for standalone indicates that the document has an
10548
     * XML declaration but it does not have a standalone attribute.
10549
     * It will be overwritten later if a standalone attribute is found.
10550
     */
10551
4.65k
    ctxt->input->standalone = -2;
10552
10553
    /*
10554
     * We know that '<?xml' is here.
10555
     */
10556
4.65k
    SKIP(5);
10557
10558
4.65k
    if (!IS_BLANK_CH(RAW)) {
10559
0
  xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
10560
0
                 "Blank needed after '<?xml'\n");
10561
0
    }
10562
4.65k
    SKIP_BLANKS;
10563
10564
    /*
10565
     * We must have the VersionInfo here.
10566
     */
10567
4.65k
    version = xmlParseVersionInfo(ctxt);
10568
4.65k
    if (version == NULL) {
10569
2.09k
  xmlFatalErr(ctxt, XML_ERR_VERSION_MISSING, NULL);
10570
2.55k
    } else {
10571
2.55k
  if (!xmlStrEqual(version, (const xmlChar *) XML_DEFAULT_VERSION)) {
10572
      /*
10573
       * Changed here for XML-1.0 5th edition
10574
       */
10575
2.01k
      if (ctxt->options & XML_PARSE_OLD10) {
10576
0
    xmlFatalErrMsgStr(ctxt, XML_ERR_UNKNOWN_VERSION,
10577
0
                "Unsupported version '%s'\n",
10578
0
                version);
10579
2.01k
      } else {
10580
2.01k
          if ((version[0] == '1') && ((version[1] == '.'))) {
10581
1.90k
        xmlWarningMsg(ctxt, XML_WAR_UNKNOWN_VERSION,
10582
1.90k
                      "Unsupported version '%s'\n",
10583
1.90k
          version, NULL);
10584
1.90k
    } else {
10585
105
        xmlFatalErrMsgStr(ctxt, XML_ERR_UNKNOWN_VERSION,
10586
105
              "Unsupported version '%s'\n",
10587
105
              version);
10588
105
    }
10589
2.01k
      }
10590
2.01k
  }
10591
2.55k
  if (ctxt->version != NULL)
10592
0
      xmlFree((void *) ctxt->version);
10593
2.55k
  ctxt->version = version;
10594
2.55k
    }
10595
10596
    /*
10597
     * We may have the encoding declaration
10598
     */
10599
4.65k
    if (!IS_BLANK_CH(RAW)) {
10600
2.13k
        if ((RAW == '?') && (NXT(1) == '>')) {
10601
19
      SKIP(2);
10602
19
      return;
10603
19
  }
10604
2.11k
  xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
10605
2.11k
    }
10606
4.63k
    xmlParseEncodingDecl(ctxt);
10607
4.63k
    if ((ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) ||
10608
4.63k
         (ctxt->instate == XML_PARSER_EOF)) {
10609
  /*
10610
   * The XML REC instructs us to stop parsing right here
10611
   */
10612
413
        return;
10613
413
    }
10614
10615
    /*
10616
     * We may have the standalone status.
10617
     */
10618
4.21k
    if ((ctxt->input->encoding != NULL) && (!IS_BLANK_CH(RAW))) {
10619
3.48k
        if ((RAW == '?') && (NXT(1) == '>')) {
10620
2.31k
      SKIP(2);
10621
2.31k
      return;
10622
2.31k
  }
10623
1.16k
  xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
10624
1.16k
    }
10625
10626
    /*
10627
     * We can grow the input buffer freely at that point
10628
     */
10629
1.90k
    GROW;
10630
10631
1.90k
    SKIP_BLANKS;
10632
1.90k
    ctxt->input->standalone = xmlParseSDDecl(ctxt);
10633
10634
1.90k
    SKIP_BLANKS;
10635
1.90k
    if ((RAW == '?') && (NXT(1) == '>')) {
10636
163
        SKIP(2);
10637
1.73k
    } else if (RAW == '>') {
10638
        /* Deprecated old WD ... */
10639
637
  xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
10640
637
  NEXT;
10641
1.10k
    } else {
10642
1.10k
  xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
10643
1.10k
  MOVETO_ENDTAG(CUR_PTR);
10644
1.10k
  NEXT;
10645
1.10k
    }
10646
1.90k
}
10647
10648
/**
10649
 * xmlParseMisc:
10650
 * @ctxt:  an XML parser context
10651
 *
10652
 * parse an XML Misc* optional field.
10653
 *
10654
 * [27] Misc ::= Comment | PI |  S
10655
 */
10656
10657
void
10658
37.3k
xmlParseMisc(xmlParserCtxtPtr ctxt) {
10659
45.6k
    while (ctxt->instate != XML_PARSER_EOF) {
10660
45.6k
        SKIP_BLANKS;
10661
45.6k
        GROW;
10662
45.6k
        if ((RAW == '<') && (NXT(1) == '?')) {
10663
7.06k
      xmlParsePI(ctxt);
10664
38.5k
        } else if (CMP4(CUR_PTR, '<', '!', '-', '-')) {
10665
1.16k
      xmlParseComment(ctxt);
10666
37.3k
        } else {
10667
37.3k
            break;
10668
37.3k
        }
10669
45.6k
    }
10670
37.3k
}
10671
10672
/**
10673
 * xmlParseDocument:
10674
 * @ctxt:  an XML parser context
10675
 *
10676
 * parse an XML document (and build a tree if using the standard SAX
10677
 * interface).
10678
 *
10679
 * [1] document ::= prolog element Misc*
10680
 *
10681
 * [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
10682
 *
10683
 * Returns 0, -1 in case of error. the parser context is augmented
10684
 *                as a result of the parsing.
10685
 */
10686
10687
int
10688
18.9k
xmlParseDocument(xmlParserCtxtPtr ctxt) {
10689
18.9k
    xmlChar start[4];
10690
18.9k
    xmlCharEncoding enc;
10691
10692
18.9k
    xmlInitParser();
10693
10694
18.9k
    if ((ctxt == NULL) || (ctxt->input == NULL))
10695
0
        return(-1);
10696
10697
18.9k
    GROW;
10698
10699
    /*
10700
     * SAX: detecting the level.
10701
     */
10702
18.9k
    xmlDetectSAX2(ctxt);
10703
10704
    /*
10705
     * SAX: beginning of the document processing.
10706
     */
10707
18.9k
    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
10708
18.9k
        ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
10709
18.9k
    if (ctxt->instate == XML_PARSER_EOF)
10710
0
  return(-1);
10711
10712
18.9k
    if ((ctxt->encoding == NULL) &&
10713
18.9k
        ((ctxt->input->end - ctxt->input->cur) >= 4)) {
10714
  /*
10715
   * Get the 4 first bytes and decode the charset
10716
   * if enc != XML_CHAR_ENCODING_NONE
10717
   * plug some encoding conversion routines.
10718
   */
10719
18.6k
  start[0] = RAW;
10720
18.6k
  start[1] = NXT(1);
10721
18.6k
  start[2] = NXT(2);
10722
18.6k
  start[3] = NXT(3);
10723
18.6k
  enc = xmlDetectCharEncoding(&start[0], 4);
10724
18.6k
  if (enc != XML_CHAR_ENCODING_NONE) {
10725
5.39k
      xmlSwitchEncoding(ctxt, enc);
10726
5.39k
  }
10727
18.6k
    }
10728
10729
10730
18.9k
    if (CUR == 0) {
10731
60
  xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
10732
60
  return(-1);
10733
60
    }
10734
10735
    /*
10736
     * Check for the XMLDecl in the Prolog.
10737
     * do not GROW here to avoid the detected encoder to decode more
10738
     * than just the first line, unless the amount of data is really
10739
     * too small to hold "<?xml version="1.0" encoding="foo"
10740
     */
10741
18.9k
    if ((ctxt->input->end - ctxt->input->cur) < 35) {
10742
6.93k
       GROW;
10743
6.93k
    }
10744
18.9k
    if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
10745
10746
  /*
10747
   * Note that we will switch encoding on the fly.
10748
   */
10749
4.65k
  xmlParseXMLDecl(ctxt);
10750
4.65k
  if ((ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) ||
10751
4.65k
      (ctxt->instate == XML_PARSER_EOF)) {
10752
      /*
10753
       * The XML REC instructs us to stop parsing right here
10754
       */
10755
413
      return(-1);
10756
413
  }
10757
4.23k
  ctxt->standalone = ctxt->input->standalone;
10758
4.23k
  SKIP_BLANKS;
10759
14.2k
    } else {
10760
14.2k
  ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
10761
14.2k
    }
10762
18.5k
    if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
10763
16.6k
        ctxt->sax->startDocument(ctxt->userData);
10764
18.5k
    if (ctxt->instate == XML_PARSER_EOF)
10765
0
  return(-1);
10766
18.5k
    if ((ctxt->myDoc != NULL) && (ctxt->input != NULL) &&
10767
18.5k
        (ctxt->input->buf != NULL) && (ctxt->input->buf->compressed >= 0)) {
10768
0
  ctxt->myDoc->compression = ctxt->input->buf->compressed;
10769
0
    }
10770
10771
    /*
10772
     * The Misc part of the Prolog
10773
     */
10774
18.5k
    xmlParseMisc(ctxt);
10775
10776
    /*
10777
     * Then possibly doc type declaration(s) and more Misc
10778
     * (doctypedecl Misc*)?
10779
     */
10780
18.5k
    GROW;
10781
18.5k
    if (CMP9(CUR_PTR, '<', '!', 'D', 'O', 'C', 'T', 'Y', 'P', 'E')) {
10782
10783
9.57k
  ctxt->inSubset = 1;
10784
9.57k
  xmlParseDocTypeDecl(ctxt);
10785
9.57k
  if (RAW == '[') {
10786
9.13k
      ctxt->instate = XML_PARSER_DTD;
10787
9.13k
      xmlParseInternalSubset(ctxt);
10788
9.13k
      if (ctxt->instate == XML_PARSER_EOF)
10789
984
    return(-1);
10790
9.13k
  }
10791
10792
  /*
10793
   * Create and update the external subset.
10794
   */
10795
8.59k
  ctxt->inSubset = 2;
10796
8.59k
  if ((ctxt->sax != NULL) && (ctxt->sax->externalSubset != NULL) &&
10797
8.59k
      (!ctxt->disableSAX))
10798
1.94k
      ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
10799
1.94k
                                ctxt->extSubSystem, ctxt->extSubURI);
10800
8.59k
  if (ctxt->instate == XML_PARSER_EOF)
10801
0
      return(-1);
10802
8.59k
  ctxt->inSubset = 0;
10803
10804
8.59k
        xmlCleanSpecialAttr(ctxt);
10805
10806
8.59k
  ctxt->instate = XML_PARSER_PROLOG;
10807
8.59k
  xmlParseMisc(ctxt);
10808
8.59k
    }
10809
10810
    /*
10811
     * Time to start parsing the tree itself
10812
     */
10813
17.5k
    GROW;
10814
17.5k
    if (RAW != '<') {
10815
7.26k
  xmlFatalErrMsg(ctxt, XML_ERR_DOCUMENT_EMPTY,
10816
7.26k
           "Start tag expected, '<' not found\n");
10817
10.2k
    } else {
10818
10.2k
  ctxt->instate = XML_PARSER_CONTENT;
10819
10.2k
  xmlParseElement(ctxt);
10820
10.2k
  ctxt->instate = XML_PARSER_EPILOG;
10821
10822
10823
  /*
10824
   * The Misc part at the end
10825
   */
10826
10.2k
  xmlParseMisc(ctxt);
10827
10828
10.2k
  if (RAW != 0) {
10829
1.27k
      xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
10830
1.27k
  }
10831
10.2k
  ctxt->instate = XML_PARSER_EOF;
10832
10.2k
    }
10833
10834
    /*
10835
     * SAX: end of the document processing.
10836
     */
10837
17.5k
    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
10838
17.5k
        ctxt->sax->endDocument(ctxt->userData);
10839
10840
    /*
10841
     * Remove locally kept entity definitions if the tree was not built
10842
     */
10843
17.5k
    if ((ctxt->myDoc != NULL) &&
10844
17.5k
  (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) {
10845
177
  xmlFreeDoc(ctxt->myDoc);
10846
177
  ctxt->myDoc = NULL;
10847
177
    }
10848
10849
17.5k
    if ((ctxt->wellFormed) && (ctxt->myDoc != NULL)) {
10850
9
        ctxt->myDoc->properties |= XML_DOC_WELLFORMED;
10851
9
  if (ctxt->valid)
10852
8
      ctxt->myDoc->properties |= XML_DOC_DTDVALID;
10853
9
  if (ctxt->nsWellFormed)
10854
7
      ctxt->myDoc->properties |= XML_DOC_NSVALID;
10855
9
  if (ctxt->options & XML_PARSE_OLD10)
10856
0
      ctxt->myDoc->properties |= XML_DOC_OLD10;
10857
9
    }
10858
17.5k
    if (! ctxt->wellFormed) {
10859
17.5k
  ctxt->valid = 0;
10860
17.5k
  return(-1);
10861
17.5k
    }
10862
9
    return(0);
10863
17.5k
}
10864
10865
/**
10866
 * xmlParseExtParsedEnt:
10867
 * @ctxt:  an XML parser context
10868
 *
10869
 * parse a general parsed entity
10870
 * An external general parsed entity is well-formed if it matches the
10871
 * production labeled extParsedEnt.
10872
 *
10873
 * [78] extParsedEnt ::= TextDecl? content
10874
 *
10875
 * Returns 0, -1 in case of error. the parser context is augmented
10876
 *                as a result of the parsing.
10877
 */
10878
10879
int
10880
0
xmlParseExtParsedEnt(xmlParserCtxtPtr ctxt) {
10881
0
    xmlChar start[4];
10882
0
    xmlCharEncoding enc;
10883
10884
0
    if ((ctxt == NULL) || (ctxt->input == NULL))
10885
0
        return(-1);
10886
10887
0
    xmlDetectSAX2(ctxt);
10888
10889
0
    GROW;
10890
10891
    /*
10892
     * SAX: beginning of the document processing.
10893
     */
10894
0
    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
10895
0
        ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
10896
10897
    /*
10898
     * Get the 4 first bytes and decode the charset
10899
     * if enc != XML_CHAR_ENCODING_NONE
10900
     * plug some encoding conversion routines.
10901
     */
10902
0
    if ((ctxt->input->end - ctxt->input->cur) >= 4) {
10903
0
  start[0] = RAW;
10904
0
  start[1] = NXT(1);
10905
0
  start[2] = NXT(2);
10906
0
  start[3] = NXT(3);
10907
0
  enc = xmlDetectCharEncoding(start, 4);
10908
0
  if (enc != XML_CHAR_ENCODING_NONE) {
10909
0
      xmlSwitchEncoding(ctxt, enc);
10910
0
  }
10911
0
    }
10912
10913
10914
0
    if (CUR == 0) {
10915
0
  xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
10916
0
    }
10917
10918
    /*
10919
     * Check for the XMLDecl in the Prolog.
10920
     */
10921
0
    GROW;
10922
0
    if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
10923
10924
  /*
10925
   * Note that we will switch encoding on the fly.
10926
   */
10927
0
  xmlParseXMLDecl(ctxt);
10928
0
  if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
10929
      /*
10930
       * The XML REC instructs us to stop parsing right here
10931
       */
10932
0
      return(-1);
10933
0
  }
10934
0
  SKIP_BLANKS;
10935
0
    } else {
10936
0
  ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
10937
0
    }
10938
0
    if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
10939
0
        ctxt->sax->startDocument(ctxt->userData);
10940
0
    if (ctxt->instate == XML_PARSER_EOF)
10941
0
  return(-1);
10942
10943
    /*
10944
     * Doing validity checking on chunk doesn't make sense
10945
     */
10946
0
    ctxt->instate = XML_PARSER_CONTENT;
10947
0
    ctxt->validate = 0;
10948
0
    ctxt->loadsubset = 0;
10949
0
    ctxt->depth = 0;
10950
10951
0
    xmlParseContent(ctxt);
10952
0
    if (ctxt->instate == XML_PARSER_EOF)
10953
0
  return(-1);
10954
10955
0
    if ((RAW == '<') && (NXT(1) == '/')) {
10956
0
  xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
10957
0
    } else if (RAW != 0) {
10958
0
  xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
10959
0
    }
10960
10961
    /*
10962
     * SAX: end of the document processing.
10963
     */
10964
0
    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
10965
0
        ctxt->sax->endDocument(ctxt->userData);
10966
10967
0
    if (! ctxt->wellFormed) return(-1);
10968
0
    return(0);
10969
0
}
10970
10971
#ifdef LIBXML_PUSH_ENABLED
10972
/************************************************************************
10973
 *                  *
10974
 *    Progressive parsing interfaces        *
10975
 *                  *
10976
 ************************************************************************/
10977
10978
/**
10979
 * xmlParseLookupSequence:
10980
 * @ctxt:  an XML parser context
10981
 * @first:  the first char to lookup
10982
 * @next:  the next char to lookup or zero
10983
 * @third:  the next char to lookup or zero
10984
 *
10985
 * Try to find if a sequence (first, next, third) or  just (first next) or
10986
 * (first) is available in the input stream.
10987
 * This function has a side effect of (possibly) incrementing ctxt->checkIndex
10988
 * to avoid rescanning sequences of bytes, it DOES change the state of the
10989
 * parser, do not use liberally.
10990
 *
10991
 * Returns the index to the current parsing point if the full sequence
10992
 *      is available, -1 otherwise.
10993
 */
10994
static int
10995
xmlParseLookupSequence(xmlParserCtxtPtr ctxt, xmlChar first,
10996
0
                       xmlChar next, xmlChar third) {
10997
0
    int base, len;
10998
0
    xmlParserInputPtr in;
10999
0
    const xmlChar *buf;
11000
11001
0
    in = ctxt->input;
11002
0
    if (in == NULL) return(-1);
11003
0
    base = in->cur - in->base;
11004
0
    if (base < 0) return(-1);
11005
0
    if (ctxt->checkIndex > base)
11006
0
        base = ctxt->checkIndex;
11007
0
    if (in->buf == NULL) {
11008
0
  buf = in->base;
11009
0
  len = in->length;
11010
0
    } else {
11011
0
  buf = xmlBufContent(in->buf->buffer);
11012
0
  len = xmlBufUse(in->buf->buffer);
11013
0
    }
11014
    /* take into account the sequence length */
11015
0
    if (third) len -= 2;
11016
0
    else if (next) len --;
11017
0
    for (;base < len;base++) {
11018
0
        if (buf[base] == first) {
11019
0
      if (third != 0) {
11020
0
    if ((buf[base + 1] != next) ||
11021
0
        (buf[base + 2] != third)) continue;
11022
0
      } else if (next != 0) {
11023
0
    if (buf[base + 1] != next) continue;
11024
0
      }
11025
0
      ctxt->checkIndex = 0;
11026
#ifdef DEBUG_PUSH
11027
      if (next == 0)
11028
    xmlGenericError(xmlGenericErrorContext,
11029
      "PP: lookup '%c' found at %d\n",
11030
      first, base);
11031
      else if (third == 0)
11032
    xmlGenericError(xmlGenericErrorContext,
11033
      "PP: lookup '%c%c' found at %d\n",
11034
      first, next, base);
11035
      else
11036
    xmlGenericError(xmlGenericErrorContext,
11037
      "PP: lookup '%c%c%c' found at %d\n",
11038
      first, next, third, base);
11039
#endif
11040
0
      return(base - (in->cur - in->base));
11041
0
  }
11042
0
    }
11043
0
    ctxt->checkIndex = base;
11044
#ifdef DEBUG_PUSH
11045
    if (next == 0)
11046
  xmlGenericError(xmlGenericErrorContext,
11047
    "PP: lookup '%c' failed\n", first);
11048
    else if (third == 0)
11049
  xmlGenericError(xmlGenericErrorContext,
11050
    "PP: lookup '%c%c' failed\n", first, next);
11051
    else
11052
  xmlGenericError(xmlGenericErrorContext,
11053
    "PP: lookup '%c%c%c' failed\n", first, next, third);
11054
#endif
11055
0
    return(-1);
11056
0
}
11057
11058
/**
11059
 * xmlParseGetLasts:
11060
 * @ctxt:  an XML parser context
11061
 * @lastlt:  pointer to store the last '<' from the input
11062
 * @lastgt:  pointer to store the last '>' from the input
11063
 *
11064
 * Lookup the last < and > in the current chunk
11065
 */
11066
static void
11067
xmlParseGetLasts(xmlParserCtxtPtr ctxt, const xmlChar **lastlt,
11068
0
                 const xmlChar **lastgt) {
11069
0
    const xmlChar *tmp;
11070
11071
0
    if ((ctxt == NULL) || (lastlt == NULL) || (lastgt == NULL)) {
11072
0
  xmlGenericError(xmlGenericErrorContext,
11073
0
        "Internal error: xmlParseGetLasts\n");
11074
0
  return;
11075
0
    }
11076
0
    if ((ctxt->progressive != 0) && (ctxt->inputNr == 1)) {
11077
0
        tmp = ctxt->input->end;
11078
0
  tmp--;
11079
0
  while ((tmp >= ctxt->input->base) && (*tmp != '<')) tmp--;
11080
0
  if (tmp < ctxt->input->base) {
11081
0
      *lastlt = NULL;
11082
0
      *lastgt = NULL;
11083
0
  } else {
11084
0
      *lastlt = tmp;
11085
0
      tmp++;
11086
0
      while ((tmp < ctxt->input->end) && (*tmp != '>')) {
11087
0
          if (*tmp == '\'') {
11088
0
        tmp++;
11089
0
        while ((tmp < ctxt->input->end) && (*tmp != '\'')) tmp++;
11090
0
        if (tmp < ctxt->input->end) tmp++;
11091
0
    } else if (*tmp == '"') {
11092
0
        tmp++;
11093
0
        while ((tmp < ctxt->input->end) && (*tmp != '"')) tmp++;
11094
0
        if (tmp < ctxt->input->end) tmp++;
11095
0
    } else
11096
0
        tmp++;
11097
0
      }
11098
0
      if (tmp < ctxt->input->end)
11099
0
          *lastgt = tmp;
11100
0
      else {
11101
0
          tmp = *lastlt;
11102
0
    tmp--;
11103
0
    while ((tmp >= ctxt->input->base) && (*tmp != '>')) tmp--;
11104
0
    if (tmp >= ctxt->input->base)
11105
0
        *lastgt = tmp;
11106
0
    else
11107
0
        *lastgt = NULL;
11108
0
      }
11109
0
  }
11110
0
    } else {
11111
0
        *lastlt = NULL;
11112
0
  *lastgt = NULL;
11113
0
    }
11114
0
}
11115
/**
11116
 * xmlCheckCdataPush:
11117
 * @cur: pointer to the block of characters
11118
 * @len: length of the block in bytes
11119
 * @complete: 1 if complete CDATA block is passed in, 0 if partial block
11120
 *
11121
 * Check that the block of characters is okay as SCdata content [20]
11122
 *
11123
 * Returns the number of bytes to pass if okay, a negative index where an
11124
 *         UTF-8 error occurred otherwise
11125
 */
11126
static int
11127
0
xmlCheckCdataPush(const xmlChar *utf, int len, int complete) {
11128
0
    int ix;
11129
0
    unsigned char c;
11130
0
    int codepoint;
11131
11132
0
    if ((utf == NULL) || (len <= 0))
11133
0
        return(0);
11134
11135
0
    for (ix = 0; ix < len;) {      /* string is 0-terminated */
11136
0
        c = utf[ix];
11137
0
        if ((c & 0x80) == 0x00) { /* 1-byte code, starts with 10 */
11138
0
      if (c >= 0x20)
11139
0
    ix++;
11140
0
      else if ((c == 0xA) || (c == 0xD) || (c == 0x9))
11141
0
          ix++;
11142
0
      else
11143
0
          return(-ix);
11144
0
  } else if ((c & 0xe0) == 0xc0) {/* 2-byte code, starts with 110 */
11145
0
      if (ix + 2 > len) return(complete ? -ix : ix);
11146
0
      if ((utf[ix+1] & 0xc0 ) != 0x80)
11147
0
          return(-ix);
11148
0
      codepoint = (utf[ix] & 0x1f) << 6;
11149
0
      codepoint |= utf[ix+1] & 0x3f;
11150
0
      if (!xmlIsCharQ(codepoint))
11151
0
          return(-ix);
11152
0
      ix += 2;
11153
0
  } else if ((c & 0xf0) == 0xe0) {/* 3-byte code, starts with 1110 */
11154
0
      if (ix + 3 > len) return(complete ? -ix : ix);
11155
0
      if (((utf[ix+1] & 0xc0) != 0x80) ||
11156
0
          ((utf[ix+2] & 0xc0) != 0x80))
11157
0
        return(-ix);
11158
0
      codepoint = (utf[ix] & 0xf) << 12;
11159
0
      codepoint |= (utf[ix+1] & 0x3f) << 6;
11160
0
      codepoint |= utf[ix+2] & 0x3f;
11161
0
      if (!xmlIsCharQ(codepoint))
11162
0
          return(-ix);
11163
0
      ix += 3;
11164
0
  } else if ((c & 0xf8) == 0xf0) {/* 4-byte code, starts with 11110 */
11165
0
      if (ix + 4 > len) return(complete ? -ix : ix);
11166
0
      if (((utf[ix+1] & 0xc0) != 0x80) ||
11167
0
          ((utf[ix+2] & 0xc0) != 0x80) ||
11168
0
    ((utf[ix+3] & 0xc0) != 0x80))
11169
0
        return(-ix);
11170
0
      codepoint = (utf[ix] & 0x7) << 18;
11171
0
      codepoint |= (utf[ix+1] & 0x3f) << 12;
11172
0
      codepoint |= (utf[ix+2] & 0x3f) << 6;
11173
0
      codepoint |= utf[ix+3] & 0x3f;
11174
0
      if (!xmlIsCharQ(codepoint))
11175
0
          return(-ix);
11176
0
      ix += 4;
11177
0
  } else       /* unknown encoding */
11178
0
      return(-ix);
11179
0
      }
11180
0
      return(ix);
11181
0
}
11182
11183
/**
11184
 * xmlParseTryOrFinish:
11185
 * @ctxt:  an XML parser context
11186
 * @terminate:  last chunk indicator
11187
 *
11188
 * Try to progress on parsing
11189
 *
11190
 * Returns zero if no parsing was possible
11191
 */
11192
static int
11193
0
xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
11194
0
    int ret = 0;
11195
0
    int avail, tlen;
11196
0
    xmlChar cur, next;
11197
0
    const xmlChar *lastlt, *lastgt;
11198
11199
0
    if (ctxt->input == NULL)
11200
0
        return(0);
11201
11202
#ifdef DEBUG_PUSH
11203
    switch (ctxt->instate) {
11204
  case XML_PARSER_EOF:
11205
      xmlGenericError(xmlGenericErrorContext,
11206
        "PP: try EOF\n"); break;
11207
  case XML_PARSER_START:
11208
      xmlGenericError(xmlGenericErrorContext,
11209
        "PP: try START\n"); break;
11210
  case XML_PARSER_MISC:
11211
      xmlGenericError(xmlGenericErrorContext,
11212
        "PP: try MISC\n");break;
11213
  case XML_PARSER_COMMENT:
11214
      xmlGenericError(xmlGenericErrorContext,
11215
        "PP: try COMMENT\n");break;
11216
  case XML_PARSER_PROLOG:
11217
      xmlGenericError(xmlGenericErrorContext,
11218
        "PP: try PROLOG\n");break;
11219
  case XML_PARSER_START_TAG:
11220
      xmlGenericError(xmlGenericErrorContext,
11221
        "PP: try START_TAG\n");break;
11222
  case XML_PARSER_CONTENT:
11223
      xmlGenericError(xmlGenericErrorContext,
11224
        "PP: try CONTENT\n");break;
11225
  case XML_PARSER_CDATA_SECTION:
11226
      xmlGenericError(xmlGenericErrorContext,
11227
        "PP: try CDATA_SECTION\n");break;
11228
  case XML_PARSER_END_TAG:
11229
      xmlGenericError(xmlGenericErrorContext,
11230
        "PP: try END_TAG\n");break;
11231
  case XML_PARSER_ENTITY_DECL:
11232
      xmlGenericError(xmlGenericErrorContext,
11233
        "PP: try ENTITY_DECL\n");break;
11234
  case XML_PARSER_ENTITY_VALUE:
11235
      xmlGenericError(xmlGenericErrorContext,
11236
        "PP: try ENTITY_VALUE\n");break;
11237
  case XML_PARSER_ATTRIBUTE_VALUE:
11238
      xmlGenericError(xmlGenericErrorContext,
11239
        "PP: try ATTRIBUTE_VALUE\n");break;
11240
  case XML_PARSER_DTD:
11241
      xmlGenericError(xmlGenericErrorContext,
11242
        "PP: try DTD\n");break;
11243
  case XML_PARSER_EPILOG:
11244
      xmlGenericError(xmlGenericErrorContext,
11245
        "PP: try EPILOG\n");break;
11246
  case XML_PARSER_PI:
11247
      xmlGenericError(xmlGenericErrorContext,
11248
        "PP: try PI\n");break;
11249
        case XML_PARSER_IGNORE:
11250
            xmlGenericError(xmlGenericErrorContext,
11251
        "PP: try IGNORE\n");break;
11252
    }
11253
#endif
11254
11255
0
    if ((ctxt->input != NULL) &&
11256
0
        (ctxt->input->cur - ctxt->input->base > 4096)) {
11257
0
  xmlSHRINK(ctxt);
11258
0
  ctxt->checkIndex = 0;
11259
0
    }
11260
0
    xmlParseGetLasts(ctxt, &lastlt, &lastgt);
11261
11262
0
    while (ctxt->instate != XML_PARSER_EOF) {
11263
0
  if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
11264
0
      return(0);
11265
11266
0
  if (ctxt->input == NULL) break;
11267
0
  if (ctxt->input->buf == NULL)
11268
0
      avail = ctxt->input->length -
11269
0
              (ctxt->input->cur - ctxt->input->base);
11270
0
  else {
11271
      /*
11272
       * If we are operating on converted input, try to flush
11273
       * remaining chars to avoid them stalling in the non-converted
11274
       * buffer. But do not do this in document start where
11275
       * encoding="..." may not have been read and we work on a
11276
       * guessed encoding.
11277
       */
11278
0
      if ((ctxt->instate != XML_PARSER_START) &&
11279
0
          (ctxt->input->buf->raw != NULL) &&
11280
0
    (xmlBufIsEmpty(ctxt->input->buf->raw) == 0)) {
11281
0
                size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer,
11282
0
                                                 ctxt->input);
11283
0
    size_t current = ctxt->input->cur - ctxt->input->base;
11284
11285
0
    xmlParserInputBufferPush(ctxt->input->buf, 0, "");
11286
0
                xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input,
11287
0
                                      base, current);
11288
0
      }
11289
0
      avail = xmlBufUse(ctxt->input->buf->buffer) -
11290
0
        (ctxt->input->cur - ctxt->input->base);
11291
0
  }
11292
0
        if (avail < 1)
11293
0
      goto done;
11294
0
        switch (ctxt->instate) {
11295
0
            case XML_PARSER_EOF:
11296
          /*
11297
     * Document parsing is done !
11298
     */
11299
0
          goto done;
11300
0
            case XML_PARSER_START:
11301
0
    if (ctxt->charset == XML_CHAR_ENCODING_NONE) {
11302
0
        xmlChar start[4];
11303
0
        xmlCharEncoding enc;
11304
11305
        /*
11306
         * Very first chars read from the document flow.
11307
         */
11308
0
        if (avail < 4)
11309
0
      goto done;
11310
11311
        /*
11312
         * Get the 4 first bytes and decode the charset
11313
         * if enc != XML_CHAR_ENCODING_NONE
11314
         * plug some encoding conversion routines,
11315
         * else xmlSwitchEncoding will set to (default)
11316
         * UTF8.
11317
         */
11318
0
        start[0] = RAW;
11319
0
        start[1] = NXT(1);
11320
0
        start[2] = NXT(2);
11321
0
        start[3] = NXT(3);
11322
0
        enc = xmlDetectCharEncoding(start, 4);
11323
0
        xmlSwitchEncoding(ctxt, enc);
11324
0
        break;
11325
0
    }
11326
11327
0
    if (avail < 2)
11328
0
        goto done;
11329
0
    cur = ctxt->input->cur[0];
11330
0
    next = ctxt->input->cur[1];
11331
0
    if (cur == 0) {
11332
0
        if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
11333
0
      ctxt->sax->setDocumentLocator(ctxt->userData,
11334
0
                  &xmlDefaultSAXLocator);
11335
0
        xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
11336
0
        xmlHaltParser(ctxt);
11337
#ifdef DEBUG_PUSH
11338
        xmlGenericError(xmlGenericErrorContext,
11339
          "PP: entering EOF\n");
11340
#endif
11341
0
        if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
11342
0
      ctxt->sax->endDocument(ctxt->userData);
11343
0
        goto done;
11344
0
    }
11345
0
          if ((cur == '<') && (next == '?')) {
11346
        /* PI or XML decl */
11347
0
        if (avail < 5) return(ret);
11348
0
        if ((!terminate) &&
11349
0
            (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
11350
0
      return(ret);
11351
0
        if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
11352
0
      ctxt->sax->setDocumentLocator(ctxt->userData,
11353
0
                  &xmlDefaultSAXLocator);
11354
0
        if ((ctxt->input->cur[2] == 'x') &&
11355
0
      (ctxt->input->cur[3] == 'm') &&
11356
0
      (ctxt->input->cur[4] == 'l') &&
11357
0
      (IS_BLANK_CH(ctxt->input->cur[5]))) {
11358
0
      ret += 5;
11359
#ifdef DEBUG_PUSH
11360
      xmlGenericError(xmlGenericErrorContext,
11361
        "PP: Parsing XML Decl\n");
11362
#endif
11363
0
      xmlParseXMLDecl(ctxt);
11364
0
      if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
11365
          /*
11366
           * The XML REC instructs us to stop parsing right
11367
           * here
11368
           */
11369
0
          xmlHaltParser(ctxt);
11370
0
          return(0);
11371
0
      }
11372
0
      ctxt->standalone = ctxt->input->standalone;
11373
0
      if ((ctxt->encoding == NULL) &&
11374
0
          (ctxt->input->encoding != NULL))
11375
0
          ctxt->encoding = xmlStrdup(ctxt->input->encoding);
11376
0
      if ((ctxt->sax) && (ctxt->sax->startDocument) &&
11377
0
          (!ctxt->disableSAX))
11378
0
          ctxt->sax->startDocument(ctxt->userData);
11379
0
      ctxt->instate = XML_PARSER_MISC;
11380
#ifdef DEBUG_PUSH
11381
      xmlGenericError(xmlGenericErrorContext,
11382
        "PP: entering MISC\n");
11383
#endif
11384
0
        } else {
11385
0
      ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
11386
0
      if ((ctxt->sax) && (ctxt->sax->startDocument) &&
11387
0
          (!ctxt->disableSAX))
11388
0
          ctxt->sax->startDocument(ctxt->userData);
11389
0
      ctxt->instate = XML_PARSER_MISC;
11390
#ifdef DEBUG_PUSH
11391
      xmlGenericError(xmlGenericErrorContext,
11392
        "PP: entering MISC\n");
11393
#endif
11394
0
        }
11395
0
    } else {
11396
0
        if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
11397
0
      ctxt->sax->setDocumentLocator(ctxt->userData,
11398
0
                  &xmlDefaultSAXLocator);
11399
0
        ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
11400
0
        if (ctxt->version == NULL) {
11401
0
            xmlErrMemory(ctxt, NULL);
11402
0
      break;
11403
0
        }
11404
0
        if ((ctxt->sax) && (ctxt->sax->startDocument) &&
11405
0
            (!ctxt->disableSAX))
11406
0
      ctxt->sax->startDocument(ctxt->userData);
11407
0
        ctxt->instate = XML_PARSER_MISC;
11408
#ifdef DEBUG_PUSH
11409
        xmlGenericError(xmlGenericErrorContext,
11410
          "PP: entering MISC\n");
11411
#endif
11412
0
    }
11413
0
    break;
11414
0
            case XML_PARSER_START_TAG: {
11415
0
          const xmlChar *name;
11416
0
    const xmlChar *prefix = NULL;
11417
0
    const xmlChar *URI = NULL;
11418
0
                int line = ctxt->input->line;
11419
0
    int nsNr = ctxt->nsNr;
11420
11421
0
    if ((avail < 2) && (ctxt->inputNr == 1))
11422
0
        goto done;
11423
0
    cur = ctxt->input->cur[0];
11424
0
          if (cur != '<') {
11425
0
        xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
11426
0
        xmlHaltParser(ctxt);
11427
0
        if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
11428
0
      ctxt->sax->endDocument(ctxt->userData);
11429
0
        goto done;
11430
0
    }
11431
0
    if (!terminate) {
11432
0
        if (ctxt->progressive) {
11433
            /* > can be found unescaped in attribute values */
11434
0
            if ((lastgt == NULL) || (ctxt->input->cur >= lastgt))
11435
0
          goto done;
11436
0
        } else if (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0) {
11437
0
      goto done;
11438
0
        }
11439
0
    }
11440
0
    if (ctxt->spaceNr == 0)
11441
0
        spacePush(ctxt, -1);
11442
0
    else if (*ctxt->space == -2)
11443
0
        spacePush(ctxt, -1);
11444
0
    else
11445
0
        spacePush(ctxt, *ctxt->space);
11446
0
#ifdef LIBXML_SAX1_ENABLED
11447
0
    if (ctxt->sax2)
11448
0
#endif /* LIBXML_SAX1_ENABLED */
11449
0
        name = xmlParseStartTag2(ctxt, &prefix, &URI, &tlen);
11450
0
#ifdef LIBXML_SAX1_ENABLED
11451
0
    else
11452
0
        name = xmlParseStartTag(ctxt);
11453
0
#endif /* LIBXML_SAX1_ENABLED */
11454
0
    if (ctxt->instate == XML_PARSER_EOF)
11455
0
        goto done;
11456
0
    if (name == NULL) {
11457
0
        spacePop(ctxt);
11458
0
        xmlHaltParser(ctxt);
11459
0
        if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
11460
0
      ctxt->sax->endDocument(ctxt->userData);
11461
0
        goto done;
11462
0
    }
11463
0
#ifdef LIBXML_VALID_ENABLED
11464
    /*
11465
     * [ VC: Root Element Type ]
11466
     * The Name in the document type declaration must match
11467
     * the element type of the root element.
11468
     */
11469
0
    if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
11470
0
        ctxt->node && (ctxt->node == ctxt->myDoc->children))
11471
0
        ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
11472
0
#endif /* LIBXML_VALID_ENABLED */
11473
11474
    /*
11475
     * Check for an Empty Element.
11476
     */
11477
0
    if ((RAW == '/') && (NXT(1) == '>')) {
11478
0
        SKIP(2);
11479
11480
0
        if (ctxt->sax2) {
11481
0
      if ((ctxt->sax != NULL) &&
11482
0
          (ctxt->sax->endElementNs != NULL) &&
11483
0
          (!ctxt->disableSAX))
11484
0
          ctxt->sax->endElementNs(ctxt->userData, name,
11485
0
                                  prefix, URI);
11486
0
      if (ctxt->nsNr - nsNr > 0)
11487
0
          nsPop(ctxt, ctxt->nsNr - nsNr);
11488
0
#ifdef LIBXML_SAX1_ENABLED
11489
0
        } else {
11490
0
      if ((ctxt->sax != NULL) &&
11491
0
          (ctxt->sax->endElement != NULL) &&
11492
0
          (!ctxt->disableSAX))
11493
0
          ctxt->sax->endElement(ctxt->userData, name);
11494
0
#endif /* LIBXML_SAX1_ENABLED */
11495
0
        }
11496
0
        if (ctxt->instate == XML_PARSER_EOF)
11497
0
      goto done;
11498
0
        spacePop(ctxt);
11499
0
        if (ctxt->nameNr == 0) {
11500
0
      ctxt->instate = XML_PARSER_EPILOG;
11501
0
        } else {
11502
0
      ctxt->instate = XML_PARSER_CONTENT;
11503
0
        }
11504
0
                    ctxt->progressive = 1;
11505
0
        break;
11506
0
    }
11507
0
    if (RAW == '>') {
11508
0
        NEXT;
11509
0
    } else {
11510
0
        xmlFatalErrMsgStr(ctxt, XML_ERR_GT_REQUIRED,
11511
0
           "Couldn't find end of Start Tag %s\n",
11512
0
           name);
11513
0
        nodePop(ctxt);
11514
0
        spacePop(ctxt);
11515
0
    }
11516
0
                nameNsPush(ctxt, name, prefix, URI, line, ctxt->nsNr - nsNr);
11517
11518
0
    ctxt->instate = XML_PARSER_CONTENT;
11519
0
                ctxt->progressive = 1;
11520
0
                break;
11521
0
      }
11522
0
            case XML_PARSER_CONTENT: {
11523
0
    int id;
11524
0
    unsigned long cons;
11525
0
    if ((avail < 2) && (ctxt->inputNr == 1))
11526
0
        goto done;
11527
0
    cur = ctxt->input->cur[0];
11528
0
    next = ctxt->input->cur[1];
11529
11530
0
    id = ctxt->input->id;
11531
0
          cons = CUR_CONSUMED;
11532
0
    if ((cur == '<') && (next == '/')) {
11533
0
        ctxt->instate = XML_PARSER_END_TAG;
11534
0
        break;
11535
0
          } else if ((cur == '<') && (next == '?')) {
11536
0
        if ((!terminate) &&
11537
0
            (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0)) {
11538
0
                        ctxt->progressive = XML_PARSER_PI;
11539
0
      goto done;
11540
0
                    }
11541
0
        xmlParsePI(ctxt);
11542
0
        ctxt->instate = XML_PARSER_CONTENT;
11543
0
                    ctxt->progressive = 1;
11544
0
    } else if ((cur == '<') && (next != '!')) {
11545
0
        ctxt->instate = XML_PARSER_START_TAG;
11546
0
        break;
11547
0
    } else if ((cur == '<') && (next == '!') &&
11548
0
               (ctxt->input->cur[2] == '-') &&
11549
0
         (ctxt->input->cur[3] == '-')) {
11550
0
        int term;
11551
11552
0
              if (avail < 4)
11553
0
            goto done;
11554
0
        ctxt->input->cur += 4;
11555
0
        term = xmlParseLookupSequence(ctxt, '-', '-', '>');
11556
0
        ctxt->input->cur -= 4;
11557
0
        if ((!terminate) && (term < 0)) {
11558
0
                        ctxt->progressive = XML_PARSER_COMMENT;
11559
0
      goto done;
11560
0
                    }
11561
0
        xmlParseComment(ctxt);
11562
0
        ctxt->instate = XML_PARSER_CONTENT;
11563
0
                    ctxt->progressive = 1;
11564
0
    } else if ((cur == '<') && (ctxt->input->cur[1] == '!') &&
11565
0
        (ctxt->input->cur[2] == '[') &&
11566
0
        (ctxt->input->cur[3] == 'C') &&
11567
0
        (ctxt->input->cur[4] == 'D') &&
11568
0
        (ctxt->input->cur[5] == 'A') &&
11569
0
        (ctxt->input->cur[6] == 'T') &&
11570
0
        (ctxt->input->cur[7] == 'A') &&
11571
0
        (ctxt->input->cur[8] == '[')) {
11572
0
        SKIP(9);
11573
0
        ctxt->instate = XML_PARSER_CDATA_SECTION;
11574
0
        break;
11575
0
    } else if ((cur == '<') && (next == '!') &&
11576
0
               (avail < 9)) {
11577
0
        goto done;
11578
0
    } else if (cur == '&') {
11579
0
        if ((!terminate) &&
11580
0
            (xmlParseLookupSequence(ctxt, ';', 0, 0) < 0))
11581
0
      goto done;
11582
0
        xmlParseReference(ctxt);
11583
0
    } else {
11584
        /* TODO Avoid the extra copy, handle directly !!! */
11585
        /*
11586
         * Goal of the following test is:
11587
         *  - minimize calls to the SAX 'character' callback
11588
         *    when they are mergeable
11589
         *  - handle an problem for isBlank when we only parse
11590
         *    a sequence of blank chars and the next one is
11591
         *    not available to check against '<' presence.
11592
         *  - tries to homogenize the differences in SAX
11593
         *    callbacks between the push and pull versions
11594
         *    of the parser.
11595
         */
11596
0
        if ((ctxt->inputNr == 1) &&
11597
0
            (avail < XML_PARSER_BIG_BUFFER_SIZE)) {
11598
0
      if (!terminate) {
11599
0
          if (ctxt->progressive) {
11600
0
        if ((lastlt == NULL) ||
11601
0
            (ctxt->input->cur > lastlt))
11602
0
            goto done;
11603
0
          } else if (xmlParseLookupSequence(ctxt,
11604
0
                                            '<', 0, 0) < 0) {
11605
0
        goto done;
11606
0
          }
11607
0
      }
11608
0
                    }
11609
0
        ctxt->checkIndex = 0;
11610
0
        xmlParseCharData(ctxt, 0);
11611
0
    }
11612
0
    if ((cons == CUR_CONSUMED) && (id == ctxt->input->id)) {
11613
0
        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
11614
0
                    "detected an error in element content\n");
11615
0
        xmlHaltParser(ctxt);
11616
0
        break;
11617
0
    }
11618
0
    break;
11619
0
      }
11620
0
            case XML_PARSER_END_TAG:
11621
0
    if (avail < 2)
11622
0
        goto done;
11623
0
    if (!terminate) {
11624
0
        if (ctxt->progressive) {
11625
            /* > can be found unescaped in attribute values */
11626
0
            if ((lastgt == NULL) || (ctxt->input->cur >= lastgt))
11627
0
          goto done;
11628
0
        } else if (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0) {
11629
0
      goto done;
11630
0
        }
11631
0
    }
11632
0
    if (ctxt->sax2) {
11633
0
              xmlParseEndTag2(ctxt, &ctxt->pushTab[ctxt->nameNr - 1]);
11634
0
        nameNsPop(ctxt);
11635
0
    }
11636
0
#ifdef LIBXML_SAX1_ENABLED
11637
0
      else
11638
0
        xmlParseEndTag1(ctxt, 0);
11639
0
#endif /* LIBXML_SAX1_ENABLED */
11640
0
    if (ctxt->instate == XML_PARSER_EOF) {
11641
        /* Nothing */
11642
0
    } else if (ctxt->nameNr == 0) {
11643
0
        ctxt->instate = XML_PARSER_EPILOG;
11644
0
    } else {
11645
0
        ctxt->instate = XML_PARSER_CONTENT;
11646
0
    }
11647
0
    break;
11648
0
            case XML_PARSER_CDATA_SECTION: {
11649
          /*
11650
     * The Push mode need to have the SAX callback for
11651
     * cdataBlock merge back contiguous callbacks.
11652
     */
11653
0
    int base;
11654
11655
0
    base = xmlParseLookupSequence(ctxt, ']', ']', '>');
11656
0
    if (base < 0) {
11657
0
        if (avail >= XML_PARSER_BIG_BUFFER_SIZE + 2) {
11658
0
            int tmp;
11659
11660
0
      tmp = xmlCheckCdataPush(ctxt->input->cur,
11661
0
                              XML_PARSER_BIG_BUFFER_SIZE, 0);
11662
0
      if (tmp < 0) {
11663
0
          tmp = -tmp;
11664
0
          ctxt->input->cur += tmp;
11665
0
          goto encoding_error;
11666
0
      }
11667
0
      if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
11668
0
          if (ctxt->sax->cdataBlock != NULL)
11669
0
        ctxt->sax->cdataBlock(ctxt->userData,
11670
0
                              ctxt->input->cur, tmp);
11671
0
          else if (ctxt->sax->characters != NULL)
11672
0
        ctxt->sax->characters(ctxt->userData,
11673
0
                              ctxt->input->cur, tmp);
11674
0
      }
11675
0
      if (ctxt->instate == XML_PARSER_EOF)
11676
0
          goto done;
11677
0
      SKIPL(tmp);
11678
0
      ctxt->checkIndex = 0;
11679
0
        }
11680
0
        goto done;
11681
0
    } else {
11682
0
        int tmp;
11683
11684
0
        tmp = xmlCheckCdataPush(ctxt->input->cur, base, 1);
11685
0
        if ((tmp < 0) || (tmp != base)) {
11686
0
      tmp = -tmp;
11687
0
      ctxt->input->cur += tmp;
11688
0
      goto encoding_error;
11689
0
        }
11690
0
        if ((ctxt->sax != NULL) && (base == 0) &&
11691
0
            (ctxt->sax->cdataBlock != NULL) &&
11692
0
            (!ctxt->disableSAX)) {
11693
      /*
11694
       * Special case to provide identical behaviour
11695
       * between pull and push parsers on enpty CDATA
11696
       * sections
11697
       */
11698
0
       if ((ctxt->input->cur - ctxt->input->base >= 9) &&
11699
0
           (!strncmp((const char *)&ctxt->input->cur[-9],
11700
0
                     "<![CDATA[", 9)))
11701
0
           ctxt->sax->cdataBlock(ctxt->userData,
11702
0
                                 BAD_CAST "", 0);
11703
0
        } else if ((ctxt->sax != NULL) && (base > 0) &&
11704
0
      (!ctxt->disableSAX)) {
11705
0
      if (ctxt->sax->cdataBlock != NULL)
11706
0
          ctxt->sax->cdataBlock(ctxt->userData,
11707
0
              ctxt->input->cur, base);
11708
0
      else if (ctxt->sax->characters != NULL)
11709
0
          ctxt->sax->characters(ctxt->userData,
11710
0
              ctxt->input->cur, base);
11711
0
        }
11712
0
        if (ctxt->instate == XML_PARSER_EOF)
11713
0
      goto done;
11714
0
        SKIPL(base + 3);
11715
0
        ctxt->checkIndex = 0;
11716
0
        ctxt->instate = XML_PARSER_CONTENT;
11717
#ifdef DEBUG_PUSH
11718
        xmlGenericError(xmlGenericErrorContext,
11719
          "PP: entering CONTENT\n");
11720
#endif
11721
0
    }
11722
0
    break;
11723
0
      }
11724
0
            case XML_PARSER_MISC:
11725
0
    SKIP_BLANKS;
11726
0
    if (ctxt->input->buf == NULL)
11727
0
        avail = ctxt->input->length -
11728
0
                (ctxt->input->cur - ctxt->input->base);
11729
0
    else
11730
0
        avail = xmlBufUse(ctxt->input->buf->buffer) -
11731
0
                (ctxt->input->cur - ctxt->input->base);
11732
0
    if (avail < 2)
11733
0
        goto done;
11734
0
    cur = ctxt->input->cur[0];
11735
0
    next = ctxt->input->cur[1];
11736
0
          if ((cur == '<') && (next == '?')) {
11737
0
        if ((!terminate) &&
11738
0
            (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0)) {
11739
0
                        ctxt->progressive = XML_PARSER_PI;
11740
0
      goto done;
11741
0
                    }
11742
#ifdef DEBUG_PUSH
11743
        xmlGenericError(xmlGenericErrorContext,
11744
          "PP: Parsing PI\n");
11745
#endif
11746
0
        xmlParsePI(ctxt);
11747
0
        if (ctxt->instate == XML_PARSER_EOF)
11748
0
      goto done;
11749
0
        ctxt->instate = XML_PARSER_MISC;
11750
0
                    ctxt->progressive = 1;
11751
0
        ctxt->checkIndex = 0;
11752
0
    } else if ((cur == '<') && (next == '!') &&
11753
0
        (ctxt->input->cur[2] == '-') &&
11754
0
        (ctxt->input->cur[3] == '-')) {
11755
0
        if ((!terminate) &&
11756
0
            (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0)) {
11757
0
                        ctxt->progressive = XML_PARSER_COMMENT;
11758
0
      goto done;
11759
0
                    }
11760
#ifdef DEBUG_PUSH
11761
        xmlGenericError(xmlGenericErrorContext,
11762
          "PP: Parsing Comment\n");
11763
#endif
11764
0
        xmlParseComment(ctxt);
11765
0
        if (ctxt->instate == XML_PARSER_EOF)
11766
0
      goto done;
11767
0
        ctxt->instate = XML_PARSER_MISC;
11768
0
                    ctxt->progressive = 1;
11769
0
        ctxt->checkIndex = 0;
11770
0
    } else if ((cur == '<') && (next == '!') &&
11771
0
        (ctxt->input->cur[2] == 'D') &&
11772
0
        (ctxt->input->cur[3] == 'O') &&
11773
0
        (ctxt->input->cur[4] == 'C') &&
11774
0
        (ctxt->input->cur[5] == 'T') &&
11775
0
        (ctxt->input->cur[6] == 'Y') &&
11776
0
        (ctxt->input->cur[7] == 'P') &&
11777
0
        (ctxt->input->cur[8] == 'E')) {
11778
0
        if ((!terminate) &&
11779
0
            (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0)) {
11780
0
                        ctxt->progressive = XML_PARSER_DTD;
11781
0
      goto done;
11782
0
                    }
11783
#ifdef DEBUG_PUSH
11784
        xmlGenericError(xmlGenericErrorContext,
11785
          "PP: Parsing internal subset\n");
11786
#endif
11787
0
        ctxt->inSubset = 1;
11788
0
                    ctxt->progressive = 0;
11789
0
        ctxt->checkIndex = 0;
11790
0
        xmlParseDocTypeDecl(ctxt);
11791
0
        if (ctxt->instate == XML_PARSER_EOF)
11792
0
      goto done;
11793
0
        if (RAW == '[') {
11794
0
      ctxt->instate = XML_PARSER_DTD;
11795
#ifdef DEBUG_PUSH
11796
      xmlGenericError(xmlGenericErrorContext,
11797
        "PP: entering DTD\n");
11798
#endif
11799
0
        } else {
11800
      /*
11801
       * Create and update the external subset.
11802
       */
11803
0
      ctxt->inSubset = 2;
11804
0
      if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
11805
0
          (ctxt->sax->externalSubset != NULL))
11806
0
          ctxt->sax->externalSubset(ctxt->userData,
11807
0
            ctxt->intSubName, ctxt->extSubSystem,
11808
0
            ctxt->extSubURI);
11809
0
      ctxt->inSubset = 0;
11810
0
      xmlCleanSpecialAttr(ctxt);
11811
0
      ctxt->instate = XML_PARSER_PROLOG;
11812
#ifdef DEBUG_PUSH
11813
      xmlGenericError(xmlGenericErrorContext,
11814
        "PP: entering PROLOG\n");
11815
#endif
11816
0
        }
11817
0
    } else if ((cur == '<') && (next == '!') &&
11818
0
               (avail < 9)) {
11819
0
        goto done;
11820
0
    } else {
11821
0
        ctxt->instate = XML_PARSER_START_TAG;
11822
0
        ctxt->progressive = XML_PARSER_START_TAG;
11823
0
        xmlParseGetLasts(ctxt, &lastlt, &lastgt);
11824
#ifdef DEBUG_PUSH
11825
        xmlGenericError(xmlGenericErrorContext,
11826
          "PP: entering START_TAG\n");
11827
#endif
11828
0
    }
11829
0
    break;
11830
0
            case XML_PARSER_PROLOG:
11831
0
    SKIP_BLANKS;
11832
0
    if (ctxt->input->buf == NULL)
11833
0
        avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
11834
0
    else
11835
0
        avail = xmlBufUse(ctxt->input->buf->buffer) -
11836
0
                            (ctxt->input->cur - ctxt->input->base);
11837
0
    if (avail < 2)
11838
0
        goto done;
11839
0
    cur = ctxt->input->cur[0];
11840
0
    next = ctxt->input->cur[1];
11841
0
          if ((cur == '<') && (next == '?')) {
11842
0
        if ((!terminate) &&
11843
0
            (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0)) {
11844
0
                        ctxt->progressive = XML_PARSER_PI;
11845
0
      goto done;
11846
0
                    }
11847
#ifdef DEBUG_PUSH
11848
        xmlGenericError(xmlGenericErrorContext,
11849
          "PP: Parsing PI\n");
11850
#endif
11851
0
        xmlParsePI(ctxt);
11852
0
        if (ctxt->instate == XML_PARSER_EOF)
11853
0
      goto done;
11854
0
        ctxt->instate = XML_PARSER_PROLOG;
11855
0
                    ctxt->progressive = 1;
11856
0
    } else if ((cur == '<') && (next == '!') &&
11857
0
        (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
11858
0
        if ((!terminate) &&
11859
0
            (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0)) {
11860
0
                        ctxt->progressive = XML_PARSER_COMMENT;
11861
0
      goto done;
11862
0
                    }
11863
#ifdef DEBUG_PUSH
11864
        xmlGenericError(xmlGenericErrorContext,
11865
          "PP: Parsing Comment\n");
11866
#endif
11867
0
        xmlParseComment(ctxt);
11868
0
        if (ctxt->instate == XML_PARSER_EOF)
11869
0
      goto done;
11870
0
        ctxt->instate = XML_PARSER_PROLOG;
11871
0
                    ctxt->progressive = 1;
11872
0
    } else if ((cur == '<') && (next == '!') &&
11873
0
               (avail < 4)) {
11874
0
        goto done;
11875
0
    } else {
11876
0
        ctxt->instate = XML_PARSER_START_TAG;
11877
0
        if (ctxt->progressive == 0)
11878
0
      ctxt->progressive = XML_PARSER_START_TAG;
11879
0
        xmlParseGetLasts(ctxt, &lastlt, &lastgt);
11880
#ifdef DEBUG_PUSH
11881
        xmlGenericError(xmlGenericErrorContext,
11882
          "PP: entering START_TAG\n");
11883
#endif
11884
0
    }
11885
0
    break;
11886
0
            case XML_PARSER_EPILOG:
11887
0
    SKIP_BLANKS;
11888
0
    if (ctxt->input->buf == NULL)
11889
0
        avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
11890
0
    else
11891
0
        avail = xmlBufUse(ctxt->input->buf->buffer) -
11892
0
                            (ctxt->input->cur - ctxt->input->base);
11893
0
    if (avail < 2)
11894
0
        goto done;
11895
0
    cur = ctxt->input->cur[0];
11896
0
    next = ctxt->input->cur[1];
11897
0
          if ((cur == '<') && (next == '?')) {
11898
0
        if ((!terminate) &&
11899
0
            (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0)) {
11900
0
                        ctxt->progressive = XML_PARSER_PI;
11901
0
      goto done;
11902
0
                    }
11903
#ifdef DEBUG_PUSH
11904
        xmlGenericError(xmlGenericErrorContext,
11905
          "PP: Parsing PI\n");
11906
#endif
11907
0
        xmlParsePI(ctxt);
11908
0
        if (ctxt->instate == XML_PARSER_EOF)
11909
0
      goto done;
11910
0
        ctxt->instate = XML_PARSER_EPILOG;
11911
0
                    ctxt->progressive = 1;
11912
0
    } else if ((cur == '<') && (next == '!') &&
11913
0
        (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
11914
0
        if ((!terminate) &&
11915
0
            (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0)) {
11916
0
                        ctxt->progressive = XML_PARSER_COMMENT;
11917
0
      goto done;
11918
0
                    }
11919
#ifdef DEBUG_PUSH
11920
        xmlGenericError(xmlGenericErrorContext,
11921
          "PP: Parsing Comment\n");
11922
#endif
11923
0
        xmlParseComment(ctxt);
11924
0
        if (ctxt->instate == XML_PARSER_EOF)
11925
0
      goto done;
11926
0
        ctxt->instate = XML_PARSER_EPILOG;
11927
0
                    ctxt->progressive = 1;
11928
0
    } else if ((cur == '<') && (next == '!') &&
11929
0
               (avail < 4)) {
11930
0
        goto done;
11931
0
    } else {
11932
0
        xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
11933
0
        xmlHaltParser(ctxt);
11934
#ifdef DEBUG_PUSH
11935
        xmlGenericError(xmlGenericErrorContext,
11936
          "PP: entering EOF\n");
11937
#endif
11938
0
        if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
11939
0
      ctxt->sax->endDocument(ctxt->userData);
11940
0
        goto done;
11941
0
    }
11942
0
    break;
11943
0
            case XML_PARSER_DTD: {
11944
          /*
11945
     * Sorry but progressive parsing of the internal subset
11946
     * is not expected to be supported. We first check that
11947
     * the full content of the internal subset is available and
11948
     * the parsing is launched only at that point.
11949
     * Internal subset ends up with "']' S? '>'" in an unescaped
11950
     * section and not in a ']]>' sequence which are conditional
11951
     * sections (whoever argued to keep that crap in XML deserve
11952
     * a place in hell !).
11953
     */
11954
0
    int base, i;
11955
0
    xmlChar *buf;
11956
0
          xmlChar quote = 0;
11957
0
                size_t use;
11958
11959
0
    base = ctxt->input->cur - ctxt->input->base;
11960
0
    if (base < 0) return(0);
11961
0
    if (ctxt->checkIndex > base)
11962
0
        base = ctxt->checkIndex;
11963
0
    buf = xmlBufContent(ctxt->input->buf->buffer);
11964
0
                use = xmlBufUse(ctxt->input->buf->buffer);
11965
0
    for (;(unsigned int) base < use; base++) {
11966
0
        if (quote != 0) {
11967
0
            if (buf[base] == quote)
11968
0
          quote = 0;
11969
0
      continue;
11970
0
        }
11971
0
        if ((quote == 0) && (buf[base] == '<')) {
11972
0
            int found  = 0;
11973
      /* special handling of comments */
11974
0
            if (((unsigned int) base + 4 < use) &&
11975
0
          (buf[base + 1] == '!') &&
11976
0
          (buf[base + 2] == '-') &&
11977
0
          (buf[base + 3] == '-')) {
11978
0
          for (;(unsigned int) base + 3 < use; base++) {
11979
0
        if ((buf[base] == '-') &&
11980
0
            (buf[base + 1] == '-') &&
11981
0
            (buf[base + 2] == '>')) {
11982
0
            found = 1;
11983
0
            base += 2;
11984
0
            break;
11985
0
        }
11986
0
                }
11987
0
          if (!found) {
11988
#if 0
11989
              fprintf(stderr, "unfinished comment\n");
11990
#endif
11991
0
              break; /* for */
11992
0
                }
11993
0
                continue;
11994
0
      }
11995
0
        }
11996
0
        if (buf[base] == '"') {
11997
0
            quote = '"';
11998
0
      continue;
11999
0
        }
12000
0
        if (buf[base] == '\'') {
12001
0
            quote = '\'';
12002
0
      continue;
12003
0
        }
12004
0
        if (buf[base] == ']') {
12005
#if 0
12006
            fprintf(stderr, "%c%c%c%c: ", buf[base],
12007
              buf[base + 1], buf[base + 2], buf[base + 3]);
12008
#endif
12009
0
            if ((unsigned int) base +1 >= use)
12010
0
          break;
12011
0
      if (buf[base + 1] == ']') {
12012
          /* conditional crap, skip both ']' ! */
12013
0
          base++;
12014
0
          continue;
12015
0
      }
12016
0
            for (i = 1; (unsigned int) base + i < use; i++) {
12017
0
          if (buf[base + i] == '>') {
12018
#if 0
12019
              fprintf(stderr, "found\n");
12020
#endif
12021
0
              goto found_end_int_subset;
12022
0
          }
12023
0
          if (!IS_BLANK_CH(buf[base + i])) {
12024
#if 0
12025
              fprintf(stderr, "not found\n");
12026
#endif
12027
0
              goto not_end_of_int_subset;
12028
0
          }
12029
0
      }
12030
#if 0
12031
      fprintf(stderr, "end of stream\n");
12032
#endif
12033
0
            break;
12034
12035
0
        }
12036
0
not_end_of_int_subset:
12037
0
                    continue; /* for */
12038
0
    }
12039
    /*
12040
     * We didn't found the end of the Internal subset
12041
     */
12042
0
                if (quote == 0)
12043
0
                    ctxt->checkIndex = base;
12044
0
                else
12045
0
                    ctxt->checkIndex = 0;
12046
#ifdef DEBUG_PUSH
12047
    if (next == 0)
12048
        xmlGenericError(xmlGenericErrorContext,
12049
          "PP: lookup of int subset end filed\n");
12050
#endif
12051
0
          goto done;
12052
12053
0
found_end_int_subset:
12054
0
                ctxt->checkIndex = 0;
12055
0
    xmlParseInternalSubset(ctxt);
12056
0
    if (ctxt->instate == XML_PARSER_EOF)
12057
0
        goto done;
12058
0
    ctxt->inSubset = 2;
12059
0
    if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
12060
0
        (ctxt->sax->externalSubset != NULL))
12061
0
        ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
12062
0
          ctxt->extSubSystem, ctxt->extSubURI);
12063
0
    ctxt->inSubset = 0;
12064
0
    xmlCleanSpecialAttr(ctxt);
12065
0
    if (ctxt->instate == XML_PARSER_EOF)
12066
0
        goto done;
12067
0
    ctxt->instate = XML_PARSER_PROLOG;
12068
0
    ctxt->checkIndex = 0;
12069
#ifdef DEBUG_PUSH
12070
    xmlGenericError(xmlGenericErrorContext,
12071
      "PP: entering PROLOG\n");
12072
#endif
12073
0
                break;
12074
0
      }
12075
0
            case XML_PARSER_COMMENT:
12076
0
    xmlGenericError(xmlGenericErrorContext,
12077
0
      "PP: internal error, state == COMMENT\n");
12078
0
    ctxt->instate = XML_PARSER_CONTENT;
12079
#ifdef DEBUG_PUSH
12080
    xmlGenericError(xmlGenericErrorContext,
12081
      "PP: entering CONTENT\n");
12082
#endif
12083
0
    break;
12084
0
            case XML_PARSER_IGNORE:
12085
0
    xmlGenericError(xmlGenericErrorContext,
12086
0
      "PP: internal error, state == IGNORE");
12087
0
          ctxt->instate = XML_PARSER_DTD;
12088
#ifdef DEBUG_PUSH
12089
    xmlGenericError(xmlGenericErrorContext,
12090
      "PP: entering DTD\n");
12091
#endif
12092
0
          break;
12093
0
            case XML_PARSER_PI:
12094
0
    xmlGenericError(xmlGenericErrorContext,
12095
0
      "PP: internal error, state == PI\n");
12096
0
    ctxt->instate = XML_PARSER_CONTENT;
12097
#ifdef DEBUG_PUSH
12098
    xmlGenericError(xmlGenericErrorContext,
12099
      "PP: entering CONTENT\n");
12100
#endif
12101
0
    break;
12102
0
            case XML_PARSER_ENTITY_DECL:
12103
0
    xmlGenericError(xmlGenericErrorContext,
12104
0
      "PP: internal error, state == ENTITY_DECL\n");
12105
0
    ctxt->instate = XML_PARSER_DTD;
12106
#ifdef DEBUG_PUSH
12107
    xmlGenericError(xmlGenericErrorContext,
12108
      "PP: entering DTD\n");
12109
#endif
12110
0
    break;
12111
0
            case XML_PARSER_ENTITY_VALUE:
12112
0
    xmlGenericError(xmlGenericErrorContext,
12113
0
      "PP: internal error, state == ENTITY_VALUE\n");
12114
0
    ctxt->instate = XML_PARSER_CONTENT;
12115
#ifdef DEBUG_PUSH
12116
    xmlGenericError(xmlGenericErrorContext,
12117
      "PP: entering DTD\n");
12118
#endif
12119
0
    break;
12120
0
            case XML_PARSER_ATTRIBUTE_VALUE:
12121
0
    xmlGenericError(xmlGenericErrorContext,
12122
0
      "PP: internal error, state == ATTRIBUTE_VALUE\n");
12123
0
    ctxt->instate = XML_PARSER_START_TAG;
12124
#ifdef DEBUG_PUSH
12125
    xmlGenericError(xmlGenericErrorContext,
12126
      "PP: entering START_TAG\n");
12127
#endif
12128
0
    break;
12129
0
            case XML_PARSER_SYSTEM_LITERAL:
12130
0
    xmlGenericError(xmlGenericErrorContext,
12131
0
      "PP: internal error, state == SYSTEM_LITERAL\n");
12132
0
    ctxt->instate = XML_PARSER_START_TAG;
12133
#ifdef DEBUG_PUSH
12134
    xmlGenericError(xmlGenericErrorContext,
12135
      "PP: entering START_TAG\n");
12136
#endif
12137
0
    break;
12138
0
            case XML_PARSER_PUBLIC_LITERAL:
12139
0
    xmlGenericError(xmlGenericErrorContext,
12140
0
      "PP: internal error, state == PUBLIC_LITERAL\n");
12141
0
    ctxt->instate = XML_PARSER_START_TAG;
12142
#ifdef DEBUG_PUSH
12143
    xmlGenericError(xmlGenericErrorContext,
12144
      "PP: entering START_TAG\n");
12145
#endif
12146
0
    break;
12147
0
  }
12148
0
    }
12149
0
done:
12150
#ifdef DEBUG_PUSH
12151
    xmlGenericError(xmlGenericErrorContext, "PP: done %d\n", ret);
12152
#endif
12153
0
    return(ret);
12154
0
encoding_error:
12155
0
    {
12156
0
        char buffer[150];
12157
12158
0
  snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
12159
0
      ctxt->input->cur[0], ctxt->input->cur[1],
12160
0
      ctxt->input->cur[2], ctxt->input->cur[3]);
12161
0
  __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
12162
0
         "Input is not proper UTF-8, indicate encoding !\n%s",
12163
0
         BAD_CAST buffer, NULL);
12164
0
    }
12165
0
    return(0);
12166
0
}
12167
12168
/**
12169
 * xmlParseCheckTransition:
12170
 * @ctxt:  an XML parser context
12171
 * @chunk:  a char array
12172
 * @size:  the size in byte of the chunk
12173
 *
12174
 * Check depending on the current parser state if the chunk given must be
12175
 * processed immediately or one need more data to advance on parsing.
12176
 *
12177
 * Returns -1 in case of error, 0 if the push is not needed and 1 if needed
12178
 */
12179
static int
12180
0
xmlParseCheckTransition(xmlParserCtxtPtr ctxt, const char *chunk, int size) {
12181
0
    if ((ctxt == NULL) || (chunk == NULL) || (size < 0))
12182
0
        return(-1);
12183
0
    if (ctxt->instate == XML_PARSER_START_TAG) {
12184
0
        if (memchr(chunk, '>', size) != NULL)
12185
0
            return(1);
12186
0
        return(0);
12187
0
    }
12188
0
    if (ctxt->progressive == XML_PARSER_COMMENT) {
12189
0
        if (memchr(chunk, '>', size) != NULL)
12190
0
            return(1);
12191
0
        return(0);
12192
0
    }
12193
0
    if (ctxt->instate == XML_PARSER_CDATA_SECTION) {
12194
0
        if (memchr(chunk, '>', size) != NULL)
12195
0
            return(1);
12196
0
        return(0);
12197
0
    }
12198
0
    if (ctxt->progressive == XML_PARSER_PI) {
12199
0
        if (memchr(chunk, '>', size) != NULL)
12200
0
            return(1);
12201
0
        return(0);
12202
0
    }
12203
0
    if (ctxt->instate == XML_PARSER_END_TAG) {
12204
0
        if (memchr(chunk, '>', size) != NULL)
12205
0
            return(1);
12206
0
        return(0);
12207
0
    }
12208
0
    if ((ctxt->progressive == XML_PARSER_DTD) ||
12209
0
        (ctxt->instate == XML_PARSER_DTD)) {
12210
0
        if (memchr(chunk, '>', size) != NULL)
12211
0
            return(1);
12212
0
        return(0);
12213
0
    }
12214
0
    return(1);
12215
0
}
12216
12217
/**
12218
 * xmlParseChunk:
12219
 * @ctxt:  an XML parser context
12220
 * @chunk:  an char array
12221
 * @size:  the size in byte of the chunk
12222
 * @terminate:  last chunk indicator
12223
 *
12224
 * Parse a Chunk of memory
12225
 *
12226
 * Returns zero if no error, the xmlParserErrors otherwise.
12227
 */
12228
int
12229
xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
12230
0
              int terminate) {
12231
0
    int end_in_lf = 0;
12232
0
    int remain = 0;
12233
0
    size_t old_avail = 0;
12234
0
    size_t avail = 0;
12235
12236
0
    if (ctxt == NULL)
12237
0
        return(XML_ERR_INTERNAL_ERROR);
12238
0
    if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
12239
0
        return(ctxt->errNo);
12240
0
    if (ctxt->instate == XML_PARSER_EOF)
12241
0
        return(-1);
12242
0
    if (ctxt->instate == XML_PARSER_START)
12243
0
        xmlDetectSAX2(ctxt);
12244
0
    if ((size > 0) && (chunk != NULL) && (!terminate) &&
12245
0
        (chunk[size - 1] == '\r')) {
12246
0
  end_in_lf = 1;
12247
0
  size--;
12248
0
    }
12249
12250
0
xmldecl_done:
12251
12252
0
    if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
12253
0
        (ctxt->input->buf != NULL) && (ctxt->instate != XML_PARSER_EOF))  {
12254
0
  size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer, ctxt->input);
12255
0
  size_t cur = ctxt->input->cur - ctxt->input->base;
12256
0
  int res;
12257
12258
0
        old_avail = xmlBufUse(ctxt->input->buf->buffer);
12259
        /*
12260
         * Specific handling if we autodetected an encoding, we should not
12261
         * push more than the first line ... which depend on the encoding
12262
         * And only push the rest once the final encoding was detected
12263
         */
12264
0
        if ((ctxt->instate == XML_PARSER_START) && (ctxt->input != NULL) &&
12265
0
            (ctxt->input->buf != NULL) && (ctxt->input->buf->encoder != NULL)) {
12266
0
            unsigned int len = 45;
12267
12268
0
            if ((xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
12269
0
                               BAD_CAST "UTF-16")) ||
12270
0
                (xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
12271
0
                               BAD_CAST "UTF16")))
12272
0
                len = 90;
12273
0
            else if ((xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
12274
0
                                    BAD_CAST "UCS-4")) ||
12275
0
                     (xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
12276
0
                                    BAD_CAST "UCS4")))
12277
0
                len = 180;
12278
12279
0
            if (ctxt->input->buf->rawconsumed < len)
12280
0
                len -= ctxt->input->buf->rawconsumed;
12281
12282
            /*
12283
             * Change size for reading the initial declaration only
12284
             * if size is greater than len. Otherwise, memmove in xmlBufferAdd
12285
             * will blindly copy extra bytes from memory.
12286
             */
12287
0
            if ((unsigned int) size > len) {
12288
0
                remain = size - len;
12289
0
                size = len;
12290
0
            } else {
12291
0
                remain = 0;
12292
0
            }
12293
0
        }
12294
0
  res = xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
12295
0
        xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur);
12296
0
  if (res < 0) {
12297
0
      ctxt->errNo = XML_PARSER_EOF;
12298
0
      xmlHaltParser(ctxt);
12299
0
      return (XML_PARSER_EOF);
12300
0
  }
12301
#ifdef DEBUG_PUSH
12302
  xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
12303
#endif
12304
12305
0
    } else if (ctxt->instate != XML_PARSER_EOF) {
12306
0
  if ((ctxt->input != NULL) && ctxt->input->buf != NULL) {
12307
0
      xmlParserInputBufferPtr in = ctxt->input->buf;
12308
0
      if ((in->encoder != NULL) && (in->buffer != NULL) &&
12309
0
        (in->raw != NULL)) {
12310
0
    int nbchars;
12311
0
    size_t base = xmlBufGetInputBase(in->buffer, ctxt->input);
12312
0
    size_t current = ctxt->input->cur - ctxt->input->base;
12313
12314
0
    nbchars = xmlCharEncInput(in, terminate);
12315
0
    xmlBufSetInputBaseCur(in->buffer, ctxt->input, base, current);
12316
0
    if (nbchars < 0) {
12317
        /* TODO 2.6.0 */
12318
0
        xmlGenericError(xmlGenericErrorContext,
12319
0
            "xmlParseChunk: encoder error\n");
12320
0
                    xmlHaltParser(ctxt);
12321
0
        return(XML_ERR_INVALID_ENCODING);
12322
0
    }
12323
0
      }
12324
0
  }
12325
0
    }
12326
0
    if (remain != 0) {
12327
0
        xmlParseTryOrFinish(ctxt, 0);
12328
0
    } else {
12329
0
        if ((ctxt->input != NULL) && (ctxt->input->buf != NULL))
12330
0
            avail = xmlBufUse(ctxt->input->buf->buffer);
12331
        /*
12332
         * Depending on the current state it may not be such
12333
         * a good idea to try parsing if there is nothing in the chunk
12334
         * which would be worth doing a parser state transition and we
12335
         * need to wait for more data
12336
         */
12337
0
        if ((terminate) || (avail > XML_MAX_TEXT_LENGTH) ||
12338
0
            (old_avail == 0) || (avail == 0) ||
12339
0
            (xmlParseCheckTransition(ctxt,
12340
0
                       (const char *)&ctxt->input->base[old_avail],
12341
0
                                     avail - old_avail)))
12342
0
            xmlParseTryOrFinish(ctxt, terminate);
12343
0
    }
12344
0
    if (ctxt->instate == XML_PARSER_EOF)
12345
0
        return(ctxt->errNo);
12346
12347
0
    if ((ctxt->input != NULL) &&
12348
0
         (((ctxt->input->end - ctxt->input->cur) > XML_MAX_LOOKUP_LIMIT) ||
12349
0
         ((ctxt->input->cur - ctxt->input->base) > XML_MAX_LOOKUP_LIMIT)) &&
12350
0
        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
12351
0
        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "Huge input lookup");
12352
0
        xmlHaltParser(ctxt);
12353
0
    }
12354
0
    if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
12355
0
        return(ctxt->errNo);
12356
12357
0
    if (remain != 0) {
12358
0
        chunk += size;
12359
0
        size = remain;
12360
0
        remain = 0;
12361
0
        goto xmldecl_done;
12362
0
    }
12363
0
    if ((end_in_lf == 1) && (ctxt->input != NULL) &&
12364
0
        (ctxt->input->buf != NULL)) {
12365
0
  size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer,
12366
0
           ctxt->input);
12367
0
  size_t current = ctxt->input->cur - ctxt->input->base;
12368
12369
0
  xmlParserInputBufferPush(ctxt->input->buf, 1, "\r");
12370
12371
0
  xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input,
12372
0
            base, current);
12373
0
    }
12374
0
    if (terminate) {
12375
  /*
12376
   * Check for termination
12377
   */
12378
0
  int cur_avail = 0;
12379
12380
0
  if (ctxt->input != NULL) {
12381
0
      if (ctxt->input->buf == NULL)
12382
0
    cur_avail = ctxt->input->length -
12383
0
          (ctxt->input->cur - ctxt->input->base);
12384
0
      else
12385
0
    cur_avail = xmlBufUse(ctxt->input->buf->buffer) -
12386
0
                    (ctxt->input->cur - ctxt->input->base);
12387
0
  }
12388
12389
0
  if ((ctxt->instate != XML_PARSER_EOF) &&
12390
0
      (ctxt->instate != XML_PARSER_EPILOG)) {
12391
0
      xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
12392
0
  }
12393
0
  if ((ctxt->instate == XML_PARSER_EPILOG) && (cur_avail > 0)) {
12394
0
      xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
12395
0
  }
12396
0
  if (ctxt->instate != XML_PARSER_EOF) {
12397
0
      if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
12398
0
    ctxt->sax->endDocument(ctxt->userData);
12399
0
  }
12400
0
  ctxt->instate = XML_PARSER_EOF;
12401
0
    }
12402
0
    if (ctxt->wellFormed == 0)
12403
0
  return((xmlParserErrors) ctxt->errNo);
12404
0
    else
12405
0
        return(0);
12406
0
}
12407
12408
/************************************************************************
12409
 *                  *
12410
 *    I/O front end functions to the parser     *
12411
 *                  *
12412
 ************************************************************************/
12413
12414
/**
12415
 * xmlCreatePushParserCtxt:
12416
 * @sax:  a SAX handler
12417
 * @user_data:  The user data returned on SAX callbacks
12418
 * @chunk:  a pointer to an array of chars
12419
 * @size:  number of chars in the array
12420
 * @filename:  an optional file name or URI
12421
 *
12422
 * Create a parser context for using the XML parser in push mode.
12423
 * If @buffer and @size are non-NULL, the data is used to detect
12424
 * the encoding.  The remaining characters will be parsed so they
12425
 * don't need to be fed in again through xmlParseChunk.
12426
 * To allow content encoding detection, @size should be >= 4
12427
 * The value of @filename is used for fetching external entities
12428
 * and error/warning reports.
12429
 *
12430
 * Returns the new parser context or NULL
12431
 */
12432
12433
xmlParserCtxtPtr
12434
xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
12435
0
                        const char *chunk, int size, const char *filename) {
12436
0
    xmlParserCtxtPtr ctxt;
12437
0
    xmlParserInputPtr inputStream;
12438
0
    xmlParserInputBufferPtr buf;
12439
0
    xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
12440
12441
    /*
12442
     * plug some encoding conversion routines
12443
     */
12444
0
    if ((chunk != NULL) && (size >= 4))
12445
0
  enc = xmlDetectCharEncoding((const xmlChar *) chunk, size);
12446
12447
0
    buf = xmlAllocParserInputBuffer(enc);
12448
0
    if (buf == NULL) return(NULL);
12449
12450
0
    ctxt = xmlNewParserCtxt();
12451
0
    if (ctxt == NULL) {
12452
0
        xmlErrMemory(NULL, "creating parser: out of memory\n");
12453
0
  xmlFreeParserInputBuffer(buf);
12454
0
  return(NULL);
12455
0
    }
12456
0
    ctxt->dictNames = 1;
12457
0
    if (sax != NULL) {
12458
0
#ifdef LIBXML_SAX1_ENABLED
12459
0
  if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
12460
0
#endif /* LIBXML_SAX1_ENABLED */
12461
0
      xmlFree(ctxt->sax);
12462
0
  ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
12463
0
  if (ctxt->sax == NULL) {
12464
0
      xmlErrMemory(ctxt, NULL);
12465
0
      xmlFreeParserInputBuffer(buf);
12466
0
      xmlFreeParserCtxt(ctxt);
12467
0
      return(NULL);
12468
0
  }
12469
0
  memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
12470
0
  if (sax->initialized == XML_SAX2_MAGIC)
12471
0
      memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
12472
0
  else
12473
0
      memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
12474
0
  if (user_data != NULL)
12475
0
      ctxt->userData = user_data;
12476
0
    }
12477
0
    if (filename == NULL) {
12478
0
  ctxt->directory = NULL;
12479
0
    } else {
12480
0
        ctxt->directory = xmlParserGetDirectory(filename);
12481
0
    }
12482
12483
0
    inputStream = xmlNewInputStream(ctxt);
12484
0
    if (inputStream == NULL) {
12485
0
  xmlFreeParserCtxt(ctxt);
12486
0
  xmlFreeParserInputBuffer(buf);
12487
0
  return(NULL);
12488
0
    }
12489
12490
0
    if (filename == NULL)
12491
0
  inputStream->filename = NULL;
12492
0
    else {
12493
0
  inputStream->filename = (char *)
12494
0
      xmlCanonicPath((const xmlChar *) filename);
12495
0
  if (inputStream->filename == NULL) {
12496
0
      xmlFreeParserCtxt(ctxt);
12497
0
      xmlFreeParserInputBuffer(buf);
12498
0
      return(NULL);
12499
0
  }
12500
0
    }
12501
0
    inputStream->buf = buf;
12502
0
    xmlBufResetInput(inputStream->buf->buffer, inputStream);
12503
0
    inputPush(ctxt, inputStream);
12504
12505
    /*
12506
     * If the caller didn't provide an initial 'chunk' for determining
12507
     * the encoding, we set the context to XML_CHAR_ENCODING_NONE so
12508
     * that it can be automatically determined later
12509
     */
12510
0
    if ((size == 0) || (chunk == NULL)) {
12511
0
  ctxt->charset = XML_CHAR_ENCODING_NONE;
12512
0
    } else if ((ctxt->input != NULL) && (ctxt->input->buf != NULL)) {
12513
0
  size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer, ctxt->input);
12514
0
  size_t cur = ctxt->input->cur - ctxt->input->base;
12515
12516
0
  xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
12517
12518
0
        xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur);
12519
#ifdef DEBUG_PUSH
12520
  xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
12521
#endif
12522
0
    }
12523
12524
0
    if (enc != XML_CHAR_ENCODING_NONE) {
12525
0
        xmlSwitchEncoding(ctxt, enc);
12526
0
    }
12527
12528
0
    return(ctxt);
12529
0
}
12530
#endif /* LIBXML_PUSH_ENABLED */
12531
12532
/**
12533
 * xmlHaltParser:
12534
 * @ctxt:  an XML parser context
12535
 *
12536
 * Blocks further parser processing don't override error
12537
 * for internal use
12538
 */
12539
static void
12540
287k
xmlHaltParser(xmlParserCtxtPtr ctxt) {
12541
287k
    if (ctxt == NULL)
12542
0
        return;
12543
287k
    ctxt->instate = XML_PARSER_EOF;
12544
287k
    ctxt->disableSAX = 1;
12545
288k
    while (ctxt->inputNr > 1)
12546
1.14k
        xmlFreeInputStream(inputPop(ctxt));
12547
287k
    if (ctxt->input != NULL) {
12548
        /*
12549
   * in case there was a specific allocation deallocate before
12550
   * overriding base
12551
   */
12552
287k
        if (ctxt->input->free != NULL) {
12553
0
      ctxt->input->free((xmlChar *) ctxt->input->base);
12554
0
      ctxt->input->free = NULL;
12555
0
  }
12556
287k
        if (ctxt->input->buf != NULL) {
12557
234k
            xmlFreeParserInputBuffer(ctxt->input->buf);
12558
234k
            ctxt->input->buf = NULL;
12559
234k
        }
12560
287k
  ctxt->input->cur = BAD_CAST"";
12561
287k
        ctxt->input->length = 0;
12562
287k
  ctxt->input->base = ctxt->input->cur;
12563
287k
        ctxt->input->end = ctxt->input->cur;
12564
287k
    }
12565
287k
}
12566
12567
/**
12568
 * xmlStopParser:
12569
 * @ctxt:  an XML parser context
12570
 *
12571
 * Blocks further parser processing
12572
 */
12573
void
12574
16
xmlStopParser(xmlParserCtxtPtr ctxt) {
12575
16
    if (ctxt == NULL)
12576
0
        return;
12577
16
    xmlHaltParser(ctxt);
12578
16
    ctxt->errNo = XML_ERR_USER_STOP;
12579
16
}
12580
12581
/**
12582
 * xmlCreateIOParserCtxt:
12583
 * @sax:  a SAX handler
12584
 * @user_data:  The user data returned on SAX callbacks
12585
 * @ioread:  an I/O read function
12586
 * @ioclose:  an I/O close function
12587
 * @ioctx:  an I/O handler
12588
 * @enc:  the charset encoding if known
12589
 *
12590
 * Create a parser context for using the XML parser with an existing
12591
 * I/O stream
12592
 *
12593
 * Returns the new parser context or NULL
12594
 */
12595
xmlParserCtxtPtr
12596
xmlCreateIOParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
12597
  xmlInputReadCallback   ioread, xmlInputCloseCallback  ioclose,
12598
0
  void *ioctx, xmlCharEncoding enc) {
12599
0
    xmlParserCtxtPtr ctxt;
12600
0
    xmlParserInputPtr inputStream;
12601
0
    xmlParserInputBufferPtr buf;
12602
12603
0
    if (ioread == NULL) return(NULL);
12604
12605
0
    buf = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx, enc);
12606
0
    if (buf == NULL) {
12607
0
        if (ioclose != NULL)
12608
0
            ioclose(ioctx);
12609
0
        return (NULL);
12610
0
    }
12611
12612
0
    ctxt = xmlNewParserCtxt();
12613
0
    if (ctxt == NULL) {
12614
0
  xmlFreeParserInputBuffer(buf);
12615
0
  return(NULL);
12616
0
    }
12617
0
    if (sax != NULL) {
12618
0
#ifdef LIBXML_SAX1_ENABLED
12619
0
  if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
12620
0
#endif /* LIBXML_SAX1_ENABLED */
12621
0
      xmlFree(ctxt->sax);
12622
0
  ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
12623
0
  if (ctxt->sax == NULL) {
12624
0
      xmlFreeParserInputBuffer(buf);
12625
0
      xmlErrMemory(ctxt, NULL);
12626
0
      xmlFreeParserCtxt(ctxt);
12627
0
      return(NULL);
12628
0
  }
12629
0
  memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
12630
0
  if (sax->initialized == XML_SAX2_MAGIC)
12631
0
      memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
12632
0
  else
12633
0
      memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
12634
0
  if (user_data != NULL)
12635
0
      ctxt->userData = user_data;
12636
0
    }
12637
12638
0
    inputStream = xmlNewIOInputStream(ctxt, buf, enc);
12639
0
    if (inputStream == NULL) {
12640
0
  xmlFreeParserCtxt(ctxt);
12641
0
  return(NULL);
12642
0
    }
12643
0
    inputPush(ctxt, inputStream);
12644
12645
0
    return(ctxt);
12646
0
}
12647
12648
#ifdef LIBXML_VALID_ENABLED
12649
/************************************************************************
12650
 *                  *
12651
 *    Front ends when parsing a DTD       *
12652
 *                  *
12653
 ************************************************************************/
12654
12655
/**
12656
 * xmlIOParseDTD:
12657
 * @sax:  the SAX handler block or NULL
12658
 * @input:  an Input Buffer
12659
 * @enc:  the charset encoding if known
12660
 *
12661
 * Load and parse a DTD
12662
 *
12663
 * Returns the resulting xmlDtdPtr or NULL in case of error.
12664
 * @input will be freed by the function in any case.
12665
 */
12666
12667
xmlDtdPtr
12668
xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input,
12669
0
        xmlCharEncoding enc) {
12670
0
    xmlDtdPtr ret = NULL;
12671
0
    xmlParserCtxtPtr ctxt;
12672
0
    xmlParserInputPtr pinput = NULL;
12673
0
    xmlChar start[4];
12674
12675
0
    if (input == NULL)
12676
0
  return(NULL);
12677
12678
0
    ctxt = xmlNewParserCtxt();
12679
0
    if (ctxt == NULL) {
12680
0
        xmlFreeParserInputBuffer(input);
12681
0
  return(NULL);
12682
0
    }
12683
12684
    /* We are loading a DTD */
12685
0
    ctxt->options |= XML_PARSE_DTDLOAD;
12686
12687
    /*
12688
     * Set-up the SAX context
12689
     */
12690
0
    if (sax != NULL) {
12691
0
  if (ctxt->sax != NULL)
12692
0
      xmlFree(ctxt->sax);
12693
0
        ctxt->sax = sax;
12694
0
        ctxt->userData = ctxt;
12695
0
    }
12696
0
    xmlDetectSAX2(ctxt);
12697
12698
    /*
12699
     * generate a parser input from the I/O handler
12700
     */
12701
12702
0
    pinput = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
12703
0
    if (pinput == NULL) {
12704
0
        if (sax != NULL) ctxt->sax = NULL;
12705
0
        xmlFreeParserInputBuffer(input);
12706
0
  xmlFreeParserCtxt(ctxt);
12707
0
  return(NULL);
12708
0
    }
12709
12710
    /*
12711
     * plug some encoding conversion routines here.
12712
     */
12713
0
    if (xmlPushInput(ctxt, pinput) < 0) {
12714
0
        if (sax != NULL) ctxt->sax = NULL;
12715
0
  xmlFreeParserCtxt(ctxt);
12716
0
  return(NULL);
12717
0
    }
12718
0
    if (enc != XML_CHAR_ENCODING_NONE) {
12719
0
        xmlSwitchEncoding(ctxt, enc);
12720
0
    }
12721
12722
0
    pinput->filename = NULL;
12723
0
    pinput->line = 1;
12724
0
    pinput->col = 1;
12725
0
    pinput->base = ctxt->input->cur;
12726
0
    pinput->cur = ctxt->input->cur;
12727
0
    pinput->free = NULL;
12728
12729
    /*
12730
     * let's parse that entity knowing it's an external subset.
12731
     */
12732
0
    ctxt->inSubset = 2;
12733
0
    ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
12734
0
    if (ctxt->myDoc == NULL) {
12735
0
  xmlErrMemory(ctxt, "New Doc failed");
12736
0
  return(NULL);
12737
0
    }
12738
0
    ctxt->myDoc->properties = XML_DOC_INTERNAL;
12739
0
    ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
12740
0
                                 BAD_CAST "none", BAD_CAST "none");
12741
12742
0
    if ((enc == XML_CHAR_ENCODING_NONE) &&
12743
0
        ((ctxt->input->end - ctxt->input->cur) >= 4)) {
12744
  /*
12745
   * Get the 4 first bytes and decode the charset
12746
   * if enc != XML_CHAR_ENCODING_NONE
12747
   * plug some encoding conversion routines.
12748
   */
12749
0
  start[0] = RAW;
12750
0
  start[1] = NXT(1);
12751
0
  start[2] = NXT(2);
12752
0
  start[3] = NXT(3);
12753
0
  enc = xmlDetectCharEncoding(start, 4);
12754
0
  if (enc != XML_CHAR_ENCODING_NONE) {
12755
0
      xmlSwitchEncoding(ctxt, enc);
12756
0
  }
12757
0
    }
12758
12759
0
    xmlParseExternalSubset(ctxt, BAD_CAST "none", BAD_CAST "none");
12760
12761
0
    if (ctxt->myDoc != NULL) {
12762
0
  if (ctxt->wellFormed) {
12763
0
      ret = ctxt->myDoc->extSubset;
12764
0
      ctxt->myDoc->extSubset = NULL;
12765
0
      if (ret != NULL) {
12766
0
    xmlNodePtr tmp;
12767
12768
0
    ret->doc = NULL;
12769
0
    tmp = ret->children;
12770
0
    while (tmp != NULL) {
12771
0
        tmp->doc = NULL;
12772
0
        tmp = tmp->next;
12773
0
    }
12774
0
      }
12775
0
  } else {
12776
0
      ret = NULL;
12777
0
  }
12778
0
        xmlFreeDoc(ctxt->myDoc);
12779
0
        ctxt->myDoc = NULL;
12780
0
    }
12781
0
    if (sax != NULL) ctxt->sax = NULL;
12782
0
    xmlFreeParserCtxt(ctxt);
12783
12784
0
    return(ret);
12785
0
}
12786
12787
/**
12788
 * xmlSAXParseDTD:
12789
 * @sax:  the SAX handler block
12790
 * @ExternalID:  a NAME* containing the External ID of the DTD
12791
 * @SystemID:  a NAME* containing the URL to the DTD
12792
 *
12793
 * Load and parse an external subset.
12794
 *
12795
 * Returns the resulting xmlDtdPtr or NULL in case of error.
12796
 */
12797
12798
xmlDtdPtr
12799
xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID,
12800
0
                          const xmlChar *SystemID) {
12801
0
    xmlDtdPtr ret = NULL;
12802
0
    xmlParserCtxtPtr ctxt;
12803
0
    xmlParserInputPtr input = NULL;
12804
0
    xmlCharEncoding enc;
12805
0
    xmlChar* systemIdCanonic;
12806
12807
0
    if ((ExternalID == NULL) && (SystemID == NULL)) return(NULL);
12808
12809
0
    ctxt = xmlNewParserCtxt();
12810
0
    if (ctxt == NULL) {
12811
0
  return(NULL);
12812
0
    }
12813
12814
    /* We are loading a DTD */
12815
0
    ctxt->options |= XML_PARSE_DTDLOAD;
12816
12817
    /*
12818
     * Set-up the SAX context
12819
     */
12820
0
    if (sax != NULL) {
12821
0
  if (ctxt->sax != NULL)
12822
0
      xmlFree(ctxt->sax);
12823
0
        ctxt->sax = sax;
12824
0
        ctxt->userData = ctxt;
12825
0
    }
12826
12827
    /*
12828
     * Canonicalise the system ID
12829
     */
12830
0
    systemIdCanonic = xmlCanonicPath(SystemID);
12831
0
    if ((SystemID != NULL) && (systemIdCanonic == NULL)) {
12832
0
  xmlFreeParserCtxt(ctxt);
12833
0
  return(NULL);
12834
0
    }
12835
12836
    /*
12837
     * Ask the Entity resolver to load the damn thing
12838
     */
12839
12840
0
    if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
12841
0
  input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID,
12842
0
                                   systemIdCanonic);
12843
0
    if (input == NULL) {
12844
0
        if (sax != NULL) ctxt->sax = NULL;
12845
0
  xmlFreeParserCtxt(ctxt);
12846
0
  if (systemIdCanonic != NULL)
12847
0
      xmlFree(systemIdCanonic);
12848
0
  return(NULL);
12849
0
    }
12850
12851
    /*
12852
     * plug some encoding conversion routines here.
12853
     */
12854
0
    if (xmlPushInput(ctxt, input) < 0) {
12855
0
        if (sax != NULL) ctxt->sax = NULL;
12856
0
  xmlFreeParserCtxt(ctxt);
12857
0
  if (systemIdCanonic != NULL)
12858
0
      xmlFree(systemIdCanonic);
12859
0
  return(NULL);
12860
0
    }
12861
0
    if ((ctxt->input->end - ctxt->input->cur) >= 4) {
12862
0
  enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
12863
0
  xmlSwitchEncoding(ctxt, enc);
12864
0
    }
12865
12866
0
    if (input->filename == NULL)
12867
0
  input->filename = (char *) systemIdCanonic;
12868
0
    else
12869
0
  xmlFree(systemIdCanonic);
12870
0
    input->line = 1;
12871
0
    input->col = 1;
12872
0
    input->base = ctxt->input->cur;
12873
0
    input->cur = ctxt->input->cur;
12874
0
    input->free = NULL;
12875
12876
    /*
12877
     * let's parse that entity knowing it's an external subset.
12878
     */
12879
0
    ctxt->inSubset = 2;
12880
0
    ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
12881
0
    if (ctxt->myDoc == NULL) {
12882
0
  xmlErrMemory(ctxt, "New Doc failed");
12883
0
        if (sax != NULL) ctxt->sax = NULL;
12884
0
  xmlFreeParserCtxt(ctxt);
12885
0
  return(NULL);
12886
0
    }
12887
0
    ctxt->myDoc->properties = XML_DOC_INTERNAL;
12888
0
    ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
12889
0
                                 ExternalID, SystemID);
12890
0
    xmlParseExternalSubset(ctxt, ExternalID, SystemID);
12891
12892
0
    if (ctxt->myDoc != NULL) {
12893
0
  if (ctxt->wellFormed) {
12894
0
      ret = ctxt->myDoc->extSubset;
12895
0
      ctxt->myDoc->extSubset = NULL;
12896
0
      if (ret != NULL) {
12897
0
    xmlNodePtr tmp;
12898
12899
0
    ret->doc = NULL;
12900
0
    tmp = ret->children;
12901
0
    while (tmp != NULL) {
12902
0
        tmp->doc = NULL;
12903
0
        tmp = tmp->next;
12904
0
    }
12905
0
      }
12906
0
  } else {
12907
0
      ret = NULL;
12908
0
  }
12909
0
        xmlFreeDoc(ctxt->myDoc);
12910
0
        ctxt->myDoc = NULL;
12911
0
    }
12912
0
    if (sax != NULL) ctxt->sax = NULL;
12913
0
    xmlFreeParserCtxt(ctxt);
12914
12915
0
    return(ret);
12916
0
}
12917
12918
12919
/**
12920
 * xmlParseDTD:
12921
 * @ExternalID:  a NAME* containing the External ID of the DTD
12922
 * @SystemID:  a NAME* containing the URL to the DTD
12923
 *
12924
 * Load and parse an external subset.
12925
 *
12926
 * Returns the resulting xmlDtdPtr or NULL in case of error.
12927
 */
12928
12929
xmlDtdPtr
12930
0
xmlParseDTD(const xmlChar *ExternalID, const xmlChar *SystemID) {
12931
0
    return(xmlSAXParseDTD(NULL, ExternalID, SystemID));
12932
0
}
12933
#endif /* LIBXML_VALID_ENABLED */
12934
12935
/************************************************************************
12936
 *                  *
12937
 *    Front ends when parsing an Entity     *
12938
 *                  *
12939
 ************************************************************************/
12940
12941
/**
12942
 * xmlParseCtxtExternalEntity:
12943
 * @ctx:  the existing parsing context
12944
 * @URL:  the URL for the entity to load
12945
 * @ID:  the System ID for the entity to load
12946
 * @lst:  the return value for the set of parsed nodes
12947
 *
12948
 * Parse an external general entity within an existing parsing context
12949
 * An external general parsed entity is well-formed if it matches the
12950
 * production labeled extParsedEnt.
12951
 *
12952
 * [78] extParsedEnt ::= TextDecl? content
12953
 *
12954
 * Returns 0 if the entity is well formed, -1 in case of args problem and
12955
 *    the parser error code otherwise
12956
 */
12957
12958
int
12959
xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx, const xmlChar *URL,
12960
0
                 const xmlChar *ID, xmlNodePtr *lst) {
12961
0
    void *userData;
12962
12963
0
    if (ctx == NULL) return(-1);
12964
    /*
12965
     * If the user provided their own SAX callbacks, then reuse the
12966
     * userData callback field, otherwise the expected setup in a
12967
     * DOM builder is to have userData == ctxt
12968
     */
12969
0
    if (ctx->userData == ctx)
12970
0
        userData = NULL;
12971
0
    else
12972
0
        userData = ctx->userData;
12973
0
    return xmlParseExternalEntityPrivate(ctx->myDoc, ctx, ctx->sax,
12974
0
                                         userData, ctx->depth + 1,
12975
0
                                         URL, ID, lst);
12976
0
}
12977
12978
/**
12979
 * xmlParseExternalEntityPrivate:
12980
 * @doc:  the document the chunk pertains to
12981
 * @oldctxt:  the previous parser context if available
12982
 * @sax:  the SAX handler block (possibly NULL)
12983
 * @user_data:  The user data returned on SAX callbacks (possibly NULL)
12984
 * @depth:  Used for loop detection, use 0
12985
 * @URL:  the URL for the entity to load
12986
 * @ID:  the System ID for the entity to load
12987
 * @list:  the return value for the set of parsed nodes
12988
 *
12989
 * Private version of xmlParseExternalEntity()
12990
 *
12991
 * Returns 0 if the entity is well formed, -1 in case of args problem and
12992
 *    the parser error code otherwise
12993
 */
12994
12995
static xmlParserErrors
12996
xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
12997
                xmlSAXHandlerPtr sax,
12998
          void *user_data, int depth, const xmlChar *URL,
12999
0
          const xmlChar *ID, xmlNodePtr *list) {
13000
0
    xmlParserCtxtPtr ctxt;
13001
0
    xmlDocPtr newDoc;
13002
0
    xmlNodePtr newRoot;
13003
0
    xmlSAXHandlerPtr oldsax = NULL;
13004
0
    xmlParserErrors ret = XML_ERR_OK;
13005
0
    xmlChar start[4];
13006
0
    xmlCharEncoding enc;
13007
13008
0
    if (((depth > 40) &&
13009
0
  ((oldctxt == NULL) || (oldctxt->options & XML_PARSE_HUGE) == 0)) ||
13010
0
  (depth > 1024)) {
13011
0
  return(XML_ERR_ENTITY_LOOP);
13012
0
    }
13013
13014
0
    if (list != NULL)
13015
0
        *list = NULL;
13016
0
    if ((URL == NULL) && (ID == NULL))
13017
0
  return(XML_ERR_INTERNAL_ERROR);
13018
0
    if (doc == NULL)
13019
0
  return(XML_ERR_INTERNAL_ERROR);
13020
13021
13022
0
    ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, oldctxt);
13023
0
    if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
13024
0
    ctxt->userData = ctxt;
13025
0
    if (sax != NULL) {
13026
0
  oldsax = ctxt->sax;
13027
0
        ctxt->sax = sax;
13028
0
  if (user_data != NULL)
13029
0
      ctxt->userData = user_data;
13030
0
    }
13031
0
    xmlDetectSAX2(ctxt);
13032
0
    newDoc = xmlNewDoc(BAD_CAST "1.0");
13033
0
    if (newDoc == NULL) {
13034
0
  xmlFreeParserCtxt(ctxt);
13035
0
  return(XML_ERR_INTERNAL_ERROR);
13036
0
    }
13037
0
    newDoc->properties = XML_DOC_INTERNAL;
13038
0
    if (doc) {
13039
0
        newDoc->intSubset = doc->intSubset;
13040
0
        newDoc->extSubset = doc->extSubset;
13041
0
        if (doc->dict) {
13042
0
            newDoc->dict = doc->dict;
13043
0
            xmlDictReference(newDoc->dict);
13044
0
        }
13045
0
        if (doc->URL != NULL) {
13046
0
            newDoc->URL = xmlStrdup(doc->URL);
13047
0
        }
13048
0
    }
13049
0
    newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
13050
0
    if (newRoot == NULL) {
13051
0
  if (sax != NULL)
13052
0
      ctxt->sax = oldsax;
13053
0
  xmlFreeParserCtxt(ctxt);
13054
0
  newDoc->intSubset = NULL;
13055
0
  newDoc->extSubset = NULL;
13056
0
        xmlFreeDoc(newDoc);
13057
0
  return(XML_ERR_INTERNAL_ERROR);
13058
0
    }
13059
0
    xmlAddChild((xmlNodePtr) newDoc, newRoot);
13060
0
    nodePush(ctxt, newDoc->children);
13061
0
    if (doc == NULL) {
13062
0
        ctxt->myDoc = newDoc;
13063
0
    } else {
13064
0
        ctxt->myDoc = doc;
13065
0
        newRoot->doc = doc;
13066
0
    }
13067
13068
    /*
13069
     * Get the 4 first bytes and decode the charset
13070
     * if enc != XML_CHAR_ENCODING_NONE
13071
     * plug some encoding conversion routines.
13072
     */
13073
0
    GROW;
13074
0
    if ((ctxt->input->end - ctxt->input->cur) >= 4) {
13075
0
  start[0] = RAW;
13076
0
  start[1] = NXT(1);
13077
0
  start[2] = NXT(2);
13078
0
  start[3] = NXT(3);
13079
0
  enc = xmlDetectCharEncoding(start, 4);
13080
0
  if (enc != XML_CHAR_ENCODING_NONE) {
13081
0
      xmlSwitchEncoding(ctxt, enc);
13082
0
  }
13083
0
    }
13084
13085
    /*
13086
     * Parse a possible text declaration first
13087
     */
13088
0
    if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
13089
0
  xmlParseTextDecl(ctxt);
13090
        /*
13091
         * An XML-1.0 document can't reference an entity not XML-1.0
13092
         */
13093
0
        if ((xmlStrEqual(oldctxt->version, BAD_CAST "1.0")) &&
13094
0
            (!xmlStrEqual(ctxt->input->version, BAD_CAST "1.0"))) {
13095
0
            xmlFatalErrMsg(ctxt, XML_ERR_VERSION_MISMATCH,
13096
0
                           "Version mismatch between document and entity\n");
13097
0
        }
13098
0
    }
13099
13100
0
    ctxt->instate = XML_PARSER_CONTENT;
13101
0
    ctxt->depth = depth;
13102
0
    if (oldctxt != NULL) {
13103
0
  ctxt->_private = oldctxt->_private;
13104
0
  ctxt->loadsubset = oldctxt->loadsubset;
13105
0
  ctxt->validate = oldctxt->validate;
13106
0
  ctxt->valid = oldctxt->valid;
13107
0
  ctxt->replaceEntities = oldctxt->replaceEntities;
13108
0
        if (oldctxt->validate) {
13109
0
            ctxt->vctxt.error = oldctxt->vctxt.error;
13110
0
            ctxt->vctxt.warning = oldctxt->vctxt.warning;
13111
0
            ctxt->vctxt.userData = oldctxt->vctxt.userData;
13112
0
        }
13113
0
  ctxt->external = oldctxt->external;
13114
0
        if (ctxt->dict) xmlDictFree(ctxt->dict);
13115
0
        ctxt->dict = oldctxt->dict;
13116
0
        ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
13117
0
        ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
13118
0
        ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
13119
0
        ctxt->dictNames = oldctxt->dictNames;
13120
0
        ctxt->attsDefault = oldctxt->attsDefault;
13121
0
        ctxt->attsSpecial = oldctxt->attsSpecial;
13122
0
        ctxt->linenumbers = oldctxt->linenumbers;
13123
0
  ctxt->record_info = oldctxt->record_info;
13124
0
  ctxt->node_seq.maximum = oldctxt->node_seq.maximum;
13125
0
  ctxt->node_seq.length = oldctxt->node_seq.length;
13126
0
  ctxt->node_seq.buffer = oldctxt->node_seq.buffer;
13127
0
    } else {
13128
  /*
13129
   * Doing validity checking on chunk without context
13130
   * doesn't make sense
13131
   */
13132
0
  ctxt->_private = NULL;
13133
0
  ctxt->validate = 0;
13134
0
  ctxt->external = 2;
13135
0
  ctxt->loadsubset = 0;
13136
0
    }
13137
13138
0
    xmlParseContent(ctxt);
13139
13140
0
    if ((RAW == '<') && (NXT(1) == '/')) {
13141
0
  xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13142
0
    } else if (RAW != 0) {
13143
0
  xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
13144
0
    }
13145
0
    if (ctxt->node != newDoc->children) {
13146
0
  xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13147
0
    }
13148
13149
0
    if (!ctxt->wellFormed) {
13150
0
        if (ctxt->errNo == 0)
13151
0
      ret = XML_ERR_INTERNAL_ERROR;
13152
0
  else
13153
0
      ret = (xmlParserErrors)ctxt->errNo;
13154
0
    } else {
13155
0
  if (list != NULL) {
13156
0
      xmlNodePtr cur;
13157
13158
      /*
13159
       * Return the newly created nodeset after unlinking it from
13160
       * they pseudo parent.
13161
       */
13162
0
      cur = newDoc->children->children;
13163
0
      *list = cur;
13164
0
      while (cur != NULL) {
13165
0
    cur->parent = NULL;
13166
0
    cur = cur->next;
13167
0
      }
13168
0
            newDoc->children->children = NULL;
13169
0
  }
13170
0
  ret = XML_ERR_OK;
13171
0
    }
13172
13173
    /*
13174
     * Record in the parent context the number of entities replacement
13175
     * done when parsing that reference.
13176
     */
13177
0
    if (oldctxt != NULL)
13178
0
        oldctxt->nbentities += ctxt->nbentities;
13179
13180
    /*
13181
     * Also record the size of the entity parsed
13182
     */
13183
0
    if (ctxt->input != NULL && oldctxt != NULL) {
13184
0
  oldctxt->sizeentities += ctxt->input->consumed;
13185
0
  oldctxt->sizeentities += (ctxt->input->cur - ctxt->input->base);
13186
0
    }
13187
    /*
13188
     * And record the last error if any
13189
     */
13190
0
    if ((oldctxt != NULL) && (ctxt->lastError.code != XML_ERR_OK))
13191
0
        xmlCopyError(&ctxt->lastError, &oldctxt->lastError);
13192
13193
0
    if (sax != NULL)
13194
0
  ctxt->sax = oldsax;
13195
0
    if (oldctxt != NULL) {
13196
0
        ctxt->dict = NULL;
13197
0
        ctxt->attsDefault = NULL;
13198
0
        ctxt->attsSpecial = NULL;
13199
0
        oldctxt->validate = ctxt->validate;
13200
0
        oldctxt->valid = ctxt->valid;
13201
0
        oldctxt->node_seq.maximum = ctxt->node_seq.maximum;
13202
0
        oldctxt->node_seq.length = ctxt->node_seq.length;
13203
0
        oldctxt->node_seq.buffer = ctxt->node_seq.buffer;
13204
0
    }
13205
0
    ctxt->node_seq.maximum = 0;
13206
0
    ctxt->node_seq.length = 0;
13207
0
    ctxt->node_seq.buffer = NULL;
13208
0
    xmlFreeParserCtxt(ctxt);
13209
0
    newDoc->intSubset = NULL;
13210
0
    newDoc->extSubset = NULL;
13211
0
    xmlFreeDoc(newDoc);
13212
13213
0
    return(ret);
13214
0
}
13215
13216
#ifdef LIBXML_SAX1_ENABLED
13217
/**
13218
 * xmlParseExternalEntity:
13219
 * @doc:  the document the chunk pertains to
13220
 * @sax:  the SAX handler block (possibly NULL)
13221
 * @user_data:  The user data returned on SAX callbacks (possibly NULL)
13222
 * @depth:  Used for loop detection, use 0
13223
 * @URL:  the URL for the entity to load
13224
 * @ID:  the System ID for the entity to load
13225
 * @lst:  the return value for the set of parsed nodes
13226
 *
13227
 * Parse an external general entity
13228
 * An external general parsed entity is well-formed if it matches the
13229
 * production labeled extParsedEnt.
13230
 *
13231
 * [78] extParsedEnt ::= TextDecl? content
13232
 *
13233
 * Returns 0 if the entity is well formed, -1 in case of args problem and
13234
 *    the parser error code otherwise
13235
 */
13236
13237
int
13238
xmlParseExternalEntity(xmlDocPtr doc, xmlSAXHandlerPtr sax, void *user_data,
13239
0
    int depth, const xmlChar *URL, const xmlChar *ID, xmlNodePtr *lst) {
13240
0
    return(xmlParseExternalEntityPrivate(doc, NULL, sax, user_data, depth, URL,
13241
0
                           ID, lst));
13242
0
}
13243
13244
/**
13245
 * xmlParseBalancedChunkMemory:
13246
 * @doc:  the document the chunk pertains to (must not be NULL)
13247
 * @sax:  the SAX handler block (possibly NULL)
13248
 * @user_data:  The user data returned on SAX callbacks (possibly NULL)
13249
 * @depth:  Used for loop detection, use 0
13250
 * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
13251
 * @lst:  the return value for the set of parsed nodes
13252
 *
13253
 * Parse a well-balanced chunk of an XML document
13254
 * called by the parser
13255
 * The allowed sequence for the Well Balanced Chunk is the one defined by
13256
 * the content production in the XML grammar:
13257
 *
13258
 * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
13259
 *
13260
 * Returns 0 if the chunk is well balanced, -1 in case of args problem and
13261
 *    the parser error code otherwise
13262
 */
13263
13264
int
13265
xmlParseBalancedChunkMemory(xmlDocPtr doc, xmlSAXHandlerPtr sax,
13266
0
     void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst) {
13267
0
    return xmlParseBalancedChunkMemoryRecover( doc, sax, user_data,
13268
0
                                                depth, string, lst, 0 );
13269
0
}
13270
#endif /* LIBXML_SAX1_ENABLED */
13271
13272
/**
13273
 * xmlParseBalancedChunkMemoryInternal:
13274
 * @oldctxt:  the existing parsing context
13275
 * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
13276
 * @user_data:  the user data field for the parser context
13277
 * @lst:  the return value for the set of parsed nodes
13278
 *
13279
 *
13280
 * Parse a well-balanced chunk of an XML document
13281
 * called by the parser
13282
 * The allowed sequence for the Well Balanced Chunk is the one defined by
13283
 * the content production in the XML grammar:
13284
 *
13285
 * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
13286
 *
13287
 * Returns XML_ERR_OK if the chunk is well balanced, and the parser
13288
 * error code otherwise
13289
 *
13290
 * In case recover is set to 1, the nodelist will not be empty even if
13291
 * the parsed chunk is not well balanced.
13292
 */
13293
static xmlParserErrors
13294
xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
13295
433k
  const xmlChar *string, void *user_data, xmlNodePtr *lst) {
13296
433k
    xmlParserCtxtPtr ctxt;
13297
433k
    xmlDocPtr newDoc = NULL;
13298
433k
    xmlNodePtr newRoot;
13299
433k
    xmlSAXHandlerPtr oldsax = NULL;
13300
433k
    xmlNodePtr content = NULL;
13301
433k
    xmlNodePtr last = NULL;
13302
433k
    int size;
13303
433k
    xmlParserErrors ret = XML_ERR_OK;
13304
433k
#ifdef SAX2
13305
433k
    int i;
13306
433k
#endif
13307
13308
433k
    if (((oldctxt->depth > 40) && ((oldctxt->options & XML_PARSE_HUGE) == 0)) ||
13309
433k
        (oldctxt->depth >  1024)) {
13310
582
  return(XML_ERR_ENTITY_LOOP);
13311
582
    }
13312
13313
13314
432k
    if (lst != NULL)
13315
299k
        *lst = NULL;
13316
432k
    if (string == NULL)
13317
0
        return(XML_ERR_INTERNAL_ERROR);
13318
13319
432k
    size = xmlStrlen(string);
13320
13321
432k
    ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
13322
432k
    if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
13323
300k
    if (user_data != NULL)
13324
0
  ctxt->userData = user_data;
13325
300k
    else
13326
300k
  ctxt->userData = ctxt;
13327
300k
    if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
13328
300k
    ctxt->dict = oldctxt->dict;
13329
300k
    ctxt->input_id = oldctxt->input_id + 1;
13330
300k
    ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
13331
300k
    ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
13332
300k
    ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
13333
13334
300k
#ifdef SAX2
13335
    /* propagate namespaces down the entity */
13336
29.2M
    for (i = 0;i < oldctxt->nsNr;i += 2) {
13337
28.9M
        nsPush(ctxt, oldctxt->nsTab[i], oldctxt->nsTab[i+1]);
13338
28.9M
    }
13339
300k
#endif
13340
13341
300k
    oldsax = ctxt->sax;
13342
300k
    ctxt->sax = oldctxt->sax;
13343
300k
    xmlDetectSAX2(ctxt);
13344
300k
    ctxt->replaceEntities = oldctxt->replaceEntities;
13345
300k
    ctxt->options = oldctxt->options;
13346
13347
300k
    ctxt->_private = oldctxt->_private;
13348
300k
    if (oldctxt->myDoc == NULL) {
13349
0
  newDoc = xmlNewDoc(BAD_CAST "1.0");
13350
0
  if (newDoc == NULL) {
13351
0
      ctxt->sax = oldsax;
13352
0
      ctxt->dict = NULL;
13353
0
      xmlFreeParserCtxt(ctxt);
13354
0
      return(XML_ERR_INTERNAL_ERROR);
13355
0
  }
13356
0
  newDoc->properties = XML_DOC_INTERNAL;
13357
0
  newDoc->dict = ctxt->dict;
13358
0
  xmlDictReference(newDoc->dict);
13359
0
  ctxt->myDoc = newDoc;
13360
300k
    } else {
13361
300k
  ctxt->myDoc = oldctxt->myDoc;
13362
300k
        content = ctxt->myDoc->children;
13363
300k
  last = ctxt->myDoc->last;
13364
300k
    }
13365
300k
    newRoot = xmlNewDocNode(ctxt->myDoc, NULL, BAD_CAST "pseudoroot", NULL);
13366
300k
    if (newRoot == NULL) {
13367
0
  ctxt->sax = oldsax;
13368
0
  ctxt->dict = NULL;
13369
0
  xmlFreeParserCtxt(ctxt);
13370
0
  if (newDoc != NULL) {
13371
0
      xmlFreeDoc(newDoc);
13372
0
  }
13373
0
  return(XML_ERR_INTERNAL_ERROR);
13374
0
    }
13375
300k
    ctxt->myDoc->children = NULL;
13376
300k
    ctxt->myDoc->last = NULL;
13377
300k
    xmlAddChild((xmlNodePtr) ctxt->myDoc, newRoot);
13378
300k
    nodePush(ctxt, ctxt->myDoc->children);
13379
300k
    ctxt->instate = XML_PARSER_CONTENT;
13380
300k
    ctxt->depth = oldctxt->depth + 1;
13381
13382
300k
    ctxt->validate = 0;
13383
300k
    ctxt->loadsubset = oldctxt->loadsubset;
13384
300k
    if ((oldctxt->validate) || (oldctxt->replaceEntities != 0)) {
13385
  /*
13386
   * ID/IDREF registration will be done in xmlValidateElement below
13387
   */
13388
0
  ctxt->loadsubset |= XML_SKIP_IDS;
13389
0
    }
13390
300k
    ctxt->dictNames = oldctxt->dictNames;
13391
300k
    ctxt->attsDefault = oldctxt->attsDefault;
13392
300k
    ctxt->attsSpecial = oldctxt->attsSpecial;
13393
13394
300k
    xmlParseContent(ctxt);
13395
300k
    if ((RAW == '<') && (NXT(1) == '/')) {
13396
1.56k
  xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13397
299k
    } else if (RAW != 0) {
13398
0
  xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
13399
0
    }
13400
300k
    if (ctxt->node != ctxt->myDoc->children) {
13401
125k
  xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13402
125k
    }
13403
13404
300k
    if (!ctxt->wellFormed) {
13405
299k
        if (ctxt->errNo == 0)
13406
0
      ret = XML_ERR_INTERNAL_ERROR;
13407
299k
  else
13408
299k
      ret = (xmlParserErrors)ctxt->errNo;
13409
299k
    } else {
13410
1.35k
      ret = XML_ERR_OK;
13411
1.35k
    }
13412
13413
300k
    if ((lst != NULL) && (ret == XML_ERR_OK)) {
13414
255
  xmlNodePtr cur;
13415
13416
  /*
13417
   * Return the newly created nodeset after unlinking it from
13418
   * they pseudo parent.
13419
   */
13420
255
  cur = ctxt->myDoc->children->children;
13421
255
  *lst = cur;
13422
2.64k
  while (cur != NULL) {
13423
2.38k
#ifdef LIBXML_VALID_ENABLED
13424
2.38k
      if ((oldctxt->validate) && (oldctxt->wellFormed) &&
13425
2.38k
    (oldctxt->myDoc) && (oldctxt->myDoc->intSubset) &&
13426
2.38k
    (cur->type == XML_ELEMENT_NODE)) {
13427
0
    oldctxt->valid &= xmlValidateElement(&oldctxt->vctxt,
13428
0
      oldctxt->myDoc, cur);
13429
0
      }
13430
2.38k
#endif /* LIBXML_VALID_ENABLED */
13431
2.38k
      cur->parent = NULL;
13432
2.38k
      cur = cur->next;
13433
2.38k
  }
13434
255
  ctxt->myDoc->children->children = NULL;
13435
255
    }
13436
300k
    if (ctxt->myDoc != NULL) {
13437
300k
  xmlFreeNode(ctxt->myDoc->children);
13438
300k
        ctxt->myDoc->children = content;
13439
300k
        ctxt->myDoc->last = last;
13440
300k
    }
13441
13442
    /*
13443
     * Record in the parent context the number of entities replacement
13444
     * done when parsing that reference.
13445
     */
13446
300k
    if (oldctxt != NULL)
13447
300k
        oldctxt->nbentities += ctxt->nbentities;
13448
13449
    /*
13450
     * Also record the last error if any
13451
     */
13452
300k
    if (ctxt->lastError.code != XML_ERR_OK)
13453
299k
        xmlCopyError(&ctxt->lastError, &oldctxt->lastError);
13454
13455
300k
    ctxt->sax = oldsax;
13456
300k
    ctxt->dict = NULL;
13457
300k
    ctxt->attsDefault = NULL;
13458
300k
    ctxt->attsSpecial = NULL;
13459
300k
    xmlFreeParserCtxt(ctxt);
13460
300k
    if (newDoc != NULL) {
13461
0
  xmlFreeDoc(newDoc);
13462
0
    }
13463
13464
300k
    return(ret);
13465
300k
}
13466
13467
/**
13468
 * xmlParseInNodeContext:
13469
 * @node:  the context node
13470
 * @data:  the input string
13471
 * @datalen:  the input string length in bytes
13472
 * @options:  a combination of xmlParserOption
13473
 * @lst:  the return value for the set of parsed nodes
13474
 *
13475
 * Parse a well-balanced chunk of an XML document
13476
 * within the context (DTD, namespaces, etc ...) of the given node.
13477
 *
13478
 * The allowed sequence for the data is a Well Balanced Chunk defined by
13479
 * the content production in the XML grammar:
13480
 *
13481
 * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
13482
 *
13483
 * Returns XML_ERR_OK if the chunk is well balanced, and the parser
13484
 * error code otherwise
13485
 */
13486
xmlParserErrors
13487
xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen,
13488
0
                      int options, xmlNodePtr *lst) {
13489
0
#ifdef SAX2
13490
0
    xmlParserCtxtPtr ctxt;
13491
0
    xmlDocPtr doc = NULL;
13492
0
    xmlNodePtr fake, cur;
13493
0
    int nsnr = 0;
13494
13495
0
    xmlParserErrors ret = XML_ERR_OK;
13496
13497
    /*
13498
     * check all input parameters, grab the document
13499
     */
13500
0
    if ((lst == NULL) || (node == NULL) || (data == NULL) || (datalen < 0))
13501
0
        return(XML_ERR_INTERNAL_ERROR);
13502
0
    switch (node->type) {
13503
0
        case XML_ELEMENT_NODE:
13504
0
        case XML_ATTRIBUTE_NODE:
13505
0
        case XML_TEXT_NODE:
13506
0
        case XML_CDATA_SECTION_NODE:
13507
0
        case XML_ENTITY_REF_NODE:
13508
0
        case XML_PI_NODE:
13509
0
        case XML_COMMENT_NODE:
13510
0
        case XML_DOCUMENT_NODE:
13511
0
        case XML_HTML_DOCUMENT_NODE:
13512
0
      break;
13513
0
  default:
13514
0
      return(XML_ERR_INTERNAL_ERROR);
13515
13516
0
    }
13517
0
    while ((node != NULL) && (node->type != XML_ELEMENT_NODE) &&
13518
0
           (node->type != XML_DOCUMENT_NODE) &&
13519
0
     (node->type != XML_HTML_DOCUMENT_NODE))
13520
0
  node = node->parent;
13521
0
    if (node == NULL)
13522
0
  return(XML_ERR_INTERNAL_ERROR);
13523
0
    if (node->type == XML_ELEMENT_NODE)
13524
0
  doc = node->doc;
13525
0
    else
13526
0
        doc = (xmlDocPtr) node;
13527
0
    if (doc == NULL)
13528
0
  return(XML_ERR_INTERNAL_ERROR);
13529
13530
    /*
13531
     * allocate a context and set-up everything not related to the
13532
     * node position in the tree
13533
     */
13534
0
    if (doc->type == XML_DOCUMENT_NODE)
13535
0
  ctxt = xmlCreateMemoryParserCtxt((char *) data, datalen);
13536
0
#ifdef LIBXML_HTML_ENABLED
13537
0
    else if (doc->type == XML_HTML_DOCUMENT_NODE) {
13538
0
  ctxt = htmlCreateMemoryParserCtxt((char *) data, datalen);
13539
        /*
13540
         * When parsing in context, it makes no sense to add implied
13541
         * elements like html/body/etc...
13542
         */
13543
0
        options |= HTML_PARSE_NOIMPLIED;
13544
0
    }
13545
0
#endif
13546
0
    else
13547
0
        return(XML_ERR_INTERNAL_ERROR);
13548
13549
0
    if (ctxt == NULL)
13550
0
        return(XML_ERR_NO_MEMORY);
13551
13552
    /*
13553
     * Use input doc's dict if present, else assure XML_PARSE_NODICT is set.
13554
     * We need a dictionary for xmlDetectSAX2, so if there's no doc dict
13555
     * we must wait until the last moment to free the original one.
13556
     */
13557
0
    if (doc->dict != NULL) {
13558
0
        if (ctxt->dict != NULL)
13559
0
      xmlDictFree(ctxt->dict);
13560
0
  ctxt->dict = doc->dict;
13561
0
    } else
13562
0
        options |= XML_PARSE_NODICT;
13563
13564
0
    if (doc->encoding != NULL) {
13565
0
        xmlCharEncodingHandlerPtr hdlr;
13566
13567
0
        if (ctxt->encoding != NULL)
13568
0
      xmlFree((xmlChar *) ctxt->encoding);
13569
0
        ctxt->encoding = xmlStrdup((const xmlChar *) doc->encoding);
13570
13571
0
        hdlr = xmlFindCharEncodingHandler((const char *) doc->encoding);
13572
0
        if (hdlr != NULL) {
13573
0
            xmlSwitchToEncoding(ctxt, hdlr);
13574
0
  } else {
13575
0
            return(XML_ERR_UNSUPPORTED_ENCODING);
13576
0
        }
13577
0
    }
13578
13579
0
    xmlCtxtUseOptionsInternal(ctxt, options, NULL);
13580
0
    xmlDetectSAX2(ctxt);
13581
0
    ctxt->myDoc = doc;
13582
    /* parsing in context, i.e. as within existing content */
13583
0
    ctxt->input_id = 2;
13584
0
    ctxt->instate = XML_PARSER_CONTENT;
13585
13586
0
    fake = xmlNewComment(NULL);
13587
0
    if (fake == NULL) {
13588
0
        xmlFreeParserCtxt(ctxt);
13589
0
  return(XML_ERR_NO_MEMORY);
13590
0
    }
13591
0
    xmlAddChild(node, fake);
13592
13593
0
    if (node->type == XML_ELEMENT_NODE) {
13594
0
  nodePush(ctxt, node);
13595
  /*
13596
   * initialize the SAX2 namespaces stack
13597
   */
13598
0
  cur = node;
13599
0
  while ((cur != NULL) && (cur->type == XML_ELEMENT_NODE)) {
13600
0
      xmlNsPtr ns = cur->nsDef;
13601
0
      const xmlChar *iprefix, *ihref;
13602
13603
0
      while (ns != NULL) {
13604
0
    if (ctxt->dict) {
13605
0
        iprefix = xmlDictLookup(ctxt->dict, ns->prefix, -1);
13606
0
        ihref = xmlDictLookup(ctxt->dict, ns->href, -1);
13607
0
    } else {
13608
0
        iprefix = ns->prefix;
13609
0
        ihref = ns->href;
13610
0
    }
13611
13612
0
          if (xmlGetNamespace(ctxt, iprefix) == NULL) {
13613
0
        nsPush(ctxt, iprefix, ihref);
13614
0
        nsnr++;
13615
0
    }
13616
0
    ns = ns->next;
13617
0
      }
13618
0
      cur = cur->parent;
13619
0
  }
13620
0
    }
13621
13622
0
    if ((ctxt->validate) || (ctxt->replaceEntities != 0)) {
13623
  /*
13624
   * ID/IDREF registration will be done in xmlValidateElement below
13625
   */
13626
0
  ctxt->loadsubset |= XML_SKIP_IDS;
13627
0
    }
13628
13629
0
#ifdef LIBXML_HTML_ENABLED
13630
0
    if (doc->type == XML_HTML_DOCUMENT_NODE)
13631
0
        __htmlParseContent(ctxt);
13632
0
    else
13633
0
#endif
13634
0
  xmlParseContent(ctxt);
13635
13636
0
    nsPop(ctxt, nsnr);
13637
0
    if ((RAW == '<') && (NXT(1) == '/')) {
13638
0
  xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13639
0
    } else if (RAW != 0) {
13640
0
  xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
13641
0
    }
13642
0
    if ((ctxt->node != NULL) && (ctxt->node != node)) {
13643
0
  xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13644
0
  ctxt->wellFormed = 0;
13645
0
    }
13646
13647
0
    if (!ctxt->wellFormed) {
13648
0
        if (ctxt->errNo == 0)
13649
0
      ret = XML_ERR_INTERNAL_ERROR;
13650
0
  else
13651
0
      ret = (xmlParserErrors)ctxt->errNo;
13652
0
    } else {
13653
0
        ret = XML_ERR_OK;
13654
0
    }
13655
13656
    /*
13657
     * Return the newly created nodeset after unlinking it from
13658
     * the pseudo sibling.
13659
     */
13660
13661
0
    cur = fake->next;
13662
0
    fake->next = NULL;
13663
0
    node->last = fake;
13664
13665
0
    if (cur != NULL) {
13666
0
  cur->prev = NULL;
13667
0
    }
13668
13669
0
    *lst = cur;
13670
13671
0
    while (cur != NULL) {
13672
0
  cur->parent = NULL;
13673
0
  cur = cur->next;
13674
0
    }
13675
13676
0
    xmlUnlinkNode(fake);
13677
0
    xmlFreeNode(fake);
13678
13679
13680
0
    if (ret != XML_ERR_OK) {
13681
0
        xmlFreeNodeList(*lst);
13682
0
  *lst = NULL;
13683
0
    }
13684
13685
0
    if (doc->dict != NULL)
13686
0
        ctxt->dict = NULL;
13687
0
    xmlFreeParserCtxt(ctxt);
13688
13689
0
    return(ret);
13690
#else /* !SAX2 */
13691
    return(XML_ERR_INTERNAL_ERROR);
13692
#endif
13693
0
}
13694
13695
#ifdef LIBXML_SAX1_ENABLED
13696
/**
13697
 * xmlParseBalancedChunkMemoryRecover:
13698
 * @doc:  the document the chunk pertains to (must not be NULL)
13699
 * @sax:  the SAX handler block (possibly NULL)
13700
 * @user_data:  The user data returned on SAX callbacks (possibly NULL)
13701
 * @depth:  Used for loop detection, use 0
13702
 * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
13703
 * @lst:  the return value for the set of parsed nodes
13704
 * @recover: return nodes even if the data is broken (use 0)
13705
 *
13706
 *
13707
 * Parse a well-balanced chunk of an XML document
13708
 * called by the parser
13709
 * The allowed sequence for the Well Balanced Chunk is the one defined by
13710
 * the content production in the XML grammar:
13711
 *
13712
 * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
13713
 *
13714
 * Returns 0 if the chunk is well balanced, -1 in case of args problem and
13715
 *    the parser error code otherwise
13716
 *
13717
 * In case recover is set to 1, the nodelist will not be empty even if
13718
 * the parsed chunk is not well balanced, assuming the parsing succeeded to
13719
 * some extent.
13720
 */
13721
int
13722
xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax,
13723
     void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst,
13724
0
     int recover) {
13725
0
    xmlParserCtxtPtr ctxt;
13726
0
    xmlDocPtr newDoc;
13727
0
    xmlSAXHandlerPtr oldsax = NULL;
13728
0
    xmlNodePtr content, newRoot;
13729
0
    int size;
13730
0
    int ret = 0;
13731
13732
0
    if (depth > 40) {
13733
0
  return(XML_ERR_ENTITY_LOOP);
13734
0
    }
13735
13736
13737
0
    if (lst != NULL)
13738
0
        *lst = NULL;
13739
0
    if (string == NULL)
13740
0
        return(-1);
13741
13742
0
    size = xmlStrlen(string);
13743
13744
0
    ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
13745
0
    if (ctxt == NULL) return(-1);
13746
0
    ctxt->userData = ctxt;
13747
0
    if (sax != NULL) {
13748
0
  oldsax = ctxt->sax;
13749
0
        ctxt->sax = sax;
13750
0
  if (user_data != NULL)
13751
0
      ctxt->userData = user_data;
13752
0
    }
13753
0
    newDoc = xmlNewDoc(BAD_CAST "1.0");
13754
0
    if (newDoc == NULL) {
13755
0
  xmlFreeParserCtxt(ctxt);
13756
0
  return(-1);
13757
0
    }
13758
0
    newDoc->properties = XML_DOC_INTERNAL;
13759
0
    if ((doc != NULL) && (doc->dict != NULL)) {
13760
0
        xmlDictFree(ctxt->dict);
13761
0
  ctxt->dict = doc->dict;
13762
0
  xmlDictReference(ctxt->dict);
13763
0
  ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
13764
0
  ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
13765
0
  ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
13766
0
  ctxt->dictNames = 1;
13767
0
    } else {
13768
0
  xmlCtxtUseOptionsInternal(ctxt, XML_PARSE_NODICT, NULL);
13769
0
    }
13770
    /* doc == NULL is only supported for historic reasons */
13771
0
    if (doc != NULL) {
13772
0
  newDoc->intSubset = doc->intSubset;
13773
0
  newDoc->extSubset = doc->extSubset;
13774
0
    }
13775
0
    newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
13776
0
    if (newRoot == NULL) {
13777
0
  if (sax != NULL)
13778
0
      ctxt->sax = oldsax;
13779
0
  xmlFreeParserCtxt(ctxt);
13780
0
  newDoc->intSubset = NULL;
13781
0
  newDoc->extSubset = NULL;
13782
0
        xmlFreeDoc(newDoc);
13783
0
  return(-1);
13784
0
    }
13785
0
    xmlAddChild((xmlNodePtr) newDoc, newRoot);
13786
0
    nodePush(ctxt, newRoot);
13787
    /* doc == NULL is only supported for historic reasons */
13788
0
    if (doc == NULL) {
13789
0
  ctxt->myDoc = newDoc;
13790
0
    } else {
13791
0
  ctxt->myDoc = newDoc;
13792
0
  newDoc->children->doc = doc;
13793
  /* Ensure that doc has XML spec namespace */
13794
0
  xmlSearchNsByHref(doc, (xmlNodePtr)doc, XML_XML_NAMESPACE);
13795
0
  newDoc->oldNs = doc->oldNs;
13796
0
    }
13797
0
    ctxt->instate = XML_PARSER_CONTENT;
13798
0
    ctxt->input_id = 2;
13799
0
    ctxt->depth = depth;
13800
13801
    /*
13802
     * Doing validity checking on chunk doesn't make sense
13803
     */
13804
0
    ctxt->validate = 0;
13805
0
    ctxt->loadsubset = 0;
13806
0
    xmlDetectSAX2(ctxt);
13807
13808
0
    if ( doc != NULL ){
13809
0
        content = doc->children;
13810
0
        doc->children = NULL;
13811
0
        xmlParseContent(ctxt);
13812
0
        doc->children = content;
13813
0
    }
13814
0
    else {
13815
0
        xmlParseContent(ctxt);
13816
0
    }
13817
0
    if ((RAW == '<') && (NXT(1) == '/')) {
13818
0
  xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13819
0
    } else if (RAW != 0) {
13820
0
  xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
13821
0
    }
13822
0
    if (ctxt->node != newDoc->children) {
13823
0
  xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13824
0
    }
13825
13826
0
    if (!ctxt->wellFormed) {
13827
0
        if (ctxt->errNo == 0)
13828
0
      ret = 1;
13829
0
  else
13830
0
      ret = ctxt->errNo;
13831
0
    } else {
13832
0
      ret = 0;
13833
0
    }
13834
13835
0
    if ((lst != NULL) && ((ret == 0) || (recover == 1))) {
13836
0
  xmlNodePtr cur;
13837
13838
  /*
13839
   * Return the newly created nodeset after unlinking it from
13840
   * they pseudo parent.
13841
   */
13842
0
  cur = newDoc->children->children;
13843
0
  *lst = cur;
13844
0
  while (cur != NULL) {
13845
0
      xmlSetTreeDoc(cur, doc);
13846
0
      cur->parent = NULL;
13847
0
      cur = cur->next;
13848
0
  }
13849
0
  newDoc->children->children = NULL;
13850
0
    }
13851
13852
0
    if (sax != NULL)
13853
0
  ctxt->sax = oldsax;
13854
0
    xmlFreeParserCtxt(ctxt);
13855
0
    newDoc->intSubset = NULL;
13856
0
    newDoc->extSubset = NULL;
13857
    /* This leaks the namespace list if doc == NULL */
13858
0
    newDoc->oldNs = NULL;
13859
0
    xmlFreeDoc(newDoc);
13860
13861
0
    return(ret);
13862
0
}
13863
13864
/**
13865
 * xmlSAXParseEntity:
13866
 * @sax:  the SAX handler block
13867
 * @filename:  the filename
13868
 *
13869
 * parse an XML external entity out of context and build a tree.
13870
 * It use the given SAX function block to handle the parsing callback.
13871
 * If sax is NULL, fallback to the default DOM tree building routines.
13872
 *
13873
 * [78] extParsedEnt ::= TextDecl? content
13874
 *
13875
 * This correspond to a "Well Balanced" chunk
13876
 *
13877
 * Returns the resulting document tree
13878
 */
13879
13880
xmlDocPtr
13881
0
xmlSAXParseEntity(xmlSAXHandlerPtr sax, const char *filename) {
13882
0
    xmlDocPtr ret;
13883
0
    xmlParserCtxtPtr ctxt;
13884
13885
0
    ctxt = xmlCreateFileParserCtxt(filename);
13886
0
    if (ctxt == NULL) {
13887
0
  return(NULL);
13888
0
    }
13889
0
    if (sax != NULL) {
13890
0
  if (ctxt->sax != NULL)
13891
0
      xmlFree(ctxt->sax);
13892
0
        ctxt->sax = sax;
13893
0
        ctxt->userData = NULL;
13894
0
    }
13895
13896
0
    xmlParseExtParsedEnt(ctxt);
13897
13898
0
    if (ctxt->wellFormed)
13899
0
  ret = ctxt->myDoc;
13900
0
    else {
13901
0
        ret = NULL;
13902
0
        xmlFreeDoc(ctxt->myDoc);
13903
0
        ctxt->myDoc = NULL;
13904
0
    }
13905
0
    if (sax != NULL)
13906
0
        ctxt->sax = NULL;
13907
0
    xmlFreeParserCtxt(ctxt);
13908
13909
0
    return(ret);
13910
0
}
13911
13912
/**
13913
 * xmlParseEntity:
13914
 * @filename:  the filename
13915
 *
13916
 * parse an XML external entity out of context and build a tree.
13917
 *
13918
 * [78] extParsedEnt ::= TextDecl? content
13919
 *
13920
 * This correspond to a "Well Balanced" chunk
13921
 *
13922
 * Returns the resulting document tree
13923
 */
13924
13925
xmlDocPtr
13926
0
xmlParseEntity(const char *filename) {
13927
0
    return(xmlSAXParseEntity(NULL, filename));
13928
0
}
13929
#endif /* LIBXML_SAX1_ENABLED */
13930
13931
/**
13932
 * xmlCreateEntityParserCtxtInternal:
13933
 * @URL:  the entity URL
13934
 * @ID:  the entity PUBLIC ID
13935
 * @base:  a possible base for the target URI
13936
 * @pctx:  parser context used to set options on new context
13937
 *
13938
 * Create a parser context for an external entity
13939
 * Automatic support for ZLIB/Compress compressed document is provided
13940
 * by default if found at compile-time.
13941
 *
13942
 * Returns the new parser context or NULL
13943
 */
13944
static xmlParserCtxtPtr
13945
xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
13946
0
                    const xmlChar *base, xmlParserCtxtPtr pctx) {
13947
0
    xmlParserCtxtPtr ctxt;
13948
0
    xmlParserInputPtr inputStream;
13949
0
    char *directory = NULL;
13950
0
    xmlChar *uri;
13951
13952
0
    ctxt = xmlNewParserCtxt();
13953
0
    if (ctxt == NULL) {
13954
0
  return(NULL);
13955
0
    }
13956
13957
0
    if (pctx != NULL) {
13958
0
        ctxt->options = pctx->options;
13959
0
        ctxt->_private = pctx->_private;
13960
  /*
13961
   * this is a subparser of pctx, so the input_id should be
13962
   * incremented to distinguish from main entity
13963
   */
13964
0
  ctxt->input_id = pctx->input_id + 1;
13965
0
    }
13966
13967
    /* Don't read from stdin. */
13968
0
    if (xmlStrcmp(URL, BAD_CAST "-") == 0)
13969
0
        URL = BAD_CAST "./-";
13970
13971
0
    uri = xmlBuildURI(URL, base);
13972
13973
0
    if (uri == NULL) {
13974
0
  inputStream = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt);
13975
0
  if (inputStream == NULL) {
13976
0
      xmlFreeParserCtxt(ctxt);
13977
0
      return(NULL);
13978
0
  }
13979
13980
0
  inputPush(ctxt, inputStream);
13981
13982
0
  if ((ctxt->directory == NULL) && (directory == NULL))
13983
0
      directory = xmlParserGetDirectory((char *)URL);
13984
0
  if ((ctxt->directory == NULL) && (directory != NULL))
13985
0
      ctxt->directory = directory;
13986
0
    } else {
13987
0
  inputStream = xmlLoadExternalEntity((char *)uri, (char *)ID, ctxt);
13988
0
  if (inputStream == NULL) {
13989
0
      xmlFree(uri);
13990
0
      xmlFreeParserCtxt(ctxt);
13991
0
      return(NULL);
13992
0
  }
13993
13994
0
  inputPush(ctxt, inputStream);
13995
13996
0
  if ((ctxt->directory == NULL) && (directory == NULL))
13997
0
      directory = xmlParserGetDirectory((char *)uri);
13998
0
  if ((ctxt->directory == NULL) && (directory != NULL))
13999
0
      ctxt->directory = directory;
14000
0
  xmlFree(uri);
14001
0
    }
14002
0
    return(ctxt);
14003
0
}
14004
14005
/**
14006
 * xmlCreateEntityParserCtxt:
14007
 * @URL:  the entity URL
14008
 * @ID:  the entity PUBLIC ID
14009
 * @base:  a possible base for the target URI
14010
 *
14011
 * Create a parser context for an external entity
14012
 * Automatic support for ZLIB/Compress compressed document is provided
14013
 * by default if found at compile-time.
14014
 *
14015
 * Returns the new parser context or NULL
14016
 */
14017
xmlParserCtxtPtr
14018
xmlCreateEntityParserCtxt(const xmlChar *URL, const xmlChar *ID,
14019
0
                    const xmlChar *base) {
14020
0
    return xmlCreateEntityParserCtxtInternal(URL, ID, base, NULL);
14021
14022
0
}
14023
14024
/************************************************************************
14025
 *                  *
14026
 *    Front ends when parsing from a file     *
14027
 *                  *
14028
 ************************************************************************/
14029
14030
/**
14031
 * xmlCreateURLParserCtxt:
14032
 * @filename:  the filename or URL
14033
 * @options:  a combination of xmlParserOption
14034
 *
14035
 * Create a parser context for a file or URL content.
14036
 * Automatic support for ZLIB/Compress compressed document is provided
14037
 * by default if found at compile-time and for file accesses
14038
 *
14039
 * Returns the new parser context or NULL
14040
 */
14041
xmlParserCtxtPtr
14042
xmlCreateURLParserCtxt(const char *filename, int options)
14043
0
{
14044
0
    xmlParserCtxtPtr ctxt;
14045
0
    xmlParserInputPtr inputStream;
14046
0
    char *directory = NULL;
14047
14048
0
    ctxt = xmlNewParserCtxt();
14049
0
    if (ctxt == NULL) {
14050
0
  xmlErrMemory(NULL, "cannot allocate parser context");
14051
0
  return(NULL);
14052
0
    }
14053
14054
0
    if (options)
14055
0
  xmlCtxtUseOptionsInternal(ctxt, options, NULL);
14056
0
    ctxt->linenumbers = 1;
14057
14058
0
    inputStream = xmlLoadExternalEntity(filename, NULL, ctxt);
14059
0
    if (inputStream == NULL) {
14060
0
  xmlFreeParserCtxt(ctxt);
14061
0
  return(NULL);
14062
0
    }
14063
14064
0
    inputPush(ctxt, inputStream);
14065
0
    if ((ctxt->directory == NULL) && (directory == NULL))
14066
0
        directory = xmlParserGetDirectory(filename);
14067
0
    if ((ctxt->directory == NULL) && (directory != NULL))
14068
0
        ctxt->directory = directory;
14069
14070
0
    return(ctxt);
14071
0
}
14072
14073
/**
14074
 * xmlCreateFileParserCtxt:
14075
 * @filename:  the filename
14076
 *
14077
 * Create a parser context for a file content.
14078
 * Automatic support for ZLIB/Compress compressed document is provided
14079
 * by default if found at compile-time.
14080
 *
14081
 * Returns the new parser context or NULL
14082
 */
14083
xmlParserCtxtPtr
14084
xmlCreateFileParserCtxt(const char *filename)
14085
0
{
14086
0
    return(xmlCreateURLParserCtxt(filename, 0));
14087
0
}
14088
14089
#ifdef LIBXML_SAX1_ENABLED
14090
/**
14091
 * xmlSAXParseFileWithData:
14092
 * @sax:  the SAX handler block
14093
 * @filename:  the filename
14094
 * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
14095
 *             documents
14096
 * @data:  the userdata
14097
 *
14098
 * parse an XML file and build a tree. Automatic support for ZLIB/Compress
14099
 * compressed document is provided by default if found at compile-time.
14100
 * It use the given SAX function block to handle the parsing callback.
14101
 * If sax is NULL, fallback to the default DOM tree building routines.
14102
 *
14103
 * User data (void *) is stored within the parser context in the
14104
 * context's _private member, so it is available nearly everywhere in libxml
14105
 *
14106
 * Returns the resulting document tree
14107
 */
14108
14109
xmlDocPtr
14110
xmlSAXParseFileWithData(xmlSAXHandlerPtr sax, const char *filename,
14111
0
                        int recovery, void *data) {
14112
0
    xmlDocPtr ret;
14113
0
    xmlParserCtxtPtr ctxt;
14114
14115
0
    xmlInitParser();
14116
14117
0
    ctxt = xmlCreateFileParserCtxt(filename);
14118
0
    if (ctxt == NULL) {
14119
0
  return(NULL);
14120
0
    }
14121
0
    if (sax != NULL) {
14122
0
  if (ctxt->sax != NULL)
14123
0
      xmlFree(ctxt->sax);
14124
0
        ctxt->sax = sax;
14125
0
    }
14126
0
    xmlDetectSAX2(ctxt);
14127
0
    if (data!=NULL) {
14128
0
  ctxt->_private = data;
14129
0
    }
14130
14131
0
    if (ctxt->directory == NULL)
14132
0
        ctxt->directory = xmlParserGetDirectory(filename);
14133
14134
0
    ctxt->recovery = recovery;
14135
14136
0
    xmlParseDocument(ctxt);
14137
14138
0
    if ((ctxt->wellFormed) || recovery) {
14139
0
        ret = ctxt->myDoc;
14140
0
  if ((ret != NULL) && (ctxt->input->buf != NULL)) {
14141
0
      if (ctxt->input->buf->compressed > 0)
14142
0
    ret->compression = 9;
14143
0
      else
14144
0
    ret->compression = ctxt->input->buf->compressed;
14145
0
  }
14146
0
    }
14147
0
    else {
14148
0
       ret = NULL;
14149
0
       xmlFreeDoc(ctxt->myDoc);
14150
0
       ctxt->myDoc = NULL;
14151
0
    }
14152
0
    if (sax != NULL)
14153
0
        ctxt->sax = NULL;
14154
0
    xmlFreeParserCtxt(ctxt);
14155
14156
0
    return(ret);
14157
0
}
14158
14159
/**
14160
 * xmlSAXParseFile:
14161
 * @sax:  the SAX handler block
14162
 * @filename:  the filename
14163
 * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
14164
 *             documents
14165
 *
14166
 * parse an XML file and build a tree. Automatic support for ZLIB/Compress
14167
 * compressed document is provided by default if found at compile-time.
14168
 * It use the given SAX function block to handle the parsing callback.
14169
 * If sax is NULL, fallback to the default DOM tree building routines.
14170
 *
14171
 * Returns the resulting document tree
14172
 */
14173
14174
xmlDocPtr
14175
xmlSAXParseFile(xmlSAXHandlerPtr sax, const char *filename,
14176
0
                          int recovery) {
14177
0
    return(xmlSAXParseFileWithData(sax,filename,recovery,NULL));
14178
0
}
14179
14180
/**
14181
 * xmlRecoverDoc:
14182
 * @cur:  a pointer to an array of xmlChar
14183
 *
14184
 * parse an XML in-memory document and build a tree.
14185
 * In the case the document is not Well Formed, a attempt to build a
14186
 * tree is tried anyway
14187
 *
14188
 * Returns the resulting document tree or NULL in case of failure
14189
 */
14190
14191
xmlDocPtr
14192
0
xmlRecoverDoc(const xmlChar *cur) {
14193
0
    return(xmlSAXParseDoc(NULL, cur, 1));
14194
0
}
14195
14196
/**
14197
 * xmlParseFile:
14198
 * @filename:  the filename
14199
 *
14200
 * parse an XML file and build a tree. Automatic support for ZLIB/Compress
14201
 * compressed document is provided by default if found at compile-time.
14202
 *
14203
 * Returns the resulting document tree if the file was wellformed,
14204
 * NULL otherwise.
14205
 */
14206
14207
xmlDocPtr
14208
0
xmlParseFile(const char *filename) {
14209
0
    return(xmlSAXParseFile(NULL, filename, 0));
14210
0
}
14211
14212
/**
14213
 * xmlRecoverFile:
14214
 * @filename:  the filename
14215
 *
14216
 * parse an XML file and build a tree. Automatic support for ZLIB/Compress
14217
 * compressed document is provided by default if found at compile-time.
14218
 * In the case the document is not Well Formed, it attempts to build
14219
 * a tree anyway
14220
 *
14221
 * Returns the resulting document tree or NULL in case of failure
14222
 */
14223
14224
xmlDocPtr
14225
0
xmlRecoverFile(const char *filename) {
14226
0
    return(xmlSAXParseFile(NULL, filename, 1));
14227
0
}
14228
14229
14230
/**
14231
 * xmlSetupParserForBuffer:
14232
 * @ctxt:  an XML parser context
14233
 * @buffer:  a xmlChar * buffer
14234
 * @filename:  a file name
14235
 *
14236
 * Setup the parser context to parse a new buffer; Clears any prior
14237
 * contents from the parser context. The buffer parameter must not be
14238
 * NULL, but the filename parameter can be
14239
 */
14240
void
14241
xmlSetupParserForBuffer(xmlParserCtxtPtr ctxt, const xmlChar* buffer,
14242
                             const char* filename)
14243
0
{
14244
0
    xmlParserInputPtr input;
14245
14246
0
    if ((ctxt == NULL) || (buffer == NULL))
14247
0
        return;
14248
14249
0
    input = xmlNewInputStream(ctxt);
14250
0
    if (input == NULL) {
14251
0
        xmlErrMemory(NULL, "parsing new buffer: out of memory\n");
14252
0
        xmlClearParserCtxt(ctxt);
14253
0
        return;
14254
0
    }
14255
14256
0
    xmlClearParserCtxt(ctxt);
14257
0
    if (filename != NULL)
14258
0
        input->filename = (char *) xmlCanonicPath((const xmlChar *)filename);
14259
0
    input->base = buffer;
14260
0
    input->cur = buffer;
14261
0
    input->end = &buffer[xmlStrlen(buffer)];
14262
0
    inputPush(ctxt, input);
14263
0
}
14264
14265
/**
14266
 * xmlSAXUserParseFile:
14267
 * @sax:  a SAX handler
14268
 * @user_data:  The user data returned on SAX callbacks
14269
 * @filename:  a file name
14270
 *
14271
 * parse an XML file and call the given SAX handler routines.
14272
 * Automatic support for ZLIB/Compress compressed document is provided
14273
 *
14274
 * Returns 0 in case of success or a error number otherwise
14275
 */
14276
int
14277
xmlSAXUserParseFile(xmlSAXHandlerPtr sax, void *user_data,
14278
0
                    const char *filename) {
14279
0
    int ret = 0;
14280
0
    xmlParserCtxtPtr ctxt;
14281
14282
0
    ctxt = xmlCreateFileParserCtxt(filename);
14283
0
    if (ctxt == NULL) return -1;
14284
0
    if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
14285
0
  xmlFree(ctxt->sax);
14286
0
    ctxt->sax = sax;
14287
0
    xmlDetectSAX2(ctxt);
14288
14289
0
    if (user_data != NULL)
14290
0
  ctxt->userData = user_data;
14291
14292
0
    xmlParseDocument(ctxt);
14293
14294
0
    if (ctxt->wellFormed)
14295
0
  ret = 0;
14296
0
    else {
14297
0
        if (ctxt->errNo != 0)
14298
0
      ret = ctxt->errNo;
14299
0
  else
14300
0
      ret = -1;
14301
0
    }
14302
0
    if (sax != NULL)
14303
0
  ctxt->sax = NULL;
14304
0
    if (ctxt->myDoc != NULL) {
14305
0
        xmlFreeDoc(ctxt->myDoc);
14306
0
  ctxt->myDoc = NULL;
14307
0
    }
14308
0
    xmlFreeParserCtxt(ctxt);
14309
14310
0
    return ret;
14311
0
}
14312
#endif /* LIBXML_SAX1_ENABLED */
14313
14314
/************************************************************************
14315
 *                  *
14316
 *    Front ends when parsing from memory     *
14317
 *                  *
14318
 ************************************************************************/
14319
14320
/**
14321
 * xmlCreateMemoryParserCtxt:
14322
 * @buffer:  a pointer to a char array
14323
 * @size:  the size of the array
14324
 *
14325
 * Create a parser context for an XML in-memory document.
14326
 *
14327
 * Returns the new parser context or NULL
14328
 */
14329
xmlParserCtxtPtr
14330
451k
xmlCreateMemoryParserCtxt(const char *buffer, int size) {
14331
451k
    xmlParserCtxtPtr ctxt;
14332
451k
    xmlParserInputPtr input;
14333
451k
    xmlParserInputBufferPtr buf;
14334
14335
451k
    if (buffer == NULL)
14336
0
  return(NULL);
14337
451k
    if (size <= 0)
14338
131k
  return(NULL);
14339
14340
319k
    ctxt = xmlNewParserCtxt();
14341
319k
    if (ctxt == NULL)
14342
0
  return(NULL);
14343
14344
    /* TODO: xmlParserInputBufferCreateStatic, requires some serious changes */
14345
319k
    buf = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
14346
319k
    if (buf == NULL) {
14347
0
  xmlFreeParserCtxt(ctxt);
14348
0
  return(NULL);
14349
0
    }
14350
14351
319k
    input = xmlNewInputStream(ctxt);
14352
319k
    if (input == NULL) {
14353
0
  xmlFreeParserInputBuffer(buf);
14354
0
  xmlFreeParserCtxt(ctxt);
14355
0
  return(NULL);
14356
0
    }
14357
14358
319k
    input->filename = NULL;
14359
319k
    input->buf = buf;
14360
319k
    xmlBufResetInput(input->buf->buffer, input);
14361
14362
319k
    inputPush(ctxt, input);
14363
319k
    return(ctxt);
14364
319k
}
14365
14366
#ifdef LIBXML_SAX1_ENABLED
14367
/**
14368
 * xmlSAXParseMemoryWithData:
14369
 * @sax:  the SAX handler block
14370
 * @buffer:  an pointer to a char array
14371
 * @size:  the size of the array
14372
 * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
14373
 *             documents
14374
 * @data:  the userdata
14375
 *
14376
 * parse an XML in-memory block and use the given SAX function block
14377
 * to handle the parsing callback. If sax is NULL, fallback to the default
14378
 * DOM tree building routines.
14379
 *
14380
 * User data (void *) is stored within the parser context in the
14381
 * context's _private member, so it is available nearly everywhere in libxml
14382
 *
14383
 * Returns the resulting document tree
14384
 */
14385
14386
xmlDocPtr
14387
xmlSAXParseMemoryWithData(xmlSAXHandlerPtr sax, const char *buffer,
14388
0
            int size, int recovery, void *data) {
14389
0
    xmlDocPtr ret;
14390
0
    xmlParserCtxtPtr ctxt;
14391
14392
0
    xmlInitParser();
14393
14394
0
    ctxt = xmlCreateMemoryParserCtxt(buffer, size);
14395
0
    if (ctxt == NULL) return(NULL);
14396
0
    if (sax != NULL) {
14397
0
  if (ctxt->sax != NULL)
14398
0
      xmlFree(ctxt->sax);
14399
0
        ctxt->sax = sax;
14400
0
    }
14401
0
    xmlDetectSAX2(ctxt);
14402
0
    if (data!=NULL) {
14403
0
  ctxt->_private=data;
14404
0
    }
14405
14406
0
    ctxt->recovery = recovery;
14407
14408
0
    xmlParseDocument(ctxt);
14409
14410
0
    if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
14411
0
    else {
14412
0
       ret = NULL;
14413
0
       xmlFreeDoc(ctxt->myDoc);
14414
0
       ctxt->myDoc = NULL;
14415
0
    }
14416
0
    if (sax != NULL)
14417
0
  ctxt->sax = NULL;
14418
0
    xmlFreeParserCtxt(ctxt);
14419
14420
0
    return(ret);
14421
0
}
14422
14423
/**
14424
 * xmlSAXParseMemory:
14425
 * @sax:  the SAX handler block
14426
 * @buffer:  an pointer to a char array
14427
 * @size:  the size of the array
14428
 * @recovery:  work in recovery mode, i.e. tries to read not Well Formed
14429
 *             documents
14430
 *
14431
 * parse an XML in-memory block and use the given SAX function block
14432
 * to handle the parsing callback. If sax is NULL, fallback to the default
14433
 * DOM tree building routines.
14434
 *
14435
 * Returns the resulting document tree
14436
 */
14437
xmlDocPtr
14438
xmlSAXParseMemory(xmlSAXHandlerPtr sax, const char *buffer,
14439
0
            int size, int recovery) {
14440
0
    return xmlSAXParseMemoryWithData(sax, buffer, size, recovery, NULL);
14441
0
}
14442
14443
/**
14444
 * xmlParseMemory:
14445
 * @buffer:  an pointer to a char array
14446
 * @size:  the size of the array
14447
 *
14448
 * parse an XML in-memory block and build a tree.
14449
 *
14450
 * Returns the resulting document tree
14451
 */
14452
14453
0
xmlDocPtr xmlParseMemory(const char *buffer, int size) {
14454
0
   return(xmlSAXParseMemory(NULL, buffer, size, 0));
14455
0
}
14456
14457
/**
14458
 * xmlRecoverMemory:
14459
 * @buffer:  an pointer to a char array
14460
 * @size:  the size of the array
14461
 *
14462
 * parse an XML in-memory block and build a tree.
14463
 * In the case the document is not Well Formed, an attempt to
14464
 * build a tree is tried anyway
14465
 *
14466
 * Returns the resulting document tree or NULL in case of error
14467
 */
14468
14469
0
xmlDocPtr xmlRecoverMemory(const char *buffer, int size) {
14470
0
   return(xmlSAXParseMemory(NULL, buffer, size, 1));
14471
0
}
14472
14473
/**
14474
 * xmlSAXUserParseMemory:
14475
 * @sax:  a SAX handler
14476
 * @user_data:  The user data returned on SAX callbacks
14477
 * @buffer:  an in-memory XML document input
14478
 * @size:  the length of the XML document in bytes
14479
 *
14480
 * A better SAX parsing routine.
14481
 * parse an XML in-memory buffer and call the given SAX handler routines.
14482
 *
14483
 * Returns 0 in case of success or a error number otherwise
14484
 */
14485
int xmlSAXUserParseMemory(xmlSAXHandlerPtr sax, void *user_data,
14486
0
        const char *buffer, int size) {
14487
0
    int ret = 0;
14488
0
    xmlParserCtxtPtr ctxt;
14489
14490
0
    xmlInitParser();
14491
14492
0
    ctxt = xmlCreateMemoryParserCtxt(buffer, size);
14493
0
    if (ctxt == NULL) return -1;
14494
0
    if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
14495
0
        xmlFree(ctxt->sax);
14496
0
    ctxt->sax = sax;
14497
0
    xmlDetectSAX2(ctxt);
14498
14499
0
    if (user_data != NULL)
14500
0
  ctxt->userData = user_data;
14501
14502
0
    xmlParseDocument(ctxt);
14503
14504
0
    if (ctxt->wellFormed)
14505
0
  ret = 0;
14506
0
    else {
14507
0
        if (ctxt->errNo != 0)
14508
0
      ret = ctxt->errNo;
14509
0
  else
14510
0
      ret = -1;
14511
0
    }
14512
0
    if (sax != NULL)
14513
0
        ctxt->sax = NULL;
14514
0
    if (ctxt->myDoc != NULL) {
14515
0
        xmlFreeDoc(ctxt->myDoc);
14516
0
  ctxt->myDoc = NULL;
14517
0
    }
14518
0
    xmlFreeParserCtxt(ctxt);
14519
14520
0
    return ret;
14521
0
}
14522
#endif /* LIBXML_SAX1_ENABLED */
14523
14524
/**
14525
 * xmlCreateDocParserCtxt:
14526
 * @cur:  a pointer to an array of xmlChar
14527
 *
14528
 * Creates a parser context for an XML in-memory document.
14529
 *
14530
 * Returns the new parser context or NULL
14531
 */
14532
xmlParserCtxtPtr
14533
0
xmlCreateDocParserCtxt(const xmlChar *cur) {
14534
0
    int len;
14535
14536
0
    if (cur == NULL)
14537
0
  return(NULL);
14538
0
    len = xmlStrlen(cur);
14539
0
    return(xmlCreateMemoryParserCtxt((const char *)cur, len));
14540
0
}
14541
14542
#ifdef LIBXML_SAX1_ENABLED
14543
/**
14544
 * xmlSAXParseDoc:
14545
 * @sax:  the SAX handler block
14546
 * @cur:  a pointer to an array of xmlChar
14547
 * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
14548
 *             documents
14549
 *
14550
 * parse an XML in-memory document and build a tree.
14551
 * It use the given SAX function block to handle the parsing callback.
14552
 * If sax is NULL, fallback to the default DOM tree building routines.
14553
 *
14554
 * Returns the resulting document tree
14555
 */
14556
14557
xmlDocPtr
14558
0
xmlSAXParseDoc(xmlSAXHandlerPtr sax, const xmlChar *cur, int recovery) {
14559
0
    xmlDocPtr ret;
14560
0
    xmlParserCtxtPtr ctxt;
14561
0
    xmlSAXHandlerPtr oldsax = NULL;
14562
14563
0
    if (cur == NULL) return(NULL);
14564
14565
14566
0
    ctxt = xmlCreateDocParserCtxt(cur);
14567
0
    if (ctxt == NULL) return(NULL);
14568
0
    if (sax != NULL) {
14569
0
        oldsax = ctxt->sax;
14570
0
        ctxt->sax = sax;
14571
0
        ctxt->userData = NULL;
14572
0
    }
14573
0
    xmlDetectSAX2(ctxt);
14574
14575
0
    xmlParseDocument(ctxt);
14576
0
    if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
14577
0
    else {
14578
0
       ret = NULL;
14579
0
       xmlFreeDoc(ctxt->myDoc);
14580
0
       ctxt->myDoc = NULL;
14581
0
    }
14582
0
    if (sax != NULL)
14583
0
  ctxt->sax = oldsax;
14584
0
    xmlFreeParserCtxt(ctxt);
14585
14586
0
    return(ret);
14587
0
}
14588
14589
/**
14590
 * xmlParseDoc:
14591
 * @cur:  a pointer to an array of xmlChar
14592
 *
14593
 * parse an XML in-memory document and build a tree.
14594
 *
14595
 * Returns the resulting document tree
14596
 */
14597
14598
xmlDocPtr
14599
0
xmlParseDoc(const xmlChar *cur) {
14600
0
    return(xmlSAXParseDoc(NULL, cur, 0));
14601
0
}
14602
#endif /* LIBXML_SAX1_ENABLED */
14603
14604
#ifdef LIBXML_LEGACY_ENABLED
14605
/************************************************************************
14606
 *                  *
14607
 *  Specific function to keep track of entities references    *
14608
 *  and used by the XSLT debugger         *
14609
 *                  *
14610
 ************************************************************************/
14611
14612
static xmlEntityReferenceFunc xmlEntityRefFunc = NULL;
14613
14614
/**
14615
 * xmlAddEntityReference:
14616
 * @ent : A valid entity
14617
 * @firstNode : A valid first node for children of entity
14618
 * @lastNode : A valid last node of children entity
14619
 *
14620
 * Notify of a reference to an entity of type XML_EXTERNAL_GENERAL_PARSED_ENTITY
14621
 */
14622
static void
14623
xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
14624
                      xmlNodePtr lastNode)
14625
{
14626
    if (xmlEntityRefFunc != NULL) {
14627
        (*xmlEntityRefFunc) (ent, firstNode, lastNode);
14628
    }
14629
}
14630
14631
14632
/**
14633
 * xmlSetEntityReferenceFunc:
14634
 * @func: A valid function
14635
 *
14636
 * Set the function to call call back when a xml reference has been made
14637
 */
14638
void
14639
xmlSetEntityReferenceFunc(xmlEntityReferenceFunc func)
14640
{
14641
    xmlEntityRefFunc = func;
14642
}
14643
#endif /* LIBXML_LEGACY_ENABLED */
14644
14645
/************************************************************************
14646
 *                  *
14647
 *        Miscellaneous       *
14648
 *                  *
14649
 ************************************************************************/
14650
14651
#ifdef LIBXML_XPATH_ENABLED
14652
#include <libxml/xpath.h>
14653
#endif
14654
14655
extern void XMLCDECL xmlGenericErrorDefaultFunc(void *ctx, const char *msg, ...);
14656
static int xmlParserInitialized = 0;
14657
14658
/**
14659
 * xmlInitParser:
14660
 *
14661
 * Initialization function for the XML parser.
14662
 * This is not reentrant. Call once before processing in case of
14663
 * use in multithreaded programs.
14664
 */
14665
14666
void
14667
338k
xmlInitParser(void) {
14668
338k
    if (xmlParserInitialized != 0)
14669
338k
  return;
14670
14671
#if defined(_WIN32) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
14672
    if (xmlFree == free)
14673
        atexit(xmlCleanupParser);
14674
#endif
14675
14676
1
#ifdef LIBXML_THREAD_ENABLED
14677
1
    __xmlGlobalInitMutexLock();
14678
1
    if (xmlParserInitialized == 0) {
14679
1
#endif
14680
1
  xmlInitThreads();
14681
1
  xmlInitGlobals();
14682
1
  if ((xmlGenericError == xmlGenericErrorDefaultFunc) ||
14683
1
      (xmlGenericError == NULL))
14684
0
      initGenericErrorDefaultFunc(NULL);
14685
1
  xmlInitMemory();
14686
1
        xmlInitializeDict();
14687
1
  xmlInitCharEncodingHandlers();
14688
1
  xmlDefaultSAXHandlerInit();
14689
1
  xmlRegisterDefaultInputCallbacks();
14690
1
#ifdef LIBXML_OUTPUT_ENABLED
14691
1
  xmlRegisterDefaultOutputCallbacks();
14692
1
#endif /* LIBXML_OUTPUT_ENABLED */
14693
1
#ifdef LIBXML_HTML_ENABLED
14694
1
  htmlInitAutoClose();
14695
1
  htmlDefaultSAXHandlerInit();
14696
1
#endif
14697
1
#ifdef LIBXML_XPATH_ENABLED
14698
1
  xmlXPathInit();
14699
1
#endif
14700
1
  xmlParserInitialized = 1;
14701
1
#ifdef LIBXML_THREAD_ENABLED
14702
1
    }
14703
1
    __xmlGlobalInitMutexUnlock();
14704
1
#endif
14705
1
}
14706
14707
/**
14708
 * xmlCleanupParser:
14709
 *
14710
 * This function name is somewhat misleading. It does not clean up
14711
 * parser state, it cleans up memory allocated by the library itself.
14712
 * It is a cleanup function for the XML library. It tries to reclaim all
14713
 * related global memory allocated for the library processing.
14714
 * It doesn't deallocate any document related memory. One should
14715
 * call xmlCleanupParser() only when the process has finished using
14716
 * the library and all XML/HTML documents built with it.
14717
 * See also xmlInitParser() which has the opposite function of preparing
14718
 * the library for operations.
14719
 *
14720
 * WARNING: if your application is multithreaded or has plugin support
14721
 *          calling this may crash the application if another thread or
14722
 *          a plugin is still using libxml2. It's sometimes very hard to
14723
 *          guess if libxml2 is in use in the application, some libraries
14724
 *          or plugins may use it without notice. In case of doubt abstain
14725
 *          from calling this function or do it just before calling exit()
14726
 *          to avoid leak reports from valgrind !
14727
 */
14728
14729
void
14730
0
xmlCleanupParser(void) {
14731
0
    if (!xmlParserInitialized)
14732
0
  return;
14733
14734
0
    xmlCleanupCharEncodingHandlers();
14735
0
#ifdef LIBXML_CATALOG_ENABLED
14736
0
    xmlCatalogCleanup();
14737
0
#endif
14738
0
    xmlDictCleanup();
14739
0
    xmlCleanupInputCallbacks();
14740
0
#ifdef LIBXML_OUTPUT_ENABLED
14741
0
    xmlCleanupOutputCallbacks();
14742
0
#endif
14743
0
#ifdef LIBXML_SCHEMAS_ENABLED
14744
0
    xmlSchemaCleanupTypes();
14745
0
    xmlRelaxNGCleanupTypes();
14746
0
#endif
14747
0
    xmlCleanupGlobals();
14748
0
    xmlCleanupThreads(); /* must be last if called not from the main thread */
14749
0
    xmlCleanupMemory();
14750
0
    xmlParserInitialized = 0;
14751
0
}
14752
14753
#if defined(HAVE_ATTRIBUTE_DESTRUCTOR) && !defined(LIBXML_STATIC) && \
14754
    !defined(_WIN32)
14755
static void
14756
ATTRIBUTE_DESTRUCTOR
14757
xmlDestructor(void) {
14758
    /*
14759
     * Calling custom deallocation functions in a destructor can cause
14760
     * problems, for example with Nokogiri.
14761
     */
14762
    if (xmlFree == free)
14763
        xmlCleanupParser();
14764
}
14765
#endif
14766
14767
/************************************************************************
14768
 *                  *
14769
 *  New set (2.6.0) of simpler and more flexible APIs   *
14770
 *                  *
14771
 ************************************************************************/
14772
14773
/**
14774
 * DICT_FREE:
14775
 * @str:  a string
14776
 *
14777
 * Free a string if it is not owned by the "dict" dictionary in the
14778
 * current scope
14779
 */
14780
#define DICT_FREE(str)            \
14781
0
  if ((str) && ((!dict) ||       \
14782
0
      (xmlDictOwns(dict, (const xmlChar *)(str)) == 0)))  \
14783
0
      xmlFree((char *)(str));
14784
14785
/**
14786
 * xmlCtxtReset:
14787
 * @ctxt: an XML parser context
14788
 *
14789
 * Reset a parser context
14790
 */
14791
void
14792
xmlCtxtReset(xmlParserCtxtPtr ctxt)
14793
0
{
14794
0
    xmlParserInputPtr input;
14795
0
    xmlDictPtr dict;
14796
14797
0
    if (ctxt == NULL)
14798
0
        return;
14799
14800
0
    dict = ctxt->dict;
14801
14802
0
    while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
14803
0
        xmlFreeInputStream(input);
14804
0
    }
14805
0
    ctxt->inputNr = 0;
14806
0
    ctxt->input = NULL;
14807
14808
0
    ctxt->spaceNr = 0;
14809
0
    if (ctxt->spaceTab != NULL) {
14810
0
  ctxt->spaceTab[0] = -1;
14811
0
  ctxt->space = &ctxt->spaceTab[0];
14812
0
    } else {
14813
0
        ctxt->space = NULL;
14814
0
    }
14815
14816
14817
0
    ctxt->nodeNr = 0;
14818
0
    ctxt->node = NULL;
14819
14820
0
    ctxt->nameNr = 0;
14821
0
    ctxt->name = NULL;
14822
14823
0
    DICT_FREE(ctxt->version);
14824
0
    ctxt->version = NULL;
14825
0
    DICT_FREE(ctxt->encoding);
14826
0
    ctxt->encoding = NULL;
14827
0
    DICT_FREE(ctxt->directory);
14828
0
    ctxt->directory = NULL;
14829
0
    DICT_FREE(ctxt->extSubURI);
14830
0
    ctxt->extSubURI = NULL;
14831
0
    DICT_FREE(ctxt->extSubSystem);
14832
0
    ctxt->extSubSystem = NULL;
14833
0
    if (ctxt->myDoc != NULL)
14834
0
        xmlFreeDoc(ctxt->myDoc);
14835
0
    ctxt->myDoc = NULL;
14836
14837
0
    ctxt->standalone = -1;
14838
0
    ctxt->hasExternalSubset = 0;
14839
0
    ctxt->hasPErefs = 0;
14840
0
    ctxt->html = 0;
14841
0
    ctxt->external = 0;
14842
0
    ctxt->instate = XML_PARSER_START;
14843
0
    ctxt->token = 0;
14844
14845
0
    ctxt->wellFormed = 1;
14846
0
    ctxt->nsWellFormed = 1;
14847
0
    ctxt->disableSAX = 0;
14848
0
    ctxt->valid = 1;
14849
#if 0
14850
    ctxt->vctxt.userData = ctxt;
14851
    ctxt->vctxt.error = xmlParserValidityError;
14852
    ctxt->vctxt.warning = xmlParserValidityWarning;
14853
#endif
14854
0
    ctxt->record_info = 0;
14855
0
    ctxt->checkIndex = 0;
14856
0
    ctxt->inSubset = 0;
14857
0
    ctxt->errNo = XML_ERR_OK;
14858
0
    ctxt->depth = 0;
14859
0
    ctxt->charset = XML_CHAR_ENCODING_UTF8;
14860
0
    ctxt->catalogs = NULL;
14861
0
    ctxt->nbentities = 0;
14862
0
    ctxt->sizeentities = 0;
14863
0
    ctxt->sizeentcopy = 0;
14864
0
    xmlInitNodeInfoSeq(&ctxt->node_seq);
14865
14866
0
    if (ctxt->attsDefault != NULL) {
14867
0
        xmlHashFree(ctxt->attsDefault, xmlHashDefaultDeallocator);
14868
0
        ctxt->attsDefault = NULL;
14869
0
    }
14870
0
    if (ctxt->attsSpecial != NULL) {
14871
0
        xmlHashFree(ctxt->attsSpecial, NULL);
14872
0
        ctxt->attsSpecial = NULL;
14873
0
    }
14874
14875
0
#ifdef LIBXML_CATALOG_ENABLED
14876
0
    if (ctxt->catalogs != NULL)
14877
0
  xmlCatalogFreeLocal(ctxt->catalogs);
14878
0
#endif
14879
0
    if (ctxt->lastError.code != XML_ERR_OK)
14880
0
        xmlResetError(&ctxt->lastError);
14881
0
}
14882
14883
/**
14884
 * xmlCtxtResetPush:
14885
 * @ctxt: an XML parser context
14886
 * @chunk:  a pointer to an array of chars
14887
 * @size:  number of chars in the array
14888
 * @filename:  an optional file name or URI
14889
 * @encoding:  the document encoding, or NULL
14890
 *
14891
 * Reset a push parser context
14892
 *
14893
 * Returns 0 in case of success and 1 in case of error
14894
 */
14895
int
14896
xmlCtxtResetPush(xmlParserCtxtPtr ctxt, const char *chunk,
14897
                 int size, const char *filename, const char *encoding)
14898
0
{
14899
0
    xmlParserInputPtr inputStream;
14900
0
    xmlParserInputBufferPtr buf;
14901
0
    xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
14902
14903
0
    if (ctxt == NULL)
14904
0
        return(1);
14905
14906
0
    if ((encoding == NULL) && (chunk != NULL) && (size >= 4))
14907
0
        enc = xmlDetectCharEncoding((const xmlChar *) chunk, size);
14908
14909
0
    buf = xmlAllocParserInputBuffer(enc);
14910
0
    if (buf == NULL)
14911
0
        return(1);
14912
14913
0
    if (ctxt == NULL) {
14914
0
        xmlFreeParserInputBuffer(buf);
14915
0
        return(1);
14916
0
    }
14917
14918
0
    xmlCtxtReset(ctxt);
14919
14920
0
    if (filename == NULL) {
14921
0
        ctxt->directory = NULL;
14922
0
    } else {
14923
0
        ctxt->directory = xmlParserGetDirectory(filename);
14924
0
    }
14925
14926
0
    inputStream = xmlNewInputStream(ctxt);
14927
0
    if (inputStream == NULL) {
14928
0
        xmlFreeParserInputBuffer(buf);
14929
0
        return(1);
14930
0
    }
14931
14932
0
    if (filename == NULL)
14933
0
        inputStream->filename = NULL;
14934
0
    else
14935
0
        inputStream->filename = (char *)
14936
0
            xmlCanonicPath((const xmlChar *) filename);
14937
0
    inputStream->buf = buf;
14938
0
    xmlBufResetInput(buf->buffer, inputStream);
14939
14940
0
    inputPush(ctxt, inputStream);
14941
14942
0
    if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
14943
0
        (ctxt->input->buf != NULL)) {
14944
0
  size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer, ctxt->input);
14945
0
        size_t cur = ctxt->input->cur - ctxt->input->base;
14946
14947
0
        xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
14948
14949
0
        xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur);
14950
#ifdef DEBUG_PUSH
14951
        xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
14952
#endif
14953
0
    }
14954
14955
0
    if (encoding != NULL) {
14956
0
        xmlCharEncodingHandlerPtr hdlr;
14957
14958
0
        if (ctxt->encoding != NULL)
14959
0
      xmlFree((xmlChar *) ctxt->encoding);
14960
0
        ctxt->encoding = xmlStrdup((const xmlChar *) encoding);
14961
14962
0
        hdlr = xmlFindCharEncodingHandler(encoding);
14963
0
        if (hdlr != NULL) {
14964
0
            xmlSwitchToEncoding(ctxt, hdlr);
14965
0
  } else {
14966
0
      xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
14967
0
            "Unsupported encoding %s\n", BAD_CAST encoding);
14968
0
        }
14969
0
    } else if (enc != XML_CHAR_ENCODING_NONE) {
14970
0
        xmlSwitchEncoding(ctxt, enc);
14971
0
    }
14972
14973
0
    return(0);
14974
0
}
14975
14976
14977
/**
14978
 * xmlCtxtUseOptionsInternal:
14979
 * @ctxt: an XML parser context
14980
 * @options:  a combination of xmlParserOption
14981
 * @encoding:  the user provided encoding to use
14982
 *
14983
 * Applies the options to the parser context
14984
 *
14985
 * Returns 0 in case of success, the set of unknown or unimplemented options
14986
 *         in case of error.
14987
 */
14988
static int
14989
xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options, const char *encoding)
14990
18.9k
{
14991
18.9k
    if (ctxt == NULL)
14992
0
        return(-1);
14993
18.9k
    if (encoding != NULL) {
14994
0
        if (ctxt->encoding != NULL)
14995
0
      xmlFree((xmlChar *) ctxt->encoding);
14996
0
        ctxt->encoding = xmlStrdup((const xmlChar *) encoding);
14997
0
    }
14998
18.9k
    if (options & XML_PARSE_RECOVER) {
14999
0
        ctxt->recovery = 1;
15000
0
        options -= XML_PARSE_RECOVER;
15001
0
  ctxt->options |= XML_PARSE_RECOVER;
15002
0
    } else
15003
18.9k
        ctxt->recovery = 0;
15004
18.9k
    if (options & XML_PARSE_DTDLOAD) {
15005
0
        ctxt->loadsubset = XML_DETECT_IDS;
15006
0
        options -= XML_PARSE_DTDLOAD;
15007
0
  ctxt->options |= XML_PARSE_DTDLOAD;
15008
0
    } else
15009
18.9k
        ctxt->loadsubset = 0;
15010
18.9k
    if (options & XML_PARSE_DTDATTR) {
15011
0
        ctxt->loadsubset |= XML_COMPLETE_ATTRS;
15012
0
        options -= XML_PARSE_DTDATTR;
15013
0
  ctxt->options |= XML_PARSE_DTDATTR;
15014
0
    }
15015
18.9k
    if (options & XML_PARSE_NOENT) {
15016
0
        ctxt->replaceEntities = 1;
15017
        /* ctxt->loadsubset |= XML_DETECT_IDS; */
15018
0
        options -= XML_PARSE_NOENT;
15019
0
  ctxt->options |= XML_PARSE_NOENT;
15020
0
    } else
15021
18.9k
        ctxt->replaceEntities = 0;
15022
18.9k
    if (options & XML_PARSE_PEDANTIC) {
15023
0
        ctxt->pedantic = 1;
15024
0
        options -= XML_PARSE_PEDANTIC;
15025
0
  ctxt->options |= XML_PARSE_PEDANTIC;
15026
0
    } else
15027
18.9k
        ctxt->pedantic = 0;
15028
18.9k
    if (options & XML_PARSE_NOBLANKS) {
15029
0
        ctxt->keepBlanks = 0;
15030
0
        ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
15031
0
        options -= XML_PARSE_NOBLANKS;
15032
0
  ctxt->options |= XML_PARSE_NOBLANKS;
15033
0
    } else
15034
18.9k
        ctxt->keepBlanks = 1;
15035
18.9k
    if (options & XML_PARSE_DTDVALID) {
15036
0
        ctxt->validate = 1;
15037
0
        if (options & XML_PARSE_NOWARNING)
15038
0
            ctxt->vctxt.warning = NULL;
15039
0
        if (options & XML_PARSE_NOERROR)
15040
0
            ctxt->vctxt.error = NULL;
15041
0
        options -= XML_PARSE_DTDVALID;
15042
0
  ctxt->options |= XML_PARSE_DTDVALID;
15043
0
    } else
15044
18.9k
        ctxt->validate = 0;
15045
18.9k
    if (options & XML_PARSE_NOWARNING) {
15046
0
        ctxt->sax->warning = NULL;
15047
0
        options -= XML_PARSE_NOWARNING;
15048
0
    }
15049
18.9k
    if (options & XML_PARSE_NOERROR) {
15050
0
        ctxt->sax->error = NULL;
15051
0
        ctxt->sax->fatalError = NULL;
15052
0
        options -= XML_PARSE_NOERROR;
15053
0
    }
15054
18.9k
#ifdef LIBXML_SAX1_ENABLED
15055
18.9k
    if (options & XML_PARSE_SAX1) {
15056
0
        ctxt->sax->startElement = xmlSAX2StartElement;
15057
0
        ctxt->sax->endElement = xmlSAX2EndElement;
15058
0
        ctxt->sax->startElementNs = NULL;
15059
0
        ctxt->sax->endElementNs = NULL;
15060
0
        ctxt->sax->initialized = 1;
15061
0
        options -= XML_PARSE_SAX1;
15062
0
  ctxt->options |= XML_PARSE_SAX1;
15063
0
    }
15064
18.9k
#endif /* LIBXML_SAX1_ENABLED */
15065
18.9k
    if (options & XML_PARSE_NODICT) {
15066
18.9k
        ctxt->dictNames = 0;
15067
18.9k
        options -= XML_PARSE_NODICT;
15068
18.9k
  ctxt->options |= XML_PARSE_NODICT;
15069
18.9k
    } else {
15070
0
        ctxt->dictNames = 1;
15071
0
    }
15072
18.9k
    if (options & XML_PARSE_NOCDATA) {
15073
0
        ctxt->sax->cdataBlock = NULL;
15074
0
        options -= XML_PARSE_NOCDATA;
15075
0
  ctxt->options |= XML_PARSE_NOCDATA;
15076
0
    }
15077
18.9k
    if (options & XML_PARSE_NSCLEAN) {
15078
0
  ctxt->options |= XML_PARSE_NSCLEAN;
15079
0
        options -= XML_PARSE_NSCLEAN;
15080
0
    }
15081
18.9k
    if (options & XML_PARSE_NONET) {
15082
18.9k
  ctxt->options |= XML_PARSE_NONET;
15083
18.9k
        options -= XML_PARSE_NONET;
15084
18.9k
    }
15085
18.9k
    if (options & XML_PARSE_COMPACT) {
15086
0
  ctxt->options |= XML_PARSE_COMPACT;
15087
0
        options -= XML_PARSE_COMPACT;
15088
0
    }
15089
18.9k
    if (options & XML_PARSE_OLD10) {
15090
0
  ctxt->options |= XML_PARSE_OLD10;
15091
0
        options -= XML_PARSE_OLD10;
15092
0
    }
15093
18.9k
    if (options & XML_PARSE_NOBASEFIX) {
15094
0
  ctxt->options |= XML_PARSE_NOBASEFIX;
15095
0
        options -= XML_PARSE_NOBASEFIX;
15096
0
    }
15097
18.9k
    if (options & XML_PARSE_HUGE) {
15098
18.9k
  ctxt->options |= XML_PARSE_HUGE;
15099
18.9k
        options -= XML_PARSE_HUGE;
15100
18.9k
        if (ctxt->dict != NULL)
15101
18.9k
            xmlDictSetLimit(ctxt->dict, 0);
15102
18.9k
    }
15103
18.9k
    if (options & XML_PARSE_OLDSAX) {
15104
0
  ctxt->options |= XML_PARSE_OLDSAX;
15105
0
        options -= XML_PARSE_OLDSAX;
15106
0
    }
15107
18.9k
    if (options & XML_PARSE_IGNORE_ENC) {
15108
0
  ctxt->options |= XML_PARSE_IGNORE_ENC;
15109
0
        options -= XML_PARSE_IGNORE_ENC;
15110
0
    }
15111
18.9k
    if (options & XML_PARSE_BIG_LINES) {
15112
0
  ctxt->options |= XML_PARSE_BIG_LINES;
15113
0
        options -= XML_PARSE_BIG_LINES;
15114
0
    }
15115
18.9k
    ctxt->linenumbers = 1;
15116
18.9k
    return (options);
15117
18.9k
}
15118
15119
/**
15120
 * xmlCtxtUseOptions:
15121
 * @ctxt: an XML parser context
15122
 * @options:  a combination of xmlParserOption
15123
 *
15124
 * Applies the options to the parser context
15125
 *
15126
 * Returns 0 in case of success, the set of unknown or unimplemented options
15127
 *         in case of error.
15128
 */
15129
int
15130
xmlCtxtUseOptions(xmlParserCtxtPtr ctxt, int options)
15131
18.9k
{
15132
18.9k
   return(xmlCtxtUseOptionsInternal(ctxt, options, NULL));
15133
18.9k
}
15134
15135
/**
15136
 * xmlDoRead:
15137
 * @ctxt:  an XML parser context
15138
 * @URL:  the base URL to use for the document
15139
 * @encoding:  the document encoding, or NULL
15140
 * @options:  a combination of xmlParserOption
15141
 * @reuse:  keep the context for reuse
15142
 *
15143
 * Common front-end for the xmlRead functions
15144
 *
15145
 * Returns the resulting document tree or NULL
15146
 */
15147
static xmlDocPtr
15148
xmlDoRead(xmlParserCtxtPtr ctxt, const char *URL, const char *encoding,
15149
          int options, int reuse)
15150
0
{
15151
0
    xmlDocPtr ret;
15152
15153
0
    xmlCtxtUseOptionsInternal(ctxt, options, encoding);
15154
0
    if (encoding != NULL) {
15155
0
        xmlCharEncodingHandlerPtr hdlr;
15156
15157
0
  hdlr = xmlFindCharEncodingHandler(encoding);
15158
0
  if (hdlr != NULL)
15159
0
      xmlSwitchToEncoding(ctxt, hdlr);
15160
0
    }
15161
0
    if ((URL != NULL) && (ctxt->input != NULL) &&
15162
0
        (ctxt->input->filename == NULL))
15163
0
        ctxt->input->filename = (char *) xmlStrdup((const xmlChar *) URL);
15164
0
    xmlParseDocument(ctxt);
15165
0
    if ((ctxt->wellFormed) || ctxt->recovery)
15166
0
        ret = ctxt->myDoc;
15167
0
    else {
15168
0
        ret = NULL;
15169
0
  if (ctxt->myDoc != NULL) {
15170
0
      xmlFreeDoc(ctxt->myDoc);
15171
0
  }
15172
0
    }
15173
0
    ctxt->myDoc = NULL;
15174
0
    if (!reuse) {
15175
0
  xmlFreeParserCtxt(ctxt);
15176
0
    }
15177
15178
0
    return (ret);
15179
0
}
15180
15181
/**
15182
 * xmlReadDoc:
15183
 * @cur:  a pointer to a zero terminated string
15184
 * @URL:  the base URL to use for the document
15185
 * @encoding:  the document encoding, or NULL
15186
 * @options:  a combination of xmlParserOption
15187
 *
15188
 * parse an XML in-memory document and build a tree.
15189
 *
15190
 * Returns the resulting document tree
15191
 */
15192
xmlDocPtr
15193
xmlReadDoc(const xmlChar * cur, const char *URL, const char *encoding, int options)
15194
0
{
15195
0
    xmlParserCtxtPtr ctxt;
15196
15197
0
    if (cur == NULL)
15198
0
        return (NULL);
15199
0
    xmlInitParser();
15200
15201
0
    ctxt = xmlCreateDocParserCtxt(cur);
15202
0
    if (ctxt == NULL)
15203
0
        return (NULL);
15204
0
    return (xmlDoRead(ctxt, URL, encoding, options, 0));
15205
0
}
15206
15207
/**
15208
 * xmlReadFile:
15209
 * @filename:  a file or URL
15210
 * @encoding:  the document encoding, or NULL
15211
 * @options:  a combination of xmlParserOption
15212
 *
15213
 * parse an XML file from the filesystem or the network.
15214
 *
15215
 * Returns the resulting document tree
15216
 */
15217
xmlDocPtr
15218
xmlReadFile(const char *filename, const char *encoding, int options)
15219
0
{
15220
0
    xmlParserCtxtPtr ctxt;
15221
15222
0
    xmlInitParser();
15223
0
    ctxt = xmlCreateURLParserCtxt(filename, options);
15224
0
    if (ctxt == NULL)
15225
0
        return (NULL);
15226
0
    return (xmlDoRead(ctxt, NULL, encoding, options, 0));
15227
0
}
15228
15229
/**
15230
 * xmlReadMemory:
15231
 * @buffer:  a pointer to a char array
15232
 * @size:  the size of the array
15233
 * @URL:  the base URL to use for the document
15234
 * @encoding:  the document encoding, or NULL
15235
 * @options:  a combination of xmlParserOption
15236
 *
15237
 * parse an XML in-memory document and build a tree.
15238
 *
15239
 * Returns the resulting document tree
15240
 */
15241
xmlDocPtr
15242
xmlReadMemory(const char *buffer, int size, const char *URL, const char *encoding, int options)
15243
0
{
15244
0
    xmlParserCtxtPtr ctxt;
15245
15246
0
    xmlInitParser();
15247
0
    ctxt = xmlCreateMemoryParserCtxt(buffer, size);
15248
0
    if (ctxt == NULL)
15249
0
        return (NULL);
15250
0
    return (xmlDoRead(ctxt, URL, encoding, options, 0));
15251
0
}
15252
15253
/**
15254
 * xmlReadFd:
15255
 * @fd:  an open file descriptor
15256
 * @URL:  the base URL to use for the document
15257
 * @encoding:  the document encoding, or NULL
15258
 * @options:  a combination of xmlParserOption
15259
 *
15260
 * parse an XML from a file descriptor and build a tree.
15261
 * NOTE that the file descriptor will not be closed when the
15262
 *      reader is closed or reset.
15263
 *
15264
 * Returns the resulting document tree
15265
 */
15266
xmlDocPtr
15267
xmlReadFd(int fd, const char *URL, const char *encoding, int options)
15268
0
{
15269
0
    xmlParserCtxtPtr ctxt;
15270
0
    xmlParserInputBufferPtr input;
15271
0
    xmlParserInputPtr stream;
15272
15273
0
    if (fd < 0)
15274
0
        return (NULL);
15275
0
    xmlInitParser();
15276
15277
0
    input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
15278
0
    if (input == NULL)
15279
0
        return (NULL);
15280
0
    input->closecallback = NULL;
15281
0
    ctxt = xmlNewParserCtxt();
15282
0
    if (ctxt == NULL) {
15283
0
        xmlFreeParserInputBuffer(input);
15284
0
        return (NULL);
15285
0
    }
15286
0
    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
15287
0
    if (stream == NULL) {
15288
0
        xmlFreeParserInputBuffer(input);
15289
0
  xmlFreeParserCtxt(ctxt);
15290
0
        return (NULL);
15291
0
    }
15292
0
    inputPush(ctxt, stream);
15293
0
    return (xmlDoRead(ctxt, URL, encoding, options, 0));
15294
0
}
15295
15296
/**
15297
 * xmlReadIO:
15298
 * @ioread:  an I/O read function
15299
 * @ioclose:  an I/O close function
15300
 * @ioctx:  an I/O handler
15301
 * @URL:  the base URL to use for the document
15302
 * @encoding:  the document encoding, or NULL
15303
 * @options:  a combination of xmlParserOption
15304
 *
15305
 * parse an XML document from I/O functions and source and build a tree.
15306
 *
15307
 * Returns the resulting document tree
15308
 */
15309
xmlDocPtr
15310
xmlReadIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
15311
          void *ioctx, const char *URL, const char *encoding, int options)
15312
0
{
15313
0
    xmlParserCtxtPtr ctxt;
15314
0
    xmlParserInputBufferPtr input;
15315
0
    xmlParserInputPtr stream;
15316
15317
0
    if (ioread == NULL)
15318
0
        return (NULL);
15319
0
    xmlInitParser();
15320
15321
0
    input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
15322
0
                                         XML_CHAR_ENCODING_NONE);
15323
0
    if (input == NULL) {
15324
0
        if (ioclose != NULL)
15325
0
            ioclose(ioctx);
15326
0
        return (NULL);
15327
0
    }
15328
0
    ctxt = xmlNewParserCtxt();
15329
0
    if (ctxt == NULL) {
15330
0
        xmlFreeParserInputBuffer(input);
15331
0
        return (NULL);
15332
0
    }
15333
0
    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
15334
0
    if (stream == NULL) {
15335
0
        xmlFreeParserInputBuffer(input);
15336
0
  xmlFreeParserCtxt(ctxt);
15337
0
        return (NULL);
15338
0
    }
15339
0
    inputPush(ctxt, stream);
15340
0
    return (xmlDoRead(ctxt, URL, encoding, options, 0));
15341
0
}
15342
15343
/**
15344
 * xmlCtxtReadDoc:
15345
 * @ctxt:  an XML parser context
15346
 * @cur:  a pointer to a zero terminated string
15347
 * @URL:  the base URL to use for the document
15348
 * @encoding:  the document encoding, or NULL
15349
 * @options:  a combination of xmlParserOption
15350
 *
15351
 * parse an XML in-memory document and build a tree.
15352
 * This reuses the existing @ctxt parser context
15353
 *
15354
 * Returns the resulting document tree
15355
 */
15356
xmlDocPtr
15357
xmlCtxtReadDoc(xmlParserCtxtPtr ctxt, const xmlChar * cur,
15358
               const char *URL, const char *encoding, int options)
15359
0
{
15360
0
    xmlParserInputPtr stream;
15361
15362
0
    if (cur == NULL)
15363
0
        return (NULL);
15364
0
    if (ctxt == NULL)
15365
0
        return (NULL);
15366
0
    xmlInitParser();
15367
15368
0
    xmlCtxtReset(ctxt);
15369
15370
0
    stream = xmlNewStringInputStream(ctxt, cur);
15371
0
    if (stream == NULL) {
15372
0
        return (NULL);
15373
0
    }
15374
0
    inputPush(ctxt, stream);
15375
0
    return (xmlDoRead(ctxt, URL, encoding, options, 1));
15376
0
}
15377
15378
/**
15379
 * xmlCtxtReadFile:
15380
 * @ctxt:  an XML parser context
15381
 * @filename:  a file or URL
15382
 * @encoding:  the document encoding, or NULL
15383
 * @options:  a combination of xmlParserOption
15384
 *
15385
 * parse an XML file from the filesystem or the network.
15386
 * This reuses the existing @ctxt parser context
15387
 *
15388
 * Returns the resulting document tree
15389
 */
15390
xmlDocPtr
15391
xmlCtxtReadFile(xmlParserCtxtPtr ctxt, const char *filename,
15392
                const char *encoding, int options)
15393
0
{
15394
0
    xmlParserInputPtr stream;
15395
15396
0
    if (filename == NULL)
15397
0
        return (NULL);
15398
0
    if (ctxt == NULL)
15399
0
        return (NULL);
15400
0
    xmlInitParser();
15401
15402
0
    xmlCtxtReset(ctxt);
15403
15404
0
    stream = xmlLoadExternalEntity(filename, NULL, ctxt);
15405
0
    if (stream == NULL) {
15406
0
        return (NULL);
15407
0
    }
15408
0
    inputPush(ctxt, stream);
15409
0
    return (xmlDoRead(ctxt, NULL, encoding, options, 1));
15410
0
}
15411
15412
/**
15413
 * xmlCtxtReadMemory:
15414
 * @ctxt:  an XML parser context
15415
 * @buffer:  a pointer to a char array
15416
 * @size:  the size of the array
15417
 * @URL:  the base URL to use for the document
15418
 * @encoding:  the document encoding, or NULL
15419
 * @options:  a combination of xmlParserOption
15420
 *
15421
 * parse an XML in-memory document and build a tree.
15422
 * This reuses the existing @ctxt parser context
15423
 *
15424
 * Returns the resulting document tree
15425
 */
15426
xmlDocPtr
15427
xmlCtxtReadMemory(xmlParserCtxtPtr ctxt, const char *buffer, int size,
15428
                  const char *URL, const char *encoding, int options)
15429
0
{
15430
0
    xmlParserInputBufferPtr input;
15431
0
    xmlParserInputPtr stream;
15432
15433
0
    if (ctxt == NULL)
15434
0
        return (NULL);
15435
0
    if (buffer == NULL)
15436
0
        return (NULL);
15437
0
    xmlInitParser();
15438
15439
0
    xmlCtxtReset(ctxt);
15440
15441
0
    input = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
15442
0
    if (input == NULL) {
15443
0
  return(NULL);
15444
0
    }
15445
15446
0
    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
15447
0
    if (stream == NULL) {
15448
0
  xmlFreeParserInputBuffer(input);
15449
0
  return(NULL);
15450
0
    }
15451
15452
0
    inputPush(ctxt, stream);
15453
0
    return (xmlDoRead(ctxt, URL, encoding, options, 1));
15454
0
}
15455
15456
/**
15457
 * xmlCtxtReadFd:
15458
 * @ctxt:  an XML parser context
15459
 * @fd:  an open file descriptor
15460
 * @URL:  the base URL to use for the document
15461
 * @encoding:  the document encoding, or NULL
15462
 * @options:  a combination of xmlParserOption
15463
 *
15464
 * parse an XML from a file descriptor and build a tree.
15465
 * This reuses the existing @ctxt parser context
15466
 * NOTE that the file descriptor will not be closed when the
15467
 *      reader is closed or reset.
15468
 *
15469
 * Returns the resulting document tree
15470
 */
15471
xmlDocPtr
15472
xmlCtxtReadFd(xmlParserCtxtPtr ctxt, int fd,
15473
              const char *URL, const char *encoding, int options)
15474
0
{
15475
0
    xmlParserInputBufferPtr input;
15476
0
    xmlParserInputPtr stream;
15477
15478
0
    if (fd < 0)
15479
0
        return (NULL);
15480
0
    if (ctxt == NULL)
15481
0
        return (NULL);
15482
0
    xmlInitParser();
15483
15484
0
    xmlCtxtReset(ctxt);
15485
15486
15487
0
    input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
15488
0
    if (input == NULL)
15489
0
        return (NULL);
15490
0
    input->closecallback = NULL;
15491
0
    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
15492
0
    if (stream == NULL) {
15493
0
        xmlFreeParserInputBuffer(input);
15494
0
        return (NULL);
15495
0
    }
15496
0
    inputPush(ctxt, stream);
15497
0
    return (xmlDoRead(ctxt, URL, encoding, options, 1));
15498
0
}
15499
15500
/**
15501
 * xmlCtxtReadIO:
15502
 * @ctxt:  an XML parser context
15503
 * @ioread:  an I/O read function
15504
 * @ioclose:  an I/O close function
15505
 * @ioctx:  an I/O handler
15506
 * @URL:  the base URL to use for the document
15507
 * @encoding:  the document encoding, or NULL
15508
 * @options:  a combination of xmlParserOption
15509
 *
15510
 * parse an XML document from I/O functions and source and build a tree.
15511
 * This reuses the existing @ctxt parser context
15512
 *
15513
 * Returns the resulting document tree
15514
 */
15515
xmlDocPtr
15516
xmlCtxtReadIO(xmlParserCtxtPtr ctxt, xmlInputReadCallback ioread,
15517
              xmlInputCloseCallback ioclose, void *ioctx,
15518
        const char *URL,
15519
              const char *encoding, int options)
15520
0
{
15521
0
    xmlParserInputBufferPtr input;
15522
0
    xmlParserInputPtr stream;
15523
15524
0
    if (ioread == NULL)
15525
0
        return (NULL);
15526
0
    if (ctxt == NULL)
15527
0
        return (NULL);
15528
0
    xmlInitParser();
15529
15530
0
    xmlCtxtReset(ctxt);
15531
15532
0
    input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
15533
0
                                         XML_CHAR_ENCODING_NONE);
15534
0
    if (input == NULL) {
15535
0
        if (ioclose != NULL)
15536
0
            ioclose(ioctx);
15537
0
        return (NULL);
15538
0
    }
15539
0
    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
15540
0
    if (stream == NULL) {
15541
0
        xmlFreeParserInputBuffer(input);
15542
0
        return (NULL);
15543
0
    }
15544
0
    inputPush(ctxt, stream);
15545
0
    return (xmlDoRead(ctxt, URL, encoding, options, 1));
15546
0
}
15547