diff --git a/daemon/.ycm_extra_conf.py b/daemon/.ycm_extra_conf.py index 2607fa60e..c2fe8c69e 100644 --- a/daemon/.ycm_extra_conf.py +++ b/daemon/.ycm_extra_conf.py @@ -39,6 +39,7 @@ flags = [ '-D_GNU_SOURCE', '-D__DEBUG=1', '-D__YCM=1', + '-DPCRE2_CODE_UNIT_WIDTH=8', '-DRTPENGINE_VERSION="dummy"', '-DRE_PLUGIN_DIR="/usr/lib/rtpengine"', '-DWITH_IPTABLES_OPTION', diff --git a/daemon/Makefile b/daemon/Makefile index 0840905a0..bb57894fd 100644 --- a/daemon/Makefile +++ b/daemon/Makefile @@ -13,7 +13,8 @@ CFLAGS+= $(shell pkg-config --cflags gthread-2.0) CFLAGS+= $(shell pkg-config --cflags zlib) CFLAGS+= $(shell pkg-config --cflags openssl) CFLAGS+= $(shell pkg-config --cflags libevent_pthreads) -CFLAGS+= $(shell pkg-config --cflags libpcre) +CFLAGS+= -DPCRE2_CODE_UNIT_WIDTH=8 +CFLAGS+= $(shell pkg-config --cflags libpcre2-8) CFLAGS+= $(shell pkg-config xmlrpc_client --cflags 2> /dev/null || xmlrpc-c-config client --cflags) CFLAGS+= $(shell pkg-config xmlrpc --cflags 2> /dev/null) CFLAGS+= $(shell pkg-config xmlrpc_util --cflags 2> /dev/null) @@ -47,7 +48,7 @@ LDLIBS= -lm -ldl LDLIBS+= $(shell pkg-config --libs glib-2.0) LDLIBS+= $(shell pkg-config --libs gthread-2.0) LDLIBS+= $(shell pkg-config --libs zlib) -LDLIBS+= $(shell pkg-config --libs libpcre) +LDLIBS+= $(shell pkg-config --libs libpcre2-8) LDLIBS+= $(shell pkg-config --libs libcrypto) LDLIBS+= $(shell pkg-config --libs openssl) LDLIBS+= $(shell pkg-config --libs libevent_pthreads) diff --git a/daemon/call.c b/daemon/call.c index b19eec885..ef47d680c 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -4,7 +4,6 @@ #include #include #include -#include #include #include #include diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index c6acffaca..02f6db1af 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include "call_interfaces.h" @@ -33,10 +33,8 @@ #include "dtmf.h" -static pcre *info_re; -static pcre_extra *info_ree; -static pcre *streams_re; -static pcre_extra *streams_ree; +static pcre2_code *info_re; +static pcre2_code *streams_re; bool trust_address_def; bool dtls_passive_def; @@ -259,7 +257,7 @@ static bool info_parse_func(char **a, void **ret, void *p) { } static void info_parse(const char *s, GHashTable *ih) { - pcre_multi_match(info_re, info_ree, s, 2, info_parse_func, ih, NULL); + pcre2_multi_match(info_re, s, 3, info_parse_func, ih, NULL); } @@ -302,7 +300,7 @@ fail: static void streams_parse(const char *s, GQueue *q) { int i; i = 0; - pcre_multi_match(streams_re, streams_ree, s, 3, streams_parse_func, &i, q); + pcre2_multi_match(streams_re, s, 4, streams_parse_func, &i, q); } void call_unlock_release(struct call **c) { if (!*c) @@ -3561,39 +3559,29 @@ const char *call_unsubscribe_ng(bencode_item_t *input, bencode_item_t *output) { void call_interfaces_free() { if (info_re) { - pcre_free(info_re); + pcre2_code_free(info_re); info_re = NULL; } if (streams_re) { - pcre_free(streams_re); + pcre2_code_free(streams_re); streams_re= NULL; } - - if (info_ree) { - pcre_free_study(info_ree); - info_ree = NULL; - } - - if (streams_ree) { - pcre_free_study(streams_ree); - streams_ree = NULL; - } } int call_interfaces_init() { - const char *errptr; - int erroff; + int errcode; + PCRE2_SIZE erroff; - info_re = pcre_compile("^([^:,]+)(?::(.*?))?(?:$|,)", PCRE_DOLLAR_ENDONLY | PCRE_DOTALL, &errptr, &erroff, NULL); + info_re = pcre2_compile((PCRE2_SPTR8) "^([^:,]+)(?::(.*?))?(?:$|,)", PCRE2_ZERO_TERMINATED, + PCRE2_DOLLAR_ENDONLY | PCRE2_DOTALL, &errcode, &erroff, NULL); if (!info_re) return -1; - info_ree = pcre_study(info_re, 0, &errptr); - streams_re = pcre_compile("^([\\d.]+):(\\d+)(?::(.*?))?(?:$|,)", PCRE_DOLLAR_ENDONLY | PCRE_DOTALL, &errptr, &erroff, NULL); + streams_re = pcre2_compile((PCRE2_SPTR8) "^([\\d.]+):(\\d+)(?::(.*?))?(?:$|,)", PCRE2_ZERO_TERMINATED, + PCRE2_DOLLAR_ENDONLY | PCRE2_DOTALL, &errcode, &erroff, NULL); if (!streams_re) return -1; - streams_ree = pcre_study(streams_re, 0, &errptr); return 0; } diff --git a/daemon/control_tcp.c b/daemon/control_tcp.c index d4b680838..370154396 100644 --- a/daemon/control_tcp.c +++ b/daemon/control_tcp.c @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include #include @@ -28,8 +28,7 @@ struct control_tcp { struct streambuf_listener listener; - pcre *parse_re; - pcre_extra *parse_ree; + pcre2_code *parse_re; }; @@ -62,13 +61,14 @@ static void control_list(struct control_tcp *c, struct streambuf_stream *s) { static int control_stream_parse(struct streambuf_stream *s, char *line) { - int ovec[60]; int ret; char **out; struct control_tcp *c = (void *) s->parent; str *output = NULL; - ret = pcre_exec(c->parse_re, c->parse_ree, line, strlen(line), 0, 0, ovec, G_N_ELEMENTS(ovec)); + pcre2_match_data *md = pcre2_match_data_create(20, NULL); + ret = pcre2_match(c->parse_re, (PCRE2_SPTR8) line, PCRE2_ZERO_TERMINATED, + 0, 0, md, NULL); if (ret <= 0) { ilogs(control, LOG_WARNING, "Unable to parse command line from %s: %s", s->addr, line); return -1; @@ -76,7 +76,7 @@ static int control_stream_parse(struct streambuf_stream *s, char *line) { ilogs(control, LOG_INFO, "Got valid command from %s: %s", s->addr, line); - pcre_get_substring_list(line, ovec, ret, (const char ***) &out); + pcre2_substring_list_get(md, (PCRE2_UCHAR ***) &out, NULL); if (out[RE_TCP_RL_CALLID]) @@ -105,7 +105,8 @@ static int control_stream_parse(struct streambuf_stream *s, char *line) { free(output); } - pcre_free(out); + pcre2_substring_list_free((PCRE2_SPTR *) out); + pcre2_match_data_free(md); log_info_pop(); return 1; } @@ -147,14 +148,11 @@ static void control_incoming(struct streambuf_stream *s) { static void control_tcp_free(void *p) { struct control_tcp *c = p; streambuf_listener_shutdown(&c->listener); - pcre_free(c->parse_re); - pcre_free_study(c->parse_ree); + pcre2_code_free(c->parse_re); } struct control_tcp *control_tcp_new(const endpoint_t *ep) { struct control_tcp *c; - const char *errptr; - int erroff; c = obj_alloc0("control", sizeof(*c), control_tcp_free); @@ -167,11 +165,14 @@ struct control_tcp *control_tcp_new(const endpoint_t *ep) { goto fail; } - c->parse_re = pcre_compile( + int errcode; + PCRE2_SIZE erroff; + + c->parse_re = pcre2_compile( /* reqtype callid streams ip fromdom fromtype todom totype agent info |reqtype callid info | reqtype */ - "^(?:(request|lookup)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+info=(\\S*)|(delete)\\s+(\\S+)\\s+info=(\\S*)|(build|version|controls|quit|exit|status))$", - PCRE_DOLLAR_ENDONLY | PCRE_DOTALL, &errptr, &erroff, NULL); - c->parse_ree = pcre_study(c->parse_re, 0, &errptr); + (PCRE2_SPTR8) "^(?:(request|lookup)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+info=(\\S*)|(delete)\\s+(\\S+)\\s+info=(\\S*)|(build|version|controls|quit|exit|status))$", + PCRE2_ZERO_TERMINATED, + PCRE2_DOLLAR_ENDONLY | PCRE2_DOTALL, &errcode, &erroff, NULL); obj_put(c); return c; diff --git a/daemon/control_udp.c b/daemon/control_udp.c index 63a2995bd..3bd2f85b6 100644 --- a/daemon/control_udp.c +++ b/daemon/control_udp.c @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include #include @@ -24,15 +24,15 @@ static void control_udp_incoming(struct obj *obj, struct udp_buffer *udp_buf) { struct control_udp *u = (void *) obj; int ret; - int ovec[100]; char **out; struct iovec iov[10]; unsigned int iovlen; str cookie, *reply; - ret = pcre_exec(u->parse_re, u->parse_ree, udp_buf->str.s, udp_buf->str.len, 0, 0, ovec, G_N_ELEMENTS(ovec)); + pcre2_match_data *md = pcre2_match_data_create(30, NULL); + ret = pcre2_match(u->parse_re, (PCRE2_SPTR8) udp_buf->str.s, udp_buf->str.len, 0, 0, md, NULL); if (ret <= 0) { - ret = pcre_exec(u->fallback_re, NULL, udp_buf->str.s, udp_buf->str.len, 0, 0, ovec, G_N_ELEMENTS(ovec)); + ret = pcre2_match(u->fallback_re, (PCRE2_SPTR8) udp_buf->str.s, udp_buf->str.len, 0, 0, md, NULL); if (ret <= 0) { ilogs(control, LOG_WARNING, "Unable to parse command line from udp:%s: %.*s", udp_buf->addr, STR_FMT(&udp_buf->str)); return; @@ -40,7 +40,7 @@ static void control_udp_incoming(struct obj *obj, struct udp_buffer *udp_buf) { ilogs(control, LOG_WARNING, "Failed to properly parse UDP command line '%.*s' from %s, using fallback RE", STR_FMT(&udp_buf->str), udp_buf->addr); - pcre_get_substring_list(udp_buf->str.s, ovec, ret, (const char ***) &out); + pcre2_substring_list_get(md, (PCRE2_UCHAR ***) &out, NULL); iov[0].iov_base = (void *) out[RE_UDP_COOKIE]; iov[0].iov_len = strlen(out[RE_UDP_COOKIE]); @@ -61,14 +61,15 @@ static void control_udp_incoming(struct obj *obj, struct udp_buffer *udp_buf) { socket_sendiov(udp_buf->listener, iov, iovlen, &udp_buf->sin); - pcre_free(out); + pcre2_substring_list_free((PCRE2_SPTR *) out); + pcre2_match_data_free(md); return; } ilogs(control, LOG_INFO, "Got valid command from udp:%s: %.*s", udp_buf->addr, STR_FMT(&udp_buf->str)); - pcre_get_substring_list(udp_buf->str.s, ovec, ret, (const char ***) &out); + pcre2_substring_list_get(md, (PCRE2_UCHAR ***) &out, NULL); str_init(&cookie, (void *) out[RE_UDP_COOKIE]); reply = cookie_cache_lookup(&u->cookie_cache, &cookie); @@ -129,29 +130,29 @@ static void control_udp_incoming(struct obj *obj, struct udp_buffer *udp_buf) { cookie_cache_remove(&u->cookie_cache, &cookie); out: - pcre_free(out); + pcre2_substring_list_free((PCRE2_SPTR *) out); + pcre2_match_data_free(md); log_info_pop(); } void control_udp_free(void *p) { struct control_udp *u = p; - pcre_free_study(u->parse_ree); - pcre_free(u->parse_re); - pcre_free(u->fallback_re); + pcre2_code_free(u->parse_re); + pcre2_code_free(u->fallback_re); close_socket(&u->udp_listener); cookie_cache_cleanup(&u->cookie_cache); } struct control_udp *control_udp_new(const endpoint_t *ep) { struct control_udp *c; - const char *errptr; - int erroff; + PCRE2_SIZE erroff; + int errcode; c = obj_alloc0("control_udp", sizeof(*c), control_udp_free); - c->parse_re = pcre_compile( + c->parse_re = pcre2_compile( /* cookie cmd flags callid viabranch:5 */ - "^(\\S+)\\s+(?:([ul])(\\S*)\\s+([^;]+)(?:;(\\S+))?\\s+" \ + (PCRE2_SPTR8) "^(\\S+)\\s+(?:([ul])(\\S*)\\s+([^;]+)(?:;(\\S+))?\\s+" \ /* addr4 addr6:7 */ "(?:([\\d.]+)|([\\da-f:]+(?::ffff:[\\d.]+)?))" \ /* port fromtag num totag:11 */ @@ -160,10 +161,12 @@ struct control_udp *control_udp_new(const endpoint_t *ep) { "|([dq])(\\S*)\\s+([^;\\s]+)(?:;(\\S+))?\\s+(\\S+?)(?:;\\d+)?(?:\\s+(\\S+?)(?:;\\d+)?)?\r?\n?$" \ /* v flags params:20 */ "|(v)(\\S*)(?:\\s+(\\S+))?)", - PCRE_DOLLAR_ENDONLY | PCRE_DOTALL | PCRE_CASELESS, &errptr, &erroff, NULL); - c->parse_ree = pcre_study(c->parse_re, 0, &errptr); + PCRE2_ZERO_TERMINATED, + PCRE2_DOLLAR_ENDONLY | PCRE2_DOTALL | PCRE2_CASELESS, &errcode, &erroff, NULL); /* cookie cmd flags callid addr port */ - c->fallback_re = pcre_compile("^(\\S+)(?:\\s+(\\S)\\S*\\s+\\S+(\\s+\\S+)(\\s+\\S+))?", PCRE_DOLLAR_ENDONLY | PCRE_DOTALL | PCRE_CASELESS, &errptr, &erroff, NULL); + c->fallback_re = pcre2_compile((PCRE2_SPTR8) "^(\\S+)(?:\\s+(\\S)\\S*\\s+\\S+(\\s+\\S+)(\\s+\\S+))?", + PCRE2_ZERO_TERMINATED, + PCRE2_DOLLAR_ENDONLY | PCRE2_DOTALL | PCRE2_CASELESS, &errcode, &erroff, NULL); if (!c->parse_re || !c->fallback_re) goto fail2; diff --git a/daemon/helpers.c b/daemon/helpers.c index 5be4b1d7f..3bc030900 100644 --- a/daemon/helpers.c +++ b/daemon/helpers.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #include #include @@ -86,22 +86,27 @@ GList *g_list_link(GList *list, GList *el) { } -int pcre_multi_match(pcre *re, pcre_extra *ree, const char *s, unsigned int num, parse_func f, +int pcre2_multi_match(pcre2_code *re, const char *s, unsigned int num, parse_func f, void *p, GQueue *q) { - unsigned int start, len; - int ovec[60]; - int *ov; + size_t start, len, next; char **el; unsigned int i; void *ins; el = malloc(sizeof(*el) * num); - - for (start = 0, len = strlen(s); pcre_exec(re, ree, s + start, len - start, 0, 0, ovec, G_N_ELEMENTS(ovec)) > 0; start += ovec[1]) { + pcre2_match_data *md = pcre2_match_data_create(num, NULL); + + for (start = 0, len = strlen(s); + pcre2_match(re, (PCRE2_SPTR8) s + start, len - start, 0, 0, md, NULL) >= 0; + start += next) + { + PCRE2_SIZE *ovec = pcre2_get_ovector_pointer(md); + uint32_t count = pcre2_get_ovector_count(md); + next = ovec[1]; for (i = 0; i < num; i++) { - ov = ovec + 2 + i*2; - el[i] = (ov[0] == -1) ? NULL : g_strndup(s + start + ov[0], ov[1] - ov[0]); + size_t *ov = ovec + 2 + i*2; + el[i] = (i + 1 >= count) ? NULL : g_strndup(s + start + ov[0], ov[1] - ov[0]); } if (f(el, &ins, p)) @@ -112,6 +117,7 @@ int pcre_multi_match(pcre *re, pcre_extra *ree, const char *s, unsigned int num, } free(el); + pcre2_match_data_free(md); return q ? q->length : 0; } diff --git a/debian/control b/debian/control index b2bdace8f..8f4f92fc9 100644 --- a/debian/control +++ b/debian/control @@ -34,7 +34,7 @@ Build-Depends: libnet-interface-perl, libopus-dev, libpcap0.8-dev, - libpcre3-dev, + libpcre2-dev, libsocket6-perl, libspandsp-dev, libssl-dev (>= 1.0.1), diff --git a/include/.ycm_extra_conf.py b/include/.ycm_extra_conf.py index 7b695a7e4..e97afb8d6 100644 --- a/include/.ycm_extra_conf.py +++ b/include/.ycm_extra_conf.py @@ -28,6 +28,7 @@ flags = [ '-D_GNU_SOURCE', '-D__DEBUG=1', '-D__YCM=1', + '-DPCRE2_CODE_UNIT_WIDTH=8', '-DRTPENGINE_VERSION="dummy"', '-DRE_PLUGIN_DIR="/usr/lib/rtpengine"', '-DWITH_IPTABLES_OPTION', diff --git a/include/call.h b/include/call.h index 4d55a977a..5a7c5b8fc 100644 --- a/include/call.h +++ b/include/call.h @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include diff --git a/include/control_udp.h b/include/control_udp.h index 6e4276a55..f17421d59 100644 --- a/include/control_udp.h +++ b/include/control_udp.h @@ -5,7 +5,7 @@ -#include +#include #include #include #include @@ -46,9 +46,8 @@ struct control_udp { struct cookie_cache cookie_cache; socket_t udp_listener; - pcre *parse_re; - pcre_extra *parse_ree; - pcre *fallback_re; + pcre2_code *parse_re; + pcre2_code *fallback_re; }; diff --git a/include/helpers.h b/include/helpers.h index d4c2c26cb..91eebb6d0 100644 --- a/include/helpers.h +++ b/include/helpers.h @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include #include @@ -32,7 +32,7 @@ typedef bool (*parse_func)(char **, void **, void *); -int pcre_multi_match(pcre *, pcre_extra *, const char *, unsigned int, parse_func, void *, GQueue *); +int pcre2_multi_match(pcre2_code *, const char *, unsigned int, parse_func, void *, GQueue *); INLINE void strmove(char **, char **); INLINE void strdupfree(char **, const char *); diff --git a/t/.ycm_extra_conf.py b/t/.ycm_extra_conf.py index 93817917d..7b965e7ad 100644 --- a/t/.ycm_extra_conf.py +++ b/t/.ycm_extra_conf.py @@ -28,6 +28,7 @@ flags = [ '-D_GNU_SOURCE', '-D__DEBUG=1', '-D__YCM=1', + '-DPCRE2_CODE_UNIT_WIDTH=8', '-DRTPENGINE_VERSION="dummy"', '-DRE_PLUGIN_DIR="/usr/lib/rtpengine"', '-DWITH_IPTABLES_OPTION', diff --git a/t/Makefile b/t/Makefile index e03ba4eab..545b8fa16 100644 --- a/t/Makefile +++ b/t/Makefile @@ -12,7 +12,8 @@ CFLAGS+= $(shell pkg-config --cflags gthread-2.0) CFLAGS+= $(shell pkg-config --cflags openssl) CFLAGS+= -I. -I../lib/ -I../kernel-module/ -I../include/ CFLAGS+= -D_GNU_SOURCE -CFLAGS+= $(shell pkg-config --cflags libpcre) +CFLAGS+= -DPCRE2_CODE_UNIT_WIDTH=8 +CFLAGS+= $(shell pkg-config --cflags libpcre2-8) CFLAGS+= $(shell pkg-config --cflags json-glib-1.0) ifeq ($(with_transcoding),yes) CFLAGS+= $(shell pkg-config --cflags libavcodec) @@ -42,7 +43,7 @@ LDLIBS+= $(shell pkg-config --libs glib-2.0) LDLIBS+= $(shell pkg-config --libs gthread-2.0) LDLIBS+= $(shell pkg-config --libs libcrypto) LDLIBS+= $(shell pkg-config --libs openssl) -LDLIBS+= $(shell pkg-config --libs libpcre) +LDLIBS+= $(shell pkg-config --libs libpcre2-8) LDLIBS+= $(shell pkg-config --libs json-glib-1.0) ifeq ($(with_transcoding),yes) LDLIBS+= $(shell pkg-config --libs libavcodec)