Skip to content

Commit e8dfd8e

Browse files
committed
Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4: ext/intl: Fix overlapping grapheme matches with negative search offsets (#24028)
2 parents 0a8c4e0 + be5442d commit e8dfd8e

3 files changed

Lines changed: 40 additions & 0 deletions

File tree

‎NEWS‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ PHP NEWS
7272
. Fixed grapheme_strstr() and grapheme_strpos() missing canonically
7373
equivalent matches, and grapheme searches reporting ICU errors for empty
7474
haystacks. (Weilin Du)
75+
. Fixed grapheme_strrpos() and grapheme_strripos() skipping overlapping matches
76+
when using a negative offset. (Weilin Du)
7577

7678
- Lexbor:
7779
. Merge patches lexbor/lexbor@8a14bc0 and lexbor/lexbor@f67ce4b, fixing a

‎ext/intl/grapheme/grapheme_util.c‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,12 @@ int32_t grapheme_strpos_utf16(char *haystack, size_t haystack_len, char *needle,
184184
break;
185185
}
186186
prev_pos = char_pos;
187+
int32_t next_pos = ubrk_following(bi, char_pos);
188+
if (next_pos == UBRK_DONE) {
189+
break;
190+
}
191+
usearch_setOffset(src, next_pos, &status);
192+
STRPOS_CHECK_STATUS(status, "Invalid search offset");
187193
} while(1);
188194
}
189195
} else {
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
--TEST--
2+
grapheme_strrpos() and grapheme_strripos() find overlapping matches with negative offsets
3+
--EXTENSIONS--
4+
intl
5+
--FILE--
6+
<?php
7+
foreach (['a', "\u{00E9}", "e\u{0301}", "\u{1F600}"] as $grapheme) {
8+
foreach (['grapheme_strrpos', 'grapheme_strripos'] as $function) {
9+
$positions = [];
10+
foreach ([0, 1, -1, -2, -3] as $offset) {
11+
$positions[] = $function(str_repeat($grapheme, 3), str_repeat($grapheme, 2), $offset);
12+
}
13+
echo $function, ': ', implode(', ', $positions), "\n";
14+
}
15+
}
16+
17+
var_dump(grapheme_strripos("\u{00C9}\u{00E9}\u{00C9}", "\u{00E9}\u{00E9}", -1));
18+
var_dump(grapheme_strrpos("\u{00E9}\u{00E9}x\u{00E9}\u{00E9}", "\u{00E9}\u{00E9}", -1));
19+
var_dump(grapheme_strrpos("\u{00E9}\u{00E9}x\u{00E9}\u{00E9}", "\u{00E9}\u{00E9}", -3));
20+
?>
21+
--EXPECT--
22+
grapheme_strrpos: 1, 1, 1, 1, 0
23+
grapheme_strripos: 1, 1, 1, 1, 0
24+
grapheme_strrpos: 1, 1, 1, 1, 0
25+
grapheme_strripos: 1, 1, 1, 1, 0
26+
grapheme_strrpos: 1, 1, 1, 1, 0
27+
grapheme_strripos: 1, 1, 1, 1, 0
28+
grapheme_strrpos: 1, 1, 1, 1, 0
29+
grapheme_strripos: 1, 1, 1, 1, 0
30+
int(1)
31+
int(3)
32+
int(0)

0 commit comments

Comments
 (0)