Skip to content

Commit

Permalink
Solve #73 for rule names - renaming rule also renames all references …
Browse files Browse the repository at this point in the history
…to it
  • Loading branch information
TadeasKucera committed Apr 15, 2020
1 parent f3db299 commit 56020c2
Show file tree
Hide file tree
Showing 10 changed files with 110 additions and 30 deletions.
2 changes: 1 addition & 1 deletion include/yaramod/types/expressions.h
Original file line number Diff line number Diff line change
Expand Up @@ -1220,7 +1220,7 @@ class IdExpression : public Expression
{
_symbol = symbol;
if (_symbolToken)
_symbolToken.value()->setValue(_symbol, _symbol->getName());
_symbolToken.value()->setValue(_symbol);
}

protected:
Expand Down
4 changes: 1 addition & 3 deletions include/yaramod/types/literal.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,7 @@ class Literal
void setValue(std::int64_t i, const std::optional<std::string>& integral_formatted_value = std::nullopt);
void setValue(std::uint64_t i, const std::optional<std::string>& integral_formatted_value = std::nullopt);
void setValue(double f, const std::optional<std::string>& integral_formatted_value = std::nullopt);
void setValue(const std::shared_ptr<Symbol>& s, const std::string& symbol_name);
//TODO delete this
void setValue(std::shared_ptr<Symbol>&& s, std::string&& symbol_name);
void setValue(const std::shared_ptr<Symbol>& s);
void setValue(std::shared_ptr<Symbol>&& s);
/// @}

Expand Down
1 change: 0 additions & 1 deletion include/yaramod/types/rule.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ class Rule
std::shared_ptr<StringsTrie> _strings; ///< Strings
Expression::Ptr _condition; ///< Condition expression
std::vector<TokenIt> _tags; ///< Tags
std::shared_ptr<Symbol> _symbol; ///< Symbol representing rule
Location _location; ///< Which file was this rule included from
};

Expand Down
6 changes: 6 additions & 0 deletions include/yaramod/types/symbol.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ class Symbol
}
/// @}

/// @name Setter methods
/// @{
template<typename T>
void setName(T&& name) { _name = std::forward<T>(name); }
/// @}

/// @name Detection methods
/// @{
bool isValue() const { return _type == Symbol::Type::Value; }
Expand Down
5 changes: 2 additions & 3 deletions include/yaramod/types/token.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,8 @@ class Token
void setValue(std::int64_t value, const std::optional<std::string>& integral_formated_value = std::nullopt) { _value->setValue(value, integral_formated_value); }
void setValue(std::uint64_t value, const std::optional<std::string>& integral_formated_value = std::nullopt) { _value->setValue(value, integral_formated_value); }
void setValue(double value, const std::optional<std::string>& integral_formated_value = std::nullopt) { _value->setValue(value, integral_formated_value); }
void setValue(const std::shared_ptr<Symbol>& value, const std::string& symbol_name) { _value->setValue(value, symbol_name); }
void setValue(std::shared_ptr<Symbol>&& value, std::string&& symbol_name) { _value->setValue(std::move(value), std::move(symbol_name)); }
void setValue(std::shared_ptr<Symbol>&& value);
void setValue(const std::shared_ptr<Symbol>& value) { _value->setValue(value); }
void setValue(std::shared_ptr<Symbol>&& value) { _value->setValue(std::move(value)); }

void setType(TokenType type) { _type = type; }
void setFlag(bool flag) { _flag = flag; }
Expand Down
21 changes: 16 additions & 5 deletions src/parser/parser_driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -435,9 +435,11 @@ void ParserDriver::defineGrammar()
_lastRuleTokenStream = currentFileContext()->getTokenStream();
return {};
}, "ID", [&](auto&& args) -> Value {
args[3].getTokenIt()->setType(RULE_NAME);
if (ruleExists(args[3].getTokenIt()->getString()))
const std::string& name_text = args[3].getTokenIt()->getString();
if (ruleExists(name_text))
error_handle(args[3].getTokenIt()->getLocation(), "Redefinition of rule '" + args[3].getTokenIt()->getString() + "'");
args[3].getTokenIt()->setType(RULE_NAME);
args[3].getTokenIt()->setValue(std::make_shared<ValueSymbol>(name_text, Expression::Type::Bool));
return {};
},
"tags", "LCB", "metas", "strings", "condition", "RCB", [&](auto&& args) -> Value {
Expand Down Expand Up @@ -1371,8 +1373,17 @@ void ParserDriver::defineGrammar()
TokenIt symbol_token = args[0].getTokenIt();
auto symbol = findSymbol(symbol_token->getString());
if (!symbol)
error_handle(args[0].getTokenIt()->getLocation(), "Unrecognized identifier '" + args[0].getTokenIt()->getString() + "' referenced");
symbol_token->setValue(symbol, symbol->getName());
{
if (_mode != ParserMode::Incomplete)
error_handle(args[0].getTokenIt()->getLocation(), "Unrecognized identifier '" + args[0].getTokenIt()->getPureText() + "' referenced");
else
{
error_handle(args[0].getTokenIt()->getLocation(), "TODO remove this exception '" + args[0].getTokenIt()->getPureText() + "' referenced");
//TODO: add new symbol with flag undefined
}
}
symbol_token->setValue(symbol);
std::cout << "identifier '" << args[0].getTokenIt()->getText() << "' = symbol '" << symbol->getName() << std::endl;
auto output = std::make_shared<IdExpression>(symbol_token);
output->setType(symbol->getDataType());
return output;
Expand All @@ -1393,7 +1404,7 @@ void ParserDriver::defineGrammar()
error_handle(args[2].getTokenIt()->getLocation(), "Unrecognized identifier '" + symbol_token->getString() + "' referenced");

auto symbol = attr.value();
symbol_token->setValue(symbol, symbol->getName());
symbol_token->setValue(symbol);
symbol_token->setType(symbol->getTokenType());
auto output = std::make_shared<StructAccessExpression>(std::move(expr), args[1].getTokenIt(), symbol_token);
output->setType(symbol->getDataType());
Expand Down
10 changes: 1 addition & 9 deletions src/types/literal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,17 +158,9 @@ void Literal::setValue(double f, const std::optional<std::string>& integral_form
_formatted_value = integral_formatted_value;
}

void Literal::setValue(const std::shared_ptr<Symbol>& s, const std::string& symbol_name)
void Literal::setValue(const std::shared_ptr<Symbol>& s)
{
_value = s;
_formatted_value = symbol_name;
}

//TODO delete
void Literal::setValue(std::shared_ptr<Symbol>&& s, std::string&& symbol_name)
{
_value = std::move(s);
_formatted_value = std::move(symbol_name);
}

void Literal::setValue(std::shared_ptr<Symbol>&& s)
Expand Down
11 changes: 8 additions & 3 deletions src/types/rule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ Rule::Rule(const std::shared_ptr<TokenStream>& tokenStream, TokenIt name, std::o
, _strings(std::move(strings))
, _condition(std::move(condition))
, _tags(tags)
, _symbol(std::make_shared<ValueSymbol>(name->getPureText(), Expression::Type::Bool))
, _location({"[stream]", 0})
{
}
Expand Down Expand Up @@ -206,7 +205,7 @@ std::vector<std::string> Rule::getTags() const
*/
const std::shared_ptr<Symbol>& Rule::getSymbol() const
{
return _symbol;
return _name->getSymbol();
}

/**
Expand Down Expand Up @@ -247,7 +246,13 @@ const Rule::Location& Rule::getLocation() const
*/
void Rule::setName(const std::string& name)
{
_name->setValue(name);
if (_name->isString())
_name->setValue(name);
else
{
assert(_name->isSymbol());
_name->getSymbol()->setName(name);
}
}

/**
Expand Down
5 changes: 0 additions & 5 deletions src/types/token.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,6 @@ const std::shared_ptr<Symbol>& Token::getSymbol() const
return _value->getSymbol();
}

void Token::setValue(std::shared_ptr<Symbol>&& value)
{
_value->setValue(std::move(value));
}

const std::shared_ptr<TokenStream>& Token::getSubTokenStream() const
{
return _subTokenStream;
Expand Down
75 changes: 75 additions & 0 deletions tests/cpp/parser_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5858,6 +5858,81 @@ rule oneline_rule_2
EXPECT_EQ(expected, driver.getParsedFile().getTextFormatted());
}

TEST_F(ParserTests,
IncompleteRulesModeReferenceUnknownSymbol) {
prepareInput(
R"(
rule abc
{
condition:
unknown_rule
}
)"
);
EXPECT_TRUE(driver.parse(input, ParserMode::Incomplete));
ASSERT_EQ(1u, driver.getParsedFile().getRules().size());
ASSERT_EQ(input_text, driver.getParsedFile().getTextFormatted());
}

TEST_F(ParserTests,
IncompleteRulesModeIncompleteRule) {
prepareInput(
R"(
rule abc
{
condition:
)"
);
EXPECT_TRUE(driver.parse(input, ParserMode::Incomplete));
ASSERT_EQ(0u, driver.getParsedFile().getRules().size());
ASSERT_EQ(input_text, driver.getParsedFile().getTextFormatted());

}

TEST_F(ParserTests,
RenameReferencedRuleWorks) {
prepareInput(
R"(
rule abc
{
condition:
true
}
rule def
{
condition:
abc
}
)"
);
EXPECT_TRUE(driver.parse(input, ParserMode::Incomplete));
ASSERT_EQ(2u, driver.getParsedFile().getRules().size());
ASSERT_EQ(input_text, driver.getParsedFile().getTextFormatted());

const auto& rule1 = driver.getParsedFile().getRules()[0];
rule1->setName("XYZ");
EXPECT_EQ(rule1->getName(), "XYZ");
const auto& rule2 = driver.getParsedFile().getRules()[1];
EXPECT_EQ(rule2->getCondition()->getText(), "XYZ");

std::string expected = R"(
rule XYZ
{
condition:
true
}
rule def
{
condition:
XYZ
}
)";

EXPECT_EQ(expected, driver.getParsedFile().getTextFormatted());
}

TEST_F(ParserTests,
CuckooScheduledTaskModuleFunction) {
prepareInput(
Expand Down

0 comments on commit 56020c2

Please sign in to comment.