Coverage Report

Created: 2025-08-04 07:15

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