Skip to content

Commit 55e44ee

Browse files
committed
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
1 parent 785f714 commit 55e44ee

3 files changed

Lines changed: 32 additions & 1 deletion

File tree

‎NEWS‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ PHP NEWS
4949
- Phpdbg:
5050
. Fix wrong command names. (ndossche, Weilin Du)
5151

52+
- Readline:
53+
. Fixed a crash in readline_info() when completion_append_character
54+
contains a non-ASCII byte. (Weilin Du)
55+
5256
- SOAP:
5357
. Fixed use of uninitialized func in do_request() on OOM bailout.
5458
(David Carlier)

‎ext/readline/readline.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ PHP_FUNCTION(readline_info)
248248
if (!try_convert_to_string(value)) {
249249
RETURN_THROWS();
250250
}
251-
rl_completion_append_character = (int)Z_STRVAL_P(value)[0];
251+
rl_completion_append_character = (unsigned char)Z_STRVAL_P(value)[0];
252252
}
253253
RETVAL_INTERNED_STR(
254254
oldval == 0 ? ZSTR_EMPTY_ALLOC() : ZSTR_CHAR(oldval));
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
readline_info(): completion_append_character supports non-ASCII bytes
3+
--EXTENSIONS--
4+
readline
5+
--SKIPIF--
6+
<?php
7+
if (READLINE_LIB !== 'readline') die('skip readline only');
8+
?>
9+
--FILE--
10+
<?php
11+
readline_info('completion_append_character', '');
12+
foreach (["\x7f", "\x80", "\xfftail", ''] as $value) {
13+
$old = readline_info('completion_append_character', $value);
14+
$current = readline_info('completion_append_character');
15+
$info = readline_info();
16+
printf("old=%s current=%s info=%s\n",
17+
bin2hex($old),
18+
bin2hex($current),
19+
bin2hex($info['completion_append_character'])
20+
);
21+
}
22+
?>
23+
--EXPECT--
24+
old= current=7f info=7f
25+
old=7f current=80 info=80
26+
old=80 current=ff info=ff
27+
old=ff current= info=

0 commit comments

Comments
 (0)