[mapserver-commits] r7694 - trunk/mapserver

svn at osgeo.org svn at osgeo.org
Wed Jun 18 17:26:46 EDT 2008


Author: dmorissette
Date: 2008-06-18 17:26:45 -0400 (Wed, 18 Jun 2008)
New Revision: 7694

Modified:
   trunk/mapserver/HISTORY.TXT
   trunk/mapserver/mapio.c
Log:
Got rid of static buffer limit in msIO_*printf(). Automatically grow buffer until vsnprintf succeeds. (#2214)

Modified: trunk/mapserver/HISTORY.TXT
===================================================================
--- trunk/mapserver/HISTORY.TXT	2008-06-18 21:04:32 UTC (rev 7693)
+++ trunk/mapserver/HISTORY.TXT	2008-06-18 21:26:45 UTC (rev 7694)
@@ -13,6 +13,8 @@
 Current Version (SVN trunk):
 ----------------------------
 
+- Removed static buffer size limit in msIO_*printf() functions (#2214)
+
 - Fixed libiconv detection in configure for OSX 10.5 64 bit (#2396)
 
 - mapstring.c: possible buffer overflow in msGetPath (#2649)

Modified: trunk/mapserver/mapio.c
===================================================================
--- trunk/mapserver/mapio.c	2008-06-18 21:04:32 UTC (rev 7693)
+++ trunk/mapserver/mapio.c	2008-06-18 21:26:45 UTC (rev 7694)
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id:$
+ * $Id$
  *
  * Project:  MapServer
  * Purpose:  Implementations for MapServer IO redirection capability.
@@ -240,37 +240,127 @@
 /* ==================================================================== */
 
 /************************************************************************/
+/*                            _ms_vsprintf()                            */
+/************************************************************************/
+
+static int _ms_vsprintf(char **workBufPtr, const char *format, va_list ap )
+
+{
+    int     ret_val;
+    int   workBufSize = 16000;
+
+    *workBufPtr = (char*)malloc(workBufSize * sizeof(char));
+    if (*workBufPtr == NULL)
+    {
+        msSetError( MS_MEMERR, NULL, "_ms_vsprintf()");
+        return -1;
+    }
+
+#if defined(HAVE_VSNPRINTF)
+    /* This should grow a big enough buffer to hold any formatted result. */
+    {
+        va_list wrk_args;
+
+#ifdef va_copy
+        va_copy( wrk_args, ap );
+#else
+        wrk_args = ap;
+#endif
+
+        while( (ret_val = vsnprintf( *workBufPtr, workBufSize, 
+                                     format, wrk_args)) >= workBufSize-1 
+               || ret_val == -1 )
+        {
+            workBufSize *= 4;
+            *workBufPtr = (char *) realloc(*workBufPtr, workBufSize );
+            if (*workBufPtr == NULL)
+            {
+                msSetError( MS_MEMERR, NULL, "_ms_vsprintf()");
+                va_end( wrk_args );
+                return -1;
+            }
+#ifdef va_copy
+            va_end( wrk_args );
+            va_copy( wrk_args, ap );
+#else
+            wrk_args = ap;
+#endif
+        }
+        va_end( wrk_args );
+    }
+#else
+    /* We do not have vsnprintf()... there is a risk of buffer overrun */
+    ret_val = vsprintf( *workBufPtr, format, ap );
+
+    if( ret_val < 0 || ret_val >= workBufSize )
+    {
+        msSetError(MS_MISCERR, "Possible buffer overrun.", "_ms_vsprintf()");
+        msFree(*workBufPtr);
+        *workBufPtr = NULL;
+        return -1;
+    }
+#endif
+
+    return ret_val;
+}
+
+
+/************************************************************************/
 /*                            msIO_printf()                             */
 /************************************************************************/
 
 int msIO_printf( const char *format, ... )
 
 {
-    va_list args;
+    va_list args, args_copy;
     int     return_val;
     msIOContext *context;
-    char workBuf[8000];
+    char workBuf[8000], *largerBuf = NULL;
 
     va_start( args, format );
-#if defined(HAVE_VSNPRINTF)
-    return_val = vsnprintf( workBuf, sizeof(workBuf), format, args );
-#else
+
+#if !defined(HAVE_VSNPRINTF)
     return_val = vsprintf( workBuf, format, args);
-#endif
 
-    va_end( args );
-
     if( return_val < 0 || return_val >= sizeof(workBuf) )
     {
+        va_end( args );
         msSetError(MS_MISCERR, "Possible buffer overrun.", "msIO_printf()");
         return -1;
     }
 
+#else
+
+#ifdef va_copy
+    va_copy( args_copy, args );
+#else
+    args_copy = args;
+#endif /* va_copy */
+
+    return_val = vsnprintf( workBuf, sizeof(workBuf), format, args );
+    if (return_val == -1 || return_val >= sizeof(workBuf)-1)
+    {
+        return_val = _ms_vsprintf(&largerBuf, format, args_copy );
+    }
+    va_end(args_copy);
+
+#endif /* HAVE_VSNPRINTF */
+
+    va_end( args );
+
+    if (return_val < 0)
+        return -1;
+
     context = msIO_getHandler( stdout );
     if( context == NULL )
         return -1;
 
-    return msIO_contextWrite( context, workBuf, return_val );
+    return_val = msIO_contextWrite( context, 
+                                    largerBuf?largerBuf:workBuf, 
+                                    return_val );
+    msFree(largerBuf);
+
+    return return_val;
 }
 
 /************************************************************************/
@@ -280,31 +370,56 @@
 int msIO_fprintf( FILE *fp, const char *format, ... )
 
 {
-    va_list args;
+    va_list args, args_copy;
     int     return_val;
     msIOContext *context;
-    char workBuf[8000];
+    char workBuf[8000], *largerBuf = NULL;
 
     va_start( args, format );
-#if defined(HAVE_VSNPRINTF)
-    return_val = vsnprintf( workBuf, sizeof(workBuf), format, args );
-#else
+
+#if !defined(HAVE_VSNPRINTF)
     return_val = vsprintf( workBuf, format, args);
-#endif
 
-    va_end( args );
-
     if( return_val < 0 || return_val >= sizeof(workBuf) )
     {
+        va_end( args );
         msSetError(MS_MISCERR, "Possible buffer overrun.", "msIO_fprintf()");
         return -1;
     }
 
+#else
+
+#ifdef va_copy
+    va_copy( args_copy, args );
+#else
+    args_copy = args;
+#endif /* va_copy */
+
+    return_val = vsnprintf( workBuf, sizeof(workBuf), format, args );
+    if (return_val == -1 || return_val >= sizeof(workBuf)-1)
+    {
+        return_val = _ms_vsprintf(&largerBuf, format, args_copy );
+    }
+    va_end(args_copy);
+
+#endif /* HAVE_VSNPRINTF */
+
+    va_end( args );
+
+    if (return_val < 0)
+        return -1;
+
     context = msIO_getHandler( fp );
     if( context == NULL )
-        return fwrite( workBuf, 1, return_val, fp );
+        return_val = fwrite( largerBuf?largerBuf:workBuf, 1, return_val, fp );
     else
-        return msIO_contextWrite( context, workBuf, return_val );
+        return_val =  msIO_contextWrite( context, 
+                                         largerBuf?largerBuf:workBuf, 
+                                         return_val );
+
+    msFree(largerBuf);
+
+    return return_val;
 }
 
 /************************************************************************/
@@ -314,15 +429,13 @@
 int msIO_vfprintf( FILE *fp, const char *format, va_list ap )
 
 {
+    va_list args_copy;
     int     return_val;
     msIOContext *context;
-    char workBuf[8000];
+    char workBuf[8000], *largerBuf = NULL;
 
-#if defined(HAVE_VSNPRINTF)
-    return_val = vsnprintf( workBuf, sizeof(workBuf), format, ap );
-#else
-    return_val = vsprintf( workBuf, format, ap );
-#endif
+#if !defined(HAVE_VSNPRINTF)
+    return_val = vsprintf( workBuf, format, ap);
 
     if( return_val < 0 || return_val >= sizeof(workBuf) )
     {
@@ -330,11 +443,37 @@
         return -1;
     }
 
+#else
+
+#ifdef va_copy
+    va_copy( args_copy, ap );
+#else
+    args_copy = ap;
+#endif /* va_copy */
+
+    return_val = vsnprintf( workBuf, sizeof(workBuf), format, ap );
+    if (return_val == -1 || return_val >= sizeof(workBuf)-1)
+    {
+        return_val = _ms_vsprintf(&largerBuf, format, args_copy );
+    }
+    va_end(args_copy);
+
+#endif /* HAVE_VSNPRINTF */
+
+    if (return_val < 0)
+        return -1;
+
     context = msIO_getHandler( fp );
     if( context == NULL )
-        return fwrite( workBuf, 1, return_val, fp );
+        return_val = fwrite( largerBuf?largerBuf:workBuf, 1, return_val, fp );
     else
-        return msIO_contextWrite( context, workBuf, return_val );
+        return_val =  msIO_contextWrite( context, 
+                                         largerBuf?largerBuf:workBuf, 
+                                         return_val );
+
+    msFree(largerBuf);
+
+    return return_val;
 }
 
 /************************************************************************/



More information about the mapserver-commits mailing list