[gl2ps] Patch for gl2psPrintf

David Lonie david.lonie at kitware.com
Mon Nov 5 14:23:42 CET 2012


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()

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