]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
[Core] Upgrade FreeSWITCH to use PCRE2 library. Be aware of breaking changes.
authorAndrey Volk <andywolk@gmail.com>
Tue, 8 Jul 2025 18:11:25 +0000 (21:11 +0300)
committerAndrey Volk <andywolk@gmail.com>
Tue, 15 Jul 2025 15:26:17 +0000 (18:26 +0300)
40 files changed:
.github/workflows/macos.yml
Makefile.am
build/Makefile.centos5
build/Makefile.centos6
build/Makefile.openbsd
build/Makefile.solaris11
configure.ac
debian/bootstrap.sh
docker/examples/Debian11/Dockerfile
freeswitch.spec
libs/.gitignore
src/include/switch.h
src/include/switch_regex.h
src/mod/applications/mod_commands/mod_commands.c
src/mod/applications/mod_dptools/mod_dptools.c
src/mod/applications/mod_enum/mod_enum.c
src/mod/applications/mod_lcr/mod_lcr.c
src/mod/applications/mod_sms/mod_sms.c
src/mod/applications/mod_translate/mod_translate.c
src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c
src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c
src/mod/endpoints/mod_sofia/sofia_glue.c
src/mod/endpoints/mod_verto/mod_verto.c
src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c
src/mod/event_handlers/mod_event_socket/mod_event_socket.c
src/mod/languages/mod_managed/freeswitch_managed.h
src/mod/languages/mod_v8/include/fspcre.hpp
src/mod/languages/mod_v8/src/fseventhandler.cpp
src/mod/languages/mod_v8/src/fspcre.cpp
src/switch_channel.c
src/switch_ivr.c
src/switch_ivr_async.c
src/switch_ivr_menu.c
src/switch_ivr_play_say.c
src/switch_regex.c
src/switch_utils.c
tests/unit/switch_core.c
tests/unit/test_switch_core.2017.vcxproj
w32/pcre-version.props
w32/pcre.props

index a9c13d5392045900a048f7b8dc17cace9935bcfd..adb11e77a1f26fbb71c4ef0cc6a436545b9b0595 100644 (file)
@@ -40,7 +40,7 @@ jobs:
             lua \
             opus \
             ossp-uuid \
-            pcre \
+            pcre2 \
             pkgconf \
             sofia-sip \
             speex \
index 8f7679af9cf4d2d0ac277875d804d6aa318769ab..56c52d03a1186b22a0a61b197801b2d74658b1fd 100644 (file)
@@ -231,9 +231,9 @@ CORE_LIBS+=libfreeswitch_libyuv.la
 endif
 
 lib_LTLIBRARIES                 = libfreeswitch.la
-libfreeswitch_la_CFLAGS  = $(CORE_CFLAGS) $(SQLITE_CFLAGS) $(GUMBO_CFLAGS) $(FVAD_CFLAGS) $(FREETYPE_CFLAGS) $(CURL_CFLAGS) $(PCRE_CFLAGS) $(SPEEX_CFLAGS) $(LIBEDIT_CFLAGS) $(openssl_CFLAGS) $(SOFIA_SIP_CFLAGS) $(AM_CFLAGS) $(TPL_CFLAGS)
+libfreeswitch_la_CFLAGS  = $(CORE_CFLAGS) $(SQLITE_CFLAGS) $(GUMBO_CFLAGS) $(FVAD_CFLAGS) $(FREETYPE_CFLAGS) $(CURL_CFLAGS) $(PCRE2_CFLAGS) $(SPEEX_CFLAGS) $(LIBEDIT_CFLAGS) $(openssl_CFLAGS) $(SOFIA_SIP_CFLAGS) $(AM_CFLAGS) $(TPL_CFLAGS)
 libfreeswitch_la_LDFLAGS = -version-info 1:0:0 $(AM_LDFLAGS) $(PLATFORM_CORE_LDFLAGS) -no-undefined
-libfreeswitch_la_LIBADD  = $(CORE_LIBS) $(APR_LIBS) $(SQLITE_LIBS) $(GUMBO_LIBS) $(FVAD_LIBS) $(FREETYPE_LIBS) $(CURL_LIBS) $(PCRE_LIBS) $(SPEEX_LIBS) $(LIBEDIT_LIBS) $(SYSTEMD_LIBS) $(openssl_LIBS) $(PLATFORM_CORE_LIBS) $(TPL_LIBS) $(SPANDSP_LIBS) $(SOFIA_SIP_LIBS)
+libfreeswitch_la_LIBADD  = $(CORE_LIBS) $(APR_LIBS) $(SQLITE_LIBS) $(GUMBO_LIBS) $(FVAD_LIBS) $(FREETYPE_LIBS) $(CURL_LIBS) $(PCRE2_LIBS) $(SPEEX_LIBS) $(LIBEDIT_LIBS) $(SYSTEMD_LIBS) $(openssl_LIBS) $(PLATFORM_CORE_LIBS) $(TPL_LIBS) $(SPANDSP_LIBS) $(SOFIA_SIP_LIBS)
 libfreeswitch_la_DEPENDENCIES = $(BUILT_SOURCES)
 
 if HAVE_PNG
index 92dc5467a806358edb5d797d3f94d8d1324263fb..0f46d9555b2c69fe1af60e42f345981cd63f2736 100644 (file)
@@ -13,7 +13,7 @@ DOWNLOAD=http://files.freeswitch.org/downloads/libs
 JPEG=v8d
 OPENSSL=1.0.1l
 SQLITE=autoconf-3080403
-PCRE=8.35
+PCRE2=10.42
 CURL=7.40.0
 SPEEX=1.2rc1
 LIBEDIT=20140618-3.1
@@ -45,7 +45,7 @@ has-git:
        @git --version || (echo "please install git by running 'make install-git'" && false)
 
 clean:
-       @rm -rf openssl* ldns* jpeg* pcre* perl* pkg-config* speex* sqlite* libedit* curl* *~
+       @rm -rf openssl* ldns* jpeg* pcre2* perl* pkg-config* speex* sqlite* libedit* curl* *~
        (cd freeswitch.git && git clean -fdx && git reset --hard HEAD && git pull)
 
 libjpeg: jpeg-8d/.done
@@ -66,9 +66,9 @@ sqlite-$(SQLITE):
        (test -d $@) || (wget -4 -O $@.tar.gz $(DOWNLOAD)/$@.tar.gz && tar zxfv $@.tar.gz)
        (cd $@ && ./configure --prefix=$(PREFIX) && make && sudo make install && touch .done_sqlite && touch .done)
 
-pcre: pcre-$(PCRE)/.done
-pcre-$(PCRE)/.done: pcre-$(PCRE)
-pcre-$(PCRE):
+pcre2: pcre2-$(PCRE2)/.done
+pcre2-$(PCRE2)/.done: pcre2-$(PCRE2)
+pcre2-$(PCRE2):
        (test -d $@) || (wget -4 -O $@.tar.gz $(DOWNLOAD)/$@.tar.gz && tar zxfv $@.tar.gz)
        (cd $@ && ./configure --prefix=$(PREFIX) && make && sudo make install && touch .done)
 
@@ -96,4 +96,4 @@ ldns-$(LDNS):
        (test -d $@) || (wget -4 -O $@.tar.gz $(DOWNLOAD)/$@.tar.gz && tar zxfv $@.tar.gz)
        (cd $@ && ./configure --with-ssl=$(PREFIX) --prefix=$(PREFIX) && make && sudo make install && touch .done)
 
-deps: libjpeg openssl sqlite pcre curl speex libedit ldns
+deps: libjpeg openssl sqlite pcre2 curl speex libedit ldns
index 24b4ac39a63b6ce71ecfd80b2ce9b47961e2a879..ff03d124efc1f28ed5e170e3fe8b33693d5e0ee6 100644 (file)
@@ -6,8 +6,8 @@
 # in that same directory.
 #
 #
-RPMS=git gcc-c++ autoconf automake libtool wget ncurses-devel zlib-devel libjpeg-devel openssl-devel e2fsprogs-devel sqlite-devel libcurl-devel pcre-devel speex-devel ldns-devel libedit-devel
-DEBS=git build-essential automake autoconf 'libtool-bin|libtool' wget uuid-dev zlib1g-dev 'libjpeg8-dev|libjpeg62-turbo-dev' libncurses5-dev libssl-dev libpcre3-dev libcurl4-openssl-dev libldns-dev libedit-dev libspeexdsp-dev  libspeexdsp-dev libsqlite3-dev perl libgdbm-dev libdb-dev bison libvlc-dev pkg-config
+RPMS=git gcc-c++ autoconf automake libtool wget ncurses-devel zlib-devel libjpeg-devel openssl-devel e2fsprogs-devel sqlite-devel libcurl-devel pcre2-devel speex-devel ldns-devel libedit-devel
+DEBS=git build-essential automake autoconf 'libtool-bin|libtool' wget uuid-dev zlib1g-dev 'libjpeg8-dev|libjpeg62-turbo-dev' libncurses5-dev libssl-dev libpcre2-dev libcurl4-openssl-dev libldns-dev libedit-dev libspeexdsp-dev  libspeexdsp-dev libsqlite3-dev perl libgdbm-dev libdb-dev bison libvlc-dev pkg-config
 
 freeswitch: deps has-git freeswitch.git/Makefile
        cd freeswitch.git && make
index f23dff40753138d45ec8ce9e94ccefe177f017df..c2ae3cee9be7f0bcf78c377484a3b564ca3d25ac 100644 (file)
@@ -7,7 +7,7 @@
 #
 #
 
-PKG=rsync-3.1.0 git automake-1.14.1 autoconf-2.69p1 libtool gmake bzip2 jpeg wget pcre speex libldns
+PKG=rsync-3.1.0 git automake-1.14.1 autoconf-2.69p1 libtool gmake bzip2 jpeg wget pcre2 speex libldns
 PREFIX=/usr/local/freeswitch
 DOWNLOAD=http://files.freeswitch.org/downloads/libs
 OPENSSL=1.0.1j
index dd35215961bfaa3ed0ed76974d0cf03121f7f219..5c8e13b86a5ffe8b24112feb42ec3b62f1116ad5 100644 (file)
@@ -12,7 +12,7 @@ DOWNLOAD=http://files.freeswitch.org/downloads/libs
 JP=v8d
 SSL=1.0.1j
 SQLITE=autoconf-3080403
-PCRE=8.35
+PCRE2=10.42
 CURL=7.35.0
 SPEEX=1.2rc1
 LIBEDIT=20140618-3.1
@@ -43,7 +43,7 @@ has-git:
        @git --version || (echo "please install git by running 'gmake install-git'" && false)
 
 clean:
-       @rm -rf openssl* ldns* jpeg* pcre* perl* pkg-config* speex* sqlite* libedit* curl* *~
+       @rm -rf openssl* ldns* jpeg* pcre2* perl* pkg-config* speex* sqlite* libedit* curl* *~
        (cd freeswitch.git && git clean -fdx && git reset --hard HEAD && git pull)
 
 libjpeg: jpeg-8d/.done
@@ -64,9 +64,9 @@ sqlite-$(SQLITE):
        (test -d $@) || (wget -4 -O $@.tar.gz $(DOWNLOAD)/$@.tar.gz && tar zxfv $@.tar.gz)
        (cd $@ && CFLAGS=-m64 LDFLAGS=-m64 ./configure --prefix=$(PREFIX) && gmake && sudo gmake install && touch .done)
 
-pcre: pcre-$(PCRE)/.done
-pcre-$(PCRE)/.done: pcre-$(PCRE)
-pcre-$(PCRE):
+pcre2: pcre2-$(PCRE2)/.done
+pcre2-$(PCRE2)/.done: pcre2-$(PCRE2)
+pcre2-$(PCRE2):
        (test -d $@) || (wget -4 -O $@.tar.gz $(DOWNLOAD)/$@.tar.gz && tar zxfv $@.tar.gz)
        (cd $@ && CXXFLAGS=-m64 CFLAGS=-m64 LDFLAGS=-m64 ./configure --prefix=$(PREFIX) && gmake && sudo gmake install && touch .done)
 
@@ -107,4 +107,4 @@ perl-$(PERL):
        (test -d $@) || (wget -4 -O $@.tar.gz $(DOWNLOAD)/$@.tar.gz && tar zxfv $@.tar.gz)
        (cd $@ && CFLAGS=-m64 LDFLAGS=-m64 ./configure.gnu -Dcc=gcc --prefix=$(PREFIX) && gmake && sudo gmake install && touch .done)
 
-deps: has-git libjpeg openssl sqlite pcre curl speex libedit ldns pkg-config perl
+deps: has-git libjpeg openssl sqlite pcre2 curl speex libedit ldns pkg-config perl
index bd6b2892f0478843211ede8d0c3d39a0723598d9..c1c53a457467dc0b1902e4e0618081b99b93ddbd 100644 (file)
@@ -1319,7 +1319,7 @@ PKG_CHECK_MODULES([TPL], [libtpl >= 1.5],[
 
 PKG_CHECK_MODULES([SQLITE], [sqlite3 >= 3.6.20])
 PKG_CHECK_MODULES([CURL], [libcurl >= 7.19])
-PKG_CHECK_MODULES([PCRE], [libpcre >= 7.8])
+PKG_CHECK_MODULES([PCRE2], [libpcre2-8 >=  10.00])
 PKG_CHECK_MODULES([SPEEX], [speex >= 1.2rc1 speexdsp >= 1.2rc1])
 PKG_CHECK_MODULES([LDNS], [libldns-fs >= 1.6.6],[
   AM_CONDITIONAL([HAVE_LDNS],[true])],[
index adfc6bafa376d3a2168186de893c95dd2c977998..3ffe8e1a12def39a0d4be36a0318d56200a4cd66 100755 (executable)
@@ -302,7 +302,7 @@ Build-Depends:
 # core build
  dpkg-dev (>= 1.15.8.12), gcc (>= 4:4.4.5), g++ (>= 4:4.4.5),
  libc6-dev (>= 2.11.3), make (>= 3.81),
- libpcre3-dev,
+ libpcre2-dev,
  libedit-dev (>= 2.11),
  libsqlite3-dev,
  libtiff5-dev,
index 10d9302be18adfc6d0a9abbd0bde267aa1e22f02..440ba4be8f7b13a96e62d3098556af589a6967ec 100644 (file)
@@ -15,7 +15,7 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get -yq install \
 # general\r
     libssl-dev zlib1g-dev libdb-dev unixodbc-dev libncurses5-dev libexpat1-dev libgdbm-dev bison erlang-dev libtpl-dev libtiff5-dev uuid-dev \\r
 # core\r
-    libpcre3-dev libedit-dev libsqlite3-dev libcurl4-openssl-dev nasm \\r
+    libpcre2-dev libedit-dev libsqlite3-dev libcurl4-openssl-dev nasm \\r
 # core codecs\r
     libogg-dev libspeex-dev libspeexdsp-dev \\r
 # mod_enum\r
index c7e441c5ae44be306302f3908e9d5bda2685da5f..43593dd07e5249ea780322006e8e8819a6ecfe4d 100755 (executable)
@@ -133,7 +133,7 @@ BuildRequires: libtool >= 1.5.17
 BuildRequires: openssl-devel >= 1.0.1e
 BuildRequires: sofia-sip-devel >= 1.13.17
 BuildRequires: spandsp3-devel >= 3.0
-BuildRequires: pcre-devel 
+BuildRequires: pcre2-devel 
 BuildRequires: speex-devel 
 BuildRequires: sqlite-devel >= 3.6.20
 BuildRequires: libtiff-devel
@@ -147,7 +147,7 @@ BuildRequires: zlib-devel
 BuildRequires: libxml2-devel
 BuildRequires: libsndfile-devel
 Requires: curl >= 7.19
-Requires: pcre
+Requires: pcre2
 Requires: speex
 Requires: sqlite >= 3.6.20
 Requires: libtiff
index def72ad13eec001560eab45e9ff18f9596a055f3..685ce0fc723fec489c7e61ae4bd63ad293c31ab6 100644 (file)
@@ -525,7 +525,6 @@ opal
 /win32/celt/*/*/libcelt.log
 /win32/libg722_1/*/*/libg722_1.log
 /win32/libshout/*/*/libshout.log
-/win32/pcre/pcre_chartables.c
 /win32/tmp*.bat
 !/xmlrpc-c/include/xmlrpc-c/config.h.in
 /xmlrpc-c/stamp-h2
@@ -580,7 +579,6 @@ opal
 broadvoice/config/compile
 ilbc/config/compile
 libg722_1/config/compile
-pcre/compile
 srtp/build/compile
 /pcre-*/
 /speex-*/
index 68c20044c5e3a94f342255b31d0e79a4c9ba4b68..3ac11766704d06df3b07d9dc8b784099f4ff77bc 100644 (file)
  *             - APR (http://apr.apache.org)
  *             - APR-Util (http://apr.apache.org)
  *             - SQLite (http://www.sqlite.org)
- *             - Pcre (http://www.pcre.org/)
+ *             - Pcre2 (http://www.pcre.org/)
  *             - SRTP (http://srtp.sourceforge.net/srtp.html)
  *
  *     Additionally, the various external modules make use of several external modules:
index 22147c180960601402069070450f9f273102cf28..04aebf15d0ad138c31c993b6bdc5cd001bbfdcac 100644 (file)
@@ -25,7 +25,7 @@
  *
  * Michael Jerris <mike@jerris.com>
  *
- * switch_regex.h -- pcre wrapper and extensions Header
+ * switch_regex.h -- pcre2 wrapper and extensions Header
  *
  */
 /*! \file switch_regex.h
@@ -40,18 +40,23 @@ SWITCH_BEGIN_EXTERN_C
  * @ingroup FREESWITCH
  * @{
  */
-       typedef struct real_pcre switch_regex_t;
+typedef struct pcre2_real_code switch_regex_t;
+typedef struct pcre2_real_match_data_8 switch_regex_match_t;
+typedef struct pcre2_real_compile_context_8 switch_regex_compile_context_t;
 
-SWITCH_DECLARE(switch_regex_t *) switch_regex_compile(const char *pattern, int options, const char **errorptr, int *erroroffset,
-                                                                                                         const unsigned char *tables);
+SWITCH_DECLARE(switch_regex_t *) switch_regex_compile(const char *pattern, int options, int *errorcode, unsigned int *erroroffset,
+                                                                                                         switch_regex_compile_context_t *ccontext);
 
-SWITCH_DECLARE(int) switch_regex_copy_substring(const char *subject, int *ovector, int stringcount, int stringnumber, char *buffer, int size);
+SWITCH_DECLARE(int) switch_regex_copy_substring(switch_regex_match_t *match_data, int stringnumber, char *buffer, size_t *size);
 
+SWITCH_DECLARE(void) switch_regex_match_free(void *data);
 SWITCH_DECLARE(void) switch_regex_free(void *data);
 
-SWITCH_DECLARE(int) switch_regex_perform(const char *field, const char *expression, switch_regex_t **new_re, int *ovector, uint32_t olen);
-SWITCH_DECLARE(void) switch_perform_substitution(switch_regex_t *re, int match_count, const char *data, const char *field_data,
-                                                                                                char *substituted, switch_size_t len, int *ovector);
+SWITCH_DECLARE(int) switch_regex_perform(const char *field, const char *expression, switch_regex_t **new_re, switch_regex_match_t **new_match_data);
+#define switch_regex(field, expression) switch_regex_perform(field, expression, NULL, NULL)
+
+SWITCH_DECLARE(void) switch_perform_substitution(switch_regex_match_t *match_data, const char *data,
+                                                                                                char *substituted, switch_size_t len);
 
 /*!
  \brief Function to evaluate an expression against a string
@@ -70,12 +75,17 @@ SWITCH_DECLARE(switch_status_t) switch_regex_match(const char *target, const cha
 */
 SWITCH_DECLARE(switch_status_t) switch_regex_match_partial(const char *target, const char *expression, int *partial_match);
 
-SWITCH_DECLARE(void) switch_capture_regex(switch_regex_t *re, int match_count, const char *field_data,
-                                                                                 int *ovector, const char *var, switch_cap_callback_t callback, void *user_data);
+SWITCH_DECLARE(void) switch_capture_regex(switch_regex_match_t *match_data, int match_count,
+                                                                                 const char *var, switch_cap_callback_t callback, void *user_data);
 
 SWITCH_DECLARE_NONSTD(void) switch_regex_set_var_callback(const char *var, const char *val, void *user_data);
 SWITCH_DECLARE_NONSTD(void) switch_regex_set_event_header_callback(const char *var, const char *val, void *user_data);
 
+#define switch_regex_match_safe_free(match_data)       if (match_data) {\
+                               switch_regex_match_free(match_data);\
+                               match_data = NULL;\
+                       }
+
 #define switch_regex_safe_free(re)     if (re) {\
                                switch_regex_free(re);\
                                re = NULL;\
index 5b9620a7812af6ee8caf4b77e427b53b09b6d5e8..970fa356bee467f08680ad7f03e2ba8f81fc195a 100644 (file)
@@ -2014,7 +2014,7 @@ SWITCH_STANDARD_API(replace_function)
 SWITCH_STANDARD_API(regex_function)
 {
        switch_regex_t *re = NULL;
-       int ovector[30];
+       switch_regex_match_t *match_data = NULL;
        int argc;
        char *mydata = NULL, *argv[4];
        size_t len = 0;
@@ -2054,7 +2054,7 @@ SWITCH_STANDARD_API(regex_function)
                goto error;
        }
 
-       proceed = switch_regex_perform(argv[0], argv[1], &re, ovector, sizeof(ovector) / sizeof(ovector[0]));
+       proceed = switch_regex_perform(argv[0], argv[1], &re, &match_data);
 
        if (argc > 2) {
                char *flags = "";
@@ -2069,7 +2069,7 @@ SWITCH_STANDARD_API(regex_function)
                        switch_assert(substituted);
                        memset(substituted, 0, len);
                        switch_replace_char(argv[2], '%', '$', SWITCH_FALSE);
-                       switch_perform_substitution(re, proceed, argv[2], argv[0], substituted, len, ovector);
+                       switch_perform_substitution(match_data, argv[2], substituted, len);
 
                        stream->write_function(stream, "%s", substituted);
                        free(substituted);
@@ -2091,6 +2091,7 @@ SWITCH_STANDARD_API(regex_function)
   error:
        stream->write_function(stream, "-ERR");
   ok:
+       switch_regex_match_safe_free(match_data);
        switch_regex_safe_free(re);
        switch_safe_free(mydata);
        return SWITCH_STATUS_SUCCESS;
index d134576fb99f666eb5cb2f12c4406119a2a089d1..23fd2125ef71bbd1f9ee47f381230621c15e344b 100644 (file)
@@ -3211,15 +3211,17 @@ SWITCH_STANDARD_APP(capture_function)
 {
        char *argv[3] = { 0 };
        switch_regex_t *re = NULL;
-       int ovector[30] = {0};
+       switch_regex_match_t *match_data = NULL;
        char *lbuf;
        int proceed;
 
        if (!zstr(data) && (lbuf = switch_core_session_strdup(session, data))
                && switch_separate_string(lbuf, '|', argv, (sizeof(argv) / sizeof(argv[0]))) == 3) {
-               if ((proceed = switch_regex_perform(argv[1], argv[2], &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
-                       switch_capture_regex(re, proceed, argv[1], ovector, argv[0], switch_regex_set_var_callback, session);
+               if ((proceed = switch_regex_perform(argv[1], argv[2], &re, &match_data))) {
+                       switch_capture_regex(match_data, proceed, argv[0], switch_regex_set_var_callback, session);
                }
+
+               switch_regex_match_safe_free(match_data);
                switch_regex_safe_free(re);
        } else {
                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No data specified.\n");
index aa87f24826348346ebb1eb333b9401fb1d332e01..3a6efbaa8dfc42fc3fe307d620a266d3ce7b89b8 100644 (file)
@@ -365,7 +365,8 @@ static void parse_naptr(const ldns_rr *naptr, const char *number, enum_record_t
 
        if (service && regex && replace) {
                switch_regex_t *re = NULL, *re2 = NULL;
-               int proceed = 0, ovector[30];
+               switch_regex_match_t *match_data = NULL, *match_data2 = NULL;
+               int proceed = 0;
                char *substituted = NULL;
                char *substituted_2 = NULL;
                char *orig_uri;
@@ -374,17 +375,18 @@ static void parse_naptr(const ldns_rr *naptr, const char *number, enum_record_t
                int supported = 0;
                uint32_t len = 0;
 
-               if ((proceed = switch_regex_perform(number, regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
+               if ((proceed = switch_regex_perform(number, regex, &re, &match_data))) {
                        if (strchr(regex, '(')) {
                                len = (uint32_t) (strlen(number) + strlen(replace) + 10) * proceed;
                                if (!(substituted = malloc(len))) {
                                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
+                                       switch_regex_match_safe_free(match_data);
                                        switch_regex_safe_free(re);
                                        goto end;
                                }
                                memset(substituted, 0, len);
 
-                               switch_perform_substitution(re, proceed, replace, number, substituted, len, ovector);
+                               switch_perform_substitution(match_data, replace, substituted, len);
                                orig_uri = substituted;
                        } else {
                                orig_uri = replace;
@@ -398,7 +400,7 @@ static void parse_naptr(const ldns_rr *naptr, const char *number, enum_record_t
                                        continue;
                                }
 
-                               if ((proceed = switch_regex_perform(uri, route->regex, &re2, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
+                               if ((proceed = switch_regex_perform(uri, route->regex, &re2, &match_data2))) {
                                        switch_event_t *event = NULL;
 
                                        if (strchr(route->regex, '(')) {
@@ -406,6 +408,8 @@ static void parse_naptr(const ldns_rr *naptr, const char *number, enum_record_t
                                                if (!(substituted_2 = malloc(len))) {
                                                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
                                                        switch_safe_free(substituted);
+                                                       switch_regex_match_safe_free(match_data);
+                                                       switch_regex_match_safe_free(match_data2);
                                                        switch_regex_safe_free(re);
                                                        switch_regex_safe_free(re2);
                                                        switch_mutex_unlock(MUTEX);
@@ -413,7 +417,7 @@ static void parse_naptr(const ldns_rr *naptr, const char *number, enum_record_t
                                                }
                                                memset(substituted_2, 0, len);
 
-                                               switch_perform_substitution(re2, proceed, route->replace, uri, substituted_2, len, ovector);
+                                               switch_perform_substitution(match_data2, route->replace, substituted_2, len);
                                                uri = substituted_2;
                                        } else {
                                                uri = route->replace;
@@ -434,6 +438,7 @@ static void parse_naptr(const ldns_rr *naptr, const char *number, enum_record_t
                                }
                                switch_safe_free(uri_expanded);
                                switch_safe_free(substituted_2);
+                               switch_regex_match_safe_free(match_data2);
                                switch_regex_safe_free(re2);
                        }
                        switch_mutex_unlock(MUTEX);
@@ -443,6 +448,7 @@ static void parse_naptr(const ldns_rr *naptr, const char *number, enum_record_t
                        }
 
                        switch_safe_free(substituted);
+                       switch_regex_match_safe_free(match_data);
                        switch_regex_safe_free(re);
                }
        }
index ab7c163ce5a698c22fba75ad239c0d8ea9b7e6ce..3525d46b35b933a58431264c57d9411087194914 100644 (file)
@@ -166,7 +166,8 @@ static void lcr_destroy(lcr_route route)
 static const char *do_cid(switch_memory_pool_t *pool, const char *cid, const char *number, switch_core_session_t *session)
 {
        switch_regex_t *re = NULL;
-       int proceed = 0, ovector[30];
+       switch_regex_match_t *match_data = NULL;
+       int proceed = 0;
        char *substituted = NULL;
        uint32_t len = 0;
        char *src = NULL;
@@ -230,23 +231,25 @@ static const char *do_cid(switch_memory_pool_t *pool, const char *cid, const cha
                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "expanded src: %s, dst: %s\n", src, dst);
        }
 
-       if ((proceed = switch_regex_perform(number, src, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
+       if ((proceed = switch_regex_perform(number, src, &re, &match_data))) {
                len = (uint32_t) (strlen(src) + strlen(dst) + 10) * proceed; /* guestimate size */
                if (!(substituted = switch_core_alloc(pool, len))) {
                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Memory Error!\n");
                        goto done;
                }
                memset(substituted, 0, len);
-               switch_perform_substitution(re, proceed, dst, number, substituted, len, ovector);
+               switch_perform_substitution(match_data, dst, substituted, len);
        } else {
                goto done;
        }
 
+       switch_regex_match_safe_free(match_data);
        switch_regex_safe_free(re);
 
        return substituted;
 
 done:
+       switch_regex_match_safe_free(match_data);
        switch_regex_safe_free(re);
        switch_safe_free(tmp_regex);
        return number;
index 68ad7d7cccacdf2d2f57e5eda62b899f60c20765..537530879470762ba973a7751103f90b69f4150d 100644 (file)
@@ -124,6 +124,7 @@ static int parse_exten(switch_event_t *event, switch_xml_t xexten, switch_event_
        int proceed = 0;
        char *expression_expanded = NULL, *field_expanded = NULL;
        switch_regex_t *re = NULL;
+       switch_regex_match_t *match_data = NULL;
        const char *to = switch_event_get_header(event, "to");
        const char *tzoff = NULL, *tzname_ = NULL;
        int offset = 0;
@@ -143,7 +144,6 @@ static int parse_exten(switch_event_t *event, switch_xml_t xexten, switch_event_
                char *do_break_a = NULL;
                char *expression = NULL;
                const char *field_data = NULL;
-               int ovector[30];
                switch_bool_t anti_action = SWITCH_TRUE;
                break_t do_break_i = BREAK_ON_FALSE;
                int time_match;
@@ -214,7 +214,7 @@ static int parse_exten(switch_event_t *event, switch_xml_t xexten, switch_event_
                                field_data = "";
                        }
 
-                       if ((proceed = switch_regex_perform(field_data, expression, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
+                       if ((proceed = switch_regex_perform(field_data, expression, &re, &match_data))) {
                                switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG,
                                                                  "Chatplan: %s Regex (PASS) [%s] %s(%s) =~ /%s/ break=%s\n",
                                                                  to, exten_name, field, field_data, expression, do_break_a ? do_break_a : "on-false");
@@ -271,7 +271,7 @@ static int parse_exten(switch_event_t *event, switch_xml_t xexten, switch_event_
                } else {
                        if (field && strchr(expression, '(')) {
                                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "DP_MATCH", NULL);
-                               switch_capture_regex(re, proceed, field_data, ovector, "DP_MATCH", switch_regex_set_event_header_callback, event);
+                               switch_capture_regex(match_data, proceed, "DP_MATCH", switch_regex_set_event_header_callback, event);
                        }
 
                        for (xaction = switch_xml_child(xcond, "action"); xaction; xaction = xaction->next) {
@@ -297,7 +297,7 @@ static int parse_exten(switch_event_t *event, switch_xml_t xexten, switch_event_
                                                abort();
                                        }
                                        memset(substituted, 0, len);
-                                       switch_perform_substitution(re, proceed, data, field_data, substituted, len, ovector);
+                                       switch_perform_substitution(match_data, data, substituted, len);
                                        app_data = substituted;
                                } else {
                                        app_data = data;
@@ -326,6 +326,8 @@ static int parse_exten(switch_event_t *event, switch_xml_t xexten, switch_event_
                                switch_safe_free(substituted);
                        }
                }
+
+               switch_regex_match_safe_free(match_data);
                switch_regex_safe_free(re);
 
                if (((anti_action == SWITCH_FALSE && do_break_i == BREAK_ON_TRUE) ||
@@ -335,6 +337,7 @@ static int parse_exten(switch_event_t *event, switch_xml_t xexten, switch_event_
        }
 
   done:
+       switch_regex_match_safe_free(match_data);
        switch_regex_safe_free(re);
        switch_safe_free(field_expanded);
        switch_safe_free(expression_expanded);
index 34b1ad54fc9f9d973c64d884c69a8fed6b77b91b..cc31b1f8ea32324f8f1a5f4052bacf2f88621554 100644 (file)
@@ -117,7 +117,8 @@ static void translate_number(char *number, char *profile, char **translated, swi
        translate_rule_t *hi = NULL;
        translate_rule_t *rule = NULL;
        switch_regex_t *re = NULL;
-       int proceed = 0, ovector[30];
+       switch_regex_match_t *match_data = NULL;
+       int proceed = 0;
        char *substituted = NULL, *subbed = NULL;
        uint32_t len = 0;
 
@@ -136,17 +137,18 @@ static void translate_number(char *number, char *profile, char **translated, swi
 
        for (rule = hi; rule; rule = rule->next) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s =~ /%s/\n", number, rule->regex);
-               if ((proceed = switch_regex_perform(number, rule->regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
+               if ((proceed = switch_regex_perform(number, rule->regex, &re, &match_data))) {
                        len = (uint32_t) (strlen(number) + strlen(rule->replace) + 10) * proceed;
                        if (!(substituted = malloc(len))) {
                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
+                               switch_regex_match_safe_free(match_data);
                                switch_regex_safe_free(re);
                                goto end;
                        }
 
                        memset(substituted, 0, len);
 
-                       switch_perform_substitution(re, proceed, rule->replace, number, substituted, len, ovector);
+                       switch_perform_substitution(match_data, rule->replace, substituted, len);
 
                        if ((switch_string_var_check_const(substituted) || switch_string_has_escaped_data(substituted))) {
                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "perform variable expansion\n");
@@ -169,6 +171,7 @@ static void translate_number(char *number, char *profile, char **translated, swi
                                switch_safe_free(subbed);
                        }
 
+                       switch_regex_match_safe_free(match_data);
                        switch_regex_safe_free(re);
                        break;
                }
index 652d292e65538ae54cd7b7de339cdeef006db767..f51f78d354b4e599f17f1a90edc1aba54dc0151e 100644 (file)
@@ -170,9 +170,8 @@ SWITCH_STANDARD_DIALPLAN(asterisk_dialplan_hunt)
                                char *expression = NULL, expression_buf[1024] = { 0 };
                                char substituted[2048] = "";
                                const char *field_data = caller_profile->destination_number;
-                               int proceed = 0;
                                switch_regex_t *re = NULL;
-                               int ovector[30] = { 0 };
+                               switch_regex_match_t *match_data = NULL;
                                char *cid = NULL;
 
                                expression = expression_buf;
@@ -221,7 +220,8 @@ SWITCH_STANDARD_DIALPLAN(asterisk_dialplan_hunt)
                                                field_data = "";
                                        }
 
-                                       if (!(proceed = switch_regex_perform(field_data, expression, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
+                                       if (!(switch_regex_perform(field_data, expression, &re, &match_data))) {
+                                               switch_regex_match_safe_free(match_data);
                                                switch_regex_safe_free(re);
                                                switch_safe_free(field_expanded);
                                                continue;
@@ -267,10 +267,11 @@ SWITCH_STANDARD_DIALPLAN(asterisk_dialplan_hunt)
                                }
 
                                if (strchr(expression, '(')) {
-                                       switch_perform_substitution(re, proceed, argument, field_data, substituted, sizeof(substituted), ovector);
+                                       switch_perform_substitution(match_data, argument, substituted, sizeof(substituted));
                                        argument = substituted;
                                }
 
+                               switch_regex_match_safe_free(match_data);
                                switch_regex_safe_free(re);
 
                                if (!extension) {
index f85a9855bb138754ac1f7196813ed93b3b1d36f7..3d3fdfd8a93ccf9380d3991287fdef54cf3c9966 100644 (file)
@@ -103,6 +103,7 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
        int proceed = 0, save_proceed = 0;
        char *expression_expanded = NULL, *field_expanded = NULL;
        switch_regex_t *re = NULL, *save_re = NULL;
+       switch_regex_match_t *match_data = NULL, *save_match_data = NULL;
        int offset = 0;
        const char *tmp, *tzoff = NULL, *tzname_ = NULL, *req_nesta = NULL;
        char nbuf[128] = "";
@@ -170,7 +171,6 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
                char *expression = NULL, *save_expression = NULL, *save_field_data = NULL;
                char *regex_rule = NULL;
                const char *field_data = NULL;
-               int ovector[30];
                switch_bool_t anti_action = SWITCH_TRUE;
                break_t do_break_i = BREAK_ON_FALSE;
                int time_match;
@@ -292,7 +292,7 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
                                                field_data = "";
                                        }
 
-                                       if ((proceed = switch_regex_perform(field_data, expression, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
+                                       if ((proceed = switch_regex_perform(field_data, expression, &re, &match_data))) {
                                                if ( switch_core_test_flag(SCF_DIALPLAN_TIMESTAMPS) ) {
                                                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
                                                                                  "%sDialplan: %s Regex (PASS) [%s] %s(%s) =~ /%s/ match=%s\n", space,
@@ -344,20 +344,23 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
                                        switch_snprintf(var, sizeof(var), "DP_REGEX_MATCH_%d", total);
 
                                        switch_channel_set_variable(channel, var, NULL);
-                                       switch_capture_regex(re, proceed, field_data, ovector, var, switch_regex_set_var_callback, session);
+                                       switch_capture_regex(match_data, proceed, var, switch_regex_set_var_callback, session);
 
                                        switch_safe_free(save_expression);
                                        switch_safe_free(save_field_data);
+                                       switch_regex_match_safe_free(match_data);
                                        switch_regex_safe_free(save_re);
 
                                        save_expression = strdup(expression);
                                        save_field_data = strdup(field_data);
                                        save_re = re;
+                                       save_match_data = match_data;
                                        save_proceed = proceed;
 
                                        re = NULL;
                                }
 
+                               switch_regex_match_safe_free(match_data);
                                switch_regex_safe_free(re);
 
                                switch_safe_free(field_expanded);
@@ -406,7 +409,7 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
                                        field_data = "";
                                }
 
-                               if ((proceed = switch_regex_perform(field_data, expression, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
+                               if ((proceed = switch_regex_perform(field_data, expression, &re, &match_data))) {
                                        if ( switch_core_test_flag(SCF_DIALPLAN_TIMESTAMPS) ) {
                                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
                                                                          "%sDialplan: %s Regex (PASS) [%s] %s(%s) =~ /%s/ break=%s\n", space,
@@ -446,7 +449,9 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
 
                if (save_re) {
                        re = save_re;
+                       match_data = save_match_data;
                        save_re = NULL;
+                       save_match_data = NULL;
 
                        expression = expression_expanded = save_expression;
                        save_expression = NULL;
@@ -506,7 +511,7 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
                } else {
                        if (field && expression && strchr(expression, '(')) {
                                switch_channel_set_variable(channel, "DP_MATCH", NULL);
-                               switch_capture_regex(re, proceed, field_data, ovector, "DP_MATCH", switch_regex_set_var_callback, session);
+                               switch_capture_regex(match_data, proceed, "DP_MATCH", switch_regex_set_var_callback, session);
                        }
 
                        for (xaction = switch_xml_child(xcond, "action"); xaction; xaction = xaction->next) {
@@ -534,7 +539,7 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
                                                goto done;
                                        }
                                        memset(substituted, 0, len);
-                                       switch_perform_substitution(re, proceed, data, field_data, substituted, len, ovector);
+                                       switch_perform_substitution(match_data, data, substituted, len);
                                        app_data = substituted;
                                } else {
                                        app_data = data;
@@ -571,6 +576,8 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
                                switch_safe_free(substituted);
                        }
                }
+
+               switch_regex_match_safe_free(match_data);
                switch_regex_safe_free(re);
 
                if (((anti_action == SWITCH_FALSE && do_break_i == BREAK_ON_TRUE) ||
@@ -591,6 +598,7 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *
        }
 
   done:
+       switch_regex_match_safe_free(match_data);
        switch_regex_safe_free(re);
        switch_safe_free(field_expanded);
        switch_safe_free(expression_expanded);
index 1452a7cf0fc3f2b8230cf30e8cb6a0b7a927f2fb..33904aaac462ce3e8663cba65423d2252cf06321 100644 (file)
@@ -911,8 +911,6 @@ char *sofia_glue_get_extra_headers(switch_channel_t *channel, const char *prefix
        switch_stream_handle_t stream = { 0 };
        switch_event_header_t *hi = NULL;
        const char *exclude_regex = NULL;
-       switch_regex_t *re = NULL;
-       int ovector[30] = {0};
 
        exclude_regex = switch_channel_get_variable(channel, "exclude_outgoing_extra_header");
        SWITCH_STANDARD_STREAM(stream);
@@ -926,12 +924,11 @@ char *sofia_glue_get_extra_headers(switch_channel_t *channel, const char *prefix
                        }
 
                        if (!strncasecmp(name, prefix, strlen(prefix))) {
-                               if ( !exclude_regex || !(/*proceed*/ switch_regex_perform(name, exclude_regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
+                               if ( !exclude_regex || !(/*proceed*/ switch_regex(name, exclude_regex))) {
                                        const char *hname = name + strlen(prefix);
                                        stream.write_function(&stream, "%s: %s\r\n", hname, value);
                                } else {
                                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Ignoring Extra Header [%s] , matches exclude_outgoing_extra_header [%s]\n", name, exclude_regex);
-                                       switch_regex_safe_free(re);
                                }
                        }
                }
index c91b39610631dc149b150a41d41035854f542747..40bb51171ab8fbf9e5c755a913622c3b88b27d25 100644 (file)
@@ -1882,23 +1882,19 @@ authed:
 
        if (vhost->rewrites) {
                switch_event_header_t *rule = vhost->rewrites->headers;
-               switch_regex_t *re = NULL;
-               int ovector[30];
                int proceed;
 
                while(rule) {
                        char *expression = rule->name;
 
-                       if ((proceed = switch_regex_perform(request->uri, expression, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
+                       if ((proceed = switch_regex(request->uri, expression))) {
                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
                                                                  "%d request [%s] matched expr [%s]\n", proceed, request->uri, expression);
                                request->uri = rule->value;
-                               switch_regex_safe_free(re);
                                break;
                        }
 
                        rule = rule->next;
-                       switch_regex_safe_free(re);
                }
        }
 
index bd7bf8e26c0354f6c4d2888dfc9d727c9c9d2782..f163b2197f09f24a969bbbc315516808d93c407c 100644 (file)
@@ -249,10 +249,7 @@ static void event_handler(switch_event_t *event)
                                                }
 
                                                if (*hp->value == '/') {
-                                                       switch_regex_t *re = NULL;
-                                                       int ovector[30];
-                                                       cmp = !!switch_regex_perform(hval, comp_to, &re, ovector, sizeof(ovector) / sizeof(ovector[0]));
-                                                       switch_regex_safe_free(re);
+                                                       cmp = !!switch_regex(hval, comp_to);
                                                } else {
                                                        cmp = !strcasecmp(hval, comp_to);
                                                }
index 935f726ee15072dc051f7cc6b0b75d1faecc7dac..1c35b6f0493049defa199f3dcd53a3342b1359f5 100644 (file)
@@ -349,10 +349,7 @@ static void event_handler(switch_event_t *event)
                                                }
 
                                                if (*hp->value == '/') {
-                                                       switch_regex_t *re = NULL;
-                                                       int ovector[30];
-                                                       cmp = !!switch_regex_perform(hval, comp_to, &re, ovector, sizeof(ovector) / sizeof(ovector[0]));
-                                                       switch_regex_safe_free(re);
+                                                       cmp = !!switch_regex(hval, comp_to);
                                                } else {
                                                        cmp = !strcasecmp(hval, comp_to);
                                                }
index aac135d629cdeaf4581ed7f7870028e1f3cd2a2e..f2949710a8652c3578b85226290637a908d23cc8 100644 (file)
@@ -135,7 +135,13 @@ struct sqlite3 {
 struct switch_ivr_digit_stream {
        char foo[];
 };
-struct real_pcre {
+struct real_pcre2 {
+       char foo[];
+};
+struct pcre2_real_match_data_8 {
+       char foo[];
+};
+struct pcre2_real_compile_context_8 {
        char foo[];
 };
 struct HashElem {
index da1a3bbe2d78dbadb419ded4f1b7db1066a6baef..5bbed2e848a7f67bb1ad6965a201ba35bc2a7191 100644 (file)
@@ -46,9 +46,9 @@ class FSPCRE : public JSBase
 {
 private:
        switch_regex_t *_re;
+       switch_regex_match_t *_match_data;
        char *_str;
        int _proceed;
-       int _ovector[30];
        int _freed;
 
        void Init();
index 145984c83fdcec7b87cd817e3826006c77e09998..8e69d9b842b81fbe01f1f6e04b17518f1e9b98da 100644 (file)
@@ -138,10 +138,7 @@ void FSEventHandler::QueueEvent(switch_event_t *event)
                                        }
 
                                        if (*hp->value == '/') {
-                                               switch_regex_t *re = NULL;
-                                               int ovector[30];
-                                               cmp = !!switch_regex_perform(hval, comp_to, &re, ovector, sizeof(ovector) / sizeof(ovector[0]));
-                                               switch_regex_safe_free(re);
+                                               cmp = !!switch_regex(hval, comp_to);
                                        } else {
                                                cmp = !strcasecmp(hval, comp_to);
                                        }
index 1b1b97e2a77ea04f4726060aab4906ea1a31f7e3..e76cbcbcaa74dfed6a4503edf4913969042682df 100644 (file)
@@ -40,6 +40,7 @@ static const char js_class_name[] = "PCRE";
 FSPCRE::~FSPCRE(void)
 {
        if (!_freed && _re) {
+               switch_regex_match_safe_free(_match_data);
                switch_regex_safe_free(_re);
                switch_safe_free(_str);
        }
@@ -53,9 +54,9 @@ string FSPCRE::GetJSClassName()
 void FSPCRE::Init()
 {
        _re = NULL;
+       _match_data = NULL;
        _str = NULL;
        _proceed = 0;
-       memset(&_ovector, 0, sizeof(_ovector));
        _freed = 0;
 }
 
@@ -74,11 +75,11 @@ JS_PCRE_FUNCTION_IMPL(Compile)
                String::Utf8Value str2(info[1]);
                string = js_safe_str(*str1);
                regex_string = js_safe_str(*str2);
+               switch_regex_match_safe_free(this->_match_data);
                switch_regex_safe_free(this->_re);
                switch_safe_free(this->_str);
                js_strdup(this->_str, string);
-               this->_proceed = switch_regex_perform(this->_str, regex_string, &this->_re, this->_ovector,
-                                                                                                sizeof(this->_ovector) / sizeof(this->_ovector[0]));
+               this->_proceed = switch_regex_perform(this->_str, regex_string, &this->_re, &this->_match_data);
                info.GetReturnValue().Set(this->_proceed ? true : false);
        } else {
                info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid args"));
@@ -103,7 +104,7 @@ JS_PCRE_FUNCTION_IMPL(Substitute)
                len = (uint32_t) (strlen(this->_str) + strlen(subst_string) + 10) * this->_proceed;
                substituted = (char *)malloc(len);
                switch_assert(substituted != NULL);
-               switch_perform_substitution(this->_re, this->_proceed, subst_string, this->_str, substituted, len, this->_ovector);
+               switch_perform_substitution(this->_match_data, subst_string, substituted, len);
                info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), substituted));
                free(substituted);
        } else {
index 66e18a323c20179fb41f5c9f977c3711bea607eb..d360c8a951781d7b5153f1c65f90311a03f94d14 100644 (file)
@@ -33,7 +33,8 @@
 
 #include <switch.h>
 #include <switch_channel.h>
-#include <pcre.h>
+#define PCRE2_CODE_UNIT_WIDTH 8
+#include <pcre2.h>
 
 struct switch_cause_table {
        const char *name;
@@ -4549,21 +4550,22 @@ SWITCH_DECLARE(switch_status_t) switch_channel_set_timestamps(switch_channel_t *
                char *digit_string = dtstr;
                char *X = NULL;
                switch_regex_t *re = NULL;
+               switch_regex_match_t *match_data = NULL;
                char *substituted = NULL;
 
                if (!zstr(var)) {
                        int proceed = 0;
-                       int ovector[30];
 
-                       if ((proceed = switch_regex_perform(dtstr, var, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
+                       if ((proceed = switch_regex_perform(dtstr, var, &re, &match_data))) {
                                int len = (strlen(dtstr) + strlen(var) + 10) * proceed;
                                int i = 0;
                                const char *replace = NULL;
+                               PCRE2_SIZE replace_size;
 
                                X = malloc(len);
 
                                for (i = 0; i < proceed; i++) {
-                                       if (pcre_get_substring(dtstr, ovector, proceed, i, &replace) >= 0) {
+                                       if (pcre2_substring_get_bynumber(match_data, i, (PCRE2_UCHAR **)&replace, &replace_size) >= 0) {
                                                if (replace) {
                                                        switch_size_t plen = strlen(replace);
                                                        memset(X, 'X', plen);
@@ -4572,7 +4574,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_set_timestamps(switch_channel_t *
                                                        switch_safe_free(substituted);
                                                        substituted = switch_string_replace(substituted ? substituted : dtstr, replace, X);
                                                        
-                                                       pcre_free_substring(replace);
+                                                       pcre2_substring_free((PCRE2_UCHAR *)replace);
                                                }
                                        }
                                }
@@ -4584,6 +4586,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_set_timestamps(switch_channel_t *
                }
 
                switch_channel_set_variable(channel, "digits_dialed", digit_string);
+               switch_regex_match_safe_free(match_data);
                switch_regex_safe_free(re);
                switch_safe_free(substituted);
                switch_safe_free(X);
index 1443f989cfaeb2d7bed5c9f44c28d8654019221b..098f7a843145d72c265f8a906552949f2d2ffc5d 100644 (file)
@@ -4343,8 +4343,6 @@ SWITCH_DECLARE(char *) switch_ivr_check_presence_mapping(const char *exten_name,
        switch_xml_t cfg, xml, x_domains, x_domain, x_exten;
        char *r = NULL;
        switch_event_t *params = NULL;
-       switch_regex_t *re = NULL;
-       int proceed = 0, ovector[100];
 
        switch_event_create(&params, SWITCH_EVENT_REQUEST_PARAMS);
        switch_assert(params);
@@ -4375,17 +4373,11 @@ SWITCH_DECLARE(char *) switch_ivr_check_presence_mapping(const char *exten_name,
                        const char *regex = switch_xml_attr(x_exten, "regex");
                        const char *proto = switch_xml_attr(x_exten, "proto");
 
-                       if (!zstr(regex) && !zstr(proto)) {
-                               proceed = switch_regex_perform(exten_name, regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0]));
-                               switch_regex_safe_free(re);
-
-                               if (proceed) {
-                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Mapping %s@%s to proto %s matching expression [%s]\n",
-                                                                         exten_name, domain_name, proto, regex);
-                                       r = strdup(proto);
-                                       goto end;
-                               }
-
+                       if (!zstr(regex) && !zstr(proto) && switch_regex(exten_name, regex)) {
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Mapping %s@%s to proto %s matching expression [%s]\n",
+                                                                 exten_name, domain_name, proto, regex);
+                               r = strdup(proto);
+                               goto end;
                        }
                }
        }
index 4075f0adce489ddd0e6ce9c5031b04865c376117..ba80ea15f44f2ea617f05991ee19bee34d99079a 100644 (file)
@@ -370,12 +370,11 @@ static dm_match_t switch_ivr_dmachine_check_match(switch_ivr_dmachine_t *dmachin
        for(bp = dmachine->realm->binding_list; bp; bp = bp->next) {
                if (bp->is_regex) {
                        if (bp->repl) {
-                               int ovector[30] = { 0 };
                                int proceed = 0;
                                switch_regex_t *re = NULL;
-
+                               switch_regex_match_t *match_data = NULL;
                                
-                               proceed = switch_regex_perform(dmachine->digits, bp->digits, &re, ovector, sizeof(ovector) / sizeof(ovector[0]));
+                               proceed = switch_regex_perform(dmachine->digits, bp->digits, &re, &match_data);
                                
                                if (proceed) {
                                        char *substituted = NULL;
@@ -385,12 +384,14 @@ static dm_match_t switch_ivr_dmachine_check_match(switch_ivr_dmachine_t *dmachin
                                        substituted = malloc(len);
                                        switch_assert(substituted);
                                        memset(substituted, 0, len);
-                                       switch_perform_substitution(re, proceed, bp->repl, dmachine->digits, substituted, len, ovector);
+                                       switch_perform_substitution(match_data, bp->repl, substituted, len);
 
                                        if (!bp->substituted || strcmp(substituted, bp->substituted)) {
                                                bp->substituted = switch_core_strdup(dmachine->pool, substituted);
                                        }
+
                                        free(substituted);
+                                       switch_regex_match_safe_free(match_data);
                                        switch_regex_safe_free(re);
                                        bp->rmatch = 1;
                                } else {
index 255c9a4f127cd46df961d2efb30f0b6b256684d8..39fc5394753c01c7eb2765a02a0bed6926bbca0d 100644 (file)
@@ -553,14 +553,15 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_menu_execute(switch_core_session_t *s
 
                                if (ap->re) {
                                        switch_regex_t *re = NULL;
-                                       int ovector[30];
+                                       switch_regex_match_t *match_data = NULL;
 
-                                       if ((ok = switch_regex_perform(menu->buf, ap->bind, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
-                                               switch_perform_substitution(re, ok, ap->arg, menu->buf, substituted, sizeof(substituted), ovector);
+                                       if ((ok = switch_regex_perform(menu->buf, ap->bind, &re, &match_data))) {
+                                               switch_perform_substitution(match_data, ap->arg, substituted, sizeof(substituted));
                                                use_arg = substituted;
                                        }
                                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "action regex [%s] [%s] [%d]\n", menu->buf, ap->bind, ok);
 
+                                       switch_regex_match_safe_free(match_data);
                                        switch_regex_safe_free(re);
                                } else {
                                        ok = !strcmp(menu->buf, ap->bind);
index 2ac77be19dbe9771317c172833851503cc7bffaf..1970364b7ff9ffad62fb65dee16d48e50431862b 100644 (file)
@@ -178,7 +178,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro_event(switch_core_sessio
                char *field_expanded = NULL;
                char *field_expanded_alloc = NULL;
                switch_regex_t *re = NULL;
-               int proceed = 0, ovector[100];
+               switch_regex_match_t *match_data = NULL;
+               int proceed = 0;
                switch_xml_t match = NULL;
 
                searched = 1;
@@ -204,7 +205,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro_event(switch_core_sessio
 
                status = SWITCH_STATUS_SUCCESS;
 
-               if ((proceed = switch_regex_perform(field_expanded, pattern, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
+               if ((proceed = switch_regex_perform(field_expanded, pattern, &re, &match_data))) {
                        match = switch_xml_child(input, "match");
                } else {
                        match = switch_xml_child(input, "nomatch");
@@ -224,12 +225,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro_event(switch_core_sessio
                                        len = (uint32_t) (strlen(data) + strlen(adata) + 10) * proceed;
                                        if (!(substituted = malloc(len))) {
                                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Memory Error!\n");
+                                               switch_regex_match_safe_free(match_data);
                                                switch_regex_safe_free(re);
                                                switch_safe_free(field_expanded_alloc);
                                                goto done;
                                        }
                                        memset(substituted, 0, len);
-                                       switch_perform_substitution(re, proceed, adata, field_expanded, substituted, len, ovector);
+                                       switch_perform_substitution(match_data, adata, substituted, len);
                                        odata = substituted;
                                } else {
                                        odata = adata;
@@ -326,6 +328,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro_event(switch_core_sessio
                        }
                }
 
+               switch_regex_match_safe_free(match_data);
                switch_regex_safe_free(re);
                switch_safe_free(field_expanded_alloc);
 
index 21e54b29fef86e7bf85a75c7fec72f2419aba6be..39fcd34a6e78724a09ad65cada073b72d71dad77 100644 (file)
  * Contributor(s):
  *
  * Michael Jerris <mike@jerris.com>
+ * Christian Marangi <ansuelsmth@gmail.com> # PCRE2 conversion
  *
  *
- * switch_regex.c -- PCRE wrapper
+ * switch_regex.c -- PCRE2 wrapper
  *
  */
 
 #include <switch.h>
-#include <pcre.h>
+#define PCRE2_CODE_UNIT_WIDTH 8
+#include <pcre2.h>
 
 SWITCH_DECLARE(switch_regex_t *) switch_regex_compile(const char *pattern,
-                                                                                                         int options, const char **errorptr, int *erroroffset, const unsigned char *tables)
+                                                                                                         int options, int *errorcode, unsigned int *erroroffset, switch_regex_compile_context_t *ccontext)
 {
 
-       return (switch_regex_t *)pcre_compile(pattern, options, errorptr, erroroffset, tables);
+       return (switch_regex_t *)pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, options, errorcode, (PCRE2_SIZE *)erroroffset, ccontext);
+}
 
+SWITCH_DECLARE(int) switch_regex_copy_substring(switch_regex_match_t *match_data, int stringnumber, char *buffer, size_t *size)
+{
+       return pcre2_substring_copy_bynumber(match_data, stringnumber, (PCRE2_UCHAR *)buffer, (PCRE2_SIZE *)size);
 }
 
-SWITCH_DECLARE(int) switch_regex_copy_substring(const char *subject, int *ovector, int stringcount, int stringnumber, char *buffer, int size)
+SWITCH_DECLARE(void) switch_regex_match_free(void *data)
 {
-       return pcre_copy_substring(subject, ovector, stringcount, stringnumber, buffer, size);
+       pcre2_match_data_free(data);
 }
 
 SWITCH_DECLARE(void) switch_regex_free(void *data)
 {
-       pcre_free(data);
+       pcre2_code_free(data);
 
 }
 
-SWITCH_DECLARE(int) switch_regex_perform(const char *field, const char *expression, switch_regex_t **new_re, int *ovector, uint32_t olen)
+SWITCH_DECLARE(int) switch_regex_perform(const char *field, const char *expression, switch_regex_t **new_re, switch_regex_match_t **new_match_data)
 {
-       const char *error = NULL;
-       int erroffset = 0;
-       pcre *re = NULL;
+       int error_code = 0;
+       PCRE2_UCHAR error_str[128];
+       PCRE2_SIZE error_offset = 0;
+       pcre2_code *re = NULL;
+       pcre2_match_data *match_data;
        int match_count = 0;
        char *tmp = NULL;
        uint32_t flags = 0;
@@ -87,52 +95,68 @@ SWITCH_DECLARE(int) switch_regex_perform(const char *field, const char *expressi
                expression = tmp;
                if (*opts) {
                        if (strchr(opts, 'i')) {
-                               flags |= PCRE_CASELESS;
+                               flags |= PCRE2_CASELESS;
                        }
                        if (strchr(opts, 's')) {
-                               flags |= PCRE_DOTALL;
+                               flags |= PCRE2_DOTALL;
                        }
                }
        }
 
-       re = pcre_compile(expression,   /* the pattern */
+       re = pcre2_compile((PCRE2_SPTR)expression,      /* the pattern */
+                                         PCRE2_ZERO_TERMINATED,
                                          flags,        /* default options */
-                                         &error,       /* for error message */
-                                         &erroffset,   /* for error offset */
+                                         &error_code,  /* for error code */
+                                         &error_offset,        /* for error offset */
                                          NULL);        /* use default character tables */
-       if (error) {
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "COMPILE ERROR: %d [%s][%s]\n", erroffset, error, expression);
-               switch_regex_safe_free(re);
+       if (!re) {
+               pcre2_get_error_message(error_code, error_str, 128);
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "COMPILE ERROR: %zu [%s][%s]\n", error_offset, error_str, expression);
                goto end;
        }
 
-       match_count = pcre_exec(re,     /* result of pcre_compile() */
-                                                       NULL,   /* we didn't study the pattern */
-                                                       field,  /* the subject string */
+       match_data = pcre2_match_data_create_from_pattern(re, NULL);
+
+       match_count = pcre2_match(re,   /* result of pcre_compile() */
+                                                       (PCRE2_SPTR)field,      /* the subject string */
                                                        (int) strlen(field),    /* the length of the subject string */
                                                        0,      /* start at offset 0 in the subject */
                                                        0,      /* default options */
-                                                       ovector,        /* vector of integers for substring information */
-                                                       olen);  /* number of elements (NOT size in bytes) */
+                                                       match_data,     /* vector of integers for substring information */
+                                                       NULL);  /* number of elements (NOT size in bytes) */
 
 
        if (match_count <= 0) {
+               switch_regex_match_safe_free(match_data);
                switch_regex_safe_free(re);
                match_count = 0;
        }
 
-       *new_re = (switch_regex_t *) re;
+       if (!new_re || !new_match_data) {
+               switch_regex_match_safe_free(match_data);
+               switch_regex_safe_free(re);
+       }
+
+       if (new_re) {
+               *new_re = (switch_regex_t *)re;
+       }
+
+       if (new_match_data) {
+               *new_match_data = (switch_regex_match_t *)match_data;
+       }
 
   end:
        switch_safe_free(tmp);
+
        return match_count;
 }
 
-SWITCH_DECLARE(void) switch_perform_substitution(switch_regex_t *re, int match_count, const char *data, const char *field_data,
-                                                                                                char *substituted, switch_size_t len, int *ovector)
+SWITCH_DECLARE(void) switch_perform_substitution(switch_regex_match_t *match_data, const char *data,
+                                                                                                char *substituted, switch_size_t len)
 {
        char index[10] = "";
        const char *replace = NULL;
+       PCRE2_SIZE replace_size;
        switch_size_t x, y = 0, z = 0;
        int num = 0;
        int brace;
@@ -174,14 +198,15 @@ SWITCH_DECLARE(void) switch_perform_substitution(switch_regex_t *re, int match_c
                                num = -1;
                        }
 
-                       if (pcre_get_substring(field_data, ovector, match_count, num, &replace) >= 0) {
+                       if (pcre2_substring_get_bynumber(match_data, num, (PCRE2_UCHAR **)&replace, &replace_size) >= 0) {
                                if (replace) {
                                        switch_size_t r;
 
                                        for (r = 0; r < strlen(replace) && y < (len - 1); r++) {
                                                substituted[y++] = replace[r];
                                        }
-                                       pcre_free_substring(replace);
+
+                                       pcre2_substring_free((PCRE2_UCHAR *)replace);
                                }
                        }
                } else {
@@ -193,20 +218,21 @@ SWITCH_DECLARE(void) switch_perform_substitution(switch_regex_t *re, int match_c
 }
 
 
-SWITCH_DECLARE(void) switch_capture_regex(switch_regex_t *re, int match_count, const char *field_data,
-                                                                                 int *ovector, const char *var, switch_cap_callback_t callback, void *user_data)
+SWITCH_DECLARE(void) switch_capture_regex(switch_regex_match_t *match_data, int match_count,
+                                                                                 const char *var, switch_cap_callback_t callback, void *user_data)
 
 {
 
 
        const char *replace;
+       PCRE2_SIZE replace_size;
        int i;
 
        for (i = 0; i < match_count; i++) {
-               if (pcre_get_substring(field_data, ovector, match_count, i, &replace) >= 0) {
+               if (pcre2_substring_get_bynumber(match_data, i, (PCRE2_UCHAR **)&replace, &replace_size) >= 0) {
                        if (replace) {
-                               callback(var, replace, user_data);
-                               pcre_free_substring(replace);
+                               callback(var, (const char *)replace, user_data);
+                               pcre2_substring_free((PCRE2_UCHAR *)replace);
                        }
                }
        }
@@ -214,12 +240,13 @@ SWITCH_DECLARE(void) switch_capture_regex(switch_regex_t *re, int match_count, c
 
 SWITCH_DECLARE(switch_status_t) switch_regex_match_partial(const char *target, const char *expression, int *partial)
 {
-       const char *error = NULL;       /* Used to hold any errors                                           */
-       int error_offset = 0;           /* Holds the offset of an error                                      */
-       pcre *pcre_prepared = NULL;     /* Holds the compiled regex                                          */
+       PCRE2_UCHAR error[128]; /* Used to hold any errors                                           */
+       int error_code = 0;     /* Holds the code of an error                                           */
+       PCRE2_SIZE error_offset = 0;            /* Holds the offset of an error                                      */
+       pcre2_code *pcre_prepared = NULL;       /* Holds the compiled regex                                          */
        int match_count = 0;            /* Number of times the regex was matched                             */
-       int offset_vectors[255];        /* not used, but has to exist or pcre won't even try to find a match */
-       int pcre_flags = 0;
+       pcre2_match_data *match_data;
+       int pcre2_flags = 0;
        uint32_t flags = 0;
        char *tmp = NULL;
        switch_status_t status = SWITCH_STATUS_FALSE;
@@ -239,43 +266,44 @@ SWITCH_DECLARE(switch_status_t) switch_regex_match_partial(const char *target, c
                expression = tmp;
                if (*opts) {
                        if (strchr(opts, 'i')) {
-                               flags |= PCRE_CASELESS;
+                               flags |= PCRE2_CASELESS;
                        }
                        if (strchr(opts, 's')) {
-                               flags |= PCRE_DOTALL;
+                               flags |= PCRE2_DOTALL;
                        }
                }
        }
 
        /* Compile the expression */
-       pcre_prepared = pcre_compile(expression, flags, &error, &error_offset, NULL);
+       pcre_prepared = pcre2_compile((PCRE2_SPTR)expression, PCRE2_ZERO_TERMINATED, flags, &error_code, &error_offset, NULL);
 
        /* See if there was an error in the expression */
-       if (error != NULL) {
-               /* Clean up after ourselves */
-               if (pcre_prepared) {
-                       pcre_free(pcre_prepared);
-                       pcre_prepared = NULL;
-               }
+       if (!pcre_prepared) {
+               pcre2_get_error_message(error_code, error, 128);
+
                /* Note our error */
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
-                                                 "Regular Expression Error expression[%s] error[%s] location[%d]\n", expression, error, error_offset);
+                                                 "Regular Expression Error expression[%s] error[%s] location[%zu]\n", expression, error, error_offset);
 
                /* We definitely didn't match anything */
                goto end;
        }
 
        if (*partial) {
-               pcre_flags = PCRE_PARTIAL;
+               pcre2_flags = PCRE2_PARTIAL_SOFT;
        }
 
        /* So far so good, run the regex */
+       match_data = pcre2_match_data_create_from_pattern(pcre_prepared, NULL);
+
        match_count =
-               pcre_exec(pcre_prepared, NULL, target, (int) strlen(target), 0, pcre_flags, offset_vectors, sizeof(offset_vectors) / sizeof(offset_vectors[0]));
+               pcre2_match(pcre_prepared, (PCRE2_SPTR)target, (int) strlen(target), 0, pcre2_flags, match_data, NULL);
+
+       pcre2_match_data_free(match_data);
 
        /* Clean up */
        if (pcre_prepared) {
-               pcre_free(pcre_prepared);
+               pcre2_code_free(pcre_prepared);
                pcre_prepared = NULL;
        }
 
@@ -285,7 +313,7 @@ SWITCH_DECLARE(switch_status_t) switch_regex_match_partial(const char *target, c
        if (match_count > 0) {
                *partial = 0;
                switch_goto_status(SWITCH_STATUS_SUCCESS, end);
-       } else if (match_count == PCRE_ERROR_PARTIAL || match_count == PCRE_ERROR_BADPARTIAL) {
+       } else if (match_count == PCRE2_ERROR_PARTIAL) {
                /* yes it is already set, but the code is clearer this way */
                *partial = 1;
                switch_goto_status(SWITCH_STATUS_SUCCESS, end);
index 1293ca3fbdced69214e6055aca672fe847446f49..206f99218a17a855cb596743576ea3ba1fd278b7 100644 (file)
@@ -2081,8 +2081,9 @@ SWITCH_DECLARE(switch_status_t) switch_find_interface_ip(char *buf, int len, int
 SWITCH_DECLARE(switch_time_t) switch_str_time(const char *in)
 {
        switch_time_exp_t tm = { 0 }, local_tm = { 0 };
-       int proceed = 0, ovector[30], time_only = 0;
+       int proceed = 0, time_only = 0;
        switch_regex_t *re = NULL;
+       switch_regex_match_t *match_data = NULL;
        char replace[1024] = "";
        switch_time_t ret = 0, local_time = 0;
        char *pattern = "^(\\d+)-(\\d+)-(\\d+)\\s*(\\d*):{0,1}(\\d*):{0,1}(\\d*)";
@@ -2092,66 +2093,78 @@ SWITCH_DECLARE(switch_time_t) switch_str_time(const char *in)
        switch_time_exp_lt(&tm, switch_micro_time_now());
 
 
-       if ((time_only = switch_regex_perform(in, pattern3, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
+       if ((time_only = switch_regex_perform(in, pattern3, &re, &match_data))) {
                tm.tm_hour = 0;
                tm.tm_min = 0;
                tm.tm_sec = 0;
        } else {
                tm.tm_year = tm.tm_mon = tm.tm_mday = tm.tm_hour = tm.tm_min = tm.tm_sec = tm.tm_usec = 0;
 
-               if (!(proceed = switch_regex_perform(in, pattern, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
+               if (!(proceed = switch_regex_perform(in, pattern, &re, &match_data))) {
+                       switch_regex_match_safe_free(match_data);
                        switch_regex_safe_free(re);
-                       proceed = switch_regex_perform(in, pattern2, &re, ovector, sizeof(ovector) / sizeof(ovector[0]));
+                       proceed = switch_regex_perform(in, pattern2, &re, &match_data);
                }
        }
 
        if (proceed || time_only) {
+               size_t replace_size;
 
                if (time_only > 1) {
-                       switch_regex_copy_substring(in, ovector, time_only, 1, replace, sizeof(replace));
+                       replace_size = sizeof(replace);
+                       switch_regex_copy_substring(match_data, 1, replace, &replace_size);
                        tm.tm_hour = atoi(replace);
                }
 
                if (time_only > 2) {
-                       switch_regex_copy_substring(in, ovector, time_only, 2, replace, sizeof(replace));
+                       replace_size = sizeof(replace);
+                       switch_regex_copy_substring(match_data, 2, replace, &replace_size);
                        tm.tm_min = atoi(replace);
                }
 
                if (time_only > 3) {
-                       switch_regex_copy_substring(in, ovector, time_only, 3, replace, sizeof(replace));
+                       replace_size = sizeof(replace);
+                       switch_regex_copy_substring(match_data, 3, replace, &replace_size);
                        tm.tm_sec = atoi(replace);
                }
 
                if (proceed > 1) {
-                       switch_regex_copy_substring(in, ovector, proceed, 1, replace, sizeof(replace));
+                       replace_size = sizeof(replace);
+                       switch_regex_copy_substring(match_data, 1, replace, &replace_size);
                        tm.tm_year = atoi(replace) - 1900;
                }
 
                if (proceed > 2) {
-                       switch_regex_copy_substring(in, ovector, proceed, 2, replace, sizeof(replace));
+                       replace_size = sizeof(replace);
+                       switch_regex_copy_substring(match_data, 2, replace, &replace_size);
                        tm.tm_mon = atoi(replace) - 1;
                }
 
                if (proceed > 3) {
-                       switch_regex_copy_substring(in, ovector, proceed, 3, replace, sizeof(replace));
+                       replace_size = sizeof(replace);
+                       switch_regex_copy_substring(match_data, 3, replace, &replace_size);
                        tm.tm_mday = atoi(replace);
                }
 
                if (proceed > 4) {
-                       switch_regex_copy_substring(in, ovector, proceed, 4, replace, sizeof(replace));
+                       replace_size = sizeof(replace);
+                       switch_regex_copy_substring(match_data, 4, replace, &replace_size);
                        tm.tm_hour = atoi(replace);
                }
 
                if (proceed > 5) {
-                       switch_regex_copy_substring(in, ovector, proceed, 5, replace, sizeof(replace));
+                       replace_size = sizeof(replace);
+                       switch_regex_copy_substring(match_data, 5, replace, &replace_size);
                        tm.tm_min = atoi(replace);
                }
 
                if (proceed > 6) {
-                       switch_regex_copy_substring(in, ovector, proceed, 6, replace, sizeof(replace));
+                       replace_size = sizeof(replace);
+                       switch_regex_copy_substring(match_data, 6, replace, &replace_size);
                        tm.tm_sec = atoi(replace);
                }
                
+               switch_regex_match_safe_free(match_data);
                switch_regex_safe_free(re);
 
                switch_time_exp_get(&local_time, &tm);
@@ -2160,9 +2173,11 @@ SWITCH_DECLARE(switch_time_t) switch_str_time(const char *in)
                tm.tm_gmtoff = local_tm.tm_gmtoff;
 
                switch_time_exp_gmt_get(&ret, &tm);
+
                return ret;
        }
 
+       switch_regex_match_safe_free(match_data);
        switch_regex_safe_free(re);
 
        return ret;
index 397fe919caccfec39d842132a43c92ffc900b320..61b1cfb349c12a9276aae2f5bc25b8ab4d690320 100644 (file)
@@ -53,6 +53,23 @@ FST_CORE_BEGIN("./conf")
                }
                FST_TEARDOWN_END()
 
+               FST_TEST_BEGIN(test_switch_regex)
+               {
+                       switch_regex_match_t *match_data = NULL;
+                       switch_regex_t *re = NULL;
+                       char buf[100] = { 0 };
+                       size_t size = sizeof(buf);
+
+                       switch_regex_perform("1234", "^[0-9]+$", &re, &match_data);
+                       switch_regex_copy_substring(match_data, 0, buf, &size);
+                       switch_regex_match_free(match_data);
+                       switch_regex_free(re);
+
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "\n%s\n", buf);
+                       fst_check_string_equals(buf, "1234");
+               }
+               FST_TEST_END()
+
                FST_TEST_BEGIN(test_fctstr_safe_cpy)
                {
                        char *dst;
index 453e4a6bb889d9405a46391d2ca263b230e37d1c..60a2a5049f0e2d0518340e82c2f3ba30feb260bb 100644 (file)
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup Label="ProjectConfigurations">
     <ProjectConfiguration Include="Debug|Win32">
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(PlatformName)\$(Configuration)\</OutDir>
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(PlatformName)\$(Configuration)\$(ProjectName)\</IntDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(PlatformName)\$(Configuration)\$(ProjectName)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(PlatformName)\$(Configuration)\</OutDir>
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(PlatformName)\$(Configuration)\</OutDir>
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(PlatformName)\$(Configuration)\$(ProjectName)\</IntDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(PlatformName)\$(Configuration)\$(ProjectName)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
-    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>\r
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
   </PropertyGroup>
   <ItemDefinitionGroup>
index 8de44dd140ad9594fb52b63cb3e84a772d8c0a76..bfa6de553f6721a8c819674083790e6bbc461438 100644 (file)
@@ -4,7 +4,7 @@
     <Import Project="basedir.props" Condition=" '$(BaseDirImported)' == ''"/>
   </ImportGroup>
   <PropertyGroup Label="UserMacros">
-    <pcreVersion>8.34</pcreVersion>
+    <pcreVersion>10.45</pcreVersion>
   </PropertyGroup>
   <PropertyGroup>
     <pcreVersionImported>true</pcreVersionImported>
index 6a6a07dec8acc164060861003744bc074d7c4f85..6a241184bb262695dd454cbc825d01001cbebafa 100644 (file)
@@ -12,8 +12,8 @@
   <PropertyGroup>
     <LibraryConfiguration Condition="$(Configuration.ToLower().Contains('debug'))">Debug</LibraryConfiguration>
     <LibraryConfiguration Condition="$(Configuration.ToLower().Contains('release'))">Release</LibraryConfiguration>
-    <PCRELibraryFileName Condition=" '$(LibraryConfiguration)' == 'Debug' ">pcred</PCRELibraryFileName>
-    <PCRELibraryFileName Condition=" '$(LibraryConfiguration)' == 'Release' ">pcre</PCRELibraryFileName>
+    <PCRELibraryFileName Condition=" '$(LibraryConfiguration)' == 'Debug' ">pcre2-8d</PCRELibraryFileName>
+    <PCRELibraryFileName Condition=" '$(LibraryConfiguration)' == 'Release' ">pcre2-8</PCRELibraryFileName>
   </PropertyGroup>
 
   <PropertyGroup Label="UserMacros">
@@ -52,7 +52,7 @@
   <Target Name="pcreHeadersDownloadTarget" BeforeTargets="CustomBuild" DependsOnTargets="7za">
       <DownloadPackageTask
            package="http://files.freeswitch.org/windows/packages/pcre/$(pcreVersion)/pcre-$(pcreVersion)-headers.zip"
-           expectfileordirectory="$(pcreLibDir)\include\pcre.h"
+           expectfileordirectory="$(pcreLibDir)\include\pcre2.h"
            outputfolder=""
            outputfilename=""
            extractto="$(BaseDir)libs\"
     <ClCompile>
       <AdditionalIncludeDirectories>$(BaseDir)libs\pcre-$(pcreVersion)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <PreprocessorDefinitions>;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ClCompile>
     <Link>
       <AdditionalLibraryDirectories>$(SolutionDir)libs\pcre-$(pcreVersion)\binaries\$(Platform)\$(LibraryConfiguration)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
-      <AdditionalDependencies Condition=" '$(LibraryConfiguration)' == 'Debug' ">pcred.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalDependencies Condition=" '$(LibraryConfiguration)' == 'Release' ">pcre.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>$(PCRELibraryFileName).lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
   <ItemGroup />