Skip to content

Commit b89fa3c

Browse files
committed
Stop grapheme_strrev from using UBRK_DONE as a byte index
ubrk_previous() returns UBRK_DONE after the first boundary. The loop condition ran before that assignment, so the body treated -1 as an offset and wrote into the zend_string NUL. Break when the iterator is done, and NUL-terminate the result of zend_string_alloc.
1 parent e5623ea commit b89fa3c

3 files changed

Lines changed: 33 additions & 0 deletions

File tree

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ PHP NEWS
2020
left busy for the next fetch, and rows delivered from a result another
2121
statement took over. (KentarouTakeda)
2222

23+
- Intl:
24+
. Fixed grapheme_strrev() treating UBRK_DONE as a byte index and leaving
25+
the result without a terminating NUL. (iliaal)
26+
2327
- Phar:
2428
. Fixed Phar archives being automatically detected when ".phar" only occurs
2529
in a directory name or is not a filename extension in an included file's

ext/intl/grapheme/grapheme_string.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,13 +1175,17 @@ U_CFUNC PHP_FUNCTION(grapheme_strrev)
11751175
current = ZSTR_LEN(string);
11761176
for (end = pstr; pos != UBRK_DONE; ) {
11771177
pos = ubrk_previous(bi);
1178+
if (pos == UBRK_DONE) {
1179+
break;
1180+
}
11781181
end_len = current - pos;
11791182
for (int32_t j = 0; j < end_len; j++) {
11801183
*p++ = *(pstr + pos + j);
11811184
}
11821185
current = pos;
11831186
}
11841187
ubrk_end:
1188+
ZSTR_VAL(ret)[ZSTR_LEN(ret)] = '\0';
11851189
RETVAL_NEW_STR(ret);
11861190
ubrk_close(bi);
11871191
close:
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--TEST--
2+
grapheme_strrev() stops at UBRK_DONE instead of using it as a byte index
3+
--EXTENSIONS--
4+
intl
5+
--FILE--
6+
<?php
7+
8+
$cases = [
9+
'abc',
10+
'a',
11+
'土下座',
12+
"null\x00byte",
13+
];
14+
15+
foreach ($cases as $s) {
16+
$rev = grapheme_strrev($s);
17+
echo strlen($s), ' ', strlen($rev), ' ', bin2hex($rev), "\n";
18+
}
19+
20+
?>
21+
--EXPECT--
22+
3 3 636261
23+
1 1 61
24+
9 9 e5baa7e4b88be59c9f
25+
9 9 65747962006c6c756e

0 commit comments

Comments
 (0)