Annotation of embedaddon/php/ext/xml/compat.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:    +----------------------------------------------------------------------+
                      3:    | PHP Version 5                                                        |
                      4:    +----------------------------------------------------------------------+
                      5:    | Copyright (c) 1997-2012 The PHP Group                                |
                      6:    +----------------------------------------------------------------------+
                      7:    | This source file is subject to version 3.01 of the PHP license,      |
                      8:    | that is bundled with this package in the file LICENSE, and is        |
                      9:    | available through the world-wide-web at the following url:           |
                     10:    | http://www.php.net/license/3_01.txt                                  |
                     11:    | If you did not receive a copy of the PHP license and are unable to   |
                     12:    | obtain it through the world-wide-web, please send a note to          |
                     13:    | license@php.net so we can mail you a copy immediately.               |
                     14:    +----------------------------------------------------------------------+
                     15:    | Authors: Sterling Hughes <sterling@php.net>                          |
                     16:    +----------------------------------------------------------------------+
                     17:  */
                     18: 
                     19: #include "php.h"
                     20: #if defined(HAVE_LIBXML) && (defined(HAVE_XML) || defined(HAVE_XMLRPC)) && !defined(HAVE_LIBEXPAT)
                     21: #include "expat_compat.h"
                     22: 
                     23: typedef struct _php_xml_ns {
                     24:        xmlNsPtr nsptr;
                     25:        int ref_count;
                     26:        void *next;
                     27:        void *prev;
                     28: } php_xml_ns;
                     29: 
                     30: #ifdef LIBXML_EXPAT_COMPAT
                     31: 
                     32: #define IS_NS_DECL(__ns) \
                     33:        ((__ns) != NULL && strlen(__ns) == 5 && *(__ns) == 'x' && *((__ns)+1) == 'm' && \
                     34:         *((__ns)+2) == 'l' && *((__ns)+3) == 'n' && *((__ns)+4) == 's')
                     35: 
                     36: static void 
                     37: _qualify_namespace(XML_Parser parser, const xmlChar *name, const xmlChar *URI, xmlChar **qualified)
                     38: {
                     39:        if (URI) {
                     40:                        /* Use libxml functions otherwise its memory deallocation is screwed up */
                     41:                        *qualified = xmlStrdup(URI);
                     42:                        *qualified = xmlStrncat(*qualified, parser->_ns_seperator, 1);
                     43:                        *qualified = xmlStrncat(*qualified, name, xmlStrlen(name));
                     44:        } else {
                     45:                *qualified = xmlStrdup(name);
                     46:        }
                     47: }
                     48: 
                     49: static void
                     50: _start_element_handler(void *user, const xmlChar *name, const xmlChar **attributes)
                     51: {
                     52:        XML_Parser  parser = (XML_Parser) user;
                     53:        xmlChar    *qualified_name = NULL;
                     54: 
                     55:        if (parser->h_start_element == NULL) {
                     56:                if (parser->h_default) {
                     57:                        int attno = 0;
                     58: 
                     59:                        qualified_name = xmlStrncatNew((xmlChar *)"<", name, xmlStrlen(name));
                     60:                        if (attributes) {
                     61:                                while (attributes[attno] != NULL) {
                     62:                                        int att_len;
                     63:                                        char *att_string, *att_name, *att_value;
                     64: 
                     65:                                        att_name = (char *)attributes[attno++];
                     66:                                        att_value = (char *)attributes[attno++];
                     67: 
                     68:                                        att_len = spprintf(&att_string, 0, " %s=\"%s\"", att_name, att_value);
                     69: 
                     70:                                        qualified_name = xmlStrncat(qualified_name, (xmlChar *)att_string, att_len);
                     71:                                        efree(att_string);
                     72:                                }
                     73: 
                     74:                        }
                     75:                        qualified_name = xmlStrncat(qualified_name, (xmlChar *)">", 1);
                     76:                        parser->h_default(parser->user, (const XML_Char *) qualified_name, xmlStrlen(qualified_name));
                     77:                        xmlFree(qualified_name);
                     78:                }
                     79:                return;
                     80:        }
                     81: 
                     82:        qualified_name = xmlStrdup(name);
                     83: 
                     84:        parser->h_start_element(parser->user, (const XML_Char *) qualified_name, (const XML_Char **) attributes);
                     85: 
                     86:        xmlFree(qualified_name);
                     87: }
                     88: 
                     89: static void
                     90: _start_element_handler_ns(void *user, const xmlChar *name, const xmlChar *prefix, const xmlChar *URI, int nb_namespaces, const xmlChar ** namespaces, int nb_attributes, int nb_defaulted, const xmlChar ** attributes)
                     91: {
                     92:        XML_Parser  parser = (XML_Parser) user;
                     93:        xmlChar    *qualified_name = NULL;
                     94:        xmlChar **attrs = NULL;
                     95:        int i;
                     96:        int z = 0;
                     97:        int y = 0;
                     98:        
                     99:        if (nb_namespaces > 0 && parser->h_start_ns != NULL) {
                    100:                for (i = 0; i < nb_namespaces; i += 1) {
                    101:                        parser->h_start_ns(parser->user, (const XML_Char *) namespaces[y], (const XML_Char *) namespaces[y+1]);
                    102:                        y += 2;
                    103:                }
                    104:                y = 0;
                    105:        }
                    106:        
                    107:        if (parser->h_start_element == NULL) {
                    108:                if (parser->h_default) {
                    109: 
                    110:                        if (prefix) {
                    111:                                qualified_name = xmlStrncatNew((xmlChar *)"<", prefix, xmlStrlen(prefix));
                    112:                                qualified_name = xmlStrncat(qualified_name, (xmlChar *)":", 1);
                    113:                                qualified_name = xmlStrncat(qualified_name, name, xmlStrlen(name));
                    114:                        } else {
                    115:                                qualified_name = xmlStrncatNew((xmlChar *)"<", name, xmlStrlen(name));
                    116:                        }
                    117:                        
                    118:                        if (namespaces) {
                    119:                                int i, j;
                    120:                                for (i = 0,j = 0;j < nb_namespaces;j++) {
                    121:                                        int ns_len;
                    122:                                        char *ns_string, *ns_prefix, *ns_url;
                    123:                                        
                    124:                                        ns_prefix = (char *) namespaces[i++];
                    125:                                        ns_url = (char *) namespaces[i++];
                    126:                                        
                    127:                                        if (ns_prefix) {
                    128:                                                ns_len = spprintf(&ns_string, 0, " xmlns:%s=\"%s\"", ns_prefix, ns_url);
                    129:                                        } else {
                    130:                                                ns_len = spprintf(&ns_string, 0, " xmlns=\"%s\"", ns_url);
                    131:                                        }
                    132:                                        qualified_name = xmlStrncat(qualified_name, (xmlChar *)ns_string, ns_len);
                    133:                                        
                    134:                                        efree(ns_string);
                    135:                                }
                    136:                        }
                    137:                        
                    138:                        if (attributes) {
                    139:                                for (i = 0; i < nb_attributes; i += 1) {
                    140:                                        int att_len;
                    141:                                        char *att_string, *att_name, *att_value, *att_prefix, *att_valueend;
                    142: 
                    143:                                        att_name = (char *) attributes[y++];
                    144:                                        att_prefix = (char *)attributes[y++];
                    145:                                        y++;
                    146:                                        att_value = (char *)attributes[y++];
                    147:                                        att_valueend = (char *)attributes[y++];
                    148: 
                    149:                                        if (att_prefix) {
                    150:                                                att_len = spprintf(&att_string, 0, " %s:%s=\"", att_prefix, att_name);
                    151:                                        } else {
                    152:                                                att_len = spprintf(&att_string, 0, " %s=\"", att_name);
                    153:                                        }
                    154: 
                    155:                                        qualified_name = xmlStrncat(qualified_name, (xmlChar *)att_string, att_len);
                    156:                                        qualified_name = xmlStrncat(qualified_name, (xmlChar *)att_value, att_valueend - att_value);
                    157:                                        qualified_name = xmlStrncat(qualified_name, (xmlChar *)"\"", 1);
                    158:                                        
                    159:                                        efree(att_string);
                    160:                                }
                    161: 
                    162:                        }
                    163:                        qualified_name = xmlStrncat(qualified_name, (xmlChar *)">", 1);
                    164:                        parser->h_default(parser->user, (const XML_Char *) qualified_name, xmlStrlen(qualified_name));
                    165:                        xmlFree(qualified_name);
                    166:                }
                    167:                return;
                    168:        }
                    169:        _qualify_namespace(parser, name, URI, &qualified_name);
                    170:        
                    171:        if (attributes != NULL) {
                    172:                xmlChar    *qualified_name_attr = NULL;
                    173:                attrs = safe_emalloc((nb_attributes  * 2) + 1, sizeof(int *), 0);
                    174: 
                    175:                for (i = 0; i < nb_attributes; i += 1) {
                    176: 
                    177:                        if (attributes[y+1] != NULL) {
                    178:                                _qualify_namespace(parser, attributes[y] , attributes[y + 2], &qualified_name_attr);
                    179:                        } else {
                    180:                                qualified_name_attr = xmlStrdup(attributes[y]);
                    181:                        }
                    182:                        attrs[z] = qualified_name_attr;
                    183:                        attrs[z + 1] = xmlStrndup(attributes[y + 3] , (int) (attributes[y + 4] - attributes[y + 3]));
                    184:                        z += 2;
                    185:                        y += 5;
                    186:                }
                    187: 
                    188:                attrs[z] = NULL;
                    189:        }
                    190:        parser->h_start_element(parser->user, (const XML_Char *) qualified_name, (const XML_Char **) attrs);
                    191:        if (attrs) {
                    192:                for (i = 0; i < z; i++) {
                    193:                        xmlFree(attrs[i]);
                    194:                }
                    195:                efree(attrs);
                    196:        }
                    197:        xmlFree(qualified_name);
                    198: }
                    199: 
                    200: static void
                    201: _namespace_handler(XML_Parser parser, xmlNsPtr nsptr)
                    202: {
                    203:        if (nsptr != NULL) {
                    204:                _namespace_handler(parser, nsptr->next);
                    205:                parser->h_end_ns(parser->user, nsptr->prefix);
                    206:        }
                    207: }
                    208: 
                    209: static void
                    210: _end_element_handler(void *user, const xmlChar *name)
                    211: {
                    212:        xmlChar    *qualified_name;
                    213:        XML_Parser  parser = (XML_Parser) user;
                    214: 
                    215:        if (parser->h_end_element == NULL) {
                    216:                if (parser->h_default) {
                    217:                        char *end_element;
                    218: 
                    219:                        spprintf(&end_element, 0, "</%s>", (char *)name);
                    220:                        parser->h_default(parser->user, (const XML_Char *) end_element, strlen(end_element));
                    221:                        efree(end_element);
                    222:                }
                    223:                return;
                    224:        }
                    225:        
                    226:        qualified_name = xmlStrdup(name);
                    227: 
                    228:        parser->h_end_element(parser->user, (const XML_Char *) qualified_name);
                    229: 
                    230:        xmlFree(qualified_name);
                    231: }
                    232: 
                    233: static void
                    234: _end_element_handler_ns(void *user, const xmlChar *name, const xmlChar * prefix, const xmlChar *URI)
                    235: {
                    236:        xmlChar    *qualified_name;
                    237:        XML_Parser  parser = (XML_Parser) user;
                    238: 
                    239:        if (parser->h_end_element == NULL) {
                    240:                if (parser->h_default) {
                    241:                        char *end_element;
                    242:                        int end_element_len;
                    243: 
                    244:                        if (prefix) {
                    245:                                end_element_len = spprintf(&end_element, 0, "</%s:%s>", (char *) prefix, (char *)name);
                    246:                        } else {
                    247:                                end_element_len = spprintf(&end_element, 0, "</%s>", (char *)name);
                    248:                        }
                    249:                        parser->h_default(parser->user, (const XML_Char *) end_element, end_element_len);
                    250:                        efree(end_element);
                    251:                }
                    252:                return;
                    253:        }
                    254: 
                    255:        _qualify_namespace(parser, name, URI,  &qualified_name);
                    256: 
                    257:        parser->h_end_element(parser->user, (const XML_Char *) qualified_name);
                    258: 
                    259:        xmlFree(qualified_name);
                    260: }
                    261: 
                    262: static void
                    263: _cdata_handler(void *user, const xmlChar *cdata, int cdata_len)
                    264: {
                    265:        XML_Parser parser = (XML_Parser) user;
                    266: 
                    267:        if (parser->h_cdata == NULL) {
                    268:                if (parser->h_default) {
                    269:                        parser->h_default(parser->user, (const XML_Char *) cdata, cdata_len);
                    270:                }
                    271:                return;
                    272:        }
                    273: 
                    274:        parser->h_cdata(parser->user, (const XML_Char *) cdata, cdata_len);
                    275: }
                    276: 
                    277: static void
                    278: _pi_handler(void *user, const xmlChar *target, const xmlChar *data)
                    279: {
                    280:        XML_Parser parser = (XML_Parser) user;
                    281: 
                    282:        if (parser->h_pi == NULL) {
                    283:                if (parser->h_default) {
                    284:                        char    *full_pi;
                    285:                        spprintf(&full_pi, 0, "<?%s %s?>", (char *)target, (char *)data);
                    286:                        parser->h_default(parser->user, (const XML_Char *) full_pi, strlen(full_pi));
                    287:                        efree(full_pi);
                    288:                }
                    289:                return;
                    290:        }
                    291: 
                    292:        parser->h_pi(parser->user, (const XML_Char *) target, (const XML_Char *) data);
                    293: }
                    294: 
                    295: static void
                    296: _unparsed_entity_decl_handler(void *user, 
                    297:                               const xmlChar *name, 
                    298:                                                          const xmlChar *pub_id, 
                    299:                                                          const xmlChar *sys_id, 
                    300:                                                          const xmlChar *notation)
                    301: {
                    302:        XML_Parser parser = (XML_Parser) user;
                    303: 
                    304:        if (parser->h_unparsed_entity_decl == NULL) {
                    305:                return;
                    306:        }
                    307: 
                    308:        parser->h_unparsed_entity_decl(parser->user, name, NULL, sys_id, pub_id, notation);
                    309: }
                    310: 
                    311: static void
                    312: _notation_decl_handler(void *user, const xmlChar *notation, const xmlChar *pub_id, const xmlChar *sys_id)
                    313: {
                    314:        XML_Parser parser = (XML_Parser) user;
                    315: 
                    316:        if (parser->h_notation_decl == NULL) {
                    317:                return;
                    318:        }
                    319: 
                    320:        parser->h_notation_decl(parser->user, notation, NULL, sys_id, pub_id);
                    321: }
                    322: 
                    323: static void
                    324: _build_comment(const xmlChar *data, int data_len, xmlChar **comment, int *comment_len)
                    325: {
                    326:        *comment_len = data_len + 7;
                    327:        
                    328:        *comment = xmlMalloc(*comment_len + 1);
                    329:        memcpy(*comment, "<!--", 4);
                    330:        memcpy(*comment + 4, data, data_len);
                    331:        memcpy(*comment + 4 + data_len, "-->", 3);
                    332: 
                    333:        (*comment)[*comment_len] = '\0';
                    334: }
                    335: 
                    336: static void
                    337: _comment_handler(void *user, const xmlChar *comment)
                    338: {
                    339:        XML_Parser parser = (XML_Parser) user;
                    340: 
                    341:        if (parser->h_default) {
                    342:                xmlChar *d_comment;
                    343:                int      d_comment_len;
                    344: 
                    345:                _build_comment(comment, xmlStrlen(comment), &d_comment, &d_comment_len);
                    346:                parser->h_default(parser->user, d_comment, d_comment_len);
                    347:                xmlFree(d_comment);
                    348:        }
                    349: }
                    350: 
                    351: static void
                    352: _build_entity(const xmlChar *name, int len, xmlChar **entity, int *entity_len) 
                    353: {
                    354:        *entity_len = len + 2;
                    355:        *entity = xmlMalloc(*entity_len + 1);
                    356:        (*entity)[0] = '&';
                    357:        memcpy(*entity+1, name, len);
                    358:        (*entity)[len+1] = ';';
                    359:        (*entity)[*entity_len] = '\0';
                    360: }
                    361: 
                    362: static void
                    363: _external_entity_ref_handler(void *user, const xmlChar *names, int type, const xmlChar *sys_id, const xmlChar *pub_id, xmlChar *content)
                    364: {
                    365:        XML_Parser parser = (XML_Parser) user;
                    366: 
                    367:        if (parser->h_external_entity_ref == NULL) {
                    368:                return;
                    369:        }
                    370: 
                    371:        parser->h_external_entity_ref(parser, names, "", sys_id, pub_id);
                    372: }
                    373: 
                    374: static xmlEntityPtr
                    375: _get_entity(void *user, const xmlChar *name)
                    376: {
                    377:        XML_Parser parser = (XML_Parser) user;
                    378:        xmlEntityPtr ret = NULL;
                    379: 
                    380:        if (parser->parser->inSubset == 0) {
                    381:                ret = xmlGetPredefinedEntity(name);
                    382:                if (ret == NULL)
                    383:                        ret = xmlGetDocEntity(parser->parser->myDoc, name);
                    384: 
                    385:                if (ret == NULL || (parser->parser->instate != XML_PARSER_ENTITY_VALUE && parser->parser->instate != XML_PARSER_ATTRIBUTE_VALUE)) {
                    386:                        if (ret == NULL || ret->etype == XML_INTERNAL_GENERAL_ENTITY || ret->etype == XML_INTERNAL_PARAMETER_ENTITY || ret->etype == XML_INTERNAL_PREDEFINED_ENTITY) {
                    387:                                /* Predefined entities will expand unless no cdata handler is present */
                    388:                                if (parser->h_default && ! (ret && ret->etype == XML_INTERNAL_PREDEFINED_ENTITY && parser->h_cdata)) {
                    389:                                        xmlChar *entity;
                    390:                                        int      len;
                    391:                                        
                    392:                                        _build_entity(name, xmlStrlen(name), &entity, &len);
                    393:                                        parser->h_default(parser->user, (const xmlChar *) entity, len);
                    394:                                        xmlFree(entity);
                    395:                                } else {
                    396:                                        /* expat will not expand internal entities if default handler is present otherwise
                    397:                                        it will expand and pass them to cdata handler */
                    398:                                        if (parser->h_cdata && ret) {
                    399:                                                parser->h_cdata(parser->user, ret->content, xmlStrlen(ret->content));
                    400:                                        }
                    401:                                }
                    402:                        } else {
                    403:                                if (ret->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
                    404:                                        _external_entity_ref_handler(user, ret->name, ret->etype, ret->SystemID, ret->ExternalID, NULL);
                    405:                                }
                    406:                        }
                    407:                }
                    408:        }
                    409: 
                    410:        return ret;
                    411: }
                    412: 
                    413: static xmlSAXHandler 
                    414: php_xml_compat_handlers = {
                    415:        NULL, /* internalSubset */
                    416:        NULL, /* isStandalone */
                    417:        NULL, /* hasInternalSubset */
                    418:        NULL, /* hasExternalSubset */
                    419:        NULL, /* resolveEntity */
                    420:        _get_entity, /* getEntity */
                    421:        NULL, /* entityDecl */
                    422:        _notation_decl_handler,
                    423:        NULL, /* attributeDecl */
                    424:        NULL, /* elementDecl */
                    425:        _unparsed_entity_decl_handler, /* unparsedEntity */
                    426:        NULL, /* setDocumentLocator */
                    427:        NULL, /* startDocument */
                    428:        NULL, /* endDocument */
                    429:        _start_element_handler, /* startElement */
                    430:        _end_element_handler, /* endElement */
                    431:        NULL, /* reference */
                    432:        _cdata_handler,
                    433:        NULL, /* ignorableWhitespace */
                    434:        _pi_handler,
                    435:        _comment_handler, /* comment */
                    436:        NULL, /* warning */
                    437:        NULL, /* error */
                    438:        NULL,  /* fatalError */
                    439:        NULL,  /* getParameterEntity */
                    440:        _cdata_handler, /* cdataBlock */
                    441:        NULL, /* externalSubset */
                    442:        XML_SAX2_MAGIC,
                    443:        NULL,
                    444:        _start_element_handler_ns,
                    445:        _end_element_handler_ns,
                    446:        NULL    
                    447: };
                    448: 
                    449: PHPAPI XML_Parser 
                    450: XML_ParserCreate(const XML_Char *encoding)
                    451: {
                    452:        return XML_ParserCreate_MM(encoding, NULL, NULL);
                    453: }
                    454: 
                    455: PHPAPI XML_Parser
                    456: XML_ParserCreateNS(const XML_Char *encoding, const XML_Char sep)
                    457: {
                    458:        XML_Char tmp[2];
                    459:        tmp[0] = sep;
                    460:        tmp[1] = '\0';
                    461:        return XML_ParserCreate_MM(encoding, NULL, tmp);
                    462: }
                    463: 
                    464: PHPAPI XML_Parser
                    465: XML_ParserCreate_MM(const XML_Char *encoding, const XML_Memory_Handling_Suite *memsuite, const XML_Char *sep)
                    466: {
                    467:        XML_Parser parser;
                    468: 
                    469:        parser = (XML_Parser) emalloc(sizeof(struct _XML_Parser));
                    470:        memset(parser, 0, sizeof(struct _XML_Parser));
                    471:        parser->use_namespace = 0;
                    472:        parser->_ns_seperator = NULL;
                    473: 
                    474:        parser->parser = xmlCreatePushParserCtxt((xmlSAXHandlerPtr) &php_xml_compat_handlers, (void *) parser, NULL, 0, NULL);
                    475:        if (parser->parser == NULL) {
                    476:                efree(parser);
                    477:                return NULL;
                    478:        }
                    479: #if LIBXML_VERSION <= 20617
                    480:        /* for older versions of libxml2, allow correct detection of
                    481:         * charset in documents with a BOM: */
                    482:        parser->parser->charset = XML_CHAR_ENCODING_NONE;
                    483: #endif
                    484: 
                    485: #if LIBXML_VERSION >= 20703
                    486:        xmlCtxtUseOptions(parser->parser, XML_PARSE_OLDSAX);
                    487: #endif
                    488: 
                    489:        parser->parser->replaceEntities = 1;
                    490:        parser->parser->wellFormed = 0;
                    491:        if (sep != NULL) {
                    492:                parser->use_namespace = 1;
                    493:                parser->parser->sax2 = 1;
                    494:                parser->_ns_seperator = xmlStrdup(sep);
                    495:        } else {
                    496:                /* Reset flag as XML_SAX2_MAGIC is needed for xmlCreatePushParserCtxt 
                    497:                so must be set in the handlers */
                    498:                parser->parser->sax->initialized = 1;
                    499:        }
                    500:        return parser;
                    501: }
                    502: 
                    503: PHPAPI void
                    504: XML_SetUserData(XML_Parser parser, void *user)
                    505: {
                    506:        parser->user = user;
                    507: }
                    508: 
                    509: PHPAPI void *
                    510: XML_GetUserData(XML_Parser parser)
                    511: {
                    512:        return parser->user;
                    513: }
                    514: 
                    515: PHPAPI void
                    516: XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start, XML_EndElementHandler end)
                    517: {
                    518:        parser->h_start_element = start;
                    519:        parser->h_end_element = end;
                    520: }
                    521: 
                    522: PHPAPI void
                    523: XML_SetCharacterDataHandler(XML_Parser parser, XML_CharacterDataHandler cdata)
                    524: {
                    525:        parser->h_cdata = cdata;
                    526: }
                    527: 
                    528: PHPAPI void
                    529: XML_SetProcessingInstructionHandler(XML_Parser parser, XML_ProcessingInstructionHandler pi)
                    530: {
                    531:        parser->h_pi = pi;
                    532: }
                    533: 
                    534: PHPAPI void
                    535: XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler comment)
                    536: {
                    537:        parser->h_comment = comment;
                    538: }
                    539: 
                    540: PHPAPI void 
                    541: XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler d)
                    542: {
                    543:        parser->h_default = d;
                    544: }
                    545: 
                    546: PHPAPI void
                    547: XML_SetUnparsedEntityDeclHandler(XML_Parser parser, XML_UnparsedEntityDeclHandler unparsed_decl)
                    548: {
                    549:        parser->h_unparsed_entity_decl = unparsed_decl;
                    550: }
                    551: 
                    552: PHPAPI void
                    553: XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler notation_decl)
                    554: {
                    555:        parser->h_notation_decl = notation_decl;
                    556: }
                    557: 
                    558: PHPAPI void
                    559: XML_SetExternalEntityRefHandler(XML_Parser parser, XML_ExternalEntityRefHandler ext_entity)
                    560: {
                    561:        parser->h_external_entity_ref = ext_entity;
                    562: }
                    563: 
                    564: PHPAPI void
                    565: XML_SetStartNamespaceDeclHandler(XML_Parser parser, XML_StartNamespaceDeclHandler start_ns)
                    566: {
                    567:        parser->h_start_ns = start_ns;
                    568: }
                    569: 
                    570: PHPAPI void
                    571: XML_SetEndNamespaceDeclHandler(XML_Parser parser, XML_EndNamespaceDeclHandler end_ns)
                    572: {
                    573:        parser->h_end_ns = end_ns;
                    574: }
                    575: 
                    576: PHPAPI int
                    577: XML_Parse(XML_Parser parser, const XML_Char *data, int data_len, int is_final)
                    578: {
                    579:        int error;
                    580: 
                    581: /* The following is a hack to keep BC with PHP 4 while avoiding 
                    582: the inifite loop in libxml <= 2.6.17 which occurs when no encoding 
                    583: has been defined and none can be detected */
                    584: #if LIBXML_VERSION <= 20617
                    585:        if (parser->parser->charset == XML_CHAR_ENCODING_NONE) {
                    586:                if (data_len >= 4 || (parser->parser->input->buf->buffer->use + data_len >= 4)) {
                    587:                        xmlChar start[4];
                    588:                        int char_count;
                    589: 
                    590:                        char_count = parser->parser->input->buf->buffer->use;
                    591:                        if (char_count > 4) {
                    592:                                char_count = 4;
                    593:                        }
                    594: 
                    595:                        memcpy(start, parser->parser->input->buf->buffer->content, (size_t)char_count);
                    596:                        memcpy(start + char_count, data, (size_t)(4 - char_count));
                    597: 
                    598:                        if (xmlDetectCharEncoding(&start[0], 4) == XML_CHAR_ENCODING_NONE) {
                    599:                                parser->parser->charset = XML_CHAR_ENCODING_UTF8;
                    600:                        }
                    601:                }
                    602:        }
                    603: #endif
                    604: 
                    605:        error = xmlParseChunk(parser->parser, data, data_len, is_final);
                    606:        if (!error) {
                    607:                return 1;
                    608:        } else if (parser->parser->lastError.level > XML_ERR_WARNING ){
                    609:                return 0;
                    610:        } else {
                    611:                return 1;
                    612:        }
                    613: }
                    614: 
                    615: PHPAPI int
                    616: XML_GetErrorCode(XML_Parser parser)
                    617: {
                    618:        return parser->parser->errNo;
                    619: }
                    620: 
                    621: static const XML_Char *const error_mapping[] = {
                    622:        "No error",
                    623:        "No memory",
                    624:        "Invalid document start",
                    625:        "Empty document",
                    626:        "Not well-formed (invalid token)",
                    627:        "Invalid document end",
                    628:        "Invalid hexadecimal character reference",
                    629:        "Invalid decimal character reference",
                    630:        "Invalid character reference",
                    631:        "Invalid character",
                    632:        "XML_ERR_CHARREF_AT_EOF",
                    633:        "XML_ERR_CHARREF_IN_PROLOG",
                    634:        "XML_ERR_CHARREF_IN_EPILOG",
                    635:        "XML_ERR_CHARREF_IN_DTD",
                    636:        "XML_ERR_ENTITYREF_AT_EOF",
                    637:        "XML_ERR_ENTITYREF_IN_PROLOG",
                    638:        "XML_ERR_ENTITYREF_IN_EPILOG",
                    639:        "XML_ERR_ENTITYREF_IN_DTD",
                    640:        "PEReference at end of document",
                    641:        "PEReference in prolog",
                    642:        "PEReference in epilog",
                    643:        "PEReference: forbidden within markup decl in internal subset",
                    644:        "XML_ERR_ENTITYREF_NO_NAME",
                    645:        "EntityRef: expecting ';'",
                    646:        "PEReference: no name",
                    647:        "PEReference: expecting ';'",
                    648:        "Undeclared entity error",
                    649:        "Undeclared entity warning",
                    650:        "Unparsed Entity",
                    651:        "XML_ERR_ENTITY_IS_EXTERNAL",
                    652:        "XML_ERR_ENTITY_IS_PARAMETER",
                    653:        "Unknown encoding",
                    654:        "Unsupported encoding",
                    655:        "String not started expecting ' or \"",
                    656:        "String not closed expecting \" or '",
                    657:        "Namespace declaration error",
                    658:        "EntityValue: \" or ' expected",
                    659:        "EntityValue: \" or ' expected",
                    660:        "< in attribute",
                    661:        "Attribute not started",
                    662:        "Attribute not finished",
                    663:        "Attribute without value",
                    664:        "Attribute redefined",
                    665:        "SystemLiteral \" or ' expected",
                    666:        "SystemLiteral \" or ' expected",
                    667:        /* "XML_ERR_COMMENT_NOT_STARTED", <= eliminated on purpose */
                    668:        "Comment not finished",
                    669:        "Processing Instruction not started",
                    670:        "Processing Instruction not finished",
                    671:        "NOTATION: Name expected here",
                    672:        "'>' required to close NOTATION declaration",
                    673:        "'(' required to start ATTLIST enumeration",
                    674:        "'(' required to start ATTLIST enumeration",
                    675:        "MixedContentDecl : '|' or ')*' expected",
                    676:        "XML_ERR_MIXED_NOT_FINISHED",
                    677:        "ELEMENT in DTD not started",
                    678:        "ELEMENT in DTD not finished",
                    679:        "XML declaration not started",
                    680:        "XML declaration not finished",
                    681:        "XML_ERR_CONDSEC_NOT_STARTED",
                    682:        "XML conditional section not closed",
                    683:        "Content error in the external subset",
                    684:        "DOCTYPE not finished",
                    685:        "Sequence ']]>' not allowed in content",
                    686:        "CDATA not finished",
                    687:        "Reserved XML Name",
                    688:        "Space required",
                    689:        "XML_ERR_SEPARATOR_REQUIRED",
                    690:        "NmToken expected in ATTLIST enumeration",
                    691:        "XML_ERR_NAME_REQUIRED",
                    692:        "MixedContentDecl : '#PCDATA' expected",
                    693:        "SYSTEM or PUBLIC, the URI is missing",
                    694:        "PUBLIC, the Public Identifier is missing",
                    695:        "< required",
                    696:        "> required",
                    697:        "</ required",
                    698:        "= required",
                    699:        "Mismatched tag",
                    700:        "Tag not finished",
                    701:        "standalone accepts only 'yes' or 'no'",
                    702:        "Invalid XML encoding name",
                    703:        "Comment must not contain '--' (double-hyphen)",
                    704:        "Invalid encoding",
                    705:        "external parsed entities cannot be standalone",
                    706:        "XML conditional section '[' expected",
                    707:        "Entity value required",
                    708:        "chunk is not well balanced",
                    709:        "extra content at the end of well balanced chunk",
                    710:     "XML_ERR_ENTITY_CHAR_ERROR",
                    711:     "PEReferences forbidden in internal subset",
                    712:     "Detected an entity reference loop",
                    713:     "XML_ERR_ENTITY_BOUNDARY",
                    714:     "Invalid URI",
                    715:     "Fragment not allowed",
                    716:     "XML_WAR_CATALOG_PI",
                    717:     "XML_ERR_NO_DTD",
                    718:     "conditional section INCLUDE or IGNORE keyword expected", /* 95 */
                    719:     "Version in XML Declaration missing", /* 96 */
                    720:     "XML_WAR_UNKNOWN_VERSION", /* 97 */
                    721:     "XML_WAR_LANG_VALUE", /* 98 */
                    722:     "XML_WAR_NS_URI", /* 99 */
                    723:     "XML_WAR_NS_URI_RELATIVE", /* 100 */
                    724:     "Missing encoding in text declaration" /* 101 */
                    725: };
                    726: 
                    727: PHPAPI const XML_Char *
                    728: XML_ErrorString(int code)
                    729: {
                    730:        if (code < 0 || code >= (int)(sizeof(error_mapping) / sizeof(error_mapping[0]))) {
                    731:                return "Unknown";
                    732:        }
                    733:        return error_mapping[code];
                    734: }
                    735: 
                    736: PHPAPI int
                    737: XML_GetCurrentLineNumber(XML_Parser parser)
                    738: {
                    739:        return parser->parser->input->line;
                    740: }
                    741: 
                    742: PHPAPI int
                    743: XML_GetCurrentColumnNumber(XML_Parser parser)
                    744: {
                    745:        return parser->parser->input->col;
                    746: }
                    747: 
                    748: PHPAPI int
                    749: XML_GetCurrentByteIndex(XML_Parser parser)
                    750: {
                    751:        return parser->parser->input->consumed +
                    752:                        (parser->parser->input->cur - parser->parser->input->base);
                    753: }
                    754: 
                    755: PHPAPI int
                    756: XML_GetCurrentByteCount(XML_Parser parser)
                    757: {
                    758:        /* WARNING: this is identical to ByteIndex; it should probably
                    759:         * be different */
                    760:        return parser->parser->input->consumed +
                    761:                        (parser->parser->input->cur - parser->parser->input->base);
                    762: }
                    763: 
                    764: PHPAPI const XML_Char *XML_ExpatVersion(void)
                    765: {
                    766:        return "1.0";
                    767: }
                    768: 
                    769: PHPAPI void
                    770: XML_ParserFree(XML_Parser parser)
                    771: {
                    772:        if (parser->use_namespace) {
                    773:                if (parser->_ns_seperator) {
                    774:                        xmlFree(parser->_ns_seperator);
                    775:                }
                    776:        }
                    777:        if (parser->parser->myDoc) {
                    778:                xmlFreeDoc(parser->parser->myDoc);
                    779:                parser->parser->myDoc = NULL;
                    780:        }
                    781:        xmlFreeParserCtxt(parser->parser);
                    782:        efree(parser);
                    783: }
                    784: 
                    785: #endif /* LIBXML_EXPAT_COMPAT */
                    786: #endif
                    787: 
                    788: /**
                    789:  * Local Variables:
                    790:  * tab-width: 4
                    791:  * c-basic-offset: 4
                    792:  * indent-tabs-mode: t
                    793:  * End:
                    794:  * vim600: fdm=marker
                    795:  * vim: ts=4 noet sw=4
                    796:  */

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