diff --git a/src/interfaces.cpp b/src/interfaces.cpp index 76b9acd..2fb07c8 100644 --- a/src/interfaces.cpp +++ b/src/interfaces.cpp @@ -87,10 +87,7 @@ std::string parseProxy(const std::string &source) return proxy; } -#define basic_types "DOMAIN", "DOMAIN-SUFFIX", "DOMAIN-KEYWORD", "IP-CIDR", "SRC-IP-CIDR", "GEOIP", "MATCH", "FINAL" -const string_array clash_rule_type = {basic_types, "IP-CIDR6", "SRC-PORT", "DST-PORT"}; -const string_array surge_rule_type = {basic_types, "IP-CIDR6", "USER-AGENT", "URL-REGEX", "AND", "OR", "NOT", "PROCESS-NAME", "IN-PORT", "DEST-PORT", "SRC-IP"}; -const string_array quanx_rule_type = {basic_types, "USER-AGENT", "HOST", "HOST-SUFFIX", "HOST-KEYWORD"}; +extern string_array clash_rule_type, surge_rule_type, quanx_rule_type; const std::map ruleset_types = {{"clash-domain:", RULESET_CLASH_DOMAIN}, {"clash-ipcidr:", RULESET_CLASH_IPCIDR}, {"clash-classic:", RULESET_CLASH_CLASSICAL}, \ {"quanx:", RULESET_QUANX}, {"surge:", RULESET_SURGE}}; diff --git a/src/misc.cpp b/src/misc.cpp index abf11c9..b89cb37 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -198,7 +198,7 @@ std::string UrlDecode(const std::string& str) /* static inline bool is_base64(unsigned char c) { - return (isalnum(c) || (c == '+') || (c == '/')); + return (isalnum(c) || (c == '+') || (c == '/') || (c == '-') || (c == '_')); } */ @@ -280,7 +280,12 @@ std::string base64_decode(const std::string &encoded_string, bool accept_urlsafe { uchar = encoded_string[in_]; // make compiler happy if (!(accept_urlsafe ? itable[uchar] : (itable[uchar] == 1))) // break away from the while condition + { + ret += uchar; // not base64 encoded data, copy to result + in_++; + i = 0; continue; + } char_array_4[i++] = uchar; in_++; if (i == 4) @@ -696,10 +701,10 @@ bool regFind(const std::string &src, const std::string &match) return reg.match(src, "g"); } -std::string regReplace(const std::string &src, const std::string &match, const std::string &rep, bool global) +std::string regReplace(const std::string &src, const std::string &match, const std::string &rep, bool global, bool multiline) { jp::Regex reg; - reg.setPattern(match).addModifier("m").addPcre2Option(PCRE2_UTF|PCRE2_MULTILINE|PCRE2_ALT_BSUX).compile(); + reg.setPattern(match).addModifier(multiline ? "m" : "").addPcre2Option(PCRE2_UTF|PCRE2_MULTILINE|PCRE2_ALT_BSUX).compile(); if(!reg) return src; return reg.replace(src, rep, global ? "gx" : "x"); @@ -747,7 +752,7 @@ int regGetMatch(const std::string &src, const std::string &match, size_t group_c std::string regTrim(const std::string &src) { - return regReplace(src, "^\\s*?([\\s\\S]*)\\s*$", "$1", false); + return regReplace(src, "^\\s*([\\s\\S]*)\\s*$", "$1", false, false); } std::string speedCalc(double speed) diff --git a/src/misc.h b/src/misc.h index 34c9cd2..0271579 100644 --- a/src/misc.h +++ b/src/misc.h @@ -64,7 +64,7 @@ std::string getFormData(const std::string &raw_data); void sleep(int interval); bool regValid(const std::string ®); bool regFind(const std::string &src, const std::string &match); -std::string regReplace(const std::string &src, const std::string &match, const std::string &rep, bool global = true); +std::string regReplace(const std::string &src, const std::string &match, const std::string &rep, bool global = true, bool multiline = true); bool regMatch(const std::string &src, const std::string &match); int regGetMatch(const std::string &src, const std::string &match, size_t group_count, ...); std::string regTrim(const std::string &src); diff --git a/src/speedtestutil.cpp b/src/speedtestutil.cpp index 489e043..f862e4e 100644 --- a/src/speedtestutil.cpp +++ b/src/speedtestutil.cpp @@ -719,7 +719,7 @@ void explodeHTTPSub(std::string link, const std::string &custom_port, nodeInfo & void explodeTrojan(std::string trojan, const std::string &custom_port, nodeInfo &node) { - std::string server, port, psk, addition, remark, host; + std::string server, port, psk, addition, group, remark, host; tribool tfo, scv; trojan.erase(0, 9); string_size pos = trojan.rfind("#"); @@ -746,18 +746,21 @@ void explodeTrojan(std::string trojan, const std::string &custom_port, nodeInfo host = getUrlArg(addition, "peer"); tfo = getUrlArg(addition, "tfo"); scv = getUrlArg(addition, "allowInsecure"); + group = UrlDecode(getUrlArg(addition, "group")); if(remark.empty()) remark = server + ":" + port; if(host.empty() && !isIPv4(server) && !isIPv6(server)) host = server; + if(group.empty()) + group = TROJAN_DEFAULT_GROUP; node.linkType = SPEEDTEST_MESSAGE_FOUNDTROJAN; - node.group = TROJAN_DEFAULT_GROUP; + node.group = group; node.remarks = remark; node.server = server; node.port = to_int(port, 1); - node.proxyStr = trojanConstruct(node.group, remark, server, port, psk, host, true, tribool(), tfo, scv); + node.proxyStr = trojanConstruct(group, remark, server, port, psk, host, true, tribool(), tfo, scv); } void explodeQuan(const std::string &quan, const std::string &custom_port, nodeInfo &node) @@ -1140,7 +1143,7 @@ void explodeShadowrocket(std::string rocket, const std::string &custom_port, nod port = custom_port; if(port == "0") return; - remarks = UrlDecode(getUrlArg(addition, "remark")); + remarks = UrlDecode(getUrlArg(addition, "remarks")); obfs = getUrlArg(addition, "obfs"); if(obfs.size()) { @@ -1996,7 +1999,7 @@ void explodeSub(std::string sub, bool sslibev, bool ssrlibev, const std::string //try to parse as normal subscription if(!processed) { - sub = urlsafe_base64_decode(trim(sub)); + sub = urlsafe_base64_decode(sub); if(regFind(sub, "(vmess|shadowsocks|http|trojan)\\s*?=")) { if(explodeSurge(sub, custom_port, nodes, sslibev)) diff --git a/src/subexport.cpp b/src/subexport.cpp index b230bde..b2e2a16 100644 --- a/src/subexport.cpp +++ b/src/subexport.cpp @@ -34,11 +34,11 @@ const string_array clash_ssr_ciphers = {"rc4-md5", "aes-128-ctr", "aes-192-ctr", /// rule type lists #define basic_types "DOMAIN", "DOMAIN-SUFFIX", "DOMAIN-KEYWORD", "IP-CIDR", "SRC-IP-CIDR", "GEOIP", "MATCH", "FINAL" -const string_array clash_rule_type = {basic_types, "IP-CIDR6", "SRC-PORT", "DST-PORT"}; -const string_array surge2_rule_type = {basic_types, "IP-CIDR6", "USER-AGENT", "URL-REGEX", "PROCESS-NAME", "IN-PORT", "DEST-PORT", "SRC-IP"}; -const string_array surge_rule_type = {basic_types, "IP-CIDR6", "USER-AGENT", "URL-REGEX", "AND", "OR", "NOT", "PROCESS-NAME", "IN-PORT", "DEST-PORT", "SRC-IP"}; -const string_array quanx_rule_type = {basic_types, "USER-AGENT", "HOST", "HOST-SUFFIX", "HOST-KEYWORD"}; -const string_array surfb_rule_type = {basic_types, "IP-CIDR6", "PROCESS-NAME", "IN-PORT", "DEST-PORT", "SRC-IP"}; +string_array clash_rule_type = {basic_types, "IP-CIDR6", "SRC-PORT", "DST-PORT"}; +string_array surge2_rule_type = {basic_types, "IP-CIDR6", "USER-AGENT", "URL-REGEX", "PROCESS-NAME", "IN-PORT", "DEST-PORT", "SRC-IP"}; +string_array surge_rule_type = {basic_types, "IP-CIDR6", "USER-AGENT", "URL-REGEX", "AND", "OR", "NOT", "PROCESS-NAME", "IN-PORT", "DEST-PORT", "SRC-IP"}; +string_array quanx_rule_type = {basic_types, "USER-AGENT", "HOST", "HOST-SUFFIX", "HOST-KEYWORD"}; +string_array surfb_rule_type = {basic_types, "IP-CIDR6", "PROCESS-NAME", "IN-PORT", "DEST-PORT", "SRC-IP"}; std::string hostnameToIPAddr(const std::string &host) {