Coverage Report

Created: 2023-03-02 15:25

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