diff options
Diffstat (limited to 'ext/soap')
47 files changed, 2013 insertions, 148 deletions
diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index 8553dd0c1..b82bf7dbe 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -17,7 +17,7 @@ | Dmitry Stogov <dmitry@zend.com> | +----------------------------------------------------------------------+ */ -/* $Id: php_encoding.c,v 1.103.2.21.2.13 2006/10/24 05:20:50 dmitry Exp $ */ +/* $Id: php_encoding.c,v 1.103.2.21.2.32 2007/05/02 17:24:16 dmitry Exp $ */ #include <time.h> @@ -270,6 +270,85 @@ static encodePtr find_encoder_by_type_name(sdlPtr sdl, const char *type) return NULL; } +static zend_bool soap_check_zval_ref(zval *data, xmlNodePtr node TSRMLS_DC) { + xmlNodePtr *node_ptr; + + if (SOAP_GLOBAL(ref_map)) { + if (Z_TYPE_P(data) == IS_OBJECT) { + data = (zval*)zend_objects_get_address(data TSRMLS_CC); + } + if (zend_hash_index_find(SOAP_GLOBAL(ref_map), (ulong)data, (void**)&node_ptr) == SUCCESS) { + xmlAttrPtr attr = (*node_ptr)->properties; + char *id; + smart_str prefix = {0}; + + if (*node_ptr == node) { + return 0; + } + xmlNodeSetName(node, (*node_ptr)->name); + xmlSetNs(node, (*node_ptr)->ns); + if (SOAP_GLOBAL(soap_version) == SOAP_1_1) { + while (1) { + attr = get_attribute(attr, "id"); + if (attr == NULL || attr->ns == NULL) { + break; + } + attr = attr->next; + } + if (attr) { + id = (char*)attr->children->content; + } else { + SOAP_GLOBAL(cur_uniq_ref)++; + smart_str_appendl(&prefix, "#ref", 4); + smart_str_append_long(&prefix, SOAP_GLOBAL(cur_uniq_ref)); + smart_str_0(&prefix); + id = prefix.c; + xmlSetProp((*node_ptr), BAD_CAST("id"), BAD_CAST(id+1)); + } + xmlSetProp(node, BAD_CAST("href"), BAD_CAST(id)); + } else { + attr = get_attribute_ex(attr, "id", SOAP_1_2_ENC_NAMESPACE); + if (attr) { + id = (char*)attr->children->content; + } else { + SOAP_GLOBAL(cur_uniq_ref)++; + smart_str_appendl(&prefix, "#ref", 4); + smart_str_append_long(&prefix, SOAP_GLOBAL(cur_uniq_ref)); + smart_str_0(&prefix); + id = prefix.c; + set_ns_prop((*node_ptr), SOAP_1_2_ENC_NAMESPACE, "id", id+1); + } + set_ns_prop(node, SOAP_1_2_ENC_NAMESPACE, "ref", id); + } + smart_str_free(&prefix); + return 1; + } else { + zend_hash_index_update(SOAP_GLOBAL(ref_map), (ulong)data, (void**)&node, sizeof(xmlNodePtr), NULL); + } + } + return 0; +} + +static zend_bool soap_check_xml_ref(zval **data, xmlNodePtr node TSRMLS_DC) +{ + zval **data_ptr; + + if (SOAP_GLOBAL(ref_map)) { + if (zend_hash_index_find(SOAP_GLOBAL(ref_map), (ulong)node, (void**)&data_ptr) == SUCCESS) { + if (*data != *data_ptr) { + zval_ptr_dtor(data); + *data = *data_ptr; + (*data)->is_ref = 1; + (*data)->refcount++; + return 1; + } + } else { + zend_hash_index_update(SOAP_GLOBAL(ref_map), (ulong)node, (void**)data, sizeof(zval*), NULL); + } + } + return 0; +} + xmlNodePtr master_to_xml(encodePtr encode, zval *data, int style, xmlNodePtr parent) { xmlNodePtr node = NULL; @@ -669,9 +748,15 @@ static zval *to_zval_base64(encodeTypePtr type, xmlNodePtr data) if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) { whiteSpace_collapse(data->children->content); str = (char*)php_base64_decode(data->children->content, strlen((char*)data->children->content), &str_len); + if (!str) { + soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); + } ZVAL_STRINGL(ret, str, str_len, 0); } else if (data->children->type == XML_CDATA_SECTION_NODE && data->children->next == NULL) { str = (char*)php_base64_decode(data->children->content, strlen((char*)data->children->content), &str_len); + if (!str) { + soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); + } ZVAL_STRINGL(ret, str, str_len, 0); } else { soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); @@ -708,6 +793,8 @@ static zval *to_zval_hexbin(encodeTypePtr type, xmlNodePtr data) str[i] = (c - 'a' + 10) << 4; } else if (c >= 'A' && c <= 'F') { str[i] = (c - 'A' + 10) << 4; + } else { + soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); } c = data->children->content[j++]; if (c >= '0' && c <= '9') { @@ -716,6 +803,8 @@ static zval *to_zval_hexbin(encodeTypePtr type, xmlNodePtr data) str[i] |= c - 'a' + 10; } else if (c >= 'A' && c <= 'F') { str[i] |= c - 'A' + 10; + } else { + soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); } } str[str_len] = '\0'; @@ -858,8 +947,22 @@ static zval *to_zval_double(encodeTypePtr type, xmlNodePtr data) if (data && data->children) { if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) { + long lval; + double dval; + whiteSpace_collapse(data->children->content); - ZVAL_DOUBLE(ret, atof((char*)data->children->content)); + switch (is_numeric_string((char*)data->children->content, strlen((char*)data->children->content), &lval, &dval, 0)) { + case IS_LONG: + Z_TYPE_P(ret) = IS_DOUBLE; + Z_DVAL_P(ret) = lval; + break; + case IS_DOUBLE: + Z_TYPE_P(ret) = IS_DOUBLE; + Z_DVAL_P(ret) = dval; + break; + default: + soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); + } } else { soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); } @@ -877,14 +980,21 @@ static zval *to_zval_long(encodeTypePtr type, xmlNodePtr data) if (data && data->children) { if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) { + long lval; + double dval; + whiteSpace_collapse(data->children->content); errno = 0; - ret->value.lval = strtol((char*)data->children->content, NULL, 0); - if (errno == ERANGE) { /* overflow */ - ret->value.dval = zend_strtod((char*)data->children->content, NULL); - ret->type = IS_DOUBLE; - } else { - ret->type = IS_LONG; + + switch ((Z_TYPE_P(ret) = is_numeric_string((char*)data->children->content, strlen((char*)data->children->content), &lval, &dval, 0))) { + case IS_LONG: + Z_LVAL_P(ret) = lval; + break; + case IS_DOUBLE: + Z_DVAL_P(ret) = dval; + break; + default: + soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); } } else { soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); @@ -906,7 +1016,7 @@ static xmlNodePtr to_xml_long(encodeTypePtr type, zval *data, int style, xmlNode if (Z_TYPE_P(data) == IS_DOUBLE) { char s[256]; - sprintf(s, "%0.0f",floor(Z_DVAL_P(data))); + snprintf(s, sizeof(s), "%0.0F",floor(Z_DVAL_P(data))); xmlNodeSetContent(ret, BAD_CAST(s)); } else { zval tmp = *data; @@ -930,19 +1040,23 @@ static xmlNodePtr to_xml_double(encodeTypePtr type, zval *data, int style, xmlNo { xmlNodePtr ret; zval tmp; + char *str; + TSRMLS_FETCH(); ret = xmlNewNode(NULL, BAD_CAST("BOGUS")); xmlAddChild(parent, ret); FIND_ZVAL_NULL(data, ret, style); tmp = *data; - zval_copy_ctor(&tmp); if (Z_TYPE(tmp) != IS_DOUBLE) { + zval_copy_ctor(&tmp); convert_to_double(&tmp); } - convert_to_string(&tmp); - xmlNodeSetContentLen(ret, BAD_CAST(Z_STRVAL(tmp)), Z_STRLEN(tmp)); - zval_dtor(&tmp); + + str = (char *) safe_emalloc(EG(precision), 1, MAX_LENGTH_OF_DOUBLE + 1); + php_gcvt(Z_DVAL(tmp), EG(precision), '.', 'E', str); + xmlNodeSetContentLen(ret, BAD_CAST(str), strlen(str)); + efree(str); if (style == SOAP_ENCODED) { set_ns_and_type(ret, type); @@ -1102,23 +1216,23 @@ static void model_to_zval_any(zval *ret, xmlNodePtr node TSRMLS_DC) } add_string_to_string(val, val, val2); zval_ptr_dtor(&val2); - node = node->next; + node = node->next; } } if (any == NULL) { any = val; } else { if (Z_TYPE_P(any) != IS_ARRAY) { - /* Convert into array */ - zval *arr; + /* Convert into array */ + zval *arr; - MAKE_STD_ZVAL(arr); - array_init(arr); - add_next_index_zval(arr, any); - any = arr; - } - /* Add array element */ - add_next_index_zval(any, val); + MAKE_STD_ZVAL(arr); + array_init(arr); + add_next_index_zval(arr, any); + any = arr; + } + /* Add array element */ + add_next_index_zval(any, val); } } node = node->next; @@ -1137,13 +1251,14 @@ static void model_to_zval_object(zval *ret, sdlContentModelPtr model, xmlNodePtr if (node) { zval *val; + xmlNodePtr r_node; - node = check_and_resolve_href(node); - if (node && node->children && node->children->content) { - if (model->u.element->fixed && strcmp(model->u.element->fixed, (char*)node->children->content) != 0) { - soap_error3(E_ERROR, "Encoding: Element '%s' has fixed value '%s' (value '%s' is not allowed)", model->u.element->name, model->u.element->fixed, node->children->content); + r_node = check_and_resolve_href(node); + if (r_node && r_node->children && r_node->children->content) { + if (model->u.element->fixed && strcmp(model->u.element->fixed, (char*)r_node->children->content) != 0) { + soap_error3(E_ERROR, "Encoding: Element '%s' has fixed value '%s' (value '%s' is not allowed)", model->u.element->name, model->u.element->fixed, r_node->children->content); } - val = master_to_zval(model->u.element->encode, node); + val = master_to_zval(model->u.element->encode, r_node); } else if (model->u.element->fixed) { xmlNodePtr dummy = xmlNewNode(NULL, BAD_CAST("BOGUS")); xmlNodeSetContent(dummy, BAD_CAST(model->u.element->fixed)); @@ -1155,7 +1270,7 @@ static void model_to_zval_object(zval *ret, sdlContentModelPtr model, xmlNodePtr val = master_to_zval(model->u.element->encode, dummy); xmlFreeNode(dummy); } else { - val = master_to_zval(model->u.element->encode, node); + val = master_to_zval(model->u.element->encode, r_node); } if ((node = get_node(node->next, model->u.element->name)) != NULL) { zval *array; @@ -1185,7 +1300,8 @@ static void model_to_zval_object(zval *ret, sdlContentModelPtr model, xmlNodePtr add_next_index_zval(array, val); } while ((node = get_node(node->next, model->u.element->name)) != NULL); val = array; - } else if ((SOAP_GLOBAL(features) & SOAP_SINGLE_ELEMENT_ARRAYS) && + } else if ((Z_TYPE_P(val) != IS_NULL || !model->u.element->nillable) && + (SOAP_GLOBAL(features) & SOAP_SINGLE_ELEMENT_ARRAYS) && (model->max_occurs == -1 || model->max_occurs > 1)) { zval *array; @@ -1266,14 +1382,20 @@ static zval *to_zval_object_ex(encodeTypePtr type, xmlNodePtr data, zend_class_e if (enc) { zval *base; - MAKE_STD_ZVAL(ret); + ALLOC_INIT_ZVAL(ret); + if (soap_check_xml_ref(&ret, data TSRMLS_CC)) { + return ret; + } object_init_ex(ret, ce); base = master_to_zval_int(enc, data); set_zval_property(ret, "_", base TSRMLS_CC); } else { - MAKE_STD_ZVAL(ret); + ALLOC_INIT_ZVAL(ret); FIND_XML_NULL(data, ret); + if (soap_check_xml_ref(&ret, data TSRMLS_CC)) { + return ret; + } object_init_ex(ret, ce); } } else if (sdlType->kind == XSD_TYPEKIND_EXTENSION && @@ -1298,6 +1420,9 @@ static zval *to_zval_object_ex(encodeTypePtr type, xmlNodePtr data, zend_class_e ret = master_to_zval_int(sdlType->encode, data); } FIND_XML_NULL(data, ret); + if (soap_check_xml_ref(&ret, data TSRMLS_CC)) { + return ret; + } if (get_zval_property(ret, "any" TSRMLS_CC) != NULL) { unset_zval_property(ret, "any" TSRMLS_CC); redo_any = 1; @@ -1309,15 +1434,21 @@ static zval *to_zval_object_ex(encodeTypePtr type, xmlNodePtr data, zend_class_e } else { zval *base; - MAKE_STD_ZVAL(ret); + ALLOC_INIT_ZVAL(ret); + if (soap_check_xml_ref(&ret, data TSRMLS_CC)) { + return ret; + } object_init_ex(ret, ce); base = master_to_zval_int(sdlType->encode, data); set_zval_property(ret, "_", base TSRMLS_CC); } } else { - MAKE_STD_ZVAL(ret); + ALLOC_INIT_ZVAL(ret); FIND_XML_NULL(data, ret); + if (soap_check_xml_ref(&ret, data TSRMLS_CC)) { + return ret; + } object_init_ex(ret, ce); } if (sdlType->model) { @@ -1363,10 +1494,13 @@ static zval *to_zval_object_ex(encodeTypePtr type, xmlNodePtr data, zend_class_e } } else { - MAKE_STD_ZVAL(ret); + ALLOC_INIT_ZVAL(ret); FIND_XML_NULL(data, ret); - object_init_ex(ret, ce); + if (soap_check_xml_ref(&ret, data TSRMLS_CC)) { + return ret; + } + object_init_ex(ret, ce); trav = data->children; while (trav != NULL) { @@ -1378,22 +1512,31 @@ static zval *to_zval_object_ex(encodeTypePtr type, xmlNodePtr data, zend_class_e prop = get_zval_property(ret, (char*)trav->name TSRMLS_CC); if (!prop) { - set_zval_property(ret, (char*)trav->name, tmpVal TSRMLS_CC); + if (!trav->next || !get_node(trav->next, (char*)trav->name)) { + set_zval_property(ret, (char*)trav->name, tmpVal TSRMLS_CC); + } else { + zval *arr; + + MAKE_STD_ZVAL(arr); + array_init(arr); + add_next_index_zval(arr, tmpVal); + set_zval_property(ret, (char*)trav->name, arr TSRMLS_CC); + } } else { - /* Property already exist - make array */ - if (Z_TYPE_P(prop) != IS_ARRAY) { - /* Convert into array */ - zval *arr; - - MAKE_STD_ZVAL(arr); - array_init(arr); - prop->refcount++; - add_next_index_zval(arr, prop); - set_zval_property(ret, (char*)trav->name, arr TSRMLS_CC); - prop = arr; - } - /* Add array element */ - add_next_index_zval(prop, tmpVal); + /* Property already exist - make array */ + if (Z_TYPE_P(prop) != IS_ARRAY) { + /* Convert into array */ + zval *arr; + + MAKE_STD_ZVAL(arr); + array_init(arr); + prop->refcount++; + add_next_index_zval(arr, prop); + set_zval_property(ret, (char*)trav->name, arr TSRMLS_CC); + prop = arr; + } + /* Add array element */ + add_next_index_zval(prop, tmpVal); } } trav = trav->next; @@ -1529,8 +1672,10 @@ static int model_to_xml_object(xmlNodePtr node, sdlContentModelPtr model, zval * zend_hash_internal_pointer_reset_ex(model->u.content, &pos); while (zend_hash_get_current_data_ex(model->u.content, (void**)&tmp, &pos) == SUCCESS) { - if (!model_to_xml_object(node, *tmp, object, style, model->min_occurs > 0 TSRMLS_CC)) { - return 0; + if (!model_to_xml_object(node, *tmp, object, style, (*tmp)->min_occurs > 0 TSRMLS_CC)) { + if ((*tmp)->min_occurs > 0) { + return 0; + } } zend_hash_move_forward_ex(model->u.content, &pos); } @@ -1607,6 +1752,7 @@ static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNo xmlAddChild(parent, xmlParam); if (style == SOAP_ENCODED) { set_xsi_nil(xmlParam); + set_ns_and_type(xmlParam, type); } return xmlParam; } @@ -1670,10 +1816,13 @@ static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNo xmlAddChild(parent, xmlParam); } + if (soap_check_zval_ref(data, xmlParam TSRMLS_CC)) { + return xmlParam; + } if (prop != NULL) { - sdlTypePtr array_el; + sdlTypePtr array_el; - if (Z_TYPE_P(data) == IS_ARRAY && + if (Z_TYPE_P(data) == IS_ARRAY && !is_map(data) && sdlType->attributes == NULL && sdlType->model != NULL && @@ -1747,6 +1896,9 @@ static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNo xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS")); xmlAddChild(parent, xmlParam); + if (soap_check_zval_ref(data, xmlParam TSRMLS_CC)) { + return xmlParam; + } if (prop != NULL) { i = zend_hash_num_elements(prop); zend_hash_internal_pointer_reset(prop); @@ -1999,7 +2151,17 @@ static xmlNodePtr to_xml_array(encodeTypePtr type, zval *data, int style, xmlNod xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS")); xmlAddChild(parent, xmlParam); - FIND_ZVAL_NULL(data, xmlParam, style); + if (!data || Z_TYPE_P(data) == IS_NULL) { + if (style == SOAP_ENCODED) { + set_xsi_nil(xmlParam); + if (SOAP_GLOBAL(features) & SOAP_USE_XSI_ARRAY_TYPE) { + set_ns_and_type_ex(xmlParam, (soap_version == SOAP_1_1) ? SOAP_1_1_ENC_NAMESPACE : SOAP_1_2_ENC_NAMESPACE, "Array"); + } else { + set_ns_and_type(xmlParam, type); + } + } + return xmlParam; + } if (Z_TYPE_P(data) == IS_ARRAY) { sdlAttributePtr *arrayType; @@ -2013,6 +2175,7 @@ static xmlNodePtr to_xml_array(encodeTypePtr type, zval *data, int style, xmlNod zend_hash_find(sdl_type->attributes, SOAP_1_1_ENC_NAMESPACE":arrayType", sizeof(SOAP_1_1_ENC_NAMESPACE":arrayType"), (void **)&arrayType) == SUCCESS && + (*arrayType)->extraAttributes && zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":arrayType", sizeof(WSDL_NAMESPACE":arrayType"), (void **)&ext) == SUCCESS) { char *value, *end; @@ -2061,6 +2224,7 @@ static xmlNodePtr to_xml_array(encodeTypePtr type, zval *data, int style, xmlNod zend_hash_find(sdl_type->attributes, SOAP_1_2_ENC_NAMESPACE":itemType", sizeof(SOAP_1_2_ENC_NAMESPACE":itemType"), (void **)&arrayType) == SUCCESS && + (*arrayType)->extraAttributes && zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":itemType", sizeof(WSDL_NAMESPACE":itemType"), (void **)&ext) == SUCCESS) { if ((*ext)->ns != NULL) { enc = get_encoder(SOAP_GLOBAL(sdl), (*ext)->ns, (*ext)->val); @@ -2071,6 +2235,7 @@ static xmlNodePtr to_xml_array(encodeTypePtr type, zval *data, int style, xmlNod if (zend_hash_find(sdl_type->attributes, SOAP_1_2_ENC_NAMESPACE":arraySize", sizeof(SOAP_1_2_ENC_NAMESPACE":arraySize"), (void **)&arrayType) == SUCCESS && + (*arrayType)->extraAttributes && zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":arraySize", sizeof(WSDL_NAMESPACE":arraysize"), (void **)&ext) == SUCCESS) { dimension = calc_dimension_12((*ext)->val); dims = get_position_12(dimension, (*ext)->val); @@ -2091,6 +2256,7 @@ static xmlNodePtr to_xml_array(encodeTypePtr type, zval *data, int style, xmlNod zend_hash_find(sdl_type->attributes, SOAP_1_2_ENC_NAMESPACE":arraySize", sizeof(SOAP_1_2_ENC_NAMESPACE":arraySize"), (void **)&arrayType) == SUCCESS && + (*arrayType)->extraAttributes && zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":arraySize", sizeof(WSDL_NAMESPACE":arraySize"), (void **)&ext) == SUCCESS) { dimension = calc_dimension_12((*ext)->val); dims = get_position_12(dimension, (*ext)->val); @@ -2168,7 +2334,11 @@ static xmlNodePtr to_xml_array(encodeTypePtr type, zval *data, int style, xmlNod efree(dims); } if (style == SOAP_ENCODED) { - set_ns_and_type(xmlParam, type); + if (SOAP_GLOBAL(features) & SOAP_USE_XSI_ARRAY_TYPE) { + set_ns_and_type_ex(xmlParam, (soap_version == SOAP_1_1) ? SOAP_1_1_ENC_NAMESPACE : SOAP_1_2_ENC_NAMESPACE, "Array"); + } else { + set_ns_and_type(xmlParam, type); + } } return xmlParam; } @@ -2248,6 +2418,7 @@ static zval *to_zval_array(encodeTypePtr type, xmlNodePtr data) zend_hash_find(type->sdl_type->attributes, SOAP_1_1_ENC_NAMESPACE":arrayType", sizeof(SOAP_1_1_ENC_NAMESPACE":arrayType"), (void **)&arrayType) == SUCCESS && + (*arrayType)->extraAttributes && zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":arrayType", sizeof(WSDL_NAMESPACE":arrayType"), (void **)&ext) == SUCCESS) { char *type, *end; @@ -2269,6 +2440,7 @@ static zval *to_zval_array(encodeTypePtr type, xmlNodePtr data) zend_hash_find(type->sdl_type->attributes, SOAP_1_2_ENC_NAMESPACE":itemType", sizeof(SOAP_1_2_ENC_NAMESPACE":itemType"), (void **)&arrayType) == SUCCESS && + (*arrayType)->extraAttributes && zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":itemType", sizeof(WSDL_NAMESPACE":itemType"), (void **)&ext) == SUCCESS) { if ((*ext)->ns != NULL) { @@ -2278,6 +2450,7 @@ static zval *to_zval_array(encodeTypePtr type, xmlNodePtr data) if (zend_hash_find(type->sdl_type->attributes, SOAP_1_2_ENC_NAMESPACE":arraySize", sizeof(SOAP_1_2_ENC_NAMESPACE":arraySize"), (void **)&arrayType) == SUCCESS && + (*arrayType)->extraAttributes && zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":arraySize", sizeof(WSDL_NAMESPACE":arraysize"), (void **)&ext) == SUCCESS) { dimension = calc_dimension_12((*ext)->val); dims = get_position_12(dimension, (*ext)->val); @@ -2290,6 +2463,7 @@ static zval *to_zval_array(encodeTypePtr type, xmlNodePtr data) zend_hash_find(type->sdl_type->attributes, SOAP_1_2_ENC_NAMESPACE":arraySize", sizeof(SOAP_1_2_ENC_NAMESPACE":arraySize"), (void **)&arrayType) == SUCCESS && + (*arrayType)->extraAttributes && zend_hash_find((*arrayType)->extraAttributes, WSDL_NAMESPACE":arraySize", sizeof(WSDL_NAMESPACE":arraysize"), (void **)&ext) == SUCCESS) { dimension = calc_dimension_12((*ext)->val); @@ -2623,12 +2797,12 @@ static xmlNodePtr to_xml_datetime_ex(encodeTypePtr type, zval *data, char *forma /* Time zone support */ #ifdef HAVE_TM_GMTOFF - sprintf(tzbuf, "%c%02d:%02d", (ta->tm_gmtoff < 0) ? '-' : '+', abs(ta->tm_gmtoff / 3600), abs( (ta->tm_gmtoff % 3600) / 60 )); + snprintf(tzbuf, sizeof(tzbuf), "%c%02d:%02d", (ta->tm_gmtoff < 0) ? '-' : '+', abs(ta->tm_gmtoff / 3600), abs( (ta->tm_gmtoff % 3600) / 60 )); #else # ifdef __CYGWIN__ - sprintf(tzbuf, "%c%02d:%02d", ((ta->tm_isdst ? _timezone - 3600:_timezone)>0)?'-':'+', abs((ta->tm_isdst ? _timezone - 3600 : _timezone) / 3600), abs(((ta->tm_isdst ? _timezone - 3600 : _timezone) % 3600) / 60)); + snprintf(tzbuf, sizeof(tzbuf), "%c%02d:%02d", ((ta->tm_isdst ? _timezone - 3600:_timezone)>0)?'-':'+', abs((ta->tm_isdst ? _timezone - 3600 : _timezone) / 3600), abs(((ta->tm_isdst ? _timezone - 3600 : _timezone) % 3600) / 60)); # else - sprintf(tzbuf, "%c%02d:%02d", ((ta->tm_isdst ? timezone - 3600:timezone)>0)?'-':'+', abs((ta->tm_isdst ? timezone - 3600 : timezone) / 3600), abs(((ta->tm_isdst ? timezone - 3600 : timezone) % 3600) / 60)); + snprintf(tzbuf, sizeof(tzbuf), "%c%02d:%02d", ((ta->tm_isdst ? timezone - 3600:timezone)>0)?'-':'+', abs((ta->tm_isdst ? timezone - 3600 : timezone) / 3600), abs(((ta->tm_isdst ? timezone - 3600 : timezone) % 3600) / 60)); # endif #endif if (strcmp(tzbuf,"+00:00") == 0) { @@ -2833,8 +3007,18 @@ static xmlNodePtr to_xml_any(encodeTypePtr type, zval *data, int style, xmlNodeP ret = xmlNewTextLen(BAD_CAST(Z_STRVAL(tmp)), Z_STRLEN(tmp)); zval_dtor(&tmp); } + ret->name = xmlStringTextNoenc; - xmlAddChild(parent, ret); + ret->parent = parent; + ret->doc = parent->doc; + ret->prev = parent->last; + ret->next = NULL; + if (parent->last) { + parent->last->next = ret; + } else { + parent->children = ret; + } + parent->last = ret; return ret; } @@ -2960,9 +3144,9 @@ xmlNodePtr sdl_guess_convert_xml(encodeTypePtr enc, zval *data, int style, xmlNo if (type->encode && (type->encode->details.type == IS_ARRAY || type->encode->details.type == SOAP_ENC_ARRAY)) { - ret = to_xml_array(enc, data, style, parent); + return to_xml_array(enc, data, style, parent); } else { - ret = to_xml_object(enc, data, style, parent); + return to_xml_object(enc, data, style, parent); } break; default: @@ -3133,6 +3317,25 @@ void encode_reset_ns() { TSRMLS_FETCH(); SOAP_GLOBAL(cur_uniq_ns) = 0; + SOAP_GLOBAL(cur_uniq_ref) = 0; + if (SOAP_GLOBAL(ref_map)) { + zend_hash_destroy(SOAP_GLOBAL(ref_map)); + } else { + SOAP_GLOBAL(ref_map) = emalloc(sizeof(HashTable)); + } + zend_hash_init(SOAP_GLOBAL(ref_map), 0, NULL, NULL, 0); +} + +void encode_finish() +{ + TSRMLS_FETCH(); + SOAP_GLOBAL(cur_uniq_ns) = 0; + SOAP_GLOBAL(cur_uniq_ref) = 0; + if (SOAP_GLOBAL(ref_map)) { + zend_hash_destroy(SOAP_GLOBAL(ref_map)); + efree(SOAP_GLOBAL(ref_map)); + SOAP_GLOBAL(ref_map) = NULL; + } } encodePtr get_conversion(int encode) diff --git a/ext/soap/php_encoding.h b/ext/soap/php_encoding.h index aa27705ed..f894ffa68 100644 --- a/ext/soap/php_encoding.h +++ b/ext/soap/php_encoding.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -17,7 +17,7 @@ | Dmitry Stogov <dmitry@zend.com> | +----------------------------------------------------------------------+ */ -/* $Id: php_encoding.h,v 1.38.2.3.2.2 2006/09/20 13:42:50 dmitry Exp $ */ +/* $Id: php_encoding.h,v 1.38.2.3.2.4 2007/04/02 13:43:08 dmitry Exp $ */ #ifndef PHP_ENCODING_H #define PHP_ENCODING_H @@ -201,6 +201,7 @@ void whiteSpace_collapse(xmlChar* str); xmlNodePtr sdl_guess_convert_xml(encodeTypePtr enc, zval* data, int style, xmlNodePtr parent); zval *sdl_guess_convert_zval(encodeTypePtr enc, xmlNodePtr data); +void encode_finish(); void encode_reset_ns(); xmlNsPtr encode_add_ns(xmlNodePtr node, const char* ns); diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index aef629f73..d41bf6997 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -17,7 +17,7 @@ | Dmitry Stogov <dmitry@zend.com> | +----------------------------------------------------------------------+ */ -/* $Id: php_http.c,v 1.77.2.11.2.3 2006/09/06 11:03:45 dmitry Exp $ */ +/* $Id: php_http.c,v 1.77.2.11.2.8 2007/02/24 02:17:26 helly Exp $ */ #include "php_soap.h" #include "ext/standard/base64.h" @@ -469,9 +469,10 @@ try_again: char HA1[33], HA2[33], response[33], cnonce[33], nc[9]; PHP_MD5_CTX md5ctx; unsigned char hash[16]; + unsigned int ctx; PHP_MD5Init(&md5ctx); - sprintf(cnonce, "%d", rand()); + snprintf(cnonce, sizeof(cnonce), "%d", php_rand_r(&ctx)); PHP_MD5Update(&md5ctx, (unsigned char*)cnonce, strlen(cnonce)); PHP_MD5Final(hash, &md5ctx); make_digest(cnonce, hash); @@ -479,7 +480,7 @@ try_again: if (zend_hash_find(Z_ARRVAL_PP(digest), "nc", sizeof("nc"), (void **)&tmp) == SUCCESS && Z_TYPE_PP(tmp) == IS_LONG) { Z_LVAL_PP(tmp)++; - sprintf(nc, "%08ld", Z_LVAL_PP(tmp)); + snprintf(nc, sizeof(nc), "%08ld", Z_LVAL_PP(tmp)); } else { add_assoc_long(*digest, "nc", 1); strcpy(nc, "00000001"); @@ -909,19 +910,20 @@ try_again: efree(http_body); efree(loc); if (new_url->scheme == NULL && new_url->path != NULL) { - new_url->scheme = estrdup(phpurl->scheme); - new_url->host = estrdup(phpurl->host); + new_url->scheme = NULL; + new_url->host = phpurl->host ? estrdup(phpurl->host) : NULL; new_url->port = phpurl->port; if (new_url->path && new_url->path[0] != '/') { - char *t = phpurl->path?phpurl->path:"/"; + char *t = phpurl->path; char *p = strrchr(t, '/'); - char *s = emalloc((p - t) + strlen(new_url->path) + 2); - - strncpy(s, t, (p - t) + 1); - s[(p - t) + 1] = 0; - strcat(s, new_url->path); - efree(new_url->path); - new_url->path = s; + if (p) { + char *s = emalloc((p - t) + strlen(new_url->path) + 2); + strncpy(s, t, (p - t) + 1); + s[(p - t) + 1] = 0; + strcat(s, new_url->path); + efree(new_url->path); + new_url->path = s; + } } } phpurl = new_url; diff --git a/ext/soap/php_http.h b/ext/soap/php_http.h index 1e855232d..f4125b85a 100644 --- a/ext/soap/php_http.h +++ b/ext/soap/php_http.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -17,7 +17,7 @@ | Dmitry Stogov <dmitry@zend.com> | +----------------------------------------------------------------------+ */ -/* $Id: php_http.h,v 1.16.2.1 2006/01/01 12:50:13 sniper Exp $ */ +/* $Id: php_http.h,v 1.16.2.1.2.1 2007/01/01 09:36:06 sebastian Exp $ */ #ifndef PHP_HTTP_H #define PHP_HTTP_H diff --git a/ext/soap/php_packet_soap.c b/ext/soap/php_packet_soap.c index 33fd37839..de7dbd14c 100644 --- a/ext/soap/php_packet_soap.c +++ b/ext/soap/php_packet_soap.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -17,7 +17,7 @@ | Dmitry Stogov <dmitry@zend.com> | +----------------------------------------------------------------------+ */ -/* $Id: php_packet_soap.c,v 1.42.2.1.2.2 2006/07/11 14:24:18 dmitry Exp $ */ +/* $Id: php_packet_soap.c,v 1.42.2.1.2.4 2007/01/01 09:36:06 sebastian Exp $ */ #include "php_soap.h" @@ -350,10 +350,22 @@ int parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunction if (val != NULL) { if (!node_is_equal_ex(val,"result",RPC_SOAP12_NAMESPACE)) { zval *tmp; + zval **arr; tmp = master_to_zval(NULL, val); if (val->name) { - add_assoc_zval(return_value, (char*)val->name, tmp); + if (zend_hash_find(Z_ARRVAL_P(return_value), (char*)val->name, strlen((char*)val->name)+1, (void**)&arr) == SUCCESS) { + add_next_index_zval(*arr, tmp); + } else if (val->next && get_node(val->next, (char*)val->name)) { + zval *arr; + + MAKE_STD_ZVAL(arr); + array_init(arr); + add_next_index_zval(arr, tmp); + add_assoc_zval(return_value, (char*)val->name, arr); + } else { + add_assoc_zval(return_value, (char*)val->name, tmp); + } } else { add_next_index_zval(return_value, tmp); } diff --git a/ext/soap/php_packet_soap.h b/ext/soap/php_packet_soap.h index 97dff61fc..47167fb61 100644 --- a/ext/soap/php_packet_soap.h +++ b/ext/soap/php_packet_soap.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -17,7 +17,7 @@ | Dmitry Stogov <dmitry@zend.com> | +----------------------------------------------------------------------+ */ -/* $Id: php_packet_soap.h,v 1.10.2.1 2006/01/01 12:50:13 sniper Exp $ */ +/* $Id: php_packet_soap.h,v 1.10.2.1.2.1 2007/01/01 09:36:06 sebastian Exp $ */ #ifndef PHP_PACKET_SOAP_H #define PHP_PACKET_SOAP_H diff --git a/ext/soap/php_schema.c b/ext/soap/php_schema.c index 11553ea76..6e7303885 100644 --- a/ext/soap/php_schema.c +++ b/ext/soap/php_schema.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -17,7 +17,7 @@ | Dmitry Stogov <dmitry@zend.com> | +----------------------------------------------------------------------+ */ -/* $Id: php_schema.c,v 1.58.2.6.2.3 2006/10/03 19:51:01 iliaa Exp $ */ +/* $Id: php_schema.c,v 1.58.2.6.2.5 2007/02/15 17:01:29 dmitry Exp $ */ #include "php_soap.h" #include "libxml/uri.h" @@ -681,7 +681,9 @@ static int schema_restriction_simpleContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodeP cur_type->restrictions->enumeration = emalloc(sizeof(HashTable)); zend_hash_init(cur_type->restrictions->enumeration, 0, NULL, delete_restriction_var_char, 0); } - zend_hash_add(cur_type->restrictions->enumeration, enumval->value, strlen(enumval->value)+1, &enumval, sizeof(sdlRestrictionCharPtr), NULL); + if (zend_hash_add(cur_type->restrictions->enumeration, enumval->value, strlen(enumval->value)+1, &enumval, sizeof(sdlRestrictionCharPtr), NULL) == FAILURE) { + delete_restriction_var_char(&enumval); + } } else { break; } @@ -2313,6 +2315,7 @@ void delete_model_persistent(void *handle) void delete_type(void *data) { sdlTypePtr type = *((sdlTypePtr*)data); + if (type->name) { efree(type->name); } diff --git a/ext/soap/php_schema.h b/ext/soap/php_schema.h index 58b8f32cb..6acf476ee 100644 --- a/ext/soap/php_schema.h +++ b/ext/soap/php_schema.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -17,7 +17,7 @@ | Dmitry Stogov <dmitry@zend.com> | +----------------------------------------------------------------------+ */ -/* $Id: php_schema.h,v 1.13.2.2 2006/04/09 23:35:51 andrei Exp $ */ +/* $Id: php_schema.h,v 1.13.2.2.2.1 2007/01/01 09:36:06 sebastian Exp $ */ #ifndef PHP_SCHEMA_H #define PHP_SCHEMA_H diff --git a/ext/soap/php_sdl.c b/ext/soap/php_sdl.c index 12c4da661..e2d830c44 100644 --- a/ext/soap/php_sdl.c +++ b/ext/soap/php_sdl.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -17,7 +17,7 @@ | Dmitry Stogov <dmitry@zend.com> | +----------------------------------------------------------------------+ */ -/* $Id: php_sdl.c,v 1.88.2.12.2.3 2006/09/20 13:42:50 dmitry Exp $ */ +/* $Id: php_sdl.c,v 1.88.2.12.2.7 2007/02/23 20:40:55 stas Exp $ */ #include "php_soap.h" #include "ext/libxml/php_libxml.h" @@ -1250,7 +1250,7 @@ static void sdl_deserialize_type(sdlTypePtr type, sdlTypePtr *types, encodePtr * WSDL_CACHE_GET_INT(i, in); if (i > 0) { - elements = emalloc((i+1) * sizeof(sdlTypePtr)); + elements = safe_emalloc((i+1), sizeof(sdlTypePtr), 0); elements[0] = NULL; type->elements = emalloc(sizeof(HashTable)); zend_hash_init(type->elements, i, NULL, delete_type, 0); @@ -1479,7 +1479,7 @@ static sdlPtr get_sdl_from_cache(const char *fn, const char *uri, time_t t, time WSDL_CACHE_GET_INT(num_encoders, &in); i = num_groups+num_types+num_elements; - types = emalloc((i+1)*sizeof(sdlTypePtr)); + types = safe_emalloc((i+1), sizeof(sdlTypePtr), 0); types[0] = NULL; while (i > 0) { types[i] = emalloc(sizeof(sdlType)); @@ -1492,7 +1492,7 @@ static sdlPtr get_sdl_from_cache(const char *fn, const char *uri, time_t t, time while (enc->details.type != END_KNOWN_TYPES) { i++; enc++; } - encoders = emalloc((i+1)*sizeof(encodePtr)); + encoders = safe_emalloc((i+1), sizeof(encodePtr), 0); i = num_encoders; encoders[0] = NULL; while (i > 0) { @@ -1550,7 +1550,7 @@ static sdlPtr get_sdl_from_cache(const char *fn, const char *uri, time_t t, time /* deserialize bindings */ WSDL_CACHE_GET_INT(num_bindings, &in); - bindings = emalloc(num_bindings*sizeof(sdlBindingPtr)); + bindings = safe_emalloc(num_bindings, sizeof(sdlBindingPtr), 0); if (num_bindings > 0) { sdl->bindings = emalloc(sizeof(HashTable)); zend_hash_init(sdl->bindings, num_bindings, NULL, delete_binding, 0); @@ -1576,7 +1576,7 @@ static sdlPtr get_sdl_from_cache(const char *fn, const char *uri, time_t t, time WSDL_CACHE_GET_INT(num_func, &in); zend_hash_init(&sdl->functions, num_func, NULL, delete_function, 0); if (num_func > 0) { - functions = emalloc(num_func*sizeof(sdlFunctionPtr)); + functions = safe_emalloc(num_func, sizeof(sdlFunctionPtr), 0); for (i = 0; i < num_func; i++) { int binding_num, num_faults; sdlFunctionPtr func = emalloc(sizeof(sdlFunction)); @@ -1862,8 +1862,8 @@ static void sdl_serialize_type(sdlTypePtr type, HashTable *tmp_encoders, HashTab if (i > 0) { sdlTypePtr *tmp; - tmp_elements = emalloc(sizeof(HashTable)); - zend_hash_init(tmp_elements, 0, NULL, NULL, 0); + tmp_elements = emalloc(sizeof(HashTable)); + zend_hash_init(tmp_elements, i, NULL, NULL, 0); zend_hash_internal_pointer_reset(type->elements); while (zend_hash_get_current_data(type->elements, (void**)&tmp) == SUCCESS) { diff --git a/ext/soap/php_sdl.h b/ext/soap/php_sdl.h index a10bbed3e..d8e098368 100644 --- a/ext/soap/php_sdl.h +++ b/ext/soap/php_sdl.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -17,7 +17,7 @@ | Dmitry Stogov <dmitry@zend.com> | +----------------------------------------------------------------------+ */ -/* $Id: php_sdl.h,v 1.37.2.3.2.1 2006/07/11 14:24:18 dmitry Exp $ */ +/* $Id: php_sdl.h,v 1.37.2.3.2.2 2007/01/01 09:36:06 sebastian Exp $ */ #ifndef PHP_SDL_H #define PHP_SDL_H diff --git a/ext/soap/php_soap.h b/ext/soap/php_soap.h index 56841218f..10165f609 100644 --- a/ext/soap/php_soap.h +++ b/ext/soap/php_soap.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -17,7 +17,7 @@ | Dmitry Stogov <dmitry@zend.com> | +----------------------------------------------------------------------+ */ -/* $Id: php_soap.h,v 1.38.2.6.2.2 2006/09/20 13:42:50 dmitry Exp $ */ +/* $Id: php_soap.h,v 1.38.2.6.2.5 2007/04/02 13:43:08 dmitry Exp $ */ #ifndef PHP_SOAP_H #define PHP_SOAP_H @@ -140,7 +140,8 @@ struct _soapService { #define SOAP_AUTHENTICATION_DIGEST 1 #define SOAP_SINGLE_ELEMENT_ARRAYS (1<<0) -#define SOAP_WAIT_ONE_WAY_CALLS (2<<0) +#define SOAP_WAIT_ONE_WAY_CALLS (1<<1) +#define SOAP_USE_XSI_ARRAY_TYPE (1<<2) #define WSDL_CACHE_NONE 0x0 #define WSDL_CACHE_DISK 0x1 @@ -167,6 +168,8 @@ ZEND_BEGIN_MODULE_GLOBALS(soap) HashTable *class_map; int features; HashTable wsdl_cache; + int cur_uniq_ref; + HashTable *ref_map; ZEND_END_MODULE_GLOBALS(soap) #ifdef PHP_WIN32 diff --git a/ext/soap/php_xml.c b/ext/soap/php_xml.c index db3159151..1912e36b0 100644 --- a/ext/soap/php_xml.c +++ b/ext/soap/php_xml.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -17,7 +17,7 @@ | Dmitry Stogov <dmitry@zend.com> | +----------------------------------------------------------------------+ */ -/* $Id: php_xml.c,v 1.25.2.1.2.1 2006/07/11 14:24:18 dmitry Exp $ */ +/* $Id: php_xml.c,v 1.25.2.1.2.2 2007/01/01 09:36:06 sebastian Exp $ */ #include "php_soap.h" #include "libxml/parser.h" diff --git a/ext/soap/php_xml.h b/ext/soap/php_xml.h index b43a219dd..4a1da587b 100644 --- a/ext/soap/php_xml.h +++ b/ext/soap/php_xml.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -17,7 +17,7 @@ | Dmitry Stogov <dmitry@zend.com> | +----------------------------------------------------------------------+ */ -/* $Id: php_xml.h,v 1.17.2.1.2.1 2006/07/11 14:24:18 dmitry Exp $ */ +/* $Id: php_xml.h,v 1.17.2.1.2.2 2007/01/01 09:36:06 sebastian Exp $ */ #ifndef PHP_SOAP_XML_H #define PHP_SOAP_XML_H diff --git a/ext/soap/soap.c b/ext/soap/soap.c index 22007f07a..1b26a8df3 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -17,7 +17,7 @@ | Dmitry Stogov <dmitry@zend.com> | +----------------------------------------------------------------------+ */ -/* $Id: soap.c,v 1.156.2.28.2.16 2006/10/03 19:51:01 iliaa Exp $ */ +/* $Id: soap.c,v 1.156.2.28.2.23 2007/05/02 08:22:13 dmitry Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -444,8 +444,7 @@ static void php_soap_prepare_globals() if (defaultEncoding[i].details.type_str) { if (defaultEncoding[i].details.ns != NULL) { char *ns_type; - ns_type = emalloc(strlen(defaultEncoding[i].details.ns) + strlen(defaultEncoding[i].details.type_str) + 2); - sprintf(ns_type, "%s:%s", defaultEncoding[i].details.ns, defaultEncoding[i].details.type_str); + spprintf(&ns_type, 0, "%s:%s", defaultEncoding[i].details.ns, defaultEncoding[i].details.type_str); zend_hash_add(&defEnc, ns_type, strlen(ns_type) + 1, &enc, sizeof(encodePtr), NULL); efree(ns_type); } else { @@ -480,6 +479,7 @@ static void php_soap_init_globals(zend_soap_globals *soap_globals TSRMLS_DC) soap_globals->sdl = NULL; soap_globals->soap_version = SOAP_1_1; soap_globals->mem_cache = NULL; + soap_globals->ref_map = NULL; } PHP_MSHUTDOWN_FUNCTION(soap) @@ -654,6 +654,8 @@ PHP_MINIT_FUNCTION(soap) REGISTER_LONG_CONSTANT("XSD_ANYTYPE", XSD_ANYTYPE, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("XSD_ANYXML", XSD_ANYXML, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("APACHE_MAP", APACHE_MAP, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SOAP_ENC_OBJECT", SOAP_ENC_OBJECT, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SOAP_ENC_ARRAY", SOAP_ENC_ARRAY, CONST_CS | CONST_PERSISTENT); @@ -664,6 +666,7 @@ PHP_MINIT_FUNCTION(soap) REGISTER_LONG_CONSTANT("SOAP_SINGLE_ELEMENT_ARRAYS", SOAP_SINGLE_ELEMENT_ARRAYS, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SOAP_WAIT_ONE_WAY_CALLS", SOAP_WAIT_ONE_WAY_CALLS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SOAP_USE_XSI_ARRAY_TYPE", SOAP_USE_XSI_ARRAY_TYPE, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("WSDL_CACHE_NONE", WSDL_CACHE_NONE, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("WSDL_CACHE_DISK", WSDL_CACHE_DISK, CONST_CS | CONST_PERSISTENT); @@ -1853,7 +1856,7 @@ PHP_METHOD(SoapServer, handle) php_error_docref(NULL TSRMLS_CC, E_ERROR, "Dump memory failed"); } - sprintf(cont_len, "Content-Length: %d", size); + snprintf(cont_len, sizeof(cont_len), "Content-Length: %d", size); sapi_add_header(cont_len, strlen(cont_len), 1); if (soap_version == SOAP_1_2) { sapi_add_header("Content-Type: application/soap+xml; charset=utf-8", sizeof("Content-Type: application/soap+xml; charset=utf-8")-1, 1); @@ -1982,7 +1985,7 @@ static void soap_server_fault_ex(sdlFunctionPtr function, zval* fault, soapHeade our fault code with their own handling... Figure this out later */ sapi_add_header("HTTP/1.1 500 Internal Service Error", sizeof("HTTP/1.1 500 Internal Service Error")-1, 1); - sprintf(cont_len,"Content-Length: %d", size); + snprintf(cont_len, sizeof(cont_len), "Content-Length: %d", size); sapi_add_header(cont_len, strlen(cont_len), 1); if (soap_version == SOAP_1_2) { sapi_add_header("Content-Type: application/soap+xml; charset=utf-8", sizeof("Content-Type: application/soap+xml; charset=utf-8")-1, 1); @@ -2050,10 +2053,10 @@ static void soap_error_handler(int error_num, const char *error_filename, const INIT_ZVAL(outbuflen); #ifdef va_copy va_copy(argcopy, args); - buffer_len = vsnprintf(buffer, sizeof(buffer)-1, format, argcopy); + buffer_len = vslprintf(buffer, sizeof(buffer)-1, format, argcopy); va_end(argcopy); #else - buffer_len = vsnprintf(buffer, sizeof(buffer)-1, format, args); + buffer_len = vslprintf(buffer, sizeof(buffer)-1, format, args); #endif buffer[sizeof(buffer)-1]=0; if (buffer_len > sizeof(buffer) - 1 || buffer_len < 0) { @@ -2110,10 +2113,10 @@ static void soap_error_handler(int error_num, const char *error_filename, const #ifdef va_copy va_copy(argcopy, args); - buffer_len = vsnprintf(buffer, sizeof(buffer)-1, format, argcopy); + buffer_len = vslprintf(buffer, sizeof(buffer)-1, format, argcopy); va_end(argcopy); #else - buffer_len = vsnprintf(buffer, sizeof(buffer)-1, format, args); + buffer_len = vslprintf(buffer, sizeof(buffer)-1, format, args); #endif buffer[sizeof(buffer)-1]=0; if (buffer_len > sizeof(buffer) - 1 || buffer_len < 0) { @@ -2583,7 +2586,9 @@ static void do_soap_call(zval* this_ptr, xmlFreeDoc(request); if (ret && Z_TYPE(response) == IS_STRING) { + encode_reset_ns(); ret = parse_packet_soap(this_ptr, Z_STRVAL(response), Z_STRLEN(response), fn, NULL, return_value, output_headers TSRMLS_CC); + encode_finish(); } zval_dtor(&response); @@ -2626,7 +2631,9 @@ static void do_soap_call(zval* this_ptr, xmlFreeDoc(request); if (ret && Z_TYPE(response) == IS_STRING) { + encode_reset_ns(); ret = parse_packet_soap(this_ptr, Z_STRVAL(response), Z_STRLEN(response), NULL, function, return_value, output_headers TSRMLS_CC); + encode_finish(); } zval_dtor(&response); @@ -3282,6 +3289,8 @@ static sdlFunctionPtr deserialize_function_call(sdlPtr sdl, xmlDocPtr request, c xmlAttrPtr attr; sdlFunctionPtr function; + encode_reset_ns(); + /* Get <Envelope> element */ env = NULL; trav = request->children; @@ -3530,6 +3539,9 @@ ignore_header: func = func->children; } deserialize_parameters(func, function, num_params, parameters); + + encode_finish(); + return function; } @@ -3982,6 +3994,8 @@ static xmlDocPtr serialize_response_call(sdlFunctionPtr function, char *function } } + encode_finish(); + if (function && function->responseName == NULL && body->children == NULL && head == NULL) { xmlFreeDoc(doc); @@ -4196,6 +4210,8 @@ static xmlDocPtr serialize_function_call(zval *this_ptr, sdlFunctionPtr function } } + encode_finish(); + return doc; } @@ -4223,7 +4239,7 @@ static xmlNodePtr serialize_parameter(sdlParamPtr param, zval *param_val, int in } else { if (name == NULL) { paramName = paramNameBuf; - sprintf(paramName,"param%d",index); + snprintf(paramName, sizeof(paramNameBuf), "param%d",index); } else { paramName = name; } diff --git a/ext/soap/tests/bugs/bug34657.phpt b/ext/soap/tests/bugs/bug34657.phpt new file mode 100755 index 000000000..88f07738d --- /dev/null +++ b/ext/soap/tests/bugs/bug34657.phpt @@ -0,0 +1,35 @@ +--TEST--
+Bug #34657 (If you get a communication problem when loading the WSDL, it fatal's)
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+if (extension_loaded("openssl")) {
+ /*
+ when openssl loaded, tcp stream is less verbose, so some error messages are missing
+ so let's skip the test in this case
+ */
+ die("skip");
+}
+?>
+--FILE--
+<?php
+try {
+ $client = new SoapClient('http://i_dont_exist.com/some.wsdl');
+ echo "?\n";
+} catch (SoapFault $e) {
+ echo get_class($e)."\n";
+ echo $e->faultstring."\n";
+ echo "ok\n";
+} catch (Exception $e) {
+ echo get_class($e)."\n";
+}
+?>
+--EXPECTF--
+Warning: SoapClient::SoapClient(): %s %sbug34657.php on line 3
+
+Warning: SoapClient::SoapClient(http://i_dont_exist.com/some.wsdl): failed to open stream: %sbug34657.php on line 3
+
+Warning: SoapClient::SoapClient(): I/O warning : failed to load external entity "http://i_dont_exist.com/some.wsdl" in %sbug34657.php on line 3
+SoapFault
+SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://i_dont_exist.com/some.wsdl'
+ok
diff --git a/ext/soap/tests/bugs/bug36226-2.phpt b/ext/soap/tests/bugs/bug36226-2.phpt new file mode 100755 index 000000000..5479ae9d1 --- /dev/null +++ b/ext/soap/tests/bugs/bug36226-2.phpt @@ -0,0 +1,121 @@ +--TEST-- +Bug #36226 (Inconsistent handling when passing nillable arrays) +--INI-- +soap.wsdl_cache_enabled=0 +--FILE-- +<?php +$timestamp = "2005-11-08T11:22:07+03:00"; +$wsdl = dirname(__FILE__)."/bug36226-2.wsdl"; + +function PostEvents($x) { + var_dump($x); + exit(); + return $x; +} + +class TestSoapClient extends SoapClient { + function __construct($wsdl, $options) { + parent::__construct($wsdl, $options); + $this->server = new SoapServer($wsdl, $options); + $this->server->addFunction('PostEvents'); + } + + function __doRequest($request, $location, $action, $version) { + echo "$request\n"; + $this->server->handle($request); + return $response; + } +} + +$soapClient = new TestSoapClient($wsdl, + array( + 'trace' => 1, + 'exceptions' => 0, + 'classmap' => array( + 'logOnEvent' => 'LogOnEvent', + 'logOffEvent' => 'LogOffEvent', + 'events' => 'IVREvents' + ), + 'features' => SOAP_SINGLE_ELEMENT_ARRAYS + )); + +$logOnEvent = null; +//$logOnEvent = array(); +$logOffEvents[] = new LogOffEvent(34567, $timestamp, "Smoked"); +//$logOffEvents[] = new LogOffEvent(34568, $timestamp, "SmokeFree"); +$ivrEvents = new IVREvents("1.0", 101, 12345, 'IVR', $logOnEvent, $logOffEvents); +$result = $soapClient->PostEvents($ivrEvents); + +class LogOffEvent { + public $audienceMemberId; + public $timestamp; + public $smokeStatus; + public $callInitiator; + + function __construct($audienceMemberId, $timestamp, $smokeStatus) { + $this->audienceMemberId = $audienceMemberId; + $this->timestamp = $timestamp; + $this->smokeStatus = $smokeStatus; + $this->callInitiator = "IVR"; + } +} + +class LogOnEvent { + public $audienceMemberId; + public $timestamp; + + function __construct($audienceMemberId, $timestamp) { + $this->audienceMemberId = $audienceMemberId; + $this->timestamp = $timestamp; + } +} + +class IVREvents { + public $version; + public $activityId; + public $messageId; + public $source; + public $logOnEvent; + public $logOffEvent; + + function __construct($version, $activityId, $messageId, $source, $logOnEvent=NULL, $logOffEvent=NULL) { + $this->version = $version; + $this->activityId = $activityId; + $this->messageId = $messageId; + $this->source = $source; + $this->logOnEvent = $logOnEvent; + $this->logOffEvent = $logOffEvent; + } + +} +?> +--EXPECT-- +<?xml version="1.0" encoding="UTF-8"?> +<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://testurl/Message" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><SOAP-ENV:Body><ns1:ivrEvents version="1.0" activityId="101" messageId="12345" source="IVR"><ns1:logOffEvent audienceMemberId="34567" timestamp="2005-11-08T11:22:07+03:00" smokeStatus="Smoked" callInitiator="IVR"/><ns1:logOnEvent xsi:nil="true"/></ns1:ivrEvents></SOAP-ENV:Body></SOAP-ENV:Envelope> + +object(IVREvents)#5 (6) { + ["version"]=> + string(3) "1.0" + ["activityId"]=> + int(101) + ["messageId"]=> + int(12345) + ["source"]=> + string(3) "IVR" + ["logOnEvent"]=> + NULL + ["logOffEvent"]=> + array(1) { + [0]=> + object(LogOffEvent)#6 (4) { + ["audienceMemberId"]=> + int(34567) + ["timestamp"]=> + string(25) "2005-11-08T11:22:07+03:00" + ["smokeStatus"]=> + string(6) "Smoked" + ["callInitiator"]=> + string(3) "IVR" + } + } +} diff --git a/ext/soap/tests/bugs/bug36226-2.wsdl b/ext/soap/tests/bugs/bug36226-2.wsdl new file mode 100755 index 000000000..18c2ce3c0 --- /dev/null +++ b/ext/soap/tests/bugs/bug36226-2.wsdl @@ -0,0 +1,543 @@ +<?xml version="1.0" encoding="utf-8"?>
+<definitions xmlns:s1="http://testurl/Events" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:s0="http://testurl/Message" xmlns:s3="http://testurl/Smoker" xmlns:soap12enc="http://www.w3.org/2002/06/soap-envelope" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:s4="http://testurl/AudienceMember" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s2="http://testurl/Actions" xmlns:tns="http://testurl/Service" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" targetNamespace="http://testurl/Service" xmlns="http://schemas.xmlsoap.org/wsdl/">
+ <types>
+ <s:schema elementFormDefault="qualified" targetNamespace="http://testurl/Message">
+ <s:import namespace="http://testurl/Events" />
+ <s:import namespace="http://testurl/Actions" />
+ <s:element name="ivrActions" type="s0:actions" />
+ <s:complexType name="actions">
+ <s:complexContent mixed="false">
+ <s:extension base="s0:abstractMessage">
+ <s:sequence>
+ <s:choice minOccurs="0" maxOccurs="unbounded">
+ <s:element minOccurs="0" maxOccurs="1" name="pauseSmokerAction" type="s2:pauseSmokerAction" />
+ <s:element minOccurs="0" maxOccurs="1" name="terminateSmokerAction" type="s2:terminateSmokerAction" />
+ <s:element minOccurs="0" maxOccurs="1" name="activateSmokerAction" type="s2:activateSmokerAction" />
+ <s:element minOccurs="0" maxOccurs="1" name="addSmokerAction" type="s2:addSmokerAction" />
+ <s:element minOccurs="0" maxOccurs="1" name="updateSmokerAction" type="s2:updateSmokerAction" />
+ <s:element minOccurs="0" maxOccurs="1" name="deleteSmokerAction" type="s2:deleteSmokerAction" />
+ </s:choice>
+ </s:sequence>
+ <s:attribute default="Client" name="source" type="s0:ivrMessageSource" />
+ </s:extension>
+ </s:complexContent>
+ </s:complexType>
+ <s:complexType name="abstractMessage" abstract="true">
+ <s:attribute default="1.0" name="version" type="s:string" />
+ <s:attribute name="activityId" type="s:unsignedLong" use="required" />
+ <s:attribute name="messageId" type="s:unsignedLong" use="required" />
+ </s:complexType>
+ <s:complexType name="events">
+ <s:complexContent mixed="false">
+ <s:extension base="s0:abstractMessage">
+ <s:sequence>
+ <s:choice minOccurs="0" maxOccurs="unbounded">
+ <s:element minOccurs="0" maxOccurs="1" name="authFailureEvent" type="s1:authFailureEvent" />
+ <s:element minOccurs="0" maxOccurs="1" name="logOffEvent" type="s1:logOffEvent" />
+ <s:element minOccurs="0" maxOccurs="1" name="cravingLineEvent" type="s1:cravingLineEvent" />
+ <s:element minOccurs="0" maxOccurs="1" name="terminateEvent" type="s1:terminateEvent" />
+ <s:element minOccurs="0" maxOccurs="1" name="relapseWakeSmsReplaceEvent" type="s1:relapseWakeSmsReplaceEvent" />
+ <s:element minOccurs="0" maxOccurs="1" name="confessionLineEvent" type="s1:confessionLineEvent" />
+ <s:element minOccurs="0" maxOccurs="1" name="rfqRecordedEvent" type="s1:rfqRecordedEvent" />
+ <s:element nillable="true" minOccurs="0" maxOccurs="1" name="logOnEvent" type="s1:logOnEvent" />
+ </s:choice>
+ </s:sequence>
+ <s:attribute default="IVR" name="source" type="s0:ivrMessageSource" />
+ </s:extension>
+ </s:complexContent>
+ </s:complexType>
+ <s:simpleType name="ivrMessageSource">
+ <s:restriction base="s:string">
+ <s:enumeration value="IVR" />
+ <s:enumeration value="Client" />
+ </s:restriction>
+ </s:simpleType>
+ <s:complexType name="actionResults">
+ <s:complexContent mixed="false">
+ <s:extension base="s0:abstractMessage">
+ <s:sequence>
+ <s:choice minOccurs="0" maxOccurs="unbounded">
+ <s:element minOccurs="0" maxOccurs="1" name="updateSmokerActionResult" type="s2:updateSmokerActionResult" />
+ <s:element minOccurs="0" maxOccurs="1" name="activateSmokerActionResult" type="s2:activateSmokerActionResult" />
+ <s:element minOccurs="0" maxOccurs="1" name="deleteSmokerActionResult" type="s2:deleteSmokerActionResult" />
+ <s:element minOccurs="0" maxOccurs="1" name="addSmokerActionResult" type="s2:addSmokerActionResult" />
+ <s:element minOccurs="0" maxOccurs="1" name="pauseSmokerActionResult" type="s2:pauseSmokerActionResult" />
+ <s:element minOccurs="0" maxOccurs="1" name="terminateSmokerActionResult" type="s2:terminateSmokerActionResult" />
+ </s:choice>
+ </s:sequence>
+ <s:attribute default="IVR" name="source" type="s0:ivrMessageSource" />
+ </s:extension>
+ </s:complexContent>
+ </s:complexType>
+ <s:complexType name="eventResults">
+ <s:complexContent mixed="false">
+ <s:extension base="s0:abstractMessage">
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="unbounded" name="eventResult" type="s1:eventResult" />
+ </s:sequence>
+ <s:attribute default="IVR" name="source" type="s0:ivrMessageSource" />
+ </s:extension>
+ </s:complexContent>
+ </s:complexType>
+ <s:element name="ivrActionResults" type="s0:actionResults" />
+ <s:element name="ivrEvents" type="s0:events" />
+ <s:element name="ivrEventResults" type="s0:eventResults" />
+ </s:schema>
+ <s:schema elementFormDefault="qualified" targetNamespace="http://testurl/Events">
+ <s:complexType name="authFailureEvent">
+ <s:complexContent mixed="false">
+ <s:extension base="s1:abstractEvent">
+ <s:attribute name="mobileNumber" type="s:string" />
+ <s:attribute name="line" type="s1:line" use="required" />
+ <s:attribute name="reason" type="s:string" />
+ </s:extension>
+ </s:complexContent>
+ </s:complexType>
+ <s:complexType name="abstractEvent" abstract="true">
+ <s:attribute name="audienceMemberId" type="s:unsignedLong" />
+ <s:attribute name="timestamp" type="s:dateTime" use="required" />
+ </s:complexType>
+ <s:complexType name="logOnEvent">
+ <s:complexContent mixed="false">
+ <s:extension base="s1:abstractEvent" />
+ </s:complexContent>
+ </s:complexType>
+ <s:complexType name="cravingLineEvent">
+ <s:complexContent mixed="false">
+ <s:extension base="s1:abstractEvent">
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="unbounded" name="selection" type="s1:cravingLineEventSelection" />
+ </s:sequence>
+ </s:extension>
+ </s:complexContent>
+ </s:complexType>
+ <s:complexType name="cravingLineEventSelection">
+ <s:attribute name="type" type="s1:cravingLineMessageType" use="required" />
+ <s:attribute name="msgNumber" type="s:positiveInteger" />
+ </s:complexType>
+ <s:simpleType name="cravingLineMessageType">
+ <s:restriction base="s:string">
+ <s:enumeration value="Motivational" />
+ <s:enumeration value="StressReval" />
+ <s:enumeration value="EffectReg" />
+ </s:restriction>
+ </s:simpleType>
+ <s:complexType name="confessionLineEvent">
+ <s:complexContent mixed="false">
+ <s:extension base="s1:abstractEvent">
+ <s:attribute name="smokeStatus" type="s1:smokeStatus" use="required" />
+ </s:extension>
+ </s:complexContent>
+ </s:complexType>
+ <s:simpleType name="smokeStatus">
+ <s:restriction base="s:string">
+ <s:enumeration value="Smoked" />
+ <s:enumeration value="SmokeFree" />
+ </s:restriction>
+ </s:simpleType>
+ <s:complexType name="rfqRecordedEvent">
+ <s:complexContent mixed="false">
+ <s:extension base="s1:abstractEvent" />
+ </s:complexContent>
+ </s:complexType>
+ <s:complexType name="terminateEvent">
+ <s:complexContent mixed="false">
+ <s:extension base="s1:abstractEvent" />
+ </s:complexContent>
+ </s:complexType>
+ <s:complexType name="logOffEvent">
+ <s:complexContent mixed="false">
+ <s:extension base="s1:abstractEvent">
+ <s:attribute name="smokeStatus" type="s1:smokeStatus" use="required" />
+ <s:attribute name="callInitiator" type="s1:callInitiator" use="required" />
+ </s:extension>
+ </s:complexContent>
+ </s:complexType>
+ <s:simpleType name="callInitiator">
+ <s:restriction base="s:string">
+ <s:enumeration value="AudienceMember" />
+ <s:enumeration value="IVR" />
+ </s:restriction>
+ </s:simpleType>
+ <s:complexType name="relapseWakeSmsReplaceEvent">
+ <s:complexContent mixed="false">
+ <s:extension base="s1:abstractEvent">
+ <s:attribute name="relapseCount" type="s:positiveInteger" />
+ </s:extension>
+ </s:complexContent>
+ </s:complexType>
+ <s:simpleType name="line">
+ <s:restriction base="s:string">
+ <s:enumeration value="LogOnOffLine" />
+ <s:enumeration value="CravingLine" />
+ <s:enumeration value="ConfessionLine" />
+ <s:enumeration value="ReasonsForQuittingLine" />
+ </s:restriction>
+ </s:simpleType>
+ <s:complexType name="eventResult">
+ <s:attribute name="success" type="s:boolean" use="required" />
+ </s:complexType>
+ </s:schema>
+ <s:schema elementFormDefault="qualified" targetNamespace="http://testurl/Actions">
+ <s:import namespace="http://testurl/Smoker" />
+ <s:complexType name="updateSmokerActionResult">
+ <s:complexContent mixed="false">
+ <s:extension base="s2:abstractActionResult">
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="unbounded" name="smoker" type="s2:updateSmokerActionResultSmoker" />
+ </s:sequence>
+ </s:extension>
+ </s:complexContent>
+ </s:complexType>
+ <s:complexType name="abstractActionResult">
+ <s:attribute name="resultId" type="s:unsignedLong" use="required" />
+ </s:complexType>
+ <s:complexType name="pauseSmokerActionResult">
+ <s:complexContent mixed="false">
+ <s:extension base="s2:abstractActionResult">
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="unbounded" name="smoker" type="s2:pauseSmokerActionResultSmoker" />
+ </s:sequence>
+ </s:extension>
+ </s:complexContent>
+ </s:complexType>
+ <s:complexType name="pauseSmokerActionResultSmoker">
+ <s:attribute name="audienceMemberId" type="s:unsignedLong" use="required" />
+ <s:attribute name="status" type="s2:pauseSmokerActionResultSmokerStatus" use="required" />
+ <s:attribute name="exception" type="s2:pauseSmokerActionResultSmokerException" />
+ </s:complexType>
+ <s:simpleType name="pauseSmokerActionResultSmokerStatus">
+ <s:restriction base="s:string">
+ <s:enumeration value="Paused" />
+ <s:enumeration value="NotPaused" />
+ </s:restriction>
+ </s:simpleType>
+ <s:simpleType name="pauseSmokerActionResultSmokerException">
+ <s:restriction base="s:string">
+ <s:enumeration value="UnspecifiedError" />
+ <s:enumeration value="IDNotFound" />
+ </s:restriction>
+ </s:simpleType>
+ <s:complexType name="addSmokerActionResult">
+ <s:complexContent mixed="false">
+ <s:extension base="s2:abstractActionResult">
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="unbounded" name="smoker" type="s2:addSmokerActionResultSmoker" />
+ </s:sequence>
+ </s:extension>
+ </s:complexContent>
+ </s:complexType>
+ <s:complexType name="addSmokerActionResultSmoker">
+ <s:attribute name="audienceMemberId" type="s:unsignedLong" use="required" />
+ <s:attribute name="status" type="s2:addSmokerActionResultSmokerStatus" use="required" />
+ <s:attribute name="exception" type="s2:addSmokerActionResultSmokerException" />
+ </s:complexType>
+ <s:simpleType name="addSmokerActionResultSmokerStatus">
+ <s:restriction base="s:string">
+ <s:enumeration value="Added" />
+ <s:enumeration value="NotAdded" />
+ </s:restriction>
+ </s:simpleType>
+ <s:simpleType name="addSmokerActionResultSmokerException">
+ <s:restriction base="s:string">
+ <s:enumeration value="UnspecifiedError" />
+ <s:enumeration value="DuplicateID" />
+ </s:restriction>
+ </s:simpleType>
+ <s:complexType name="deleteSmokerActionResult">
+ <s:complexContent mixed="false">
+ <s:extension base="s2:abstractActionResult">
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="unbounded" name="smoker" type="s2:deleteSmokerActionResultSmoker" />
+ </s:sequence>
+ </s:extension>
+ </s:complexContent>
+ </s:complexType>
+ <s:complexType name="deleteSmokerActionResultSmoker">
+ <s:attribute name="audienceMemberId" type="s:unsignedLong" use="required" />
+ <s:attribute name="status" type="s2:deleteSmokerActionResultSmokerStatus" use="required" />
+ <s:attribute name="exception" type="s2:deleteSmokerActionResultSmokerException" />
+ </s:complexType>
+ <s:simpleType name="deleteSmokerActionResultSmokerStatus">
+ <s:restriction base="s:string">
+ <s:enumeration value="Deleted" />
+ <s:enumeration value="NotDeleted" />
+ </s:restriction>
+ </s:simpleType>
+ <s:simpleType name="deleteSmokerActionResultSmokerException">
+ <s:restriction base="s:string">
+ <s:enumeration value="UnspecifiedError" />
+ <s:enumeration value="IDNotFound" />
+ </s:restriction>
+ </s:simpleType>
+ <s:complexType name="activateSmokerActionResult">
+ <s:complexContent mixed="false">
+ <s:extension base="s2:abstractActionResult">
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="unbounded" name="smoker" type="s2:activateSmokerActionResultSmoker" />
+ </s:sequence>
+ </s:extension>
+ </s:complexContent>
+ </s:complexType>
+ <s:complexType name="activateSmokerActionResultSmoker">
+ <s:attribute name="audienceMemberId" type="s:unsignedLong" use="required" />
+ <s:attribute name="status" type="s2:activateSmokerActionResultSmokerStatus" use="required" />
+ <s:attribute name="exception" type="s2:activateSmokerActionResultSmokerException" />
+ </s:complexType>
+ <s:simpleType name="activateSmokerActionResultSmokerStatus">
+ <s:restriction base="s:string">
+ <s:enumeration value="Activated" />
+ <s:enumeration value="NotActivated" />
+ </s:restriction>
+ </s:simpleType>
+ <s:simpleType name="activateSmokerActionResultSmokerException">
+ <s:restriction base="s:string">
+ <s:enumeration value="UnspecifiedError" />
+ <s:enumeration value="IDNotFound" />
+ </s:restriction>
+ </s:simpleType>
+ <s:complexType name="terminateSmokerActionResult">
+ <s:complexContent mixed="false">
+ <s:extension base="s2:abstractActionResult">
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="unbounded" name="smoker" type="s2:terminateSmokerActionResultSmoker" />
+ </s:sequence>
+ </s:extension>
+ </s:complexContent>
+ </s:complexType>
+ <s:complexType name="terminateSmokerActionResultSmoker">
+ <s:attribute name="audienceMemberId" type="s:unsignedLong" use="required" />
+ <s:attribute name="status" type="s2:terminateSmokerActionResultSmokerStatus" use="required" />
+ <s:attribute name="exception" type="s2:terminateSmokerActionResultSmokerException" />
+ </s:complexType>
+ <s:simpleType name="terminateSmokerActionResultSmokerStatus">
+ <s:restriction base="s:string">
+ <s:enumeration value="Terminated" />
+ <s:enumeration value="NotTerminated" />
+ </s:restriction>
+ </s:simpleType>
+ <s:simpleType name="terminateSmokerActionResultSmokerException">
+ <s:restriction base="s:string">
+ <s:enumeration value="UnspecifiedError" />
+ <s:enumeration value="IDNotFound" />
+ </s:restriction>
+ </s:simpleType>
+ <s:complexType name="updateSmokerActionResultSmoker">
+ <s:attribute name="audienceMemberId" type="s:unsignedLong" use="required" />
+ <s:attribute name="status" type="s2:updateSmokerActionResultSmokerStatus" use="required" />
+ <s:attribute name="exception" type="s2:updateSmokerActionResultSmokerException" />
+ </s:complexType>
+ <s:simpleType name="updateSmokerActionResultSmokerStatus">
+ <s:restriction base="s:string">
+ <s:enumeration value="Updated" />
+ <s:enumeration value="NotUpdated" />
+ </s:restriction>
+ </s:simpleType>
+ <s:simpleType name="updateSmokerActionResultSmokerException">
+ <s:restriction base="s:string">
+ <s:enumeration value="UnspecifiedError" />
+ <s:enumeration value="IDNotFound" />
+ </s:restriction>
+ </s:simpleType>
+ <s:complexType name="pauseSmokerAction">
+ <s:complexContent mixed="false">
+ <s:extension base="s2:abstractAction">
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="unbounded" name="audienceMemberID" type="s:unsignedLong" />
+ </s:sequence>
+ </s:extension>
+ </s:complexContent>
+ </s:complexType>
+ <s:complexType name="abstractAction" abstract="true">
+ <s:attribute name="requestId" type="s:unsignedLong" use="required" />
+ </s:complexType>
+ <s:complexType name="addSmokerAction">
+ <s:complexContent mixed="false">
+ <s:extension base="s2:abstractAction">
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="unbounded" name="smoker" type="s3:smoker" />
+ </s:sequence>
+ </s:extension>
+ </s:complexContent>
+ </s:complexType>
+ <s:complexType name="updateSmokerAction">
+ <s:complexContent mixed="false">
+ <s:extension base="s2:abstractAction">
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="unbounded" name="smoker" type="s3:smoker" />
+ </s:sequence>
+ </s:extension>
+ </s:complexContent>
+ </s:complexType>
+ <s:complexType name="terminateSmokerAction">
+ <s:complexContent mixed="false">
+ <s:extension base="s2:abstractAction">
+ <s:attribute name="audienceMemberId" type="s:unsignedLong" use="required" />
+ </s:extension>
+ </s:complexContent>
+ </s:complexType>
+ <s:complexType name="deleteSmokerAction">
+ <s:complexContent mixed="false">
+ <s:extension base="s2:abstractAction">
+ <s:sequence>
+ <s:element minOccurs="0" maxOccurs="unbounded" name="audienceMemberID" type="s:unsignedLong" />
+ </s:sequence>
+ </s:extension>
+ </s:complexContent>
+ </s:complexType>
+ <s:complexType name="activateSmokerAction">
+ <s:complexContent mixed="false">
+ <s:extension base="s2:abstractAction">
+ <s:attribute name="audienceMemberId" type="s:unsignedLong" use="required" />
+ </s:extension>
+ </s:complexContent>
+ </s:complexType>
+ </s:schema>
+ <s:schema elementFormDefault="qualified" targetNamespace="http://testurl/Smoker">
+ <s:import namespace="http://testurl/AudienceMember" />
+ <s:complexType name="smoker">
+ <s:complexContent mixed="false">
+ <s:extension base="s4:ivrAudienceMember">
+ <s:attribute name="startDate" type="s:date" use="required" />
+ <s:attribute name="phase" type="s3:phase" use="required" />
+ <s:attribute name="day" type="s:positiveInteger" />
+ <s:attribute name="track" type="s3:track" use="required" />
+ <s:attribute name="status" type="s3:status" use="required" />
+ <s:attribute name="baseTime" type="s:string" />
+ <s:attribute name="sunWakeOffset" type="s:string" />
+ <s:attribute name="monWakeOffset" type="s:string" />
+ <s:attribute name="tueWakeOffset" type="s:string" />
+ <s:attribute name="wedWakeOffset" type="s:string" />
+ <s:attribute name="thuWakeOffset" type="s:string" />
+ <s:attribute name="friWakeOffset" type="s:string" />
+ <s:attribute name="satWakeOffset" type="s:string" />
+ <s:attribute name="sunSleepOffset" type="s:string" />
+ <s:attribute name="monSleepOffset" type="s:string" />
+ <s:attribute name="tueSleepOffset" type="s:string" />
+ <s:attribute name="wedSleepOffset" type="s:string" />
+ <s:attribute name="thuSleepOffset" type="s:string" />
+ <s:attribute name="friSleepOffset" type="s:string" />
+ <s:attribute name="satSleepOffset" type="s:string" />
+ <s:attribute name="sunLogOnWindowOffset" type="s:string" />
+ <s:attribute name="monLogOnWindowOffset" type="s:string" />
+ <s:attribute name="tueLogOnWindowOffset" type="s:string" />
+ <s:attribute name="wedLogOnWindowOffset" type="s:string" />
+ <s:attribute name="thuLogOnWindowOffset" type="s:string" />
+ <s:attribute name="friLogOnWindowOffset" type="s:string" />
+ <s:attribute name="satLogOnWindowOffset" type="s:string" />
+ <s:attribute name="sunLogOffWindowOffset" type="s:string" />
+ <s:attribute name="monLogOffWindowOffset" type="s:string" />
+ <s:attribute name="tueLogOffWindowOffset" type="s:string" />
+ <s:attribute name="wedLogOffWindowOffset" type="s:string" />
+ <s:attribute name="thuLogOffWindowOffset" type="s:string" />
+ <s:attribute name="friLogOffWindowOffset" type="s:string" />
+ <s:attribute name="satLogOffWindowOffset" type="s:string" />
+ </s:extension>
+ </s:complexContent>
+ </s:complexType>
+ <s:simpleType name="phase">
+ <s:restriction base="s:string">
+ <s:enumeration value="Prep" />
+ <s:enumeration value="Quit" />
+ <s:enumeration value="Followup" />
+ </s:restriction>
+ </s:simpleType>
+ <s:simpleType name="track">
+ <s:restriction base="s:string">
+ <s:enumeration value="NRT" />
+ <s:enumeration value="NonNRT" />
+ </s:restriction>
+ </s:simpleType>
+ <s:simpleType name="status">
+ <s:restriction base="s:string">
+ <s:enumeration value="Pre-Start" />
+ <s:enumeration value="Completed" />
+ <s:enumeration value="Terminated" />
+ <s:enumeration value="Paused" />
+ <s:enumeration value="Active" />
+ </s:restriction>
+ </s:simpleType>
+ </s:schema>
+ <s:schema elementFormDefault="qualified" targetNamespace="http://testurl/AudienceMember">
+ <s:import namespace="http://testurl/Smoker" />
+ <s:complexType name="ivrAudienceMember">
+ <s:attribute name="id" type="s:unsignedLong" use="required" />
+ <s:attribute name="mobileNumber" type="s:string" />
+ <s:attribute name="firstName" type="s:string" />
+ <s:attribute name="lastName" type="s:string" />
+ </s:complexType>
+ </s:schema>
+ </types>
+ <message name="PostActionsSoapIn">
+ <part name="ivrActions" element="s0:ivrActions" />
+ </message>
+ <message name="PostActionsSoapOut">
+ <part name="PostActionsResult" element="s0:ivrActionResults" />
+ </message>
+ <message name="PostEventsSoapIn">
+ <part name="ivrEvents" element="s0:ivrEvents" />
+ </message>
+ <message name="PostEventsSoapOut">
+ <part name="PostEventsResult" element="s0:ivrEventResults" />
+ </message>
+ <portType name="IVRServicePortSoap">
+ <operation name="PostActions">
+ <input message="tns:PostActionsSoapIn" />
+ <output message="tns:PostActionsSoapOut" />
+ </operation>
+ <operation name="PostEvents">
+ <input message="tns:PostEventsSoapIn" />
+ <output message="tns:PostEventsSoapOut" />
+ </operation>
+ </portType>
+ <binding name="IVRServicePortSoap" type="tns:IVRServicePortSoap">
+ <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" />
+ <operation name="PostActions">
+ <soap:operation soapAction="http://testurl/Service:postActionsIn" style="document" />
+ <input>
+ <soap:body use="literal" />
+ </input>
+ <output>
+ <soap:body use="literal" />
+ </output>
+ </operation>
+ <operation name="PostEvents">
+ <soap:operation soapAction="http://testurl/Service:postEventsIn" style="document" />
+ <input>
+ <soap:body use="literal" />
+ </input>
+ <output>
+ <soap:body use="literal" />
+ </output>
+ </operation>
+ </binding>
+ <binding name="IVRServicePortSoap12" type="tns:IVRServicePortSoap">
+ <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" />
+ <operation name="PostActions">
+ <soap12:operation soapAction="http://testurl/Service:postActionsIn" style="document" />
+ <input>
+ <soap12:body use="literal" />
+ </input>
+ <output>
+ <soap12:body use="literal" />
+ </output>
+ </operation>
+ <operation name="PostEvents">
+ <soap12:operation soapAction="http://testurl/Service:postEventsIn" style="document" />
+ <input>
+ <soap12:body use="literal" />
+ </input>
+ <output>
+ <soap12:body use="literal" />
+ </output>
+ </operation>
+ </binding>
+ <service name="IVRServicePort">
+ <port name="IVRServicePortSoap" binding="tns:IVRServicePortSoap">
+ <soap:address location="test://" />
+ </port>
+ <port name="IVRServicePortSoap12" binding="tns:IVRServicePortSoap12">
+ <soap12:address location="test://" />
+ </port>
+ </service>
+</definitions>
diff --git a/ext/soap/tests/bugs/bug36999.phpt b/ext/soap/tests/bugs/bug36999.phpt new file mode 100755 index 000000000..3ce8378b8 --- /dev/null +++ b/ext/soap/tests/bugs/bug36999.phpt @@ -0,0 +1,50 @@ +--TEST--
+Bug #36999 (xsd:long values clamped to LONG_MAX instead of using double)
+--SKIPIF--
+<?php
+ if (!extension_loaded('soap')) die('skip soap extension not available');
+?>
+--INI--
+soap.wsdl_cache_enabled=0
+--FILE--
+<?php
+
+function echoLong($num) {
+ return $num;
+}
+
+class LocalSoapClient extends SoapClient {
+
+ function __construct($wsdl) {
+ parent::__construct($wsdl);
+ $this->server = new SoapServer($wsdl);
+ $this->server->addFunction('echoLong');
+ }
+
+ function __doRequest($request, $location, $action, $version) {
+ ob_start();
+ $this->server->handle($request);
+ $response = ob_get_contents();
+ ob_end_clean();
+ return $response;
+ }
+
+}
+
+$soap = new LocalSoapClient(dirname(__FILE__)."/bug36999.wsdl");
+
+function test($num) {
+ global $soap;
+ try {
+ printf("%s %0.0f\n", gettype($num), $num);
+ $ret = $soap->echoLong($num);
+ printf("%s %0.0f\n", gettype($ret), $ret);
+ } catch (SoapFault $ex) {
+ var_dump($ex);
+ }
+}
+test(3706790240);
+?>
+--EXPECTF--
+%s 3706790240
+%s 3706790240
diff --git a/ext/soap/tests/bugs/bug36999.wsdl b/ext/soap/tests/bugs/bug36999.wsdl new file mode 100755 index 000000000..80d20b053 --- /dev/null +++ b/ext/soap/tests/bugs/bug36999.wsdl @@ -0,0 +1,48 @@ +<?xml version="1.0" ?> +<definitions + xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" + xmlns:si="http://soapinterop.org/xsd" + xmlns:tns="http://linuxsrv.home/~dmitry/soap/test.wsdl" + xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" + xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" + xmlns="http://schemas.xmlsoap.org/wsdl/" + targetNamespace="http://linuxsrv.home/~dmitry/soap/test.wsdl"> + + <message name="echoLongRequest"> + <part name="x" type="xsd:long" /> + </message> + + <message name="echoLongResponse"> + <part name="x" type="xsd:long" /> + </message> + + <portType name="TestServicePortType"> + <operation name="echoLong"> + <input message="tns:echoLongRequest" /> + <output message="tns:echoLongResponse" /> + </operation> + </portType> + + <binding name="TestServiceBinding" type="tns:TestServicePortType"> + <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" /> + <operation name="echoLong"> + <soap:operation style="rpc" /> + <input> + <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" /> + </input> + <output> + <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" /> + </output> + </operation> + </binding> + + <service name="TestService"> + <port name="TestServicePort" binding="tns:TestServiceBinding"> + <soap:address location="test://" /> + </port> + </service> + +</definitions> diff --git a/ext/soap/tests/bugs/bug37013.phpt b/ext/soap/tests/bugs/bug37013.phpt new file mode 100755 index 000000000..956625030 --- /dev/null +++ b/ext/soap/tests/bugs/bug37013.phpt @@ -0,0 +1,58 @@ +--TEST--
+Bug #37013 (server hangs when returning circular object references)
+--SKIPIF--
+<?php
+ if (!extension_loaded('soap')) die('skip soap extension not available');
+?>
+--INI--
+soap.wsdl_cache_enabled=0
+--FILE--
+<?php
+$request = <<<REQUEST
+<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope
+xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
+xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+<soapenv:Body>
+<ns2:getThingWithParent
+ soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
+ xmlns:ns2="urn:test.soapserver#"/>
+</soapenv:Body>
+
+</soapenv:Envelope>
+REQUEST;
+
+
+class ThingWithParent
+{
+ var $parent;
+ var $id;
+ var $children;
+ function __construct( $id, $parent ) {
+ $this->id = $id;
+ $this->parent = $parent;
+ }
+}
+
+
+class MultiRefTest {
+ public function getThingWithParent() {
+ $p = new ThingWithParent( 1, null );
+ $p2 = new ThingWithParent( 2, $p );
+ $p3 = new ThingWithParent( 3, $p );
+
+ $p->children = array( $p2, $p3 );
+
+ return $p2;
+ }
+}
+
+
+$server = new SoapServer(dirname(__FILE__)."/bug37013.wsdl");
+$server->setClass( "MultiRefTest");
+$server->handle( $request );
+?>
+--EXPECT--
+<?xml version="1.0" encoding="UTF-8"?>
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:test.soapserver#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:getThingWithParentResponse><result id="ref1" xsi:type="SOAP-ENC:Struct"><parent id="ref2" xsi:type="SOAP-ENC:Struct"><parent xsi:nil="true"/><id xsi:type="xsd:int">1</id><children SOAP-ENC:arrayType="SOAP-ENC:Struct[2]" xsi:type="SOAP-ENC:Array"><item href="#ref1"/><item xsi:type="SOAP-ENC:Struct"><parent href="#ref2"/><id xsi:type="xsd:int">3</id><children xsi:nil="true"/></item></children></parent><id xsi:type="xsd:int">2</id><children xsi:nil="true"/></result></ns1:getThingWithParentResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
diff --git a/ext/soap/tests/bugs/bug37013.wsdl b/ext/soap/tests/bugs/bug37013.wsdl new file mode 100755 index 000000000..dbd77fd8d --- /dev/null +++ b/ext/soap/tests/bugs/bug37013.wsdl @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="utf-8"?>
+<definitions name="shoppingcart"
+ xmlns="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:tns="urn:test.soapserver#"
+targetNamespace="urn:test.soapserver#"
+ xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+ xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:types="urn:test.soapserver.types#">
+
+ <!-- all datatypes will be imported to namespace types: -->
+ <types>
+ <xs:schema targetNamespace="urn:test.soapserver.types#">
+ <xs:complexType name="ThingWithParent">
+ <xs:all>
+ <xs:element name="id" type="xs:string"/>
+ <xs:element name="parent" type="types:ThingWithParent"/>
+ <xs:element name="children" type="types:ArrayOfThingWithParent"/>
+ </xs:all>
+ </xs:complexType>
+ <xs:complexType name="ArrayOfThingWithParent">
+ <xs:complexContent>
+ <xs:restriction base="soapenc:Array">
+ <xs:attribute ref="soapenc:arrayType"
+ wsdl:arrayType="tns:ThingWithParent[]"/>
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ </xs:schema>
+ </types>
+ <message name="getThingWithParent-request"/>
+ <message name="getThingWithParent-response">
+ <part name="result" element="types:ThingWithParent"/>
+ </message>
+ <portType name="soapserver-porttype">
+ <operation name="getThingWithParent">
+ <input name="getThingWithParent-request" message="tns:getThingWithParent-request"/>
+ <output name="getThingWithParent-response" message="tns:getThingWithParent-response"/>
+ </operation>
+ </portType>
+ <binding name="soapserver-binding" type="tns:soapserver-porttype">
+ <soap:binding style="rpc"
+ transport="http://schemas.xmlsoap.org/soap/http"/>
+ <operation name="getThingWithParent">
+ <soap:operation soapAction="urn:test.soapserver.SoapServer#getThingWithParent"/>
+ <input>
+ <soap:body use="encoded"
+namespace="urn:test.soapserver#"
+encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </input>
+ <output>
+ <soap:body use="encoded"
+namespace="urn:test.soapserver#"
+encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </output>
+ </operation>
+ </binding>
+
+ <service name="soapserver">
+ <!-- @binding doesn't like to be tns: -->
+ <port name="soapserver-port" binding="tns:soapserver-binding">
+ <soap:address location="xxxxxxxxxxxx"/>
+ </port>
+ </service>
+
+</definitions>
diff --git a/ext/soap/tests/bugs/bug38536.phpt b/ext/soap/tests/bugs/bug38536.phpt new file mode 100755 index 000000000..1dd84d601 --- /dev/null +++ b/ext/soap/tests/bugs/bug38536.phpt @@ -0,0 +1,52 @@ +--TEST-- +Bug #38536 (SOAP returns an array of values instead of an object) +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--INI-- +soap.wsdl_cache_enabled=0 +--FILE-- +<?php +class LocalSoapClient extends SoapClient { + function __doRequest($request, $location, $action, $version) { + return <<<EOF +<?xml version="1.0" encoding="UTF-8"?> +<SOAP-ENV:Envelope + SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" + xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" + xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:ns1="http://www.grupos.com.br/ws/enturma/client"> +<SOAP-ENV:Body> +<getClientInfoFromDomainResponse SOAP-ENC:root="1"> + <xsd:Result xsi:type="ns1:ClientType"> + <id xsi:type="xsd:int">2</id> + <address href="#i2"/> + </xsd:Result> +</getClientInfoFromDomainResponse> +<xsd:address id="i2" xsi:type="ns1:ClientAddressType" SOAP-ENC:root="0"> + <idClient xsi:type="xsd:long">2</idClient> + <address href="#i3"/> +</xsd:address> +<address xsi:type="xsd:string" id="i3" SOAP-ENC:root="0">Test</address> +</SOAP-ENV:Body> +</SOAP-ENV:Envelope> +EOF; + } +} + +ini_set("soap.wsdl_cache_enabled", 0); +$SOAPObject = new LocalSoapClient(dirname(__FILE__).'/bug38536.wsdl'); +print_r($SOAPObject->test()); +?> +--EXPECT-- +stdClass Object +( + [id] => 2 + [address] => stdClass Object + ( + [idClient] => 2 + [address] => Test + ) + +) diff --git a/ext/soap/tests/bugs/bug38536.wsdl b/ext/soap/tests/bugs/bug38536.wsdl new file mode 100755 index 000000000..0ef3fd43c --- /dev/null +++ b/ext/soap/tests/bugs/bug38536.wsdl @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="iso-8859-1"?> +<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" + xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" + xmlns:enturma="http://www.grupos.com.br/ws/enturmaServices" + xmlns:clientTypes="http://www.grupos.com.br/ws/enturma/client" + targetNamespace="http://www.grupos.com.br/ws/enturmaServices" + elementFormDefault="qualified" + attributeFormDefault="qualified"> + <types> + <schema xmlns="http://www.w3.org/2001/XMLSchema" + xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" + xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/" + targetNamespace="http://www.grupos.com.br/ws/enturma/client"> + <complexType name="ClientType"> + <sequence> + <element name="id" type="int"/> + <element name="address" type="clientTypes:ClientAddressType" minOccurs="0"/> + </sequence> + </complexType> + <complexType name="ClientAddressType"> + <sequence> + <element name="idClient" type="int"/> + <element name="address" type="string" minOccurs="0"/> + </sequence> + </complexType> + </schema> + </types> + <message name="testMessage" /> + <message name="testResponse"> + <part name="domain" type="clientTypes:ClientType"/> + </message> + + <portType name="SessionImpl"> + <operation name="test"> + <input message="enturma:testMessage" /> + <output message="enturma:testResponse" /> + </operation> + </portType> + <binding name="SessionBind" type="enturma:SessionImpl"> + <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> + <operation name="test"> + <soap:operation soapAction="test://"/> + <input> + <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="test://"/> + </input> + <output> + <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="test://"/> + </output> + </operation> + </binding> + <service name="Session"> + <port name="SessionImpl" binding="enturma:SessionBind"> + <soap:address location="test://"/> + </port> + </service> +</definitions> diff --git a/ext/soap/tests/bugs/bug39121.phpt b/ext/soap/tests/bugs/bug39121.phpt new file mode 100755 index 000000000..30d60fbfb --- /dev/null +++ b/ext/soap/tests/bugs/bug39121.phpt @@ -0,0 +1,73 @@ +--TEST--
+Bug #39121 (Incorrect return array handling in non-wsdl soap client)
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--INI--
+soap.wsdl_cache_enabled=0
+--FILE--
+<?php
+class LocalSoapClient extends SoapClient {
+ function __doRequest($request, $location, $action, $version) {
+ return <<<EOF
+<?xml version="1.0" encoding="UTF-8"?>
+<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
+ <soap:Body>
+ <getDIDAreaResponse xmlns="http://didx.org/GetList">
+ <soapenc:Array soapenc:arrayType="xsd:string[2]" xsi:type="soapenc:Array">
+ <item xsi:type="xsd:string">StateCode</item>
+ <item xsi:type="xsd:string">description</item>
+ </soapenc:Array>
+ <soapenc:Array soapenc:arrayType="xsd:anyType[2]" xsi:type="soapenc:Array">
+ <item xsi:type="xsd:int">241</item>
+ <item xsi:type="xsd:string">Carabobo</item>
+ </soapenc:Array>
+ <soapenc:Array soapenc:arrayType="xsd:anyType[2]" xsi:type="soapenc:Array">
+ <item xsi:type="xsd:int">243</item>
+ <item xsi:type="xsd:string">Aragua and Carabobo</item>
+ </soapenc:Array>
+ <soapenc:Array soapenc:arrayType="xsd:anyType[2]" xsi:type="soapenc:Array">
+ <item xsi:type="xsd:int">261</item>
+ <item xsi:type="xsd:string">Zulia</item>
+ </soapenc:Array>
+ </getDIDAreaResponse>
+ </soap:Body>
+</soap:Envelope>
+EOF;
+ }
+}
+
+$client = new LocalSoapClient(NULL, array('location'=>'test://','uri'=>'test://'));
+print_r($client->getDIDAreaResponse());
+?>
+--EXPECT--
+Array
+(
+ [Array] => Array
+ (
+ [0] => Array
+ (
+ [0] => StateCode
+ [1] => description
+ )
+
+ [1] => Array
+ (
+ [0] => 241
+ [1] => Carabobo
+ )
+
+ [2] => Array
+ (
+ [0] => 243
+ [1] => Aragua and Carabobo
+ )
+
+ [3] => Array
+ (
+ [0] => 261
+ [1] => Zulia
+ )
+
+ )
+
+)
diff --git a/ext/soap/tests/bugs/bug39815.phpt b/ext/soap/tests/bugs/bug39815.phpt new file mode 100755 index 000000000..ced64cddf --- /dev/null +++ b/ext/soap/tests/bugs/bug39815.phpt @@ -0,0 +1,47 @@ +--TEST--
+Bug #39815 (to_zval_double() in ext/soap/php_encoding.c is not locale-independent)
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+if (!function_exists('setlocale')) die('skip setlocale() not available');
+if (!@setlocale(LC_ALL, 'sv_SE', 'sv_SE.ISO8859-1')) die('skip sv_SE locale not available');
+if (!@setlocale(LC_ALL, 'en_US', 'en_US.ISO8859-1')) die('skip en_US locale not available');
+?>
+--FILE--
+<?php
+function test(){
+ return 123.456;
+}
+class LocalSoapClient extends SoapClient {
+
+ function __construct($wsdl, $options) {
+ parent::__construct($wsdl, $options);
+ $this->server = new SoapServer($wsdl, $options);
+ $this->server->addFunction('test');
+ }
+
+ function __doRequest($request, $location, $action, $version) {
+ ob_start();
+ $this->server->handle($request);
+ $response = ob_get_contents();
+ ob_end_clean();
+ return $response;
+ }
+
+}
+$x = new LocalSoapClient(NULL,array('location'=>'test://',
+ 'uri'=>'http://testuri.org',
+ "trace"=>1));
+setlocale(LC_ALL,"sv_SE","sv_SE.ISO8859-1");
+var_dump($x->test());
+echo $x->__getLastResponse();
+setlocale(LC_ALL,"en_US","en_US.ISO8859-1");
+var_dump($x->test());
+echo $x->__getLastResponse();
+--EXPECT--
+float(123,456)
+<?xml version="1.0" encoding="UTF-8"?>
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://testuri.org" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:testResponse><return xsi:type="xsd:float">123.456</return></ns1:testResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
+float(123.456)
+<?xml version="1.0" encoding="UTF-8"?>
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://testuri.org" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:testResponse><return xsi:type="xsd:float">123.456</return></ns1:testResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
diff --git a/ext/soap/tests/bugs/bug39832.phpt b/ext/soap/tests/bugs/bug39832.phpt new file mode 100755 index 000000000..b8510f32c --- /dev/null +++ b/ext/soap/tests/bugs/bug39832.phpt @@ -0,0 +1,29 @@ +--TEST--
+Bug #39832 (SOAP Server: parameter not matching the WSDL specified type are set to 0)
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--INI--
+soap.wsdl_cache_enabled=0
+--FILE--
+<?php
+$HTTP_RAW_POST_DATA = <<<EOF
+<?xml version="1.0" encoding="UTF-8"?>
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://test.pl"><SOAP-ENV:Body>
+<SOAP-ENV:Test>
+<parameters priority="high">
+<ns1:NetworkErrorCode>1</ns1:NetworkErrorCode>
+</parameters>
+</SOAP-ENV:Test></SOAP-ENV:Body></SOAP-ENV:Envelope>
+EOF;
+
+function Test($x) {
+ return $x->priority;
+}
+
+$x = new SoapServer(dirname(__FILE__)."/bug39832.wsdl");
+$x->addFunction("Test");
+$x->handle();
+?>
+--EXPECT--
+<?xml version="1.0" encoding="UTF-8"?>
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>SOAP-ENV:Server</faultcode><faultstring>SOAP-ERROR: Encoding: Violation of encoding rules</faultstring></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>
diff --git a/ext/soap/tests/bugs/bug39832.wsdl b/ext/soap/tests/bugs/bug39832.wsdl new file mode 100755 index 000000000..a71f581dd --- /dev/null +++ b/ext/soap/tests/bugs/bug39832.wsdl @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<definitions
+ xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
+ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+ xmlns:s="http://www.w3.org/2001/XMLSchema"
+ xmlns:s0="http://test.pl"
+ targetNamespace="http://test.pl"
+ xmlns="http://schemas.xmlsoap.org/wsdl/">
+ <types>
+ <s:schema elementFormDefault="qualified" targetNamespace="http://test.pl">
+ <s:complexType name="MessageInfoType">
+ <s:sequence>
+ <s:element name="NetworkErrorCode" type="s:integer" minOccurs="0"/>
+ </s:sequence>
+ <s:attribute name="priority" type="s0:PriorityType"/>
+ </s:complexType>
+ <s:simpleType name="PriorityType">
+ <s:restriction base="s:integer">
+ <s:minInclusive value="0"/>
+ <s:maxInclusive value="3"/>
+ </s:restriction>
+ </s:simpleType>
+ </s:schema>
+ </types>
+
+ <message name="TestSoapIn">
+ <part name="parameters" type="s0:MessageInfoType" />
+ </message>
+ <message name="TestSoapOut">
+ <part name="parameters" type="s:string" />
+ </message>
+ <portType name="TestSoap">
+ <operation name="Test">
+ <input message="s0:TestSoapIn"/>
+ <output message="s0:TestSoapOut"/>
+ </operation>
+ </portType>
+ <binding name="TestSoap" type="s0:TestSoap">
+ <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
+ <operation name="Test">
+ <soap:operation soapAction="http:/Test/Test" style="rpc"/>
+ <input>
+ <soap:body use="literal"/>
+ </input>
+ <output>
+ <soap:body use="literal"/>
+ </output>
+ </operation>
+ </binding>
+ <service name="Test">
+ <port name="TestSoapPort" binding="s0:TestSoap">
+ <soap:address location="http://localhost/server.php"/>
+ </port>
+ </service>
+</definitions>
diff --git a/ext/soap/tests/bugs/bug40609.phpt b/ext/soap/tests/bugs/bug40609.phpt new file mode 100755 index 000000000..2c96a8fa9 --- /dev/null +++ b/ext/soap/tests/bugs/bug40609.phpt @@ -0,0 +1,21 @@ +--TEST--
+Bug #40609 (Segfaults when using more than one SoapVar in a request)
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--INI--
+soap.wsdl_cache_enabled=0
+--FILE--
+<?php
+ini_set("soap.wsdl_cache_enabled", 0);
+
+$c = new SoapClient(dirname(__FILE__)."/bug40609.wsdl", array('trace' => 1, 'exceptions' => 0));
+
+$c->update(array('symbol' => new SoapVar("<symbol>MSFT</symbol>", XSD_ANYXML),
+ 'price' => new SoapVar("<price>1000</price>", XSD_ANYXML)));
+echo $c->__getLastRequest();
+echo "ok\n";
+?>
+--EXPECT--
+<?xml version="1.0" encoding="UTF-8"?>
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://quickstart.samples/xsd"><SOAP-ENV:Body><ns1:update><symbol>MSFT</symbol><price>1000</price></ns1:update></SOAP-ENV:Body></SOAP-ENV:Envelope>
+ok
diff --git a/ext/soap/tests/bugs/bug40609.wsdl b/ext/soap/tests/bugs/bug40609.wsdl new file mode 100755 index 000000000..0792e90b3 --- /dev/null +++ b/ext/soap/tests/bugs/bug40609.wsdl @@ -0,0 +1,26 @@ +<wsdl:definitions xmlns:axis2="http://quickstart.samples/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:ns="http://quickstart.samples/xsd" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://quickstart.samples/"><wsdl:documentation>
+ Stock Quote Service
+ </wsdl:documentation><wsdl:types><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://quickstart.samples/xsd">
+<xs:element name="getPrice">
+<xs:complexType>
+<xs:sequence>
+<xs:element name="symbol" nillable="true" type="xs:string" />
+</xs:sequence>
+</xs:complexType>
+</xs:element>
+<xs:element name="getPriceResponse">
+<xs:complexType>
+<xs:sequence>
+<xs:element name="return" nillable="true" type="xs:double" />
+</xs:sequence>
+</xs:complexType>
+</xs:element>
+<xs:element name="update">
+<xs:complexType>
+<xs:sequence>
+<xs:element name="symbol" nillable="true" type="xs:any" />
+<xs:element name="price" nillable="true" type="xs:any" />
+</xs:sequence>
+</xs:complexType>
+</xs:element>
+</xs:schema></wsdl:types><wsdl:message name="updateMessage"><wsdl:part name="part1" element="ns:update" /></wsdl:message><wsdl:message name="getPriceMessage"><wsdl:part name="part1" element="ns:getPrice" /></wsdl:message><wsdl:message name="getPriceResponseMessage"><wsdl:part name="part1" element="ns:getPriceResponse" /></wsdl:message><wsdl:portType name="StockQuoteServicePortType"><wsdl:operation name="update"><wsdl:input xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" message="axis2:updateMessage" wsaw:Action="urn:update" /></wsdl:operation><wsdl:operation name="getPrice"><wsdl:input xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" message="axis2:getPriceMessage" wsaw:Action="urn:getPrice" /><wsdl:output xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" message="axis2:getPriceResponseMessage" wsaw:Action="http://quickstart.samples/StockQuoteServicePortType/getPriceResponse" /></wsdl:operation></wsdl:portType><wsdl:binding name="StockQuoteServiceSOAP11Binding" type="axis2:StockQuoteServicePortType"><soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" /><wsdl:operation name="update"><soap:operation soapAction="urn:update" style="document" /><wsdl:input><soap:body use="literal" /></wsdl:input></wsdl:operation><wsdl:operation name="getPrice"><soap:operation soapAction="urn:getPrice" style="document" /><wsdl:input><soap:body use="literal" /></wsdl:input><wsdl:output><soap:body use="literal" /></wsdl:output></wsdl:operation></wsdl:binding><wsdl:binding name="StockQuoteServiceSOAP12Binding" type="axis2:StockQuoteServicePortType"><soap12:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" /><wsdl:operation name="update"><soap12:operation soapAction="urn:update" style="document" /><wsdl:input><soap12:body use="literal" /></wsdl:input></wsdl:operation><wsdl:operation name="getPrice"><soap12:operation soapAction="urn:getPrice" style="document" /><wsdl:input><soap12:body use="literal" /></wsdl:input><wsdl:output><soap12:body use="literal" /></wsdl:output></wsdl:operation></wsdl:binding><wsdl:binding name="StockQuoteServiceHttpBinding" type="axis2:StockQuoteServicePortType"><http:binding verb="POST" /><wsdl:operation name="update"><http:operation location="update" /><wsdl:input><mime:content type="text/xml" /></wsdl:input></wsdl:operation><wsdl:operation name="getPrice"><http:operation location="getPrice" /><wsdl:input><mime:content type="text/xml" /></wsdl:input><wsdl:output><mime:content type="text/xml" /></wsdl:output></wsdl:operation></wsdl:binding><wsdl:service name="StockQuoteService"><wsdl:port name="StockQuoteServiceSOAP11port_http" binding="axis2:StockQuoteServiceSOAP11Binding"><soap:address location="test://" /></wsdl:port><wsdl:port name="StockQuoteServiceSOAP12port_http" binding="axis2:StockQuoteServiceSOAP12Binding"><soap12:address location="test://" /></wsdl:port><wsdl:port name="StockQuoteServiceHttpport1" binding="axis2:StockQuoteServiceHttpBinding"><http:address location="test://" /></wsdl:port></wsdl:service></wsdl:definitions>
\ No newline at end of file diff --git a/ext/soap/tests/bugs/bug41004.phpt b/ext/soap/tests/bugs/bug41004.phpt new file mode 100755 index 000000000..7359ead38 --- /dev/null +++ b/ext/soap/tests/bugs/bug41004.phpt @@ -0,0 +1,36 @@ +--TEST--
+Bug #41004 minOccurs="0" and null class member variable
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+ini_set('soap.wsdl_cache_enabled', false);
+
+class EchoBean{
+ public $mandatoryElement;
+ public $optionalElement;
+
+}
+
+class EchoRequest{
+ public $in;
+}
+
+class EchoResponse{
+ public $out;
+}
+
+$wsdl = dirname(__FILE__)."/bug41004.wsdl";
+$classmap = array('EchoBean'=>'EchoBean','echo'=>'EchoRequest','echoResponse'=>'EchoResponse');
+$client = new SoapClient($wsdl, array('location'=>'test://',"classmap" => $classmap, 'exceptions'=>0, 'trace'=>1));
+$echo=new EchoRequest();
+$in=new EchoBean();
+$in->mandatoryElement="REV";
+$in->optionalElement=NULL;
+$echo->in=$in;
+$client->echo($echo);
+echo $client->__getLastRequest();
+?>
+--EXPECT--
+<?xml version="1.0" encoding="UTF-8"?>
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:Formation"><SOAP-ENV:Body><ns1:echo><in><mandatoryElement>REV</mandatoryElement></in></ns1:echo></SOAP-ENV:Body></SOAP-ENV:Envelope>
diff --git a/ext/soap/tests/bugs/bug41004.wsdl b/ext/soap/tests/bugs/bug41004.wsdl new file mode 100755 index 000000000..d683e5d4a --- /dev/null +++ b/ext/soap/tests/bugs/bug41004.wsdl @@ -0,0 +1,69 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+ xmlns:tns="urn:Formation" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="Formation"
+ targetNamespace="urn:Formation">
+ <wsdl:types>
+ <xsd:schema targetNamespace="urn:Formation">
+ <xsd:element name="echo">
+ <xsd:complexType>
+ <xsd:sequence>
<xsd:element name="in" type="tns:EchoBean"></xsd:element> + </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element> + <xsd:element name="echoResponse"> + <xsd:complexType> + <xsd:sequence>
+ <xsd:element name="out" type="tns:EchoBean"></xsd:element> + </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element> + <xsd:simpleType name="Product1Type">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="REV"></xsd:enumeration>
+ <xsd:enumeration value="CLA"></xsd:enumeration>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:complexType name="EchoBean"> + <xsd:sequence> + <xsd:element name="mandatoryElement"
+ type="tns:Product1Type"> + </xsd:element>
+ <xsd:element name="optionalElement"
+ type="tns:Product1Type" maxOccurs="1" minOccurs="0">
+ </xsd:element> + </xsd:sequence>
+ </xsd:complexType> + </xsd:schema>
+ </wsdl:types>
+ <wsdl:message name="echoRequest">
+ <wsdl:part name="parameters" element="tns:echo"></wsdl:part>
+ </wsdl:message> + <wsdl:message name="echoResponse"> + <wsdl:part name="parameters" element="tns:echoResponse"></wsdl:part>
+ </wsdl:message> + <wsdl:portType name="Formation">
+ <wsdl:operation name="echo">
+ <wsdl:input message="tns:echoRequest"></wsdl:input> + <wsdl:output message="tns:echoResponse"></wsdl:output>
+ </wsdl:operation> + </wsdl:portType>
+ <wsdl:binding name="FormationServiceV1" type="tns:Formation">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="echo">
+ <soap:operation soapAction="urn:Formation/echo" /> + <wsdl:input> + <soap:body use="literal" />
+ </wsdl:input> + <wsdl:output> + <soap:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation> + </wsdl:binding>
+ <wsdl:service name="Formation">
+ <wsdl:port binding="tns:FormationServiceV1"
+ name="FormationSOAP">
+ <soap:address
+ location="http://localhost:8080/webapp/services/FormationServiceV1" />
+ </wsdl:port>
+ </wsdl:service>
+</wsdl:definitions>
diff --git a/ext/soap/tests/bugs/bug41097.phpt b/ext/soap/tests/bugs/bug41097.phpt new file mode 100755 index 000000000..a9cfd1414 --- /dev/null +++ b/ext/soap/tests/bugs/bug41097.phpt @@ -0,0 +1,27 @@ +--TEST-- +Bug #41097 (ext/soap returning associative array as indexed without using WSDL) +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +function test($soap, $array) { + $soap->test($array); + echo (strpos($soap->__getLastRequest(), ':Map"') != false)?"Map\n":"Array\n"; +} + + +$soap = new SoapClient(null, array('uri' => 'http://uri/', 'location' => 'test://', 'exceptions' => 0, 'trace' => 1)); +test($soap, array('Foo', 'Bar')); +test($soap, array(5 => 'Foo', 10 => 'Bar')); +test($soap, array('5' => 'Foo', '10' => 'Bar')); +$soap->test(new SoapVar(array('Foo', 'Bar'), APACHE_MAP)); +echo (strpos($soap->__getLastRequest(), ':Map"') != false)?"Map\n":"Array\n"; +$soap->test(new SoapVar(array('Foo', 'Bar'), SOAP_ENC_ARRAY)); +echo (strpos($soap->__getLastRequest(), ':Map"') != false)?"Map\n":"Array\n"; +?> +--EXPECT-- +Array +Map +Map +Map +Array diff --git a/ext/soap/tests/interop/Round2/Base/r2_base_009s.phpt b/ext/soap/tests/interop/Round2/Base/r2_base_009s.phpt index 3a2890c99..f1371511d 100644 --- a/ext/soap/tests/interop/Round2/Base/r2_base_009s.phpt +++ b/ext/soap/tests/interop/Round2/Base/r2_base_009s.phpt @@ -14,7 +14,7 @@ echo "ok\n"; ?>
--EXPECT--
<?xml version="1.0" encoding="UTF-8"?>
-<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://soapinterop.org/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="http://soapinterop.org/xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:echoStringArray><inputStringArray xsi:nil="true" xsi:type="ns2:ArrayOfstring"/></ns1:echoStringArray></SOAP-ENV:Body></SOAP-ENV:Envelope>
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://soapinterop.org/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns2="http://soapinterop.org/xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:echoStringArray><inputStringArray xsi:nil="true" xsi:type="ns2:ArrayOfstring"/></ns1:echoStringArray></SOAP-ENV:Body></SOAP-ENV:Envelope>
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://soapinterop.org/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="http://soapinterop.org/xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:echoStringArrayResponse><outputStringArray xsi:nil="true" xsi:type="ns2:ArrayOfstring"/></ns1:echoStringArrayResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
ok
diff --git a/ext/soap/tests/interop/Round2/Base/r2_base_015p.phpt b/ext/soap/tests/interop/Round2/Base/r2_base_015p.phpt index b88162cfe..702da37b9 100644 --- a/ext/soap/tests/interop/Round2/Base/r2_base_015p.phpt +++ b/ext/soap/tests/interop/Round2/Base/r2_base_015p.phpt @@ -12,9 +12,10 @@ class SOAPStruct { }
}
-$struct = new SOAPStruct('arg',34,325.325);
+$struct1 = new SOAPStruct('arg',34,325.325);
+$struct2 = new SOAPStruct('arg',34,325.325);
$client = new SoapClient(NULL,array("location"=>"test://","uri"=>"http://soapinterop.org/","trace"=>1,"exceptions"=>0));
-$client->__soapCall("echoStructArray", array(array($struct,$struct)), array("soapaction"=>"http://soapinterop.org/","uri"=>"http://soapinterop.org/"));
+$client->__soapCall("echoStructArray", array(array($struct1,$struct2)), array("soapaction"=>"http://soapinterop.org/","uri"=>"http://soapinterop.org/"));
echo $client->__getlastrequest();
$HTTP_RAW_POST_DATA = $client->__getlastrequest();
include("round2_base.inc");
diff --git a/ext/soap/tests/interop/Round2/Base/r2_base_015s.phpt b/ext/soap/tests/interop/Round2/Base/r2_base_015s.phpt index 424d7950d..dafb53065 100644 --- a/ext/soap/tests/interop/Round2/Base/r2_base_015s.phpt +++ b/ext/soap/tests/interop/Round2/Base/r2_base_015s.phpt @@ -12,17 +12,21 @@ class SOAPStruct { }
}
-$struct = new SoapVar(array(
+$struct1 = new SoapVar(array(
+ new SoapVar('arg', XSD_STRING, null, null, 'varString'),
+ new SoapVar('34', XSD_INT, null, null, 'varInt'),
+ new SoapVar('325.325', XSD_FLOAT, null, null, 'varFloat')
+ ),SOAP_ENC_OBJECT,"SOAPStruct","http://soapinterop.org/xsd");
+$struct2 = new SoapVar(array(
new SoapVar('arg', XSD_STRING, null, null, 'varString'),
new SoapVar('34', XSD_INT, null, null, 'varInt'),
new SoapVar('325.325', XSD_FLOAT, null, null, 'varFloat')
),SOAP_ENC_OBJECT,"SOAPStruct","http://soapinterop.org/xsd");
$param = new SoapParam(new SoapVar(array(
- $struct,
- $struct
+ $struct1,
+ $struct2
),SOAP_ENC_ARRAY,"ArrayOfSOAPStruct","http://soapinterop.org/xsd"), "inputStructArray");
-$struct = new SOAPStruct('arg',34,325.325);
$client = new SoapClient(NULL,array("location"=>"test://","uri"=>"http://soapinterop.org/","trace"=>1,"exceptions"=>0));
$client->__soapCall("echoStructArray", array($param), array("soapaction"=>"http://soapinterop.org/","uri"=>"http://soapinterop.org/"));
echo $client->__getlastrequest();
diff --git a/ext/soap/tests/interop/Round2/Base/r2_base_015w.phpt b/ext/soap/tests/interop/Round2/Base/r2_base_015w.phpt index 31803f846..9ffd2e5e1 100644 --- a/ext/soap/tests/interop/Round2/Base/r2_base_015w.phpt +++ b/ext/soap/tests/interop/Round2/Base/r2_base_015w.phpt @@ -12,9 +12,10 @@ class SOAPStruct { }
}
-$struct = new SOAPStruct('arg',34,325.325);
+$struct1 = new SOAPStruct('arg',34,325.325);
+$struct2 = new SOAPStruct('arg',34,325.325);
$client = new SoapClient(dirname(__FILE__)."/round2_base.wsdl",array("trace"=>1,"exceptions"=>0));
-$client->echoStructArray(array($struct,$struct));
+$client->echoStructArray(array($struct1,$struct2));
echo $client->__getlastrequest();
$HTTP_RAW_POST_DATA = $client->__getlastrequest();
include("round2_base.inc");
diff --git a/ext/soap/tests/interop/Round3/GroupD/r3_groupD_import3_002w.phpt b/ext/soap/tests/interop/Round3/GroupD/r3_groupD_import3_002w.phpt index 9f9603607..1a670731a 100644 --- a/ext/soap/tests/interop/Round3/GroupD/r3_groupD_import3_002w.phpt +++ b/ext/soap/tests/interop/Round3/GroupD/r3_groupD_import3_002w.phpt @@ -11,9 +11,10 @@ class SOAPStruct { $this->varFloat = $f;
}
}
-$struct = new SOAPStruct('arg',34,325.325);
+$struct1 = new SOAPStruct('arg',34,325.325);
+$struct2 = new SOAPStruct('arg',34,325.325);
$client = new SoapClient(dirname(__FILE__)."/round3_groupD_import3.wsdl",array("trace"=>1,"exceptions"=>0));
-$client->echoStructArray(array($struct,$struct));
+$client->echoStructArray(array($struct1,$struct2));
echo $client->__getlastrequest();
$HTTP_RAW_POST_DATA = $client->__getlastrequest();
include("round3_groupD_import3.inc");
diff --git a/ext/soap/tests/interop/Round3/GroupE/r3_groupE_list_005w.phpt b/ext/soap/tests/interop/Round3/GroupE/r3_groupE_list_005w.phpt index 224f44dc2..922d7ea2e 100644 --- a/ext/soap/tests/interop/Round3/GroupE/r3_groupE_list_005w.phpt +++ b/ext/soap/tests/interop/Round3/GroupE/r3_groupE_list_005w.phpt @@ -1,7 +1,7 @@ --TEST--
SOAP Interop Round3 GroupE List 005 (php/wsdl): echoLinkedList (cyclic)
--SKIPIF--
-<?php require_once('skipif.inc'); die('skip cyclic stuctures are not supported yet'); ?>
+<?php require_once('skipif.inc'); ?>
--FILE--
<?php
class SOAPList {
@@ -22,9 +22,9 @@ echo "ok\n"; ?>
--EXPECT--
<?xml version="1.0" encoding="UTF-8"?>
-<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://soapinterop.org/WSDLInteropTestRpcEnc" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns2="http://soapinterop.org/xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:echoLinkedList><param0 xsi:type="ns2:List"><varInt xsi:type="xsd:int">1</varInt><varString xsi:type="xsd:string">arg1</varString><child xsi:type="ns2:List"><varInt xsi:type="xsd:int">2</varInt><varString xsi:type="xsd:string">arg2</varString><child xsi:type="ns2:List"><varInt xsi:type="xsd:int">3</varInt><varString xsi:type="xsd:string">arg3</varString><child xsi:nil="1" xsi:type="ns2:List"/></child></child></param0></ns1:echoLinkedList></SOAP-ENV:Body></SOAP-ENV:Envelope>
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://soapinterop.org/WSDLInteropTestRpcEnc" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="http://soapinterop.org/xsd" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:echoLinkedList><param0 id="ref1" xsi:type="ns2:List"><varInt xsi:type="xsd:int">1</varInt><varString xsi:type="xsd:string">arg1</varString><child xsi:type="ns2:List"><varInt xsi:type="xsd:int">2</varInt><varString xsi:type="xsd:string">arg2</varString><child xsi:type="ns2:List"><varInt xsi:type="xsd:int">3</varInt><varString xsi:type="xsd:string">arg3</varString><child href="#ref1"/></child></child></param0></ns1:echoLinkedList></SOAP-ENV:Body></SOAP-ENV:Envelope>
<?xml version="1.0" encoding="UTF-8"?>
-<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://soapinterop.org/WSDLInteropTestRpcEnc" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns2="http://soapinterop.org/xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:echoLinkedListResponse><return xsi:type="ns2:List"><varInt xsi:type="xsd:int">1</varInt><varString xsi:type="xsd:string">arg1</varString><child xsi:type="ns2:List"><varInt xsi:type="xsd:int">2</varInt><varString xsi:type="xsd:string">arg2</varString><child xsi:type="ns2:List"><varInt xsi:type="xsd:int">3</varInt><varString xsi:type="xsd:string">arg3</varString><child xsi:nil="1" xsi:type="ns2:List"/></child></child></return></ns1:echoLinkedListResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://soapinterop.org/WSDLInteropTestRpcEnc" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="http://soapinterop.org/xsd" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:echoLinkedListResponse><return id="ref1" xsi:type="ns2:List"><varInt xsi:type="xsd:int">1</varInt><varString xsi:type="xsd:string">arg1</varString><child xsi:type="ns2:List"><varInt xsi:type="xsd:int">2</varInt><varString xsi:type="xsd:string">arg2</varString><child xsi:type="ns2:List"><varInt xsi:type="xsd:int">3</varInt><varString xsi:type="xsd:string">arg3</varString><child href="#ref1"/></child></child></return></ns1:echoLinkedListResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
object(stdClass)#7 (3) {
["varInt"]=>
int(1)
@@ -43,7 +43,28 @@ object(stdClass)#7 (3) { ["varString"]=>
string(4) "arg3"
["child"]=>
- NULL
+ object(stdClass)#7 (3) {
+ ["varInt"]=>
+ int(1)
+ ["varString"]=>
+ string(4) "arg1"
+ ["child"]=>
+ object(stdClass)#8 (3) {
+ ["varInt"]=>
+ int(2)
+ ["varString"]=>
+ string(4) "arg2"
+ ["child"]=>
+ object(stdClass)#9 (3) {
+ ["varInt"]=>
+ int(3)
+ ["varString"]=>
+ string(4) "arg3"
+ ["child"]=>
+ *RECURSION*
+ }
+ }
+ }
}
}
}
diff --git a/ext/soap/tests/interop/Round3/GroupE/r3_groupE_list_006w.phpt b/ext/soap/tests/interop/Round3/GroupE/r3_groupE_list_006w.phpt index a786492df..f51c4afa1 100644 --- a/ext/soap/tests/interop/Round3/GroupE/r3_groupE_list_006w.phpt +++ b/ext/soap/tests/interop/Round3/GroupE/r3_groupE_list_006w.phpt @@ -1,7 +1,7 @@ --TEST--
SOAP Interop Round3 GroupE List 006 (php/wsdl): echoLinkedList (cyclic)
--SKIPIF--
-<?php require_once('skipif.inc'); die("skip cyclic stuctures are not supported yet"); ?>
+<?php require_once('skipif.inc'); ?>
--FILE--
<?php
class SOAPList {
@@ -22,16 +22,16 @@ echo "ok\n"; ?>
--EXPECT--
<?xml version="1.0" encoding="UTF-8"?>
-<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://soapinterop.org/WSDLInteropTestRpcEnc" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns2="http://soapinterop.org/xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:echoLinkedList><param0 xsi:type="ns2:List"><varInt xsi:type="xsd:int">1</varInt><varString xsi:type="xsd:string">arg1</varString><child xsi:type="ns2:List"><varInt xsi:type="xsd:int">2</varInt><varString xsi:type="xsd:string">arg2</varString><child xsi:type="ns2:List"><varInt xsi:type="xsd:int">3</varInt><varString xsi:type="xsd:string">arg3</varString><child xsi:nil="1" xsi:type="ns2:List"/></child></child></param0></ns1:echoLinkedList></SOAP-ENV:Body></SOAP-ENV:Envelope>
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://soapinterop.org/WSDLInteropTestRpcEnc" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="http://soapinterop.org/xsd" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:echoLinkedList><param0 xsi:type="ns2:List"><varInt xsi:type="xsd:int">1</varInt><varString xsi:type="xsd:string">arg1</varString><child id="ref1" xsi:type="ns2:List"><varInt xsi:type="xsd:int">2</varInt><varString xsi:type="xsd:string">arg2</varString><child xsi:type="ns2:List"><varInt xsi:type="xsd:int">3</varInt><varString xsi:type="xsd:string">arg3</varString><child href="#ref1"/></child></child></param0></ns1:echoLinkedList></SOAP-ENV:Body></SOAP-ENV:Envelope>
<?xml version="1.0" encoding="UTF-8"?>
-<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://soapinterop.org/WSDLInteropTestRpcEnc" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns2="http://soapinterop.org/xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:echoLinkedListResponse><return xsi:type="ns2:List"><varInt xsi:type="xsd:int">1</varInt><varString xsi:type="xsd:string">arg1</varString><child xsi:type="ns2:List"><varInt xsi:type="xsd:int">2</varInt><varString xsi:type="xsd:string">arg2</varString><child xsi:type="ns2:List"><varInt xsi:type="xsd:int">3</varInt><varString xsi:type="xsd:string">arg3</varString><child xsi:nil="1" xsi:type="ns2:List"/></child></child></return></ns1:echoLinkedListResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://soapinterop.org/WSDLInteropTestRpcEnc" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="http://soapinterop.org/xsd" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:echoLinkedListResponse><return xsi:type="ns2:List"><varInt xsi:type="xsd:int">1</varInt><varString xsi:type="xsd:string">arg1</varString><child id="ref1" xsi:type="ns2:List"><varInt xsi:type="xsd:int">2</varInt><varString xsi:type="xsd:string">arg2</varString><child xsi:type="ns2:List"><varInt xsi:type="xsd:int">3</varInt><varString xsi:type="xsd:string">arg3</varString><child href="#ref1"/></child></child></return></ns1:echoLinkedListResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
object(stdClass)#7 (3) {
["varInt"]=>
int(1)
["varString"]=>
string(4) "arg1"
["child"]=>
- object(stdClass)#8 (3) {
+ &object(stdClass)#8 (3) {
["varInt"]=>
int(2)
["varString"]=>
@@ -43,7 +43,21 @@ object(stdClass)#7 (3) { ["varString"]=>
string(4) "arg3"
["child"]=>
- NULL
+ object(stdClass)#8 (3) {
+ ["varInt"]=>
+ int(2)
+ ["varString"]=>
+ string(4) "arg2"
+ ["child"]=>
+ object(stdClass)#9 (3) {
+ ["varInt"]=>
+ int(3)
+ ["varString"]=>
+ string(4) "arg3"
+ ["child"]=>
+ *RECURSION*
+ }
+ }
}
}
}
diff --git a/ext/soap/tests/interop/Round4/GroupI/r4_groupI_xsd_014w.phpt b/ext/soap/tests/interop/Round4/GroupI/r4_groupI_xsd_014w.phpt index eb6dd7af1..052333a27 100644 --- a/ext/soap/tests/interop/Round4/GroupI/r4_groupI_xsd_014w.phpt +++ b/ext/soap/tests/interop/Round4/GroupI/r4_groupI_xsd_014w.phpt @@ -11,9 +11,11 @@ class SOAPComplexType { $this->varFloat = $f;
}
}
-$struct = new SOAPComplexType('arg',34,325.325);
+$struct1 = new SOAPComplexType('arg',34,325.325);
+$struct2 = new SOAPComplexType('arg',34,325.325);
+$struct3 = new SOAPComplexType('arg',34,325.325);
$client = new SoapClient(dirname(__FILE__)."/round4_groupI_xsd.wsdl",array("trace"=>1,"exceptions"=>0));
-$client->echoComplexTypeMultiOccurs(array("inputComplexTypeMultiOccurs"=>array($struct,$struct,$struct)));
+$client->echoComplexTypeMultiOccurs(array("inputComplexTypeMultiOccurs"=>array($struct1,$struct2,$struct3)));
echo $client->__getlastrequest();
$HTTP_RAW_POST_DATA = $client->__getlastrequest();
include("round4_groupI_xsd.inc");
diff --git a/ext/soap/tests/interop/Round4/GroupI/r4_groupI_xsd_015w.phpt b/ext/soap/tests/interop/Round4/GroupI/r4_groupI_xsd_015w.phpt index e0c705238..ac7de377b 100644 --- a/ext/soap/tests/interop/Round4/GroupI/r4_groupI_xsd_015w.phpt +++ b/ext/soap/tests/interop/Round4/GroupI/r4_groupI_xsd_015w.phpt @@ -11,9 +11,10 @@ class SOAPComplexType { $this->varFloat = $f;
}
}
-$struct = new SOAPComplexType('arg',34,325.325);
+$struct1 = new SOAPComplexType('arg',34,325.325);
+$struct2 = new SOAPComplexType('arg',34,325.325);
$client = new SoapClient(dirname(__FILE__)."/round4_groupI_xsd.wsdl",array("trace"=>1,"exceptions"=>0));
-$client->echoComplexTypeMultiOccurs(array("inputComplexTypeMultiOccurs"=>array($struct,null,$struct)));
+$client->echoComplexTypeMultiOccurs(array("inputComplexTypeMultiOccurs"=>array($struct1,null,$struct2)));
echo $client->__getlastrequest();
$HTTP_RAW_POST_DATA = $client->__getlastrequest();
include("round4_groupI_xsd.inc");
diff --git a/ext/soap/tests/schema/schema081.phpt b/ext/soap/tests/schema/schema081.phpt new file mode 100644 index 000000000..337f08126 --- /dev/null +++ b/ext/soap/tests/schema/schema081.phpt @@ -0,0 +1,29 @@ +--TEST-- +SOAP XML Schema 81: SOAP 1.1 Array with SOAP_USE_XSI_ARRAY_TYPE +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +include "test_schema.inc"; +$schema = <<<EOF + <complexType name="testType"> + <complexContent> + <restriction base="SOAP-ENC:Array"> + <attribute ref="SOAP-ENC:arrayType" wsdl:arrayType="int[]"/> + </restriction> + </complexContent> + </complexType> +EOF; +test_schema($schema,'type="tns:testType"',array(123,123.5),"rpc","encoded",'',SOAP_USE_XSI_ARRAY_TYPE); +echo "ok"; +?> +--EXPECT-- +<?xml version="1.0" encoding="UTF-8"?> +<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://test-uri/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:test><testParam SOAP-ENC:arrayType="xsd:int[2]" xsi:type="SOAP-ENC:Array"><item xsi:type="xsd:int">123</item><item xsi:type="xsd:int">123</item></testParam></ns1:test></SOAP-ENV:Body></SOAP-ENV:Envelope> +array(2) { + [0]=> + int(123) + [1]=> + int(123) +} +ok diff --git a/ext/soap/tests/schema/schema082.phpt b/ext/soap/tests/schema/schema082.phpt new file mode 100755 index 000000000..34c4c76c2 --- /dev/null +++ b/ext/soap/tests/schema/schema082.phpt @@ -0,0 +1,31 @@ +--TEST-- +SOAP XML Schema 82: SOAP 1.1 Array with SOAP_USE_XSI_ARRAY_TYPE (second way) +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +include "test_schema.inc"; +$schema = <<<EOF + <complexType name="testType"> + <complexContent> + <restriction base="SOAP-ENC:Array"> + <all> + <element name="x_item" type="int" maxOccurs="unbounded"/> + </all> + </restriction> + </complexContent> + </complexType> +EOF; +test_schema($schema,'type="tns:testType"',array(123,123.5),"rpc","encoded",'',SOAP_USE_XSI_ARRAY_TYPE); +echo "ok"; +?> +--EXPECT-- +<?xml version="1.0" encoding="UTF-8"?> +<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://test-uri/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:test><testParam SOAP-ENC:arrayType="xsd:int[2]" xsi:type="SOAP-ENC:Array"><x_item xsi:type="xsd:int">123</x_item><x_item xsi:type="xsd:int">123</x_item></testParam></ns1:test></SOAP-ENV:Body></SOAP-ENV:Envelope> +array(2) { + [0]=> + int(123) + [1]=> + int(123) +} +ok diff --git a/ext/soap/tests/schema/schema083.phpt b/ext/soap/tests/schema/schema083.phpt new file mode 100755 index 000000000..854c4f9ff --- /dev/null +++ b/ext/soap/tests/schema/schema083.phpt @@ -0,0 +1,30 @@ +--TEST-- +SOAP XML Schema 83: SOAP 1.2 Array with SOAP_USE_XSI_ARRAY_TYPE +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +include "test_schema.inc"; +$schema = <<<EOF + <complexType name="testType"> + <complexContent> + <restriction base="enc12:Array" xmlns:enc12="http://www.w3.org/2003/05/soap-encoding"> + <attribute ref="enc12:itemType" wsdl:itemType="int"/> + <attribute ref="enc12:arraySize" wsdl:arraySize="*"/> + </restriction> + </complexContent> + </complexType> +EOF; +test_schema($schema,'type="tns:testType"',array(123,123.5),"rpc","encoded",'',SOAP_USE_XSI_ARRAY_TYPE); +echo "ok"; +?> +--EXPECT-- +<?xml version="1.0" encoding="UTF-8"?> +<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://test-uri/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:test><testParam SOAP-ENC:arrayType="xsd:int[2]" xsi:type="SOAP-ENC:Array"><item xsi:type="xsd:int">123</item><item xsi:type="xsd:int">123</item></testParam></ns1:test></SOAP-ENV:Body></SOAP-ENV:Envelope> +array(2) { + [0]=> + int(123) + [1]=> + int(123) +} +ok diff --git a/ext/soap/tests/schema/schema084.phpt b/ext/soap/tests/schema/schema084.phpt new file mode 100755 index 000000000..94a9551fa --- /dev/null +++ b/ext/soap/tests/schema/schema084.phpt @@ -0,0 +1,31 @@ +--TEST-- +SOAP XML Schema 84: SOAP 1.2 Array with SOAP_USE_XSI_ARRAY_TYPE (second way) +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +include "test_schema.inc"; +$schema = <<<EOF + <complexType name="testType"> + <complexContent> + <restriction base="enc12:Array" xmlns:enc12="http://www.w3.org/2003/05/soap-encoding"> + <all> + <element name="x_item" type="int" maxOccurs="unbounded"/> + </all> + </restriction> + </complexContent> + </complexType> +EOF; +test_schema($schema,'type="tns:testType"',array(123,123.5),"rpc","encoded",'',SOAP_USE_XSI_ARRAY_TYPE); +echo "ok"; +?> +--EXPECT-- +<?xml version="1.0" encoding="UTF-8"?> +<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://test-uri/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:test><testParam SOAP-ENC:arrayType="xsd:int[2]" xsi:type="SOAP-ENC:Array"><x_item xsi:type="xsd:int">123</x_item><x_item xsi:type="xsd:int">123</x_item></testParam></ns1:test></SOAP-ENV:Body></SOAP-ENV:Envelope> +array(2) { + [0]=> + int(123) + [1]=> + int(123) +} +ok diff --git a/ext/soap/tests/schema/schema085.phpt b/ext/soap/tests/schema/schema085.phpt new file mode 100755 index 000000000..9a93ac723 --- /dev/null +++ b/ext/soap/tests/schema/schema085.phpt @@ -0,0 +1,45 @@ +--TEST-- +SOAP XML Schema 85: Extension of complex type (elements order) +--SKIPIF-- +<?php require_once('skipif.inc'); ?> +--FILE-- +<?php +include "test_schema.inc"; +$schema = <<<EOF + <complexType name="testType2"> + <sequence> + <element name="int" type="int"/> + </sequence> + </complexType> + <complexType name="testType"> + <complexContent> + <extension base="tns:testType2"> + <sequence> + <element name="int2" type="int"/> + </sequence> + </extension> + </complexContent> + </complexType> +EOF; +class A { + public $int = 1; +} + +class B extends A { + public $int2 = 2; +} + + +test_schema($schema,'type="tns:testType"',new B()); +echo "ok"; +?> +--EXPECT-- +<?xml version="1.0" encoding="UTF-8"?> +<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://test-uri/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:test><testParam xsi:type="ns1:testType"><int xsi:type="xsd:int">1</int><int2 xsi:type="xsd:int">2</int2></testParam></ns1:test></SOAP-ENV:Body></SOAP-ENV:Envelope> +object(stdClass)#5 (2) { + ["int"]=> + int(1) + ["int2"]=> + int(2) +} +ok diff --git a/ext/soap/tests/schema/test_schema.inc b/ext/soap/tests/schema/test_schema.inc index 23b6c8b8b..06e139b40 100644 --- a/ext/soap/tests/schema/test_schema.inc +++ b/ext/soap/tests/schema/test_schema.inc @@ -6,7 +6,7 @@ function test($input) { $val = $input;
}
-function test_schema($schema,$type,$param,$style="rpc",$use="encoded", $attributeFormDefault='') {
+function test_schema($schema,$type,$param,$style="rpc",$use="encoded", $attributeFormDefault='',$features=0) {
global $HTTP_RAW_POST_DATA, $val;
$wsdl = <<<EOF
<definitions name="InteropTest"
@@ -55,8 +55,8 @@ EOF; fwrite($f,$wsdl);
fclose($f);
ini_set("soap.wsdl_cache_enabled",0);
- $x = new SoapClient($fname, array("trace"=>1,"exceptions"=>0));
- $y = new SoapServer($fname);
+ $x = new SoapClient($fname, array("trace"=>1,"exceptions"=>0,"features"=>$features));
+ $y = new SoapServer($fname, array("features"=>$features));
$y->addfunction("test");
unlink($fname);
|
