[GRASS-SVN] r54761 - in grass/trunk: include/defs lib/gis

svn_grass at osgeo.org svn_grass at osgeo.org
Wed Jan 23 05:53:20 PST 2013


Author: mmetz
Date: 2013-01-23 05:53:18 -0800 (Wed, 23 Jan 2013)
New Revision: 54761

Modified:
   grass/trunk/include/defs/gis.h
   grass/trunk/lib/gis/asprintf.c
Log:
libgis: fix vsnprintf usage in G_rasprintf

Modified: grass/trunk/include/defs/gis.h
===================================================================
--- grass/trunk/include/defs/gis.h	2013-01-23 13:51:30 UTC (rev 54760)
+++ grass/trunk/include/defs/gis.h	2013-01-23 13:53:18 UTC (rev 54761)
@@ -116,7 +116,6 @@
 int G_asprintf(char **, const char *, ...)
     __attribute__ ((format(printf, 2, 3)));
 
-int G_vsnprintf(char **, size_t *,const char *, va_list);
 int G_rasprintf(char **, size_t *,const char *, ...)
     __attribute__ ((format(printf, 3, 4)));
 

Modified: grass/trunk/lib/gis/asprintf.c
===================================================================
--- grass/trunk/lib/gis/asprintf.c	2013-01-23 13:51:30 UTC (rev 54760)
+++ grass/trunk/lib/gis/asprintf.c	2013-01-23 13:53:18 UTC (rev 54761)
@@ -17,7 +17,6 @@
  */
 
 #define _GNU_SOURCE		/* enable asprintf */
-#include <grass/config.h>
 #include <stdio.h>
 #include <stdarg.h>
 #include <string.h>
@@ -50,6 +49,10 @@
     int count;
 
     for (;;) {
+	/* BUG: according to man vsnprintf,
+	 * va_start() should be called immediately before vsnprintf(),
+	 * and va_end() immediately after vsnprintf()
+	 * otherwise there will be memory corruption */
 	count = vsnprintf(buf, size, fmt, ap);
 	if (count >= 0 && count < size)
 	    break;
@@ -95,40 +98,34 @@
  * \return number of bytes written
  */
 
-int G_vsnprintf(char **out, size_t *osize, const char *fmt, va_list ap)
+int G_rasprintf(char **out, size_t *size, const char *fmt, ...)
 {
-    char *buf = *out;
+    va_list ap;
     int count;
-    size_t size = *osize;
-    
-    if (size < strlen(fmt) + 50) {
-	size = strlen(fmt) + 50;
-	buf = G_realloc(buf, size);
+    char *buf = *out;
+    size_t osize = *size;
+
+    if (osize < strlen(fmt) + 50) {
+	osize = strlen(fmt) + 50;
+	buf = G_realloc(buf, osize);
     }
 
     for (;;) {
-	count = vsnprintf(buf, size, fmt, ap);
-	if (count >= 0 && count < size)
+	va_start(ap, fmt);
+	count = vsnprintf(buf, osize, fmt, ap);
+	va_end(ap);
+	if (count >= 0 && count < osize)
 	    break;
-	size *= 2;
-	buf = G_realloc(buf, size);
+	if (count > -1)
+	    osize = count + 1;
+	else
+	    osize *= 2;
+	
+	buf = G_realloc(buf, osize);
     }
 
-    buf = G_realloc(buf, count + 1);
     *out = buf;
-    *osize = size;
+    *size = osize;
 
     return count;
 }
-
-int G_rasprintf(char **out, size_t *size, const char *fmt, ...)
-{
-    va_list ap;
-    int count;
-
-    va_start(ap, fmt);
-    count = G_vsnprintf(out, size, fmt, ap);
-    va_end(ap);
-
-    return count;
-}



More information about the grass-commit mailing list