diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2021-02-15 20:05:18 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2021-02-15 20:05:18 +0000 |
commit | 138b26b184a2e73350b0ba2d7cdbf0def3c30734 (patch) | |
tree | 1cf4bf95107759551273c8aca5fb1b813a533ea4 /src | |
parent | aa209cfbcfc1acb4a12ba1ff77d8342119371938 (diff) | |
download | rspamd-138b26b184a2e73350b0ba2d7cdbf0def3c30734.tar.gz rspamd-138b26b184a2e73350b0ba2d7cdbf0def3c30734.zip |
[Project] Css: Allow at rules parsing
Diffstat (limited to 'src')
-rw-r--r-- | src/libserver/css/css_parser.cxx | 91 |
1 files changed, 88 insertions, 3 deletions
diff --git a/src/libserver/css/css_parser.cxx b/src/libserver/css/css_parser.cxx index 0e6ec4e84..084d1b50a 100644 --- a/src/libserver/css/css_parser.cxx +++ b/src/libserver/css/css_parser.cxx @@ -210,6 +210,7 @@ private: css_parser_token::token_type expected_end, bool consume_current) -> bool; auto qualified_rule_consumer(std::unique_ptr<css_consumed_block> &top) -> bool; + auto at_rule_consumer(std::unique_ptr<css_consumed_block> &top) -> bool; }; /* @@ -352,11 +353,70 @@ auto css_parser::qualified_rule_consumer(std::unique_ptr<css_consumed_block> &to return false; } - auto ret = true; + auto ret = true, want_more = true; auto block = std::make_unique<css_consumed_block>( css_consumed_block::parser_tag_type::css_qualified_rule); - while (ret && !eof) { + while (ret && want_more && !eof) { + auto next_token = tokeniser->next_token(); + switch (next_token.type) { + case css_parser_token::token_type::eof_token: + eof = true; + break; + case css_parser_token::token_type::cdo_token: + case css_parser_token::token_type::cdc_token: + if (top->tag == css_consumed_block::parser_tag_type::css_top_block) { + /* Ignore */ + ret = true; + } + else { + + } + break; + case css_parser_token::token_type::ocurlbrace_token: + ret = simple_block_consumer(block, + css_parser_token::token_type::ecurlbrace_token, false); + want_more = false; + break; + case css_parser_token::token_type::whitespace_token: + /* Ignore whitespaces */ + break; + default: + tokeniser->pushback_token(std::move(next_token)); + ret = component_value_consumer(block); + break; + }; + } + + if (ret) { + if (top->tag == css_consumed_block::parser_tag_type::css_top_block) { + msg_debug_css("attached node qualified rule %s; length=%d", + block->token_type_str(), (int)block->size()); + top->attach_block(std::move(block)); + } + } + + --rec_level; + + return ret; +} + +auto css_parser::at_rule_consumer(std::unique_ptr<css_consumed_block> &top) -> bool +{ + msg_debug_css("consume at-rule block; top block: %s, recursion level %d", + top->token_type_str(), rec_level); + + if (++rec_level > max_rec) { + msg_err_css("max nesting reached, ignore style"); + error = css_parse_error(css_parse_error_type::PARSE_ERROR_BAD_NESTING); + return false; + } + + auto ret = true, want_more = true; + auto block = std::make_unique<css_consumed_block>( + css_consumed_block::parser_tag_type::css_at_rule); + + while (ret && want_more && !eof) { auto next_token = tokeniser->next_token(); switch (next_token.type) { case css_parser_token::token_type::eof_token: @@ -375,6 +435,13 @@ auto css_parser::qualified_rule_consumer(std::unique_ptr<css_consumed_block> &to case css_parser_token::token_type::ocurlbrace_token: ret = simple_block_consumer(block, css_parser_token::token_type::ecurlbrace_token, false); + want_more = false; + break; + case css_parser_token::token_type::whitespace_token: + /* Ignore whitespaces */ + break; + case css_parser_token::token_type::semicolon_token: + want_more = false; break; default: tokeniser->pushback_token(std::move(next_token)); @@ -482,7 +549,25 @@ bool css_parser::consume_input(const std::string_view &sv) std::make_unique<css_consumed_block>(css_consumed_block::parser_tag_type::css_top_block); while (!eof && ret) { - ret = qualified_rule_consumer(consumed_blocks); + auto next_token = tokeniser->next_token(); + + switch (next_token.type) { + case css_parser_token::token_type::whitespace_token: + /* Ignore whitespaces */ + break; + case css_parser_token::token_type::eof_token: + eof = true; + break; + case css_parser_token::token_type::at_keyword_token: + tokeniser->pushback_token(std::move(next_token)); + ret = at_rule_consumer(consumed_blocks); + break; + default: + tokeniser->pushback_token(std::move(next_token)); + ret = qualified_rule_consumer(consumed_blocks); + break; + } + } auto debug_str = consumed_blocks->debug_str(); |