Annotation of embedaddon/php/ext/soap/php_xml.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: 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>