|
@@ -41,7 +41,7 @@
|
|
|
|
|
|
void repl_expr_free(struct subst_expr *se)
|
|
void repl_expr_free(struct subst_expr *se)
|
|
{
|
|
{
|
|
- if(!se)
|
|
|
|
|
|
+ if(!se)
|
|
return;
|
|
return;
|
|
|
|
|
|
if(se->replacement.s){
|
|
if(se->replacement.s){
|
|
@@ -62,11 +62,22 @@ struct subst_expr* repl_exp_parse(str subst)
|
|
int replace_all;
|
|
int replace_all;
|
|
char * p, *end, *repl, *repl_end;
|
|
char * p, *end, *repl, *repl_end;
|
|
int max_pmatch, r;
|
|
int max_pmatch, r;
|
|
|
|
+ str shms;
|
|
|
|
|
|
se = 0;
|
|
se = 0;
|
|
replace_all = 0;
|
|
replace_all = 0;
|
|
- p = subst.s;
|
|
|
|
- end = p + subst.len;
|
|
|
|
|
|
+ shms.s = NULL;
|
|
|
|
+
|
|
|
|
+ if (!(shms.s=shm_malloc((subst.len+1) * sizeof(char))) ){
|
|
|
|
+ LM_ERR("out of shm memory\n");
|
|
|
|
+ goto error;
|
|
|
|
+ }
|
|
|
|
+ memcpy(shms.s, subst.s, subst.len);
|
|
|
|
+ shms.len = subst.len;
|
|
|
|
+ shms.s[shms.len] = '\0';
|
|
|
|
+
|
|
|
|
+ p = shms.s;
|
|
|
|
+ end = p + shms.len;
|
|
rw_no = 0;
|
|
rw_no = 0;
|
|
|
|
|
|
repl = p;
|
|
repl = p;
|
|
@@ -75,7 +86,7 @@ struct subst_expr* repl_exp_parse(str subst)
|
|
|
|
|
|
repl_end=p;
|
|
repl_end=p;
|
|
|
|
|
|
- /* construct the subst_expr structure */
|
|
|
|
|
|
+ /* construct the subst_expr structure */
|
|
se = shm_malloc(sizeof(struct subst_expr)+
|
|
se = shm_malloc(sizeof(struct subst_expr)+
|
|
((rw_no)?(rw_no-1)*sizeof(struct replace_with):0));
|
|
((rw_no)?(rw_no-1)*sizeof(struct replace_with):0));
|
|
/* 1 replace_with structure is already included in subst_expr */
|
|
/* 1 replace_with structure is already included in subst_expr */
|
|
@@ -85,26 +96,27 @@ struct subst_expr* repl_exp_parse(str subst)
|
|
}
|
|
}
|
|
memset((void*)se, 0, sizeof(struct subst_expr));
|
|
memset((void*)se, 0, sizeof(struct subst_expr));
|
|
|
|
|
|
|
|
+ se->replacement.s = shms.s;
|
|
|
|
+ shms.s = NULL;
|
|
se->replacement.len=repl_end-repl;
|
|
se->replacement.len=repl_end-repl;
|
|
- if (!(se->replacement.s=shm_malloc(se->replacement.len * sizeof(char))) ){
|
|
|
|
- LM_ERR("out of shm memory \n");
|
|
|
|
- goto error;
|
|
|
|
- }
|
|
|
|
if(!rw_no){
|
|
if(!rw_no){
|
|
replace_all = 1;
|
|
replace_all = 1;
|
|
}
|
|
}
|
|
/* start copying */
|
|
/* start copying */
|
|
- memcpy(se->replacement.s, repl, se->replacement.len);
|
|
|
|
|
|
+ LM_DBG("replacement expression is [%.*s]\n", se->replacement.len,
|
|
|
|
+ se->replacement.s);
|
|
se->re=0;
|
|
se->re=0;
|
|
se->replace_all=replace_all;
|
|
se->replace_all=replace_all;
|
|
se->n_escapes=rw_no;
|
|
se->n_escapes=rw_no;
|
|
se->max_pmatch=max_pmatch;
|
|
se->max_pmatch=max_pmatch;
|
|
|
|
|
|
- /*replace_with is a simple structure, no shm alloc needed*/
|
|
|
|
|
|
+ /*replace_with is a simple structure, no shm alloc needed*/
|
|
for (r=0; r<rw_no; r++) se->replace[r]=rw[r];
|
|
for (r=0; r<rw_no; r++) se->replace[r]=rw[r];
|
|
return se;
|
|
return se;
|
|
|
|
|
|
error:
|
|
error:
|
|
|
|
+ if(shms.s != NULL)
|
|
|
|
+ shm_free(shms.s);
|
|
if (se) { repl_expr_free(se);}
|
|
if (se) { repl_expr_free(se);}
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
@@ -113,7 +125,7 @@ error:
|
|
#define MAX_PHONE_NB_DIGITS 127
|
|
#define MAX_PHONE_NB_DIGITS 127
|
|
static char dp_output_buf[MAX_PHONE_NB_DIGITS+1];
|
|
static char dp_output_buf[MAX_PHONE_NB_DIGITS+1];
|
|
int rule_translate(struct sip_msg *msg, str string, dpl_node_t * rule,
|
|
int rule_translate(struct sip_msg *msg, str string, dpl_node_t * rule,
|
|
- str * result)
|
|
|
|
|
|
+ str * result)
|
|
{
|
|
{
|
|
int repl_nb, offset, match_nb, rc, cap_cnt;
|
|
int repl_nb, offset, match_nb, rc, cap_cnt;
|
|
struct replace_with token;
|
|
struct replace_with token;
|
|
@@ -144,23 +156,23 @@ int rule_translate(struct sip_msg *msg, str string, dpl_node_t * rule,
|
|
&cap_cnt);
|
|
&cap_cnt);
|
|
if (rc != 0) {
|
|
if (rc != 0) {
|
|
LM_ERR("pcre_fullinfo on compiled pattern yielded error: %d\n",
|
|
LM_ERR("pcre_fullinfo on compiled pattern yielded error: %d\n",
|
|
- rc);
|
|
|
|
|
|
+ rc);
|
|
return -1;;
|
|
return -1;;
|
|
}
|
|
}
|
|
if(repl_comp->max_pmatch > cap_cnt){
|
|
if(repl_comp->max_pmatch > cap_cnt){
|
|
LM_ERR("illegal access to the %i-th subexpr of the subst expr\n",
|
|
LM_ERR("illegal access to the %i-th subexpr of the subst expr\n",
|
|
- repl_comp->max_pmatch);
|
|
|
|
|
|
+ repl_comp->max_pmatch);
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
/*search for the pattern from the compiled subst_exp*/
|
|
/*search for the pattern from the compiled subst_exp*/
|
|
if (pcre_exec(rule->subst_comp, NULL, string.s, string.len,
|
|
if (pcre_exec(rule->subst_comp, NULL, string.s, string.len,
|
|
- 0, 0, ovector, 3 * (MAX_REPLACE_WITH + 1)) <= 0) {
|
|
|
|
|
|
+ 0, 0, ovector, 3 * (MAX_REPLACE_WITH + 1)) <= 0) {
|
|
LM_ERR("the string %.*s matched "
|
|
LM_ERR("the string %.*s matched "
|
|
- "the match_exp %.*s but not the subst_exp %.*s!\n",
|
|
|
|
- string.len, string.s,
|
|
|
|
- rule->match_exp.len, rule->match_exp.s,
|
|
|
|
- rule->subst_exp.len, rule->subst_exp.s);
|
|
|
|
|
|
+ "the match_exp %.*s but not the subst_exp %.*s!\n",
|
|
|
|
+ string.len, string.s,
|
|
|
|
+ rule->match_exp.len, rule->match_exp.s,
|
|
|
|
+ rule->subst_exp.len, rule->subst_exp.s);
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -187,10 +199,10 @@ int rule_translate(struct sip_msg *msg, str string, dpl_node_t * rule,
|
|
while( repl_nb < repl_comp->n_escapes){
|
|
while( repl_nb < repl_comp->n_escapes){
|
|
|
|
|
|
token = repl_comp->replace[repl_nb];
|
|
token = repl_comp->replace[repl_nb];
|
|
-
|
|
|
|
|
|
+
|
|
if(offset< token.offset){
|
|
if(offset< token.offset){
|
|
if((repl_comp->replacement.len < offset)||
|
|
if((repl_comp->replacement.len < offset)||
|
|
- (result->len + token.offset -offset >= MAX_PHONE_NB_DIGITS)){
|
|
|
|
|
|
+ (result->len + token.offset -offset >= MAX_PHONE_NB_DIGITS)){
|
|
LM_ERR("invalid length\n");
|
|
LM_ERR("invalid length\n");
|
|
goto error;
|
|
goto error;
|
|
}
|
|
}
|
|
@@ -198,7 +210,7 @@ int rule_translate(struct sip_msg *msg, str string, dpl_node_t * rule,
|
|
size = token.offset - offset;
|
|
size = token.offset - offset;
|
|
memcpy(result->s + result->len, p + offset, size);
|
|
memcpy(result->s + result->len, p + offset, size);
|
|
LM_DBG("copying <%.*s> from replacing string\n",
|
|
LM_DBG("copying <%.*s> from replacing string\n",
|
|
- size, p + offset);
|
|
|
|
|
|
+ size, p + offset);
|
|
result->len += size;
|
|
result->len += size;
|
|
offset = token.offset;
|
|
offset = token.offset;
|
|
}
|
|
}
|
|
@@ -216,10 +228,10 @@ int rule_translate(struct sip_msg *msg, str string, dpl_node_t * rule,
|
|
|
|
|
|
memcpy(result->s + result->len, match.s, match.len);
|
|
memcpy(result->s + result->len, match.s, match.len);
|
|
LM_DBG("copying match <%.*s> token size %d\n",
|
|
LM_DBG("copying match <%.*s> token size %d\n",
|
|
- match.len, match.s, token.size);
|
|
|
|
|
|
+ match.len, match.s, token.size);
|
|
result->len += match.len;
|
|
result->len += match.len;
|
|
offset += token.size;
|
|
offset += token.size;
|
|
- break;
|
|
|
|
|
|
+ break;
|
|
case REPLACE_CHAR:
|
|
case REPLACE_CHAR:
|
|
if(result->len + 1>= MAX_PHONE_NB_DIGITS){
|
|
if(result->len + 1>= MAX_PHONE_NB_DIGITS){
|
|
LM_ERR("overflow\n");
|
|
LM_ERR("overflow\n");
|
|
@@ -227,14 +239,14 @@ int rule_translate(struct sip_msg *msg, str string, dpl_node_t * rule,
|
|
}
|
|
}
|
|
*(result->s + result->len) = token.u.c;
|
|
*(result->s + result->len) = token.u.c;
|
|
LM_DBG("copying char <%c> token size %d\n",
|
|
LM_DBG("copying char <%c> token size %d\n",
|
|
- token.u.c, token.size);
|
|
|
|
|
|
+ token.u.c, token.size);
|
|
result->len++;
|
|
result->len++;
|
|
offset += token.size;
|
|
offset += token.size;
|
|
- break;
|
|
|
|
|
|
+ break;
|
|
case REPLACE_URI:
|
|
case REPLACE_URI:
|
|
if ( msg== NULL || msg->first_line.type!=SIP_REQUEST){
|
|
if ( msg== NULL || msg->first_line.type!=SIP_REQUEST){
|
|
LM_CRIT("uri substitution attempt on no request"
|
|
LM_CRIT("uri substitution attempt on no request"
|
|
- " message\n");
|
|
|
|
|
|
+ " message\n");
|
|
break; /* ignore, we can continue */
|
|
break; /* ignore, we can continue */
|
|
}
|
|
}
|
|
uri= (msg->new_uri.s)?(&msg->new_uri):
|
|
uri= (msg->new_uri.s)?(&msg->new_uri):
|
|
@@ -245,10 +257,10 @@ int rule_translate(struct sip_msg *msg, str string, dpl_node_t * rule,
|
|
}
|
|
}
|
|
memcpy(result->s + result->len, uri->s, uri->len);
|
|
memcpy(result->s + result->len, uri->s, uri->len);
|
|
LM_DBG("copying uri <%.*s> token size %d\n",
|
|
LM_DBG("copying uri <%.*s> token size %d\n",
|
|
- uri->len, uri->s, token.size);
|
|
|
|
|
|
+ uri->len, uri->s, token.size);
|
|
result->len+=uri->len;
|
|
result->len+=uri->len;
|
|
offset += token.size;
|
|
offset += token.size;
|
|
- break;
|
|
|
|
|
|
+ break;
|
|
case REPLACE_SPEC:
|
|
case REPLACE_SPEC:
|
|
if (msg== NULL) {
|
|
if (msg== NULL) {
|
|
LM_DBG("replace spec attempted on no message\n");
|
|
LM_DBG("replace spec attempted on no message\n");
|
|
@@ -263,12 +275,12 @@ int rule_translate(struct sip_msg *msg, str string, dpl_node_t * rule,
|
|
goto error;
|
|
goto error;
|
|
}
|
|
}
|
|
memcpy(result->s + result->len, sv.rs.s,
|
|
memcpy(result->s + result->len, sv.rs.s,
|
|
- sv.rs.len);
|
|
|
|
|
|
+ sv.rs.len);
|
|
LM_DBG("copying pvar value <%.*s> token size %d\n",
|
|
LM_DBG("copying pvar value <%.*s> token size %d\n",
|
|
- sv.rs.len, sv.rs.s, token.size);
|
|
|
|
|
|
+ sv.rs.len, sv.rs.s, token.size);
|
|
result->len+=sv.rs.len;
|
|
result->len+=sv.rs.len;
|
|
offset += token.size;
|
|
offset += token.size;
|
|
- break;
|
|
|
|
|
|
+ break;
|
|
default:
|
|
default:
|
|
LM_CRIT("unknown type %d\n", repl_comp->replace[repl_nb].type);
|
|
LM_CRIT("unknown type %d\n", repl_comp->replace[repl_nb].type);
|
|
/* ignore it */
|
|
/* ignore it */
|
|
@@ -281,7 +293,7 @@ int rule_translate(struct sip_msg *msg, str string, dpl_node_t * rule,
|
|
size = repl_comp->replacement.len - offset;
|
|
size = repl_comp->replacement.len - offset;
|
|
memcpy(result->s + result->len, p + offset, size);
|
|
memcpy(result->s + result->len, p + offset, size);
|
|
LM_DBG("copying leftover <%.*s> from replacing string\n",
|
|
LM_DBG("copying leftover <%.*s> from replacing string\n",
|
|
- size, p + offset);
|
|
|
|
|
|
+ size, p + offset);
|
|
result->len += size;
|
|
result->len += size;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -297,12 +309,12 @@ error:
|
|
#define DP_MAX_ATTRS_LEN 32
|
|
#define DP_MAX_ATTRS_LEN 32
|
|
static char dp_attrs_buf[DP_MAX_ATTRS_LEN+1];
|
|
static char dp_attrs_buf[DP_MAX_ATTRS_LEN+1];
|
|
int translate(struct sip_msg *msg, str input, str *output, dpl_id_p idp,
|
|
int translate(struct sip_msg *msg, str input, str *output, dpl_id_p idp,
|
|
- str *attrs)
|
|
|
|
|
|
+ str *attrs)
|
|
{
|
|
{
|
|
dpl_node_p rulep;
|
|
dpl_node_p rulep;
|
|
dpl_index_p indexp;
|
|
dpl_index_p indexp;
|
|
int user_len, rez;
|
|
int user_len, rez;
|
|
-
|
|
|
|
|
|
+
|
|
if(!input.s || !input.len) {
|
|
if(!input.s || !input.len) {
|
|
LM_ERR("invalid input string\n");
|
|
LM_ERR("invalid input string\n");
|
|
return -1;
|
|
return -1;
|
|
@@ -323,21 +335,21 @@ search_rule:
|
|
switch(rulep->matchop) {
|
|
switch(rulep->matchop) {
|
|
|
|
|
|
case REGEX_OP:
|
|
case REGEX_OP:
|
|
- LM_DBG("regex operator testing\n");
|
|
|
|
|
|
+ LM_DBG("regex operator testing\n");
|
|
rez = pcre_exec(rulep->match_comp, NULL, input.s, input.len,
|
|
rez = pcre_exec(rulep->match_comp, NULL, input.s, input.len,
|
|
- 0, 0, NULL, 0);
|
|
|
|
- break;
|
|
|
|
|
|
+ 0, 0, NULL, 0);
|
|
|
|
+ break;
|
|
|
|
|
|
case EQUAL_OP:
|
|
case EQUAL_OP:
|
|
LM_DBG("equal operator testing\n");
|
|
LM_DBG("equal operator testing\n");
|
|
- if(rulep->match_exp.len != input.len) {
|
|
|
|
|
|
+ if(rulep->match_exp.len != input.len) {
|
|
rez = -1;
|
|
rez = -1;
|
|
} else {
|
|
} else {
|
|
rez = strncmp(rulep->match_exp.s,input.s,input.len);
|
|
rez = strncmp(rulep->match_exp.s,input.s,input.len);
|
|
rez = (rez==0)?0:-1;
|
|
rez = (rez==0)?0:-1;
|
|
}
|
|
}
|
|
- break;
|
|
|
|
-
|
|
|
|
|
|
+ break;
|
|
|
|
+
|
|
default:
|
|
default:
|
|
LM_ERR("bogus match operator code %i\n", rulep->matchop);
|
|
LM_ERR("bogus match operator code %i\n", rulep->matchop);
|
|
return -1;
|
|
return -1;
|
|
@@ -351,33 +363,33 @@ search_rule:
|
|
if(!indexp->len)
|
|
if(!indexp->len)
|
|
break;
|
|
break;
|
|
if(indexp)
|
|
if(indexp)
|
|
- goto search_rule;
|
|
|
|
|
|
+ goto search_rule;
|
|
}
|
|
}
|
|
-
|
|
|
|
- LM_DBG("no matching rule\n");
|
|
|
|
- return -1;
|
|
|
|
|
|
+
|
|
|
|
+ LM_DBG("no matching rule\n");
|
|
|
|
+ return -1;
|
|
|
|
|
|
repl:
|
|
repl:
|
|
LM_DBG("found a matching rule %p: pr %i, match_exp %.*s\n",
|
|
LM_DBG("found a matching rule %p: pr %i, match_exp %.*s\n",
|
|
- rulep, rulep->pr, rulep->match_exp.len, rulep->match_exp.s);
|
|
|
|
|
|
+ rulep, rulep->pr, rulep->match_exp.len, rulep->match_exp.s);
|
|
|
|
|
|
if(attrs) {
|
|
if(attrs) {
|
|
attrs->len = 0;
|
|
attrs->len = 0;
|
|
attrs->s = 0;
|
|
attrs->s = 0;
|
|
if(rulep->attrs.len>0) {
|
|
if(rulep->attrs.len>0) {
|
|
LM_DBG("the rule's attrs are %.*s\n",
|
|
LM_DBG("the rule's attrs are %.*s\n",
|
|
- rulep->attrs.len, rulep->attrs.s);
|
|
|
|
|
|
+ rulep->attrs.len, rulep->attrs.s);
|
|
if(rulep->attrs.len >= DP_MAX_ATTRS_LEN) {
|
|
if(rulep->attrs.len >= DP_MAX_ATTRS_LEN) {
|
|
LM_ERR("out of memory for attributes\n");
|
|
LM_ERR("out of memory for attributes\n");
|
|
return -1;
|
|
return -1;
|
|
- }
|
|
|
|
|
|
+ }
|
|
attrs->s = dp_attrs_buf;
|
|
attrs->s = dp_attrs_buf;
|
|
memcpy(attrs->s, rulep->attrs.s, rulep->attrs.len*sizeof(char));
|
|
memcpy(attrs->s, rulep->attrs.s, rulep->attrs.len*sizeof(char));
|
|
attrs->len = rulep->attrs.len;
|
|
attrs->len = rulep->attrs.len;
|
|
attrs->s[attrs->len] = '\0';
|
|
attrs->s[attrs->len] = '\0';
|
|
|
|
|
|
LM_DBG("the copied attributes are: %.*s\n",
|
|
LM_DBG("the copied attributes are: %.*s\n",
|
|
- attrs->len, attrs->s);
|
|
|
|
|
|
+ attrs->len, attrs->s);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|