Coverage Report

Created: 2023-06-07 06:06

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