mirror of
https://github.com/tnodir/fort
synced 2024-11-14 21:55:37 +00:00
Tests: tst_ruletextparser.h: Add "lineIpPort" test
This commit is contained in:
parent
5b852bb78d
commit
7731f47cc4
@ -6,6 +6,23 @@
|
||||
|
||||
#include <util/conf/ruletextparser.h>
|
||||
|
||||
namespace {
|
||||
|
||||
bool compareStringList(const StringViewList &l1, const QStringList &l2)
|
||||
{
|
||||
if (l1.size() != l2.size())
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < l1.size(); ++i) {
|
||||
if (l1[i] != l2[i])
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class RuleTextParserTest : public Test
|
||||
{
|
||||
// Test interface
|
||||
@ -26,3 +43,24 @@ TEST_F(RuleTextParserTest, emptyList)
|
||||
|
||||
ASSERT_EQ(p.ruleFilters().size(), 0);
|
||||
}
|
||||
|
||||
TEST_F(RuleTextParserTest, lineIpPort)
|
||||
{
|
||||
RuleTextParser p("1.1.1.1:53");
|
||||
|
||||
ASSERT_TRUE(p.parse());
|
||||
|
||||
ASSERT_EQ(p.ruleFilters().size(), 4);
|
||||
|
||||
// Check IP
|
||||
{
|
||||
const RuleFilter &rf = p.ruleFilters()[2];
|
||||
ASSERT_TRUE(compareStringList(rf.values, { "1.1.1.1" }));
|
||||
}
|
||||
|
||||
// Check Port
|
||||
{
|
||||
const RuleFilter &rf = p.ruleFilters()[3];
|
||||
ASSERT_TRUE(compareStringList(rf.values, { "53" }));
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,8 @@
|
||||
namespace {
|
||||
|
||||
const char *const extraNameChars = "_";
|
||||
const char *const extraValueChars = ".:-/";
|
||||
const char *const extraValueChars = ".-/";
|
||||
const char *const extraValueEndChars = ".-/:";
|
||||
|
||||
int getCharIndex(const char *chars, const char c)
|
||||
{
|
||||
@ -89,7 +90,7 @@ void RuleTextParser::parseLines()
|
||||
const int nodeIndex = beginList(FORT_RULE_FILTER_TYPE_LIST_OR);
|
||||
|
||||
for (;;) {
|
||||
if (!skipComments(CharAnyBegin))
|
||||
if (!skipComments(CharLineBegin))
|
||||
break;
|
||||
|
||||
if (!parseLine())
|
||||
@ -103,20 +104,31 @@ bool RuleTextParser::parseLine()
|
||||
{
|
||||
const int nodeIndex = beginList(FORT_RULE_FILTER_TYPE_LIST_AND);
|
||||
|
||||
m_ruleFilter.type = FORT_RULE_FILTER_TYPE_ADDRESS; // default type
|
||||
RuleCharTypes expectedSeparator = CharNone;
|
||||
|
||||
m_ruleFilter.type = FORT_RULE_FILTER_TYPE_ADDRESS; // Default type
|
||||
|
||||
for (;;) {
|
||||
if (!parseLineSection())
|
||||
if (!parseLineSection(expectedSeparator))
|
||||
break;
|
||||
|
||||
if (m_ruleFilter.isLineEnd || m_ruleFilter.isListEnd)
|
||||
break;
|
||||
|
||||
const bool isSectionEnd = m_ruleFilter.isSectionEnd;
|
||||
|
||||
if (!checkAddFilter())
|
||||
return false;
|
||||
|
||||
if (!m_ruleFilter.hasFilterName) {
|
||||
// next default type, if applicable
|
||||
resetFilter();
|
||||
|
||||
// Next default type, if applicable
|
||||
if (!isSectionEnd && !m_ruleFilter.hasFilterName) {
|
||||
m_ruleFilter.type = m_ruleFilter.isTypeAddress() ? FORT_RULE_FILTER_TYPE_PORT
|
||||
: FORT_RULE_FILTER_TYPE_INVALID;
|
||||
}
|
||||
|
||||
expectedSeparator = CharColon | CharNewLine;
|
||||
}
|
||||
|
||||
endList(nodeIndex);
|
||||
@ -124,10 +136,10 @@ bool RuleTextParser::parseLine()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RuleTextParser::parseLineSection()
|
||||
bool RuleTextParser::parseLineSection(RuleCharTypes expectedSeparator)
|
||||
{
|
||||
for (;;) {
|
||||
if (!nextCharType(CharAnyBegin, CharSpace))
|
||||
if (!nextCharType(CharLineBegin | expectedSeparator, CharSpace))
|
||||
return false;
|
||||
|
||||
if (!processSection())
|
||||
@ -157,7 +169,9 @@ bool RuleTextParser::processSectionBlock()
|
||||
} break;
|
||||
case CharDigit:
|
||||
case CharValueBegin: {
|
||||
parseValue();
|
||||
const bool expectValueEnd = (m_charType == CharValueBegin);
|
||||
|
||||
parseValue(expectValueEnd);
|
||||
} break;
|
||||
}
|
||||
|
||||
@ -174,10 +188,12 @@ bool RuleTextParser::processSectionChar()
|
||||
m_ruleFilter.isNot = !m_ruleFilter.isNot;
|
||||
return true;
|
||||
} break;
|
||||
case CharColon:
|
||||
case CharNewLine: {
|
||||
case CharColon: {
|
||||
m_ruleFilter.isSectionEnd = true;
|
||||
} break;
|
||||
case CharNewLine: {
|
||||
m_ruleFilter.isLineEnd = true;
|
||||
} break;
|
||||
case CharListEnd: {
|
||||
m_ruleFilter.isListEnd = true;
|
||||
checkListEnd();
|
||||
@ -278,27 +294,36 @@ bool RuleTextParser::parseBracketValue(RuleCharTypes expectedSeparator)
|
||||
resetParsedCharTypes();
|
||||
|
||||
if (!parseChars(CharValueBegin | CharValue,
|
||||
CharSpaceComment | CharBracketEnd | expectedSeparator, extraValueChars))
|
||||
CharSpaceComment | CharBracketEnd | expectedSeparator, extraValueEndChars))
|
||||
return false;
|
||||
|
||||
if ((m_parsedCharTypes & CharBracketEnd) != 0)
|
||||
if (hasParsedCharTypes(CharBracketEnd))
|
||||
return false;
|
||||
|
||||
if ((m_parsedCharTypes & expectedSeparator) == 0) {
|
||||
if (!hasParsedCharTypes(expectedSeparator)) {
|
||||
setErrorMessage(tr("Unexpected end of values list"));
|
||||
return false;
|
||||
}
|
||||
|
||||
return parseValue();
|
||||
const bool expectValueEnd = hasParsedCharTypes(CharValueBegin);
|
||||
|
||||
return parseValue(expectValueEnd);
|
||||
}
|
||||
|
||||
bool RuleTextParser::parseValue()
|
||||
bool RuleTextParser::parseValue(bool expectValueEnd)
|
||||
{
|
||||
const QChar *value = parsedCharPtr();
|
||||
|
||||
if (!parseChars(CharLetter | CharValue | CharValueEnd, extraValueChars))
|
||||
const char *extraChars = expectValueEnd ? extraValueEndChars : extraValueChars;
|
||||
|
||||
if (!parseChars(CharLetter | CharValue, extraChars))
|
||||
return false;
|
||||
|
||||
if (expectValueEnd && m_charType != CharValueEnd) {
|
||||
setErrorMessage(tr("Unexpected end of value"));
|
||||
return false;
|
||||
}
|
||||
|
||||
const QStringView valueView(value, currentCharPtr() - value);
|
||||
|
||||
m_ruleFilter.addValue(valueView);
|
||||
@ -309,7 +334,7 @@ bool RuleTextParser::parseValue()
|
||||
bool RuleTextParser::checkAddFilter()
|
||||
{
|
||||
if (!m_ruleFilter.hasValues()) {
|
||||
if (m_ruleFilter.isSectionEnd) {
|
||||
if (!m_ruleFilter.isSectionEnd) {
|
||||
setErrorMessage(tr("Unexpected end of line section"));
|
||||
return false;
|
||||
}
|
||||
@ -332,6 +357,7 @@ void RuleTextParser::resetFilter()
|
||||
m_ruleFilter.isNot = false;
|
||||
m_ruleFilter.hasFilterName = false;
|
||||
m_ruleFilter.isListEnd = false;
|
||||
m_ruleFilter.isLineEnd = false;
|
||||
m_ruleFilter.isSectionEnd = false;
|
||||
|
||||
// m_ruleFilter.type is not reset
|
||||
@ -342,8 +368,6 @@ void RuleTextParser::resetFilter()
|
||||
void RuleTextParser::addFilter()
|
||||
{
|
||||
m_ruleFilters.append(m_ruleFilter);
|
||||
|
||||
resetFilter();
|
||||
}
|
||||
|
||||
int RuleTextParser::beginList(qint8 listType)
|
||||
@ -354,6 +378,8 @@ int RuleTextParser::beginList(qint8 listType)
|
||||
|
||||
addFilter();
|
||||
|
||||
resetFilter();
|
||||
|
||||
return nodeIndex;
|
||||
}
|
||||
|
||||
@ -392,11 +418,18 @@ bool RuleTextParser::parseChars(
|
||||
return false;
|
||||
}
|
||||
|
||||
ungetChar();
|
||||
ungetParsedChar();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RuleTextParser::ungetParsedChar()
|
||||
{
|
||||
if (!isEmpty()) {
|
||||
ungetChar();
|
||||
}
|
||||
}
|
||||
|
||||
bool RuleTextParser::nextCharType(
|
||||
RuleCharTypes expectedCharTypes, RuleCharTypes skipCharTypes, const char *extraChars)
|
||||
{
|
||||
@ -406,7 +439,7 @@ bool RuleTextParser::nextCharType(
|
||||
|
||||
m_charType = CharNone;
|
||||
|
||||
while (m_p < m_end) {
|
||||
while (!isEmpty()) {
|
||||
const QChar c = *m_p++;
|
||||
|
||||
m_charType = getCharType(m_charType, c, extraChars);
|
||||
|
@ -26,10 +26,10 @@ enum RuleCharType : RuleCharTypes {
|
||||
CharNot = (1 << 13), // !
|
||||
CharExtra = (1 << 14), // Name | Value
|
||||
// Complex types
|
||||
CharAnyBegin = (CharListBegin | CharListEnd | CharBracketBegin | CharLetter | CharDigit
|
||||
CharLineBegin = (CharListBegin | CharListEnd | CharBracketBegin | CharLetter | CharDigit
|
||||
| CharValueBegin | CharNot),
|
||||
CharName = (CharLetter | CharExtra), // a-zA-Z_
|
||||
CharValue = (CharDigit | CharExtra), // 0-9.:-/
|
||||
CharValue = (CharDigit | CharExtra), // 0-9.-/:
|
||||
CharSpaceComment = (CharSpace | CharComment),
|
||||
};
|
||||
|
||||
@ -43,6 +43,7 @@ struct RuleFilter
|
||||
bool isNot : 1 = false;
|
||||
bool hasFilterName : 1 = false;
|
||||
bool isListEnd : 1 = false;
|
||||
bool isLineEnd : 1 = false;
|
||||
bool isSectionEnd : 1 = false;
|
||||
|
||||
qint8 type = 0;
|
||||
@ -74,7 +75,7 @@ private:
|
||||
|
||||
void parseLines();
|
||||
bool parseLine();
|
||||
bool parseLineSection();
|
||||
bool parseLineSection(RuleCharTypes expectedSeparator);
|
||||
bool processSection();
|
||||
bool processSectionBlock();
|
||||
bool processSectionChar();
|
||||
@ -86,7 +87,7 @@ private:
|
||||
|
||||
void parseBracketValues();
|
||||
bool parseBracketValue(RuleCharTypes expectedSeparator);
|
||||
bool parseValue();
|
||||
bool parseValue(bool expectValueEnd);
|
||||
|
||||
bool checkAddFilter();
|
||||
|
||||
@ -97,12 +98,15 @@ private:
|
||||
void endList(int nodeIndex);
|
||||
|
||||
void resetParsedCharTypes() { m_parsedCharTypes = CharNone; }
|
||||
bool hasParsedCharTypes(RuleCharTypes v) { return v != 0 && (m_parsedCharTypes & v) != 0; }
|
||||
|
||||
void ungetChar() { --m_p; }
|
||||
|
||||
const QChar *currentCharPtr() const { return m_p; }
|
||||
const QChar *parsedCharPtr() const { return m_p - 1; }
|
||||
|
||||
bool isEmpty() const { return m_p >= m_end; }
|
||||
|
||||
RuleFilter &listNode(int listIndex) { return m_ruleFilters[listIndex]; }
|
||||
|
||||
bool skipComments(RuleCharTypes expectedCharTypes);
|
||||
@ -115,6 +119,8 @@ private:
|
||||
bool parseChars(RuleCharTypes expectedCharTypes, RuleCharTypes skipCharTypes,
|
||||
const char *extraChars = nullptr);
|
||||
|
||||
void ungetParsedChar();
|
||||
|
||||
bool nextCharType(RuleCharTypes expectedCharTypes, RuleCharTypes skipCharTypes,
|
||||
const char *extraChars = nullptr);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user