Browse Source

fix incorrect end pointer in some cases when wcsrtombs stops early

when wcsrtombs stopped due to hitting zero remaining space in the
output buffer, it was wrongly clearing the position pointer as if it
had completed the conversion successfully.

this commit rearranges the code somewhat to make a clear separation
between the cases of ending due to running out of output buffer space,
and ending due to reaching the end of input or an illegal sequence in
the input. the new branches have been arranged with the hope of
optimizing more common cases, too.

(cherry picked from commit 8fba4458afb7304b32ca887e4a3990c6029131f9)
Rich Felker 11 năm trước cách đây
mục cha
commit
5fa12af8da
1 tập tin đã thay đổi với 15 bổ sung7 xóa
  1. 15 7
      src/multibyte/wcsrtombs.c

+ 15 - 7
src/multibyte/wcsrtombs.c

@@ -21,8 +21,13 @@ size_t wcsrtombs(char *restrict s, const wchar_t **restrict ws, size_t n, mbstat
 		}
 		return n;
 	}
-	while (n>=4 && **ws) {
-		if (**ws >= 0x80u) {
+	while (n>=4) {
+		if (**ws-1u >= 0x7fu) {
+			if (!**ws) {
+				*s = 0;
+				*ws = 0;
+				return N-n;
+			}
 			l = wcrtomb(s, **ws, 0);
 			if (!(l+1)) return -1;
 			s += l;
@@ -33,8 +38,13 @@ size_t wcsrtombs(char *restrict s, const wchar_t **restrict ws, size_t n, mbstat
 		}
 		(*ws)++;
 	}
-	while (n && **ws) {
-		if (**ws >= 0x80u) {
+	while (n) {
+		if (**ws-1u >= 0x7fu) {
+			if (!**ws) {
+				*s = 0;
+				*ws = 0;
+				return N-n;
+			}
 			l = wcrtomb(buf, **ws, 0);
 			if (!(l+1)) return -1;
 			if (l>n) return N-n;
@@ -47,7 +57,5 @@ size_t wcsrtombs(char *restrict s, const wchar_t **restrict ws, size_t n, mbstat
 		}
 		(*ws)++;
 	}
-	if (n) *s = 0;
-	*ws = 0;
-	return N-n;
+	return N;
 }