Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ PHP NEWS
replacement when a \k<name> backref has no closing delimiter.
(Ilia Alshanetsky)

- ODBC:
. Fixed odbc_field_len(), odbc_field_scale() and odbc_field_type()
returning uninitialized memory when SQLColAttribute fails.
(Ilia Alshanetsky)

- PCNTL:
. Fixed the declared signature of pcntl_signal(), whose $restart_syscalls
argument accepts null and defaults to it. (lacatoire)
Expand All @@ -78,6 +83,8 @@ PHP NEWS
- SOAP:
. Fixed WSDL cache corruption when a soap:header defines headerfaults.
(Ilia Alshanetsky)
. Fixed stack overflow when parsing a WSDL with self-referential schema
groups or attributeGroups. (Ilia Alshanetsky)

- Sodium:
. Added support for the libsodium 1.0.22 KEM APIs (X-Wing and ML-KEM768).
Expand Down
36 changes: 34 additions & 2 deletions ext/odbc/php_odbc.c
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,7 @@ void odbc_bindcols(odbc_result *result)
result->values[i].value_max_len = 0;
colfieldid = SQL_COLUMN_DISPLAY_SIZE;

result->values[i].name[0] = '\0';
rc = SQLColAttribute(result->stmt, (SQLUSMALLINT)(i+1), SQL_DESC_NAME,
result->values[i].name, sizeof(result->values[i].name), &colnamelen, 0);
result->values[i].coltype = 0;
Expand Down Expand Up @@ -784,10 +785,30 @@ void odbc_transact(INTERNAL_FUNCTION_PARAMETERS, int type)
}
/* }}} */

static void odbc_colattribute_failed(odbc_result *result, zend_long pv_num)
{
#if defined(ODBCVER) && (ODBCVER >= 0x0300)
SQLINTEGER diag_error;
SQLCHAR diag_state[6];
SQLCHAR diag_text[128];

memset(diag_state, '\0', sizeof(diag_state));
memset(diag_text, '\0', sizeof(diag_text));
if (SQL_SUCCESS == SQLGetDiagRec(SQL_HANDLE_STMT, result->stmt, 1, diag_state, &diag_error, diag_text, sizeof(diag_text), NULL)) {
diag_state[sizeof(diag_state) - 1] = '\0';
diag_text[sizeof(diag_text) - 1] = '\0';
php_error_docref(NULL, E_WARNING, "SQLColAttribute failed for field #%d: [%s] %s", (int)pv_num, diag_state, diag_text);
return;
}
#endif
php_error_docref(NULL, E_WARNING, "SQLColAttribute failed for field #%d", (int)pv_num);
}

/* {{{ odbc_column_lengths */
void odbc_column_lengths(INTERNAL_FUNCTION_PARAMETERS, int type)
{
odbc_result *result;
RETCODE rc;
SQLLEN len;
zend_long pv_num;

Expand All @@ -813,7 +834,11 @@ void odbc_column_lengths(INTERNAL_FUNCTION_PARAMETERS, int type)
RETURN_FALSE;
}

SQLColAttribute(result->stmt, (SQLUSMALLINT)pv_num, (SQLUSMALLINT) (type?SQL_COLUMN_SCALE:SQL_COLUMN_PRECISION), NULL, 0, NULL, &len);
rc = SQLColAttribute(result->stmt, (SQLUSMALLINT)pv_num, (SQLUSMALLINT)(type ? SQL_COLUMN_SCALE : SQL_COLUMN_PRECISION), NULL, 0, NULL, &len);
if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
odbc_colattribute_failed(result, pv_num);
len = 0;
}

RETURN_LONG(len);
}
Expand Down Expand Up @@ -2315,6 +2340,7 @@ PHP_FUNCTION(odbc_field_type)
odbc_result *result;
char tmp[32];
SQLSMALLINT tmplen;
RETCODE rc;
zend_long pv_num;

ZEND_PARSE_PARAMETERS_START(2, 2)
Expand All @@ -2339,7 +2365,13 @@ PHP_FUNCTION(odbc_field_type)
RETURN_FALSE;
}

SQLColAttribute(result->stmt, (SQLUSMALLINT)pv_num, SQL_COLUMN_TYPE_NAME, tmp, 31, &tmplen, NULL);
tmp[0] = '\0';
rc = SQLColAttribute(result->stmt, (SQLUSMALLINT)pv_num, SQL_COLUMN_TYPE_NAME, tmp, sizeof(tmp) - 1, &tmplen, NULL);
if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
odbc_colattribute_failed(result, pv_num);
RETURN_FALSE;
}

RETURN_STRING(tmp);
}
/* }}} */
Expand Down
4 changes: 2 additions & 2 deletions ext/session/tests/user_session_module/gh23043.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ string(0) ""

Warning: SessionHandler::write(): Session ID is too long or contains illegal characters. Only the A-Z, a-z, 0-9, "-", and "," characters are allowed in %s on line %d

Warning: session_write_close(): Failed to write session data using user defined save handler. (session.save_path: , handler: a::write) in %s on line %d
Warning: session_write_close(): Failed to write session data using user defined save handler. (session.save_path: %S, handler: a::write) in %s on line %d
string(0) ""

Warning: SessionHandler::write(): Session ID is too long or contains illegal characters. Only the A-Z, a-z, 0-9, "-", and "," characters are allowed in Unknown on line 0

Warning: session_write_close(): Failed to write session data using user defined save handler. (session.save_path: , handler: a::write) in Unknown on line 0
Warning: session_write_close(): Failed to write session data using user defined save handler. (session.save_path: %S, handler: a::write) in Unknown on line 0
15 changes: 15 additions & 0 deletions ext/soap/php_schema.c
Original file line number Diff line number Diff line change
Expand Up @@ -2193,6 +2193,10 @@ static void schema_attributegroup_fixup(sdlCtx *ctx, sdlAttributePtr attr, HashT
if (ctx->attributeGroups != NULL) {
tmp = (sdlTypePtr)schema_find_by_ref(ctx->attributeGroups, attr->ref);
if (tmp) {
if (zend_hash_index_find_ptr(&ctx->fixupInProgress, (zend_ulong)(uintptr_t)tmp) != NULL) {
soap_error1(E_ERROR, "Parsing Schema: recursive attributeGroup 'ref' attribute '%s'", attr->ref);
}
zend_hash_index_add_ptr(&ctx->fixupInProgress, (zend_ulong)(uintptr_t)tmp, tmp);
if (tmp->attributes) {
zend_hash_internal_pointer_reset(tmp->attributes);
while ((tmp_attr = zend_hash_get_current_data_ptr(tmp->attributes)) != NULL) {
Expand Down Expand Up @@ -2228,6 +2232,7 @@ static void schema_attributegroup_fixup(sdlCtx *ctx, sdlAttributePtr attr, HashT
}
}
}
zend_hash_index_del(&ctx->fixupInProgress, (zend_ulong)(uintptr_t)tmp);
}
}
efree(attr->ref);
Expand All @@ -2242,6 +2247,9 @@ static void schema_content_model_fixup(sdlCtx *ctx, sdlContentModelPtr model)
sdlTypePtr tmp;

if (ctx->sdl->groups && (tmp = zend_hash_str_find_ptr(ctx->sdl->groups, model->u.group_ref, strlen(model->u.group_ref))) != NULL) {
if (zend_hash_index_find_ptr(&ctx->fixupInProgress, (zend_ulong)(uintptr_t)tmp) != NULL) {
soap_error1(E_ERROR, "Parsing Schema: recursive group 'ref' attribute '%s'", model->u.group_ref);
}
schema_type_fixup(ctx, tmp);
efree(model->u.group_ref);
model->kind = XSD_CONTENT_GROUP;
Expand Down Expand Up @@ -2285,6 +2293,8 @@ static void schema_type_fixup(sdlCtx *ctx, sdlTypePtr type)
sdlTypePtr tmp;
sdlAttributePtr attr;

zend_hash_index_add_ptr(&ctx->fixupInProgress, (zend_ulong)(uintptr_t)type, type);

if (type->ref != NULL) {
if (ctx->sdl->elements != NULL) {
tmp = (sdlTypePtr)schema_find_by_ref(ctx->sdl->elements, type->ref);
Expand Down Expand Up @@ -2337,6 +2347,7 @@ static void schema_type_fixup(sdlCtx *ctx, sdlTypePtr type)
}
}
}
zend_hash_index_del(&ctx->fixupInProgress, (zend_ulong)(uintptr_t)type);
}

void schema_pass2(sdlCtx *ctx)
Expand All @@ -2345,6 +2356,8 @@ void schema_pass2(sdlCtx *ctx)
sdlAttributePtr attr;
sdlTypePtr type;

zend_hash_init(&ctx->fixupInProgress, 0, NULL, NULL, 0);

if (ctx->attributes) {
ZEND_HASH_FOREACH_PTR(ctx->attributes, attr) {
schema_attribute_fixup(ctx, attr);
Expand Down Expand Up @@ -2378,6 +2391,8 @@ void schema_pass2(sdlCtx *ctx)
zend_hash_destroy(ctx->attributeGroups);
efree(ctx->attributeGroups);
}

zend_hash_destroy(&ctx->fixupInProgress);
}

void delete_model(zval *zv)
Expand Down
1 change: 1 addition & 0 deletions ext/soap/php_sdl.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ typedef struct sdlCtx {

HashTable *attributes; /* array of sdlAttributePtr */
HashTable *attributeGroups; /* array of sdlTypesPtr */
HashTable fixupInProgress;
php_stream_context *context;
zval old_header;
} sdlCtx;
Expand Down
44 changes: 44 additions & 0 deletions ext/soap/tests/schema-selfref-attrgroup.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
--TEST--
SOAP XML Schema: self-referential attributeGroup fix-up recursion is rejected
--EXTENSIONS--
soap
--FILE--
<?php
$wsdl = '<?xml version="1.0"?>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="urn:test" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<types>
<xsd:schema targetNamespace="urn:test" xmlns="http://www.w3.org/2001/XMLSchema">
<attributeGroup name="A">
<attribute name="a" type="string"/>
<attributeGroup ref="tns:A"/>
</attributeGroup>
<element name="root">
<complexType><attributeGroup ref="tns:A"/></complexType>
</element>
</xsd:schema>
</types>
<message name="m"><part name="p" element="tns:root"/></message>
<portType name="pt"><operation name="op"><input message="tns:m"/></operation></portType>
<binding name="b" type="tns:pt"><soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"/>
<operation name="op"><soap:operation soapAction="" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"/><input><soap:body use="literal" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"/></input></operation>
</binding>
<service name="s"><port name="p1" binding="tns:b"><soap:address location="http://localhost/x" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"/></port></service>
</definitions>';
$file = __DIR__ . '/schema-selfref-attrgroup.wsdl';
file_put_contents($file, $wsdl);
try {
$c = new SoapClient($file, ['exceptions' => true, 'cache_wsdl' => WSDL_CACHE_NONE]);
echo "parsed ok\n";
} catch (Throwable $e) {
echo $e::class, ": ", substr($e->getMessage(), 0, 120), "\n";
}
echo "done\n";
?>
--CLEAN--
<?php
@unlink(__DIR__ . '/schema-selfref-attrgroup.wsdl');
?>
--EXPECTF--
SoapFault: SOAP-ERROR: Parsing Schema: recursive attributeGroup 'ref' attribute '%s'
done
46 changes: 46 additions & 0 deletions ext/soap/tests/schema-selfref-group.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
--TEST--
SOAP XML Schema: self-referential group fix-up recursion is rejected
--EXTENSIONS--
soap
--FILE--
<?php
$wsdl = '<?xml version="1.0"?>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="urn:test" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<types>
<xsd:schema targetNamespace="urn:test" xmlns="http://www.w3.org/2001/XMLSchema">
<group name="A">
<sequence>
<element name="a" type="string"/>
<group ref="tns:A"/>
</sequence>
</group>
<element name="root">
<complexType><group ref="tns:A"/></complexType>
</element>
</xsd:schema>
</types>
<message name="m"><part name="p" element="tns:root"/></message>
<portType name="pt"><operation name="op"><input message="tns:m"/></operation></portType>
<binding name="b" type="tns:pt"><soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"/>
<operation name="op"><soap:operation soapAction="" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"/><input><soap:body use="literal" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"/></input></operation>
</binding>
<service name="s"><port name="p1" binding="tns:b"><soap:address location="http://localhost/x" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"/></port></service>
</definitions>';
$file = __DIR__ . '/schema-selfref-group.wsdl';
file_put_contents($file, $wsdl);
try {
$c = new SoapClient($file, ['exceptions' => true, 'cache_wsdl' => WSDL_CACHE_NONE]);
echo "parsed ok\n";
} catch (Throwable $e) {
echo $e::class, ": ", substr($e->getMessage(), 0, 120), "\n";
}
echo "done\n";
?>
--CLEAN--
<?php
@unlink(__DIR__ . '/schema-selfref-group.wsdl');
?>
--EXPECTF--
SoapFault: SOAP-ERROR: Parsing Schema: recursive group 'ref' attribute '%s'
done