UI: RuleTextParser: Prepare parseValue()

This commit is contained in:
Nodir Temirkhodjaev 2024-11-05 20:35:27 +05:00
parent f4683f5b5b
commit 483aef4611
4 changed files with 116 additions and 63 deletions

View File

@ -3,23 +3,23 @@
#include "common.h" #include "common.h"
#define FORT_CONF_IP_MAX (2 * 1024 * 1024) #define FORT_CONF_IP_MAX (2 * 1024 * 1024)
#define FORT_CONF_IP4_ARR_SIZE(n) ((n) * sizeof(UINT32)) #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_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_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_IP6_RANGE_SIZE(n) (FORT_CONF_IP6_ARR_SIZE(n) * 2)
#define FORT_CONF_RULE_MAX 1024 #define FORT_CONF_RULE_MAX 1024
#define FORT_CONF_RULE_SET_MAX 32 #define FORT_CONF_RULE_SET_MAX 32
#define FORT_CONF_RULE_DEPTH_MAX 4 #define FORT_CONF_RULE_FILTER_DEPTH_MAX 4
#define FORT_CONF_RULE_SET_DEPTH_MAX 8 #define FORT_CONF_RULE_SET_DEPTH_MAX 8
#define FORT_CONF_ZONE_MAX 32 #define FORT_CONF_ZONE_MAX 32
#define FORT_CONF_GROUP_MAX 16 #define FORT_CONF_GROUP_MAX 16
#define FORT_CONF_APPS_LEN_MAX (64 * 1024 * 1024) #define FORT_CONF_APPS_LEN_MAX (64 * 1024 * 1024)
#define FORT_CONF_APP_PATH_MAX 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_APP_PATH_MAX_SIZE (FORT_CONF_APP_PATH_MAX * sizeof(WCHAR))
#define FORT_CONF_STR_ALIGN 4 #define FORT_CONF_STR_ALIGN 4
#define FORT_CONF_STR_HEADER_SIZE(n) (((n) + 1) * sizeof(UINT32)) #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_STR_DATA_SIZE(size) FORT_ALIGN_SIZE((size), FORT_CONF_STR_ALIGN)
typedef struct fort_conf_flags typedef struct fort_conf_flags
{ {

View File

@ -16,7 +16,7 @@ int ConfUtil::ruleSetMaxCount()
int ConfUtil::ruleDepthMaxCount() int ConfUtil::ruleDepthMaxCount()
{ {
return FORT_CONF_RULE_DEPTH_MAX; return FORT_CONF_RULE_FILTER_DEPTH_MAX;
} }
int ConfUtil::ruleSetDepthMaxCount() int ConfUtil::ruleSetDepthMaxCount()

View File

@ -7,7 +7,7 @@
namespace { namespace {
const char *const extraNameChars = "_"; const char *const extraNameChars = "_";
const char *const extraValueChars = ".:-/]"; const char *const extraValueChars = ".:-/";
int getCharIndex(const char *chars, const char c) int getCharIndex(const char *chars, const char c)
{ {
@ -35,10 +35,10 @@ RuleCharType processChar(const QChar c, const char *extraChars = nullptr)
return CharExtra; return CharExtra;
} }
static const char chars[] = "{}()[,:#!\n"; static const char chars[] = "{}()[],:#!\n";
static const RuleCharType charTypes[] = { CharListBegin, CharListEnd, CharBracketBegin, static const RuleCharType charTypes[] = { CharListBegin, CharListEnd, CharBracketBegin,
CharBracketEnd, CharValueBegin, CharValueSeparator, CharColon, CharComment, CharNot, CharBracketEnd, CharValueBegin, CharValueEnd, CharValueSeparator, CharColon, CharComment,
CharNewLine }; CharNot, CharNewLine };
const int index = getCharIndex(chars, c1); const int index = getCharIndex(chars, c1);
@ -140,19 +140,42 @@ bool RuleTextParser::parseLineSection()
if (!nextCharType(CharAnyBegin | CharSpace)) if (!nextCharType(CharAnyBegin | CharSpace))
return false; return false;
if (!processSectionChar()) if (!processSection())
break; break;
} }
return !hasError(); return !hasError();
} }
bool RuleTextParser::processSectionChar() bool RuleTextParser::processSection()
{ {
if ((m_charType & (CharListBegin | CharBracketBegin | CharDigit | CharValueBegin)) != 0) { if ((m_charType & (CharListBegin | CharBracketBegin | CharDigit | CharValueBegin)) != 0) {
return processSectionBlock(); 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) { switch (m_charType) {
case CharLetter: { case CharLetter: {
return parseName(); return parseName();
@ -167,32 +190,18 @@ bool RuleTextParser::processSectionChar()
} break; } break;
case CharListEnd: { case CharListEnd: {
m_ruleFilter.isListEnd = true; m_ruleFilter.isListEnd = true;
checkListEnd();
} break; } break;
} }
return false; return false;
} }
bool RuleTextParser::processSectionBlock() void RuleTextParser::processSectionList()
{ {
switch (m_charType) { if (!checkListBegin())
case CharListBegin: { return;
processSectionLines();
} break;
case CharBracketBegin: {
parseBracketValues();
} break;
case CharDigit:
case CharValueBegin: {
parseValue();
} break;
}
return false;
}
void RuleTextParser::processSectionLines()
{
parseLines(); parseLines();
if (!m_ruleFilter.isListEnd) { 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() bool RuleTextParser::parseName()
{ {
const QChar *name = parsedCharPtr(); const QChar *name = parsedCharPtr();
while (nextCharType(CharName, extraNameChars)) { if (!parseChars(CharName, extraNameChars)) {
continue;
}
if (hasError()) {
return false; return false;
} }
ungetChar();
static const QHash<QString, qint8> filterTypesMap = { static const QHash<QString, qint8> filterTypesMap = {
{ "ip", FORT_RULE_FILTER_TYPE_ADDRESS }, { "ip", FORT_RULE_FILTER_TYPE_ADDRESS },
{ "port", FORT_RULE_FILTER_TYPE_PORT }, { "port", FORT_RULE_FILTER_TYPE_PORT },
@ -250,12 +273,19 @@ bool RuleTextParser::parseName()
void RuleTextParser::parseBracketValues() 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() bool RuleTextParser::checkAddFilter()
@ -323,6 +353,21 @@ void RuleTextParser::endList(int nodeIndex)
ruleFilter.listCount = currentIndex - 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) bool RuleTextParser::nextCharType(quint32 expectedCharTypes, const char *extraChars)
{ {
Q_ASSERT(!extraChars || (expectedCharTypes & CharExtra) != 0); Q_ASSERT(!extraChars || (expectedCharTypes & CharExtra) != 0);

View File

@ -17,18 +17,19 @@ enum RuleCharType : RuleCharTypes {
CharLetter = (1 << 4), // a-zA-Z CharLetter = (1 << 4), // a-zA-Z
CharDigit = (1 << 5), // 0-9 CharDigit = (1 << 5), // 0-9
CharValueBegin = (1 << 6), // [ CharValueBegin = (1 << 6), // [
CharValueSeparator = (1 << 7), // , CharValueEnd = (1 << 7), // ]
CharColon = (1 << 8), // : CharValueSeparator = (1 << 8), // ,
CharSpace = (1 << 9), CharColon = (1 << 9), // :
CharNewLine = (1 << 10), // \n CharSpace = (1 << 10),
CharComment = (1 << 11), // # CharNewLine = (1 << 11), // \n
CharNot = (1 << 12), // ! CharComment = (1 << 12), // #
CharExtra = (1 << 13), // Name | Value CharNot = (1 << 13), // !
CharExtra = (1 << 14), // Name | Value
// Complex types // Complex types
CharAnyBegin = CharAnyBegin =
(CharListBegin | CharBracketBegin | CharLetter | CharDigit | CharValueBegin | CharNot), (CharListBegin | CharBracketBegin | CharLetter | CharDigit | CharValueBegin | CharNot),
CharName = (CharLetter | CharExtra), // a-zA-Z_ CharName = (CharLetter | CharExtra), // a-zA-Z_
CharValue = (CharDigit | CharValueBegin | CharExtra), // 0-9.:-/] CharValue = (CharDigit | CharExtra), // 0-9.:-/
CharLineBreak = (CharSpace | CharNewLine | CharComment), CharLineBreak = (CharSpace | CharNewLine | CharComment),
}; };
@ -37,6 +38,8 @@ struct RuleFilter
bool isTypeAddress() const; bool isTypeAddress() const;
bool hasValues() const { return !values.isEmpty(); } bool hasValues() const { return !values.isEmpty(); }
void addValue(const QStringView v) { values.append(v); }
bool isNot : 1 = false; bool isNot : 1 = false;
bool hasFilterName : 1 = false; bool hasFilterName : 1 = false;
bool isSectionEnd : 1 = false; bool isSectionEnd : 1 = false;
@ -73,14 +76,17 @@ private:
bool skipComments(); bool skipComments();
bool parseLine(); bool parseLine();
bool parseLineSection(); bool parseLineSection();
bool processSectionChar(); bool processSection();
bool processSectionBlock(); bool processSectionBlock();
void processSectionLines(); bool processSectionChar();
void processSectionList();
bool checkListBegin();
bool checkListEnd();
bool parseName(); bool parseName();
void parseBracketValues(); void parseBracketValues();
void parseValue(); void parseValue(quint32 extraCharTypes = 0);
bool checkAddFilter(); bool checkAddFilter();
@ -97,10 +103,12 @@ private:
RuleFilter &listNode(int listIndex) { return m_ruleFilterArray[listIndex]; } 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 nextCharType(quint32 expectedCharTypes, const char *extraChars = nullptr);
bool checkNextCharType(quint32 expectedCharTypes, const QChar c); bool checkNextCharType(quint32 expectedCharTypes, const QChar c);
private: private:
qint8 m_listDepth = 0;
RuleCharType m_charType = CharNone; RuleCharType m_charType = CharNone;
RuleFilter m_ruleFilter; RuleFilter m_ruleFilter;