|
Message-Id: <20230529183341.198911-1-izbyshev@ispras.ru> Date: Mon, 29 May 2023 21:33:41 +0300 From: Alexey Izbyshev <izbyshev@...ras.ru> To: musl@...ts.openwall.com Subject: [PATCH] mbsrtowcs: fix wrong *src update in case of EILSEQ with non-initial mbstate_t If mbsrtowcs is called with non-initial conversion state, it resumes from the point where normally the first byte of a multibyte sequence has already been consumed. If the multibyte sequence can't be completed, s is decremented with the intention to point it to the start of that sequence, but in this case it ends up equal to src-1. Fix that by remembering the start of the last (sub)sequence that we tried to convert instead of decrementing s. Do this only if ws is not NULL, since we don't update *src otherwise. --- src/multibyte/mbsrtowcs.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/multibyte/mbsrtowcs.c b/src/multibyte/mbsrtowcs.c index 9b2f2dfb..cbab539d 100644 --- a/src/multibyte/mbsrtowcs.c +++ b/src/multibyte/mbsrtowcs.c @@ -7,12 +7,13 @@ size_t mbsrtowcs(wchar_t *restrict ws, const char **restrict src, size_t wn, mbstate_t *restrict st) { - const unsigned char *s = (const void *)*src; + const unsigned char *s = (const void *)*src, *s0; size_t wn0 = wn; unsigned c = 0; if (st && (c = *(unsigned *)st)) { if (ws) { + s0 = s; *(unsigned *)st = 0; goto resume; } else { @@ -55,13 +56,13 @@ size_t mbsrtowcs(wchar_t *restrict ws, const char **restrict src, size_t wn, mbs if (*s-SA > SB-SA) break; c = bittab[*s++-SA]; resume0: - if (OOB(c,*s)) { s--; break; } + if (OOB(c,*s)) break; s++; if (c&(1U<<25)) { - if (*s-0x80u >= 0x40) { s-=2; break; } + if (*s-0x80u >= 0x40) break; s++; if (c&(1U<<19)) { - if (*s-0x80u >= 0x40) { s-=3; break; } + if (*s-0x80u >= 0x40) break; s++; } } @@ -89,16 +90,17 @@ resume0: wn--; continue; } + s0 = s; if (*s-SA > SB-SA) break; c = bittab[*s++-SA]; resume: - if (OOB(c,*s)) { s--; break; } + if (OOB(c,*s)) break; c = (c<<6) | *s++-0x80; if (c&(1U<<31)) { - if (*s-0x80u >= 0x40) { s-=2; break; } + if (*s-0x80u >= 0x40) break; c = (c<<6) | *s++-0x80; if (c&(1U<<31)) { - if (*s-0x80u >= 0x40) { s-=3; break; } + if (*s-0x80u >= 0x40) break; c = (c<<6) | *s++-0x80; } } @@ -115,6 +117,6 @@ resume: return wn0-wn; } errno = EILSEQ; - if (ws) *src = (const void *)s; + if (ws) *src = (const void *)s0; return -1; } -- 2.39.2
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.