Sign in to follow this  
MajinMusashi

Avoiding a potential memory leak trimmed

Recommended Posts

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!

Share this post


Link to post
Share on other sites
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)

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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!!!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this