[gl2ps] Patch for gl2psPrintf

Christophe Geuzaine cgeuzaine at ulg.ac.be
Sun Nov 4 14:43:59 CET 2012


Hi David - Indeed, we should fix this. In Gmsh we need to check (at configure time) if vsnprintf is available... How should we handle this in gl2ps?

On 30 Oct 2012, at 20:48, David Lonie <david.lonie at kitware.com> wrote:

> 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{
> 
> _______________________________________________
> gl2ps mailing list
> gl2ps at geuz.org
> http://www.geuz.org/mailman/listinfo/gl2ps

-- 
Prof. Christophe Geuzaine
University of Liege, Electrical Engineering and Computer Science 
http://www.montefiore.ulg.ac.be/~geuzaine