Coverage Report

Created: 2024-02-11 06:20

/src/libxml2-2.12.5/parserInternals.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * parserInternals.c : Internal routines (and obsolete ones) needed for the
3
 *                     XML and HTML parsers.
4
 *
5
 * See Copyright for the status of this software.
6
 *
7
 * daniel@veillard.com
8
 */
9
10
#define IN_LIBXML
11
#include "libxml.h"
12
13
#if defined(_WIN32)
14
#define XML_DIR_SEP '\\'
15
#else
16
#define XML_DIR_SEP '/'
17
#endif
18
19
#include <string.h>
20
#include <ctype.h>
21
#include <stdlib.h>
22
23
#include <libxml/xmlmemory.h>
24
#include <libxml/tree.h>
25
#include <libxml/parser.h>
26
#include <libxml/parserInternals.h>
27
#include <libxml/entities.h>
28
#include <libxml/xmlerror.h>
29
#include <libxml/encoding.h>
30
#include <libxml/xmlIO.h>
31
#include <libxml/uri.h>
32
#include <libxml/dict.h>
33
#include <libxml/xmlsave.h>
34
#ifdef LIBXML_CATALOG_ENABLED
35
#include <libxml/catalog.h>
36
#endif
37
#include <libxml/chvalid.h>
38
39
#define CUR(ctxt) ctxt->input->cur
40
#define END(ctxt) ctxt->input->end
41
42
#include "private/buf.h"
43
#include "private/enc.h"
44
#include "private/error.h"
45
#include "private/io.h"
46
#include "private/parser.h"
47
48
/*
49
 * XML_MAX_AMPLIFICATION_DEFAULT is the default maximum allowed amplification
50
 * factor of serialized output after entity expansion.
51
 */
52
16.2k
#define XML_MAX_AMPLIFICATION_DEFAULT 5
53
54
/*
55
 * Various global defaults for parsing
56
 */
57
58
/**
59
 * xmlCheckVersion:
60
 * @version: the include version number
61
 *
62
 * check the compiled lib version against the include one.
63
 * This can warn or immediately kill the application
64
 */
65
void
66
0
xmlCheckVersion(int version) {
67
0
    int myversion = LIBXML_VERSION;
68
69
0
    xmlInitParser();
70
71
0
    if ((myversion / 10000) != (version / 10000)) {
72
0
  xmlGenericError(xmlGenericErrorContext,
73
0
    "Fatal: program compiled against libxml %d using libxml %d\n",
74
0
    (version / 10000), (myversion / 10000));
75
0
  fprintf(stderr,
76
0
    "Fatal: program compiled against libxml %d using libxml %d\n",
77
0
    (version / 10000), (myversion / 10000));
78
0
    }
79
0
    if ((myversion / 100) < (version / 100)) {
80
0
  xmlGenericError(xmlGenericErrorContext,
81
0
    "Warning: program compiled against libxml %d using older %d\n",
82
0
    (version / 100), (myversion / 100));
83
0
    }
84
0
}
85
86
87
/************************************************************************
88
 *                  *
89
 *    Some factorized error routines        *
90
 *                  *
91
 ************************************************************************/
92
93
94
/**
95
 * xmlErrMemory:
96
 * @ctxt:  an XML parser context
97
 * @extra:  extra information
98
 *
99
 * Handle a redefinition of attribute error
100
 */
101
void
102
xmlErrMemory(xmlParserCtxtPtr ctxt, const char *extra)
103
0
{
104
0
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
105
0
        (ctxt->instate == XML_PARSER_EOF))
106
0
  return;
107
0
    if (ctxt != NULL) {
108
0
        ctxt->errNo = XML_ERR_NO_MEMORY;
109
0
        ctxt->instate = XML_PARSER_EOF;
110
0
        ctxt->disableSAX = 1;
111
0
    }
112
0
    if (extra)
113
0
        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
114
0
                        XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
115
0
                        NULL, NULL, 0, 0,
116
0
                        "Memory allocation failed : %s\n", extra);
117
0
    else
118
0
        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
119
0
                        XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, NULL,
120
0
                        NULL, NULL, 0, 0, "Memory allocation failed\n");
121
0
}
122
123
/**
124
 * __xmlErrEncoding:
125
 * @ctxt:  an XML parser context
126
 * @xmlerr:  the error number
127
 * @msg:  the error message
128
 * @str1:  an string info
129
 * @str2:  an string info
130
 *
131
 * Handle an encoding error
132
 */
133
void
134
__xmlErrEncoding(xmlParserCtxtPtr ctxt, xmlParserErrors xmlerr,
135
                 const char *msg, const xmlChar * str1, const xmlChar * str2)
136
4.87k
{
137
4.87k
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
138
4.87k
        (ctxt->instate == XML_PARSER_EOF))
139
0
  return;
140
4.87k
    if (ctxt != NULL)
141
4.87k
        ctxt->errNo = xmlerr;
142
4.87k
    __xmlRaiseError(NULL, NULL, NULL,
143
4.87k
                    ctxt, NULL, XML_FROM_PARSER, xmlerr, XML_ERR_FATAL,
144
4.87k
                    NULL, 0, (const char *) str1, (const char *) str2,
145
4.87k
                    NULL, 0, 0, msg, str1, str2);
146
4.87k
    if (ctxt != NULL) {
147
4.87k
        ctxt->wellFormed = 0;
148
4.87k
        if (ctxt->recovery == 0)
149
4.87k
            ctxt->disableSAX = 1;
150
4.87k
    }
151
4.87k
}
152
153
/**
154
 * xmlErrInternal:
155
 * @ctxt:  an XML parser context
156
 * @msg:  the error message
157
 * @str:  error information
158
 *
159
 * Handle an internal error
160
 */
161
static void LIBXML_ATTR_FORMAT(2,0)
162
xmlErrInternal(xmlParserCtxtPtr ctxt, const char *msg, const xmlChar * str)
163
11
{
164
11
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
165
11
        (ctxt->instate == XML_PARSER_EOF))
166
0
  return;
167
11
    if (ctxt != NULL)
168
11
        ctxt->errNo = XML_ERR_INTERNAL_ERROR;
169
11
    __xmlRaiseError(NULL, NULL, NULL,
170
11
                    ctxt, NULL, XML_FROM_PARSER, XML_ERR_INTERNAL_ERROR,
171
11
                    XML_ERR_FATAL, NULL, 0, (const char *) str, NULL, NULL,
172
11
                    0, 0, msg, str);
173
11
    if (ctxt != NULL) {
174
11
        ctxt->wellFormed = 0;
175
11
        if (ctxt->recovery == 0)
176
11
            ctxt->disableSAX = 1;
177
11
    }
178
11
}
179
180
/**
181
 * xmlFatalErr:
182
 * @ctxt:  an XML parser context
183
 * @error:  the error number
184
 * @info:  extra information string
185
 *
186
 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
187
 */
188
void
189
xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info)
190
185k
{
191
185k
    const char *errmsg;
192
193
185k
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
194
185k
        (ctxt->instate == XML_PARSER_EOF))
195
965
  return;
196
184k
    switch (error) {
197
7.55k
        case XML_ERR_INVALID_HEX_CHARREF:
198
7.55k
            errmsg = "CharRef: invalid hexadecimal value";
199
7.55k
            break;
200
13.8k
        case XML_ERR_INVALID_DEC_CHARREF:
201
13.8k
            errmsg = "CharRef: invalid decimal value";
202
13.8k
            break;
203
0
        case XML_ERR_INVALID_CHARREF:
204
0
            errmsg = "CharRef: invalid value";
205
0
            break;
206
2.80k
        case XML_ERR_INTERNAL_ERROR:
207
2.80k
            errmsg = "internal error";
208
2.80k
            break;
209
0
        case XML_ERR_PEREF_AT_EOF:
210
0
            errmsg = "PEReference at end of document";
211
0
            break;
212
0
        case XML_ERR_PEREF_IN_PROLOG:
213
0
            errmsg = "PEReference in prolog";
214
0
            break;
215
0
        case XML_ERR_PEREF_IN_EPILOG:
216
0
            errmsg = "PEReference in epilog";
217
0
            break;
218
0
        case XML_ERR_PEREF_NO_NAME:
219
0
            errmsg = "PEReference: no name";
220
0
            break;
221
487
        case XML_ERR_PEREF_SEMICOL_MISSING:
222
487
            errmsg = "PEReference: expecting ';'";
223
487
            break;
224
0
        case XML_ERR_ENTITY_LOOP:
225
0
            errmsg = "Detected an entity reference loop";
226
0
            break;
227
0
        case XML_ERR_ENTITY_NOT_STARTED:
228
0
            errmsg = "EntityValue: \" or ' expected";
229
0
            break;
230
86
        case XML_ERR_ENTITY_PE_INTERNAL:
231
86
            errmsg = "PEReferences forbidden in internal subset";
232
86
            break;
233
180
        case XML_ERR_ENTITY_NOT_FINISHED:
234
180
            errmsg = "EntityValue: \" or ' expected";
235
180
            break;
236
741
        case XML_ERR_ATTRIBUTE_NOT_STARTED:
237
741
            errmsg = "AttValue: \" or ' expected";
238
741
            break;
239
525
        case XML_ERR_LT_IN_ATTRIBUTE:
240
525
            errmsg = "Unescaped '<' not allowed in attributes values";
241
525
            break;
242
2.15k
        case XML_ERR_LITERAL_NOT_STARTED:
243
2.15k
            errmsg = "SystemLiteral \" or ' expected";
244
2.15k
            break;
245
699
        case XML_ERR_LITERAL_NOT_FINISHED:
246
699
            errmsg = "Unfinished System or Public ID \" or ' expected";
247
699
            break;
248
227
        case XML_ERR_MISPLACED_CDATA_END:
249
227
            errmsg = "Sequence ']]>' not allowed in content";
250
227
            break;
251
1.63k
        case XML_ERR_URI_REQUIRED:
252
1.63k
            errmsg = "SYSTEM or PUBLIC, the URI is missing";
253
1.63k
            break;
254
522
        case XML_ERR_PUBID_REQUIRED:
255
522
            errmsg = "PUBLIC, the Public Identifier is missing";
256
522
            break;
257
11.4k
        case XML_ERR_HYPHEN_IN_COMMENT:
258
11.4k
            errmsg = "Comment must not contain '--' (double-hyphen)";
259
11.4k
            break;
260
618
        case XML_ERR_PI_NOT_STARTED:
261
618
            errmsg = "xmlParsePI : no target name";
262
618
            break;
263
758
        case XML_ERR_RESERVED_XML_NAME:
264
758
            errmsg = "Invalid PI name";
265
758
            break;
266
151
        case XML_ERR_NOTATION_NOT_STARTED:
267
151
            errmsg = "NOTATION: Name expected here";
268
151
            break;
269
1.11k
        case XML_ERR_NOTATION_NOT_FINISHED:
270
1.11k
            errmsg = "'>' required to close NOTATION declaration";
271
1.11k
            break;
272
1.37k
        case XML_ERR_VALUE_REQUIRED:
273
1.37k
            errmsg = "Entity value required";
274
1.37k
            break;
275
596
        case XML_ERR_URI_FRAGMENT:
276
596
            errmsg = "Fragment not allowed";
277
596
            break;
278
613
        case XML_ERR_ATTLIST_NOT_STARTED:
279
613
            errmsg = "'(' required to start ATTLIST enumeration";
280
613
            break;
281
289
        case XML_ERR_NMTOKEN_REQUIRED:
282
289
            errmsg = "NmToken expected in ATTLIST enumeration";
283
289
            break;
284
364
        case XML_ERR_ATTLIST_NOT_FINISHED:
285
364
            errmsg = "')' required to finish ATTLIST enumeration";
286
364
            break;
287
262
        case XML_ERR_MIXED_NOT_STARTED:
288
262
            errmsg = "MixedContentDecl : '|' or ')*' expected";
289
262
            break;
290
0
        case XML_ERR_PCDATA_REQUIRED:
291
0
            errmsg = "MixedContentDecl : '#PCDATA' expected";
292
0
            break;
293
730
        case XML_ERR_ELEMCONTENT_NOT_STARTED:
294
730
            errmsg = "ContentDecl : Name or '(' expected";
295
730
            break;
296
1.23k
        case XML_ERR_ELEMCONTENT_NOT_FINISHED:
297
1.23k
            errmsg = "ContentDecl : ',' '|' or ')' expected";
298
1.23k
            break;
299
0
        case XML_ERR_PEREF_IN_INT_SUBSET:
300
0
            errmsg =
301
0
                "PEReference: forbidden within markup decl in internal subset";
302
0
            break;
303
3.37k
        case XML_ERR_GT_REQUIRED:
304
3.37k
            errmsg = "expected '>'";
305
3.37k
            break;
306
0
        case XML_ERR_CONDSEC_INVALID:
307
0
            errmsg = "XML conditional section '[' expected";
308
0
            break;
309
0
        case XML_ERR_EXT_SUBSET_NOT_FINISHED:
310
0
            errmsg = "Content error in the external subset";
311
0
            break;
312
0
        case XML_ERR_CONDSEC_INVALID_KEYWORD:
313
0
            errmsg =
314
0
                "conditional section INCLUDE or IGNORE keyword expected";
315
0
            break;
316
0
        case XML_ERR_CONDSEC_NOT_FINISHED:
317
0
            errmsg = "XML conditional section not closed";
318
0
            break;
319
0
        case XML_ERR_XMLDECL_NOT_STARTED:
320
0
            errmsg = "Text declaration '<?xml' required";
321
0
            break;
322
601
        case XML_ERR_XMLDECL_NOT_FINISHED:
323
601
            errmsg = "parsing XML declaration: '?>' expected";
324
601
            break;
325
0
        case XML_ERR_EXT_ENTITY_STANDALONE:
326
0
            errmsg = "external parsed entities cannot be standalone";
327
0
            break;
328
127k
        case XML_ERR_ENTITYREF_SEMICOL_MISSING:
329
127k
            errmsg = "EntityRef: expecting ';'";
330
127k
            break;
331
276
        case XML_ERR_DOCTYPE_NOT_FINISHED:
332
276
            errmsg = "DOCTYPE improperly terminated";
333
276
            break;
334
0
        case XML_ERR_LTSLASH_REQUIRED:
335
0
            errmsg = "EndTag: '</' not found";
336
0
            break;
337
42
        case XML_ERR_EQUAL_REQUIRED:
338
42
            errmsg = "expected '='";
339
42
            break;
340
178
        case XML_ERR_STRING_NOT_CLOSED:
341
178
            errmsg = "String not closed expecting \" or '";
342
178
            break;
343
17
        case XML_ERR_STRING_NOT_STARTED:
344
17
            errmsg = "String not started expecting ' or \"";
345
17
            break;
346
13
        case XML_ERR_ENCODING_NAME:
347
13
            errmsg = "Invalid XML encoding name";
348
13
            break;
349
29
        case XML_ERR_STANDALONE_VALUE:
350
29
            errmsg = "standalone accepts only 'yes' or 'no'";
351
29
            break;
352
0
        case XML_ERR_DOCUMENT_EMPTY:
353
0
            errmsg = "Document is empty";
354
0
            break;
355
23
        case XML_ERR_DOCUMENT_END:
356
23
            errmsg = "Extra content at the end of the document";
357
23
            break;
358
0
        case XML_ERR_NOT_WELL_BALANCED:
359
0
            errmsg = "chunk is not well balanced";
360
0
            break;
361
0
        case XML_ERR_EXTRA_CONTENT:
362
0
            errmsg = "extra content at the end of well balanced chunk";
363
0
            break;
364
909
        case XML_ERR_VERSION_MISSING:
365
909
            errmsg = "Malformed declaration expecting version";
366
909
            break;
367
18
        case XML_ERR_NAME_TOO_LONG:
368
18
            errmsg = "Name too long";
369
18
            break;
370
44
        case XML_ERR_INVALID_ENCODING:
371
44
            errmsg = "Invalid bytes in character encoding";
372
44
            break;
373
0
        case XML_IO_UNKNOWN:
374
0
            errmsg = "I/O error";
375
0
            break;
376
#if 0
377
        case:
378
            errmsg = "";
379
            break;
380
#endif
381
0
        default:
382
0
            errmsg = "Unregistered error message";
383
184k
    }
384
184k
    if (ctxt != NULL)
385
184k
  ctxt->errNo = error;
386
184k
    if (info == NULL) {
387
181k
        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
388
181k
                        XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, "%s\n",
389
181k
                        errmsg);
390
181k
    } else {
391
2.82k
        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
392
2.82k
                        XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, "%s: %s\n",
393
2.82k
                        errmsg, info);
394
2.82k
    }
395
184k
    if (ctxt != NULL) {
396
184k
  ctxt->wellFormed = 0;
397
184k
  if (ctxt->recovery == 0)
398
184k
      ctxt->disableSAX = 1;
399
184k
    }
400
184k
}
401
402
/**
403
 * xmlErrEncodingInt:
404
 * @ctxt:  an XML parser context
405
 * @error:  the error number
406
 * @msg:  the error message
407
 * @val:  an integer value
408
 *
409
 * n encoding error
410
 */
411
static void LIBXML_ATTR_FORMAT(3,0)
412
xmlErrEncodingInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
413
                  const char *msg, int val)
414
596
{
415
596
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
416
596
        (ctxt->instate == XML_PARSER_EOF))
417
0
  return;
418
596
    if (ctxt != NULL)
419
596
        ctxt->errNo = error;
420
596
    __xmlRaiseError(NULL, NULL, NULL,
421
596
                    ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
422
596
                    NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
423
596
    if (ctxt != NULL) {
424
596
        ctxt->wellFormed = 0;
425
596
        if (ctxt->recovery == 0)
426
596
            ctxt->disableSAX = 1;
427
596
    }
428
596
}
429
430
/**
431
 * xmlIsLetter:
432
 * @c:  an unicode character (int)
433
 *
434
 * Check whether the character is allowed by the production
435
 * [84] Letter ::= BaseChar | Ideographic
436
 *
437
 * Returns 0 if not, non-zero otherwise
438
 */
439
int
440
0
xmlIsLetter(int c) {
441
0
    return(IS_BASECHAR(c) || IS_IDEOGRAPHIC(c));
442
0
}
443
444
/************************************************************************
445
 *                  *
446
 *    Input handling functions for progressive parsing  *
447
 *                  *
448
 ************************************************************************/
449
450
/* we need to keep enough input to show errors in context */
451
10.2k
#define LINE_LEN        80
452
453
/**
454
 * xmlHaltParser:
455
 * @ctxt:  an XML parser context
456
 *
457
 * Blocks further parser processing don't override error
458
 * for internal use
459
 */
460
void
461
4.91k
xmlHaltParser(xmlParserCtxtPtr ctxt) {
462
4.91k
    if (ctxt == NULL)
463
0
        return;
464
4.91k
    ctxt->instate = XML_PARSER_EOF;
465
4.91k
    ctxt->disableSAX = 1;
466
4.91k
    while (ctxt->inputNr > 1)
467
0
        xmlFreeInputStream(inputPop(ctxt));
468
4.91k
    if (ctxt->input != NULL) {
469
        /*
470
   * in case there was a specific allocation deallocate before
471
   * overriding base
472
   */
473
4.91k
        if (ctxt->input->free != NULL) {
474
0
      ctxt->input->free((xmlChar *) ctxt->input->base);
475
0
      ctxt->input->free = NULL;
476
0
  }
477
4.91k
        if (ctxt->input->buf != NULL) {
478
4.43k
            xmlFreeParserInputBuffer(ctxt->input->buf);
479
4.43k
            ctxt->input->buf = NULL;
480
4.43k
        }
481
4.91k
  ctxt->input->cur = BAD_CAST"";
482
4.91k
        ctxt->input->length = 0;
483
4.91k
  ctxt->input->base = ctxt->input->cur;
484
4.91k
        ctxt->input->end = ctxt->input->cur;
485
4.91k
    }
486
4.91k
}
487
488
/**
489
 * xmlParserInputRead:
490
 * @in:  an XML parser input
491
 * @len:  an indicative size for the lookahead
492
 *
493
 * DEPRECATED: This function was internal and is deprecated.
494
 *
495
 * Returns -1 as this is an error to use it.
496
 */
497
int
498
0
xmlParserInputRead(xmlParserInputPtr in ATTRIBUTE_UNUSED, int len ATTRIBUTE_UNUSED) {
499
0
    return(-1);
500
0
}
501
502
/**
503
 * xmlParserGrow:
504
 * @ctxt:  an XML parser context
505
 *
506
 * Grow the input buffer.
507
 *
508
 * Returns the number of bytes read or -1 in case of error.
509
 */
510
int
511
1.80M
xmlParserGrow(xmlParserCtxtPtr ctxt) {
512
1.80M
    xmlParserInputPtr in = ctxt->input;
513
1.80M
    xmlParserInputBufferPtr buf = in->buf;
514
1.80M
    ptrdiff_t curEnd = in->end - in->cur;
515
1.80M
    ptrdiff_t curBase = in->cur - in->base;
516
1.80M
    int ret;
517
518
1.80M
    if (buf == NULL)
519
965
        return(0);
520
    /* Don't grow push parser buffer. */
521
1.80M
    if ((ctxt->progressive) && (ctxt->inputNr <= 1))
522
1.80M
        return(0);
523
    /* Don't grow memory buffers. */
524
0
    if ((buf->encoder == NULL) && (buf->readcallback == NULL))
525
0
        return(0);
526
0
    if (buf->error != 0)
527
0
        return(-1);
528
529
0
    if (((curEnd > XML_MAX_LOOKUP_LIMIT) ||
530
0
         (curBase > XML_MAX_LOOKUP_LIMIT)) &&
531
0
        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
532
0
        xmlErrMemory(ctxt, "Huge input lookup");
533
0
        xmlHaltParser(ctxt);
534
0
  return(-1);
535
0
    }
536
537
0
    if (curEnd >= INPUT_CHUNK)
538
0
        return(0);
539
540
0
    ret = xmlParserInputBufferGrow(buf, INPUT_CHUNK);
541
0
    xmlBufUpdateInput(buf->buffer, in, curBase);
542
543
0
    if (ret < 0) {
544
0
        xmlFatalErr(ctxt, buf->error, NULL);
545
        /* Buffer contents may be lost in case of memory errors. */
546
0
        if (buf->error == XML_ERR_NO_MEMORY)
547
0
            xmlHaltParser(ctxt);
548
0
    }
549
550
0
    return(ret);
551
0
}
552
553
/**
554
 * xmlParserInputGrow:
555
 * @in:  an XML parser input
556
 * @len:  an indicative size for the lookahead
557
 *
558
 * DEPRECATED: Don't use.
559
 *
560
 * This function increase the input for the parser. It tries to
561
 * preserve pointers to the input buffer, and keep already read data
562
 *
563
 * Returns the amount of char read, or -1 in case of error, 0 indicate the
564
 * end of this entity
565
 */
566
int
567
0
xmlParserInputGrow(xmlParserInputPtr in, int len) {
568
0
    int ret;
569
0
    size_t indx;
570
571
0
    if ((in == NULL) || (len < 0)) return(-1);
572
0
    if (in->buf == NULL) return(-1);
573
0
    if (in->base == NULL) return(-1);
574
0
    if (in->cur == NULL) return(-1);
575
0
    if (in->buf->buffer == NULL) return(-1);
576
577
    /* Don't grow memory buffers. */
578
0
    if ((in->buf->encoder == NULL) && (in->buf->readcallback == NULL))
579
0
        return(0);
580
581
0
    indx = in->cur - in->base;
582
0
    if (xmlBufUse(in->buf->buffer) > (unsigned int) indx + INPUT_CHUNK) {
583
0
        return(0);
584
0
    }
585
0
    ret = xmlParserInputBufferGrow(in->buf, len);
586
587
0
    in->base = xmlBufContent(in->buf->buffer);
588
0
    if (in->base == NULL) {
589
0
        in->base = BAD_CAST "";
590
0
        in->cur = in->base;
591
0
        in->end = in->base;
592
0
        return(-1);
593
0
    }
594
0
    in->cur = in->base + indx;
595
0
    in->end = xmlBufEnd(in->buf->buffer);
596
597
0
    return(ret);
598
0
}
599
600
/**
601
 * xmlParserShrink:
602
 * @ctxt:  an XML parser context
603
 *
604
 * Shrink the input buffer.
605
 */
606
void
607
10.2k
xmlParserShrink(xmlParserCtxtPtr ctxt) {
608
10.2k
    xmlParserInputPtr in = ctxt->input;
609
10.2k
    xmlParserInputBufferPtr buf = in->buf;
610
10.2k
    size_t used;
611
612
10.2k
    if (buf == NULL)
613
0
        return;
614
    /* Don't shrink pull parser memory buffers. */
615
10.2k
    if (((ctxt->progressive == 0) || (ctxt->inputNr > 1)) &&
616
10.2k
        (buf->encoder == NULL) &&
617
10.2k
        (buf->readcallback == NULL))
618
0
        return;
619
620
10.2k
    used = in->cur - in->base;
621
    /*
622
     * Do not shrink on large buffers whose only a tiny fraction
623
     * was consumed
624
     */
625
10.2k
    if (used > INPUT_CHUNK) {
626
10.2k
  size_t res = xmlBufShrink(buf->buffer, used - LINE_LEN);
627
628
10.2k
  if (res > 0) {
629
10.2k
            used -= res;
630
10.2k
            if ((res > ULONG_MAX) ||
631
10.2k
                (in->consumed > ULONG_MAX - (unsigned long)res))
632
0
                in->consumed = ULONG_MAX;
633
10.2k
            else
634
10.2k
                in->consumed += res;
635
10.2k
  }
636
10.2k
    }
637
638
10.2k
    xmlBufUpdateInput(buf->buffer, in, used);
639
10.2k
}
640
641
/**
642
 * xmlParserInputShrink:
643
 * @in:  an XML parser input
644
 *
645
 * DEPRECATED: Don't use.
646
 *
647
 * This function removes used input for the parser.
648
 */
649
void
650
0
xmlParserInputShrink(xmlParserInputPtr in) {
651
0
    size_t used;
652
0
    size_t ret;
653
654
0
    if (in == NULL) return;
655
0
    if (in->buf == NULL) return;
656
0
    if (in->base == NULL) return;
657
0
    if (in->cur == NULL) return;
658
0
    if (in->buf->buffer == NULL) return;
659
660
0
    used = in->cur - in->base;
661
    /*
662
     * Do not shrink on large buffers whose only a tiny fraction
663
     * was consumed
664
     */
665
0
    if (used > INPUT_CHUNK) {
666
0
  ret = xmlBufShrink(in->buf->buffer, used - LINE_LEN);
667
0
  if (ret > 0) {
668
0
            used -= ret;
669
0
            if ((ret > ULONG_MAX) ||
670
0
                (in->consumed > ULONG_MAX - (unsigned long)ret))
671
0
                in->consumed = ULONG_MAX;
672
0
            else
673
0
                in->consumed += ret;
674
0
  }
675
0
    }
676
677
0
    if (xmlBufUse(in->buf->buffer) <= INPUT_CHUNK) {
678
0
        xmlParserInputBufferRead(in->buf, 2 * INPUT_CHUNK);
679
0
    }
680
681
0
    in->base = xmlBufContent(in->buf->buffer);
682
0
    if (in->base == NULL) {
683
        /* TODO: raise error */
684
0
        in->base = BAD_CAST "";
685
0
        in->cur = in->base;
686
0
        in->end = in->base;
687
0
        return;
688
0
    }
689
0
    in->cur = in->base + used;
690
0
    in->end = xmlBufEnd(in->buf->buffer);
691
0
}
692
693
/************************************************************************
694
 *                  *
695
 *    UTF8 character input and related functions    *
696
 *                  *
697
 ************************************************************************/
698
699
/**
700
 * xmlNextChar:
701
 * @ctxt:  the XML parser context
702
 *
703
 * DEPRECATED: Internal function, do not use.
704
 *
705
 * Skip to the next char input char.
706
 */
707
708
void
709
xmlNextChar(xmlParserCtxtPtr ctxt)
710
15.9M
{
711
15.9M
    const unsigned char *cur;
712
15.9M
    size_t avail;
713
15.9M
    int c;
714
715
15.9M
    if ((ctxt == NULL) || (ctxt->instate == XML_PARSER_EOF) ||
716
15.9M
        (ctxt->input == NULL))
717
0
        return;
718
719
15.9M
    avail = ctxt->input->end - ctxt->input->cur;
720
721
15.9M
    if (avail < INPUT_CHUNK) {
722
301k
        xmlParserGrow(ctxt);
723
301k
        if ((ctxt->instate == XML_PARSER_EOF) ||
724
301k
            (ctxt->input->cur >= ctxt->input->end))
725
90
            return;
726
301k
        avail = ctxt->input->end - ctxt->input->cur;
727
301k
    }
728
729
15.9M
    cur = ctxt->input->cur;
730
15.9M
    c = *cur;
731
732
15.9M
    if (c < 0x80) {
733
11.7M
        if (c == '\n') {
734
36.5k
            ctxt->input->cur++;
735
36.5k
            ctxt->input->line++;
736
36.5k
            ctxt->input->col = 1;
737
11.7M
        } else if (c == '\r') {
738
            /*
739
             *   2.11 End-of-Line Handling
740
             *   the literal two-character sequence "#xD#xA" or a standalone
741
             *   literal #xD, an XML processor must pass to the application
742
             *   the single character #xA.
743
             */
744
202k
            ctxt->input->cur += ((cur[1] == '\n') ? 2 : 1);
745
202k
            ctxt->input->line++;
746
202k
            ctxt->input->col = 1;
747
202k
            return;
748
11.5M
        } else {
749
11.5M
            ctxt->input->cur++;
750
11.5M
            ctxt->input->col++;
751
11.5M
        }
752
11.7M
    } else {
753
4.12M
        ctxt->input->col++;
754
755
4.12M
        if ((avail < 2) || (cur[1] & 0xc0) != 0x80)
756
2.35k
            goto encoding_error;
757
758
4.12M
        if (c < 0xe0) {
759
            /* 2-byte code */
760
89.5k
            if (c < 0xc2)
761
69.0k
                goto encoding_error;
762
20.4k
            ctxt->input->cur += 2;
763
4.03M
        } else {
764
4.03M
            unsigned int val = (c << 8) | cur[1];
765
766
4.03M
            if ((avail < 3) || (cur[2] & 0xc0) != 0x80)
767
232
                goto encoding_error;
768
769
4.03M
            if (c < 0xf0) {
770
                /* 3-byte code */
771
4.02M
                if ((val < 0xe0a0) || ((val >= 0xeda0) && (val < 0xee00)))
772
453
                    goto encoding_error;
773
4.02M
                ctxt->input->cur += 3;
774
4.02M
            } else {
775
1.08k
                if ((avail < 4) || ((cur[3] & 0xc0) != 0x80))
776
210
                    goto encoding_error;
777
778
                /* 4-byte code */
779
878
                if ((val < 0xf090) || (val >= 0xf490))
780
425
                    goto encoding_error;
781
453
                ctxt->input->cur += 4;
782
453
            }
783
4.03M
        }
784
4.12M
    }
785
786
15.6M
    return;
787
788
15.6M
encoding_error:
789
    /* Only report the first error */
790
72.7k
    if ((ctxt->input->flags & XML_INPUT_ENCODING_ERROR) == 0) {
791
195
        if ((ctxt == NULL) || (ctxt->input == NULL) ||
792
195
            (ctxt->input->end - ctxt->input->cur < 4)) {
793
81
            __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
794
81
                         "Input is not proper UTF-8, indicate encoding !\n",
795
81
                         NULL, NULL);
796
114
        } else {
797
114
            char buffer[150];
798
799
114
            snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
800
114
                            ctxt->input->cur[0], ctxt->input->cur[1],
801
114
                            ctxt->input->cur[2], ctxt->input->cur[3]);
802
114
            __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
803
114
                         "Input is not proper UTF-8, indicate encoding !\n%s",
804
114
                         BAD_CAST buffer, NULL);
805
114
        }
806
195
        ctxt->input->flags |= XML_INPUT_ENCODING_ERROR;
807
195
    }
808
72.7k
    ctxt->input->cur++;
809
72.7k
    return;
810
15.9M
}
811
812
/**
813
 * xmlCurrentChar:
814
 * @ctxt:  the XML parser context
815
 * @len:  pointer to the length of the char read
816
 *
817
 * DEPRECATED: Internal function, do not use.
818
 *
819
 * The current char value, if using UTF-8 this may actually span multiple
820
 * bytes in the input buffer. Implement the end of line normalization:
821
 * 2.11 End-of-Line Handling
822
 * Wherever an external parsed entity or the literal entity value
823
 * of an internal parsed entity contains either the literal two-character
824
 * sequence "#xD#xA" or a standalone literal #xD, an XML processor
825
 * must pass to the application the single character #xA.
826
 * This behavior can conveniently be produced by normalizing all
827
 * line breaks to #xA on input, before parsing.)
828
 *
829
 * Returns the current char value and its length
830
 */
831
832
int
833
445M
xmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) {
834
445M
    const unsigned char *cur;
835
445M
    size_t avail;
836
445M
    int c;
837
838
445M
    if ((ctxt == NULL) || (len == NULL) || (ctxt->input == NULL)) return(0);
839
445M
    if (ctxt->instate == XML_PARSER_EOF)
840
0
  return(0);
841
842
445M
    avail = ctxt->input->end - ctxt->input->cur;
843
844
445M
    if (avail < INPUT_CHUNK) {
845
573k
        xmlParserGrow(ctxt);
846
573k
        if (ctxt->instate == XML_PARSER_EOF)
847
0
            return(0);
848
573k
        avail = ctxt->input->end - ctxt->input->cur;
849
573k
    }
850
851
445M
    cur = ctxt->input->cur;
852
445M
    c = *cur;
853
854
445M
    if (c < 0x80) {
855
  /* 1-byte code */
856
8.51M
        if (c < 0x20) {
857
            /*
858
             *   2.11 End-of-Line Handling
859
             *   the literal two-character sequence "#xD#xA" or a standalone
860
             *   literal #xD, an XML processor must pass to the application
861
             *   the single character #xA.
862
             */
863
840k
            if (c == '\r') {
864
                /*
865
                 * TODO: This function shouldn't change the 'cur' pointer
866
                 * as side effect, but the NEXTL macro in parser.c relies
867
                 * on this behavior when incrementing line numbers.
868
                 */
869
608k
                if (cur[1] == '\n')
870
85.9k
                    ctxt->input->cur++;
871
608k
                *len = 1;
872
608k
                c = '\n';
873
608k
            } else if (c == 0) {
874
9.53k
                if (ctxt->input->cur >= ctxt->input->end) {
875
8.93k
                    *len = 0;
876
8.93k
                } else {
877
596
                    *len = 1;
878
                    /*
879
                     * TODO: Null bytes should be handled by callers,
880
                     * but this can be tricky.
881
                     */
882
596
                    xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR,
883
596
                            "Char 0x0 out of allowed range\n", c);
884
596
                }
885
222k
            } else {
886
222k
                *len = 1;
887
222k
            }
888
7.67M
        } else {
889
7.67M
            *len = 1;
890
7.67M
        }
891
892
8.51M
        return(c);
893
436M
    } else {
894
436M
        int val;
895
896
436M
        if (avail < 2)
897
769
            goto incomplete_sequence;
898
436M
        if ((cur[1] & 0xc0) != 0x80)
899
1.14M
            goto encoding_error;
900
901
435M
        if (c < 0xe0) {
902
            /* 2-byte code */
903
4.72M
            if (c < 0xc2)
904
4.57M
                goto encoding_error;
905
145k
            val = (c & 0x1f) << 6;
906
145k
            val |= cur[1] & 0x3f;
907
145k
            *len = 2;
908
431M
        } else {
909
431M
            if (avail < 3)
910
94
                goto incomplete_sequence;
911
431M
            if ((cur[2] & 0xc0) != 0x80)
912
7.99k
                goto encoding_error;
913
914
431M
            if (c < 0xf0) {
915
                /* 3-byte code */
916
430M
                val = (c & 0xf) << 12;
917
430M
                val |= (cur[1] & 0x3f) << 6;
918
430M
                val |= cur[2] & 0x3f;
919
430M
                if ((val < 0x800) || ((val >= 0xd800) && (val < 0xe000)))
920
1.78k
                    goto encoding_error;
921
430M
                *len = 3;
922
430M
            } else {
923
262k
                if (avail < 4)
924
50
                    goto incomplete_sequence;
925
262k
                if ((cur[3] & 0xc0) != 0x80)
926
1.26k
                    goto encoding_error;
927
928
                /* 4-byte code */
929
261k
                val = (c & 0x0f) << 18;
930
261k
                val |= (cur[1] & 0x3f) << 12;
931
261k
                val |= (cur[2] & 0x3f) << 6;
932
261k
                val |= cur[3] & 0x3f;
933
261k
                if ((val < 0x10000) || (val >= 0x110000))
934
112k
                    goto encoding_error;
935
148k
                *len = 4;
936
148k
            }
937
431M
        }
938
939
431M
        return(val);
940
435M
    }
941
942
5.84M
encoding_error:
943
    /* Only report the first error */
944
5.84M
    if ((ctxt->input->flags & XML_INPUT_ENCODING_ERROR) == 0) {
945
4.08k
        if (ctxt->input->end - ctxt->input->cur < 4) {
946
380
            __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
947
380
                         "Input is not proper UTF-8, indicate encoding !\n",
948
380
                         NULL, NULL);
949
3.70k
        } else {
950
3.70k
            char buffer[150];
951
952
3.70k
            snprintf(&buffer[0], 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
953
3.70k
                            ctxt->input->cur[0], ctxt->input->cur[1],
954
3.70k
                            ctxt->input->cur[2], ctxt->input->cur[3]);
955
3.70k
            __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
956
3.70k
                         "Input is not proper UTF-8, indicate encoding !\n%s",
957
3.70k
                         BAD_CAST buffer, NULL);
958
3.70k
        }
959
4.08k
        ctxt->input->flags |= XML_INPUT_ENCODING_ERROR;
960
4.08k
    }
961
5.84M
    *len = 1;
962
5.84M
    return(0xFFFD); /* U+FFFD Replacement Character */
963
964
913
incomplete_sequence:
965
    /*
966
     * An encoding problem may arise from a truncated input buffer
967
     * splitting a character in the middle. In that case do not raise
968
     * an error but return 0. This should only happen when push parsing
969
     * char data.
970
     */
971
913
    *len = 0;
972
913
    return(0);
973
445M
}
974
975
/**
976
 * xmlStringCurrentChar:
977
 * @ctxt:  the XML parser context
978
 * @cur:  pointer to the beginning of the char
979
 * @len:  pointer to the length of the char read
980
 *
981
 * DEPRECATED: Internal function, do not use.
982
 *
983
 * The current char value, if using UTF-8 this may actually span multiple
984
 * bytes in the input buffer.
985
 *
986
 * Returns the current char value and its length
987
 */
988
989
int
990
xmlStringCurrentChar(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
991
21.8M
                     const xmlChar *cur, int *len) {
992
21.8M
    int c;
993
994
21.8M
    if ((cur == NULL) || (len == NULL))
995
0
        return(0);
996
997
    /* cur is zero-terminated, so we can lie about its length. */
998
21.8M
    *len = 4;
999
21.8M
    c = xmlGetUTF8Char(cur, len);
1000
1001
21.8M
    return((c < 0) ? 0 : c);
1002
21.8M
}
1003
1004
/**
1005
 * xmlCopyCharMultiByte:
1006
 * @out:  pointer to an array of xmlChar
1007
 * @val:  the char value
1008
 *
1009
 * append the char value in the array
1010
 *
1011
 * Returns the number of xmlChar written
1012
 */
1013
int
1014
265M
xmlCopyCharMultiByte(xmlChar *out, int val) {
1015
265M
    if ((out == NULL) || (val < 0)) return(0);
1016
    /*
1017
     * We are supposed to handle UTF8, check it's valid
1018
     * From rfc2044: encoding of the Unicode values on UTF-8:
1019
     *
1020
     * UCS-4 range (hex.)           UTF-8 octet sequence (binary)
1021
     * 0000 0000-0000 007F   0xxxxxxx
1022
     * 0000 0080-0000 07FF   110xxxxx 10xxxxxx
1023
     * 0000 0800-0000 FFFF   1110xxxx 10xxxxxx 10xxxxxx
1024
     */
1025
265M
    if  (val >= 0x80) {
1026
265M
  xmlChar *savedout = out;
1027
265M
  int bits;
1028
265M
  if (val <   0x800) { *out++= (val >>  6) | 0xC0;  bits=  0; }
1029
265M
  else if (val < 0x10000) { *out++= (val >> 12) | 0xE0;  bits=  6;}
1030
149k
  else if (val < 0x110000)  { *out++= (val >> 18) | 0xF0;  bits=  12; }
1031
0
  else {
1032
0
      xmlErrEncodingInt(NULL, XML_ERR_INVALID_CHAR,
1033
0
        "Internal error, xmlCopyCharMultiByte 0x%X out of bound\n",
1034
0
            val);
1035
0
      return(0);
1036
0
  }
1037
797M
  for ( ; bits >= 0; bits-= 6)
1038
531M
      *out++= ((val >> bits) & 0x3F) | 0x80 ;
1039
265M
  return (out - savedout);
1040
265M
    }
1041
0
    *out = val;
1042
0
    return 1;
1043
265M
}
1044
1045
/**
1046
 * xmlCopyChar:
1047
 * @len:  Ignored, compatibility
1048
 * @out:  pointer to an array of xmlChar
1049
 * @val:  the char value
1050
 *
1051
 * append the char value in the array
1052
 *
1053
 * Returns the number of xmlChar written
1054
 */
1055
1056
int
1057
29.1k
xmlCopyChar(int len ATTRIBUTE_UNUSED, xmlChar *out, int val) {
1058
29.1k
    if ((out == NULL) || (val < 0)) return(0);
1059
    /* the len parameter is ignored */
1060
29.1k
    if  (val >= 0x80) {
1061
23.8k
  return(xmlCopyCharMultiByte (out, val));
1062
23.8k
    }
1063
5.31k
    *out = val;
1064
5.31k
    return 1;
1065
29.1k
}
1066
1067
/************************************************************************
1068
 *                  *
1069
 *    Commodity functions to switch encodings     *
1070
 *                  *
1071
 ************************************************************************/
1072
1073
static xmlCharEncodingHandlerPtr
1074
246
xmlDetectEBCDIC(xmlParserInputPtr input) {
1075
246
    xmlChar out[200];
1076
246
    xmlCharEncodingHandlerPtr handler;
1077
246
    int inlen, outlen, res, i;
1078
1079
    /*
1080
     * To detect the EBCDIC code page, we convert the first 200 bytes
1081
     * to EBCDIC-US and try to find the encoding declaration.
1082
     */
1083
246
    handler = xmlGetCharEncodingHandler(XML_CHAR_ENCODING_EBCDIC);
1084
246
    if (handler == NULL)
1085
0
        return(NULL);
1086
246
    outlen = sizeof(out) - 1;
1087
246
    inlen = input->end - input->cur;
1088
246
    res = xmlEncInputChunk(handler, out, &outlen, input->cur, &inlen);
1089
246
    if (res < 0)
1090
8
        return(handler);
1091
238
    out[outlen] = 0;
1092
1093
3.08k
    for (i = 0; i < outlen; i++) {
1094
2.98k
        if (out[i] == '>')
1095
2
            break;
1096
2.98k
        if ((out[i] == 'e') &&
1097
2.98k
            (xmlStrncmp(out + i, BAD_CAST "encoding", 8) == 0)) {
1098
135
            int start, cur, quote;
1099
1100
135
            i += 8;
1101
135
            while (IS_BLANK_CH(out[i]))
1102
654
                i += 1;
1103
135
            if (out[i++] != '=')
1104
26
                break;
1105
109
            while (IS_BLANK_CH(out[i]))
1106
592
                i += 1;
1107
109
            quote = out[i++];
1108
109
            if ((quote != '\'') && (quote != '"'))
1109
33
                break;
1110
76
            start = i;
1111
76
            cur = out[i];
1112
1.86k
            while (((cur >= 'a') && (cur <= 'z')) ||
1113
1.86k
                   ((cur >= 'A') && (cur <= 'Z')) ||
1114
1.86k
                   ((cur >= '0') && (cur <= '9')) ||
1115
1.86k
                   (cur == '.') || (cur == '_') ||
1116
1.86k
                   (cur == '-'))
1117
1.79k
                cur = out[++i];
1118
76
            if (cur != quote)
1119
67
                break;
1120
9
            out[i] = 0;
1121
9
            xmlCharEncCloseFunc(handler);
1122
9
            return(xmlFindCharEncodingHandler((char *) out + start));
1123
76
        }
1124
2.98k
    }
1125
1126
    /*
1127
     * ICU handlers are stateful, so we have to recreate them.
1128
     */
1129
229
    xmlCharEncCloseFunc(handler);
1130
229
    return(xmlGetCharEncodingHandler(XML_CHAR_ENCODING_EBCDIC));
1131
238
}
1132
1133
/**
1134
 * xmlSwitchEncoding:
1135
 * @ctxt:  the parser context
1136
 * @enc:  the encoding value (number)
1137
 *
1138
 * Use encoding specified by enum to decode input data.
1139
 *
1140
 * This function can be used to enforce the encoding of chunks passed
1141
 * to xmlParseChunk.
1142
 *
1143
 * Returns 0 in case of success, -1 otherwise
1144
 */
1145
int
1146
xmlSwitchEncoding(xmlParserCtxtPtr ctxt, xmlCharEncoding enc)
1147
1.27k
{
1148
1.27k
    xmlCharEncodingHandlerPtr handler = NULL;
1149
1.27k
    int check = 1;
1150
1.27k
    int ret;
1151
1152
1.27k
    if ((ctxt == NULL) || (ctxt->input == NULL))
1153
0
        return(-1);
1154
1155
1.27k
    switch (enc) {
1156
0
  case XML_CHAR_ENCODING_NONE:
1157
452
  case XML_CHAR_ENCODING_UTF8:
1158
452
        case XML_CHAR_ENCODING_ASCII:
1159
452
            check = 0;
1160
452
            break;
1161
246
        case XML_CHAR_ENCODING_EBCDIC:
1162
246
            handler = xmlDetectEBCDIC(ctxt->input);
1163
246
            break;
1164
581
        default:
1165
581
            handler = xmlGetCharEncodingHandler(enc);
1166
581
            break;
1167
1.27k
    }
1168
1169
1.27k
    if ((check) && (handler == NULL)) {
1170
8
        const char *name = xmlGetCharEncodingName(enc);
1171
1172
8
        __xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
1173
8
                "encoding not supported: %s\n",
1174
8
                BAD_CAST (name ? name : "<null>"), NULL);
1175
        /*
1176
         * TODO: We could recover from errors in external entities
1177
         * if we didn't stop the parser. But most callers of this
1178
         * function don't check the return value.
1179
         */
1180
8
        xmlStopParser(ctxt);
1181
8
        return(-1);
1182
8
    }
1183
1184
1.27k
    ret = xmlSwitchInputEncoding(ctxt, ctxt->input, handler);
1185
1186
1.27k
    if ((ret >= 0) && (enc == XML_CHAR_ENCODING_NONE)) {
1187
0
        ctxt->input->flags &= ~XML_INPUT_HAS_ENCODING;
1188
0
    }
1189
1190
1.27k
    return(ret);
1191
1.27k
}
1192
1193
/**
1194
 * xmlSwitchInputEncoding:
1195
 * @ctxt:  the parser context
1196
 * @input:  the input stream
1197
 * @handler:  the encoding handler
1198
 *
1199
 * DEPRECATED: Internal function, don't use.
1200
 *
1201
 * Use encoding handler to decode input data.
1202
 *
1203
 * Returns 0 in case of success, -1 otherwise
1204
 */
1205
int
1206
xmlSwitchInputEncoding(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
1207
                       xmlCharEncodingHandlerPtr handler)
1208
3.21k
{
1209
3.21k
    int nbchars;
1210
3.21k
    xmlParserInputBufferPtr in;
1211
1212
3.21k
    if ((input == NULL) || (input->buf == NULL)) {
1213
0
        xmlCharEncCloseFunc(handler);
1214
0
  return (-1);
1215
0
    }
1216
3.21k
    in = input->buf;
1217
1218
3.21k
    input->flags |= XML_INPUT_HAS_ENCODING;
1219
1220
    /*
1221
     * UTF-8 requires no encoding handler.
1222
     */
1223
3.21k
    if ((handler != NULL) &&
1224
3.21k
        (xmlStrcasecmp(BAD_CAST handler->name, BAD_CAST "UTF-8") == 0)) {
1225
195
        xmlCharEncCloseFunc(handler);
1226
195
        handler = NULL;
1227
195
    }
1228
1229
3.21k
    if (in->encoder == handler)
1230
647
        return (0);
1231
1232
2.57k
    if (in->encoder != NULL) {
1233
        /*
1234
         * Switching encodings during parsing is a really bad idea,
1235
         * but Chromium can switch between ISO-8859-1 and UTF-16 before
1236
         * separate calls to xmlParseChunk.
1237
         *
1238
         * TODO: We should check whether the "raw" input buffer is empty and
1239
         * convert the old content using the old encoder.
1240
         */
1241
1242
0
        xmlCharEncCloseFunc(in->encoder);
1243
0
        in->encoder = handler;
1244
0
        return (0);
1245
0
    }
1246
1247
2.57k
    in->encoder = handler;
1248
1249
    /*
1250
     * Is there already some content down the pipe to convert ?
1251
     */
1252
2.57k
    if (xmlBufIsEmpty(in->buffer) == 0) {
1253
2.57k
        size_t processed;
1254
1255
        /*
1256
         * Shrink the current input buffer.
1257
         * Move it as the raw buffer and create a new input buffer
1258
         */
1259
2.57k
        processed = input->cur - input->base;
1260
2.57k
        xmlBufShrink(in->buffer, processed);
1261
2.57k
        input->consumed += processed;
1262
2.57k
        in->raw = in->buffer;
1263
2.57k
        in->buffer = xmlBufCreate();
1264
2.57k
        in->rawconsumed = processed;
1265
1266
2.57k
        nbchars = xmlCharEncInput(in);
1267
2.57k
        xmlBufResetInput(in->buffer, input);
1268
2.57k
        if (nbchars < 0) {
1269
            /* TODO: This could be an out of memory or an encoding error. */
1270
11
            xmlErrInternal(ctxt,
1271
11
                           "switching encoding: encoder error\n",
1272
11
                           NULL);
1273
11
            xmlHaltParser(ctxt);
1274
11
            return (-1);
1275
11
        }
1276
2.57k
    }
1277
2.56k
    return (0);
1278
2.57k
}
1279
1280
/**
1281
 * xmlSwitchToEncoding:
1282
 * @ctxt:  the parser context
1283
 * @handler:  the encoding handler
1284
 *
1285
 * Use encoding handler to decode input data.
1286
 *
1287
 * This function can be used to enforce the encoding of chunks passed
1288
 * to xmlParseChunk.
1289
 *
1290
 * Returns 0 in case of success, -1 otherwise
1291
 */
1292
int
1293
xmlSwitchToEncoding(xmlParserCtxtPtr ctxt, xmlCharEncodingHandlerPtr handler)
1294
1.94k
{
1295
1.94k
    if (ctxt == NULL)
1296
0
        return(-1);
1297
1.94k
    return(xmlSwitchInputEncoding(ctxt, ctxt->input, handler));
1298
1.94k
}
1299
1300
/**
1301
 * xmlDetectEncoding:
1302
 * @ctxt:  the parser context
1303
 *
1304
 * Handle optional BOM, detect and switch to encoding.
1305
 *
1306
 * Assumes that there are at least four bytes in the input buffer.
1307
 */
1308
void
1309
16.2k
xmlDetectEncoding(xmlParserCtxtPtr ctxt) {
1310
16.2k
    const xmlChar *in;
1311
16.2k
    xmlCharEncoding enc;
1312
16.2k
    int bomSize;
1313
16.2k
    int autoFlag = 0;
1314
1315
16.2k
    if (xmlParserGrow(ctxt) < 0)
1316
0
        return;
1317
16.2k
    in = ctxt->input->cur;
1318
16.2k
    if (ctxt->input->end - in < 4)
1319
284
        return;
1320
1321
16.0k
    if (ctxt->input->flags & XML_INPUT_HAS_ENCODING) {
1322
        /*
1323
         * If the encoding was already set, only skip the BOM which was
1324
         * possibly decoded to UTF-8.
1325
         */
1326
0
        if ((in[0] == 0xEF) && (in[1] == 0xBB) && (in[2] == 0xBF)) {
1327
0
            ctxt->input->cur += 3;
1328
0
        }
1329
1330
0
        return;
1331
0
    }
1332
1333
16.0k
    enc = XML_CHAR_ENCODING_NONE;
1334
16.0k
    bomSize = 0;
1335
1336
16.0k
    switch (in[0]) {
1337
110
        case 0x00:
1338
110
            if ((in[1] == 0x00) && (in[2] == 0x00) && (in[3] == 0x3C)) {
1339
18
                enc = XML_CHAR_ENCODING_UCS4BE;
1340
18
                autoFlag = XML_INPUT_AUTO_OTHER;
1341
92
            } else if ((in[1] == 0x3C) && (in[2] == 0x00) && (in[3] == 0x3F)) {
1342
69
                enc = XML_CHAR_ENCODING_UTF16BE;
1343
69
                autoFlag = XML_INPUT_AUTO_UTF16BE;
1344
69
            }
1345
110
            break;
1346
1347
14.6k
        case 0x3C:
1348
14.6k
            if (in[1] == 0x00) {
1349
197
                if ((in[2] == 0x00) && (in[3] == 0x00)) {
1350
3
                    enc = XML_CHAR_ENCODING_UCS4LE;
1351
3
                    autoFlag = XML_INPUT_AUTO_OTHER;
1352
194
                } else if ((in[2] == 0x3F) && (in[3] == 0x00)) {
1353
183
                    enc = XML_CHAR_ENCODING_UTF16LE;
1354
183
                    autoFlag = XML_INPUT_AUTO_UTF16LE;
1355
183
                }
1356
197
            }
1357
14.6k
            break;
1358
1359
263
        case 0x4C:
1360
263
      if ((in[1] == 0x6F) && (in[2] == 0xA7) && (in[3] == 0x94)) {
1361
246
          enc = XML_CHAR_ENCODING_EBCDIC;
1362
246
                autoFlag = XML_INPUT_AUTO_OTHER;
1363
246
            }
1364
263
            break;
1365
1366
456
        case 0xEF:
1367
456
            if ((in[1] == 0xBB) && (in[2] == 0xBF)) {
1368
452
                enc = XML_CHAR_ENCODING_UTF8;
1369
452
                autoFlag = XML_INPUT_AUTO_UTF8;
1370
452
                bomSize = 3;
1371
452
            }
1372
456
            break;
1373
1374
198
        case 0xFE:
1375
198
            if (in[1] == 0xFF) {
1376
191
                enc = XML_CHAR_ENCODING_UTF16BE;
1377
191
                autoFlag = XML_INPUT_AUTO_UTF16BE;
1378
191
                bomSize = 2;
1379
191
            }
1380
198
            break;
1381
1382
126
        case 0xFF:
1383
126
            if (in[1] == 0xFE) {
1384
117
                enc = XML_CHAR_ENCODING_UTF16LE;
1385
117
                autoFlag = XML_INPUT_AUTO_UTF16LE;
1386
117
                bomSize = 2;
1387
117
            }
1388
126
            break;
1389
16.0k
    }
1390
1391
16.0k
    if (bomSize > 0) {
1392
760
        ctxt->input->cur += bomSize;
1393
760
    }
1394
1395
16.0k
    if (enc != XML_CHAR_ENCODING_NONE) {
1396
1.27k
        ctxt->input->flags |= autoFlag;
1397
1.27k
        xmlSwitchEncoding(ctxt, enc);
1398
1.27k
    }
1399
16.0k
}
1400
1401
/**
1402
 * xmlSetDeclaredEncoding:
1403
 * @ctxt:  the parser context
1404
 * @encoding:  declared encoding
1405
 *
1406
 * Set the encoding from a declaration in the document.
1407
 *
1408
 * If no encoding was set yet, switch the encoding. Otherwise, only warn
1409
 * about encoding mismatches.
1410
 *
1411
 * Takes ownership of 'encoding'.
1412
 */
1413
void
1414
2.38k
xmlSetDeclaredEncoding(xmlParserCtxtPtr ctxt, xmlChar *encoding) {
1415
2.38k
    if (ctxt->encoding != NULL)
1416
0
        xmlFree((xmlChar *) ctxt->encoding);
1417
2.38k
    ctxt->encoding = encoding;
1418
1419
2.38k
    if (((ctxt->input->flags & XML_INPUT_HAS_ENCODING) == 0) &&
1420
2.38k
        ((ctxt->options & XML_PARSE_IGNORE_ENC) == 0)) {
1421
2.36k
        xmlCharEncodingHandlerPtr handler;
1422
1423
2.36k
        handler = xmlFindCharEncodingHandler((const char *) encoding);
1424
2.36k
        if (handler == NULL) {
1425
419
            __xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
1426
419
                             "Unsupported encoding: %s\n",
1427
419
                             encoding, NULL);
1428
419
            return;
1429
419
        }
1430
1431
1.94k
        xmlSwitchToEncoding(ctxt, handler);
1432
1.94k
        ctxt->input->flags |= XML_INPUT_USES_ENC_DECL;
1433
1.94k
    } else if (ctxt->input->flags & XML_INPUT_AUTO_ENCODING) {
1434
13
        static const char *allowedUTF8[] = {
1435
13
            "UTF-8", "UTF8", NULL
1436
13
        };
1437
13
        static const char *allowedUTF16LE[] = {
1438
13
            "UTF-16", "UTF-16LE", "UTF16", NULL
1439
13
        };
1440
13
        static const char *allowedUTF16BE[] = {
1441
13
            "UTF-16", "UTF-16BE", "UTF16", NULL
1442
13
        };
1443
13
        const char **allowed = NULL;
1444
13
        const char *autoEnc = NULL;
1445
1446
13
        switch (ctxt->input->flags & XML_INPUT_AUTO_ENCODING) {
1447
9
            case XML_INPUT_AUTO_UTF8:
1448
9
                allowed = allowedUTF8;
1449
9
                autoEnc = "UTF-8";
1450
9
                break;
1451
2
            case XML_INPUT_AUTO_UTF16LE:
1452
2
                allowed = allowedUTF16LE;
1453
2
                autoEnc = "UTF-16LE";
1454
2
                break;
1455
1
            case XML_INPUT_AUTO_UTF16BE:
1456
1
                allowed = allowedUTF16BE;
1457
1
                autoEnc = "UTF-16BE";
1458
1
                break;
1459
13
        }
1460
1461
13
        if (allowed != NULL) {
1462
12
            const char **p;
1463
12
            int match = 0;
1464
1465
36
            for (p = allowed; *p != NULL; p++) {
1466
26
                if (xmlStrcasecmp(encoding, BAD_CAST *p) == 0) {
1467
2
                    match = 1;
1468
2
                    break;
1469
2
                }
1470
26
            }
1471
1472
12
            if (match == 0) {
1473
10
                xmlWarningMsg(ctxt, XML_WAR_ENCODING_MISMATCH,
1474
10
                              "Encoding '%s' doesn't match "
1475
10
                              "auto-detected '%s'\n",
1476
10
                              encoding, BAD_CAST autoEnc);
1477
10
            }
1478
12
        }
1479
13
    }
1480
2.38k
}
1481
1482
/************************************************************************
1483
 *                  *
1484
 *  Commodity functions to handle entities processing   *
1485
 *                  *
1486
 ************************************************************************/
1487
1488
/**
1489
 * xmlFreeInputStream:
1490
 * @input:  an xmlParserInputPtr
1491
 *
1492
 * Free up an input stream.
1493
 */
1494
void
1495
16.2k
xmlFreeInputStream(xmlParserInputPtr input) {
1496
16.2k
    if (input == NULL) return;
1497
1498
16.2k
    if (input->filename != NULL) xmlFree((char *) input->filename);
1499
16.2k
    if (input->directory != NULL) xmlFree((char *) input->directory);
1500
16.2k
    if (input->version != NULL) xmlFree((char *) input->version);
1501
16.2k
    if ((input->free != NULL) && (input->base != NULL))
1502
0
        input->free((xmlChar *) input->base);
1503
16.2k
    if (input->buf != NULL)
1504
11.8k
        xmlFreeParserInputBuffer(input->buf);
1505
16.2k
    xmlFree(input);
1506
16.2k
}
1507
1508
/**
1509
 * xmlNewInputStream:
1510
 * @ctxt:  an XML parser context
1511
 *
1512
 * Create a new input stream structure.
1513
 *
1514
 * Returns the new input stream or NULL
1515
 */
1516
xmlParserInputPtr
1517
16.2k
xmlNewInputStream(xmlParserCtxtPtr ctxt) {
1518
16.2k
    xmlParserInputPtr input;
1519
1520
16.2k
    input = (xmlParserInputPtr) xmlMalloc(sizeof(xmlParserInput));
1521
16.2k
    if (input == NULL) {
1522
0
        xmlErrMemory(ctxt,  "couldn't allocate a new input stream\n");
1523
0
  return(NULL);
1524
0
    }
1525
16.2k
    memset(input, 0, sizeof(xmlParserInput));
1526
16.2k
    input->line = 1;
1527
16.2k
    input->col = 1;
1528
1529
    /*
1530
     * If the context is NULL the id cannot be initialized, but that
1531
     * should not happen while parsing which is the situation where
1532
     * the id is actually needed.
1533
     */
1534
16.2k
    if (ctxt != NULL) {
1535
16.2k
        if (input->id >= INT_MAX) {
1536
0
            xmlErrMemory(ctxt, "Input ID overflow\n");
1537
0
            return(NULL);
1538
0
        }
1539
16.2k
        input->id = ctxt->input_id++;
1540
16.2k
    }
1541
1542
16.2k
    return(input);
1543
16.2k
}
1544
1545
/**
1546
 * xmlNewIOInputStream:
1547
 * @ctxt:  an XML parser context
1548
 * @input:  an I/O Input
1549
 * @enc:  the charset encoding if known
1550
 *
1551
 * Create a new input stream structure encapsulating the @input into
1552
 * a stream suitable for the parser.
1553
 *
1554
 * Returns the new input stream or NULL
1555
 */
1556
xmlParserInputPtr
1557
xmlNewIOInputStream(xmlParserCtxtPtr ctxt, xmlParserInputBufferPtr input,
1558
0
              xmlCharEncoding enc) {
1559
0
    xmlParserInputPtr inputStream;
1560
1561
0
    if (input == NULL) return(NULL);
1562
0
    if (xmlParserDebugEntities)
1563
0
  xmlGenericError(xmlGenericErrorContext, "new input from I/O\n");
1564
0
    inputStream = xmlNewInputStream(ctxt);
1565
0
    if (inputStream == NULL) {
1566
0
  return(NULL);
1567
0
    }
1568
0
    inputStream->filename = NULL;
1569
0
    inputStream->buf = input;
1570
0
    xmlBufResetInput(inputStream->buf->buffer, inputStream);
1571
1572
0
    if (enc != XML_CHAR_ENCODING_NONE) {
1573
0
        xmlSwitchEncoding(ctxt, enc);
1574
0
    }
1575
1576
0
    return(inputStream);
1577
0
}
1578
1579
/**
1580
 * xmlNewEntityInputStream:
1581
 * @ctxt:  an XML parser context
1582
 * @entity:  an Entity pointer
1583
 *
1584
 * DEPRECATED: Internal function, do not use.
1585
 *
1586
 * Create a new input stream based on an xmlEntityPtr
1587
 *
1588
 * Returns the new input stream or NULL
1589
 */
1590
xmlParserInputPtr
1591
0
xmlNewEntityInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
1592
0
    xmlParserInputPtr input;
1593
1594
0
    if (entity == NULL) {
1595
0
        xmlErrInternal(ctxt, "xmlNewEntityInputStream entity = NULL\n",
1596
0
                 NULL);
1597
0
  return(NULL);
1598
0
    }
1599
0
    if (xmlParserDebugEntities)
1600
0
  xmlGenericError(xmlGenericErrorContext,
1601
0
    "new input from entity: %s\n", entity->name);
1602
0
    if (entity->content == NULL) {
1603
0
  switch (entity->etype) {
1604
0
            case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
1605
0
          xmlErrInternal(ctxt, "Cannot parse entity %s\n",
1606
0
                   entity->name);
1607
0
                break;
1608
0
            case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
1609
0
            case XML_EXTERNAL_PARAMETER_ENTITY:
1610
0
    input = xmlLoadExternalEntity((char *) entity->URI,
1611
0
           (char *) entity->ExternalID, ctxt);
1612
0
                if (input != NULL)
1613
0
                    input->entity = entity;
1614
0
                return(input);
1615
0
            case XML_INTERNAL_GENERAL_ENTITY:
1616
0
          xmlErrInternal(ctxt,
1617
0
          "Internal entity %s without content !\n",
1618
0
                   entity->name);
1619
0
                break;
1620
0
            case XML_INTERNAL_PARAMETER_ENTITY:
1621
0
          xmlErrInternal(ctxt,
1622
0
          "Internal parameter entity %s without content !\n",
1623
0
                   entity->name);
1624
0
                break;
1625
0
            case XML_INTERNAL_PREDEFINED_ENTITY:
1626
0
          xmlErrInternal(ctxt,
1627
0
          "Predefined entity %s without content !\n",
1628
0
                   entity->name);
1629
0
                break;
1630
0
  }
1631
0
  return(NULL);
1632
0
    }
1633
0
    input = xmlNewInputStream(ctxt);
1634
0
    if (input == NULL) {
1635
0
  return(NULL);
1636
0
    }
1637
0
    if (entity->URI != NULL)
1638
0
  input->filename = (char *) xmlStrdup((xmlChar *) entity->URI);
1639
0
    input->base = entity->content;
1640
0
    if (entity->length == 0)
1641
0
        entity->length = xmlStrlen(entity->content);
1642
0
    input->cur = entity->content;
1643
0
    input->length = entity->length;
1644
0
    input->end = &entity->content[input->length];
1645
0
    input->entity = entity;
1646
0
    return(input);
1647
0
}
1648
1649
/**
1650
 * xmlNewStringInputStream:
1651
 * @ctxt:  an XML parser context
1652
 * @buffer:  an memory buffer
1653
 *
1654
 * Create a new input stream based on a memory buffer.
1655
 * Returns the new input stream
1656
 */
1657
xmlParserInputPtr
1658
0
xmlNewStringInputStream(xmlParserCtxtPtr ctxt, const xmlChar *buffer) {
1659
0
    xmlParserInputPtr input;
1660
0
    xmlParserInputBufferPtr buf;
1661
1662
0
    if (buffer == NULL) {
1663
0
        xmlErrInternal(ctxt, "xmlNewStringInputStream string = NULL\n",
1664
0
                 NULL);
1665
0
  return(NULL);
1666
0
    }
1667
0
    if (xmlParserDebugEntities)
1668
0
  xmlGenericError(xmlGenericErrorContext,
1669
0
    "new fixed input: %.30s\n", buffer);
1670
0
    buf = xmlParserInputBufferCreateString(buffer);
1671
0
    if (buf == NULL) {
1672
0
  xmlErrMemory(ctxt, NULL);
1673
0
        return(NULL);
1674
0
    }
1675
0
    input = xmlNewInputStream(ctxt);
1676
0
    if (input == NULL) {
1677
0
        xmlErrMemory(ctxt,  "couldn't allocate a new input stream\n");
1678
0
  xmlFreeParserInputBuffer(buf);
1679
0
  return(NULL);
1680
0
    }
1681
0
    input->buf = buf;
1682
0
    xmlBufResetInput(input->buf->buffer, input);
1683
0
    return(input);
1684
0
}
1685
1686
/**
1687
 * xmlNewInputFromFile:
1688
 * @ctxt:  an XML parser context
1689
 * @filename:  the filename to use as entity
1690
 *
1691
 * Create a new input stream based on a file or an URL.
1692
 *
1693
 * Returns the new input stream or NULL in case of error
1694
 */
1695
xmlParserInputPtr
1696
0
xmlNewInputFromFile(xmlParserCtxtPtr ctxt, const char *filename) {
1697
0
    xmlParserInputBufferPtr buf;
1698
0
    xmlParserInputPtr inputStream;
1699
0
    char *directory = NULL;
1700
0
    xmlChar *URI = NULL;
1701
1702
0
    if (xmlParserDebugEntities)
1703
0
  xmlGenericError(xmlGenericErrorContext,
1704
0
    "new input from file: %s\n", filename);
1705
0
    if (ctxt == NULL) return(NULL);
1706
0
    buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
1707
0
    if (buf == NULL) {
1708
0
  if (filename == NULL)
1709
0
      __xmlLoaderErr(ctxt,
1710
0
                     "failed to load external entity: NULL filename \n",
1711
0
         NULL);
1712
0
  else
1713
0
      __xmlLoaderErr(ctxt, "failed to load external entity \"%s\"\n",
1714
0
         (const char *) filename);
1715
0
  return(NULL);
1716
0
    }
1717
1718
0
    inputStream = xmlNewInputStream(ctxt);
1719
0
    if (inputStream == NULL) {
1720
0
  xmlFreeParserInputBuffer(buf);
1721
0
  return(NULL);
1722
0
    }
1723
1724
0
    inputStream->buf = buf;
1725
0
    inputStream = xmlCheckHTTPInput(ctxt, inputStream);
1726
0
    if (inputStream == NULL)
1727
0
        return(NULL);
1728
1729
0
    if (inputStream->filename == NULL)
1730
0
  URI = xmlStrdup((xmlChar *) filename);
1731
0
    else
1732
0
  URI = xmlStrdup((xmlChar *) inputStream->filename);
1733
0
    directory = xmlParserGetDirectory((const char *) URI);
1734
0
    if (inputStream->filename != NULL) xmlFree((char *)inputStream->filename);
1735
0
    inputStream->filename = (char *) xmlCanonicPath((const xmlChar *) URI);
1736
0
    if (URI != NULL) xmlFree((char *) URI);
1737
0
    inputStream->directory = directory;
1738
1739
0
    xmlBufResetInput(inputStream->buf->buffer, inputStream);
1740
0
    if ((ctxt->directory == NULL) && (directory != NULL))
1741
0
        ctxt->directory = (char *) xmlStrdup((const xmlChar *) directory);
1742
0
    return(inputStream);
1743
0
}
1744
1745
/************************************************************************
1746
 *                  *
1747
 *    Commodity functions to handle parser contexts   *
1748
 *                  *
1749
 ************************************************************************/
1750
1751
/**
1752
 * xmlInitSAXParserCtxt:
1753
 * @ctxt:  XML parser context
1754
 * @sax:  SAX handlert
1755
 * @userData:  user data
1756
 *
1757
 * Initialize a SAX parser context
1758
 *
1759
 * Returns 0 in case of success and -1 in case of error
1760
 */
1761
1762
static int
1763
xmlInitSAXParserCtxt(xmlParserCtxtPtr ctxt, const xmlSAXHandler *sax,
1764
                     void *userData)
1765
16.2k
{
1766
16.2k
    xmlParserInputPtr input;
1767
1768
16.2k
    if(ctxt==NULL) {
1769
0
        xmlErrInternal(NULL, "Got NULL parser context\n", NULL);
1770
0
        return(-1);
1771
0
    }
1772
1773
16.2k
    xmlInitParser();
1774
1775
16.2k
    if (ctxt->dict == NULL)
1776
16.2k
  ctxt->dict = xmlDictCreate();
1777
16.2k
    if (ctxt->dict == NULL) {
1778
0
        xmlErrMemory(NULL, "cannot initialize parser context\n");
1779
0
  return(-1);
1780
0
    }
1781
16.2k
    xmlDictSetLimit(ctxt->dict, XML_MAX_DICTIONARY_LIMIT);
1782
1783
16.2k
    if (ctxt->sax == NULL)
1784
16.2k
  ctxt->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
1785
16.2k
    if (ctxt->sax == NULL) {
1786
0
        xmlErrMemory(NULL, "cannot initialize parser context\n");
1787
0
  return(-1);
1788
0
    }
1789
16.2k
    if (sax == NULL) {
1790
0
  memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
1791
0
        xmlSAXVersion(ctxt->sax, 2);
1792
0
        ctxt->userData = ctxt;
1793
16.2k
    } else {
1794
16.2k
  if (sax->initialized == XML_SAX2_MAGIC) {
1795
16.2k
      memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
1796
16.2k
        } else {
1797
0
      memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
1798
0
      memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
1799
0
        }
1800
16.2k
        ctxt->userData = userData ? userData : ctxt;
1801
16.2k
    }
1802
1803
16.2k
    ctxt->maxatts = 0;
1804
16.2k
    ctxt->atts = NULL;
1805
    /* Allocate the Input stack */
1806
16.2k
    if (ctxt->inputTab == NULL) {
1807
16.2k
  ctxt->inputTab = (xmlParserInputPtr *)
1808
16.2k
        xmlMalloc(5 * sizeof(xmlParserInputPtr));
1809
16.2k
  ctxt->inputMax = 5;
1810
16.2k
    }
1811
16.2k
    if (ctxt->inputTab == NULL) {
1812
0
        xmlErrMemory(NULL, "cannot initialize parser context\n");
1813
0
  ctxt->inputNr = 0;
1814
0
  ctxt->inputMax = 0;
1815
0
  ctxt->input = NULL;
1816
0
  return(-1);
1817
0
    }
1818
16.2k
    while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
1819
0
        xmlFreeInputStream(input);
1820
0
    }
1821
16.2k
    ctxt->inputNr = 0;
1822
16.2k
    ctxt->input = NULL;
1823
1824
16.2k
    ctxt->version = NULL;
1825
16.2k
    ctxt->encoding = NULL;
1826
16.2k
    ctxt->standalone = -1;
1827
16.2k
    ctxt->hasExternalSubset = 0;
1828
16.2k
    ctxt->hasPErefs = 0;
1829
16.2k
    ctxt->html = 0;
1830
16.2k
    ctxt->external = 0;
1831
16.2k
    ctxt->instate = XML_PARSER_START;
1832
16.2k
    ctxt->token = 0;
1833
16.2k
    ctxt->directory = NULL;
1834
1835
    /* Allocate the Node stack */
1836
16.2k
    if (ctxt->nodeTab == NULL) {
1837
16.2k
  ctxt->nodeTab = (xmlNodePtr *) xmlMalloc(10 * sizeof(xmlNodePtr));
1838
16.2k
  ctxt->nodeMax = 10;
1839
16.2k
    }
1840
16.2k
    if (ctxt->nodeTab == NULL) {
1841
0
        xmlErrMemory(NULL, "cannot initialize parser context\n");
1842
0
  ctxt->nodeNr = 0;
1843
0
  ctxt->nodeMax = 0;
1844
0
  ctxt->node = NULL;
1845
0
  ctxt->inputNr = 0;
1846
0
  ctxt->inputMax = 0;
1847
0
  ctxt->input = NULL;
1848
0
  return(-1);
1849
0
    }
1850
16.2k
    ctxt->nodeNr = 0;
1851
16.2k
    ctxt->node = NULL;
1852
1853
    /* Allocate the Name stack */
1854
16.2k
    if (ctxt->nameTab == NULL) {
1855
16.2k
  ctxt->nameTab = (const xmlChar **) xmlMalloc(10 * sizeof(xmlChar *));
1856
16.2k
  ctxt->nameMax = 10;
1857
16.2k
    }
1858
16.2k
    if (ctxt->nameTab == NULL) {
1859
0
        xmlErrMemory(NULL, "cannot initialize parser context\n");
1860
0
  ctxt->nodeNr = 0;
1861
0
  ctxt->nodeMax = 0;
1862
0
  ctxt->node = NULL;
1863
0
  ctxt->inputNr = 0;
1864
0
  ctxt->inputMax = 0;
1865
0
  ctxt->input = NULL;
1866
0
  ctxt->nameNr = 0;
1867
0
  ctxt->nameMax = 0;
1868
0
  ctxt->name = NULL;
1869
0
  return(-1);
1870
0
    }
1871
16.2k
    ctxt->nameNr = 0;
1872
16.2k
    ctxt->name = NULL;
1873
1874
    /* Allocate the space stack */
1875
16.2k
    if (ctxt->spaceTab == NULL) {
1876
16.2k
  ctxt->spaceTab = (int *) xmlMalloc(10 * sizeof(int));
1877
16.2k
  ctxt->spaceMax = 10;
1878
16.2k
    }
1879
16.2k
    if (ctxt->spaceTab == NULL) {
1880
0
        xmlErrMemory(NULL, "cannot initialize parser context\n");
1881
0
  ctxt->nodeNr = 0;
1882
0
  ctxt->nodeMax = 0;
1883
0
  ctxt->node = NULL;
1884
0
  ctxt->inputNr = 0;
1885
0
  ctxt->inputMax = 0;
1886
0
  ctxt->input = NULL;
1887
0
  ctxt->nameNr = 0;
1888
0
  ctxt->nameMax = 0;
1889
0
  ctxt->name = NULL;
1890
0
  ctxt->spaceNr = 0;
1891
0
  ctxt->spaceMax = 0;
1892
0
  ctxt->space = NULL;
1893
0
  return(-1);
1894
0
    }
1895
16.2k
    ctxt->spaceNr = 1;
1896
16.2k
    ctxt->spaceMax = 10;
1897
16.2k
    ctxt->spaceTab[0] = -1;
1898
16.2k
    ctxt->space = &ctxt->spaceTab[0];
1899
16.2k
    ctxt->myDoc = NULL;
1900
16.2k
    ctxt->wellFormed = 1;
1901
16.2k
    ctxt->nsWellFormed = 1;
1902
16.2k
    ctxt->valid = 1;
1903
16.2k
    ctxt->loadsubset = xmlLoadExtDtdDefaultValue;
1904
16.2k
    if (ctxt->loadsubset) {
1905
0
        ctxt->options |= XML_PARSE_DTDLOAD;
1906
0
    }
1907
16.2k
    ctxt->validate = xmlDoValidityCheckingDefaultValue;
1908
16.2k
    ctxt->pedantic = xmlPedanticParserDefaultValue;
1909
16.2k
    if (ctxt->pedantic) {
1910
0
        ctxt->options |= XML_PARSE_PEDANTIC;
1911
0
    }
1912
16.2k
    ctxt->linenumbers = xmlLineNumbersDefaultValue;
1913
16.2k
    ctxt->keepBlanks = xmlKeepBlanksDefaultValue;
1914
16.2k
    if (ctxt->keepBlanks == 0) {
1915
0
  ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
1916
0
  ctxt->options |= XML_PARSE_NOBLANKS;
1917
0
    }
1918
1919
16.2k
    ctxt->vctxt.flags = XML_VCTXT_USE_PCTXT;
1920
16.2k
    ctxt->vctxt.userData = ctxt;
1921
16.2k
    ctxt->vctxt.error = xmlParserValidityError;
1922
16.2k
    ctxt->vctxt.warning = xmlParserValidityWarning;
1923
16.2k
    if (ctxt->validate) {
1924
0
  if (xmlGetWarningsDefaultValue == 0)
1925
0
      ctxt->vctxt.warning = NULL;
1926
0
  else
1927
0
      ctxt->vctxt.warning = xmlParserValidityWarning;
1928
0
  ctxt->vctxt.nodeMax = 0;
1929
0
        ctxt->options |= XML_PARSE_DTDVALID;
1930
0
    }
1931
16.2k
    ctxt->replaceEntities = xmlSubstituteEntitiesDefaultValue;
1932
16.2k
    if (ctxt->replaceEntities) {
1933
0
        ctxt->options |= XML_PARSE_NOENT;
1934
0
    }
1935
16.2k
    ctxt->record_info = 0;
1936
16.2k
    ctxt->checkIndex = 0;
1937
16.2k
    ctxt->inSubset = 0;
1938
16.2k
    ctxt->errNo = XML_ERR_OK;
1939
16.2k
    ctxt->depth = 0;
1940
16.2k
    ctxt->catalogs = NULL;
1941
16.2k
    ctxt->sizeentities = 0;
1942
16.2k
    ctxt->sizeentcopy = 0;
1943
16.2k
    ctxt->input_id = 1;
1944
16.2k
    ctxt->maxAmpl = XML_MAX_AMPLIFICATION_DEFAULT;
1945
16.2k
    xmlInitNodeInfoSeq(&ctxt->node_seq);
1946
1947
16.2k
    if (ctxt->nsdb == NULL) {
1948
16.2k
        ctxt->nsdb = xmlParserNsCreate();
1949
16.2k
        if (ctxt->nsdb == NULL) {
1950
0
            xmlErrMemory(ctxt, NULL);
1951
0
            return(-1);
1952
0
        }
1953
16.2k
    }
1954
1955
16.2k
    return(0);
1956
16.2k
}
1957
1958
/**
1959
 * xmlInitParserCtxt:
1960
 * @ctxt:  an XML parser context
1961
 *
1962
 * DEPRECATED: Internal function which will be made private in a future
1963
 * version.
1964
 *
1965
 * Initialize a parser context
1966
 *
1967
 * Returns 0 in case of success and -1 in case of error
1968
 */
1969
1970
int
1971
xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
1972
0
{
1973
0
    return(xmlInitSAXParserCtxt(ctxt, NULL, NULL));
1974
0
}
1975
1976
/**
1977
 * xmlFreeParserCtxt:
1978
 * @ctxt:  an XML parser context
1979
 *
1980
 * Free all the memory used by a parser context. However the parsed
1981
 * document in ctxt->myDoc is not freed.
1982
 */
1983
1984
void
1985
xmlFreeParserCtxt(xmlParserCtxtPtr ctxt)
1986
16.2k
{
1987
16.2k
    xmlParserInputPtr input;
1988
1989
16.2k
    if (ctxt == NULL) return;
1990
1991
32.5k
    while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
1992
16.2k
        xmlFreeInputStream(input);
1993
16.2k
    }
1994
16.2k
    if (ctxt->spaceTab != NULL) xmlFree(ctxt->spaceTab);
1995
16.2k
    if (ctxt->nameTab != NULL) xmlFree((xmlChar * *)ctxt->nameTab);
1996
16.2k
    if (ctxt->nodeTab != NULL) xmlFree(ctxt->nodeTab);
1997
16.2k
    if (ctxt->nodeInfoTab != NULL) xmlFree(ctxt->nodeInfoTab);
1998
16.2k
    if (ctxt->inputTab != NULL) xmlFree(ctxt->inputTab);
1999
16.2k
    if (ctxt->version != NULL) xmlFree((char *) ctxt->version);
2000
16.2k
    if (ctxt->encoding != NULL) xmlFree((char *) ctxt->encoding);
2001
16.2k
    if (ctxt->extSubURI != NULL) xmlFree((char *) ctxt->extSubURI);
2002
16.2k
    if (ctxt->extSubSystem != NULL) xmlFree((char *) ctxt->extSubSystem);
2003
16.2k
#ifdef LIBXML_SAX1_ENABLED
2004
16.2k
    if ((ctxt->sax != NULL) &&
2005
16.2k
        (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler))
2006
#else
2007
    if (ctxt->sax != NULL)
2008
#endif /* LIBXML_SAX1_ENABLED */
2009
16.2k
        xmlFree(ctxt->sax);
2010
16.2k
    if (ctxt->directory != NULL) xmlFree((char *) ctxt->directory);
2011
16.2k
    if (ctxt->vctxt.nodeTab != NULL) xmlFree(ctxt->vctxt.nodeTab);
2012
16.2k
    if (ctxt->atts != NULL) xmlFree((xmlChar * *)ctxt->atts);
2013
16.2k
    if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
2014
16.2k
    if (ctxt->nsTab != NULL) xmlFree(ctxt->nsTab);
2015
16.2k
    if (ctxt->nsdb != NULL) xmlParserNsFree(ctxt->nsdb);
2016
16.2k
    if (ctxt->attrHash != NULL) xmlFree(ctxt->attrHash);
2017
16.2k
    if (ctxt->pushTab != NULL) xmlFree(ctxt->pushTab);
2018
16.2k
    if (ctxt->attallocs != NULL) xmlFree(ctxt->attallocs);
2019
16.2k
    if (ctxt->attsDefault != NULL)
2020
1.50k
        xmlHashFree(ctxt->attsDefault, xmlHashDefaultDeallocator);
2021
16.2k
    if (ctxt->attsSpecial != NULL)
2022
1.58k
        xmlHashFree(ctxt->attsSpecial, NULL);
2023
16.2k
    if (ctxt->freeElems != NULL) {
2024
0
        xmlNodePtr cur, next;
2025
2026
0
  cur = ctxt->freeElems;
2027
0
  while (cur != NULL) {
2028
0
      next = cur->next;
2029
0
      xmlFree(cur);
2030
0
      cur = next;
2031
0
  }
2032
0
    }
2033
16.2k
    if (ctxt->freeAttrs != NULL) {
2034
0
        xmlAttrPtr cur, next;
2035
2036
0
  cur = ctxt->freeAttrs;
2037
0
  while (cur != NULL) {
2038
0
      next = cur->next;
2039
0
      xmlFree(cur);
2040
0
      cur = next;
2041
0
  }
2042
0
    }
2043
    /*
2044
     * cleanup the error strings
2045
     */
2046
16.2k
    if (ctxt->lastError.message != NULL)
2047
15.6k
        xmlFree(ctxt->lastError.message);
2048
16.2k
    if (ctxt->lastError.file != NULL)
2049
0
        xmlFree(ctxt->lastError.file);
2050
16.2k
    if (ctxt->lastError.str1 != NULL)
2051
12.5k
        xmlFree(ctxt->lastError.str1);
2052
16.2k
    if (ctxt->lastError.str2 != NULL)
2053
321
        xmlFree(ctxt->lastError.str2);
2054
16.2k
    if (ctxt->lastError.str3 != NULL)
2055
60
        xmlFree(ctxt->lastError.str3);
2056
2057
16.2k
#ifdef LIBXML_CATALOG_ENABLED
2058
16.2k
    if (ctxt->catalogs != NULL)
2059
34
  xmlCatalogFreeLocal(ctxt->catalogs);
2060
16.2k
#endif
2061
16.2k
    xmlFree(ctxt);
2062
16.2k
}
2063
2064
/**
2065
 * xmlNewParserCtxt:
2066
 *
2067
 * Allocate and initialize a new parser context.
2068
 *
2069
 * Returns the xmlParserCtxtPtr or NULL
2070
 */
2071
2072
xmlParserCtxtPtr
2073
xmlNewParserCtxt(void)
2074
0
{
2075
0
    return(xmlNewSAXParserCtxt(NULL, NULL));
2076
0
}
2077
2078
/**
2079
 * xmlNewSAXParserCtxt:
2080
 * @sax:  SAX handler
2081
 * @userData:  user data
2082
 *
2083
 * Allocate and initialize a new SAX parser context. If userData is NULL,
2084
 * the parser context will be passed as user data.
2085
 *
2086
 * Returns the xmlParserCtxtPtr or NULL if memory allocation failed.
2087
 */
2088
2089
xmlParserCtxtPtr
2090
xmlNewSAXParserCtxt(const xmlSAXHandler *sax, void *userData)
2091
16.2k
{
2092
16.2k
    xmlParserCtxtPtr ctxt;
2093
2094
16.2k
    ctxt = (xmlParserCtxtPtr) xmlMalloc(sizeof(xmlParserCtxt));
2095
16.2k
    if (ctxt == NULL) {
2096
0
  xmlErrMemory(NULL, "cannot allocate parser context\n");
2097
0
  return(NULL);
2098
0
    }
2099
16.2k
    memset(ctxt, 0, sizeof(xmlParserCtxt));
2100
16.2k
    if (xmlInitSAXParserCtxt(ctxt, sax, userData) < 0) {
2101
0
        xmlFreeParserCtxt(ctxt);
2102
0
  return(NULL);
2103
0
    }
2104
16.2k
    return(ctxt);
2105
16.2k
}
2106
2107
/************************************************************************
2108
 *                  *
2109
 *    Handling of node information        *
2110
 *                  *
2111
 ************************************************************************/
2112
2113
/**
2114
 * xmlClearParserCtxt:
2115
 * @ctxt:  an XML parser context
2116
 *
2117
 * Clear (release owned resources) and reinitialize a parser context
2118
 */
2119
2120
void
2121
xmlClearParserCtxt(xmlParserCtxtPtr ctxt)
2122
0
{
2123
0
  if (ctxt==NULL)
2124
0
    return;
2125
0
  xmlClearNodeInfoSeq(&ctxt->node_seq);
2126
0
  xmlCtxtReset(ctxt);
2127
0
}
2128
2129
2130
/**
2131
 * xmlParserFindNodeInfo:
2132
 * @ctx:  an XML parser context
2133
 * @node:  an XML node within the tree
2134
 *
2135
 * DEPRECATED: Don't use.
2136
 *
2137
 * Find the parser node info struct for a given node
2138
 *
2139
 * Returns an xmlParserNodeInfo block pointer or NULL
2140
 */
2141
const xmlParserNodeInfo *
2142
xmlParserFindNodeInfo(const xmlParserCtxtPtr ctx, const xmlNodePtr node)
2143
0
{
2144
0
    unsigned long pos;
2145
2146
0
    if ((ctx == NULL) || (node == NULL))
2147
0
        return (NULL);
2148
    /* Find position where node should be at */
2149
0
    pos = xmlParserFindNodeInfoIndex(&ctx->node_seq, node);
2150
0
    if (pos < ctx->node_seq.length
2151
0
        && ctx->node_seq.buffer[pos].node == node)
2152
0
        return &ctx->node_seq.buffer[pos];
2153
0
    else
2154
0
        return NULL;
2155
0
}
2156
2157
2158
/**
2159
 * xmlInitNodeInfoSeq:
2160
 * @seq:  a node info sequence pointer
2161
 *
2162
 * DEPRECATED: Don't use.
2163
 *
2164
 * -- Initialize (set to initial state) node info sequence
2165
 */
2166
void
2167
xmlInitNodeInfoSeq(xmlParserNodeInfoSeqPtr seq)
2168
16.2k
{
2169
16.2k
    if (seq == NULL)
2170
0
        return;
2171
16.2k
    seq->length = 0;
2172
16.2k
    seq->maximum = 0;
2173
16.2k
    seq->buffer = NULL;
2174
16.2k
}
2175
2176
/**
2177
 * xmlClearNodeInfoSeq:
2178
 * @seq:  a node info sequence pointer
2179
 *
2180
 * DEPRECATED: Don't use.
2181
 *
2182
 * -- Clear (release memory and reinitialize) node
2183
 *   info sequence
2184
 */
2185
void
2186
xmlClearNodeInfoSeq(xmlParserNodeInfoSeqPtr seq)
2187
0
{
2188
0
    if (seq == NULL)
2189
0
        return;
2190
0
    if (seq->buffer != NULL)
2191
0
        xmlFree(seq->buffer);
2192
0
    xmlInitNodeInfoSeq(seq);
2193
0
}
2194
2195
/**
2196
 * xmlParserFindNodeInfoIndex:
2197
 * @seq:  a node info sequence pointer
2198
 * @node:  an XML node pointer
2199
 *
2200
 * DEPRECATED: Don't use.
2201
 *
2202
 * xmlParserFindNodeInfoIndex : Find the index that the info record for
2203
 *   the given node is or should be at in a sorted sequence
2204
 *
2205
 * Returns a long indicating the position of the record
2206
 */
2207
unsigned long
2208
xmlParserFindNodeInfoIndex(const xmlParserNodeInfoSeqPtr seq,
2209
                           const xmlNodePtr node)
2210
0
{
2211
0
    unsigned long upper, lower, middle;
2212
0
    int found = 0;
2213
2214
0
    if ((seq == NULL) || (node == NULL))
2215
0
        return ((unsigned long) -1);
2216
2217
    /* Do a binary search for the key */
2218
0
    lower = 1;
2219
0
    upper = seq->length;
2220
0
    middle = 0;
2221
0
    while (lower <= upper && !found) {
2222
0
        middle = lower + (upper - lower) / 2;
2223
0
        if (node == seq->buffer[middle - 1].node)
2224
0
            found = 1;
2225
0
        else if (node < seq->buffer[middle - 1].node)
2226
0
            upper = middle - 1;
2227
0
        else
2228
0
            lower = middle + 1;
2229
0
    }
2230
2231
    /* Return position */
2232
0
    if (middle == 0 || seq->buffer[middle - 1].node < node)
2233
0
        return middle;
2234
0
    else
2235
0
        return middle - 1;
2236
0
}
2237
2238
2239
/**
2240
 * xmlParserAddNodeInfo:
2241
 * @ctxt:  an XML parser context
2242
 * @info:  a node info sequence pointer
2243
 *
2244
 * DEPRECATED: Don't use.
2245
 *
2246
 * Insert node info record into the sorted sequence
2247
 */
2248
void
2249
xmlParserAddNodeInfo(xmlParserCtxtPtr ctxt,
2250
                     const xmlParserNodeInfoPtr info)
2251
0
{
2252
0
    unsigned long pos;
2253
2254
0
    if ((ctxt == NULL) || (info == NULL)) return;
2255
2256
    /* Find pos and check to see if node is already in the sequence */
2257
0
    pos = xmlParserFindNodeInfoIndex(&ctxt->node_seq, (xmlNodePtr)
2258
0
                                     info->node);
2259
2260
0
    if ((pos < ctxt->node_seq.length) &&
2261
0
        (ctxt->node_seq.buffer != NULL) &&
2262
0
        (ctxt->node_seq.buffer[pos].node == info->node)) {
2263
0
        ctxt->node_seq.buffer[pos] = *info;
2264
0
    }
2265
2266
    /* Otherwise, we need to add new node to buffer */
2267
0
    else {
2268
0
        if ((ctxt->node_seq.length + 1 > ctxt->node_seq.maximum) ||
2269
0
      (ctxt->node_seq.buffer == NULL)) {
2270
0
            xmlParserNodeInfo *tmp_buffer;
2271
0
            unsigned int byte_size;
2272
2273
0
            if (ctxt->node_seq.maximum == 0)
2274
0
                ctxt->node_seq.maximum = 2;
2275
0
            byte_size = (sizeof(*ctxt->node_seq.buffer) *
2276
0
      (2 * ctxt->node_seq.maximum));
2277
2278
0
            if (ctxt->node_seq.buffer == NULL)
2279
0
                tmp_buffer = (xmlParserNodeInfo *) xmlMalloc(byte_size);
2280
0
            else
2281
0
                tmp_buffer =
2282
0
                    (xmlParserNodeInfo *) xmlRealloc(ctxt->node_seq.buffer,
2283
0
                                                     byte_size);
2284
2285
0
            if (tmp_buffer == NULL) {
2286
0
    xmlErrMemory(ctxt, "failed to allocate buffer\n");
2287
0
                return;
2288
0
            }
2289
0
            ctxt->node_seq.buffer = tmp_buffer;
2290
0
            ctxt->node_seq.maximum *= 2;
2291
0
        }
2292
2293
        /* If position is not at end, move elements out of the way */
2294
0
        if (pos != ctxt->node_seq.length) {
2295
0
            unsigned long i;
2296
2297
0
            for (i = ctxt->node_seq.length; i > pos; i--)
2298
0
                ctxt->node_seq.buffer[i] = ctxt->node_seq.buffer[i - 1];
2299
0
        }
2300
2301
        /* Copy element and increase length */
2302
0
        ctxt->node_seq.buffer[pos] = *info;
2303
0
        ctxt->node_seq.length++;
2304
0
    }
2305
0
}
2306
2307
/************************************************************************
2308
 *                  *
2309
 *    Defaults settings         *
2310
 *                  *
2311
 ************************************************************************/
2312
/**
2313
 * xmlPedanticParserDefault:
2314
 * @val:  int 0 or 1
2315
 *
2316
 * DEPRECATED: Use the modern options API with XML_PARSE_PEDANTIC.
2317
 *
2318
 * Set and return the previous value for enabling pedantic warnings.
2319
 *
2320
 * Returns the last value for 0 for no substitution, 1 for substitution.
2321
 */
2322
2323
int
2324
0
xmlPedanticParserDefault(int val) {
2325
0
    int old = xmlPedanticParserDefaultValue;
2326
2327
0
    xmlPedanticParserDefaultValue = val;
2328
0
    return(old);
2329
0
}
2330
2331
/**
2332
 * xmlLineNumbersDefault:
2333
 * @val:  int 0 or 1
2334
 *
2335
 * DEPRECATED: The modern options API always enables line numbers.
2336
 *
2337
 * Set and return the previous value for enabling line numbers in elements
2338
 * contents. This may break on old application and is turned off by default.
2339
 *
2340
 * Returns the last value for 0 for no substitution, 1 for substitution.
2341
 */
2342
2343
int
2344
0
xmlLineNumbersDefault(int val) {
2345
0
    int old = xmlLineNumbersDefaultValue;
2346
2347
0
    xmlLineNumbersDefaultValue = val;
2348
0
    return(old);
2349
0
}
2350
2351
/**
2352
 * xmlSubstituteEntitiesDefault:
2353
 * @val:  int 0 or 1
2354
 *
2355
 * DEPRECATED: Use the modern options API with XML_PARSE_NOENT.
2356
 *
2357
 * Set and return the previous value for default entity support.
2358
 * Initially the parser always keep entity references instead of substituting
2359
 * entity values in the output. This function has to be used to change the
2360
 * default parser behavior
2361
 * SAX::substituteEntities() has to be used for changing that on a file by
2362
 * file basis.
2363
 *
2364
 * Returns the last value for 0 for no substitution, 1 for substitution.
2365
 */
2366
2367
int
2368
0
xmlSubstituteEntitiesDefault(int val) {
2369
0
    int old = xmlSubstituteEntitiesDefaultValue;
2370
2371
0
    xmlSubstituteEntitiesDefaultValue = val;
2372
0
    return(old);
2373
0
}
2374
2375
/**
2376
 * xmlKeepBlanksDefault:
2377
 * @val:  int 0 or 1
2378
 *
2379
 * DEPRECATED: Use the modern options API with XML_PARSE_NOBLANKS.
2380
 *
2381
 * Set and return the previous value for default blanks text nodes support.
2382
 * The 1.x version of the parser used an heuristic to try to detect
2383
 * ignorable white spaces. As a result the SAX callback was generating
2384
 * xmlSAX2IgnorableWhitespace() callbacks instead of characters() one, and when
2385
 * using the DOM output text nodes containing those blanks were not generated.
2386
 * The 2.x and later version will switch to the XML standard way and
2387
 * ignorableWhitespace() are only generated when running the parser in
2388
 * validating mode and when the current element doesn't allow CDATA or
2389
 * mixed content.
2390
 * This function is provided as a way to force the standard behavior
2391
 * on 1.X libs and to switch back to the old mode for compatibility when
2392
 * running 1.X client code on 2.X . Upgrade of 1.X code should be done
2393
 * by using xmlIsBlankNode() commodity function to detect the "empty"
2394
 * nodes generated.
2395
 * This value also affect autogeneration of indentation when saving code
2396
 * if blanks sections are kept, indentation is not generated.
2397
 *
2398
 * Returns the last value for 0 for no substitution, 1 for substitution.
2399
 */
2400
2401
int
2402
0
xmlKeepBlanksDefault(int val) {
2403
0
    int old = xmlKeepBlanksDefaultValue;
2404
2405
0
    xmlKeepBlanksDefaultValue = val;
2406
0
#ifdef LIBXML_OUTPUT_ENABLED
2407
0
    if (!val)
2408
0
        xmlIndentTreeOutput = 1;
2409
0
#endif
2410
0
    return(old);
2411
0
}
2412