[gl2ps] Patch for gl2psPrintf

David Lonie david.lonie at kitware.com
Tue Oct 30 20:48:11 CET 2012


Hi list,

I've uncovered a bug when passing a large string to gl2psSpecial with
zlib compression enabled -- the current gl2psPrintf function will only
use a 1000 byte buffer for compression; if the string length exceeds
that, the application crashes.

I've written a patch (below) that corrects this by allocating larger
buffers if needed. For the usual case (the string is <1024 bytes), the
code behaves as before using the static, fixed size buffer. If the
string exceeds this, the buffer size is doubled until the write is
successful.

I'll commit this to VTK's gl2ps sources for now, let me know if this
is acceptable to merge upstream.

Dave

diff --git a/ThirdParty/gl2ps/vtkgl2ps/gl2ps.c
b/ThirdParty/gl2ps/vtkgl2ps/gl2ps.c
index 96255de..94d69a5 100644
--- a/ThirdParty/gl2ps/vtkgl2ps/gl2ps.c
+++ b/ThirdParty/gl2ps/vtkgl2ps/gl2ps.c
@@ -426,15 +426,31 @@ static int gl2psPrintf(const char* fmt, ...)
   va_list args;

 #if defined(GL2PS_HAVE_ZLIB)
+  GLboolean freeBuffer = GL_FALSE;
+  size_t bufferSize = 1024;
   unsigned int oldsize = 0;
-  static char buf[1000];
+  /* Try writing the string to a 1024 byte buffer. If it is too small to fit,
+     keep trying larger sizes until it does. */
+  static char buf[1024];
+  char *bufPtr = buf;
   if(gl2ps->options & GL2PS_COMPRESS){
     va_start(args, fmt);
-    ret = vsprintf(buf, fmt, args);
+    ret = vsnprintf(bufPtr, bufferSize, fmt, args);
     va_end(args);
+    while(ret >= (bufferSize - 1) || ret < 0){
+      /* Too big. Allocate a new buffer. */
+      bufferSize *= 2;
+      if(freeBuffer == GL_TRUE) gl2psFree(bufPtr);
+      bufPtr = (const char *)gl2psMalloc(bufferSize);
+      freeBuffer = GL_TRUE;
+      va_start(args, fmt);
+      ret = vsnprintf(bufPtr, bufferSize, fmt, args);
+      va_end(args);
+    }
     oldsize = gl2ps->compress->srcLen;
     gl2ps->compress->start = (Bytef*)gl2psReallocCompress(oldsize + ret);
-    memcpy(gl2ps->compress->start+oldsize, buf, ret);
+    memcpy(gl2ps->compress->start+oldsize, bufPtr, ret);
+    if(freeBuffer == GL_TRUE) gl2psFree(bufPtr);
     ret = 0;
   }
   else{