Annotation of embedaddon/libxml2/SAX2.c, revision 1.1.1.3

1.1       misho       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:  */
1.1.1.3 ! misho      48: #define TODO                                                           \
1.1       misho      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) {
1.1.1.3 ! misho      60:     xmlStructuredErrorFunc schannel = NULL;
        !            61:     const char *str1 = "out of memory\n";
        !            62: 
1.1       misho      63:     if (ctxt != NULL) {
1.1.1.3 ! misho      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);
1.1       misho      73:        ctxt->errNo = XML_ERR_NO_MEMORY;
                     74:        ctxt->instate = XML_PARSER_EOF;
                     75:        ctxt->disableSAX = 1;
1.1.1.3 ! misho      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);
1.1       misho      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,
1.1.1.3 ! misho     146:                     XML_ERR_FATAL, NULL, 0,
1.1       misho     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,
1.1.1.3 ! misho     177:                     XML_ERR_WARNING, NULL, 0,
1.1       misho     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,
1.1.1.3 ! misho     202:                     XML_ERR_ERROR, NULL, 0,
1.1       misho     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,
1.1.1.3 ! misho     226:                     XML_ERR_WARNING, NULL, 0,
1.1       misho     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);
1.1.1.3 ! misho     260:     return((const xmlChar *) ctxt->input->filename);
1.1       misho     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:     }
1.1.1.3 ! misho     375:     ctxt->myDoc->intSubset =
1.1       misho     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;
1.1.1.3 ! misho     414:        const xmlChar *oldencoding;
1.1       misho     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;
1.1.1.3 ! misho     436:        oldencoding = ctxt->encoding;
        !           437:        ctxt->encoding = NULL;
1.1       misho     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;
1.1.1.3 ! misho     448:            ctxt->encoding = oldencoding;
1.1       misho     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;
1.1.1.3 ! misho     494:        if ((ctxt->encoding != NULL) &&
        !           495:            ((ctxt->dict == NULL) ||
        !           496:             (!xmlDictOwns(ctxt->dict, ctxt->encoding))))
        !           497:            xmlFree((xmlChar *) ctxt->encoding);
        !           498:        ctxt->encoding = oldencoding;
1.1       misho     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;
1.1.1.3 ! misho     603:        unsigned long oldnbent = ctxt->nbentities;
1.1       misho     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;
1.1.1.3 ! misho     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:        }
1.1       misho     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)
1.1.1.3 ! misho     654:  * @name:  the entity name
        !           655:  * @type:  the entity type
1.1       misho     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;
1.1.1.3 ! misho     690: 
1.1       misho     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))
1.1.1.3 ! misho     699:            ctxt->sax->warning(ctxt->userData,
1.1       misho     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;
1.1.1.3 ! misho     709: 
1.1       misho     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
1.1.1.3 ! misho     724:  * @fullname:  the attribute name
        !           725:  * @type:  the attribute type
1.1       misho     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,
1.1.1.3 ! misho     768:           name, prefix, (xmlAttributeType) type,
1.1       misho     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)
1.1.1.3 ! misho     794:  * @name:  the element name
        !           795:  * @type:  the element type
1.1       misho     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))
1.1.1.3 ! misho     916:            ctxt->sax->warning(ctxt->userData,
1.1       misho     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;
1.1.1.3 ! misho     926: 
1.1       misho     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))
1.1.1.3 ! misho     936:            ctxt->sax->warning(ctxt->userData,
1.1       misho     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;
1.1.1.3 ! misho     946: 
1.1       misho     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))
1.1.1.3 ! misho    1190:                    ctxt->sax->warning(ctxt->userData,
1.1       misho    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))
1.1.1.3 ! misho    1195:                        ctxt->sax->warning(ctxt->userData,
1.1       misho    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 */
1.1.1.3 ! misho    1215:        if (name != NULL)
1.1       misho    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);
1.1.1.3 ! misho    1237:                if (name != NULL)
1.1       misho    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 */
1.1.1.3 ! misho    1278:        if (name != NULL)
1.1       misho    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) {
1.1.1.3 ! misho    1344: 
1.1       misho    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--;
1.1.1.3 ! misho    1356: 
1.1       misho    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);
1.1.1.3 ! misho    1413:     if (ns != NULL)
1.1       misho    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
1.1.1.3 ! misho    1512:                 *  - there isn't already an attribute definition
1.1       misho    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:      */
1.1.1.3 ! misho    1601:     if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) &&
1.1       misho    1602:         ((ctxt->myDoc->intSubset == NULL) ||
1.1.1.3 ! misho    1603:         ((ctxt->myDoc->intSubset->notations == NULL) &&
1.1       misho    1604:          (ctxt->myDoc->intSubset->elements == NULL) &&
1.1.1.3 ! misho    1605:          (ctxt->myDoc->intSubset->attributes == NULL) &&
1.1       misho    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:     }
1.1.1.3 ! misho    1611: 
1.1       misho    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
1.1.1.3 ! misho    1799: 
1.1       misho    1800:     /* Capture end position and add node */
                   1801:     if (cur != NULL && ctxt->record_info) {
1.1.1.2   misho    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);
1.1       misho    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: 
1.1.1.3 ! misho    1816: 
1.1       misho    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
1.1.1.3 ! misho    1832:  *
        !          1833:  * Callback for a text node
1.1       misho    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)) {
1.1.1.3 ! misho    1866:            /* store the string in the node overriding properties and nsDef */
1.1       misho    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: 
1.1.1.3 ! misho    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:     }
1.1       misho    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
1.1.1.3 ! misho    1921:  *
1.1       misho    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: 
1.1.1.3 ! misho    1987:        ret->parent = ctxt->node;
1.1       misho    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)
1.1.1.3 ! misho    2011:            ret = xmlNewNsPropEatName(ctxt->node, namespace,
1.1       misho    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;
1.1.1.3 ! misho    2097: 
1.1       misho    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;
1.1.1.2   misho    2204:     xmlChar *lname = NULL;
1.1       misho    2205:     int i, j;
                   2206: 
                   2207:     if (ctx == NULL) return;
                   2208:     parent = ctxt->node;
                   2209:     /*
                   2210:      * First check on validity:
                   2211:      */
1.1.1.3 ! misho    2212:     if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) &&
1.1       misho    2213:         ((ctxt->myDoc->intSubset == NULL) ||
1.1.1.3 ! misho    2214:         ((ctxt->myDoc->intSubset->notations == NULL) &&
1.1       misho    2215:          (ctxt->myDoc->intSubset->elements == NULL) &&
1.1.1.3 ! misho    2216:          (ctxt->myDoc->intSubset->attributes == NULL) &&
1.1       misho    2217:          (ctxt->myDoc->intSubset->entities == NULL)))) {
1.1.1.3 ! misho    2218:        xmlErrValid(ctxt, XML_DTD_NO_DTD,
1.1       misho    2219:          "Validation failed: no DTD found !", NULL, NULL);
                   2220:        ctxt->validate = 0;
                   2221:     }
                   2222: 
                   2223:     /*
1.1.1.2   misho    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:     /*
1.1       misho    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 {
1.1.1.2   misho    2250:            if (lname == NULL)
                   2251:                ret->name = xmlStrdup(localname);
                   2252:            else
                   2253:                ret->name = lname;
1.1       misho    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)
1.1.1.3 ! misho    2263:            ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL,
1.1       misho    2264:                                       (xmlChar *) localname, NULL);
1.1.1.2   misho    2265:        else if (lname == NULL)
1.1       misho    2266:            ret = xmlNewDocNode(ctxt->myDoc, NULL, localname, NULL);
1.1.1.2   misho    2267:        else
1.1.1.3 ! misho    2268:            ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL,
1.1.1.2   misho    2269:                                       (xmlChar *) lname, NULL);
1.1       misho    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: 
1.1.1.2   misho    2284:     if (parent == NULL) {
1.1       misho    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) {
1.1.1.2   misho    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:            }
1.1       misho    2401:            xmlSAX2AttributeNs(ctxt, attributes[j], attributes[j+1],
1.1.1.2   misho    2402:                               attributes[j+3], attributes[j+4]);
1.1       misho    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:  *
1.1.1.3 ! misho    2473:  * called when an entity xmlSAX2Reference is detected.
1.1       misho    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:             }
1.1.1.3 ! misho    2578:            if ((size_t)ctxt->nodelen > SIZE_T_MAX - (size_t)len ||
1.1       misho    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:     }
1.1.1.2   misho    2682:     if (parent == NULL) {
1.1       misho    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:     }
1.1.1.2   misho    2743:     if (parent == NULL) {
1.1       misho    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"

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>