diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2020-12-25 14:01:41 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2020-12-25 14:02:37 +0000 |
commit | 2ccd109189b31349ac128ad82e5563b585fb0f06 (patch) | |
tree | 8683a00d4ffe2d6071ce7f6648012c4df32e13f4 /src/libserver/logger | |
parent | 2d580ae44f9646513748a234f1683e412d750f9b (diff) | |
download | rspamd-2ccd109189b31349ac128ad82e5563b585fb0f06.tar.gz rspamd-2ccd109189b31349ac128ad82e5563b585fb0f06.zip |
[Minor] Optimize the common case + fix signed char
Diffstat (limited to 'src/libserver/logger')
-rw-r--r-- | src/libserver/logger/logger.c | 79 | ||||
-rw-r--r-- | src/libserver/logger/logger_private.h | 20 |
2 files changed, 83 insertions, 16 deletions
diff --git a/src/libserver/logger/logger.c b/src/libserver/logger/logger.c index 93bfe39a0..fee4477a5 100644 --- a/src/libserver/logger/logger.c +++ b/src/libserver/logger/logger.c @@ -418,20 +418,31 @@ rspamd_common_logv (rspamd_logger_t *rspamd_log, gint level_flags, gchar *end; gint level = level_flags & (RSPAMD_LOG_LEVEL_MASK & G_LOG_LEVEL_MASK), mod_id; bool ret = false; - gchar logbuf[RSPAMD_LOGBUF_SIZE], logbuf_escaped[RSPAMD_LOGBUF_SIZE]; + gchar logbuf[RSPAMD_LOGBUF_SIZE], *log_line; + gsize nescaped; if (G_UNLIKELY (rspamd_log == NULL)) { rspamd_log = default_logger; } + log_line = logbuf; + if (G_UNLIKELY (rspamd_log == NULL)) { /* Just fprintf message to stderr */ if (level >= G_LOG_LEVEL_INFO) { end = rspamd_vsnprintf (logbuf, sizeof (logbuf), fmt, args); - end = rspamd_log_line_hex_escape (logbuf, (end - logbuf), - logbuf_escaped, sizeof (logbuf_escaped)); - rspamd_fprintf (stderr, "%*s\n", (gint)(end - logbuf_escaped), - logbuf_escaped); + + if ((nescaped = rspamd_log_line_need_escape (logbuf, end - logbuf)) != 0) { + gsize unsecaped_len = end - logbuf; + gchar *logbuf_escaped = g_alloca (unsecaped_len + nescaped * 4); + log_line = logbuf_escaped; + + end = rspamd_log_line_hex_escape (logbuf, unsecaped_len, + logbuf_escaped,unsecaped_len + nescaped * 4); + } + + rspamd_fprintf (stderr, "%*s\n", (gint)(end - log_line), + log_line); } } else { @@ -444,14 +455,21 @@ rspamd_common_logv (rspamd_logger_t *rspamd_log, gint level_flags, if (rspamd_logger_need_log (rspamd_log, level_flags, mod_id)) { end = rspamd_vsnprintf (logbuf, sizeof (logbuf), fmt, args); - end = rspamd_log_line_hex_escape (logbuf, (end - logbuf), - logbuf_escaped, sizeof (logbuf_escaped)); + + if ((nescaped = rspamd_log_line_need_escape (logbuf, end - logbuf)) != 0) { + gsize unsecaped_len = end - logbuf; + gchar *logbuf_escaped = g_alloca (unsecaped_len + nescaped * 4); + log_line = logbuf_escaped; + + end = rspamd_log_line_hex_escape (logbuf, unsecaped_len, + logbuf_escaped,unsecaped_len + nescaped * 4); + } if ((level_flags & RSPAMD_LOG_ENCRYPTED) && rspamd_log->pk) { gchar *encrypted; gsize enc_len; - encrypted = rspamd_log_encrypt_message (logbuf_escaped, end, &enc_len, + encrypted = rspamd_log_encrypt_message (log_line, end, &enc_len, rspamd_log); ret = rspamd_log->ops.log (module, id, function, @@ -466,8 +484,8 @@ rspamd_common_logv (rspamd_logger_t *rspamd_log, gint level_flags, ret = rspamd_log->ops.log (module, id, function, level_flags, - logbuf_escaped, - end - logbuf_escaped, + log_line, + end - log_line, rspamd_log, rspamd_log->ops.specific); } @@ -475,8 +493,8 @@ rspamd_common_logv (rspamd_logger_t *rspamd_log, gint level_flags, switch (level) { case G_LOG_LEVEL_CRITICAL: rspamd_log->log_cnt[0] ++; - rspamd_log_write_ringbuffer (rspamd_log, module, id, logbuf_escaped, - end - logbuf_escaped); + rspamd_log_write_ringbuffer (rspamd_log, module, id, log_line, + end - log_line); break; case G_LOG_LEVEL_WARNING: rspamd_log->log_cnt[1]++; @@ -893,7 +911,7 @@ rspamd_logger_set_log_function (rspamd_logger_t *logger, gchar * -rspamd_log_line_hex_escape (const gchar *src, gsize srclen, +rspamd_log_line_hex_escape (const guchar *src, gsize srclen, gchar *dst, gsize dstlen) { static const gchar hexdigests[16] = "0123456789ABCDEF"; @@ -941,4 +959,39 @@ rspamd_log_line_hex_escape (const gchar *src, gsize srclen, } return d; +} + +gsize +rspamd_log_line_need_escape (const guchar *src, gsize srclen) +{ + static guint32 escape[] = { + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + + /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */ + 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0100 */ + + /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */ + 0x00000000, /* 0001 0000 0000 0000 0000 0000 0000 0000 */ + + /* ~}| {zyx wvut srqp onml kjih gfed cba` */ + 0x80000000, /* 1000 0000 0000 0000 0000 0000 0000 0000 */ + + /* Allow all 8bit characters (assuming they are valid utf8) */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + }; + gsize n = 0; + + while (srclen) { + if (escape[*src >> 5] & (1U << (*src & 0x1f))) { + n++; + } + + src ++; + srclen --; + } + + return n; }
\ No newline at end of file diff --git a/src/libserver/logger/logger_private.h b/src/libserver/logger/logger_private.h index e43202312..cb06abe7c 100644 --- a/src/libserver/logger/logger_private.h +++ b/src/libserver/logger/logger_private.h @@ -102,10 +102,24 @@ bool rspamd_log_file_log (const gchar *module, const gchar *id, gpointer arg); bool rspamd_log_file_on_fork (rspamd_logger_t *logger, struct rspamd_config *cfg, gpointer arg, GError **err); -gchar* rspamd_log_line_hex_escape (const gchar *src, gsize srclen, +/** + * Escape log line by replacing unprintable characters to hex escapes like \xNN + * @param src + * @param srclen + * @param dst + * @param dstlen + * @return end of the escaped buffer + */ +gchar* rspamd_log_line_hex_escape (const guchar *src, gsize srclen, gchar *dst, gsize dstlen); - - +/** + * Returns number of characters to be escaped, e.g. a caller can allocate a new buffer + * the desired number of characters + * @param src + * @param srclen + * @return number of characters to be escaped + */ +gsize rspamd_log_line_need_escape (const guchar *src, gsize srclen); static const struct rspamd_logger_funcs file_log_funcs = { .init = rspamd_log_file_init, |