From 78b4fec7d9ec0d551c2bf7d32f74a840cda998bf Mon Sep 17 00:00:00 2001 From: Tindy X <49061470+tindy2013@users.noreply.github.com> Date: Sat, 15 Feb 2020 11:29:40 +0800 Subject: [PATCH] Bug fixes Fix a potential random crash on non-Windows platforms. Fix compatibility with some non-standard Shadowsocks and Shadowcsocks Android subscriptions. Optimize codes. --- src/ini_reader.h | 48 ++++++++++++++++++++------------------ src/interfaces.cpp | 7 +++--- src/main.cpp | 4 ++++ src/multithread.cpp | 21 +++++++++++++---- src/multithread.h | 6 +++++ src/speedtestutil.cpp | 16 +++++++++---- src/webget.cpp | 3 ++- src/webserver_libevent.cpp | 3 +++ 8 files changed, 70 insertions(+), 38 deletions(-) diff --git a/src/ini_reader.h b/src/ini_reader.h index 3cbbaaa..574fd16 100644 --- a/src/ini_reader.h +++ b/src/ini_reader.h @@ -107,6 +107,28 @@ public: ~INIReader() = default; + INIReader& operator=(const INIReader& src) + { + //copy contents + ini_content = src.ini_content; + //copy status + parsed = src.parsed; + current_section = src.current_section; + exclude_sections = src.exclude_sections; + include_sections = src.include_sections; + read_sections = src.read_sections; + section_order = src.section_order; + isolated_items_section = src.isolated_items_section; + //copy preferences + do_utf8_to_gbk = src.do_utf8_to_gbk; + store_any_line = src.store_any_line; + store_isolated_line = src.store_isolated_line; + allow_dup_section_titles = src.allow_dup_section_titles; + return *this; + } + + INIReader(const INIReader &src) = default; + std::string GetErrorString(int error) { switch(error) @@ -158,26 +180,6 @@ public: isolated_items_section = section; } - INIReader& operator=(const INIReader& src) - { - //copy contents - ini_content = src.ini_content; - //copy status - parsed = src.parsed; - current_section = src.current_section; - exclude_sections = src.exclude_sections; - include_sections = src.include_sections; - read_sections = src.read_sections; - section_order = src.section_order; - isolated_items_section = src.isolated_items_section; - //copy preferences - do_utf8_to_gbk = src.do_utf8_to_gbk; - store_any_line = src.store_any_line; - store_isolated_line = src.store_isolated_line; - allow_dup_section_titles = src.allow_dup_section_titles; - return *this; - } - /** * @brief Parse INI content into mapped data structure. * If exclude sections are set, these sections will not be stored. @@ -211,13 +213,13 @@ public: { last_error_index++; lineSize = strLine.size(); - if(!lineSize || strLine[0] == ';' || strLine[0] == '#' || (lineSize >= 2 && strLine[0] == '/' && strLine[1] == '/')) //empty lines and comments are ignored - continue; - if(strLine[lineSize - 1] == '\r') //remove line break + if(lineSize && strLine[lineSize - 1] == '\r') //remove line break { strLine = strLine.substr(0, lineSize - 1); lineSize--; } + if(!lineSize || strLine[0] == ';' || strLine[0] == '#' || (lineSize >= 2 && strLine[0] == '/' && strLine[1] == '/')) //empty lines and comments are ignored + continue; if(strLine.find("=") != strLine.npos) //is an item { if(inExcludedSection) //this section is excluded diff --git a/src/interfaces.cpp b/src/interfaces.cpp index 48cf0b5..27df275 100644 --- a/src/interfaces.cpp +++ b/src/interfaces.cpp @@ -141,7 +141,7 @@ int importItems(string_array &target) while(getline(ss, strLine, delimiter)) { lineSize = strLine.size(); - if(strLine[lineSize - 1] == '\r') //remove line break + if(lineSize && strLine[lineSize - 1] == '\r') //remove line break { strLine = strLine.substr(0, lineSize - 1); lineSize--; @@ -1003,8 +1003,7 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS) } else { - YAML::Node yamlnode; - yamlnode = clash_base; + YAML::Node yamlnode = safe_get_clash_base(); netchToClash(nodes, yamlnode, extra_group, target == "clashr", ext); output_content = YAML::Dump(yamlnode); } @@ -1059,7 +1058,7 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS) else { INIReader ini; - ini = mellow_base; + ini = safe_get_mellow_base(); netchToMellow(nodes, ini, rca, extra_group, ext); output_content = ini.ToString(); } diff --git a/src/main.cpp b/src/main.cpp index f24f150..1112274 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "interfaces.h" #include "version.h" @@ -70,6 +71,9 @@ int main(int argc, char *argv[]) return 1; } SetConsoleOutputCP(65001); +#else + signal(SIGPIPE, SIG_IGN); + signal(SIGABRT, SIG_IGN); #endif // _WIN32 SetConsoleTitle("subconverter " VERSION); diff --git a/src/multithread.cpp b/src/multithread.cpp index 1604869..cc18193 100644 --- a/src/multithread.cpp +++ b/src/multithread.cpp @@ -1,13 +1,12 @@ -#include - -#include "misc.h" +#include "multithread.h" //safety lock for multi-thread -typedef std::lock_guard guarded_mutex; -std::mutex on_emoji, on_rename, on_stream, on_time; +std::mutex on_emoji, on_rename, on_stream, on_time, clash_base_mutex, mellow_base_mutex; extern string_array emojis, renames; extern string_array stream_rules, time_rules; +extern YAML::Node clash_base; +extern INIReader mellow_base; string_array safe_get_emojis() { @@ -33,6 +32,18 @@ string_array safe_get_times() return time_rules; } +YAML::Node safe_get_clash_base() +{ + guarded_mutex guard(clash_base_mutex); + return clash_base; +} + +INIReader safe_get_mellow_base() +{ + guarded_mutex guard(mellow_base_mutex); + return mellow_base; +} + void safe_set_emojis(string_array &data) { guarded_mutex guard(on_emoji); diff --git a/src/multithread.h b/src/multithread.h index 26e884b..8060afd 100644 --- a/src/multithread.h +++ b/src/multithread.h @@ -2,7 +2,11 @@ #define MULTITHREAD_H_INCLUDED #include + +#include + #include "misc.h" +#include "ini_reader.h" typedef std::lock_guard guarded_mutex; @@ -10,6 +14,8 @@ string_array safe_get_emojis(); string_array safe_get_renames(); string_array safe_get_streams(); string_array safe_get_times(); +YAML::Node safe_get_clash_base(); +INIReader safe_get_mellow_base(); void safe_set_emojis(string_array &data); void safe_set_renames(string_array &data); void safe_set_streams(string_array &data); diff --git a/src/speedtestutil.cpp b/src/speedtestutil.cpp index f9244dc..381dfc4 100644 --- a/src/speedtestutil.cpp +++ b/src/speedtestutil.cpp @@ -235,6 +235,8 @@ void explodeSS(std::string ss, bool libev, std::string custom_port, int local_po ss = regReplace(ss, "(.*?)@(.*):(.*)", "$1|$2|$3"); args = split(ss, "|"); secret = split(urlsafe_base64_decode(args[0]), ":"); + if(args.size() < 3 || secret.size() < 2) + return; method = secret[0]; password = secret[1]; server = args[1]; @@ -246,6 +248,8 @@ void explodeSS(std::string ss, bool libev, std::string custom_port, int local_po return; ss = regReplace(urlsafe_base64_decode(ss), "(.*?):(.*?)@(.*):(.*)", "$1|$2|$3|$4"); args = split(ss, "|"); + if(args.size() < 4) + return; method = args[0]; password = args[1]; server = args[2]; @@ -325,16 +329,18 @@ void explodeSSAndroid(std::string ss, bool libev, std::string custom_port, int l for(unsigned int i = 0; i < json["nodes"].Size(); i++) { - json["nodes"][i]["remarks"] >> ps; - json["nodes"][i]["server"] >> server; + server = GetMember(json["nodes"][i], "server"); + if(server.empty()) + continue; + ps = GetMember(json["nodes"][i], "remarks"); if(custom_port.size()) port = custom_port; else - json["nodes"][i]["server_port"] >> port; + port = GetMember(json["nodes"][i], "server_port"); if(ps == "") ps = server + ":" + port; - json["nodes"][i]["password"] >> password; - json["nodes"][i]["method"] >> method; + password = GetMember(json["nodes"][i], "password"); + method = GetMember(json["nodes"][i], "method"); plugin = GetMember(json["nodes"][i], "plugin"); pluginopts = GetMember(json["nodes"][i], "plugin_opts"); diff --git a/src/webget.cpp b/src/webget.cpp index ecfb37c..39bc4f2 100644 --- a/src/webget.cpp +++ b/src/webget.cpp @@ -4,11 +4,12 @@ #include #include "webget.h" +#include "version.h" extern bool print_debug_info; //std::string user_agent_str = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36"; -std::string user_agent_str = "subconverter/latest cURL/7.xx-DEV"; +std::string user_agent_str = "subconverter/" + std::string(VERSION) + " cURL/" + std::string(LIBCURL_VERSION); static int writer(char *data, size_t size, size_t nmemb, std::string *writerData) { diff --git a/src/webserver_libevent.cpp b/src/webserver_libevent.cpp index b0e4eae..9b38039 100644 --- a/src/webserver_libevent.cpp +++ b/src/webserver_libevent.cpp @@ -194,6 +194,9 @@ int httpserver_bindsocket(std::string listen_address, int listen_port, int backl int one = 1; ret = setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(int)); +#ifdef SO_NOSIGPIPE + ret = setsockopt(nfd, SOL_SOCKET, SO_NOSIGPIPE, (char *)&one, sizeof(int)); +#endif struct sockaddr_in addr; memset(&addr, 0, sizeof(addr));