ソースを参照

libgis: fix vsnprintf usage in G_rasprintf

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@54761 15284696-431f-4ddb-bdfa-cd5b030d7da7
Markus Metz 12 年 前
コミット
e0ca521985
2 ファイル変更23 行追加27 行削除
  1. 0 1
      include/defs/gis.h
  2. 23 26
      lib/gis/asprintf.c

+ 0 - 1
include/defs/gis.h

@@ -116,7 +116,6 @@ int G_vasprintf(char **, const char *, va_list);
 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)));
 

+ 23 - 26
lib/gis/asprintf.c

@@ -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 G_vasprintf(char **out, const char *fmt, va_list ap)
     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 @@ int G_asprintf(char **out, const char *fmt, ...)
  * \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;
-
-    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);
+    *size = osize;
 
     return count;
 }