about summary refs log tree commit diff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2007-05-01 04:11:51 +0000
committerUlrich Drepper <drepper@redhat.com>2007-05-01 04:11:51 +0000
commitc01c245517b43fa3b983168197e7d05eef5f9828 (patch)
treeea28243abe444e41613541b9ca0349c02b636270
parentb866373d82d6378a4ae22bab1a00f8e012b7da68 (diff)
downloadglibc-c01c245517b43fa3b983168197e7d05eef5f9828.tar.gz
glibc-c01c245517b43fa3b983168197e7d05eef5f9828.tar.xz
glibc-c01c245517b43fa3b983168197e7d05eef5f9828.zip
[BZ #4438]
2007-04-30  Ulrich Drepper  <drepper@redhat.com>
	[BZ #4438]
	* stdio-common/vfprintf.c (process_string_arg): Don't overflow the
	stack for large precisions.
-rw-r--r--ChangeLog6
-rw-r--r--stdio-common/vfprintf.c24
2 files changed, 21 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 7c98365613..6ba3a12edb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2007-04-30  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #4438]
+	* stdio-common/vfprintf.c (process_string_arg): Don't overflow the
+	stack for large precisions.
+
 2007-04-30  Jakub Jelinek  <jakub@redhat.com>
 
 	* stdio-common/printf_fp.c (___printf_fp): Don't print negative sign
diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c
index 946551f2d6..31bc523025 100644
--- a/stdio-common/vfprintf.c
+++ b/stdio-common/vfprintf.c
@@ -1160,19 +1160,25 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
 		else							      \
 		  {							      \
 		    /* In case we have a multibyte character set the	      \
-		       situation is more compilcated.  We must not copy	      \
+		       situation is more complicated.  We must not copy	      \
 		       bytes at the end which form an incomplete character. */\
-		    wchar_t ignore[prec];				      \
+		    wchar_t ignore[1024];				      \
 		    const char *str2 = string;				      \
-		    mbstate_t ps;					      \
+		    const char *strend = string + prec;			      \
+		    if (strend < string)				      \
+		      strend = (const char *) UINTPTR_MAX;		      \
 									      \
+		    mbstate_t ps;					      \
 		    memset (&ps, '\0', sizeof (ps));			      \
-		    if (__mbsnrtowcs (ignore, &str2, prec, prec, &ps)	      \
-			== (size_t) -1)					      \
-		      {							      \
-			done = -1;					      \
-			goto all_done;					      \
-		      }							      \
+									      \
+		    while (str2 != NULL && str2 < strend)		      \
+		      if (__mbsnrtowcs (ignore, &str2, strend - str2, 1024,   \
+					&ps) == (size_t) -1)		      \
+			{						      \
+			  done = -1;					      \
+			  goto all_done;				      \
+			}						      \
+									      \
 		    if (str2 == NULL)					      \
 		      len = strlen (string);				      \
 		    else						      \