diff options
author | Vsevolod Stakhov <vsevolod@rspamd.com> | 2025-03-11 01:47:32 +0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-03-11 01:47:32 +0600 |
commit | efd17b77423c0809bfee76279ad5149211e98873 (patch) | |
tree | 20b762151eeecade537010ebdb74c849de21384d /src | |
parent | dc70a8ad2418c8adc7286001c79540a8f21c064c (diff) | |
parent | 020daff6ff76f054258c752c2dc319ef7763bb65 (diff) | |
download | rspamd-efd17b77423c0809bfee76279ad5149211e98873.tar.gz rspamd-efd17b77423c0809bfee76279ad5149211e98873.zip |
[Minor] Fix and improve format string processing in lua_logger_log_format()
Diffstat (limited to 'src')
-rw-r--r-- | src/lua/lua_logger.c | 128 |
1 files changed, 37 insertions, 91 deletions
diff --git a/src/lua/lua_logger.c b/src/lua/lua_logger.c index 21aad8136..004b82e72 100644 --- a/src/lua/lua_logger.c +++ b/src/lua/lua_logger.c @@ -733,124 +733,70 @@ lua_logger_log_format(lua_State *L, int fmt_pos, gboolean is_string, { char *d; const char *s, *c; - gsize r, cpylen = 0; - unsigned int arg_num = 0, cur_arg; - bool num_arg = false; + gsize r; + unsigned int arg_num, arg_max, cur_arg; struct lua_logger_trace tr; - enum { - copy_char = 0, - got_percent, - parse_arg_num - } state = copy_char; + int digit; - d = logbuf; s = lua_tostring(L, fmt_pos); - c = s; - cur_arg = fmt_pos; - if (s == NULL) { return FALSE; } - while (remain > 0 && *s != '\0') { - switch (state) { - case copy_char: - if (*s == '%') { - state = got_percent; - s++; - if (cpylen > 0) { - memcpy(d, c, cpylen); - d += cpylen; + arg_max = (unsigned int) lua_gettop(L) - fmt_pos; + d = logbuf; + cur_arg = 0; + + while (remain > 0 && *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; + } } - cpylen = 0; - } - else { - s++; - cpylen++; - remain--; - } - break; - case got_percent: - if (g_ascii_isdigit(*s) || *s == 's') { - state = parse_arg_num; - c = s; - } - else { - *d++ = *s++; - c = s; - state = copy_char; - } - break; - case parse_arg_num: - if (g_ascii_isdigit(*s)) { - s++; - num_arg = true; - } - else { - if (num_arg) { - arg_num = strtoul(c, NULL, 10); - arg_num += fmt_pos - 1; + + if (s > c) { /* Update the current argument */ cur_arg = arg_num; } - else { - /* We have non numeric argument, e.g. %s */ - arg_num = cur_arg++; - s++; - } - - if (arg_num < 1 || arg_num > (unsigned int) lua_gettop(L) + 1) { - msg_err("wrong argument number: %ud", arg_num); + } + if (s > c) { + if (cur_arg < 1 || cur_arg > arg_max) { + msg_err("wrong argument number: %ud", cur_arg); return FALSE; } memset(&tr, 0, sizeof(tr)); - r = lua_logger_out_type(L, arg_num + 1, d, remain, &tr, - is_string ? LUA_ESCAPE_UNPRINTABLE : LUA_ESCAPE_LOG); + r = lua_logger_out_type(L, fmt_pos + cur_arg, d, remain, &tr, + is_string ? LUA_ESCAPE_UNPRINTABLE : LUA_ESCAPE_LOG); g_assert(r <= remain); remain -= r; d += r; - state = copy_char; - c = s; + continue; } - break; - } - } - if (state == parse_arg_num) { - if (num_arg) { - arg_num = strtoul(c, NULL, 10); - arg_num += fmt_pos - 1; - } - else { - /* We have non numeric argument, e.g. %s */ - arg_num = cur_arg; - } - - if (arg_num < 1 || arg_num > (unsigned int) lua_gettop(L) + 1) { - msg_err("wrong argument number: %ud", arg_num); - - return FALSE; + /* Copy % */ + --s; } - memset(&tr, 0, sizeof(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; - } - else if (state == copy_char) { - if (cpylen > 0 && remain > 0) { - memcpy(d, c, cpylen); - d += cpylen; - } + *d++ = *s++; + --remain; } *d = '\0'; - return TRUE; } |