~ubuntu-branches/ubuntu/utopic/libxml2/utopic

« back to all changes in this revision

Viewing changes to .pc/lp1321869.patch/parser.c

  • Committer: Package Import Robot
  • Author(s): Aron Xu, Christian Svensson, Daniel Schepler, Helmut Grohne, Adam Conrad, Matthias Klose, Aron Xu
  • Date: 2014-07-09 05:40:15 UTC
  • mfrom: (43.2.6 sid)
  • Revision ID: package-import@ubuntu.com-20140709054015-1q7dyagza4p2gkm0
Tags: 2.9.1+dfsg1-4
[ Christian Svensson ]
* Do not build-depend on readline (Closes: #742350)

[ Daniel Schepler ]
* Patch to bootstrap without python (Closes: #738080)

[ Helmut Grohne ]
* Drop unneeded B-D on perl and binutils (Closes: #753005)

[ Adam Conrad ]
* Actually run dh_autoreconf, which the old/new mixed rules file misses.

[ Matthias Klose ]
* Add patch to fix python multiarch issue
* Allow the package to cross-build by tweaking B-Ds on python
* Set PYTHON_LIBS for cross builds

[ Aron Xu ]
* Use correct $CC
* Configure udeb without python
* New round of cherry-picking upstream fixes
  - Includes fixes for CVE-2014-0191 (Closes: #747309).
* Call prename with -vf
* Require python-all-dev (>= 2.7.5-5~)
* Bump std-ver: 3.9.4 -> 3.9.5, no change

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
#define IN_LIBXML
34
 
#include "libxml.h"
35
 
 
36
 
#if defined(WIN32) && !defined (__CYGWIN__)
37
 
#define XML_DIR_SEP '\\'
38
 
#else
39
 
#define XML_DIR_SEP '/'
40
 
#endif
41
 
 
42
 
#include <stdlib.h>
43
 
#include <limits.h>
44
 
#include <string.h>
45
 
#include <stdarg.h>
46
 
#include <libxml/xmlmemory.h>
47
 
#include <libxml/threads.h>
48
 
#include <libxml/globals.h>
49
 
#include <libxml/tree.h>
50
 
#include <libxml/parser.h>
51
 
#include <libxml/parserInternals.h>
52
 
#include <libxml/valid.h>
53
 
#include <libxml/entities.h>
54
 
#include <libxml/xmlerror.h>
55
 
#include <libxml/encoding.h>
56
 
#include <libxml/xmlIO.h>
57
 
#include <libxml/uri.h>
58
 
#ifdef LIBXML_CATALOG_ENABLED
59
 
#include <libxml/catalog.h>
60
 
#endif
61
 
#ifdef LIBXML_SCHEMAS_ENABLED
62
 
#include <libxml/xmlschemastypes.h>
63
 
#include <libxml/relaxng.h>
64
 
#endif
65
 
#ifdef HAVE_CTYPE_H
66
 
#include <ctype.h>
67
 
#endif
68
 
#ifdef HAVE_STDLIB_H
69
 
#include <stdlib.h>
70
 
#endif
71
 
#ifdef HAVE_SYS_STAT_H
72
 
#include <sys/stat.h>
73
 
#endif
74
 
#ifdef HAVE_FCNTL_H
75
 
#include <fcntl.h>
76
 
#endif
77
 
#ifdef HAVE_UNISTD_H
78
 
#include <unistd.h>
79
 
#endif
80
 
#ifdef HAVE_ZLIB_H
81
 
#include <zlib.h>
82
 
#endif
83
 
#ifdef HAVE_LZMA_H
84
 
#include <lzma.h>
85
 
#endif
86
 
 
87
 
#include "buf.h"
88
 
#include "enc.h"
89
 
 
90
 
static void
91
 
xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info);
92
 
 
93
 
static xmlParserCtxtPtr
94
 
xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
95
 
                          const xmlChar *base, xmlParserCtxtPtr pctx);
96
 
 
97
 
/************************************************************************
98
 
 *                                                                      *
99
 
 *      Arbitrary limits set in the parser. See XML_PARSE_HUGE          *
100
 
 *                                                                      *
101
 
 ************************************************************************/
102
 
 
103
 
#define XML_PARSER_BIG_ENTITY 1000
104
 
#define XML_PARSER_LOT_ENTITY 5000
105
 
 
106
 
/*
107
 
 * XML_PARSER_NON_LINEAR is the threshold where the ratio of parsed entity
108
 
 *    replacement over the size in byte of the input indicates that you have
109
 
 *    and eponential behaviour. A value of 10 correspond to at least 3 entity
110
 
 *    replacement per byte of input.
111
 
 */
112
 
#define XML_PARSER_NON_LINEAR 10
113
 
 
114
 
/*
115
 
 * xmlParserEntityCheck
116
 
 *
117
 
 * Function to check non-linear entity expansion behaviour
118
 
 * This is here to detect and stop exponential linear entity expansion
119
 
 * This is not a limitation of the parser but a safety
120
 
 * boundary feature. It can be disabled with the XML_PARSE_HUGE
121
 
 * parser option.
122
 
 */
123
 
static int
124
 
xmlParserEntityCheck(xmlParserCtxtPtr ctxt, size_t size,
125
 
                     xmlEntityPtr ent, size_t replacement)
126
 
{
127
 
    size_t consumed = 0;
128
 
 
129
 
    if ((ctxt == NULL) || (ctxt->options & XML_PARSE_HUGE))
130
 
        return (0);
131
 
    if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
132
 
        return (1);
133
 
    if (replacement != 0) {
134
 
        if (replacement < XML_MAX_TEXT_LENGTH)
135
 
            return(0);
136
 
 
137
 
        /*
138
 
         * If the volume of entity copy reaches 10 times the
139
 
         * amount of parsed data and over the large text threshold
140
 
         * then that's very likely to be an abuse.
141
 
         */
142
 
        if (ctxt->input != NULL) {
143
 
            consumed = ctxt->input->consumed +
144
 
                       (ctxt->input->cur - ctxt->input->base);
145
 
        }
146
 
        consumed += ctxt->sizeentities;
147
 
 
148
 
        if (replacement < XML_PARSER_NON_LINEAR * consumed)
149
 
            return(0);
150
 
    } else if (size != 0) {
151
 
        /*
152
 
         * Do the check based on the replacement size of the entity
153
 
         */
154
 
        if (size < XML_PARSER_BIG_ENTITY)
155
 
            return(0);
156
 
 
157
 
        /*
158
 
         * A limit on the amount of text data reasonably used
159
 
         */
160
 
        if (ctxt->input != NULL) {
161
 
            consumed = ctxt->input->consumed +
162
 
                (ctxt->input->cur - ctxt->input->base);
163
 
        }
164
 
        consumed += ctxt->sizeentities;
165
 
 
166
 
        if ((size < XML_PARSER_NON_LINEAR * consumed) &&
167
 
            (ctxt->nbentities * 3 < XML_PARSER_NON_LINEAR * consumed))
168
 
            return (0);
169
 
    } else if (ent != NULL) {
170
 
        /*
171
 
         * use the number of parsed entities in the replacement
172
 
         */
173
 
        size = ent->checked / 2;
174
 
 
175
 
        /*
176
 
         * The amount of data parsed counting entities size only once
177
 
         */
178
 
        if (ctxt->input != NULL) {
179
 
            consumed = ctxt->input->consumed +
180
 
                (ctxt->input->cur - ctxt->input->base);
181
 
        }
182
 
        consumed += ctxt->sizeentities;
183
 
 
184
 
        /*
185
 
         * Check the density of entities for the amount of data
186
 
         * knowing an entity reference will take at least 3 bytes
187
 
         */
188
 
        if (size * 3 < consumed * XML_PARSER_NON_LINEAR)
189
 
            return (0);
190
 
    } else {
191
 
        /*
192
 
         * strange we got no data for checking just return
193
 
         */
194
 
        return (0);
195
 
    }
196
 
    xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
197
 
    return (1);
198
 
}
199
 
 
200
 
/**
201
 
 * xmlParserMaxDepth:
202
 
 *
203
 
 * arbitrary depth limit for the XML documents that we allow to
204
 
 * process. This is not a limitation of the parser but a safety
205
 
 * boundary feature. It can be disabled with the XML_PARSE_HUGE
206
 
 * parser option.
207
 
 */
208
 
unsigned int xmlParserMaxDepth = 256;
209
 
 
210
 
 
211
 
 
212
 
#define SAX2 1
213
 
#define XML_PARSER_BIG_BUFFER_SIZE 300
214
 
#define XML_PARSER_BUFFER_SIZE 100
215
 
#define SAX_COMPAT_MODE BAD_CAST "SAX compatibility mode document"
216
 
 
217
 
/**
218
 
 * XML_PARSER_CHUNK_SIZE
219
 
 *
220
 
 * When calling GROW that's the minimal amount of data
221
 
 * the parser expected to have received. It is not a hard
222
 
 * limit but an optimization when reading strings like Names
223
 
 * It is not strictly needed as long as inputs available characters
224
 
 * are followed by 0, which should be provided by the I/O level
225
 
 */
226
 
#define XML_PARSER_CHUNK_SIZE 100
227
 
 
228
 
/*
229
 
 * List of XML prefixed PI allowed by W3C specs
230
 
 */
231
 
 
232
 
static const char *xmlW3CPIs[] = {
233
 
    "xml-stylesheet",
234
 
    "xml-model",
235
 
    NULL
236
 
};
237
 
 
238
 
 
239
 
/* DEPR void xmlParserHandleReference(xmlParserCtxtPtr ctxt); */
240
 
static xmlEntityPtr xmlParseStringPEReference(xmlParserCtxtPtr ctxt,
241
 
                                              const xmlChar **str);
242
 
 
243
 
static xmlParserErrors
244
 
xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
245
 
                      xmlSAXHandlerPtr sax,
246
 
                      void *user_data, int depth, const xmlChar *URL,
247
 
                      const xmlChar *ID, xmlNodePtr *list);
248
 
 
249
 
static int
250
 
xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options,
251
 
                          const char *encoding);
252
 
#ifdef LIBXML_LEGACY_ENABLED
253
 
static void
254
 
xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
255
 
                      xmlNodePtr lastNode);
256
 
#endif /* LIBXML_LEGACY_ENABLED */
257
 
 
258
 
static xmlParserErrors
259
 
xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
260
 
                      const xmlChar *string, void *user_data, xmlNodePtr *lst);
261
 
 
262
 
static int
263
 
xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity);
264
 
 
265
 
/************************************************************************
266
 
 *                                                                      *
267
 
 *              Some factorized error routines                          *
268
 
 *                                                                      *
269
 
 ************************************************************************/
270
 
 
271
 
/**
272
 
 * xmlErrAttributeDup:
273
 
 * @ctxt:  an XML parser context
274
 
 * @prefix:  the attribute prefix
275
 
 * @localname:  the attribute localname
276
 
 *
277
 
 * Handle a redefinition of attribute error
278
 
 */
279
 
static void
280
 
xmlErrAttributeDup(xmlParserCtxtPtr ctxt, const xmlChar * prefix,
281
 
                   const xmlChar * localname)
282
 
{
283
 
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
284
 
        (ctxt->instate == XML_PARSER_EOF))
285
 
        return;
286
 
    if (ctxt != NULL)
287
 
        ctxt->errNo = XML_ERR_ATTRIBUTE_REDEFINED;
288
 
 
289
 
    if (prefix == NULL)
290
 
        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
291
 
                        XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL, NULL, 0,
292
 
                        (const char *) localname, NULL, NULL, 0, 0,
293
 
                        "Attribute %s redefined\n", localname);
294
 
    else
295
 
        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
296
 
                        XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL, NULL, 0,
297
 
                        (const char *) prefix, (const char *) localname,
298
 
                        NULL, 0, 0, "Attribute %s:%s redefined\n", prefix,
299
 
                        localname);
300
 
    if (ctxt != NULL) {
301
 
        ctxt->wellFormed = 0;
302
 
        if (ctxt->recovery == 0)
303
 
            ctxt->disableSAX = 1;
304
 
    }
305
 
}
306
 
 
307
 
/**
308
 
 * xmlFatalErr:
309
 
 * @ctxt:  an XML parser context
310
 
 * @error:  the error number
311
 
 * @extra:  extra information string
312
 
 *
313
 
 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
314
 
 */
315
 
static void
316
 
xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info)
317
 
{
318
 
    const char *errmsg;
319
 
    char errstr[129] = "";
320
 
 
321
 
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
322
 
        (ctxt->instate == XML_PARSER_EOF))
323
 
        return;
324
 
    switch (error) {
325
 
        case XML_ERR_INVALID_HEX_CHARREF:
326
 
            errmsg = "CharRef: invalid hexadecimal value";
327
 
            break;
328
 
        case XML_ERR_INVALID_DEC_CHARREF:
329
 
            errmsg = "CharRef: invalid decimal value";
330
 
            break;
331
 
        case XML_ERR_INVALID_CHARREF:
332
 
            errmsg = "CharRef: invalid value";
333
 
            break;
334
 
        case XML_ERR_INTERNAL_ERROR:
335
 
            errmsg = "internal error";
336
 
            break;
337
 
        case XML_ERR_PEREF_AT_EOF:
338
 
            errmsg = "PEReference at end of document";
339
 
            break;
340
 
        case XML_ERR_PEREF_IN_PROLOG:
341
 
            errmsg = "PEReference in prolog";
342
 
            break;
343
 
        case XML_ERR_PEREF_IN_EPILOG:
344
 
            errmsg = "PEReference in epilog";
345
 
            break;
346
 
        case XML_ERR_PEREF_NO_NAME:
347
 
            errmsg = "PEReference: no name";
348
 
            break;
349
 
        case XML_ERR_PEREF_SEMICOL_MISSING:
350
 
            errmsg = "PEReference: expecting ';'";
351
 
            break;
352
 
        case XML_ERR_ENTITY_LOOP:
353
 
            errmsg = "Detected an entity reference loop";
354
 
            break;
355
 
        case XML_ERR_ENTITY_NOT_STARTED:
356
 
            errmsg = "EntityValue: \" or ' expected";
357
 
            break;
358
 
        case XML_ERR_ENTITY_PE_INTERNAL:
359
 
            errmsg = "PEReferences forbidden in internal subset";
360
 
            break;
361
 
        case XML_ERR_ENTITY_NOT_FINISHED:
362
 
            errmsg = "EntityValue: \" or ' expected";
363
 
            break;
364
 
        case XML_ERR_ATTRIBUTE_NOT_STARTED:
365
 
            errmsg = "AttValue: \" or ' expected";
366
 
            break;
367
 
        case XML_ERR_LT_IN_ATTRIBUTE:
368
 
            errmsg = "Unescaped '<' not allowed in attributes values";
369
 
            break;
370
 
        case XML_ERR_LITERAL_NOT_STARTED:
371
 
            errmsg = "SystemLiteral \" or ' expected";
372
 
            break;
373
 
        case XML_ERR_LITERAL_NOT_FINISHED:
374
 
            errmsg = "Unfinished System or Public ID \" or ' expected";
375
 
            break;
376
 
        case XML_ERR_MISPLACED_CDATA_END:
377
 
            errmsg = "Sequence ']]>' not allowed in content";
378
 
            break;
379
 
        case XML_ERR_URI_REQUIRED:
380
 
            errmsg = "SYSTEM or PUBLIC, the URI is missing";
381
 
            break;
382
 
        case XML_ERR_PUBID_REQUIRED:
383
 
            errmsg = "PUBLIC, the Public Identifier is missing";
384
 
            break;
385
 
        case XML_ERR_HYPHEN_IN_COMMENT:
386
 
            errmsg = "Comment must not contain '--' (double-hyphen)";
387
 
            break;
388
 
        case XML_ERR_PI_NOT_STARTED:
389
 
            errmsg = "xmlParsePI : no target name";
390
 
            break;
391
 
        case XML_ERR_RESERVED_XML_NAME:
392
 
            errmsg = "Invalid PI name";
393
 
            break;
394
 
        case XML_ERR_NOTATION_NOT_STARTED:
395
 
            errmsg = "NOTATION: Name expected here";
396
 
            break;
397
 
        case XML_ERR_NOTATION_NOT_FINISHED:
398
 
            errmsg = "'>' required to close NOTATION declaration";
399
 
            break;
400
 
        case XML_ERR_VALUE_REQUIRED:
401
 
            errmsg = "Entity value required";
402
 
            break;
403
 
        case XML_ERR_URI_FRAGMENT:
404
 
            errmsg = "Fragment not allowed";
405
 
            break;
406
 
        case XML_ERR_ATTLIST_NOT_STARTED:
407
 
            errmsg = "'(' required to start ATTLIST enumeration";
408
 
            break;
409
 
        case XML_ERR_NMTOKEN_REQUIRED:
410
 
            errmsg = "NmToken expected in ATTLIST enumeration";
411
 
            break;
412
 
        case XML_ERR_ATTLIST_NOT_FINISHED:
413
 
            errmsg = "')' required to finish ATTLIST enumeration";
414
 
            break;
415
 
        case XML_ERR_MIXED_NOT_STARTED:
416
 
            errmsg = "MixedContentDecl : '|' or ')*' expected";
417
 
            break;
418
 
        case XML_ERR_PCDATA_REQUIRED:
419
 
            errmsg = "MixedContentDecl : '#PCDATA' expected";
420
 
            break;
421
 
        case XML_ERR_ELEMCONTENT_NOT_STARTED:
422
 
            errmsg = "ContentDecl : Name or '(' expected";
423
 
            break;
424
 
        case XML_ERR_ELEMCONTENT_NOT_FINISHED:
425
 
            errmsg = "ContentDecl : ',' '|' or ')' expected";
426
 
            break;
427
 
        case XML_ERR_PEREF_IN_INT_SUBSET:
428
 
            errmsg =
429
 
                "PEReference: forbidden within markup decl in internal subset";
430
 
            break;
431
 
        case XML_ERR_GT_REQUIRED:
432
 
            errmsg = "expected '>'";
433
 
            break;
434
 
        case XML_ERR_CONDSEC_INVALID:
435
 
            errmsg = "XML conditional section '[' expected";
436
 
            break;
437
 
        case XML_ERR_EXT_SUBSET_NOT_FINISHED:
438
 
            errmsg = "Content error in the external subset";
439
 
            break;
440
 
        case XML_ERR_CONDSEC_INVALID_KEYWORD:
441
 
            errmsg =
442
 
                "conditional section INCLUDE or IGNORE keyword expected";
443
 
            break;
444
 
        case XML_ERR_CONDSEC_NOT_FINISHED:
445
 
            errmsg = "XML conditional section not closed";
446
 
            break;
447
 
        case XML_ERR_XMLDECL_NOT_STARTED:
448
 
            errmsg = "Text declaration '<?xml' required";
449
 
            break;
450
 
        case XML_ERR_XMLDECL_NOT_FINISHED:
451
 
            errmsg = "parsing XML declaration: '?>' expected";
452
 
            break;
453
 
        case XML_ERR_EXT_ENTITY_STANDALONE:
454
 
            errmsg = "external parsed entities cannot be standalone";
455
 
            break;
456
 
        case XML_ERR_ENTITYREF_SEMICOL_MISSING:
457
 
            errmsg = "EntityRef: expecting ';'";
458
 
            break;
459
 
        case XML_ERR_DOCTYPE_NOT_FINISHED:
460
 
            errmsg = "DOCTYPE improperly terminated";
461
 
            break;
462
 
        case XML_ERR_LTSLASH_REQUIRED:
463
 
            errmsg = "EndTag: '</' not found";
464
 
            break;
465
 
        case XML_ERR_EQUAL_REQUIRED:
466
 
            errmsg = "expected '='";
467
 
            break;
468
 
        case XML_ERR_STRING_NOT_CLOSED:
469
 
            errmsg = "String not closed expecting \" or '";
470
 
            break;
471
 
        case XML_ERR_STRING_NOT_STARTED:
472
 
            errmsg = "String not started expecting ' or \"";
473
 
            break;
474
 
        case XML_ERR_ENCODING_NAME:
475
 
            errmsg = "Invalid XML encoding name";
476
 
            break;
477
 
        case XML_ERR_STANDALONE_VALUE:
478
 
            errmsg = "standalone accepts only 'yes' or 'no'";
479
 
            break;
480
 
        case XML_ERR_DOCUMENT_EMPTY:
481
 
            errmsg = "Document is empty";
482
 
            break;
483
 
        case XML_ERR_DOCUMENT_END:
484
 
            errmsg = "Extra content at the end of the document";
485
 
            break;
486
 
        case XML_ERR_NOT_WELL_BALANCED:
487
 
            errmsg = "chunk is not well balanced";
488
 
            break;
489
 
        case XML_ERR_EXTRA_CONTENT:
490
 
            errmsg = "extra content at the end of well balanced chunk";
491
 
            break;
492
 
        case XML_ERR_VERSION_MISSING:
493
 
            errmsg = "Malformed declaration expecting version";
494
 
            break;
495
 
        case XML_ERR_NAME_TOO_LONG:
496
 
            errmsg = "Name too long use XML_PARSE_HUGE option";
497
 
            break;
498
 
#if 0
499
 
        case:
500
 
            errmsg = "";
501
 
            break;
502
 
#endif
503
 
        default:
504
 
            errmsg = "Unregistered error message";
505
 
    }
506
 
    if (info == NULL)
507
 
        snprintf(errstr, 128, "%s\n", errmsg);
508
 
    else
509
 
        snprintf(errstr, 128, "%s: %%s\n", errmsg);
510
 
    if (ctxt != NULL)
511
 
        ctxt->errNo = error;
512
 
    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
513
 
                    XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, &errstr[0],
514
 
                    info);
515
 
    if (ctxt != NULL) {
516
 
        ctxt->wellFormed = 0;
517
 
        if (ctxt->recovery == 0)
518
 
            ctxt->disableSAX = 1;
519
 
    }
520
 
}
521
 
 
522
 
/**
523
 
 * xmlFatalErrMsg:
524
 
 * @ctxt:  an XML parser context
525
 
 * @error:  the error number
526
 
 * @msg:  the error message
527
 
 *
528
 
 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
529
 
 */
530
 
static void
531
 
xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
532
 
               const char *msg)
533
 
{
534
 
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
535
 
        (ctxt->instate == XML_PARSER_EOF))
536
 
        return;
537
 
    if (ctxt != NULL)
538
 
        ctxt->errNo = error;
539
 
    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
540
 
                    XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg);
541
 
    if (ctxt != NULL) {
542
 
        ctxt->wellFormed = 0;
543
 
        if (ctxt->recovery == 0)
544
 
            ctxt->disableSAX = 1;
545
 
    }
546
 
}
547
 
 
548
 
/**
549
 
 * xmlWarningMsg:
550
 
 * @ctxt:  an XML parser context
551
 
 * @error:  the error number
552
 
 * @msg:  the error message
553
 
 * @str1:  extra data
554
 
 * @str2:  extra data
555
 
 *
556
 
 * Handle a warning.
557
 
 */
558
 
static void
559
 
xmlWarningMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
560
 
              const char *msg, const xmlChar *str1, const xmlChar *str2)
561
 
{
562
 
    xmlStructuredErrorFunc schannel = NULL;
563
 
 
564
 
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
565
 
        (ctxt->instate == XML_PARSER_EOF))
566
 
        return;
567
 
    if ((ctxt != NULL) && (ctxt->sax != NULL) &&
568
 
        (ctxt->sax->initialized == XML_SAX2_MAGIC))
569
 
        schannel = ctxt->sax->serror;
570
 
    if (ctxt != NULL) {
571
 
        __xmlRaiseError(schannel,
572
 
                    (ctxt->sax) ? ctxt->sax->warning : NULL,
573
 
                    ctxt->userData,
574
 
                    ctxt, NULL, XML_FROM_PARSER, error,
575
 
                    XML_ERR_WARNING, NULL, 0,
576
 
                    (const char *) str1, (const char *) str2, NULL, 0, 0,
577
 
                    msg, (const char *) str1, (const char *) str2);
578
 
    } else {
579
 
        __xmlRaiseError(schannel, NULL, NULL,
580
 
                    ctxt, NULL, XML_FROM_PARSER, error,
581
 
                    XML_ERR_WARNING, NULL, 0,
582
 
                    (const char *) str1, (const char *) str2, NULL, 0, 0,
583
 
                    msg, (const char *) str1, (const char *) str2);
584
 
    }
585
 
}
586
 
 
587
 
/**
588
 
 * xmlValidityError:
589
 
 * @ctxt:  an XML parser context
590
 
 * @error:  the error number
591
 
 * @msg:  the error message
592
 
 * @str1:  extra data
593
 
 *
594
 
 * Handle a validity error.
595
 
 */
596
 
static void
597
 
xmlValidityError(xmlParserCtxtPtr ctxt, xmlParserErrors error,
598
 
              const char *msg, const xmlChar *str1, const xmlChar *str2)
599
 
{
600
 
    xmlStructuredErrorFunc schannel = NULL;
601
 
 
602
 
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
603
 
        (ctxt->instate == XML_PARSER_EOF))
604
 
        return;
605
 
    if (ctxt != NULL) {
606
 
        ctxt->errNo = error;
607
 
        if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
608
 
            schannel = ctxt->sax->serror;
609
 
    }
610
 
    if (ctxt != NULL) {
611
 
        __xmlRaiseError(schannel,
612
 
                    ctxt->vctxt.error, ctxt->vctxt.userData,
613
 
                    ctxt, NULL, XML_FROM_DTD, error,
614
 
                    XML_ERR_ERROR, NULL, 0, (const char *) str1,
615
 
                    (const char *) str2, NULL, 0, 0,
616
 
                    msg, (const char *) str1, (const char *) str2);
617
 
        ctxt->valid = 0;
618
 
    } else {
619
 
        __xmlRaiseError(schannel, NULL, NULL,
620
 
                    ctxt, NULL, XML_FROM_DTD, error,
621
 
                    XML_ERR_ERROR, NULL, 0, (const char *) str1,
622
 
                    (const char *) str2, NULL, 0, 0,
623
 
                    msg, (const char *) str1, (const char *) str2);
624
 
    }
625
 
}
626
 
 
627
 
/**
628
 
 * xmlFatalErrMsgInt:
629
 
 * @ctxt:  an XML parser context
630
 
 * @error:  the error number
631
 
 * @msg:  the error message
632
 
 * @val:  an integer value
633
 
 *
634
 
 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
635
 
 */
636
 
static void
637
 
xmlFatalErrMsgInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
638
 
                  const char *msg, int val)
639
 
{
640
 
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
641
 
        (ctxt->instate == XML_PARSER_EOF))
642
 
        return;
643
 
    if (ctxt != NULL)
644
 
        ctxt->errNo = error;
645
 
    __xmlRaiseError(NULL, NULL, NULL,
646
 
                    ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
647
 
                    NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
648
 
    if (ctxt != NULL) {
649
 
        ctxt->wellFormed = 0;
650
 
        if (ctxt->recovery == 0)
651
 
            ctxt->disableSAX = 1;
652
 
    }
653
 
}
654
 
 
655
 
/**
656
 
 * xmlFatalErrMsgStrIntStr:
657
 
 * @ctxt:  an XML parser context
658
 
 * @error:  the error number
659
 
 * @msg:  the error message
660
 
 * @str1:  an string info
661
 
 * @val:  an integer value
662
 
 * @str2:  an string info
663
 
 *
664
 
 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
665
 
 */
666
 
static void
667
 
xmlFatalErrMsgStrIntStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
668
 
                  const char *msg, const xmlChar *str1, int val,
669
 
                  const xmlChar *str2)
670
 
{
671
 
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
672
 
        (ctxt->instate == XML_PARSER_EOF))
673
 
        return;
674
 
    if (ctxt != NULL)
675
 
        ctxt->errNo = error;
676
 
    __xmlRaiseError(NULL, NULL, NULL,
677
 
                    ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
678
 
                    NULL, 0, (const char *) str1, (const char *) str2,
679
 
                    NULL, val, 0, msg, str1, val, str2);
680
 
    if (ctxt != NULL) {
681
 
        ctxt->wellFormed = 0;
682
 
        if (ctxt->recovery == 0)
683
 
            ctxt->disableSAX = 1;
684
 
    }
685
 
}
686
 
 
687
 
/**
688
 
 * xmlFatalErrMsgStr:
689
 
 * @ctxt:  an XML parser context
690
 
 * @error:  the error number
691
 
 * @msg:  the error message
692
 
 * @val:  a string value
693
 
 *
694
 
 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
695
 
 */
696
 
static void
697
 
xmlFatalErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
698
 
                  const char *msg, const xmlChar * val)
699
 
{
700
 
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
701
 
        (ctxt->instate == XML_PARSER_EOF))
702
 
        return;
703
 
    if (ctxt != NULL)
704
 
        ctxt->errNo = error;
705
 
    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL,
706
 
                    XML_FROM_PARSER, error, XML_ERR_FATAL,
707
 
                    NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
708
 
                    val);
709
 
    if (ctxt != NULL) {
710
 
        ctxt->wellFormed = 0;
711
 
        if (ctxt->recovery == 0)
712
 
            ctxt->disableSAX = 1;
713
 
    }
714
 
}
715
 
 
716
 
/**
717
 
 * xmlErrMsgStr:
718
 
 * @ctxt:  an XML parser context
719
 
 * @error:  the error number
720
 
 * @msg:  the error message
721
 
 * @val:  a string value
722
 
 *
723
 
 * Handle a non fatal parser error
724
 
 */
725
 
static void
726
 
xmlErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
727
 
                  const char *msg, const xmlChar * val)
728
 
{
729
 
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
730
 
        (ctxt->instate == XML_PARSER_EOF))
731
 
        return;
732
 
    if (ctxt != NULL)
733
 
        ctxt->errNo = error;
734
 
    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL,
735
 
                    XML_FROM_PARSER, error, XML_ERR_ERROR,
736
 
                    NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg,
737
 
                    val);
738
 
}
739
 
 
740
 
/**
741
 
 * xmlNsErr:
742
 
 * @ctxt:  an XML parser context
743
 
 * @error:  the error number
744
 
 * @msg:  the message
745
 
 * @info1:  extra information string
746
 
 * @info2:  extra information string
747
 
 *
748
 
 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
749
 
 */
750
 
static void
751
 
xmlNsErr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
752
 
         const char *msg,
753
 
         const xmlChar * info1, const xmlChar * info2,
754
 
         const xmlChar * info3)
755
 
{
756
 
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
757
 
        (ctxt->instate == XML_PARSER_EOF))
758
 
        return;
759
 
    if (ctxt != NULL)
760
 
        ctxt->errNo = error;
761
 
    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
762
 
                    XML_ERR_ERROR, NULL, 0, (const char *) info1,
763
 
                    (const char *) info2, (const char *) info3, 0, 0, msg,
764
 
                    info1, info2, info3);
765
 
    if (ctxt != NULL)
766
 
        ctxt->nsWellFormed = 0;
767
 
}
768
 
 
769
 
/**
770
 
 * xmlNsWarn
771
 
 * @ctxt:  an XML parser context
772
 
 * @error:  the error number
773
 
 * @msg:  the message
774
 
 * @info1:  extra information string
775
 
 * @info2:  extra information string
776
 
 *
777
 
 * Handle a namespace warning error
778
 
 */
779
 
static void
780
 
xmlNsWarn(xmlParserCtxtPtr ctxt, xmlParserErrors error,
781
 
         const char *msg,
782
 
         const xmlChar * info1, const xmlChar * info2,
783
 
         const xmlChar * info3)
784
 
{
785
 
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
786
 
        (ctxt->instate == XML_PARSER_EOF))
787
 
        return;
788
 
    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
789
 
                    XML_ERR_WARNING, NULL, 0, (const char *) info1,
790
 
                    (const char *) info2, (const char *) info3, 0, 0, msg,
791
 
                    info1, info2, info3);
792
 
}
793
 
 
794
 
/************************************************************************
795
 
 *                                                                      *
796
 
 *              Library wide options                                    *
797
 
 *                                                                      *
798
 
 ************************************************************************/
799
 
 
800
 
/**
801
 
  * xmlHasFeature:
802
 
  * @feature: the feature to be examined
803
 
  *
804
 
  * Examines if the library has been compiled with a given feature.
805
 
  *
806
 
  * Returns a non-zero value if the feature exist, otherwise zero.
807
 
  * Returns zero (0) if the feature does not exist or an unknown
808
 
  * unknown feature is requested, non-zero otherwise.
809
 
  */
810
 
int
811
 
xmlHasFeature(xmlFeature feature)
812
 
{
813
 
    switch (feature) {
814
 
        case XML_WITH_THREAD:
815
 
#ifdef LIBXML_THREAD_ENABLED
816
 
            return(1);
817
 
#else
818
 
            return(0);
819
 
#endif
820
 
        case XML_WITH_TREE:
821
 
#ifdef LIBXML_TREE_ENABLED
822
 
            return(1);
823
 
#else
824
 
            return(0);
825
 
#endif
826
 
        case XML_WITH_OUTPUT:
827
 
#ifdef LIBXML_OUTPUT_ENABLED
828
 
            return(1);
829
 
#else
830
 
            return(0);
831
 
#endif
832
 
        case XML_WITH_PUSH:
833
 
#ifdef LIBXML_PUSH_ENABLED
834
 
            return(1);
835
 
#else
836
 
            return(0);
837
 
#endif
838
 
        case XML_WITH_READER:
839
 
#ifdef LIBXML_READER_ENABLED
840
 
            return(1);
841
 
#else
842
 
            return(0);
843
 
#endif
844
 
        case XML_WITH_PATTERN:
845
 
#ifdef LIBXML_PATTERN_ENABLED
846
 
            return(1);
847
 
#else
848
 
            return(0);
849
 
#endif
850
 
        case XML_WITH_WRITER:
851
 
#ifdef LIBXML_WRITER_ENABLED
852
 
            return(1);
853
 
#else
854
 
            return(0);
855
 
#endif
856
 
        case XML_WITH_SAX1:
857
 
#ifdef LIBXML_SAX1_ENABLED
858
 
            return(1);
859
 
#else
860
 
            return(0);
861
 
#endif
862
 
        case XML_WITH_FTP:
863
 
#ifdef LIBXML_FTP_ENABLED
864
 
            return(1);
865
 
#else
866
 
            return(0);
867
 
#endif
868
 
        case XML_WITH_HTTP:
869
 
#ifdef LIBXML_HTTP_ENABLED
870
 
            return(1);
871
 
#else
872
 
            return(0);
873
 
#endif
874
 
        case XML_WITH_VALID:
875
 
#ifdef LIBXML_VALID_ENABLED
876
 
            return(1);
877
 
#else
878
 
            return(0);
879
 
#endif
880
 
        case XML_WITH_HTML:
881
 
#ifdef LIBXML_HTML_ENABLED
882
 
            return(1);
883
 
#else
884
 
            return(0);
885
 
#endif
886
 
        case XML_WITH_LEGACY:
887
 
#ifdef LIBXML_LEGACY_ENABLED
888
 
            return(1);
889
 
#else
890
 
            return(0);
891
 
#endif
892
 
        case XML_WITH_C14N:
893
 
#ifdef LIBXML_C14N_ENABLED
894
 
            return(1);
895
 
#else
896
 
            return(0);
897
 
#endif
898
 
        case XML_WITH_CATALOG:
899
 
#ifdef LIBXML_CATALOG_ENABLED
900
 
            return(1);
901
 
#else
902
 
            return(0);
903
 
#endif
904
 
        case XML_WITH_XPATH:
905
 
#ifdef LIBXML_XPATH_ENABLED
906
 
            return(1);
907
 
#else
908
 
            return(0);
909
 
#endif
910
 
        case XML_WITH_XPTR:
911
 
#ifdef LIBXML_XPTR_ENABLED
912
 
            return(1);
913
 
#else
914
 
            return(0);
915
 
#endif
916
 
        case XML_WITH_XINCLUDE:
917
 
#ifdef LIBXML_XINCLUDE_ENABLED
918
 
            return(1);
919
 
#else
920
 
            return(0);
921
 
#endif
922
 
        case XML_WITH_ICONV:
923
 
#ifdef LIBXML_ICONV_ENABLED
924
 
            return(1);
925
 
#else
926
 
            return(0);
927
 
#endif
928
 
        case XML_WITH_ISO8859X:
929
 
#ifdef LIBXML_ISO8859X_ENABLED
930
 
            return(1);
931
 
#else
932
 
            return(0);
933
 
#endif
934
 
        case XML_WITH_UNICODE:
935
 
#ifdef LIBXML_UNICODE_ENABLED
936
 
            return(1);
937
 
#else
938
 
            return(0);
939
 
#endif
940
 
        case XML_WITH_REGEXP:
941
 
#ifdef LIBXML_REGEXP_ENABLED
942
 
            return(1);
943
 
#else
944
 
            return(0);
945
 
#endif
946
 
        case XML_WITH_AUTOMATA:
947
 
#ifdef LIBXML_AUTOMATA_ENABLED
948
 
            return(1);
949
 
#else
950
 
            return(0);
951
 
#endif
952
 
        case XML_WITH_EXPR:
953
 
#ifdef LIBXML_EXPR_ENABLED
954
 
            return(1);
955
 
#else
956
 
            return(0);
957
 
#endif
958
 
        case XML_WITH_SCHEMAS:
959
 
#ifdef LIBXML_SCHEMAS_ENABLED
960
 
            return(1);
961
 
#else
962
 
            return(0);
963
 
#endif
964
 
        case XML_WITH_SCHEMATRON:
965
 
#ifdef LIBXML_SCHEMATRON_ENABLED
966
 
            return(1);
967
 
#else
968
 
            return(0);
969
 
#endif
970
 
        case XML_WITH_MODULES:
971
 
#ifdef LIBXML_MODULES_ENABLED
972
 
            return(1);
973
 
#else
974
 
            return(0);
975
 
#endif
976
 
        case XML_WITH_DEBUG:
977
 
#ifdef LIBXML_DEBUG_ENABLED
978
 
            return(1);
979
 
#else
980
 
            return(0);
981
 
#endif
982
 
        case XML_WITH_DEBUG_MEM:
983
 
#ifdef DEBUG_MEMORY_LOCATION
984
 
            return(1);
985
 
#else
986
 
            return(0);
987
 
#endif
988
 
        case XML_WITH_DEBUG_RUN:
989
 
#ifdef LIBXML_DEBUG_RUNTIME
990
 
            return(1);
991
 
#else
992
 
            return(0);
993
 
#endif
994
 
        case XML_WITH_ZLIB:
995
 
#ifdef LIBXML_ZLIB_ENABLED
996
 
            return(1);
997
 
#else
998
 
            return(0);
999
 
#endif
1000
 
        case XML_WITH_LZMA:
1001
 
#ifdef LIBXML_LZMA_ENABLED
1002
 
            return(1);
1003
 
#else
1004
 
            return(0);
1005
 
#endif
1006
 
        case XML_WITH_ICU:
1007
 
#ifdef LIBXML_ICU_ENABLED
1008
 
            return(1);
1009
 
#else
1010
 
            return(0);
1011
 
#endif
1012
 
        default:
1013
 
            break;
1014
 
     }
1015
 
     return(0);
1016
 
}
1017
 
 
1018
 
/************************************************************************
1019
 
 *                                                                      *
1020
 
 *              SAX2 defaulted attributes handling                      *
1021
 
 *                                                                      *
1022
 
 ************************************************************************/
1023
 
 
1024
 
/**
1025
 
 * xmlDetectSAX2:
1026
 
 * @ctxt:  an XML parser context
1027
 
 *
1028
 
 * Do the SAX2 detection and specific intialization
1029
 
 */
1030
 
static void
1031
 
xmlDetectSAX2(xmlParserCtxtPtr ctxt) {
1032
 
    if (ctxt == NULL) return;
1033
 
#ifdef LIBXML_SAX1_ENABLED
1034
 
    if ((ctxt->sax) &&  (ctxt->sax->initialized == XML_SAX2_MAGIC) &&
1035
 
        ((ctxt->sax->startElementNs != NULL) ||
1036
 
         (ctxt->sax->endElementNs != NULL))) ctxt->sax2 = 1;
1037
 
#else
1038
 
    ctxt->sax2 = 1;
1039
 
#endif /* LIBXML_SAX1_ENABLED */
1040
 
 
1041
 
    ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
1042
 
    ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
1043
 
    ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
1044
 
    if ((ctxt->str_xml==NULL) || (ctxt->str_xmlns==NULL) ||
1045
 
                (ctxt->str_xml_ns == NULL)) {
1046
 
        xmlErrMemory(ctxt, NULL);
1047
 
    }
1048
 
}
1049
 
 
1050
 
typedef struct _xmlDefAttrs xmlDefAttrs;
1051
 
typedef xmlDefAttrs *xmlDefAttrsPtr;
1052
 
struct _xmlDefAttrs {
1053
 
    int nbAttrs;        /* number of defaulted attributes on that element */
1054
 
    int maxAttrs;       /* the size of the array */
1055
 
    const xmlChar *values[5]; /* array of localname/prefix/values/external */
1056
 
};
1057
 
 
1058
 
/**
1059
 
 * xmlAttrNormalizeSpace:
1060
 
 * @src: the source string
1061
 
 * @dst: the target string
1062
 
 *
1063
 
 * Normalize the space in non CDATA attribute values:
1064
 
 * If the attribute type is not CDATA, then the XML processor MUST further
1065
 
 * process the normalized attribute value by discarding any leading and
1066
 
 * trailing space (#x20) characters, and by replacing sequences of space
1067
 
 * (#x20) characters by a single space (#x20) character.
1068
 
 * Note that the size of dst need to be at least src, and if one doesn't need
1069
 
 * to preserve dst (and it doesn't come from a dictionary or read-only) then
1070
 
 * passing src as dst is just fine.
1071
 
 *
1072
 
 * Returns a pointer to the normalized value (dst) or NULL if no conversion
1073
 
 *         is needed.
1074
 
 */
1075
 
static xmlChar *
1076
 
xmlAttrNormalizeSpace(const xmlChar *src, xmlChar *dst)
1077
 
{
1078
 
    if ((src == NULL) || (dst == NULL))
1079
 
        return(NULL);
1080
 
 
1081
 
    while (*src == 0x20) src++;
1082
 
    while (*src != 0) {
1083
 
        if (*src == 0x20) {
1084
 
            while (*src == 0x20) src++;
1085
 
            if (*src != 0)
1086
 
                *dst++ = 0x20;
1087
 
        } else {
1088
 
            *dst++ = *src++;
1089
 
        }
1090
 
    }
1091
 
    *dst = 0;
1092
 
    if (dst == src)
1093
 
       return(NULL);
1094
 
    return(dst);
1095
 
}
1096
 
 
1097
 
/**
1098
 
 * xmlAttrNormalizeSpace2:
1099
 
 * @src: the source string
1100
 
 *
1101
 
 * Normalize the space in non CDATA attribute values, a slightly more complex
1102
 
 * front end to avoid allocation problems when running on attribute values
1103
 
 * coming from the input.
1104
 
 *
1105
 
 * Returns a pointer to the normalized value (dst) or NULL if no conversion
1106
 
 *         is needed.
1107
 
 */
1108
 
static const xmlChar *
1109
 
xmlAttrNormalizeSpace2(xmlParserCtxtPtr ctxt, xmlChar *src, int *len)
1110
 
{
1111
 
    int i;
1112
 
    int remove_head = 0;
1113
 
    int need_realloc = 0;
1114
 
    const xmlChar *cur;
1115
 
 
1116
 
    if ((ctxt == NULL) || (src == NULL) || (len == NULL))
1117
 
        return(NULL);
1118
 
    i = *len;
1119
 
    if (i <= 0)
1120
 
        return(NULL);
1121
 
 
1122
 
    cur = src;
1123
 
    while (*cur == 0x20) {
1124
 
        cur++;
1125
 
        remove_head++;
1126
 
    }
1127
 
    while (*cur != 0) {
1128
 
        if (*cur == 0x20) {
1129
 
            cur++;
1130
 
            if ((*cur == 0x20) || (*cur == 0)) {
1131
 
                need_realloc = 1;
1132
 
                break;
1133
 
            }
1134
 
        } else
1135
 
            cur++;
1136
 
    }
1137
 
    if (need_realloc) {
1138
 
        xmlChar *ret;
1139
 
 
1140
 
        ret = xmlStrndup(src + remove_head, i - remove_head + 1);
1141
 
        if (ret == NULL) {
1142
 
            xmlErrMemory(ctxt, NULL);
1143
 
            return(NULL);
1144
 
        }
1145
 
        xmlAttrNormalizeSpace(ret, ret);
1146
 
        *len = (int) strlen((const char *)ret);
1147
 
        return(ret);
1148
 
    } else if (remove_head) {
1149
 
        *len -= remove_head;
1150
 
        memmove(src, src + remove_head, 1 + *len);
1151
 
        return(src);
1152
 
    }
1153
 
    return(NULL);
1154
 
}
1155
 
 
1156
 
/**
1157
 
 * xmlAddDefAttrs:
1158
 
 * @ctxt:  an XML parser context
1159
 
 * @fullname:  the element fullname
1160
 
 * @fullattr:  the attribute fullname
1161
 
 * @value:  the attribute value
1162
 
 *
1163
 
 * Add a defaulted attribute for an element
1164
 
 */
1165
 
static void
1166
 
xmlAddDefAttrs(xmlParserCtxtPtr ctxt,
1167
 
               const xmlChar *fullname,
1168
 
               const xmlChar *fullattr,
1169
 
               const xmlChar *value) {
1170
 
    xmlDefAttrsPtr defaults;
1171
 
    int len;
1172
 
    const xmlChar *name;
1173
 
    const xmlChar *prefix;
1174
 
 
1175
 
    /*
1176
 
     * Allows to detect attribute redefinitions
1177
 
     */
1178
 
    if (ctxt->attsSpecial != NULL) {
1179
 
        if (xmlHashLookup2(ctxt->attsSpecial, fullname, fullattr) != NULL)
1180
 
            return;
1181
 
    }
1182
 
 
1183
 
    if (ctxt->attsDefault == NULL) {
1184
 
        ctxt->attsDefault = xmlHashCreateDict(10, ctxt->dict);
1185
 
        if (ctxt->attsDefault == NULL)
1186
 
            goto mem_error;
1187
 
    }
1188
 
 
1189
 
    /*
1190
 
     * split the element name into prefix:localname , the string found
1191
 
     * are within the DTD and then not associated to namespace names.
1192
 
     */
1193
 
    name = xmlSplitQName3(fullname, &len);
1194
 
    if (name == NULL) {
1195
 
        name = xmlDictLookup(ctxt->dict, fullname, -1);
1196
 
        prefix = NULL;
1197
 
    } else {
1198
 
        name = xmlDictLookup(ctxt->dict, name, -1);
1199
 
        prefix = xmlDictLookup(ctxt->dict, fullname, len);
1200
 
    }
1201
 
 
1202
 
    /*
1203
 
     * make sure there is some storage
1204
 
     */
1205
 
    defaults = xmlHashLookup2(ctxt->attsDefault, name, prefix);
1206
 
    if (defaults == NULL) {
1207
 
        defaults = (xmlDefAttrsPtr) xmlMalloc(sizeof(xmlDefAttrs) +
1208
 
                           (4 * 5) * sizeof(const xmlChar *));
1209
 
        if (defaults == NULL)
1210
 
            goto mem_error;
1211
 
        defaults->nbAttrs = 0;
1212
 
        defaults->maxAttrs = 4;
1213
 
        if (xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix,
1214
 
                                defaults, NULL) < 0) {
1215
 
            xmlFree(defaults);
1216
 
            goto mem_error;
1217
 
        }
1218
 
    } else if (defaults->nbAttrs >= defaults->maxAttrs) {
1219
 
        xmlDefAttrsPtr temp;
1220
 
 
1221
 
        temp = (xmlDefAttrsPtr) xmlRealloc(defaults, sizeof(xmlDefAttrs) +
1222
 
                       (2 * defaults->maxAttrs * 5) * sizeof(const xmlChar *));
1223
 
        if (temp == NULL)
1224
 
            goto mem_error;
1225
 
        defaults = temp;
1226
 
        defaults->maxAttrs *= 2;
1227
 
        if (xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix,
1228
 
                                defaults, NULL) < 0) {
1229
 
            xmlFree(defaults);
1230
 
            goto mem_error;
1231
 
        }
1232
 
    }
1233
 
 
1234
 
    /*
1235
 
     * Split the element name into prefix:localname , the string found
1236
 
     * are within the DTD and hen not associated to namespace names.
1237
 
     */
1238
 
    name = xmlSplitQName3(fullattr, &len);
1239
 
    if (name == NULL) {
1240
 
        name = xmlDictLookup(ctxt->dict, fullattr, -1);
1241
 
        prefix = NULL;
1242
 
    } else {
1243
 
        name = xmlDictLookup(ctxt->dict, name, -1);
1244
 
        prefix = xmlDictLookup(ctxt->dict, fullattr, len);
1245
 
    }
1246
 
 
1247
 
    defaults->values[5 * defaults->nbAttrs] = name;
1248
 
    defaults->values[5 * defaults->nbAttrs + 1] = prefix;
1249
 
    /* intern the string and precompute the end */
1250
 
    len = xmlStrlen(value);
1251
 
    value = xmlDictLookup(ctxt->dict, value, len);
1252
 
    defaults->values[5 * defaults->nbAttrs + 2] = value;
1253
 
    defaults->values[5 * defaults->nbAttrs + 3] = value + len;
1254
 
    if (ctxt->external)
1255
 
        defaults->values[5 * defaults->nbAttrs + 4] = BAD_CAST "external";
1256
 
    else
1257
 
        defaults->values[5 * defaults->nbAttrs + 4] = NULL;
1258
 
    defaults->nbAttrs++;
1259
 
 
1260
 
    return;
1261
 
 
1262
 
mem_error:
1263
 
    xmlErrMemory(ctxt, NULL);
1264
 
    return;
1265
 
}
1266
 
 
1267
 
/**
1268
 
 * xmlAddSpecialAttr:
1269
 
 * @ctxt:  an XML parser context
1270
 
 * @fullname:  the element fullname
1271
 
 * @fullattr:  the attribute fullname
1272
 
 * @type:  the attribute type
1273
 
 *
1274
 
 * Register this attribute type
1275
 
 */
1276
 
static void
1277
 
xmlAddSpecialAttr(xmlParserCtxtPtr ctxt,
1278
 
                  const xmlChar *fullname,
1279
 
                  const xmlChar *fullattr,
1280
 
                  int type)
1281
 
{
1282
 
    if (ctxt->attsSpecial == NULL) {
1283
 
        ctxt->attsSpecial = xmlHashCreateDict(10, ctxt->dict);
1284
 
        if (ctxt->attsSpecial == NULL)
1285
 
            goto mem_error;
1286
 
    }
1287
 
 
1288
 
    if (xmlHashLookup2(ctxt->attsSpecial, fullname, fullattr) != NULL)
1289
 
        return;
1290
 
 
1291
 
    xmlHashAddEntry2(ctxt->attsSpecial, fullname, fullattr,
1292
 
                     (void *) (long) type);
1293
 
    return;
1294
 
 
1295
 
mem_error:
1296
 
    xmlErrMemory(ctxt, NULL);
1297
 
    return;
1298
 
}
1299
 
 
1300
 
/**
1301
 
 * xmlCleanSpecialAttrCallback:
1302
 
 *
1303
 
 * Removes CDATA attributes from the special attribute table
1304
 
 */
1305
 
static void
1306
 
xmlCleanSpecialAttrCallback(void *payload, void *data,
1307
 
                            const xmlChar *fullname, const xmlChar *fullattr,
1308
 
                            const xmlChar *unused ATTRIBUTE_UNUSED) {
1309
 
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) data;
1310
 
 
1311
 
    if (((long) payload) == XML_ATTRIBUTE_CDATA) {
1312
 
        xmlHashRemoveEntry2(ctxt->attsSpecial, fullname, fullattr, NULL);
1313
 
    }
1314
 
}
1315
 
 
1316
 
/**
1317
 
 * xmlCleanSpecialAttr:
1318
 
 * @ctxt:  an XML parser context
1319
 
 *
1320
 
 * Trim the list of attributes defined to remove all those of type
1321
 
 * CDATA as they are not special. This call should be done when finishing
1322
 
 * to parse the DTD and before starting to parse the document root.
1323
 
 */
1324
 
static void
1325
 
xmlCleanSpecialAttr(xmlParserCtxtPtr ctxt)
1326
 
{
1327
 
    if (ctxt->attsSpecial == NULL)
1328
 
        return;
1329
 
 
1330
 
    xmlHashScanFull(ctxt->attsSpecial, xmlCleanSpecialAttrCallback, ctxt);
1331
 
 
1332
 
    if (xmlHashSize(ctxt->attsSpecial) == 0) {
1333
 
        xmlHashFree(ctxt->attsSpecial, NULL);
1334
 
        ctxt->attsSpecial = NULL;
1335
 
    }
1336
 
    return;
1337
 
}
1338
 
 
1339
 
/**
1340
 
 * xmlCheckLanguageID:
1341
 
 * @lang:  pointer to the string value
1342
 
 *
1343
 
 * Checks that the value conforms to the LanguageID production:
1344
 
 *
1345
 
 * NOTE: this is somewhat deprecated, those productions were removed from
1346
 
 *       the XML Second edition.
1347
 
 *
1348
 
 * [33] LanguageID ::= Langcode ('-' Subcode)*
1349
 
 * [34] Langcode ::= ISO639Code |  IanaCode |  UserCode
1350
 
 * [35] ISO639Code ::= ([a-z] | [A-Z]) ([a-z] | [A-Z])
1351
 
 * [36] IanaCode ::= ('i' | 'I') '-' ([a-z] | [A-Z])+
1352
 
 * [37] UserCode ::= ('x' | 'X') '-' ([a-z] | [A-Z])+
1353
 
 * [38] Subcode ::= ([a-z] | [A-Z])+
1354
 
 *
1355
 
 * The current REC reference the sucessors of RFC 1766, currently 5646
1356
 
 *
1357
 
 * http://www.rfc-editor.org/rfc/rfc5646.txt
1358
 
 * langtag       = language
1359
 
 *                 ["-" script]
1360
 
 *                 ["-" region]
1361
 
 *                 *("-" variant)
1362
 
 *                 *("-" extension)
1363
 
 *                 ["-" privateuse]
1364
 
 * language      = 2*3ALPHA            ; shortest ISO 639 code
1365
 
 *                 ["-" extlang]       ; sometimes followed by
1366
 
 *                                     ; extended language subtags
1367
 
 *               / 4ALPHA              ; or reserved for future use
1368
 
 *               / 5*8ALPHA            ; or registered language subtag
1369
 
 *
1370
 
 * extlang       = 3ALPHA              ; selected ISO 639 codes
1371
 
 *                 *2("-" 3ALPHA)      ; permanently reserved
1372
 
 *
1373
 
 * script        = 4ALPHA              ; ISO 15924 code
1374
 
 *
1375
 
 * region        = 2ALPHA              ; ISO 3166-1 code
1376
 
 *               / 3DIGIT              ; UN M.49 code
1377
 
 *
1378
 
 * variant       = 5*8alphanum         ; registered variants
1379
 
 *               / (DIGIT 3alphanum)
1380
 
 *
1381
 
 * extension     = singleton 1*("-" (2*8alphanum))
1382
 
 *
1383
 
 *                                     ; Single alphanumerics
1384
 
 *                                     ; "x" reserved for private use
1385
 
 * singleton     = DIGIT               ; 0 - 9
1386
 
 *               / %x41-57             ; A - W
1387
 
 *               / %x59-5A             ; Y - Z
1388
 
 *               / %x61-77             ; a - w
1389
 
 *               / %x79-7A             ; y - z
1390
 
 *
1391
 
 * it sounds right to still allow Irregular i-xxx IANA and user codes too
1392
 
 * The parser below doesn't try to cope with extension or privateuse
1393
 
 * that could be added but that's not interoperable anyway
1394
 
 *
1395
 
 * Returns 1 if correct 0 otherwise
1396
 
 **/
1397
 
int
1398
 
xmlCheckLanguageID(const xmlChar * lang)
1399
 
{
1400
 
    const xmlChar *cur = lang, *nxt;
1401
 
 
1402
 
    if (cur == NULL)
1403
 
        return (0);
1404
 
    if (((cur[0] == 'i') && (cur[1] == '-')) ||
1405
 
        ((cur[0] == 'I') && (cur[1] == '-')) ||
1406
 
        ((cur[0] == 'x') && (cur[1] == '-')) ||
1407
 
        ((cur[0] == 'X') && (cur[1] == '-'))) {
1408
 
        /*
1409
 
         * Still allow IANA code and user code which were coming
1410
 
         * from the previous version of the XML-1.0 specification
1411
 
         * it's deprecated but we should not fail
1412
 
         */
1413
 
        cur += 2;
1414
 
        while (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
1415
 
               ((cur[0] >= 'a') && (cur[0] <= 'z')))
1416
 
            cur++;
1417
 
        return(cur[0] == 0);
1418
 
    }
1419
 
    nxt = cur;
1420
 
    while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
1421
 
           ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
1422
 
           nxt++;
1423
 
    if (nxt - cur >= 4) {
1424
 
        /*
1425
 
         * Reserved
1426
 
         */
1427
 
        if ((nxt - cur > 8) || (nxt[0] != 0))
1428
 
            return(0);
1429
 
        return(1);
1430
 
    }
1431
 
    if (nxt - cur < 2)
1432
 
        return(0);
1433
 
    /* we got an ISO 639 code */
1434
 
    if (nxt[0] == 0)
1435
 
        return(1);
1436
 
    if (nxt[0] != '-')
1437
 
        return(0);
1438
 
 
1439
 
    nxt++;
1440
 
    cur = nxt;
1441
 
    /* now we can have extlang or script or region or variant */
1442
 
    if ((nxt[0] >= '0') && (nxt[0] <= '9'))
1443
 
        goto region_m49;
1444
 
 
1445
 
    while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
1446
 
           ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
1447
 
           nxt++;
1448
 
    if (nxt - cur == 4)
1449
 
        goto script;
1450
 
    if (nxt - cur == 2)
1451
 
        goto region;
1452
 
    if ((nxt - cur >= 5) && (nxt - cur <= 8))
1453
 
        goto variant;
1454
 
    if (nxt - cur != 3)
1455
 
        return(0);
1456
 
    /* we parsed an extlang */
1457
 
    if (nxt[0] == 0)
1458
 
        return(1);
1459
 
    if (nxt[0] != '-')
1460
 
        return(0);
1461
 
 
1462
 
    nxt++;
1463
 
    cur = nxt;
1464
 
    /* now we can have script or region or variant */
1465
 
    if ((nxt[0] >= '0') && (nxt[0] <= '9'))
1466
 
        goto region_m49;
1467
 
 
1468
 
    while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
1469
 
           ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
1470
 
           nxt++;
1471
 
    if (nxt - cur == 2)
1472
 
        goto region;
1473
 
    if ((nxt - cur >= 5) && (nxt - cur <= 8))
1474
 
        goto variant;
1475
 
    if (nxt - cur != 4)
1476
 
        return(0);
1477
 
    /* we parsed a script */
1478
 
script:
1479
 
    if (nxt[0] == 0)
1480
 
        return(1);
1481
 
    if (nxt[0] != '-')
1482
 
        return(0);
1483
 
 
1484
 
    nxt++;
1485
 
    cur = nxt;
1486
 
    /* now we can have region or variant */
1487
 
    if ((nxt[0] >= '0') && (nxt[0] <= '9'))
1488
 
        goto region_m49;
1489
 
 
1490
 
    while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
1491
 
           ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
1492
 
           nxt++;
1493
 
 
1494
 
    if ((nxt - cur >= 5) && (nxt - cur <= 8))
1495
 
        goto variant;
1496
 
    if (nxt - cur != 2)
1497
 
        return(0);
1498
 
    /* we parsed a region */
1499
 
region:
1500
 
    if (nxt[0] == 0)
1501
 
        return(1);
1502
 
    if (nxt[0] != '-')
1503
 
        return(0);
1504
 
 
1505
 
    nxt++;
1506
 
    cur = nxt;
1507
 
    /* now we can just have a variant */
1508
 
    while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
1509
 
           ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
1510
 
           nxt++;
1511
 
 
1512
 
    if ((nxt - cur < 5) || (nxt - cur > 8))
1513
 
        return(0);
1514
 
 
1515
 
    /* we parsed a variant */
1516
 
variant:
1517
 
    if (nxt[0] == 0)
1518
 
        return(1);
1519
 
    if (nxt[0] != '-')
1520
 
        return(0);
1521
 
    /* extensions and private use subtags not checked */
1522
 
    return (1);
1523
 
 
1524
 
region_m49:
1525
 
    if (((nxt[1] >= '0') && (nxt[1] <= '9')) &&
1526
 
        ((nxt[2] >= '0') && (nxt[2] <= '9'))) {
1527
 
        nxt += 3;
1528
 
        goto region;
1529
 
    }
1530
 
    return(0);
1531
 
}
1532
 
 
1533
 
/************************************************************************
1534
 
 *                                                                      *
1535
 
 *              Parser stacks related functions and macros              *
1536
 
 *                                                                      *
1537
 
 ************************************************************************/
1538
 
 
1539
 
static xmlEntityPtr xmlParseStringEntityRef(xmlParserCtxtPtr ctxt,
1540
 
                                            const xmlChar ** str);
1541
 
 
1542
 
#ifdef SAX2
1543
 
/**
1544
 
 * nsPush:
1545
 
 * @ctxt:  an XML parser context
1546
 
 * @prefix:  the namespace prefix or NULL
1547
 
 * @URL:  the namespace name
1548
 
 *
1549
 
 * Pushes a new parser namespace on top of the ns stack
1550
 
 *
1551
 
 * Returns -1 in case of error, -2 if the namespace should be discarded
1552
 
 *         and the index in the stack otherwise.
1553
 
 */
1554
 
static int
1555
 
nsPush(xmlParserCtxtPtr ctxt, const xmlChar *prefix, const xmlChar *URL)
1556
 
{
1557
 
    if (ctxt->options & XML_PARSE_NSCLEAN) {
1558
 
        int i;
1559
 
        for (i = ctxt->nsNr - 2;i >= 0;i -= 2) {
1560
 
            if (ctxt->nsTab[i] == prefix) {
1561
 
                /* in scope */
1562
 
                if (ctxt->nsTab[i + 1] == URL)
1563
 
                    return(-2);
1564
 
                /* out of scope keep it */
1565
 
                break;
1566
 
            }
1567
 
        }
1568
 
    }
1569
 
    if ((ctxt->nsMax == 0) || (ctxt->nsTab == NULL)) {
1570
 
        ctxt->nsMax = 10;
1571
 
        ctxt->nsNr = 0;
1572
 
        ctxt->nsTab = (const xmlChar **)
1573
 
                      xmlMalloc(ctxt->nsMax * sizeof(xmlChar *));
1574
 
        if (ctxt->nsTab == NULL) {
1575
 
            xmlErrMemory(ctxt, NULL);
1576
 
            ctxt->nsMax = 0;
1577
 
            return (-1);
1578
 
        }
1579
 
    } else if (ctxt->nsNr >= ctxt->nsMax) {
1580
 
        const xmlChar ** tmp;
1581
 
        ctxt->nsMax *= 2;
1582
 
        tmp = (const xmlChar **) xmlRealloc((char *) ctxt->nsTab,
1583
 
                                    ctxt->nsMax * sizeof(ctxt->nsTab[0]));
1584
 
        if (tmp == NULL) {
1585
 
            xmlErrMemory(ctxt, NULL);
1586
 
            ctxt->nsMax /= 2;
1587
 
            return (-1);
1588
 
        }
1589
 
        ctxt->nsTab = tmp;
1590
 
    }
1591
 
    ctxt->nsTab[ctxt->nsNr++] = prefix;
1592
 
    ctxt->nsTab[ctxt->nsNr++] = URL;
1593
 
    return (ctxt->nsNr);
1594
 
}
1595
 
/**
1596
 
 * nsPop:
1597
 
 * @ctxt: an XML parser context
1598
 
 * @nr:  the number to pop
1599
 
 *
1600
 
 * Pops the top @nr parser prefix/namespace from the ns stack
1601
 
 *
1602
 
 * Returns the number of namespaces removed
1603
 
 */
1604
 
static int
1605
 
nsPop(xmlParserCtxtPtr ctxt, int nr)
1606
 
{
1607
 
    int i;
1608
 
 
1609
 
    if (ctxt->nsTab == NULL) return(0);
1610
 
    if (ctxt->nsNr < nr) {
1611
 
        xmlGenericError(xmlGenericErrorContext, "Pbm popping %d NS\n", nr);
1612
 
        nr = ctxt->nsNr;
1613
 
    }
1614
 
    if (ctxt->nsNr <= 0)
1615
 
        return (0);
1616
 
 
1617
 
    for (i = 0;i < nr;i++) {
1618
 
         ctxt->nsNr--;
1619
 
         ctxt->nsTab[ctxt->nsNr] = NULL;
1620
 
    }
1621
 
    return(nr);
1622
 
}
1623
 
#endif
1624
 
 
1625
 
static int
1626
 
xmlCtxtGrowAttrs(xmlParserCtxtPtr ctxt, int nr) {
1627
 
    const xmlChar **atts;
1628
 
    int *attallocs;
1629
 
    int maxatts;
1630
 
 
1631
 
    if (ctxt->atts == NULL) {
1632
 
        maxatts = 55; /* allow for 10 attrs by default */
1633
 
        atts = (const xmlChar **)
1634
 
               xmlMalloc(maxatts * sizeof(xmlChar *));
1635
 
        if (atts == NULL) goto mem_error;
1636
 
        ctxt->atts = atts;
1637
 
        attallocs = (int *) xmlMalloc((maxatts / 5) * sizeof(int));
1638
 
        if (attallocs == NULL) goto mem_error;
1639
 
        ctxt->attallocs = attallocs;
1640
 
        ctxt->maxatts = maxatts;
1641
 
    } else if (nr + 5 > ctxt->maxatts) {
1642
 
        maxatts = (nr + 5) * 2;
1643
 
        atts = (const xmlChar **) xmlRealloc((void *) ctxt->atts,
1644
 
                                     maxatts * sizeof(const xmlChar *));
1645
 
        if (atts == NULL) goto mem_error;
1646
 
        ctxt->atts = atts;
1647
 
        attallocs = (int *) xmlRealloc((void *) ctxt->attallocs,
1648
 
                                     (maxatts / 5) * sizeof(int));
1649
 
        if (attallocs == NULL) goto mem_error;
1650
 
        ctxt->attallocs = attallocs;
1651
 
        ctxt->maxatts = maxatts;
1652
 
    }
1653
 
    return(ctxt->maxatts);
1654
 
mem_error:
1655
 
    xmlErrMemory(ctxt, NULL);
1656
 
    return(-1);
1657
 
}
1658
 
 
1659
 
/**
1660
 
 * inputPush:
1661
 
 * @ctxt:  an XML parser context
1662
 
 * @value:  the parser input
1663
 
 *
1664
 
 * Pushes a new parser input on top of the input stack
1665
 
 *
1666
 
 * Returns -1 in case of error, the index in the stack otherwise
1667
 
 */
1668
 
int
1669
 
inputPush(xmlParserCtxtPtr ctxt, xmlParserInputPtr value)
1670
 
{
1671
 
    if ((ctxt == NULL) || (value == NULL))
1672
 
        return(-1);
1673
 
    if (ctxt->inputNr >= ctxt->inputMax) {
1674
 
        ctxt->inputMax *= 2;
1675
 
        ctxt->inputTab =
1676
 
            (xmlParserInputPtr *) xmlRealloc(ctxt->inputTab,
1677
 
                                             ctxt->inputMax *
1678
 
                                             sizeof(ctxt->inputTab[0]));
1679
 
        if (ctxt->inputTab == NULL) {
1680
 
            xmlErrMemory(ctxt, NULL);
1681
 
            xmlFreeInputStream(value);
1682
 
            ctxt->inputMax /= 2;
1683
 
            value = NULL;
1684
 
            return (-1);
1685
 
        }
1686
 
    }
1687
 
    ctxt->inputTab[ctxt->inputNr] = value;
1688
 
    ctxt->input = value;
1689
 
    return (ctxt->inputNr++);
1690
 
}
1691
 
/**
1692
 
 * inputPop:
1693
 
 * @ctxt: an XML parser context
1694
 
 *
1695
 
 * Pops the top parser input from the input stack
1696
 
 *
1697
 
 * Returns the input just removed
1698
 
 */
1699
 
xmlParserInputPtr
1700
 
inputPop(xmlParserCtxtPtr ctxt)
1701
 
{
1702
 
    xmlParserInputPtr ret;
1703
 
 
1704
 
    if (ctxt == NULL)
1705
 
        return(NULL);
1706
 
    if (ctxt->inputNr <= 0)
1707
 
        return (NULL);
1708
 
    ctxt->inputNr--;
1709
 
    if (ctxt->inputNr > 0)
1710
 
        ctxt->input = ctxt->inputTab[ctxt->inputNr - 1];
1711
 
    else
1712
 
        ctxt->input = NULL;
1713
 
    ret = ctxt->inputTab[ctxt->inputNr];
1714
 
    ctxt->inputTab[ctxt->inputNr] = NULL;
1715
 
    return (ret);
1716
 
}
1717
 
/**
1718
 
 * nodePush:
1719
 
 * @ctxt:  an XML parser context
1720
 
 * @value:  the element node
1721
 
 *
1722
 
 * Pushes a new element node on top of the node stack
1723
 
 *
1724
 
 * Returns -1 in case of error, the index in the stack otherwise
1725
 
 */
1726
 
int
1727
 
nodePush(xmlParserCtxtPtr ctxt, xmlNodePtr value)
1728
 
{
1729
 
    if (ctxt == NULL) return(0);
1730
 
    if (ctxt->nodeNr >= ctxt->nodeMax) {
1731
 
        xmlNodePtr *tmp;
1732
 
 
1733
 
        tmp = (xmlNodePtr *) xmlRealloc(ctxt->nodeTab,
1734
 
                                      ctxt->nodeMax * 2 *
1735
 
                                      sizeof(ctxt->nodeTab[0]));
1736
 
        if (tmp == NULL) {
1737
 
            xmlErrMemory(ctxt, NULL);
1738
 
            return (-1);
1739
 
        }
1740
 
        ctxt->nodeTab = tmp;
1741
 
        ctxt->nodeMax *= 2;
1742
 
    }
1743
 
    if ((((unsigned int) ctxt->nodeNr) > xmlParserMaxDepth) &&
1744
 
        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
1745
 
        xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
1746
 
                 "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
1747
 
                          xmlParserMaxDepth);
1748
 
        ctxt->instate = XML_PARSER_EOF;
1749
 
        return(-1);
1750
 
    }
1751
 
    ctxt->nodeTab[ctxt->nodeNr] = value;
1752
 
    ctxt->node = value;
1753
 
    return (ctxt->nodeNr++);
1754
 
}
1755
 
 
1756
 
/**
1757
 
 * nodePop:
1758
 
 * @ctxt: an XML parser context
1759
 
 *
1760
 
 * Pops the top element node from the node stack
1761
 
 *
1762
 
 * Returns the node just removed
1763
 
 */
1764
 
xmlNodePtr
1765
 
nodePop(xmlParserCtxtPtr ctxt)
1766
 
{
1767
 
    xmlNodePtr ret;
1768
 
 
1769
 
    if (ctxt == NULL) return(NULL);
1770
 
    if (ctxt->nodeNr <= 0)
1771
 
        return (NULL);
1772
 
    ctxt->nodeNr--;
1773
 
    if (ctxt->nodeNr > 0)
1774
 
        ctxt->node = ctxt->nodeTab[ctxt->nodeNr - 1];
1775
 
    else
1776
 
        ctxt->node = NULL;
1777
 
    ret = ctxt->nodeTab[ctxt->nodeNr];
1778
 
    ctxt->nodeTab[ctxt->nodeNr] = NULL;
1779
 
    return (ret);
1780
 
}
1781
 
 
1782
 
#ifdef LIBXML_PUSH_ENABLED
1783
 
/**
1784
 
 * nameNsPush:
1785
 
 * @ctxt:  an XML parser context
1786
 
 * @value:  the element name
1787
 
 * @prefix:  the element prefix
1788
 
 * @URI:  the element namespace name
1789
 
 *
1790
 
 * Pushes a new element name/prefix/URL on top of the name stack
1791
 
 *
1792
 
 * Returns -1 in case of error, the index in the stack otherwise
1793
 
 */
1794
 
static int
1795
 
nameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value,
1796
 
           const xmlChar *prefix, const xmlChar *URI, int nsNr)
1797
 
{
1798
 
    if (ctxt->nameNr >= ctxt->nameMax) {
1799
 
        const xmlChar * *tmp;
1800
 
        void **tmp2;
1801
 
        ctxt->nameMax *= 2;
1802
 
        tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,
1803
 
                                    ctxt->nameMax *
1804
 
                                    sizeof(ctxt->nameTab[0]));
1805
 
        if (tmp == NULL) {
1806
 
            ctxt->nameMax /= 2;
1807
 
            goto mem_error;
1808
 
        }
1809
 
        ctxt->nameTab = tmp;
1810
 
        tmp2 = (void **) xmlRealloc((void * *)ctxt->pushTab,
1811
 
                                    ctxt->nameMax * 3 *
1812
 
                                    sizeof(ctxt->pushTab[0]));
1813
 
        if (tmp2 == NULL) {
1814
 
            ctxt->nameMax /= 2;
1815
 
            goto mem_error;
1816
 
        }
1817
 
        ctxt->pushTab = tmp2;
1818
 
    }
1819
 
    ctxt->nameTab[ctxt->nameNr] = value;
1820
 
    ctxt->name = value;
1821
 
    ctxt->pushTab[ctxt->nameNr * 3] = (void *) prefix;
1822
 
    ctxt->pushTab[ctxt->nameNr * 3 + 1] = (void *) URI;
1823
 
    ctxt->pushTab[ctxt->nameNr * 3 + 2] = (void *) (long) nsNr;
1824
 
    return (ctxt->nameNr++);
1825
 
mem_error:
1826
 
    xmlErrMemory(ctxt, NULL);
1827
 
    return (-1);
1828
 
}
1829
 
/**
1830
 
 * nameNsPop:
1831
 
 * @ctxt: an XML parser context
1832
 
 *
1833
 
 * Pops the top element/prefix/URI name from the name stack
1834
 
 *
1835
 
 * Returns the name just removed
1836
 
 */
1837
 
static const xmlChar *
1838
 
nameNsPop(xmlParserCtxtPtr ctxt)
1839
 
{
1840
 
    const xmlChar *ret;
1841
 
 
1842
 
    if (ctxt->nameNr <= 0)
1843
 
        return (NULL);
1844
 
    ctxt->nameNr--;
1845
 
    if (ctxt->nameNr > 0)
1846
 
        ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
1847
 
    else
1848
 
        ctxt->name = NULL;
1849
 
    ret = ctxt->nameTab[ctxt->nameNr];
1850
 
    ctxt->nameTab[ctxt->nameNr] = NULL;
1851
 
    return (ret);
1852
 
}
1853
 
#endif /* LIBXML_PUSH_ENABLED */
1854
 
 
1855
 
/**
1856
 
 * namePush:
1857
 
 * @ctxt:  an XML parser context
1858
 
 * @value:  the element name
1859
 
 *
1860
 
 * Pushes a new element name on top of the name stack
1861
 
 *
1862
 
 * Returns -1 in case of error, the index in the stack otherwise
1863
 
 */
1864
 
int
1865
 
namePush(xmlParserCtxtPtr ctxt, const xmlChar * value)
1866
 
{
1867
 
    if (ctxt == NULL) return (-1);
1868
 
 
1869
 
    if (ctxt->nameNr >= ctxt->nameMax) {
1870
 
        const xmlChar * *tmp;
1871
 
        tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,
1872
 
                                    ctxt->nameMax * 2 *
1873
 
                                    sizeof(ctxt->nameTab[0]));
1874
 
        if (tmp == NULL) {
1875
 
            goto mem_error;
1876
 
        }
1877
 
        ctxt->nameTab = tmp;
1878
 
        ctxt->nameMax *= 2;
1879
 
    }
1880
 
    ctxt->nameTab[ctxt->nameNr] = value;
1881
 
    ctxt->name = value;
1882
 
    return (ctxt->nameNr++);
1883
 
mem_error:
1884
 
    xmlErrMemory(ctxt, NULL);
1885
 
    return (-1);
1886
 
}
1887
 
/**
1888
 
 * namePop:
1889
 
 * @ctxt: an XML parser context
1890
 
 *
1891
 
 * Pops the top element name from the name stack
1892
 
 *
1893
 
 * Returns the name just removed
1894
 
 */
1895
 
const xmlChar *
1896
 
namePop(xmlParserCtxtPtr ctxt)
1897
 
{
1898
 
    const xmlChar *ret;
1899
 
 
1900
 
    if ((ctxt == NULL) || (ctxt->nameNr <= 0))
1901
 
        return (NULL);
1902
 
    ctxt->nameNr--;
1903
 
    if (ctxt->nameNr > 0)
1904
 
        ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
1905
 
    else
1906
 
        ctxt->name = NULL;
1907
 
    ret = ctxt->nameTab[ctxt->nameNr];
1908
 
    ctxt->nameTab[ctxt->nameNr] = NULL;
1909
 
    return (ret);
1910
 
}
1911
 
 
1912
 
static int spacePush(xmlParserCtxtPtr ctxt, int val) {
1913
 
    if (ctxt->spaceNr >= ctxt->spaceMax) {
1914
 
        int *tmp;
1915
 
 
1916
 
        ctxt->spaceMax *= 2;
1917
 
        tmp = (int *) xmlRealloc(ctxt->spaceTab,
1918
 
                                 ctxt->spaceMax * sizeof(ctxt->spaceTab[0]));
1919
 
        if (tmp == NULL) {
1920
 
            xmlErrMemory(ctxt, NULL);
1921
 
            ctxt->spaceMax /=2;
1922
 
            return(-1);
1923
 
        }
1924
 
        ctxt->spaceTab = tmp;
1925
 
    }
1926
 
    ctxt->spaceTab[ctxt->spaceNr] = val;
1927
 
    ctxt->space = &ctxt->spaceTab[ctxt->spaceNr];
1928
 
    return(ctxt->spaceNr++);
1929
 
}
1930
 
 
1931
 
static int spacePop(xmlParserCtxtPtr ctxt) {
1932
 
    int ret;
1933
 
    if (ctxt->spaceNr <= 0) return(0);
1934
 
    ctxt->spaceNr--;
1935
 
    if (ctxt->spaceNr > 0)
1936
 
        ctxt->space = &ctxt->spaceTab[ctxt->spaceNr - 1];
1937
 
    else
1938
 
        ctxt->space = &ctxt->spaceTab[0];
1939
 
    ret = ctxt->spaceTab[ctxt->spaceNr];
1940
 
    ctxt->spaceTab[ctxt->spaceNr] = -1;
1941
 
    return(ret);
1942
 
}
1943
 
 
1944
 
/*
1945
 
 * Macros for accessing the content. Those should be used only by the parser,
1946
 
 * and not exported.
1947
 
 *
1948
 
 * Dirty macros, i.e. one often need to make assumption on the context to
1949
 
 * use them
1950
 
 *
1951
 
 *   CUR_PTR return the current pointer to the xmlChar to be parsed.
1952
 
 *           To be used with extreme caution since operations consuming
1953
 
 *           characters may move the input buffer to a different location !
1954
 
 *   CUR     returns the current xmlChar value, i.e. a 8 bit value if compiled
1955
 
 *           This should be used internally by the parser
1956
 
 *           only to compare to ASCII values otherwise it would break when
1957
 
 *           running with UTF-8 encoding.
1958
 
 *   RAW     same as CUR but in the input buffer, bypass any token
1959
 
 *           extraction that may have been done
1960
 
 *   NXT(n)  returns the n'th next xmlChar. Same as CUR is should be used only
1961
 
 *           to compare on ASCII based substring.
1962
 
 *   SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
1963
 
 *           strings without newlines within the parser.
1964
 
 *   NEXT1(l) Skip 1 xmlChar, and must also be used only to skip 1 non-newline ASCII
1965
 
 *           defined char within the parser.
1966
 
 * Clean macros, not dependent of an ASCII context, expect UTF-8 encoding
1967
 
 *
1968
 
 *   NEXT    Skip to the next character, this does the proper decoding
1969
 
 *           in UTF-8 mode. It also pop-up unfinished entities on the fly.
1970
 
 *   NEXTL(l) Skip the current unicode character of l xmlChars long.
1971
 
 *   CUR_CHAR(l) returns the current unicode character (int), set l
1972
 
 *           to the number of xmlChars used for the encoding [0-5].
1973
 
 *   CUR_SCHAR  same but operate on a string instead of the context
1974
 
 *   COPY_BUF  copy the current unicode char to the target buffer, increment
1975
 
 *            the index
1976
 
 *   GROW, SHRINK  handling of input buffers
1977
 
 */
1978
 
 
1979
 
#define RAW (*ctxt->input->cur)
1980
 
#define CUR (*ctxt->input->cur)
1981
 
#define NXT(val) ctxt->input->cur[(val)]
1982
 
#define CUR_PTR ctxt->input->cur
1983
 
 
1984
 
#define CMP4( s, c1, c2, c3, c4 ) \
1985
 
  ( ((unsigned char *) s)[ 0 ] == c1 && ((unsigned char *) s)[ 1 ] == c2 && \
1986
 
    ((unsigned char *) s)[ 2 ] == c3 && ((unsigned char *) s)[ 3 ] == c4 )
1987
 
#define CMP5( s, c1, c2, c3, c4, c5 ) \
1988
 
  ( CMP4( s, c1, c2, c3, c4 ) && ((unsigned char *) s)[ 4 ] == c5 )
1989
 
#define CMP6( s, c1, c2, c3, c4, c5, c6 ) \
1990
 
  ( CMP5( s, c1, c2, c3, c4, c5 ) && ((unsigned char *) s)[ 5 ] == c6 )
1991
 
#define CMP7( s, c1, c2, c3, c4, c5, c6, c7 ) \
1992
 
  ( CMP6( s, c1, c2, c3, c4, c5, c6 ) && ((unsigned char *) s)[ 6 ] == c7 )
1993
 
#define CMP8( s, c1, c2, c3, c4, c5, c6, c7, c8 ) \
1994
 
  ( CMP7( s, c1, c2, c3, c4, c5, c6, c7 ) && ((unsigned char *) s)[ 7 ] == c8 )
1995
 
#define CMP9( s, c1, c2, c3, c4, c5, c6, c7, c8, c9 ) \
1996
 
  ( CMP8( s, c1, c2, c3, c4, c5, c6, c7, c8 ) && \
1997
 
    ((unsigned char *) s)[ 8 ] == c9 )
1998
 
#define CMP10( s, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10 ) \
1999
 
  ( CMP9( s, c1, c2, c3, c4, c5, c6, c7, c8, c9 ) && \
2000
 
    ((unsigned char *) s)[ 9 ] == c10 )
2001
 
 
2002
 
#define SKIP(val) do {                                                  \
2003
 
    ctxt->nbChars += (val),ctxt->input->cur += (val),ctxt->input->col+=(val);                   \
2004
 
    if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);     \
2005
 
    if ((*ctxt->input->cur == 0) &&                                     \
2006
 
        (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))            \
2007
 
            xmlPopInput(ctxt);                                          \
2008
 
  } while (0)
2009
 
 
2010
 
#define SKIPL(val) do {                                                 \
2011
 
    int skipl;                                                          \
2012
 
    for(skipl=0; skipl<val; skipl++) {                                  \
2013
 
        if (*(ctxt->input->cur) == '\n') {                              \
2014
 
        ctxt->input->line++; ctxt->input->col = 1;                      \
2015
 
        } else ctxt->input->col++;                                      \
2016
 
        ctxt->nbChars++;                                                \
2017
 
        ctxt->input->cur++;                                             \
2018
 
    }                                                                   \
2019
 
    if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);     \
2020
 
    if ((*ctxt->input->cur == 0) &&                                     \
2021
 
        (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))            \
2022
 
            xmlPopInput(ctxt);                                          \
2023
 
  } while (0)
2024
 
 
2025
 
#define SHRINK if ((ctxt->progressive == 0) &&                          \
2026
 
                   (ctxt->input->cur - ctxt->input->base > 2 * INPUT_CHUNK) && \
2027
 
                   (ctxt->input->end - ctxt->input->cur < 2 * INPUT_CHUNK)) \
2028
 
        xmlSHRINK (ctxt);
2029
 
 
2030
 
static void xmlSHRINK (xmlParserCtxtPtr ctxt) {
2031
 
    xmlParserInputShrink(ctxt->input);
2032
 
    if ((*ctxt->input->cur == 0) &&
2033
 
        (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
2034
 
            xmlPopInput(ctxt);
2035
 
  }
2036
 
 
2037
 
#define GROW if ((ctxt->progressive == 0) &&                            \
2038
 
                 (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK))   \
2039
 
        xmlGROW (ctxt);
2040
 
 
2041
 
static void xmlGROW (xmlParserCtxtPtr ctxt) {
2042
 
    if ((((ctxt->input->end - ctxt->input->cur) > XML_MAX_LOOKUP_LIMIT) ||
2043
 
         ((ctxt->input->cur - ctxt->input->base) > XML_MAX_LOOKUP_LIMIT)) &&
2044
 
         ((ctxt->input->buf) && (ctxt->input->buf->readcallback != (xmlInputReadCallback) xmlNop)) &&
2045
 
        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
2046
 
        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "Huge input lookup");
2047
 
        ctxt->instate = XML_PARSER_EOF;
2048
 
    }
2049
 
    xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
2050
 
    if ((ctxt->input->cur != NULL) && (*ctxt->input->cur == 0) &&
2051
 
        (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
2052
 
            xmlPopInput(ctxt);
2053
 
}
2054
 
 
2055
 
#define SKIP_BLANKS xmlSkipBlankChars(ctxt)
2056
 
 
2057
 
#define NEXT xmlNextChar(ctxt)
2058
 
 
2059
 
#define NEXT1 {                                                         \
2060
 
        ctxt->input->col++;                                             \
2061
 
        ctxt->input->cur++;                                             \
2062
 
        ctxt->nbChars++;                                                \
2063
 
        if (*ctxt->input->cur == 0)                                     \
2064
 
            xmlParserInputGrow(ctxt->input, INPUT_CHUNK);               \
2065
 
    }
2066
 
 
2067
 
#define NEXTL(l) do {                                                   \
2068
 
    if (*(ctxt->input->cur) == '\n') {                                  \
2069
 
        ctxt->input->line++; ctxt->input->col = 1;                      \
2070
 
    } else ctxt->input->col++;                                          \
2071
 
    ctxt->input->cur += l;                              \
2072
 
    if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);     \
2073
 
  } while (0)
2074
 
 
2075
 
#define CUR_CHAR(l) xmlCurrentChar(ctxt, &l)
2076
 
#define CUR_SCHAR(s, l) xmlStringCurrentChar(ctxt, s, &l)
2077
 
 
2078
 
#define COPY_BUF(l,b,i,v)                                               \
2079
 
    if (l == 1) b[i++] = (xmlChar) v;                                   \
2080
 
    else i += xmlCopyCharMultiByte(&b[i],v)
2081
 
 
2082
 
/**
2083
 
 * xmlSkipBlankChars:
2084
 
 * @ctxt:  the XML parser context
2085
 
 *
2086
 
 * skip all blanks character found at that point in the input streams.
2087
 
 * It pops up finished entities in the process if allowable at that point.
2088
 
 *
2089
 
 * Returns the number of space chars skipped
2090
 
 */
2091
 
 
2092
 
int
2093
 
xmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
2094
 
    int res = 0;
2095
 
 
2096
 
    /*
2097
 
     * It's Okay to use CUR/NEXT here since all the blanks are on
2098
 
     * the ASCII range.
2099
 
     */
2100
 
    if ((ctxt->inputNr == 1) && (ctxt->instate != XML_PARSER_DTD)) {
2101
 
        const xmlChar *cur;
2102
 
        /*
2103
 
         * if we are in the document content, go really fast
2104
 
         */
2105
 
        cur = ctxt->input->cur;
2106
 
        while (IS_BLANK_CH(*cur)) {
2107
 
            if (*cur == '\n') {
2108
 
                ctxt->input->line++; ctxt->input->col = 1;
2109
 
            }
2110
 
            cur++;
2111
 
            res++;
2112
 
            if (*cur == 0) {
2113
 
                ctxt->input->cur = cur;
2114
 
                xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
2115
 
                cur = ctxt->input->cur;
2116
 
            }
2117
 
        }
2118
 
        ctxt->input->cur = cur;
2119
 
    } else {
2120
 
        int cur;
2121
 
        do {
2122
 
            cur = CUR;
2123
 
            while (IS_BLANK_CH(cur)) { /* CHECKED tstblanks.xml */
2124
 
                NEXT;
2125
 
                cur = CUR;
2126
 
                res++;
2127
 
            }
2128
 
            while ((cur == 0) && (ctxt->inputNr > 1) &&
2129
 
                   (ctxt->instate != XML_PARSER_COMMENT)) {
2130
 
                xmlPopInput(ctxt);
2131
 
                cur = CUR;
2132
 
            }
2133
 
            /*
2134
 
             * Need to handle support of entities branching here
2135
 
             */
2136
 
            if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);
2137
 
        } while (IS_BLANK(cur)); /* CHECKED tstblanks.xml */
2138
 
    }
2139
 
    return(res);
2140
 
}
2141
 
 
2142
 
/************************************************************************
2143
 
 *                                                                      *
2144
 
 *              Commodity functions to handle entities                  *
2145
 
 *                                                                      *
2146
 
 ************************************************************************/
2147
 
 
2148
 
/**
2149
 
 * xmlPopInput:
2150
 
 * @ctxt:  an XML parser context
2151
 
 *
2152
 
 * xmlPopInput: the current input pointed by ctxt->input came to an end
2153
 
 *          pop it and return the next char.
2154
 
 *
2155
 
 * Returns the current xmlChar in the parser context
2156
 
 */
2157
 
xmlChar
2158
 
xmlPopInput(xmlParserCtxtPtr ctxt) {
2159
 
    if ((ctxt == NULL) || (ctxt->inputNr <= 1)) return(0);
2160
 
    if (xmlParserDebugEntities)
2161
 
        xmlGenericError(xmlGenericErrorContext,
2162
 
                "Popping input %d\n", ctxt->inputNr);
2163
 
    xmlFreeInputStream(inputPop(ctxt));
2164
 
    if ((*ctxt->input->cur == 0) &&
2165
 
        (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
2166
 
            return(xmlPopInput(ctxt));
2167
 
    return(CUR);
2168
 
}
2169
 
 
2170
 
/**
2171
 
 * xmlPushInput:
2172
 
 * @ctxt:  an XML parser context
2173
 
 * @input:  an XML parser input fragment (entity, XML fragment ...).
2174
 
 *
2175
 
 * xmlPushInput: switch to a new input stream which is stacked on top
2176
 
 *               of the previous one(s).
2177
 
 * Returns -1 in case of error or the index in the input stack
2178
 
 */
2179
 
int
2180
 
xmlPushInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr input) {
2181
 
    int ret;
2182
 
    if (input == NULL) return(-1);
2183
 
 
2184
 
    if (xmlParserDebugEntities) {
2185
 
        if ((ctxt->input != NULL) && (ctxt->input->filename))
2186
 
            xmlGenericError(xmlGenericErrorContext,
2187
 
                    "%s(%d): ", ctxt->input->filename,
2188
 
                    ctxt->input->line);
2189
 
        xmlGenericError(xmlGenericErrorContext,
2190
 
                "Pushing input %d : %.30s\n", ctxt->inputNr+1, input->cur);
2191
 
    }
2192
 
    ret = inputPush(ctxt, input);
2193
 
    if (ctxt->instate == XML_PARSER_EOF)
2194
 
        return(-1);
2195
 
    GROW;
2196
 
    return(ret);
2197
 
}
2198
 
 
2199
 
/**
2200
 
 * xmlParseCharRef:
2201
 
 * @ctxt:  an XML parser context
2202
 
 *
2203
 
 * parse Reference declarations
2204
 
 *
2205
 
 * [66] CharRef ::= '&#' [0-9]+ ';' |
2206
 
 *                  '&#x' [0-9a-fA-F]+ ';'
2207
 
 *
2208
 
 * [ WFC: Legal Character ]
2209
 
 * Characters referred to using character references must match the
2210
 
 * production for Char.
2211
 
 *
2212
 
 * Returns the value parsed (as an int), 0 in case of error
2213
 
 */
2214
 
int
2215
 
xmlParseCharRef(xmlParserCtxtPtr ctxt) {
2216
 
    unsigned int val = 0;
2217
 
    int count = 0;
2218
 
    unsigned int outofrange = 0;
2219
 
 
2220
 
    /*
2221
 
     * Using RAW/CUR/NEXT is okay since we are working on ASCII range here
2222
 
     */
2223
 
    if ((RAW == '&') && (NXT(1) == '#') &&
2224
 
        (NXT(2) == 'x')) {
2225
 
        SKIP(3);
2226
 
        GROW;
2227
 
        while (RAW != ';') { /* loop blocked by count */
2228
 
            if (count++ > 20) {
2229
 
                count = 0;
2230
 
                GROW;
2231
 
                if (ctxt->instate == XML_PARSER_EOF)
2232
 
                    return(0);
2233
 
            }
2234
 
            if ((RAW >= '0') && (RAW <= '9'))
2235
 
                val = val * 16 + (CUR - '0');
2236
 
            else if ((RAW >= 'a') && (RAW <= 'f') && (count < 20))
2237
 
                val = val * 16 + (CUR - 'a') + 10;
2238
 
            else if ((RAW >= 'A') && (RAW <= 'F') && (count < 20))
2239
 
                val = val * 16 + (CUR - 'A') + 10;
2240
 
            else {
2241
 
                xmlFatalErr(ctxt, XML_ERR_INVALID_HEX_CHARREF, NULL);
2242
 
                val = 0;
2243
 
                break;
2244
 
            }
2245
 
            if (val > 0x10FFFF)
2246
 
                outofrange = val;
2247
 
 
2248
 
            NEXT;
2249
 
            count++;
2250
 
        }
2251
 
        if (RAW == ';') {
2252
 
            /* on purpose to avoid reentrancy problems with NEXT and SKIP */
2253
 
            ctxt->input->col++;
2254
 
            ctxt->nbChars ++;
2255
 
            ctxt->input->cur++;
2256
 
        }
2257
 
    } else if  ((RAW == '&') && (NXT(1) == '#')) {
2258
 
        SKIP(2);
2259
 
        GROW;
2260
 
        while (RAW != ';') { /* loop blocked by count */
2261
 
            if (count++ > 20) {
2262
 
                count = 0;
2263
 
                GROW;
2264
 
                if (ctxt->instate == XML_PARSER_EOF)
2265
 
                    return(0);
2266
 
            }
2267
 
            if ((RAW >= '0') && (RAW <= '9'))
2268
 
                val = val * 10 + (CUR - '0');
2269
 
            else {
2270
 
                xmlFatalErr(ctxt, XML_ERR_INVALID_DEC_CHARREF, NULL);
2271
 
                val = 0;
2272
 
                break;
2273
 
            }
2274
 
            if (val > 0x10FFFF)
2275
 
                outofrange = val;
2276
 
 
2277
 
            NEXT;
2278
 
            count++;
2279
 
        }
2280
 
        if (RAW == ';') {
2281
 
            /* on purpose to avoid reentrancy problems with NEXT and SKIP */
2282
 
            ctxt->input->col++;
2283
 
            ctxt->nbChars ++;
2284
 
            ctxt->input->cur++;
2285
 
        }
2286
 
    } else {
2287
 
        xmlFatalErr(ctxt, XML_ERR_INVALID_CHARREF, NULL);
2288
 
    }
2289
 
 
2290
 
    /*
2291
 
     * [ WFC: Legal Character ]
2292
 
     * Characters referred to using character references must match the
2293
 
     * production for Char.
2294
 
     */
2295
 
    if ((IS_CHAR(val) && (outofrange == 0))) {
2296
 
        return(val);
2297
 
    } else {
2298
 
        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
2299
 
                          "xmlParseCharRef: invalid xmlChar value %d\n",
2300
 
                          val);
2301
 
    }
2302
 
    return(0);
2303
 
}
2304
 
 
2305
 
/**
2306
 
 * xmlParseStringCharRef:
2307
 
 * @ctxt:  an XML parser context
2308
 
 * @str:  a pointer to an index in the string
2309
 
 *
2310
 
 * parse Reference declarations, variant parsing from a string rather
2311
 
 * than an an input flow.
2312
 
 *
2313
 
 * [66] CharRef ::= '&#' [0-9]+ ';' |
2314
 
 *                  '&#x' [0-9a-fA-F]+ ';'
2315
 
 *
2316
 
 * [ WFC: Legal Character ]
2317
 
 * Characters referred to using character references must match the
2318
 
 * production for Char.
2319
 
 *
2320
 
 * Returns the value parsed (as an int), 0 in case of error, str will be
2321
 
 *         updated to the current value of the index
2322
 
 */
2323
 
static int
2324
 
xmlParseStringCharRef(xmlParserCtxtPtr ctxt, const xmlChar **str) {
2325
 
    const xmlChar *ptr;
2326
 
    xmlChar cur;
2327
 
    unsigned int val = 0;
2328
 
    unsigned int outofrange = 0;
2329
 
 
2330
 
    if ((str == NULL) || (*str == NULL)) return(0);
2331
 
    ptr = *str;
2332
 
    cur = *ptr;
2333
 
    if ((cur == '&') && (ptr[1] == '#') && (ptr[2] == 'x')) {
2334
 
        ptr += 3;
2335
 
        cur = *ptr;
2336
 
        while (cur != ';') { /* Non input consuming loop */
2337
 
            if ((cur >= '0') && (cur <= '9'))
2338
 
                val = val * 16 + (cur - '0');
2339
 
            else if ((cur >= 'a') && (cur <= 'f'))
2340
 
                val = val * 16 + (cur - 'a') + 10;
2341
 
            else if ((cur >= 'A') && (cur <= 'F'))
2342
 
                val = val * 16 + (cur - 'A') + 10;
2343
 
            else {
2344
 
                xmlFatalErr(ctxt, XML_ERR_INVALID_HEX_CHARREF, NULL);
2345
 
                val = 0;
2346
 
                break;
2347
 
            }
2348
 
            if (val > 0x10FFFF)
2349
 
                outofrange = val;
2350
 
 
2351
 
            ptr++;
2352
 
            cur = *ptr;
2353
 
        }
2354
 
        if (cur == ';')
2355
 
            ptr++;
2356
 
    } else if  ((cur == '&') && (ptr[1] == '#')){
2357
 
        ptr += 2;
2358
 
        cur = *ptr;
2359
 
        while (cur != ';') { /* Non input consuming loops */
2360
 
            if ((cur >= '0') && (cur <= '9'))
2361
 
                val = val * 10 + (cur - '0');
2362
 
            else {
2363
 
                xmlFatalErr(ctxt, XML_ERR_INVALID_DEC_CHARREF, NULL);
2364
 
                val = 0;
2365
 
                break;
2366
 
            }
2367
 
            if (val > 0x10FFFF)
2368
 
                outofrange = val;
2369
 
 
2370
 
            ptr++;
2371
 
            cur = *ptr;
2372
 
        }
2373
 
        if (cur == ';')
2374
 
            ptr++;
2375
 
    } else {
2376
 
        xmlFatalErr(ctxt, XML_ERR_INVALID_CHARREF, NULL);
2377
 
        return(0);
2378
 
    }
2379
 
    *str = ptr;
2380
 
 
2381
 
    /*
2382
 
     * [ WFC: Legal Character ]
2383
 
     * Characters referred to using character references must match the
2384
 
     * production for Char.
2385
 
     */
2386
 
    if ((IS_CHAR(val) && (outofrange == 0))) {
2387
 
        return(val);
2388
 
    } else {
2389
 
        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
2390
 
                          "xmlParseStringCharRef: invalid xmlChar value %d\n",
2391
 
                          val);
2392
 
    }
2393
 
    return(0);
2394
 
}
2395
 
 
2396
 
/**
2397
 
 * xmlNewBlanksWrapperInputStream:
2398
 
 * @ctxt:  an XML parser context
2399
 
 * @entity:  an Entity pointer
2400
 
 *
2401
 
 * Create a new input stream for wrapping
2402
 
 * blanks around a PEReference
2403
 
 *
2404
 
 * Returns the new input stream or NULL
2405
 
 */
2406
 
 
2407
 
static void deallocblankswrapper (xmlChar *str) {xmlFree(str);}
2408
 
 
2409
 
static xmlParserInputPtr
2410
 
xmlNewBlanksWrapperInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
2411
 
    xmlParserInputPtr input;
2412
 
    xmlChar *buffer;
2413
 
    size_t length;
2414
 
    if (entity == NULL) {
2415
 
        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
2416
 
                    "xmlNewBlanksWrapperInputStream entity\n");
2417
 
        return(NULL);
2418
 
    }
2419
 
    if (xmlParserDebugEntities)
2420
 
        xmlGenericError(xmlGenericErrorContext,
2421
 
                "new blanks wrapper for entity: %s\n", entity->name);
2422
 
    input = xmlNewInputStream(ctxt);
2423
 
    if (input == NULL) {
2424
 
        return(NULL);
2425
 
    }
2426
 
    length = xmlStrlen(entity->name) + 5;
2427
 
    buffer = xmlMallocAtomic(length);
2428
 
    if (buffer == NULL) {
2429
 
        xmlErrMemory(ctxt, NULL);
2430
 
        xmlFree(input);
2431
 
        return(NULL);
2432
 
    }
2433
 
    buffer [0] = ' ';
2434
 
    buffer [1] = '%';
2435
 
    buffer [length-3] = ';';
2436
 
    buffer [length-2] = ' ';
2437
 
    buffer [length-1] = 0;
2438
 
    memcpy(buffer + 2, entity->name, length - 5);
2439
 
    input->free = deallocblankswrapper;
2440
 
    input->base = buffer;
2441
 
    input->cur = buffer;
2442
 
    input->length = length;
2443
 
    input->end = &buffer[length];
2444
 
    return(input);
2445
 
}
2446
 
 
2447
 
/**
2448
 
 * xmlParserHandlePEReference:
2449
 
 * @ctxt:  the parser context
2450
 
 *
2451
 
 * [69] PEReference ::= '%' Name ';'
2452
 
 *
2453
 
 * [ WFC: No Recursion ]
2454
 
 * A parsed entity must not contain a recursive
2455
 
 * reference to itself, either directly or indirectly.
2456
 
 *
2457
 
 * [ WFC: Entity Declared ]
2458
 
 * In a document without any DTD, a document with only an internal DTD
2459
 
 * subset which contains no parameter entity references, or a document
2460
 
 * with "standalone='yes'", ...  ... The declaration of a parameter
2461
 
 * entity must precede any reference to it...
2462
 
 *
2463
 
 * [ VC: Entity Declared ]
2464
 
 * In a document with an external subset or external parameter entities
2465
 
 * with "standalone='no'", ...  ... The declaration of a parameter entity
2466
 
 * must precede any reference to it...
2467
 
 *
2468
 
 * [ WFC: In DTD ]
2469
 
 * Parameter-entity references may only appear in the DTD.
2470
 
 * NOTE: misleading but this is handled.
2471
 
 *
2472
 
 * A PEReference may have been detected in the current input stream
2473
 
 * the handling is done accordingly to
2474
 
 *      http://www.w3.org/TR/REC-xml#entproc
2475
 
 * i.e.
2476
 
 *   - Included in literal in entity values
2477
 
 *   - Included as Parameter Entity reference within DTDs
2478
 
 */
2479
 
void
2480
 
xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) {
2481
 
    const xmlChar *name;
2482
 
    xmlEntityPtr entity = NULL;
2483
 
    xmlParserInputPtr input;
2484
 
 
2485
 
    if (RAW != '%') return;
2486
 
    switch(ctxt->instate) {
2487
 
        case XML_PARSER_CDATA_SECTION:
2488
 
            return;
2489
 
        case XML_PARSER_COMMENT:
2490
 
            return;
2491
 
        case XML_PARSER_START_TAG:
2492
 
            return;
2493
 
        case XML_PARSER_END_TAG:
2494
 
            return;
2495
 
        case XML_PARSER_EOF:
2496
 
            xmlFatalErr(ctxt, XML_ERR_PEREF_AT_EOF, NULL);
2497
 
            return;
2498
 
        case XML_PARSER_PROLOG:
2499
 
        case XML_PARSER_START:
2500
 
        case XML_PARSER_MISC:
2501
 
            xmlFatalErr(ctxt, XML_ERR_PEREF_IN_PROLOG, NULL);
2502
 
            return;
2503
 
        case XML_PARSER_ENTITY_DECL:
2504
 
        case XML_PARSER_CONTENT:
2505
 
        case XML_PARSER_ATTRIBUTE_VALUE:
2506
 
        case XML_PARSER_PI:
2507
 
        case XML_PARSER_SYSTEM_LITERAL:
2508
 
        case XML_PARSER_PUBLIC_LITERAL:
2509
 
            /* we just ignore it there */
2510
 
            return;
2511
 
        case XML_PARSER_EPILOG:
2512
 
            xmlFatalErr(ctxt, XML_ERR_PEREF_IN_EPILOG, NULL);
2513
 
            return;
2514
 
        case XML_PARSER_ENTITY_VALUE:
2515
 
            /*
2516
 
             * NOTE: in the case of entity values, we don't do the
2517
 
             *       substitution here since we need the literal
2518
 
             *       entity value to be able to save the internal
2519
 
             *       subset of the document.
2520
 
             *       This will be handled by xmlStringDecodeEntities
2521
 
             */
2522
 
            return;
2523
 
        case XML_PARSER_DTD:
2524
 
            /*
2525
 
             * [WFC: Well-Formedness Constraint: PEs in Internal Subset]
2526
 
             * In the internal DTD subset, parameter-entity references
2527
 
             * can occur only where markup declarations can occur, not
2528
 
             * within markup declarations.
2529
 
             * In that case this is handled in xmlParseMarkupDecl
2530
 
             */
2531
 
            if ((ctxt->external == 0) && (ctxt->inputNr == 1))
2532
 
                return;
2533
 
            if (IS_BLANK_CH(NXT(1)) || NXT(1) == 0)
2534
 
                return;
2535
 
            break;
2536
 
        case XML_PARSER_IGNORE:
2537
 
            return;
2538
 
    }
2539
 
 
2540
 
    NEXT;
2541
 
    name = xmlParseName(ctxt);
2542
 
    if (xmlParserDebugEntities)
2543
 
        xmlGenericError(xmlGenericErrorContext,
2544
 
                "PEReference: %s\n", name);
2545
 
    if (name == NULL) {
2546
 
        xmlFatalErr(ctxt, XML_ERR_PEREF_NO_NAME, NULL);
2547
 
    } else {
2548
 
        if (RAW == ';') {
2549
 
            NEXT;
2550
 
            if ((ctxt->sax != NULL) && (ctxt->sax->getParameterEntity != NULL))
2551
 
                entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
2552
 
            if (ctxt->instate == XML_PARSER_EOF)
2553
 
                return;
2554
 
            if (entity == NULL) {
2555
 
 
2556
 
                /*
2557
 
                 * [ WFC: Entity Declared ]
2558
 
                 * In a document without any DTD, a document with only an
2559
 
                 * internal DTD subset which contains no parameter entity
2560
 
                 * references, or a document with "standalone='yes'", ...
2561
 
                 * ... The declaration of a parameter entity must precede
2562
 
                 * any reference to it...
2563
 
                 */
2564
 
                if ((ctxt->standalone == 1) ||
2565
 
                    ((ctxt->hasExternalSubset == 0) &&
2566
 
                     (ctxt->hasPErefs == 0))) {
2567
 
                    xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
2568
 
                         "PEReference: %%%s; not found\n", name);
2569
 
                } else {
2570
 
                    /*
2571
 
                     * [ VC: Entity Declared ]
2572
 
                     * In a document with an external subset or external
2573
 
                     * parameter entities with "standalone='no'", ...
2574
 
                     * ... The declaration of a parameter entity must precede
2575
 
                     * any reference to it...
2576
 
                     */
2577
 
                    if ((ctxt->validate) && (ctxt->vctxt.error != NULL)) {
2578
 
                        xmlValidityError(ctxt, XML_WAR_UNDECLARED_ENTITY,
2579
 
                                         "PEReference: %%%s; not found\n",
2580
 
                                         name, NULL);
2581
 
                    } else
2582
 
                        xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
2583
 
                                      "PEReference: %%%s; not found\n",
2584
 
                                      name, NULL);
2585
 
                    ctxt->valid = 0;
2586
 
                }
2587
 
            } else if (ctxt->input->free != deallocblankswrapper) {
2588
 
                    input = xmlNewBlanksWrapperInputStream(ctxt, entity);
2589
 
                    if (xmlPushInput(ctxt, input) < 0)
2590
 
                        return;
2591
 
            } else {
2592
 
                if ((entity->etype == XML_INTERNAL_PARAMETER_ENTITY) ||
2593
 
                    (entity->etype == XML_EXTERNAL_PARAMETER_ENTITY)) {
2594
 
                    xmlChar start[4];
2595
 
                    xmlCharEncoding enc;
2596
 
 
2597
 
                    /*
2598
 
                     * Note: external parsed entities will not be loaded, it is
2599
 
                     * not required for a non-validating parser, unless the
2600
 
                     * option of validating, or substituting entities were
2601
 
                     * given. Doing so is far more secure as the parser will
2602
 
                     * only process data coming from the document entity by
2603
 
                     * default.
2604
 
                     */
2605
 
                    if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
2606
 
                        ((ctxt->options & XML_PARSE_NOENT) == 0) &&
2607
 
                        ((ctxt->options & XML_PARSE_DTDVALID) == 0) &&
2608
 
                        (ctxt->validate == 0))
2609
 
                        return;
2610
 
 
2611
 
                    /*
2612
 
                     * handle the extra spaces added before and after
2613
 
                     * c.f. http://www.w3.org/TR/REC-xml#as-PE
2614
 
                     * this is done independently.
2615
 
                     */
2616
 
                    input = xmlNewEntityInputStream(ctxt, entity);
2617
 
                    if (xmlPushInput(ctxt, input) < 0)
2618
 
                        return;
2619
 
 
2620
 
                    /*
2621
 
                     * Get the 4 first bytes and decode the charset
2622
 
                     * if enc != XML_CHAR_ENCODING_NONE
2623
 
                     * plug some encoding conversion routines.
2624
 
                     * Note that, since we may have some non-UTF8
2625
 
                     * encoding (like UTF16, bug 135229), the 'length'
2626
 
                     * is not known, but we can calculate based upon
2627
 
                     * the amount of data in the buffer.
2628
 
                     */
2629
 
                    GROW
2630
 
                    if (ctxt->instate == XML_PARSER_EOF)
2631
 
                        return;
2632
 
                    if ((ctxt->input->end - ctxt->input->cur)>=4) {
2633
 
                        start[0] = RAW;
2634
 
                        start[1] = NXT(1);
2635
 
                        start[2] = NXT(2);
2636
 
                        start[3] = NXT(3);
2637
 
                        enc = xmlDetectCharEncoding(start, 4);
2638
 
                        if (enc != XML_CHAR_ENCODING_NONE) {
2639
 
                            xmlSwitchEncoding(ctxt, enc);
2640
 
                        }
2641
 
                    }
2642
 
 
2643
 
                    if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
2644
 
                        (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l' )) &&
2645
 
                        (IS_BLANK_CH(NXT(5)))) {
2646
 
                        xmlParseTextDecl(ctxt);
2647
 
                    }
2648
 
                } else {
2649
 
                    xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
2650
 
                             "PEReference: %s is not a parameter entity\n",
2651
 
                                      name);
2652
 
                }
2653
 
            }
2654
 
        } else {
2655
 
            xmlFatalErr(ctxt, XML_ERR_PEREF_SEMICOL_MISSING, NULL);
2656
 
        }
2657
 
    }
2658
 
}
2659
 
 
2660
 
/*
2661
 
 * Macro used to grow the current buffer.
2662
 
 * buffer##_size is expected to be a size_t
2663
 
 * mem_error: is expected to handle memory allocation failures
2664
 
 */
2665
 
#define growBuffer(buffer, n) {                                         \
2666
 
    xmlChar *tmp;                                                       \
2667
 
    size_t new_size = buffer##_size * 2 + n;                            \
2668
 
    if (new_size < buffer##_size) goto mem_error;                       \
2669
 
    tmp = (xmlChar *) xmlRealloc(buffer, new_size);                     \
2670
 
    if (tmp == NULL) goto mem_error;                                    \
2671
 
    buffer = tmp;                                                       \
2672
 
    buffer##_size = new_size;                                           \
2673
 
}
2674
 
 
2675
 
/**
2676
 
 * xmlStringLenDecodeEntities:
2677
 
 * @ctxt:  the parser context
2678
 
 * @str:  the input string
2679
 
 * @len: the string length
2680
 
 * @what:  combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
2681
 
 * @end:  an end marker xmlChar, 0 if none
2682
 
 * @end2:  an end marker xmlChar, 0 if none
2683
 
 * @end3:  an end marker xmlChar, 0 if none
2684
 
 *
2685
 
 * Takes a entity string content and process to do the adequate substitutions.
2686
 
 *
2687
 
 * [67] Reference ::= EntityRef | CharRef
2688
 
 *
2689
 
 * [69] PEReference ::= '%' Name ';'
2690
 
 *
2691
 
 * Returns A newly allocated string with the substitution done. The caller
2692
 
 *      must deallocate it !
2693
 
 */
2694
 
xmlChar *
2695
 
xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
2696
 
                      int what, xmlChar end, xmlChar  end2, xmlChar end3) {
2697
 
    xmlChar *buffer = NULL;
2698
 
    size_t buffer_size = 0;
2699
 
    size_t nbchars = 0;
2700
 
 
2701
 
    xmlChar *current = NULL;
2702
 
    xmlChar *rep = NULL;
2703
 
    const xmlChar *last;
2704
 
    xmlEntityPtr ent;
2705
 
    int c,l;
2706
 
 
2707
 
    if ((ctxt == NULL) || (str == NULL) || (len < 0))
2708
 
        return(NULL);
2709
 
    last = str + len;
2710
 
 
2711
 
    if (((ctxt->depth > 40) &&
2712
 
         ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
2713
 
        (ctxt->depth > 1024)) {
2714
 
        xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
2715
 
        return(NULL);
2716
 
    }
2717
 
 
2718
 
    /*
2719
 
     * allocate a translation buffer.
2720
 
     */
2721
 
    buffer_size = XML_PARSER_BIG_BUFFER_SIZE;
2722
 
    buffer = (xmlChar *) xmlMallocAtomic(buffer_size);
2723
 
    if (buffer == NULL) goto mem_error;
2724
 
 
2725
 
    /*
2726
 
     * OK loop until we reach one of the ending char or a size limit.
2727
 
     * we are operating on already parsed values.
2728
 
     */
2729
 
    if (str < last)
2730
 
        c = CUR_SCHAR(str, l);
2731
 
    else
2732
 
        c = 0;
2733
 
    while ((c != 0) && (c != end) && /* non input consuming loop */
2734
 
           (c != end2) && (c != end3)) {
2735
 
 
2736
 
        if (c == 0) break;
2737
 
        if ((c == '&') && (str[1] == '#')) {
2738
 
            int val = xmlParseStringCharRef(ctxt, &str);
2739
 
            if (val != 0) {
2740
 
                COPY_BUF(0,buffer,nbchars,val);
2741
 
            }
2742
 
            if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
2743
 
                growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2744
 
            }
2745
 
        } else if ((c == '&') && (what & XML_SUBSTITUTE_REF)) {
2746
 
            if (xmlParserDebugEntities)
2747
 
                xmlGenericError(xmlGenericErrorContext,
2748
 
                        "String decoding Entity Reference: %.30s\n",
2749
 
                        str);
2750
 
            ent = xmlParseStringEntityRef(ctxt, &str);
2751
 
            if ((ctxt->lastError.code == XML_ERR_ENTITY_LOOP) ||
2752
 
                (ctxt->lastError.code == XML_ERR_INTERNAL_ERROR))
2753
 
                goto int_error;
2754
 
            if (ent != NULL)
2755
 
                ctxt->nbentities += ent->checked / 2;
2756
 
            if ((ent != NULL) &&
2757
 
                (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
2758
 
                if (ent->content != NULL) {
2759
 
                    COPY_BUF(0,buffer,nbchars,ent->content[0]);
2760
 
                    if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
2761
 
                        growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2762
 
                    }
2763
 
                } else {
2764
 
                    xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
2765
 
                            "predefined entity has no content\n");
2766
 
                }
2767
 
            } else if ((ent != NULL) && (ent->content != NULL)) {
2768
 
                ctxt->depth++;
2769
 
                rep = xmlStringDecodeEntities(ctxt, ent->content, what,
2770
 
                                              0, 0, 0);
2771
 
                ctxt->depth--;
2772
 
 
2773
 
                if (rep != NULL) {
2774
 
                    current = rep;
2775
 
                    while (*current != 0) { /* non input consuming loop */
2776
 
                        buffer[nbchars++] = *current++;
2777
 
                        if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
2778
 
                            if (xmlParserEntityCheck(ctxt, nbchars, ent, 0))
2779
 
                                goto int_error;
2780
 
                            growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2781
 
                        }
2782
 
                    }
2783
 
                    xmlFree(rep);
2784
 
                    rep = NULL;
2785
 
                }
2786
 
            } else if (ent != NULL) {
2787
 
                int i = xmlStrlen(ent->name);
2788
 
                const xmlChar *cur = ent->name;
2789
 
 
2790
 
                buffer[nbchars++] = '&';
2791
 
                if (nbchars + i + XML_PARSER_BUFFER_SIZE > buffer_size) {
2792
 
                    growBuffer(buffer, i + XML_PARSER_BUFFER_SIZE);
2793
 
                }
2794
 
                for (;i > 0;i--)
2795
 
                    buffer[nbchars++] = *cur++;
2796
 
                buffer[nbchars++] = ';';
2797
 
            }
2798
 
        } else if (c == '%' && (what & XML_SUBSTITUTE_PEREF)) {
2799
 
            if (xmlParserDebugEntities)
2800
 
                xmlGenericError(xmlGenericErrorContext,
2801
 
                        "String decoding PE Reference: %.30s\n", str);
2802
 
            ent = xmlParseStringPEReference(ctxt, &str);
2803
 
            if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
2804
 
                goto int_error;
2805
 
            if (ent != NULL)
2806
 
                ctxt->nbentities += ent->checked / 2;
2807
 
            if (ent != NULL) {
2808
 
                if (ent->content == NULL) {
2809
 
                    xmlLoadEntityContent(ctxt, ent);
2810
 
                }
2811
 
                ctxt->depth++;
2812
 
                rep = xmlStringDecodeEntities(ctxt, ent->content, what,
2813
 
                                              0, 0, 0);
2814
 
                ctxt->depth--;
2815
 
                if (rep != NULL) {
2816
 
                    current = rep;
2817
 
                    while (*current != 0) { /* non input consuming loop */
2818
 
                        buffer[nbchars++] = *current++;
2819
 
                        if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
2820
 
                            if (xmlParserEntityCheck(ctxt, nbchars, ent, 0))
2821
 
                                goto int_error;
2822
 
                            growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2823
 
                        }
2824
 
                    }
2825
 
                    xmlFree(rep);
2826
 
                    rep = NULL;
2827
 
                }
2828
 
            }
2829
 
        } else {
2830
 
            COPY_BUF(l,buffer,nbchars,c);
2831
 
            str += l;
2832
 
            if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
2833
 
                growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2834
 
            }
2835
 
        }
2836
 
        if (str < last)
2837
 
            c = CUR_SCHAR(str, l);
2838
 
        else
2839
 
            c = 0;
2840
 
    }
2841
 
    buffer[nbchars] = 0;
2842
 
    return(buffer);
2843
 
 
2844
 
mem_error:
2845
 
    xmlErrMemory(ctxt, NULL);
2846
 
int_error:
2847
 
    if (rep != NULL)
2848
 
        xmlFree(rep);
2849
 
    if (buffer != NULL)
2850
 
        xmlFree(buffer);
2851
 
    return(NULL);
2852
 
}
2853
 
 
2854
 
/**
2855
 
 * xmlStringDecodeEntities:
2856
 
 * @ctxt:  the parser context
2857
 
 * @str:  the input string
2858
 
 * @what:  combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
2859
 
 * @end:  an end marker xmlChar, 0 if none
2860
 
 * @end2:  an end marker xmlChar, 0 if none
2861
 
 * @end3:  an end marker xmlChar, 0 if none
2862
 
 *
2863
 
 * Takes a entity string content and process to do the adequate substitutions.
2864
 
 *
2865
 
 * [67] Reference ::= EntityRef | CharRef
2866
 
 *
2867
 
 * [69] PEReference ::= '%' Name ';'
2868
 
 *
2869
 
 * Returns A newly allocated string with the substitution done. The caller
2870
 
 *      must deallocate it !
2871
 
 */
2872
 
xmlChar *
2873
 
xmlStringDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int what,
2874
 
                        xmlChar end, xmlChar  end2, xmlChar end3) {
2875
 
    if ((ctxt == NULL) || (str == NULL)) return(NULL);
2876
 
    return(xmlStringLenDecodeEntities(ctxt, str, xmlStrlen(str), what,
2877
 
           end, end2, end3));
2878
 
}
2879
 
 
2880
 
/************************************************************************
2881
 
 *                                                                      *
2882
 
 *              Commodity functions, cleanup needed ?                   *
2883
 
 *                                                                      *
2884
 
 ************************************************************************/
2885
 
 
2886
 
/**
2887
 
 * areBlanks:
2888
 
 * @ctxt:  an XML parser context
2889
 
 * @str:  a xmlChar *
2890
 
 * @len:  the size of @str
2891
 
 * @blank_chars: we know the chars are blanks
2892
 
 *
2893
 
 * Is this a sequence of blank chars that one can ignore ?
2894
 
 *
2895
 
 * Returns 1 if ignorable 0 otherwise.
2896
 
 */
2897
 
 
2898
 
static int areBlanks(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
2899
 
                     int blank_chars) {
2900
 
    int i, ret;
2901
 
    xmlNodePtr lastChild;
2902
 
 
2903
 
    /*
2904
 
     * Don't spend time trying to differentiate them, the same callback is
2905
 
     * used !
2906
 
     */
2907
 
    if (ctxt->sax->ignorableWhitespace == ctxt->sax->characters)
2908
 
        return(0);
2909
 
 
2910
 
    /*
2911
 
     * Check for xml:space value.
2912
 
     */
2913
 
    if ((ctxt->space == NULL) || (*(ctxt->space) == 1) ||
2914
 
        (*(ctxt->space) == -2))
2915
 
        return(0);
2916
 
 
2917
 
    /*
2918
 
     * Check that the string is made of blanks
2919
 
     */
2920
 
    if (blank_chars == 0) {
2921
 
        for (i = 0;i < len;i++)
2922
 
            if (!(IS_BLANK_CH(str[i]))) return(0);
2923
 
    }
2924
 
 
2925
 
    /*
2926
 
     * Look if the element is mixed content in the DTD if available
2927
 
     */
2928
 
    if (ctxt->node == NULL) return(0);
2929
 
    if (ctxt->myDoc != NULL) {
2930
 
        ret = xmlIsMixedElement(ctxt->myDoc, ctxt->node->name);
2931
 
        if (ret == 0) return(1);
2932
 
        if (ret == 1) return(0);
2933
 
    }
2934
 
 
2935
 
    /*
2936
 
     * Otherwise, heuristic :-\
2937
 
     */
2938
 
    if ((RAW != '<') && (RAW != 0xD)) return(0);
2939
 
    if ((ctxt->node->children == NULL) &&
2940
 
        (RAW == '<') && (NXT(1) == '/')) return(0);
2941
 
 
2942
 
    lastChild = xmlGetLastChild(ctxt->node);
2943
 
    if (lastChild == NULL) {
2944
 
        if ((ctxt->node->type != XML_ELEMENT_NODE) &&
2945
 
            (ctxt->node->content != NULL)) return(0);
2946
 
    } else if (xmlNodeIsText(lastChild))
2947
 
        return(0);
2948
 
    else if ((ctxt->node->children != NULL) &&
2949
 
             (xmlNodeIsText(ctxt->node->children)))
2950
 
        return(0);
2951
 
    return(1);
2952
 
}
2953
 
 
2954
 
/************************************************************************
2955
 
 *                                                                      *
2956
 
 *              Extra stuff for namespace support                       *
2957
 
 *      Relates to http://www.w3.org/TR/WD-xml-names                    *
2958
 
 *                                                                      *
2959
 
 ************************************************************************/
2960
 
 
2961
 
/**
2962
 
 * xmlSplitQName:
2963
 
 * @ctxt:  an XML parser context
2964
 
 * @name:  an XML parser context
2965
 
 * @prefix:  a xmlChar **
2966
 
 *
2967
 
 * parse an UTF8 encoded XML qualified name string
2968
 
 *
2969
 
 * [NS 5] QName ::= (Prefix ':')? LocalPart
2970
 
 *
2971
 
 * [NS 6] Prefix ::= NCName
2972
 
 *
2973
 
 * [NS 7] LocalPart ::= NCName
2974
 
 *
2975
 
 * Returns the local part, and prefix is updated
2976
 
 *   to get the Prefix if any.
2977
 
 */
2978
 
 
2979
 
xmlChar *
2980
 
xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) {
2981
 
    xmlChar buf[XML_MAX_NAMELEN + 5];
2982
 
    xmlChar *buffer = NULL;
2983
 
    int len = 0;
2984
 
    int max = XML_MAX_NAMELEN;
2985
 
    xmlChar *ret = NULL;
2986
 
    const xmlChar *cur = name;
2987
 
    int c;
2988
 
 
2989
 
    if (prefix == NULL) return(NULL);
2990
 
    *prefix = NULL;
2991
 
 
2992
 
    if (cur == NULL) return(NULL);
2993
 
 
2994
 
#ifndef XML_XML_NAMESPACE
2995
 
    /* xml: prefix is not really a namespace */
2996
 
    if ((cur[0] == 'x') && (cur[1] == 'm') &&
2997
 
        (cur[2] == 'l') && (cur[3] == ':'))
2998
 
        return(xmlStrdup(name));
2999
 
#endif
3000
 
 
3001
 
    /* nasty but well=formed */
3002
 
    if (cur[0] == ':')
3003
 
        return(xmlStrdup(name));
3004
 
 
3005
 
    c = *cur++;
3006
 
    while ((c != 0) && (c != ':') && (len < max)) { /* tested bigname.xml */
3007
 
        buf[len++] = c;
3008
 
        c = *cur++;
3009
 
    }
3010
 
    if (len >= max) {
3011
 
        /*
3012
 
         * Okay someone managed to make a huge name, so he's ready to pay
3013
 
         * for the processing speed.
3014
 
         */
3015
 
        max = len * 2;
3016
 
 
3017
 
        buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
3018
 
        if (buffer == NULL) {
3019
 
            xmlErrMemory(ctxt, NULL);
3020
 
            return(NULL);
3021
 
        }
3022
 
        memcpy(buffer, buf, len);
3023
 
        while ((c != 0) && (c != ':')) { /* tested bigname.xml */
3024
 
            if (len + 10 > max) {
3025
 
                xmlChar *tmp;
3026
 
 
3027
 
                max *= 2;
3028
 
                tmp = (xmlChar *) xmlRealloc(buffer,
3029
 
                                                max * sizeof(xmlChar));
3030
 
                if (tmp == NULL) {
3031
 
                    xmlFree(buffer);
3032
 
                    xmlErrMemory(ctxt, NULL);
3033
 
                    return(NULL);
3034
 
                }
3035
 
                buffer = tmp;
3036
 
            }
3037
 
            buffer[len++] = c;
3038
 
            c = *cur++;
3039
 
        }
3040
 
        buffer[len] = 0;
3041
 
    }
3042
 
 
3043
 
    if ((c == ':') && (*cur == 0)) {
3044
 
        if (buffer != NULL)
3045
 
            xmlFree(buffer);
3046
 
        *prefix = NULL;
3047
 
        return(xmlStrdup(name));
3048
 
    }
3049
 
 
3050
 
    if (buffer == NULL)
3051
 
        ret = xmlStrndup(buf, len);
3052
 
    else {
3053
 
        ret = buffer;
3054
 
        buffer = NULL;
3055
 
        max = XML_MAX_NAMELEN;
3056
 
    }
3057
 
 
3058
 
 
3059
 
    if (c == ':') {
3060
 
        c = *cur;
3061
 
        *prefix = ret;
3062
 
        if (c == 0) {
3063
 
            return(xmlStrndup(BAD_CAST "", 0));
3064
 
        }
3065
 
        len = 0;
3066
 
 
3067
 
        /*
3068
 
         * Check that the first character is proper to start
3069
 
         * a new name
3070
 
         */
3071
 
        if (!(((c >= 0x61) && (c <= 0x7A)) ||
3072
 
              ((c >= 0x41) && (c <= 0x5A)) ||
3073
 
              (c == '_') || (c == ':'))) {
3074
 
            int l;
3075
 
            int first = CUR_SCHAR(cur, l);
3076
 
 
3077
 
            if (!IS_LETTER(first) && (first != '_')) {
3078
 
                xmlFatalErrMsgStr(ctxt, XML_NS_ERR_QNAME,
3079
 
                            "Name %s is not XML Namespace compliant\n",
3080
 
                                  name);
3081
 
            }
3082
 
        }
3083
 
        cur++;
3084
 
 
3085
 
        while ((c != 0) && (len < max)) { /* tested bigname2.xml */
3086
 
            buf[len++] = c;
3087
 
            c = *cur++;
3088
 
        }
3089
 
        if (len >= max) {
3090
 
            /*
3091
 
             * Okay someone managed to make a huge name, so he's ready to pay
3092
 
             * for the processing speed.
3093
 
             */
3094
 
            max = len * 2;
3095
 
 
3096
 
            buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
3097
 
            if (buffer == NULL) {
3098
 
                xmlErrMemory(ctxt, NULL);
3099
 
                return(NULL);
3100
 
            }
3101
 
            memcpy(buffer, buf, len);
3102
 
            while (c != 0) { /* tested bigname2.xml */
3103
 
                if (len + 10 > max) {
3104
 
                    xmlChar *tmp;
3105
 
 
3106
 
                    max *= 2;
3107
 
                    tmp = (xmlChar *) xmlRealloc(buffer,
3108
 
                                                    max * sizeof(xmlChar));
3109
 
                    if (tmp == NULL) {
3110
 
                        xmlErrMemory(ctxt, NULL);
3111
 
                        xmlFree(buffer);
3112
 
                        return(NULL);
3113
 
                    }
3114
 
                    buffer = tmp;
3115
 
                }
3116
 
                buffer[len++] = c;
3117
 
                c = *cur++;
3118
 
            }
3119
 
            buffer[len] = 0;
3120
 
        }
3121
 
 
3122
 
        if (buffer == NULL)
3123
 
            ret = xmlStrndup(buf, len);
3124
 
        else {
3125
 
            ret = buffer;
3126
 
        }
3127
 
    }
3128
 
 
3129
 
    return(ret);
3130
 
}
3131
 
 
3132
 
/************************************************************************
3133
 
 *                                                                      *
3134
 
 *                      The parser itself                               *
3135
 
 *      Relates to http://www.w3.org/TR/REC-xml                         *
3136
 
 *                                                                      *
3137
 
 ************************************************************************/
3138
 
 
3139
 
/************************************************************************
3140
 
 *                                                                      *
3141
 
 *      Routines to parse Name, NCName and NmToken                      *
3142
 
 *                                                                      *
3143
 
 ************************************************************************/
3144
 
#ifdef DEBUG
3145
 
static unsigned long nbParseName = 0;
3146
 
static unsigned long nbParseNmToken = 0;
3147
 
static unsigned long nbParseNCName = 0;
3148
 
static unsigned long nbParseNCNameComplex = 0;
3149
 
static unsigned long nbParseNameComplex = 0;
3150
 
static unsigned long nbParseStringName = 0;
3151
 
#endif
3152
 
 
3153
 
/*
3154
 
 * The two following functions are related to the change of accepted
3155
 
 * characters for Name and NmToken in the Revision 5 of XML-1.0
3156
 
 * They correspond to the modified production [4] and the new production [4a]
3157
 
 * changes in that revision. Also note that the macros used for the
3158
 
 * productions Letter, Digit, CombiningChar and Extender are not needed
3159
 
 * anymore.
3160
 
 * We still keep compatibility to pre-revision5 parsing semantic if the
3161
 
 * new XML_PARSE_OLD10 option is given to the parser.
3162
 
 */
3163
 
static int
3164
 
xmlIsNameStartChar(xmlParserCtxtPtr ctxt, int c) {
3165
 
    if ((ctxt->options & XML_PARSE_OLD10) == 0) {
3166
 
        /*
3167
 
         * Use the new checks of production [4] [4a] amd [5] of the
3168
 
         * Update 5 of XML-1.0
3169
 
         */
3170
 
        if ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
3171
 
            (((c >= 'a') && (c <= 'z')) ||
3172
 
             ((c >= 'A') && (c <= 'Z')) ||
3173
 
             (c == '_') || (c == ':') ||
3174
 
             ((c >= 0xC0) && (c <= 0xD6)) ||
3175
 
             ((c >= 0xD8) && (c <= 0xF6)) ||
3176
 
             ((c >= 0xF8) && (c <= 0x2FF)) ||
3177
 
             ((c >= 0x370) && (c <= 0x37D)) ||
3178
 
             ((c >= 0x37F) && (c <= 0x1FFF)) ||
3179
 
             ((c >= 0x200C) && (c <= 0x200D)) ||
3180
 
             ((c >= 0x2070) && (c <= 0x218F)) ||
3181
 
             ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3182
 
             ((c >= 0x3001) && (c <= 0xD7FF)) ||
3183
 
             ((c >= 0xF900) && (c <= 0xFDCF)) ||
3184
 
             ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3185
 
             ((c >= 0x10000) && (c <= 0xEFFFF))))
3186
 
            return(1);
3187
 
    } else {
3188
 
        if (IS_LETTER(c) || (c == '_') || (c == ':'))
3189
 
            return(1);
3190
 
    }
3191
 
    return(0);
3192
 
}
3193
 
 
3194
 
static int
3195
 
xmlIsNameChar(xmlParserCtxtPtr ctxt, int c) {
3196
 
    if ((ctxt->options & XML_PARSE_OLD10) == 0) {
3197
 
        /*
3198
 
         * Use the new checks of production [4] [4a] amd [5] of the
3199
 
         * Update 5 of XML-1.0
3200
 
         */
3201
 
        if ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
3202
 
            (((c >= 'a') && (c <= 'z')) ||
3203
 
             ((c >= 'A') && (c <= 'Z')) ||
3204
 
             ((c >= '0') && (c <= '9')) || /* !start */
3205
 
             (c == '_') || (c == ':') ||
3206
 
             (c == '-') || (c == '.') || (c == 0xB7) || /* !start */
3207
 
             ((c >= 0xC0) && (c <= 0xD6)) ||
3208
 
             ((c >= 0xD8) && (c <= 0xF6)) ||
3209
 
             ((c >= 0xF8) && (c <= 0x2FF)) ||
3210
 
             ((c >= 0x300) && (c <= 0x36F)) || /* !start */
3211
 
             ((c >= 0x370) && (c <= 0x37D)) ||
3212
 
             ((c >= 0x37F) && (c <= 0x1FFF)) ||
3213
 
             ((c >= 0x200C) && (c <= 0x200D)) ||
3214
 
             ((c >= 0x203F) && (c <= 0x2040)) || /* !start */
3215
 
             ((c >= 0x2070) && (c <= 0x218F)) ||
3216
 
             ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3217
 
             ((c >= 0x3001) && (c <= 0xD7FF)) ||
3218
 
             ((c >= 0xF900) && (c <= 0xFDCF)) ||
3219
 
             ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3220
 
             ((c >= 0x10000) && (c <= 0xEFFFF))))
3221
 
             return(1);
3222
 
    } else {
3223
 
        if ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
3224
 
            (c == '.') || (c == '-') ||
3225
 
            (c == '_') || (c == ':') ||
3226
 
            (IS_COMBINING(c)) ||
3227
 
            (IS_EXTENDER(c)))
3228
 
            return(1);
3229
 
    }
3230
 
    return(0);
3231
 
}
3232
 
 
3233
 
static xmlChar * xmlParseAttValueInternal(xmlParserCtxtPtr ctxt,
3234
 
                                          int *len, int *alloc, int normalize);
3235
 
 
3236
 
static const xmlChar *
3237
 
xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
3238
 
    int len = 0, l;
3239
 
    int c;
3240
 
    int count = 0;
3241
 
 
3242
 
#ifdef DEBUG
3243
 
    nbParseNameComplex++;
3244
 
#endif
3245
 
 
3246
 
    /*
3247
 
     * Handler for more complex cases
3248
 
     */
3249
 
    GROW;
3250
 
    if (ctxt->instate == XML_PARSER_EOF)
3251
 
        return(NULL);
3252
 
    c = CUR_CHAR(l);
3253
 
    if ((ctxt->options & XML_PARSE_OLD10) == 0) {
3254
 
        /*
3255
 
         * Use the new checks of production [4] [4a] amd [5] of the
3256
 
         * Update 5 of XML-1.0
3257
 
         */
3258
 
        if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
3259
 
            (!(((c >= 'a') && (c <= 'z')) ||
3260
 
               ((c >= 'A') && (c <= 'Z')) ||
3261
 
               (c == '_') || (c == ':') ||
3262
 
               ((c >= 0xC0) && (c <= 0xD6)) ||
3263
 
               ((c >= 0xD8) && (c <= 0xF6)) ||
3264
 
               ((c >= 0xF8) && (c <= 0x2FF)) ||
3265
 
               ((c >= 0x370) && (c <= 0x37D)) ||
3266
 
               ((c >= 0x37F) && (c <= 0x1FFF)) ||
3267
 
               ((c >= 0x200C) && (c <= 0x200D)) ||
3268
 
               ((c >= 0x2070) && (c <= 0x218F)) ||
3269
 
               ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3270
 
               ((c >= 0x3001) && (c <= 0xD7FF)) ||
3271
 
               ((c >= 0xF900) && (c <= 0xFDCF)) ||
3272
 
               ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3273
 
               ((c >= 0x10000) && (c <= 0xEFFFF))))) {
3274
 
            return(NULL);
3275
 
        }
3276
 
        len += l;
3277
 
        NEXTL(l);
3278
 
        c = CUR_CHAR(l);
3279
 
        while ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
3280
 
               (((c >= 'a') && (c <= 'z')) ||
3281
 
                ((c >= 'A') && (c <= 'Z')) ||
3282
 
                ((c >= '0') && (c <= '9')) || /* !start */
3283
 
                (c == '_') || (c == ':') ||
3284
 
                (c == '-') || (c == '.') || (c == 0xB7) || /* !start */
3285
 
                ((c >= 0xC0) && (c <= 0xD6)) ||
3286
 
                ((c >= 0xD8) && (c <= 0xF6)) ||
3287
 
                ((c >= 0xF8) && (c <= 0x2FF)) ||
3288
 
                ((c >= 0x300) && (c <= 0x36F)) || /* !start */
3289
 
                ((c >= 0x370) && (c <= 0x37D)) ||
3290
 
                ((c >= 0x37F) && (c <= 0x1FFF)) ||
3291
 
                ((c >= 0x200C) && (c <= 0x200D)) ||
3292
 
                ((c >= 0x203F) && (c <= 0x2040)) || /* !start */
3293
 
                ((c >= 0x2070) && (c <= 0x218F)) ||
3294
 
                ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3295
 
                ((c >= 0x3001) && (c <= 0xD7FF)) ||
3296
 
                ((c >= 0xF900) && (c <= 0xFDCF)) ||
3297
 
                ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3298
 
                ((c >= 0x10000) && (c <= 0xEFFFF))
3299
 
                )) {
3300
 
            if (count++ > XML_PARSER_CHUNK_SIZE) {
3301
 
                count = 0;
3302
 
                GROW;
3303
 
                if (ctxt->instate == XML_PARSER_EOF)
3304
 
                    return(NULL);
3305
 
            }
3306
 
            len += l;
3307
 
            NEXTL(l);
3308
 
            c = CUR_CHAR(l);
3309
 
        }
3310
 
    } else {
3311
 
        if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
3312
 
            (!IS_LETTER(c) && (c != '_') &&
3313
 
             (c != ':'))) {
3314
 
            return(NULL);
3315
 
        }
3316
 
        len += l;
3317
 
        NEXTL(l);
3318
 
        c = CUR_CHAR(l);
3319
 
 
3320
 
        while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
3321
 
               ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
3322
 
                (c == '.') || (c == '-') ||
3323
 
                (c == '_') || (c == ':') ||
3324
 
                (IS_COMBINING(c)) ||
3325
 
                (IS_EXTENDER(c)))) {
3326
 
            if (count++ > XML_PARSER_CHUNK_SIZE) {
3327
 
                count = 0;
3328
 
                GROW;
3329
 
                if (ctxt->instate == XML_PARSER_EOF)
3330
 
                    return(NULL);
3331
 
            }
3332
 
            len += l;
3333
 
            NEXTL(l);
3334
 
            c = CUR_CHAR(l);
3335
 
            if (c == 0) {
3336
 
                count = 0;
3337
 
                GROW;
3338
 
                if (ctxt->instate == XML_PARSER_EOF)
3339
 
                    return(NULL);
3340
 
                c = CUR_CHAR(l);
3341
 
            }
3342
 
        }
3343
 
    }
3344
 
    if ((len > XML_MAX_NAME_LENGTH) &&
3345
 
        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3346
 
        xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name");
3347
 
        return(NULL);
3348
 
    }
3349
 
    if ((*ctxt->input->cur == '\n') && (ctxt->input->cur[-1] == '\r'))
3350
 
        return(xmlDictLookup(ctxt->dict, ctxt->input->cur - (len + 1), len));
3351
 
    return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
3352
 
}
3353
 
 
3354
 
/**
3355
 
 * xmlParseName:
3356
 
 * @ctxt:  an XML parser context
3357
 
 *
3358
 
 * parse an XML name.
3359
 
 *
3360
 
 * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
3361
 
 *                  CombiningChar | Extender
3362
 
 *
3363
 
 * [5] Name ::= (Letter | '_' | ':') (NameChar)*
3364
 
 *
3365
 
 * [6] Names ::= Name (#x20 Name)*
3366
 
 *
3367
 
 * Returns the Name parsed or NULL
3368
 
 */
3369
 
 
3370
 
const xmlChar *
3371
 
xmlParseName(xmlParserCtxtPtr ctxt) {
3372
 
    const xmlChar *in;
3373
 
    const xmlChar *ret;
3374
 
    int count = 0;
3375
 
 
3376
 
    GROW;
3377
 
 
3378
 
#ifdef DEBUG
3379
 
    nbParseName++;
3380
 
#endif
3381
 
 
3382
 
    /*
3383
 
     * Accelerator for simple ASCII names
3384
 
     */
3385
 
    in = ctxt->input->cur;
3386
 
    if (((*in >= 0x61) && (*in <= 0x7A)) ||
3387
 
        ((*in >= 0x41) && (*in <= 0x5A)) ||
3388
 
        (*in == '_') || (*in == ':')) {
3389
 
        in++;
3390
 
        while (((*in >= 0x61) && (*in <= 0x7A)) ||
3391
 
               ((*in >= 0x41) && (*in <= 0x5A)) ||
3392
 
               ((*in >= 0x30) && (*in <= 0x39)) ||
3393
 
               (*in == '_') || (*in == '-') ||
3394
 
               (*in == ':') || (*in == '.'))
3395
 
            in++;
3396
 
        if ((*in > 0) && (*in < 0x80)) {
3397
 
            count = in - ctxt->input->cur;
3398
 
            if ((count > XML_MAX_NAME_LENGTH) &&
3399
 
                ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3400
 
                xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name");
3401
 
                return(NULL);
3402
 
            }
3403
 
            ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
3404
 
            ctxt->input->cur = in;
3405
 
            ctxt->nbChars += count;
3406
 
            ctxt->input->col += count;
3407
 
            if (ret == NULL)
3408
 
                xmlErrMemory(ctxt, NULL);
3409
 
            return(ret);
3410
 
        }
3411
 
    }
3412
 
    /* accelerator for special cases */
3413
 
    return(xmlParseNameComplex(ctxt));
3414
 
}
3415
 
 
3416
 
static const xmlChar *
3417
 
xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
3418
 
    int len = 0, l;
3419
 
    int c;
3420
 
    int count = 0;
3421
 
    const xmlChar *end; /* needed because CUR_CHAR() can move cur on \r\n */
3422
 
 
3423
 
#ifdef DEBUG
3424
 
    nbParseNCNameComplex++;
3425
 
#endif
3426
 
 
3427
 
    /*
3428
 
     * Handler for more complex cases
3429
 
     */
3430
 
    GROW;
3431
 
    end = ctxt->input->cur;
3432
 
    c = CUR_CHAR(l);
3433
 
    if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
3434
 
        (!xmlIsNameStartChar(ctxt, c) || (c == ':'))) {
3435
 
        return(NULL);
3436
 
    }
3437
 
 
3438
 
    while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
3439
 
           (xmlIsNameChar(ctxt, c) && (c != ':'))) {
3440
 
        if (count++ > XML_PARSER_CHUNK_SIZE) {
3441
 
            if ((len > XML_MAX_NAME_LENGTH) &&
3442
 
                ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3443
 
                xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
3444
 
                return(NULL);
3445
 
            }
3446
 
            count = 0;
3447
 
            GROW;
3448
 
            if (ctxt->instate == XML_PARSER_EOF)
3449
 
                return(NULL);
3450
 
        }
3451
 
        len += l;
3452
 
        NEXTL(l);
3453
 
        end = ctxt->input->cur;
3454
 
        c = CUR_CHAR(l);
3455
 
        if (c == 0) {
3456
 
            count = 0;
3457
 
            GROW;
3458
 
            if (ctxt->instate == XML_PARSER_EOF)
3459
 
                return(NULL);
3460
 
            end = ctxt->input->cur;
3461
 
            c = CUR_CHAR(l);
3462
 
        }
3463
 
    }
3464
 
    if ((len > XML_MAX_NAME_LENGTH) &&
3465
 
        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3466
 
        xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
3467
 
        return(NULL);
3468
 
    }
3469
 
    return(xmlDictLookup(ctxt->dict, end - len, len));
3470
 
}
3471
 
 
3472
 
/**
3473
 
 * xmlParseNCName:
3474
 
 * @ctxt:  an XML parser context
3475
 
 * @len:  length of the string parsed
3476
 
 *
3477
 
 * parse an XML name.
3478
 
 *
3479
 
 * [4NS] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
3480
 
 *                      CombiningChar | Extender
3481
 
 *
3482
 
 * [5NS] NCName ::= (Letter | '_') (NCNameChar)*
3483
 
 *
3484
 
 * Returns the Name parsed or NULL
3485
 
 */
3486
 
 
3487
 
static const xmlChar *
3488
 
xmlParseNCName(xmlParserCtxtPtr ctxt) {
3489
 
    const xmlChar *in;
3490
 
    const xmlChar *ret;
3491
 
    int count = 0;
3492
 
 
3493
 
#ifdef DEBUG
3494
 
    nbParseNCName++;
3495
 
#endif
3496
 
 
3497
 
    /*
3498
 
     * Accelerator for simple ASCII names
3499
 
     */
3500
 
    in = ctxt->input->cur;
3501
 
    if (((*in >= 0x61) && (*in <= 0x7A)) ||
3502
 
        ((*in >= 0x41) && (*in <= 0x5A)) ||
3503
 
        (*in == '_')) {
3504
 
        in++;
3505
 
        while (((*in >= 0x61) && (*in <= 0x7A)) ||
3506
 
               ((*in >= 0x41) && (*in <= 0x5A)) ||
3507
 
               ((*in >= 0x30) && (*in <= 0x39)) ||
3508
 
               (*in == '_') || (*in == '-') ||
3509
 
               (*in == '.'))
3510
 
            in++;
3511
 
        if ((*in > 0) && (*in < 0x80)) {
3512
 
            count = in - ctxt->input->cur;
3513
 
            if ((count > XML_MAX_NAME_LENGTH) &&
3514
 
                ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3515
 
                xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
3516
 
                return(NULL);
3517
 
            }
3518
 
            ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
3519
 
            ctxt->input->cur = in;
3520
 
            ctxt->nbChars += count;
3521
 
            ctxt->input->col += count;
3522
 
            if (ret == NULL) {
3523
 
                xmlErrMemory(ctxt, NULL);
3524
 
            }
3525
 
            return(ret);
3526
 
        }
3527
 
    }
3528
 
    return(xmlParseNCNameComplex(ctxt));
3529
 
}
3530
 
 
3531
 
/**
3532
 
 * xmlParseNameAndCompare:
3533
 
 * @ctxt:  an XML parser context
3534
 
 *
3535
 
 * parse an XML name and compares for match
3536
 
 * (specialized for endtag parsing)
3537
 
 *
3538
 
 * Returns NULL for an illegal name, (xmlChar*) 1 for success
3539
 
 * and the name for mismatch
3540
 
 */
3541
 
 
3542
 
static const xmlChar *
3543
 
xmlParseNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *other) {
3544
 
    register const xmlChar *cmp = other;
3545
 
    register const xmlChar *in;
3546
 
    const xmlChar *ret;
3547
 
 
3548
 
    GROW;
3549
 
    if (ctxt->instate == XML_PARSER_EOF)
3550
 
        return(NULL);
3551
 
 
3552
 
    in = ctxt->input->cur;
3553
 
    while (*in != 0 && *in == *cmp) {
3554
 
        ++in;
3555
 
        ++cmp;
3556
 
        ctxt->input->col++;
3557
 
    }
3558
 
    if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) {
3559
 
        /* success */
3560
 
        ctxt->input->cur = in;
3561
 
        return (const xmlChar*) 1;
3562
 
    }
3563
 
    /* failure (or end of input buffer), check with full function */
3564
 
    ret = xmlParseName (ctxt);
3565
 
    /* strings coming from the dictionnary direct compare possible */
3566
 
    if (ret == other) {
3567
 
        return (const xmlChar*) 1;
3568
 
    }
3569
 
    return ret;
3570
 
}
3571
 
 
3572
 
/**
3573
 
 * xmlParseStringName:
3574
 
 * @ctxt:  an XML parser context
3575
 
 * @str:  a pointer to the string pointer (IN/OUT)
3576
 
 *
3577
 
 * parse an XML name.
3578
 
 *
3579
 
 * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
3580
 
 *                  CombiningChar | Extender
3581
 
 *
3582
 
 * [5] Name ::= (Letter | '_' | ':') (NameChar)*
3583
 
 *
3584
 
 * [6] Names ::= Name (#x20 Name)*
3585
 
 *
3586
 
 * Returns the Name parsed or NULL. The @str pointer
3587
 
 * is updated to the current location in the string.
3588
 
 */
3589
 
 
3590
 
static xmlChar *
3591
 
xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
3592
 
    xmlChar buf[XML_MAX_NAMELEN + 5];
3593
 
    const xmlChar *cur = *str;
3594
 
    int len = 0, l;
3595
 
    int c;
3596
 
 
3597
 
#ifdef DEBUG
3598
 
    nbParseStringName++;
3599
 
#endif
3600
 
 
3601
 
    c = CUR_SCHAR(cur, l);
3602
 
    if (!xmlIsNameStartChar(ctxt, c)) {
3603
 
        return(NULL);
3604
 
    }
3605
 
 
3606
 
    COPY_BUF(l,buf,len,c);
3607
 
    cur += l;
3608
 
    c = CUR_SCHAR(cur, l);
3609
 
    while (xmlIsNameChar(ctxt, c)) {
3610
 
        COPY_BUF(l,buf,len,c);
3611
 
        cur += l;
3612
 
        c = CUR_SCHAR(cur, l);
3613
 
        if (len >= XML_MAX_NAMELEN) { /* test bigentname.xml */
3614
 
            /*
3615
 
             * Okay someone managed to make a huge name, so he's ready to pay
3616
 
             * for the processing speed.
3617
 
             */
3618
 
            xmlChar *buffer;
3619
 
            int max = len * 2;
3620
 
 
3621
 
            buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
3622
 
            if (buffer == NULL) {
3623
 
                xmlErrMemory(ctxt, NULL);
3624
 
                return(NULL);
3625
 
            }
3626
 
            memcpy(buffer, buf, len);
3627
 
            while (xmlIsNameChar(ctxt, c)) {
3628
 
                if (len + 10 > max) {
3629
 
                    xmlChar *tmp;
3630
 
 
3631
 
                    if ((len > XML_MAX_NAME_LENGTH) &&
3632
 
                        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3633
 
                        xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
3634
 
                        xmlFree(buffer);
3635
 
                        return(NULL);
3636
 
                    }
3637
 
                    max *= 2;
3638
 
                    tmp = (xmlChar *) xmlRealloc(buffer,
3639
 
                                                    max * sizeof(xmlChar));
3640
 
                    if (tmp == NULL) {
3641
 
                        xmlErrMemory(ctxt, NULL);
3642
 
                        xmlFree(buffer);
3643
 
                        return(NULL);
3644
 
                    }
3645
 
                    buffer = tmp;
3646
 
                }
3647
 
                COPY_BUF(l,buffer,len,c);
3648
 
                cur += l;
3649
 
                c = CUR_SCHAR(cur, l);
3650
 
            }
3651
 
            buffer[len] = 0;
3652
 
            *str = cur;
3653
 
            return(buffer);
3654
 
        }
3655
 
    }
3656
 
    if ((len > XML_MAX_NAME_LENGTH) &&
3657
 
        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3658
 
        xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
3659
 
        return(NULL);
3660
 
    }
3661
 
    *str = cur;
3662
 
    return(xmlStrndup(buf, len));
3663
 
}
3664
 
 
3665
 
/**
3666
 
 * xmlParseNmtoken:
3667
 
 * @ctxt:  an XML parser context
3668
 
 *
3669
 
 * parse an XML Nmtoken.
3670
 
 *
3671
 
 * [7] Nmtoken ::= (NameChar)+
3672
 
 *
3673
 
 * [8] Nmtokens ::= Nmtoken (#x20 Nmtoken)*
3674
 
 *
3675
 
 * Returns the Nmtoken parsed or NULL
3676
 
 */
3677
 
 
3678
 
xmlChar *
3679
 
xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
3680
 
    xmlChar buf[XML_MAX_NAMELEN + 5];
3681
 
    int len = 0, l;
3682
 
    int c;
3683
 
    int count = 0;
3684
 
 
3685
 
#ifdef DEBUG
3686
 
    nbParseNmToken++;
3687
 
#endif
3688
 
 
3689
 
    GROW;
3690
 
    if (ctxt->instate == XML_PARSER_EOF)
3691
 
        return(NULL);
3692
 
    c = CUR_CHAR(l);
3693
 
 
3694
 
    while (xmlIsNameChar(ctxt, c)) {
3695
 
        if (count++ > XML_PARSER_CHUNK_SIZE) {
3696
 
            count = 0;
3697
 
            GROW;
3698
 
        }
3699
 
        COPY_BUF(l,buf,len,c);
3700
 
        NEXTL(l);
3701
 
        c = CUR_CHAR(l);
3702
 
        if (c == 0) {
3703
 
            count = 0;
3704
 
            GROW;
3705
 
            if (ctxt->instate == XML_PARSER_EOF)
3706
 
                return(NULL);
3707
 
            c = CUR_CHAR(l);
3708
 
        }
3709
 
        if (len >= XML_MAX_NAMELEN) {
3710
 
            /*
3711
 
             * Okay someone managed to make a huge token, so he's ready to pay
3712
 
             * for the processing speed.
3713
 
             */
3714
 
            xmlChar *buffer;
3715
 
            int max = len * 2;
3716
 
 
3717
 
            buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
3718
 
            if (buffer == NULL) {
3719
 
                xmlErrMemory(ctxt, NULL);
3720
 
                return(NULL);
3721
 
            }
3722
 
            memcpy(buffer, buf, len);
3723
 
            while (xmlIsNameChar(ctxt, c)) {
3724
 
                if (count++ > XML_PARSER_CHUNK_SIZE) {
3725
 
                    count = 0;
3726
 
                    GROW;
3727
 
                    if (ctxt->instate == XML_PARSER_EOF) {
3728
 
                        xmlFree(buffer);
3729
 
                        return(NULL);
3730
 
                    }
3731
 
                }
3732
 
                if (len + 10 > max) {
3733
 
                    xmlChar *tmp;
3734
 
 
3735
 
                    if ((max > XML_MAX_NAME_LENGTH) &&
3736
 
                        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3737
 
                        xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken");
3738
 
                        xmlFree(buffer);
3739
 
                        return(NULL);
3740
 
                    }
3741
 
                    max *= 2;
3742
 
                    tmp = (xmlChar *) xmlRealloc(buffer,
3743
 
                                                    max * sizeof(xmlChar));
3744
 
                    if (tmp == NULL) {
3745
 
                        xmlErrMemory(ctxt, NULL);
3746
 
                        xmlFree(buffer);
3747
 
                        return(NULL);
3748
 
                    }
3749
 
                    buffer = tmp;
3750
 
                }
3751
 
                COPY_BUF(l,buffer,len,c);
3752
 
                NEXTL(l);
3753
 
                c = CUR_CHAR(l);
3754
 
            }
3755
 
            buffer[len] = 0;
3756
 
            return(buffer);
3757
 
        }
3758
 
    }
3759
 
    if (len == 0)
3760
 
        return(NULL);
3761
 
    if ((len > XML_MAX_NAME_LENGTH) &&
3762
 
        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3763
 
        xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken");
3764
 
        return(NULL);
3765
 
    }
3766
 
    return(xmlStrndup(buf, len));
3767
 
}
3768
 
 
3769
 
/**
3770
 
 * xmlParseEntityValue:
3771
 
 * @ctxt:  an XML parser context
3772
 
 * @orig:  if non-NULL store a copy of the original entity value
3773
 
 *
3774
 
 * parse a value for ENTITY declarations
3775
 
 *
3776
 
 * [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"' |
3777
 
 *                     "'" ([^%&'] | PEReference | Reference)* "'"
3778
 
 *
3779
 
 * Returns the EntityValue parsed with reference substituted or NULL
3780
 
 */
3781
 
 
3782
 
xmlChar *
3783
 
xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
3784
 
    xmlChar *buf = NULL;
3785
 
    int len = 0;
3786
 
    int size = XML_PARSER_BUFFER_SIZE;
3787
 
    int c, l;
3788
 
    xmlChar stop;
3789
 
    xmlChar *ret = NULL;
3790
 
    const xmlChar *cur = NULL;
3791
 
    xmlParserInputPtr input;
3792
 
 
3793
 
    if (RAW == '"') stop = '"';
3794
 
    else if (RAW == '\'') stop = '\'';
3795
 
    else {
3796
 
        xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_STARTED, NULL);
3797
 
        return(NULL);
3798
 
    }
3799
 
    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
3800
 
    if (buf == NULL) {
3801
 
        xmlErrMemory(ctxt, NULL);
3802
 
        return(NULL);
3803
 
    }
3804
 
 
3805
 
    /*
3806
 
     * The content of the entity definition is copied in a buffer.
3807
 
     */
3808
 
 
3809
 
    ctxt->instate = XML_PARSER_ENTITY_VALUE;
3810
 
    input = ctxt->input;
3811
 
    GROW;
3812
 
    if (ctxt->instate == XML_PARSER_EOF) {
3813
 
        xmlFree(buf);
3814
 
        return(NULL);
3815
 
    }
3816
 
    NEXT;
3817
 
    c = CUR_CHAR(l);
3818
 
    /*
3819
 
     * NOTE: 4.4.5 Included in Literal
3820
 
     * When a parameter entity reference appears in a literal entity
3821
 
     * value, ... a single or double quote character in the replacement
3822
 
     * text is always treated as a normal data character and will not
3823
 
     * terminate the literal.
3824
 
     * In practice it means we stop the loop only when back at parsing
3825
 
     * the initial entity and the quote is found
3826
 
     */
3827
 
    while (((IS_CHAR(c)) && ((c != stop) || /* checked */
3828
 
            (ctxt->input != input))) && (ctxt->instate != XML_PARSER_EOF)) {
3829
 
        if (len + 5 >= size) {
3830
 
            xmlChar *tmp;
3831
 
 
3832
 
            size *= 2;
3833
 
            tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
3834
 
            if (tmp == NULL) {
3835
 
                xmlErrMemory(ctxt, NULL);
3836
 
                xmlFree(buf);
3837
 
                return(NULL);
3838
 
            }
3839
 
            buf = tmp;
3840
 
        }
3841
 
        COPY_BUF(l,buf,len,c);
3842
 
        NEXTL(l);
3843
 
        /*
3844
 
         * Pop-up of finished entities.
3845
 
         */
3846
 
        while ((RAW == 0) && (ctxt->inputNr > 1)) /* non input consuming */
3847
 
            xmlPopInput(ctxt);
3848
 
 
3849
 
        GROW;
3850
 
        c = CUR_CHAR(l);
3851
 
        if (c == 0) {
3852
 
            GROW;
3853
 
            c = CUR_CHAR(l);
3854
 
        }
3855
 
    }
3856
 
    buf[len] = 0;
3857
 
    if (ctxt->instate == XML_PARSER_EOF) {
3858
 
        xmlFree(buf);
3859
 
        return(NULL);
3860
 
    }
3861
 
 
3862
 
    /*
3863
 
     * Raise problem w.r.t. '&' and '%' being used in non-entities
3864
 
     * reference constructs. Note Charref will be handled in
3865
 
     * xmlStringDecodeEntities()
3866
 
     */
3867
 
    cur = buf;
3868
 
    while (*cur != 0) { /* non input consuming */
3869
 
        if ((*cur == '%') || ((*cur == '&') && (cur[1] != '#'))) {
3870
 
            xmlChar *name;
3871
 
            xmlChar tmp = *cur;
3872
 
 
3873
 
            cur++;
3874
 
            name = xmlParseStringName(ctxt, &cur);
3875
 
            if ((name == NULL) || (*cur != ';')) {
3876
 
                xmlFatalErrMsgInt(ctxt, XML_ERR_ENTITY_CHAR_ERROR,
3877
 
            "EntityValue: '%c' forbidden except for entities references\n",
3878
 
                                  tmp);
3879
 
            }
3880
 
            if ((tmp == '%') && (ctxt->inSubset == 1) &&
3881
 
                (ctxt->inputNr == 1)) {
3882
 
                xmlFatalErr(ctxt, XML_ERR_ENTITY_PE_INTERNAL, NULL);
3883
 
            }
3884
 
            if (name != NULL)
3885
 
                xmlFree(name);
3886
 
            if (*cur == 0)
3887
 
                break;
3888
 
        }
3889
 
        cur++;
3890
 
    }
3891
 
 
3892
 
    /*
3893
 
     * Then PEReference entities are substituted.
3894
 
     */
3895
 
    if (c != stop) {
3896
 
        xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_FINISHED, NULL);
3897
 
        xmlFree(buf);
3898
 
    } else {
3899
 
        NEXT;
3900
 
        /*
3901
 
         * NOTE: 4.4.7 Bypassed
3902
 
         * When a general entity reference appears in the EntityValue in
3903
 
         * an entity declaration, it is bypassed and left as is.
3904
 
         * so XML_SUBSTITUTE_REF is not set here.
3905
 
         */
3906
 
        ret = xmlStringDecodeEntities(ctxt, buf, XML_SUBSTITUTE_PEREF,
3907
 
                                      0, 0, 0);
3908
 
        if (orig != NULL)
3909
 
            *orig = buf;
3910
 
        else
3911
 
            xmlFree(buf);
3912
 
    }
3913
 
 
3914
 
    return(ret);
3915
 
}
3916
 
 
3917
 
/**
3918
 
 * xmlParseAttValueComplex:
3919
 
 * @ctxt:  an XML parser context
3920
 
 * @len:   the resulting attribute len
3921
 
 * @normalize:  wether to apply the inner normalization
3922
 
 *
3923
 
 * parse a value for an attribute, this is the fallback function
3924
 
 * of xmlParseAttValue() when the attribute parsing requires handling
3925
 
 * of non-ASCII characters, or normalization compaction.
3926
 
 *
3927
 
 * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
3928
 
 */
3929
 
static xmlChar *
3930
 
xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
3931
 
    xmlChar limit = 0;
3932
 
    xmlChar *buf = NULL;
3933
 
    xmlChar *rep = NULL;
3934
 
    size_t len = 0;
3935
 
    size_t buf_size = 0;
3936
 
    int c, l, in_space = 0;
3937
 
    xmlChar *current = NULL;
3938
 
    xmlEntityPtr ent;
3939
 
 
3940
 
    if (NXT(0) == '"') {
3941
 
        ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
3942
 
        limit = '"';
3943
 
        NEXT;
3944
 
    } else if (NXT(0) == '\'') {
3945
 
        limit = '\'';
3946
 
        ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
3947
 
        NEXT;
3948
 
    } else {
3949
 
        xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
3950
 
        return(NULL);
3951
 
    }
3952
 
 
3953
 
    /*
3954
 
     * allocate a translation buffer.
3955
 
     */
3956
 
    buf_size = XML_PARSER_BUFFER_SIZE;
3957
 
    buf = (xmlChar *) xmlMallocAtomic(buf_size);
3958
 
    if (buf == NULL) goto mem_error;
3959
 
 
3960
 
    /*
3961
 
     * OK loop until we reach one of the ending char or a size limit.
3962
 
     */
3963
 
    c = CUR_CHAR(l);
3964
 
    while (((NXT(0) != limit) && /* checked */
3965
 
            (IS_CHAR(c)) && (c != '<')) &&
3966
 
            (ctxt->instate != XML_PARSER_EOF)) {
3967
 
        /*
3968
 
         * Impose a reasonable limit on attribute size, unless XML_PARSE_HUGE
3969
 
         * special option is given
3970
 
         */
3971
 
        if ((len > XML_MAX_TEXT_LENGTH) &&
3972
 
            ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3973
 
            xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
3974
 
                           "AttValue length too long\n");
3975
 
            goto mem_error;
3976
 
        }
3977
 
        if (c == 0) break;
3978
 
        if (c == '&') {
3979
 
            in_space = 0;
3980
 
            if (NXT(1) == '#') {
3981
 
                int val = xmlParseCharRef(ctxt);
3982
 
 
3983
 
                if (val == '&') {
3984
 
                    if (ctxt->replaceEntities) {
3985
 
                        if (len + 10 > buf_size) {
3986
 
                            growBuffer(buf, 10);
3987
 
                        }
3988
 
                        buf[len++] = '&';
3989
 
                    } else {
3990
 
                        /*
3991
 
                         * The reparsing will be done in xmlStringGetNodeList()
3992
 
                         * called by the attribute() function in SAX.c
3993
 
                         */
3994
 
                        if (len + 10 > buf_size) {
3995
 
                            growBuffer(buf, 10);
3996
 
                        }
3997
 
                        buf[len++] = '&';
3998
 
                        buf[len++] = '#';
3999
 
                        buf[len++] = '3';
4000
 
                        buf[len++] = '8';
4001
 
                        buf[len++] = ';';
4002
 
                    }
4003
 
                } else if (val != 0) {
4004
 
                    if (len + 10 > buf_size) {
4005
 
                        growBuffer(buf, 10);
4006
 
                    }
4007
 
                    len += xmlCopyChar(0, &buf[len], val);
4008
 
                }
4009
 
            } else {
4010
 
                ent = xmlParseEntityRef(ctxt);
4011
 
                ctxt->nbentities++;
4012
 
                if (ent != NULL)
4013
 
                    ctxt->nbentities += ent->owner;
4014
 
                if ((ent != NULL) &&
4015
 
                    (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
4016
 
                    if (len + 10 > buf_size) {
4017
 
                        growBuffer(buf, 10);
4018
 
                    }
4019
 
                    if ((ctxt->replaceEntities == 0) &&
4020
 
                        (ent->content[0] == '&')) {
4021
 
                        buf[len++] = '&';
4022
 
                        buf[len++] = '#';
4023
 
                        buf[len++] = '3';
4024
 
                        buf[len++] = '8';
4025
 
                        buf[len++] = ';';
4026
 
                    } else {
4027
 
                        buf[len++] = ent->content[0];
4028
 
                    }
4029
 
                } else if ((ent != NULL) &&
4030
 
                           (ctxt->replaceEntities != 0)) {
4031
 
                    if (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) {
4032
 
                        rep = xmlStringDecodeEntities(ctxt, ent->content,
4033
 
                                                      XML_SUBSTITUTE_REF,
4034
 
                                                      0, 0, 0);
4035
 
                        if (rep != NULL) {
4036
 
                            current = rep;
4037
 
                            while (*current != 0) { /* non input consuming */
4038
 
                                if ((*current == 0xD) || (*current == 0xA) ||
4039
 
                                    (*current == 0x9)) {
4040
 
                                    buf[len++] = 0x20;
4041
 
                                    current++;
4042
 
                                } else
4043
 
                                    buf[len++] = *current++;
4044
 
                                if (len + 10 > buf_size) {
4045
 
                                    growBuffer(buf, 10);
4046
 
                                }
4047
 
                            }
4048
 
                            xmlFree(rep);
4049
 
                            rep = NULL;
4050
 
                        }
4051
 
                    } else {
4052
 
                        if (len + 10 > buf_size) {
4053
 
                            growBuffer(buf, 10);
4054
 
                        }
4055
 
                        if (ent->content != NULL)
4056
 
                            buf[len++] = ent->content[0];
4057
 
                    }
4058
 
                } else if (ent != NULL) {
4059
 
                    int i = xmlStrlen(ent->name);
4060
 
                    const xmlChar *cur = ent->name;
4061
 
 
4062
 
                    /*
4063
 
                     * This may look absurd but is needed to detect
4064
 
                     * entities problems
4065
 
                     */
4066
 
                    if ((ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
4067
 
                        (ent->content != NULL) && (ent->checked == 0)) {
4068
 
                        unsigned long oldnbent = ctxt->nbentities;
4069
 
 
4070
 
                        rep = xmlStringDecodeEntities(ctxt, ent->content,
4071
 
                                                  XML_SUBSTITUTE_REF, 0, 0, 0);
4072
 
 
4073
 
                        ent->checked = (ctxt->nbentities - oldnbent + 1) * 2;
4074
 
                        if (rep != NULL) {
4075
 
                            if (xmlStrchr(rep, '<'))
4076
 
                                ent->checked |= 1;
4077
 
                            xmlFree(rep);
4078
 
                            rep = NULL;
4079
 
                        }
4080
 
                    }
4081
 
 
4082
 
                    /*
4083
 
                     * Just output the reference
4084
 
                     */
4085
 
                    buf[len++] = '&';
4086
 
                    while (len + i + 10 > buf_size) {
4087
 
                        growBuffer(buf, i + 10);
4088
 
                    }
4089
 
                    for (;i > 0;i--)
4090
 
                        buf[len++] = *cur++;
4091
 
                    buf[len++] = ';';
4092
 
                }
4093
 
            }
4094
 
        } else {
4095
 
            if ((c == 0x20) || (c == 0xD) || (c == 0xA) || (c == 0x9)) {
4096
 
                if ((len != 0) || (!normalize)) {
4097
 
                    if ((!normalize) || (!in_space)) {
4098
 
                        COPY_BUF(l,buf,len,0x20);
4099
 
                        while (len + 10 > buf_size) {
4100
 
                            growBuffer(buf, 10);
4101
 
                        }
4102
 
                    }
4103
 
                    in_space = 1;
4104
 
                }
4105
 
            } else {
4106
 
                in_space = 0;
4107
 
                COPY_BUF(l,buf,len,c);
4108
 
                if (len + 10 > buf_size) {
4109
 
                    growBuffer(buf, 10);
4110
 
                }
4111
 
            }
4112
 
            NEXTL(l);
4113
 
        }
4114
 
        GROW;
4115
 
        c = CUR_CHAR(l);
4116
 
    }
4117
 
    if (ctxt->instate == XML_PARSER_EOF)
4118
 
        goto error;
4119
 
 
4120
 
    if ((in_space) && (normalize)) {
4121
 
        while ((len > 0) && (buf[len - 1] == 0x20)) len--;
4122
 
    }
4123
 
    buf[len] = 0;
4124
 
    if (RAW == '<') {
4125
 
        xmlFatalErr(ctxt, XML_ERR_LT_IN_ATTRIBUTE, NULL);
4126
 
    } else if (RAW != limit) {
4127
 
        if ((c != 0) && (!IS_CHAR(c))) {
4128
 
            xmlFatalErrMsg(ctxt, XML_ERR_INVALID_CHAR,
4129
 
                           "invalid character in attribute value\n");
4130
 
        } else {
4131
 
            xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
4132
 
                           "AttValue: ' expected\n");
4133
 
        }
4134
 
    } else
4135
 
        NEXT;
4136
 
 
4137
 
    /*
4138
 
     * There we potentially risk an overflow, don't allow attribute value of
4139
 
     * length more than INT_MAX it is a very reasonnable assumption !
4140
 
     */
4141
 
    if (len >= INT_MAX) {
4142
 
        xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
4143
 
                       "AttValue length too long\n");
4144
 
        goto mem_error;
4145
 
    }
4146
 
 
4147
 
    if (attlen != NULL) *attlen = (int) len;
4148
 
    return(buf);
4149
 
 
4150
 
mem_error:
4151
 
    xmlErrMemory(ctxt, NULL);
4152
 
error:
4153
 
    if (buf != NULL)
4154
 
        xmlFree(buf);
4155
 
    if (rep != NULL)
4156
 
        xmlFree(rep);
4157
 
    return(NULL);
4158
 
}
4159
 
 
4160
 
/**
4161
 
 * xmlParseAttValue:
4162
 
 * @ctxt:  an XML parser context
4163
 
 *
4164
 
 * parse a value for an attribute
4165
 
 * Note: the parser won't do substitution of entities here, this
4166
 
 * will be handled later in xmlStringGetNodeList
4167
 
 *
4168
 
 * [10] AttValue ::= '"' ([^<&"] | Reference)* '"' |
4169
 
 *                   "'" ([^<&'] | Reference)* "'"
4170
 
 *
4171
 
 * 3.3.3 Attribute-Value Normalization:
4172
 
 * Before the value of an attribute is passed to the application or
4173
 
 * checked for validity, the XML processor must normalize it as follows:
4174
 
 * - a character reference is processed by appending the referenced
4175
 
 *   character to the attribute value
4176
 
 * - an entity reference is processed by recursively processing the
4177
 
 *   replacement text of the entity
4178
 
 * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
4179
 
 *   appending #x20 to the normalized value, except that only a single
4180
 
 *   #x20 is appended for a "#xD#xA" sequence that is part of an external
4181
 
 *   parsed entity or the literal entity value of an internal parsed entity
4182
 
 * - other characters are processed by appending them to the normalized value
4183
 
 * If the declared value is not CDATA, then the XML processor must further
4184
 
 * process the normalized attribute value by discarding any leading and
4185
 
 * trailing space (#x20) characters, and by replacing sequences of space
4186
 
 * (#x20) characters by a single space (#x20) character.
4187
 
 * All attributes for which no declaration has been read should be treated
4188
 
 * by a non-validating parser as if declared CDATA.
4189
 
 *
4190
 
 * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
4191
 
 */
4192
 
 
4193
 
 
4194
 
xmlChar *
4195
 
xmlParseAttValue(xmlParserCtxtPtr ctxt) {
4196
 
    if ((ctxt == NULL) || (ctxt->input == NULL)) return(NULL);
4197
 
    return(xmlParseAttValueInternal(ctxt, NULL, NULL, 0));
4198
 
}
4199
 
 
4200
 
/**
4201
 
 * xmlParseSystemLiteral:
4202
 
 * @ctxt:  an XML parser context
4203
 
 *
4204
 
 * parse an XML Literal
4205
 
 *
4206
 
 * [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
4207
 
 *
4208
 
 * Returns the SystemLiteral parsed or NULL
4209
 
 */
4210
 
 
4211
 
xmlChar *
4212
 
xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
4213
 
    xmlChar *buf = NULL;
4214
 
    int len = 0;
4215
 
    int size = XML_PARSER_BUFFER_SIZE;
4216
 
    int cur, l;
4217
 
    xmlChar stop;
4218
 
    int state = ctxt->instate;
4219
 
    int count = 0;
4220
 
 
4221
 
    SHRINK;
4222
 
    if (RAW == '"') {
4223
 
        NEXT;
4224
 
        stop = '"';
4225
 
    } else if (RAW == '\'') {
4226
 
        NEXT;
4227
 
        stop = '\'';
4228
 
    } else {
4229
 
        xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, NULL);
4230
 
        return(NULL);
4231
 
    }
4232
 
 
4233
 
    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
4234
 
    if (buf == NULL) {
4235
 
        xmlErrMemory(ctxt, NULL);
4236
 
        return(NULL);
4237
 
    }
4238
 
    ctxt->instate = XML_PARSER_SYSTEM_LITERAL;
4239
 
    cur = CUR_CHAR(l);
4240
 
    while ((IS_CHAR(cur)) && (cur != stop)) { /* checked */
4241
 
        if (len + 5 >= size) {
4242
 
            xmlChar *tmp;
4243
 
 
4244
 
            if ((size > XML_MAX_NAME_LENGTH) &&
4245
 
                ((ctxt->options & XML_PARSE_HUGE) == 0)) {
4246
 
                xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "SystemLiteral");
4247
 
                xmlFree(buf);
4248
 
                ctxt->instate = (xmlParserInputState) state;
4249
 
                return(NULL);
4250
 
            }
4251
 
            size *= 2;
4252
 
            tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
4253
 
            if (tmp == NULL) {
4254
 
                xmlFree(buf);
4255
 
                xmlErrMemory(ctxt, NULL);
4256
 
                ctxt->instate = (xmlParserInputState) state;
4257
 
                return(NULL);
4258
 
            }
4259
 
            buf = tmp;
4260
 
        }
4261
 
        count++;
4262
 
        if (count > 50) {
4263
 
            GROW;
4264
 
            count = 0;
4265
 
            if (ctxt->instate == XML_PARSER_EOF) {
4266
 
                xmlFree(buf);
4267
 
                return(NULL);
4268
 
            }
4269
 
        }
4270
 
        COPY_BUF(l,buf,len,cur);
4271
 
        NEXTL(l);
4272
 
        cur = CUR_CHAR(l);
4273
 
        if (cur == 0) {
4274
 
            GROW;
4275
 
            SHRINK;
4276
 
            cur = CUR_CHAR(l);
4277
 
        }
4278
 
    }
4279
 
    buf[len] = 0;
4280
 
    ctxt->instate = (xmlParserInputState) state;
4281
 
    if (!IS_CHAR(cur)) {
4282
 
        xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
4283
 
    } else {
4284
 
        NEXT;
4285
 
    }
4286
 
    return(buf);
4287
 
}
4288
 
 
4289
 
/**
4290
 
 * xmlParsePubidLiteral:
4291
 
 * @ctxt:  an XML parser context
4292
 
 *
4293
 
 * parse an XML public literal
4294
 
 *
4295
 
 * [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
4296
 
 *
4297
 
 * Returns the PubidLiteral parsed or NULL.
4298
 
 */
4299
 
 
4300
 
xmlChar *
4301
 
xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
4302
 
    xmlChar *buf = NULL;
4303
 
    int len = 0;
4304
 
    int size = XML_PARSER_BUFFER_SIZE;
4305
 
    xmlChar cur;
4306
 
    xmlChar stop;
4307
 
    int count = 0;
4308
 
    xmlParserInputState oldstate = ctxt->instate;
4309
 
 
4310
 
    SHRINK;
4311
 
    if (RAW == '"') {
4312
 
        NEXT;
4313
 
        stop = '"';
4314
 
    } else if (RAW == '\'') {
4315
 
        NEXT;
4316
 
        stop = '\'';
4317
 
    } else {
4318
 
        xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, NULL);
4319
 
        return(NULL);
4320
 
    }
4321
 
    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
4322
 
    if (buf == NULL) {
4323
 
        xmlErrMemory(ctxt, NULL);
4324
 
        return(NULL);
4325
 
    }
4326
 
    ctxt->instate = XML_PARSER_PUBLIC_LITERAL;
4327
 
    cur = CUR;
4328
 
    while ((IS_PUBIDCHAR_CH(cur)) && (cur != stop)) { /* checked */
4329
 
        if (len + 1 >= size) {
4330
 
            xmlChar *tmp;
4331
 
 
4332
 
            if ((size > XML_MAX_NAME_LENGTH) &&
4333
 
                ((ctxt->options & XML_PARSE_HUGE) == 0)) {
4334
 
                xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Public ID");
4335
 
                xmlFree(buf);
4336
 
                return(NULL);
4337
 
            }
4338
 
            size *= 2;
4339
 
            tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
4340
 
            if (tmp == NULL) {
4341
 
                xmlErrMemory(ctxt, NULL);
4342
 
                xmlFree(buf);
4343
 
                return(NULL);
4344
 
            }
4345
 
            buf = tmp;
4346
 
        }
4347
 
        buf[len++] = cur;
4348
 
        count++;
4349
 
        if (count > 50) {
4350
 
            GROW;
4351
 
            count = 0;
4352
 
            if (ctxt->instate == XML_PARSER_EOF) {
4353
 
                xmlFree(buf);
4354
 
                return(NULL);
4355
 
            }
4356
 
        }
4357
 
        NEXT;
4358
 
        cur = CUR;
4359
 
        if (cur == 0) {
4360
 
            GROW;
4361
 
            SHRINK;
4362
 
            cur = CUR;
4363
 
        }
4364
 
    }
4365
 
    buf[len] = 0;
4366
 
    if (cur != stop) {
4367
 
        xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
4368
 
    } else {
4369
 
        NEXT;
4370
 
    }
4371
 
    ctxt->instate = oldstate;
4372
 
    return(buf);
4373
 
}
4374
 
 
4375
 
static void xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata);
4376
 
 
4377
 
/*
4378
 
 * used for the test in the inner loop of the char data testing
4379
 
 */
4380
 
static const unsigned char test_char_data[256] = {
4381
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4382
 
    0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9, CR/LF separated */
4383
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4384
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4385
 
    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x00, 0x27, /* & */
4386
 
    0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
4387
 
    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
4388
 
    0x38, 0x39, 0x3A, 0x3B, 0x00, 0x3D, 0x3E, 0x3F, /* < */
4389
 
    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
4390
 
    0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
4391
 
    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
4392
 
    0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x00, 0x5E, 0x5F, /* ] */
4393
 
    0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
4394
 
    0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
4395
 
    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
4396
 
    0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
4397
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* non-ascii */
4398
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4399
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4400
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4401
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4402
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4403
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4404
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4405
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4406
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4407
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4408
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4409
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4410
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4411
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4412
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
4413
 
};
4414
 
 
4415
 
/**
4416
 
 * xmlParseCharData:
4417
 
 * @ctxt:  an XML parser context
4418
 
 * @cdata:  int indicating whether we are within a CDATA section
4419
 
 *
4420
 
 * parse a CharData section.
4421
 
 * if we are within a CDATA section ']]>' marks an end of section.
4422
 
 *
4423
 
 * The right angle bracket (>) may be represented using the string "&gt;",
4424
 
 * and must, for compatibility, be escaped using "&gt;" or a character
4425
 
 * reference when it appears in the string "]]>" in content, when that
4426
 
 * string is not marking the end of a CDATA section.
4427
 
 *
4428
 
 * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
4429
 
 */
4430
 
 
4431
 
void
4432
 
xmlParseCharData(xmlParserCtxtPtr ctxt, int cdata) {
4433
 
    const xmlChar *in;
4434
 
    int nbchar = 0;
4435
 
    int line = ctxt->input->line;
4436
 
    int col = ctxt->input->col;
4437
 
    int ccol;
4438
 
 
4439
 
    SHRINK;
4440
 
    GROW;
4441
 
    /*
4442
 
     * Accelerated common case where input don't need to be
4443
 
     * modified before passing it to the handler.
4444
 
     */
4445
 
    if (!cdata) {
4446
 
        in = ctxt->input->cur;
4447
 
        do {
4448
 
get_more_space:
4449
 
            while (*in == 0x20) { in++; ctxt->input->col++; }
4450
 
            if (*in == 0xA) {
4451
 
                do {
4452
 
                    ctxt->input->line++; ctxt->input->col = 1;
4453
 
                    in++;
4454
 
                } while (*in == 0xA);
4455
 
                goto get_more_space;
4456
 
            }
4457
 
            if (*in == '<') {
4458
 
                nbchar = in - ctxt->input->cur;
4459
 
                if (nbchar > 0) {
4460
 
                    const xmlChar *tmp = ctxt->input->cur;
4461
 
                    ctxt->input->cur = in;
4462
 
 
4463
 
                    if ((ctxt->sax != NULL) &&
4464
 
                        (ctxt->sax->ignorableWhitespace !=
4465
 
                         ctxt->sax->characters)) {
4466
 
                        if (areBlanks(ctxt, tmp, nbchar, 1)) {
4467
 
                            if (ctxt->sax->ignorableWhitespace != NULL)
4468
 
                                ctxt->sax->ignorableWhitespace(ctxt->userData,
4469
 
                                                       tmp, nbchar);
4470
 
                        } else {
4471
 
                            if (ctxt->sax->characters != NULL)
4472
 
                                ctxt->sax->characters(ctxt->userData,
4473
 
                                                      tmp, nbchar);
4474
 
                            if (*ctxt->space == -1)
4475
 
                                *ctxt->space = -2;
4476
 
                        }
4477
 
                    } else if ((ctxt->sax != NULL) &&
4478
 
                               (ctxt->sax->characters != NULL)) {
4479
 
                        ctxt->sax->characters(ctxt->userData,
4480
 
                                              tmp, nbchar);
4481
 
                    }
4482
 
                }
4483
 
                return;
4484
 
            }
4485
 
 
4486
 
get_more:
4487
 
            ccol = ctxt->input->col;
4488
 
            while (test_char_data[*in]) {
4489
 
                in++;
4490
 
                ccol++;
4491
 
            }
4492
 
            ctxt->input->col = ccol;
4493
 
            if (*in == 0xA) {
4494
 
                do {
4495
 
                    ctxt->input->line++; ctxt->input->col = 1;
4496
 
                    in++;
4497
 
                } while (*in == 0xA);
4498
 
                goto get_more;
4499
 
            }
4500
 
            if (*in == ']') {
4501
 
                if ((in[1] == ']') && (in[2] == '>')) {
4502
 
                    xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
4503
 
                    ctxt->input->cur = in;
4504
 
                    return;
4505
 
                }
4506
 
                in++;
4507
 
                ctxt->input->col++;
4508
 
                goto get_more;
4509
 
            }
4510
 
            nbchar = in - ctxt->input->cur;
4511
 
            if (nbchar > 0) {
4512
 
                if ((ctxt->sax != NULL) &&
4513
 
                    (ctxt->sax->ignorableWhitespace !=
4514
 
                     ctxt->sax->characters) &&
4515
 
                    (IS_BLANK_CH(*ctxt->input->cur))) {
4516
 
                    const xmlChar *tmp = ctxt->input->cur;
4517
 
                    ctxt->input->cur = in;
4518
 
 
4519
 
                    if (areBlanks(ctxt, tmp, nbchar, 0)) {
4520
 
                        if (ctxt->sax->ignorableWhitespace != NULL)
4521
 
                            ctxt->sax->ignorableWhitespace(ctxt->userData,
4522
 
                                                           tmp, nbchar);
4523
 
                    } else {
4524
 
                        if (ctxt->sax->characters != NULL)
4525
 
                            ctxt->sax->characters(ctxt->userData,
4526
 
                                                  tmp, nbchar);
4527
 
                        if (*ctxt->space == -1)
4528
 
                            *ctxt->space = -2;
4529
 
                    }
4530
 
                    line = ctxt->input->line;
4531
 
                    col = ctxt->input->col;
4532
 
                } else if (ctxt->sax != NULL) {
4533
 
                    if (ctxt->sax->characters != NULL)
4534
 
                        ctxt->sax->characters(ctxt->userData,
4535
 
                                              ctxt->input->cur, nbchar);
4536
 
                    line = ctxt->input->line;
4537
 
                    col = ctxt->input->col;
4538
 
                }
4539
 
                /* something really bad happened in the SAX callback */
4540
 
                if (ctxt->instate != XML_PARSER_CONTENT)
4541
 
                    return;
4542
 
            }
4543
 
            ctxt->input->cur = in;
4544
 
            if (*in == 0xD) {
4545
 
                in++;
4546
 
                if (*in == 0xA) {
4547
 
                    ctxt->input->cur = in;
4548
 
                    in++;
4549
 
                    ctxt->input->line++; ctxt->input->col = 1;
4550
 
                    continue; /* while */
4551
 
                }
4552
 
                in--;
4553
 
            }
4554
 
            if (*in == '<') {
4555
 
                return;
4556
 
            }
4557
 
            if (*in == '&') {
4558
 
                return;
4559
 
            }
4560
 
            SHRINK;
4561
 
            GROW;
4562
 
            if (ctxt->instate == XML_PARSER_EOF)
4563
 
                return;
4564
 
            in = ctxt->input->cur;
4565
 
        } while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09));
4566
 
        nbchar = 0;
4567
 
    }
4568
 
    ctxt->input->line = line;
4569
 
    ctxt->input->col = col;
4570
 
    xmlParseCharDataComplex(ctxt, cdata);
4571
 
}
4572
 
 
4573
 
/**
4574
 
 * xmlParseCharDataComplex:
4575
 
 * @ctxt:  an XML parser context
4576
 
 * @cdata:  int indicating whether we are within a CDATA section
4577
 
 *
4578
 
 * parse a CharData section.this is the fallback function
4579
 
 * of xmlParseCharData() when the parsing requires handling
4580
 
 * of non-ASCII characters.
4581
 
 */
4582
 
static void
4583
 
xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata) {
4584
 
    xmlChar buf[XML_PARSER_BIG_BUFFER_SIZE + 5];
4585
 
    int nbchar = 0;
4586
 
    int cur, l;
4587
 
    int count = 0;
4588
 
 
4589
 
    SHRINK;
4590
 
    GROW;
4591
 
    cur = CUR_CHAR(l);
4592
 
    while ((cur != '<') && /* checked */
4593
 
           (cur != '&') &&
4594
 
           (IS_CHAR(cur))) /* test also done in xmlCurrentChar() */ {
4595
 
        if ((cur == ']') && (NXT(1) == ']') &&
4596
 
            (NXT(2) == '>')) {
4597
 
            if (cdata) break;
4598
 
            else {
4599
 
                xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
4600
 
            }
4601
 
        }
4602
 
        COPY_BUF(l,buf,nbchar,cur);
4603
 
        if (nbchar >= XML_PARSER_BIG_BUFFER_SIZE) {
4604
 
            buf[nbchar] = 0;
4605
 
 
4606
 
            /*
4607
 
             * OK the segment is to be consumed as chars.
4608
 
             */
4609
 
            if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
4610
 
                if (areBlanks(ctxt, buf, nbchar, 0)) {
4611
 
                    if (ctxt->sax->ignorableWhitespace != NULL)
4612
 
                        ctxt->sax->ignorableWhitespace(ctxt->userData,
4613
 
                                                       buf, nbchar);
4614
 
                } else {
4615
 
                    if (ctxt->sax->characters != NULL)
4616
 
                        ctxt->sax->characters(ctxt->userData, buf, nbchar);
4617
 
                    if ((ctxt->sax->characters !=
4618
 
                         ctxt->sax->ignorableWhitespace) &&
4619
 
                        (*ctxt->space == -1))
4620
 
                        *ctxt->space = -2;
4621
 
                }
4622
 
            }
4623
 
            nbchar = 0;
4624
 
            /* something really bad happened in the SAX callback */
4625
 
            if (ctxt->instate != XML_PARSER_CONTENT)
4626
 
                return;
4627
 
        }
4628
 
        count++;
4629
 
        if (count > 50) {
4630
 
            GROW;
4631
 
            count = 0;
4632
 
            if (ctxt->instate == XML_PARSER_EOF)
4633
 
                return;
4634
 
        }
4635
 
        NEXTL(l);
4636
 
        cur = CUR_CHAR(l);
4637
 
    }
4638
 
    if (nbchar != 0) {
4639
 
        buf[nbchar] = 0;
4640
 
        /*
4641
 
         * OK the segment is to be consumed as chars.
4642
 
         */
4643
 
        if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
4644
 
            if (areBlanks(ctxt, buf, nbchar, 0)) {
4645
 
                if (ctxt->sax->ignorableWhitespace != NULL)
4646
 
                    ctxt->sax->ignorableWhitespace(ctxt->userData, buf, nbchar);
4647
 
            } else {
4648
 
                if (ctxt->sax->characters != NULL)
4649
 
                    ctxt->sax->characters(ctxt->userData, buf, nbchar);
4650
 
                if ((ctxt->sax->characters != ctxt->sax->ignorableWhitespace) &&
4651
 
                    (*ctxt->space == -1))
4652
 
                    *ctxt->space = -2;
4653
 
            }
4654
 
        }
4655
 
    }
4656
 
    if ((cur != 0) && (!IS_CHAR(cur))) {
4657
 
        /* Generate the error and skip the offending character */
4658
 
        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
4659
 
                          "PCDATA invalid Char value %d\n",
4660
 
                          cur);
4661
 
        NEXTL(l);
4662
 
    }
4663
 
}
4664
 
 
4665
 
/**
4666
 
 * xmlParseExternalID:
4667
 
 * @ctxt:  an XML parser context
4668
 
 * @publicID:  a xmlChar** receiving PubidLiteral
4669
 
 * @strict: indicate whether we should restrict parsing to only
4670
 
 *          production [75], see NOTE below
4671
 
 *
4672
 
 * Parse an External ID or a Public ID
4673
 
 *
4674
 
 * NOTE: Productions [75] and [83] interact badly since [75] can generate
4675
 
 *       'PUBLIC' S PubidLiteral S SystemLiteral
4676
 
 *
4677
 
 * [75] ExternalID ::= 'SYSTEM' S SystemLiteral
4678
 
 *                   | 'PUBLIC' S PubidLiteral S SystemLiteral
4679
 
 *
4680
 
 * [83] PublicID ::= 'PUBLIC' S PubidLiteral
4681
 
 *
4682
 
 * Returns the function returns SystemLiteral and in the second
4683
 
 *                case publicID receives PubidLiteral, is strict is off
4684
 
 *                it is possible to return NULL and have publicID set.
4685
 
 */
4686
 
 
4687
 
xmlChar *
4688
 
xmlParseExternalID(xmlParserCtxtPtr ctxt, xmlChar **publicID, int strict) {
4689
 
    xmlChar *URI = NULL;
4690
 
 
4691
 
    SHRINK;
4692
 
 
4693
 
    *publicID = NULL;
4694
 
    if (CMP6(CUR_PTR, 'S', 'Y', 'S', 'T', 'E', 'M')) {
4695
 
        SKIP(6);
4696
 
        if (!IS_BLANK_CH(CUR)) {
4697
 
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4698
 
                           "Space required after 'SYSTEM'\n");
4699
 
        }
4700
 
        SKIP_BLANKS;
4701
 
        URI = xmlParseSystemLiteral(ctxt);
4702
 
        if (URI == NULL) {
4703
 
            xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
4704
 
        }
4705
 
    } else if (CMP6(CUR_PTR, 'P', 'U', 'B', 'L', 'I', 'C')) {
4706
 
        SKIP(6);
4707
 
        if (!IS_BLANK_CH(CUR)) {
4708
 
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4709
 
                    "Space required after 'PUBLIC'\n");
4710
 
        }
4711
 
        SKIP_BLANKS;
4712
 
        *publicID = xmlParsePubidLiteral(ctxt);
4713
 
        if (*publicID == NULL) {
4714
 
            xmlFatalErr(ctxt, XML_ERR_PUBID_REQUIRED, NULL);
4715
 
        }
4716
 
        if (strict) {
4717
 
            /*
4718
 
             * We don't handle [83] so "S SystemLiteral" is required.
4719
 
             */
4720
 
            if (!IS_BLANK_CH(CUR)) {
4721
 
                xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4722
 
                        "Space required after the Public Identifier\n");
4723
 
            }
4724
 
        } else {
4725
 
            /*
4726
 
             * We handle [83] so we return immediately, if
4727
 
             * "S SystemLiteral" is not detected. From a purely parsing
4728
 
             * point of view that's a nice mess.
4729
 
             */
4730
 
            const xmlChar *ptr;
4731
 
            GROW;
4732
 
 
4733
 
            ptr = CUR_PTR;
4734
 
            if (!IS_BLANK_CH(*ptr)) return(NULL);
4735
 
 
4736
 
            while (IS_BLANK_CH(*ptr)) ptr++; /* TODO: dangerous, fix ! */
4737
 
            if ((*ptr != '\'') && (*ptr != '"')) return(NULL);
4738
 
        }
4739
 
        SKIP_BLANKS;
4740
 
        URI = xmlParseSystemLiteral(ctxt);
4741
 
        if (URI == NULL) {
4742
 
            xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
4743
 
        }
4744
 
    }
4745
 
    return(URI);
4746
 
}
4747
 
 
4748
 
/**
4749
 
 * xmlParseCommentComplex:
4750
 
 * @ctxt:  an XML parser context
4751
 
 * @buf:  the already parsed part of the buffer
4752
 
 * @len:  number of bytes filles in the buffer
4753
 
 * @size:  allocated size of the buffer
4754
 
 *
4755
 
 * Skip an XML (SGML) comment <!-- .... -->
4756
 
 *  The spec says that "For compatibility, the string "--" (double-hyphen)
4757
 
 *  must not occur within comments. "
4758
 
 * This is the slow routine in case the accelerator for ascii didn't work
4759
 
 *
4760
 
 * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
4761
 
 */
4762
 
static void
4763
 
xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf,
4764
 
                       size_t len, size_t size) {
4765
 
    int q, ql;
4766
 
    int r, rl;
4767
 
    int cur, l;
4768
 
    size_t count = 0;
4769
 
    int inputid;
4770
 
 
4771
 
    inputid = ctxt->input->id;
4772
 
 
4773
 
    if (buf == NULL) {
4774
 
        len = 0;
4775
 
        size = XML_PARSER_BUFFER_SIZE;
4776
 
        buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
4777
 
        if (buf == NULL) {
4778
 
            xmlErrMemory(ctxt, NULL);
4779
 
            return;
4780
 
        }
4781
 
    }
4782
 
    GROW;       /* Assure there's enough input data */
4783
 
    q = CUR_CHAR(ql);
4784
 
    if (q == 0)
4785
 
        goto not_terminated;
4786
 
    if (!IS_CHAR(q)) {
4787
 
        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
4788
 
                          "xmlParseComment: invalid xmlChar value %d\n",
4789
 
                          q);
4790
 
        xmlFree (buf);
4791
 
        return;
4792
 
    }
4793
 
    NEXTL(ql);
4794
 
    r = CUR_CHAR(rl);
4795
 
    if (r == 0)
4796
 
        goto not_terminated;
4797
 
    if (!IS_CHAR(r)) {
4798
 
        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
4799
 
                          "xmlParseComment: invalid xmlChar value %d\n",
4800
 
                          q);
4801
 
        xmlFree (buf);
4802
 
        return;
4803
 
    }
4804
 
    NEXTL(rl);
4805
 
    cur = CUR_CHAR(l);
4806
 
    if (cur == 0)
4807
 
        goto not_terminated;
4808
 
    while (IS_CHAR(cur) && /* checked */
4809
 
           ((cur != '>') ||
4810
 
            (r != '-') || (q != '-'))) {
4811
 
        if ((r == '-') && (q == '-')) {
4812
 
            xmlFatalErr(ctxt, XML_ERR_HYPHEN_IN_COMMENT, NULL);
4813
 
        }
4814
 
        if ((len > XML_MAX_TEXT_LENGTH) &&
4815
 
            ((ctxt->options & XML_PARSE_HUGE) == 0)) {
4816
 
            xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
4817
 
                         "Comment too big found", NULL);
4818
 
            xmlFree (buf);
4819
 
            return;
4820
 
        }
4821
 
        if (len + 5 >= size) {
4822
 
            xmlChar *new_buf;
4823
 
            size_t new_size;
4824
 
 
4825
 
            new_size = size * 2;
4826
 
            new_buf = (xmlChar *) xmlRealloc(buf, new_size);
4827
 
            if (new_buf == NULL) {
4828
 
                xmlFree (buf);
4829
 
                xmlErrMemory(ctxt, NULL);
4830
 
                return;
4831
 
            }
4832
 
            buf = new_buf;
4833
 
            size = new_size;
4834
 
        }
4835
 
        COPY_BUF(ql,buf,len,q);
4836
 
        q = r;
4837
 
        ql = rl;
4838
 
        r = cur;
4839
 
        rl = l;
4840
 
 
4841
 
        count++;
4842
 
        if (count > 50) {
4843
 
            GROW;
4844
 
            count = 0;
4845
 
            if (ctxt->instate == XML_PARSER_EOF) {
4846
 
                xmlFree(buf);
4847
 
                return;
4848
 
            }
4849
 
        }
4850
 
        NEXTL(l);
4851
 
        cur = CUR_CHAR(l);
4852
 
        if (cur == 0) {
4853
 
            SHRINK;
4854
 
            GROW;
4855
 
            cur = CUR_CHAR(l);
4856
 
        }
4857
 
    }
4858
 
    buf[len] = 0;
4859
 
    if (cur == 0) {
4860
 
        xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
4861
 
                             "Comment not terminated \n<!--%.50s\n", buf);
4862
 
    } else if (!IS_CHAR(cur)) {
4863
 
        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
4864
 
                          "xmlParseComment: invalid xmlChar value %d\n",
4865
 
                          cur);
4866
 
    } else {
4867
 
        if (inputid != ctxt->input->id) {
4868
 
            xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
4869
 
                "Comment doesn't start and stop in the same entity\n");
4870
 
        }
4871
 
        NEXT;
4872
 
        if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
4873
 
            (!ctxt->disableSAX))
4874
 
            ctxt->sax->comment(ctxt->userData, buf);
4875
 
    }
4876
 
    xmlFree(buf);
4877
 
    return;
4878
 
not_terminated:
4879
 
    xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
4880
 
                         "Comment not terminated\n", NULL);
4881
 
    xmlFree(buf);
4882
 
    return;
4883
 
}
4884
 
 
4885
 
/**
4886
 
 * xmlParseComment:
4887
 
 * @ctxt:  an XML parser context
4888
 
 *
4889
 
 * Skip an XML (SGML) comment <!-- .... -->
4890
 
 *  The spec says that "For compatibility, the string "--" (double-hyphen)
4891
 
 *  must not occur within comments. "
4892
 
 *
4893
 
 * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
4894
 
 */
4895
 
void
4896
 
xmlParseComment(xmlParserCtxtPtr ctxt) {
4897
 
    xmlChar *buf = NULL;
4898
 
    size_t size = XML_PARSER_BUFFER_SIZE;
4899
 
    size_t len = 0;
4900
 
    xmlParserInputState state;
4901
 
    const xmlChar *in;
4902
 
    size_t nbchar = 0;
4903
 
    int ccol;
4904
 
    int inputid;
4905
 
 
4906
 
    /*
4907
 
     * Check that there is a comment right here.
4908
 
     */
4909
 
    if ((RAW != '<') || (NXT(1) != '!') ||
4910
 
        (NXT(2) != '-') || (NXT(3) != '-')) return;
4911
 
    state = ctxt->instate;
4912
 
    ctxt->instate = XML_PARSER_COMMENT;
4913
 
    inputid = ctxt->input->id;
4914
 
    SKIP(4);
4915
 
    SHRINK;
4916
 
    GROW;
4917
 
 
4918
 
    /*
4919
 
     * Accelerated common case where input don't need to be
4920
 
     * modified before passing it to the handler.
4921
 
     */
4922
 
    in = ctxt->input->cur;
4923
 
    do {
4924
 
        if (*in == 0xA) {
4925
 
            do {
4926
 
                ctxt->input->line++; ctxt->input->col = 1;
4927
 
                in++;
4928
 
            } while (*in == 0xA);
4929
 
        }
4930
 
get_more:
4931
 
        ccol = ctxt->input->col;
4932
 
        while (((*in > '-') && (*in <= 0x7F)) ||
4933
 
               ((*in >= 0x20) && (*in < '-')) ||
4934
 
               (*in == 0x09)) {
4935
 
                    in++;
4936
 
                    ccol++;
4937
 
        }
4938
 
        ctxt->input->col = ccol;
4939
 
        if (*in == 0xA) {
4940
 
            do {
4941
 
                ctxt->input->line++; ctxt->input->col = 1;
4942
 
                in++;
4943
 
            } while (*in == 0xA);
4944
 
            goto get_more;
4945
 
        }
4946
 
        nbchar = in - ctxt->input->cur;
4947
 
        /*
4948
 
         * save current set of data
4949
 
         */
4950
 
        if (nbchar > 0) {
4951
 
            if ((ctxt->sax != NULL) &&
4952
 
                (ctxt->sax->comment != NULL)) {
4953
 
                if (buf == NULL) {
4954
 
                    if ((*in == '-') && (in[1] == '-'))
4955
 
                        size = nbchar + 1;
4956
 
                    else
4957
 
                        size = XML_PARSER_BUFFER_SIZE + nbchar;
4958
 
                    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
4959
 
                    if (buf == NULL) {
4960
 
                        xmlErrMemory(ctxt, NULL);
4961
 
                        ctxt->instate = state;
4962
 
                        return;
4963
 
                    }
4964
 
                    len = 0;
4965
 
                } else if (len + nbchar + 1 >= size) {
4966
 
                    xmlChar *new_buf;
4967
 
                    size  += len + nbchar + XML_PARSER_BUFFER_SIZE;
4968
 
                    new_buf = (xmlChar *) xmlRealloc(buf,
4969
 
                                                     size * sizeof(xmlChar));
4970
 
                    if (new_buf == NULL) {
4971
 
                        xmlFree (buf);
4972
 
                        xmlErrMemory(ctxt, NULL);
4973
 
                        ctxt->instate = state;
4974
 
                        return;
4975
 
                    }
4976
 
                    buf = new_buf;
4977
 
                }
4978
 
                memcpy(&buf[len], ctxt->input->cur, nbchar);
4979
 
                len += nbchar;
4980
 
                buf[len] = 0;
4981
 
            }
4982
 
        }
4983
 
        if ((len > XML_MAX_TEXT_LENGTH) &&
4984
 
            ((ctxt->options & XML_PARSE_HUGE) == 0)) {
4985
 
            xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
4986
 
                         "Comment too big found", NULL);
4987
 
            xmlFree (buf);
4988
 
            return;
4989
 
        }
4990
 
        ctxt->input->cur = in;
4991
 
        if (*in == 0xA) {
4992
 
            in++;
4993
 
            ctxt->input->line++; ctxt->input->col = 1;
4994
 
        }
4995
 
        if (*in == 0xD) {
4996
 
            in++;
4997
 
            if (*in == 0xA) {
4998
 
                ctxt->input->cur = in;
4999
 
                in++;
5000
 
                ctxt->input->line++; ctxt->input->col = 1;
5001
 
                continue; /* while */
5002
 
            }
5003
 
            in--;
5004
 
        }
5005
 
        SHRINK;
5006
 
        GROW;
5007
 
        if (ctxt->instate == XML_PARSER_EOF) {
5008
 
            xmlFree(buf);
5009
 
            return;
5010
 
        }
5011
 
        in = ctxt->input->cur;
5012
 
        if (*in == '-') {
5013
 
            if (in[1] == '-') {
5014
 
                if (in[2] == '>') {
5015
 
                    if (ctxt->input->id != inputid) {
5016
 
                        xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
5017
 
                        "comment doesn't start and stop in the same entity\n");
5018
 
                    }
5019
 
                    SKIP(3);
5020
 
                    if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
5021
 
                        (!ctxt->disableSAX)) {
5022
 
                        if (buf != NULL)
5023
 
                            ctxt->sax->comment(ctxt->userData, buf);
5024
 
                        else
5025
 
                            ctxt->sax->comment(ctxt->userData, BAD_CAST "");
5026
 
                    }
5027
 
                    if (buf != NULL)
5028
 
                        xmlFree(buf);
5029
 
                    if (ctxt->instate != XML_PARSER_EOF)
5030
 
                        ctxt->instate = state;
5031
 
                    return;
5032
 
                }
5033
 
                if (buf != NULL) {
5034
 
                    xmlFatalErrMsgStr(ctxt, XML_ERR_HYPHEN_IN_COMMENT,
5035
 
                                      "Double hyphen within comment: "
5036
 
                                      "<!--%.50s\n",
5037
 
                                      buf);
5038
 
                } else
5039
 
                    xmlFatalErrMsgStr(ctxt, XML_ERR_HYPHEN_IN_COMMENT,
5040
 
                                      "Double hyphen within comment\n", NULL);
5041
 
                in++;
5042
 
                ctxt->input->col++;
5043
 
            }
5044
 
            in++;
5045
 
            ctxt->input->col++;
5046
 
            goto get_more;
5047
 
        }
5048
 
    } while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09));
5049
 
    xmlParseCommentComplex(ctxt, buf, len, size);
5050
 
    ctxt->instate = state;
5051
 
    return;
5052
 
}
5053
 
 
5054
 
 
5055
 
/**
5056
 
 * xmlParsePITarget:
5057
 
 * @ctxt:  an XML parser context
5058
 
 *
5059
 
 * parse the name of a PI
5060
 
 *
5061
 
 * [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
5062
 
 *
5063
 
 * Returns the PITarget name or NULL
5064
 
 */
5065
 
 
5066
 
const xmlChar *
5067
 
xmlParsePITarget(xmlParserCtxtPtr ctxt) {
5068
 
    const xmlChar *name;
5069
 
 
5070
 
    name = xmlParseName(ctxt);
5071
 
    if ((name != NULL) &&
5072
 
        ((name[0] == 'x') || (name[0] == 'X')) &&
5073
 
        ((name[1] == 'm') || (name[1] == 'M')) &&
5074
 
        ((name[2] == 'l') || (name[2] == 'L'))) {
5075
 
        int i;
5076
 
        if ((name[0] == 'x') && (name[1] == 'm') &&
5077
 
            (name[2] == 'l') && (name[3] == 0)) {
5078
 
            xmlFatalErrMsg(ctxt, XML_ERR_RESERVED_XML_NAME,
5079
 
                 "XML declaration allowed only at the start of the document\n");
5080
 
            return(name);
5081
 
        } else if (name[3] == 0) {
5082
 
            xmlFatalErr(ctxt, XML_ERR_RESERVED_XML_NAME, NULL);
5083
 
            return(name);
5084
 
        }
5085
 
        for (i = 0;;i++) {
5086
 
            if (xmlW3CPIs[i] == NULL) break;
5087
 
            if (xmlStrEqual(name, (const xmlChar *)xmlW3CPIs[i]))
5088
 
                return(name);
5089
 
        }
5090
 
        xmlWarningMsg(ctxt, XML_ERR_RESERVED_XML_NAME,
5091
 
                      "xmlParsePITarget: invalid name prefix 'xml'\n",
5092
 
                      NULL, NULL);
5093
 
    }
5094
 
    if ((name != NULL) && (xmlStrchr(name, ':') != NULL)) {
5095
 
        xmlNsErr(ctxt, XML_NS_ERR_COLON,
5096
 
                 "colon are forbidden from PI names '%s'\n", name, NULL, NULL);
5097
 
    }
5098
 
    return(name);
5099
 
}
5100
 
 
5101
 
#ifdef LIBXML_CATALOG_ENABLED
5102
 
/**
5103
 
 * xmlParseCatalogPI:
5104
 
 * @ctxt:  an XML parser context
5105
 
 * @catalog:  the PI value string
5106
 
 *
5107
 
 * parse an XML Catalog Processing Instruction.
5108
 
 *
5109
 
 * <?oasis-xml-catalog catalog="http://example.com/catalog.xml"?>
5110
 
 *
5111
 
 * Occurs only if allowed by the user and if happening in the Misc
5112
 
 * part of the document before any doctype informations
5113
 
 * This will add the given catalog to the parsing context in order
5114
 
 * to be used if there is a resolution need further down in the document
5115
 
 */
5116
 
 
5117
 
static void
5118
 
xmlParseCatalogPI(xmlParserCtxtPtr ctxt, const xmlChar *catalog) {
5119
 
    xmlChar *URL = NULL;
5120
 
    const xmlChar *tmp, *base;
5121
 
    xmlChar marker;
5122
 
 
5123
 
    tmp = catalog;
5124
 
    while (IS_BLANK_CH(*tmp)) tmp++;
5125
 
    if (xmlStrncmp(tmp, BAD_CAST"catalog", 7))
5126
 
        goto error;
5127
 
    tmp += 7;
5128
 
    while (IS_BLANK_CH(*tmp)) tmp++;
5129
 
    if (*tmp != '=') {
5130
 
        return;
5131
 
    }
5132
 
    tmp++;
5133
 
    while (IS_BLANK_CH(*tmp)) tmp++;
5134
 
    marker = *tmp;
5135
 
    if ((marker != '\'') && (marker != '"'))
5136
 
        goto error;
5137
 
    tmp++;
5138
 
    base = tmp;
5139
 
    while ((*tmp != 0) && (*tmp != marker)) tmp++;
5140
 
    if (*tmp == 0)
5141
 
        goto error;
5142
 
    URL = xmlStrndup(base, tmp - base);
5143
 
    tmp++;
5144
 
    while (IS_BLANK_CH(*tmp)) tmp++;
5145
 
    if (*tmp != 0)
5146
 
        goto error;
5147
 
 
5148
 
    if (URL != NULL) {
5149
 
        ctxt->catalogs = xmlCatalogAddLocal(ctxt->catalogs, URL);
5150
 
        xmlFree(URL);
5151
 
    }
5152
 
    return;
5153
 
 
5154
 
error:
5155
 
    xmlWarningMsg(ctxt, XML_WAR_CATALOG_PI,
5156
 
                  "Catalog PI syntax error: %s\n",
5157
 
                  catalog, NULL);
5158
 
    if (URL != NULL)
5159
 
        xmlFree(URL);
5160
 
}
5161
 
#endif
5162
 
 
5163
 
/**
5164
 
 * xmlParsePI:
5165
 
 * @ctxt:  an XML parser context
5166
 
 *
5167
 
 * parse an XML Processing Instruction.
5168
 
 *
5169
 
 * [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
5170
 
 *
5171
 
 * The processing is transfered to SAX once parsed.
5172
 
 */
5173
 
 
5174
 
void
5175
 
xmlParsePI(xmlParserCtxtPtr ctxt) {
5176
 
    xmlChar *buf = NULL;
5177
 
    size_t len = 0;
5178
 
    size_t size = XML_PARSER_BUFFER_SIZE;
5179
 
    int cur, l;
5180
 
    const xmlChar *target;
5181
 
    xmlParserInputState state;
5182
 
    int count = 0;
5183
 
 
5184
 
    if ((RAW == '<') && (NXT(1) == '?')) {
5185
 
        xmlParserInputPtr input = ctxt->input;
5186
 
        state = ctxt->instate;
5187
 
        ctxt->instate = XML_PARSER_PI;
5188
 
        /*
5189
 
         * this is a Processing Instruction.
5190
 
         */
5191
 
        SKIP(2);
5192
 
        SHRINK;
5193
 
 
5194
 
        /*
5195
 
         * Parse the target name and check for special support like
5196
 
         * namespace.
5197
 
         */
5198
 
        target = xmlParsePITarget(ctxt);
5199
 
        if (target != NULL) {
5200
 
            if ((RAW == '?') && (NXT(1) == '>')) {
5201
 
                if (input != ctxt->input) {
5202
 
                    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
5203
 
            "PI declaration doesn't start and stop in the same entity\n");
5204
 
                }
5205
 
                SKIP(2);
5206
 
 
5207
 
                /*
5208
 
                 * SAX: PI detected.
5209
 
                 */
5210
 
                if ((ctxt->sax) && (!ctxt->disableSAX) &&
5211
 
                    (ctxt->sax->processingInstruction != NULL))
5212
 
                    ctxt->sax->processingInstruction(ctxt->userData,
5213
 
                                                     target, NULL);
5214
 
                if (ctxt->instate != XML_PARSER_EOF)
5215
 
                    ctxt->instate = state;
5216
 
                return;
5217
 
            }
5218
 
            buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
5219
 
            if (buf == NULL) {
5220
 
                xmlErrMemory(ctxt, NULL);
5221
 
                ctxt->instate = state;
5222
 
                return;
5223
 
            }
5224
 
            cur = CUR;
5225
 
            if (!IS_BLANK(cur)) {
5226
 
                xmlFatalErrMsgStr(ctxt, XML_ERR_SPACE_REQUIRED,
5227
 
                          "ParsePI: PI %s space expected\n", target);
5228
 
            }
5229
 
            SKIP_BLANKS;
5230
 
            cur = CUR_CHAR(l);
5231
 
            while (IS_CHAR(cur) && /* checked */
5232
 
                   ((cur != '?') || (NXT(1) != '>'))) {
5233
 
                if (len + 5 >= size) {
5234
 
                    xmlChar *tmp;
5235
 
                    size_t new_size = size * 2;
5236
 
                    tmp = (xmlChar *) xmlRealloc(buf, new_size);
5237
 
                    if (tmp == NULL) {
5238
 
                        xmlErrMemory(ctxt, NULL);
5239
 
                        xmlFree(buf);
5240
 
                        ctxt->instate = state;
5241
 
                        return;
5242
 
                    }
5243
 
                    buf = tmp;
5244
 
                    size = new_size;
5245
 
                }
5246
 
                count++;
5247
 
                if (count > 50) {
5248
 
                    GROW;
5249
 
                    if (ctxt->instate == XML_PARSER_EOF) {
5250
 
                        xmlFree(buf);
5251
 
                        return;
5252
 
                    }
5253
 
                    count = 0;
5254
 
                    if ((len > XML_MAX_TEXT_LENGTH) &&
5255
 
                        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
5256
 
                        xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
5257
 
                                          "PI %s too big found", target);
5258
 
                        xmlFree(buf);
5259
 
                        ctxt->instate = state;
5260
 
                        return;
5261
 
                    }
5262
 
                }
5263
 
                COPY_BUF(l,buf,len,cur);
5264
 
                NEXTL(l);
5265
 
                cur = CUR_CHAR(l);
5266
 
                if (cur == 0) {
5267
 
                    SHRINK;
5268
 
                    GROW;
5269
 
                    cur = CUR_CHAR(l);
5270
 
                }
5271
 
            }
5272
 
            if ((len > XML_MAX_TEXT_LENGTH) &&
5273
 
                ((ctxt->options & XML_PARSE_HUGE) == 0)) {
5274
 
                xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
5275
 
                                  "PI %s too big found", target);
5276
 
                xmlFree(buf);
5277
 
                ctxt->instate = state;
5278
 
                return;
5279
 
            }
5280
 
            buf[len] = 0;
5281
 
            if (cur != '?') {
5282
 
                xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
5283
 
                      "ParsePI: PI %s never end ...\n", target);
5284
 
            } else {
5285
 
                if (input != ctxt->input) {
5286
 
                    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5287
 
            "PI declaration doesn't start and stop in the same entity\n");
5288
 
                }
5289
 
                SKIP(2);
5290
 
 
5291
 
#ifdef LIBXML_CATALOG_ENABLED
5292
 
                if (((state == XML_PARSER_MISC) ||
5293
 
                     (state == XML_PARSER_START)) &&
5294
 
                    (xmlStrEqual(target, XML_CATALOG_PI))) {
5295
 
                    xmlCatalogAllow allow = xmlCatalogGetDefaults();
5296
 
                    if ((allow == XML_CATA_ALLOW_DOCUMENT) ||
5297
 
                        (allow == XML_CATA_ALLOW_ALL))
5298
 
                        xmlParseCatalogPI(ctxt, buf);
5299
 
                }
5300
 
#endif
5301
 
 
5302
 
 
5303
 
                /*
5304
 
                 * SAX: PI detected.
5305
 
                 */
5306
 
                if ((ctxt->sax) && (!ctxt->disableSAX) &&
5307
 
                    (ctxt->sax->processingInstruction != NULL))
5308
 
                    ctxt->sax->processingInstruction(ctxt->userData,
5309
 
                                                     target, buf);
5310
 
            }
5311
 
            xmlFree(buf);
5312
 
        } else {
5313
 
            xmlFatalErr(ctxt, XML_ERR_PI_NOT_STARTED, NULL);
5314
 
        }
5315
 
        if (ctxt->instate != XML_PARSER_EOF)
5316
 
            ctxt->instate = state;
5317
 
    }
5318
 
}
5319
 
 
5320
 
/**
5321
 
 * xmlParseNotationDecl:
5322
 
 * @ctxt:  an XML parser context
5323
 
 *
5324
 
 * parse a notation declaration
5325
 
 *
5326
 
 * [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID |  PublicID) S? '>'
5327
 
 *
5328
 
 * Hence there is actually 3 choices:
5329
 
 *     'PUBLIC' S PubidLiteral
5330
 
 *     'PUBLIC' S PubidLiteral S SystemLiteral
5331
 
 * and 'SYSTEM' S SystemLiteral
5332
 
 *
5333
 
 * See the NOTE on xmlParseExternalID().
5334
 
 */
5335
 
 
5336
 
void
5337
 
xmlParseNotationDecl(xmlParserCtxtPtr ctxt) {
5338
 
    const xmlChar *name;
5339
 
    xmlChar *Pubid;
5340
 
    xmlChar *Systemid;
5341
 
 
5342
 
    if (CMP10(CUR_PTR, '<', '!', 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
5343
 
        xmlParserInputPtr input = ctxt->input;
5344
 
        SHRINK;
5345
 
        SKIP(10);
5346
 
        if (!IS_BLANK_CH(CUR)) {
5347
 
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5348
 
                           "Space required after '<!NOTATION'\n");
5349
 
            return;
5350
 
        }
5351
 
        SKIP_BLANKS;
5352
 
 
5353
 
        name = xmlParseName(ctxt);
5354
 
        if (name == NULL) {
5355
 
            xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
5356
 
            return;
5357
 
        }
5358
 
        if (!IS_BLANK_CH(CUR)) {
5359
 
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5360
 
                     "Space required after the NOTATION name'\n");
5361
 
            return;
5362
 
        }
5363
 
        if (xmlStrchr(name, ':') != NULL) {
5364
 
            xmlNsErr(ctxt, XML_NS_ERR_COLON,
5365
 
                     "colon are forbidden from notation names '%s'\n",
5366
 
                     name, NULL, NULL);
5367
 
        }
5368
 
        SKIP_BLANKS;
5369
 
 
5370
 
        /*
5371
 
         * Parse the IDs.
5372
 
         */
5373
 
        Systemid = xmlParseExternalID(ctxt, &Pubid, 0);
5374
 
        SKIP_BLANKS;
5375
 
 
5376
 
        if (RAW == '>') {
5377
 
            if (input != ctxt->input) {
5378
 
                xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5379
 
        "Notation declaration doesn't start and stop in the same entity\n");
5380
 
            }
5381
 
            NEXT;
5382
 
            if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
5383
 
                (ctxt->sax->notationDecl != NULL))
5384
 
                ctxt->sax->notationDecl(ctxt->userData, name, Pubid, Systemid);
5385
 
        } else {
5386
 
            xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
5387
 
        }
5388
 
        if (Systemid != NULL) xmlFree(Systemid);
5389
 
        if (Pubid != NULL) xmlFree(Pubid);
5390
 
    }
5391
 
}
5392
 
 
5393
 
/**
5394
 
 * xmlParseEntityDecl:
5395
 
 * @ctxt:  an XML parser context
5396
 
 *
5397
 
 * parse <!ENTITY declarations
5398
 
 *
5399
 
 * [70] EntityDecl ::= GEDecl | PEDecl
5400
 
 *
5401
 
 * [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
5402
 
 *
5403
 
 * [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
5404
 
 *
5405
 
 * [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
5406
 
 *
5407
 
 * [74] PEDef ::= EntityValue | ExternalID
5408
 
 *
5409
 
 * [76] NDataDecl ::= S 'NDATA' S Name
5410
 
 *
5411
 
 * [ VC: Notation Declared ]
5412
 
 * The Name must match the declared name of a notation.
5413
 
 */
5414
 
 
5415
 
void
5416
 
xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
5417
 
    const xmlChar *name = NULL;
5418
 
    xmlChar *value = NULL;
5419
 
    xmlChar *URI = NULL, *literal = NULL;
5420
 
    const xmlChar *ndata = NULL;
5421
 
    int isParameter = 0;
5422
 
    xmlChar *orig = NULL;
5423
 
    int skipped;
5424
 
 
5425
 
    /* GROW; done in the caller */
5426
 
    if (CMP8(CUR_PTR, '<', '!', 'E', 'N', 'T', 'I', 'T', 'Y')) {
5427
 
        xmlParserInputPtr input = ctxt->input;
5428
 
        SHRINK;
5429
 
        SKIP(8);
5430
 
        skipped = SKIP_BLANKS;
5431
 
        if (skipped == 0) {
5432
 
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5433
 
                           "Space required after '<!ENTITY'\n");
5434
 
        }
5435
 
 
5436
 
        if (RAW == '%') {
5437
 
            NEXT;
5438
 
            skipped = SKIP_BLANKS;
5439
 
            if (skipped == 0) {
5440
 
                xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5441
 
                               "Space required after '%'\n");
5442
 
            }
5443
 
            isParameter = 1;
5444
 
        }
5445
 
 
5446
 
        name = xmlParseName(ctxt);
5447
 
        if (name == NULL) {
5448
 
            xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
5449
 
                           "xmlParseEntityDecl: no name\n");
5450
 
            return;
5451
 
        }
5452
 
        if (xmlStrchr(name, ':') != NULL) {
5453
 
            xmlNsErr(ctxt, XML_NS_ERR_COLON,
5454
 
                     "colon are forbidden from entities names '%s'\n",
5455
 
                     name, NULL, NULL);
5456
 
        }
5457
 
        skipped = SKIP_BLANKS;
5458
 
        if (skipped == 0) {
5459
 
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5460
 
                           "Space required after the entity name\n");
5461
 
        }
5462
 
 
5463
 
        ctxt->instate = XML_PARSER_ENTITY_DECL;
5464
 
        /*
5465
 
         * handle the various case of definitions...
5466
 
         */
5467
 
        if (isParameter) {
5468
 
            if ((RAW == '"') || (RAW == '\'')) {
5469
 
                value = xmlParseEntityValue(ctxt, &orig);
5470
 
                if (value) {
5471
 
                    if ((ctxt->sax != NULL) &&
5472
 
                        (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
5473
 
                        ctxt->sax->entityDecl(ctxt->userData, name,
5474
 
                                    XML_INTERNAL_PARAMETER_ENTITY,
5475
 
                                    NULL, NULL, value);
5476
 
                }
5477
 
            } else {
5478
 
                URI = xmlParseExternalID(ctxt, &literal, 1);
5479
 
                if ((URI == NULL) && (literal == NULL)) {
5480
 
                    xmlFatalErr(ctxt, XML_ERR_VALUE_REQUIRED, NULL);
5481
 
                }
5482
 
                if (URI) {
5483
 
                    xmlURIPtr uri;
5484
 
 
5485
 
                    uri = xmlParseURI((const char *) URI);
5486
 
                    if (uri == NULL) {
5487
 
                        xmlErrMsgStr(ctxt, XML_ERR_INVALID_URI,
5488
 
                                     "Invalid URI: %s\n", URI);
5489
 
                        /*
5490
 
                         * This really ought to be a well formedness error
5491
 
                         * but the XML Core WG decided otherwise c.f. issue
5492
 
                         * E26 of the XML erratas.
5493
 
                         */
5494
 
                    } else {
5495
 
                        if (uri->fragment != NULL) {
5496
 
                            /*
5497
 
                             * Okay this is foolish to block those but not
5498
 
                             * invalid URIs.
5499
 
                             */
5500
 
                            xmlFatalErr(ctxt, XML_ERR_URI_FRAGMENT, NULL);
5501
 
                        } else {
5502
 
                            if ((ctxt->sax != NULL) &&
5503
 
                                (!ctxt->disableSAX) &&
5504
 
                                (ctxt->sax->entityDecl != NULL))
5505
 
                                ctxt->sax->entityDecl(ctxt->userData, name,
5506
 
                                            XML_EXTERNAL_PARAMETER_ENTITY,
5507
 
                                            literal, URI, NULL);
5508
 
                        }
5509
 
                        xmlFreeURI(uri);
5510
 
                    }
5511
 
                }
5512
 
            }
5513
 
        } else {
5514
 
            if ((RAW == '"') || (RAW == '\'')) {
5515
 
                value = xmlParseEntityValue(ctxt, &orig);
5516
 
                if ((ctxt->sax != NULL) &&
5517
 
                    (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
5518
 
                    ctxt->sax->entityDecl(ctxt->userData, name,
5519
 
                                XML_INTERNAL_GENERAL_ENTITY,
5520
 
                                NULL, NULL, value);
5521
 
                /*
5522
 
                 * For expat compatibility in SAX mode.
5523
 
                 */
5524
 
                if ((ctxt->myDoc == NULL) ||
5525
 
                    (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) {
5526
 
                    if (ctxt->myDoc == NULL) {
5527
 
                        ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
5528
 
                        if (ctxt->myDoc == NULL) {
5529
 
                            xmlErrMemory(ctxt, "New Doc failed");
5530
 
                            return;
5531
 
                        }
5532
 
                        ctxt->myDoc->properties = XML_DOC_INTERNAL;
5533
 
                    }
5534
 
                    if (ctxt->myDoc->intSubset == NULL)
5535
 
                        ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
5536
 
                                            BAD_CAST "fake", NULL, NULL);
5537
 
 
5538
 
                    xmlSAX2EntityDecl(ctxt, name, XML_INTERNAL_GENERAL_ENTITY,
5539
 
                                      NULL, NULL, value);
5540
 
                }
5541
 
            } else {
5542
 
                URI = xmlParseExternalID(ctxt, &literal, 1);
5543
 
                if ((URI == NULL) && (literal == NULL)) {
5544
 
                    xmlFatalErr(ctxt, XML_ERR_VALUE_REQUIRED, NULL);
5545
 
                }
5546
 
                if (URI) {
5547
 
                    xmlURIPtr uri;
5548
 
 
5549
 
                    uri = xmlParseURI((const char *)URI);
5550
 
                    if (uri == NULL) {
5551
 
                        xmlErrMsgStr(ctxt, XML_ERR_INVALID_URI,
5552
 
                                     "Invalid URI: %s\n", URI);
5553
 
                        /*
5554
 
                         * This really ought to be a well formedness error
5555
 
                         * but the XML Core WG decided otherwise c.f. issue
5556
 
                         * E26 of the XML erratas.
5557
 
                         */
5558
 
                    } else {
5559
 
                        if (uri->fragment != NULL) {
5560
 
                            /*
5561
 
                             * Okay this is foolish to block those but not
5562
 
                             * invalid URIs.
5563
 
                             */
5564
 
                            xmlFatalErr(ctxt, XML_ERR_URI_FRAGMENT, NULL);
5565
 
                        }
5566
 
                        xmlFreeURI(uri);
5567
 
                    }
5568
 
                }
5569
 
                if ((RAW != '>') && (!IS_BLANK_CH(CUR))) {
5570
 
                    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5571
 
                                   "Space required before 'NDATA'\n");
5572
 
                }
5573
 
                SKIP_BLANKS;
5574
 
                if (CMP5(CUR_PTR, 'N', 'D', 'A', 'T', 'A')) {
5575
 
                    SKIP(5);
5576
 
                    if (!IS_BLANK_CH(CUR)) {
5577
 
                        xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5578
 
                                       "Space required after 'NDATA'\n");
5579
 
                    }
5580
 
                    SKIP_BLANKS;
5581
 
                    ndata = xmlParseName(ctxt);
5582
 
                    if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
5583
 
                        (ctxt->sax->unparsedEntityDecl != NULL))
5584
 
                        ctxt->sax->unparsedEntityDecl(ctxt->userData, name,
5585
 
                                    literal, URI, ndata);
5586
 
                } else {
5587
 
                    if ((ctxt->sax != NULL) &&
5588
 
                        (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
5589
 
                        ctxt->sax->entityDecl(ctxt->userData, name,
5590
 
                                    XML_EXTERNAL_GENERAL_PARSED_ENTITY,
5591
 
                                    literal, URI, NULL);
5592
 
                    /*
5593
 
                     * For expat compatibility in SAX mode.
5594
 
                     * assuming the entity repalcement was asked for
5595
 
                     */
5596
 
                    if ((ctxt->replaceEntities != 0) &&
5597
 
                        ((ctxt->myDoc == NULL) ||
5598
 
                        (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE)))) {
5599
 
                        if (ctxt->myDoc == NULL) {
5600
 
                            ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
5601
 
                            if (ctxt->myDoc == NULL) {
5602
 
                                xmlErrMemory(ctxt, "New Doc failed");
5603
 
                                return;
5604
 
                            }
5605
 
                            ctxt->myDoc->properties = XML_DOC_INTERNAL;
5606
 
                        }
5607
 
 
5608
 
                        if (ctxt->myDoc->intSubset == NULL)
5609
 
                            ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
5610
 
                                                BAD_CAST "fake", NULL, NULL);
5611
 
                        xmlSAX2EntityDecl(ctxt, name,
5612
 
                                          XML_EXTERNAL_GENERAL_PARSED_ENTITY,
5613
 
                                          literal, URI, NULL);
5614
 
                    }
5615
 
                }
5616
 
            }
5617
 
        }
5618
 
        if (ctxt->instate == XML_PARSER_EOF)
5619
 
            return;
5620
 
        SKIP_BLANKS;
5621
 
        if (RAW != '>') {
5622
 
            xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_NOT_FINISHED,
5623
 
                    "xmlParseEntityDecl: entity %s not terminated\n", name);
5624
 
        } else {
5625
 
            if (input != ctxt->input) {
5626
 
                xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
5627
 
        "Entity declaration doesn't start and stop in the same entity\n");
5628
 
            }
5629
 
            NEXT;
5630
 
        }
5631
 
        if (orig != NULL) {
5632
 
            /*
5633
 
             * Ugly mechanism to save the raw entity value.
5634
 
             */
5635
 
            xmlEntityPtr cur = NULL;
5636
 
 
5637
 
            if (isParameter) {
5638
 
                if ((ctxt->sax != NULL) &&
5639
 
                    (ctxt->sax->getParameterEntity != NULL))
5640
 
                    cur = ctxt->sax->getParameterEntity(ctxt->userData, name);
5641
 
            } else {
5642
 
                if ((ctxt->sax != NULL) &&
5643
 
                    (ctxt->sax->getEntity != NULL))
5644
 
                    cur = ctxt->sax->getEntity(ctxt->userData, name);
5645
 
                if ((cur == NULL) && (ctxt->userData==ctxt)) {
5646
 
                    cur = xmlSAX2GetEntity(ctxt, name);
5647
 
                }
5648
 
            }
5649
 
            if (cur != NULL) {
5650
 
                if (cur->orig != NULL)
5651
 
                    xmlFree(orig);
5652
 
                else
5653
 
                    cur->orig = orig;
5654
 
            } else
5655
 
                xmlFree(orig);
5656
 
        }
5657
 
        if (value != NULL) xmlFree(value);
5658
 
        if (URI != NULL) xmlFree(URI);
5659
 
        if (literal != NULL) xmlFree(literal);
5660
 
    }
5661
 
}
5662
 
 
5663
 
/**
5664
 
 * xmlParseDefaultDecl:
5665
 
 * @ctxt:  an XML parser context
5666
 
 * @value:  Receive a possible fixed default value for the attribute
5667
 
 *
5668
 
 * Parse an attribute default declaration
5669
 
 *
5670
 
 * [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)
5671
 
 *
5672
 
 * [ VC: Required Attribute ]
5673
 
 * if the default declaration is the keyword #REQUIRED, then the
5674
 
 * attribute must be specified for all elements of the type in the
5675
 
 * attribute-list declaration.
5676
 
 *
5677
 
 * [ VC: Attribute Default Legal ]
5678
 
 * The declared default value must meet the lexical constraints of
5679
 
 * the declared attribute type c.f. xmlValidateAttributeDecl()
5680
 
 *
5681
 
 * [ VC: Fixed Attribute Default ]
5682
 
 * if an attribute has a default value declared with the #FIXED
5683
 
 * keyword, instances of that attribute must match the default value.
5684
 
 *
5685
 
 * [ WFC: No < in Attribute Values ]
5686
 
 * handled in xmlParseAttValue()
5687
 
 *
5688
 
 * returns: XML_ATTRIBUTE_NONE, XML_ATTRIBUTE_REQUIRED, XML_ATTRIBUTE_IMPLIED
5689
 
 *          or XML_ATTRIBUTE_FIXED.
5690
 
 */
5691
 
 
5692
 
int
5693
 
xmlParseDefaultDecl(xmlParserCtxtPtr ctxt, xmlChar **value) {
5694
 
    int val;
5695
 
    xmlChar *ret;
5696
 
 
5697
 
    *value = NULL;
5698
 
    if (CMP9(CUR_PTR, '#', 'R', 'E', 'Q', 'U', 'I', 'R', 'E', 'D')) {
5699
 
        SKIP(9);
5700
 
        return(XML_ATTRIBUTE_REQUIRED);
5701
 
    }
5702
 
    if (CMP8(CUR_PTR, '#', 'I', 'M', 'P', 'L', 'I', 'E', 'D')) {
5703
 
        SKIP(8);
5704
 
        return(XML_ATTRIBUTE_IMPLIED);
5705
 
    }
5706
 
    val = XML_ATTRIBUTE_NONE;
5707
 
    if (CMP6(CUR_PTR, '#', 'F', 'I', 'X', 'E', 'D')) {
5708
 
        SKIP(6);
5709
 
        val = XML_ATTRIBUTE_FIXED;
5710
 
        if (!IS_BLANK_CH(CUR)) {
5711
 
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5712
 
                           "Space required after '#FIXED'\n");
5713
 
        }
5714
 
        SKIP_BLANKS;
5715
 
    }
5716
 
    ret = xmlParseAttValue(ctxt);
5717
 
    ctxt->instate = XML_PARSER_DTD;
5718
 
    if (ret == NULL) {
5719
 
        xmlFatalErrMsg(ctxt, (xmlParserErrors)ctxt->errNo,
5720
 
                       "Attribute default value declaration error\n");
5721
 
    } else
5722
 
        *value = ret;
5723
 
    return(val);
5724
 
}
5725
 
 
5726
 
/**
5727
 
 * xmlParseNotationType:
5728
 
 * @ctxt:  an XML parser context
5729
 
 *
5730
 
 * parse an Notation attribute type.
5731
 
 *
5732
 
 * Note: the leading 'NOTATION' S part has already being parsed...
5733
 
 *
5734
 
 * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
5735
 
 *
5736
 
 * [ VC: Notation Attributes ]
5737
 
 * Values of this type must match one of the notation names included
5738
 
 * in the declaration; all notation names in the declaration must be declared.
5739
 
 *
5740
 
 * Returns: the notation attribute tree built while parsing
5741
 
 */
5742
 
 
5743
 
xmlEnumerationPtr
5744
 
xmlParseNotationType(xmlParserCtxtPtr ctxt) {
5745
 
    const xmlChar *name;
5746
 
    xmlEnumerationPtr ret = NULL, last = NULL, cur, tmp;
5747
 
 
5748
 
    if (RAW != '(') {
5749
 
        xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
5750
 
        return(NULL);
5751
 
    }
5752
 
    SHRINK;
5753
 
    do {
5754
 
        NEXT;
5755
 
        SKIP_BLANKS;
5756
 
        name = xmlParseName(ctxt);
5757
 
        if (name == NULL) {
5758
 
            xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
5759
 
                           "Name expected in NOTATION declaration\n");
5760
 
            xmlFreeEnumeration(ret);
5761
 
            return(NULL);
5762
 
        }
5763
 
        tmp = ret;
5764
 
        while (tmp != NULL) {
5765
 
            if (xmlStrEqual(name, tmp->name)) {
5766
 
                xmlValidityError(ctxt, XML_DTD_DUP_TOKEN,
5767
 
          "standalone: attribute notation value token %s duplicated\n",
5768
 
                                 name, NULL);
5769
 
                if (!xmlDictOwns(ctxt->dict, name))
5770
 
                    xmlFree((xmlChar *) name);
5771
 
                break;
5772
 
            }
5773
 
            tmp = tmp->next;
5774
 
        }
5775
 
        if (tmp == NULL) {
5776
 
            cur = xmlCreateEnumeration(name);
5777
 
            if (cur == NULL) {
5778
 
                xmlFreeEnumeration(ret);
5779
 
                return(NULL);
5780
 
            }
5781
 
            if (last == NULL) ret = last = cur;
5782
 
            else {
5783
 
                last->next = cur;
5784
 
                last = cur;
5785
 
            }
5786
 
        }
5787
 
        SKIP_BLANKS;
5788
 
    } while (RAW == '|');
5789
 
    if (RAW != ')') {
5790
 
        xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
5791
 
        xmlFreeEnumeration(ret);
5792
 
        return(NULL);
5793
 
    }
5794
 
    NEXT;
5795
 
    return(ret);
5796
 
}
5797
 
 
5798
 
/**
5799
 
 * xmlParseEnumerationType:
5800
 
 * @ctxt:  an XML parser context
5801
 
 *
5802
 
 * parse an Enumeration attribute type.
5803
 
 *
5804
 
 * [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
5805
 
 *
5806
 
 * [ VC: Enumeration ]
5807
 
 * Values of this type must match one of the Nmtoken tokens in
5808
 
 * the declaration
5809
 
 *
5810
 
 * Returns: the enumeration attribute tree built while parsing
5811
 
 */
5812
 
 
5813
 
xmlEnumerationPtr
5814
 
xmlParseEnumerationType(xmlParserCtxtPtr ctxt) {
5815
 
    xmlChar *name;
5816
 
    xmlEnumerationPtr ret = NULL, last = NULL, cur, tmp;
5817
 
 
5818
 
    if (RAW != '(') {
5819
 
        xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_STARTED, NULL);
5820
 
        return(NULL);
5821
 
    }
5822
 
    SHRINK;
5823
 
    do {
5824
 
        NEXT;
5825
 
        SKIP_BLANKS;
5826
 
        name = xmlParseNmtoken(ctxt);
5827
 
        if (name == NULL) {
5828
 
            xmlFatalErr(ctxt, XML_ERR_NMTOKEN_REQUIRED, NULL);
5829
 
            return(ret);
5830
 
        }
5831
 
        tmp = ret;
5832
 
        while (tmp != NULL) {
5833
 
            if (xmlStrEqual(name, tmp->name)) {
5834
 
                xmlValidityError(ctxt, XML_DTD_DUP_TOKEN,
5835
 
          "standalone: attribute enumeration value token %s duplicated\n",
5836
 
                                 name, NULL);
5837
 
                if (!xmlDictOwns(ctxt->dict, name))
5838
 
                    xmlFree(name);
5839
 
                break;
5840
 
            }
5841
 
            tmp = tmp->next;
5842
 
        }
5843
 
        if (tmp == NULL) {
5844
 
            cur = xmlCreateEnumeration(name);
5845
 
            if (!xmlDictOwns(ctxt->dict, name))
5846
 
                xmlFree(name);
5847
 
            if (cur == NULL) {
5848
 
                xmlFreeEnumeration(ret);
5849
 
                return(NULL);
5850
 
            }
5851
 
            if (last == NULL) ret = last = cur;
5852
 
            else {
5853
 
                last->next = cur;
5854
 
                last = cur;
5855
 
            }
5856
 
        }
5857
 
        SKIP_BLANKS;
5858
 
    } while (RAW == '|');
5859
 
    if (RAW != ')') {
5860
 
        xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_FINISHED, NULL);
5861
 
        return(ret);
5862
 
    }
5863
 
    NEXT;
5864
 
    return(ret);
5865
 
}
5866
 
 
5867
 
/**
5868
 
 * xmlParseEnumeratedType:
5869
 
 * @ctxt:  an XML parser context
5870
 
 * @tree:  the enumeration tree built while parsing
5871
 
 *
5872
 
 * parse an Enumerated attribute type.
5873
 
 *
5874
 
 * [57] EnumeratedType ::= NotationType | Enumeration
5875
 
 *
5876
 
 * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
5877
 
 *
5878
 
 *
5879
 
 * Returns: XML_ATTRIBUTE_ENUMERATION or XML_ATTRIBUTE_NOTATION
5880
 
 */
5881
 
 
5882
 
int
5883
 
xmlParseEnumeratedType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
5884
 
    if (CMP8(CUR_PTR, 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
5885
 
        SKIP(8);
5886
 
        if (!IS_BLANK_CH(CUR)) {
5887
 
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5888
 
                           "Space required after 'NOTATION'\n");
5889
 
            return(0);
5890
 
        }
5891
 
        SKIP_BLANKS;
5892
 
        *tree = xmlParseNotationType(ctxt);
5893
 
        if (*tree == NULL) return(0);
5894
 
        return(XML_ATTRIBUTE_NOTATION);
5895
 
    }
5896
 
    *tree = xmlParseEnumerationType(ctxt);
5897
 
    if (*tree == NULL) return(0);
5898
 
    return(XML_ATTRIBUTE_ENUMERATION);
5899
 
}
5900
 
 
5901
 
/**
5902
 
 * xmlParseAttributeType:
5903
 
 * @ctxt:  an XML parser context
5904
 
 * @tree:  the enumeration tree built while parsing
5905
 
 *
5906
 
 * parse the Attribute list def for an element
5907
 
 *
5908
 
 * [54] AttType ::= StringType | TokenizedType | EnumeratedType
5909
 
 *
5910
 
 * [55] StringType ::= 'CDATA'
5911
 
 *
5912
 
 * [56] TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' |
5913
 
 *                        'ENTITIES' | 'NMTOKEN' | 'NMTOKENS'
5914
 
 *
5915
 
 * Validity constraints for attribute values syntax are checked in
5916
 
 * xmlValidateAttributeValue()
5917
 
 *
5918
 
 * [ VC: ID ]
5919
 
 * Values of type ID must match the Name production. A name must not
5920
 
 * appear more than once in an XML document as a value of this type;
5921
 
 * i.e., ID values must uniquely identify the elements which bear them.
5922
 
 *
5923
 
 * [ VC: One ID per Element Type ]
5924
 
 * No element type may have more than one ID attribute specified.
5925
 
 *
5926
 
 * [ VC: ID Attribute Default ]
5927
 
 * An ID attribute must have a declared default of #IMPLIED or #REQUIRED.
5928
 
 *
5929
 
 * [ VC: IDREF ]
5930
 
 * Values of type IDREF must match the Name production, and values
5931
 
 * of type IDREFS must match Names; each IDREF Name must match the value
5932
 
 * of an ID attribute on some element in the XML document; i.e. IDREF
5933
 
 * values must match the value of some ID attribute.
5934
 
 *
5935
 
 * [ VC: Entity Name ]
5936
 
 * Values of type ENTITY must match the Name production, values
5937
 
 * of type ENTITIES must match Names; each Entity Name must match the
5938
 
 * name of an unparsed entity declared in the DTD.
5939
 
 *
5940
 
 * [ VC: Name Token ]
5941
 
 * Values of type NMTOKEN must match the Nmtoken production; values
5942
 
 * of type NMTOKENS must match Nmtokens.
5943
 
 *
5944
 
 * Returns the attribute type
5945
 
 */
5946
 
int
5947
 
xmlParseAttributeType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
5948
 
    SHRINK;
5949
 
    if (CMP5(CUR_PTR, 'C', 'D', 'A', 'T', 'A')) {
5950
 
        SKIP(5);
5951
 
        return(XML_ATTRIBUTE_CDATA);
5952
 
     } else if (CMP6(CUR_PTR, 'I', 'D', 'R', 'E', 'F', 'S')) {
5953
 
        SKIP(6);
5954
 
        return(XML_ATTRIBUTE_IDREFS);
5955
 
     } else if (CMP5(CUR_PTR, 'I', 'D', 'R', 'E', 'F')) {
5956
 
        SKIP(5);
5957
 
        return(XML_ATTRIBUTE_IDREF);
5958
 
     } else if ((RAW == 'I') && (NXT(1) == 'D')) {
5959
 
        SKIP(2);
5960
 
        return(XML_ATTRIBUTE_ID);
5961
 
     } else if (CMP6(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'Y')) {
5962
 
        SKIP(6);
5963
 
        return(XML_ATTRIBUTE_ENTITY);
5964
 
     } else if (CMP8(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S')) {
5965
 
        SKIP(8);
5966
 
        return(XML_ATTRIBUTE_ENTITIES);
5967
 
     } else if (CMP8(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S')) {
5968
 
        SKIP(8);
5969
 
        return(XML_ATTRIBUTE_NMTOKENS);
5970
 
     } else if (CMP7(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N')) {
5971
 
        SKIP(7);
5972
 
        return(XML_ATTRIBUTE_NMTOKEN);
5973
 
     }
5974
 
     return(xmlParseEnumeratedType(ctxt, tree));
5975
 
}
5976
 
 
5977
 
/**
5978
 
 * xmlParseAttributeListDecl:
5979
 
 * @ctxt:  an XML parser context
5980
 
 *
5981
 
 * : parse the Attribute list def for an element
5982
 
 *
5983
 
 * [52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
5984
 
 *
5985
 
 * [53] AttDef ::= S Name S AttType S DefaultDecl
5986
 
 *
5987
 
 */
5988
 
void
5989
 
xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) {
5990
 
    const xmlChar *elemName;
5991
 
    const xmlChar *attrName;
5992
 
    xmlEnumerationPtr tree;
5993
 
 
5994
 
    if (CMP9(CUR_PTR, '<', '!', 'A', 'T', 'T', 'L', 'I', 'S', 'T')) {
5995
 
        xmlParserInputPtr input = ctxt->input;
5996
 
 
5997
 
        SKIP(9);
5998
 
        if (!IS_BLANK_CH(CUR)) {
5999
 
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6000
 
                                 "Space required after '<!ATTLIST'\n");
6001
 
        }
6002
 
        SKIP_BLANKS;
6003
 
        elemName = xmlParseName(ctxt);
6004
 
        if (elemName == NULL) {
6005
 
            xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
6006
 
                           "ATTLIST: no name for Element\n");
6007
 
            return;
6008
 
        }
6009
 
        SKIP_BLANKS;
6010
 
        GROW;
6011
 
        while ((RAW != '>') && (ctxt->instate != XML_PARSER_EOF)) {
6012
 
            const xmlChar *check = CUR_PTR;
6013
 
            int type;
6014
 
            int def;
6015
 
            xmlChar *defaultValue = NULL;
6016
 
 
6017
 
            GROW;
6018
 
            tree = NULL;
6019
 
            attrName = xmlParseName(ctxt);
6020
 
            if (attrName == NULL) {
6021
 
                xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
6022
 
                               "ATTLIST: no name for Attribute\n");
6023
 
                break;
6024
 
            }
6025
 
            GROW;
6026
 
            if (!IS_BLANK_CH(CUR)) {
6027
 
                xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6028
 
                        "Space required after the attribute name\n");
6029
 
                break;
6030
 
            }
6031
 
            SKIP_BLANKS;
6032
 
 
6033
 
            type = xmlParseAttributeType(ctxt, &tree);
6034
 
            if (type <= 0) {
6035
 
                break;
6036
 
            }
6037
 
 
6038
 
            GROW;
6039
 
            if (!IS_BLANK_CH(CUR)) {
6040
 
                xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6041
 
                               "Space required after the attribute type\n");
6042
 
                if (tree != NULL)
6043
 
                    xmlFreeEnumeration(tree);
6044
 
                break;
6045
 
            }
6046
 
            SKIP_BLANKS;
6047
 
 
6048
 
            def = xmlParseDefaultDecl(ctxt, &defaultValue);
6049
 
            if (def <= 0) {
6050
 
                if (defaultValue != NULL)
6051
 
                    xmlFree(defaultValue);
6052
 
                if (tree != NULL)
6053
 
                    xmlFreeEnumeration(tree);
6054
 
                break;
6055
 
            }
6056
 
            if ((type != XML_ATTRIBUTE_CDATA) && (defaultValue != NULL))
6057
 
                xmlAttrNormalizeSpace(defaultValue, defaultValue);
6058
 
 
6059
 
            GROW;
6060
 
            if (RAW != '>') {
6061
 
                if (!IS_BLANK_CH(CUR)) {
6062
 
                    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6063
 
                        "Space required after the attribute default value\n");
6064
 
                    if (defaultValue != NULL)
6065
 
                        xmlFree(defaultValue);
6066
 
                    if (tree != NULL)
6067
 
                        xmlFreeEnumeration(tree);
6068
 
                    break;
6069
 
                }
6070
 
                SKIP_BLANKS;
6071
 
            }
6072
 
            if (check == CUR_PTR) {
6073
 
                xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
6074
 
                            "in xmlParseAttributeListDecl\n");
6075
 
                if (defaultValue != NULL)
6076
 
                    xmlFree(defaultValue);
6077
 
                if (tree != NULL)
6078
 
                    xmlFreeEnumeration(tree);
6079
 
                break;
6080
 
            }
6081
 
            if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
6082
 
                (ctxt->sax->attributeDecl != NULL))
6083
 
                ctxt->sax->attributeDecl(ctxt->userData, elemName, attrName,
6084
 
                                type, def, defaultValue, tree);
6085
 
            else if (tree != NULL)
6086
 
                xmlFreeEnumeration(tree);
6087
 
 
6088
 
            if ((ctxt->sax2) && (defaultValue != NULL) &&
6089
 
                (def != XML_ATTRIBUTE_IMPLIED) &&
6090
 
                (def != XML_ATTRIBUTE_REQUIRED)) {
6091
 
                xmlAddDefAttrs(ctxt, elemName, attrName, defaultValue);
6092
 
            }
6093
 
            if (ctxt->sax2) {
6094
 
                xmlAddSpecialAttr(ctxt, elemName, attrName, type);
6095
 
            }
6096
 
            if (defaultValue != NULL)
6097
 
                xmlFree(defaultValue);
6098
 
            GROW;
6099
 
        }
6100
 
        if (RAW == '>') {
6101
 
            if (input != ctxt->input) {
6102
 
                xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
6103
 
    "Attribute list declaration doesn't start and stop in the same entity\n",
6104
 
                                 NULL, NULL);
6105
 
            }
6106
 
            NEXT;
6107
 
        }
6108
 
    }
6109
 
}
6110
 
 
6111
 
/**
6112
 
 * xmlParseElementMixedContentDecl:
6113
 
 * @ctxt:  an XML parser context
6114
 
 * @inputchk:  the input used for the current entity, needed for boundary checks
6115
 
 *
6116
 
 * parse the declaration for a Mixed Element content
6117
 
 * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
6118
 
 *
6119
 
 * [51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' |
6120
 
 *                '(' S? '#PCDATA' S? ')'
6121
 
 *
6122
 
 * [ VC: Proper Group/PE Nesting ] applies to [51] too (see [49])
6123
 
 *
6124
 
 * [ VC: No Duplicate Types ]
6125
 
 * The same name must not appear more than once in a single
6126
 
 * mixed-content declaration.
6127
 
 *
6128
 
 * returns: the list of the xmlElementContentPtr describing the element choices
6129
 
 */
6130
 
xmlElementContentPtr
6131
 
xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
6132
 
    xmlElementContentPtr ret = NULL, cur = NULL, n;
6133
 
    const xmlChar *elem = NULL;
6134
 
 
6135
 
    GROW;
6136
 
    if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
6137
 
        SKIP(7);
6138
 
        SKIP_BLANKS;
6139
 
        SHRINK;
6140
 
        if (RAW == ')') {
6141
 
            if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
6142
 
                xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
6143
 
"Element content declaration doesn't start and stop in the same entity\n",
6144
 
                                 NULL, NULL);
6145
 
            }
6146
 
            NEXT;
6147
 
            ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA);
6148
 
            if (ret == NULL)
6149
 
                return(NULL);
6150
 
            if (RAW == '*') {
6151
 
                ret->ocur = XML_ELEMENT_CONTENT_MULT;
6152
 
                NEXT;
6153
 
            }
6154
 
            return(ret);
6155
 
        }
6156
 
        if ((RAW == '(') || (RAW == '|')) {
6157
 
            ret = cur = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA);
6158
 
            if (ret == NULL) return(NULL);
6159
 
        }
6160
 
        while ((RAW == '|') && (ctxt->instate != XML_PARSER_EOF)) {
6161
 
            NEXT;
6162
 
            if (elem == NULL) {
6163
 
                ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
6164
 
                if (ret == NULL) return(NULL);
6165
 
                ret->c1 = cur;
6166
 
                if (cur != NULL)
6167
 
                    cur->parent = ret;
6168
 
                cur = ret;
6169
 
            } else {
6170
 
                n = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
6171
 
                if (n == NULL) return(NULL);
6172
 
                n->c1 = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
6173
 
                if (n->c1 != NULL)
6174
 
                    n->c1->parent = n;
6175
 
                cur->c2 = n;
6176
 
                if (n != NULL)
6177
 
                    n->parent = cur;
6178
 
                cur = n;
6179
 
            }
6180
 
            SKIP_BLANKS;
6181
 
            elem = xmlParseName(ctxt);
6182
 
            if (elem == NULL) {
6183
 
                xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
6184
 
                        "xmlParseElementMixedContentDecl : Name expected\n");
6185
 
                xmlFreeDocElementContent(ctxt->myDoc, cur);
6186
 
                return(NULL);
6187
 
            }
6188
 
            SKIP_BLANKS;
6189
 
            GROW;
6190
 
        }
6191
 
        if ((RAW == ')') && (NXT(1) == '*')) {
6192
 
            if (elem != NULL) {
6193
 
                cur->c2 = xmlNewDocElementContent(ctxt->myDoc, elem,
6194
 
                                               XML_ELEMENT_CONTENT_ELEMENT);
6195
 
                if (cur->c2 != NULL)
6196
 
                    cur->c2->parent = cur;
6197
 
            }
6198
 
            if (ret != NULL)
6199
 
                ret->ocur = XML_ELEMENT_CONTENT_MULT;
6200
 
            if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
6201
 
                xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
6202
 
"Element content declaration doesn't start and stop in the same entity\n",
6203
 
                                 NULL, NULL);
6204
 
            }
6205
 
            SKIP(2);
6206
 
        } else {
6207
 
            xmlFreeDocElementContent(ctxt->myDoc, ret);
6208
 
            xmlFatalErr(ctxt, XML_ERR_MIXED_NOT_STARTED, NULL);
6209
 
            return(NULL);
6210
 
        }
6211
 
 
6212
 
    } else {
6213
 
        xmlFatalErr(ctxt, XML_ERR_PCDATA_REQUIRED, NULL);
6214
 
    }
6215
 
    return(ret);
6216
 
}
6217
 
 
6218
 
/**
6219
 
 * xmlParseElementChildrenContentDeclPriv:
6220
 
 * @ctxt:  an XML parser context
6221
 
 * @inputchk:  the input used for the current entity, needed for boundary checks
6222
 
 * @depth: the level of recursion
6223
 
 *
6224
 
 * parse the declaration for a Mixed Element content
6225
 
 * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
6226
 
 *
6227
 
 *
6228
 
 * [47] children ::= (choice | seq) ('?' | '*' | '+')?
6229
 
 *
6230
 
 * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
6231
 
 *
6232
 
 * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
6233
 
 *
6234
 
 * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
6235
 
 *
6236
 
 * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
6237
 
 * TODO Parameter-entity replacement text must be properly nested
6238
 
 *      with parenthesized groups. That is to say, if either of the
6239
 
 *      opening or closing parentheses in a choice, seq, or Mixed
6240
 
 *      construct is contained in the replacement text for a parameter
6241
 
 *      entity, both must be contained in the same replacement text. For
6242
 
 *      interoperability, if a parameter-entity reference appears in a
6243
 
 *      choice, seq, or Mixed construct, its replacement text should not
6244
 
 *      be empty, and neither the first nor last non-blank character of
6245
 
 *      the replacement text should be a connector (| or ,).
6246
 
 *
6247
 
 * Returns the tree of xmlElementContentPtr describing the element
6248
 
 *          hierarchy.
6249
 
 */
6250
 
static xmlElementContentPtr
6251
 
xmlParseElementChildrenContentDeclPriv(xmlParserCtxtPtr ctxt, int inputchk,
6252
 
                                       int depth) {
6253
 
    xmlElementContentPtr ret = NULL, cur = NULL, last = NULL, op = NULL;
6254
 
    const xmlChar *elem;
6255
 
    xmlChar type = 0;
6256
 
 
6257
 
    if (((depth > 128) && ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
6258
 
        (depth >  2048)) {
6259
 
        xmlFatalErrMsgInt(ctxt, XML_ERR_ELEMCONTENT_NOT_FINISHED,
6260
 
"xmlParseElementChildrenContentDecl : depth %d too deep, use XML_PARSE_HUGE\n",
6261
 
                          depth);
6262
 
        return(NULL);
6263
 
    }
6264
 
    SKIP_BLANKS;
6265
 
    GROW;
6266
 
    if (RAW == '(') {
6267
 
        int inputid = ctxt->input->id;
6268
 
 
6269
 
        /* Recurse on first child */
6270
 
        NEXT;
6271
 
        SKIP_BLANKS;
6272
 
        cur = ret = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
6273
 
                                                           depth + 1);
6274
 
        SKIP_BLANKS;
6275
 
        GROW;
6276
 
    } else {
6277
 
        elem = xmlParseName(ctxt);
6278
 
        if (elem == NULL) {
6279
 
            xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
6280
 
            return(NULL);
6281
 
        }
6282
 
        cur = ret = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
6283
 
        if (cur == NULL) {
6284
 
            xmlErrMemory(ctxt, NULL);
6285
 
            return(NULL);
6286
 
        }
6287
 
        GROW;
6288
 
        if (RAW == '?') {
6289
 
            cur->ocur = XML_ELEMENT_CONTENT_OPT;
6290
 
            NEXT;
6291
 
        } else if (RAW == '*') {
6292
 
            cur->ocur = XML_ELEMENT_CONTENT_MULT;
6293
 
            NEXT;
6294
 
        } else if (RAW == '+') {
6295
 
            cur->ocur = XML_ELEMENT_CONTENT_PLUS;
6296
 
            NEXT;
6297
 
        } else {
6298
 
            cur->ocur = XML_ELEMENT_CONTENT_ONCE;
6299
 
        }
6300
 
        GROW;
6301
 
    }
6302
 
    SKIP_BLANKS;
6303
 
    SHRINK;
6304
 
    while ((RAW != ')') && (ctxt->instate != XML_PARSER_EOF)) {
6305
 
        /*
6306
 
         * Each loop we parse one separator and one element.
6307
 
         */
6308
 
        if (RAW == ',') {
6309
 
            if (type == 0) type = CUR;
6310
 
 
6311
 
            /*
6312
 
             * Detect "Name | Name , Name" error
6313
 
             */
6314
 
            else if (type != CUR) {
6315
 
                xmlFatalErrMsgInt(ctxt, XML_ERR_SEPARATOR_REQUIRED,
6316
 
                    "xmlParseElementChildrenContentDecl : '%c' expected\n",
6317
 
                                  type);
6318
 
                if ((last != NULL) && (last != ret))
6319
 
                    xmlFreeDocElementContent(ctxt->myDoc, last);
6320
 
                if (ret != NULL)
6321
 
                    xmlFreeDocElementContent(ctxt->myDoc, ret);
6322
 
                return(NULL);
6323
 
            }
6324
 
            NEXT;
6325
 
 
6326
 
            op = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_SEQ);
6327
 
            if (op == NULL) {
6328
 
                if ((last != NULL) && (last != ret))
6329
 
                    xmlFreeDocElementContent(ctxt->myDoc, last);
6330
 
                xmlFreeDocElementContent(ctxt->myDoc, ret);
6331
 
                return(NULL);
6332
 
            }
6333
 
            if (last == NULL) {
6334
 
                op->c1 = ret;
6335
 
                if (ret != NULL)
6336
 
                    ret->parent = op;
6337
 
                ret = cur = op;
6338
 
            } else {
6339
 
                cur->c2 = op;
6340
 
                if (op != NULL)
6341
 
                    op->parent = cur;
6342
 
                op->c1 = last;
6343
 
                if (last != NULL)
6344
 
                    last->parent = op;
6345
 
                cur =op;
6346
 
                last = NULL;
6347
 
            }
6348
 
        } else if (RAW == '|') {
6349
 
            if (type == 0) type = CUR;
6350
 
 
6351
 
            /*
6352
 
             * Detect "Name , Name | Name" error
6353
 
             */
6354
 
            else if (type != CUR) {
6355
 
                xmlFatalErrMsgInt(ctxt, XML_ERR_SEPARATOR_REQUIRED,
6356
 
                    "xmlParseElementChildrenContentDecl : '%c' expected\n",
6357
 
                                  type);
6358
 
                if ((last != NULL) && (last != ret))
6359
 
                    xmlFreeDocElementContent(ctxt->myDoc, last);
6360
 
                if (ret != NULL)
6361
 
                    xmlFreeDocElementContent(ctxt->myDoc, ret);
6362
 
                return(NULL);
6363
 
            }
6364
 
            NEXT;
6365
 
 
6366
 
            op = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
6367
 
            if (op == NULL) {
6368
 
                if ((last != NULL) && (last != ret))
6369
 
                    xmlFreeDocElementContent(ctxt->myDoc, last);
6370
 
                if (ret != NULL)
6371
 
                    xmlFreeDocElementContent(ctxt->myDoc, ret);
6372
 
                return(NULL);
6373
 
            }
6374
 
            if (last == NULL) {
6375
 
                op->c1 = ret;
6376
 
                if (ret != NULL)
6377
 
                    ret->parent = op;
6378
 
                ret = cur = op;
6379
 
            } else {
6380
 
                cur->c2 = op;
6381
 
                if (op != NULL)
6382
 
                    op->parent = cur;
6383
 
                op->c1 = last;
6384
 
                if (last != NULL)
6385
 
                    last->parent = op;
6386
 
                cur =op;
6387
 
                last = NULL;
6388
 
            }
6389
 
        } else {
6390
 
            xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_FINISHED, NULL);
6391
 
            if ((last != NULL) && (last != ret))
6392
 
                xmlFreeDocElementContent(ctxt->myDoc, last);
6393
 
            if (ret != NULL)
6394
 
                xmlFreeDocElementContent(ctxt->myDoc, ret);
6395
 
            return(NULL);
6396
 
        }
6397
 
        GROW;
6398
 
        SKIP_BLANKS;
6399
 
        GROW;
6400
 
        if (RAW == '(') {
6401
 
            int inputid = ctxt->input->id;
6402
 
            /* Recurse on second child */
6403
 
            NEXT;
6404
 
            SKIP_BLANKS;
6405
 
            last = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
6406
 
                                                          depth + 1);
6407
 
            SKIP_BLANKS;
6408
 
        } else {
6409
 
            elem = xmlParseName(ctxt);
6410
 
            if (elem == NULL) {
6411
 
                xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
6412
 
                if (ret != NULL)
6413
 
                    xmlFreeDocElementContent(ctxt->myDoc, ret);
6414
 
                return(NULL);
6415
 
            }
6416
 
            last = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
6417
 
            if (last == NULL) {
6418
 
                if (ret != NULL)
6419
 
                    xmlFreeDocElementContent(ctxt->myDoc, ret);
6420
 
                return(NULL);
6421
 
            }
6422
 
            if (RAW == '?') {
6423
 
                last->ocur = XML_ELEMENT_CONTENT_OPT;
6424
 
                NEXT;
6425
 
            } else if (RAW == '*') {
6426
 
                last->ocur = XML_ELEMENT_CONTENT_MULT;
6427
 
                NEXT;
6428
 
            } else if (RAW == '+') {
6429
 
                last->ocur = XML_ELEMENT_CONTENT_PLUS;
6430
 
                NEXT;
6431
 
            } else {
6432
 
                last->ocur = XML_ELEMENT_CONTENT_ONCE;
6433
 
            }
6434
 
        }
6435
 
        SKIP_BLANKS;
6436
 
        GROW;
6437
 
    }
6438
 
    if ((cur != NULL) && (last != NULL)) {
6439
 
        cur->c2 = last;
6440
 
        if (last != NULL)
6441
 
            last->parent = cur;
6442
 
    }
6443
 
    if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
6444
 
        xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
6445
 
"Element content declaration doesn't start and stop in the same entity\n",
6446
 
                         NULL, NULL);
6447
 
    }
6448
 
    NEXT;
6449
 
    if (RAW == '?') {
6450
 
        if (ret != NULL) {
6451
 
            if ((ret->ocur == XML_ELEMENT_CONTENT_PLUS) ||
6452
 
                (ret->ocur == XML_ELEMENT_CONTENT_MULT))
6453
 
                ret->ocur = XML_ELEMENT_CONTENT_MULT;
6454
 
            else
6455
 
                ret->ocur = XML_ELEMENT_CONTENT_OPT;
6456
 
        }
6457
 
        NEXT;
6458
 
    } else if (RAW == '*') {
6459
 
        if (ret != NULL) {
6460
 
            ret->ocur = XML_ELEMENT_CONTENT_MULT;
6461
 
            cur = ret;
6462
 
            /*
6463
 
             * Some normalization:
6464
 
             * (a | b* | c?)* == (a | b | c)*
6465
 
             */
6466
 
            while ((cur != NULL) && (cur->type == XML_ELEMENT_CONTENT_OR)) {
6467
 
                if ((cur->c1 != NULL) &&
6468
 
                    ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
6469
 
                     (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT)))
6470
 
                    cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
6471
 
                if ((cur->c2 != NULL) &&
6472
 
                    ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
6473
 
                     (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT)))
6474
 
                    cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
6475
 
                cur = cur->c2;
6476
 
            }
6477
 
        }
6478
 
        NEXT;
6479
 
    } else if (RAW == '+') {
6480
 
        if (ret != NULL) {
6481
 
            int found = 0;
6482
 
 
6483
 
            if ((ret->ocur == XML_ELEMENT_CONTENT_OPT) ||
6484
 
                (ret->ocur == XML_ELEMENT_CONTENT_MULT))
6485
 
                ret->ocur = XML_ELEMENT_CONTENT_MULT;
6486
 
            else
6487
 
                ret->ocur = XML_ELEMENT_CONTENT_PLUS;
6488
 
            /*
6489
 
             * Some normalization:
6490
 
             * (a | b*)+ == (a | b)*
6491
 
             * (a | b?)+ == (a | b)*
6492
 
             */
6493
 
            while ((cur != NULL) && (cur->type == XML_ELEMENT_CONTENT_OR)) {
6494
 
                if ((cur->c1 != NULL) &&
6495
 
                    ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
6496
 
                     (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT))) {
6497
 
                    cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
6498
 
                    found = 1;
6499
 
                }
6500
 
                if ((cur->c2 != NULL) &&
6501
 
                    ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
6502
 
                     (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT))) {
6503
 
                    cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
6504
 
                    found = 1;
6505
 
                }
6506
 
                cur = cur->c2;
6507
 
            }
6508
 
            if (found)
6509
 
                ret->ocur = XML_ELEMENT_CONTENT_MULT;
6510
 
        }
6511
 
        NEXT;
6512
 
    }
6513
 
    return(ret);
6514
 
}
6515
 
 
6516
 
/**
6517
 
 * xmlParseElementChildrenContentDecl:
6518
 
 * @ctxt:  an XML parser context
6519
 
 * @inputchk:  the input used for the current entity, needed for boundary checks
6520
 
 *
6521
 
 * parse the declaration for a Mixed Element content
6522
 
 * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
6523
 
 *
6524
 
 * [47] children ::= (choice | seq) ('?' | '*' | '+')?
6525
 
 *
6526
 
 * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
6527
 
 *
6528
 
 * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
6529
 
 *
6530
 
 * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
6531
 
 *
6532
 
 * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
6533
 
 * TODO Parameter-entity replacement text must be properly nested
6534
 
 *      with parenthesized groups. That is to say, if either of the
6535
 
 *      opening or closing parentheses in a choice, seq, or Mixed
6536
 
 *      construct is contained in the replacement text for a parameter
6537
 
 *      entity, both must be contained in the same replacement text. For
6538
 
 *      interoperability, if a parameter-entity reference appears in a
6539
 
 *      choice, seq, or Mixed construct, its replacement text should not
6540
 
 *      be empty, and neither the first nor last non-blank character of
6541
 
 *      the replacement text should be a connector (| or ,).
6542
 
 *
6543
 
 * Returns the tree of xmlElementContentPtr describing the element
6544
 
 *          hierarchy.
6545
 
 */
6546
 
xmlElementContentPtr
6547
 
xmlParseElementChildrenContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
6548
 
    /* stub left for API/ABI compat */
6549
 
    return(xmlParseElementChildrenContentDeclPriv(ctxt, inputchk, 1));
6550
 
}
6551
 
 
6552
 
/**
6553
 
 * xmlParseElementContentDecl:
6554
 
 * @ctxt:  an XML parser context
6555
 
 * @name:  the name of the element being defined.
6556
 
 * @result:  the Element Content pointer will be stored here if any
6557
 
 *
6558
 
 * parse the declaration for an Element content either Mixed or Children,
6559
 
 * the cases EMPTY and ANY are handled directly in xmlParseElementDecl
6560
 
 *
6561
 
 * [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
6562
 
 *
6563
 
 * returns: the type of element content XML_ELEMENT_TYPE_xxx
6564
 
 */
6565
 
 
6566
 
int
6567
 
xmlParseElementContentDecl(xmlParserCtxtPtr ctxt, const xmlChar *name,
6568
 
                           xmlElementContentPtr *result) {
6569
 
 
6570
 
    xmlElementContentPtr tree = NULL;
6571
 
    int inputid = ctxt->input->id;
6572
 
    int res;
6573
 
 
6574
 
    *result = NULL;
6575
 
 
6576
 
    if (RAW != '(') {
6577
 
        xmlFatalErrMsgStr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED,
6578
 
                "xmlParseElementContentDecl : %s '(' expected\n", name);
6579
 
        return(-1);
6580
 
    }
6581
 
    NEXT;
6582
 
    GROW;
6583
 
    if (ctxt->instate == XML_PARSER_EOF)
6584
 
        return(-1);
6585
 
    SKIP_BLANKS;
6586
 
    if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
6587
 
        tree = xmlParseElementMixedContentDecl(ctxt, inputid);
6588
 
        res = XML_ELEMENT_TYPE_MIXED;
6589
 
    } else {
6590
 
        tree = xmlParseElementChildrenContentDeclPriv(ctxt, inputid, 1);
6591
 
        res = XML_ELEMENT_TYPE_ELEMENT;
6592
 
    }
6593
 
    SKIP_BLANKS;
6594
 
    *result = tree;
6595
 
    return(res);
6596
 
}
6597
 
 
6598
 
/**
6599
 
 * xmlParseElementDecl:
6600
 
 * @ctxt:  an XML parser context
6601
 
 *
6602
 
 * parse an Element declaration.
6603
 
 *
6604
 
 * [45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
6605
 
 *
6606
 
 * [ VC: Unique Element Type Declaration ]
6607
 
 * No element type may be declared more than once
6608
 
 *
6609
 
 * Returns the type of the element, or -1 in case of error
6610
 
 */
6611
 
int
6612
 
xmlParseElementDecl(xmlParserCtxtPtr ctxt) {
6613
 
    const xmlChar *name;
6614
 
    int ret = -1;
6615
 
    xmlElementContentPtr content  = NULL;
6616
 
 
6617
 
    /* GROW; done in the caller */
6618
 
    if (CMP9(CUR_PTR, '<', '!', 'E', 'L', 'E', 'M', 'E', 'N', 'T')) {
6619
 
        xmlParserInputPtr input = ctxt->input;
6620
 
 
6621
 
        SKIP(9);
6622
 
        if (!IS_BLANK_CH(CUR)) {
6623
 
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6624
 
                           "Space required after 'ELEMENT'\n");
6625
 
        }
6626
 
        SKIP_BLANKS;
6627
 
        name = xmlParseName(ctxt);
6628
 
        if (name == NULL) {
6629
 
            xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
6630
 
                           "xmlParseElementDecl: no name for Element\n");
6631
 
            return(-1);
6632
 
        }
6633
 
        while ((RAW == 0) && (ctxt->inputNr > 1))
6634
 
            xmlPopInput(ctxt);
6635
 
        if (!IS_BLANK_CH(CUR)) {
6636
 
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6637
 
                           "Space required after the element name\n");
6638
 
        }
6639
 
        SKIP_BLANKS;
6640
 
        if (CMP5(CUR_PTR, 'E', 'M', 'P', 'T', 'Y')) {
6641
 
            SKIP(5);
6642
 
            /*
6643
 
             * Element must always be empty.
6644
 
             */
6645
 
            ret = XML_ELEMENT_TYPE_EMPTY;
6646
 
        } else if ((RAW == 'A') && (NXT(1) == 'N') &&
6647
 
                   (NXT(2) == 'Y')) {
6648
 
            SKIP(3);
6649
 
            /*
6650
 
             * Element is a generic container.
6651
 
             */
6652
 
            ret = XML_ELEMENT_TYPE_ANY;
6653
 
        } else if (RAW == '(') {
6654
 
            ret = xmlParseElementContentDecl(ctxt, name, &content);
6655
 
        } else {
6656
 
            /*
6657
 
             * [ WFC: PEs in Internal Subset ] error handling.
6658
 
             */
6659
 
            if ((RAW == '%') && (ctxt->external == 0) &&
6660
 
                (ctxt->inputNr == 1)) {
6661
 
                xmlFatalErrMsg(ctxt, XML_ERR_PEREF_IN_INT_SUBSET,
6662
 
          "PEReference: forbidden within markup decl in internal subset\n");
6663
 
            } else {
6664
 
                xmlFatalErrMsg(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED,
6665
 
                      "xmlParseElementDecl: 'EMPTY', 'ANY' or '(' expected\n");
6666
 
            }
6667
 
            return(-1);
6668
 
        }
6669
 
 
6670
 
        SKIP_BLANKS;
6671
 
        /*
6672
 
         * Pop-up of finished entities.
6673
 
         */
6674
 
        while ((RAW == 0) && (ctxt->inputNr > 1))
6675
 
            xmlPopInput(ctxt);
6676
 
        SKIP_BLANKS;
6677
 
 
6678
 
        if (RAW != '>') {
6679
 
            xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
6680
 
            if (content != NULL) {
6681
 
                xmlFreeDocElementContent(ctxt->myDoc, content);
6682
 
            }
6683
 
        } else {
6684
 
            if (input != ctxt->input) {
6685
 
                xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6686
 
    "Element declaration doesn't start and stop in the same entity\n");
6687
 
            }
6688
 
 
6689
 
            NEXT;
6690
 
            if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
6691
 
                (ctxt->sax->elementDecl != NULL)) {
6692
 
                if (content != NULL)
6693
 
                    content->parent = NULL;
6694
 
                ctxt->sax->elementDecl(ctxt->userData, name, ret,
6695
 
                                       content);
6696
 
                if ((content != NULL) && (content->parent == NULL)) {
6697
 
                    /*
6698
 
                     * this is a trick: if xmlAddElementDecl is called,
6699
 
                     * instead of copying the full tree it is plugged directly
6700
 
                     * if called from the parser. Avoid duplicating the
6701
 
                     * interfaces or change the API/ABI
6702
 
                     */
6703
 
                    xmlFreeDocElementContent(ctxt->myDoc, content);
6704
 
                }
6705
 
            } else if (content != NULL) {
6706
 
                xmlFreeDocElementContent(ctxt->myDoc, content);
6707
 
            }
6708
 
        }
6709
 
    }
6710
 
    return(ret);
6711
 
}
6712
 
 
6713
 
/**
6714
 
 * xmlParseConditionalSections
6715
 
 * @ctxt:  an XML parser context
6716
 
 *
6717
 
 * [61] conditionalSect ::= includeSect | ignoreSect
6718
 
 * [62] includeSect ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>'
6719
 
 * [63] ignoreSect ::= '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>'
6720
 
 * [64] ignoreSectContents ::= Ignore ('<![' ignoreSectContents ']]>' Ignore)*
6721
 
 * [65] Ignore ::= Char* - (Char* ('<![' | ']]>') Char*)
6722
 
 */
6723
 
 
6724
 
static void
6725
 
xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
6726
 
    int id = ctxt->input->id;
6727
 
 
6728
 
    SKIP(3);
6729
 
    SKIP_BLANKS;
6730
 
    if (CMP7(CUR_PTR, 'I', 'N', 'C', 'L', 'U', 'D', 'E')) {
6731
 
        SKIP(7);
6732
 
        SKIP_BLANKS;
6733
 
        if (RAW != '[') {
6734
 
            xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
6735
 
        } else {
6736
 
            if (ctxt->input->id != id) {
6737
 
                xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
6738
 
            "All markup of the conditional section is not in the same entity\n",
6739
 
                                     NULL, NULL);
6740
 
            }
6741
 
            NEXT;
6742
 
        }
6743
 
        if (xmlParserDebugEntities) {
6744
 
            if ((ctxt->input != NULL) && (ctxt->input->filename))
6745
 
                xmlGenericError(xmlGenericErrorContext,
6746
 
                        "%s(%d): ", ctxt->input->filename,
6747
 
                        ctxt->input->line);
6748
 
            xmlGenericError(xmlGenericErrorContext,
6749
 
                    "Entering INCLUDE Conditional Section\n");
6750
 
        }
6751
 
 
6752
 
        while (((RAW != 0) && ((RAW != ']') || (NXT(1) != ']') ||
6753
 
                (NXT(2) != '>'))) && (ctxt->instate != XML_PARSER_EOF)) {
6754
 
            const xmlChar *check = CUR_PTR;
6755
 
            unsigned int cons = ctxt->input->consumed;
6756
 
 
6757
 
            if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
6758
 
                xmlParseConditionalSections(ctxt);
6759
 
            } else if (IS_BLANK_CH(CUR)) {
6760
 
                NEXT;
6761
 
            } else if (RAW == '%') {
6762
 
                xmlParsePEReference(ctxt);
6763
 
            } else
6764
 
                xmlParseMarkupDecl(ctxt);
6765
 
 
6766
 
            /*
6767
 
             * Pop-up of finished entities.
6768
 
             */
6769
 
            while ((RAW == 0) && (ctxt->inputNr > 1))
6770
 
                xmlPopInput(ctxt);
6771
 
 
6772
 
            if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
6773
 
                xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
6774
 
                break;
6775
 
            }
6776
 
        }
6777
 
        if (xmlParserDebugEntities) {
6778
 
            if ((ctxt->input != NULL) && (ctxt->input->filename))
6779
 
                xmlGenericError(xmlGenericErrorContext,
6780
 
                        "%s(%d): ", ctxt->input->filename,
6781
 
                        ctxt->input->line);
6782
 
            xmlGenericError(xmlGenericErrorContext,
6783
 
                    "Leaving INCLUDE Conditional Section\n");
6784
 
        }
6785
 
 
6786
 
    } else if (CMP6(CUR_PTR, 'I', 'G', 'N', 'O', 'R', 'E')) {
6787
 
        int state;
6788
 
        xmlParserInputState instate;
6789
 
        int depth = 0;
6790
 
 
6791
 
        SKIP(6);
6792
 
        SKIP_BLANKS;
6793
 
        if (RAW != '[') {
6794
 
            xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
6795
 
        } else {
6796
 
            if (ctxt->input->id != id) {
6797
 
                xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
6798
 
            "All markup of the conditional section is not in the same entity\n",
6799
 
                                     NULL, NULL);
6800
 
            }
6801
 
            NEXT;
6802
 
        }
6803
 
        if (xmlParserDebugEntities) {
6804
 
            if ((ctxt->input != NULL) && (ctxt->input->filename))
6805
 
                xmlGenericError(xmlGenericErrorContext,
6806
 
                        "%s(%d): ", ctxt->input->filename,
6807
 
                        ctxt->input->line);
6808
 
            xmlGenericError(xmlGenericErrorContext,
6809
 
                    "Entering IGNORE Conditional Section\n");
6810
 
        }
6811
 
 
6812
 
        /*
6813
 
         * Parse up to the end of the conditional section
6814
 
         * But disable SAX event generating DTD building in the meantime
6815
 
         */
6816
 
        state = ctxt->disableSAX;
6817
 
        instate = ctxt->instate;
6818
 
        if (ctxt->recovery == 0) ctxt->disableSAX = 1;
6819
 
        ctxt->instate = XML_PARSER_IGNORE;
6820
 
 
6821
 
        while (((depth >= 0) && (RAW != 0)) &&
6822
 
               (ctxt->instate != XML_PARSER_EOF)) {
6823
 
          if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
6824
 
            depth++;
6825
 
            SKIP(3);
6826
 
            continue;
6827
 
          }
6828
 
          if ((RAW == ']') && (NXT(1) == ']') && (NXT(2) == '>')) {
6829
 
            if (--depth >= 0) SKIP(3);
6830
 
            continue;
6831
 
          }
6832
 
          NEXT;
6833
 
          continue;
6834
 
        }
6835
 
 
6836
 
        ctxt->disableSAX = state;
6837
 
        ctxt->instate = instate;
6838
 
 
6839
 
        if (xmlParserDebugEntities) {
6840
 
            if ((ctxt->input != NULL) && (ctxt->input->filename))
6841
 
                xmlGenericError(xmlGenericErrorContext,
6842
 
                        "%s(%d): ", ctxt->input->filename,
6843
 
                        ctxt->input->line);
6844
 
            xmlGenericError(xmlGenericErrorContext,
6845
 
                    "Leaving IGNORE Conditional Section\n");
6846
 
        }
6847
 
 
6848
 
    } else {
6849
 
        xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID_KEYWORD, NULL);
6850
 
    }
6851
 
 
6852
 
    if (RAW == 0)
6853
 
        SHRINK;
6854
 
 
6855
 
    if (RAW == 0) {
6856
 
        xmlFatalErr(ctxt, XML_ERR_CONDSEC_NOT_FINISHED, NULL);
6857
 
    } else {
6858
 
        if (ctxt->input->id != id) {
6859
 
            xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
6860
 
        "All markup of the conditional section is not in the same entity\n",
6861
 
                                 NULL, NULL);
6862
 
        }
6863
 
        SKIP(3);
6864
 
    }
6865
 
}
6866
 
 
6867
 
/**
6868
 
 * xmlParseMarkupDecl:
6869
 
 * @ctxt:  an XML parser context
6870
 
 *
6871
 
 * parse Markup declarations
6872
 
 *
6873
 
 * [29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl |
6874
 
 *                     NotationDecl | PI | Comment
6875
 
 *
6876
 
 * [ VC: Proper Declaration/PE Nesting ]
6877
 
 * Parameter-entity replacement text must be properly nested with
6878
 
 * markup declarations. That is to say, if either the first character
6879
 
 * or the last character of a markup declaration (markupdecl above) is
6880
 
 * contained in the replacement text for a parameter-entity reference,
6881
 
 * both must be contained in the same replacement text.
6882
 
 *
6883
 
 * [ WFC: PEs in Internal Subset ]
6884
 
 * In the internal DTD subset, parameter-entity references can occur
6885
 
 * only where markup declarations can occur, not within markup declarations.
6886
 
 * (This does not apply to references that occur in external parameter
6887
 
 * entities or to the external subset.)
6888
 
 */
6889
 
void
6890
 
xmlParseMarkupDecl(xmlParserCtxtPtr ctxt) {
6891
 
    GROW;
6892
 
    if (CUR == '<') {
6893
 
        if (NXT(1) == '!') {
6894
 
            switch (NXT(2)) {
6895
 
                case 'E':
6896
 
                    if (NXT(3) == 'L')
6897
 
                        xmlParseElementDecl(ctxt);
6898
 
                    else if (NXT(3) == 'N')
6899
 
                        xmlParseEntityDecl(ctxt);
6900
 
                    break;
6901
 
                case 'A':
6902
 
                    xmlParseAttributeListDecl(ctxt);
6903
 
                    break;
6904
 
                case 'N':
6905
 
                    xmlParseNotationDecl(ctxt);
6906
 
                    break;
6907
 
                case '-':
6908
 
                    xmlParseComment(ctxt);
6909
 
                    break;
6910
 
                default:
6911
 
                    /* there is an error but it will be detected later */
6912
 
                    break;
6913
 
            }
6914
 
        } else if (NXT(1) == '?') {
6915
 
            xmlParsePI(ctxt);
6916
 
        }
6917
 
    }
6918
 
    /*
6919
 
     * This is only for internal subset. On external entities,
6920
 
     * the replacement is done before parsing stage
6921
 
     */
6922
 
    if ((ctxt->external == 0) && (ctxt->inputNr == 1))
6923
 
        xmlParsePEReference(ctxt);
6924
 
 
6925
 
    /*
6926
 
     * Conditional sections are allowed from entities included
6927
 
     * by PE References in the internal subset.
6928
 
     */
6929
 
    if ((ctxt->external == 0) && (ctxt->inputNr > 1)) {
6930
 
        if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
6931
 
            xmlParseConditionalSections(ctxt);
6932
 
        }
6933
 
    }
6934
 
 
6935
 
    ctxt->instate = XML_PARSER_DTD;
6936
 
}
6937
 
 
6938
 
/**
6939
 
 * xmlParseTextDecl:
6940
 
 * @ctxt:  an XML parser context
6941
 
 *
6942
 
 * parse an XML declaration header for external entities
6943
 
 *
6944
 
 * [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
6945
 
 */
6946
 
 
6947
 
void
6948
 
xmlParseTextDecl(xmlParserCtxtPtr ctxt) {
6949
 
    xmlChar *version;
6950
 
    const xmlChar *encoding;
6951
 
 
6952
 
    /*
6953
 
     * We know that '<?xml' is here.
6954
 
     */
6955
 
    if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
6956
 
        SKIP(5);
6957
 
    } else {
6958
 
        xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_STARTED, NULL);
6959
 
        return;
6960
 
    }
6961
 
 
6962
 
    if (!IS_BLANK_CH(CUR)) {
6963
 
        xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6964
 
                       "Space needed after '<?xml'\n");
6965
 
    }
6966
 
    SKIP_BLANKS;
6967
 
 
6968
 
    /*
6969
 
     * We may have the VersionInfo here.
6970
 
     */
6971
 
    version = xmlParseVersionInfo(ctxt);
6972
 
    if (version == NULL)
6973
 
        version = xmlCharStrdup(XML_DEFAULT_VERSION);
6974
 
    else {
6975
 
        if (!IS_BLANK_CH(CUR)) {
6976
 
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6977
 
                           "Space needed here\n");
6978
 
        }
6979
 
    }
6980
 
    ctxt->input->version = version;
6981
 
 
6982
 
    /*
6983
 
     * We must have the encoding declaration
6984
 
     */
6985
 
    encoding = xmlParseEncodingDecl(ctxt);
6986
 
    if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
6987
 
        /*
6988
 
         * The XML REC instructs us to stop parsing right here
6989
 
         */
6990
 
        return;
6991
 
    }
6992
 
    if ((encoding == NULL) && (ctxt->errNo == XML_ERR_OK)) {
6993
 
        xmlFatalErrMsg(ctxt, XML_ERR_MISSING_ENCODING,
6994
 
                       "Missing encoding in text declaration\n");
6995
 
    }
6996
 
 
6997
 
    SKIP_BLANKS;
6998
 
    if ((RAW == '?') && (NXT(1) == '>')) {
6999
 
        SKIP(2);
7000
 
    } else if (RAW == '>') {
7001
 
        /* Deprecated old WD ... */
7002
 
        xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
7003
 
        NEXT;
7004
 
    } else {
7005
 
        xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
7006
 
        MOVETO_ENDTAG(CUR_PTR);
7007
 
        NEXT;
7008
 
    }
7009
 
}
7010
 
 
7011
 
/**
7012
 
 * xmlParseExternalSubset:
7013
 
 * @ctxt:  an XML parser context
7014
 
 * @ExternalID: the external identifier
7015
 
 * @SystemID: the system identifier (or URL)
7016
 
 *
7017
 
 * parse Markup declarations from an external subset
7018
 
 *
7019
 
 * [30] extSubset ::= textDecl? extSubsetDecl
7020
 
 *
7021
 
 * [31] extSubsetDecl ::= (markupdecl | conditionalSect | PEReference | S) *
7022
 
 */
7023
 
void
7024
 
xmlParseExternalSubset(xmlParserCtxtPtr ctxt, const xmlChar *ExternalID,
7025
 
                       const xmlChar *SystemID) {
7026
 
    xmlDetectSAX2(ctxt);
7027
 
    GROW;
7028
 
 
7029
 
    if ((ctxt->encoding == NULL) &&
7030
 
        (ctxt->input->end - ctxt->input->cur >= 4)) {
7031
 
        xmlChar start[4];
7032
 
        xmlCharEncoding enc;
7033
 
 
7034
 
        start[0] = RAW;
7035
 
        start[1] = NXT(1);
7036
 
        start[2] = NXT(2);
7037
 
        start[3] = NXT(3);
7038
 
        enc = xmlDetectCharEncoding(start, 4);
7039
 
        if (enc != XML_CHAR_ENCODING_NONE)
7040
 
            xmlSwitchEncoding(ctxt, enc);
7041
 
    }
7042
 
 
7043
 
    if (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) {
7044
 
        xmlParseTextDecl(ctxt);
7045
 
        if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
7046
 
            /*
7047
 
             * The XML REC instructs us to stop parsing right here
7048
 
             */
7049
 
            ctxt->instate = XML_PARSER_EOF;
7050
 
            return;
7051
 
        }
7052
 
    }
7053
 
    if (ctxt->myDoc == NULL) {
7054
 
        ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
7055
 
        if (ctxt->myDoc == NULL) {
7056
 
            xmlErrMemory(ctxt, "New Doc failed");
7057
 
            return;
7058
 
        }
7059
 
        ctxt->myDoc->properties = XML_DOC_INTERNAL;
7060
 
    }
7061
 
    if ((ctxt->myDoc != NULL) && (ctxt->myDoc->intSubset == NULL))
7062
 
        xmlCreateIntSubset(ctxt->myDoc, NULL, ExternalID, SystemID);
7063
 
 
7064
 
    ctxt->instate = XML_PARSER_DTD;
7065
 
    ctxt->external = 1;
7066
 
    while (((RAW == '<') && (NXT(1) == '?')) ||
7067
 
           ((RAW == '<') && (NXT(1) == '!')) ||
7068
 
           (RAW == '%') || IS_BLANK_CH(CUR)) {
7069
 
        const xmlChar *check = CUR_PTR;
7070
 
        unsigned int cons = ctxt->input->consumed;
7071
 
 
7072
 
        GROW;
7073
 
        if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
7074
 
            xmlParseConditionalSections(ctxt);
7075
 
        } else if (IS_BLANK_CH(CUR)) {
7076
 
            NEXT;
7077
 
        } else if (RAW == '%') {
7078
 
            xmlParsePEReference(ctxt);
7079
 
        } else
7080
 
            xmlParseMarkupDecl(ctxt);
7081
 
 
7082
 
        /*
7083
 
         * Pop-up of finished entities.
7084
 
         */
7085
 
        while ((RAW == 0) && (ctxt->inputNr > 1))
7086
 
            xmlPopInput(ctxt);
7087
 
 
7088
 
        if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
7089
 
            xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
7090
 
            break;
7091
 
        }
7092
 
    }
7093
 
 
7094
 
    if (RAW != 0) {
7095
 
        xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
7096
 
    }
7097
 
 
7098
 
}
7099
 
 
7100
 
/**
7101
 
 * xmlParseReference:
7102
 
 * @ctxt:  an XML parser context
7103
 
 *
7104
 
 * parse and handle entity references in content, depending on the SAX
7105
 
 * interface, this may end-up in a call to character() if this is a
7106
 
 * CharRef, a predefined entity, if there is no reference() callback.
7107
 
 * or if the parser was asked to switch to that mode.
7108
 
 *
7109
 
 * [67] Reference ::= EntityRef | CharRef
7110
 
 */
7111
 
void
7112
 
xmlParseReference(xmlParserCtxtPtr ctxt) {
7113
 
    xmlEntityPtr ent;
7114
 
    xmlChar *val;
7115
 
    int was_checked;
7116
 
    xmlNodePtr list = NULL;
7117
 
    xmlParserErrors ret = XML_ERR_OK;
7118
 
 
7119
 
 
7120
 
    if (RAW != '&')
7121
 
        return;
7122
 
 
7123
 
    /*
7124
 
     * Simple case of a CharRef
7125
 
     */
7126
 
    if (NXT(1) == '#') {
7127
 
        int i = 0;
7128
 
        xmlChar out[10];
7129
 
        int hex = NXT(2);
7130
 
        int value = xmlParseCharRef(ctxt);
7131
 
 
7132
 
        if (value == 0)
7133
 
            return;
7134
 
        if (ctxt->charset != XML_CHAR_ENCODING_UTF8) {
7135
 
            /*
7136
 
             * So we are using non-UTF-8 buffers
7137
 
             * Check that the char fit on 8bits, if not
7138
 
             * generate a CharRef.
7139
 
             */
7140
 
            if (value <= 0xFF) {
7141
 
                out[0] = value;
7142
 
                out[1] = 0;
7143
 
                if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
7144
 
                    (!ctxt->disableSAX))
7145
 
                    ctxt->sax->characters(ctxt->userData, out, 1);
7146
 
            } else {
7147
 
                if ((hex == 'x') || (hex == 'X'))
7148
 
                    snprintf((char *)out, sizeof(out), "#x%X", value);
7149
 
                else
7150
 
                    snprintf((char *)out, sizeof(out), "#%d", value);
7151
 
                if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
7152
 
                    (!ctxt->disableSAX))
7153
 
                    ctxt->sax->reference(ctxt->userData, out);
7154
 
            }
7155
 
        } else {
7156
 
            /*
7157
 
             * Just encode the value in UTF-8
7158
 
             */
7159
 
            COPY_BUF(0 ,out, i, value);
7160
 
            out[i] = 0;
7161
 
            if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
7162
 
                (!ctxt->disableSAX))
7163
 
                ctxt->sax->characters(ctxt->userData, out, i);
7164
 
        }
7165
 
        return;
7166
 
    }
7167
 
 
7168
 
    /*
7169
 
     * We are seeing an entity reference
7170
 
     */
7171
 
    ent = xmlParseEntityRef(ctxt);
7172
 
    if (ent == NULL) return;
7173
 
    if (!ctxt->wellFormed)
7174
 
        return;
7175
 
    was_checked = ent->checked;
7176
 
 
7177
 
    /* special case of predefined entities */
7178
 
    if ((ent->name == NULL) ||
7179
 
        (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
7180
 
        val = ent->content;
7181
 
        if (val == NULL) return;
7182
 
        /*
7183
 
         * inline the entity.
7184
 
         */
7185
 
        if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
7186
 
            (!ctxt->disableSAX))
7187
 
            ctxt->sax->characters(ctxt->userData, val, xmlStrlen(val));
7188
 
        return;
7189
 
    }
7190
 
 
7191
 
    /*
7192
 
     * The first reference to the entity trigger a parsing phase
7193
 
     * where the ent->children is filled with the result from
7194
 
     * the parsing.
7195
 
     * Note: external parsed entities will not be loaded, it is not
7196
 
     * required for a non-validating parser, unless the parsing option
7197
 
     * of validating, or substituting entities were given. Doing so is
7198
 
     * far more secure as the parser will only process data coming from
7199
 
     * the document entity by default.
7200
 
     */
7201
 
    if ((ent->checked == 0) &&
7202
 
        ((ent->etype != XML_EXTERNAL_GENERAL_PARSED_ENTITY) ||
7203
 
         (ctxt->options & (XML_PARSE_NOENT | XML_PARSE_DTDVALID)))) {
7204
 
        unsigned long oldnbent = ctxt->nbentities;
7205
 
 
7206
 
        /*
7207
 
         * This is a bit hackish but this seems the best
7208
 
         * way to make sure both SAX and DOM entity support
7209
 
         * behaves okay.
7210
 
         */
7211
 
        void *user_data;
7212
 
        if (ctxt->userData == ctxt)
7213
 
            user_data = NULL;
7214
 
        else
7215
 
            user_data = ctxt->userData;
7216
 
 
7217
 
        /*
7218
 
         * Check that this entity is well formed
7219
 
         * 4.3.2: An internal general parsed entity is well-formed
7220
 
         * if its replacement text matches the production labeled
7221
 
         * content.
7222
 
         */
7223
 
        if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
7224
 
            ctxt->depth++;
7225
 
            ret = xmlParseBalancedChunkMemoryInternal(ctxt, ent->content,
7226
 
                                                      user_data, &list);
7227
 
            ctxt->depth--;
7228
 
 
7229
 
        } else if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
7230
 
            ctxt->depth++;
7231
 
            ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt, ctxt->sax,
7232
 
                                           user_data, ctxt->depth, ent->URI,
7233
 
                                           ent->ExternalID, &list);
7234
 
            ctxt->depth--;
7235
 
        } else {
7236
 
            ret = XML_ERR_ENTITY_PE_INTERNAL;
7237
 
            xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
7238
 
                         "invalid entity type found\n", NULL);
7239
 
        }
7240
 
 
7241
 
        /*
7242
 
         * Store the number of entities needing parsing for this entity
7243
 
         * content and do checkings
7244
 
         */
7245
 
        ent->checked = (ctxt->nbentities - oldnbent + 1) * 2;
7246
 
        if ((ent->content != NULL) && (xmlStrchr(ent->content, '<')))
7247
 
            ent->checked |= 1;
7248
 
        if (ret == XML_ERR_ENTITY_LOOP) {
7249
 
            xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
7250
 
            xmlFreeNodeList(list);
7251
 
            return;
7252
 
        }
7253
 
        if (xmlParserEntityCheck(ctxt, 0, ent, 0)) {
7254
 
            xmlFreeNodeList(list);
7255
 
            return;
7256
 
        }
7257
 
 
7258
 
        if ((ret == XML_ERR_OK) && (list != NULL)) {
7259
 
            if (((ent->etype == XML_INTERNAL_GENERAL_ENTITY) ||
7260
 
             (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY))&&
7261
 
                (ent->children == NULL)) {
7262
 
                ent->children = list;
7263
 
                if (ctxt->replaceEntities) {
7264
 
                    /*
7265
 
                     * Prune it directly in the generated document
7266
 
                     * except for single text nodes.
7267
 
                     */
7268
 
                    if (((list->type == XML_TEXT_NODE) &&
7269
 
                         (list->next == NULL)) ||
7270
 
                        (ctxt->parseMode == XML_PARSE_READER)) {
7271
 
                        list->parent = (xmlNodePtr) ent;
7272
 
                        list = NULL;
7273
 
                        ent->owner = 1;
7274
 
                    } else {
7275
 
                        ent->owner = 0;
7276
 
                        while (list != NULL) {
7277
 
                            list->parent = (xmlNodePtr) ctxt->node;
7278
 
                            list->doc = ctxt->myDoc;
7279
 
                            if (list->next == NULL)
7280
 
                                ent->last = list;
7281
 
                            list = list->next;
7282
 
                        }
7283
 
                        list = ent->children;
7284
 
#ifdef LIBXML_LEGACY_ENABLED
7285
 
                        if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
7286
 
                          xmlAddEntityReference(ent, list, NULL);
7287
 
#endif /* LIBXML_LEGACY_ENABLED */
7288
 
                    }
7289
 
                } else {
7290
 
                    ent->owner = 1;
7291
 
                    while (list != NULL) {
7292
 
                        list->parent = (xmlNodePtr) ent;
7293
 
                        xmlSetTreeDoc(list, ent->doc);
7294
 
                        if (list->next == NULL)
7295
 
                            ent->last = list;
7296
 
                        list = list->next;
7297
 
                    }
7298
 
                }
7299
 
            } else {
7300
 
                xmlFreeNodeList(list);
7301
 
                list = NULL;
7302
 
            }
7303
 
        } else if ((ret != XML_ERR_OK) &&
7304
 
                   (ret != XML_WAR_UNDECLARED_ENTITY)) {
7305
 
            xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
7306
 
                     "Entity '%s' failed to parse\n", ent->name);
7307
 
        } else if (list != NULL) {
7308
 
            xmlFreeNodeList(list);
7309
 
            list = NULL;
7310
 
        }
7311
 
        if (ent->checked == 0)
7312
 
            ent->checked = 2;
7313
 
    } else if (ent->checked != 1) {
7314
 
        ctxt->nbentities += ent->checked / 2;
7315
 
    }
7316
 
 
7317
 
    /*
7318
 
     * Now that the entity content has been gathered
7319
 
     * provide it to the application, this can take different forms based
7320
 
     * on the parsing modes.
7321
 
     */
7322
 
    if (ent->children == NULL) {
7323
 
        /*
7324
 
         * Probably running in SAX mode and the callbacks don't
7325
 
         * build the entity content. So unless we already went
7326
 
         * though parsing for first checking go though the entity
7327
 
         * content to generate callbacks associated to the entity
7328
 
         */
7329
 
        if (was_checked != 0) {
7330
 
            void *user_data;
7331
 
            /*
7332
 
             * This is a bit hackish but this seems the best
7333
 
             * way to make sure both SAX and DOM entity support
7334
 
             * behaves okay.
7335
 
             */
7336
 
            if (ctxt->userData == ctxt)
7337
 
                user_data = NULL;
7338
 
            else
7339
 
                user_data = ctxt->userData;
7340
 
 
7341
 
            if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
7342
 
                ctxt->depth++;
7343
 
                ret = xmlParseBalancedChunkMemoryInternal(ctxt,
7344
 
                                   ent->content, user_data, NULL);
7345
 
                ctxt->depth--;
7346
 
            } else if (ent->etype ==
7347
 
                       XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
7348
 
                ctxt->depth++;
7349
 
                ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt,
7350
 
                           ctxt->sax, user_data, ctxt->depth,
7351
 
                           ent->URI, ent->ExternalID, NULL);
7352
 
                ctxt->depth--;
7353
 
            } else {
7354
 
                ret = XML_ERR_ENTITY_PE_INTERNAL;
7355
 
                xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
7356
 
                             "invalid entity type found\n", NULL);
7357
 
            }
7358
 
            if (ret == XML_ERR_ENTITY_LOOP) {
7359
 
                xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
7360
 
                return;
7361
 
            }
7362
 
        }
7363
 
        if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
7364
 
            (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
7365
 
            /*
7366
 
             * Entity reference callback comes second, it's somewhat
7367
 
             * superfluous but a compatibility to historical behaviour
7368
 
             */
7369
 
            ctxt->sax->reference(ctxt->userData, ent->name);
7370
 
        }
7371
 
        return;
7372
 
    }
7373
 
 
7374
 
    /*
7375
 
     * If we didn't get any children for the entity being built
7376
 
     */
7377
 
    if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
7378
 
        (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
7379
 
        /*
7380
 
         * Create a node.
7381
 
         */
7382
 
        ctxt->sax->reference(ctxt->userData, ent->name);
7383
 
        return;
7384
 
    }
7385
 
 
7386
 
    if ((ctxt->replaceEntities) || (ent->children == NULL))  {
7387
 
        /*
7388
 
         * There is a problem on the handling of _private for entities
7389
 
         * (bug 155816): Should we copy the content of the field from
7390
 
         * the entity (possibly overwriting some value set by the user
7391
 
         * when a copy is created), should we leave it alone, or should
7392
 
         * we try to take care of different situations?  The problem
7393
 
         * is exacerbated by the usage of this field by the xmlReader.
7394
 
         * To fix this bug, we look at _private on the created node
7395
 
         * and, if it's NULL, we copy in whatever was in the entity.
7396
 
         * If it's not NULL we leave it alone.  This is somewhat of a
7397
 
         * hack - maybe we should have further tests to determine
7398
 
         * what to do.
7399
 
         */
7400
 
        if ((ctxt->node != NULL) && (ent->children != NULL)) {
7401
 
            /*
7402
 
             * Seems we are generating the DOM content, do
7403
 
             * a simple tree copy for all references except the first
7404
 
             * In the first occurrence list contains the replacement.
7405
 
             */
7406
 
            if (((list == NULL) && (ent->owner == 0)) ||
7407
 
                (ctxt->parseMode == XML_PARSE_READER)) {
7408
 
                xmlNodePtr nw = NULL, cur, firstChild = NULL;
7409
 
 
7410
 
                /*
7411
 
                 * We are copying here, make sure there is no abuse
7412
 
                 */
7413
 
                ctxt->sizeentcopy += ent->length;
7414
 
                if (xmlParserEntityCheck(ctxt, 0, ent, ctxt->sizeentcopy))
7415
 
                    return;
7416
 
 
7417
 
                /*
7418
 
                 * when operating on a reader, the entities definitions
7419
 
                 * are always owning the entities subtree.
7420
 
                if (ctxt->parseMode == XML_PARSE_READER)
7421
 
                    ent->owner = 1;
7422
 
                 */
7423
 
 
7424
 
                cur = ent->children;
7425
 
                while (cur != NULL) {
7426
 
                    nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
7427
 
                    if (nw != NULL) {
7428
 
                        if (nw->_private == NULL)
7429
 
                            nw->_private = cur->_private;
7430
 
                        if (firstChild == NULL){
7431
 
                            firstChild = nw;
7432
 
                        }
7433
 
                        nw = xmlAddChild(ctxt->node, nw);
7434
 
                    }
7435
 
                    if (cur == ent->last) {
7436
 
                        /*
7437
 
                         * needed to detect some strange empty
7438
 
                         * node cases in the reader tests
7439
 
                         */
7440
 
                        if ((ctxt->parseMode == XML_PARSE_READER) &&
7441
 
                            (nw != NULL) &&
7442
 
                            (nw->type == XML_ELEMENT_NODE) &&
7443
 
                            (nw->children == NULL))
7444
 
                            nw->extra = 1;
7445
 
 
7446
 
                        break;
7447
 
                    }
7448
 
                    cur = cur->next;
7449
 
                }
7450
 
#ifdef LIBXML_LEGACY_ENABLED
7451
 
                if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
7452
 
                  xmlAddEntityReference(ent, firstChild, nw);
7453
 
#endif /* LIBXML_LEGACY_ENABLED */
7454
 
            } else if ((list == NULL) || (ctxt->inputNr > 0)) {
7455
 
                xmlNodePtr nw = NULL, cur, next, last,
7456
 
                           firstChild = NULL;
7457
 
 
7458
 
                /*
7459
 
                 * We are copying here, make sure there is no abuse
7460
 
                 */
7461
 
                ctxt->sizeentcopy += ent->length;
7462
 
                if (xmlParserEntityCheck(ctxt, 0, ent, ctxt->sizeentcopy))
7463
 
                    return;
7464
 
 
7465
 
                /*
7466
 
                 * Copy the entity child list and make it the new
7467
 
                 * entity child list. The goal is to make sure any
7468
 
                 * ID or REF referenced will be the one from the
7469
 
                 * document content and not the entity copy.
7470
 
                 */
7471
 
                cur = ent->children;
7472
 
                ent->children = NULL;
7473
 
                last = ent->last;
7474
 
                ent->last = NULL;
7475
 
                while (cur != NULL) {
7476
 
                    next = cur->next;
7477
 
                    cur->next = NULL;
7478
 
                    cur->parent = NULL;
7479
 
                    nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
7480
 
                    if (nw != NULL) {
7481
 
                        if (nw->_private == NULL)
7482
 
                            nw->_private = cur->_private;
7483
 
                        if (firstChild == NULL){
7484
 
                            firstChild = cur;
7485
 
                        }
7486
 
                        xmlAddChild((xmlNodePtr) ent, nw);
7487
 
                        xmlAddChild(ctxt->node, cur);
7488
 
                    }
7489
 
                    if (cur == last)
7490
 
                        break;
7491
 
                    cur = next;
7492
 
                }
7493
 
                if (ent->owner == 0)
7494
 
                    ent->owner = 1;
7495
 
#ifdef LIBXML_LEGACY_ENABLED
7496
 
                if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
7497
 
                  xmlAddEntityReference(ent, firstChild, nw);
7498
 
#endif /* LIBXML_LEGACY_ENABLED */
7499
 
            } else {
7500
 
                const xmlChar *nbktext;
7501
 
 
7502
 
                /*
7503
 
                 * the name change is to avoid coalescing of the
7504
 
                 * node with a possible previous text one which
7505
 
                 * would make ent->children a dangling pointer
7506
 
                 */
7507
 
                nbktext = xmlDictLookup(ctxt->dict, BAD_CAST "nbktext",
7508
 
                                        -1);
7509
 
                if (ent->children->type == XML_TEXT_NODE)
7510
 
                    ent->children->name = nbktext;
7511
 
                if ((ent->last != ent->children) &&
7512
 
                    (ent->last->type == XML_TEXT_NODE))
7513
 
                    ent->last->name = nbktext;
7514
 
                xmlAddChildList(ctxt->node, ent->children);
7515
 
            }
7516
 
 
7517
 
            /*
7518
 
             * This is to avoid a nasty side effect, see
7519
 
             * characters() in SAX.c
7520
 
             */
7521
 
            ctxt->nodemem = 0;
7522
 
            ctxt->nodelen = 0;
7523
 
            return;
7524
 
        }
7525
 
    }
7526
 
}
7527
 
 
7528
 
/**
7529
 
 * xmlParseEntityRef:
7530
 
 * @ctxt:  an XML parser context
7531
 
 *
7532
 
 * parse ENTITY references declarations
7533
 
 *
7534
 
 * [68] EntityRef ::= '&' Name ';'
7535
 
 *
7536
 
 * [ WFC: Entity Declared ]
7537
 
 * In a document without any DTD, a document with only an internal DTD
7538
 
 * subset which contains no parameter entity references, or a document
7539
 
 * with "standalone='yes'", the Name given in the entity reference
7540
 
 * must match that in an entity declaration, except that well-formed
7541
 
 * documents need not declare any of the following entities: amp, lt,
7542
 
 * gt, apos, quot.  The declaration of a parameter entity must precede
7543
 
 * any reference to it.  Similarly, the declaration of a general entity
7544
 
 * must precede any reference to it which appears in a default value in an
7545
 
 * attribute-list declaration. Note that if entities are declared in the
7546
 
 * external subset or in external parameter entities, a non-validating
7547
 
 * processor is not obligated to read and process their declarations;
7548
 
 * for such documents, the rule that an entity must be declared is a
7549
 
 * well-formedness constraint only if standalone='yes'.
7550
 
 *
7551
 
 * [ WFC: Parsed Entity ]
7552
 
 * An entity reference must not contain the name of an unparsed entity
7553
 
 *
7554
 
 * Returns the xmlEntityPtr if found, or NULL otherwise.
7555
 
 */
7556
 
xmlEntityPtr
7557
 
xmlParseEntityRef(xmlParserCtxtPtr ctxt) {
7558
 
    const xmlChar *name;
7559
 
    xmlEntityPtr ent = NULL;
7560
 
 
7561
 
    GROW;
7562
 
    if (ctxt->instate == XML_PARSER_EOF)
7563
 
        return(NULL);
7564
 
 
7565
 
    if (RAW != '&')
7566
 
        return(NULL);
7567
 
    NEXT;
7568
 
    name = xmlParseName(ctxt);
7569
 
    if (name == NULL) {
7570
 
        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
7571
 
                       "xmlParseEntityRef: no name\n");
7572
 
        return(NULL);
7573
 
    }
7574
 
    if (RAW != ';') {
7575
 
        xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
7576
 
        return(NULL);
7577
 
    }
7578
 
    NEXT;
7579
 
 
7580
 
    /*
7581
 
     * Predefined entities override any extra definition
7582
 
     */
7583
 
    if ((ctxt->options & XML_PARSE_OLDSAX) == 0) {
7584
 
        ent = xmlGetPredefinedEntity(name);
7585
 
        if (ent != NULL)
7586
 
            return(ent);
7587
 
    }
7588
 
 
7589
 
    /*
7590
 
     * Increase the number of entity references parsed
7591
 
     */
7592
 
    ctxt->nbentities++;
7593
 
 
7594
 
    /*
7595
 
     * Ask first SAX for entity resolution, otherwise try the
7596
 
     * entities which may have stored in the parser context.
7597
 
     */
7598
 
    if (ctxt->sax != NULL) {
7599
 
        if (ctxt->sax->getEntity != NULL)
7600
 
            ent = ctxt->sax->getEntity(ctxt->userData, name);
7601
 
        if ((ctxt->wellFormed == 1 ) && (ent == NULL) &&
7602
 
            (ctxt->options & XML_PARSE_OLDSAX))
7603
 
            ent = xmlGetPredefinedEntity(name);
7604
 
        if ((ctxt->wellFormed == 1 ) && (ent == NULL) &&
7605
 
            (ctxt->userData==ctxt)) {
7606
 
            ent = xmlSAX2GetEntity(ctxt, name);
7607
 
        }
7608
 
    }
7609
 
    if (ctxt->instate == XML_PARSER_EOF)
7610
 
        return(NULL);
7611
 
    /*
7612
 
     * [ WFC: Entity Declared ]
7613
 
     * In a document without any DTD, a document with only an
7614
 
     * internal DTD subset which contains no parameter entity
7615
 
     * references, or a document with "standalone='yes'", the
7616
 
     * Name given in the entity reference must match that in an
7617
 
     * entity declaration, except that well-formed documents
7618
 
     * need not declare any of the following entities: amp, lt,
7619
 
     * gt, apos, quot.
7620
 
     * The declaration of a parameter entity must precede any
7621
 
     * reference to it.
7622
 
     * Similarly, the declaration of a general entity must
7623
 
     * precede any reference to it which appears in a default
7624
 
     * value in an attribute-list declaration. Note that if
7625
 
     * entities are declared in the external subset or in
7626
 
     * external parameter entities, a non-validating processor
7627
 
     * is not obligated to read and process their declarations;
7628
 
     * for such documents, the rule that an entity must be
7629
 
     * declared is a well-formedness constraint only if
7630
 
     * standalone='yes'.
7631
 
     */
7632
 
    if (ent == NULL) {
7633
 
        if ((ctxt->standalone == 1) ||
7634
 
            ((ctxt->hasExternalSubset == 0) &&
7635
 
             (ctxt->hasPErefs == 0))) {
7636
 
            xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
7637
 
                     "Entity '%s' not defined\n", name);
7638
 
        } else {
7639
 
            xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
7640
 
                     "Entity '%s' not defined\n", name);
7641
 
            if ((ctxt->inSubset == 0) &&
7642
 
                (ctxt->sax != NULL) &&
7643
 
                (ctxt->sax->reference != NULL)) {
7644
 
                ctxt->sax->reference(ctxt->userData, name);
7645
 
            }
7646
 
        }
7647
 
        ctxt->valid = 0;
7648
 
    }
7649
 
 
7650
 
    /*
7651
 
     * [ WFC: Parsed Entity ]
7652
 
     * An entity reference must not contain the name of an
7653
 
     * unparsed entity
7654
 
     */
7655
 
    else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
7656
 
        xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
7657
 
                 "Entity reference to unparsed entity %s\n", name);
7658
 
    }
7659
 
 
7660
 
    /*
7661
 
     * [ WFC: No External Entity References ]
7662
 
     * Attribute values cannot contain direct or indirect
7663
 
     * entity references to external entities.
7664
 
     */
7665
 
    else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
7666
 
             (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
7667
 
        xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
7668
 
             "Attribute references external entity '%s'\n", name);
7669
 
    }
7670
 
    /*
7671
 
     * [ WFC: No < in Attribute Values ]
7672
 
     * The replacement text of any entity referred to directly or
7673
 
     * indirectly in an attribute value (other than "&lt;") must
7674
 
     * not contain a <.
7675
 
     */
7676
 
    else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
7677
 
             (ent != NULL) && 
7678
 
             (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY)) {
7679
 
        if ((ent->checked & 1) || ((ent->checked == 0) &&
7680
 
             (ent->content != NULL) &&(xmlStrchr(ent->content, '<')))) {
7681
 
            xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
7682
 
        "'<' in entity '%s' is not allowed in attributes values\n", name);
7683
 
        }
7684
 
    }
7685
 
 
7686
 
    /*
7687
 
     * Internal check, no parameter entities here ...
7688
 
     */
7689
 
    else {
7690
 
        switch (ent->etype) {
7691
 
            case XML_INTERNAL_PARAMETER_ENTITY:
7692
 
            case XML_EXTERNAL_PARAMETER_ENTITY:
7693
 
            xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
7694
 
             "Attempt to reference the parameter entity '%s'\n",
7695
 
                              name);
7696
 
            break;
7697
 
            default:
7698
 
            break;
7699
 
        }
7700
 
    }
7701
 
 
7702
 
    /*
7703
 
     * [ WFC: No Recursion ]
7704
 
     * A parsed entity must not contain a recursive reference
7705
 
     * to itself, either directly or indirectly.
7706
 
     * Done somewhere else
7707
 
     */
7708
 
    return(ent);
7709
 
}
7710
 
 
7711
 
/**
7712
 
 * xmlParseStringEntityRef:
7713
 
 * @ctxt:  an XML parser context
7714
 
 * @str:  a pointer to an index in the string
7715
 
 *
7716
 
 * parse ENTITY references declarations, but this version parses it from
7717
 
 * a string value.
7718
 
 *
7719
 
 * [68] EntityRef ::= '&' Name ';'
7720
 
 *
7721
 
 * [ WFC: Entity Declared ]
7722
 
 * In a document without any DTD, a document with only an internal DTD
7723
 
 * subset which contains no parameter entity references, or a document
7724
 
 * with "standalone='yes'", the Name given in the entity reference
7725
 
 * must match that in an entity declaration, except that well-formed
7726
 
 * documents need not declare any of the following entities: amp, lt,
7727
 
 * gt, apos, quot.  The declaration of a parameter entity must precede
7728
 
 * any reference to it.  Similarly, the declaration of a general entity
7729
 
 * must precede any reference to it which appears in a default value in an
7730
 
 * attribute-list declaration. Note that if entities are declared in the
7731
 
 * external subset or in external parameter entities, a non-validating
7732
 
 * processor is not obligated to read and process their declarations;
7733
 
 * for such documents, the rule that an entity must be declared is a
7734
 
 * well-formedness constraint only if standalone='yes'.
7735
 
 *
7736
 
 * [ WFC: Parsed Entity ]
7737
 
 * An entity reference must not contain the name of an unparsed entity
7738
 
 *
7739
 
 * Returns the xmlEntityPtr if found, or NULL otherwise. The str pointer
7740
 
 * is updated to the current location in the string.
7741
 
 */
7742
 
static xmlEntityPtr
7743
 
xmlParseStringEntityRef(xmlParserCtxtPtr ctxt, const xmlChar ** str) {
7744
 
    xmlChar *name;
7745
 
    const xmlChar *ptr;
7746
 
    xmlChar cur;
7747
 
    xmlEntityPtr ent = NULL;
7748
 
 
7749
 
    if ((str == NULL) || (*str == NULL))
7750
 
        return(NULL);
7751
 
    ptr = *str;
7752
 
    cur = *ptr;
7753
 
    if (cur != '&')
7754
 
        return(NULL);
7755
 
 
7756
 
    ptr++;
7757
 
    name = xmlParseStringName(ctxt, &ptr);
7758
 
    if (name == NULL) {
7759
 
        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
7760
 
                       "xmlParseStringEntityRef: no name\n");
7761
 
        *str = ptr;
7762
 
        return(NULL);
7763
 
    }
7764
 
    if (*ptr != ';') {
7765
 
        xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
7766
 
        xmlFree(name);
7767
 
        *str = ptr;
7768
 
        return(NULL);
7769
 
    }
7770
 
    ptr++;
7771
 
 
7772
 
 
7773
 
    /*
7774
 
     * Predefined entites override any extra definition
7775
 
     */
7776
 
    if ((ctxt->options & XML_PARSE_OLDSAX) == 0) {
7777
 
        ent = xmlGetPredefinedEntity(name);
7778
 
        if (ent != NULL) {
7779
 
            xmlFree(name);
7780
 
            *str = ptr;
7781
 
            return(ent);
7782
 
        }
7783
 
    }
7784
 
 
7785
 
    /*
7786
 
     * Increate the number of entity references parsed
7787
 
     */
7788
 
    ctxt->nbentities++;
7789
 
 
7790
 
    /*
7791
 
     * Ask first SAX for entity resolution, otherwise try the
7792
 
     * entities which may have stored in the parser context.
7793
 
     */
7794
 
    if (ctxt->sax != NULL) {
7795
 
        if (ctxt->sax->getEntity != NULL)
7796
 
            ent = ctxt->sax->getEntity(ctxt->userData, name);
7797
 
        if ((ent == NULL) && (ctxt->options & XML_PARSE_OLDSAX))
7798
 
            ent = xmlGetPredefinedEntity(name);
7799
 
        if ((ent == NULL) && (ctxt->userData==ctxt)) {
7800
 
            ent = xmlSAX2GetEntity(ctxt, name);
7801
 
        }
7802
 
    }
7803
 
    if (ctxt->instate == XML_PARSER_EOF) {
7804
 
        xmlFree(name);
7805
 
        return(NULL);
7806
 
    }
7807
 
 
7808
 
    /*
7809
 
     * [ WFC: Entity Declared ]
7810
 
     * In a document without any DTD, a document with only an
7811
 
     * internal DTD subset which contains no parameter entity
7812
 
     * references, or a document with "standalone='yes'", the
7813
 
     * Name given in the entity reference must match that in an
7814
 
     * entity declaration, except that well-formed documents
7815
 
     * need not declare any of the following entities: amp, lt,
7816
 
     * gt, apos, quot.
7817
 
     * The declaration of a parameter entity must precede any
7818
 
     * reference to it.
7819
 
     * Similarly, the declaration of a general entity must
7820
 
     * precede any reference to it which appears in a default
7821
 
     * value in an attribute-list declaration. Note that if
7822
 
     * entities are declared in the external subset or in
7823
 
     * external parameter entities, a non-validating processor
7824
 
     * is not obligated to read and process their declarations;
7825
 
     * for such documents, the rule that an entity must be
7826
 
     * declared is a well-formedness constraint only if
7827
 
     * standalone='yes'.
7828
 
     */
7829
 
    if (ent == NULL) {
7830
 
        if ((ctxt->standalone == 1) ||
7831
 
            ((ctxt->hasExternalSubset == 0) &&
7832
 
             (ctxt->hasPErefs == 0))) {
7833
 
            xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
7834
 
                     "Entity '%s' not defined\n", name);
7835
 
        } else {
7836
 
            xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
7837
 
                          "Entity '%s' not defined\n",
7838
 
                          name);
7839
 
        }
7840
 
        /* TODO ? check regressions ctxt->valid = 0; */
7841
 
    }
7842
 
 
7843
 
    /*
7844
 
     * [ WFC: Parsed Entity ]
7845
 
     * An entity reference must not contain the name of an
7846
 
     * unparsed entity
7847
 
     */
7848
 
    else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
7849
 
        xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
7850
 
                 "Entity reference to unparsed entity %s\n", name);
7851
 
    }
7852
 
 
7853
 
    /*
7854
 
     * [ WFC: No External Entity References ]
7855
 
     * Attribute values cannot contain direct or indirect
7856
 
     * entity references to external entities.
7857
 
     */
7858
 
    else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
7859
 
             (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
7860
 
        xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
7861
 
         "Attribute references external entity '%s'\n", name);
7862
 
    }
7863
 
    /*
7864
 
     * [ WFC: No < in Attribute Values ]
7865
 
     * The replacement text of any entity referred to directly or
7866
 
     * indirectly in an attribute value (other than "&lt;") must
7867
 
     * not contain a <.
7868
 
     */
7869
 
    else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
7870
 
             (ent != NULL) && (ent->content != NULL) &&
7871
 
             (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
7872
 
             (xmlStrchr(ent->content, '<'))) {
7873
 
        xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
7874
 
     "'<' in entity '%s' is not allowed in attributes values\n",
7875
 
                          name);
7876
 
    }
7877
 
 
7878
 
    /*
7879
 
     * Internal check, no parameter entities here ...
7880
 
     */
7881
 
    else {
7882
 
        switch (ent->etype) {
7883
 
            case XML_INTERNAL_PARAMETER_ENTITY:
7884
 
            case XML_EXTERNAL_PARAMETER_ENTITY:
7885
 
                xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
7886
 
             "Attempt to reference the parameter entity '%s'\n",
7887
 
                                  name);
7888
 
            break;
7889
 
            default:
7890
 
            break;
7891
 
        }
7892
 
    }
7893
 
 
7894
 
    /*
7895
 
     * [ WFC: No Recursion ]
7896
 
     * A parsed entity must not contain a recursive reference
7897
 
     * to itself, either directly or indirectly.
7898
 
     * Done somewhere else
7899
 
     */
7900
 
 
7901
 
    xmlFree(name);
7902
 
    *str = ptr;
7903
 
    return(ent);
7904
 
}
7905
 
 
7906
 
/**
7907
 
 * xmlParsePEReference:
7908
 
 * @ctxt:  an XML parser context
7909
 
 *
7910
 
 * parse PEReference declarations
7911
 
 * The entity content is handled directly by pushing it's content as
7912
 
 * a new input stream.
7913
 
 *
7914
 
 * [69] PEReference ::= '%' Name ';'
7915
 
 *
7916
 
 * [ WFC: No Recursion ]
7917
 
 * A parsed entity must not contain a recursive
7918
 
 * reference to itself, either directly or indirectly.
7919
 
 *
7920
 
 * [ WFC: Entity Declared ]
7921
 
 * In a document without any DTD, a document with only an internal DTD
7922
 
 * subset which contains no parameter entity references, or a document
7923
 
 * with "standalone='yes'", ...  ... The declaration of a parameter
7924
 
 * entity must precede any reference to it...
7925
 
 *
7926
 
 * [ VC: Entity Declared ]
7927
 
 * In a document with an external subset or external parameter entities
7928
 
 * with "standalone='no'", ...  ... The declaration of a parameter entity
7929
 
 * must precede any reference to it...
7930
 
 *
7931
 
 * [ WFC: In DTD ]
7932
 
 * Parameter-entity references may only appear in the DTD.
7933
 
 * NOTE: misleading but this is handled.
7934
 
 */
7935
 
void
7936
 
xmlParsePEReference(xmlParserCtxtPtr ctxt)
7937
 
{
7938
 
    const xmlChar *name;
7939
 
    xmlEntityPtr entity = NULL;
7940
 
    xmlParserInputPtr input;
7941
 
 
7942
 
    if (RAW != '%')
7943
 
        return;
7944
 
    NEXT;
7945
 
    name = xmlParseName(ctxt);
7946
 
    if (name == NULL) {
7947
 
        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
7948
 
                       "xmlParsePEReference: no name\n");
7949
 
        return;
7950
 
    }
7951
 
    if (RAW != ';') {
7952
 
        xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
7953
 
        return;
7954
 
    }
7955
 
 
7956
 
    NEXT;
7957
 
 
7958
 
    /*
7959
 
     * Increate the number of entity references parsed
7960
 
     */
7961
 
    ctxt->nbentities++;
7962
 
 
7963
 
    /*
7964
 
     * Request the entity from SAX
7965
 
     */
7966
 
    if ((ctxt->sax != NULL) &&
7967
 
        (ctxt->sax->getParameterEntity != NULL))
7968
 
        entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
7969
 
    if (ctxt->instate == XML_PARSER_EOF)
7970
 
        return;
7971
 
    if (entity == NULL) {
7972
 
        /*
7973
 
         * [ WFC: Entity Declared ]
7974
 
         * In a document without any DTD, a document with only an
7975
 
         * internal DTD subset which contains no parameter entity
7976
 
         * references, or a document with "standalone='yes'", ...
7977
 
         * ... The declaration of a parameter entity must precede
7978
 
         * any reference to it...
7979
 
         */
7980
 
        if ((ctxt->standalone == 1) ||
7981
 
            ((ctxt->hasExternalSubset == 0) &&
7982
 
             (ctxt->hasPErefs == 0))) {
7983
 
            xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
7984
 
                              "PEReference: %%%s; not found\n",
7985
 
                              name);
7986
 
        } else {
7987
 
            /*
7988
 
             * [ VC: Entity Declared ]
7989
 
             * In a document with an external subset or external
7990
 
             * parameter entities with "standalone='no'", ...
7991
 
             * ... The declaration of a parameter entity must
7992
 
             * precede any reference to it...
7993
 
             */
7994
 
            xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
7995
 
                          "PEReference: %%%s; not found\n",
7996
 
                          name, NULL);
7997
 
            ctxt->valid = 0;
7998
 
        }
7999
 
    } else {
8000
 
        /*
8001
 
         * Internal checking in case the entity quest barfed
8002
 
         */
8003
 
        if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
8004
 
            (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
8005
 
            xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
8006
 
                  "Internal: %%%s; is not a parameter entity\n",
8007
 
                          name, NULL);
8008
 
        } else if (ctxt->input->free != deallocblankswrapper) {
8009
 
            input = xmlNewBlanksWrapperInputStream(ctxt, entity);
8010
 
            if (xmlPushInput(ctxt, input) < 0)
8011
 
                return;
8012
 
        } else {
8013
 
            /*
8014
 
             * TODO !!!
8015
 
             * handle the extra spaces added before and after
8016
 
             * c.f. http://www.w3.org/TR/REC-xml#as-PE
8017
 
             */
8018
 
            input = xmlNewEntityInputStream(ctxt, entity);
8019
 
            if (xmlPushInput(ctxt, input) < 0)
8020
 
                return;
8021
 
            if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
8022
 
                (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) &&
8023
 
                (IS_BLANK_CH(NXT(5)))) {
8024
 
                xmlParseTextDecl(ctxt);
8025
 
                if (ctxt->errNo ==
8026
 
                    XML_ERR_UNSUPPORTED_ENCODING) {
8027
 
                    /*
8028
 
                     * The XML REC instructs us to stop parsing
8029
 
                     * right here
8030
 
                     */
8031
 
                    ctxt->instate = XML_PARSER_EOF;
8032
 
                    return;
8033
 
                }
8034
 
            }
8035
 
        }
8036
 
    }
8037
 
    ctxt->hasPErefs = 1;
8038
 
}
8039
 
 
8040
 
/**
8041
 
 * xmlLoadEntityContent:
8042
 
 * @ctxt:  an XML parser context
8043
 
 * @entity: an unloaded system entity
8044
 
 *
8045
 
 * Load the original content of the given system entity from the
8046
 
 * ExternalID/SystemID given. This is to be used for Included in Literal
8047
 
 * http://www.w3.org/TR/REC-xml/#inliteral processing of entities references
8048
 
 *
8049
 
 * Returns 0 in case of success and -1 in case of failure
8050
 
 */
8051
 
static int
8052
 
xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
8053
 
    xmlParserInputPtr input;
8054
 
    xmlBufferPtr buf;
8055
 
    int l, c;
8056
 
    int count = 0;
8057
 
 
8058
 
    if ((ctxt == NULL) || (entity == NULL) ||
8059
 
        ((entity->etype != XML_EXTERNAL_PARAMETER_ENTITY) &&
8060
 
         (entity->etype != XML_EXTERNAL_GENERAL_PARSED_ENTITY)) ||
8061
 
        (entity->content != NULL)) {
8062
 
        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
8063
 
                    "xmlLoadEntityContent parameter error");
8064
 
        return(-1);
8065
 
    }
8066
 
 
8067
 
    if (xmlParserDebugEntities)
8068
 
        xmlGenericError(xmlGenericErrorContext,
8069
 
                "Reading %s entity content input\n", entity->name);
8070
 
 
8071
 
    buf = xmlBufferCreate();
8072
 
    if (buf == NULL) {
8073
 
        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
8074
 
                    "xmlLoadEntityContent parameter error");
8075
 
        return(-1);
8076
 
    }
8077
 
 
8078
 
    input = xmlNewEntityInputStream(ctxt, entity);
8079
 
    if (input == NULL) {
8080
 
        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
8081
 
                    "xmlLoadEntityContent input error");
8082
 
        xmlBufferFree(buf);
8083
 
        return(-1);
8084
 
    }
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
 
    if (xmlPushInput(ctxt, input) < 0) {
8091
 
        xmlBufferFree(buf);
8092
 
        return(-1);
8093
 
    }
8094
 
 
8095
 
    GROW;
8096
 
    c = CUR_CHAR(l);
8097
 
    while ((ctxt->input == input) && (ctxt->input->cur < ctxt->input->end) &&
8098
 
           (IS_CHAR(c))) {
8099
 
        xmlBufferAdd(buf, ctxt->input->cur, l);
8100
 
        if (count++ > XML_PARSER_CHUNK_SIZE) {
8101
 
            count = 0;
8102
 
            GROW;
8103
 
            if (ctxt->instate == XML_PARSER_EOF) {
8104
 
                xmlBufferFree(buf);
8105
 
                return(-1);
8106
 
            }
8107
 
        }
8108
 
        NEXTL(l);
8109
 
        c = CUR_CHAR(l);
8110
 
        if (c == 0) {
8111
 
            count = 0;
8112
 
            GROW;
8113
 
            if (ctxt->instate == XML_PARSER_EOF) {
8114
 
                xmlBufferFree(buf);
8115
 
                return(-1);
8116
 
            }
8117
 
            c = CUR_CHAR(l);
8118
 
        }
8119
 
    }
8120
 
 
8121
 
    if ((ctxt->input == input) && (ctxt->input->cur >= ctxt->input->end)) {
8122
 
        xmlPopInput(ctxt);
8123
 
    } else if (!IS_CHAR(c)) {
8124
 
        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
8125
 
                          "xmlLoadEntityContent: invalid char value %d\n",
8126
 
                          c);
8127
 
        xmlBufferFree(buf);
8128
 
        return(-1);
8129
 
    }
8130
 
    entity->content = buf->content;
8131
 
    buf->content = NULL;
8132
 
    xmlBufferFree(buf);
8133
 
 
8134
 
    return(0);
8135
 
}
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
 
xmlParseStringPEReference(xmlParserCtxtPtr ctxt, const xmlChar **str) {
8170
 
    const xmlChar *ptr;
8171
 
    xmlChar cur;
8172
 
    xmlChar *name;
8173
 
    xmlEntityPtr entity = NULL;
8174
 
 
8175
 
    if ((str == NULL) || (*str == NULL)) return(NULL);
8176
 
    ptr = *str;
8177
 
    cur = *ptr;
8178
 
    if (cur != '%')
8179
 
        return(NULL);
8180
 
    ptr++;
8181
 
    name = xmlParseStringName(ctxt, &ptr);
8182
 
    if (name == NULL) {
8183
 
        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8184
 
                       "xmlParseStringPEReference: no name\n");
8185
 
        *str = ptr;
8186
 
        return(NULL);
8187
 
    }
8188
 
    cur = *ptr;
8189
 
    if (cur != ';') {
8190
 
        xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
8191
 
        xmlFree(name);
8192
 
        *str = ptr;
8193
 
        return(NULL);
8194
 
    }
8195
 
    ptr++;
8196
 
 
8197
 
    /*
8198
 
     * Increate the number of entity references parsed
8199
 
     */
8200
 
    ctxt->nbentities++;
8201
 
 
8202
 
    /*
8203
 
     * Request the entity from SAX
8204
 
     */
8205
 
    if ((ctxt->sax != NULL) &&
8206
 
        (ctxt->sax->getParameterEntity != NULL))
8207
 
        entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
8208
 
    if (ctxt->instate == XML_PARSER_EOF) {
8209
 
        xmlFree(name);
8210
 
        return(NULL);
8211
 
    }
8212
 
    if (entity == NULL) {
8213
 
        /*
8214
 
         * [ WFC: Entity Declared ]
8215
 
         * In a document without any DTD, a document with only an
8216
 
         * internal DTD subset which contains no parameter entity
8217
 
         * references, or a document with "standalone='yes'", ...
8218
 
         * ... The declaration of a parameter entity must precede
8219
 
         * any reference to it...
8220
 
         */
8221
 
        if ((ctxt->standalone == 1) ||
8222
 
            ((ctxt->hasExternalSubset == 0) && (ctxt->hasPErefs == 0))) {
8223
 
            xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
8224
 
                 "PEReference: %%%s; not found\n", name);
8225
 
        } else {
8226
 
            /*
8227
 
             * [ VC: Entity Declared ]
8228
 
             * In a document with an external subset or external
8229
 
             * parameter entities with "standalone='no'", ...
8230
 
             * ... The declaration of a parameter entity must
8231
 
             * precede any reference to it...
8232
 
             */
8233
 
            xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
8234
 
                          "PEReference: %%%s; not found\n",
8235
 
                          name, NULL);
8236
 
            ctxt->valid = 0;
8237
 
        }
8238
 
    } else {
8239
 
        /*
8240
 
         * Internal checking in case the entity quest barfed
8241
 
         */
8242
 
        if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
8243
 
            (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
8244
 
            xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
8245
 
                          "%%%s; is not a parameter entity\n",
8246
 
                          name, NULL);
8247
 
        }
8248
 
    }
8249
 
    ctxt->hasPErefs = 1;
8250
 
    xmlFree(name);
8251
 
    *str = ptr;
8252
 
    return(entity);
8253
 
}
8254
 
 
8255
 
/**
8256
 
 * xmlParseDocTypeDecl:
8257
 
 * @ctxt:  an XML parser context
8258
 
 *
8259
 
 * parse a DOCTYPE declaration
8260
 
 *
8261
 
 * [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S?
8262
 
 *                      ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
8263
 
 *
8264
 
 * [ VC: Root Element Type ]
8265
 
 * The Name in the document type declaration must match the element
8266
 
 * type of the root element.
8267
 
 */
8268
 
 
8269
 
void
8270
 
xmlParseDocTypeDecl(xmlParserCtxtPtr ctxt) {
8271
 
    const xmlChar *name = NULL;
8272
 
    xmlChar *ExternalID = NULL;
8273
 
    xmlChar *URI = NULL;
8274
 
 
8275
 
    /*
8276
 
     * We know that '<!DOCTYPE' has been detected.
8277
 
     */
8278
 
    SKIP(9);
8279
 
 
8280
 
    SKIP_BLANKS;
8281
 
 
8282
 
    /*
8283
 
     * Parse the DOCTYPE name.
8284
 
     */
8285
 
    name = xmlParseName(ctxt);
8286
 
    if (name == NULL) {
8287
 
        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8288
 
                       "xmlParseDocTypeDecl : no DOCTYPE name !\n");
8289
 
    }
8290
 
    ctxt->intSubName = name;
8291
 
 
8292
 
    SKIP_BLANKS;
8293
 
 
8294
 
    /*
8295
 
     * Check for SystemID and ExternalID
8296
 
     */
8297
 
    URI = xmlParseExternalID(ctxt, &ExternalID, 1);
8298
 
 
8299
 
    if ((URI != NULL) || (ExternalID != NULL)) {
8300
 
        ctxt->hasExternalSubset = 1;
8301
 
    }
8302
 
    ctxt->extSubURI = URI;
8303
 
    ctxt->extSubSystem = ExternalID;
8304
 
 
8305
 
    SKIP_BLANKS;
8306
 
 
8307
 
    /*
8308
 
     * Create and update the internal subset.
8309
 
     */
8310
 
    if ((ctxt->sax != NULL) && (ctxt->sax->internalSubset != NULL) &&
8311
 
        (!ctxt->disableSAX))
8312
 
        ctxt->sax->internalSubset(ctxt->userData, name, ExternalID, URI);
8313
 
    if (ctxt->instate == XML_PARSER_EOF)
8314
 
        return;
8315
 
 
8316
 
    /*
8317
 
     * Is there any internal subset declarations ?
8318
 
     * they are handled separately in xmlParseInternalSubset()
8319
 
     */
8320
 
    if (RAW == '[')
8321
 
        return;
8322
 
 
8323
 
    /*
8324
 
     * We should be at the end of the DOCTYPE declaration.
8325
 
     */
8326
 
    if (RAW != '>') {
8327
 
        xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
8328
 
    }
8329
 
    NEXT;
8330
 
}
8331
 
 
8332
 
/**
8333
 
 * xmlParseInternalSubset:
8334
 
 * @ctxt:  an XML parser context
8335
 
 *
8336
 
 * parse the internal subset declaration
8337
 
 *
8338
 
 * [28 end] ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
8339
 
 */
8340
 
 
8341
 
static void
8342
 
xmlParseInternalSubset(xmlParserCtxtPtr ctxt) {
8343
 
    /*
8344
 
     * Is there any DTD definition ?
8345
 
     */
8346
 
    if (RAW == '[') {
8347
 
        ctxt->instate = XML_PARSER_DTD;
8348
 
        NEXT;
8349
 
        /*
8350
 
         * Parse the succession of Markup declarations and
8351
 
         * PEReferences.
8352
 
         * Subsequence (markupdecl | PEReference | S)*
8353
 
         */
8354
 
        while ((RAW != ']') && (ctxt->instate != XML_PARSER_EOF)) {
8355
 
            const xmlChar *check = CUR_PTR;
8356
 
            unsigned int cons = ctxt->input->consumed;
8357
 
 
8358
 
            SKIP_BLANKS;
8359
 
            xmlParseMarkupDecl(ctxt);
8360
 
            xmlParsePEReference(ctxt);
8361
 
 
8362
 
            /*
8363
 
             * Pop-up of finished entities.
8364
 
             */
8365
 
            while ((RAW == 0) && (ctxt->inputNr > 1))
8366
 
                xmlPopInput(ctxt);
8367
 
 
8368
 
            if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
8369
 
                xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
8370
 
             "xmlParseInternalSubset: error detected in Markup declaration\n");
8371
 
                break;
8372
 
            }
8373
 
        }
8374
 
        if (RAW == ']') {
8375
 
            NEXT;
8376
 
            SKIP_BLANKS;
8377
 
        }
8378
 
    }
8379
 
 
8380
 
    /*
8381
 
     * We should be at the end of the DOCTYPE declaration.
8382
 
     */
8383
 
    if (RAW != '>') {
8384
 
        xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
8385
 
    }
8386
 
    NEXT;
8387
 
}
8388
 
 
8389
 
#ifdef LIBXML_SAX1_ENABLED
8390
 
/**
8391
 
 * xmlParseAttribute:
8392
 
 * @ctxt:  an XML parser context
8393
 
 * @value:  a xmlChar ** used to store the value of the attribute
8394
 
 *
8395
 
 * parse an attribute
8396
 
 *
8397
 
 * [41] Attribute ::= Name Eq AttValue
8398
 
 *
8399
 
 * [ WFC: No External Entity References ]
8400
 
 * Attribute values cannot contain direct or indirect entity references
8401
 
 * to external entities.
8402
 
 *
8403
 
 * [ WFC: No < in Attribute Values ]
8404
 
 * The replacement text of any entity referred to directly or indirectly in
8405
 
 * an attribute value (other than "&lt;") must not contain a <.
8406
 
 *
8407
 
 * [ VC: Attribute Value Type ]
8408
 
 * The attribute must have been declared; the value must be of the type
8409
 
 * declared for it.
8410
 
 *
8411
 
 * [25] Eq ::= S? '=' S?
8412
 
 *
8413
 
 * With namespace:
8414
 
 *
8415
 
 * [NS 11] Attribute ::= QName Eq AttValue
8416
 
 *
8417
 
 * Also the case QName == xmlns:??? is handled independently as a namespace
8418
 
 * definition.
8419
 
 *
8420
 
 * Returns the attribute name, and the value in *value.
8421
 
 */
8422
 
 
8423
 
const xmlChar *
8424
 
xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlChar **value) {
8425
 
    const xmlChar *name;
8426
 
    xmlChar *val;
8427
 
 
8428
 
    *value = NULL;
8429
 
    GROW;
8430
 
    name = xmlParseName(ctxt);
8431
 
    if (name == NULL) {
8432
 
        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8433
 
                       "error parsing attribute name\n");
8434
 
        return(NULL);
8435
 
    }
8436
 
 
8437
 
    /*
8438
 
     * read the value
8439
 
     */
8440
 
    SKIP_BLANKS;
8441
 
    if (RAW == '=') {
8442
 
        NEXT;
8443
 
        SKIP_BLANKS;
8444
 
        val = xmlParseAttValue(ctxt);
8445
 
        ctxt->instate = XML_PARSER_CONTENT;
8446
 
    } else {
8447
 
        xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
8448
 
               "Specification mandate value for attribute %s\n", name);
8449
 
        return(NULL);
8450
 
    }
8451
 
 
8452
 
    /*
8453
 
     * Check that xml:lang conforms to the specification
8454
 
     * No more registered as an error, just generate a warning now
8455
 
     * since this was deprecated in XML second edition
8456
 
     */
8457
 
    if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "xml:lang"))) {
8458
 
        if (!xmlCheckLanguageID(val)) {
8459
 
            xmlWarningMsg(ctxt, XML_WAR_LANG_VALUE,
8460
 
                          "Malformed value for xml:lang : %s\n",
8461
 
                          val, NULL);
8462
 
        }
8463
 
    }
8464
 
 
8465
 
    /*
8466
 
     * Check that xml:space conforms to the specification
8467
 
     */
8468
 
    if (xmlStrEqual(name, BAD_CAST "xml:space")) {
8469
 
        if (xmlStrEqual(val, BAD_CAST "default"))
8470
 
            *(ctxt->space) = 0;
8471
 
        else if (xmlStrEqual(val, BAD_CAST "preserve"))
8472
 
            *(ctxt->space) = 1;
8473
 
        else {
8474
 
                xmlWarningMsg(ctxt, XML_WAR_SPACE_VALUE,
8475
 
"Invalid value \"%s\" for xml:space : \"default\" or \"preserve\" expected\n",
8476
 
                                 val, NULL);
8477
 
        }
8478
 
    }
8479
 
 
8480
 
    *value = val;
8481
 
    return(name);
8482
 
}
8483
 
 
8484
 
/**
8485
 
 * xmlParseStartTag:
8486
 
 * @ctxt:  an XML parser context
8487
 
 *
8488
 
 * parse a start of tag either for rule element or
8489
 
 * EmptyElement. In both case we don't parse the tag closing chars.
8490
 
 *
8491
 
 * [40] STag ::= '<' Name (S Attribute)* S? '>'
8492
 
 *
8493
 
 * [ WFC: Unique Att Spec ]
8494
 
 * No attribute name may appear more than once in the same start-tag or
8495
 
 * empty-element tag.
8496
 
 *
8497
 
 * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
8498
 
 *
8499
 
 * [ WFC: Unique Att Spec ]
8500
 
 * No attribute name may appear more than once in the same start-tag or
8501
 
 * empty-element tag.
8502
 
 *
8503
 
 * With namespace:
8504
 
 *
8505
 
 * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
8506
 
 *
8507
 
 * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
8508
 
 *
8509
 
 * Returns the element name parsed
8510
 
 */
8511
 
 
8512
 
const xmlChar *
8513
 
xmlParseStartTag(xmlParserCtxtPtr ctxt) {
8514
 
    const xmlChar *name;
8515
 
    const xmlChar *attname;
8516
 
    xmlChar *attvalue;
8517
 
    const xmlChar **atts = ctxt->atts;
8518
 
    int nbatts = 0;
8519
 
    int maxatts = ctxt->maxatts;
8520
 
    int i;
8521
 
 
8522
 
    if (RAW != '<') return(NULL);
8523
 
    NEXT1;
8524
 
 
8525
 
    name = xmlParseName(ctxt);
8526
 
    if (name == NULL) {
8527
 
        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8528
 
             "xmlParseStartTag: invalid element name\n");
8529
 
        return(NULL);
8530
 
    }
8531
 
 
8532
 
    /*
8533
 
     * Now parse the attributes, it ends up with the ending
8534
 
     *
8535
 
     * (S Attribute)* S?
8536
 
     */
8537
 
    SKIP_BLANKS;
8538
 
    GROW;
8539
 
 
8540
 
    while (((RAW != '>') &&
8541
 
           ((RAW != '/') || (NXT(1) != '>')) &&
8542
 
           (IS_BYTE_CHAR(RAW))) && (ctxt->instate != XML_PARSER_EOF)) {
8543
 
        const xmlChar *q = CUR_PTR;
8544
 
        unsigned int cons = ctxt->input->consumed;
8545
 
 
8546
 
        attname = xmlParseAttribute(ctxt, &attvalue);
8547
 
        if ((attname != NULL) && (attvalue != NULL)) {
8548
 
            /*
8549
 
             * [ WFC: Unique Att Spec ]
8550
 
             * No attribute name may appear more than once in the same
8551
 
             * start-tag or empty-element tag.
8552
 
             */
8553
 
            for (i = 0; i < nbatts;i += 2) {
8554
 
                if (xmlStrEqual(atts[i], attname)) {
8555
 
                    xmlErrAttributeDup(ctxt, NULL, attname);
8556
 
                    xmlFree(attvalue);
8557
 
                    goto failed;
8558
 
                }
8559
 
            }
8560
 
            /*
8561
 
             * Add the pair to atts
8562
 
             */
8563
 
            if (atts == NULL) {
8564
 
                maxatts = 22; /* allow for 10 attrs by default */
8565
 
                atts = (const xmlChar **)
8566
 
                       xmlMalloc(maxatts * sizeof(xmlChar *));
8567
 
                if (atts == NULL) {
8568
 
                    xmlErrMemory(ctxt, NULL);
8569
 
                    if (attvalue != NULL)
8570
 
                        xmlFree(attvalue);
8571
 
                    goto failed;
8572
 
                }
8573
 
                ctxt->atts = atts;
8574
 
                ctxt->maxatts = maxatts;
8575
 
            } else if (nbatts + 4 > maxatts) {
8576
 
                const xmlChar **n;
8577
 
 
8578
 
                maxatts *= 2;
8579
 
                n = (const xmlChar **) xmlRealloc((void *) atts,
8580
 
                                             maxatts * sizeof(const xmlChar *));
8581
 
                if (n == NULL) {
8582
 
                    xmlErrMemory(ctxt, NULL);
8583
 
                    if (attvalue != NULL)
8584
 
                        xmlFree(attvalue);
8585
 
                    goto failed;
8586
 
                }
8587
 
                atts = n;
8588
 
                ctxt->atts = atts;
8589
 
                ctxt->maxatts = maxatts;
8590
 
            }
8591
 
            atts[nbatts++] = attname;
8592
 
            atts[nbatts++] = attvalue;
8593
 
            atts[nbatts] = NULL;
8594
 
            atts[nbatts + 1] = NULL;
8595
 
        } else {
8596
 
            if (attvalue != NULL)
8597
 
                xmlFree(attvalue);
8598
 
        }
8599
 
 
8600
 
failed:
8601
 
 
8602
 
        GROW
8603
 
        if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
8604
 
            break;
8605
 
        if (!IS_BLANK_CH(RAW)) {
8606
 
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
8607
 
                           "attributes construct error\n");
8608
 
        }
8609
 
        SKIP_BLANKS;
8610
 
        if ((cons == ctxt->input->consumed) && (q == CUR_PTR) &&
8611
 
            (attname == NULL) && (attvalue == NULL)) {
8612
 
            xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
8613
 
                           "xmlParseStartTag: problem parsing attributes\n");
8614
 
            break;
8615
 
        }
8616
 
        SHRINK;
8617
 
        GROW;
8618
 
    }
8619
 
 
8620
 
    /*
8621
 
     * SAX: Start of Element !
8622
 
     */
8623
 
    if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL) &&
8624
 
        (!ctxt->disableSAX)) {
8625
 
        if (nbatts > 0)
8626
 
            ctxt->sax->startElement(ctxt->userData, name, atts);
8627
 
        else
8628
 
            ctxt->sax->startElement(ctxt->userData, name, NULL);
8629
 
    }
8630
 
 
8631
 
    if (atts != NULL) {
8632
 
        /* Free only the content strings */
8633
 
        for (i = 1;i < nbatts;i+=2)
8634
 
            if (atts[i] != NULL)
8635
 
               xmlFree((xmlChar *) atts[i]);
8636
 
    }
8637
 
    return(name);
8638
 
}
8639
 
 
8640
 
/**
8641
 
 * xmlParseEndTag1:
8642
 
 * @ctxt:  an XML parser context
8643
 
 * @line:  line of the start tag
8644
 
 * @nsNr:  number of namespaces on the start tag
8645
 
 *
8646
 
 * parse an end of tag
8647
 
 *
8648
 
 * [42] ETag ::= '</' Name S? '>'
8649
 
 *
8650
 
 * With namespace
8651
 
 *
8652
 
 * [NS 9] ETag ::= '</' QName S? '>'
8653
 
 */
8654
 
 
8655
 
static void
8656
 
xmlParseEndTag1(xmlParserCtxtPtr ctxt, int line) {
8657
 
    const xmlChar *name;
8658
 
 
8659
 
    GROW;
8660
 
    if ((RAW != '<') || (NXT(1) != '/')) {
8661
 
        xmlFatalErrMsg(ctxt, XML_ERR_LTSLASH_REQUIRED,
8662
 
                       "xmlParseEndTag: '</' not found\n");
8663
 
        return;
8664
 
    }
8665
 
    SKIP(2);
8666
 
 
8667
 
    name = xmlParseNameAndCompare(ctxt,ctxt->name);
8668
 
 
8669
 
    /*
8670
 
     * We should definitely be at the ending "S? '>'" part
8671
 
     */
8672
 
    GROW;
8673
 
    SKIP_BLANKS;
8674
 
    if ((!IS_BYTE_CHAR(RAW)) || (RAW != '>')) {
8675
 
        xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
8676
 
    } else
8677
 
        NEXT1;
8678
 
 
8679
 
    /*
8680
 
     * [ WFC: Element Type Match ]
8681
 
     * The Name in an element's end-tag must match the element type in the
8682
 
     * start-tag.
8683
 
     *
8684
 
     */
8685
 
    if (name != (xmlChar*)1) {
8686
 
        if (name == NULL) name = BAD_CAST "unparseable";
8687
 
        xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
8688
 
                     "Opening and ending tag mismatch: %s line %d and %s\n",
8689
 
                                ctxt->name, line, name);
8690
 
    }
8691
 
 
8692
 
    /*
8693
 
     * SAX: End of Tag
8694
 
     */
8695
 
    if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
8696
 
        (!ctxt->disableSAX))
8697
 
        ctxt->sax->endElement(ctxt->userData, ctxt->name);
8698
 
 
8699
 
    namePop(ctxt);
8700
 
    spacePop(ctxt);
8701
 
    return;
8702
 
}
8703
 
 
8704
 
/**
8705
 
 * xmlParseEndTag:
8706
 
 * @ctxt:  an XML parser context
8707
 
 *
8708
 
 * parse an end of tag
8709
 
 *
8710
 
 * [42] ETag ::= '</' Name S? '>'
8711
 
 *
8712
 
 * With namespace
8713
 
 *
8714
 
 * [NS 9] ETag ::= '</' QName S? '>'
8715
 
 */
8716
 
 
8717
 
void
8718
 
xmlParseEndTag(xmlParserCtxtPtr ctxt) {
8719
 
    xmlParseEndTag1(ctxt, 0);
8720
 
}
8721
 
#endif /* LIBXML_SAX1_ENABLED */
8722
 
 
8723
 
/************************************************************************
8724
 
 *                                                                      *
8725
 
 *                    SAX 2 specific operations                         *
8726
 
 *                                                                      *
8727
 
 ************************************************************************/
8728
 
 
8729
 
/*
8730
 
 * xmlGetNamespace:
8731
 
 * @ctxt:  an XML parser context
8732
 
 * @prefix:  the prefix to lookup
8733
 
 *
8734
 
 * Lookup the namespace name for the @prefix (which ca be NULL)
8735
 
 * The prefix must come from the @ctxt->dict dictionnary
8736
 
 *
8737
 
 * Returns the namespace name or NULL if not bound
8738
 
 */
8739
 
static const xmlChar *
8740
 
xmlGetNamespace(xmlParserCtxtPtr ctxt, const xmlChar *prefix) {
8741
 
    int i;
8742
 
 
8743
 
    if (prefix == ctxt->str_xml) return(ctxt->str_xml_ns);
8744
 
    for (i = ctxt->nsNr - 2;i >= 0;i-=2)
8745
 
        if (ctxt->nsTab[i] == prefix) {
8746
 
            if ((prefix == NULL) && (*ctxt->nsTab[i + 1] == 0))
8747
 
                return(NULL);
8748
 
            return(ctxt->nsTab[i + 1]);
8749
 
        }
8750
 
    return(NULL);
8751
 
}
8752
 
 
8753
 
/**
8754
 
 * xmlParseQName:
8755
 
 * @ctxt:  an XML parser context
8756
 
 * @prefix:  pointer to store the prefix part
8757
 
 *
8758
 
 * parse an XML Namespace QName
8759
 
 *
8760
 
 * [6]  QName  ::= (Prefix ':')? LocalPart
8761
 
 * [7]  Prefix  ::= NCName
8762
 
 * [8]  LocalPart  ::= NCName
8763
 
 *
8764
 
 * Returns the Name parsed or NULL
8765
 
 */
8766
 
 
8767
 
static const xmlChar *
8768
 
xmlParseQName(xmlParserCtxtPtr ctxt, const xmlChar **prefix) {
8769
 
    const xmlChar *l, *p;
8770
 
 
8771
 
    GROW;
8772
 
 
8773
 
    l = xmlParseNCName(ctxt);
8774
 
    if (l == NULL) {
8775
 
        if (CUR == ':') {
8776
 
            l = xmlParseName(ctxt);
8777
 
            if (l != NULL) {
8778
 
                xmlNsErr(ctxt, XML_NS_ERR_QNAME,
8779
 
                         "Failed to parse QName '%s'\n", l, NULL, NULL);
8780
 
                *prefix = NULL;
8781
 
                return(l);
8782
 
            }
8783
 
        }
8784
 
        return(NULL);
8785
 
    }
8786
 
    if (CUR == ':') {
8787
 
        NEXT;
8788
 
        p = l;
8789
 
        l = xmlParseNCName(ctxt);
8790
 
        if (l == NULL) {
8791
 
            xmlChar *tmp;
8792
 
 
8793
 
            xmlNsErr(ctxt, XML_NS_ERR_QNAME,
8794
 
                     "Failed to parse QName '%s:'\n", p, NULL, NULL);
8795
 
            l = xmlParseNmtoken(ctxt);
8796
 
            if (l == NULL)
8797
 
                tmp = xmlBuildQName(BAD_CAST "", p, NULL, 0);
8798
 
            else {
8799
 
                tmp = xmlBuildQName(l, p, NULL, 0);
8800
 
                xmlFree((char *)l);
8801
 
            }
8802
 
            p = xmlDictLookup(ctxt->dict, tmp, -1);
8803
 
            if (tmp != NULL) xmlFree(tmp);
8804
 
            *prefix = NULL;
8805
 
            return(p);
8806
 
        }
8807
 
        if (CUR == ':') {
8808
 
            xmlChar *tmp;
8809
 
 
8810
 
            xmlNsErr(ctxt, XML_NS_ERR_QNAME,
8811
 
                     "Failed to parse QName '%s:%s:'\n", p, l, NULL);
8812
 
            NEXT;
8813
 
            tmp = (xmlChar *) xmlParseName(ctxt);
8814
 
            if (tmp != NULL) {
8815
 
                tmp = xmlBuildQName(tmp, l, NULL, 0);
8816
 
                l = xmlDictLookup(ctxt->dict, tmp, -1);
8817
 
                if (tmp != NULL) xmlFree(tmp);
8818
 
                *prefix = p;
8819
 
                return(l);
8820
 
            }
8821
 
            tmp = xmlBuildQName(BAD_CAST "", l, NULL, 0);
8822
 
            l = xmlDictLookup(ctxt->dict, tmp, -1);
8823
 
            if (tmp != NULL) xmlFree(tmp);
8824
 
            *prefix = p;
8825
 
            return(l);
8826
 
        }
8827
 
        *prefix = p;
8828
 
    } else
8829
 
        *prefix = NULL;
8830
 
    return(l);
8831
 
}
8832
 
 
8833
 
/**
8834
 
 * xmlParseQNameAndCompare:
8835
 
 * @ctxt:  an XML parser context
8836
 
 * @name:  the localname
8837
 
 * @prefix:  the prefix, if any.
8838
 
 *
8839
 
 * parse an XML name and compares for match
8840
 
 * (specialized for endtag parsing)
8841
 
 *
8842
 
 * Returns NULL for an illegal name, (xmlChar*) 1 for success
8843
 
 * and the name for mismatch
8844
 
 */
8845
 
 
8846
 
static const xmlChar *
8847
 
xmlParseQNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *name,
8848
 
                        xmlChar const *prefix) {
8849
 
    const xmlChar *cmp;
8850
 
    const xmlChar *in;
8851
 
    const xmlChar *ret;
8852
 
    const xmlChar *prefix2;
8853
 
 
8854
 
    if (prefix == NULL) return(xmlParseNameAndCompare(ctxt, name));
8855
 
 
8856
 
    GROW;
8857
 
    in = ctxt->input->cur;
8858
 
 
8859
 
    cmp = prefix;
8860
 
    while (*in != 0 && *in == *cmp) {
8861
 
        ++in;
8862
 
        ++cmp;
8863
 
    }
8864
 
    if ((*cmp == 0) && (*in == ':')) {
8865
 
        in++;
8866
 
        cmp = name;
8867
 
        while (*in != 0 && *in == *cmp) {
8868
 
            ++in;
8869
 
            ++cmp;
8870
 
        }
8871
 
        if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) {
8872
 
            /* success */
8873
 
            ctxt->input->cur = in;
8874
 
            return((const xmlChar*) 1);
8875
 
        }
8876
 
    }
8877
 
    /*
8878
 
     * all strings coms from the dictionary, equality can be done directly
8879
 
     */
8880
 
    ret = xmlParseQName (ctxt, &prefix2);
8881
 
    if ((ret == name) && (prefix == prefix2))
8882
 
        return((const xmlChar*) 1);
8883
 
    return ret;
8884
 
}
8885
 
 
8886
 
/**
8887
 
 * xmlParseAttValueInternal:
8888
 
 * @ctxt:  an XML parser context
8889
 
 * @len:  attribute len result
8890
 
 * @alloc:  whether the attribute was reallocated as a new string
8891
 
 * @normalize:  if 1 then further non-CDATA normalization must be done
8892
 
 *
8893
 
 * parse a value for an attribute.
8894
 
 * NOTE: if no normalization is needed, the routine will return pointers
8895
 
 *       directly from the data buffer.
8896
 
 *
8897
 
 * 3.3.3 Attribute-Value Normalization:
8898
 
 * Before the value of an attribute is passed to the application or
8899
 
 * checked for validity, the XML processor must normalize it as follows:
8900
 
 * - a character reference is processed by appending the referenced
8901
 
 *   character to the attribute value
8902
 
 * - an entity reference is processed by recursively processing the
8903
 
 *   replacement text of the entity
8904
 
 * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
8905
 
 *   appending #x20 to the normalized value, except that only a single
8906
 
 *   #x20 is appended for a "#xD#xA" sequence that is part of an external
8907
 
 *   parsed entity or the literal entity value of an internal parsed entity
8908
 
 * - other characters are processed by appending them to the normalized value
8909
 
 * If the declared value is not CDATA, then the XML processor must further
8910
 
 * process the normalized attribute value by discarding any leading and
8911
 
 * trailing space (#x20) characters, and by replacing sequences of space
8912
 
 * (#x20) characters by a single space (#x20) character.
8913
 
 * All attributes for which no declaration has been read should be treated
8914
 
 * by a non-validating parser as if declared CDATA.
8915
 
 *
8916
 
 * Returns the AttValue parsed or NULL. The value has to be freed by the
8917
 
 *     caller if it was copied, this can be detected by val[*len] == 0.
8918
 
 */
8919
 
 
8920
 
static xmlChar *
8921
 
xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
8922
 
                         int normalize)
8923
 
{
8924
 
    xmlChar limit = 0;
8925
 
    const xmlChar *in = NULL, *start, *end, *last;
8926
 
    xmlChar *ret = NULL;
8927
 
 
8928
 
    GROW;
8929
 
    in = (xmlChar *) CUR_PTR;
8930
 
    if (*in != '"' && *in != '\'') {
8931
 
        xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
8932
 
        return (NULL);
8933
 
    }
8934
 
    ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
8935
 
 
8936
 
    /*
8937
 
     * try to handle in this routine the most common case where no
8938
 
     * allocation of a new string is required and where content is
8939
 
     * pure ASCII.
8940
 
     */
8941
 
    limit = *in++;
8942
 
    end = ctxt->input->end;
8943
 
    start = in;
8944
 
    if (in >= end) {
8945
 
        const xmlChar *oldbase = ctxt->input->base;
8946
 
        GROW;
8947
 
        if (oldbase != ctxt->input->base) {
8948
 
            long delta = ctxt->input->base - oldbase;
8949
 
            start = start + delta;
8950
 
            in = in + delta;
8951
 
        }
8952
 
        end = ctxt->input->end;
8953
 
    }
8954
 
    if (normalize) {
8955
 
        /*
8956
 
         * Skip any leading spaces
8957
 
         */
8958
 
        while ((in < end) && (*in != limit) &&
8959
 
               ((*in == 0x20) || (*in == 0x9) ||
8960
 
                (*in == 0xA) || (*in == 0xD))) {
8961
 
            in++;
8962
 
            start = in;
8963
 
            if (in >= end) {
8964
 
                const xmlChar *oldbase = ctxt->input->base;
8965
 
                GROW;
8966
 
                if (ctxt->instate == XML_PARSER_EOF)
8967
 
                    return(NULL);
8968
 
                if (oldbase != ctxt->input->base) {
8969
 
                    long delta = ctxt->input->base - oldbase;
8970
 
                    start = start + delta;
8971
 
                    in = in + delta;
8972
 
                }
8973
 
                end = ctxt->input->end;
8974
 
                if (((in - start) > XML_MAX_TEXT_LENGTH) &&
8975
 
                    ((ctxt->options & XML_PARSE_HUGE) == 0)) {
8976
 
                    xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
8977
 
                                   "AttValue length too long\n");
8978
 
                    return(NULL);
8979
 
                }
8980
 
            }
8981
 
        }
8982
 
        while ((in < end) && (*in != limit) && (*in >= 0x20) &&
8983
 
               (*in <= 0x7f) && (*in != '&') && (*in != '<')) {
8984
 
            if ((*in++ == 0x20) && (*in == 0x20)) break;
8985
 
            if (in >= end) {
8986
 
                const xmlChar *oldbase = ctxt->input->base;
8987
 
                GROW;
8988
 
                if (ctxt->instate == XML_PARSER_EOF)
8989
 
                    return(NULL);
8990
 
                if (oldbase != ctxt->input->base) {
8991
 
                    long delta = ctxt->input->base - oldbase;
8992
 
                    start = start + delta;
8993
 
                    in = in + delta;
8994
 
                }
8995
 
                end = ctxt->input->end;
8996
 
                if (((in - start) > XML_MAX_TEXT_LENGTH) &&
8997
 
                    ((ctxt->options & XML_PARSE_HUGE) == 0)) {
8998
 
                    xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
8999
 
                                   "AttValue length too long\n");
9000
 
                    return(NULL);
9001
 
                }
9002
 
            }
9003
 
        }
9004
 
        last = in;
9005
 
        /*
9006
 
         * skip the trailing blanks
9007
 
         */
9008
 
        while ((last[-1] == 0x20) && (last > start)) last--;
9009
 
        while ((in < end) && (*in != limit) &&
9010
 
               ((*in == 0x20) || (*in == 0x9) ||
9011
 
                (*in == 0xA) || (*in == 0xD))) {
9012
 
            in++;
9013
 
            if (in >= end) {
9014
 
                const xmlChar *oldbase = ctxt->input->base;
9015
 
                GROW;
9016
 
                if (ctxt->instate == XML_PARSER_EOF)
9017
 
                    return(NULL);
9018
 
                if (oldbase != ctxt->input->base) {
9019
 
                    long delta = ctxt->input->base - oldbase;
9020
 
                    start = start + delta;
9021
 
                    in = in + delta;
9022
 
                    last = last + delta;
9023
 
                }
9024
 
                end = ctxt->input->end;
9025
 
                if (((in - start) > XML_MAX_TEXT_LENGTH) &&
9026
 
                    ((ctxt->options & XML_PARSE_HUGE) == 0)) {
9027
 
                    xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
9028
 
                                   "AttValue length too long\n");
9029
 
                    return(NULL);
9030
 
                }
9031
 
            }
9032
 
        }
9033
 
        if (((in - start) > XML_MAX_TEXT_LENGTH) &&
9034
 
            ((ctxt->options & XML_PARSE_HUGE) == 0)) {
9035
 
            xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
9036
 
                           "AttValue length too long\n");
9037
 
            return(NULL);
9038
 
        }
9039
 
        if (*in != limit) goto need_complex;
9040
 
    } else {
9041
 
        while ((in < end) && (*in != limit) && (*in >= 0x20) &&
9042
 
               (*in <= 0x7f) && (*in != '&') && (*in != '<')) {
9043
 
            in++;
9044
 
            if (in >= end) {
9045
 
                const xmlChar *oldbase = ctxt->input->base;
9046
 
                GROW;
9047
 
                if (ctxt->instate == XML_PARSER_EOF)
9048
 
                    return(NULL);
9049
 
                if (oldbase != ctxt->input->base) {
9050
 
                    long delta = ctxt->input->base - oldbase;
9051
 
                    start = start + delta;
9052
 
                    in = in + delta;
9053
 
                }
9054
 
                end = ctxt->input->end;
9055
 
                if (((in - start) > XML_MAX_TEXT_LENGTH) &&
9056
 
                    ((ctxt->options & XML_PARSE_HUGE) == 0)) {
9057
 
                    xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
9058
 
                                   "AttValue length too long\n");
9059
 
                    return(NULL);
9060
 
                }
9061
 
            }
9062
 
        }
9063
 
        last = in;
9064
 
        if (((in - start) > XML_MAX_TEXT_LENGTH) &&
9065
 
            ((ctxt->options & XML_PARSE_HUGE) == 0)) {
9066
 
            xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
9067
 
                           "AttValue length too long\n");
9068
 
            return(NULL);
9069
 
        }
9070
 
        if (*in != limit) goto need_complex;
9071
 
    }
9072
 
    in++;
9073
 
    if (len != NULL) {
9074
 
        *len = last - start;
9075
 
        ret = (xmlChar *) start;
9076
 
    } else {
9077
 
        if (alloc) *alloc = 1;
9078
 
        ret = xmlStrndup(start, last - start);
9079
 
    }
9080
 
    CUR_PTR = in;
9081
 
    if (alloc) *alloc = 0;
9082
 
    return ret;
9083
 
need_complex:
9084
 
    if (alloc) *alloc = 1;
9085
 
    return xmlParseAttValueComplex(ctxt, len, normalize);
9086
 
}
9087
 
 
9088
 
/**
9089
 
 * xmlParseAttribute2:
9090
 
 * @ctxt:  an XML parser context
9091
 
 * @pref:  the element prefix
9092
 
 * @elem:  the element name
9093
 
 * @prefix:  a xmlChar ** used to store the value of the attribute prefix
9094
 
 * @value:  a xmlChar ** used to store the value of the attribute
9095
 
 * @len:  an int * to save the length of the attribute
9096
 
 * @alloc:  an int * to indicate if the attribute was allocated
9097
 
 *
9098
 
 * parse an attribute in the new SAX2 framework.
9099
 
 *
9100
 
 * Returns the attribute name, and the value in *value, .
9101
 
 */
9102
 
 
9103
 
static const xmlChar *
9104
 
xmlParseAttribute2(xmlParserCtxtPtr ctxt,
9105
 
                   const xmlChar * pref, const xmlChar * elem,
9106
 
                   const xmlChar ** prefix, xmlChar ** value,
9107
 
                   int *len, int *alloc)
9108
 
{
9109
 
    const xmlChar *name;
9110
 
    xmlChar *val, *internal_val = NULL;
9111
 
    int normalize = 0;
9112
 
 
9113
 
    *value = NULL;
9114
 
    GROW;
9115
 
    name = xmlParseQName(ctxt, prefix);
9116
 
    if (name == NULL) {
9117
 
        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
9118
 
                       "error parsing attribute name\n");
9119
 
        return (NULL);
9120
 
    }
9121
 
 
9122
 
    /*
9123
 
     * get the type if needed
9124
 
     */
9125
 
    if (ctxt->attsSpecial != NULL) {
9126
 
        int type;
9127
 
 
9128
 
        type = (int) (long) xmlHashQLookup2(ctxt->attsSpecial,
9129
 
                                            pref, elem, *prefix, name);
9130
 
        if (type != 0)
9131
 
            normalize = 1;
9132
 
    }
9133
 
 
9134
 
    /*
9135
 
     * read the value
9136
 
     */
9137
 
    SKIP_BLANKS;
9138
 
    if (RAW == '=') {
9139
 
        NEXT;
9140
 
        SKIP_BLANKS;
9141
 
        val = xmlParseAttValueInternal(ctxt, len, alloc, normalize);
9142
 
        if (normalize) {
9143
 
            /*
9144
 
             * Sometimes a second normalisation pass for spaces is needed
9145
 
             * but that only happens if charrefs or entities refernces
9146
 
             * have been used in the attribute value, i.e. the attribute
9147
 
             * value have been extracted in an allocated string already.
9148
 
             */
9149
 
            if (*alloc) {
9150
 
                const xmlChar *val2;
9151
 
 
9152
 
                val2 = xmlAttrNormalizeSpace2(ctxt, val, len);
9153
 
                if ((val2 != NULL) && (val2 != val)) {
9154
 
                    xmlFree(val);
9155
 
                    val = (xmlChar *) val2;
9156
 
                }
9157
 
            }
9158
 
        }
9159
 
        ctxt->instate = XML_PARSER_CONTENT;
9160
 
    } else {
9161
 
        xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
9162
 
                          "Specification mandate value for attribute %s\n",
9163
 
                          name);
9164
 
        return (NULL);
9165
 
    }
9166
 
 
9167
 
    if (*prefix == ctxt->str_xml) {
9168
 
        /*
9169
 
         * Check that xml:lang conforms to the specification
9170
 
         * No more registered as an error, just generate a warning now
9171
 
         * since this was deprecated in XML second edition
9172
 
         */
9173
 
        if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "lang"))) {
9174
 
            internal_val = xmlStrndup(val, *len);
9175
 
            if (!xmlCheckLanguageID(internal_val)) {
9176
 
                xmlWarningMsg(ctxt, XML_WAR_LANG_VALUE,
9177
 
                              "Malformed value for xml:lang : %s\n",
9178
 
                              internal_val, NULL);
9179
 
            }
9180
 
        }
9181
 
 
9182
 
        /*
9183
 
         * Check that xml:space conforms to the specification
9184
 
         */
9185
 
        if (xmlStrEqual(name, BAD_CAST "space")) {
9186
 
            internal_val = xmlStrndup(val, *len);
9187
 
            if (xmlStrEqual(internal_val, BAD_CAST "default"))
9188
 
                *(ctxt->space) = 0;
9189
 
            else if (xmlStrEqual(internal_val, BAD_CAST "preserve"))
9190
 
                *(ctxt->space) = 1;
9191
 
            else {
9192
 
                xmlWarningMsg(ctxt, XML_WAR_SPACE_VALUE,
9193
 
                              "Invalid value \"%s\" for xml:space : \"default\" or \"preserve\" expected\n",
9194
 
                              internal_val, NULL);
9195
 
            }
9196
 
        }
9197
 
        if (internal_val) {
9198
 
            xmlFree(internal_val);
9199
 
        }
9200
 
    }
9201
 
 
9202
 
    *value = val;
9203
 
    return (name);
9204
 
}
9205
 
/**
9206
 
 * xmlParseStartTag2:
9207
 
 * @ctxt:  an XML parser context
9208
 
 *
9209
 
 * parse a start of tag either for rule element or
9210
 
 * EmptyElement. In both case we don't parse the tag closing chars.
9211
 
 * This routine is called when running SAX2 parsing
9212
 
 *
9213
 
 * [40] STag ::= '<' Name (S Attribute)* S? '>'
9214
 
 *
9215
 
 * [ WFC: Unique Att Spec ]
9216
 
 * No attribute name may appear more than once in the same start-tag or
9217
 
 * empty-element tag.
9218
 
 *
9219
 
 * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
9220
 
 *
9221
 
 * [ WFC: Unique Att Spec ]
9222
 
 * No attribute name may appear more than once in the same start-tag or
9223
 
 * empty-element tag.
9224
 
 *
9225
 
 * With namespace:
9226
 
 *
9227
 
 * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
9228
 
 *
9229
 
 * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
9230
 
 *
9231
 
 * Returns the element name parsed
9232
 
 */
9233
 
 
9234
 
static const xmlChar *
9235
 
xmlParseStartTag2(xmlParserCtxtPtr ctxt, const xmlChar **pref,
9236
 
                  const xmlChar **URI, int *tlen) {
9237
 
    const xmlChar *localname;
9238
 
    const xmlChar *prefix;
9239
 
    const xmlChar *attname;
9240
 
    const xmlChar *aprefix;
9241
 
    const xmlChar *nsname;
9242
 
    xmlChar *attvalue;
9243
 
    const xmlChar **atts = ctxt->atts;
9244
 
    int maxatts = ctxt->maxatts;
9245
 
    int nratts, nbatts, nbdef;
9246
 
    int i, j, nbNs, attval, oldline, oldcol;
9247
 
    const xmlChar *base;
9248
 
    unsigned long cur;
9249
 
    int nsNr = ctxt->nsNr;
9250
 
 
9251
 
    if (RAW != '<') return(NULL);
9252
 
    NEXT1;
9253
 
 
9254
 
    /*
9255
 
     * NOTE: it is crucial with the SAX2 API to never call SHRINK beyond that
9256
 
     *       point since the attribute values may be stored as pointers to
9257
 
     *       the buffer and calling SHRINK would destroy them !
9258
 
     *       The Shrinking is only possible once the full set of attribute
9259
 
     *       callbacks have been done.
9260
 
     */
9261
 
reparse:
9262
 
    SHRINK;
9263
 
    base = ctxt->input->base;
9264
 
    cur = ctxt->input->cur - ctxt->input->base;
9265
 
    oldline = ctxt->input->line;
9266
 
    oldcol = ctxt->input->col;
9267
 
    nbatts = 0;
9268
 
    nratts = 0;
9269
 
    nbdef = 0;
9270
 
    nbNs = 0;
9271
 
    attval = 0;
9272
 
    /* Forget any namespaces added during an earlier parse of this element. */
9273
 
    ctxt->nsNr = nsNr;
9274
 
 
9275
 
    localname = xmlParseQName(ctxt, &prefix);
9276
 
    if (localname == NULL) {
9277
 
        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
9278
 
                       "StartTag: invalid element name\n");
9279
 
        return(NULL);
9280
 
    }
9281
 
    *tlen = ctxt->input->cur - ctxt->input->base - cur;
9282
 
 
9283
 
    /*
9284
 
     * Now parse the attributes, it ends up with the ending
9285
 
     *
9286
 
     * (S Attribute)* S?
9287
 
     */
9288
 
    SKIP_BLANKS;
9289
 
    GROW;
9290
 
    if (ctxt->input->base != base) goto base_changed;
9291
 
 
9292
 
    while (((RAW != '>') &&
9293
 
           ((RAW != '/') || (NXT(1) != '>')) &&
9294
 
           (IS_BYTE_CHAR(RAW))) && (ctxt->instate != XML_PARSER_EOF)) {
9295
 
        const xmlChar *q = CUR_PTR;
9296
 
        unsigned int cons = ctxt->input->consumed;
9297
 
        int len = -1, alloc = 0;
9298
 
 
9299
 
        attname = xmlParseAttribute2(ctxt, prefix, localname,
9300
 
                                     &aprefix, &attvalue, &len, &alloc);
9301
 
        if (ctxt->input->base != base) {
9302
 
            if ((attvalue != NULL) && (alloc != 0))
9303
 
                xmlFree(attvalue);
9304
 
            attvalue = NULL;
9305
 
            goto base_changed;
9306
 
        }
9307
 
        if ((attname != NULL) && (attvalue != NULL)) {
9308
 
            if (len < 0) len = xmlStrlen(attvalue);
9309
 
            if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
9310
 
                const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
9311
 
                xmlURIPtr uri;
9312
 
 
9313
 
                if (*URL != 0) {
9314
 
                    uri = xmlParseURI((const char *) URL);
9315
 
                    if (uri == NULL) {
9316
 
                        xmlNsErr(ctxt, XML_WAR_NS_URI,
9317
 
                                 "xmlns: '%s' is not a valid URI\n",
9318
 
                                           URL, NULL, NULL);
9319
 
                    } else {
9320
 
                        if (uri->scheme == NULL) {
9321
 
                            xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
9322
 
                                      "xmlns: URI %s is not absolute\n",
9323
 
                                      URL, NULL, NULL);
9324
 
                        }
9325
 
                        xmlFreeURI(uri);
9326
 
                    }
9327
 
                    if (URL == ctxt->str_xml_ns) {
9328
 
                        if (attname != ctxt->str_xml) {
9329
 
                            xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9330
 
                         "xml namespace URI cannot be the default namespace\n",
9331
 
                                     NULL, NULL, NULL);
9332
 
                        }
9333
 
                        goto skip_default_ns;
9334
 
                    }
9335
 
                    if ((len == 29) &&
9336
 
                        (xmlStrEqual(URL,
9337
 
                                 BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
9338
 
                        xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9339
 
                             "reuse of the xmlns namespace name is forbidden\n",
9340
 
                                 NULL, NULL, NULL);
9341
 
                        goto skip_default_ns;
9342
 
                    }
9343
 
                }
9344
 
                /*
9345
 
                 * check that it's not a defined namespace
9346
 
                 */
9347
 
                for (j = 1;j <= nbNs;j++)
9348
 
                    if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
9349
 
                        break;
9350
 
                if (j <= nbNs)
9351
 
                    xmlErrAttributeDup(ctxt, NULL, attname);
9352
 
                else
9353
 
                    if (nsPush(ctxt, NULL, URL) > 0) nbNs++;
9354
 
skip_default_ns:
9355
 
                if (alloc != 0) xmlFree(attvalue);
9356
 
                SKIP_BLANKS;
9357
 
                continue;
9358
 
            }
9359
 
            if (aprefix == ctxt->str_xmlns) {
9360
 
                const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
9361
 
                xmlURIPtr uri;
9362
 
 
9363
 
                if (attname == ctxt->str_xml) {
9364
 
                    if (URL != ctxt->str_xml_ns) {
9365
 
                        xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9366
 
                                 "xml namespace prefix mapped to wrong URI\n",
9367
 
                                 NULL, NULL, NULL);
9368
 
                    }
9369
 
                    /*
9370
 
                     * Do not keep a namespace definition node
9371
 
                     */
9372
 
                    goto skip_ns;
9373
 
                }
9374
 
                if (URL == ctxt->str_xml_ns) {
9375
 
                    if (attname != ctxt->str_xml) {
9376
 
                        xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9377
 
                                 "xml namespace URI mapped to wrong prefix\n",
9378
 
                                 NULL, NULL, NULL);
9379
 
                    }
9380
 
                    goto skip_ns;
9381
 
                }
9382
 
                if (attname == ctxt->str_xmlns) {
9383
 
                    xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9384
 
                             "redefinition of the xmlns prefix is forbidden\n",
9385
 
                             NULL, NULL, NULL);
9386
 
                    goto skip_ns;
9387
 
                }
9388
 
                if ((len == 29) &&
9389
 
                    (xmlStrEqual(URL,
9390
 
                                 BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
9391
 
                    xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9392
 
                             "reuse of the xmlns namespace name is forbidden\n",
9393
 
                             NULL, NULL, NULL);
9394
 
                    goto skip_ns;
9395
 
                }
9396
 
                if ((URL == NULL) || (URL[0] == 0)) {
9397
 
                    xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9398
 
                             "xmlns:%s: Empty XML namespace is not allowed\n",
9399
 
                                  attname, NULL, NULL);
9400
 
                    goto skip_ns;
9401
 
                } else {
9402
 
                    uri = xmlParseURI((const char *) URL);
9403
 
                    if (uri == NULL) {
9404
 
                        xmlNsErr(ctxt, XML_WAR_NS_URI,
9405
 
                             "xmlns:%s: '%s' is not a valid URI\n",
9406
 
                                           attname, URL, NULL);
9407
 
                    } else {
9408
 
                        if ((ctxt->pedantic) && (uri->scheme == NULL)) {
9409
 
                            xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
9410
 
                                      "xmlns:%s: URI %s is not absolute\n",
9411
 
                                      attname, URL, NULL);
9412
 
                        }
9413
 
                        xmlFreeURI(uri);
9414
 
                    }
9415
 
                }
9416
 
 
9417
 
                /*
9418
 
                 * check that it's not a defined namespace
9419
 
                 */
9420
 
                for (j = 1;j <= nbNs;j++)
9421
 
                    if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
9422
 
                        break;
9423
 
                if (j <= nbNs)
9424
 
                    xmlErrAttributeDup(ctxt, aprefix, attname);
9425
 
                else
9426
 
                    if (nsPush(ctxt, attname, URL) > 0) nbNs++;
9427
 
skip_ns:
9428
 
                if (alloc != 0) xmlFree(attvalue);
9429
 
                SKIP_BLANKS;
9430
 
                if (ctxt->input->base != base) goto base_changed;
9431
 
                continue;
9432
 
            }
9433
 
 
9434
 
            /*
9435
 
             * Add the pair to atts
9436
 
             */
9437
 
            if ((atts == NULL) || (nbatts + 5 > maxatts)) {
9438
 
                if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
9439
 
                    if (attvalue[len] == 0)
9440
 
                        xmlFree(attvalue);
9441
 
                    goto failed;
9442
 
                }
9443
 
                maxatts = ctxt->maxatts;
9444
 
                atts = ctxt->atts;
9445
 
            }
9446
 
            ctxt->attallocs[nratts++] = alloc;
9447
 
            atts[nbatts++] = attname;
9448
 
            atts[nbatts++] = aprefix;
9449
 
            atts[nbatts++] = NULL; /* the URI will be fetched later */
9450
 
            atts[nbatts++] = attvalue;
9451
 
            attvalue += len;
9452
 
            atts[nbatts++] = attvalue;
9453
 
            /*
9454
 
             * tag if some deallocation is needed
9455
 
             */
9456
 
            if (alloc != 0) attval = 1;
9457
 
        } else {
9458
 
            if ((attvalue != NULL) && (attvalue[len] == 0))
9459
 
                xmlFree(attvalue);
9460
 
        }
9461
 
 
9462
 
failed:
9463
 
 
9464
 
        GROW
9465
 
        if (ctxt->instate == XML_PARSER_EOF)
9466
 
            break;
9467
 
        if (ctxt->input->base != base) goto base_changed;
9468
 
        if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
9469
 
            break;
9470
 
        if (!IS_BLANK_CH(RAW)) {
9471
 
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
9472
 
                           "attributes construct error\n");
9473
 
            break;
9474
 
        }
9475
 
        SKIP_BLANKS;
9476
 
        if ((cons == ctxt->input->consumed) && (q == CUR_PTR) &&
9477
 
            (attname == NULL) && (attvalue == NULL)) {
9478
 
            xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
9479
 
                 "xmlParseStartTag: problem parsing attributes\n");
9480
 
            break;
9481
 
        }
9482
 
        GROW;
9483
 
        if (ctxt->input->base != base) goto base_changed;
9484
 
    }
9485
 
 
9486
 
    /*
9487
 
     * The attributes defaulting
9488
 
     */
9489
 
    if (ctxt->attsDefault != NULL) {
9490
 
        xmlDefAttrsPtr defaults;
9491
 
 
9492
 
        defaults = xmlHashLookup2(ctxt->attsDefault, localname, prefix);
9493
 
        if (defaults != NULL) {
9494
 
            for (i = 0;i < defaults->nbAttrs;i++) {
9495
 
                attname = defaults->values[5 * i];
9496
 
                aprefix = defaults->values[5 * i + 1];
9497
 
 
9498
 
                /*
9499
 
                 * special work for namespaces defaulted defs
9500
 
                 */
9501
 
                if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
9502
 
                    /*
9503
 
                     * check that it's not a defined namespace
9504
 
                     */
9505
 
                    for (j = 1;j <= nbNs;j++)
9506
 
                        if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
9507
 
                            break;
9508
 
                    if (j <= nbNs) continue;
9509
 
 
9510
 
                    nsname = xmlGetNamespace(ctxt, NULL);
9511
 
                    if (nsname != defaults->values[5 * i + 2]) {
9512
 
                        if (nsPush(ctxt, NULL,
9513
 
                                   defaults->values[5 * i + 2]) > 0)
9514
 
                            nbNs++;
9515
 
                    }
9516
 
                } else if (aprefix == ctxt->str_xmlns) {
9517
 
                    /*
9518
 
                     * check that it's not a defined namespace
9519
 
                     */
9520
 
                    for (j = 1;j <= nbNs;j++)
9521
 
                        if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
9522
 
                            break;
9523
 
                    if (j <= nbNs) continue;
9524
 
 
9525
 
                    nsname = xmlGetNamespace(ctxt, attname);
9526
 
                    if (nsname != defaults->values[2]) {
9527
 
                        if (nsPush(ctxt, attname,
9528
 
                                   defaults->values[5 * i + 2]) > 0)
9529
 
                            nbNs++;
9530
 
                    }
9531
 
                } else {
9532
 
                    /*
9533
 
                     * check that it's not a defined attribute
9534
 
                     */
9535
 
                    for (j = 0;j < nbatts;j+=5) {
9536
 
                        if ((attname == atts[j]) && (aprefix == atts[j+1]))
9537
 
                            break;
9538
 
                    }
9539
 
                    if (j < nbatts) continue;
9540
 
 
9541
 
                    if ((atts == NULL) || (nbatts + 5 > maxatts)) {
9542
 
                        if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
9543
 
                            return(NULL);
9544
 
                        }
9545
 
                        maxatts = ctxt->maxatts;
9546
 
                        atts = ctxt->atts;
9547
 
                    }
9548
 
                    atts[nbatts++] = attname;
9549
 
                    atts[nbatts++] = aprefix;
9550
 
                    if (aprefix == NULL)
9551
 
                        atts[nbatts++] = NULL;
9552
 
                    else
9553
 
                        atts[nbatts++] = xmlGetNamespace(ctxt, aprefix);
9554
 
                    atts[nbatts++] = defaults->values[5 * i + 2];
9555
 
                    atts[nbatts++] = defaults->values[5 * i + 3];
9556
 
                    if ((ctxt->standalone == 1) &&
9557
 
                        (defaults->values[5 * i + 4] != NULL)) {
9558
 
                        xmlValidityError(ctxt, XML_DTD_STANDALONE_DEFAULTED,
9559
 
          "standalone: attribute %s on %s defaulted from external subset\n",
9560
 
                                         attname, localname);
9561
 
                    }
9562
 
                    nbdef++;
9563
 
                }
9564
 
            }
9565
 
        }
9566
 
    }
9567
 
 
9568
 
    /*
9569
 
     * The attributes checkings
9570
 
     */
9571
 
    for (i = 0; i < nbatts;i += 5) {
9572
 
        /*
9573
 
        * The default namespace does not apply to attribute names.
9574
 
        */
9575
 
        if (atts[i + 1] != NULL) {
9576
 
            nsname = xmlGetNamespace(ctxt, atts[i + 1]);
9577
 
            if (nsname == NULL) {
9578
 
                xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
9579
 
                    "Namespace prefix %s for %s on %s is not defined\n",
9580
 
                    atts[i + 1], atts[i], localname);
9581
 
            }
9582
 
            atts[i + 2] = nsname;
9583
 
        } else
9584
 
            nsname = NULL;
9585
 
        /*
9586
 
         * [ WFC: Unique Att Spec ]
9587
 
         * No attribute name may appear more than once in the same
9588
 
         * start-tag or empty-element tag.
9589
 
         * As extended by the Namespace in XML REC.
9590
 
         */
9591
 
        for (j = 0; j < i;j += 5) {
9592
 
            if (atts[i] == atts[j]) {
9593
 
                if (atts[i+1] == atts[j+1]) {
9594
 
                    xmlErrAttributeDup(ctxt, atts[i+1], atts[i]);
9595
 
                    break;
9596
 
                }
9597
 
                if ((nsname != NULL) && (atts[j + 2] == nsname)) {
9598
 
                    xmlNsErr(ctxt, XML_NS_ERR_ATTRIBUTE_REDEFINED,
9599
 
                             "Namespaced Attribute %s in '%s' redefined\n",
9600
 
                             atts[i], nsname, NULL);
9601
 
                    break;
9602
 
                }
9603
 
            }
9604
 
        }
9605
 
    }
9606
 
 
9607
 
    nsname = xmlGetNamespace(ctxt, prefix);
9608
 
    if ((prefix != NULL) && (nsname == NULL)) {
9609
 
        xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
9610
 
                 "Namespace prefix %s on %s is not defined\n",
9611
 
                 prefix, localname, NULL);
9612
 
    }
9613
 
    *pref = prefix;
9614
 
    *URI = nsname;
9615
 
 
9616
 
    /*
9617
 
     * SAX: Start of Element !
9618
 
     */
9619
 
    if ((ctxt->sax != NULL) && (ctxt->sax->startElementNs != NULL) &&
9620
 
        (!ctxt->disableSAX)) {
9621
 
        if (nbNs > 0)
9622
 
            ctxt->sax->startElementNs(ctxt->userData, localname, prefix,
9623
 
                          nsname, nbNs, &ctxt->nsTab[ctxt->nsNr - 2 * nbNs],
9624
 
                          nbatts / 5, nbdef, atts);
9625
 
        else
9626
 
            ctxt->sax->startElementNs(ctxt->userData, localname, prefix,
9627
 
                          nsname, 0, NULL, nbatts / 5, nbdef, atts);
9628
 
    }
9629
 
 
9630
 
    /*
9631
 
     * Free up attribute allocated strings if needed
9632
 
     */
9633
 
    if (attval != 0) {
9634
 
        for (i = 3,j = 0; j < nratts;i += 5,j++)
9635
 
            if ((ctxt->attallocs[j] != 0) && (atts[i] != NULL))
9636
 
                xmlFree((xmlChar *) atts[i]);
9637
 
    }
9638
 
 
9639
 
    return(localname);
9640
 
 
9641
 
base_changed:
9642
 
    /*
9643
 
     * the attribute strings are valid iif the base didn't changed
9644
 
     */
9645
 
    if (attval != 0) {
9646
 
        for (i = 3,j = 0; j < nratts;i += 5,j++)
9647
 
            if ((ctxt->attallocs[j] != 0) && (atts[i] != NULL))
9648
 
                xmlFree((xmlChar *) atts[i]);
9649
 
    }
9650
 
    ctxt->input->cur = ctxt->input->base + cur;
9651
 
    ctxt->input->line = oldline;
9652
 
    ctxt->input->col = oldcol;
9653
 
    if (ctxt->wellFormed == 1) {
9654
 
        goto reparse;
9655
 
    }
9656
 
    return(NULL);
9657
 
}
9658
 
 
9659
 
/**
9660
 
 * xmlParseEndTag2:
9661
 
 * @ctxt:  an XML parser context
9662
 
 * @line:  line of the start tag
9663
 
 * @nsNr:  number of namespaces on the start tag
9664
 
 *
9665
 
 * parse an end of tag
9666
 
 *
9667
 
 * [42] ETag ::= '</' Name S? '>'
9668
 
 *
9669
 
 * With namespace
9670
 
 *
9671
 
 * [NS 9] ETag ::= '</' QName S? '>'
9672
 
 */
9673
 
 
9674
 
static void
9675
 
xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlChar *prefix,
9676
 
                const xmlChar *URI, int line, int nsNr, int tlen) {
9677
 
    const xmlChar *name;
9678
 
 
9679
 
    GROW;
9680
 
    if ((RAW != '<') || (NXT(1) != '/')) {
9681
 
        xmlFatalErr(ctxt, XML_ERR_LTSLASH_REQUIRED, NULL);
9682
 
        return;
9683
 
    }
9684
 
    SKIP(2);
9685
 
 
9686
 
    if ((tlen > 0) && (xmlStrncmp(ctxt->input->cur, ctxt->name, tlen) == 0)) {
9687
 
        if (ctxt->input->cur[tlen] == '>') {
9688
 
            ctxt->input->cur += tlen + 1;
9689
 
            goto done;
9690
 
        }
9691
 
        ctxt->input->cur += tlen;
9692
 
        name = (xmlChar*)1;
9693
 
    } else {
9694
 
        if (prefix == NULL)
9695
 
            name = xmlParseNameAndCompare(ctxt, ctxt->name);
9696
 
        else
9697
 
            name = xmlParseQNameAndCompare(ctxt, ctxt->name, prefix);
9698
 
    }
9699
 
 
9700
 
    /*
9701
 
     * We should definitely be at the ending "S? '>'" part
9702
 
     */
9703
 
    GROW;
9704
 
    if (ctxt->instate == XML_PARSER_EOF)
9705
 
        return;
9706
 
    SKIP_BLANKS;
9707
 
    if ((!IS_BYTE_CHAR(RAW)) || (RAW != '>')) {
9708
 
        xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
9709
 
    } else
9710
 
        NEXT1;
9711
 
 
9712
 
    /*
9713
 
     * [ WFC: Element Type Match ]
9714
 
     * The Name in an element's end-tag must match the element type in the
9715
 
     * start-tag.
9716
 
     *
9717
 
     */
9718
 
    if (name != (xmlChar*)1) {
9719
 
        if (name == NULL) name = BAD_CAST "unparseable";
9720
 
        if ((line == 0) && (ctxt->node != NULL))
9721
 
            line = ctxt->node->line;
9722
 
        xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
9723
 
                     "Opening and ending tag mismatch: %s line %d and %s\n",
9724
 
                                ctxt->name, line, name);
9725
 
    }
9726
 
 
9727
 
    /*
9728
 
     * SAX: End of Tag
9729
 
     */
9730
 
done:
9731
 
    if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
9732
 
        (!ctxt->disableSAX))
9733
 
        ctxt->sax->endElementNs(ctxt->userData, ctxt->name, prefix, URI);
9734
 
 
9735
 
    spacePop(ctxt);
9736
 
    if (nsNr != 0)
9737
 
        nsPop(ctxt, nsNr);
9738
 
    return;
9739
 
}
9740
 
 
9741
 
/**
9742
 
 * xmlParseCDSect:
9743
 
 * @ctxt:  an XML parser context
9744
 
 *
9745
 
 * Parse escaped pure raw content.
9746
 
 *
9747
 
 * [18] CDSect ::= CDStart CData CDEnd
9748
 
 *
9749
 
 * [19] CDStart ::= '<![CDATA['
9750
 
 *
9751
 
 * [20] Data ::= (Char* - (Char* ']]>' Char*))
9752
 
 *
9753
 
 * [21] CDEnd ::= ']]>'
9754
 
 */
9755
 
void
9756
 
xmlParseCDSect(xmlParserCtxtPtr ctxt) {
9757
 
    xmlChar *buf = NULL;
9758
 
    int len = 0;
9759
 
    int size = XML_PARSER_BUFFER_SIZE;
9760
 
    int r, rl;
9761
 
    int s, sl;
9762
 
    int cur, l;
9763
 
    int count = 0;
9764
 
 
9765
 
    /* Check 2.6.0 was NXT(0) not RAW */
9766
 
    if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) {
9767
 
        SKIP(9);
9768
 
    } else
9769
 
        return;
9770
 
 
9771
 
    ctxt->instate = XML_PARSER_CDATA_SECTION;
9772
 
    r = CUR_CHAR(rl);
9773
 
    if (!IS_CHAR(r)) {
9774
 
        xmlFatalErr(ctxt, XML_ERR_CDATA_NOT_FINISHED, NULL);
9775
 
        ctxt->instate = XML_PARSER_CONTENT;
9776
 
        return;
9777
 
    }
9778
 
    NEXTL(rl);
9779
 
    s = CUR_CHAR(sl);
9780
 
    if (!IS_CHAR(s)) {
9781
 
        xmlFatalErr(ctxt, XML_ERR_CDATA_NOT_FINISHED, NULL);
9782
 
        ctxt->instate = XML_PARSER_CONTENT;
9783
 
        return;
9784
 
    }
9785
 
    NEXTL(sl);
9786
 
    cur = CUR_CHAR(l);
9787
 
    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
9788
 
    if (buf == NULL) {
9789
 
        xmlErrMemory(ctxt, NULL);
9790
 
        return;
9791
 
    }
9792
 
    while (IS_CHAR(cur) &&
9793
 
           ((r != ']') || (s != ']') || (cur != '>'))) {
9794
 
        if (len + 5 >= size) {
9795
 
            xmlChar *tmp;
9796
 
 
9797
 
            if ((size > XML_MAX_TEXT_LENGTH) &&
9798
 
                ((ctxt->options & XML_PARSE_HUGE) == 0)) {
9799
 
                xmlFatalErrMsgStr(ctxt, XML_ERR_CDATA_NOT_FINISHED,
9800
 
                             "CData section too big found", NULL);
9801
 
                xmlFree (buf);
9802
 
                return;
9803
 
            }
9804
 
            tmp = (xmlChar *) xmlRealloc(buf, size * 2 * sizeof(xmlChar));
9805
 
            if (tmp == NULL) {
9806
 
                xmlFree(buf);
9807
 
                xmlErrMemory(ctxt, NULL);
9808
 
                return;
9809
 
            }
9810
 
            buf = tmp;
9811
 
            size *= 2;
9812
 
        }
9813
 
        COPY_BUF(rl,buf,len,r);
9814
 
        r = s;
9815
 
        rl = sl;
9816
 
        s = cur;
9817
 
        sl = l;
9818
 
        count++;
9819
 
        if (count > 50) {
9820
 
            GROW;
9821
 
            if (ctxt->instate == XML_PARSER_EOF) {
9822
 
                xmlFree(buf);
9823
 
                return;
9824
 
            }
9825
 
            count = 0;
9826
 
        }
9827
 
        NEXTL(l);
9828
 
        cur = CUR_CHAR(l);
9829
 
    }
9830
 
    buf[len] = 0;
9831
 
    ctxt->instate = XML_PARSER_CONTENT;
9832
 
    if (cur != '>') {
9833
 
        xmlFatalErrMsgStr(ctxt, XML_ERR_CDATA_NOT_FINISHED,
9834
 
                             "CData section not finished\n%.50s\n", buf);
9835
 
        xmlFree(buf);
9836
 
        return;
9837
 
    }
9838
 
    NEXTL(l);
9839
 
 
9840
 
    /*
9841
 
     * OK the buffer is to be consumed as cdata.
9842
 
     */
9843
 
    if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
9844
 
        if (ctxt->sax->cdataBlock != NULL)
9845
 
            ctxt->sax->cdataBlock(ctxt->userData, buf, len);
9846
 
        else if (ctxt->sax->characters != NULL)
9847
 
            ctxt->sax->characters(ctxt->userData, buf, len);
9848
 
    }
9849
 
    xmlFree(buf);
9850
 
}
9851
 
 
9852
 
/**
9853
 
 * xmlParseContent:
9854
 
 * @ctxt:  an XML parser context
9855
 
 *
9856
 
 * Parse a content:
9857
 
 *
9858
 
 * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
9859
 
 */
9860
 
 
9861
 
void
9862
 
xmlParseContent(xmlParserCtxtPtr ctxt) {
9863
 
    GROW;
9864
 
    while ((RAW != 0) &&
9865
 
           ((RAW != '<') || (NXT(1) != '/')) &&
9866
 
           (ctxt->instate != XML_PARSER_EOF)) {
9867
 
        const xmlChar *test = CUR_PTR;
9868
 
        unsigned int cons = ctxt->input->consumed;
9869
 
        const xmlChar *cur = ctxt->input->cur;
9870
 
 
9871
 
        /*
9872
 
         * First case : a Processing Instruction.
9873
 
         */
9874
 
        if ((*cur == '<') && (cur[1] == '?')) {
9875
 
            xmlParsePI(ctxt);
9876
 
        }
9877
 
 
9878
 
        /*
9879
 
         * Second case : a CDSection
9880
 
         */
9881
 
        /* 2.6.0 test was *cur not RAW */
9882
 
        else if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) {
9883
 
            xmlParseCDSect(ctxt);
9884
 
        }
9885
 
 
9886
 
        /*
9887
 
         * Third case :  a comment
9888
 
         */
9889
 
        else if ((*cur == '<') && (NXT(1) == '!') &&
9890
 
                 (NXT(2) == '-') && (NXT(3) == '-')) {
9891
 
            xmlParseComment(ctxt);
9892
 
            ctxt->instate = XML_PARSER_CONTENT;
9893
 
        }
9894
 
 
9895
 
        /*
9896
 
         * Fourth case :  a sub-element.
9897
 
         */
9898
 
        else if (*cur == '<') {
9899
 
            xmlParseElement(ctxt);
9900
 
        }
9901
 
 
9902
 
        /*
9903
 
         * Fifth case : a reference. If if has not been resolved,
9904
 
         *    parsing returns it's Name, create the node
9905
 
         */
9906
 
 
9907
 
        else if (*cur == '&') {
9908
 
            xmlParseReference(ctxt);
9909
 
        }
9910
 
 
9911
 
        /*
9912
 
         * Last case, text. Note that References are handled directly.
9913
 
         */
9914
 
        else {
9915
 
            xmlParseCharData(ctxt, 0);
9916
 
        }
9917
 
 
9918
 
        GROW;
9919
 
        /*
9920
 
         * Pop-up of finished entities.
9921
 
         */
9922
 
        while ((RAW == 0) && (ctxt->inputNr > 1))
9923
 
            xmlPopInput(ctxt);
9924
 
        SHRINK;
9925
 
 
9926
 
        if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
9927
 
            xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
9928
 
                        "detected an error in element content\n");
9929
 
            ctxt->instate = XML_PARSER_EOF;
9930
 
            break;
9931
 
        }
9932
 
    }
9933
 
}
9934
 
 
9935
 
/**
9936
 
 * xmlParseElement:
9937
 
 * @ctxt:  an XML parser context
9938
 
 *
9939
 
 * parse an XML element, this is highly recursive
9940
 
 *
9941
 
 * [39] element ::= EmptyElemTag | STag content ETag
9942
 
 *
9943
 
 * [ WFC: Element Type Match ]
9944
 
 * The Name in an element's end-tag must match the element type in the
9945
 
 * start-tag.
9946
 
 *
9947
 
 */
9948
 
 
9949
 
void
9950
 
xmlParseElement(xmlParserCtxtPtr ctxt) {
9951
 
    const xmlChar *name;
9952
 
    const xmlChar *prefix = NULL;
9953
 
    const xmlChar *URI = NULL;
9954
 
    xmlParserNodeInfo node_info;
9955
 
    int line, tlen = 0;
9956
 
    xmlNodePtr ret;
9957
 
    int nsNr = ctxt->nsNr;
9958
 
 
9959
 
    if (((unsigned int) ctxt->nameNr > xmlParserMaxDepth) &&
9960
 
        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
9961
 
        xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
9962
 
                 "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
9963
 
                          xmlParserMaxDepth);
9964
 
        ctxt->instate = XML_PARSER_EOF;
9965
 
        return;
9966
 
    }
9967
 
 
9968
 
    /* Capture start position */
9969
 
    if (ctxt->record_info) {
9970
 
        node_info.begin_pos = ctxt->input->consumed +
9971
 
                          (CUR_PTR - ctxt->input->base);
9972
 
        node_info.begin_line = ctxt->input->line;
9973
 
    }
9974
 
 
9975
 
    if (ctxt->spaceNr == 0)
9976
 
        spacePush(ctxt, -1);
9977
 
    else if (*ctxt->space == -2)
9978
 
        spacePush(ctxt, -1);
9979
 
    else
9980
 
        spacePush(ctxt, *ctxt->space);
9981
 
 
9982
 
    line = ctxt->input->line;
9983
 
#ifdef LIBXML_SAX1_ENABLED
9984
 
    if (ctxt->sax2)
9985
 
#endif /* LIBXML_SAX1_ENABLED */
9986
 
        name = xmlParseStartTag2(ctxt, &prefix, &URI, &tlen);
9987
 
#ifdef LIBXML_SAX1_ENABLED
9988
 
    else
9989
 
        name = xmlParseStartTag(ctxt);
9990
 
#endif /* LIBXML_SAX1_ENABLED */
9991
 
    if (ctxt->instate == XML_PARSER_EOF)
9992
 
        return;
9993
 
    if (name == NULL) {
9994
 
        spacePop(ctxt);
9995
 
        return;
9996
 
    }
9997
 
    namePush(ctxt, name);
9998
 
    ret = ctxt->node;
9999
 
 
10000
 
#ifdef LIBXML_VALID_ENABLED
10001
 
    /*
10002
 
     * [ VC: Root Element Type ]
10003
 
     * The Name in the document type declaration must match the element
10004
 
     * type of the root element.
10005
 
     */
10006
 
    if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
10007
 
        ctxt->node && (ctxt->node == ctxt->myDoc->children))
10008
 
        ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
10009
 
#endif /* LIBXML_VALID_ENABLED */
10010
 
 
10011
 
    /*
10012
 
     * Check for an Empty Element.
10013
 
     */
10014
 
    if ((RAW == '/') && (NXT(1) == '>')) {
10015
 
        SKIP(2);
10016
 
        if (ctxt->sax2) {
10017
 
            if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
10018
 
                (!ctxt->disableSAX))
10019
 
                ctxt->sax->endElementNs(ctxt->userData, name, prefix, URI);
10020
 
#ifdef LIBXML_SAX1_ENABLED
10021
 
        } else {
10022
 
            if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
10023
 
                (!ctxt->disableSAX))
10024
 
                ctxt->sax->endElement(ctxt->userData, name);
10025
 
#endif /* LIBXML_SAX1_ENABLED */
10026
 
        }
10027
 
        namePop(ctxt);
10028
 
        spacePop(ctxt);
10029
 
        if (nsNr != ctxt->nsNr)
10030
 
            nsPop(ctxt, ctxt->nsNr - nsNr);
10031
 
        if ( ret != NULL && ctxt->record_info ) {
10032
 
           node_info.end_pos = ctxt->input->consumed +
10033
 
                              (CUR_PTR - ctxt->input->base);
10034
 
           node_info.end_line = ctxt->input->line;
10035
 
           node_info.node = ret;
10036
 
           xmlParserAddNodeInfo(ctxt, &node_info);
10037
 
        }
10038
 
        return;
10039
 
    }
10040
 
    if (RAW == '>') {
10041
 
        NEXT1;
10042
 
    } else {
10043
 
        xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_GT_REQUIRED,
10044
 
                     "Couldn't find end of Start Tag %s line %d\n",
10045
 
                                name, line, NULL);
10046
 
 
10047
 
        /*
10048
 
         * end of parsing of this node.
10049
 
         */
10050
 
        nodePop(ctxt);
10051
 
        namePop(ctxt);
10052
 
        spacePop(ctxt);
10053
 
        if (nsNr != ctxt->nsNr)
10054
 
            nsPop(ctxt, ctxt->nsNr - nsNr);
10055
 
 
10056
 
        /*
10057
 
         * Capture end position and add node
10058
 
         */
10059
 
        if ( ret != NULL && ctxt->record_info ) {
10060
 
           node_info.end_pos = ctxt->input->consumed +
10061
 
                              (CUR_PTR - ctxt->input->base);
10062
 
           node_info.end_line = ctxt->input->line;
10063
 
           node_info.node = ret;
10064
 
           xmlParserAddNodeInfo(ctxt, &node_info);
10065
 
        }
10066
 
        return;
10067
 
    }
10068
 
 
10069
 
    /*
10070
 
     * Parse the content of the element:
10071
 
     */
10072
 
    xmlParseContent(ctxt);
10073
 
    if (ctxt->instate == XML_PARSER_EOF)
10074
 
        return;
10075
 
    if (!IS_BYTE_CHAR(RAW)) {
10076
 
        xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
10077
 
         "Premature end of data in tag %s line %d\n",
10078
 
                                name, line, NULL);
10079
 
 
10080
 
        /*
10081
 
         * end of parsing of this node.
10082
 
         */
10083
 
        nodePop(ctxt);
10084
 
        namePop(ctxt);
10085
 
        spacePop(ctxt);
10086
 
        if (nsNr != ctxt->nsNr)
10087
 
            nsPop(ctxt, ctxt->nsNr - nsNr);
10088
 
        return;
10089
 
    }
10090
 
 
10091
 
    /*
10092
 
     * parse the end of tag: '</' should be here.
10093
 
     */
10094
 
    if (ctxt->sax2) {
10095
 
        xmlParseEndTag2(ctxt, prefix, URI, line, ctxt->nsNr - nsNr, tlen);
10096
 
        namePop(ctxt);
10097
 
    }
10098
 
#ifdef LIBXML_SAX1_ENABLED
10099
 
      else
10100
 
        xmlParseEndTag1(ctxt, line);
10101
 
#endif /* LIBXML_SAX1_ENABLED */
10102
 
 
10103
 
    /*
10104
 
     * Capture end position and add node
10105
 
     */
10106
 
    if ( ret != NULL && ctxt->record_info ) {
10107
 
       node_info.end_pos = ctxt->input->consumed +
10108
 
                          (CUR_PTR - ctxt->input->base);
10109
 
       node_info.end_line = ctxt->input->line;
10110
 
       node_info.node = ret;
10111
 
       xmlParserAddNodeInfo(ctxt, &node_info);
10112
 
    }
10113
 
}
10114
 
 
10115
 
/**
10116
 
 * xmlParseVersionNum:
10117
 
 * @ctxt:  an XML parser context
10118
 
 *
10119
 
 * parse the XML version value.
10120
 
 *
10121
 
 * [26] VersionNum ::= '1.' [0-9]+
10122
 
 *
10123
 
 * In practice allow [0-9].[0-9]+ at that level
10124
 
 *
10125
 
 * Returns the string giving the XML version number, or NULL
10126
 
 */
10127
 
xmlChar *
10128
 
xmlParseVersionNum(xmlParserCtxtPtr ctxt) {
10129
 
    xmlChar *buf = NULL;
10130
 
    int len = 0;
10131
 
    int size = 10;
10132
 
    xmlChar cur;
10133
 
 
10134
 
    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
10135
 
    if (buf == NULL) {
10136
 
        xmlErrMemory(ctxt, NULL);
10137
 
        return(NULL);
10138
 
    }
10139
 
    cur = CUR;
10140
 
    if (!((cur >= '0') && (cur <= '9'))) {
10141
 
        xmlFree(buf);
10142
 
        return(NULL);
10143
 
    }
10144
 
    buf[len++] = cur;
10145
 
    NEXT;
10146
 
    cur=CUR;
10147
 
    if (cur != '.') {
10148
 
        xmlFree(buf);
10149
 
        return(NULL);
10150
 
    }
10151
 
    buf[len++] = cur;
10152
 
    NEXT;
10153
 
    cur=CUR;
10154
 
    while ((cur >= '0') && (cur <= '9')) {
10155
 
        if (len + 1 >= size) {
10156
 
            xmlChar *tmp;
10157
 
 
10158
 
            size *= 2;
10159
 
            tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
10160
 
            if (tmp == NULL) {
10161
 
                xmlFree(buf);
10162
 
                xmlErrMemory(ctxt, NULL);
10163
 
                return(NULL);
10164
 
            }
10165
 
            buf = tmp;
10166
 
        }
10167
 
        buf[len++] = cur;
10168
 
        NEXT;
10169
 
        cur=CUR;
10170
 
    }
10171
 
    buf[len] = 0;
10172
 
    return(buf);
10173
 
}
10174
 
 
10175
 
/**
10176
 
 * xmlParseVersionInfo:
10177
 
 * @ctxt:  an XML parser context
10178
 
 *
10179
 
 * parse the XML version.
10180
 
 *
10181
 
 * [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
10182
 
 *
10183
 
 * [25] Eq ::= S? '=' S?
10184
 
 *
10185
 
 * Returns the version string, e.g. "1.0"
10186
 
 */
10187
 
 
10188
 
xmlChar *
10189
 
xmlParseVersionInfo(xmlParserCtxtPtr ctxt) {
10190
 
    xmlChar *version = NULL;
10191
 
 
10192
 
    if (CMP7(CUR_PTR, 'v', 'e', 'r', 's', 'i', 'o', 'n')) {
10193
 
        SKIP(7);
10194
 
        SKIP_BLANKS;
10195
 
        if (RAW != '=') {
10196
 
            xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
10197
 
            return(NULL);
10198
 
        }
10199
 
        NEXT;
10200
 
        SKIP_BLANKS;
10201
 
        if (RAW == '"') {
10202
 
            NEXT;
10203
 
            version = xmlParseVersionNum(ctxt);
10204
 
            if (RAW != '"') {
10205
 
                xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10206
 
            } else
10207
 
                NEXT;
10208
 
        } else if (RAW == '\''){
10209
 
            NEXT;
10210
 
            version = xmlParseVersionNum(ctxt);
10211
 
            if (RAW != '\'') {
10212
 
                xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10213
 
            } else
10214
 
                NEXT;
10215
 
        } else {
10216
 
            xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
10217
 
        }
10218
 
    }
10219
 
    return(version);
10220
 
}
10221
 
 
10222
 
/**
10223
 
 * xmlParseEncName:
10224
 
 * @ctxt:  an XML parser context
10225
 
 *
10226
 
 * parse the XML encoding name
10227
 
 *
10228
 
 * [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
10229
 
 *
10230
 
 * Returns the encoding name value or NULL
10231
 
 */
10232
 
xmlChar *
10233
 
xmlParseEncName(xmlParserCtxtPtr ctxt) {
10234
 
    xmlChar *buf = NULL;
10235
 
    int len = 0;
10236
 
    int size = 10;
10237
 
    xmlChar cur;
10238
 
 
10239
 
    cur = CUR;
10240
 
    if (((cur >= 'a') && (cur <= 'z')) ||
10241
 
        ((cur >= 'A') && (cur <= 'Z'))) {
10242
 
        buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
10243
 
        if (buf == NULL) {
10244
 
            xmlErrMemory(ctxt, NULL);
10245
 
            return(NULL);
10246
 
        }
10247
 
 
10248
 
        buf[len++] = cur;
10249
 
        NEXT;
10250
 
        cur = CUR;
10251
 
        while (((cur >= 'a') && (cur <= 'z')) ||
10252
 
               ((cur >= 'A') && (cur <= 'Z')) ||
10253
 
               ((cur >= '0') && (cur <= '9')) ||
10254
 
               (cur == '.') || (cur == '_') ||
10255
 
               (cur == '-')) {
10256
 
            if (len + 1 >= size) {
10257
 
                xmlChar *tmp;
10258
 
 
10259
 
                size *= 2;
10260
 
                tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
10261
 
                if (tmp == NULL) {
10262
 
                    xmlErrMemory(ctxt, NULL);
10263
 
                    xmlFree(buf);
10264
 
                    return(NULL);
10265
 
                }
10266
 
                buf = tmp;
10267
 
            }
10268
 
            buf[len++] = cur;
10269
 
            NEXT;
10270
 
            cur = CUR;
10271
 
            if (cur == 0) {
10272
 
                SHRINK;
10273
 
                GROW;
10274
 
                cur = CUR;
10275
 
            }
10276
 
        }
10277
 
        buf[len] = 0;
10278
 
    } else {
10279
 
        xmlFatalErr(ctxt, XML_ERR_ENCODING_NAME, NULL);
10280
 
    }
10281
 
    return(buf);
10282
 
}
10283
 
 
10284
 
/**
10285
 
 * xmlParseEncodingDecl:
10286
 
 * @ctxt:  an XML parser context
10287
 
 *
10288
 
 * parse the XML encoding declaration
10289
 
 *
10290
 
 * [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' |  "'" EncName "'")
10291
 
 *
10292
 
 * this setups the conversion filters.
10293
 
 *
10294
 
 * Returns the encoding value or NULL
10295
 
 */
10296
 
 
10297
 
const xmlChar *
10298
 
xmlParseEncodingDecl(xmlParserCtxtPtr ctxt) {
10299
 
    xmlChar *encoding = NULL;
10300
 
 
10301
 
    SKIP_BLANKS;
10302
 
    if (CMP8(CUR_PTR, 'e', 'n', 'c', 'o', 'd', 'i', 'n', 'g')) {
10303
 
        SKIP(8);
10304
 
        SKIP_BLANKS;
10305
 
        if (RAW != '=') {
10306
 
            xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
10307
 
            return(NULL);
10308
 
        }
10309
 
        NEXT;
10310
 
        SKIP_BLANKS;
10311
 
        if (RAW == '"') {
10312
 
            NEXT;
10313
 
            encoding = xmlParseEncName(ctxt);
10314
 
            if (RAW != '"') {
10315
 
                xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10316
 
            } else
10317
 
                NEXT;
10318
 
        } else if (RAW == '\''){
10319
 
            NEXT;
10320
 
            encoding = xmlParseEncName(ctxt);
10321
 
            if (RAW != '\'') {
10322
 
                xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10323
 
            } else
10324
 
                NEXT;
10325
 
        } else {
10326
 
            xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
10327
 
        }
10328
 
 
10329
 
        /*
10330
 
         * Non standard parsing, allowing the user to ignore encoding
10331
 
         */
10332
 
        if (ctxt->options & XML_PARSE_IGNORE_ENC)
10333
 
            return(encoding);
10334
 
 
10335
 
        /*
10336
 
         * UTF-16 encoding stwich has already taken place at this stage,
10337
 
         * more over the little-endian/big-endian selection is already done
10338
 
         */
10339
 
        if ((encoding != NULL) &&
10340
 
            ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-16")) ||
10341
 
             (!xmlStrcasecmp(encoding, BAD_CAST "UTF16")))) {
10342
 
            /*
10343
 
             * If no encoding was passed to the parser, that we are
10344
 
             * using UTF-16 and no decoder is present i.e. the
10345
 
             * document is apparently UTF-8 compatible, then raise an
10346
 
             * encoding mismatch fatal error
10347
 
             */
10348
 
            if ((ctxt->encoding == NULL) &&
10349
 
                (ctxt->input->buf != NULL) &&
10350
 
                (ctxt->input->buf->encoder == NULL)) {
10351
 
                xmlFatalErrMsg(ctxt, XML_ERR_INVALID_ENCODING,
10352
 
                  "Document labelled UTF-16 but has UTF-8 content\n");
10353
 
            }
10354
 
            if (ctxt->encoding != NULL)
10355
 
                xmlFree((xmlChar *) ctxt->encoding);
10356
 
            ctxt->encoding = encoding;
10357
 
        }
10358
 
        /*
10359
 
         * UTF-8 encoding is handled natively
10360
 
         */
10361
 
        else if ((encoding != NULL) &&
10362
 
            ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-8")) ||
10363
 
             (!xmlStrcasecmp(encoding, BAD_CAST "UTF8")))) {
10364
 
            if (ctxt->encoding != NULL)
10365
 
                xmlFree((xmlChar *) ctxt->encoding);
10366
 
            ctxt->encoding = encoding;
10367
 
        }
10368
 
        else if (encoding != NULL) {
10369
 
            xmlCharEncodingHandlerPtr handler;
10370
 
 
10371
 
            if (ctxt->input->encoding != NULL)
10372
 
                xmlFree((xmlChar *) ctxt->input->encoding);
10373
 
            ctxt->input->encoding = encoding;
10374
 
 
10375
 
            handler = xmlFindCharEncodingHandler((const char *) encoding);
10376
 
            if (handler != NULL) {
10377
 
                xmlSwitchToEncoding(ctxt, handler);
10378
 
            } else {
10379
 
                xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
10380
 
                        "Unsupported encoding %s\n", encoding);
10381
 
                return(NULL);
10382
 
            }
10383
 
        }
10384
 
    }
10385
 
    return(encoding);
10386
 
}
10387
 
 
10388
 
/**
10389
 
 * xmlParseSDDecl:
10390
 
 * @ctxt:  an XML parser context
10391
 
 *
10392
 
 * parse the XML standalone declaration
10393
 
 *
10394
 
 * [32] SDDecl ::= S 'standalone' Eq
10395
 
 *                 (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no')'"'))
10396
 
 *
10397
 
 * [ VC: Standalone Document Declaration ]
10398
 
 * TODO The standalone document declaration must have the value "no"
10399
 
 * if any external markup declarations contain declarations of:
10400
 
 *  - attributes with default values, if elements to which these
10401
 
 *    attributes apply appear in the document without specifications
10402
 
 *    of values for these attributes, or
10403
 
 *  - entities (other than amp, lt, gt, apos, quot), if references
10404
 
 *    to those entities appear in the document, or
10405
 
 *  - attributes with values subject to normalization, where the
10406
 
 *    attribute appears in the document with a value which will change
10407
 
 *    as a result of normalization, or
10408
 
 *  - element types with element content, if white space occurs directly
10409
 
 *    within any instance of those types.
10410
 
 *
10411
 
 * Returns:
10412
 
 *   1 if standalone="yes"
10413
 
 *   0 if standalone="no"
10414
 
 *  -2 if standalone attribute is missing or invalid
10415
 
 *        (A standalone value of -2 means that the XML declaration was found,
10416
 
 *         but no value was specified for the standalone attribute).
10417
 
 */
10418
 
 
10419
 
int
10420
 
xmlParseSDDecl(xmlParserCtxtPtr ctxt) {
10421
 
    int standalone = -2;
10422
 
 
10423
 
    SKIP_BLANKS;
10424
 
    if (CMP10(CUR_PTR, 's', 't', 'a', 'n', 'd', 'a', 'l', 'o', 'n', 'e')) {
10425
 
        SKIP(10);
10426
 
        SKIP_BLANKS;
10427
 
        if (RAW != '=') {
10428
 
            xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
10429
 
            return(standalone);
10430
 
        }
10431
 
        NEXT;
10432
 
        SKIP_BLANKS;
10433
 
        if (RAW == '\''){
10434
 
            NEXT;
10435
 
            if ((RAW == 'n') && (NXT(1) == 'o')) {
10436
 
                standalone = 0;
10437
 
                SKIP(2);
10438
 
            } else if ((RAW == 'y') && (NXT(1) == 'e') &&
10439
 
                       (NXT(2) == 's')) {
10440
 
                standalone = 1;
10441
 
                SKIP(3);
10442
 
            } else {
10443
 
                xmlFatalErr(ctxt, XML_ERR_STANDALONE_VALUE, NULL);
10444
 
            }
10445
 
            if (RAW != '\'') {
10446
 
                xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10447
 
            } else
10448
 
                NEXT;
10449
 
        } else if (RAW == '"'){
10450
 
            NEXT;
10451
 
            if ((RAW == 'n') && (NXT(1) == 'o')) {
10452
 
                standalone = 0;
10453
 
                SKIP(2);
10454
 
            } else if ((RAW == 'y') && (NXT(1) == 'e') &&
10455
 
                       (NXT(2) == 's')) {
10456
 
                standalone = 1;
10457
 
                SKIP(3);
10458
 
            } else {
10459
 
                xmlFatalErr(ctxt, XML_ERR_STANDALONE_VALUE, NULL);
10460
 
            }
10461
 
            if (RAW != '"') {
10462
 
                xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10463
 
            } else
10464
 
                NEXT;
10465
 
        } else {
10466
 
            xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
10467
 
        }
10468
 
    }
10469
 
    return(standalone);
10470
 
}
10471
 
 
10472
 
/**
10473
 
 * xmlParseXMLDecl:
10474
 
 * @ctxt:  an XML parser context
10475
 
 *
10476
 
 * parse an XML declaration header
10477
 
 *
10478
 
 * [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
10479
 
 */
10480
 
 
10481
 
void
10482
 
xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
10483
 
    xmlChar *version;
10484
 
 
10485
 
    /*
10486
 
     * This value for standalone indicates that the document has an
10487
 
     * XML declaration but it does not have a standalone attribute.
10488
 
     * It will be overwritten later if a standalone attribute is found.
10489
 
     */
10490
 
    ctxt->input->standalone = -2;
10491
 
 
10492
 
    /*
10493
 
     * We know that '<?xml' is here.
10494
 
     */
10495
 
    SKIP(5);
10496
 
 
10497
 
    if (!IS_BLANK_CH(RAW)) {
10498
 
        xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
10499
 
                       "Blank needed after '<?xml'\n");
10500
 
    }
10501
 
    SKIP_BLANKS;
10502
 
 
10503
 
    /*
10504
 
     * We must have the VersionInfo here.
10505
 
     */
10506
 
    version = xmlParseVersionInfo(ctxt);
10507
 
    if (version == NULL) {
10508
 
        xmlFatalErr(ctxt, XML_ERR_VERSION_MISSING, NULL);
10509
 
    } else {
10510
 
        if (!xmlStrEqual(version, (const xmlChar *) XML_DEFAULT_VERSION)) {
10511
 
            /*
10512
 
             * Changed here for XML-1.0 5th edition
10513
 
             */
10514
 
            if (ctxt->options & XML_PARSE_OLD10) {
10515
 
                xmlFatalErrMsgStr(ctxt, XML_ERR_UNKNOWN_VERSION,
10516
 
                                  "Unsupported version '%s'\n",
10517
 
                                  version);
10518
 
            } else {
10519
 
                if ((version[0] == '1') && ((version[1] == '.'))) {
10520
 
                    xmlWarningMsg(ctxt, XML_WAR_UNKNOWN_VERSION,
10521
 
                                  "Unsupported version '%s'\n",
10522
 
                                  version, NULL);
10523
 
                } else {
10524
 
                    xmlFatalErrMsgStr(ctxt, XML_ERR_UNKNOWN_VERSION,
10525
 
                                      "Unsupported version '%s'\n",
10526
 
                                      version);
10527
 
                }
10528
 
            }
10529
 
        }
10530
 
        if (ctxt->version != NULL)
10531
 
            xmlFree((void *) ctxt->version);
10532
 
        ctxt->version = version;
10533
 
    }
10534
 
 
10535
 
    /*
10536
 
     * We may have the encoding declaration
10537
 
     */
10538
 
    if (!IS_BLANK_CH(RAW)) {
10539
 
        if ((RAW == '?') && (NXT(1) == '>')) {
10540
 
            SKIP(2);
10541
 
            return;
10542
 
        }
10543
 
        xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
10544
 
    }
10545
 
    xmlParseEncodingDecl(ctxt);
10546
 
    if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
10547
 
        /*
10548
 
         * The XML REC instructs us to stop parsing right here
10549
 
         */
10550
 
        return;
10551
 
    }
10552
 
 
10553
 
    /*
10554
 
     * We may have the standalone status.
10555
 
     */
10556
 
    if ((ctxt->input->encoding != NULL) && (!IS_BLANK_CH(RAW))) {
10557
 
        if ((RAW == '?') && (NXT(1) == '>')) {
10558
 
            SKIP(2);
10559
 
            return;
10560
 
        }
10561
 
        xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
10562
 
    }
10563
 
 
10564
 
    /*
10565
 
     * We can grow the input buffer freely at that point
10566
 
     */
10567
 
    GROW;
10568
 
 
10569
 
    SKIP_BLANKS;
10570
 
    ctxt->input->standalone = xmlParseSDDecl(ctxt);
10571
 
 
10572
 
    SKIP_BLANKS;
10573
 
    if ((RAW == '?') && (NXT(1) == '>')) {
10574
 
        SKIP(2);
10575
 
    } else if (RAW == '>') {
10576
 
        /* Deprecated old WD ... */
10577
 
        xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
10578
 
        NEXT;
10579
 
    } else {
10580
 
        xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
10581
 
        MOVETO_ENDTAG(CUR_PTR);
10582
 
        NEXT;
10583
 
    }
10584
 
}
10585
 
 
10586
 
/**
10587
 
 * xmlParseMisc:
10588
 
 * @ctxt:  an XML parser context
10589
 
 *
10590
 
 * parse an XML Misc* optional field.
10591
 
 *
10592
 
 * [27] Misc ::= Comment | PI |  S
10593
 
 */
10594
 
 
10595
 
void
10596
 
xmlParseMisc(xmlParserCtxtPtr ctxt) {
10597
 
    while ((ctxt->instate != XML_PARSER_EOF) &&
10598
 
           (((RAW == '<') && (NXT(1) == '?')) ||
10599
 
            (CMP4(CUR_PTR, '<', '!', '-', '-')) ||
10600
 
            IS_BLANK_CH(CUR))) {
10601
 
        if ((RAW == '<') && (NXT(1) == '?')) {
10602
 
            xmlParsePI(ctxt);
10603
 
        } else if (IS_BLANK_CH(CUR)) {
10604
 
            NEXT;
10605
 
        } else
10606
 
            xmlParseComment(ctxt);
10607
 
    }
10608
 
}
10609
 
 
10610
 
/**
10611
 
 * xmlParseDocument:
10612
 
 * @ctxt:  an XML parser context
10613
 
 *
10614
 
 * parse an XML document (and build a tree if using the standard SAX
10615
 
 * interface).
10616
 
 *
10617
 
 * [1] document ::= prolog element Misc*
10618
 
 *
10619
 
 * [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
10620
 
 *
10621
 
 * Returns 0, -1 in case of error. the parser context is augmented
10622
 
 *                as a result of the parsing.
10623
 
 */
10624
 
 
10625
 
int
10626
 
xmlParseDocument(xmlParserCtxtPtr ctxt) {
10627
 
    xmlChar start[4];
10628
 
    xmlCharEncoding enc;
10629
 
 
10630
 
    xmlInitParser();
10631
 
 
10632
 
    if ((ctxt == NULL) || (ctxt->input == NULL))
10633
 
        return(-1);
10634
 
 
10635
 
    GROW;
10636
 
 
10637
 
    /*
10638
 
     * SAX: detecting the level.
10639
 
     */
10640
 
    xmlDetectSAX2(ctxt);
10641
 
 
10642
 
    /*
10643
 
     * SAX: beginning of the document processing.
10644
 
     */
10645
 
    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
10646
 
        ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
10647
 
    if (ctxt->instate == XML_PARSER_EOF)
10648
 
        return(-1);
10649
 
 
10650
 
    if ((ctxt->encoding == NULL) &&
10651
 
        ((ctxt->input->end - ctxt->input->cur) >= 4)) {
10652
 
        /*
10653
 
         * Get the 4 first bytes and decode the charset
10654
 
         * if enc != XML_CHAR_ENCODING_NONE
10655
 
         * plug some encoding conversion routines.
10656
 
         */
10657
 
        start[0] = RAW;
10658
 
        start[1] = NXT(1);
10659
 
        start[2] = NXT(2);
10660
 
        start[3] = NXT(3);
10661
 
        enc = xmlDetectCharEncoding(&start[0], 4);
10662
 
        if (enc != XML_CHAR_ENCODING_NONE) {
10663
 
            xmlSwitchEncoding(ctxt, enc);
10664
 
        }
10665
 
    }
10666
 
 
10667
 
 
10668
 
    if (CUR == 0) {
10669
 
        xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
10670
 
    }
10671
 
 
10672
 
    /*
10673
 
     * Check for the XMLDecl in the Prolog.
10674
 
     * do not GROW here to avoid the detected encoder to decode more
10675
 
     * than just the first line, unless the amount of data is really
10676
 
     * too small to hold "<?xml version="1.0" encoding="foo"
10677
 
     */
10678
 
    if ((ctxt->input->end - ctxt->input->cur) < 35) {
10679
 
       GROW;
10680
 
    }
10681
 
    if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
10682
 
 
10683
 
        /*
10684
 
         * Note that we will switch encoding on the fly.
10685
 
         */
10686
 
        xmlParseXMLDecl(ctxt);
10687
 
        if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
10688
 
            /*
10689
 
             * The XML REC instructs us to stop parsing right here
10690
 
             */
10691
 
            return(-1);
10692
 
        }
10693
 
        ctxt->standalone = ctxt->input->standalone;
10694
 
        SKIP_BLANKS;
10695
 
    } else {
10696
 
        ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
10697
 
    }
10698
 
    if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
10699
 
        ctxt->sax->startDocument(ctxt->userData);
10700
 
    if (ctxt->instate == XML_PARSER_EOF)
10701
 
        return(-1);
10702
 
 
10703
 
    /*
10704
 
     * The Misc part of the Prolog
10705
 
     */
10706
 
    GROW;
10707
 
    xmlParseMisc(ctxt);
10708
 
 
10709
 
    /*
10710
 
     * Then possibly doc type declaration(s) and more Misc
10711
 
     * (doctypedecl Misc*)?
10712
 
     */
10713
 
    GROW;
10714
 
    if (CMP9(CUR_PTR, '<', '!', 'D', 'O', 'C', 'T', 'Y', 'P', 'E')) {
10715
 
 
10716
 
        ctxt->inSubset = 1;
10717
 
        xmlParseDocTypeDecl(ctxt);
10718
 
        if (RAW == '[') {
10719
 
            ctxt->instate = XML_PARSER_DTD;
10720
 
            xmlParseInternalSubset(ctxt);
10721
 
            if (ctxt->instate == XML_PARSER_EOF)
10722
 
                return(-1);
10723
 
        }
10724
 
 
10725
 
        /*
10726
 
         * Create and update the external subset.
10727
 
         */
10728
 
        ctxt->inSubset = 2;
10729
 
        if ((ctxt->sax != NULL) && (ctxt->sax->externalSubset != NULL) &&
10730
 
            (!ctxt->disableSAX))
10731
 
            ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
10732
 
                                      ctxt->extSubSystem, ctxt->extSubURI);
10733
 
        if (ctxt->instate == XML_PARSER_EOF)
10734
 
            return(-1);
10735
 
        ctxt->inSubset = 0;
10736
 
 
10737
 
        xmlCleanSpecialAttr(ctxt);
10738
 
 
10739
 
        ctxt->instate = XML_PARSER_PROLOG;
10740
 
        xmlParseMisc(ctxt);
10741
 
    }
10742
 
 
10743
 
    /*
10744
 
     * Time to start parsing the tree itself
10745
 
     */
10746
 
    GROW;
10747
 
    if (RAW != '<') {
10748
 
        xmlFatalErrMsg(ctxt, XML_ERR_DOCUMENT_EMPTY,
10749
 
                       "Start tag expected, '<' not found\n");
10750
 
    } else {
10751
 
        ctxt->instate = XML_PARSER_CONTENT;
10752
 
        xmlParseElement(ctxt);
10753
 
        ctxt->instate = XML_PARSER_EPILOG;
10754
 
 
10755
 
 
10756
 
        /*
10757
 
         * The Misc part at the end
10758
 
         */
10759
 
        xmlParseMisc(ctxt);
10760
 
 
10761
 
        if (RAW != 0) {
10762
 
            xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
10763
 
        }
10764
 
        ctxt->instate = XML_PARSER_EOF;
10765
 
    }
10766
 
 
10767
 
    /*
10768
 
     * SAX: end of the document processing.
10769
 
     */
10770
 
    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
10771
 
        ctxt->sax->endDocument(ctxt->userData);
10772
 
 
10773
 
    /*
10774
 
     * Remove locally kept entity definitions if the tree was not built
10775
 
     */
10776
 
    if ((ctxt->myDoc != NULL) &&
10777
 
        (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) {
10778
 
        xmlFreeDoc(ctxt->myDoc);
10779
 
        ctxt->myDoc = NULL;
10780
 
    }
10781
 
 
10782
 
    if ((ctxt->wellFormed) && (ctxt->myDoc != NULL)) {
10783
 
        ctxt->myDoc->properties |= XML_DOC_WELLFORMED;
10784
 
        if (ctxt->valid)
10785
 
            ctxt->myDoc->properties |= XML_DOC_DTDVALID;
10786
 
        if (ctxt->nsWellFormed)
10787
 
            ctxt->myDoc->properties |= XML_DOC_NSVALID;
10788
 
        if (ctxt->options & XML_PARSE_OLD10)
10789
 
            ctxt->myDoc->properties |= XML_DOC_OLD10;
10790
 
    }
10791
 
    if (! ctxt->wellFormed) {
10792
 
        ctxt->valid = 0;
10793
 
        return(-1);
10794
 
    }
10795
 
    return(0);
10796
 
}
10797
 
 
10798
 
/**
10799
 
 * xmlParseExtParsedEnt:
10800
 
 * @ctxt:  an XML parser context
10801
 
 *
10802
 
 * parse a general parsed entity
10803
 
 * An external general parsed entity is well-formed if it matches the
10804
 
 * production labeled extParsedEnt.
10805
 
 *
10806
 
 * [78] extParsedEnt ::= TextDecl? content
10807
 
 *
10808
 
 * Returns 0, -1 in case of error. the parser context is augmented
10809
 
 *                as a result of the parsing.
10810
 
 */
10811
 
 
10812
 
int
10813
 
xmlParseExtParsedEnt(xmlParserCtxtPtr ctxt) {
10814
 
    xmlChar start[4];
10815
 
    xmlCharEncoding enc;
10816
 
 
10817
 
    if ((ctxt == NULL) || (ctxt->input == NULL))
10818
 
        return(-1);
10819
 
 
10820
 
    xmlDefaultSAXHandlerInit();
10821
 
 
10822
 
    xmlDetectSAX2(ctxt);
10823
 
 
10824
 
    GROW;
10825
 
 
10826
 
    /*
10827
 
     * SAX: beginning of the document processing.
10828
 
     */
10829
 
    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
10830
 
        ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
10831
 
 
10832
 
    /*
10833
 
     * Get the 4 first bytes and decode the charset
10834
 
     * if enc != XML_CHAR_ENCODING_NONE
10835
 
     * plug some encoding conversion routines.
10836
 
     */
10837
 
    if ((ctxt->input->end - ctxt->input->cur) >= 4) {
10838
 
        start[0] = RAW;
10839
 
        start[1] = NXT(1);
10840
 
        start[2] = NXT(2);
10841
 
        start[3] = NXT(3);
10842
 
        enc = xmlDetectCharEncoding(start, 4);
10843
 
        if (enc != XML_CHAR_ENCODING_NONE) {
10844
 
            xmlSwitchEncoding(ctxt, enc);
10845
 
        }
10846
 
    }
10847
 
 
10848
 
 
10849
 
    if (CUR == 0) {
10850
 
        xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
10851
 
    }
10852
 
 
10853
 
    /*
10854
 
     * Check for the XMLDecl in the Prolog.
10855
 
     */
10856
 
    GROW;
10857
 
    if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
10858
 
 
10859
 
        /*
10860
 
         * Note that we will switch encoding on the fly.
10861
 
         */
10862
 
        xmlParseXMLDecl(ctxt);
10863
 
        if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
10864
 
            /*
10865
 
             * The XML REC instructs us to stop parsing right here
10866
 
             */
10867
 
            return(-1);
10868
 
        }
10869
 
        SKIP_BLANKS;
10870
 
    } else {
10871
 
        ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
10872
 
    }
10873
 
    if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
10874
 
        ctxt->sax->startDocument(ctxt->userData);
10875
 
    if (ctxt->instate == XML_PARSER_EOF)
10876
 
        return(-1);
10877
 
 
10878
 
    /*
10879
 
     * Doing validity checking on chunk doesn't make sense
10880
 
     */
10881
 
    ctxt->instate = XML_PARSER_CONTENT;
10882
 
    ctxt->validate = 0;
10883
 
    ctxt->loadsubset = 0;
10884
 
    ctxt->depth = 0;
10885
 
 
10886
 
    xmlParseContent(ctxt);
10887
 
    if (ctxt->instate == XML_PARSER_EOF)
10888
 
        return(-1);
10889
 
 
10890
 
    if ((RAW == '<') && (NXT(1) == '/')) {
10891
 
        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
10892
 
    } else if (RAW != 0) {
10893
 
        xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
10894
 
    }
10895
 
 
10896
 
    /*
10897
 
     * SAX: end of the document processing.
10898
 
     */
10899
 
    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
10900
 
        ctxt->sax->endDocument(ctxt->userData);
10901
 
 
10902
 
    if (! ctxt->wellFormed) return(-1);
10903
 
    return(0);
10904
 
}
10905
 
 
10906
 
#ifdef LIBXML_PUSH_ENABLED
10907
 
/************************************************************************
10908
 
 *                                                                      *
10909
 
 *              Progressive parsing interfaces                          *
10910
 
 *                                                                      *
10911
 
 ************************************************************************/
10912
 
 
10913
 
/**
10914
 
 * xmlParseLookupSequence:
10915
 
 * @ctxt:  an XML parser context
10916
 
 * @first:  the first char to lookup
10917
 
 * @next:  the next char to lookup or zero
10918
 
 * @third:  the next char to lookup or zero
10919
 
 *
10920
 
 * Try to find if a sequence (first, next, third) or  just (first next) or
10921
 
 * (first) is available in the input stream.
10922
 
 * This function has a side effect of (possibly) incrementing ctxt->checkIndex
10923
 
 * to avoid rescanning sequences of bytes, it DOES change the state of the
10924
 
 * parser, do not use liberally.
10925
 
 *
10926
 
 * Returns the index to the current parsing point if the full sequence
10927
 
 *      is available, -1 otherwise.
10928
 
 */
10929
 
static int
10930
 
xmlParseLookupSequence(xmlParserCtxtPtr ctxt, xmlChar first,
10931
 
                       xmlChar next, xmlChar third) {
10932
 
    int base, len;
10933
 
    xmlParserInputPtr in;
10934
 
    const xmlChar *buf;
10935
 
 
10936
 
    in = ctxt->input;
10937
 
    if (in == NULL) return(-1);
10938
 
    base = in->cur - in->base;
10939
 
    if (base < 0) return(-1);
10940
 
    if (ctxt->checkIndex > base)
10941
 
        base = ctxt->checkIndex;
10942
 
    if (in->buf == NULL) {
10943
 
        buf = in->base;
10944
 
        len = in->length;
10945
 
    } else {
10946
 
        buf = xmlBufContent(in->buf->buffer);
10947
 
        len = xmlBufUse(in->buf->buffer);
10948
 
    }
10949
 
    /* take into account the sequence length */
10950
 
    if (third) len -= 2;
10951
 
    else if (next) len --;
10952
 
    for (;base < len;base++) {
10953
 
        if (buf[base] == first) {
10954
 
            if (third != 0) {
10955
 
                if ((buf[base + 1] != next) ||
10956
 
                    (buf[base + 2] != third)) continue;
10957
 
            } else if (next != 0) {
10958
 
                if (buf[base + 1] != next) continue;
10959
 
            }
10960
 
            ctxt->checkIndex = 0;
10961
 
#ifdef DEBUG_PUSH
10962
 
            if (next == 0)
10963
 
                xmlGenericError(xmlGenericErrorContext,
10964
 
                        "PP: lookup '%c' found at %d\n",
10965
 
                        first, base);
10966
 
            else if (third == 0)
10967
 
                xmlGenericError(xmlGenericErrorContext,
10968
 
                        "PP: lookup '%c%c' found at %d\n",
10969
 
                        first, next, base);
10970
 
            else
10971
 
                xmlGenericError(xmlGenericErrorContext,
10972
 
                        "PP: lookup '%c%c%c' found at %d\n",
10973
 
                        first, next, third, base);
10974
 
#endif
10975
 
            return(base - (in->cur - in->base));
10976
 
        }
10977
 
    }
10978
 
    ctxt->checkIndex = base;
10979
 
#ifdef DEBUG_PUSH
10980
 
    if (next == 0)
10981
 
        xmlGenericError(xmlGenericErrorContext,
10982
 
                "PP: lookup '%c' failed\n", first);
10983
 
    else if (third == 0)
10984
 
        xmlGenericError(xmlGenericErrorContext,
10985
 
                "PP: lookup '%c%c' failed\n", first, next);
10986
 
    else
10987
 
        xmlGenericError(xmlGenericErrorContext,
10988
 
                "PP: lookup '%c%c%c' failed\n", first, next, third);
10989
 
#endif
10990
 
    return(-1);
10991
 
}
10992
 
 
10993
 
/**
10994
 
 * xmlParseGetLasts:
10995
 
 * @ctxt:  an XML parser context
10996
 
 * @lastlt:  pointer to store the last '<' from the input
10997
 
 * @lastgt:  pointer to store the last '>' from the input
10998
 
 *
10999
 
 * Lookup the last < and > in the current chunk
11000
 
 */
11001
 
static void
11002
 
xmlParseGetLasts(xmlParserCtxtPtr ctxt, const xmlChar **lastlt,
11003
 
                 const xmlChar **lastgt) {
11004
 
    const xmlChar *tmp;
11005
 
 
11006
 
    if ((ctxt == NULL) || (lastlt == NULL) || (lastgt == NULL)) {
11007
 
        xmlGenericError(xmlGenericErrorContext,
11008
 
                    "Internal error: xmlParseGetLasts\n");
11009
 
        return;
11010
 
    }
11011
 
    if ((ctxt->progressive != 0) && (ctxt->inputNr == 1)) {
11012
 
        tmp = ctxt->input->end;
11013
 
        tmp--;
11014
 
        while ((tmp >= ctxt->input->base) && (*tmp != '<')) tmp--;
11015
 
        if (tmp < ctxt->input->base) {
11016
 
            *lastlt = NULL;
11017
 
            *lastgt = NULL;
11018
 
        } else {
11019
 
            *lastlt = tmp;
11020
 
            tmp++;
11021
 
            while ((tmp < ctxt->input->end) && (*tmp != '>')) {
11022
 
                if (*tmp == '\'') {
11023
 
                    tmp++;
11024
 
                    while ((tmp < ctxt->input->end) && (*tmp != '\'')) tmp++;
11025
 
                    if (tmp < ctxt->input->end) tmp++;
11026
 
                } else if (*tmp == '"') {
11027
 
                    tmp++;
11028
 
                    while ((tmp < ctxt->input->end) && (*tmp != '"')) tmp++;
11029
 
                    if (tmp < ctxt->input->end) tmp++;
11030
 
                } else
11031
 
                    tmp++;
11032
 
            }
11033
 
            if (tmp < ctxt->input->end)
11034
 
                *lastgt = tmp;
11035
 
            else {
11036
 
                tmp = *lastlt;
11037
 
                tmp--;
11038
 
                while ((tmp >= ctxt->input->base) && (*tmp != '>')) tmp--;
11039
 
                if (tmp >= ctxt->input->base)
11040
 
                    *lastgt = tmp;
11041
 
                else
11042
 
                    *lastgt = NULL;
11043
 
            }
11044
 
        }
11045
 
    } else {
11046
 
        *lastlt = NULL;
11047
 
        *lastgt = NULL;
11048
 
    }
11049
 
}
11050
 
/**
11051
 
 * xmlCheckCdataPush:
11052
 
 * @cur: pointer to the bock of characters
11053
 
 * @len: length of the block in bytes
11054
 
 *
11055
 
 * Check that the block of characters is okay as SCdata content [20]
11056
 
 *
11057
 
 * Returns the number of bytes to pass if okay, a negative index where an
11058
 
 *         UTF-8 error occured otherwise
11059
 
 */
11060
 
static int
11061
 
xmlCheckCdataPush(const xmlChar *utf, int len) {
11062
 
    int ix;
11063
 
    unsigned char c;
11064
 
    int codepoint;
11065
 
 
11066
 
    if ((utf == NULL) || (len <= 0))
11067
 
        return(0);
11068
 
 
11069
 
    for (ix = 0; ix < len;) {      /* string is 0-terminated */
11070
 
        c = utf[ix];
11071
 
        if ((c & 0x80) == 0x00) {       /* 1-byte code, starts with 10 */
11072
 
            if (c >= 0x20)
11073
 
                ix++;
11074
 
            else if ((c == 0xA) || (c == 0xD) || (c == 0x9))
11075
 
                ix++;
11076
 
            else
11077
 
                return(-ix);
11078
 
        } else if ((c & 0xe0) == 0xc0) {/* 2-byte code, starts with 110 */
11079
 
            if (ix + 2 > len) return(ix);
11080
 
            if ((utf[ix+1] & 0xc0 ) != 0x80)
11081
 
                return(-ix);
11082
 
            codepoint = (utf[ix] & 0x1f) << 6;
11083
 
            codepoint |= utf[ix+1] & 0x3f;
11084
 
            if (!xmlIsCharQ(codepoint))
11085
 
                return(-ix);
11086
 
            ix += 2;
11087
 
        } else if ((c & 0xf0) == 0xe0) {/* 3-byte code, starts with 1110 */
11088
 
            if (ix + 3 > len) return(ix);
11089
 
            if (((utf[ix+1] & 0xc0) != 0x80) ||
11090
 
                ((utf[ix+2] & 0xc0) != 0x80))
11091
 
                    return(-ix);
11092
 
            codepoint = (utf[ix] & 0xf) << 12;
11093
 
            codepoint |= (utf[ix+1] & 0x3f) << 6;
11094
 
            codepoint |= utf[ix+2] & 0x3f;
11095
 
            if (!xmlIsCharQ(codepoint))
11096
 
                return(-ix);
11097
 
            ix += 3;
11098
 
        } else if ((c & 0xf8) == 0xf0) {/* 4-byte code, starts with 11110 */
11099
 
            if (ix + 4 > len) return(ix);
11100
 
            if (((utf[ix+1] & 0xc0) != 0x80) ||
11101
 
                ((utf[ix+2] & 0xc0) != 0x80) ||
11102
 
                ((utf[ix+3] & 0xc0) != 0x80))
11103
 
                    return(-ix);
11104
 
            codepoint = (utf[ix] & 0x7) << 18;
11105
 
            codepoint |= (utf[ix+1] & 0x3f) << 12;
11106
 
            codepoint |= (utf[ix+2] & 0x3f) << 6;
11107
 
            codepoint |= utf[ix+3] & 0x3f;
11108
 
            if (!xmlIsCharQ(codepoint))
11109
 
                return(-ix);
11110
 
            ix += 4;
11111
 
        } else                          /* unknown encoding */
11112
 
            return(-ix);
11113
 
      }
11114
 
      return(ix);
11115
 
}
11116
 
 
11117
 
/**
11118
 
 * xmlParseTryOrFinish:
11119
 
 * @ctxt:  an XML parser context
11120
 
 * @terminate:  last chunk indicator
11121
 
 *
11122
 
 * Try to progress on parsing
11123
 
 *
11124
 
 * Returns zero if no parsing was possible
11125
 
 */
11126
 
static int
11127
 
xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
11128
 
    int ret = 0;
11129
 
    int avail, tlen;
11130
 
    xmlChar cur, next;
11131
 
    const xmlChar *lastlt, *lastgt;
11132
 
 
11133
 
    if (ctxt->input == NULL)
11134
 
        return(0);
11135
 
 
11136
 
#ifdef DEBUG_PUSH
11137
 
    switch (ctxt->instate) {
11138
 
        case XML_PARSER_EOF:
11139
 
            xmlGenericError(xmlGenericErrorContext,
11140
 
                    "PP: try EOF\n"); break;
11141
 
        case XML_PARSER_START:
11142
 
            xmlGenericError(xmlGenericErrorContext,
11143
 
                    "PP: try START\n"); break;
11144
 
        case XML_PARSER_MISC:
11145
 
            xmlGenericError(xmlGenericErrorContext,
11146
 
                    "PP: try MISC\n");break;
11147
 
        case XML_PARSER_COMMENT:
11148
 
            xmlGenericError(xmlGenericErrorContext,
11149
 
                    "PP: try COMMENT\n");break;
11150
 
        case XML_PARSER_PROLOG:
11151
 
            xmlGenericError(xmlGenericErrorContext,
11152
 
                    "PP: try PROLOG\n");break;
11153
 
        case XML_PARSER_START_TAG:
11154
 
            xmlGenericError(xmlGenericErrorContext,
11155
 
                    "PP: try START_TAG\n");break;
11156
 
        case XML_PARSER_CONTENT:
11157
 
            xmlGenericError(xmlGenericErrorContext,
11158
 
                    "PP: try CONTENT\n");break;
11159
 
        case XML_PARSER_CDATA_SECTION:
11160
 
            xmlGenericError(xmlGenericErrorContext,
11161
 
                    "PP: try CDATA_SECTION\n");break;
11162
 
        case XML_PARSER_END_TAG:
11163
 
            xmlGenericError(xmlGenericErrorContext,
11164
 
                    "PP: try END_TAG\n");break;
11165
 
        case XML_PARSER_ENTITY_DECL:
11166
 
            xmlGenericError(xmlGenericErrorContext,
11167
 
                    "PP: try ENTITY_DECL\n");break;
11168
 
        case XML_PARSER_ENTITY_VALUE:
11169
 
            xmlGenericError(xmlGenericErrorContext,
11170
 
                    "PP: try ENTITY_VALUE\n");break;
11171
 
        case XML_PARSER_ATTRIBUTE_VALUE:
11172
 
            xmlGenericError(xmlGenericErrorContext,
11173
 
                    "PP: try ATTRIBUTE_VALUE\n");break;
11174
 
        case XML_PARSER_DTD:
11175
 
            xmlGenericError(xmlGenericErrorContext,
11176
 
                    "PP: try DTD\n");break;
11177
 
        case XML_PARSER_EPILOG:
11178
 
            xmlGenericError(xmlGenericErrorContext,
11179
 
                    "PP: try EPILOG\n");break;
11180
 
        case XML_PARSER_PI:
11181
 
            xmlGenericError(xmlGenericErrorContext,
11182
 
                    "PP: try PI\n");break;
11183
 
        case XML_PARSER_IGNORE:
11184
 
            xmlGenericError(xmlGenericErrorContext,
11185
 
                    "PP: try IGNORE\n");break;
11186
 
    }
11187
 
#endif
11188
 
 
11189
 
    if ((ctxt->input != NULL) &&
11190
 
        (ctxt->input->cur - ctxt->input->base > 4096)) {
11191
 
        xmlSHRINK(ctxt);
11192
 
        ctxt->checkIndex = 0;
11193
 
    }
11194
 
    xmlParseGetLasts(ctxt, &lastlt, &lastgt);
11195
 
 
11196
 
    while (ctxt->instate != XML_PARSER_EOF) {
11197
 
        if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
11198
 
            return(0);
11199
 
 
11200
 
 
11201
 
        /*
11202
 
         * Pop-up of finished entities.
11203
 
         */
11204
 
        while ((RAW == 0) && (ctxt->inputNr > 1))
11205
 
            xmlPopInput(ctxt);
11206
 
 
11207
 
        if (ctxt->input == NULL) break;
11208
 
        if (ctxt->input->buf == NULL)
11209
 
            avail = ctxt->input->length -
11210
 
                    (ctxt->input->cur - ctxt->input->base);
11211
 
        else {
11212
 
            /*
11213
 
             * If we are operating on converted input, try to flush
11214
 
             * remainng chars to avoid them stalling in the non-converted
11215
 
             * buffer. But do not do this in document start where
11216
 
             * encoding="..." may not have been read and we work on a
11217
 
             * guessed encoding.
11218
 
             */
11219
 
            if ((ctxt->instate != XML_PARSER_START) &&
11220
 
                (ctxt->input->buf->raw != NULL) &&
11221
 
                (xmlBufIsEmpty(ctxt->input->buf->raw) == 0)) {
11222
 
                size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer,
11223
 
                                                 ctxt->input);
11224
 
                size_t current = ctxt->input->cur - ctxt->input->base;
11225
 
 
11226
 
                xmlParserInputBufferPush(ctxt->input->buf, 0, "");
11227
 
                xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input,
11228
 
                                      base, current);
11229
 
            }
11230
 
            avail = xmlBufUse(ctxt->input->buf->buffer) -
11231
 
                    (ctxt->input->cur - ctxt->input->base);
11232
 
        }
11233
 
        if (avail < 1)
11234
 
            goto done;
11235
 
        switch (ctxt->instate) {
11236
 
            case XML_PARSER_EOF:
11237
 
                /*
11238
 
                 * Document parsing is done !
11239
 
                 */
11240
 
                goto done;
11241
 
            case XML_PARSER_START:
11242
 
                if (ctxt->charset == XML_CHAR_ENCODING_NONE) {
11243
 
                    xmlChar start[4];
11244
 
                    xmlCharEncoding enc;
11245
 
 
11246
 
                    /*
11247
 
                     * Very first chars read from the document flow.
11248
 
                     */
11249
 
                    if (avail < 4)
11250
 
                        goto done;
11251
 
 
11252
 
                    /*
11253
 
                     * Get the 4 first bytes and decode the charset
11254
 
                     * if enc != XML_CHAR_ENCODING_NONE
11255
 
                     * plug some encoding conversion routines,
11256
 
                     * else xmlSwitchEncoding will set to (default)
11257
 
                     * UTF8.
11258
 
                     */
11259
 
                    start[0] = RAW;
11260
 
                    start[1] = NXT(1);
11261
 
                    start[2] = NXT(2);
11262
 
                    start[3] = NXT(3);
11263
 
                    enc = xmlDetectCharEncoding(start, 4);
11264
 
                    xmlSwitchEncoding(ctxt, enc);
11265
 
                    break;
11266
 
                }
11267
 
 
11268
 
                if (avail < 2)
11269
 
                    goto done;
11270
 
                cur = ctxt->input->cur[0];
11271
 
                next = ctxt->input->cur[1];
11272
 
                if (cur == 0) {
11273
 
                    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
11274
 
                        ctxt->sax->setDocumentLocator(ctxt->userData,
11275
 
                                                      &xmlDefaultSAXLocator);
11276
 
                    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
11277
 
                    ctxt->instate = XML_PARSER_EOF;
11278
 
#ifdef DEBUG_PUSH
11279
 
                    xmlGenericError(xmlGenericErrorContext,
11280
 
                            "PP: entering EOF\n");
11281
 
#endif
11282
 
                    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
11283
 
                        ctxt->sax->endDocument(ctxt->userData);
11284
 
                    goto done;
11285
 
                }
11286
 
                if ((cur == '<') && (next == '?')) {
11287
 
                    /* PI or XML decl */
11288
 
                    if (avail < 5) return(ret);
11289
 
                    if ((!terminate) &&
11290
 
                        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
11291
 
                        return(ret);
11292
 
                    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
11293
 
                        ctxt->sax->setDocumentLocator(ctxt->userData,
11294
 
                                                      &xmlDefaultSAXLocator);
11295
 
                    if ((ctxt->input->cur[2] == 'x') &&
11296
 
                        (ctxt->input->cur[3] == 'm') &&
11297
 
                        (ctxt->input->cur[4] == 'l') &&
11298
 
                        (IS_BLANK_CH(ctxt->input->cur[5]))) {
11299
 
                        ret += 5;
11300
 
#ifdef DEBUG_PUSH
11301
 
                        xmlGenericError(xmlGenericErrorContext,
11302
 
                                "PP: Parsing XML Decl\n");
11303
 
#endif
11304
 
                        xmlParseXMLDecl(ctxt);
11305
 
                        if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
11306
 
                            /*
11307
 
                             * The XML REC instructs us to stop parsing right
11308
 
                             * here
11309
 
                             */
11310
 
                            ctxt->instate = XML_PARSER_EOF;
11311
 
                            return(0);
11312
 
                        }
11313
 
                        ctxt->standalone = ctxt->input->standalone;
11314
 
                        if ((ctxt->encoding == NULL) &&
11315
 
                            (ctxt->input->encoding != NULL))
11316
 
                            ctxt->encoding = xmlStrdup(ctxt->input->encoding);
11317
 
                        if ((ctxt->sax) && (ctxt->sax->startDocument) &&
11318
 
                            (!ctxt->disableSAX))
11319
 
                            ctxt->sax->startDocument(ctxt->userData);
11320
 
                        ctxt->instate = XML_PARSER_MISC;
11321
 
#ifdef DEBUG_PUSH
11322
 
                        xmlGenericError(xmlGenericErrorContext,
11323
 
                                "PP: entering MISC\n");
11324
 
#endif
11325
 
                    } else {
11326
 
                        ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
11327
 
                        if ((ctxt->sax) && (ctxt->sax->startDocument) &&
11328
 
                            (!ctxt->disableSAX))
11329
 
                            ctxt->sax->startDocument(ctxt->userData);
11330
 
                        ctxt->instate = XML_PARSER_MISC;
11331
 
#ifdef DEBUG_PUSH
11332
 
                        xmlGenericError(xmlGenericErrorContext,
11333
 
                                "PP: entering MISC\n");
11334
 
#endif
11335
 
                    }
11336
 
                } else {
11337
 
                    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
11338
 
                        ctxt->sax->setDocumentLocator(ctxt->userData,
11339
 
                                                      &xmlDefaultSAXLocator);
11340
 
                    ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
11341
 
                    if (ctxt->version == NULL) {
11342
 
                        xmlErrMemory(ctxt, NULL);
11343
 
                        break;
11344
 
                    }
11345
 
                    if ((ctxt->sax) && (ctxt->sax->startDocument) &&
11346
 
                        (!ctxt->disableSAX))
11347
 
                        ctxt->sax->startDocument(ctxt->userData);
11348
 
                    ctxt->instate = XML_PARSER_MISC;
11349
 
#ifdef DEBUG_PUSH
11350
 
                    xmlGenericError(xmlGenericErrorContext,
11351
 
                            "PP: entering MISC\n");
11352
 
#endif
11353
 
                }
11354
 
                break;
11355
 
            case XML_PARSER_START_TAG: {
11356
 
                const xmlChar *name;
11357
 
                const xmlChar *prefix = NULL;
11358
 
                const xmlChar *URI = NULL;
11359
 
                int nsNr = ctxt->nsNr;
11360
 
 
11361
 
                if ((avail < 2) && (ctxt->inputNr == 1))
11362
 
                    goto done;
11363
 
                cur = ctxt->input->cur[0];
11364
 
                if (cur != '<') {
11365
 
                    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
11366
 
                    ctxt->instate = XML_PARSER_EOF;
11367
 
                    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
11368
 
                        ctxt->sax->endDocument(ctxt->userData);
11369
 
                    goto done;
11370
 
                }
11371
 
                if (!terminate) {
11372
 
                    if (ctxt->progressive) {
11373
 
                        /* > can be found unescaped in attribute values */
11374
 
                        if ((lastgt == NULL) || (ctxt->input->cur >= lastgt))
11375
 
                            goto done;
11376
 
                    } else if (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0) {
11377
 
                        goto done;
11378
 
                    }
11379
 
                }
11380
 
                if (ctxt->spaceNr == 0)
11381
 
                    spacePush(ctxt, -1);
11382
 
                else if (*ctxt->space == -2)
11383
 
                    spacePush(ctxt, -1);
11384
 
                else
11385
 
                    spacePush(ctxt, *ctxt->space);
11386
 
#ifdef LIBXML_SAX1_ENABLED
11387
 
                if (ctxt->sax2)
11388
 
#endif /* LIBXML_SAX1_ENABLED */
11389
 
                    name = xmlParseStartTag2(ctxt, &prefix, &URI, &tlen);
11390
 
#ifdef LIBXML_SAX1_ENABLED
11391
 
                else
11392
 
                    name = xmlParseStartTag(ctxt);
11393
 
#endif /* LIBXML_SAX1_ENABLED */
11394
 
                if (ctxt->instate == XML_PARSER_EOF)
11395
 
                    goto done;
11396
 
                if (name == NULL) {
11397
 
                    spacePop(ctxt);
11398
 
                    ctxt->instate = XML_PARSER_EOF;
11399
 
                    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
11400
 
                        ctxt->sax->endDocument(ctxt->userData);
11401
 
                    goto done;
11402
 
                }
11403
 
#ifdef LIBXML_VALID_ENABLED
11404
 
                /*
11405
 
                 * [ VC: Root Element Type ]
11406
 
                 * The Name in the document type declaration must match
11407
 
                 * the element type of the root element.
11408
 
                 */
11409
 
                if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
11410
 
                    ctxt->node && (ctxt->node == ctxt->myDoc->children))
11411
 
                    ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
11412
 
#endif /* LIBXML_VALID_ENABLED */
11413
 
 
11414
 
                /*
11415
 
                 * Check for an Empty Element.
11416
 
                 */
11417
 
                if ((RAW == '/') && (NXT(1) == '>')) {
11418
 
                    SKIP(2);
11419
 
 
11420
 
                    if (ctxt->sax2) {
11421
 
                        if ((ctxt->sax != NULL) &&
11422
 
                            (ctxt->sax->endElementNs != NULL) &&
11423
 
                            (!ctxt->disableSAX))
11424
 
                            ctxt->sax->endElementNs(ctxt->userData, name,
11425
 
                                                    prefix, URI);
11426
 
                        if (ctxt->nsNr - nsNr > 0)
11427
 
                            nsPop(ctxt, ctxt->nsNr - nsNr);
11428
 
#ifdef LIBXML_SAX1_ENABLED
11429
 
                    } else {
11430
 
                        if ((ctxt->sax != NULL) &&
11431
 
                            (ctxt->sax->endElement != NULL) &&
11432
 
                            (!ctxt->disableSAX))
11433
 
                            ctxt->sax->endElement(ctxt->userData, name);
11434
 
#endif /* LIBXML_SAX1_ENABLED */
11435
 
                    }
11436
 
                    if (ctxt->instate == XML_PARSER_EOF)
11437
 
                        goto done;
11438
 
                    spacePop(ctxt);
11439
 
                    if (ctxt->nameNr == 0) {
11440
 
                        ctxt->instate = XML_PARSER_EPILOG;
11441
 
                    } else {
11442
 
                        ctxt->instate = XML_PARSER_CONTENT;
11443
 
                    }
11444
 
                    ctxt->progressive = 1;
11445
 
                    break;
11446
 
                }
11447
 
                if (RAW == '>') {
11448
 
                    NEXT;
11449
 
                } else {
11450
 
                    xmlFatalErrMsgStr(ctxt, XML_ERR_GT_REQUIRED,
11451
 
                                         "Couldn't find end of Start Tag %s\n",
11452
 
                                         name);
11453
 
                    nodePop(ctxt);
11454
 
                    spacePop(ctxt);
11455
 
                }
11456
 
                if (ctxt->sax2)
11457
 
                    nameNsPush(ctxt, name, prefix, URI, ctxt->nsNr - nsNr);
11458
 
#ifdef LIBXML_SAX1_ENABLED
11459
 
                else
11460
 
                    namePush(ctxt, name);
11461
 
#endif /* LIBXML_SAX1_ENABLED */
11462
 
 
11463
 
                ctxt->instate = XML_PARSER_CONTENT;
11464
 
                ctxt->progressive = 1;
11465
 
                break;
11466
 
            }
11467
 
            case XML_PARSER_CONTENT: {
11468
 
                const xmlChar *test;
11469
 
                unsigned int cons;
11470
 
                if ((avail < 2) && (ctxt->inputNr == 1))
11471
 
                    goto done;
11472
 
                cur = ctxt->input->cur[0];
11473
 
                next = ctxt->input->cur[1];
11474
 
 
11475
 
                test = CUR_PTR;
11476
 
                cons = ctxt->input->consumed;
11477
 
                if ((cur == '<') && (next == '/')) {
11478
 
                    ctxt->instate = XML_PARSER_END_TAG;
11479
 
                    break;
11480
 
                } else if ((cur == '<') && (next == '?')) {
11481
 
                    if ((!terminate) &&
11482
 
                        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0)) {
11483
 
                        ctxt->progressive = XML_PARSER_PI;
11484
 
                        goto done;
11485
 
                    }
11486
 
                    xmlParsePI(ctxt);
11487
 
                    ctxt->instate = XML_PARSER_CONTENT;
11488
 
                    ctxt->progressive = 1;
11489
 
                } else if ((cur == '<') && (next != '!')) {
11490
 
                    ctxt->instate = XML_PARSER_START_TAG;
11491
 
                    break;
11492
 
                } else if ((cur == '<') && (next == '!') &&
11493
 
                           (ctxt->input->cur[2] == '-') &&
11494
 
                           (ctxt->input->cur[3] == '-')) {
11495
 
                    int term;
11496
 
 
11497
 
                    if (avail < 4)
11498
 
                        goto done;
11499
 
                    ctxt->input->cur += 4;
11500
 
                    term = xmlParseLookupSequence(ctxt, '-', '-', '>');
11501
 
                    ctxt->input->cur -= 4;
11502
 
                    if ((!terminate) && (term < 0)) {
11503
 
                        ctxt->progressive = XML_PARSER_COMMENT;
11504
 
                        goto done;
11505
 
                    }
11506
 
                    xmlParseComment(ctxt);
11507
 
                    ctxt->instate = XML_PARSER_CONTENT;
11508
 
                    ctxt->progressive = 1;
11509
 
                } else if ((cur == '<') && (ctxt->input->cur[1] == '!') &&
11510
 
                    (ctxt->input->cur[2] == '[') &&
11511
 
                    (ctxt->input->cur[3] == 'C') &&
11512
 
                    (ctxt->input->cur[4] == 'D') &&
11513
 
                    (ctxt->input->cur[5] == 'A') &&
11514
 
                    (ctxt->input->cur[6] == 'T') &&
11515
 
                    (ctxt->input->cur[7] == 'A') &&
11516
 
                    (ctxt->input->cur[8] == '[')) {
11517
 
                    SKIP(9);
11518
 
                    ctxt->instate = XML_PARSER_CDATA_SECTION;
11519
 
                    break;
11520
 
                } else if ((cur == '<') && (next == '!') &&
11521
 
                           (avail < 9)) {
11522
 
                    goto done;
11523
 
                } else if (cur == '&') {
11524
 
                    if ((!terminate) &&
11525
 
                        (xmlParseLookupSequence(ctxt, ';', 0, 0) < 0))
11526
 
                        goto done;
11527
 
                    xmlParseReference(ctxt);
11528
 
                } else {
11529
 
                    /* TODO Avoid the extra copy, handle directly !!! */
11530
 
                    /*
11531
 
                     * Goal of the following test is:
11532
 
                     *  - minimize calls to the SAX 'character' callback
11533
 
                     *    when they are mergeable
11534
 
                     *  - handle an problem for isBlank when we only parse
11535
 
                     *    a sequence of blank chars and the next one is
11536
 
                     *    not available to check against '<' presence.
11537
 
                     *  - tries to homogenize the differences in SAX
11538
 
                     *    callbacks between the push and pull versions
11539
 
                     *    of the parser.
11540
 
                     */
11541
 
                    if ((ctxt->inputNr == 1) &&
11542
 
                        (avail < XML_PARSER_BIG_BUFFER_SIZE)) {
11543
 
                        if (!terminate) {
11544
 
                            if (ctxt->progressive) {
11545
 
                                if ((lastlt == NULL) ||
11546
 
                                    (ctxt->input->cur > lastlt))
11547
 
                                    goto done;
11548
 
                            } else if (xmlParseLookupSequence(ctxt,
11549
 
                                                              '<', 0, 0) < 0) {
11550
 
                                goto done;
11551
 
                            }
11552
 
                        }
11553
 
                    }
11554
 
                    ctxt->checkIndex = 0;
11555
 
                    xmlParseCharData(ctxt, 0);
11556
 
                }
11557
 
                /*
11558
 
                 * Pop-up of finished entities.
11559
 
                 */
11560
 
                while ((RAW == 0) && (ctxt->inputNr > 1))
11561
 
                    xmlPopInput(ctxt);
11562
 
                if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
11563
 
                    xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
11564
 
                                "detected an error in element content\n");
11565
 
                    ctxt->instate = XML_PARSER_EOF;
11566
 
                    break;
11567
 
                }
11568
 
                break;
11569
 
            }
11570
 
            case XML_PARSER_END_TAG:
11571
 
                if (avail < 2)
11572
 
                    goto done;
11573
 
                if (!terminate) {
11574
 
                    if (ctxt->progressive) {
11575
 
                        /* > can be found unescaped in attribute values */
11576
 
                        if ((lastgt == NULL) || (ctxt->input->cur >= lastgt))
11577
 
                            goto done;
11578
 
                    } else if (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0) {
11579
 
                        goto done;
11580
 
                    }
11581
 
                }
11582
 
                if (ctxt->sax2) {
11583
 
                    xmlParseEndTag2(ctxt,
11584
 
                           (void *) ctxt->pushTab[ctxt->nameNr * 3 - 3],
11585
 
                           (void *) ctxt->pushTab[ctxt->nameNr * 3 - 2], 0,
11586
 
                       (int) (long) ctxt->pushTab[ctxt->nameNr * 3 - 1], 0);
11587
 
                    nameNsPop(ctxt);
11588
 
                }
11589
 
#ifdef LIBXML_SAX1_ENABLED
11590
 
                  else
11591
 
                    xmlParseEndTag1(ctxt, 0);
11592
 
#endif /* LIBXML_SAX1_ENABLED */
11593
 
                if (ctxt->instate == XML_PARSER_EOF) {
11594
 
                    /* Nothing */
11595
 
                } else if (ctxt->nameNr == 0) {
11596
 
                    ctxt->instate = XML_PARSER_EPILOG;
11597
 
                } else {
11598
 
                    ctxt->instate = XML_PARSER_CONTENT;
11599
 
                }
11600
 
                break;
11601
 
            case XML_PARSER_CDATA_SECTION: {
11602
 
                /*
11603
 
                 * The Push mode need to have the SAX callback for
11604
 
                 * cdataBlock merge back contiguous callbacks.
11605
 
                 */
11606
 
                int base;
11607
 
 
11608
 
                base = xmlParseLookupSequence(ctxt, ']', ']', '>');
11609
 
                if (base < 0) {
11610
 
                    if (avail >= XML_PARSER_BIG_BUFFER_SIZE + 2) {
11611
 
                        int tmp;
11612
 
 
11613
 
                        tmp = xmlCheckCdataPush(ctxt->input->cur,
11614
 
                                                XML_PARSER_BIG_BUFFER_SIZE);
11615
 
                        if (tmp < 0) {
11616
 
                            tmp = -tmp;
11617
 
                            ctxt->input->cur += tmp;
11618
 
                            goto encoding_error;
11619
 
                        }
11620
 
                        if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
11621
 
                            if (ctxt->sax->cdataBlock != NULL)
11622
 
                                ctxt->sax->cdataBlock(ctxt->userData,
11623
 
                                                      ctxt->input->cur, tmp);
11624
 
                            else if (ctxt->sax->characters != NULL)
11625
 
                                ctxt->sax->characters(ctxt->userData,
11626
 
                                                      ctxt->input->cur, tmp);
11627
 
                        }
11628
 
                        if (ctxt->instate == XML_PARSER_EOF)
11629
 
                            goto done;
11630
 
                        SKIPL(tmp);
11631
 
                        ctxt->checkIndex = 0;
11632
 
                    }
11633
 
                    goto done;
11634
 
                } else {
11635
 
                    int tmp;
11636
 
 
11637
 
                    tmp = xmlCheckCdataPush(ctxt->input->cur, base);
11638
 
                    if ((tmp < 0) || (tmp != base)) {
11639
 
                        tmp = -tmp;
11640
 
                        ctxt->input->cur += tmp;
11641
 
                        goto encoding_error;
11642
 
                    }
11643
 
                    if ((ctxt->sax != NULL) && (base == 0) &&
11644
 
                        (ctxt->sax->cdataBlock != NULL) &&
11645
 
                        (!ctxt->disableSAX)) {
11646
 
                        /*
11647
 
                         * Special case to provide identical behaviour
11648
 
                         * between pull and push parsers on enpty CDATA
11649
 
                         * sections
11650
 
                         */
11651
 
                         if ((ctxt->input->cur - ctxt->input->base >= 9) &&
11652
 
                             (!strncmp((const char *)&ctxt->input->cur[-9],
11653
 
                                       "<![CDATA[", 9)))
11654
 
                             ctxt->sax->cdataBlock(ctxt->userData,
11655
 
                                                   BAD_CAST "", 0);
11656
 
                    } else if ((ctxt->sax != NULL) && (base > 0) &&
11657
 
                        (!ctxt->disableSAX)) {
11658
 
                        if (ctxt->sax->cdataBlock != NULL)
11659
 
                            ctxt->sax->cdataBlock(ctxt->userData,
11660
 
                                                  ctxt->input->cur, base);
11661
 
                        else if (ctxt->sax->characters != NULL)
11662
 
                            ctxt->sax->characters(ctxt->userData,
11663
 
                                                  ctxt->input->cur, base);
11664
 
                    }
11665
 
                    if (ctxt->instate == XML_PARSER_EOF)
11666
 
                        goto done;
11667
 
                    SKIPL(base + 3);
11668
 
                    ctxt->checkIndex = 0;
11669
 
                    ctxt->instate = XML_PARSER_CONTENT;
11670
 
#ifdef DEBUG_PUSH
11671
 
                    xmlGenericError(xmlGenericErrorContext,
11672
 
                            "PP: entering CONTENT\n");
11673
 
#endif
11674
 
                }
11675
 
                break;
11676
 
            }
11677
 
            case XML_PARSER_MISC:
11678
 
                SKIP_BLANKS;
11679
 
                if (ctxt->input->buf == NULL)
11680
 
                    avail = ctxt->input->length -
11681
 
                            (ctxt->input->cur - ctxt->input->base);
11682
 
                else
11683
 
                    avail = xmlBufUse(ctxt->input->buf->buffer) -
11684
 
                            (ctxt->input->cur - ctxt->input->base);
11685
 
                if (avail < 2)
11686
 
                    goto done;
11687
 
                cur = ctxt->input->cur[0];
11688
 
                next = ctxt->input->cur[1];
11689
 
                if ((cur == '<') && (next == '?')) {
11690
 
                    if ((!terminate) &&
11691
 
                        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0)) {
11692
 
                        ctxt->progressive = XML_PARSER_PI;
11693
 
                        goto done;
11694
 
                    }
11695
 
#ifdef DEBUG_PUSH
11696
 
                    xmlGenericError(xmlGenericErrorContext,
11697
 
                            "PP: Parsing PI\n");
11698
 
#endif
11699
 
                    xmlParsePI(ctxt);
11700
 
                    if (ctxt->instate == XML_PARSER_EOF)
11701
 
                        goto done;
11702
 
                    ctxt->instate = XML_PARSER_MISC;
11703
 
                    ctxt->progressive = 1;
11704
 
                    ctxt->checkIndex = 0;
11705
 
                } else if ((cur == '<') && (next == '!') &&
11706
 
                    (ctxt->input->cur[2] == '-') &&
11707
 
                    (ctxt->input->cur[3] == '-')) {
11708
 
                    if ((!terminate) &&
11709
 
                        (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0)) {
11710
 
                        ctxt->progressive = XML_PARSER_COMMENT;
11711
 
                        goto done;
11712
 
                    }
11713
 
#ifdef DEBUG_PUSH
11714
 
                    xmlGenericError(xmlGenericErrorContext,
11715
 
                            "PP: Parsing Comment\n");
11716
 
#endif
11717
 
                    xmlParseComment(ctxt);
11718
 
                    if (ctxt->instate == XML_PARSER_EOF)
11719
 
                        goto done;
11720
 
                    ctxt->instate = XML_PARSER_MISC;
11721
 
                    ctxt->progressive = 1;
11722
 
                    ctxt->checkIndex = 0;
11723
 
                } else if ((cur == '<') && (next == '!') &&
11724
 
                    (ctxt->input->cur[2] == 'D') &&
11725
 
                    (ctxt->input->cur[3] == 'O') &&
11726
 
                    (ctxt->input->cur[4] == 'C') &&
11727
 
                    (ctxt->input->cur[5] == 'T') &&
11728
 
                    (ctxt->input->cur[6] == 'Y') &&
11729
 
                    (ctxt->input->cur[7] == 'P') &&
11730
 
                    (ctxt->input->cur[8] == 'E')) {
11731
 
                    if ((!terminate) &&
11732
 
                        (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0)) {
11733
 
                        ctxt->progressive = XML_PARSER_DTD;
11734
 
                        goto done;
11735
 
                    }
11736
 
#ifdef DEBUG_PUSH
11737
 
                    xmlGenericError(xmlGenericErrorContext,
11738
 
                            "PP: Parsing internal subset\n");
11739
 
#endif
11740
 
                    ctxt->inSubset = 1;
11741
 
                    ctxt->progressive = 0;
11742
 
                    ctxt->checkIndex = 0;
11743
 
                    xmlParseDocTypeDecl(ctxt);
11744
 
                    if (ctxt->instate == XML_PARSER_EOF)
11745
 
                        goto done;
11746
 
                    if (RAW == '[') {
11747
 
                        ctxt->instate = XML_PARSER_DTD;
11748
 
#ifdef DEBUG_PUSH
11749
 
                        xmlGenericError(xmlGenericErrorContext,
11750
 
                                "PP: entering DTD\n");
11751
 
#endif
11752
 
                    } else {
11753
 
                        /*
11754
 
                         * Create and update the external subset.
11755
 
                         */
11756
 
                        ctxt->inSubset = 2;
11757
 
                        if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
11758
 
                            (ctxt->sax->externalSubset != NULL))
11759
 
                            ctxt->sax->externalSubset(ctxt->userData,
11760
 
                                    ctxt->intSubName, ctxt->extSubSystem,
11761
 
                                    ctxt->extSubURI);
11762
 
                        ctxt->inSubset = 0;
11763
 
                        xmlCleanSpecialAttr(ctxt);
11764
 
                        ctxt->instate = XML_PARSER_PROLOG;
11765
 
#ifdef DEBUG_PUSH
11766
 
                        xmlGenericError(xmlGenericErrorContext,
11767
 
                                "PP: entering PROLOG\n");
11768
 
#endif
11769
 
                    }
11770
 
                } else if ((cur == '<') && (next == '!') &&
11771
 
                           (avail < 9)) {
11772
 
                    goto done;
11773
 
                } else {
11774
 
                    ctxt->instate = XML_PARSER_START_TAG;
11775
 
                    ctxt->progressive = XML_PARSER_START_TAG;
11776
 
                    xmlParseGetLasts(ctxt, &lastlt, &lastgt);
11777
 
#ifdef DEBUG_PUSH
11778
 
                    xmlGenericError(xmlGenericErrorContext,
11779
 
                            "PP: entering START_TAG\n");
11780
 
#endif
11781
 
                }
11782
 
                break;
11783
 
            case XML_PARSER_PROLOG:
11784
 
                SKIP_BLANKS;
11785
 
                if (ctxt->input->buf == NULL)
11786
 
                    avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
11787
 
                else
11788
 
                    avail = xmlBufUse(ctxt->input->buf->buffer) -
11789
 
                            (ctxt->input->cur - ctxt->input->base);
11790
 
                if (avail < 2)
11791
 
                    goto done;
11792
 
                cur = ctxt->input->cur[0];
11793
 
                next = ctxt->input->cur[1];
11794
 
                if ((cur == '<') && (next == '?')) {
11795
 
                    if ((!terminate) &&
11796
 
                        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0)) {
11797
 
                        ctxt->progressive = XML_PARSER_PI;
11798
 
                        goto done;
11799
 
                    }
11800
 
#ifdef DEBUG_PUSH
11801
 
                    xmlGenericError(xmlGenericErrorContext,
11802
 
                            "PP: Parsing PI\n");
11803
 
#endif
11804
 
                    xmlParsePI(ctxt);
11805
 
                    if (ctxt->instate == XML_PARSER_EOF)
11806
 
                        goto done;
11807
 
                    ctxt->instate = XML_PARSER_PROLOG;
11808
 
                    ctxt->progressive = 1;
11809
 
                } else if ((cur == '<') && (next == '!') &&
11810
 
                    (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
11811
 
                    if ((!terminate) &&
11812
 
                        (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0)) {
11813
 
                        ctxt->progressive = XML_PARSER_COMMENT;
11814
 
                        goto done;
11815
 
                    }
11816
 
#ifdef DEBUG_PUSH
11817
 
                    xmlGenericError(xmlGenericErrorContext,
11818
 
                            "PP: Parsing Comment\n");
11819
 
#endif
11820
 
                    xmlParseComment(ctxt);
11821
 
                    if (ctxt->instate == XML_PARSER_EOF)
11822
 
                        goto done;
11823
 
                    ctxt->instate = XML_PARSER_PROLOG;
11824
 
                    ctxt->progressive = 1;
11825
 
                } else if ((cur == '<') && (next == '!') &&
11826
 
                           (avail < 4)) {
11827
 
                    goto done;
11828
 
                } else {
11829
 
                    ctxt->instate = XML_PARSER_START_TAG;
11830
 
                    if (ctxt->progressive == 0)
11831
 
                        ctxt->progressive = XML_PARSER_START_TAG;
11832
 
                    xmlParseGetLasts(ctxt, &lastlt, &lastgt);
11833
 
#ifdef DEBUG_PUSH
11834
 
                    xmlGenericError(xmlGenericErrorContext,
11835
 
                            "PP: entering START_TAG\n");
11836
 
#endif
11837
 
                }
11838
 
                break;
11839
 
            case XML_PARSER_EPILOG:
11840
 
                SKIP_BLANKS;
11841
 
                if (ctxt->input->buf == NULL)
11842
 
                    avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
11843
 
                else
11844
 
                    avail = xmlBufUse(ctxt->input->buf->buffer) -
11845
 
                            (ctxt->input->cur - ctxt->input->base);
11846
 
                if (avail < 2)
11847
 
                    goto done;
11848
 
                cur = ctxt->input->cur[0];
11849
 
                next = ctxt->input->cur[1];
11850
 
                if ((cur == '<') && (next == '?')) {
11851
 
                    if ((!terminate) &&
11852
 
                        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0)) {
11853
 
                        ctxt->progressive = XML_PARSER_PI;
11854
 
                        goto done;
11855
 
                    }
11856
 
#ifdef DEBUG_PUSH
11857
 
                    xmlGenericError(xmlGenericErrorContext,
11858
 
                            "PP: Parsing PI\n");
11859
 
#endif
11860
 
                    xmlParsePI(ctxt);
11861
 
                    if (ctxt->instate == XML_PARSER_EOF)
11862
 
                        goto done;
11863
 
                    ctxt->instate = XML_PARSER_EPILOG;
11864
 
                    ctxt->progressive = 1;
11865
 
                } else if ((cur == '<') && (next == '!') &&
11866
 
                    (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
11867
 
                    if ((!terminate) &&
11868
 
                        (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0)) {
11869
 
                        ctxt->progressive = XML_PARSER_COMMENT;
11870
 
                        goto done;
11871
 
                    }
11872
 
#ifdef DEBUG_PUSH
11873
 
                    xmlGenericError(xmlGenericErrorContext,
11874
 
                            "PP: Parsing Comment\n");
11875
 
#endif
11876
 
                    xmlParseComment(ctxt);
11877
 
                    if (ctxt->instate == XML_PARSER_EOF)
11878
 
                        goto done;
11879
 
                    ctxt->instate = XML_PARSER_EPILOG;
11880
 
                    ctxt->progressive = 1;
11881
 
                } else if ((cur == '<') && (next == '!') &&
11882
 
                           (avail < 4)) {
11883
 
                    goto done;
11884
 
                } else {
11885
 
                    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
11886
 
                    ctxt->instate = XML_PARSER_EOF;
11887
 
#ifdef DEBUG_PUSH
11888
 
                    xmlGenericError(xmlGenericErrorContext,
11889
 
                            "PP: entering EOF\n");
11890
 
#endif
11891
 
                    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
11892
 
                        ctxt->sax->endDocument(ctxt->userData);
11893
 
                    goto done;
11894
 
                }
11895
 
                break;
11896
 
            case XML_PARSER_DTD: {
11897
 
                /*
11898
 
                 * Sorry but progressive parsing of the internal subset
11899
 
                 * is not expected to be supported. We first check that
11900
 
                 * the full content of the internal subset is available and
11901
 
                 * the parsing is launched only at that point.
11902
 
                 * Internal subset ends up with "']' S? '>'" in an unescaped
11903
 
                 * section and not in a ']]>' sequence which are conditional
11904
 
                 * sections (whoever argued to keep that crap in XML deserve
11905
 
                 * a place in hell !).
11906
 
                 */
11907
 
                int base, i;
11908
 
                xmlChar *buf;
11909
 
                xmlChar quote = 0;
11910
 
                size_t use;
11911
 
 
11912
 
                base = ctxt->input->cur - ctxt->input->base;
11913
 
                if (base < 0) return(0);
11914
 
                if (ctxt->checkIndex > base)
11915
 
                    base = ctxt->checkIndex;
11916
 
                buf = xmlBufContent(ctxt->input->buf->buffer);
11917
 
                use = xmlBufUse(ctxt->input->buf->buffer);
11918
 
                for (;(unsigned int) base < use; base++) {
11919
 
                    if (quote != 0) {
11920
 
                        if (buf[base] == quote)
11921
 
                            quote = 0;
11922
 
                        continue;
11923
 
                    }
11924
 
                    if ((quote == 0) && (buf[base] == '<')) {
11925
 
                        int found  = 0;
11926
 
                        /* special handling of comments */
11927
 
                        if (((unsigned int) base + 4 < use) &&
11928
 
                            (buf[base + 1] == '!') &&
11929
 
                            (buf[base + 2] == '-') &&
11930
 
                            (buf[base + 3] == '-')) {
11931
 
                            for (;(unsigned int) base + 3 < use; base++) {
11932
 
                                if ((buf[base] == '-') &&
11933
 
                                    (buf[base + 1] == '-') &&
11934
 
                                    (buf[base + 2] == '>')) {
11935
 
                                    found = 1;
11936
 
                                    base += 2;
11937
 
                                    break;
11938
 
                                }
11939
 
                            }
11940
 
                            if (!found) {
11941
 
#if 0
11942
 
                                fprintf(stderr, "unfinished comment\n");
11943
 
#endif
11944
 
                                break; /* for */
11945
 
                            }
11946
 
                            continue;
11947
 
                        }
11948
 
                    }
11949
 
                    if (buf[base] == '"') {
11950
 
                        quote = '"';
11951
 
                        continue;
11952
 
                    }
11953
 
                    if (buf[base] == '\'') {
11954
 
                        quote = '\'';
11955
 
                        continue;
11956
 
                    }
11957
 
                    if (buf[base] == ']') {
11958
 
#if 0
11959
 
                        fprintf(stderr, "%c%c%c%c: ", buf[base],
11960
 
                                buf[base + 1], buf[base + 2], buf[base + 3]);
11961
 
#endif
11962
 
                        if ((unsigned int) base +1 >= use)
11963
 
                            break;
11964
 
                        if (buf[base + 1] == ']') {
11965
 
                            /* conditional crap, skip both ']' ! */
11966
 
                            base++;
11967
 
                            continue;
11968
 
                        }
11969
 
                        for (i = 1; (unsigned int) base + i < use; i++) {
11970
 
                            if (buf[base + i] == '>') {
11971
 
#if 0
11972
 
                                fprintf(stderr, "found\n");
11973
 
#endif
11974
 
                                goto found_end_int_subset;
11975
 
                            }
11976
 
                            if (!IS_BLANK_CH(buf[base + i])) {
11977
 
#if 0
11978
 
                                fprintf(stderr, "not found\n");
11979
 
#endif
11980
 
                                goto not_end_of_int_subset;
11981
 
                            }
11982
 
                        }
11983
 
#if 0
11984
 
                        fprintf(stderr, "end of stream\n");
11985
 
#endif
11986
 
                        break;
11987
 
 
11988
 
                    }
11989
 
not_end_of_int_subset:
11990
 
                    continue; /* for */
11991
 
                }
11992
 
                /*
11993
 
                 * We didn't found the end of the Internal subset
11994
 
                 */
11995
 
                if (quote == 0)
11996
 
                    ctxt->checkIndex = base;
11997
 
                else
11998
 
                    ctxt->checkIndex = 0;
11999
 
#ifdef DEBUG_PUSH
12000
 
                if (next == 0)
12001
 
                    xmlGenericError(xmlGenericErrorContext,
12002
 
                            "PP: lookup of int subset end filed\n");
12003
 
#endif
12004
 
                goto done;
12005
 
 
12006
 
found_end_int_subset:
12007
 
                ctxt->checkIndex = 0;
12008
 
                xmlParseInternalSubset(ctxt);
12009
 
                if (ctxt->instate == XML_PARSER_EOF)
12010
 
                    goto done;
12011
 
                ctxt->inSubset = 2;
12012
 
                if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
12013
 
                    (ctxt->sax->externalSubset != NULL))
12014
 
                    ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
12015
 
                            ctxt->extSubSystem, ctxt->extSubURI);
12016
 
                ctxt->inSubset = 0;
12017
 
                xmlCleanSpecialAttr(ctxt);
12018
 
                if (ctxt->instate == XML_PARSER_EOF)
12019
 
                    goto done;
12020
 
                ctxt->instate = XML_PARSER_PROLOG;
12021
 
                ctxt->checkIndex = 0;
12022
 
#ifdef DEBUG_PUSH
12023
 
                xmlGenericError(xmlGenericErrorContext,
12024
 
                        "PP: entering PROLOG\n");
12025
 
#endif
12026
 
                break;
12027
 
            }
12028
 
            case XML_PARSER_COMMENT:
12029
 
                xmlGenericError(xmlGenericErrorContext,
12030
 
                        "PP: internal error, state == COMMENT\n");
12031
 
                ctxt->instate = XML_PARSER_CONTENT;
12032
 
#ifdef DEBUG_PUSH
12033
 
                xmlGenericError(xmlGenericErrorContext,
12034
 
                        "PP: entering CONTENT\n");
12035
 
#endif
12036
 
                break;
12037
 
            case XML_PARSER_IGNORE:
12038
 
                xmlGenericError(xmlGenericErrorContext,
12039
 
                        "PP: internal error, state == IGNORE");
12040
 
                ctxt->instate = XML_PARSER_DTD;
12041
 
#ifdef DEBUG_PUSH
12042
 
                xmlGenericError(xmlGenericErrorContext,
12043
 
                        "PP: entering DTD\n");
12044
 
#endif
12045
 
                break;
12046
 
            case XML_PARSER_PI:
12047
 
                xmlGenericError(xmlGenericErrorContext,
12048
 
                        "PP: internal error, state == PI\n");
12049
 
                ctxt->instate = XML_PARSER_CONTENT;
12050
 
#ifdef DEBUG_PUSH
12051
 
                xmlGenericError(xmlGenericErrorContext,
12052
 
                        "PP: entering CONTENT\n");
12053
 
#endif
12054
 
                break;
12055
 
            case XML_PARSER_ENTITY_DECL:
12056
 
                xmlGenericError(xmlGenericErrorContext,
12057
 
                        "PP: internal error, state == ENTITY_DECL\n");
12058
 
                ctxt->instate = XML_PARSER_DTD;
12059
 
#ifdef DEBUG_PUSH
12060
 
                xmlGenericError(xmlGenericErrorContext,
12061
 
                        "PP: entering DTD\n");
12062
 
#endif
12063
 
                break;
12064
 
            case XML_PARSER_ENTITY_VALUE:
12065
 
                xmlGenericError(xmlGenericErrorContext,
12066
 
                        "PP: internal error, state == ENTITY_VALUE\n");
12067
 
                ctxt->instate = XML_PARSER_CONTENT;
12068
 
#ifdef DEBUG_PUSH
12069
 
                xmlGenericError(xmlGenericErrorContext,
12070
 
                        "PP: entering DTD\n");
12071
 
#endif
12072
 
                break;
12073
 
            case XML_PARSER_ATTRIBUTE_VALUE:
12074
 
                xmlGenericError(xmlGenericErrorContext,
12075
 
                        "PP: internal error, state == ATTRIBUTE_VALUE\n");
12076
 
                ctxt->instate = XML_PARSER_START_TAG;
12077
 
#ifdef DEBUG_PUSH
12078
 
                xmlGenericError(xmlGenericErrorContext,
12079
 
                        "PP: entering START_TAG\n");
12080
 
#endif
12081
 
                break;
12082
 
            case XML_PARSER_SYSTEM_LITERAL:
12083
 
                xmlGenericError(xmlGenericErrorContext,
12084
 
                        "PP: internal error, state == SYSTEM_LITERAL\n");
12085
 
                ctxt->instate = XML_PARSER_START_TAG;
12086
 
#ifdef DEBUG_PUSH
12087
 
                xmlGenericError(xmlGenericErrorContext,
12088
 
                        "PP: entering START_TAG\n");
12089
 
#endif
12090
 
                break;
12091
 
            case XML_PARSER_PUBLIC_LITERAL:
12092
 
                xmlGenericError(xmlGenericErrorContext,
12093
 
                        "PP: internal error, state == PUBLIC_LITERAL\n");
12094
 
                ctxt->instate = XML_PARSER_START_TAG;
12095
 
#ifdef DEBUG_PUSH
12096
 
                xmlGenericError(xmlGenericErrorContext,
12097
 
                        "PP: entering START_TAG\n");
12098
 
#endif
12099
 
                break;
12100
 
        }
12101
 
    }
12102
 
done:
12103
 
#ifdef DEBUG_PUSH
12104
 
    xmlGenericError(xmlGenericErrorContext, "PP: done %d\n", ret);
12105
 
#endif
12106
 
    return(ret);
12107
 
encoding_error:
12108
 
    {
12109
 
        char buffer[150];
12110
 
 
12111
 
        snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
12112
 
                        ctxt->input->cur[0], ctxt->input->cur[1],
12113
 
                        ctxt->input->cur[2], ctxt->input->cur[3]);
12114
 
        __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
12115
 
                     "Input is not proper UTF-8, indicate encoding !\n%s",
12116
 
                     BAD_CAST buffer, NULL);
12117
 
    }
12118
 
    return(0);
12119
 
}
12120
 
 
12121
 
/**
12122
 
 * xmlParseCheckTransition:
12123
 
 * @ctxt:  an XML parser context
12124
 
 * @chunk:  a char array
12125
 
 * @size:  the size in byte of the chunk
12126
 
 *
12127
 
 * Check depending on the current parser state if the chunk given must be
12128
 
 * processed immediately or one need more data to advance on parsing.
12129
 
 *
12130
 
 * Returns -1 in case of error, 0 if the push is not needed and 1 if needed
12131
 
 */
12132
 
static int
12133
 
xmlParseCheckTransition(xmlParserCtxtPtr ctxt, const char *chunk, int size) {
12134
 
    if ((ctxt == NULL) || (chunk == NULL) || (size < 0))
12135
 
        return(-1);
12136
 
    if (ctxt->instate == XML_PARSER_START_TAG) {
12137
 
        if (memchr(chunk, '>', size) != NULL)
12138
 
            return(1);
12139
 
        return(0);
12140
 
    }
12141
 
    if (ctxt->progressive == XML_PARSER_COMMENT) {
12142
 
        if (memchr(chunk, '>', size) != NULL)
12143
 
            return(1);
12144
 
        return(0);
12145
 
    }
12146
 
    if (ctxt->instate == XML_PARSER_CDATA_SECTION) {
12147
 
        if (memchr(chunk, '>', size) != NULL)
12148
 
            return(1);
12149
 
        return(0);
12150
 
    }
12151
 
    if (ctxt->progressive == XML_PARSER_PI) {
12152
 
        if (memchr(chunk, '>', size) != NULL)
12153
 
            return(1);
12154
 
        return(0);
12155
 
    }
12156
 
    if (ctxt->instate == XML_PARSER_END_TAG) {
12157
 
        if (memchr(chunk, '>', size) != NULL)
12158
 
            return(1);
12159
 
        return(0);
12160
 
    }
12161
 
    if ((ctxt->progressive == XML_PARSER_DTD) ||
12162
 
        (ctxt->instate == XML_PARSER_DTD)) {
12163
 
        if (memchr(chunk, '>', size) != NULL)
12164
 
            return(1);
12165
 
        return(0);
12166
 
    }
12167
 
    return(1);
12168
 
}
12169
 
 
12170
 
/**
12171
 
 * xmlParseChunk:
12172
 
 * @ctxt:  an XML parser context
12173
 
 * @chunk:  an char array
12174
 
 * @size:  the size in byte of the chunk
12175
 
 * @terminate:  last chunk indicator
12176
 
 *
12177
 
 * Parse a Chunk of memory
12178
 
 *
12179
 
 * Returns zero if no error, the xmlParserErrors otherwise.
12180
 
 */
12181
 
int
12182
 
xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
12183
 
              int terminate) {
12184
 
    int end_in_lf = 0;
12185
 
    int remain = 0;
12186
 
    size_t old_avail = 0;
12187
 
    size_t avail = 0;
12188
 
 
12189
 
    if (ctxt == NULL)
12190
 
        return(XML_ERR_INTERNAL_ERROR);
12191
 
    if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
12192
 
        return(ctxt->errNo);
12193
 
    if (ctxt->instate == XML_PARSER_EOF)
12194
 
        return(-1);
12195
 
    if (ctxt->instate == XML_PARSER_START)
12196
 
        xmlDetectSAX2(ctxt);
12197
 
    if ((size > 0) && (chunk != NULL) && (!terminate) &&
12198
 
        (chunk[size - 1] == '\r')) {
12199
 
        end_in_lf = 1;
12200
 
        size--;
12201
 
    }
12202
 
 
12203
 
xmldecl_done:
12204
 
 
12205
 
    if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
12206
 
        (ctxt->input->buf != NULL) && (ctxt->instate != XML_PARSER_EOF))  {
12207
 
        size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer, ctxt->input);
12208
 
        size_t cur = ctxt->input->cur - ctxt->input->base;
12209
 
        int res;
12210
 
 
12211
 
        old_avail = xmlBufUse(ctxt->input->buf->buffer);
12212
 
        /*
12213
 
         * Specific handling if we autodetected an encoding, we should not
12214
 
         * push more than the first line ... which depend on the encoding
12215
 
         * And only push the rest once the final encoding was detected
12216
 
         */
12217
 
        if ((ctxt->instate == XML_PARSER_START) && (ctxt->input != NULL) &&
12218
 
            (ctxt->input->buf != NULL) && (ctxt->input->buf->encoder != NULL)) {
12219
 
            unsigned int len = 45;
12220
 
 
12221
 
            if ((xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
12222
 
                               BAD_CAST "UTF-16")) ||
12223
 
                (xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
12224
 
                               BAD_CAST "UTF16")))
12225
 
                len = 90;
12226
 
            else if ((xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
12227
 
                                    BAD_CAST "UCS-4")) ||
12228
 
                     (xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
12229
 
                                    BAD_CAST "UCS4")))
12230
 
                len = 180;
12231
 
 
12232
 
            if (ctxt->input->buf->rawconsumed < len)
12233
 
                len -= ctxt->input->buf->rawconsumed;
12234
 
 
12235
 
            /*
12236
 
             * Change size for reading the initial declaration only
12237
 
             * if size is greater than len. Otherwise, memmove in xmlBufferAdd
12238
 
             * will blindly copy extra bytes from memory.
12239
 
             */
12240
 
            if ((unsigned int) size > len) {
12241
 
                remain = size - len;
12242
 
                size = len;
12243
 
            } else {
12244
 
                remain = 0;
12245
 
            }
12246
 
        }
12247
 
        res = xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
12248
 
        if (res < 0) {
12249
 
            ctxt->errNo = XML_PARSER_EOF;
12250
 
            ctxt->disableSAX = 1;
12251
 
            return (XML_PARSER_EOF);
12252
 
        }
12253
 
        xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur);
12254
 
#ifdef DEBUG_PUSH
12255
 
        xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
12256
 
#endif
12257
 
 
12258
 
    } else if (ctxt->instate != XML_PARSER_EOF) {
12259
 
        if ((ctxt->input != NULL) && ctxt->input->buf != NULL) {
12260
 
            xmlParserInputBufferPtr in = ctxt->input->buf;
12261
 
            if ((in->encoder != NULL) && (in->buffer != NULL) &&
12262
 
                    (in->raw != NULL)) {
12263
 
                int nbchars;
12264
 
                size_t base = xmlBufGetInputBase(in->buffer, ctxt->input);
12265
 
                size_t current = ctxt->input->cur - ctxt->input->base;
12266
 
 
12267
 
                nbchars = xmlCharEncInput(in, terminate);
12268
 
                if (nbchars < 0) {
12269
 
                    /* TODO 2.6.0 */
12270
 
                    xmlGenericError(xmlGenericErrorContext,
12271
 
                                    "xmlParseChunk: encoder error\n");
12272
 
                    return(XML_ERR_INVALID_ENCODING);
12273
 
                }
12274
 
                xmlBufSetInputBaseCur(in->buffer, ctxt->input, base, current);
12275
 
            }
12276
 
        }
12277
 
    }
12278
 
    if (remain != 0) {
12279
 
        xmlParseTryOrFinish(ctxt, 0);
12280
 
    } else {
12281
 
        if ((ctxt->input != NULL) && (ctxt->input->buf != NULL))
12282
 
            avail = xmlBufUse(ctxt->input->buf->buffer);
12283
 
        /*
12284
 
         * Depending on the current state it may not be such
12285
 
         * a good idea to try parsing if there is nothing in the chunk
12286
 
         * which would be worth doing a parser state transition and we
12287
 
         * need to wait for more data
12288
 
         */
12289
 
        if ((terminate) || (avail > XML_MAX_TEXT_LENGTH) ||
12290
 
            (old_avail == 0) || (avail == 0) ||
12291
 
            (xmlParseCheckTransition(ctxt,
12292
 
                       (const char *)&ctxt->input->base[old_avail],
12293
 
                                     avail - old_avail)))
12294
 
            xmlParseTryOrFinish(ctxt, terminate);
12295
 
    }
12296
 
    if (ctxt->instate == XML_PARSER_EOF)
12297
 
        return(ctxt->errNo);
12298
 
 
12299
 
    if ((ctxt->input != NULL) &&
12300
 
         (((ctxt->input->end - ctxt->input->cur) > XML_MAX_LOOKUP_LIMIT) ||
12301
 
         ((ctxt->input->cur - ctxt->input->base) > XML_MAX_LOOKUP_LIMIT)) &&
12302
 
        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
12303
 
        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "Huge input lookup");
12304
 
        ctxt->instate = XML_PARSER_EOF;
12305
 
    }
12306
 
    if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
12307
 
        return(ctxt->errNo);
12308
 
 
12309
 
    if (remain != 0) {
12310
 
        chunk += size;
12311
 
        size = remain;
12312
 
        remain = 0;
12313
 
        goto xmldecl_done;
12314
 
    }
12315
 
    if ((end_in_lf == 1) && (ctxt->input != NULL) &&
12316
 
        (ctxt->input->buf != NULL)) {
12317
 
        size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer,
12318
 
                                         ctxt->input);
12319
 
        size_t current = ctxt->input->cur - ctxt->input->base;
12320
 
 
12321
 
        xmlParserInputBufferPush(ctxt->input->buf, 1, "\r");
12322
 
 
12323
 
        xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input,
12324
 
                              base, current);
12325
 
    }
12326
 
    if (terminate) {
12327
 
        /*
12328
 
         * Check for termination
12329
 
         */
12330
 
        int cur_avail = 0;
12331
 
 
12332
 
        if (ctxt->input != NULL) {
12333
 
            if (ctxt->input->buf == NULL)
12334
 
                cur_avail = ctxt->input->length -
12335
 
                            (ctxt->input->cur - ctxt->input->base);
12336
 
            else
12337
 
                cur_avail = xmlBufUse(ctxt->input->buf->buffer) -
12338
 
                                      (ctxt->input->cur - ctxt->input->base);
12339
 
        }
12340
 
 
12341
 
        if ((ctxt->instate != XML_PARSER_EOF) &&
12342
 
            (ctxt->instate != XML_PARSER_EPILOG)) {
12343
 
            xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
12344
 
        }
12345
 
        if ((ctxt->instate == XML_PARSER_EPILOG) && (cur_avail > 0)) {
12346
 
            xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
12347
 
        }
12348
 
        if (ctxt->instate != XML_PARSER_EOF) {
12349
 
            if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
12350
 
                ctxt->sax->endDocument(ctxt->userData);
12351
 
        }
12352
 
        ctxt->instate = XML_PARSER_EOF;
12353
 
    }
12354
 
    if (ctxt->wellFormed == 0)
12355
 
        return((xmlParserErrors) ctxt->errNo);
12356
 
    else
12357
 
        return(0);
12358
 
}
12359
 
 
12360
 
/************************************************************************
12361
 
 *                                                                      *
12362
 
 *              I/O front end functions to the parser                   *
12363
 
 *                                                                      *
12364
 
 ************************************************************************/
12365
 
 
12366
 
/**
12367
 
 * xmlCreatePushParserCtxt:
12368
 
 * @sax:  a SAX handler
12369
 
 * @user_data:  The user data returned on SAX callbacks
12370
 
 * @chunk:  a pointer to an array of chars
12371
 
 * @size:  number of chars in the array
12372
 
 * @filename:  an optional file name or URI
12373
 
 *
12374
 
 * Create a parser context for using the XML parser in push mode.
12375
 
 * If @buffer and @size are non-NULL, the data is used to detect
12376
 
 * the encoding.  The remaining characters will be parsed so they
12377
 
 * don't need to be fed in again through xmlParseChunk.
12378
 
 * To allow content encoding detection, @size should be >= 4
12379
 
 * The value of @filename is used for fetching external entities
12380
 
 * and error/warning reports.
12381
 
 *
12382
 
 * Returns the new parser context or NULL
12383
 
 */
12384
 
 
12385
 
xmlParserCtxtPtr
12386
 
xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
12387
 
                        const char *chunk, int size, const char *filename) {
12388
 
    xmlParserCtxtPtr ctxt;
12389
 
    xmlParserInputPtr inputStream;
12390
 
    xmlParserInputBufferPtr buf;
12391
 
    xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
12392
 
 
12393
 
    /*
12394
 
     * plug some encoding conversion routines
12395
 
     */
12396
 
    if ((chunk != NULL) && (size >= 4))
12397
 
        enc = xmlDetectCharEncoding((const xmlChar *) chunk, size);
12398
 
 
12399
 
    buf = xmlAllocParserInputBuffer(enc);
12400
 
    if (buf == NULL) return(NULL);
12401
 
 
12402
 
    ctxt = xmlNewParserCtxt();
12403
 
    if (ctxt == NULL) {
12404
 
        xmlErrMemory(NULL, "creating parser: out of memory\n");
12405
 
        xmlFreeParserInputBuffer(buf);
12406
 
        return(NULL);
12407
 
    }
12408
 
    ctxt->dictNames = 1;
12409
 
    ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 * sizeof(xmlChar *));
12410
 
    if (ctxt->pushTab == NULL) {
12411
 
        xmlErrMemory(ctxt, NULL);
12412
 
        xmlFreeParserInputBuffer(buf);
12413
 
        xmlFreeParserCtxt(ctxt);
12414
 
        return(NULL);
12415
 
    }
12416
 
    if (sax != NULL) {
12417
 
#ifdef LIBXML_SAX1_ENABLED
12418
 
        if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
12419
 
#endif /* LIBXML_SAX1_ENABLED */
12420
 
            xmlFree(ctxt->sax);
12421
 
        ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
12422
 
        if (ctxt->sax == NULL) {
12423
 
            xmlErrMemory(ctxt, NULL);
12424
 
            xmlFreeParserInputBuffer(buf);
12425
 
            xmlFreeParserCtxt(ctxt);
12426
 
            return(NULL);
12427
 
        }
12428
 
        memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
12429
 
        if (sax->initialized == XML_SAX2_MAGIC)
12430
 
            memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
12431
 
        else
12432
 
            memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
12433
 
        if (user_data != NULL)
12434
 
            ctxt->userData = user_data;
12435
 
    }
12436
 
    if (filename == NULL) {
12437
 
        ctxt->directory = NULL;
12438
 
    } else {
12439
 
        ctxt->directory = xmlParserGetDirectory(filename);
12440
 
    }
12441
 
 
12442
 
    inputStream = xmlNewInputStream(ctxt);
12443
 
    if (inputStream == NULL) {
12444
 
        xmlFreeParserCtxt(ctxt);
12445
 
        xmlFreeParserInputBuffer(buf);
12446
 
        return(NULL);
12447
 
    }
12448
 
 
12449
 
    if (filename == NULL)
12450
 
        inputStream->filename = NULL;
12451
 
    else {
12452
 
        inputStream->filename = (char *)
12453
 
            xmlCanonicPath((const xmlChar *) filename);
12454
 
        if (inputStream->filename == NULL) {
12455
 
            xmlFreeParserCtxt(ctxt);
12456
 
            xmlFreeParserInputBuffer(buf);
12457
 
            return(NULL);
12458
 
        }
12459
 
    }
12460
 
    inputStream->buf = buf;
12461
 
    xmlBufResetInput(inputStream->buf->buffer, inputStream);
12462
 
    inputPush(ctxt, inputStream);
12463
 
 
12464
 
    /*
12465
 
     * If the caller didn't provide an initial 'chunk' for determining
12466
 
     * the encoding, we set the context to XML_CHAR_ENCODING_NONE so
12467
 
     * that it can be automatically determined later
12468
 
     */
12469
 
    if ((size == 0) || (chunk == NULL)) {
12470
 
        ctxt->charset = XML_CHAR_ENCODING_NONE;
12471
 
    } else if ((ctxt->input != NULL) && (ctxt->input->buf != NULL)) {
12472
 
        size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer, ctxt->input);
12473
 
        size_t cur = ctxt->input->cur - ctxt->input->base;
12474
 
 
12475
 
        xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
12476
 
 
12477
 
        xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur);
12478
 
#ifdef DEBUG_PUSH
12479
 
        xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
12480
 
#endif
12481
 
    }
12482
 
 
12483
 
    if (enc != XML_CHAR_ENCODING_NONE) {
12484
 
        xmlSwitchEncoding(ctxt, enc);
12485
 
    }
12486
 
 
12487
 
    return(ctxt);
12488
 
}
12489
 
#endif /* LIBXML_PUSH_ENABLED */
12490
 
 
12491
 
/**
12492
 
 * xmlStopParser:
12493
 
 * @ctxt:  an XML parser context
12494
 
 *
12495
 
 * Blocks further parser processing
12496
 
 */
12497
 
void
12498
 
xmlStopParser(xmlParserCtxtPtr ctxt) {
12499
 
    if (ctxt == NULL)
12500
 
        return;
12501
 
    ctxt->instate = XML_PARSER_EOF;
12502
 
    ctxt->errNo = XML_ERR_USER_STOP;
12503
 
    ctxt->disableSAX = 1;
12504
 
    if (ctxt->input != NULL) {
12505
 
        ctxt->input->cur = BAD_CAST"";
12506
 
        ctxt->input->base = ctxt->input->cur;
12507
 
    }
12508
 
}
12509
 
 
12510
 
/**
12511
 
 * xmlCreateIOParserCtxt:
12512
 
 * @sax:  a SAX handler
12513
 
 * @user_data:  The user data returned on SAX callbacks
12514
 
 * @ioread:  an I/O read function
12515
 
 * @ioclose:  an I/O close function
12516
 
 * @ioctx:  an I/O handler
12517
 
 * @enc:  the charset encoding if known
12518
 
 *
12519
 
 * Create a parser context for using the XML parser with an existing
12520
 
 * I/O stream
12521
 
 *
12522
 
 * Returns the new parser context or NULL
12523
 
 */
12524
 
xmlParserCtxtPtr
12525
 
xmlCreateIOParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
12526
 
        xmlInputReadCallback   ioread, xmlInputCloseCallback  ioclose,
12527
 
        void *ioctx, xmlCharEncoding enc) {
12528
 
    xmlParserCtxtPtr ctxt;
12529
 
    xmlParserInputPtr inputStream;
12530
 
    xmlParserInputBufferPtr buf;
12531
 
 
12532
 
    if (ioread == NULL) return(NULL);
12533
 
 
12534
 
    buf = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx, enc);
12535
 
    if (buf == NULL) {
12536
 
        if (ioclose != NULL)
12537
 
            ioclose(ioctx);
12538
 
        return (NULL);
12539
 
    }
12540
 
 
12541
 
    ctxt = xmlNewParserCtxt();
12542
 
    if (ctxt == NULL) {
12543
 
        xmlFreeParserInputBuffer(buf);
12544
 
        return(NULL);
12545
 
    }
12546
 
    if (sax != NULL) {
12547
 
#ifdef LIBXML_SAX1_ENABLED
12548
 
        if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
12549
 
#endif /* LIBXML_SAX1_ENABLED */
12550
 
            xmlFree(ctxt->sax);
12551
 
        ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
12552
 
        if (ctxt->sax == NULL) {
12553
 
            xmlErrMemory(ctxt, NULL);
12554
 
            xmlFreeParserCtxt(ctxt);
12555
 
            return(NULL);
12556
 
        }
12557
 
        memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
12558
 
        if (sax->initialized == XML_SAX2_MAGIC)
12559
 
            memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
12560
 
        else
12561
 
            memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
12562
 
        if (user_data != NULL)
12563
 
            ctxt->userData = user_data;
12564
 
    }
12565
 
 
12566
 
    inputStream = xmlNewIOInputStream(ctxt, buf, enc);
12567
 
    if (inputStream == NULL) {
12568
 
        xmlFreeParserCtxt(ctxt);
12569
 
        return(NULL);
12570
 
    }
12571
 
    inputPush(ctxt, inputStream);
12572
 
 
12573
 
    return(ctxt);
12574
 
}
12575
 
 
12576
 
#ifdef LIBXML_VALID_ENABLED
12577
 
/************************************************************************
12578
 
 *                                                                      *
12579
 
 *              Front ends when parsing a DTD                           *
12580
 
 *                                                                      *
12581
 
 ************************************************************************/
12582
 
 
12583
 
/**
12584
 
 * xmlIOParseDTD:
12585
 
 * @sax:  the SAX handler block or NULL
12586
 
 * @input:  an Input Buffer
12587
 
 * @enc:  the charset encoding if known
12588
 
 *
12589
 
 * Load and parse a DTD
12590
 
 *
12591
 
 * Returns the resulting xmlDtdPtr or NULL in case of error.
12592
 
 * @input will be freed by the function in any case.
12593
 
 */
12594
 
 
12595
 
xmlDtdPtr
12596
 
xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input,
12597
 
              xmlCharEncoding enc) {
12598
 
    xmlDtdPtr ret = NULL;
12599
 
    xmlParserCtxtPtr ctxt;
12600
 
    xmlParserInputPtr pinput = NULL;
12601
 
    xmlChar start[4];
12602
 
 
12603
 
    if (input == NULL)
12604
 
        return(NULL);
12605
 
 
12606
 
    ctxt = xmlNewParserCtxt();
12607
 
    if (ctxt == NULL) {
12608
 
        xmlFreeParserInputBuffer(input);
12609
 
        return(NULL);
12610
 
    }
12611
 
 
12612
 
    /*
12613
 
     * Set-up the SAX context
12614
 
     */
12615
 
    if (sax != NULL) {
12616
 
        if (ctxt->sax != NULL)
12617
 
            xmlFree(ctxt->sax);
12618
 
        ctxt->sax = sax;
12619
 
        ctxt->userData = ctxt;
12620
 
    }
12621
 
    xmlDetectSAX2(ctxt);
12622
 
 
12623
 
    /*
12624
 
     * generate a parser input from the I/O handler
12625
 
     */
12626
 
 
12627
 
    pinput = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
12628
 
    if (pinput == NULL) {
12629
 
        if (sax != NULL) ctxt->sax = NULL;
12630
 
        xmlFreeParserInputBuffer(input);
12631
 
        xmlFreeParserCtxt(ctxt);
12632
 
        return(NULL);
12633
 
    }
12634
 
 
12635
 
    /*
12636
 
     * plug some encoding conversion routines here.
12637
 
     */
12638
 
    if (xmlPushInput(ctxt, pinput) < 0) {
12639
 
        if (sax != NULL) ctxt->sax = NULL;
12640
 
        xmlFreeParserCtxt(ctxt);
12641
 
        return(NULL);
12642
 
    }
12643
 
    if (enc != XML_CHAR_ENCODING_NONE) {
12644
 
        xmlSwitchEncoding(ctxt, enc);
12645
 
    }
12646
 
 
12647
 
    pinput->filename = NULL;
12648
 
    pinput->line = 1;
12649
 
    pinput->col = 1;
12650
 
    pinput->base = ctxt->input->cur;
12651
 
    pinput->cur = ctxt->input->cur;
12652
 
    pinput->free = NULL;
12653
 
 
12654
 
    /*
12655
 
     * let's parse that entity knowing it's an external subset.
12656
 
     */
12657
 
    ctxt->inSubset = 2;
12658
 
    ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
12659
 
    if (ctxt->myDoc == NULL) {
12660
 
        xmlErrMemory(ctxt, "New Doc failed");
12661
 
        return(NULL);
12662
 
    }
12663
 
    ctxt->myDoc->properties = XML_DOC_INTERNAL;
12664
 
    ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
12665
 
                                       BAD_CAST "none", BAD_CAST "none");
12666
 
 
12667
 
    if ((enc == XML_CHAR_ENCODING_NONE) &&
12668
 
        ((ctxt->input->end - ctxt->input->cur) >= 4)) {
12669
 
        /*
12670
 
         * Get the 4 first bytes and decode the charset
12671
 
         * if enc != XML_CHAR_ENCODING_NONE
12672
 
         * plug some encoding conversion routines.
12673
 
         */
12674
 
        start[0] = RAW;
12675
 
        start[1] = NXT(1);
12676
 
        start[2] = NXT(2);
12677
 
        start[3] = NXT(3);
12678
 
        enc = xmlDetectCharEncoding(start, 4);
12679
 
        if (enc != XML_CHAR_ENCODING_NONE) {
12680
 
            xmlSwitchEncoding(ctxt, enc);
12681
 
        }
12682
 
    }
12683
 
 
12684
 
    xmlParseExternalSubset(ctxt, BAD_CAST "none", BAD_CAST "none");
12685
 
 
12686
 
    if (ctxt->myDoc != NULL) {
12687
 
        if (ctxt->wellFormed) {
12688
 
            ret = ctxt->myDoc->extSubset;
12689
 
            ctxt->myDoc->extSubset = NULL;
12690
 
            if (ret != NULL) {
12691
 
                xmlNodePtr tmp;
12692
 
 
12693
 
                ret->doc = NULL;
12694
 
                tmp = ret->children;
12695
 
                while (tmp != NULL) {
12696
 
                    tmp->doc = NULL;
12697
 
                    tmp = tmp->next;
12698
 
                }
12699
 
            }
12700
 
        } else {
12701
 
            ret = NULL;
12702
 
        }
12703
 
        xmlFreeDoc(ctxt->myDoc);
12704
 
        ctxt->myDoc = NULL;
12705
 
    }
12706
 
    if (sax != NULL) ctxt->sax = NULL;
12707
 
    xmlFreeParserCtxt(ctxt);
12708
 
 
12709
 
    return(ret);
12710
 
}
12711
 
 
12712
 
/**
12713
 
 * xmlSAXParseDTD:
12714
 
 * @sax:  the SAX handler block
12715
 
 * @ExternalID:  a NAME* containing the External ID of the DTD
12716
 
 * @SystemID:  a NAME* containing the URL to the DTD
12717
 
 *
12718
 
 * Load and parse an external subset.
12719
 
 *
12720
 
 * Returns the resulting xmlDtdPtr or NULL in case of error.
12721
 
 */
12722
 
 
12723
 
xmlDtdPtr
12724
 
xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID,
12725
 
                          const xmlChar *SystemID) {
12726
 
    xmlDtdPtr ret = NULL;
12727
 
    xmlParserCtxtPtr ctxt;
12728
 
    xmlParserInputPtr input = NULL;
12729
 
    xmlCharEncoding enc;
12730
 
    xmlChar* systemIdCanonic;
12731
 
 
12732
 
    if ((ExternalID == NULL) && (SystemID == NULL)) return(NULL);
12733
 
 
12734
 
    ctxt = xmlNewParserCtxt();
12735
 
    if (ctxt == NULL) {
12736
 
        return(NULL);
12737
 
    }
12738
 
 
12739
 
    /*
12740
 
     * Set-up the SAX context
12741
 
     */
12742
 
    if (sax != NULL) {
12743
 
        if (ctxt->sax != NULL)
12744
 
            xmlFree(ctxt->sax);
12745
 
        ctxt->sax = sax;
12746
 
        ctxt->userData = ctxt;
12747
 
    }
12748
 
 
12749
 
    /*
12750
 
     * Canonicalise the system ID
12751
 
     */
12752
 
    systemIdCanonic = xmlCanonicPath(SystemID);
12753
 
    if ((SystemID != NULL) && (systemIdCanonic == NULL)) {
12754
 
        xmlFreeParserCtxt(ctxt);
12755
 
        return(NULL);
12756
 
    }
12757
 
 
12758
 
    /*
12759
 
     * Ask the Entity resolver to load the damn thing
12760
 
     */
12761
 
 
12762
 
    if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
12763
 
        input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID,
12764
 
                                         systemIdCanonic);
12765
 
    if (input == NULL) {
12766
 
        if (sax != NULL) ctxt->sax = NULL;
12767
 
        xmlFreeParserCtxt(ctxt);
12768
 
        if (systemIdCanonic != NULL)
12769
 
            xmlFree(systemIdCanonic);
12770
 
        return(NULL);
12771
 
    }
12772
 
 
12773
 
    /*
12774
 
     * plug some encoding conversion routines here.
12775
 
     */
12776
 
    if (xmlPushInput(ctxt, input) < 0) {
12777
 
        if (sax != NULL) ctxt->sax = NULL;
12778
 
        xmlFreeParserCtxt(ctxt);
12779
 
        if (systemIdCanonic != NULL)
12780
 
            xmlFree(systemIdCanonic);
12781
 
        return(NULL);
12782
 
    }
12783
 
    if ((ctxt->input->end - ctxt->input->cur) >= 4) {
12784
 
        enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
12785
 
        xmlSwitchEncoding(ctxt, enc);
12786
 
    }
12787
 
 
12788
 
    if (input->filename == NULL)
12789
 
        input->filename = (char *) systemIdCanonic;
12790
 
    else
12791
 
        xmlFree(systemIdCanonic);
12792
 
    input->line = 1;
12793
 
    input->col = 1;
12794
 
    input->base = ctxt->input->cur;
12795
 
    input->cur = ctxt->input->cur;
12796
 
    input->free = NULL;
12797
 
 
12798
 
    /*
12799
 
     * let's parse that entity knowing it's an external subset.
12800
 
     */
12801
 
    ctxt->inSubset = 2;
12802
 
    ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
12803
 
    if (ctxt->myDoc == NULL) {
12804
 
        xmlErrMemory(ctxt, "New Doc failed");
12805
 
        if (sax != NULL) ctxt->sax = NULL;
12806
 
        xmlFreeParserCtxt(ctxt);
12807
 
        return(NULL);
12808
 
    }
12809
 
    ctxt->myDoc->properties = XML_DOC_INTERNAL;
12810
 
    ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
12811
 
                                       ExternalID, SystemID);
12812
 
    xmlParseExternalSubset(ctxt, ExternalID, SystemID);
12813
 
 
12814
 
    if (ctxt->myDoc != NULL) {
12815
 
        if (ctxt->wellFormed) {
12816
 
            ret = ctxt->myDoc->extSubset;
12817
 
            ctxt->myDoc->extSubset = NULL;
12818
 
            if (ret != NULL) {
12819
 
                xmlNodePtr tmp;
12820
 
 
12821
 
                ret->doc = NULL;
12822
 
                tmp = ret->children;
12823
 
                while (tmp != NULL) {
12824
 
                    tmp->doc = NULL;
12825
 
                    tmp = tmp->next;
12826
 
                }
12827
 
            }
12828
 
        } else {
12829
 
            ret = NULL;
12830
 
        }
12831
 
        xmlFreeDoc(ctxt->myDoc);
12832
 
        ctxt->myDoc = NULL;
12833
 
    }
12834
 
    if (sax != NULL) ctxt->sax = NULL;
12835
 
    xmlFreeParserCtxt(ctxt);
12836
 
 
12837
 
    return(ret);
12838
 
}
12839
 
 
12840
 
 
12841
 
/**
12842
 
 * xmlParseDTD:
12843
 
 * @ExternalID:  a NAME* containing the External ID of the DTD
12844
 
 * @SystemID:  a NAME* containing the URL to the DTD
12845
 
 *
12846
 
 * Load and parse an external subset.
12847
 
 *
12848
 
 * Returns the resulting xmlDtdPtr or NULL in case of error.
12849
 
 */
12850
 
 
12851
 
xmlDtdPtr
12852
 
xmlParseDTD(const xmlChar *ExternalID, const xmlChar *SystemID) {
12853
 
    return(xmlSAXParseDTD(NULL, ExternalID, SystemID));
12854
 
}
12855
 
#endif /* LIBXML_VALID_ENABLED */
12856
 
 
12857
 
/************************************************************************
12858
 
 *                                                                      *
12859
 
 *              Front ends when parsing an Entity                       *
12860
 
 *                                                                      *
12861
 
 ************************************************************************/
12862
 
 
12863
 
/**
12864
 
 * xmlParseCtxtExternalEntity:
12865
 
 * @ctx:  the existing parsing context
12866
 
 * @URL:  the URL for the entity to load
12867
 
 * @ID:  the System ID for the entity to load
12868
 
 * @lst:  the return value for the set of parsed nodes
12869
 
 *
12870
 
 * Parse an external general entity within an existing parsing context
12871
 
 * An external general parsed entity is well-formed if it matches the
12872
 
 * production labeled extParsedEnt.
12873
 
 *
12874
 
 * [78] extParsedEnt ::= TextDecl? content
12875
 
 *
12876
 
 * Returns 0 if the entity is well formed, -1 in case of args problem and
12877
 
 *    the parser error code otherwise
12878
 
 */
12879
 
 
12880
 
int
12881
 
xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx, const xmlChar *URL,
12882
 
                       const xmlChar *ID, xmlNodePtr *lst) {
12883
 
    xmlParserCtxtPtr ctxt;
12884
 
    xmlDocPtr newDoc;
12885
 
    xmlNodePtr newRoot;
12886
 
    xmlSAXHandlerPtr oldsax = NULL;
12887
 
    int ret = 0;
12888
 
    xmlChar start[4];
12889
 
    xmlCharEncoding enc;
12890
 
 
12891
 
    if (ctx == NULL) return(-1);
12892
 
 
12893
 
    if (((ctx->depth > 40) && ((ctx->options & XML_PARSE_HUGE) == 0)) ||
12894
 
        (ctx->depth > 1024)) {
12895
 
        return(XML_ERR_ENTITY_LOOP);
12896
 
    }
12897
 
 
12898
 
    if (lst != NULL)
12899
 
        *lst = NULL;
12900
 
    if ((URL == NULL) && (ID == NULL))
12901
 
        return(-1);
12902
 
    if (ctx->myDoc == NULL) /* @@ relax but check for dereferences */
12903
 
        return(-1);
12904
 
 
12905
 
    ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, ctx);
12906
 
    if (ctxt == NULL) {
12907
 
        return(-1);
12908
 
    }
12909
 
 
12910
 
    oldsax = ctxt->sax;
12911
 
    ctxt->sax = ctx->sax;
12912
 
    xmlDetectSAX2(ctxt);
12913
 
    newDoc = xmlNewDoc(BAD_CAST "1.0");
12914
 
    if (newDoc == NULL) {
12915
 
        xmlFreeParserCtxt(ctxt);
12916
 
        return(-1);
12917
 
    }
12918
 
    newDoc->properties = XML_DOC_INTERNAL;
12919
 
    if (ctx->myDoc->dict) {
12920
 
        newDoc->dict = ctx->myDoc->dict;
12921
 
        xmlDictReference(newDoc->dict);
12922
 
    }
12923
 
    if (ctx->myDoc != NULL) {
12924
 
        newDoc->intSubset = ctx->myDoc->intSubset;
12925
 
        newDoc->extSubset = ctx->myDoc->extSubset;
12926
 
    }
12927
 
    if (ctx->myDoc->URL != NULL) {
12928
 
        newDoc->URL = xmlStrdup(ctx->myDoc->URL);
12929
 
    }
12930
 
    newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
12931
 
    if (newRoot == NULL) {
12932
 
        ctxt->sax = oldsax;
12933
 
        xmlFreeParserCtxt(ctxt);
12934
 
        newDoc->intSubset = NULL;
12935
 
        newDoc->extSubset = NULL;
12936
 
        xmlFreeDoc(newDoc);
12937
 
        return(-1);
12938
 
    }
12939
 
    xmlAddChild((xmlNodePtr) newDoc, newRoot);
12940
 
    nodePush(ctxt, newDoc->children);
12941
 
    if (ctx->myDoc == NULL) {
12942
 
        ctxt->myDoc = newDoc;
12943
 
    } else {
12944
 
        ctxt->myDoc = ctx->myDoc;
12945
 
        newDoc->children->doc = ctx->myDoc;
12946
 
    }
12947
 
 
12948
 
    /*
12949
 
     * Get the 4 first bytes and decode the charset
12950
 
     * if enc != XML_CHAR_ENCODING_NONE
12951
 
     * plug some encoding conversion routines.
12952
 
     */
12953
 
    GROW
12954
 
    if ((ctxt->input->end - ctxt->input->cur) >= 4) {
12955
 
        start[0] = RAW;
12956
 
        start[1] = NXT(1);
12957
 
        start[2] = NXT(2);
12958
 
        start[3] = NXT(3);
12959
 
        enc = xmlDetectCharEncoding(start, 4);
12960
 
        if (enc != XML_CHAR_ENCODING_NONE) {
12961
 
            xmlSwitchEncoding(ctxt, enc);
12962
 
        }
12963
 
    }
12964
 
 
12965
 
    /*
12966
 
     * Parse a possible text declaration first
12967
 
     */
12968
 
    if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
12969
 
        xmlParseTextDecl(ctxt);
12970
 
        /*
12971
 
         * An XML-1.0 document can't reference an entity not XML-1.0
12972
 
         */
12973
 
        if ((xmlStrEqual(ctx->version, BAD_CAST "1.0")) &&
12974
 
            (!xmlStrEqual(ctxt->input->version, BAD_CAST "1.0"))) {
12975
 
            xmlFatalErrMsg(ctxt, XML_ERR_VERSION_MISMATCH,
12976
 
                           "Version mismatch between document and entity\n");
12977
 
        }
12978
 
    }
12979
 
 
12980
 
    /*
12981
 
     * If the user provided its own SAX callbacks then reuse the
12982
 
     * useData callback field, otherwise the expected setup in a
12983
 
     * DOM builder is to have userData == ctxt
12984
 
     */
12985
 
    if (ctx->userData == ctx)
12986
 
        ctxt->userData = ctxt;
12987
 
    else
12988
 
        ctxt->userData = ctx->userData;
12989
 
 
12990
 
    /*
12991
 
     * Doing validity checking on chunk doesn't make sense
12992
 
     */
12993
 
    ctxt->instate = XML_PARSER_CONTENT;
12994
 
    ctxt->validate = ctx->validate;
12995
 
    ctxt->valid = ctx->valid;
12996
 
    ctxt->loadsubset = ctx->loadsubset;
12997
 
    ctxt->depth = ctx->depth + 1;
12998
 
    ctxt->replaceEntities = ctx->replaceEntities;
12999
 
    if (ctxt->validate) {
13000
 
        ctxt->vctxt.error = ctx->vctxt.error;
13001
 
        ctxt->vctxt.warning = ctx->vctxt.warning;
13002
 
    } else {
13003
 
        ctxt->vctxt.error = NULL;
13004
 
        ctxt->vctxt.warning = NULL;
13005
 
    }
13006
 
    ctxt->vctxt.nodeTab = NULL;
13007
 
    ctxt->vctxt.nodeNr = 0;
13008
 
    ctxt->vctxt.nodeMax = 0;
13009
 
    ctxt->vctxt.node = NULL;
13010
 
    if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
13011
 
    ctxt->dict = ctx->dict;
13012
 
    ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
13013
 
    ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
13014
 
    ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
13015
 
    ctxt->dictNames = ctx->dictNames;
13016
 
    ctxt->attsDefault = ctx->attsDefault;
13017
 
    ctxt->attsSpecial = ctx->attsSpecial;
13018
 
    ctxt->linenumbers = ctx->linenumbers;
13019
 
 
13020
 
    xmlParseContent(ctxt);
13021
 
 
13022
 
    ctx->validate = ctxt->validate;
13023
 
    ctx->valid = ctxt->valid;
13024
 
    if ((RAW == '<') && (NXT(1) == '/')) {
13025
 
        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13026
 
    } else if (RAW != 0) {
13027
 
        xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
13028
 
    }
13029
 
    if (ctxt->node != newDoc->children) {
13030
 
        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13031
 
    }
13032
 
 
13033
 
    if (!ctxt->wellFormed) {
13034
 
        if (ctxt->errNo == 0)
13035
 
            ret = 1;
13036
 
        else
13037
 
            ret = ctxt->errNo;
13038
 
    } else {
13039
 
        if (lst != NULL) {
13040
 
            xmlNodePtr cur;
13041
 
 
13042
 
            /*
13043
 
             * Return the newly created nodeset after unlinking it from
13044
 
             * they pseudo parent.
13045
 
             */
13046
 
            cur = newDoc->children->children;
13047
 
            *lst = cur;
13048
 
            while (cur != NULL) {
13049
 
                cur->parent = NULL;
13050
 
                cur = cur->next;
13051
 
            }
13052
 
            newDoc->children->children = NULL;
13053
 
        }
13054
 
        ret = 0;
13055
 
    }
13056
 
    ctxt->sax = oldsax;
13057
 
    ctxt->dict = NULL;
13058
 
    ctxt->attsDefault = NULL;
13059
 
    ctxt->attsSpecial = NULL;
13060
 
    xmlFreeParserCtxt(ctxt);
13061
 
    newDoc->intSubset = NULL;
13062
 
    newDoc->extSubset = NULL;
13063
 
    xmlFreeDoc(newDoc);
13064
 
 
13065
 
    return(ret);
13066
 
}
13067
 
 
13068
 
/**
13069
 
 * xmlParseExternalEntityPrivate:
13070
 
 * @doc:  the document the chunk pertains to
13071
 
 * @oldctxt:  the previous parser context if available
13072
 
 * @sax:  the SAX handler bloc (possibly NULL)
13073
 
 * @user_data:  The user data returned on SAX callbacks (possibly NULL)
13074
 
 * @depth:  Used for loop detection, use 0
13075
 
 * @URL:  the URL for the entity to load
13076
 
 * @ID:  the System ID for the entity to load
13077
 
 * @list:  the return value for the set of parsed nodes
13078
 
 *
13079
 
 * Private version of xmlParseExternalEntity()
13080
 
 *
13081
 
 * Returns 0 if the entity is well formed, -1 in case of args problem and
13082
 
 *    the parser error code otherwise
13083
 
 */
13084
 
 
13085
 
static xmlParserErrors
13086
 
xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
13087
 
                      xmlSAXHandlerPtr sax,
13088
 
                      void *user_data, int depth, const xmlChar *URL,
13089
 
                      const xmlChar *ID, xmlNodePtr *list) {
13090
 
    xmlParserCtxtPtr ctxt;
13091
 
    xmlDocPtr newDoc;
13092
 
    xmlNodePtr newRoot;
13093
 
    xmlSAXHandlerPtr oldsax = NULL;
13094
 
    xmlParserErrors ret = XML_ERR_OK;
13095
 
    xmlChar start[4];
13096
 
    xmlCharEncoding enc;
13097
 
 
13098
 
    if (((depth > 40) &&
13099
 
        ((oldctxt == NULL) || (oldctxt->options & XML_PARSE_HUGE) == 0)) ||
13100
 
        (depth > 1024)) {
13101
 
        return(XML_ERR_ENTITY_LOOP);
13102
 
    }
13103
 
 
13104
 
    if (list != NULL)
13105
 
        *list = NULL;
13106
 
    if ((URL == NULL) && (ID == NULL))
13107
 
        return(XML_ERR_INTERNAL_ERROR);
13108
 
    if (doc == NULL)
13109
 
        return(XML_ERR_INTERNAL_ERROR);
13110
 
 
13111
 
 
13112
 
    ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, oldctxt);
13113
 
    if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
13114
 
    ctxt->userData = ctxt;
13115
 
    if (oldctxt != NULL) {
13116
 
        ctxt->_private = oldctxt->_private;
13117
 
        ctxt->loadsubset = oldctxt->loadsubset;
13118
 
        ctxt->validate = oldctxt->validate;
13119
 
        ctxt->external = oldctxt->external;
13120
 
        ctxt->record_info = oldctxt->record_info;
13121
 
        ctxt->node_seq.maximum = oldctxt->node_seq.maximum;
13122
 
        ctxt->node_seq.length = oldctxt->node_seq.length;
13123
 
        ctxt->node_seq.buffer = oldctxt->node_seq.buffer;
13124
 
    } else {
13125
 
        /*
13126
 
         * Doing validity checking on chunk without context
13127
 
         * doesn't make sense
13128
 
         */
13129
 
        ctxt->_private = NULL;
13130
 
        ctxt->validate = 0;
13131
 
        ctxt->external = 2;
13132
 
        ctxt->loadsubset = 0;
13133
 
    }
13134
 
    if (sax != NULL) {
13135
 
        oldsax = ctxt->sax;
13136
 
        ctxt->sax = sax;
13137
 
        if (user_data != NULL)
13138
 
            ctxt->userData = user_data;
13139
 
    }
13140
 
    xmlDetectSAX2(ctxt);
13141
 
    newDoc = xmlNewDoc(BAD_CAST "1.0");
13142
 
    if (newDoc == NULL) {
13143
 
        ctxt->node_seq.maximum = 0;
13144
 
        ctxt->node_seq.length = 0;
13145
 
        ctxt->node_seq.buffer = NULL;
13146
 
        xmlFreeParserCtxt(ctxt);
13147
 
        return(XML_ERR_INTERNAL_ERROR);
13148
 
    }
13149
 
    newDoc->properties = XML_DOC_INTERNAL;
13150
 
    newDoc->intSubset = doc->intSubset;
13151
 
    newDoc->extSubset = doc->extSubset;
13152
 
    newDoc->dict = doc->dict;
13153
 
    xmlDictReference(newDoc->dict);
13154
 
 
13155
 
    if (doc->URL != NULL) {
13156
 
        newDoc->URL = xmlStrdup(doc->URL);
13157
 
    }
13158
 
    newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
13159
 
    if (newRoot == NULL) {
13160
 
        if (sax != NULL)
13161
 
            ctxt->sax = oldsax;
13162
 
        ctxt->node_seq.maximum = 0;
13163
 
        ctxt->node_seq.length = 0;
13164
 
        ctxt->node_seq.buffer = NULL;
13165
 
        xmlFreeParserCtxt(ctxt);
13166
 
        newDoc->intSubset = NULL;
13167
 
        newDoc->extSubset = NULL;
13168
 
        xmlFreeDoc(newDoc);
13169
 
        return(XML_ERR_INTERNAL_ERROR);
13170
 
    }
13171
 
    xmlAddChild((xmlNodePtr) newDoc, newRoot);
13172
 
    nodePush(ctxt, newDoc->children);
13173
 
    ctxt->myDoc = doc;
13174
 
    newRoot->doc = doc;
13175
 
 
13176
 
    /*
13177
 
     * Get the 4 first bytes and decode the charset
13178
 
     * if enc != XML_CHAR_ENCODING_NONE
13179
 
     * plug some encoding conversion routines.
13180
 
     */
13181
 
    GROW;
13182
 
    if ((ctxt->input->end - ctxt->input->cur) >= 4) {
13183
 
        start[0] = RAW;
13184
 
        start[1] = NXT(1);
13185
 
        start[2] = NXT(2);
13186
 
        start[3] = NXT(3);
13187
 
        enc = xmlDetectCharEncoding(start, 4);
13188
 
        if (enc != XML_CHAR_ENCODING_NONE) {
13189
 
            xmlSwitchEncoding(ctxt, enc);
13190
 
        }
13191
 
    }
13192
 
 
13193
 
    /*
13194
 
     * Parse a possible text declaration first
13195
 
     */
13196
 
    if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
13197
 
        xmlParseTextDecl(ctxt);
13198
 
    }
13199
 
 
13200
 
    ctxt->instate = XML_PARSER_CONTENT;
13201
 
    ctxt->depth = depth;
13202
 
 
13203
 
    xmlParseContent(ctxt);
13204
 
 
13205
 
    if ((RAW == '<') && (NXT(1) == '/')) {
13206
 
        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13207
 
    } else if (RAW != 0) {
13208
 
        xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
13209
 
    }
13210
 
    if (ctxt->node != newDoc->children) {
13211
 
        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13212
 
    }
13213
 
 
13214
 
    if (!ctxt->wellFormed) {
13215
 
        if (ctxt->errNo == 0)
13216
 
            ret = XML_ERR_INTERNAL_ERROR;
13217
 
        else
13218
 
            ret = (xmlParserErrors)ctxt->errNo;
13219
 
    } else {
13220
 
        if (list != NULL) {
13221
 
            xmlNodePtr cur;
13222
 
 
13223
 
            /*
13224
 
             * Return the newly created nodeset after unlinking it from
13225
 
             * they pseudo parent.
13226
 
             */
13227
 
            cur = newDoc->children->children;
13228
 
            *list = cur;
13229
 
            while (cur != NULL) {
13230
 
                cur->parent = NULL;
13231
 
                cur = cur->next;
13232
 
            }
13233
 
            newDoc->children->children = NULL;
13234
 
        }
13235
 
        ret = XML_ERR_OK;
13236
 
    }
13237
 
 
13238
 
    /*
13239
 
     * Record in the parent context the number of entities replacement
13240
 
     * done when parsing that reference.
13241
 
     */
13242
 
    if (oldctxt != NULL)
13243
 
        oldctxt->nbentities += ctxt->nbentities;
13244
 
 
13245
 
    /*
13246
 
     * Also record the size of the entity parsed
13247
 
     */
13248
 
    if (ctxt->input != NULL) {
13249
 
        oldctxt->sizeentities += ctxt->input->consumed;
13250
 
        oldctxt->sizeentities += (ctxt->input->cur - ctxt->input->base);
13251
 
    }
13252
 
    /*
13253
 
     * And record the last error if any
13254
 
     */
13255
 
    if (ctxt->lastError.code != XML_ERR_OK)
13256
 
        xmlCopyError(&ctxt->lastError, &oldctxt->lastError);
13257
 
 
13258
 
    if (sax != NULL)
13259
 
        ctxt->sax = oldsax;
13260
 
    oldctxt->node_seq.maximum = ctxt->node_seq.maximum;
13261
 
    oldctxt->node_seq.length = ctxt->node_seq.length;
13262
 
    oldctxt->node_seq.buffer = ctxt->node_seq.buffer;
13263
 
    ctxt->node_seq.maximum = 0;
13264
 
    ctxt->node_seq.length = 0;
13265
 
    ctxt->node_seq.buffer = NULL;
13266
 
    xmlFreeParserCtxt(ctxt);
13267
 
    newDoc->intSubset = NULL;
13268
 
    newDoc->extSubset = NULL;
13269
 
    xmlFreeDoc(newDoc);
13270
 
 
13271
 
    return(ret);
13272
 
}
13273
 
 
13274
 
#ifdef LIBXML_SAX1_ENABLED
13275
 
/**
13276
 
 * xmlParseExternalEntity:
13277
 
 * @doc:  the document the chunk pertains to
13278
 
 * @sax:  the SAX handler bloc (possibly NULL)
13279
 
 * @user_data:  The user data returned on SAX callbacks (possibly NULL)
13280
 
 * @depth:  Used for loop detection, use 0
13281
 
 * @URL:  the URL for the entity to load
13282
 
 * @ID:  the System ID for the entity to load
13283
 
 * @lst:  the return value for the set of parsed nodes
13284
 
 *
13285
 
 * Parse an external general entity
13286
 
 * An external general parsed entity is well-formed if it matches the
13287
 
 * production labeled extParsedEnt.
13288
 
 *
13289
 
 * [78] extParsedEnt ::= TextDecl? content
13290
 
 *
13291
 
 * Returns 0 if the entity is well formed, -1 in case of args problem and
13292
 
 *    the parser error code otherwise
13293
 
 */
13294
 
 
13295
 
int
13296
 
xmlParseExternalEntity(xmlDocPtr doc, xmlSAXHandlerPtr sax, void *user_data,
13297
 
          int depth, const xmlChar *URL, const xmlChar *ID, xmlNodePtr *lst) {
13298
 
    return(xmlParseExternalEntityPrivate(doc, NULL, sax, user_data, depth, URL,
13299
 
                                       ID, lst));
13300
 
}
13301
 
 
13302
 
/**
13303
 
 * xmlParseBalancedChunkMemory:
13304
 
 * @doc:  the document the chunk pertains to
13305
 
 * @sax:  the SAX handler bloc (possibly NULL)
13306
 
 * @user_data:  The user data returned on SAX callbacks (possibly NULL)
13307
 
 * @depth:  Used for loop detection, use 0
13308
 
 * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
13309
 
 * @lst:  the return value for the set of parsed nodes
13310
 
 *
13311
 
 * Parse a well-balanced chunk of an XML document
13312
 
 * called by the parser
13313
 
 * The allowed sequence for the Well Balanced Chunk is the one defined by
13314
 
 * the content production in the XML grammar:
13315
 
 *
13316
 
 * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
13317
 
 *
13318
 
 * Returns 0 if the chunk is well balanced, -1 in case of args problem and
13319
 
 *    the parser error code otherwise
13320
 
 */
13321
 
 
13322
 
int
13323
 
xmlParseBalancedChunkMemory(xmlDocPtr doc, xmlSAXHandlerPtr sax,
13324
 
     void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst) {
13325
 
    return xmlParseBalancedChunkMemoryRecover( doc, sax, user_data,
13326
 
                                                depth, string, lst, 0 );
13327
 
}
13328
 
#endif /* LIBXML_SAX1_ENABLED */
13329
 
 
13330
 
/**
13331
 
 * xmlParseBalancedChunkMemoryInternal:
13332
 
 * @oldctxt:  the existing parsing context
13333
 
 * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
13334
 
 * @user_data:  the user data field for the parser context
13335
 
 * @lst:  the return value for the set of parsed nodes
13336
 
 *
13337
 
 *
13338
 
 * Parse a well-balanced chunk of an XML document
13339
 
 * called by the parser
13340
 
 * The allowed sequence for the Well Balanced Chunk is the one defined by
13341
 
 * the content production in the XML grammar:
13342
 
 *
13343
 
 * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
13344
 
 *
13345
 
 * Returns XML_ERR_OK if the chunk is well balanced, and the parser
13346
 
 * error code otherwise
13347
 
 *
13348
 
 * In case recover is set to 1, the nodelist will not be empty even if
13349
 
 * the parsed chunk is not well balanced.
13350
 
 */
13351
 
static xmlParserErrors
13352
 
xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
13353
 
        const xmlChar *string, void *user_data, xmlNodePtr *lst) {
13354
 
    xmlParserCtxtPtr ctxt;
13355
 
    xmlDocPtr newDoc = NULL;
13356
 
    xmlNodePtr newRoot;
13357
 
    xmlSAXHandlerPtr oldsax = NULL;
13358
 
    xmlNodePtr content = NULL;
13359
 
    xmlNodePtr last = NULL;
13360
 
    int size;
13361
 
    xmlParserErrors ret = XML_ERR_OK;
13362
 
#ifdef SAX2
13363
 
    int i;
13364
 
#endif
13365
 
 
13366
 
    if (((oldctxt->depth > 40) && ((oldctxt->options & XML_PARSE_HUGE) == 0)) ||
13367
 
        (oldctxt->depth >  1024)) {
13368
 
        return(XML_ERR_ENTITY_LOOP);
13369
 
    }
13370
 
 
13371
 
 
13372
 
    if (lst != NULL)
13373
 
        *lst = NULL;
13374
 
    if (string == NULL)
13375
 
        return(XML_ERR_INTERNAL_ERROR);
13376
 
 
13377
 
    size = xmlStrlen(string);
13378
 
 
13379
 
    ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
13380
 
    if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
13381
 
    if (user_data != NULL)
13382
 
        ctxt->userData = user_data;
13383
 
    else
13384
 
        ctxt->userData = ctxt;
13385
 
    if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
13386
 
    ctxt->dict = oldctxt->dict;
13387
 
    ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
13388
 
    ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
13389
 
    ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
13390
 
 
13391
 
#ifdef SAX2
13392
 
    /* propagate namespaces down the entity */
13393
 
    for (i = 0;i < oldctxt->nsNr;i += 2) {
13394
 
        nsPush(ctxt, oldctxt->nsTab[i], oldctxt->nsTab[i+1]);
13395
 
    }
13396
 
#endif
13397
 
 
13398
 
    oldsax = ctxt->sax;
13399
 
    ctxt->sax = oldctxt->sax;
13400
 
    xmlDetectSAX2(ctxt);
13401
 
    ctxt->replaceEntities = oldctxt->replaceEntities;
13402
 
    ctxt->options = oldctxt->options;
13403
 
 
13404
 
    ctxt->_private = oldctxt->_private;
13405
 
    if (oldctxt->myDoc == NULL) {
13406
 
        newDoc = xmlNewDoc(BAD_CAST "1.0");
13407
 
        if (newDoc == NULL) {
13408
 
            ctxt->sax = oldsax;
13409
 
            ctxt->dict = NULL;
13410
 
            xmlFreeParserCtxt(ctxt);
13411
 
            return(XML_ERR_INTERNAL_ERROR);
13412
 
        }
13413
 
        newDoc->properties = XML_DOC_INTERNAL;
13414
 
        newDoc->dict = ctxt->dict;
13415
 
        xmlDictReference(newDoc->dict);
13416
 
        ctxt->myDoc = newDoc;
13417
 
    } else {
13418
 
        ctxt->myDoc = oldctxt->myDoc;
13419
 
        content = ctxt->myDoc->children;
13420
 
        last = ctxt->myDoc->last;
13421
 
    }
13422
 
    newRoot = xmlNewDocNode(ctxt->myDoc, NULL, BAD_CAST "pseudoroot", NULL);
13423
 
    if (newRoot == NULL) {
13424
 
        ctxt->sax = oldsax;
13425
 
        ctxt->dict = NULL;
13426
 
        xmlFreeParserCtxt(ctxt);
13427
 
        if (newDoc != NULL) {
13428
 
            xmlFreeDoc(newDoc);
13429
 
        }
13430
 
        return(XML_ERR_INTERNAL_ERROR);
13431
 
    }
13432
 
    ctxt->myDoc->children = NULL;
13433
 
    ctxt->myDoc->last = NULL;
13434
 
    xmlAddChild((xmlNodePtr) ctxt->myDoc, newRoot);
13435
 
    nodePush(ctxt, ctxt->myDoc->children);
13436
 
    ctxt->instate = XML_PARSER_CONTENT;
13437
 
    ctxt->depth = oldctxt->depth + 1;
13438
 
 
13439
 
    ctxt->validate = 0;
13440
 
    ctxt->loadsubset = oldctxt->loadsubset;
13441
 
    if ((oldctxt->validate) || (oldctxt->replaceEntities != 0)) {
13442
 
        /*
13443
 
         * ID/IDREF registration will be done in xmlValidateElement below
13444
 
         */
13445
 
        ctxt->loadsubset |= XML_SKIP_IDS;
13446
 
    }
13447
 
    ctxt->dictNames = oldctxt->dictNames;
13448
 
    ctxt->attsDefault = oldctxt->attsDefault;
13449
 
    ctxt->attsSpecial = oldctxt->attsSpecial;
13450
 
 
13451
 
    xmlParseContent(ctxt);
13452
 
    if ((RAW == '<') && (NXT(1) == '/')) {
13453
 
        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13454
 
    } else if (RAW != 0) {
13455
 
        xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
13456
 
    }
13457
 
    if (ctxt->node != ctxt->myDoc->children) {
13458
 
        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13459
 
    }
13460
 
 
13461
 
    if (!ctxt->wellFormed) {
13462
 
        if (ctxt->errNo == 0)
13463
 
            ret = XML_ERR_INTERNAL_ERROR;
13464
 
        else
13465
 
            ret = (xmlParserErrors)ctxt->errNo;
13466
 
    } else {
13467
 
      ret = XML_ERR_OK;
13468
 
    }
13469
 
 
13470
 
    if ((lst != NULL) && (ret == XML_ERR_OK)) {
13471
 
        xmlNodePtr cur;
13472
 
 
13473
 
        /*
13474
 
         * Return the newly created nodeset after unlinking it from
13475
 
         * they pseudo parent.
13476
 
         */
13477
 
        cur = ctxt->myDoc->children->children;
13478
 
        *lst = cur;
13479
 
        while (cur != NULL) {
13480
 
#ifdef LIBXML_VALID_ENABLED
13481
 
            if ((oldctxt->validate) && (oldctxt->wellFormed) &&
13482
 
                (oldctxt->myDoc) && (oldctxt->myDoc->intSubset) &&
13483
 
                (cur->type == XML_ELEMENT_NODE)) {
13484
 
                oldctxt->valid &= xmlValidateElement(&oldctxt->vctxt,
13485
 
                        oldctxt->myDoc, cur);
13486
 
            }
13487
 
#endif /* LIBXML_VALID_ENABLED */
13488
 
            cur->parent = NULL;
13489
 
            cur = cur->next;
13490
 
        }
13491
 
        ctxt->myDoc->children->children = NULL;
13492
 
    }
13493
 
    if (ctxt->myDoc != NULL) {
13494
 
        xmlFreeNode(ctxt->myDoc->children);
13495
 
        ctxt->myDoc->children = content;
13496
 
        ctxt->myDoc->last = last;
13497
 
    }
13498
 
 
13499
 
    /*
13500
 
     * Record in the parent context the number of entities replacement
13501
 
     * done when parsing that reference.
13502
 
     */
13503
 
    if (oldctxt != NULL)
13504
 
        oldctxt->nbentities += ctxt->nbentities;
13505
 
 
13506
 
    /*
13507
 
     * Also record the last error if any
13508
 
     */
13509
 
    if (ctxt->lastError.code != XML_ERR_OK)
13510
 
        xmlCopyError(&ctxt->lastError, &oldctxt->lastError);
13511
 
 
13512
 
    ctxt->sax = oldsax;
13513
 
    ctxt->dict = NULL;
13514
 
    ctxt->attsDefault = NULL;
13515
 
    ctxt->attsSpecial = NULL;
13516
 
    xmlFreeParserCtxt(ctxt);
13517
 
    if (newDoc != NULL) {
13518
 
        xmlFreeDoc(newDoc);
13519
 
    }
13520
 
 
13521
 
    return(ret);
13522
 
}
13523
 
 
13524
 
/**
13525
 
 * xmlParseInNodeContext:
13526
 
 * @node:  the context node
13527
 
 * @data:  the input string
13528
 
 * @datalen:  the input string length in bytes
13529
 
 * @options:  a combination of xmlParserOption
13530
 
 * @lst:  the return value for the set of parsed nodes
13531
 
 *
13532
 
 * Parse a well-balanced chunk of an XML document
13533
 
 * within the context (DTD, namespaces, etc ...) of the given node.
13534
 
 *
13535
 
 * The allowed sequence for the data is a Well Balanced Chunk defined by
13536
 
 * the content production in the XML grammar:
13537
 
 *
13538
 
 * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
13539
 
 *
13540
 
 * Returns XML_ERR_OK if the chunk is well balanced, and the parser
13541
 
 * error code otherwise
13542
 
 */
13543
 
xmlParserErrors
13544
 
xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen,
13545
 
                      int options, xmlNodePtr *lst) {
13546
 
#ifdef SAX2
13547
 
    xmlParserCtxtPtr ctxt;
13548
 
    xmlDocPtr doc = NULL;
13549
 
    xmlNodePtr fake, cur;
13550
 
    int nsnr = 0;
13551
 
 
13552
 
    xmlParserErrors ret = XML_ERR_OK;
13553
 
 
13554
 
    /*
13555
 
     * check all input parameters, grab the document
13556
 
     */
13557
 
    if ((lst == NULL) || (node == NULL) || (data == NULL) || (datalen < 0))
13558
 
        return(XML_ERR_INTERNAL_ERROR);
13559
 
    switch (node->type) {
13560
 
        case XML_ELEMENT_NODE:
13561
 
        case XML_ATTRIBUTE_NODE:
13562
 
        case XML_TEXT_NODE:
13563
 
        case XML_CDATA_SECTION_NODE:
13564
 
        case XML_ENTITY_REF_NODE:
13565
 
        case XML_PI_NODE:
13566
 
        case XML_COMMENT_NODE:
13567
 
        case XML_DOCUMENT_NODE:
13568
 
        case XML_HTML_DOCUMENT_NODE:
13569
 
            break;
13570
 
        default:
13571
 
            return(XML_ERR_INTERNAL_ERROR);
13572
 
 
13573
 
    }
13574
 
    while ((node != NULL) && (node->type != XML_ELEMENT_NODE) &&
13575
 
           (node->type != XML_DOCUMENT_NODE) &&
13576
 
           (node->type != XML_HTML_DOCUMENT_NODE))
13577
 
        node = node->parent;
13578
 
    if (node == NULL)
13579
 
        return(XML_ERR_INTERNAL_ERROR);
13580
 
    if (node->type == XML_ELEMENT_NODE)
13581
 
        doc = node->doc;
13582
 
    else
13583
 
        doc = (xmlDocPtr) node;
13584
 
    if (doc == NULL)
13585
 
        return(XML_ERR_INTERNAL_ERROR);
13586
 
 
13587
 
    /*
13588
 
     * allocate a context and set-up everything not related to the
13589
 
     * node position in the tree
13590
 
     */
13591
 
    if (doc->type == XML_DOCUMENT_NODE)
13592
 
        ctxt = xmlCreateMemoryParserCtxt((char *) data, datalen);
13593
 
#ifdef LIBXML_HTML_ENABLED
13594
 
    else if (doc->type == XML_HTML_DOCUMENT_NODE) {
13595
 
        ctxt = htmlCreateMemoryParserCtxt((char *) data, datalen);
13596
 
        /*
13597
 
         * When parsing in context, it makes no sense to add implied
13598
 
         * elements like html/body/etc...
13599
 
         */
13600
 
        options |= HTML_PARSE_NOIMPLIED;
13601
 
    }
13602
 
#endif
13603
 
    else
13604
 
        return(XML_ERR_INTERNAL_ERROR);
13605
 
 
13606
 
    if (ctxt == NULL)
13607
 
        return(XML_ERR_NO_MEMORY);
13608
 
 
13609
 
    /*
13610
 
     * Use input doc's dict if present, else assure XML_PARSE_NODICT is set.
13611
 
     * We need a dictionary for xmlDetectSAX2, so if there's no doc dict
13612
 
     * we must wait until the last moment to free the original one.
13613
 
     */
13614
 
    if (doc->dict != NULL) {
13615
 
        if (ctxt->dict != NULL)
13616
 
            xmlDictFree(ctxt->dict);
13617
 
        ctxt->dict = doc->dict;
13618
 
    } else
13619
 
        options |= XML_PARSE_NODICT;
13620
 
 
13621
 
    if (doc->encoding != NULL) {
13622
 
        xmlCharEncodingHandlerPtr hdlr;
13623
 
 
13624
 
        if (ctxt->encoding != NULL)
13625
 
            xmlFree((xmlChar *) ctxt->encoding);
13626
 
        ctxt->encoding = xmlStrdup((const xmlChar *) doc->encoding);
13627
 
 
13628
 
        hdlr = xmlFindCharEncodingHandler(doc->encoding);
13629
 
        if (hdlr != NULL) {
13630
 
            xmlSwitchToEncoding(ctxt, hdlr);
13631
 
        } else {
13632
 
            return(XML_ERR_UNSUPPORTED_ENCODING);
13633
 
        }
13634
 
    }
13635
 
 
13636
 
    xmlCtxtUseOptionsInternal(ctxt, options, NULL);
13637
 
    xmlDetectSAX2(ctxt);
13638
 
    ctxt->myDoc = doc;
13639
 
 
13640
 
    fake = xmlNewComment(NULL);
13641
 
    if (fake == NULL) {
13642
 
        xmlFreeParserCtxt(ctxt);
13643
 
        return(XML_ERR_NO_MEMORY);
13644
 
    }
13645
 
    xmlAddChild(node, fake);
13646
 
 
13647
 
    if (node->type == XML_ELEMENT_NODE) {
13648
 
        nodePush(ctxt, node);
13649
 
        /*
13650
 
         * initialize the SAX2 namespaces stack
13651
 
         */
13652
 
        cur = node;
13653
 
        while ((cur != NULL) && (cur->type == XML_ELEMENT_NODE)) {
13654
 
            xmlNsPtr ns = cur->nsDef;
13655
 
            const xmlChar *iprefix, *ihref;
13656
 
 
13657
 
            while (ns != NULL) {
13658
 
                if (ctxt->dict) {
13659
 
                    iprefix = xmlDictLookup(ctxt->dict, ns->prefix, -1);
13660
 
                    ihref = xmlDictLookup(ctxt->dict, ns->href, -1);
13661
 
                } else {
13662
 
                    iprefix = ns->prefix;
13663
 
                    ihref = ns->href;
13664
 
                }
13665
 
 
13666
 
                if (xmlGetNamespace(ctxt, iprefix) == NULL) {
13667
 
                    nsPush(ctxt, iprefix, ihref);
13668
 
                    nsnr++;
13669
 
                }
13670
 
                ns = ns->next;
13671
 
            }
13672
 
            cur = cur->parent;
13673
 
        }
13674
 
        ctxt->instate = XML_PARSER_CONTENT;
13675
 
    }
13676
 
 
13677
 
    if ((ctxt->validate) || (ctxt->replaceEntities != 0)) {
13678
 
        /*
13679
 
         * ID/IDREF registration will be done in xmlValidateElement below
13680
 
         */
13681
 
        ctxt->loadsubset |= XML_SKIP_IDS;
13682
 
    }
13683
 
 
13684
 
#ifdef LIBXML_HTML_ENABLED
13685
 
    if (doc->type == XML_HTML_DOCUMENT_NODE)
13686
 
        __htmlParseContent(ctxt);
13687
 
    else
13688
 
#endif
13689
 
        xmlParseContent(ctxt);
13690
 
 
13691
 
    nsPop(ctxt, nsnr);
13692
 
    if ((RAW == '<') && (NXT(1) == '/')) {
13693
 
        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13694
 
    } else if (RAW != 0) {
13695
 
        xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
13696
 
    }
13697
 
    if ((ctxt->node != NULL) && (ctxt->node != node)) {
13698
 
        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13699
 
        ctxt->wellFormed = 0;
13700
 
    }
13701
 
 
13702
 
    if (!ctxt->wellFormed) {
13703
 
        if (ctxt->errNo == 0)
13704
 
            ret = XML_ERR_INTERNAL_ERROR;
13705
 
        else
13706
 
            ret = (xmlParserErrors)ctxt->errNo;
13707
 
    } else {
13708
 
        ret = XML_ERR_OK;
13709
 
    }
13710
 
 
13711
 
    /*
13712
 
     * Return the newly created nodeset after unlinking it from
13713
 
     * the pseudo sibling.
13714
 
     */
13715
 
 
13716
 
    cur = fake->next;
13717
 
    fake->next = NULL;
13718
 
    node->last = fake;
13719
 
 
13720
 
    if (cur != NULL) {
13721
 
        cur->prev = NULL;
13722
 
    }
13723
 
 
13724
 
    *lst = cur;
13725
 
 
13726
 
    while (cur != NULL) {
13727
 
        cur->parent = NULL;
13728
 
        cur = cur->next;
13729
 
    }
13730
 
 
13731
 
    xmlUnlinkNode(fake);
13732
 
    xmlFreeNode(fake);
13733
 
 
13734
 
 
13735
 
    if (ret != XML_ERR_OK) {
13736
 
        xmlFreeNodeList(*lst);
13737
 
        *lst = NULL;
13738
 
    }
13739
 
 
13740
 
    if (doc->dict != NULL)
13741
 
        ctxt->dict = NULL;
13742
 
    xmlFreeParserCtxt(ctxt);
13743
 
 
13744
 
    return(ret);
13745
 
#else /* !SAX2 */
13746
 
    return(XML_ERR_INTERNAL_ERROR);
13747
 
#endif
13748
 
}
13749
 
 
13750
 
#ifdef LIBXML_SAX1_ENABLED
13751
 
/**
13752
 
 * xmlParseBalancedChunkMemoryRecover:
13753
 
 * @doc:  the document the chunk pertains to
13754
 
 * @sax:  the SAX handler bloc (possibly NULL)
13755
 
 * @user_data:  The user data returned on SAX callbacks (possibly NULL)
13756
 
 * @depth:  Used for loop detection, use 0
13757
 
 * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
13758
 
 * @lst:  the return value for the set of parsed nodes
13759
 
 * @recover: return nodes even if the data is broken (use 0)
13760
 
 *
13761
 
 *
13762
 
 * Parse a well-balanced chunk of an XML document
13763
 
 * called by the parser
13764
 
 * The allowed sequence for the Well Balanced Chunk is the one defined by
13765
 
 * the content production in the XML grammar:
13766
 
 *
13767
 
 * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
13768
 
 *
13769
 
 * Returns 0 if the chunk is well balanced, -1 in case of args problem and
13770
 
 *    the parser error code otherwise
13771
 
 *
13772
 
 * In case recover is set to 1, the nodelist will not be empty even if
13773
 
 * the parsed chunk is not well balanced, assuming the parsing succeeded to
13774
 
 * some extent.
13775
 
 */
13776
 
int
13777
 
xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax,
13778
 
     void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst,
13779
 
     int recover) {
13780
 
    xmlParserCtxtPtr ctxt;
13781
 
    xmlDocPtr newDoc;
13782
 
    xmlSAXHandlerPtr oldsax = NULL;
13783
 
    xmlNodePtr content, newRoot;
13784
 
    int size;
13785
 
    int ret = 0;
13786
 
 
13787
 
    if (depth > 40) {
13788
 
        return(XML_ERR_ENTITY_LOOP);
13789
 
    }
13790
 
 
13791
 
 
13792
 
    if (lst != NULL)
13793
 
        *lst = NULL;
13794
 
    if (string == NULL)
13795
 
        return(-1);
13796
 
 
13797
 
    size = xmlStrlen(string);
13798
 
 
13799
 
    ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
13800
 
    if (ctxt == NULL) return(-1);
13801
 
    ctxt->userData = ctxt;
13802
 
    if (sax != NULL) {
13803
 
        oldsax = ctxt->sax;
13804
 
        ctxt->sax = sax;
13805
 
        if (user_data != NULL)
13806
 
            ctxt->userData = user_data;
13807
 
    }
13808
 
    newDoc = xmlNewDoc(BAD_CAST "1.0");
13809
 
    if (newDoc == NULL) {
13810
 
        xmlFreeParserCtxt(ctxt);
13811
 
        return(-1);
13812
 
    }
13813
 
    newDoc->properties = XML_DOC_INTERNAL;
13814
 
    if ((doc != NULL) && (doc->dict != NULL)) {
13815
 
        xmlDictFree(ctxt->dict);
13816
 
        ctxt->dict = doc->dict;
13817
 
        xmlDictReference(ctxt->dict);
13818
 
        ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
13819
 
        ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
13820
 
        ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
13821
 
        ctxt->dictNames = 1;
13822
 
    } else {
13823
 
        xmlCtxtUseOptionsInternal(ctxt, XML_PARSE_NODICT, NULL);
13824
 
    }
13825
 
    if (doc != NULL) {
13826
 
        newDoc->intSubset = doc->intSubset;
13827
 
        newDoc->extSubset = doc->extSubset;
13828
 
    }
13829
 
    newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
13830
 
    if (newRoot == NULL) {
13831
 
        if (sax != NULL)
13832
 
            ctxt->sax = oldsax;
13833
 
        xmlFreeParserCtxt(ctxt);
13834
 
        newDoc->intSubset = NULL;
13835
 
        newDoc->extSubset = NULL;
13836
 
        xmlFreeDoc(newDoc);
13837
 
        return(-1);
13838
 
    }
13839
 
    xmlAddChild((xmlNodePtr) newDoc, newRoot);
13840
 
    nodePush(ctxt, newRoot);
13841
 
    if (doc == NULL) {
13842
 
        ctxt->myDoc = newDoc;
13843
 
    } else {
13844
 
        ctxt->myDoc = newDoc;
13845
 
        newDoc->children->doc = doc;
13846
 
        /* Ensure that doc has XML spec namespace */
13847
 
        xmlSearchNsByHref(doc, (xmlNodePtr)doc, XML_XML_NAMESPACE);
13848
 
        newDoc->oldNs = doc->oldNs;
13849
 
    }
13850
 
    ctxt->instate = XML_PARSER_CONTENT;
13851
 
    ctxt->depth = depth;
13852
 
 
13853
 
    /*
13854
 
     * Doing validity checking on chunk doesn't make sense
13855
 
     */
13856
 
    ctxt->validate = 0;
13857
 
    ctxt->loadsubset = 0;
13858
 
    xmlDetectSAX2(ctxt);
13859
 
 
13860
 
    if ( doc != NULL ){
13861
 
        content = doc->children;
13862
 
        doc->children = NULL;
13863
 
        xmlParseContent(ctxt);
13864
 
        doc->children = content;
13865
 
    }
13866
 
    else {
13867
 
        xmlParseContent(ctxt);
13868
 
    }
13869
 
    if ((RAW == '<') && (NXT(1) == '/')) {
13870
 
        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13871
 
    } else if (RAW != 0) {
13872
 
        xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
13873
 
    }
13874
 
    if (ctxt->node != newDoc->children) {
13875
 
        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13876
 
    }
13877
 
 
13878
 
    if (!ctxt->wellFormed) {
13879
 
        if (ctxt->errNo == 0)
13880
 
            ret = 1;
13881
 
        else
13882
 
            ret = ctxt->errNo;
13883
 
    } else {
13884
 
      ret = 0;
13885
 
    }
13886
 
 
13887
 
    if ((lst != NULL) && ((ret == 0) || (recover == 1))) {
13888
 
        xmlNodePtr cur;
13889
 
 
13890
 
        /*
13891
 
         * Return the newly created nodeset after unlinking it from
13892
 
         * they pseudo parent.
13893
 
         */
13894
 
        cur = newDoc->children->children;
13895
 
        *lst = cur;
13896
 
        while (cur != NULL) {
13897
 
            xmlSetTreeDoc(cur, doc);
13898
 
            cur->parent = NULL;
13899
 
            cur = cur->next;
13900
 
        }
13901
 
        newDoc->children->children = NULL;
13902
 
    }
13903
 
 
13904
 
    if (sax != NULL)
13905
 
        ctxt->sax = oldsax;
13906
 
    xmlFreeParserCtxt(ctxt);
13907
 
    newDoc->intSubset = NULL;
13908
 
    newDoc->extSubset = NULL;
13909
 
    newDoc->oldNs = NULL;
13910
 
    xmlFreeDoc(newDoc);
13911
 
 
13912
 
    return(ret);
13913
 
}
13914
 
 
13915
 
/**
13916
 
 * xmlSAXParseEntity:
13917
 
 * @sax:  the SAX handler block
13918
 
 * @filename:  the filename
13919
 
 *
13920
 
 * parse an XML external entity out of context and build a tree.
13921
 
 * It use the given SAX function block to handle the parsing callback.
13922
 
 * If sax is NULL, fallback to the default DOM tree building routines.
13923
 
 *
13924
 
 * [78] extParsedEnt ::= TextDecl? content
13925
 
 *
13926
 
 * This correspond to a "Well Balanced" chunk
13927
 
 *
13928
 
 * Returns the resulting document tree
13929
 
 */
13930
 
 
13931
 
xmlDocPtr
13932
 
xmlSAXParseEntity(xmlSAXHandlerPtr sax, const char *filename) {
13933
 
    xmlDocPtr ret;
13934
 
    xmlParserCtxtPtr ctxt;
13935
 
 
13936
 
    ctxt = xmlCreateFileParserCtxt(filename);
13937
 
    if (ctxt == NULL) {
13938
 
        return(NULL);
13939
 
    }
13940
 
    if (sax != NULL) {
13941
 
        if (ctxt->sax != NULL)
13942
 
            xmlFree(ctxt->sax);
13943
 
        ctxt->sax = sax;
13944
 
        ctxt->userData = NULL;
13945
 
    }
13946
 
 
13947
 
    xmlParseExtParsedEnt(ctxt);
13948
 
 
13949
 
    if (ctxt->wellFormed)
13950
 
        ret = ctxt->myDoc;
13951
 
    else {
13952
 
        ret = NULL;
13953
 
        xmlFreeDoc(ctxt->myDoc);
13954
 
        ctxt->myDoc = NULL;
13955
 
    }
13956
 
    if (sax != NULL)
13957
 
        ctxt->sax = NULL;
13958
 
    xmlFreeParserCtxt(ctxt);
13959
 
 
13960
 
    return(ret);
13961
 
}
13962
 
 
13963
 
/**
13964
 
 * xmlParseEntity:
13965
 
 * @filename:  the filename
13966
 
 *
13967
 
 * parse an XML external entity out of context and build a tree.
13968
 
 *
13969
 
 * [78] extParsedEnt ::= TextDecl? content
13970
 
 *
13971
 
 * This correspond to a "Well Balanced" chunk
13972
 
 *
13973
 
 * Returns the resulting document tree
13974
 
 */
13975
 
 
13976
 
xmlDocPtr
13977
 
xmlParseEntity(const char *filename) {
13978
 
    return(xmlSAXParseEntity(NULL, filename));
13979
 
}
13980
 
#endif /* LIBXML_SAX1_ENABLED */
13981
 
 
13982
 
/**
13983
 
 * xmlCreateEntityParserCtxtInternal:
13984
 
 * @URL:  the entity URL
13985
 
 * @ID:  the entity PUBLIC ID
13986
 
 * @base:  a possible base for the target URI
13987
 
 * @pctx:  parser context used to set options on new context
13988
 
 *
13989
 
 * Create a parser context for an external entity
13990
 
 * Automatic support for ZLIB/Compress compressed document is provided
13991
 
 * by default if found at compile-time.
13992
 
 *
13993
 
 * Returns the new parser context or NULL
13994
 
 */
13995
 
static xmlParserCtxtPtr
13996
 
xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
13997
 
                          const xmlChar *base, xmlParserCtxtPtr pctx) {
13998
 
    xmlParserCtxtPtr ctxt;
13999
 
    xmlParserInputPtr inputStream;
14000
 
    char *directory = NULL;
14001
 
    xmlChar *uri;
14002
 
 
14003
 
    ctxt = xmlNewParserCtxt();
14004
 
    if (ctxt == NULL) {
14005
 
        return(NULL);
14006
 
    }
14007
 
 
14008
 
    if (pctx != NULL) {
14009
 
        ctxt->options = pctx->options;
14010
 
        ctxt->_private = pctx->_private;
14011
 
    }
14012
 
 
14013
 
    uri = xmlBuildURI(URL, base);
14014
 
 
14015
 
    if (uri == NULL) {
14016
 
        inputStream = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt);
14017
 
        if (inputStream == NULL) {
14018
 
            xmlFreeParserCtxt(ctxt);
14019
 
            return(NULL);
14020
 
        }
14021
 
 
14022
 
        inputPush(ctxt, inputStream);
14023
 
 
14024
 
        if ((ctxt->directory == NULL) && (directory == NULL))
14025
 
            directory = xmlParserGetDirectory((char *)URL);
14026
 
        if ((ctxt->directory == NULL) && (directory != NULL))
14027
 
            ctxt->directory = directory;
14028
 
    } else {
14029
 
        inputStream = xmlLoadExternalEntity((char *)uri, (char *)ID, ctxt);
14030
 
        if (inputStream == NULL) {
14031
 
            xmlFree(uri);
14032
 
            xmlFreeParserCtxt(ctxt);
14033
 
            return(NULL);
14034
 
        }
14035
 
 
14036
 
        inputPush(ctxt, inputStream);
14037
 
 
14038
 
        if ((ctxt->directory == NULL) && (directory == NULL))
14039
 
            directory = xmlParserGetDirectory((char *)uri);
14040
 
        if ((ctxt->directory == NULL) && (directory != NULL))
14041
 
            ctxt->directory = directory;
14042
 
        xmlFree(uri);
14043
 
    }
14044
 
    return(ctxt);
14045
 
}
14046
 
 
14047
 
/**
14048
 
 * xmlCreateEntityParserCtxt:
14049
 
 * @URL:  the entity URL
14050
 
 * @ID:  the entity PUBLIC ID
14051
 
 * @base:  a possible base for the target URI
14052
 
 *
14053
 
 * Create a parser context for an external entity
14054
 
 * Automatic support for ZLIB/Compress compressed document is provided
14055
 
 * by default if found at compile-time.
14056
 
 *
14057
 
 * Returns the new parser context or NULL
14058
 
 */
14059
 
xmlParserCtxtPtr
14060
 
xmlCreateEntityParserCtxt(const xmlChar *URL, const xmlChar *ID,
14061
 
                          const xmlChar *base) {
14062
 
    return xmlCreateEntityParserCtxtInternal(URL, ID, base, NULL);
14063
 
 
14064
 
}
14065
 
 
14066
 
/************************************************************************
14067
 
 *                                                                      *
14068
 
 *              Front ends when parsing from a file                     *
14069
 
 *                                                                      *
14070
 
 ************************************************************************/
14071
 
 
14072
 
/**
14073
 
 * xmlCreateURLParserCtxt:
14074
 
 * @filename:  the filename or URL
14075
 
 * @options:  a combination of xmlParserOption
14076
 
 *
14077
 
 * Create a parser context for a file or URL content.
14078
 
 * Automatic support for ZLIB/Compress compressed document is provided
14079
 
 * by default if found at compile-time and for file accesses
14080
 
 *
14081
 
 * Returns the new parser context or NULL
14082
 
 */
14083
 
xmlParserCtxtPtr
14084
 
xmlCreateURLParserCtxt(const char *filename, int options)
14085
 
{
14086
 
    xmlParserCtxtPtr ctxt;
14087
 
    xmlParserInputPtr inputStream;
14088
 
    char *directory = NULL;
14089
 
 
14090
 
    ctxt = xmlNewParserCtxt();
14091
 
    if (ctxt == NULL) {
14092
 
        xmlErrMemory(NULL, "cannot allocate parser context");
14093
 
        return(NULL);
14094
 
    }
14095
 
 
14096
 
    if (options)
14097
 
        xmlCtxtUseOptionsInternal(ctxt, options, NULL);
14098
 
    ctxt->linenumbers = 1;
14099
 
 
14100
 
    inputStream = xmlLoadExternalEntity(filename, NULL, ctxt);
14101
 
    if (inputStream == NULL) {
14102
 
        xmlFreeParserCtxt(ctxt);
14103
 
        return(NULL);
14104
 
    }
14105
 
 
14106
 
    inputPush(ctxt, inputStream);
14107
 
    if ((ctxt->directory == NULL) && (directory == NULL))
14108
 
        directory = xmlParserGetDirectory(filename);
14109
 
    if ((ctxt->directory == NULL) && (directory != NULL))
14110
 
        ctxt->directory = directory;
14111
 
 
14112
 
    return(ctxt);
14113
 
}
14114
 
 
14115
 
/**
14116
 
 * xmlCreateFileParserCtxt:
14117
 
 * @filename:  the filename
14118
 
 *
14119
 
 * Create a parser context for a file content.
14120
 
 * Automatic support for ZLIB/Compress compressed document is provided
14121
 
 * by default if found at compile-time.
14122
 
 *
14123
 
 * Returns the new parser context or NULL
14124
 
 */
14125
 
xmlParserCtxtPtr
14126
 
xmlCreateFileParserCtxt(const char *filename)
14127
 
{
14128
 
    return(xmlCreateURLParserCtxt(filename, 0));
14129
 
}
14130
 
 
14131
 
#ifdef LIBXML_SAX1_ENABLED
14132
 
/**
14133
 
 * xmlSAXParseFileWithData:
14134
 
 * @sax:  the SAX handler block
14135
 
 * @filename:  the filename
14136
 
 * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
14137
 
 *             documents
14138
 
 * @data:  the userdata
14139
 
 *
14140
 
 * parse an XML file and build a tree. Automatic support for ZLIB/Compress
14141
 
 * compressed document is provided by default if found at compile-time.
14142
 
 * It use the given SAX function block to handle the parsing callback.
14143
 
 * If sax is NULL, fallback to the default DOM tree building routines.
14144
 
 *
14145
 
 * User data (void *) is stored within the parser context in the
14146
 
 * context's _private member, so it is available nearly everywhere in libxml
14147
 
 *
14148
 
 * Returns the resulting document tree
14149
 
 */
14150
 
 
14151
 
xmlDocPtr
14152
 
xmlSAXParseFileWithData(xmlSAXHandlerPtr sax, const char *filename,
14153
 
                        int recovery, void *data) {
14154
 
    xmlDocPtr ret;
14155
 
    xmlParserCtxtPtr ctxt;
14156
 
 
14157
 
    xmlInitParser();
14158
 
 
14159
 
    ctxt = xmlCreateFileParserCtxt(filename);
14160
 
    if (ctxt == NULL) {
14161
 
        return(NULL);
14162
 
    }
14163
 
    if (sax != NULL) {
14164
 
        if (ctxt->sax != NULL)
14165
 
            xmlFree(ctxt->sax);
14166
 
        ctxt->sax = sax;
14167
 
    }
14168
 
    xmlDetectSAX2(ctxt);
14169
 
    if (data!=NULL) {
14170
 
        ctxt->_private = data;
14171
 
    }
14172
 
 
14173
 
    if (ctxt->directory == NULL)
14174
 
        ctxt->directory = xmlParserGetDirectory(filename);
14175
 
 
14176
 
    ctxt->recovery = recovery;
14177
 
 
14178
 
    xmlParseDocument(ctxt);
14179
 
 
14180
 
    if ((ctxt->wellFormed) || recovery) {
14181
 
        ret = ctxt->myDoc;
14182
 
        if (ret != NULL) {
14183
 
            if (ctxt->input->buf->compressed > 0)
14184
 
                ret->compression = 9;
14185
 
            else
14186
 
                ret->compression = ctxt->input->buf->compressed;
14187
 
        }
14188
 
    }
14189
 
    else {
14190
 
       ret = NULL;
14191
 
       xmlFreeDoc(ctxt->myDoc);
14192
 
       ctxt->myDoc = NULL;
14193
 
    }
14194
 
    if (sax != NULL)
14195
 
        ctxt->sax = NULL;
14196
 
    xmlFreeParserCtxt(ctxt);
14197
 
 
14198
 
    return(ret);
14199
 
}
14200
 
 
14201
 
/**
14202
 
 * xmlSAXParseFile:
14203
 
 * @sax:  the SAX handler block
14204
 
 * @filename:  the filename
14205
 
 * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
14206
 
 *             documents
14207
 
 *
14208
 
 * parse an XML file and build a tree. Automatic support for ZLIB/Compress
14209
 
 * compressed document is provided by default if found at compile-time.
14210
 
 * It use the given SAX function block to handle the parsing callback.
14211
 
 * If sax is NULL, fallback to the default DOM tree building routines.
14212
 
 *
14213
 
 * Returns the resulting document tree
14214
 
 */
14215
 
 
14216
 
xmlDocPtr
14217
 
xmlSAXParseFile(xmlSAXHandlerPtr sax, const char *filename,
14218
 
                          int recovery) {
14219
 
    return(xmlSAXParseFileWithData(sax,filename,recovery,NULL));
14220
 
}
14221
 
 
14222
 
/**
14223
 
 * xmlRecoverDoc:
14224
 
 * @cur:  a pointer to an array of xmlChar
14225
 
 *
14226
 
 * parse an XML in-memory document and build a tree.
14227
 
 * In the case the document is not Well Formed, a attempt to build a
14228
 
 * tree is tried anyway
14229
 
 *
14230
 
 * Returns the resulting document tree or NULL in case of failure
14231
 
 */
14232
 
 
14233
 
xmlDocPtr
14234
 
xmlRecoverDoc(const xmlChar *cur) {
14235
 
    return(xmlSAXParseDoc(NULL, cur, 1));
14236
 
}
14237
 
 
14238
 
/**
14239
 
 * xmlParseFile:
14240
 
 * @filename:  the filename
14241
 
 *
14242
 
 * parse an XML file and build a tree. Automatic support for ZLIB/Compress
14243
 
 * compressed document is provided by default if found at compile-time.
14244
 
 *
14245
 
 * Returns the resulting document tree if the file was wellformed,
14246
 
 * NULL otherwise.
14247
 
 */
14248
 
 
14249
 
xmlDocPtr
14250
 
xmlParseFile(const char *filename) {
14251
 
    return(xmlSAXParseFile(NULL, filename, 0));
14252
 
}
14253
 
 
14254
 
/**
14255
 
 * xmlRecoverFile:
14256
 
 * @filename:  the filename
14257
 
 *
14258
 
 * parse an XML file and build a tree. Automatic support for ZLIB/Compress
14259
 
 * compressed document is provided by default if found at compile-time.
14260
 
 * In the case the document is not Well Formed, it attempts to build
14261
 
 * a tree anyway
14262
 
 *
14263
 
 * Returns the resulting document tree or NULL in case of failure
14264
 
 */
14265
 
 
14266
 
xmlDocPtr
14267
 
xmlRecoverFile(const char *filename) {
14268
 
    return(xmlSAXParseFile(NULL, filename, 1));
14269
 
}
14270
 
 
14271
 
 
14272
 
/**
14273
 
 * xmlSetupParserForBuffer:
14274
 
 * @ctxt:  an XML parser context
14275
 
 * @buffer:  a xmlChar * buffer
14276
 
 * @filename:  a file name
14277
 
 *
14278
 
 * Setup the parser context to parse a new buffer; Clears any prior
14279
 
 * contents from the parser context. The buffer parameter must not be
14280
 
 * NULL, but the filename parameter can be
14281
 
 */
14282
 
void
14283
 
xmlSetupParserForBuffer(xmlParserCtxtPtr ctxt, const xmlChar* buffer,
14284
 
                             const char* filename)
14285
 
{
14286
 
    xmlParserInputPtr input;
14287
 
 
14288
 
    if ((ctxt == NULL) || (buffer == NULL))
14289
 
        return;
14290
 
 
14291
 
    input = xmlNewInputStream(ctxt);
14292
 
    if (input == NULL) {
14293
 
        xmlErrMemory(NULL, "parsing new buffer: out of memory\n");
14294
 
        xmlClearParserCtxt(ctxt);
14295
 
        return;
14296
 
    }
14297
 
 
14298
 
    xmlClearParserCtxt(ctxt);
14299
 
    if (filename != NULL)
14300
 
        input->filename = (char *) xmlCanonicPath((const xmlChar *)filename);
14301
 
    input->base = buffer;
14302
 
    input->cur = buffer;
14303
 
    input->end = &buffer[xmlStrlen(buffer)];
14304
 
    inputPush(ctxt, input);
14305
 
}
14306
 
 
14307
 
/**
14308
 
 * xmlSAXUserParseFile:
14309
 
 * @sax:  a SAX handler
14310
 
 * @user_data:  The user data returned on SAX callbacks
14311
 
 * @filename:  a file name
14312
 
 *
14313
 
 * parse an XML file and call the given SAX handler routines.
14314
 
 * Automatic support for ZLIB/Compress compressed document is provided
14315
 
 *
14316
 
 * Returns 0 in case of success or a error number otherwise
14317
 
 */
14318
 
int
14319
 
xmlSAXUserParseFile(xmlSAXHandlerPtr sax, void *user_data,
14320
 
                    const char *filename) {
14321
 
    int ret = 0;
14322
 
    xmlParserCtxtPtr ctxt;
14323
 
 
14324
 
    ctxt = xmlCreateFileParserCtxt(filename);
14325
 
    if (ctxt == NULL) return -1;
14326
 
    if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
14327
 
        xmlFree(ctxt->sax);
14328
 
    ctxt->sax = sax;
14329
 
    xmlDetectSAX2(ctxt);
14330
 
 
14331
 
    if (user_data != NULL)
14332
 
        ctxt->userData = user_data;
14333
 
 
14334
 
    xmlParseDocument(ctxt);
14335
 
 
14336
 
    if (ctxt->wellFormed)
14337
 
        ret = 0;
14338
 
    else {
14339
 
        if (ctxt->errNo != 0)
14340
 
            ret = ctxt->errNo;
14341
 
        else
14342
 
            ret = -1;
14343
 
    }
14344
 
    if (sax != NULL)
14345
 
        ctxt->sax = NULL;
14346
 
    if (ctxt->myDoc != NULL) {
14347
 
        xmlFreeDoc(ctxt->myDoc);
14348
 
        ctxt->myDoc = NULL;
14349
 
    }
14350
 
    xmlFreeParserCtxt(ctxt);
14351
 
 
14352
 
    return ret;
14353
 
}
14354
 
#endif /* LIBXML_SAX1_ENABLED */
14355
 
 
14356
 
/************************************************************************
14357
 
 *                                                                      *
14358
 
 *              Front ends when parsing from memory                     *
14359
 
 *                                                                      *
14360
 
 ************************************************************************/
14361
 
 
14362
 
/**
14363
 
 * xmlCreateMemoryParserCtxt:
14364
 
 * @buffer:  a pointer to a char array
14365
 
 * @size:  the size of the array
14366
 
 *
14367
 
 * Create a parser context for an XML in-memory document.
14368
 
 *
14369
 
 * Returns the new parser context or NULL
14370
 
 */
14371
 
xmlParserCtxtPtr
14372
 
xmlCreateMemoryParserCtxt(const char *buffer, int size) {
14373
 
    xmlParserCtxtPtr ctxt;
14374
 
    xmlParserInputPtr input;
14375
 
    xmlParserInputBufferPtr buf;
14376
 
 
14377
 
    if (buffer == NULL)
14378
 
        return(NULL);
14379
 
    if (size <= 0)
14380
 
        return(NULL);
14381
 
 
14382
 
    ctxt = xmlNewParserCtxt();
14383
 
    if (ctxt == NULL)
14384
 
        return(NULL);
14385
 
 
14386
 
    /* TODO: xmlParserInputBufferCreateStatic, requires some serious changes */
14387
 
    buf = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
14388
 
    if (buf == NULL) {
14389
 
        xmlFreeParserCtxt(ctxt);
14390
 
        return(NULL);
14391
 
    }
14392
 
 
14393
 
    input = xmlNewInputStream(ctxt);
14394
 
    if (input == NULL) {
14395
 
        xmlFreeParserInputBuffer(buf);
14396
 
        xmlFreeParserCtxt(ctxt);
14397
 
        return(NULL);
14398
 
    }
14399
 
 
14400
 
    input->filename = NULL;
14401
 
    input->buf = buf;
14402
 
    xmlBufResetInput(input->buf->buffer, input);
14403
 
 
14404
 
    inputPush(ctxt, input);
14405
 
    return(ctxt);
14406
 
}
14407
 
 
14408
 
#ifdef LIBXML_SAX1_ENABLED
14409
 
/**
14410
 
 * xmlSAXParseMemoryWithData:
14411
 
 * @sax:  the SAX handler block
14412
 
 * @buffer:  an pointer to a char array
14413
 
 * @size:  the size of the array
14414
 
 * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
14415
 
 *             documents
14416
 
 * @data:  the userdata
14417
 
 *
14418
 
 * parse an XML in-memory block and use the given SAX function block
14419
 
 * to handle the parsing callback. If sax is NULL, fallback to the default
14420
 
 * DOM tree building routines.
14421
 
 *
14422
 
 * User data (void *) is stored within the parser context in the
14423
 
 * context's _private member, so it is available nearly everywhere in libxml
14424
 
 *
14425
 
 * Returns the resulting document tree
14426
 
 */
14427
 
 
14428
 
xmlDocPtr
14429
 
xmlSAXParseMemoryWithData(xmlSAXHandlerPtr sax, const char *buffer,
14430
 
                  int size, int recovery, void *data) {
14431
 
    xmlDocPtr ret;
14432
 
    xmlParserCtxtPtr ctxt;
14433
 
 
14434
 
    xmlInitParser();
14435
 
 
14436
 
    ctxt = xmlCreateMemoryParserCtxt(buffer, size);
14437
 
    if (ctxt == NULL) return(NULL);
14438
 
    if (sax != NULL) {
14439
 
        if (ctxt->sax != NULL)
14440
 
            xmlFree(ctxt->sax);
14441
 
        ctxt->sax = sax;
14442
 
    }
14443
 
    xmlDetectSAX2(ctxt);
14444
 
    if (data!=NULL) {
14445
 
        ctxt->_private=data;
14446
 
    }
14447
 
 
14448
 
    ctxt->recovery = recovery;
14449
 
 
14450
 
    xmlParseDocument(ctxt);
14451
 
 
14452
 
    if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
14453
 
    else {
14454
 
       ret = NULL;
14455
 
       xmlFreeDoc(ctxt->myDoc);
14456
 
       ctxt->myDoc = NULL;
14457
 
    }
14458
 
    if (sax != NULL)
14459
 
        ctxt->sax = NULL;
14460
 
    xmlFreeParserCtxt(ctxt);
14461
 
 
14462
 
    return(ret);
14463
 
}
14464
 
 
14465
 
/**
14466
 
 * xmlSAXParseMemory:
14467
 
 * @sax:  the SAX handler block
14468
 
 * @buffer:  an pointer to a char array
14469
 
 * @size:  the size of the array
14470
 
 * @recovery:  work in recovery mode, i.e. tries to read not Well Formed
14471
 
 *             documents
14472
 
 *
14473
 
 * parse an XML in-memory block and use the given SAX function block
14474
 
 * to handle the parsing callback. If sax is NULL, fallback to the default
14475
 
 * DOM tree building routines.
14476
 
 *
14477
 
 * Returns the resulting document tree
14478
 
 */
14479
 
xmlDocPtr
14480
 
xmlSAXParseMemory(xmlSAXHandlerPtr sax, const char *buffer,
14481
 
                  int size, int recovery) {
14482
 
    return xmlSAXParseMemoryWithData(sax, buffer, size, recovery, NULL);
14483
 
}
14484
 
 
14485
 
/**
14486
 
 * xmlParseMemory:
14487
 
 * @buffer:  an pointer to a char array
14488
 
 * @size:  the size of the array
14489
 
 *
14490
 
 * parse an XML in-memory block and build a tree.
14491
 
 *
14492
 
 * Returns the resulting document tree
14493
 
 */
14494
 
 
14495
 
xmlDocPtr xmlParseMemory(const char *buffer, int size) {
14496
 
   return(xmlSAXParseMemory(NULL, buffer, size, 0));
14497
 
}
14498
 
 
14499
 
/**
14500
 
 * xmlRecoverMemory:
14501
 
 * @buffer:  an pointer to a char array
14502
 
 * @size:  the size of the array
14503
 
 *
14504
 
 * parse an XML in-memory block and build a tree.
14505
 
 * In the case the document is not Well Formed, an attempt to
14506
 
 * build a tree is tried anyway
14507
 
 *
14508
 
 * Returns the resulting document tree or NULL in case of error
14509
 
 */
14510
 
 
14511
 
xmlDocPtr xmlRecoverMemory(const char *buffer, int size) {
14512
 
   return(xmlSAXParseMemory(NULL, buffer, size, 1));
14513
 
}
14514
 
 
14515
 
/**
14516
 
 * xmlSAXUserParseMemory:
14517
 
 * @sax:  a SAX handler
14518
 
 * @user_data:  The user data returned on SAX callbacks
14519
 
 * @buffer:  an in-memory XML document input
14520
 
 * @size:  the length of the XML document in bytes
14521
 
 *
14522
 
 * A better SAX parsing routine.
14523
 
 * parse an XML in-memory buffer and call the given SAX handler routines.
14524
 
 *
14525
 
 * Returns 0 in case of success or a error number otherwise
14526
 
 */
14527
 
int xmlSAXUserParseMemory(xmlSAXHandlerPtr sax, void *user_data,
14528
 
                          const char *buffer, int size) {
14529
 
    int ret = 0;
14530
 
    xmlParserCtxtPtr ctxt;
14531
 
 
14532
 
    xmlInitParser();
14533
 
 
14534
 
    ctxt = xmlCreateMemoryParserCtxt(buffer, size);
14535
 
    if (ctxt == NULL) return -1;
14536
 
    if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
14537
 
        xmlFree(ctxt->sax);
14538
 
    ctxt->sax = sax;
14539
 
    xmlDetectSAX2(ctxt);
14540
 
 
14541
 
    if (user_data != NULL)
14542
 
        ctxt->userData = user_data;
14543
 
 
14544
 
    xmlParseDocument(ctxt);
14545
 
 
14546
 
    if (ctxt->wellFormed)
14547
 
        ret = 0;
14548
 
    else {
14549
 
        if (ctxt->errNo != 0)
14550
 
            ret = ctxt->errNo;
14551
 
        else
14552
 
            ret = -1;
14553
 
    }
14554
 
    if (sax != NULL)
14555
 
        ctxt->sax = NULL;
14556
 
    if (ctxt->myDoc != NULL) {
14557
 
        xmlFreeDoc(ctxt->myDoc);
14558
 
        ctxt->myDoc = NULL;
14559
 
    }
14560
 
    xmlFreeParserCtxt(ctxt);
14561
 
 
14562
 
    return ret;
14563
 
}
14564
 
#endif /* LIBXML_SAX1_ENABLED */
14565
 
 
14566
 
/**
14567
 
 * xmlCreateDocParserCtxt:
14568
 
 * @cur:  a pointer to an array of xmlChar
14569
 
 *
14570
 
 * Creates a parser context for an XML in-memory document.
14571
 
 *
14572
 
 * Returns the new parser context or NULL
14573
 
 */
14574
 
xmlParserCtxtPtr
14575
 
xmlCreateDocParserCtxt(const xmlChar *cur) {
14576
 
    int len;
14577
 
 
14578
 
    if (cur == NULL)
14579
 
        return(NULL);
14580
 
    len = xmlStrlen(cur);
14581
 
    return(xmlCreateMemoryParserCtxt((const char *)cur, len));
14582
 
}
14583
 
 
14584
 
#ifdef LIBXML_SAX1_ENABLED
14585
 
/**
14586
 
 * xmlSAXParseDoc:
14587
 
 * @sax:  the SAX handler block
14588
 
 * @cur:  a pointer to an array of xmlChar
14589
 
 * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
14590
 
 *             documents
14591
 
 *
14592
 
 * parse an XML in-memory document and build a tree.
14593
 
 * It use the given SAX function block to handle the parsing callback.
14594
 
 * If sax is NULL, fallback to the default DOM tree building routines.
14595
 
 *
14596
 
 * Returns the resulting document tree
14597
 
 */
14598
 
 
14599
 
xmlDocPtr
14600
 
xmlSAXParseDoc(xmlSAXHandlerPtr sax, const xmlChar *cur, int recovery) {
14601
 
    xmlDocPtr ret;
14602
 
    xmlParserCtxtPtr ctxt;
14603
 
    xmlSAXHandlerPtr oldsax = NULL;
14604
 
 
14605
 
    if (cur == NULL) return(NULL);
14606
 
 
14607
 
 
14608
 
    ctxt = xmlCreateDocParserCtxt(cur);
14609
 
    if (ctxt == NULL) return(NULL);
14610
 
    if (sax != NULL) {
14611
 
        oldsax = ctxt->sax;
14612
 
        ctxt->sax = sax;
14613
 
        ctxt->userData = NULL;
14614
 
    }
14615
 
    xmlDetectSAX2(ctxt);
14616
 
 
14617
 
    xmlParseDocument(ctxt);
14618
 
    if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
14619
 
    else {
14620
 
       ret = NULL;
14621
 
       xmlFreeDoc(ctxt->myDoc);
14622
 
       ctxt->myDoc = NULL;
14623
 
    }
14624
 
    if (sax != NULL)
14625
 
        ctxt->sax = oldsax;
14626
 
    xmlFreeParserCtxt(ctxt);
14627
 
 
14628
 
    return(ret);
14629
 
}
14630
 
 
14631
 
/**
14632
 
 * xmlParseDoc:
14633
 
 * @cur:  a pointer to an array of xmlChar
14634
 
 *
14635
 
 * parse an XML in-memory document and build a tree.
14636
 
 *
14637
 
 * Returns the resulting document tree
14638
 
 */
14639
 
 
14640
 
xmlDocPtr
14641
 
xmlParseDoc(const xmlChar *cur) {
14642
 
    return(xmlSAXParseDoc(NULL, cur, 0));
14643
 
}
14644
 
#endif /* LIBXML_SAX1_ENABLED */
14645
 
 
14646
 
#ifdef LIBXML_LEGACY_ENABLED
14647
 
/************************************************************************
14648
 
 *                                                                      *
14649
 
 *      Specific function to keep track of entities references          *
14650
 
 *      and used by the XSLT debugger                                   *
14651
 
 *                                                                      *
14652
 
 ************************************************************************/
14653
 
 
14654
 
static xmlEntityReferenceFunc xmlEntityRefFunc = NULL;
14655
 
 
14656
 
/**
14657
 
 * xmlAddEntityReference:
14658
 
 * @ent : A valid entity
14659
 
 * @firstNode : A valid first node for children of entity
14660
 
 * @lastNode : A valid last node of children entity
14661
 
 *
14662
 
 * Notify of a reference to an entity of type XML_EXTERNAL_GENERAL_PARSED_ENTITY
14663
 
 */
14664
 
static void
14665
 
xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
14666
 
                      xmlNodePtr lastNode)
14667
 
{
14668
 
    if (xmlEntityRefFunc != NULL) {
14669
 
        (*xmlEntityRefFunc) (ent, firstNode, lastNode);
14670
 
    }
14671
 
}
14672
 
 
14673
 
 
14674
 
/**
14675
 
 * xmlSetEntityReferenceFunc:
14676
 
 * @func: A valid function
14677
 
 *
14678
 
 * Set the function to call call back when a xml reference has been made
14679
 
 */
14680
 
void
14681
 
xmlSetEntityReferenceFunc(xmlEntityReferenceFunc func)
14682
 
{
14683
 
    xmlEntityRefFunc = func;
14684
 
}
14685
 
#endif /* LIBXML_LEGACY_ENABLED */
14686
 
 
14687
 
/************************************************************************
14688
 
 *                                                                      *
14689
 
 *                              Miscellaneous                           *
14690
 
 *                                                                      *
14691
 
 ************************************************************************/
14692
 
 
14693
 
#ifdef LIBXML_XPATH_ENABLED
14694
 
#include <libxml/xpath.h>
14695
 
#endif
14696
 
 
14697
 
extern void XMLCDECL xmlGenericErrorDefaultFunc(void *ctx, const char *msg, ...);
14698
 
static int xmlParserInitialized = 0;
14699
 
 
14700
 
/**
14701
 
 * xmlInitParser:
14702
 
 *
14703
 
 * Initialization function for the XML parser.
14704
 
 * This is not reentrant. Call once before processing in case of
14705
 
 * use in multithreaded programs.
14706
 
 */
14707
 
 
14708
 
void
14709
 
xmlInitParser(void) {
14710
 
    if (xmlParserInitialized != 0)
14711
 
        return;
14712
 
 
14713
 
#ifdef LIBXML_THREAD_ENABLED
14714
 
    __xmlGlobalInitMutexLock();
14715
 
    if (xmlParserInitialized == 0) {
14716
 
#endif
14717
 
        xmlInitThreads();
14718
 
        xmlInitGlobals();
14719
 
        if ((xmlGenericError == xmlGenericErrorDefaultFunc) ||
14720
 
            (xmlGenericError == NULL))
14721
 
            initGenericErrorDefaultFunc(NULL);
14722
 
        xmlInitMemory();
14723
 
        xmlInitializeDict();
14724
 
        xmlInitCharEncodingHandlers();
14725
 
        xmlDefaultSAXHandlerInit();
14726
 
        xmlRegisterDefaultInputCallbacks();
14727
 
#ifdef LIBXML_OUTPUT_ENABLED
14728
 
        xmlRegisterDefaultOutputCallbacks();
14729
 
#endif /* LIBXML_OUTPUT_ENABLED */
14730
 
#ifdef LIBXML_HTML_ENABLED
14731
 
        htmlInitAutoClose();
14732
 
        htmlDefaultSAXHandlerInit();
14733
 
#endif
14734
 
#ifdef LIBXML_XPATH_ENABLED
14735
 
        xmlXPathInit();
14736
 
#endif
14737
 
        xmlParserInitialized = 1;
14738
 
#ifdef LIBXML_THREAD_ENABLED
14739
 
    }
14740
 
    __xmlGlobalInitMutexUnlock();
14741
 
#endif
14742
 
}
14743
 
 
14744
 
/**
14745
 
 * xmlCleanupParser:
14746
 
 *
14747
 
 * This function name is somewhat misleading. It does not clean up
14748
 
 * parser state, it cleans up memory allocated by the library itself.
14749
 
 * It is a cleanup function for the XML library. It tries to reclaim all
14750
 
 * related global memory allocated for the library processing.
14751
 
 * It doesn't deallocate any document related memory. One should
14752
 
 * call xmlCleanupParser() only when the process has finished using
14753
 
 * the library and all XML/HTML documents built with it.
14754
 
 * See also xmlInitParser() which has the opposite function of preparing
14755
 
 * the library for operations.
14756
 
 *
14757
 
 * WARNING: if your application is multithreaded or has plugin support
14758
 
 *          calling this may crash the application if another thread or
14759
 
 *          a plugin is still using libxml2. It's sometimes very hard to
14760
 
 *          guess if libxml2 is in use in the application, some libraries
14761
 
 *          or plugins may use it without notice. In case of doubt abstain
14762
 
 *          from calling this function or do it just before calling exit()
14763
 
 *          to avoid leak reports from valgrind !
14764
 
 */
14765
 
 
14766
 
void
14767
 
xmlCleanupParser(void) {
14768
 
    if (!xmlParserInitialized)
14769
 
        return;
14770
 
 
14771
 
    xmlCleanupCharEncodingHandlers();
14772
 
#ifdef LIBXML_CATALOG_ENABLED
14773
 
    xmlCatalogCleanup();
14774
 
#endif
14775
 
    xmlDictCleanup();
14776
 
    xmlCleanupInputCallbacks();
14777
 
#ifdef LIBXML_OUTPUT_ENABLED
14778
 
    xmlCleanupOutputCallbacks();
14779
 
#endif
14780
 
#ifdef LIBXML_SCHEMAS_ENABLED
14781
 
    xmlSchemaCleanupTypes();
14782
 
    xmlRelaxNGCleanupTypes();
14783
 
#endif
14784
 
    xmlResetLastError();
14785
 
    xmlCleanupGlobals();
14786
 
    xmlCleanupThreads(); /* must be last if called not from the main thread */
14787
 
    xmlCleanupMemory();
14788
 
    xmlParserInitialized = 0;
14789
 
}
14790
 
 
14791
 
/************************************************************************
14792
 
 *                                                                      *
14793
 
 *      New set (2.6.0) of simpler and more flexible APIs               *
14794
 
 *                                                                      *
14795
 
 ************************************************************************/
14796
 
 
14797
 
/**
14798
 
 * DICT_FREE:
14799
 
 * @str:  a string
14800
 
 *
14801
 
 * Free a string if it is not owned by the "dict" dictionnary in the
14802
 
 * current scope
14803
 
 */
14804
 
#define DICT_FREE(str)                                          \
14805
 
        if ((str) && ((!dict) ||                                \
14806
 
            (xmlDictOwns(dict, (const xmlChar *)(str)) == 0)))  \
14807
 
            xmlFree((char *)(str));
14808
 
 
14809
 
/**
14810
 
 * xmlCtxtReset:
14811
 
 * @ctxt: an XML parser context
14812
 
 *
14813
 
 * Reset a parser context
14814
 
 */
14815
 
void
14816
 
xmlCtxtReset(xmlParserCtxtPtr ctxt)
14817
 
{
14818
 
    xmlParserInputPtr input;
14819
 
    xmlDictPtr dict;
14820
 
 
14821
 
    if (ctxt == NULL)
14822
 
        return;
14823
 
 
14824
 
    dict = ctxt->dict;
14825
 
 
14826
 
    while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
14827
 
        xmlFreeInputStream(input);
14828
 
    }
14829
 
    ctxt->inputNr = 0;
14830
 
    ctxt->input = NULL;
14831
 
 
14832
 
    ctxt->spaceNr = 0;
14833
 
    if (ctxt->spaceTab != NULL) {
14834
 
        ctxt->spaceTab[0] = -1;
14835
 
        ctxt->space = &ctxt->spaceTab[0];
14836
 
    } else {
14837
 
        ctxt->space = NULL;
14838
 
    }
14839
 
 
14840
 
 
14841
 
    ctxt->nodeNr = 0;
14842
 
    ctxt->node = NULL;
14843
 
 
14844
 
    ctxt->nameNr = 0;
14845
 
    ctxt->name = NULL;
14846
 
 
14847
 
    DICT_FREE(ctxt->version);
14848
 
    ctxt->version = NULL;
14849
 
    DICT_FREE(ctxt->encoding);
14850
 
    ctxt->encoding = NULL;
14851
 
    DICT_FREE(ctxt->directory);
14852
 
    ctxt->directory = NULL;
14853
 
    DICT_FREE(ctxt->extSubURI);
14854
 
    ctxt->extSubURI = NULL;
14855
 
    DICT_FREE(ctxt->extSubSystem);
14856
 
    ctxt->extSubSystem = NULL;
14857
 
    if (ctxt->myDoc != NULL)
14858
 
        xmlFreeDoc(ctxt->myDoc);
14859
 
    ctxt->myDoc = NULL;
14860
 
 
14861
 
    ctxt->standalone = -1;
14862
 
    ctxt->hasExternalSubset = 0;
14863
 
    ctxt->hasPErefs = 0;
14864
 
    ctxt->html = 0;
14865
 
    ctxt->external = 0;
14866
 
    ctxt->instate = XML_PARSER_START;
14867
 
    ctxt->token = 0;
14868
 
 
14869
 
    ctxt->wellFormed = 1;
14870
 
    ctxt->nsWellFormed = 1;
14871
 
    ctxt->disableSAX = 0;
14872
 
    ctxt->valid = 1;
14873
 
#if 0
14874
 
    ctxt->vctxt.userData = ctxt;
14875
 
    ctxt->vctxt.error = xmlParserValidityError;
14876
 
    ctxt->vctxt.warning = xmlParserValidityWarning;
14877
 
#endif
14878
 
    ctxt->record_info = 0;
14879
 
    ctxt->nbChars = 0;
14880
 
    ctxt->checkIndex = 0;
14881
 
    ctxt->inSubset = 0;
14882
 
    ctxt->errNo = XML_ERR_OK;
14883
 
    ctxt->depth = 0;
14884
 
    ctxt->charset = XML_CHAR_ENCODING_UTF8;
14885
 
    ctxt->catalogs = NULL;
14886
 
    ctxt->nbentities = 0;
14887
 
    ctxt->sizeentities = 0;
14888
 
    ctxt->sizeentcopy = 0;
14889
 
    xmlInitNodeInfoSeq(&ctxt->node_seq);
14890
 
 
14891
 
    if (ctxt->attsDefault != NULL) {
14892
 
        xmlHashFree(ctxt->attsDefault, (xmlHashDeallocator) xmlFree);
14893
 
        ctxt->attsDefault = NULL;
14894
 
    }
14895
 
    if (ctxt->attsSpecial != NULL) {
14896
 
        xmlHashFree(ctxt->attsSpecial, NULL);
14897
 
        ctxt->attsSpecial = NULL;
14898
 
    }
14899
 
 
14900
 
#ifdef LIBXML_CATALOG_ENABLED
14901
 
    if (ctxt->catalogs != NULL)
14902
 
        xmlCatalogFreeLocal(ctxt->catalogs);
14903
 
#endif
14904
 
    if (ctxt->lastError.code != XML_ERR_OK)
14905
 
        xmlResetError(&ctxt->lastError);
14906
 
}
14907
 
 
14908
 
/**
14909
 
 * xmlCtxtResetPush:
14910
 
 * @ctxt: an XML parser context
14911
 
 * @chunk:  a pointer to an array of chars
14912
 
 * @size:  number of chars in the array
14913
 
 * @filename:  an optional file name or URI
14914
 
 * @encoding:  the document encoding, or NULL
14915
 
 *
14916
 
 * Reset a push parser context
14917
 
 *
14918
 
 * Returns 0 in case of success and 1 in case of error
14919
 
 */
14920
 
int
14921
 
xmlCtxtResetPush(xmlParserCtxtPtr ctxt, const char *chunk,
14922
 
                 int size, const char *filename, const char *encoding)
14923
 
{
14924
 
    xmlParserInputPtr inputStream;
14925
 
    xmlParserInputBufferPtr buf;
14926
 
    xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
14927
 
 
14928
 
    if (ctxt == NULL)
14929
 
        return(1);
14930
 
 
14931
 
    if ((encoding == NULL) && (chunk != NULL) && (size >= 4))
14932
 
        enc = xmlDetectCharEncoding((const xmlChar *) chunk, size);
14933
 
 
14934
 
    buf = xmlAllocParserInputBuffer(enc);
14935
 
    if (buf == NULL)
14936
 
        return(1);
14937
 
 
14938
 
    if (ctxt == NULL) {
14939
 
        xmlFreeParserInputBuffer(buf);
14940
 
        return(1);
14941
 
    }
14942
 
 
14943
 
    xmlCtxtReset(ctxt);
14944
 
 
14945
 
    if (ctxt->pushTab == NULL) {
14946
 
        ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 *
14947
 
                                            sizeof(xmlChar *));
14948
 
        if (ctxt->pushTab == NULL) {
14949
 
            xmlErrMemory(ctxt, NULL);
14950
 
            xmlFreeParserInputBuffer(buf);
14951
 
            return(1);
14952
 
        }
14953
 
    }
14954
 
 
14955
 
    if (filename == NULL) {
14956
 
        ctxt->directory = NULL;
14957
 
    } else {
14958
 
        ctxt->directory = xmlParserGetDirectory(filename);
14959
 
    }
14960
 
 
14961
 
    inputStream = xmlNewInputStream(ctxt);
14962
 
    if (inputStream == NULL) {
14963
 
        xmlFreeParserInputBuffer(buf);
14964
 
        return(1);
14965
 
    }
14966
 
 
14967
 
    if (filename == NULL)
14968
 
        inputStream->filename = NULL;
14969
 
    else
14970
 
        inputStream->filename = (char *)
14971
 
            xmlCanonicPath((const xmlChar *) filename);
14972
 
    inputStream->buf = buf;
14973
 
    xmlBufResetInput(buf->buffer, inputStream);
14974
 
 
14975
 
    inputPush(ctxt, inputStream);
14976
 
 
14977
 
    if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
14978
 
        (ctxt->input->buf != NULL)) {
14979
 
        size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer, ctxt->input);
14980
 
        size_t cur = ctxt->input->cur - ctxt->input->base;
14981
 
 
14982
 
        xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
14983
 
 
14984
 
        xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur);
14985
 
#ifdef DEBUG_PUSH
14986
 
        xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
14987
 
#endif
14988
 
    }
14989
 
 
14990
 
    if (encoding != NULL) {
14991
 
        xmlCharEncodingHandlerPtr hdlr;
14992
 
 
14993
 
        if (ctxt->encoding != NULL)
14994
 
            xmlFree((xmlChar *) ctxt->encoding);
14995
 
        ctxt->encoding = xmlStrdup((const xmlChar *) encoding);
14996
 
 
14997
 
        hdlr = xmlFindCharEncodingHandler(encoding);
14998
 
        if (hdlr != NULL) {
14999
 
            xmlSwitchToEncoding(ctxt, hdlr);
15000
 
        } else {
15001
 
            xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
15002
 
                              "Unsupported encoding %s\n", BAD_CAST encoding);
15003
 
        }
15004
 
    } else if (enc != XML_CHAR_ENCODING_NONE) {
15005
 
        xmlSwitchEncoding(ctxt, enc);
15006
 
    }
15007
 
 
15008
 
    return(0);
15009
 
}
15010
 
 
15011
 
 
15012
 
/**
15013
 
 * xmlCtxtUseOptionsInternal:
15014
 
 * @ctxt: an XML parser context
15015
 
 * @options:  a combination of xmlParserOption
15016
 
 * @encoding:  the user provided encoding to use
15017
 
 *
15018
 
 * Applies the options to the parser context
15019
 
 *
15020
 
 * Returns 0 in case of success, the set of unknown or unimplemented options
15021
 
 *         in case of error.
15022
 
 */
15023
 
static int
15024
 
xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options, const char *encoding)
15025
 
{
15026
 
    if (ctxt == NULL)
15027
 
        return(-1);
15028
 
    if (encoding != NULL) {
15029
 
        if (ctxt->encoding != NULL)
15030
 
            xmlFree((xmlChar *) ctxt->encoding);
15031
 
        ctxt->encoding = xmlStrdup((const xmlChar *) encoding);
15032
 
    }
15033
 
    if (options & XML_PARSE_RECOVER) {
15034
 
        ctxt->recovery = 1;
15035
 
        options -= XML_PARSE_RECOVER;
15036
 
        ctxt->options |= XML_PARSE_RECOVER;
15037
 
    } else
15038
 
        ctxt->recovery = 0;
15039
 
    if (options & XML_PARSE_DTDLOAD) {
15040
 
        ctxt->loadsubset = XML_DETECT_IDS;
15041
 
        options -= XML_PARSE_DTDLOAD;
15042
 
        ctxt->options |= XML_PARSE_DTDLOAD;
15043
 
    } else
15044
 
        ctxt->loadsubset = 0;
15045
 
    if (options & XML_PARSE_DTDATTR) {
15046
 
        ctxt->loadsubset |= XML_COMPLETE_ATTRS;
15047
 
        options -= XML_PARSE_DTDATTR;
15048
 
        ctxt->options |= XML_PARSE_DTDATTR;
15049
 
    }
15050
 
    if (options & XML_PARSE_NOENT) {
15051
 
        ctxt->replaceEntities = 1;
15052
 
        /* ctxt->loadsubset |= XML_DETECT_IDS; */
15053
 
        options -= XML_PARSE_NOENT;
15054
 
        ctxt->options |= XML_PARSE_NOENT;
15055
 
    } else
15056
 
        ctxt->replaceEntities = 0;
15057
 
    if (options & XML_PARSE_PEDANTIC) {
15058
 
        ctxt->pedantic = 1;
15059
 
        options -= XML_PARSE_PEDANTIC;
15060
 
        ctxt->options |= XML_PARSE_PEDANTIC;
15061
 
    } else
15062
 
        ctxt->pedantic = 0;
15063
 
    if (options & XML_PARSE_NOBLANKS) {
15064
 
        ctxt->keepBlanks = 0;
15065
 
        ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
15066
 
        options -= XML_PARSE_NOBLANKS;
15067
 
        ctxt->options |= XML_PARSE_NOBLANKS;
15068
 
    } else
15069
 
        ctxt->keepBlanks = 1;
15070
 
    if (options & XML_PARSE_DTDVALID) {
15071
 
        ctxt->validate = 1;
15072
 
        if (options & XML_PARSE_NOWARNING)
15073
 
            ctxt->vctxt.warning = NULL;
15074
 
        if (options & XML_PARSE_NOERROR)
15075
 
            ctxt->vctxt.error = NULL;
15076
 
        options -= XML_PARSE_DTDVALID;
15077
 
        ctxt->options |= XML_PARSE_DTDVALID;
15078
 
    } else
15079
 
        ctxt->validate = 0;
15080
 
    if (options & XML_PARSE_NOWARNING) {
15081
 
        ctxt->sax->warning = NULL;
15082
 
        options -= XML_PARSE_NOWARNING;
15083
 
    }
15084
 
    if (options & XML_PARSE_NOERROR) {
15085
 
        ctxt->sax->error = NULL;
15086
 
        ctxt->sax->fatalError = NULL;
15087
 
        options -= XML_PARSE_NOERROR;
15088
 
    }
15089
 
#ifdef LIBXML_SAX1_ENABLED
15090
 
    if (options & XML_PARSE_SAX1) {
15091
 
        ctxt->sax->startElement = xmlSAX2StartElement;
15092
 
        ctxt->sax->endElement = xmlSAX2EndElement;
15093
 
        ctxt->sax->startElementNs = NULL;
15094
 
        ctxt->sax->endElementNs = NULL;
15095
 
        ctxt->sax->initialized = 1;
15096
 
        options -= XML_PARSE_SAX1;
15097
 
        ctxt->options |= XML_PARSE_SAX1;
15098
 
    }
15099
 
#endif /* LIBXML_SAX1_ENABLED */
15100
 
    if (options & XML_PARSE_NODICT) {
15101
 
        ctxt->dictNames = 0;
15102
 
        options -= XML_PARSE_NODICT;
15103
 
        ctxt->options |= XML_PARSE_NODICT;
15104
 
    } else {
15105
 
        ctxt->dictNames = 1;
15106
 
    }
15107
 
    if (options & XML_PARSE_NOCDATA) {
15108
 
        ctxt->sax->cdataBlock = NULL;
15109
 
        options -= XML_PARSE_NOCDATA;
15110
 
        ctxt->options |= XML_PARSE_NOCDATA;
15111
 
    }
15112
 
    if (options & XML_PARSE_NSCLEAN) {
15113
 
        ctxt->options |= XML_PARSE_NSCLEAN;
15114
 
        options -= XML_PARSE_NSCLEAN;
15115
 
    }
15116
 
    if (options & XML_PARSE_NONET) {
15117
 
        ctxt->options |= XML_PARSE_NONET;
15118
 
        options -= XML_PARSE_NONET;
15119
 
    }
15120
 
    if (options & XML_PARSE_COMPACT) {
15121
 
        ctxt->options |= XML_PARSE_COMPACT;
15122
 
        options -= XML_PARSE_COMPACT;
15123
 
    }
15124
 
    if (options & XML_PARSE_OLD10) {
15125
 
        ctxt->options |= XML_PARSE_OLD10;
15126
 
        options -= XML_PARSE_OLD10;
15127
 
    }
15128
 
    if (options & XML_PARSE_NOBASEFIX) {
15129
 
        ctxt->options |= XML_PARSE_NOBASEFIX;
15130
 
        options -= XML_PARSE_NOBASEFIX;
15131
 
    }
15132
 
    if (options & XML_PARSE_HUGE) {
15133
 
        ctxt->options |= XML_PARSE_HUGE;
15134
 
        options -= XML_PARSE_HUGE;
15135
 
        if (ctxt->dict != NULL)
15136
 
            xmlDictSetLimit(ctxt->dict, 0);
15137
 
    }
15138
 
    if (options & XML_PARSE_OLDSAX) {
15139
 
        ctxt->options |= XML_PARSE_OLDSAX;
15140
 
        options -= XML_PARSE_OLDSAX;
15141
 
    }
15142
 
    if (options & XML_PARSE_IGNORE_ENC) {
15143
 
        ctxt->options |= XML_PARSE_IGNORE_ENC;
15144
 
        options -= XML_PARSE_IGNORE_ENC;
15145
 
    }
15146
 
    if (options & XML_PARSE_BIG_LINES) {
15147
 
        ctxt->options |= XML_PARSE_BIG_LINES;
15148
 
        options -= XML_PARSE_BIG_LINES;
15149
 
    }
15150
 
    ctxt->linenumbers = 1;
15151
 
    return (options);
15152
 
}
15153
 
 
15154
 
/**
15155
 
 * xmlCtxtUseOptions:
15156
 
 * @ctxt: an XML parser context
15157
 
 * @options:  a combination of xmlParserOption
15158
 
 *
15159
 
 * Applies the options to the parser context
15160
 
 *
15161
 
 * Returns 0 in case of success, the set of unknown or unimplemented options
15162
 
 *         in case of error.
15163
 
 */
15164
 
int
15165
 
xmlCtxtUseOptions(xmlParserCtxtPtr ctxt, int options)
15166
 
{
15167
 
   return(xmlCtxtUseOptionsInternal(ctxt, options, NULL));
15168
 
}
15169
 
 
15170
 
/**
15171
 
 * xmlDoRead:
15172
 
 * @ctxt:  an XML parser context
15173
 
 * @URL:  the base URL to use for the document
15174
 
 * @encoding:  the document encoding, or NULL
15175
 
 * @options:  a combination of xmlParserOption
15176
 
 * @reuse:  keep the context for reuse
15177
 
 *
15178
 
 * Common front-end for the xmlRead functions
15179
 
 *
15180
 
 * Returns the resulting document tree or NULL
15181
 
 */
15182
 
static xmlDocPtr
15183
 
xmlDoRead(xmlParserCtxtPtr ctxt, const char *URL, const char *encoding,
15184
 
          int options, int reuse)
15185
 
{
15186
 
    xmlDocPtr ret;
15187
 
 
15188
 
    xmlCtxtUseOptionsInternal(ctxt, options, encoding);
15189
 
    if (encoding != NULL) {
15190
 
        xmlCharEncodingHandlerPtr hdlr;
15191
 
 
15192
 
        hdlr = xmlFindCharEncodingHandler(encoding);
15193
 
        if (hdlr != NULL)
15194
 
            xmlSwitchToEncoding(ctxt, hdlr);
15195
 
    }
15196
 
    if ((URL != NULL) && (ctxt->input != NULL) &&
15197
 
        (ctxt->input->filename == NULL))
15198
 
        ctxt->input->filename = (char *) xmlStrdup((const xmlChar *) URL);
15199
 
    xmlParseDocument(ctxt);
15200
 
    if ((ctxt->wellFormed) || ctxt->recovery)
15201
 
        ret = ctxt->myDoc;
15202
 
    else {
15203
 
        ret = NULL;
15204
 
        if (ctxt->myDoc != NULL) {
15205
 
            xmlFreeDoc(ctxt->myDoc);
15206
 
        }
15207
 
    }
15208
 
    ctxt->myDoc = NULL;
15209
 
    if (!reuse) {
15210
 
        xmlFreeParserCtxt(ctxt);
15211
 
    }
15212
 
 
15213
 
    return (ret);
15214
 
}
15215
 
 
15216
 
/**
15217
 
 * xmlReadDoc:
15218
 
 * @cur:  a pointer to a zero terminated string
15219
 
 * @URL:  the base URL to use for the document
15220
 
 * @encoding:  the document encoding, or NULL
15221
 
 * @options:  a combination of xmlParserOption
15222
 
 *
15223
 
 * parse an XML in-memory document and build a tree.
15224
 
 *
15225
 
 * Returns the resulting document tree
15226
 
 */
15227
 
xmlDocPtr
15228
 
xmlReadDoc(const xmlChar * cur, const char *URL, const char *encoding, int options)
15229
 
{
15230
 
    xmlParserCtxtPtr ctxt;
15231
 
 
15232
 
    if (cur == NULL)
15233
 
        return (NULL);
15234
 
 
15235
 
    ctxt = xmlCreateDocParserCtxt(cur);
15236
 
    if (ctxt == NULL)
15237
 
        return (NULL);
15238
 
    return (xmlDoRead(ctxt, URL, encoding, options, 0));
15239
 
}
15240
 
 
15241
 
/**
15242
 
 * xmlReadFile:
15243
 
 * @filename:  a file or URL
15244
 
 * @encoding:  the document encoding, or NULL
15245
 
 * @options:  a combination of xmlParserOption
15246
 
 *
15247
 
 * parse an XML file from the filesystem or the network.
15248
 
 *
15249
 
 * Returns the resulting document tree
15250
 
 */
15251
 
xmlDocPtr
15252
 
xmlReadFile(const char *filename, const char *encoding, int options)
15253
 
{
15254
 
    xmlParserCtxtPtr ctxt;
15255
 
 
15256
 
    ctxt = xmlCreateURLParserCtxt(filename, options);
15257
 
    if (ctxt == NULL)
15258
 
        return (NULL);
15259
 
    return (xmlDoRead(ctxt, NULL, encoding, options, 0));
15260
 
}
15261
 
 
15262
 
/**
15263
 
 * xmlReadMemory:
15264
 
 * @buffer:  a pointer to a char array
15265
 
 * @size:  the size of the array
15266
 
 * @URL:  the base URL to use for the document
15267
 
 * @encoding:  the document encoding, or NULL
15268
 
 * @options:  a combination of xmlParserOption
15269
 
 *
15270
 
 * parse an XML in-memory document and build a tree.
15271
 
 *
15272
 
 * Returns the resulting document tree
15273
 
 */
15274
 
xmlDocPtr
15275
 
xmlReadMemory(const char *buffer, int size, const char *URL, const char *encoding, int options)
15276
 
{
15277
 
    xmlParserCtxtPtr ctxt;
15278
 
 
15279
 
    ctxt = xmlCreateMemoryParserCtxt(buffer, size);
15280
 
    if (ctxt == NULL)
15281
 
        return (NULL);
15282
 
    return (xmlDoRead(ctxt, URL, encoding, options, 0));
15283
 
}
15284
 
 
15285
 
/**
15286
 
 * xmlReadFd:
15287
 
 * @fd:  an open file descriptor
15288
 
 * @URL:  the base URL to use for the document
15289
 
 * @encoding:  the document encoding, or NULL
15290
 
 * @options:  a combination of xmlParserOption
15291
 
 *
15292
 
 * parse an XML from a file descriptor and build a tree.
15293
 
 * NOTE that the file descriptor will not be closed when the
15294
 
 *      reader is closed or reset.
15295
 
 *
15296
 
 * Returns the resulting document tree
15297
 
 */
15298
 
xmlDocPtr
15299
 
xmlReadFd(int fd, const char *URL, const char *encoding, int options)
15300
 
{
15301
 
    xmlParserCtxtPtr ctxt;
15302
 
    xmlParserInputBufferPtr input;
15303
 
    xmlParserInputPtr stream;
15304
 
 
15305
 
    if (fd < 0)
15306
 
        return (NULL);
15307
 
 
15308
 
    input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
15309
 
    if (input == NULL)
15310
 
        return (NULL);
15311
 
    input->closecallback = NULL;
15312
 
    ctxt = xmlNewParserCtxt();
15313
 
    if (ctxt == NULL) {
15314
 
        xmlFreeParserInputBuffer(input);
15315
 
        return (NULL);
15316
 
    }
15317
 
    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
15318
 
    if (stream == NULL) {
15319
 
        xmlFreeParserInputBuffer(input);
15320
 
        xmlFreeParserCtxt(ctxt);
15321
 
        return (NULL);
15322
 
    }
15323
 
    inputPush(ctxt, stream);
15324
 
    return (xmlDoRead(ctxt, URL, encoding, options, 0));
15325
 
}
15326
 
 
15327
 
/**
15328
 
 * xmlReadIO:
15329
 
 * @ioread:  an I/O read function
15330
 
 * @ioclose:  an I/O close function
15331
 
 * @ioctx:  an I/O handler
15332
 
 * @URL:  the base URL to use for the document
15333
 
 * @encoding:  the document encoding, or NULL
15334
 
 * @options:  a combination of xmlParserOption
15335
 
 *
15336
 
 * parse an XML document from I/O functions and source and build a tree.
15337
 
 *
15338
 
 * Returns the resulting document tree
15339
 
 */
15340
 
xmlDocPtr
15341
 
xmlReadIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
15342
 
          void *ioctx, const char *URL, const char *encoding, int options)
15343
 
{
15344
 
    xmlParserCtxtPtr ctxt;
15345
 
    xmlParserInputBufferPtr input;
15346
 
    xmlParserInputPtr stream;
15347
 
 
15348
 
    if (ioread == NULL)
15349
 
        return (NULL);
15350
 
 
15351
 
    input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
15352
 
                                         XML_CHAR_ENCODING_NONE);
15353
 
    if (input == NULL) {
15354
 
        if (ioclose != NULL)
15355
 
            ioclose(ioctx);
15356
 
        return (NULL);
15357
 
    }
15358
 
    ctxt = xmlNewParserCtxt();
15359
 
    if (ctxt == NULL) {
15360
 
        xmlFreeParserInputBuffer(input);
15361
 
        return (NULL);
15362
 
    }
15363
 
    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
15364
 
    if (stream == NULL) {
15365
 
        xmlFreeParserInputBuffer(input);
15366
 
        xmlFreeParserCtxt(ctxt);
15367
 
        return (NULL);
15368
 
    }
15369
 
    inputPush(ctxt, stream);
15370
 
    return (xmlDoRead(ctxt, URL, encoding, options, 0));
15371
 
}
15372
 
 
15373
 
/**
15374
 
 * xmlCtxtReadDoc:
15375
 
 * @ctxt:  an XML parser context
15376
 
 * @cur:  a pointer to a zero terminated string
15377
 
 * @URL:  the base URL to use for the document
15378
 
 * @encoding:  the document encoding, or NULL
15379
 
 * @options:  a combination of xmlParserOption
15380
 
 *
15381
 
 * parse an XML in-memory document and build a tree.
15382
 
 * This reuses the existing @ctxt parser context
15383
 
 *
15384
 
 * Returns the resulting document tree
15385
 
 */
15386
 
xmlDocPtr
15387
 
xmlCtxtReadDoc(xmlParserCtxtPtr ctxt, const xmlChar * cur,
15388
 
               const char *URL, const char *encoding, int options)
15389
 
{
15390
 
    xmlParserInputPtr stream;
15391
 
 
15392
 
    if (cur == NULL)
15393
 
        return (NULL);
15394
 
    if (ctxt == NULL)
15395
 
        return (NULL);
15396
 
 
15397
 
    xmlCtxtReset(ctxt);
15398
 
 
15399
 
    stream = xmlNewStringInputStream(ctxt, cur);
15400
 
    if (stream == NULL) {
15401
 
        return (NULL);
15402
 
    }
15403
 
    inputPush(ctxt, stream);
15404
 
    return (xmlDoRead(ctxt, URL, encoding, options, 1));
15405
 
}
15406
 
 
15407
 
/**
15408
 
 * xmlCtxtReadFile:
15409
 
 * @ctxt:  an XML parser context
15410
 
 * @filename:  a file or URL
15411
 
 * @encoding:  the document encoding, or NULL
15412
 
 * @options:  a combination of xmlParserOption
15413
 
 *
15414
 
 * parse an XML file from the filesystem or the network.
15415
 
 * This reuses the existing @ctxt parser context
15416
 
 *
15417
 
 * Returns the resulting document tree
15418
 
 */
15419
 
xmlDocPtr
15420
 
xmlCtxtReadFile(xmlParserCtxtPtr ctxt, const char *filename,
15421
 
                const char *encoding, int options)
15422
 
{
15423
 
    xmlParserInputPtr stream;
15424
 
 
15425
 
    if (filename == NULL)
15426
 
        return (NULL);
15427
 
    if (ctxt == NULL)
15428
 
        return (NULL);
15429
 
 
15430
 
    xmlCtxtReset(ctxt);
15431
 
 
15432
 
    stream = xmlLoadExternalEntity(filename, NULL, ctxt);
15433
 
    if (stream == NULL) {
15434
 
        return (NULL);
15435
 
    }
15436
 
    inputPush(ctxt, stream);
15437
 
    return (xmlDoRead(ctxt, NULL, encoding, options, 1));
15438
 
}
15439
 
 
15440
 
/**
15441
 
 * xmlCtxtReadMemory:
15442
 
 * @ctxt:  an XML parser context
15443
 
 * @buffer:  a pointer to a char array
15444
 
 * @size:  the size of the array
15445
 
 * @URL:  the base URL to use for the document
15446
 
 * @encoding:  the document encoding, or NULL
15447
 
 * @options:  a combination of xmlParserOption
15448
 
 *
15449
 
 * parse an XML in-memory document and build a tree.
15450
 
 * This reuses the existing @ctxt parser context
15451
 
 *
15452
 
 * Returns the resulting document tree
15453
 
 */
15454
 
xmlDocPtr
15455
 
xmlCtxtReadMemory(xmlParserCtxtPtr ctxt, const char *buffer, int size,
15456
 
                  const char *URL, const char *encoding, int options)
15457
 
{
15458
 
    xmlParserInputBufferPtr input;
15459
 
    xmlParserInputPtr stream;
15460
 
 
15461
 
    if (ctxt == NULL)
15462
 
        return (NULL);
15463
 
    if (buffer == NULL)
15464
 
        return (NULL);
15465
 
 
15466
 
    xmlCtxtReset(ctxt);
15467
 
 
15468
 
    input = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
15469
 
    if (input == NULL) {
15470
 
        return(NULL);
15471
 
    }
15472
 
 
15473
 
    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
15474
 
    if (stream == NULL) {
15475
 
        xmlFreeParserInputBuffer(input);
15476
 
        return(NULL);
15477
 
    }
15478
 
 
15479
 
    inputPush(ctxt, stream);
15480
 
    return (xmlDoRead(ctxt, URL, encoding, options, 1));
15481
 
}
15482
 
 
15483
 
/**
15484
 
 * xmlCtxtReadFd:
15485
 
 * @ctxt:  an XML parser context
15486
 
 * @fd:  an open file descriptor
15487
 
 * @URL:  the base URL to use for the document
15488
 
 * @encoding:  the document encoding, or NULL
15489
 
 * @options:  a combination of xmlParserOption
15490
 
 *
15491
 
 * parse an XML from a file descriptor and build a tree.
15492
 
 * This reuses the existing @ctxt parser context
15493
 
 * NOTE that the file descriptor will not be closed when the
15494
 
 *      reader is closed or reset.
15495
 
 *
15496
 
 * Returns the resulting document tree
15497
 
 */
15498
 
xmlDocPtr
15499
 
xmlCtxtReadFd(xmlParserCtxtPtr ctxt, int fd,
15500
 
              const char *URL, const char *encoding, int options)
15501
 
{
15502
 
    xmlParserInputBufferPtr input;
15503
 
    xmlParserInputPtr stream;
15504
 
 
15505
 
    if (fd < 0)
15506
 
        return (NULL);
15507
 
    if (ctxt == NULL)
15508
 
        return (NULL);
15509
 
 
15510
 
    xmlCtxtReset(ctxt);
15511
 
 
15512
 
 
15513
 
    input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
15514
 
    if (input == NULL)
15515
 
        return (NULL);
15516
 
    input->closecallback = NULL;
15517
 
    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
15518
 
    if (stream == NULL) {
15519
 
        xmlFreeParserInputBuffer(input);
15520
 
        return (NULL);
15521
 
    }
15522
 
    inputPush(ctxt, stream);
15523
 
    return (xmlDoRead(ctxt, URL, encoding, options, 1));
15524
 
}
15525
 
 
15526
 
/**
15527
 
 * xmlCtxtReadIO:
15528
 
 * @ctxt:  an XML parser context
15529
 
 * @ioread:  an I/O read function
15530
 
 * @ioclose:  an I/O close function
15531
 
 * @ioctx:  an I/O handler
15532
 
 * @URL:  the base URL to use for the document
15533
 
 * @encoding:  the document encoding, or NULL
15534
 
 * @options:  a combination of xmlParserOption
15535
 
 *
15536
 
 * parse an XML document from I/O functions and source and build a tree.
15537
 
 * This reuses the existing @ctxt parser context
15538
 
 *
15539
 
 * Returns the resulting document tree
15540
 
 */
15541
 
xmlDocPtr
15542
 
xmlCtxtReadIO(xmlParserCtxtPtr ctxt, xmlInputReadCallback ioread,
15543
 
              xmlInputCloseCallback ioclose, void *ioctx,
15544
 
              const char *URL,
15545
 
              const char *encoding, int options)
15546
 
{
15547
 
    xmlParserInputBufferPtr input;
15548
 
    xmlParserInputPtr stream;
15549
 
 
15550
 
    if (ioread == NULL)
15551
 
        return (NULL);
15552
 
    if (ctxt == NULL)
15553
 
        return (NULL);
15554
 
 
15555
 
    xmlCtxtReset(ctxt);
15556
 
 
15557
 
    input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
15558
 
                                         XML_CHAR_ENCODING_NONE);
15559
 
    if (input == NULL) {
15560
 
        if (ioclose != NULL)
15561
 
            ioclose(ioctx);
15562
 
        return (NULL);
15563
 
    }
15564
 
    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
15565
 
    if (stream == NULL) {
15566
 
        xmlFreeParserInputBuffer(input);
15567
 
        return (NULL);
15568
 
    }
15569
 
    inputPush(ctxt, stream);
15570
 
    return (xmlDoRead(ctxt, URL, encoding, options, 1));
15571
 
}
15572
 
 
15573
 
#define bottom_parser
15574
 
#include "elfgcchack.h"