summaryrefslogtreecommitdiffstats
path: root/src/rcl
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2013-08-16 17:26:16 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2013-08-16 17:26:16 +0100
commitfc9dbea5f5e423a12d5c8d7324ef48e7369b675c (patch)
tree8f8b3ae6b8f4b439b292d66be8f4821a5045795a /src/rcl
parentbc93613db3a49f7b0570eb9b91c5de4b243f9e2c (diff)
downloadrspamd-fc9dbea5f5e423a12d5c8d7324ef48e7369b675c.tar.gz
rspamd-fc9dbea5f5e423a12d5c8d7324ef48e7369b675c.zip
Add macro value parsing code.
Diffstat (limited to 'src/rcl')
-rw-r--r--src/rcl/rcl_parser.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/src/rcl/rcl_parser.c b/src/rcl/rcl_parser.c
index 1c13922dd..c38edb943 100644
--- a/src/rcl/rcl_parser.c
+++ b/src/rcl/rcl_parser.c
@@ -954,6 +954,92 @@ rspamd_cl_parse_after_value (struct rspamd_cl_parser *parser, struct rspamd_cl_c
}
/**
+ * Handle macro data
+ * @param parser
+ * @param chunk
+ * @param err
+ * @return
+ */
+static gboolean
+rspamd_cl_parse_macro_value (struct rspamd_cl_parser *parser,
+ struct rspamd_cl_chunk *chunk, struct rspamd_cl_macro *macro, GError **err)
+{
+ const guchar *p, *c;
+
+ p = chunk->pos;
+
+ switch (*p) {
+ case '"':
+ /* We have macro value encoded in quotes */
+ c = p;
+ rspamd_cl_chunk_skipc (chunk, *p);
+ p ++;
+ if (!rspamd_cl_lex_json_string (parser, chunk, err)) {
+ return FALSE;
+ }
+
+ if (!macro->handler (c + 1, chunk->pos - c - 2, macro->ud, err)) {
+ return FALSE;
+ }
+ p = chunk->pos;
+ break;
+ case '{':
+ /* We got a multiline macro body */
+ rspamd_cl_chunk_skipc (chunk, *p);
+ p ++;
+ /* Skip spaces at the beginning */
+ while (p < chunk->end) {
+ if (g_ascii_isspace (*p)) {
+ rspamd_cl_chunk_skipc (chunk, *p);
+ p ++;
+ }
+ else {
+ break;
+ }
+ }
+ c = p;
+ while (p < chunk->end) {
+ if (*p == '}') {
+ break;
+ }
+ rspamd_cl_chunk_skipc (chunk, *p);
+ p ++;
+ }
+ if (!macro->handler (c, p - c, macro->ud, err)) {
+ return FALSE;
+ }
+ rspamd_cl_chunk_skipc (chunk, *p);
+ p ++;
+ break;
+ default:
+ /* Macro is not enclosed in quotes or braces */
+ c = p;
+ while (p < chunk->end) {
+ if (rspamd_cl_lex_is_atom_end (*p)) {
+ break;
+ }
+ rspamd_cl_chunk_skipc (chunk, *p);
+ p ++;
+ }
+ if (!macro->handler (c, p - c, macro->ud, err)) {
+ return FALSE;
+ }
+ break;
+ }
+
+ /* We are at the end of a macro */
+ /* Skip ';' and space characters and return to previous state */
+ while (p < chunk->end) {
+ if (!g_ascii_isspace (*p) && *p != ';') {
+ break;
+ }
+ rspamd_cl_chunk_skipc (chunk, *p);
+ p ++;
+ }
+ return TRUE;
+}
+
+/**
* Handle the main states of rcl parser
* @param parser parser structure
* @param data the pointer to the beginning of a chunk
@@ -1089,6 +1175,12 @@ rspamd_cl_state_machine (struct rspamd_cl_parser *parser, GError **err)
}
break;
case RSPAMD_RCL_STATE_MACRO:
+ if (!rspamd_cl_parse_macro_value (parser, chunk, macro, err)) {
+ parser->prev_state = parser->state;
+ parser->state = RSPAMD_RCL_STATE_ERROR;
+ return FALSE;
+ }
+ parser->state = parser->prev_state;
break;
default:
/* TODO: add all states */