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

« back to all changes in this revision

Viewing changes to .pc/0002-Fix-an-error-in-xmlCleanupParser.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
 
                     * handle the extra spaces added before and after
2599
 
                     * c.f. http://www.w3.org/TR/REC-xml#as-PE
2600
 
                     * this is done independently.
2601
 
                     */
2602
 
                    input = xmlNewEntityInputStream(ctxt, entity);
2603
 
                    if (xmlPushInput(ctxt, input) < 0)
2604
 
                        return;
2605
 
 
2606
 
                    /*
2607
 
                     * Get the 4 first bytes and decode the charset
2608
 
                     * if enc != XML_CHAR_ENCODING_NONE
2609
 
                     * plug some encoding conversion routines.
2610
 
                     * Note that, since we may have some non-UTF8
2611
 
                     * encoding (like UTF16, bug 135229), the 'length'
2612
 
                     * is not known, but we can calculate based upon
2613
 
                     * the amount of data in the buffer.
2614
 
                     */
2615
 
                    GROW
2616
 
                    if (ctxt->instate == XML_PARSER_EOF)
2617
 
                        return;
2618
 
                    if ((ctxt->input->end - ctxt->input->cur)>=4) {
2619
 
                        start[0] = RAW;
2620
 
                        start[1] = NXT(1);
2621
 
                        start[2] = NXT(2);
2622
 
                        start[3] = NXT(3);
2623
 
                        enc = xmlDetectCharEncoding(start, 4);
2624
 
                        if (enc != XML_CHAR_ENCODING_NONE) {
2625
 
                            xmlSwitchEncoding(ctxt, enc);
2626
 
                        }
2627
 
                    }
2628
 
 
2629
 
                    if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
2630
 
                        (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l' )) &&
2631
 
                        (IS_BLANK_CH(NXT(5)))) {
2632
 
                        xmlParseTextDecl(ctxt);
2633
 
                    }
2634
 
                } else {
2635
 
                    xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
2636
 
                             "PEReference: %s is not a parameter entity\n",
2637
 
                                      name);
2638
 
                }
2639
 
            }
2640
 
        } else {
2641
 
            xmlFatalErr(ctxt, XML_ERR_PEREF_SEMICOL_MISSING, NULL);
2642
 
        }
2643
 
    }
2644
 
}
2645
 
 
2646
 
/*
2647
 
 * Macro used to grow the current buffer.
2648
 
 * buffer##_size is expected to be a size_t
2649
 
 * mem_error: is expected to handle memory allocation failures
2650
 
 */
2651
 
#define growBuffer(buffer, n) {                                         \
2652
 
    xmlChar *tmp;                                                       \
2653
 
    size_t new_size = buffer##_size * 2 + n;                            \
2654
 
    if (new_size < buffer##_size) goto mem_error;                       \
2655
 
    tmp = (xmlChar *) xmlRealloc(buffer, new_size);                     \
2656
 
    if (tmp == NULL) goto mem_error;                                    \
2657
 
    buffer = tmp;                                                       \
2658
 
    buffer##_size = new_size;                                           \
2659
 
}
2660
 
 
2661
 
/**
2662
 
 * xmlStringLenDecodeEntities:
2663
 
 * @ctxt:  the parser context
2664
 
 * @str:  the input string
2665
 
 * @len: the string length
2666
 
 * @what:  combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
2667
 
 * @end:  an end marker xmlChar, 0 if none
2668
 
 * @end2:  an end marker xmlChar, 0 if none
2669
 
 * @end3:  an end marker xmlChar, 0 if none
2670
 
 *
2671
 
 * Takes a entity string content and process to do the adequate substitutions.
2672
 
 *
2673
 
 * [67] Reference ::= EntityRef | CharRef
2674
 
 *
2675
 
 * [69] PEReference ::= '%' Name ';'
2676
 
 *
2677
 
 * Returns A newly allocated string with the substitution done. The caller
2678
 
 *      must deallocate it !
2679
 
 */
2680
 
xmlChar *
2681
 
xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
2682
 
                      int what, xmlChar end, xmlChar  end2, xmlChar end3) {
2683
 
    xmlChar *buffer = NULL;
2684
 
    size_t buffer_size = 0;
2685
 
    size_t nbchars = 0;
2686
 
 
2687
 
    xmlChar *current = NULL;
2688
 
    xmlChar *rep = NULL;
2689
 
    const xmlChar *last;
2690
 
    xmlEntityPtr ent;
2691
 
    int c,l;
2692
 
 
2693
 
    if ((ctxt == NULL) || (str == NULL) || (len < 0))
2694
 
        return(NULL);
2695
 
    last = str + len;
2696
 
 
2697
 
    if (((ctxt->depth > 40) &&
2698
 
         ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
2699
 
        (ctxt->depth > 1024)) {
2700
 
        xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
2701
 
        return(NULL);
2702
 
    }
2703
 
 
2704
 
    /*
2705
 
     * allocate a translation buffer.
2706
 
     */
2707
 
    buffer_size = XML_PARSER_BIG_BUFFER_SIZE;
2708
 
    buffer = (xmlChar *) xmlMallocAtomic(buffer_size);
2709
 
    if (buffer == NULL) goto mem_error;
2710
 
 
2711
 
    /*
2712
 
     * OK loop until we reach one of the ending char or a size limit.
2713
 
     * we are operating on already parsed values.
2714
 
     */
2715
 
    if (str < last)
2716
 
        c = CUR_SCHAR(str, l);
2717
 
    else
2718
 
        c = 0;
2719
 
    while ((c != 0) && (c != end) && /* non input consuming loop */
2720
 
           (c != end2) && (c != end3)) {
2721
 
 
2722
 
        if (c == 0) break;
2723
 
        if ((c == '&') && (str[1] == '#')) {
2724
 
            int val = xmlParseStringCharRef(ctxt, &str);
2725
 
            if (val != 0) {
2726
 
                COPY_BUF(0,buffer,nbchars,val);
2727
 
            }
2728
 
            if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
2729
 
                growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2730
 
            }
2731
 
        } else if ((c == '&') && (what & XML_SUBSTITUTE_REF)) {
2732
 
            if (xmlParserDebugEntities)
2733
 
                xmlGenericError(xmlGenericErrorContext,
2734
 
                        "String decoding Entity Reference: %.30s\n",
2735
 
                        str);
2736
 
            ent = xmlParseStringEntityRef(ctxt, &str);
2737
 
            if ((ctxt->lastError.code == XML_ERR_ENTITY_LOOP) ||
2738
 
                (ctxt->lastError.code == XML_ERR_INTERNAL_ERROR))
2739
 
                goto int_error;
2740
 
            if (ent != NULL)
2741
 
                ctxt->nbentities += ent->checked / 2;
2742
 
            if ((ent != NULL) &&
2743
 
                (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
2744
 
                if (ent->content != NULL) {
2745
 
                    COPY_BUF(0,buffer,nbchars,ent->content[0]);
2746
 
                    if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
2747
 
                        growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2748
 
                    }
2749
 
                } else {
2750
 
                    xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
2751
 
                            "predefined entity has no content\n");
2752
 
                }
2753
 
            } else if ((ent != NULL) && (ent->content != NULL)) {
2754
 
                ctxt->depth++;
2755
 
                rep = xmlStringDecodeEntities(ctxt, ent->content, what,
2756
 
                                              0, 0, 0);
2757
 
                ctxt->depth--;
2758
 
 
2759
 
                if (rep != NULL) {
2760
 
                    current = rep;
2761
 
                    while (*current != 0) { /* non input consuming loop */
2762
 
                        buffer[nbchars++] = *current++;
2763
 
                        if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
2764
 
                            if (xmlParserEntityCheck(ctxt, nbchars, ent, 0))
2765
 
                                goto int_error;
2766
 
                            growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2767
 
                        }
2768
 
                    }
2769
 
                    xmlFree(rep);
2770
 
                    rep = NULL;
2771
 
                }
2772
 
            } else if (ent != NULL) {
2773
 
                int i = xmlStrlen(ent->name);
2774
 
                const xmlChar *cur = ent->name;
2775
 
 
2776
 
                buffer[nbchars++] = '&';
2777
 
                if (nbchars + i + XML_PARSER_BUFFER_SIZE > buffer_size) {
2778
 
                    growBuffer(buffer, i + XML_PARSER_BUFFER_SIZE);
2779
 
                }
2780
 
                for (;i > 0;i--)
2781
 
                    buffer[nbchars++] = *cur++;
2782
 
                buffer[nbchars++] = ';';
2783
 
            }
2784
 
        } else if (c == '%' && (what & XML_SUBSTITUTE_PEREF)) {
2785
 
            if (xmlParserDebugEntities)
2786
 
                xmlGenericError(xmlGenericErrorContext,
2787
 
                        "String decoding PE Reference: %.30s\n", str);
2788
 
            ent = xmlParseStringPEReference(ctxt, &str);
2789
 
            if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
2790
 
                goto int_error;
2791
 
            if (ent != NULL)
2792
 
                ctxt->nbentities += ent->checked / 2;
2793
 
            if (ent != NULL) {
2794
 
                if (ent->content == NULL) {
2795
 
                    xmlLoadEntityContent(ctxt, ent);
2796
 
                }
2797
 
                ctxt->depth++;
2798
 
                rep = xmlStringDecodeEntities(ctxt, ent->content, what,
2799
 
                                              0, 0, 0);
2800
 
                ctxt->depth--;
2801
 
                if (rep != NULL) {
2802
 
                    current = rep;
2803
 
                    while (*current != 0) { /* non input consuming loop */
2804
 
                        buffer[nbchars++] = *current++;
2805
 
                        if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
2806
 
                            if (xmlParserEntityCheck(ctxt, nbchars, ent, 0))
2807
 
                                goto int_error;
2808
 
                            growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2809
 
                        }
2810
 
                    }
2811
 
                    xmlFree(rep);
2812
 
                    rep = NULL;
2813
 
                }
2814
 
            }
2815
 
        } else {
2816
 
            COPY_BUF(l,buffer,nbchars,c);
2817
 
            str += l;
2818
 
            if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
2819
 
                growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
2820
 
            }
2821
 
        }
2822
 
        if (str < last)
2823
 
            c = CUR_SCHAR(str, l);
2824
 
        else
2825
 
            c = 0;
2826
 
    }
2827
 
    buffer[nbchars] = 0;
2828
 
    return(buffer);
2829
 
 
2830
 
mem_error:
2831
 
    xmlErrMemory(ctxt, NULL);
2832
 
int_error:
2833
 
    if (rep != NULL)
2834
 
        xmlFree(rep);
2835
 
    if (buffer != NULL)
2836
 
        xmlFree(buffer);
2837
 
    return(NULL);
2838
 
}
2839
 
 
2840
 
/**
2841
 
 * xmlStringDecodeEntities:
2842
 
 * @ctxt:  the parser context
2843
 
 * @str:  the input string
2844
 
 * @what:  combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
2845
 
 * @end:  an end marker xmlChar, 0 if none
2846
 
 * @end2:  an end marker xmlChar, 0 if none
2847
 
 * @end3:  an end marker xmlChar, 0 if none
2848
 
 *
2849
 
 * Takes a entity string content and process to do the adequate substitutions.
2850
 
 *
2851
 
 * [67] Reference ::= EntityRef | CharRef
2852
 
 *
2853
 
 * [69] PEReference ::= '%' Name ';'
2854
 
 *
2855
 
 * Returns A newly allocated string with the substitution done. The caller
2856
 
 *      must deallocate it !
2857
 
 */
2858
 
xmlChar *
2859
 
xmlStringDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int what,
2860
 
                        xmlChar end, xmlChar  end2, xmlChar end3) {
2861
 
    if ((ctxt == NULL) || (str == NULL)) return(NULL);
2862
 
    return(xmlStringLenDecodeEntities(ctxt, str, xmlStrlen(str), what,
2863
 
           end, end2, end3));
2864
 
}
2865
 
 
2866
 
/************************************************************************
2867
 
 *                                                                      *
2868
 
 *              Commodity functions, cleanup needed ?                   *
2869
 
 *                                                                      *
2870
 
 ************************************************************************/
2871
 
 
2872
 
/**
2873
 
 * areBlanks:
2874
 
 * @ctxt:  an XML parser context
2875
 
 * @str:  a xmlChar *
2876
 
 * @len:  the size of @str
2877
 
 * @blank_chars: we know the chars are blanks
2878
 
 *
2879
 
 * Is this a sequence of blank chars that one can ignore ?
2880
 
 *
2881
 
 * Returns 1 if ignorable 0 otherwise.
2882
 
 */
2883
 
 
2884
 
static int areBlanks(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
2885
 
                     int blank_chars) {
2886
 
    int i, ret;
2887
 
    xmlNodePtr lastChild;
2888
 
 
2889
 
    /*
2890
 
     * Don't spend time trying to differentiate them, the same callback is
2891
 
     * used !
2892
 
     */
2893
 
    if (ctxt->sax->ignorableWhitespace == ctxt->sax->characters)
2894
 
        return(0);
2895
 
 
2896
 
    /*
2897
 
     * Check for xml:space value.
2898
 
     */
2899
 
    if ((ctxt->space == NULL) || (*(ctxt->space) == 1) ||
2900
 
        (*(ctxt->space) == -2))
2901
 
        return(0);
2902
 
 
2903
 
    /*
2904
 
     * Check that the string is made of blanks
2905
 
     */
2906
 
    if (blank_chars == 0) {
2907
 
        for (i = 0;i < len;i++)
2908
 
            if (!(IS_BLANK_CH(str[i]))) return(0);
2909
 
    }
2910
 
 
2911
 
    /*
2912
 
     * Look if the element is mixed content in the DTD if available
2913
 
     */
2914
 
    if (ctxt->node == NULL) return(0);
2915
 
    if (ctxt->myDoc != NULL) {
2916
 
        ret = xmlIsMixedElement(ctxt->myDoc, ctxt->node->name);
2917
 
        if (ret == 0) return(1);
2918
 
        if (ret == 1) return(0);
2919
 
    }
2920
 
 
2921
 
    /*
2922
 
     * Otherwise, heuristic :-\
2923
 
     */
2924
 
    if ((RAW != '<') && (RAW != 0xD)) return(0);
2925
 
    if ((ctxt->node->children == NULL) &&
2926
 
        (RAW == '<') && (NXT(1) == '/')) return(0);
2927
 
 
2928
 
    lastChild = xmlGetLastChild(ctxt->node);
2929
 
    if (lastChild == NULL) {
2930
 
        if ((ctxt->node->type != XML_ELEMENT_NODE) &&
2931
 
            (ctxt->node->content != NULL)) return(0);
2932
 
    } else if (xmlNodeIsText(lastChild))
2933
 
        return(0);
2934
 
    else if ((ctxt->node->children != NULL) &&
2935
 
             (xmlNodeIsText(ctxt->node->children)))
2936
 
        return(0);
2937
 
    return(1);
2938
 
}
2939
 
 
2940
 
/************************************************************************
2941
 
 *                                                                      *
2942
 
 *              Extra stuff for namespace support                       *
2943
 
 *      Relates to http://www.w3.org/TR/WD-xml-names                    *
2944
 
 *                                                                      *
2945
 
 ************************************************************************/
2946
 
 
2947
 
/**
2948
 
 * xmlSplitQName:
2949
 
 * @ctxt:  an XML parser context
2950
 
 * @name:  an XML parser context
2951
 
 * @prefix:  a xmlChar **
2952
 
 *
2953
 
 * parse an UTF8 encoded XML qualified name string
2954
 
 *
2955
 
 * [NS 5] QName ::= (Prefix ':')? LocalPart
2956
 
 *
2957
 
 * [NS 6] Prefix ::= NCName
2958
 
 *
2959
 
 * [NS 7] LocalPart ::= NCName
2960
 
 *
2961
 
 * Returns the local part, and prefix is updated
2962
 
 *   to get the Prefix if any.
2963
 
 */
2964
 
 
2965
 
xmlChar *
2966
 
xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) {
2967
 
    xmlChar buf[XML_MAX_NAMELEN + 5];
2968
 
    xmlChar *buffer = NULL;
2969
 
    int len = 0;
2970
 
    int max = XML_MAX_NAMELEN;
2971
 
    xmlChar *ret = NULL;
2972
 
    const xmlChar *cur = name;
2973
 
    int c;
2974
 
 
2975
 
    if (prefix == NULL) return(NULL);
2976
 
    *prefix = NULL;
2977
 
 
2978
 
    if (cur == NULL) return(NULL);
2979
 
 
2980
 
#ifndef XML_XML_NAMESPACE
2981
 
    /* xml: prefix is not really a namespace */
2982
 
    if ((cur[0] == 'x') && (cur[1] == 'm') &&
2983
 
        (cur[2] == 'l') && (cur[3] == ':'))
2984
 
        return(xmlStrdup(name));
2985
 
#endif
2986
 
 
2987
 
    /* nasty but well=formed */
2988
 
    if (cur[0] == ':')
2989
 
        return(xmlStrdup(name));
2990
 
 
2991
 
    c = *cur++;
2992
 
    while ((c != 0) && (c != ':') && (len < max)) { /* tested bigname.xml */
2993
 
        buf[len++] = c;
2994
 
        c = *cur++;
2995
 
    }
2996
 
    if (len >= max) {
2997
 
        /*
2998
 
         * Okay someone managed to make a huge name, so he's ready to pay
2999
 
         * for the processing speed.
3000
 
         */
3001
 
        max = len * 2;
3002
 
 
3003
 
        buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
3004
 
        if (buffer == NULL) {
3005
 
            xmlErrMemory(ctxt, NULL);
3006
 
            return(NULL);
3007
 
        }
3008
 
        memcpy(buffer, buf, len);
3009
 
        while ((c != 0) && (c != ':')) { /* tested bigname.xml */
3010
 
            if (len + 10 > max) {
3011
 
                xmlChar *tmp;
3012
 
 
3013
 
                max *= 2;
3014
 
                tmp = (xmlChar *) xmlRealloc(buffer,
3015
 
                                                max * sizeof(xmlChar));
3016
 
                if (tmp == NULL) {
3017
 
                    xmlFree(buffer);
3018
 
                    xmlErrMemory(ctxt, NULL);
3019
 
                    return(NULL);
3020
 
                }
3021
 
                buffer = tmp;
3022
 
            }
3023
 
            buffer[len++] = c;
3024
 
            c = *cur++;
3025
 
        }
3026
 
        buffer[len] = 0;
3027
 
    }
3028
 
 
3029
 
    if ((c == ':') && (*cur == 0)) {
3030
 
        if (buffer != NULL)
3031
 
            xmlFree(buffer);
3032
 
        *prefix = NULL;
3033
 
        return(xmlStrdup(name));
3034
 
    }
3035
 
 
3036
 
    if (buffer == NULL)
3037
 
        ret = xmlStrndup(buf, len);
3038
 
    else {
3039
 
        ret = buffer;
3040
 
        buffer = NULL;
3041
 
        max = XML_MAX_NAMELEN;
3042
 
    }
3043
 
 
3044
 
 
3045
 
    if (c == ':') {
3046
 
        c = *cur;
3047
 
        *prefix = ret;
3048
 
        if (c == 0) {
3049
 
            return(xmlStrndup(BAD_CAST "", 0));
3050
 
        }
3051
 
        len = 0;
3052
 
 
3053
 
        /*
3054
 
         * Check that the first character is proper to start
3055
 
         * a new name
3056
 
         */
3057
 
        if (!(((c >= 0x61) && (c <= 0x7A)) ||
3058
 
              ((c >= 0x41) && (c <= 0x5A)) ||
3059
 
              (c == '_') || (c == ':'))) {
3060
 
            int l;
3061
 
            int first = CUR_SCHAR(cur, l);
3062
 
 
3063
 
            if (!IS_LETTER(first) && (first != '_')) {
3064
 
                xmlFatalErrMsgStr(ctxt, XML_NS_ERR_QNAME,
3065
 
                            "Name %s is not XML Namespace compliant\n",
3066
 
                                  name);
3067
 
            }
3068
 
        }
3069
 
        cur++;
3070
 
 
3071
 
        while ((c != 0) && (len < max)) { /* tested bigname2.xml */
3072
 
            buf[len++] = c;
3073
 
            c = *cur++;
3074
 
        }
3075
 
        if (len >= max) {
3076
 
            /*
3077
 
             * Okay someone managed to make a huge name, so he's ready to pay
3078
 
             * for the processing speed.
3079
 
             */
3080
 
            max = len * 2;
3081
 
 
3082
 
            buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
3083
 
            if (buffer == NULL) {
3084
 
                xmlErrMemory(ctxt, NULL);
3085
 
                return(NULL);
3086
 
            }
3087
 
            memcpy(buffer, buf, len);
3088
 
            while (c != 0) { /* tested bigname2.xml */
3089
 
                if (len + 10 > max) {
3090
 
                    xmlChar *tmp;
3091
 
 
3092
 
                    max *= 2;
3093
 
                    tmp = (xmlChar *) xmlRealloc(buffer,
3094
 
                                                    max * sizeof(xmlChar));
3095
 
                    if (tmp == NULL) {
3096
 
                        xmlErrMemory(ctxt, NULL);
3097
 
                        xmlFree(buffer);
3098
 
                        return(NULL);
3099
 
                    }
3100
 
                    buffer = tmp;
3101
 
                }
3102
 
                buffer[len++] = c;
3103
 
                c = *cur++;
3104
 
            }
3105
 
            buffer[len] = 0;
3106
 
        }
3107
 
 
3108
 
        if (buffer == NULL)
3109
 
            ret = xmlStrndup(buf, len);
3110
 
        else {
3111
 
            ret = buffer;
3112
 
        }
3113
 
    }
3114
 
 
3115
 
    return(ret);
3116
 
}
3117
 
 
3118
 
/************************************************************************
3119
 
 *                                                                      *
3120
 
 *                      The parser itself                               *
3121
 
 *      Relates to http://www.w3.org/TR/REC-xml                         *
3122
 
 *                                                                      *
3123
 
 ************************************************************************/
3124
 
 
3125
 
/************************************************************************
3126
 
 *                                                                      *
3127
 
 *      Routines to parse Name, NCName and NmToken                      *
3128
 
 *                                                                      *
3129
 
 ************************************************************************/
3130
 
#ifdef DEBUG
3131
 
static unsigned long nbParseName = 0;
3132
 
static unsigned long nbParseNmToken = 0;
3133
 
static unsigned long nbParseNCName = 0;
3134
 
static unsigned long nbParseNCNameComplex = 0;
3135
 
static unsigned long nbParseNameComplex = 0;
3136
 
static unsigned long nbParseStringName = 0;
3137
 
#endif
3138
 
 
3139
 
/*
3140
 
 * The two following functions are related to the change of accepted
3141
 
 * characters for Name and NmToken in the Revision 5 of XML-1.0
3142
 
 * They correspond to the modified production [4] and the new production [4a]
3143
 
 * changes in that revision. Also note that the macros used for the
3144
 
 * productions Letter, Digit, CombiningChar and Extender are not needed
3145
 
 * anymore.
3146
 
 * We still keep compatibility to pre-revision5 parsing semantic if the
3147
 
 * new XML_PARSE_OLD10 option is given to the parser.
3148
 
 */
3149
 
static int
3150
 
xmlIsNameStartChar(xmlParserCtxtPtr ctxt, int c) {
3151
 
    if ((ctxt->options & XML_PARSE_OLD10) == 0) {
3152
 
        /*
3153
 
         * Use the new checks of production [4] [4a] amd [5] of the
3154
 
         * Update 5 of XML-1.0
3155
 
         */
3156
 
        if ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
3157
 
            (((c >= 'a') && (c <= 'z')) ||
3158
 
             ((c >= 'A') && (c <= 'Z')) ||
3159
 
             (c == '_') || (c == ':') ||
3160
 
             ((c >= 0xC0) && (c <= 0xD6)) ||
3161
 
             ((c >= 0xD8) && (c <= 0xF6)) ||
3162
 
             ((c >= 0xF8) && (c <= 0x2FF)) ||
3163
 
             ((c >= 0x370) && (c <= 0x37D)) ||
3164
 
             ((c >= 0x37F) && (c <= 0x1FFF)) ||
3165
 
             ((c >= 0x200C) && (c <= 0x200D)) ||
3166
 
             ((c >= 0x2070) && (c <= 0x218F)) ||
3167
 
             ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3168
 
             ((c >= 0x3001) && (c <= 0xD7FF)) ||
3169
 
             ((c >= 0xF900) && (c <= 0xFDCF)) ||
3170
 
             ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3171
 
             ((c >= 0x10000) && (c <= 0xEFFFF))))
3172
 
            return(1);
3173
 
    } else {
3174
 
        if (IS_LETTER(c) || (c == '_') || (c == ':'))
3175
 
            return(1);
3176
 
    }
3177
 
    return(0);
3178
 
}
3179
 
 
3180
 
static int
3181
 
xmlIsNameChar(xmlParserCtxtPtr ctxt, int c) {
3182
 
    if ((ctxt->options & XML_PARSE_OLD10) == 0) {
3183
 
        /*
3184
 
         * Use the new checks of production [4] [4a] amd [5] of the
3185
 
         * Update 5 of XML-1.0
3186
 
         */
3187
 
        if ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
3188
 
            (((c >= 'a') && (c <= 'z')) ||
3189
 
             ((c >= 'A') && (c <= 'Z')) ||
3190
 
             ((c >= '0') && (c <= '9')) || /* !start */
3191
 
             (c == '_') || (c == ':') ||
3192
 
             (c == '-') || (c == '.') || (c == 0xB7) || /* !start */
3193
 
             ((c >= 0xC0) && (c <= 0xD6)) ||
3194
 
             ((c >= 0xD8) && (c <= 0xF6)) ||
3195
 
             ((c >= 0xF8) && (c <= 0x2FF)) ||
3196
 
             ((c >= 0x300) && (c <= 0x36F)) || /* !start */
3197
 
             ((c >= 0x370) && (c <= 0x37D)) ||
3198
 
             ((c >= 0x37F) && (c <= 0x1FFF)) ||
3199
 
             ((c >= 0x200C) && (c <= 0x200D)) ||
3200
 
             ((c >= 0x203F) && (c <= 0x2040)) || /* !start */
3201
 
             ((c >= 0x2070) && (c <= 0x218F)) ||
3202
 
             ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3203
 
             ((c >= 0x3001) && (c <= 0xD7FF)) ||
3204
 
             ((c >= 0xF900) && (c <= 0xFDCF)) ||
3205
 
             ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3206
 
             ((c >= 0x10000) && (c <= 0xEFFFF))))
3207
 
             return(1);
3208
 
    } else {
3209
 
        if ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
3210
 
            (c == '.') || (c == '-') ||
3211
 
            (c == '_') || (c == ':') ||
3212
 
            (IS_COMBINING(c)) ||
3213
 
            (IS_EXTENDER(c)))
3214
 
            return(1);
3215
 
    }
3216
 
    return(0);
3217
 
}
3218
 
 
3219
 
static xmlChar * xmlParseAttValueInternal(xmlParserCtxtPtr ctxt,
3220
 
                                          int *len, int *alloc, int normalize);
3221
 
 
3222
 
static const xmlChar *
3223
 
xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
3224
 
    int len = 0, l;
3225
 
    int c;
3226
 
    int count = 0;
3227
 
 
3228
 
#ifdef DEBUG
3229
 
    nbParseNameComplex++;
3230
 
#endif
3231
 
 
3232
 
    /*
3233
 
     * Handler for more complex cases
3234
 
     */
3235
 
    GROW;
3236
 
    if (ctxt->instate == XML_PARSER_EOF)
3237
 
        return(NULL);
3238
 
    c = CUR_CHAR(l);
3239
 
    if ((ctxt->options & XML_PARSE_OLD10) == 0) {
3240
 
        /*
3241
 
         * Use the new checks of production [4] [4a] amd [5] of the
3242
 
         * Update 5 of XML-1.0
3243
 
         */
3244
 
        if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
3245
 
            (!(((c >= 'a') && (c <= 'z')) ||
3246
 
               ((c >= 'A') && (c <= 'Z')) ||
3247
 
               (c == '_') || (c == ':') ||
3248
 
               ((c >= 0xC0) && (c <= 0xD6)) ||
3249
 
               ((c >= 0xD8) && (c <= 0xF6)) ||
3250
 
               ((c >= 0xF8) && (c <= 0x2FF)) ||
3251
 
               ((c >= 0x370) && (c <= 0x37D)) ||
3252
 
               ((c >= 0x37F) && (c <= 0x1FFF)) ||
3253
 
               ((c >= 0x200C) && (c <= 0x200D)) ||
3254
 
               ((c >= 0x2070) && (c <= 0x218F)) ||
3255
 
               ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3256
 
               ((c >= 0x3001) && (c <= 0xD7FF)) ||
3257
 
               ((c >= 0xF900) && (c <= 0xFDCF)) ||
3258
 
               ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3259
 
               ((c >= 0x10000) && (c <= 0xEFFFF))))) {
3260
 
            return(NULL);
3261
 
        }
3262
 
        len += l;
3263
 
        NEXTL(l);
3264
 
        c = CUR_CHAR(l);
3265
 
        while ((c != ' ') && (c != '>') && (c != '/') && /* accelerators */
3266
 
               (((c >= 'a') && (c <= 'z')) ||
3267
 
                ((c >= 'A') && (c <= 'Z')) ||
3268
 
                ((c >= '0') && (c <= '9')) || /* !start */
3269
 
                (c == '_') || (c == ':') ||
3270
 
                (c == '-') || (c == '.') || (c == 0xB7) || /* !start */
3271
 
                ((c >= 0xC0) && (c <= 0xD6)) ||
3272
 
                ((c >= 0xD8) && (c <= 0xF6)) ||
3273
 
                ((c >= 0xF8) && (c <= 0x2FF)) ||
3274
 
                ((c >= 0x300) && (c <= 0x36F)) || /* !start */
3275
 
                ((c >= 0x370) && (c <= 0x37D)) ||
3276
 
                ((c >= 0x37F) && (c <= 0x1FFF)) ||
3277
 
                ((c >= 0x200C) && (c <= 0x200D)) ||
3278
 
                ((c >= 0x203F) && (c <= 0x2040)) || /* !start */
3279
 
                ((c >= 0x2070) && (c <= 0x218F)) ||
3280
 
                ((c >= 0x2C00) && (c <= 0x2FEF)) ||
3281
 
                ((c >= 0x3001) && (c <= 0xD7FF)) ||
3282
 
                ((c >= 0xF900) && (c <= 0xFDCF)) ||
3283
 
                ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
3284
 
                ((c >= 0x10000) && (c <= 0xEFFFF))
3285
 
                )) {
3286
 
            if (count++ > XML_PARSER_CHUNK_SIZE) {
3287
 
                count = 0;
3288
 
                GROW;
3289
 
                if (ctxt->instate == XML_PARSER_EOF)
3290
 
                    return(NULL);
3291
 
            }
3292
 
            len += l;
3293
 
            NEXTL(l);
3294
 
            c = CUR_CHAR(l);
3295
 
        }
3296
 
    } else {
3297
 
        if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
3298
 
            (!IS_LETTER(c) && (c != '_') &&
3299
 
             (c != ':'))) {
3300
 
            return(NULL);
3301
 
        }
3302
 
        len += l;
3303
 
        NEXTL(l);
3304
 
        c = CUR_CHAR(l);
3305
 
 
3306
 
        while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
3307
 
               ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
3308
 
                (c == '.') || (c == '-') ||
3309
 
                (c == '_') || (c == ':') ||
3310
 
                (IS_COMBINING(c)) ||
3311
 
                (IS_EXTENDER(c)))) {
3312
 
            if (count++ > XML_PARSER_CHUNK_SIZE) {
3313
 
                count = 0;
3314
 
                GROW;
3315
 
                if (ctxt->instate == XML_PARSER_EOF)
3316
 
                    return(NULL);
3317
 
            }
3318
 
            len += l;
3319
 
            NEXTL(l);
3320
 
            c = CUR_CHAR(l);
3321
 
            if (c == 0) {
3322
 
                count = 0;
3323
 
                GROW;
3324
 
                if (ctxt->instate == XML_PARSER_EOF)
3325
 
                    return(NULL);
3326
 
                c = CUR_CHAR(l);
3327
 
            }
3328
 
        }
3329
 
    }
3330
 
    if ((len > XML_MAX_NAME_LENGTH) &&
3331
 
        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3332
 
        xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name");
3333
 
        return(NULL);
3334
 
    }
3335
 
    if ((*ctxt->input->cur == '\n') && (ctxt->input->cur[-1] == '\r'))
3336
 
        return(xmlDictLookup(ctxt->dict, ctxt->input->cur - (len + 1), len));
3337
 
    return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
3338
 
}
3339
 
 
3340
 
/**
3341
 
 * xmlParseName:
3342
 
 * @ctxt:  an XML parser context
3343
 
 *
3344
 
 * parse an XML name.
3345
 
 *
3346
 
 * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
3347
 
 *                  CombiningChar | Extender
3348
 
 *
3349
 
 * [5] Name ::= (Letter | '_' | ':') (NameChar)*
3350
 
 *
3351
 
 * [6] Names ::= Name (#x20 Name)*
3352
 
 *
3353
 
 * Returns the Name parsed or NULL
3354
 
 */
3355
 
 
3356
 
const xmlChar *
3357
 
xmlParseName(xmlParserCtxtPtr ctxt) {
3358
 
    const xmlChar *in;
3359
 
    const xmlChar *ret;
3360
 
    int count = 0;
3361
 
 
3362
 
    GROW;
3363
 
 
3364
 
#ifdef DEBUG
3365
 
    nbParseName++;
3366
 
#endif
3367
 
 
3368
 
    /*
3369
 
     * Accelerator for simple ASCII names
3370
 
     */
3371
 
    in = ctxt->input->cur;
3372
 
    if (((*in >= 0x61) && (*in <= 0x7A)) ||
3373
 
        ((*in >= 0x41) && (*in <= 0x5A)) ||
3374
 
        (*in == '_') || (*in == ':')) {
3375
 
        in++;
3376
 
        while (((*in >= 0x61) && (*in <= 0x7A)) ||
3377
 
               ((*in >= 0x41) && (*in <= 0x5A)) ||
3378
 
               ((*in >= 0x30) && (*in <= 0x39)) ||
3379
 
               (*in == '_') || (*in == '-') ||
3380
 
               (*in == ':') || (*in == '.'))
3381
 
            in++;
3382
 
        if ((*in > 0) && (*in < 0x80)) {
3383
 
            count = in - ctxt->input->cur;
3384
 
            if ((count > XML_MAX_NAME_LENGTH) &&
3385
 
                ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3386
 
                xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name");
3387
 
                return(NULL);
3388
 
            }
3389
 
            ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
3390
 
            ctxt->input->cur = in;
3391
 
            ctxt->nbChars += count;
3392
 
            ctxt->input->col += count;
3393
 
            if (ret == NULL)
3394
 
                xmlErrMemory(ctxt, NULL);
3395
 
            return(ret);
3396
 
        }
3397
 
    }
3398
 
    /* accelerator for special cases */
3399
 
    return(xmlParseNameComplex(ctxt));
3400
 
}
3401
 
 
3402
 
static const xmlChar *
3403
 
xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
3404
 
    int len = 0, l;
3405
 
    int c;
3406
 
    int count = 0;
3407
 
 
3408
 
#ifdef DEBUG
3409
 
    nbParseNCNameComplex++;
3410
 
#endif
3411
 
 
3412
 
    /*
3413
 
     * Handler for more complex cases
3414
 
     */
3415
 
    GROW;
3416
 
    c = CUR_CHAR(l);
3417
 
    if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
3418
 
        (!xmlIsNameStartChar(ctxt, c) || (c == ':'))) {
3419
 
        return(NULL);
3420
 
    }
3421
 
 
3422
 
    while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
3423
 
           (xmlIsNameChar(ctxt, c) && (c != ':'))) {
3424
 
        if (count++ > XML_PARSER_CHUNK_SIZE) {
3425
 
            if ((len > XML_MAX_NAME_LENGTH) &&
3426
 
                ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3427
 
                xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
3428
 
                return(NULL);
3429
 
            }
3430
 
            count = 0;
3431
 
            GROW;
3432
 
            if (ctxt->instate == XML_PARSER_EOF)
3433
 
                return(NULL);
3434
 
        }
3435
 
        len += l;
3436
 
        NEXTL(l);
3437
 
        c = CUR_CHAR(l);
3438
 
        if (c == 0) {
3439
 
            count = 0;
3440
 
            GROW;
3441
 
            if (ctxt->instate == XML_PARSER_EOF)
3442
 
                return(NULL);
3443
 
            c = CUR_CHAR(l);
3444
 
        }
3445
 
    }
3446
 
    if ((len > XML_MAX_NAME_LENGTH) &&
3447
 
        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3448
 
        xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
3449
 
        return(NULL);
3450
 
    }
3451
 
    return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
3452
 
}
3453
 
 
3454
 
/**
3455
 
 * xmlParseNCName:
3456
 
 * @ctxt:  an XML parser context
3457
 
 * @len:  length of the string parsed
3458
 
 *
3459
 
 * parse an XML name.
3460
 
 *
3461
 
 * [4NS] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
3462
 
 *                      CombiningChar | Extender
3463
 
 *
3464
 
 * [5NS] NCName ::= (Letter | '_') (NCNameChar)*
3465
 
 *
3466
 
 * Returns the Name parsed or NULL
3467
 
 */
3468
 
 
3469
 
static const xmlChar *
3470
 
xmlParseNCName(xmlParserCtxtPtr ctxt) {
3471
 
    const xmlChar *in;
3472
 
    const xmlChar *ret;
3473
 
    int count = 0;
3474
 
 
3475
 
#ifdef DEBUG
3476
 
    nbParseNCName++;
3477
 
#endif
3478
 
 
3479
 
    /*
3480
 
     * Accelerator for simple ASCII names
3481
 
     */
3482
 
    in = ctxt->input->cur;
3483
 
    if (((*in >= 0x61) && (*in <= 0x7A)) ||
3484
 
        ((*in >= 0x41) && (*in <= 0x5A)) ||
3485
 
        (*in == '_')) {
3486
 
        in++;
3487
 
        while (((*in >= 0x61) && (*in <= 0x7A)) ||
3488
 
               ((*in >= 0x41) && (*in <= 0x5A)) ||
3489
 
               ((*in >= 0x30) && (*in <= 0x39)) ||
3490
 
               (*in == '_') || (*in == '-') ||
3491
 
               (*in == '.'))
3492
 
            in++;
3493
 
        if ((*in > 0) && (*in < 0x80)) {
3494
 
            count = in - ctxt->input->cur;
3495
 
            if ((count > XML_MAX_NAME_LENGTH) &&
3496
 
                ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3497
 
                xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
3498
 
                return(NULL);
3499
 
            }
3500
 
            ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
3501
 
            ctxt->input->cur = in;
3502
 
            ctxt->nbChars += count;
3503
 
            ctxt->input->col += count;
3504
 
            if (ret == NULL) {
3505
 
                xmlErrMemory(ctxt, NULL);
3506
 
            }
3507
 
            return(ret);
3508
 
        }
3509
 
    }
3510
 
    return(xmlParseNCNameComplex(ctxt));
3511
 
}
3512
 
 
3513
 
/**
3514
 
 * xmlParseNameAndCompare:
3515
 
 * @ctxt:  an XML parser context
3516
 
 *
3517
 
 * parse an XML name and compares for match
3518
 
 * (specialized for endtag parsing)
3519
 
 *
3520
 
 * Returns NULL for an illegal name, (xmlChar*) 1 for success
3521
 
 * and the name for mismatch
3522
 
 */
3523
 
 
3524
 
static const xmlChar *
3525
 
xmlParseNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *other) {
3526
 
    register const xmlChar *cmp = other;
3527
 
    register const xmlChar *in;
3528
 
    const xmlChar *ret;
3529
 
 
3530
 
    GROW;
3531
 
    if (ctxt->instate == XML_PARSER_EOF)
3532
 
        return(NULL);
3533
 
 
3534
 
    in = ctxt->input->cur;
3535
 
    while (*in != 0 && *in == *cmp) {
3536
 
        ++in;
3537
 
        ++cmp;
3538
 
        ctxt->input->col++;
3539
 
    }
3540
 
    if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) {
3541
 
        /* success */
3542
 
        ctxt->input->cur = in;
3543
 
        return (const xmlChar*) 1;
3544
 
    }
3545
 
    /* failure (or end of input buffer), check with full function */
3546
 
    ret = xmlParseName (ctxt);
3547
 
    /* strings coming from the dictionnary direct compare possible */
3548
 
    if (ret == other) {
3549
 
        return (const xmlChar*) 1;
3550
 
    }
3551
 
    return ret;
3552
 
}
3553
 
 
3554
 
/**
3555
 
 * xmlParseStringName:
3556
 
 * @ctxt:  an XML parser context
3557
 
 * @str:  a pointer to the string pointer (IN/OUT)
3558
 
 *
3559
 
 * parse an XML name.
3560
 
 *
3561
 
 * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
3562
 
 *                  CombiningChar | Extender
3563
 
 *
3564
 
 * [5] Name ::= (Letter | '_' | ':') (NameChar)*
3565
 
 *
3566
 
 * [6] Names ::= Name (#x20 Name)*
3567
 
 *
3568
 
 * Returns the Name parsed or NULL. The @str pointer
3569
 
 * is updated to the current location in the string.
3570
 
 */
3571
 
 
3572
 
static xmlChar *
3573
 
xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
3574
 
    xmlChar buf[XML_MAX_NAMELEN + 5];
3575
 
    const xmlChar *cur = *str;
3576
 
    int len = 0, l;
3577
 
    int c;
3578
 
 
3579
 
#ifdef DEBUG
3580
 
    nbParseStringName++;
3581
 
#endif
3582
 
 
3583
 
    c = CUR_SCHAR(cur, l);
3584
 
    if (!xmlIsNameStartChar(ctxt, c)) {
3585
 
        return(NULL);
3586
 
    }
3587
 
 
3588
 
    COPY_BUF(l,buf,len,c);
3589
 
    cur += l;
3590
 
    c = CUR_SCHAR(cur, l);
3591
 
    while (xmlIsNameChar(ctxt, c)) {
3592
 
        COPY_BUF(l,buf,len,c);
3593
 
        cur += l;
3594
 
        c = CUR_SCHAR(cur, l);
3595
 
        if (len >= XML_MAX_NAMELEN) { /* test bigentname.xml */
3596
 
            /*
3597
 
             * Okay someone managed to make a huge name, so he's ready to pay
3598
 
             * for the processing speed.
3599
 
             */
3600
 
            xmlChar *buffer;
3601
 
            int max = len * 2;
3602
 
 
3603
 
            buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
3604
 
            if (buffer == NULL) {
3605
 
                xmlErrMemory(ctxt, NULL);
3606
 
                return(NULL);
3607
 
            }
3608
 
            memcpy(buffer, buf, len);
3609
 
            while (xmlIsNameChar(ctxt, c)) {
3610
 
                if (len + 10 > max) {
3611
 
                    xmlChar *tmp;
3612
 
 
3613
 
                    if ((len > XML_MAX_NAME_LENGTH) &&
3614
 
                        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3615
 
                        xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
3616
 
                        xmlFree(buffer);
3617
 
                        return(NULL);
3618
 
                    }
3619
 
                    max *= 2;
3620
 
                    tmp = (xmlChar *) xmlRealloc(buffer,
3621
 
                                                    max * sizeof(xmlChar));
3622
 
                    if (tmp == NULL) {
3623
 
                        xmlErrMemory(ctxt, NULL);
3624
 
                        xmlFree(buffer);
3625
 
                        return(NULL);
3626
 
                    }
3627
 
                    buffer = tmp;
3628
 
                }
3629
 
                COPY_BUF(l,buffer,len,c);
3630
 
                cur += l;
3631
 
                c = CUR_SCHAR(cur, l);
3632
 
            }
3633
 
            buffer[len] = 0;
3634
 
            *str = cur;
3635
 
            return(buffer);
3636
 
        }
3637
 
    }
3638
 
    if ((len > XML_MAX_NAME_LENGTH) &&
3639
 
        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3640
 
        xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
3641
 
        return(NULL);
3642
 
    }
3643
 
    *str = cur;
3644
 
    return(xmlStrndup(buf, len));
3645
 
}
3646
 
 
3647
 
/**
3648
 
 * xmlParseNmtoken:
3649
 
 * @ctxt:  an XML parser context
3650
 
 *
3651
 
 * parse an XML Nmtoken.
3652
 
 *
3653
 
 * [7] Nmtoken ::= (NameChar)+
3654
 
 *
3655
 
 * [8] Nmtokens ::= Nmtoken (#x20 Nmtoken)*
3656
 
 *
3657
 
 * Returns the Nmtoken parsed or NULL
3658
 
 */
3659
 
 
3660
 
xmlChar *
3661
 
xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
3662
 
    xmlChar buf[XML_MAX_NAMELEN + 5];
3663
 
    int len = 0, l;
3664
 
    int c;
3665
 
    int count = 0;
3666
 
 
3667
 
#ifdef DEBUG
3668
 
    nbParseNmToken++;
3669
 
#endif
3670
 
 
3671
 
    GROW;
3672
 
    if (ctxt->instate == XML_PARSER_EOF)
3673
 
        return(NULL);
3674
 
    c = CUR_CHAR(l);
3675
 
 
3676
 
    while (xmlIsNameChar(ctxt, c)) {
3677
 
        if (count++ > XML_PARSER_CHUNK_SIZE) {
3678
 
            count = 0;
3679
 
            GROW;
3680
 
        }
3681
 
        COPY_BUF(l,buf,len,c);
3682
 
        NEXTL(l);
3683
 
        c = CUR_CHAR(l);
3684
 
        if (c == 0) {
3685
 
            count = 0;
3686
 
            GROW;
3687
 
            if (ctxt->instate == XML_PARSER_EOF)
3688
 
                return(NULL);
3689
 
            c = CUR_CHAR(l);
3690
 
        }
3691
 
        if (len >= XML_MAX_NAMELEN) {
3692
 
            /*
3693
 
             * Okay someone managed to make a huge token, so he's ready to pay
3694
 
             * for the processing speed.
3695
 
             */
3696
 
            xmlChar *buffer;
3697
 
            int max = len * 2;
3698
 
 
3699
 
            buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
3700
 
            if (buffer == NULL) {
3701
 
                xmlErrMemory(ctxt, NULL);
3702
 
                return(NULL);
3703
 
            }
3704
 
            memcpy(buffer, buf, len);
3705
 
            while (xmlIsNameChar(ctxt, c)) {
3706
 
                if (count++ > XML_PARSER_CHUNK_SIZE) {
3707
 
                    count = 0;
3708
 
                    GROW;
3709
 
                    if (ctxt->instate == XML_PARSER_EOF) {
3710
 
                        xmlFree(buffer);
3711
 
                        return(NULL);
3712
 
                    }
3713
 
                }
3714
 
                if (len + 10 > max) {
3715
 
                    xmlChar *tmp;
3716
 
 
3717
 
                    if ((max > XML_MAX_NAME_LENGTH) &&
3718
 
                        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3719
 
                        xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken");
3720
 
                        xmlFree(buffer);
3721
 
                        return(NULL);
3722
 
                    }
3723
 
                    max *= 2;
3724
 
                    tmp = (xmlChar *) xmlRealloc(buffer,
3725
 
                                                    max * sizeof(xmlChar));
3726
 
                    if (tmp == NULL) {
3727
 
                        xmlErrMemory(ctxt, NULL);
3728
 
                        xmlFree(buffer);
3729
 
                        return(NULL);
3730
 
                    }
3731
 
                    buffer = tmp;
3732
 
                }
3733
 
                COPY_BUF(l,buffer,len,c);
3734
 
                NEXTL(l);
3735
 
                c = CUR_CHAR(l);
3736
 
            }
3737
 
            buffer[len] = 0;
3738
 
            return(buffer);
3739
 
        }
3740
 
    }
3741
 
    if (len == 0)
3742
 
        return(NULL);
3743
 
    if ((len > XML_MAX_NAME_LENGTH) &&
3744
 
        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3745
 
        xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken");
3746
 
        return(NULL);
3747
 
    }
3748
 
    return(xmlStrndup(buf, len));
3749
 
}
3750
 
 
3751
 
/**
3752
 
 * xmlParseEntityValue:
3753
 
 * @ctxt:  an XML parser context
3754
 
 * @orig:  if non-NULL store a copy of the original entity value
3755
 
 *
3756
 
 * parse a value for ENTITY declarations
3757
 
 *
3758
 
 * [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"' |
3759
 
 *                     "'" ([^%&'] | PEReference | Reference)* "'"
3760
 
 *
3761
 
 * Returns the EntityValue parsed with reference substituted or NULL
3762
 
 */
3763
 
 
3764
 
xmlChar *
3765
 
xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
3766
 
    xmlChar *buf = NULL;
3767
 
    int len = 0;
3768
 
    int size = XML_PARSER_BUFFER_SIZE;
3769
 
    int c, l;
3770
 
    xmlChar stop;
3771
 
    xmlChar *ret = NULL;
3772
 
    const xmlChar *cur = NULL;
3773
 
    xmlParserInputPtr input;
3774
 
 
3775
 
    if (RAW == '"') stop = '"';
3776
 
    else if (RAW == '\'') stop = '\'';
3777
 
    else {
3778
 
        xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_STARTED, NULL);
3779
 
        return(NULL);
3780
 
    }
3781
 
    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
3782
 
    if (buf == NULL) {
3783
 
        xmlErrMemory(ctxt, NULL);
3784
 
        return(NULL);
3785
 
    }
3786
 
 
3787
 
    /*
3788
 
     * The content of the entity definition is copied in a buffer.
3789
 
     */
3790
 
 
3791
 
    ctxt->instate = XML_PARSER_ENTITY_VALUE;
3792
 
    input = ctxt->input;
3793
 
    GROW;
3794
 
    if (ctxt->instate == XML_PARSER_EOF) {
3795
 
        xmlFree(buf);
3796
 
        return(NULL);
3797
 
    }
3798
 
    NEXT;
3799
 
    c = CUR_CHAR(l);
3800
 
    /*
3801
 
     * NOTE: 4.4.5 Included in Literal
3802
 
     * When a parameter entity reference appears in a literal entity
3803
 
     * value, ... a single or double quote character in the replacement
3804
 
     * text is always treated as a normal data character and will not
3805
 
     * terminate the literal.
3806
 
     * In practice it means we stop the loop only when back at parsing
3807
 
     * the initial entity and the quote is found
3808
 
     */
3809
 
    while (((IS_CHAR(c)) && ((c != stop) || /* checked */
3810
 
            (ctxt->input != input))) && (ctxt->instate != XML_PARSER_EOF)) {
3811
 
        if (len + 5 >= size) {
3812
 
            xmlChar *tmp;
3813
 
 
3814
 
            size *= 2;
3815
 
            tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
3816
 
            if (tmp == NULL) {
3817
 
                xmlErrMemory(ctxt, NULL);
3818
 
                xmlFree(buf);
3819
 
                return(NULL);
3820
 
            }
3821
 
            buf = tmp;
3822
 
        }
3823
 
        COPY_BUF(l,buf,len,c);
3824
 
        NEXTL(l);
3825
 
        /*
3826
 
         * Pop-up of finished entities.
3827
 
         */
3828
 
        while ((RAW == 0) && (ctxt->inputNr > 1)) /* non input consuming */
3829
 
            xmlPopInput(ctxt);
3830
 
 
3831
 
        GROW;
3832
 
        c = CUR_CHAR(l);
3833
 
        if (c == 0) {
3834
 
            GROW;
3835
 
            c = CUR_CHAR(l);
3836
 
        }
3837
 
    }
3838
 
    buf[len] = 0;
3839
 
    if (ctxt->instate == XML_PARSER_EOF) {
3840
 
        xmlFree(buf);
3841
 
        return(NULL);
3842
 
    }
3843
 
 
3844
 
    /*
3845
 
     * Raise problem w.r.t. '&' and '%' being used in non-entities
3846
 
     * reference constructs. Note Charref will be handled in
3847
 
     * xmlStringDecodeEntities()
3848
 
     */
3849
 
    cur = buf;
3850
 
    while (*cur != 0) { /* non input consuming */
3851
 
        if ((*cur == '%') || ((*cur == '&') && (cur[1] != '#'))) {
3852
 
            xmlChar *name;
3853
 
            xmlChar tmp = *cur;
3854
 
 
3855
 
            cur++;
3856
 
            name = xmlParseStringName(ctxt, &cur);
3857
 
            if ((name == NULL) || (*cur != ';')) {
3858
 
                xmlFatalErrMsgInt(ctxt, XML_ERR_ENTITY_CHAR_ERROR,
3859
 
            "EntityValue: '%c' forbidden except for entities references\n",
3860
 
                                  tmp);
3861
 
            }
3862
 
            if ((tmp == '%') && (ctxt->inSubset == 1) &&
3863
 
                (ctxt->inputNr == 1)) {
3864
 
                xmlFatalErr(ctxt, XML_ERR_ENTITY_PE_INTERNAL, NULL);
3865
 
            }
3866
 
            if (name != NULL)
3867
 
                xmlFree(name);
3868
 
            if (*cur == 0)
3869
 
                break;
3870
 
        }
3871
 
        cur++;
3872
 
    }
3873
 
 
3874
 
    /*
3875
 
     * Then PEReference entities are substituted.
3876
 
     */
3877
 
    if (c != stop) {
3878
 
        xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_FINISHED, NULL);
3879
 
        xmlFree(buf);
3880
 
    } else {
3881
 
        NEXT;
3882
 
        /*
3883
 
         * NOTE: 4.4.7 Bypassed
3884
 
         * When a general entity reference appears in the EntityValue in
3885
 
         * an entity declaration, it is bypassed and left as is.
3886
 
         * so XML_SUBSTITUTE_REF is not set here.
3887
 
         */
3888
 
        ret = xmlStringDecodeEntities(ctxt, buf, XML_SUBSTITUTE_PEREF,
3889
 
                                      0, 0, 0);
3890
 
        if (orig != NULL)
3891
 
            *orig = buf;
3892
 
        else
3893
 
            xmlFree(buf);
3894
 
    }
3895
 
 
3896
 
    return(ret);
3897
 
}
3898
 
 
3899
 
/**
3900
 
 * xmlParseAttValueComplex:
3901
 
 * @ctxt:  an XML parser context
3902
 
 * @len:   the resulting attribute len
3903
 
 * @normalize:  wether to apply the inner normalization
3904
 
 *
3905
 
 * parse a value for an attribute, this is the fallback function
3906
 
 * of xmlParseAttValue() when the attribute parsing requires handling
3907
 
 * of non-ASCII characters, or normalization compaction.
3908
 
 *
3909
 
 * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
3910
 
 */
3911
 
static xmlChar *
3912
 
xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
3913
 
    xmlChar limit = 0;
3914
 
    xmlChar *buf = NULL;
3915
 
    xmlChar *rep = NULL;
3916
 
    size_t len = 0;
3917
 
    size_t buf_size = 0;
3918
 
    int c, l, in_space = 0;
3919
 
    xmlChar *current = NULL;
3920
 
    xmlEntityPtr ent;
3921
 
 
3922
 
    if (NXT(0) == '"') {
3923
 
        ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
3924
 
        limit = '"';
3925
 
        NEXT;
3926
 
    } else if (NXT(0) == '\'') {
3927
 
        limit = '\'';
3928
 
        ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
3929
 
        NEXT;
3930
 
    } else {
3931
 
        xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
3932
 
        return(NULL);
3933
 
    }
3934
 
 
3935
 
    /*
3936
 
     * allocate a translation buffer.
3937
 
     */
3938
 
    buf_size = XML_PARSER_BUFFER_SIZE;
3939
 
    buf = (xmlChar *) xmlMallocAtomic(buf_size);
3940
 
    if (buf == NULL) goto mem_error;
3941
 
 
3942
 
    /*
3943
 
     * OK loop until we reach one of the ending char or a size limit.
3944
 
     */
3945
 
    c = CUR_CHAR(l);
3946
 
    while (((NXT(0) != limit) && /* checked */
3947
 
            (IS_CHAR(c)) && (c != '<')) &&
3948
 
            (ctxt->instate != XML_PARSER_EOF)) {
3949
 
        /*
3950
 
         * Impose a reasonable limit on attribute size, unless XML_PARSE_HUGE
3951
 
         * special option is given
3952
 
         */
3953
 
        if ((len > XML_MAX_TEXT_LENGTH) &&
3954
 
            ((ctxt->options & XML_PARSE_HUGE) == 0)) {
3955
 
            xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
3956
 
                           "AttValue length too long\n");
3957
 
            goto mem_error;
3958
 
        }
3959
 
        if (c == 0) break;
3960
 
        if (c == '&') {
3961
 
            in_space = 0;
3962
 
            if (NXT(1) == '#') {
3963
 
                int val = xmlParseCharRef(ctxt);
3964
 
 
3965
 
                if (val == '&') {
3966
 
                    if (ctxt->replaceEntities) {
3967
 
                        if (len + 10 > buf_size) {
3968
 
                            growBuffer(buf, 10);
3969
 
                        }
3970
 
                        buf[len++] = '&';
3971
 
                    } else {
3972
 
                        /*
3973
 
                         * The reparsing will be done in xmlStringGetNodeList()
3974
 
                         * called by the attribute() function in SAX.c
3975
 
                         */
3976
 
                        if (len + 10 > buf_size) {
3977
 
                            growBuffer(buf, 10);
3978
 
                        }
3979
 
                        buf[len++] = '&';
3980
 
                        buf[len++] = '#';
3981
 
                        buf[len++] = '3';
3982
 
                        buf[len++] = '8';
3983
 
                        buf[len++] = ';';
3984
 
                    }
3985
 
                } else if (val != 0) {
3986
 
                    if (len + 10 > buf_size) {
3987
 
                        growBuffer(buf, 10);
3988
 
                    }
3989
 
                    len += xmlCopyChar(0, &buf[len], val);
3990
 
                }
3991
 
            } else {
3992
 
                ent = xmlParseEntityRef(ctxt);
3993
 
                ctxt->nbentities++;
3994
 
                if (ent != NULL)
3995
 
                    ctxt->nbentities += ent->owner;
3996
 
                if ((ent != NULL) &&
3997
 
                    (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
3998
 
                    if (len + 10 > buf_size) {
3999
 
                        growBuffer(buf, 10);
4000
 
                    }
4001
 
                    if ((ctxt->replaceEntities == 0) &&
4002
 
                        (ent->content[0] == '&')) {
4003
 
                        buf[len++] = '&';
4004
 
                        buf[len++] = '#';
4005
 
                        buf[len++] = '3';
4006
 
                        buf[len++] = '8';
4007
 
                        buf[len++] = ';';
4008
 
                    } else {
4009
 
                        buf[len++] = ent->content[0];
4010
 
                    }
4011
 
                } else if ((ent != NULL) &&
4012
 
                           (ctxt->replaceEntities != 0)) {
4013
 
                    if (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) {
4014
 
                        rep = xmlStringDecodeEntities(ctxt, ent->content,
4015
 
                                                      XML_SUBSTITUTE_REF,
4016
 
                                                      0, 0, 0);
4017
 
                        if (rep != NULL) {
4018
 
                            current = rep;
4019
 
                            while (*current != 0) { /* non input consuming */
4020
 
                                if ((*current == 0xD) || (*current == 0xA) ||
4021
 
                                    (*current == 0x9)) {
4022
 
                                    buf[len++] = 0x20;
4023
 
                                    current++;
4024
 
                                } else
4025
 
                                    buf[len++] = *current++;
4026
 
                                if (len + 10 > buf_size) {
4027
 
                                    growBuffer(buf, 10);
4028
 
                                }
4029
 
                            }
4030
 
                            xmlFree(rep);
4031
 
                            rep = NULL;
4032
 
                        }
4033
 
                    } else {
4034
 
                        if (len + 10 > buf_size) {
4035
 
                            growBuffer(buf, 10);
4036
 
                        }
4037
 
                        if (ent->content != NULL)
4038
 
                            buf[len++] = ent->content[0];
4039
 
                    }
4040
 
                } else if (ent != NULL) {
4041
 
                    int i = xmlStrlen(ent->name);
4042
 
                    const xmlChar *cur = ent->name;
4043
 
 
4044
 
                    /*
4045
 
                     * This may look absurd but is needed to detect
4046
 
                     * entities problems
4047
 
                     */
4048
 
                    if ((ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
4049
 
                        (ent->content != NULL) && (ent->checked == 0)) {
4050
 
                        unsigned long oldnbent = ctxt->nbentities;
4051
 
 
4052
 
                        rep = xmlStringDecodeEntities(ctxt, ent->content,
4053
 
                                                  XML_SUBSTITUTE_REF, 0, 0, 0);
4054
 
 
4055
 
                        ent->checked = (ctxt->nbentities - oldnbent + 1) * 2;
4056
 
                        if (rep != NULL) {
4057
 
                            if (xmlStrchr(rep, '<'))
4058
 
                                ent->checked |= 1;
4059
 
                            xmlFree(rep);
4060
 
                            rep = NULL;
4061
 
                        }
4062
 
                    }
4063
 
 
4064
 
                    /*
4065
 
                     * Just output the reference
4066
 
                     */
4067
 
                    buf[len++] = '&';
4068
 
                    while (len + i + 10 > buf_size) {
4069
 
                        growBuffer(buf, i + 10);
4070
 
                    }
4071
 
                    for (;i > 0;i--)
4072
 
                        buf[len++] = *cur++;
4073
 
                    buf[len++] = ';';
4074
 
                }
4075
 
            }
4076
 
        } else {
4077
 
            if ((c == 0x20) || (c == 0xD) || (c == 0xA) || (c == 0x9)) {
4078
 
                if ((len != 0) || (!normalize)) {
4079
 
                    if ((!normalize) || (!in_space)) {
4080
 
                        COPY_BUF(l,buf,len,0x20);
4081
 
                        while (len + 10 > buf_size) {
4082
 
                            growBuffer(buf, 10);
4083
 
                        }
4084
 
                    }
4085
 
                    in_space = 1;
4086
 
                }
4087
 
            } else {
4088
 
                in_space = 0;
4089
 
                COPY_BUF(l,buf,len,c);
4090
 
                if (len + 10 > buf_size) {
4091
 
                    growBuffer(buf, 10);
4092
 
                }
4093
 
            }
4094
 
            NEXTL(l);
4095
 
        }
4096
 
        GROW;
4097
 
        c = CUR_CHAR(l);
4098
 
    }
4099
 
    if (ctxt->instate == XML_PARSER_EOF)
4100
 
        goto error;
4101
 
 
4102
 
    if ((in_space) && (normalize)) {
4103
 
        while ((len > 0) && (buf[len - 1] == 0x20)) len--;
4104
 
    }
4105
 
    buf[len] = 0;
4106
 
    if (RAW == '<') {
4107
 
        xmlFatalErr(ctxt, XML_ERR_LT_IN_ATTRIBUTE, NULL);
4108
 
    } else if (RAW != limit) {
4109
 
        if ((c != 0) && (!IS_CHAR(c))) {
4110
 
            xmlFatalErrMsg(ctxt, XML_ERR_INVALID_CHAR,
4111
 
                           "invalid character in attribute value\n");
4112
 
        } else {
4113
 
            xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
4114
 
                           "AttValue: ' expected\n");
4115
 
        }
4116
 
    } else
4117
 
        NEXT;
4118
 
 
4119
 
    /*
4120
 
     * There we potentially risk an overflow, don't allow attribute value of
4121
 
     * length more than INT_MAX it is a very reasonnable assumption !
4122
 
     */
4123
 
    if (len >= INT_MAX) {
4124
 
        xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
4125
 
                       "AttValue length too long\n");
4126
 
        goto mem_error;
4127
 
    }
4128
 
 
4129
 
    if (attlen != NULL) *attlen = (int) len;
4130
 
    return(buf);
4131
 
 
4132
 
mem_error:
4133
 
    xmlErrMemory(ctxt, NULL);
4134
 
error:
4135
 
    if (buf != NULL)
4136
 
        xmlFree(buf);
4137
 
    if (rep != NULL)
4138
 
        xmlFree(rep);
4139
 
    return(NULL);
4140
 
}
4141
 
 
4142
 
/**
4143
 
 * xmlParseAttValue:
4144
 
 * @ctxt:  an XML parser context
4145
 
 *
4146
 
 * parse a value for an attribute
4147
 
 * Note: the parser won't do substitution of entities here, this
4148
 
 * will be handled later in xmlStringGetNodeList
4149
 
 *
4150
 
 * [10] AttValue ::= '"' ([^<&"] | Reference)* '"' |
4151
 
 *                   "'" ([^<&'] | Reference)* "'"
4152
 
 *
4153
 
 * 3.3.3 Attribute-Value Normalization:
4154
 
 * Before the value of an attribute is passed to the application or
4155
 
 * checked for validity, the XML processor must normalize it as follows:
4156
 
 * - a character reference is processed by appending the referenced
4157
 
 *   character to the attribute value
4158
 
 * - an entity reference is processed by recursively processing the
4159
 
 *   replacement text of the entity
4160
 
 * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
4161
 
 *   appending #x20 to the normalized value, except that only a single
4162
 
 *   #x20 is appended for a "#xD#xA" sequence that is part of an external
4163
 
 *   parsed entity or the literal entity value of an internal parsed entity
4164
 
 * - other characters are processed by appending them to the normalized value
4165
 
 * If the declared value is not CDATA, then the XML processor must further
4166
 
 * process the normalized attribute value by discarding any leading and
4167
 
 * trailing space (#x20) characters, and by replacing sequences of space
4168
 
 * (#x20) characters by a single space (#x20) character.
4169
 
 * All attributes for which no declaration has been read should be treated
4170
 
 * by a non-validating parser as if declared CDATA.
4171
 
 *
4172
 
 * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
4173
 
 */
4174
 
 
4175
 
 
4176
 
xmlChar *
4177
 
xmlParseAttValue(xmlParserCtxtPtr ctxt) {
4178
 
    if ((ctxt == NULL) || (ctxt->input == NULL)) return(NULL);
4179
 
    return(xmlParseAttValueInternal(ctxt, NULL, NULL, 0));
4180
 
}
4181
 
 
4182
 
/**
4183
 
 * xmlParseSystemLiteral:
4184
 
 * @ctxt:  an XML parser context
4185
 
 *
4186
 
 * parse an XML Literal
4187
 
 *
4188
 
 * [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
4189
 
 *
4190
 
 * Returns the SystemLiteral parsed or NULL
4191
 
 */
4192
 
 
4193
 
xmlChar *
4194
 
xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
4195
 
    xmlChar *buf = NULL;
4196
 
    int len = 0;
4197
 
    int size = XML_PARSER_BUFFER_SIZE;
4198
 
    int cur, l;
4199
 
    xmlChar stop;
4200
 
    int state = ctxt->instate;
4201
 
    int count = 0;
4202
 
 
4203
 
    SHRINK;
4204
 
    if (RAW == '"') {
4205
 
        NEXT;
4206
 
        stop = '"';
4207
 
    } else if (RAW == '\'') {
4208
 
        NEXT;
4209
 
        stop = '\'';
4210
 
    } else {
4211
 
        xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, NULL);
4212
 
        return(NULL);
4213
 
    }
4214
 
 
4215
 
    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
4216
 
    if (buf == NULL) {
4217
 
        xmlErrMemory(ctxt, NULL);
4218
 
        return(NULL);
4219
 
    }
4220
 
    ctxt->instate = XML_PARSER_SYSTEM_LITERAL;
4221
 
    cur = CUR_CHAR(l);
4222
 
    while ((IS_CHAR(cur)) && (cur != stop)) { /* checked */
4223
 
        if (len + 5 >= size) {
4224
 
            xmlChar *tmp;
4225
 
 
4226
 
            if ((size > XML_MAX_NAME_LENGTH) &&
4227
 
                ((ctxt->options & XML_PARSE_HUGE) == 0)) {
4228
 
                xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "SystemLiteral");
4229
 
                xmlFree(buf);
4230
 
                ctxt->instate = (xmlParserInputState) state;
4231
 
                return(NULL);
4232
 
            }
4233
 
            size *= 2;
4234
 
            tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
4235
 
            if (tmp == NULL) {
4236
 
                xmlFree(buf);
4237
 
                xmlErrMemory(ctxt, NULL);
4238
 
                ctxt->instate = (xmlParserInputState) state;
4239
 
                return(NULL);
4240
 
            }
4241
 
            buf = tmp;
4242
 
        }
4243
 
        count++;
4244
 
        if (count > 50) {
4245
 
            GROW;
4246
 
            count = 0;
4247
 
            if (ctxt->instate == XML_PARSER_EOF) {
4248
 
                xmlFree(buf);
4249
 
                return(NULL);
4250
 
            }
4251
 
        }
4252
 
        COPY_BUF(l,buf,len,cur);
4253
 
        NEXTL(l);
4254
 
        cur = CUR_CHAR(l);
4255
 
        if (cur == 0) {
4256
 
            GROW;
4257
 
            SHRINK;
4258
 
            cur = CUR_CHAR(l);
4259
 
        }
4260
 
    }
4261
 
    buf[len] = 0;
4262
 
    ctxt->instate = (xmlParserInputState) state;
4263
 
    if (!IS_CHAR(cur)) {
4264
 
        xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
4265
 
    } else {
4266
 
        NEXT;
4267
 
    }
4268
 
    return(buf);
4269
 
}
4270
 
 
4271
 
/**
4272
 
 * xmlParsePubidLiteral:
4273
 
 * @ctxt:  an XML parser context
4274
 
 *
4275
 
 * parse an XML public literal
4276
 
 *
4277
 
 * [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
4278
 
 *
4279
 
 * Returns the PubidLiteral parsed or NULL.
4280
 
 */
4281
 
 
4282
 
xmlChar *
4283
 
xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
4284
 
    xmlChar *buf = NULL;
4285
 
    int len = 0;
4286
 
    int size = XML_PARSER_BUFFER_SIZE;
4287
 
    xmlChar cur;
4288
 
    xmlChar stop;
4289
 
    int count = 0;
4290
 
    xmlParserInputState oldstate = ctxt->instate;
4291
 
 
4292
 
    SHRINK;
4293
 
    if (RAW == '"') {
4294
 
        NEXT;
4295
 
        stop = '"';
4296
 
    } else if (RAW == '\'') {
4297
 
        NEXT;
4298
 
        stop = '\'';
4299
 
    } else {
4300
 
        xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_STARTED, NULL);
4301
 
        return(NULL);
4302
 
    }
4303
 
    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
4304
 
    if (buf == NULL) {
4305
 
        xmlErrMemory(ctxt, NULL);
4306
 
        return(NULL);
4307
 
    }
4308
 
    ctxt->instate = XML_PARSER_PUBLIC_LITERAL;
4309
 
    cur = CUR;
4310
 
    while ((IS_PUBIDCHAR_CH(cur)) && (cur != stop)) { /* checked */
4311
 
        if (len + 1 >= size) {
4312
 
            xmlChar *tmp;
4313
 
 
4314
 
            if ((size > XML_MAX_NAME_LENGTH) &&
4315
 
                ((ctxt->options & XML_PARSE_HUGE) == 0)) {
4316
 
                xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Public ID");
4317
 
                xmlFree(buf);
4318
 
                return(NULL);
4319
 
            }
4320
 
            size *= 2;
4321
 
            tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
4322
 
            if (tmp == NULL) {
4323
 
                xmlErrMemory(ctxt, NULL);
4324
 
                xmlFree(buf);
4325
 
                return(NULL);
4326
 
            }
4327
 
            buf = tmp;
4328
 
        }
4329
 
        buf[len++] = cur;
4330
 
        count++;
4331
 
        if (count > 50) {
4332
 
            GROW;
4333
 
            count = 0;
4334
 
            if (ctxt->instate == XML_PARSER_EOF) {
4335
 
                xmlFree(buf);
4336
 
                return(NULL);
4337
 
            }
4338
 
        }
4339
 
        NEXT;
4340
 
        cur = CUR;
4341
 
        if (cur == 0) {
4342
 
            GROW;
4343
 
            SHRINK;
4344
 
            cur = CUR;
4345
 
        }
4346
 
    }
4347
 
    buf[len] = 0;
4348
 
    if (cur != stop) {
4349
 
        xmlFatalErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, NULL);
4350
 
    } else {
4351
 
        NEXT;
4352
 
    }
4353
 
    ctxt->instate = oldstate;
4354
 
    return(buf);
4355
 
}
4356
 
 
4357
 
static void xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata);
4358
 
 
4359
 
/*
4360
 
 * used for the test in the inner loop of the char data testing
4361
 
 */
4362
 
static const unsigned char test_char_data[256] = {
4363
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4364
 
    0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9, CR/LF separated */
4365
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4366
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4367
 
    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x00, 0x27, /* & */
4368
 
    0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
4369
 
    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
4370
 
    0x38, 0x39, 0x3A, 0x3B, 0x00, 0x3D, 0x3E, 0x3F, /* < */
4371
 
    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
4372
 
    0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
4373
 
    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
4374
 
    0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x00, 0x5E, 0x5F, /* ] */
4375
 
    0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
4376
 
    0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
4377
 
    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
4378
 
    0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
4379
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* non-ascii */
4380
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4381
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4382
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4383
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4384
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4385
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4386
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4387
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4388
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4389
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4390
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4391
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4392
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4393
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4394
 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
4395
 
};
4396
 
 
4397
 
/**
4398
 
 * xmlParseCharData:
4399
 
 * @ctxt:  an XML parser context
4400
 
 * @cdata:  int indicating whether we are within a CDATA section
4401
 
 *
4402
 
 * parse a CharData section.
4403
 
 * if we are within a CDATA section ']]>' marks an end of section.
4404
 
 *
4405
 
 * The right angle bracket (>) may be represented using the string "&gt;",
4406
 
 * and must, for compatibility, be escaped using "&gt;" or a character
4407
 
 * reference when it appears in the string "]]>" in content, when that
4408
 
 * string is not marking the end of a CDATA section.
4409
 
 *
4410
 
 * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
4411
 
 */
4412
 
 
4413
 
void
4414
 
xmlParseCharData(xmlParserCtxtPtr ctxt, int cdata) {
4415
 
    const xmlChar *in;
4416
 
    int nbchar = 0;
4417
 
    int line = ctxt->input->line;
4418
 
    int col = ctxt->input->col;
4419
 
    int ccol;
4420
 
 
4421
 
    SHRINK;
4422
 
    GROW;
4423
 
    /*
4424
 
     * Accelerated common case where input don't need to be
4425
 
     * modified before passing it to the handler.
4426
 
     */
4427
 
    if (!cdata) {
4428
 
        in = ctxt->input->cur;
4429
 
        do {
4430
 
get_more_space:
4431
 
            while (*in == 0x20) { in++; ctxt->input->col++; }
4432
 
            if (*in == 0xA) {
4433
 
                do {
4434
 
                    ctxt->input->line++; ctxt->input->col = 1;
4435
 
                    in++;
4436
 
                } while (*in == 0xA);
4437
 
                goto get_more_space;
4438
 
            }
4439
 
            if (*in == '<') {
4440
 
                nbchar = in - ctxt->input->cur;
4441
 
                if (nbchar > 0) {
4442
 
                    const xmlChar *tmp = ctxt->input->cur;
4443
 
                    ctxt->input->cur = in;
4444
 
 
4445
 
                    if ((ctxt->sax != NULL) &&
4446
 
                        (ctxt->sax->ignorableWhitespace !=
4447
 
                         ctxt->sax->characters)) {
4448
 
                        if (areBlanks(ctxt, tmp, nbchar, 1)) {
4449
 
                            if (ctxt->sax->ignorableWhitespace != NULL)
4450
 
                                ctxt->sax->ignorableWhitespace(ctxt->userData,
4451
 
                                                       tmp, nbchar);
4452
 
                        } else {
4453
 
                            if (ctxt->sax->characters != NULL)
4454
 
                                ctxt->sax->characters(ctxt->userData,
4455
 
                                                      tmp, nbchar);
4456
 
                            if (*ctxt->space == -1)
4457
 
                                *ctxt->space = -2;
4458
 
                        }
4459
 
                    } else if ((ctxt->sax != NULL) &&
4460
 
                               (ctxt->sax->characters != NULL)) {
4461
 
                        ctxt->sax->characters(ctxt->userData,
4462
 
                                              tmp, nbchar);
4463
 
                    }
4464
 
                }
4465
 
                return;
4466
 
            }
4467
 
 
4468
 
get_more:
4469
 
            ccol = ctxt->input->col;
4470
 
            while (test_char_data[*in]) {
4471
 
                in++;
4472
 
                ccol++;
4473
 
            }
4474
 
            ctxt->input->col = ccol;
4475
 
            if (*in == 0xA) {
4476
 
                do {
4477
 
                    ctxt->input->line++; ctxt->input->col = 1;
4478
 
                    in++;
4479
 
                } while (*in == 0xA);
4480
 
                goto get_more;
4481
 
            }
4482
 
            if (*in == ']') {
4483
 
                if ((in[1] == ']') && (in[2] == '>')) {
4484
 
                    xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
4485
 
                    ctxt->input->cur = in;
4486
 
                    return;
4487
 
                }
4488
 
                in++;
4489
 
                ctxt->input->col++;
4490
 
                goto get_more;
4491
 
            }
4492
 
            nbchar = in - ctxt->input->cur;
4493
 
            if (nbchar > 0) {
4494
 
                if ((ctxt->sax != NULL) &&
4495
 
                    (ctxt->sax->ignorableWhitespace !=
4496
 
                     ctxt->sax->characters) &&
4497
 
                    (IS_BLANK_CH(*ctxt->input->cur))) {
4498
 
                    const xmlChar *tmp = ctxt->input->cur;
4499
 
                    ctxt->input->cur = in;
4500
 
 
4501
 
                    if (areBlanks(ctxt, tmp, nbchar, 0)) {
4502
 
                        if (ctxt->sax->ignorableWhitespace != NULL)
4503
 
                            ctxt->sax->ignorableWhitespace(ctxt->userData,
4504
 
                                                           tmp, nbchar);
4505
 
                    } else {
4506
 
                        if (ctxt->sax->characters != NULL)
4507
 
                            ctxt->sax->characters(ctxt->userData,
4508
 
                                                  tmp, nbchar);
4509
 
                        if (*ctxt->space == -1)
4510
 
                            *ctxt->space = -2;
4511
 
                    }
4512
 
                    line = ctxt->input->line;
4513
 
                    col = ctxt->input->col;
4514
 
                } else if (ctxt->sax != NULL) {
4515
 
                    if (ctxt->sax->characters != NULL)
4516
 
                        ctxt->sax->characters(ctxt->userData,
4517
 
                                              ctxt->input->cur, nbchar);
4518
 
                    line = ctxt->input->line;
4519
 
                    col = ctxt->input->col;
4520
 
                }
4521
 
                /* something really bad happened in the SAX callback */
4522
 
                if (ctxt->instate != XML_PARSER_CONTENT)
4523
 
                    return;
4524
 
            }
4525
 
            ctxt->input->cur = in;
4526
 
            if (*in == 0xD) {
4527
 
                in++;
4528
 
                if (*in == 0xA) {
4529
 
                    ctxt->input->cur = in;
4530
 
                    in++;
4531
 
                    ctxt->input->line++; ctxt->input->col = 1;
4532
 
                    continue; /* while */
4533
 
                }
4534
 
                in--;
4535
 
            }
4536
 
            if (*in == '<') {
4537
 
                return;
4538
 
            }
4539
 
            if (*in == '&') {
4540
 
                return;
4541
 
            }
4542
 
            SHRINK;
4543
 
            GROW;
4544
 
            if (ctxt->instate == XML_PARSER_EOF)
4545
 
                return;
4546
 
            in = ctxt->input->cur;
4547
 
        } while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09));
4548
 
        nbchar = 0;
4549
 
    }
4550
 
    ctxt->input->line = line;
4551
 
    ctxt->input->col = col;
4552
 
    xmlParseCharDataComplex(ctxt, cdata);
4553
 
}
4554
 
 
4555
 
/**
4556
 
 * xmlParseCharDataComplex:
4557
 
 * @ctxt:  an XML parser context
4558
 
 * @cdata:  int indicating whether we are within a CDATA section
4559
 
 *
4560
 
 * parse a CharData section.this is the fallback function
4561
 
 * of xmlParseCharData() when the parsing requires handling
4562
 
 * of non-ASCII characters.
4563
 
 */
4564
 
static void
4565
 
xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata) {
4566
 
    xmlChar buf[XML_PARSER_BIG_BUFFER_SIZE + 5];
4567
 
    int nbchar = 0;
4568
 
    int cur, l;
4569
 
    int count = 0;
4570
 
 
4571
 
    SHRINK;
4572
 
    GROW;
4573
 
    cur = CUR_CHAR(l);
4574
 
    while ((cur != '<') && /* checked */
4575
 
           (cur != '&') &&
4576
 
           (IS_CHAR(cur))) /* test also done in xmlCurrentChar() */ {
4577
 
        if ((cur == ']') && (NXT(1) == ']') &&
4578
 
            (NXT(2) == '>')) {
4579
 
            if (cdata) break;
4580
 
            else {
4581
 
                xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
4582
 
            }
4583
 
        }
4584
 
        COPY_BUF(l,buf,nbchar,cur);
4585
 
        if (nbchar >= XML_PARSER_BIG_BUFFER_SIZE) {
4586
 
            buf[nbchar] = 0;
4587
 
 
4588
 
            /*
4589
 
             * OK the segment is to be consumed as chars.
4590
 
             */
4591
 
            if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
4592
 
                if (areBlanks(ctxt, buf, nbchar, 0)) {
4593
 
                    if (ctxt->sax->ignorableWhitespace != NULL)
4594
 
                        ctxt->sax->ignorableWhitespace(ctxt->userData,
4595
 
                                                       buf, nbchar);
4596
 
                } else {
4597
 
                    if (ctxt->sax->characters != NULL)
4598
 
                        ctxt->sax->characters(ctxt->userData, buf, nbchar);
4599
 
                    if ((ctxt->sax->characters !=
4600
 
                         ctxt->sax->ignorableWhitespace) &&
4601
 
                        (*ctxt->space == -1))
4602
 
                        *ctxt->space = -2;
4603
 
                }
4604
 
            }
4605
 
            nbchar = 0;
4606
 
            /* something really bad happened in the SAX callback */
4607
 
            if (ctxt->instate != XML_PARSER_CONTENT)
4608
 
                return;
4609
 
        }
4610
 
        count++;
4611
 
        if (count > 50) {
4612
 
            GROW;
4613
 
            count = 0;
4614
 
            if (ctxt->instate == XML_PARSER_EOF)
4615
 
                return;
4616
 
        }
4617
 
        NEXTL(l);
4618
 
        cur = CUR_CHAR(l);
4619
 
    }
4620
 
    if (nbchar != 0) {
4621
 
        buf[nbchar] = 0;
4622
 
        /*
4623
 
         * OK the segment is to be consumed as chars.
4624
 
         */
4625
 
        if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
4626
 
            if (areBlanks(ctxt, buf, nbchar, 0)) {
4627
 
                if (ctxt->sax->ignorableWhitespace != NULL)
4628
 
                    ctxt->sax->ignorableWhitespace(ctxt->userData, buf, nbchar);
4629
 
            } else {
4630
 
                if (ctxt->sax->characters != NULL)
4631
 
                    ctxt->sax->characters(ctxt->userData, buf, nbchar);
4632
 
                if ((ctxt->sax->characters != ctxt->sax->ignorableWhitespace) &&
4633
 
                    (*ctxt->space == -1))
4634
 
                    *ctxt->space = -2;
4635
 
            }
4636
 
        }
4637
 
    }
4638
 
    if ((cur != 0) && (!IS_CHAR(cur))) {
4639
 
        /* Generate the error and skip the offending character */
4640
 
        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
4641
 
                          "PCDATA invalid Char value %d\n",
4642
 
                          cur);
4643
 
        NEXTL(l);
4644
 
    }
4645
 
}
4646
 
 
4647
 
/**
4648
 
 * xmlParseExternalID:
4649
 
 * @ctxt:  an XML parser context
4650
 
 * @publicID:  a xmlChar** receiving PubidLiteral
4651
 
 * @strict: indicate whether we should restrict parsing to only
4652
 
 *          production [75], see NOTE below
4653
 
 *
4654
 
 * Parse an External ID or a Public ID
4655
 
 *
4656
 
 * NOTE: Productions [75] and [83] interact badly since [75] can generate
4657
 
 *       'PUBLIC' S PubidLiteral S SystemLiteral
4658
 
 *
4659
 
 * [75] ExternalID ::= 'SYSTEM' S SystemLiteral
4660
 
 *                   | 'PUBLIC' S PubidLiteral S SystemLiteral
4661
 
 *
4662
 
 * [83] PublicID ::= 'PUBLIC' S PubidLiteral
4663
 
 *
4664
 
 * Returns the function returns SystemLiteral and in the second
4665
 
 *                case publicID receives PubidLiteral, is strict is off
4666
 
 *                it is possible to return NULL and have publicID set.
4667
 
 */
4668
 
 
4669
 
xmlChar *
4670
 
xmlParseExternalID(xmlParserCtxtPtr ctxt, xmlChar **publicID, int strict) {
4671
 
    xmlChar *URI = NULL;
4672
 
 
4673
 
    SHRINK;
4674
 
 
4675
 
    *publicID = NULL;
4676
 
    if (CMP6(CUR_PTR, 'S', 'Y', 'S', 'T', 'E', 'M')) {
4677
 
        SKIP(6);
4678
 
        if (!IS_BLANK_CH(CUR)) {
4679
 
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4680
 
                           "Space required after 'SYSTEM'\n");
4681
 
        }
4682
 
        SKIP_BLANKS;
4683
 
        URI = xmlParseSystemLiteral(ctxt);
4684
 
        if (URI == NULL) {
4685
 
            xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
4686
 
        }
4687
 
    } else if (CMP6(CUR_PTR, 'P', 'U', 'B', 'L', 'I', 'C')) {
4688
 
        SKIP(6);
4689
 
        if (!IS_BLANK_CH(CUR)) {
4690
 
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4691
 
                    "Space required after 'PUBLIC'\n");
4692
 
        }
4693
 
        SKIP_BLANKS;
4694
 
        *publicID = xmlParsePubidLiteral(ctxt);
4695
 
        if (*publicID == NULL) {
4696
 
            xmlFatalErr(ctxt, XML_ERR_PUBID_REQUIRED, NULL);
4697
 
        }
4698
 
        if (strict) {
4699
 
            /*
4700
 
             * We don't handle [83] so "S SystemLiteral" is required.
4701
 
             */
4702
 
            if (!IS_BLANK_CH(CUR)) {
4703
 
                xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
4704
 
                        "Space required after the Public Identifier\n");
4705
 
            }
4706
 
        } else {
4707
 
            /*
4708
 
             * We handle [83] so we return immediately, if
4709
 
             * "S SystemLiteral" is not detected. From a purely parsing
4710
 
             * point of view that's a nice mess.
4711
 
             */
4712
 
            const xmlChar *ptr;
4713
 
            GROW;
4714
 
 
4715
 
            ptr = CUR_PTR;
4716
 
            if (!IS_BLANK_CH(*ptr)) return(NULL);
4717
 
 
4718
 
            while (IS_BLANK_CH(*ptr)) ptr++; /* TODO: dangerous, fix ! */
4719
 
            if ((*ptr != '\'') && (*ptr != '"')) return(NULL);
4720
 
        }
4721
 
        SKIP_BLANKS;
4722
 
        URI = xmlParseSystemLiteral(ctxt);
4723
 
        if (URI == NULL) {
4724
 
            xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL);
4725
 
        }
4726
 
    }
4727
 
    return(URI);
4728
 
}
4729
 
 
4730
 
/**
4731
 
 * xmlParseCommentComplex:
4732
 
 * @ctxt:  an XML parser context
4733
 
 * @buf:  the already parsed part of the buffer
4734
 
 * @len:  number of bytes filles in the buffer
4735
 
 * @size:  allocated size of the buffer
4736
 
 *
4737
 
 * Skip an XML (SGML) comment <!-- .... -->
4738
 
 *  The spec says that "For compatibility, the string "--" (double-hyphen)
4739
 
 *  must not occur within comments. "
4740
 
 * This is the slow routine in case the accelerator for ascii didn't work
4741
 
 *
4742
 
 * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
4743
 
 */
4744
 
static void
4745
 
xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf,
4746
 
                       size_t len, size_t size) {
4747
 
    int q, ql;
4748
 
    int r, rl;
4749
 
    int cur, l;
4750
 
    size_t count = 0;
4751
 
    int inputid;
4752
 
 
4753
 
    inputid = ctxt->input->id;
4754
 
 
4755
 
    if (buf == NULL) {
4756
 
        len = 0;
4757
 
        size = XML_PARSER_BUFFER_SIZE;
4758
 
        buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
4759
 
        if (buf == NULL) {
4760
 
            xmlErrMemory(ctxt, NULL);
4761
 
            return;
4762
 
        }
4763
 
    }
4764
 
    GROW;       /* Assure there's enough input data */
4765
 
    q = CUR_CHAR(ql);
4766
 
    if (q == 0)
4767
 
        goto not_terminated;
4768
 
    if (!IS_CHAR(q)) {
4769
 
        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
4770
 
                          "xmlParseComment: invalid xmlChar value %d\n",
4771
 
                          q);
4772
 
        xmlFree (buf);
4773
 
        return;
4774
 
    }
4775
 
    NEXTL(ql);
4776
 
    r = CUR_CHAR(rl);
4777
 
    if (r == 0)
4778
 
        goto not_terminated;
4779
 
    if (!IS_CHAR(r)) {
4780
 
        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
4781
 
                          "xmlParseComment: invalid xmlChar value %d\n",
4782
 
                          q);
4783
 
        xmlFree (buf);
4784
 
        return;
4785
 
    }
4786
 
    NEXTL(rl);
4787
 
    cur = CUR_CHAR(l);
4788
 
    if (cur == 0)
4789
 
        goto not_terminated;
4790
 
    while (IS_CHAR(cur) && /* checked */
4791
 
           ((cur != '>') ||
4792
 
            (r != '-') || (q != '-'))) {
4793
 
        if ((r == '-') && (q == '-')) {
4794
 
            xmlFatalErr(ctxt, XML_ERR_HYPHEN_IN_COMMENT, NULL);
4795
 
        }
4796
 
        if ((len > XML_MAX_TEXT_LENGTH) &&
4797
 
            ((ctxt->options & XML_PARSE_HUGE) == 0)) {
4798
 
            xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
4799
 
                         "Comment too big found", NULL);
4800
 
            xmlFree (buf);
4801
 
            return;
4802
 
        }
4803
 
        if (len + 5 >= size) {
4804
 
            xmlChar *new_buf;
4805
 
            size_t new_size;
4806
 
 
4807
 
            new_size = size * 2;
4808
 
            new_buf = (xmlChar *) xmlRealloc(buf, new_size);
4809
 
            if (new_buf == NULL) {
4810
 
                xmlFree (buf);
4811
 
                xmlErrMemory(ctxt, NULL);
4812
 
                return;
4813
 
            }
4814
 
            buf = new_buf;
4815
 
            size = new_size;
4816
 
        }
4817
 
        COPY_BUF(ql,buf,len,q);
4818
 
        q = r;
4819
 
        ql = rl;
4820
 
        r = cur;
4821
 
        rl = l;
4822
 
 
4823
 
        count++;
4824
 
        if (count > 50) {
4825
 
            GROW;
4826
 
            count = 0;
4827
 
            if (ctxt->instate == XML_PARSER_EOF) {
4828
 
                xmlFree(buf);
4829
 
                return;
4830
 
            }
4831
 
        }
4832
 
        NEXTL(l);
4833
 
        cur = CUR_CHAR(l);
4834
 
        if (cur == 0) {
4835
 
            SHRINK;
4836
 
            GROW;
4837
 
            cur = CUR_CHAR(l);
4838
 
        }
4839
 
    }
4840
 
    buf[len] = 0;
4841
 
    if (cur == 0) {
4842
 
        xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
4843
 
                             "Comment not terminated \n<!--%.50s\n", buf);
4844
 
    } else if (!IS_CHAR(cur)) {
4845
 
        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
4846
 
                          "xmlParseComment: invalid xmlChar value %d\n",
4847
 
                          cur);
4848
 
    } else {
4849
 
        if (inputid != ctxt->input->id) {
4850
 
            xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
4851
 
                "Comment doesn't start and stop in the same entity\n");
4852
 
        }
4853
 
        NEXT;
4854
 
        if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
4855
 
            (!ctxt->disableSAX))
4856
 
            ctxt->sax->comment(ctxt->userData, buf);
4857
 
    }
4858
 
    xmlFree(buf);
4859
 
    return;
4860
 
not_terminated:
4861
 
    xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
4862
 
                         "Comment not terminated\n", NULL);
4863
 
    xmlFree(buf);
4864
 
    return;
4865
 
}
4866
 
 
4867
 
/**
4868
 
 * xmlParseComment:
4869
 
 * @ctxt:  an XML parser context
4870
 
 *
4871
 
 * Skip an XML (SGML) comment <!-- .... -->
4872
 
 *  The spec says that "For compatibility, the string "--" (double-hyphen)
4873
 
 *  must not occur within comments. "
4874
 
 *
4875
 
 * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
4876
 
 */
4877
 
void
4878
 
xmlParseComment(xmlParserCtxtPtr ctxt) {
4879
 
    xmlChar *buf = NULL;
4880
 
    size_t size = XML_PARSER_BUFFER_SIZE;
4881
 
    size_t len = 0;
4882
 
    xmlParserInputState state;
4883
 
    const xmlChar *in;
4884
 
    size_t nbchar = 0;
4885
 
    int ccol;
4886
 
    int inputid;
4887
 
 
4888
 
    /*
4889
 
     * Check that there is a comment right here.
4890
 
     */
4891
 
    if ((RAW != '<') || (NXT(1) != '!') ||
4892
 
        (NXT(2) != '-') || (NXT(3) != '-')) return;
4893
 
    state = ctxt->instate;
4894
 
    ctxt->instate = XML_PARSER_COMMENT;
4895
 
    inputid = ctxt->input->id;
4896
 
    SKIP(4);
4897
 
    SHRINK;
4898
 
    GROW;
4899
 
 
4900
 
    /*
4901
 
     * Accelerated common case where input don't need to be
4902
 
     * modified before passing it to the handler.
4903
 
     */
4904
 
    in = ctxt->input->cur;
4905
 
    do {
4906
 
        if (*in == 0xA) {
4907
 
            do {
4908
 
                ctxt->input->line++; ctxt->input->col = 1;
4909
 
                in++;
4910
 
            } while (*in == 0xA);
4911
 
        }
4912
 
get_more:
4913
 
        ccol = ctxt->input->col;
4914
 
        while (((*in > '-') && (*in <= 0x7F)) ||
4915
 
               ((*in >= 0x20) && (*in < '-')) ||
4916
 
               (*in == 0x09)) {
4917
 
                    in++;
4918
 
                    ccol++;
4919
 
        }
4920
 
        ctxt->input->col = ccol;
4921
 
        if (*in == 0xA) {
4922
 
            do {
4923
 
                ctxt->input->line++; ctxt->input->col = 1;
4924
 
                in++;
4925
 
            } while (*in == 0xA);
4926
 
            goto get_more;
4927
 
        }
4928
 
        nbchar = in - ctxt->input->cur;
4929
 
        /*
4930
 
         * save current set of data
4931
 
         */
4932
 
        if (nbchar > 0) {
4933
 
            if ((ctxt->sax != NULL) &&
4934
 
                (ctxt->sax->comment != NULL)) {
4935
 
                if (buf == NULL) {
4936
 
                    if ((*in == '-') && (in[1] == '-'))
4937
 
                        size = nbchar + 1;
4938
 
                    else
4939
 
                        size = XML_PARSER_BUFFER_SIZE + nbchar;
4940
 
                    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
4941
 
                    if (buf == NULL) {
4942
 
                        xmlErrMemory(ctxt, NULL);
4943
 
                        ctxt->instate = state;
4944
 
                        return;
4945
 
                    }
4946
 
                    len = 0;
4947
 
                } else if (len + nbchar + 1 >= size) {
4948
 
                    xmlChar *new_buf;
4949
 
                    size  += len + nbchar + XML_PARSER_BUFFER_SIZE;
4950
 
                    new_buf = (xmlChar *) xmlRealloc(buf,
4951
 
                                                     size * sizeof(xmlChar));
4952
 
                    if (new_buf == NULL) {
4953
 
                        xmlFree (buf);
4954
 
                        xmlErrMemory(ctxt, NULL);
4955
 
                        ctxt->instate = state;
4956
 
                        return;
4957
 
                    }
4958
 
                    buf = new_buf;
4959
 
                }
4960
 
                memcpy(&buf[len], ctxt->input->cur, nbchar);
4961
 
                len += nbchar;
4962
 
                buf[len] = 0;
4963
 
            }
4964
 
        }
4965
 
        if ((len > XML_MAX_TEXT_LENGTH) &&
4966
 
            ((ctxt->options & XML_PARSE_HUGE) == 0)) {
4967
 
            xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
4968
 
                         "Comment too big found", NULL);
4969
 
            xmlFree (buf);
4970
 
            return;
4971
 
        }
4972
 
        ctxt->input->cur = in;
4973
 
        if (*in == 0xA) {
4974
 
            in++;
4975
 
            ctxt->input->line++; ctxt->input->col = 1;
4976
 
        }
4977
 
        if (*in == 0xD) {
4978
 
            in++;
4979
 
            if (*in == 0xA) {
4980
 
                ctxt->input->cur = in;
4981
 
                in++;
4982
 
                ctxt->input->line++; ctxt->input->col = 1;
4983
 
                continue; /* while */
4984
 
            }
4985
 
            in--;
4986
 
        }
4987
 
        SHRINK;
4988
 
        GROW;
4989
 
        if (ctxt->instate == XML_PARSER_EOF) {
4990
 
            xmlFree(buf);
4991
 
            return;
4992
 
        }
4993
 
        in = ctxt->input->cur;
4994
 
        if (*in == '-') {
4995
 
            if (in[1] == '-') {
4996
 
                if (in[2] == '>') {
4997
 
                    if (ctxt->input->id != inputid) {
4998
 
                        xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
4999
 
                        "comment doesn't start and stop in the same entity\n");
5000
 
                    }
5001
 
                    SKIP(3);
5002
 
                    if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
5003
 
                        (!ctxt->disableSAX)) {
5004
 
                        if (buf != NULL)
5005
 
                            ctxt->sax->comment(ctxt->userData, buf);
5006
 
                        else
5007
 
                            ctxt->sax->comment(ctxt->userData, BAD_CAST "");
5008
 
                    }
5009
 
                    if (buf != NULL)
5010
 
                        xmlFree(buf);
5011
 
                    if (ctxt->instate != XML_PARSER_EOF)
5012
 
                        ctxt->instate = state;
5013
 
                    return;
5014
 
                }
5015
 
                if (buf != NULL) {
5016
 
                    xmlFatalErrMsgStr(ctxt, XML_ERR_HYPHEN_IN_COMMENT,
5017
 
                                      "Double hyphen within comment: "
5018
 
                                      "<!--%.50s\n",
5019
 
                                      buf);
5020
 
                } else
5021
 
                    xmlFatalErrMsgStr(ctxt, XML_ERR_HYPHEN_IN_COMMENT,
5022
 
                                      "Double hyphen within comment\n", NULL);
5023
 
                in++;
5024
 
                ctxt->input->col++;
5025
 
            }
5026
 
            in++;
5027
 
            ctxt->input->col++;
5028
 
            goto get_more;
5029
 
        }
5030
 
    } while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09));
5031
 
    xmlParseCommentComplex(ctxt, buf, len, size);
5032
 
    ctxt->instate = state;
5033
 
    return;
5034
 
}
5035
 
 
5036
 
 
5037
 
/**
5038
 
 * xmlParsePITarget:
5039
 
 * @ctxt:  an XML parser context
5040
 
 *
5041
 
 * parse the name of a PI
5042
 
 *
5043
 
 * [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
5044
 
 *
5045
 
 * Returns the PITarget name or NULL
5046
 
 */
5047
 
 
5048
 
const xmlChar *
5049
 
xmlParsePITarget(xmlParserCtxtPtr ctxt) {
5050
 
    const xmlChar *name;
5051
 
 
5052
 
    name = xmlParseName(ctxt);
5053
 
    if ((name != NULL) &&
5054
 
        ((name[0] == 'x') || (name[0] == 'X')) &&
5055
 
        ((name[1] == 'm') || (name[1] == 'M')) &&
5056
 
        ((name[2] == 'l') || (name[2] == 'L'))) {
5057
 
        int i;
5058
 
        if ((name[0] == 'x') && (name[1] == 'm') &&
5059
 
            (name[2] == 'l') && (name[3] == 0)) {
5060
 
            xmlFatalErrMsg(ctxt, XML_ERR_RESERVED_XML_NAME,
5061
 
                 "XML declaration allowed only at the start of the document\n");
5062
 
            return(name);
5063
 
        } else if (name[3] == 0) {
5064
 
            xmlFatalErr(ctxt, XML_ERR_RESERVED_XML_NAME, NULL);
5065
 
            return(name);
5066
 
        }
5067
 
        for (i = 0;;i++) {
5068
 
            if (xmlW3CPIs[i] == NULL) break;
5069
 
            if (xmlStrEqual(name, (const xmlChar *)xmlW3CPIs[i]))
5070
 
                return(name);
5071
 
        }
5072
 
        xmlWarningMsg(ctxt, XML_ERR_RESERVED_XML_NAME,
5073
 
                      "xmlParsePITarget: invalid name prefix 'xml'\n",
5074
 
                      NULL, NULL);
5075
 
    }
5076
 
    if ((name != NULL) && (xmlStrchr(name, ':') != NULL)) {
5077
 
        xmlNsErr(ctxt, XML_NS_ERR_COLON,
5078
 
                 "colon are forbidden from PI names '%s'\n", name, NULL, NULL);
5079
 
    }
5080
 
    return(name);
5081
 
}
5082
 
 
5083
 
#ifdef LIBXML_CATALOG_ENABLED
5084
 
/**
5085
 
 * xmlParseCatalogPI:
5086
 
 * @ctxt:  an XML parser context
5087
 
 * @catalog:  the PI value string
5088
 
 *
5089
 
 * parse an XML Catalog Processing Instruction.
5090
 
 *
5091
 
 * <?oasis-xml-catalog catalog="http://example.com/catalog.xml"?>
5092
 
 *
5093
 
 * Occurs only if allowed by the user and if happening in the Misc
5094
 
 * part of the document before any doctype informations
5095
 
 * This will add the given catalog to the parsing context in order
5096
 
 * to be used if there is a resolution need further down in the document
5097
 
 */
5098
 
 
5099
 
static void
5100
 
xmlParseCatalogPI(xmlParserCtxtPtr ctxt, const xmlChar *catalog) {
5101
 
    xmlChar *URL = NULL;
5102
 
    const xmlChar *tmp, *base;
5103
 
    xmlChar marker;
5104
 
 
5105
 
    tmp = catalog;
5106
 
    while (IS_BLANK_CH(*tmp)) tmp++;
5107
 
    if (xmlStrncmp(tmp, BAD_CAST"catalog", 7))
5108
 
        goto error;
5109
 
    tmp += 7;
5110
 
    while (IS_BLANK_CH(*tmp)) tmp++;
5111
 
    if (*tmp != '=') {
5112
 
        return;
5113
 
    }
5114
 
    tmp++;
5115
 
    while (IS_BLANK_CH(*tmp)) tmp++;
5116
 
    marker = *tmp;
5117
 
    if ((marker != '\'') && (marker != '"'))
5118
 
        goto error;
5119
 
    tmp++;
5120
 
    base = tmp;
5121
 
    while ((*tmp != 0) && (*tmp != marker)) tmp++;
5122
 
    if (*tmp == 0)
5123
 
        goto error;
5124
 
    URL = xmlStrndup(base, tmp - base);
5125
 
    tmp++;
5126
 
    while (IS_BLANK_CH(*tmp)) tmp++;
5127
 
    if (*tmp != 0)
5128
 
        goto error;
5129
 
 
5130
 
    if (URL != NULL) {
5131
 
        ctxt->catalogs = xmlCatalogAddLocal(ctxt->catalogs, URL);
5132
 
        xmlFree(URL);
5133
 
    }
5134
 
    return;
5135
 
 
5136
 
error:
5137
 
    xmlWarningMsg(ctxt, XML_WAR_CATALOG_PI,
5138
 
                  "Catalog PI syntax error: %s\n",
5139
 
                  catalog, NULL);
5140
 
    if (URL != NULL)
5141
 
        xmlFree(URL);
5142
 
}
5143
 
#endif
5144
 
 
5145
 
/**
5146
 
 * xmlParsePI:
5147
 
 * @ctxt:  an XML parser context
5148
 
 *
5149
 
 * parse an XML Processing Instruction.
5150
 
 *
5151
 
 * [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
5152
 
 *
5153
 
 * The processing is transfered to SAX once parsed.
5154
 
 */
5155
 
 
5156
 
void
5157
 
xmlParsePI(xmlParserCtxtPtr ctxt) {
5158
 
    xmlChar *buf = NULL;
5159
 
    size_t len = 0;
5160
 
    size_t size = XML_PARSER_BUFFER_SIZE;
5161
 
    int cur, l;
5162
 
    const xmlChar *target;
5163
 
    xmlParserInputState state;
5164
 
    int count = 0;
5165
 
 
5166
 
    if ((RAW == '<') && (NXT(1) == '?')) {
5167
 
        xmlParserInputPtr input = ctxt->input;
5168
 
        state = ctxt->instate;
5169
 
        ctxt->instate = XML_PARSER_PI;
5170
 
        /*
5171
 
         * this is a Processing Instruction.
5172
 
         */
5173
 
        SKIP(2);
5174
 
        SHRINK;
5175
 
 
5176
 
        /*
5177
 
         * Parse the target name and check for special support like
5178
 
         * namespace.
5179
 
         */
5180
 
        target = xmlParsePITarget(ctxt);
5181
 
        if (target != NULL) {
5182
 
            if ((RAW == '?') && (NXT(1) == '>')) {
5183
 
                if (input != ctxt->input) {
5184
 
                    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
5185
 
            "PI declaration doesn't start and stop in the same entity\n");
5186
 
                }
5187
 
                SKIP(2);
5188
 
 
5189
 
                /*
5190
 
                 * SAX: PI detected.
5191
 
                 */
5192
 
                if ((ctxt->sax) && (!ctxt->disableSAX) &&
5193
 
                    (ctxt->sax->processingInstruction != NULL))
5194
 
                    ctxt->sax->processingInstruction(ctxt->userData,
5195
 
                                                     target, NULL);
5196
 
                if (ctxt->instate != XML_PARSER_EOF)
5197
 
                    ctxt->instate = state;
5198
 
                return;
5199
 
            }
5200
 
            buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
5201
 
            if (buf == NULL) {
5202
 
                xmlErrMemory(ctxt, NULL);
5203
 
                ctxt->instate = state;
5204
 
                return;
5205
 
            }
5206
 
            cur = CUR;
5207
 
            if (!IS_BLANK(cur)) {
5208
 
                xmlFatalErrMsgStr(ctxt, XML_ERR_SPACE_REQUIRED,
5209
 
                          "ParsePI: PI %s space expected\n", target);
5210
 
            }
5211
 
            SKIP_BLANKS;
5212
 
            cur = CUR_CHAR(l);
5213
 
            while (IS_CHAR(cur) && /* checked */
5214
 
                   ((cur != '?') || (NXT(1) != '>'))) {
5215
 
                if (len + 5 >= size) {
5216
 
                    xmlChar *tmp;
5217
 
                    size_t new_size = size * 2;
5218
 
                    tmp = (xmlChar *) xmlRealloc(buf, new_size);
5219
 
                    if (tmp == NULL) {
5220
 
                        xmlErrMemory(ctxt, NULL);
5221
 
                        xmlFree(buf);
5222
 
                        ctxt->instate = state;
5223
 
                        return;
5224
 
                    }
5225
 
                    buf = tmp;
5226
 
                    size = new_size;
5227
 
                }
5228
 
                count++;
5229
 
                if (count > 50) {
5230
 
                    GROW;
5231
 
                    if (ctxt->instate == XML_PARSER_EOF) {
5232
 
                        xmlFree(buf);
5233
 
                        return;
5234
 
                    }
5235
 
                    count = 0;
5236
 
                    if ((len > XML_MAX_TEXT_LENGTH) &&
5237
 
                        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
5238
 
                        xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
5239
 
                                          "PI %s too big found", target);
5240
 
                        xmlFree(buf);
5241
 
                        ctxt->instate = state;
5242
 
                        return;
5243
 
                    }
5244
 
                }
5245
 
                COPY_BUF(l,buf,len,cur);
5246
 
                NEXTL(l);
5247
 
                cur = CUR_CHAR(l);
5248
 
                if (cur == 0) {
5249
 
                    SHRINK;
5250
 
                    GROW;
5251
 
                    cur = CUR_CHAR(l);
5252
 
                }
5253
 
            }
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
 
            buf[len] = 0;
5263
 
            if (cur != '?') {
5264
 
                xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
5265
 
                      "ParsePI: PI %s never end ...\n", target);
5266
 
            } else {
5267
 
                if (input != ctxt->input) {
5268
 
                    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5269
 
            "PI declaration doesn't start and stop in the same entity\n");
5270
 
                }
5271
 
                SKIP(2);
5272
 
 
5273
 
#ifdef LIBXML_CATALOG_ENABLED
5274
 
                if (((state == XML_PARSER_MISC) ||
5275
 
                     (state == XML_PARSER_START)) &&
5276
 
                    (xmlStrEqual(target, XML_CATALOG_PI))) {
5277
 
                    xmlCatalogAllow allow = xmlCatalogGetDefaults();
5278
 
                    if ((allow == XML_CATA_ALLOW_DOCUMENT) ||
5279
 
                        (allow == XML_CATA_ALLOW_ALL))
5280
 
                        xmlParseCatalogPI(ctxt, buf);
5281
 
                }
5282
 
#endif
5283
 
 
5284
 
 
5285
 
                /*
5286
 
                 * SAX: PI detected.
5287
 
                 */
5288
 
                if ((ctxt->sax) && (!ctxt->disableSAX) &&
5289
 
                    (ctxt->sax->processingInstruction != NULL))
5290
 
                    ctxt->sax->processingInstruction(ctxt->userData,
5291
 
                                                     target, buf);
5292
 
            }
5293
 
            xmlFree(buf);
5294
 
        } else {
5295
 
            xmlFatalErr(ctxt, XML_ERR_PI_NOT_STARTED, NULL);
5296
 
        }
5297
 
        if (ctxt->instate != XML_PARSER_EOF)
5298
 
            ctxt->instate = state;
5299
 
    }
5300
 
}
5301
 
 
5302
 
/**
5303
 
 * xmlParseNotationDecl:
5304
 
 * @ctxt:  an XML parser context
5305
 
 *
5306
 
 * parse a notation declaration
5307
 
 *
5308
 
 * [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID |  PublicID) S? '>'
5309
 
 *
5310
 
 * Hence there is actually 3 choices:
5311
 
 *     'PUBLIC' S PubidLiteral
5312
 
 *     'PUBLIC' S PubidLiteral S SystemLiteral
5313
 
 * and 'SYSTEM' S SystemLiteral
5314
 
 *
5315
 
 * See the NOTE on xmlParseExternalID().
5316
 
 */
5317
 
 
5318
 
void
5319
 
xmlParseNotationDecl(xmlParserCtxtPtr ctxt) {
5320
 
    const xmlChar *name;
5321
 
    xmlChar *Pubid;
5322
 
    xmlChar *Systemid;
5323
 
 
5324
 
    if (CMP10(CUR_PTR, '<', '!', 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
5325
 
        xmlParserInputPtr input = ctxt->input;
5326
 
        SHRINK;
5327
 
        SKIP(10);
5328
 
        if (!IS_BLANK_CH(CUR)) {
5329
 
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5330
 
                           "Space required after '<!NOTATION'\n");
5331
 
            return;
5332
 
        }
5333
 
        SKIP_BLANKS;
5334
 
 
5335
 
        name = xmlParseName(ctxt);
5336
 
        if (name == NULL) {
5337
 
            xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
5338
 
            return;
5339
 
        }
5340
 
        if (!IS_BLANK_CH(CUR)) {
5341
 
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5342
 
                     "Space required after the NOTATION name'\n");
5343
 
            return;
5344
 
        }
5345
 
        if (xmlStrchr(name, ':') != NULL) {
5346
 
            xmlNsErr(ctxt, XML_NS_ERR_COLON,
5347
 
                     "colon are forbidden from notation names '%s'\n",
5348
 
                     name, NULL, NULL);
5349
 
        }
5350
 
        SKIP_BLANKS;
5351
 
 
5352
 
        /*
5353
 
         * Parse the IDs.
5354
 
         */
5355
 
        Systemid = xmlParseExternalID(ctxt, &Pubid, 0);
5356
 
        SKIP_BLANKS;
5357
 
 
5358
 
        if (RAW == '>') {
5359
 
            if (input != ctxt->input) {
5360
 
                xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5361
 
        "Notation declaration doesn't start and stop in the same entity\n");
5362
 
            }
5363
 
            NEXT;
5364
 
            if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
5365
 
                (ctxt->sax->notationDecl != NULL))
5366
 
                ctxt->sax->notationDecl(ctxt->userData, name, Pubid, Systemid);
5367
 
        } else {
5368
 
            xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
5369
 
        }
5370
 
        if (Systemid != NULL) xmlFree(Systemid);
5371
 
        if (Pubid != NULL) xmlFree(Pubid);
5372
 
    }
5373
 
}
5374
 
 
5375
 
/**
5376
 
 * xmlParseEntityDecl:
5377
 
 * @ctxt:  an XML parser context
5378
 
 *
5379
 
 * parse <!ENTITY declarations
5380
 
 *
5381
 
 * [70] EntityDecl ::= GEDecl | PEDecl
5382
 
 *
5383
 
 * [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
5384
 
 *
5385
 
 * [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
5386
 
 *
5387
 
 * [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
5388
 
 *
5389
 
 * [74] PEDef ::= EntityValue | ExternalID
5390
 
 *
5391
 
 * [76] NDataDecl ::= S 'NDATA' S Name
5392
 
 *
5393
 
 * [ VC: Notation Declared ]
5394
 
 * The Name must match the declared name of a notation.
5395
 
 */
5396
 
 
5397
 
void
5398
 
xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
5399
 
    const xmlChar *name = NULL;
5400
 
    xmlChar *value = NULL;
5401
 
    xmlChar *URI = NULL, *literal = NULL;
5402
 
    const xmlChar *ndata = NULL;
5403
 
    int isParameter = 0;
5404
 
    xmlChar *orig = NULL;
5405
 
    int skipped;
5406
 
 
5407
 
    /* GROW; done in the caller */
5408
 
    if (CMP8(CUR_PTR, '<', '!', 'E', 'N', 'T', 'I', 'T', 'Y')) {
5409
 
        xmlParserInputPtr input = ctxt->input;
5410
 
        SHRINK;
5411
 
        SKIP(8);
5412
 
        skipped = SKIP_BLANKS;
5413
 
        if (skipped == 0) {
5414
 
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5415
 
                           "Space required after '<!ENTITY'\n");
5416
 
        }
5417
 
 
5418
 
        if (RAW == '%') {
5419
 
            NEXT;
5420
 
            skipped = SKIP_BLANKS;
5421
 
            if (skipped == 0) {
5422
 
                xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5423
 
                               "Space required after '%'\n");
5424
 
            }
5425
 
            isParameter = 1;
5426
 
        }
5427
 
 
5428
 
        name = xmlParseName(ctxt);
5429
 
        if (name == NULL) {
5430
 
            xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
5431
 
                           "xmlParseEntityDecl: no name\n");
5432
 
            return;
5433
 
        }
5434
 
        if (xmlStrchr(name, ':') != NULL) {
5435
 
            xmlNsErr(ctxt, XML_NS_ERR_COLON,
5436
 
                     "colon are forbidden from entities names '%s'\n",
5437
 
                     name, NULL, NULL);
5438
 
        }
5439
 
        skipped = SKIP_BLANKS;
5440
 
        if (skipped == 0) {
5441
 
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5442
 
                           "Space required after the entity name\n");
5443
 
        }
5444
 
 
5445
 
        ctxt->instate = XML_PARSER_ENTITY_DECL;
5446
 
        /*
5447
 
         * handle the various case of definitions...
5448
 
         */
5449
 
        if (isParameter) {
5450
 
            if ((RAW == '"') || (RAW == '\'')) {
5451
 
                value = xmlParseEntityValue(ctxt, &orig);
5452
 
                if (value) {
5453
 
                    if ((ctxt->sax != NULL) &&
5454
 
                        (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
5455
 
                        ctxt->sax->entityDecl(ctxt->userData, name,
5456
 
                                    XML_INTERNAL_PARAMETER_ENTITY,
5457
 
                                    NULL, NULL, value);
5458
 
                }
5459
 
            } else {
5460
 
                URI = xmlParseExternalID(ctxt, &literal, 1);
5461
 
                if ((URI == NULL) && (literal == NULL)) {
5462
 
                    xmlFatalErr(ctxt, XML_ERR_VALUE_REQUIRED, NULL);
5463
 
                }
5464
 
                if (URI) {
5465
 
                    xmlURIPtr uri;
5466
 
 
5467
 
                    uri = xmlParseURI((const char *) URI);
5468
 
                    if (uri == NULL) {
5469
 
                        xmlErrMsgStr(ctxt, XML_ERR_INVALID_URI,
5470
 
                                     "Invalid URI: %s\n", URI);
5471
 
                        /*
5472
 
                         * This really ought to be a well formedness error
5473
 
                         * but the XML Core WG decided otherwise c.f. issue
5474
 
                         * E26 of the XML erratas.
5475
 
                         */
5476
 
                    } else {
5477
 
                        if (uri->fragment != NULL) {
5478
 
                            /*
5479
 
                             * Okay this is foolish to block those but not
5480
 
                             * invalid URIs.
5481
 
                             */
5482
 
                            xmlFatalErr(ctxt, XML_ERR_URI_FRAGMENT, NULL);
5483
 
                        } else {
5484
 
                            if ((ctxt->sax != NULL) &&
5485
 
                                (!ctxt->disableSAX) &&
5486
 
                                (ctxt->sax->entityDecl != NULL))
5487
 
                                ctxt->sax->entityDecl(ctxt->userData, name,
5488
 
                                            XML_EXTERNAL_PARAMETER_ENTITY,
5489
 
                                            literal, URI, NULL);
5490
 
                        }
5491
 
                        xmlFreeURI(uri);
5492
 
                    }
5493
 
                }
5494
 
            }
5495
 
        } else {
5496
 
            if ((RAW == '"') || (RAW == '\'')) {
5497
 
                value = xmlParseEntityValue(ctxt, &orig);
5498
 
                if ((ctxt->sax != NULL) &&
5499
 
                    (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
5500
 
                    ctxt->sax->entityDecl(ctxt->userData, name,
5501
 
                                XML_INTERNAL_GENERAL_ENTITY,
5502
 
                                NULL, NULL, value);
5503
 
                /*
5504
 
                 * For expat compatibility in SAX mode.
5505
 
                 */
5506
 
                if ((ctxt->myDoc == NULL) ||
5507
 
                    (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) {
5508
 
                    if (ctxt->myDoc == NULL) {
5509
 
                        ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
5510
 
                        if (ctxt->myDoc == NULL) {
5511
 
                            xmlErrMemory(ctxt, "New Doc failed");
5512
 
                            return;
5513
 
                        }
5514
 
                        ctxt->myDoc->properties = XML_DOC_INTERNAL;
5515
 
                    }
5516
 
                    if (ctxt->myDoc->intSubset == NULL)
5517
 
                        ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
5518
 
                                            BAD_CAST "fake", NULL, NULL);
5519
 
 
5520
 
                    xmlSAX2EntityDecl(ctxt, name, XML_INTERNAL_GENERAL_ENTITY,
5521
 
                                      NULL, NULL, value);
5522
 
                }
5523
 
            } else {
5524
 
                URI = xmlParseExternalID(ctxt, &literal, 1);
5525
 
                if ((URI == NULL) && (literal == NULL)) {
5526
 
                    xmlFatalErr(ctxt, XML_ERR_VALUE_REQUIRED, NULL);
5527
 
                }
5528
 
                if (URI) {
5529
 
                    xmlURIPtr uri;
5530
 
 
5531
 
                    uri = xmlParseURI((const char *)URI);
5532
 
                    if (uri == NULL) {
5533
 
                        xmlErrMsgStr(ctxt, XML_ERR_INVALID_URI,
5534
 
                                     "Invalid URI: %s\n", URI);
5535
 
                        /*
5536
 
                         * This really ought to be a well formedness error
5537
 
                         * but the XML Core WG decided otherwise c.f. issue
5538
 
                         * E26 of the XML erratas.
5539
 
                         */
5540
 
                    } else {
5541
 
                        if (uri->fragment != NULL) {
5542
 
                            /*
5543
 
                             * Okay this is foolish to block those but not
5544
 
                             * invalid URIs.
5545
 
                             */
5546
 
                            xmlFatalErr(ctxt, XML_ERR_URI_FRAGMENT, NULL);
5547
 
                        }
5548
 
                        xmlFreeURI(uri);
5549
 
                    }
5550
 
                }
5551
 
                if ((RAW != '>') && (!IS_BLANK_CH(CUR))) {
5552
 
                    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5553
 
                                   "Space required before 'NDATA'\n");
5554
 
                }
5555
 
                SKIP_BLANKS;
5556
 
                if (CMP5(CUR_PTR, 'N', 'D', 'A', 'T', 'A')) {
5557
 
                    SKIP(5);
5558
 
                    if (!IS_BLANK_CH(CUR)) {
5559
 
                        xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5560
 
                                       "Space required after 'NDATA'\n");
5561
 
                    }
5562
 
                    SKIP_BLANKS;
5563
 
                    ndata = xmlParseName(ctxt);
5564
 
                    if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
5565
 
                        (ctxt->sax->unparsedEntityDecl != NULL))
5566
 
                        ctxt->sax->unparsedEntityDecl(ctxt->userData, name,
5567
 
                                    literal, URI, ndata);
5568
 
                } else {
5569
 
                    if ((ctxt->sax != NULL) &&
5570
 
                        (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
5571
 
                        ctxt->sax->entityDecl(ctxt->userData, name,
5572
 
                                    XML_EXTERNAL_GENERAL_PARSED_ENTITY,
5573
 
                                    literal, URI, NULL);
5574
 
                    /*
5575
 
                     * For expat compatibility in SAX mode.
5576
 
                     * assuming the entity repalcement was asked for
5577
 
                     */
5578
 
                    if ((ctxt->replaceEntities != 0) &&
5579
 
                        ((ctxt->myDoc == NULL) ||
5580
 
                        (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE)))) {
5581
 
                        if (ctxt->myDoc == NULL) {
5582
 
                            ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
5583
 
                            if (ctxt->myDoc == NULL) {
5584
 
                                xmlErrMemory(ctxt, "New Doc failed");
5585
 
                                return;
5586
 
                            }
5587
 
                            ctxt->myDoc->properties = XML_DOC_INTERNAL;
5588
 
                        }
5589
 
 
5590
 
                        if (ctxt->myDoc->intSubset == NULL)
5591
 
                            ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
5592
 
                                                BAD_CAST "fake", NULL, NULL);
5593
 
                        xmlSAX2EntityDecl(ctxt, name,
5594
 
                                          XML_EXTERNAL_GENERAL_PARSED_ENTITY,
5595
 
                                          literal, URI, NULL);
5596
 
                    }
5597
 
                }
5598
 
            }
5599
 
        }
5600
 
        if (ctxt->instate == XML_PARSER_EOF)
5601
 
            return;
5602
 
        SKIP_BLANKS;
5603
 
        if (RAW != '>') {
5604
 
            xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_NOT_FINISHED,
5605
 
                    "xmlParseEntityDecl: entity %s not terminated\n", name);
5606
 
        } else {
5607
 
            if (input != ctxt->input) {
5608
 
                xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
5609
 
        "Entity declaration doesn't start and stop in the same entity\n");
5610
 
            }
5611
 
            NEXT;
5612
 
        }
5613
 
        if (orig != NULL) {
5614
 
            /*
5615
 
             * Ugly mechanism to save the raw entity value.
5616
 
             */
5617
 
            xmlEntityPtr cur = NULL;
5618
 
 
5619
 
            if (isParameter) {
5620
 
                if ((ctxt->sax != NULL) &&
5621
 
                    (ctxt->sax->getParameterEntity != NULL))
5622
 
                    cur = ctxt->sax->getParameterEntity(ctxt->userData, name);
5623
 
            } else {
5624
 
                if ((ctxt->sax != NULL) &&
5625
 
                    (ctxt->sax->getEntity != NULL))
5626
 
                    cur = ctxt->sax->getEntity(ctxt->userData, name);
5627
 
                if ((cur == NULL) && (ctxt->userData==ctxt)) {
5628
 
                    cur = xmlSAX2GetEntity(ctxt, name);
5629
 
                }
5630
 
            }
5631
 
            if (cur != NULL) {
5632
 
                if (cur->orig != NULL)
5633
 
                    xmlFree(orig);
5634
 
                else
5635
 
                    cur->orig = orig;
5636
 
            } else
5637
 
                xmlFree(orig);
5638
 
        }
5639
 
        if (value != NULL) xmlFree(value);
5640
 
        if (URI != NULL) xmlFree(URI);
5641
 
        if (literal != NULL) xmlFree(literal);
5642
 
    }
5643
 
}
5644
 
 
5645
 
/**
5646
 
 * xmlParseDefaultDecl:
5647
 
 * @ctxt:  an XML parser context
5648
 
 * @value:  Receive a possible fixed default value for the attribute
5649
 
 *
5650
 
 * Parse an attribute default declaration
5651
 
 *
5652
 
 * [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)
5653
 
 *
5654
 
 * [ VC: Required Attribute ]
5655
 
 * if the default declaration is the keyword #REQUIRED, then the
5656
 
 * attribute must be specified for all elements of the type in the
5657
 
 * attribute-list declaration.
5658
 
 *
5659
 
 * [ VC: Attribute Default Legal ]
5660
 
 * The declared default value must meet the lexical constraints of
5661
 
 * the declared attribute type c.f. xmlValidateAttributeDecl()
5662
 
 *
5663
 
 * [ VC: Fixed Attribute Default ]
5664
 
 * if an attribute has a default value declared with the #FIXED
5665
 
 * keyword, instances of that attribute must match the default value.
5666
 
 *
5667
 
 * [ WFC: No < in Attribute Values ]
5668
 
 * handled in xmlParseAttValue()
5669
 
 *
5670
 
 * returns: XML_ATTRIBUTE_NONE, XML_ATTRIBUTE_REQUIRED, XML_ATTRIBUTE_IMPLIED
5671
 
 *          or XML_ATTRIBUTE_FIXED.
5672
 
 */
5673
 
 
5674
 
int
5675
 
xmlParseDefaultDecl(xmlParserCtxtPtr ctxt, xmlChar **value) {
5676
 
    int val;
5677
 
    xmlChar *ret;
5678
 
 
5679
 
    *value = NULL;
5680
 
    if (CMP9(CUR_PTR, '#', 'R', 'E', 'Q', 'U', 'I', 'R', 'E', 'D')) {
5681
 
        SKIP(9);
5682
 
        return(XML_ATTRIBUTE_REQUIRED);
5683
 
    }
5684
 
    if (CMP8(CUR_PTR, '#', 'I', 'M', 'P', 'L', 'I', 'E', 'D')) {
5685
 
        SKIP(8);
5686
 
        return(XML_ATTRIBUTE_IMPLIED);
5687
 
    }
5688
 
    val = XML_ATTRIBUTE_NONE;
5689
 
    if (CMP6(CUR_PTR, '#', 'F', 'I', 'X', 'E', 'D')) {
5690
 
        SKIP(6);
5691
 
        val = XML_ATTRIBUTE_FIXED;
5692
 
        if (!IS_BLANK_CH(CUR)) {
5693
 
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5694
 
                           "Space required after '#FIXED'\n");
5695
 
        }
5696
 
        SKIP_BLANKS;
5697
 
    }
5698
 
    ret = xmlParseAttValue(ctxt);
5699
 
    ctxt->instate = XML_PARSER_DTD;
5700
 
    if (ret == NULL) {
5701
 
        xmlFatalErrMsg(ctxt, (xmlParserErrors)ctxt->errNo,
5702
 
                       "Attribute default value declaration error\n");
5703
 
    } else
5704
 
        *value = ret;
5705
 
    return(val);
5706
 
}
5707
 
 
5708
 
/**
5709
 
 * xmlParseNotationType:
5710
 
 * @ctxt:  an XML parser context
5711
 
 *
5712
 
 * parse an Notation attribute type.
5713
 
 *
5714
 
 * Note: the leading 'NOTATION' S part has already being parsed...
5715
 
 *
5716
 
 * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
5717
 
 *
5718
 
 * [ VC: Notation Attributes ]
5719
 
 * Values of this type must match one of the notation names included
5720
 
 * in the declaration; all notation names in the declaration must be declared.
5721
 
 *
5722
 
 * Returns: the notation attribute tree built while parsing
5723
 
 */
5724
 
 
5725
 
xmlEnumerationPtr
5726
 
xmlParseNotationType(xmlParserCtxtPtr ctxt) {
5727
 
    const xmlChar *name;
5728
 
    xmlEnumerationPtr ret = NULL, last = NULL, cur, tmp;
5729
 
 
5730
 
    if (RAW != '(') {
5731
 
        xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_STARTED, NULL);
5732
 
        return(NULL);
5733
 
    }
5734
 
    SHRINK;
5735
 
    do {
5736
 
        NEXT;
5737
 
        SKIP_BLANKS;
5738
 
        name = xmlParseName(ctxt);
5739
 
        if (name == NULL) {
5740
 
            xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
5741
 
                           "Name expected in NOTATION declaration\n");
5742
 
            xmlFreeEnumeration(ret);
5743
 
            return(NULL);
5744
 
        }
5745
 
        tmp = ret;
5746
 
        while (tmp != NULL) {
5747
 
            if (xmlStrEqual(name, tmp->name)) {
5748
 
                xmlValidityError(ctxt, XML_DTD_DUP_TOKEN,
5749
 
          "standalone: attribute notation value token %s duplicated\n",
5750
 
                                 name, NULL);
5751
 
                if (!xmlDictOwns(ctxt->dict, name))
5752
 
                    xmlFree((xmlChar *) name);
5753
 
                break;
5754
 
            }
5755
 
            tmp = tmp->next;
5756
 
        }
5757
 
        if (tmp == NULL) {
5758
 
            cur = xmlCreateEnumeration(name);
5759
 
            if (cur == NULL) {
5760
 
                xmlFreeEnumeration(ret);
5761
 
                return(NULL);
5762
 
            }
5763
 
            if (last == NULL) ret = last = cur;
5764
 
            else {
5765
 
                last->next = cur;
5766
 
                last = cur;
5767
 
            }
5768
 
        }
5769
 
        SKIP_BLANKS;
5770
 
    } while (RAW == '|');
5771
 
    if (RAW != ')') {
5772
 
        xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
5773
 
        xmlFreeEnumeration(ret);
5774
 
        return(NULL);
5775
 
    }
5776
 
    NEXT;
5777
 
    return(ret);
5778
 
}
5779
 
 
5780
 
/**
5781
 
 * xmlParseEnumerationType:
5782
 
 * @ctxt:  an XML parser context
5783
 
 *
5784
 
 * parse an Enumeration attribute type.
5785
 
 *
5786
 
 * [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
5787
 
 *
5788
 
 * [ VC: Enumeration ]
5789
 
 * Values of this type must match one of the Nmtoken tokens in
5790
 
 * the declaration
5791
 
 *
5792
 
 * Returns: the enumeration attribute tree built while parsing
5793
 
 */
5794
 
 
5795
 
xmlEnumerationPtr
5796
 
xmlParseEnumerationType(xmlParserCtxtPtr ctxt) {
5797
 
    xmlChar *name;
5798
 
    xmlEnumerationPtr ret = NULL, last = NULL, cur, tmp;
5799
 
 
5800
 
    if (RAW != '(') {
5801
 
        xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_STARTED, NULL);
5802
 
        return(NULL);
5803
 
    }
5804
 
    SHRINK;
5805
 
    do {
5806
 
        NEXT;
5807
 
        SKIP_BLANKS;
5808
 
        name = xmlParseNmtoken(ctxt);
5809
 
        if (name == NULL) {
5810
 
            xmlFatalErr(ctxt, XML_ERR_NMTOKEN_REQUIRED, NULL);
5811
 
            return(ret);
5812
 
        }
5813
 
        tmp = ret;
5814
 
        while (tmp != NULL) {
5815
 
            if (xmlStrEqual(name, tmp->name)) {
5816
 
                xmlValidityError(ctxt, XML_DTD_DUP_TOKEN,
5817
 
          "standalone: attribute enumeration value token %s duplicated\n",
5818
 
                                 name, NULL);
5819
 
                if (!xmlDictOwns(ctxt->dict, name))
5820
 
                    xmlFree(name);
5821
 
                break;
5822
 
            }
5823
 
            tmp = tmp->next;
5824
 
        }
5825
 
        if (tmp == NULL) {
5826
 
            cur = xmlCreateEnumeration(name);
5827
 
            if (!xmlDictOwns(ctxt->dict, name))
5828
 
                xmlFree(name);
5829
 
            if (cur == NULL) {
5830
 
                xmlFreeEnumeration(ret);
5831
 
                return(NULL);
5832
 
            }
5833
 
            if (last == NULL) ret = last = cur;
5834
 
            else {
5835
 
                last->next = cur;
5836
 
                last = cur;
5837
 
            }
5838
 
        }
5839
 
        SKIP_BLANKS;
5840
 
    } while (RAW == '|');
5841
 
    if (RAW != ')') {
5842
 
        xmlFatalErr(ctxt, XML_ERR_ATTLIST_NOT_FINISHED, NULL);
5843
 
        return(ret);
5844
 
    }
5845
 
    NEXT;
5846
 
    return(ret);
5847
 
}
5848
 
 
5849
 
/**
5850
 
 * xmlParseEnumeratedType:
5851
 
 * @ctxt:  an XML parser context
5852
 
 * @tree:  the enumeration tree built while parsing
5853
 
 *
5854
 
 * parse an Enumerated attribute type.
5855
 
 *
5856
 
 * [57] EnumeratedType ::= NotationType | Enumeration
5857
 
 *
5858
 
 * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
5859
 
 *
5860
 
 *
5861
 
 * Returns: XML_ATTRIBUTE_ENUMERATION or XML_ATTRIBUTE_NOTATION
5862
 
 */
5863
 
 
5864
 
int
5865
 
xmlParseEnumeratedType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
5866
 
    if (CMP8(CUR_PTR, 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) {
5867
 
        SKIP(8);
5868
 
        if (!IS_BLANK_CH(CUR)) {
5869
 
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5870
 
                           "Space required after 'NOTATION'\n");
5871
 
            return(0);
5872
 
        }
5873
 
        SKIP_BLANKS;
5874
 
        *tree = xmlParseNotationType(ctxt);
5875
 
        if (*tree == NULL) return(0);
5876
 
        return(XML_ATTRIBUTE_NOTATION);
5877
 
    }
5878
 
    *tree = xmlParseEnumerationType(ctxt);
5879
 
    if (*tree == NULL) return(0);
5880
 
    return(XML_ATTRIBUTE_ENUMERATION);
5881
 
}
5882
 
 
5883
 
/**
5884
 
 * xmlParseAttributeType:
5885
 
 * @ctxt:  an XML parser context
5886
 
 * @tree:  the enumeration tree built while parsing
5887
 
 *
5888
 
 * parse the Attribute list def for an element
5889
 
 *
5890
 
 * [54] AttType ::= StringType | TokenizedType | EnumeratedType
5891
 
 *
5892
 
 * [55] StringType ::= 'CDATA'
5893
 
 *
5894
 
 * [56] TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' |
5895
 
 *                        'ENTITIES' | 'NMTOKEN' | 'NMTOKENS'
5896
 
 *
5897
 
 * Validity constraints for attribute values syntax are checked in
5898
 
 * xmlValidateAttributeValue()
5899
 
 *
5900
 
 * [ VC: ID ]
5901
 
 * Values of type ID must match the Name production. A name must not
5902
 
 * appear more than once in an XML document as a value of this type;
5903
 
 * i.e., ID values must uniquely identify the elements which bear them.
5904
 
 *
5905
 
 * [ VC: One ID per Element Type ]
5906
 
 * No element type may have more than one ID attribute specified.
5907
 
 *
5908
 
 * [ VC: ID Attribute Default ]
5909
 
 * An ID attribute must have a declared default of #IMPLIED or #REQUIRED.
5910
 
 *
5911
 
 * [ VC: IDREF ]
5912
 
 * Values of type IDREF must match the Name production, and values
5913
 
 * of type IDREFS must match Names; each IDREF Name must match the value
5914
 
 * of an ID attribute on some element in the XML document; i.e. IDREF
5915
 
 * values must match the value of some ID attribute.
5916
 
 *
5917
 
 * [ VC: Entity Name ]
5918
 
 * Values of type ENTITY must match the Name production, values
5919
 
 * of type ENTITIES must match Names; each Entity Name must match the
5920
 
 * name of an unparsed entity declared in the DTD.
5921
 
 *
5922
 
 * [ VC: Name Token ]
5923
 
 * Values of type NMTOKEN must match the Nmtoken production; values
5924
 
 * of type NMTOKENS must match Nmtokens.
5925
 
 *
5926
 
 * Returns the attribute type
5927
 
 */
5928
 
int
5929
 
xmlParseAttributeType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
5930
 
    SHRINK;
5931
 
    if (CMP5(CUR_PTR, 'C', 'D', 'A', 'T', 'A')) {
5932
 
        SKIP(5);
5933
 
        return(XML_ATTRIBUTE_CDATA);
5934
 
     } else if (CMP6(CUR_PTR, 'I', 'D', 'R', 'E', 'F', 'S')) {
5935
 
        SKIP(6);
5936
 
        return(XML_ATTRIBUTE_IDREFS);
5937
 
     } else if (CMP5(CUR_PTR, 'I', 'D', 'R', 'E', 'F')) {
5938
 
        SKIP(5);
5939
 
        return(XML_ATTRIBUTE_IDREF);
5940
 
     } else if ((RAW == 'I') && (NXT(1) == 'D')) {
5941
 
        SKIP(2);
5942
 
        return(XML_ATTRIBUTE_ID);
5943
 
     } else if (CMP6(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'Y')) {
5944
 
        SKIP(6);
5945
 
        return(XML_ATTRIBUTE_ENTITY);
5946
 
     } else if (CMP8(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S')) {
5947
 
        SKIP(8);
5948
 
        return(XML_ATTRIBUTE_ENTITIES);
5949
 
     } else if (CMP8(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S')) {
5950
 
        SKIP(8);
5951
 
        return(XML_ATTRIBUTE_NMTOKENS);
5952
 
     } else if (CMP7(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N')) {
5953
 
        SKIP(7);
5954
 
        return(XML_ATTRIBUTE_NMTOKEN);
5955
 
     }
5956
 
     return(xmlParseEnumeratedType(ctxt, tree));
5957
 
}
5958
 
 
5959
 
/**
5960
 
 * xmlParseAttributeListDecl:
5961
 
 * @ctxt:  an XML parser context
5962
 
 *
5963
 
 * : parse the Attribute list def for an element
5964
 
 *
5965
 
 * [52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
5966
 
 *
5967
 
 * [53] AttDef ::= S Name S AttType S DefaultDecl
5968
 
 *
5969
 
 */
5970
 
void
5971
 
xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) {
5972
 
    const xmlChar *elemName;
5973
 
    const xmlChar *attrName;
5974
 
    xmlEnumerationPtr tree;
5975
 
 
5976
 
    if (CMP9(CUR_PTR, '<', '!', 'A', 'T', 'T', 'L', 'I', 'S', 'T')) {
5977
 
        xmlParserInputPtr input = ctxt->input;
5978
 
 
5979
 
        SKIP(9);
5980
 
        if (!IS_BLANK_CH(CUR)) {
5981
 
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
5982
 
                                 "Space required after '<!ATTLIST'\n");
5983
 
        }
5984
 
        SKIP_BLANKS;
5985
 
        elemName = xmlParseName(ctxt);
5986
 
        if (elemName == NULL) {
5987
 
            xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
5988
 
                           "ATTLIST: no name for Element\n");
5989
 
            return;
5990
 
        }
5991
 
        SKIP_BLANKS;
5992
 
        GROW;
5993
 
        while ((RAW != '>') && (ctxt->instate != XML_PARSER_EOF)) {
5994
 
            const xmlChar *check = CUR_PTR;
5995
 
            int type;
5996
 
            int def;
5997
 
            xmlChar *defaultValue = NULL;
5998
 
 
5999
 
            GROW;
6000
 
            tree = NULL;
6001
 
            attrName = xmlParseName(ctxt);
6002
 
            if (attrName == NULL) {
6003
 
                xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
6004
 
                               "ATTLIST: no name for Attribute\n");
6005
 
                break;
6006
 
            }
6007
 
            GROW;
6008
 
            if (!IS_BLANK_CH(CUR)) {
6009
 
                xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6010
 
                        "Space required after the attribute name\n");
6011
 
                break;
6012
 
            }
6013
 
            SKIP_BLANKS;
6014
 
 
6015
 
            type = xmlParseAttributeType(ctxt, &tree);
6016
 
            if (type <= 0) {
6017
 
                break;
6018
 
            }
6019
 
 
6020
 
            GROW;
6021
 
            if (!IS_BLANK_CH(CUR)) {
6022
 
                xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6023
 
                               "Space required after the attribute type\n");
6024
 
                if (tree != NULL)
6025
 
                    xmlFreeEnumeration(tree);
6026
 
                break;
6027
 
            }
6028
 
            SKIP_BLANKS;
6029
 
 
6030
 
            def = xmlParseDefaultDecl(ctxt, &defaultValue);
6031
 
            if (def <= 0) {
6032
 
                if (defaultValue != NULL)
6033
 
                    xmlFree(defaultValue);
6034
 
                if (tree != NULL)
6035
 
                    xmlFreeEnumeration(tree);
6036
 
                break;
6037
 
            }
6038
 
            if ((type != XML_ATTRIBUTE_CDATA) && (defaultValue != NULL))
6039
 
                xmlAttrNormalizeSpace(defaultValue, defaultValue);
6040
 
 
6041
 
            GROW;
6042
 
            if (RAW != '>') {
6043
 
                if (!IS_BLANK_CH(CUR)) {
6044
 
                    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6045
 
                        "Space required after the attribute default value\n");
6046
 
                    if (defaultValue != NULL)
6047
 
                        xmlFree(defaultValue);
6048
 
                    if (tree != NULL)
6049
 
                        xmlFreeEnumeration(tree);
6050
 
                    break;
6051
 
                }
6052
 
                SKIP_BLANKS;
6053
 
            }
6054
 
            if (check == CUR_PTR) {
6055
 
                xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
6056
 
                            "in xmlParseAttributeListDecl\n");
6057
 
                if (defaultValue != NULL)
6058
 
                    xmlFree(defaultValue);
6059
 
                if (tree != NULL)
6060
 
                    xmlFreeEnumeration(tree);
6061
 
                break;
6062
 
            }
6063
 
            if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
6064
 
                (ctxt->sax->attributeDecl != NULL))
6065
 
                ctxt->sax->attributeDecl(ctxt->userData, elemName, attrName,
6066
 
                                type, def, defaultValue, tree);
6067
 
            else if (tree != NULL)
6068
 
                xmlFreeEnumeration(tree);
6069
 
 
6070
 
            if ((ctxt->sax2) && (defaultValue != NULL) &&
6071
 
                (def != XML_ATTRIBUTE_IMPLIED) &&
6072
 
                (def != XML_ATTRIBUTE_REQUIRED)) {
6073
 
                xmlAddDefAttrs(ctxt, elemName, attrName, defaultValue);
6074
 
            }
6075
 
            if (ctxt->sax2) {
6076
 
                xmlAddSpecialAttr(ctxt, elemName, attrName, type);
6077
 
            }
6078
 
            if (defaultValue != NULL)
6079
 
                xmlFree(defaultValue);
6080
 
            GROW;
6081
 
        }
6082
 
        if (RAW == '>') {
6083
 
            if (input != ctxt->input) {
6084
 
                xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
6085
 
    "Attribute list declaration doesn't start and stop in the same entity\n",
6086
 
                                 NULL, NULL);
6087
 
            }
6088
 
            NEXT;
6089
 
        }
6090
 
    }
6091
 
}
6092
 
 
6093
 
/**
6094
 
 * xmlParseElementMixedContentDecl:
6095
 
 * @ctxt:  an XML parser context
6096
 
 * @inputchk:  the input used for the current entity, needed for boundary checks
6097
 
 *
6098
 
 * parse the declaration for a Mixed Element content
6099
 
 * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
6100
 
 *
6101
 
 * [51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' |
6102
 
 *                '(' S? '#PCDATA' S? ')'
6103
 
 *
6104
 
 * [ VC: Proper Group/PE Nesting ] applies to [51] too (see [49])
6105
 
 *
6106
 
 * [ VC: No Duplicate Types ]
6107
 
 * The same name must not appear more than once in a single
6108
 
 * mixed-content declaration.
6109
 
 *
6110
 
 * returns: the list of the xmlElementContentPtr describing the element choices
6111
 
 */
6112
 
xmlElementContentPtr
6113
 
xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
6114
 
    xmlElementContentPtr ret = NULL, cur = NULL, n;
6115
 
    const xmlChar *elem = NULL;
6116
 
 
6117
 
    GROW;
6118
 
    if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
6119
 
        SKIP(7);
6120
 
        SKIP_BLANKS;
6121
 
        SHRINK;
6122
 
        if (RAW == ')') {
6123
 
            if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
6124
 
                xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
6125
 
"Element content declaration doesn't start and stop in the same entity\n",
6126
 
                                 NULL, NULL);
6127
 
            }
6128
 
            NEXT;
6129
 
            ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA);
6130
 
            if (ret == NULL)
6131
 
                return(NULL);
6132
 
            if (RAW == '*') {
6133
 
                ret->ocur = XML_ELEMENT_CONTENT_MULT;
6134
 
                NEXT;
6135
 
            }
6136
 
            return(ret);
6137
 
        }
6138
 
        if ((RAW == '(') || (RAW == '|')) {
6139
 
            ret = cur = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA);
6140
 
            if (ret == NULL) return(NULL);
6141
 
        }
6142
 
        while ((RAW == '|') && (ctxt->instate != XML_PARSER_EOF)) {
6143
 
            NEXT;
6144
 
            if (elem == NULL) {
6145
 
                ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
6146
 
                if (ret == NULL) return(NULL);
6147
 
                ret->c1 = cur;
6148
 
                if (cur != NULL)
6149
 
                    cur->parent = ret;
6150
 
                cur = ret;
6151
 
            } else {
6152
 
                n = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
6153
 
                if (n == NULL) return(NULL);
6154
 
                n->c1 = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
6155
 
                if (n->c1 != NULL)
6156
 
                    n->c1->parent = n;
6157
 
                cur->c2 = n;
6158
 
                if (n != NULL)
6159
 
                    n->parent = cur;
6160
 
                cur = n;
6161
 
            }
6162
 
            SKIP_BLANKS;
6163
 
            elem = xmlParseName(ctxt);
6164
 
            if (elem == NULL) {
6165
 
                xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
6166
 
                        "xmlParseElementMixedContentDecl : Name expected\n");
6167
 
                xmlFreeDocElementContent(ctxt->myDoc, cur);
6168
 
                return(NULL);
6169
 
            }
6170
 
            SKIP_BLANKS;
6171
 
            GROW;
6172
 
        }
6173
 
        if ((RAW == ')') && (NXT(1) == '*')) {
6174
 
            if (elem != NULL) {
6175
 
                cur->c2 = xmlNewDocElementContent(ctxt->myDoc, elem,
6176
 
                                               XML_ELEMENT_CONTENT_ELEMENT);
6177
 
                if (cur->c2 != NULL)
6178
 
                    cur->c2->parent = cur;
6179
 
            }
6180
 
            if (ret != NULL)
6181
 
                ret->ocur = XML_ELEMENT_CONTENT_MULT;
6182
 
            if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
6183
 
                xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
6184
 
"Element content declaration doesn't start and stop in the same entity\n",
6185
 
                                 NULL, NULL);
6186
 
            }
6187
 
            SKIP(2);
6188
 
        } else {
6189
 
            xmlFreeDocElementContent(ctxt->myDoc, ret);
6190
 
            xmlFatalErr(ctxt, XML_ERR_MIXED_NOT_STARTED, NULL);
6191
 
            return(NULL);
6192
 
        }
6193
 
 
6194
 
    } else {
6195
 
        xmlFatalErr(ctxt, XML_ERR_PCDATA_REQUIRED, NULL);
6196
 
    }
6197
 
    return(ret);
6198
 
}
6199
 
 
6200
 
/**
6201
 
 * xmlParseElementChildrenContentDeclPriv:
6202
 
 * @ctxt:  an XML parser context
6203
 
 * @inputchk:  the input used for the current entity, needed for boundary checks
6204
 
 * @depth: the level of recursion
6205
 
 *
6206
 
 * parse the declaration for a Mixed Element content
6207
 
 * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
6208
 
 *
6209
 
 *
6210
 
 * [47] children ::= (choice | seq) ('?' | '*' | '+')?
6211
 
 *
6212
 
 * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
6213
 
 *
6214
 
 * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
6215
 
 *
6216
 
 * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
6217
 
 *
6218
 
 * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
6219
 
 * TODO Parameter-entity replacement text must be properly nested
6220
 
 *      with parenthesized groups. That is to say, if either of the
6221
 
 *      opening or closing parentheses in a choice, seq, or Mixed
6222
 
 *      construct is contained in the replacement text for a parameter
6223
 
 *      entity, both must be contained in the same replacement text. For
6224
 
 *      interoperability, if a parameter-entity reference appears in a
6225
 
 *      choice, seq, or Mixed construct, its replacement text should not
6226
 
 *      be empty, and neither the first nor last non-blank character of
6227
 
 *      the replacement text should be a connector (| or ,).
6228
 
 *
6229
 
 * Returns the tree of xmlElementContentPtr describing the element
6230
 
 *          hierarchy.
6231
 
 */
6232
 
static xmlElementContentPtr
6233
 
xmlParseElementChildrenContentDeclPriv(xmlParserCtxtPtr ctxt, int inputchk,
6234
 
                                       int depth) {
6235
 
    xmlElementContentPtr ret = NULL, cur = NULL, last = NULL, op = NULL;
6236
 
    const xmlChar *elem;
6237
 
    xmlChar type = 0;
6238
 
 
6239
 
    if (((depth > 128) && ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
6240
 
        (depth >  2048)) {
6241
 
        xmlFatalErrMsgInt(ctxt, XML_ERR_ELEMCONTENT_NOT_FINISHED,
6242
 
"xmlParseElementChildrenContentDecl : depth %d too deep, use XML_PARSE_HUGE\n",
6243
 
                          depth);
6244
 
        return(NULL);
6245
 
    }
6246
 
    SKIP_BLANKS;
6247
 
    GROW;
6248
 
    if (RAW == '(') {
6249
 
        int inputid = ctxt->input->id;
6250
 
 
6251
 
        /* Recurse on first child */
6252
 
        NEXT;
6253
 
        SKIP_BLANKS;
6254
 
        cur = ret = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
6255
 
                                                           depth + 1);
6256
 
        SKIP_BLANKS;
6257
 
        GROW;
6258
 
    } else {
6259
 
        elem = xmlParseName(ctxt);
6260
 
        if (elem == NULL) {
6261
 
            xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
6262
 
            return(NULL);
6263
 
        }
6264
 
        cur = ret = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
6265
 
        if (cur == NULL) {
6266
 
            xmlErrMemory(ctxt, NULL);
6267
 
            return(NULL);
6268
 
        }
6269
 
        GROW;
6270
 
        if (RAW == '?') {
6271
 
            cur->ocur = XML_ELEMENT_CONTENT_OPT;
6272
 
            NEXT;
6273
 
        } else if (RAW == '*') {
6274
 
            cur->ocur = XML_ELEMENT_CONTENT_MULT;
6275
 
            NEXT;
6276
 
        } else if (RAW == '+') {
6277
 
            cur->ocur = XML_ELEMENT_CONTENT_PLUS;
6278
 
            NEXT;
6279
 
        } else {
6280
 
            cur->ocur = XML_ELEMENT_CONTENT_ONCE;
6281
 
        }
6282
 
        GROW;
6283
 
    }
6284
 
    SKIP_BLANKS;
6285
 
    SHRINK;
6286
 
    while ((RAW != ')') && (ctxt->instate != XML_PARSER_EOF)) {
6287
 
        /*
6288
 
         * Each loop we parse one separator and one element.
6289
 
         */
6290
 
        if (RAW == ',') {
6291
 
            if (type == 0) type = CUR;
6292
 
 
6293
 
            /*
6294
 
             * Detect "Name | Name , Name" error
6295
 
             */
6296
 
            else if (type != CUR) {
6297
 
                xmlFatalErrMsgInt(ctxt, XML_ERR_SEPARATOR_REQUIRED,
6298
 
                    "xmlParseElementChildrenContentDecl : '%c' expected\n",
6299
 
                                  type);
6300
 
                if ((last != NULL) && (last != ret))
6301
 
                    xmlFreeDocElementContent(ctxt->myDoc, last);
6302
 
                if (ret != NULL)
6303
 
                    xmlFreeDocElementContent(ctxt->myDoc, ret);
6304
 
                return(NULL);
6305
 
            }
6306
 
            NEXT;
6307
 
 
6308
 
            op = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_SEQ);
6309
 
            if (op == NULL) {
6310
 
                if ((last != NULL) && (last != ret))
6311
 
                    xmlFreeDocElementContent(ctxt->myDoc, last);
6312
 
                xmlFreeDocElementContent(ctxt->myDoc, ret);
6313
 
                return(NULL);
6314
 
            }
6315
 
            if (last == NULL) {
6316
 
                op->c1 = ret;
6317
 
                if (ret != NULL)
6318
 
                    ret->parent = op;
6319
 
                ret = cur = op;
6320
 
            } else {
6321
 
                cur->c2 = op;
6322
 
                if (op != NULL)
6323
 
                    op->parent = cur;
6324
 
                op->c1 = last;
6325
 
                if (last != NULL)
6326
 
                    last->parent = op;
6327
 
                cur =op;
6328
 
                last = NULL;
6329
 
            }
6330
 
        } else if (RAW == '|') {
6331
 
            if (type == 0) type = CUR;
6332
 
 
6333
 
            /*
6334
 
             * Detect "Name , Name | Name" error
6335
 
             */
6336
 
            else if (type != CUR) {
6337
 
                xmlFatalErrMsgInt(ctxt, XML_ERR_SEPARATOR_REQUIRED,
6338
 
                    "xmlParseElementChildrenContentDecl : '%c' expected\n",
6339
 
                                  type);
6340
 
                if ((last != NULL) && (last != ret))
6341
 
                    xmlFreeDocElementContent(ctxt->myDoc, last);
6342
 
                if (ret != NULL)
6343
 
                    xmlFreeDocElementContent(ctxt->myDoc, ret);
6344
 
                return(NULL);
6345
 
            }
6346
 
            NEXT;
6347
 
 
6348
 
            op = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
6349
 
            if (op == NULL) {
6350
 
                if ((last != NULL) && (last != ret))
6351
 
                    xmlFreeDocElementContent(ctxt->myDoc, last);
6352
 
                if (ret != NULL)
6353
 
                    xmlFreeDocElementContent(ctxt->myDoc, ret);
6354
 
                return(NULL);
6355
 
            }
6356
 
            if (last == NULL) {
6357
 
                op->c1 = ret;
6358
 
                if (ret != NULL)
6359
 
                    ret->parent = op;
6360
 
                ret = cur = op;
6361
 
            } else {
6362
 
                cur->c2 = op;
6363
 
                if (op != NULL)
6364
 
                    op->parent = cur;
6365
 
                op->c1 = last;
6366
 
                if (last != NULL)
6367
 
                    last->parent = op;
6368
 
                cur =op;
6369
 
                last = NULL;
6370
 
            }
6371
 
        } else {
6372
 
            xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_FINISHED, NULL);
6373
 
            if ((last != NULL) && (last != ret))
6374
 
                xmlFreeDocElementContent(ctxt->myDoc, last);
6375
 
            if (ret != NULL)
6376
 
                xmlFreeDocElementContent(ctxt->myDoc, ret);
6377
 
            return(NULL);
6378
 
        }
6379
 
        GROW;
6380
 
        SKIP_BLANKS;
6381
 
        GROW;
6382
 
        if (RAW == '(') {
6383
 
            int inputid = ctxt->input->id;
6384
 
            /* Recurse on second child */
6385
 
            NEXT;
6386
 
            SKIP_BLANKS;
6387
 
            last = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
6388
 
                                                          depth + 1);
6389
 
            SKIP_BLANKS;
6390
 
        } else {
6391
 
            elem = xmlParseName(ctxt);
6392
 
            if (elem == NULL) {
6393
 
                xmlFatalErr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED, NULL);
6394
 
                if (ret != NULL)
6395
 
                    xmlFreeDocElementContent(ctxt->myDoc, ret);
6396
 
                return(NULL);
6397
 
            }
6398
 
            last = xmlNewDocElementContent(ctxt->myDoc, elem, XML_ELEMENT_CONTENT_ELEMENT);
6399
 
            if (last == NULL) {
6400
 
                if (ret != NULL)
6401
 
                    xmlFreeDocElementContent(ctxt->myDoc, ret);
6402
 
                return(NULL);
6403
 
            }
6404
 
            if (RAW == '?') {
6405
 
                last->ocur = XML_ELEMENT_CONTENT_OPT;
6406
 
                NEXT;
6407
 
            } else if (RAW == '*') {
6408
 
                last->ocur = XML_ELEMENT_CONTENT_MULT;
6409
 
                NEXT;
6410
 
            } else if (RAW == '+') {
6411
 
                last->ocur = XML_ELEMENT_CONTENT_PLUS;
6412
 
                NEXT;
6413
 
            } else {
6414
 
                last->ocur = XML_ELEMENT_CONTENT_ONCE;
6415
 
            }
6416
 
        }
6417
 
        SKIP_BLANKS;
6418
 
        GROW;
6419
 
    }
6420
 
    if ((cur != NULL) && (last != NULL)) {
6421
 
        cur->c2 = last;
6422
 
        if (last != NULL)
6423
 
            last->parent = cur;
6424
 
    }
6425
 
    if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
6426
 
        xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
6427
 
"Element content declaration doesn't start and stop in the same entity\n",
6428
 
                         NULL, NULL);
6429
 
    }
6430
 
    NEXT;
6431
 
    if (RAW == '?') {
6432
 
        if (ret != NULL) {
6433
 
            if ((ret->ocur == XML_ELEMENT_CONTENT_PLUS) ||
6434
 
                (ret->ocur == XML_ELEMENT_CONTENT_MULT))
6435
 
                ret->ocur = XML_ELEMENT_CONTENT_MULT;
6436
 
            else
6437
 
                ret->ocur = XML_ELEMENT_CONTENT_OPT;
6438
 
        }
6439
 
        NEXT;
6440
 
    } else if (RAW == '*') {
6441
 
        if (ret != NULL) {
6442
 
            ret->ocur = XML_ELEMENT_CONTENT_MULT;
6443
 
            cur = ret;
6444
 
            /*
6445
 
             * Some normalization:
6446
 
             * (a | b* | c?)* == (a | b | c)*
6447
 
             */
6448
 
            while ((cur != NULL) && (cur->type == XML_ELEMENT_CONTENT_OR)) {
6449
 
                if ((cur->c1 != NULL) &&
6450
 
                    ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
6451
 
                     (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT)))
6452
 
                    cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
6453
 
                if ((cur->c2 != NULL) &&
6454
 
                    ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
6455
 
                     (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT)))
6456
 
                    cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
6457
 
                cur = cur->c2;
6458
 
            }
6459
 
        }
6460
 
        NEXT;
6461
 
    } else if (RAW == '+') {
6462
 
        if (ret != NULL) {
6463
 
            int found = 0;
6464
 
 
6465
 
            if ((ret->ocur == XML_ELEMENT_CONTENT_OPT) ||
6466
 
                (ret->ocur == XML_ELEMENT_CONTENT_MULT))
6467
 
                ret->ocur = XML_ELEMENT_CONTENT_MULT;
6468
 
            else
6469
 
                ret->ocur = XML_ELEMENT_CONTENT_PLUS;
6470
 
            /*
6471
 
             * Some normalization:
6472
 
             * (a | b*)+ == (a | b)*
6473
 
             * (a | b?)+ == (a | b)*
6474
 
             */
6475
 
            while ((cur != NULL) && (cur->type == XML_ELEMENT_CONTENT_OR)) {
6476
 
                if ((cur->c1 != NULL) &&
6477
 
                    ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
6478
 
                     (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT))) {
6479
 
                    cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
6480
 
                    found = 1;
6481
 
                }
6482
 
                if ((cur->c2 != NULL) &&
6483
 
                    ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
6484
 
                     (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT))) {
6485
 
                    cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
6486
 
                    found = 1;
6487
 
                }
6488
 
                cur = cur->c2;
6489
 
            }
6490
 
            if (found)
6491
 
                ret->ocur = XML_ELEMENT_CONTENT_MULT;
6492
 
        }
6493
 
        NEXT;
6494
 
    }
6495
 
    return(ret);
6496
 
}
6497
 
 
6498
 
/**
6499
 
 * xmlParseElementChildrenContentDecl:
6500
 
 * @ctxt:  an XML parser context
6501
 
 * @inputchk:  the input used for the current entity, needed for boundary checks
6502
 
 *
6503
 
 * parse the declaration for a Mixed Element content
6504
 
 * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
6505
 
 *
6506
 
 * [47] children ::= (choice | seq) ('?' | '*' | '+')?
6507
 
 *
6508
 
 * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
6509
 
 *
6510
 
 * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
6511
 
 *
6512
 
 * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
6513
 
 *
6514
 
 * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
6515
 
 * TODO Parameter-entity replacement text must be properly nested
6516
 
 *      with parenthesized groups. That is to say, if either of the
6517
 
 *      opening or closing parentheses in a choice, seq, or Mixed
6518
 
 *      construct is contained in the replacement text for a parameter
6519
 
 *      entity, both must be contained in the same replacement text. For
6520
 
 *      interoperability, if a parameter-entity reference appears in a
6521
 
 *      choice, seq, or Mixed construct, its replacement text should not
6522
 
 *      be empty, and neither the first nor last non-blank character of
6523
 
 *      the replacement text should be a connector (| or ,).
6524
 
 *
6525
 
 * Returns the tree of xmlElementContentPtr describing the element
6526
 
 *          hierarchy.
6527
 
 */
6528
 
xmlElementContentPtr
6529
 
xmlParseElementChildrenContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
6530
 
    /* stub left for API/ABI compat */
6531
 
    return(xmlParseElementChildrenContentDeclPriv(ctxt, inputchk, 1));
6532
 
}
6533
 
 
6534
 
/**
6535
 
 * xmlParseElementContentDecl:
6536
 
 * @ctxt:  an XML parser context
6537
 
 * @name:  the name of the element being defined.
6538
 
 * @result:  the Element Content pointer will be stored here if any
6539
 
 *
6540
 
 * parse the declaration for an Element content either Mixed or Children,
6541
 
 * the cases EMPTY and ANY are handled directly in xmlParseElementDecl
6542
 
 *
6543
 
 * [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
6544
 
 *
6545
 
 * returns: the type of element content XML_ELEMENT_TYPE_xxx
6546
 
 */
6547
 
 
6548
 
int
6549
 
xmlParseElementContentDecl(xmlParserCtxtPtr ctxt, const xmlChar *name,
6550
 
                           xmlElementContentPtr *result) {
6551
 
 
6552
 
    xmlElementContentPtr tree = NULL;
6553
 
    int inputid = ctxt->input->id;
6554
 
    int res;
6555
 
 
6556
 
    *result = NULL;
6557
 
 
6558
 
    if (RAW != '(') {
6559
 
        xmlFatalErrMsgStr(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED,
6560
 
                "xmlParseElementContentDecl : %s '(' expected\n", name);
6561
 
        return(-1);
6562
 
    }
6563
 
    NEXT;
6564
 
    GROW;
6565
 
    if (ctxt->instate == XML_PARSER_EOF)
6566
 
        return(-1);
6567
 
    SKIP_BLANKS;
6568
 
    if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
6569
 
        tree = xmlParseElementMixedContentDecl(ctxt, inputid);
6570
 
        res = XML_ELEMENT_TYPE_MIXED;
6571
 
    } else {
6572
 
        tree = xmlParseElementChildrenContentDeclPriv(ctxt, inputid, 1);
6573
 
        res = XML_ELEMENT_TYPE_ELEMENT;
6574
 
    }
6575
 
    SKIP_BLANKS;
6576
 
    *result = tree;
6577
 
    return(res);
6578
 
}
6579
 
 
6580
 
/**
6581
 
 * xmlParseElementDecl:
6582
 
 * @ctxt:  an XML parser context
6583
 
 *
6584
 
 * parse an Element declaration.
6585
 
 *
6586
 
 * [45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
6587
 
 *
6588
 
 * [ VC: Unique Element Type Declaration ]
6589
 
 * No element type may be declared more than once
6590
 
 *
6591
 
 * Returns the type of the element, or -1 in case of error
6592
 
 */
6593
 
int
6594
 
xmlParseElementDecl(xmlParserCtxtPtr ctxt) {
6595
 
    const xmlChar *name;
6596
 
    int ret = -1;
6597
 
    xmlElementContentPtr content  = NULL;
6598
 
 
6599
 
    /* GROW; done in the caller */
6600
 
    if (CMP9(CUR_PTR, '<', '!', 'E', 'L', 'E', 'M', 'E', 'N', 'T')) {
6601
 
        xmlParserInputPtr input = ctxt->input;
6602
 
 
6603
 
        SKIP(9);
6604
 
        if (!IS_BLANK_CH(CUR)) {
6605
 
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6606
 
                           "Space required after 'ELEMENT'\n");
6607
 
        }
6608
 
        SKIP_BLANKS;
6609
 
        name = xmlParseName(ctxt);
6610
 
        if (name == NULL) {
6611
 
            xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
6612
 
                           "xmlParseElementDecl: no name for Element\n");
6613
 
            return(-1);
6614
 
        }
6615
 
        while ((RAW == 0) && (ctxt->inputNr > 1))
6616
 
            xmlPopInput(ctxt);
6617
 
        if (!IS_BLANK_CH(CUR)) {
6618
 
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6619
 
                           "Space required after the element name\n");
6620
 
        }
6621
 
        SKIP_BLANKS;
6622
 
        if (CMP5(CUR_PTR, 'E', 'M', 'P', 'T', 'Y')) {
6623
 
            SKIP(5);
6624
 
            /*
6625
 
             * Element must always be empty.
6626
 
             */
6627
 
            ret = XML_ELEMENT_TYPE_EMPTY;
6628
 
        } else if ((RAW == 'A') && (NXT(1) == 'N') &&
6629
 
                   (NXT(2) == 'Y')) {
6630
 
            SKIP(3);
6631
 
            /*
6632
 
             * Element is a generic container.
6633
 
             */
6634
 
            ret = XML_ELEMENT_TYPE_ANY;
6635
 
        } else if (RAW == '(') {
6636
 
            ret = xmlParseElementContentDecl(ctxt, name, &content);
6637
 
        } else {
6638
 
            /*
6639
 
             * [ WFC: PEs in Internal Subset ] error handling.
6640
 
             */
6641
 
            if ((RAW == '%') && (ctxt->external == 0) &&
6642
 
                (ctxt->inputNr == 1)) {
6643
 
                xmlFatalErrMsg(ctxt, XML_ERR_PEREF_IN_INT_SUBSET,
6644
 
          "PEReference: forbidden within markup decl in internal subset\n");
6645
 
            } else {
6646
 
                xmlFatalErrMsg(ctxt, XML_ERR_ELEMCONTENT_NOT_STARTED,
6647
 
                      "xmlParseElementDecl: 'EMPTY', 'ANY' or '(' expected\n");
6648
 
            }
6649
 
            return(-1);
6650
 
        }
6651
 
 
6652
 
        SKIP_BLANKS;
6653
 
        /*
6654
 
         * Pop-up of finished entities.
6655
 
         */
6656
 
        while ((RAW == 0) && (ctxt->inputNr > 1))
6657
 
            xmlPopInput(ctxt);
6658
 
        SKIP_BLANKS;
6659
 
 
6660
 
        if (RAW != '>') {
6661
 
            xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
6662
 
            if (content != NULL) {
6663
 
                xmlFreeDocElementContent(ctxt->myDoc, content);
6664
 
            }
6665
 
        } else {
6666
 
            if (input != ctxt->input) {
6667
 
                xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
6668
 
    "Element declaration doesn't start and stop in the same entity\n");
6669
 
            }
6670
 
 
6671
 
            NEXT;
6672
 
            if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
6673
 
                (ctxt->sax->elementDecl != NULL)) {
6674
 
                if (content != NULL)
6675
 
                    content->parent = NULL;
6676
 
                ctxt->sax->elementDecl(ctxt->userData, name, ret,
6677
 
                                       content);
6678
 
                if ((content != NULL) && (content->parent == NULL)) {
6679
 
                    /*
6680
 
                     * this is a trick: if xmlAddElementDecl is called,
6681
 
                     * instead of copying the full tree it is plugged directly
6682
 
                     * if called from the parser. Avoid duplicating the
6683
 
                     * interfaces or change the API/ABI
6684
 
                     */
6685
 
                    xmlFreeDocElementContent(ctxt->myDoc, content);
6686
 
                }
6687
 
            } else if (content != NULL) {
6688
 
                xmlFreeDocElementContent(ctxt->myDoc, content);
6689
 
            }
6690
 
        }
6691
 
    }
6692
 
    return(ret);
6693
 
}
6694
 
 
6695
 
/**
6696
 
 * xmlParseConditionalSections
6697
 
 * @ctxt:  an XML parser context
6698
 
 *
6699
 
 * [61] conditionalSect ::= includeSect | ignoreSect
6700
 
 * [62] includeSect ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>'
6701
 
 * [63] ignoreSect ::= '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>'
6702
 
 * [64] ignoreSectContents ::= Ignore ('<![' ignoreSectContents ']]>' Ignore)*
6703
 
 * [65] Ignore ::= Char* - (Char* ('<![' | ']]>') Char*)
6704
 
 */
6705
 
 
6706
 
static void
6707
 
xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
6708
 
    int id = ctxt->input->id;
6709
 
 
6710
 
    SKIP(3);
6711
 
    SKIP_BLANKS;
6712
 
    if (CMP7(CUR_PTR, 'I', 'N', 'C', 'L', 'U', 'D', 'E')) {
6713
 
        SKIP(7);
6714
 
        SKIP_BLANKS;
6715
 
        if (RAW != '[') {
6716
 
            xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
6717
 
        } else {
6718
 
            if (ctxt->input->id != id) {
6719
 
                xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
6720
 
            "All markup of the conditional section is not in the same entity\n",
6721
 
                                     NULL, NULL);
6722
 
            }
6723
 
            NEXT;
6724
 
        }
6725
 
        if (xmlParserDebugEntities) {
6726
 
            if ((ctxt->input != NULL) && (ctxt->input->filename))
6727
 
                xmlGenericError(xmlGenericErrorContext,
6728
 
                        "%s(%d): ", ctxt->input->filename,
6729
 
                        ctxt->input->line);
6730
 
            xmlGenericError(xmlGenericErrorContext,
6731
 
                    "Entering INCLUDE Conditional Section\n");
6732
 
        }
6733
 
 
6734
 
        while (((RAW != 0) && ((RAW != ']') || (NXT(1) != ']') ||
6735
 
                (NXT(2) != '>'))) && (ctxt->instate != XML_PARSER_EOF)) {
6736
 
            const xmlChar *check = CUR_PTR;
6737
 
            unsigned int cons = ctxt->input->consumed;
6738
 
 
6739
 
            if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
6740
 
                xmlParseConditionalSections(ctxt);
6741
 
            } else if (IS_BLANK_CH(CUR)) {
6742
 
                NEXT;
6743
 
            } else if (RAW == '%') {
6744
 
                xmlParsePEReference(ctxt);
6745
 
            } else
6746
 
                xmlParseMarkupDecl(ctxt);
6747
 
 
6748
 
            /*
6749
 
             * Pop-up of finished entities.
6750
 
             */
6751
 
            while ((RAW == 0) && (ctxt->inputNr > 1))
6752
 
                xmlPopInput(ctxt);
6753
 
 
6754
 
            if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
6755
 
                xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
6756
 
                break;
6757
 
            }
6758
 
        }
6759
 
        if (xmlParserDebugEntities) {
6760
 
            if ((ctxt->input != NULL) && (ctxt->input->filename))
6761
 
                xmlGenericError(xmlGenericErrorContext,
6762
 
                        "%s(%d): ", ctxt->input->filename,
6763
 
                        ctxt->input->line);
6764
 
            xmlGenericError(xmlGenericErrorContext,
6765
 
                    "Leaving INCLUDE Conditional Section\n");
6766
 
        }
6767
 
 
6768
 
    } else if (CMP6(CUR_PTR, 'I', 'G', 'N', 'O', 'R', 'E')) {
6769
 
        int state;
6770
 
        xmlParserInputState instate;
6771
 
        int depth = 0;
6772
 
 
6773
 
        SKIP(6);
6774
 
        SKIP_BLANKS;
6775
 
        if (RAW != '[') {
6776
 
            xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
6777
 
        } else {
6778
 
            if (ctxt->input->id != id) {
6779
 
                xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
6780
 
            "All markup of the conditional section is not in the same entity\n",
6781
 
                                     NULL, NULL);
6782
 
            }
6783
 
            NEXT;
6784
 
        }
6785
 
        if (xmlParserDebugEntities) {
6786
 
            if ((ctxt->input != NULL) && (ctxt->input->filename))
6787
 
                xmlGenericError(xmlGenericErrorContext,
6788
 
                        "%s(%d): ", ctxt->input->filename,
6789
 
                        ctxt->input->line);
6790
 
            xmlGenericError(xmlGenericErrorContext,
6791
 
                    "Entering IGNORE Conditional Section\n");
6792
 
        }
6793
 
 
6794
 
        /*
6795
 
         * Parse up to the end of the conditional section
6796
 
         * But disable SAX event generating DTD building in the meantime
6797
 
         */
6798
 
        state = ctxt->disableSAX;
6799
 
        instate = ctxt->instate;
6800
 
        if (ctxt->recovery == 0) ctxt->disableSAX = 1;
6801
 
        ctxt->instate = XML_PARSER_IGNORE;
6802
 
 
6803
 
        while (((depth >= 0) && (RAW != 0)) &&
6804
 
               (ctxt->instate != XML_PARSER_EOF)) {
6805
 
          if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
6806
 
            depth++;
6807
 
            SKIP(3);
6808
 
            continue;
6809
 
          }
6810
 
          if ((RAW == ']') && (NXT(1) == ']') && (NXT(2) == '>')) {
6811
 
            if (--depth >= 0) SKIP(3);
6812
 
            continue;
6813
 
          }
6814
 
          NEXT;
6815
 
          continue;
6816
 
        }
6817
 
 
6818
 
        ctxt->disableSAX = state;
6819
 
        ctxt->instate = instate;
6820
 
 
6821
 
        if (xmlParserDebugEntities) {
6822
 
            if ((ctxt->input != NULL) && (ctxt->input->filename))
6823
 
                xmlGenericError(xmlGenericErrorContext,
6824
 
                        "%s(%d): ", ctxt->input->filename,
6825
 
                        ctxt->input->line);
6826
 
            xmlGenericError(xmlGenericErrorContext,
6827
 
                    "Leaving IGNORE Conditional Section\n");
6828
 
        }
6829
 
 
6830
 
    } else {
6831
 
        xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID_KEYWORD, NULL);
6832
 
    }
6833
 
 
6834
 
    if (RAW == 0)
6835
 
        SHRINK;
6836
 
 
6837
 
    if (RAW == 0) {
6838
 
        xmlFatalErr(ctxt, XML_ERR_CONDSEC_NOT_FINISHED, NULL);
6839
 
    } else {
6840
 
        if (ctxt->input->id != id) {
6841
 
            xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
6842
 
        "All markup of the conditional section is not in the same entity\n",
6843
 
                                 NULL, NULL);
6844
 
        }
6845
 
        SKIP(3);
6846
 
    }
6847
 
}
6848
 
 
6849
 
/**
6850
 
 * xmlParseMarkupDecl:
6851
 
 * @ctxt:  an XML parser context
6852
 
 *
6853
 
 * parse Markup declarations
6854
 
 *
6855
 
 * [29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl |
6856
 
 *                     NotationDecl | PI | Comment
6857
 
 *
6858
 
 * [ VC: Proper Declaration/PE Nesting ]
6859
 
 * Parameter-entity replacement text must be properly nested with
6860
 
 * markup declarations. That is to say, if either the first character
6861
 
 * or the last character of a markup declaration (markupdecl above) is
6862
 
 * contained in the replacement text for a parameter-entity reference,
6863
 
 * both must be contained in the same replacement text.
6864
 
 *
6865
 
 * [ WFC: PEs in Internal Subset ]
6866
 
 * In the internal DTD subset, parameter-entity references can occur
6867
 
 * only where markup declarations can occur, not within markup declarations.
6868
 
 * (This does not apply to references that occur in external parameter
6869
 
 * entities or to the external subset.)
6870
 
 */
6871
 
void
6872
 
xmlParseMarkupDecl(xmlParserCtxtPtr ctxt) {
6873
 
    GROW;
6874
 
    if (CUR == '<') {
6875
 
        if (NXT(1) == '!') {
6876
 
            switch (NXT(2)) {
6877
 
                case 'E':
6878
 
                    if (NXT(3) == 'L')
6879
 
                        xmlParseElementDecl(ctxt);
6880
 
                    else if (NXT(3) == 'N')
6881
 
                        xmlParseEntityDecl(ctxt);
6882
 
                    break;
6883
 
                case 'A':
6884
 
                    xmlParseAttributeListDecl(ctxt);
6885
 
                    break;
6886
 
                case 'N':
6887
 
                    xmlParseNotationDecl(ctxt);
6888
 
                    break;
6889
 
                case '-':
6890
 
                    xmlParseComment(ctxt);
6891
 
                    break;
6892
 
                default:
6893
 
                    /* there is an error but it will be detected later */
6894
 
                    break;
6895
 
            }
6896
 
        } else if (NXT(1) == '?') {
6897
 
            xmlParsePI(ctxt);
6898
 
        }
6899
 
    }
6900
 
    /*
6901
 
     * This is only for internal subset. On external entities,
6902
 
     * the replacement is done before parsing stage
6903
 
     */
6904
 
    if ((ctxt->external == 0) && (ctxt->inputNr == 1))
6905
 
        xmlParsePEReference(ctxt);
6906
 
 
6907
 
    /*
6908
 
     * Conditional sections are allowed from entities included
6909
 
     * by PE References in the internal subset.
6910
 
     */
6911
 
    if ((ctxt->external == 0) && (ctxt->inputNr > 1)) {
6912
 
        if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
6913
 
            xmlParseConditionalSections(ctxt);
6914
 
        }
6915
 
    }
6916
 
 
6917
 
    ctxt->instate = XML_PARSER_DTD;
6918
 
}
6919
 
 
6920
 
/**
6921
 
 * xmlParseTextDecl:
6922
 
 * @ctxt:  an XML parser context
6923
 
 *
6924
 
 * parse an XML declaration header for external entities
6925
 
 *
6926
 
 * [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
6927
 
 */
6928
 
 
6929
 
void
6930
 
xmlParseTextDecl(xmlParserCtxtPtr ctxt) {
6931
 
    xmlChar *version;
6932
 
    const xmlChar *encoding;
6933
 
 
6934
 
    /*
6935
 
     * We know that '<?xml' is here.
6936
 
     */
6937
 
    if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
6938
 
        SKIP(5);
6939
 
    } else {
6940
 
        xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_STARTED, NULL);
6941
 
        return;
6942
 
    }
6943
 
 
6944
 
    if (!IS_BLANK_CH(CUR)) {
6945
 
        xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6946
 
                       "Space needed after '<?xml'\n");
6947
 
    }
6948
 
    SKIP_BLANKS;
6949
 
 
6950
 
    /*
6951
 
     * We may have the VersionInfo here.
6952
 
     */
6953
 
    version = xmlParseVersionInfo(ctxt);
6954
 
    if (version == NULL)
6955
 
        version = xmlCharStrdup(XML_DEFAULT_VERSION);
6956
 
    else {
6957
 
        if (!IS_BLANK_CH(CUR)) {
6958
 
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
6959
 
                           "Space needed here\n");
6960
 
        }
6961
 
    }
6962
 
    ctxt->input->version = version;
6963
 
 
6964
 
    /*
6965
 
     * We must have the encoding declaration
6966
 
     */
6967
 
    encoding = xmlParseEncodingDecl(ctxt);
6968
 
    if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
6969
 
        /*
6970
 
         * The XML REC instructs us to stop parsing right here
6971
 
         */
6972
 
        return;
6973
 
    }
6974
 
    if ((encoding == NULL) && (ctxt->errNo == XML_ERR_OK)) {
6975
 
        xmlFatalErrMsg(ctxt, XML_ERR_MISSING_ENCODING,
6976
 
                       "Missing encoding in text declaration\n");
6977
 
    }
6978
 
 
6979
 
    SKIP_BLANKS;
6980
 
    if ((RAW == '?') && (NXT(1) == '>')) {
6981
 
        SKIP(2);
6982
 
    } else if (RAW == '>') {
6983
 
        /* Deprecated old WD ... */
6984
 
        xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
6985
 
        NEXT;
6986
 
    } else {
6987
 
        xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
6988
 
        MOVETO_ENDTAG(CUR_PTR);
6989
 
        NEXT;
6990
 
    }
6991
 
}
6992
 
 
6993
 
/**
6994
 
 * xmlParseExternalSubset:
6995
 
 * @ctxt:  an XML parser context
6996
 
 * @ExternalID: the external identifier
6997
 
 * @SystemID: the system identifier (or URL)
6998
 
 *
6999
 
 * parse Markup declarations from an external subset
7000
 
 *
7001
 
 * [30] extSubset ::= textDecl? extSubsetDecl
7002
 
 *
7003
 
 * [31] extSubsetDecl ::= (markupdecl | conditionalSect | PEReference | S) *
7004
 
 */
7005
 
void
7006
 
xmlParseExternalSubset(xmlParserCtxtPtr ctxt, const xmlChar *ExternalID,
7007
 
                       const xmlChar *SystemID) {
7008
 
    xmlDetectSAX2(ctxt);
7009
 
    GROW;
7010
 
 
7011
 
    if ((ctxt->encoding == NULL) &&
7012
 
        (ctxt->input->end - ctxt->input->cur >= 4)) {
7013
 
        xmlChar start[4];
7014
 
        xmlCharEncoding enc;
7015
 
 
7016
 
        start[0] = RAW;
7017
 
        start[1] = NXT(1);
7018
 
        start[2] = NXT(2);
7019
 
        start[3] = NXT(3);
7020
 
        enc = xmlDetectCharEncoding(start, 4);
7021
 
        if (enc != XML_CHAR_ENCODING_NONE)
7022
 
            xmlSwitchEncoding(ctxt, enc);
7023
 
    }
7024
 
 
7025
 
    if (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) {
7026
 
        xmlParseTextDecl(ctxt);
7027
 
        if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
7028
 
            /*
7029
 
             * The XML REC instructs us to stop parsing right here
7030
 
             */
7031
 
            ctxt->instate = XML_PARSER_EOF;
7032
 
            return;
7033
 
        }
7034
 
    }
7035
 
    if (ctxt->myDoc == NULL) {
7036
 
        ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
7037
 
        if (ctxt->myDoc == NULL) {
7038
 
            xmlErrMemory(ctxt, "New Doc failed");
7039
 
            return;
7040
 
        }
7041
 
        ctxt->myDoc->properties = XML_DOC_INTERNAL;
7042
 
    }
7043
 
    if ((ctxt->myDoc != NULL) && (ctxt->myDoc->intSubset == NULL))
7044
 
        xmlCreateIntSubset(ctxt->myDoc, NULL, ExternalID, SystemID);
7045
 
 
7046
 
    ctxt->instate = XML_PARSER_DTD;
7047
 
    ctxt->external = 1;
7048
 
    while (((RAW == '<') && (NXT(1) == '?')) ||
7049
 
           ((RAW == '<') && (NXT(1) == '!')) ||
7050
 
           (RAW == '%') || IS_BLANK_CH(CUR)) {
7051
 
        const xmlChar *check = CUR_PTR;
7052
 
        unsigned int cons = ctxt->input->consumed;
7053
 
 
7054
 
        GROW;
7055
 
        if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
7056
 
            xmlParseConditionalSections(ctxt);
7057
 
        } else if (IS_BLANK_CH(CUR)) {
7058
 
            NEXT;
7059
 
        } else if (RAW == '%') {
7060
 
            xmlParsePEReference(ctxt);
7061
 
        } else
7062
 
            xmlParseMarkupDecl(ctxt);
7063
 
 
7064
 
        /*
7065
 
         * Pop-up of finished entities.
7066
 
         */
7067
 
        while ((RAW == 0) && (ctxt->inputNr > 1))
7068
 
            xmlPopInput(ctxt);
7069
 
 
7070
 
        if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
7071
 
            xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
7072
 
            break;
7073
 
        }
7074
 
    }
7075
 
 
7076
 
    if (RAW != 0) {
7077
 
        xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
7078
 
    }
7079
 
 
7080
 
}
7081
 
 
7082
 
/**
7083
 
 * xmlParseReference:
7084
 
 * @ctxt:  an XML parser context
7085
 
 *
7086
 
 * parse and handle entity references in content, depending on the SAX
7087
 
 * interface, this may end-up in a call to character() if this is a
7088
 
 * CharRef, a predefined entity, if there is no reference() callback.
7089
 
 * or if the parser was asked to switch to that mode.
7090
 
 *
7091
 
 * [67] Reference ::= EntityRef | CharRef
7092
 
 */
7093
 
void
7094
 
xmlParseReference(xmlParserCtxtPtr ctxt) {
7095
 
    xmlEntityPtr ent;
7096
 
    xmlChar *val;
7097
 
    int was_checked;
7098
 
    xmlNodePtr list = NULL;
7099
 
    xmlParserErrors ret = XML_ERR_OK;
7100
 
 
7101
 
 
7102
 
    if (RAW != '&')
7103
 
        return;
7104
 
 
7105
 
    /*
7106
 
     * Simple case of a CharRef
7107
 
     */
7108
 
    if (NXT(1) == '#') {
7109
 
        int i = 0;
7110
 
        xmlChar out[10];
7111
 
        int hex = NXT(2);
7112
 
        int value = xmlParseCharRef(ctxt);
7113
 
 
7114
 
        if (value == 0)
7115
 
            return;
7116
 
        if (ctxt->charset != XML_CHAR_ENCODING_UTF8) {
7117
 
            /*
7118
 
             * So we are using non-UTF-8 buffers
7119
 
             * Check that the char fit on 8bits, if not
7120
 
             * generate a CharRef.
7121
 
             */
7122
 
            if (value <= 0xFF) {
7123
 
                out[0] = value;
7124
 
                out[1] = 0;
7125
 
                if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
7126
 
                    (!ctxt->disableSAX))
7127
 
                    ctxt->sax->characters(ctxt->userData, out, 1);
7128
 
            } else {
7129
 
                if ((hex == 'x') || (hex == 'X'))
7130
 
                    snprintf((char *)out, sizeof(out), "#x%X", value);
7131
 
                else
7132
 
                    snprintf((char *)out, sizeof(out), "#%d", value);
7133
 
                if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
7134
 
                    (!ctxt->disableSAX))
7135
 
                    ctxt->sax->reference(ctxt->userData, out);
7136
 
            }
7137
 
        } else {
7138
 
            /*
7139
 
             * Just encode the value in UTF-8
7140
 
             */
7141
 
            COPY_BUF(0 ,out, i, value);
7142
 
            out[i] = 0;
7143
 
            if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
7144
 
                (!ctxt->disableSAX))
7145
 
                ctxt->sax->characters(ctxt->userData, out, i);
7146
 
        }
7147
 
        return;
7148
 
    }
7149
 
 
7150
 
    /*
7151
 
     * We are seeing an entity reference
7152
 
     */
7153
 
    ent = xmlParseEntityRef(ctxt);
7154
 
    if (ent == NULL) return;
7155
 
    if (!ctxt->wellFormed)
7156
 
        return;
7157
 
    was_checked = ent->checked;
7158
 
 
7159
 
    /* special case of predefined entities */
7160
 
    if ((ent->name == NULL) ||
7161
 
        (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
7162
 
        val = ent->content;
7163
 
        if (val == NULL) return;
7164
 
        /*
7165
 
         * inline the entity.
7166
 
         */
7167
 
        if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
7168
 
            (!ctxt->disableSAX))
7169
 
            ctxt->sax->characters(ctxt->userData, val, xmlStrlen(val));
7170
 
        return;
7171
 
    }
7172
 
 
7173
 
    /*
7174
 
     * The first reference to the entity trigger a parsing phase
7175
 
     * where the ent->children is filled with the result from
7176
 
     * the parsing.
7177
 
     * Note: external parsed entities will not be loaded, it is not
7178
 
     * required for a non-validating parser, unless the parsing option
7179
 
     * of validating, or substituting entities were given. Doing so is
7180
 
     * far more secure as the parser will only process data coming from
7181
 
     * the document entity by default.
7182
 
     */
7183
 
    if ((ent->checked == 0) &&
7184
 
        ((ent->etype != XML_EXTERNAL_GENERAL_PARSED_ENTITY) ||
7185
 
         (ctxt->options & (XML_PARSE_NOENT | XML_PARSE_DTDVALID)))) {
7186
 
        unsigned long oldnbent = ctxt->nbentities;
7187
 
 
7188
 
        /*
7189
 
         * This is a bit hackish but this seems the best
7190
 
         * way to make sure both SAX and DOM entity support
7191
 
         * behaves okay.
7192
 
         */
7193
 
        void *user_data;
7194
 
        if (ctxt->userData == ctxt)
7195
 
            user_data = NULL;
7196
 
        else
7197
 
            user_data = ctxt->userData;
7198
 
 
7199
 
        /*
7200
 
         * Check that this entity is well formed
7201
 
         * 4.3.2: An internal general parsed entity is well-formed
7202
 
         * if its replacement text matches the production labeled
7203
 
         * content.
7204
 
         */
7205
 
        if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
7206
 
            ctxt->depth++;
7207
 
            ret = xmlParseBalancedChunkMemoryInternal(ctxt, ent->content,
7208
 
                                                      user_data, &list);
7209
 
            ctxt->depth--;
7210
 
 
7211
 
        } else if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
7212
 
            ctxt->depth++;
7213
 
            ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt, ctxt->sax,
7214
 
                                           user_data, ctxt->depth, ent->URI,
7215
 
                                           ent->ExternalID, &list);
7216
 
            ctxt->depth--;
7217
 
        } else {
7218
 
            ret = XML_ERR_ENTITY_PE_INTERNAL;
7219
 
            xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
7220
 
                         "invalid entity type found\n", NULL);
7221
 
        }
7222
 
 
7223
 
        /*
7224
 
         * Store the number of entities needing parsing for this entity
7225
 
         * content and do checkings
7226
 
         */
7227
 
        ent->checked = (ctxt->nbentities - oldnbent + 1) * 2;
7228
 
        if ((ent->content != NULL) && (xmlStrchr(ent->content, '<')))
7229
 
            ent->checked |= 1;
7230
 
        if (ret == XML_ERR_ENTITY_LOOP) {
7231
 
            xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
7232
 
            xmlFreeNodeList(list);
7233
 
            return;
7234
 
        }
7235
 
        if (xmlParserEntityCheck(ctxt, 0, ent, 0)) {
7236
 
            xmlFreeNodeList(list);
7237
 
            return;
7238
 
        }
7239
 
 
7240
 
        if ((ret == XML_ERR_OK) && (list != NULL)) {
7241
 
            if (((ent->etype == XML_INTERNAL_GENERAL_ENTITY) ||
7242
 
             (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY))&&
7243
 
                (ent->children == NULL)) {
7244
 
                ent->children = list;
7245
 
                if (ctxt->replaceEntities) {
7246
 
                    /*
7247
 
                     * Prune it directly in the generated document
7248
 
                     * except for single text nodes.
7249
 
                     */
7250
 
                    if (((list->type == XML_TEXT_NODE) &&
7251
 
                         (list->next == NULL)) ||
7252
 
                        (ctxt->parseMode == XML_PARSE_READER)) {
7253
 
                        list->parent = (xmlNodePtr) ent;
7254
 
                        list = NULL;
7255
 
                        ent->owner = 1;
7256
 
                    } else {
7257
 
                        ent->owner = 0;
7258
 
                        while (list != NULL) {
7259
 
                            list->parent = (xmlNodePtr) ctxt->node;
7260
 
                            list->doc = ctxt->myDoc;
7261
 
                            if (list->next == NULL)
7262
 
                                ent->last = list;
7263
 
                            list = list->next;
7264
 
                        }
7265
 
                        list = ent->children;
7266
 
#ifdef LIBXML_LEGACY_ENABLED
7267
 
                        if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
7268
 
                          xmlAddEntityReference(ent, list, NULL);
7269
 
#endif /* LIBXML_LEGACY_ENABLED */
7270
 
                    }
7271
 
                } else {
7272
 
                    ent->owner = 1;
7273
 
                    while (list != NULL) {
7274
 
                        list->parent = (xmlNodePtr) ent;
7275
 
                        xmlSetTreeDoc(list, ent->doc);
7276
 
                        if (list->next == NULL)
7277
 
                            ent->last = list;
7278
 
                        list = list->next;
7279
 
                    }
7280
 
                }
7281
 
            } else {
7282
 
                xmlFreeNodeList(list);
7283
 
                list = NULL;
7284
 
            }
7285
 
        } else if ((ret != XML_ERR_OK) &&
7286
 
                   (ret != XML_WAR_UNDECLARED_ENTITY)) {
7287
 
            xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
7288
 
                     "Entity '%s' failed to parse\n", ent->name);
7289
 
        } else if (list != NULL) {
7290
 
            xmlFreeNodeList(list);
7291
 
            list = NULL;
7292
 
        }
7293
 
        if (ent->checked == 0)
7294
 
            ent->checked = 2;
7295
 
    } else if (ent->checked != 1) {
7296
 
        ctxt->nbentities += ent->checked / 2;
7297
 
    }
7298
 
 
7299
 
    /*
7300
 
     * Now that the entity content has been gathered
7301
 
     * provide it to the application, this can take different forms based
7302
 
     * on the parsing modes.
7303
 
     */
7304
 
    if (ent->children == NULL) {
7305
 
        /*
7306
 
         * Probably running in SAX mode and the callbacks don't
7307
 
         * build the entity content. So unless we already went
7308
 
         * though parsing for first checking go though the entity
7309
 
         * content to generate callbacks associated to the entity
7310
 
         */
7311
 
        if (was_checked != 0) {
7312
 
            void *user_data;
7313
 
            /*
7314
 
             * This is a bit hackish but this seems the best
7315
 
             * way to make sure both SAX and DOM entity support
7316
 
             * behaves okay.
7317
 
             */
7318
 
            if (ctxt->userData == ctxt)
7319
 
                user_data = NULL;
7320
 
            else
7321
 
                user_data = ctxt->userData;
7322
 
 
7323
 
            if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
7324
 
                ctxt->depth++;
7325
 
                ret = xmlParseBalancedChunkMemoryInternal(ctxt,
7326
 
                                   ent->content, user_data, NULL);
7327
 
                ctxt->depth--;
7328
 
            } else if (ent->etype ==
7329
 
                       XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
7330
 
                ctxt->depth++;
7331
 
                ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt,
7332
 
                           ctxt->sax, user_data, ctxt->depth,
7333
 
                           ent->URI, ent->ExternalID, NULL);
7334
 
                ctxt->depth--;
7335
 
            } else {
7336
 
                ret = XML_ERR_ENTITY_PE_INTERNAL;
7337
 
                xmlErrMsgStr(ctxt, XML_ERR_INTERNAL_ERROR,
7338
 
                             "invalid entity type found\n", NULL);
7339
 
            }
7340
 
            if (ret == XML_ERR_ENTITY_LOOP) {
7341
 
                xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
7342
 
                return;
7343
 
            }
7344
 
        }
7345
 
        if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
7346
 
            (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
7347
 
            /*
7348
 
             * Entity reference callback comes second, it's somewhat
7349
 
             * superfluous but a compatibility to historical behaviour
7350
 
             */
7351
 
            ctxt->sax->reference(ctxt->userData, ent->name);
7352
 
        }
7353
 
        return;
7354
 
    }
7355
 
 
7356
 
    /*
7357
 
     * If we didn't get any children for the entity being built
7358
 
     */
7359
 
    if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
7360
 
        (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
7361
 
        /*
7362
 
         * Create a node.
7363
 
         */
7364
 
        ctxt->sax->reference(ctxt->userData, ent->name);
7365
 
        return;
7366
 
    }
7367
 
 
7368
 
    if ((ctxt->replaceEntities) || (ent->children == NULL))  {
7369
 
        /*
7370
 
         * There is a problem on the handling of _private for entities
7371
 
         * (bug 155816): Should we copy the content of the field from
7372
 
         * the entity (possibly overwriting some value set by the user
7373
 
         * when a copy is created), should we leave it alone, or should
7374
 
         * we try to take care of different situations?  The problem
7375
 
         * is exacerbated by the usage of this field by the xmlReader.
7376
 
         * To fix this bug, we look at _private on the created node
7377
 
         * and, if it's NULL, we copy in whatever was in the entity.
7378
 
         * If it's not NULL we leave it alone.  This is somewhat of a
7379
 
         * hack - maybe we should have further tests to determine
7380
 
         * what to do.
7381
 
         */
7382
 
        if ((ctxt->node != NULL) && (ent->children != NULL)) {
7383
 
            /*
7384
 
             * Seems we are generating the DOM content, do
7385
 
             * a simple tree copy for all references except the first
7386
 
             * In the first occurrence list contains the replacement.
7387
 
             */
7388
 
            if (((list == NULL) && (ent->owner == 0)) ||
7389
 
                (ctxt->parseMode == XML_PARSE_READER)) {
7390
 
                xmlNodePtr nw = NULL, cur, firstChild = NULL;
7391
 
 
7392
 
                /*
7393
 
                 * We are copying here, make sure there is no abuse
7394
 
                 */
7395
 
                ctxt->sizeentcopy += ent->length;
7396
 
                if (xmlParserEntityCheck(ctxt, 0, ent, ctxt->sizeentcopy))
7397
 
                    return;
7398
 
 
7399
 
                /*
7400
 
                 * when operating on a reader, the entities definitions
7401
 
                 * are always owning the entities subtree.
7402
 
                if (ctxt->parseMode == XML_PARSE_READER)
7403
 
                    ent->owner = 1;
7404
 
                 */
7405
 
 
7406
 
                cur = ent->children;
7407
 
                while (cur != NULL) {
7408
 
                    nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
7409
 
                    if (nw != NULL) {
7410
 
                        if (nw->_private == NULL)
7411
 
                            nw->_private = cur->_private;
7412
 
                        if (firstChild == NULL){
7413
 
                            firstChild = nw;
7414
 
                        }
7415
 
                        nw = xmlAddChild(ctxt->node, nw);
7416
 
                    }
7417
 
                    if (cur == ent->last) {
7418
 
                        /*
7419
 
                         * needed to detect some strange empty
7420
 
                         * node cases in the reader tests
7421
 
                         */
7422
 
                        if ((ctxt->parseMode == XML_PARSE_READER) &&
7423
 
                            (nw != NULL) &&
7424
 
                            (nw->type == XML_ELEMENT_NODE) &&
7425
 
                            (nw->children == NULL))
7426
 
                            nw->extra = 1;
7427
 
 
7428
 
                        break;
7429
 
                    }
7430
 
                    cur = cur->next;
7431
 
                }
7432
 
#ifdef LIBXML_LEGACY_ENABLED
7433
 
                if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
7434
 
                  xmlAddEntityReference(ent, firstChild, nw);
7435
 
#endif /* LIBXML_LEGACY_ENABLED */
7436
 
            } else if ((list == NULL) || (ctxt->inputNr > 0)) {
7437
 
                xmlNodePtr nw = NULL, cur, next, last,
7438
 
                           firstChild = NULL;
7439
 
 
7440
 
                /*
7441
 
                 * We are copying here, make sure there is no abuse
7442
 
                 */
7443
 
                ctxt->sizeentcopy += ent->length;
7444
 
                if (xmlParserEntityCheck(ctxt, 0, ent, ctxt->sizeentcopy))
7445
 
                    return;
7446
 
 
7447
 
                /*
7448
 
                 * Copy the entity child list and make it the new
7449
 
                 * entity child list. The goal is to make sure any
7450
 
                 * ID or REF referenced will be the one from the
7451
 
                 * document content and not the entity copy.
7452
 
                 */
7453
 
                cur = ent->children;
7454
 
                ent->children = NULL;
7455
 
                last = ent->last;
7456
 
                ent->last = NULL;
7457
 
                while (cur != NULL) {
7458
 
                    next = cur->next;
7459
 
                    cur->next = NULL;
7460
 
                    cur->parent = NULL;
7461
 
                    nw = xmlDocCopyNode(cur, ctxt->myDoc, 1);
7462
 
                    if (nw != NULL) {
7463
 
                        if (nw->_private == NULL)
7464
 
                            nw->_private = cur->_private;
7465
 
                        if (firstChild == NULL){
7466
 
                            firstChild = cur;
7467
 
                        }
7468
 
                        xmlAddChild((xmlNodePtr) ent, nw);
7469
 
                        xmlAddChild(ctxt->node, cur);
7470
 
                    }
7471
 
                    if (cur == last)
7472
 
                        break;
7473
 
                    cur = next;
7474
 
                }
7475
 
                if (ent->owner == 0)
7476
 
                    ent->owner = 1;
7477
 
#ifdef LIBXML_LEGACY_ENABLED
7478
 
                if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
7479
 
                  xmlAddEntityReference(ent, firstChild, nw);
7480
 
#endif /* LIBXML_LEGACY_ENABLED */
7481
 
            } else {
7482
 
                const xmlChar *nbktext;
7483
 
 
7484
 
                /*
7485
 
                 * the name change is to avoid coalescing of the
7486
 
                 * node with a possible previous text one which
7487
 
                 * would make ent->children a dangling pointer
7488
 
                 */
7489
 
                nbktext = xmlDictLookup(ctxt->dict, BAD_CAST "nbktext",
7490
 
                                        -1);
7491
 
                if (ent->children->type == XML_TEXT_NODE)
7492
 
                    ent->children->name = nbktext;
7493
 
                if ((ent->last != ent->children) &&
7494
 
                    (ent->last->type == XML_TEXT_NODE))
7495
 
                    ent->last->name = nbktext;
7496
 
                xmlAddChildList(ctxt->node, ent->children);
7497
 
            }
7498
 
 
7499
 
            /*
7500
 
             * This is to avoid a nasty side effect, see
7501
 
             * characters() in SAX.c
7502
 
             */
7503
 
            ctxt->nodemem = 0;
7504
 
            ctxt->nodelen = 0;
7505
 
            return;
7506
 
        }
7507
 
    }
7508
 
}
7509
 
 
7510
 
/**
7511
 
 * xmlParseEntityRef:
7512
 
 * @ctxt:  an XML parser context
7513
 
 *
7514
 
 * parse ENTITY references declarations
7515
 
 *
7516
 
 * [68] EntityRef ::= '&' Name ';'
7517
 
 *
7518
 
 * [ WFC: Entity Declared ]
7519
 
 * In a document without any DTD, a document with only an internal DTD
7520
 
 * subset which contains no parameter entity references, or a document
7521
 
 * with "standalone='yes'", the Name given in the entity reference
7522
 
 * must match that in an entity declaration, except that well-formed
7523
 
 * documents need not declare any of the following entities: amp, lt,
7524
 
 * gt, apos, quot.  The declaration of a parameter entity must precede
7525
 
 * any reference to it.  Similarly, the declaration of a general entity
7526
 
 * must precede any reference to it which appears in a default value in an
7527
 
 * attribute-list declaration. Note that if entities are declared in the
7528
 
 * external subset or in external parameter entities, a non-validating
7529
 
 * processor is not obligated to read and process their declarations;
7530
 
 * for such documents, the rule that an entity must be declared is a
7531
 
 * well-formedness constraint only if standalone='yes'.
7532
 
 *
7533
 
 * [ WFC: Parsed Entity ]
7534
 
 * An entity reference must not contain the name of an unparsed entity
7535
 
 *
7536
 
 * Returns the xmlEntityPtr if found, or NULL otherwise.
7537
 
 */
7538
 
xmlEntityPtr
7539
 
xmlParseEntityRef(xmlParserCtxtPtr ctxt) {
7540
 
    const xmlChar *name;
7541
 
    xmlEntityPtr ent = NULL;
7542
 
 
7543
 
    GROW;
7544
 
    if (ctxt->instate == XML_PARSER_EOF)
7545
 
        return(NULL);
7546
 
 
7547
 
    if (RAW != '&')
7548
 
        return(NULL);
7549
 
    NEXT;
7550
 
    name = xmlParseName(ctxt);
7551
 
    if (name == NULL) {
7552
 
        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
7553
 
                       "xmlParseEntityRef: no name\n");
7554
 
        return(NULL);
7555
 
    }
7556
 
    if (RAW != ';') {
7557
 
        xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
7558
 
        return(NULL);
7559
 
    }
7560
 
    NEXT;
7561
 
 
7562
 
    /*
7563
 
     * Predefined entities override any extra definition
7564
 
     */
7565
 
    if ((ctxt->options & XML_PARSE_OLDSAX) == 0) {
7566
 
        ent = xmlGetPredefinedEntity(name);
7567
 
        if (ent != NULL)
7568
 
            return(ent);
7569
 
    }
7570
 
 
7571
 
    /*
7572
 
     * Increase the number of entity references parsed
7573
 
     */
7574
 
    ctxt->nbentities++;
7575
 
 
7576
 
    /*
7577
 
     * Ask first SAX for entity resolution, otherwise try the
7578
 
     * entities which may have stored in the parser context.
7579
 
     */
7580
 
    if (ctxt->sax != NULL) {
7581
 
        if (ctxt->sax->getEntity != NULL)
7582
 
            ent = ctxt->sax->getEntity(ctxt->userData, name);
7583
 
        if ((ctxt->wellFormed == 1 ) && (ent == NULL) &&
7584
 
            (ctxt->options & XML_PARSE_OLDSAX))
7585
 
            ent = xmlGetPredefinedEntity(name);
7586
 
        if ((ctxt->wellFormed == 1 ) && (ent == NULL) &&
7587
 
            (ctxt->userData==ctxt)) {
7588
 
            ent = xmlSAX2GetEntity(ctxt, name);
7589
 
        }
7590
 
    }
7591
 
    if (ctxt->instate == XML_PARSER_EOF)
7592
 
        return(NULL);
7593
 
    /*
7594
 
     * [ WFC: Entity Declared ]
7595
 
     * In a document without any DTD, a document with only an
7596
 
     * internal DTD subset which contains no parameter entity
7597
 
     * references, or a document with "standalone='yes'", the
7598
 
     * Name given in the entity reference must match that in an
7599
 
     * entity declaration, except that well-formed documents
7600
 
     * need not declare any of the following entities: amp, lt,
7601
 
     * gt, apos, quot.
7602
 
     * The declaration of a parameter entity must precede any
7603
 
     * reference to it.
7604
 
     * Similarly, the declaration of a general entity must
7605
 
     * precede any reference to it which appears in a default
7606
 
     * value in an attribute-list declaration. Note that if
7607
 
     * entities are declared in the external subset or in
7608
 
     * external parameter entities, a non-validating processor
7609
 
     * is not obligated to read and process their declarations;
7610
 
     * for such documents, the rule that an entity must be
7611
 
     * declared is a well-formedness constraint only if
7612
 
     * standalone='yes'.
7613
 
     */
7614
 
    if (ent == NULL) {
7615
 
        if ((ctxt->standalone == 1) ||
7616
 
            ((ctxt->hasExternalSubset == 0) &&
7617
 
             (ctxt->hasPErefs == 0))) {
7618
 
            xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
7619
 
                     "Entity '%s' not defined\n", name);
7620
 
        } else {
7621
 
            xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
7622
 
                     "Entity '%s' not defined\n", name);
7623
 
            if ((ctxt->inSubset == 0) &&
7624
 
                (ctxt->sax != NULL) &&
7625
 
                (ctxt->sax->reference != NULL)) {
7626
 
                ctxt->sax->reference(ctxt->userData, name);
7627
 
            }
7628
 
        }
7629
 
        ctxt->valid = 0;
7630
 
    }
7631
 
 
7632
 
    /*
7633
 
     * [ WFC: Parsed Entity ]
7634
 
     * An entity reference must not contain the name of an
7635
 
     * unparsed entity
7636
 
     */
7637
 
    else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
7638
 
        xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
7639
 
                 "Entity reference to unparsed entity %s\n", name);
7640
 
    }
7641
 
 
7642
 
    /*
7643
 
     * [ WFC: No External Entity References ]
7644
 
     * Attribute values cannot contain direct or indirect
7645
 
     * entity references to external entities.
7646
 
     */
7647
 
    else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
7648
 
             (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
7649
 
        xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
7650
 
             "Attribute references external entity '%s'\n", name);
7651
 
    }
7652
 
    /*
7653
 
     * [ WFC: No < in Attribute Values ]
7654
 
     * The replacement text of any entity referred to directly or
7655
 
     * indirectly in an attribute value (other than "&lt;") must
7656
 
     * not contain a <.
7657
 
     */
7658
 
    else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
7659
 
             (ent != NULL) && 
7660
 
             (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY)) {
7661
 
        if ((ent->checked & 1) || ((ent->checked == 0) &&
7662
 
             (ent->content != NULL) &&(xmlStrchr(ent->content, '<')))) {
7663
 
            xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
7664
 
        "'<' in entity '%s' is not allowed in attributes values\n", name);
7665
 
        }
7666
 
    }
7667
 
 
7668
 
    /*
7669
 
     * Internal check, no parameter entities here ...
7670
 
     */
7671
 
    else {
7672
 
        switch (ent->etype) {
7673
 
            case XML_INTERNAL_PARAMETER_ENTITY:
7674
 
            case XML_EXTERNAL_PARAMETER_ENTITY:
7675
 
            xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
7676
 
             "Attempt to reference the parameter entity '%s'\n",
7677
 
                              name);
7678
 
            break;
7679
 
            default:
7680
 
            break;
7681
 
        }
7682
 
    }
7683
 
 
7684
 
    /*
7685
 
     * [ WFC: No Recursion ]
7686
 
     * A parsed entity must not contain a recursive reference
7687
 
     * to itself, either directly or indirectly.
7688
 
     * Done somewhere else
7689
 
     */
7690
 
    return(ent);
7691
 
}
7692
 
 
7693
 
/**
7694
 
 * xmlParseStringEntityRef:
7695
 
 * @ctxt:  an XML parser context
7696
 
 * @str:  a pointer to an index in the string
7697
 
 *
7698
 
 * parse ENTITY references declarations, but this version parses it from
7699
 
 * a string value.
7700
 
 *
7701
 
 * [68] EntityRef ::= '&' Name ';'
7702
 
 *
7703
 
 * [ WFC: Entity Declared ]
7704
 
 * In a document without any DTD, a document with only an internal DTD
7705
 
 * subset which contains no parameter entity references, or a document
7706
 
 * with "standalone='yes'", the Name given in the entity reference
7707
 
 * must match that in an entity declaration, except that well-formed
7708
 
 * documents need not declare any of the following entities: amp, lt,
7709
 
 * gt, apos, quot.  The declaration of a parameter entity must precede
7710
 
 * any reference to it.  Similarly, the declaration of a general entity
7711
 
 * must precede any reference to it which appears in a default value in an
7712
 
 * attribute-list declaration. Note that if entities are declared in the
7713
 
 * external subset or in external parameter entities, a non-validating
7714
 
 * processor is not obligated to read and process their declarations;
7715
 
 * for such documents, the rule that an entity must be declared is a
7716
 
 * well-formedness constraint only if standalone='yes'.
7717
 
 *
7718
 
 * [ WFC: Parsed Entity ]
7719
 
 * An entity reference must not contain the name of an unparsed entity
7720
 
 *
7721
 
 * Returns the xmlEntityPtr if found, or NULL otherwise. The str pointer
7722
 
 * is updated to the current location in the string.
7723
 
 */
7724
 
static xmlEntityPtr
7725
 
xmlParseStringEntityRef(xmlParserCtxtPtr ctxt, const xmlChar ** str) {
7726
 
    xmlChar *name;
7727
 
    const xmlChar *ptr;
7728
 
    xmlChar cur;
7729
 
    xmlEntityPtr ent = NULL;
7730
 
 
7731
 
    if ((str == NULL) || (*str == NULL))
7732
 
        return(NULL);
7733
 
    ptr = *str;
7734
 
    cur = *ptr;
7735
 
    if (cur != '&')
7736
 
        return(NULL);
7737
 
 
7738
 
    ptr++;
7739
 
    name = xmlParseStringName(ctxt, &ptr);
7740
 
    if (name == NULL) {
7741
 
        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
7742
 
                       "xmlParseStringEntityRef: no name\n");
7743
 
        *str = ptr;
7744
 
        return(NULL);
7745
 
    }
7746
 
    if (*ptr != ';') {
7747
 
        xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
7748
 
        xmlFree(name);
7749
 
        *str = ptr;
7750
 
        return(NULL);
7751
 
    }
7752
 
    ptr++;
7753
 
 
7754
 
 
7755
 
    /*
7756
 
     * Predefined entites override any extra definition
7757
 
     */
7758
 
    if ((ctxt->options & XML_PARSE_OLDSAX) == 0) {
7759
 
        ent = xmlGetPredefinedEntity(name);
7760
 
        if (ent != NULL) {
7761
 
            xmlFree(name);
7762
 
            *str = ptr;
7763
 
            return(ent);
7764
 
        }
7765
 
    }
7766
 
 
7767
 
    /*
7768
 
     * Increate the number of entity references parsed
7769
 
     */
7770
 
    ctxt->nbentities++;
7771
 
 
7772
 
    /*
7773
 
     * Ask first SAX for entity resolution, otherwise try the
7774
 
     * entities which may have stored in the parser context.
7775
 
     */
7776
 
    if (ctxt->sax != NULL) {
7777
 
        if (ctxt->sax->getEntity != NULL)
7778
 
            ent = ctxt->sax->getEntity(ctxt->userData, name);
7779
 
        if ((ent == NULL) && (ctxt->options & XML_PARSE_OLDSAX))
7780
 
            ent = xmlGetPredefinedEntity(name);
7781
 
        if ((ent == NULL) && (ctxt->userData==ctxt)) {
7782
 
            ent = xmlSAX2GetEntity(ctxt, name);
7783
 
        }
7784
 
    }
7785
 
    if (ctxt->instate == XML_PARSER_EOF) {
7786
 
        xmlFree(name);
7787
 
        return(NULL);
7788
 
    }
7789
 
 
7790
 
    /*
7791
 
     * [ WFC: Entity Declared ]
7792
 
     * In a document without any DTD, a document with only an
7793
 
     * internal DTD subset which contains no parameter entity
7794
 
     * references, or a document with "standalone='yes'", the
7795
 
     * Name given in the entity reference must match that in an
7796
 
     * entity declaration, except that well-formed documents
7797
 
     * need not declare any of the following entities: amp, lt,
7798
 
     * gt, apos, quot.
7799
 
     * The declaration of a parameter entity must precede any
7800
 
     * reference to it.
7801
 
     * Similarly, the declaration of a general entity must
7802
 
     * precede any reference to it which appears in a default
7803
 
     * value in an attribute-list declaration. Note that if
7804
 
     * entities are declared in the external subset or in
7805
 
     * external parameter entities, a non-validating processor
7806
 
     * is not obligated to read and process their declarations;
7807
 
     * for such documents, the rule that an entity must be
7808
 
     * declared is a well-formedness constraint only if
7809
 
     * standalone='yes'.
7810
 
     */
7811
 
    if (ent == NULL) {
7812
 
        if ((ctxt->standalone == 1) ||
7813
 
            ((ctxt->hasExternalSubset == 0) &&
7814
 
             (ctxt->hasPErefs == 0))) {
7815
 
            xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
7816
 
                     "Entity '%s' not defined\n", name);
7817
 
        } else {
7818
 
            xmlErrMsgStr(ctxt, XML_WAR_UNDECLARED_ENTITY,
7819
 
                          "Entity '%s' not defined\n",
7820
 
                          name);
7821
 
        }
7822
 
        /* TODO ? check regressions ctxt->valid = 0; */
7823
 
    }
7824
 
 
7825
 
    /*
7826
 
     * [ WFC: Parsed Entity ]
7827
 
     * An entity reference must not contain the name of an
7828
 
     * unparsed entity
7829
 
     */
7830
 
    else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
7831
 
        xmlFatalErrMsgStr(ctxt, XML_ERR_UNPARSED_ENTITY,
7832
 
                 "Entity reference to unparsed entity %s\n", name);
7833
 
    }
7834
 
 
7835
 
    /*
7836
 
     * [ WFC: No External Entity References ]
7837
 
     * Attribute values cannot contain direct or indirect
7838
 
     * entity references to external entities.
7839
 
     */
7840
 
    else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
7841
 
             (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
7842
 
        xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_EXTERNAL,
7843
 
         "Attribute references external entity '%s'\n", name);
7844
 
    }
7845
 
    /*
7846
 
     * [ WFC: No < in Attribute Values ]
7847
 
     * The replacement text of any entity referred to directly or
7848
 
     * indirectly in an attribute value (other than "&lt;") must
7849
 
     * not contain a <.
7850
 
     */
7851
 
    else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
7852
 
             (ent != NULL) && (ent->content != NULL) &&
7853
 
             (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
7854
 
             (xmlStrchr(ent->content, '<'))) {
7855
 
        xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
7856
 
     "'<' in entity '%s' is not allowed in attributes values\n",
7857
 
                          name);
7858
 
    }
7859
 
 
7860
 
    /*
7861
 
     * Internal check, no parameter entities here ...
7862
 
     */
7863
 
    else {
7864
 
        switch (ent->etype) {
7865
 
            case XML_INTERNAL_PARAMETER_ENTITY:
7866
 
            case XML_EXTERNAL_PARAMETER_ENTITY:
7867
 
                xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,
7868
 
             "Attempt to reference the parameter entity '%s'\n",
7869
 
                                  name);
7870
 
            break;
7871
 
            default:
7872
 
            break;
7873
 
        }
7874
 
    }
7875
 
 
7876
 
    /*
7877
 
     * [ WFC: No Recursion ]
7878
 
     * A parsed entity must not contain a recursive reference
7879
 
     * to itself, either directly or indirectly.
7880
 
     * Done somewhere else
7881
 
     */
7882
 
 
7883
 
    xmlFree(name);
7884
 
    *str = ptr;
7885
 
    return(ent);
7886
 
}
7887
 
 
7888
 
/**
7889
 
 * xmlParsePEReference:
7890
 
 * @ctxt:  an XML parser context
7891
 
 *
7892
 
 * parse PEReference declarations
7893
 
 * The entity content is handled directly by pushing it's content as
7894
 
 * a new input stream.
7895
 
 *
7896
 
 * [69] PEReference ::= '%' Name ';'
7897
 
 *
7898
 
 * [ WFC: No Recursion ]
7899
 
 * A parsed entity must not contain a recursive
7900
 
 * reference to itself, either directly or indirectly.
7901
 
 *
7902
 
 * [ WFC: Entity Declared ]
7903
 
 * In a document without any DTD, a document with only an internal DTD
7904
 
 * subset which contains no parameter entity references, or a document
7905
 
 * with "standalone='yes'", ...  ... The declaration of a parameter
7906
 
 * entity must precede any reference to it...
7907
 
 *
7908
 
 * [ VC: Entity Declared ]
7909
 
 * In a document with an external subset or external parameter entities
7910
 
 * with "standalone='no'", ...  ... The declaration of a parameter entity
7911
 
 * must precede any reference to it...
7912
 
 *
7913
 
 * [ WFC: In DTD ]
7914
 
 * Parameter-entity references may only appear in the DTD.
7915
 
 * NOTE: misleading but this is handled.
7916
 
 */
7917
 
void
7918
 
xmlParsePEReference(xmlParserCtxtPtr ctxt)
7919
 
{
7920
 
    const xmlChar *name;
7921
 
    xmlEntityPtr entity = NULL;
7922
 
    xmlParserInputPtr input;
7923
 
 
7924
 
    if (RAW != '%')
7925
 
        return;
7926
 
    NEXT;
7927
 
    name = xmlParseName(ctxt);
7928
 
    if (name == NULL) {
7929
 
        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
7930
 
                       "xmlParsePEReference: no name\n");
7931
 
        return;
7932
 
    }
7933
 
    if (RAW != ';') {
7934
 
        xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
7935
 
        return;
7936
 
    }
7937
 
 
7938
 
    NEXT;
7939
 
 
7940
 
    /*
7941
 
     * Increate the number of entity references parsed
7942
 
     */
7943
 
    ctxt->nbentities++;
7944
 
 
7945
 
    /*
7946
 
     * Request the entity from SAX
7947
 
     */
7948
 
    if ((ctxt->sax != NULL) &&
7949
 
        (ctxt->sax->getParameterEntity != NULL))
7950
 
        entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
7951
 
    if (ctxt->instate == XML_PARSER_EOF)
7952
 
        return;
7953
 
    if (entity == NULL) {
7954
 
        /*
7955
 
         * [ WFC: Entity Declared ]
7956
 
         * In a document without any DTD, a document with only an
7957
 
         * internal DTD subset which contains no parameter entity
7958
 
         * references, or a document with "standalone='yes'", ...
7959
 
         * ... The declaration of a parameter entity must precede
7960
 
         * any reference to it...
7961
 
         */
7962
 
        if ((ctxt->standalone == 1) ||
7963
 
            ((ctxt->hasExternalSubset == 0) &&
7964
 
             (ctxt->hasPErefs == 0))) {
7965
 
            xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
7966
 
                              "PEReference: %%%s; not found\n",
7967
 
                              name);
7968
 
        } else {
7969
 
            /*
7970
 
             * [ VC: Entity Declared ]
7971
 
             * In a document with an external subset or external
7972
 
             * parameter entities with "standalone='no'", ...
7973
 
             * ... The declaration of a parameter entity must
7974
 
             * precede any reference to it...
7975
 
             */
7976
 
            xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
7977
 
                          "PEReference: %%%s; not found\n",
7978
 
                          name, NULL);
7979
 
            ctxt->valid = 0;
7980
 
        }
7981
 
    } else {
7982
 
        /*
7983
 
         * Internal checking in case the entity quest barfed
7984
 
         */
7985
 
        if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
7986
 
            (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
7987
 
            xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
7988
 
                  "Internal: %%%s; is not a parameter entity\n",
7989
 
                          name, NULL);
7990
 
        } else if (ctxt->input->free != deallocblankswrapper) {
7991
 
            input = xmlNewBlanksWrapperInputStream(ctxt, entity);
7992
 
            if (xmlPushInput(ctxt, input) < 0)
7993
 
                return;
7994
 
        } else {
7995
 
            /*
7996
 
             * TODO !!!
7997
 
             * handle the extra spaces added before and after
7998
 
             * c.f. http://www.w3.org/TR/REC-xml#as-PE
7999
 
             */
8000
 
            input = xmlNewEntityInputStream(ctxt, entity);
8001
 
            if (xmlPushInput(ctxt, input) < 0)
8002
 
                return;
8003
 
            if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
8004
 
                (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) &&
8005
 
                (IS_BLANK_CH(NXT(5)))) {
8006
 
                xmlParseTextDecl(ctxt);
8007
 
                if (ctxt->errNo ==
8008
 
                    XML_ERR_UNSUPPORTED_ENCODING) {
8009
 
                    /*
8010
 
                     * The XML REC instructs us to stop parsing
8011
 
                     * right here
8012
 
                     */
8013
 
                    ctxt->instate = XML_PARSER_EOF;
8014
 
                    return;
8015
 
                }
8016
 
            }
8017
 
        }
8018
 
    }
8019
 
    ctxt->hasPErefs = 1;
8020
 
}
8021
 
 
8022
 
/**
8023
 
 * xmlLoadEntityContent:
8024
 
 * @ctxt:  an XML parser context
8025
 
 * @entity: an unloaded system entity
8026
 
 *
8027
 
 * Load the original content of the given system entity from the
8028
 
 * ExternalID/SystemID given. This is to be used for Included in Literal
8029
 
 * http://www.w3.org/TR/REC-xml/#inliteral processing of entities references
8030
 
 *
8031
 
 * Returns 0 in case of success and -1 in case of failure
8032
 
 */
8033
 
static int
8034
 
xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
8035
 
    xmlParserInputPtr input;
8036
 
    xmlBufferPtr buf;
8037
 
    int l, c;
8038
 
    int count = 0;
8039
 
 
8040
 
    if ((ctxt == NULL) || (entity == NULL) ||
8041
 
        ((entity->etype != XML_EXTERNAL_PARAMETER_ENTITY) &&
8042
 
         (entity->etype != XML_EXTERNAL_GENERAL_PARSED_ENTITY)) ||
8043
 
        (entity->content != NULL)) {
8044
 
        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
8045
 
                    "xmlLoadEntityContent parameter error");
8046
 
        return(-1);
8047
 
    }
8048
 
 
8049
 
    if (xmlParserDebugEntities)
8050
 
        xmlGenericError(xmlGenericErrorContext,
8051
 
                "Reading %s entity content input\n", entity->name);
8052
 
 
8053
 
    buf = xmlBufferCreate();
8054
 
    if (buf == NULL) {
8055
 
        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
8056
 
                    "xmlLoadEntityContent parameter error");
8057
 
        return(-1);
8058
 
    }
8059
 
 
8060
 
    input = xmlNewEntityInputStream(ctxt, entity);
8061
 
    if (input == NULL) {
8062
 
        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
8063
 
                    "xmlLoadEntityContent input error");
8064
 
        xmlBufferFree(buf);
8065
 
        return(-1);
8066
 
    }
8067
 
 
8068
 
    /*
8069
 
     * Push the entity as the current input, read char by char
8070
 
     * saving to the buffer until the end of the entity or an error
8071
 
     */
8072
 
    if (xmlPushInput(ctxt, input) < 0) {
8073
 
        xmlBufferFree(buf);
8074
 
        return(-1);
8075
 
    }
8076
 
 
8077
 
    GROW;
8078
 
    c = CUR_CHAR(l);
8079
 
    while ((ctxt->input == input) && (ctxt->input->cur < ctxt->input->end) &&
8080
 
           (IS_CHAR(c))) {
8081
 
        xmlBufferAdd(buf, ctxt->input->cur, l);
8082
 
        if (count++ > XML_PARSER_CHUNK_SIZE) {
8083
 
            count = 0;
8084
 
            GROW;
8085
 
            if (ctxt->instate == XML_PARSER_EOF) {
8086
 
                xmlBufferFree(buf);
8087
 
                return(-1);
8088
 
            }
8089
 
        }
8090
 
        NEXTL(l);
8091
 
        c = CUR_CHAR(l);
8092
 
        if (c == 0) {
8093
 
            count = 0;
8094
 
            GROW;
8095
 
            if (ctxt->instate == XML_PARSER_EOF) {
8096
 
                xmlBufferFree(buf);
8097
 
                return(-1);
8098
 
            }
8099
 
            c = CUR_CHAR(l);
8100
 
        }
8101
 
    }
8102
 
 
8103
 
    if ((ctxt->input == input) && (ctxt->input->cur >= ctxt->input->end)) {
8104
 
        xmlPopInput(ctxt);
8105
 
    } else if (!IS_CHAR(c)) {
8106
 
        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
8107
 
                          "xmlLoadEntityContent: invalid char value %d\n",
8108
 
                          c);
8109
 
        xmlBufferFree(buf);
8110
 
        return(-1);
8111
 
    }
8112
 
    entity->content = buf->content;
8113
 
    buf->content = NULL;
8114
 
    xmlBufferFree(buf);
8115
 
 
8116
 
    return(0);
8117
 
}
8118
 
 
8119
 
/**
8120
 
 * xmlParseStringPEReference:
8121
 
 * @ctxt:  an XML parser context
8122
 
 * @str:  a pointer to an index in the string
8123
 
 *
8124
 
 * parse PEReference declarations
8125
 
 *
8126
 
 * [69] PEReference ::= '%' Name ';'
8127
 
 *
8128
 
 * [ WFC: No Recursion ]
8129
 
 * A parsed entity must not contain a recursive
8130
 
 * reference to itself, either directly or indirectly.
8131
 
 *
8132
 
 * [ WFC: Entity Declared ]
8133
 
 * In a document without any DTD, a document with only an internal DTD
8134
 
 * subset which contains no parameter entity references, or a document
8135
 
 * with "standalone='yes'", ...  ... The declaration of a parameter
8136
 
 * entity must precede any reference to it...
8137
 
 *
8138
 
 * [ VC: Entity Declared ]
8139
 
 * In a document with an external subset or external parameter entities
8140
 
 * with "standalone='no'", ...  ... The declaration of a parameter entity
8141
 
 * must precede any reference to it...
8142
 
 *
8143
 
 * [ WFC: In DTD ]
8144
 
 * Parameter-entity references may only appear in the DTD.
8145
 
 * NOTE: misleading but this is handled.
8146
 
 *
8147
 
 * Returns the string of the entity content.
8148
 
 *         str is updated to the current value of the index
8149
 
 */
8150
 
static xmlEntityPtr
8151
 
xmlParseStringPEReference(xmlParserCtxtPtr ctxt, const xmlChar **str) {
8152
 
    const xmlChar *ptr;
8153
 
    xmlChar cur;
8154
 
    xmlChar *name;
8155
 
    xmlEntityPtr entity = NULL;
8156
 
 
8157
 
    if ((str == NULL) || (*str == NULL)) return(NULL);
8158
 
    ptr = *str;
8159
 
    cur = *ptr;
8160
 
    if (cur != '%')
8161
 
        return(NULL);
8162
 
    ptr++;
8163
 
    name = xmlParseStringName(ctxt, &ptr);
8164
 
    if (name == NULL) {
8165
 
        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8166
 
                       "xmlParseStringPEReference: no name\n");
8167
 
        *str = ptr;
8168
 
        return(NULL);
8169
 
    }
8170
 
    cur = *ptr;
8171
 
    if (cur != ';') {
8172
 
        xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL);
8173
 
        xmlFree(name);
8174
 
        *str = ptr;
8175
 
        return(NULL);
8176
 
    }
8177
 
    ptr++;
8178
 
 
8179
 
    /*
8180
 
     * Increate the number of entity references parsed
8181
 
     */
8182
 
    ctxt->nbentities++;
8183
 
 
8184
 
    /*
8185
 
     * Request the entity from SAX
8186
 
     */
8187
 
    if ((ctxt->sax != NULL) &&
8188
 
        (ctxt->sax->getParameterEntity != NULL))
8189
 
        entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
8190
 
    if (ctxt->instate == XML_PARSER_EOF) {
8191
 
        xmlFree(name);
8192
 
        return(NULL);
8193
 
    }
8194
 
    if (entity == NULL) {
8195
 
        /*
8196
 
         * [ WFC: Entity Declared ]
8197
 
         * In a document without any DTD, a document with only an
8198
 
         * internal DTD subset which contains no parameter entity
8199
 
         * references, or a document with "standalone='yes'", ...
8200
 
         * ... The declaration of a parameter entity must precede
8201
 
         * any reference to it...
8202
 
         */
8203
 
        if ((ctxt->standalone == 1) ||
8204
 
            ((ctxt->hasExternalSubset == 0) && (ctxt->hasPErefs == 0))) {
8205
 
            xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
8206
 
                 "PEReference: %%%s; not found\n", name);
8207
 
        } else {
8208
 
            /*
8209
 
             * [ VC: Entity Declared ]
8210
 
             * In a document with an external subset or external
8211
 
             * parameter entities with "standalone='no'", ...
8212
 
             * ... The declaration of a parameter entity must
8213
 
             * precede any reference to it...
8214
 
             */
8215
 
            xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
8216
 
                          "PEReference: %%%s; not found\n",
8217
 
                          name, NULL);
8218
 
            ctxt->valid = 0;
8219
 
        }
8220
 
    } else {
8221
 
        /*
8222
 
         * Internal checking in case the entity quest barfed
8223
 
         */
8224
 
        if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
8225
 
            (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
8226
 
            xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,
8227
 
                          "%%%s; is not a parameter entity\n",
8228
 
                          name, NULL);
8229
 
        }
8230
 
    }
8231
 
    ctxt->hasPErefs = 1;
8232
 
    xmlFree(name);
8233
 
    *str = ptr;
8234
 
    return(entity);
8235
 
}
8236
 
 
8237
 
/**
8238
 
 * xmlParseDocTypeDecl:
8239
 
 * @ctxt:  an XML parser context
8240
 
 *
8241
 
 * parse a DOCTYPE declaration
8242
 
 *
8243
 
 * [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S?
8244
 
 *                      ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
8245
 
 *
8246
 
 * [ VC: Root Element Type ]
8247
 
 * The Name in the document type declaration must match the element
8248
 
 * type of the root element.
8249
 
 */
8250
 
 
8251
 
void
8252
 
xmlParseDocTypeDecl(xmlParserCtxtPtr ctxt) {
8253
 
    const xmlChar *name = NULL;
8254
 
    xmlChar *ExternalID = NULL;
8255
 
    xmlChar *URI = NULL;
8256
 
 
8257
 
    /*
8258
 
     * We know that '<!DOCTYPE' has been detected.
8259
 
     */
8260
 
    SKIP(9);
8261
 
 
8262
 
    SKIP_BLANKS;
8263
 
 
8264
 
    /*
8265
 
     * Parse the DOCTYPE name.
8266
 
     */
8267
 
    name = xmlParseName(ctxt);
8268
 
    if (name == NULL) {
8269
 
        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8270
 
                       "xmlParseDocTypeDecl : no DOCTYPE name !\n");
8271
 
    }
8272
 
    ctxt->intSubName = name;
8273
 
 
8274
 
    SKIP_BLANKS;
8275
 
 
8276
 
    /*
8277
 
     * Check for SystemID and ExternalID
8278
 
     */
8279
 
    URI = xmlParseExternalID(ctxt, &ExternalID, 1);
8280
 
 
8281
 
    if ((URI != NULL) || (ExternalID != NULL)) {
8282
 
        ctxt->hasExternalSubset = 1;
8283
 
    }
8284
 
    ctxt->extSubURI = URI;
8285
 
    ctxt->extSubSystem = ExternalID;
8286
 
 
8287
 
    SKIP_BLANKS;
8288
 
 
8289
 
    /*
8290
 
     * Create and update the internal subset.
8291
 
     */
8292
 
    if ((ctxt->sax != NULL) && (ctxt->sax->internalSubset != NULL) &&
8293
 
        (!ctxt->disableSAX))
8294
 
        ctxt->sax->internalSubset(ctxt->userData, name, ExternalID, URI);
8295
 
    if (ctxt->instate == XML_PARSER_EOF)
8296
 
        return;
8297
 
 
8298
 
    /*
8299
 
     * Is there any internal subset declarations ?
8300
 
     * they are handled separately in xmlParseInternalSubset()
8301
 
     */
8302
 
    if (RAW == '[')
8303
 
        return;
8304
 
 
8305
 
    /*
8306
 
     * We should be at the end of the DOCTYPE declaration.
8307
 
     */
8308
 
    if (RAW != '>') {
8309
 
        xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
8310
 
    }
8311
 
    NEXT;
8312
 
}
8313
 
 
8314
 
/**
8315
 
 * xmlParseInternalSubset:
8316
 
 * @ctxt:  an XML parser context
8317
 
 *
8318
 
 * parse the internal subset declaration
8319
 
 *
8320
 
 * [28 end] ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
8321
 
 */
8322
 
 
8323
 
static void
8324
 
xmlParseInternalSubset(xmlParserCtxtPtr ctxt) {
8325
 
    /*
8326
 
     * Is there any DTD definition ?
8327
 
     */
8328
 
    if (RAW == '[') {
8329
 
        ctxt->instate = XML_PARSER_DTD;
8330
 
        NEXT;
8331
 
        /*
8332
 
         * Parse the succession of Markup declarations and
8333
 
         * PEReferences.
8334
 
         * Subsequence (markupdecl | PEReference | S)*
8335
 
         */
8336
 
        while ((RAW != ']') && (ctxt->instate != XML_PARSER_EOF)) {
8337
 
            const xmlChar *check = CUR_PTR;
8338
 
            unsigned int cons = ctxt->input->consumed;
8339
 
 
8340
 
            SKIP_BLANKS;
8341
 
            xmlParseMarkupDecl(ctxt);
8342
 
            xmlParsePEReference(ctxt);
8343
 
 
8344
 
            /*
8345
 
             * Pop-up of finished entities.
8346
 
             */
8347
 
            while ((RAW == 0) && (ctxt->inputNr > 1))
8348
 
                xmlPopInput(ctxt);
8349
 
 
8350
 
            if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
8351
 
                xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
8352
 
             "xmlParseInternalSubset: error detected in Markup declaration\n");
8353
 
                break;
8354
 
            }
8355
 
        }
8356
 
        if (RAW == ']') {
8357
 
            NEXT;
8358
 
            SKIP_BLANKS;
8359
 
        }
8360
 
    }
8361
 
 
8362
 
    /*
8363
 
     * We should be at the end of the DOCTYPE declaration.
8364
 
     */
8365
 
    if (RAW != '>') {
8366
 
        xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
8367
 
    }
8368
 
    NEXT;
8369
 
}
8370
 
 
8371
 
#ifdef LIBXML_SAX1_ENABLED
8372
 
/**
8373
 
 * xmlParseAttribute:
8374
 
 * @ctxt:  an XML parser context
8375
 
 * @value:  a xmlChar ** used to store the value of the attribute
8376
 
 *
8377
 
 * parse an attribute
8378
 
 *
8379
 
 * [41] Attribute ::= Name Eq AttValue
8380
 
 *
8381
 
 * [ WFC: No External Entity References ]
8382
 
 * Attribute values cannot contain direct or indirect entity references
8383
 
 * to external entities.
8384
 
 *
8385
 
 * [ WFC: No < in Attribute Values ]
8386
 
 * The replacement text of any entity referred to directly or indirectly in
8387
 
 * an attribute value (other than "&lt;") must not contain a <.
8388
 
 *
8389
 
 * [ VC: Attribute Value Type ]
8390
 
 * The attribute must have been declared; the value must be of the type
8391
 
 * declared for it.
8392
 
 *
8393
 
 * [25] Eq ::= S? '=' S?
8394
 
 *
8395
 
 * With namespace:
8396
 
 *
8397
 
 * [NS 11] Attribute ::= QName Eq AttValue
8398
 
 *
8399
 
 * Also the case QName == xmlns:??? is handled independently as a namespace
8400
 
 * definition.
8401
 
 *
8402
 
 * Returns the attribute name, and the value in *value.
8403
 
 */
8404
 
 
8405
 
const xmlChar *
8406
 
xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlChar **value) {
8407
 
    const xmlChar *name;
8408
 
    xmlChar *val;
8409
 
 
8410
 
    *value = NULL;
8411
 
    GROW;
8412
 
    name = xmlParseName(ctxt);
8413
 
    if (name == NULL) {
8414
 
        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8415
 
                       "error parsing attribute name\n");
8416
 
        return(NULL);
8417
 
    }
8418
 
 
8419
 
    /*
8420
 
     * read the value
8421
 
     */
8422
 
    SKIP_BLANKS;
8423
 
    if (RAW == '=') {
8424
 
        NEXT;
8425
 
        SKIP_BLANKS;
8426
 
        val = xmlParseAttValue(ctxt);
8427
 
        ctxt->instate = XML_PARSER_CONTENT;
8428
 
    } else {
8429
 
        xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
8430
 
               "Specification mandate value for attribute %s\n", name);
8431
 
        return(NULL);
8432
 
    }
8433
 
 
8434
 
    /*
8435
 
     * Check that xml:lang conforms to the specification
8436
 
     * No more registered as an error, just generate a warning now
8437
 
     * since this was deprecated in XML second edition
8438
 
     */
8439
 
    if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "xml:lang"))) {
8440
 
        if (!xmlCheckLanguageID(val)) {
8441
 
            xmlWarningMsg(ctxt, XML_WAR_LANG_VALUE,
8442
 
                          "Malformed value for xml:lang : %s\n",
8443
 
                          val, NULL);
8444
 
        }
8445
 
    }
8446
 
 
8447
 
    /*
8448
 
     * Check that xml:space conforms to the specification
8449
 
     */
8450
 
    if (xmlStrEqual(name, BAD_CAST "xml:space")) {
8451
 
        if (xmlStrEqual(val, BAD_CAST "default"))
8452
 
            *(ctxt->space) = 0;
8453
 
        else if (xmlStrEqual(val, BAD_CAST "preserve"))
8454
 
            *(ctxt->space) = 1;
8455
 
        else {
8456
 
                xmlWarningMsg(ctxt, XML_WAR_SPACE_VALUE,
8457
 
"Invalid value \"%s\" for xml:space : \"default\" or \"preserve\" expected\n",
8458
 
                                 val, NULL);
8459
 
        }
8460
 
    }
8461
 
 
8462
 
    *value = val;
8463
 
    return(name);
8464
 
}
8465
 
 
8466
 
/**
8467
 
 * xmlParseStartTag:
8468
 
 * @ctxt:  an XML parser context
8469
 
 *
8470
 
 * parse a start of tag either for rule element or
8471
 
 * EmptyElement. In both case we don't parse the tag closing chars.
8472
 
 *
8473
 
 * [40] STag ::= '<' Name (S Attribute)* S? '>'
8474
 
 *
8475
 
 * [ WFC: Unique Att Spec ]
8476
 
 * No attribute name may appear more than once in the same start-tag or
8477
 
 * empty-element tag.
8478
 
 *
8479
 
 * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
8480
 
 *
8481
 
 * [ WFC: Unique Att Spec ]
8482
 
 * No attribute name may appear more than once in the same start-tag or
8483
 
 * empty-element tag.
8484
 
 *
8485
 
 * With namespace:
8486
 
 *
8487
 
 * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
8488
 
 *
8489
 
 * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
8490
 
 *
8491
 
 * Returns the element name parsed
8492
 
 */
8493
 
 
8494
 
const xmlChar *
8495
 
xmlParseStartTag(xmlParserCtxtPtr ctxt) {
8496
 
    const xmlChar *name;
8497
 
    const xmlChar *attname;
8498
 
    xmlChar *attvalue;
8499
 
    const xmlChar **atts = ctxt->atts;
8500
 
    int nbatts = 0;
8501
 
    int maxatts = ctxt->maxatts;
8502
 
    int i;
8503
 
 
8504
 
    if (RAW != '<') return(NULL);
8505
 
    NEXT1;
8506
 
 
8507
 
    name = xmlParseName(ctxt);
8508
 
    if (name == NULL) {
8509
 
        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
8510
 
             "xmlParseStartTag: invalid element name\n");
8511
 
        return(NULL);
8512
 
    }
8513
 
 
8514
 
    /*
8515
 
     * Now parse the attributes, it ends up with the ending
8516
 
     *
8517
 
     * (S Attribute)* S?
8518
 
     */
8519
 
    SKIP_BLANKS;
8520
 
    GROW;
8521
 
 
8522
 
    while (((RAW != '>') &&
8523
 
           ((RAW != '/') || (NXT(1) != '>')) &&
8524
 
           (IS_BYTE_CHAR(RAW))) && (ctxt->instate != XML_PARSER_EOF)) {
8525
 
        const xmlChar *q = CUR_PTR;
8526
 
        unsigned int cons = ctxt->input->consumed;
8527
 
 
8528
 
        attname = xmlParseAttribute(ctxt, &attvalue);
8529
 
        if ((attname != NULL) && (attvalue != NULL)) {
8530
 
            /*
8531
 
             * [ WFC: Unique Att Spec ]
8532
 
             * No attribute name may appear more than once in the same
8533
 
             * start-tag or empty-element tag.
8534
 
             */
8535
 
            for (i = 0; i < nbatts;i += 2) {
8536
 
                if (xmlStrEqual(atts[i], attname)) {
8537
 
                    xmlErrAttributeDup(ctxt, NULL, attname);
8538
 
                    xmlFree(attvalue);
8539
 
                    goto failed;
8540
 
                }
8541
 
            }
8542
 
            /*
8543
 
             * Add the pair to atts
8544
 
             */
8545
 
            if (atts == NULL) {
8546
 
                maxatts = 22; /* allow for 10 attrs by default */
8547
 
                atts = (const xmlChar **)
8548
 
                       xmlMalloc(maxatts * sizeof(xmlChar *));
8549
 
                if (atts == NULL) {
8550
 
                    xmlErrMemory(ctxt, NULL);
8551
 
                    if (attvalue != NULL)
8552
 
                        xmlFree(attvalue);
8553
 
                    goto failed;
8554
 
                }
8555
 
                ctxt->atts = atts;
8556
 
                ctxt->maxatts = maxatts;
8557
 
            } else if (nbatts + 4 > maxatts) {
8558
 
                const xmlChar **n;
8559
 
 
8560
 
                maxatts *= 2;
8561
 
                n = (const xmlChar **) xmlRealloc((void *) atts,
8562
 
                                             maxatts * sizeof(const xmlChar *));
8563
 
                if (n == NULL) {
8564
 
                    xmlErrMemory(ctxt, NULL);
8565
 
                    if (attvalue != NULL)
8566
 
                        xmlFree(attvalue);
8567
 
                    goto failed;
8568
 
                }
8569
 
                atts = n;
8570
 
                ctxt->atts = atts;
8571
 
                ctxt->maxatts = maxatts;
8572
 
            }
8573
 
            atts[nbatts++] = attname;
8574
 
            atts[nbatts++] = attvalue;
8575
 
            atts[nbatts] = NULL;
8576
 
            atts[nbatts + 1] = NULL;
8577
 
        } else {
8578
 
            if (attvalue != NULL)
8579
 
                xmlFree(attvalue);
8580
 
        }
8581
 
 
8582
 
failed:
8583
 
 
8584
 
        GROW
8585
 
        if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
8586
 
            break;
8587
 
        if (!IS_BLANK_CH(RAW)) {
8588
 
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
8589
 
                           "attributes construct error\n");
8590
 
        }
8591
 
        SKIP_BLANKS;
8592
 
        if ((cons == ctxt->input->consumed) && (q == CUR_PTR) &&
8593
 
            (attname == NULL) && (attvalue == NULL)) {
8594
 
            xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
8595
 
                           "xmlParseStartTag: problem parsing attributes\n");
8596
 
            break;
8597
 
        }
8598
 
        SHRINK;
8599
 
        GROW;
8600
 
    }
8601
 
 
8602
 
    /*
8603
 
     * SAX: Start of Element !
8604
 
     */
8605
 
    if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL) &&
8606
 
        (!ctxt->disableSAX)) {
8607
 
        if (nbatts > 0)
8608
 
            ctxt->sax->startElement(ctxt->userData, name, atts);
8609
 
        else
8610
 
            ctxt->sax->startElement(ctxt->userData, name, NULL);
8611
 
    }
8612
 
 
8613
 
    if (atts != NULL) {
8614
 
        /* Free only the content strings */
8615
 
        for (i = 1;i < nbatts;i+=2)
8616
 
            if (atts[i] != NULL)
8617
 
               xmlFree((xmlChar *) atts[i]);
8618
 
    }
8619
 
    return(name);
8620
 
}
8621
 
 
8622
 
/**
8623
 
 * xmlParseEndTag1:
8624
 
 * @ctxt:  an XML parser context
8625
 
 * @line:  line of the start tag
8626
 
 * @nsNr:  number of namespaces on the start tag
8627
 
 *
8628
 
 * parse an end of tag
8629
 
 *
8630
 
 * [42] ETag ::= '</' Name S? '>'
8631
 
 *
8632
 
 * With namespace
8633
 
 *
8634
 
 * [NS 9] ETag ::= '</' QName S? '>'
8635
 
 */
8636
 
 
8637
 
static void
8638
 
xmlParseEndTag1(xmlParserCtxtPtr ctxt, int line) {
8639
 
    const xmlChar *name;
8640
 
 
8641
 
    GROW;
8642
 
    if ((RAW != '<') || (NXT(1) != '/')) {
8643
 
        xmlFatalErrMsg(ctxt, XML_ERR_LTSLASH_REQUIRED,
8644
 
                       "xmlParseEndTag: '</' not found\n");
8645
 
        return;
8646
 
    }
8647
 
    SKIP(2);
8648
 
 
8649
 
    name = xmlParseNameAndCompare(ctxt,ctxt->name);
8650
 
 
8651
 
    /*
8652
 
     * We should definitely be at the ending "S? '>'" part
8653
 
     */
8654
 
    GROW;
8655
 
    SKIP_BLANKS;
8656
 
    if ((!IS_BYTE_CHAR(RAW)) || (RAW != '>')) {
8657
 
        xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
8658
 
    } else
8659
 
        NEXT1;
8660
 
 
8661
 
    /*
8662
 
     * [ WFC: Element Type Match ]
8663
 
     * The Name in an element's end-tag must match the element type in the
8664
 
     * start-tag.
8665
 
     *
8666
 
     */
8667
 
    if (name != (xmlChar*)1) {
8668
 
        if (name == NULL) name = BAD_CAST "unparseable";
8669
 
        xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
8670
 
                     "Opening and ending tag mismatch: %s line %d and %s\n",
8671
 
                                ctxt->name, line, name);
8672
 
    }
8673
 
 
8674
 
    /*
8675
 
     * SAX: End of Tag
8676
 
     */
8677
 
    if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
8678
 
        (!ctxt->disableSAX))
8679
 
        ctxt->sax->endElement(ctxt->userData, ctxt->name);
8680
 
 
8681
 
    namePop(ctxt);
8682
 
    spacePop(ctxt);
8683
 
    return;
8684
 
}
8685
 
 
8686
 
/**
8687
 
 * xmlParseEndTag:
8688
 
 * @ctxt:  an XML parser context
8689
 
 *
8690
 
 * parse an end of tag
8691
 
 *
8692
 
 * [42] ETag ::= '</' Name S? '>'
8693
 
 *
8694
 
 * With namespace
8695
 
 *
8696
 
 * [NS 9] ETag ::= '</' QName S? '>'
8697
 
 */
8698
 
 
8699
 
void
8700
 
xmlParseEndTag(xmlParserCtxtPtr ctxt) {
8701
 
    xmlParseEndTag1(ctxt, 0);
8702
 
}
8703
 
#endif /* LIBXML_SAX1_ENABLED */
8704
 
 
8705
 
/************************************************************************
8706
 
 *                                                                      *
8707
 
 *                    SAX 2 specific operations                         *
8708
 
 *                                                                      *
8709
 
 ************************************************************************/
8710
 
 
8711
 
/*
8712
 
 * xmlGetNamespace:
8713
 
 * @ctxt:  an XML parser context
8714
 
 * @prefix:  the prefix to lookup
8715
 
 *
8716
 
 * Lookup the namespace name for the @prefix (which ca be NULL)
8717
 
 * The prefix must come from the @ctxt->dict dictionnary
8718
 
 *
8719
 
 * Returns the namespace name or NULL if not bound
8720
 
 */
8721
 
static const xmlChar *
8722
 
xmlGetNamespace(xmlParserCtxtPtr ctxt, const xmlChar *prefix) {
8723
 
    int i;
8724
 
 
8725
 
    if (prefix == ctxt->str_xml) return(ctxt->str_xml_ns);
8726
 
    for (i = ctxt->nsNr - 2;i >= 0;i-=2)
8727
 
        if (ctxt->nsTab[i] == prefix) {
8728
 
            if ((prefix == NULL) && (*ctxt->nsTab[i + 1] == 0))
8729
 
                return(NULL);
8730
 
            return(ctxt->nsTab[i + 1]);
8731
 
        }
8732
 
    return(NULL);
8733
 
}
8734
 
 
8735
 
/**
8736
 
 * xmlParseQName:
8737
 
 * @ctxt:  an XML parser context
8738
 
 * @prefix:  pointer to store the prefix part
8739
 
 *
8740
 
 * parse an XML Namespace QName
8741
 
 *
8742
 
 * [6]  QName  ::= (Prefix ':')? LocalPart
8743
 
 * [7]  Prefix  ::= NCName
8744
 
 * [8]  LocalPart  ::= NCName
8745
 
 *
8746
 
 * Returns the Name parsed or NULL
8747
 
 */
8748
 
 
8749
 
static const xmlChar *
8750
 
xmlParseQName(xmlParserCtxtPtr ctxt, const xmlChar **prefix) {
8751
 
    const xmlChar *l, *p;
8752
 
 
8753
 
    GROW;
8754
 
 
8755
 
    l = xmlParseNCName(ctxt);
8756
 
    if (l == NULL) {
8757
 
        if (CUR == ':') {
8758
 
            l = xmlParseName(ctxt);
8759
 
            if (l != NULL) {
8760
 
                xmlNsErr(ctxt, XML_NS_ERR_QNAME,
8761
 
                         "Failed to parse QName '%s'\n", l, NULL, NULL);
8762
 
                *prefix = NULL;
8763
 
                return(l);
8764
 
            }
8765
 
        }
8766
 
        return(NULL);
8767
 
    }
8768
 
    if (CUR == ':') {
8769
 
        NEXT;
8770
 
        p = l;
8771
 
        l = xmlParseNCName(ctxt);
8772
 
        if (l == NULL) {
8773
 
            xmlChar *tmp;
8774
 
 
8775
 
            xmlNsErr(ctxt, XML_NS_ERR_QNAME,
8776
 
                     "Failed to parse QName '%s:'\n", p, NULL, NULL);
8777
 
            l = xmlParseNmtoken(ctxt);
8778
 
            if (l == NULL)
8779
 
                tmp = xmlBuildQName(BAD_CAST "", p, NULL, 0);
8780
 
            else {
8781
 
                tmp = xmlBuildQName(l, p, NULL, 0);
8782
 
                xmlFree((char *)l);
8783
 
            }
8784
 
            p = xmlDictLookup(ctxt->dict, tmp, -1);
8785
 
            if (tmp != NULL) xmlFree(tmp);
8786
 
            *prefix = NULL;
8787
 
            return(p);
8788
 
        }
8789
 
        if (CUR == ':') {
8790
 
            xmlChar *tmp;
8791
 
 
8792
 
            xmlNsErr(ctxt, XML_NS_ERR_QNAME,
8793
 
                     "Failed to parse QName '%s:%s:'\n", p, l, NULL);
8794
 
            NEXT;
8795
 
            tmp = (xmlChar *) xmlParseName(ctxt);
8796
 
            if (tmp != NULL) {
8797
 
                tmp = xmlBuildQName(tmp, l, NULL, 0);
8798
 
                l = xmlDictLookup(ctxt->dict, tmp, -1);
8799
 
                if (tmp != NULL) xmlFree(tmp);
8800
 
                *prefix = p;
8801
 
                return(l);
8802
 
            }
8803
 
            tmp = xmlBuildQName(BAD_CAST "", l, NULL, 0);
8804
 
            l = xmlDictLookup(ctxt->dict, tmp, -1);
8805
 
            if (tmp != NULL) xmlFree(tmp);
8806
 
            *prefix = p;
8807
 
            return(l);
8808
 
        }
8809
 
        *prefix = p;
8810
 
    } else
8811
 
        *prefix = NULL;
8812
 
    return(l);
8813
 
}
8814
 
 
8815
 
/**
8816
 
 * xmlParseQNameAndCompare:
8817
 
 * @ctxt:  an XML parser context
8818
 
 * @name:  the localname
8819
 
 * @prefix:  the prefix, if any.
8820
 
 *
8821
 
 * parse an XML name and compares for match
8822
 
 * (specialized for endtag parsing)
8823
 
 *
8824
 
 * Returns NULL for an illegal name, (xmlChar*) 1 for success
8825
 
 * and the name for mismatch
8826
 
 */
8827
 
 
8828
 
static const xmlChar *
8829
 
xmlParseQNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *name,
8830
 
                        xmlChar const *prefix) {
8831
 
    const xmlChar *cmp;
8832
 
    const xmlChar *in;
8833
 
    const xmlChar *ret;
8834
 
    const xmlChar *prefix2;
8835
 
 
8836
 
    if (prefix == NULL) return(xmlParseNameAndCompare(ctxt, name));
8837
 
 
8838
 
    GROW;
8839
 
    in = ctxt->input->cur;
8840
 
 
8841
 
    cmp = prefix;
8842
 
    while (*in != 0 && *in == *cmp) {
8843
 
        ++in;
8844
 
        ++cmp;
8845
 
    }
8846
 
    if ((*cmp == 0) && (*in == ':')) {
8847
 
        in++;
8848
 
        cmp = name;
8849
 
        while (*in != 0 && *in == *cmp) {
8850
 
            ++in;
8851
 
            ++cmp;
8852
 
        }
8853
 
        if (*cmp == 0 && (*in == '>' || IS_BLANK_CH (*in))) {
8854
 
            /* success */
8855
 
            ctxt->input->cur = in;
8856
 
            return((const xmlChar*) 1);
8857
 
        }
8858
 
    }
8859
 
    /*
8860
 
     * all strings coms from the dictionary, equality can be done directly
8861
 
     */
8862
 
    ret = xmlParseQName (ctxt, &prefix2);
8863
 
    if ((ret == name) && (prefix == prefix2))
8864
 
        return((const xmlChar*) 1);
8865
 
    return ret;
8866
 
}
8867
 
 
8868
 
/**
8869
 
 * xmlParseAttValueInternal:
8870
 
 * @ctxt:  an XML parser context
8871
 
 * @len:  attribute len result
8872
 
 * @alloc:  whether the attribute was reallocated as a new string
8873
 
 * @normalize:  if 1 then further non-CDATA normalization must be done
8874
 
 *
8875
 
 * parse a value for an attribute.
8876
 
 * NOTE: if no normalization is needed, the routine will return pointers
8877
 
 *       directly from the data buffer.
8878
 
 *
8879
 
 * 3.3.3 Attribute-Value Normalization:
8880
 
 * Before the value of an attribute is passed to the application or
8881
 
 * checked for validity, the XML processor must normalize it as follows:
8882
 
 * - a character reference is processed by appending the referenced
8883
 
 *   character to the attribute value
8884
 
 * - an entity reference is processed by recursively processing the
8885
 
 *   replacement text of the entity
8886
 
 * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
8887
 
 *   appending #x20 to the normalized value, except that only a single
8888
 
 *   #x20 is appended for a "#xD#xA" sequence that is part of an external
8889
 
 *   parsed entity or the literal entity value of an internal parsed entity
8890
 
 * - other characters are processed by appending them to the normalized value
8891
 
 * If the declared value is not CDATA, then the XML processor must further
8892
 
 * process the normalized attribute value by discarding any leading and
8893
 
 * trailing space (#x20) characters, and by replacing sequences of space
8894
 
 * (#x20) characters by a single space (#x20) character.
8895
 
 * All attributes for which no declaration has been read should be treated
8896
 
 * by a non-validating parser as if declared CDATA.
8897
 
 *
8898
 
 * Returns the AttValue parsed or NULL. The value has to be freed by the
8899
 
 *     caller if it was copied, this can be detected by val[*len] == 0.
8900
 
 */
8901
 
 
8902
 
static xmlChar *
8903
 
xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
8904
 
                         int normalize)
8905
 
{
8906
 
    xmlChar limit = 0;
8907
 
    const xmlChar *in = NULL, *start, *end, *last;
8908
 
    xmlChar *ret = NULL;
8909
 
 
8910
 
    GROW;
8911
 
    in = (xmlChar *) CUR_PTR;
8912
 
    if (*in != '"' && *in != '\'') {
8913
 
        xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
8914
 
        return (NULL);
8915
 
    }
8916
 
    ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
8917
 
 
8918
 
    /*
8919
 
     * try to handle in this routine the most common case where no
8920
 
     * allocation of a new string is required and where content is
8921
 
     * pure ASCII.
8922
 
     */
8923
 
    limit = *in++;
8924
 
    end = ctxt->input->end;
8925
 
    start = in;
8926
 
    if (in >= end) {
8927
 
        const xmlChar *oldbase = ctxt->input->base;
8928
 
        GROW;
8929
 
        if (oldbase != ctxt->input->base) {
8930
 
            long delta = ctxt->input->base - oldbase;
8931
 
            start = start + delta;
8932
 
            in = in + delta;
8933
 
        }
8934
 
        end = ctxt->input->end;
8935
 
    }
8936
 
    if (normalize) {
8937
 
        /*
8938
 
         * Skip any leading spaces
8939
 
         */
8940
 
        while ((in < end) && (*in != limit) &&
8941
 
               ((*in == 0x20) || (*in == 0x9) ||
8942
 
                (*in == 0xA) || (*in == 0xD))) {
8943
 
            in++;
8944
 
            start = in;
8945
 
            if (in >= end) {
8946
 
                const xmlChar *oldbase = ctxt->input->base;
8947
 
                GROW;
8948
 
                if (ctxt->instate == XML_PARSER_EOF)
8949
 
                    return(NULL);
8950
 
                if (oldbase != ctxt->input->base) {
8951
 
                    long delta = ctxt->input->base - oldbase;
8952
 
                    start = start + delta;
8953
 
                    in = in + delta;
8954
 
                }
8955
 
                end = ctxt->input->end;
8956
 
                if (((in - start) > XML_MAX_TEXT_LENGTH) &&
8957
 
                    ((ctxt->options & XML_PARSE_HUGE) == 0)) {
8958
 
                    xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
8959
 
                                   "AttValue length too long\n");
8960
 
                    return(NULL);
8961
 
                }
8962
 
            }
8963
 
        }
8964
 
        while ((in < end) && (*in != limit) && (*in >= 0x20) &&
8965
 
               (*in <= 0x7f) && (*in != '&') && (*in != '<')) {
8966
 
            if ((*in++ == 0x20) && (*in == 0x20)) break;
8967
 
            if (in >= end) {
8968
 
                const xmlChar *oldbase = ctxt->input->base;
8969
 
                GROW;
8970
 
                if (ctxt->instate == XML_PARSER_EOF)
8971
 
                    return(NULL);
8972
 
                if (oldbase != ctxt->input->base) {
8973
 
                    long delta = ctxt->input->base - oldbase;
8974
 
                    start = start + delta;
8975
 
                    in = in + delta;
8976
 
                }
8977
 
                end = ctxt->input->end;
8978
 
                if (((in - start) > XML_MAX_TEXT_LENGTH) &&
8979
 
                    ((ctxt->options & XML_PARSE_HUGE) == 0)) {
8980
 
                    xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
8981
 
                                   "AttValue length too long\n");
8982
 
                    return(NULL);
8983
 
                }
8984
 
            }
8985
 
        }
8986
 
        last = in;
8987
 
        /*
8988
 
         * skip the trailing blanks
8989
 
         */
8990
 
        while ((last[-1] == 0x20) && (last > start)) last--;
8991
 
        while ((in < end) && (*in != limit) &&
8992
 
               ((*in == 0x20) || (*in == 0x9) ||
8993
 
                (*in == 0xA) || (*in == 0xD))) {
8994
 
            in++;
8995
 
            if (in >= end) {
8996
 
                const xmlChar *oldbase = ctxt->input->base;
8997
 
                GROW;
8998
 
                if (ctxt->instate == XML_PARSER_EOF)
8999
 
                    return(NULL);
9000
 
                if (oldbase != ctxt->input->base) {
9001
 
                    long delta = ctxt->input->base - oldbase;
9002
 
                    start = start + delta;
9003
 
                    in = in + delta;
9004
 
                    last = last + delta;
9005
 
                }
9006
 
                end = ctxt->input->end;
9007
 
                if (((in - start) > XML_MAX_TEXT_LENGTH) &&
9008
 
                    ((ctxt->options & XML_PARSE_HUGE) == 0)) {
9009
 
                    xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
9010
 
                                   "AttValue length too long\n");
9011
 
                    return(NULL);
9012
 
                }
9013
 
            }
9014
 
        }
9015
 
        if (((in - start) > XML_MAX_TEXT_LENGTH) &&
9016
 
            ((ctxt->options & XML_PARSE_HUGE) == 0)) {
9017
 
            xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
9018
 
                           "AttValue length too long\n");
9019
 
            return(NULL);
9020
 
        }
9021
 
        if (*in != limit) goto need_complex;
9022
 
    } else {
9023
 
        while ((in < end) && (*in != limit) && (*in >= 0x20) &&
9024
 
               (*in <= 0x7f) && (*in != '&') && (*in != '<')) {
9025
 
            in++;
9026
 
            if (in >= end) {
9027
 
                const xmlChar *oldbase = ctxt->input->base;
9028
 
                GROW;
9029
 
                if (ctxt->instate == XML_PARSER_EOF)
9030
 
                    return(NULL);
9031
 
                if (oldbase != ctxt->input->base) {
9032
 
                    long delta = ctxt->input->base - oldbase;
9033
 
                    start = start + delta;
9034
 
                    in = in + delta;
9035
 
                }
9036
 
                end = ctxt->input->end;
9037
 
                if (((in - start) > XML_MAX_TEXT_LENGTH) &&
9038
 
                    ((ctxt->options & XML_PARSE_HUGE) == 0)) {
9039
 
                    xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
9040
 
                                   "AttValue length too long\n");
9041
 
                    return(NULL);
9042
 
                }
9043
 
            }
9044
 
        }
9045
 
        last = in;
9046
 
        if (((in - start) > XML_MAX_TEXT_LENGTH) &&
9047
 
            ((ctxt->options & XML_PARSE_HUGE) == 0)) {
9048
 
            xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
9049
 
                           "AttValue length too long\n");
9050
 
            return(NULL);
9051
 
        }
9052
 
        if (*in != limit) goto need_complex;
9053
 
    }
9054
 
    in++;
9055
 
    if (len != NULL) {
9056
 
        *len = last - start;
9057
 
        ret = (xmlChar *) start;
9058
 
    } else {
9059
 
        if (alloc) *alloc = 1;
9060
 
        ret = xmlStrndup(start, last - start);
9061
 
    }
9062
 
    CUR_PTR = in;
9063
 
    if (alloc) *alloc = 0;
9064
 
    return ret;
9065
 
need_complex:
9066
 
    if (alloc) *alloc = 1;
9067
 
    return xmlParseAttValueComplex(ctxt, len, normalize);
9068
 
}
9069
 
 
9070
 
/**
9071
 
 * xmlParseAttribute2:
9072
 
 * @ctxt:  an XML parser context
9073
 
 * @pref:  the element prefix
9074
 
 * @elem:  the element name
9075
 
 * @prefix:  a xmlChar ** used to store the value of the attribute prefix
9076
 
 * @value:  a xmlChar ** used to store the value of the attribute
9077
 
 * @len:  an int * to save the length of the attribute
9078
 
 * @alloc:  an int * to indicate if the attribute was allocated
9079
 
 *
9080
 
 * parse an attribute in the new SAX2 framework.
9081
 
 *
9082
 
 * Returns the attribute name, and the value in *value, .
9083
 
 */
9084
 
 
9085
 
static const xmlChar *
9086
 
xmlParseAttribute2(xmlParserCtxtPtr ctxt,
9087
 
                   const xmlChar * pref, const xmlChar * elem,
9088
 
                   const xmlChar ** prefix, xmlChar ** value,
9089
 
                   int *len, int *alloc)
9090
 
{
9091
 
    const xmlChar *name;
9092
 
    xmlChar *val, *internal_val = NULL;
9093
 
    int normalize = 0;
9094
 
 
9095
 
    *value = NULL;
9096
 
    GROW;
9097
 
    name = xmlParseQName(ctxt, prefix);
9098
 
    if (name == NULL) {
9099
 
        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
9100
 
                       "error parsing attribute name\n");
9101
 
        return (NULL);
9102
 
    }
9103
 
 
9104
 
    /*
9105
 
     * get the type if needed
9106
 
     */
9107
 
    if (ctxt->attsSpecial != NULL) {
9108
 
        int type;
9109
 
 
9110
 
        type = (int) (long) xmlHashQLookup2(ctxt->attsSpecial,
9111
 
                                            pref, elem, *prefix, name);
9112
 
        if (type != 0)
9113
 
            normalize = 1;
9114
 
    }
9115
 
 
9116
 
    /*
9117
 
     * read the value
9118
 
     */
9119
 
    SKIP_BLANKS;
9120
 
    if (RAW == '=') {
9121
 
        NEXT;
9122
 
        SKIP_BLANKS;
9123
 
        val = xmlParseAttValueInternal(ctxt, len, alloc, normalize);
9124
 
        if (normalize) {
9125
 
            /*
9126
 
             * Sometimes a second normalisation pass for spaces is needed
9127
 
             * but that only happens if charrefs or entities refernces
9128
 
             * have been used in the attribute value, i.e. the attribute
9129
 
             * value have been extracted in an allocated string already.
9130
 
             */
9131
 
            if (*alloc) {
9132
 
                const xmlChar *val2;
9133
 
 
9134
 
                val2 = xmlAttrNormalizeSpace2(ctxt, val, len);
9135
 
                if ((val2 != NULL) && (val2 != val)) {
9136
 
                    xmlFree(val);
9137
 
                    val = (xmlChar *) val2;
9138
 
                }
9139
 
            }
9140
 
        }
9141
 
        ctxt->instate = XML_PARSER_CONTENT;
9142
 
    } else {
9143
 
        xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
9144
 
                          "Specification mandate value for attribute %s\n",
9145
 
                          name);
9146
 
        return (NULL);
9147
 
    }
9148
 
 
9149
 
    if (*prefix == ctxt->str_xml) {
9150
 
        /*
9151
 
         * Check that xml:lang conforms to the specification
9152
 
         * No more registered as an error, just generate a warning now
9153
 
         * since this was deprecated in XML second edition
9154
 
         */
9155
 
        if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "lang"))) {
9156
 
            internal_val = xmlStrndup(val, *len);
9157
 
            if (!xmlCheckLanguageID(internal_val)) {
9158
 
                xmlWarningMsg(ctxt, XML_WAR_LANG_VALUE,
9159
 
                              "Malformed value for xml:lang : %s\n",
9160
 
                              internal_val, NULL);
9161
 
            }
9162
 
        }
9163
 
 
9164
 
        /*
9165
 
         * Check that xml:space conforms to the specification
9166
 
         */
9167
 
        if (xmlStrEqual(name, BAD_CAST "space")) {
9168
 
            internal_val = xmlStrndup(val, *len);
9169
 
            if (xmlStrEqual(internal_val, BAD_CAST "default"))
9170
 
                *(ctxt->space) = 0;
9171
 
            else if (xmlStrEqual(internal_val, BAD_CAST "preserve"))
9172
 
                *(ctxt->space) = 1;
9173
 
            else {
9174
 
                xmlWarningMsg(ctxt, XML_WAR_SPACE_VALUE,
9175
 
                              "Invalid value \"%s\" for xml:space : \"default\" or \"preserve\" expected\n",
9176
 
                              internal_val, NULL);
9177
 
            }
9178
 
        }
9179
 
        if (internal_val) {
9180
 
            xmlFree(internal_val);
9181
 
        }
9182
 
    }
9183
 
 
9184
 
    *value = val;
9185
 
    return (name);
9186
 
}
9187
 
/**
9188
 
 * xmlParseStartTag2:
9189
 
 * @ctxt:  an XML parser context
9190
 
 *
9191
 
 * parse a start of tag either for rule element or
9192
 
 * EmptyElement. In both case we don't parse the tag closing chars.
9193
 
 * This routine is called when running SAX2 parsing
9194
 
 *
9195
 
 * [40] STag ::= '<' Name (S Attribute)* S? '>'
9196
 
 *
9197
 
 * [ WFC: Unique Att Spec ]
9198
 
 * No attribute name may appear more than once in the same start-tag or
9199
 
 * empty-element tag.
9200
 
 *
9201
 
 * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
9202
 
 *
9203
 
 * [ WFC: Unique Att Spec ]
9204
 
 * No attribute name may appear more than once in the same start-tag or
9205
 
 * empty-element tag.
9206
 
 *
9207
 
 * With namespace:
9208
 
 *
9209
 
 * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
9210
 
 *
9211
 
 * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
9212
 
 *
9213
 
 * Returns the element name parsed
9214
 
 */
9215
 
 
9216
 
static const xmlChar *
9217
 
xmlParseStartTag2(xmlParserCtxtPtr ctxt, const xmlChar **pref,
9218
 
                  const xmlChar **URI, int *tlen) {
9219
 
    const xmlChar *localname;
9220
 
    const xmlChar *prefix;
9221
 
    const xmlChar *attname;
9222
 
    const xmlChar *aprefix;
9223
 
    const xmlChar *nsname;
9224
 
    xmlChar *attvalue;
9225
 
    const xmlChar **atts = ctxt->atts;
9226
 
    int maxatts = ctxt->maxatts;
9227
 
    int nratts, nbatts, nbdef;
9228
 
    int i, j, nbNs, attval, oldline, oldcol;
9229
 
    const xmlChar *base;
9230
 
    unsigned long cur;
9231
 
    int nsNr = ctxt->nsNr;
9232
 
 
9233
 
    if (RAW != '<') return(NULL);
9234
 
    NEXT1;
9235
 
 
9236
 
    /*
9237
 
     * NOTE: it is crucial with the SAX2 API to never call SHRINK beyond that
9238
 
     *       point since the attribute values may be stored as pointers to
9239
 
     *       the buffer and calling SHRINK would destroy them !
9240
 
     *       The Shrinking is only possible once the full set of attribute
9241
 
     *       callbacks have been done.
9242
 
     */
9243
 
reparse:
9244
 
    SHRINK;
9245
 
    base = ctxt->input->base;
9246
 
    cur = ctxt->input->cur - ctxt->input->base;
9247
 
    oldline = ctxt->input->line;
9248
 
    oldcol = ctxt->input->col;
9249
 
    nbatts = 0;
9250
 
    nratts = 0;
9251
 
    nbdef = 0;
9252
 
    nbNs = 0;
9253
 
    attval = 0;
9254
 
    /* Forget any namespaces added during an earlier parse of this element. */
9255
 
    ctxt->nsNr = nsNr;
9256
 
 
9257
 
    localname = xmlParseQName(ctxt, &prefix);
9258
 
    if (localname == NULL) {
9259
 
        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
9260
 
                       "StartTag: invalid element name\n");
9261
 
        return(NULL);
9262
 
    }
9263
 
    *tlen = ctxt->input->cur - ctxt->input->base - cur;
9264
 
 
9265
 
    /*
9266
 
     * Now parse the attributes, it ends up with the ending
9267
 
     *
9268
 
     * (S Attribute)* S?
9269
 
     */
9270
 
    SKIP_BLANKS;
9271
 
    GROW;
9272
 
    if (ctxt->input->base != base) goto base_changed;
9273
 
 
9274
 
    while (((RAW != '>') &&
9275
 
           ((RAW != '/') || (NXT(1) != '>')) &&
9276
 
           (IS_BYTE_CHAR(RAW))) && (ctxt->instate != XML_PARSER_EOF)) {
9277
 
        const xmlChar *q = CUR_PTR;
9278
 
        unsigned int cons = ctxt->input->consumed;
9279
 
        int len = -1, alloc = 0;
9280
 
 
9281
 
        attname = xmlParseAttribute2(ctxt, prefix, localname,
9282
 
                                     &aprefix, &attvalue, &len, &alloc);
9283
 
        if (ctxt->input->base != base) {
9284
 
            if ((attvalue != NULL) && (alloc != 0))
9285
 
                xmlFree(attvalue);
9286
 
            attvalue = NULL;
9287
 
            goto base_changed;
9288
 
        }
9289
 
        if ((attname != NULL) && (attvalue != NULL)) {
9290
 
            if (len < 0) len = xmlStrlen(attvalue);
9291
 
            if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
9292
 
                const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
9293
 
                xmlURIPtr uri;
9294
 
 
9295
 
                if (*URL != 0) {
9296
 
                    uri = xmlParseURI((const char *) URL);
9297
 
                    if (uri == NULL) {
9298
 
                        xmlNsErr(ctxt, XML_WAR_NS_URI,
9299
 
                                 "xmlns: '%s' is not a valid URI\n",
9300
 
                                           URL, NULL, NULL);
9301
 
                    } else {
9302
 
                        if (uri->scheme == NULL) {
9303
 
                            xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
9304
 
                                      "xmlns: URI %s is not absolute\n",
9305
 
                                      URL, NULL, NULL);
9306
 
                        }
9307
 
                        xmlFreeURI(uri);
9308
 
                    }
9309
 
                    if (URL == ctxt->str_xml_ns) {
9310
 
                        if (attname != ctxt->str_xml) {
9311
 
                            xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9312
 
                         "xml namespace URI cannot be the default namespace\n",
9313
 
                                     NULL, NULL, NULL);
9314
 
                        }
9315
 
                        goto skip_default_ns;
9316
 
                    }
9317
 
                    if ((len == 29) &&
9318
 
                        (xmlStrEqual(URL,
9319
 
                                 BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
9320
 
                        xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9321
 
                             "reuse of the xmlns namespace name is forbidden\n",
9322
 
                                 NULL, NULL, NULL);
9323
 
                        goto skip_default_ns;
9324
 
                    }
9325
 
                }
9326
 
                /*
9327
 
                 * check that it's not a defined namespace
9328
 
                 */
9329
 
                for (j = 1;j <= nbNs;j++)
9330
 
                    if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
9331
 
                        break;
9332
 
                if (j <= nbNs)
9333
 
                    xmlErrAttributeDup(ctxt, NULL, attname);
9334
 
                else
9335
 
                    if (nsPush(ctxt, NULL, URL) > 0) nbNs++;
9336
 
skip_default_ns:
9337
 
                if (alloc != 0) xmlFree(attvalue);
9338
 
                SKIP_BLANKS;
9339
 
                continue;
9340
 
            }
9341
 
            if (aprefix == ctxt->str_xmlns) {
9342
 
                const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
9343
 
                xmlURIPtr uri;
9344
 
 
9345
 
                if (attname == ctxt->str_xml) {
9346
 
                    if (URL != ctxt->str_xml_ns) {
9347
 
                        xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9348
 
                                 "xml namespace prefix mapped to wrong URI\n",
9349
 
                                 NULL, NULL, NULL);
9350
 
                    }
9351
 
                    /*
9352
 
                     * Do not keep a namespace definition node
9353
 
                     */
9354
 
                    goto skip_ns;
9355
 
                }
9356
 
                if (URL == ctxt->str_xml_ns) {
9357
 
                    if (attname != ctxt->str_xml) {
9358
 
                        xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9359
 
                                 "xml namespace URI mapped to wrong prefix\n",
9360
 
                                 NULL, NULL, NULL);
9361
 
                    }
9362
 
                    goto skip_ns;
9363
 
                }
9364
 
                if (attname == ctxt->str_xmlns) {
9365
 
                    xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9366
 
                             "redefinition of the xmlns prefix is forbidden\n",
9367
 
                             NULL, NULL, NULL);
9368
 
                    goto skip_ns;
9369
 
                }
9370
 
                if ((len == 29) &&
9371
 
                    (xmlStrEqual(URL,
9372
 
                                 BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
9373
 
                    xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9374
 
                             "reuse of the xmlns namespace name is forbidden\n",
9375
 
                             NULL, NULL, NULL);
9376
 
                    goto skip_ns;
9377
 
                }
9378
 
                if ((URL == NULL) || (URL[0] == 0)) {
9379
 
                    xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
9380
 
                             "xmlns:%s: Empty XML namespace is not allowed\n",
9381
 
                                  attname, NULL, NULL);
9382
 
                    goto skip_ns;
9383
 
                } else {
9384
 
                    uri = xmlParseURI((const char *) URL);
9385
 
                    if (uri == NULL) {
9386
 
                        xmlNsErr(ctxt, XML_WAR_NS_URI,
9387
 
                             "xmlns:%s: '%s' is not a valid URI\n",
9388
 
                                           attname, URL, NULL);
9389
 
                    } else {
9390
 
                        if ((ctxt->pedantic) && (uri->scheme == NULL)) {
9391
 
                            xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
9392
 
                                      "xmlns:%s: URI %s is not absolute\n",
9393
 
                                      attname, URL, NULL);
9394
 
                        }
9395
 
                        xmlFreeURI(uri);
9396
 
                    }
9397
 
                }
9398
 
 
9399
 
                /*
9400
 
                 * check that it's not a defined namespace
9401
 
                 */
9402
 
                for (j = 1;j <= nbNs;j++)
9403
 
                    if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
9404
 
                        break;
9405
 
                if (j <= nbNs)
9406
 
                    xmlErrAttributeDup(ctxt, aprefix, attname);
9407
 
                else
9408
 
                    if (nsPush(ctxt, attname, URL) > 0) nbNs++;
9409
 
skip_ns:
9410
 
                if (alloc != 0) xmlFree(attvalue);
9411
 
                SKIP_BLANKS;
9412
 
                if (ctxt->input->base != base) goto base_changed;
9413
 
                continue;
9414
 
            }
9415
 
 
9416
 
            /*
9417
 
             * Add the pair to atts
9418
 
             */
9419
 
            if ((atts == NULL) || (nbatts + 5 > maxatts)) {
9420
 
                if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
9421
 
                    if (attvalue[len] == 0)
9422
 
                        xmlFree(attvalue);
9423
 
                    goto failed;
9424
 
                }
9425
 
                maxatts = ctxt->maxatts;
9426
 
                atts = ctxt->atts;
9427
 
            }
9428
 
            ctxt->attallocs[nratts++] = alloc;
9429
 
            atts[nbatts++] = attname;
9430
 
            atts[nbatts++] = aprefix;
9431
 
            atts[nbatts++] = NULL; /* the URI will be fetched later */
9432
 
            atts[nbatts++] = attvalue;
9433
 
            attvalue += len;
9434
 
            atts[nbatts++] = attvalue;
9435
 
            /*
9436
 
             * tag if some deallocation is needed
9437
 
             */
9438
 
            if (alloc != 0) attval = 1;
9439
 
        } else {
9440
 
            if ((attvalue != NULL) && (attvalue[len] == 0))
9441
 
                xmlFree(attvalue);
9442
 
        }
9443
 
 
9444
 
failed:
9445
 
 
9446
 
        GROW
9447
 
        if (ctxt->instate == XML_PARSER_EOF)
9448
 
            break;
9449
 
        if (ctxt->input->base != base) goto base_changed;
9450
 
        if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
9451
 
            break;
9452
 
        if (!IS_BLANK_CH(RAW)) {
9453
 
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
9454
 
                           "attributes construct error\n");
9455
 
            break;
9456
 
        }
9457
 
        SKIP_BLANKS;
9458
 
        if ((cons == ctxt->input->consumed) && (q == CUR_PTR) &&
9459
 
            (attname == NULL) && (attvalue == NULL)) {
9460
 
            xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
9461
 
                 "xmlParseStartTag: problem parsing attributes\n");
9462
 
            break;
9463
 
        }
9464
 
        GROW;
9465
 
        if (ctxt->input->base != base) goto base_changed;
9466
 
    }
9467
 
 
9468
 
    /*
9469
 
     * The attributes defaulting
9470
 
     */
9471
 
    if (ctxt->attsDefault != NULL) {
9472
 
        xmlDefAttrsPtr defaults;
9473
 
 
9474
 
        defaults = xmlHashLookup2(ctxt->attsDefault, localname, prefix);
9475
 
        if (defaults != NULL) {
9476
 
            for (i = 0;i < defaults->nbAttrs;i++) {
9477
 
                attname = defaults->values[5 * i];
9478
 
                aprefix = defaults->values[5 * i + 1];
9479
 
 
9480
 
                /*
9481
 
                 * special work for namespaces defaulted defs
9482
 
                 */
9483
 
                if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
9484
 
                    /*
9485
 
                     * check that it's not a defined namespace
9486
 
                     */
9487
 
                    for (j = 1;j <= nbNs;j++)
9488
 
                        if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
9489
 
                            break;
9490
 
                    if (j <= nbNs) continue;
9491
 
 
9492
 
                    nsname = xmlGetNamespace(ctxt, NULL);
9493
 
                    if (nsname != defaults->values[5 * i + 2]) {
9494
 
                        if (nsPush(ctxt, NULL,
9495
 
                                   defaults->values[5 * i + 2]) > 0)
9496
 
                            nbNs++;
9497
 
                    }
9498
 
                } else if (aprefix == ctxt->str_xmlns) {
9499
 
                    /*
9500
 
                     * check that it's not a defined namespace
9501
 
                     */
9502
 
                    for (j = 1;j <= nbNs;j++)
9503
 
                        if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
9504
 
                            break;
9505
 
                    if (j <= nbNs) continue;
9506
 
 
9507
 
                    nsname = xmlGetNamespace(ctxt, attname);
9508
 
                    if (nsname != defaults->values[2]) {
9509
 
                        if (nsPush(ctxt, attname,
9510
 
                                   defaults->values[5 * i + 2]) > 0)
9511
 
                            nbNs++;
9512
 
                    }
9513
 
                } else {
9514
 
                    /*
9515
 
                     * check that it's not a defined attribute
9516
 
                     */
9517
 
                    for (j = 0;j < nbatts;j+=5) {
9518
 
                        if ((attname == atts[j]) && (aprefix == atts[j+1]))
9519
 
                            break;
9520
 
                    }
9521
 
                    if (j < nbatts) continue;
9522
 
 
9523
 
                    if ((atts == NULL) || (nbatts + 5 > maxatts)) {
9524
 
                        if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
9525
 
                            return(NULL);
9526
 
                        }
9527
 
                        maxatts = ctxt->maxatts;
9528
 
                        atts = ctxt->atts;
9529
 
                    }
9530
 
                    atts[nbatts++] = attname;
9531
 
                    atts[nbatts++] = aprefix;
9532
 
                    if (aprefix == NULL)
9533
 
                        atts[nbatts++] = NULL;
9534
 
                    else
9535
 
                        atts[nbatts++] = xmlGetNamespace(ctxt, aprefix);
9536
 
                    atts[nbatts++] = defaults->values[5 * i + 2];
9537
 
                    atts[nbatts++] = defaults->values[5 * i + 3];
9538
 
                    if ((ctxt->standalone == 1) &&
9539
 
                        (defaults->values[5 * i + 4] != NULL)) {
9540
 
                        xmlValidityError(ctxt, XML_DTD_STANDALONE_DEFAULTED,
9541
 
          "standalone: attribute %s on %s defaulted from external subset\n",
9542
 
                                         attname, localname);
9543
 
                    }
9544
 
                    nbdef++;
9545
 
                }
9546
 
            }
9547
 
        }
9548
 
    }
9549
 
 
9550
 
    /*
9551
 
     * The attributes checkings
9552
 
     */
9553
 
    for (i = 0; i < nbatts;i += 5) {
9554
 
        /*
9555
 
        * The default namespace does not apply to attribute names.
9556
 
        */
9557
 
        if (atts[i + 1] != NULL) {
9558
 
            nsname = xmlGetNamespace(ctxt, atts[i + 1]);
9559
 
            if (nsname == NULL) {
9560
 
                xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
9561
 
                    "Namespace prefix %s for %s on %s is not defined\n",
9562
 
                    atts[i + 1], atts[i], localname);
9563
 
            }
9564
 
            atts[i + 2] = nsname;
9565
 
        } else
9566
 
            nsname = NULL;
9567
 
        /*
9568
 
         * [ WFC: Unique Att Spec ]
9569
 
         * No attribute name may appear more than once in the same
9570
 
         * start-tag or empty-element tag.
9571
 
         * As extended by the Namespace in XML REC.
9572
 
         */
9573
 
        for (j = 0; j < i;j += 5) {
9574
 
            if (atts[i] == atts[j]) {
9575
 
                if (atts[i+1] == atts[j+1]) {
9576
 
                    xmlErrAttributeDup(ctxt, atts[i+1], atts[i]);
9577
 
                    break;
9578
 
                }
9579
 
                if ((nsname != NULL) && (atts[j + 2] == nsname)) {
9580
 
                    xmlNsErr(ctxt, XML_NS_ERR_ATTRIBUTE_REDEFINED,
9581
 
                             "Namespaced Attribute %s in '%s' redefined\n",
9582
 
                             atts[i], nsname, NULL);
9583
 
                    break;
9584
 
                }
9585
 
            }
9586
 
        }
9587
 
    }
9588
 
 
9589
 
    nsname = xmlGetNamespace(ctxt, prefix);
9590
 
    if ((prefix != NULL) && (nsname == NULL)) {
9591
 
        xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
9592
 
                 "Namespace prefix %s on %s is not defined\n",
9593
 
                 prefix, localname, NULL);
9594
 
    }
9595
 
    *pref = prefix;
9596
 
    *URI = nsname;
9597
 
 
9598
 
    /*
9599
 
     * SAX: Start of Element !
9600
 
     */
9601
 
    if ((ctxt->sax != NULL) && (ctxt->sax->startElementNs != NULL) &&
9602
 
        (!ctxt->disableSAX)) {
9603
 
        if (nbNs > 0)
9604
 
            ctxt->sax->startElementNs(ctxt->userData, localname, prefix,
9605
 
                          nsname, nbNs, &ctxt->nsTab[ctxt->nsNr - 2 * nbNs],
9606
 
                          nbatts / 5, nbdef, atts);
9607
 
        else
9608
 
            ctxt->sax->startElementNs(ctxt->userData, localname, prefix,
9609
 
                          nsname, 0, NULL, nbatts / 5, nbdef, atts);
9610
 
    }
9611
 
 
9612
 
    /*
9613
 
     * Free up attribute allocated strings if needed
9614
 
     */
9615
 
    if (attval != 0) {
9616
 
        for (i = 3,j = 0; j < nratts;i += 5,j++)
9617
 
            if ((ctxt->attallocs[j] != 0) && (atts[i] != NULL))
9618
 
                xmlFree((xmlChar *) atts[i]);
9619
 
    }
9620
 
 
9621
 
    return(localname);
9622
 
 
9623
 
base_changed:
9624
 
    /*
9625
 
     * the attribute strings are valid iif the base didn't changed
9626
 
     */
9627
 
    if (attval != 0) {
9628
 
        for (i = 3,j = 0; j < nratts;i += 5,j++)
9629
 
            if ((ctxt->attallocs[j] != 0) && (atts[i] != NULL))
9630
 
                xmlFree((xmlChar *) atts[i]);
9631
 
    }
9632
 
    ctxt->input->cur = ctxt->input->base + cur;
9633
 
    ctxt->input->line = oldline;
9634
 
    ctxt->input->col = oldcol;
9635
 
    if (ctxt->wellFormed == 1) {
9636
 
        goto reparse;
9637
 
    }
9638
 
    return(NULL);
9639
 
}
9640
 
 
9641
 
/**
9642
 
 * xmlParseEndTag2:
9643
 
 * @ctxt:  an XML parser context
9644
 
 * @line:  line of the start tag
9645
 
 * @nsNr:  number of namespaces on the start tag
9646
 
 *
9647
 
 * parse an end of tag
9648
 
 *
9649
 
 * [42] ETag ::= '</' Name S? '>'
9650
 
 *
9651
 
 * With namespace
9652
 
 *
9653
 
 * [NS 9] ETag ::= '</' QName S? '>'
9654
 
 */
9655
 
 
9656
 
static void
9657
 
xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlChar *prefix,
9658
 
                const xmlChar *URI, int line, int nsNr, int tlen) {
9659
 
    const xmlChar *name;
9660
 
 
9661
 
    GROW;
9662
 
    if ((RAW != '<') || (NXT(1) != '/')) {
9663
 
        xmlFatalErr(ctxt, XML_ERR_LTSLASH_REQUIRED, NULL);
9664
 
        return;
9665
 
    }
9666
 
    SKIP(2);
9667
 
 
9668
 
    if ((tlen > 0) && (xmlStrncmp(ctxt->input->cur, ctxt->name, tlen) == 0)) {
9669
 
        if (ctxt->input->cur[tlen] == '>') {
9670
 
            ctxt->input->cur += tlen + 1;
9671
 
            goto done;
9672
 
        }
9673
 
        ctxt->input->cur += tlen;
9674
 
        name = (xmlChar*)1;
9675
 
    } else {
9676
 
        if (prefix == NULL)
9677
 
            name = xmlParseNameAndCompare(ctxt, ctxt->name);
9678
 
        else
9679
 
            name = xmlParseQNameAndCompare(ctxt, ctxt->name, prefix);
9680
 
    }
9681
 
 
9682
 
    /*
9683
 
     * We should definitely be at the ending "S? '>'" part
9684
 
     */
9685
 
    GROW;
9686
 
    if (ctxt->instate == XML_PARSER_EOF)
9687
 
        return;
9688
 
    SKIP_BLANKS;
9689
 
    if ((!IS_BYTE_CHAR(RAW)) || (RAW != '>')) {
9690
 
        xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
9691
 
    } else
9692
 
        NEXT1;
9693
 
 
9694
 
    /*
9695
 
     * [ WFC: Element Type Match ]
9696
 
     * The Name in an element's end-tag must match the element type in the
9697
 
     * start-tag.
9698
 
     *
9699
 
     */
9700
 
    if (name != (xmlChar*)1) {
9701
 
        if (name == NULL) name = BAD_CAST "unparseable";
9702
 
        if ((line == 0) && (ctxt->node != NULL))
9703
 
            line = ctxt->node->line;
9704
 
        xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
9705
 
                     "Opening and ending tag mismatch: %s line %d and %s\n",
9706
 
                                ctxt->name, line, name);
9707
 
    }
9708
 
 
9709
 
    /*
9710
 
     * SAX: End of Tag
9711
 
     */
9712
 
done:
9713
 
    if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
9714
 
        (!ctxt->disableSAX))
9715
 
        ctxt->sax->endElementNs(ctxt->userData, ctxt->name, prefix, URI);
9716
 
 
9717
 
    spacePop(ctxt);
9718
 
    if (nsNr != 0)
9719
 
        nsPop(ctxt, nsNr);
9720
 
    return;
9721
 
}
9722
 
 
9723
 
/**
9724
 
 * xmlParseCDSect:
9725
 
 * @ctxt:  an XML parser context
9726
 
 *
9727
 
 * Parse escaped pure raw content.
9728
 
 *
9729
 
 * [18] CDSect ::= CDStart CData CDEnd
9730
 
 *
9731
 
 * [19] CDStart ::= '<![CDATA['
9732
 
 *
9733
 
 * [20] Data ::= (Char* - (Char* ']]>' Char*))
9734
 
 *
9735
 
 * [21] CDEnd ::= ']]>'
9736
 
 */
9737
 
void
9738
 
xmlParseCDSect(xmlParserCtxtPtr ctxt) {
9739
 
    xmlChar *buf = NULL;
9740
 
    int len = 0;
9741
 
    int size = XML_PARSER_BUFFER_SIZE;
9742
 
    int r, rl;
9743
 
    int s, sl;
9744
 
    int cur, l;
9745
 
    int count = 0;
9746
 
 
9747
 
    /* Check 2.6.0 was NXT(0) not RAW */
9748
 
    if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) {
9749
 
        SKIP(9);
9750
 
    } else
9751
 
        return;
9752
 
 
9753
 
    ctxt->instate = XML_PARSER_CDATA_SECTION;
9754
 
    r = CUR_CHAR(rl);
9755
 
    if (!IS_CHAR(r)) {
9756
 
        xmlFatalErr(ctxt, XML_ERR_CDATA_NOT_FINISHED, NULL);
9757
 
        ctxt->instate = XML_PARSER_CONTENT;
9758
 
        return;
9759
 
    }
9760
 
    NEXTL(rl);
9761
 
    s = CUR_CHAR(sl);
9762
 
    if (!IS_CHAR(s)) {
9763
 
        xmlFatalErr(ctxt, XML_ERR_CDATA_NOT_FINISHED, NULL);
9764
 
        ctxt->instate = XML_PARSER_CONTENT;
9765
 
        return;
9766
 
    }
9767
 
    NEXTL(sl);
9768
 
    cur = CUR_CHAR(l);
9769
 
    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
9770
 
    if (buf == NULL) {
9771
 
        xmlErrMemory(ctxt, NULL);
9772
 
        return;
9773
 
    }
9774
 
    while (IS_CHAR(cur) &&
9775
 
           ((r != ']') || (s != ']') || (cur != '>'))) {
9776
 
        if (len + 5 >= size) {
9777
 
            xmlChar *tmp;
9778
 
 
9779
 
            if ((size > XML_MAX_TEXT_LENGTH) &&
9780
 
                ((ctxt->options & XML_PARSE_HUGE) == 0)) {
9781
 
                xmlFatalErrMsgStr(ctxt, XML_ERR_CDATA_NOT_FINISHED,
9782
 
                             "CData section too big found", NULL);
9783
 
                xmlFree (buf);
9784
 
                return;
9785
 
            }
9786
 
            tmp = (xmlChar *) xmlRealloc(buf, size * 2 * sizeof(xmlChar));
9787
 
            if (tmp == NULL) {
9788
 
                xmlFree(buf);
9789
 
                xmlErrMemory(ctxt, NULL);
9790
 
                return;
9791
 
            }
9792
 
            buf = tmp;
9793
 
            size *= 2;
9794
 
        }
9795
 
        COPY_BUF(rl,buf,len,r);
9796
 
        r = s;
9797
 
        rl = sl;
9798
 
        s = cur;
9799
 
        sl = l;
9800
 
        count++;
9801
 
        if (count > 50) {
9802
 
            GROW;
9803
 
            if (ctxt->instate == XML_PARSER_EOF) {
9804
 
                xmlFree(buf);
9805
 
                return;
9806
 
            }
9807
 
            count = 0;
9808
 
        }
9809
 
        NEXTL(l);
9810
 
        cur = CUR_CHAR(l);
9811
 
    }
9812
 
    buf[len] = 0;
9813
 
    ctxt->instate = XML_PARSER_CONTENT;
9814
 
    if (cur != '>') {
9815
 
        xmlFatalErrMsgStr(ctxt, XML_ERR_CDATA_NOT_FINISHED,
9816
 
                             "CData section not finished\n%.50s\n", buf);
9817
 
        xmlFree(buf);
9818
 
        return;
9819
 
    }
9820
 
    NEXTL(l);
9821
 
 
9822
 
    /*
9823
 
     * OK the buffer is to be consumed as cdata.
9824
 
     */
9825
 
    if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
9826
 
        if (ctxt->sax->cdataBlock != NULL)
9827
 
            ctxt->sax->cdataBlock(ctxt->userData, buf, len);
9828
 
        else if (ctxt->sax->characters != NULL)
9829
 
            ctxt->sax->characters(ctxt->userData, buf, len);
9830
 
    }
9831
 
    xmlFree(buf);
9832
 
}
9833
 
 
9834
 
/**
9835
 
 * xmlParseContent:
9836
 
 * @ctxt:  an XML parser context
9837
 
 *
9838
 
 * Parse a content:
9839
 
 *
9840
 
 * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
9841
 
 */
9842
 
 
9843
 
void
9844
 
xmlParseContent(xmlParserCtxtPtr ctxt) {
9845
 
    GROW;
9846
 
    while ((RAW != 0) &&
9847
 
           ((RAW != '<') || (NXT(1) != '/')) &&
9848
 
           (ctxt->instate != XML_PARSER_EOF)) {
9849
 
        const xmlChar *test = CUR_PTR;
9850
 
        unsigned int cons = ctxt->input->consumed;
9851
 
        const xmlChar *cur = ctxt->input->cur;
9852
 
 
9853
 
        /*
9854
 
         * First case : a Processing Instruction.
9855
 
         */
9856
 
        if ((*cur == '<') && (cur[1] == '?')) {
9857
 
            xmlParsePI(ctxt);
9858
 
        }
9859
 
 
9860
 
        /*
9861
 
         * Second case : a CDSection
9862
 
         */
9863
 
        /* 2.6.0 test was *cur not RAW */
9864
 
        else if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) {
9865
 
            xmlParseCDSect(ctxt);
9866
 
        }
9867
 
 
9868
 
        /*
9869
 
         * Third case :  a comment
9870
 
         */
9871
 
        else if ((*cur == '<') && (NXT(1) == '!') &&
9872
 
                 (NXT(2) == '-') && (NXT(3) == '-')) {
9873
 
            xmlParseComment(ctxt);
9874
 
            ctxt->instate = XML_PARSER_CONTENT;
9875
 
        }
9876
 
 
9877
 
        /*
9878
 
         * Fourth case :  a sub-element.
9879
 
         */
9880
 
        else if (*cur == '<') {
9881
 
            xmlParseElement(ctxt);
9882
 
        }
9883
 
 
9884
 
        /*
9885
 
         * Fifth case : a reference. If if has not been resolved,
9886
 
         *    parsing returns it's Name, create the node
9887
 
         */
9888
 
 
9889
 
        else if (*cur == '&') {
9890
 
            xmlParseReference(ctxt);
9891
 
        }
9892
 
 
9893
 
        /*
9894
 
         * Last case, text. Note that References are handled directly.
9895
 
         */
9896
 
        else {
9897
 
            xmlParseCharData(ctxt, 0);
9898
 
        }
9899
 
 
9900
 
        GROW;
9901
 
        /*
9902
 
         * Pop-up of finished entities.
9903
 
         */
9904
 
        while ((RAW == 0) && (ctxt->inputNr > 1))
9905
 
            xmlPopInput(ctxt);
9906
 
        SHRINK;
9907
 
 
9908
 
        if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
9909
 
            xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
9910
 
                        "detected an error in element content\n");
9911
 
            ctxt->instate = XML_PARSER_EOF;
9912
 
            break;
9913
 
        }
9914
 
    }
9915
 
}
9916
 
 
9917
 
/**
9918
 
 * xmlParseElement:
9919
 
 * @ctxt:  an XML parser context
9920
 
 *
9921
 
 * parse an XML element, this is highly recursive
9922
 
 *
9923
 
 * [39] element ::= EmptyElemTag | STag content ETag
9924
 
 *
9925
 
 * [ WFC: Element Type Match ]
9926
 
 * The Name in an element's end-tag must match the element type in the
9927
 
 * start-tag.
9928
 
 *
9929
 
 */
9930
 
 
9931
 
void
9932
 
xmlParseElement(xmlParserCtxtPtr ctxt) {
9933
 
    const xmlChar *name;
9934
 
    const xmlChar *prefix = NULL;
9935
 
    const xmlChar *URI = NULL;
9936
 
    xmlParserNodeInfo node_info;
9937
 
    int line, tlen = 0;
9938
 
    xmlNodePtr ret;
9939
 
    int nsNr = ctxt->nsNr;
9940
 
 
9941
 
    if (((unsigned int) ctxt->nameNr > xmlParserMaxDepth) &&
9942
 
        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
9943
 
        xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
9944
 
                 "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
9945
 
                          xmlParserMaxDepth);
9946
 
        ctxt->instate = XML_PARSER_EOF;
9947
 
        return;
9948
 
    }
9949
 
 
9950
 
    /* Capture start position */
9951
 
    if (ctxt->record_info) {
9952
 
        node_info.begin_pos = ctxt->input->consumed +
9953
 
                          (CUR_PTR - ctxt->input->base);
9954
 
        node_info.begin_line = ctxt->input->line;
9955
 
    }
9956
 
 
9957
 
    if (ctxt->spaceNr == 0)
9958
 
        spacePush(ctxt, -1);
9959
 
    else if (*ctxt->space == -2)
9960
 
        spacePush(ctxt, -1);
9961
 
    else
9962
 
        spacePush(ctxt, *ctxt->space);
9963
 
 
9964
 
    line = ctxt->input->line;
9965
 
#ifdef LIBXML_SAX1_ENABLED
9966
 
    if (ctxt->sax2)
9967
 
#endif /* LIBXML_SAX1_ENABLED */
9968
 
        name = xmlParseStartTag2(ctxt, &prefix, &URI, &tlen);
9969
 
#ifdef LIBXML_SAX1_ENABLED
9970
 
    else
9971
 
        name = xmlParseStartTag(ctxt);
9972
 
#endif /* LIBXML_SAX1_ENABLED */
9973
 
    if (ctxt->instate == XML_PARSER_EOF)
9974
 
        return;
9975
 
    if (name == NULL) {
9976
 
        spacePop(ctxt);
9977
 
        return;
9978
 
    }
9979
 
    namePush(ctxt, name);
9980
 
    ret = ctxt->node;
9981
 
 
9982
 
#ifdef LIBXML_VALID_ENABLED
9983
 
    /*
9984
 
     * [ VC: Root Element Type ]
9985
 
     * The Name in the document type declaration must match the element
9986
 
     * type of the root element.
9987
 
     */
9988
 
    if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
9989
 
        ctxt->node && (ctxt->node == ctxt->myDoc->children))
9990
 
        ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
9991
 
#endif /* LIBXML_VALID_ENABLED */
9992
 
 
9993
 
    /*
9994
 
     * Check for an Empty Element.
9995
 
     */
9996
 
    if ((RAW == '/') && (NXT(1) == '>')) {
9997
 
        SKIP(2);
9998
 
        if (ctxt->sax2) {
9999
 
            if ((ctxt->sax != NULL) && (ctxt->sax->endElementNs != NULL) &&
10000
 
                (!ctxt->disableSAX))
10001
 
                ctxt->sax->endElementNs(ctxt->userData, name, prefix, URI);
10002
 
#ifdef LIBXML_SAX1_ENABLED
10003
 
        } else {
10004
 
            if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
10005
 
                (!ctxt->disableSAX))
10006
 
                ctxt->sax->endElement(ctxt->userData, name);
10007
 
#endif /* LIBXML_SAX1_ENABLED */
10008
 
        }
10009
 
        namePop(ctxt);
10010
 
        spacePop(ctxt);
10011
 
        if (nsNr != ctxt->nsNr)
10012
 
            nsPop(ctxt, ctxt->nsNr - nsNr);
10013
 
        if ( ret != NULL && ctxt->record_info ) {
10014
 
           node_info.end_pos = ctxt->input->consumed +
10015
 
                              (CUR_PTR - ctxt->input->base);
10016
 
           node_info.end_line = ctxt->input->line;
10017
 
           node_info.node = ret;
10018
 
           xmlParserAddNodeInfo(ctxt, &node_info);
10019
 
        }
10020
 
        return;
10021
 
    }
10022
 
    if (RAW == '>') {
10023
 
        NEXT1;
10024
 
    } else {
10025
 
        xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_GT_REQUIRED,
10026
 
                     "Couldn't find end of Start Tag %s line %d\n",
10027
 
                                name, line, NULL);
10028
 
 
10029
 
        /*
10030
 
         * end of parsing of this node.
10031
 
         */
10032
 
        nodePop(ctxt);
10033
 
        namePop(ctxt);
10034
 
        spacePop(ctxt);
10035
 
        if (nsNr != ctxt->nsNr)
10036
 
            nsPop(ctxt, ctxt->nsNr - nsNr);
10037
 
 
10038
 
        /*
10039
 
         * Capture end position and add node
10040
 
         */
10041
 
        if ( ret != NULL && ctxt->record_info ) {
10042
 
           node_info.end_pos = ctxt->input->consumed +
10043
 
                              (CUR_PTR - ctxt->input->base);
10044
 
           node_info.end_line = ctxt->input->line;
10045
 
           node_info.node = ret;
10046
 
           xmlParserAddNodeInfo(ctxt, &node_info);
10047
 
        }
10048
 
        return;
10049
 
    }
10050
 
 
10051
 
    /*
10052
 
     * Parse the content of the element:
10053
 
     */
10054
 
    xmlParseContent(ctxt);
10055
 
    if (ctxt->instate == XML_PARSER_EOF)
10056
 
        return;
10057
 
    if (!IS_BYTE_CHAR(RAW)) {
10058
 
        xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
10059
 
         "Premature end of data in tag %s line %d\n",
10060
 
                                name, line, NULL);
10061
 
 
10062
 
        /*
10063
 
         * end of parsing of this node.
10064
 
         */
10065
 
        nodePop(ctxt);
10066
 
        namePop(ctxt);
10067
 
        spacePop(ctxt);
10068
 
        if (nsNr != ctxt->nsNr)
10069
 
            nsPop(ctxt, ctxt->nsNr - nsNr);
10070
 
        return;
10071
 
    }
10072
 
 
10073
 
    /*
10074
 
     * parse the end of tag: '</' should be here.
10075
 
     */
10076
 
    if (ctxt->sax2) {
10077
 
        xmlParseEndTag2(ctxt, prefix, URI, line, ctxt->nsNr - nsNr, tlen);
10078
 
        namePop(ctxt);
10079
 
    }
10080
 
#ifdef LIBXML_SAX1_ENABLED
10081
 
      else
10082
 
        xmlParseEndTag1(ctxt, line);
10083
 
#endif /* LIBXML_SAX1_ENABLED */
10084
 
 
10085
 
    /*
10086
 
     * Capture end position and add node
10087
 
     */
10088
 
    if ( ret != NULL && ctxt->record_info ) {
10089
 
       node_info.end_pos = ctxt->input->consumed +
10090
 
                          (CUR_PTR - ctxt->input->base);
10091
 
       node_info.end_line = ctxt->input->line;
10092
 
       node_info.node = ret;
10093
 
       xmlParserAddNodeInfo(ctxt, &node_info);
10094
 
    }
10095
 
}
10096
 
 
10097
 
/**
10098
 
 * xmlParseVersionNum:
10099
 
 * @ctxt:  an XML parser context
10100
 
 *
10101
 
 * parse the XML version value.
10102
 
 *
10103
 
 * [26] VersionNum ::= '1.' [0-9]+
10104
 
 *
10105
 
 * In practice allow [0-9].[0-9]+ at that level
10106
 
 *
10107
 
 * Returns the string giving the XML version number, or NULL
10108
 
 */
10109
 
xmlChar *
10110
 
xmlParseVersionNum(xmlParserCtxtPtr ctxt) {
10111
 
    xmlChar *buf = NULL;
10112
 
    int len = 0;
10113
 
    int size = 10;
10114
 
    xmlChar cur;
10115
 
 
10116
 
    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
10117
 
    if (buf == NULL) {
10118
 
        xmlErrMemory(ctxt, NULL);
10119
 
        return(NULL);
10120
 
    }
10121
 
    cur = CUR;
10122
 
    if (!((cur >= '0') && (cur <= '9'))) {
10123
 
        xmlFree(buf);
10124
 
        return(NULL);
10125
 
    }
10126
 
    buf[len++] = cur;
10127
 
    NEXT;
10128
 
    cur=CUR;
10129
 
    if (cur != '.') {
10130
 
        xmlFree(buf);
10131
 
        return(NULL);
10132
 
    }
10133
 
    buf[len++] = cur;
10134
 
    NEXT;
10135
 
    cur=CUR;
10136
 
    while ((cur >= '0') && (cur <= '9')) {
10137
 
        if (len + 1 >= size) {
10138
 
            xmlChar *tmp;
10139
 
 
10140
 
            size *= 2;
10141
 
            tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
10142
 
            if (tmp == NULL) {
10143
 
                xmlFree(buf);
10144
 
                xmlErrMemory(ctxt, NULL);
10145
 
                return(NULL);
10146
 
            }
10147
 
            buf = tmp;
10148
 
        }
10149
 
        buf[len++] = cur;
10150
 
        NEXT;
10151
 
        cur=CUR;
10152
 
    }
10153
 
    buf[len] = 0;
10154
 
    return(buf);
10155
 
}
10156
 
 
10157
 
/**
10158
 
 * xmlParseVersionInfo:
10159
 
 * @ctxt:  an XML parser context
10160
 
 *
10161
 
 * parse the XML version.
10162
 
 *
10163
 
 * [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
10164
 
 *
10165
 
 * [25] Eq ::= S? '=' S?
10166
 
 *
10167
 
 * Returns the version string, e.g. "1.0"
10168
 
 */
10169
 
 
10170
 
xmlChar *
10171
 
xmlParseVersionInfo(xmlParserCtxtPtr ctxt) {
10172
 
    xmlChar *version = NULL;
10173
 
 
10174
 
    if (CMP7(CUR_PTR, 'v', 'e', 'r', 's', 'i', 'o', 'n')) {
10175
 
        SKIP(7);
10176
 
        SKIP_BLANKS;
10177
 
        if (RAW != '=') {
10178
 
            xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
10179
 
            return(NULL);
10180
 
        }
10181
 
        NEXT;
10182
 
        SKIP_BLANKS;
10183
 
        if (RAW == '"') {
10184
 
            NEXT;
10185
 
            version = xmlParseVersionNum(ctxt);
10186
 
            if (RAW != '"') {
10187
 
                xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10188
 
            } else
10189
 
                NEXT;
10190
 
        } else if (RAW == '\''){
10191
 
            NEXT;
10192
 
            version = xmlParseVersionNum(ctxt);
10193
 
            if (RAW != '\'') {
10194
 
                xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10195
 
            } else
10196
 
                NEXT;
10197
 
        } else {
10198
 
            xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
10199
 
        }
10200
 
    }
10201
 
    return(version);
10202
 
}
10203
 
 
10204
 
/**
10205
 
 * xmlParseEncName:
10206
 
 * @ctxt:  an XML parser context
10207
 
 *
10208
 
 * parse the XML encoding name
10209
 
 *
10210
 
 * [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
10211
 
 *
10212
 
 * Returns the encoding name value or NULL
10213
 
 */
10214
 
xmlChar *
10215
 
xmlParseEncName(xmlParserCtxtPtr ctxt) {
10216
 
    xmlChar *buf = NULL;
10217
 
    int len = 0;
10218
 
    int size = 10;
10219
 
    xmlChar cur;
10220
 
 
10221
 
    cur = CUR;
10222
 
    if (((cur >= 'a') && (cur <= 'z')) ||
10223
 
        ((cur >= 'A') && (cur <= 'Z'))) {
10224
 
        buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
10225
 
        if (buf == NULL) {
10226
 
            xmlErrMemory(ctxt, NULL);
10227
 
            return(NULL);
10228
 
        }
10229
 
 
10230
 
        buf[len++] = cur;
10231
 
        NEXT;
10232
 
        cur = CUR;
10233
 
        while (((cur >= 'a') && (cur <= 'z')) ||
10234
 
               ((cur >= 'A') && (cur <= 'Z')) ||
10235
 
               ((cur >= '0') && (cur <= '9')) ||
10236
 
               (cur == '.') || (cur == '_') ||
10237
 
               (cur == '-')) {
10238
 
            if (len + 1 >= size) {
10239
 
                xmlChar *tmp;
10240
 
 
10241
 
                size *= 2;
10242
 
                tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
10243
 
                if (tmp == NULL) {
10244
 
                    xmlErrMemory(ctxt, NULL);
10245
 
                    xmlFree(buf);
10246
 
                    return(NULL);
10247
 
                }
10248
 
                buf = tmp;
10249
 
            }
10250
 
            buf[len++] = cur;
10251
 
            NEXT;
10252
 
            cur = CUR;
10253
 
            if (cur == 0) {
10254
 
                SHRINK;
10255
 
                GROW;
10256
 
                cur = CUR;
10257
 
            }
10258
 
        }
10259
 
        buf[len] = 0;
10260
 
    } else {
10261
 
        xmlFatalErr(ctxt, XML_ERR_ENCODING_NAME, NULL);
10262
 
    }
10263
 
    return(buf);
10264
 
}
10265
 
 
10266
 
/**
10267
 
 * xmlParseEncodingDecl:
10268
 
 * @ctxt:  an XML parser context
10269
 
 *
10270
 
 * parse the XML encoding declaration
10271
 
 *
10272
 
 * [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' |  "'" EncName "'")
10273
 
 *
10274
 
 * this setups the conversion filters.
10275
 
 *
10276
 
 * Returns the encoding value or NULL
10277
 
 */
10278
 
 
10279
 
const xmlChar *
10280
 
xmlParseEncodingDecl(xmlParserCtxtPtr ctxt) {
10281
 
    xmlChar *encoding = NULL;
10282
 
 
10283
 
    SKIP_BLANKS;
10284
 
    if (CMP8(CUR_PTR, 'e', 'n', 'c', 'o', 'd', 'i', 'n', 'g')) {
10285
 
        SKIP(8);
10286
 
        SKIP_BLANKS;
10287
 
        if (RAW != '=') {
10288
 
            xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
10289
 
            return(NULL);
10290
 
        }
10291
 
        NEXT;
10292
 
        SKIP_BLANKS;
10293
 
        if (RAW == '"') {
10294
 
            NEXT;
10295
 
            encoding = xmlParseEncName(ctxt);
10296
 
            if (RAW != '"') {
10297
 
                xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10298
 
            } else
10299
 
                NEXT;
10300
 
        } else if (RAW == '\''){
10301
 
            NEXT;
10302
 
            encoding = xmlParseEncName(ctxt);
10303
 
            if (RAW != '\'') {
10304
 
                xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10305
 
            } else
10306
 
                NEXT;
10307
 
        } else {
10308
 
            xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
10309
 
        }
10310
 
 
10311
 
        /*
10312
 
         * Non standard parsing, allowing the user to ignore encoding
10313
 
         */
10314
 
        if (ctxt->options & XML_PARSE_IGNORE_ENC)
10315
 
            return(encoding);
10316
 
 
10317
 
        /*
10318
 
         * UTF-16 encoding stwich has already taken place at this stage,
10319
 
         * more over the little-endian/big-endian selection is already done
10320
 
         */
10321
 
        if ((encoding != NULL) &&
10322
 
            ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-16")) ||
10323
 
             (!xmlStrcasecmp(encoding, BAD_CAST "UTF16")))) {
10324
 
            /*
10325
 
             * If no encoding was passed to the parser, that we are
10326
 
             * using UTF-16 and no decoder is present i.e. the
10327
 
             * document is apparently UTF-8 compatible, then raise an
10328
 
             * encoding mismatch fatal error
10329
 
             */
10330
 
            if ((ctxt->encoding == NULL) &&
10331
 
                (ctxt->input->buf != NULL) &&
10332
 
                (ctxt->input->buf->encoder == NULL)) {
10333
 
                xmlFatalErrMsg(ctxt, XML_ERR_INVALID_ENCODING,
10334
 
                  "Document labelled UTF-16 but has UTF-8 content\n");
10335
 
            }
10336
 
            if (ctxt->encoding != NULL)
10337
 
                xmlFree((xmlChar *) ctxt->encoding);
10338
 
            ctxt->encoding = encoding;
10339
 
        }
10340
 
        /*
10341
 
         * UTF-8 encoding is handled natively
10342
 
         */
10343
 
        else if ((encoding != NULL) &&
10344
 
            ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-8")) ||
10345
 
             (!xmlStrcasecmp(encoding, BAD_CAST "UTF8")))) {
10346
 
            if (ctxt->encoding != NULL)
10347
 
                xmlFree((xmlChar *) ctxt->encoding);
10348
 
            ctxt->encoding = encoding;
10349
 
        }
10350
 
        else if (encoding != NULL) {
10351
 
            xmlCharEncodingHandlerPtr handler;
10352
 
 
10353
 
            if (ctxt->input->encoding != NULL)
10354
 
                xmlFree((xmlChar *) ctxt->input->encoding);
10355
 
            ctxt->input->encoding = encoding;
10356
 
 
10357
 
            handler = xmlFindCharEncodingHandler((const char *) encoding);
10358
 
            if (handler != NULL) {
10359
 
                xmlSwitchToEncoding(ctxt, handler);
10360
 
            } else {
10361
 
                xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
10362
 
                        "Unsupported encoding %s\n", encoding);
10363
 
                return(NULL);
10364
 
            }
10365
 
        }
10366
 
    }
10367
 
    return(encoding);
10368
 
}
10369
 
 
10370
 
/**
10371
 
 * xmlParseSDDecl:
10372
 
 * @ctxt:  an XML parser context
10373
 
 *
10374
 
 * parse the XML standalone declaration
10375
 
 *
10376
 
 * [32] SDDecl ::= S 'standalone' Eq
10377
 
 *                 (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no')'"'))
10378
 
 *
10379
 
 * [ VC: Standalone Document Declaration ]
10380
 
 * TODO The standalone document declaration must have the value "no"
10381
 
 * if any external markup declarations contain declarations of:
10382
 
 *  - attributes with default values, if elements to which these
10383
 
 *    attributes apply appear in the document without specifications
10384
 
 *    of values for these attributes, or
10385
 
 *  - entities (other than amp, lt, gt, apos, quot), if references
10386
 
 *    to those entities appear in the document, or
10387
 
 *  - attributes with values subject to normalization, where the
10388
 
 *    attribute appears in the document with a value which will change
10389
 
 *    as a result of normalization, or
10390
 
 *  - element types with element content, if white space occurs directly
10391
 
 *    within any instance of those types.
10392
 
 *
10393
 
 * Returns:
10394
 
 *   1 if standalone="yes"
10395
 
 *   0 if standalone="no"
10396
 
 *  -2 if standalone attribute is missing or invalid
10397
 
 *        (A standalone value of -2 means that the XML declaration was found,
10398
 
 *         but no value was specified for the standalone attribute).
10399
 
 */
10400
 
 
10401
 
int
10402
 
xmlParseSDDecl(xmlParserCtxtPtr ctxt) {
10403
 
    int standalone = -2;
10404
 
 
10405
 
    SKIP_BLANKS;
10406
 
    if (CMP10(CUR_PTR, 's', 't', 'a', 'n', 'd', 'a', 'l', 'o', 'n', 'e')) {
10407
 
        SKIP(10);
10408
 
        SKIP_BLANKS;
10409
 
        if (RAW != '=') {
10410
 
            xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
10411
 
            return(standalone);
10412
 
        }
10413
 
        NEXT;
10414
 
        SKIP_BLANKS;
10415
 
        if (RAW == '\''){
10416
 
            NEXT;
10417
 
            if ((RAW == 'n') && (NXT(1) == 'o')) {
10418
 
                standalone = 0;
10419
 
                SKIP(2);
10420
 
            } else if ((RAW == 'y') && (NXT(1) == 'e') &&
10421
 
                       (NXT(2) == 's')) {
10422
 
                standalone = 1;
10423
 
                SKIP(3);
10424
 
            } else {
10425
 
                xmlFatalErr(ctxt, XML_ERR_STANDALONE_VALUE, NULL);
10426
 
            }
10427
 
            if (RAW != '\'') {
10428
 
                xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10429
 
            } else
10430
 
                NEXT;
10431
 
        } else if (RAW == '"'){
10432
 
            NEXT;
10433
 
            if ((RAW == 'n') && (NXT(1) == 'o')) {
10434
 
                standalone = 0;
10435
 
                SKIP(2);
10436
 
            } else if ((RAW == 'y') && (NXT(1) == 'e') &&
10437
 
                       (NXT(2) == 's')) {
10438
 
                standalone = 1;
10439
 
                SKIP(3);
10440
 
            } else {
10441
 
                xmlFatalErr(ctxt, XML_ERR_STANDALONE_VALUE, NULL);
10442
 
            }
10443
 
            if (RAW != '"') {
10444
 
                xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
10445
 
            } else
10446
 
                NEXT;
10447
 
        } else {
10448
 
            xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
10449
 
        }
10450
 
    }
10451
 
    return(standalone);
10452
 
}
10453
 
 
10454
 
/**
10455
 
 * xmlParseXMLDecl:
10456
 
 * @ctxt:  an XML parser context
10457
 
 *
10458
 
 * parse an XML declaration header
10459
 
 *
10460
 
 * [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
10461
 
 */
10462
 
 
10463
 
void
10464
 
xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
10465
 
    xmlChar *version;
10466
 
 
10467
 
    /*
10468
 
     * This value for standalone indicates that the document has an
10469
 
     * XML declaration but it does not have a standalone attribute.
10470
 
     * It will be overwritten later if a standalone attribute is found.
10471
 
     */
10472
 
    ctxt->input->standalone = -2;
10473
 
 
10474
 
    /*
10475
 
     * We know that '<?xml' is here.
10476
 
     */
10477
 
    SKIP(5);
10478
 
 
10479
 
    if (!IS_BLANK_CH(RAW)) {
10480
 
        xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
10481
 
                       "Blank needed after '<?xml'\n");
10482
 
    }
10483
 
    SKIP_BLANKS;
10484
 
 
10485
 
    /*
10486
 
     * We must have the VersionInfo here.
10487
 
     */
10488
 
    version = xmlParseVersionInfo(ctxt);
10489
 
    if (version == NULL) {
10490
 
        xmlFatalErr(ctxt, XML_ERR_VERSION_MISSING, NULL);
10491
 
    } else {
10492
 
        if (!xmlStrEqual(version, (const xmlChar *) XML_DEFAULT_VERSION)) {
10493
 
            /*
10494
 
             * Changed here for XML-1.0 5th edition
10495
 
             */
10496
 
            if (ctxt->options & XML_PARSE_OLD10) {
10497
 
                xmlFatalErrMsgStr(ctxt, XML_ERR_UNKNOWN_VERSION,
10498
 
                                  "Unsupported version '%s'\n",
10499
 
                                  version);
10500
 
            } else {
10501
 
                if ((version[0] == '1') && ((version[1] == '.'))) {
10502
 
                    xmlWarningMsg(ctxt, XML_WAR_UNKNOWN_VERSION,
10503
 
                                  "Unsupported version '%s'\n",
10504
 
                                  version, NULL);
10505
 
                } else {
10506
 
                    xmlFatalErrMsgStr(ctxt, XML_ERR_UNKNOWN_VERSION,
10507
 
                                      "Unsupported version '%s'\n",
10508
 
                                      version);
10509
 
                }
10510
 
            }
10511
 
        }
10512
 
        if (ctxt->version != NULL)
10513
 
            xmlFree((void *) ctxt->version);
10514
 
        ctxt->version = version;
10515
 
    }
10516
 
 
10517
 
    /*
10518
 
     * We may have the encoding declaration
10519
 
     */
10520
 
    if (!IS_BLANK_CH(RAW)) {
10521
 
        if ((RAW == '?') && (NXT(1) == '>')) {
10522
 
            SKIP(2);
10523
 
            return;
10524
 
        }
10525
 
        xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
10526
 
    }
10527
 
    xmlParseEncodingDecl(ctxt);
10528
 
    if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
10529
 
        /*
10530
 
         * The XML REC instructs us to stop parsing right here
10531
 
         */
10532
 
        return;
10533
 
    }
10534
 
 
10535
 
    /*
10536
 
     * We may have the standalone status.
10537
 
     */
10538
 
    if ((ctxt->input->encoding != NULL) && (!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
 
 
10546
 
    /*
10547
 
     * We can grow the input buffer freely at that point
10548
 
     */
10549
 
    GROW;
10550
 
 
10551
 
    SKIP_BLANKS;
10552
 
    ctxt->input->standalone = xmlParseSDDecl(ctxt);
10553
 
 
10554
 
    SKIP_BLANKS;
10555
 
    if ((RAW == '?') && (NXT(1) == '>')) {
10556
 
        SKIP(2);
10557
 
    } else if (RAW == '>') {
10558
 
        /* Deprecated old WD ... */
10559
 
        xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
10560
 
        NEXT;
10561
 
    } else {
10562
 
        xmlFatalErr(ctxt, XML_ERR_XMLDECL_NOT_FINISHED, NULL);
10563
 
        MOVETO_ENDTAG(CUR_PTR);
10564
 
        NEXT;
10565
 
    }
10566
 
}
10567
 
 
10568
 
/**
10569
 
 * xmlParseMisc:
10570
 
 * @ctxt:  an XML parser context
10571
 
 *
10572
 
 * parse an XML Misc* optional field.
10573
 
 *
10574
 
 * [27] Misc ::= Comment | PI |  S
10575
 
 */
10576
 
 
10577
 
void
10578
 
xmlParseMisc(xmlParserCtxtPtr ctxt) {
10579
 
    while ((ctxt->instate != XML_PARSER_EOF) &&
10580
 
           (((RAW == '<') && (NXT(1) == '?')) ||
10581
 
            (CMP4(CUR_PTR, '<', '!', '-', '-')) ||
10582
 
            IS_BLANK_CH(CUR))) {
10583
 
        if ((RAW == '<') && (NXT(1) == '?')) {
10584
 
            xmlParsePI(ctxt);
10585
 
        } else if (IS_BLANK_CH(CUR)) {
10586
 
            NEXT;
10587
 
        } else
10588
 
            xmlParseComment(ctxt);
10589
 
    }
10590
 
}
10591
 
 
10592
 
/**
10593
 
 * xmlParseDocument:
10594
 
 * @ctxt:  an XML parser context
10595
 
 *
10596
 
 * parse an XML document (and build a tree if using the standard SAX
10597
 
 * interface).
10598
 
 *
10599
 
 * [1] document ::= prolog element Misc*
10600
 
 *
10601
 
 * [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
10602
 
 *
10603
 
 * Returns 0, -1 in case of error. the parser context is augmented
10604
 
 *                as a result of the parsing.
10605
 
 */
10606
 
 
10607
 
int
10608
 
xmlParseDocument(xmlParserCtxtPtr ctxt) {
10609
 
    xmlChar start[4];
10610
 
    xmlCharEncoding enc;
10611
 
 
10612
 
    xmlInitParser();
10613
 
 
10614
 
    if ((ctxt == NULL) || (ctxt->input == NULL))
10615
 
        return(-1);
10616
 
 
10617
 
    GROW;
10618
 
 
10619
 
    /*
10620
 
     * SAX: detecting the level.
10621
 
     */
10622
 
    xmlDetectSAX2(ctxt);
10623
 
 
10624
 
    /*
10625
 
     * SAX: beginning of the document processing.
10626
 
     */
10627
 
    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
10628
 
        ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
10629
 
    if (ctxt->instate == XML_PARSER_EOF)
10630
 
        return(-1);
10631
 
 
10632
 
    if ((ctxt->encoding == NULL) &&
10633
 
        ((ctxt->input->end - ctxt->input->cur) >= 4)) {
10634
 
        /*
10635
 
         * Get the 4 first bytes and decode the charset
10636
 
         * if enc != XML_CHAR_ENCODING_NONE
10637
 
         * plug some encoding conversion routines.
10638
 
         */
10639
 
        start[0] = RAW;
10640
 
        start[1] = NXT(1);
10641
 
        start[2] = NXT(2);
10642
 
        start[3] = NXT(3);
10643
 
        enc = xmlDetectCharEncoding(&start[0], 4);
10644
 
        if (enc != XML_CHAR_ENCODING_NONE) {
10645
 
            xmlSwitchEncoding(ctxt, enc);
10646
 
        }
10647
 
    }
10648
 
 
10649
 
 
10650
 
    if (CUR == 0) {
10651
 
        xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
10652
 
    }
10653
 
 
10654
 
    /*
10655
 
     * Check for the XMLDecl in the Prolog.
10656
 
     * do not GROW here to avoid the detected encoder to decode more
10657
 
     * than just the first line, unless the amount of data is really
10658
 
     * too small to hold "<?xml version="1.0" encoding="foo"
10659
 
     */
10660
 
    if ((ctxt->input->end - ctxt->input->cur) < 35) {
10661
 
       GROW;
10662
 
    }
10663
 
    if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
10664
 
 
10665
 
        /*
10666
 
         * Note that we will switch encoding on the fly.
10667
 
         */
10668
 
        xmlParseXMLDecl(ctxt);
10669
 
        if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
10670
 
            /*
10671
 
             * The XML REC instructs us to stop parsing right here
10672
 
             */
10673
 
            return(-1);
10674
 
        }
10675
 
        ctxt->standalone = ctxt->input->standalone;
10676
 
        SKIP_BLANKS;
10677
 
    } else {
10678
 
        ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
10679
 
    }
10680
 
    if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
10681
 
        ctxt->sax->startDocument(ctxt->userData);
10682
 
    if (ctxt->instate == XML_PARSER_EOF)
10683
 
        return(-1);
10684
 
 
10685
 
    /*
10686
 
     * The Misc part of the Prolog
10687
 
     */
10688
 
    GROW;
10689
 
    xmlParseMisc(ctxt);
10690
 
 
10691
 
    /*
10692
 
     * Then possibly doc type declaration(s) and more Misc
10693
 
     * (doctypedecl Misc*)?
10694
 
     */
10695
 
    GROW;
10696
 
    if (CMP9(CUR_PTR, '<', '!', 'D', 'O', 'C', 'T', 'Y', 'P', 'E')) {
10697
 
 
10698
 
        ctxt->inSubset = 1;
10699
 
        xmlParseDocTypeDecl(ctxt);
10700
 
        if (RAW == '[') {
10701
 
            ctxt->instate = XML_PARSER_DTD;
10702
 
            xmlParseInternalSubset(ctxt);
10703
 
            if (ctxt->instate == XML_PARSER_EOF)
10704
 
                return(-1);
10705
 
        }
10706
 
 
10707
 
        /*
10708
 
         * Create and update the external subset.
10709
 
         */
10710
 
        ctxt->inSubset = 2;
10711
 
        if ((ctxt->sax != NULL) && (ctxt->sax->externalSubset != NULL) &&
10712
 
            (!ctxt->disableSAX))
10713
 
            ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
10714
 
                                      ctxt->extSubSystem, ctxt->extSubURI);
10715
 
        if (ctxt->instate == XML_PARSER_EOF)
10716
 
            return(-1);
10717
 
        ctxt->inSubset = 0;
10718
 
 
10719
 
        xmlCleanSpecialAttr(ctxt);
10720
 
 
10721
 
        ctxt->instate = XML_PARSER_PROLOG;
10722
 
        xmlParseMisc(ctxt);
10723
 
    }
10724
 
 
10725
 
    /*
10726
 
     * Time to start parsing the tree itself
10727
 
     */
10728
 
    GROW;
10729
 
    if (RAW != '<') {
10730
 
        xmlFatalErrMsg(ctxt, XML_ERR_DOCUMENT_EMPTY,
10731
 
                       "Start tag expected, '<' not found\n");
10732
 
    } else {
10733
 
        ctxt->instate = XML_PARSER_CONTENT;
10734
 
        xmlParseElement(ctxt);
10735
 
        ctxt->instate = XML_PARSER_EPILOG;
10736
 
 
10737
 
 
10738
 
        /*
10739
 
         * The Misc part at the end
10740
 
         */
10741
 
        xmlParseMisc(ctxt);
10742
 
 
10743
 
        if (RAW != 0) {
10744
 
            xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
10745
 
        }
10746
 
        ctxt->instate = XML_PARSER_EOF;
10747
 
    }
10748
 
 
10749
 
    /*
10750
 
     * SAX: end of the document processing.
10751
 
     */
10752
 
    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
10753
 
        ctxt->sax->endDocument(ctxt->userData);
10754
 
 
10755
 
    /*
10756
 
     * Remove locally kept entity definitions if the tree was not built
10757
 
     */
10758
 
    if ((ctxt->myDoc != NULL) &&
10759
 
        (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) {
10760
 
        xmlFreeDoc(ctxt->myDoc);
10761
 
        ctxt->myDoc = NULL;
10762
 
    }
10763
 
 
10764
 
    if ((ctxt->wellFormed) && (ctxt->myDoc != NULL)) {
10765
 
        ctxt->myDoc->properties |= XML_DOC_WELLFORMED;
10766
 
        if (ctxt->valid)
10767
 
            ctxt->myDoc->properties |= XML_DOC_DTDVALID;
10768
 
        if (ctxt->nsWellFormed)
10769
 
            ctxt->myDoc->properties |= XML_DOC_NSVALID;
10770
 
        if (ctxt->options & XML_PARSE_OLD10)
10771
 
            ctxt->myDoc->properties |= XML_DOC_OLD10;
10772
 
    }
10773
 
    if (! ctxt->wellFormed) {
10774
 
        ctxt->valid = 0;
10775
 
        return(-1);
10776
 
    }
10777
 
    return(0);
10778
 
}
10779
 
 
10780
 
/**
10781
 
 * xmlParseExtParsedEnt:
10782
 
 * @ctxt:  an XML parser context
10783
 
 *
10784
 
 * parse a general parsed entity
10785
 
 * An external general parsed entity is well-formed if it matches the
10786
 
 * production labeled extParsedEnt.
10787
 
 *
10788
 
 * [78] extParsedEnt ::= TextDecl? content
10789
 
 *
10790
 
 * Returns 0, -1 in case of error. the parser context is augmented
10791
 
 *                as a result of the parsing.
10792
 
 */
10793
 
 
10794
 
int
10795
 
xmlParseExtParsedEnt(xmlParserCtxtPtr ctxt) {
10796
 
    xmlChar start[4];
10797
 
    xmlCharEncoding enc;
10798
 
 
10799
 
    if ((ctxt == NULL) || (ctxt->input == NULL))
10800
 
        return(-1);
10801
 
 
10802
 
    xmlDefaultSAXHandlerInit();
10803
 
 
10804
 
    xmlDetectSAX2(ctxt);
10805
 
 
10806
 
    GROW;
10807
 
 
10808
 
    /*
10809
 
     * SAX: beginning of the document processing.
10810
 
     */
10811
 
    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
10812
 
        ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
10813
 
 
10814
 
    /*
10815
 
     * Get the 4 first bytes and decode the charset
10816
 
     * if enc != XML_CHAR_ENCODING_NONE
10817
 
     * plug some encoding conversion routines.
10818
 
     */
10819
 
    if ((ctxt->input->end - ctxt->input->cur) >= 4) {
10820
 
        start[0] = RAW;
10821
 
        start[1] = NXT(1);
10822
 
        start[2] = NXT(2);
10823
 
        start[3] = NXT(3);
10824
 
        enc = xmlDetectCharEncoding(start, 4);
10825
 
        if (enc != XML_CHAR_ENCODING_NONE) {
10826
 
            xmlSwitchEncoding(ctxt, enc);
10827
 
        }
10828
 
    }
10829
 
 
10830
 
 
10831
 
    if (CUR == 0) {
10832
 
        xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
10833
 
    }
10834
 
 
10835
 
    /*
10836
 
     * Check for the XMLDecl in the Prolog.
10837
 
     */
10838
 
    GROW;
10839
 
    if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
10840
 
 
10841
 
        /*
10842
 
         * Note that we will switch encoding on the fly.
10843
 
         */
10844
 
        xmlParseXMLDecl(ctxt);
10845
 
        if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
10846
 
            /*
10847
 
             * The XML REC instructs us to stop parsing right here
10848
 
             */
10849
 
            return(-1);
10850
 
        }
10851
 
        SKIP_BLANKS;
10852
 
    } else {
10853
 
        ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
10854
 
    }
10855
 
    if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
10856
 
        ctxt->sax->startDocument(ctxt->userData);
10857
 
    if (ctxt->instate == XML_PARSER_EOF)
10858
 
        return(-1);
10859
 
 
10860
 
    /*
10861
 
     * Doing validity checking on chunk doesn't make sense
10862
 
     */
10863
 
    ctxt->instate = XML_PARSER_CONTENT;
10864
 
    ctxt->validate = 0;
10865
 
    ctxt->loadsubset = 0;
10866
 
    ctxt->depth = 0;
10867
 
 
10868
 
    xmlParseContent(ctxt);
10869
 
    if (ctxt->instate == XML_PARSER_EOF)
10870
 
        return(-1);
10871
 
 
10872
 
    if ((RAW == '<') && (NXT(1) == '/')) {
10873
 
        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
10874
 
    } else if (RAW != 0) {
10875
 
        xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
10876
 
    }
10877
 
 
10878
 
    /*
10879
 
     * SAX: end of the document processing.
10880
 
     */
10881
 
    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
10882
 
        ctxt->sax->endDocument(ctxt->userData);
10883
 
 
10884
 
    if (! ctxt->wellFormed) return(-1);
10885
 
    return(0);
10886
 
}
10887
 
 
10888
 
#ifdef LIBXML_PUSH_ENABLED
10889
 
/************************************************************************
10890
 
 *                                                                      *
10891
 
 *              Progressive parsing interfaces                          *
10892
 
 *                                                                      *
10893
 
 ************************************************************************/
10894
 
 
10895
 
/**
10896
 
 * xmlParseLookupSequence:
10897
 
 * @ctxt:  an XML parser context
10898
 
 * @first:  the first char to lookup
10899
 
 * @next:  the next char to lookup or zero
10900
 
 * @third:  the next char to lookup or zero
10901
 
 *
10902
 
 * Try to find if a sequence (first, next, third) or  just (first next) or
10903
 
 * (first) is available in the input stream.
10904
 
 * This function has a side effect of (possibly) incrementing ctxt->checkIndex
10905
 
 * to avoid rescanning sequences of bytes, it DOES change the state of the
10906
 
 * parser, do not use liberally.
10907
 
 *
10908
 
 * Returns the index to the current parsing point if the full sequence
10909
 
 *      is available, -1 otherwise.
10910
 
 */
10911
 
static int
10912
 
xmlParseLookupSequence(xmlParserCtxtPtr ctxt, xmlChar first,
10913
 
                       xmlChar next, xmlChar third) {
10914
 
    int base, len;
10915
 
    xmlParserInputPtr in;
10916
 
    const xmlChar *buf;
10917
 
 
10918
 
    in = ctxt->input;
10919
 
    if (in == NULL) return(-1);
10920
 
    base = in->cur - in->base;
10921
 
    if (base < 0) return(-1);
10922
 
    if (ctxt->checkIndex > base)
10923
 
        base = ctxt->checkIndex;
10924
 
    if (in->buf == NULL) {
10925
 
        buf = in->base;
10926
 
        len = in->length;
10927
 
    } else {
10928
 
        buf = xmlBufContent(in->buf->buffer);
10929
 
        len = xmlBufUse(in->buf->buffer);
10930
 
    }
10931
 
    /* take into account the sequence length */
10932
 
    if (third) len -= 2;
10933
 
    else if (next) len --;
10934
 
    for (;base < len;base++) {
10935
 
        if (buf[base] == first) {
10936
 
            if (third != 0) {
10937
 
                if ((buf[base + 1] != next) ||
10938
 
                    (buf[base + 2] != third)) continue;
10939
 
            } else if (next != 0) {
10940
 
                if (buf[base + 1] != next) continue;
10941
 
            }
10942
 
            ctxt->checkIndex = 0;
10943
 
#ifdef DEBUG_PUSH
10944
 
            if (next == 0)
10945
 
                xmlGenericError(xmlGenericErrorContext,
10946
 
                        "PP: lookup '%c' found at %d\n",
10947
 
                        first, base);
10948
 
            else if (third == 0)
10949
 
                xmlGenericError(xmlGenericErrorContext,
10950
 
                        "PP: lookup '%c%c' found at %d\n",
10951
 
                        first, next, base);
10952
 
            else
10953
 
                xmlGenericError(xmlGenericErrorContext,
10954
 
                        "PP: lookup '%c%c%c' found at %d\n",
10955
 
                        first, next, third, base);
10956
 
#endif
10957
 
            return(base - (in->cur - in->base));
10958
 
        }
10959
 
    }
10960
 
    ctxt->checkIndex = base;
10961
 
#ifdef DEBUG_PUSH
10962
 
    if (next == 0)
10963
 
        xmlGenericError(xmlGenericErrorContext,
10964
 
                "PP: lookup '%c' failed\n", first);
10965
 
    else if (third == 0)
10966
 
        xmlGenericError(xmlGenericErrorContext,
10967
 
                "PP: lookup '%c%c' failed\n", first, next);
10968
 
    else
10969
 
        xmlGenericError(xmlGenericErrorContext,
10970
 
                "PP: lookup '%c%c%c' failed\n", first, next, third);
10971
 
#endif
10972
 
    return(-1);
10973
 
}
10974
 
 
10975
 
/**
10976
 
 * xmlParseGetLasts:
10977
 
 * @ctxt:  an XML parser context
10978
 
 * @lastlt:  pointer to store the last '<' from the input
10979
 
 * @lastgt:  pointer to store the last '>' from the input
10980
 
 *
10981
 
 * Lookup the last < and > in the current chunk
10982
 
 */
10983
 
static void
10984
 
xmlParseGetLasts(xmlParserCtxtPtr ctxt, const xmlChar **lastlt,
10985
 
                 const xmlChar **lastgt) {
10986
 
    const xmlChar *tmp;
10987
 
 
10988
 
    if ((ctxt == NULL) || (lastlt == NULL) || (lastgt == NULL)) {
10989
 
        xmlGenericError(xmlGenericErrorContext,
10990
 
                    "Internal error: xmlParseGetLasts\n");
10991
 
        return;
10992
 
    }
10993
 
    if ((ctxt->progressive != 0) && (ctxt->inputNr == 1)) {
10994
 
        tmp = ctxt->input->end;
10995
 
        tmp--;
10996
 
        while ((tmp >= ctxt->input->base) && (*tmp != '<')) tmp--;
10997
 
        if (tmp < ctxt->input->base) {
10998
 
            *lastlt = NULL;
10999
 
            *lastgt = NULL;
11000
 
        } else {
11001
 
            *lastlt = tmp;
11002
 
            tmp++;
11003
 
            while ((tmp < ctxt->input->end) && (*tmp != '>')) {
11004
 
                if (*tmp == '\'') {
11005
 
                    tmp++;
11006
 
                    while ((tmp < ctxt->input->end) && (*tmp != '\'')) tmp++;
11007
 
                    if (tmp < ctxt->input->end) tmp++;
11008
 
                } else if (*tmp == '"') {
11009
 
                    tmp++;
11010
 
                    while ((tmp < ctxt->input->end) && (*tmp != '"')) tmp++;
11011
 
                    if (tmp < ctxt->input->end) tmp++;
11012
 
                } else
11013
 
                    tmp++;
11014
 
            }
11015
 
            if (tmp < ctxt->input->end)
11016
 
                *lastgt = tmp;
11017
 
            else {
11018
 
                tmp = *lastlt;
11019
 
                tmp--;
11020
 
                while ((tmp >= ctxt->input->base) && (*tmp != '>')) tmp--;
11021
 
                if (tmp >= ctxt->input->base)
11022
 
                    *lastgt = tmp;
11023
 
                else
11024
 
                    *lastgt = NULL;
11025
 
            }
11026
 
        }
11027
 
    } else {
11028
 
        *lastlt = NULL;
11029
 
        *lastgt = NULL;
11030
 
    }
11031
 
}
11032
 
/**
11033
 
 * xmlCheckCdataPush:
11034
 
 * @cur: pointer to the bock of characters
11035
 
 * @len: length of the block in bytes
11036
 
 *
11037
 
 * Check that the block of characters is okay as SCdata content [20]
11038
 
 *
11039
 
 * Returns the number of bytes to pass if okay, a negative index where an
11040
 
 *         UTF-8 error occured otherwise
11041
 
 */
11042
 
static int
11043
 
xmlCheckCdataPush(const xmlChar *utf, int len) {
11044
 
    int ix;
11045
 
    unsigned char c;
11046
 
    int codepoint;
11047
 
 
11048
 
    if ((utf == NULL) || (len <= 0))
11049
 
        return(0);
11050
 
 
11051
 
    for (ix = 0; ix < len;) {      /* string is 0-terminated */
11052
 
        c = utf[ix];
11053
 
        if ((c & 0x80) == 0x00) {       /* 1-byte code, starts with 10 */
11054
 
            if (c >= 0x20)
11055
 
                ix++;
11056
 
            else if ((c == 0xA) || (c == 0xD) || (c == 0x9))
11057
 
                ix++;
11058
 
            else
11059
 
                return(-ix);
11060
 
        } else if ((c & 0xe0) == 0xc0) {/* 2-byte code, starts with 110 */
11061
 
            if (ix + 2 > len) return(ix);
11062
 
            if ((utf[ix+1] & 0xc0 ) != 0x80)
11063
 
                return(-ix);
11064
 
            codepoint = (utf[ix] & 0x1f) << 6;
11065
 
            codepoint |= utf[ix+1] & 0x3f;
11066
 
            if (!xmlIsCharQ(codepoint))
11067
 
                return(-ix);
11068
 
            ix += 2;
11069
 
        } else if ((c & 0xf0) == 0xe0) {/* 3-byte code, starts with 1110 */
11070
 
            if (ix + 3 > len) return(ix);
11071
 
            if (((utf[ix+1] & 0xc0) != 0x80) ||
11072
 
                ((utf[ix+2] & 0xc0) != 0x80))
11073
 
                    return(-ix);
11074
 
            codepoint = (utf[ix] & 0xf) << 12;
11075
 
            codepoint |= (utf[ix+1] & 0x3f) << 6;
11076
 
            codepoint |= utf[ix+2] & 0x3f;
11077
 
            if (!xmlIsCharQ(codepoint))
11078
 
                return(-ix);
11079
 
            ix += 3;
11080
 
        } else if ((c & 0xf8) == 0xf0) {/* 4-byte code, starts with 11110 */
11081
 
            if (ix + 4 > len) return(ix);
11082
 
            if (((utf[ix+1] & 0xc0) != 0x80) ||
11083
 
                ((utf[ix+2] & 0xc0) != 0x80) ||
11084
 
                ((utf[ix+3] & 0xc0) != 0x80))
11085
 
                    return(-ix);
11086
 
            codepoint = (utf[ix] & 0x7) << 18;
11087
 
            codepoint |= (utf[ix+1] & 0x3f) << 12;
11088
 
            codepoint |= (utf[ix+2] & 0x3f) << 6;
11089
 
            codepoint |= utf[ix+3] & 0x3f;
11090
 
            if (!xmlIsCharQ(codepoint))
11091
 
                return(-ix);
11092
 
            ix += 4;
11093
 
        } else                          /* unknown encoding */
11094
 
            return(-ix);
11095
 
      }
11096
 
      return(ix);
11097
 
}
11098
 
 
11099
 
/**
11100
 
 * xmlParseTryOrFinish:
11101
 
 * @ctxt:  an XML parser context
11102
 
 * @terminate:  last chunk indicator
11103
 
 *
11104
 
 * Try to progress on parsing
11105
 
 *
11106
 
 * Returns zero if no parsing was possible
11107
 
 */
11108
 
static int
11109
 
xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
11110
 
    int ret = 0;
11111
 
    int avail, tlen;
11112
 
    xmlChar cur, next;
11113
 
    const xmlChar *lastlt, *lastgt;
11114
 
 
11115
 
    if (ctxt->input == NULL)
11116
 
        return(0);
11117
 
 
11118
 
#ifdef DEBUG_PUSH
11119
 
    switch (ctxt->instate) {
11120
 
        case XML_PARSER_EOF:
11121
 
            xmlGenericError(xmlGenericErrorContext,
11122
 
                    "PP: try EOF\n"); break;
11123
 
        case XML_PARSER_START:
11124
 
            xmlGenericError(xmlGenericErrorContext,
11125
 
                    "PP: try START\n"); break;
11126
 
        case XML_PARSER_MISC:
11127
 
            xmlGenericError(xmlGenericErrorContext,
11128
 
                    "PP: try MISC\n");break;
11129
 
        case XML_PARSER_COMMENT:
11130
 
            xmlGenericError(xmlGenericErrorContext,
11131
 
                    "PP: try COMMENT\n");break;
11132
 
        case XML_PARSER_PROLOG:
11133
 
            xmlGenericError(xmlGenericErrorContext,
11134
 
                    "PP: try PROLOG\n");break;
11135
 
        case XML_PARSER_START_TAG:
11136
 
            xmlGenericError(xmlGenericErrorContext,
11137
 
                    "PP: try START_TAG\n");break;
11138
 
        case XML_PARSER_CONTENT:
11139
 
            xmlGenericError(xmlGenericErrorContext,
11140
 
                    "PP: try CONTENT\n");break;
11141
 
        case XML_PARSER_CDATA_SECTION:
11142
 
            xmlGenericError(xmlGenericErrorContext,
11143
 
                    "PP: try CDATA_SECTION\n");break;
11144
 
        case XML_PARSER_END_TAG:
11145
 
            xmlGenericError(xmlGenericErrorContext,
11146
 
                    "PP: try END_TAG\n");break;
11147
 
        case XML_PARSER_ENTITY_DECL:
11148
 
            xmlGenericError(xmlGenericErrorContext,
11149
 
                    "PP: try ENTITY_DECL\n");break;
11150
 
        case XML_PARSER_ENTITY_VALUE:
11151
 
            xmlGenericError(xmlGenericErrorContext,
11152
 
                    "PP: try ENTITY_VALUE\n");break;
11153
 
        case XML_PARSER_ATTRIBUTE_VALUE:
11154
 
            xmlGenericError(xmlGenericErrorContext,
11155
 
                    "PP: try ATTRIBUTE_VALUE\n");break;
11156
 
        case XML_PARSER_DTD:
11157
 
            xmlGenericError(xmlGenericErrorContext,
11158
 
                    "PP: try DTD\n");break;
11159
 
        case XML_PARSER_EPILOG:
11160
 
            xmlGenericError(xmlGenericErrorContext,
11161
 
                    "PP: try EPILOG\n");break;
11162
 
        case XML_PARSER_PI:
11163
 
            xmlGenericError(xmlGenericErrorContext,
11164
 
                    "PP: try PI\n");break;
11165
 
        case XML_PARSER_IGNORE:
11166
 
            xmlGenericError(xmlGenericErrorContext,
11167
 
                    "PP: try IGNORE\n");break;
11168
 
    }
11169
 
#endif
11170
 
 
11171
 
    if ((ctxt->input != NULL) &&
11172
 
        (ctxt->input->cur - ctxt->input->base > 4096)) {
11173
 
        xmlSHRINK(ctxt);
11174
 
        ctxt->checkIndex = 0;
11175
 
    }
11176
 
    xmlParseGetLasts(ctxt, &lastlt, &lastgt);
11177
 
 
11178
 
    while (ctxt->instate != XML_PARSER_EOF) {
11179
 
        if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
11180
 
            return(0);
11181
 
 
11182
 
 
11183
 
        /*
11184
 
         * Pop-up of finished entities.
11185
 
         */
11186
 
        while ((RAW == 0) && (ctxt->inputNr > 1))
11187
 
            xmlPopInput(ctxt);
11188
 
 
11189
 
        if (ctxt->input == NULL) break;
11190
 
        if (ctxt->input->buf == NULL)
11191
 
            avail = ctxt->input->length -
11192
 
                    (ctxt->input->cur - ctxt->input->base);
11193
 
        else {
11194
 
            /*
11195
 
             * If we are operating on converted input, try to flush
11196
 
             * remainng chars to avoid them stalling in the non-converted
11197
 
             * buffer. But do not do this in document start where
11198
 
             * encoding="..." may not have been read and we work on a
11199
 
             * guessed encoding.
11200
 
             */
11201
 
            if ((ctxt->instate != XML_PARSER_START) &&
11202
 
                (ctxt->input->buf->raw != NULL) &&
11203
 
                (xmlBufIsEmpty(ctxt->input->buf->raw) == 0)) {
11204
 
                size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer,
11205
 
                                                 ctxt->input);
11206
 
                size_t current = ctxt->input->cur - ctxt->input->base;
11207
 
 
11208
 
                xmlParserInputBufferPush(ctxt->input->buf, 0, "");
11209
 
                xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input,
11210
 
                                      base, current);
11211
 
            }
11212
 
            avail = xmlBufUse(ctxt->input->buf->buffer) -
11213
 
                    (ctxt->input->cur - ctxt->input->base);
11214
 
        }
11215
 
        if (avail < 1)
11216
 
            goto done;
11217
 
        switch (ctxt->instate) {
11218
 
            case XML_PARSER_EOF:
11219
 
                /*
11220
 
                 * Document parsing is done !
11221
 
                 */
11222
 
                goto done;
11223
 
            case XML_PARSER_START:
11224
 
                if (ctxt->charset == XML_CHAR_ENCODING_NONE) {
11225
 
                    xmlChar start[4];
11226
 
                    xmlCharEncoding enc;
11227
 
 
11228
 
                    /*
11229
 
                     * Very first chars read from the document flow.
11230
 
                     */
11231
 
                    if (avail < 4)
11232
 
                        goto done;
11233
 
 
11234
 
                    /*
11235
 
                     * Get the 4 first bytes and decode the charset
11236
 
                     * if enc != XML_CHAR_ENCODING_NONE
11237
 
                     * plug some encoding conversion routines,
11238
 
                     * else xmlSwitchEncoding will set to (default)
11239
 
                     * UTF8.
11240
 
                     */
11241
 
                    start[0] = RAW;
11242
 
                    start[1] = NXT(1);
11243
 
                    start[2] = NXT(2);
11244
 
                    start[3] = NXT(3);
11245
 
                    enc = xmlDetectCharEncoding(start, 4);
11246
 
                    xmlSwitchEncoding(ctxt, enc);
11247
 
                    break;
11248
 
                }
11249
 
 
11250
 
                if (avail < 2)
11251
 
                    goto done;
11252
 
                cur = ctxt->input->cur[0];
11253
 
                next = ctxt->input->cur[1];
11254
 
                if (cur == 0) {
11255
 
                    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
11256
 
                        ctxt->sax->setDocumentLocator(ctxt->userData,
11257
 
                                                      &xmlDefaultSAXLocator);
11258
 
                    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
11259
 
                    ctxt->instate = XML_PARSER_EOF;
11260
 
#ifdef DEBUG_PUSH
11261
 
                    xmlGenericError(xmlGenericErrorContext,
11262
 
                            "PP: entering EOF\n");
11263
 
#endif
11264
 
                    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
11265
 
                        ctxt->sax->endDocument(ctxt->userData);
11266
 
                    goto done;
11267
 
                }
11268
 
                if ((cur == '<') && (next == '?')) {
11269
 
                    /* PI or XML decl */
11270
 
                    if (avail < 5) return(ret);
11271
 
                    if ((!terminate) &&
11272
 
                        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
11273
 
                        return(ret);
11274
 
                    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
11275
 
                        ctxt->sax->setDocumentLocator(ctxt->userData,
11276
 
                                                      &xmlDefaultSAXLocator);
11277
 
                    if ((ctxt->input->cur[2] == 'x') &&
11278
 
                        (ctxt->input->cur[3] == 'm') &&
11279
 
                        (ctxt->input->cur[4] == 'l') &&
11280
 
                        (IS_BLANK_CH(ctxt->input->cur[5]))) {
11281
 
                        ret += 5;
11282
 
#ifdef DEBUG_PUSH
11283
 
                        xmlGenericError(xmlGenericErrorContext,
11284
 
                                "PP: Parsing XML Decl\n");
11285
 
#endif
11286
 
                        xmlParseXMLDecl(ctxt);
11287
 
                        if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
11288
 
                            /*
11289
 
                             * The XML REC instructs us to stop parsing right
11290
 
                             * here
11291
 
                             */
11292
 
                            ctxt->instate = XML_PARSER_EOF;
11293
 
                            return(0);
11294
 
                        }
11295
 
                        ctxt->standalone = ctxt->input->standalone;
11296
 
                        if ((ctxt->encoding == NULL) &&
11297
 
                            (ctxt->input->encoding != NULL))
11298
 
                            ctxt->encoding = xmlStrdup(ctxt->input->encoding);
11299
 
                        if ((ctxt->sax) && (ctxt->sax->startDocument) &&
11300
 
                            (!ctxt->disableSAX))
11301
 
                            ctxt->sax->startDocument(ctxt->userData);
11302
 
                        ctxt->instate = XML_PARSER_MISC;
11303
 
#ifdef DEBUG_PUSH
11304
 
                        xmlGenericError(xmlGenericErrorContext,
11305
 
                                "PP: entering MISC\n");
11306
 
#endif
11307
 
                    } else {
11308
 
                        ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
11309
 
                        if ((ctxt->sax) && (ctxt->sax->startDocument) &&
11310
 
                            (!ctxt->disableSAX))
11311
 
                            ctxt->sax->startDocument(ctxt->userData);
11312
 
                        ctxt->instate = XML_PARSER_MISC;
11313
 
#ifdef DEBUG_PUSH
11314
 
                        xmlGenericError(xmlGenericErrorContext,
11315
 
                                "PP: entering MISC\n");
11316
 
#endif
11317
 
                    }
11318
 
                } else {
11319
 
                    if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
11320
 
                        ctxt->sax->setDocumentLocator(ctxt->userData,
11321
 
                                                      &xmlDefaultSAXLocator);
11322
 
                    ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
11323
 
                    if (ctxt->version == NULL) {
11324
 
                        xmlErrMemory(ctxt, NULL);
11325
 
                        break;
11326
 
                    }
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
 
                break;
11337
 
            case XML_PARSER_START_TAG: {
11338
 
                const xmlChar *name;
11339
 
                const xmlChar *prefix = NULL;
11340
 
                const xmlChar *URI = NULL;
11341
 
                int nsNr = ctxt->nsNr;
11342
 
 
11343
 
                if ((avail < 2) && (ctxt->inputNr == 1))
11344
 
                    goto done;
11345
 
                cur = ctxt->input->cur[0];
11346
 
                if (cur != '<') {
11347
 
                    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
11348
 
                    ctxt->instate = XML_PARSER_EOF;
11349
 
                    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
11350
 
                        ctxt->sax->endDocument(ctxt->userData);
11351
 
                    goto done;
11352
 
                }
11353
 
                if (!terminate) {
11354
 
                    if (ctxt->progressive) {
11355
 
                        /* > can be found unescaped in attribute values */
11356
 
                        if ((lastgt == NULL) || (ctxt->input->cur >= lastgt))
11357
 
                            goto done;
11358
 
                    } else if (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0) {
11359
 
                        goto done;
11360
 
                    }
11361
 
                }
11362
 
                if (ctxt->spaceNr == 0)
11363
 
                    spacePush(ctxt, -1);
11364
 
                else if (*ctxt->space == -2)
11365
 
                    spacePush(ctxt, -1);
11366
 
                else
11367
 
                    spacePush(ctxt, *ctxt->space);
11368
 
#ifdef LIBXML_SAX1_ENABLED
11369
 
                if (ctxt->sax2)
11370
 
#endif /* LIBXML_SAX1_ENABLED */
11371
 
                    name = xmlParseStartTag2(ctxt, &prefix, &URI, &tlen);
11372
 
#ifdef LIBXML_SAX1_ENABLED
11373
 
                else
11374
 
                    name = xmlParseStartTag(ctxt);
11375
 
#endif /* LIBXML_SAX1_ENABLED */
11376
 
                if (ctxt->instate == XML_PARSER_EOF)
11377
 
                    goto done;
11378
 
                if (name == NULL) {
11379
 
                    spacePop(ctxt);
11380
 
                    ctxt->instate = XML_PARSER_EOF;
11381
 
                    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
11382
 
                        ctxt->sax->endDocument(ctxt->userData);
11383
 
                    goto done;
11384
 
                }
11385
 
#ifdef LIBXML_VALID_ENABLED
11386
 
                /*
11387
 
                 * [ VC: Root Element Type ]
11388
 
                 * The Name in the document type declaration must match
11389
 
                 * the element type of the root element.
11390
 
                 */
11391
 
                if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
11392
 
                    ctxt->node && (ctxt->node == ctxt->myDoc->children))
11393
 
                    ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
11394
 
#endif /* LIBXML_VALID_ENABLED */
11395
 
 
11396
 
                /*
11397
 
                 * Check for an Empty Element.
11398
 
                 */
11399
 
                if ((RAW == '/') && (NXT(1) == '>')) {
11400
 
                    SKIP(2);
11401
 
 
11402
 
                    if (ctxt->sax2) {
11403
 
                        if ((ctxt->sax != NULL) &&
11404
 
                            (ctxt->sax->endElementNs != NULL) &&
11405
 
                            (!ctxt->disableSAX))
11406
 
                            ctxt->sax->endElementNs(ctxt->userData, name,
11407
 
                                                    prefix, URI);
11408
 
                        if (ctxt->nsNr - nsNr > 0)
11409
 
                            nsPop(ctxt, ctxt->nsNr - nsNr);
11410
 
#ifdef LIBXML_SAX1_ENABLED
11411
 
                    } else {
11412
 
                        if ((ctxt->sax != NULL) &&
11413
 
                            (ctxt->sax->endElement != NULL) &&
11414
 
                            (!ctxt->disableSAX))
11415
 
                            ctxt->sax->endElement(ctxt->userData, name);
11416
 
#endif /* LIBXML_SAX1_ENABLED */
11417
 
                    }
11418
 
                    if (ctxt->instate == XML_PARSER_EOF)
11419
 
                        goto done;
11420
 
                    spacePop(ctxt);
11421
 
                    if (ctxt->nameNr == 0) {
11422
 
                        ctxt->instate = XML_PARSER_EPILOG;
11423
 
                    } else {
11424
 
                        ctxt->instate = XML_PARSER_CONTENT;
11425
 
                    }
11426
 
                    ctxt->progressive = 1;
11427
 
                    break;
11428
 
                }
11429
 
                if (RAW == '>') {
11430
 
                    NEXT;
11431
 
                } else {
11432
 
                    xmlFatalErrMsgStr(ctxt, XML_ERR_GT_REQUIRED,
11433
 
                                         "Couldn't find end of Start Tag %s\n",
11434
 
                                         name);
11435
 
                    nodePop(ctxt);
11436
 
                    spacePop(ctxt);
11437
 
                }
11438
 
                if (ctxt->sax2)
11439
 
                    nameNsPush(ctxt, name, prefix, URI, ctxt->nsNr - nsNr);
11440
 
#ifdef LIBXML_SAX1_ENABLED
11441
 
                else
11442
 
                    namePush(ctxt, name);
11443
 
#endif /* LIBXML_SAX1_ENABLED */
11444
 
 
11445
 
                ctxt->instate = XML_PARSER_CONTENT;
11446
 
                ctxt->progressive = 1;
11447
 
                break;
11448
 
            }
11449
 
            case XML_PARSER_CONTENT: {
11450
 
                const xmlChar *test;
11451
 
                unsigned int cons;
11452
 
                if ((avail < 2) && (ctxt->inputNr == 1))
11453
 
                    goto done;
11454
 
                cur = ctxt->input->cur[0];
11455
 
                next = ctxt->input->cur[1];
11456
 
 
11457
 
                test = CUR_PTR;
11458
 
                cons = ctxt->input->consumed;
11459
 
                if ((cur == '<') && (next == '/')) {
11460
 
                    ctxt->instate = XML_PARSER_END_TAG;
11461
 
                    break;
11462
 
                } else if ((cur == '<') && (next == '?')) {
11463
 
                    if ((!terminate) &&
11464
 
                        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0)) {
11465
 
                        ctxt->progressive = XML_PARSER_PI;
11466
 
                        goto done;
11467
 
                    }
11468
 
                    xmlParsePI(ctxt);
11469
 
                    ctxt->instate = XML_PARSER_CONTENT;
11470
 
                    ctxt->progressive = 1;
11471
 
                } else if ((cur == '<') && (next != '!')) {
11472
 
                    ctxt->instate = XML_PARSER_START_TAG;
11473
 
                    break;
11474
 
                } else if ((cur == '<') && (next == '!') &&
11475
 
                           (ctxt->input->cur[2] == '-') &&
11476
 
                           (ctxt->input->cur[3] == '-')) {
11477
 
                    int term;
11478
 
 
11479
 
                    if (avail < 4)
11480
 
                        goto done;
11481
 
                    ctxt->input->cur += 4;
11482
 
                    term = xmlParseLookupSequence(ctxt, '-', '-', '>');
11483
 
                    ctxt->input->cur -= 4;
11484
 
                    if ((!terminate) && (term < 0)) {
11485
 
                        ctxt->progressive = XML_PARSER_COMMENT;
11486
 
                        goto done;
11487
 
                    }
11488
 
                    xmlParseComment(ctxt);
11489
 
                    ctxt->instate = XML_PARSER_CONTENT;
11490
 
                    ctxt->progressive = 1;
11491
 
                } else if ((cur == '<') && (ctxt->input->cur[1] == '!') &&
11492
 
                    (ctxt->input->cur[2] == '[') &&
11493
 
                    (ctxt->input->cur[3] == 'C') &&
11494
 
                    (ctxt->input->cur[4] == 'D') &&
11495
 
                    (ctxt->input->cur[5] == 'A') &&
11496
 
                    (ctxt->input->cur[6] == 'T') &&
11497
 
                    (ctxt->input->cur[7] == 'A') &&
11498
 
                    (ctxt->input->cur[8] == '[')) {
11499
 
                    SKIP(9);
11500
 
                    ctxt->instate = XML_PARSER_CDATA_SECTION;
11501
 
                    break;
11502
 
                } else if ((cur == '<') && (next == '!') &&
11503
 
                           (avail < 9)) {
11504
 
                    goto done;
11505
 
                } else if (cur == '&') {
11506
 
                    if ((!terminate) &&
11507
 
                        (xmlParseLookupSequence(ctxt, ';', 0, 0) < 0))
11508
 
                        goto done;
11509
 
                    xmlParseReference(ctxt);
11510
 
                } else {
11511
 
                    /* TODO Avoid the extra copy, handle directly !!! */
11512
 
                    /*
11513
 
                     * Goal of the following test is:
11514
 
                     *  - minimize calls to the SAX 'character' callback
11515
 
                     *    when they are mergeable
11516
 
                     *  - handle an problem for isBlank when we only parse
11517
 
                     *    a sequence of blank chars and the next one is
11518
 
                     *    not available to check against '<' presence.
11519
 
                     *  - tries to homogenize the differences in SAX
11520
 
                     *    callbacks between the push and pull versions
11521
 
                     *    of the parser.
11522
 
                     */
11523
 
                    if ((ctxt->inputNr == 1) &&
11524
 
                        (avail < XML_PARSER_BIG_BUFFER_SIZE)) {
11525
 
                        if (!terminate) {
11526
 
                            if (ctxt->progressive) {
11527
 
                                if ((lastlt == NULL) ||
11528
 
                                    (ctxt->input->cur > lastlt))
11529
 
                                    goto done;
11530
 
                            } else if (xmlParseLookupSequence(ctxt,
11531
 
                                                              '<', 0, 0) < 0) {
11532
 
                                goto done;
11533
 
                            }
11534
 
                        }
11535
 
                    }
11536
 
                    ctxt->checkIndex = 0;
11537
 
                    xmlParseCharData(ctxt, 0);
11538
 
                }
11539
 
                /*
11540
 
                 * Pop-up of finished entities.
11541
 
                 */
11542
 
                while ((RAW == 0) && (ctxt->inputNr > 1))
11543
 
                    xmlPopInput(ctxt);
11544
 
                if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
11545
 
                    xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
11546
 
                                "detected an error in element content\n");
11547
 
                    ctxt->instate = XML_PARSER_EOF;
11548
 
                    break;
11549
 
                }
11550
 
                break;
11551
 
            }
11552
 
            case XML_PARSER_END_TAG:
11553
 
                if (avail < 2)
11554
 
                    goto done;
11555
 
                if (!terminate) {
11556
 
                    if (ctxt->progressive) {
11557
 
                        /* > can be found unescaped in attribute values */
11558
 
                        if ((lastgt == NULL) || (ctxt->input->cur >= lastgt))
11559
 
                            goto done;
11560
 
                    } else if (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0) {
11561
 
                        goto done;
11562
 
                    }
11563
 
                }
11564
 
                if (ctxt->sax2) {
11565
 
                    xmlParseEndTag2(ctxt,
11566
 
                           (void *) ctxt->pushTab[ctxt->nameNr * 3 - 3],
11567
 
                           (void *) ctxt->pushTab[ctxt->nameNr * 3 - 2], 0,
11568
 
                       (int) (long) ctxt->pushTab[ctxt->nameNr * 3 - 1], 0);
11569
 
                    nameNsPop(ctxt);
11570
 
                }
11571
 
#ifdef LIBXML_SAX1_ENABLED
11572
 
                  else
11573
 
                    xmlParseEndTag1(ctxt, 0);
11574
 
#endif /* LIBXML_SAX1_ENABLED */
11575
 
                if (ctxt->instate == XML_PARSER_EOF) {
11576
 
                    /* Nothing */
11577
 
                } else if (ctxt->nameNr == 0) {
11578
 
                    ctxt->instate = XML_PARSER_EPILOG;
11579
 
                } else {
11580
 
                    ctxt->instate = XML_PARSER_CONTENT;
11581
 
                }
11582
 
                break;
11583
 
            case XML_PARSER_CDATA_SECTION: {
11584
 
                /*
11585
 
                 * The Push mode need to have the SAX callback for
11586
 
                 * cdataBlock merge back contiguous callbacks.
11587
 
                 */
11588
 
                int base;
11589
 
 
11590
 
                base = xmlParseLookupSequence(ctxt, ']', ']', '>');
11591
 
                if (base < 0) {
11592
 
                    if (avail >= XML_PARSER_BIG_BUFFER_SIZE + 2) {
11593
 
                        int tmp;
11594
 
 
11595
 
                        tmp = xmlCheckCdataPush(ctxt->input->cur,
11596
 
                                                XML_PARSER_BIG_BUFFER_SIZE);
11597
 
                        if (tmp < 0) {
11598
 
                            tmp = -tmp;
11599
 
                            ctxt->input->cur += tmp;
11600
 
                            goto encoding_error;
11601
 
                        }
11602
 
                        if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
11603
 
                            if (ctxt->sax->cdataBlock != NULL)
11604
 
                                ctxt->sax->cdataBlock(ctxt->userData,
11605
 
                                                      ctxt->input->cur, tmp);
11606
 
                            else if (ctxt->sax->characters != NULL)
11607
 
                                ctxt->sax->characters(ctxt->userData,
11608
 
                                                      ctxt->input->cur, tmp);
11609
 
                        }
11610
 
                        if (ctxt->instate == XML_PARSER_EOF)
11611
 
                            goto done;
11612
 
                        SKIPL(tmp);
11613
 
                        ctxt->checkIndex = 0;
11614
 
                    }
11615
 
                    goto done;
11616
 
                } else {
11617
 
                    int tmp;
11618
 
 
11619
 
                    tmp = xmlCheckCdataPush(ctxt->input->cur, base);
11620
 
                    if ((tmp < 0) || (tmp != base)) {
11621
 
                        tmp = -tmp;
11622
 
                        ctxt->input->cur += tmp;
11623
 
                        goto encoding_error;
11624
 
                    }
11625
 
                    if ((ctxt->sax != NULL) && (base == 0) &&
11626
 
                        (ctxt->sax->cdataBlock != NULL) &&
11627
 
                        (!ctxt->disableSAX)) {
11628
 
                        /*
11629
 
                         * Special case to provide identical behaviour
11630
 
                         * between pull and push parsers on enpty CDATA
11631
 
                         * sections
11632
 
                         */
11633
 
                         if ((ctxt->input->cur - ctxt->input->base >= 9) &&
11634
 
                             (!strncmp((const char *)&ctxt->input->cur[-9],
11635
 
                                       "<![CDATA[", 9)))
11636
 
                             ctxt->sax->cdataBlock(ctxt->userData,
11637
 
                                                   BAD_CAST "", 0);
11638
 
                    } else if ((ctxt->sax != NULL) && (base > 0) &&
11639
 
                        (!ctxt->disableSAX)) {
11640
 
                        if (ctxt->sax->cdataBlock != NULL)
11641
 
                            ctxt->sax->cdataBlock(ctxt->userData,
11642
 
                                                  ctxt->input->cur, base);
11643
 
                        else if (ctxt->sax->characters != NULL)
11644
 
                            ctxt->sax->characters(ctxt->userData,
11645
 
                                                  ctxt->input->cur, base);
11646
 
                    }
11647
 
                    if (ctxt->instate == XML_PARSER_EOF)
11648
 
                        goto done;
11649
 
                    SKIPL(base + 3);
11650
 
                    ctxt->checkIndex = 0;
11651
 
                    ctxt->instate = XML_PARSER_CONTENT;
11652
 
#ifdef DEBUG_PUSH
11653
 
                    xmlGenericError(xmlGenericErrorContext,
11654
 
                            "PP: entering CONTENT\n");
11655
 
#endif
11656
 
                }
11657
 
                break;
11658
 
            }
11659
 
            case XML_PARSER_MISC:
11660
 
                SKIP_BLANKS;
11661
 
                if (ctxt->input->buf == NULL)
11662
 
                    avail = ctxt->input->length -
11663
 
                            (ctxt->input->cur - ctxt->input->base);
11664
 
                else
11665
 
                    avail = xmlBufUse(ctxt->input->buf->buffer) -
11666
 
                            (ctxt->input->cur - ctxt->input->base);
11667
 
                if (avail < 2)
11668
 
                    goto done;
11669
 
                cur = ctxt->input->cur[0];
11670
 
                next = ctxt->input->cur[1];
11671
 
                if ((cur == '<') && (next == '?')) {
11672
 
                    if ((!terminate) &&
11673
 
                        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0)) {
11674
 
                        ctxt->progressive = XML_PARSER_PI;
11675
 
                        goto done;
11676
 
                    }
11677
 
#ifdef DEBUG_PUSH
11678
 
                    xmlGenericError(xmlGenericErrorContext,
11679
 
                            "PP: Parsing PI\n");
11680
 
#endif
11681
 
                    xmlParsePI(ctxt);
11682
 
                    if (ctxt->instate == XML_PARSER_EOF)
11683
 
                        goto done;
11684
 
                    ctxt->instate = XML_PARSER_MISC;
11685
 
                    ctxt->progressive = 1;
11686
 
                    ctxt->checkIndex = 0;
11687
 
                } else if ((cur == '<') && (next == '!') &&
11688
 
                    (ctxt->input->cur[2] == '-') &&
11689
 
                    (ctxt->input->cur[3] == '-')) {
11690
 
                    if ((!terminate) &&
11691
 
                        (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0)) {
11692
 
                        ctxt->progressive = XML_PARSER_COMMENT;
11693
 
                        goto done;
11694
 
                    }
11695
 
#ifdef DEBUG_PUSH
11696
 
                    xmlGenericError(xmlGenericErrorContext,
11697
 
                            "PP: Parsing Comment\n");
11698
 
#endif
11699
 
                    xmlParseComment(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] == 'D') &&
11707
 
                    (ctxt->input->cur[3] == 'O') &&
11708
 
                    (ctxt->input->cur[4] == 'C') &&
11709
 
                    (ctxt->input->cur[5] == 'T') &&
11710
 
                    (ctxt->input->cur[6] == 'Y') &&
11711
 
                    (ctxt->input->cur[7] == 'P') &&
11712
 
                    (ctxt->input->cur[8] == 'E')) {
11713
 
                    if ((!terminate) &&
11714
 
                        (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0)) {
11715
 
                        ctxt->progressive = XML_PARSER_DTD;
11716
 
                        goto done;
11717
 
                    }
11718
 
#ifdef DEBUG_PUSH
11719
 
                    xmlGenericError(xmlGenericErrorContext,
11720
 
                            "PP: Parsing internal subset\n");
11721
 
#endif
11722
 
                    ctxt->inSubset = 1;
11723
 
                    ctxt->progressive = 0;
11724
 
                    ctxt->checkIndex = 0;
11725
 
                    xmlParseDocTypeDecl(ctxt);
11726
 
                    if (ctxt->instate == XML_PARSER_EOF)
11727
 
                        goto done;
11728
 
                    if (RAW == '[') {
11729
 
                        ctxt->instate = XML_PARSER_DTD;
11730
 
#ifdef DEBUG_PUSH
11731
 
                        xmlGenericError(xmlGenericErrorContext,
11732
 
                                "PP: entering DTD\n");
11733
 
#endif
11734
 
                    } else {
11735
 
                        /*
11736
 
                         * Create and update the external subset.
11737
 
                         */
11738
 
                        ctxt->inSubset = 2;
11739
 
                        if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
11740
 
                            (ctxt->sax->externalSubset != NULL))
11741
 
                            ctxt->sax->externalSubset(ctxt->userData,
11742
 
                                    ctxt->intSubName, ctxt->extSubSystem,
11743
 
                                    ctxt->extSubURI);
11744
 
                        ctxt->inSubset = 0;
11745
 
                        xmlCleanSpecialAttr(ctxt);
11746
 
                        ctxt->instate = XML_PARSER_PROLOG;
11747
 
#ifdef DEBUG_PUSH
11748
 
                        xmlGenericError(xmlGenericErrorContext,
11749
 
                                "PP: entering PROLOG\n");
11750
 
#endif
11751
 
                    }
11752
 
                } else if ((cur == '<') && (next == '!') &&
11753
 
                           (avail < 9)) {
11754
 
                    goto done;
11755
 
                } else {
11756
 
                    ctxt->instate = XML_PARSER_START_TAG;
11757
 
                    ctxt->progressive = XML_PARSER_START_TAG;
11758
 
                    xmlParseGetLasts(ctxt, &lastlt, &lastgt);
11759
 
#ifdef DEBUG_PUSH
11760
 
                    xmlGenericError(xmlGenericErrorContext,
11761
 
                            "PP: entering START_TAG\n");
11762
 
#endif
11763
 
                }
11764
 
                break;
11765
 
            case XML_PARSER_PROLOG:
11766
 
                SKIP_BLANKS;
11767
 
                if (ctxt->input->buf == NULL)
11768
 
                    avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
11769
 
                else
11770
 
                    avail = xmlBufUse(ctxt->input->buf->buffer) -
11771
 
                            (ctxt->input->cur - ctxt->input->base);
11772
 
                if (avail < 2)
11773
 
                    goto done;
11774
 
                cur = ctxt->input->cur[0];
11775
 
                next = ctxt->input->cur[1];
11776
 
                if ((cur == '<') && (next == '?')) {
11777
 
                    if ((!terminate) &&
11778
 
                        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0)) {
11779
 
                        ctxt->progressive = XML_PARSER_PI;
11780
 
                        goto done;
11781
 
                    }
11782
 
#ifdef DEBUG_PUSH
11783
 
                    xmlGenericError(xmlGenericErrorContext,
11784
 
                            "PP: Parsing PI\n");
11785
 
#endif
11786
 
                    xmlParsePI(ctxt);
11787
 
                    if (ctxt->instate == XML_PARSER_EOF)
11788
 
                        goto done;
11789
 
                    ctxt->instate = XML_PARSER_PROLOG;
11790
 
                    ctxt->progressive = 1;
11791
 
                } else if ((cur == '<') && (next == '!') &&
11792
 
                    (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
11793
 
                    if ((!terminate) &&
11794
 
                        (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0)) {
11795
 
                        ctxt->progressive = XML_PARSER_COMMENT;
11796
 
                        goto done;
11797
 
                    }
11798
 
#ifdef DEBUG_PUSH
11799
 
                    xmlGenericError(xmlGenericErrorContext,
11800
 
                            "PP: Parsing Comment\n");
11801
 
#endif
11802
 
                    xmlParseComment(ctxt);
11803
 
                    if (ctxt->instate == XML_PARSER_EOF)
11804
 
                        goto done;
11805
 
                    ctxt->instate = XML_PARSER_PROLOG;
11806
 
                    ctxt->progressive = 1;
11807
 
                } else if ((cur == '<') && (next == '!') &&
11808
 
                           (avail < 4)) {
11809
 
                    goto done;
11810
 
                } else {
11811
 
                    ctxt->instate = XML_PARSER_START_TAG;
11812
 
                    if (ctxt->progressive == 0)
11813
 
                        ctxt->progressive = XML_PARSER_START_TAG;
11814
 
                    xmlParseGetLasts(ctxt, &lastlt, &lastgt);
11815
 
#ifdef DEBUG_PUSH
11816
 
                    xmlGenericError(xmlGenericErrorContext,
11817
 
                            "PP: entering START_TAG\n");
11818
 
#endif
11819
 
                }
11820
 
                break;
11821
 
            case XML_PARSER_EPILOG:
11822
 
                SKIP_BLANKS;
11823
 
                if (ctxt->input->buf == NULL)
11824
 
                    avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
11825
 
                else
11826
 
                    avail = xmlBufUse(ctxt->input->buf->buffer) -
11827
 
                            (ctxt->input->cur - ctxt->input->base);
11828
 
                if (avail < 2)
11829
 
                    goto done;
11830
 
                cur = ctxt->input->cur[0];
11831
 
                next = ctxt->input->cur[1];
11832
 
                if ((cur == '<') && (next == '?')) {
11833
 
                    if ((!terminate) &&
11834
 
                        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0)) {
11835
 
                        ctxt->progressive = XML_PARSER_PI;
11836
 
                        goto done;
11837
 
                    }
11838
 
#ifdef DEBUG_PUSH
11839
 
                    xmlGenericError(xmlGenericErrorContext,
11840
 
                            "PP: Parsing PI\n");
11841
 
#endif
11842
 
                    xmlParsePI(ctxt);
11843
 
                    if (ctxt->instate == XML_PARSER_EOF)
11844
 
                        goto done;
11845
 
                    ctxt->instate = XML_PARSER_EPILOG;
11846
 
                    ctxt->progressive = 1;
11847
 
                } else if ((cur == '<') && (next == '!') &&
11848
 
                    (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
11849
 
                    if ((!terminate) &&
11850
 
                        (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0)) {
11851
 
                        ctxt->progressive = XML_PARSER_COMMENT;
11852
 
                        goto done;
11853
 
                    }
11854
 
#ifdef DEBUG_PUSH
11855
 
                    xmlGenericError(xmlGenericErrorContext,
11856
 
                            "PP: Parsing Comment\n");
11857
 
#endif
11858
 
                    xmlParseComment(ctxt);
11859
 
                    if (ctxt->instate == XML_PARSER_EOF)
11860
 
                        goto done;
11861
 
                    ctxt->instate = XML_PARSER_EPILOG;
11862
 
                    ctxt->progressive = 1;
11863
 
                } else if ((cur == '<') && (next == '!') &&
11864
 
                           (avail < 4)) {
11865
 
                    goto done;
11866
 
                } else {
11867
 
                    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
11868
 
                    ctxt->instate = XML_PARSER_EOF;
11869
 
#ifdef DEBUG_PUSH
11870
 
                    xmlGenericError(xmlGenericErrorContext,
11871
 
                            "PP: entering EOF\n");
11872
 
#endif
11873
 
                    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
11874
 
                        ctxt->sax->endDocument(ctxt->userData);
11875
 
                    goto done;
11876
 
                }
11877
 
                break;
11878
 
            case XML_PARSER_DTD: {
11879
 
                /*
11880
 
                 * Sorry but progressive parsing of the internal subset
11881
 
                 * is not expected to be supported. We first check that
11882
 
                 * the full content of the internal subset is available and
11883
 
                 * the parsing is launched only at that point.
11884
 
                 * Internal subset ends up with "']' S? '>'" in an unescaped
11885
 
                 * section and not in a ']]>' sequence which are conditional
11886
 
                 * sections (whoever argued to keep that crap in XML deserve
11887
 
                 * a place in hell !).
11888
 
                 */
11889
 
                int base, i;
11890
 
                xmlChar *buf;
11891
 
                xmlChar quote = 0;
11892
 
                size_t use;
11893
 
 
11894
 
                base = ctxt->input->cur - ctxt->input->base;
11895
 
                if (base < 0) return(0);
11896
 
                if (ctxt->checkIndex > base)
11897
 
                    base = ctxt->checkIndex;
11898
 
                buf = xmlBufContent(ctxt->input->buf->buffer);
11899
 
                use = xmlBufUse(ctxt->input->buf->buffer);
11900
 
                for (;(unsigned int) base < use; base++) {
11901
 
                    if (quote != 0) {
11902
 
                        if (buf[base] == quote)
11903
 
                            quote = 0;
11904
 
                        continue;
11905
 
                    }
11906
 
                    if ((quote == 0) && (buf[base] == '<')) {
11907
 
                        int found  = 0;
11908
 
                        /* special handling of comments */
11909
 
                        if (((unsigned int) base + 4 < use) &&
11910
 
                            (buf[base + 1] == '!') &&
11911
 
                            (buf[base + 2] == '-') &&
11912
 
                            (buf[base + 3] == '-')) {
11913
 
                            for (;(unsigned int) base + 3 < use; base++) {
11914
 
                                if ((buf[base] == '-') &&
11915
 
                                    (buf[base + 1] == '-') &&
11916
 
                                    (buf[base + 2] == '>')) {
11917
 
                                    found = 1;
11918
 
                                    base += 2;
11919
 
                                    break;
11920
 
                                }
11921
 
                            }
11922
 
                            if (!found) {
11923
 
#if 0
11924
 
                                fprintf(stderr, "unfinished comment\n");
11925
 
#endif
11926
 
                                break; /* for */
11927
 
                            }
11928
 
                            continue;
11929
 
                        }
11930
 
                    }
11931
 
                    if (buf[base] == '"') {
11932
 
                        quote = '"';
11933
 
                        continue;
11934
 
                    }
11935
 
                    if (buf[base] == '\'') {
11936
 
                        quote = '\'';
11937
 
                        continue;
11938
 
                    }
11939
 
                    if (buf[base] == ']') {
11940
 
#if 0
11941
 
                        fprintf(stderr, "%c%c%c%c: ", buf[base],
11942
 
                                buf[base + 1], buf[base + 2], buf[base + 3]);
11943
 
#endif
11944
 
                        if ((unsigned int) base +1 >= use)
11945
 
                            break;
11946
 
                        if (buf[base + 1] == ']') {
11947
 
                            /* conditional crap, skip both ']' ! */
11948
 
                            base++;
11949
 
                            continue;
11950
 
                        }
11951
 
                        for (i = 1; (unsigned int) base + i < use; i++) {
11952
 
                            if (buf[base + i] == '>') {
11953
 
#if 0
11954
 
                                fprintf(stderr, "found\n");
11955
 
#endif
11956
 
                                goto found_end_int_subset;
11957
 
                            }
11958
 
                            if (!IS_BLANK_CH(buf[base + i])) {
11959
 
#if 0
11960
 
                                fprintf(stderr, "not found\n");
11961
 
#endif
11962
 
                                goto not_end_of_int_subset;
11963
 
                            }
11964
 
                        }
11965
 
#if 0
11966
 
                        fprintf(stderr, "end of stream\n");
11967
 
#endif
11968
 
                        break;
11969
 
 
11970
 
                    }
11971
 
not_end_of_int_subset:
11972
 
                    continue; /* for */
11973
 
                }
11974
 
                /*
11975
 
                 * We didn't found the end of the Internal subset
11976
 
                 */
11977
 
                if (quote == 0)
11978
 
                    ctxt->checkIndex = base;
11979
 
                else
11980
 
                    ctxt->checkIndex = 0;
11981
 
#ifdef DEBUG_PUSH
11982
 
                if (next == 0)
11983
 
                    xmlGenericError(xmlGenericErrorContext,
11984
 
                            "PP: lookup of int subset end filed\n");
11985
 
#endif
11986
 
                goto done;
11987
 
 
11988
 
found_end_int_subset:
11989
 
                ctxt->checkIndex = 0;
11990
 
                xmlParseInternalSubset(ctxt);
11991
 
                if (ctxt->instate == XML_PARSER_EOF)
11992
 
                    goto done;
11993
 
                ctxt->inSubset = 2;
11994
 
                if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
11995
 
                    (ctxt->sax->externalSubset != NULL))
11996
 
                    ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
11997
 
                            ctxt->extSubSystem, ctxt->extSubURI);
11998
 
                ctxt->inSubset = 0;
11999
 
                xmlCleanSpecialAttr(ctxt);
12000
 
                if (ctxt->instate == XML_PARSER_EOF)
12001
 
                    goto done;
12002
 
                ctxt->instate = XML_PARSER_PROLOG;
12003
 
                ctxt->checkIndex = 0;
12004
 
#ifdef DEBUG_PUSH
12005
 
                xmlGenericError(xmlGenericErrorContext,
12006
 
                        "PP: entering PROLOG\n");
12007
 
#endif
12008
 
                break;
12009
 
            }
12010
 
            case XML_PARSER_COMMENT:
12011
 
                xmlGenericError(xmlGenericErrorContext,
12012
 
                        "PP: internal error, state == COMMENT\n");
12013
 
                ctxt->instate = XML_PARSER_CONTENT;
12014
 
#ifdef DEBUG_PUSH
12015
 
                xmlGenericError(xmlGenericErrorContext,
12016
 
                        "PP: entering CONTENT\n");
12017
 
#endif
12018
 
                break;
12019
 
            case XML_PARSER_IGNORE:
12020
 
                xmlGenericError(xmlGenericErrorContext,
12021
 
                        "PP: internal error, state == IGNORE");
12022
 
                ctxt->instate = XML_PARSER_DTD;
12023
 
#ifdef DEBUG_PUSH
12024
 
                xmlGenericError(xmlGenericErrorContext,
12025
 
                        "PP: entering DTD\n");
12026
 
#endif
12027
 
                break;
12028
 
            case XML_PARSER_PI:
12029
 
                xmlGenericError(xmlGenericErrorContext,
12030
 
                        "PP: internal error, state == PI\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_ENTITY_DECL:
12038
 
                xmlGenericError(xmlGenericErrorContext,
12039
 
                        "PP: internal error, state == ENTITY_DECL\n");
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_ENTITY_VALUE:
12047
 
                xmlGenericError(xmlGenericErrorContext,
12048
 
                        "PP: internal error, state == ENTITY_VALUE\n");
12049
 
                ctxt->instate = XML_PARSER_CONTENT;
12050
 
#ifdef DEBUG_PUSH
12051
 
                xmlGenericError(xmlGenericErrorContext,
12052
 
                        "PP: entering DTD\n");
12053
 
#endif
12054
 
                break;
12055
 
            case XML_PARSER_ATTRIBUTE_VALUE:
12056
 
                xmlGenericError(xmlGenericErrorContext,
12057
 
                        "PP: internal error, state == ATTRIBUTE_VALUE\n");
12058
 
                ctxt->instate = XML_PARSER_START_TAG;
12059
 
#ifdef DEBUG_PUSH
12060
 
                xmlGenericError(xmlGenericErrorContext,
12061
 
                        "PP: entering START_TAG\n");
12062
 
#endif
12063
 
                break;
12064
 
            case XML_PARSER_SYSTEM_LITERAL:
12065
 
                xmlGenericError(xmlGenericErrorContext,
12066
 
                        "PP: internal error, state == SYSTEM_LITERAL\n");
12067
 
                ctxt->instate = XML_PARSER_START_TAG;
12068
 
#ifdef DEBUG_PUSH
12069
 
                xmlGenericError(xmlGenericErrorContext,
12070
 
                        "PP: entering START_TAG\n");
12071
 
#endif
12072
 
                break;
12073
 
            case XML_PARSER_PUBLIC_LITERAL:
12074
 
                xmlGenericError(xmlGenericErrorContext,
12075
 
                        "PP: internal error, state == PUBLIC_LITERAL\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
 
        }
12083
 
    }
12084
 
done:
12085
 
#ifdef DEBUG_PUSH
12086
 
    xmlGenericError(xmlGenericErrorContext, "PP: done %d\n", ret);
12087
 
#endif
12088
 
    return(ret);
12089
 
encoding_error:
12090
 
    {
12091
 
        char buffer[150];
12092
 
 
12093
 
        snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
12094
 
                        ctxt->input->cur[0], ctxt->input->cur[1],
12095
 
                        ctxt->input->cur[2], ctxt->input->cur[3]);
12096
 
        __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
12097
 
                     "Input is not proper UTF-8, indicate encoding !\n%s",
12098
 
                     BAD_CAST buffer, NULL);
12099
 
    }
12100
 
    return(0);
12101
 
}
12102
 
 
12103
 
/**
12104
 
 * xmlParseCheckTransition:
12105
 
 * @ctxt:  an XML parser context
12106
 
 * @chunk:  a char array
12107
 
 * @size:  the size in byte of the chunk
12108
 
 *
12109
 
 * Check depending on the current parser state if the chunk given must be
12110
 
 * processed immediately or one need more data to advance on parsing.
12111
 
 *
12112
 
 * Returns -1 in case of error, 0 if the push is not needed and 1 if needed
12113
 
 */
12114
 
static int
12115
 
xmlParseCheckTransition(xmlParserCtxtPtr ctxt, const char *chunk, int size) {
12116
 
    if ((ctxt == NULL) || (chunk == NULL) || (size < 0))
12117
 
        return(-1);
12118
 
    if (ctxt->instate == XML_PARSER_START_TAG) {
12119
 
        if (memchr(chunk, '>', size) != NULL)
12120
 
            return(1);
12121
 
        return(0);
12122
 
    }
12123
 
    if (ctxt->progressive == XML_PARSER_COMMENT) {
12124
 
        if (memchr(chunk, '>', size) != NULL)
12125
 
            return(1);
12126
 
        return(0);
12127
 
    }
12128
 
    if (ctxt->instate == XML_PARSER_CDATA_SECTION) {
12129
 
        if (memchr(chunk, '>', size) != NULL)
12130
 
            return(1);
12131
 
        return(0);
12132
 
    }
12133
 
    if (ctxt->progressive == XML_PARSER_PI) {
12134
 
        if (memchr(chunk, '>', size) != NULL)
12135
 
            return(1);
12136
 
        return(0);
12137
 
    }
12138
 
    if (ctxt->instate == XML_PARSER_END_TAG) {
12139
 
        if (memchr(chunk, '>', size) != NULL)
12140
 
            return(1);
12141
 
        return(0);
12142
 
    }
12143
 
    if ((ctxt->progressive == XML_PARSER_DTD) ||
12144
 
        (ctxt->instate == XML_PARSER_DTD)) {
12145
 
        if (memchr(chunk, '>', size) != NULL)
12146
 
            return(1);
12147
 
        return(0);
12148
 
    }
12149
 
    return(1);
12150
 
}
12151
 
 
12152
 
/**
12153
 
 * xmlParseChunk:
12154
 
 * @ctxt:  an XML parser context
12155
 
 * @chunk:  an char array
12156
 
 * @size:  the size in byte of the chunk
12157
 
 * @terminate:  last chunk indicator
12158
 
 *
12159
 
 * Parse a Chunk of memory
12160
 
 *
12161
 
 * Returns zero if no error, the xmlParserErrors otherwise.
12162
 
 */
12163
 
int
12164
 
xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
12165
 
              int terminate) {
12166
 
    int end_in_lf = 0;
12167
 
    int remain = 0;
12168
 
    size_t old_avail = 0;
12169
 
    size_t avail = 0;
12170
 
 
12171
 
    if (ctxt == NULL)
12172
 
        return(XML_ERR_INTERNAL_ERROR);
12173
 
    if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
12174
 
        return(ctxt->errNo);
12175
 
    if (ctxt->instate == XML_PARSER_EOF)
12176
 
        return(-1);
12177
 
    if (ctxt->instate == XML_PARSER_START)
12178
 
        xmlDetectSAX2(ctxt);
12179
 
    if ((size > 0) && (chunk != NULL) && (!terminate) &&
12180
 
        (chunk[size - 1] == '\r')) {
12181
 
        end_in_lf = 1;
12182
 
        size--;
12183
 
    }
12184
 
 
12185
 
xmldecl_done:
12186
 
 
12187
 
    if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
12188
 
        (ctxt->input->buf != NULL) && (ctxt->instate != XML_PARSER_EOF))  {
12189
 
        size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer, ctxt->input);
12190
 
        size_t cur = ctxt->input->cur - ctxt->input->base;
12191
 
        int res;
12192
 
 
12193
 
        old_avail = xmlBufUse(ctxt->input->buf->buffer);
12194
 
        /*
12195
 
         * Specific handling if we autodetected an encoding, we should not
12196
 
         * push more than the first line ... which depend on the encoding
12197
 
         * And only push the rest once the final encoding was detected
12198
 
         */
12199
 
        if ((ctxt->instate == XML_PARSER_START) && (ctxt->input != NULL) &&
12200
 
            (ctxt->input->buf != NULL) && (ctxt->input->buf->encoder != NULL)) {
12201
 
            unsigned int len = 45;
12202
 
 
12203
 
            if ((xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
12204
 
                               BAD_CAST "UTF-16")) ||
12205
 
                (xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
12206
 
                               BAD_CAST "UTF16")))
12207
 
                len = 90;
12208
 
            else if ((xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
12209
 
                                    BAD_CAST "UCS-4")) ||
12210
 
                     (xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
12211
 
                                    BAD_CAST "UCS4")))
12212
 
                len = 180;
12213
 
 
12214
 
            if (ctxt->input->buf->rawconsumed < len)
12215
 
                len -= ctxt->input->buf->rawconsumed;
12216
 
 
12217
 
            /*
12218
 
             * Change size for reading the initial declaration only
12219
 
             * if size is greater than len. Otherwise, memmove in xmlBufferAdd
12220
 
             * will blindly copy extra bytes from memory.
12221
 
             */
12222
 
            if ((unsigned int) size > len) {
12223
 
                remain = size - len;
12224
 
                size = len;
12225
 
            } else {
12226
 
                remain = 0;
12227
 
            }
12228
 
        }
12229
 
        res = xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
12230
 
        if (res < 0) {
12231
 
            ctxt->errNo = XML_PARSER_EOF;
12232
 
            ctxt->disableSAX = 1;
12233
 
            return (XML_PARSER_EOF);
12234
 
        }
12235
 
        xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur);
12236
 
#ifdef DEBUG_PUSH
12237
 
        xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
12238
 
#endif
12239
 
 
12240
 
    } else if (ctxt->instate != XML_PARSER_EOF) {
12241
 
        if ((ctxt->input != NULL) && ctxt->input->buf != NULL) {
12242
 
            xmlParserInputBufferPtr in = ctxt->input->buf;
12243
 
            if ((in->encoder != NULL) && (in->buffer != NULL) &&
12244
 
                    (in->raw != NULL)) {
12245
 
                int nbchars;
12246
 
                size_t base = xmlBufGetInputBase(in->buffer, ctxt->input);
12247
 
                size_t current = ctxt->input->cur - ctxt->input->base;
12248
 
 
12249
 
                nbchars = xmlCharEncInput(in, terminate);
12250
 
                if (nbchars < 0) {
12251
 
                    /* TODO 2.6.0 */
12252
 
                    xmlGenericError(xmlGenericErrorContext,
12253
 
                                    "xmlParseChunk: encoder error\n");
12254
 
                    return(XML_ERR_INVALID_ENCODING);
12255
 
                }
12256
 
                xmlBufSetInputBaseCur(in->buffer, ctxt->input, base, current);
12257
 
            }
12258
 
        }
12259
 
    }
12260
 
    if (remain != 0) {
12261
 
        xmlParseTryOrFinish(ctxt, 0);
12262
 
    } else {
12263
 
        if ((ctxt->input != NULL) && (ctxt->input->buf != NULL))
12264
 
            avail = xmlBufUse(ctxt->input->buf->buffer);
12265
 
        /*
12266
 
         * Depending on the current state it may not be such
12267
 
         * a good idea to try parsing if there is nothing in the chunk
12268
 
         * which would be worth doing a parser state transition and we
12269
 
         * need to wait for more data
12270
 
         */
12271
 
        if ((terminate) || (avail > XML_MAX_TEXT_LENGTH) ||
12272
 
            (old_avail == 0) || (avail == 0) ||
12273
 
            (xmlParseCheckTransition(ctxt,
12274
 
                       (const char *)&ctxt->input->base[old_avail],
12275
 
                                     avail - old_avail)))
12276
 
            xmlParseTryOrFinish(ctxt, terminate);
12277
 
    }
12278
 
    if (ctxt->instate == XML_PARSER_EOF)
12279
 
        return(ctxt->errNo);
12280
 
 
12281
 
    if ((ctxt->input != NULL) &&
12282
 
         (((ctxt->input->end - ctxt->input->cur) > XML_MAX_LOOKUP_LIMIT) ||
12283
 
         ((ctxt->input->cur - ctxt->input->base) > XML_MAX_LOOKUP_LIMIT)) &&
12284
 
        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
12285
 
        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "Huge input lookup");
12286
 
        ctxt->instate = XML_PARSER_EOF;
12287
 
    }
12288
 
    if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
12289
 
        return(ctxt->errNo);
12290
 
 
12291
 
    if (remain != 0) {
12292
 
        chunk += size;
12293
 
        size = remain;
12294
 
        remain = 0;
12295
 
        goto xmldecl_done;
12296
 
    }
12297
 
    if ((end_in_lf == 1) && (ctxt->input != NULL) &&
12298
 
        (ctxt->input->buf != NULL)) {
12299
 
        size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer,
12300
 
                                         ctxt->input);
12301
 
        size_t current = ctxt->input->cur - ctxt->input->base;
12302
 
 
12303
 
        xmlParserInputBufferPush(ctxt->input->buf, 1, "\r");
12304
 
 
12305
 
        xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input,
12306
 
                              base, current);
12307
 
    }
12308
 
    if (terminate) {
12309
 
        /*
12310
 
         * Check for termination
12311
 
         */
12312
 
        int cur_avail = 0;
12313
 
 
12314
 
        if (ctxt->input != NULL) {
12315
 
            if (ctxt->input->buf == NULL)
12316
 
                cur_avail = ctxt->input->length -
12317
 
                            (ctxt->input->cur - ctxt->input->base);
12318
 
            else
12319
 
                cur_avail = xmlBufUse(ctxt->input->buf->buffer) -
12320
 
                                      (ctxt->input->cur - ctxt->input->base);
12321
 
        }
12322
 
 
12323
 
        if ((ctxt->instate != XML_PARSER_EOF) &&
12324
 
            (ctxt->instate != XML_PARSER_EPILOG)) {
12325
 
            xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
12326
 
        }
12327
 
        if ((ctxt->instate == XML_PARSER_EPILOG) && (cur_avail > 0)) {
12328
 
            xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
12329
 
        }
12330
 
        if (ctxt->instate != XML_PARSER_EOF) {
12331
 
            if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
12332
 
                ctxt->sax->endDocument(ctxt->userData);
12333
 
        }
12334
 
        ctxt->instate = XML_PARSER_EOF;
12335
 
    }
12336
 
    if (ctxt->wellFormed == 0)
12337
 
        return((xmlParserErrors) ctxt->errNo);
12338
 
    else
12339
 
        return(0);
12340
 
}
12341
 
 
12342
 
/************************************************************************
12343
 
 *                                                                      *
12344
 
 *              I/O front end functions to the parser                   *
12345
 
 *                                                                      *
12346
 
 ************************************************************************/
12347
 
 
12348
 
/**
12349
 
 * xmlCreatePushParserCtxt:
12350
 
 * @sax:  a SAX handler
12351
 
 * @user_data:  The user data returned on SAX callbacks
12352
 
 * @chunk:  a pointer to an array of chars
12353
 
 * @size:  number of chars in the array
12354
 
 * @filename:  an optional file name or URI
12355
 
 *
12356
 
 * Create a parser context for using the XML parser in push mode.
12357
 
 * If @buffer and @size are non-NULL, the data is used to detect
12358
 
 * the encoding.  The remaining characters will be parsed so they
12359
 
 * don't need to be fed in again through xmlParseChunk.
12360
 
 * To allow content encoding detection, @size should be >= 4
12361
 
 * The value of @filename is used for fetching external entities
12362
 
 * and error/warning reports.
12363
 
 *
12364
 
 * Returns the new parser context or NULL
12365
 
 */
12366
 
 
12367
 
xmlParserCtxtPtr
12368
 
xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
12369
 
                        const char *chunk, int size, const char *filename) {
12370
 
    xmlParserCtxtPtr ctxt;
12371
 
    xmlParserInputPtr inputStream;
12372
 
    xmlParserInputBufferPtr buf;
12373
 
    xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
12374
 
 
12375
 
    /*
12376
 
     * plug some encoding conversion routines
12377
 
     */
12378
 
    if ((chunk != NULL) && (size >= 4))
12379
 
        enc = xmlDetectCharEncoding((const xmlChar *) chunk, size);
12380
 
 
12381
 
    buf = xmlAllocParserInputBuffer(enc);
12382
 
    if (buf == NULL) return(NULL);
12383
 
 
12384
 
    ctxt = xmlNewParserCtxt();
12385
 
    if (ctxt == NULL) {
12386
 
        xmlErrMemory(NULL, "creating parser: out of memory\n");
12387
 
        xmlFreeParserInputBuffer(buf);
12388
 
        return(NULL);
12389
 
    }
12390
 
    ctxt->dictNames = 1;
12391
 
    ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 * sizeof(xmlChar *));
12392
 
    if (ctxt->pushTab == NULL) {
12393
 
        xmlErrMemory(ctxt, NULL);
12394
 
        xmlFreeParserInputBuffer(buf);
12395
 
        xmlFreeParserCtxt(ctxt);
12396
 
        return(NULL);
12397
 
    }
12398
 
    if (sax != NULL) {
12399
 
#ifdef LIBXML_SAX1_ENABLED
12400
 
        if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
12401
 
#endif /* LIBXML_SAX1_ENABLED */
12402
 
            xmlFree(ctxt->sax);
12403
 
        ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
12404
 
        if (ctxt->sax == NULL) {
12405
 
            xmlErrMemory(ctxt, NULL);
12406
 
            xmlFreeParserInputBuffer(buf);
12407
 
            xmlFreeParserCtxt(ctxt);
12408
 
            return(NULL);
12409
 
        }
12410
 
        memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
12411
 
        if (sax->initialized == XML_SAX2_MAGIC)
12412
 
            memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
12413
 
        else
12414
 
            memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
12415
 
        if (user_data != NULL)
12416
 
            ctxt->userData = user_data;
12417
 
    }
12418
 
    if (filename == NULL) {
12419
 
        ctxt->directory = NULL;
12420
 
    } else {
12421
 
        ctxt->directory = xmlParserGetDirectory(filename);
12422
 
    }
12423
 
 
12424
 
    inputStream = xmlNewInputStream(ctxt);
12425
 
    if (inputStream == NULL) {
12426
 
        xmlFreeParserCtxt(ctxt);
12427
 
        xmlFreeParserInputBuffer(buf);
12428
 
        return(NULL);
12429
 
    }
12430
 
 
12431
 
    if (filename == NULL)
12432
 
        inputStream->filename = NULL;
12433
 
    else {
12434
 
        inputStream->filename = (char *)
12435
 
            xmlCanonicPath((const xmlChar *) filename);
12436
 
        if (inputStream->filename == NULL) {
12437
 
            xmlFreeParserCtxt(ctxt);
12438
 
            xmlFreeParserInputBuffer(buf);
12439
 
            return(NULL);
12440
 
        }
12441
 
    }
12442
 
    inputStream->buf = buf;
12443
 
    xmlBufResetInput(inputStream->buf->buffer, inputStream);
12444
 
    inputPush(ctxt, inputStream);
12445
 
 
12446
 
    /*
12447
 
     * If the caller didn't provide an initial 'chunk' for determining
12448
 
     * the encoding, we set the context to XML_CHAR_ENCODING_NONE so
12449
 
     * that it can be automatically determined later
12450
 
     */
12451
 
    if ((size == 0) || (chunk == NULL)) {
12452
 
        ctxt->charset = XML_CHAR_ENCODING_NONE;
12453
 
    } else if ((ctxt->input != NULL) && (ctxt->input->buf != NULL)) {
12454
 
        size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer, ctxt->input);
12455
 
        size_t cur = ctxt->input->cur - ctxt->input->base;
12456
 
 
12457
 
        xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
12458
 
 
12459
 
        xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur);
12460
 
#ifdef DEBUG_PUSH
12461
 
        xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
12462
 
#endif
12463
 
    }
12464
 
 
12465
 
    if (enc != XML_CHAR_ENCODING_NONE) {
12466
 
        xmlSwitchEncoding(ctxt, enc);
12467
 
    }
12468
 
 
12469
 
    return(ctxt);
12470
 
}
12471
 
#endif /* LIBXML_PUSH_ENABLED */
12472
 
 
12473
 
/**
12474
 
 * xmlStopParser:
12475
 
 * @ctxt:  an XML parser context
12476
 
 *
12477
 
 * Blocks further parser processing
12478
 
 */
12479
 
void
12480
 
xmlStopParser(xmlParserCtxtPtr ctxt) {
12481
 
    if (ctxt == NULL)
12482
 
        return;
12483
 
    ctxt->instate = XML_PARSER_EOF;
12484
 
    ctxt->errNo = XML_ERR_USER_STOP;
12485
 
    ctxt->disableSAX = 1;
12486
 
    if (ctxt->input != NULL) {
12487
 
        ctxt->input->cur = BAD_CAST"";
12488
 
        ctxt->input->base = ctxt->input->cur;
12489
 
    }
12490
 
}
12491
 
 
12492
 
/**
12493
 
 * xmlCreateIOParserCtxt:
12494
 
 * @sax:  a SAX handler
12495
 
 * @user_data:  The user data returned on SAX callbacks
12496
 
 * @ioread:  an I/O read function
12497
 
 * @ioclose:  an I/O close function
12498
 
 * @ioctx:  an I/O handler
12499
 
 * @enc:  the charset encoding if known
12500
 
 *
12501
 
 * Create a parser context for using the XML parser with an existing
12502
 
 * I/O stream
12503
 
 *
12504
 
 * Returns the new parser context or NULL
12505
 
 */
12506
 
xmlParserCtxtPtr
12507
 
xmlCreateIOParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
12508
 
        xmlInputReadCallback   ioread, xmlInputCloseCallback  ioclose,
12509
 
        void *ioctx, xmlCharEncoding enc) {
12510
 
    xmlParserCtxtPtr ctxt;
12511
 
    xmlParserInputPtr inputStream;
12512
 
    xmlParserInputBufferPtr buf;
12513
 
 
12514
 
    if (ioread == NULL) return(NULL);
12515
 
 
12516
 
    buf = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx, enc);
12517
 
    if (buf == NULL) {
12518
 
        if (ioclose != NULL)
12519
 
            ioclose(ioctx);
12520
 
        return (NULL);
12521
 
    }
12522
 
 
12523
 
    ctxt = xmlNewParserCtxt();
12524
 
    if (ctxt == NULL) {
12525
 
        xmlFreeParserInputBuffer(buf);
12526
 
        return(NULL);
12527
 
    }
12528
 
    if (sax != NULL) {
12529
 
#ifdef LIBXML_SAX1_ENABLED
12530
 
        if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
12531
 
#endif /* LIBXML_SAX1_ENABLED */
12532
 
            xmlFree(ctxt->sax);
12533
 
        ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
12534
 
        if (ctxt->sax == NULL) {
12535
 
            xmlErrMemory(ctxt, NULL);
12536
 
            xmlFreeParserCtxt(ctxt);
12537
 
            return(NULL);
12538
 
        }
12539
 
        memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
12540
 
        if (sax->initialized == XML_SAX2_MAGIC)
12541
 
            memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
12542
 
        else
12543
 
            memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
12544
 
        if (user_data != NULL)
12545
 
            ctxt->userData = user_data;
12546
 
    }
12547
 
 
12548
 
    inputStream = xmlNewIOInputStream(ctxt, buf, enc);
12549
 
    if (inputStream == NULL) {
12550
 
        xmlFreeParserCtxt(ctxt);
12551
 
        return(NULL);
12552
 
    }
12553
 
    inputPush(ctxt, inputStream);
12554
 
 
12555
 
    return(ctxt);
12556
 
}
12557
 
 
12558
 
#ifdef LIBXML_VALID_ENABLED
12559
 
/************************************************************************
12560
 
 *                                                                      *
12561
 
 *              Front ends when parsing a DTD                           *
12562
 
 *                                                                      *
12563
 
 ************************************************************************/
12564
 
 
12565
 
/**
12566
 
 * xmlIOParseDTD:
12567
 
 * @sax:  the SAX handler block or NULL
12568
 
 * @input:  an Input Buffer
12569
 
 * @enc:  the charset encoding if known
12570
 
 *
12571
 
 * Load and parse a DTD
12572
 
 *
12573
 
 * Returns the resulting xmlDtdPtr or NULL in case of error.
12574
 
 * @input will be freed by the function in any case.
12575
 
 */
12576
 
 
12577
 
xmlDtdPtr
12578
 
xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input,
12579
 
              xmlCharEncoding enc) {
12580
 
    xmlDtdPtr ret = NULL;
12581
 
    xmlParserCtxtPtr ctxt;
12582
 
    xmlParserInputPtr pinput = NULL;
12583
 
    xmlChar start[4];
12584
 
 
12585
 
    if (input == NULL)
12586
 
        return(NULL);
12587
 
 
12588
 
    ctxt = xmlNewParserCtxt();
12589
 
    if (ctxt == NULL) {
12590
 
        xmlFreeParserInputBuffer(input);
12591
 
        return(NULL);
12592
 
    }
12593
 
 
12594
 
    /*
12595
 
     * Set-up the SAX context
12596
 
     */
12597
 
    if (sax != NULL) {
12598
 
        if (ctxt->sax != NULL)
12599
 
            xmlFree(ctxt->sax);
12600
 
        ctxt->sax = sax;
12601
 
        ctxt->userData = ctxt;
12602
 
    }
12603
 
    xmlDetectSAX2(ctxt);
12604
 
 
12605
 
    /*
12606
 
     * generate a parser input from the I/O handler
12607
 
     */
12608
 
 
12609
 
    pinput = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
12610
 
    if (pinput == NULL) {
12611
 
        if (sax != NULL) ctxt->sax = NULL;
12612
 
        xmlFreeParserInputBuffer(input);
12613
 
        xmlFreeParserCtxt(ctxt);
12614
 
        return(NULL);
12615
 
    }
12616
 
 
12617
 
    /*
12618
 
     * plug some encoding conversion routines here.
12619
 
     */
12620
 
    if (xmlPushInput(ctxt, pinput) < 0) {
12621
 
        if (sax != NULL) ctxt->sax = NULL;
12622
 
        xmlFreeParserCtxt(ctxt);
12623
 
        return(NULL);
12624
 
    }
12625
 
    if (enc != XML_CHAR_ENCODING_NONE) {
12626
 
        xmlSwitchEncoding(ctxt, enc);
12627
 
    }
12628
 
 
12629
 
    pinput->filename = NULL;
12630
 
    pinput->line = 1;
12631
 
    pinput->col = 1;
12632
 
    pinput->base = ctxt->input->cur;
12633
 
    pinput->cur = ctxt->input->cur;
12634
 
    pinput->free = NULL;
12635
 
 
12636
 
    /*
12637
 
     * let's parse that entity knowing it's an external subset.
12638
 
     */
12639
 
    ctxt->inSubset = 2;
12640
 
    ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
12641
 
    if (ctxt->myDoc == NULL) {
12642
 
        xmlErrMemory(ctxt, "New Doc failed");
12643
 
        return(NULL);
12644
 
    }
12645
 
    ctxt->myDoc->properties = XML_DOC_INTERNAL;
12646
 
    ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
12647
 
                                       BAD_CAST "none", BAD_CAST "none");
12648
 
 
12649
 
    if ((enc == XML_CHAR_ENCODING_NONE) &&
12650
 
        ((ctxt->input->end - ctxt->input->cur) >= 4)) {
12651
 
        /*
12652
 
         * Get the 4 first bytes and decode the charset
12653
 
         * if enc != XML_CHAR_ENCODING_NONE
12654
 
         * plug some encoding conversion routines.
12655
 
         */
12656
 
        start[0] = RAW;
12657
 
        start[1] = NXT(1);
12658
 
        start[2] = NXT(2);
12659
 
        start[3] = NXT(3);
12660
 
        enc = xmlDetectCharEncoding(start, 4);
12661
 
        if (enc != XML_CHAR_ENCODING_NONE) {
12662
 
            xmlSwitchEncoding(ctxt, enc);
12663
 
        }
12664
 
    }
12665
 
 
12666
 
    xmlParseExternalSubset(ctxt, BAD_CAST "none", BAD_CAST "none");
12667
 
 
12668
 
    if (ctxt->myDoc != NULL) {
12669
 
        if (ctxt->wellFormed) {
12670
 
            ret = ctxt->myDoc->extSubset;
12671
 
            ctxt->myDoc->extSubset = NULL;
12672
 
            if (ret != NULL) {
12673
 
                xmlNodePtr tmp;
12674
 
 
12675
 
                ret->doc = NULL;
12676
 
                tmp = ret->children;
12677
 
                while (tmp != NULL) {
12678
 
                    tmp->doc = NULL;
12679
 
                    tmp = tmp->next;
12680
 
                }
12681
 
            }
12682
 
        } else {
12683
 
            ret = NULL;
12684
 
        }
12685
 
        xmlFreeDoc(ctxt->myDoc);
12686
 
        ctxt->myDoc = NULL;
12687
 
    }
12688
 
    if (sax != NULL) ctxt->sax = NULL;
12689
 
    xmlFreeParserCtxt(ctxt);
12690
 
 
12691
 
    return(ret);
12692
 
}
12693
 
 
12694
 
/**
12695
 
 * xmlSAXParseDTD:
12696
 
 * @sax:  the SAX handler block
12697
 
 * @ExternalID:  a NAME* containing the External ID of the DTD
12698
 
 * @SystemID:  a NAME* containing the URL to the DTD
12699
 
 *
12700
 
 * Load and parse an external subset.
12701
 
 *
12702
 
 * Returns the resulting xmlDtdPtr or NULL in case of error.
12703
 
 */
12704
 
 
12705
 
xmlDtdPtr
12706
 
xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID,
12707
 
                          const xmlChar *SystemID) {
12708
 
    xmlDtdPtr ret = NULL;
12709
 
    xmlParserCtxtPtr ctxt;
12710
 
    xmlParserInputPtr input = NULL;
12711
 
    xmlCharEncoding enc;
12712
 
    xmlChar* systemIdCanonic;
12713
 
 
12714
 
    if ((ExternalID == NULL) && (SystemID == NULL)) return(NULL);
12715
 
 
12716
 
    ctxt = xmlNewParserCtxt();
12717
 
    if (ctxt == NULL) {
12718
 
        return(NULL);
12719
 
    }
12720
 
 
12721
 
    /*
12722
 
     * Set-up the SAX context
12723
 
     */
12724
 
    if (sax != NULL) {
12725
 
        if (ctxt->sax != NULL)
12726
 
            xmlFree(ctxt->sax);
12727
 
        ctxt->sax = sax;
12728
 
        ctxt->userData = ctxt;
12729
 
    }
12730
 
 
12731
 
    /*
12732
 
     * Canonicalise the system ID
12733
 
     */
12734
 
    systemIdCanonic = xmlCanonicPath(SystemID);
12735
 
    if ((SystemID != NULL) && (systemIdCanonic == NULL)) {
12736
 
        xmlFreeParserCtxt(ctxt);
12737
 
        return(NULL);
12738
 
    }
12739
 
 
12740
 
    /*
12741
 
     * Ask the Entity resolver to load the damn thing
12742
 
     */
12743
 
 
12744
 
    if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
12745
 
        input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID,
12746
 
                                         systemIdCanonic);
12747
 
    if (input == NULL) {
12748
 
        if (sax != NULL) ctxt->sax = NULL;
12749
 
        xmlFreeParserCtxt(ctxt);
12750
 
        if (systemIdCanonic != NULL)
12751
 
            xmlFree(systemIdCanonic);
12752
 
        return(NULL);
12753
 
    }
12754
 
 
12755
 
    /*
12756
 
     * plug some encoding conversion routines here.
12757
 
     */
12758
 
    if (xmlPushInput(ctxt, input) < 0) {
12759
 
        if (sax != NULL) ctxt->sax = NULL;
12760
 
        xmlFreeParserCtxt(ctxt);
12761
 
        if (systemIdCanonic != NULL)
12762
 
            xmlFree(systemIdCanonic);
12763
 
        return(NULL);
12764
 
    }
12765
 
    if ((ctxt->input->end - ctxt->input->cur) >= 4) {
12766
 
        enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
12767
 
        xmlSwitchEncoding(ctxt, enc);
12768
 
    }
12769
 
 
12770
 
    if (input->filename == NULL)
12771
 
        input->filename = (char *) systemIdCanonic;
12772
 
    else
12773
 
        xmlFree(systemIdCanonic);
12774
 
    input->line = 1;
12775
 
    input->col = 1;
12776
 
    input->base = ctxt->input->cur;
12777
 
    input->cur = ctxt->input->cur;
12778
 
    input->free = NULL;
12779
 
 
12780
 
    /*
12781
 
     * let's parse that entity knowing it's an external subset.
12782
 
     */
12783
 
    ctxt->inSubset = 2;
12784
 
    ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
12785
 
    if (ctxt->myDoc == NULL) {
12786
 
        xmlErrMemory(ctxt, "New Doc failed");
12787
 
        if (sax != NULL) ctxt->sax = NULL;
12788
 
        xmlFreeParserCtxt(ctxt);
12789
 
        return(NULL);
12790
 
    }
12791
 
    ctxt->myDoc->properties = XML_DOC_INTERNAL;
12792
 
    ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
12793
 
                                       ExternalID, SystemID);
12794
 
    xmlParseExternalSubset(ctxt, ExternalID, SystemID);
12795
 
 
12796
 
    if (ctxt->myDoc != NULL) {
12797
 
        if (ctxt->wellFormed) {
12798
 
            ret = ctxt->myDoc->extSubset;
12799
 
            ctxt->myDoc->extSubset = NULL;
12800
 
            if (ret != NULL) {
12801
 
                xmlNodePtr tmp;
12802
 
 
12803
 
                ret->doc = NULL;
12804
 
                tmp = ret->children;
12805
 
                while (tmp != NULL) {
12806
 
                    tmp->doc = NULL;
12807
 
                    tmp = tmp->next;
12808
 
                }
12809
 
            }
12810
 
        } else {
12811
 
            ret = NULL;
12812
 
        }
12813
 
        xmlFreeDoc(ctxt->myDoc);
12814
 
        ctxt->myDoc = NULL;
12815
 
    }
12816
 
    if (sax != NULL) ctxt->sax = NULL;
12817
 
    xmlFreeParserCtxt(ctxt);
12818
 
 
12819
 
    return(ret);
12820
 
}
12821
 
 
12822
 
 
12823
 
/**
12824
 
 * xmlParseDTD:
12825
 
 * @ExternalID:  a NAME* containing the External ID of the DTD
12826
 
 * @SystemID:  a NAME* containing the URL to the DTD
12827
 
 *
12828
 
 * Load and parse an external subset.
12829
 
 *
12830
 
 * Returns the resulting xmlDtdPtr or NULL in case of error.
12831
 
 */
12832
 
 
12833
 
xmlDtdPtr
12834
 
xmlParseDTD(const xmlChar *ExternalID, const xmlChar *SystemID) {
12835
 
    return(xmlSAXParseDTD(NULL, ExternalID, SystemID));
12836
 
}
12837
 
#endif /* LIBXML_VALID_ENABLED */
12838
 
 
12839
 
/************************************************************************
12840
 
 *                                                                      *
12841
 
 *              Front ends when parsing an Entity                       *
12842
 
 *                                                                      *
12843
 
 ************************************************************************/
12844
 
 
12845
 
/**
12846
 
 * xmlParseCtxtExternalEntity:
12847
 
 * @ctx:  the existing parsing context
12848
 
 * @URL:  the URL for the entity to load
12849
 
 * @ID:  the System ID for the entity to load
12850
 
 * @lst:  the return value for the set of parsed nodes
12851
 
 *
12852
 
 * Parse an external general entity within an existing parsing context
12853
 
 * An external general parsed entity is well-formed if it matches the
12854
 
 * production labeled extParsedEnt.
12855
 
 *
12856
 
 * [78] extParsedEnt ::= TextDecl? content
12857
 
 *
12858
 
 * Returns 0 if the entity is well formed, -1 in case of args problem and
12859
 
 *    the parser error code otherwise
12860
 
 */
12861
 
 
12862
 
int
12863
 
xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx, const xmlChar *URL,
12864
 
                       const xmlChar *ID, xmlNodePtr *lst) {
12865
 
    xmlParserCtxtPtr ctxt;
12866
 
    xmlDocPtr newDoc;
12867
 
    xmlNodePtr newRoot;
12868
 
    xmlSAXHandlerPtr oldsax = NULL;
12869
 
    int ret = 0;
12870
 
    xmlChar start[4];
12871
 
    xmlCharEncoding enc;
12872
 
 
12873
 
    if (ctx == NULL) return(-1);
12874
 
 
12875
 
    if (((ctx->depth > 40) && ((ctx->options & XML_PARSE_HUGE) == 0)) ||
12876
 
        (ctx->depth > 1024)) {
12877
 
        return(XML_ERR_ENTITY_LOOP);
12878
 
    }
12879
 
 
12880
 
    if (lst != NULL)
12881
 
        *lst = NULL;
12882
 
    if ((URL == NULL) && (ID == NULL))
12883
 
        return(-1);
12884
 
    if (ctx->myDoc == NULL) /* @@ relax but check for dereferences */
12885
 
        return(-1);
12886
 
 
12887
 
    ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, ctx);
12888
 
    if (ctxt == NULL) {
12889
 
        return(-1);
12890
 
    }
12891
 
 
12892
 
    oldsax = ctxt->sax;
12893
 
    ctxt->sax = ctx->sax;
12894
 
    xmlDetectSAX2(ctxt);
12895
 
    newDoc = xmlNewDoc(BAD_CAST "1.0");
12896
 
    if (newDoc == NULL) {
12897
 
        xmlFreeParserCtxt(ctxt);
12898
 
        return(-1);
12899
 
    }
12900
 
    newDoc->properties = XML_DOC_INTERNAL;
12901
 
    if (ctx->myDoc->dict) {
12902
 
        newDoc->dict = ctx->myDoc->dict;
12903
 
        xmlDictReference(newDoc->dict);
12904
 
    }
12905
 
    if (ctx->myDoc != NULL) {
12906
 
        newDoc->intSubset = ctx->myDoc->intSubset;
12907
 
        newDoc->extSubset = ctx->myDoc->extSubset;
12908
 
    }
12909
 
    if (ctx->myDoc->URL != NULL) {
12910
 
        newDoc->URL = xmlStrdup(ctx->myDoc->URL);
12911
 
    }
12912
 
    newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
12913
 
    if (newRoot == NULL) {
12914
 
        ctxt->sax = oldsax;
12915
 
        xmlFreeParserCtxt(ctxt);
12916
 
        newDoc->intSubset = NULL;
12917
 
        newDoc->extSubset = NULL;
12918
 
        xmlFreeDoc(newDoc);
12919
 
        return(-1);
12920
 
    }
12921
 
    xmlAddChild((xmlNodePtr) newDoc, newRoot);
12922
 
    nodePush(ctxt, newDoc->children);
12923
 
    if (ctx->myDoc == NULL) {
12924
 
        ctxt->myDoc = newDoc;
12925
 
    } else {
12926
 
        ctxt->myDoc = ctx->myDoc;
12927
 
        newDoc->children->doc = ctx->myDoc;
12928
 
    }
12929
 
 
12930
 
    /*
12931
 
     * Get the 4 first bytes and decode the charset
12932
 
     * if enc != XML_CHAR_ENCODING_NONE
12933
 
     * plug some encoding conversion routines.
12934
 
     */
12935
 
    GROW
12936
 
    if ((ctxt->input->end - ctxt->input->cur) >= 4) {
12937
 
        start[0] = RAW;
12938
 
        start[1] = NXT(1);
12939
 
        start[2] = NXT(2);
12940
 
        start[3] = NXT(3);
12941
 
        enc = xmlDetectCharEncoding(start, 4);
12942
 
        if (enc != XML_CHAR_ENCODING_NONE) {
12943
 
            xmlSwitchEncoding(ctxt, enc);
12944
 
        }
12945
 
    }
12946
 
 
12947
 
    /*
12948
 
     * Parse a possible text declaration first
12949
 
     */
12950
 
    if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
12951
 
        xmlParseTextDecl(ctxt);
12952
 
        /*
12953
 
         * An XML-1.0 document can't reference an entity not XML-1.0
12954
 
         */
12955
 
        if ((xmlStrEqual(ctx->version, BAD_CAST "1.0")) &&
12956
 
            (!xmlStrEqual(ctxt->input->version, BAD_CAST "1.0"))) {
12957
 
            xmlFatalErrMsg(ctxt, XML_ERR_VERSION_MISMATCH,
12958
 
                           "Version mismatch between document and entity\n");
12959
 
        }
12960
 
    }
12961
 
 
12962
 
    /*
12963
 
     * If the user provided its own SAX callbacks then reuse the
12964
 
     * useData callback field, otherwise the expected setup in a
12965
 
     * DOM builder is to have userData == ctxt
12966
 
     */
12967
 
    if (ctx->userData == ctx)
12968
 
        ctxt->userData = ctxt;
12969
 
    else
12970
 
        ctxt->userData = ctx->userData;
12971
 
 
12972
 
    /*
12973
 
     * Doing validity checking on chunk doesn't make sense
12974
 
     */
12975
 
    ctxt->instate = XML_PARSER_CONTENT;
12976
 
    ctxt->validate = ctx->validate;
12977
 
    ctxt->valid = ctx->valid;
12978
 
    ctxt->loadsubset = ctx->loadsubset;
12979
 
    ctxt->depth = ctx->depth + 1;
12980
 
    ctxt->replaceEntities = ctx->replaceEntities;
12981
 
    if (ctxt->validate) {
12982
 
        ctxt->vctxt.error = ctx->vctxt.error;
12983
 
        ctxt->vctxt.warning = ctx->vctxt.warning;
12984
 
    } else {
12985
 
        ctxt->vctxt.error = NULL;
12986
 
        ctxt->vctxt.warning = NULL;
12987
 
    }
12988
 
    ctxt->vctxt.nodeTab = NULL;
12989
 
    ctxt->vctxt.nodeNr = 0;
12990
 
    ctxt->vctxt.nodeMax = 0;
12991
 
    ctxt->vctxt.node = NULL;
12992
 
    if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
12993
 
    ctxt->dict = ctx->dict;
12994
 
    ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
12995
 
    ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
12996
 
    ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
12997
 
    ctxt->dictNames = ctx->dictNames;
12998
 
    ctxt->attsDefault = ctx->attsDefault;
12999
 
    ctxt->attsSpecial = ctx->attsSpecial;
13000
 
    ctxt->linenumbers = ctx->linenumbers;
13001
 
 
13002
 
    xmlParseContent(ctxt);
13003
 
 
13004
 
    ctx->validate = ctxt->validate;
13005
 
    ctx->valid = ctxt->valid;
13006
 
    if ((RAW == '<') && (NXT(1) == '/')) {
13007
 
        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13008
 
    } else if (RAW != 0) {
13009
 
        xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
13010
 
    }
13011
 
    if (ctxt->node != newDoc->children) {
13012
 
        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13013
 
    }
13014
 
 
13015
 
    if (!ctxt->wellFormed) {
13016
 
        if (ctxt->errNo == 0)
13017
 
            ret = 1;
13018
 
        else
13019
 
            ret = ctxt->errNo;
13020
 
    } else {
13021
 
        if (lst != NULL) {
13022
 
            xmlNodePtr cur;
13023
 
 
13024
 
            /*
13025
 
             * Return the newly created nodeset after unlinking it from
13026
 
             * they pseudo parent.
13027
 
             */
13028
 
            cur = newDoc->children->children;
13029
 
            *lst = cur;
13030
 
            while (cur != NULL) {
13031
 
                cur->parent = NULL;
13032
 
                cur = cur->next;
13033
 
            }
13034
 
            newDoc->children->children = NULL;
13035
 
        }
13036
 
        ret = 0;
13037
 
    }
13038
 
    ctxt->sax = oldsax;
13039
 
    ctxt->dict = NULL;
13040
 
    ctxt->attsDefault = NULL;
13041
 
    ctxt->attsSpecial = NULL;
13042
 
    xmlFreeParserCtxt(ctxt);
13043
 
    newDoc->intSubset = NULL;
13044
 
    newDoc->extSubset = NULL;
13045
 
    xmlFreeDoc(newDoc);
13046
 
 
13047
 
    return(ret);
13048
 
}
13049
 
 
13050
 
/**
13051
 
 * xmlParseExternalEntityPrivate:
13052
 
 * @doc:  the document the chunk pertains to
13053
 
 * @oldctxt:  the previous parser context if available
13054
 
 * @sax:  the SAX handler bloc (possibly NULL)
13055
 
 * @user_data:  The user data returned on SAX callbacks (possibly NULL)
13056
 
 * @depth:  Used for loop detection, use 0
13057
 
 * @URL:  the URL for the entity to load
13058
 
 * @ID:  the System ID for the entity to load
13059
 
 * @list:  the return value for the set of parsed nodes
13060
 
 *
13061
 
 * Private version of xmlParseExternalEntity()
13062
 
 *
13063
 
 * Returns 0 if the entity is well formed, -1 in case of args problem and
13064
 
 *    the parser error code otherwise
13065
 
 */
13066
 
 
13067
 
static xmlParserErrors
13068
 
xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
13069
 
                      xmlSAXHandlerPtr sax,
13070
 
                      void *user_data, int depth, const xmlChar *URL,
13071
 
                      const xmlChar *ID, xmlNodePtr *list) {
13072
 
    xmlParserCtxtPtr ctxt;
13073
 
    xmlDocPtr newDoc;
13074
 
    xmlNodePtr newRoot;
13075
 
    xmlSAXHandlerPtr oldsax = NULL;
13076
 
    xmlParserErrors ret = XML_ERR_OK;
13077
 
    xmlChar start[4];
13078
 
    xmlCharEncoding enc;
13079
 
 
13080
 
    if (((depth > 40) &&
13081
 
        ((oldctxt == NULL) || (oldctxt->options & XML_PARSE_HUGE) == 0)) ||
13082
 
        (depth > 1024)) {
13083
 
        return(XML_ERR_ENTITY_LOOP);
13084
 
    }
13085
 
 
13086
 
    if (list != NULL)
13087
 
        *list = NULL;
13088
 
    if ((URL == NULL) && (ID == NULL))
13089
 
        return(XML_ERR_INTERNAL_ERROR);
13090
 
    if (doc == NULL)
13091
 
        return(XML_ERR_INTERNAL_ERROR);
13092
 
 
13093
 
 
13094
 
    ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, oldctxt);
13095
 
    if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
13096
 
    ctxt->userData = ctxt;
13097
 
    if (oldctxt != NULL) {
13098
 
        ctxt->_private = oldctxt->_private;
13099
 
        ctxt->loadsubset = oldctxt->loadsubset;
13100
 
        ctxt->validate = oldctxt->validate;
13101
 
        ctxt->external = oldctxt->external;
13102
 
        ctxt->record_info = oldctxt->record_info;
13103
 
        ctxt->node_seq.maximum = oldctxt->node_seq.maximum;
13104
 
        ctxt->node_seq.length = oldctxt->node_seq.length;
13105
 
        ctxt->node_seq.buffer = oldctxt->node_seq.buffer;
13106
 
    } else {
13107
 
        /*
13108
 
         * Doing validity checking on chunk without context
13109
 
         * doesn't make sense
13110
 
         */
13111
 
        ctxt->_private = NULL;
13112
 
        ctxt->validate = 0;
13113
 
        ctxt->external = 2;
13114
 
        ctxt->loadsubset = 0;
13115
 
    }
13116
 
    if (sax != NULL) {
13117
 
        oldsax = ctxt->sax;
13118
 
        ctxt->sax = sax;
13119
 
        if (user_data != NULL)
13120
 
            ctxt->userData = user_data;
13121
 
    }
13122
 
    xmlDetectSAX2(ctxt);
13123
 
    newDoc = xmlNewDoc(BAD_CAST "1.0");
13124
 
    if (newDoc == NULL) {
13125
 
        ctxt->node_seq.maximum = 0;
13126
 
        ctxt->node_seq.length = 0;
13127
 
        ctxt->node_seq.buffer = NULL;
13128
 
        xmlFreeParserCtxt(ctxt);
13129
 
        return(XML_ERR_INTERNAL_ERROR);
13130
 
    }
13131
 
    newDoc->properties = XML_DOC_INTERNAL;
13132
 
    newDoc->intSubset = doc->intSubset;
13133
 
    newDoc->extSubset = doc->extSubset;
13134
 
    newDoc->dict = doc->dict;
13135
 
    xmlDictReference(newDoc->dict);
13136
 
 
13137
 
    if (doc->URL != NULL) {
13138
 
        newDoc->URL = xmlStrdup(doc->URL);
13139
 
    }
13140
 
    newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
13141
 
    if (newRoot == NULL) {
13142
 
        if (sax != NULL)
13143
 
            ctxt->sax = oldsax;
13144
 
        ctxt->node_seq.maximum = 0;
13145
 
        ctxt->node_seq.length = 0;
13146
 
        ctxt->node_seq.buffer = NULL;
13147
 
        xmlFreeParserCtxt(ctxt);
13148
 
        newDoc->intSubset = NULL;
13149
 
        newDoc->extSubset = NULL;
13150
 
        xmlFreeDoc(newDoc);
13151
 
        return(XML_ERR_INTERNAL_ERROR);
13152
 
    }
13153
 
    xmlAddChild((xmlNodePtr) newDoc, newRoot);
13154
 
    nodePush(ctxt, newDoc->children);
13155
 
    ctxt->myDoc = doc;
13156
 
    newRoot->doc = doc;
13157
 
 
13158
 
    /*
13159
 
     * Get the 4 first bytes and decode the charset
13160
 
     * if enc != XML_CHAR_ENCODING_NONE
13161
 
     * plug some encoding conversion routines.
13162
 
     */
13163
 
    GROW;
13164
 
    if ((ctxt->input->end - ctxt->input->cur) >= 4) {
13165
 
        start[0] = RAW;
13166
 
        start[1] = NXT(1);
13167
 
        start[2] = NXT(2);
13168
 
        start[3] = NXT(3);
13169
 
        enc = xmlDetectCharEncoding(start, 4);
13170
 
        if (enc != XML_CHAR_ENCODING_NONE) {
13171
 
            xmlSwitchEncoding(ctxt, enc);
13172
 
        }
13173
 
    }
13174
 
 
13175
 
    /*
13176
 
     * Parse a possible text declaration first
13177
 
     */
13178
 
    if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
13179
 
        xmlParseTextDecl(ctxt);
13180
 
    }
13181
 
 
13182
 
    ctxt->instate = XML_PARSER_CONTENT;
13183
 
    ctxt->depth = depth;
13184
 
 
13185
 
    xmlParseContent(ctxt);
13186
 
 
13187
 
    if ((RAW == '<') && (NXT(1) == '/')) {
13188
 
        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13189
 
    } else if (RAW != 0) {
13190
 
        xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
13191
 
    }
13192
 
    if (ctxt->node != newDoc->children) {
13193
 
        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13194
 
    }
13195
 
 
13196
 
    if (!ctxt->wellFormed) {
13197
 
        if (ctxt->errNo == 0)
13198
 
            ret = XML_ERR_INTERNAL_ERROR;
13199
 
        else
13200
 
            ret = (xmlParserErrors)ctxt->errNo;
13201
 
    } else {
13202
 
        if (list != NULL) {
13203
 
            xmlNodePtr cur;
13204
 
 
13205
 
            /*
13206
 
             * Return the newly created nodeset after unlinking it from
13207
 
             * they pseudo parent.
13208
 
             */
13209
 
            cur = newDoc->children->children;
13210
 
            *list = cur;
13211
 
            while (cur != NULL) {
13212
 
                cur->parent = NULL;
13213
 
                cur = cur->next;
13214
 
            }
13215
 
            newDoc->children->children = NULL;
13216
 
        }
13217
 
        ret = XML_ERR_OK;
13218
 
    }
13219
 
 
13220
 
    /*
13221
 
     * Record in the parent context the number of entities replacement
13222
 
     * done when parsing that reference.
13223
 
     */
13224
 
    if (oldctxt != NULL)
13225
 
        oldctxt->nbentities += ctxt->nbentities;
13226
 
 
13227
 
    /*
13228
 
     * Also record the size of the entity parsed
13229
 
     */
13230
 
    if (ctxt->input != NULL) {
13231
 
        oldctxt->sizeentities += ctxt->input->consumed;
13232
 
        oldctxt->sizeentities += (ctxt->input->cur - ctxt->input->base);
13233
 
    }
13234
 
    /*
13235
 
     * And record the last error if any
13236
 
     */
13237
 
    if (ctxt->lastError.code != XML_ERR_OK)
13238
 
        xmlCopyError(&ctxt->lastError, &oldctxt->lastError);
13239
 
 
13240
 
    if (sax != NULL)
13241
 
        ctxt->sax = oldsax;
13242
 
    oldctxt->node_seq.maximum = ctxt->node_seq.maximum;
13243
 
    oldctxt->node_seq.length = ctxt->node_seq.length;
13244
 
    oldctxt->node_seq.buffer = ctxt->node_seq.buffer;
13245
 
    ctxt->node_seq.maximum = 0;
13246
 
    ctxt->node_seq.length = 0;
13247
 
    ctxt->node_seq.buffer = NULL;
13248
 
    xmlFreeParserCtxt(ctxt);
13249
 
    newDoc->intSubset = NULL;
13250
 
    newDoc->extSubset = NULL;
13251
 
    xmlFreeDoc(newDoc);
13252
 
 
13253
 
    return(ret);
13254
 
}
13255
 
 
13256
 
#ifdef LIBXML_SAX1_ENABLED
13257
 
/**
13258
 
 * xmlParseExternalEntity:
13259
 
 * @doc:  the document the chunk pertains to
13260
 
 * @sax:  the SAX handler bloc (possibly NULL)
13261
 
 * @user_data:  The user data returned on SAX callbacks (possibly NULL)
13262
 
 * @depth:  Used for loop detection, use 0
13263
 
 * @URL:  the URL for the entity to load
13264
 
 * @ID:  the System ID for the entity to load
13265
 
 * @lst:  the return value for the set of parsed nodes
13266
 
 *
13267
 
 * Parse an external general entity
13268
 
 * An external general parsed entity is well-formed if it matches the
13269
 
 * production labeled extParsedEnt.
13270
 
 *
13271
 
 * [78] extParsedEnt ::= TextDecl? content
13272
 
 *
13273
 
 * Returns 0 if the entity is well formed, -1 in case of args problem and
13274
 
 *    the parser error code otherwise
13275
 
 */
13276
 
 
13277
 
int
13278
 
xmlParseExternalEntity(xmlDocPtr doc, xmlSAXHandlerPtr sax, void *user_data,
13279
 
          int depth, const xmlChar *URL, const xmlChar *ID, xmlNodePtr *lst) {
13280
 
    return(xmlParseExternalEntityPrivate(doc, NULL, sax, user_data, depth, URL,
13281
 
                                       ID, lst));
13282
 
}
13283
 
 
13284
 
/**
13285
 
 * xmlParseBalancedChunkMemory:
13286
 
 * @doc:  the document the chunk pertains to
13287
 
 * @sax:  the SAX handler bloc (possibly NULL)
13288
 
 * @user_data:  The user data returned on SAX callbacks (possibly NULL)
13289
 
 * @depth:  Used for loop detection, use 0
13290
 
 * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
13291
 
 * @lst:  the return value for the set of parsed nodes
13292
 
 *
13293
 
 * Parse a well-balanced chunk of an XML document
13294
 
 * called by the parser
13295
 
 * The allowed sequence for the Well Balanced Chunk is the one defined by
13296
 
 * the content production in the XML grammar:
13297
 
 *
13298
 
 * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
13299
 
 *
13300
 
 * Returns 0 if the chunk is well balanced, -1 in case of args problem and
13301
 
 *    the parser error code otherwise
13302
 
 */
13303
 
 
13304
 
int
13305
 
xmlParseBalancedChunkMemory(xmlDocPtr doc, xmlSAXHandlerPtr sax,
13306
 
     void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst) {
13307
 
    return xmlParseBalancedChunkMemoryRecover( doc, sax, user_data,
13308
 
                                                depth, string, lst, 0 );
13309
 
}
13310
 
#endif /* LIBXML_SAX1_ENABLED */
13311
 
 
13312
 
/**
13313
 
 * xmlParseBalancedChunkMemoryInternal:
13314
 
 * @oldctxt:  the existing parsing context
13315
 
 * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
13316
 
 * @user_data:  the user data field for the parser context
13317
 
 * @lst:  the return value for the set of parsed nodes
13318
 
 *
13319
 
 *
13320
 
 * Parse a well-balanced chunk of an XML document
13321
 
 * called by the parser
13322
 
 * The allowed sequence for the Well Balanced Chunk is the one defined by
13323
 
 * the content production in the XML grammar:
13324
 
 *
13325
 
 * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
13326
 
 *
13327
 
 * Returns XML_ERR_OK if the chunk is well balanced, and the parser
13328
 
 * error code otherwise
13329
 
 *
13330
 
 * In case recover is set to 1, the nodelist will not be empty even if
13331
 
 * the parsed chunk is not well balanced.
13332
 
 */
13333
 
static xmlParserErrors
13334
 
xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
13335
 
        const xmlChar *string, void *user_data, xmlNodePtr *lst) {
13336
 
    xmlParserCtxtPtr ctxt;
13337
 
    xmlDocPtr newDoc = NULL;
13338
 
    xmlNodePtr newRoot;
13339
 
    xmlSAXHandlerPtr oldsax = NULL;
13340
 
    xmlNodePtr content = NULL;
13341
 
    xmlNodePtr last = NULL;
13342
 
    int size;
13343
 
    xmlParserErrors ret = XML_ERR_OK;
13344
 
#ifdef SAX2
13345
 
    int i;
13346
 
#endif
13347
 
 
13348
 
    if (((oldctxt->depth > 40) && ((oldctxt->options & XML_PARSE_HUGE) == 0)) ||
13349
 
        (oldctxt->depth >  1024)) {
13350
 
        return(XML_ERR_ENTITY_LOOP);
13351
 
    }
13352
 
 
13353
 
 
13354
 
    if (lst != NULL)
13355
 
        *lst = NULL;
13356
 
    if (string == NULL)
13357
 
        return(XML_ERR_INTERNAL_ERROR);
13358
 
 
13359
 
    size = xmlStrlen(string);
13360
 
 
13361
 
    ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
13362
 
    if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
13363
 
    if (user_data != NULL)
13364
 
        ctxt->userData = user_data;
13365
 
    else
13366
 
        ctxt->userData = ctxt;
13367
 
    if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
13368
 
    ctxt->dict = oldctxt->dict;
13369
 
    ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
13370
 
    ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
13371
 
    ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
13372
 
 
13373
 
#ifdef SAX2
13374
 
    /* propagate namespaces down the entity */
13375
 
    for (i = 0;i < oldctxt->nsNr;i += 2) {
13376
 
        nsPush(ctxt, oldctxt->nsTab[i], oldctxt->nsTab[i+1]);
13377
 
    }
13378
 
#endif
13379
 
 
13380
 
    oldsax = ctxt->sax;
13381
 
    ctxt->sax = oldctxt->sax;
13382
 
    xmlDetectSAX2(ctxt);
13383
 
    ctxt->replaceEntities = oldctxt->replaceEntities;
13384
 
    ctxt->options = oldctxt->options;
13385
 
 
13386
 
    ctxt->_private = oldctxt->_private;
13387
 
    if (oldctxt->myDoc == NULL) {
13388
 
        newDoc = xmlNewDoc(BAD_CAST "1.0");
13389
 
        if (newDoc == NULL) {
13390
 
            ctxt->sax = oldsax;
13391
 
            ctxt->dict = NULL;
13392
 
            xmlFreeParserCtxt(ctxt);
13393
 
            return(XML_ERR_INTERNAL_ERROR);
13394
 
        }
13395
 
        newDoc->properties = XML_DOC_INTERNAL;
13396
 
        newDoc->dict = ctxt->dict;
13397
 
        xmlDictReference(newDoc->dict);
13398
 
        ctxt->myDoc = newDoc;
13399
 
    } else {
13400
 
        ctxt->myDoc = oldctxt->myDoc;
13401
 
        content = ctxt->myDoc->children;
13402
 
        last = ctxt->myDoc->last;
13403
 
    }
13404
 
    newRoot = xmlNewDocNode(ctxt->myDoc, NULL, BAD_CAST "pseudoroot", NULL);
13405
 
    if (newRoot == NULL) {
13406
 
        ctxt->sax = oldsax;
13407
 
        ctxt->dict = NULL;
13408
 
        xmlFreeParserCtxt(ctxt);
13409
 
        if (newDoc != NULL) {
13410
 
            xmlFreeDoc(newDoc);
13411
 
        }
13412
 
        return(XML_ERR_INTERNAL_ERROR);
13413
 
    }
13414
 
    ctxt->myDoc->children = NULL;
13415
 
    ctxt->myDoc->last = NULL;
13416
 
    xmlAddChild((xmlNodePtr) ctxt->myDoc, newRoot);
13417
 
    nodePush(ctxt, ctxt->myDoc->children);
13418
 
    ctxt->instate = XML_PARSER_CONTENT;
13419
 
    ctxt->depth = oldctxt->depth + 1;
13420
 
 
13421
 
    ctxt->validate = 0;
13422
 
    ctxt->loadsubset = oldctxt->loadsubset;
13423
 
    if ((oldctxt->validate) || (oldctxt->replaceEntities != 0)) {
13424
 
        /*
13425
 
         * ID/IDREF registration will be done in xmlValidateElement below
13426
 
         */
13427
 
        ctxt->loadsubset |= XML_SKIP_IDS;
13428
 
    }
13429
 
    ctxt->dictNames = oldctxt->dictNames;
13430
 
    ctxt->attsDefault = oldctxt->attsDefault;
13431
 
    ctxt->attsSpecial = oldctxt->attsSpecial;
13432
 
 
13433
 
    xmlParseContent(ctxt);
13434
 
    if ((RAW == '<') && (NXT(1) == '/')) {
13435
 
        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13436
 
    } else if (RAW != 0) {
13437
 
        xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
13438
 
    }
13439
 
    if (ctxt->node != ctxt->myDoc->children) {
13440
 
        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13441
 
    }
13442
 
 
13443
 
    if (!ctxt->wellFormed) {
13444
 
        if (ctxt->errNo == 0)
13445
 
            ret = XML_ERR_INTERNAL_ERROR;
13446
 
        else
13447
 
            ret = (xmlParserErrors)ctxt->errNo;
13448
 
    } else {
13449
 
      ret = XML_ERR_OK;
13450
 
    }
13451
 
 
13452
 
    if ((lst != NULL) && (ret == XML_ERR_OK)) {
13453
 
        xmlNodePtr cur;
13454
 
 
13455
 
        /*
13456
 
         * Return the newly created nodeset after unlinking it from
13457
 
         * they pseudo parent.
13458
 
         */
13459
 
        cur = ctxt->myDoc->children->children;
13460
 
        *lst = cur;
13461
 
        while (cur != NULL) {
13462
 
#ifdef LIBXML_VALID_ENABLED
13463
 
            if ((oldctxt->validate) && (oldctxt->wellFormed) &&
13464
 
                (oldctxt->myDoc) && (oldctxt->myDoc->intSubset) &&
13465
 
                (cur->type == XML_ELEMENT_NODE)) {
13466
 
                oldctxt->valid &= xmlValidateElement(&oldctxt->vctxt,
13467
 
                        oldctxt->myDoc, cur);
13468
 
            }
13469
 
#endif /* LIBXML_VALID_ENABLED */
13470
 
            cur->parent = NULL;
13471
 
            cur = cur->next;
13472
 
        }
13473
 
        ctxt->myDoc->children->children = NULL;
13474
 
    }
13475
 
    if (ctxt->myDoc != NULL) {
13476
 
        xmlFreeNode(ctxt->myDoc->children);
13477
 
        ctxt->myDoc->children = content;
13478
 
        ctxt->myDoc->last = last;
13479
 
    }
13480
 
 
13481
 
    /*
13482
 
     * Record in the parent context the number of entities replacement
13483
 
     * done when parsing that reference.
13484
 
     */
13485
 
    if (oldctxt != NULL)
13486
 
        oldctxt->nbentities += ctxt->nbentities;
13487
 
 
13488
 
    /*
13489
 
     * Also record the last error if any
13490
 
     */
13491
 
    if (ctxt->lastError.code != XML_ERR_OK)
13492
 
        xmlCopyError(&ctxt->lastError, &oldctxt->lastError);
13493
 
 
13494
 
    ctxt->sax = oldsax;
13495
 
    ctxt->dict = NULL;
13496
 
    ctxt->attsDefault = NULL;
13497
 
    ctxt->attsSpecial = NULL;
13498
 
    xmlFreeParserCtxt(ctxt);
13499
 
    if (newDoc != NULL) {
13500
 
        xmlFreeDoc(newDoc);
13501
 
    }
13502
 
 
13503
 
    return(ret);
13504
 
}
13505
 
 
13506
 
/**
13507
 
 * xmlParseInNodeContext:
13508
 
 * @node:  the context node
13509
 
 * @data:  the input string
13510
 
 * @datalen:  the input string length in bytes
13511
 
 * @options:  a combination of xmlParserOption
13512
 
 * @lst:  the return value for the set of parsed nodes
13513
 
 *
13514
 
 * Parse a well-balanced chunk of an XML document
13515
 
 * within the context (DTD, namespaces, etc ...) of the given node.
13516
 
 *
13517
 
 * The allowed sequence for the data is a Well Balanced Chunk defined by
13518
 
 * the content production in the XML grammar:
13519
 
 *
13520
 
 * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
13521
 
 *
13522
 
 * Returns XML_ERR_OK if the chunk is well balanced, and the parser
13523
 
 * error code otherwise
13524
 
 */
13525
 
xmlParserErrors
13526
 
xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen,
13527
 
                      int options, xmlNodePtr *lst) {
13528
 
#ifdef SAX2
13529
 
    xmlParserCtxtPtr ctxt;
13530
 
    xmlDocPtr doc = NULL;
13531
 
    xmlNodePtr fake, cur;
13532
 
    int nsnr = 0;
13533
 
 
13534
 
    xmlParserErrors ret = XML_ERR_OK;
13535
 
 
13536
 
    /*
13537
 
     * check all input parameters, grab the document
13538
 
     */
13539
 
    if ((lst == NULL) || (node == NULL) || (data == NULL) || (datalen < 0))
13540
 
        return(XML_ERR_INTERNAL_ERROR);
13541
 
    switch (node->type) {
13542
 
        case XML_ELEMENT_NODE:
13543
 
        case XML_ATTRIBUTE_NODE:
13544
 
        case XML_TEXT_NODE:
13545
 
        case XML_CDATA_SECTION_NODE:
13546
 
        case XML_ENTITY_REF_NODE:
13547
 
        case XML_PI_NODE:
13548
 
        case XML_COMMENT_NODE:
13549
 
        case XML_DOCUMENT_NODE:
13550
 
        case XML_HTML_DOCUMENT_NODE:
13551
 
            break;
13552
 
        default:
13553
 
            return(XML_ERR_INTERNAL_ERROR);
13554
 
 
13555
 
    }
13556
 
    while ((node != NULL) && (node->type != XML_ELEMENT_NODE) &&
13557
 
           (node->type != XML_DOCUMENT_NODE) &&
13558
 
           (node->type != XML_HTML_DOCUMENT_NODE))
13559
 
        node = node->parent;
13560
 
    if (node == NULL)
13561
 
        return(XML_ERR_INTERNAL_ERROR);
13562
 
    if (node->type == XML_ELEMENT_NODE)
13563
 
        doc = node->doc;
13564
 
    else
13565
 
        doc = (xmlDocPtr) node;
13566
 
    if (doc == NULL)
13567
 
        return(XML_ERR_INTERNAL_ERROR);
13568
 
 
13569
 
    /*
13570
 
     * allocate a context and set-up everything not related to the
13571
 
     * node position in the tree
13572
 
     */
13573
 
    if (doc->type == XML_DOCUMENT_NODE)
13574
 
        ctxt = xmlCreateMemoryParserCtxt((char *) data, datalen);
13575
 
#ifdef LIBXML_HTML_ENABLED
13576
 
    else if (doc->type == XML_HTML_DOCUMENT_NODE) {
13577
 
        ctxt = htmlCreateMemoryParserCtxt((char *) data, datalen);
13578
 
        /*
13579
 
         * When parsing in context, it makes no sense to add implied
13580
 
         * elements like html/body/etc...
13581
 
         */
13582
 
        options |= HTML_PARSE_NOIMPLIED;
13583
 
    }
13584
 
#endif
13585
 
    else
13586
 
        return(XML_ERR_INTERNAL_ERROR);
13587
 
 
13588
 
    if (ctxt == NULL)
13589
 
        return(XML_ERR_NO_MEMORY);
13590
 
 
13591
 
    /*
13592
 
     * Use input doc's dict if present, else assure XML_PARSE_NODICT is set.
13593
 
     * We need a dictionary for xmlDetectSAX2, so if there's no doc dict
13594
 
     * we must wait until the last moment to free the original one.
13595
 
     */
13596
 
    if (doc->dict != NULL) {
13597
 
        if (ctxt->dict != NULL)
13598
 
            xmlDictFree(ctxt->dict);
13599
 
        ctxt->dict = doc->dict;
13600
 
    } else
13601
 
        options |= XML_PARSE_NODICT;
13602
 
 
13603
 
    if (doc->encoding != NULL) {
13604
 
        xmlCharEncodingHandlerPtr hdlr;
13605
 
 
13606
 
        if (ctxt->encoding != NULL)
13607
 
            xmlFree((xmlChar *) ctxt->encoding);
13608
 
        ctxt->encoding = xmlStrdup((const xmlChar *) doc->encoding);
13609
 
 
13610
 
        hdlr = xmlFindCharEncodingHandler(doc->encoding);
13611
 
        if (hdlr != NULL) {
13612
 
            xmlSwitchToEncoding(ctxt, hdlr);
13613
 
        } else {
13614
 
            return(XML_ERR_UNSUPPORTED_ENCODING);
13615
 
        }
13616
 
    }
13617
 
 
13618
 
    xmlCtxtUseOptionsInternal(ctxt, options, NULL);
13619
 
    xmlDetectSAX2(ctxt);
13620
 
    ctxt->myDoc = doc;
13621
 
 
13622
 
    fake = xmlNewComment(NULL);
13623
 
    if (fake == NULL) {
13624
 
        xmlFreeParserCtxt(ctxt);
13625
 
        return(XML_ERR_NO_MEMORY);
13626
 
    }
13627
 
    xmlAddChild(node, fake);
13628
 
 
13629
 
    if (node->type == XML_ELEMENT_NODE) {
13630
 
        nodePush(ctxt, node);
13631
 
        /*
13632
 
         * initialize the SAX2 namespaces stack
13633
 
         */
13634
 
        cur = node;
13635
 
        while ((cur != NULL) && (cur->type == XML_ELEMENT_NODE)) {
13636
 
            xmlNsPtr ns = cur->nsDef;
13637
 
            const xmlChar *iprefix, *ihref;
13638
 
 
13639
 
            while (ns != NULL) {
13640
 
                if (ctxt->dict) {
13641
 
                    iprefix = xmlDictLookup(ctxt->dict, ns->prefix, -1);
13642
 
                    ihref = xmlDictLookup(ctxt->dict, ns->href, -1);
13643
 
                } else {
13644
 
                    iprefix = ns->prefix;
13645
 
                    ihref = ns->href;
13646
 
                }
13647
 
 
13648
 
                if (xmlGetNamespace(ctxt, iprefix) == NULL) {
13649
 
                    nsPush(ctxt, iprefix, ihref);
13650
 
                    nsnr++;
13651
 
                }
13652
 
                ns = ns->next;
13653
 
            }
13654
 
            cur = cur->parent;
13655
 
        }
13656
 
        ctxt->instate = XML_PARSER_CONTENT;
13657
 
    }
13658
 
 
13659
 
    if ((ctxt->validate) || (ctxt->replaceEntities != 0)) {
13660
 
        /*
13661
 
         * ID/IDREF registration will be done in xmlValidateElement below
13662
 
         */
13663
 
        ctxt->loadsubset |= XML_SKIP_IDS;
13664
 
    }
13665
 
 
13666
 
#ifdef LIBXML_HTML_ENABLED
13667
 
    if (doc->type == XML_HTML_DOCUMENT_NODE)
13668
 
        __htmlParseContent(ctxt);
13669
 
    else
13670
 
#endif
13671
 
        xmlParseContent(ctxt);
13672
 
 
13673
 
    nsPop(ctxt, nsnr);
13674
 
    if ((RAW == '<') && (NXT(1) == '/')) {
13675
 
        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13676
 
    } else if (RAW != 0) {
13677
 
        xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
13678
 
    }
13679
 
    if ((ctxt->node != NULL) && (ctxt->node != node)) {
13680
 
        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13681
 
        ctxt->wellFormed = 0;
13682
 
    }
13683
 
 
13684
 
    if (!ctxt->wellFormed) {
13685
 
        if (ctxt->errNo == 0)
13686
 
            ret = XML_ERR_INTERNAL_ERROR;
13687
 
        else
13688
 
            ret = (xmlParserErrors)ctxt->errNo;
13689
 
    } else {
13690
 
        ret = XML_ERR_OK;
13691
 
    }
13692
 
 
13693
 
    /*
13694
 
     * Return the newly created nodeset after unlinking it from
13695
 
     * the pseudo sibling.
13696
 
     */
13697
 
 
13698
 
    cur = fake->next;
13699
 
    fake->next = NULL;
13700
 
    node->last = fake;
13701
 
 
13702
 
    if (cur != NULL) {
13703
 
        cur->prev = NULL;
13704
 
    }
13705
 
 
13706
 
    *lst = cur;
13707
 
 
13708
 
    while (cur != NULL) {
13709
 
        cur->parent = NULL;
13710
 
        cur = cur->next;
13711
 
    }
13712
 
 
13713
 
    xmlUnlinkNode(fake);
13714
 
    xmlFreeNode(fake);
13715
 
 
13716
 
 
13717
 
    if (ret != XML_ERR_OK) {
13718
 
        xmlFreeNodeList(*lst);
13719
 
        *lst = NULL;
13720
 
    }
13721
 
 
13722
 
    if (doc->dict != NULL)
13723
 
        ctxt->dict = NULL;
13724
 
    xmlFreeParserCtxt(ctxt);
13725
 
 
13726
 
    return(ret);
13727
 
#else /* !SAX2 */
13728
 
    return(XML_ERR_INTERNAL_ERROR);
13729
 
#endif
13730
 
}
13731
 
 
13732
 
#ifdef LIBXML_SAX1_ENABLED
13733
 
/**
13734
 
 * xmlParseBalancedChunkMemoryRecover:
13735
 
 * @doc:  the document the chunk pertains to
13736
 
 * @sax:  the SAX handler bloc (possibly NULL)
13737
 
 * @user_data:  The user data returned on SAX callbacks (possibly NULL)
13738
 
 * @depth:  Used for loop detection, use 0
13739
 
 * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
13740
 
 * @lst:  the return value for the set of parsed nodes
13741
 
 * @recover: return nodes even if the data is broken (use 0)
13742
 
 *
13743
 
 *
13744
 
 * Parse a well-balanced chunk of an XML document
13745
 
 * called by the parser
13746
 
 * The allowed sequence for the Well Balanced Chunk is the one defined by
13747
 
 * the content production in the XML grammar:
13748
 
 *
13749
 
 * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
13750
 
 *
13751
 
 * Returns 0 if the chunk is well balanced, -1 in case of args problem and
13752
 
 *    the parser error code otherwise
13753
 
 *
13754
 
 * In case recover is set to 1, the nodelist will not be empty even if
13755
 
 * the parsed chunk is not well balanced, assuming the parsing succeeded to
13756
 
 * some extent.
13757
 
 */
13758
 
int
13759
 
xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax,
13760
 
     void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst,
13761
 
     int recover) {
13762
 
    xmlParserCtxtPtr ctxt;
13763
 
    xmlDocPtr newDoc;
13764
 
    xmlSAXHandlerPtr oldsax = NULL;
13765
 
    xmlNodePtr content, newRoot;
13766
 
    int size;
13767
 
    int ret = 0;
13768
 
 
13769
 
    if (depth > 40) {
13770
 
        return(XML_ERR_ENTITY_LOOP);
13771
 
    }
13772
 
 
13773
 
 
13774
 
    if (lst != NULL)
13775
 
        *lst = NULL;
13776
 
    if (string == NULL)
13777
 
        return(-1);
13778
 
 
13779
 
    size = xmlStrlen(string);
13780
 
 
13781
 
    ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
13782
 
    if (ctxt == NULL) return(-1);
13783
 
    ctxt->userData = ctxt;
13784
 
    if (sax != NULL) {
13785
 
        oldsax = ctxt->sax;
13786
 
        ctxt->sax = sax;
13787
 
        if (user_data != NULL)
13788
 
            ctxt->userData = user_data;
13789
 
    }
13790
 
    newDoc = xmlNewDoc(BAD_CAST "1.0");
13791
 
    if (newDoc == NULL) {
13792
 
        xmlFreeParserCtxt(ctxt);
13793
 
        return(-1);
13794
 
    }
13795
 
    newDoc->properties = XML_DOC_INTERNAL;
13796
 
    if ((doc != NULL) && (doc->dict != NULL)) {
13797
 
        xmlDictFree(ctxt->dict);
13798
 
        ctxt->dict = doc->dict;
13799
 
        xmlDictReference(ctxt->dict);
13800
 
        ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
13801
 
        ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
13802
 
        ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
13803
 
        ctxt->dictNames = 1;
13804
 
    } else {
13805
 
        xmlCtxtUseOptionsInternal(ctxt, XML_PARSE_NODICT, NULL);
13806
 
    }
13807
 
    if (doc != NULL) {
13808
 
        newDoc->intSubset = doc->intSubset;
13809
 
        newDoc->extSubset = doc->extSubset;
13810
 
    }
13811
 
    newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
13812
 
    if (newRoot == NULL) {
13813
 
        if (sax != NULL)
13814
 
            ctxt->sax = oldsax;
13815
 
        xmlFreeParserCtxt(ctxt);
13816
 
        newDoc->intSubset = NULL;
13817
 
        newDoc->extSubset = NULL;
13818
 
        xmlFreeDoc(newDoc);
13819
 
        return(-1);
13820
 
    }
13821
 
    xmlAddChild((xmlNodePtr) newDoc, newRoot);
13822
 
    nodePush(ctxt, newRoot);
13823
 
    if (doc == NULL) {
13824
 
        ctxt->myDoc = newDoc;
13825
 
    } else {
13826
 
        ctxt->myDoc = newDoc;
13827
 
        newDoc->children->doc = doc;
13828
 
        /* Ensure that doc has XML spec namespace */
13829
 
        xmlSearchNsByHref(doc, (xmlNodePtr)doc, XML_XML_NAMESPACE);
13830
 
        newDoc->oldNs = doc->oldNs;
13831
 
    }
13832
 
    ctxt->instate = XML_PARSER_CONTENT;
13833
 
    ctxt->depth = depth;
13834
 
 
13835
 
    /*
13836
 
     * Doing validity checking on chunk doesn't make sense
13837
 
     */
13838
 
    ctxt->validate = 0;
13839
 
    ctxt->loadsubset = 0;
13840
 
    xmlDetectSAX2(ctxt);
13841
 
 
13842
 
    if ( doc != NULL ){
13843
 
        content = doc->children;
13844
 
        doc->children = NULL;
13845
 
        xmlParseContent(ctxt);
13846
 
        doc->children = content;
13847
 
    }
13848
 
    else {
13849
 
        xmlParseContent(ctxt);
13850
 
    }
13851
 
    if ((RAW == '<') && (NXT(1) == '/')) {
13852
 
        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13853
 
    } else if (RAW != 0) {
13854
 
        xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
13855
 
    }
13856
 
    if (ctxt->node != newDoc->children) {
13857
 
        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
13858
 
    }
13859
 
 
13860
 
    if (!ctxt->wellFormed) {
13861
 
        if (ctxt->errNo == 0)
13862
 
            ret = 1;
13863
 
        else
13864
 
            ret = ctxt->errNo;
13865
 
    } else {
13866
 
      ret = 0;
13867
 
    }
13868
 
 
13869
 
    if ((lst != NULL) && ((ret == 0) || (recover == 1))) {
13870
 
        xmlNodePtr cur;
13871
 
 
13872
 
        /*
13873
 
         * Return the newly created nodeset after unlinking it from
13874
 
         * they pseudo parent.
13875
 
         */
13876
 
        cur = newDoc->children->children;
13877
 
        *lst = cur;
13878
 
        while (cur != NULL) {
13879
 
            xmlSetTreeDoc(cur, doc);
13880
 
            cur->parent = NULL;
13881
 
            cur = cur->next;
13882
 
        }
13883
 
        newDoc->children->children = NULL;
13884
 
    }
13885
 
 
13886
 
    if (sax != NULL)
13887
 
        ctxt->sax = oldsax;
13888
 
    xmlFreeParserCtxt(ctxt);
13889
 
    newDoc->intSubset = NULL;
13890
 
    newDoc->extSubset = NULL;
13891
 
    newDoc->oldNs = NULL;
13892
 
    xmlFreeDoc(newDoc);
13893
 
 
13894
 
    return(ret);
13895
 
}
13896
 
 
13897
 
/**
13898
 
 * xmlSAXParseEntity:
13899
 
 * @sax:  the SAX handler block
13900
 
 * @filename:  the filename
13901
 
 *
13902
 
 * parse an XML external entity out of context and build a tree.
13903
 
 * It use the given SAX function block to handle the parsing callback.
13904
 
 * If sax is NULL, fallback to the default DOM tree building routines.
13905
 
 *
13906
 
 * [78] extParsedEnt ::= TextDecl? content
13907
 
 *
13908
 
 * This correspond to a "Well Balanced" chunk
13909
 
 *
13910
 
 * Returns the resulting document tree
13911
 
 */
13912
 
 
13913
 
xmlDocPtr
13914
 
xmlSAXParseEntity(xmlSAXHandlerPtr sax, const char *filename) {
13915
 
    xmlDocPtr ret;
13916
 
    xmlParserCtxtPtr ctxt;
13917
 
 
13918
 
    ctxt = xmlCreateFileParserCtxt(filename);
13919
 
    if (ctxt == NULL) {
13920
 
        return(NULL);
13921
 
    }
13922
 
    if (sax != NULL) {
13923
 
        if (ctxt->sax != NULL)
13924
 
            xmlFree(ctxt->sax);
13925
 
        ctxt->sax = sax;
13926
 
        ctxt->userData = NULL;
13927
 
    }
13928
 
 
13929
 
    xmlParseExtParsedEnt(ctxt);
13930
 
 
13931
 
    if (ctxt->wellFormed)
13932
 
        ret = ctxt->myDoc;
13933
 
    else {
13934
 
        ret = NULL;
13935
 
        xmlFreeDoc(ctxt->myDoc);
13936
 
        ctxt->myDoc = NULL;
13937
 
    }
13938
 
    if (sax != NULL)
13939
 
        ctxt->sax = NULL;
13940
 
    xmlFreeParserCtxt(ctxt);
13941
 
 
13942
 
    return(ret);
13943
 
}
13944
 
 
13945
 
/**
13946
 
 * xmlParseEntity:
13947
 
 * @filename:  the filename
13948
 
 *
13949
 
 * parse an XML external entity out of context and build a tree.
13950
 
 *
13951
 
 * [78] extParsedEnt ::= TextDecl? content
13952
 
 *
13953
 
 * This correspond to a "Well Balanced" chunk
13954
 
 *
13955
 
 * Returns the resulting document tree
13956
 
 */
13957
 
 
13958
 
xmlDocPtr
13959
 
xmlParseEntity(const char *filename) {
13960
 
    return(xmlSAXParseEntity(NULL, filename));
13961
 
}
13962
 
#endif /* LIBXML_SAX1_ENABLED */
13963
 
 
13964
 
/**
13965
 
 * xmlCreateEntityParserCtxtInternal:
13966
 
 * @URL:  the entity URL
13967
 
 * @ID:  the entity PUBLIC ID
13968
 
 * @base:  a possible base for the target URI
13969
 
 * @pctx:  parser context used to set options on new context
13970
 
 *
13971
 
 * Create a parser context for an external entity
13972
 
 * Automatic support for ZLIB/Compress compressed document is provided
13973
 
 * by default if found at compile-time.
13974
 
 *
13975
 
 * Returns the new parser context or NULL
13976
 
 */
13977
 
static xmlParserCtxtPtr
13978
 
xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
13979
 
                          const xmlChar *base, xmlParserCtxtPtr pctx) {
13980
 
    xmlParserCtxtPtr ctxt;
13981
 
    xmlParserInputPtr inputStream;
13982
 
    char *directory = NULL;
13983
 
    xmlChar *uri;
13984
 
 
13985
 
    ctxt = xmlNewParserCtxt();
13986
 
    if (ctxt == NULL) {
13987
 
        return(NULL);
13988
 
    }
13989
 
 
13990
 
    if (pctx != NULL) {
13991
 
        ctxt->options = pctx->options;
13992
 
        ctxt->_private = pctx->_private;
13993
 
    }
13994
 
 
13995
 
    uri = xmlBuildURI(URL, base);
13996
 
 
13997
 
    if (uri == NULL) {
13998
 
        inputStream = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt);
13999
 
        if (inputStream == NULL) {
14000
 
            xmlFreeParserCtxt(ctxt);
14001
 
            return(NULL);
14002
 
        }
14003
 
 
14004
 
        inputPush(ctxt, inputStream);
14005
 
 
14006
 
        if ((ctxt->directory == NULL) && (directory == NULL))
14007
 
            directory = xmlParserGetDirectory((char *)URL);
14008
 
        if ((ctxt->directory == NULL) && (directory != NULL))
14009
 
            ctxt->directory = directory;
14010
 
    } else {
14011
 
        inputStream = xmlLoadExternalEntity((char *)uri, (char *)ID, ctxt);
14012
 
        if (inputStream == NULL) {
14013
 
            xmlFree(uri);
14014
 
            xmlFreeParserCtxt(ctxt);
14015
 
            return(NULL);
14016
 
        }
14017
 
 
14018
 
        inputPush(ctxt, inputStream);
14019
 
 
14020
 
        if ((ctxt->directory == NULL) && (directory == NULL))
14021
 
            directory = xmlParserGetDirectory((char *)uri);
14022
 
        if ((ctxt->directory == NULL) && (directory != NULL))
14023
 
            ctxt->directory = directory;
14024
 
        xmlFree(uri);
14025
 
    }
14026
 
    return(ctxt);
14027
 
}
14028
 
 
14029
 
/**
14030
 
 * xmlCreateEntityParserCtxt:
14031
 
 * @URL:  the entity URL
14032
 
 * @ID:  the entity PUBLIC ID
14033
 
 * @base:  a possible base for the target URI
14034
 
 *
14035
 
 * Create a parser context for an external entity
14036
 
 * Automatic support for ZLIB/Compress compressed document is provided
14037
 
 * by default if found at compile-time.
14038
 
 *
14039
 
 * Returns the new parser context or NULL
14040
 
 */
14041
 
xmlParserCtxtPtr
14042
 
xmlCreateEntityParserCtxt(const xmlChar *URL, const xmlChar *ID,
14043
 
                          const xmlChar *base) {
14044
 
    return xmlCreateEntityParserCtxtInternal(URL, ID, base, NULL);
14045
 
 
14046
 
}
14047
 
 
14048
 
/************************************************************************
14049
 
 *                                                                      *
14050
 
 *              Front ends when parsing from a file                     *
14051
 
 *                                                                      *
14052
 
 ************************************************************************/
14053
 
 
14054
 
/**
14055
 
 * xmlCreateURLParserCtxt:
14056
 
 * @filename:  the filename or URL
14057
 
 * @options:  a combination of xmlParserOption
14058
 
 *
14059
 
 * Create a parser context for a file or URL content.
14060
 
 * Automatic support for ZLIB/Compress compressed document is provided
14061
 
 * by default if found at compile-time and for file accesses
14062
 
 *
14063
 
 * Returns the new parser context or NULL
14064
 
 */
14065
 
xmlParserCtxtPtr
14066
 
xmlCreateURLParserCtxt(const char *filename, int options)
14067
 
{
14068
 
    xmlParserCtxtPtr ctxt;
14069
 
    xmlParserInputPtr inputStream;
14070
 
    char *directory = NULL;
14071
 
 
14072
 
    ctxt = xmlNewParserCtxt();
14073
 
    if (ctxt == NULL) {
14074
 
        xmlErrMemory(NULL, "cannot allocate parser context");
14075
 
        return(NULL);
14076
 
    }
14077
 
 
14078
 
    if (options)
14079
 
        xmlCtxtUseOptionsInternal(ctxt, options, NULL);
14080
 
    ctxt->linenumbers = 1;
14081
 
 
14082
 
    inputStream = xmlLoadExternalEntity(filename, NULL, ctxt);
14083
 
    if (inputStream == NULL) {
14084
 
        xmlFreeParserCtxt(ctxt);
14085
 
        return(NULL);
14086
 
    }
14087
 
 
14088
 
    inputPush(ctxt, inputStream);
14089
 
    if ((ctxt->directory == NULL) && (directory == NULL))
14090
 
        directory = xmlParserGetDirectory(filename);
14091
 
    if ((ctxt->directory == NULL) && (directory != NULL))
14092
 
        ctxt->directory = directory;
14093
 
 
14094
 
    return(ctxt);
14095
 
}
14096
 
 
14097
 
/**
14098
 
 * xmlCreateFileParserCtxt:
14099
 
 * @filename:  the filename
14100
 
 *
14101
 
 * Create a parser context for a file content.
14102
 
 * Automatic support for ZLIB/Compress compressed document is provided
14103
 
 * by default if found at compile-time.
14104
 
 *
14105
 
 * Returns the new parser context or NULL
14106
 
 */
14107
 
xmlParserCtxtPtr
14108
 
xmlCreateFileParserCtxt(const char *filename)
14109
 
{
14110
 
    return(xmlCreateURLParserCtxt(filename, 0));
14111
 
}
14112
 
 
14113
 
#ifdef LIBXML_SAX1_ENABLED
14114
 
/**
14115
 
 * xmlSAXParseFileWithData:
14116
 
 * @sax:  the SAX handler block
14117
 
 * @filename:  the filename
14118
 
 * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
14119
 
 *             documents
14120
 
 * @data:  the userdata
14121
 
 *
14122
 
 * parse an XML file and build a tree. Automatic support for ZLIB/Compress
14123
 
 * compressed document is provided by default if found at compile-time.
14124
 
 * It use the given SAX function block to handle the parsing callback.
14125
 
 * If sax is NULL, fallback to the default DOM tree building routines.
14126
 
 *
14127
 
 * User data (void *) is stored within the parser context in the
14128
 
 * context's _private member, so it is available nearly everywhere in libxml
14129
 
 *
14130
 
 * Returns the resulting document tree
14131
 
 */
14132
 
 
14133
 
xmlDocPtr
14134
 
xmlSAXParseFileWithData(xmlSAXHandlerPtr sax, const char *filename,
14135
 
                        int recovery, void *data) {
14136
 
    xmlDocPtr ret;
14137
 
    xmlParserCtxtPtr ctxt;
14138
 
 
14139
 
    xmlInitParser();
14140
 
 
14141
 
    ctxt = xmlCreateFileParserCtxt(filename);
14142
 
    if (ctxt == NULL) {
14143
 
        return(NULL);
14144
 
    }
14145
 
    if (sax != NULL) {
14146
 
        if (ctxt->sax != NULL)
14147
 
            xmlFree(ctxt->sax);
14148
 
        ctxt->sax = sax;
14149
 
    }
14150
 
    xmlDetectSAX2(ctxt);
14151
 
    if (data!=NULL) {
14152
 
        ctxt->_private = data;
14153
 
    }
14154
 
 
14155
 
    if (ctxt->directory == NULL)
14156
 
        ctxt->directory = xmlParserGetDirectory(filename);
14157
 
 
14158
 
    ctxt->recovery = recovery;
14159
 
 
14160
 
    xmlParseDocument(ctxt);
14161
 
 
14162
 
    if ((ctxt->wellFormed) || recovery) {
14163
 
        ret = ctxt->myDoc;
14164
 
        if (ret != NULL) {
14165
 
            if (ctxt->input->buf->compressed > 0)
14166
 
                ret->compression = 9;
14167
 
            else
14168
 
                ret->compression = ctxt->input->buf->compressed;
14169
 
        }
14170
 
    }
14171
 
    else {
14172
 
       ret = NULL;
14173
 
       xmlFreeDoc(ctxt->myDoc);
14174
 
       ctxt->myDoc = NULL;
14175
 
    }
14176
 
    if (sax != NULL)
14177
 
        ctxt->sax = NULL;
14178
 
    xmlFreeParserCtxt(ctxt);
14179
 
 
14180
 
    return(ret);
14181
 
}
14182
 
 
14183
 
/**
14184
 
 * xmlSAXParseFile:
14185
 
 * @sax:  the SAX handler block
14186
 
 * @filename:  the filename
14187
 
 * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
14188
 
 *             documents
14189
 
 *
14190
 
 * parse an XML file and build a tree. Automatic support for ZLIB/Compress
14191
 
 * compressed document is provided by default if found at compile-time.
14192
 
 * It use the given SAX function block to handle the parsing callback.
14193
 
 * If sax is NULL, fallback to the default DOM tree building routines.
14194
 
 *
14195
 
 * Returns the resulting document tree
14196
 
 */
14197
 
 
14198
 
xmlDocPtr
14199
 
xmlSAXParseFile(xmlSAXHandlerPtr sax, const char *filename,
14200
 
                          int recovery) {
14201
 
    return(xmlSAXParseFileWithData(sax,filename,recovery,NULL));
14202
 
}
14203
 
 
14204
 
/**
14205
 
 * xmlRecoverDoc:
14206
 
 * @cur:  a pointer to an array of xmlChar
14207
 
 *
14208
 
 * parse an XML in-memory document and build a tree.
14209
 
 * In the case the document is not Well Formed, a attempt to build a
14210
 
 * tree is tried anyway
14211
 
 *
14212
 
 * Returns the resulting document tree or NULL in case of failure
14213
 
 */
14214
 
 
14215
 
xmlDocPtr
14216
 
xmlRecoverDoc(const xmlChar *cur) {
14217
 
    return(xmlSAXParseDoc(NULL, cur, 1));
14218
 
}
14219
 
 
14220
 
/**
14221
 
 * xmlParseFile:
14222
 
 * @filename:  the filename
14223
 
 *
14224
 
 * parse an XML file and build a tree. Automatic support for ZLIB/Compress
14225
 
 * compressed document is provided by default if found at compile-time.
14226
 
 *
14227
 
 * Returns the resulting document tree if the file was wellformed,
14228
 
 * NULL otherwise.
14229
 
 */
14230
 
 
14231
 
xmlDocPtr
14232
 
xmlParseFile(const char *filename) {
14233
 
    return(xmlSAXParseFile(NULL, filename, 0));
14234
 
}
14235
 
 
14236
 
/**
14237
 
 * xmlRecoverFile:
14238
 
 * @filename:  the filename
14239
 
 *
14240
 
 * parse an XML file and build a tree. Automatic support for ZLIB/Compress
14241
 
 * compressed document is provided by default if found at compile-time.
14242
 
 * In the case the document is not Well Formed, it attempts to build
14243
 
 * a tree anyway
14244
 
 *
14245
 
 * Returns the resulting document tree or NULL in case of failure
14246
 
 */
14247
 
 
14248
 
xmlDocPtr
14249
 
xmlRecoverFile(const char *filename) {
14250
 
    return(xmlSAXParseFile(NULL, filename, 1));
14251
 
}
14252
 
 
14253
 
 
14254
 
/**
14255
 
 * xmlSetupParserForBuffer:
14256
 
 * @ctxt:  an XML parser context
14257
 
 * @buffer:  a xmlChar * buffer
14258
 
 * @filename:  a file name
14259
 
 *
14260
 
 * Setup the parser context to parse a new buffer; Clears any prior
14261
 
 * contents from the parser context. The buffer parameter must not be
14262
 
 * NULL, but the filename parameter can be
14263
 
 */
14264
 
void
14265
 
xmlSetupParserForBuffer(xmlParserCtxtPtr ctxt, const xmlChar* buffer,
14266
 
                             const char* filename)
14267
 
{
14268
 
    xmlParserInputPtr input;
14269
 
 
14270
 
    if ((ctxt == NULL) || (buffer == NULL))
14271
 
        return;
14272
 
 
14273
 
    input = xmlNewInputStream(ctxt);
14274
 
    if (input == NULL) {
14275
 
        xmlErrMemory(NULL, "parsing new buffer: out of memory\n");
14276
 
        xmlClearParserCtxt(ctxt);
14277
 
        return;
14278
 
    }
14279
 
 
14280
 
    xmlClearParserCtxt(ctxt);
14281
 
    if (filename != NULL)
14282
 
        input->filename = (char *) xmlCanonicPath((const xmlChar *)filename);
14283
 
    input->base = buffer;
14284
 
    input->cur = buffer;
14285
 
    input->end = &buffer[xmlStrlen(buffer)];
14286
 
    inputPush(ctxt, input);
14287
 
}
14288
 
 
14289
 
/**
14290
 
 * xmlSAXUserParseFile:
14291
 
 * @sax:  a SAX handler
14292
 
 * @user_data:  The user data returned on SAX callbacks
14293
 
 * @filename:  a file name
14294
 
 *
14295
 
 * parse an XML file and call the given SAX handler routines.
14296
 
 * Automatic support for ZLIB/Compress compressed document is provided
14297
 
 *
14298
 
 * Returns 0 in case of success or a error number otherwise
14299
 
 */
14300
 
int
14301
 
xmlSAXUserParseFile(xmlSAXHandlerPtr sax, void *user_data,
14302
 
                    const char *filename) {
14303
 
    int ret = 0;
14304
 
    xmlParserCtxtPtr ctxt;
14305
 
 
14306
 
    ctxt = xmlCreateFileParserCtxt(filename);
14307
 
    if (ctxt == NULL) return -1;
14308
 
    if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
14309
 
        xmlFree(ctxt->sax);
14310
 
    ctxt->sax = sax;
14311
 
    xmlDetectSAX2(ctxt);
14312
 
 
14313
 
    if (user_data != NULL)
14314
 
        ctxt->userData = user_data;
14315
 
 
14316
 
    xmlParseDocument(ctxt);
14317
 
 
14318
 
    if (ctxt->wellFormed)
14319
 
        ret = 0;
14320
 
    else {
14321
 
        if (ctxt->errNo != 0)
14322
 
            ret = ctxt->errNo;
14323
 
        else
14324
 
            ret = -1;
14325
 
    }
14326
 
    if (sax != NULL)
14327
 
        ctxt->sax = NULL;
14328
 
    if (ctxt->myDoc != NULL) {
14329
 
        xmlFreeDoc(ctxt->myDoc);
14330
 
        ctxt->myDoc = NULL;
14331
 
    }
14332
 
    xmlFreeParserCtxt(ctxt);
14333
 
 
14334
 
    return ret;
14335
 
}
14336
 
#endif /* LIBXML_SAX1_ENABLED */
14337
 
 
14338
 
/************************************************************************
14339
 
 *                                                                      *
14340
 
 *              Front ends when parsing from memory                     *
14341
 
 *                                                                      *
14342
 
 ************************************************************************/
14343
 
 
14344
 
/**
14345
 
 * xmlCreateMemoryParserCtxt:
14346
 
 * @buffer:  a pointer to a char array
14347
 
 * @size:  the size of the array
14348
 
 *
14349
 
 * Create a parser context for an XML in-memory document.
14350
 
 *
14351
 
 * Returns the new parser context or NULL
14352
 
 */
14353
 
xmlParserCtxtPtr
14354
 
xmlCreateMemoryParserCtxt(const char *buffer, int size) {
14355
 
    xmlParserCtxtPtr ctxt;
14356
 
    xmlParserInputPtr input;
14357
 
    xmlParserInputBufferPtr buf;
14358
 
 
14359
 
    if (buffer == NULL)
14360
 
        return(NULL);
14361
 
    if (size <= 0)
14362
 
        return(NULL);
14363
 
 
14364
 
    ctxt = xmlNewParserCtxt();
14365
 
    if (ctxt == NULL)
14366
 
        return(NULL);
14367
 
 
14368
 
    /* TODO: xmlParserInputBufferCreateStatic, requires some serious changes */
14369
 
    buf = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
14370
 
    if (buf == NULL) {
14371
 
        xmlFreeParserCtxt(ctxt);
14372
 
        return(NULL);
14373
 
    }
14374
 
 
14375
 
    input = xmlNewInputStream(ctxt);
14376
 
    if (input == NULL) {
14377
 
        xmlFreeParserInputBuffer(buf);
14378
 
        xmlFreeParserCtxt(ctxt);
14379
 
        return(NULL);
14380
 
    }
14381
 
 
14382
 
    input->filename = NULL;
14383
 
    input->buf = buf;
14384
 
    xmlBufResetInput(input->buf->buffer, input);
14385
 
 
14386
 
    inputPush(ctxt, input);
14387
 
    return(ctxt);
14388
 
}
14389
 
 
14390
 
#ifdef LIBXML_SAX1_ENABLED
14391
 
/**
14392
 
 * xmlSAXParseMemoryWithData:
14393
 
 * @sax:  the SAX handler block
14394
 
 * @buffer:  an pointer to a char array
14395
 
 * @size:  the size of the array
14396
 
 * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
14397
 
 *             documents
14398
 
 * @data:  the userdata
14399
 
 *
14400
 
 * parse an XML in-memory block and use the given SAX function block
14401
 
 * to handle the parsing callback. If sax is NULL, fallback to the default
14402
 
 * DOM tree building routines.
14403
 
 *
14404
 
 * User data (void *) is stored within the parser context in the
14405
 
 * context's _private member, so it is available nearly everywhere in libxml
14406
 
 *
14407
 
 * Returns the resulting document tree
14408
 
 */
14409
 
 
14410
 
xmlDocPtr
14411
 
xmlSAXParseMemoryWithData(xmlSAXHandlerPtr sax, const char *buffer,
14412
 
                  int size, int recovery, void *data) {
14413
 
    xmlDocPtr ret;
14414
 
    xmlParserCtxtPtr ctxt;
14415
 
 
14416
 
    xmlInitParser();
14417
 
 
14418
 
    ctxt = xmlCreateMemoryParserCtxt(buffer, size);
14419
 
    if (ctxt == NULL) return(NULL);
14420
 
    if (sax != NULL) {
14421
 
        if (ctxt->sax != NULL)
14422
 
            xmlFree(ctxt->sax);
14423
 
        ctxt->sax = sax;
14424
 
    }
14425
 
    xmlDetectSAX2(ctxt);
14426
 
    if (data!=NULL) {
14427
 
        ctxt->_private=data;
14428
 
    }
14429
 
 
14430
 
    ctxt->recovery = recovery;
14431
 
 
14432
 
    xmlParseDocument(ctxt);
14433
 
 
14434
 
    if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
14435
 
    else {
14436
 
       ret = NULL;
14437
 
       xmlFreeDoc(ctxt->myDoc);
14438
 
       ctxt->myDoc = NULL;
14439
 
    }
14440
 
    if (sax != NULL)
14441
 
        ctxt->sax = NULL;
14442
 
    xmlFreeParserCtxt(ctxt);
14443
 
 
14444
 
    return(ret);
14445
 
}
14446
 
 
14447
 
/**
14448
 
 * xmlSAXParseMemory:
14449
 
 * @sax:  the SAX handler block
14450
 
 * @buffer:  an pointer to a char array
14451
 
 * @size:  the size of the array
14452
 
 * @recovery:  work in recovery mode, i.e. tries to read not Well Formed
14453
 
 *             documents
14454
 
 *
14455
 
 * parse an XML in-memory block and use the given SAX function block
14456
 
 * to handle the parsing callback. If sax is NULL, fallback to the default
14457
 
 * DOM tree building routines.
14458
 
 *
14459
 
 * Returns the resulting document tree
14460
 
 */
14461
 
xmlDocPtr
14462
 
xmlSAXParseMemory(xmlSAXHandlerPtr sax, const char *buffer,
14463
 
                  int size, int recovery) {
14464
 
    return xmlSAXParseMemoryWithData(sax, buffer, size, recovery, NULL);
14465
 
}
14466
 
 
14467
 
/**
14468
 
 * xmlParseMemory:
14469
 
 * @buffer:  an pointer to a char array
14470
 
 * @size:  the size of the array
14471
 
 *
14472
 
 * parse an XML in-memory block and build a tree.
14473
 
 *
14474
 
 * Returns the resulting document tree
14475
 
 */
14476
 
 
14477
 
xmlDocPtr xmlParseMemory(const char *buffer, int size) {
14478
 
   return(xmlSAXParseMemory(NULL, buffer, size, 0));
14479
 
}
14480
 
 
14481
 
/**
14482
 
 * xmlRecoverMemory:
14483
 
 * @buffer:  an pointer to a char array
14484
 
 * @size:  the size of the array
14485
 
 *
14486
 
 * parse an XML in-memory block and build a tree.
14487
 
 * In the case the document is not Well Formed, an attempt to
14488
 
 * build a tree is tried anyway
14489
 
 *
14490
 
 * Returns the resulting document tree or NULL in case of error
14491
 
 */
14492
 
 
14493
 
xmlDocPtr xmlRecoverMemory(const char *buffer, int size) {
14494
 
   return(xmlSAXParseMemory(NULL, buffer, size, 1));
14495
 
}
14496
 
 
14497
 
/**
14498
 
 * xmlSAXUserParseMemory:
14499
 
 * @sax:  a SAX handler
14500
 
 * @user_data:  The user data returned on SAX callbacks
14501
 
 * @buffer:  an in-memory XML document input
14502
 
 * @size:  the length of the XML document in bytes
14503
 
 *
14504
 
 * A better SAX parsing routine.
14505
 
 * parse an XML in-memory buffer and call the given SAX handler routines.
14506
 
 *
14507
 
 * Returns 0 in case of success or a error number otherwise
14508
 
 */
14509
 
int xmlSAXUserParseMemory(xmlSAXHandlerPtr sax, void *user_data,
14510
 
                          const char *buffer, int size) {
14511
 
    int ret = 0;
14512
 
    xmlParserCtxtPtr ctxt;
14513
 
 
14514
 
    xmlInitParser();
14515
 
 
14516
 
    ctxt = xmlCreateMemoryParserCtxt(buffer, size);
14517
 
    if (ctxt == NULL) return -1;
14518
 
    if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
14519
 
        xmlFree(ctxt->sax);
14520
 
    ctxt->sax = sax;
14521
 
    xmlDetectSAX2(ctxt);
14522
 
 
14523
 
    if (user_data != NULL)
14524
 
        ctxt->userData = user_data;
14525
 
 
14526
 
    xmlParseDocument(ctxt);
14527
 
 
14528
 
    if (ctxt->wellFormed)
14529
 
        ret = 0;
14530
 
    else {
14531
 
        if (ctxt->errNo != 0)
14532
 
            ret = ctxt->errNo;
14533
 
        else
14534
 
            ret = -1;
14535
 
    }
14536
 
    if (sax != NULL)
14537
 
        ctxt->sax = NULL;
14538
 
    if (ctxt->myDoc != NULL) {
14539
 
        xmlFreeDoc(ctxt->myDoc);
14540
 
        ctxt->myDoc = NULL;
14541
 
    }
14542
 
    xmlFreeParserCtxt(ctxt);
14543
 
 
14544
 
    return ret;
14545
 
}
14546
 
#endif /* LIBXML_SAX1_ENABLED */
14547
 
 
14548
 
/**
14549
 
 * xmlCreateDocParserCtxt:
14550
 
 * @cur:  a pointer to an array of xmlChar
14551
 
 *
14552
 
 * Creates a parser context for an XML in-memory document.
14553
 
 *
14554
 
 * Returns the new parser context or NULL
14555
 
 */
14556
 
xmlParserCtxtPtr
14557
 
xmlCreateDocParserCtxt(const xmlChar *cur) {
14558
 
    int len;
14559
 
 
14560
 
    if (cur == NULL)
14561
 
        return(NULL);
14562
 
    len = xmlStrlen(cur);
14563
 
    return(xmlCreateMemoryParserCtxt((const char *)cur, len));
14564
 
}
14565
 
 
14566
 
#ifdef LIBXML_SAX1_ENABLED
14567
 
/**
14568
 
 * xmlSAXParseDoc:
14569
 
 * @sax:  the SAX handler block
14570
 
 * @cur:  a pointer to an array of xmlChar
14571
 
 * @recovery:  work in recovery mode, i.e. tries to read no Well Formed
14572
 
 *             documents
14573
 
 *
14574
 
 * parse an XML in-memory document and build a tree.
14575
 
 * It use the given SAX function block to handle the parsing callback.
14576
 
 * If sax is NULL, fallback to the default DOM tree building routines.
14577
 
 *
14578
 
 * Returns the resulting document tree
14579
 
 */
14580
 
 
14581
 
xmlDocPtr
14582
 
xmlSAXParseDoc(xmlSAXHandlerPtr sax, const xmlChar *cur, int recovery) {
14583
 
    xmlDocPtr ret;
14584
 
    xmlParserCtxtPtr ctxt;
14585
 
    xmlSAXHandlerPtr oldsax = NULL;
14586
 
 
14587
 
    if (cur == NULL) return(NULL);
14588
 
 
14589
 
 
14590
 
    ctxt = xmlCreateDocParserCtxt(cur);
14591
 
    if (ctxt == NULL) return(NULL);
14592
 
    if (sax != NULL) {
14593
 
        oldsax = ctxt->sax;
14594
 
        ctxt->sax = sax;
14595
 
        ctxt->userData = NULL;
14596
 
    }
14597
 
    xmlDetectSAX2(ctxt);
14598
 
 
14599
 
    xmlParseDocument(ctxt);
14600
 
    if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
14601
 
    else {
14602
 
       ret = NULL;
14603
 
       xmlFreeDoc(ctxt->myDoc);
14604
 
       ctxt->myDoc = NULL;
14605
 
    }
14606
 
    if (sax != NULL)
14607
 
        ctxt->sax = oldsax;
14608
 
    xmlFreeParserCtxt(ctxt);
14609
 
 
14610
 
    return(ret);
14611
 
}
14612
 
 
14613
 
/**
14614
 
 * xmlParseDoc:
14615
 
 * @cur:  a pointer to an array of xmlChar
14616
 
 *
14617
 
 * parse an XML in-memory document and build a tree.
14618
 
 *
14619
 
 * Returns the resulting document tree
14620
 
 */
14621
 
 
14622
 
xmlDocPtr
14623
 
xmlParseDoc(const xmlChar *cur) {
14624
 
    return(xmlSAXParseDoc(NULL, cur, 0));
14625
 
}
14626
 
#endif /* LIBXML_SAX1_ENABLED */
14627
 
 
14628
 
#ifdef LIBXML_LEGACY_ENABLED
14629
 
/************************************************************************
14630
 
 *                                                                      *
14631
 
 *      Specific function to keep track of entities references          *
14632
 
 *      and used by the XSLT debugger                                   *
14633
 
 *                                                                      *
14634
 
 ************************************************************************/
14635
 
 
14636
 
static xmlEntityReferenceFunc xmlEntityRefFunc = NULL;
14637
 
 
14638
 
/**
14639
 
 * xmlAddEntityReference:
14640
 
 * @ent : A valid entity
14641
 
 * @firstNode : A valid first node for children of entity
14642
 
 * @lastNode : A valid last node of children entity
14643
 
 *
14644
 
 * Notify of a reference to an entity of type XML_EXTERNAL_GENERAL_PARSED_ENTITY
14645
 
 */
14646
 
static void
14647
 
xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
14648
 
                      xmlNodePtr lastNode)
14649
 
{
14650
 
    if (xmlEntityRefFunc != NULL) {
14651
 
        (*xmlEntityRefFunc) (ent, firstNode, lastNode);
14652
 
    }
14653
 
}
14654
 
 
14655
 
 
14656
 
/**
14657
 
 * xmlSetEntityReferenceFunc:
14658
 
 * @func: A valid function
14659
 
 *
14660
 
 * Set the function to call call back when a xml reference has been made
14661
 
 */
14662
 
void
14663
 
xmlSetEntityReferenceFunc(xmlEntityReferenceFunc func)
14664
 
{
14665
 
    xmlEntityRefFunc = func;
14666
 
}
14667
 
#endif /* LIBXML_LEGACY_ENABLED */
14668
 
 
14669
 
/************************************************************************
14670
 
 *                                                                      *
14671
 
 *                              Miscellaneous                           *
14672
 
 *                                                                      *
14673
 
 ************************************************************************/
14674
 
 
14675
 
#ifdef LIBXML_XPATH_ENABLED
14676
 
#include <libxml/xpath.h>
14677
 
#endif
14678
 
 
14679
 
extern void XMLCDECL xmlGenericErrorDefaultFunc(void *ctx, const char *msg, ...);
14680
 
static int xmlParserInitialized = 0;
14681
 
 
14682
 
/**
14683
 
 * xmlInitParser:
14684
 
 *
14685
 
 * Initialization function for the XML parser.
14686
 
 * This is not reentrant. Call once before processing in case of
14687
 
 * use in multithreaded programs.
14688
 
 */
14689
 
 
14690
 
void
14691
 
xmlInitParser(void) {
14692
 
    if (xmlParserInitialized != 0)
14693
 
        return;
14694
 
 
14695
 
#ifdef LIBXML_THREAD_ENABLED
14696
 
    __xmlGlobalInitMutexLock();
14697
 
    if (xmlParserInitialized == 0) {
14698
 
#endif
14699
 
        xmlInitThreads();
14700
 
        xmlInitGlobals();
14701
 
        if ((xmlGenericError == xmlGenericErrorDefaultFunc) ||
14702
 
            (xmlGenericError == NULL))
14703
 
            initGenericErrorDefaultFunc(NULL);
14704
 
        xmlInitMemory();
14705
 
        xmlInitializeDict();
14706
 
        xmlInitCharEncodingHandlers();
14707
 
        xmlDefaultSAXHandlerInit();
14708
 
        xmlRegisterDefaultInputCallbacks();
14709
 
#ifdef LIBXML_OUTPUT_ENABLED
14710
 
        xmlRegisterDefaultOutputCallbacks();
14711
 
#endif /* LIBXML_OUTPUT_ENABLED */
14712
 
#ifdef LIBXML_HTML_ENABLED
14713
 
        htmlInitAutoClose();
14714
 
        htmlDefaultSAXHandlerInit();
14715
 
#endif
14716
 
#ifdef LIBXML_XPATH_ENABLED
14717
 
        xmlXPathInit();
14718
 
#endif
14719
 
        xmlParserInitialized = 1;
14720
 
#ifdef LIBXML_THREAD_ENABLED
14721
 
    }
14722
 
    __xmlGlobalInitMutexUnlock();
14723
 
#endif
14724
 
}
14725
 
 
14726
 
/**
14727
 
 * xmlCleanupParser:
14728
 
 *
14729
 
 * This function name is somewhat misleading. It does not clean up
14730
 
 * parser state, it cleans up memory allocated by the library itself.
14731
 
 * It is a cleanup function for the XML library. It tries to reclaim all
14732
 
 * related global memory allocated for the library processing.
14733
 
 * It doesn't deallocate any document related memory. One should
14734
 
 * call xmlCleanupParser() only when the process has finished using
14735
 
 * the library and all XML/HTML documents built with it.
14736
 
 * See also xmlInitParser() which has the opposite function of preparing
14737
 
 * the library for operations.
14738
 
 *
14739
 
 * WARNING: if your application is multithreaded or has plugin support
14740
 
 *          calling this may crash the application if another thread or
14741
 
 *          a plugin is still using libxml2. It's sometimes very hard to
14742
 
 *          guess if libxml2 is in use in the application, some libraries
14743
 
 *          or plugins may use it without notice. In case of doubt abstain
14744
 
 *          from calling this function or do it just before calling exit()
14745
 
 *          to avoid leak reports from valgrind !
14746
 
 */
14747
 
 
14748
 
void
14749
 
xmlCleanupParser(void) {
14750
 
    if (!xmlParserInitialized)
14751
 
        return;
14752
 
 
14753
 
    xmlCleanupCharEncodingHandlers();
14754
 
#ifdef LIBXML_CATALOG_ENABLED
14755
 
    xmlCatalogCleanup();
14756
 
#endif
14757
 
    xmlDictCleanup();
14758
 
    xmlCleanupInputCallbacks();
14759
 
#ifdef LIBXML_OUTPUT_ENABLED
14760
 
    xmlCleanupOutputCallbacks();
14761
 
#endif
14762
 
#ifdef LIBXML_SCHEMAS_ENABLED
14763
 
    xmlSchemaCleanupTypes();
14764
 
    xmlRelaxNGCleanupTypes();
14765
 
#endif
14766
 
    xmlCleanupGlobals();
14767
 
    xmlResetLastError();
14768
 
    xmlCleanupThreads(); /* must be last if called not from the main thread */
14769
 
    xmlCleanupMemory();
14770
 
    xmlParserInitialized = 0;
14771
 
}
14772
 
 
14773
 
/************************************************************************
14774
 
 *                                                                      *
14775
 
 *      New set (2.6.0) of simpler and more flexible APIs               *
14776
 
 *                                                                      *
14777
 
 ************************************************************************/
14778
 
 
14779
 
/**
14780
 
 * DICT_FREE:
14781
 
 * @str:  a string
14782
 
 *
14783
 
 * Free a string if it is not owned by the "dict" dictionnary in the
14784
 
 * current scope
14785
 
 */
14786
 
#define DICT_FREE(str)                                          \
14787
 
        if ((str) && ((!dict) ||                                \
14788
 
            (xmlDictOwns(dict, (const xmlChar *)(str)) == 0)))  \
14789
 
            xmlFree((char *)(str));
14790
 
 
14791
 
/**
14792
 
 * xmlCtxtReset:
14793
 
 * @ctxt: an XML parser context
14794
 
 *
14795
 
 * Reset a parser context
14796
 
 */
14797
 
void
14798
 
xmlCtxtReset(xmlParserCtxtPtr ctxt)
14799
 
{
14800
 
    xmlParserInputPtr input;
14801
 
    xmlDictPtr dict;
14802
 
 
14803
 
    if (ctxt == NULL)
14804
 
        return;
14805
 
 
14806
 
    dict = ctxt->dict;
14807
 
 
14808
 
    while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
14809
 
        xmlFreeInputStream(input);
14810
 
    }
14811
 
    ctxt->inputNr = 0;
14812
 
    ctxt->input = NULL;
14813
 
 
14814
 
    ctxt->spaceNr = 0;
14815
 
    if (ctxt->spaceTab != NULL) {
14816
 
        ctxt->spaceTab[0] = -1;
14817
 
        ctxt->space = &ctxt->spaceTab[0];
14818
 
    } else {
14819
 
        ctxt->space = NULL;
14820
 
    }
14821
 
 
14822
 
 
14823
 
    ctxt->nodeNr = 0;
14824
 
    ctxt->node = NULL;
14825
 
 
14826
 
    ctxt->nameNr = 0;
14827
 
    ctxt->name = NULL;
14828
 
 
14829
 
    DICT_FREE(ctxt->version);
14830
 
    ctxt->version = NULL;
14831
 
    DICT_FREE(ctxt->encoding);
14832
 
    ctxt->encoding = NULL;
14833
 
    DICT_FREE(ctxt->directory);
14834
 
    ctxt->directory = NULL;
14835
 
    DICT_FREE(ctxt->extSubURI);
14836
 
    ctxt->extSubURI = NULL;
14837
 
    DICT_FREE(ctxt->extSubSystem);
14838
 
    ctxt->extSubSystem = NULL;
14839
 
    if (ctxt->myDoc != NULL)
14840
 
        xmlFreeDoc(ctxt->myDoc);
14841
 
    ctxt->myDoc = NULL;
14842
 
 
14843
 
    ctxt->standalone = -1;
14844
 
    ctxt->hasExternalSubset = 0;
14845
 
    ctxt->hasPErefs = 0;
14846
 
    ctxt->html = 0;
14847
 
    ctxt->external = 0;
14848
 
    ctxt->instate = XML_PARSER_START;
14849
 
    ctxt->token = 0;
14850
 
 
14851
 
    ctxt->wellFormed = 1;
14852
 
    ctxt->nsWellFormed = 1;
14853
 
    ctxt->disableSAX = 0;
14854
 
    ctxt->valid = 1;
14855
 
#if 0
14856
 
    ctxt->vctxt.userData = ctxt;
14857
 
    ctxt->vctxt.error = xmlParserValidityError;
14858
 
    ctxt->vctxt.warning = xmlParserValidityWarning;
14859
 
#endif
14860
 
    ctxt->record_info = 0;
14861
 
    ctxt->nbChars = 0;
14862
 
    ctxt->checkIndex = 0;
14863
 
    ctxt->inSubset = 0;
14864
 
    ctxt->errNo = XML_ERR_OK;
14865
 
    ctxt->depth = 0;
14866
 
    ctxt->charset = XML_CHAR_ENCODING_UTF8;
14867
 
    ctxt->catalogs = NULL;
14868
 
    ctxt->nbentities = 0;
14869
 
    ctxt->sizeentities = 0;
14870
 
    ctxt->sizeentcopy = 0;
14871
 
    xmlInitNodeInfoSeq(&ctxt->node_seq);
14872
 
 
14873
 
    if (ctxt->attsDefault != NULL) {
14874
 
        xmlHashFree(ctxt->attsDefault, (xmlHashDeallocator) xmlFree);
14875
 
        ctxt->attsDefault = NULL;
14876
 
    }
14877
 
    if (ctxt->attsSpecial != NULL) {
14878
 
        xmlHashFree(ctxt->attsSpecial, NULL);
14879
 
        ctxt->attsSpecial = NULL;
14880
 
    }
14881
 
 
14882
 
#ifdef LIBXML_CATALOG_ENABLED
14883
 
    if (ctxt->catalogs != NULL)
14884
 
        xmlCatalogFreeLocal(ctxt->catalogs);
14885
 
#endif
14886
 
    if (ctxt->lastError.code != XML_ERR_OK)
14887
 
        xmlResetError(&ctxt->lastError);
14888
 
}
14889
 
 
14890
 
/**
14891
 
 * xmlCtxtResetPush:
14892
 
 * @ctxt: an XML parser context
14893
 
 * @chunk:  a pointer to an array of chars
14894
 
 * @size:  number of chars in the array
14895
 
 * @filename:  an optional file name or URI
14896
 
 * @encoding:  the document encoding, or NULL
14897
 
 *
14898
 
 * Reset a push parser context
14899
 
 *
14900
 
 * Returns 0 in case of success and 1 in case of error
14901
 
 */
14902
 
int
14903
 
xmlCtxtResetPush(xmlParserCtxtPtr ctxt, const char *chunk,
14904
 
                 int size, const char *filename, const char *encoding)
14905
 
{
14906
 
    xmlParserInputPtr inputStream;
14907
 
    xmlParserInputBufferPtr buf;
14908
 
    xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
14909
 
 
14910
 
    if (ctxt == NULL)
14911
 
        return(1);
14912
 
 
14913
 
    if ((encoding == NULL) && (chunk != NULL) && (size >= 4))
14914
 
        enc = xmlDetectCharEncoding((const xmlChar *) chunk, size);
14915
 
 
14916
 
    buf = xmlAllocParserInputBuffer(enc);
14917
 
    if (buf == NULL)
14918
 
        return(1);
14919
 
 
14920
 
    if (ctxt == NULL) {
14921
 
        xmlFreeParserInputBuffer(buf);
14922
 
        return(1);
14923
 
    }
14924
 
 
14925
 
    xmlCtxtReset(ctxt);
14926
 
 
14927
 
    if (ctxt->pushTab == NULL) {
14928
 
        ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 *
14929
 
                                            sizeof(xmlChar *));
14930
 
        if (ctxt->pushTab == NULL) {
14931
 
            xmlErrMemory(ctxt, NULL);
14932
 
            xmlFreeParserInputBuffer(buf);
14933
 
            return(1);
14934
 
        }
14935
 
    }
14936
 
 
14937
 
    if (filename == NULL) {
14938
 
        ctxt->directory = NULL;
14939
 
    } else {
14940
 
        ctxt->directory = xmlParserGetDirectory(filename);
14941
 
    }
14942
 
 
14943
 
    inputStream = xmlNewInputStream(ctxt);
14944
 
    if (inputStream == NULL) {
14945
 
        xmlFreeParserInputBuffer(buf);
14946
 
        return(1);
14947
 
    }
14948
 
 
14949
 
    if (filename == NULL)
14950
 
        inputStream->filename = NULL;
14951
 
    else
14952
 
        inputStream->filename = (char *)
14953
 
            xmlCanonicPath((const xmlChar *) filename);
14954
 
    inputStream->buf = buf;
14955
 
    xmlBufResetInput(buf->buffer, inputStream);
14956
 
 
14957
 
    inputPush(ctxt, inputStream);
14958
 
 
14959
 
    if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
14960
 
        (ctxt->input->buf != NULL)) {
14961
 
        size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer, ctxt->input);
14962
 
        size_t cur = ctxt->input->cur - ctxt->input->base;
14963
 
 
14964
 
        xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
14965
 
 
14966
 
        xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur);
14967
 
#ifdef DEBUG_PUSH
14968
 
        xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
14969
 
#endif
14970
 
    }
14971
 
 
14972
 
    if (encoding != NULL) {
14973
 
        xmlCharEncodingHandlerPtr hdlr;
14974
 
 
14975
 
        if (ctxt->encoding != NULL)
14976
 
            xmlFree((xmlChar *) ctxt->encoding);
14977
 
        ctxt->encoding = xmlStrdup((const xmlChar *) encoding);
14978
 
 
14979
 
        hdlr = xmlFindCharEncodingHandler(encoding);
14980
 
        if (hdlr != NULL) {
14981
 
            xmlSwitchToEncoding(ctxt, hdlr);
14982
 
        } else {
14983
 
            xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
14984
 
                              "Unsupported encoding %s\n", BAD_CAST encoding);
14985
 
        }
14986
 
    } else if (enc != XML_CHAR_ENCODING_NONE) {
14987
 
        xmlSwitchEncoding(ctxt, enc);
14988
 
    }
14989
 
 
14990
 
    return(0);
14991
 
}
14992
 
 
14993
 
 
14994
 
/**
14995
 
 * xmlCtxtUseOptionsInternal:
14996
 
 * @ctxt: an XML parser context
14997
 
 * @options:  a combination of xmlParserOption
14998
 
 * @encoding:  the user provided encoding to use
14999
 
 *
15000
 
 * Applies the options to the parser context
15001
 
 *
15002
 
 * Returns 0 in case of success, the set of unknown or unimplemented options
15003
 
 *         in case of error.
15004
 
 */
15005
 
static int
15006
 
xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options, const char *encoding)
15007
 
{
15008
 
    if (ctxt == NULL)
15009
 
        return(-1);
15010
 
    if (encoding != NULL) {
15011
 
        if (ctxt->encoding != NULL)
15012
 
            xmlFree((xmlChar *) ctxt->encoding);
15013
 
        ctxt->encoding = xmlStrdup((const xmlChar *) encoding);
15014
 
    }
15015
 
    if (options & XML_PARSE_RECOVER) {
15016
 
        ctxt->recovery = 1;
15017
 
        options -= XML_PARSE_RECOVER;
15018
 
        ctxt->options |= XML_PARSE_RECOVER;
15019
 
    } else
15020
 
        ctxt->recovery = 0;
15021
 
    if (options & XML_PARSE_DTDLOAD) {
15022
 
        ctxt->loadsubset = XML_DETECT_IDS;
15023
 
        options -= XML_PARSE_DTDLOAD;
15024
 
        ctxt->options |= XML_PARSE_DTDLOAD;
15025
 
    } else
15026
 
        ctxt->loadsubset = 0;
15027
 
    if (options & XML_PARSE_DTDATTR) {
15028
 
        ctxt->loadsubset |= XML_COMPLETE_ATTRS;
15029
 
        options -= XML_PARSE_DTDATTR;
15030
 
        ctxt->options |= XML_PARSE_DTDATTR;
15031
 
    }
15032
 
    if (options & XML_PARSE_NOENT) {
15033
 
        ctxt->replaceEntities = 1;
15034
 
        /* ctxt->loadsubset |= XML_DETECT_IDS; */
15035
 
        options -= XML_PARSE_NOENT;
15036
 
        ctxt->options |= XML_PARSE_NOENT;
15037
 
    } else
15038
 
        ctxt->replaceEntities = 0;
15039
 
    if (options & XML_PARSE_PEDANTIC) {
15040
 
        ctxt->pedantic = 1;
15041
 
        options -= XML_PARSE_PEDANTIC;
15042
 
        ctxt->options |= XML_PARSE_PEDANTIC;
15043
 
    } else
15044
 
        ctxt->pedantic = 0;
15045
 
    if (options & XML_PARSE_NOBLANKS) {
15046
 
        ctxt->keepBlanks = 0;
15047
 
        ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
15048
 
        options -= XML_PARSE_NOBLANKS;
15049
 
        ctxt->options |= XML_PARSE_NOBLANKS;
15050
 
    } else
15051
 
        ctxt->keepBlanks = 1;
15052
 
    if (options & XML_PARSE_DTDVALID) {
15053
 
        ctxt->validate = 1;
15054
 
        if (options & XML_PARSE_NOWARNING)
15055
 
            ctxt->vctxt.warning = NULL;
15056
 
        if (options & XML_PARSE_NOERROR)
15057
 
            ctxt->vctxt.error = NULL;
15058
 
        options -= XML_PARSE_DTDVALID;
15059
 
        ctxt->options |= XML_PARSE_DTDVALID;
15060
 
    } else
15061
 
        ctxt->validate = 0;
15062
 
    if (options & XML_PARSE_NOWARNING) {
15063
 
        ctxt->sax->warning = NULL;
15064
 
        options -= XML_PARSE_NOWARNING;
15065
 
    }
15066
 
    if (options & XML_PARSE_NOERROR) {
15067
 
        ctxt->sax->error = NULL;
15068
 
        ctxt->sax->fatalError = NULL;
15069
 
        options -= XML_PARSE_NOERROR;
15070
 
    }
15071
 
#ifdef LIBXML_SAX1_ENABLED
15072
 
    if (options & XML_PARSE_SAX1) {
15073
 
        ctxt->sax->startElement = xmlSAX2StartElement;
15074
 
        ctxt->sax->endElement = xmlSAX2EndElement;
15075
 
        ctxt->sax->startElementNs = NULL;
15076
 
        ctxt->sax->endElementNs = NULL;
15077
 
        ctxt->sax->initialized = 1;
15078
 
        options -= XML_PARSE_SAX1;
15079
 
        ctxt->options |= XML_PARSE_SAX1;
15080
 
    }
15081
 
#endif /* LIBXML_SAX1_ENABLED */
15082
 
    if (options & XML_PARSE_NODICT) {
15083
 
        ctxt->dictNames = 0;
15084
 
        options -= XML_PARSE_NODICT;
15085
 
        ctxt->options |= XML_PARSE_NODICT;
15086
 
    } else {
15087
 
        ctxt->dictNames = 1;
15088
 
    }
15089
 
    if (options & XML_PARSE_NOCDATA) {
15090
 
        ctxt->sax->cdataBlock = NULL;
15091
 
        options -= XML_PARSE_NOCDATA;
15092
 
        ctxt->options |= XML_PARSE_NOCDATA;
15093
 
    }
15094
 
    if (options & XML_PARSE_NSCLEAN) {
15095
 
        ctxt->options |= XML_PARSE_NSCLEAN;
15096
 
        options -= XML_PARSE_NSCLEAN;
15097
 
    }
15098
 
    if (options & XML_PARSE_NONET) {
15099
 
        ctxt->options |= XML_PARSE_NONET;
15100
 
        options -= XML_PARSE_NONET;
15101
 
    }
15102
 
    if (options & XML_PARSE_COMPACT) {
15103
 
        ctxt->options |= XML_PARSE_COMPACT;
15104
 
        options -= XML_PARSE_COMPACT;
15105
 
    }
15106
 
    if (options & XML_PARSE_OLD10) {
15107
 
        ctxt->options |= XML_PARSE_OLD10;
15108
 
        options -= XML_PARSE_OLD10;
15109
 
    }
15110
 
    if (options & XML_PARSE_NOBASEFIX) {
15111
 
        ctxt->options |= XML_PARSE_NOBASEFIX;
15112
 
        options -= XML_PARSE_NOBASEFIX;
15113
 
    }
15114
 
    if (options & XML_PARSE_HUGE) {
15115
 
        ctxt->options |= XML_PARSE_HUGE;
15116
 
        options -= XML_PARSE_HUGE;
15117
 
        if (ctxt->dict != NULL)
15118
 
            xmlDictSetLimit(ctxt->dict, 0);
15119
 
    }
15120
 
    if (options & XML_PARSE_OLDSAX) {
15121
 
        ctxt->options |= XML_PARSE_OLDSAX;
15122
 
        options -= XML_PARSE_OLDSAX;
15123
 
    }
15124
 
    if (options & XML_PARSE_IGNORE_ENC) {
15125
 
        ctxt->options |= XML_PARSE_IGNORE_ENC;
15126
 
        options -= XML_PARSE_IGNORE_ENC;
15127
 
    }
15128
 
    if (options & XML_PARSE_BIG_LINES) {
15129
 
        ctxt->options |= XML_PARSE_BIG_LINES;
15130
 
        options -= XML_PARSE_BIG_LINES;
15131
 
    }
15132
 
    ctxt->linenumbers = 1;
15133
 
    return (options);
15134
 
}
15135
 
 
15136
 
/**
15137
 
 * xmlCtxtUseOptions:
15138
 
 * @ctxt: an XML parser context
15139
 
 * @options:  a combination of xmlParserOption
15140
 
 *
15141
 
 * Applies the options to the parser context
15142
 
 *
15143
 
 * Returns 0 in case of success, the set of unknown or unimplemented options
15144
 
 *         in case of error.
15145
 
 */
15146
 
int
15147
 
xmlCtxtUseOptions(xmlParserCtxtPtr ctxt, int options)
15148
 
{
15149
 
   return(xmlCtxtUseOptionsInternal(ctxt, options, NULL));
15150
 
}
15151
 
 
15152
 
/**
15153
 
 * xmlDoRead:
15154
 
 * @ctxt:  an XML parser context
15155
 
 * @URL:  the base URL to use for the document
15156
 
 * @encoding:  the document encoding, or NULL
15157
 
 * @options:  a combination of xmlParserOption
15158
 
 * @reuse:  keep the context for reuse
15159
 
 *
15160
 
 * Common front-end for the xmlRead functions
15161
 
 *
15162
 
 * Returns the resulting document tree or NULL
15163
 
 */
15164
 
static xmlDocPtr
15165
 
xmlDoRead(xmlParserCtxtPtr ctxt, const char *URL, const char *encoding,
15166
 
          int options, int reuse)
15167
 
{
15168
 
    xmlDocPtr ret;
15169
 
 
15170
 
    xmlCtxtUseOptionsInternal(ctxt, options, encoding);
15171
 
    if (encoding != NULL) {
15172
 
        xmlCharEncodingHandlerPtr hdlr;
15173
 
 
15174
 
        hdlr = xmlFindCharEncodingHandler(encoding);
15175
 
        if (hdlr != NULL)
15176
 
            xmlSwitchToEncoding(ctxt, hdlr);
15177
 
    }
15178
 
    if ((URL != NULL) && (ctxt->input != NULL) &&
15179
 
        (ctxt->input->filename == NULL))
15180
 
        ctxt->input->filename = (char *) xmlStrdup((const xmlChar *) URL);
15181
 
    xmlParseDocument(ctxt);
15182
 
    if ((ctxt->wellFormed) || ctxt->recovery)
15183
 
        ret = ctxt->myDoc;
15184
 
    else {
15185
 
        ret = NULL;
15186
 
        if (ctxt->myDoc != NULL) {
15187
 
            xmlFreeDoc(ctxt->myDoc);
15188
 
        }
15189
 
    }
15190
 
    ctxt->myDoc = NULL;
15191
 
    if (!reuse) {
15192
 
        xmlFreeParserCtxt(ctxt);
15193
 
    }
15194
 
 
15195
 
    return (ret);
15196
 
}
15197
 
 
15198
 
/**
15199
 
 * xmlReadDoc:
15200
 
 * @cur:  a pointer to a zero terminated string
15201
 
 * @URL:  the base URL to use for the document
15202
 
 * @encoding:  the document encoding, or NULL
15203
 
 * @options:  a combination of xmlParserOption
15204
 
 *
15205
 
 * parse an XML in-memory document and build a tree.
15206
 
 *
15207
 
 * Returns the resulting document tree
15208
 
 */
15209
 
xmlDocPtr
15210
 
xmlReadDoc(const xmlChar * cur, const char *URL, const char *encoding, int options)
15211
 
{
15212
 
    xmlParserCtxtPtr ctxt;
15213
 
 
15214
 
    if (cur == NULL)
15215
 
        return (NULL);
15216
 
 
15217
 
    ctxt = xmlCreateDocParserCtxt(cur);
15218
 
    if (ctxt == NULL)
15219
 
        return (NULL);
15220
 
    return (xmlDoRead(ctxt, URL, encoding, options, 0));
15221
 
}
15222
 
 
15223
 
/**
15224
 
 * xmlReadFile:
15225
 
 * @filename:  a file or URL
15226
 
 * @encoding:  the document encoding, or NULL
15227
 
 * @options:  a combination of xmlParserOption
15228
 
 *
15229
 
 * parse an XML file from the filesystem or the network.
15230
 
 *
15231
 
 * Returns the resulting document tree
15232
 
 */
15233
 
xmlDocPtr
15234
 
xmlReadFile(const char *filename, const char *encoding, int options)
15235
 
{
15236
 
    xmlParserCtxtPtr ctxt;
15237
 
 
15238
 
    ctxt = xmlCreateURLParserCtxt(filename, options);
15239
 
    if (ctxt == NULL)
15240
 
        return (NULL);
15241
 
    return (xmlDoRead(ctxt, NULL, encoding, options, 0));
15242
 
}
15243
 
 
15244
 
/**
15245
 
 * xmlReadMemory:
15246
 
 * @buffer:  a pointer to a char array
15247
 
 * @size:  the size of the array
15248
 
 * @URL:  the base URL to use for the document
15249
 
 * @encoding:  the document encoding, or NULL
15250
 
 * @options:  a combination of xmlParserOption
15251
 
 *
15252
 
 * parse an XML in-memory document and build a tree.
15253
 
 *
15254
 
 * Returns the resulting document tree
15255
 
 */
15256
 
xmlDocPtr
15257
 
xmlReadMemory(const char *buffer, int size, const char *URL, const char *encoding, int options)
15258
 
{
15259
 
    xmlParserCtxtPtr ctxt;
15260
 
 
15261
 
    ctxt = xmlCreateMemoryParserCtxt(buffer, size);
15262
 
    if (ctxt == NULL)
15263
 
        return (NULL);
15264
 
    return (xmlDoRead(ctxt, URL, encoding, options, 0));
15265
 
}
15266
 
 
15267
 
/**
15268
 
 * xmlReadFd:
15269
 
 * @fd:  an open file descriptor
15270
 
 * @URL:  the base URL to use for the document
15271
 
 * @encoding:  the document encoding, or NULL
15272
 
 * @options:  a combination of xmlParserOption
15273
 
 *
15274
 
 * parse an XML from a file descriptor and build a tree.
15275
 
 * NOTE that the file descriptor will not be closed when the
15276
 
 *      reader is closed or reset.
15277
 
 *
15278
 
 * Returns the resulting document tree
15279
 
 */
15280
 
xmlDocPtr
15281
 
xmlReadFd(int fd, const char *URL, const char *encoding, int options)
15282
 
{
15283
 
    xmlParserCtxtPtr ctxt;
15284
 
    xmlParserInputBufferPtr input;
15285
 
    xmlParserInputPtr stream;
15286
 
 
15287
 
    if (fd < 0)
15288
 
        return (NULL);
15289
 
 
15290
 
    input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
15291
 
    if (input == NULL)
15292
 
        return (NULL);
15293
 
    input->closecallback = NULL;
15294
 
    ctxt = xmlNewParserCtxt();
15295
 
    if (ctxt == NULL) {
15296
 
        xmlFreeParserInputBuffer(input);
15297
 
        return (NULL);
15298
 
    }
15299
 
    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
15300
 
    if (stream == NULL) {
15301
 
        xmlFreeParserInputBuffer(input);
15302
 
        xmlFreeParserCtxt(ctxt);
15303
 
        return (NULL);
15304
 
    }
15305
 
    inputPush(ctxt, stream);
15306
 
    return (xmlDoRead(ctxt, URL, encoding, options, 0));
15307
 
}
15308
 
 
15309
 
/**
15310
 
 * xmlReadIO:
15311
 
 * @ioread:  an I/O read function
15312
 
 * @ioclose:  an I/O close function
15313
 
 * @ioctx:  an I/O handler
15314
 
 * @URL:  the base URL to use for the document
15315
 
 * @encoding:  the document encoding, or NULL
15316
 
 * @options:  a combination of xmlParserOption
15317
 
 *
15318
 
 * parse an XML document from I/O functions and source and build a tree.
15319
 
 *
15320
 
 * Returns the resulting document tree
15321
 
 */
15322
 
xmlDocPtr
15323
 
xmlReadIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
15324
 
          void *ioctx, const char *URL, const char *encoding, int options)
15325
 
{
15326
 
    xmlParserCtxtPtr ctxt;
15327
 
    xmlParserInputBufferPtr input;
15328
 
    xmlParserInputPtr stream;
15329
 
 
15330
 
    if (ioread == NULL)
15331
 
        return (NULL);
15332
 
 
15333
 
    input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
15334
 
                                         XML_CHAR_ENCODING_NONE);
15335
 
    if (input == NULL) {
15336
 
        if (ioclose != NULL)
15337
 
            ioclose(ioctx);
15338
 
        return (NULL);
15339
 
    }
15340
 
    ctxt = xmlNewParserCtxt();
15341
 
    if (ctxt == NULL) {
15342
 
        xmlFreeParserInputBuffer(input);
15343
 
        return (NULL);
15344
 
    }
15345
 
    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
15346
 
    if (stream == NULL) {
15347
 
        xmlFreeParserInputBuffer(input);
15348
 
        xmlFreeParserCtxt(ctxt);
15349
 
        return (NULL);
15350
 
    }
15351
 
    inputPush(ctxt, stream);
15352
 
    return (xmlDoRead(ctxt, URL, encoding, options, 0));
15353
 
}
15354
 
 
15355
 
/**
15356
 
 * xmlCtxtReadDoc:
15357
 
 * @ctxt:  an XML parser context
15358
 
 * @cur:  a pointer to a zero terminated string
15359
 
 * @URL:  the base URL to use for the document
15360
 
 * @encoding:  the document encoding, or NULL
15361
 
 * @options:  a combination of xmlParserOption
15362
 
 *
15363
 
 * parse an XML in-memory document and build a tree.
15364
 
 * This reuses the existing @ctxt parser context
15365
 
 *
15366
 
 * Returns the resulting document tree
15367
 
 */
15368
 
xmlDocPtr
15369
 
xmlCtxtReadDoc(xmlParserCtxtPtr ctxt, const xmlChar * cur,
15370
 
               const char *URL, const char *encoding, int options)
15371
 
{
15372
 
    xmlParserInputPtr stream;
15373
 
 
15374
 
    if (cur == NULL)
15375
 
        return (NULL);
15376
 
    if (ctxt == NULL)
15377
 
        return (NULL);
15378
 
 
15379
 
    xmlCtxtReset(ctxt);
15380
 
 
15381
 
    stream = xmlNewStringInputStream(ctxt, cur);
15382
 
    if (stream == NULL) {
15383
 
        return (NULL);
15384
 
    }
15385
 
    inputPush(ctxt, stream);
15386
 
    return (xmlDoRead(ctxt, URL, encoding, options, 1));
15387
 
}
15388
 
 
15389
 
/**
15390
 
 * xmlCtxtReadFile:
15391
 
 * @ctxt:  an XML parser context
15392
 
 * @filename:  a file or URL
15393
 
 * @encoding:  the document encoding, or NULL
15394
 
 * @options:  a combination of xmlParserOption
15395
 
 *
15396
 
 * parse an XML file from the filesystem or the network.
15397
 
 * This reuses the existing @ctxt parser context
15398
 
 *
15399
 
 * Returns the resulting document tree
15400
 
 */
15401
 
xmlDocPtr
15402
 
xmlCtxtReadFile(xmlParserCtxtPtr ctxt, const char *filename,
15403
 
                const char *encoding, int options)
15404
 
{
15405
 
    xmlParserInputPtr stream;
15406
 
 
15407
 
    if (filename == NULL)
15408
 
        return (NULL);
15409
 
    if (ctxt == NULL)
15410
 
        return (NULL);
15411
 
 
15412
 
    xmlCtxtReset(ctxt);
15413
 
 
15414
 
    stream = xmlLoadExternalEntity(filename, NULL, ctxt);
15415
 
    if (stream == NULL) {
15416
 
        return (NULL);
15417
 
    }
15418
 
    inputPush(ctxt, stream);
15419
 
    return (xmlDoRead(ctxt, NULL, encoding, options, 1));
15420
 
}
15421
 
 
15422
 
/**
15423
 
 * xmlCtxtReadMemory:
15424
 
 * @ctxt:  an XML parser context
15425
 
 * @buffer:  a pointer to a char array
15426
 
 * @size:  the size of the array
15427
 
 * @URL:  the base URL to use for the document
15428
 
 * @encoding:  the document encoding, or NULL
15429
 
 * @options:  a combination of xmlParserOption
15430
 
 *
15431
 
 * parse an XML in-memory document and build a tree.
15432
 
 * This reuses the existing @ctxt parser context
15433
 
 *
15434
 
 * Returns the resulting document tree
15435
 
 */
15436
 
xmlDocPtr
15437
 
xmlCtxtReadMemory(xmlParserCtxtPtr ctxt, const char *buffer, int size,
15438
 
                  const char *URL, const char *encoding, int options)
15439
 
{
15440
 
    xmlParserInputBufferPtr input;
15441
 
    xmlParserInputPtr stream;
15442
 
 
15443
 
    if (ctxt == NULL)
15444
 
        return (NULL);
15445
 
    if (buffer == NULL)
15446
 
        return (NULL);
15447
 
 
15448
 
    xmlCtxtReset(ctxt);
15449
 
 
15450
 
    input = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
15451
 
    if (input == NULL) {
15452
 
        return(NULL);
15453
 
    }
15454
 
 
15455
 
    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
15456
 
    if (stream == NULL) {
15457
 
        xmlFreeParserInputBuffer(input);
15458
 
        return(NULL);
15459
 
    }
15460
 
 
15461
 
    inputPush(ctxt, stream);
15462
 
    return (xmlDoRead(ctxt, URL, encoding, options, 1));
15463
 
}
15464
 
 
15465
 
/**
15466
 
 * xmlCtxtReadFd:
15467
 
 * @ctxt:  an XML parser context
15468
 
 * @fd:  an open file descriptor
15469
 
 * @URL:  the base URL to use for the document
15470
 
 * @encoding:  the document encoding, or NULL
15471
 
 * @options:  a combination of xmlParserOption
15472
 
 *
15473
 
 * parse an XML from a file descriptor and build a tree.
15474
 
 * This reuses the existing @ctxt parser context
15475
 
 * NOTE that the file descriptor will not be closed when the
15476
 
 *      reader is closed or reset.
15477
 
 *
15478
 
 * Returns the resulting document tree
15479
 
 */
15480
 
xmlDocPtr
15481
 
xmlCtxtReadFd(xmlParserCtxtPtr ctxt, int fd,
15482
 
              const char *URL, const char *encoding, int options)
15483
 
{
15484
 
    xmlParserInputBufferPtr input;
15485
 
    xmlParserInputPtr stream;
15486
 
 
15487
 
    if (fd < 0)
15488
 
        return (NULL);
15489
 
    if (ctxt == NULL)
15490
 
        return (NULL);
15491
 
 
15492
 
    xmlCtxtReset(ctxt);
15493
 
 
15494
 
 
15495
 
    input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
15496
 
    if (input == NULL)
15497
 
        return (NULL);
15498
 
    input->closecallback = NULL;
15499
 
    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
15500
 
    if (stream == NULL) {
15501
 
        xmlFreeParserInputBuffer(input);
15502
 
        return (NULL);
15503
 
    }
15504
 
    inputPush(ctxt, stream);
15505
 
    return (xmlDoRead(ctxt, URL, encoding, options, 1));
15506
 
}
15507
 
 
15508
 
/**
15509
 
 * xmlCtxtReadIO:
15510
 
 * @ctxt:  an XML parser context
15511
 
 * @ioread:  an I/O read function
15512
 
 * @ioclose:  an I/O close function
15513
 
 * @ioctx:  an I/O handler
15514
 
 * @URL:  the base URL to use for the document
15515
 
 * @encoding:  the document encoding, or NULL
15516
 
 * @options:  a combination of xmlParserOption
15517
 
 *
15518
 
 * parse an XML document from I/O functions and source and build a tree.
15519
 
 * This reuses the existing @ctxt parser context
15520
 
 *
15521
 
 * Returns the resulting document tree
15522
 
 */
15523
 
xmlDocPtr
15524
 
xmlCtxtReadIO(xmlParserCtxtPtr ctxt, xmlInputReadCallback ioread,
15525
 
              xmlInputCloseCallback ioclose, void *ioctx,
15526
 
              const char *URL,
15527
 
              const char *encoding, int options)
15528
 
{
15529
 
    xmlParserInputBufferPtr input;
15530
 
    xmlParserInputPtr stream;
15531
 
 
15532
 
    if (ioread == NULL)
15533
 
        return (NULL);
15534
 
    if (ctxt == NULL)
15535
 
        return (NULL);
15536
 
 
15537
 
    xmlCtxtReset(ctxt);
15538
 
 
15539
 
    input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
15540
 
                                         XML_CHAR_ENCODING_NONE);
15541
 
    if (input == NULL) {
15542
 
        if (ioclose != NULL)
15543
 
            ioclose(ioctx);
15544
 
        return (NULL);
15545
 
    }
15546
 
    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
15547
 
    if (stream == NULL) {
15548
 
        xmlFreeParserInputBuffer(input);
15549
 
        return (NULL);
15550
 
    }
15551
 
    inputPush(ctxt, stream);
15552
 
    return (xmlDoRead(ctxt, URL, encoding, options, 1));
15553
 
}
15554
 
 
15555
 
#define bottom_parser
15556
 
#include "elfgcchack.h"