Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
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
11 changes: 11 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ PHP NEWS
. Fixed bug GH-19679 (zend_ssa_range_widening may fail to converge). (Arnaud)
. Using null as an array offset or when calling array_key_exists() is now
deprecated. (alexandre-daubois)
. Fixed bug GH-19681 (PHP_EXPAND_PATH broken with bash 5.3.0). (Remi)

- CLI:
. Fixed bug GH-19461 (Improve error message on listening error with IPv6
address). (alexandre-daubois)

- Date:
. Fixed date_sunrise() and date_sunset() with partial-hour UTC offset.
Expand All @@ -35,12 +40,18 @@ PHP NEWS
- PDO:
. Driver specific methods in the PDO class are now deprecated. (Arnaud)

- Reflection:
. Fix GH-19691 (getModifierNames() not reporting asymmetric visibility).
(DanielEScherzer)

- Session:
. Fix RC violation of session SID constant deprecation attribute. (ilutov)

- Standard:
. Fix GH-19610 (Deprecation warnings in functions taking as argument).
(Girgias)
. Fixed bug GH-19577 (Avoid integer overflow when using a small offset
and PHP_INT_MAX with LimitIterator). (alexandre-daubois)

- Streams:
. Fixed bug GH-14506 (Closing a userspace stream inside a userspace handler
Expand Down
18 changes: 0 additions & 18 deletions Zend/zend_alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -379,24 +379,6 @@ static const uint32_t bin_pages[] = {
ZEND_MM_BINS_INFO(_BIN_DATA_PAGES, x, y)
};

#if ZEND_DEBUG
ZEND_COLD void zend_debug_alloc_output(char *format, ...)
{
char output_buf[256];
va_list args;

va_start(args, format);
vsprintf(output_buf, format, args);
va_end(args);

#ifdef ZEND_WIN32
OutputDebugString(output_buf);
#else
fprintf(stderr, "%s", output_buf);
#endif
}
#endif

static ZEND_COLD ZEND_NORETURN void zend_mm_panic(const char *message)
{
fprintf(stderr, "%s\n", message);
Expand Down
6 changes: 5 additions & 1 deletion build/php.m4
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,11 @@ AC_DEFUN([PHP_EXPAND_PATH],[
changequote({,})
ep_dir=$(echo $1|$SED 's%/*[^/][^/]*/*$%%')
changequote([,])
ep_realdir=$(cd "$ep_dir" && pwd)
if test -z $ep_dir ; then
ep_realdir=$(pwd)
else
ep_realdir=$(cd "$ep_dir" && pwd)
fi
$2="$ep_realdir"/$(basename "$1")
fi
])
Expand Down
10 changes: 4 additions & 6 deletions ext/pdo_firebird/firebird_statement.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ static int get_formatted_time_tz(pdo_stmt_t *stmt, const ISC_TIME_TZ* timeTz, zv
struct tm t;
ISC_TIME time;
char timeBuf[80] = {0};
char timeTzBuf[124] = {0};
if (fb_decode_time_tz(S->H->isc_status, timeTz, &hours, &minutes, &seconds, &fractions, sizeof(timeZoneBuffer), timeZoneBuffer)) {
return 1;
}
Expand All @@ -100,8 +99,8 @@ static int get_formatted_time_tz(pdo_stmt_t *stmt, const ISC_TIME_TZ* timeTz, zv
return 1;
}

size_t time_tz_len = sprintf(timeTzBuf, "%s %s", timeBuf, timeZoneBuffer);
ZVAL_STRINGL(result, timeTzBuf, time_tz_len);
zend_string *time_tz_str = zend_strpprintf(0, "%s %s", timeBuf, timeZoneBuffer);
ZVAL_NEW_STR(result, time_tz_str);
return 0;
}

Expand All @@ -115,7 +114,6 @@ static int get_formatted_timestamp_tz(pdo_stmt_t *stmt, const ISC_TIMESTAMP_TZ*
struct tm t;
ISC_TIMESTAMP ts;
char timestampBuf[80] = {0};
char timestampTzBuf[124] = {0};
if (fb_decode_timestamp_tz(S->H->isc_status, timestampTz, &year, &month, &day, &hours, &minutes, &seconds, &fractions, sizeof(timeZoneBuffer), timeZoneBuffer)) {
return 1;
}
Expand All @@ -130,8 +128,8 @@ static int get_formatted_timestamp_tz(pdo_stmt_t *stmt, const ISC_TIMESTAMP_TZ*
return 1;
}

size_t timestamp_tz_len = sprintf(timestampTzBuf, "%s %s", timestampBuf, timeZoneBuffer);
ZVAL_STRINGL(result, timestampTzBuf, timestamp_tz_len);
zend_string *timestamp_tz_str = zend_strpprintf(0, "%s %s", timestampBuf, timeZoneBuffer);
ZVAL_NEW_STR(result, timestamp_tz_str);
return 0;
}

Expand Down
9 changes: 9 additions & 0 deletions ext/reflection/php_reflection.c
Original file line number Diff line number Diff line change
Expand Up @@ -1713,6 +1713,15 @@ ZEND_METHOD(Reflection, getModifierNames)
add_next_index_stringl(return_value, "protected", sizeof("protected")-1);
break;
}
/* These are also mutually exclusive */
switch (modifiers & ZEND_ACC_PPP_SET_MASK) {
case ZEND_ACC_PROTECTED_SET:
add_next_index_stringl(return_value, "protected(set)", sizeof("protected(set)")-1);
break;
case ZEND_ACC_PRIVATE_SET:
add_next_index_stringl(return_value, "private(set)", sizeof("private(set)")-1);
break;
}

if (modifiers & ZEND_ACC_STATIC) {
add_next_index_str(return_value, ZSTR_KNOWN(ZEND_STR_STATIC));
Expand Down
4 changes: 4 additions & 0 deletions ext/reflection/tests/Reflection_getModifierNames_001.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ printModifiers(ReflectionMethod::IS_ABSTRACT | ReflectionMethod::IS_FINAL);
printModifiers(ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_STATIC | ReflectionProperty::IS_READONLY);
printModifiers(ReflectionClass::IS_READONLY);
printModifiers(ReflectionProperty::IS_VIRTUAL);
printModifiers(ReflectionProperty::IS_PROTECTED_SET);
printModifiers(ReflectionProperty::IS_PRIVATE_SET);
?>
--EXPECT--
private
Expand All @@ -25,3 +27,5 @@ abstract,final
public,static,readonly
readonly
virtual
protected(set)
private(set)
25 changes: 19 additions & 6 deletions ext/spl/spl_iterators.c
Original file line number Diff line number Diff line change
Expand Up @@ -2115,14 +2115,27 @@ static zend_object *spl_dual_it_new(zend_class_entry *class_type)
}
/* }}} */

/* Returns the relative position for the current iterator position. */
static zend_long spl_limit_it_relative_pos(spl_dual_it_object *intern)
{
return intern->current.pos - intern->u.limit.offset;
}

/* Returns the relative position for an arbitrary position. */
static zend_long spl_limit_it_relative_pos_for(spl_dual_it_object *intern, zend_long pos)
{
return pos - intern->u.limit.offset;
}

static inline zend_result spl_limit_it_valid(spl_dual_it_object *intern)
{
/* FAILURE / SUCCESS */
if (intern->u.limit.count != -1 && intern->current.pos >= intern->u.limit.offset + intern->u.limit.count) {
if (intern->u.limit.count != -1 &&
spl_limit_it_relative_pos(intern) >= intern->u.limit.count) {
return FAILURE;
} else {
return spl_dual_it_valid(intern);
}

return spl_dual_it_valid(intern);
}

static inline void spl_limit_it_seek(spl_dual_it_object *intern, zend_long pos)
Expand All @@ -2134,7 +2147,7 @@ static inline void spl_limit_it_seek(spl_dual_it_object *intern, zend_long pos)
zend_throw_exception_ex(spl_ce_OutOfBoundsException, 0, "Cannot seek to " ZEND_LONG_FMT " which is below the offset " ZEND_LONG_FMT, pos, intern->u.limit.offset);
return;
}
if (pos - intern->u.limit.offset >= intern->u.limit.count && intern->u.limit.count != -1) {
if (spl_limit_it_relative_pos_for(intern, pos) >= intern->u.limit.count && intern->u.limit.count != -1) {
zend_throw_exception_ex(spl_ce_OutOfBoundsException, 0, "Cannot seek to " ZEND_LONG_FMT " which is behind offset " ZEND_LONG_FMT " plus count " ZEND_LONG_FMT, pos, intern->u.limit.offset, intern->u.limit.count);
return;
}
Expand Down Expand Up @@ -2191,7 +2204,7 @@ PHP_METHOD(LimitIterator, valid)
SPL_FETCH_AND_CHECK_DUAL_IT(intern, ZEND_THIS);

/* RETURN_BOOL(spl_limit_it_valid(intern) == SUCCESS);*/
RETURN_BOOL((intern->u.limit.count == -1 || intern->current.pos < intern->u.limit.offset + intern->u.limit.count) && Z_TYPE(intern->current.data) != IS_UNDEF);
RETURN_BOOL((intern->u.limit.count == -1 || spl_limit_it_relative_pos(intern) < intern->u.limit.count) && Z_TYPE(intern->current.data) != IS_UNDEF);
} /* }}} */

/* {{{ Move the iterator forward */
Expand All @@ -2204,7 +2217,7 @@ PHP_METHOD(LimitIterator, next)
SPL_FETCH_AND_CHECK_DUAL_IT(intern, ZEND_THIS);

spl_dual_it_next(intern, 1);
if (intern->u.limit.count == -1 || intern->current.pos < intern->u.limit.offset + intern->u.limit.count) {
if (intern->u.limit.count == -1 || spl_limit_it_relative_pos(intern) < intern->u.limit.count) {
spl_dual_it_fetch(intern, 1);
}
} /* }}} */
Expand Down
16 changes: 16 additions & 0 deletions ext/spl/tests/gh19577.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
--TEST--
GH-19577: Integer overflow in LimitIterator with small offset and PHP_INT_MAX count
--FILE--
<?php

$it = new ArrayIterator(array(0 => 'A', 1 => 'B', 2 => 'C', 3 => 'D'));
$it = new LimitIterator($it, 2, PHP_INT_MAX);

foreach($it as $val => $key) {
echo "Key: $val, Value: $key\n";
}

?>
--EXPECT--
Key: 2, Value: C
Key: 3, Value: D
6 changes: 5 additions & 1 deletion sapi/cli/php_cli_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -2563,7 +2563,11 @@ static zend_result php_cli_server_ctor(php_cli_server *server, const char *addr,

server_sock = php_network_listen_socket(host, &port, SOCK_STREAM, &server->address_family, &server->socklen, &errstr);
if (server_sock == SOCK_ERR) {
php_cli_server_logf(PHP_CLI_SERVER_LOG_ERROR, "Failed to listen on %s:%d (reason: %s)", host, port, errstr ? ZSTR_VAL(errstr) : "?");
if (strchr(host, ':')) {
php_cli_server_logf(PHP_CLI_SERVER_LOG_ERROR, "Failed to listen on [%s]:%d (reason: %s)", host, port, errstr ? ZSTR_VAL(errstr) : "?");
} else {
php_cli_server_logf(PHP_CLI_SERVER_LOG_ERROR, "Failed to listen on %s:%d (reason: %s)", host, port, errstr ? ZSTR_VAL(errstr) : "?");
}
if (errstr) {
zend_string_release_ex(errstr, 0);
}
Expand Down
41 changes: 41 additions & 0 deletions sapi/cli/tests/php_cli_server_ipv4_error_message.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
--TEST--
IPv4 address error message formatting
--SKIPIF--
<?php
if (substr(PHP_OS, 0, 3) == 'WIN') {
die("skip not for Windows");
}
?>
--FILE--
<?php

$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("pipe", "w")
);

$process = proc_open(
PHP_BINARY . ' -S "192.168.1.999:8080"',
$descriptorspec,
$pipes
);

if (is_resource($process)) {
usleep(100000);

$stderr = stream_get_contents($pipes[2]);

fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);

proc_terminate($process);
proc_close($process);

var_dump($stderr);
}
?>
--EXPECTF--
string(%d) "[%s] Failed to listen on 192.168.1.999:8080 %s
"
40 changes: 40 additions & 0 deletions sapi/cli/tests/php_cli_server_ipv6_error_message.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
--TEST--
IPv6 address error message formatting
--SKIPIF--
<?php
if (substr(PHP_OS, 0, 3) == 'WIN') {
die("skip not for Windows");
}
?>
--FILE--
<?php
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("pipe", "w")
);

$process = proc_open(
PHP_BINARY . ' -S "[2001:db8::]:8080"',
$descriptorspec,
$pipes
);

if (is_resource($process)) {
usleep(100000);

$stderr = stream_get_contents($pipes[2]);

fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);

proc_terminate($process);
proc_close($process);

var_dump($stderr);
}
?>
--EXPECTF--
string(%d) "[%s] Failed to listen on [2001:db8::]:8080 %s
"