diff --git a/CMakeLists.txt b/CMakeLists.txt index d305be7..bd63727 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,12 +2,12 @@ project(subconverter LANGUAGES CXX) cmake_minimum_required(VERSION 3.4) SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/") IF(NOT CMAKE_BUILD_TYPE) - SET(CMAKE_BUILD_TYPE Release) + SET(CMAKE_BUILD_TYPE Release) ENDIF() SET(CMAKE_CXX_STANDARD 17) ADD_DEFINITIONS(-Wall -Wextra -Wno-unused-parameter -Wno-unused-result) -OPTION(USING_STD_REGEX "Use std::regex from C++ library instead of PCRECPP." OFF) +OPTION(USING_STD_REGEX "Use std::regex from C++ library instead of PCRE2." OFF) OPTION(USING_MALLOC_TRIM "Call malloc_trim after processing request to lower memory usage (Your system must support malloc_trim)." OFF) INCLUDE(CheckCXXSourceCompiles) @@ -18,28 +18,28 @@ int main(){std::to_string(0);return 0;} " HAVE_TO_STRING) IF(APPLE) - ADD_DEFINITIONS(-D_MACOS) + ADD_DEFINITIONS(-D_MACOS) ENDIF() IF(HAVE_TO_STRING) - ADD_DEFINITIONS(-DHAVE_TO_STRING) + ADD_DEFINITIONS(-DHAVE_TO_STRING) ENDIF() IF(USING_MALLOC_TRIM) - ADD_DEFINITIONS(-DMALLOC_TRIM) + ADD_DEFINITIONS(-DMALLOC_TRIM) ENDIF() ADD_EXECUTABLE(subconverter - src/logger.cpp - src/main.cpp - src/misc.cpp - src/multithread.cpp - src/nodemanip.cpp - src/rapidjson_extra.cpp - src/speedtestutil.cpp - src/subexport.cpp - src/webget.cpp - src/webserver_libevent.cpp) + src/logger.cpp + src/main.cpp + src/misc.cpp + src/multithread.cpp + src/nodemanip.cpp + src/rapidjson_extra.cpp + src/speedtestutil.cpp + src/subexport.cpp + src/webget.cpp + src/webserver_libevent.cpp) INCLUDE_DIRECTORIES(src) LINK_DIRECTORIES(${CMAKE_SOURCE_DIR}) @@ -75,18 +75,21 @@ INCLUDE_DIRECTORIES(${YAML_CPP_INCLUDE_DIRS}) TARGET_LINK_LIBRARIES(subconverter ${YAML_CPP_LIBRARY}) IF(USING_STD_REGEX STREQUAL "ON") - ADD_DEFINITIONS(-DUSE_STD_REGEX) + ADD_DEFINITIONS(-DUSE_STD_REGEX) ELSE() - FIND_PACKAGE(PCRECPP REQUIRED) - INCLUDE_DIRECTORIES(${PCRECPP_INCLUDE_DIRS}) - TARGET_LINK_LIBRARIES(subconverter ${PCRECPP_LIBRARIES}) - ADD_DEFINITIONS(-DPCRE_STATIC) + PKG_CHECK_MODULES(PCRE2 libpcre2-8 REQUIRED) + INCLUDE_DIRECTORIES(${PCRE2_INCLUDE_DIRS}) + TARGET_LINK_LIBRARIES(subconverter ${PCRE2_LIBRARIES}) + ADD_DEFINITIONS(-DPCRE2_STATIC) + + FIND_PACKAGE(JPCRE2 REQUIRED) + INCLUDE_DIRECTORIES(${JPCRE2_INCLUDE_DIRS}) ENDIF() IF(WIN32) - TARGET_LINK_LIBRARIES(subconverter wsock32 ws2_32) + TARGET_LINK_LIBRARIES(subconverter wsock32 ws2_32) ELSE() - INCLUDE(GNUInstallDirs) - INSTALL(TARGETS subconverter DESTINATION ${CMAKE_INSTALL_BINDIR}/subconverter) - INSTALL(DIRECTORY base/ DESTINATION ${CMAKE_INSTALL_BINDIR}/subconverter FILES_MATCHING PATTERN "*") + INCLUDE(GNUInstallDirs) + INSTALL(TARGETS subconverter DESTINATION ${CMAKE_INSTALL_BINDIR}/subconverter) + INSTALL(DIRECTORY base/ DESTINATION ${CMAKE_INSTALL_BINDIR}/subconverter FILES_MATCHING PATTERN "*") ENDIF() diff --git a/cmake/FindJPCRE2.cmake b/cmake/FindJPCRE2.cmake new file mode 100644 index 0000000..d8b2071 --- /dev/null +++ b/cmake/FindJPCRE2.cmake @@ -0,0 +1,27 @@ +# - Find JPCRE2 +# Find the JPCRE2 headers. +# +# JPCRE2_INCLUDE_DIRS - where to find jpcre2.h. +# JPCRE2_FOUND - True if JPCRE2 found. + +# Look for the header file. +FIND_PATH(JPCRE2_INCLUDE_DIR NAMES jpcre2.hpp) +MARK_AS_ADVANCED(JPCRE2_INCLUDE_DIR) + +if(JPCRE2_INCLUDE_DIR) + set(JPCRE2_FOUND TRUE) +endif() + +IF(JPCRE2_FOUND) + SET(JPCRE2_INCLUDE_DIRS ${JPCRE2_INCLUDE_DIR}) +ENDIF(JPCRE2_FOUND) + +if(JPCRE2_FOUND) + if(NOT JPCRE2_FIND_QUIETLY) + message(STATUS "Found JPCRE2 header files in ${JPCRE2_INCLUDE_DIRS}") + endif() +elseif(JPCRE2_FIND_REQUIRED) + message(FATAL_ERROR "Could not find JPCRE2") +else() + message(STATUS "Optional package JPCRE2 was not found") +endif() diff --git a/scripts/Dockerfile b/scripts/Dockerfile index 9b1a18e..5fb1b5c 100644 --- a/scripts/Dockerfile +++ b/scripts/Dockerfile @@ -3,7 +3,7 @@ MAINTAINER Tindy X # build minimized RUN apk add git g++ build-base linux-headers cmake && \ - apk add libressl-dev curl-dev rapidjson-dev libevent-dev pcre-dev yaml-cpp-dev && \ + apk add libressl-dev curl-dev rapidjson-dev libevent-dev pcre2-dev yaml-cpp-dev && \ git clone https://github.com/tindy2013/subconverter && \ cd subconverter && \ cmake . && \ @@ -12,8 +12,8 @@ RUN apk add git g++ build-base linux-headers cmake && \ mv base ../ && \ cd .. && \ rm -rf subconverter && \ - apk add libcurl yaml-cpp libevent libpcrecpp && \ - apk del git gcc g++ build-base linux-headers cmake libressl-dev curl-dev rapidjson-dev libevent-dev pcre-dev yaml-cpp-dev + apk add pcre2 libcurl yaml-cpp libevent libpcrecpp && \ + apk del git gcc g++ build-base linux-headers cmake libressl-dev curl-dev rapidjson-dev libevent-dev pcre2-dev yaml-cpp-dev # set entry CMD /base/subconverter diff --git a/scripts/build.alpine.release.sh b/scripts/build.alpine.release.sh index 7f5fef2..42c9cf5 100644 --- a/scripts/build.alpine.release.sh +++ b/scripts/build.alpine.release.sh @@ -3,7 +3,7 @@ mkdir obj set -xe apk add gcc g++ build-base linux-headers cmake make autoconf automake libtool -apk add openssl-dev openssl-libs-static curl-dev curl-static nghttp2-static zlib-dev rapidjson-dev libevent-dev libevent-static zlib-static pcre-dev bzip2-static +apk add openssl-dev openssl-libs-static curl-dev curl-static nghttp2-static zlib-dev rapidjson-dev libevent-dev libevent-static zlib-static pcre2-dev bzip2-static git clone https://github.com/jbeder/yaml-cpp cd yaml-cpp @@ -11,9 +11,12 @@ cmake -DYAML_CPP_BUILD_TESTS=OFF -DYAML_CPP_BUILD_TOOLS=OFF . > /dev/null make install -j4 > /dev/null cd .. +curl -LO https://raw.githubusercontent.com/jpcre2/jpcre2/release/src/jpcre2.hpp +cp jpcre2.hpp /usr/local/include/ + cmake . make -j4 -g++ -o base/subconverter CMakeFiles/subconverter.dir/src/*.o -static -lpcrecpp -lpcre -levent -lyaml-cpp -lcurl -lnghttp2 -lssl -lcrypto -lz -lbz2 -ldl -lpthread -O3 -s +g++ -o base/subconverter CMakeFiles/subconverter.dir/src/*.o -static -lpcre2-8 -levent -lyaml-cpp -lcurl -lnghttp2 -lssl -lcrypto -lz -lbz2 -ldl -lpthread -O3 -s cd base chmod +rx subconverter diff --git a/scripts/build.clang.sh b/scripts/build.clang.sh index c4dbbbf..9ded4c7 100644 --- a/scripts/build.clang.sh +++ b/scripts/build.clang.sh @@ -3,16 +3,16 @@ mkdir obj set -xe -c++ -std=c++17 -D_MACOS -Wall -fexceptions -c src/logger.cpp -o obj/logger.o -c++ -std=c++17 -D_MACOS -Wall -fexceptions -c src/main.cpp -o obj/main.o -c++ -std=c++17 -D_MACOS -Wall -fexceptions -c src/misc.cpp -o obj/misc.o -c++ -std=c++17 -D_MACOS -Wall -fexceptions -c src/multithread.cpp -o obj/multithread.o -c++ -std=c++17 -D_MACOS -Wall -fexceptions -c src/nodemanip.cpp -o obj/nodemanip.o -c++ -std=c++17 -D_MACOS -Wall -fexceptions -c src/rapidjson_extra.cpp -o obj/rapidjson_extra.o -c++ -std=c++17 -D_MACOS -Wall -fexceptions -c src/speedtestutil.cpp -o obj/speedtestutil.o -c++ -std=c++17 -D_MACOS -Wall -fexceptions -c src/subexport.cpp -o obj/subexport.o -c++ -std=c++17 -D_MACOS -Wall -fexceptions -c src/webget.cpp -o obj/webget.o -c++ -std=c++17 -D_MACOS -Wall -fexceptions -c src/webserver_libevent.cpp -o obj/webserver_libevent.o -c++ -o subconverter obj/logger.o obj/main.o obj/misc.o obj/multithread.o obj/nodemanip.o obj/rapidjson_extra.o obj/speedtestutil.o obj/subexport.o obj/webget.o obj/webserver_libevent.o -lpcrecpp -lpcre -levent -lpthread -lyaml-cpp -lcurl -lssl -lcrypto -lz -O3 -s +c++ -std=c++17 -Wall -fexceptions -c src/logger.cpp -o obj/logger.o +c++ -std=c++17 -Wall -fexceptions -c src/main.cpp -o obj/main.o +c++ -std=c++17 -Wall -fexceptions -c src/misc.cpp -o obj/misc.o +c++ -std=c++17 -Wall -fexceptions -c src/multithread.cpp -o obj/multithread.o +c++ -std=c++17 -Wall -fexceptions -c src/nodemanip.cpp -o obj/nodemanip.o +c++ -std=c++17 -Wall -fexceptions -c src/rapidjson_extra.cpp -o obj/rapidjson_extra.o +c++ -std=c++17 -Wall -fexceptions -c src/speedtestutil.cpp -o obj/speedtestutil.o +c++ -std=c++17 -Wall -fexceptions -c src/subexport.cpp -o obj/subexport.o +c++ -std=c++17 -Wall -fexceptions -c src/webget.cpp -o obj/webget.o +c++ -std=c++17 -Wall -fexceptions -c src/webserver_libevent.cpp -o obj/webserver_libevent.o +c++ -o subconverter obj/*.o -lpcre2-8 -levent -lpthread -lyaml-cpp -lcurl -lssl -lcrypto -lz -O3 -s chmod +x subconverter diff --git a/scripts/build.macos.release.sh b/scripts/build.macos.release.sh index a1f8c03..fe78603 100644 --- a/scripts/build.macos.release.sh +++ b/scripts/build.macos.release.sh @@ -2,7 +2,7 @@ mkdir obj set -xe -brew reinstall yaml-cpp rapidjson libevent zlib pcre bzip2 pkgconfig +brew reinstall yaml-cpp rapidjson libevent zlib pcre2 bzip2 pkgconfig git clone https://github.com/curl/curl cd curl @@ -11,20 +11,22 @@ cd curl make -j8 > /dev/null cd .. +curl -LO https://raw.githubusercontent.com/jpcre2/jpcre2/release/src/jpcre2.hpp +cp jpcre2.hpp /usr/local/include/ + cp curl/lib/.libs/libcurl.a . cp /usr/local/lib/libevent.a . cp /usr/local/opt/zlib/lib/libz.a . cp /usr/local/opt/openssl@1.1/lib/libssl.a . cp /usr/local/opt/openssl@1.1/lib/libcrypto.a . cp /usr/local/lib/libyaml-cpp.a . -cp /usr/local/lib/libpcre.a . -cp /usr/local/lib/libpcrecpp.a . +cp /usr/local/lib/libpcre2-8.a . cp /usr/local/opt/bzip2/lib/libbz2.a . export CMAKE_CXX_FLAGS="-I/usr/local/include -I/usr/local/opt/openssl@1.1/include -I/usr/local/opt/curl/include" -cmake -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl@1.1 -DMACOS=on . +cmake -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl@1.1 . make -j8 -c++ -Xlinker -unexported_symbol -Xlinker "*" -o base/subconverter CMakeFiles/subconverter.dir/src/*.o libpcrecpp.a libpcre.a libevent.a libcurl.a libz.a libssl.a libcrypto.a libyaml-cpp.a libbz2.a -ldl -lpthread -O3 +c++ -Xlinker -unexported_symbol -Xlinker "*" -o base/subconverter CMakeFiles/subconverter.dir/src/*.o libpcre2-8.a libevent.a libcurl.a libz.a libssl.a libcrypto.a libyaml-cpp.a libbz2.a -ldl -lpthread -O3 cd base chmod +rx subconverter diff --git a/scripts/config.termux.sh b/scripts/config.termux.sh index 022d691..0394ed8 100644 --- a/scripts/config.termux.sh +++ b/scripts/config.termux.sh @@ -3,7 +3,7 @@ set -xe apt update apt install -y git cmake clang pkg-config -apt install -y libevent libcurl openssl pcre +apt install -y libevent libcurl openssl pcre2 git clone https://github.com/jbeder/yaml-cpp cd yaml-cpp @@ -15,3 +15,6 @@ git clone https://github.com/tencent/rapidjson cd rapidjson cp -r include/* /data/data/com.termux/files/usr/include/ cd .. + +curl -LO https://raw.githubusercontent.com/jpcre2/jpcre2/release/src/jpcre2.hpp +cp jpcre2.hpp /data/data/com.termux/files/usr/include/ diff --git a/src/misc.cpp b/src/misc.cpp index f2555bb..05acdd0 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -11,7 +11,8 @@ #ifdef USE_STD_REGEX #include #else -#include +#include +typedef jpcre2::select jp; #endif // USE_STD_REGEX #include @@ -489,7 +490,7 @@ bool regValid(std::string ®) { try { - std::regex r(reg); + std::regex r(reg, std::regex::ECMAScript); return true; } catch (std::regex_error &e) @@ -502,7 +503,13 @@ bool regFind(std::string src, std::string target) { try { - std::regex reg(target); + std::regex::flag_type flags = std::regex::extended | std::regex::ECMAScript; + if(target.find("(?i)") == 0) + { + target.erase(0, 4); + flags |= std::regex::icase; + } + std::regex reg(target, flags); return regex_search(src, reg); } catch (std::regex_error &e) @@ -516,7 +523,13 @@ std::string regReplace(std::string src, std::string match, std::string rep) std::string result = ""; try { - std::regex reg(match); + std::regex::flag_type flags = std::regex::extended | std::regex::ECMAScript; + if(match.find("(?i)") == 0) + { + match.erase(0, 4); + flags |= std::regex::icase; + } + std::regex reg(match, flags); regex_replace(back_inserter(result), src.begin(), src.end(), reg, rep); } catch (std::regex_error &e) @@ -530,7 +543,13 @@ bool regMatch(std::string src, std::string match) { try { - std::regex reg(match); + std::regex::flag_type flags = std::regex::extended | std::regex::ECMAScript; + if(match.find("(?i)") == 0) + { + match.erase(0, 4); + flags |= std::regex::icase; + } + std::regex reg(match, flags); return regex_match(src, reg); } catch (std::regex_error &e) @@ -541,62 +560,37 @@ bool regMatch(std::string src, std::string match) #else -bool regValid(std::string ®) +bool regMatch(std::string src, std::string target, bool partial) { - try - { - pcrecpp::RE r(reg); - return true; - } - catch (std::exception &e) - { + jp::Regex reg; + reg.setPattern(target).addModifier("gm").compile(); + if(!reg) return false; - } + return reg.replace(src, "$0") == src; } bool regFind(std::string src, std::string target) { - try - { - pcrecpp::RE reg(target); - return reg.PartialMatch(src); - } - catch (std::exception &e) - { + jp::Regex reg; + reg.setPattern(target).addModifier("gm").compile(); + if(!reg) return false; - } + return reg.match(src); } -std::string regReplace(std::string src, std::string match, std::string rep) +std::string regReplace(std::string src, std::string target, std::string rep) { - std::string result = src; - try - { - if(rep.find("$") != rep.npos) - rep = replace_all_distinct(rep, "$", "\\"); - pcrecpp::RE reg(match); - if(reg.GlobalReplace(rep, &result)) - return result; - else - return src; - } - catch (std::exception &e) - { + jp::Regex reg; + reg.setPattern(target).addModifier("gm").compile(); + if(!reg) return src; - } + return reg.replace(src, rep); } -bool regMatch(std::string src, std::string match) +bool regValid(std::string &target) { - try - { - pcrecpp::RE reg(match); - return reg.FullMatch(src); - } - catch (std::exception &e) - { - return false; - } + jp::Regex reg(target); + return !!reg; } #endif // USE_STD_REGEX @@ -640,19 +634,19 @@ std::string getMD5(std::string data) unsigned int i = 0; unsigned char digest[16] = {}; - #ifdef USE_MBEDTLS +#ifdef USE_MBEDTLS mbedtls_md5_context ctx; mbedtls_md5_init(&ctx); mbedtls_md5_update(&ctx, data.data(), data.size()); mbedtls_md5_finish(&ctx, (unsigned char *)&digest); - #else +#else MD5_CTX ctx; MD5_Init(&ctx); MD5_Update(&ctx, data.data(), data.size()); MD5_Final((unsigned char *)&digest, &ctx); - #endif // USE_MBEDTLS +#endif // USE_MBEDTLS char tmp[3] = {}; for(i = 0; i < 16; i++) @@ -673,11 +667,11 @@ std::string fileGet(std::string path, bool binary, bool scope_limit) if(scope_limit) { #ifdef _WIN32 - if(path.find(":/") != path.npos || path.find("..") != path.npos) - return std::string(); + if(path.find(":/") != path.npos || path.find("..") != path.npos) + return std::string(); #else - if(path.find("/") == 0 || path.find("..") != path.npos) - return std::string(); + if(path.find("/") == 0 || path.find("..") != path.npos) + return std::string(); #endif // _WIN32 } diff --git a/src/misc.h b/src/misc.h index aa5a72b..00a43a3 100644 --- a/src/misc.h +++ b/src/misc.h @@ -40,10 +40,10 @@ bool is_str_utf8(std::string data); std::string getFormData(const std::string &raw_data); void sleep(int interval); -bool regValid(std::string ®); +bool regValid(std::string &target); bool regFind(std::string src, std::string target); std::string regReplace(std::string src, std::string match, std::string rep); -bool regMatch(std::string src, std::string match); +bool regMatch(std::string src, std::string match, bool partial = false); std::string speedCalc(double speed); std::string getMD5(std::string data); bool isIPv4(std::string &address); diff --git a/src/speedtestutil.cpp b/src/speedtestutil.cpp index 61a2322..c3bff3a 100644 --- a/src/speedtestutil.cpp +++ b/src/speedtestutil.cpp @@ -1593,22 +1593,22 @@ time_t dateStringToTimestamp(std::string date) bool getSubInfoFromHeader(std::string &header, std::string &result) { - bool ret = false; - pcrecpp::RE reg("^(?i:Subscription-UserInfo): (.*?)\\r$", pcrecpp::MULTILINE()); - try + std::string pattern = "(?:[\\s\\S]*?)^(?i:Subscription-UserInfo): (.*?)\\s$(?:[\\s\\S]*)", retStr; + if(regFind(header, pattern)) { - ret = reg.PartialMatch(header, &result); + retStr = regReplace(header, pattern, "$1"); + if(retStr != header) + { + result = retStr; + return true; + } } - catch (std::exception &e) - { - //ignore - } - return ret; + return false; } bool getSubInfoFromNodes(std::vector &nodes, string_array &stream_rules, string_array &time_rules, std::string &result) { - std::string remarks, pattern, target, stream_info, time_info; + std::string remarks, pattern, target, stream_info, time_info, retStr; string_array vArray; for(nodeInfo &x : nodes) @@ -1623,13 +1623,14 @@ bool getSubInfoFromNodes(std::vector &nodes, string_array &stream_rule continue; pattern = vArray[0]; target = vArray[1]; - pcrecpp::RE reg(pattern, pcrecpp::UTF8()); - if(reg.FullMatch(remarks)) + if(regMatch(remarks, pattern)) { - if(target.find("$") != target.npos) - target = replace_all_distinct(target, "$", "\\"); - if(reg.GlobalReplace(target, &remarks)) - stream_info = remarks; + retStr = regReplace(remarks, pattern, target); + if(retStr != remarks) + { + stream_info = retStr; + break; + } } else continue; @@ -1646,13 +1647,14 @@ bool getSubInfoFromNodes(std::vector &nodes, string_array &stream_rule continue; pattern = vArray[0]; target = vArray[1]; - pcrecpp::RE reg(pattern, pcrecpp::UTF8()); - if(reg.FullMatch(remarks)) + if(regMatch(remarks, pattern)) { - if(target.find("$") != target.npos) - target = replace_all_distinct(target, "$", "\\"); - if(reg.GlobalReplace(target, &remarks)) - time_info = remarks; + retStr = regReplace(remarks, pattern, target); + if(retStr != remarks) + { + time_info = retStr; + break; + } } else continue; diff --git a/src/subexport.cpp b/src/subexport.cpp index c143dca..7ffcdfb 100644 --- a/src/subexport.cpp +++ b/src/subexport.cpp @@ -1625,14 +1625,7 @@ void netchToQuanX(std::vector &nodes, INIReader &ini, std::vector