Changeset 0600976 in mainline for common/stdc/uchar.c


Ignore:
Timestamp:
2025-04-14T11:23:38Z (3 months ago)
Author:
Jiří Zárevúcky <zarevucky.jiri@…>
Branches:
master
Children:
5d2bdaa
Parents:
11782da
git-author:
Jiří Zárevúcky <zarevucky.jiri@…> (2025-04-14 10:57:38)
git-committer:
Jiří Zárevúcky <zarevucky.jiri@…> (2025-04-14 11:23:38)
Message:

Reject invalid non-shortest UTF-8 forms and fix some other issues in str

File:
1 edited

Legend:

Unmodified
Added
Removed
  • common/stdc/uchar.c

    r11782da r0600976  
    8484}
    8585
     86static bool _is_non_shortest(unsigned short cont, uint8_t b)
     87{
     88        return (cont == 0b1111110000000000 && !(b & 0b00100000)) ||
     89            (cont == 0b1111111111110000 && !(b & 0b00110000));
     90}
     91
    8692size_t mbrtoc32(char32_t *c, const char *s, size_t n, mbstate_t *mb)
    8793{
     
    139145
    140146                if (_is_2_byte(b)) {
     147                        /* Reject non-shortest form. */
     148                        if (!(b & 0b00011110)) {
     149                                _set_ilseq();
     150                                return UCHAR_ILSEQ;
     151                        }
     152
    141153                        /* 2 byte encoding               110xxxxx */
    142154                        mb->continuation = b ^ 0b0000000011000000;
     
    152164        }
    153165
    154         while (i < n) {
     166        for (; i < n; i++) {
    155167                /* Read continuation bytes. */
    156 
    157                 if (!_is_continuation(s[i])) {
     168                uint8_t b = s[i];
     169
     170                if (!_is_continuation(b) || _is_non_shortest(mb->continuation, b)) {
    158171                        _set_ilseq();
    159172                        return UCHAR_ILSEQ;
     
    162175                /* Top bit becomes zero just before the last byte is shifted in. */
    163176                if (!(mb->continuation & 0x8000)) {
    164                         *c = ((char32_t) mb->continuation) << 6 | (s[i++] & 0x3f);
     177                        *c = ((char32_t) mb->continuation) << 6 | (b & 0x3f);
    165178                        mb->continuation = 0;
    166                         return i;
    167                 }
    168 
    169                 mb->continuation = mb->continuation << 6 | (s[i++] & 0x3f);
     179                        return ++i;
     180                }
     181
     182                mb->continuation = mb->continuation << 6 | (b & 0x3f);
    170183        }
    171184
Note: See TracChangeset for help on using the changeset viewer.