{"id":2221304,"url":"http://patchwork.ozlabs.org/api/1.2/patches/2221304/?format=json","web_url":"http://patchwork.ozlabs.org/project/buildroot/patch/20260409073223.3644434-1-bernd@kuhls.net/","project":{"id":27,"url":"http://patchwork.ozlabs.org/api/1.2/projects/27/?format=json","name":"Buildroot development","link_name":"buildroot","list_id":"buildroot.buildroot.org","list_email":"buildroot@buildroot.org","web_url":"","scm_url":"","webscm_url":"","list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<20260409073223.3644434-1-bernd@kuhls.net>","list_archive_url":null,"date":"2026-04-09T07:32:23","name":"[1/1] package/freeswitch: switch to pcre2","commit_ref":null,"pull_url":null,"state":"superseded","archived":false,"hash":"71ce5cf54ee718c68657890b82bfb30e6d2ad044","submitter":{"id":86624,"url":"http://patchwork.ozlabs.org/api/1.2/people/86624/?format=json","name":"Bernd Kuhls","email":"bernd@kuhls.net"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/buildroot/patch/20260409073223.3644434-1-bernd@kuhls.net/mbox/","series":[{"id":499245,"url":"http://patchwork.ozlabs.org/api/1.2/series/499245/?format=json","web_url":"http://patchwork.ozlabs.org/project/buildroot/list/?series=499245","date":"2026-04-09T07:32:23","name":"[1/1] package/freeswitch: switch to pcre2","version":1,"mbox":"http://patchwork.ozlabs.org/series/499245/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2221304/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2221304/checks/","tags":{},"related":[],"headers":{"Return-Path":"<buildroot-bounces@buildroot.org>","X-Original-To":["incoming-buildroot@patchwork.ozlabs.org","buildroot@buildroot.org"],"Delivered-To":["patchwork-incoming-buildroot@legolas.ozlabs.org","buildroot@buildroot.org"],"Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=buildroot.org header.i=@buildroot.org\n header.a=rsa-sha256 header.s=default header.b=Dvf0kIyn;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=buildroot.org\n (client-ip=2605:bc80:3010::137; helo=smtp4.osuosl.org;\n envelope-from=buildroot-bounces@buildroot.org; receiver=patchwork.ozlabs.org)"],"Received":["from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4frs8w64Qyz1xtJ\n\tfor <incoming-buildroot@patchwork.ozlabs.org>;\n Thu, 09 Apr 2026 17:32:46 +1000 (AEST)","from localhost (localhost [127.0.0.1])\n\tby smtp4.osuosl.org (Postfix) with ESMTP id 5358B40F4E;\n\tThu,  9 Apr 2026 07:32:38 +0000 (UTC)","from smtp4.osuosl.org ([127.0.0.1])\n by localhost (smtp4.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP\n id NjKKG17uugxT; Thu,  9 Apr 2026 07:32:35 +0000 (UTC)","from lists1.osuosl.org (lists1.osuosl.org [140.211.166.142])\n\tby smtp4.osuosl.org (Postfix) with ESMTP id 77A5840B9B;\n\tThu,  9 Apr 2026 07:32:35 +0000 (UTC)","from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137])\n by lists1.osuosl.org (Postfix) with ESMTP id 7B2881D6\n for <buildroot@buildroot.org>; Thu,  9 Apr 2026 07:32:33 +0000 (UTC)","from localhost (localhost [127.0.0.1])\n by smtp4.osuosl.org (Postfix) with ESMTP id 6110A40B9B\n for <buildroot@buildroot.org>; Thu,  9 Apr 2026 07:32:33 +0000 (UTC)","from smtp4.osuosl.org ([127.0.0.1])\n by localhost (smtp4.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP\n id 6FBf0Ug-OriU for <buildroot@buildroot.org>;\n Thu,  9 Apr 2026 07:32:30 +0000 (UTC)","from dd20012.kasserver.com (dd20012.kasserver.com [85.13.140.57])\n by smtp4.osuosl.org (Postfix) with ESMTPS id D1D7240B2F\n for <buildroot@buildroot.org>; Thu,  9 Apr 2026 07:32:29 +0000 (UTC)","from fli4l.lan.fli4l (p4fd6ca66.dip0.t-ipconnect.de\n [79.214.202.102])\n by dd20012.kasserver.com (Postfix) with ESMTPSA id 218AFA4C02D2\n for <buildroot@buildroot.org>; Thu,  9 Apr 2026 09:32:26 +0200 (CEST)","from bruckner.lan.fli4l ([192.168.1.1]:53660)\n by fli4l.lan.fli4l with esmtp (Exim 4.99.1)\n (envelope-from <bernd@kuhls.net>) id 1wAjsG-000000000QG-1ZX0\n for buildroot@buildroot.org; Thu, 09 Apr 2026 07:32:25 +0000"],"X-Virus-Scanned":["amavis at osuosl.org","amavis at osuosl.org"],"X-Comment":"SPF check N/A for local connections - client-ip=140.211.166.142;\n helo=lists1.osuosl.org; envelope-from=buildroot-bounces@buildroot.org;\n receiver=<UNKNOWN> ","DKIM-Filter":["OpenDKIM Filter v2.11.0 smtp4.osuosl.org 77A5840B9B","OpenDKIM Filter v2.11.0 smtp4.osuosl.org D1D7240B2F"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=buildroot.org;\n\ts=default; t=1775719955;\n\tbh=p0C56hIf04YxuZMUVOA8y7dDm44quvLN+2ezvIh2VHk=;\n\th=From:To:Date:Subject:List-Id:List-Unsubscribe:List-Archive:\n\t List-Post:List-Help:List-Subscribe:From;\n\tb=Dvf0kIynEjaTt4ERUyZfpFmUyJXXAzQWUBXC5WBTNFHlQUCSESMJZSJRpILKOXQlp\n\t LPhtWrmq8l+t1tjrDLhPLwJucnHc9hERsvP3sdJu0YvqnzoCY33YDVVjWC5lEhFeIj\n\t oYIFQIRVAr/R18NBGWyIX2ahMsPS8OxvC2kDkucEsvuy4HCBL+8I+GLFzSioiJPkEM\n\t sF2EMhW56raO2tY2cBAVzEG7OGFwq7VUeUmrfdmKNxwBaUknxzp+GoeVGMqOFaualB\n\t GnrsHxFDt5Eg+Kkxg+iEFCvmXO3tP/AGt8UJCJuVD0afUqNhiBCnAx45N2cXiyUvkE\n\t IVlzNjmtdui3Q==","Received-SPF":"Pass (mailfrom) identity=mailfrom; client-ip=85.13.140.57;\n helo=dd20012.kasserver.com; envelope-from=bernd@kuhls.net;\n receiver=<UNKNOWN>","DMARC-Filter":"OpenDMARC Filter v1.4.2 smtp4.osuosl.org D1D7240B2F","From":"Bernd Kuhls <bernd@kuhls.net>","To":"buildroot@buildroot.org","Date":"Thu,  9 Apr 2026 09:32:23 +0200","Message-ID":"<20260409073223.3644434-1-bernd@kuhls.net>","X-Mailer":"git-send-email 2.47.3","MIME-Version":"1.0","X-Spamd-Bar":"--","X-Mailman-Original-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=kuhls.net;\n s=kas202511301023; t=1775719946;\n bh=1zi79R+qkk6Eet+QBecjd57x8Fp561lqZN8XMgasytY=;\n h=From:To:Subject:Date:From;\n b=rt8pA2wn6YgiSO0i3c/zNu3J0uAV8P+3ZRWlljSvGnTG52FCbGpGvlu9/PB+I1bgO\n vgmYdLrLiTSnYPp6Pyo+ktYglLcVZIUWaIYTMKG6u+mDx6uEYfn0rzDuDJxcItMvph\n fJt7NKiWeL4PhTzFq8veHQOnmZt/QTdZz5R6P1lpF+0GsiobJQ2NA8Z4j4EPwKdwgz\n J+y6Z3wBBQnEtjqyiICdhQmgLY1Ax9DxtgHDhXICHckh2DfbeuA5GN//Z1qEYoaqM7\n UPm6FK7NVSrGpElzoW6qPs/U8NZ/fG97rIrsJkYumi7tLGyFcneJwMFMZ1p1nRvyZP\n Utg18ChWfOklA==","X-Mailman-Original-Authentication-Results":["smtp4.osuosl.org;\n dmarc=pass (p=none dis=none)\n header.from=kuhls.net","smtp4.osuosl.org;\n dkim=pass (2048-bit key,\n unprotected) header.d=kuhls.net header.i=@kuhls.net header.a=rsa-sha256\n header.s=kas202511301023 header.b=rt8pA2wn"],"Subject":"[Buildroot] [PATCH 1/1] package/freeswitch: switch to pcre2","X-BeenThere":"buildroot@buildroot.org","X-Mailman-Version":"2.1.30","Precedence":"list","List-Id":"Discussion and development of buildroot <buildroot.buildroot.org>","List-Unsubscribe":"<https://lists.buildroot.org/mailman/options/buildroot>,\n <mailto:buildroot-request@buildroot.org?subject=unsubscribe>","List-Archive":"<http://lists.buildroot.org/pipermail/buildroot/>","List-Post":"<mailto:buildroot@buildroot.org>","List-Help":"<mailto:buildroot-request@buildroot.org?subject=help>","List-Subscribe":"<https://lists.buildroot.org/mailman/listinfo/buildroot>,\n <mailto:buildroot-request@buildroot.org?subject=subscribe>","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"buildroot-bounces@buildroot.org","Sender":"\"buildroot\" <buildroot-bounces@buildroot.org>"},"content":"Added patch 0006 which replaces the usage of pcre in favour of pcre2,\nthis is a rebased version of upstream commits used by OpenWRT:\nhttps://github.com/openwrt/telephony/commit/75acd1cdc29740a47454212cd48755b9abbd7a12\n\nAdded patch 0005 which is a prerequisite for patch 0006, also used by\nOpenWRT.\n\nAdded patch 0007 which fixes a runtime crash caused by patch 0006.\n\nAdded Upstream: tag to patch 0001.\n\nSigned-off-by: Bernd Kuhls <bernd@kuhls.net>\n---\n .checkpackageignore                           |    1 -\n ...-hash-hmac_ossl.c-fix-build-with-lib.patch |    2 +\n ...mory-leak-by-correctly-freeing-regex.patch |   34 +\n .../0006-Move-project-to-PCRE2.patch          | 1813 +++++++++++++++++\n ...x-double-free-after-upgrade-to-pcre2.patch |   27 +\n package/freeswitch/Config.in                  |    2 +-\n package/freeswitch/freeswitch.mk              |    5 +-\n 7 files changed, 1881 insertions(+), 3 deletions(-)\n create mode 100644 package/freeswitch/0005-Fix-memory-leak-by-correctly-freeing-regex.patch\n create mode 100644 package/freeswitch/0006-Move-project-to-PCRE2.patch\n create mode 100644 package/freeswitch/0007-Fix-double-free-after-upgrade-to-pcre2.patch","diff":"diff --git a/.checkpackageignore b/.checkpackageignore\nindex 6599435b62..1eca2febe9 100644\n--- a/.checkpackageignore\n+++ b/.checkpackageignore\n@@ -354,7 +354,6 @@ package/freescale-imx/imx-uuc/S80imx-uuc Shellcheck lib_sysv.Indent lib_sysv.Var\n package/freescale-imx/imx-vpu-hantro/0001-Fix-ion.h-header-inclusion-to-be-standard.patch lib_patch.Upstream\n package/freescale-imx/imx-vpu-hantro/0002-Fix-build-with-uclibc-toolchain.patch lib_patch.Upstream\n package/freescale-imx/imx-vpu-hantro/0003-Fix-Linux-kernel-version-header.patch lib_patch.Upstream\n-package/freeswitch/0001-libs-srtp-crypto-hash-hmac_ossl.c-fix-build-with-lib.patch lib_patch.Upstream\n package/frr/S50frr Shellcheck\n package/fstrcmp/0001-disable-rpath.patch lib_patch.Upstream\n package/ftop/0001-overflow.patch lib_patch.Upstream\ndiff --git a/package/freeswitch/0001-libs-srtp-crypto-hash-hmac_ossl.c-fix-build-with-lib.patch b/package/freeswitch/0001-libs-srtp-crypto-hash-hmac_ossl.c-fix-build-with-lib.patch\nindex eb717fc26d..1a66e7c8d5 100644\n--- a/package/freeswitch/0001-libs-srtp-crypto-hash-hmac_ossl.c-fix-build-with-lib.patch\n+++ b/package/freeswitch/0001-libs-srtp-crypto-hash-hmac_ossl.c-fix-build-with-lib.patch\n@@ -25,6 +25,8 @@ crypto/hash/hmac_ossl.c:133:40: error: invalid application of 'sizeof' to incomp\n Fixes:\n  - http://autobuild.buildroot.org/results/e696ead9ffffa5bb80928d75607bfbb9b263d3c6\n \n+Upstream: https://github.com/signalwire/freeswitch/pull/1654\n+\n Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>\n ---\n  libs/srtp/crypto/hash/hmac_ossl.c | 6 ++++--\ndiff --git a/package/freeswitch/0005-Fix-memory-leak-by-correctly-freeing-regex.patch b/package/freeswitch/0005-Fix-memory-leak-by-correctly-freeing-regex.patch\nnew file mode 100644\nindex 0000000000..5ce3a060a8\n--- /dev/null\n+++ b/package/freeswitch/0005-Fix-memory-leak-by-correctly-freeing-regex.patch\n@@ -0,0 +1,34 @@\n+From 12b47fe7f91b93ba9cec90676e62c6239a097c98 Mon Sep 17 00:00:00 2001\n+From: Christian Marangi <ansuelsmth@gmail.com>\n+Date: Fri, 3 Nov 2023 17:27:06 +0100\n+Subject: [PATCH] [mod_verto] Fix memory leak by correctly freeing regex\n+\n+For mod_verto regex was never freed and was actually leaking memory.\n+Correctly free the compiled regex to fix the memory leak.\n+\n+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>\n+\n+Upstream: https://github.com/signalwire/freeswitch/commit/12b47fe7f91b93ba9cec90676e62c6239a097c98\n+\n+Signed-off-by: Bernd Kuhls <bernd@kuhls.net>\n+---\n+ src/mod/endpoints/mod_verto/mod_verto.c | 2 ++\n+ 1 file changed, 2 insertions(+)\n+\n+diff --git a/src/mod/endpoints/mod_verto/mod_verto.c b/src/mod/endpoints/mod_verto/mod_verto.c\n+index 48c40527b56..36aba6db5e2 100644\n+--- a/src/mod/endpoints/mod_verto/mod_verto.c\n++++ b/src/mod/endpoints/mod_verto/mod_verto.c\n+@@ -1893,10 +1893,12 @@ static void http_run(jsock_t *jsock)\n+ \t\t\t\tswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,\n+ \t\t\t\t\t\t\t\t  \"%d request [%s] matched expr [%s]\\n\", proceed, request->uri, expression);\n+ \t\t\t\trequest->uri = rule->value;\n++\t\t\t\tswitch_regex_safe_free(re);\n+ \t\t\t\tbreak;\n+ \t\t\t}\n+ \n+ \t\t\trule = rule->next;\n++\t\t\tswitch_regex_safe_free(re);\n+ \t\t}\n+ \t}\n+ \ndiff --git a/package/freeswitch/0006-Move-project-to-PCRE2.patch b/package/freeswitch/0006-Move-project-to-PCRE2.patch\nnew file mode 100644\nindex 0000000000..f9d3d53574\n--- /dev/null\n+++ b/package/freeswitch/0006-Move-project-to-PCRE2.patch\n@@ -0,0 +1,1813 @@\n+From b0692d4810466ca048fcfb217dfc7ce012620e5a Mon Sep 17 00:00:00 2001\n+From: Christian Marangi <ansuelsmth@gmail.com>\n+Date: Fri, 3 Nov 2023 17:23:31 +0100\n+Subject: [PATCH] [Core] Move project to PCRE2\n+\n+Move project to PCRE2 as PCRE is EOL and won't receive any security\n+updates anymore.\n+\n+PCRE2 have different API compared to PCRE. Mainly PCRE2 have the concept\n+of match_data, no ovector needs to be passed, different handling for\n+error string and different handling for substring manipulation.\n+\n+Update any user of PCRE library with the new API\n+\n+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>\n+\n+Upstream: https://github.com/signalwire/freeswitch/pull/2858\n+\n+Downloaded rebased version from\n+https://github.com/openwrt/telephony/blob/master/net/freeswitch/patches/900-Core-Move-project-to-PCRE2.patch\n+\n+Signed-off-by: Bernd Kuhls <bernd@kuhls.net>\n+---\n+ Makefile.am                                   |   4 +-\n+ build/Makefile.centos5                        |  10 +-\n+ build/Makefile.centos6                        |   4 +-\n+ build/Makefile.openbsd                        |   2 +-\n+ build/Makefile.solaris11                      |  10 +-\n+ configure.ac                                  |   2 +-\n+ freeswitch.spec                               |   4 +-\n+ libs/.gitignore                               |  10 +-\n+ libs/apr/build/prebuildNW.bat                 |   6 +-\n+ src/include/switch.h                          |   2 +-\n+ src/include/switch_regex.h                    |  33 +++--\n+ .../mod_abstraction/mod_abstraction.c         |   8 +-\n+ .../applications/mod_commands/mod_commands.c  |   8 +-\n+ .../applications/mod_dptools/mod_dptools.c    |   8 +-\n+ src/mod/applications/mod_enum/mod_enum.c      |  21 +--\n+ src/mod/applications/mod_lcr/mod_lcr.c        |  11 +-\n+ src/mod/applications/mod_sms/mod_sms.c        |  12 +-\n+ .../mod_translate/mod_translate.c             |  11 +-\n+ .../mod_dialplan_asterisk.c                   |  11 +-\n+ .../mod_dialplan_xml/mod_dialplan_xml.c       |  23 ++--\n+ src/mod/endpoints/mod_sofia/sofia_glue.c      |   6 +-\n+ src/mod/endpoints/mod_verto/mod_verto.c       |   8 +-\n+ .../mod_erlang_event/mod_erlang_event.c       |   6 +-\n+ .../mod_event_socket/mod_event_socket.c       |   6 +-\n+ src/mod/event_handlers/mod_rayo/Makefile.am   |  18 +--\n+ src/mod/event_handlers/mod_rayo/srgs.c        |  62 +++++----\n+ .../mod_managed/freeswitch_managed.h          |   8 +-\n+ .../languages/mod_managed/freeswitch_wrap.cxx | Bin 1672594 -> 1672494 bytes\n+ src/mod/languages/mod_managed/managed/swig.cs | Bin 2625569 -> 2629167 bytes\n+ src/mod/languages/mod_v8/include/fspcre.hpp   |   2 +-\n+ .../languages/mod_v8/src/fseventhandler.cpp   |   5 +-\n+ src/mod/languages/mod_v8/src/fspcre.cpp       |  11 +-\n+ src/mod/languages/mod_yaml/mod_yaml.c         |  10 +-\n+ .../xml_int/mod_xml_radius/mod_xml_radius.c   |   8 +-\n+ src/switch_channel.c                          |  14 +-\n+ src/switch_ivr.c                              |   7 +-\n+ src/switch_ivr_async.c                        |   8 +-\n+ src/switch_ivr_menu.c                         |   8 +-\n+ src/switch_ivr_play_say.c                     |  11 +-\n+ src/switch_regex.c                            | 123 ++++++++++--------\n+ src/switch_utils.c                            |  43 +++---\n+ 41 files changed, 317 insertions(+), 247 deletions(-)\n+\n+--- a/Makefile.am\n++++ b/Makefile.am\n+@@ -231,9 +231,9 @@ CORE_LIBS+=libfreeswitch_libyuv.la\n+ endif\n+ \n+ lib_LTLIBRARIES\t         = libfreeswitch.la\n+-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)\n++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)\n+ libfreeswitch_la_LDFLAGS = -version-info 1:0:0 $(AM_LDFLAGS) $(PLATFORM_CORE_LDFLAGS) -no-undefined\n+-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)\n++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)\n+ libfreeswitch_la_DEPENDENCIES = $(BUILT_SOURCES)\n+ \n+ if HAVE_PNG\n+--- a/build/Makefile.centos5\n++++ b/build/Makefile.centos5\n+@@ -13,7 +13,7 @@ DOWNLOAD=http://files.freeswitch.org/dow\n+ JPEG=v8d\n+ OPENSSL=1.0.1l\n+ SQLITE=autoconf-3080403\n+-PCRE=8.35\n++PCRE2=10.42\n+ CURL=7.40.0\n+ SPEEX=1.2rc1\n+ LIBEDIT=20140618-3.1\n+@@ -45,7 +45,7 @@ has-git:\n+ \t@git --version || (echo \"please install git by running 'make install-git'\" && false)\n+ \n+ clean:\n+-\t@rm -rf openssl* ldns* jpeg* pcre* perl* pkg-config* speex* sqlite* libedit* curl* *~\n++\t@rm -rf openssl* ldns* jpeg* pcre2* perl* pkg-config* speex* sqlite* libedit* curl* *~\n+ \t(cd freeswitch.git && git clean -fdx && git reset --hard HEAD && git pull)\n+ \n+ libjpeg: jpeg-8d/.done\n+@@ -66,9 +66,9 @@ sqlite-$(SQLITE):\n+ \t(test -d $@) || (wget -4 -O $@.tar.gz $(DOWNLOAD)/$@.tar.gz && tar zxfv $@.tar.gz)\n+ \t(cd $@ && ./configure --prefix=$(PREFIX) && make && sudo make install && touch .done_sqlite && touch .done)\n+ \n+-pcre: pcre-$(PCRE)/.done\n+-pcre-$(PCRE)/.done: pcre-$(PCRE)\n+-pcre-$(PCRE):\n++pcre2: pcre2-$(PCRE2)/.done\n++pcre2-$(PCRE2)/.done: pcre2-$(PCRE2)\n++pcre2-$(PCRE2):\n+ \t(test -d $@) || (wget -4 -O $@.tar.gz $(DOWNLOAD)/$@.tar.gz && tar zxfv $@.tar.gz)\n+ \t(cd $@ && ./configure --prefix=$(PREFIX) && make && sudo make install && touch .done)\n+ \n+--- a/build/Makefile.centos6\n++++ b/build/Makefile.centos6\n+@@ -6,8 +6,8 @@\n+ # in that same directory.\n+ #\n+ #\n+-RPMS=git gcc-c++ autoconf automake libtool wget python ncurses-devel zlib-devel libjpeg-devel openssl-devel e2fsprogs-devel sqlite-devel libcurl-devel pcre-devel speex-devel ldns-devel libedit-devel\n+-DEBS=git build-essential automake autoconf 'libtool-bin|libtool' wget python 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\n++RPMS=git gcc-c++ autoconf automake libtool wget python ncurses-devel zlib-devel libjpeg-devel openssl-devel e2fsprogs-devel sqlite-devel libcurl-devel pcre2-devel speex-devel ldns-devel libedit-devel\n++DEBS=git build-essential automake autoconf 'libtool-bin|libtool' wget python 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\n+ \n+ freeswitch: deps has-git freeswitch.git/Makefile\n+ \tcd freeswitch.git && make\n+--- a/build/Makefile.openbsd\n++++ b/build/Makefile.openbsd\n+@@ -7,7 +7,7 @@\n+ #\n+ #\n+ \n+-PKG=rsync-3.1.0 git automake-1.14.1 autoconf-2.69p1 libtool gmake bzip2 jpeg wget pcre speex libldns\n++PKG=rsync-3.1.0 git automake-1.14.1 autoconf-2.69p1 libtool gmake bzip2 jpeg wget pcre2 speex libldns\n+ PREFIX=/usr/local/freeswitch\n+ DOWNLOAD=http://files.freeswitch.org/downloads/libs\n+ OPENSSL=1.0.1j\n+--- a/build/Makefile.solaris11\n++++ b/build/Makefile.solaris11\n+@@ -12,7 +12,7 @@ DOWNLOAD=http://files.freeswitch.org/dow\n+ JP=v8d\n+ SSL=1.0.1j\n+ SQLITE=autoconf-3080403\n+-PCRE=8.35\n++PCRE2=10.42\n+ CURL=7.35.0\n+ SPEEX=1.2rc1\n+ LIBEDIT=20140618-3.1\n+@@ -43,7 +43,7 @@ has-git:\n+ \t@git --version || (echo \"please install git by running 'gmake install-git'\" && false)\n+ \n+ clean:\n+-\t@rm -rf openssl* ldns* jpeg* pcre* perl* pkg-config* speex* sqlite* libedit* curl* *~\n++\t@rm -rf openssl* ldns* jpeg* pcre2* perl* pkg-config* speex* sqlite* libedit* curl* *~\n+ \t(cd freeswitch.git && git clean -fdx && git reset --hard HEAD && git pull)\n+ \n+ libjpeg: jpeg-8d/.done\n+@@ -64,9 +64,9 @@ sqlite-$(SQLITE):\n+ \t(test -d $@) || (wget -4 -O $@.tar.gz $(DOWNLOAD)/$@.tar.gz && tar zxfv $@.tar.gz)\n+ \t(cd $@ && CFLAGS=-m64 LDFLAGS=-m64 ./configure --prefix=$(PREFIX) && gmake && sudo gmake install && touch .done)\n+ \n+-pcre: pcre-$(PCRE)/.done\n+-pcre-$(PCRE)/.done: pcre-$(PCRE)\n+-pcre-$(PCRE):\n++pcre2: pcre2-$(PCRE2)/.done\n++pcre2-$(PCRE2)/.done: pcre2-$(PCRE2)\n++pcre2-$(PCRE2):\n+ \t(test -d $@) || (wget -4 -O $@.tar.gz $(DOWNLOAD)/$@.tar.gz && tar zxfv $@.tar.gz)\n+ \t(cd $@ && CXXFLAGS=-m64 CFLAGS=-m64 LDFLAGS=-m64 ./configure --prefix=$(PREFIX) && gmake && sudo gmake install && touch .done)\n+ \n+--- a/configure.ac\n++++ b/configure.ac\n+@@ -1312,7 +1312,7 @@ PKG_CHECK_MODULES([TPL], [libtpl >= 1.5]\n+ \n+ PKG_CHECK_MODULES([SQLITE], [sqlite3 >= 3.6.20])\n+ PKG_CHECK_MODULES([CURL], [libcurl >= 7.19])\n+-PKG_CHECK_MODULES([PCRE], [libpcre >= 7.8])\n++PKG_CHECK_MODULES([PCRE2], [libpcre2-8 >=  10.00])\n+ PKG_CHECK_MODULES([SPEEX], [speex >= 1.2rc1 speexdsp >= 1.2rc1])\n+ PKG_CHECK_MODULES([YAML], [yaml-0.1 >= 0.1.4],[\n+   AM_CONDITIONAL([HAVE_YAML],[true])],[\n+--- a/freeswitch.spec\n++++ b/freeswitch.spec\n+@@ -142,7 +142,7 @@ BuildRequires: libtool >= 1.5.17\n+ BuildRequires: openssl-devel >= 1.0.1e\n+ BuildRequires: sofia-sip-devel >= 1.13.17\n+ BuildRequires: spandsp3-devel >= 3.0\n+-BuildRequires: pcre-devel \n++BuildRequires: pcre2-devel \n+ BuildRequires: speex-devel \n+ BuildRequires: sqlite-devel >= 3.6.20\n+ BuildRequires: libtiff-devel\n+@@ -156,7 +156,7 @@ BuildRequires: zlib-devel\n+ BuildRequires: libxml2-devel\n+ BuildRequires: libsndfile-devel\n+ Requires: curl >= 7.19\n+-Requires: pcre\n++Requires: pcre2\n+ Requires: speex\n+ Requires: sqlite >= 3.6.20\n+ Requires: libtiff\n+--- a/libs/.gitignore\n++++ b/libs/.gitignore\n+@@ -554,7 +554,7 @@ opal\n+ /win32/celt/*/*/libcelt.log\n+ /win32/libg722_1/*/*/libg722_1.log\n+ /win32/libshout/*/*/libshout.log\n+-/win32/pcre/pcre_chartables.c\n++/win32/pcre2/pcre2_chartables.c\n+ /win32/tmp*.bat\n+ !/xmlrpc-c/include/xmlrpc-c/config.h.in\n+ /xmlrpc-c/stamp-h2\n+@@ -610,9 +610,9 @@ opal\n+ broadvoice/config/compile\n+ ilbc/config/compile\n+ libg722_1/config/compile\n+-pcre/compile\n++pcre2/compile\n+ srtp/build/compile\n+-/pcre-*/\n++/pcre2-*/\n+ /speex-*/\n+ /curl-*/\n+ /sqlite-*.zip\n+@@ -637,8 +637,8 @@ curl-*/\n+ curl-*\n+ flite-*/\n+ flite-*\n+-pcre-*/\n+-pcre-*\n++pcre2-*/\n++pcre2-*\n+ libsndfile-*/\n+ libsndfile-*\n+ opencv-*/\n+--- a/libs/apr/build/prebuildNW.bat\n++++ b/libs/apr/build/prebuildNW.bat\n+@@ -35,9 +35,9 @@ copy ..\\..\\apr-util\\xml\\expat\\lib\\expat.\n+ copy ..\\..\\apr-util\\xml\\expat\\lib\\config.hnw ..\\..\\apr-util\\xml\\expat\\lib\\config.h\n+ copy ..\\..\\apr-util\\include\\private\\apu_select_dbm.hw ..\\..\\apr-util\\include\\private\\apu_select_dbm.h\n+ \n+-@echo Fixing up the pcre headers\n+-copy ..\\..\\pcre\\config.hw ..\\..\\pcre\\config.h\n+-copy ..\\..\\pcre\\pcre.hw ..\\..\\pcre\\pcre.h\n++@echo Fixing up the pcre2 headers\n++copy ..\\..\\pcre2\\config.hw ..\\..\\pcre2\\config.h\n++copy ..\\..\\pcre2\\pcre2.hw ..\\..\\pcre2\\pcre2.h\n+ \n+ @echo Generating the import list...\n+ set MWCIncludes=..\\include;..\\include\\arch\\netware;..\\include\\arch\\unix;..\\..\\apr-util\\include;+%NovellLibC%\n+--- a/src/include/switch.h\n++++ b/src/include/switch.h\n+@@ -172,7 +172,7 @@\n+  *\t\t- APR (http://apr.apache.org)\n+  *\t\t- APR-Util (http://apr.apache.org)\n+  *\t\t- SQLite (http://www.sqlite.org)\n+- *\t\t- Pcre (http://www.pcre.org/)\n++ *\t\t- Pcre2 (http://www.pcre.org/)\n+  *\t\t- SRTP (http://srtp.sourceforge.net/srtp.html)\n+  *\n+  *\tAdditionally, the various external modules make use of several external modules:\n+--- a/src/include/switch_regex.h\n++++ b/src/include/switch_regex.h\n+@@ -25,7 +25,7 @@\n+  *\n+  * Michael Jerris <mike@jerris.com>\n+  *\n+- * switch_regex.h -- pcre wrapper and extensions Header\n++ * switch_regex.h -- pcre2 wrapper and extensions Header\n+  *\n+  */\n+ /*! \\file switch_regex.h\n+@@ -40,18 +40,21 @@ SWITCH_BEGIN_EXTERN_C\n+  * @ingroup FREESWITCH\n+  * @{\n+  */\n+-\ttypedef struct real_pcre switch_regex_t;\n++\ttypedef struct pcre2_real_code switch_regex_t;\n++\ttypedef struct pcre2_real_match_data_8 switch_regex_match_data_t;\n++\ttypedef struct pcre2_real_compile_context_8 switch_regex_compile_context_t;\n+ \n+-SWITCH_DECLARE(switch_regex_t *) switch_regex_compile(const char *pattern, int options, const char **errorptr, int *erroroffset,\n+-\t\t\t\t\t\t\t\t\t\t\t\t\t  const unsigned char *tables);\n++SWITCH_DECLARE(switch_regex_t *) switch_regex_compile(const char *pattern, int options, int *errorcode, unsigned int *erroroffset,\n++\t\t\t\t\t\t\t\t\t\t\t\t\t  switch_regex_compile_context_t *ccontext);\n+ \n+-SWITCH_DECLARE(int) switch_regex_copy_substring(const char *subject, int *ovector, int stringcount, int stringnumber, char *buffer, int size);\n++SWITCH_DECLARE(int) switch_regex_copy_substring(switch_regex_match_data_t *match_data, int stringnumber, char *buffer, unsigned int *size);\n+ \n++SWITCH_DECLARE(void) switch_regex_match_free(void *data);\n+ SWITCH_DECLARE(void) switch_regex_free(void *data);\n+ \n+-SWITCH_DECLARE(int) switch_regex_perform(const char *field, const char *expression, switch_regex_t **new_re, int *ovector, uint32_t olen);\n+-SWITCH_DECLARE(void) switch_perform_substitution(switch_regex_t *re, int match_count, const char *data, const char *field_data,\n+-\t\t\t\t\t\t\t\t\t\t\t\t char *substituted, switch_size_t len, int *ovector);\n++SWITCH_DECLARE(int) switch_regex_perform(const char *field, const char *expression, switch_regex_t **new_re, switch_regex_match_data_t **new_match_data);\n++SWITCH_DECLARE(void) switch_perform_substitution(switch_regex_match_data_t *match_data, const char *data,\n++\t\t\t\t\t\t\t\t\t\t\t\t char *substituted, switch_size_t len);\n+ \n+ /*!\n+  \\brief Function to evaluate an expression against a string\n+@@ -70,17 +73,27 @@ SWITCH_DECLARE(switch_status_t) switch_r\n+ */\n+ SWITCH_DECLARE(switch_status_t) switch_regex_match_partial(const char *target, const char *expression, int *partial_match);\n+ \n+-SWITCH_DECLARE(void) switch_capture_regex(switch_regex_t *re, int match_count, const char *field_data,\n+-\t\t\t\t\t\t\t\t\t\t  int *ovector, const char *var, switch_cap_callback_t callback, void *user_data);\n++SWITCH_DECLARE(void) switch_capture_regex(switch_regex_match_data_t *match_data, int match_count,\n++\t\t\t\t\t\t\t\t\t\t  const char *var, switch_cap_callback_t callback, void *user_data);\n+ \n+ SWITCH_DECLARE_NONSTD(void) switch_regex_set_var_callback(const char *var, const char *val, void *user_data);\n+ SWITCH_DECLARE_NONSTD(void) switch_regex_set_event_header_callback(const char *var, const char *val, void *user_data);\n+ \n++#define switch_match_data_safe_free(match_data)\tif (match_data) {\\\n++\t\t\t\tswitch_regex_match_free(match_data);\\\n++\t\t\t\tmatch_data = NULL;\\\n++\t\t\t}\n++\n+ #define switch_regex_safe_free(re)\tif (re) {\\\n+ \t\t\t\tswitch_regex_free(re);\\\n+ \t\t\t\tre = NULL;\\\n+ \t\t\t}\n+ \n++#define switch_regex_and_match_data_safe_free(re, match_data) {\\\n++\t\t\t\tswitch_match_data_safe_free(match_data);\\\n++\t\t\t\tswitch_regex_safe_free(re);\\\n++\t\t\t}\n++\n+ \n+ /** @} */\n+ \n+--- a/src/mod/applications/mod_abstraction/mod_abstraction.c\n++++ b/src/mod/applications/mod_abstraction/mod_abstraction.c\n+@@ -65,9 +65,9 @@ SWITCH_STANDARD_API(api_abstraction_func\n+ \n+ \t\tint proceed;\n+ \t\tswitch_regex_t *re = NULL;\n+-\t\tint ovector[30];\n++\t\tswitch_regex_match_data_t *match_data = NULL;\n+ \n+-\t\tif ((proceed = switch_regex_perform(cmd, parse, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {\n++\t\tif ((proceed = switch_regex_perform(cmd, parse, &re, &match_data))) {\n+ \t\t\tconst char *api_args = NULL;\n+ \t\t\tchar *substituted = NULL;\n+ \n+@@ -78,7 +78,7 @@ SWITCH_STANDARD_API(api_abstraction_func\n+ \t\t\t\t\tgoto end;\n+ \t\t\t\t}\n+ \t\t\t\tmemset(substituted, 0, len);\n+-\t\t\t\tswitch_perform_substitution(re, proceed, arguments, cmd , substituted, len, ovector);\n++\t\t\t\tswitch_perform_substitution(match_data, arguments, substituted, len);\n+ \t\t\t\tapi_args = substituted;\n+ \t\t\t} else {\n+ \t\t\t\tapi_args = arguments;\n+@@ -89,7 +89,7 @@ SWITCH_STANDARD_API(api_abstraction_func\n+ \t\t} else {\n+ \t\t\tswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, \"No match for API %s  (%s != %s)\\n\", api_name, parse, cmd);\n+ \t\t}\n+-\t\tswitch_regex_safe_free(re);\n++\t\tswitch_regex_and_match_data_safe_free(re, match_data);\n+ \n+ \t} else {\n+ \t\tswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, \"API %s doesn't exist inside the xml structure.  You might have forgot to reload the module after editing it\\n\", api_name);\n+--- a/src/mod/applications/mod_commands/mod_commands.c\n++++ b/src/mod/applications/mod_commands/mod_commands.c\n+@@ -2014,7 +2014,7 @@ SWITCH_STANDARD_API(replace_function)\n+ SWITCH_STANDARD_API(regex_function)\n+ {\n+ \tswitch_regex_t *re = NULL;\n+-\tint ovector[30];\n++\tswitch_regex_match_data_t *match_data = NULL;\n+ \tint argc;\n+ \tchar *mydata = NULL, *argv[4];\n+ \tsize_t len = 0;\n+@@ -2054,7 +2054,7 @@ SWITCH_STANDARD_API(regex_function)\n+ \t\tgoto error;\n+ \t}\n+ \n+-\tproceed = switch_regex_perform(argv[0], argv[1], &re, ovector, sizeof(ovector) / sizeof(ovector[0]));\n++\tproceed = switch_regex_perform(argv[0], argv[1], &re, &match_data);\n+ \n+ \tif (argc > 2) {\n+ \t\tchar *flags = \"\";\n+@@ -2069,7 +2069,7 @@ SWITCH_STANDARD_API(regex_function)\n+ \t\t\tswitch_assert(substituted);\n+ \t\t\tmemset(substituted, 0, len);\n+ \t\t\tswitch_replace_char(argv[2], '%', '$', SWITCH_FALSE);\n+-\t\t\tswitch_perform_substitution(re, proceed, argv[2], argv[0], substituted, len, ovector);\n++\t\t\tswitch_perform_substitution(match_data, argv[2], substituted, len);\n+ \n+ \t\t\tstream->write_function(stream, \"%s\", substituted);\n+ \t\t\tfree(substituted);\n+@@ -2091,7 +2091,7 @@ SWITCH_STANDARD_API(regex_function)\n+   error:\n+ \tstream->write_function(stream, \"-ERR\");\n+   ok:\n+-\tswitch_regex_safe_free(re);\n++\tswitch_regex_and_match_data_safe_free(re, match_data);\n+ \tswitch_safe_free(mydata);\n+ \treturn SWITCH_STATUS_SUCCESS;\n+ }\n+--- a/src/mod/applications/mod_dptools/mod_dptools.c\n++++ b/src/mod/applications/mod_dptools/mod_dptools.c\n+@@ -3211,16 +3211,16 @@ SWITCH_STANDARD_APP(capture_function)\n+ {\n+ \tchar *argv[3] = { 0 };\n+ \tswitch_regex_t *re = NULL;\n+-\tint ovector[30] = {0};\n++\tswitch_regex_match_data_t *match_data = NULL;\n+ \tchar *lbuf;\n+ \tint proceed;\n+ \n+ \tif (!zstr(data) && (lbuf = switch_core_session_strdup(session, data))\n+ \t\t&& switch_separate_string(lbuf, '|', argv, (sizeof(argv) / sizeof(argv[0]))) == 3) {\n+-\t\tif ((proceed = switch_regex_perform(argv[1], argv[2], &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {\n+-\t\t\tswitch_capture_regex(re, proceed, argv[1], ovector, argv[0], switch_regex_set_var_callback, session);\n++\t\tif ((proceed = switch_regex_perform(argv[1], argv[2], &re, &match_data))) {\n++\t\t\tswitch_capture_regex(match_data, proceed, argv[0], switch_regex_set_var_callback, session);\n+ \t\t}\n+-\t\tswitch_regex_safe_free(re);\n++\t\tswitch_regex_and_match_data_safe_free(re, match_data);\n+ \t} else {\n+ \t\tswitch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, \"No data specified.\\n\");\n+ \t}\n+--- a/src/mod/applications/mod_enum/mod_enum.c\n++++ b/src/mod/applications/mod_enum/mod_enum.c\n+@@ -365,7 +365,8 @@ static void parse_naptr(const ldns_rr *n\n+ \n+ \tif (service && regex && replace) {\n+ \t\tswitch_regex_t *re = NULL, *re2 = NULL;\n+-\t\tint proceed = 0, ovector[30];\n++\t\tswitch_regex_match_data_t *match_data = NULL, *match_data2 = NULL;\n++\t\tint proceed = 0;\n+ \t\tchar *substituted = NULL;\n+ \t\tchar *substituted_2 = NULL;\n+ \t\tchar *orig_uri;\n+@@ -374,17 +375,17 @@ static void parse_naptr(const ldns_rr *n\n+ \t\tint supported = 0;\n+ \t\tuint32_t len = 0;\n+ \n+-\t\tif ((proceed = switch_regex_perform(number, regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {\n++\t\tif ((proceed = switch_regex_perform(number, regex, &re, &match_data))) {\n+ \t\t\tif (strchr(regex, '(')) {\n+ \t\t\t\tlen = (uint32_t) (strlen(number) + strlen(replace) + 10) * proceed;\n+ \t\t\t\tif (!(substituted = malloc(len))) {\n+ \t\t\t\t\tswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, \"Memory Error!\\n\");\n+-\t\t\t\t\tswitch_regex_safe_free(re);\n++\t\t\t\t\tswitch_regex_and_match_data_safe_free(re, match_data);\n+ \t\t\t\t\tgoto end;\n+ \t\t\t\t}\n+ \t\t\t\tmemset(substituted, 0, len);\n+ \n+-\t\t\t\tswitch_perform_substitution(re, proceed, replace, number, substituted, len, ovector);\n++\t\t\t\tswitch_perform_substitution(match_data, replace, substituted, len);\n+ \t\t\t\torig_uri = substituted;\n+ \t\t\t} else {\n+ \t\t\t\torig_uri = replace;\n+@@ -398,7 +399,7 @@ static void parse_naptr(const ldns_rr *n\n+ \t\t\t\t\tcontinue;\n+ \t\t\t\t}\n+ \n+-\t\t\t\tif ((proceed = switch_regex_perform(uri, route->regex, &re2, ovector, sizeof(ovector) / sizeof(ovector[0])))) {\n++\t\t\t\tif ((proceed = switch_regex_perform(uri, route->regex, &re2, &match_data2))) {\n+ \t\t\t\t\tswitch_event_t *event = NULL;\n+ \n+ \t\t\t\t\tif (strchr(route->regex, '(')) {\n+@@ -406,14 +407,14 @@ static void parse_naptr(const ldns_rr *n\n+ \t\t\t\t\t\tif (!(substituted_2 = malloc(len))) {\n+ \t\t\t\t\t\t\tswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, \"Memory Error!\\n\");\n+ \t\t\t\t\t\t\tswitch_safe_free(substituted);\n+-\t\t\t\t\t\t\tswitch_regex_safe_free(re);\n+-\t\t\t\t\t\t\tswitch_regex_safe_free(re2);\n++\t\t\t\t\t\t\tswitch_regex_and_match_data_safe_free(re, match_data);\n++\t\t\t\t\t\t\tswitch_regex_and_match_data_safe_free(re2, match_data2);\n+ \t\t\t\t\t\t\tswitch_mutex_unlock(MUTEX);\n+ \t\t\t\t\t\t\tgoto end;\n+ \t\t\t\t\t\t}\n+ \t\t\t\t\t\tmemset(substituted_2, 0, len);\n+ \n+-\t\t\t\t\t\tswitch_perform_substitution(re2, proceed, route->replace, uri, substituted_2, len, ovector);\n++\t\t\t\t\t\tswitch_perform_substitution(match_data2, route->replace, substituted_2, len);\n+ \t\t\t\t\t\turi = substituted_2;\n+ \t\t\t\t\t} else {\n+ \t\t\t\t\t\turi = route->replace;\n+@@ -434,7 +435,7 @@ static void parse_naptr(const ldns_rr *n\n+ \t\t\t\t}\n+ \t\t\t\tswitch_safe_free(uri_expanded);\n+ \t\t\t\tswitch_safe_free(substituted_2);\n+-\t\t\t\tswitch_regex_safe_free(re2);\n++\t\t\t\tswitch_regex_and_match_data_safe_free(re2, match_data2);\n+ \t\t\t}\n+ \t\t\tswitch_mutex_unlock(MUTEX);\n+ \n+@@ -443,7 +444,7 @@ static void parse_naptr(const ldns_rr *n\n+ \t\t\t}\n+ \n+ \t\t\tswitch_safe_free(substituted);\n+-\t\t\tswitch_regex_safe_free(re);\n++\t\t\tswitch_regex_and_match_data_safe_free(re, match_data);\n+ \t\t}\n+ \t}\n+ \n+--- a/src/mod/applications/mod_lcr/mod_lcr.c\n++++ b/src/mod/applications/mod_lcr/mod_lcr.c\n+@@ -166,7 +166,8 @@ static void lcr_destroy(lcr_route route)\n+ static const char *do_cid(switch_memory_pool_t *pool, const char *cid, const char *number, switch_core_session_t *session)\n+ {\n+ \tswitch_regex_t *re = NULL;\n+-\tint proceed = 0, ovector[30];\n++\tswitch_regex_match_data_t *match_data = NULL;\n++\tint proceed = 0;\n+ \tchar *substituted = NULL;\n+ \tuint32_t len = 0;\n+ \tchar *src = NULL;\n+@@ -230,24 +231,24 @@ static const char *do_cid(switch_memory_\n+ \t\tswitch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, \"expanded src: %s, dst: %s\\n\", src, dst);\n+ \t}\n+ \n+-\tif ((proceed = switch_regex_perform(number, src, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {\n++\tif ((proceed = switch_regex_perform(number, src, &re, &match_data))) {\n+ \t\tlen = (uint32_t) (strlen(src) + strlen(dst) + 10) * proceed; /* guestimate size */\n+ \t\tif (!(substituted = switch_core_alloc(pool, len))) {\n+ \t\t\tswitch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, \"Memory Error!\\n\");\n+ \t\t\tgoto done;\n+ \t\t}\n+ \t\tmemset(substituted, 0, len);\n+-\t\tswitch_perform_substitution(re, proceed, dst, number, substituted, len, ovector);\n++\t\tswitch_perform_substitution(match_data, dst, substituted, len);\n+ \t} else {\n+ \t\tgoto done;\n+ \t}\n+ \n+-\tswitch_regex_safe_free(re);\n++\tswitch_regex_and_match_data_safe_free(re, match_data);\n+ \n+ \treturn substituted;\n+ \n+ done:\n+-\tswitch_regex_safe_free(re);\n++\tswitch_regex_and_match_data_safe_free(re, match_data);\n+ \tswitch_safe_free(tmp_regex);\n+ \treturn number;\n+ }\n+--- a/src/mod/applications/mod_sms/mod_sms.c\n++++ b/src/mod/applications/mod_sms/mod_sms.c\n+@@ -124,6 +124,7 @@ static int parse_exten(switch_event_t *e\n+ \tint proceed = 0;\n+ \tchar *expression_expanded = NULL, *field_expanded = NULL;\n+ \tswitch_regex_t *re = NULL;\n++\tswitch_regex_match_data_t *match_data = NULL;\n+ \tconst char *to = switch_event_get_header(event, \"to\");\n+ \tconst char *tzoff = NULL, *tzname_ = NULL;\n+ \tint offset = 0;\n+@@ -143,7 +144,6 @@ static int parse_exten(switch_event_t *e\n+ \t\tchar *do_break_a = NULL;\n+ \t\tchar *expression = NULL;\n+ \t\tconst char *field_data = NULL;\n+-\t\tint ovector[30];\n+ \t\tswitch_bool_t anti_action = SWITCH_TRUE;\n+ \t\tbreak_t do_break_i = BREAK_ON_FALSE;\n+ \t\tint time_match;\n+@@ -214,7 +214,7 @@ static int parse_exten(switch_event_t *e\n+ \t\t\t\tfield_data = \"\";\n+ \t\t\t}\n+ \n+-\t\t\tif ((proceed = switch_regex_perform(field_data, expression, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {\n++\t\t\tif ((proceed = switch_regex_perform(field_data, expression, &re, &match_data))) {\n+ \t\t\t\tswitch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG,\n+ \t\t\t\t\t\t\t\t  \"Chatplan: %s Regex (PASS) [%s] %s(%s) =~ /%s/ break=%s\\n\",\n+ \t\t\t\t\t\t\t\t  to, exten_name, field, field_data, expression, do_break_a ? do_break_a : \"on-false\");\n+@@ -271,7 +271,7 @@ static int parse_exten(switch_event_t *e\n+ \t\t} else {\n+ \t\t\tif (field && strchr(expression, '(')) {\n+ \t\t\t\tswitch_event_add_header_string(event, SWITCH_STACK_BOTTOM, \"DP_MATCH\", NULL);\n+-\t\t\t\tswitch_capture_regex(re, proceed, field_data, ovector, \"DP_MATCH\", switch_regex_set_event_header_callback, event);\n++\t\t\t\tswitch_capture_regex(match_data, proceed, \"DP_MATCH\", switch_regex_set_event_header_callback, event);\n+ \t\t\t}\n+ \n+ \t\t\tfor (xaction = switch_xml_child(xcond, \"action\"); xaction; xaction = xaction->next) {\n+@@ -297,7 +297,7 @@ static int parse_exten(switch_event_t *e\n+ \t\t\t\t\t\tabort();\n+ \t\t\t\t\t}\n+ \t\t\t\t\tmemset(substituted, 0, len);\n+-\t\t\t\t\tswitch_perform_substitution(re, proceed, data, field_data, substituted, len, ovector);\n++\t\t\t\t\tswitch_perform_substitution(match_data, data, substituted, len);\n+ \t\t\t\t\tapp_data = substituted;\n+ \t\t\t\t} else {\n+ \t\t\t\t\tapp_data = data;\n+@@ -326,7 +326,7 @@ static int parse_exten(switch_event_t *e\n+ \t\t\t\tswitch_safe_free(substituted);\n+ \t\t\t}\n+ \t\t}\n+-\t\tswitch_regex_safe_free(re);\n++\t\tswitch_regex_and_match_data_safe_free(re, match_data);\n+ \n+ \t\tif (((anti_action == SWITCH_FALSE && do_break_i == BREAK_ON_TRUE) ||\n+ \t\t\t (anti_action == SWITCH_TRUE && do_break_i == BREAK_ON_FALSE)) || do_break_i == BREAK_ALWAYS) {\n+@@ -335,7 +335,7 @@ static int parse_exten(switch_event_t *e\n+ \t}\n+ \n+   done:\n+-\tswitch_regex_safe_free(re);\n++\tswitch_regex_and_match_data_safe_free(re, match_data);\n+ \tswitch_safe_free(field_expanded);\n+ \tswitch_safe_free(expression_expanded);\n+ \treturn proceed;\n+--- a/src/mod/applications/mod_translate/mod_translate.c\n++++ b/src/mod/applications/mod_translate/mod_translate.c\n+@@ -117,7 +117,8 @@ static void translate_number(char *numbe\n+ \ttranslate_rule_t *hi = NULL;\n+ \ttranslate_rule_t *rule = NULL;\n+ \tswitch_regex_t *re = NULL;\n+-\tint proceed = 0, ovector[30];\n++\tswitch_regex_match_data_t *match_data = NULL;\n++\tint proceed = 0;\n+ \tchar *substituted = NULL, *subbed = NULL;\n+ \tuint32_t len = 0;\n+ \n+@@ -136,17 +137,17 @@ static void translate_number(char *numbe\n+ \n+ \tfor (rule = hi; rule; rule = rule->next) {\n+ \t\tswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, \"%s =~ /%s/\\n\", number, rule->regex);\n+-\t\tif ((proceed = switch_regex_perform(number, rule->regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {\n++\t\tif ((proceed = switch_regex_perform(number, rule->regex, &re, &match_data))) {\n+ \t\t\tlen = (uint32_t) (strlen(number) + strlen(rule->replace) + 10) * proceed;\n+ \t\t\tif (!(substituted = malloc(len))) {\n+ \t\t\t\tswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, \"Memory Error!\\n\");\n+-\t\t\t\tswitch_regex_safe_free(re);\n++\t\t\t\tswitch_regex_and_match_data_safe_free(re, match_data);\n+ \t\t\t\tgoto end;\n+ \t\t\t}\n+ \n+ \t\t\tmemset(substituted, 0, len);\n+ \n+-\t\t\tswitch_perform_substitution(re, proceed, rule->replace, number, substituted, len, ovector);\n++\t\t\tswitch_perform_substitution(match_data, rule->replace, substituted, len);\n+ \n+ \t\t\tif ((switch_string_var_check_const(substituted) || switch_string_has_escaped_data(substituted))) {\n+ \t\t\t\tswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, \"perform variable expansion\\n\");\n+@@ -169,7 +170,7 @@ static void translate_number(char *numbe\n+ \t\t\t\tswitch_safe_free(subbed);\n+ \t\t\t}\n+ \n+-\t\t\tswitch_regex_safe_free(re);\n++\t\t\tswitch_regex_and_match_data_safe_free(re, match_data);\n+ \t\t\tbreak;\n+ \t\t}\n+ \t}\n+--- a/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c\n++++ b/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c\n+@@ -170,9 +170,8 @@ SWITCH_STANDARD_DIALPLAN(asterisk_dialpl\n+ \t\t\t\tchar *expression = NULL, expression_buf[1024] = { 0 };\n+ \t\t\t\tchar substituted[2048] = \"\";\n+ \t\t\t\tconst char *field_data = caller_profile->destination_number;\n+-\t\t\t\tint proceed = 0;\n+ \t\t\t\tswitch_regex_t *re = NULL;\n+-\t\t\t\tint ovector[30] = { 0 };\n++\t\t\t\tswitch_regex_match_data_t *match_data = NULL;\n+ \t\t\t\tchar *cid = NULL;\n+ \n+ \t\t\t\texpression = expression_buf;\n+@@ -221,8 +220,8 @@ SWITCH_STANDARD_DIALPLAN(asterisk_dialpl\n+ \t\t\t\t\t\tfield_data = \"\";\n+ \t\t\t\t\t}\n+ \n+-\t\t\t\t\tif (!(proceed = switch_regex_perform(field_data, expression, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {\n+-\t\t\t\t\t\tswitch_regex_safe_free(re);\n++\t\t\t\t\tif (!(switch_regex_perform(field_data, expression, &re, &match_data))) {\n++\t\t\t\t\t\tswitch_regex_and_match_data_safe_free(re, match_data);\n+ \t\t\t\t\t\tswitch_safe_free(field_expanded);\n+ \t\t\t\t\t\tcontinue;\n+ \t\t\t\t\t}\n+@@ -267,11 +266,11 @@ SWITCH_STANDARD_DIALPLAN(asterisk_dialpl\n+ \t\t\t\t}\n+ \n+ \t\t\t\tif (strchr(expression, '(')) {\n+-\t\t\t\t\tswitch_perform_substitution(re, proceed, argument, field_data, substituted, sizeof(substituted), ovector);\n++\t\t\t\t\tswitch_perform_substitution(match_data, argument, substituted, sizeof(substituted));\n+ \t\t\t\t\targument = substituted;\n+ \t\t\t\t}\n+ \n+-\t\t\t\tswitch_regex_safe_free(re);\n++\t\t\t\tswitch_regex_and_match_data_safe_free(re, match_data);\n+ \n+ \t\t\t\tif (!extension) {\n+ \t\t\t\t\tif (zstr(field_data)) {\n+--- a/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c\n++++ b/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c\n+@@ -103,6 +103,7 @@ static int parse_exten(switch_core_sessi\n+ \tint proceed = 0, save_proceed = 0;\n+ \tchar *expression_expanded = NULL, *field_expanded = NULL;\n+ \tswitch_regex_t *re = NULL, *save_re = NULL;\n++\tswitch_regex_match_data_t *match_data = NULL, *save_match_data = NULL;\n+ \tint offset = 0;\n+ \tconst char *tmp, *tzoff = NULL, *tzname_ = NULL, *req_nesta = NULL;\n+ \tchar nbuf[128] = \"\";\n+@@ -170,7 +171,6 @@ static int parse_exten(switch_core_sessi\n+ \t\tchar *expression = NULL, *save_expression = NULL, *save_field_data = NULL;\n+ \t\tchar *regex_rule = NULL;\n+ \t\tconst char *field_data = NULL;\n+-\t\tint ovector[30];\n+ \t\tswitch_bool_t anti_action = SWITCH_TRUE;\n+ \t\tbreak_t do_break_i = BREAK_ON_FALSE;\n+ \t\tint time_match;\n+@@ -292,7 +292,7 @@ static int parse_exten(switch_core_sessi\n+ \t\t\t\t\t\tfield_data = \"\";\n+ \t\t\t\t\t}\n+ \n+-\t\t\t\t\tif ((proceed = switch_regex_perform(field_data, expression, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {\n++\t\t\t\t\tif ((proceed = switch_regex_perform(field_data, expression, &re, &match_data))) {\n+ \t\t\t\t\t\tif ( switch_core_test_flag(SCF_DIALPLAN_TIMESTAMPS) ) {\n+ \t\t\t\t\t\t\tswitch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,\n+ \t\t\t\t\t\t\t\t\t\t  \"%sDialplan: %s Regex (PASS) [%s] %s(%s) =~ /%s/ match=%s\\n\", space,\n+@@ -344,21 +344,22 @@ static int parse_exten(switch_core_sessi\n+ \t\t\t\t\tswitch_snprintf(var, sizeof(var), \"DP_REGEX_MATCH_%d\", total);\n+ \n+ \t\t\t\t\tswitch_channel_set_variable(channel, var, NULL);\n+-\t\t\t\t\tswitch_capture_regex(re, proceed, field_data, ovector, var, switch_regex_set_var_callback, session);\n++\t\t\t\t\tswitch_capture_regex(match_data, proceed, var, switch_regex_set_var_callback, session);\n+ \n+ \t\t\t\t\tswitch_safe_free(save_expression);\n+ \t\t\t\t\tswitch_safe_free(save_field_data);\n+-\t\t\t\t\tswitch_regex_safe_free(save_re);\n++\t\t\t\t\tswitch_regex_and_match_data_safe_free(save_re, save_match_data);\n+ \n+ \t\t\t\t\tsave_expression = strdup(expression);\n+ \t\t\t\t\tsave_field_data = strdup(field_data);\n+ \t\t\t\t\tsave_re = re;\n++\t\t\t\t\tsave_match_data = match_data;\n+ \t\t\t\t\tsave_proceed = proceed;\n+ \n+ \t\t\t\t\tre = NULL;\n+ \t\t\t\t}\n+ \n+-\t\t\t\tswitch_regex_safe_free(re);\n++\t\t\t\tswitch_regex_and_match_data_safe_free(re, match_data);\n+ \n+ \t\t\t\tswitch_safe_free(field_expanded);\n+ \t\t\t\tif (expression == expression_expanded) expression = NULL;\n+@@ -406,7 +407,7 @@ static int parse_exten(switch_core_sessi\n+ \t\t\t\t\tfield_data = \"\";\n+ \t\t\t\t}\n+ \n+-\t\t\t\tif ((proceed = switch_regex_perform(field_data, expression, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {\n++\t\t\t\tif ((proceed = switch_regex_perform(field_data, expression, &re, &match_data))) {\n+ \t\t\t\t\tif ( switch_core_test_flag(SCF_DIALPLAN_TIMESTAMPS) ) {\n+ \t\t\t\t\t\tswitch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,\n+ \t\t\t\t\t\t\t\t\t  \"%sDialplan: %s Regex (PASS) [%s] %s(%s) =~ /%s/ break=%s\\n\", space,\n+@@ -446,7 +447,9 @@ static int parse_exten(switch_core_sessi\n+ \n+ \t\tif (save_re) {\n+ \t\t\tre = save_re;\n++\t\t\tmatch_data = save_match_data;\n+ \t\t\tsave_re = NULL;\n++\t\t\tsave_match_data = NULL;\n+ \n+ \t\t\texpression = expression_expanded = save_expression;\n+ \t\t\tsave_expression = NULL;\n+@@ -506,7 +509,7 @@ static int parse_exten(switch_core_sessi\n+ \t\t} else {\n+ \t\t\tif (field && expression && strchr(expression, '(')) {\n+ \t\t\t\tswitch_channel_set_variable(channel, \"DP_MATCH\", NULL);\n+-\t\t\t\tswitch_capture_regex(re, proceed, field_data, ovector, \"DP_MATCH\", switch_regex_set_var_callback, session);\n++\t\t\t\tswitch_capture_regex(match_data, proceed, \"DP_MATCH\", switch_regex_set_var_callback, session);\n+ \t\t\t}\n+ \n+ \t\t\tfor (xaction = switch_xml_child(xcond, \"action\"); xaction; xaction = xaction->next) {\n+@@ -534,7 +537,7 @@ static int parse_exten(switch_core_sessi\n+ \t\t\t\t\t\tgoto done;\n+ \t\t\t\t\t}\n+ \t\t\t\t\tmemset(substituted, 0, len);\n+-\t\t\t\t\tswitch_perform_substitution(re, proceed, data, field_data, substituted, len, ovector);\n++\t\t\t\t\tswitch_perform_substitution(match_data, data, substituted, len);\n+ \t\t\t\t\tapp_data = substituted;\n+ \t\t\t\t} else {\n+ \t\t\t\t\tapp_data = data;\n+@@ -571,7 +574,7 @@ static int parse_exten(switch_core_sessi\n+ \t\t\t\tswitch_safe_free(substituted);\n+ \t\t\t}\n+ \t\t}\n+-\t\tswitch_regex_safe_free(re);\n++\t\tswitch_regex_and_match_data_safe_free(re, match_data);\n+ \n+ \t\tif (((anti_action == SWITCH_FALSE && do_break_i == BREAK_ON_TRUE) ||\n+ \t\t\t (anti_action == SWITCH_TRUE && do_break_i == BREAK_ON_FALSE)) || do_break_i == BREAK_ALWAYS) {\n+@@ -591,7 +594,7 @@ static int parse_exten(switch_core_sessi\n+ \t}\n+ \n+   done:\n+-\tswitch_regex_safe_free(re);\n++\tswitch_regex_and_match_data_safe_free(re, match_data);\n+ \tswitch_safe_free(field_expanded);\n+ \tswitch_safe_free(expression_expanded);\n+ \n+--- a/src/mod/endpoints/mod_sofia/sofia_glue.c\n++++ b/src/mod/endpoints/mod_sofia/sofia_glue.c\n+@@ -912,7 +912,7 @@ char *sofia_glue_get_extra_headers(switc\n+ \tswitch_event_header_t *hi = NULL;\n+ \tconst char *exclude_regex = NULL;\n+ \tswitch_regex_t *re = NULL;\n+-\tint ovector[30] = {0};\n++\tswitch_regex_match_data_t *match_data = NULL;\n+ \n+ \texclude_regex = switch_channel_get_variable(channel, \"exclude_outgoing_extra_header\");\n+ \tSWITCH_STANDARD_STREAM(stream);\n+@@ -926,13 +926,13 @@ char *sofia_glue_get_extra_headers(switc\n+ \t\t\t}\n+ \n+ \t\t\tif (!strncasecmp(name, prefix, strlen(prefix))) {\n+-\t\t\t\tif ( !exclude_regex || !(/*proceed*/ switch_regex_perform(name, exclude_regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {\n++\t\t\t\tif ( !exclude_regex || !(/*proceed*/ switch_regex_perform(name, exclude_regex, &re, &match_data))) {\n+ \t\t\t\t\tconst char *hname = name + strlen(prefix);\n+ \t\t\t\t\tstream.write_function(&stream, \"%s: %s\\r\\n\", hname, value);\n+ \t\t\t\t} else {\n+ \t\t\t\t\tswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, \"Ignoring Extra Header [%s] , matches exclude_outgoing_extra_header [%s]\\n\", name, exclude_regex);\n+-\t\t\t\t\tswitch_regex_safe_free(re);\n+ \t\t\t\t}\n++\t\t\t\tswitch_regex_and_match_data_safe_free(re, match_data);\n+ \t\t\t}\n+ \t\t}\n+ \t\tswitch_channel_variable_last(channel);\n+--- a/src/mod/endpoints/mod_verto/mod_verto.c\n++++ b/src/mod/endpoints/mod_verto/mod_verto.c\n+@@ -1883,22 +1883,22 @@ authed:\n+ \tif (vhost->rewrites) {\n+ \t\tswitch_event_header_t *rule = vhost->rewrites->headers;\n+ \t\tswitch_regex_t *re = NULL;\n+-\t\tint ovector[30];\n++\t\tswitch_regex_match_data_t *match_data = NULL;\n+ \t\tint proceed;\n+ \n+ \t\twhile(rule) {\n+ \t\t\tchar *expression = rule->name;\n+ \n+-\t\t\tif ((proceed = switch_regex_perform(request->uri, expression, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {\n++\t\t\tif ((proceed = switch_regex_perform(request->uri, expression, &re, &match_data))) {\n+ \t\t\t\tswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,\n+ \t\t\t\t\t\t\t\t  \"%d request [%s] matched expr [%s]\\n\", proceed, request->uri, expression);\n+ \t\t\t\trequest->uri = rule->value;\n+-\t\t\t\tswitch_regex_safe_free(re);\n++\t\t\t\tswitch_regex_and_match_data_safe_free(re, match_data);\n+ \t\t\t\tbreak;\n+ \t\t\t}\n+ \n+ \t\t\trule = rule->next;\n+-\t\t\tswitch_regex_safe_free(re);\n++\t\t\tswitch_regex_and_match_data_safe_free(re, match_data);\n+ \t\t}\n+ \t}\n+ \n+--- a/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c\n++++ b/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c\n+@@ -250,9 +250,9 @@ static void event_handler(switch_event_t\n+ \n+ \t\t\t\t\t\tif (*hp->value == '/') {\n+ \t\t\t\t\t\t\tswitch_regex_t *re = NULL;\n+-\t\t\t\t\t\t\tint ovector[30];\n+-\t\t\t\t\t\t\tcmp = !!switch_regex_perform(hval, comp_to, &re, ovector, sizeof(ovector) / sizeof(ovector[0]));\n+-\t\t\t\t\t\t\tswitch_regex_safe_free(re);\n++\t\t\t\t\t\t\tswitch_regex_match_data_t *match_data = NULL;\n++\t\t\t\t\t\t\tcmp = !!switch_regex_perform(hval, comp_to, &re, &match_data);\n++\t\t\t\t\t\t\tswitch_regex_and_match_data_safe_free(re, match_data);\n+ \t\t\t\t\t\t} else {\n+ \t\t\t\t\t\t\tcmp = !strcasecmp(hval, comp_to);\n+ \t\t\t\t\t\t}\n+--- a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c\n++++ b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c\n+@@ -350,9 +350,9 @@ static void event_handler(switch_event_t\n+ \n+ \t\t\t\t\t\tif (*hp->value == '/') {\n+ \t\t\t\t\t\t\tswitch_regex_t *re = NULL;\n+-\t\t\t\t\t\t\tint ovector[30];\n+-\t\t\t\t\t\t\tcmp = !!switch_regex_perform(hval, comp_to, &re, ovector, sizeof(ovector) / sizeof(ovector[0]));\n+-\t\t\t\t\t\t\tswitch_regex_safe_free(re);\n++\t\t\t\t\t\t\tswitch_regex_match_data_t *match_data = NULL;\n++\t\t\t\t\t\t\tcmp = !!switch_regex_perform(hval, comp_to, &re, &match_data);\n++\t\t\t\t\t\t\tswitch_regex_and_match_data_safe_free(re, match_data);\n+ \t\t\t\t\t\t} else {\n+ \t\t\t\t\t\t\tcmp = !strcasecmp(hval, comp_to);\n+ \t\t\t\t\t\t}\n+--- a/src/mod/event_handlers/mod_rayo/Makefile.am\n++++ b/src/mod/event_handlers/mod_rayo/Makefile.am\n+@@ -8,12 +8,12 @@ IKS_LA=$(IKS_BUILDDIR)/src/libiksemel.la\n+ noinst_LTLIBRARIES = librayomod.la\n+ librayomod_la_SOURCES = mod_rayo.c iks_helpers.c nlsml.c rayo_components.c rayo_cpa_component.c rayo_cpa_detector.c rayo_elements.c rayo_fax_components.c\n+ librayomod_la_SOURCES += rayo_input_component.c rayo_output_component.c rayo_prompt_component.c rayo_record_component.c sasl.c srgs.c xmpp_streams.c rayo_exec_component.c\n+-librayomod_la_CFLAGS = $(AM_CFLAGS) -I$(switch_builddir)/libs/iksemel/include $(PCRE_CFLAGS)\n++librayomod_la_CFLAGS = $(AM_CFLAGS) -I$(switch_builddir)/libs/iksemel/include $(PCRE2_CFLAGS)\n+ \n+ mod_LTLIBRARIES = mod_rayo.la\n+ mod_rayo_la_SOURCES  = \n+-mod_rayo_la_CFLAGS   = $(AM_CFLAGS) -I$(IKS_DIR)/include $(PCRE_CFLAGS)\n+-mod_rayo_la_LIBADD   = $(switch_builddir)/libfreeswitch.la $(IKS_LA) $(PCRE_LIBS) librayomod.la\n++mod_rayo_la_CFLAGS   = $(AM_CFLAGS) -I$(IKS_DIR)/include $(PCRE2_CFLAGS)\n++mod_rayo_la_LIBADD   = $(switch_builddir)/libfreeswitch.la $(IKS_LA) $(PCRE2_LIBS) librayomod.la\n+ mod_rayo_la_LDFLAGS  = -avoid-version -module -no-undefined -shared\n+ \n+ BUILT_SOURCES=$(IKS_LA)\n+@@ -25,19 +25,19 @@ $(IKS_LA): $(IKS_BUILDDIR) $(IKS_DIR) $(\n+ noinst_PROGRAMS = test/test_iks test/test_nlsml test/test_srgs\n+ \n+ test_test_iks_SOURCES = test/test_iks.c\n+-test_test_iks_CFLAGS = $(AM_CFLAGS) -I. -I$(switch_builddir)/libs/iksemel/include $(PCRE_CFLAGS) -DSWITCH_TEST_BASE_DIR_FOR_CONF=\\\"${abs_builddir}/test\\\" -DSWITCH_TEST_BASE_DIR_OVERRIDE=\\\"${abs_builddir}/test\\\"\n++test_test_iks_CFLAGS = $(AM_CFLAGS) -I. -I$(switch_builddir)/libs/iksemel/include $(PCRE2_CFLAGS) -DSWITCH_TEST_BASE_DIR_FOR_CONF=\\\"${abs_builddir}/test\\\" -DSWITCH_TEST_BASE_DIR_OVERRIDE=\\\"${abs_builddir}/test\\\"\n+ test_test_iks_LDFLAGS = $(AM_LDFLAGS) -avoid-version -no-undefined $(freeswitch_LDFLAGS) $(switch_builddir)/libfreeswitch.la $(CORE_LIBS) $(APR_LIBS)\n+-test_test_iks_LDADD = librayomod.la $(IKS_LA) $(PCRE_LIBS) $(switch_builddir)/libfreeswitch.la\n++test_test_iks_LDADD = librayomod.la $(IKS_LA) $(PCRE2_LIBS) $(switch_builddir)/libfreeswitch.la\n+ \n+ test_test_nlsml_SOURCES = test/test_nlsml.c\n+-test_test_nlsml_CFLAGS = $(AM_CFLAGS) -I. -I$(switch_builddir)/libs/iksemel/include $(PCRE_CFLAGS) -DSWITCH_TEST_BASE_DIR_FOR_CONF=\\\"${abs_builddir}/test\\\" -DSWITCH_TEST_BASE_DIR_OVERRIDE=\\\"${abs_builddir}/test\\\"\n++test_test_nlsml_CFLAGS = $(AM_CFLAGS) -I. -I$(switch_builddir)/libs/iksemel/include $(PCRE2_CFLAGS) -DSWITCH_TEST_BASE_DIR_FOR_CONF=\\\"${abs_builddir}/test\\\" -DSWITCH_TEST_BASE_DIR_OVERRIDE=\\\"${abs_builddir}/test\\\"\n+ test_test_nlsml_LDFLAGS = $(AM_LDFLAGS) -avoid-version -no-undefined $(freeswitch_LDFLAGS) $(switch_builddir)/libfreeswitch.la $(CORE_LIBS) $(APR_LIBS)\n+-test_test_nlsml_LDADD = librayomod.la $(IKS_LA) $(PCRE_LIBS) $(switch_builddir)/libfreeswitch.la\n++test_test_nlsml_LDADD = librayomod.la $(IKS_LA) $(PCRE2_LIBS) $(switch_builddir)/libfreeswitch.la\n+ \n+ test_test_srgs_SOURCES = test/test_srgs.c\n+-test_test_srgs_CFLAGS = $(AM_CFLAGS) -I. -I$(switch_builddir)/libs/iksemel/include $(PCRE_CFLAGS) -DSWITCH_TEST_BASE_DIR_FOR_CONF=\\\"${abs_builddir}/test\\\" -DSWITCH_TEST_BASE_DIR_OVERRIDE=\\\"${abs_builddir}/test\\\"\n++test_test_srgs_CFLAGS = $(AM_CFLAGS) -I. -I$(switch_builddir)/libs/iksemel/include $(PCRE2_CFLAGS) -DSWITCH_TEST_BASE_DIR_FOR_CONF=\\\"${abs_builddir}/test\\\" -DSWITCH_TEST_BASE_DIR_OVERRIDE=\\\"${abs_builddir}/test\\\"\n+ test_test_srgs_LDFLAGS = $(AM_LDFLAGS) -avoid-version -no-undefined $(freeswitch_LDFLAGS) $(switch_builddir)/libfreeswitch.la $(CORE_LIBS) $(APR_LIBS)\n+-test_test_srgs_LDADD = librayomod.la $(IKS_LA) $(PCRE_LIBS) $(switch_builddir)/libfreeswitch.la\n++test_test_srgs_LDADD = librayomod.la $(IKS_LA) $(PCRE2_LIBS) $(switch_builddir)/libfreeswitch.la\n+ \n+ \n+ TESTS = $(noinst_PROGRAMS)\n+--- a/src/mod/event_handlers/mod_rayo/srgs.c\n++++ b/src/mod/event_handlers/mod_rayo/srgs.c\n+@@ -28,7 +28,8 @@\n+  */\n+ #include <switch.h>\n+ #include <iksemel.h>\n+-#include <pcre.h>\n++#define PCRE2_CODE_UNIT_WIDTH 8\n++#include <pcre2.h>\n+ \n+ #include \"srgs.h\"\n+ \n+@@ -179,7 +180,7 @@ struct srgs_grammar {\n+ \t/** root rule */\n+ \tstruct srgs_node *root_rule;\n+ \t/** compiled grammar regex */\n+-\tpcre *compiled_regex;\n++\tpcre2_code *compiled_regex;\n+ \t/** grammar in regex format */\n+ \tchar *regex;\n+ \t/** grammar in JSGF format */\n+@@ -846,7 +847,7 @@ static void srgs_grammar_destroy(struct\n+ {\n+ \tswitch_memory_pool_t *pool = grammar->pool;\n+ \tif (grammar->compiled_regex) {\n+-\t\tpcre_free(grammar->compiled_regex);\n++\t\tpcre2_code_free(grammar->compiled_regex);\n+ \t}\n+ \tif (grammar->jsgf_file_name) {\n+ \t\tswitch_file_remove(grammar->jsgf_file_name, pool);\n+@@ -986,7 +987,7 @@ static int create_regexes(struct srgs_gr\n+ \t\t\t\t\tcase '+':\n+ \t\t\t\t\tcase '(':\n+ \t\t\t\t\tcase ')':\n+-\t\t\t\t\t\t/* escape special PCRE regex characters */\n++\t\t\t\t\t\t/* escape special PCRE2 regex characters */\n+ \t\t\t\t\t\tstream->write_function(stream, \"\\\\%c\", node->value.string[i]);\n+ \t\t\t\t\t\tbreak;\n+ \t\t\t\t\tdefault:\n+@@ -1082,10 +1083,10 @@ static int create_regexes(struct srgs_gr\n+ /**\n+  * Compile regex\n+  */\n+-static pcre *get_compiled_regex(struct srgs_grammar *grammar)\n++static pcre2_code *get_compiled_regex(struct srgs_grammar *grammar)\n+ {\n+-\tint erroffset = 0;\n+-\tconst char *errptr = \"\";\n++\tPCRE2_SIZE erroffset = 0;\n++\tint errcode = 0;\n+ \tint options = 0;\n+ \tconst char *regex;\n+ \n+@@ -1096,7 +1097,7 @@ static pcre *get_compiled_regex(struct s\n+ \n+ \tswitch_mutex_lock(grammar->mutex);\n+ \tif (!grammar->compiled_regex && (regex = srgs_grammar_to_regex(grammar))) {\n+-\t\tif (!(grammar->compiled_regex = pcre_compile(regex, options, &errptr, &erroffset, NULL))) {\n++\t\tif (!(grammar->compiled_regex = pcre2_compile((PCRE2_SPTR)regex, PCRE2_ZERO_TERMINATED, options, &errcode, &erroffset, NULL))) {\n+ \t\t\tswitch_log_printf(SWITCH_CHANNEL_UUID_LOG(grammar->uuid), SWITCH_LOG_WARNING, \"Failed to compile grammar regex: %s\\n\", regex);\n+ \t\t}\n+ \t}\n+@@ -1225,7 +1226,6 @@ struct srgs_grammar *srgs_parse(struct s\n+ }\n+ \n+ #define MAX_INPUT_SIZE 128\n+-#define OVECTOR_SIZE MAX_TAGS\n+ #define WORKSPACE_SIZE 1024\n+ \n+ /**\n+@@ -1234,9 +1234,9 @@ struct srgs_grammar *srgs_parse(struct s\n+  * @param input the input to check\n+  * @return true if end of match (no more input can be added)\n+  */\n+-static int is_match_end(pcre *compiled_regex, const char *input)\n++static int is_match_end(pcre2_code *compiled_regex, const char *input)\n+ {\n+-\tint ovector[OVECTOR_SIZE];\n++\tpcre2_match_data *match_data;\n+ \tint input_size = strlen(input);\n+ \tchar search_input[MAX_INPUT_SIZE + 2];\n+ \tconst char *search_set = \"0123456789#*ABCD\";\n+@@ -1257,13 +1257,15 @@ static int is_match_end(pcre *compiled_r\n+ \t\t\tsearch = search_set;\n+ \t\t}\n+ \t\tsearch_input[input_size] = *search++;\n+-\t\tresult = pcre_exec(compiled_regex, NULL, search_input, input_size + 1, 0, PCRE_PARTIAL,\n+-\t\t\tovector, sizeof(ovector) / sizeof(ovector[0]));\n++\t\tmatch_data = pcre2_match_data_create_from_pattern(compiled_regex, NULL);\n++\t\tresult = pcre2_match(compiled_regex, (PCRE2_SPTR)search_input, input_size + 1, 0,\n++\t\t\t\t     PCRE2_PARTIAL_SOFT, match_data, 0);\n++\t\tpcre2_match_data_free(match_data);\n+ \t\tif (result > 0) {\n+ \t\t\tswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, \"not match end\\n\");\n+ \t\t\treturn 0;\n+ \t\t}\n+-\t\tif (result == PCRE_ERROR_PARTIAL) {\n++\t\tif (result == PCRE2_ERROR_PARTIAL) {\n+ \t\t\tswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, \"partial match possible - not match end\\n\");\n+ \t\t\treturn 0;\n+ \t\t}\n+@@ -1282,8 +1284,8 @@ static int is_match_end(pcre *compiled_r\n+ enum srgs_match_type srgs_grammar_match(struct srgs_grammar *grammar, const char *input, const char **interpretation)\n+ {\n+ \tint result = 0;\n+-\tint ovector[OVECTOR_SIZE];\n+-\tpcre *compiled_regex;\n++\tpcre2_code *compiled_regex;\n++\tpcre2_match_data *match_data;\n+ \n+ \t*interpretation = NULL;\n+ \n+@@ -1298,8 +1300,11 @@ enum srgs_match_type srgs_grammar_match(\n+ \tif (!(compiled_regex = get_compiled_regex(grammar))) {\n+ \t\treturn SMT_NO_MATCH;\n+ \t}\n+-\tresult = pcre_exec(compiled_regex, NULL, input, strlen(input), 0, PCRE_PARTIAL,\n+-\t\tovector, OVECTOR_SIZE);\n++\n++\tmatch_data = pcre2_match_data_create_from_pattern(compiled_regex, NULL);\n++\n++\tresult = pcre2_match(compiled_regex, (PCRE2_SPTR)input, strlen(input), 0, PCRE2_PARTIAL_SOFT,\n++\t\t\t     match_data, NULL);\n+ \n+ \tswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, \"match = %i\\n\", result);\n+ \tif (result > 0) {\n+@@ -1310,24 +1315,33 @@ enum srgs_match_type srgs_grammar_match(\n+ \t\t/* find matching instance... */\n+ \t\tfor (i = 1; i <= grammar->tag_count; i++) {\n+ \t\t\tchar substring_name[16] = { 0 };\n++\t\t\tPCRE2_SIZE buffer_size = MAX_INPUT_SIZE + 1;\n+ \t\t\tbuffer[0] = '\\0';\n+ \t\t\tsnprintf(substring_name, 16, \"tag%d\", i);\n+-\t\t\tif (pcre_copy_named_substring(compiled_regex, input, ovector, result, substring_name, buffer, MAX_INPUT_SIZE) != PCRE_ERROR_NOSUBSTRING && !zstr_buf(buffer)) {\n++\t\t\tif (pcre2_substring_copy_byname(match_data, (PCRE2_SPTR)substring_name, (PCRE2_UCHAR *)buffer, &buffer_size) != PCRE2_ERROR_NOSUBSTRING && !zstr_buf(buffer)) {\n+ \t\t\t\t*interpretation = grammar->tags[i];\n+ \t\t\t\tbreak;\n+ \t\t\t}\n+ \t\t}\n+ \n+ \t\tif (is_match_end(compiled_regex, input)) {\n+-\t\t\treturn SMT_MATCH_END;\n++\t\t\tresult = SMT_MATCH_END;\n++\t\t\tgoto exit;\n+ \t\t}\n+-\t\treturn SMT_MATCH;\n++\t\tresult = SMT_MATCH;\n++\t\tgoto exit;\n+ \t}\n+-\tif (result == PCRE_ERROR_PARTIAL) {\n+-\t\treturn SMT_MATCH_PARTIAL;\n++\n++\tif (result == PCRE2_ERROR_PARTIAL) {\n++\t\tresult = SMT_MATCH_PARTIAL;\n++\t\tgoto exit;\n+ \t}\n+ \n+-\treturn SMT_NO_MATCH;\n++\tresult = SMT_NO_MATCH;\n++exit:\n++\tpcre2_match_data_free(match_data);\n++\n++\treturn result;\n+ }\n+ \n+ /**\n+--- a/src/mod/languages/mod_managed/freeswitch_managed.h\n++++ b/src/mod/languages/mod_managed/freeswitch_managed.h\n+@@ -135,7 +135,13 @@ struct sqlite3 {\n+ struct switch_ivr_digit_stream {\n+ \tchar foo[];\n+ };\n+-struct real_pcre {\n++struct real_pcre2 {\n++\tchar foo[];\n++};\n++struct pcre2_real_match_data_8 {\n++\tchar foo[];\n++};\n++struct pcre2_real_compile_context_8 {\n+ \tchar foo[];\n+ };\n+ struct HashElem {\n+--- a/src/mod/languages/mod_v8/include/fspcre.hpp\n++++ b/src/mod/languages/mod_v8/include/fspcre.hpp\n+@@ -46,9 +46,9 @@ class FSPCRE : public JSBase\n+ {\n+ private:\n+ \tswitch_regex_t *_re;\n++\tswitch_regex_match_data_t *_match_data;\n+ \tchar *_str;\n+ \tint _proceed;\n+-\tint _ovector[30];\n+ \tint _freed;\n+ \n+ \tvoid Init();\n+--- a/src/mod/languages/mod_v8/src/fseventhandler.cpp\n++++ b/src/mod/languages/mod_v8/src/fseventhandler.cpp\n+@@ -139,9 +139,10 @@ void FSEventHandler::QueueEvent(switch_e\n+ \n+ \t\t\t\t\tif (*hp->value == '/') {\n+ \t\t\t\t\t\tswitch_regex_t *re = NULL;\n++\t\t\t\t\t\tswitch_regex_match_data_t *match_data = NULL;\n+ \t\t\t\t\t\tint ovector[30];\n+-\t\t\t\t\t\tcmp = !!switch_regex_perform(hval, comp_to, &re, ovector, sizeof(ovector) / sizeof(ovector[0]));\n+-\t\t\t\t\t\tswitch_regex_safe_free(re);\n++\t\t\t\t\t\tcmp = !!switch_regex_perform(hval, comp_to, &re, &match_data);\n++\t\t\t\t\t\tswitch_regex_and_match_data_safe_free(re, match_data);\n+ \t\t\t\t\t} else {\n+ \t\t\t\t\t\tcmp = !strcasecmp(hval, comp_to);\n+ \t\t\t\t\t}\n+--- a/src/mod/languages/mod_v8/src/fspcre.cpp\n++++ b/src/mod/languages/mod_v8/src/fspcre.cpp\n+@@ -40,7 +40,7 @@ static const char js_class_name[] = \"PCR\n+ FSPCRE::~FSPCRE(void)\n+ {\n+ \tif (!_freed && _re) {\n+-\t\tswitch_regex_safe_free(_re);\n++\t\tswitch_regex_and_match_data_safe_free(_re, _match_data);\n+ \t\tswitch_safe_free(_str);\n+ \t}\n+ }\n+@@ -53,9 +53,9 @@ string FSPCRE::GetJSClassName()\n+ void FSPCRE::Init()\n+ {\n+ \t_re = NULL;\n++\t_match_data = NULL;\n+ \t_str = NULL;\n+ \t_proceed = 0;\n+-\tmemset(&_ovector, 0, sizeof(_ovector));\n+ \t_freed = 0;\n+ }\n+ \n+@@ -74,11 +74,10 @@ JS_PCRE_FUNCTION_IMPL(Compile)\n+ \t\tString::Utf8Value str2(info[1]);\n+ \t\tstring = js_safe_str(*str1);\n+ \t\tregex_string = js_safe_str(*str2);\n+-\t\tswitch_regex_safe_free(this->_re);\n++\t\tswitch_regex_and_match_data_safe_free(this->_re, this->_match_data);\n+ \t\tswitch_safe_free(this->_str);\n+ \t\tjs_strdup(this->_str, string);\n+-\t\tthis->_proceed = switch_regex_perform(this->_str, regex_string, &this->_re, this->_ovector,\n+-\t\t\t\t\t\t\t\t\t\t\t\t sizeof(this->_ovector) / sizeof(this->_ovector[0]));\n++\t\tthis->_proceed = switch_regex_perform(this->_str, regex_string, &this->_re, &this->_match_data);\n+ \t\tinfo.GetReturnValue().Set(this->_proceed ? true : false);\n+ \t} else {\n+ \t\tinfo.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), \"Invalid args\"));\n+@@ -103,7 +102,7 @@ JS_PCRE_FUNCTION_IMPL(Substitute)\n+ \t\tlen = (uint32_t) (strlen(this->_str) + strlen(subst_string) + 10) * this->_proceed;\n+ \t\tsubstituted = (char *)malloc(len);\n+ \t\tswitch_assert(substituted != NULL);\n+-\t\tswitch_perform_substitution(this->_re, this->_proceed, subst_string, this->_str, substituted, len, this->_ovector);\n++\t\tswitch_perform_substitution(this->_match_data, subst_string, substituted, len);\n+ \t\tinfo.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), substituted));\n+ \t\tfree(substituted);\n+ \t} else {\n+--- a/src/mod/languages/mod_yaml/mod_yaml.c\n++++ b/src/mod/languages/mod_yaml/mod_yaml.c\n+@@ -215,7 +215,7 @@ static switch_caller_extension_t *parse_\n+ \tint context_hit = 0;\n+ \tint proceed = 0;\n+ \tswitch_regex_t *re = NULL;\n+-\tint ovector[30];\n++\tswitch_regex_match_data_t *match_data = NULL;\n+ \tint parens = 0;\n+ \n+ \tif (!caller_profile) {\n+@@ -266,7 +266,7 @@ static switch_caller_extension_t *parse_\n+ \n+ \t\t\t\t\t\tparens = 0;\n+ \t\t\t\t\t\tproceed = 0;\n+-\t\t\t\t\t\tswitch_regex_safe_free(re);\n++\t\t\t\t\t\tswitch_regex_and_match_data_safe_free(re, match_data);\n+ \n+ \t\t\t\t\t\tif ((p = strstr(field, \"=~\"))) {\n+ \t\t\t\t\t\t\t*p = '\\0';\n+@@ -305,7 +305,7 @@ static switch_caller_extension_t *parse_\n+ \t\t\t\t\t\t\tlast_field = strdup(field_data);\n+ \n+ \t\t\t\t\t\t\tswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, \"test conditions %s(%s) =~ /%s/\\n\", field, field_data, expression);\n+-\t\t\t\t\t\t\tif (!(proceed = switch_regex_perform(field_data, expression, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {\n++\t\t\t\t\t\t\tif (!(proceed = switch_regex_perform(field_data, expression, &re, &match_data))) {\n+ \t\t\t\t\t\t\t\tswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, \"Regex mismatch\\n\");\n+ \t\t\t\t\t\t\t}\n+ \n+@@ -343,7 +343,7 @@ static switch_caller_extension_t *parse_\n+ \t\t\t\t\t\t\tif (parens) {\n+ \t\t\t\t\t\t\t\tlen = (uint32_t) (strlen(value) + strlen(last_field) + 10) * proceed;\n+ \t\t\t\t\t\t\t\tswitch_zmalloc(substituted, len);\n+-\t\t\t\t\t\t\t\tswitch_perform_substitution(re, proceed, value, last_field, substituted, len, ovector);\n++\t\t\t\t\t\t\t\tswitch_perform_substitution(match_data, value, substituted, len);\n+ \t\t\t\t\t\t\t\tapp_data = substituted;\n+ \t\t\t\t\t\t\t} else {\n+ \t\t\t\t\t\t\t\tapp_data = value;\n+@@ -368,7 +368,7 @@ static switch_caller_extension_t *parse_\n+   end:\n+ \n+ \tswitch_safe_free(last_field);\n+-\tswitch_regex_safe_free(re);\n++\tswitch_regex_and_match_data_safe_free(re, match_data);\n+ \tyaml_parser_delete(&parser);\n+ \n+ \tif (input) {\n+--- a/src/mod/xml_int/mod_xml_radius/mod_xml_radius.c\n++++ b/src/mod/xml_int/mod_xml_radius/mod_xml_radius.c\n+@@ -531,20 +531,20 @@ switch_status_t mod_xml_radius_add_param\n+ \n+ \t\t\t\t\t\tif ( regex && val ) {\n+                                                         switch_regex_t *re = NULL;\n+-                                                        int ovector[30];\n++                                                        switch_regex_match_data_t *match_data = NULL;\n+                                                         int proceed;\n+                                                         char replace[1024] = \"\";\n+                                                         proceed = 0;\n+-                                                        proceed = switch_regex_perform(val, regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0]));\n++                                                        proceed = switch_regex_perform(val, regex, &re, &match_data);\n+                                                         if ( proceed > 0 ) {\n+-                                                            switch_regex_copy_substring(val, ovector, proceed, proceed - 1, replace, sizeof(replace));\n++                                                            switch_regex_copy_substring(match_data, proceed - 1, replace, sizeof(replace));\n+ \t\t\t\t\t\t\t    switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, \"original value: %s, regex: %s, result: %s\\n\", val, regex, replace);\n+                                                             val = replace;\n+                                                         }\n+                                                         else {\n+ \t\t\t\t\t\t\t    switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, \"original value: %s, regex: %s, result: nomatch, value left intact\\n\", val, regex);\n+                                                         }\n+-                                                        switch_regex_safe_free(re);\n++                                                        switch_regex_and_match_data_safe_free(re, match_data);\n+ \t\t\t\t\t\t}\n+ \n+ \t\t\t\t\t\tif ( val == NULL && val_default != NULL) {\n+--- a/src/switch_channel.c\n++++ b/src/switch_channel.c\n+@@ -33,7 +33,8 @@\n+ \n+ #include <switch.h>\n+ #include <switch_channel.h>\n+-#include <pcre.h>\n++#define PCRE2_CODE_UNIT_WIDTH 8\n++#include <pcre2.h>\n+ \n+ struct switch_cause_table {\n+ \tconst char *name;\n+@@ -4548,21 +4549,22 @@ SWITCH_DECLARE(switch_status_t) switch_c\n+ \t\tchar *digit_string = dtstr;\n+ \t\tchar *X = NULL;\n+ \t\tswitch_regex_t *re = NULL;\n++\t\tswitch_regex_match_data_t *match_data = NULL;\n+ \t\tchar *substituted = NULL;\n+ \n+ \t\tif (!zstr(var)) {\n+ \t\t\tint proceed = 0;\n+-\t\t\tint ovector[30];\n+ \n+-\t\t\tif ((proceed = switch_regex_perform(dtstr, var, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {\n++\t\t\tif ((proceed = switch_regex_perform(dtstr, var, &re, &match_data))) {\n+ \t\t\t\tint len = (strlen(dtstr) + strlen(var) + 10) * proceed;\n+ \t\t\t\tint i = 0;\n+ \t\t\t\tconst char *replace = NULL;\n++\t\t\t\tPCRE2_SIZE replace_size;\n+ \n+ \t\t\t\tX = malloc(len);\n+ \n+ \t\t\t\tfor (i = 0; i < proceed; i++) {\n+-\t\t\t\t\tif (pcre_get_substring(dtstr, ovector, proceed, i, &replace) >= 0) {\n++\t\t\t\t\tif (pcre2_substring_get_bynumber(match_data, i, (PCRE2_UCHAR **)&replace, &replace_size) >= 0) {\n+ \t\t\t\t\t\tif (replace) {\n+ \t\t\t\t\t\t\tswitch_size_t plen = strlen(replace);\n+ \t\t\t\t\t\t\tmemset(X, 'X', plen);\n+@@ -4571,7 +4573,7 @@ SWITCH_DECLARE(switch_status_t) switch_c\n+ \t\t\t\t\t\t\tswitch_safe_free(substituted);\n+ \t\t\t\t\t\t\tsubstituted = switch_string_replace(substituted ? substituted : dtstr, replace, X);\n+ \t\t\t\t\t\t\t\n+-\t\t\t\t\t\t\tpcre_free_substring(replace);\n++\t\t\t\t\t\t\tpcre2_substring_free((PCRE2_UCHAR *)replace);\n+ \t\t\t\t\t\t}\n+ \t\t\t\t\t}\n+ \t\t\t\t}\n+@@ -4583,7 +4585,7 @@ SWITCH_DECLARE(switch_status_t) switch_c\n+ \t\t}\n+ \n+ \t\tswitch_channel_set_variable(channel, \"digits_dialed\", digit_string);\n+-\t\tswitch_regex_safe_free(re);\n++\t\tswitch_regex_and_match_data_safe_free(re, match_data);\n+ \t\tswitch_safe_free(substituted);\n+ \t\tswitch_safe_free(X);\n+ \t} else {\n+--- a/src/switch_ivr.c\n++++ b/src/switch_ivr.c\n+@@ -4344,7 +4344,8 @@ SWITCH_DECLARE(char *) switch_ivr_check_\n+ \tchar *r = NULL;\n+ \tswitch_event_t *params = NULL;\n+ \tswitch_regex_t *re = NULL;\n+-\tint proceed = 0, ovector[100];\n++\tswitch_regex_match_data_t *match_data = NULL;\n++\tint proceed = 0;\n+ \n+ \tswitch_event_create(&params, SWITCH_EVENT_REQUEST_PARAMS);\n+ \tswitch_assert(params);\n+@@ -4376,8 +4377,8 @@ SWITCH_DECLARE(char *) switch_ivr_check_\n+ \t\t\tconst char *proto = switch_xml_attr(x_exten, \"proto\");\n+ \n+ \t\t\tif (!zstr(regex) && !zstr(proto)) {\n+-\t\t\t\tproceed = switch_regex_perform(exten_name, regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0]));\n+-\t\t\t\tswitch_regex_safe_free(re);\n++\t\t\t\tproceed = switch_regex_perform(exten_name, regex, &re, &match_data);\n++\t\t\t\tswitch_regex_and_match_data_safe_free(re, match_data);\n+ \n+ \t\t\t\tif (proceed) {\n+ \t\t\t\t\tswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, \"Mapping %s@%s to proto %s matching expression [%s]\\n\",\n+--- a/src/switch_ivr_async.c\n++++ b/src/switch_ivr_async.c\n+@@ -370,12 +370,12 @@ static dm_match_t switch_ivr_dmachine_ch\n+ \tfor(bp = dmachine->realm->binding_list; bp; bp = bp->next) {\n+ \t\tif (bp->is_regex) {\n+ \t\t\tif (bp->repl) {\n+-\t\t\t\tint ovector[30] = { 0 };\n+ \t\t\t\tint proceed = 0;\n+ \t\t\t\tswitch_regex_t *re = NULL;\n++\t\t\t\tswitch_regex_match_data_t *match_data = NULL;\n+ \n+ \t\t\t\t\n+-\t\t\t\tproceed = switch_regex_perform(dmachine->digits, bp->digits, &re, ovector, sizeof(ovector) / sizeof(ovector[0]));\n++\t\t\t\tproceed = switch_regex_perform(dmachine->digits, bp->digits, &re, &match_data);\n+ \t\t\t\t\n+ \t\t\t\tif (proceed) {\n+ \t\t\t\t\tchar *substituted = NULL;\n+@@ -385,13 +385,13 @@ static dm_match_t switch_ivr_dmachine_ch\n+ \t\t\t\t\tsubstituted = malloc(len);\n+ \t\t\t\t\tswitch_assert(substituted);\n+ \t\t\t\t\tmemset(substituted, 0, len);\n+-\t\t\t\t\tswitch_perform_substitution(re, proceed, bp->repl, dmachine->digits, substituted, len, ovector);\n++\t\t\t\t\tswitch_perform_substitution(match_data, bp->repl, substituted, len);\n+ \n+ \t\t\t\t\tif (!bp->substituted || strcmp(substituted, bp->substituted)) {\n+ \t\t\t\t\t\tbp->substituted = switch_core_strdup(dmachine->pool, substituted);\n+ \t\t\t\t\t}\n+ \t\t\t\t\tfree(substituted);\n+-\t\t\t\t\tswitch_regex_safe_free(re);\n++\t\t\t\t\tswitch_regex_and_match_data_safe_free(re, match_data);\n+ \t\t\t\t\tbp->rmatch = 1;\n+ \t\t\t\t} else {\n+ \t\t\t\t\tbp->substituted = NULL;\n+--- a/src/switch_ivr_menu.c\n++++ b/src/switch_ivr_menu.c\n+@@ -553,15 +553,15 @@ SWITCH_DECLARE(switch_status_t) switch_i\n+ \n+ \t\t\t\tif (ap->re) {\n+ \t\t\t\t\tswitch_regex_t *re = NULL;\n+-\t\t\t\t\tint ovector[30];\n++\t\t\t\t\tswitch_regex_match_data_t *match_data = NULL;\n+ \n+-\t\t\t\t\tif ((ok = switch_regex_perform(menu->buf, ap->bind, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {\n+-\t\t\t\t\t\tswitch_perform_substitution(re, ok, ap->arg, menu->buf, substituted, sizeof(substituted), ovector);\n++\t\t\t\t\tif ((ok = switch_regex_perform(menu->buf, ap->bind, &re, &match_data))) {\n++\t\t\t\t\t\tswitch_perform_substitution(match_data, ap->arg, substituted, sizeof(substituted));\n+ \t\t\t\t\t\tuse_arg = substituted;\n+ \t\t\t\t\t}\n+ \t\t\t\t\tswitch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, \"action regex [%s] [%s] [%d]\\n\", menu->buf, ap->bind, ok);\n+ \n+-\t\t\t\t\tswitch_regex_safe_free(re);\n++\t\t\t\t\tswitch_regex_and_match_data_safe_free(re, match_data);\n+ \t\t\t\t} else {\n+ \t\t\t\t\tok = !strcmp(menu->buf, ap->bind);\n+ \t\t\t\t}\n+--- a/src/switch_ivr_play_say.c\n++++ b/src/switch_ivr_play_say.c\n+@@ -178,7 +178,8 @@ SWITCH_DECLARE(switch_status_t) switch_i\n+ \t\tchar *field_expanded = NULL;\n+ \t\tchar *field_expanded_alloc = NULL;\n+ \t\tswitch_regex_t *re = NULL;\n+-\t\tint proceed = 0, ovector[100];\n++\t\tswitch_regex_match_data_t *match_data = NULL;\n++\t\tint proceed = 0;\n+ \t\tswitch_xml_t match = NULL;\n+ \n+ \t\tsearched = 1;\n+@@ -204,7 +205,7 @@ SWITCH_DECLARE(switch_status_t) switch_i\n+ \n+ \t\tstatus = SWITCH_STATUS_SUCCESS;\n+ \n+-\t\tif ((proceed = switch_regex_perform(field_expanded, pattern, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {\n++\t\tif ((proceed = switch_regex_perform(field_expanded, pattern, &re, &match_data))) {\n+ \t\t\tmatch = switch_xml_child(input, \"match\");\n+ \t\t} else {\n+ \t\t\tmatch = switch_xml_child(input, \"nomatch\");\n+@@ -224,12 +225,12 @@ SWITCH_DECLARE(switch_status_t) switch_i\n+ \t\t\t\t\tlen = (uint32_t) (strlen(data) + strlen(adata) + 10) * proceed;\n+ \t\t\t\t\tif (!(substituted = malloc(len))) {\n+ \t\t\t\t\t\tswitch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, \"Memory Error!\\n\");\n+-\t\t\t\t\t\tswitch_regex_safe_free(re);\n++\t\t\t\t\t\tswitch_regex_and_match_data_safe_free(re, match_data);\n+ \t\t\t\t\t\tswitch_safe_free(field_expanded_alloc);\n+ \t\t\t\t\t\tgoto done;\n+ \t\t\t\t\t}\n+ \t\t\t\t\tmemset(substituted, 0, len);\n+-\t\t\t\t\tswitch_perform_substitution(re, proceed, adata, field_expanded, substituted, len, ovector);\n++\t\t\t\t\tswitch_perform_substitution(match_data, adata, substituted, len);\n+ \t\t\t\t\todata = substituted;\n+ \t\t\t\t} else {\n+ \t\t\t\t\todata = adata;\n+@@ -326,7 +327,7 @@ SWITCH_DECLARE(switch_status_t) switch_i\n+ \t\t\t}\n+ \t\t}\n+ \n+-\t\tswitch_regex_safe_free(re);\n++\t\tswitch_regex_and_match_data_safe_free(re, match_data);\n+ \t\tswitch_safe_free(field_expanded_alloc);\n+ \n+ \t\tif (done || status != SWITCH_STATUS_SUCCESS\n+--- a/src/switch_regex.c\n++++ b/src/switch_regex.c\n+@@ -24,39 +24,49 @@\n+  * Contributor(s):\n+  *\n+  * Michael Jerris <mike@jerris.com>\n++ * Christian Marangi <ansuelsmth@gmail.com> # PCRE2 conversion\n+  *\n+  *\n+- * switch_regex.c -- PCRE wrapper\n++ * switch_regex.c -- PCRE2 wrapper\n+  *\n+  */\n+ \n+ #include <switch.h>\n+-#include <pcre.h>\n++#define PCRE2_CODE_UNIT_WIDTH 8\n++#include <pcre2.h>\n+ \n+ SWITCH_DECLARE(switch_regex_t *) switch_regex_compile(const char *pattern,\n+-\t\t\t\t\t\t\t\t\t\t\t\t\t  int options, const char **errorptr, int *erroroffset, const unsigned char *tables)\n++\t\t\t\t\t\t\t\t\t\t\t\t\t  int options, int *errorcode, unsigned int *erroroffset, switch_regex_compile_context_t *ccontext)\n+ {\n+ \n+-\treturn (switch_regex_t *)pcre_compile(pattern, options, errorptr, erroroffset, tables);\n++\treturn (switch_regex_t *)pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, options, errorcode, (PCRE2_SIZE *)erroroffset, ccontext);\n+ \n+ }\n+ \n+-SWITCH_DECLARE(int) switch_regex_copy_substring(const char *subject, int *ovector, int stringcount, int stringnumber, char *buffer, int size)\n++SWITCH_DECLARE(int) switch_regex_copy_substring(switch_regex_match_data_t *match_data, int stringnumber, char *buffer, unsigned int *size)\n+ {\n+-\treturn pcre_copy_substring(subject, ovector, stringcount, stringnumber, buffer, size);\n++\treturn pcre2_substring_copy_bynumber(match_data, stringnumber, (PCRE2_UCHAR *)buffer, (PCRE2_SIZE *)size);\n++}\n++\n++SWITCH_DECLARE(void) switch_regex_match_free(void *data)\n++{\n++\tpcre2_match_context_free(data);\n++\n+ }\n+ \n+ SWITCH_DECLARE(void) switch_regex_free(void *data)\n+ {\n+-\tpcre_free(data);\n++\tpcre2_code_free(data);\n+ \n+ }\n+ \n+-SWITCH_DECLARE(int) switch_regex_perform(const char *field, const char *expression, switch_regex_t **new_re, int *ovector, uint32_t olen)\n++SWITCH_DECLARE(int) switch_regex_perform(const char *field, const char *expression, switch_regex_t **new_re, switch_regex_match_data_t **new_match_data)\n+ {\n+-\tconst char *error = NULL;\n+-\tint erroffset = 0;\n+-\tpcre *re = NULL;\n++\tint error_code = 0;\n++\tPCRE2_UCHAR error_str[128];\n++\tPCRE2_SIZE error_offset = 0;\n++\tpcre2_code *re = NULL;\n++\tpcre2_match_data *match_data;\n+ \tint match_count = 0;\n+ \tchar *tmp = NULL;\n+ \tuint32_t flags = 0;\n+@@ -87,52 +97,56 @@ SWITCH_DECLARE(int) switch_regex_perform\n+ \t\texpression = tmp;\n+ \t\tif (*opts) {\n+ \t\t\tif (strchr(opts, 'i')) {\n+-\t\t\t\tflags |= PCRE_CASELESS;\n++\t\t\t\tflags |= PCRE2_CASELESS;\n+ \t\t\t}\n+ \t\t\tif (strchr(opts, 's')) {\n+-\t\t\t\tflags |= PCRE_DOTALL;\n++\t\t\t\tflags |= PCRE2_DOTALL;\n+ \t\t\t}\n+ \t\t}\n+ \t}\n+ \n+-\tre = pcre_compile(expression,\t/* the pattern */\n++\tre = pcre2_compile((PCRE2_SPTR)expression,\t/* the pattern */\n++\t\t\t\t\t  PCRE2_ZERO_TERMINATED,\n+ \t\t\t\t\t  flags,\t/* default options */\n+-\t\t\t\t\t  &error,\t/* for error message */\n+-\t\t\t\t\t  &erroffset,\t/* for error offset */\n++\t\t\t\t\t  &error_code,\t/* for error code */\n++\t\t\t\t\t  &error_offset,\t/* for error offset */\n+ \t\t\t\t\t  NULL);\t/* use default character tables */\n+-\tif (error) {\n+-\t\tswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, \"COMPILE ERROR: %d [%s][%s]\\n\", erroffset, error, expression);\n+-\t\tswitch_regex_safe_free(re);\n++\tif (!re) {\n++\t\tpcre2_get_error_message(error_code, error_str, 128);\n++\t\tswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, \"COMPILE ERROR: %zu [%s][%s]\\n\", error_offset, error_str, expression);\n+ \t\tgoto end;\n+ \t}\n+ \n+-\tmatch_count = pcre_exec(re,\t/* result of pcre_compile() */\n+-\t\t\t\t\t\t\tNULL,\t/* we didn't study the pattern */\n+-\t\t\t\t\t\t\tfield,\t/* the subject string */\n++\tmatch_data = pcre2_match_data_create_from_pattern(re, NULL);\n++\n++\tmatch_count = pcre2_match(re,\t/* result of pcre_compile() */\n++\t\t\t\t\t\t\t(PCRE2_SPTR)field,\t/* the subject string */\n+ \t\t\t\t\t\t\t(int) strlen(field),\t/* the length of the subject string */\n+ \t\t\t\t\t\t\t0,\t/* start at offset 0 in the subject */\n+ \t\t\t\t\t\t\t0,\t/* default options */\n+-\t\t\t\t\t\t\tovector,\t/* vector of integers for substring information */\n+-\t\t\t\t\t\t\tolen);\t/* number of elements (NOT size in bytes) */\n++\t\t\t\t\t\t\tmatch_data,\t/* vector of integers for substring information */\n++\t\t\t\t\t\t\tNULL);\t/* number of elements (NOT size in bytes) */\n+ \n+ \n+ \tif (match_count <= 0) {\n+-\t\tswitch_regex_safe_free(re);\n++\t\tswitch_regex_and_match_data_safe_free(re, match_data);\n+ \t\tmatch_count = 0;\n+ \t}\n+ \n+ \t*new_re = (switch_regex_t *) re;\n++\t*new_match_data = (switch_regex_match_data_t *) match_data;\n+ \n+   end:\n+ \tswitch_safe_free(tmp);\n+ \treturn match_count;\n+ }\n+ \n+-SWITCH_DECLARE(void) switch_perform_substitution(switch_regex_t *re, int match_count, const char *data, const char *field_data,\n+-\t\t\t\t\t\t\t\t\t\t\t\t char *substituted, switch_size_t len, int *ovector)\n++SWITCH_DECLARE(void) switch_perform_substitution(switch_regex_match_data_t *match_data, const char *data,\n++\t\t\t\t\t\t\t\t\t\t\t\t char *substituted, switch_size_t len)\n+ {\n+ \tchar index[10] = \"\";\n+ \tconst char *replace = NULL;\n++\tPCRE2_SIZE replace_size;\n+ \tswitch_size_t x, y = 0, z = 0;\n+ \tint num = 0;\n+ \tint brace;\n+@@ -174,14 +188,14 @@ SWITCH_DECLARE(void) switch_perform_subs\n+ \t\t\t\tnum = -1;\n+ \t\t\t}\n+ \n+-\t\t\tif (pcre_get_substring(field_data, ovector, match_count, num, &replace) >= 0) {\n++\t\t\tif (pcre2_substring_get_bynumber(match_data, num, (PCRE2_UCHAR **)&replace, &replace_size) >= 0) {\n+ \t\t\t\tif (replace) {\n+ \t\t\t\t\tswitch_size_t r;\n+ \n+ \t\t\t\t\tfor (r = 0; r < strlen(replace) && y < (len - 1); r++) {\n+ \t\t\t\t\t\tsubstituted[y++] = replace[r];\n+ \t\t\t\t\t}\n+-\t\t\t\t\tpcre_free_substring(replace);\n++\t\t\t\t\tpcre2_substring_free((PCRE2_UCHAR *)replace);\n+ \t\t\t\t}\n+ \t\t\t}\n+ \t\t} else {\n+@@ -193,20 +207,21 @@ SWITCH_DECLARE(void) switch_perform_subs\n+ }\n+ \n+ \n+-SWITCH_DECLARE(void) switch_capture_regex(switch_regex_t *re, int match_count, const char *field_data,\n+-\t\t\t\t\t\t\t\t\t\t  int *ovector, const char *var, switch_cap_callback_t callback, void *user_data)\n++SWITCH_DECLARE(void) switch_capture_regex(switch_regex_match_data_t *match_data, int match_count,\n++\t\t\t\t\t\t\t\t\t\t  const char *var, switch_cap_callback_t callback, void *user_data)\n+ \n+ {\n+ \n+ \n+ \tconst char *replace;\n++\tPCRE2_SIZE replace_size;\n+ \tint i;\n+ \n+ \tfor (i = 0; i < match_count; i++) {\n+-\t\tif (pcre_get_substring(field_data, ovector, match_count, i, &replace) >= 0) {\n++\t\tif (pcre2_substring_get_bynumber(match_data, i, (PCRE2_UCHAR **)&replace, &replace_size) >= 0) {\n+ \t\t\tif (replace) {\n+-\t\t\t\tcallback(var, replace, user_data);\n+-\t\t\t\tpcre_free_substring(replace);\n++\t\t\t\tcallback(var, (const char *)replace, user_data);\n++\t\t\t\tpcre2_substring_free((PCRE2_UCHAR *)replace);\n+ \t\t\t}\n+ \t\t}\n+ \t}\n+@@ -214,12 +229,13 @@ SWITCH_DECLARE(void) switch_capture_rege\n+ \n+ SWITCH_DECLARE(switch_status_t) switch_regex_match_partial(const char *target, const char *expression, int *partial)\n+ {\n+-\tconst char *error = NULL;\t/* Used to hold any errors                                           */\n+-\tint error_offset = 0;\t\t/* Holds the offset of an error                                      */\n+-\tpcre *pcre_prepared = NULL;\t/* Holds the compiled regex                                          */\n++\tPCRE2_UCHAR error[128]; /* Used to hold any errors                                           */\n++\tint error_code = 0;\t/* Holds the code of an error                                           */\n++\tPCRE2_SIZE error_offset = 0;\t\t/* Holds the offset of an error                                      */\n++\tpcre2_code *pcre_prepared = NULL;\t/* Holds the compiled regex                                          */\n+ \tint match_count = 0;\t\t/* Number of times the regex was matched                             */\n+-\tint offset_vectors[255];\t/* not used, but has to exist or pcre won't even try to find a match */\n+-\tint pcre_flags = 0;\n++\tpcre2_match_data *match_data;\n++\tint pcre2_flags = 0;\n+ \tuint32_t flags = 0;\n+ \tchar *tmp = NULL;\n+ \tswitch_status_t status = SWITCH_STATUS_FALSE;\n+@@ -239,43 +255,44 @@ SWITCH_DECLARE(switch_status_t) switch_r\n+ \t\texpression = tmp;\n+ \t\tif (*opts) {\n+ \t\t\tif (strchr(opts, 'i')) {\n+-\t\t\t\tflags |= PCRE_CASELESS;\n++\t\t\t\tflags |= PCRE2_CASELESS;\n+ \t\t\t}\n+ \t\t\tif (strchr(opts, 's')) {\n+-\t\t\t\tflags |= PCRE_DOTALL;\n++\t\t\t\tflags |= PCRE2_DOTALL;\n+ \t\t\t}\n+ \t\t}\n+ \t}\n+ \n+ \t/* Compile the expression */\n+-\tpcre_prepared = pcre_compile(expression, flags, &error, &error_offset, NULL);\n++\tpcre_prepared = pcre2_compile((PCRE2_SPTR)expression, PCRE2_ZERO_TERMINATED, flags, &error_code, &error_offset, NULL);\n+ \n+ \t/* See if there was an error in the expression */\n+-\tif (error != NULL) {\n+-\t\t/* Clean up after ourselves */\n+-\t\tif (pcre_prepared) {\n+-\t\t\tpcre_free(pcre_prepared);\n+-\t\t\tpcre_prepared = NULL;\n+-\t\t}\n++\tif (!pcre_prepared) {\n++\t\tpcre2_get_error_message(error_code, error, 128);\n++\n+ \t\t/* Note our error */\n+ \t\tswitch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,\n+-\t\t\t\t\t\t  \"Regular Expression Error expression[%s] error[%s] location[%d]\\n\", expression, error, error_offset);\n++\t\t\t\t\t\t  \"Regular Expression Error expression[%s] error[%s] location[%zu]\\n\", expression, error, error_offset);\n+ \n+ \t\t/* We definitely didn't match anything */\n+ \t\tgoto end;\n+ \t}\n+ \n+ \tif (*partial) {\n+-\t\tpcre_flags = PCRE_PARTIAL;\n++\t\tpcre2_flags = PCRE2_PARTIAL_SOFT;\n+ \t}\n+ \n+ \t/* So far so good, run the regex */\n++\tmatch_data = pcre2_match_data_create_from_pattern(pcre_prepared, NULL);\n++\n+ \tmatch_count =\n+-\t\tpcre_exec(pcre_prepared, NULL, target, (int) strlen(target), 0, pcre_flags, offset_vectors, sizeof(offset_vectors) / sizeof(offset_vectors[0]));\n++\t\tpcre2_match(pcre_prepared, (PCRE2_SPTR)target, (int) strlen(target), 0, pcre2_flags, match_data, NULL);\n++\n++\tpcre2_match_data_free(match_data);\n+ \n+ \t/* Clean up */\n+ \tif (pcre_prepared) {\n+-\t\tpcre_free(pcre_prepared);\n++\t\tpcre2_code_free(pcre_prepared);\n+ \t\tpcre_prepared = NULL;\n+ \t}\n+ \n+@@ -285,7 +302,7 @@ SWITCH_DECLARE(switch_status_t) switch_r\n+ \tif (match_count > 0) {\n+ \t\t*partial = 0;\n+ \t\tswitch_goto_status(SWITCH_STATUS_SUCCESS, end);\n+-\t} else if (match_count == PCRE_ERROR_PARTIAL || match_count == PCRE_ERROR_BADPARTIAL) {\n++\t} else if (match_count == PCRE2_ERROR_PARTIAL) {\n+ \t\t/* yes it is already set, but the code is clearer this way */\n+ \t\t*partial = 1;\n+ \t\tswitch_goto_status(SWITCH_STATUS_SUCCESS, end);\n+--- a/src/switch_utils.c\n++++ b/src/switch_utils.c\n+@@ -2081,8 +2081,9 @@ SWITCH_DECLARE(switch_status_t) switch_f\n+ SWITCH_DECLARE(switch_time_t) switch_str_time(const char *in)\n+ {\n+ \tswitch_time_exp_t tm = { 0 }, local_tm = { 0 };\n+-\tint proceed = 0, ovector[30], time_only = 0;\n++\tint proceed = 0, time_only = 0;\n+ \tswitch_regex_t *re = NULL;\n++\tswitch_regex_match_data_t *match_data = NULL;\n+ \tchar replace[1024] = \"\";\n+ \tswitch_time_t ret = 0, local_time = 0;\n+ \tchar *pattern = \"^(\\\\d+)-(\\\\d+)-(\\\\d+)\\\\s*(\\\\d*):{0,1}(\\\\d*):{0,1}(\\\\d*)\";\n+@@ -2092,67 +2093,77 @@ SWITCH_DECLARE(switch_time_t) switch_str\n+ \tswitch_time_exp_lt(&tm, switch_micro_time_now());\n+ \n+ \n+-\tif ((time_only = switch_regex_perform(in, pattern3, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {\n++\tif ((time_only = switch_regex_perform(in, pattern3, &re, &match_data))) {\n+ \t\ttm.tm_hour = 0;\n+ \t\ttm.tm_min = 0;\n+ \t\ttm.tm_sec = 0;\n+ \t} else {\n+ \t\ttm.tm_year = tm.tm_mon = tm.tm_mday = tm.tm_hour = tm.tm_min = tm.tm_sec = tm.tm_usec = 0;\n+ \n+-\t\tif (!(proceed = switch_regex_perform(in, pattern, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {\n+-\t\t\tswitch_regex_safe_free(re);\n+-\t\t\tproceed = switch_regex_perform(in, pattern2, &re, ovector, sizeof(ovector) / sizeof(ovector[0]));\n++\t\tif (!(proceed = switch_regex_perform(in, pattern, &re, &match_data))) {\n++\t\t\tswitch_regex_and_match_data_safe_free(re, match_data);\n++\t\t\tproceed = switch_regex_perform(in, pattern2, &re, &match_data);\n+ \t\t}\n+ \t}\n+ \n+ \tif (proceed || time_only) {\n++\t\tunsigned int replace_size;\n+ \n+ \t\tif (time_only > 1) {\n+-\t\t\tswitch_regex_copy_substring(in, ovector, time_only, 1, replace, sizeof(replace));\n++\t\t\treplace_size = sizeof(replace);\n++\t\t\tswitch_regex_copy_substring(match_data, 1, replace, &replace_size);\n+ \t\t\ttm.tm_hour = atoi(replace);\n+ \t\t}\n+ \n+ \t\tif (time_only > 2) {\n+-\t\t\tswitch_regex_copy_substring(in, ovector, time_only, 2, replace, sizeof(replace));\n++\t\t\treplace_size = sizeof(replace);\n++\t\t\tswitch_regex_copy_substring(match_data, 2, replace, &replace_size);\n+ \t\t\ttm.tm_min = atoi(replace);\n+ \t\t}\n+ \n+ \t\tif (time_only > 3) {\n+-\t\t\tswitch_regex_copy_substring(in, ovector, time_only, 3, replace, sizeof(replace));\n++\t\t\treplace_size = sizeof(replace);\n++\t\t\tswitch_regex_copy_substring(match_data, 3, replace, &replace_size);\n+ \t\t\ttm.tm_sec = atoi(replace);\n+ \t\t}\n+ \n+ \t\tif (proceed > 1) {\n+-\t\t\tswitch_regex_copy_substring(in, ovector, proceed, 1, replace, sizeof(replace));\n++\t\t\treplace_size = sizeof(replace);\n++\t\t\tswitch_regex_copy_substring(match_data, 1, replace, &replace_size);\n+ \t\t\ttm.tm_year = atoi(replace) - 1900;\n+ \t\t}\n+ \n+ \t\tif (proceed > 2) {\n+-\t\t\tswitch_regex_copy_substring(in, ovector, proceed, 2, replace, sizeof(replace));\n++\t\t\treplace_size = sizeof(replace);\n++\t\t\tswitch_regex_copy_substring(match_data, 2, replace, &replace_size);\n+ \t\t\ttm.tm_mon = atoi(replace) - 1;\n+ \t\t}\n+ \n+ \t\tif (proceed > 3) {\n+-\t\t\tswitch_regex_copy_substring(in, ovector, proceed, 3, replace, sizeof(replace));\n++\t\t\treplace_size = sizeof(replace);\n++\t\t\tswitch_regex_copy_substring(match_data, 3, replace, &replace_size);\n+ \t\t\ttm.tm_mday = atoi(replace);\n+ \t\t}\n+ \n+ \t\tif (proceed > 4) {\n+-\t\t\tswitch_regex_copy_substring(in, ovector, proceed, 4, replace, sizeof(replace));\n++\t\t\treplace_size = sizeof(replace);\n++\t\t\tswitch_regex_copy_substring(match_data, 4, replace, &replace_size);\n+ \t\t\ttm.tm_hour = atoi(replace);\n+ \t\t}\n+ \n+ \t\tif (proceed > 5) {\n+-\t\t\tswitch_regex_copy_substring(in, ovector, proceed, 5, replace, sizeof(replace));\n++\t\t\treplace_size = sizeof(replace);\n++\t\t\tswitch_regex_copy_substring(match_data, 5, replace, &replace_size);\n+ \t\t\ttm.tm_min = atoi(replace);\n+ \t\t}\n+ \n+ \t\tif (proceed > 6) {\n+-\t\t\tswitch_regex_copy_substring(in, ovector, proceed, 6, replace, sizeof(replace));\n++\t\t\treplace_size = sizeof(replace);\n++\t\t\tswitch_regex_copy_substring(match_data, 6, replace, &replace_size);\n+ \t\t\ttm.tm_sec = atoi(replace);\n+ \t\t}\n+ \t\t\n+-\t\tswitch_regex_safe_free(re);\n++\t\tswitch_regex_and_match_data_safe_free(re, match_data);\n+ \n+ \t\tswitch_time_exp_get(&local_time, &tm);\n+ \t\tswitch_time_exp_lt(&local_tm, local_time);\n+@@ -2163,7 +2174,7 @@ SWITCH_DECLARE(switch_time_t) switch_str\n+ \t\treturn ret;\n+ \t}\n+ \n+-\tswitch_regex_safe_free(re);\n++\tswitch_regex_and_match_data_safe_free(re, match_data);\n+ \n+ \treturn ret;\n+ }\ndiff --git a/package/freeswitch/0007-Fix-double-free-after-upgrade-to-pcre2.patch b/package/freeswitch/0007-Fix-double-free-after-upgrade-to-pcre2.patch\nnew file mode 100644\nindex 0000000000..37455d7794\n--- /dev/null\n+++ b/package/freeswitch/0007-Fix-double-free-after-upgrade-to-pcre2.patch\n@@ -0,0 +1,27 @@\n+From 02549c10d9155d0f71f36289aeeddc9c73a4d46e Mon Sep 17 00:00:00 2001\n+From: Andrey Volk <andywolk@gmail.com>\n+Date: Thu, 13 Nov 2025 17:42:04 +0300\n+Subject: [PATCH] [mod_dialplan_xml] Fix double free after upgrade to pcre2.\n+ (#2946)\n+\n+Upstream: https://github.com/signalwire/freeswitch/commit/02549c10d9155d0f71f36289aeeddc9c73a4d46e\n+\n+[backported only second part of upstream commit, the first part is\n+ already included in patch 0006]\n+Signed-off-by: Bernd Kuhls <bernd@kuhls.net>\n+---\n+ src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c | 3 ++-\n+ 1 file changed, 2 insertions(+), 1 deletion(-)\n+\n+diff --git a/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c b/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c\n+index 3d3fdfd8a93..cab522887c4 100644\n+--- a/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c\n++++ b/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c\n+@@ -357,6 +357,7 @@ static int parse_exten(switch_core_session_t *session, switch_caller_profile_t *\n+ \t\t\t\t\tsave_proceed = proceed;\n+ \n+ \t\t\t\t\tre = NULL;\n++\t\t\t\t\tmatch_data = NULL;\n+ \t\t\t\t}\n+ \n+ \t\t\t\tswitch_regex_and_match_data_safe_free(re, match_data);\ndiff --git a/package/freeswitch/Config.in b/package/freeswitch/Config.in\nindex 3633a29903..ad54efc0cb 100644\n--- a/package/freeswitch/Config.in\n+++ b/package/freeswitch/Config.in\n@@ -10,7 +10,7 @@ config BR2_PACKAGE_FREESWITCH\n \tselect BR2_PACKAGE_LIBXCRYPT if BR2_TOOLCHAIN_USES_GLIBC\n \tselect BR2_PACKAGE_JPEG\n \tselect BR2_PACKAGE_OPENSSL\n-\tselect BR2_PACKAGE_PCRE\n+\tselect BR2_PACKAGE_PCRE2\n \tselect BR2_PACKAGE_SOFIA_SIP\n \tselect BR2_PACKAGE_SPANDSP\n \tselect BR2_PACKAGE_SPEEX\ndiff --git a/package/freeswitch/freeswitch.mk b/package/freeswitch/freeswitch.mk\nindex 1121bfa9cc..5cd80cfc4f 100644\n--- a/package/freeswitch/freeswitch.mk\n+++ b/package/freeswitch/freeswitch.mk\n@@ -19,6 +19,9 @@ FREESWITCH_LICENSE_FILES = \\\n \tlibs/apr/LICENSE \\\n \tlibs/srtp/LICENSE\n \n+# 0006-Move-project-to-PCRE2.patch\n+FREESWITCH_AUTORECONF = YES\n+\n FREESWITCH_CPE_ID_VENDOR = freeswitch\n \n # required dependencies\n@@ -27,7 +30,7 @@ FREESWITCH_DEPENDENCIES = \\\n \tjpeg \\\n \tlibcurl \\\n \topenssl \\\n-\tpcre \\\n+\tpcre2 \\\n \tspandsp \\\n \tsofia-sip \\\n \tspeex \\\n","prefixes":["1/1"]}