summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2017-08-31 14:30:28 -0400
committerRich Felker <dalias@aerifal.cx>2017-08-31 15:48:00 -0400
commit11ddc314b57196519316103b02acffe10299dad3 (patch)
tree378a974b331fad6963b364b31e33bed049c3c1cd
parent8459c6f2647a378eca2c6375210ddf29dd499043 (diff)
downloadmusl-11ddc314b57196519316103b02acffe10299dad3.tar.gz
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.c4
-rw-r--r--src/multibyte/wcsnrtombs.c4
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) {