Coverage Report

Created: 2025-10-13 06:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libxml2/SAX2.c
Line
Count
Source
1
/*
2
 * SAX2.c : Default SAX2 handler to build a tree.
3
 *
4
 * See Copyright for the status of this software.
5
 *
6
 * Author: Daniel Veillard
7
 */
8
9
10
#define IN_LIBXML
11
#include "libxml.h"
12
#include <stdlib.h>
13
#include <string.h>
14
#include <limits.h>
15
#include <stddef.h>
16
#include <libxml/SAX2.h>
17
#include <libxml/xmlmemory.h>
18
#include <libxml/tree.h>
19
#include <libxml/parser.h>
20
#include <libxml/parserInternals.h>
21
#include <libxml/valid.h>
22
#include <libxml/entities.h>
23
#include <libxml/xmlerror.h>
24
#include <libxml/xmlIO.h>
25
#include <libxml/uri.h>
26
#include <libxml/valid.h>
27
#include <libxml/HTMLtree.h>
28
29
#include "private/error.h"
30
#include "private/parser.h"
31
#include "private/tree.h"
32
33
#ifndef SIZE_MAX
34
  #define SIZE_MAX ((size_t) -1)
35
#endif
36
37
/*
38
 * @param ctxt  an XML validation parser context
39
 * @param msg  a string to accompany the error message
40
 */
41
static void
42
9.66k
xmlSAX2ErrMemory(xmlParserCtxtPtr ctxt) {
43
9.66k
    xmlCtxtErrMemory(ctxt);
44
9.66k
}
45
46
#ifdef LIBXML_VALID_ENABLED
47
/**
48
 * Handle a validation error
49
 *
50
 * @param ctxt  an XML validation parser context
51
 * @param error  the error number
52
 * @param msg  the error message
53
 * @param str1  extra data
54
 * @param str2  extra data
55
 */
56
static void LIBXML_ATTR_FORMAT(3,0)
57
xmlErrValid(xmlParserCtxtPtr ctxt, xmlParserErrors error,
58
            const char *msg, const xmlChar *str1, const xmlChar *str2)
59
40.7k
{
60
40.7k
    xmlCtxtErr(ctxt, NULL, XML_FROM_DTD, error, XML_ERR_ERROR,
61
40.7k
               str1, str2, NULL, 0, msg, str1, str2);
62
40.7k
    if (ctxt != NULL)
63
40.7k
  ctxt->valid = 0;
64
40.7k
}
65
#endif /* LIBXML_VALID_ENABLED */
66
67
/**
68
 * Handle a fatal parser error, i.e. violating Well-Formedness constraints
69
 *
70
 * @param ctxt  an XML parser context
71
 * @param error  the error number
72
 * @param msg  the error message
73
 * @param str1  an error string
74
 * @param str2  an error string
75
 */
76
static void LIBXML_ATTR_FORMAT(3,0)
77
xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
78
               const char *msg, const xmlChar *str1, const xmlChar *str2)
79
1.72k
{
80
1.72k
    xmlCtxtErr(ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
81
1.72k
               str1, str2, NULL, 0, msg, str1, str2);
82
1.72k
}
83
84
/**
85
 * Handle an xml:id error
86
 *
87
 * @param ctxt  an XML validation parser context
88
 * @param error  the error number
89
 * @param msg  the error message
90
 * @param str1  extra data
91
 */
92
static void LIBXML_ATTR_FORMAT(3,0)
93
xmlErrId(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *msg,
94
         const xmlChar *str1)
95
15.5k
{
96
15.5k
    xmlCtxtErr(ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_ERROR,
97
15.5k
               str1, NULL, NULL, 0, msg, str1);
98
15.5k
}
99
100
/**
101
 * Handle a parser warning
102
 *
103
 * @param ctxt  an XML parser context
104
 * @param error  the error number
105
 * @param msg  the error message
106
 * @param str1  an error string
107
 */
108
static void LIBXML_ATTR_FORMAT(3,0)
109
xmlWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
110
               const char *msg, const xmlChar *str1)
111
94.0k
{
112
94.0k
    xmlCtxtErr(ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_WARNING,
113
94.0k
               str1, NULL, NULL, 0, msg, str1);
114
94.0k
}
115
116
/**
117
 * Handle a namespace warning
118
 *
119
 * @param ctxt  an XML parser context
120
 * @param error  the error number
121
 * @param msg  the error message
122
 * @param str1  an error string
123
 * @param str2  an error string
124
 */
125
static void LIBXML_ATTR_FORMAT(3,0)
126
xmlNsWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
127
             const char *msg, const xmlChar *str1, const xmlChar *str2)
128
106k
{
129
106k
    xmlCtxtErr(ctxt, NULL, XML_FROM_NAMESPACE, error, XML_ERR_WARNING,
130
106k
               str1, str2, NULL, 0, msg, str1, str2);
131
106k
}
132
133
/**
134
 * Provides the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN"
135
 *
136
 * @param ctx  the user data (XML parser context)
137
 * @returns a xmlChar *
138
 */
139
const xmlChar *
140
xmlSAX2GetPublicId(void *ctx ATTRIBUTE_UNUSED)
141
0
{
142
    /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
143
0
    return(NULL);
144
0
}
145
146
/**
147
 * Provides the system ID, basically URL or filename e.g.
148
 * http://www.sgmlsource.com/dtds/memo.dtd
149
 *
150
 * @param ctx  the user data (XML parser context)
151
 * @returns a xmlChar *
152
 */
153
const xmlChar *
154
xmlSAX2GetSystemId(void *ctx)
155
0
{
156
0
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
157
0
    if ((ctx == NULL) || (ctxt->input == NULL)) return(NULL);
158
0
    return((const xmlChar *) ctxt->input->filename);
159
0
}
160
161
/**
162
 * Provide the line number of the current parsing point.
163
 *
164
 * @param ctx  the user data (XML parser context)
165
 * @returns an int
166
 */
167
int
168
xmlSAX2GetLineNumber(void *ctx)
169
0
{
170
0
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
171
0
    if ((ctx == NULL) || (ctxt->input == NULL)) return(0);
172
0
    return(ctxt->input->line);
173
0
}
174
175
/**
176
 * Provide the column number of the current parsing point.
177
 *
178
 * @param ctx  the user data (XML parser context)
179
 * @returns an int
180
 */
181
int
182
xmlSAX2GetColumnNumber(void *ctx)
183
0
{
184
0
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
185
0
    if ((ctx == NULL) || (ctxt->input == NULL)) return(0);
186
0
    return(ctxt->input->col);
187
0
}
188
189
/**
190
 * Is this document tagged standalone ?
191
 *
192
 * @param ctx  the user data (XML parser context)
193
 * @returns 1 if true
194
 */
195
int
196
xmlSAX2IsStandalone(void *ctx)
197
0
{
198
0
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
199
0
    if ((ctx == NULL) || (ctxt->myDoc == NULL)) return(0);
200
0
    return(ctxt->myDoc->standalone == 1);
201
0
}
202
203
/**
204
 * Does this document has an internal subset
205
 *
206
 * @param ctx  the user data (XML parser context)
207
 * @returns 1 if true
208
 */
209
int
210
xmlSAX2HasInternalSubset(void *ctx)
211
0
{
212
0
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
213
0
    if ((ctxt == NULL) || (ctxt->myDoc == NULL)) return(0);
214
0
    return(ctxt->myDoc->intSubset != NULL);
215
0
}
216
217
/**
218
 * Does this document has an external subset
219
 *
220
 * @param ctx  the user data (XML parser context)
221
 * @returns 1 if true
222
 */
223
int
224
xmlSAX2HasExternalSubset(void *ctx)
225
0
{
226
0
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
227
0
    if ((ctxt == NULL) || (ctxt->myDoc == NULL)) return(0);
228
0
    return(ctxt->myDoc->extSubset != NULL);
229
0
}
230
231
/**
232
 * Callback on internal subset declaration.
233
 *
234
 * @param ctx  the user data (XML parser context)
235
 * @param name  the root element name
236
 * @param publicId  public identifier of the DTD (optional)
237
 * @param systemId  system identifier (URL) of the DTD
238
 */
239
void
240
xmlSAX2InternalSubset(void *ctx, const xmlChar *name,
241
         const xmlChar *publicId, const xmlChar *systemId)
242
251k
{
243
251k
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
244
251k
    xmlDtdPtr dtd;
245
251k
    if (ctx == NULL) return;
246
247
251k
    if (ctxt->myDoc == NULL)
248
0
  return;
249
251k
    if ((ctxt->html) && (ctxt->instate != XML_PARSER_MISC))
250
49.5k
        return;
251
201k
    dtd = xmlGetIntSubset(ctxt->myDoc);
252
201k
    if (dtd != NULL) {
253
0
  xmlUnlinkNode((xmlNodePtr) dtd);
254
0
  xmlFreeDtd(dtd);
255
0
  ctxt->myDoc->intSubset = NULL;
256
0
    }
257
201k
    ctxt->myDoc->intSubset =
258
201k
  xmlCreateIntSubset(ctxt->myDoc, name, publicId, systemId);
259
201k
    if (ctxt->myDoc->intSubset == NULL)
260
474
        xmlSAX2ErrMemory(ctxt);
261
201k
}
262
263
/**
264
 * Callback on external subset declaration.
265
 *
266
 * @param ctx  the user data (XML parser context)
267
 * @param name  the root element name
268
 * @param publicId  public identifier of the DTD (optional)
269
 * @param systemId  system identifier (URL) of the DTD
270
 */
271
void
272
xmlSAX2ExternalSubset(void *ctx, const xmlChar *name,
273
         const xmlChar *publicId, const xmlChar *systemId)
274
173k
{
275
173k
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
276
173k
    if (ctx == NULL) return;
277
173k
    if ((systemId != NULL) &&
278
93.5k
        ((ctxt->options & XML_PARSE_NO_XXE) == 0) &&
279
72.7k
        (((ctxt->validate) || (ctxt->loadsubset & ~XML_SKIP_IDS)) &&
280
36.5k
   (ctxt->wellFormed && ctxt->myDoc))) {
281
  /*
282
   * Try to fetch and parse the external subset.
283
   */
284
28.2k
  xmlParserInputPtr oldinput;
285
28.2k
  int oldinputNr;
286
28.2k
  int oldinputMax;
287
28.2k
  xmlParserInputPtr *oldinputTab;
288
28.2k
  xmlParserInputPtr input = NULL;
289
28.2k
  xmlChar *oldencoding;
290
28.2k
        unsigned long consumed;
291
28.2k
        size_t buffered;
292
28.2k
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
293
28.2k
        int inputMax = 1;
294
#else
295
        int inputMax = 5;
296
#endif
297
298
  /*
299
   * Ask the Entity resolver to load the damn thing
300
   */
301
28.2k
  if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
302
28.2k
      input = ctxt->sax->resolveEntity(ctxt->userData, publicId,
303
28.2k
                                       systemId);
304
28.2k
  if (input == NULL) {
305
18.0k
      return;
306
18.0k
  }
307
308
10.1k
  if (xmlNewDtd(ctxt->myDoc, name, publicId, systemId) == NULL) {
309
46
            xmlSAX2ErrMemory(ctxt);
310
46
            xmlFreeInputStream(input);
311
46
            return;
312
46
        }
313
314
  /*
315
   * make sure we won't destroy the main document context
316
   */
317
10.0k
  oldinput = ctxt->input;
318
10.0k
  oldinputNr = ctxt->inputNr;
319
10.0k
  oldinputMax = ctxt->inputMax;
320
10.0k
  oldinputTab = ctxt->inputTab;
321
10.0k
  oldencoding = ctxt->encoding;
322
10.0k
  ctxt->encoding = NULL;
323
324
10.0k
  ctxt->inputTab = xmlMalloc(inputMax * sizeof(xmlParserInputPtr));
325
10.0k
  if (ctxt->inputTab == NULL) {
326
17
      xmlSAX2ErrMemory(ctxt);
327
17
            goto error;
328
17
  }
329
10.0k
  ctxt->inputNr = 0;
330
10.0k
  ctxt->inputMax = inputMax;
331
10.0k
  ctxt->input = NULL;
332
10.0k
  if (xmlCtxtPushInput(ctxt, input) < 0)
333
68
            goto error;
334
335
9.99k
  if (input->filename == NULL)
336
0
      input->filename = (char *) xmlCanonicPath(systemId);
337
9.99k
  input->line = 1;
338
9.99k
  input->col = 1;
339
9.99k
  input->base = ctxt->input->cur;
340
9.99k
  input->cur = ctxt->input->cur;
341
9.99k
  input->free = NULL;
342
343
  /*
344
   * let's parse that entity knowing it's an external subset.
345
   */
346
9.99k
  xmlParseExternalSubset(ctxt, publicId, systemId);
347
348
        /*
349
   * Free up the external entities
350
   */
351
352
10.4k
  while (ctxt->inputNr > 1)
353
489
      xmlFreeInputStream(xmlCtxtPopInput(ctxt));
354
355
9.99k
        consumed = ctxt->input->consumed;
356
9.99k
        buffered = ctxt->input->cur - ctxt->input->base;
357
9.99k
        if (buffered > ULONG_MAX - consumed)
358
0
            consumed = ULONG_MAX;
359
9.99k
        else
360
9.99k
            consumed += buffered;
361
9.99k
        if (consumed > ULONG_MAX - ctxt->sizeentities)
362
0
            ctxt->sizeentities = ULONG_MAX;
363
9.99k
        else
364
9.99k
            ctxt->sizeentities += consumed;
365
366
10.0k
error:
367
10.0k
  xmlFreeInputStream(input);
368
10.0k
        xmlFree(ctxt->inputTab);
369
370
  /*
371
   * Restore the parsing context of the main entity
372
   */
373
10.0k
  ctxt->input = oldinput;
374
10.0k
  ctxt->inputNr = oldinputNr;
375
10.0k
  ctxt->inputMax = oldinputMax;
376
10.0k
  ctxt->inputTab = oldinputTab;
377
10.0k
  if (ctxt->encoding != NULL)
378
277
      xmlFree(ctxt->encoding);
379
10.0k
  ctxt->encoding = oldencoding;
380
  /* ctxt->wellFormed = oldwellFormed; */
381
10.0k
    }
382
173k
}
383
384
/**
385
 * This is only used to load DTDs. The preferred way to install
386
 * custom resolvers is #xmlCtxtSetResourceLoader.
387
 *
388
 * @param ctx  the user data (XML parser context)
389
 * @param publicId  The public ID of the entity
390
 * @param systemId  The system ID (URL) of the entity
391
 * @returns a parser input.
392
 */
393
xmlParserInput *
394
xmlSAX2ResolveEntity(void *ctx, const xmlChar *publicId,
395
                     const xmlChar *systemId)
396
39.9k
{
397
39.9k
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
398
39.9k
    xmlParserInputPtr ret = NULL;
399
39.9k
    xmlChar *URI = NULL;
400
401
39.9k
    if (ctx == NULL) return(NULL);
402
403
39.9k
    if (systemId != NULL) {
404
39.7k
        const xmlChar *base = NULL;
405
39.7k
        int res;
406
407
39.7k
        if (ctxt->input != NULL)
408
28.2k
            base = BAD_CAST ctxt->input->filename;
409
410
        /*
411
         * We don't really need the 'directory' struct member, but some
412
         * users set it manually to a base URI for memory streams.
413
         */
414
39.7k
        if (base == NULL)
415
14.5k
            base = BAD_CAST ctxt->directory;
416
417
39.7k
        if ((xmlStrlen(systemId) > XML_MAX_URI_LENGTH) ||
418
39.5k
            (xmlStrlen(base) > XML_MAX_URI_LENGTH)) {
419
207
            xmlFatalErr(ctxt, XML_ERR_RESOURCE_LIMIT, "URI too long");
420
207
            return(NULL);
421
207
        }
422
39.5k
        res = xmlBuildURISafe(systemId, base, &URI);
423
39.5k
        if (URI == NULL) {
424
4.04k
            if (res < 0)
425
504
                xmlSAX2ErrMemory(ctxt);
426
3.54k
            else
427
3.54k
                xmlWarnMsg(ctxt, XML_ERR_INVALID_URI,
428
3.54k
                           "Can't resolve URI: %s\n", systemId);
429
4.04k
            return(NULL);
430
4.04k
        }
431
35.4k
        if (xmlStrlen(URI) > XML_MAX_URI_LENGTH) {
432
209
            xmlFatalErr(ctxt, XML_ERR_RESOURCE_LIMIT, "URI too long");
433
209
            xmlFree(URI);
434
209
            return(NULL);
435
209
        }
436
35.4k
    }
437
438
35.5k
    ret = xmlLoadResource(ctxt, (const char *) URI,
439
35.5k
                          (const char *) publicId, XML_RESOURCE_DTD);
440
441
35.5k
    xmlFree(URI);
442
35.5k
    return(ret);
443
39.9k
}
444
445
/**
446
 * Get an entity by name
447
 *
448
 * @param ctx  the user data (XML parser context)
449
 * @param name  The entity name
450
 * @returns the xmlEntity if found.
451
 */
452
xmlEntity *
453
xmlSAX2GetEntity(void *ctx, const xmlChar *name)
454
11.4M
{
455
11.4M
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
456
11.4M
    xmlEntityPtr ret = NULL;
457
458
11.4M
    if (ctx == NULL) return(NULL);
459
460
11.4M
    if (ctxt->inSubset == 0) {
461
10.7M
  ret = xmlGetPredefinedEntity(name);
462
10.7M
  if (ret != NULL)
463
1.79M
      return(ret);
464
10.7M
    }
465
9.65M
    if ((ctxt->myDoc != NULL) && (ctxt->myDoc->standalone == 1)) {
466
56.0k
  if (ctxt->inSubset == 2) {
467
693
      ctxt->myDoc->standalone = 0;
468
693
      ret = xmlGetDocEntity(ctxt->myDoc, name);
469
693
      ctxt->myDoc->standalone = 1;
470
55.3k
  } else {
471
55.3k
      ret = xmlGetDocEntity(ctxt->myDoc, name);
472
55.3k
      if (ret == NULL) {
473
5.33k
    ctxt->myDoc->standalone = 0;
474
5.33k
    ret = xmlGetDocEntity(ctxt->myDoc, name);
475
5.33k
    if (ret != NULL) {
476
512
        xmlFatalErrMsg(ctxt, XML_ERR_NOT_STANDALONE,
477
512
   "Entity(%s) document marked standalone but requires external subset\n",
478
512
           name, NULL);
479
512
    }
480
5.33k
    ctxt->myDoc->standalone = 1;
481
5.33k
      }
482
55.3k
  }
483
9.60M
    } else {
484
9.60M
  ret = xmlGetDocEntity(ctxt->myDoc, name);
485
9.60M
    }
486
9.65M
    return(ret);
487
11.4M
}
488
489
/**
490
 * Get a parameter entity by name
491
 *
492
 * @param ctx  the user data (XML parser context)
493
 * @param name  The entity name
494
 * @returns the xmlEntity if found.
495
 */
496
xmlEntity *
497
xmlSAX2GetParameterEntity(void *ctx, const xmlChar *name)
498
1.25M
{
499
1.25M
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
500
1.25M
    xmlEntityPtr ret;
501
502
1.25M
    if (ctx == NULL) return(NULL);
503
504
1.25M
    ret = xmlGetParameterEntity(ctxt->myDoc, name);
505
1.25M
    return(ret);
506
1.25M
}
507
508
509
/**
510
 * An entity definition has been parsed
511
 *
512
 * @param ctx  the user data (XML parser context)
513
 * @param name  the entity name
514
 * @param type  the entity type
515
 * @param publicId  The public ID of the entity
516
 * @param systemId  The system ID of the entity
517
 * @param content  the entity value (without processing).
518
 */
519
void
520
xmlSAX2EntityDecl(void *ctx, const xmlChar *name, int type,
521
          const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
522
403k
{
523
403k
    xmlEntityPtr ent;
524
403k
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
525
403k
    int extSubset;
526
403k
    int res;
527
528
403k
    if ((ctxt == NULL) || (ctxt->myDoc == NULL))
529
0
        return;
530
531
403k
    extSubset = ctxt->inSubset == 2;
532
403k
    res = xmlAddEntity(ctxt->myDoc, extSubset, name, type, publicId, systemId,
533
403k
                       content, &ent);
534
403k
    switch (res) {
535
163k
        case XML_ERR_OK:
536
163k
            break;
537
425
        case XML_ERR_NO_MEMORY:
538
425
            xmlSAX2ErrMemory(ctxt);
539
425
            return;
540
195k
        case XML_WAR_ENTITY_REDEFINED:
541
195k
            if (ctxt->pedantic) {
542
44.3k
                if (extSubset)
543
3.49k
                    xmlWarnMsg(ctxt, res, "Entity(%s) already defined in the"
544
3.49k
                               " external subset\n", name);
545
40.8k
                else
546
40.8k
                    xmlWarnMsg(ctxt, res, "Entity(%s) already defined in the"
547
40.8k
                               " internal subset\n", name);
548
44.3k
            }
549
195k
            return;
550
43.1k
        case XML_ERR_REDECL_PREDEF_ENTITY:
551
            /*
552
             * Technically an error but it's a common mistake to get double
553
             * escaping according to "4.6 Predefined Entities" wrong.
554
             */
555
43.1k
            xmlWarnMsg(ctxt, res, "Invalid redeclaration of predefined"
556
43.1k
                       " entity '%s'", name);
557
43.1k
            return;
558
0
        default:
559
0
            xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
560
0
                           "Unexpected error code from xmlAddEntity\n",
561
0
                           NULL, NULL);
562
0
            return;
563
403k
    }
564
565
163k
    if ((ent->URI == NULL) && (systemId != NULL)) {
566
52.6k
        xmlChar *URI;
567
52.6k
        const char *base = NULL;
568
52.6k
        int i;
569
570
59.9k
        for (i = ctxt->inputNr - 1; i >= 0; i--) {
571
52.9k
            if (ctxt->inputTab[i]->filename != NULL) {
572
45.6k
                base = ctxt->inputTab[i]->filename;
573
45.6k
                break;
574
45.6k
            }
575
52.9k
        }
576
577
        /*
578
         * We don't really need the 'directory' struct member, but some
579
         * users set it manually to a base URI for memory streams.
580
         */
581
52.6k
        if (base == NULL)
582
6.99k
            base = ctxt->directory;
583
584
52.6k
        res = xmlBuildURISafe(systemId, (const xmlChar *) base, &URI);
585
586
52.6k
        if (URI == NULL) {
587
3.29k
            if (res < 0) {
588
285
                xmlSAX2ErrMemory(ctxt);
589
3.01k
            } else {
590
3.01k
                xmlWarnMsg(ctxt, XML_ERR_INVALID_URI,
591
3.01k
                           "Can't resolve URI: %s\n", systemId);
592
3.01k
            }
593
49.3k
        } else if (xmlStrlen(URI) > XML_MAX_URI_LENGTH) {
594
160
            xmlFatalErr(ctxt, XML_ERR_RESOURCE_LIMIT, "URI too long");
595
160
            xmlFree(URI);
596
49.1k
        } else {
597
49.1k
            ent->URI = URI;
598
49.1k
        }
599
52.6k
    }
600
163k
}
601
602
/**
603
 * An attribute definition has been parsed
604
 *
605
 * @param ctx  the user data (XML parser context)
606
 * @param elem  the name of the element
607
 * @param fullname  the attribute name
608
 * @param type  the attribute type
609
 * @param def  the type of default value
610
 * @param defaultValue  the attribute default value
611
 * @param tree  the tree of enumerated value set
612
 */
613
void
614
xmlSAX2AttributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname,
615
              int type, int def, const xmlChar *defaultValue,
616
        xmlEnumeration *tree)
617
315k
{
618
315k
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
619
315k
    xmlAttributePtr attr;
620
315k
    const xmlChar *name = NULL;
621
315k
    xmlChar *prefix = NULL;
622
623
    /* Avoid unused variable warning if features are disabled. */
624
315k
    (void) attr;
625
626
315k
    if ((ctxt == NULL) || (ctxt->myDoc == NULL))
627
0
        return;
628
629
315k
    if ((xmlStrEqual(fullname, BAD_CAST "xml:id")) &&
630
2.81k
        (type != XML_ATTRIBUTE_ID)) {
631
1.51k
  xmlErrId(ctxt, XML_DTD_XMLID_TYPE,
632
1.51k
        "xml:id : attribute type should be ID\n", NULL);
633
1.51k
    }
634
315k
    name = xmlSplitQName4(fullname, &prefix);
635
315k
    if (name == NULL)
636
80
        xmlSAX2ErrMemory(ctxt);
637
315k
    ctxt->vctxt.valid = 1;
638
315k
    if (ctxt->inSubset == 1)
639
226k
  attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, elem,
640
226k
         name, prefix, (xmlAttributeType) type,
641
226k
         (xmlAttributeDefault) def, defaultValue, tree);
642
88.8k
    else if (ctxt->inSubset == 2)
643
88.8k
  attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, elem,
644
88.8k
     name, prefix, (xmlAttributeType) type,
645
88.8k
     (xmlAttributeDefault) def, defaultValue, tree);
646
0
    else {
647
0
        xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
648
0
       "SAX.xmlSAX2AttributeDecl(%s) called while not in subset\n",
649
0
                 name, NULL);
650
0
  xmlFree(prefix);
651
0
  xmlFreeEnumeration(tree);
652
0
  return;
653
0
    }
654
315k
#ifdef LIBXML_VALID_ENABLED
655
315k
    if (ctxt->vctxt.valid == 0)
656
13.7k
  ctxt->valid = 0;
657
315k
    if ((attr != NULL) && (ctxt->validate) && (ctxt->wellFormed) &&
658
54.2k
        (ctxt->myDoc->intSubset != NULL))
659
54.2k
  ctxt->valid &= xmlValidateAttributeDecl(&ctxt->vctxt, ctxt->myDoc,
660
54.2k
                                          attr);
661
315k
#endif /* LIBXML_VALID_ENABLED */
662
315k
    if (prefix != NULL)
663
41.2k
  xmlFree(prefix);
664
315k
}
665
666
/**
667
 * An element definition has been parsed
668
 *
669
 * @param ctx  the user data (XML parser context)
670
 * @param name  the element name
671
 * @param type  the element type
672
 * @param content  the element value tree
673
 */
674
void
675
xmlSAX2ElementDecl(void *ctx, const xmlChar * name, int type,
676
            xmlElementContent *content)
677
122k
{
678
122k
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
679
122k
    xmlElementPtr elem = NULL;
680
681
    /* Avoid unused variable warning if features are disabled. */
682
122k
    (void) elem;
683
684
122k
    if ((ctxt == NULL) || (ctxt->myDoc == NULL))
685
0
        return;
686
687
122k
    if (ctxt->inSubset == 1)
688
69.8k
        elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->intSubset,
689
69.8k
                                 name, (xmlElementTypeVal) type, content);
690
52.5k
    else if (ctxt->inSubset == 2)
691
52.5k
        elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->extSubset,
692
52.5k
                                 name, (xmlElementTypeVal) type, content);
693
0
    else {
694
0
        xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
695
0
       "SAX.xmlSAX2ElementDecl(%s) called while not in subset\n",
696
0
                 name, NULL);
697
0
        return;
698
0
    }
699
122k
#ifdef LIBXML_VALID_ENABLED
700
122k
    if (elem == NULL)
701
61.5k
        ctxt->valid = 0;
702
122k
    if (ctxt->validate && ctxt->wellFormed &&
703
29.1k
        ctxt->myDoc && ctxt->myDoc->intSubset)
704
29.1k
        ctxt->valid &=
705
29.1k
            xmlValidateElementDecl(&ctxt->vctxt, ctxt->myDoc, elem);
706
122k
#endif /* LIBXML_VALID_ENABLED */
707
122k
}
708
709
/**
710
 * What to do when a notation declaration has been parsed.
711
 *
712
 * @param ctx  the user data (XML parser context)
713
 * @param name  The name of the notation
714
 * @param publicId  The public ID of the entity
715
 * @param systemId  The system ID of the entity
716
 */
717
void
718
xmlSAX2NotationDecl(void *ctx, const xmlChar *name,
719
       const xmlChar *publicId, const xmlChar *systemId)
720
19.5k
{
721
19.5k
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
722
19.5k
    xmlNotationPtr nota = NULL;
723
724
    /* Avoid unused variable warning if features are disabled. */
725
19.5k
    (void) nota;
726
727
19.5k
    if ((ctxt == NULL) || (ctxt->myDoc == NULL))
728
0
        return;
729
730
19.5k
    if ((publicId == NULL) && (systemId == NULL)) {
731
1.20k
  xmlFatalErrMsg(ctxt, XML_ERR_NOTATION_PROCESSING,
732
1.20k
       "SAX.xmlSAX2NotationDecl(%s) externalID or PublicID missing\n",
733
1.20k
                 name, NULL);
734
1.20k
  return;
735
18.3k
    } else if (ctxt->inSubset == 1)
736
11.4k
  nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name,
737
11.4k
                              publicId, systemId);
738
6.95k
    else if (ctxt->inSubset == 2)
739
6.95k
  nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, name,
740
6.95k
                              publicId, systemId);
741
0
    else {
742
0
  xmlFatalErrMsg(ctxt, XML_ERR_NOTATION_PROCESSING,
743
0
       "SAX.xmlSAX2NotationDecl(%s) called while not in subset\n",
744
0
                 name, NULL);
745
0
  return;
746
0
    }
747
18.3k
#ifdef LIBXML_VALID_ENABLED
748
18.3k
    if (nota == NULL) ctxt->valid = 0;
749
18.3k
    if ((ctxt->validate) && (ctxt->wellFormed) &&
750
2.96k
        (ctxt->myDoc->intSubset != NULL))
751
2.96k
  ctxt->valid &= xmlValidateNotationDecl(&ctxt->vctxt, ctxt->myDoc,
752
2.96k
                                         nota);
753
18.3k
#endif /* LIBXML_VALID_ENABLED */
754
18.3k
}
755
756
/**
757
 * What to do when an unparsed entity declaration is parsed
758
 *
759
 * @param ctx  the user data (XML parser context)
760
 * @param name  The name of the entity
761
 * @param publicId  The public ID of the entity
762
 * @param systemId  The system ID of the entity
763
 * @param notationName  the name of the notation
764
 */
765
void
766
xmlSAX2UnparsedEntityDecl(void *ctx, const xmlChar *name,
767
       const xmlChar *publicId, const xmlChar *systemId,
768
       const xmlChar *notationName)
769
5.69k
{
770
5.69k
    xmlSAX2EntityDecl(ctx, name, XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
771
5.69k
                      publicId, systemId, (xmlChar *) notationName);
772
5.69k
}
773
774
/**
775
 * Receive the document locator at startup, actually xmlDefaultSAXLocator
776
 * Everything is available on the context, so this is useless in our case.
777
 *
778
 * @param ctx  the user data (XML parser context)
779
 * @param loc  A SAX Locator
780
 */
781
void
782
xmlSAX2SetDocumentLocator(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocator *loc ATTRIBUTE_UNUSED)
783
452k
{
784
452k
}
785
786
/**
787
 * called when the document start being processed.
788
 *
789
 * @param ctx  the user data (XML parser context)
790
 */
791
void
792
xmlSAX2StartDocument(void *ctx)
793
418k
{
794
418k
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
795
418k
    xmlDocPtr doc;
796
797
418k
    if (ctx == NULL) return;
798
799
418k
#ifdef LIBXML_HTML_ENABLED
800
418k
    if (ctxt->html) {
801
19.9k
  if (ctxt->myDoc == NULL)
802
19.9k
      ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
803
19.9k
  if (ctxt->myDoc == NULL) {
804
231
      xmlSAX2ErrMemory(ctxt);
805
231
      return;
806
231
  }
807
19.7k
  ctxt->myDoc->properties = XML_DOC_HTML;
808
19.7k
  ctxt->myDoc->parseFlags = ctxt->options;
809
19.7k
    } else
810
398k
#endif
811
398k
    {
812
398k
  doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
813
398k
  if (doc != NULL) {
814
397k
      doc->properties = 0;
815
397k
      if (ctxt->options & XML_PARSE_OLD10)
816
109k
          doc->properties |= XML_DOC_OLD10;
817
397k
      doc->parseFlags = ctxt->options;
818
397k
      doc->standalone = ctxt->standalone;
819
397k
  } else {
820
528
      xmlSAX2ErrMemory(ctxt);
821
528
      return;
822
528
  }
823
397k
  if ((ctxt->dictNames) && (doc != NULL)) {
824
284k
      doc->dict = ctxt->dict;
825
284k
      xmlDictReference(doc->dict);
826
284k
  }
827
397k
    }
828
417k
    if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
829
417k
  (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
830
313k
  ctxt->myDoc->URL = xmlPathToURI((const xmlChar *)ctxt->input->filename);
831
313k
  if (ctxt->myDoc->URL == NULL)
832
506
      xmlSAX2ErrMemory(ctxt);
833
313k
    }
834
417k
}
835
836
/**
837
 * called when the document end has been detected.
838
 *
839
 * @param ctx  the user data (XML parser context)
840
 */
841
void
842
xmlSAX2EndDocument(void *ctx)
843
406k
{
844
406k
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
845
406k
    xmlDocPtr doc;
846
847
406k
    if (ctx == NULL) return;
848
406k
#ifdef LIBXML_VALID_ENABLED
849
406k
    if (ctxt->validate && ctxt->wellFormed &&
850
11.5k
        ctxt->myDoc && ctxt->myDoc->intSubset)
851
11.5k
  ctxt->valid &= xmlValidateDocumentFinal(&ctxt->vctxt, ctxt->myDoc);
852
406k
#endif /* LIBXML_VALID_ENABLED */
853
854
406k
    doc = ctxt->myDoc;
855
406k
    if (doc == NULL)
856
25.1k
        return;
857
858
381k
    if (doc->encoding == NULL) {
859
381k
        const xmlChar *encoding = xmlGetActualEncoding(ctxt);
860
861
381k
        if (encoding != NULL) {
862
37.5k
            doc->encoding = xmlStrdup(encoding);
863
37.5k
            if (doc->encoding == NULL)
864
149
                xmlSAX2ErrMemory(ctxt);
865
37.5k
        }
866
381k
    }
867
868
381k
#ifdef LIBXML_HTML_ENABLED
869
381k
    if (ctxt->html) {
870
19.1k
        if (((ctxt->options & HTML_PARSE_NODEFDTD) == 0) &&
871
13.1k
            (doc->intSubset == NULL)) {
872
12.4k
            doc->intSubset = xmlCreateIntSubset(doc, BAD_CAST "html",
873
12.4k
                    BAD_CAST "-//W3C//DTD HTML 4.0 Transitional//EN",
874
12.4k
                    BAD_CAST "http://www.w3.org/TR/REC-html40/loose.dtd");
875
12.4k
            if (doc->intSubset == NULL)
876
451
                xmlSAX2ErrMemory(ctxt);
877
12.4k
        }
878
19.1k
    } else
879
362k
#endif /* LIBXML_HTML_ENABLED */
880
362k
    {
881
362k
        if (ctxt->wellFormed) {
882
60.2k
            doc->properties |= XML_DOC_WELLFORMED;
883
60.2k
            if (ctxt->valid)
884
37.4k
                doc->properties |= XML_DOC_DTDVALID;
885
60.2k
            if (ctxt->nsWellFormed)
886
49.2k
                doc->properties |= XML_DOC_NSVALID;
887
60.2k
        }
888
889
362k
        if (ctxt->options & XML_PARSE_OLD10)
890
95.7k
            doc->properties |= XML_DOC_OLD10;
891
362k
    }
892
381k
}
893
894
static void
895
9.81M
xmlSAX2AppendChild(xmlParserCtxtPtr ctxt, xmlNodePtr node) {
896
9.81M
    xmlNodePtr parent;
897
9.81M
    xmlNodePtr last;
898
899
9.81M
    if (ctxt->inSubset == 1) {
900
141k
  parent = (xmlNodePtr) ctxt->myDoc->intSubset;
901
9.67M
    } else if (ctxt->inSubset == 2) {
902
1.11M
  parent = (xmlNodePtr) ctxt->myDoc->extSubset;
903
8.55M
    } else {
904
8.55M
        parent = ctxt->node;
905
8.55M
        if (parent == NULL)
906
1.05M
            parent = (xmlNodePtr) ctxt->myDoc;
907
8.55M
    }
908
909
9.81M
    last = parent->last;
910
9.81M
    if (last == NULL) {
911
1.51M
        parent->children = node;
912
8.29M
    } else {
913
8.29M
        last->next = node;
914
8.29M
        node->prev = last;
915
8.29M
    }
916
917
9.81M
    parent->last = node;
918
9.81M
    node->parent = parent;
919
920
9.81M
    if ((node->type != XML_TEXT_NODE) &&
921
8.03M
  (ctxt->input != NULL)) {
922
8.03M
        if ((unsigned) ctxt->input->line < (unsigned) USHRT_MAX)
923
7.66M
            node->line = ctxt->input->line;
924
366k
        else
925
366k
            node->line = USHRT_MAX;
926
8.03M
    }
927
9.81M
}
928
929
#if defined(LIBXML_SAX1_ENABLED)
930
/**
931
 * Handle a namespace error
932
 *
933
 * @param ctxt  an XML parser context
934
 * @param error  the error number
935
 * @param msg  the error message
936
 * @param str1  an error string
937
 * @param str2  an error string
938
 */
939
static void LIBXML_ATTR_FORMAT(3,0)
940
xmlNsErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
941
            const char *msg, const xmlChar *str1, const xmlChar *str2)
942
21.4k
{
943
21.4k
    xmlCtxtErr(ctxt, NULL, XML_FROM_NAMESPACE, error, XML_ERR_ERROR,
944
21.4k
               str1, str2, NULL, 0, msg, str1, str2);
945
21.4k
}
946
947
/**
948
 * Handle an attribute that has been read by the parser.
949
 *
950
 * Deprecated SAX1 interface.
951
 *
952
 * @param ctxt  the parser context
953
 * @param fullname  the attribute name, including namespace prefix
954
 * @param value  the attribute value
955
 * @param prefix  the namespace prefix
956
 */
957
static void
958
xmlSAX1Attribute(xmlParserCtxtPtr ctxt, const xmlChar *fullname,
959
                 const xmlChar *value, const xmlChar *prefix)
960
280k
{
961
280k
    xmlAttrPtr ret;
962
280k
    const xmlChar *name;
963
280k
    xmlChar *ns;
964
280k
    xmlNsPtr namespace;
965
966
    /*
967
     * Split the full name into a namespace prefix and the tag name
968
     */
969
280k
    name = xmlSplitQName4(fullname, &ns);
970
280k
    if (name == NULL) {
971
66
        xmlSAX2ErrMemory(ctxt);
972
66
        return;
973
66
    }
974
975
    /*
976
     * Check whether it's a namespace definition
977
     */
978
280k
    if ((ns == NULL) &&
979
146k
        (name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') &&
980
53.5k
        (name[3] == 'n') && (name[4] == 's') && (name[5] == 0)) {
981
46.4k
  xmlNsPtr nsret;
982
46.4k
  xmlChar *val;
983
984
        /* Avoid unused variable warning if features are disabled. */
985
46.4k
        (void) nsret;
986
987
46.4k
        if (!ctxt->replaceEntities) {
988
            /* TODO: normalize if needed */
989
23.7k
      val = xmlExpandEntitiesInAttValue(ctxt, value, /* normalize */ 0);
990
23.7k
      if (val == NULL) {
991
72
          xmlSAX2ErrMemory(ctxt);
992
72
    return;
993
72
      }
994
23.7k
  } else {
995
22.6k
      val = (xmlChar *) value;
996
22.6k
  }
997
998
46.3k
  if (val[0] != 0) {
999
43.8k
      xmlURIPtr uri;
1000
1001
43.8k
      if (xmlParseURISafe((const char *)val, &uri) < 0)
1002
320
                xmlSAX2ErrMemory(ctxt);
1003
43.8k
      if (uri == NULL) {
1004
22.1k
                xmlNsWarnMsg(ctxt, XML_WAR_NS_URI,
1005
22.1k
                             "xmlns:%s: %s not a valid URI\n", name, value);
1006
22.1k
      } else {
1007
21.6k
    if (uri->scheme == NULL) {
1008
16.5k
                    xmlNsWarnMsg(ctxt, XML_WAR_NS_URI_RELATIVE,
1009
16.5k
                                 "xmlns:%s: URI %s is not absolute\n",
1010
16.5k
                                 name, value);
1011
16.5k
    }
1012
21.6k
    xmlFreeURI(uri);
1013
21.6k
      }
1014
43.8k
  }
1015
1016
  /* a default namespace definition */
1017
46.3k
  nsret = xmlNewNs(ctxt->node, val, NULL);
1018
46.3k
        if (nsret == NULL) {
1019
80
            xmlSAX2ErrMemory(ctxt);
1020
80
        }
1021
46.2k
#ifdef LIBXML_VALID_ENABLED
1022
  /*
1023
   * Validate also for namespace decls, they are attributes from
1024
   * an XML-1.0 perspective
1025
   */
1026
46.2k
        else if (ctxt->validate && ctxt->wellFormed &&
1027
8.10k
                 ctxt->myDoc && ctxt->myDoc->intSubset) {
1028
8.10k
      ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
1029
8.10k
             ctxt->node, prefix, nsret, val);
1030
8.10k
        }
1031
46.3k
#endif /* LIBXML_VALID_ENABLED */
1032
46.3k
  if (val != value)
1033
23.7k
      xmlFree(val);
1034
46.3k
  return;
1035
46.4k
    }
1036
234k
    if ((ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') &&
1037
109k
        (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) {
1038
74.3k
  xmlNsPtr nsret;
1039
74.3k
  xmlChar *val;
1040
1041
        /* Avoid unused variable warning if features are disabled. */
1042
74.3k
        (void) nsret;
1043
1044
74.3k
        if (!ctxt->replaceEntities) {
1045
            /* TODO: normalize if needed */
1046
13.5k
      val = xmlExpandEntitiesInAttValue(ctxt, value, /* normalize */ 0);
1047
13.5k
      if (val == NULL) {
1048
20
          xmlSAX2ErrMemory(ctxt);
1049
20
          xmlFree(ns);
1050
20
    return;
1051
20
      }
1052
60.8k
  } else {
1053
60.8k
      val = (xmlChar *) value;
1054
60.8k
  }
1055
1056
74.3k
  if (val[0] == 0) {
1057
3.57k
      xmlNsErrMsg(ctxt, XML_NS_ERR_EMPTY,
1058
3.57k
            "Empty namespace name for prefix %s\n", name, NULL);
1059
3.57k
  }
1060
74.3k
  if ((ctxt->pedantic != 0) && (val[0] != 0)) {
1061
49.8k
      xmlURIPtr uri;
1062
1063
49.8k
      if (xmlParseURISafe((const char *)val, &uri) < 0)
1064
25
                xmlSAX2ErrMemory(ctxt);
1065
49.8k
      if (uri == NULL) {
1066
12.7k
          xmlNsWarnMsg(ctxt, XML_WAR_NS_URI,
1067
12.7k
       "xmlns:%s: %s not a valid URI\n", name, value);
1068
37.0k
      } else {
1069
37.0k
    if (uri->scheme == NULL) {
1070
31.5k
        xmlNsWarnMsg(ctxt, XML_WAR_NS_URI_RELATIVE,
1071
31.5k
         "xmlns:%s: URI %s is not absolute\n", name, value);
1072
31.5k
    }
1073
37.0k
    xmlFreeURI(uri);
1074
37.0k
      }
1075
49.8k
  }
1076
1077
  /* a standard namespace definition */
1078
74.3k
  nsret = xmlNewNs(ctxt->node, val, name);
1079
74.3k
  xmlFree(ns);
1080
1081
74.3k
        if (nsret == NULL) {
1082
60
            xmlSAX2ErrMemory(ctxt);
1083
60
        }
1084
74.3k
#ifdef LIBXML_VALID_ENABLED
1085
  /*
1086
   * Validate also for namespace decls, they are attributes from
1087
   * an XML-1.0 perspective
1088
   */
1089
74.3k
        else if (ctxt->validate && ctxt->wellFormed &&
1090
7.96k
           ctxt->myDoc && ctxt->myDoc->intSubset) {
1091
7.96k
      ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
1092
7.96k
             ctxt->node, prefix, nsret, value);
1093
7.96k
        }
1094
74.3k
#endif /* LIBXML_VALID_ENABLED */
1095
74.3k
  if (val != value)
1096
13.5k
      xmlFree(val);
1097
74.3k
  return;
1098
74.3k
    }
1099
1100
159k
    if (ns != NULL) {
1101
59.2k
        int res;
1102
1103
59.2k
  res = xmlSearchNsSafe(ctxt->node, ns, &namespace);
1104
59.2k
        if (res < 0)
1105
62
            xmlSAX2ErrMemory(ctxt);
1106
1107
59.2k
  if (namespace == NULL) {
1108
17.8k
      xmlNsErrMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
1109
17.8k
        "Namespace prefix %s of attribute %s is not defined\n",
1110
17.8k
                 ns, name);
1111
41.3k
  } else {
1112
41.3k
            xmlAttrPtr prop;
1113
1114
41.3k
            prop = ctxt->node->properties;
1115
343k
            while (prop != NULL) {
1116
303k
                if (prop->ns != NULL) {
1117
210k
                    if ((xmlStrEqual(name, prop->name)) &&
1118
2.22k
                        ((namespace == prop->ns) ||
1119
2.22k
                         (xmlStrEqual(namespace->href, prop->ns->href)))) {
1120
630
                        xmlCtxtErr(ctxt, NULL, XML_FROM_PARSER,
1121
630
                                   XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL,
1122
630
                                   name, NULL, NULL, 0,
1123
630
                                   "Attribute %s in %s redefined\n",
1124
630
                                   name, namespace->href);
1125
630
                        goto error;
1126
630
                    }
1127
210k
                }
1128
302k
                prop = prop->next;
1129
302k
            }
1130
41.3k
        }
1131
100k
    } else {
1132
100k
  namespace = NULL;
1133
100k
    }
1134
1135
    /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */
1136
159k
    ret = xmlNewNsProp(ctxt->node, namespace, name, NULL);
1137
159k
    if (ret == NULL) {
1138
128
        xmlSAX2ErrMemory(ctxt);
1139
128
        goto error;
1140
128
    }
1141
1142
158k
    if (ctxt->replaceEntities == 0) {
1143
64.2k
        if (xmlNodeParseAttValue(ret->doc, ret, value, SIZE_MAX, NULL) < 0)
1144
141
            xmlSAX2ErrMemory(ctxt);
1145
94.7k
    } else if (value != NULL) {
1146
94.7k
        ret->children = xmlNewDocText(ctxt->myDoc, value);
1147
94.7k
        if (ret->children == NULL) {
1148
132
            xmlSAX2ErrMemory(ctxt);
1149
94.5k
        } else {
1150
94.5k
            ret->last = ret->children;
1151
94.5k
            ret->children->parent = (xmlNodePtr) ret;
1152
94.5k
        }
1153
94.7k
    }
1154
1155
158k
#ifdef LIBXML_VALID_ENABLED
1156
158k
    if (ctxt->validate && ctxt->wellFormed &&
1157
25.7k
        ctxt->myDoc && ctxt->myDoc->intSubset) {
1158
1159
  /*
1160
   * If we don't substitute entities, the validation should be
1161
   * done on a value with replaced entities anyway.
1162
   */
1163
25.7k
        if (!ctxt->replaceEntities) {
1164
13.6k
      xmlChar *val;
1165
1166
            /* TODO: normalize if needed */
1167
13.6k
      val = xmlExpandEntitiesInAttValue(ctxt, value, /* normalize */ 0);
1168
1169
13.6k
      if (val == NULL)
1170
28
    ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
1171
28
        ctxt->myDoc, ctxt->node, ret, value);
1172
13.6k
      else {
1173
13.6k
    xmlChar *nvalnorm;
1174
1175
    /*
1176
     * Do the last stage of the attribute normalization
1177
     * It need to be done twice ... it's an extra burden related
1178
     * to the ability to keep xmlSAX2References in attributes
1179
     */
1180
13.6k
                nvalnorm = xmlValidCtxtNormalizeAttributeValue(
1181
13.6k
                                 &ctxt->vctxt, ctxt->myDoc,
1182
13.6k
                                 ctxt->node, fullname, val);
1183
13.6k
    if (nvalnorm != NULL) {
1184
7.64k
        xmlFree(val);
1185
7.64k
        val = nvalnorm;
1186
7.64k
    }
1187
1188
13.6k
    ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
1189
13.6k
              ctxt->myDoc, ctxt->node, ret, val);
1190
13.6k
                xmlFree(val);
1191
13.6k
      }
1192
13.6k
  } else {
1193
            /*
1194
             * When replacing entities, make sure that IDs in
1195
             * entities aren't registered. This also shouldn't be
1196
             * done when entities aren't replaced, but this would
1197
             * require to rework IDREF checks.
1198
             */
1199
12.0k
            if (ctxt->input->entity != NULL)
1200
567
                ctxt->vctxt.flags |= XML_VCTXT_IN_ENTITY;
1201
1202
12.0k
      ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc,
1203
12.0k
                 ctxt->node, ret, value);
1204
1205
12.0k
            ctxt->vctxt.flags &= ~XML_VCTXT_IN_ENTITY;
1206
12.0k
  }
1207
25.7k
    } else
1208
133k
#endif /* LIBXML_VALID_ENABLED */
1209
133k
           if (((ctxt->loadsubset & XML_SKIP_IDS) == 0) &&
1210
67.0k
               (ctxt->input->entity == NULL) &&
1211
               /* Don't create IDs containing entity references */
1212
60.0k
               (ret->children != NULL) &&
1213
55.2k
               (ret->children->type == XML_TEXT_NODE) &&
1214
54.5k
               (ret->children->next == NULL)) {
1215
53.6k
        xmlChar *content = ret->children->content;
1216
        /*
1217
   * when validating, the ID registration is done at the attribute
1218
   * validation level. Otherwise we have to do specific handling here.
1219
   */
1220
53.6k
  if (xmlStrEqual(fullname, BAD_CAST "xml:id")) {
1221
      /*
1222
       * Add the xml:id value
1223
       *
1224
       * Open issue: normalization of the value.
1225
       */
1226
2.16k
      if (xmlValidateNCName(content, 1) != 0) {
1227
1.24k
          xmlErrId(ctxt, XML_DTD_XMLID_VALUE,
1228
1.24k
             "xml:id : attribute value %s is not an NCName\n",
1229
1.24k
             content);
1230
1.24k
      }
1231
2.16k
      xmlAddID(&ctxt->vctxt, ctxt->myDoc, content, ret);
1232
51.4k
  } else {
1233
51.4k
            int res = xmlIsID(ctxt->myDoc, ctxt->node, ret);
1234
1235
51.4k
            if (res < 0)
1236
8
                xmlCtxtErrMemory(ctxt);
1237
51.4k
            else if (res > 0)
1238
7.10k
                xmlAddID(&ctxt->vctxt, ctxt->myDoc, content, ret);
1239
44.3k
            else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret))
1240
9.43k
                xmlAddRef(&ctxt->vctxt, ctxt->myDoc, content, ret);
1241
51.4k
        }
1242
53.6k
    }
1243
1244
159k
error:
1245
159k
    if (ns != NULL)
1246
59.2k
  xmlFree(ns);
1247
159k
}
1248
1249
/*
1250
 *
1251
 * Check defaulted attributes from the DTD
1252
 *
1253
 * Deprecated SAX1 interface.
1254
 */
1255
static void
1256
xmlCheckDefaultedAttributes(xmlParserCtxtPtr ctxt, const xmlChar *name,
1257
324k
  const xmlChar *prefix, const xmlChar **atts) {
1258
324k
    xmlElementPtr elemDecl;
1259
324k
    const xmlChar *att;
1260
324k
    int internal = 1;
1261
324k
    int i;
1262
1263
324k
    elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->intSubset, name, prefix);
1264
324k
    if (elemDecl == NULL) {
1265
190k
  elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->extSubset, name, prefix);
1266
190k
  internal = 0;
1267
190k
    }
1268
1269
459k
process_external_subset:
1270
1271
459k
    if (elemDecl != NULL) {
1272
144k
  xmlAttributePtr attr = elemDecl->attributes;
1273
1274
144k
#ifdef LIBXML_VALID_ENABLED
1275
        /*
1276
         * Check against defaulted attributes from the external subset
1277
         * if the document is stamped as standalone.
1278
         *
1279
         * This should be moved to valid.c, but we don't keep track
1280
         * whether an attribute was defaulted.
1281
         */
1282
144k
  if ((ctxt->myDoc->standalone == 1) &&
1283
21.5k
      (ctxt->myDoc->extSubset != NULL) &&
1284
4.38k
      (ctxt->validate)) {
1285
6.04k
      while (attr != NULL) {
1286
2.85k
    if ((attr->defaultValue != NULL) &&
1287
2.17k
        (xmlGetDtdQAttrDesc(ctxt->myDoc->extSubset,
1288
2.17k
          attr->elem, attr->name,
1289
2.17k
          attr->prefix) == attr) &&
1290
2.16k
        (xmlGetDtdQAttrDesc(ctxt->myDoc->intSubset,
1291
2.16k
          attr->elem, attr->name,
1292
2.16k
          attr->prefix) == NULL)) {
1293
2.16k
        xmlChar *fulln;
1294
1295
2.16k
        if (attr->prefix != NULL) {
1296
400
      fulln = xmlStrdup(attr->prefix);
1297
400
                        if (fulln != NULL)
1298
396
          fulln = xmlStrcat(fulln, BAD_CAST ":");
1299
400
                        if (fulln != NULL)
1300
396
          fulln = xmlStrcat(fulln, attr->name);
1301
1.76k
        } else {
1302
1.76k
      fulln = xmlStrdup(attr->name);
1303
1.76k
        }
1304
2.16k
                    if (fulln == NULL) {
1305
4
                        xmlSAX2ErrMemory(ctxt);
1306
4
                        break;
1307
4
                    }
1308
1309
        /*
1310
         * Check that the attribute is not declared in the
1311
         * serialization
1312
         */
1313
2.16k
        att = NULL;
1314
2.16k
        if (atts != NULL) {
1315
996
      i = 0;
1316
996
      att = atts[i];
1317
1.96k
      while (att != NULL) {
1318
1.26k
          if (xmlStrEqual(att, fulln))
1319
298
        break;
1320
964
          i += 2;
1321
964
          att = atts[i];
1322
964
      }
1323
996
        }
1324
2.16k
        if (att == NULL) {
1325
1.86k
            xmlErrValid(ctxt, XML_DTD_STANDALONE_DEFAULTED,
1326
1.86k
      "standalone: attribute %s on %s defaulted from external subset\n",
1327
1.86k
            fulln,
1328
1.86k
            attr->elem);
1329
1.86k
        }
1330
2.16k
                    xmlFree(fulln);
1331
2.16k
    }
1332
2.85k
    attr = attr->nexth;
1333
2.85k
      }
1334
3.19k
  }
1335
144k
#endif
1336
1337
  /*
1338
   * Actually insert defaulted values when needed
1339
   */
1340
144k
  attr = elemDecl->attributes;
1341
301k
  while (attr != NULL) {
1342
      /*
1343
       * Make sure that attributes redefinition occurring in the
1344
       * internal subset are not overridden by definitions in the
1345
       * external subset.
1346
       */
1347
156k
      if (attr->defaultValue != NULL) {
1348
    /*
1349
     * the element should be instantiated in the tree if:
1350
     *  - this is a namespace prefix
1351
     *  - the user required for completion in the tree
1352
     *    like XSLT
1353
     *  - there isn't already an attribute definition
1354
     *    in the internal subset overriding it.
1355
     */
1356
109k
    if (((attr->prefix != NULL) &&
1357
27.5k
         (xmlStrEqual(attr->prefix, BAD_CAST "xmlns"))) ||
1358
96.8k
        ((attr->prefix == NULL) &&
1359
82.3k
         (xmlStrEqual(attr->name, BAD_CAST "xmlns"))) ||
1360
101k
        (ctxt->loadsubset & XML_COMPLETE_ATTRS)) {
1361
101k
        xmlAttributePtr tst;
1362
1363
101k
        tst = xmlGetDtdQAttrDesc(ctxt->myDoc->intSubset,
1364
101k
               attr->elem, attr->name,
1365
101k
               attr->prefix);
1366
101k
        if ((tst == attr) || (tst == NULL)) {
1367
101k
            xmlChar fn[50];
1368
101k
      xmlChar *fulln;
1369
1370
101k
                        fulln = xmlBuildQName(attr->name, attr->prefix, fn, 50);
1371
101k
      if (fulln == NULL) {
1372
13
          xmlSAX2ErrMemory(ctxt);
1373
13
          return;
1374
13
      }
1375
1376
      /*
1377
       * Check that the attribute is not declared in the
1378
       * serialization
1379
       */
1380
101k
      att = NULL;
1381
101k
      if (atts != NULL) {
1382
8.78k
          i = 0;
1383
8.78k
          att = atts[i];
1384
15.7k
          while (att != NULL) {
1385
10.2k
        if (xmlStrEqual(att, fulln))
1386
3.27k
            break;
1387
6.94k
        i += 2;
1388
6.94k
        att = atts[i];
1389
6.94k
          }
1390
8.78k
      }
1391
101k
      if (att == NULL) {
1392
98.2k
          xmlSAX1Attribute(ctxt, fulln,
1393
98.2k
               attr->defaultValue, prefix);
1394
98.2k
      }
1395
101k
      if ((fulln != fn) && (fulln != attr->name))
1396
18.2k
          xmlFree(fulln);
1397
101k
        }
1398
101k
    }
1399
109k
      }
1400
156k
      attr = attr->nexth;
1401
156k
  }
1402
144k
  if (internal == 1) {
1403
134k
      elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->extSubset,
1404
134k
                                 name, prefix);
1405
134k
      internal = 0;
1406
134k
      goto process_external_subset;
1407
134k
  }
1408
144k
    }
1409
459k
}
1410
1411
/**
1412
 * called when an opening tag has been processed.
1413
 *
1414
 * Deprecated SAX1 interface.
1415
 *
1416
 * @param ctx  the user data (XML parser context)
1417
 * @param fullname  The element name, including namespace prefix
1418
 * @param atts  An array of name/value attributes pairs, NULL terminated
1419
 */
1420
static void
1421
xmlSAX1StartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
1422
552k
{
1423
552k
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1424
552k
    xmlNodePtr ret;
1425
552k
    xmlNodePtr parent;
1426
552k
    xmlNsPtr ns;
1427
552k
    const xmlChar *name;
1428
552k
    xmlChar *prefix;
1429
552k
    const xmlChar *att;
1430
552k
    const xmlChar *value;
1431
552k
    int i, res;
1432
1433
552k
    if ((ctx == NULL) || (fullname == NULL) || (ctxt->myDoc == NULL)) return;
1434
1435
552k
#ifdef LIBXML_VALID_ENABLED
1436
    /*
1437
     * First check on validity:
1438
     */
1439
552k
    if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) &&
1440
187k
        ((ctxt->myDoc->intSubset == NULL) ||
1441
169k
   ((ctxt->myDoc->intSubset->notations == NULL) &&
1442
165k
    (ctxt->myDoc->intSubset->elements == NULL) &&
1443
32.3k
    (ctxt->myDoc->intSubset->attributes == NULL) &&
1444
32.3k
    (ctxt->myDoc->intSubset->entities == NULL)))) {
1445
23.8k
  xmlErrValid(ctxt, XML_ERR_NO_DTD,
1446
23.8k
    "Validation failed: no DTD found !", NULL, NULL);
1447
23.8k
  ctxt->validate = 0;
1448
23.8k
    }
1449
552k
#endif
1450
1451
    /*
1452
     * Split the full name into a namespace prefix and the tag name
1453
     */
1454
552k
    name = xmlSplitQName4(fullname, &prefix);
1455
552k
    if (name == NULL) {
1456
26
        xmlSAX2ErrMemory(ctxt);
1457
26
        return;
1458
26
    }
1459
1460
    /*
1461
     * Note : the namespace resolution is deferred until the end of the
1462
     *        attributes parsing, since local namespace can be defined as
1463
     *        an attribute at this level.
1464
     */
1465
552k
    ret = xmlNewDocNode(ctxt->myDoc, NULL, name, NULL);
1466
552k
    if (ret == NULL) {
1467
749
  xmlFree(prefix);
1468
749
  xmlSAX2ErrMemory(ctxt);
1469
749
        return;
1470
749
    }
1471
551k
    ctxt->nodemem = -1;
1472
1473
    /* Initialize parent before pushing node */
1474
551k
    parent = ctxt->node;
1475
551k
    if (parent == NULL)
1476
57.5k
        parent = (xmlNodePtr) ctxt->myDoc;
1477
1478
    /*
1479
     * Link the child element
1480
     */
1481
551k
    xmlSAX2AppendChild(ctxt, ret);
1482
1483
    /*
1484
     * We are parsing a new node.
1485
     */
1486
551k
    if (nodePush(ctxt, ret) < 0) {
1487
147
        xmlUnlinkNode(ret);
1488
147
        xmlFreeNode(ret);
1489
147
        if (prefix != NULL)
1490
10
            xmlFree(prefix);
1491
147
        return;
1492
147
    }
1493
1494
    /*
1495
     * Insert all the defaulted attributes from the DTD especially
1496
     * namespaces
1497
     */
1498
551k
    if ((ctxt->myDoc->intSubset != NULL) ||
1499
324k
        (ctxt->myDoc->extSubset != NULL)) {
1500
324k
        xmlCheckDefaultedAttributes(ctxt, name, prefix, atts);
1501
324k
    }
1502
1503
    /*
1504
     * process all the attributes whose name start with "xmlns"
1505
     */
1506
551k
    if (atts != NULL) {
1507
141k
        i = 0;
1508
141k
        att = atts[i++];
1509
141k
        value = atts[i++];
1510
323k
        while ((att != NULL) && (value != NULL)) {
1511
182k
            if ((att[0] == 'x') && (att[1] == 'm') && (att[2] == 'l') &&
1512
111k
                (att[3] == 'n') && (att[4] == 's'))
1513
80.0k
                xmlSAX1Attribute(ctxt, att, value, prefix);
1514
1515
182k
            att = atts[i++];
1516
182k
            value = atts[i++];
1517
182k
        }
1518
141k
    }
1519
1520
    /*
1521
     * Search the namespace, note that since the attributes have been
1522
     * processed, the local namespaces are available.
1523
     */
1524
551k
    res = xmlSearchNsSafe(ret, prefix, &ns);
1525
551k
    if (res < 0)
1526
20
        xmlSAX2ErrMemory(ctxt);
1527
551k
    if ((ns == NULL) && (parent != NULL)) {
1528
429k
        res = xmlSearchNsSafe(parent, prefix, &ns);
1529
429k
        if (res < 0)
1530
0
            xmlSAX2ErrMemory(ctxt);
1531
429k
    }
1532
551k
    if ((prefix != NULL) && (ns == NULL)) {
1533
22.7k
        xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
1534
22.7k
                     "Namespace prefix %s is not defined\n",
1535
22.7k
                     prefix, NULL);
1536
22.7k
        ns = xmlNewNs(ret, NULL, prefix);
1537
22.7k
        if (ns == NULL)
1538
22
            xmlSAX2ErrMemory(ctxt);
1539
22.7k
    }
1540
1541
    /*
1542
     * set the namespace node, making sure that if the default namespace
1543
     * is unbound on a parent we simply keep it NULL
1544
     */
1545
551k
    if ((ns != NULL) && (ns->href != NULL) &&
1546
121k
        ((ns->href[0] != 0) || (ns->prefix != NULL)))
1547
118k
        xmlSetNs(ret, ns);
1548
1549
    /*
1550
     * process all the other attributes
1551
     */
1552
551k
    if (atts != NULL) {
1553
141k
        i = 0;
1554
141k
  att = atts[i++];
1555
141k
  value = atts[i++];
1556
323k
        while ((att != NULL) && (value != NULL)) {
1557
182k
            if ((att[0] != 'x') || (att[1] != 'm') || (att[2] != 'l') ||
1558
111k
                (att[3] != 'n') || (att[4] != 's'))
1559
102k
                xmlSAX1Attribute(ctxt, att, value, NULL);
1560
1561
            /*
1562
             * Next ones
1563
             */
1564
182k
            att = atts[i++];
1565
182k
            value = atts[i++];
1566
182k
        }
1567
141k
    }
1568
1569
551k
#ifdef LIBXML_VALID_ENABLED
1570
    /*
1571
     * If it's the Document root, finish the DTD validation and
1572
     * check the document root element for validity
1573
     */
1574
551k
    if ((ctxt->validate) &&
1575
182k
        ((ctxt->vctxt.flags & XML_VCTXT_DTD_VALIDATED) == 0)) {
1576
17.6k
  int chk;
1577
1578
17.6k
  chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
1579
17.6k
  if (chk <= 0)
1580
311
      ctxt->valid = 0;
1581
17.6k
  if (chk < 0)
1582
0
      ctxt->wellFormed = 0;
1583
17.6k
  ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
1584
17.6k
  ctxt->vctxt.flags |= XML_VCTXT_DTD_VALIDATED;
1585
17.6k
    }
1586
551k
#endif /* LIBXML_VALID_ENABLED */
1587
1588
551k
    if (prefix != NULL)
1589
70.4k
  xmlFree(prefix);
1590
1591
551k
}
1592
#endif /* LIBXML_SAX1_ENABLED */
1593
1594
#ifdef LIBXML_HTML_ENABLED
1595
static void
1596
xmlSAX2HtmlAttribute(xmlParserCtxtPtr ctxt, const xmlChar *fullname,
1597
616k
                     const xmlChar *value) {
1598
616k
    xmlAttrPtr ret;
1599
616k
    xmlChar *nval = NULL;
1600
1601
616k
    ret = xmlNewNsProp(ctxt->node, NULL, fullname, NULL);
1602
616k
    if (ret == NULL) {
1603
96
        xmlSAX2ErrMemory(ctxt);
1604
96
        return;
1605
96
    }
1606
1607
616k
    if ((value == NULL) && (htmlIsBooleanAttr(fullname))) {
1608
649
        nval = xmlStrdup(fullname);
1609
649
        if (nval == NULL) {
1610
3
            xmlSAX2ErrMemory(ctxt);
1611
3
            return;
1612
3
        }
1613
646
        value = nval;
1614
646
    }
1615
1616
616k
    if (value != NULL) {
1617
102k
        ret->children = xmlNewDocText(ctxt->myDoc, value);
1618
102k
        if (ret->children == NULL) {
1619
47
            xmlSAX2ErrMemory(ctxt);
1620
102k
        } else {
1621
102k
            ret->last = ret->children;
1622
102k
            ret->children->parent = (xmlNodePtr) ret;
1623
102k
        }
1624
102k
    }
1625
1626
616k
    if (((ctxt->loadsubset & XML_SKIP_IDS) == 0) &&
1627
        /*
1628
         * Don't create IDs containing entity references (should
1629
         * be always the case with HTML)
1630
         */
1631
616k
        (ret->children != NULL) &&
1632
102k
        (ret->children->type == XML_TEXT_NODE) &&
1633
102k
        (ret->children->next == NULL)) {
1634
102k
        int res = xmlIsID(ctxt->myDoc, ctxt->node, ret);
1635
1636
102k
        if (res < 0)
1637
0
            xmlCtxtErrMemory(ctxt);
1638
102k
        else if (res > 0)
1639
56.4k
            xmlAddID(&ctxt->vctxt, ctxt->myDoc, ret->children->content, ret);
1640
102k
    }
1641
1642
616k
    if (nval != NULL)
1643
646
        xmlFree(nval);
1644
616k
}
1645
1646
/**
1647
 * Called when an opening tag has been processed.
1648
 *
1649
 * @param ctxt  parser context
1650
 * @param fullname  The element name, including namespace prefix
1651
 * @param atts  An array of name/value attributes pairs, NULL terminated
1652
 */
1653
static void
1654
xmlSAX2StartHtmlElement(xmlParserCtxtPtr ctxt, const xmlChar *fullname,
1655
352k
                        const xmlChar **atts) {
1656
352k
    xmlNodePtr ret;
1657
352k
    xmlNodePtr parent;
1658
352k
    const xmlChar *att;
1659
352k
    const xmlChar *value;
1660
352k
    int i;
1661
1662
352k
    ret = xmlNewDocNode(ctxt->myDoc, NULL, fullname, NULL);
1663
352k
    if (ret == NULL) {
1664
301
  xmlSAX2ErrMemory(ctxt);
1665
301
        return;
1666
301
    }
1667
352k
    ctxt->nodemem = -1;
1668
1669
    /* Initialize parent before pushing node */
1670
352k
    parent = ctxt->node;
1671
352k
    if (parent == NULL)
1672
20.7k
        parent = (xmlNodePtr) ctxt->myDoc;
1673
1674
    /*
1675
     * Link the child element
1676
     */
1677
352k
    xmlSAX2AppendChild(ctxt, ret);
1678
1679
    /*
1680
     * We are parsing a new node.
1681
     */
1682
352k
    if (nodePush(ctxt, ret) < 0) {
1683
139
        xmlUnlinkNode(ret);
1684
139
        xmlFreeNode(ret);
1685
139
        return;
1686
139
    }
1687
1688
352k
    if (atts != NULL) {
1689
101k
        i = 0;
1690
101k
  att = atts[i++];
1691
101k
  value = atts[i++];
1692
718k
        while (att != NULL) {
1693
616k
            xmlSAX2HtmlAttribute(ctxt, att, value);
1694
616k
            att = atts[i++];
1695
616k
            value = atts[i++];
1696
616k
        }
1697
101k
    }
1698
352k
}
1699
#endif /* LIBXML_HTML_ENABLED */
1700
1701
/**
1702
 * Called when an opening tag has been processed.
1703
 *
1704
 * @deprecated Don't call this function directly.
1705
 *
1706
 * Used for HTML and SAX1.
1707
 *
1708
 * @param ctx  the user data (XML parser context)
1709
 * @param fullname  The element name, including namespace prefix
1710
 * @param atts  An array of name/value attributes pairs, NULL terminated
1711
 */
1712
void
1713
905k
xmlSAX2StartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts) {
1714
905k
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1715
1716
905k
    (void) atts;
1717
1718
905k
    if ((ctxt == NULL) || (fullname == NULL) || (ctxt->myDoc == NULL))
1719
0
        return;
1720
1721
905k
#ifdef LIBXML_SAX1_ENABLED
1722
905k
    if (!ctxt->html) {
1723
552k
        xmlSAX1StartElement(ctxt, fullname, atts);
1724
552k
        return;
1725
552k
    }
1726
352k
#endif
1727
1728
352k
#ifdef LIBXML_HTML_ENABLED
1729
352k
    if (ctxt->html) {
1730
352k
        xmlSAX2StartHtmlElement(ctxt, fullname, atts);
1731
352k
        return;
1732
352k
    }
1733
352k
#endif
1734
352k
}
1735
1736
/**
1737
 * called when the end of an element has been detected.
1738
 *
1739
 * @deprecated Don't call this function directly.
1740
 *
1741
 * Used for HTML and SAX1.
1742
 *
1743
 * @param ctx  the user data (XML parser context)
1744
 * @param name  The element name
1745
 */
1746
void
1747
xmlSAX2EndElement(void *ctx, const xmlChar *name ATTRIBUTE_UNUSED)
1748
512k
{
1749
512k
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1750
1751
512k
    if (ctxt == NULL)
1752
0
        return;
1753
1754
512k
#if defined(LIBXML_SAX1_ENABLED) && defined(LIBXML_VALID_ENABLED)
1755
512k
    if (!ctxt->html && ctxt->validate && ctxt->wellFormed &&
1756
40.7k
        ctxt->myDoc && ctxt->myDoc->intSubset)
1757
40.7k
        ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc,
1758
40.7k
               ctxt->node);
1759
512k
#endif /* LIBXML_VALID_ENABLED */
1760
1761
512k
#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED)
1762
512k
    ctxt->nodemem = -1;
1763
1764
    /*
1765
     * end of parsing of this node.
1766
     */
1767
512k
    nodePop(ctxt);
1768
512k
#endif
1769
512k
}
1770
1771
/*
1772
 * @param ctxt  the parser context
1773
 * @param doc  the document
1774
 * @param str  the input string
1775
 * @param len  the string length
1776
 *
1777
 * Callback for a text node
1778
 *
1779
 * @returns the newly allocated string or NULL if not needed or error
1780
 */
1781
static xmlNodePtr
1782
xmlSAX2TextNode(xmlParserCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *str,
1783
4.16M
                int len) {
1784
4.16M
    xmlNodePtr ret;
1785
4.16M
    const xmlChar *intern = NULL;
1786
1787
    /*
1788
     * Allocate
1789
     */
1790
4.16M
    if (ctxt->freeElems != NULL) {
1791
3.28k
  ret = ctxt->freeElems;
1792
3.28k
  ctxt->freeElems = ret->next;
1793
3.28k
  ctxt->freeElemsNr--;
1794
4.16M
    } else {
1795
4.16M
  ret = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
1796
4.16M
    }
1797
4.16M
    if (ret == NULL) {
1798
559
        xmlCtxtErrMemory(ctxt);
1799
559
  return(NULL);
1800
559
    }
1801
4.16M
    memset(ret, 0, sizeof(xmlNode));
1802
    /*
1803
     * intern the formatting blanks found between tags, or the
1804
     * very short strings
1805
     */
1806
4.16M
    if ((!ctxt->html) && (ctxt->dictNames)) {
1807
3.02M
        xmlChar cur = str[len];
1808
1809
3.02M
  if ((len < (int) (2 * sizeof(void *))) &&
1810
2.40M
      (ctxt->options & XML_PARSE_COMPACT)) {
1811
      /* store the string in the node overriding properties and nsDef */
1812
550k
      xmlChar *tmp = (xmlChar *) &(ret->properties);
1813
550k
      memcpy(tmp, str, len);
1814
550k
      tmp[len] = 0;
1815
550k
      intern = tmp;
1816
2.47M
  } else if ((len <= 3) && ((cur == '"') || (cur == '\'') ||
1817
794k
      ((cur == '<') && (str[len + 1] != '!')))) {
1818
794k
      intern = xmlDictLookup(ctxt->dict, str, len);
1819
794k
            if (intern == NULL) {
1820
18
                xmlSAX2ErrMemory(ctxt);
1821
18
                xmlFree(ret);
1822
18
                return(NULL);
1823
18
            }
1824
1.67M
  } else if (IS_BLANK_CH(*str) && (len < 60) && (cur == '<') &&
1825
392k
             (str[len + 1] != '!')) {
1826
375k
      int i;
1827
1828
2.91M
      for (i = 1;i < len;i++) {
1829
2.58M
    if (!IS_BLANK_CH(str[i])) goto skip;
1830
2.58M
      }
1831
333k
      intern = xmlDictLookup(ctxt->dict, str, len);
1832
333k
            if (intern == NULL) {
1833
12
                xmlSAX2ErrMemory(ctxt);
1834
12
                xmlFree(ret);
1835
12
                return(NULL);
1836
12
            }
1837
333k
  }
1838
3.02M
    }
1839
4.16M
skip:
1840
4.16M
    ret->type = XML_TEXT_NODE;
1841
4.16M
    ret->doc = doc;
1842
1843
4.16M
    ret->name = xmlStringText;
1844
4.16M
    if (intern == NULL) {
1845
2.48M
  ret->content = xmlStrndup(str, len);
1846
2.48M
  if (ret->content == NULL) {
1847
330
      xmlSAX2ErrMemory(ctxt);
1848
330
      xmlFree(ret);
1849
330
      return(NULL);
1850
330
  }
1851
2.48M
    } else
1852
1.67M
  ret->content = (xmlChar *) intern;
1853
1854
4.16M
    if ((xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
1855
0
  xmlRegisterNodeDefaultValue(ret);
1856
4.16M
    return(ret);
1857
4.16M
}
1858
1859
#ifdef LIBXML_VALID_ENABLED
1860
/*
1861
 * @param ctxt  the parser context
1862
 * @param str  the input string
1863
 * @param len  the string length
1864
 *
1865
 * Remove the entities from an attribute value
1866
 *
1867
 * @returns the newly allocated string or NULL if not needed or error
1868
 */
1869
static xmlChar *
1870
xmlSAX2DecodeAttrEntities(xmlParserCtxtPtr ctxt, const xmlChar *str,
1871
19.3k
                          const xmlChar *end) {
1872
19.3k
    const xmlChar *in;
1873
1874
19.3k
    in = str;
1875
172k
    while (in < end)
1876
159k
        if (*in++ == '&')
1877
6.17k
      goto decode;
1878
13.1k
    return(NULL);
1879
6.17k
decode:
1880
    /*
1881
     * If the value contains '&', we can be sure it was allocated and is
1882
     * zero-terminated.
1883
     */
1884
    /* TODO: normalize if needed */
1885
6.17k
    return(xmlExpandEntitiesInAttValue(ctxt, str, /* normalize */ 0));
1886
19.3k
}
1887
#endif /* LIBXML_VALID_ENABLED */
1888
1889
/**
1890
 * Handle an attribute that has been read by the parser.
1891
 * The default handling is to convert the attribute into an
1892
 * DOM subtree and past it in a new xmlAttr element added to
1893
 * the element.
1894
 *
1895
 * @param ctxt  the parser context
1896
 * @param localname  the local name of the attribute
1897
 * @param prefix  the attribute namespace prefix if available
1898
 * @param value  start of the attribute value
1899
 * @param valueend  end of the attribute value
1900
 * @returns the new attribute or NULL in case of error.
1901
 */
1902
static xmlAttrPtr
1903
xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
1904
                   const xmlChar * localname,
1905
                   const xmlChar * prefix,
1906
       const xmlChar * value,
1907
       const xmlChar * valueend)
1908
1.84M
{
1909
1.84M
    xmlAttrPtr ret;
1910
1.84M
    xmlNsPtr namespace = NULL;
1911
1.84M
    xmlChar *dup = NULL;
1912
1913
    /*
1914
     * Note: if prefix == NULL, the attribute is not in the default namespace
1915
     */
1916
1.84M
    if (prefix != NULL) {
1917
271k
  namespace = xmlParserNsLookupSax(ctxt, prefix);
1918
271k
  if ((namespace == NULL) && (xmlStrEqual(prefix, BAD_CAST "xml"))) {
1919
160k
            int res;
1920
1921
160k
      res = xmlSearchNsSafe(ctxt->node, prefix, &namespace);
1922
160k
            if (res < 0)
1923
111
                xmlSAX2ErrMemory(ctxt);
1924
160k
  }
1925
271k
    }
1926
1927
    /*
1928
     * allocate the node
1929
     */
1930
1.84M
    if (ctxt->freeAttrs != NULL) {
1931
1.47k
        ret = ctxt->freeAttrs;
1932
1.47k
  ctxt->freeAttrs = ret->next;
1933
1.47k
  ctxt->freeAttrsNr--;
1934
1.84M
    } else {
1935
1.84M
        ret = xmlMalloc(sizeof(*ret));
1936
1.84M
        if (ret == NULL) {
1937
176
            xmlSAX2ErrMemory(ctxt);
1938
176
            return(NULL);
1939
176
        }
1940
1.84M
    }
1941
1942
1.84M
    memset(ret, 0, sizeof(xmlAttr));
1943
1.84M
    ret->type = XML_ATTRIBUTE_NODE;
1944
1945
    /*
1946
     * xmlParseBalancedChunkMemoryRecover had a bug that could result in
1947
     * a mismatch between ctxt->node->doc and ctxt->myDoc. We use
1948
     * ctxt->node->doc here, but we should somehow make sure that the
1949
     * document pointers match.
1950
     */
1951
1952
    /* assert(ctxt->node->doc == ctxt->myDoc); */
1953
1954
1.84M
    ret->parent = ctxt->node;
1955
1.84M
    ret->doc = ctxt->node->doc;
1956
1.84M
    ret->ns = namespace;
1957
1958
1.84M
    if (ctxt->dictNames) {
1959
1.47M
        ret->name = localname;
1960
1.47M
    } else {
1961
367k
        ret->name = xmlStrdup(localname);
1962
367k
        if (ret->name == NULL)
1963
124
            xmlSAX2ErrMemory(ctxt);
1964
367k
    }
1965
1966
1.84M
    if ((xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
1967
0
        xmlRegisterNodeDefaultValue((xmlNodePtr)ret);
1968
1969
1.84M
    if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
1970
615k
  xmlNodePtr tmp;
1971
1972
  /*
1973
   * We know that if there is an entity reference, then
1974
   * the string has been dup'ed and terminates with 0
1975
   * otherwise with ' or "
1976
   */
1977
615k
  if (*valueend != 0) {
1978
249k
      tmp = xmlSAX2TextNode(ctxt, ret->doc, value, valueend - value);
1979
249k
      ret->children = tmp;
1980
249k
      ret->last = tmp;
1981
249k
      if (tmp != NULL) {
1982
249k
    tmp->parent = (xmlNodePtr) ret;
1983
249k
      }
1984
366k
  } else if (valueend > value) {
1985
357k
            if (xmlNodeParseAttValue(ret->doc, ret, value, valueend - value,
1986
357k
                                     NULL) < 0)
1987
287
                xmlSAX2ErrMemory(ctxt);
1988
357k
  }
1989
1.22M
    } else if (value != NULL) {
1990
1.22M
  xmlNodePtr tmp;
1991
1992
1.22M
  tmp = xmlSAX2TextNode(ctxt, ret->doc, value, valueend - value);
1993
1.22M
  ret->children = tmp;
1994
1.22M
  ret->last = tmp;
1995
1.22M
  if (tmp != NULL) {
1996
1.22M
      tmp->parent = (xmlNodePtr) ret;
1997
1.22M
  }
1998
1.22M
    }
1999
2000
1.84M
#ifdef LIBXML_VALID_ENABLED
2001
1.84M
    if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
2002
81.5k
        ctxt->myDoc && ctxt->myDoc->intSubset) {
2003
  /*
2004
   * If we don't substitute entities, the validation should be
2005
   * done on a value with replaced entities anyway.
2006
   */
2007
81.5k
        if (!ctxt->replaceEntities) {
2008
19.3k
      dup = xmlSAX2DecodeAttrEntities(ctxt, value, valueend);
2009
19.3k
      if (dup == NULL) {
2010
13.1k
          if (*valueend == 0) {
2011
9.55k
        ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
2012
9.55k
            ctxt->myDoc, ctxt->node, ret, value);
2013
9.55k
    } else {
2014
        /*
2015
         * That should already be normalized.
2016
         * cheaper to finally allocate here than duplicate
2017
         * entry points in the full validation code
2018
         */
2019
3.61k
        dup = xmlStrndup(value, valueend - value);
2020
3.61k
                    if (dup == NULL)
2021
15
                        xmlSAX2ErrMemory(ctxt);
2022
2023
3.61k
        ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
2024
3.61k
            ctxt->myDoc, ctxt->node, ret, dup);
2025
3.61k
    }
2026
13.1k
      } else {
2027
          /*
2028
     * dup now contains a string of the flattened attribute
2029
     * content with entities substituted. Check if we need to
2030
     * apply an extra layer of normalization.
2031
     * It need to be done twice ... it's an extra burden related
2032
     * to the ability to keep references in attributes
2033
     */
2034
6.15k
    if (ctxt->attsSpecial != NULL) {
2035
5.31k
        xmlChar *nvalnorm;
2036
5.31k
        xmlChar fn[50];
2037
5.31k
        xmlChar *fullname;
2038
2039
5.31k
        fullname = xmlBuildQName(localname, prefix, fn, 50);
2040
5.31k
                    if (fullname == NULL) {
2041
7
                        xmlSAX2ErrMemory(ctxt);
2042
5.30k
                    } else {
2043
5.30k
      ctxt->vctxt.valid = 1;
2044
5.30k
            nvalnorm = xmlValidCtxtNormalizeAttributeValue(
2045
5.30k
                       &ctxt->vctxt, ctxt->myDoc,
2046
5.30k
           ctxt->node, fullname, dup);
2047
5.30k
      if (ctxt->vctxt.valid != 1)
2048
0
          ctxt->valid = 0;
2049
2050
5.30k
      if ((fullname != fn) && (fullname != localname))
2051
750
          xmlFree(fullname);
2052
5.30k
      if (nvalnorm != NULL) {
2053
4.50k
          xmlFree(dup);
2054
4.50k
          dup = nvalnorm;
2055
4.50k
      }
2056
5.30k
        }
2057
5.31k
    }
2058
2059
6.15k
    ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
2060
6.15k
              ctxt->myDoc, ctxt->node, ret, dup);
2061
6.15k
      }
2062
62.2k
  } else {
2063
      /*
2064
       * if entities already have been substituted, then
2065
       * the attribute as passed is already normalized
2066
       */
2067
62.2k
      dup = xmlStrndup(value, valueend - value);
2068
62.2k
            if (dup == NULL)
2069
42
                xmlSAX2ErrMemory(ctxt);
2070
2071
            /*
2072
             * When replacing entities, make sure that IDs in
2073
             * entities aren't registered. This also shouldn't be
2074
             * done when entities aren't replaced, but this would
2075
             * require to rework IDREF checks.
2076
             */
2077
62.2k
            if (ctxt->input->entity != NULL)
2078
576
                ctxt->vctxt.flags |= XML_VCTXT_IN_ENTITY;
2079
2080
62.2k
      ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
2081
62.2k
                               ctxt->myDoc, ctxt->node, ret, dup);
2082
2083
62.2k
            ctxt->vctxt.flags &= ~XML_VCTXT_IN_ENTITY;
2084
62.2k
  }
2085
81.5k
    } else
2086
1.76M
#endif /* LIBXML_VALID_ENABLED */
2087
1.76M
           if (((ctxt->loadsubset & XML_SKIP_IDS) == 0) &&
2088
1.33M
               (ctxt->input->entity == NULL) &&
2089
               /* Don't create IDs containing entity references */
2090
1.24M
               (ret->children != NULL) &&
2091
1.24M
               (ret->children->type == XML_TEXT_NODE) &&
2092
1.23M
               (ret->children->next == NULL)) {
2093
1.23M
        xmlChar *content = ret->children->content;
2094
        /*
2095
   * when validating, the ID registration is done at the attribute
2096
   * validation level. Otherwise we have to do specific handling here.
2097
   */
2098
1.23M
        if ((prefix == ctxt->str_xml) &&
2099
80.7k
             (localname[0] == 'i') && (localname[1] == 'd') &&
2100
18.7k
       (localname[2] == 0)) {
2101
      /*
2102
       * Add the xml:id value
2103
       *
2104
       * Open issue: normalization of the value.
2105
       */
2106
16.2k
      if (xmlValidateNCName(content, 1) != 0) {
2107
12.8k
          xmlErrId(ctxt, XML_DTD_XMLID_VALUE,
2108
12.8k
                         "xml:id : attribute value %s is not an NCName\n",
2109
12.8k
                         content);
2110
12.8k
      }
2111
16.2k
      xmlAddID(&ctxt->vctxt, ctxt->myDoc, content, ret);
2112
1.21M
  } else {
2113
1.21M
            int res = xmlIsID(ctxt->myDoc, ctxt->node, ret);
2114
2115
1.21M
            if (res < 0)
2116
14
                xmlCtxtErrMemory(ctxt);
2117
1.21M
            else if (res > 0)
2118
59.9k
                xmlAddID(&ctxt->vctxt, ctxt->myDoc, content, ret);
2119
1.15M
            else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret))
2120
100k
                xmlAddRef(&ctxt->vctxt, ctxt->myDoc, content, ret);
2121
1.21M
  }
2122
1.23M
    }
2123
1.84M
    if (dup != NULL)
2124
71.9k
  xmlFree(dup);
2125
2126
1.84M
    return(ret);
2127
1.84M
}
2128
2129
/**
2130
 * SAX2 callback when an element start has been detected by the parser.
2131
 * It provides the namespace information for the element, as well as
2132
 * the new namespace declarations on the element.
2133
 *
2134
 * @param ctx  the user data (XML parser context)
2135
 * @param localname  the local name of the element
2136
 * @param prefix  the element namespace prefix if available
2137
 * @param URI  the element namespace name if available
2138
 * @param nb_namespaces  number of namespace definitions on that node
2139
 * @param namespaces  pointer to the array of prefix/URI pairs namespace definitions
2140
 * @param nb_attributes  the number of attributes on that node
2141
 * @param nb_defaulted  the number of defaulted attributes.
2142
 * @param attributes  pointer to the array of (localname/prefix/URI/value/end)
2143
 *               attribute values.
2144
 */
2145
void
2146
xmlSAX2StartElementNs(void *ctx,
2147
                      const xmlChar *localname,
2148
          const xmlChar *prefix,
2149
          const xmlChar *URI,
2150
          int nb_namespaces,
2151
          const xmlChar **namespaces,
2152
          int nb_attributes,
2153
          int nb_defaulted,
2154
          const xmlChar **attributes)
2155
4.03M
{
2156
4.03M
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
2157
4.03M
    xmlNodePtr ret;
2158
4.03M
    xmlNsPtr last = NULL, ns;
2159
4.03M
    const xmlChar *uri, *pref;
2160
4.03M
    xmlChar *lname = NULL;
2161
4.03M
    int i, j;
2162
2163
4.03M
    if (ctx == NULL) return;
2164
2165
4.03M
#ifdef LIBXML_VALID_ENABLED
2166
    /*
2167
     * First check on validity:
2168
     */
2169
4.03M
    if (ctxt->validate &&
2170
535k
        ((ctxt->myDoc == NULL) ||
2171
535k
         ((ctxt->myDoc->extSubset == NULL) &&
2172
518k
          ((ctxt->myDoc->intSubset == NULL) ||
2173
505k
     ((ctxt->myDoc->intSubset->notations == NULL) &&
2174
501k
      (ctxt->myDoc->intSubset->elements == NULL) &&
2175
86.7k
      (ctxt->myDoc->intSubset->attributes == NULL) &&
2176
86.7k
      (ctxt->myDoc->intSubset->entities == NULL)))))) {
2177
15.0k
  xmlErrValid(ctxt, XML_DTD_NO_DTD,
2178
15.0k
    "Validation failed: no DTD found !", NULL, NULL);
2179
15.0k
  ctxt->validate = 0;
2180
15.0k
    }
2181
4.03M
#endif /* LIBXML_VALID_ENABLED */
2182
2183
    /*
2184
     * Take care of the rare case of an undefined namespace prefix
2185
     */
2186
4.03M
    if ((prefix != NULL) && (URI == NULL)) {
2187
107k
        if (ctxt->dictNames) {
2188
80.0k
      const xmlChar *fullname;
2189
2190
80.0k
      fullname = xmlDictQLookup(ctxt->dict, prefix, localname);
2191
80.0k
      if (fullname == NULL) {
2192
26
                xmlSAX2ErrMemory(ctxt);
2193
26
                return;
2194
26
            }
2195
80.0k
      localname = fullname;
2196
80.0k
  } else {
2197
27.2k
      lname = xmlBuildQName(localname, prefix, NULL, 0);
2198
27.2k
            if (lname == NULL) {
2199
25
                xmlSAX2ErrMemory(ctxt);
2200
25
                return;
2201
25
            }
2202
27.2k
  }
2203
107k
    }
2204
    /*
2205
     * allocate the node
2206
     */
2207
4.03M
    if (ctxt->freeElems != NULL) {
2208
2.10k
        ret = ctxt->freeElems;
2209
2.10k
  ctxt->freeElems = ret->next;
2210
2.10k
  ctxt->freeElemsNr--;
2211
2.10k
  memset(ret, 0, sizeof(xmlNode));
2212
2.10k
        ret->doc = ctxt->myDoc;
2213
2.10k
  ret->type = XML_ELEMENT_NODE;
2214
2215
2.10k
  if (ctxt->dictNames)
2216
1.11k
      ret->name = localname;
2217
986
  else {
2218
986
      if (lname == NULL)
2219
780
    ret->name = xmlStrdup(localname);
2220
206
      else
2221
206
          ret->name = lname;
2222
986
      if (ret->name == NULL) {
2223
1
          xmlSAX2ErrMemory(ctxt);
2224
1
                xmlFree(ret);
2225
1
    return;
2226
1
      }
2227
986
  }
2228
2.10k
  if ((xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
2229
0
      xmlRegisterNodeDefaultValue(ret);
2230
4.03M
    } else {
2231
4.03M
  if (ctxt->dictNames)
2232
3.07M
      ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL,
2233
3.07M
                                 (xmlChar *) localname, NULL);
2234
959k
  else if (lname == NULL)
2235
932k
      ret = xmlNewDocNode(ctxt->myDoc, NULL, localname, NULL);
2236
27.0k
  else
2237
27.0k
      ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL, lname, NULL);
2238
4.03M
  if (ret == NULL) {
2239
541
      xmlSAX2ErrMemory(ctxt);
2240
541
      return;
2241
541
  }
2242
4.03M
    }
2243
2244
    /*
2245
     * Build the namespace list
2246
     */
2247
4.99M
    for (i = 0,j = 0;j < nb_namespaces;j++) {
2248
955k
        pref = namespaces[i++];
2249
955k
  uri = namespaces[i++];
2250
955k
  ns = xmlNewNs(NULL, uri, pref);
2251
955k
  if (ns != NULL) {
2252
955k
      if (last == NULL) {
2253
489k
          ret->nsDef = last = ns;
2254
489k
      } else {
2255
465k
          last->next = ns;
2256
465k
    last = ns;
2257
465k
      }
2258
955k
      if ((URI != NULL) && (prefix == pref))
2259
190k
    ret->ns = ns;
2260
955k
  } else {
2261
408
            xmlSAX2ErrMemory(ctxt);
2262
408
      continue;
2263
408
  }
2264
2265
955k
        xmlParserNsUpdateSax(ctxt, pref, ns);
2266
2267
955k
#ifdef LIBXML_VALID_ENABLED
2268
955k
  if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
2269
14.5k
      ctxt->myDoc && ctxt->myDoc->intSubset) {
2270
14.5k
      ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
2271
14.5k
                                             ret, prefix, ns, uri);
2272
14.5k
  }
2273
955k
#endif /* LIBXML_VALID_ENABLED */
2274
955k
    }
2275
4.03M
    ctxt->nodemem = -1;
2276
2277
    /*
2278
     * Link the child element
2279
     */
2280
4.03M
    xmlSAX2AppendChild(ctxt, ret);
2281
2282
    /*
2283
     * We are parsing a new node.
2284
     */
2285
4.03M
    if (nodePush(ctxt, ret) < 0) {
2286
288
        xmlUnlinkNode(ret);
2287
288
        xmlFreeNode(ret);
2288
288
        return;
2289
288
    }
2290
2291
    /*
2292
     * Insert the defaulted attributes from the DTD only if requested:
2293
     */
2294
4.03M
    if ((nb_defaulted != 0) &&
2295
252k
        ((ctxt->loadsubset & XML_COMPLETE_ATTRS) == 0))
2296
63.6k
  nb_attributes -= nb_defaulted;
2297
2298
    /*
2299
     * Search the namespace if it wasn't already found
2300
     * Note that, if prefix is NULL, this searches for the default Ns
2301
     */
2302
4.03M
    if ((URI != NULL) && (ret->ns == NULL)) {
2303
1.41M
        ret->ns = xmlParserNsLookupSax(ctxt, prefix);
2304
1.41M
  if ((ret->ns == NULL) && (xmlStrEqual(prefix, BAD_CAST "xml"))) {
2305
8.54k
            int res;
2306
2307
8.54k
      res = xmlSearchNsSafe(ret, prefix, &ret->ns);
2308
8.54k
            if (res < 0)
2309
29
                xmlSAX2ErrMemory(ctxt);
2310
8.54k
  }
2311
1.41M
  if (ret->ns == NULL) {
2312
211
      ns = xmlNewNs(ret, NULL, prefix);
2313
211
      if (ns == NULL) {
2314
2315
0
          xmlSAX2ErrMemory(ctxt);
2316
0
    return;
2317
0
      }
2318
211
            if (prefix != NULL)
2319
80
                xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
2320
80
                             "Namespace prefix %s was not found\n",
2321
80
                             prefix, NULL);
2322
131
            else
2323
131
                xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
2324
131
                             "Namespace default prefix was not found\n",
2325
131
                             NULL, NULL);
2326
211
  }
2327
1.41M
    }
2328
2329
    /*
2330
     * process all the other attributes
2331
     */
2332
4.03M
    if (nb_attributes > 0) {
2333
1.03M
        xmlAttrPtr prev = NULL;
2334
2335
2.87M
        for (j = 0,i = 0;i < nb_attributes;i++,j+=5) {
2336
1.84M
            xmlAttrPtr attr = NULL;
2337
2338
      /*
2339
       * Handle the rare case of an undefined attribute prefix
2340
       */
2341
1.84M
      if ((attributes[j+1] != NULL) && (attributes[j+2] == NULL)) {
2342
185k
    if (ctxt->dictNames) {
2343
115k
        const xmlChar *fullname;
2344
2345
115k
        fullname = xmlDictQLookup(ctxt->dict, attributes[j+1],
2346
115k
                                  attributes[j]);
2347
115k
        if (fullname == NULL) {
2348
13
                        xmlSAX2ErrMemory(ctxt);
2349
13
                        return;
2350
13
                    }
2351
115k
                    attr = xmlSAX2AttributeNs(ctxt, fullname, NULL,
2352
115k
                                              attributes[j+3],
2353
115k
                                              attributes[j+4]);
2354
115k
                    goto have_attr;
2355
115k
    } else {
2356
70.3k
        lname = xmlBuildQName(attributes[j], attributes[j+1],
2357
70.3k
                              NULL, 0);
2358
70.3k
        if (lname == NULL) {
2359
16
                        xmlSAX2ErrMemory(ctxt);
2360
16
                        return;
2361
16
                    }
2362
70.3k
                    attr = xmlSAX2AttributeNs(ctxt, lname, NULL,
2363
70.3k
                                              attributes[j+3],
2364
70.3k
                                              attributes[j+4]);
2365
70.3k
                    xmlFree(lname);
2366
70.3k
                    goto have_attr;
2367
70.3k
    }
2368
185k
      }
2369
1.65M
            attr = xmlSAX2AttributeNs(ctxt, attributes[j], attributes[j+1],
2370
1.65M
                                      attributes[j+3], attributes[j+4]);
2371
1.84M
have_attr:
2372
1.84M
            if (attr == NULL)
2373
176
                continue;
2374
2375
            /* link at the end to preserve order */
2376
1.84M
            if (prev == NULL) {
2377
1.03M
                ctxt->node->properties = attr;
2378
1.03M
            } else {
2379
809k
                prev->next = attr;
2380
809k
                attr->prev = prev;
2381
809k
            }
2382
2383
1.84M
            prev = attr;
2384
1.84M
  }
2385
1.03M
    }
2386
2387
4.03M
#ifdef LIBXML_VALID_ENABLED
2388
    /*
2389
     * If it's the Document root, finish the DTD validation and
2390
     * check the document root element for validity
2391
     */
2392
4.03M
    if ((ctxt->validate) &&
2393
520k
        ((ctxt->vctxt.flags & XML_VCTXT_DTD_VALIDATED) == 0)) {
2394
17.4k
  int chk;
2395
2396
17.4k
  chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
2397
17.4k
  if (chk <= 0)
2398
422
      ctxt->valid = 0;
2399
17.4k
  if (chk < 0)
2400
0
      ctxt->wellFormed = 0;
2401
17.4k
  ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
2402
17.4k
  ctxt->vctxt.flags |= XML_VCTXT_DTD_VALIDATED;
2403
17.4k
    }
2404
4.03M
#endif /* LIBXML_VALID_ENABLED */
2405
4.03M
}
2406
2407
/**
2408
 * SAX2 callback when an element end has been detected by the parser.
2409
 * It provides the namespace information for the element.
2410
 *
2411
 * @param ctx  the user data (XML parser context)
2412
 * @param localname  the local name of the element
2413
 * @param prefix  the element namespace prefix if available
2414
 * @param URI  the element namespace name if available
2415
 */
2416
void
2417
xmlSAX2EndElementNs(void *ctx,
2418
                    const xmlChar * localname ATTRIBUTE_UNUSED,
2419
                    const xmlChar * prefix ATTRIBUTE_UNUSED,
2420
        const xmlChar * URI ATTRIBUTE_UNUSED)
2421
1.47M
{
2422
1.47M
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
2423
2424
1.47M
    if (ctx == NULL) return;
2425
1.47M
    ctxt->nodemem = -1;
2426
2427
1.47M
#ifdef LIBXML_VALID_ENABLED
2428
1.47M
    if (ctxt->validate && ctxt->wellFormed &&
2429
45.2k
        ctxt->myDoc && ctxt->myDoc->intSubset)
2430
45.2k
        ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc,
2431
45.2k
                                             ctxt->node);
2432
1.47M
#endif /* LIBXML_VALID_ENABLED */
2433
2434
    /*
2435
     * end of parsing of this node.
2436
     */
2437
1.47M
    nodePop(ctxt);
2438
1.47M
}
2439
2440
/**
2441
 * called when an entity #xmlSAX2Reference is detected.
2442
 *
2443
 * @param ctx  the user data (XML parser context)
2444
 * @param name  The entity name
2445
 */
2446
void
2447
xmlSAX2Reference(void *ctx, const xmlChar *name)
2448
257k
{
2449
257k
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
2450
257k
    xmlNodePtr ret;
2451
2452
257k
    if (ctx == NULL) return;
2453
257k
    ret = xmlNewReference(ctxt->myDoc, name);
2454
257k
    if (ret == NULL) {
2455
73
        xmlSAX2ErrMemory(ctxt);
2456
73
        return;
2457
73
    }
2458
2459
257k
    xmlSAX2AppendChild(ctxt, ret);
2460
257k
}
2461
2462
/**
2463
 * Append characters.
2464
 *
2465
 * @param ctxt  the parser context
2466
 * @param ch  a xmlChar string
2467
 * @param len  the number of xmlChar
2468
 * @param type  text or cdata
2469
 */
2470
static void
2471
xmlSAX2Text(xmlParserCtxtPtr ctxt, const xmlChar *ch, int len,
2472
            xmlElementType type)
2473
23.8M
{
2474
23.8M
    xmlNodePtr lastChild;
2475
23.8M
    xmlNodePtr parent;
2476
2477
23.8M
    if (ctxt == NULL)
2478
0
        return;
2479
2480
23.8M
    parent = ctxt->node;
2481
23.8M
    if (parent == NULL)
2482
1.14M
        return;
2483
22.6M
    lastChild = parent->last;
2484
2485
    /*
2486
     * Try to merge with previous text node using size and capacity
2487
     * stored in the parser context to avoid naive concatenation.
2488
     *
2489
     * Don't merge CDATA sections. In HTML mode, CDATA is used for
2490
     * raw text which should be merged.
2491
     */
2492
22.6M
    if ((lastChild == NULL) ||
2493
21.7M
        (lastChild->type != type) ||
2494
19.8M
        ((!ctxt->html) && (type != XML_TEXT_NODE))) {
2495
2.77M
        xmlNode *node;
2496
2497
2.77M
        if (type == XML_TEXT_NODE)
2498
2.69M
            node = xmlSAX2TextNode(ctxt, parent->doc, ch, len);
2499
85.2k
        else
2500
85.2k
            node = xmlNewCDataBlock(parent->doc, ch, len);
2501
2.77M
  if (node == NULL) {
2502
781
      xmlSAX2ErrMemory(ctxt);
2503
781
      return;
2504
781
  }
2505
2506
2.77M
        if (lastChild == NULL) {
2507
928k
            parent->children = node;
2508
928k
            parent->last = node;
2509
928k
            node->parent = parent;
2510
1.84M
        } else {
2511
1.84M
            xmlSAX2AppendChild(ctxt, node);
2512
1.84M
        }
2513
2514
2.77M
        ctxt->nodelen = len;
2515
2.77M
        ctxt->nodemem = len + 1;
2516
2.77M
        lastChild = node;
2517
19.8M
    } else {
2518
19.8M
        xmlChar *content;
2519
19.8M
        int oldSize, newSize, capacity;
2520
19.8M
        int maxSize = (ctxt->options & XML_PARSE_HUGE) ?
2521
10.4M
                      XML_MAX_HUGE_LENGTH :
2522
19.8M
                      XML_MAX_TEXT_LENGTH;
2523
2524
19.8M
        content = lastChild->content;
2525
19.8M
        oldSize = ctxt->nodelen;
2526
19.8M
        capacity = ctxt->nodemem;
2527
2528
        /* Shouldn't happen */
2529
19.8M
        if ((content == NULL) || (capacity <= 0)) {
2530
0
            xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
2531
0
                        "xmlSAX2Text: no content");
2532
0
            return;
2533
0
        }
2534
2535
19.8M
        if ((len > maxSize) || (oldSize > maxSize - len)) {
2536
68
            xmlFatalErr(ctxt, XML_ERR_RESOURCE_LIMIT,
2537
68
                        "Text node too long, try XML_PARSE_HUGE");
2538
68
            return;
2539
68
        }
2540
2541
19.8M
        newSize = oldSize + len;
2542
2543
19.8M
        if (newSize >= capacity) {
2544
810k
            if (newSize <= 20)
2545
377k
                capacity = 40;
2546
432k
            else
2547
432k
                capacity = newSize > INT_MAX / 2 ? INT_MAX : newSize * 2;
2548
2549
            /*
2550
             * If the content was stored in properties or in
2551
             * the dictionary, don't realloc.
2552
             */
2553
810k
            if ((content == (xmlChar *) &lastChild->properties) ||
2554
704k
                ((ctxt->nodemem == oldSize + 1) &&
2555
508k
                 (xmlDictOwns(ctxt->dict, content)))) {
2556
116k
                xmlChar *newContent;
2557
2558
116k
                newContent = xmlMalloc(capacity);
2559
116k
                if (newContent == NULL) {
2560
40
                    xmlSAX2ErrMemory(ctxt);
2561
40
                    return;
2562
40
                }
2563
2564
116k
                memcpy(newContent, content, oldSize);
2565
116k
                lastChild->properties = NULL;
2566
116k
                content = newContent;
2567
693k
            } else {
2568
693k
                content = xmlRealloc(content, capacity);
2569
693k
                if (content == NULL) {
2570
183
                    xmlSAX2ErrMemory(ctxt);
2571
183
                    return;
2572
183
                }
2573
693k
            }
2574
2575
810k
            ctxt->nodemem = capacity;
2576
810k
            lastChild->content = content;
2577
810k
        }
2578
2579
19.8M
        memcpy(&content[oldSize], ch, len);
2580
19.8M
        content[newSize] = 0;
2581
19.8M
        ctxt->nodelen = newSize;
2582
19.8M
    }
2583
2584
22.6M
    if ((lastChild != NULL) &&
2585
22.6M
        (type == XML_TEXT_NODE) &&
2586
15.3M
        (ctxt->input != NULL)) {
2587
15.3M
        if ((unsigned) ctxt->input->line < (unsigned) USHRT_MAX)
2588
15.0M
            lastChild->line = ctxt->input->line;
2589
259k
        else {
2590
259k
            lastChild->line = USHRT_MAX;
2591
259k
            if (ctxt->options & XML_PARSE_BIG_LINES)
2592
64.2k
                lastChild->psvi = XML_INT_TO_PTR(ctxt->input->line);
2593
259k
        }
2594
15.3M
    }
2595
22.6M
}
2596
2597
/**
2598
 * receiving some chars from the parser.
2599
 *
2600
 * @param ctx  the user data (XML parser context)
2601
 * @param ch  a xmlChar string
2602
 * @param len  the number of xmlChar
2603
 */
2604
void
2605
xmlSAX2Characters(void *ctx, const xmlChar *ch, int len)
2606
16.4M
{
2607
16.4M
    xmlSAX2Text((xmlParserCtxtPtr) ctx, ch, len, XML_TEXT_NODE);
2608
16.4M
}
2609
2610
/**
2611
 * receiving some ignorable whitespaces from the parser.
2612
 * UNUSED: by default the DOM building will use #xmlSAX2Characters
2613
 *
2614
 * @param ctx  the user data (XML parser context)
2615
 * @param ch  a xmlChar string
2616
 * @param len  the number of xmlChar
2617
 */
2618
void
2619
xmlSAX2IgnorableWhitespace(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch ATTRIBUTE_UNUSED, int len ATTRIBUTE_UNUSED)
2620
44.2k
{
2621
44.2k
}
2622
2623
/**
2624
 * A processing instruction has been parsed.
2625
 *
2626
 * @param ctx  the user data (XML parser context)
2627
 * @param target  the target name
2628
 * @param data  the PI data's
2629
 */
2630
void
2631
xmlSAX2ProcessingInstruction(void *ctx, const xmlChar *target,
2632
                      const xmlChar *data)
2633
300k
{
2634
300k
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
2635
300k
    xmlNodePtr ret;
2636
2637
300k
    if (ctx == NULL) return;
2638
2639
300k
    ret = xmlNewDocPI(ctxt->myDoc, target, data);
2640
300k
    if (ret == NULL) {
2641
93
        xmlSAX2ErrMemory(ctxt);
2642
93
        return;
2643
93
    }
2644
2645
300k
    xmlSAX2AppendChild(ctxt, ret);
2646
300k
}
2647
2648
/**
2649
 * A #xmlSAX2Comment has been parsed.
2650
 *
2651
 * @param ctx  the user data (XML parser context)
2652
 * @param value  the #xmlSAX2Comment content
2653
 */
2654
void
2655
xmlSAX2Comment(void *ctx, const xmlChar *value)
2656
2.46M
{
2657
2.46M
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
2658
2.46M
    xmlNodePtr ret;
2659
2660
2.46M
    if (ctx == NULL) return;
2661
2662
2.46M
    ret = xmlNewDocComment(ctxt->myDoc, value);
2663
2.46M
    if (ret == NULL) {
2664
228
        xmlSAX2ErrMemory(ctxt);
2665
228
        return;
2666
228
    }
2667
2668
2.46M
    xmlSAX2AppendChild(ctxt, ret);
2669
2.46M
}
2670
2671
/**
2672
 * called when a pcdata block has been parsed
2673
 *
2674
 * @param ctx  the user data (XML parser context)
2675
 * @param value  The pcdata content
2676
 * @param len  the block length
2677
 */
2678
void
2679
xmlSAX2CDataBlock(void *ctx, const xmlChar *value, int len)
2680
7.35M
{
2681
7.35M
    xmlSAX2Text((xmlParserCtxtPtr) ctx, value, len, XML_CDATA_SECTION_NODE);
2682
7.35M
}
2683
2684
#ifdef LIBXML_SAX1_ENABLED
2685
/**
2686
 * Has no effect.
2687
 *
2688
 * @deprecated Use parser option XML_PARSE_SAX1.
2689
 *
2690
 * @param version  the version, must be 2
2691
 * @returns 2 in case of success and -1 in case of error.
2692
 */
2693
int
2694
xmlSAXDefaultVersion(int version)
2695
0
{
2696
0
    if (version != 2)
2697
0
        return(-1);
2698
0
    return(2);
2699
0
}
2700
#endif /* LIBXML_SAX1_ENABLED */
2701
2702
/**
2703
 * Initialize the default XML SAX handler according to the version
2704
 *
2705
 * @param hdlr  the SAX handler
2706
 * @param version  the version, 1 or 2
2707
 * @returns 0 in case of success and -1 in case of error.
2708
 */
2709
int
2710
xmlSAXVersion(xmlSAXHandler *hdlr, int version)
2711
501k
{
2712
501k
    if (hdlr == NULL) return(-1);
2713
501k
    if (version == 2) {
2714
501k
  hdlr->startElementNs = xmlSAX2StartElementNs;
2715
501k
  hdlr->endElementNs = xmlSAX2EndElementNs;
2716
501k
  hdlr->serror = NULL;
2717
501k
  hdlr->initialized = XML_SAX2_MAGIC;
2718
501k
#ifdef LIBXML_SAX1_ENABLED
2719
501k
    } else if (version == 1) {
2720
0
  hdlr->initialized = 1;
2721
0
#endif /* LIBXML_SAX1_ENABLED */
2722
0
    } else
2723
0
        return(-1);
2724
501k
#ifdef LIBXML_SAX1_ENABLED
2725
501k
    hdlr->startElement = xmlSAX2StartElement;
2726
501k
    hdlr->endElement = xmlSAX2EndElement;
2727
#else
2728
    hdlr->startElement = NULL;
2729
    hdlr->endElement = NULL;
2730
#endif /* LIBXML_SAX1_ENABLED */
2731
501k
    hdlr->internalSubset = xmlSAX2InternalSubset;
2732
501k
    hdlr->externalSubset = xmlSAX2ExternalSubset;
2733
501k
    hdlr->isStandalone = xmlSAX2IsStandalone;
2734
501k
    hdlr->hasInternalSubset = xmlSAX2HasInternalSubset;
2735
501k
    hdlr->hasExternalSubset = xmlSAX2HasExternalSubset;
2736
501k
    hdlr->resolveEntity = xmlSAX2ResolveEntity;
2737
501k
    hdlr->getEntity = xmlSAX2GetEntity;
2738
501k
    hdlr->getParameterEntity = xmlSAX2GetParameterEntity;
2739
501k
    hdlr->entityDecl = xmlSAX2EntityDecl;
2740
501k
    hdlr->attributeDecl = xmlSAX2AttributeDecl;
2741
501k
    hdlr->elementDecl = xmlSAX2ElementDecl;
2742
501k
    hdlr->notationDecl = xmlSAX2NotationDecl;
2743
501k
    hdlr->unparsedEntityDecl = xmlSAX2UnparsedEntityDecl;
2744
501k
    hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator;
2745
501k
    hdlr->startDocument = xmlSAX2StartDocument;
2746
501k
    hdlr->endDocument = xmlSAX2EndDocument;
2747
501k
    hdlr->reference = xmlSAX2Reference;
2748
501k
    hdlr->characters = xmlSAX2Characters;
2749
501k
    hdlr->cdataBlock = xmlSAX2CDataBlock;
2750
501k
    hdlr->ignorableWhitespace = xmlSAX2Characters;
2751
501k
    hdlr->processingInstruction = xmlSAX2ProcessingInstruction;
2752
501k
    hdlr->comment = xmlSAX2Comment;
2753
501k
    hdlr->warning = xmlParserWarning;
2754
501k
    hdlr->error = xmlParserError;
2755
501k
    hdlr->fatalError = xmlParserError;
2756
2757
501k
    return(0);
2758
501k
}
2759
2760
/**
2761
 * Initialize the default XML SAX2 handler
2762
 *
2763
 * @param hdlr  the SAX handler
2764
 * @param warning  flag if non-zero sets the handler warning procedure
2765
 */
2766
void
2767
xmlSAX2InitDefaultSAXHandler(xmlSAXHandler *hdlr, int warning)
2768
0
{
2769
0
    if ((hdlr == NULL) || (hdlr->initialized != 0))
2770
0
  return;
2771
2772
0
    xmlSAXVersion(hdlr, 2);
2773
0
    if (warning == 0)
2774
0
  hdlr->warning = NULL;
2775
0
}
2776
2777
/**
2778
 * Initialize the default SAX2 handler
2779
 *
2780
 * @deprecated This function is a no-op. Call #xmlInitParser to
2781
 * initialize the library.
2782
 *
2783
 */
2784
void
2785
xmlDefaultSAXHandlerInit(void)
2786
0
{
2787
0
}
2788
2789
#ifdef LIBXML_HTML_ENABLED
2790
2791
/**
2792
 * Initialize the default HTML SAX2 handler
2793
 *
2794
 * @param hdlr  the SAX handler
2795
 */
2796
void
2797
xmlSAX2InitHtmlDefaultSAXHandler(xmlSAXHandler *hdlr)
2798
21.3k
{
2799
21.3k
    if ((hdlr == NULL) || (hdlr->initialized != 0))
2800
0
  return;
2801
2802
21.3k
    hdlr->internalSubset = xmlSAX2InternalSubset;
2803
21.3k
    hdlr->externalSubset = NULL;
2804
21.3k
    hdlr->isStandalone = NULL;
2805
21.3k
    hdlr->hasInternalSubset = NULL;
2806
21.3k
    hdlr->hasExternalSubset = NULL;
2807
21.3k
    hdlr->resolveEntity = NULL;
2808
21.3k
    hdlr->getEntity = xmlSAX2GetEntity;
2809
21.3k
    hdlr->getParameterEntity = NULL;
2810
21.3k
    hdlr->entityDecl = NULL;
2811
21.3k
    hdlr->attributeDecl = NULL;
2812
21.3k
    hdlr->elementDecl = NULL;
2813
21.3k
    hdlr->notationDecl = NULL;
2814
21.3k
    hdlr->unparsedEntityDecl = NULL;
2815
21.3k
    hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator;
2816
21.3k
    hdlr->startDocument = xmlSAX2StartDocument;
2817
21.3k
    hdlr->endDocument = xmlSAX2EndDocument;
2818
21.3k
    hdlr->startElement = xmlSAX2StartElement;
2819
21.3k
    hdlr->endElement = xmlSAX2EndElement;
2820
21.3k
    hdlr->reference = NULL;
2821
21.3k
    hdlr->characters = xmlSAX2Characters;
2822
21.3k
    hdlr->cdataBlock = xmlSAX2CDataBlock;
2823
21.3k
    hdlr->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
2824
21.3k
    hdlr->processingInstruction = xmlSAX2ProcessingInstruction;
2825
21.3k
    hdlr->comment = xmlSAX2Comment;
2826
21.3k
    hdlr->warning = xmlParserWarning;
2827
21.3k
    hdlr->error = xmlParserError;
2828
21.3k
    hdlr->fatalError = xmlParserError;
2829
2830
21.3k
    hdlr->initialized = 1;
2831
21.3k
}
2832
2833
/**
2834
 * @deprecated This function is a no-op. Call #xmlInitParser to
2835
 * initialize the library.
2836
 */
2837
void
2838
htmlDefaultSAXHandlerInit(void)
2839
0
{
2840
0
}
2841
2842
#endif /* LIBXML_HTML_ENABLED */