window: display_string: properly handle invalid multibyte characters
This commit is contained in:
@@ -93,12 +93,34 @@ void display_string()
|
|||||||
else
|
else
|
||||||
*w << ws;
|
*w << ws;
|
||||||
};
|
};
|
||||||
|
auto narrow_to_wide = [](wchar_t *dest, const char *src, size_t n) {
|
||||||
|
size_t result = 0;
|
||||||
|
// convert the string and substitute invalid multibyte chars with dots.
|
||||||
|
for (size_t i = 0; i < n;)
|
||||||
|
{
|
||||||
|
int ret = mbtowc(&dest[result], &src[i], n-i);
|
||||||
|
if (ret > 0)
|
||||||
|
{
|
||||||
|
i += ret;
|
||||||
|
++result;
|
||||||
|
}
|
||||||
|
else if (ret == -1)
|
||||||
|
{
|
||||||
|
dest[result] = L'.';
|
||||||
|
++i;
|
||||||
|
++result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw std::runtime_error("mbtowc: unexpected return value");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
// copy the part of the string that is before the cursor to pre_pos
|
// copy the part of the string that is before the cursor to pre_pos
|
||||||
char pt = rl_line_buffer[rl_point];
|
char pt = rl_line_buffer[rl_point];
|
||||||
rl_line_buffer[rl_point] = 0;
|
rl_line_buffer[rl_point] = 0;
|
||||||
wchar_t pre_pos[rl_point+1];
|
wchar_t pre_pos[rl_point+1];
|
||||||
pre_pos[mbstowcs(pre_pos, rl_line_buffer, rl_point)] = 0;
|
pre_pos[narrow_to_wide(pre_pos, rl_line_buffer, rl_point)] = 0;
|
||||||
rl_line_buffer[rl_point] = pt;
|
rl_line_buffer[rl_point] = pt;
|
||||||
|
|
||||||
int pos = wcswidth(pre_pos, rl_point);
|
int pos = wcswidth(pre_pos, rl_point);
|
||||||
@@ -118,7 +140,7 @@ void display_string()
|
|||||||
|
|
||||||
// ...and then print the rest char-by-char until there is no more area
|
// ...and then print the rest char-by-char until there is no more area
|
||||||
wchar_t post_pos[rl_end-rl_point+1];
|
wchar_t post_pos[rl_end-rl_point+1];
|
||||||
post_pos[mbstowcs(post_pos, rl_line_buffer+rl_point, rl_end-rl_point)] = 0;
|
post_pos[narrow_to_wide(post_pos, rl_line_buffer+rl_point, rl_end-rl_point)] = 0;
|
||||||
|
|
||||||
size_t cpos = pos;
|
size_t cpos = pos;
|
||||||
for (wchar_t *c = post_pos; *c != 0; ++c)
|
for (wchar_t *c = post_pos; *c != 0; ++c)
|
||||||
|
|||||||
Reference in New Issue
Block a user