Fix detecting supported rule type in sing-box configs

This commit is contained in:
Tindy X
2023-11-11 23:49:50 +08:00
parent 6c7e009645
commit 7ea43f9c01
5 changed files with 87 additions and 15 deletions

View File

@@ -486,17 +486,21 @@ static rapidjson::Value transformRuleToSingBox(const std::string& rule, const st
static void appendSingBoxRule(rapidjson::Value &rules, const std::string& rule, rapidjson::MemoryPoolAllocator<>& allocator)
{
using namespace rapidjson_ext;
auto args = split(rule, ",");
auto args = split(rule, ',');
if (args.size() < 2) return;
auto type = toLower(std::string(args[0]));
auto value = toLower(args[1]);
auto type = args[0];
// std::string_view option;
// if (args.size() >= 3) option = args[2];
type = replaceAllDistinct(type, "-", "_");
type = replaceAllDistinct(type, "ip_cidr6", "ip_cidr");
if (none_of(SingBoxRuleTypes, [&](const std::string& t){ return type == t; }))
return;
rules | AppendToArray(type.c_str(), rapidjson::Value(value.c_str(), allocator), allocator);
auto realType = toLower(std::string(type));
auto value = toLower(std::string(args[1]));
realType = replaceAllDistinct(realType, "-", "_");
realType = replaceAllDistinct(realType, "ip_cidr6", "ip_cidr");
rules | AppendToArray(realType.c_str(), rapidjson::Value(value.c_str(), value.size(), allocator), allocator);
}
void rulesetToSingBox(rapidjson::Document &base_rule, std::vector<RulesetContent> &ruleset_content_array, bool overwrite_original_rules)
@@ -565,8 +569,6 @@ void rulesetToSingBox(rapidjson::Document &base_rule, std::vector<RulesetContent
lineSize = strLine.size();
if(!lineSize || strLine[0] == ';' || strLine[0] == '#' || (lineSize >= 2 && strLine[0] == '/' && strLine[1] == '/')) //empty lines and comments are ignored
continue;
if(std::none_of(SingBoxRuleTypes.begin(), SingBoxRuleTypes.end(), [strLine](const std::string& type){return startsWith(strLine, type);}))
continue;
if(strFind(strLine, "//"))
{
strLine.erase(strLine.find("//"));

View File

@@ -117,14 +117,23 @@ namespace rapidjson_ext {
struct AppendToArray : public ExtensionFunction<rapidjson::Value &>
{
rapidjson::Value &value;
const rapidjson::Value::Ch *name;
rapidjson::GenericValue<rapidjson::UTF8<>> name;
rapidjson::MemoryPoolAllocator<> &allocator;
AppendToArray(const rapidjson::Value::Ch *name, rapidjson::Value &value,
rapidjson::MemoryPoolAllocator<> &allocator): value(value), name(name), allocator(allocator) {}
rapidjson::MemoryPoolAllocator<> &allocator): value(value), name(rapidjson::Value(name, allocator)), allocator(allocator) {}
AppendToArray(const rapidjson::Value::Ch *name, rapidjson::Value &&value,
rapidjson::MemoryPoolAllocator<> &allocator): value(value), name(name), allocator(allocator) {}
rapidjson::MemoryPoolAllocator<> &allocator): value(value), name(rapidjson::Value(name, allocator)), allocator(allocator) {}
AppendToArray(const rapidjson::Value::Ch *name, std::size_t length, rapidjson::Value &value,
rapidjson::MemoryPoolAllocator<> &allocator): value(value), name(rapidjson::Value(name, length, allocator)), allocator(allocator) {}
AppendToArray(const rapidjson::Value::Ch *name, std::size_t length, rapidjson::Value &&value,
rapidjson::MemoryPoolAllocator<> &allocator): value(value), name(rapidjson::Value(name, length, allocator)), allocator(allocator) {}
AppendToArray(rapidjson::Value &&name, rapidjson::Value &value,
rapidjson::MemoryPoolAllocator<> &allocator): value(value), allocator(allocator) { this->name.Swap(name); }
inline rapidjson::Value &operator()(rapidjson::Value &root) const override
{

View File

@@ -14,4 +14,25 @@ template <typename T> inline void eraseElements(T &target)
T().swap(target);
}
template <typename Container, typename Element>
concept ConstIterable = requires(Container a, Element b) {
{ a.cbegin() } -> std::same_as<typename Container::const_iterator>;
{ a.cend() } -> std::same_as<typename Container::const_iterator>;
typename Container::const_reference;
};
template <typename Container, typename Element>
concept Iterable = requires(Container a, Element b) {
{ a.begin() } -> std::same_as<typename Container::iterator>;
{ a.end() } -> std::same_as<typename Container::iterator>;
typename Container::reference;
};
template <typename ConstIterableContainer>
requires ConstIterable<ConstIterableContainer, typename ConstIterableContainer::value_type>
inline bool none_of(ConstIterableContainer &container, std::function<bool(typename ConstIterableContainer::const_reference)> func)
{
return std::none_of(container.cbegin(), container.cend(), func);
}
#endif // STL_EXTRA_H_INCLUDED

View File

@@ -9,7 +9,7 @@
#include "string.h"
#include "map_extra.h"
std::vector<std::string> split(const std::string &s, const std::string &seperator)
std::vector<std::string> split(const std::string &s, const std::string &separator)
{
std::vector<std::string> result;
string_size i = 0;
@@ -20,7 +20,7 @@ std::vector<std::string> split(const std::string &s, const std::string &seperato
while(i != s.size() && flag == 0)
{
flag = 1;
for(char x : seperator)
for(char x : separator)
if(s[i] == x)
{
++i;
@@ -33,7 +33,7 @@ std::vector<std::string> split(const std::string &s, const std::string &seperato
string_size j = i;
while(j != s.size() && flag == 0)
{
for(char x : seperator)
for(char x : separator)
if(s[j] == x)
{
flag = 1;
@@ -51,6 +51,45 @@ std::vector<std::string> split(const std::string &s, const std::string &seperato
return result;
}
std::vector<std::string_view> split(std::string_view s, char separator)
{
std::vector<std::string_view> result;
string_size i = 0;
while (i != s.size())
{
int flag = 0;
while(i != s.size() && flag == 0)
{
flag = 1;
if(s[i] == separator)
{
++i;
flag = 0;
break;
}
}
flag = 0;
string_size j = i;
while(j != s.size() && flag == 0)
{
if(s[j] == separator)
{
flag = 1;
break;
}
++j;
}
if (i != j)
{
result.push_back(s.substr(i, j-i));
i = j;
}
}
return result;
}
std::string UTF8ToCodePoint(const std::string &data)
{
std::stringstream ss;

View File

@@ -14,7 +14,8 @@ using string_map = std::map<std::string, std::string>;
using string_multimap = std::multimap<std::string, std::string>;
using string_pair_array = std::vector<std::pair<std::string, std::string>>;
std::vector<std::string> split(const std::string &s, const std::string &seperator);
std::vector<std::string> split(const std::string &s, const std::string &separator);
std::vector<std::string_view> split(std::string_view s, char separator);
std::string join(const string_array &arr, const std::string &delimiter);
template <typename InputIt>