Browse code

dialplan: migrate to PCRE2 WIP!!!!

related #2946

Victor Seva authored on 03/12/2021 01:08:29
Showing 4 changed files
... ...
@@ -6,20 +6,15 @@ auto_gen=
6 6
 NAME=dialplan.so
7 7
 
8 8
 ifeq ($(CROSS_COMPILE),)
9
-PCRE_BUILDER = $(shell \
10
-	if pkg-config --exists libcre; then \
11
-		echo 'pkg-config libpcre'; \
12
-	else \
13
-		which pcre-config; \
14
-	fi)
9
+PCRE_BUILDER = $(shell command -v pcre2-config)
15 10
 endif
16 11
 
17 12
 ifeq ($(PCRE_BUILDER),)
18 13
 	PCREDEFS=-I$(LOCALBASE)/include
19
-	PCRELIBS=-L$(LOCALBASE)/lib -lpcre
14
+	PCRELIBS=-L$(LOCALBASE)/lib -lpcre2-8
20 15
 else
21 16
 	PCREDEFS = $(shell $(PCRE_BUILDER) --cflags)
22
-	PCRELIBS = $(shell $(PCRE_BUILDER) --libs)
17
+	PCRELIBS = $(shell $(PCRE_BUILDER) --libs8)
23 18
 endif
24 19
 DEFS+=$(PCREDEFS)
25 20
 LIBS=$(PCRELIBS)
... ...
@@ -30,7 +30,8 @@
30 30
 #ifndef _DP_DIALPLAN_H
31 31
 #define _DP_DIALPLAN_H
32 32
 
33
-#include <pcre.h>
33
+#define PCRE2_CODE_UNIT_WIDTH 8
34
+#include <pcre2.h>
34 35
 #include "../../core/pvar.h"
35 36
 #include "../../core/parser/msg_parser.h"
36 37
 
... ...
@@ -51,8 +52,8 @@ typedef struct dpl_node {
51 52
 	str match_exp;    /* match-first string */
52 53
 	str subst_exp;    /* match string with subtitution groupping */
53 54
 	str repl_exp;     /* replacement expression string */
54
-	pcre *match_comp; /* compiled matching expression */
55
-	pcre *subst_comp; /* compiled substitution expression */
55
+	pcre2_code *match_comp; /* compiled matching expression */
56
+	pcre2_code *subst_comp; /* compiled substitution expression */
56 57
 	struct subst_expr *repl_comp; /* compiled replacement */
57 58
 	str attrs;        /* attributes string */
58 59
 	unsigned int tflags; /* flags for type of values for matching */
... ...
@@ -99,7 +100,7 @@ void repl_expr_free(struct subst_expr *se);
99 100
 int dp_translate_helper(sip_msg_t *msg, str *user_name, str *repl_user,
100 101
 		dpl_id_p idp, str *);
101 102
 int rule_translate(sip_msg_t *msg, str *instr, dpl_node_t *rule,
102
-		pcre *subst_comp, str *);
103
+		pcre2_code *subst_comp, str *);
103 104
 
104
-pcre *reg_ex_comp(const char *pattern, int *cap_cnt, int mtype);
105
+pcre2_code *reg_ex_comp(const char *pattern, int *cap_cnt, int mtype);
105 106
 #endif
... ...
@@ -369,43 +369,44 @@ int dpl_str_to_shm(str src, str *dest, int mterm)
369 369
 
370 370
 /* Compile pcre pattern
371 371
  * if mtype==0 - return pointer to shm copy of result
372
- * if mtype==1 - return pcre pointer that has to be pcre_free() */
373
-pcre *reg_ex_comp(const char *pattern, int *cap_cnt, int mtype)
372
+ * if mtype==1 - return pcre2_code pointer that has to be pcre2_code_free() */
373
+pcre2_code *reg_ex_comp(const char *pattern, int *cap_cnt, int mtype)
374 374
 {
375
-	pcre *re, *result;
376
-	const char *error;
377
-	int rc, err_offset;
378
-	size_t size;
375
+	pcre2_code *re, *result;
376
+	PCRE2_UCHAR error[256];
377
+	int rc, err_number;
378
+	size_t size, err_offset;
379 379
 
380
-	re = pcre_compile(pattern, 0, &error, &err_offset, NULL);
380
+	re = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, 0, &err_number, &err_offset, NULL);
381 381
 	if (re == NULL) {
382
-		LM_ERR("PCRE compilation of '%s' failed at offset %d: %s\n",
382
+		pcre2_get_error_message(err_number, error, sizeof(error));
383
+		LM_ERR("PCRE compilation of '%s' failed at offset %zu: %s\n",
383 384
 				pattern, err_offset, error);
384
-		return (pcre *)0;
385
+		return NULL;
385 386
 	}
386
-	rc = pcre_fullinfo(re, NULL, PCRE_INFO_SIZE, &size);
387
+	rc = pcre2_pattern_info(re, PCRE2_INFO_SIZE, &size);
387 388
 	if (rc != 0) {
388
-		pcre_free(re);
389
+		pcre2_code_free(re);
389 390
 		LM_ERR("pcre_fullinfo on compiled pattern '%s' yielded error: %d\n",
390 391
 				pattern, rc);
391
-		return (pcre *)0;
392
+		return NULL;
392 393
 	}
393
-	rc = pcre_fullinfo(re, NULL, PCRE_INFO_CAPTURECOUNT, cap_cnt);
394
+	rc = pcre2_pattern_info(re, PCRE2_INFO_CAPTURECOUNT, cap_cnt);
394 395
 	if (rc != 0) {
395
-		pcre_free(re);
396
+		pcre2_code_free(re);
396 397
 		LM_ERR("pcre_fullinfo on compiled pattern '%s' yielded error: %d\n",
397 398
 				pattern, rc);
398
-		return (pcre *)0;
399
+		return NULL;
399 400
 	}
400 401
 	if(mtype==0) {
401
-		result = (pcre *)shm_malloc(size);
402
+		result = (pcre2_code *)shm_malloc(size);
402 403
 		if (result == NULL) {
403
-			pcre_free(re);
404
+			pcre2_code_free(re);
404 405
 			LM_ERR("not enough shared memory for compiled PCRE pattern\n");
405
-			return (pcre *)0;
406
+			return NULL;
406 407
 		}
407 408
 		memcpy(result, re, size);
408
-		pcre_free(re);
409
+		pcre2_code_free(re);
409 410
 		return result;
410 411
 	} else {
411 412
 		return re;
... ...
@@ -416,7 +417,7 @@ pcre *reg_ex_comp(const char *pattern, int *cap_cnt, int mtype)
416 417
 /*compile the expressions, and if ok, build the rule */
417 418
 dpl_node_t * build_rule(db_val_t * values)
418 419
 {
419
-	pcre *match_comp, *subst_comp;
420
+	pcre2_code *match_comp, *subst_comp;
420 421
 	struct subst_expr *repl_comp;
421 422
 	dpl_node_t * new_rule;
422 423
 	str match_exp, subst_exp, repl_exp, attrs;
... ...
@@ -38,7 +38,7 @@
38 38
 
39 39
 typedef struct dpl_dyn_pcre
40 40
 {
41
-	pcre *re;
41
+	pcre2_code *re;
42 42
 	int cnt;
43 43
 	str expr;
44 44
 
... ...
@@ -175,9 +175,9 @@ int dpl_detect_avp_indx(const pv_elem_p elem, pv_elem_p *avp)
175 175
 	return 0;
176 176
 }
177 177
 
178
-pcre *dpl_dyn_pcre_comp(sip_msg_t *msg, str *expr, str *vexpr, int *cap_cnt)
178
+pcre2_code *dpl_dyn_pcre_comp(sip_msg_t *msg, str *expr, str *vexpr, int *cap_cnt)
179 179
 {
180
-	pcre *re = NULL;
180
+	pcre2_code *re = NULL;
181 181
 	int ccnt = 0;
182 182
 
183 183
 	if(expr==NULL || expr->s==NULL || expr->len<=0 ||
... ...
@@ -214,7 +214,7 @@ dpl_dyn_pcre_p dpl_dynamic_pcre_list(sip_msg_t *msg, str *expr)
214 214
 	dpl_dyn_pcre_p rt = NULL;
215 215
 	struct str_list *l = NULL;
216 216
 	struct str_list *t = NULL;
217
-	pcre *re = NULL;
217
+	pcre2_code *re = NULL;
218 218
 	int cnt = 0;
219 219
 	str vexpr = STR_NULL;
220 220
 
... ...
@@ -251,6 +251,7 @@ dpl_dyn_pcre_p dpl_dynamic_pcre_list(sip_msg_t *msg, str *expr)
251 251
 					goto error;
252 252
 				}
253 253
 				rt->re = re;
254
+				rt->match_data = pcre2_match_data_create_from_pattern(re, NULL);
254 255
 				rt->expr.s = t->s.s;
255 256
 				rt->expr.len = t->s.len;
256 257
 				rt->cnt = cnt;
... ...
@@ -274,6 +275,7 @@ dpl_dyn_pcre_p dpl_dynamic_pcre_list(sip_msg_t *msg, str *expr)
274 275
 				goto error;
275 276
 			}
276 277
 			rt->re = re;
278
+			rt->match_data = pcre2_match_data_create_from_pattern(re, NULL);
277 279
 			rt->expr.s = expr->s;
278 280
 			rt->expr.len = expr->len;
279 281
 			rt->cnt = cnt;
... ...
@@ -285,7 +287,8 @@ dpl_dyn_pcre_p dpl_dynamic_pcre_list(sip_msg_t *msg, str *expr)
285 287
 error:
286 288
 	while(re_list) {
287 289
 		rt = re_list->next;
288
-		if(re_list->re) pcre_free(re_list->re);
290
+		if(re_list->match_data) pcre2_match_data_free(re_list->match_data);
291
+		if(re_list->re) pcre2_code_free(re_list->re);
289 292
 		pkg_free(re_list);
290 293
 		re_list = rt;
291 294
 	}
... ...
@@ -387,7 +390,7 @@ error:
387 390
 #define MAX_PHONE_NB_DIGITS		127
388 391
 static char dp_output_buf[MAX_PHONE_NB_DIGITS+1];
389 392
 int rule_translate(sip_msg_t *msg, str *instr, dpl_node_t *rule,
390
-		pcre *subst_comp, str *result)
393
+		pcre2_code *subst_comp, pcre2_match_data *match_data, str *result)
391 394
 {
392 395
 	int repl_nb, offset, match_nb, rc, cap_cnt;
393 396
 	struct replace_with token;
... ...
@@ -411,7 +414,7 @@ int rule_translate(sip_msg_t *msg, str *instr, dpl_node_t *rule,
411 414
 
412 415
 	if(subst_comp){
413 416
 		/*just in case something went wrong at load time*/
414
-		rc = pcre_fullinfo(subst_comp, NULL, PCRE_INFO_CAPTURECOUNT,
417
+		rc = pcre2_pattern_info(subst_comp, PCRE2_INFO_CAPTURECOUNT,
415 418
 				&cap_cnt);
416 419
 		if (rc != 0) {
417 420
 			LM_ERR("pcre_fullinfo on compiled pattern yielded error: %d\n",
... ...
@@ -430,7 +433,7 @@ int rule_translate(sip_msg_t *msg, str *instr, dpl_node_t *rule,
430 433
 		}
431 434
 
432 435
 		/*search for the pattern from the compiled subst_exp*/
433
-		if (pcre_exec(subst_comp, NULL, instr->s, instr->len,
436
+		if (pcre2_match(subst_comp, instr->s, instr->len,
434 437
 					0, 0, ovector, 3 * (MAX_REPLACE_WITH + 1)) <= 0) {
435 438
 			LM_DBG("the string %.*s matched "
436 439
 					"the match_exp %.*s but not the subst_exp %.*s!\n",
... ...
@@ -615,21 +618,22 @@ search_rule:
615 618
 					rez = -1;
616 619
 					do {
617 620
 						if(rez<0) {
618
-							rez = pcre_exec(re_list->re, NULL, input->s, input->len,
619
-									0, 0, NULL, 0);
621
+							rez = pcre2_match(re_list->re, input->s, input->len,
622
+									0, 0, re_list->match_data, NULL);
620 623
 							LM_DBG("match check: [%.*s] %d\n",
621 624
 								re_list->expr.len, re_list->expr.s, rez);
622 625
 						}
623 626
 						else LM_DBG("match check skipped: [%.*s] %d\n",
624 627
 								re_list->expr.len, re_list->expr.s, rez);
625 628
 						rt = re_list->next;
626
-						pcre_free(re_list->re);
629
+						pcre2_match_data_free(re_list->match_data);
630
+						pcre2_code_free(re_list->re);
627 631
 						pkg_free(re_list);
628 632
 						re_list = rt;
629 633
 					} while(re_list);
630 634
 				} else {
631
-					rez = pcre_exec(rulep->match_comp, NULL, input->s, input->len,
632
-						0, 0, NULL, 0);
635
+					rez = pcre_exec(rulep->match_comp, input->s, input->len,
636
+						0, 0, rulep->match_data, NULL);
633 637
 				}
634 638
 				break;
635 639
 
... ...
@@ -713,14 +717,15 @@ repl:
713 717
 		rez = -1;
714 718
 		do {
715 719
 			if(rez<0) {
716
-				rez = rule_translate(msg, input, rulep, re_list->re, output);
720
+				rez = rule_translate(msg, input, rulep, re_list->re, re_list->match_data, output);
717 721
 				LM_DBG("subst check: [%.*s] %d\n",
718 722
 					re_list->expr.len, re_list->expr.s, rez);
719 723
 			}
720 724
 			else LM_DBG("subst check skipped: [%.*s] %d\n",
721 725
 					re_list->expr.len, re_list->expr.s, rez);
722 726
 			rt = re_list->next;
723
-			pcre_free(re_list->re);
727
+			pcre2_match_data_free(re_list->match_data);
728
+			pcre2_code_free(re_list->re);
724 729
 			pkg_free(re_list);
725 730
 			re_list = rt;
726 731
 		} while(re_list);
... ...
@@ -733,7 +738,7 @@ repl:
733 738
 		}
734 739
 	}
735 740
 	else {
736
-		if(rule_translate(msg, input, rulep, rulep->subst_comp, output)!=0){
741
+		if(rule_translate(msg, input, rulep, rulep->subst_comp, rulep->match_data, output)!=0){
737 742
 			LM_ERR("could not build the output\n");
738 743
 			return -1;
739 744
 		}