[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