Annotation of embedaddon/php/ext/soap/php_xml.c, revision 1.1.1.3

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

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