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>