2011-08-07  Christian Franke  <Christian.Franke@t-online.de>

	* stdio/mingw_vfscanf.c: Fix segmentation fault when a char or string
	format (without malloc option) is used.

git-svn-id: svn+ssh://svn.code.sf.net/p/mingw-w64/code/trunk@4325 4407c894-4637-0410-b4f5-ada5f102cad1
diff --git a/mingw-w64-crt/ChangeLog b/mingw-w64-crt/ChangeLog
index 89fa82d..d63550b 100644
--- a/mingw-w64-crt/ChangeLog
+++ b/mingw-w64-crt/ChangeLog
@@ -1,3 +1,8 @@
+2011-08-07  Christian Franke  <Christian.Franke@t-online.de>
+
+	* stdio/mingw_vfscanf.c: Fix segmentation fault when a char or string
+	format (without malloc option) is used.
+
 2011-07-23  Ozkan Sezer  <sezeroz@gmail.com>
 
 	* lib32/vfw32.mri: Adjust for lib32 subdirectory.
diff --git a/mingw-w64-crt/stdio/mingw_vfscanf.c b/mingw-w64-crt/stdio/mingw_vfscanf.c
old mode 100755
new mode 100644
index aa8703f..cb53ebf
--- a/mingw-w64-crt/stdio/mingw_vfscanf.c
+++ b/mingw-w64-crt/stdio/mingw_vfscanf.c
@@ -95,13 +95,19 @@
 }
 
 static void
-optimize_alloc (int do_realloc, char **p, size_t sz, size_t need_sz, size_t typ_sz)
+optimize_alloc (char **p, char *end, size_t alloc_sz)
 {
+  size_t need_sz;
   char *h;
 
-  if (!do_realloc || sz == need_sz || !p || *p == NULL)
+  if (!p || !*p)
     return;
-  if ((h = (char *) realloc (*p, need_sz * typ_sz)) != NULL)
+
+  need_sz = end - *p;
+  if (need_sz == alloc_sz)
+    return;
+
+  if ((h = (char *) realloc (*p, need_sz)) != NULL)
     *p = h;
 }
 
@@ -619,8 +625,7 @@
 
 	  if ((flags & IS_SUPPRESSED) == 0)
 	    {
-	      optimize_alloc ((flags & IS_ALLOC_USED) != 0, pstr, str_sz,
-			      (str - *pstr), sizeof (char));
+	      optimize_alloc (pstr, str, str_sz);
 	      pstr = NULL;
 	      ++rval;
 	    }
@@ -717,8 +722,7 @@
 
 	  if ((flags & IS_SUPPRESSED) == 0)
 	    {
-	      optimize_alloc ((flags & IS_ALLOC_USED) != 0, pstr, str_sz,
-	      		      (wstr - (wchar_t *) *pstr), sizeof (wchar_t));
+	      optimize_alloc (pstr, (char *) wstr, str_sz * sizeof (wchar_t));
 	      pstr = NULL;
 	      ++rval;
 	    }
@@ -796,8 +800,7 @@
 	  if ((flags & IS_SUPPRESSED) == 0)
 	    {
 	      *str++ = 0;
-	      optimize_alloc ((flags & IS_ALLOC_USED) != 0, pstr, str_sz,
-			      (str - *pstr), sizeof (char));
+	      optimize_alloc (pstr, str, str_sz);
 	      pstr = NULL;
 	      ++rval;
 	    }
@@ -902,8 +905,7 @@
 	  if ((flags & IS_SUPPRESSED) == 0)
 	    {
 	      *wstr++ = 0;
-	      optimize_alloc ((flags & IS_ALLOC_USED) != 0, pstr, str_sz,
-			      (wstr - (wchar_t *) *pstr), sizeof (wchar_t));
+	      optimize_alloc (pstr, (char *) wstr, str_sz * sizeof (wchar_t));
 	      pstr = NULL;
 	      ++rval;
 	    }
@@ -1508,8 +1510,7 @@
 	      if ((flags & IS_SUPPRESSED) == 0)
 		{
 		  *wstr++ = 0;
-		  optimize_alloc ((flags & IS_ALLOC_USED) != 0, pstr, str_sz,
-				  (wstr - (wchar_t *) *pstr), sizeof (wchar_t));
+		  optimize_alloc (pstr, (char *) wstr, str_sz * sizeof (wchar_t));
 		  pstr = NULL;
 		  ++rval;
 		}
@@ -1565,8 +1566,7 @@
 	      if ((flags & IS_SUPPRESSED) == 0)
 		{
 		  *str++ = 0;
-		  optimize_alloc ((flags & IS_ALLOC_USED) != 0, pstr, str_sz,
-		  		  (str - *pstr), sizeof (char));
+		  optimize_alloc (pstr, str, str_sz);
 		  pstr = NULL;
 		  ++rval;
 		}
diff --git a/mingw-w64-crt/stdio/mingw_wvfscanf.c b/mingw-w64-crt/stdio/mingw_wvfscanf.c
old mode 100755
new mode 100644