svn commit: r309626 - head/contrib/libc-vis

Bryan Drewery bdrewery at FreeBSD.org
Tue Dec 6 17:05:04 UTC 2016


Author: bdrewery
Date: Tue Dec  6 17:05:02 2016
New Revision: 309626
URL: https://svnweb.freebsd.org/changeset/base/309626

Log:
  strvis(3): Avoid internal state of multibyte functions being tainted.
  
  The mbtoc(3) and wctomb(3) functions use internal state which may be
  tainted before the call to strvis(3).  In this context we can just use
  the thread-safe versions mbrtoc(3) and wcrtomb(3) which allow passing
  our own state from our stack.
  
  MFC after:	2 weeks
  Sponsored by:	Dell EMC Isilon

Modified:
  head/contrib/libc-vis/vis.c

Modified: head/contrib/libc-vis/vis.c
==============================================================================
--- head/contrib/libc-vis/vis.c	Tue Dec  6 15:49:39 2016	(r309625)
+++ head/contrib/libc-vis/vis.c	Tue Dec  6 17:05:02 2016	(r309626)
@@ -353,12 +353,14 @@ makeextralist(int flags, const char *src
 	wchar_t *dst, *d;
 	size_t len;
 	const wchar_t *s;
+	mbstate_t mbstate;
 
+	bzero(&mbstate, sizeof(mbstate));
 	len = strlen(src);
 	if ((dst = calloc(len + MAXEXTRAS, sizeof(*dst))) == NULL)
 		return NULL;
 
-	if ((flags & VIS_NOLOCALE) || mbstowcs(dst, src, len) == (size_t)-1) {
+	if ((flags & VIS_NOLOCALE) || mbsrtowcs(dst, &src, len, &mbstate) == (size_t)-1) {
 		size_t i;
 		for (i = 0; i < len; i++)
 			dst[i] = (wchar_t)(u_char)src[i];
@@ -400,6 +402,7 @@ istrsenvisx(char **mbdstp, size_t *dlen,
 	int clen = 0, cerr, error = -1, i, shft;
 	char *mbdst, *mdst;
 	ssize_t mbslength, maxolen;
+	mbstate_t mbstate;
 
 	_DIAGASSERT(mbdstp != NULL);
 	_DIAGASSERT(mbsrc != NULL || mblength == 0);
@@ -456,10 +459,11 @@ istrsenvisx(char **mbdstp, size_t *dlen,
 	 */
 	if (mbslength == 1)
 		mbslength++;
+	bzero(&mbstate, sizeof(mbstate));
 	while (mbslength > 0) {
 		/* Convert one multibyte character to wchar_t. */
 		if (!cerr)
-			clen = mbtowc(src, mbsrc, MB_LEN_MAX);
+			clen = mbrtowc(src, mbsrc, MB_LEN_MAX, &mbstate);
 		if (cerr || clen < 0) {
 			/* Conversion error, process as a byte instead. */
 			*src = (wint_t)(u_char)*mbsrc;
@@ -530,9 +534,10 @@ istrsenvisx(char **mbdstp, size_t *dlen,
 	len = wcslen(start);
 	maxolen = dlen ? *dlen : (wcslen(start) * MB_LEN_MAX + 1);
 	olen = 0;
+	bzero(&mbstate, sizeof(mbstate));
 	for (dst = start; len > 0; len--) {
 		if (!cerr)
-			clen = wctomb(mbdst, *dst);
+			clen = wcrtomb(mbdst, *dst, &mbstate);
 		if (cerr || clen < 0) {
 			/*
 			 * Conversion error, process as a byte(s) instead.


More information about the svn-src-all mailing list