Skip to content

Commit e0a9940

Browse files
committed
Merge branch 'PHP-8.4' into PHP-8.5
2 parents 740d1f5 + 0d6ab53 commit e0a9940

3 files changed

Lines changed: 39 additions & 1 deletion

File tree

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ PHP NEWS
1818
. Fixed bug GH-22763 (JIT fails to clear ZREG_TYPE_ONLY after setting reg).
1919
(Arnaud)
2020

21+
- MBString:
22+
. Fixed bug GH-22779 (mb_strrpos() returns the wrong position for a negative
23+
offset in a non-UTF-8 encoding). (Eyüp Can Akman)
24+
2125
- Sockets:
2226
. Fixed socket_set_option() validation error messages for UDP_SEGMENT and
2327
SO_LINGER options. (Weilin Du)

ext/mbstring/mbstring.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1937,7 +1937,7 @@ static size_t mb_find_strpos(zend_string *haystack, zend_string *needle, const m
19371937
} else if (offset >= 0) {
19381938
found_pos = zend_memnrstr((const char*)offset_pointer, ZSTR_VAL(needle_u8), ZSTR_LEN(needle_u8), ZSTR_VAL(haystack_u8) + ZSTR_LEN(haystack_u8));
19391939
} else {
1940-
size_t needle_len = pointer_to_offset_utf8((unsigned char*)ZSTR_VAL(needle), (unsigned char*)ZSTR_VAL(needle) + ZSTR_LEN(needle));
1940+
size_t needle_len = pointer_to_offset_utf8((unsigned char*)ZSTR_VAL(needle_u8), (unsigned char*)ZSTR_VAL(needle_u8) + ZSTR_LEN(needle_u8));
19411941
offset_pointer = offset_to_pointer_utf8(offset_pointer, (unsigned char*)ZSTR_VAL(haystack_u8) + ZSTR_LEN(haystack_u8), needle_len);
19421942
if (!offset_pointer) {
19431943
offset_pointer = (unsigned char*)ZSTR_VAL(haystack_u8) + ZSTR_LEN(haystack_u8);

ext/mbstring/tests/gh22779.phpt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
--TEST--
2+
GH-22779: mb_strrpos() wrong result for a negative offset in a non-UTF-8 encoding
3+
--EXTENSIONS--
4+
mbstring
5+
--FILE--
6+
<?php
7+
/* mb_strrpos() with a negative offset must return the correct position in non-UTF-8 encodings. */
8+
$haystack = "\xA9\xA9X";
9+
$needle = "\xA9";
10+
foreach ([-1, -2, -3] as $offset) {
11+
var_dump(mb_strrpos($haystack, $needle, $offset, 'ISO-8859-1'));
12+
}
13+
var_dump(mb_strrpos("X\xA9", "\xA9", -1, 'ISO-8859-1'));
14+
var_dump(mb_strrpos("\x95Z\x95Z", "\x95", -1, 'Windows-1252'));
15+
var_dump(mb_strrpos("\x95Z\x95Z", "\x95", -2, 'Windows-1252'));
16+
// Two-byte needle in a single-byte encoding.
17+
var_dump(mb_strrpos("\xA9\xB0\xA9\xB0Z", "\xA9\xB0", -2, 'ISO-8859-1'));
18+
// Multibyte: "ああA" in Shift_JIS, needle "あ" (\x82\xA0).
19+
var_dump(mb_strrpos("\x82\xA0\x82\xA0A", "\x82\xA0", -2, 'SJIS'));
20+
var_dump(mb_strrpos("\x82\xA0\x82\xA0A", "\x82\xA0", -3, 'SJIS'));
21+
// UTF-16: an ASCII needle miscounts the other way.
22+
var_dump(mb_strrpos("\x00A\x00X\x00A", "\x00A", -2, 'UTF-16BE'));
23+
?>
24+
--EXPECT--
25+
int(1)
26+
int(1)
27+
int(0)
28+
int(1)
29+
int(2)
30+
int(2)
31+
int(2)
32+
int(1)
33+
int(0)
34+
int(0)

0 commit comments

Comments
 (0)