public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/opensips] f43: Switch to PCRE2
@ 2026-06-24 17:40 Peter Lemenkov
  0 siblings, 0 replies; only message in thread
From: Peter Lemenkov @ 2026-06-24 17:40 UTC (permalink / raw)
  To: git-commits

            A new commit has been pushed.

            Repo   : rpms/opensips
            Branch : f43
            Commit : e6f4e47746c0f1639117cec04a9f0e40f357e377
            Author : Peter Lemenkov <lemenkov@gmail.com>
            Date   : 2026-04-02T20:55:32+02:00
            Stats  : +1473/-3 in 23 file(s)
            URL    : https://src.fedoraproject.org/rpms/opensips/c/e6f4e47746c0f1639117cec04a9f0e40f357e377?branch=f43

            Log:
            Switch to PCRE2

Signed-off-by: Peter Lemenkov <lemenkov@gmail.com>

---
diff --git a/opensips-0001-Consistently-use-rtpproxy-switches.patch b/opensips-0001-Consistently-use-rtpproxy-switches.patch
index be4ac58..91a1f48 100644
--- a/opensips-0001-Consistently-use-rtpproxy-switches.patch
+++ b/opensips-0001-Consistently-use-rtpproxy-switches.patch
@@ -1,3 +1,4 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Peter Lemenkov <lemenkov@gmail.com>
 Date: Thu, 11 Aug 2011 16:37:04 +0400
 Subject: [PATCH] Consistently use rtpproxy switches

diff --git a/opensips-0002-Cleanup-Oracle-s-makefiles.patch b/opensips-0002-Cleanup-Oracle-s-makefiles.patch
index e34e94f..424409c 100644
--- a/opensips-0002-Cleanup-Oracle-s-makefiles.patch
+++ b/opensips-0002-Cleanup-Oracle-s-makefiles.patch
@@ -1,3 +1,4 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Peter Lemenkov <lemenkov@gmail.com>
 Date: Thu, 14 Jun 2012 11:38:48 +0400
 Subject: [PATCH] Cleanup Oracle's makefiles

diff --git a/opensips-0003-db_ora-null-terminating-string-is-more-safely-most-m.patch b/opensips-0003-db_ora-null-terminating-string-is-more-safely-most-m.patch
index c32386d..92923e6 100644
--- a/opensips-0003-db_ora-null-terminating-string-is-more-safely-most-m.patch
+++ b/opensips-0003-db_ora-null-terminating-string-is-more-safely-most-m.patch
@@ -1,3 +1,4 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: dronord <dronord@gmail.com>
 Date: Fri, 3 Nov 2017 17:05:35 +0300
 Subject: [PATCH] db_ora: null-terminating string is more safely, most modules

diff --git a/opensips-0004-Return-actual-payload-ID-in-case-of-a-dynamic-payloa.patch b/opensips-0004-Return-actual-payload-ID-in-case-of-a-dynamic-payloa.patch
index e841ef4..2469aff 100644
--- a/opensips-0004-Return-actual-payload-ID-in-case-of-a-dynamic-payloa.patch
+++ b/opensips-0004-Return-actual-payload-ID-in-case-of-a-dynamic-payloa.patch
@@ -1,3 +1,4 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Peter Lemenkov <lemenkov@gmail.com>
 Date: Fri, 11 Jan 2013 14:40:08 +0400
 Subject: [PATCH] Return actual payload ID in case of a dynamic payload

diff --git a/opensips-0005-Fix-rabbitmq-c-deprecated-header-warnings.patch b/opensips-0005-Fix-rabbitmq-c-deprecated-header-warnings.patch
index 23d4498..6b8a34d 100644
--- a/opensips-0005-Fix-rabbitmq-c-deprecated-header-warnings.patch
+++ b/opensips-0005-Fix-rabbitmq-c-deprecated-header-warnings.patch
@@ -1,3 +1,4 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Peter Lemenkov <lemenkov@gmail.com>
 Date: Sun, 26 Oct 2025 15:29:04 +0100
 Subject: [PATCH] Fix rabbitmq-c deprecated header warnings

diff --git a/opensips-0006-Fix-uninitialized-variable-warnings-in-SQL-API-funct.patch b/opensips-0006-Fix-uninitialized-variable-warnings-in-SQL-API-funct.patch
index d12e283..c95cffd 100644
--- a/opensips-0006-Fix-uninitialized-variable-warnings-in-SQL-API-funct.patch
+++ b/opensips-0006-Fix-uninitialized-variable-warnings-in-SQL-API-funct.patch
@@ -1,3 +1,4 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Peter Lemenkov <lemenkov@gmail.com>
 Date: Sun, 26 Oct 2025 16:50:53 +0100
 Subject: [PATCH] Fix uninitialized variable warnings in SQL API functions

diff --git a/opensips-0007-Fix-const-correctness-warnings-in-HTTP-and-FreeSWITC.patch b/opensips-0007-Fix-const-correctness-warnings-in-HTTP-and-FreeSWITC.patch
index bd7a318..07db783 100644
--- a/opensips-0007-Fix-const-correctness-warnings-in-HTTP-and-FreeSWITC.patch
+++ b/opensips-0007-Fix-const-correctness-warnings-in-HTTP-and-FreeSWITC.patch
@@ -1,3 +1,4 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Peter Lemenkov <lemenkov@gmail.com>
 Date: Sat, 20 Dec 2025 20:16:48 +0100
 Subject: [PATCH] Fix const-correctness warnings in HTTP and FreeSWITCH ESL

diff --git a/opensips-0008-Fix-uninitialized-va_list-warning-on-ppc64le-and-i68.patch b/opensips-0008-Fix-uninitialized-va_list-warning-on-ppc64le-and-i68.patch
index d901d3d..8e995df 100644
--- a/opensips-0008-Fix-uninitialized-va_list-warning-on-ppc64le-and-i68.patch
+++ b/opensips-0008-Fix-uninitialized-va_list-warning-on-ppc64le-and-i68.patch
@@ -1,3 +1,4 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Peter Lemenkov <lemenkov@gmail.com>
 Date: Fri, 26 Dec 2025 17:25:05 +0100
 Subject: [PATCH] Fix uninitialized va_list warning on ppc64le and i686 with

diff --git a/opensips-0009-Fix-format-specifier-warnings-on-32-bit-architecture.patch b/opensips-0009-Fix-format-specifier-warnings-on-32-bit-architecture.patch
index f287ff2..c538f5c 100644
--- a/opensips-0009-Fix-format-specifier-warnings-on-32-bit-architecture.patch
+++ b/opensips-0009-Fix-format-specifier-warnings-on-32-bit-architecture.patch
@@ -1,3 +1,4 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Peter Lemenkov <lemenkov@gmail.com>
 Date: Fri, 26 Dec 2025 17:49:21 +0100
 Subject: [PATCH] Fix format specifier warnings on 32-bit architectures (i686)

diff --git a/opensips-0010-Fix-pointer-truncation-warning-on-32-bit-architectur.patch b/opensips-0010-Fix-pointer-truncation-warning-on-32-bit-architectur.patch
index ee8e978..d9b0da5 100644
--- a/opensips-0010-Fix-pointer-truncation-warning-on-32-bit-architectur.patch
+++ b/opensips-0010-Fix-pointer-truncation-warning-on-32-bit-architectur.patch
@@ -1,3 +1,4 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Peter Lemenkov <lemenkov@gmail.com>
 Date: Fri, 26 Dec 2025 21:08:00 +0100
 Subject: [PATCH] Fix pointer truncation warning on 32-bit architectures in

diff --git a/opensips-0011-Fix-C90-style-declaration-warnings-in-snmpstats-modu.patch b/opensips-0011-Fix-C90-style-declaration-warnings-in-snmpstats-modu.patch
index 2d300d8..e6047a6 100644
--- a/opensips-0011-Fix-C90-style-declaration-warnings-in-snmpstats-modu.patch
+++ b/opensips-0011-Fix-C90-style-declaration-warnings-in-snmpstats-modu.patch
@@ -1,3 +1,4 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Peter Lemenkov <lemenkov@gmail.com>
 Date: Sat, 31 Jan 2026 15:11:20 +0100
 Subject: [PATCH] Fix C90-style declaration warnings in snmpstats module

diff --git a/opensips-0012-support-for-libmongc-libbson-version-2.patch b/opensips-0012-support-for-libmongc-libbson-version-2.patch
index 19ef4a9..cf165c6 100644
--- a/opensips-0012-support-for-libmongc-libbson-version-2.patch
+++ b/opensips-0012-support-for-libmongc-libbson-version-2.patch
@@ -1,3 +1,4 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Remi Collet <remi@remirepo.net>
 Date: Thu, 19 Feb 2026 12:46:28 +0100
 Subject: [PATCH] support for libmongc/libbson version 2

diff --git a/opensips-0013-require-libpcre2.patch b/opensips-0013-require-libpcre2.patch
new file mode 100644
index 0000000..abcb7f0
--- /dev/null
+++ b/opensips-0013-require-libpcre2.patch
@@ -0,0 +1,170 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Steve Ayre <steven.ayre@dubber.net>
+Date: Wed, 17 Sep 2025 19:20:47 +0100
+Subject: [PATCH] require libpcre2
+
+(cherry picked from commit 1cb16e082e9ba1cd63f04996eecd75632682df7c)
+
+diff --git a/.lgtm.yml b/.lgtm.yml
+index 7d584c772..64235966f 100644
+--- a/.lgtm.yml
++++ b/.lgtm.yml
+@@ -22,7 +22,7 @@ extraction:
+         - libldap2-dev
+         - libcurl4-gnutls-dev
+         - libgeoip-dev
+-        - libpcre3-dev
++        - libpcre2-dev
+         - libmemcached-dev
+         - libmicrohttpd-dev
+         - librabbitmq-dev
+diff --git a/Makefile.conf.template b/Makefile.conf.template
+index ed7bc257a..a0c8aa9ae 100644
+--- a/Makefile.conf.template
++++ b/Makefile.conf.template
+@@ -19,13 +19,13 @@
+ #db_postgres= Provides Postgres connectivity for OpenSIPS | PostgreSQL library and development library - typically libpq5 and libpq-dev
+ #db_sqlite= Provides SQLite connectivity for OpenSIPS | SQLite library and development library - typically libsqlite3 and libsqlite3-dev
+ #db_unixodbc= Allows to use the unixodbc package with OpenSIPS | ODBC library and ODBC development library
+-#dialplan= Implements generic string translations based on matching and replacement rules | PCRE development library, typically libpcre-dev
++#dialplan= Implements generic string translations based on matching and replacement rules | PCRE development library, typically libpcre2-dev
+ #emergency= Provides emergency call treatment for OpenSIPS | CURL dev library - typically libcurl4-openssl-dev
+ #event_rabbitmq= Provides the implementation of a RabbitMQ client for the Event Interface | RabbitMQ development library, librabbitmq-dev
+ #event_sqs= Provides the implementation of a Amazon SQS client for the Event Interface | AWS SDK C++, aws-sdk-cpp
+ #event_kafka= Provides the implementation of an Apache Kafka producer for the Event Interface | Kafka development library, librdkafka-dev
+ #h350= Enables access to SIP account data stored in an LDAP [RFC4510] directory containing H.350 commObjects | OpenLDAP library & development files, typically libldap and libldap-dev
+-#regex= Offers matching operations against regular expressions using the powerful PCRE library. | Development library for PCRE, typically libpcre-dev
++#regex= Offers matching operations against regular expressions using the powerful PCRE library. | Development library for PCRE, typically libpcre2-dev
+ #identity= Adds support for SIP Identity (see RFC 4474). | SSL library, typically libssl
+ #jabber= Integrates XODE XML parser for parsing Jabber messages | Expat library.
+ #json= Introduces a new type of variable that provides both serialization and de-serialization from JSON format. | JSON library, libjson
+diff --git a/modules/dialplan/dialplan.h b/modules/dialplan/dialplan.h
+index 954359a7a..c4af9435f 100644
+--- a/modules/dialplan/dialplan.h
++++ b/modules/dialplan/dialplan.h
+@@ -31,7 +31,8 @@
+ 
+ #include "../../db/db.h"
+ #include "../../re.h"
+-#include <pcre.h>
++#define PCRE2_CODE_UNIT_WIDTH 8
++#include <pcre2.h>
+ 
+ #define REGEX_OP	1
+ #define EQUAL_OP	0
+diff --git a/modules/regex/regex_mod.c b/modules/regex/regex_mod.c
+index 59d5a6724..d1a91449c 100644
+--- a/modules/regex/regex_mod.c
++++ b/modules/regex/regex_mod.c
+@@ -24,6 +24,7 @@
+  *  2009-01-14  initial version (Iñaki Baz Castillo)
+  *  2023-08-12  export pcres_match to MI (Fabien Aunay)
+  *  2023-08-12  export pcres_match_group to MI (Fabien Aunay)
++ *  2025-09-17  switch to libpcre2 (Steven Ayre)
+  */
+ 
+ 
+@@ -39,7 +40,8 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <sys/stat.h>
+-#include <pcre.h>
++#define PCRE2_CODE_UNIT_WIDTH 8
++#include <pcre2.h>
+ #include "../../sr_module.h"
+ #include "../../dprint.h"
+ #include "../../pt.h"
+diff --git a/packaging/arch/Makefile.conf.template b/packaging/arch/Makefile.conf.template
+index 27a7ba8ad..f0dc257b3 100644
+--- a/packaging/arch/Makefile.conf.template
++++ b/packaging/arch/Makefile.conf.template
+@@ -17,11 +17,11 @@
+ #db_postgres= Provides Postgres connectivity for OpenSIPS | PostgreSQL library and development library - tipically libpq5 and libpq-dev
+ #db_sqlite= Provides SQLite connectivity for OpenSIPS | SQLite library and development library - tipically libsqlite3 and libsqlite3-dev
+ #db_unixodbc= Allows to use the unixodbc package with OpenSIPS | ODBC library and ODBC development library
+-#dialplan= Implements generic string translations based on matching and replacement rules | PCRE development library, tipically libpcre-dev
++#dialplan= Implements generic string translations based on matching and replacement rules | PCRE development library, tipically libpcre2-dev
+ #emergency= Provides emergency call treatment for OpenSIPS | CURL dev library - tipically libcurl4-openssl-dev
+ #event_rabbitmq= Provides the implementation of a RabbitMQ client for the Event Interface | RabbitMQ development library, librabbitmq-dev
+ #h350= Enables access to SIP account data stored in an LDAP [RFC4510] directory containing H.350 commObjects | OpenLDAP library & development files, tipically libldap and libldap-dev
+-#regex= Offers matching operations against regular expressions using the powerful PCRE library. | Development library for PCRE, tipically libpcre-dev
++#regex= Offers matching operations against regular expressions using the powerful PCRE library. | Development library for PCRE, tipically libpcre2-dev
+ #identity= Adds support for SIP Identity (see RFC 4474). | SSL library, tipically libssl
+ #jabber= Integrates XODE XML parser for parsing Jabber messages | Expat library.
+ #json= Introduces a new type of variable that provides both serialization and de-serialization from JSON format. | JSON library, libjson
+diff --git a/packaging/arch/PKGBUILD.git b/packaging/arch/PKGBUILD.git
+index ad3387460..882491be9 100644
+--- a/packaging/arch/PKGBUILD.git
++++ b/packaging/arch/PKGBUILD.git
+@@ -128,7 +128,7 @@ package_opensips-git() {
+ 		'mongo-c-driver: C-Interface for Mongo-DB support'
+ 		'net-snmp: SNMP support'
+ 		'osptoolkit: OSP Toolkit support'
+-		'pcre: Perl Regular-Expression support'
++		'pcre2: Perl Regular-Expression support'
+ 		'perl: Perl support'
+ 		'postgresql-libs: PostgreSQL-DB support'
+ 		'python2: Python v2 support'
+diff --git a/packaging/debian/control b/packaging/debian/control
+index 56a7b5587..141f815f6 100644
+--- a/packaging/debian/control
++++ b/packaging/debian/control
+@@ -29,7 +29,7 @@ Build-Depends: bison,
+                libbson-dev | base-files,
+                libmongoc-dev | base-files,
+                libncurses5-dev,
+-               libpcre3-dev,
++               libpcre2-dev,
+                libperl-dev,
+                libpq-dev,
+                librabbitmq-dev,
+diff --git a/packaging/redhat_fedora/opensips.spec b/packaging/redhat_fedora/opensips.spec
+index 6ab686c58..5135a383f 100644
+--- a/packaging/redhat_fedora/opensips.spec
++++ b/packaging/redhat_fedora/opensips.spec
+@@ -79,7 +79,7 @@ BuildRequires:  openldap-devel
+ BuildRequires:  curl-devel
+ # BuildRequires:  GeoIP-devel
+ BuildRequires:  libmaxminddb-devel
+-BuildRequires:  pcre-devel
++BuildRequires:  pcre2-devel
+ %if 0%{?_with_python3:1}
+ BuildRequires:  python3-devel
+ %else
+diff --git a/packaging/solaris/regex-preinstall b/packaging/solaris/regex-preinstall
+index 38d94c61f..79ca6da14 100644
+--- a/packaging/solaris/regex-preinstall
++++ b/packaging/solaris/regex-preinstall
+@@ -2,7 +2,7 @@
+ # Script for checking prerequisites for OpenSIPS-xmlrpc
+ 
+ BASE="OpenSIPS-base"
+-LIBPCRE="libpcre.so"
++LIBPCRE="libpcre2.so"
+ TMPLIST="/tmp/.opensipspcre"
+ 
+ pkginfo | grep -i $BASE > /dev/null
+diff --git a/scripts/build/apt_requirements.txt b/scripts/build/apt_requirements.txt
+index f094b73e3..f95bd22f3 100644
+--- a/scripts/build/apt_requirements.txt
++++ b/scripts/build/apt_requirements.txt
+@@ -13,9 +13,8 @@ libmaxminddb-dev
+ libmemcached-dev
+ libmicrohttpd-dev
+ libmnl-dev
+-libmysqlclient-dev
+ libncurses5-dev
+-libpcre3-dev
++libpcre2-dev
+ libperl-dev
+ libpq-dev
+ librabbitmq-dev
+@@ -27,7 +26,7 @@ libxml2-dev
+ make
+ odbcinst
+ patch
+-python-dev
++python3-dev
+ unixodbc
+ unixodbc-dev
+ uuid-dev

diff --git a/opensips-0014-update-dialplan-module-for-pcre2.patch b/opensips-0014-update-dialplan-module-for-pcre2.patch
new file mode 100644
index 0000000..6e1e206
--- /dev/null
+++ b/opensips-0014-update-dialplan-module-for-pcre2.patch
@@ -0,0 +1,337 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Steve Ayre <steven.ayre@dubber.net>
+Date: Thu, 18 Sep 2025 15:47:58 +0100
+Subject: [PATCH] update dialplan module for pcre2
+
+(cherry picked from commit c58e3af0cc7b44ceb304ac1b6d2c8b45feca4b5b)
+
+diff --git a/modules/dialplan/Makefile b/modules/dialplan/Makefile
+index a7c6a0a91..c4b35720a 100644
+--- a/modules/dialplan/Makefile
++++ b/modules/dialplan/Makefile
+@@ -9,11 +9,11 @@ NAME=dialplan.so
+ # CROSS_COMPILE=true
+ 
+ ifeq ($(CROSS_COMPILE),)
+-PCRE_BUILDER := $(shell \
+-	if which pcre-config >/dev/null 2>/dev/null; then \
+-		echo 'pcre-config'; \
+-	elif pkg-config --exists libcre; then \
+-		echo 'pkg-config libpcre'; \
++PCRE_BUILDER = $(shell \
++	if which pcre2-config >/dev/null 2>/dev/null; then \
++		echo 'pcre2-config'; \
++	elif pkg-config --exists libpcre2-8; then \
++		echo 'pkg-config libpcre2-8'; \
+ 	fi)
+ endif
+ 
+@@ -21,10 +21,10 @@ ifeq ($(PCRE_BUILDER),)
+ 	DEFS += -I$(SYSBASE)/include \
+ 			-I$(LOCALBASE)/include
+ 	LIBS += -L$(SYSBASE)/lib \
+-			-L$(LOCALBASE)/lib -lpcre
++			-L$(LOCALBASE)/lib -lpcre2-8
+ else
+ 	DEFS += $(shell $(PCRE_BUILDER) --cflags)
+-	LIBS += $(shell $(PCRE_BUILDER) --libs)
++	LIBS += $(shell $(PCRE_BUILDER) --libs8)
+ endif
+ 
+ include ../../Makefile.modules
+diff --git a/modules/dialplan/README b/modules/dialplan/README
+index fe720ede9..3cf84f02e 100644
+--- a/modules/dialplan/README
++++ b/modules/dialplan/README
+@@ -243,7 +243,7 @@ Chapter 1. Admin Guide
+ 
+    The following libraries or applications must be installed
+    before running OpenSIPS with this module loaded:
+-     * libpcre-dev - the development libraries of PCRE.
++     * libpcre2-dev - the development libraries of PCRE.
+ 
+ 1.6. Exported Parameters
+ 
+diff --git a/modules/dialplan/dialplan.c b/modules/dialplan/dialplan.c
+index 454f9a6ca..3b37e3e59 100644
+--- a/modules/dialplan/dialplan.c
++++ b/modules/dialplan/dialplan.c
+@@ -869,51 +869,61 @@ static mi_response_t *mi_translate3(const mi_params_t *params,
+ }
+ 
+ 
+-void * wrap_shm_malloc(size_t size)
++void * wrap_shm_malloc(PCRE2_SIZE size, void * memory_data)
+ {
++	UNUSED(memory_data);
+ 	return shm_malloc(size);
+ }
+ 
+-void  wrap_shm_free(void * p )
++void wrap_shm_free(void * p, void * memory_data)
+ {
++	UNUSED(memory_data);
+ 	shm_free(p);
+ }
+ 
+-
+-pcre * wrap_pcre_compile(char *  pattern, int flags)
++pcre2_code * wrap_pcre_compile(char *  pattern, int flags)
+ {
+-		pcre * ret ;
+-		func_malloc old_malloc ;
+-		func_free old_free;
+-		const char * error;
+-		int erroffset;
+-		int pcre_flags = 0;
+-
+-
+-		old_malloc = pcre_malloc;
+-		old_free = pcre_free;
+-
+-		pcre_malloc = wrap_shm_malloc;
+-		pcre_free = wrap_shm_free;
+-
+-		if (flags & DP_CASE_INSENSITIVE)
+-			pcre_flags |= PCRE_CASELESS;
+-
+-		ret = pcre_compile(
+-				pattern,			/* the pattern */
+-				pcre_flags,			/* default options */
+-				&error,				/* for error message */
+-				&erroffset,			/* for error offset */
+-				NULL);
+-
+-		pcre_malloc = old_malloc;
+-		pcre_free = old_free;
+-
+-		return ret;
++	pcre2_general_context *gcontext;
++	pcre2_compile_context *ccontext;
++	pcre2_code * ret ;
++	int error;
++	PCRE2_SIZE erroffset;
++	int pcre_flags = 0;
++
++	// TODO generate once per worker
++	gcontext = pcre2_general_context_create(wrap_shm_malloc, wrap_shm_free, NULL);
++	if (!gcontext) {
++		LM_ERR("Unable to create pcre general context\n");
++		return NULL;
++	}
++
++	// TODO generate once per worker
++	ccontext = pcre2_compile_context_create(gcontext);
++	if (!ccontext) {
++		LM_ERR("Unable to create pcre compile context\n");
++		pcre2_general_context_free(gcontext);
++		return NULL;
++	}
++
++	if (flags & DP_CASE_INSENSITIVE)
++		pcre_flags |= PCRE2_CASELESS;
++
++	ret = pcre2_compile(
++			(PCRE2_SPTR)pattern,		/* the pattern */
++			PCRE2_ZERO_TERMINATED,
++			pcre_flags,			/* default options */
++			&error,				/* for error message */
++			&erroffset,			/* for error offset */
++			ccontext);                      /* compile context, to allocate memory in shm */
++
++	pcre2_compile_context_free(ccontext);
++	pcre2_general_context_free(gcontext);
++
++	return ret;
+ }
+ 
+-void wrap_pcre_free( pcre* re)
++void wrap_pcre_free( pcre2_code* re)
+ {
++	// TODO pcre2_code_free
+ 	shm_free(re);
+-
+ }
+diff --git a/modules/dialplan/dialplan.h b/modules/dialplan/dialplan.h
+index c4af9435f..d798ae4a7 100644
+--- a/modules/dialplan/dialplan.h
++++ b/modules/dialplan/dialplan.h
+@@ -49,7 +49,7 @@ typedef struct dpl_node{
+ 	int matchop;
+ 	int match_flags;
+ 	str match_exp, subst_exp, repl_exp; /*keeping the original strings*/
+-	pcre * match_comp, * subst_comp; /*compiled patterns*/
++	pcre2_code * match_comp, * subst_comp; /*compiled patterns*/
+ 	struct subst_expr * repl_comp;
+ 	str attrs;
+ 	str timerec;
+@@ -122,19 +122,11 @@ struct subst_expr* repl_exp_parse(str subst);
+ void repl_expr_free(struct subst_expr *se);
+ int translate(struct sip_msg *msg, str user_name, str* repl_user, dpl_id_p idp, str *);
+ int rule_translate(struct sip_msg *msg, str , dpl_node_t * rule,  str *);
+-int test_match(str string, pcre * exp, int * out, int out_max);
++int test_match(str string, pcre2_code * exp, int * out, int out_max);
+ 
+ 
+-typedef void * (*func_malloc)(size_t );
+-typedef void  (*func_free)(void * );
+-
+-void * wrap_shm_malloc(size_t size);
+-void  wrap_shm_free(void *);
+-
+-
+-pcre * wrap_pcre_compile(char *  pattern, int flags);
+-void wrap_pcre_free( pcre*);
+-
++pcre2_code * wrap_pcre_compile(char *  pattern, int flags);
++void wrap_pcre_free( pcre2_code*);
+ 
+ extern rw_lock_t *ref_lock;
+ extern str dp_df_part;
+diff --git a/modules/dialplan/dp_db.c b/modules/dialplan/dp_db.c
+index e88682a5f..cacac3018 100644
+--- a/modules/dialplan/dp_db.c
++++ b/modules/dialplan/dp_db.c
+@@ -467,12 +467,12 @@ int str_to_shm(str src, str * dest)
+ dpl_node_t * build_rule(db_val_t * values)
+ {
+ 	tmrec_expr *parsed_timerec;
+-	pcre * match_comp, *subst_comp;
++	pcre2_code * match_comp, *subst_comp;
+ 	struct subst_expr * repl_comp;
+ 	dpl_node_t * new_rule;
+ 	str match_exp, subst_exp, repl_exp, attrs, timerec;
+ 	int matchop;
+-	int namecount;
++	uint32_t namecount;
+ 
+ 	matchop = VAL_INT(values+2);
+ 
+@@ -524,10 +524,9 @@ dpl_node_t * build_rule(db_val_t * values)
+ 		}
+ 	}
+ 
+-	pcre_fullinfo(
++	pcre2_pattern_info(
+ 		subst_comp, /* the compiled pattern */
+-		NULL, /* no extra data - we didn't study the pattern */
+-		PCRE_INFO_CAPTURECOUNT, /* number of named substrings */
++		PCRE2_INFO_CAPTURECOUNT, /* number of named substrings */
+ 		&namecount); /* where to put the answer */
+ 
+ 	LM_DBG("references:%d , max:%d\n",namecount,
+diff --git a/modules/dialplan/dp_repl.c b/modules/dialplan/dp_repl.c
+index 6ff94dd03..4317b334d 100644
+--- a/modules/dialplan/dp_repl.c
++++ b/modules/dialplan/dp_repl.c
+@@ -110,11 +110,11 @@ int rule_translate(struct sip_msg *msg, str string, dpl_node_t * rule,
+ {
+ 	int repl_nb, offset, match_nb;
+ 	struct replace_with token;
+-	pcre * subst_comp;
++	pcre2_code * subst_comp;
+ 	struct subst_expr * repl_comp;
+ 	pv_value_t sv;
+ 	str* uri;
+-	int capturecount;
++	uint32_t capturecount;
+ 	char *match_begin;
+ 	int match_len;
+ 
+@@ -133,11 +133,10 @@ int rule_translate(struct sip_msg *msg, str string, dpl_node_t * rule,
+ 
+ 	if(subst_comp){
+ 
+-		pcre_fullinfo(
+-		subst_comp,                   /* the compiled pattern */
+-		NULL,                 /* no extra data - we didn't study the pattern */
+-		PCRE_INFO_CAPTURECOUNT ,  /* number of named substrings */
+-		&capturecount);          /* where to put the answer */
++		pcre2_pattern_info(
++			subst_comp,              /* the compiled pattern */
++			PCRE2_INFO_CAPTURECOUNT, /* number of named substrings */
++			&capturecount);          /* where to put the answer */
+ 
+ 
+ 		/*just in case something went wrong at load time*/
+@@ -397,11 +396,13 @@ int translate(struct sip_msg *msg, str input, str * output, dpl_id_p idp, str *
+ }
+ 
+ 
+-int test_match(str string, pcre * exp, int * out, int out_max)
++int test_match(str string, pcre2_code * exp, int * out, int out_max)
+ {
+ 	int i, result_count;
+ 	char *substring_start;
+ 	int substring_length;
++	pcre2_match_data *match_data;
++	PCRE2_SIZE *ovector;
+ 	UNUSED(substring_start);
+ 	UNUSED(substring_length);
+ 
+@@ -410,34 +411,50 @@ int test_match(str string, pcre * exp, int * out, int out_max)
+ 		return -1;
+ 	}
+ 
+-	result_count = pcre_exec(
+-							exp, /* the compiled pattern */
+-							NULL, /* no extra data - we didn't study the pattern */
+-							string.s, /* the subject string */
+-							string.len, /* the length of the subject */
+-							0, /* start at offset 0 in the subject */
+-							0, /* default options */
+-							out, /* output vector for substring information */
+-							out_max); /* number of elements in the output vector */
+-
+-	if( result_count < 0 )
+-		return result_count;
++	match_data = pcre2_match_data_create_from_pattern(exp, NULL);
++	if (!match_data) {
++		LM_ERR("failed to allocate match data\n");
++		return -1;
++	}
+ 
+-	if( result_count == 0)
++	result_count = pcre2_match(
++		exp, /* the compiled pattern */
++		(PCRE2_SPTR)string.s, /* the subject string */
++		(PCRE2_SIZE)string.len, /* the length of the subject */
++		0, /* start at offset 0 in the subject */
++		0, /* default options */
++		match_data, /* match data block */
++		NULL); /* match context */
++
++	if (result_count < 0)
+ 	{
+-		LM_ERR("Not enough space for mathing\n");
++		pcre2_match_data_free(match_data);
+ 		return result_count;
+ 	}
+ 
++	if (result_count == 0)
++	{
++		LM_ERR("Not enough space for matching\n");
++		pcre2_match_data_free(match_data);
++		return result_count;
++	}
+ 
++	ovector = pcre2_get_ovector_pointer(match_data);
+ 	for (i = 0; i < result_count; i++)
+ 	{
++		// avoid buffer overflow
++		if (i >= out_max)
++			break;
++
++		// ovector is freed by pcre2_match_data_free, copy offsets to out[]
++		out[i] = ovector[i];
++
+ 		substring_start = string.s + out[2 * i];
+ 		substring_length = out[2 * i + 1] - out[2 * i];
+ 		LM_DBG("test_match:[%d] %.*s\n",i, substring_length, substring_start);
+ 	}
+ 
+-
++	pcre2_match_data_free(match_data);
+ 	return result_count;
+ }
+ 

diff --git a/opensips-0015-create-pcre2-compile-context-once-instead-of-for-eac.patch b/opensips-0015-create-pcre2-compile-context-once-instead-of-for-eac.patch
new file mode 100644
index 0000000..9f2ddab
--- /dev/null
+++ b/opensips-0015-create-pcre2-compile-context-once-instead-of-for-eac.patch
@@ -0,0 +1,111 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Steve Ayre <steven.ayre@dubber.net>
+Date: Thu, 18 Sep 2025 15:54:02 +0100
+Subject: [PATCH] create pcre2 compile context once instead of for each compile
+
+(cherry picked from commit 6082b43fa8b44cbfea7de8afb38998354b54d1fb)
+
+diff --git a/modules/dialplan/dialplan.c b/modules/dialplan/dialplan.c
+index 3b37e3e59..8bc7cfbec 100644
+--- a/modules/dialplan/dialplan.c
++++ b/modules/dialplan/dialplan.c
+@@ -86,6 +86,12 @@ static str database_url = {NULL, 0};
+ 
+ void *dp_srg = NULL;
+ 
++pcre2_general_context *dp_gcontext = NULL;
++pcre2_compile_context *dp_ccontext = NULL;
++
++void * wrap_shm_malloc(PCRE2_SIZE size, void * memory_data);
++void wrap_shm_free(void * p, void * memory_data);
++
+ 
+ static const param_export_t mod_params[]={
+ 	{ "partition",		STR_PARAM|USE_FUNC_PARAM,
+@@ -398,6 +404,18 @@ static int mod_init(void)
+ 		return -1;
+ 	}
+ 
++	dp_gcontext = pcre2_general_context_create(wrap_shm_malloc, wrap_shm_free, NULL);
++	if (!dp_gcontext) {
++		LM_ERR("Unable to create pcre general context\n");
++		return -1;
++	}
++
++	dp_ccontext = pcre2_compile_context_create(dp_gcontext);
++	if (!dp_ccontext) {
++		LM_ERR("Unable to create pcre compile context\n");
++		return -1;
++	}
++
+ 	return 0;
+ }
+ 
+@@ -452,6 +470,18 @@ static void mod_destroy(void)
+ 	}
+ 
+ 	destroy_data();
++
++	if (dp_ccontext)
++	{
++		pcre2_compile_context_free(dp_ccontext);
++		dp_ccontext = NULL;
++	}
++
++	if (dp_gcontext)
++	{
++		pcre2_general_context_free(dp_gcontext);
++		dp_gcontext = NULL;
++	}
+ }
+ 
+ 
+@@ -883,28 +913,11 @@ void wrap_shm_free(void * p, void * memory_data)
+ 
+ pcre2_code * wrap_pcre_compile(char *  pattern, int flags)
+ {
+-	pcre2_general_context *gcontext;
+-	pcre2_compile_context *ccontext;
+ 	pcre2_code * ret ;
+ 	int error;
+ 	PCRE2_SIZE erroffset;
+ 	int pcre_flags = 0;
+ 
+-	// TODO generate once per worker
+-	gcontext = pcre2_general_context_create(wrap_shm_malloc, wrap_shm_free, NULL);
+-	if (!gcontext) {
+-		LM_ERR("Unable to create pcre general context\n");
+-		return NULL;
+-	}
+-
+-	// TODO generate once per worker
+-	ccontext = pcre2_compile_context_create(gcontext);
+-	if (!ccontext) {
+-		LM_ERR("Unable to create pcre compile context\n");
+-		pcre2_general_context_free(gcontext);
+-		return NULL;
+-	}
+-
+ 	if (flags & DP_CASE_INSENSITIVE)
+ 		pcre_flags |= PCRE2_CASELESS;
+ 
+@@ -914,16 +927,14 @@ pcre2_code * wrap_pcre_compile(char *  pattern, int flags)
+ 			pcre_flags,			/* default options */
+ 			&error,				/* for error message */
+ 			&erroffset,			/* for error offset */
+-			ccontext);                      /* compile context, to allocate memory in shm */
+-
+-	pcre2_compile_context_free(ccontext);
+-	pcre2_general_context_free(gcontext);
++			dp_ccontext);                      /* compile context, to allocate memory in shm */
+ 
+ 	return ret;
+ }
+ 
+ void wrap_pcre_free( pcre2_code* re)
+ {
+-	// TODO pcre2_code_free
++	// *not* pcre2_code_free
++	// shm_free is used because pcre2_general_context_create overrides malloc with wrap_shm_malloc
+ 	shm_free(re);
+ }

diff --git a/opensips-0016-Makefile-tweaks-to-avoid-shell-.-expansions-from-fai.patch b/opensips-0016-Makefile-tweaks-to-avoid-shell-.-expansions-from-fai.patch
new file mode 100644
index 0000000..c044c4b
--- /dev/null
+++ b/opensips-0016-Makefile-tweaks-to-avoid-shell-.-expansions-from-fai.patch
@@ -0,0 +1,41 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Ken Rice <krice@sipnavigator.com>
+Date: Thu, 11 Sep 2025 10:57:39 -0400
+Subject: [PATCH] Makefile tweaks to avoid $(shell ...) expansions from failing
+
+Fixes #3717
+
+(cherry picked from commit a3ae498d8726894753483738e801dfc0e63e3ba9)
+
+diff --git a/modules/dialplan/Makefile b/modules/dialplan/Makefile
+index c4b35720a..505bd9540 100644
+--- a/modules/dialplan/Makefile
++++ b/modules/dialplan/Makefile
+@@ -9,7 +9,7 @@ NAME=dialplan.so
+ # CROSS_COMPILE=true
+ 
+ ifeq ($(CROSS_COMPILE),)
+-PCRE_BUILDER = $(shell \
++PCRE_BUILDER := $(shell \
+ 	if which pcre2-config >/dev/null 2>/dev/null; then \
+ 		echo 'pcre2-config'; \
+ 	elif pkg-config --exists libpcre2-8; then \
+diff --git a/modules/regex/Makefile b/modules/regex/Makefile
+index 79a150839..496c0438e 100644
+--- a/modules/regex/Makefile
++++ b/modules/regex/Makefile
+@@ -10,10 +10,10 @@ NAME=regex.so
+ 
+ ifeq ($(CROSS_COMPILE),)
+ PCRE_BUILDER := $(shell \
+-	if which pcre-config >/dev/null 2>/dev/null; then \
+-		echo 'pcre-config'; \
+-	elif pkg-config --exists libcre; then \
+-		echo 'pkg-config libpcre'; \
++	if which pcre2-config >/dev/null 2>/dev/null; then \
++		echo 'pcre2-config'; \
++	elif pkg-config --exists libpcre2-8; then \
++		echo 'pkg-config libpcre2-8'; \
+ 	fi)
+ endif
+ 

diff --git a/opensips-0017-dialplan-fix-copying-subst-s-out-vector.patch b/opensips-0017-dialplan-fix-copying-subst-s-out-vector.patch
new file mode 100644
index 0000000..a8406fc
--- /dev/null
+++ b/opensips-0017-dialplan-fix-copying-subst-s-out-vector.patch
@@ -0,0 +1,40 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Razvan Crainea <razvan@opensips.org>
+Date: Tue, 2 Dec 2025 15:40:15 +0200
+Subject: [PATCH] dialplan: fix copying subst's out vector
+
+(cherry picked from commit 30825e4e0809a1a61f06cec964589c825645b62b)
+
+diff --git a/modules/dialplan/dp_repl.c b/modules/dialplan/dp_repl.c
+index 4317b334d..0764148a9 100644
+--- a/modules/dialplan/dp_repl.c
++++ b/modules/dialplan/dp_repl.c
+@@ -440,21 +440,21 @@ int test_match(str string, pcre2_code * exp, int * out, int out_max)
+ 	}
+ 
+ 	ovector = pcre2_get_ovector_pointer(match_data);
+-	for (i = 0; i < result_count; i++)
+-	{
+-		// avoid buffer overflow
+-		if (i >= out_max)
+-			break;
++	if (2 * result_count >= out_max)
++		result_count = out_max / 2;
+ 
+-		// ovector is freed by pcre2_match_data_free, copy offsets to out[]
++	// ovector is freed by pcre2_match_data_free, copy offsets to out[]
++	for (i = 0; i < result_count * 2; i++)
+ 		out[i] = ovector[i];
++	pcre2_match_data_free(match_data);
+ 
++	for (i = 0; i < result_count; i++)
++	{
+ 		substring_start = string.s + out[2 * i];
+ 		substring_length = out[2 * i + 1] - out[2 * i];
+ 		LM_DBG("test_match:[%d] %.*s\n",i, substring_length, substring_start);
+ 	}
+ 
+-	pcre2_match_data_free(match_data);
+ 	return result_count;
+ }
+ 

diff --git a/opensips-0018-dialplan-make-module-work-with-both-pcre2-and-pcre3-.patch b/opensips-0018-dialplan-make-module-work-with-both-pcre2-and-pcre3-.patch
new file mode 100644
index 0000000..b61424f
--- /dev/null
+++ b/opensips-0018-dialplan-make-module-work-with-both-pcre2-and-pcre3-.patch
@@ -0,0 +1,249 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Razvan Crainea <razvan@opensips.org>
+Date: Thu, 4 Dec 2025 19:27:07 +0200
+Subject: [PATCH] dialplan: make module work with both pcre2 and pcre3 libs
+
+(cherry picked from commit 67483a5a27ce656eaf9409f7710cf67798e70aac)
+
+diff --git a/modules/dialplan/Makefile b/modules/dialplan/Makefile
+index 505bd9540..a937d3285 100644
+--- a/modules/dialplan/Makefile
++++ b/modules/dialplan/Makefile
+@@ -8,12 +8,16 @@ NAME=dialplan.so
+ # the autodetection
+ # CROSS_COMPILE=true
+ 
++PCRE_LIB ?= pcre2-8
++PCRE_VERSION ?= $(word 1,$(subst -, , $(PCRE_LIB)))
++PCRE_CONFIG ?= $(PCRE_VERSION)-config
++
+ ifeq ($(CROSS_COMPILE),)
+ PCRE_BUILDER := $(shell \
+-	if which pcre2-config >/dev/null 2>/dev/null; then \
+-		echo 'pcre2-config'; \
+-	elif pkg-config --exists libpcre2-8; then \
+-		echo 'pkg-config libpcre2-8'; \
++	if which $(PCRE_CONFIG) >/dev/null 2>/dev/null; then \
++		echo '$(PCRE_CONFIG)'; \
++	elif pkg-config --exists lib$(PCRE_LIB); then \
++		echo 'pkg-config lib$(PCRE_LIB)'; \
+ 	fi)
+ endif
+ 
+@@ -21,10 +25,12 @@ ifeq ($(PCRE_BUILDER),)
+ 	DEFS += -I$(SYSBASE)/include \
+ 			-I$(LOCALBASE)/include
+ 	LIBS += -L$(SYSBASE)/lib \
+-			-L$(LOCALBASE)/lib -lpcre2-8
++			-L$(LOCALBASE)/lib -l$(PCRE_LIB)
+ else
+ 	DEFS += $(shell $(PCRE_BUILDER) --cflags)
+-	LIBS += $(shell $(PCRE_BUILDER) --libs8)
++	LIBS += $(shell $(PCRE_BUILDER) --libs 2>/dev/null) \
++			$(shell $(PCRE_BUILDER) --libs$(word 2,$(subst -, ,$(PCRE_LIB))) 2>/dev/null)
+ endif
++DEFS += -D$(shell echo $(PCRE_VERSION) | tr 'a-z' 'A-Z')_LIB
+ 
+ include ../../Makefile.modules
+diff --git a/modules/dialplan/dialplan.c b/modules/dialplan/dialplan.c
+index 8bc7cfbec..d62ad80e9 100644
+--- a/modules/dialplan/dialplan.c
++++ b/modules/dialplan/dialplan.c
+@@ -86,12 +86,32 @@ static str database_url = {NULL, 0};
+ 
+ void *dp_srg = NULL;
+ 
++#ifdef PCRE2_LIB
+ pcre2_general_context *dp_gcontext = NULL;
+ pcre2_compile_context *dp_ccontext = NULL;
+ 
+-void * wrap_shm_malloc(PCRE2_SIZE size, void * memory_data);
+-void wrap_shm_free(void * p, void * memory_data);
++void * wrap_shm_malloc(PCRE2_SIZE size, void * memory_data)
++{
++	UNUSED(memory_data);
++	return shm_malloc(size);
++}
++
++void  wrap_shm_free(void * p, void * memory_data)
++{
++	UNUSED(memory_data);
++	shm_free(p);
++}
++#else
++void * wrap_shm_malloc(size_t size)
++{
++	return shm_malloc(size);
++}
+ 
++void  wrap_shm_free(void * p )
++{
++	shm_free(p);
++}
++#endif
+ 
+ static const param_export_t mod_params[]={
+ 	{ "partition",		STR_PARAM|USE_FUNC_PARAM,
+@@ -404,6 +424,7 @@ static int mod_init(void)
+ 		return -1;
+ 	}
+ 
++#ifdef PCRE2_LIB
+ 	dp_gcontext = pcre2_general_context_create(wrap_shm_malloc, wrap_shm_free, NULL);
+ 	if (!dp_gcontext) {
+ 		LM_ERR("Unable to create pcre general context\n");
+@@ -415,6 +436,8 @@ static int mod_init(void)
+ 		LM_ERR("Unable to create pcre compile context\n");
+ 		return -1;
+ 	}
++#endif
++
+ 
+ 	return 0;
+ }
+@@ -470,7 +493,7 @@ static void mod_destroy(void)
+ 	}
+ 
+ 	destroy_data();
+-
++#ifdef PCRE2_LIB
+ 	if (dp_ccontext)
+ 	{
+ 		pcre2_compile_context_free(dp_ccontext);
+@@ -482,6 +505,7 @@ static void mod_destroy(void)
+ 		pcre2_general_context_free(dp_gcontext);
+ 		dp_gcontext = NULL;
+ 	}
++#endif
+ }
+ 
+ 
+@@ -899,25 +923,21 @@ static mi_response_t *mi_translate3(const mi_params_t *params,
+ }
+ 
+ 
+-void * wrap_shm_malloc(PCRE2_SIZE size, void * memory_data)
+-{
+-	UNUSED(memory_data);
+-	return shm_malloc(size);
+-}
+-
+-void wrap_shm_free(void * p, void * memory_data)
+-{
+-	UNUSED(memory_data);
+-	shm_free(p);
+-}
+-
+ pcre2_code * wrap_pcre_compile(char *  pattern, int flags)
+ {
+ 	pcre2_code * ret ;
+-	int error;
++	PCRE2_ERR error;
+ 	PCRE2_SIZE erroffset;
+ 	int pcre_flags = 0;
+ 
++#ifndef PCRE2_LIB
++	void *(*old_malloc)(size_t) = pcre_malloc;
++	void  (*old_free)(void *) = pcre_free;
++
++	pcre_malloc = wrap_shm_malloc;
++	pcre_free = wrap_shm_free;
++#endif
++
+ 	if (flags & DP_CASE_INSENSITIVE)
+ 		pcre_flags |= PCRE2_CASELESS;
+ 
+@@ -929,6 +949,11 @@ pcre2_code * wrap_pcre_compile(char *  pattern, int flags)
+ 			&erroffset,			/* for error offset */
+ 			dp_ccontext);                      /* compile context, to allocate memory in shm */
+ 
++#ifndef PCRE2_LIB
++	pcre_malloc = old_malloc;
++	pcre_free = old_free;
++#endif
++
+ 	return ret;
+ }
+ 
+diff --git a/modules/dialplan/dialplan.h b/modules/dialplan/dialplan.h
+index d798ae4a7..7d1578e79 100644
+--- a/modules/dialplan/dialplan.h
++++ b/modules/dialplan/dialplan.h
+@@ -31,8 +31,25 @@
+ 
+ #include "../../db/db.h"
+ #include "../../re.h"
++
++#ifdef PCRE2_LIB
+ #define PCRE2_CODE_UNIT_WIDTH 8
++#define PCRE2_ERR int
+ #include <pcre2.h>
++#else
++/* backwards compatibility */
++#define pcre2_code pcre
++#define PCRE2_CASELESS PCRE_CASELESS
++#define PCRE2_SIZE int
++#define PCRE2_ERR const char *
++#define pcre2_pattern_info(subst_comp, flag, ret) \
++	pcre_fullinfo(subst_comp, NULL, PCRE_INFO_CAPTURECOUNT, ret);
++#define PCRE2_SPTR char *
++#define pcre2_compile(pattern, _, flags, error, erroffset, ctx) \
++	pcre_compile(pattern, flags, error, erroffset, NULL)
++#include <pcre.h>
++#endif
++
+ 
+ #define REGEX_OP	1
+ #define EQUAL_OP	0
+diff --git a/modules/dialplan/dp_repl.c b/modules/dialplan/dp_repl.c
+index 0764148a9..c6b97c23e 100644
+--- a/modules/dialplan/dp_repl.c
++++ b/modules/dialplan/dp_repl.c
+@@ -401,16 +401,36 @@ int test_match(str string, pcre2_code * exp, int * out, int out_max)
+ 	int i, result_count;
+ 	char *substring_start;
+ 	int substring_length;
++#ifdef PCRE2_LIB
+ 	pcre2_match_data *match_data;
+ 	PCRE2_SIZE *ovector;
+-	UNUSED(substring_start);
+-	UNUSED(substring_length);
++#endif
+ 
+ 	if(!exp){
+ 		LM_ERR("invalid compiled expression\n");
+ 		return -1;
+ 	}
+ 
++#ifndef PCRE2_LIB
++	result_count = pcre_exec(
++							exp, /* the compiled pattern */
++							NULL, /* no extra data - we didn't study the pattern */
++							string.s, /* the subject string */
++							string.len, /* the length of the subject */
++							0, /* start at offset 0 in the subject */
++							0, /* default options */
++							out, /* output vector for substring information */
++							out_max); /* number of elements in the output vector */
++
++	if( result_count < 0 )
++		return result_count;
++
++	if( result_count == 0)
++	{
++		LM_ERR("Not enough space for mathing\n");
++		return result_count;
++	}
++#else
+ 	match_data = pcre2_match_data_create_from_pattern(exp, NULL);
+ 	if (!match_data) {
+ 		LM_ERR("failed to allocate match data\n");
+@@ -447,6 +467,8 @@ int test_match(str string, pcre2_code * exp, int * out, int out_max)
+ 	for (i = 0; i < result_count * 2; i++)
+ 		out[i] = ovector[i];
+ 	pcre2_match_data_free(match_data);
++#endif
++
+ 
+ 	for (i = 0; i < result_count; i++)
+ 	{

diff --git a/opensips-0019-update-regex-module-for-pcre2.patch b/opensips-0019-update-regex-module-for-pcre2.patch
new file mode 100644
index 0000000..c27d61e
--- /dev/null
+++ b/opensips-0019-update-regex-module-for-pcre2.patch
@@ -0,0 +1,264 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Steve Ayre <steven.ayre@dubber.net>
+Date: Wed, 17 Sep 2025 22:11:25 +0100
+Subject: [PATCH] update regex module for pcre2
+
+(cherry picked from commit 3cc28d166b5a3d7db2cd2d944406480e5a1474f5)
+
+diff --git a/modules/regex/Makefile b/modules/regex/Makefile
+index 496c0438e..b4c2dfe07 100644
+--- a/modules/regex/Makefile
++++ b/modules/regex/Makefile
+@@ -21,10 +21,10 @@ ifeq ($(PCRE_BUILDER),)
+ 	DEFS += -I$(SYSBASE)/include \
+ 			-I$(LOCALBASE)/include
+ 	LIBS += -L$(SYSBASE)/lib \
+-			-L$(LOCALBASE)/lib -lpcre
++			-L$(LOCALBASE)/lib -lpcre2-8
+ else
+ 	DEFS += $(shell $(PCRE_BUILDER) --cflags)
+-	LIBS += $(shell $(PCRE_BUILDER) --libs)
++	LIBS += $(shell $(PCRE_BUILDER) --libs8)
+ endif
+ 
+ include ../../Makefile.modules
+diff --git a/modules/regex/regex_mod.c b/modules/regex/regex_mod.c
+index d1a91449c..9311d2b93 100644
+--- a/modules/regex/regex_mod.c
++++ b/modules/regex/regex_mod.c
+@@ -58,6 +58,8 @@
+ #define MAX_GROUPS 20            /*!< Max number of groups */
+ #define GROUP_MAX_SIZE 8192      /*!< Max size of a group */
+ 
++#define ERROR_BUF_SIZE 100
++
+ 
+ /*
+  * Locking variables
+@@ -80,8 +82,8 @@ static int pcre_extended         = 0;
+ /*
+  * Module internal parameter variables
+  */
+-static pcre **pcres;
+-static pcre ***pcres_addr;
++static pcre2_code **pcres;
++static pcre2_code ***pcres_addr;
+ static int *num_pcres;
+ static int pcre_options = 0x00000000;
+ 
+@@ -221,24 +223,24 @@ static int mod_init(void)
+ 		/* PCRE options */
+ 		if (pcre_caseless != 0) {
+ 			LM_DBG("PCRE CASELESS enabled\n");
+-			pcre_options = pcre_options | PCRE_CASELESS;
++			pcre_options = pcre_options | PCRE2_CASELESS;
+ 		}
+ 		if (pcre_multiline != 0) {
+ 			LM_DBG("PCRE MULTILINE enabled\n");
+-			pcre_options = pcre_options | PCRE_MULTILINE;
++			pcre_options = pcre_options | PCRE2_MULTILINE;
+ 		}
+ 		if (pcre_dotall != 0) {
+ 			LM_DBG("PCRE DOTALL enabled\n");
+-			pcre_options = pcre_options | PCRE_DOTALL;
++			pcre_options = pcre_options | PCRE2_DOTALL;
+ 		}
+ 		if (pcre_extended != 0) {
+ 			LM_DBG("PCRE EXTENDED enabled\n");
+-			pcre_options = pcre_options | PCRE_EXTENDED;
++			pcre_options = pcre_options | PCRE2_EXTENDED;
+ 		}
+ 		LM_DBG("PCRE options: %i\n", pcre_options);
+ 
+ 		/* Pointer to pcres */
+-		if ((pcres_addr = shm_malloc(sizeof(pcre **))) == 0) {
++		if ((pcres_addr = shm_malloc(sizeof(pcre2_code **))) == 0) {
+ 			LM_ERR("no memory for pcres_addr\n");
+ 			goto err;
+ 		}
+@@ -279,13 +281,14 @@ static int load_pcres(int action)
+ 	FILE *f;
+ 	char line[FILE_MAX_LINE];
+ 	char **patterns = NULL;
+-	pcre *pcre_tmp = NULL;
+-	int pcre_size;
++	pcre2_code *pcre_tmp = NULL;
++	size_t pcre_size;
+ 	int pcre_rc;
+-	const char *pcre_error;
+-	int pcre_erroffset;
++	int pcre_error;
++	PCRE2_UCHAR pcre_error_str[ERROR_BUF_SIZE];
++	PCRE2_SIZE pcre_erroffset;
+ 	int num_pcres_tmp = 0;
+-	pcre **pcres_tmp = NULL;
++	pcre2_code **pcres_tmp = NULL;
+ 
+ 	/* Get the lock */
+ 	lock_get(reload_lock);
+@@ -420,7 +423,7 @@ static int load_pcres(int action)
+ 	}
+ 
+ 	/* Temporal pointer of pcres */
+-	if ((pcres_tmp = pkg_malloc(sizeof(pcre *) * num_pcres_tmp)) == 0) {
++	if ((pcres_tmp = pkg_malloc(sizeof(pcre2_code *) * num_pcres_tmp)) == 0) {
+ 		LM_ERR("no more memory for pcres_tmp\n");
+ 		goto err;
+ 	}
+@@ -431,14 +434,15 @@ static int load_pcres(int action)
+ 	/* Compile the patters */
+ 	for (i=0; i<num_pcres_tmp; i++) {
+ 
+-		pcre_tmp = pcre_compile(patterns[i], pcre_options, &pcre_error, &pcre_erroffset, NULL);
++		pcre_tmp = pcre2_compile((PCRE2_SPTR)patterns[i], PCRE2_ZERO_TERMINATED, pcre_options, &pcre_error, &pcre_erroffset, NULL);
+ 		if (pcre_tmp == NULL) {
+-			LM_ERR("pcre_tmp compilation of '%s' failed at offset %d: %s\n", patterns[i], pcre_erroffset, pcre_error);
++                	pcre2_get_error_message(pcre_error, pcre_error_str, sizeof(pcre_error_str));
++			LM_ERR("pcre_tmp compilation of '%s' failed at offset %ld: %s\n", patterns[i], pcre_erroffset, pcre_error_str);
+ 			goto err;
+ 		}
+-		pcre_rc = pcre_fullinfo(pcre_tmp, NULL, PCRE_INFO_SIZE, &pcre_size);
++		pcre_rc = pcre2_pattern_info(pcre_tmp, PCRE2_INFO_SIZE, &pcre_size);
+ 		if (pcre_rc) {
+-			printf("pcre_fullinfo on compiled pattern[%i] yielded error: %d\n", i, pcre_rc);
++			printf("pcre2_pattern_info on compiled pattern[%i] yielded error: %d\n", i, pcre_rc);
+ 			goto err;
+ 		}
+ 
+@@ -448,7 +452,7 @@ static int load_pcres(int action)
+ 		}
+ 
+ 		memcpy(pcres_tmp[i], pcre_tmp, pcre_size);
+-		pcre_free(pcre_tmp);
++		pcre2_code_free(pcre_tmp);
+ 		pkg_free(patterns[i]);
+ 	}
+ 
+@@ -461,7 +465,7 @@ static int load_pcres(int action)
+ 		}
+ 		shm_free(pcres);
+ 	}
+-	if ((pcres = shm_malloc(sizeof(pcre *) * num_pcres_tmp)) == 0) {
++	if ((pcres = shm_malloc(sizeof(pcre2_code *) * num_pcres_tmp)) == 0) {
+ 		LM_ERR("no more memory for pcres\n");
+ 		goto err;
+ 	}
+@@ -469,7 +473,7 @@ static int load_pcres(int action)
+ 		pcres[i] = NULL;
+ 	}
+ 	for (i=0; i<num_pcres_tmp; i++) {
+-		pcre_rc = pcre_fullinfo(pcres_tmp[i], NULL, PCRE_INFO_SIZE, &pcre_size);
++		pcre_rc = pcre2_pattern_info(pcres_tmp[i], PCRE2_INFO_SIZE, &pcre_size);
+ 		if ((pcres[i] = shm_malloc(pcre_size)) == 0) {
+ 			LM_ERR("no more memory for pcres[%i]\n", i);
+ 			goto err;
+@@ -555,48 +559,54 @@ static void free_shared_memory(void)
+ /*! \brief Return true if the argument matches the regular expression parameter */
+ static int w_pcre_match(struct sip_msg* _msg, str* string, str* _regex_s)
+ {
+-	pcre *pcre_re = NULL;
++	pcre2_code *pcre_re = NULL;
+ 	int pcre_rc;
+-	const char *pcre_error;
+-	int pcre_erroffset;
++	int pcre_error;
++	PCRE2_UCHAR pcre_error_str[ERROR_BUF_SIZE];
++	PCRE2_SIZE pcre_erroffset;
++	pcre2_match_data *match_data;
+ 	str regex;
+ 
+ 	if (pkg_nt_str_dup(&regex, _regex_s) < 0)
+ 		return -1;
+ 
+-	pcre_re = pcre_compile(regex.s, pcre_options, &pcre_error, &pcre_erroffset, NULL);
++	pcre_re = pcre2_compile((PCRE2_SPTR)regex.s, PCRE2_ZERO_TERMINATED, pcre_options, &pcre_error, &pcre_erroffset, NULL);
+ 	if (pcre_re == NULL) {
+-		LM_ERR("pcre_re compilation of '%s' failed at offset %d: %s\n", regex.s, pcre_erroffset, pcre_error);
++                pcre2_get_error_message(pcre_error, pcre_error_str, sizeof(pcre_error_str));
++		LM_ERR("pcre_re compilation of '%s' failed at offset %ld: %s\n", regex.s, pcre_erroffset, pcre_error_str);
+ 		pkg_free(regex.s);
+ 		return -4;
+ 	}
+ 
+-	pcre_rc = pcre_exec(
++	match_data = pcre2_match_data_create(0, NULL); // no captures needed
++
++	pcre_rc = pcre2_match(
+ 		pcre_re,                    /* the compiled pattern */
+-		NULL,                       /* no extra data - we didn't study the pattern */
+-		string->s,                   /* the matching string */
+-		(int)(string->len),          /* the length of the subject */
++		(PCRE2_SPTR)string->s,                  /* the matching string */
++		(PCRE2_SIZE)(string->len),  /* the length of the subject */
+ 		0,                          /* start at offset 0 in the string */
+ 		0,                          /* default options */
+-		NULL,                       /* output vector for substring information */
+-		0);                         /* number of elements in the output vector */
++		match_data,                 /* match data block */
++		NULL);                      /* match context */
++
++	pcre2_match_data_free(match_data);
+ 
+ 	/* Matching failed: handle error cases */
+ 	if (pcre_rc < 0) {
+ 		switch(pcre_rc) {
+-			case PCRE_ERROR_NOMATCH:
++			case PCRE2_ERROR_NOMATCH:
+ 				LM_DBG("'%s' doesn't match '%s'\n", string->s, regex.s);
+ 				break;
+ 			default:
+ 				LM_DBG("matching error '%d'\n", pcre_rc);
+ 				break;
+ 		}
+-		pcre_free(pcre_re);
++		pcre2_code_free(pcre_re);
+ 		pkg_free(regex.s);
+ 		return -1;
+ 	}
+ 
+-	pcre_free(pcre_re);
++	pcre2_code_free(pcre_re);
+ 	pkg_free(regex.s);
+ 	LM_DBG("'%s' matches '%s'\n", string->s, regex.s);
+ 	return 1;
+@@ -608,6 +618,7 @@ static int w_pcre_match_group(struct sip_msg* _msg, str* string, int* _num_pcre)
+ {
+ 	int num_pcre;
+ 	int pcre_rc;
++	pcre2_match_data *match_data;
+ 
+ 	/* Check if group matching feature is enabled */
+ 	if (file == NULL) {
+@@ -627,22 +638,25 @@ static int w_pcre_match_group(struct sip_msg* _msg, str* string, int* _num_pcre)
+ 
+ 	lock_get(reload_lock);
+ 
+-	pcre_rc = pcre_exec(
++	match_data = pcre2_match_data_create(0, NULL); // no captures needed
++
++	pcre_rc = pcre2_match(
+ 		(*pcres_addr)[num_pcre],    /* the compiled pattern */
+-		NULL,                       /* no extra data - we didn't study the pattern */
+-		string->s,                   /* the matching string */
+-		(int)(string->len),          /* the length of the subject */
++		(PCRE2_SPTR)string->s,                  /* the matching string */
++		(PCRE2_SIZE)(string->len),  /* the length of the subject */
+ 		0,                          /* start at offset 0 in the string */
+ 		0,                          /* default options */
+-		NULL,                       /* output vector for substring information */
+-		0);                         /* number of elements in the output vector */
++		match_data,                 /* match data block */
++		0);                         /* match context */
++
++	pcre2_match_data_free(match_data);
+ 
+ 	lock_release(reload_lock);
+ 
+ 	/* Matching failed: handle error cases */
+ 	if (pcre_rc < 0) {
+ 		switch(pcre_rc) {
+-			case PCRE_ERROR_NOMATCH:
++			case PCRE2_ERROR_NOMATCH:
+ 				LM_DBG("'%s' doesn't match pcres[%i]\n", string->s, num_pcre);
+ 				break;
+ 			default:

diff --git a/opensips-0020-regex-allow-pcre3-library.patch b/opensips-0020-regex-allow-pcre3-library.patch
new file mode 100644
index 0000000..7a1a377
--- /dev/null
+++ b/opensips-0020-regex-allow-pcre3-library.patch
@@ -0,0 +1,46 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Razvan Crainea <razvan@opensips.org>
+Date: Wed, 11 Feb 2026 16:15:11 +0200
+Subject: [PATCH] regex: allow pcre3 library
+
+
+diff --git a/modules/regex/Makefile b/modules/regex/Makefile
+index b4c2dfe07..d09aa245b 100644
+--- a/modules/regex/Makefile
++++ b/modules/regex/Makefile
+@@ -8,12 +8,16 @@ NAME=regex.so
+ # the autodetection
+ # CROSS_COMPILE=true
+ 
++PCRE_LIB ?= pcre2-8
++PCRE_VERSION ?= $(word 1,$(subst -, , $(PCRE_LIB)))
++PCRE_CONFIG ?= $(PCRE_VERSION)-config
++
+ ifeq ($(CROSS_COMPILE),)
+ PCRE_BUILDER := $(shell \
+-	if which pcre2-config >/dev/null 2>/dev/null; then \
+-		echo 'pcre2-config'; \
+-	elif pkg-config --exists libpcre2-8; then \
+-		echo 'pkg-config libpcre2-8'; \
++	if which $(PCRE_CONFIG) >/dev/null 2>/dev/null; then \
++		echo '$(PCRE_CONFIG)'; \
++	elif pkg-config --exists lib$(PCRE_LIB); then \
++		echo 'pkg-config lib$(PCRE_LIB)'; \
+ 	fi)
+ endif
+ 
+@@ -21,10 +25,12 @@ ifeq ($(PCRE_BUILDER),)
+ 	DEFS += -I$(SYSBASE)/include \
+ 			-I$(LOCALBASE)/include
+ 	LIBS += -L$(SYSBASE)/lib \
+-			-L$(LOCALBASE)/lib -lpcre2-8
++			-L$(LOCALBASE)/lib -l$(PCRE_LIB)
+ else
+ 	DEFS += $(shell $(PCRE_BUILDER) --cflags)
+-	LIBS += $(shell $(PCRE_BUILDER) --libs8)
++	LIBS += $(shell $(PCRE_BUILDER) --libs 2>/dev/null) \
++			$(shell $(PCRE_BUILDER) --libs$(word 2,$(subst -, ,$(PCRE_LIB))) 2>/dev/null)
+ endif
++DEFS += -D$(shell echo $(PCRE_VERSION) | tr 'a-z' 'A-Z')_LIB
+ 
+ include ../../Makefile.modules

diff --git a/opensips-0021-regex-make-module-work-with-both-pcre2-and-pcre3-not.patch b/opensips-0021-regex-make-module-work-with-both-pcre2-and-pcre3-not.patch
new file mode 100644
index 0000000..afc6d60
--- /dev/null
+++ b/opensips-0021-regex-make-module-work-with-both-pcre2-and-pcre3-not.patch
@@ -0,0 +1,149 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Razvan Crainea <razvan@opensips.org>
+Date: Thu, 19 Feb 2026 11:34:02 +0200
+Subject: [PATCH] regex: make module work with both pcre2 and pcre3, not just
+ compile
+
+(cherry picked from commit bbc1a75d5ba25c0f26afcd208b0f5c7e1fffd3b7)
+
+diff --git a/modules/regex/regex_mod.c b/modules/regex/regex_mod.c
+index 9311d2b93..6734fb8bf 100644
+--- a/modules/regex/regex_mod.c
++++ b/modules/regex/regex_mod.c
+@@ -40,8 +40,36 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <sys/stat.h>
++#ifdef PCRE2_LIB
+ #define PCRE2_CODE_UNIT_WIDTH 8
++#define PCRE2_ERR int
+ #include <pcre2.h>
++#else
++#define pcre2_code pcre
++#define PCRE2_SIZE int
++#define PCRE2_ERR const char *
++#define PCRE2_CASELESS PCRE_CASELESS
++#define PCRE2_MULTILINE PCRE_MULTILINE
++#define PCRE2_DOTALL PCRE_DOTALL
++#define PCRE2_EXTENDED PCRE_EXTENDED
++#define PCRE2_ERROR_NOMATCH PCRE_ERROR_NOMATCH
++#define PCRE2_UCHAR unsigned char
++#define PCRE2_SPTR char *
++#define pcre2_pattern_info(subst_comp, flag, ret) \
++	pcre_fullinfo(subst_comp, NULL, PCRE_INFO_CAPTURECOUNT, ret);
++#define pcre2_compile(pattern, _, flags, error, erroffset, ctx) \
++	pcre_compile(pattern, flags, error, erroffset, NULL)
++#define pcre2_code_free pcre_free
++#define pcre2_get_error_message(error, error_str, error_str_len) \
++	do { \
++		int _len = strlen(error); \
++		if (_len > error_str_len - 1) \
++			_len = error_str_len - 1; \
++		memcpy(error_str, error, _len); \
++		error_str[_len] = '\0'; \
++	} while (0)
++#include <pcre.h>
++#endif
+ #include "../../sr_module.h"
+ #include "../../dprint.h"
+ #include "../../pt.h"
+@@ -284,7 +312,7 @@ static int load_pcres(int action)
+ 	pcre2_code *pcre_tmp = NULL;
+ 	size_t pcre_size;
+ 	int pcre_rc;
+-	int pcre_error;
++	PCRE2_ERR pcre_error;
+ 	PCRE2_UCHAR pcre_error_str[ERROR_BUF_SIZE];
+ 	PCRE2_SIZE pcre_erroffset;
+ 	int num_pcres_tmp = 0;
+@@ -437,7 +465,7 @@ static int load_pcres(int action)
+ 		pcre_tmp = pcre2_compile((PCRE2_SPTR)patterns[i], PCRE2_ZERO_TERMINATED, pcre_options, &pcre_error, &pcre_erroffset, NULL);
+ 		if (pcre_tmp == NULL) {
+                 	pcre2_get_error_message(pcre_error, pcre_error_str, sizeof(pcre_error_str));
+-			LM_ERR("pcre_tmp compilation of '%s' failed at offset %ld: %s\n", patterns[i], pcre_erroffset, pcre_error_str);
++			LM_ERR("pcre_tmp compilation of '%s' failed at offset %zu: %s\n", patterns[i], (long)pcre_erroffset, pcre_error_str);
+ 			goto err;
+ 		}
+ 		pcre_rc = pcre2_pattern_info(pcre_tmp, PCRE2_INFO_SIZE, &pcre_size);
+@@ -561,10 +589,12 @@ static int w_pcre_match(struct sip_msg* _msg, str* string, str* _regex_s)
+ {
+ 	pcre2_code *pcre_re = NULL;
+ 	int pcre_rc;
+-	int pcre_error;
++	PCRE2_ERR pcre_error;
+ 	PCRE2_UCHAR pcre_error_str[ERROR_BUF_SIZE];
+ 	PCRE2_SIZE pcre_erroffset;
++#ifdef PCRE2_LIB
+ 	pcre2_match_data *match_data;
++#endif
+ 	str regex;
+ 
+ 	if (pkg_nt_str_dup(&regex, _regex_s) < 0)
+@@ -573,11 +603,22 @@ static int w_pcre_match(struct sip_msg* _msg, str* string, str* _regex_s)
+ 	pcre_re = pcre2_compile((PCRE2_SPTR)regex.s, PCRE2_ZERO_TERMINATED, pcre_options, &pcre_error, &pcre_erroffset, NULL);
+ 	if (pcre_re == NULL) {
+                 pcre2_get_error_message(pcre_error, pcre_error_str, sizeof(pcre_error_str));
+-		LM_ERR("pcre_re compilation of '%s' failed at offset %ld: %s\n", regex.s, pcre_erroffset, pcre_error_str);
++		LM_ERR("pcre_re compilation of '%s' failed at offset %zu: %s\n", regex.s, (long)pcre_erroffset, pcre_error_str);
+ 		pkg_free(regex.s);
+ 		return -4;
+ 	}
+ 
++#ifndef PCRE2_LIB
++	pcre_rc = pcre_exec(
++			pcre_re, /* the compiled pattern */
++			NULL, /* no extra data - we didn't study the pattern */
++			string->s, /* the subject string */
++			string->len, /* the length of the subject */
++			0, /* start at offset 0 in the subject */
++			0, /* default options */
++			NULL, /* output vector for substring information */
++			0); /* number of elements in the output vector */
++#else
+ 	match_data = pcre2_match_data_create(0, NULL); // no captures needed
+ 
+ 	pcre_rc = pcre2_match(
+@@ -590,6 +631,7 @@ static int w_pcre_match(struct sip_msg* _msg, str* string, str* _regex_s)
+ 		NULL);                      /* match context */
+ 
+ 	pcre2_match_data_free(match_data);
++#endif
+ 
+ 	/* Matching failed: handle error cases */
+ 	if (pcre_rc < 0) {
+@@ -618,7 +660,9 @@ static int w_pcre_match_group(struct sip_msg* _msg, str* string, int* _num_pcre)
+ {
+ 	int num_pcre;
+ 	int pcre_rc;
++#ifdef PCRE2_LIB
+ 	pcre2_match_data *match_data;
++#endif
+ 
+ 	/* Check if group matching feature is enabled */
+ 	if (file == NULL) {
+@@ -638,6 +682,17 @@ static int w_pcre_match_group(struct sip_msg* _msg, str* string, int* _num_pcre)
+ 
+ 	lock_get(reload_lock);
+ 
++#ifndef PCRE2_LIB
++	pcre_rc = pcre_exec(
++			(*pcres_addr)[num_pcre], /* the compiled pattern */
++			NULL, /* no extra data - we didn't study the pattern */
++			string->s, /* the subject string */
++			string->len, /* the length of the subject */
++			0, /* start at offset 0 in the subject */
++			0, /* default options */
++			NULL, /* output vector for substring information */
++			0); /* number of elements in the output vector */
++#else
+ 	match_data = pcre2_match_data_create(0, NULL); // no captures needed
+ 
+ 	pcre_rc = pcre2_match(
+@@ -650,6 +705,7 @@ static int w_pcre_match_group(struct sip_msg* _msg, str* string, int* _num_pcre)
+ 		0);                         /* match context */
+ 
+ 	pcre2_match_data_free(match_data);
++#endif
+ 
+ 	lock_release(reload_lock);
+ 

diff --git a/opensips-0022-regex-fix-broken-merge.patch b/opensips-0022-regex-fix-broken-merge.patch
new file mode 100644
index 0000000..c8a3efd
--- /dev/null
+++ b/opensips-0022-regex-fix-broken-merge.patch
@@ -0,0 +1,29 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Razvan Crainea <razvan@opensips.org>
+Date: Thu, 19 Feb 2026 12:37:26 +0200
+Subject: [PATCH] regex: fix broken merge
+
+(cherry picked from commit b0c1bcafa284977e53fc6b2ac6c659365f88404c)
+
+diff --git a/modules/regex/regex_mod.c b/modules/regex/regex_mod.c
+index 6734fb8bf..1ac492b25 100644
+--- a/modules/regex/regex_mod.c
++++ b/modules/regex/regex_mod.c
+@@ -465,7 +465,7 @@ static int load_pcres(int action)
+ 		pcre_tmp = pcre2_compile((PCRE2_SPTR)patterns[i], PCRE2_ZERO_TERMINATED, pcre_options, &pcre_error, &pcre_erroffset, NULL);
+ 		if (pcre_tmp == NULL) {
+                 	pcre2_get_error_message(pcre_error, pcre_error_str, sizeof(pcre_error_str));
+-			LM_ERR("pcre_tmp compilation of '%s' failed at offset %zu: %s\n", patterns[i], (long)pcre_erroffset, pcre_error_str);
++			LM_ERR("pcre_tmp compilation of '%s' failed at offset %lu: %s\n", patterns[i], (unsigned long)pcre_erroffset, pcre_error_str);
+ 			goto err;
+ 		}
+ 		pcre_rc = pcre2_pattern_info(pcre_tmp, PCRE2_INFO_SIZE, &pcre_size);
+@@ -603,7 +603,7 @@ static int w_pcre_match(struct sip_msg* _msg, str* string, str* _regex_s)
+ 	pcre_re = pcre2_compile((PCRE2_SPTR)regex.s, PCRE2_ZERO_TERMINATED, pcre_options, &pcre_error, &pcre_erroffset, NULL);
+ 	if (pcre_re == NULL) {
+                 pcre2_get_error_message(pcre_error, pcre_error_str, sizeof(pcre_error_str));
+-		LM_ERR("pcre_re compilation of '%s' failed at offset %zu: %s\n", regex.s, (long)pcre_erroffset, pcre_error_str);
++		LM_ERR("pcre_re compilation of '%s' failed at offset %lu: %s\n", regex.s, (unsigned long)pcre_erroffset, pcre_error_str);
+ 		pkg_free(regex.s);
+ 		return -4;
+ 	}

diff --git a/opensips.spec b/opensips.spec
index fec7e0f..74e105b 100644
--- a/opensips.spec
+++ b/opensips.spec
@@ -22,6 +22,16 @@ Patch: opensips-0009-Fix-format-specifier-warnings-on-32-bit-architecture.patch
 Patch: opensips-0010-Fix-pointer-truncation-warning-on-32-bit-architectur.patch
 Patch: opensips-0011-Fix-C90-style-declaration-warnings-in-snmpstats-modu.patch
 Patch: opensips-0012-support-for-libmongc-libbson-version-2.patch
+Patch: opensips-0013-require-libpcre2.patch
+Patch: opensips-0014-update-dialplan-module-for-pcre2.patch
+Patch: opensips-0015-create-pcre2-compile-context-once-instead-of-for-eac.patch
+Patch: opensips-0016-Makefile-tweaks-to-avoid-shell-.-expansions-from-fai.patch
+Patch: opensips-0017-dialplan-fix-copying-subst-s-out-vector.patch
+Patch: opensips-0018-dialplan-make-module-work-with-both-pcre2-and-pcre3-.patch
+Patch: opensips-0019-update-regex-module-for-pcre2.patch
+Patch: opensips-0020-regex-allow-pcre3-library.patch
+Patch: opensips-0021-regex-make-module-work-with-both-pcre2-and-pcre3-not.patch
+Patch: opensips-0022-regex-fix-broken-merge.patch
 
 URL:      https://opensips.org
 
@@ -33,7 +43,6 @@ BuildRequires: libxslt
 BuildRequires: lynx
 BuildRequires: make
 BuildRequires: ncurses-devel
-BuildRequires: pcre-devel
 BuildRequires: systemd-units
 
 # Users and groups
@@ -307,6 +316,16 @@ BuildRequires: unixODBC-devel
 This module contains the unixODBC plugin for %{name}, which
 allows unixODBC to be used for persistent storage.
 
+%package  dialplan
+Summary:  Dialplans implementation
+Requires: %{name}%{?_isa} = %{version}-%{release}
+BuildRequires: pcre2-devel
+
+%description dialplan
+This module implements generic string translations based on matching and
+replacement rules. It can be used to manipulate R-URI or a PV and to translated
+to a new format/value.
+
 %package  event_kafka
 Summary:  Event Kafka module
 Requires: %{name}%{?_isa} = %{version}-%{release}
@@ -779,6 +798,7 @@ the flexible AMQP protocol.
 %package  regex
 Summary:  RegExp via PCRE library
 Requires: %{name}%{?_isa} = %{version}-%{release}
+BuildRequires: pcre2-devel
 
 %description regex
 This module offers matching operations against regular
@@ -1022,7 +1042,6 @@ install -D -p -m 644 packaging/redhat_fedora/%{name}.sysconfig %{buildroot}%{_sy
 %{_libdir}/opensips/modules/db_text.so
 %{_libdir}/opensips/modules/db_virtual.so
 %{_libdir}/opensips/modules/dialog.so
-%{_libdir}/opensips/modules/dialplan.so
 %{_libdir}/opensips/modules/dispatcher.so
 %{_libdir}/opensips/modules/diversion.so
 %{_libdir}/opensips/modules/dns_cache.so
@@ -1120,7 +1139,6 @@ install -D -p -m 644 packaging/redhat_fedora/%{name}.sysconfig %{buildroot}%{_sy
 %doc docdir/README.db_text
 %doc docdir/README.db_virtual
 %doc docdir/README.dialog
-%doc docdir/README.dialplan
 %doc docdir/README.dispatcher
 %doc docdir/README.diversion
 %doc docdir/README.dns_cache
@@ -1333,6 +1351,10 @@ install -D -p -m 644 packaging/redhat_fedora/%{name}.sysconfig %{buildroot}%{_sy
 %{_libdir}/opensips/modules/db_unixodbc.so
 %doc docdir/README.db_unixodbc
 
+%files dialplan
+%doc docdir/README.dialplan
+%{_libdir}/opensips/modules/dialplan.so
+
 %files event_kafka
 %{_libdir}/opensips/modules/event_kafka.so
 %doc docdir/README.event_kafka

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-06-24 17:40 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-06-24 17:40 [rpms/opensips] f43: Switch to PCRE2 Peter Lemenkov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox