fix undefined left-shift of negative values in utf-8 state table
[musl] / src / multibyte / wcsrtombs.c
1 /* 
2  * This code was written by Rich Felker in 2010; no copyright is claimed.
3  * This code is in the public domain. Attribution is appreciated but
4  * unnecessary.
5  */
6
7 #include <wchar.h>
8
9 size_t wcsrtombs(char *restrict s, const wchar_t **restrict ws, size_t n, mbstate_t *restrict st)
10 {
11         const wchar_t *ws2;
12         char buf[4];
13         size_t N = n, l;
14         if (!s) {
15                 for (n=0, ws2=*ws; *ws2; ws2++) {
16                         if (*ws2 >= 0x80u) {
17                                 l = wcrtomb(buf, *ws2, 0);
18                                 if (!(l+1)) return -1;
19                                 n += l;
20                         } else n++;
21                 }
22                 return n;
23         }
24         while (n>=4) {
25                 if (**ws-1u >= 0x7fu) {
26                         if (!**ws) {
27                                 *s = 0;
28                                 *ws = 0;
29                                 return N-n;
30                         }
31                         l = wcrtomb(s, **ws, 0);
32                         if (!(l+1)) return -1;
33                         s += l;
34                         n -= l;
35                 } else {
36                         *s++ = **ws;
37                         n--;
38                 }
39                 (*ws)++;
40         }
41         while (n) {
42                 if (**ws-1u >= 0x7fu) {
43                         if (!**ws) {
44                                 *s = 0;
45                                 *ws = 0;
46                                 return N-n;
47                         }
48                         l = wcrtomb(buf, **ws, 0);
49                         if (!(l+1)) return -1;
50                         if (l>n) return N-n;
51                         wcrtomb(s, **ws, 0);
52                         s += l;
53                         n -= l;
54                 } else {
55                         *s++ = **ws;
56                         n--;
57                 }
58                 (*ws)++;
59         }
60         return N;
61 }