__inline int my_sprintf (char *dest,char *format,...)
{
va_list va;
va_start(va,format);
return vsprintf(dest,format,va);
}
My issue is that I can't add the buffer size parameter to my_sprintf because it's used in more than 50k places, this I can't replace vsprintf with vsprintf_s or vsnprintf.
any alternative to make the above function safer ?
What you're asking here is a specialization of the (in)famous question: "how to get the size of an array if all I have is a pointer?"
There's no way to figure out what's the size of the object pointed to by dest
. Your best option is likely to bite the bullet and change those 50k places to pass the size.
There might be more to your code that you're not telling us. For example, in those "50k" places that you mention, is the size known? If so you could get away with a dirty variadic macro that uses sizeof
behind the scenes and then calls a function that takes a length parameter.
Sorry, there's no silver bullet for you here, as @cnicutar already mentioned.
You can start by restricting the buffer size and asserting on overflows. Something like:
#define SPRINTF_TRACE_BUFSIZE 4096
int my_sprintf( char* dest, const char* fmt, ... )
{
/* in threaded code use malloc(3) instead */
static char trace_buf[SPRINTF_TRACE_BUFSIZE];
va_list va;
va_start( va, fmt );
int rc = vsnprintf( trace_buf, SPRINTF_TRACE_BUFSIZE, fmt, va );
assert( rc != -1 && rc < SPRINTF_TRACE_BUFSIZE );
memcpy( dest, trace_buf, rc + 1 ); /* +1 for \0 terminator */
return rc;
}
And then start lowering the tracing buffer size until asserts start firing. At that point you can find and fix the offending calls.
This will of course slow down the overall system, but we are not talking about performance here.
Just to underscore it - this is a quick and dirty hack to fight with large old existing code-base, do not use it for new development.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With