5840dc1aac2b70767cd5e03f1b86ac0b00fae2d5
[openwrt/staging/chunkeey.git] / toolchain / musl / patches / 700-wcsnrtombs-cve-2020-28928.diff
1 --- a/src/multibyte/wcsnrtombs.c
2 +++ b/src/multibyte/wcsnrtombs.c
3 @@ -1,41 +1,33 @@
4 #include <wchar.h>
5 +#include <limits.h>
6 +#include <string.h>
7
8 size_t wcsnrtombs(char *restrict dst, const wchar_t **restrict wcs, size_t wn, size_t n, mbstate_t *restrict st)
9 {
10 - size_t l, cnt=0, n2;
11 - char *s, buf[256];
12 const wchar_t *ws = *wcs;
13 - const wchar_t *tmp_ws;
14 -
15 - if (!dst) s = buf, n = sizeof buf;
16 - else s = dst;
17 -
18 - while ( ws && n && ( (n2=wn)>=n || n2>32 ) ) {
19 - if (n2>=n) n2=n;
20 - tmp_ws = ws;
21 - l = wcsrtombs(s, &ws, n2, 0);
22 - if (!(l+1)) {
23 - cnt = l;
24 - n = 0;
25 + size_t cnt = 0;
26 + if (!dst) n=0;
27 + while (ws && wn) {
28 + char tmp[MB_LEN_MAX];
29 + size_t l = wcrtomb(n<MB_LEN_MAX ? tmp : dst, *ws, 0);
30 + if (l==-1) {
31 + cnt = -1;
32 break;
33 }
34 - if (s != buf) {
35 - s += l;
36 + if (dst) {
37 + if (n<MB_LEN_MAX) {
38 + if (l>n) break;
39 + memcpy(dst, tmp, l);
40 + }
41 + dst += l;
42 n -= l;
43 }
44 - wn = ws ? wn - (ws - tmp_ws) : 0;
45 - cnt += l;
46 - }
47 - if (ws) while (n && wn) {
48 - l = wcrtomb(s, *ws, 0);
49 - if ((l+1)<=1) {
50 - if (!l) ws = 0;
51 - else cnt = l;
52 + if (!*ws) {
53 + ws = 0;
54 break;
55 }
56 - ws++; wn--;
57 - /* safe - this loop runs fewer than sizeof(buf) times */
58 - s+=l; n-=l;
59 + ws++;
60 + wn--;
61 cnt += l;
62 }
63 if (dst) *wcs = ws;