Coverage Report

Created: 2023-03-09 18:04

/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
2.63k
xmlSAX2ErrMemory(xmlParserCtxtPtr ctxt, const char *msg) {
60
2.63k
    xmlStructuredErrorFunc schannel = NULL;
61
2.63k
    const char *str1 = "out of memory\n";
62
63
2.63k
    if (ctxt != NULL) {
64
2.63k
  ctxt->errNo = XML_ERR_NO_MEMORY;
65
2.63k
  if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
66
0
      schannel = ctxt->sax->serror;
67
2.63k
  __xmlRaiseError(schannel,
68
2.63k
      ctxt->vctxt.error, ctxt->vctxt.userData,
69
2.63k
      ctxt, NULL, XML_FROM_PARSER, XML_ERR_NO_MEMORY,
70
2.63k
      XML_ERR_ERROR, NULL, 0, (const char *) str1,
71
2.63k
      NULL, NULL, 0, 0,
72
2.63k
      msg, (const char *) str1, NULL);
73
2.63k
  ctxt->errNo = XML_ERR_NO_MEMORY;
74
2.63k
  ctxt->instate = XML_PARSER_EOF;
75
2.63k
  ctxt->disableSAX = 1;
76
2.63k
    } 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
2.63k
}
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
310k
{
100
310k
    xmlStructuredErrorFunc schannel = NULL;
101
102
310k
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
103
310k
        (ctxt->instate == XML_PARSER_EOF))
104
0
  return;
105
310k
    if (ctxt != NULL) {
106
310k
  ctxt->errNo = error;
107
310k
  if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
108
134k
      schannel = ctxt->sax->serror;
109
310k
  __xmlRaiseError(schannel,
110
310k
      ctxt->vctxt.error, ctxt->vctxt.userData,
111
310k
      ctxt, NULL, XML_FROM_DTD, error,
112
310k
      XML_ERR_ERROR, NULL, 0, (const char *) str1,
113
310k
      (const char *) str2, NULL, 0, 0,
114
310k
      msg, (const char *) str1, (const char *) str2);
115
310k
  ctxt->valid = 0;
116
310k
    } 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
310k
}
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
435
{
140
435
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
141
435
        (ctxt->instate == XML_PARSER_EOF))
142
0
  return;
143
435
    if (ctxt != NULL)
144
435
  ctxt->errNo = error;
145
435
    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
146
435
                    XML_ERR_FATAL, NULL, 0,
147
435
        (const char *) str1, (const char *) str2,
148
435
        NULL, 0, 0, msg, str1, str2);
149
435
    if (ctxt != NULL) {
150
435
  ctxt->wellFormed = 0;
151
435
  ctxt->valid = 0;
152
435
  if (ctxt->recovery == 0)
153
138
      ctxt->disableSAX = 1;
154
435
    }
155
435
}
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.05M
{
171
1.05M
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
172
1.05M
        (ctxt->instate == XML_PARSER_EOF))
173
0
  return;
174
1.05M
    if (ctxt != NULL)
175
1.05M
  ctxt->errNo = error;
176
1.05M
    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
177
1.05M
                    XML_ERR_WARNING, NULL, 0,
178
1.05M
        (const char *) str1, NULL,
179
1.05M
        NULL, 0, 0, msg, str1);
180
1.05M
}
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
1.49M
{
195
1.49M
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
196
1.49M
        (ctxt->instate == XML_PARSER_EOF))
197
1.95k
  return;
198
1.48M
    if (ctxt != NULL)
199
1.48M
  ctxt->errNo = error;
200
1.48M
    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
201
1.48M
                    XML_ERR_WARNING, NULL, 0,
202
1.48M
        (const char *) str1, (const char *) str2,
203
1.48M
        NULL, 0, 0, msg, str1, str2);
204
1.48M
}
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
607k
{
331
607k
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
332
607k
    xmlDtdPtr dtd;
333
607k
    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
607k
    if (ctxt->myDoc == NULL)
341
0
  return;
342
607k
    dtd = xmlGetIntSubset(ctxt->myDoc);
343
607k
    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
607k
    ctxt->myDoc->intSubset =
351
607k
  xmlCreateIntSubset(ctxt->myDoc, name, ExternalID, SystemID);
352
607k
    if (ctxt->myDoc->intSubset == NULL)
353
0
        xmlSAX2ErrMemory(ctxt, "xmlSAX2InternalSubset");
354
607k
}
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
455k
{
369
455k
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
370
455k
    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
455k
    if (((ExternalID != NULL) || (SystemID != NULL)) &&
377
455k
        (((ctxt->validate) || (ctxt->loadsubset != 0)) &&
378
112k
   (ctxt->wellFormed && ctxt->myDoc))) {
379
  /*
380
   * Try to fetch and parse the external subset.
381
   */
382
82.8k
  xmlParserInputPtr oldinput;
383
82.8k
  int oldinputNr;
384
82.8k
  int oldinputMax;
385
82.8k
  xmlParserInputPtr *oldinputTab;
386
82.8k
  xmlParserInputPtr input = NULL;
387
82.8k
  xmlCharEncoding enc;
388
82.8k
  int oldcharset;
389
82.8k
  const xmlChar *oldencoding;
390
391
  /*
392
   * Ask the Entity resolver to load the damn thing
393
   */
394
82.8k
  if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
395
82.8k
      input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID,
396
82.8k
                                          SystemID);
397
82.8k
  if (input == NULL) {
398
47.3k
      return;
399
47.3k
  }
400
401
35.5k
  xmlNewDtd(ctxt->myDoc, name, ExternalID, SystemID);
402
403
  /*
404
   * make sure we won't destroy the main document context
405
   */
406
35.5k
  oldinput = ctxt->input;
407
35.5k
  oldinputNr = ctxt->inputNr;
408
35.5k
  oldinputMax = ctxt->inputMax;
409
35.5k
  oldinputTab = ctxt->inputTab;
410
35.5k
  oldcharset = ctxt->charset;
411
35.5k
  oldencoding = ctxt->encoding;
412
35.5k
  ctxt->encoding = NULL;
413
414
35.5k
  ctxt->inputTab = (xmlParserInputPtr *)
415
35.5k
                   xmlMalloc(5 * sizeof(xmlParserInputPtr));
416
35.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
35.5k
  ctxt->inputNr = 0;
427
35.5k
  ctxt->inputMax = 5;
428
35.5k
  ctxt->input = NULL;
429
35.5k
  xmlPushInput(ctxt, input);
430
431
  /*
432
   * On the fly encoding conversion if needed
433
   */
434
35.5k
  if (ctxt->input->length >= 4) {
435
0
      enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
436
0
      xmlSwitchEncoding(ctxt, enc);
437
0
  }
438
439
35.5k
  if (input->filename == NULL)
440
35.5k
      input->filename = (char *) xmlCanonicPath(SystemID);
441
35.5k
  input->line = 1;
442
35.5k
  input->col = 1;
443
35.5k
  input->base = ctxt->input->cur;
444
35.5k
  input->cur = ctxt->input->cur;
445
35.5k
  input->free = NULL;
446
447
  /*
448
   * let's parse that entity knowing it's an external subset.
449
   */
450
35.5k
  xmlParseExternalSubset(ctxt, ExternalID, SystemID);
451
452
        /*
453
   * Free up the external entities
454
   */
455
456
35.7k
  while (ctxt->inputNr > 1)
457
241
      xmlPopInput(ctxt);
458
35.5k
  xmlFreeInputStream(ctxt->input);
459
35.5k
        xmlFree(ctxt->inputTab);
460
461
  /*
462
   * Restore the parsing context of the main entity
463
   */
464
35.5k
  ctxt->input = oldinput;
465
35.5k
  ctxt->inputNr = oldinputNr;
466
35.5k
  ctxt->inputMax = oldinputMax;
467
35.5k
  ctxt->inputTab = oldinputTab;
468
35.5k
  ctxt->charset = oldcharset;
469
35.5k
  if ((ctxt->encoding != NULL) &&
470
35.5k
      ((ctxt->dict == NULL) ||
471
1.80k
       (!xmlDictOwns(ctxt->dict, ctxt->encoding))))
472
1.80k
      xmlFree((xmlChar *) ctxt->encoding);
473
35.5k
  ctxt->encoding = oldencoding;
474
  /* ctxt->wellFormed = oldwellFormed; */
475
35.5k
    }
476
455k
}
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
82.8k
{
495
82.8k
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
496
82.8k
    xmlParserInputPtr ret;
497
82.8k
    xmlChar *URI;
498
82.8k
    const char *base = NULL;
499
500
82.8k
    if (ctx == NULL) return(NULL);
501
82.8k
    if (ctxt->input != NULL)
502
82.8k
  base = ctxt->input->filename;
503
82.8k
    if (base == NULL)
504
32.9k
  base = ctxt->directory;
505
506
82.8k
    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
82.8k
    ret = xmlLoadExternalEntity((const char *) URI,
514
82.8k
        (const char *) publicId, ctxt);
515
82.8k
    if (URI != NULL)
516
80.8k
  xmlFree(URI);
517
82.8k
    return(ret);
518
82.8k
}
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
10.1M
{
532
10.1M
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
533
10.1M
    xmlEntityPtr ret = NULL;
534
535
10.1M
    if (ctx == NULL) return(NULL);
536
#ifdef DEBUG_SAX
537
    xmlGenericError(xmlGenericErrorContext,
538
      "SAX.xmlSAX2GetEntity(%s)\n", name);
539
#endif
540
541
10.1M
    if (ctxt->inSubset == 0) {
542
9.72M
  ret = xmlGetPredefinedEntity(name);
543
9.72M
  if (ret != NULL)
544
1.09M
      return(ret);
545
9.72M
    }
546
9.01M
    if ((ctxt->myDoc != NULL) && (ctxt->myDoc->standalone == 1)) {
547
31.4k
  if (ctxt->inSubset == 2) {
548
57
      ctxt->myDoc->standalone = 0;
549
57
      ret = xmlGetDocEntity(ctxt->myDoc, name);
550
57
      ctxt->myDoc->standalone = 1;
551
31.4k
  } else {
552
31.4k
      ret = xmlGetDocEntity(ctxt->myDoc, name);
553
31.4k
      if (ret == NULL) {
554
11.5k
    ctxt->myDoc->standalone = 0;
555
11.5k
    ret = xmlGetDocEntity(ctxt->myDoc, name);
556
11.5k
    if (ret != NULL) {
557
7
        xmlFatalErrMsg(ctxt, XML_ERR_NOT_STANDALONE,
558
7
   "Entity(%s) document marked standalone but requires external subset\n",
559
7
           name, NULL);
560
7
    }
561
11.5k
    ctxt->myDoc->standalone = 1;
562
11.5k
      }
563
31.4k
  }
564
8.98M
    } else {
565
8.98M
  ret = xmlGetDocEntity(ctxt->myDoc, name);
566
8.98M
    }
567
9.01M
    return(ret);
568
10.1M
}
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
8.24M
{
582
8.24M
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
583
8.24M
    xmlEntityPtr ret;
584
585
8.24M
    if (ctx == NULL) return(NULL);
586
#ifdef DEBUG_SAX
587
    xmlGenericError(xmlGenericErrorContext,
588
      "SAX.xmlSAX2GetParameterEntity(%s)\n", name);
589
#endif
590
591
8.24M
    ret = xmlGetParameterEntity(ctxt->myDoc, name);
592
8.24M
    return(ret);
593
8.24M
}
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
4.03M
{
611
4.03M
    xmlEntityPtr ent;
612
4.03M
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
613
614
4.03M
    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
4.03M
    if (ctxt->inSubset == 1) {
621
3.99M
  ent = xmlAddDocEntity(ctxt->myDoc, name, type, publicId,
622
3.99M
                  systemId, content);
623
3.99M
  if ((ent == NULL) && (ctxt->pedantic))
624
1.05M
      xmlWarnMsg(ctxt, XML_WAR_ENTITY_REDEFINED,
625
1.05M
       "Entity(%s) already defined in the internal subset\n",
626
1.05M
                 name);
627
3.99M
  if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
628
63.1k
      xmlChar *URI;
629
63.1k
      const char *base = NULL;
630
631
63.1k
      if (ctxt->input != NULL)
632
63.1k
    base = ctxt->input->filename;
633
63.1k
      if (base == NULL)
634
30.6k
    base = ctxt->directory;
635
636
63.1k
      URI = xmlBuildURI(systemId, (const xmlChar *) base);
637
63.1k
      ent->URI = URI;
638
63.1k
  }
639
3.99M
    } else if (ctxt->inSubset == 2) {
640
41.0k
  ent = xmlAddDtdEntity(ctxt->myDoc, name, type, publicId,
641
41.0k
                  systemId, content);
642
41.0k
  if ((ent == NULL) && (ctxt->pedantic) &&
643
41.0k
      (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
644
777
      ctxt->sax->warning(ctxt->userData,
645
777
       "Entity(%s) already defined in the external subset\n", name);
646
41.0k
  if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
647
6.44k
      xmlChar *URI;
648
6.44k
      const char *base = NULL;
649
650
6.44k
      if (ctxt->input != NULL)
651
6.44k
    base = ctxt->input->filename;
652
6.44k
      if (base == NULL)
653
9
    base = ctxt->directory;
654
655
6.44k
      URI = xmlBuildURI(systemId, (const xmlChar *) base);
656
6.44k
      ent->URI = URI;
657
6.44k
  }
658
41.0k
    } 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
4.03M
}
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
4.22M
{
682
4.22M
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
683
4.22M
    xmlAttributePtr attr;
684
4.22M
    xmlChar *name = NULL, *prefix = NULL;
685
686
    /* Avoid unused variable warning if features are disabled. */
687
4.22M
    (void) attr;
688
689
4.22M
    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
4.22M
    if ((xmlStrEqual(fullname, BAD_CAST "xml:id")) &&
698
4.22M
        (type != XML_ATTRIBUTE_ID)) {
699
  /*
700
   * Raise the error but keep the validity flag
701
   */
702
445
  int tmp = ctxt->valid;
703
445
  xmlErrValid(ctxt, XML_DTD_XMLID_TYPE,
704
445
        "xml:id : attribute type should be ID\n", NULL, NULL);
705
445
  ctxt->valid = tmp;
706
445
    }
707
    /* TODO: optimize name/prefix allocation */
708
4.22M
    name = xmlSplitQName(ctxt, fullname, &prefix);
709
4.22M
    ctxt->vctxt.valid = 1;
710
4.22M
    if (ctxt->inSubset == 1)
711
4.18M
  attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, elem,
712
4.18M
         name, prefix, (xmlAttributeType) type,
713
4.18M
         (xmlAttributeDefault) def, defaultValue, tree);
714
37.5k
    else if (ctxt->inSubset == 2)
715
37.5k
  attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, elem,
716
37.5k
     name, prefix, (xmlAttributeType) type,
717
37.5k
     (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
4.22M
#ifdef LIBXML_VALID_ENABLED
727
4.22M
    if (ctxt->vctxt.valid == 0)
728
141k
  ctxt->valid = 0;
729
4.22M
    if ((attr != NULL) && (ctxt->validate) && (ctxt->wellFormed) &&
730
4.22M
        (ctxt->myDoc->intSubset != NULL))
731
315k
  ctxt->valid &= xmlValidateAttributeDecl(&ctxt->vctxt, ctxt->myDoc,
732
315k
                                          attr);
733
4.22M
#endif /* LIBXML_VALID_ENABLED */
734
4.22M
    if (prefix != NULL)
735
208k
  xmlFree(prefix);
736
4.22M
    if (name != NULL)
737
4.22M
  xmlFree(name);
738
4.22M
}
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
2.15M
{
753
2.15M
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
754
2.15M
    xmlElementPtr elem = NULL;
755
756
    /* Avoid unused variable warning if features are disabled. */
757
2.15M
    (void) elem;
758
759
2.15M
    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
2.15M
    if (ctxt->inSubset == 1)
768
2.09M
        elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->intSubset,
769
2.09M
                                 name, (xmlElementTypeVal) type, content);
770
56.9k
    else if (ctxt->inSubset == 2)
771
56.9k
        elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->extSubset,
772
56.9k
                                 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
2.15M
#ifdef LIBXML_VALID_ENABLED
780
2.15M
    if (elem == NULL)
781
1.46M
        ctxt->valid = 0;
782
2.15M
    if (ctxt->validate && ctxt->wellFormed &&
783
2.15M
        ctxt->myDoc && ctxt->myDoc->intSubset)
784
345k
        ctxt->valid &=
785
345k
            xmlValidateElementDecl(&ctxt->vctxt, ctxt->myDoc, elem);
786
2.15M
#endif /* LIBXML_VALID_ENABLED */
787
2.15M
}
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
6.41k
{
802
6.41k
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
803
6.41k
    xmlNotationPtr nota = NULL;
804
805
    /* Avoid unused variable warning if features are disabled. */
806
6.41k
    (void) nota;
807
808
6.41k
    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
6.41k
    if ((publicId == NULL) && (systemId == NULL)) {
817
428
  xmlFatalErrMsg(ctxt, XML_ERR_NOTATION_PROCESSING,
818
428
       "SAX.xmlSAX2NotationDecl(%s) externalID or PublicID missing\n",
819
428
                 name, NULL);
820
428
  return;
821
5.98k
    } else if (ctxt->inSubset == 1)
822
5.72k
  nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name,
823
5.72k
                              publicId, systemId);
824
261
    else if (ctxt->inSubset == 2)
825
261
  nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, name,
826
261
                              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
5.98k
#ifdef LIBXML_VALID_ENABLED
834
5.98k
    if (nota == NULL) ctxt->valid = 0;
835
5.98k
    if ((ctxt->validate) && (ctxt->wellFormed) &&
836
5.98k
        (ctxt->myDoc->intSubset != NULL))
837
1.79k
  ctxt->valid &= xmlValidateNotationDecl(&ctxt->vctxt, ctxt->myDoc,
838
1.79k
                                         nota);
839
5.98k
#endif /* LIBXML_VALID_ENABLED */
840
5.98k
}
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
19.0k
{
857
19.0k
    xmlEntityPtr ent;
858
19.0k
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
859
19.0k
    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
19.0k
    if (ctxt->inSubset == 1) {
866
18.5k
  ent = xmlAddDocEntity(ctxt->myDoc, name,
867
18.5k
      XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
868
18.5k
      publicId, systemId, notationName);
869
18.5k
  if ((ent == NULL) && (ctxt->pedantic) &&
870
18.5k
      (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
871
3.50k
      ctxt->sax->warning(ctxt->userData,
872
3.50k
       "Entity(%s) already defined in the internal subset\n", name);
873
18.5k
  if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
874
6.84k
      xmlChar *URI;
875
6.84k
      const char *base = NULL;
876
877
6.84k
      if (ctxt->input != NULL)
878
6.84k
    base = ctxt->input->filename;
879
6.84k
      if (base == NULL)
880
3.85k
    base = ctxt->directory;
881
882
6.84k
      URI = xmlBuildURI(systemId, (const xmlChar *) base);
883
6.84k
      ent->URI = URI;
884
6.84k
  }
885
18.5k
    } else if (ctxt->inSubset == 2) {
886
522
  ent = xmlAddDtdEntity(ctxt->myDoc, name,
887
522
      XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
888
522
      publicId, systemId, notationName);
889
522
  if ((ent == NULL) && (ctxt->pedantic) &&
890
522
      (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
891
64
      ctxt->sax->warning(ctxt->userData,
892
64
       "Entity(%s) already defined in the external subset\n", name);
893
522
  if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
894
306
      xmlChar *URI;
895
306
      const char *base = NULL;
896
897
306
      if (ctxt->input != NULL)
898
306
    base = ctxt->input->filename;
899
306
      if (base == NULL)
900
0
    base = ctxt->directory;
901
902
306
      URI = xmlBuildURI(systemId, (const xmlChar *) base);
903
306
      ent->URI = URI;
904
306
  }
905
522
    } 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
19.0k
}
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
1.20M
{
923
    /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
924
#ifdef DEBUG_SAX
925
    xmlGenericError(xmlGenericErrorContext,
926
      "SAX.xmlSAX2SetDocumentLocator()\n");
927
#endif
928
1.20M
}
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
1.15M
{
939
1.15M
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
940
1.15M
    xmlDocPtr doc;
941
942
1.15M
    if (ctx == NULL) return;
943
944
#ifdef DEBUG_SAX
945
    xmlGenericError(xmlGenericErrorContext,
946
      "SAX.xmlSAX2StartDocument()\n");
947
#endif
948
1.15M
    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
1.15M
    } else {
967
1.15M
  doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
968
1.15M
  if (doc != NULL) {
969
1.15M
      doc->properties = 0;
970
1.15M
      if (ctxt->options & XML_PARSE_OLD10)
971
444k
          doc->properties |= XML_DOC_OLD10;
972
1.15M
      doc->parseFlags = ctxt->options;
973
1.15M
      if (ctxt->encoding != NULL)
974
65.2k
    doc->encoding = xmlStrdup(ctxt->encoding);
975
1.09M
      else
976
1.09M
    doc->encoding = NULL;
977
1.15M
      doc->standalone = ctxt->standalone;
978
1.15M
  } else {
979
0
      xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument");
980
0
      return;
981
0
  }
982
1.15M
  if ((ctxt->dictNames) && (doc != NULL)) {
983
677k
      doc->dict = ctxt->dict;
984
677k
      xmlDictReference(doc->dict);
985
677k
  }
986
1.15M
    }
987
1.15M
    if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
988
1.15M
  (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
989
588k
  ctxt->myDoc->URL = xmlPathToURI((const xmlChar *)ctxt->input->filename);
990
588k
  if (ctxt->myDoc->URL == NULL)
991
0
      xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument");
992
588k
    }
993
1.15M
}
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
832k
{
1004
832k
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1005
#ifdef DEBUG_SAX
1006
    xmlGenericError(xmlGenericErrorContext,
1007
      "SAX.xmlSAX2EndDocument()\n");
1008
#endif
1009
832k
    if (ctx == NULL) return;
1010
832k
#ifdef LIBXML_VALID_ENABLED
1011
832k
    if (ctxt->validate && ctxt->wellFormed &&
1012
832k
        ctxt->myDoc && ctxt->myDoc->intSubset)
1013
51.9k
  ctxt->valid &= xmlValidateDocumentFinal(&ctxt->vctxt, ctxt->myDoc);
1014
832k
#endif /* LIBXML_VALID_ENABLED */
1015
1016
    /*
1017
     * Grab the encoding if it was added on-the-fly
1018
     */
1019
832k
    if ((ctxt->encoding != NULL) && (ctxt->myDoc != NULL) &&
1020
832k
  (ctxt->myDoc->encoding == NULL)) {
1021
46
  ctxt->myDoc->encoding = ctxt->encoding;
1022
46
  ctxt->encoding = NULL;
1023
46
    }
1024
832k
    if ((ctxt->inputTab != NULL) &&
1025
832k
        (ctxt->inputNr > 0) && (ctxt->inputTab[0] != NULL) &&
1026
832k
        (ctxt->inputTab[0]->encoding != NULL) && (ctxt->myDoc != NULL) &&
1027
832k
  (ctxt->myDoc->encoding == NULL)) {
1028
18.3k
  ctxt->myDoc->encoding = xmlStrdup(ctxt->inputTab[0]->encoding);
1029
18.3k
    }
1030
832k
    if ((ctxt->charset != XML_CHAR_ENCODING_NONE) && (ctxt->myDoc != NULL) &&
1031
832k
  (ctxt->myDoc->charset == XML_CHAR_ENCODING_NONE)) {
1032
0
  ctxt->myDoc->charset = ctxt->charset;
1033
0
    }
1034
832k
}
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
272k
{
1051
272k
    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
1052
272k
        (ctxt->instate == XML_PARSER_EOF))
1053
6
  return;
1054
272k
    if (ctxt != NULL)
1055
272k
  ctxt->errNo = error;
1056
272k
    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
1057
272k
                    XML_ERR_ERROR, NULL, 0,
1058
272k
        (const char *) str1, (const char *) str2,
1059
272k
        NULL, 0, 0, msg, str1, str2);
1060
272k
}
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
5.43M
{
1078
5.43M
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1079
5.43M
    xmlAttrPtr ret;
1080
5.43M
    xmlChar *name;
1081
5.43M
    xmlChar *ns;
1082
5.43M
    xmlChar *nval;
1083
5.43M
    xmlNsPtr namespace;
1084
1085
5.43M
    if (ctxt->html) {
1086
0
  name = xmlStrdup(fullname);
1087
0
  ns = NULL;
1088
0
  namespace = NULL;
1089
5.43M
    } else {
1090
  /*
1091
   * Split the full name into a namespace prefix and the tag name
1092
   */
1093
5.43M
  name = xmlSplitQName(ctxt, fullname, &ns);
1094
5.43M
  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
5.43M
    }
1111
5.43M
    if (name == NULL) {
1112
0
        xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
1113
0
  if (ns != NULL)
1114
0
      xmlFree(ns);
1115
0
  return;
1116
0
    }
1117
1118
5.43M
#ifdef LIBXML_HTML_ENABLED
1119
5.43M
    if ((ctxt->html) &&
1120
5.43M
        (value == NULL) && (htmlIsBooleanAttr(fullname))) {
1121
0
            nval = xmlStrdup(fullname);
1122
0
            value = (const xmlChar *) nval;
1123
0
    } else
1124
5.43M
#endif
1125
5.43M
    {
1126
5.43M
#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
5.43M
        ctxt->vctxt.valid = 1;
1133
5.43M
        nval = xmlValidCtxtNormalizeAttributeValue(&ctxt->vctxt,
1134
5.43M
                                               ctxt->myDoc, ctxt->node,
1135
5.43M
                                               fullname, value);
1136
5.43M
        if (ctxt->vctxt.valid != 1) {
1137
1.03k
            ctxt->valid = 0;
1138
1.03k
        }
1139
5.43M
        if (nval != NULL)
1140
374k
            value = nval;
1141
#else
1142
        nval = NULL;
1143
#endif /* LIBXML_VALID_ENABLED */
1144
5.43M
    }
1145
1146
    /*
1147
     * Check whether it's a namespace definition
1148
     */
1149
5.43M
    if ((!ctxt->html) && (ns == NULL) &&
1150
5.43M
        (name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') &&
1151
5.43M
        (name[3] == 'n') && (name[4] == 's') && (name[5] == 0)) {
1152
259k
  xmlNsPtr nsret;
1153
259k
  xmlChar *val;
1154
1155
        /* Avoid unused variable warning if features are disabled. */
1156
259k
        (void) nsret;
1157
1158
259k
        if (!ctxt->replaceEntities) {
1159
196k
      ctxt->depth++;
1160
196k
      val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
1161
196k
                              0,0,0);
1162
196k
      ctxt->depth--;
1163
196k
      if (val == NULL) {
1164
299
          xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
1165
299
    if (name != NULL)
1166
299
        xmlFree(name);
1167
299
                if (nval != NULL)
1168
0
                    xmlFree(nval);
1169
299
    return;
1170
299
      }
1171
196k
  } else {
1172
63.7k
      val = (xmlChar *) value;
1173
63.7k
  }
1174
1175
259k
  if (val[0] != 0) {
1176
258k
      xmlURIPtr uri;
1177
1178
258k
      uri = xmlParseURI((const char *)val);
1179
258k
      if (uri == NULL) {
1180
125k
    if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
1181
59.2k
        ctxt->sax->warning(ctxt->userData,
1182
59.2k
       "xmlns: %s not a valid URI\n", val);
1183
132k
      } else {
1184
132k
    if (uri->scheme == NULL) {
1185
97.1k
        if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
1186
51.0k
      ctxt->sax->warning(ctxt->userData,
1187
51.0k
           "xmlns: URI %s is not absolute\n", val);
1188
97.1k
    }
1189
132k
    xmlFreeURI(uri);
1190
132k
      }
1191
258k
  }
1192
1193
  /* a default namespace definition */
1194
259k
  nsret = xmlNewNs(ctxt->node, val, NULL);
1195
1196
259k
#ifdef LIBXML_VALID_ENABLED
1197
  /*
1198
   * Validate also for namespace decls, they are attributes from
1199
   * an XML-1.0 perspective
1200
   */
1201
259k
        if (nsret != NULL && ctxt->validate && ctxt->wellFormed &&
1202
259k
      ctxt->myDoc && ctxt->myDoc->intSubset)
1203
7.06k
      ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
1204
7.06k
             ctxt->node, prefix, nsret, val);
1205
259k
#endif /* LIBXML_VALID_ENABLED */
1206
259k
  if (name != NULL)
1207
259k
      xmlFree(name);
1208
259k
  if (nval != NULL)
1209
0
      xmlFree(nval);
1210
259k
  if (val != value)
1211
195k
      xmlFree(val);
1212
259k
  return;
1213
259k
    }
1214
5.17M
    if ((!ctxt->html) &&
1215
5.17M
  (ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') &&
1216
5.17M
        (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) {
1217
1.52M
  xmlNsPtr nsret;
1218
1.52M
  xmlChar *val;
1219
1220
        /* Avoid unused variable warning if features are disabled. */
1221
1.52M
        (void) nsret;
1222
1223
1.52M
        if (!ctxt->replaceEntities) {
1224
1.14M
      ctxt->depth++;
1225
1.14M
      val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
1226
1.14M
                              0,0,0);
1227
1.14M
      ctxt->depth--;
1228
1.14M
      if (val == NULL) {
1229
2.34k
          xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
1230
2.34k
          xmlFree(ns);
1231
2.34k
    if (name != NULL)
1232
2.34k
        xmlFree(name);
1233
2.34k
                if (nval != NULL)
1234
0
                    xmlFree(nval);
1235
2.34k
    return;
1236
2.34k
      }
1237
1.14M
  } else {
1238
372k
      val = (xmlChar *) value;
1239
372k
  }
1240
1241
1.52M
  if (val[0] == 0) {
1242
6.84k
      xmlNsErrMsg(ctxt, XML_NS_ERR_EMPTY,
1243
6.84k
            "Empty namespace name for prefix %s\n", name, NULL);
1244
6.84k
  }
1245
1.52M
  if ((ctxt->pedantic != 0) && (val[0] != 0)) {
1246
299k
      xmlURIPtr uri;
1247
1248
299k
      uri = xmlParseURI((const char *)val);
1249
299k
      if (uri == NULL) {
1250
28.6k
          xmlNsWarnMsg(ctxt, XML_WAR_NS_URI,
1251
28.6k
       "xmlns:%s: %s not a valid URI\n", name, value);
1252
270k
      } else {
1253
270k
    if (uri->scheme == NULL) {
1254
28.8k
        xmlNsWarnMsg(ctxt, XML_WAR_NS_URI_RELATIVE,
1255
28.8k
         "xmlns:%s: URI %s is not absolute\n", name, value);
1256
28.8k
    }
1257
270k
    xmlFreeURI(uri);
1258
270k
      }
1259
299k
  }
1260
1261
  /* a standard namespace definition */
1262
1.52M
  nsret = xmlNewNs(ctxt->node, val, name);
1263
1.52M
  xmlFree(ns);
1264
1.52M
#ifdef LIBXML_VALID_ENABLED
1265
  /*
1266
   * Validate also for namespace decls, they are attributes from
1267
   * an XML-1.0 perspective
1268
   */
1269
1.52M
        if (nsret != NULL && ctxt->validate && ctxt->wellFormed &&
1270
1.52M
      ctxt->myDoc && ctxt->myDoc->intSubset)
1271
539k
      ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
1272
539k
             ctxt->node, prefix, nsret, value);
1273
1.52M
#endif /* LIBXML_VALID_ENABLED */
1274
1.52M
  if (name != NULL)
1275
1.52M
      xmlFree(name);
1276
1.52M
  if (nval != NULL)
1277
12.6k
      xmlFree(nval);
1278
1.52M
  if (val != value)
1279
1.14M
      xmlFree(val);
1280
1.52M
  return;
1281
1.52M
    }
1282
1283
3.65M
    if (ns != NULL) {
1284
586k
  namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, ns);
1285
1286
586k
  if (namespace == NULL) {
1287
265k
      xmlNsErrMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
1288
265k
        "Namespace prefix %s of attribute %s is not defined\n",
1289
265k
                 ns, name);
1290
321k
  } else {
1291
321k
            xmlAttrPtr prop;
1292
1293
321k
            prop = ctxt->node->properties;
1294
366k
            while (prop != NULL) {
1295
45.2k
                if (prop->ns != NULL) {
1296
17.5k
                    if ((xmlStrEqual(name, prop->name)) &&
1297
17.5k
                        ((namespace == prop->ns) ||
1298
419
                         (xmlStrEqual(namespace->href, prop->ns->href)))) {
1299
230
                            xmlNsErrMsg(ctxt, XML_ERR_ATTRIBUTE_REDEFINED,
1300
230
                                    "Attribute %s in %s redefined\n",
1301
230
                                             name, namespace->href);
1302
230
                        ctxt->wellFormed = 0;
1303
230
                        if (ctxt->recovery == 0) ctxt->disableSAX = 1;
1304
230
                        if (name != NULL)
1305
230
                            xmlFree(name);
1306
230
                        goto error;
1307
230
                    }
1308
17.5k
                }
1309
45.0k
                prop = prop->next;
1310
45.0k
            }
1311
321k
        }
1312
3.06M
    } else {
1313
3.06M
  namespace = NULL;
1314
3.06M
    }
1315
1316
    /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */
1317
3.65M
    ret = xmlNewNsPropEatName(ctxt->node, namespace, name, NULL);
1318
1319
3.65M
    if (ret != NULL) {
1320
3.65M
        if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
1321
2.37M
      xmlNodePtr tmp;
1322
1323
2.37M
      ret->children = xmlStringGetNodeList(ctxt->myDoc, value);
1324
2.37M
      tmp = ret->children;
1325
4.81M
      while (tmp != NULL) {
1326
2.44M
    tmp->parent = (xmlNodePtr) ret;
1327
2.44M
    if (tmp->next == NULL)
1328
2.33M
        ret->last = tmp;
1329
2.44M
    tmp = tmp->next;
1330
2.44M
      }
1331
2.37M
  } else if (value != NULL) {
1332
1.28M
      ret->children = xmlNewDocText(ctxt->myDoc, value);
1333
1.28M
      ret->last = ret->children;
1334
1.28M
      if (ret->children != NULL)
1335
1.28M
    ret->children->parent = (xmlNodePtr) ret;
1336
1.28M
  }
1337
3.65M
    }
1338
1339
3.65M
#ifdef LIBXML_VALID_ENABLED
1340
3.65M
    if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
1341
3.65M
        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
813k
        if (!ctxt->replaceEntities) {
1348
671k
      xmlChar *val;
1349
1350
671k
      ctxt->depth++;
1351
671k
      val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
1352
671k
                              0,0,0);
1353
671k
      ctxt->depth--;
1354
1355
671k
      if (val == NULL)
1356
2.55k
    ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
1357
2.55k
        ctxt->myDoc, ctxt->node, ret, value);
1358
669k
      else {
1359
669k
    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
669k
    nvalnorm = xmlValidNormalizeAttributeValue(ctxt->myDoc,
1367
669k
              ctxt->node, fullname, val);
1368
669k
    if (nvalnorm != NULL) {
1369
34.1k
        xmlFree(val);
1370
34.1k
        val = nvalnorm;
1371
34.1k
    }
1372
1373
669k
    ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
1374
669k
              ctxt->myDoc, ctxt->node, ret, val);
1375
669k
                xmlFree(val);
1376
669k
      }
1377
671k
  } else {
1378
142k
      ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc,
1379
142k
                 ctxt->node, ret, value);
1380
142k
  }
1381
813k
    } else
1382
2.83M
#endif /* LIBXML_VALID_ENABLED */
1383
2.83M
           if (((ctxt->loadsubset & XML_SKIP_IDS) == 0) &&
1384
2.83M
         (((ctxt->replaceEntities == 0) && (ctxt->external != 2)) ||
1385
2.76M
          ((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0))) &&
1386
               /* Don't create IDs containing entity references */
1387
2.83M
               (ret->children != NULL) &&
1388
2.83M
               (ret->children->type == XML_TEXT_NODE) &&
1389
2.83M
               (ret->children->next == NULL)) {
1390
2.70M
        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
2.70M
  if (xmlStrEqual(fullname, BAD_CAST "xml:id")) {
1396
      /*
1397
       * Add the xml:id value
1398
       *
1399
       * Open issue: normalization of the value.
1400
       */
1401
153k
      if (xmlValidateNCName(content, 1) != 0) {
1402
48.7k
          xmlErrValid(ctxt, XML_DTD_XMLID_VALUE,
1403
48.7k
          "xml:id : attribute value %s is not an NCName\n",
1404
48.7k
          (const char *) content, NULL);
1405
48.7k
      }
1406
153k
      xmlAddID(&ctxt->vctxt, ctxt->myDoc, content, ret);
1407
2.55M
  } else if (xmlIsID(ctxt->myDoc, ctxt->node, ret))
1408
204k
      xmlAddID(&ctxt->vctxt, ctxt->myDoc, content, ret);
1409
2.34M
  else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret))
1410
7.70k
      xmlAddRef(&ctxt->vctxt, ctxt->myDoc, content, ret);
1411
2.70M
    }
1412
1413
3.65M
error:
1414
3.65M
    if (nval != NULL)
1415
361k
  xmlFree(nval);
1416
3.65M
    if (ns != NULL)
1417
586k
  xmlFree(ns);
1418
3.65M
}
1419
1420
/*
1421
 * xmlCheckDefaultedAttributes:
1422
 *
1423
 * Check defaulted attributes from the DTD
1424
 */
1425
static void
1426
xmlCheckDefaultedAttributes(xmlParserCtxtPtr ctxt, const xmlChar *name,
1427
6.24M
  const xmlChar *prefix, const xmlChar **atts) {
1428
6.24M
    xmlElementPtr elemDecl;
1429
6.24M
    const xmlChar *att;
1430
6.24M
    int internal = 1;
1431
6.24M
    int i;
1432
1433
6.24M
    elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->intSubset, name, prefix);
1434
6.24M
    if (elemDecl == NULL) {
1435
5.52M
  elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->extSubset, name, prefix);
1436
5.52M
  internal = 0;
1437
5.52M
    }
1438
1439
6.96M
process_external_subset:
1440
1441
6.96M
    if (elemDecl != NULL) {
1442
748k
  xmlAttributePtr attr = elemDecl->attributes;
1443
  /*
1444
   * Check against defaulted attributes from the external subset
1445
   * if the document is stamped as standalone
1446
   */
1447
748k
  if ((ctxt->myDoc->standalone == 1) &&
1448
748k
      (ctxt->myDoc->extSubset != NULL) &&
1449
748k
      (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
748k
  attr = elemDecl->attributes;
1503
1.41M
  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
662k
      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
176k
    if (((attr->prefix != NULL) &&
1519
176k
         (xmlStrEqual(attr->prefix, BAD_CAST "xmlns"))) ||
1520
176k
        ((attr->prefix == NULL) &&
1521
128k
         (xmlStrEqual(attr->name, BAD_CAST "xmlns"))) ||
1522
176k
        (ctxt->loadsubset & XML_COMPLETE_ATTRS)) {
1523
144k
        xmlAttributePtr tst;
1524
1525
144k
        tst = xmlGetDtdQAttrDesc(ctxt->myDoc->intSubset,
1526
144k
               attr->elem, attr->name,
1527
144k
               attr->prefix);
1528
144k
        if ((tst == attr) || (tst == NULL)) {
1529
144k
            xmlChar fn[50];
1530
144k
      xmlChar *fulln;
1531
1532
144k
                        fulln = xmlBuildQName(attr->name, attr->prefix, fn, 50);
1533
144k
      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
144k
      att = NULL;
1543
144k
      if (atts != NULL) {
1544
73.0k
          i = 0;
1545
73.0k
          att = atts[i];
1546
142k
          while (att != NULL) {
1547
75.9k
        if (xmlStrEqual(att, fulln))
1548
6.09k
            break;
1549
69.8k
        i += 2;
1550
69.8k
        att = atts[i];
1551
69.8k
          }
1552
73.0k
      }
1553
144k
      if (att == NULL) {
1554
137k
          xmlSAX2AttributeInternal(ctxt, fulln,
1555
137k
             attr->defaultValue, prefix);
1556
137k
      }
1557
144k
      if ((fulln != fn) && (fulln != attr->name))
1558
27.5k
          xmlFree(fulln);
1559
144k
        }
1560
144k
    }
1561
176k
      }
1562
662k
      attr = attr->nexth;
1563
662k
  }
1564
748k
  if (internal == 1) {
1565
724k
      elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->extSubset,
1566
724k
                                 name, prefix);
1567
724k
      internal = 0;
1568
724k
      goto process_external_subset;
1569
724k
  }
1570
748k
    }
1571
6.96M
}
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
9.03M
{
1584
9.03M
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1585
9.03M
    xmlNodePtr ret;
1586
9.03M
    xmlNodePtr parent;
1587
9.03M
    xmlNsPtr ns;
1588
9.03M
    xmlChar *name;
1589
9.03M
    xmlChar *prefix;
1590
9.03M
    const xmlChar *att;
1591
9.03M
    const xmlChar *value;
1592
9.03M
    int i;
1593
1594
9.03M
    if ((ctx == NULL) || (fullname == NULL) || (ctxt->myDoc == NULL)) return;
1595
9.03M
    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
9.03M
    if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) &&
1605
9.03M
        ((ctxt->myDoc->intSubset == NULL) ||
1606
3.27M
   ((ctxt->myDoc->intSubset->notations == NULL) &&
1607
3.15M
    (ctxt->myDoc->intSubset->elements == NULL) &&
1608
3.15M
    (ctxt->myDoc->intSubset->attributes == NULL) &&
1609
3.15M
    (ctxt->myDoc->intSubset->entities == NULL)))) {
1610
126k
  xmlErrValid(ctxt, XML_ERR_NO_DTD,
1611
126k
    "Validation failed: no DTD found !", NULL, NULL);
1612
126k
  ctxt->validate = 0;
1613
126k
    }
1614
1615
1616
    /*
1617
     * Split the full name into a namespace prefix and the tag name
1618
     */
1619
9.03M
    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
9.03M
    ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL, name, NULL);
1628
9.03M
    if (ret == NULL) {
1629
0
        if (prefix != NULL)
1630
0
      xmlFree(prefix);
1631
0
  xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
1632
0
        return;
1633
0
    }
1634
9.03M
    if (ctxt->myDoc->children == NULL) {
1635
#ifdef DEBUG_SAX_TREE
1636
  xmlGenericError(xmlGenericErrorContext, "Setting %s as root\n", name);
1637
#endif
1638
201k
        xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
1639
8.83M
    } else if (parent == NULL) {
1640
212k
        parent = ctxt->myDoc->children;
1641
212k
    }
1642
9.03M
    ctxt->nodemem = -1;
1643
9.03M
    if (ctxt->linenumbers) {
1644
7.72M
  if (ctxt->input != NULL) {
1645
7.72M
      if ((unsigned) ctxt->input->line < (unsigned) USHRT_MAX)
1646
7.71M
    ret->line = ctxt->input->line;
1647
7.20k
      else
1648
7.20k
          ret->line = USHRT_MAX;
1649
7.72M
  }
1650
7.72M
    }
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
9.03M
    if (nodePush(ctxt, ret) < 0) {
1659
79
        xmlUnlinkNode(ret);
1660
79
        xmlFreeNode(ret);
1661
79
        if (prefix != NULL)
1662
38
            xmlFree(prefix);
1663
79
        return;
1664
79
    }
1665
1666
    /*
1667
     * Link the child element
1668
     */
1669
9.03M
    if (parent != NULL) {
1670
8.83M
        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
8.66M
      xmlAddChild(parent, ret);
1676
8.66M
  } else {
1677
#ifdef DEBUG_SAX_TREE
1678
      xmlGenericError(xmlGenericErrorContext,
1679
        "adding sibling %s to ", name);
1680
      xmlDebugDumpOneNode(stderr, parent, 0);
1681
#endif
1682
170k
      xmlAddSibling(parent, ret);
1683
170k
  }
1684
8.83M
    }
1685
1686
9.03M
    if (!ctxt->html) {
1687
        /*
1688
         * Insert all the defaulted attributes from the DTD especially
1689
         * namespaces
1690
         */
1691
9.03M
        if ((ctxt->myDoc->intSubset != NULL) ||
1692
9.03M
            (ctxt->myDoc->extSubset != NULL)) {
1693
6.24M
            xmlCheckDefaultedAttributes(ctxt, name, prefix, atts);
1694
6.24M
        }
1695
1696
        /*
1697
         * process all the attributes whose name start with "xmlns"
1698
         */
1699
9.03M
        if (atts != NULL) {
1700
4.19M
            i = 0;
1701
4.19M
            att = atts[i++];
1702
4.19M
            value = atts[i++];
1703
9.49M
      while ((att != NULL) && (value != NULL)) {
1704
5.29M
    if ((att[0] == 'x') && (att[1] == 'm') && (att[2] == 'l') &&
1705
5.29M
        (att[3] == 'n') && (att[4] == 's'))
1706
1.75M
        xmlSAX2AttributeInternal(ctxt, att, value, prefix);
1707
1708
5.29M
    att = atts[i++];
1709
5.29M
    value = atts[i++];
1710
5.29M
      }
1711
4.19M
        }
1712
1713
        /*
1714
         * Search the namespace, note that since the attributes have been
1715
         * processed, the local namespaces are available.
1716
         */
1717
9.03M
        ns = xmlSearchNs(ctxt->myDoc, ret, prefix);
1718
9.03M
        if ((ns == NULL) && (parent != NULL))
1719
6.11M
            ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
1720
9.03M
        if ((prefix != NULL) && (ns == NULL)) {
1721
1.26M
            ns = xmlNewNs(ret, NULL, prefix);
1722
1.26M
            xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
1723
1.26M
                         "Namespace prefix %s is not defined\n",
1724
1.26M
                         prefix, NULL);
1725
1.26M
        }
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
9.03M
        if ((ns != NULL) && (ns->href != NULL) &&
1732
9.03M
            ((ns->href[0] != 0) || (ns->prefix != NULL)))
1733
2.73M
            xmlSetNs(ret, ns);
1734
9.03M
    }
1735
1736
    /*
1737
     * process all the other attributes
1738
     */
1739
9.03M
    if (atts != NULL) {
1740
4.19M
        i = 0;
1741
4.19M
  att = atts[i++];
1742
4.19M
  value = atts[i++];
1743
4.19M
  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
4.19M
  } else {
1750
9.49M
      while ((att != NULL) && (value != NULL)) {
1751
5.29M
    if ((att[0] != 'x') || (att[1] != 'm') || (att[2] != 'l') ||
1752
5.29M
        (att[3] != 'n') || (att[4] != 's'))
1753
3.54M
        xmlSAX2AttributeInternal(ctxt, att, value, NULL);
1754
1755
    /*
1756
     * Next ones
1757
     */
1758
5.29M
    att = atts[i++];
1759
5.29M
    value = atts[i++];
1760
5.29M
      }
1761
4.19M
  }
1762
4.19M
    }
1763
1764
9.03M
#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
9.03M
    if ((ctxt->validate) &&
1770
9.03M
        ((ctxt->vctxt.flags & XML_VCTXT_DTD_VALIDATED) == 0)) {
1771
1.08M
  int chk;
1772
1773
1.08M
  chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
1774
1.08M
  if (chk <= 0)
1775
8.82k
      ctxt->valid = 0;
1776
1.08M
  if (chk < 0)
1777
0
      ctxt->wellFormed = 0;
1778
1.08M
  ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
1779
1.08M
  ctxt->vctxt.flags |= XML_VCTXT_DTD_VALIDATED;
1780
1.08M
    }
1781
9.03M
#endif /* LIBXML_VALID_ENABLED */
1782
1783
9.03M
    if (prefix != NULL)
1784
3.54M
  xmlFree(prefix);
1785
1786
9.03M
}
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
4.01M
{
1798
4.01M
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
1799
4.01M
    xmlNodePtr cur;
1800
1801
4.01M
    if (ctx == NULL) return;
1802
4.01M
    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
4.01M
    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
4.01M
    ctxt->nodemem = -1;
1818
1819
4.01M
#ifdef LIBXML_VALID_ENABLED
1820
4.01M
    if (ctxt->validate && ctxt->wellFormed &&
1821
4.01M
        ctxt->myDoc && ctxt->myDoc->intSubset)
1822
942k
        ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc,
1823
942k
               cur);
1824
4.01M
#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
4.01M
    nodePop(ctxt);
1834
4.01M
}
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
19.3M
xmlSAX2TextNode(xmlParserCtxtPtr ctxt, const xmlChar *str, int len) {
1849
19.3M
    xmlNodePtr ret;
1850
19.3M
    const xmlChar *intern = NULL;
1851
1852
    /*
1853
     * Allocate
1854
     */
1855
19.3M
    if (ctxt->freeElems != NULL) {
1856
22.7k
  ret = ctxt->freeElems;
1857
22.7k
  ctxt->freeElems = ret->next;
1858
22.7k
  ctxt->freeElemsNr--;
1859
19.3M
    } else {
1860
19.3M
  ret = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
1861
19.3M
    }
1862
19.3M
    if (ret == NULL) {
1863
0
        xmlErrMemory(ctxt, "xmlSAX2Characters");
1864
0
  return(NULL);
1865
0
    }
1866
19.3M
    memset(ret, 0, sizeof(xmlNode));
1867
    /*
1868
     * intern the formatting blanks found between tags, or the
1869
     * very short strings
1870
     */
1871
19.3M
    if (ctxt->dictNames) {
1872
11.0M
        xmlChar cur = str[len];
1873
1874
11.0M
  if ((len < (int) (2 * sizeof(void *))) &&
1875
11.0M
      (ctxt->options & XML_PARSE_COMPACT)) {
1876
      /* store the string in the node overriding properties and nsDef */
1877
4.84M
      xmlChar *tmp = (xmlChar *) &(ret->properties);
1878
4.84M
      memcpy(tmp, str, len);
1879
4.84M
      tmp[len] = 0;
1880
4.84M
      intern = tmp;
1881
6.20M
  } else if ((len <= 3) && ((cur == '"') || (cur == '\'') ||
1882
1.44M
      ((cur == '<') && (str[len + 1] != '!')))) {
1883
1.06M
      intern = xmlDictLookup(ctxt->dict, str, len);
1884
5.13M
  } else if (IS_BLANK_CH(*str) && (len < 60) && (cur == '<') &&
1885
5.13M
             (str[len + 1] != '!')) {
1886
1.30M
      int i;
1887
1888
8.82M
      for (i = 1;i < len;i++) {
1889
7.79M
    if (!IS_BLANK_CH(str[i])) goto skip;
1890
7.79M
      }
1891
1.03M
      intern = xmlDictLookup(ctxt->dict, str, len);
1892
1.03M
  }
1893
11.0M
    }
1894
19.3M
skip:
1895
19.3M
    ret->type = XML_TEXT_NODE;
1896
1897
19.3M
    ret->name = xmlStringText;
1898
19.3M
    if (intern == NULL) {
1899
12.4M
  ret->content = xmlStrndup(str, len);
1900
12.4M
  if (ret->content == NULL) {
1901
0
      xmlSAX2ErrMemory(ctxt, "xmlSAX2TextNode");
1902
0
      xmlFree(ret);
1903
0
      return(NULL);
1904
0
  }
1905
12.4M
    } else
1906
6.94M
  ret->content = (xmlChar *) intern;
1907
1908
19.3M
    if (ctxt->linenumbers) {
1909
15.0M
  if (ctxt->input != NULL) {
1910
15.0M
      if ((unsigned) ctxt->input->line < (unsigned) USHRT_MAX)
1911
14.9M
    ret->line = ctxt->input->line;
1912
15.1k
      else {
1913
15.1k
          ret->line = USHRT_MAX;
1914
15.1k
    if (ctxt->options & XML_PARSE_BIG_LINES)
1915
5.99k
        ret->psvi = (void *) (ptrdiff_t) ctxt->input->line;
1916
15.1k
      }
1917
15.0M
  }
1918
15.0M
    }
1919
1920
19.3M
    if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
1921
0
  xmlRegisterNodeDefaultValue(ret);
1922
19.3M
    return(ret);
1923
19.3M
}
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
447k
                          const xmlChar *end) {
1939
447k
    const xmlChar *in;
1940
447k
    xmlChar *ret;
1941
1942
447k
    in = str;
1943
19.4M
    while (in < end)
1944
19.0M
        if (*in++ == '&')
1945
32.0k
      goto decode;
1946
415k
    return(NULL);
1947
32.0k
decode:
1948
32.0k
    ctxt->depth++;
1949
32.0k
    ret = xmlStringLenDecodeEntities(ctxt, str, end - str,
1950
32.0k
             XML_SUBSTITUTE_REF, 0,0,0);
1951
32.0k
    ctxt->depth--;
1952
32.0k
    return(ret);
1953
447k
}
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
3.76M
{
1977
3.76M
    xmlAttrPtr ret;
1978
3.76M
    xmlNsPtr namespace = NULL;
1979
3.76M
    xmlChar *dup = NULL;
1980
1981
    /*
1982
     * Note: if prefix == NULL, the attribute is not in the default namespace
1983
     */
1984
3.76M
    if (prefix != NULL)
1985
340k
  namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, prefix);
1986
1987
    /*
1988
     * allocate the node
1989
     */
1990
3.76M
    if (ctxt->freeAttrs != NULL) {
1991
22.6k
        ret = ctxt->freeAttrs;
1992
22.6k
  ctxt->freeAttrs = ret->next;
1993
22.6k
  ctxt->freeAttrsNr--;
1994
22.6k
  memset(ret, 0, sizeof(xmlAttr));
1995
22.6k
  ret->type = XML_ATTRIBUTE_NODE;
1996
1997
22.6k
  ret->parent = ctxt->node;
1998
22.6k
  ret->doc = ctxt->myDoc;
1999
22.6k
  ret->ns = namespace;
2000
2001
22.6k
  if (ctxt->dictNames)
2002
17.4k
      ret->name = localname;
2003
5.25k
  else
2004
5.25k
      ret->name = xmlStrdup(localname);
2005
2006
        /* link at the end to preserve order, TODO speed up with a last */
2007
22.6k
  if (ctxt->node->properties == NULL) {
2008
22.6k
      ctxt->node->properties = ret;
2009
22.6k
  } 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
22.6k
  if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
2018
0
      xmlRegisterNodeDefaultValue((xmlNodePtr)ret);
2019
3.74M
    } else {
2020
3.74M
  if (ctxt->dictNames)
2021
2.37M
      ret = xmlNewNsPropEatName(ctxt->node, namespace,
2022
2.37M
                                (xmlChar *) localname, NULL);
2023
1.36M
  else
2024
1.36M
      ret = xmlNewNsProp(ctxt->node, namespace, localname, NULL);
2025
3.74M
  if (ret == NULL) {
2026
0
      xmlErrMemory(ctxt, "xmlSAX2AttributeNs");
2027
0
      return;
2028
0
  }
2029
3.74M
    }
2030
2031
3.76M
    if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
2032
1.97M
  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
1.97M
  if (*valueend != 0) {
2040
1.42M
      tmp = xmlSAX2TextNode(ctxt, value, valueend - value);
2041
1.42M
      ret->children = tmp;
2042
1.42M
      ret->last = tmp;
2043
1.42M
      if (tmp != NULL) {
2044
1.42M
    tmp->doc = ret->doc;
2045
1.42M
    tmp->parent = (xmlNodePtr) ret;
2046
1.42M
      }
2047
1.42M
  } else {
2048
541k
      ret->children = xmlStringLenGetNodeList(ctxt->myDoc, value,
2049
541k
                valueend - value);
2050
541k
      tmp = ret->children;
2051
1.23M
      while (tmp != NULL) {
2052
694k
          tmp->doc = ret->doc;
2053
694k
    tmp->parent = (xmlNodePtr) ret;
2054
694k
    if (tmp->next == NULL)
2055
541k
        ret->last = tmp;
2056
694k
    tmp = tmp->next;
2057
694k
      }
2058
541k
  }
2059
1.97M
    } else if (value != NULL) {
2060
1.79M
  xmlNodePtr tmp;
2061
2062
1.79M
  tmp = xmlSAX2TextNode(ctxt, value, valueend - value);
2063
1.79M
  ret->children = tmp;
2064
1.79M
  ret->last = tmp;
2065
1.79M
  if (tmp != NULL) {
2066
1.79M
      tmp->doc = ret->doc;
2067
1.79M
      tmp->parent = (xmlNodePtr) ret;
2068
1.79M
  }
2069
1.79M
    }
2070
2071
3.76M
#ifdef LIBXML_VALID_ENABLED
2072
3.76M
    if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
2073
3.76M
        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
539k
        if (!ctxt->replaceEntities) {
2079
447k
      dup = xmlSAX2DecodeAttrEntities(ctxt, value, valueend);
2080
447k
      if (dup == NULL) {
2081
415k
          if (*valueend == 0) {
2082
70.3k
        ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
2083
70.3k
            ctxt->myDoc, ctxt->node, ret, value);
2084
345k
    } 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
345k
        dup = xmlStrndup(value, valueend - value);
2091
2092
345k
        ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
2093
345k
            ctxt->myDoc, ctxt->node, ret, dup);
2094
345k
    }
2095
415k
      } 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
31.8k
    if (ctxt->attsSpecial != NULL) {
2104
8.29k
        xmlChar *nvalnorm;
2105
8.29k
        xmlChar fn[50];
2106
8.29k
        xmlChar *fullname;
2107
2108
8.29k
        fullname = xmlBuildQName(localname, prefix, fn, 50);
2109
8.29k
        if (fullname != NULL) {
2110
8.29k
      ctxt->vctxt.valid = 1;
2111
8.29k
            nvalnorm = xmlValidCtxtNormalizeAttributeValue(
2112
8.29k
                       &ctxt->vctxt, ctxt->myDoc,
2113
8.29k
           ctxt->node, fullname, dup);
2114
8.29k
      if (ctxt->vctxt.valid != 1)
2115
0
          ctxt->valid = 0;
2116
2117
8.29k
      if ((fullname != fn) && (fullname != localname))
2118
0
          xmlFree(fullname);
2119
8.29k
      if (nvalnorm != NULL) {
2120
3.66k
          xmlFree(dup);
2121
3.66k
          dup = nvalnorm;
2122
3.66k
      }
2123
8.29k
        }
2124
8.29k
    }
2125
2126
31.8k
    ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
2127
31.8k
              ctxt->myDoc, ctxt->node, ret, dup);
2128
31.8k
      }
2129
447k
  } else {
2130
      /*
2131
       * if entities already have been substituted, then
2132
       * the attribute as passed is already normalized
2133
       */
2134
91.7k
      dup = xmlStrndup(value, valueend - value);
2135
2136
91.7k
      ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
2137
91.7k
                               ctxt->myDoc, ctxt->node, ret, dup);
2138
91.7k
  }
2139
539k
    } else
2140
3.22M
#endif /* LIBXML_VALID_ENABLED */
2141
3.22M
           if (((ctxt->loadsubset & XML_SKIP_IDS) == 0) &&
2142
3.22M
         (((ctxt->replaceEntities == 0) && (ctxt->external != 2)) ||
2143
3.06M
          ((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0))) &&
2144
               /* Don't create IDs containing entity references */
2145
3.22M
               (ret->children != NULL) &&
2146
3.22M
               (ret->children->type == XML_TEXT_NODE) &&
2147
3.22M
               (ret->children->next == NULL)) {
2148
3.04M
        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
3.04M
        if ((prefix == ctxt->str_xml) &&
2154
3.04M
             (localname[0] == 'i') && (localname[1] == 'd') &&
2155
3.04M
       (localname[2] == 0)) {
2156
      /*
2157
       * Add the xml:id value
2158
       *
2159
       * Open issue: normalization of the value.
2160
       */
2161
165k
#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
2162
165k
#ifdef LIBXML_VALID_ENABLED
2163
165k
      if (xmlValidateNCName(content, 1) != 0) {
2164
61.7k
          xmlErrValid(ctxt, XML_DTD_XMLID_VALUE,
2165
61.7k
          "xml:id : attribute value %s is not an NCName\n",
2166
61.7k
          (const char *) content, NULL);
2167
61.7k
      }
2168
165k
#endif
2169
165k
#endif
2170
165k
      xmlAddID(&ctxt->vctxt, ctxt->myDoc, content, ret);
2171
2.87M
  } else if (xmlIsID(ctxt->myDoc, ctxt->node, ret)) {
2172
103k
      xmlAddID(&ctxt->vctxt, ctxt->myDoc, content, ret);
2173
2.77M
  } else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret)) {
2174
12.1k
      xmlAddRef(&ctxt->vctxt, ctxt->myDoc, content, ret);
2175
12.1k
  }
2176
3.04M
    }
2177
3.76M
    if (dup != NULL)
2178
468k
  xmlFree(dup);
2179
3.76M
}
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
8.57M
{
2209
8.57M
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
2210
8.57M
    xmlNodePtr ret;
2211
8.57M
    xmlNodePtr parent;
2212
8.57M
    xmlNsPtr last = NULL, ns;
2213
8.57M
    const xmlChar *uri, *pref;
2214
8.57M
    xmlChar *lname = NULL;
2215
8.57M
    int i, j;
2216
2217
8.57M
    if (ctx == NULL) return;
2218
8.57M
    parent = ctxt->node;
2219
    /*
2220
     * First check on validity:
2221
     */
2222
8.57M
    if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) &&
2223
8.57M
        ((ctxt->myDoc->intSubset == NULL) ||
2224
1.74M
   ((ctxt->myDoc->intSubset->notations == NULL) &&
2225
1.68M
    (ctxt->myDoc->intSubset->elements == NULL) &&
2226
1.68M
    (ctxt->myDoc->intSubset->attributes == NULL) &&
2227
1.68M
    (ctxt->myDoc->intSubset->entities == NULL)))) {
2228
72.8k
  xmlErrValid(ctxt, XML_DTD_NO_DTD,
2229
72.8k
    "Validation failed: no DTD found !", NULL, NULL);
2230
72.8k
  ctxt->validate = 0;
2231
72.8k
    }
2232
2233
    /*
2234
     * Take care of the rare case of an undefined namespace prefix
2235
     */
2236
8.57M
    if ((prefix != NULL) && (URI == NULL)) {
2237
1.52M
        if (ctxt->dictNames) {
2238
923k
      const xmlChar *fullname;
2239
2240
923k
      fullname = xmlDictQLookup(ctxt->dict, prefix, localname);
2241
923k
      if (fullname != NULL)
2242
923k
          localname = fullname;
2243
923k
  } else {
2244
598k
      lname = xmlBuildQName(localname, prefix, NULL, 0);
2245
598k
  }
2246
1.52M
    }
2247
    /*
2248
     * allocate the node
2249
     */
2250
8.57M
    if (ctxt->freeElems != NULL) {
2251
19.9k
        ret = ctxt->freeElems;
2252
19.9k
  ctxt->freeElems = ret->next;
2253
19.9k
  ctxt->freeElemsNr--;
2254
19.9k
  memset(ret, 0, sizeof(xmlNode));
2255
19.9k
        ret->doc = ctxt->myDoc;
2256
19.9k
  ret->type = XML_ELEMENT_NODE;
2257
2258
19.9k
  if (ctxt->dictNames)
2259
14.5k
      ret->name = localname;
2260
5.36k
  else {
2261
5.36k
      if (lname == NULL)
2262
4.87k
    ret->name = xmlStrdup(localname);
2263
484
      else
2264
484
          ret->name = lname;
2265
5.36k
      if (ret->name == NULL) {
2266
0
          xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
2267
0
    return;
2268
0
      }
2269
5.36k
  }
2270
19.9k
  if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
2271
0
      xmlRegisterNodeDefaultValue(ret);
2272
8.55M
    } else {
2273
8.55M
  if (ctxt->dictNames)
2274
5.12M
      ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL,
2275
5.12M
                                 (xmlChar *) localname, NULL);
2276
3.42M
  else if (lname == NULL)
2277
2.82M
      ret = xmlNewDocNode(ctxt->myDoc, NULL, localname, NULL);
2278
597k
  else
2279
597k
      ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL,
2280
597k
                                 (xmlChar *) lname, NULL);
2281
8.55M
  if (ret == NULL) {
2282
0
      xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
2283
0
      return;
2284
0
  }
2285
8.55M
    }
2286
8.57M
    if (ctxt->linenumbers) {
2287
7.20M
  if (ctxt->input != NULL) {
2288
7.20M
      if ((unsigned) ctxt->input->line < (unsigned) USHRT_MAX)
2289
7.19M
    ret->line = ctxt->input->line;
2290
4.79k
      else
2291
4.79k
          ret->line = USHRT_MAX;
2292
7.20M
  }
2293
7.20M
    }
2294
2295
8.57M
    if (parent == NULL) {
2296
432k
        xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
2297
432k
    }
2298
    /*
2299
     * Build the namespace list
2300
     */
2301
9.53M
    for (i = 0,j = 0;j < nb_namespaces;j++) {
2302
959k
        pref = namespaces[i++];
2303
959k
  uri = namespaces[i++];
2304
959k
  ns = xmlNewNs(NULL, uri, pref);
2305
959k
  if (ns != NULL) {
2306
959k
      if (last == NULL) {
2307
878k
          ret->nsDef = last = ns;
2308
878k
      } else {
2309
81.7k
          last->next = ns;
2310
81.7k
    last = ns;
2311
81.7k
      }
2312
959k
      if ((URI != NULL) && (prefix == pref))
2313
502k
    ret->ns = ns;
2314
959k
  } 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
959k
#ifdef LIBXML_VALID_ENABLED
2323
959k
  if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
2324
959k
      ctxt->myDoc && ctxt->myDoc->intSubset) {
2325
103k
      ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
2326
103k
                                             ret, prefix, ns, uri);
2327
103k
  }
2328
959k
#endif /* LIBXML_VALID_ENABLED */
2329
959k
    }
2330
8.57M
    ctxt->nodemem = -1;
2331
2332
    /*
2333
     * We are parsing a new node.
2334
     */
2335
8.57M
    if (nodePush(ctxt, ret) < 0) {
2336
81
        xmlUnlinkNode(ret);
2337
81
        xmlFreeNode(ret);
2338
81
        return;
2339
81
    }
2340
2341
    /*
2342
     * Link the child element
2343
     */
2344
8.57M
    if (parent != NULL) {
2345
8.13M
        if (parent->type == XML_ELEMENT_NODE) {
2346
8.13M
      xmlAddChild(parent, ret);
2347
8.13M
  } else {
2348
0
      xmlAddSibling(parent, ret);
2349
0
  }
2350
8.13M
    }
2351
2352
    /*
2353
     * Insert the defaulted attributes from the DTD only if requested:
2354
     */
2355
8.57M
    if ((nb_defaulted != 0) &&
2356
8.57M
        ((ctxt->loadsubset & XML_COMPLETE_ATTRS) == 0))
2357
21.2k
  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
8.57M
    if ((URI != NULL) && (ret->ns == NULL)) {
2364
1.49M
        ret->ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
2365
1.49M
  if ((ret->ns == NULL) && (xmlStrEqual(prefix, BAD_CAST "xml"))) {
2366
392
      ret->ns = xmlSearchNs(ctxt->myDoc, ret, prefix);
2367
392
  }
2368
1.49M
  if (ret->ns == NULL) {
2369
170k
      ns = xmlNewNs(ret, NULL, prefix);
2370
170k
      if (ns == NULL) {
2371
2372
0
          xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
2373
0
    return;
2374
0
      }
2375
170k
            if (prefix != NULL)
2376
44.6k
                xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
2377
44.6k
                             "Namespace prefix %s was not found\n",
2378
44.6k
                             prefix, NULL);
2379
125k
            else
2380
125k
                xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
2381
125k
                             "Namespace default prefix was not found\n",
2382
125k
                             NULL, NULL);
2383
170k
  }
2384
1.49M
    }
2385
2386
    /*
2387
     * process all the other attributes
2388
     */
2389
8.57M
    if (nb_attributes > 0) {
2390
6.72M
        for (j = 0,i = 0;i < nb_attributes;i++,j+=5) {
2391
      /*
2392
       * Handle the rare case of an undefined attribute prefix
2393
       */
2394
3.76M
      if ((attributes[j+1] != NULL) && (attributes[j+2] == NULL)) {
2395
200k
    if (ctxt->dictNames) {
2396
149k
        const xmlChar *fullname;
2397
2398
149k
        fullname = xmlDictQLookup(ctxt->dict, attributes[j+1],
2399
149k
                                  attributes[j]);
2400
149k
        if (fullname != NULL) {
2401
149k
      xmlSAX2AttributeNs(ctxt, fullname, NULL,
2402
149k
                         attributes[j+3], attributes[j+4]);
2403
149k
            continue;
2404
149k
        }
2405
149k
    } else {
2406
50.4k
        lname = xmlBuildQName(attributes[j], attributes[j+1],
2407
50.4k
                              NULL, 0);
2408
50.4k
        if (lname != NULL) {
2409
50.4k
      xmlSAX2AttributeNs(ctxt, lname, NULL,
2410
50.4k
                         attributes[j+3], attributes[j+4]);
2411
50.4k
      xmlFree(lname);
2412
50.4k
            continue;
2413
50.4k
        }
2414
50.4k
    }
2415
200k
      }
2416
3.56M
      xmlSAX2AttributeNs(ctxt, attributes[j], attributes[j+1],
2417
3.56M
             attributes[j+3], attributes[j+4]);
2418
3.56M
  }
2419
2.96M
    }
2420
2421
8.57M
#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
8.57M
    if ((ctxt->validate) &&
2427
8.57M
        ((ctxt->vctxt.flags & XML_VCTXT_DTD_VALIDATED) == 0)) {
2428
357k
  int chk;
2429
2430
357k
  chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
2431
357k
  if (chk <= 0)
2432
5.85k
      ctxt->valid = 0;
2433
357k
  if (chk < 0)
2434
0
      ctxt->wellFormed = 0;
2435
357k
  ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
2436
357k
  ctxt->vctxt.flags |= XML_VCTXT_DTD_VALIDATED;
2437
357k
    }
2438
8.57M
#endif /* LIBXML_VALID_ENABLED */
2439
8.57M
}
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
3.90M
{
2457
3.90M
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
2458
3.90M
    xmlParserNodeInfo node_info;
2459
3.90M
    xmlNodePtr cur;
2460
2461
3.90M
    if (ctx == NULL) return;
2462
3.90M
    cur = ctxt->node;
2463
    /* Capture end position and add node */
2464
3.90M
    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
3.90M
    ctxt->nodemem = -1;
2471
2472
3.90M
#ifdef LIBXML_VALID_ENABLED
2473
3.90M
    if (ctxt->validate && ctxt->wellFormed &&
2474
3.90M
        ctxt->myDoc && ctxt->myDoc->intSubset)
2475
513k
        ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc, cur);
2476
3.90M
#endif /* LIBXML_VALID_ENABLED */
2477
2478
    /*
2479
     * end of parsing of this node.
2480
     */
2481
3.90M
    nodePop(ctxt);
2482
3.90M
}
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
437k
{
2494
437k
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
2495
437k
    xmlNodePtr ret;
2496
2497
437k
    if (ctx == NULL) return;
2498
#ifdef DEBUG_SAX
2499
    xmlGenericError(xmlGenericErrorContext,
2500
      "SAX.xmlSAX2Reference(%s)\n", name);
2501
#endif
2502
437k
    if (name[0] == '#')
2503
18.0k
  ret = xmlNewCharRef(ctxt->myDoc, name);
2504
419k
    else
2505
419k
  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
437k
    if (xmlAddChild(ctxt->node, ret) == NULL) {
2511
14.0k
        xmlFreeNode(ret);
2512
14.0k
    }
2513
437k
}
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
42.5M
{
2528
42.5M
    xmlNodePtr lastChild;
2529
2530
42.5M
    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
42.5M
    if (ctxt->node == NULL) {
2542
#ifdef DEBUG_SAX_TREE
2543
  xmlGenericError(xmlGenericErrorContext,
2544
    "add chars: ctxt->node == NULL !\n");
2545
#endif
2546
8.59M
        return;
2547
8.59M
    }
2548
33.9M
    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
33.9M
    if (lastChild == NULL) {
2559
6.27M
        if (type == XML_TEXT_NODE)
2560
6.24M
            lastChild = xmlSAX2TextNode(ctxt, ch, len);
2561
23.6k
        else
2562
23.6k
            lastChild = xmlNewCDataBlock(ctxt->myDoc, ch, len);
2563
6.27M
  if (lastChild != NULL) {
2564
6.27M
      ctxt->node->children = lastChild;
2565
6.27M
      ctxt->node->last = lastChild;
2566
6.27M
      lastChild->parent = ctxt->node;
2567
6.27M
      lastChild->doc = ctxt->node->doc;
2568
6.27M
      ctxt->nodelen = len;
2569
6.27M
      ctxt->nodemem = len + 1;
2570
6.27M
  } else {
2571
0
      xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters");
2572
0
      return;
2573
0
  }
2574
27.6M
    } else {
2575
27.6M
  int coalesceText = (lastChild != NULL) &&
2576
27.6M
      (lastChild->type == type) &&
2577
27.6M
      ((type != XML_TEXT_NODE) ||
2578
17.6M
             (lastChild->name == xmlStringText));
2579
27.6M
  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
17.5M
      if (lastChild->content == (xmlChar *)&(lastChild->properties)) {
2588
648k
    lastChild->content = xmlStrdup(lastChild->content);
2589
648k
    lastChild->properties = NULL;
2590
16.9M
      } else if ((ctxt->nodemem == ctxt->nodelen + 1) &&
2591
16.9M
                 (xmlDictOwns(ctxt->dict, lastChild->content))) {
2592
19.0k
    lastChild->content = xmlStrdup(lastChild->content);
2593
19.0k
      }
2594
17.5M
      if (lastChild->content == NULL) {
2595
0
    xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters: xmlStrdup returned NULL");
2596
0
    return;
2597
0
      }
2598
17.5M
      if (ctxt->nodelen > INT_MAX - len) {
2599
0
                xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters overflow prevented");
2600
0
                return;
2601
0
      }
2602
17.5M
            if ((ctxt->nodelen + len > XML_MAX_TEXT_LENGTH) &&
2603
17.5M
                ((ctxt->options & XML_PARSE_HUGE) == 0)) {
2604
0
                xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters: huge text node");
2605
0
                return;
2606
0
            }
2607
17.5M
      if (ctxt->nodelen + len >= ctxt->nodemem) {
2608
5.24M
    xmlChar *newbuf;
2609
5.24M
    int size;
2610
2611
5.24M
    size = ctxt->nodemem > INT_MAX - len ?
2612
0
                       INT_MAX :
2613
5.24M
                       ctxt->nodemem + len;
2614
5.24M
    size = size > INT_MAX / 2 ? INT_MAX : size * 2;
2615
5.24M
                newbuf = (xmlChar *) xmlRealloc(lastChild->content,size);
2616
5.24M
    if (newbuf == NULL) {
2617
0
        xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters");
2618
0
        return;
2619
0
    }
2620
5.24M
    ctxt->nodemem = size;
2621
5.24M
    lastChild->content = newbuf;
2622
5.24M
      }
2623
17.5M
      memcpy(&lastChild->content[ctxt->nodelen], ch, len);
2624
17.5M
      ctxt->nodelen += len;
2625
17.5M
      lastChild->content[ctxt->nodelen] = 0;
2626
17.5M
  } else if (coalesceText) {
2627
100k
      if (xmlTextConcat(lastChild, ch, len)) {
2628
0
    xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters");
2629
0
      }
2630
100k
      if (ctxt->node->children != NULL) {
2631
100k
    ctxt->nodelen = xmlStrlen(lastChild->content);
2632
100k
    ctxt->nodemem = ctxt->nodelen + 1;
2633
100k
      }
2634
9.98M
  } else {
2635
      /* Mixed content, first time */
2636
9.98M
            if (type == XML_TEXT_NODE) {
2637
9.90M
                lastChild = xmlSAX2TextNode(ctxt, ch, len);
2638
9.90M
                lastChild->doc = ctxt->myDoc;
2639
9.90M
            } else
2640
80.5k
                lastChild = xmlNewCDataBlock(ctxt->myDoc, ch, len);
2641
9.98M
      if (lastChild != NULL) {
2642
9.98M
    xmlAddChild(ctxt->node, lastChild);
2643
9.98M
    if (ctxt->node->children != NULL) {
2644
9.98M
        ctxt->nodelen = len;
2645
9.98M
        ctxt->nodemem = len + 1;
2646
9.98M
    }
2647
9.98M
      }
2648
9.98M
  }
2649
27.6M
    }
2650
33.9M
}
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
42.3M
{
2663
42.3M
    xmlSAX2Text((xmlParserCtxtPtr) ctx, ch, len, XML_TEXT_NODE);
2664
42.3M
}
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.39M
{
2678
    /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
2679
#ifdef DEBUG_SAX
2680
    xmlGenericError(xmlGenericErrorContext,
2681
      "SAX.xmlSAX2IgnorableWhitespace(%.30s, %d)\n", ch, len);
2682
#endif
2683
3.39M
}
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
829k
{
2697
829k
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
2698
829k
    xmlNodePtr ret;
2699
829k
    xmlNodePtr parent;
2700
2701
829k
    if (ctx == NULL) return;
2702
829k
    parent = ctxt->node;
2703
#ifdef DEBUG_SAX
2704
    xmlGenericError(xmlGenericErrorContext,
2705
      "SAX.xmlSAX2ProcessingInstruction(%s, %s)\n", target, data);
2706
#endif
2707
2708
829k
    ret = xmlNewDocPI(ctxt->myDoc, target, data);
2709
829k
    if (ret == NULL) return;
2710
2711
829k
    if (ctxt->linenumbers) {
2712
316k
  if (ctxt->input != NULL) {
2713
316k
      if ((unsigned) ctxt->input->line < (unsigned) USHRT_MAX)
2714
316k
    ret->line = ctxt->input->line;
2715
360
      else
2716
360
          ret->line = USHRT_MAX;
2717
316k
  }
2718
316k
    }
2719
829k
    if (ctxt->inSubset == 1) {
2720
30.4k
  xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
2721
30.4k
  return;
2722
798k
    } else if (ctxt->inSubset == 2) {
2723
2.53k
  xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
2724
2.53k
  return;
2725
2.53k
    }
2726
796k
    if (parent == NULL) {
2727
#ifdef DEBUG_SAX_TREE
2728
      xmlGenericError(xmlGenericErrorContext,
2729
        "Setting PI %s as root\n", target);
2730
#endif
2731
101k
        xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
2732
101k
  return;
2733
101k
    }
2734
694k
    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
694k
  xmlAddChild(parent, ret);
2740
694k
    } 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
694k
}
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
1.24M
{
2760
1.24M
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
2761
1.24M
    xmlNodePtr ret;
2762
1.24M
    xmlNodePtr parent;
2763
2764
1.24M
    if (ctx == NULL) return;
2765
1.24M
    parent = ctxt->node;
2766
#ifdef DEBUG_SAX
2767
    xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2Comment(%s)\n", value);
2768
#endif
2769
1.24M
    ret = xmlNewDocComment(ctxt->myDoc, value);
2770
1.24M
    if (ret == NULL) return;
2771
1.24M
    if (ctxt->linenumbers) {
2772
1.17M
  if (ctxt->input != NULL) {
2773
1.17M
      if ((unsigned) ctxt->input->line < (unsigned) USHRT_MAX)
2774
1.17M
    ret->line = ctxt->input->line;
2775
2.09k
      else
2776
2.09k
          ret->line = USHRT_MAX;
2777
1.17M
  }
2778
1.17M
    }
2779
2780
1.24M
    if (ctxt->inSubset == 1) {
2781
531k
  xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
2782
531k
  return;
2783
711k
    } else if (ctxt->inSubset == 2) {
2784
23.9k
  xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
2785
23.9k
  return;
2786
23.9k
    }
2787
687k
    if (parent == NULL) {
2788
#ifdef DEBUG_SAX_TREE
2789
      xmlGenericError(xmlGenericErrorContext,
2790
        "Setting xmlSAX2Comment as root\n");
2791
#endif
2792
56.4k
        xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
2793
56.4k
  return;
2794
56.4k
    }
2795
631k
    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
631k
  xmlAddChild(parent, ret);
2801
631k
    } 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
631k
}
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
140k
{
2822
140k
    xmlSAX2Text((xmlParserCtxtPtr) ctx, value, len, XML_CDATA_SECTION_NODE);
2823
140k
}
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
3.02M
{
2866
3.02M
    if (hdlr == NULL) return(-1);
2867
3.02M
    if (version == 2) {
2868
3.01M
  hdlr->startElement = NULL;
2869
3.01M
  hdlr->endElement = NULL;
2870
3.01M
  hdlr->startElementNs = xmlSAX2StartElementNs;
2871
3.01M
  hdlr->endElementNs = xmlSAX2EndElementNs;
2872
3.01M
  hdlr->serror = NULL;
2873
3.01M
  hdlr->initialized = XML_SAX2_MAGIC;
2874
3.01M
#ifdef LIBXML_SAX1_ENABLED
2875
3.01M
    } else if (version == 1) {
2876
3.79k
  hdlr->startElement = xmlSAX2StartElement;
2877
3.79k
  hdlr->endElement = xmlSAX2EndElement;
2878
3.79k
  hdlr->initialized = 1;
2879
3.79k
#endif /* LIBXML_SAX1_ENABLED */
2880
3.79k
    } else
2881
0
        return(-1);
2882
3.02M
    hdlr->internalSubset = xmlSAX2InternalSubset;
2883
3.02M
    hdlr->externalSubset = xmlSAX2ExternalSubset;
2884
3.02M
    hdlr->isStandalone = xmlSAX2IsStandalone;
2885
3.02M
    hdlr->hasInternalSubset = xmlSAX2HasInternalSubset;
2886
3.02M
    hdlr->hasExternalSubset = xmlSAX2HasExternalSubset;
2887
3.02M
    hdlr->resolveEntity = xmlSAX2ResolveEntity;
2888
3.02M
    hdlr->getEntity = xmlSAX2GetEntity;
2889
3.02M
    hdlr->getParameterEntity = xmlSAX2GetParameterEntity;
2890
3.02M
    hdlr->entityDecl = xmlSAX2EntityDecl;
2891
3.02M
    hdlr->attributeDecl = xmlSAX2AttributeDecl;
2892
3.02M
    hdlr->elementDecl = xmlSAX2ElementDecl;
2893
3.02M
    hdlr->notationDecl = xmlSAX2NotationDecl;
2894
3.02M
    hdlr->unparsedEntityDecl = xmlSAX2UnparsedEntityDecl;
2895
3.02M
    hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator;
2896
3.02M
    hdlr->startDocument = xmlSAX2StartDocument;
2897
3.02M
    hdlr->endDocument = xmlSAX2EndDocument;
2898
3.02M
    hdlr->reference = xmlSAX2Reference;
2899
3.02M
    hdlr->characters = xmlSAX2Characters;
2900
3.02M
    hdlr->cdataBlock = xmlSAX2CDataBlock;
2901
3.02M
    hdlr->ignorableWhitespace = xmlSAX2Characters;
2902
3.02M
    hdlr->processingInstruction = xmlSAX2ProcessingInstruction;
2903
3.02M
    hdlr->comment = xmlSAX2Comment;
2904
3.02M
    hdlr->warning = xmlParserWarning;
2905
3.02M
    hdlr->error = xmlParserError;
2906
3.02M
    hdlr->fatalError = xmlParserError;
2907
2908
3.02M
    return(0);
2909
3.02M
}
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
3.79k
{
2942
3.79k
#ifdef LIBXML_SAX1_ENABLED
2943
3.79k
    xmlSAXVersion((xmlSAXHandlerPtr) &xmlDefaultSAXHandler, 1);
2944
3.79k
#endif /* LIBXML_SAX1_ENABLED */
2945
3.79k
}
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
3.79k
{
2958
3.79k
    if ((hdlr == NULL) || (hdlr->initialized != 0))
2959
0
  return;
2960
2961
3.79k
    hdlr->internalSubset = xmlSAX2InternalSubset;
2962
3.79k
    hdlr->externalSubset = NULL;
2963
3.79k
    hdlr->isStandalone = NULL;
2964
3.79k
    hdlr->hasInternalSubset = NULL;
2965
3.79k
    hdlr->hasExternalSubset = NULL;
2966
3.79k
    hdlr->resolveEntity = NULL;
2967
3.79k
    hdlr->getEntity = xmlSAX2GetEntity;
2968
3.79k
    hdlr->getParameterEntity = NULL;
2969
3.79k
    hdlr->entityDecl = NULL;
2970
3.79k
    hdlr->attributeDecl = NULL;
2971
3.79k
    hdlr->elementDecl = NULL;
2972
3.79k
    hdlr->notationDecl = NULL;
2973
3.79k
    hdlr->unparsedEntityDecl = NULL;
2974
3.79k
    hdlr->setDocumentLocator = xmlSAX2SetDocumentLocator;
2975
3.79k
    hdlr->startDocument = xmlSAX2StartDocument;
2976
3.79k
    hdlr->endDocument = xmlSAX2EndDocument;
2977
3.79k
    hdlr->startElement = xmlSAX2StartElement;
2978
3.79k
    hdlr->endElement = xmlSAX2EndElement;
2979
3.79k
    hdlr->reference = NULL;
2980
3.79k
    hdlr->characters = xmlSAX2Characters;
2981
3.79k
    hdlr->cdataBlock = xmlSAX2CDataBlock;
2982
3.79k
    hdlr->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
2983
3.79k
    hdlr->processingInstruction = xmlSAX2ProcessingInstruction;
2984
3.79k
    hdlr->comment = xmlSAX2Comment;
2985
3.79k
    hdlr->warning = xmlParserWarning;
2986
3.79k
    hdlr->error = xmlParserError;
2987
3.79k
    hdlr->fatalError = xmlParserError;
2988
2989
3.79k
    hdlr->initialized = 1;
2990
3.79k
}
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
3.79k
{
3003
3.79k
#ifdef LIBXML_SAX1_ENABLED
3004
3.79k
    xmlSAX2InitHtmlDefaultSAXHandler((xmlSAXHandlerPtr) &htmlDefaultSAXHandler);
3005
3.79k
#endif
3006
3.79k
}
3007
3008
#endif /* LIBXML_HTML_ENABLED */