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_sdl.c 287425 2009-08-17 18:23:48Z dmitry $ */
21 :
22 : #include "php_soap.h"
23 : #include "ext/libxml/php_libxml.h"
24 : #include "libxml/uri.h"
25 :
26 : #include "ext/standard/md5.h"
27 : #include "tsrm_virtual_cwd.h"
28 :
29 : #include <sys/types.h>
30 : #include <sys/stat.h>
31 : #include <fcntl.h>
32 :
33 : #ifndef O_BINARY
34 : # define O_BINARY 0
35 : #endif
36 :
37 : static void delete_fault(void *fault);
38 : static void delete_fault_persistent(void *fault);
39 : static void delete_binding(void *binding);
40 : static void delete_binding_persistent(void *binding);
41 : static void delete_function(void *function);
42 : static void delete_function_persistent(void *function);
43 : static void delete_parameter(void *paramater);
44 : static void delete_parameter_persistent(void *paramater);
45 : static void delete_header(void *header);
46 : static void delete_header_persistent(void *header);
47 : static void delete_document(void *doc_ptr);
48 :
49 : encodePtr get_encoder_from_prefix(sdlPtr sdl, xmlNodePtr node, const xmlChar *type)
50 10673 : {
51 10673 : encodePtr enc = NULL;
52 : xmlNsPtr nsptr;
53 : char *ns, *cptype;
54 :
55 10673 : parse_namespace(type, &cptype, &ns);
56 10673 : nsptr = xmlSearchNs(node->doc, node, BAD_CAST(ns));
57 10673 : if (nsptr != NULL) {
58 10650 : enc = get_encoder(sdl, (char*)nsptr->href, cptype);
59 10650 : if (enc == NULL) {
60 7 : enc = get_encoder_ex(sdl, cptype, strlen(cptype));
61 : }
62 : } else {
63 23 : enc = get_encoder_ex(sdl, (char*)type, xmlStrlen(type));
64 : }
65 10673 : efree(cptype);
66 10673 : if (ns) {efree(ns);}
67 10673 : return enc;
68 : }
69 :
70 : static sdlTypePtr get_element(sdlPtr sdl, xmlNodePtr node, const xmlChar *type)
71 10167 : {
72 10167 : sdlTypePtr ret = NULL;
73 :
74 10167 : if (sdl->elements) {
75 : xmlNsPtr nsptr;
76 : char *ns, *cptype;
77 : sdlTypePtr *sdl_type;
78 :
79 10166 : parse_namespace(type, &cptype, &ns);
80 10166 : nsptr = xmlSearchNs(node->doc, node, BAD_CAST(ns));
81 10166 : if (nsptr != NULL) {
82 10166 : int ns_len = xmlStrlen(nsptr->href);
83 10166 : int type_len = strlen(cptype);
84 10166 : int len = ns_len + type_len + 1;
85 10166 : char *nscat = emalloc(len + 1);
86 :
87 10166 : memcpy(nscat, nsptr->href, ns_len);
88 10166 : nscat[ns_len] = ':';
89 10166 : memcpy(nscat+ns_len+1, cptype, type_len);
90 10166 : nscat[len] = '\0';
91 :
92 10166 : if (zend_hash_find(sdl->elements, nscat, len + 1, (void **)&sdl_type) == SUCCESS) {
93 10166 : ret = *sdl_type;
94 0 : } else if (zend_hash_find(sdl->elements, (char*)type, type_len + 1, (void **)&sdl_type) == SUCCESS) {
95 0 : ret = *sdl_type;
96 : }
97 10166 : efree(nscat);
98 : } else {
99 0 : if (zend_hash_find(sdl->elements, (char*)type, xmlStrlen(type) + 1, (void **)&sdl_type) == SUCCESS) {
100 0 : ret = *sdl_type;
101 : }
102 : }
103 :
104 10166 : efree(cptype);
105 10166 : if (ns) {efree(ns);}
106 : }
107 10167 : return ret;
108 : }
109 :
110 : encodePtr get_encoder(sdlPtr sdl, const char *ns, const char *type)
111 24157 : {
112 24157 : encodePtr enc = NULL;
113 : char *nscat;
114 24157 : int ns_len = strlen(ns);
115 24157 : int type_len = strlen(type);
116 24157 : int len = ns_len + type_len + 1;
117 :
118 24157 : nscat = emalloc(len + 1);
119 24157 : memcpy(nscat, ns, ns_len);
120 24157 : nscat[ns_len] = ':';
121 24157 : memcpy(nscat+ns_len+1, type, type_len);
122 24157 : nscat[len] = '\0';
123 :
124 24157 : enc = get_encoder_ex(sdl, nscat, len);
125 :
126 24157 : if (enc == NULL &&
127 : ((ns_len == sizeof(SOAP_1_1_ENC_NAMESPACE)-1 &&
128 : memcmp(ns, SOAP_1_1_ENC_NAMESPACE, sizeof(SOAP_1_1_ENC_NAMESPACE)-1) == 0) ||
129 : (ns_len == sizeof(SOAP_1_2_ENC_NAMESPACE)-1 &&
130 : memcmp(ns, SOAP_1_2_ENC_NAMESPACE, sizeof(SOAP_1_2_ENC_NAMESPACE)-1) == 0))) {
131 : char *enc_nscat;
132 : int enc_ns_len;
133 : int enc_len;
134 :
135 4 : enc_ns_len = sizeof(XSD_NAMESPACE)-1;
136 4 : enc_len = enc_ns_len + type_len + 1;
137 4 : enc_nscat = emalloc(enc_len + 1);
138 4 : memcpy(enc_nscat, XSD_NAMESPACE, sizeof(XSD_NAMESPACE)-1);
139 4 : enc_nscat[enc_ns_len] = ':';
140 4 : memcpy(enc_nscat+enc_ns_len+1, type, type_len);
141 4 : enc_nscat[enc_len] = '\0';
142 :
143 4 : enc = get_encoder_ex(NULL, enc_nscat, enc_len);
144 4 : efree(enc_nscat);
145 4 : if (enc && sdl) {
146 4 : encodePtr new_enc = pemalloc(sizeof(encode), sdl->is_persistent);
147 4 : memcpy(new_enc, enc, sizeof(encode));
148 4 : if (sdl->is_persistent) {
149 2 : new_enc->details.ns = zend_strndup(ns, ns_len);
150 2 : new_enc->details.type_str = strdup(new_enc->details.type_str);
151 : } else {
152 2 : new_enc->details.ns = estrndup(ns, ns_len);
153 2 : new_enc->details.type_str = estrdup(new_enc->details.type_str);
154 : }
155 4 : if (sdl->encoders == NULL) {
156 0 : sdl->encoders = pemalloc(sizeof(HashTable), sdl->is_persistent);
157 0 : zend_hash_init(sdl->encoders, 0, NULL, delete_encoder, sdl->is_persistent);
158 : }
159 4 : zend_hash_update(sdl->encoders, nscat, len + 1, &new_enc, sizeof(encodePtr), NULL);
160 4 : enc = new_enc;
161 : }
162 : }
163 24157 : efree(nscat);
164 24157 : return enc;
165 : }
166 :
167 : encodePtr get_encoder_ex(sdlPtr sdl, const char *nscat, int len)
168 24193 : {
169 : encodePtr *enc;
170 : TSRMLS_FETCH();
171 :
172 24193 : if (zend_hash_find(&SOAP_GLOBAL(defEnc), (char*)nscat, len + 1, (void **)&enc) == SUCCESS) {
173 15687 : return (*enc);
174 8506 : } else if (sdl && sdl->encoders && zend_hash_find(sdl->encoders, (char*)nscat, len + 1, (void **)&enc) == SUCCESS) {
175 6806 : return (*enc);
176 : }
177 1700 : return NULL;
178 : }
179 :
180 : sdlBindingPtr get_binding_from_type(sdlPtr sdl, int type)
181 0 : {
182 : sdlBindingPtr *binding;
183 :
184 0 : if (sdl == NULL) {
185 0 : return NULL;
186 : }
187 :
188 0 : for (zend_hash_internal_pointer_reset(sdl->bindings);
189 0 : zend_hash_get_current_data(sdl->bindings, (void **) &binding) == SUCCESS;
190 0 : zend_hash_move_forward(sdl->bindings)) {
191 0 : if ((*binding)->bindingType == type) {
192 0 : return *binding;
193 : }
194 : }
195 0 : return NULL;
196 : }
197 :
198 : sdlBindingPtr get_binding_from_name(sdlPtr sdl, char *name, char *ns)
199 0 : {
200 0 : sdlBindingPtr binding = NULL;
201 0 : smart_str key = {0};
202 :
203 0 : smart_str_appends(&key, ns);
204 0 : smart_str_appendc(&key, ':');
205 0 : smart_str_appends(&key, name);
206 0 : smart_str_0(&key);
207 :
208 0 : zend_hash_find(sdl->bindings, key.c, key.len, (void **)&binding);
209 :
210 0 : smart_str_free(&key);
211 0 : return binding;
212 : }
213 :
214 : static int is_wsdl_element(xmlNodePtr node)
215 40652 : {
216 40652 : if (node->ns && strcmp((char*)node->ns->href, WSDL_NAMESPACE) != 0) {
217 : xmlAttrPtr attr;
218 117 : if ((attr = get_attribute_ex(node->properties, "required", WSDL_NAMESPACE)) != NULL &&
219 : attr->children && attr->children->content &&
220 : (strcmp((char*)attr->children->content, "1") == 0 ||
221 : strcmp((char*)attr->children->content, "true") == 0)) {
222 1 : soap_error1(E_ERROR, "Parsing WSDL: Unknown required WSDL extension '%s'", node->ns->href);
223 : }
224 116 : return 0;
225 : }
226 40535 : return 1;
227 : }
228 :
229 : void sdl_set_uri_credentials(sdlCtx *ctx, char *uri TSRMLS_DC)
230 718 : {
231 : char *s;
232 : int l1, l2;
233 718 : zval *context = NULL;
234 718 : zval **header = NULL;
235 :
236 : /* check if we load xsd from the same server */
237 718 : s = strstr(ctx->sdl->source, "://");
238 718 : if (!s) return;
239 2 : s = strchr(s+3, '/');
240 2 : l1 = s - ctx->sdl->source;
241 2 : s = strstr((char*)uri, "://");
242 2 : if (!s) return;
243 2 : s = strchr(s+3, '/');
244 2 : l2 = s - (char*)uri;
245 2 : if (l1 != l2 || memcmp(ctx->sdl->source, uri, l1) != 0) {
246 : /* another server. clear authentication credentals */
247 2 : context = php_libxml_switch_context(NULL TSRMLS_CC);
248 2 : php_libxml_switch_context(context TSRMLS_CC);
249 2 : if (context) {
250 0 : ctx->context = php_stream_context_from_zval(context, 1);
251 :
252 0 : if (ctx->context &&
253 : php_stream_context_get_option(ctx->context, "http", "header", &header) == SUCCESS) {
254 0 : s = strstr(Z_STRVAL_PP(header), "Authorization: Basic");
255 0 : if (s && (s == Z_STRVAL_PP(header) || *(s-1) == '\n' || *(s-1) == '\r')) {
256 0 : char *rest = strstr(s, "\r\n");
257 0 : if (rest) {
258 : zval new_header;
259 :
260 0 : rest += 2;
261 0 : Z_TYPE(new_header) = IS_STRING;
262 0 : Z_STRLEN(new_header) = Z_STRLEN_PP(header) - (rest - s);
263 0 : Z_STRVAL(new_header) = emalloc(Z_STRLEN_PP(header) + 1);
264 0 : memcpy(Z_STRVAL(new_header), Z_STRVAL_PP(header), s - Z_STRVAL_PP(header));
265 0 : memcpy(Z_STRVAL(new_header) + (s - Z_STRVAL_PP(header)), rest, Z_STRLEN_PP(header) - (rest - Z_STRVAL_PP(header)) + 1);
266 0 : ctx->old_header = *header;
267 0 : ctx->old_header->refcount++;
268 0 : php_stream_context_set_option(ctx->context, "http", "header", &new_header);
269 0 : zval_dtor(&new_header);
270 : }
271 : }
272 : }
273 : }
274 : }
275 : }
276 :
277 : void sdl_restore_uri_credentials(sdlCtx *ctx TSRMLS_DC)
278 718 : {
279 718 : if (ctx->old_header) {
280 0 : php_stream_context_set_option(ctx->context, "http", "header", ctx->old_header);
281 0 : zval_ptr_dtor(&ctx->old_header);
282 0 : ctx->old_header = NULL;
283 : }
284 718 : ctx->context = NULL;
285 718 : }
286 :
287 : static void load_wsdl_ex(zval *this_ptr, char *struri, sdlCtx *ctx, int include TSRMLS_DC)
288 718 : {
289 718 : sdlPtr tmpsdl = ctx->sdl;
290 : xmlDocPtr wsdl;
291 : xmlNodePtr root, definitions, trav;
292 : xmlAttrPtr targetNamespace;
293 :
294 718 : if (zend_hash_exists(&ctx->docs, struri, strlen(struri)+1)) {
295 4 : return;
296 : }
297 :
298 714 : sdl_set_uri_credentials(ctx, struri TSRMLS_CC);
299 714 : wsdl = soap_xmlParseFile(struri TSRMLS_CC);
300 714 : sdl_restore_uri_credentials(ctx TSRMLS_CC);
301 :
302 714 : if (!wsdl) {
303 2 : xmlErrorPtr xmlErrorPtr = xmlGetLastError();
304 2 : if (xmlErrorPtr) {
305 2 : soap_error2(E_ERROR, "Parsing WSDL: Couldn't load from '%s' : %s", struri, xmlErrorPtr->message);
306 : } else {
307 0 : soap_error1(E_ERROR, "Parsing WSDL: Couldn't load from '%s'", struri);
308 : }
309 : }
310 :
311 712 : zend_hash_add(&ctx->docs, struri, strlen(struri)+1, (void**)&wsdl, sizeof(xmlDocPtr), NULL);
312 :
313 712 : root = wsdl->children;
314 712 : definitions = get_node_ex(root, "definitions", WSDL_NAMESPACE);
315 712 : if (!definitions) {
316 6 : if (include) {
317 6 : xmlNodePtr schema = get_node_ex(root, "schema", XSD_NAMESPACE);
318 6 : if (schema) {
319 6 : load_schema(ctx, schema TSRMLS_CC);
320 6 : return;
321 : }
322 : }
323 0 : soap_error1(E_ERROR, "Parsing WSDL: Couldn't find <definitions> in '%s'", struri);
324 : }
325 :
326 706 : if (!include) {
327 693 : targetNamespace = get_attribute(definitions->properties, "targetNamespace");
328 693 : if (targetNamespace) {
329 693 : tmpsdl->target_ns = estrdup((char*)targetNamespace->children->content);
330 : }
331 : }
332 :
333 706 : trav = definitions->children;
334 17357 : while (trav != NULL) {
335 15945 : if (!is_wsdl_element(trav)) {
336 35 : trav = trav->next;
337 35 : continue;
338 : }
339 15910 : if (node_is_equal(trav,"types")) {
340 : /* TODO: Only one "types" is allowed */
341 673 : xmlNodePtr trav2 = trav->children;
342 :
343 2448 : while (trav2 != NULL) {
344 1102 : if (node_is_equal_ex(trav2, "schema", XSD_NAMESPACE)) {
345 1095 : load_schema(ctx, trav2 TSRMLS_CC);
346 7 : } else if (is_wsdl_element(trav2) && !node_is_equal(trav2,"documentation")) {
347 0 : soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav2->name);
348 : }
349 1102 : trav2 = trav2->next;
350 : }
351 15237 : } else if (node_is_equal(trav,"import")) {
352 : /* TODO: namespace ??? */
353 23 : xmlAttrPtr tmp = get_attribute(trav->properties, "location");
354 23 : if (tmp) {
355 : xmlChar *uri;
356 23 : xmlChar *base = xmlNodeGetBase(trav->doc, trav);
357 :
358 23 : if (base == NULL) {
359 0 : uri = xmlBuildURI(tmp->children->content, trav->doc->URL);
360 : } else {
361 23 : uri = xmlBuildURI(tmp->children->content, base);
362 23 : xmlFree(base);
363 : }
364 23 : load_wsdl_ex(this_ptr, (char*)uri, ctx, 1 TSRMLS_CC);
365 23 : xmlFree(uri);
366 : }
367 :
368 15214 : } else if (node_is_equal(trav,"message")) {
369 12883 : xmlAttrPtr name = get_attribute(trav->properties, "name");
370 25766 : if (name && name->children && name->children->content) {
371 12883 : if (zend_hash_add(&ctx->messages, (char*)name->children->content, xmlStrlen(name->children->content)+1,&trav, sizeof(xmlNodePtr), NULL) != SUCCESS) {
372 0 : soap_error1(E_ERROR, "Parsing WSDL: <message> '%s' already defined", name->children->content);
373 : }
374 : } else {
375 0 : soap_error0(E_ERROR, "Parsing WSDL: <message> hasn't name attribute");
376 : }
377 :
378 2331 : } else if (node_is_equal(trav,"portType")) {
379 775 : xmlAttrPtr name = get_attribute(trav->properties, "name");
380 1550 : if (name && name->children && name->children->content) {
381 775 : if (zend_hash_add(&ctx->portTypes, (char*)name->children->content, xmlStrlen(name->children->content)+1,&trav, sizeof(xmlNodePtr), NULL) != SUCCESS) {
382 0 : soap_error1(E_ERROR, "Parsing WSDL: <portType> '%s' already defined", name->children->content);
383 : }
384 : } else {
385 0 : soap_error0(E_ERROR, "Parsing WSDL: <portType> hasn't name attribute");
386 : }
387 :
388 1556 : } else if (node_is_equal(trav,"binding")) {
389 857 : xmlAttrPtr name = get_attribute(trav->properties, "name");
390 1714 : if (name && name->children && name->children->content) {
391 857 : if (zend_hash_add(&ctx->bindings, (char*)name->children->content, xmlStrlen(name->children->content)+1,&trav, sizeof(xmlNodePtr), NULL) != SUCCESS) {
392 0 : soap_error1(E_ERROR, "Parsing WSDL: <binding> '%s' already defined", name->children->content);
393 : }
394 : } else {
395 0 : soap_error0(E_ERROR, "Parsing WSDL: <binding> hasn't name attribute");
396 : }
397 :
398 699 : } else if (node_is_equal(trav,"service")) {
399 698 : xmlAttrPtr name = get_attribute(trav->properties, "name");
400 1396 : if (name && name->children && name->children->content) {
401 698 : if (zend_hash_add(&ctx->services, (char*)name->children->content, xmlStrlen(name->children->content)+1,&trav, sizeof(xmlNodePtr), NULL) != SUCCESS) {
402 0 : soap_error1(E_ERROR, "Parsing WSDL: <service> '%s' already defined", name->children->content);
403 : }
404 : } else {
405 0 : soap_error0(E_ERROR, "Parsing WSDL: <service> hasn't name attribute");
406 : }
407 1 : } else if (!node_is_equal(trav,"documentation")) {
408 0 : soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name);
409 : }
410 15910 : trav = trav->next;
411 : }
412 : }
413 :
414 : static sdlSoapBindingFunctionHeaderPtr wsdl_soap_binding_header(sdlCtx* ctx, xmlNodePtr header, char* wsdl_soap_namespace, int fault)
415 1619 : {
416 : xmlAttrPtr tmp;
417 : xmlNodePtr *message, part;
418 : char *ctype;
419 : sdlSoapBindingFunctionHeaderPtr h;
420 :
421 1619 : tmp = get_attribute(header->properties, "message");
422 1619 : if (!tmp) {
423 0 : soap_error0(E_ERROR, "Parsing WSDL: Missing message attribute for <header>");
424 : }
425 :
426 1619 : ctype = strrchr((char*)tmp->children->content,':');
427 1619 : if (ctype == NULL) {
428 0 : ctype = (char*)tmp->children->content;
429 : } else {
430 1619 : ++ctype;
431 : }
432 1619 : if (zend_hash_find(&ctx->messages, ctype, strlen(ctype)+1, (void**)&message) != SUCCESS) {
433 0 : soap_error1(E_ERROR, "Parsing WSDL: Missing <message> with name '%s'", tmp->children->content);
434 : }
435 :
436 1619 : tmp = get_attribute(header->properties, "part");
437 1619 : if (!tmp) {
438 0 : soap_error0(E_ERROR, "Parsing WSDL: Missing part attribute for <header>");
439 : }
440 1619 : part = get_node_with_attribute_ex((*message)->children, "part", WSDL_NAMESPACE, "name", (char*)tmp->children->content, NULL);
441 1619 : if (!part) {
442 0 : soap_error1(E_ERROR, "Parsing WSDL: Missing part '%s' in <message>", tmp->children->content);
443 : }
444 :
445 1619 : h = emalloc(sizeof(sdlSoapBindingFunctionHeader));
446 1619 : memset(h, 0, sizeof(sdlSoapBindingFunctionHeader));
447 1619 : h->name = estrdup((char*)tmp->children->content);
448 :
449 1619 : tmp = get_attribute(header->properties, "use");
450 1774 : if (tmp && !strncmp((char*)tmp->children->content, "encoded", sizeof("encoded"))) {
451 155 : h->use = SOAP_ENCODED;
452 : } else {
453 1464 : h->use = SOAP_LITERAL;
454 : }
455 :
456 1619 : tmp = get_attribute(header->properties, "namespace");
457 1619 : if (tmp) {
458 148 : h->ns = estrdup((char*)tmp->children->content);
459 : }
460 :
461 1619 : if (h->use == SOAP_ENCODED) {
462 155 : tmp = get_attribute(header->properties, "encodingStyle");
463 155 : if (tmp) {
464 155 : if (strncmp((char*)tmp->children->content, SOAP_1_1_ENC_NAMESPACE, sizeof(SOAP_1_1_ENC_NAMESPACE)) == 0) {
465 9 : h->encodingStyle = SOAP_ENCODING_1_1;
466 146 : } else if (strncmp((char*)tmp->children->content, SOAP_1_2_ENC_NAMESPACE, sizeof(SOAP_1_2_ENC_NAMESPACE)) == 0) {
467 146 : h->encodingStyle = SOAP_ENCODING_1_2;
468 : } else {
469 0 : soap_error1(E_ERROR, "Parsing WSDL: Unknown encodingStyle '%s'", tmp->children->content);
470 : }
471 : } else {
472 0 : soap_error0(E_ERROR, "Parsing WSDL: Unspecified encodingStyle");
473 : }
474 : }
475 :
476 1619 : tmp = get_attribute(part->properties, "type");
477 1619 : if (tmp != NULL) {
478 155 : h->encode = get_encoder_from_prefix(ctx->sdl, part, tmp->children->content);
479 : } else {
480 1464 : tmp = get_attribute(part->properties, "element");
481 1464 : if (tmp != NULL) {
482 1464 : h->element = get_element(ctx->sdl, part, tmp->children->content);
483 1464 : if (h->element) {
484 1464 : h->encode = h->element->encode;
485 1464 : if (!h->ns && h->element->namens) {
486 1464 : h->ns = estrdup(h->element->namens);
487 : }
488 1464 : if (h->element->name) {
489 1464 : efree(h->name);
490 1464 : h->name = estrdup(h->element->name);
491 : }
492 : }
493 : }
494 : }
495 1619 : if (!fault) {
496 1546 : xmlNodePtr trav = header->children;
497 3165 : while (trav != NULL) {
498 73 : if (node_is_equal_ex(trav, "headerfault", wsdl_soap_namespace)) {
499 73 : sdlSoapBindingFunctionHeaderPtr hf = wsdl_soap_binding_header(ctx, trav, wsdl_soap_namespace, 1);
500 73 : smart_str key = {0};
501 :
502 73 : if (h->headerfaults == NULL) {
503 73 : h->headerfaults = emalloc(sizeof(HashTable));
504 73 : zend_hash_init(h->headerfaults, 0, NULL, delete_header, 0);
505 : }
506 :
507 73 : if (hf->ns) {
508 73 : smart_str_appends(&key,hf->ns);
509 73 : smart_str_appendc(&key,':');
510 : }
511 73 : smart_str_appends(&key,hf->name);
512 73 : smart_str_0(&key);
513 73 : if (zend_hash_add(h->headerfaults, key.c, key.len+1, (void**)&hf, sizeof(sdlSoapBindingFunctionHeaderPtr), NULL) != SUCCESS) {
514 0 : delete_header((void**)&hf);
515 : }
516 73 : smart_str_free(&key);
517 0 : } else if (is_wsdl_element(trav) && !node_is_equal(trav,"documentation")) {
518 0 : soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name);
519 : }
520 73 : trav = trav->next;
521 : }
522 : }
523 1619 : return h;
524 : }
525 :
526 : static void wsdl_soap_binding_body(sdlCtx* ctx, xmlNodePtr node, char* wsdl_soap_namespace, sdlSoapBindingFunctionBody *binding, HashTable* params)
527 14928 : {
528 : xmlNodePtr body, trav;
529 : xmlAttrPtr tmp;
530 :
531 14928 : trav = node->children;
532 46342 : while (trav != NULL) {
533 16486 : if (node_is_equal_ex(trav, "body", wsdl_soap_namespace)) {
534 14928 : body = trav;
535 :
536 14928 : tmp = get_attribute(body->properties, "use");
537 23226 : if (tmp && !strncmp((char*)tmp->children->content, "literal", sizeof("literal"))) {
538 8298 : binding->use = SOAP_LITERAL;
539 : } else {
540 6630 : binding->use = SOAP_ENCODED;
541 : }
542 :
543 14928 : tmp = get_attribute(body->properties, "namespace");
544 14928 : if (tmp) {
545 6773 : binding->ns = estrdup((char*)tmp->children->content);
546 : }
547 :
548 14928 : tmp = get_attribute(body->properties, "parts");
549 14928 : if (tmp) {
550 : HashTable ht;
551 0 : char *parts = (char*)tmp->children->content;
552 :
553 : /* Delete all parts those are not in the "parts" attribute */
554 0 : zend_hash_init(&ht, 0, NULL, delete_parameter, 0);
555 0 : while (*parts) {
556 : HashPosition pos;
557 : sdlParamPtr *param;
558 0 : int found = 0;
559 : char *end;
560 :
561 0 : while (*parts == ' ') ++parts;
562 0 : if (*parts == '\0') break;
563 0 : end = strchr(parts, ' ');
564 0 : if (end) *end = '\0';
565 0 : zend_hash_internal_pointer_reset_ex(params, &pos);
566 0 : while (zend_hash_get_current_data_ex(params, (void **)¶m, &pos) != FAILURE) {
567 0 : if ((*param)->paramName &&
568 : strcmp(parts, (*param)->paramName) == 0) {
569 : sdlParamPtr x_param;
570 0 : x_param = emalloc(sizeof(sdlParam));
571 0 : *x_param = **param;
572 0 : (*param)->paramName = NULL;
573 0 : zend_hash_next_index_insert(&ht, &x_param, sizeof(sdlParamPtr), NULL);
574 0 : found = 1;
575 0 : break;
576 : }
577 0 : zend_hash_move_forward_ex(params, &pos);
578 : }
579 0 : if (!found) {
580 0 : soap_error1(E_ERROR, "Parsing WSDL: Missing part '%s' in <message>", parts);
581 : }
582 0 : parts += strlen(parts);
583 0 : if (end) *end = ' ';
584 : }
585 0 : zend_hash_destroy(params);
586 0 : *params = ht;
587 : }
588 :
589 14928 : if (binding->use == SOAP_ENCODED) {
590 6630 : tmp = get_attribute(body->properties, "encodingStyle");
591 6630 : if (tmp) {
592 6630 : if (strncmp((char*)tmp->children->content, SOAP_1_1_ENC_NAMESPACE, sizeof(SOAP_1_1_ENC_NAMESPACE)) == 0) {
593 4002 : binding->encodingStyle = SOAP_ENCODING_1_1;
594 2628 : } else if (strncmp((char*)tmp->children->content, SOAP_1_2_ENC_NAMESPACE, sizeof(SOAP_1_2_ENC_NAMESPACE)) == 0) {
595 2628 : binding->encodingStyle = SOAP_ENCODING_1_2;
596 : } else {
597 0 : soap_error1(E_ERROR, "Parsing WSDL: Unknown encodingStyle '%s'", tmp->children->content);
598 : }
599 : } else {
600 0 : soap_error0(E_ERROR, "Parsing WSDL: Unspecified encodingStyle");
601 : }
602 : }
603 1558 : } else if (node_is_equal_ex(trav, "header", wsdl_soap_namespace)) {
604 1546 : sdlSoapBindingFunctionHeaderPtr h = wsdl_soap_binding_header(ctx, trav, wsdl_soap_namespace, 0);
605 1546 : smart_str key = {0};
606 :
607 1546 : if (binding->headers == NULL) {
608 888 : binding->headers = emalloc(sizeof(HashTable));
609 888 : zend_hash_init(binding->headers, 0, NULL, delete_header, 0);
610 : }
611 :
612 1546 : if (h->ns) {
613 1539 : smart_str_appends(&key,h->ns);
614 1539 : smart_str_appendc(&key,':');
615 : }
616 1546 : smart_str_appends(&key,h->name);
617 1546 : smart_str_0(&key);
618 1546 : if (zend_hash_add(binding->headers, key.c, key.len+1, (void**)&h, sizeof(sdlSoapBindingFunctionHeaderPtr), NULL) != SUCCESS) {
619 0 : delete_header((void**)&h);
620 : }
621 1546 : smart_str_free(&key);
622 12 : } else if (is_wsdl_element(trav) && !node_is_equal(trav,"documentation")) {
623 0 : soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name);
624 : }
625 16486 : trav = trav->next;
626 : }
627 14928 : }
628 :
629 : static HashTable* wsdl_message(sdlCtx *ctx, xmlChar* message_name)
630 16140 : {
631 16140 : xmlNodePtr trav, part, message = NULL, *tmp;
632 16140 : HashTable* parameters = NULL;
633 : char *ctype;
634 :
635 16140 : ctype = strrchr((char*)message_name,':');
636 16140 : if (ctype == NULL) {
637 179 : ctype = (char*)message_name;
638 : } else {
639 15961 : ++ctype;
640 : }
641 16140 : if (zend_hash_find(&ctx->messages, ctype, strlen(ctype)+1, (void**)&tmp) != SUCCESS) {
642 0 : soap_error1(E_ERROR, "Parsing WSDL: Missing <message> with name '%s'", message_name);
643 : }
644 16140 : message = *tmp;
645 :
646 16140 : parameters = emalloc(sizeof(HashTable));
647 16140 : zend_hash_init(parameters, 0, NULL, delete_parameter, 0);
648 :
649 16140 : trav = message->children;
650 48302 : while (trav != NULL) {
651 : xmlAttrPtr element, type, name;
652 : sdlParamPtr param;
653 :
654 16022 : if (trav->ns != NULL && strcmp((char*)trav->ns->href, WSDL_NAMESPACE) != 0) {
655 0 : soap_error1(E_ERROR, "Parsing WSDL: Unexpected extensibility element <%s>", trav->name);
656 : }
657 16022 : if (node_is_equal(trav,"documentation")) {
658 8 : trav = trav->next;
659 8 : continue;
660 : }
661 16014 : if (!node_is_equal(trav,"part")) {
662 0 : soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name);
663 : }
664 16014 : part = trav;
665 16014 : param = emalloc(sizeof(sdlParam));
666 16014 : memset(param,0,sizeof(sdlParam));
667 16014 : param->order = 0;
668 :
669 16014 : name = get_attribute(part->properties, "name");
670 16014 : if (name == NULL) {
671 0 : soap_error1(E_ERROR, "Parsing WSDL: No name associated with <part> '%s'", message->name);
672 : }
673 :
674 16014 : param->paramName = estrdup((char*)name->children->content);
675 :
676 16014 : type = get_attribute(part->properties, "type");
677 16014 : if (type != NULL) {
678 7311 : param->encode = get_encoder_from_prefix(ctx->sdl, part, type->children->content);
679 : } else {
680 8703 : element = get_attribute(part->properties, "element");
681 8703 : if (element != NULL) {
682 8703 : param->element = get_element(ctx->sdl, part, element->children->content);
683 8703 : if (param->element) {
684 8702 : param->encode = param->element->encode;
685 : }
686 : }
687 : }
688 :
689 16014 : zend_hash_next_index_insert(parameters, ¶m, sizeof(sdlParamPtr), NULL);
690 :
691 16014 : trav = trav->next;
692 : }
693 16140 : return parameters;
694 : }
695 :
696 : static sdlPtr load_wsdl(zval *this_ptr, char *struri TSRMLS_DC)
697 695 : {
698 : sdlCtx ctx;
699 : int i,n;
700 :
701 695 : memset(&ctx,0,sizeof(ctx));
702 695 : ctx.sdl = emalloc(sizeof(sdl));
703 695 : memset(ctx.sdl, 0, sizeof(sdl));
704 695 : ctx.sdl->source = estrdup(struri);
705 695 : zend_hash_init(&ctx.sdl->functions, 0, NULL, delete_function, 0);
706 :
707 695 : zend_hash_init(&ctx.docs, 0, NULL, delete_document, 0);
708 695 : zend_hash_init(&ctx.messages, 0, NULL, NULL, 0);
709 695 : zend_hash_init(&ctx.bindings, 0, NULL, NULL, 0);
710 695 : zend_hash_init(&ctx.portTypes, 0, NULL, NULL, 0);
711 695 : zend_hash_init(&ctx.services, 0, NULL, NULL, 0);
712 :
713 695 : load_wsdl_ex(this_ptr, struri,&ctx, 0 TSRMLS_CC);
714 693 : schema_pass2(&ctx);
715 :
716 693 : n = zend_hash_num_elements(&ctx.services);
717 693 : if (n > 0) {
718 693 : zend_hash_internal_pointer_reset(&ctx.services);
719 1390 : for (i = 0; i < n; i++) {
720 : xmlNodePtr *tmp, service;
721 : xmlNodePtr trav, port;
722 698 : int has_soap_port = 0;
723 :
724 698 : zend_hash_get_current_data(&ctx.services, (void **)&tmp);
725 698 : service = *tmp;
726 :
727 698 : trav = service->children;
728 2332 : while (trav != NULL) {
729 : xmlAttrPtr type, name, bindingAttr, location;
730 : xmlNodePtr portType, operation;
731 : xmlNodePtr address, binding, trav2;
732 : char *ctype;
733 : sdlBindingPtr tmpbinding;
734 937 : char *wsdl_soap_namespace = NULL;
735 :
736 937 : if (!is_wsdl_element(trav) || node_is_equal(trav,"documentation")) {
737 80 : trav = trav->next;
738 80 : continue;
739 : }
740 857 : if (!node_is_equal(trav,"port")) {
741 0 : soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name);
742 : }
743 :
744 857 : port = trav;
745 :
746 857 : tmpbinding = emalloc(sizeof(sdlBinding));
747 857 : memset(tmpbinding, 0, sizeof(sdlBinding));
748 :
749 857 : bindingAttr = get_attribute(port->properties, "binding");
750 857 : if (bindingAttr == NULL) {
751 0 : soap_error0(E_ERROR, "Parsing WSDL: No binding associated with <port>");
752 : }
753 :
754 : /* find address and figure out binding type */
755 857 : address = NULL;
756 857 : trav2 = port->children;
757 2576 : while (trav2 != NULL) {
758 862 : if (node_is_equal(trav2,"address") && trav2->ns) {
759 862 : if (!strncmp((char*)trav2->ns->href, WSDL_SOAP11_NAMESPACE, sizeof(WSDL_SOAP11_NAMESPACE))) {
760 623 : address = trav2;
761 623 : wsdl_soap_namespace = WSDL_SOAP11_NAMESPACE;
762 623 : tmpbinding->bindingType = BINDING_SOAP;
763 239 : } else if (!strncmp((char*)trav2->ns->href, WSDL_SOAP12_NAMESPACE, sizeof(WSDL_SOAP12_NAMESPACE))) {
764 225 : address = trav2;
765 225 : wsdl_soap_namespace = WSDL_SOAP12_NAMESPACE;
766 225 : tmpbinding->bindingType = BINDING_SOAP;
767 14 : } else if (!strncmp((char*)trav2->ns->href, RPC_SOAP12_NAMESPACE, sizeof(RPC_SOAP12_NAMESPACE))) {
768 0 : address = trav2;
769 0 : wsdl_soap_namespace = RPC_SOAP12_NAMESPACE;
770 0 : tmpbinding->bindingType = BINDING_SOAP;
771 14 : } else if (!strncmp((char*)trav2->ns->href, WSDL_HTTP11_NAMESPACE, sizeof(WSDL_HTTP11_NAMESPACE))) {
772 7 : address = trav2;
773 7 : tmpbinding->bindingType = BINDING_HTTP;
774 7 : } else if (!strncmp((char*)trav2->ns->href, WSDL_HTTP12_NAMESPACE, sizeof(WSDL_HTTP12_NAMESPACE))) {
775 0 : address = trav2;
776 0 : tmpbinding->bindingType = BINDING_HTTP;
777 : }
778 : }
779 862 : if (trav2 != address && is_wsdl_element(trav2) && !node_is_equal(trav2,"documentation")) {
780 0 : soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav2->name);
781 : }
782 862 : trav2 = trav2->next;
783 : }
784 857 : if (!address || tmpbinding->bindingType == BINDING_HTTP) {
785 9 : if (has_soap_port || trav->next || i < n-1) {
786 8 : efree(tmpbinding);
787 8 : trav = trav->next;
788 8 : continue;
789 1 : } else if (!address) {
790 0 : soap_error0(E_ERROR, "Parsing WSDL: No address associated with <port>");
791 : }
792 : }
793 849 : has_soap_port = 1;
794 :
795 849 : location = get_attribute(address->properties, "location");
796 849 : if (!location) {
797 0 : soap_error0(E_ERROR, "Parsing WSDL: No location associated with <port>");
798 : }
799 :
800 849 : tmpbinding->location = estrdup((char*)location->children->content);
801 :
802 849 : ctype = strrchr((char*)bindingAttr->children->content,':');
803 849 : if (ctype == NULL) {
804 0 : ctype = (char*)bindingAttr->children->content;
805 : } else {
806 849 : ++ctype;
807 : }
808 849 : if (zend_hash_find(&ctx.bindings, ctype, strlen(ctype)+1, (void*)&tmp) != SUCCESS) {
809 0 : soap_error1(E_ERROR, "Parsing WSDL: No <binding> element with name '%s'", ctype);
810 : }
811 849 : binding = *tmp;
812 :
813 849 : if (tmpbinding->bindingType == BINDING_SOAP) {
814 : sdlSoapBindingPtr soapBinding;
815 : xmlNodePtr soapBindingNode;
816 : xmlAttrPtr tmp;
817 :
818 848 : soapBinding = emalloc(sizeof(sdlSoapBinding));
819 848 : memset(soapBinding, 0, sizeof(sdlSoapBinding));
820 848 : soapBinding->style = SOAP_DOCUMENT;
821 :
822 848 : soapBindingNode = get_node_ex(binding->children, "binding", wsdl_soap_namespace);
823 848 : if (soapBindingNode) {
824 848 : tmp = get_attribute(soapBindingNode->properties, "style");
825 848 : if (tmp && !strncmp((char*)tmp->children->content, "rpc", sizeof("rpc"))) {
826 502 : soapBinding->style = SOAP_RPC;
827 : }
828 :
829 848 : tmp = get_attribute(soapBindingNode->properties, "transport");
830 848 : if (tmp) {
831 848 : if (strncmp((char*)tmp->children->content, WSDL_HTTP_TRANSPORT, sizeof(WSDL_HTTP_TRANSPORT)) == 0) {
832 848 : soapBinding->transport = SOAP_TRANSPORT_HTTP;
833 : } else {
834 0 : soap_error1(E_ERROR, "Parsing WSDL: PHP-SOAP doesn't support transport '%s'", tmp->children->content);
835 : }
836 : }
837 : }
838 848 : tmpbinding->bindingAttributes = (void *)soapBinding;
839 : }
840 :
841 849 : name = get_attribute(binding->properties, "name");
842 849 : if (name == NULL) {
843 0 : soap_error0(E_ERROR, "Parsing WSDL: Missing 'name' attribute for <binding>");
844 : }
845 849 : tmpbinding->name = estrdup((char*)name->children->content);
846 :
847 849 : type = get_attribute(binding->properties, "type");
848 849 : if (type == NULL) {
849 0 : soap_error0(E_ERROR, "Parsing WSDL: Missing 'type' attribute for <binding>");
850 : }
851 :
852 849 : ctype = strrchr((char*)type->children->content,':');
853 849 : if (ctype == NULL) {
854 175 : ctype = (char*)type->children->content;
855 : } else {
856 674 : ++ctype;
857 : }
858 849 : if (zend_hash_find(&ctx.portTypes, ctype, strlen(ctype)+1, (void**)&tmp) != SUCCESS) {
859 0 : soap_error1(E_ERROR, "Parsing WSDL: Missing <portType> with name '%s'", name->children->content);
860 : }
861 849 : portType = *tmp;
862 :
863 849 : trav2 = binding->children;
864 10143 : while (trav2 != NULL) {
865 : sdlFunctionPtr function;
866 : xmlNodePtr input, output, fault, portTypeOperation, trav3;
867 : xmlAttrPtr op_name, paramOrder;
868 :
869 8446 : if ((tmpbinding->bindingType == BINDING_SOAP &&
870 : node_is_equal_ex(trav2, "binding", wsdl_soap_namespace)) ||
871 : !is_wsdl_element(trav2) ||
872 : node_is_equal(trav2,"documentation")) {
873 856 : trav2 = trav2->next;
874 856 : continue;
875 : }
876 7589 : if (!node_is_equal(trav2,"operation")) {
877 0 : soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav2->name);
878 : }
879 :
880 7589 : operation = trav2;
881 :
882 7589 : op_name = get_attribute(operation->properties, "name");
883 7589 : if (op_name == NULL) {
884 0 : soap_error0(E_ERROR, "Parsing WSDL: Missing 'name' attribute for <operation>");
885 : }
886 :
887 7589 : trav3 = operation->children;
888 38912 : while (trav3 != NULL) {
889 23734 : if (tmpbinding->bindingType == BINDING_SOAP &&
890 : node_is_equal_ex(trav3, "operation", wsdl_soap_namespace)) {
891 16147 : } else if (is_wsdl_element(trav3) &&
892 : !node_is_equal(trav3,"input") &&
893 : !node_is_equal(trav3,"output") &&
894 : !node_is_equal(trav3,"fault") &&
895 : !node_is_equal(trav3,"documentation")) {
896 0 : soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav3->name);
897 : }
898 23734 : trav3 = trav3->next;
899 : }
900 :
901 7589 : portTypeOperation = get_node_with_attribute_ex(portType->children, "operation", WSDL_NAMESPACE, "name", (char*)op_name->children->content, NULL);
902 7589 : if (portTypeOperation == NULL) {
903 0 : soap_error1(E_ERROR, "Parsing WSDL: Missing <portType>/<operation> with name '%s'", op_name->children->content);
904 : }
905 :
906 7589 : function = emalloc(sizeof(sdlFunction));
907 7589 : memset(function, 0, sizeof(sdlFunction));
908 7589 : function->functionName = estrdup((char*)op_name->children->content);
909 :
910 7589 : if (tmpbinding->bindingType == BINDING_SOAP) {
911 : sdlSoapBindingFunctionPtr soapFunctionBinding;
912 : sdlSoapBindingPtr soapBinding;
913 : xmlNodePtr soapOperation;
914 : xmlAttrPtr tmp;
915 :
916 7588 : soapFunctionBinding = emalloc(sizeof(sdlSoapBindingFunction));
917 7588 : memset(soapFunctionBinding, 0, sizeof(sdlSoapBindingFunction));
918 7588 : soapBinding = (sdlSoapBindingPtr)tmpbinding->bindingAttributes;
919 7588 : soapFunctionBinding->style = soapBinding->style;
920 :
921 7588 : soapOperation = get_node_ex(operation->children, "operation", wsdl_soap_namespace);
922 7588 : if (soapOperation) {
923 7587 : tmp = get_attribute(soapOperation->properties, "soapAction");
924 7587 : if (tmp) {
925 5905 : soapFunctionBinding->soapAction = estrdup((char*)tmp->children->content);
926 : }
927 :
928 7587 : tmp = get_attribute(soapOperation->properties, "style");
929 7587 : if (tmp) {
930 5045 : if (!strncmp((char*)tmp->children->content, "rpc", sizeof("rpc"))) {
931 1596 : soapFunctionBinding->style = SOAP_RPC;
932 : } else {
933 3449 : soapFunctionBinding->style = SOAP_DOCUMENT;
934 : }
935 : } else {
936 2542 : soapFunctionBinding->style = soapBinding->style;
937 : }
938 : }
939 :
940 7588 : function->bindingAttributes = (void *)soapFunctionBinding;
941 : }
942 :
943 7589 : input = get_node_ex(portTypeOperation->children, "input", WSDL_NAMESPACE);
944 7589 : if (input != NULL) {
945 : xmlAttrPtr message, name;
946 :
947 7589 : message = get_attribute(input->properties, "message");
948 7589 : if (message == NULL) {
949 0 : soap_error1(E_ERROR, "Parsing WSDL: Missing name for <input> of '%s'", op_name->children->content);
950 : }
951 7589 : function->requestParameters = wsdl_message(&ctx, message->children->content);
952 :
953 7589 : name = get_attribute(input->properties, "name");
954 : /* FIXME
955 : if (name != NULL) {
956 : function->requestName = estrdup(name->children->content);
957 : } else {
958 : */
959 : {
960 7589 : function->requestName = estrdup(function->functionName);
961 : }
962 :
963 7589 : if (tmpbinding->bindingType == BINDING_SOAP) {
964 7588 : input = get_node_ex(operation->children, "input", WSDL_NAMESPACE);
965 7588 : if (input != NULL) {
966 7588 : sdlSoapBindingFunctionPtr soapFunctionBinding = function->bindingAttributes;
967 7588 : wsdl_soap_binding_body(&ctx, input, wsdl_soap_namespace, &soapFunctionBinding->input, function->requestParameters);
968 : }
969 : }
970 : }
971 :
972 7589 : output = get_node_ex(portTypeOperation->children, "output", WSDL_NAMESPACE);
973 7589 : if (output != NULL) {
974 : xmlAttrPtr message, name;
975 :
976 7341 : message = get_attribute(output->properties, "message");
977 7341 : if (message == NULL) {
978 0 : soap_error1(E_ERROR, "Parsing WSDL: Missing name for <output> of '%s'", op_name->children->content);
979 : }
980 7341 : function->responseParameters = wsdl_message(&ctx, message->children->content);
981 :
982 7341 : name = get_attribute(output->properties, "name");
983 : /* FIXME
984 : if (name != NULL) {
985 : function->responseName = estrdup(name->children->content);
986 : } else if (input == NULL) {
987 : function->responseName = estrdup(function->functionName);
988 : } else {
989 : */
990 : {
991 7341 : int len = strlen(function->functionName);
992 7341 : function->responseName = emalloc(len + sizeof("Response"));
993 7341 : memcpy(function->responseName, function->functionName, len);
994 7341 : memcpy(function->responseName+len, "Response", sizeof("Response"));
995 : }
996 :
997 7341 : if (tmpbinding->bindingType == BINDING_SOAP) {
998 7340 : output = get_node_ex(operation->children, "output", WSDL_NAMESPACE);
999 7340 : if (output != NULL) {
1000 7340 : sdlSoapBindingFunctionPtr soapFunctionBinding = function->bindingAttributes;
1001 7340 : wsdl_soap_binding_body(&ctx, output, wsdl_soap_namespace, &soapFunctionBinding->output, function->responseParameters);
1002 : }
1003 : }
1004 : }
1005 :
1006 7589 : paramOrder = get_attribute(portTypeOperation->properties, "parameterOrder");
1007 : if (paramOrder) {
1008 : /* FIXME: */
1009 : }
1010 :
1011 7589 : fault = portTypeOperation->children;
1012 31330 : while (fault != NULL) {
1013 16152 : if (node_is_equal_ex(fault, "fault", WSDL_NAMESPACE)) {
1014 : xmlAttrPtr message, name;
1015 : sdlFaultPtr f;
1016 :
1017 1210 : name = get_attribute(fault->properties, "name");
1018 1210 : if (name == NULL) {
1019 0 : soap_error1(E_ERROR, "Parsing WSDL: Missing name for <fault> of '%s'", op_name->children->content);
1020 : }
1021 1210 : message = get_attribute(fault->properties, "message");
1022 1210 : if (message == NULL) {
1023 0 : soap_error1(E_ERROR, "Parsing WSDL: Missing name for <output> of '%s'", op_name->children->content);
1024 : }
1025 :
1026 1210 : f = emalloc(sizeof(sdlFault));
1027 1210 : memset(f, 0, sizeof(sdlFault));
1028 :
1029 1210 : f->name = estrdup((char*)name->children->content);
1030 1210 : f->details = wsdl_message(&ctx, message->children->content);
1031 1210 : if (f->details == NULL || zend_hash_num_elements(f->details) > 1) {
1032 0 : soap_error1(E_ERROR, "Parsing WSDL: The fault message '%s' must have a single part", message->children->content);
1033 : }
1034 :
1035 1210 : if (tmpbinding->bindingType == BINDING_SOAP) {
1036 1210 : xmlNodePtr soap_fault = get_node_with_attribute_ex(operation->children, "fault", WSDL_NAMESPACE, "name", f->name, NULL);
1037 1210 : if (soap_fault != NULL) {
1038 1176 : xmlNodePtr trav = soap_fault->children;
1039 3528 : while (trav != NULL) {
1040 1176 : if (node_is_equal_ex(trav, "fault", wsdl_soap_namespace)) {
1041 : xmlAttrPtr tmp;
1042 : sdlSoapBindingFunctionFaultPtr binding;
1043 :
1044 1176 : binding = f->bindingAttributes = emalloc(sizeof(sdlSoapBindingFunctionFault));
1045 1176 : memset(f->bindingAttributes, 0, sizeof(sdlSoapBindingFunctionFault));
1046 :
1047 1176 : tmp = get_attribute(trav->properties, "use");
1048 1784 : if (tmp && !strncmp((char*)tmp->children->content, "encoded", sizeof("encoded"))) {
1049 608 : binding->use = SOAP_ENCODED;
1050 : } else {
1051 568 : binding->use = SOAP_LITERAL;
1052 : }
1053 :
1054 1176 : tmp = get_attribute(trav->properties, "namespace");
1055 1176 : if (tmp) {
1056 608 : binding->ns = estrdup((char*)tmp->children->content);
1057 : }
1058 :
1059 1176 : if (binding->use == SOAP_ENCODED) {
1060 608 : tmp = get_attribute(trav->properties, "encodingStyle");
1061 608 : if (tmp) {
1062 608 : if (strncmp((char*)tmp->children->content, SOAP_1_1_ENC_NAMESPACE, sizeof(SOAP_1_1_ENC_NAMESPACE)) == 0) {
1063 608 : binding->encodingStyle = SOAP_ENCODING_1_1;
1064 0 : } else if (strncmp((char*)tmp->children->content, SOAP_1_2_ENC_NAMESPACE, sizeof(SOAP_1_2_ENC_NAMESPACE)) == 0) {
1065 0 : binding->encodingStyle = SOAP_ENCODING_1_2;
1066 : } else {
1067 0 : soap_error1(E_ERROR, "Parsing WSDL: Unknown encodingStyle '%s'", tmp->children->content);
1068 : }
1069 : } else {
1070 0 : soap_error0(E_ERROR, "Parsing WSDL: Unspecified encodingStyle");
1071 : }
1072 : }
1073 0 : } else if (is_wsdl_element(trav) && !node_is_equal(trav,"documentation")) {
1074 0 : soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name);
1075 : }
1076 1176 : trav = trav->next;
1077 : }
1078 : }
1079 : }
1080 1210 : if (function->faults == NULL) {
1081 682 : function->faults = emalloc(sizeof(HashTable));
1082 682 : zend_hash_init(function->faults, 0, NULL, delete_fault, 0);
1083 : }
1084 1210 : if (zend_hash_add(function->faults, f->name, strlen(f->name)+1, (void**)&f, sizeof(sdlFaultPtr), NULL) != SUCCESS) {
1085 0 : soap_error2(E_ERROR, "Parsing WSDL: <fault> with name '%s' already defined in '%s'", f->name, op_name->children->content);
1086 : }
1087 : }
1088 16152 : fault = fault->next;
1089 : }
1090 :
1091 7589 : function->binding = tmpbinding;
1092 :
1093 : {
1094 7589 : char *tmp = estrdup(function->functionName);
1095 7589 : int len = strlen(tmp);
1096 :
1097 7589 : if (zend_hash_add(&ctx.sdl->functions, php_strtolower(tmp, len), len+1, &function, sizeof(sdlFunctionPtr), NULL) != SUCCESS) {
1098 1674 : zend_hash_next_index_insert(&ctx.sdl->functions, &function, sizeof(sdlFunctionPtr), NULL);
1099 : }
1100 7589 : efree(tmp);
1101 7589 : if (function->requestName != NULL && strcmp(function->requestName,function->functionName) != 0) {
1102 0 : if (ctx.sdl->requests == NULL) {
1103 0 : ctx.sdl->requests = emalloc(sizeof(HashTable));
1104 0 : zend_hash_init(ctx.sdl->requests, 0, NULL, NULL, 0);
1105 : }
1106 0 : tmp = estrdup(function->requestName);
1107 0 : len = strlen(tmp);
1108 0 : zend_hash_add(ctx.sdl->requests, php_strtolower(tmp, len), len+1, &function, sizeof(sdlFunctionPtr), NULL);
1109 0 : efree(tmp);
1110 : }
1111 : }
1112 7589 : trav2 = trav2->next;
1113 : }
1114 :
1115 848 : if (!ctx.sdl->bindings) {
1116 692 : ctx.sdl->bindings = emalloc(sizeof(HashTable));
1117 692 : zend_hash_init(ctx.sdl->bindings, 0, NULL, delete_binding, 0);
1118 : }
1119 :
1120 848 : zend_hash_add(ctx.sdl->bindings, tmpbinding->name, strlen(tmpbinding->name), &tmpbinding, sizeof(sdlBindingPtr), NULL);
1121 848 : trav= trav->next;
1122 : }
1123 :
1124 697 : zend_hash_move_forward(&ctx.services);
1125 : }
1126 : } else {
1127 0 : soap_error0(E_ERROR, "Parsing WSDL: Couldn't bind to service");
1128 : }
1129 :
1130 692 : zend_hash_destroy(&ctx.messages);
1131 692 : zend_hash_destroy(&ctx.bindings);
1132 692 : zend_hash_destroy(&ctx.portTypes);
1133 692 : zend_hash_destroy(&ctx.services);
1134 692 : zend_hash_destroy(&ctx.docs);
1135 :
1136 692 : return ctx.sdl;
1137 : }
1138 :
1139 : #define WSDL_CACHE_VERSION 0x0e
1140 :
1141 : #define WSDL_CACHE_GET(ret,type,buf) memcpy(&ret,*buf,sizeof(type)); *buf += sizeof(type);
1142 : #define WSDL_CACHE_GET_INT(ret,buf) ret = ((unsigned char)(*buf)[0])|((unsigned char)(*buf)[1]<<8)|((unsigned char)(*buf)[2]<<16)|((int)(*buf)[3]<<24); *buf += 4;
1143 : #define WSDL_CACHE_GET_1(ret,type,buf) ret = (type)(**buf); (*buf)++;
1144 : #define WSDL_CACHE_GET_N(ret,n,buf) memcpy(ret,*buf,n); *buf += n;
1145 : #define WSDL_CACHE_SKIP(n,buf) *buf += n;
1146 :
1147 : #define WSDL_CACHE_PUT_INT(val,buf) smart_str_appendc(buf,val & 0xff); \
1148 : smart_str_appendc(buf,(val >> 8) & 0xff); \
1149 : smart_str_appendc(buf,(val >> 16) & 0xff); \
1150 : smart_str_appendc(buf,(val >> 24) & 0xff);
1151 : #define WSDL_CACHE_PUT_1(val,buf) smart_str_appendc(buf,val);
1152 : #define WSDL_CACHE_PUT_N(val,n,buf) smart_str_appendl(buf,(char*)val,n);
1153 :
1154 : static char* sdl_deserialize_string(char **in)
1155 90 : {
1156 : char *s;
1157 : int len;
1158 :
1159 90 : WSDL_CACHE_GET_INT(len, in);
1160 90 : if (len == 0x7fffffff) {
1161 29 : return NULL;
1162 : } else {
1163 61 : s = emalloc(len+1);
1164 61 : WSDL_CACHE_GET_N(s, len, in);
1165 61 : s[len] = '\0';
1166 61 : return s;
1167 : }
1168 : }
1169 :
1170 : static void sdl_deserialize_key(HashTable* ht, void* data, char **in)
1171 27 : {
1172 : int len;
1173 :
1174 27 : WSDL_CACHE_GET_INT(len, in);
1175 27 : if (len == 0) {
1176 10 : zend_hash_next_index_insert(ht, &data, sizeof(void*), NULL);
1177 : } else {
1178 17 : zend_hash_add(ht, *in, len, &data, sizeof(void*), NULL);
1179 17 : WSDL_CACHE_SKIP(len, in);
1180 : }
1181 27 : }
1182 :
1183 : static void sdl_deserialize_attribute(sdlAttributePtr attr, encodePtr *encoders, char **in)
1184 0 : {
1185 : int i;
1186 :
1187 0 : attr->name = sdl_deserialize_string(in);
1188 0 : attr->namens = sdl_deserialize_string(in);
1189 0 : attr->ref = sdl_deserialize_string(in);
1190 0 : attr->def = sdl_deserialize_string(in);
1191 0 : attr->fixed = sdl_deserialize_string(in);
1192 0 : WSDL_CACHE_GET_1(attr->form, sdlForm, in);
1193 0 : WSDL_CACHE_GET_1(attr->use, sdlUse, in);
1194 0 : WSDL_CACHE_GET_INT(i, in);
1195 0 : attr->encode = encoders[i];
1196 0 : WSDL_CACHE_GET_INT(i, in);
1197 0 : if (i > 0) {
1198 0 : attr->extraAttributes = emalloc(sizeof(HashTable));
1199 0 : zend_hash_init(attr->extraAttributes, i, NULL, delete_extra_attribute, 0);
1200 0 : while (i > 0) {
1201 0 : sdlExtraAttributePtr x = emalloc(sizeof(sdlExtraAttribute));
1202 0 : sdl_deserialize_key(attr->extraAttributes, x, in);
1203 0 : x->ns = sdl_deserialize_string(in);
1204 0 : x->val = sdl_deserialize_string(in);
1205 0 : --i;
1206 : }
1207 : }
1208 0 : }
1209 :
1210 : static sdlRestrictionIntPtr sdl_deserialize_resriction_int(char **in)
1211 0 : {
1212 0 : if (**in == 1) {
1213 0 : sdlRestrictionIntPtr x = emalloc(sizeof(sdlRestrictionInt));
1214 0 : WSDL_CACHE_SKIP(1, in);
1215 0 : WSDL_CACHE_GET_INT(x->value, in);
1216 0 : WSDL_CACHE_GET_1(x->fixed, char, in);
1217 0 : return x;
1218 : } else {
1219 0 : WSDL_CACHE_SKIP(1, in);
1220 0 : return NULL;
1221 : }
1222 : }
1223 :
1224 : static sdlRestrictionCharPtr sdl_deserialize_resriction_char(char **in)
1225 0 : {
1226 0 : if (**in == 1) {
1227 0 : sdlRestrictionCharPtr x = emalloc(sizeof(sdlRestrictionChar));
1228 0 : WSDL_CACHE_SKIP(1, in);
1229 0 : x->value = sdl_deserialize_string(in);
1230 0 : WSDL_CACHE_GET_1(x->fixed, char, in);
1231 0 : return x;
1232 : } else {
1233 0 : WSDL_CACHE_SKIP(1, in);
1234 0 : return NULL;
1235 : }
1236 : }
1237 :
1238 : static sdlContentModelPtr sdl_deserialize_model(sdlTypePtr *types, sdlTypePtr *elements, char **in)
1239 9 : {
1240 : int i;
1241 9 : sdlContentModelPtr model = emalloc(sizeof(sdlContentModel));
1242 :
1243 9 : WSDL_CACHE_GET_1(model->kind, sdlContentKind, in);
1244 9 : WSDL_CACHE_GET_INT(model->min_occurs, in);
1245 9 : WSDL_CACHE_GET_INT(model->max_occurs, in);
1246 9 : switch (model->kind) {
1247 : case XSD_CONTENT_ELEMENT:
1248 6 : WSDL_CACHE_GET_INT(i, in);
1249 6 : model->u.element = elements[i];
1250 6 : break;
1251 : case XSD_CONTENT_SEQUENCE:
1252 : case XSD_CONTENT_ALL:
1253 : case XSD_CONTENT_CHOICE:
1254 3 : WSDL_CACHE_GET_INT(i, in);
1255 3 : model->u.content = emalloc(sizeof(HashTable));
1256 3 : zend_hash_init(model->u.content, i, NULL, delete_model, 0);
1257 12 : while (i > 0) {
1258 6 : sdlContentModelPtr x = sdl_deserialize_model(types, elements, in);
1259 6 : zend_hash_next_index_insert(model->u.content,&x,sizeof(sdlContentModelPtr),NULL);
1260 6 : i--;
1261 : }
1262 3 : break;
1263 : case XSD_CONTENT_GROUP_REF:
1264 0 : model->u.group_ref = sdl_deserialize_string(in);
1265 0 : break;
1266 : case XSD_CONTENT_GROUP:
1267 0 : WSDL_CACHE_GET_INT(i, in);
1268 0 : model->u.group = types[i];
1269 : break;
1270 : default:
1271 : break;
1272 : }
1273 9 : return model;
1274 : }
1275 :
1276 : static void sdl_deserialize_type(sdlTypePtr type, sdlTypePtr *types, encodePtr *encoders, char **in)
1277 9 : {
1278 : int i;
1279 9 : sdlTypePtr *elements = NULL;
1280 :
1281 9 : WSDL_CACHE_GET_1(type->kind, sdlTypeKind, in);
1282 9 : type->name = sdl_deserialize_string(in);
1283 9 : type->namens = sdl_deserialize_string(in);
1284 9 : type->def = sdl_deserialize_string(in);
1285 9 : type->fixed = sdl_deserialize_string(in);
1286 9 : type->ref = sdl_deserialize_string(in);
1287 9 : WSDL_CACHE_GET_1(type->nillable, char, in);
1288 9 : WSDL_CACHE_GET_1(type->form, sdlForm, in);
1289 :
1290 9 : WSDL_CACHE_GET_INT(i, in);
1291 9 : type->encode = encoders[i];
1292 :
1293 9 : if (**in == 1) {
1294 0 : WSDL_CACHE_SKIP(1, in);
1295 0 : type->restrictions = emalloc(sizeof(sdlRestrictions));
1296 : /*memset(type->restrictions, 0, sizeof(sdlRestrictions));*/
1297 0 : type->restrictions->minExclusive = sdl_deserialize_resriction_int(in);
1298 0 : type->restrictions->minInclusive = sdl_deserialize_resriction_int(in);
1299 0 : type->restrictions->maxExclusive = sdl_deserialize_resriction_int(in);
1300 0 : type->restrictions->maxInclusive = sdl_deserialize_resriction_int(in);
1301 0 : type->restrictions->totalDigits = sdl_deserialize_resriction_int(in);
1302 0 : type->restrictions->fractionDigits = sdl_deserialize_resriction_int(in);
1303 0 : type->restrictions->length = sdl_deserialize_resriction_int(in);
1304 0 : type->restrictions->minLength = sdl_deserialize_resriction_int(in);
1305 0 : type->restrictions->maxLength = sdl_deserialize_resriction_int(in);
1306 0 : type->restrictions->whiteSpace = sdl_deserialize_resriction_char(in);
1307 0 : type->restrictions->pattern = sdl_deserialize_resriction_char(in);
1308 0 : WSDL_CACHE_GET_INT(i, in);
1309 0 : if (i > 0) {
1310 0 : type->restrictions->enumeration = emalloc(sizeof(HashTable));
1311 0 : zend_hash_init(type->restrictions->enumeration, i, NULL, delete_restriction_var_char, 0);
1312 0 : while (i > 0) {
1313 0 : sdlRestrictionCharPtr x = sdl_deserialize_resriction_char(in);
1314 0 : sdl_deserialize_key(type->restrictions->enumeration, x, in);
1315 0 : --i;
1316 : }
1317 : } else {
1318 0 : type->restrictions->enumeration = NULL;
1319 : }
1320 : } else {
1321 9 : WSDL_CACHE_SKIP(1, in);
1322 : }
1323 :
1324 9 : WSDL_CACHE_GET_INT(i, in);
1325 9 : if (i > 0) {
1326 3 : elements = safe_emalloc((i+1), sizeof(sdlTypePtr), 0);
1327 3 : elements[0] = NULL;
1328 3 : type->elements = emalloc(sizeof(HashTable));
1329 3 : zend_hash_init(type->elements, i, NULL, delete_type, 0);
1330 12 : while (i > 0) {
1331 6 : sdlTypePtr t = emalloc(sizeof(sdlType));
1332 6 : memset(t, 0, sizeof(sdlType));
1333 6 : sdl_deserialize_key(type->elements, t, in);
1334 6 : sdl_deserialize_type(t, types, encoders, in);
1335 6 : elements[i] = t;
1336 6 : --i;
1337 : }
1338 : }
1339 :
1340 9 : WSDL_CACHE_GET_INT(i, in);
1341 9 : if (i > 0) {
1342 0 : type->attributes = emalloc(sizeof(HashTable));
1343 0 : zend_hash_init(type->attributes, i, NULL, delete_attribute, 0);
1344 0 : while (i > 0) {
1345 0 : sdlAttributePtr attr = emalloc(sizeof(sdlAttribute));
1346 0 : memset(attr, 0, sizeof(sdlAttribute));
1347 0 : sdl_deserialize_key(type->attributes, attr, in);
1348 0 : sdl_deserialize_attribute(attr, encoders, in);
1349 0 : --i;
1350 : }
1351 : }
1352 :
1353 9 : if (**in != 0) {
1354 3 : WSDL_CACHE_SKIP(1, in);
1355 3 : type->model = sdl_deserialize_model(types, elements, in);
1356 : } else {
1357 6 : WSDL_CACHE_SKIP(1, in);
1358 : }
1359 9 : if (elements != NULL) {
1360 3 : efree(elements);
1361 : }
1362 9 : }
1363 :
1364 : static void sdl_deserialize_encoder(encodePtr enc, sdlTypePtr *types, char **in)
1365 4 : {
1366 : int i;
1367 :
1368 4 : WSDL_CACHE_GET_INT(enc->details.type, in);
1369 4 : enc->details.type_str = sdl_deserialize_string(in);
1370 4 : enc->details.ns = sdl_deserialize_string(in);
1371 4 : WSDL_CACHE_GET_INT(i, in);
1372 4 : enc->details.sdl_type = types[i];
1373 4 : enc->to_xml = sdl_guess_convert_xml;
1374 4 : enc->to_zval = sdl_guess_convert_zval;
1375 :
1376 4 : if (enc->details.sdl_type == NULL) {
1377 1 : int ns_len = strlen(enc->details.ns);
1378 1 : int type_len = strlen(enc->details.type_str);
1379 :
1380 1 : if (((ns_len == sizeof(SOAP_1_1_ENC_NAMESPACE)-1 &&
1381 : memcmp(enc->details.ns, SOAP_1_1_ENC_NAMESPACE, sizeof(SOAP_1_1_ENC_NAMESPACE)-1) == 0) ||
1382 : (ns_len == sizeof(SOAP_1_2_ENC_NAMESPACE)-1 &&
1383 : memcmp(enc->details.ns, SOAP_1_2_ENC_NAMESPACE, sizeof(SOAP_1_2_ENC_NAMESPACE)-1) == 0))) {
1384 : char *enc_nscat;
1385 : int enc_ns_len;
1386 : int enc_len;
1387 : encodePtr real_enc;
1388 :
1389 1 : enc_ns_len = sizeof(XSD_NAMESPACE)-1;
1390 1 : enc_len = enc_ns_len + type_len + 1;
1391 1 : enc_nscat = emalloc(enc_len + 1);
1392 1 : memcpy(enc_nscat, XSD_NAMESPACE, sizeof(XSD_NAMESPACE)-1);
1393 1 : enc_nscat[enc_ns_len] = ':';
1394 1 : memcpy(enc_nscat+enc_ns_len+1, enc->details.type_str, type_len);
1395 1 : enc_nscat[enc_len] = '\0';
1396 :
1397 1 : real_enc = get_encoder_ex(NULL, enc_nscat, enc_len);
1398 1 : efree(enc_nscat);
1399 1 : if (real_enc) {
1400 1 : enc->to_zval = real_enc->to_zval;
1401 1 : enc->to_xml = real_enc->to_xml;
1402 : }
1403 : }
1404 : }
1405 4 : }
1406 :
1407 : static void sdl_deserialize_soap_body(sdlSoapBindingFunctionBodyPtr body, encodePtr *encoders, sdlTypePtr *types, char **in)
1408 6 : {
1409 : int i, j, n;
1410 :
1411 6 : WSDL_CACHE_GET_1(body->use, sdlEncodingUse, in);
1412 6 : if (body->use == SOAP_ENCODED) {
1413 4 : WSDL_CACHE_GET_1(body->encodingStyle, sdlRpcEncodingStyle, in);
1414 : } else {
1415 2 : body->encodingStyle = SOAP_ENCODING_DEFAULT;
1416 : }
1417 6 : body->ns = sdl_deserialize_string(in);
1418 6 : WSDL_CACHE_GET_INT(i, in);
1419 6 : if (i > 0) {
1420 0 : body->headers = emalloc(sizeof(HashTable));
1421 0 : zend_hash_init(body->headers, i, NULL, delete_header, 0);
1422 0 : while (i > 0) {
1423 0 : sdlSoapBindingFunctionHeaderPtr tmp = emalloc(sizeof(sdlSoapBindingFunctionHeader));
1424 0 : memset(tmp, 0, sizeof(sdlSoapBindingFunctionHeader));
1425 0 : sdl_deserialize_key(body->headers, tmp, in);
1426 0 : WSDL_CACHE_GET_1(tmp->use, sdlEncodingUse, in);
1427 0 : if (tmp->use == SOAP_ENCODED) {
1428 0 : WSDL_CACHE_GET_1(tmp->encodingStyle, sdlRpcEncodingStyle, in);
1429 : } else {
1430 0 : tmp->encodingStyle = SOAP_ENCODING_DEFAULT;
1431 : }
1432 0 : tmp->name = sdl_deserialize_string(in);
1433 0 : tmp->ns = sdl_deserialize_string(in);
1434 0 : WSDL_CACHE_GET_INT(n, in);
1435 0 : tmp->encode = encoders[n];
1436 0 : WSDL_CACHE_GET_INT(n, in);
1437 0 : tmp->element = types[n];
1438 0 : --i;
1439 0 : WSDL_CACHE_GET_INT(j, in);
1440 0 : if (j > 0) {
1441 0 : tmp->headerfaults = emalloc(sizeof(HashTable));
1442 0 : zend_hash_init(tmp->headerfaults, i, NULL, delete_header, 0);
1443 0 : while (j > 0) {
1444 0 : sdlSoapBindingFunctionHeaderPtr tmp2 = emalloc(sizeof(sdlSoapBindingFunctionHeader));
1445 0 : memset(tmp2, 0, sizeof(sdlSoapBindingFunctionHeader));
1446 0 : sdl_deserialize_key(tmp->headerfaults, tmp2, in);
1447 0 : WSDL_CACHE_GET_1(tmp2->use, sdlEncodingUse, in);
1448 0 : if (tmp2->use == SOAP_ENCODED) {
1449 0 : WSDL_CACHE_GET_1(tmp2->encodingStyle, sdlRpcEncodingStyle, in);
1450 : } else {
1451 0 : tmp2->encodingStyle = SOAP_ENCODING_DEFAULT;
1452 : }
1453 0 : tmp2->name = sdl_deserialize_string(in);
1454 0 : tmp2->ns = sdl_deserialize_string(in);
1455 0 : WSDL_CACHE_GET_INT(n, in);
1456 0 : tmp2->encode = encoders[n];
1457 0 : WSDL_CACHE_GET_INT(n, in);
1458 0 : tmp2->element = types[n];
1459 0 : --j;
1460 : }
1461 : }
1462 : }
1463 : }
1464 6 : }
1465 :
1466 : static HashTable* sdl_deserialize_parameters(encodePtr *encoders, sdlTypePtr *types, char **in)
1467 8 : {
1468 : int i, n;
1469 : HashTable *ht;
1470 :
1471 8 : WSDL_CACHE_GET_INT(i, in);
1472 8 : if (i == 0) {return NULL;}
1473 7 : ht = emalloc(sizeof(HashTable));
1474 7 : zend_hash_init(ht, i, NULL, delete_parameter, 0);
1475 21 : while (i > 0) {
1476 7 : sdlParamPtr param = emalloc(sizeof(sdlParam));
1477 7 : sdl_deserialize_key(ht, param, in);
1478 7 : param->paramName = sdl_deserialize_string(in);
1479 7 : WSDL_CACHE_GET_INT(param->order, in);
1480 7 : WSDL_CACHE_GET_INT(n, in);
1481 7 : param->encode = encoders[n];
1482 7 : WSDL_CACHE_GET_INT(n, in);
1483 7 : param->element = types[n];
1484 7 : --i;
1485 : }
1486 7 : return ht;
1487 : }
1488 :
1489 : static sdlPtr get_sdl_from_cache(const char *fn, const char *uri, time_t t, time_t *cached TSRMLS_DC)
1490 7 : {
1491 : sdlPtr sdl;
1492 : time_t old_t;
1493 : int i, num_groups, num_types, num_elements, num_encoders, num_bindings, num_func;
1494 7 : sdlFunctionPtr *functions = NULL;
1495 : sdlBindingPtr *bindings;
1496 : sdlTypePtr *types;
1497 : encodePtr *encoders;
1498 : encodePtr enc;
1499 :
1500 : int f;
1501 : struct stat st;
1502 : char *in, *buf;
1503 :
1504 7 : f = open(fn, O_RDONLY|O_BINARY);
1505 7 : if (f < 0) {
1506 1 : return NULL;
1507 : }
1508 6 : if (fstat(f, &st) != 0) {
1509 0 : close(f);
1510 0 : return NULL;
1511 : }
1512 6 : buf = in = emalloc(st.st_size);
1513 6 : if (read(f, in, st.st_size) != st.st_size) {
1514 0 : close(f);
1515 0 : efree(in);
1516 0 : return NULL;
1517 : }
1518 6 : close(f);
1519 :
1520 6 : if (strncmp(in,"wsdl",4) != 0 || in[4] != WSDL_CACHE_VERSION || in[5] != '\0') {
1521 0 : unlink(fn);
1522 0 : efree(buf);
1523 0 : return NULL;
1524 : }
1525 6 : in += 6;
1526 :
1527 6 : WSDL_CACHE_GET(old_t, time_t, &in);
1528 6 : if (old_t < t) {
1529 4 : unlink(fn);
1530 4 : efree(buf);
1531 4 : return NULL;
1532 : }
1533 2 : *cached = old_t;
1534 :
1535 2 : WSDL_CACHE_GET_INT(i, &in);
1536 2 : if (i == 0 && strncmp(in, uri, i) != 0) {
1537 0 : unlink(fn);
1538 0 : efree(buf);
1539 0 : return NULL;
1540 : }
1541 2 : WSDL_CACHE_SKIP(i, &in);
1542 :
1543 2 : sdl = emalloc(sizeof(*sdl));
1544 2 : memset(sdl, 0, sizeof(*sdl));
1545 :
1546 2 : sdl->source = sdl_deserialize_string(&in);
1547 2 : sdl->target_ns = sdl_deserialize_string(&in);
1548 :
1549 2 : WSDL_CACHE_GET_INT(num_groups, &in);
1550 2 : WSDL_CACHE_GET_INT(num_types, &in);
1551 2 : WSDL_CACHE_GET_INT(num_elements, &in);
1552 2 : WSDL_CACHE_GET_INT(num_encoders, &in);
1553 :
1554 2 : i = num_groups+num_types+num_elements;
1555 2 : types = safe_emalloc((i+1), sizeof(sdlTypePtr), 0);
1556 2 : types[0] = NULL;
1557 7 : while (i > 0) {
1558 3 : types[i] = emalloc(sizeof(sdlType));
1559 3 : memset(types[i], 0, sizeof(sdlType));
1560 3 : i--;
1561 : }
1562 :
1563 2 : i = num_encoders;
1564 2 : enc = defaultEncoding;
1565 154 : while (enc->details.type != END_KNOWN_TYPES) {
1566 150 : i++; enc++;
1567 : }
1568 2 : encoders = safe_emalloc((i+1), sizeof(encodePtr), 0);
1569 2 : i = num_encoders;
1570 2 : encoders[0] = NULL;
1571 8 : while (i > 0) {
1572 4 : encoders[i] = emalloc(sizeof(encode));
1573 4 : memset(encoders[i], 0, sizeof(encode));
1574 4 : i--;
1575 : }
1576 2 : i = num_encoders;
1577 2 : enc = defaultEncoding;
1578 154 : while (enc->details.type != END_KNOWN_TYPES) {
1579 150 : encoders[++i] = enc++;
1580 : }
1581 :
1582 2 : i = 1;
1583 2 : if (num_groups > 0) {
1584 0 : sdl->groups = emalloc(sizeof(HashTable));
1585 0 : zend_hash_init(sdl->groups, num_groups, NULL, delete_type, 0);
1586 0 : while (i < num_groups+1) {
1587 0 : sdl_deserialize_key(sdl->groups, types[i], &in);
1588 0 : sdl_deserialize_type(types[i], types, encoders, &in);
1589 0 : i++;
1590 : }
1591 : }
1592 :
1593 2 : if (num_types > 0) {
1594 2 : sdl->types = emalloc(sizeof(HashTable));
1595 2 : zend_hash_init(sdl->types, num_types, NULL, delete_type, 0);
1596 7 : while (i < num_groups+num_types+1) {
1597 3 : sdl_deserialize_key(sdl->types, types[i], &in);
1598 3 : sdl_deserialize_type(types[i], types, encoders, &in);
1599 3 : i++;
1600 : }
1601 : }
1602 :
1603 2 : if (num_elements > 0) {
1604 0 : sdl->elements = emalloc(sizeof(HashTable));
1605 0 : zend_hash_init(sdl->elements, num_elements, NULL, delete_type, 0);
1606 0 : while (i < num_groups+num_types+num_elements+1) {
1607 0 : sdl_deserialize_key(sdl->elements, types[i], &in);
1608 0 : sdl_deserialize_type(types[i], types, encoders, &in);
1609 0 : i++;
1610 : }
1611 : }
1612 :
1613 2 : i = 1;
1614 2 : if (num_encoders > 0) {
1615 2 : sdl->encoders = emalloc(sizeof(HashTable));
1616 2 : zend_hash_init(sdl->encoders, num_encoders, NULL, delete_encoder, 0);
1617 8 : while (i < num_encoders+1) {
1618 4 : sdl_deserialize_key(sdl->encoders, encoders[i], &in);
1619 4 : sdl_deserialize_encoder(encoders[i], types, &in);
1620 4 : i++;
1621 : }
1622 : }
1623 :
1624 : /* deserialize bindings */
1625 2 : WSDL_CACHE_GET_INT(num_bindings, &in);
1626 2 : bindings = safe_emalloc(num_bindings, sizeof(sdlBindingPtr), 0);
1627 2 : if (num_bindings > 0) {
1628 2 : sdl->bindings = emalloc(sizeof(HashTable));
1629 2 : zend_hash_init(sdl->bindings, num_bindings, NULL, delete_binding, 0);
1630 4 : for (i = 0; i < num_bindings; i++) {
1631 2 : sdlBindingPtr binding = emalloc(sizeof(sdlBinding));
1632 2 : memset(binding, 0, sizeof(sdlBinding));
1633 2 : sdl_deserialize_key(sdl->bindings, binding, &in);
1634 2 : binding->name = sdl_deserialize_string(&in);
1635 2 : binding->location = sdl_deserialize_string(&in);
1636 2 : WSDL_CACHE_GET_1(binding->bindingType,sdlBindingType,&in);
1637 4 : if (binding->bindingType == BINDING_SOAP && *in != 0) {
1638 2 : sdlSoapBindingPtr soap_binding = binding->bindingAttributes = emalloc(sizeof(sdlSoapBinding));
1639 2 : WSDL_CACHE_GET_1(soap_binding->style,sdlEncodingStyle,&in);
1640 2 : WSDL_CACHE_GET_1(soap_binding->transport,sdlTransport,&in);
1641 : } else {
1642 0 : WSDL_CACHE_SKIP(1,&in);
1643 : }
1644 2 : bindings[i] = binding;
1645 : }
1646 : }
1647 :
1648 : /* deserialize functions */
1649 2 : WSDL_CACHE_GET_INT(num_func, &in);
1650 2 : zend_hash_init(&sdl->functions, num_func, NULL, delete_function, 0);
1651 2 : if (num_func > 0) {
1652 2 : functions = safe_emalloc(num_func, sizeof(sdlFunctionPtr), 0);
1653 5 : for (i = 0; i < num_func; i++) {
1654 : int binding_num, num_faults;
1655 3 : sdlFunctionPtr func = emalloc(sizeof(sdlFunction));
1656 3 : sdl_deserialize_key(&sdl->functions, func, &in);
1657 3 : func->functionName = sdl_deserialize_string(&in);
1658 3 : func->requestName = sdl_deserialize_string(&in);
1659 3 : func->responseName = sdl_deserialize_string(&in);
1660 :
1661 3 : WSDL_CACHE_GET_INT(binding_num, &in);
1662 3 : if (binding_num == 0) {
1663 0 : func->binding = NULL;
1664 : } else {
1665 3 : func->binding = bindings[binding_num-1];
1666 : }
1667 6 : if (func->binding && func->binding->bindingType == BINDING_SOAP && *in != 0) {
1668 3 : sdlSoapBindingFunctionPtr binding = func->bindingAttributes = emalloc(sizeof(sdlSoapBindingFunction));
1669 3 : memset(binding, 0, sizeof(sdlSoapBindingFunction));
1670 3 : WSDL_CACHE_GET_1(binding->style,sdlEncodingStyle,&in);
1671 3 : binding->soapAction = sdl_deserialize_string(&in);
1672 3 : sdl_deserialize_soap_body(&binding->input, encoders, types, &in);
1673 3 : sdl_deserialize_soap_body(&binding->output, encoders, types, &in);
1674 : } else {
1675 0 : WSDL_CACHE_SKIP(1, &in);
1676 0 : func->bindingAttributes = NULL;
1677 : }
1678 :
1679 3 : func->requestParameters = sdl_deserialize_parameters(encoders, types, &in);
1680 3 : func->responseParameters = sdl_deserialize_parameters(encoders, types, &in);
1681 :
1682 3 : WSDL_CACHE_GET_INT(num_faults, &in);
1683 3 : if (num_faults > 0) {
1684 : int j;
1685 :
1686 2 : func->faults = emalloc(sizeof(HashTable));
1687 2 : zend_hash_init(func->faults, num_faults, NULL, delete_fault, 0);
1688 :
1689 4 : for (j = 0; j < num_faults; j++) {
1690 2 : sdlFaultPtr fault = emalloc(sizeof(sdlFault));
1691 :
1692 2 : sdl_deserialize_key(func->faults, fault, &in);
1693 2 : fault->name =sdl_deserialize_string(&in);
1694 2 : fault->details =sdl_deserialize_parameters(encoders, types, &in);
1695 2 : if (*in != 0) {
1696 2 : sdlSoapBindingFunctionFaultPtr binding = fault->bindingAttributes = emalloc(sizeof(sdlSoapBindingFunctionFault));
1697 2 : memset(binding, 0, sizeof(sdlSoapBindingFunctionFault));
1698 2 : WSDL_CACHE_GET_1(binding->use,sdlEncodingUse,&in);
1699 2 : if (binding->use == SOAP_ENCODED) {
1700 2 : WSDL_CACHE_GET_1(binding->encodingStyle, sdlRpcEncodingStyle, &in);
1701 : } else {
1702 0 : binding->encodingStyle = SOAP_ENCODING_DEFAULT;
1703 : }
1704 2 : binding->ns = sdl_deserialize_string(&in);
1705 : } else {
1706 0 : WSDL_CACHE_SKIP(1, &in);
1707 0 : fault->bindingAttributes = NULL;
1708 : }
1709 : }
1710 : } else {
1711 1 : func->faults = NULL;
1712 : }
1713 3 : functions[i] = func;
1714 : }
1715 : }
1716 :
1717 : /* deserialize requests */
1718 2 : WSDL_CACHE_GET_INT(i, &in);
1719 2 : if (i > 0) {
1720 0 : sdl->requests = emalloc(sizeof(HashTable));
1721 0 : zend_hash_init(sdl->requests, i, NULL, NULL, 0);
1722 0 : while (i > 0) {
1723 : int function_num;
1724 :
1725 0 : WSDL_CACHE_GET_INT(function_num, &in);
1726 0 : sdl_deserialize_key(sdl->requests, functions[function_num-1], &in);
1727 0 : i--;
1728 : }
1729 : }
1730 :
1731 2 : if (functions) {
1732 2 : efree(functions);
1733 : }
1734 2 : efree(bindings);
1735 2 : efree(encoders);
1736 2 : efree(types);
1737 2 : efree(buf);
1738 2 : return sdl;
1739 : }
1740 :
1741 : static void sdl_serialize_string(const char *str, smart_str *out)
1742 734 : {
1743 : int i;
1744 :
1745 734 : if (str) {
1746 403 : i = strlen(str);
1747 403 : WSDL_CACHE_PUT_INT(i, out);
1748 403 : if (i > 0) {
1749 400 : WSDL_CACHE_PUT_N(str, i, out);
1750 : }
1751 : } else {
1752 331 : WSDL_CACHE_PUT_INT(0x7fffffff, out);
1753 : }
1754 734 : }
1755 :
1756 : static void sdl_serialize_key(HashTable *ht, smart_str *out)
1757 206 : {
1758 : char *key;
1759 : uint key_len;
1760 : ulong index;
1761 :
1762 206 : if (zend_hash_get_current_key_ex(ht, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
1763 144 : WSDL_CACHE_PUT_INT(key_len, out);
1764 144 : WSDL_CACHE_PUT_N(key, key_len, out);
1765 : } else {
1766 62 : WSDL_CACHE_PUT_INT(0, out);
1767 : }
1768 206 : }
1769 :
1770 130 : static void sdl_serialize_encoder_ref(encodePtr enc, HashTable *tmp_encoders, smart_str *out) {
1771 130 : if (enc) {
1772 : int *encoder_num;
1773 99 : if (zend_hash_find(tmp_encoders, (char*)&enc, sizeof(enc), (void**)&encoder_num) == SUCCESS) {
1774 99 : WSDL_CACHE_PUT_INT(*encoder_num, out);
1775 : } else {
1776 0 : WSDL_CACHE_PUT_INT(0, out);
1777 : }
1778 : } else {
1779 31 : WSDL_CACHE_PUT_INT(0, out);
1780 : }
1781 130 : }
1782 :
1783 106 : static void sdl_serialize_type_ref(sdlTypePtr type, HashTable *tmp_types, smart_str *out) {
1784 106 : if (type) {
1785 : int *type_num;
1786 94 : if (zend_hash_find(tmp_types, (char*)&type, sizeof(type), (void**)&type_num) == SUCCESS) {
1787 94 : WSDL_CACHE_PUT_INT(*type_num, out);
1788 : } else {
1789 0 : WSDL_CACHE_PUT_INT(0, out);
1790 : }
1791 : } else {
1792 12 : WSDL_CACHE_PUT_INT(0,out);
1793 : }
1794 106 : }
1795 :
1796 : static void sdl_serialize_attribute(sdlAttributePtr attr, HashTable *tmp_encoders, smart_str *out)
1797 16 : {
1798 : int i;
1799 :
1800 16 : sdl_serialize_string(attr->name, out);
1801 16 : sdl_serialize_string(attr->namens, out);
1802 16 : sdl_serialize_string(attr->ref, out);
1803 16 : sdl_serialize_string(attr->def, out);
1804 16 : sdl_serialize_string(attr->fixed, out);
1805 16 : WSDL_CACHE_PUT_1(attr->form, out);
1806 16 : WSDL_CACHE_PUT_1(attr->use, out);
1807 16 : sdl_serialize_encoder_ref(attr->encode, tmp_encoders, out);
1808 16 : if (attr->extraAttributes) {
1809 2 : i = zend_hash_num_elements(attr->extraAttributes);
1810 : } else {
1811 14 : i = 0;
1812 : }
1813 16 : WSDL_CACHE_PUT_INT(i, out);
1814 16 : if (i > 0) {
1815 : sdlExtraAttributePtr *tmp;
1816 2 : zend_hash_internal_pointer_reset(attr->extraAttributes);
1817 6 : while (zend_hash_get_current_data(attr->extraAttributes, (void**)&tmp) == SUCCESS) {
1818 2 : sdl_serialize_key(attr->extraAttributes, out);
1819 2 : sdl_serialize_string((*tmp)->ns, out);
1820 2 : sdl_serialize_string((*tmp)->val, out);
1821 2 : zend_hash_move_forward(attr->extraAttributes);
1822 : }
1823 : }
1824 16 : }
1825 :
1826 : static void sdl_serialize_model(sdlContentModelPtr model, HashTable *tmp_types, HashTable *tmp_elements, smart_str *out)
1827 71 : {
1828 71 : WSDL_CACHE_PUT_1(model->kind, out);
1829 71 : WSDL_CACHE_PUT_INT(model->min_occurs, out);
1830 71 : WSDL_CACHE_PUT_INT(model->max_occurs, out);
1831 71 : switch (model->kind) {
1832 : case XSD_CONTENT_ELEMENT:
1833 47 : sdl_serialize_type_ref(model->u.element, tmp_elements, out);
1834 47 : break;
1835 : case XSD_CONTENT_SEQUENCE:
1836 : case XSD_CONTENT_ALL:
1837 : case XSD_CONTENT_CHOICE: {
1838 : sdlContentModelPtr *tmp;
1839 24 : int i = zend_hash_num_elements(model->u.content);
1840 :
1841 24 : WSDL_CACHE_PUT_INT(i, out);
1842 24 : zend_hash_internal_pointer_reset(model->u.content);
1843 95 : while (zend_hash_get_current_data(model->u.content, (void**)&tmp) == SUCCESS) {
1844 47 : sdl_serialize_model(*tmp, tmp_types, tmp_elements, out);
1845 47 : zend_hash_move_forward(model->u.content);
1846 : }
1847 : }
1848 24 : break;
1849 : case XSD_CONTENT_GROUP_REF:
1850 0 : sdl_serialize_string(model->u.group_ref,out);
1851 0 : break;
1852 : case XSD_CONTENT_GROUP:
1853 0 : sdl_serialize_type_ref(model->u.group, tmp_types, out);
1854 : break;
1855 : default:
1856 : break;
1857 : }
1858 71 : }
1859 :
1860 : static void sdl_serialize_resriction_int(sdlRestrictionIntPtr x, smart_str *out)
1861 36 : {
1862 36 : if (x) {
1863 0 : WSDL_CACHE_PUT_1(1, out);
1864 0 : WSDL_CACHE_PUT_INT(x->value, out);
1865 0 : WSDL_CACHE_PUT_1(x->fixed, out);
1866 : } else {
1867 36 : WSDL_CACHE_PUT_1(0, out);
1868 : }
1869 36 : }
1870 :
1871 : static void sdl_serialize_resriction_char(sdlRestrictionCharPtr x, smart_str *out)
1872 32 : {
1873 32 : if (x) {
1874 24 : WSDL_CACHE_PUT_1(1, out);
1875 24 : sdl_serialize_string(x->value, out);
1876 24 : WSDL_CACHE_PUT_1(x->fixed, out);
1877 : } else {
1878 8 : WSDL_CACHE_PUT_1(0, out);
1879 : }
1880 32 : }
1881 :
1882 : static void sdl_serialize_type(sdlTypePtr type, HashTable *tmp_encoders, HashTable *tmp_types, smart_str *out)
1883 91 : {
1884 : int i;
1885 91 : HashTable *tmp_elements = NULL;
1886 :
1887 91 : WSDL_CACHE_PUT_1(type->kind, out);
1888 91 : sdl_serialize_string(type->name, out);
1889 91 : sdl_serialize_string(type->namens, out);
1890 91 : sdl_serialize_string(type->def, out);
1891 91 : sdl_serialize_string(type->fixed, out);
1892 91 : sdl_serialize_string(type->ref, out);
1893 91 : WSDL_CACHE_PUT_1(type->nillable, out);
1894 91 : WSDL_CACHE_PUT_1(type->form, out);
1895 91 : sdl_serialize_encoder_ref(type->encode, tmp_encoders, out);
1896 :
1897 91 : if (type->restrictions) {
1898 4 : WSDL_CACHE_PUT_1(1, out);
1899 4 : sdl_serialize_resriction_int(type->restrictions->minExclusive,out);
1900 4 : sdl_serialize_resriction_int(type->restrictions->minInclusive,out);
1901 4 : sdl_serialize_resriction_int(type->restrictions->maxExclusive,out);
1902 4 : sdl_serialize_resriction_int(type->restrictions->maxInclusive,out);
1903 4 : sdl_serialize_resriction_int(type->restrictions->totalDigits,out);
1904 4 : sdl_serialize_resriction_int(type->restrictions->fractionDigits,out);
1905 4 : sdl_serialize_resriction_int(type->restrictions->length,out);
1906 4 : sdl_serialize_resriction_int(type->restrictions->minLength,out);
1907 4 : sdl_serialize_resriction_int(type->restrictions->maxLength,out);
1908 4 : sdl_serialize_resriction_char(type->restrictions->whiteSpace,out);
1909 4 : sdl_serialize_resriction_char(type->restrictions->pattern,out);
1910 4 : if (type->restrictions->enumeration) {
1911 4 : i = zend_hash_num_elements(type->restrictions->enumeration);
1912 : } else {
1913 0 : i = 0;
1914 : }
1915 4 : WSDL_CACHE_PUT_INT(i, out);
1916 4 : if (i > 0) {
1917 : sdlRestrictionCharPtr *tmp;
1918 :
1919 4 : zend_hash_internal_pointer_reset(type->restrictions->enumeration);
1920 32 : while (zend_hash_get_current_data(type->restrictions->enumeration, (void**)&tmp) == SUCCESS) {
1921 24 : sdl_serialize_resriction_char(*tmp, out);
1922 24 : sdl_serialize_key(type->restrictions->enumeration, out);
1923 24 : zend_hash_move_forward(type->restrictions->enumeration);
1924 : }
1925 : }
1926 : } else {
1927 87 : WSDL_CACHE_PUT_1(0, out);
1928 : }
1929 91 : if (type->elements) {
1930 24 : i = zend_hash_num_elements(type->elements);
1931 : } else {
1932 67 : i = 0;
1933 : }
1934 91 : WSDL_CACHE_PUT_INT(i, out);
1935 91 : if (i > 0) {
1936 : sdlTypePtr *tmp;
1937 :
1938 24 : tmp_elements = emalloc(sizeof(HashTable));
1939 24 : zend_hash_init(tmp_elements, i, NULL, NULL, 0);
1940 :
1941 24 : zend_hash_internal_pointer_reset(type->elements);
1942 95 : while (zend_hash_get_current_data(type->elements, (void**)&tmp) == SUCCESS) {
1943 47 : sdl_serialize_key(type->elements, out);
1944 47 : sdl_serialize_type(*tmp, tmp_encoders, tmp_types, out);
1945 47 : zend_hash_add(tmp_elements, (char*)tmp, sizeof(*tmp), &i, sizeof(int), NULL);
1946 47 : i--;
1947 47 : zend_hash_move_forward(type->elements);
1948 : }
1949 : }
1950 :
1951 91 : if (type->attributes) {
1952 9 : i = zend_hash_num_elements(type->attributes);
1953 : } else {
1954 82 : i = 0;
1955 : }
1956 91 : WSDL_CACHE_PUT_INT(i, out);
1957 91 : if (i > 0) {
1958 : sdlAttributePtr *tmp;
1959 9 : zend_hash_internal_pointer_reset(type->attributes);
1960 34 : while (zend_hash_get_current_data(type->attributes, (void**)&tmp) == SUCCESS) {
1961 16 : sdl_serialize_key(type->attributes, out);
1962 16 : sdl_serialize_attribute(*tmp, tmp_encoders, out);
1963 16 : zend_hash_move_forward(type->attributes);
1964 : }
1965 : }
1966 91 : if (type->model) {
1967 24 : WSDL_CACHE_PUT_1(1, out);
1968 24 : sdl_serialize_model(type->model, tmp_types, tmp_elements, out);
1969 : } else {
1970 67 : WSDL_CACHE_PUT_1(0, out);
1971 : }
1972 91 : if (tmp_elements != NULL) {
1973 24 : zend_hash_destroy(tmp_elements);
1974 24 : efree(tmp_elements);
1975 : }
1976 91 : }
1977 :
1978 : static void sdl_serialize_encoder(encodePtr enc, HashTable *tmp_types, smart_str *out)
1979 36 : {
1980 36 : WSDL_CACHE_PUT_INT(enc->details.type, out);
1981 36 : sdl_serialize_string(enc->details.type_str, out);
1982 36 : sdl_serialize_string(enc->details.ns, out);
1983 36 : sdl_serialize_type_ref(enc->details.sdl_type, tmp_types, out);
1984 36 : }
1985 :
1986 : static void sdl_serialize_parameters(HashTable *ht, HashTable *tmp_encoders, HashTable *tmp_types, smart_str *out)
1987 18 : {
1988 : int i;
1989 :
1990 18 : if (ht) {
1991 18 : i = zend_hash_num_elements(ht);
1992 : } else {
1993 0 : i = 0;
1994 : }
1995 18 : WSDL_CACHE_PUT_INT(i, out);
1996 18 : if (i > 0) {
1997 : sdlParamPtr *tmp;
1998 :
1999 17 : zend_hash_internal_pointer_reset(ht);
2000 53 : while (zend_hash_get_current_data(ht, (void**)&tmp) == SUCCESS) {
2001 19 : sdl_serialize_key(ht, out);
2002 19 : sdl_serialize_string((*tmp)->paramName, out);
2003 19 : WSDL_CACHE_PUT_INT((*tmp)->order, out);
2004 19 : sdl_serialize_encoder_ref((*tmp)->encode, tmp_encoders, out);
2005 19 : sdl_serialize_type_ref((*tmp)->element, tmp_types, out);
2006 19 : zend_hash_move_forward(ht);
2007 : }
2008 : }
2009 18 : }
2010 :
2011 : static void sdl_serialize_soap_body(sdlSoapBindingFunctionBodyPtr body, HashTable *tmp_encoders, HashTable *tmp_types, smart_str *out)
2012 16 : {
2013 : int i, j;
2014 :
2015 16 : WSDL_CACHE_PUT_1(body->use, out);
2016 16 : if (body->use == SOAP_ENCODED) {
2017 6 : WSDL_CACHE_PUT_1(body->encodingStyle, out);
2018 : }
2019 16 : sdl_serialize_string(body->ns, out);
2020 16 : if (body->headers) {
2021 4 : i = zend_hash_num_elements(body->headers);
2022 : } else {
2023 12 : i = 0;
2024 : }
2025 16 : WSDL_CACHE_PUT_INT(i, out);
2026 16 : if (i > 0) {
2027 : sdlSoapBindingFunctionHeaderPtr *tmp;
2028 4 : zend_hash_internal_pointer_reset(body->headers);
2029 12 : while (zend_hash_get_current_data(body->headers, (void**)&tmp) == SUCCESS) {
2030 4 : sdl_serialize_key(body->headers, out);
2031 4 : WSDL_CACHE_PUT_1((*tmp)->use, out);
2032 4 : if ((*tmp)->use == SOAP_ENCODED) {
2033 0 : WSDL_CACHE_PUT_1((*tmp)->encodingStyle, out);
2034 : }
2035 4 : sdl_serialize_string((*tmp)->name, out);
2036 4 : sdl_serialize_string((*tmp)->ns, out);
2037 4 : sdl_serialize_encoder_ref((*tmp)->encode, tmp_encoders, out);
2038 4 : sdl_serialize_type_ref((*tmp)->element, tmp_types, out);
2039 4 : if ((*tmp)->headerfaults) {
2040 0 : j = zend_hash_num_elements((*tmp)->headerfaults);
2041 : } else {
2042 4 : j = 0;
2043 : }
2044 4 : WSDL_CACHE_PUT_INT(j, out);
2045 4 : if (j > 0) {
2046 : sdlSoapBindingFunctionHeaderPtr *tmp2;
2047 0 : zend_hash_internal_pointer_reset((*tmp)->headerfaults);
2048 0 : while (zend_hash_get_current_data((*tmp)->headerfaults, (void**)&tmp2) == SUCCESS) {
2049 0 : sdl_serialize_key((*tmp)->headerfaults, out);
2050 0 : WSDL_CACHE_PUT_1((*tmp2)->use, out);
2051 0 : if ((*tmp2)->use == SOAP_ENCODED) {
2052 0 : WSDL_CACHE_PUT_1((*tmp2)->encodingStyle, out);
2053 : }
2054 0 : sdl_serialize_string((*tmp2)->name, out);
2055 0 : sdl_serialize_string((*tmp2)->ns, out);
2056 0 : sdl_serialize_encoder_ref((*tmp2)->encode, tmp_encoders, out);
2057 0 : sdl_serialize_type_ref((*tmp2)->element, tmp_types, out);
2058 0 : zend_hash_move_forward((*tmp)->headerfaults);
2059 : }
2060 : }
2061 4 : zend_hash_move_forward(body->headers);
2062 : }
2063 : }
2064 16 : }
2065 :
2066 : static void add_sdl_to_cache(const char *fn, const char *uri, time_t t, sdlPtr sdl TSRMLS_DC)
2067 4 : {
2068 4 : smart_str buf = {0};
2069 4 : smart_str *out = &buf;
2070 : int i;
2071 4 : int type_num = 1;
2072 4 : int encoder_num = 1;
2073 : int f;
2074 : encodePtr enc;
2075 : HashTable tmp_types;
2076 : HashTable tmp_encoders;
2077 : HashTable tmp_bindings;
2078 : HashTable tmp_functions;
2079 :
2080 : #ifdef ZEND_WIN32
2081 : f = open(fn,O_CREAT|O_WRONLY|O_EXCL|O_BINARY,S_IREAD|S_IWRITE);
2082 : #else
2083 4 : f = open(fn,O_CREAT|O_WRONLY|O_EXCL|O_BINARY,S_IREAD|S_IWRITE|S_IROTH|S_IWOTH|S_IRGRP|S_IWGRP);
2084 : #endif
2085 4 : if (f < 0) {return;}
2086 :
2087 4 : zend_hash_init(&tmp_types, 0, NULL, NULL, 0);
2088 4 : zend_hash_init(&tmp_encoders, 0, NULL, NULL, 0);
2089 4 : zend_hash_init(&tmp_bindings, 0, NULL, NULL, 0);
2090 4 : zend_hash_init(&tmp_functions, 0, NULL, NULL, 0);
2091 :
2092 4 : WSDL_CACHE_PUT_N("wsdl", 4, out);
2093 4 : WSDL_CACHE_PUT_1(WSDL_CACHE_VERSION,out);
2094 4 : WSDL_CACHE_PUT_1(0,out);
2095 4 : WSDL_CACHE_PUT_N(&t, sizeof(t), out);
2096 :
2097 4 : sdl_serialize_string(uri, out);
2098 4 : sdl_serialize_string(sdl->source, out);
2099 4 : sdl_serialize_string(sdl->target_ns, out);
2100 :
2101 4 : if (sdl->groups) {
2102 0 : i = zend_hash_num_elements(sdl->groups);
2103 : } else {
2104 4 : i = 0;
2105 : }
2106 4 : WSDL_CACHE_PUT_INT(i, out);
2107 4 : if (i > 0) {
2108 : sdlTypePtr *tmp;
2109 :
2110 0 : zend_hash_internal_pointer_reset(sdl->groups);
2111 0 : while (zend_hash_get_current_data(sdl->groups, (void**)&tmp) == SUCCESS) {
2112 0 : zend_hash_add(&tmp_types, (char*)tmp, sizeof(*tmp), (void**)&type_num, sizeof(type_num), NULL);
2113 0 : ++type_num;
2114 0 : zend_hash_move_forward(sdl->groups);
2115 : }
2116 : }
2117 :
2118 4 : if (sdl->types) {
2119 4 : i = zend_hash_num_elements(sdl->types);
2120 : } else {
2121 0 : i = 0;
2122 : }
2123 4 : WSDL_CACHE_PUT_INT(i, out);
2124 4 : if (i > 0) {
2125 : sdlTypePtr *tmp;
2126 :
2127 4 : zend_hash_internal_pointer_reset(sdl->types);
2128 43 : while (zend_hash_get_current_data(sdl->types, (void**)&tmp) == SUCCESS) {
2129 35 : zend_hash_add(&tmp_types, (char*)tmp, sizeof(*tmp), (void**)&type_num, sizeof(type_num), NULL);
2130 35 : ++type_num;
2131 35 : zend_hash_move_forward(sdl->types);
2132 : }
2133 : }
2134 :
2135 4 : if (sdl->elements) {
2136 1 : i = zend_hash_num_elements(sdl->elements);
2137 : } else {
2138 3 : i = 0;
2139 : }
2140 4 : WSDL_CACHE_PUT_INT(i, out);
2141 4 : if (i > 0) {
2142 : sdlTypePtr *tmp;
2143 :
2144 1 : zend_hash_internal_pointer_reset(sdl->elements);
2145 11 : while (zend_hash_get_current_data(sdl->elements, (void**)&tmp) == SUCCESS) {
2146 9 : zend_hash_add(&tmp_types, (char*)tmp, sizeof(*tmp), (void**)&type_num, sizeof(type_num), NULL);
2147 9 : ++type_num;
2148 9 : zend_hash_move_forward(sdl->elements);
2149 : }
2150 : }
2151 :
2152 4 : if (sdl->encoders) {
2153 4 : i = zend_hash_num_elements(sdl->encoders);
2154 : } else {
2155 0 : i = 0;
2156 : }
2157 4 : WSDL_CACHE_PUT_INT(i, out);
2158 4 : if (i > 0) {
2159 : encodePtr *tmp;
2160 :
2161 4 : zend_hash_internal_pointer_reset(sdl->encoders);
2162 44 : while (zend_hash_get_current_data(sdl->encoders, (void**)&tmp) == SUCCESS) {
2163 36 : zend_hash_add(&tmp_encoders, (char*)tmp, sizeof(*tmp), (void**)&encoder_num, sizeof(encoder_num), NULL);
2164 36 : ++encoder_num;
2165 36 : zend_hash_move_forward(sdl->encoders);
2166 : }
2167 : }
2168 4 : enc = defaultEncoding;
2169 308 : while (enc->details.type != END_KNOWN_TYPES) {
2170 300 : zend_hash_add(&tmp_encoders, (char*)&enc, sizeof(encodePtr), (void**)&encoder_num, sizeof(encoder_num), NULL);
2171 300 : enc++;
2172 300 : ++encoder_num;
2173 : }
2174 :
2175 4 : if (sdl->groups) {
2176 : sdlTypePtr *tmp;
2177 0 : zend_hash_internal_pointer_reset(sdl->groups);
2178 0 : while (zend_hash_get_current_data(sdl->groups, (void**)&tmp) == SUCCESS) {
2179 0 : sdl_serialize_key(sdl->groups, out);
2180 0 : sdl_serialize_type(*tmp, &tmp_encoders, &tmp_types, out);
2181 0 : zend_hash_move_forward(sdl->groups);
2182 : }
2183 : }
2184 :
2185 4 : if (sdl->types) {
2186 : sdlTypePtr *tmp;
2187 4 : zend_hash_internal_pointer_reset(sdl->types);
2188 43 : while (zend_hash_get_current_data(sdl->types, (void**)&tmp) == SUCCESS) {
2189 35 : sdl_serialize_key(sdl->types, out);
2190 35 : sdl_serialize_type(*tmp, &tmp_encoders, &tmp_types, out);
2191 35 : zend_hash_move_forward(sdl->types);
2192 : }
2193 : }
2194 :
2195 4 : if (sdl->elements) {
2196 : sdlTypePtr *tmp;
2197 1 : zend_hash_internal_pointer_reset(sdl->elements);
2198 11 : while (zend_hash_get_current_data(sdl->elements, (void**)&tmp) == SUCCESS) {
2199 9 : sdl_serialize_key(sdl->elements, out);
2200 9 : sdl_serialize_type(*tmp, &tmp_encoders, &tmp_types, out);
2201 9 : zend_hash_move_forward(sdl->elements);
2202 : }
2203 : }
2204 :
2205 4 : if (sdl->encoders) {
2206 : encodePtr *tmp;
2207 4 : zend_hash_internal_pointer_reset(sdl->encoders);
2208 44 : while (zend_hash_get_current_data(sdl->encoders, (void**)&tmp) == SUCCESS) {
2209 36 : sdl_serialize_key(sdl->encoders, out);
2210 36 : sdl_serialize_encoder(*tmp, &tmp_types, out);
2211 36 : zend_hash_move_forward(sdl->encoders);
2212 : }
2213 : }
2214 :
2215 : /* serialize bindings */
2216 4 : if (sdl->bindings) {
2217 4 : i = zend_hash_num_elements(sdl->bindings);
2218 : } else {
2219 0 : i = 0;
2220 : }
2221 4 : WSDL_CACHE_PUT_INT(i, out);
2222 4 : if (i > 0) {
2223 : sdlBindingPtr *tmp;
2224 4 : int binding_num = 1;
2225 :
2226 4 : zend_hash_internal_pointer_reset(sdl->bindings);
2227 12 : while (zend_hash_get_current_data(sdl->bindings, (void**)&tmp) == SUCCESS) {
2228 4 : sdl_serialize_key(sdl->bindings, out);
2229 4 : sdl_serialize_string((*tmp)->name, out);
2230 4 : sdl_serialize_string((*tmp)->location, out);
2231 4 : WSDL_CACHE_PUT_1((*tmp)->bindingType,out);
2232 8 : if ((*tmp)->bindingType == BINDING_SOAP && (*tmp)->bindingAttributes != NULL) {
2233 4 : sdlSoapBindingPtr binding = (sdlSoapBindingPtr)(*tmp)->bindingAttributes;
2234 4 : WSDL_CACHE_PUT_1(binding->style, out);
2235 4 : WSDL_CACHE_PUT_1(binding->transport, out);
2236 : } else {
2237 0 : WSDL_CACHE_PUT_1(0,out);
2238 : }
2239 :
2240 4 : zend_hash_add(&tmp_bindings, (char*)tmp, sizeof(*tmp), (void**)&binding_num, sizeof(binding_num), NULL);
2241 4 : binding_num++;
2242 4 : zend_hash_move_forward(sdl->bindings);
2243 : }
2244 : }
2245 :
2246 : /* serialize functions */
2247 4 : i = zend_hash_num_elements(&sdl->functions);
2248 4 : WSDL_CACHE_PUT_INT(i, out);
2249 4 : if (i > 0) {
2250 : sdlFunctionPtr *tmp;
2251 : int *binding_num;
2252 4 : int function_num = 1;
2253 :
2254 4 : zend_hash_internal_pointer_reset(&sdl->functions);
2255 16 : while (zend_hash_get_current_data(&sdl->functions, (void**)&tmp) == SUCCESS) {
2256 8 : sdl_serialize_key(&sdl->functions, out);
2257 8 : sdl_serialize_string((*tmp)->functionName, out);
2258 8 : sdl_serialize_string((*tmp)->requestName, out);
2259 8 : sdl_serialize_string((*tmp)->responseName, out);
2260 :
2261 8 : if ((*tmp)->binding == NULL ||
2262 : zend_hash_find(&tmp_bindings,(char*)&(*tmp)->binding,sizeof((*tmp)->binding), (void**)&binding_num) != SUCCESS) {
2263 : }
2264 8 : WSDL_CACHE_PUT_INT(*binding_num, out);
2265 8 : if (*binding_num >= 0) {
2266 16 : if ((*tmp)->binding->bindingType == BINDING_SOAP && (*tmp)->bindingAttributes != NULL) {
2267 8 : sdlSoapBindingFunctionPtr binding = (sdlSoapBindingFunctionPtr)(*tmp)->bindingAttributes;
2268 8 : WSDL_CACHE_PUT_1(binding->style, out);
2269 8 : sdl_serialize_string(binding->soapAction, out);
2270 8 : sdl_serialize_soap_body(&binding->input, &tmp_encoders, &tmp_types, out);
2271 8 : sdl_serialize_soap_body(&binding->output, &tmp_encoders, &tmp_types, out);
2272 : } else {
2273 0 : WSDL_CACHE_PUT_1(0,out);
2274 : }
2275 : }
2276 8 : sdl_serialize_parameters((*tmp)->requestParameters, &tmp_encoders, &tmp_types, out);
2277 8 : sdl_serialize_parameters((*tmp)->responseParameters, &tmp_encoders, &tmp_types, out);
2278 :
2279 8 : if ((*tmp)->faults) {
2280 : sdlFaultPtr *fault;
2281 :
2282 2 : WSDL_CACHE_PUT_INT(zend_hash_num_elements((*tmp)->faults), out);
2283 :
2284 2 : zend_hash_internal_pointer_reset((*tmp)->faults);
2285 6 : while (zend_hash_get_current_data((*tmp)->faults, (void**)&fault) == SUCCESS) {
2286 2 : sdl_serialize_key((*tmp)->faults, out);
2287 2 : sdl_serialize_string((*fault)->name, out);
2288 2 : sdl_serialize_parameters((*fault)->details, &tmp_encoders, &tmp_types, out);
2289 4 : if ((*tmp)->binding->bindingType == BINDING_SOAP && (*fault)->bindingAttributes != NULL) {
2290 2 : sdlSoapBindingFunctionFaultPtr binding = (sdlSoapBindingFunctionFaultPtr)(*fault)->bindingAttributes;
2291 2 : WSDL_CACHE_PUT_1(binding->use, out);
2292 2 : if (binding->use == SOAP_ENCODED) {
2293 2 : WSDL_CACHE_PUT_1(binding->encodingStyle, out);
2294 : }
2295 2 : sdl_serialize_string(binding->ns, out);
2296 : } else {
2297 0 : WSDL_CACHE_PUT_1(0, out);
2298 : }
2299 2 : zend_hash_move_forward((*tmp)->faults);
2300 : }
2301 : } else {
2302 6 : WSDL_CACHE_PUT_INT(0, out);
2303 : }
2304 :
2305 8 : zend_hash_add(&tmp_functions, (char*)tmp, sizeof(*tmp), (void**)&function_num, sizeof(function_num), NULL);
2306 8 : function_num++;
2307 8 : zend_hash_move_forward(&sdl->functions);
2308 : }
2309 : }
2310 :
2311 : /* serialize requests */
2312 4 : if (sdl->requests) {
2313 0 : i = zend_hash_num_elements(sdl->requests);
2314 : } else {
2315 4 : i = 0;
2316 : }
2317 4 : WSDL_CACHE_PUT_INT(i, out);
2318 4 : if (i > 0) {
2319 : sdlFunctionPtr *tmp;
2320 : int *function_num;
2321 :
2322 0 : zend_hash_internal_pointer_reset(sdl->requests);
2323 0 : while (zend_hash_get_current_data(sdl->requests, (void**)&tmp) == SUCCESS) {
2324 0 : if (zend_hash_find(&tmp_functions, (char*)tmp, sizeof(*tmp), (void**)&function_num) != SUCCESS) {
2325 : }
2326 0 : WSDL_CACHE_PUT_INT(*function_num, out);
2327 0 : sdl_serialize_key(sdl->requests, out);
2328 0 : zend_hash_move_forward(sdl->requests);
2329 : }
2330 : }
2331 :
2332 4 : write(f, buf.c, buf.len);
2333 4 : close(f);
2334 4 : smart_str_free(&buf);
2335 4 : zend_hash_destroy(&tmp_functions);
2336 4 : zend_hash_destroy(&tmp_bindings);
2337 4 : zend_hash_destroy(&tmp_encoders);
2338 4 : zend_hash_destroy(&tmp_types);
2339 : }
2340 :
2341 :
2342 : static void make_persistent_restriction_int(void *data)
2343 0 : {
2344 0 : sdlRestrictionIntPtr *rest = (sdlRestrictionIntPtr *)data;
2345 0 : sdlRestrictionIntPtr prest = NULL;
2346 :
2347 0 : prest = malloc(sizeof(sdlRestrictionInt));
2348 0 : *prest = **rest;
2349 0 : *rest = prest;
2350 0 : }
2351 :
2352 :
2353 : static void make_persistent_restriction_char(void *data)
2354 0 : {
2355 0 : sdlRestrictionCharPtr *rest = (sdlRestrictionCharPtr *)data;
2356 0 : sdlRestrictionCharPtr prest = NULL;
2357 :
2358 0 : prest = malloc(sizeof(sdlRestrictionChar));
2359 0 : memset(prest, 0, sizeof(sdlRestrictionChar));
2360 0 : prest->value = strdup((*rest)->value);
2361 0 : prest->fixed = (*rest)->fixed;
2362 0 : *rest = prest;
2363 0 : }
2364 :
2365 :
2366 : static void make_persistent_sdl_type_ref(sdlTypePtr *type, HashTable *ptr_map, HashTable *bp_types)
2367 25 : {
2368 : sdlTypePtr *tmp;
2369 :
2370 25 : if (zend_hash_find(ptr_map, (char *)type, sizeof(sdlTypePtr), (void**)&tmp) == SUCCESS) {
2371 25 : *type = *tmp;
2372 : } else {
2373 0 : zend_hash_next_index_insert(bp_types, (void*)&type, sizeof(sdlTypePtr*), NULL);
2374 : }
2375 25 : }
2376 :
2377 :
2378 : static void make_persistent_sdl_encoder_ref(encodePtr *enc, HashTable *ptr_map, HashTable *bp_encoders)
2379 19 : {
2380 : encodePtr *tmp;
2381 :
2382 : /* do not process defaultEncoding's here */
2383 19 : if ((*enc) >= defaultEncoding && (*enc) < defaultEncoding + numDefaultEncodings) {
2384 16 : return;
2385 : }
2386 :
2387 3 : if (zend_hash_find(ptr_map, (char *)enc, sizeof(encodePtr), (void**)&tmp) == SUCCESS) {
2388 0 : *enc = *tmp;
2389 : } else {
2390 3 : zend_hash_next_index_insert(bp_encoders, (void*)&enc, sizeof(encodePtr*), NULL);
2391 : }
2392 : }
2393 :
2394 :
2395 : static HashTable* make_persistent_sdl_function_headers(HashTable *headers, HashTable *ptr_map)
2396 0 : {
2397 : HashTable *pheaders;
2398 : sdlSoapBindingFunctionHeaderPtr *tmp, pheader;
2399 : encodePtr *penc;
2400 : sdlTypePtr *ptype;
2401 : ulong index;
2402 : char *key;
2403 : uint key_len;
2404 :
2405 0 : pheaders = malloc(sizeof(HashTable));
2406 0 : zend_hash_init(pheaders, zend_hash_num_elements(headers), NULL, delete_header_persistent, 1);
2407 :
2408 0 : zend_hash_internal_pointer_reset(headers);
2409 0 : while (zend_hash_get_current_data(headers, (void**)&tmp) == SUCCESS) {
2410 0 : pheader = malloc(sizeof(sdlSoapBindingFunctionHeader));
2411 0 : memset(pheader, 0, sizeof(sdlSoapBindingFunctionHeader));
2412 0 : *pheader = **tmp;
2413 :
2414 0 : if (pheader->name) {
2415 0 : pheader->name = strdup(pheader->name);
2416 : }
2417 0 : if (pheader->ns) {
2418 0 : pheader->ns = strdup(pheader->ns);
2419 : }
2420 :
2421 0 : if (pheader->encode->details.sdl_type) {
2422 0 : if (zend_hash_find(ptr_map, (char*)&pheader->encode, sizeof(encodePtr), (void**)&penc) == FAILURE) {
2423 : assert(0);
2424 : }
2425 0 : pheader->encode = *penc;
2426 : }
2427 0 : if (pheader->element) {
2428 0 : if (zend_hash_find(ptr_map, (char*)&pheader->element, sizeof(sdlTypePtr), (void**)&ptype) == FAILURE) {
2429 : assert(0);
2430 : }
2431 0 : pheader->element = *ptype;
2432 : }
2433 :
2434 0 : if (pheader->headerfaults) {
2435 0 : pheader->headerfaults = make_persistent_sdl_function_headers(pheader->headerfaults, ptr_map);
2436 : }
2437 :
2438 0 : if (zend_hash_get_current_key_ex(headers, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
2439 0 : zend_hash_add(pheaders, key, key_len, (void*)&pheader, sizeof(sdlSoapBindingFunctionHeaderPtr), NULL);
2440 : } else {
2441 0 : zend_hash_next_index_insert(pheaders, (void*)&pheader, sizeof(sdlSoapBindingFunctionHeaderPtr), NULL);
2442 : }
2443 :
2444 0 : zend_hash_move_forward(headers);
2445 : }
2446 :
2447 0 : return pheaders;
2448 : }
2449 :
2450 :
2451 : static void make_persistent_sdl_soap_body(sdlSoapBindingFunctionBodyPtr body, HashTable *ptr_map)
2452 2 : {
2453 2 : if (body->ns) {
2454 2 : body->ns = strdup(body->ns);
2455 : }
2456 :
2457 2 : if (body->headers) {
2458 0 : body->headers = make_persistent_sdl_function_headers(body->headers, ptr_map);
2459 : }
2460 2 : }
2461 :
2462 :
2463 : static HashTable* make_persistent_sdl_parameters(HashTable *params, HashTable *ptr_map)
2464 2 : {
2465 : HashTable *pparams;
2466 : sdlParamPtr *tmp, pparam;
2467 : sdlTypePtr *ptype;
2468 : encodePtr *penc;
2469 : ulong index;
2470 : char *key;
2471 : uint key_len;
2472 :
2473 2 : pparams = malloc(sizeof(HashTable));
2474 2 : zend_hash_init(pparams, zend_hash_num_elements(params), NULL, delete_parameter_persistent, 1);
2475 :
2476 2 : zend_hash_internal_pointer_reset(params);
2477 8 : while (zend_hash_get_current_data(params, (void**)&tmp) == SUCCESS) {
2478 4 : pparam = malloc(sizeof(sdlParam));
2479 4 : memset(pparam, 0, sizeof(sdlParam));
2480 4 : *pparam = **tmp;
2481 :
2482 4 : if (pparam->paramName) {
2483 4 : pparam->paramName = strdup(pparam->paramName);
2484 : }
2485 :
2486 4 : if (pparam->encode && pparam->encode->details.sdl_type) {
2487 2 : if (zend_hash_find(ptr_map, (char*)&pparam->encode, sizeof(encodePtr), (void**)&penc) == FAILURE) {
2488 : assert(0);
2489 : }
2490 2 : pparam->encode = *penc;
2491 : }
2492 4 : if (pparam->element) {
2493 0 : if (zend_hash_find(ptr_map, (char*)&pparam->element, sizeof(sdlTypePtr), (void**)&ptype) == FAILURE) {
2494 : assert(0);
2495 : }
2496 0 : pparam->element = *ptype;
2497 : }
2498 :
2499 4 : if (zend_hash_get_current_key_ex(params, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
2500 0 : zend_hash_add(pparams, key, key_len, (void*)&pparam, sizeof(sdlParamPtr), NULL);
2501 : } else {
2502 4 : zend_hash_next_index_insert(pparams, (void*)&pparam, sizeof(sdlParamPtr), NULL);
2503 : }
2504 :
2505 4 : zend_hash_move_forward(params);
2506 : }
2507 :
2508 :
2509 2 : return pparams;
2510 : }
2511 :
2512 : static HashTable* make_persistent_sdl_function_faults(sdlFunctionPtr func, HashTable *faults, HashTable *ptr_map)
2513 0 : {
2514 : HashTable *pfaults;
2515 : sdlFaultPtr *tmp, pfault;
2516 : ulong index;
2517 : char *key;
2518 : uint key_len;
2519 :
2520 0 : pfaults = malloc(sizeof(HashTable));
2521 0 : zend_hash_init(pfaults, zend_hash_num_elements(faults), NULL, delete_fault_persistent, 1);
2522 :
2523 0 : zend_hash_internal_pointer_reset(faults);
2524 0 : while (zend_hash_get_current_data(faults, (void**)&tmp) == SUCCESS) {
2525 0 : pfault = malloc(sizeof(sdlFault));
2526 0 : memset(pfault, 0, sizeof(sdlFault));
2527 0 : *pfault = **tmp;
2528 :
2529 0 : if (pfault->name) {
2530 0 : pfault->name = strdup(pfault->name);
2531 : }
2532 0 : if (pfault->details) {
2533 0 : pfault->details = make_persistent_sdl_parameters(pfault->details, ptr_map);
2534 : }
2535 :
2536 0 : if (func->binding->bindingType == BINDING_SOAP && pfault->bindingAttributes) {
2537 : sdlSoapBindingFunctionFaultPtr soap_binding;
2538 :
2539 0 : soap_binding = malloc(sizeof(sdlSoapBindingFunctionFault));
2540 0 : memset(soap_binding, 0, sizeof(sdlSoapBindingFunctionFault));
2541 0 : *soap_binding = *(sdlSoapBindingFunctionFaultPtr)pfault->bindingAttributes;
2542 0 : if (soap_binding->ns) {
2543 0 : soap_binding->ns = strdup(soap_binding->ns);
2544 : }
2545 0 : pfault->bindingAttributes = soap_binding;
2546 : }
2547 :
2548 0 : if (zend_hash_get_current_key_ex(faults, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
2549 0 : zend_hash_add(pfaults, key, key_len, (void*)&pfault, sizeof(sdlParamPtr), NULL);
2550 : } else {
2551 0 : zend_hash_next_index_insert(pfaults, (void*)&pfault, sizeof(sdlParamPtr), NULL);
2552 : }
2553 :
2554 0 : zend_hash_move_forward(faults);
2555 : }
2556 :
2557 :
2558 0 : return pfaults;
2559 : }
2560 :
2561 :
2562 : static sdlAttributePtr make_persistent_sdl_attribute(sdlAttributePtr attr, HashTable *ptr_map, HashTable *bp_types, HashTable *bp_encoders)
2563 2 : {
2564 : sdlAttributePtr pattr;
2565 : ulong index;
2566 : char *key;
2567 : uint key_len;
2568 :
2569 2 : pattr = malloc(sizeof(sdlAttribute));
2570 2 : memset(pattr, 0, sizeof(sdlAttribute));
2571 :
2572 2 : *pattr = *attr;
2573 :
2574 2 : if (pattr->name) {
2575 2 : pattr->name = strdup(pattr->name);
2576 : }
2577 2 : if (pattr->namens) {
2578 2 : pattr->namens = strdup(pattr->namens);
2579 : }
2580 2 : if (pattr->ref) {
2581 0 : pattr->ref = strdup(pattr->ref);
2582 : }
2583 2 : if (pattr->def) {
2584 0 : pattr->def = strdup(pattr->def);
2585 : }
2586 2 : if (pattr->fixed) {
2587 0 : pattr->fixed = strdup(pattr->fixed);
2588 : }
2589 :
2590 : /* we do not want to process defaultEncoding's here */
2591 2 : if (pattr->encode) {
2592 0 : make_persistent_sdl_encoder_ref(&pattr->encode, ptr_map, bp_encoders);
2593 : }
2594 :
2595 2 : if (pattr->extraAttributes) {
2596 : sdlExtraAttributePtr *tmp, pextra;
2597 :
2598 2 : pattr->extraAttributes = malloc(sizeof(HashTable));
2599 2 : zend_hash_init(pattr->extraAttributes, zend_hash_num_elements(attr->extraAttributes), NULL, delete_extra_attribute_persistent, 1);
2600 :
2601 2 : zend_hash_internal_pointer_reset(pattr->extraAttributes);
2602 4 : while (zend_hash_get_current_data(attr->extraAttributes, (void**)&tmp) == SUCCESS) {
2603 0 : pextra = malloc(sizeof(sdlExtraAttribute));
2604 0 : memset(pextra, 0, sizeof(sdlExtraAttribute));
2605 0 : if ((*tmp)->ns) {
2606 0 : pextra->ns = strdup((*tmp)->ns);
2607 : }
2608 0 : if ((*tmp)->val) {
2609 0 : pextra->val = strdup((*tmp)->val);
2610 : }
2611 :
2612 0 : if (zend_hash_get_current_key_ex(attr->extraAttributes, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
2613 0 : zend_hash_add(pattr->extraAttributes, key, key_len, (void*)&pextra, sizeof(sdlExtraAttributePtr), NULL);
2614 : }
2615 :
2616 0 : zend_hash_move_forward(attr->extraAttributes);
2617 : }
2618 : }
2619 :
2620 2 : return pattr;
2621 : }
2622 :
2623 :
2624 : static sdlContentModelPtr make_persistent_sdl_model(sdlContentModelPtr model, HashTable *ptr_map, HashTable *bp_types, HashTable *bp_encoders)
2625 23 : {
2626 : sdlContentModelPtr pmodel;
2627 : sdlContentModelPtr *tmp, pcontent;
2628 :
2629 23 : pmodel = malloc(sizeof(sdlContentModel));
2630 23 : memset(pmodel, 0, sizeof(sdlContentModel));
2631 23 : *pmodel = *model;
2632 :
2633 23 : switch (pmodel->kind) {
2634 : case XSD_CONTENT_ELEMENT:
2635 17 : if (pmodel->u.element) {
2636 17 : make_persistent_sdl_type_ref(&pmodel->u.element, ptr_map, bp_types);
2637 : }
2638 17 : break;
2639 :
2640 : case XSD_CONTENT_SEQUENCE:
2641 : case XSD_CONTENT_ALL:
2642 : case XSD_CONTENT_CHOICE:
2643 6 : pmodel->u.content = malloc(sizeof(HashTable));
2644 6 : zend_hash_init(pmodel->u.content, zend_hash_num_elements(model->u.content), NULL, delete_model_persistent, 1);
2645 :
2646 6 : zend_hash_internal_pointer_reset(model->u.content);
2647 29 : while (zend_hash_get_current_data(model->u.content, (void**)&tmp) == SUCCESS) {
2648 17 : pcontent = make_persistent_sdl_model(*tmp, ptr_map, bp_types, bp_encoders);
2649 17 : zend_hash_next_index_insert(pmodel->u.content, (void*)&pcontent, sizeof(sdlContentModelPtr), NULL);
2650 17 : zend_hash_move_forward(model->u.content);
2651 : }
2652 6 : break;
2653 :
2654 : case XSD_CONTENT_GROUP_REF:
2655 0 : if (pmodel->u.group_ref) {
2656 0 : pmodel->u.group_ref = strdup(pmodel->u.group_ref);
2657 : }
2658 0 : break;
2659 :
2660 : case XSD_CONTENT_GROUP:
2661 0 : if (pmodel->u.group) {
2662 0 : make_persistent_sdl_type_ref(&pmodel->u.group, ptr_map, bp_types);
2663 : }
2664 : break;
2665 :
2666 : default:
2667 : break;
2668 : }
2669 :
2670 23 : return pmodel;
2671 : }
2672 :
2673 :
2674 : static sdlTypePtr make_persistent_sdl_type(sdlTypePtr type, HashTable *ptr_map, HashTable *bp_types, HashTable *bp_encoders)
2675 25 : {
2676 : ulong index;
2677 : char *key;
2678 : uint key_len;
2679 25 : sdlTypePtr ptype = NULL;
2680 :
2681 25 : ptype = malloc(sizeof(sdlType));
2682 25 : memset(ptype, 0, sizeof(sdlType));
2683 :
2684 25 : *ptype = *type;
2685 :
2686 25 : if (ptype->name) {
2687 25 : ptype->name = strdup(ptype->name);
2688 : }
2689 25 : if (ptype->namens) {
2690 25 : ptype->namens = strdup(ptype->namens);
2691 : }
2692 25 : if (ptype->def) {
2693 0 : ptype->def = strdup(ptype->def);
2694 : }
2695 25 : if (ptype->fixed) {
2696 0 : ptype->fixed = strdup(ptype->fixed);
2697 : }
2698 25 : if (ptype->ref) {
2699 0 : ptype->ref = strdup(ptype->ref);
2700 : }
2701 :
2702 : /* we do not want to process defaultEncoding's here */
2703 25 : if (ptype->encode) {
2704 19 : make_persistent_sdl_encoder_ref(&ptype->encode, ptr_map, bp_encoders);
2705 : }
2706 :
2707 25 : if (ptype->restrictions) {
2708 0 : ptype->restrictions = malloc(sizeof(sdlRestrictions));
2709 0 : memset(ptype->restrictions, 0, sizeof(sdlRestrictions));
2710 0 : *ptype->restrictions = *type->restrictions;
2711 :
2712 0 : if (ptype->restrictions->minExclusive) {
2713 0 : make_persistent_restriction_int(&ptype->restrictions->minExclusive);
2714 : }
2715 0 : if (ptype->restrictions->maxExclusive) {
2716 0 : make_persistent_restriction_int(&ptype->restrictions->maxExclusive);
2717 : }
2718 0 : if (ptype->restrictions->minInclusive) {
2719 0 : make_persistent_restriction_int(&ptype->restrictions->minInclusive);
2720 : }
2721 0 : if (ptype->restrictions->maxInclusive) {
2722 0 : make_persistent_restriction_int(&ptype->restrictions->maxInclusive);
2723 : }
2724 0 : if (ptype->restrictions->totalDigits) {
2725 0 : make_persistent_restriction_int(&ptype->restrictions->totalDigits);
2726 : }
2727 0 : if (ptype->restrictions->fractionDigits) {
2728 0 : make_persistent_restriction_int(&ptype->restrictions->fractionDigits);
2729 : }
2730 0 : if (ptype->restrictions->length) {
2731 0 : make_persistent_restriction_int(&ptype->restrictions->length);
2732 : }
2733 0 : if (ptype->restrictions->minLength) {
2734 0 : make_persistent_restriction_int(&ptype->restrictions->minLength);
2735 : }
2736 0 : if (ptype->restrictions->maxLength) {
2737 0 : make_persistent_restriction_int(&ptype->restrictions->maxLength);
2738 : }
2739 0 : if (ptype->restrictions->whiteSpace) {
2740 0 : make_persistent_restriction_char(&ptype->restrictions->whiteSpace);
2741 : }
2742 0 : if (ptype->restrictions->pattern) {
2743 0 : make_persistent_restriction_char(&ptype->restrictions->pattern);
2744 : }
2745 :
2746 0 : if (type->restrictions->enumeration) {
2747 : sdlRestrictionCharPtr tmp;
2748 :
2749 0 : ptype->restrictions->enumeration = malloc(sizeof(HashTable));
2750 0 : zend_hash_init(ptype->restrictions->enumeration, zend_hash_num_elements(type->restrictions->enumeration), NULL, delete_restriction_var_char_persistent, 1);
2751 0 : zend_hash_copy(ptype->restrictions->enumeration, type->restrictions->enumeration, make_persistent_restriction_char, (void*)&tmp, sizeof(sdlRestrictionCharPtr));
2752 : }
2753 : }
2754 :
2755 25 : if (ptype->elements) {
2756 : sdlTypePtr *tmp, pelem;
2757 :
2758 6 : ptype->elements = malloc(sizeof(HashTable));
2759 6 : zend_hash_init(ptype->elements, zend_hash_num_elements(type->elements), NULL, delete_type_persistent, 1);
2760 :
2761 6 : zend_hash_internal_pointer_reset(type->elements);
2762 29 : while (zend_hash_get_current_data(type->elements, (void **)&tmp) == SUCCESS) {
2763 17 : pelem = make_persistent_sdl_type(*tmp, ptr_map, bp_types, bp_encoders);
2764 17 : if (zend_hash_get_current_key_ex(type->elements, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
2765 17 : zend_hash_add(ptype->elements, key, key_len, (void*)&pelem, sizeof(sdlTypePtr), NULL);
2766 : } else {
2767 0 : zend_hash_next_index_insert(ptype->elements, (void*)&pelem, sizeof(sdlTypePtr), NULL);
2768 : }
2769 17 : zend_hash_add(ptr_map, (char*)tmp, sizeof(*tmp), (void*)&pelem, sizeof(sdlTypePtr), NULL);
2770 17 : zend_hash_move_forward(type->elements);
2771 : }
2772 : }
2773 :
2774 25 : if (ptype->attributes) {
2775 : sdlAttributePtr *tmp, pattr;
2776 :
2777 2 : ptype->attributes = malloc(sizeof(HashTable));
2778 2 : zend_hash_init(ptype->attributes, zend_hash_num_elements(type->attributes), NULL, delete_attribute_persistent, 1);
2779 :
2780 2 : zend_hash_internal_pointer_reset(type->attributes);
2781 6 : while (zend_hash_get_current_data(type->attributes, (void **)&tmp) == SUCCESS) {
2782 2 : pattr = make_persistent_sdl_attribute(*tmp, ptr_map, bp_types, bp_encoders);
2783 2 : if (zend_hash_get_current_key_ex(type->attributes, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
2784 2 : zend_hash_add(ptype->attributes, key, key_len, (void*)&pattr, sizeof(sdlAttributePtr), NULL);
2785 : } else {
2786 0 : zend_hash_next_index_insert(ptype->attributes, (void*)&pattr, sizeof(sdlAttributePtr), NULL);
2787 : }
2788 2 : zend_hash_move_forward(type->attributes);
2789 : }
2790 : }
2791 :
2792 25 : if (type->model) {
2793 6 : ptype->model = make_persistent_sdl_model(ptype->model, ptr_map, bp_types, bp_encoders);
2794 : }
2795 :
2796 25 : return ptype;
2797 : }
2798 :
2799 : static encodePtr make_persistent_sdl_encoder(encodePtr enc, HashTable *ptr_map, HashTable *bp_types, HashTable *bp_encoders)
2800 8 : {
2801 8 : encodePtr penc = NULL;
2802 :
2803 8 : penc = malloc(sizeof(encode));
2804 8 : memset(penc, 0, sizeof(encode));
2805 :
2806 8 : *penc = *enc;
2807 :
2808 8 : if (penc->details.type_str) {
2809 8 : penc->details.type_str = strdup(penc->details.type_str);
2810 : }
2811 8 : if (penc->details.ns) {
2812 8 : penc->details.ns = strdup(penc->details.ns);
2813 : }
2814 :
2815 8 : if (penc->details.sdl_type) {
2816 8 : make_persistent_sdl_type_ref(&penc->details.sdl_type, ptr_map, bp_types);
2817 : }
2818 :
2819 8 : return penc;
2820 : }
2821 :
2822 : static sdlBindingPtr make_persistent_sdl_binding(sdlBindingPtr bind, HashTable *ptr_map)
2823 1 : {
2824 1 : sdlBindingPtr pbind = NULL;
2825 :
2826 1 : pbind = malloc(sizeof(sdlBinding));
2827 1 : memset(pbind, 0, sizeof(sdlBinding));
2828 :
2829 1 : *pbind = *bind;
2830 :
2831 1 : if (pbind->name) {
2832 1 : pbind->name = strdup(pbind->name);
2833 : }
2834 1 : if (pbind->location) {
2835 1 : pbind->location = strdup(pbind->location);
2836 : }
2837 :
2838 1 : if (pbind->bindingType == BINDING_SOAP && pbind->bindingAttributes) {
2839 : sdlSoapBindingPtr soap_binding;
2840 :
2841 1 : soap_binding = malloc(sizeof(sdlSoapBinding));
2842 1 : memset(soap_binding, 0, sizeof(sdlSoapBinding));
2843 1 : *soap_binding = *(sdlSoapBindingPtr)pbind->bindingAttributes;
2844 1 : pbind->bindingAttributes = soap_binding;
2845 : }
2846 :
2847 1 : return pbind;
2848 : }
2849 :
2850 : static sdlFunctionPtr make_persistent_sdl_function(sdlFunctionPtr func, HashTable *ptr_map)
2851 1 : {
2852 1 : sdlFunctionPtr pfunc = NULL;
2853 :
2854 1 : pfunc = malloc(sizeof(sdlFunction));
2855 1 : memset(pfunc, 0, sizeof(sdlFunction));
2856 :
2857 1 : *pfunc = *func;
2858 :
2859 1 : if (pfunc->functionName) {
2860 1 : pfunc->functionName = strdup(pfunc->functionName);
2861 : }
2862 1 : if (pfunc->requestName) {
2863 1 : pfunc->requestName = strdup(pfunc->requestName);
2864 : }
2865 1 : if (pfunc->responseName) {
2866 1 : pfunc->responseName = strdup(pfunc->responseName);
2867 : }
2868 :
2869 1 : if (pfunc->binding) {
2870 : sdlBindingPtr *tmp;
2871 :
2872 1 : if (zend_hash_find(ptr_map, (char*)&pfunc->binding, sizeof(pfunc->binding), (void**)&tmp) == FAILURE) {
2873 : assert(0);
2874 : }
2875 1 : pfunc->binding = *tmp;
2876 :
2877 1 : if (pfunc->binding->bindingType == BINDING_SOAP && pfunc->bindingAttributes) {
2878 : sdlSoapBindingFunctionPtr soap_binding;
2879 :
2880 1 : soap_binding = malloc(sizeof(sdlSoapBindingFunction));
2881 1 : memset(soap_binding, 0, sizeof(sdlSoapBindingFunction));
2882 1 : *soap_binding = *(sdlSoapBindingFunctionPtr)pfunc->bindingAttributes;
2883 1 : if (soap_binding->soapAction) {
2884 1 : soap_binding->soapAction = strdup(soap_binding->soapAction);
2885 : }
2886 1 : make_persistent_sdl_soap_body(&soap_binding->input, ptr_map);
2887 1 : make_persistent_sdl_soap_body(&soap_binding->output, ptr_map);
2888 1 : pfunc->bindingAttributes = soap_binding;
2889 : }
2890 :
2891 1 : if (pfunc->requestParameters) {
2892 1 : pfunc->requestParameters = make_persistent_sdl_parameters(pfunc->requestParameters, ptr_map);
2893 : }
2894 1 : if (pfunc->responseParameters) {
2895 1 : pfunc->responseParameters = make_persistent_sdl_parameters(pfunc->responseParameters, ptr_map);
2896 : }
2897 1 : if (pfunc->faults) {
2898 0 : pfunc->faults = make_persistent_sdl_function_faults(pfunc, pfunc->faults, ptr_map);
2899 : }
2900 : }
2901 :
2902 1 : return pfunc;
2903 : }
2904 :
2905 : static sdlPtr make_persistent_sdl(sdlPtr sdl TSRMLS_DC)
2906 1 : {
2907 1 : sdlPtr psdl = NULL;
2908 : HashTable ptr_map;
2909 : HashTable bp_types, bp_encoders;
2910 : ulong index;
2911 : char *key;
2912 : uint key_len;
2913 :
2914 1 : zend_hash_init(&bp_types, 0, NULL, NULL, 0);
2915 1 : zend_hash_init(&bp_encoders, 0, NULL, NULL, 0);
2916 1 : zend_hash_init(&ptr_map, 0, NULL, NULL, 0);
2917 :
2918 1 : psdl = malloc(sizeof(*sdl));
2919 1 : memset(psdl, 0, sizeof(*sdl));
2920 :
2921 1 : if (sdl->source) {
2922 1 : psdl->source = strdup(sdl->source);
2923 : }
2924 1 : if (sdl->target_ns) {
2925 1 : psdl->target_ns = strdup(sdl->target_ns);
2926 : }
2927 :
2928 1 : if (sdl->groups) {
2929 : sdlTypePtr *tmp;
2930 : sdlTypePtr ptype;
2931 :
2932 0 : psdl->groups = malloc(sizeof(HashTable));
2933 0 : zend_hash_init(psdl->groups, zend_hash_num_elements(sdl->groups), NULL, delete_type_persistent, 1);
2934 :
2935 0 : zend_hash_internal_pointer_reset(sdl->groups);
2936 0 : while (zend_hash_get_current_data(sdl->groups, (void **)&tmp) == SUCCESS) {
2937 0 : ptype = make_persistent_sdl_type(*tmp, &ptr_map, &bp_types, &bp_encoders);
2938 0 : if (zend_hash_get_current_key_ex(sdl->groups, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
2939 0 : zend_hash_add(psdl->groups, key, key_len, (void*)&ptype, sizeof(sdlTypePtr), NULL);
2940 : } else {
2941 0 : zend_hash_next_index_insert(psdl->groups, (void*)&ptype, sizeof(sdlTypePtr), NULL);
2942 : }
2943 0 : zend_hash_add(&ptr_map, (char*)tmp, sizeof(*tmp), (void*)&ptype, sizeof(sdlTypePtr), NULL);
2944 0 : zend_hash_move_forward(sdl->groups);
2945 : }
2946 : }
2947 :
2948 1 : if (sdl->types) {
2949 : sdlTypePtr *tmp;
2950 : sdlTypePtr ptype;
2951 :
2952 1 : psdl->types = malloc(sizeof(HashTable));
2953 1 : zend_hash_init(psdl->types, zend_hash_num_elements(sdl->types), NULL, delete_type_persistent, 1);
2954 :
2955 1 : zend_hash_internal_pointer_reset(sdl->types);
2956 10 : while (zend_hash_get_current_data(sdl->types, (void **)&tmp) == SUCCESS) {
2957 8 : ptype = make_persistent_sdl_type(*tmp, &ptr_map, &bp_types, &bp_encoders);
2958 8 : if (zend_hash_get_current_key_ex(sdl->types, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
2959 0 : zend_hash_add(psdl->types, key, key_len, (void*)&ptype, sizeof(sdlTypePtr), NULL);
2960 : } else {
2961 8 : zend_hash_next_index_insert(psdl->types, (void*)&ptype, sizeof(sdlTypePtr), NULL);
2962 : }
2963 8 : zend_hash_add(&ptr_map, (char*)tmp, sizeof(*tmp), (void*)&ptype, sizeof(sdlTypePtr), NULL);
2964 8 : zend_hash_move_forward(sdl->types);
2965 : }
2966 : }
2967 :
2968 1 : if (sdl->elements) {
2969 : sdlTypePtr *tmp;
2970 : sdlTypePtr ptype;
2971 :
2972 0 : psdl->elements = malloc(sizeof(HashTable));
2973 0 : zend_hash_init(psdl->elements, zend_hash_num_elements(sdl->elements), NULL, delete_type_persistent, 1);
2974 :
2975 0 : zend_hash_internal_pointer_reset(sdl->elements);
2976 0 : while (zend_hash_get_current_data(sdl->elements, (void **)&tmp) == SUCCESS) {
2977 0 : ptype = make_persistent_sdl_type(*tmp, &ptr_map, &bp_types, &bp_encoders);
2978 0 : if (zend_hash_get_current_key_ex(sdl->elements, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
2979 0 : zend_hash_add(psdl->elements, key, key_len, (void*)&ptype, sizeof(sdlTypePtr), NULL);
2980 : } else {
2981 0 : zend_hash_next_index_insert(psdl->elements, (void*)&ptype, sizeof(sdlTypePtr), NULL);
2982 : }
2983 0 : zend_hash_add(&ptr_map, (char*)tmp, sizeof(*tmp), (void*)&ptype, sizeof(sdlTypePtr), NULL);
2984 0 : zend_hash_move_forward(sdl->elements);
2985 : }
2986 : }
2987 :
2988 1 : if (sdl->encoders) {
2989 : encodePtr *tmp;
2990 : encodePtr penc;
2991 :
2992 1 : psdl->encoders = malloc(sizeof(HashTable));
2993 1 : zend_hash_init(psdl->encoders, zend_hash_num_elements(sdl->encoders), NULL, delete_encoder_persistent, 1);
2994 :
2995 1 : zend_hash_internal_pointer_reset(sdl->encoders);
2996 10 : while (zend_hash_get_current_data(sdl->encoders, (void **)&tmp) == SUCCESS) {
2997 8 : penc = make_persistent_sdl_encoder(*tmp, &ptr_map, &bp_types, &bp_encoders);
2998 8 : if (zend_hash_get_current_key_ex(sdl->encoders, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
2999 8 : zend_hash_add(psdl->encoders, key, key_len, (void*)&penc, sizeof(encodePtr), NULL);
3000 : } else {
3001 0 : zend_hash_next_index_insert(psdl->encoders, (void*)&penc, sizeof(encodePtr), NULL);
3002 : }
3003 8 : zend_hash_add(&ptr_map, (char*)tmp, sizeof(*tmp), (void*)&penc, sizeof(encodePtr), NULL);
3004 8 : zend_hash_move_forward(sdl->encoders);
3005 : }
3006 : }
3007 :
3008 : /* do backpatching here */
3009 1 : if (zend_hash_num_elements(&bp_types)) {
3010 0 : sdlTypePtr **tmp, *ptype = NULL;
3011 :
3012 0 : zend_hash_internal_pointer_reset(&bp_types);
3013 0 : while (zend_hash_get_current_data(&bp_types, (void**)&tmp) == SUCCESS) {
3014 0 : if (zend_hash_find(&ptr_map, (char*)(*tmp), sizeof(**tmp), (void**)&ptype) == FAILURE) {
3015 : assert(0);
3016 : }
3017 0 : **tmp = *ptype;
3018 0 : zend_hash_move_forward(&bp_types);
3019 : }
3020 : }
3021 1 : if (zend_hash_num_elements(&bp_encoders)) {
3022 1 : encodePtr **tmp, *penc = NULL;
3023 :
3024 1 : zend_hash_internal_pointer_reset(&bp_encoders);
3025 5 : while (zend_hash_get_current_data(&bp_encoders, (void**)&tmp) == SUCCESS) {
3026 3 : if (zend_hash_find(&ptr_map, (char*)(*tmp), sizeof(**tmp), (void**)&penc) == FAILURE) {
3027 : assert(0);
3028 : }
3029 3 : **tmp = *penc;
3030 3 : zend_hash_move_forward(&bp_encoders);
3031 : }
3032 : }
3033 :
3034 :
3035 1 : if (sdl->bindings) {
3036 : sdlBindingPtr *tmp;
3037 : sdlBindingPtr pbind;
3038 :
3039 1 : psdl->bindings = malloc(sizeof(HashTable));
3040 1 : zend_hash_init(psdl->bindings, zend_hash_num_elements(sdl->bindings), NULL, delete_binding_persistent, 1);
3041 :
3042 1 : zend_hash_internal_pointer_reset(sdl->bindings);
3043 3 : while (zend_hash_get_current_data(sdl->bindings, (void **)&tmp) == SUCCESS) {
3044 1 : pbind = make_persistent_sdl_binding(*tmp, &ptr_map);
3045 1 : if (zend_hash_get_current_key_ex(sdl->bindings, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
3046 1 : zend_hash_add(psdl->bindings, key, key_len, (void*)&pbind, sizeof(sdlBindingPtr), NULL);
3047 : } else {
3048 0 : zend_hash_next_index_insert(psdl->bindings, (void*)&pbind, sizeof(sdlBindingPtr), NULL);
3049 : }
3050 1 : zend_hash_add(&ptr_map, (char*)tmp, sizeof(*tmp), (void*)&pbind, sizeof(sdlBindingPtr), NULL);
3051 1 : zend_hash_move_forward(sdl->bindings);
3052 : }
3053 : }
3054 :
3055 1 : zend_hash_init(&psdl->functions, zend_hash_num_elements(&sdl->functions), NULL, delete_function_persistent, 1);
3056 1 : if (zend_hash_num_elements(&sdl->functions)) {
3057 : sdlFunctionPtr *tmp;
3058 : sdlFunctionPtr pfunc;
3059 :
3060 1 : zend_hash_internal_pointer_reset(&sdl->functions);
3061 3 : while (zend_hash_get_current_data(&sdl->functions, (void **)&tmp) == SUCCESS) {
3062 1 : pfunc = make_persistent_sdl_function(*tmp, &ptr_map);
3063 1 : if (zend_hash_get_current_key_ex(&sdl->functions, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
3064 1 : zend_hash_add(&psdl->functions, key, key_len, (void*)&pfunc, sizeof(sdlFunctionPtr), NULL);
3065 : } else {
3066 0 : zend_hash_next_index_insert(&psdl->functions, (void*)&pfunc, sizeof(sdlFunctionPtr), NULL);
3067 : }
3068 1 : zend_hash_add(&ptr_map, (char*)tmp, sizeof(*tmp), (void*)&pfunc, sizeof(sdlFunctionPtr), NULL);
3069 1 : zend_hash_move_forward(&sdl->functions);
3070 : }
3071 : }
3072 :
3073 1 : if (sdl->requests) {
3074 : sdlFunctionPtr *tmp;
3075 : sdlFunctionPtr *preq;
3076 :
3077 0 : psdl->requests = malloc(sizeof(HashTable));
3078 0 : zend_hash_init(psdl->requests, zend_hash_num_elements(sdl->requests), NULL, NULL, 1);
3079 :
3080 0 : zend_hash_internal_pointer_reset(sdl->requests);
3081 0 : while (zend_hash_get_current_data(sdl->requests, (void **)&tmp) == SUCCESS) {
3082 0 : if (zend_hash_find(&ptr_map, (char*)tmp, sizeof(*tmp), (void**)&preq) == FAILURE) {
3083 : assert(0);
3084 : }
3085 0 : *tmp = *preq;
3086 0 : if (zend_hash_get_current_key_ex(sdl->requests, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) {
3087 0 : zend_hash_add(psdl->requests, key, key_len, (void*)&preq, sizeof(sdlFunctionPtr), NULL);
3088 : }
3089 0 : zend_hash_move_forward(sdl->requests);
3090 : }
3091 : }
3092 :
3093 1 : zend_hash_destroy(&ptr_map);
3094 1 : zend_hash_destroy(&bp_encoders);
3095 1 : zend_hash_destroy(&bp_types);
3096 :
3097 1 : return psdl;
3098 : }
3099 :
3100 : typedef struct _sdl_cache_bucket {
3101 : sdlPtr sdl;
3102 : time_t time;
3103 : } sdl_cache_bucket;
3104 :
3105 : static void delete_psdl(void *data)
3106 1 : {
3107 1 : sdl_cache_bucket *p = (sdl_cache_bucket*)data;
3108 1 : sdlPtr tmp = p->sdl;
3109 :
3110 1 : zend_hash_destroy(&tmp->functions);
3111 1 : if (tmp->source) {
3112 1 : free(tmp->source);
3113 : }
3114 1 : if (tmp->target_ns) {
3115 1 : free(tmp->target_ns);
3116 : }
3117 1 : if (tmp->elements) {
3118 0 : zend_hash_destroy(tmp->elements);
3119 0 : free(tmp->elements);
3120 : }
3121 1 : if (tmp->encoders) {
3122 1 : zend_hash_destroy(tmp->encoders);
3123 1 : free(tmp->encoders);
3124 : }
3125 1 : if (tmp->types) {
3126 1 : zend_hash_destroy(tmp->types);
3127 1 : free(tmp->types);
3128 : }
3129 1 : if (tmp->groups) {
3130 0 : zend_hash_destroy(tmp->groups);
3131 0 : free(tmp->groups);
3132 : }
3133 1 : if (tmp->bindings) {
3134 1 : zend_hash_destroy(tmp->bindings);
3135 1 : free(tmp->bindings);
3136 : }
3137 1 : if (tmp->requests) {
3138 0 : zend_hash_destroy(tmp->requests);
3139 0 : free(tmp->requests);
3140 : }
3141 1 : free(tmp);
3142 1 : }
3143 :
3144 : sdlPtr get_sdl(zval *this_ptr, char *uri, long cache_wsdl TSRMLS_DC)
3145 706 : {
3146 : char fn[MAXPATHLEN];
3147 706 : sdlPtr sdl = NULL;
3148 706 : char* old_error_code = SOAP_GLOBAL(error_code);
3149 706 : int uri_len = 0;
3150 706 : php_stream_context *context=NULL;
3151 706 : zval **tmp, **proxy_host, **proxy_port, *orig_context = NULL, *new_context = NULL;
3152 706 : smart_str headers = {0};
3153 706 : char* key = NULL;
3154 706 : time_t t = time(0);
3155 :
3156 1412 : if (strchr(uri,':') != NULL || IS_ABSOLUTE_PATH(uri, uri_len)) {
3157 706 : uri_len = strlen(uri);
3158 0 : } else if (VCWD_REALPATH(uri, fn) == NULL) {
3159 0 : cache_wsdl = WSDL_CACHE_NONE;
3160 : } else {
3161 0 : uri = fn;
3162 0 : uri_len = strlen(uri);
3163 : }
3164 :
3165 706 : if ((cache_wsdl & WSDL_CACHE_MEMORY) && SOAP_GLOBAL(mem_cache)) {
3166 : sdl_cache_bucket *p;
3167 :
3168 9 : if (SUCCESS == zend_hash_find(SOAP_GLOBAL(mem_cache), uri, uri_len+1, (void*)&p)) {
3169 9 : if (p->time < t - SOAP_GLOBAL(cache_ttl)) {
3170 : /* in-memory cache entry is expired */
3171 0 : zend_hash_del(&EG(persistent_list), uri, uri_len+1);
3172 : } else {
3173 9 : return p->sdl;
3174 : }
3175 : }
3176 : }
3177 :
3178 697 : if ((cache_wsdl & WSDL_CACHE_DISK) && (uri_len < MAXPATHLEN)) {
3179 7 : time_t t = time(0);
3180 : char md5str[33];
3181 : PHP_MD5_CTX context;
3182 : unsigned char digest[16];
3183 7 : int len = strlen(SOAP_GLOBAL(cache_dir));
3184 : time_t cached;
3185 :
3186 7 : md5str[0] = '\0';
3187 7 : PHP_MD5Init(&context);
3188 7 : PHP_MD5Update(&context, (unsigned char*)uri, uri_len);
3189 7 : PHP_MD5Final(digest, &context);
3190 7 : make_digest(md5str, digest);
3191 7 : key = emalloc(len+sizeof("/wsdl-")-1+sizeof(md5str));
3192 7 : memcpy(key,SOAP_GLOBAL(cache_dir),len);
3193 7 : memcpy(key+len,"/wsdl-",sizeof("/wsdl-")-1);
3194 7 : memcpy(key+len+sizeof("/wsdl-")-1,md5str,sizeof(md5str));
3195 :
3196 7 : if ((sdl = get_sdl_from_cache(key, uri, t-SOAP_GLOBAL(cache_ttl), &cached TSRMLS_CC)) != NULL) {
3197 2 : t = cached;
3198 2 : efree(key);
3199 2 : goto cache_in_memory;
3200 : }
3201 : }
3202 :
3203 695 : if (SUCCESS == zend_hash_find(Z_OBJPROP_P(this_ptr),
3204 : "_stream_context", sizeof("_stream_context"), (void**)&tmp)) {
3205 0 : context = php_stream_context_from_zval(*tmp, 0);
3206 : }
3207 :
3208 695 : if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_proxy_host", sizeof("_proxy_host"), (void **) &proxy_host) == SUCCESS &&
3209 : Z_TYPE_PP(proxy_host) == IS_STRING &&
3210 : zend_hash_find(Z_OBJPROP_P(this_ptr), "_proxy_port", sizeof("_proxy_port"), (void **) &proxy_port) == SUCCESS &&
3211 : Z_TYPE_PP(proxy_port) == IS_LONG) {
3212 : zval str_port, *str_proxy;
3213 0 : smart_str proxy = {0};
3214 0 : str_port = **proxy_port;
3215 0 : zval_copy_ctor(&str_port);
3216 0 : convert_to_string(&str_port);
3217 0 : smart_str_appends(&proxy,"tcp://");
3218 0 : smart_str_appends(&proxy,Z_STRVAL_PP(proxy_host));
3219 0 : smart_str_appends(&proxy,":");
3220 0 : smart_str_appends(&proxy,Z_STRVAL(str_port));
3221 0 : smart_str_0(&proxy);
3222 0 : zval_dtor(&str_port);
3223 0 : MAKE_STD_ZVAL(str_proxy);
3224 0 : ZVAL_STRING(str_proxy, proxy.c, 1);
3225 0 : smart_str_free(&proxy);
3226 :
3227 0 : if (!context) {
3228 0 : context = php_stream_context_alloc();
3229 : }
3230 0 : php_stream_context_set_option(context, "http", "proxy", str_proxy);
3231 0 : zval_ptr_dtor(&str_proxy);
3232 :
3233 0 : MAKE_STD_ZVAL(str_proxy);
3234 0 : ZVAL_BOOL(str_proxy, 1);
3235 0 : php_stream_context_set_option(context, "http", "request_fulluri", str_proxy);
3236 0 : zval_ptr_dtor(&str_proxy);
3237 :
3238 0 : proxy_authentication(this_ptr, &headers TSRMLS_CC);
3239 : }
3240 :
3241 695 : basic_authentication(this_ptr, &headers TSRMLS_CC);
3242 :
3243 695 : if (headers.len > 0) {
3244 : zval *str_headers;
3245 :
3246 0 : if (!context) {
3247 0 : context = php_stream_context_alloc();
3248 : }
3249 :
3250 0 : smart_str_0(&headers);
3251 0 : MAKE_STD_ZVAL(str_headers);
3252 0 : ZVAL_STRING(str_headers, headers.c, 1);
3253 0 : php_stream_context_set_option(context, "http", "header", str_headers);
3254 0 : smart_str_free(&headers);
3255 0 : zval_ptr_dtor(&str_headers);
3256 : }
3257 :
3258 695 : if (context) {
3259 0 : MAKE_STD_ZVAL(new_context);
3260 0 : php_stream_context_to_zval(context, new_context);
3261 0 : orig_context = php_libxml_switch_context(new_context TSRMLS_CC);
3262 : }
3263 :
3264 695 : SOAP_GLOBAL(error_code) = "WSDL";
3265 :
3266 695 : sdl = load_wsdl(this_ptr, uri TSRMLS_CC);
3267 692 : if (sdl) {
3268 692 : sdl->is_persistent = 0;
3269 : }
3270 :
3271 692 : SOAP_GLOBAL(error_code) = old_error_code;
3272 :
3273 692 : if (context) {
3274 0 : php_libxml_switch_context(orig_context TSRMLS_CC);
3275 0 : zval_ptr_dtor(&new_context);
3276 : }
3277 :
3278 692 : if ((cache_wsdl & WSDL_CACHE_DISK) && key) {
3279 4 : if (sdl) {
3280 4 : add_sdl_to_cache(key, uri, t, sdl TSRMLS_CC);
3281 : }
3282 4 : efree(key);
3283 : }
3284 :
3285 694 : cache_in_memory:
3286 694 : if (cache_wsdl & WSDL_CACHE_MEMORY) {
3287 1 : if (sdl) {
3288 : sdlPtr psdl;
3289 : sdl_cache_bucket p;
3290 :
3291 1 : if (SOAP_GLOBAL(mem_cache) == NULL) {
3292 1 : SOAP_GLOBAL(mem_cache) = malloc(sizeof(HashTable));
3293 1 : zend_hash_init(SOAP_GLOBAL(mem_cache), 0, NULL, delete_psdl, 1);
3294 0 : } else if (SOAP_GLOBAL(cache_limit) > 0 &&
3295 : SOAP_GLOBAL(cache_limit) <= zend_hash_num_elements(SOAP_GLOBAL(mem_cache))) {
3296 : /* in-memory cache overflow */
3297 : sdl_cache_bucket *q;
3298 : HashPosition pos;
3299 0 : time_t latest = t;
3300 0 : char *key = NULL;
3301 : uint key_len;
3302 : ulong idx;
3303 :
3304 0 : for (zend_hash_internal_pointer_reset_ex(SOAP_GLOBAL(mem_cache), &pos);
3305 0 : zend_hash_get_current_data_ex(SOAP_GLOBAL(mem_cache), (void **) &q, &pos) == SUCCESS;
3306 0 : zend_hash_move_forward_ex(SOAP_GLOBAL(mem_cache), &pos)) {
3307 0 : if (q->time < latest) {
3308 0 : latest = q->time;
3309 0 : zend_hash_get_current_key_ex(SOAP_GLOBAL(mem_cache), &key, &key_len, &idx, 0, &pos);
3310 : }
3311 : }
3312 0 : if (key) {
3313 0 : zend_hash_del(SOAP_GLOBAL(mem_cache), key, key_len);
3314 : } else {
3315 0 : return sdl;
3316 : }
3317 : }
3318 :
3319 1 : psdl = make_persistent_sdl(sdl TSRMLS_CC);
3320 1 : psdl->is_persistent = 1;
3321 1 : p.time = t;
3322 1 : p.sdl = psdl;
3323 :
3324 1 : if (SUCCESS == zend_hash_update(SOAP_GLOBAL(mem_cache), uri,
3325 : uri_len+1, (void*)&p, sizeof(sdl_cache_bucket), NULL)) {
3326 : /* remove non-persitent sdl structure */
3327 1 : delete_sdl_impl(sdl);
3328 : /* and replace it with persistent one */
3329 1 : sdl = psdl;
3330 : } else {
3331 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to register persistent entry");
3332 : /* clean up persistent sdl */
3333 0 : delete_psdl(&p);
3334 : /* keep non-persistent sdl and return it */
3335 : }
3336 : }
3337 : }
3338 :
3339 694 : return sdl;
3340 : }
3341 :
3342 : /* Deletes */
3343 : void delete_sdl_impl(void *handle)
3344 694 : {
3345 694 : sdlPtr tmp = (sdlPtr)handle;
3346 :
3347 694 : zend_hash_destroy(&tmp->functions);
3348 694 : if (tmp->source) {
3349 694 : efree(tmp->source);
3350 : }
3351 694 : if (tmp->target_ns) {
3352 694 : efree(tmp->target_ns);
3353 : }
3354 694 : if (tmp->elements) {
3355 273 : zend_hash_destroy(tmp->elements);
3356 273 : efree(tmp->elements);
3357 : }
3358 694 : if (tmp->encoders) {
3359 653 : zend_hash_destroy(tmp->encoders);
3360 653 : efree(tmp->encoders);
3361 : }
3362 694 : if (tmp->types) {
3363 672 : zend_hash_destroy(tmp->types);
3364 672 : efree(tmp->types);
3365 : }
3366 694 : if (tmp->groups) {
3367 2 : zend_hash_destroy(tmp->groups);
3368 2 : efree(tmp->groups);
3369 : }
3370 694 : if (tmp->bindings) {
3371 694 : zend_hash_destroy(tmp->bindings);
3372 694 : efree(tmp->bindings);
3373 : }
3374 694 : if (tmp->requests) {
3375 0 : zend_hash_destroy(tmp->requests);
3376 0 : efree(tmp->requests);
3377 : }
3378 694 : efree(tmp);
3379 694 : }
3380 :
3381 : void delete_sdl(void *handle)
3382 703 : {
3383 703 : sdlPtr tmp = (sdlPtr)handle;
3384 :
3385 703 : if (!tmp->is_persistent) {
3386 693 : delete_sdl_impl(tmp);
3387 : }
3388 703 : }
3389 :
3390 : static void delete_binding(void *data)
3391 850 : {
3392 850 : sdlBindingPtr binding = *((sdlBindingPtr*)data);
3393 :
3394 850 : if (binding->location) {
3395 850 : efree(binding->location);
3396 : }
3397 850 : if (binding->name) {
3398 850 : efree(binding->name);
3399 : }
3400 :
3401 850 : if (binding->bindingType == BINDING_SOAP) {
3402 849 : sdlSoapBindingPtr soapBind = binding->bindingAttributes;
3403 849 : if (soapBind) {
3404 849 : efree(soapBind);
3405 : }
3406 : }
3407 850 : efree(binding);
3408 850 : }
3409 :
3410 : static void delete_binding_persistent(void *data)
3411 1 : {
3412 1 : sdlBindingPtr binding = *((sdlBindingPtr*)data);
3413 :
3414 1 : if (binding->location) {
3415 1 : free(binding->location);
3416 : }
3417 1 : if (binding->name) {
3418 1 : free(binding->name);
3419 : }
3420 :
3421 1 : if (binding->bindingType == BINDING_SOAP) {
3422 1 : sdlSoapBindingPtr soapBind = binding->bindingAttributes;
3423 1 : if (soapBind) {
3424 1 : free(soapBind);
3425 : }
3426 : }
3427 1 : free(binding);
3428 1 : }
3429 :
3430 : static void delete_sdl_soap_binding_function_body(sdlSoapBindingFunctionBody body)
3431 15182 : {
3432 15182 : if (body.ns) {
3433 6777 : efree(body.ns);
3434 : }
3435 15182 : if (body.headers) {
3436 888 : zend_hash_destroy(body.headers);
3437 888 : efree(body.headers);
3438 : }
3439 15182 : }
3440 :
3441 : static void delete_sdl_soap_binding_function_body_persistent(sdlSoapBindingFunctionBody body)
3442 2 : {
3443 2 : if (body.ns) {
3444 2 : free(body.ns);
3445 : }
3446 2 : if (body.headers) {
3447 0 : zend_hash_destroy(body.headers);
3448 0 : free(body.headers);
3449 : }
3450 2 : }
3451 :
3452 : static void delete_function(void *data)
3453 7592 : {
3454 7592 : sdlFunctionPtr function = *((sdlFunctionPtr*)data);
3455 :
3456 7592 : if (function->functionName) {
3457 7592 : efree(function->functionName);
3458 : }
3459 7592 : if (function->requestName) {
3460 7592 : efree(function->requestName);
3461 : }
3462 7592 : if (function->responseName) {
3463 7344 : efree(function->responseName);
3464 : }
3465 7592 : if (function->requestParameters) {
3466 7591 : zend_hash_destroy(function->requestParameters);
3467 7591 : efree(function->requestParameters);
3468 : }
3469 7592 : if (function->responseParameters) {
3470 7344 : zend_hash_destroy(function->responseParameters);
3471 7344 : efree(function->responseParameters);
3472 : }
3473 7592 : if (function->faults) {
3474 684 : zend_hash_destroy(function->faults);
3475 684 : efree(function->faults);
3476 : }
3477 :
3478 7592 : if (function->bindingAttributes &&
3479 : function->binding && function->binding->bindingType == BINDING_SOAP) {
3480 7591 : sdlSoapBindingFunctionPtr soapFunction = function->bindingAttributes;
3481 7591 : if (soapFunction->soapAction) {
3482 5908 : efree(soapFunction->soapAction);
3483 : }
3484 7591 : delete_sdl_soap_binding_function_body(soapFunction->input);
3485 7591 : delete_sdl_soap_binding_function_body(soapFunction->output);
3486 7591 : efree(soapFunction);
3487 : }
3488 7592 : efree(function);
3489 7592 : }
3490 :
3491 : static void delete_function_persistent(void *data)
3492 1 : {
3493 1 : sdlFunctionPtr function = *((sdlFunctionPtr*)data);
3494 :
3495 1 : if (function->functionName) {
3496 1 : free(function->functionName);
3497 : }
3498 1 : if (function->requestName) {
3499 1 : free(function->requestName);
3500 : }
3501 1 : if (function->responseName) {
3502 1 : free(function->responseName);
3503 : }
3504 1 : if (function->requestParameters) {
3505 1 : zend_hash_destroy(function->requestParameters);
3506 1 : free(function->requestParameters);
3507 : }
3508 1 : if (function->responseParameters) {
3509 1 : zend_hash_destroy(function->responseParameters);
3510 1 : free(function->responseParameters);
3511 : }
3512 1 : if (function->faults) {
3513 0 : zend_hash_destroy(function->faults);
3514 0 : free(function->faults);
3515 : }
3516 :
3517 1 : if (function->bindingAttributes &&
3518 : function->binding && function->binding->bindingType == BINDING_SOAP) {
3519 1 : sdlSoapBindingFunctionPtr soapFunction = function->bindingAttributes;
3520 1 : if (soapFunction->soapAction) {
3521 1 : free(soapFunction->soapAction);
3522 : }
3523 1 : delete_sdl_soap_binding_function_body_persistent(soapFunction->input);
3524 1 : delete_sdl_soap_binding_function_body_persistent(soapFunction->output);
3525 1 : free(soapFunction);
3526 : }
3527 1 : free(function);
3528 1 : }
3529 :
3530 : static void delete_parameter(void *data)
3531 16021 : {
3532 16021 : sdlParamPtr param = *((sdlParamPtr*)data);
3533 16021 : if (param->paramName) {
3534 16021 : efree(param->paramName);
3535 : }
3536 16021 : efree(param);
3537 16021 : }
3538 :
3539 : static void delete_parameter_persistent(void *data)
3540 4 : {
3541 4 : sdlParamPtr param = *((sdlParamPtr*)data);
3542 4 : if (param->paramName) {
3543 4 : free(param->paramName);
3544 : }
3545 4 : free(param);
3546 4 : }
3547 :
3548 : static void delete_header(void *data)
3549 1619 : {
3550 1619 : sdlSoapBindingFunctionHeaderPtr hdr = *((sdlSoapBindingFunctionHeaderPtr*)data);
3551 1619 : if (hdr->name) {
3552 1619 : efree(hdr->name);
3553 : }
3554 1619 : if (hdr->ns) {
3555 1612 : efree(hdr->ns);
3556 : }
3557 1619 : if (hdr->headerfaults) {
3558 73 : zend_hash_destroy(hdr->headerfaults);
3559 73 : efree(hdr->headerfaults);
3560 : }
3561 1619 : efree(hdr);
3562 1619 : }
3563 :
3564 : static void delete_header_persistent(void *data)
3565 0 : {
3566 0 : sdlSoapBindingFunctionHeaderPtr hdr = *((sdlSoapBindingFunctionHeaderPtr*)data);
3567 0 : if (hdr->name) {
3568 0 : free(hdr->name);
3569 : }
3570 0 : if (hdr->ns) {
3571 0 : free(hdr->ns);
3572 : }
3573 0 : if (hdr->headerfaults) {
3574 0 : zend_hash_destroy(hdr->headerfaults);
3575 0 : free(hdr->headerfaults);
3576 : }
3577 0 : free(hdr);
3578 0 : }
3579 :
3580 : static void delete_fault(void *data)
3581 1212 : {
3582 1212 : sdlFaultPtr fault = *((sdlFaultPtr*)data);
3583 1212 : if (fault->name) {
3584 1212 : efree(fault->name);
3585 : }
3586 1212 : if (fault->details) {
3587 1212 : zend_hash_destroy(fault->details);
3588 1212 : efree(fault->details);
3589 : }
3590 1212 : if (fault->bindingAttributes) {
3591 1178 : sdlSoapBindingFunctionFaultPtr binding = (sdlSoapBindingFunctionFaultPtr)fault->bindingAttributes;
3592 :
3593 1178 : if (binding->ns) {
3594 610 : efree(binding->ns);
3595 : }
3596 1178 : efree(fault->bindingAttributes);
3597 : }
3598 1212 : efree(fault);
3599 1212 : }
3600 :
3601 : static void delete_fault_persistent(void *data)
3602 0 : {
3603 0 : sdlFaultPtr fault = *((sdlFaultPtr*)data);
3604 0 : if (fault->name) {
3605 0 : free(fault->name);
3606 : }
3607 0 : if (fault->details) {
3608 0 : zend_hash_destroy(fault->details);
3609 0 : free(fault->details);
3610 : }
3611 0 : if (fault->bindingAttributes) {
3612 0 : sdlSoapBindingFunctionFaultPtr binding = (sdlSoapBindingFunctionFaultPtr)fault->bindingAttributes;
3613 :
3614 0 : if (binding->ns) {
3615 0 : free(binding->ns);
3616 : }
3617 0 : free(fault->bindingAttributes);
3618 : }
3619 0 : free(fault);
3620 0 : }
3621 :
3622 : static void delete_document(void *doc_ptr)
3623 715 : {
3624 715 : xmlDocPtr doc = *((xmlDocPtr*)doc_ptr);
3625 715 : xmlFreeDoc(doc);
3626 715 : }
3627 :
|