Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 30 Apr 2012 01:08:18 +0000 (UTC)
From:      David Schultz <das@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r234825 - head/lib/libc/stdio
Message-ID:  <201204300108.q3U18IKb041043@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: das
Date: Mon Apr 30 01:08:18 2012
New Revision: 234825
URL: http://svn.freebsd.org/changeset/base/234825

Log:
  Fix a bug in *wscanf's handling of non-wide %s, %c, and %[
  conversions.  Both the specification and the documentation say the
  width is interpreted as the max number of wide characters to read, but
  the implementation was interpreting it as the number of bytes to convert.
  (See also r105317.)
  
  This change has security implications for any applications that depend
  on the buggy behavior, but the impact in practice is probably nil.
  Any such application would already be buggy on other platforms that
  get the semantics right.  Also, these conversions are rarely used;
  %ls, %lc, and %l[ are more appropriate.

Modified:
  head/lib/libc/stdio/vfwscanf.c

Modified: head/lib/libc/stdio/vfwscanf.c
==============================================================================
--- head/lib/libc/stdio/vfwscanf.c	Mon Apr 30 00:54:10 2012	(r234824)
+++ head/lib/libc/stdio/vfwscanf.c	Mon Apr 30 01:08:18 2012	(r234825)
@@ -144,29 +144,16 @@ convert_char(FILE *fp, char * __restrict
 	size_t nconv;
 	wint_t wi;
 	int n;
-	char mbbuf[MB_LEN_MAX];
 
 	n = 0;
 	mbs = initial_mbs;
-	while (width != 0 && (wi = __fgetwc(fp, locale)) != WEOF) {
-		if (width >= MB_CUR_MAX && mbp != SUPPRESS_PTR) {
+	while (width-- != 0 && (wi = __fgetwc(fp, locale)) != WEOF) {
+		if (mbp != SUPPRESS_PTR) {
 			nconv = wcrtomb(mbp, wi, &mbs);
 			if (nconv == (size_t)-1)
 				return (-1);
-		} else {
-			nconv = wcrtomb(mbbuf, wi, &mbs);
-			if (nconv == (size_t)-1)
-				return (-1);
-			if (nconv > width) {
-				__ungetwc(wi, fp, locale);
-				break;
-			}
-			if (mbp != SUPPRESS_PTR)
-				memcpy(mbp, mbbuf, nconv);
-		}
-		if (mbp != SUPPRESS_PTR)
 			mbp += nconv;
-		width -= nconv;
+		}
 		n++;
 	}
 	if (n == 0)
@@ -199,28 +186,17 @@ convert_ccl(FILE *fp, char * __restrict 
 	size_t nconv;
 	wint_t wi;
 	int n;
-	char mbbuf[MB_LEN_MAX];
 
 	n = 0;
 	mbs = initial_mbs;
 	while ((wi = __fgetwc(fp, locale)) != WEOF &&
-	    width != 0 && inccl(ccl, wi)) {
-		if (width >= MB_CUR_MAX && mbp != SUPPRESS_PTR) {
+	    width-- != 0 && inccl(ccl, wi)) {
+		if (mbp != SUPPRESS_PTR) {
 			nconv = wcrtomb(mbp, wi, &mbs);
 			if (nconv == (size_t)-1)
 				return (-1);
-		} else {
-			nconv = wcrtomb(mbbuf, wi, &mbs);
-			if (nconv == (size_t)-1)
-				return (-1);
-			if (nconv > width)
-				break;
-			if (mbp != SUPPRESS_PTR)
-				memcpy(mbp, mbbuf, nconv);
-		}
-		if (mbp != SUPPRESS_PTR)
 			mbp += nconv;
-		width -= nconv;
+		}
 		n++;
 	}
 	if (wi != WEOF)
@@ -267,28 +243,17 @@ convert_string(FILE *fp, char * __restri
 	size_t nconv;
 	wint_t wi;
 	int nread;
-	char mbbuf[MB_LEN_MAX];
 
 	mbs = initial_mbs;
 	nread = 0;
-	while ((wi = __fgetwc(fp, locale)) != WEOF && width != 0 &&
+	while ((wi = __fgetwc(fp, locale)) != WEOF && width-- != 0 &&
 	    !iswspace(wi)) {
-		if (width >= MB_CUR_MAX && mbp != SUPPRESS_PTR) {
+		if (mbp != SUPPRESS_PTR) {
 			nconv = wcrtomb(mbp, wi, &mbs);
 			if (nconv == (size_t)-1)
 				return (-1);
-		} else {
-			nconv = wcrtomb(mbbuf, wi, &mbs);
-			if (nconv == (size_t)-1)
-				return (-1);
-			if (nconv > width)
-				break;
-			if (mbp != SUPPRESS_PTR)
-				memcpy(mbp, mbbuf, nconv);
-		}
-		if (mbp != SUPPRESS_PTR)
 			mbp += nconv;
-		width -= nconv;
+		}
 		nread++;
 	}
 	if (wi != WEOF)



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