[gl2ps] Patch for gl2psPrintf

Christophe Geuzaine cgeuzaine at ulg.ac.be
Mon Nov 5 16:01:09 CET 2012


On 05 Nov 2012, at 14:23, David Lonie <david.lonie at kitware.com> wrote:

> On Sun, Nov 4, 2012 at 8:43 AM, Christophe Geuzaine <cgeuzaine at ulg.ac.be> wrote:
>> 
>> 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?
> 
> Something like the following can be added to the CMakeLists.txt file for gl2ps:
> 
> include(CheckFunctionExists)
> check_function_exists(vsnprintf HAVE_VSNPRINTF)
> if(NOT HAVE_VSNPRINTF)
>  message(FATAL_ERROR "Compiler does not support function 'vsnprintf'.")
> endif()
> 

Sure - but do we want this limitation? If not, I will just #ifdef the code with something like HAVE_NO_VSNPRINTF...


> Dave
> 
>> 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
>> 
>> 
>> 

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