ext/readline: Fix non-ASCII completion append characters in readline_info() (#24263)

The first byte of completion_append_character could become negative when
plain char is signed. Subsequent readline_info() calls would then use an
invalid index into the one-character string table and could crash.

Read the byte as unsigned char to keep the value within the valid range.
Add a regression test covering ASCII, non-ASCII, and empty strings.

Closes #24263
This commit is contained in:
Weilin Du committed 2026-10-13 00:04:19 +08:00
1 parent 785f7140d3
commit 55e44ee2ff
3 files changed
+32 -1

No files matched your search

+4
View File
@@ -49,6 +49,10 @@ PHP NEWS
- Phpdbg:
. Fix wrong command names. (ndossche, Weilin Du)
- Readline:
. Fixed a crash in readline_info() when completion_append_character
contains a non-ASCII byte. (Weilin Du)
- SOAP:
. Fixed use of uninitialized func in do_request() on OOM bailout.
(David Carlier)
+1 -1
View File
@@ -248,7 +248,7 @@ PHP_FUNCTION(readline_info)
if (!try_convert_to_string(value)) {
RETURN_THROWS();
}
rl_completion_append_character = (int)Z_STRVAL_P(value)[0];
rl_completion_append_character = (unsigned char)Z_STRVAL_P(value)[0];
}
RETVAL_INTERNED_STR(
oldval == 0 ? ZSTR_EMPTY_ALLOC() : ZSTR_CHAR(oldval));
@@ -0,0 +1,27 @@
--TEST--
readline_info(): completion_append_character supports non-ASCII bytes
--EXTENSIONS--
readline
--SKIPIF--
<?php
if (READLINE_LIB !== 'readline') die('skip readline only');
?>
--FILE--
<?php
readline_info('completion_append_character', '');
foreach (["\x7f", "\x80", "\xfftail", ''] as $value) {
$old = readline_info('completion_append_character', $value);
$current = readline_info('completion_append_character');
$info = readline_info();
printf("old=%s current=%s info=%s\n",
bin2hex($old),
bin2hex($current),
bin2hex($info['completion_append_character'])
);
}
?>
--EXPECT--
old= current=7f info=7f
old=7f current=80 info=80
old=80 current=ff info=ff
old=ff current= info=