Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 6 Dec 2016 17:05:03 +0000 (UTC)
From:      Bryan Drewery <bdrewery@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r309626 - head/contrib/libc-vis
Message-ID:  <201612061705.uB6H532K076359@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201612061705.uB6H532K076359>