shadowsocks-libev: convert to PCRE2

Convert package to PCRE2 by porting a pending patch from a closed PR.

The PR is old but the code never changed and is simple enough to check
the changes. The patch apply directly with no changes (aside from
commenting out the travis CI file)

The PR was never merged as PCRE2 at times was too new and they were
trying to find a better regex lib.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
This commit is contained in:
Christian Marangi 2023-10-09 18:30:58 +02:00 committed by Josef Schlehofer
parent 99b3b46abc
commit db305165c9
2 changed files with 548 additions and 4 deletions

View File

@ -14,7 +14,7 @@ include $(TOPDIR)/rules.mk
#
PKG_NAME:=shadowsocks-libev
PKG_VERSION:=3.3.5
PKG_RELEASE:=9
PKG_RELEASE:=10
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://github.com/shadowsocks/shadowsocks-libev/releases/download/v$(PKG_VERSION)
@ -29,7 +29,7 @@ PKG_FIXUP:=autoreconf
PKG_INSTALL:=1
PKG_BUILD_FLAGS:=no-mips16 lto
PKG_BUILD_PARALLEL:=1
PKG_BUILD_DEPENDS:=c-ares pcre
PKG_BUILD_DEPENDS:=c-ares pcre2
include $(INCLUDE_DIR)/package.mk
@ -71,8 +71,8 @@ define Package/shadowsocks-libev/Default
endef
DEPENDS_ss-local = +libpcre
DEPENDS_ss-server = +libcares +libpcre
DEPENDS_ss-local = +libpcre2
DEPENDS_ss-server = +libcares +libpcre2
SHADOWSOCKS_COMPONENTS:=ss-local ss-redir ss-tunnel ss-server
define shadowsocks-libev/templates

View File

@ -0,0 +1,544 @@
From d4f4d9761cbd41c3ab6de79383ff39b9f97bf452 Mon Sep 17 00:00:00 2001
From: Syrone Wong <wong.syrone@gmail.com>
Date: Sat, 18 Nov 2017 20:06:50 +0800
Subject: [PATCH] Upgrade PCRE to PCRE2
- Use 8bit variant by default
This comes from a PR closed and never reopen as at times PCRE2 was too
new(???.)
Ref: https://github.com/shadowsocks/shadowsocks-libev/pull/1792
Signed-off-by: Syrone Wong <wong.syrone@gmail.com>
[ squash the first 2 patch from PR, drop the last one ]
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
.travis.yml | 9 ++-
configure.ac | 8 +--
m4/pcre.m4 | 152 ------------------------------------------
m4/pcre2.m4 | 181 +++++++++++++++++++++++++++++++++++++++++++++++++++
src/rule.c | 53 ++++++++++++---
src/rule.h | 23 +++++--
6 files changed, 253 insertions(+), 173 deletions(-)
delete mode 100644 m4/pcre.m4
create mode 100644 m4/pcre2.m4
# diff --git a/.travis.yml b/.travis.yml
# index ee3424c..e7da08c 100644
# --- a/.travis.yml
# +++ b/.travis.yml
# @@ -11,11 +11,12 @@ env:
# global:
# - LIBSODIUM_VER=1.0.12
# - MBEDTLS_VER=2.4.0
# + - PCRE2_VER=10.30
# before_install:
# - |
# if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
# # All dependencies for macOS build. Some packages has been installed by travis so use reinstall.
# - brew reinstall autoconf automake xmlto c-ares libev mbedtls libsodium asciidoc >> /dev/null 2>&1;
# + brew reinstall autoconf automake xmlto pcre2 c-ares libev mbedtls libsodium asciidoc >> /dev/null 2>&1;
# else
# wget https://github.com/jedisct1/libsodium/releases/download/$LIBSODIUM_VER/libsodium-$LIBSODIUM_VER.tar.gz;
# tar xvf libsodium-$LIBSODIUM_VER.tar.gz;
# @@ -29,6 +30,12 @@ before_install:
# make SHARED=1;
# sudo make install;
# popd;
# + wget https://ftp.pcre.org/pub/pcre/pcre2-$PCRE2_VER.tar.gz;
# + tar xvf pcre2-$PCRE2_VER.tar.gz;
# + pushd pcre2-$PCRE2_VER;
# + ./configure --prefix=/usr --enable-pcre2-16 --enable-pcre2-32 && make;
# + sudo make install;
# + popd;
# # Load cached docker images
# if [[ -d $HOME/docker ]]; then
# ls $HOME/docker/*.tar.gz | xargs -I {file} sh -c "zcat {file} | docker load";
--- a/configure.ac
+++ b/configure.ac
@@ -20,10 +20,10 @@ AC_DISABLE_STATIC
AC_DISABLE_SHARED
LT_INIT([dlopen])
-dnl Check for pcre library
-TS_CHECK_PCRE
-if test "x${enable_pcre}" != "xyes"; then
- AC_MSG_ERROR([Cannot find pcre library. Configure --with-pcre=DIR])
+dnl Check for pcre2 library
+TS_CHECK_PCRE2
+if test "x${enable_pcre2}" != "xyes"; then
+ AC_MSG_ERROR([Cannot find pcre2 library. Configure --with-pcre2=DIR])
fi
dnl Checks for using shared libraries from system
--- a/m4/pcre.m4
+++ /dev/null
@@ -1,152 +0,0 @@
-dnl -------------------------------------------------------- -*- autoconf -*-
-dnl Licensed to the Apache Software Foundation (ASF) under one or more
-dnl contributor license agreements. See the NOTICE file distributed with
-dnl this work for additional information regarding copyright ownership.
-dnl The ASF licenses this file to You under the Apache License, Version 2.0
-dnl (the "License"); you may not use this file except in compliance with
-dnl the License. You may obtain a copy of the License at
-dnl
-dnl http://www.apache.org/licenses/LICENSE-2.0
-dnl
-dnl Unless required by applicable law or agreed to in writing, software
-dnl distributed under the License is distributed on an "AS IS" BASIS,
-dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-dnl See the License for the specific language governing permissions and
-dnl limitations under the License.
-
-dnl
-dnl TS_ADDTO(variable, value)
-dnl
-dnl Add value to variable
-dnl
-AC_DEFUN([TS_ADDTO], [
- if test "x$$1" = "x"; then
- test "x$verbose" = "xyes" && echo " setting $1 to \"$2\""
- $1="$2"
- else
- ats_addto_bugger="$2"
- for i in $ats_addto_bugger; do
- ats_addto_duplicate="0"
- for j in $$1; do
- if test "x$i" = "x$j"; then
- ats_addto_duplicate="1"
- break
- fi
- done
- if test $ats_addto_duplicate = "0"; then
- test "x$verbose" = "xyes" && echo " adding \"$i\" to $1"
- $1="$$1 $i"
- fi
- done
- fi
-])dnl
-
-dnl
-dnl TS_ADDTO_RPATH(path)
-dnl
-dnl Adds path to variable with the '-rpath' directive.
-dnl
-AC_DEFUN([TS_ADDTO_RPATH], [
- AC_MSG_NOTICE([adding $1 to RPATH])
- TS_ADDTO(LIBTOOL_LINK_FLAGS, [-R$1])
-])dnl
-
-dnl
-dnl pcre.m4: Trafficserver's pcre autoconf macros
-dnl
-
-dnl
-dnl TS_CHECK_PCRE: look for pcre libraries and headers
-dnl
-AC_DEFUN([TS_CHECK_PCRE], [
-enable_pcre=no
-AC_ARG_WITH(pcre, [AC_HELP_STRING([--with-pcre=DIR],[use a specific pcre library])],
-[
- if test "x$withval" != "xyes" && test "x$withval" != "x"; then
- pcre_base_dir="$withval"
- if test "$withval" != "no"; then
- enable_pcre=yes
- case "$withval" in
- *":"*)
- pcre_include="`echo $withval |sed -e 's/:.*$//'`"
- pcre_ldflags="`echo $withval |sed -e 's/^.*://'`"
- AC_MSG_CHECKING(checking for pcre includes in $pcre_include libs in $pcre_ldflags )
- ;;
- *)
- pcre_include="$withval/include"
- pcre_ldflags="$withval/lib"
- AC_MSG_CHECKING(checking for pcre includes in $withval)
- ;;
- esac
- fi
- fi
-],
-[
- AC_CHECK_PROG(PCRE_CONFIG, pcre-config, pcre-config)
- if test "x$PCRE_CONFIG" != "x"; then
- enable_pcre=yes
- pcre_base_dir="`$PCRE_CONFIG --prefix`"
- pcre_include="`$PCRE_CONFIG --cflags | sed -es/-I//`"
- pcre_ldflags="`$PCRE_CONFIG --libs | sed -es/-lpcre// -es/-L//`"
- fi
-])
-
-if test "x$pcre_base_dir" = "x"; then
- AC_MSG_CHECKING([for pcre location])
- AC_CACHE_VAL(ats_cv_pcre_dir,[
- for dir in /usr/local /usr ; do
- if test -d $dir && ( test -f $dir/include/pcre.h || test -f $dir/include/pcre/pcre.h ); then
- ats_cv_pcre_dir=$dir
- break
- fi
- done
- ])
- pcre_base_dir=$ats_cv_pcre_dir
- if test "x$pcre_base_dir" = "x"; then
- enable_pcre=no
- AC_MSG_RESULT([not found])
- else
- enable_pcre=yes
- pcre_include="$pcre_base_dir/include"
- pcre_ldflags="$pcre_base_dir/lib"
- AC_MSG_RESULT([$pcre_base_dir])
- fi
-else
- AC_MSG_CHECKING(for pcre headers in $pcre_include)
- if test -d $pcre_include && test -d $pcre_ldflags && ( test -f $pcre_include/pcre.h || test -f $pcre_include/pcre/pcre.h ); then
- AC_MSG_RESULT([ok])
- else
- AC_MSG_RESULT([not found])
- fi
-fi
-
-pcreh=0
-pcre_pcreh=0
-if test "$enable_pcre" != "no"; then
- saved_ldflags=$LDFLAGS
- saved_cppflags=$CFLAGS
- pcre_have_headers=0
- pcre_have_libs=0
- if test "$pcre_base_dir" != "/usr"; then
- TS_ADDTO(CFLAGS, [-I${pcre_include}])
- TS_ADDTO(CFLAGS, [-DPCRE_STATIC])
- TS_ADDTO(LDFLAGS, [-L${pcre_ldflags}])
- TS_ADDTO_RPATH(${pcre_ldflags})
- fi
- AC_SEARCH_LIBS([pcre_exec], [pcre], [pcre_have_libs=1])
- if test "$pcre_have_libs" != "0"; then
- AC_CHECK_HEADERS(pcre.h, [pcre_have_headers=1])
- AC_CHECK_HEADERS(pcre/pcre.h, [pcre_have_headers=1])
- fi
- if test "$pcre_have_headers" != "0"; then
- AC_DEFINE(HAVE_LIBPCRE,1,[Compiling with pcre support])
- AC_SUBST(LIBPCRE, [-lpcre])
- else
- enable_pcre=no
- CFLAGS=$saved_cppflags
- LDFLAGS=$saved_ldflags
- fi
-fi
-AC_SUBST(pcreh)
-AC_SUBST(pcre_pcreh)
-])
--- /dev/null
+++ b/m4/pcre2.m4
@@ -0,0 +1,181 @@
+dnl -------------------------------------------------------- -*- autoconf -*-
+dnl Licensed to the Apache Software Foundation (ASF) under one or more
+dnl contributor license agreements. See the NOTICE file distributed with
+dnl this work for additional information regarding copyright ownership.
+dnl The ASF licenses this file to You under the Apache License, Version 2.0
+dnl (the "License"); you may not use this file except in compliance with
+dnl the License. You may obtain a copy of the License at
+dnl
+dnl http://www.apache.org/licenses/LICENSE-2.0
+dnl
+dnl Unless required by applicable law or agreed to in writing, software
+dnl distributed under the License is distributed on an "AS IS" BASIS,
+dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+dnl See the License for the specific language governing permissions and
+dnl limitations under the License.
+
+dnl Modified by Syrone Wong <wong.syrone@gmail.com> to support pcre2 8bit variant only
+
+dnl
+dnl TS_ADDTO(variable, value)
+dnl
+dnl Add value to variable
+dnl
+AC_DEFUN([TS_ADDTO], [
+ if test "x$$1" = "x"; then
+ test "x$verbose" = "xyes" && echo " setting $1 to \"$2\""
+ $1="$2"
+ else
+ ats_addto_bugger="$2"
+ for i in $ats_addto_bugger; do
+ ats_addto_duplicate="0"
+ for j in $$1; do
+ if test "x$i" = "x$j"; then
+ ats_addto_duplicate="1"
+ break
+ fi
+ done
+ if test $ats_addto_duplicate = "0"; then
+ test "x$verbose" = "xyes" && echo " adding \"$i\" to $1"
+ $1="$$1 $i"
+ fi
+ done
+ fi
+])dnl
+
+dnl
+dnl TS_ADDTO_RPATH(path)
+dnl
+dnl Adds path to variable with the '-rpath' directive.
+dnl
+AC_DEFUN([TS_ADDTO_RPATH], [
+ AC_MSG_NOTICE([adding $1 to RPATH])
+ TS_ADDTO(LIBTOOL_LINK_FLAGS, [-R$1])
+])dnl
+
+dnl
+dnl pcre2.m4: Trafficserver's pcre2 autoconf macros
+dnl
+
+dnl
+dnl TS_CHECK_PCRE2: look for pcre2 libraries and headers
+dnl
+AC_DEFUN([TS_CHECK_PCRE2], [
+enable_pcre2=no
+AC_ARG_WITH(pcre2, [AC_HELP_STRING([--with-pcre2=DIR],[use a specific pcre2 library])],
+[
+ if test "x$withval" != "xyes" && test "x$withval" != "x"; then
+ pcre2_base_dir="$withval"
+ if test "$withval" != "no"; then
+ enable_pcre2=yes
+ case "$withval" in
+ *":"*)
+ pcre2_include="`echo $withval |sed -e 's/:.*$//'`"
+ pcre2_ldflags="`echo $withval |sed -e 's/^.*://'`"
+ AC_MSG_CHECKING(checking for pcre2 includes in $pcre2_include libs in $pcre2_ldflags )
+ ;;
+ *)
+ pcre2_include="$withval/include"
+ pcre2_ldflags="$withval/lib"
+ AC_MSG_CHECKING(checking for pcre2 includes in $withval)
+ ;;
+ esac
+ fi
+ fi
+],
+[
+ AC_CHECK_PROG(PCRE2_CONFIG, pcre2-config, pcre2-config)
+ if test "x$PCRE2_CONFIG" != "x"; then
+ enable_pcre2=yes
+ pcre2_base_dir="`$PCRE2_CONFIG --prefix`"
+ pcre2_include="`$PCRE2_CONFIG --cflags | sed -es/-I//`"
+ pcre2_ldflags="`$PCRE2_CONFIG --libs8 | sed -es/-lpcre2-8// -es/-L//`"
+ fi
+])
+
+if test "x$pcre2_base_dir" = "x"; then
+ AC_MSG_CHECKING([for pcre2 location])
+ AC_CACHE_VAL(ats_cv_pcre2_dir,[
+ for dir in /usr/local /usr ; do
+ if test -d $dir && ( test -f $dir/include/pcre2.h || test -f $dir/include/pcre2/pcre2.h ); then
+ ats_cv_pcre2_dir=$dir
+ break
+ fi
+ done
+ ])
+ pcre2_base_dir=$ats_cv_pcre2_dir
+ if test "x$pcre2_base_dir" = "x"; then
+ enable_pcre2=no
+ AC_MSG_RESULT([not found])
+ else
+ enable_pcre2=yes
+ pcre2_include="$pcre2_base_dir/include"
+ pcre2_ldflags="$pcre2_base_dir/lib"
+ AC_MSG_RESULT([$pcre2_base_dir])
+ fi
+else
+ AC_MSG_CHECKING(for pcre2 headers in $pcre2_include)
+ if test -d $pcre2_include && test -d $pcre2_ldflags && ( test -f $pcre2_include/pcre2.h || test -f $pcre2_include/pcre2/pcre2.h ); then
+ AC_MSG_RESULT([ok])
+ else
+ AC_MSG_RESULT([not found])
+ fi
+fi
+
+pcre2h=0
+pcre2_pcre2h=0
+if test "$enable_pcre2" != "no"; then
+ saved_ldflags=$LDFLAGS
+ saved_cppflags=$CFLAGS
+ pcre2_have_headers=0
+ pcre2_have_libs=0
+ if test "$pcre2_base_dir" != "/usr"; then
+ TS_ADDTO(CFLAGS, [-I${pcre2_include}])
+ TS_ADDTO(CFLAGS, [-DPCRE2_STATIC])
+ TS_ADDTO(LDFLAGS, [-L${pcre2_ldflags}])
+ TS_ADDTO_RPATH(${pcre2_ldflags})
+ fi
+ AC_SEARCH_LIBS([pcre2_match_8], [pcre2-8], [pcre2_have_libs=1])
+ if test "$pcre2_have_libs" != "0"; then
+ AC_MSG_CHECKING([pcre2.h])
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[
+#define PCRE2_CODE_UNIT_WIDTH 8
+#include <pcre2.h>
+ ]],
+ [[
+ ]]
+ )],
+ [pcre2_have_headers=1
+ AC_MSG_RESULT([ok])],
+ [AC_MSG_RESULT([not found])]
+ )
+
+ AC_MSG_CHECKING([pcre2/pcre2.h])
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[
+#define PCRE2_CODE_UNIT_WIDTH 8
+#include <pcre2/pcre2.h>
+ ]],
+ [[
+ ]]
+ )],
+ [pcre2_have_headers=1
+ AC_MSG_RESULT([ok])],
+ [AC_MSG_RESULT([not found])]
+ )
+ fi
+ if test "$pcre2_have_headers" != "0"; then
+ AC_DEFINE(HAVE_LIBPCRE2,1,[Compiling with pcre2 support])
+ AC_SUBST(LIBPCRE2, [-lpcre2-8])
+ else
+ enable_pcre2=no
+ CFLAGS=$saved_cppflags
+ LDFLAGS=$saved_ldflags
+ fi
+fi
+AC_SUBST(pcre2h)
+AC_SUBST(pcre2_pcre2h)
+])
--- a/src/rule.c
+++ b/src/rule.c
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2011 and 2012, Dustin Lundquist <dustin@null-ptr.net>
* Copyright (c) 2011 Manuel Kasper <mk@neon1.net>
+ * Copyright (c) 2017 Syrone Wong <wong.syrone@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -74,18 +75,37 @@ add_rule(struct cork_dllist *rules, rule
cork_dllist_add(rules, &rule->entries);
}
+/*
+ * XXX: As pattern and subject are char arguments, they can be straightforwardly
+ * cast to PCRE2_SPTR as we are working in 8-bit code units.
+ */
+
int
init_rule(rule_t *rule)
{
if (rule->pattern_re == NULL) {
- const char *reerr;
- int reerroffset;
+ int errornumber;
+ PCRE2_SIZE erroroffset;
+ rule->pattern_re = pcre2_compile(
+ (PCRE2_SPTR)rule->pattern, /* the pattern */
+ PCRE2_ZERO_TERMINATED, /* indicates pattern is zero-terminated */
+ 0, /* default options */
+ &errornumber, /* for error number */
+ &erroroffset, /* for error offset */
+ NULL); /* use default compile context */
- rule->pattern_re =
- pcre_compile(rule->pattern, 0, &reerr, &reerroffset, NULL);
if (rule->pattern_re == NULL) {
- LOGE("Regex compilation of \"%s\" failed: %s, offset %d",
- rule->pattern, reerr, reerroffset);
+ PCRE2_UCHAR errbuffer[512];
+ pcre2_get_error_message(errornumber, errbuffer, sizeof(errbuffer));
+ LOGE("PCRE2 regex compilation failed at offset %d: %s\n", (int)erroroffset,
+ errbuffer);
+ return 0;
+ }
+
+ rule->pattern_re_match_data = pcre2_match_data_create_from_pattern(rule->pattern_re, NULL);
+
+ if (rule->pattern_re_match_data == NULL) {
+ ERROR("PCRE2: the memory for the block could not be obtained");
return 0;
}
}
@@ -105,8 +125,15 @@ lookup_rule(const struct cork_dllist *ru
cork_dllist_foreach_void(rules, curr, next) {
rule_t *rule = cork_container_of(curr, rule_t, entries);
- if (pcre_exec(rule->pattern_re, NULL,
- name, name_len, 0, 0, NULL, 0) >= 0)
+ if (pcre2_match(
+ rule->pattern_re, /* the compiled pattern */
+ (PCRE2_SPTR)name, /* the subject string */
+ name_len, /* the length of the subject */
+ 0, /* start at offset 0 in the subject */
+ 0, /* default options */
+ rule->pattern_re_match_data, /* block for storing the result */
+ NULL /* use default match context */
+ ) >= 0)
return rule;
}
@@ -127,7 +154,13 @@ free_rule(rule_t *rule)
return;
ss_free(rule->pattern);
- if (rule->pattern_re != NULL)
- pcre_free(rule->pattern_re);
+ if (rule->pattern_re != NULL) {
+ pcre2_code_free(rule->pattern_re); /* data and the compiled pattern. */
+ rule->pattern_re = NULL;
+ }
+ if (rule->pattern_re_match_data != NULL) {
+ pcre2_match_data_free(rule->pattern_re_match_data); /* Release memory used for the match */
+ rule->pattern_re_match_data = NULL;
+ }
ss_free(rule);
}
--- a/src/rule.h
+++ b/src/rule.h
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2011 and 2012, Dustin Lundquist <dustin@null-ptr.net>
* Copyright (c) 2011 Manuel Kasper <mk@neon1.net>
+ * Copyright (c) 2017 Syrone Wong <wong.syrone@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -33,17 +34,27 @@
#include <libcork/ds.h>
-#ifdef HAVE_PCRE_H
-#include <pcre.h>
-#elif HAVE_PCRE_PCRE_H
-#include <pcre/pcre.h>
-#endif
+/*
+ * The PCRE2_CODE_UNIT_WIDTH macro must be defined before including pcre2.h.
+ * For a program that uses only one code unit width, setting it to 8, 16, or 32
+ * makes it possible to use generic function names such as pcre2_compile(). Note
+ * that just changing 8 to 16 (for example) is not sufficient to convert this
+ * program to process 16-bit characters. Even in a fully 16-bit environment, where
+ * string-handling functions such as strcmp() and printf() work with 16-bit
+ * characters, the code for handling the table of named substrings will still need
+ * to be modified.
+ */
+/* we only need to support ASCII chartable, thus set it to 8 */
+#define PCRE2_CODE_UNIT_WIDTH 8
+
+#include <pcre2.h>
typedef struct rule {
char *pattern;
/* Runtime fields */
- pcre *pattern_re;
+ pcre2_code *pattern_re;
+ pcre2_match_data *pattern_re_match_data;
struct cork_dllist_item entries;
} rule_t;