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>