From 03a70b9d49723c72525a0ab8f2494095027a95a6 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Fri, 11 Oct 2013 15:16:07 +0100 Subject: [PATCH] Fix rcl parser. --- src/rcl/rcl_chartable.h | 38 +++++++++++++++++++++++--------------- src/rcl/rcl_parser.c | 27 ++++++++++++++++++--------- test/rspamd_rcl_test.c | 29 ++++++++++++++++++++++++++++- 3 files changed, 69 insertions(+), 25 deletions(-) diff --git a/src/rcl/rcl_chartable.h b/src/rcl/rcl_chartable.h index aae5c2c5d..50eca9c0c 100644 --- a/src/rcl/rcl_chartable.h +++ b/src/rcl/rcl_chartable.h @@ -39,13 +39,17 @@ RCL_CHARACTER_DENIED, RCL_CHARACTER_DENIED, RCL_CHARACTER_DENIED, RCL_CHARACTER_DENIED, RCL_CHARACTER_DENIED, RCL_CHARACTER_DENIED, RCL_CHARACTER_DENIED, RCL_CHARACTER_DENIED, RCL_CHARACTER_DENIED, RCL_CHARACTER_DENIED, RCL_CHARACTER_DENIED, -RCL_CHARACTER_WHITESPACE|RCL_CHARACTER_VALUE_STR, RCL_CHARACTER_VALUE_STR, -RCL_CHARACTER_VALUE_STR, RCL_CHARACTER_VALUE_END, RCL_CHARACTER_VALUE_STR, -RCL_CHARACTER_VALUE_STR, RCL_CHARACTER_VALUE_STR, RCL_CHARACTER_VALUE_STR, -RCL_CHARACTER_VALUE_STR, RCL_CHARACTER_VALUE_STR, RCL_CHARACTER_VALUE_STR, -RCL_CHARACTER_VALUE_STR|RCL_CHARACTER_VALUE_DIGIT, RCL_CHARACTER_VALUE_STR, -RCL_CHARACTER_KEY|RCL_CHARACTER_VALUE_STR|RCL_CHARACTER_VALUE_DIGIT_START|RCL_CHARACTER_VALUE_DIGIT, -RCL_CHARACTER_VALUE_STR|RCL_CHARACTER_VALUE_DIGIT, RCL_CHARACTER_VALUE_END, +RCL_CHARACTER_WHITESPACE|RCL_CHARACTER_VALUE_STR /* */, +RCL_CHARACTER_VALUE_STR /* ! */, RCL_CHARACTER_VALUE_STR /* " */, +RCL_CHARACTER_VALUE_END /* # */, RCL_CHARACTER_VALUE_STR /* $ */, +RCL_CHARACTER_VALUE_STR /* % */, RCL_CHARACTER_VALUE_STR /* & */, +RCL_CHARACTER_VALUE_STR /* ' */, RCL_CHARACTER_VALUE_STR /* ( */, +RCL_CHARACTER_VALUE_STR /* ) */, RCL_CHARACTER_VALUE_STR /* * */, +RCL_CHARACTER_VALUE_STR|RCL_CHARACTER_VALUE_DIGIT /* + */, +RCL_CHARACTER_VALUE_END /* , */, +RCL_CHARACTER_KEY|RCL_CHARACTER_VALUE_STR|RCL_CHARACTER_VALUE_DIGIT_START|RCL_CHARACTER_VALUE_DIGIT /* - */, +RCL_CHARACTER_VALUE_STR|RCL_CHARACTER_VALUE_DIGIT /* . */, +RCL_CHARACTER_VALUE_STR /* / */, RCL_CHARACTER_KEY|RCL_CHARACTER_VALUE_STR|RCL_CHARACTER_VALUE_DIGIT_START|RCL_CHARACTER_VALUE_DIGIT /* 0 */, RCL_CHARACTER_KEY|RCL_CHARACTER_VALUE_STR|RCL_CHARACTER_VALUE_DIGIT_START|RCL_CHARACTER_VALUE_DIGIT /* 1 */, RCL_CHARACTER_KEY|RCL_CHARACTER_VALUE_STR|RCL_CHARACTER_VALUE_DIGIT_START|RCL_CHARACTER_VALUE_DIGIT /* 2 */, @@ -56,9 +60,10 @@ RCL_CHARACTER_KEY|RCL_CHARACTER_VALUE_STR|RCL_CHARACTER_VALUE_DIGIT_START|RCL_CH RCL_CHARACTER_KEY|RCL_CHARACTER_VALUE_STR|RCL_CHARACTER_VALUE_DIGIT_START|RCL_CHARACTER_VALUE_DIGIT /* 7 */, RCL_CHARACTER_KEY|RCL_CHARACTER_VALUE_STR|RCL_CHARACTER_VALUE_DIGIT_START|RCL_CHARACTER_VALUE_DIGIT /* 8 */, RCL_CHARACTER_KEY|RCL_CHARACTER_VALUE_STR|RCL_CHARACTER_VALUE_DIGIT_START|RCL_CHARACTER_VALUE_DIGIT /* 9 */, -RCL_CHARACTER_VALUE_STR, RCL_CHARACTER_VALUE_END, RCL_CHARACTER_VALUE_STR, -RCL_CHARACTER_VALUE_STR, RCL_CHARACTER_VALUE_STR, RCL_CHARACTER_VALUE_STR, -RCL_CHARACTER_VALUE_STR, +RCL_CHARACTER_VALUE_STR /* : */, RCL_CHARACTER_VALUE_END /* ; */, +RCL_CHARACTER_VALUE_STR /* < */, RCL_CHARACTER_VALUE_STR /* = */, +RCL_CHARACTER_VALUE_STR /* > */, RCL_CHARACTER_VALUE_STR /* ? */, +RCL_CHARACTER_VALUE_STR /* @ */, RCL_CHARACTER_KEY_START|RCL_CHARACTER_KEY|RCL_CHARACTER_VALUE_STR|RCL_CHARACTER_VALUE_DIGIT /* A */, RCL_CHARACTER_KEY_START|RCL_CHARACTER_KEY|RCL_CHARACTER_VALUE_STR|RCL_CHARACTER_VALUE_DIGIT /* B */, RCL_CHARACTER_KEY_START|RCL_CHARACTER_KEY|RCL_CHARACTER_VALUE_STR|RCL_CHARACTER_VALUE_DIGIT /* C */, @@ -85,9 +90,10 @@ RCL_CHARACTER_KEY_START|RCL_CHARACTER_KEY|RCL_CHARACTER_VALUE_STR|RCL_CHARACTER_ RCL_CHARACTER_KEY_START|RCL_CHARACTER_KEY|RCL_CHARACTER_VALUE_STR|RCL_CHARACTER_VALUE_DIGIT /* X */, RCL_CHARACTER_KEY_START|RCL_CHARACTER_KEY|RCL_CHARACTER_VALUE_STR|RCL_CHARACTER_VALUE_DIGIT /* Y */, RCL_CHARACTER_KEY_START|RCL_CHARACTER_KEY|RCL_CHARACTER_VALUE_STR|RCL_CHARACTER_VALUE_DIGIT /* Z */, -RCL_CHARACTER_VALUE_END, RCL_CHARACTER_VALUE_STR, RCL_CHARACTER_VALUE_STR, -RCL_CHARACTER_VALUE_STR, RCL_CHARACTER_KEY|RCL_CHARACTER_VALUE_STR, -RCL_CHARACTER_VALUE_STR, +RCL_CHARACTER_VALUE_STR /* [ */, RCL_CHARACTER_VALUE_STR /* \ */, +RCL_CHARACTER_VALUE_END /* ] */, RCL_CHARACTER_VALUE_STR /* ^ */, +RCL_CHARACTER_KEY|RCL_CHARACTER_VALUE_STR /* _ */, +RCL_CHARACTER_VALUE_STR /* ` */, RCL_CHARACTER_KEY_START|RCL_CHARACTER_KEY|RCL_CHARACTER_VALUE_STR|RCL_CHARACTER_VALUE_DIGIT /* a */, RCL_CHARACTER_KEY_START|RCL_CHARACTER_KEY|RCL_CHARACTER_VALUE_STR|RCL_CHARACTER_VALUE_DIGIT /* b */, RCL_CHARACTER_KEY_START|RCL_CHARACTER_KEY|RCL_CHARACTER_VALUE_STR|RCL_CHARACTER_VALUE_DIGIT /* c */, @@ -114,8 +120,9 @@ RCL_CHARACTER_KEY_START|RCL_CHARACTER_KEY|RCL_CHARACTER_VALUE_STR|RCL_CHARACTER_ RCL_CHARACTER_KEY_START|RCL_CHARACTER_KEY|RCL_CHARACTER_VALUE_STR|RCL_CHARACTER_VALUE_DIGIT /* x */, RCL_CHARACTER_KEY_START|RCL_CHARACTER_KEY|RCL_CHARACTER_VALUE_STR|RCL_CHARACTER_VALUE_DIGIT /* y */, RCL_CHARACTER_KEY_START|RCL_CHARACTER_KEY|RCL_CHARACTER_VALUE_STR|RCL_CHARACTER_VALUE_DIGIT /* z */, -RCL_CHARACTER_VALUE_END, RCL_CHARACTER_VALUE_STR, RCL_CHARACTER_VALUE_STR, -RCL_CHARACTER_VALUE_STR, RCL_CHARACTER_DENIED, +RCL_CHARACTER_VALUE_STR /* { */, RCL_CHARACTER_VALUE_STR /* | */, +RCL_CHARACTER_VALUE_END /* } */, RCL_CHARACTER_VALUE_STR /* ~ */, +RCL_CHARACTER_DENIED, RCL_CHARACTER_KEY_START|RCL_CHARACTER_KEY|RCL_CHARACTER_VALUE_STR, RCL_CHARACTER_KEY_START|RCL_CHARACTER_KEY|RCL_CHARACTER_VALUE_STR, RCL_CHARACTER_KEY_START|RCL_CHARACTER_KEY|RCL_CHARACTER_VALUE_STR, @@ -246,4 +253,5 @@ RCL_CHARACTER_KEY_START|RCL_CHARACTER_KEY|RCL_CHARACTER_VALUE_STR }; + #endif /* RCL_CHARTABLE_H_ */ diff --git a/src/rcl/rcl_parser.c b/src/rcl/rcl_parser.c index 13bf25c71..1b09fe283 100644 --- a/src/rcl/rcl_parser.c +++ b/src/rcl/rcl_parser.c @@ -76,32 +76,35 @@ rspamd_cl_skip_comments (struct rspamd_cl_parser *parser, GError **err) p = chunk->pos; +start: if (*p == '#') { if (parser->state != RSPAMD_RCL_STATE_SCOMMENT && parser->state != RSPAMD_RCL_STATE_MCOMMENT) { while (p < chunk->end) { if (*p == '\n') { rspamd_cl_chunk_skipc (chunk, *++p); - break; + /* Check comments again */ + goto start; } rspamd_cl_chunk_skipc (chunk, *++p); } } } else if (*p == '/' && chunk->remain >= 2) { - rspamd_cl_chunk_skipc (chunk, *++p); - if (*p == '/' && parser->state != RSPAMD_RCL_STATE_SCOMMENT && + if (p[1] == '/' && parser->state != RSPAMD_RCL_STATE_SCOMMENT && parser->state != RSPAMD_RCL_STATE_MCOMMENT) { + rspamd_cl_chunk_skipc (chunk, *++p); chunk->pos = p; while (p < chunk->end) { if (*p == '\n') { rspamd_cl_chunk_skipc (chunk, *++p); - break; + goto start; } rspamd_cl_chunk_skipc (chunk, *++p); } } - else if (*p == '*') { + else if (p[1] == '*') { + rspamd_cl_chunk_skipc (chunk, *++p); comments_nested ++; rspamd_cl_chunk_skipc (chunk, *++p); @@ -112,7 +115,7 @@ rspamd_cl_skip_comments (struct rspamd_cl_parser *parser, GError **err) comments_nested --; if (comments_nested == 0) { rspamd_cl_chunk_skipc (chunk, *++p); - break; + goto start; } } rspamd_cl_chunk_skipc (chunk, *++p); @@ -693,7 +696,7 @@ rspamd_cl_parse_string_value (struct rspamd_cl_parser *parser, p = chunk->pos; while (p < chunk->end) { - if (rspamd_cl_lex_is_atom_end (*p)) { + if (rspamd_cl_lex_is_atom_end (*p) || rspamd_cl_lex_is_comment (p[0], p[1])) { break; } rspamd_cl_chunk_skipc (chunk, *p); @@ -775,6 +778,7 @@ rspamd_cl_parse_value (struct rspamd_cl_parser *parser, struct rspamd_cl_chunk * const guchar *p, *c; struct rspamd_cl_stack *st; rspamd_cl_object_t *obj = NULL; + guint stripped_spaces; p = chunk->pos; @@ -860,8 +864,13 @@ rspamd_cl_parse_value (struct rspamd_cl_parser *parser, struct rspamd_cl_chunk * return FALSE; } if (!rspamd_cl_maybe_parse_boolean (obj, c, chunk->pos - c)) { - obj->value.sv = g_malloc (chunk->pos - c + 1); - rspamd_strlcpy (obj->value.sv, c, chunk->pos - c + 1); + /* Cut trailing spaces */ + stripped_spaces = 0; + while (g_ascii_isspace (*(chunk->pos - 1 - stripped_spaces))) { + stripped_spaces ++; + } + obj->value.sv = g_malloc (chunk->pos - c + 1 - stripped_spaces); + rspamd_strlcpy (obj->value.sv, c, chunk->pos - c + 1 - stripped_spaces); rspamd_cl_unescape_json_string (obj->value.sv); obj->type = RSPAMD_CL_STRING; } diff --git a/test/rspamd_rcl_test.c b/test/rspamd_rcl_test.c index fabfea29e..9d8399baf 100644 --- a/test/rspamd_rcl_test.c +++ b/test/rspamd_rcl_test.c @@ -50,7 +50,34 @@ const gchar *rcl_test_valid[] = { "key3 = 111some," "key4: s1," "\"key5\": \"\\n\\r123\"", - /* Macros */ + "" + "#packagesite http//pkg.freebsd.org/freebsd-9-amd64/latest\n" + "#packagesite http//pkg.freebsd.org/freebsd-9-amd64/latest\n" + "ALIAS : {\n" + " all-depends: query %dn-%dv,\n" + " annotations: info -A,\n" + " build-depends: info -qd,\n" + " download: fetch,\n" + " iinfo: info -i -g -x,\n" + " isearch: search -i -g -x,\n" + " leaf: query -e '%a == 0' '%n-%v',\n" + " leaf: query -e '%a == 0' '%n-%v',\n" + " list: info -ql,\n" + " origin: info -qo,\n" + " provided-depends: info -qb,\n" + " raw: info -R,\n" + " required-depends: info -qr,\n" + " shared-depends: info -qB,\n" + " show: info -f -k,\n" + " size: info -sq,\n" + " }\n" + "\n" + "repo_dirs : [\n" + " /home/bapt,\n" + " /usr/local/etc\n" + "]\n" + "", + /* Macros */ "section1 {key = value; section {\n" "param = \"value\";\n" "param2 = value\n" -- 2.39.5