gconstpointer traces[TRACE_POINTS];
};
+enum lua_logger_escape_type {
+ LUA_ESCAPE_NONE = (0u),
+ LUA_ESCAPE_UNPRINTABLE = (1u << 0u),
+ LUA_ESCAPE_NEWLINES = (1u << 1u),
+ LUA_ESCAPE_8BIT = (1u << 2u),
+};
+
+#define LUA_ESCAPE_LOG (LUA_ESCAPE_UNPRINTABLE|LUA_ESCAPE_NEWLINES)
+#define LUA_ESCAPE_ALL (LUA_ESCAPE_UNPRINTABLE|LUA_ESCAPE_NEWLINES|LUA_ESCAPE_8BIT)
+
/**
* Log lua object to string
* @param L
* @return
*/
gsize lua_logger_out_type (lua_State *L, gint pos, gchar *outbuf,
- gsize len, struct lua_logger_trace *trace);
+ gsize len, struct lua_logger_trace *trace,
+ enum lua_logger_escape_type esc_type);
/**
* Safely checks userdata to match specified class
return 0;
}
+static inline bool
+lua_logger_char_safe (int t, unsigned int esc_type)
+{
+ if (t & 0x80) {
+ if (esc_type & LUA_ESCAPE_8BIT) {
+ return false;
+ }
+
+ return true;
+ }
+
+ if (esc_type & LUA_ESCAPE_UNPRINTABLE) {
+ if (!g_ascii_isprint (t) && !g_ascii_isspace (t)) {
+ return false;
+ }
+ }
+
+ if (esc_type & LUA_ESCAPE_NEWLINES) {
+ if (t == '\r' || t == '\n') {
+ return false;
+ }
+ }
+
+ return true;
+}
+
static gsize
-lua_logger_out_str (lua_State *L, gint pos, gchar *outbuf, gsize len,
- struct lua_logger_trace *trace)
+lua_logger_out_str (lua_State *L, gint pos,
+ gchar *outbuf, gsize len,
+ struct lua_logger_trace *trace,
+ enum lua_logger_escape_type esc_type)
{
gsize slen, flen;
const gchar *str = lua_tolstring (L, pos, &slen);
flen = MIN (slen, len - 1);
for (r = 0; r < flen; r ++) {
- if (!(g_ascii_isprint (str[r]) || (str[r] & 0x80))) {
+ if (!lua_logger_char_safe (str[r], esc_type)) {
normal = FALSE;
break;
}
s = 0;
while (slen > 0 && len > 1) {
- if (!g_ascii_isprint (str[s])) {
- if (str[s] & 0x80) {
- outbuf[r++] = str[s];
- }
- else if (len >= 3) {
+ if (!lua_logger_char_safe (str[r], esc_type)) {
+ if (len >= 3) {
outbuf[r++] = '\\';
outbuf[r++] = hexdigests[((str[s] >> 4) & 0xF)];
outbuf[r++] = hexdigests[((str[s]) & 0xF)];
static gsize
lua_logger_out_table (lua_State *L, gint pos, gchar *outbuf, gsize len,
- struct lua_logger_trace *trace)
+ struct lua_logger_trace *trace,
+ enum lua_logger_escape_type esc_type)
{
gchar *d = outbuf;
gsize remain = len, r;
r = rspamd_snprintf (d, remain + 1, "__self");
}
else {
- r = lua_logger_out_type (L, tpos, d, remain, trace);
+ r = lua_logger_out_type (L, tpos, d, remain, trace, esc_type);
}
MOVE_BUF(d, remain, r);
r = rspamd_snprintf (d, remain + 1, "__self");
}
else {
- r = lua_logger_out_type (L, tpos, d, remain, trace);
+ r = lua_logger_out_type (L, tpos, d, remain, trace, esc_type);
}
MOVE_BUF(d, remain, r);
#undef MOVE_BUF
gsize
-lua_logger_out_type (lua_State *L, gint pos, gchar *outbuf, gsize len,
- struct lua_logger_trace *trace)
+lua_logger_out_type (lua_State *L, gint pos,
+ gchar *outbuf, gsize len,
+ struct lua_logger_trace *trace,
+ enum lua_logger_escape_type esc_type)
{
gint type;
gsize r = 0;
r = lua_logger_out_boolean (L, pos, outbuf, len, trace);
break;
case LUA_TTABLE:
- r = lua_logger_out_table (L, pos, outbuf, len, trace);
+ r = lua_logger_out_table (L, pos, outbuf, len, trace, esc_type);
break;
case LUA_TUSERDATA:
r = lua_logger_out_userdata (L, pos, outbuf, len, trace);
break;
default:
/* Try to push everything as string using tostring magic */
- r = lua_logger_out_str (L, pos, outbuf, len, trace);
+ r = lua_logger_out_str (L, pos, outbuf, len, trace, esc_type);
break;
}
}
memset (&tr, 0, sizeof (tr));
- r = lua_logger_out_type (L, arg_num + 1, d, remain, &tr);
+ r = lua_logger_out_type (L, arg_num + 1, d, remain, &tr,
+ is_string ? LUA_ESCAPE_UNPRINTABLE : LUA_ESCAPE_LOG);
g_assert (r <= remain);
remain -= r;
d += r;
}
memset (&tr, 0, sizeof (tr));
- r = lua_logger_out_type (L, arg_num + 1, d, remain, &tr);
+ r = lua_logger_out_type (L, arg_num + 1, d, remain, &tr,
+ is_string ? LUA_ESCAPE_UNPRINTABLE : LUA_ESCAPE_LOG);
g_assert (r <= remain);
remain -= r;
d += r;
rspamd_printf ("local function: %d\n", cbref);
} else {
memset (&tr, 0, sizeof (tr));
- lua_logger_out_type (L, i, outbuf, sizeof (outbuf), &tr);
+ lua_logger_out_type (L, i, outbuf, sizeof (outbuf), &tr,
+ LUA_ESCAPE_UNPRINTABLE);
rspamd_printf ("%s\n", outbuf);
}
}
for (j = old_top + 1; j <= lua_gettop (L); j ++) {
memset (&tr, 0, sizeof (tr));
- lua_logger_out_type (L, j, outbuf, sizeof (outbuf), &tr);
+ lua_logger_out_type (L, j, outbuf, sizeof (outbuf), &tr,
+ LUA_ESCAPE_UNPRINTABLE);
rspamd_printf ("%s\n", outbuf);
}
}