PageRenderTime 36ms CodeModel.GetById 8ms RepoModel.GetById 0ms app.codeStats 0ms

/php5/ext/soap/php_xml.c

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