mirror of
https://github.com/cesanta/mongoose.git
synced 2025-08-06 13:37:34 +08:00
Added printf format checking macros. Changed mg_printf() to allocate the buffer on heap if it does not fit the local one.
This commit is contained in:
parent
ee8111e424
commit
3d3359910f
29
mongoose.c
29
mongoose.c
@ -1467,15 +1467,38 @@ int mg_write(struct mg_connection *conn, const void *buf, size_t len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int mg_printf(struct mg_connection *conn, const char *fmt, ...) {
|
int mg_printf(struct mg_connection *conn, const char *fmt, ...) {
|
||||||
char buf[MG_BUF_LEN];
|
char mem[MG_BUF_LEN], *buf = mem;
|
||||||
int len;
|
int len;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
// Print in a local buffer first, hoping that it is large enough to
|
||||||
|
// hold the whole message
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
len = mg_vsnprintf(conn, buf, sizeof(buf), fmt, ap);
|
len = vsnprintf(mem, sizeof(mem), fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
return mg_write(conn, buf, (size_t)len);
|
if (len <= 0) {
|
||||||
|
// vsnprintf() error, give up
|
||||||
|
len = -1;
|
||||||
|
cry(conn, "%s(%s, ...): vsnprintf() error", __func__, fmt);
|
||||||
|
} else if (len > (int) sizeof(mem) && (buf = malloc(len + 1)) != NULL) {
|
||||||
|
// Local buffer is not large enough, allocate big buffer on heap
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vsnprintf(buf, len + 1, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
len = mg_write(conn, buf, (size_t) len);
|
||||||
|
free(buf);
|
||||||
|
} else if (len > (int) sizeof(mem)) {
|
||||||
|
// Failed to allocate large enough buffer, give up
|
||||||
|
cry(conn, "%s(%s, ...): Can't allocate %d bytes, not printing anything",
|
||||||
|
__func__, fmt, len);
|
||||||
|
len = -1;
|
||||||
|
} else {
|
||||||
|
// Copy to the local buffer succeeded
|
||||||
|
len = mg_write(conn, buf, (size_t) len);
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
// URL-decode input buffer into destination buffer.
|
// URL-decode input buffer into destination buffer.
|
||||||
|
29
mongoose.h
29
mongoose.h
@ -163,14 +163,29 @@ int mg_write(struct mg_connection *, const void *buf, size_t len);
|
|||||||
// Send data to the browser using printf() semantics.
|
// Send data to the browser using printf() semantics.
|
||||||
//
|
//
|
||||||
// Works exactly like mg_write(), but allows to do message formatting.
|
// Works exactly like mg_write(), but allows to do message formatting.
|
||||||
// Note that mg_printf() uses internal buffer of size IO_BUF_SIZE
|
// Below are the macros for enabling compiler-specific checks for
|
||||||
// (8 Kb by default) as temporary message storage for formatting. Do not
|
// printf-like arguments.
|
||||||
// print data that is bigger than that, otherwise it will be truncated.
|
|
||||||
int mg_printf(struct mg_connection *, const char *fmt, ...)
|
#undef PRINTF_FORMAT_STRING
|
||||||
#ifdef __GNUC__
|
#if _MSC_VER >= 1400
|
||||||
__attribute__((format(printf, 2, 3)))
|
#include <sal.h>
|
||||||
|
#if _MSC_VER > 1400
|
||||||
|
#define PRINTF_FORMAT_STRING(s) _Printf_format_string_ s
|
||||||
|
#else
|
||||||
|
#define PRINTF_FORMAT_STRING(s) __format_string s
|
||||||
#endif
|
#endif
|
||||||
;
|
#else
|
||||||
|
#define PRINTF_FORMAT_STRING(s) s
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define PRINTF_ARGS(x, y) __attribute__((format(printf, x, y)))
|
||||||
|
#else
|
||||||
|
#define PRINTF_ARGS(x, y)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int mg_printf(struct mg_connection *,
|
||||||
|
PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3);
|
||||||
|
|
||||||
|
|
||||||
// Send contents of the entire file together with HTTP headers.
|
// Send contents of the entire file together with HTTP headers.
|
||||||
|
Loading…
Reference in New Issue
Block a user