Bug fixes

Fix a potential random crash on non-Windows platforms.
Fix compatibility with some non-standard Shadowsocks and Shadowcsocks Android subscriptions.
Optimize codes.
This commit is contained in:
Tindy X
2020-02-15 11:29:40 +08:00
parent 794370004e
commit 78b4fec7d9
8 changed files with 70 additions and 38 deletions

View File

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

View File

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

View File

@@ -1,6 +1,7 @@
#include <iostream>
#include <string>
#include <unistd.h>
#include <signal.h>
#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);

View File

@@ -1,13 +1,12 @@
#include <mutex>
#include "misc.h"
#include "multithread.h"
//safety lock for multi-thread
typedef std::lock_guard<std::mutex> 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);

View File

@@ -2,7 +2,11 @@
#define MULTITHREAD_H_INCLUDED
#include <mutex>
#include <yaml-cpp/yaml.h>
#include "misc.h"
#include "ini_reader.h"
typedef std::lock_guard<std::mutex> 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);

View File

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

View File

@@ -4,11 +4,12 @@
#include <curl/curl.h>
#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)
{

View File

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