Using snprintf is also insecure. Sprintf and snprintf cannot handle common Len + = sprintf () scenarios, which often lead to bugs.
Worse in windows, snprintf does not guarantee the end of '\ 0.
Therefore, we need a safer sprintf. (Nginx is aware of similar problems, so it makes similar adjustments to the interface when implementing ngx_sprintf)
Statement:
// Return 0 on fail. return result length on Success (may truncate ). // We consider '-1' as a dangerous return value that may cause a lot of bugs. // 'buf' will always ended with '\ 0', and return value will always be length of the result. // It's safe to use like: Len + = safe_sprintf (BUF + Len, buf_size-len, FMT ,....) int safe_sprintf (char * Buf, int buf_size, char * FMT ,...) _ attribute _ (_ format _ (_ printf __, 3, 4 )));
Implementation:
Int safe_sprintf (char * Buf, int buf_size, char * FMT ,...) {If (BUF = NULL | buf_size <= 0) {return 0;} va_list AP; va_start (AP, FMT); int res = vsnprintf (BUF, buf_size, FMT, AP); va_end (AP); If (RES =-1) {Buf [0] = '\ 0'; return 0;} If (RES> = buf_size) {res = buf_size-1; Buf [res] = '\ 0';} return res ;}
Note: For Linux, vsnprintf can end with '\ 0'. For Windows, vsnprintf cannot end with' \ 0. Whether the vsnprintf of other platforms can guarantee that the end of '\ 0' is unknown. To ensure security on all platforms, I did not differentiate platforms when assigning zero. It's already sprintf, so don't think too much about performance.