As everyone else noted, the basic answer to your question is "Yes, you are vulnerable to buffer overflows".
In C99, you could use a VLA:
void ircsocket_print(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
int len = vsnprintf(0, 0, message, args);
va_end(args);
char buffer[len+1];
va_start(args, fmt);
int len = vsnprintf(buffer, len+1, message, args);
va_end(args);
send(ircsocket_connection, buffer, len, 0);
}
Note the idiom that calls vsnprintf()
once with length 0 (the second zero) to obtain the length required, then calls it a second time to format the data into the buffer. Also note the careful resetting of args
after each call to vsnprintf()
; that is required by the C standard:
§7.15 <stdarg.h>
If access to the varying arguments is
desired, the called function shall declare an object (generally referred to as ap
in this
subclause) having type va_list
. The object ap
may be passed as an argument to
another function; if that function invokes the va_arg
macro with parameter ap
, the
value of ap
in the calling function is indeterminate and shall be passed to the va_end
macro prior to any further reference to ap
.
One downside to this formulation is that it takes a pessimistic view and unconditionally calls vsnprintf()
twice. You might prefer to take an optimistic view (most of the time, 512 will be enough), and only allocate more space if the first call shows that it is insufficient.
One more downside to the use of a VLA like this is that if you run out of space for the local variable buffer
, your code may never get a chance to recover. You must judge how serious a problem that is. If it is an issue, use explicit memory allocation (malloc()
) instead:
char buffer = malloc(len+1);
if (buffer == 0)
return; // Report error?
...second vsnprintf() and send()...
free(buffer);
Since your function only ever returned the constant 1
, there is no obvious reason to make it a function returning anything - if it is a function returning void
, the calling code does not need any check on the returned value. OTOH, maybe you should be returning the result of the send()
call (and possibly an error indication if the malloc()
fails).
I also made the format (message) parameter into a const char *
; neither this function nor the ones it calls modify the format string.