aboutsummaryrefslogtreecommitdiffstats
path: root/src/lua/lua_xmlrpc.c
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2018-01-13 12:39:09 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2018-01-13 12:39:09 +0000
commit68b2004757a24da102276307c9d49b045d786f19 (patch)
treec7843e41fecf352f5c3e9ae4040cefa9d2e4e56f /src/lua/lua_xmlrpc.c
parent07bb08245320b20c81df9c50cfeabb3baffbd935 (diff)
downloadrspamd-68b2004757a24da102276307c9d49b045d786f19.tar.gz
rspamd-68b2004757a24da102276307c9d49b045d786f19.zip
[Rework] Improve readability of xmlrpc API
Diffstat (limited to 'src/lua/lua_xmlrpc.c')
-rw-r--r--src/lua/lua_xmlrpc.c272
1 files changed, 154 insertions, 118 deletions
diff --git a/src/lua/lua_xmlrpc.c b/src/lua/lua_xmlrpc.c
index 01850af70..96edee804 100644
--- a/src/lua/lua_xmlrpc.c
+++ b/src/lua/lua_xmlrpc.c
@@ -26,9 +26,34 @@ static const struct luaL_reg xmlrpclib_m[] = {
{NULL, NULL}
};
+enum lua_xmlrpc_state {
+ read_method_responce = 0,
+ read_params = 1,
+ read_param = 2,
+ read_param_value = 3,
+ read_param_element = 4,
+ read_struct = 5,
+ read_struct_member_name = 6,
+ read_struct_member_value = 7,
+ read_struct_element = 8,
+ read_string = 9,
+ read_int = 10,
+ read_double = 11,
+ read_array = 12,
+ read_array_value = 13,
+ read_array_element = 14,
+ error_state = 99,
+ success_state = 100,
+};
+
+enum lua_xmlrpc_stack {
+ st_array = 1,
+ st_struct = 2,
+};
+
struct lua_xmlrpc_ud {
- gint parser_state;
- gint depth;
+ enum lua_xmlrpc_state parser_state;
+ GQueue *st;
gint param_count;
gboolean got_text;
lua_State *L;
@@ -76,206 +101,208 @@ xmlrpc_start_element (GMarkupParseContext *context,
GError **error)
{
struct lua_xmlrpc_ud *ud = user_data;
- int last_state;
+ enum lua_xmlrpc_state last_state;
last_state = ud->parser_state;
switch (ud->parser_state) {
- case 0:
+ case read_method_responce:
/* Expect tag methodResponse */
if (g_ascii_strcasecmp (name, "methodResponse") == 0) {
- ud->parser_state = 1;
+ ud->parser_state =read_params;
}
else {
/* Error state */
- ud->parser_state = 99;
+ ud->parser_state = error_state;
}
break;
- case 1:
+ case read_params:
/* Expect tag params */
if (g_ascii_strcasecmp (name, "params") == 0) {
- ud->parser_state = 2;
+ ud->parser_state = read_param;
/* result -> table of params indexed by int */
lua_newtable (ud->L);
}
else {
/* Error state */
- ud->parser_state = 99;
+ ud->parser_state = error_state;
}
break;
- case 2:
+ case read_param:
/* Expect tag param */
if (g_ascii_strcasecmp (name, "param") == 0) {
- ud->parser_state = 3;
+ ud->parser_state = read_param_value;
/* Create new param */
}
else {
/* Error state */
- ud->parser_state = 99;
+ ud->parser_state = error_state;
}
break;
- case 3:
+ case read_param_value:
/* Expect tag value */
if (g_ascii_strcasecmp (name, "value") == 0) {
- ud->parser_state = 4;
+ ud->parser_state = read_param_element;
}
else {
/* Error state */
- ud->parser_state = 99;
+ ud->parser_state = error_state;
}
break;
- case 4:
+ case read_param_element:
/* Expect tag struct */
if (g_ascii_strcasecmp (name, "struct") == 0) {
- ud->parser_state = 5;
+ ud->parser_state = read_struct;
/* Create new param of table type */
lua_newtable (ud->L);
- ud->depth++;
+ g_queue_push_head (ud->st, GINT_TO_POINTER (st_struct));
}
else if (g_ascii_strcasecmp (name, "array") == 0) {
- ud->parser_state = 14;
+ ud->parser_state = read_array;
/* Create new param of table type */
lua_newtable (ud->L);
- ud->depth++;
+ g_queue_push_head (ud->st, GINT_TO_POINTER (st_array));
}
else if (g_ascii_strcasecmp (name, "string") == 0) {
- ud->parser_state = 11;
+ ud->parser_state = read_string;
ud->got_text = FALSE;
}
else if (g_ascii_strcasecmp (name, "int") == 0) {
- ud->parser_state = 12;
+ ud->parser_state = read_int;
ud->got_text = FALSE;
}
else if (g_ascii_strcasecmp (name, "double") == 0) {
- ud->parser_state = 13;
+ ud->parser_state = read_double;
ud->got_text = FALSE;
}
else {
/* Error state */
- ud->parser_state = 99;
+ ud->parser_state = error_state;
}
break;
- case 5:
+ case read_struct:
/* Parse structure */
/* Expect tag member */
if (g_ascii_strcasecmp (name, "member") == 0) {
- ud->parser_state = 6;
+ ud->parser_state = read_struct_member_name;
}
else {
/* Error state */
- ud->parser_state = 99;
+ ud->parser_state = error_state;
}
break;
- case 6:
+ case read_struct_member_name:
/* Expect tag name */
if (g_ascii_strcasecmp (name, "name") == 0) {
- ud->parser_state = 7;
+ ud->parser_state = read_struct_member_value;
}
else {
/* Error state */
- ud->parser_state = 99;
+ ud->parser_state = error_state;
}
break;
- case 7:
+ case read_struct_member_value:
/* Accept value */
if (g_ascii_strcasecmp (name, "value") == 0) {
- ud->parser_state = 8;
+ ud->parser_state = read_struct_element;
}
else {
/* Error state */
- ud->parser_state = 99;
+ ud->parser_state = error_state;
}
break;
- case 8:
+ case read_struct_element:
/* Parse any values */
/* Primitives */
if (g_ascii_strcasecmp (name, "string") == 0) {
- ud->parser_state = 11;
+ ud->parser_state = read_string;
ud->got_text = FALSE;
}
else if (g_ascii_strcasecmp (name, "int") == 0) {
- ud->parser_state = 12;
+ ud->parser_state = read_int;
ud->got_text = FALSE;
}
else if (g_ascii_strcasecmp (name, "double") == 0) {
- ud->parser_state = 13;
+ ud->parser_state = read_double;
ud->got_text = FALSE;
}
/* Structure */
else if (g_ascii_strcasecmp (name, "struct") == 0) {
- ud->parser_state = 5;
+ ud->parser_state = read_struct;
/* Create new param of table type */
lua_newtable (ud->L);
- ud->depth++;
+ g_queue_push_head (ud->st, GINT_TO_POINTER (st_struct));
}
else if (g_ascii_strcasecmp (name, "array") == 0) {
- ud->parser_state = 14;
+ ud->parser_state = read_array;
/* Create new param of table type */
lua_newtable (ud->L);
- ud->depth++;
+ g_queue_push_head (ud->st, GINT_TO_POINTER (st_array));
}
else {
/* Error state */
- ud->parser_state = 99;
+ ud->parser_state = error_state;
}
break;
- case 14:
+ case read_array:
/* Parse array */
/* Expect data */
if (g_ascii_strcasecmp (name, "data") == 0) {
- ud->parser_state = 15;
+ ud->parser_state = read_array_value;
}
else {
/* Error state */
- ud->parser_state = 99;
+ ud->parser_state = error_state;
}
break;
- case 15:
+ case read_array_value:
/* Accept array value */
if (g_ascii_strcasecmp (name, "value") == 0) {
- ud->parser_state = 16;
+ ud->parser_state = read_array_element;
}
else {
/* Error state */
- ud->parser_state = 99;
+ ud->parser_state = error_state;
}
break;
- case 16:
+ case read_array_element:
/* Parse any values */
/* Primitives */
if (g_ascii_strcasecmp (name, "string") == 0) {
- ud->parser_state = 11;
+ ud->parser_state = read_string;
ud->got_text = FALSE;
}
else if (g_ascii_strcasecmp (name, "int") == 0) {
- ud->parser_state = 12;
+ ud->parser_state = read_int;
ud->got_text = FALSE;
}
else if (g_ascii_strcasecmp (name, "double") == 0) {
- ud->parser_state = 13;
+ ud->parser_state = read_double;
ud->got_text = FALSE;
}
/* Structure */
else if (g_ascii_strcasecmp (name, "struct") == 0) {
- ud->parser_state = 5;
+ ud->parser_state = read_struct;
/* Create new param of table type */
lua_newtable (ud->L);
- ud->depth++;
+ g_queue_push_head (ud->st, GINT_TO_POINTER (st_struct));
}
else if (g_ascii_strcasecmp (name, "array") == 0) {
- ud->parser_state = 14;
+ ud->parser_state = read_array;
/* Create new param of table type */
lua_newtable (ud->L);
- ud->depth++;
+ g_queue_push_head (ud->st, GINT_TO_POINTER (st_array));
}
else {
/* Error state */
- ud->parser_state = 99;
+ ud->parser_state = error_state;
}
break;
+ default:
+ break;
}
- if (ud->parser_state == 99) {
+ if (ud->parser_state == error_state) {
g_set_error (error,
xmlrpc_error_quark (), 1, "xmlrpc parse error on state: %d, while parsing start tag: %s",
last_state, name);
@@ -289,108 +316,112 @@ xmlrpc_end_element (GMarkupParseContext *context,
GError **error)
{
struct lua_xmlrpc_ud *ud = user_data;
- int last_state;
+ enum lua_xmlrpc_state last_state;
last_state = ud->parser_state;
switch (ud->parser_state) {
- case 0:
- ud->parser_state = 99;
+ case read_method_responce:
+ ud->parser_state = error_state;
break;
- case 1:
+ case read_params:
/* Got methodResponse */
if (g_ascii_strcasecmp (name, "methodResponse") == 0) {
/* End processing */
- ud->parser_state = 100;
+ ud->parser_state = success_state;
}
else {
/* Error state */
- ud->parser_state = 99;
+ ud->parser_state = error_state;
}
break;
- case 2:
+ case read_param:
/* Got tag params */
if (g_ascii_strcasecmp (name, "params") == 0) {
- ud->parser_state = 1;
+ ud->parser_state = read_params;
}
else {
/* Error state */
- ud->parser_state = 99;
+ ud->parser_state = error_state;
}
break;
- case 3:
+ case read_param_value:
/* Got tag param */
if (g_ascii_strcasecmp (name, "param") == 0) {
- ud->parser_state = 2;
+ ud->parser_state = read_param;
lua_rawseti (ud->L, -2, ++ud->param_count);
}
else {
/* Error state */
- ud->parser_state = 99;
+ ud->parser_state = error_state;
}
break;
- case 4:
+ case read_param_element:
/* Got tag value */
if (g_ascii_strcasecmp (name, "value") == 0) {
- if (ud->depth == 0) {
- ud->parser_state = 3;
+ if (g_queue_get_length (ud->st) == 0) {
+ ud->parser_state = read_param_value;
}
else {
- /* Parse other members */
- ud->parser_state = 6;
+ if (GPOINTER_TO_INT (g_queue_peek_head (ud->st)) == st_struct) {
+ ud->parser_state = read_struct_member_name;
+ }
+ else {
+ ud->parser_state = read_array_value;
+ }
}
}
else {
/* Error state */
- ud->parser_state = 99;
+ ud->parser_state = error_state;
}
break;
- case 5:
+ case read_struct:
/* Got tag struct */
if (g_ascii_strcasecmp (name, "struct") == 0) {
- ud->parser_state = 4;
- ud->depth--;
+ ud->parser_state = read_param_element;
+ g_queue_pop_head (ud->st);
}
else {
/* Error state */
- ud->parser_state = 99;
+ ud->parser_state = error_state;
}
break;
- case 6:
+ case read_struct_member_name:
/* Got tag member */
if (g_ascii_strcasecmp (name, "member") == 0) {
- ud->parser_state = 5;
+ ud->parser_state = read_struct;
/* Set table */
lua_settable (ud->L, -3);
}
else {
/* Error state */
- ud->parser_state = 99;
+ ud->parser_state = error_state;
}
break;
- case 7:
+ case read_struct_member_value:
/* Got tag name */
if (g_ascii_strcasecmp (name, "name") == 0) {
- ud->parser_state = 7;
+ ud->parser_state = read_struct_member_value;
}
else {
/* Error state */
- ud->parser_state = 99;
+ ud->parser_state = error_state;
}
break;
- case 8:
+ case read_struct_element:
/* Got tag value */
if (g_ascii_strcasecmp (name, "value") == 0) {
- ud->parser_state = 6;
+ ud->parser_state = read_struct_member_name;
}
else {
/* Error state */
- ud->parser_state = 99;
+ ud->parser_state = error_state;
}
break;
- case 11:
- case 12:
- case 13:
+ case read_string:
+ case read_int:
+ case read_double:
/* Parse any values */
/* Handle empty tags */
if (!ud->got_text) {
@@ -400,32 +431,33 @@ xmlrpc_end_element (GMarkupParseContext *context,
ud->got_text = FALSE;
}
/* Primitives */
- if (g_ascii_strcasecmp (name, "string") == 0) {
- ud->parser_state = 8;
- }
- else if (g_ascii_strcasecmp (name, "int") == 0) {
- ud->parser_state = 8;
- }
- else if (g_ascii_strcasecmp (name, "double") == 0) {
- ud->parser_state = 8;
+ if (g_ascii_strcasecmp (name, "string") == 0 ||
+ g_ascii_strcasecmp (name, "int") == 0 ||
+ g_ascii_strcasecmp (name, "double") == 0) {
+ if (GPOINTER_TO_INT (g_queue_peek_head (ud->st)) == st_struct) {
+ ud->parser_state = read_struct_element;
+ }
+ else {
+ ud->parser_state = read_array_element;
+ }
}
else {
/* Error state */
- ud->parser_state = 99;
+ ud->parser_state = error_state;
}
break;
- case 14:
+ case read_array:
/* Got tag array */
if (g_ascii_strcasecmp (name, "array") == 0) {
- ud->parser_state = 4;
- ud->depth--;
+ ud->parser_state = read_param_element;
+ g_queue_pop_head (ud->st);
}
else {
/* Error state */
- ud->parser_state = 99;
+ ud->parser_state = error_state;
}
break;
- case 15:
+ case read_array_value:
/* Got tag data */
if (g_ascii_strcasecmp (name, "data") == 0) {
ud->parser_state = 14;
@@ -435,21 +467,23 @@ xmlrpc_end_element (GMarkupParseContext *context,
ud->parser_state = 99;
}
break;
- case 17:
+ case read_array_element:
/* Got tag value */
if (g_ascii_strcasecmp (name, "value") == 0) {
guint tbl_len = rspamd_lua_table_size (ud->L, -2);
lua_rawseti (ud->L, -2, tbl_len + 1);
- ud->parser_state = 15;
+ ud->parser_state = read_array_value;
}
else {
/* Error state */
- ud->parser_state = 99;
+ ud->parser_state = error_state;
}
break;
+ default:
+ break;
}
- if (ud->parser_state == 99) {
+ if (ud->parser_state == error_state) {
g_set_error (error,
xmlrpc_error_quark (), 1, "xmlrpc parse error on state: %d, while parsing end tag: %s",
last_state, name);
@@ -464,7 +498,7 @@ xmlrpc_text (GMarkupParseContext *context,
GError **error)
{
struct lua_xmlrpc_ud *ud = user_data;
- gint num;
+ gulong num;
gdouble dnum;
/* Strip line */
@@ -479,24 +513,26 @@ xmlrpc_text (GMarkupParseContext *context,
if (text_len > 0) {
switch (ud->parser_state) {
- case 7:
+ case read_struct_member_value:
/* Push key */
lua_pushlstring (ud->L, text, text_len);
break;
- case 11:
+ case read_string:
/* Push string value */
lua_pushlstring (ud->L, text, text_len);
break;
- case 12:
+ case read_int:
/* Push integer value */
- num = strtoul (text, NULL, 10);
+ rspamd_strtoul (text, text_len, &num);
lua_pushnumber (ud->L, num);
break;
- case 13:
+ case read_double:
/* Push integer value */
dnum = strtod (text, NULL);
lua_pushnumber (ud->L, dnum);
break;
+ default:
+ break;
}
ud->got_text = TRUE;
}
@@ -522,9 +558,9 @@ lua_xmlrpc_parse_reply (lua_State *L)
if (data != NULL) {
ud.L = L;
- ud.parser_state = 0;
- ud.depth = 0;
+ ud.parser_state = read_method_responce;
ud.param_count = 0;
+ ud.st = g_queue_new ();
ctx = g_markup_parse_context_new (&xmlrpc_parser,
G_MARKUP_TREAT_CDATA_AS_TEXT, &ud, NULL);