@@ -83,7 +83,7 @@ static gboolean rspamd_is_empty_body (struct rspamd_task *task, | |||
static rspamd_expression_atom_t * rspamd_mime_expr_parse (const gchar *line, gsize len, | |||
rspamd_mempool_t *pool, gpointer ud, GError **err); | |||
static gdouble rspamd_mime_expr_process (gpointer input, rspamd_expression_atom_t *atom); | |||
static gdouble rspamd_mime_expr_process (struct rspamd_expr_process_data *process_data, rspamd_expression_atom_t *atom); | |||
static gint rspamd_mime_expr_priority (rspamd_expression_atom_t *atom); | |||
static void rspamd_mime_expr_destroy (rspamd_expression_atom_t *atom); | |||
@@ -913,9 +913,9 @@ rspamd_mime_expr_process_function (struct rspamd_function_atom * func, | |||
} | |||
static gdouble | |||
rspamd_mime_expr_process (gpointer input, rspamd_expression_atom_t *atom) | |||
rspamd_mime_expr_process (struct rspamd_expr_process_data *process_data, rspamd_expression_atom_t *atom) | |||
{ | |||
struct rspamd_task *task = input; | |||
struct rspamd_task *task = process_data->task; | |||
struct rspamd_mime_atom *mime_atom; | |||
lua_State *L; | |||
gdouble ret = 0; |
@@ -344,8 +344,13 @@ composites_foreach_callback (gpointer key, gpointer value, void *data) | |||
return; | |||
} | |||
rc = rspamd_process_expression (comp->expr, | |||
RSPAMD_EXPRESSION_FLAG_NOOPT, cd); | |||
struct rspamd_expr_process_data process_data; | |||
memset (&process_data, 0, sizeof process_data); | |||
process_data.flags = RSPAMD_EXPRESSION_FLAG_NOOPT; | |||
process_data.cd = cd; | |||
rc = rspamd_process_expression (comp->expr, &process_data); | |||
/* Checked bit */ | |||
setbit (cd->checked, comp->id * 2); |
@@ -984,8 +984,8 @@ rspamd_ast_do_op (struct rspamd_expression_elt *elt, gdouble val, | |||
} | |||
static gdouble | |||
rspamd_ast_process_node (struct rspamd_expression *expr, gint flags, GNode *node, | |||
gpointer data, GPtrArray *track) | |||
rspamd_ast_process_node (struct rspamd_expression *expr, GNode *node, | |||
struct rspamd_expr_process_data *process_data) | |||
{ | |||
struct rspamd_expression_elt *elt, *celt, *parelt = NULL; | |||
GNode *cld; | |||
@@ -1010,13 +1010,13 @@ rspamd_ast_process_node (struct rspamd_expression *expr, gint flags, GNode *node | |||
t1 = rspamd_get_ticks (TRUE); | |||
} | |||
elt->value = expr->subr->process (data, elt->p.atom); | |||
elt->value = expr->subr->process (process_data, elt->p.atom); | |||
if (fabs (elt->value) > 1e-9) { | |||
elt->p.atom->hits ++; | |||
if (track) { | |||
g_ptr_array_add (track, elt->p.atom); | |||
if (process_data->trace) { | |||
g_ptr_array_add (process_data->trace, elt->p.atom); | |||
} | |||
} | |||
@@ -1057,7 +1057,7 @@ rspamd_ast_process_node (struct rspamd_expression *expr, gint flags, GNode *node | |||
continue; | |||
} | |||
val = rspamd_ast_process_node (expr, flags, cld, data, track); | |||
val = rspamd_ast_process_node (expr, cld, process_data); | |||
if (isnan (acc)) { | |||
acc = rspamd_ast_do_op (elt, val, 0, lim, TRUE); | |||
@@ -1066,7 +1066,7 @@ rspamd_ast_process_node (struct rspamd_expression *expr, gint flags, GNode *node | |||
acc = rspamd_ast_do_op (elt, val, acc, lim, FALSE); | |||
} | |||
if (!(flags & RSPAMD_EXPRESSION_FLAG_NOOPT)) { | |||
if (!(process_data->flags & RSPAMD_EXPRESSION_FLAG_NOOPT)) { | |||
if (rspamd_ast_node_done (elt, parelt, acc, lim)) { | |||
return acc; | |||
} | |||
@@ -1090,8 +1090,7 @@ rspamd_ast_cleanup_traverse (GNode *n, gpointer d) | |||
} | |||
gdouble | |||
rspamd_process_expression_track (struct rspamd_expression *expr, gint flags, | |||
gpointer data, GPtrArray *track) | |||
rspamd_process_expression_track (struct rspamd_expression *expr, struct rspamd_expr_process_data *process_data) | |||
{ | |||
gdouble ret = 0; | |||
@@ -1099,7 +1098,7 @@ rspamd_process_expression_track (struct rspamd_expression *expr, gint flags, | |||
/* Ensure that stack is empty at this point */ | |||
g_assert (expr->expression_stack->len == 0); | |||
ret = rspamd_ast_process_node (expr, flags, expr->ast, data, track); | |||
ret = rspamd_ast_process_node (expr, expr->ast, process_data); | |||
/* Cleanup */ | |||
g_node_traverse (expr->ast, G_IN_ORDER, G_TRAVERSE_ALL, -1, | |||
@@ -1124,10 +1123,9 @@ rspamd_process_expression_track (struct rspamd_expression *expr, gint flags, | |||
} | |||
gdouble | |||
rspamd_process_expression (struct rspamd_expression *expr, gint flags, | |||
gpointer data) | |||
rspamd_process_expression (struct rspamd_expression *expr, struct rspamd_expr_process_data *process_data) | |||
{ | |||
return rspamd_process_expression_track (expr, flags, data, NULL); | |||
return rspamd_process_expression_track (expr, process_data); | |||
} | |||
static gboolean |
@@ -56,12 +56,24 @@ typedef struct rspamd_expression_atom_s { | |||
gint priority; | |||
} rspamd_expression_atom_t; | |||
struct rspamd_expr_process_data { | |||
/* Current Lua state to run atom processing */ | |||
struct lua_State *L; | |||
/* Parameter of lua-function processing atom*/ | |||
gint stack_item; | |||
gint flags; | |||
/* != NULL if trace is collected */ | |||
GPtrArray *trace; | |||
struct composites_data *cd; | |||
struct rspamd_task *task; | |||
}; | |||
struct rspamd_atom_subr { | |||
/* Parses atom from string and returns atom structure */ | |||
rspamd_expression_atom_t * (*parse)(const gchar *line, gsize len, | |||
rspamd_mempool_t *pool, gpointer ud, GError **err); | |||
/* Process atom via the opaque pointer (e.g. struct rspamd_task *) */ | |||
gdouble (*process) (gpointer input, rspamd_expression_atom_t *atom); | |||
gdouble (*process) (struct rspamd_expr_process_data *process_data, rspamd_expression_atom_t *atom); | |||
/* Calculates the relative priority of the expression */ | |||
gint (*priority) (rspamd_expression_atom_t *atom); | |||
void (*destroy) (rspamd_expression_atom_t *atom); | |||
@@ -92,8 +104,8 @@ gboolean rspamd_parse_expression (const gchar *line, gsize len, | |||
* @param data opaque data pointer for all the atoms | |||
* @return the value of expression | |||
*/ | |||
gdouble rspamd_process_expression (struct rspamd_expression *expr, gint flags, | |||
gpointer data); | |||
gdouble rspamd_process_expression (struct rspamd_expression *expr, | |||
struct rspamd_expr_process_data *process_data); | |||
/** | |||
* Process the expression and return its value using atom 'process' functions with the specified data pointer. | |||
@@ -103,8 +115,8 @@ gdouble rspamd_process_expression (struct rspamd_expression *expr, gint flags, | |||
* @param track pointer array to atoms tracking | |||
* @return the value of expression | |||
*/ | |||
gdouble rspamd_process_expression_track (struct rspamd_expression *expr, gint flags, | |||
gpointer data, GPtrArray *track); | |||
gdouble rspamd_process_expression_track (struct rspamd_expression *expr, | |||
struct rspamd_expr_process_data *process_data); | |||
/** | |||
* Shows string representation of an expression |
@@ -98,7 +98,7 @@ static const struct luaL_reg exprlib_f[] = { | |||
static rspamd_expression_atom_t * lua_atom_parse (const gchar *line, gsize len, | |||
rspamd_mempool_t *pool, gpointer ud, GError **err); | |||
static gdouble lua_atom_process (gpointer input, rspamd_expression_atom_t *atom); | |||
static gdouble lua_atom_process (struct rspamd_expr_process_data *process_data, rspamd_expression_atom_t *atom); | |||
static const struct rspamd_atom_subr lua_atom_subr = { | |||
.parse = lua_atom_parse, | |||
@@ -166,22 +166,22 @@ lua_atom_parse (const gchar *line, gsize len, | |||
} | |||
static gdouble | |||
lua_atom_process (gpointer input, rspamd_expression_atom_t *atom) | |||
lua_atom_process (struct rspamd_expr_process_data *process_data, rspamd_expression_atom_t *atom) | |||
{ | |||
struct lua_expression *e = (struct lua_expression *)atom->data; | |||
gdouble ret = 0; | |||
lua_rawgeti (e->L, LUA_REGISTRYINDEX, e->process_idx); | |||
lua_pushlstring (e->L, atom->str, atom->len); | |||
lua_pushvalue (e->L, GPOINTER_TO_INT (input)); | |||
lua_rawgeti (process_data->L, LUA_REGISTRYINDEX, e->process_idx); | |||
lua_pushlstring (process_data->L, atom->str, atom->len); | |||
lua_pushvalue (process_data->L, process_data->stack_item); | |||
if (lua_pcall (e->L, 2, 1, 0) != 0) { | |||
msg_info ("callback call failed: %s", lua_tostring (e->L, -1)); | |||
lua_pop (e->L, 1); | |||
if (lua_pcall (process_data->L, 2, 1, 0) != 0) { | |||
msg_info ("callback call failed: %s", lua_tostring (process_data->L, -1)); | |||
lua_pop (process_data->L, 1); | |||
} | |||
else { | |||
ret = lua_tonumber (e->L, -1); | |||
lua_pop (e->L, 1); | |||
ret = lua_tonumber (process_data->L, -1); | |||
lua_pop (process_data->L, 1); | |||
} | |||
return ret; | |||
@@ -195,11 +195,16 @@ lua_expr_process (lua_State *L) | |||
gdouble res; | |||
gint flags = 0; | |||
struct rspamd_expr_process_data process_data; | |||
memset (&process_data, 0, sizeof process_data); | |||
process_data.L = L; | |||
process_data.stack_item = 2; | |||
if (lua_gettop (L) >= 3) { | |||
flags = lua_tonumber (L, 3); | |||
process_data.flags = flags; | |||
} | |||
res = rspamd_process_expression (e->expr, flags, GINT_TO_POINTER (2)); | |||
res = rspamd_process_expression (e->expr, &process_data); | |||
lua_pushnumber (L, res); | |||
@@ -214,29 +219,36 @@ lua_expr_process_traced (lua_State *L) | |||
rspamd_expression_atom_t *atom; | |||
gint res; | |||
guint i; | |||
gint flags = 0; | |||
GPtrArray *trace; | |||
struct rspamd_expr_process_data process_data; | |||
memset (&process_data, 0, sizeof process_data); | |||
process_data.L = L; | |||
/* | |||
* stack:1 - self | |||
* stack:2 - data, see process_traced() definition for details | |||
*/ | |||
process_data.stack_item = 2; | |||
if (lua_gettop (L) >= 3) { | |||
flags = lua_tonumber (L, 3); | |||
process_data.flags = lua_tonumber (L, 3); | |||
} | |||
trace = g_ptr_array_sized_new (32); | |||
res = rspamd_process_expression_track (e->expr, flags, GINT_TO_POINTER (2), | |||
trace); | |||
process_data.trace = g_ptr_array_sized_new (32); | |||
res = rspamd_process_expression_track (e->expr, &process_data); | |||
lua_pushnumber (L, res); | |||
lua_createtable (L, trace->len, 0); | |||
lua_createtable (L, process_data.trace->len, 0); | |||
for (i = 0; i < trace->len; i ++) { | |||
atom = g_ptr_array_index (trace, i); | |||
for (i = 0; i < process_data.trace->len; i ++) { | |||
atom = g_ptr_array_index (process_data.trace, i); | |||
lua_pushlstring (L, atom->str, atom->len); | |||
lua_rawseti (L, -2, i + 1); | |||
} | |||
g_ptr_array_free (trace, TRUE); | |||
g_ptr_array_free (process_data.trace, TRUE); | |||
return 2; | |||
} |
@@ -433,7 +433,12 @@ process_regexp_item (struct rspamd_task *task, void *user_data) | |||
else { | |||
/* Process expression */ | |||
if (item->expr) { | |||
res = rspamd_process_expression (item->expr, 0, task); | |||
struct rspamd_expr_process_data process_data; | |||
memset (&process_data, 0, sizeof process_data); | |||
process_data.task = task; | |||
res = rspamd_process_expression (item->expr, &process_data); | |||
} | |||
else { | |||
msg_warn_task ("FIXME: %s symbol is broken with new expressions", |