~ubuntu-branches/ubuntu/utopic/libxml2/utopic

« back to all changes in this revision

Viewing changes to .pc/0012-Fix-a-possible-NULL-dereference.patch/SAX2.c

  • Committer: Package Import Robot
  • Author(s): Aron Xu, Christian Svensson, Daniel Schepler, Helmut Grohne, Adam Conrad, Matthias Klose, Aron Xu
  • Date: 2014-07-09 05:40:15 UTC
  • mfrom: (43.2.6 sid)
  • Revision ID: package-import@ubuntu.com-20140709054015-1q7dyagza4p2gkm0
Tags: 2.9.1+dfsg1-4
[ Christian Svensson ]
* Do not build-depend on readline (Closes: #742350)

[ Daniel Schepler ]
* Patch to bootstrap without python (Closes: #738080)

[ Helmut Grohne ]
* Drop unneeded B-D on perl and binutils (Closes: #753005)

[ Adam Conrad ]
* Actually run dh_autoreconf, which the old/new mixed rules file misses.

[ Matthias Klose ]
* Add patch to fix python multiarch issue
* Allow the package to cross-build by tweaking B-Ds on python
* Set PYTHON_LIBS for cross builds

[ Aron Xu ]
* Use correct $CC
* Configure udeb without python
* New round of cherry-picking upstream fixes
  - Includes fixes for CVE-2014-0191 (Closes: #747309).
* Call prename with -vf
* Require python-all-dev (>= 2.7.5-5~)
* Bump std-ver: 3.9.4 -> 3.9.5, no change

Show diffs side-by-side

added added

removed removed

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