diff options
author | Rich Felker <dalias@aerifal.cx> | 2017-08-31 14:30:28 -0400 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2017-08-31 15:48:00 -0400 |
commit | 11ddc314b57196519316103b02acffe10299dad3 (patch) | |
tree | 378a974b331fad6963b364b31e33bed049c3c1cd | |
parent | 8459c6f2647a378eca2c6375210ddf29dd499043 (diff) | |
download | musl-11ddc314b57196519316103b02acffe10299dad3.tar.gz musl-11ddc314b57196519316103b02acffe10299dad3.tar.bz2 musl-11ddc314b57196519316103b02acffe10299dad3.tar.xz musl-11ddc314b57196519316103b02acffe10299dad3.zip |
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.
-rw-r--r-- | src/multibyte/mbsnrtowcs.c | 4 | ||||
-rw-r--r-- | src/multibyte/wcsnrtombs.c | 4 |
2 files changed, 6 insertions, 2 deletions
diff --git a/src/multibyte/mbsnrtowcs.c b/src/multibyte/mbsnrtowcs.c index cae4caa2..931192e2 100644 --- a/src/multibyte/mbsnrtowcs.c +++ b/src/multibyte/mbsnrtowcs.c @@ -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; wchar_t *ws, wbuf[256]; const char *s = *src; + const char *tmp_s; if (!wcs) ws = wbuf, wn = sizeof wbuf / sizeof *wbuf; 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 ) ) { if (n2>=wn) n2=wn; - n -= n2; + tmp_s = s; l = mbsrtowcs(ws, &s, n2, st); if (!(l+1)) { cnt = l; @@ -26,6 +27,7 @@ size_t mbsnrtowcs(wchar_t *restrict wcs, const char **restrict src, size_t n, si ws += l; wn -= l; } + n = s ? n - (s - tmp_s) : 0; cnt += l; } if (s) while (wn && n) { diff --git a/src/multibyte/wcsnrtombs.c b/src/multibyte/wcsnrtombs.c index 640cbbeb..676932b5 100644 --- a/src/multibyte/wcsnrtombs.c +++ b/src/multibyte/wcsnrtombs.c @@ -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; char *s, buf[256]; const wchar_t *ws = *wcs; + const wchar_t *tmp_ws; if (!dst) s = buf, n = sizeof buf; else s = dst; while ( ws && n && ( (n2=wn)>=n || n2>32 ) ) { if (n2>=n) n2=n; - wn -= n2; + tmp_ws = ws; l = wcsrtombs(s, &ws, n2, 0); if (!(l+1)) { cnt = l; @@ -22,6 +23,7 @@ size_t wcsnrtombs(char *restrict dst, const wchar_t **restrict wcs, size_t wn, s s += l; n -= l; } + wn = ws ? wn - (ws - tmp_ws) : 0; cnt += l; } if (ws) while (n && wn) { |