Description:
The functions 'vprintln_socket' and 'vprint_socket' in socket_io.cpp can't print strings longer than 999 bytes. When the result of the format string + varargs input are longer than the stack allocated buffer(which is 1000 bytes), the function will allocate a buffer that is big enough and call 'vsnprintf' a second time. Unfortunately the first call to 'vsnprintf' has modified the vararg list and the second call will print random junk from the stack.
How to repeat:
const char* string_longer_than_1000_bytes = "LOOOONG.... <snip> ...STRING";
vprintln_socket(socket, "%s", string_longer_than_1000_bytes);
^ will print junk to the socket.
Suggested fix:
The problem comes from having a function which takes a va_list instead of the vararg format ..., this prevents using va_start/va_end before and after each call to 'vsnprintf'.
Suggested solutions:
1) Rewrite the callers of 'vprintfln_socket' to do the mallocs if buffer are too small and thus allowing each call to 'vsnprintf' be surrounded by va_start/va_end. There doesn't seem to be many users of this function(i.e it's mainly used by SocketOutputStream) and it should be possible to collapse the two functions.
2) Use the 'va_copy' function from C99 to take a copy of the va_list before the first vsnprintf calls and use the copy in the second call. Requires a fairly modern compiler and is not yet available in Visual C++(although it seems that could be implemented with an assignment).