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"
#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
{

View File

@ -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()

View File

@ -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<QString, qint8> 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);

View File

@ -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;