mirror of
https://github.com/Rockbox/rockbox.git
synced 2026-07-10 13:29:52 -04:00
bidi: do not pass non-ASCII codepoints to ispunct()
bidi_l2v() classified each character with ispunct((int)c), but c is a decoded Unicode codepoint. ispunct() is only defined for values that fit in an unsigned char (or EOF); a larger value is undefined behaviour, and glibc then reads past the ctype table and reports some codepoints as punctuation. Hebrew final kaf (U+05DA) and gimel (U+05D2) land on such entries, so a string ending in one had that letter trimmed off its RTL block as if it were trailing punctuation and moved to the wrong end of the line. Limit the punctuation test to ASCII so the result is well-defined. Change-Id: Ie6c3d8413f35ec3652e9228e3d5af05ef5bb811a
This commit is contained in:
parent
c7d5603c63
commit
5c02cf3b3c
1 changed files with 8 additions and 2 deletions
|
|
@ -39,6 +39,12 @@
|
|||
/* ischar() now lives in bidi.h as the shared is_rtl_char() macro */
|
||||
#define _isblank(c) ((c==' ' || c=='\t') ? 1 : 0)
|
||||
#define _isnewline(c) ((c=='\n' || c=='\r') ? 1 : 0)
|
||||
/* ctype ispunct() is only defined for unsigned char values; feeding it a
|
||||
* decoded Unicode codepoint (e.g. Hebrew final kaf U+05DA, gimel U+05D2) is
|
||||
* undefined and some libcs then mis-report it as punctuation, which trims the
|
||||
* final letter off its RTL block and throws it to the wrong end of the line.
|
||||
* Restrict the punctuation test to ASCII. */
|
||||
#define _ispunct(c) ((c) < 0x80 && ispunct((int)(c)))
|
||||
#define XOR(a,b) ((a||b) && !(a&&b))
|
||||
|
||||
#ifndef BOOTLOADER
|
||||
|
|
@ -203,7 +209,7 @@ ucschar_t *bidi_l2v(const unsigned char *str, int orientation)
|
|||
|
||||
do {
|
||||
while((XOR(is_rtl_char(*(tmp+1)),block_type)
|
||||
|| _isblank(*(tmp+1)) || ispunct((int)*(tmp+1))
|
||||
|| _isblank(*(tmp+1)) || _ispunct(*(tmp+1))
|
||||
|| *(tmp+1)=='\n')
|
||||
&& block_end < length-1) {
|
||||
tmp++;
|
||||
|
|
@ -212,7 +218,7 @@ ucschar_t *bidi_l2v(const unsigned char *str, int orientation)
|
|||
}
|
||||
|
||||
if (block_type != orientation) {
|
||||
while ((_isblank(*tmp) || ispunct((int)*tmp))
|
||||
while ((_isblank(*tmp) || _ispunct(*tmp))
|
||||
&& *tmp!='/' && *tmp!='-' && block_end>block_start) {
|
||||
tmp--;
|
||||
block_end--;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue