diff --git a/src/driver/common/fortconf.h b/src/driver/common/fortconf.h index 1939172c..d3c7e7ba 100644 --- a/src/driver/common/fortconf.h +++ b/src/driver/common/fortconf.h @@ -3,23 +3,23 @@ #include "common.h" -#define FORT_CONF_IP_MAX (2 * 1024 * 1024) -#define FORT_CONF_IP4_ARR_SIZE(n) ((n) * sizeof(UINT32)) -#define FORT_CONF_IP6_ARR_SIZE(n) ((n) * sizeof(ip6_addr_t)) -#define FORT_CONF_IP4_RANGE_SIZE(n) (FORT_CONF_IP4_ARR_SIZE(n) * 2) -#define FORT_CONF_IP6_RANGE_SIZE(n) (FORT_CONF_IP6_ARR_SIZE(n) * 2) -#define FORT_CONF_RULE_MAX 1024 -#define FORT_CONF_RULE_SET_MAX 32 -#define FORT_CONF_RULE_DEPTH_MAX 4 -#define FORT_CONF_RULE_SET_DEPTH_MAX 8 -#define FORT_CONF_ZONE_MAX 32 -#define FORT_CONF_GROUP_MAX 16 -#define FORT_CONF_APPS_LEN_MAX (64 * 1024 * 1024) -#define FORT_CONF_APP_PATH_MAX 1024 -#define FORT_CONF_APP_PATH_MAX_SIZE (FORT_CONF_APP_PATH_MAX * sizeof(WCHAR)) -#define FORT_CONF_STR_ALIGN 4 -#define FORT_CONF_STR_HEADER_SIZE(n) (((n) + 1) * sizeof(UINT32)) -#define FORT_CONF_STR_DATA_SIZE(size) FORT_ALIGN_SIZE((size), FORT_CONF_STR_ALIGN) +#define FORT_CONF_IP_MAX (2 * 1024 * 1024) +#define FORT_CONF_IP4_ARR_SIZE(n) ((n) * sizeof(UINT32)) +#define FORT_CONF_IP6_ARR_SIZE(n) ((n) * sizeof(ip6_addr_t)) +#define FORT_CONF_IP4_RANGE_SIZE(n) (FORT_CONF_IP4_ARR_SIZE(n) * 2) +#define FORT_CONF_IP6_RANGE_SIZE(n) (FORT_CONF_IP6_ARR_SIZE(n) * 2) +#define FORT_CONF_RULE_MAX 1024 +#define FORT_CONF_RULE_SET_MAX 32 +#define FORT_CONF_RULE_FILTER_DEPTH_MAX 4 +#define FORT_CONF_RULE_SET_DEPTH_MAX 8 +#define FORT_CONF_ZONE_MAX 32 +#define FORT_CONF_GROUP_MAX 16 +#define FORT_CONF_APPS_LEN_MAX (64 * 1024 * 1024) +#define FORT_CONF_APP_PATH_MAX 1024 +#define FORT_CONF_APP_PATH_MAX_SIZE (FORT_CONF_APP_PATH_MAX * sizeof(WCHAR)) +#define FORT_CONF_STR_ALIGN 4 +#define FORT_CONF_STR_HEADER_SIZE(n) (((n) + 1) * sizeof(UINT32)) +#define FORT_CONF_STR_DATA_SIZE(size) FORT_ALIGN_SIZE((size), FORT_CONF_STR_ALIGN) typedef struct fort_conf_flags { diff --git a/src/ui/util/conf/confutil.cpp b/src/ui/util/conf/confutil.cpp index b9686e3f..8e5a6a13 100644 --- a/src/ui/util/conf/confutil.cpp +++ b/src/ui/util/conf/confutil.cpp @@ -16,7 +16,7 @@ int ConfUtil::ruleSetMaxCount() int ConfUtil::ruleDepthMaxCount() { - return FORT_CONF_RULE_DEPTH_MAX; + return FORT_CONF_RULE_FILTER_DEPTH_MAX; } int ConfUtil::ruleSetDepthMaxCount() diff --git a/src/ui/util/conf/ruletextparser.cpp b/src/ui/util/conf/ruletextparser.cpp index 8248bfe5..165d511b 100644 --- a/src/ui/util/conf/ruletextparser.cpp +++ b/src/ui/util/conf/ruletextparser.cpp @@ -7,7 +7,7 @@ namespace { const char *const extraNameChars = "_"; -const char *const extraValueChars = ".:-/]"; +const char *const extraValueChars = ".:-/"; int getCharIndex(const char *chars, const char c) { @@ -35,10 +35,10 @@ RuleCharType processChar(const QChar c, const char *extraChars = nullptr) return CharExtra; } - static const char chars[] = "{}()[,:#!\n"; + static const char chars[] = "{}()[],:#!\n"; static const RuleCharType charTypes[] = { CharListBegin, CharListEnd, CharBracketBegin, - CharBracketEnd, CharValueBegin, CharValueSeparator, CharColon, CharComment, CharNot, - CharNewLine }; + CharBracketEnd, CharValueBegin, CharValueEnd, CharValueSeparator, CharColon, CharComment, + CharNot, CharNewLine }; const int index = getCharIndex(chars, c1); @@ -140,19 +140,42 @@ bool RuleTextParser::parseLineSection() if (!nextCharType(CharAnyBegin | CharSpace)) return false; - if (!processSectionChar()) + if (!processSection()) break; } return !hasError(); } -bool RuleTextParser::processSectionChar() +bool RuleTextParser::processSection() { if ((m_charType & (CharListBegin | CharBracketBegin | CharDigit | CharValueBegin)) != 0) { return processSectionBlock(); } + return processSectionChar(); +} + +bool RuleTextParser::processSectionBlock() +{ + switch (m_charType) { + case CharListBegin: { + processSectionList(); + } break; + case CharBracketBegin: { + parseBracketValues(); + } break; + case CharDigit: + case CharValueBegin: { + parseValue(); + } break; + } + + return false; +} + +bool RuleTextParser::processSectionChar() +{ switch (m_charType) { case CharLetter: { return parseName(); @@ -167,32 +190,18 @@ bool RuleTextParser::processSectionChar() } break; case CharListEnd: { m_ruleFilter.isListEnd = true; + checkListEnd(); } break; } return false; } -bool RuleTextParser::processSectionBlock() +void RuleTextParser::processSectionList() { - switch (m_charType) { - case CharListBegin: { - processSectionLines(); - } break; - case CharBracketBegin: { - parseBracketValues(); - } break; - case CharDigit: - case CharValueBegin: { - parseValue(); - } break; - } + if (!checkListBegin()) + return; - return false; -} - -void RuleTextParser::processSectionLines() -{ parseLines(); if (!m_ruleFilter.isListEnd) { @@ -200,20 +209,34 @@ void RuleTextParser::processSectionLines() } } +bool RuleTextParser::checkListBegin() +{ + if (++m_listDepth > FORT_CONF_RULE_FILTER_DEPTH_MAX) { + setErrorMessage(tr("Max list depth exceeded: %1").arg(m_listDepth)); + return false; + } + + return true; +} + +bool RuleTextParser::checkListEnd() +{ + if (--m_listDepth < 0) { + setErrorMessage(tr("Unexpected symbol of list end")); + return false; + } + + return true; +} + bool RuleTextParser::parseName() { const QChar *name = parsedCharPtr(); - while (nextCharType(CharName, extraNameChars)) { - continue; - } - - if (hasError()) { + if (!parseChars(CharName, extraNameChars)) { return false; } - ungetChar(); - static const QHash filterTypesMap = { { "ip", FORT_RULE_FILTER_TYPE_ADDRESS }, { "port", FORT_RULE_FILTER_TYPE_PORT }, @@ -250,12 +273,19 @@ bool RuleTextParser::parseName() void RuleTextParser::parseBracketValues() { - parseValue(); + parseValue(CharValueEnd); } -void RuleTextParser::parseValue() +void RuleTextParser::parseValue(quint32 extraCharTypes) { - // TODO: implement + const QChar *value = parsedCharPtr(); + + if (!parseChars(CharValue | extraCharTypes, extraValueChars)) + return; + + const QStringView valueView(value, currentCharPtr() - value); + + m_ruleFilter.addValue(valueView); } bool RuleTextParser::checkAddFilter() @@ -323,6 +353,21 @@ void RuleTextParser::endList(int nodeIndex) ruleFilter.listCount = currentIndex - nodeIndex; } +bool RuleTextParser::parseChars(quint32 expectedCharTypes, const char *extraChars) +{ + while (nextCharType(expectedCharTypes, extraChars)) { + continue; + } + + if (hasError()) { + return false; + } + + ungetChar(); + + return true; +} + bool RuleTextParser::nextCharType(quint32 expectedCharTypes, const char *extraChars) { Q_ASSERT(!extraChars || (expectedCharTypes & CharExtra) != 0); diff --git a/src/ui/util/conf/ruletextparser.h b/src/ui/util/conf/ruletextparser.h index 96fd980a..e527d29b 100644 --- a/src/ui/util/conf/ruletextparser.h +++ b/src/ui/util/conf/ruletextparser.h @@ -17,18 +17,19 @@ enum RuleCharType : RuleCharTypes { CharLetter = (1 << 4), // a-zA-Z CharDigit = (1 << 5), // 0-9 CharValueBegin = (1 << 6), // [ - CharValueSeparator = (1 << 7), // , - CharColon = (1 << 8), // : - CharSpace = (1 << 9), - CharNewLine = (1 << 10), // \n - CharComment = (1 << 11), // # - CharNot = (1 << 12), // ! - CharExtra = (1 << 13), // Name | Value + CharValueEnd = (1 << 7), // ] + CharValueSeparator = (1 << 8), // , + CharColon = (1 << 9), // : + CharSpace = (1 << 10), + CharNewLine = (1 << 11), // \n + CharComment = (1 << 12), // # + CharNot = (1 << 13), // ! + CharExtra = (1 << 14), // Name | Value // Complex types CharAnyBegin = (CharListBegin | CharBracketBegin | CharLetter | CharDigit | CharValueBegin | CharNot), CharName = (CharLetter | CharExtra), // a-zA-Z_ - CharValue = (CharDigit | CharValueBegin | CharExtra), // 0-9.:-/] + CharValue = (CharDigit | CharExtra), // 0-9.:-/ CharLineBreak = (CharSpace | CharNewLine | CharComment), }; @@ -37,6 +38,8 @@ struct RuleFilter bool isTypeAddress() const; bool hasValues() const { return !values.isEmpty(); } + void addValue(const QStringView v) { values.append(v); } + bool isNot : 1 = false; bool hasFilterName : 1 = false; bool isSectionEnd : 1 = false; @@ -73,14 +76,17 @@ private: bool skipComments(); bool parseLine(); bool parseLineSection(); - bool processSectionChar(); + bool processSection(); bool processSectionBlock(); - void processSectionLines(); + bool processSectionChar(); + void processSectionList(); + bool checkListBegin(); + bool checkListEnd(); bool parseName(); void parseBracketValues(); - void parseValue(); + void parseValue(quint32 extraCharTypes = 0); bool checkAddFilter(); @@ -97,10 +103,12 @@ private: RuleFilter &listNode(int listIndex) { return m_ruleFilterArray[listIndex]; } + bool parseChars(quint32 expectedCharTypes, const char *extraChars = nullptr); bool nextCharType(quint32 expectedCharTypes, const char *extraChars = nullptr); bool checkNextCharType(quint32 expectedCharTypes, const QChar c); private: + qint8 m_listDepth = 0; RuleCharType m_charType = CharNone; RuleFilter m_ruleFilter;