ext/mbstring: Refactor mb_trim_width() to take size_t arguments

This commit is contained in:
Gina Peter Banyard 2023-11-22 17:48:13 +00:00
parent 284b66be46
commit a6775c30c0
No known key found for this signature in database
GPG key ID: 3306078E3194AEBD

View file

@ -2518,14 +2518,14 @@ PHP_FUNCTION(mb_strwidth)
RETVAL_LONG(mb_get_strwidth(string, enc)); RETVAL_LONG(mb_get_strwidth(string, enc));
} }
static zend_string* mb_trim_string(zend_string *input, zend_string *marker, const mbfl_encoding *enc, unsigned int from, int width) static zend_string* mb_trim_string(zend_string *input, zend_string *marker, const mbfl_encoding *enc, size_t from, size_t width)
{ {
uint32_t wchar_buf[128]; uint32_t wchar_buf[128];
unsigned char *in = (unsigned char*)ZSTR_VAL(input); unsigned char *in = (unsigned char*)ZSTR_VAL(input);
size_t in_len = ZSTR_LEN(input); size_t in_len = ZSTR_LEN(input);
unsigned int state = 0; unsigned int state = 0;
int remaining_width = width; size_t remaining_width = width;
unsigned int to_skip = from; size_t to_skip = from;
size_t out_len = 0; size_t out_len = 0;
bool first_call = true, input_err = false; bool first_call = true, input_err = false;
mb_convert_buf buf; mb_convert_buf buf;
@ -2537,17 +2537,23 @@ static zend_string* mb_trim_string(zend_string *input, zend_string *marker, cons
if (out_len <= to_skip) { if (out_len <= to_skip) {
to_skip -= out_len; to_skip -= out_len;
} else { } else {
for (unsigned int i = to_skip; i < out_len; i++) { for (size_t i = to_skip; i < out_len; i++) {
uint32_t w = wchar_buf[i]; uint32_t w = wchar_buf[i];
size_t current_w_width = character_width(w);
input_err |= (w == MBFL_BAD_INPUT); input_err |= (w == MBFL_BAD_INPUT);
remaining_width -= character_width(w);
if (remaining_width < 0) { if (remaining_width < current_w_width) {
/* We need to truncate string and append trim marker */ size_t marker_width = mb_get_strwidth(marker, enc);
width -= mb_get_strwidth(marker, enc);
/* 'width' is now the amount we want to take from 'input' */ /* The trim marker is larger than the desired string width */
if (width <= 0) { if (width <= marker_width) {
return zend_string_copy(marker); return zend_string_copy(marker);
} }
/* We need to truncate string and append trim marker */
width -= marker_width;
/* 'width' is now the amount we want to take from 'input' */
mb_convert_buf_init(&buf, width, MBSTRG(current_filter_illegal_substchar), MBSTRG(current_filter_illegal_mode)); mb_convert_buf_init(&buf, width, MBSTRG(current_filter_illegal_substchar), MBSTRG(current_filter_illegal_mode));
if (first_call) { if (first_call) {
@ -2558,6 +2564,7 @@ static zend_string* mb_trim_string(zend_string *input, zend_string *marker, cons
goto restart_conversion; goto restart_conversion;
} }
} }
remaining_width -= current_w_width;
} }
to_skip = 0; to_skip = 0;
} }
@ -2597,12 +2604,13 @@ dont_restart_conversion:
if (out_len <= from) { if (out_len <= from) {
from -= out_len; from -= out_len;
} else { } else {
for (unsigned int i = from; i < out_len; i++) { for (size_t i = from; i < out_len; i++) {
width -= character_width(wchar_buf[i]); size_t current_wchar_char_width = character_width(wchar_buf[i]);
if (width < 0) { if (width < current_wchar_char_width) {
enc->from_wchar(wchar_buf + from, i - from, &buf, true); enc->from_wchar(wchar_buf + from, i - from, &buf, true);
goto append_trim_marker; goto append_trim_marker;
} }
width -= current_wchar_char_width;
} }
ZEND_ASSERT(in_len > 0); ZEND_ASSERT(in_len > 0);
enc->from_wchar(wchar_buf + from, out_len - from, &buf, false); enc->from_wchar(wchar_buf + from, out_len - from, &buf, false);