diff options
author | Dmitry Petrov <dpetrov67@gmail.com> | 2025-03-15 18:57:14 -0400 |
---|---|---|
committer | Dmitry Petrov <dpetrov67@gmail.com> | 2025-03-16 17:45:38 -0400 |
commit | 20dd01ab8fe2f73777ab3fbba8458f31dc269b06 (patch) | |
tree | baa2a3fb1f457290cea107d20cd8d958301b890e /src | |
parent | 34f8e5e65fdb0bae1f6a7c77150e7cb44717d16f (diff) | |
download | rspamd-20dd01ab8fe2f73777ab3fbba8458f31dc269b06.tar.gz rspamd-20dd01ab8fe2f73777ab3fbba8458f31dc269b06.zip |
Add support for complex table keys in logging output
Diffstat (limited to 'src')
-rw-r--r-- | src/lua/lua_logger.c | 177 |
1 files changed, 95 insertions, 82 deletions
diff --git a/src/lua/lua_logger.c b/src/lua/lua_logger.c index 6c07a7fc6..8f2aa5be1 100644 --- a/src/lua/lua_logger.c +++ b/src/lua/lua_logger.c @@ -174,7 +174,8 @@ static const struct luaL_reg loggerlib_f[] = { {"__tostring", rspamd_lua_class_tostring}, {NULL, NULL}}; -gsize lua_logger_out_type(lua_State *L, int pos, char *outbuf, +static gsize +lua_logger_out_type(lua_State *L, int pos, char *outbuf, gsize len, struct lua_logger_trace *trace, enum lua_logger_escape_type esc_type); @@ -210,7 +211,7 @@ lua_common_log_line(GLogLevelFlags level, p = func_buf; } else { - p = G_STRFUNC; + p = (char *) G_STRFUNC; } rspamd_common_log_function(NULL, @@ -279,6 +280,70 @@ lua_logger_char_safe(int t, unsigned int esc_type) return true; } +/* Could return negative value in case of wrong argument number */ +static glong +lua_logger_log_format_str(lua_State *L, int offset, char *logbuf, gsize remain, + const char *fmt, + enum lua_logger_escape_type esc_type) +{ + const char *c; + gsize r; + int digit; + + char *d = logbuf; + unsigned int arg_num, cur_arg = 0, arg_max = lua_gettop(L) - offset; + + while (remain > 1 && *fmt) { + if (*fmt == '%') { + ++fmt; + c = fmt; + if (*fmt == 's') { + ++fmt; + ++cur_arg; + } else { + arg_num = 0; + while ((digit = g_ascii_digit_value(*fmt)) >= 0) { + ++fmt; + arg_num = arg_num * 10 + digit; + if (arg_num >= 100) { + /* Avoid ridiculously large numbers */ + fmt = c; + break; + } + } + + if (fmt > c) { + /* Update the current argument */ + cur_arg = arg_num; + } + } + + if (fmt > c) { + if (cur_arg < 1 || cur_arg > arg_max) { + *d = 0; + return -((glong) cur_arg + 1); /* wrong argument number */ + } + + r = lua_logger_out(L, offset + cur_arg, d, remain, esc_type); + g_assert(r < remain); + remain -= r; + d += r; + continue; + } + + /* Copy % */ + --fmt; + } + + *d++ = *fmt++; + --remain; + } + + *d = 0; + + return d - logbuf; +} + static gsize lua_logger_out_str(lua_State *L, int pos, char *outbuf, gsize len, @@ -435,7 +500,8 @@ lua_logger_out_table(lua_State *L, int pos, char *outbuf, gsize len, enum lua_logger_escape_type esc_type) { char *d = outbuf, *str; - gsize remain = len, r; + gsize remain = len; + glong r; gboolean first = TRUE; gconstpointer self = NULL; int i, last_seq = 0, top; @@ -512,17 +578,19 @@ lua_logger_out_table(lua_State *L, int pos, char *outbuf, gsize len, if (first) { first = FALSE; - str = "[%s] = "; + str = "[%2] = %1"; } else { - str = ", [%s] = "; + str = ", [%2] = %1"; + } + r = lua_logger_log_format_str(L, top + 1, d, remain, str, esc_type); + if (r < 0) { + /* should not happen */ + goto table_oob; } - r = rspamd_snprintf(d, remain, str, lua_tostring(L, -1)); MOVE_BUF(d, remain, r); - - lua_pop(L, 1); /* Remove key */ - r = lua_logger_out_type(L, -1, d, remain, trace, esc_type); - MOVE_BUF(d, remain, r); + /* Remove key */ + lua_pop(L, 1); } r = rspamd_snprintf(d, remain, "}"); @@ -536,7 +604,8 @@ table_oob: #undef MOVE_BUF -gsize lua_logger_out_type(lua_State *L, int pos, +static gsize +lua_logger_out_type(lua_State *L, int pos, char *outbuf, gsize len, struct lua_logger_trace *trace, enum lua_logger_escape_type esc_type) @@ -673,70 +742,16 @@ static gboolean lua_logger_log_format(lua_State *L, int fmt_pos, gboolean is_string, char *logbuf, gsize remain) { - char *d; - const char *s, *c; - gsize r; - unsigned int arg_num, arg_max, cur_arg; - int digit; - - s = lua_tostring(L, fmt_pos); - if (s == NULL) { + const char *fmt = lua_tostring(L, fmt_pos); + if (fmt == NULL) { return FALSE; } - arg_max = (unsigned int) lua_gettop(L) - fmt_pos; - d = logbuf; - cur_arg = 0; - - while (remain > 1 && *s) { - if (*s == '%') { - ++s; - c = s; - if (*s == 's') { - ++s; - ++cur_arg; - } else { - arg_num = 0; - while ((digit = g_ascii_digit_value(*s)) >= 0) { - ++s; - arg_num = arg_num * 10 + digit; - if (arg_num >= 100) { - /* Avoid ridiculously large numbers */ - s = c; - break; - } - } - - if (s > c) { - /* Update the current argument */ - cur_arg = arg_num; - } - } - - if (s > c) { - if (cur_arg < 1 || cur_arg > arg_max) { - msg_err("wrong argument number: %ud", cur_arg); - return FALSE; - } - - r = lua_logger_out(L, fmt_pos + cur_arg, d, remain, - is_string ? LUA_ESCAPE_UNPRINTABLE : LUA_ESCAPE_LOG); - g_assert(r <= remain); - remain -= r; - d += r; - continue; - } - - /* Copy % */ - --s; - } - - *d++ = *s++; - --remain; + glong ret = lua_logger_log_format_str(L, fmt_pos, logbuf, remain, fmt, is_string ? LUA_ESCAPE_UNPRINTABLE : LUA_ESCAPE_LOG); + if (ret < 0) { + msg_err("wrong argument number: %ud", -((int) ret + 1)); + return FALSE; } - - *d = 0; - return TRUE; } @@ -748,11 +763,11 @@ lua_logger_do_log(lua_State *L, { char logbuf[RSPAMD_LOGBUF_SIZE - 128]; const char *uid = NULL; - int fmt_pos = start_pos; int ret; - GError *err = NULL; if (lua_type(L, start_pos) == LUA_TUSERDATA) { + GError *err = NULL; + uid = lua_logger_get_id(L, start_pos, &err); if (uid == NULL) { @@ -766,15 +781,16 @@ lua_logger_do_log(lua_State *L, return ret; } - ++fmt_pos; + ++start_pos; } - else if (lua_type(L, start_pos) != LUA_TSTRING) { + + if (lua_type(L, start_pos) != LUA_TSTRING) { /* Bad argument type */ return luaL_error(L, "bad format string type: %s", lua_typename(L, lua_type(L, start_pos))); } - ret = lua_logger_log_format(L, fmt_pos, is_string, logbuf, sizeof(logbuf)); + ret = lua_logger_log_format(L, start_pos, is_string, logbuf, sizeof(logbuf)); if (ret) { if (is_string) { @@ -785,12 +801,9 @@ lua_logger_do_log(lua_State *L, lua_common_log_line(level, L, logbuf, uid, "lua", 1); } } - else { - if (is_string) { - lua_pushnil(L); - - return 1; - } + else if (is_string) { + lua_pushnil(L); + return 1; } return 0; |