Coverage Report

Created: 2023-05-11 17:19

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