Coverage Report

Created: 2022-06-08 06:16

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