root/ext/soap/php_xml.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. is_blank
  2. cleanup_xml_node
  3. soap_ignorableWhitespace
  4. soap_Comment
  5. soap_xmlParseFile
  6. soap_xmlParseMemory
  7. attr_find_ns
  8. node_find_ns
  9. attr_is_equal_ex
  10. node_is_equal_ex
  11. get_attribute_ex
  12. get_node_ex
  13. get_node_recurisve_ex
  14. get_node_with_attribute_ex
  15. get_node_with_attribute_recursive_ex
  16. parse_namespace

   1 /*
   2   +----------------------------------------------------------------------+
   3   | PHP Version 7                                                        |
   4   +----------------------------------------------------------------------+
   5   | Copyright (c) 1997-2016 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$ */
  21 
  22 #include "php_soap.h"
  23 #include "ext/libxml/php_libxml.h"
  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)
  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) {
  95                 zend_bool old;
  96 
  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;*/
 103 #if LIBXML_VERSION >= 20703
 104                 ctxt->options |= XML_PARSE_HUGE;
 105 #endif
 106                 old = php_libxml_disable_entity_loader(1);
 107                 xmlParseDocument(ctxt);
 108                 php_libxml_disable_entity_loader(old);
 109                 if (ctxt->wellFormed) {
 110                         ret = ctxt->myDoc;
 111                         if (ret->URL == NULL && ctxt->directory != NULL) {
 112                                 ret->URL = xmlCharStrdup(ctxt->directory);
 113                         }
 114                 } else {
 115                         ret = NULL;
 116                         xmlFreeDoc(ctxt->myDoc);
 117                         ctxt->myDoc = NULL;
 118                 }
 119                 xmlFreeParserCtxt(ctxt);
 120         } else {
 121                 ret = NULL;
 122         }
 123 
 124 /*
 125         xmlCleanupParser();
 126 */
 127 
 128         if (ret) {
 129                 cleanup_xml_node((xmlNodePtr)ret);
 130         }
 131         return ret;
 132 }
 133 
 134 xmlDocPtr soap_xmlParseMemory(const void *buf, size_t buf_size)
 135 {
 136         xmlParserCtxtPtr ctxt = NULL;
 137         xmlDocPtr ret;
 138 
 139 
 140 /*
 141         xmlInitParser();
 142 */
 143         ctxt = xmlCreateMemoryParserCtxt(buf, buf_size);
 144         if (ctxt) {
 145                 zend_bool old;
 146 
 147                 ctxt->sax->ignorableWhitespace = soap_ignorableWhitespace;
 148                 ctxt->sax->comment = soap_Comment;
 149                 ctxt->sax->warning = NULL;
 150                 ctxt->sax->error = NULL;
 151                 /*ctxt->sax->fatalError = NULL;*/
 152 #if LIBXML_VERSION >= 20703
 153                 ctxt->options |= XML_PARSE_HUGE;
 154 #endif
 155                 old = php_libxml_disable_entity_loader(1);
 156                 xmlParseDocument(ctxt);
 157                 php_libxml_disable_entity_loader(old);
 158                 if (ctxt->wellFormed) {
 159                         ret = ctxt->myDoc;
 160                         if (ret->URL == NULL && ctxt->directory != NULL) {
 161                                 ret->URL = xmlCharStrdup(ctxt->directory);
 162                         }
 163                 } else {
 164                         ret = NULL;
 165                         xmlFreeDoc(ctxt->myDoc);
 166                         ctxt->myDoc = NULL;
 167                 }
 168                 xmlFreeParserCtxt(ctxt);
 169         } else {
 170                 ret = NULL;
 171         }
 172 
 173 /*
 174         xmlCleanupParser();
 175 */
 176 
 177 /*
 178         if (ret) {
 179                 cleanup_xml_node((xmlNodePtr)ret);
 180         }
 181 */
 182         return ret;
 183 }
 184 
 185 xmlNsPtr attr_find_ns(xmlAttrPtr node)
 186 {
 187         if (node->ns) {
 188                 return node->ns;
 189         } else if (node->parent->ns) {
 190                 return node->parent->ns;
 191         } else {
 192                 return xmlSearchNs(node->doc, node->parent, NULL);
 193         }
 194 }
 195 
 196 xmlNsPtr node_find_ns(xmlNodePtr node)
 197 {
 198         if (node->ns) {
 199                 return node->ns;
 200         } else {
 201                 return xmlSearchNs(node->doc, node, NULL);
 202         }
 203 }
 204 
 205 int attr_is_equal_ex(xmlAttrPtr node, char *name, char *ns)
 206 {
 207         if (name == NULL || strcmp((char*)node->name, name) == 0) {
 208                 if (ns) {
 209                         xmlNsPtr nsPtr = attr_find_ns(node);
 210                         if (nsPtr) {
 211                                 return (strcmp((char*)nsPtr->href, ns) == 0);
 212                         } else {
 213                                 return FALSE;
 214                         }
 215                 }
 216                 return TRUE;
 217         }
 218         return FALSE;
 219 }
 220 
 221 int node_is_equal_ex(xmlNodePtr node, char *name, char *ns)
 222 {
 223         if (name == NULL || strcmp((char*)node->name, name) == 0) {
 224                 if (ns) {
 225                         xmlNsPtr nsPtr = node_find_ns(node);
 226                         if (nsPtr) {
 227                                 return (strcmp((char*)nsPtr->href, ns) == 0);
 228                         } else {
 229                                 return FALSE;
 230                         }
 231                 }
 232                 return TRUE;
 233         }
 234         return FALSE;
 235 }
 236 
 237 
 238 xmlAttrPtr get_attribute_ex(xmlAttrPtr node, char *name, char *ns)
 239 {
 240         while (node!=NULL) {
 241                 if (attr_is_equal_ex(node, name, ns)) {
 242                         return node;
 243                 }
 244                 node = node->next;
 245         }
 246         return NULL;
 247 }
 248 
 249 xmlNodePtr get_node_ex(xmlNodePtr node, char *name, char *ns)
 250 {
 251         while (node!=NULL) {
 252                 if (node_is_equal_ex(node, name, ns)) {
 253                         return node;
 254                 }
 255                 node = node->next;
 256         }
 257         return NULL;
 258 }
 259 
 260 xmlNodePtr get_node_recurisve_ex(xmlNodePtr node, char *name, char *ns)
 261 {
 262         while (node != NULL) {
 263                 if (node_is_equal_ex(node, name, ns)) {
 264                         return node;
 265                 } else if (node->children != NULL) {
 266                         xmlNodePtr tmp = get_node_recurisve_ex(node->children, name, ns);
 267                         if (tmp) {
 268                                 return tmp;
 269                         }
 270                 }
 271                 node = node->next;
 272         }
 273         return NULL;
 274 }
 275 
 276 xmlNodePtr get_node_with_attribute_ex(xmlNodePtr node, char *name, char *name_ns, char *attribute, char *value, char *attr_ns)
 277 {
 278         xmlAttrPtr attr;
 279 
 280         while (node != NULL) {
 281                 if (name != NULL) {
 282                         node = get_node_ex(node, name, name_ns);
 283                         if (node==NULL) {
 284                                 return NULL;
 285                         }
 286                 }
 287 
 288                 attr = get_attribute_ex(node->properties, attribute, attr_ns);
 289                 if (attr != NULL && strcmp((char*)attr->children->content, value) == 0) {
 290                         return node;
 291                 }
 292                 node = node->next;
 293         }
 294         return NULL;
 295 }
 296 
 297 xmlNodePtr get_node_with_attribute_recursive_ex(xmlNodePtr node, char *name, char *name_ns, char *attribute, char *value, char *attr_ns)
 298 {
 299         while (node != NULL) {
 300                 if (node_is_equal_ex(node, name, name_ns)) {
 301                         xmlAttrPtr 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                 }
 306                 if (node->children != NULL) {
 307                         xmlNodePtr tmp = get_node_with_attribute_recursive_ex(node->children, name, name_ns, attribute, value, attr_ns);
 308                         if (tmp) {
 309                                 return tmp;
 310                         }
 311                 }
 312                 node = node->next;
 313         }
 314         return NULL;
 315 }
 316 
 317 int parse_namespace(const xmlChar *inval, char **value, char **namespace)
 318 {
 319         char *found = strrchr((char*)inval, ':');
 320 
 321         if (found != NULL && found != (char*)inval) {
 322                 (*namespace) = estrndup((char*)inval, found - (char*)inval);
 323                 (*value) = estrdup(++found);
 324         } else {
 325                 (*value) = estrdup((char*)inval);
 326                 (*namespace) = NULL;
 327         }
 328 
 329         return FALSE;
 330 }

/* [<][>][^][v][top][bottom][index][help] */