mirror of git://git.musl-libc.org/musl
fix erroneous stop before input limit in mbsnrtowcs and wcsnrtombs
the value computed as an output limit that bounds the amount of input consumed below the input limit was incorrectly being used as the actual amount of input consumed. instead, compute the actual amount of input consumed as a difference of pointers before and after the conversion. patch by Mikhail Kremnyov.
This commit is contained in:
parent
8459c6f264
commit
11ddc314b5
|
@ -5,6 +5,7 @@ size_t mbsnrtowcs(wchar_t *restrict wcs, const char **restrict src, size_t n, si
|
||||||
size_t l, cnt=0, n2;
|
size_t l, cnt=0, n2;
|
||||||
wchar_t *ws, wbuf[256];
|
wchar_t *ws, wbuf[256];
|
||||||
const char *s = *src;
|
const char *s = *src;
|
||||||
|
const char *tmp_s;
|
||||||
|
|
||||||
if (!wcs) ws = wbuf, wn = sizeof wbuf / sizeof *wbuf;
|
if (!wcs) ws = wbuf, wn = sizeof wbuf / sizeof *wbuf;
|
||||||
else ws = wcs;
|
else ws = wcs;
|
||||||
|
@ -15,7 +16,7 @@ size_t mbsnrtowcs(wchar_t *restrict wcs, const char **restrict src, size_t n, si
|
||||||
|
|
||||||
while ( s && wn && ( (n2=n/4)>=wn || n2>32 ) ) {
|
while ( s && wn && ( (n2=n/4)>=wn || n2>32 ) ) {
|
||||||
if (n2>=wn) n2=wn;
|
if (n2>=wn) n2=wn;
|
||||||
n -= n2;
|
tmp_s = s;
|
||||||
l = mbsrtowcs(ws, &s, n2, st);
|
l = mbsrtowcs(ws, &s, n2, st);
|
||||||
if (!(l+1)) {
|
if (!(l+1)) {
|
||||||
cnt = l;
|
cnt = l;
|
||||||
|
@ -26,6 +27,7 @@ size_t mbsnrtowcs(wchar_t *restrict wcs, const char **restrict src, size_t n, si
|
||||||
ws += l;
|
ws += l;
|
||||||
wn -= l;
|
wn -= l;
|
||||||
}
|
}
|
||||||
|
n = s ? n - (s - tmp_s) : 0;
|
||||||
cnt += l;
|
cnt += l;
|
||||||
}
|
}
|
||||||
if (s) while (wn && n) {
|
if (s) while (wn && n) {
|
||||||
|
|
|
@ -5,13 +5,14 @@ size_t wcsnrtombs(char *restrict dst, const wchar_t **restrict wcs, size_t wn, s
|
||||||
size_t l, cnt=0, n2;
|
size_t l, cnt=0, n2;
|
||||||
char *s, buf[256];
|
char *s, buf[256];
|
||||||
const wchar_t *ws = *wcs;
|
const wchar_t *ws = *wcs;
|
||||||
|
const wchar_t *tmp_ws;
|
||||||
|
|
||||||
if (!dst) s = buf, n = sizeof buf;
|
if (!dst) s = buf, n = sizeof buf;
|
||||||
else s = dst;
|
else s = dst;
|
||||||
|
|
||||||
while ( ws && n && ( (n2=wn)>=n || n2>32 ) ) {
|
while ( ws && n && ( (n2=wn)>=n || n2>32 ) ) {
|
||||||
if (n2>=n) n2=n;
|
if (n2>=n) n2=n;
|
||||||
wn -= n2;
|
tmp_ws = ws;
|
||||||
l = wcsrtombs(s, &ws, n2, 0);
|
l = wcsrtombs(s, &ws, n2, 0);
|
||||||
if (!(l+1)) {
|
if (!(l+1)) {
|
||||||
cnt = l;
|
cnt = l;
|
||||||
|
@ -22,6 +23,7 @@ size_t wcsnrtombs(char *restrict dst, const wchar_t **restrict wcs, size_t wn, s
|
||||||
s += l;
|
s += l;
|
||||||
n -= l;
|
n -= l;
|
||||||
}
|
}
|
||||||
|
wn = ws ? wn - (ws - tmp_ws) : 0;
|
||||||
cnt += l;
|
cnt += l;
|
||||||
}
|
}
|
||||||
if (ws) while (n && wn) {
|
if (ws) while (n && wn) {
|
||||||
|
|
Loading…
Reference in New Issue