Avoiding a potential memory leak trimmed

Started by
5 comments, last by MajinMusashi 18 years, 4 months ago
Hello! CONTEXT: I'm almost finishing my C++ and OpenGL text rendering library (I'll post it soon), and during the revision stage I've found this piece of code which can trigger a memory leak (through the use of "vsprintf" with a buffer smaller than the converted text). This problem was solved by using "_vsnprintf", a more secure version of the previous function, and informing the maximum number of characters to be written. Please, take a look at the source below:

/** @brief Set text
  * @param rawText Raw text (including '\n')
  * @param ... Additional parameters ("printf" style)
  */
void C_TextSingle::setText( const char* rawText, ... ) {
	
  // If there's no text, return
  if ( !rawText ) {
    return;
  }

  // Merge the raw text and arguments (...) to "tempText"
  va_list argumentList;
  va_start( argumentList, rawText );
  char tempText[128];
	
  // This flavor of vsprintf avoids buffer overflows by defining the maximum
  // amount of characters to be written
  _vsnprintf( tempText, 128, rawText, argumentList );
  va_end( argumentList );
	
  // ...
}


PROBLEM: Now the code is safe (at least it seems safe), but I'm limited by 128 characters length strings. Raising this number will only make it more difficult for the user to have its string trimmed, but won't solve the real problem. QUESTION: Is there a way to avoid this method of trimming the user "raw text" argument? Any STL secret method? Thanks a lot, guys!
Advertisement
One option is to check the return value of _vsnprintf() and if it returns -1 (assuming this is a MSVC program) then increase the size of the buffer using dynamic memory and try again. Repeat until happiness is achieved.

Another option is to change from a variadic method of setting text and use stream style methods.

A third option is just accept a string from the user and let the user worry about writing code necessary to fill the string securely. (And there a plenty of options like stringstreams or boost::format)
Beware the VC's _vsnprintf function (unlinke C99's vsnprintf) does not null terminate the string if it exceeds the maximum size, it simply fills the string instead. You could also try _vscprintf if you have a recent compiler.
[EDIT]Oops I made a mistake
Quote:Original post by njpaul
I compiled this and it seemed to work when I tested it. std::strings are always easier to work with in my opinion.

*** Source Snippet Removed ***


Of course that doesn't do what the original function did, so it's kind of pointless.
Doh! Thats what I get for only testing the original function with one parameter. Sorry everyone (walks away to edit post and bang head against wall).
Quote:Original post by SiCrane
A third option is just accept a string from the user and let the user worry about writing code necessary to fill the string securely. (And there a plenty of options like stringstreams or boost::format)

I'll follow up with that! By the way, don't you sleep? Are the GDNet forums connected to your brain? Hehehehe :)
Thanks a lot!!!

This topic is closed to new replies.

Advertisement