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
4 changes: 4 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ PHP NEWS
- BCMath:
. Simplify `bc_divide()` code. (SakiTakamachi)
. If the result is 0, n_scale is set to 0. (SakiTakamachi)
. If size of BC_VECTOR array is within 64 bytes, stack area is now used.
(SakiTakamachi)

- CLI:
. Add --ini=diff to print INI settings changed from the builtin default.
Expand Down Expand Up @@ -33,6 +35,8 @@ PHP NEWS
zend.exception_string_param_max_len=0. (timwolla)
. Fixed bug GH-17959 (Relax missing trait fatal error to error exception).
(ilutov)
. Fixed bug GH-18033 (NULL-ptr dereference when using register_tick_function
in destructor). (nielsdos)

- Curl:
. Added curl_multi_get_handles(). (timwolla)
Expand Down
3 changes: 3 additions & 0 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ PHP 8.5 UPGRADE NOTES
resources that were indirectly collected through cycles.
. It is now allowed to substitute static with self or the concrete class name
in final subclasses.
. The tick handlers are now deactivated after all shutdown functions, destructors
have run and the output handlers have been cleaned up.
This is a consequence of fixing GH-18033.

- Intl:
. The extension now requires at least ICU 57.1.
Expand Down
24 changes: 24 additions & 0 deletions Zend/tests/declare/gh18033_1.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
--TEST--
GH-18033 (NULL-ptr dereference when using register_tick_function in destructor)
--DESCRIPTION--
Needs --repeat 2 or something similar to reproduce
--CREDITS--
clesmian
--FILE--
<?php
class Foo {
function __destruct() {
declare(ticks=1);
register_tick_function(
function() { }
);
echo "In destructor\n";
}
}

$bar = new Foo;
echo "Done\n";
?>
--EXPECT--
Done
In destructor
16 changes: 16 additions & 0 deletions Zend/tests/declare/gh18033_2.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
--TEST--
GH-18033 (NULL-ptr dereference when using register_tick_function in ob_start)
--DESCRIPTION--
Needs --repeat 2 or something similar to reproduce
--CREDITS--
clesmian
--FILE--
<?php
ob_start(function() {
declare(ticks=1);
register_tick_function(
function() { }
);
});
?>
--EXPECT--
30 changes: 17 additions & 13 deletions ext/bcmath/libbcmath/src/div.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,15 @@ static void bc_do_div(
size_t quot_arr_size = numerator_arr_size - divisor_arr_size + 1;
size_t quot_real_arr_size = MIN(quot_arr_size, (quot_size + BC_VECTOR_SIZE - 1) / BC_VECTOR_SIZE);

BC_VECTOR *numerator_vectors = safe_emalloc(numerator_arr_size + divisor_arr_size + quot_arr_size, sizeof(BC_VECTOR), 0);
BC_VECTOR stack_vectors[BC_STACK_VECTOR_SIZE];
size_t allocation_arr_size = numerator_arr_size + divisor_arr_size + quot_arr_size;

BC_VECTOR *numerator_vectors;
if (allocation_arr_size <= BC_STACK_VECTOR_SIZE) {
numerator_vectors = stack_vectors;
} else {
numerator_vectors = safe_emalloc(allocation_arr_size, sizeof(BC_VECTOR), 0);
}
BC_VECTOR *divisor_vectors = numerator_vectors + numerator_arr_size;
BC_VECTOR *quot_vectors = divisor_vectors + divisor_arr_size;

Expand Down Expand Up @@ -302,7 +310,9 @@ static void bc_do_div(
quot_vectors[i] /= BASE;
}

efree(numerator_vectors);
if (allocation_arr_size > BC_STACK_VECTOR_SIZE) {
efree(numerator_vectors);
}
}

static inline void bc_divide_by_one(bc_num numerator, bc_num *quot, size_t quot_scale)
Expand Down Expand Up @@ -370,12 +380,11 @@ bool bc_divide(bc_num numerator, bc_num divisor, bc_num *quot, size_t scale)
while (*numeratorptr == 0) {
numeratorptr++;
numerator_leading_zeros++;
if (numerator_leading_zeros == numerator_size) {
goto quot_zero;
}
}
if (numerator_size > numerator_leading_zeros) {
numerator_size -= numerator_leading_zeros;
} else {
goto quot_zero;
}
numerator_size -= numerator_leading_zeros;

/* check and remove divisor leading zeros */
while (*divisorptr == 0) {
Expand All @@ -396,12 +405,7 @@ bool bc_divide(bc_num numerator, bc_num divisor, bc_num *quot, size_t scale)
divisor_trailing_zeros++;
}
divisor_size -= divisor_trailing_zeros;

if (numerator_size > divisor_trailing_zeros) {
numerator_size -= divisor_trailing_zeros;
} else {
goto quot_zero;
}
numerator_size -= divisor_trailing_zeros;

size_t quot_size = numerator_size - divisor_size + 1; /* numerator_size >= divisor_size */
if (quot_size > quot_scale) {
Expand Down
3 changes: 3 additions & 0 deletions ext/bcmath/libbcmath/src/private.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@
# define BC_LITTLE_ENDIAN 1
#endif

/* 64-bytes for 64-bit */
#define BC_STACK_VECTOR_SIZE 8

/*
* Adding more than this many times may cause uint32_t/uint64_t to overflow.
* Typically this is 1844 for 64bit and 42 for 32bit.
Expand Down
26 changes: 17 additions & 9 deletions ext/bcmath/libbcmath/src/recmul.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,15 +149,21 @@ static void bc_standard_mul(bc_num n1, size_t n1len, bc_num n2, size_t n2len, bc
size_t n2_arr_size = (n2len + BC_VECTOR_SIZE - 1) / BC_VECTOR_SIZE;
size_t prod_arr_size = (prodlen + BC_VECTOR_SIZE - 1) / BC_VECTOR_SIZE;

/*
* let's say that N is the max of n1len and n2len (and a multiple of BC_VECTOR_SIZE for simplicity),
* then this sum is <= N/BC_VECTOR_SIZE + N/BC_VECTOR_SIZE + N/BC_VECTOR_SIZE + N/BC_VECTOR_SIZE - 1
* which is equal to N - 1 if BC_VECTOR_SIZE is 4, and N/2 - 1 if BC_VECTOR_SIZE is 8.
*/
BC_VECTOR *buf = safe_emalloc(n1_arr_size + n2_arr_size + prod_arr_size, sizeof(BC_VECTOR), 0);
BC_VECTOR stack_vectors[BC_STACK_VECTOR_SIZE];
size_t allocation_arr_size = n1_arr_size + n2_arr_size + prod_arr_size;

BC_VECTOR *n1_vector = buf;
BC_VECTOR *n2_vector = buf + n1_arr_size;
BC_VECTOR *n1_vector;
if (allocation_arr_size <= BC_STACK_VECTOR_SIZE) {
n1_vector = stack_vectors;
} else {
/*
* let's say that N is the max of n1len and n2len (and a multiple of BC_VECTOR_SIZE for simplicity),
* then this sum is <= N/BC_VECTOR_SIZE + N/BC_VECTOR_SIZE + N/BC_VECTOR_SIZE + N/BC_VECTOR_SIZE - 1
* which is equal to N - 1 if BC_VECTOR_SIZE is 4, and N/2 - 1 if BC_VECTOR_SIZE is 8.
*/
n1_vector = safe_emalloc(allocation_arr_size, sizeof(BC_VECTOR), 0);
}
BC_VECTOR *n2_vector = n1_vector + n1_arr_size;
BC_VECTOR *prod_vector = n2_vector + n2_arr_size;

for (i = 0; i < prod_arr_size; i++) {
Expand Down Expand Up @@ -188,7 +194,9 @@ static void bc_standard_mul(bc_num n1, size_t n1len, bc_num n2, size_t n2len, bc

bc_mul_finish_from_vector(prod_vector, prod_arr_size, prodlen, prod);

efree(buf);
if (allocation_arr_size > BC_STACK_VECTOR_SIZE) {
efree(n1_vector);
}
}

/** This is bc_standard_mul implementation for square */
Expand Down
4 changes: 2 additions & 2 deletions ext/ldap/ldap.c
Original file line number Diff line number Diff line change
Expand Up @@ -2316,12 +2316,12 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext)
SEPARATE_ARRAY(attribute_values);
uint32_t num_values = zend_hash_num_elements(Z_ARRVAL_P(attribute_values));
if (num_values == 0) {
zend_argument_value_error(3, "list of attribute values must not be empty");
zend_argument_value_error(3, "attribute \"%s\" must be a non-empty list of attribute values", ZSTR_VAL(attribute));
RETVAL_FALSE;
goto cleanup;
}
if (!php_ldap_is_numerically_indexed_array(Z_ARRVAL_P(attribute_values))) {
zend_argument_value_error(3, "must be an array of attribute values with numeric keys");
zend_argument_value_error(3, "attribute \"%s\" must be an array of attribute values with numeric keys", ZSTR_VAL(attribute));
RETVAL_FALSE;
goto cleanup;
}
Expand Down
4 changes: 2 additions & 2 deletions ext/ldap/tests/ldap_add_modify_delete_programming_errors.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ ValueError: ldap_add(): Argument #3 ($entry) must be an associative array of att
ValueError: ldap_add(): Argument #3 ($entry) key must not be empty
ValueError: ldap_add(): Argument #3 ($entry) key must not contain any null bytes
Error: Object of class stdClass could not be converted to string
ValueError: ldap_add(): Argument #3 ($entry) list of attribute values must not be empty
ValueError: ldap_add(): Argument #3 ($entry) must be an array of attribute values with numeric keys
ValueError: ldap_add(): Argument #3 ($entry) attribute "attribute2" must be a non-empty list of attribute values
ValueError: ldap_add(): Argument #3 ($entry) attribute "attribute2" must be an array of attribute values with numeric keys
TypeError: LDAP value must be of type string|int|bool, array given
Error: Object of class stdClass could not be converted to string
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,6 @@ try {
?>
--EXPECT--
Error: Object of class stdClass could not be converted to string
ValueError: ldap_add(): Argument #3 ($entry) list of attribute values must not be empty
ValueError: ldap_add(): Argument #3 ($entry) attribute "attribute2" must be a non-empty list of attribute values
TypeError: LDAP value must be of type string|int|bool, array given
TypeError: LDAP value must be of type string|int|bool, stdClass given
4 changes: 2 additions & 2 deletions ext/pdo_firebird/firebird_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,7 @@ static bool firebird_handle_preparer(pdo_dbh_t *dbh, zend_string *sql, /* {{{ */

/* make all parameters nullable */
unsigned int i;
XSQLVAR* var;
XSQLVAR* var;
for (i = 0, var = S->in_sqlda->sqlvar; i < S->in_sqlda->sqld; i++, var++) {
/* The low bit of sqltype indicates that the parameter can take a NULL value */
var->sqltype |= 1;
Expand Down Expand Up @@ -1422,7 +1422,7 @@ static int pdo_firebird_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /*
"HY000", H->isc_status[1], errmsg);
}

if (dbh->auto_commit && !H->tr) {
if (ret && dbh->auto_commit && !H->tr) {
ret = php_firebird_begin_transaction(dbh, /* auto commit mode */ true);
}

Expand Down
4 changes: 2 additions & 2 deletions main/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1904,8 +1904,6 @@ void php_request_shutdown(void *dummy)
*/
EG(current_execute_data) = NULL;

php_deactivate_ticks();

/* 0. Call any open observer end handlers that are still open after a zend_bailout */
if (ZEND_OBSERVER_ENABLED) {
zend_observer_fcall_end_all();
Expand All @@ -1926,6 +1924,8 @@ void php_request_shutdown(void *dummy)
php_output_end_all();
} zend_end_try();

php_deactivate_ticks();

/* 4. Reset max_execution_time (no longer executing php code after response sent) */
zend_try {
zend_unset_timeout();
Expand Down
Loading