diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2013-08-21 15:12:41 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2013-08-21 15:12:41 +0100 |
commit | 24d6fe7ee9d2362a199323d083d58bcdfe84df69 (patch) | |
tree | 9328909ff8006ffb17d245b98f1d7aa03bcbd970 /src/rcl | |
parent | 5607e21b22008b2f23d9f86aeeb0562f8a6671b8 (diff) | |
download | rspamd-24d6fe7ee9d2362a199323d083d58bcdfe84df69.tar.gz rspamd-24d6fe7ee9d2362a199323d083d58bcdfe84df69.zip |
Fix several problems in rcl parser.
Diffstat (limited to 'src/rcl')
-rw-r--r-- | src/rcl/rcl_parser.c | 43 | ||||
-rw-r--r-- | src/rcl/rcl_util.c | 16 |
2 files changed, 35 insertions, 24 deletions
diff --git a/src/rcl/rcl_parser.c b/src/rcl/rcl_parser.c index 3a5efb1a4..cf7384019 100644 --- a/src/rcl/rcl_parser.c +++ b/src/rcl/rcl_parser.c @@ -530,12 +530,6 @@ rspamd_cl_parse_key (struct rspamd_cl_parser *parser, p = chunk->pos; - /* Skip any spaces */ - while (p < chunk->end && g_ascii_isspace (*p)) { - rspamd_cl_chunk_skipc (chunk, *p); - p ++; - } - while (p < chunk->end) { /* * A key must start with alpha and end with space character @@ -564,6 +558,7 @@ rspamd_cl_parse_key (struct rspamd_cl_parser *parser, else { /* Invalid identifier */ rspamd_cl_set_err (chunk, RSPAMD_CL_ESYNTAX, "key must begin with a letter", err); + assert (0); return FALSE; } } @@ -934,7 +929,8 @@ rspamd_cl_parse_after_value (struct rspamd_cl_parser *parser, struct rspamd_cl_c */ static gboolean rspamd_cl_parse_macro_value (struct rspamd_cl_parser *parser, - struct rspamd_cl_chunk *chunk, struct rspamd_cl_macro *macro, GError **err) + struct rspamd_cl_chunk *chunk, struct rspamd_cl_macro *macro, + guchar const **macro_start, gsize *macro_len, GError **err) { const guchar *p, *c; @@ -950,9 +946,8 @@ rspamd_cl_parse_macro_value (struct rspamd_cl_parser *parser, return FALSE; } - if (!macro->handler (c + 1, chunk->pos - c - 2, macro->ud, err)) { - return FALSE; - } + *macro_start = c + 1; + *macro_len = chunk->pos - c - 2; p = chunk->pos; break; case '{': @@ -977,9 +972,8 @@ rspamd_cl_parse_macro_value (struct rspamd_cl_parser *parser, rspamd_cl_chunk_skipc (chunk, *p); p ++; } - if (!macro->handler (c, p - c, macro->ud, err)) { - return FALSE; - } + *macro_start = c; + *macro_len = p - c; rspamd_cl_chunk_skipc (chunk, *p); p ++; break; @@ -993,9 +987,8 @@ rspamd_cl_parse_macro_value (struct rspamd_cl_parser *parser, rspamd_cl_chunk_skipc (chunk, *p); p ++; } - if (!macro->handler (c, p - c, macro->ud, err)) { - return FALSE; - } + *macro_start = c; + *macro_len = p - c; break; } @@ -1025,12 +1018,12 @@ rspamd_cl_state_machine (struct rspamd_cl_parser *parser, GError **err) rspamd_cl_object_t *obj; struct rspamd_cl_chunk *chunk = parser->chunks; struct rspamd_cl_stack *st; - const guchar *p, *c; + const guchar *p, *c, *macro_start = NULL; + gsize macro_len = 0; struct rspamd_cl_macro *macro = NULL; p = chunk->pos; while (chunk->pos < chunk->end) { - parser->prev_state = parser->state; switch (parser->state) { case RSPAMD_RCL_STATE_INIT: /* @@ -1068,6 +1061,11 @@ rspamd_cl_state_machine (struct rspamd_cl_parser *parser, GError **err) } break; case RSPAMD_RCL_STATE_KEY: + /* Skip any spaces */ + while (p < chunk->end && g_ascii_isspace (*p)) { + rspamd_cl_chunk_skipc (chunk, *p); + p ++; + } if (*p == '}') { /* We have the end of an object */ parser->state = RSPAMD_RCL_STATE_AFTER_VALUE; @@ -1094,6 +1092,7 @@ rspamd_cl_state_machine (struct rspamd_cl_parser *parser, GError **err) return FALSE; } /* State is set in rspamd_cl_parse_value call */ + p = chunk->pos; break; case RSPAMD_RCL_STATE_AFTER_VALUE: if (!rspamd_cl_parse_after_value (parser, chunk, err)) { @@ -1114,6 +1113,7 @@ rspamd_cl_state_machine (struct rspamd_cl_parser *parser, GError **err) /* Skip everything at the end */ return TRUE; } + p = chunk->pos; break; case RSPAMD_RCL_STATE_MACRO_NAME: if (!g_ascii_isspace (*p)) { @@ -1147,12 +1147,17 @@ 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)) { + if (!rspamd_cl_parse_macro_value (parser, chunk, macro, + ¯o_start, ¯o_len, err)) { parser->prev_state = parser->state; parser->state = RSPAMD_RCL_STATE_ERROR; return FALSE; } parser->state = parser->prev_state; + if (!macro->handler (macro_start, macro_len, macro->ud, err)) { + return FALSE; + } + p = chunk->pos; break; default: /* TODO: add all states */ diff --git a/src/rcl/rcl_util.c b/src/rcl/rcl_util.c index aebc47dcc..57da0af5f 100644 --- a/src/rcl/rcl_util.c +++ b/src/rcl/rcl_util.c @@ -496,18 +496,24 @@ rspamd_cl_include_file (const guchar *data, gsize len, struct rspamd_cl_chunk *chunk; guchar *buf = NULL, *sigbuf = NULL; gsize buflen, siglen; - gchar filebuf[PATH_MAX]; + gchar filebuf[PATH_MAX], realbuf[PATH_MAX]; rspamd_snprintf (filebuf, sizeof (filebuf), "%*s", len, data); + if (realpath (filebuf, realbuf) == NULL) { + g_set_error (err, RCL_ERROR, RSPAMD_CL_EIO, "cannot open file %s: %s", + filebuf, + strerror (errno)); + return FALSE; + } - if (!rspamd_cl_fetch_file (filebuf, &buf, &buflen, err)) { + if (!rspamd_cl_fetch_file (realbuf, &buf, &buflen, err)) { return FALSE; } if (check_signature) { #ifdef HAVE_OPENSSL /* We need to check signature first */ - rspamd_snprintf (filebuf, sizeof (filebuf), "%*s.sig", len, data); + rspamd_snprintf (filebuf, sizeof (filebuf), "%s.sig", realbuf); if (!rspamd_cl_fetch_file (filebuf, &sigbuf, &siglen, err)) { return FALSE; } @@ -549,7 +555,7 @@ rspamd_cl_include_handler (const guchar *data, gsize len, gpointer ud, GError ** { struct rspamd_cl_parser *parser = ud; - if (*data == '/') { + if (*data == '/' || *data == '.') { /* Try to load a file */ return rspamd_cl_include_file (data, len, parser, FALSE, err); } @@ -570,7 +576,7 @@ rspamd_cl_includes_handler (const guchar *data, gsize len, gpointer ud, GError * { struct rspamd_cl_parser *parser = ud; - if (*data == '/') { + if (*data == '/' || *data == '.') { /* Try to load a file */ return rspamd_cl_include_file (data, len, parser, TRUE, err); } |