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>