diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2018-09-19 11:45:53 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2018-09-19 14:33:53 +0100 |
commit | a133eafedf5d2f117431896b98880a4850a6aced (patch) | |
tree | f126919bf2749962867e54d8c024357eab770760 /src/lua | |
parent | 95df15919326182a588ed339733d71d74fc7a591 (diff) | |
download | rspamd-a133eafedf5d2f117431896b98880a4850a6aced.tar.gz rspamd-a133eafedf5d2f117431896b98880a4850a6aced.zip |
[Feature] Add some recursion protection to lua logger
Diffstat (limited to 'src/lua')
-rw-r--r-- | src/lua/lua_common.h | 10 | ||||
-rw-r--r-- | src/lua/lua_logger.c | 74 |
2 files changed, 67 insertions, 17 deletions
diff --git a/src/lua/lua_common.h b/src/lua/lua_common.h index 8ccb8bef0..af0b5f824 100644 --- a/src/lua/lua_common.h +++ b/src/lua/lua_common.h @@ -352,6 +352,14 @@ guint rspamd_lua_table_size (lua_State *L, gint tbl_pos); void lua_push_emails_address_list (lua_State *L, GPtrArray *addrs); + +#define TRACE_POINTS 6 + +struct lua_logger_trace { + gint cur_level; + gconstpointer traces[TRACE_POINTS]; +}; + /** * Log lua object to string * @param L @@ -361,7 +369,7 @@ void lua_push_emails_address_list (lua_State *L, GPtrArray *addrs); * @return */ gsize lua_logger_out_type (lua_State *L, gint pos, gchar *outbuf, - gsize len); + gsize len, struct lua_logger_trace *trace); /** * Safely checks userdata to match specified class diff --git a/src/lua/lua_logger.c b/src/lua/lua_logger.c index 69fa8e420..abfc3e1fa 100644 --- a/src/lua/lua_logger.c +++ b/src/lua/lua_logger.c @@ -270,7 +270,8 @@ lua_logger_debug (lua_State *L) } static gsize -lua_logger_out_str (lua_State *L, gint pos, gchar *outbuf, gsize len) +lua_logger_out_str (lua_State *L, gint pos, gchar *outbuf, gsize len, + struct lua_logger_trace *trace) { gsize slen; const gchar *str = lua_tolstring (L, pos, &slen); @@ -284,7 +285,8 @@ lua_logger_out_str (lua_State *L, gint pos, gchar *outbuf, gsize len) } static gsize -lua_logger_out_num (lua_State *L, gint pos, gchar *outbuf, gsize len) +lua_logger_out_num (lua_State *L, gint pos, gchar *outbuf, gsize len, + struct lua_logger_trace *trace) { gdouble num = lua_tonumber (L, pos); glong inum; @@ -302,7 +304,8 @@ lua_logger_out_num (lua_State *L, gint pos, gchar *outbuf, gsize len) } static gsize -lua_logger_out_boolean (lua_State *L, gint pos, gchar *outbuf, gsize len) +lua_logger_out_boolean (lua_State *L, gint pos, gchar *outbuf, gsize len, + struct lua_logger_trace *trace) { gboolean val = lua_toboolean (L, pos); gsize r = 0; @@ -313,7 +316,8 @@ lua_logger_out_boolean (lua_State *L, gint pos, gchar *outbuf, gsize len) } static gsize -lua_logger_out_userdata (lua_State *L, gint pos, gchar *outbuf, gsize len) +lua_logger_out_userdata (lua_State *L, gint pos, gchar *outbuf, gsize len, + struct lua_logger_trace *trace) { gint r, top; const gchar *str = NULL; @@ -383,17 +387,34 @@ lua_logger_out_userdata (lua_State *L, gint pos, gchar *outbuf, gsize len) if ((remain) == 0) { lua_pop (L, 1); break; } static gsize -lua_logger_out_table (lua_State *L, gint pos, gchar *outbuf, gsize len) +lua_logger_out_table (lua_State *L, gint pos, gchar *outbuf, gsize len, + struct lua_logger_trace *trace) { gchar *d = outbuf; gsize remain = len, r; gboolean first = TRUE; - gint i; + gconstpointer self = NULL; + gint i, tpos; if (!lua_istable (L, pos) || remain == 0) { return 0; } + self = lua_topointer (L, pos); + + /* Check if we have seen this pointer */ + for (i = 0; i < TRACE_POINTS; i ++) { + if (trace->traces[i] == self) { + r = rspamd_snprintf (d, remain + 1, "ref(%p)", self); + + d += r; + + return (d - outbuf); + } + } + + trace->traces[trace->cur_level % TRACE_POINTS] = self; + lua_pushvalue (L, pos); r = rspamd_snprintf (d, remain + 1, "{"); remain -= r; @@ -415,7 +436,14 @@ lua_logger_out_table (lua_State *L, gint pos, gchar *outbuf, gsize len) r = rspamd_snprintf (d, remain + 1, "[%d] = ", i); MOVE_BUF(d, remain, r); - r = lua_logger_out_type (L, lua_gettop (L), d, remain); + tpos = lua_gettop (L); + + if (lua_topointer (L, tpos) == self) { + r = rspamd_snprintf (d, remain + 1, "__self"); + } + else { + r = lua_logger_out_type (L, tpos, d, remain, trace); + } MOVE_BUF(d, remain, r); first = FALSE; @@ -438,7 +466,14 @@ lua_logger_out_table (lua_State *L, gint pos, gchar *outbuf, gsize len) r = rspamd_snprintf (d, remain + 1, "[%s] = ", lua_tostring (L, -2)); MOVE_BUF(d, remain, r); - r = lua_logger_out_type (L, lua_gettop (L), d, remain); + tpos = lua_gettop (L); + + if (lua_topointer (L, tpos) == self) { + r = rspamd_snprintf (d, remain + 1, "__self"); + } + else { + r = lua_logger_out_type (L, tpos, d, remain, trace); + } MOVE_BUF(d, remain, r); first = FALSE; @@ -455,7 +490,8 @@ lua_logger_out_table (lua_State *L, gint pos, gchar *outbuf, gsize len) #undef MOVE_BUF gsize -lua_logger_out_type (lua_State *L, gint pos, gchar *outbuf, gsize len) +lua_logger_out_type (lua_State *L, gint pos, gchar *outbuf, gsize len, + struct lua_logger_trace *trace) { gint type; gsize r = 0; @@ -465,19 +501,20 @@ lua_logger_out_type (lua_State *L, gint pos, gchar *outbuf, gsize len) } type = lua_type (L, pos); + trace->cur_level ++; switch (type) { case LUA_TNUMBER: - r = lua_logger_out_num (L, pos, outbuf, len); + r = lua_logger_out_num (L, pos, outbuf, len, trace); break; case LUA_TBOOLEAN: - r = lua_logger_out_boolean (L, pos, outbuf, len); + r = lua_logger_out_boolean (L, pos, outbuf, len, trace); break; case LUA_TTABLE: - r = lua_logger_out_table (L, pos, outbuf, len); + r = lua_logger_out_table (L, pos, outbuf, len, trace); break; case LUA_TUSERDATA: - r = lua_logger_out_userdata (L, pos, outbuf, len); + r = lua_logger_out_userdata (L, pos, outbuf, len, trace); break; case LUA_TFUNCTION: r = rspamd_snprintf (outbuf, len + 1, "function"); @@ -490,10 +527,12 @@ lua_logger_out_type (lua_State *L, gint pos, gchar *outbuf, gsize len) break; default: /* Try to push everything as string using tostring magic */ - r = lua_logger_out_str (L, pos, outbuf, len); + r = lua_logger_out_str (L, pos, outbuf, len, trace); break; } + trace->cur_level --; + return r; } @@ -595,6 +634,7 @@ lua_logger_log_format (lua_State *L, gint fmt_pos, gboolean is_string, gsize r, cpylen = 0; guint arg_num = 0, cur_arg; bool num_arg = false; + struct lua_logger_trace tr; enum { copy_char = 0, got_percent, @@ -663,7 +703,8 @@ lua_logger_log_format (lua_State *L, gint fmt_pos, gboolean is_string, return FALSE; } - r = lua_logger_out_type (L, arg_num + 1, d, remain); + memset (&tr, 0, sizeof (tr)); + r = lua_logger_out_type (L, arg_num + 1, d, remain, &tr); g_assert (r <= remain); remain -= r; d += r; @@ -690,7 +731,8 @@ lua_logger_log_format (lua_State *L, gint fmt_pos, gboolean is_string, return FALSE; } - r = lua_logger_out_type (L, arg_num + 1, d, remain); + memset (&tr, 0, sizeof (tr)); + r = lua_logger_out_type (L, arg_num + 1, d, remain, &tr); g_assert (r <= remain); remain -= r; d += r; |