Annotation of embedaddon/php/ext/soap/php_xml.c, revision 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: Brad Lafountain <rodif_bl@yahoo.com>                        |
        !            16:   |          Shane Caraveo <shane@caraveo.com>                           |
        !            17:   |          Dmitry Stogov <dmitry@zend.com>                             |
        !            18:   +----------------------------------------------------------------------+
        !            19: */
        !            20: /* $Id: php_xml.c 321634 2012-01-01 13:15:04Z felipe $ */
        !            21: 
        !            22: #include "php_soap.h"
        !            23: #include "libxml/parser.h"
        !            24: #include "libxml/parserInternals.h"
        !            25: 
        !            26: /* Channel libxml file io layer through the PHP streams subsystem.
        !            27:  * This allows use of ftps:// and https:// urls */
        !            28: 
        !            29: static int is_blank(const xmlChar* str)
        !            30: {
        !            31:        while (*str != '\0') {
        !            32:                if (*str != ' '  && *str != 0x9 && *str != 0xa && *str != 0xd) {
        !            33:                        return 0;
        !            34:                }
        !            35:                str++;
        !            36:        }
        !            37:        return 1;
        !            38: }
        !            39: 
        !            40: /* removes all empty text, comments and other insignoficant nodes */
        !            41: static void cleanup_xml_node(xmlNodePtr node)
        !            42: {
        !            43:        xmlNodePtr trav;
        !            44:        xmlNodePtr del = NULL;
        !            45: 
        !            46:        trav = node->children;
        !            47:        while (trav != NULL) {
        !            48:                if (del != NULL) {
        !            49:                        xmlUnlinkNode(del);
        !            50:                        xmlFreeNode(del);
        !            51:                        del = NULL;
        !            52:                }
        !            53:                if (trav->type == XML_TEXT_NODE) {
        !            54:                        if (is_blank(trav->content)) {
        !            55:                                del = trav;
        !            56:                        }
        !            57:                } else if ((trav->type != XML_ELEMENT_NODE) &&
        !            58:                           (trav->type != XML_CDATA_SECTION_NODE)) {
        !            59:                        del = trav;
        !            60:                } else if (trav->children != NULL) {
        !            61:                        cleanup_xml_node(trav);
        !            62:                }
        !            63:                trav = trav->next;
        !            64:        }
        !            65:        if (del != NULL) {
        !            66:                xmlUnlinkNode(del);
        !            67:                xmlFreeNode(del);
        !            68:        }
        !            69: }
        !            70: 
        !            71: static void soap_ignorableWhitespace(void *ctx, const xmlChar *ch, int len)
        !            72: {
        !            73: }
        !            74: 
        !            75: static void soap_Comment(void *ctx, const xmlChar *value)
        !            76: {
        !            77: }
        !            78: 
        !            79: xmlDocPtr soap_xmlParseFile(const char *filename TSRMLS_DC)
        !            80: {
        !            81:        xmlParserCtxtPtr ctxt = NULL;
        !            82:        xmlDocPtr ret;
        !            83:        zend_bool old_allow_url_fopen;
        !            84: 
        !            85: /*
        !            86:        xmlInitParser();
        !            87: */
        !            88: 
        !            89:        old_allow_url_fopen = PG(allow_url_fopen);
        !            90:        PG(allow_url_fopen) = 1;
        !            91:        ctxt = xmlCreateFileParserCtxt(filename);
        !            92:        PG(allow_url_fopen) = old_allow_url_fopen;
        !            93:        if (ctxt) {
        !            94:                ctxt->keepBlanks = 0;
        !            95:                ctxt->sax->ignorableWhitespace = soap_ignorableWhitespace;
        !            96:                ctxt->sax->comment = soap_Comment;
        !            97:                ctxt->sax->warning = NULL;
        !            98:                ctxt->sax->error = NULL;
        !            99:                /*ctxt->sax->fatalError = NULL;*/
        !           100:                xmlParseDocument(ctxt);
        !           101:                if (ctxt->wellFormed) {
        !           102:                        ret = ctxt->myDoc;
        !           103:                        if (ret->URL == NULL && ctxt->directory != NULL) {
        !           104:                                ret->URL = xmlCharStrdup(ctxt->directory);
        !           105:                        }
        !           106:                } else {
        !           107:                        ret = NULL;
        !           108:                        xmlFreeDoc(ctxt->myDoc);
        !           109:                        ctxt->myDoc = NULL;
        !           110:                }
        !           111:                xmlFreeParserCtxt(ctxt);
        !           112:        } else {
        !           113:                ret = NULL;
        !           114:        }
        !           115: 
        !           116: /*
        !           117:        xmlCleanupParser();
        !           118: */
        !           119: 
        !           120:        if (ret) {
        !           121:                cleanup_xml_node((xmlNodePtr)ret);
        !           122:        }
        !           123:        return ret;
        !           124: }
        !           125: 
        !           126: xmlDocPtr soap_xmlParseMemory(const void *buf, size_t buf_size)
        !           127: {
        !           128:        xmlParserCtxtPtr ctxt = NULL;
        !           129:        xmlDocPtr ret;
        !           130: 
        !           131: /*
        !           132:        xmlInitParser();
        !           133: */
        !           134:        ctxt = xmlCreateMemoryParserCtxt(buf, buf_size);
        !           135:        if (ctxt) {
        !           136:                ctxt->sax->ignorableWhitespace = soap_ignorableWhitespace;
        !           137:                ctxt->sax->comment = soap_Comment;
        !           138:                ctxt->sax->warning = NULL;
        !           139:                ctxt->sax->error = NULL;
        !           140:                /*ctxt->sax->fatalError = NULL;*/
        !           141: #if LIBXML_VERSION >= 20703
        !           142:                ctxt->options |= XML_PARSE_HUGE;
        !           143: #endif
        !           144:                xmlParseDocument(ctxt);
        !           145:                if (ctxt->wellFormed) {
        !           146:                        ret = ctxt->myDoc;
        !           147:                        if (ret->URL == NULL && ctxt->directory != NULL) {
        !           148:                                ret->URL = xmlCharStrdup(ctxt->directory);
        !           149:                        }
        !           150:                } else {
        !           151:                        ret = NULL;
        !           152:                        xmlFreeDoc(ctxt->myDoc);
        !           153:                        ctxt->myDoc = NULL;
        !           154:                }
        !           155:                xmlFreeParserCtxt(ctxt);
        !           156:        } else {
        !           157:                ret = NULL;
        !           158:        }
        !           159: 
        !           160: /*
        !           161:        xmlCleanupParser();
        !           162: */
        !           163: 
        !           164: /*
        !           165:        if (ret) {
        !           166:                cleanup_xml_node((xmlNodePtr)ret);
        !           167:        }
        !           168: */
        !           169:        return ret;
        !           170: }
        !           171: 
        !           172: #ifndef ZEND_ENGINE_2
        !           173: int php_stream_xmlIO_match_wrapper(const char *filename)
        !           174: {
        !           175:        TSRMLS_FETCH();
        !           176:        return php_stream_locate_url_wrapper(filename, NULL, STREAM_LOCATE_WRAPPERS_ONLY TSRMLS_CC) ? 1 : 0;
        !           177: }
        !           178: 
        !           179: void *php_stream_xmlIO_open_wrapper(const char *filename)
        !           180: {
        !           181:        TSRMLS_FETCH();
        !           182:        return php_stream_open_wrapper((char*)filename, "rb", ENFORCE_SAFE_MODE|REPORT_ERRORS, NULL);
        !           183: }
        !           184: 
        !           185: int php_stream_xmlIO_read(void *context, char *buffer, int len)
        !           186: {
        !           187:        TSRMLS_FETCH();
        !           188:        return php_stream_read((php_stream*)context, buffer, len);
        !           189: }
        !           190: 
        !           191: int php_stream_xmlIO_close(void *context)
        !           192: {
        !           193:        TSRMLS_FETCH();
        !           194:        return php_stream_close((php_stream*)context);
        !           195: }
        !           196: #endif
        !           197: 
        !           198: xmlNsPtr attr_find_ns(xmlAttrPtr node)
        !           199: {
        !           200:        if (node->ns) {
        !           201:                return node->ns;
        !           202:        } else if (node->parent->ns) {
        !           203:                return node->parent->ns;
        !           204:        } else {
        !           205:                return xmlSearchNs(node->doc, node->parent, NULL);
        !           206:        }
        !           207: }
        !           208: 
        !           209: xmlNsPtr node_find_ns(xmlNodePtr node)
        !           210: {
        !           211:        if (node->ns) {
        !           212:                return node->ns;
        !           213:        } else {
        !           214:                return xmlSearchNs(node->doc, node, NULL);
        !           215:        }
        !           216: }
        !           217: 
        !           218: int attr_is_equal_ex(xmlAttrPtr node, char *name, char *ns)
        !           219: {
        !           220:        if (name == NULL || strcmp((char*)node->name, name) == 0) {
        !           221:                if (ns) {
        !           222:                        xmlNsPtr nsPtr = attr_find_ns(node);
        !           223:                        if (nsPtr) {
        !           224:                                return (strcmp((char*)nsPtr->href, ns) == 0);
        !           225:                        } else {
        !           226:                                return FALSE;
        !           227:                        }
        !           228:                }
        !           229:                return TRUE;
        !           230:        }
        !           231:        return FALSE;
        !           232: }
        !           233: 
        !           234: int node_is_equal_ex(xmlNodePtr node, char *name, char *ns)
        !           235: {
        !           236:        if (name == NULL || strcmp((char*)node->name, name) == 0) {
        !           237:                if (ns) {
        !           238:                        xmlNsPtr nsPtr = node_find_ns(node);
        !           239:                        if (nsPtr) {
        !           240:                                return (strcmp((char*)nsPtr->href, ns) == 0);
        !           241:                        } else {
        !           242:                                return FALSE;
        !           243:                        }
        !           244:                }
        !           245:                return TRUE;
        !           246:        }
        !           247:        return FALSE;
        !           248: }
        !           249: 
        !           250: 
        !           251: xmlAttrPtr get_attribute_ex(xmlAttrPtr node, char *name, char *ns)
        !           252: {
        !           253:        while (node!=NULL) {
        !           254:                if (attr_is_equal_ex(node, name, ns)) {
        !           255:                        return node;
        !           256:                }
        !           257:                node = node->next;
        !           258:        }
        !           259:        return NULL;
        !           260: }
        !           261: 
        !           262: xmlNodePtr get_node_ex(xmlNodePtr node, char *name, char *ns)
        !           263: {
        !           264:        while (node!=NULL) {
        !           265:                if (node_is_equal_ex(node, name, ns)) {
        !           266:                        return node;
        !           267:                }
        !           268:                node = node->next;
        !           269:        }
        !           270:        return NULL;
        !           271: }
        !           272: 
        !           273: xmlNodePtr get_node_recurisve_ex(xmlNodePtr node, char *name, char *ns)
        !           274: {
        !           275:        while (node != NULL) {
        !           276:                if (node_is_equal_ex(node, name, ns)) {
        !           277:                        return node;
        !           278:                } else if (node->children != NULL) {
        !           279:                        xmlNodePtr tmp = get_node_recurisve_ex(node->children, name, ns);
        !           280:                        if (tmp) {
        !           281:                                return tmp;
        !           282:                        }
        !           283:                }
        !           284:                node = node->next;
        !           285:        }
        !           286:        return NULL;
        !           287: }
        !           288: 
        !           289: xmlNodePtr get_node_with_attribute_ex(xmlNodePtr node, char *name, char *name_ns, char *attribute, char *value, char *attr_ns)
        !           290: {
        !           291:        xmlAttrPtr attr;
        !           292: 
        !           293:        while (node != NULL) {
        !           294:                if (name != NULL) {
        !           295:                        node = get_node_ex(node, name, name_ns);
        !           296:                        if (node==NULL) {
        !           297:                                return NULL;
        !           298:                        }
        !           299:                }
        !           300: 
        !           301:                attr = get_attribute_ex(node->properties, attribute, attr_ns);
        !           302:                if (attr != NULL && strcmp((char*)attr->children->content, value) == 0) {
        !           303:                        return node;
        !           304:                }
        !           305:                node = node->next;
        !           306:        }
        !           307:        return NULL;
        !           308: }
        !           309: 
        !           310: xmlNodePtr get_node_with_attribute_recursive_ex(xmlNodePtr node, char *name, char *name_ns, char *attribute, char *value, char *attr_ns)
        !           311: {
        !           312:        while (node != NULL) {
        !           313:                if (node_is_equal_ex(node, name, name_ns)) {
        !           314:                        xmlAttrPtr attr = get_attribute_ex(node->properties, attribute, attr_ns);
        !           315:                        if (attr != NULL && strcmp((char*)attr->children->content, value) == 0) {
        !           316:                                return node;
        !           317:                        }
        !           318:                }
        !           319:                if (node->children != NULL) {
        !           320:                        xmlNodePtr tmp = get_node_with_attribute_recursive_ex(node->children, name, name_ns, attribute, value, attr_ns);
        !           321:                        if (tmp) {
        !           322:                                return tmp;
        !           323:                        }
        !           324:                }
        !           325:                node = node->next;
        !           326:        }
        !           327:        return NULL;
        !           328: }
        !           329: 
        !           330: int parse_namespace(const xmlChar *inval, char **value, char **namespace)
        !           331: {
        !           332:        char *found = strrchr((char*)inval, ':');
        !           333: 
        !           334:        if (found != NULL && found != (char*)inval) {
        !           335:                (*namespace) = estrndup((char*)inval, found - (char*)inval);
        !           336:                (*value) = estrdup(++found);
        !           337:        } else {
        !           338:                (*value) = estrdup((char*)inval);
        !           339:                (*namespace) = NULL;
        !           340:        }
        !           341: 
        !           342:        return FALSE;
        !           343: }

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