From a33be66344ae88fcc5d013a4bf71fc1f2ffcd4ad Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Wed, 10 May 2023 14:12:27 +0200 Subject: [PATCH 1/2] Fix segfault in mb_strrpos/mb_strripos with ASCII encoding and negative offset We're setting the encoding from PHP_FUNCTION(mb_strpos), but mbfl_strpos would discard it, setting it to mbfl_encoding_pass, making zend_memnrstr fail due to a null-pointer exception. Fixes GH-11217 --- ext/mbstring/libmbfl/mbfl/mbfilter.c | 4 ++-- ext/mbstring/tests/gh11217.phpt | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 ext/mbstring/tests/gh11217.phpt diff --git a/ext/mbstring/libmbfl/mbfl/mbfilter.c b/ext/mbstring/libmbfl/mbfl/mbfilter.c index 5f5ce07ce6f66..a517c12c72e02 100644 --- a/ext/mbstring/libmbfl/mbfl/mbfilter.c +++ b/ext/mbstring/libmbfl/mbfl/mbfilter.c @@ -594,7 +594,7 @@ mbfl_strpos( const unsigned char *offset_pointer; if (haystack->encoding->no_encoding != mbfl_no_encoding_utf8) { - mbfl_string_init(&_haystack_u8); + mbfl_string_init_set(&_haystack_u8, haystack->encoding); haystack_u8 = mbfl_convert_encoding(haystack, &_haystack_u8, &mbfl_encoding_utf8); if (haystack_u8 == NULL) { result = MBFL_ERROR_ENCODING; @@ -605,7 +605,7 @@ mbfl_strpos( } if (needle->encoding->no_encoding != mbfl_no_encoding_utf8) { - mbfl_string_init(&_needle_u8); + mbfl_string_init_set(&_needle_u8, needle->encoding); needle_u8 = mbfl_convert_encoding(needle, &_needle_u8, &mbfl_encoding_utf8); if (needle_u8 == NULL) { result = MBFL_ERROR_ENCODING; diff --git a/ext/mbstring/tests/gh11217.phpt b/ext/mbstring/tests/gh11217.phpt new file mode 100644 index 0000000000000..d500f22cbd7bb --- /dev/null +++ b/ext/mbstring/tests/gh11217.phpt @@ -0,0 +1,12 @@ +--TEST-- +GH-11217: Segfault in mb_strrpos/mb_strripos with ASCII encoding and negative offset +--EXTENSIONS-- +mbstring +--FILE-- + +--EXPECT-- +int(0) +int(0) From c688497cb7e05f91b45ea7c482178fd0c870029a Mon Sep 17 00:00:00 2001 From: Randy Geraads Date: Wed, 10 May 2023 13:25:39 +0200 Subject: [PATCH 2/2] Added negative offset test for mb_strrpos Should expose https://github.com/php/php-src/issues/11217 --- ext/mbstring/tests/mb_strrpos_basic.phpt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ext/mbstring/tests/mb_strrpos_basic.phpt b/ext/mbstring/tests/mb_strrpos_basic.phpt index 28e038da406bc..599dfd38da12a 100644 --- a/ext/mbstring/tests/mb_strrpos_basic.phpt +++ b/ext/mbstring/tests/mb_strrpos_basic.phpt @@ -22,6 +22,9 @@ var_dump(mb_strrpos($string_ascii, 'is', 4, 'ISO-8859-1')); echo "\n-- ASCII string 2 --\n"; var_dump(mb_strrpos($string_ascii, 'hello, world')); +echo "\n-- ASCII string with negative offset --\n"; +var_dump(mb_strrpos($string_ascii, 'hello', -1, 'ISO-8859-1')); + echo "\n-- Multibyte string 1 --\n"; $needle1 = base64_decode('44CC'); var_dump(mb_strrpos($string_mb, $needle1)); @@ -41,6 +44,9 @@ int(15) -- ASCII string 2 -- bool(false) +-- ASCII string with negative offset -- +bool(false) + -- Multibyte string 1 -- int(20)