00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "../../re.h"
00030 #include "../../mem/shm_mem.h"
00031 #include "dialplan.h"
00032
00033
00034 void repl_expr_free(struct subst_expr *se)
00035 {
00036 if(!se)
00037 return;
00038
00039 if(se->replacement.s){
00040 shm_free(se->replacement.s);
00041 se->replacement.s = 0;
00042 }
00043
00044 shm_free(se);
00045 se = 0;
00046 }
00047
00048
00049 struct subst_expr* repl_exp_parse(str subst)
00050 {
00051 struct replace_with rw[MAX_REPLACE_WITH];
00052 int rw_no;
00053 struct subst_expr * se;
00054 int replace_all;
00055 char * p, *end, *repl, *repl_end;
00056 int max_pmatch, r;
00057
00058 se = 0;
00059 replace_all = 0;
00060 p = subst.s;
00061 end = p + subst.len;
00062 rw_no = 0;
00063
00064 repl = p;
00065 if((rw_no = parse_repl(rw, &p, end, &max_pmatch, WITHOUT_SEP))< 0)
00066 goto error;
00067
00068 repl_end=p;
00069
00070
00071 se = shm_malloc(sizeof(struct subst_expr)+
00072 ((rw_no)?(rw_no-1)*sizeof(struct replace_with):0));
00073
00074 if (se==0){
00075 LM_ERR("out of shm memory (subst_expr)\n");
00076 goto error;
00077 }
00078 memset((void*)se, 0, sizeof(struct subst_expr));
00079
00080 se->replacement.len=repl_end-repl;
00081 if (!(se->replacement.s=shm_malloc(se->replacement.len * sizeof(char))) ){
00082 LM_ERR("out of shm memory \n");
00083 goto error;
00084 }
00085 if(!rw_no){
00086 replace_all = 1;
00087 }
00088
00089 memcpy(se->replacement.s, repl, se->replacement.len);
00090 se->re=0;
00091 se->replace_all=replace_all;
00092 se->n_escapes=rw_no;
00093 se->max_pmatch=max_pmatch;
00094
00095
00096 for (r=0; r<rw_no; r++) se->replace[r]=rw[r];
00097 return se;
00098
00099 error:
00100 if (se) { repl_expr_free(se);}
00101 return NULL;
00102 }
00103
00104
00105 #define MAX_PHONE_NB_DIGITS 127
00106 static char dp_output_buf[MAX_PHONE_NB_DIGITS+1];
00107 int rule_translate(struct sip_msg *msg, str string, dpl_node_t * rule,
00108 str * result)
00109 {
00110 int repl_nb, offset, match_nb, rc, cap_cnt;
00111 struct replace_with token;
00112 pcre *subst_comp;
00113 struct subst_expr * repl_comp;
00114 str match;
00115 pv_value_t sv;
00116 str* uri;
00117 int ovector[3 * (MAX_REPLACE_WITH + 1)];
00118
00119 dp_output_buf[0] = '\0';
00120 result->s = dp_output_buf;
00121 result->len = 0;
00122
00123 subst_comp = rule->subst_comp;
00124 repl_comp = rule->repl_comp;
00125
00126 if(!repl_comp){
00127 LM_DBG("null replacement\n");
00128 return 0;
00129 }
00130
00131 if(subst_comp){
00132
00133 rc = pcre_fullinfo(subst_comp, NULL, PCRE_INFO_CAPTURECOUNT,
00134 &cap_cnt);
00135 if (rc != 0) {
00136 LM_ERR("pcre_fullinfo on compiled pattern yielded error: %d\n",
00137 rc);
00138 return -1;;
00139 }
00140 if(repl_comp->max_pmatch > cap_cnt){
00141 LM_ERR("illegal access to the %i-th subexpr of the subst expr\n",
00142 repl_comp->max_pmatch);
00143 return -1;
00144 }
00145
00146
00147 if (pcre_exec(rule->subst_comp, NULL, string.s, string.len,
00148 0, 0, ovector, 3 * (MAX_REPLACE_WITH + 1)) <= 0) {
00149 LM_ERR("the string %.*s matched "
00150 "the match_exp %.*s but not the subst_exp %.*s!\n",
00151 string.len, string.s,
00152 rule->match_exp.len, rule->match_exp.s,
00153 rule->subst_exp.len, rule->subst_exp.s);
00154 return -1;
00155 }
00156 }
00157
00158
00159 if(!subst_comp || (repl_comp->n_escapes <=0)){
00160 if(!repl_comp->replacement.s || repl_comp->replacement.len == 0){
00161 LM_ERR("invalid replacing string\n");
00162 goto error;
00163 }
00164 LM_DBG("simply replace the string, subst_comp %p, n_escapes %i\n",
00165 subst_comp, repl_comp->n_escapes);
00166 memcpy(result->s, repl_comp->replacement.s,
00167 repl_comp->replacement.len);
00168 result->len = repl_comp->replacement.len;
00169 result->s[result->len] = '\0';
00170 return 0;
00171 }
00172
00173
00174 result->len = repl_nb = offset = 0;
00175
00176 while( repl_nb < repl_comp->n_escapes){
00177 token = repl_comp->replace[repl_nb];
00178
00179 if(offset< token.offset){
00180 if((repl_comp->replacement.len < offset)||
00181 (result->len + token.offset -offset >= MAX_PHONE_NB_DIGITS)){
00182 LM_ERR("invalid length\n");
00183 goto error;
00184 }
00185
00186 memcpy(result->s + result->len, repl_comp->replacement.s + offset,
00187 token.offset-offset);
00188 result->len += (token.offset - offset);
00189 offset += token.offset-offset;
00190 }
00191
00192 switch(token.type) {
00193 case REPLACE_NMATCH:
00194
00195 match_nb = token.u.nmatch * 2;
00196 match.s = string.s + ovector[match_nb];
00197 match.len = ovector[match_nb + 1] - ovector[match_nb];
00198 if(result->len + match.len >= MAX_PHONE_NB_DIGITS){
00199 LM_ERR("overflow\n");
00200 goto error;
00201 }
00202
00203 memcpy(result->s + result->len, match.s, match.len);
00204 result->len += match.len;
00205 offset += token.size;
00206 break;
00207 case REPLACE_CHAR:
00208 if(result->len + 1>= MAX_PHONE_NB_DIGITS){
00209 LM_ERR("overflow\n");
00210 goto error;
00211 }
00212 *result->s=repl_comp->replace[repl_nb].u.c;
00213 result->len++;
00214 break;
00215 case REPLACE_URI:
00216 if ( msg== NULL || msg->first_line.type!=SIP_REQUEST){
00217 LM_CRIT("uri substitution attempt on no request"
00218 " message\n");
00219 break;
00220 }
00221 uri= (msg->new_uri.s)?(&msg->new_uri):
00222 (&msg->first_line.u.request.uri);
00223 if(result->len+uri->len>=MAX_PHONE_NB_DIGITS){
00224 LM_ERR("overflow\n");
00225 goto error;
00226 }
00227 memcpy(result->s + result->len, uri->s, uri->len);
00228 result->len+=uri->len;
00229 break;
00230 case REPLACE_SPEC:
00231 if (msg== NULL) {
00232 LM_DBG("replace spec attempted on no message\n");
00233 break;
00234 }
00235 if(pv_get_spec_value(msg,
00236 &repl_comp->replace[repl_nb].u.spec, &sv)!=0){
00237 LM_CRIT("item substitution returned error\n");
00238 break;
00239 }
00240 if(result->len+sv.rs.len>=MAX_PHONE_NB_DIGITS){
00241 LM_ERR("rule_translate: overflow\n");
00242 goto error;
00243 }
00244 memcpy(result->s + result->len, sv.rs.s, sv.rs.len);
00245 result->len+=sv.rs.len;
00246 break;
00247 default:
00248 LM_CRIT("unknown type %d\n", repl_comp->replace[repl_nb].type);
00249
00250 }
00251 repl_nb++;
00252 }
00253 result->s[result->len] = '\0';
00254 return 0;
00255
00256 error:
00257 result->s = 0;
00258 result->len = 0;
00259 return -1;
00260 }
00261
00262 #define DP_MAX_ATTRS_LEN 32
00263 static char dp_attrs_buf[DP_MAX_ATTRS_LEN+1];
00264 int translate(struct sip_msg *msg, str input, str *output, dpl_id_p idp,
00265 str *attrs)
00266 {
00267 dpl_node_p rulep;
00268 dpl_index_p indexp;
00269 int user_len, rez;
00270
00271 if(!input.s || !input.len) {
00272 LM_ERR("invalid input string\n");
00273 return -1;
00274 }
00275
00276 user_len = input.len;
00277 for(indexp = idp->first_index; indexp!=NULL; indexp = indexp->next)
00278 if(!indexp->len || (indexp->len!=0 && indexp->len == user_len) )
00279 break;
00280
00281 if(!indexp || (indexp!= NULL && !indexp->first_rule)){
00282 LM_DBG("no rule for len %i\n", input.len);
00283 return -1;
00284 }
00285
00286 search_rule:
00287 for(rulep=indexp->first_rule; rulep!=NULL; rulep= rulep->next) {
00288 switch(rulep->matchop) {
00289
00290 case REGEX_OP:
00291 LM_DBG("regex operator testing\n");
00292 rez = pcre_exec(rulep->match_comp, NULL, input.s, input.len,
00293 0, 0, NULL, 0);
00294 break;
00295
00296 case EQUAL_OP:
00297 LM_DBG("equal operator testing\n");
00298 if(rulep->match_exp.len != input.len)
00299 rez = -1;
00300 else
00301 rez = strncmp(rulep->match_exp.s,input.s,input.len);
00302 break;
00303
00304 default:
00305 LM_ERR("bogus match operator code %i\n", rulep->matchop);
00306 return -1;
00307 }
00308 if(rez >= 0)
00309 goto repl;
00310 }
00311
00312 if(indexp->len){
00313 for(indexp = indexp->next; indexp!=NULL; indexp = indexp->next)
00314 if(!indexp->len)
00315 break;
00316 if(indexp)
00317 goto search_rule;
00318 }
00319
00320 LM_DBG("no matching rule\n");
00321 return -1;
00322
00323 repl:
00324 LM_DBG("found a matching rule %p: pr %i, match_exp %.*s\n",
00325 rulep, rulep->pr, rulep->match_exp.len, rulep->match_exp.s);
00326
00327 if(attrs) {
00328 attrs->len = 0;
00329 attrs->s = 0;
00330 if(rulep->attrs.len>0) {
00331 LM_DBG("the rule's attrs are %.*s\n",
00332 rulep->attrs.len, rulep->attrs.s);
00333 if(rulep->attrs.len >= DP_MAX_ATTRS_LEN) {
00334 LM_ERR("out of memory for attributes\n");
00335 return -1;
00336 }
00337 attrs->s = dp_attrs_buf;
00338 memcpy(attrs->s, rulep->attrs.s, rulep->attrs.len*sizeof(char));
00339 attrs->len = rulep->attrs.len;
00340 attrs->s[attrs->len] = '\0';
00341
00342 LM_DBG("the copied attributes are: %.*s\n",
00343 attrs->len, attrs->s);
00344 }
00345 }
00346
00347 if(rule_translate(msg, input, rulep, output)!=0){
00348 LM_ERR("could not build the output\n");
00349 return -1;
00350 }
00351
00352 return 0;
00353 }