Commit 16e217ee550 for php.net
commit 16e217ee5509c35712bcfa1d2468f5d6b6470d43
Merge: 80d580b2922 c0fa54f796f
Author: Saki Takamachi <saki@php.net>
Date: Sun Jun 7 12:18:40 2026 +0900
Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
ext/bcmath: bounds-check $precision in bcround() and Number::round() (#22182)
diff --cc NEWS
index 9a98aadadf8,ff552103ebc..7bc92d48ec3
--- a/NEWS
+++ b/NEWS
@@@ -1,7 -1,11 +1,11 @@@
PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
-?? ??? ????, PHP 8.4.23
+?? ??? ????, PHP 8.5.8
+ - BCMath:
+ . Fixed issues with oversized allocations and signed overflow in bcround()
+ and BcMath\Number::round(). (edorian)
+
- GD:
. Fixed bug GH-22121 (Double free in gdImageSetStyle() after
overflow-triggered early return). (iliaal)
diff --cc UPGRADING
index 8b6e0c57cb1,821fa4a723f..39400b5ea6d
--- a/UPGRADING
+++ b/UPGRADING
@@@ -597,134 -625,149 +597,138 @@@ PHP 8.5 UPGRADE NOTE
5. Changed Functions
========================================
+ - BCMath:
+ . bcround() and BcMath\Number::round() now throw a ValueError when the precision
+ argument is out of range.
+
-- Core:
- . trigger_error() and user_error() now have a return type of true instead of
- bool.
-
-- DOM:
- . DOMDocument::registerNodeClass() now has a tentative return type of true.
- Previously, the return type was bool but only true could be returned in practice.
-
-- GD:
- . imagescale now throws a ValueError when both width and height arguments are negative.
-
-- Hash:
- . Changed the return type of hash_update() to true. It was already the case that only
- true could be returned, but the stub was not updated yet.
-
- Intl:
- . NumberFormatter::ROUND_TOWARD_ZERO and NumberFormatter::ROUND_AWAY_FROM_ZERO
- have been added as aliases for NumberFormatter::ROUND_DOWN and
- NumberFormatter::ROUND_UP to be consistent with the new PHP_ROUND_* modes.
- RFC: https://wiki.php.net/rfc/new_rounding_modes_to_round_function
- . ResourceBundle::get() now has a tentative return type of:
- ResourceBundle|array|string|int|null
- . The idn_to_ascii() and idn_to_utf8() now always throw ValueErrors if the
- $domain name is empty or too long, and if $variant is not
- INTL_IDNA_VARIANT_UTS46.
-
-- LibXML:
- . libxml_set_streams_context() now immediately throws a TypeError when a
- non-stream-context resource is passed to the function, instead of throwing
- later when the stream context is used.
+ . IntlDateFormatter::setTimeZone()/datefmt_set_timezone()
+ throws an IntlException on uninitialised classes/clone failures.
+ . grapheme_extract() properly assigns $next value when skipping over
+ invalid starting bytes. Previously there were cases where it would
+ point to the start of the grapheme boundary instead of the end.
+ . Locale:: methods throw a ValueError when locale inputs contain null
+ bytes.
+ . transliterator_get_error_code(), transliterator_get_error_message()
+ TransLiterator::getErrorCode(), and TransLiterator::getErrorMessage()
+ have dropped the false from the return type union. Returning false
+ was actually never possible.
+ . grapheme_strpos(), grapheme_stripos(), grapheme_strrpos(),
+ grapheme_strripos(), grapheme_substr(), grapheme_strstr()
+ and grapheme_stristr() functions add $locale parameter.
+ RFC: https://wiki.php.net/rfc/grapheme_add_locale_for_case_insensitive
-- MBString:
- . The behavior of mb_strcut is more consistent now on invalid UTF-8 and UTF-16
- strings. (For valid UTF-8 and UTF-16 strings, there is no change.)
+- LDAP:
+ . ldap_get_option() now accepts a NULL connection, like ldap_set_option(),
+ to allow retrieval of global options.
-- ODBC:
- . Parameter $row of odbc_fetch_object(), odbc_fetch_array(), and
- odbc_fetch_into() now has a default value of null, consistent with
- odbc_fetch_row(). Previously, the default values were -1, -1, and 0,
- respectively.
+- libxml:
+ . libxml_set_external_entity_loader() now has a formal return type of true.
- OpenSSL:
- . The extra_attributes parameter in openssl_csr_new sets CSR attributes
- instead of subject DN which was incorrectly done previously.
- . The dn parameter in openssl_csr_new allows setting array of values for
- a single entry.
- . New serial_hex parameter added to openssl_csr_sign to allow setting serial
- number in the hexadecimal format.
- . Parsing ASN.1 UTCTime by openssl_x509_parse fails if seconds are omitted
- for OpenSSL version below 3.2 (-1 is returned for such fields). The
- OpenSSL version 3.3+ does not load such certificates already.
-
-- Output:
- . Output handler status flags passed to the flags parameter of ob_start
- are now cleared.
+ . openssl_public_encrypt() and openssl_private_decrypt() have a new parameter
+ $digest_algo that allows specifying the hash digest algorithm for OAEP padding.
+ . openssl_sign() and openssl_verify() have a new parameter $padding to allow
+ using more secure RSA PSS padding.
+ . openssl_cms_encrypt() $cipher_algo parameter can be a string with the
+ cipher name. That allows to use more algorithms including AES GCM cipher
+ algorithms for auth enveloped data.
-- PDO:
- . getAttribute, enabled to get the value of ATTR_STRINGIFY_FETCHES.
-
-- PDO_FIREBIRD:
- . getAttribute, enabled to get values of FB_ATTR_DATE_FORMAT, FB_ATTR_TIME_FORMAT,
- FB_ATTR_TIMESTAMP_FORMAT.
- . Added new attributes to specify transaction isolation level and access mode.
- Along with these, five constants (Pdo\Firebird::TRANSACTION_ISOLATION_LEVEL,
- Pdo\Firebird::READ_COMMITTED, Pdo\Firebird::REPEATABLE_READ,
- Pdo\Firebird::SERIALIZABLE, Pdo\Firebird::WRITABLE_TRANSACTION) have been added.
- . When using persistent connections, there is now a liveness check in the
- constructor.
- . The content that is built changes depending on the value of FB_API_VER in
- ibase.h, so added static method Pdo\Firebird::getApiVersion() to obtain that
- value. This value can also be referenced from phpinfo.
- . Five new data types are now available: INT128, DEC16, DEC34, TIMESTAMP_TZ, TIME_TZ.
- These are available starting with Firebird 4.0.
-
-- PDO_MYSQL:
- . getAttribute, enabled to get the value of ATTR_FETCH_TABLE_NAMES.
+- PCNTL:
+ . pcntl_exec() now has a formal return type of false.
+ . pcntl_waitid() takes an additional resource_usage argument to
+ gather various platform specific metrics about the child process.
- PDO_PGSQL:
- . getAttribute() can now retrieve the memory usage of query results.
- PDO::PGSQL_ATTR_RESULT_MEMORY_SIZE was added for this feature.
- . If the column is of FLOAT4OID/FLOAT8OID type, query returns it as a
- float instead of a string.
+ . PDO::pgsqlCopyFromArray now supports Iterable inputs.
+ . Pdo\Pgsql::setAttribute and Pdo\Pgsql::prepare support setting
+ PDO::ATTR_PREFETCH to 0 which enters lazy fetch mode.
+ In this mode, statements cannot be run in parallel.
-- PGSQL:
- . pg_select, the conditions arguments accepts an empty array and is optional.
+- PDO_SQLITE:
+ . SQLite PDO::quote() will now throw an exception or emit a warning,
+ depending on the error mode, if the string contains a null byte.
+ . PDO::sqliteCreateCollation will now throw an exception
+ if the callback has the wrong return type, making it more
+ in line with Pdo_Sqlite::createCollation behavior.
-- Phar:
- . Phar::setAlias() and Phar::setDefaultStub() methods now have a tentative
- return type of true instead of bool.
+- PGSQL:
+ . pg_copy_from now supports Iterable inputs.
+ . pg_connect checks if the connection_string argument contains
+ any null byte.
+ . pg_close_stmt checks if the statement_name argument contains
+ any null byte.
- POSIX:
- . posix_isatty now sets the error number when the file descriptor/stream argument
- is invalid.
+ . posix_ttyname sets last_error to EBADF when encountering
+ an invalid file descriptor.
+ . posix_isatty raises an E_WARNING message when encountering
+ an invalid file descriptor.
+ . posix_fpathconf checks invalid file descriptors and sets
+ last_error to EBADF and raises an E_WARNING message.
+ . posix_kill throws a ValueError when the process_id argument is lower
+ or greater than what the platform supports (signed integer or long
+ range), posix_setpgid throws a ValueError when the process_id or
+ the process_group_id is lower than zero or greater than
+ what the platform supports.
+ . posix_setrlimit throws a ValueError when the hard_limit or soft_limit
+ arguments are lower than -1 or if soft_limit is greater than hard_limit.
- Reflection:
- . ReflectionGenerator::getFunction() may now be called after the generator
- finished executing.
+ . The output of ReflectionClass::__toString() for enums has changed to
+ better indicate that the class is an enum, and that the enum cases
+ are enum cases rather than normal class constants.
+ . The output of ReflectionProperty::__toString() for properties with
+ hooks has changed to indicate what hooks the property has, whether those
+ hooks are final, and whether the property is virtual. This also affects
+ the output of ReflectionClass::__toString() when a class contains hooked
+ properties.
+ . ReflectionAttribute::newInstance() can now throw errors for internal
+ attributes if the attribute was applied on an invalid target and the
+ error was delayed from compile time to runtime via the
+ #[\DelayedTargetValidation] attribute.
+ RFC: https://wiki.php.net/rfc/delayedtargetvalidation_attribute
+
+- Session:
+ . session_start is stricter in regard to the options argument.
+ It throws a ValueError if the array is not a hashmap, or
+ a TypeError if the read_and_close value is not a valid type
+ compatible with int.
+
+- SNMP:
+ . snmpget, snmpset, snmp_get2, snmp_set2, snmp_get3, snmp_set3
+ and SNMP::__construct() throw a ValueError when the hostname
+ is too large, contains any null byte or if the port is given
+ when negative or greater than 65535, timeout and retries values
+ are lower than -1 or too large.
- Sockets:
- . Parameter $backlog of socket_create_listen() now has a default value of SOMAXCONN.
- Previously, it was 128.
+ . socket_create_listen, socket_bind and socket_sendto throw a
+ ValueError if the port is lower than 0 or greater than 65535,
+ and also if any of the hints array entries are indexed numerically.
+ . socket_addrinfo_lookup throws a TypeError if any of the hints
+ values cannot be cast to int and can throw a ValueError if
+ any of these values overflow.
+ . socket_set_option with MCAST_LEAVE_GROUP/MCAST_LEAVE_SOURCE_GROUP
+ options will throw an exception if the value isn't a valid object
+ or array.
+ . socket_create/socket_bind can create AF_PACKET family sockets.
+ . socket_getsockname gets the interface index and its string
+ representation with AF_PACKET socket.
+ . socket_set_option with multicast context throws a ValueError
+ when the created socket is not of AF_INET/AF_INET6 family.
-- SPL:
- . SplPriorityQueue::insert() and SplPriorityQueue::recoverFromCorruption()
- now has a tentative return type of true
- . SplHeap::insert() and SplHeap::recoverFromCorruption()
- now has a tentative return type of true instead of bool
+- Tidy:
+ . tidy::__construct/parseFile/parseString now throws a ValueError if the
+ configuration contains an invalid value or attempts to set a read-only
+ internal entry, and a TypeError if a configuration key is not a string.
-- Standard:
- . The internal implementation for rounding to integers has been rewritten
- to be easier to verify for correctness and to be easier to maintain.
- Some rounding bugs have been fixed as a result of the rewrite. For
- example previously rounding 0.49999999999999994 to the nearest integer
- would have resulted in 1.0 instead of the correct result 0.0. Additional
- inputs might also be affected and result in different outputs compared to
- earlier PHP versions.
- . The $mode parameter of the round() function has been widened to RoundingMode|int,
- accepting instances of a new RoundingMode enum.
- RFC: https://wiki.php.net/rfc/correctly_name_the_rounding_mode_and_make_it_an_enum
- . Four new modes have been added to the round() function: RoundingMode::PositiveInfinity,
- RoundingMode::NegativeInfinity, RoundingMode::TowardsZero, RoundingMode::AwayFromZero.
- RFC: https://wiki.php.net/rfc/new_rounding_modes_to_round_function
- . Fixed a bug caused by "pre-rounding" of the round() function. Previously, using
- "pre-rounding" to treat a value like 0.285 (actually 0.28499999999999998) as a
- decimal number and round it to 0.29. However, "pre-rounding" incorrectly rounds
- certain numbers, so this fix removes "pre-rounding" and changes the way numbers
- are compared, so that the values are correctly rounded as decimal numbers.
- . The maximum precision that can be handled by round() has been extended by one
- digit. For example, `round(4503599627370495.5)` returned in `4503599627370495.5`,
- but now returns `4503599627370496`.
- . The default value of the 'cost' option for PASSWORD_BCRYPT for password_hash()
- has been increased from '10' to '12'.
- RFC: https://wiki.php.net/rfc/bcrypt_cost_2023
- . debug_zval_dump() now indicates whether an array is packed.
- . long2ip() now returns string instead of string|false.
- . output_add_rewrite_var() now uses url_rewriter.hosts instead of
- session.trans_sid_hosts for selecting hosts that will be rewritten.
- . highlight_string() now has a return type of string|true instead of string|bool.
- . print_r() now has a return type of string|true instead of string|bool.
+- Zlib:
+ . The "use_include_path" argument for the
+ gzfile, gzopen and readgzfile functions has been changed
+ from int to boolean.
+ . gzfile, gzopen and readgzfile functions now respect the default
+ stream context.
========================================
6. New Functions
diff --cc ext/bcmath/libbcmath/src/round.c
index 44df6036cbe,a495221ff00..046493b9265
--- a/ext/bcmath/libbcmath/src/round.c
+++ b/ext/bcmath/libbcmath/src/round.c
@@@ -68,18 -67,16 +68,16 @@@ size_t bc_round(bc_num num, zend_long p
if (bc_is_zero(num)) {
*result = bc_copy_num(BCG(_zero_));
- return;
+ return 0;
}
- /* If precision is -3, it becomes 1000. */
- if (UNEXPECTED(precision == ZEND_LONG_MIN)) {
- *result = bc_new_num((size_t) ZEND_LONG_MAX + 2, 0);
- } else {
- *result = bc_new_num(-precision + 1, 0);
- }
+ /* If precision is -3, it becomes 1000. Negate in unsigned space so
+ * precision == ZEND_LONG_MIN doesn't overflow signed long. */
+ zend_ulong magnitude = -(zend_ulong) precision;
+ *result = bc_new_num((size_t) magnitude + 1, 0);
(*result)->n_value[0] = 1;
(*result)->n_sign = num->n_sign;
- return;
+ return 0;
}
/* Just like bcadd('1', '1', 4) becomes '2.0000', it pads with zeros at the end if necessary. */