From fdebad0b25bade683dc8e3e04128c876b86a877a Mon Sep 17 00:00:00 2001 From: Dmitrii Derepko Date: Thu, 29 May 2025 17:47:47 +0400 Subject: [PATCH 1/8] zend_ast: Add parentheses around IIFE in zend_ast_export() (#18688) --- NEWS | 1 + Zend/tests/arrow_functions/007.phpt | 6 ++---- Zend/tests/enum/ast-dumper.phpt | 4 ++-- Zend/tests/functions/007.phpt | 18 ++++++++++++++++++ Zend/tests/match/009_ast_export.phpt | 4 ++-- Zend/zend_ast.c | 12 ++++++++++-- 6 files changed, 35 insertions(+), 10 deletions(-) create mode 100644 Zend/tests/functions/007.phpt diff --git a/NEWS b/NEWS index 557fe0aea7f25..c0f20b747da2d 100644 --- a/NEWS +++ b/NEWS @@ -52,6 +52,7 @@ PHP NEWS . Fixed bugs GH-17711 and GH-18022 (Infinite recursion on deprecated attribute evaluation) and GH-18464 (Recursion protection for deprecation constants not released on bailout). (DanielEScherzer and ilutov) + . Fixed AST printing for immediately invoked Closure. (Dmitrii Derepko) - Curl: . Added curl_multi_get_handles(). (timwolla) diff --git a/Zend/tests/arrow_functions/007.phpt b/Zend/tests/arrow_functions/007.phpt index ec1e165fd680d..66b03b84c2e93 100644 --- a/Zend/tests/arrow_functions/007.phpt +++ b/Zend/tests/arrow_functions/007.phpt @@ -5,8 +5,6 @@ zend.assertions=1 --FILE-- false)()); } catch (AssertionError $e) { @@ -21,5 +19,5 @@ try { ?> --EXPECT-- -assert(): assert(fn() => false()) failed -assert(): assert(fn&(int ...$args): ?bool => $args[0](false)) failed +assert(): assert((fn() => false)()) failed +assert(): assert((fn&(int ...$args): ?bool => $args[0])(false)) failed diff --git a/Zend/tests/enum/ast-dumper.phpt b/Zend/tests/enum/ast-dumper.phpt index ed38e44e7c2f2..7972fe64965e2 100644 --- a/Zend/tests/enum/ast-dumper.phpt +++ b/Zend/tests/enum/ast-dumper.phpt @@ -28,7 +28,7 @@ try { ?> --EXPECT-- -assert(function () { +assert((function () { enum Foo { case Bar; } @@ -45,4 +45,4 @@ assert(function () { } return false; -}()) +})()) diff --git a/Zend/tests/functions/007.phpt b/Zend/tests/functions/007.phpt new file mode 100644 index 0000000000000..0d741546dc63b --- /dev/null +++ b/Zend/tests/functions/007.phpt @@ -0,0 +1,18 @@ +--TEST-- +Pretty printing for arrow functions +--INI-- +zend.assertions=1 +--FILE-- +getMessage(), ' failed', PHP_EOL; +} + +?> +--EXPECT-- +assert(): assert((function () { + return false; +})()) failed diff --git a/Zend/tests/match/009_ast_export.phpt b/Zend/tests/match/009_ast_export.phpt index 8dc89d4fe0672..9d95b722b2229 100644 --- a/Zend/tests/match/009_ast_export.phpt +++ b/Zend/tests/match/009_ast_export.phpt @@ -19,10 +19,10 @@ assert((function () { ?> --EXPECTF-- -assert(): assert(function () { +assert(): assert((function () { match ('foo') { 'foo', 'bar' => false, 'baz' => 'a', default => 'b', }; -}()) failed +})()) failed diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index 8bdd29c5512cc..5104aad3510e0 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -2424,12 +2424,20 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio smart_str_appends(str, "::$"); zend_ast_export_var(str, ast->child[1], 0, indent); break; - case ZEND_AST_CALL: - zend_ast_export_ns_name(str, ast->child[0], 0, indent); + case ZEND_AST_CALL: { + zend_ast *left = ast->child[0]; + if (left->kind == ZEND_AST_ARROW_FUNC || left->kind == ZEND_AST_CLOSURE) { + smart_str_appends(str, "("); + zend_ast_export_ns_name(str, left, 0, indent); + smart_str_appends(str, ")"); + } else { + zend_ast_export_ns_name(str, left, 0, indent); + } smart_str_appendc(str, '('); zend_ast_export_ex(str, ast->child[1], 0, indent); smart_str_appendc(str, ')'); break; + } case ZEND_AST_PARENT_PROPERTY_HOOK_CALL: smart_str_append(str, Z_STR_P(zend_ast_get_zval(ast->child[0]))); smart_str_appendc(str, '('); From 407c9781f9357dfbd7cd0ce56554c2fb2d30af30 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Thu, 29 May 2025 15:07:35 +0100 Subject: [PATCH 2/8] ext/soap: Replace single usage of CHECK_XML_NULL with FIND_XML_NULL (#18698) This removes the implicit assumption about the variable name of the zval Moreover, nearby the FIND_XML_NULL macro is used anyway. --- ext/soap/php_encoding.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index 67543259994f3..ac9713afb3f45 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -112,22 +112,6 @@ static void set_ns_and_type(xmlNodePtr node, encodeTypePtr type); } \ } -#define CHECK_XML_NULL(xml) \ - { \ - xmlAttrPtr null; \ - if (!xml) { \ - ZVAL_NULL(ret); \ - return ret; \ - } \ - if (xml->properties) { \ - null = get_attribute(xml->properties, "nil"); \ - if (null) { \ - ZVAL_NULL(ret); \ - return ret; \ - } \ - } \ - } - #define FIND_ZVAL_NULL(zval, xml, style) \ { \ if (!zval || Z_TYPE_P(zval) == IS_NULL) { \ @@ -1480,7 +1464,7 @@ static zval *to_zval_object_ex(zval *ret, encodeTypePtr type, xmlNodePtr data, z sdlType->encode->details.sdl_type->kind != XSD_TYPEKIND_LIST && sdlType->encode->details.sdl_type->kind != XSD_TYPEKIND_UNION) { - CHECK_XML_NULL(data); + FIND_XML_NULL(data, ret); if (soap_check_xml_ref(ret, data)) { return ret; } From c9e571560f7f2682d7263e695387bc166d14038d Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Thu, 29 May 2025 15:29:55 +0100 Subject: [PATCH 3/8] ext/soap: Refactor to_zval_bool() (#18696) - Early return style - Improve logic to get rid of unnecessary comparisons - Do not use convert_to_boolean API --- ext/soap/php_encoding.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index ac9713afb3f45..bc8e42ef0dfdd 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -1118,29 +1118,27 @@ static xmlNodePtr to_xml_double(encodeTypePtr type, zval *data, int style, xmlNo static zval *to_zval_bool(zval *ret, encodeTypePtr type, xmlNodePtr data) { - ZVAL_NULL(ret); FIND_XML_NULL(data, ret); - if (data && data->children) { - if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) { - whiteSpace_collapse(data->children->content); - if (stricmp((char*)data->children->content, "true") == 0 || - stricmp((char*)data->children->content, "t") == 0 || - strcmp((char*)data->children->content, "1") == 0) { - ZVAL_TRUE(ret); - } else if (stricmp((char*)data->children->content, "false") == 0 || - stricmp((char*)data->children->content, "f") == 0 || - strcmp((char*)data->children->content, "0") == 0) { - ZVAL_FALSE(ret); - } else { - ZVAL_STRING(ret, (char*)data->children->content); - convert_to_boolean(ret); - } - } else { - soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); - } - } else { + if (!data->children) { ZVAL_NULL(ret); + return ret; + } + if (data->children->type != XML_TEXT_NODE || data->children->next != NULL) { + // TODO Convert to exception? + soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); + } + + whiteSpace_collapse(data->children->content); + if ( + data->children->content[0] == '\0' /* Check for empty string */ + || strcmp((const char*)data->children->content, "0") == 0 + || stricmp((const char*)data->children->content, "f") == 0 + || stricmp((const char*)data->children->content, "false") == 0 + ) { + ZVAL_FALSE(ret); + } else { + ZVAL_TRUE(ret); } return ret; } From 40422e9c55c83e5a453416fe1ae1a1e0c880a6dc Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Thu, 29 May 2025 15:41:22 +0100 Subject: [PATCH 4/8] ext/pgsql: Fix warning not being emittedd when failure to cancel a query --- NEWS | 4 ++++ ext/pgsql/pgsql.c | 8 +++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 87c038ebc7ea0..466ba5d89653e 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,10 @@ PHP NEWS . Add missing filter cleanups on phar failure. (nielsdos) . Fixed bug GH-18642 (Signed integer overflow in ext/phar fseek). (nielsdos) +- PGSQL: + . Fix warning not being emitted when failure to cancel a query with + pg_cancel_query(). (Girgias) + - Readline: . Fix memory leak when calloc() fails in php_readline_completion_cb(). (nielsdos) diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index e955eed0928c8..63acd26ea01f5 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -3576,8 +3576,14 @@ static void php_pgsql_do_async(INTERNAL_FUNCTION_PARAMETERS, int entry_type) int rc; c = PQgetCancel(pgsql); + /* PQcancel + * The return value of PQcancel is 1 if the cancel request was successfully dispatched and 0 if not. + * If not, errbuf is filled with an explanatory error message. + * errbuf must be a char array of size errbufsize (the recommended size is 256 bytes). + * https://www.postgresql.org/docs/current/libpq-cancel.html#LIBPQ-PQCANCEL + */ RETVAL_LONG((rc = PQcancel(c, err, sizeof(err)))); - if (rc < 0) { + if (rc == 0) { zend_error(E_WARNING, "cannot cancel the query: %s", err); } while ((pgsql_result = PQgetResult(pgsql))) { From 6399012ceec631c64b55e96ad82fe7cfb43615d0 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 29 May 2025 15:42:02 +0200 Subject: [PATCH 5/8] Fix namespace handling of WSDL and XML schema in SOAP `attr_is_equal_ex` makes no sense: attributes never inherit the namespace of their element. Yet this is wrongly used as a combo for checking both the node namespace and attribute namespace. Furthermore, not all nodes have the proper namespace check. Fix all of this by reworking the helpers and auditing the calls to the namespace helpers. Closes GH-16320. Closes bug #68576. Closes GH-18697. --- NEWS | 2 + ext/soap/php_encoding.c | 59 ++++---- ext/soap/php_encoding.h | 2 +- ext/soap/php_schema.c | 243 ++++++++++++++++-------------- ext/soap/php_xml.c | 55 ++++--- ext/soap/php_xml.h | 5 +- ext/soap/tests/bugs/bug27722.wsdl | 10 +- ext/soap/tests/bugs/bug27742.wsdl | 4 +- ext/soap/tests/bugs/bug29839.wsdl | 8 +- ext/soap/tests/bugs/bug34453.wsdl | 4 +- ext/soap/tests/bugs/bug62900.phpt | 4 +- ext/soap/tests/bugs/bug68576.phpt | 17 +++ ext/soap/tests/bugs/bug68576.wsdl | 20 +++ 13 files changed, 256 insertions(+), 177 deletions(-) create mode 100644 ext/soap/tests/bugs/bug68576.phpt create mode 100644 ext/soap/tests/bugs/bug68576.wsdl diff --git a/NEWS b/NEWS index c0f20b747da2d..6dffb0cc847a0 100644 --- a/NEWS +++ b/NEWS @@ -184,6 +184,8 @@ PHP NEWS - SOAP: . Fixed bug #49169 (SoapServer calls wrong function, although "SOAP action" header is correct). (nielsdos) + . Fix namespace handling of WSDL and XML schema in SOAP, + fixing at least GH-16320 and bug #68576. (nielsdos) - Sockets: . Added IPPROTO_ICMP/IPPROTO_ICMPV6 to create raw socket for ICMP usage. diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index bc8e42ef0dfdd..c4fa7702cf446 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -104,7 +104,7 @@ static void set_ns_and_type(xmlNodePtr node, encodeTypePtr type); return zval; \ } \ if (xml->properties) { \ - null = get_attribute(xml->properties, "nil"); \ + null = get_attribute_ex(xml->properties, "nil", XSI_NAMESPACE); \ if (null) { \ ZVAL_NULL(zval); \ return zval; \ @@ -287,13 +287,7 @@ static bool soap_check_zval_ref(zval *data, xmlNodePtr node) { return 0; } 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; - } + attr = get_attribute(attr, "id"); if (attr) { id = (char*)attr->children->content; smart_str_appendc(&prefix, '#'); @@ -1530,7 +1524,7 @@ static zval *to_zval_object_ex(zval *ret, encodeTypePtr type, xmlNodePtr data, z ZEND_HASH_FOREACH_PTR(sdlType->attributes, attr) { if (attr->name) { - xmlAttrPtr val = get_attribute(data->properties, attr->name); + xmlAttrPtr val = get_attribute_any_ns(data->properties, attr->name); char *str_val = NULL; if (val && val->children && val->children->content) { @@ -2485,6 +2479,26 @@ static xmlNodePtr to_xml_array(encodeTypePtr type, zval *data, int style, xmlNod return xmlParam; } +static xmlAttrPtr get_soap_1_1_enc_attribute(xmlAttrPtr props, const char *name) +{ + return get_attribute_ex(props, name, SOAP_1_1_ENC_NAMESPACE); +} + +static xmlAttrPtr get_soap_1_2_enc_attribute(xmlAttrPtr props, const char *name) +{ + return get_attribute_ex(props, name, SOAP_1_2_ENC_NAMESPACE); +} + +/* Be forgiving for BC */ +static xmlAttrPtr get_soap_enc_attribute(xmlAttrPtr props, const char *name) +{ + xmlAttrPtr res = get_soap_1_1_enc_attribute(props, name); + if (!res) { + res = get_soap_1_2_enc_attribute(props, name); + } + return res; +} + static zval *to_zval_array(zval *ret, encodeTypePtr type, xmlNodePtr data) { xmlNodePtr trav; @@ -2501,7 +2515,7 @@ static zval *to_zval_array(zval *ret, encodeTypePtr type, xmlNodePtr data) FIND_XML_NULL(data, ret); if (data && - (attr = get_attribute(data->properties,"arrayType")) && + (attr = get_soap_enc_attribute(data->properties,"arrayType")) && attr->children && attr->children->content) { const char *type; char *end, *ns; @@ -2521,7 +2535,7 @@ static zval *to_zval_array(zval *ret, encodeTypePtr type, xmlNodePtr data) } if (ns) {efree(ns);} - } else if ((attr = get_attribute(data->properties,"itemType")) && + } else if ((attr = get_soap_enc_attribute(data->properties,"itemType")) && attr->children && attr->children->content) { const char *type; @@ -2535,7 +2549,7 @@ static zval *to_zval_array(zval *ret, encodeTypePtr type, xmlNodePtr data) } if (ns) {efree(ns);} - if ((attr = get_attribute(data->properties,"arraySize")) && + if ((attr = get_soap_enc_attribute(data->properties,"arraySize")) && attr->children && attr->children->content) { dimension = calc_dimension_12((char*)attr->children->content); dims = get_position_12(dimension, (char*)attr->children->content); @@ -2544,7 +2558,7 @@ static zval *to_zval_array(zval *ret, encodeTypePtr type, xmlNodePtr data) *dims = 0; } - } else if ((attr = get_attribute(data->properties,"arraySize")) && + } else if ((attr = get_soap_enc_attribute(data->properties,"arraySize")) && attr->children && attr->children->content) { dimension = calc_dimension_12((char*)attr->children->content); @@ -2623,7 +2637,7 @@ static zval *to_zval_array(zval *ret, encodeTypePtr type, xmlNodePtr data) pos = safe_emalloc(sizeof(int), dimension, 0); memset(pos,0,sizeof(int)*dimension); if (data && - (attr = get_attribute(data->properties,"offset")) && + (attr = get_soap_enc_attribute(data->properties,"offset")) && attr->children && attr->children->content) { char* tmp = strrchr((char*)attr->children->content,'['); @@ -2639,7 +2653,7 @@ static zval *to_zval_array(zval *ret, encodeTypePtr type, xmlNodePtr data) if (trav->type == XML_ELEMENT_NODE) { int i; zval tmpVal, *ar; - xmlAttrPtr position = get_attribute(trav->properties,"position"); + xmlAttrPtr position = get_soap_enc_attribute(trav->properties,"position"); ZVAL_NULL(&tmpVal); master_to_zval(&tmpVal, enc, trav); @@ -2854,9 +2868,9 @@ static zval *guess_zval_convert(zval *ret, encodeTypePtr type, xmlNodePtr data) /* Logic: has children = IS_OBJECT else IS_STRING */ xmlNodePtr trav; - if (get_attribute(data->properties, "arrayType") || - get_attribute(data->properties, "itemType") || - get_attribute(data->properties, "arraySize")) { + if (get_soap_enc_attribute(data->properties, "arrayType") || + get_soap_enc_attribute(data->properties, "itemType") || + get_soap_enc_attribute(data->properties, "arraySize")) { enc = get_conversion(SOAP_ENC_ARRAY); } else { enc = get_conversion(XSD_STRING); @@ -3340,14 +3354,7 @@ xmlNodePtr sdl_guess_convert_xml(encodeTypePtr enc, zval *data, int style, xmlNo static xmlNodePtr check_and_resolve_href(xmlNodePtr data) { if (data && data->properties) { - xmlAttrPtr href; - - href = data->properties; - while (1) { - href = get_attribute(href, "href"); - if (href == NULL || href->ns == NULL) {break;} - href = href->next; - } + xmlAttrPtr href = get_attribute(data->properties, "href"); if (href) { /* Internal href try and find node */ if (href->children->content[0] == '#') { diff --git a/ext/soap/php_encoding.h b/ext/soap/php_encoding.h index 67023a81d829e..ef05c9ebe7878 100644 --- a/ext/soap/php_encoding.h +++ b/ext/soap/php_encoding.h @@ -35,7 +35,7 @@ #define SOAP_1_2_ENC_NAMESPACE "http://www.w3.org/2003/05/soap-encoding" #define SOAP_1_2_ENC_NS_PREFIX "enc" -#define SCHEMA_NAMESPACE "http://www.w3.org/2001/XMLSchema" +#define XSD_DRAFT_2000_NAMESPACE "http://www.w3.org/2000/10/XMLSchema" #define XSD_NAMESPACE "http://www.w3.org/2001/XMLSchema" #define XSD_NS_PREFIX "xsd" #define XSI_NAMESPACE "http://www.w3.org/2001/XMLSchema-instance" diff --git a/ext/soap/php_schema.c b/ext/soap/php_schema.c index ac4fb60cb2c0c..f1af0110bab57 100644 --- a/ext/soap/php_schema.c +++ b/ext/soap/php_schema.c @@ -43,6 +43,17 @@ static int schema_restriction_var_char(xmlNodePtr val, sdlRestrictionCharPtr *va static void schema_type_fixup(sdlCtx *ctx, sdlTypePtr type); +static bool node_is_equal_xsd(xmlNodePtr node, const char *name) +{ + static const char *ns[] = { + XSD_NAMESPACE, + XSD_DRAFT_2000_NAMESPACE, + NULL + }; + + return node_is_equal_ex_one_of(node, name, ns); +} + static encodePtr create_encoder(sdlPtr sdl, sdlTypePtr cur_type, const xmlChar *ns, const xmlChar *type) { smart_str nscat = {0}; @@ -226,7 +237,7 @@ int load_schema(sdlCtx *ctx, xmlNodePtr schema) trav = schema->children; while (trav != NULL) { - if (node_is_equal(trav,"include")) { + if (node_is_equal_xsd(trav,"include")) { xmlAttrPtr location; location = get_attribute(trav->properties, "schemaLocation"); @@ -238,7 +249,7 @@ int load_schema(sdlCtx *ctx, xmlNodePtr schema) xmlFree(uri); } - } else if (node_is_equal(trav,"redefine")) { + } else if (node_is_equal_xsd(trav,"redefine")) { xmlAttrPtr location; location = get_attribute(trav->properties, "schemaLocation"); @@ -251,7 +262,7 @@ int load_schema(sdlCtx *ctx, xmlNodePtr schema) /* TODO: support */ } - } else if (node_is_equal(trav,"import")) { + } else if (node_is_equal_xsd(trav,"import")) { xmlAttrPtr ns, location; xmlChar *uri = NULL; @@ -270,7 +281,7 @@ int load_schema(sdlCtx *ctx, xmlNodePtr schema) } schema_load_file(ctx, ns, uri, tns, 1); if (uri != NULL) {xmlFree(uri);} - } else if (node_is_equal(trav,"annotation")) { + } else if (node_is_equal_xsd(trav,"annotation")) { /* TODO: support */ /* annotation cleanup xmlNodePtr tmp = trav; @@ -286,21 +297,21 @@ int load_schema(sdlCtx *ctx, xmlNodePtr schema) } while (trav != NULL) { - if (node_is_equal(trav,"simpleType")) { + if (node_is_equal_xsd(trav,"simpleType")) { schema_simpleType(ctx->sdl, tns, trav, NULL); - } else if (node_is_equal(trav,"complexType")) { + } else if (node_is_equal_xsd(trav,"complexType")) { schema_complexType(ctx->sdl, tns, trav, NULL); - } else if (node_is_equal(trav,"group")) { + } else if (node_is_equal_xsd(trav,"group")) { schema_group(ctx->sdl, tns, trav, NULL, NULL); - } else if (node_is_equal(trav,"attributeGroup")) { + } else if (node_is_equal_xsd(trav,"attributeGroup")) { schema_attributeGroup(ctx->sdl, tns, trav, NULL, ctx); - } else if (node_is_equal(trav,"element")) { + } else if (node_is_equal_xsd(trav,"element")) { schema_element(ctx->sdl, tns, trav, NULL, NULL); - } else if (node_is_equal(trav,"attribute")) { + } else if (node_is_equal_xsd(trav,"attribute")) { schema_attribute(ctx->sdl, tns, trav, NULL, ctx); - } else if (node_is_equal(trav,"notation")) { + } else if (node_is_equal_xsd(trav,"notation")) { /* TODO: support */ - } else if (node_is_equal(trav,"annotation")) { + } else if (node_is_equal_xsd(trav,"annotation")) { /* TODO: support */ } else { soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in schema", trav->name); @@ -391,19 +402,19 @@ static int schema_simpleType(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr simpleType, } trav = simpleType->children; - if (trav != NULL && node_is_equal(trav,"annotation")) { + if (trav != NULL && node_is_equal_xsd(trav,"annotation")) { /* TODO: support */ trav = trav->next; } if (trav != NULL) { - if (node_is_equal(trav,"restriction")) { + if (node_is_equal_xsd(trav,"restriction")) { schema_restriction_simpleContent(sdl, tns, trav, cur_type, 1); trav = trav->next; - } else if (node_is_equal(trav,"list")) { + } else if (node_is_equal_xsd(trav,"list")) { cur_type->kind = XSD_TYPEKIND_LIST; schema_list(sdl, tns, trav, cur_type); trav = trav->next; - } else if (node_is_equal(trav,"union")) { + } else if (node_is_equal_xsd(trav,"union")) { cur_type->kind = XSD_TYPEKIND_UNION; schema_union(sdl, tns, trav, cur_type); trav = trav->next; @@ -462,11 +473,11 @@ static int schema_list(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr listType, sdlTypeP } trav = listType->children; - if (trav != NULL && node_is_equal(trav,"annotation")) { + if (trav != NULL && node_is_equal_xsd(trav,"annotation")) { /* TODO: support */ trav = trav->next; } - if (trav != NULL && node_is_equal(trav,"simpleType")) { + if (trav != NULL && node_is_equal_xsd(trav,"simpleType")) { sdlTypePtr newType; if (itemType != NULL) { @@ -562,12 +573,12 @@ static int schema_union(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr unionType, sdlTyp } trav = unionType->children; - if (trav != NULL && node_is_equal(trav,"annotation")) { + if (trav != NULL && node_is_equal_xsd(trav,"annotation")) { /* TODO: support */ trav = trav->next; } while (trav != NULL) { - if (node_is_equal(trav,"simpleType")) { + if (node_is_equal_xsd(trav,"simpleType")) { sdlTypePtr newType; newType = emalloc(sizeof(sdlType)); @@ -615,16 +626,16 @@ static int schema_simpleContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr simpCompT xmlNodePtr trav; trav = simpCompType->children; - if (trav != NULL && node_is_equal(trav,"annotation")) { + if (trav != NULL && node_is_equal_xsd(trav,"annotation")) { /* TODO: support */ trav = trav->next; } if (trav != NULL) { - if (node_is_equal(trav, "restriction")) { + if (node_is_equal_xsd(trav, "restriction")) { cur_type->kind = XSD_TYPEKIND_RESTRICTION; schema_restriction_simpleContent(sdl, tns, trav, cur_type, 0); trav = trav->next; - } else if (node_is_equal(trav, "extension")) { + } else if (node_is_equal_xsd(trav, "extension")) { cur_type->kind = XSD_TYPEKIND_EXTENSION; schema_extension_simpleContent(sdl, tns, trav, cur_type); trav = trav->next; @@ -682,38 +693,38 @@ static int schema_restriction_simpleContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodeP } trav = restType->children; - if (trav != NULL && node_is_equal(trav, "annotation")) { + if (trav != NULL && node_is_equal_xsd(trav, "annotation")) { /* TODO: support */ trav = trav->next; } - if (trav != NULL && node_is_equal(trav, "simpleType")) { + if (trav != NULL && node_is_equal_xsd(trav, "simpleType")) { schema_simpleType(sdl, tns, trav, cur_type); trav = trav->next; } while (trav != NULL) { - if (node_is_equal(trav, "minExclusive")) { + if (node_is_equal_xsd(trav, "minExclusive")) { schema_restriction_var_int(trav, &cur_type->restrictions->minExclusive); - } else if (node_is_equal(trav, "minInclusive")) { + } else if (node_is_equal_xsd(trav, "minInclusive")) { schema_restriction_var_int(trav, &cur_type->restrictions->minInclusive); - } else if (node_is_equal(trav, "maxExclusive")) { + } else if (node_is_equal_xsd(trav, "maxExclusive")) { schema_restriction_var_int(trav, &cur_type->restrictions->maxExclusive); - } else if (node_is_equal(trav, "maxInclusive")) { + } else if (node_is_equal_xsd(trav, "maxInclusive")) { schema_restriction_var_int(trav, &cur_type->restrictions->maxInclusive); - } else if (node_is_equal(trav, "totalDigits")) { + } else if (node_is_equal_xsd(trav, "totalDigits")) { schema_restriction_var_int(trav, &cur_type->restrictions->totalDigits); - } else if (node_is_equal(trav, "fractionDigits")) { + } else if (node_is_equal_xsd(trav, "fractionDigits")) { schema_restriction_var_int(trav, &cur_type->restrictions->fractionDigits); - } else if (node_is_equal(trav, "length")) { + } else if (node_is_equal_xsd(trav, "length")) { schema_restriction_var_int(trav, &cur_type->restrictions->length); - } else if (node_is_equal(trav, "minLength")) { + } else if (node_is_equal_xsd(trav, "minLength")) { schema_restriction_var_int(trav, &cur_type->restrictions->minLength); - } else if (node_is_equal(trav, "maxLength")) { + } else if (node_is_equal_xsd(trav, "maxLength")) { schema_restriction_var_int(trav, &cur_type->restrictions->maxLength); - } else if (node_is_equal(trav, "whiteSpace")) { + } else if (node_is_equal_xsd(trav, "whiteSpace")) { schema_restriction_var_char(trav, &cur_type->restrictions->whiteSpace); - } else if (node_is_equal(trav, "pattern")) { + } else if (node_is_equal_xsd(trav, "pattern")) { schema_restriction_var_char(trav, &cur_type->restrictions->pattern); - } else if (node_is_equal(trav, "enumeration")) { + } else if (node_is_equal_xsd(trav, "enumeration")) { sdlRestrictionCharPtr enumval = NULL; schema_restriction_var_char(trav, &enumval); @@ -731,11 +742,11 @@ static int schema_restriction_simpleContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodeP } if (!simpleType) { while (trav != NULL) { - if (node_is_equal(trav,"attribute")) { + if (node_is_equal_xsd(trav,"attribute")) { schema_attribute(sdl, tns, trav, cur_type, NULL); - } else if (node_is_equal(trav,"attributeGroup")) { + } else if (node_is_equal_xsd(trav,"attributeGroup")) { schema_attributeGroup(sdl, tns, trav, cur_type, NULL); - } else if (node_is_equal(trav,"anyAttribute")) { + } else if (node_is_equal_xsd(trav,"anyAttribute")) { /* TODO: support */ trav = trav->next; break; @@ -782,31 +793,31 @@ static int schema_restriction_complexContent(sdlPtr sdl, xmlAttrPtr tns, xmlNode } trav = restType->children; - if (trav != NULL && node_is_equal(trav,"annotation")) { + if (trav != NULL && node_is_equal_xsd(trav,"annotation")) { /* TODO: support */ trav = trav->next; } if (trav != NULL) { - if (node_is_equal(trav,"group")) { + if (node_is_equal_xsd(trav,"group")) { schema_group(sdl, tns, trav, cur_type, NULL); trav = trav->next; - } else if (node_is_equal(trav,"all")) { + } else if (node_is_equal_xsd(trav,"all")) { schema_all(sdl, tns, trav, cur_type, NULL); trav = trav->next; - } else if (node_is_equal(trav,"choice")) { + } else if (node_is_equal_xsd(trav,"choice")) { schema_choice(sdl, tns, trav, cur_type, NULL); trav = trav->next; - } else if (node_is_equal(trav,"sequence")) { + } else if (node_is_equal_xsd(trav,"sequence")) { schema_sequence(sdl, tns, trav, cur_type, NULL); trav = trav->next; } } while (trav != NULL) { - if (node_is_equal(trav,"attribute")) { + if (node_is_equal_xsd(trav,"attribute")) { schema_attribute(sdl, tns, trav, cur_type, NULL); - } else if (node_is_equal(trav,"attributeGroup")) { + } else if (node_is_equal_xsd(trav,"attributeGroup")) { schema_attributeGroup(sdl, tns, trav, cur_type, NULL); - } else if (node_is_equal(trav,"anyAttribute")) { + } else if (node_is_equal_xsd(trav,"anyAttribute")) { /* TODO: support */ trav = trav->next; break; @@ -907,16 +918,16 @@ static int schema_extension_simpleContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr } trav = extType->children; - if (trav != NULL && node_is_equal(trav,"annotation")) { + if (trav != NULL && node_is_equal_xsd(trav,"annotation")) { /* TODO: support */ trav = trav->next; } while (trav != NULL) { - if (node_is_equal(trav,"attribute")) { + if (node_is_equal_xsd(trav,"attribute")) { schema_attribute(sdl, tns, trav, cur_type, NULL); - } else if (node_is_equal(trav,"attributeGroup")) { + } else if (node_is_equal_xsd(trav,"attributeGroup")) { schema_attributeGroup(sdl, tns, trav, cur_type, NULL); - } else if (node_is_equal(trav,"anyAttribute")) { + } else if (node_is_equal_xsd(trav,"anyAttribute")) { /* TODO: support */ trav = trav->next; break; @@ -962,31 +973,31 @@ static int schema_extension_complexContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePt } trav = extType->children; - if (trav != NULL && node_is_equal(trav,"annotation")) { + if (trav != NULL && node_is_equal_xsd(trav,"annotation")) { /* TODO: support */ trav = trav->next; } if (trav != NULL) { - if (node_is_equal(trav,"group")) { + if (node_is_equal_xsd(trav,"group")) { schema_group(sdl, tns, trav, cur_type, NULL); trav = trav->next; - } else if (node_is_equal(trav,"all")) { + } else if (node_is_equal_xsd(trav,"all")) { schema_all(sdl, tns, trav, cur_type, NULL); trav = trav->next; - } else if (node_is_equal(trav,"choice")) { + } else if (node_is_equal_xsd(trav,"choice")) { schema_choice(sdl, tns, trav, cur_type, NULL); trav = trav->next; - } else if (node_is_equal(trav,"sequence")) { + } else if (node_is_equal_xsd(trav,"sequence")) { schema_sequence(sdl, tns, trav, cur_type, NULL); trav = trav->next; } } while (trav != NULL) { - if (node_is_equal(trav,"attribute")) { + if (node_is_equal_xsd(trav,"attribute")) { schema_attribute(sdl, tns, trav, cur_type, NULL); - } else if (node_is_equal(trav,"attributeGroup")) { + } else if (node_is_equal_xsd(trav,"attributeGroup")) { schema_attributeGroup(sdl, tns, trav, cur_type, NULL); - } else if (node_is_equal(trav,"anyAttribute")) { + } else if (node_is_equal_xsd(trav,"anyAttribute")) { /* TODO: support */ trav = trav->next; break; @@ -1050,12 +1061,12 @@ static int schema_all(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr all, sdlTypePtr cur schema_min_max(all, newModel); trav = all->children; - if (trav != NULL && node_is_equal(trav,"annotation")) { + if (trav != NULL && node_is_equal_xsd(trav,"annotation")) { /* TODO: support */ trav = trav->next; } while (trav != NULL) { - if (node_is_equal(trav,"element")) { + if (node_is_equal_xsd(trav,"element")) { schema_element(sdl, tns, trav, cur_type, newModel); } else { soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in all", trav->name); @@ -1164,26 +1175,26 @@ static int schema_group(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr groupType, sdlTyp schema_min_max(groupType, newModel); trav = groupType->children; - if (trav != NULL && node_is_equal(trav,"annotation")) { + if (trav != NULL && node_is_equal_xsd(trav,"annotation")) { /* TODO: support */ trav = trav->next; } if (trav != NULL) { - if (node_is_equal(trav,"choice")) { + if (node_is_equal_xsd(trav,"choice")) { if (ref != NULL) { soap_error0(E_ERROR, "Parsing Schema: group has both 'ref' attribute and subcontent"); } newModel->kind = XSD_CONTENT_CHOICE; schema_choice(sdl, tns, trav, cur_type, newModel); trav = trav->next; - } else if (node_is_equal(trav,"sequence")) { + } else if (node_is_equal_xsd(trav,"sequence")) { if (ref != NULL) { soap_error0(E_ERROR, "Parsing Schema: group has both 'ref' attribute and subcontent"); } newModel->kind = XSD_CONTENT_SEQUENCE; schema_sequence(sdl, tns, trav, cur_type, newModel); trav = trav->next; - } else if (node_is_equal(trav,"all")) { + } else if (node_is_equal_xsd(trav,"all")) { if (ref != NULL) { soap_error0(E_ERROR, "Parsing Schema: group has both 'ref' attribute and subcontent"); } @@ -1226,20 +1237,20 @@ static int schema_choice(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr choiceType, sdlT schema_min_max(choiceType, newModel); trav = choiceType->children; - if (trav != NULL && node_is_equal(trav,"annotation")) { + if (trav != NULL && node_is_equal_xsd(trav,"annotation")) { /* TODO: support */ trav = trav->next; } while (trav != NULL) { - if (node_is_equal(trav,"element")) { + if (node_is_equal_xsd(trav,"element")) { schema_element(sdl, tns, trav, cur_type, newModel); - } else if (node_is_equal(trav,"group")) { + } else if (node_is_equal_xsd(trav,"group")) { schema_group(sdl, tns, trav, cur_type, newModel); - } else if (node_is_equal(trav,"choice")) { + } else if (node_is_equal_xsd(trav,"choice")) { schema_choice(sdl, tns, trav, cur_type, newModel); - } else if (node_is_equal(trav,"sequence")) { + } else if (node_is_equal_xsd(trav,"sequence")) { schema_sequence(sdl, tns, trav, cur_type, newModel); - } else if (node_is_equal(trav,"any")) { + } else if (node_is_equal_xsd(trav,"any")) { schema_any(sdl, tns, trav, cur_type, newModel); } else { soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in choice", trav->name); @@ -1276,20 +1287,20 @@ static int schema_sequence(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr seqType, sdlTy schema_min_max(seqType, newModel); trav = seqType->children; - if (trav != NULL && node_is_equal(trav,"annotation")) { + if (trav != NULL && node_is_equal_xsd(trav,"annotation")) { /* TODO: support */ trav = trav->next; } while (trav != NULL) { - if (node_is_equal(trav,"element")) { + if (node_is_equal_xsd(trav,"element")) { schema_element(sdl, tns, trav, cur_type, newModel); - } else if (node_is_equal(trav,"group")) { + } else if (node_is_equal_xsd(trav,"group")) { schema_group(sdl, tns, trav, cur_type, newModel); - } else if (node_is_equal(trav,"choice")) { + } else if (node_is_equal_xsd(trav,"choice")) { schema_choice(sdl, tns, trav, cur_type, newModel); - } else if (node_is_equal(trav,"sequence")) { + } else if (node_is_equal_xsd(trav,"sequence")) { schema_sequence(sdl, tns, trav, cur_type, newModel); - } else if (node_is_equal(trav,"any")) { + } else if (node_is_equal_xsd(trav,"any")) { schema_any(sdl, tns, trav, cur_type, newModel); } else { soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in sequence", trav->name); @@ -1338,16 +1349,16 @@ static int schema_complexContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr compCont xmlNodePtr trav; trav = compCont->children; - if (trav != NULL && node_is_equal(trav,"annotation")) { + if (trav != NULL && node_is_equal_xsd(trav,"annotation")) { /* TODO: support */ trav = trav->next; } if (trav != NULL) { - if (node_is_equal(trav, "restriction")) { + if (node_is_equal_xsd(trav, "restriction")) { cur_type->kind = XSD_TYPEKIND_RESTRICTION; schema_restriction_complexContent(sdl, tns, trav, cur_type); trav = trav->next; - } else if (node_is_equal(trav, "extension")) { + } else if (node_is_equal_xsd(trav, "extension")) { cur_type->kind = XSD_TYPEKIND_EXTENSION; schema_extension_complexContent(sdl, tns, trav, cur_type); trav = trav->next; @@ -1442,37 +1453,37 @@ static int schema_complexType(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr compType, s } trav = compType->children; - if (trav != NULL && node_is_equal(trav, "annotation")) { + if (trav != NULL && node_is_equal_xsd(trav, "annotation")) { /* TODO: support */ trav = trav->next; } if (trav != NULL) { - if (node_is_equal(trav,"simpleContent")) { + if (node_is_equal_xsd(trav,"simpleContent")) { schema_simpleContent(sdl, tns, trav, cur_type); trav = trav->next; - } else if (node_is_equal(trav,"complexContent")) { + } else if (node_is_equal_xsd(trav,"complexContent")) { schema_complexContent(sdl, tns, trav, cur_type); trav = trav->next; } else { - if (node_is_equal(trav,"group")) { + if (node_is_equal_xsd(trav,"group")) { schema_group(sdl, tns, trav, cur_type, NULL); trav = trav->next; - } else if (node_is_equal(trav,"all")) { + } else if (node_is_equal_xsd(trav,"all")) { schema_all(sdl, tns, trav, cur_type, NULL); trav = trav->next; - } else if (node_is_equal(trav,"choice")) { + } else if (node_is_equal_xsd(trav,"choice")) { schema_choice(sdl, tns, trav, cur_type, NULL); trav = trav->next; - } else if (node_is_equal(trav,"sequence")) { + } else if (node_is_equal_xsd(trav,"sequence")) { schema_sequence(sdl, tns, trav, cur_type, NULL); trav = trav->next; } while (trav != NULL) { - if (node_is_equal(trav,"attribute")) { + if (node_is_equal_xsd(trav,"attribute")) { schema_attribute(sdl, tns, trav, cur_type, NULL); - } else if (node_is_equal(trav,"attributeGroup")) { + } else if (node_is_equal_xsd(trav,"attributeGroup")) { schema_attributeGroup(sdl, tns, trav, cur_type, NULL); - } else if (node_is_equal(trav,"anyAttribute")) { + } else if (node_is_equal_xsd(trav,"anyAttribute")) { /* TODO: support */ trav = trav->next; break; @@ -1659,7 +1670,7 @@ static int schema_element(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr element, sdlTyp if (cur_type->form == XSD_FORM_DEFAULT) { xmlNodePtr parent = element->parent; while (parent) { - if (node_is_equal_ex(parent, "schema", SCHEMA_NAMESPACE)) { + if (node_is_equal_xsd(parent, "schema")) { xmlAttrPtr def; def = get_attribute(parent->properties, "elementFormDefault"); if(def == NULL || strncmp((char*)def->children->content, "qualified", sizeof("qualified"))) { @@ -1695,12 +1706,12 @@ static int schema_element(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr element, sdlTyp } trav = element->children; - if (trav != NULL && node_is_equal(trav, "annotation")) { + if (trav != NULL && node_is_equal_xsd(trav, "annotation")) { /* TODO: support */ trav = trav->next; } if (trav != NULL) { - if (node_is_equal(trav,"simpleType")) { + if (node_is_equal_xsd(trav,"simpleType")) { if (ref != NULL) { soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' attribute and subtype"); } else if (type != NULL) { @@ -1708,7 +1719,7 @@ static int schema_element(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr element, sdlTyp } schema_simpleType(sdl, tns, trav, cur_type); trav = trav->next; - } else if (node_is_equal(trav,"complexType")) { + } else if (node_is_equal_xsd(trav,"complexType")) { if (ref != NULL) { soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' attribute and subtype"); } else if (type != NULL) { @@ -1719,11 +1730,11 @@ static int schema_element(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr element, sdlTyp } } while (trav != NULL) { - if (node_is_equal(trav,"unique")) { + if (node_is_equal_xsd(trav,"unique")) { /* TODO: support */ - } else if (node_is_equal(trav,"key")) { + } else if (node_is_equal_xsd(trav,"key")) { /* TODO: support */ - } else if (node_is_equal(trav,"keyref")) { + } else if (node_is_equal_xsd(trav,"keyref")) { /* TODO: support */ } else { soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in element", trav->name); @@ -1844,11 +1855,11 @@ static int schema_attribute(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrType, sdl attr = attrType->properties; while (attr != NULL) { - if (attr_is_equal_ex(attr, "default", SCHEMA_NAMESPACE)) { + if (attr_is_equal(attr, "default")) { newAttr->def = estrdup((char*)attr->children->content); - } else if (attr_is_equal_ex(attr, "fixed", SCHEMA_NAMESPACE)) { + } else if (attr_is_equal(attr, "fixed")) { newAttr->fixed = estrdup((char*)attr->children->content); - } else if (attr_is_equal_ex(attr, "form", SCHEMA_NAMESPACE)) { + } else if (attr_is_equal(attr, "form")) { if (strncmp((char*)attr->children->content, "qualified", sizeof("qualified")) == 0) { newAttr->form = XSD_FORM_QUALIFIED; } else if (strncmp((char*)attr->children->content, "unqualified", sizeof("unqualified")) == 0) { @@ -1856,15 +1867,15 @@ static int schema_attribute(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrType, sdl } else { newAttr->form = XSD_FORM_DEFAULT; } - } else if (attr_is_equal_ex(attr, "id", SCHEMA_NAMESPACE)) { + } else if (attr_is_equal(attr, "id")) { /* skip */ - } else if (attr_is_equal_ex(attr, "name", SCHEMA_NAMESPACE)) { + } else if (attr_is_equal(attr, "name")) { newAttr->name = estrdup((char*)attr->children->content); - } else if (attr_is_equal_ex(attr, "ref", SCHEMA_NAMESPACE)) { + } else if (attr_is_equal(attr, "ref")) { /* already processed */ - } else if (attr_is_equal_ex(attr, "type", SCHEMA_NAMESPACE)) { + } else if (attr_is_equal(attr, "type")) { /* already processed */ - } else if (attr_is_equal_ex(attr, "use", SCHEMA_NAMESPACE)) { + } else if (attr_is_equal(attr, "use")) { if (strncmp((char*)attr->children->content, "prohibited", sizeof("prohibited")) == 0) { newAttr->use = XSD_USE_PROHIBITED; } else if (strncmp((char*)attr->children->content, "required", sizeof("required")) == 0) { @@ -1875,9 +1886,9 @@ static int schema_attribute(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrType, sdl newAttr->use = XSD_USE_DEFAULT; } } else { - xmlNsPtr nsPtr = attr_find_ns(attr); + xmlNsPtr nsPtr = attr->ns; - if (strncmp((char*)nsPtr->href, SCHEMA_NAMESPACE, sizeof(SCHEMA_NAMESPACE))) { + if (nsPtr && strncmp((const char*) nsPtr->href, XSD_NAMESPACE, sizeof(XSD_NAMESPACE)) != 0) { smart_str key2 = {0}; sdlExtraAttributePtr ext; xmlNsPtr nsptr; @@ -1914,7 +1925,7 @@ static int schema_attribute(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrType, sdl if (newAttr->form == XSD_FORM_DEFAULT) { xmlNodePtr parent = attrType->parent; while (parent) { - if (node_is_equal_ex(parent, "schema", SCHEMA_NAMESPACE)) { + if (node_is_equal_xsd(parent, "schema")) { xmlAttrPtr def; def = get_attribute(parent->properties, "attributeFormDefault"); if(def == NULL || strncmp((char*)def->children->content, "qualified", sizeof("qualified"))) { @@ -1931,12 +1942,12 @@ static int schema_attribute(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrType, sdl } } trav = attrType->children; - if (trav != NULL && node_is_equal(trav, "annotation")) { + if (trav != NULL && node_is_equal_xsd(trav, "annotation")) { /* TODO: support */ trav = trav->next; } if (trav != NULL) { - if (node_is_equal(trav,"simpleType")) { + if (node_is_equal_xsd(trav,"simpleType")) { sdlTypePtr dummy_type; zval zv; @@ -2039,22 +2050,22 @@ static int schema_attributeGroup(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrGrou } trav = attrGroup->children; - if (trav != NULL && node_is_equal(trav, "annotation")) { + if (trav != NULL && node_is_equal_xsd(trav, "annotation")) { /* TODO: support */ trav = trav->next; } while (trav != NULL) { - if (node_is_equal(trav,"attribute")) { + if (node_is_equal_xsd(trav,"attribute")) { if (ref != NULL) { soap_error0(E_ERROR, "Parsing Schema: attributeGroup has both 'ref' attribute and subattribute"); } schema_attribute(sdl, tns, trav, cur_type, NULL); - } else if (node_is_equal(trav,"attributeGroup")) { + } else if (node_is_equal_xsd(trav,"attributeGroup")) { if (ref != NULL) { soap_error0(E_ERROR, "Parsing Schema: attributeGroup has both 'ref' attribute and subattribute"); } schema_attributeGroup(sdl, tns, trav, cur_type, NULL); - } else if (node_is_equal(trav,"anyAttribute")) { + } else if (node_is_equal_xsd(trav,"anyAttribute")) { if (ref != NULL) { soap_error0(E_ERROR, "Parsing Schema: attributeGroup has both 'ref' attribute and subattribute"); } @@ -2269,7 +2280,7 @@ static void schema_type_fixup(sdlCtx *ctx, sdlTypePtr type) type->def = estrdup(tmp->def); } type->form = tmp->form; - } else if (strcmp(type->ref, SCHEMA_NAMESPACE ":schema") == 0) { + } else if (strcmp(type->ref, XSD_NAMESPACE ":schema") == 0) { type->encode = get_conversion(XSD_ANYXML); } else { soap_error1(E_ERROR, "Parsing Schema: unresolved element 'ref' attribute '%s'", type->ref); diff --git a/ext/soap/php_xml.c b/ext/soap/php_xml.c index f3b8e18f7ddfe..185525c048cbf 100644 --- a/ext/soap/php_xml.c +++ b/ext/soap/php_xml.c @@ -167,18 +167,6 @@ xmlDocPtr soap_xmlParseMemory(const void *buf, size_t buf_size) return ret; } -/* FIXME: this is wrong, attributes don't inherit the namespace of the node they're in! */ -xmlNsPtr attr_find_ns(xmlAttrPtr node) -{ - if (node->ns) { - return node->ns; - } else if (node->parent->ns) { - return node->parent->ns; - } else { - return xmlSearchNs(node->doc, node->parent, NULL); - } -} - xmlNsPtr node_find_ns(xmlNodePtr node) { if (node->ns) { @@ -190,14 +178,16 @@ xmlNsPtr node_find_ns(xmlNodePtr node) int attr_is_equal_ex(xmlAttrPtr node, const char *name, const char *ns) { - if (name == NULL || ((node->name) && strcmp((char*)node->name, name) == 0)) { + if (node->name && strcmp((const char *) node->name, name) == 0) { + xmlNsPtr nsPtr = node->ns; if (ns) { - xmlNsPtr nsPtr = attr_find_ns(node); if (nsPtr) { - return (strcmp((char*)nsPtr->href, ns) == 0); + return (strcmp((const char *) nsPtr->href, ns) == 0); } else { return FALSE; } + } else if (nsPtr) { + return FALSE; } return TRUE; } @@ -210,7 +200,7 @@ int node_is_equal_ex(xmlNodePtr node, const char *name, const char *ns) if (ns) { xmlNsPtr nsPtr = node_find_ns(node); if (nsPtr) { - return (strcmp((char*)nsPtr->href, ns) == 0); + return strcmp((const char *) nsPtr->href, ns) == 0; } else { return FALSE; } @@ -220,10 +210,41 @@ int node_is_equal_ex(xmlNodePtr node, const char *name, const char *ns) return FALSE; } +int node_is_equal_ex_one_of(xmlNodePtr node, const char *name, const char *const *namespaces) +{ + if ((node->name) && strcmp((char*)node->name, name) == 0) { + xmlNsPtr nsPtr = node_find_ns(node); + if (nsPtr) { + do { + if (strcmp((const char *) nsPtr->href, *namespaces) == 0) { + return TRUE; + } + namespaces++; + } while (*namespaces != NULL); + } + return FALSE; + } + return FALSE; +} + +xmlAttrPtr get_attribute_any_ns(xmlAttrPtr node, const char *name) +{ + while (node!=NULL) { + if (node->name && strcmp((const char *) node->name, name) == 0) { + return node; + } + node = node->next; + } + return NULL; +} +/* Finds an attribute by name and namespace. + * If ns is NULL, the attribute must not be in any namespace. + * If ns is not NULL, the attribute must be in the specified namespace. + */ xmlAttrPtr get_attribute_ex(xmlAttrPtr node, const char *name, const char *ns) { - while (node!=NULL) { + while (node != NULL) { if (attr_is_equal_ex(node, name, ns)) { return node; } diff --git a/ext/soap/php_xml.h b/ext/soap/php_xml.h index d46767e68ed04..c967ac09d738c 100644 --- a/ext/soap/php_xml.h +++ b/ext/soap/php_xml.h @@ -30,11 +30,12 @@ xmlDocPtr soap_xmlParseFile(const char *filename); xmlDocPtr soap_xmlParseMemory(const void *buf, size_t size); -xmlNsPtr attr_find_ns(xmlAttrPtr node); xmlNsPtr node_find_ns(xmlNodePtr node); int attr_is_equal_ex(xmlAttrPtr node, const char *name, const char *ns); int node_is_equal_ex(xmlNodePtr node, const char *name, const char *ns); -xmlAttrPtr get_attribute_ex(xmlAttrPtr node,const char *name, const char *ns); +int node_is_equal_ex_one_of(xmlNodePtr node, const char *name, const char *const *namespaces); +xmlAttrPtr get_attribute_any_ns(xmlAttrPtr node, const char *name); +xmlAttrPtr get_attribute_ex(xmlAttrPtr node, const char *name, const char *ns); xmlNodePtr get_node_ex(xmlNodePtr node, const char *name, const char *ns); xmlNodePtr get_node_recursive_ex(xmlNodePtr node, const char *name, const char *ns); xmlNodePtr get_node_with_attribute_ex(xmlNodePtr node, const char *name, const char *name_ns, const char *attribute, const char *value, const char *attr_ns); diff --git a/ext/soap/tests/bugs/bug27722.wsdl b/ext/soap/tests/bugs/bug27722.wsdl index 05cb4a6e8b751..880cf14aaf36f 100644 --- a/ext/soap/tests/bugs/bug27722.wsdl +++ b/ext/soap/tests/bugs/bug27722.wsdl @@ -69,11 +69,11 @@ - - - - - + + + + + diff --git a/ext/soap/tests/bugs/bug27742.wsdl b/ext/soap/tests/bugs/bug27742.wsdl index 5843534a00326..670ff6cd1f397 100644 --- a/ext/soap/tests/bugs/bug27742.wsdl +++ b/ext/soap/tests/bugs/bug27742.wsdl @@ -1,8 +1,8 @@ - + - + ISO 8601 pattern used to denote program durations. Year, month and day are not relevant in our context and are omitted. diff --git a/ext/soap/tests/bugs/bug29839.wsdl b/ext/soap/tests/bugs/bug29839.wsdl index 2bea2da913772..352b3d6826c67 100644 --- a/ext/soap/tests/bugs/bug29839.wsdl +++ b/ext/soap/tests/bugs/bug29839.wsdl @@ -1,14 +1,14 @@ - + - + - + - + diff --git a/ext/soap/tests/bugs/bug34453.wsdl b/ext/soap/tests/bugs/bug34453.wsdl index 6b5ca48fe8c8f..e1ea4ade0b6a5 100644 --- a/ext/soap/tests/bugs/bug34453.wsdl +++ b/ext/soap/tests/bugs/bug34453.wsdl @@ -1,10 +1,10 @@ - + - + diff --git a/ext/soap/tests/bugs/bug62900.phpt b/ext/soap/tests/bugs/bug62900.phpt index c78afda5304af..64e71aa5aaf2e 100644 --- a/ext/soap/tests/bugs/bug62900.phpt +++ b/ext/soap/tests/bugs/bug62900.phpt @@ -11,7 +11,7 @@ $wsdl_with_ns = << - + @@ -21,7 +21,7 @@ $wsdl_without_ns = << - + diff --git a/ext/soap/tests/bugs/bug68576.phpt b/ext/soap/tests/bugs/bug68576.phpt new file mode 100644 index 0000000000000..ab89cd980c64b --- /dev/null +++ b/ext/soap/tests/bugs/bug68576.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #68576 (Namespaces in schema php_schema.c) +--EXTENSIONS-- +soap +--FILE-- + WSDL_CACHE_NONE]); +} catch (SoapFault $e) { + // Should throw a SoapFault for the binding to the service, not for a schema error + echo get_class($e)."\n"; + echo $e->faultstring."\n"; +} +?> +--EXPECT-- +SoapFault +SOAP-ERROR: Parsing WSDL: Couldn't bind to service diff --git a/ext/soap/tests/bugs/bug68576.wsdl b/ext/soap/tests/bugs/bug68576.wsdl new file mode 100644 index 0000000000000..7c1396c96c4df --- /dev/null +++ b/ext/soap/tests/bugs/bug68576.wsdl @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + From dd856d5ad90c642d82eaf5fe4ab511c8a3971557 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 29 May 2025 16:57:31 +0200 Subject: [PATCH 6/8] Fix potential NULL deref Backported from GH-18697. --- ext/soap/php_schema.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/soap/php_schema.c b/ext/soap/php_schema.c index 423714545ae30..2fc0eacc530f7 100644 --- a/ext/soap/php_schema.c +++ b/ext/soap/php_schema.c @@ -1872,7 +1872,7 @@ static int schema_attribute(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrType, sdl } else { xmlNsPtr nsPtr = attr_find_ns(attr); - if (strncmp((char*)nsPtr->href, SCHEMA_NAMESPACE, sizeof(SCHEMA_NAMESPACE))) { + if (nsPtr && strncmp((char*)nsPtr->href, SCHEMA_NAMESPACE, sizeof(SCHEMA_NAMESPACE))) { smart_str key2 = {0}; sdlExtraAttributePtr ext; xmlNsPtr nsptr; From bd47c14c504e27ab61b78ea0711bf4cae77a5a49 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 29 May 2025 18:26:46 +0200 Subject: [PATCH 7/8] Also allow XSD_1999_NAMESPACE --- ext/soap/php_schema.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/soap/php_schema.c b/ext/soap/php_schema.c index f1af0110bab57..dc6816034dea9 100644 --- a/ext/soap/php_schema.c +++ b/ext/soap/php_schema.c @@ -48,6 +48,7 @@ static bool node_is_equal_xsd(xmlNodePtr node, const char *name) static const char *ns[] = { XSD_NAMESPACE, XSD_DRAFT_2000_NAMESPACE, + XSD_1999_NAMESPACE, NULL }; From c267caa54211b3f87d7f7ce0cfbdc942b6598704 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 29 May 2025 18:35:19 +0200 Subject: [PATCH 8/8] Deduplicate XML parsing code for SOAP (#18700) * Deduplicate XML parsing code for SOAP * Apply suggestions from code review Co-authored-by: Gina Peter Banyard --------- Co-authored-by: Gina Peter Banyard --- ext/soap/php_xml.c | 61 ++++++++++++---------------------------------- 1 file changed, 16 insertions(+), 45 deletions(-) diff --git a/ext/soap/php_xml.c b/ext/soap/php_xml.c index 185525c048cbf..b6b0c09b9d48b 100644 --- a/ext/soap/php_xml.c +++ b/ext/soap/php_xml.c @@ -74,19 +74,11 @@ static void soap_Comment(void *ctx, const xmlChar *value) { } -xmlDocPtr soap_xmlParseFile(const char *filename) +/* Consumes `ctxt` */ +static xmlDocPtr soap_xmlParse_ex(xmlParserCtxtPtr ctxt) { - xmlParserCtxtPtr ctxt = NULL; xmlDocPtr ret; - bool old_allow_url_fopen; - - old_allow_url_fopen = PG(allow_url_fopen); - PG(allow_url_fopen) = 1; - ctxt = xmlCreateFileParserCtxt(filename); - PG(allow_url_fopen) = old_allow_url_fopen; if (ctxt) { - bool old; - php_libxml_sanitize_parse_ctxt_options(ctxt); /* TODO: In libxml2 2.14.0 change this to the new options API so we don't rely on deprecated APIs. */ ZEND_DIAGNOSTIC_IGNORED_START("-Wdeprecated-declarations") @@ -98,7 +90,7 @@ xmlDocPtr soap_xmlParseFile(const char *filename) ctxt->sax->warning = NULL; ctxt->sax->error = NULL; /*ctxt->sax->fatalError = NULL;*/ - old = php_libxml_disable_entity_loader(1); + bool old = php_libxml_disable_entity_loader(true); xmlParseDocument(ctxt); php_libxml_disable_entity_loader(old); if (ctxt->wellFormed) { @@ -115,6 +107,17 @@ xmlDocPtr soap_xmlParseFile(const char *filename) } else { ret = NULL; } + return ret; +} + +xmlDocPtr soap_xmlParseFile(const char *filename) +{ + bool old_allow_url_fopen = PG(allow_url_fopen); + PG(allow_url_fopen) = true; + xmlParserCtxtPtr ctxt = xmlCreateFileParserCtxt(filename); + PG(allow_url_fopen) = old_allow_url_fopen; + + xmlDocPtr ret = soap_xmlParse_ex(ctxt); if (ret) { cleanup_xml_node((xmlNodePtr)ret); @@ -124,40 +127,8 @@ xmlDocPtr soap_xmlParseFile(const char *filename) xmlDocPtr soap_xmlParseMemory(const void *buf, size_t buf_size) { - xmlParserCtxtPtr ctxt = NULL; - xmlDocPtr ret; - - ctxt = xmlCreateMemoryParserCtxt(buf, buf_size); - if (ctxt) { - bool old; - - php_libxml_sanitize_parse_ctxt_options(ctxt); - ctxt->sax->ignorableWhitespace = soap_ignorableWhitespace; - ctxt->sax->comment = soap_Comment; - ctxt->sax->warning = NULL; - ctxt->sax->error = NULL; - /*ctxt->sax->fatalError = NULL;*/ - /* TODO: In libxml2 2.14.0 change this to the new options API so we don't rely on deprecated APIs. */ - ZEND_DIAGNOSTIC_IGNORED_START("-Wdeprecated-declarations") - ctxt->options |= XML_PARSE_HUGE; - ZEND_DIAGNOSTIC_IGNORED_END - old = php_libxml_disable_entity_loader(1); - xmlParseDocument(ctxt); - php_libxml_disable_entity_loader(old); - if (ctxt->wellFormed) { - ret = ctxt->myDoc; - if (ret->URL == NULL && ctxt->directory != NULL) { - ret->URL = xmlCharStrdup(ctxt->directory); - } - } else { - ret = NULL; - xmlFreeDoc(ctxt->myDoc); - ctxt->myDoc = NULL; - } - xmlFreeParserCtxt(ctxt); - } else { - ret = NULL; - } + xmlParserCtxtPtr ctxt = xmlCreateMemoryParserCtxt(buf, buf_size); + xmlDocPtr ret = soap_xmlParse_ex(ctxt); /* if (ret) {