Esempio n. 1
0
/** fparam_t free function.
 *  Frees the "content" of a fparam, but not the fparam itself.
 *  Note: it doesn't free fp->orig!
 *  Assumes pkg_malloc'ed content.
 *  @param fp -  fparam to be freed
 *
 */
void fparam_free_contents(fparam_t* fp)
{

	if (fp==0)
		return;
	switch(fp->type) {
		case FPARAM_UNSPEC:
		case FPARAM_STRING: /* asciiz string, not str */
		case FPARAM_INT:
		case FPARAM_STR:
			/* nothing to do */
			break;
		case FPARAM_REGEX:
			if (fp->v.regex){
				regfree(fp->v.regex);
				pkg_free(fp->v.regex);
				fp->v.regex=0;
			}
			break;
		case FPARAM_AVP:
			free_avp_name(&fp->v.avp.flags, &fp->v.avp.name);
			break;
		case FPARAM_SELECT:
			if (fp->v.select){
				free_select(fp->v.select);
				fp->v.select=0;
			}
			break;
		case FPARAM_SUBST:
			if (fp->v.subst){
				subst_expr_free(fp->v.subst);
				fp->v.subst=0;
			}
			break;
		case FPARAM_PVS:
			if (fp->v.pvs){
				pv_spec_free(fp->v.pvs);
				fp->v.pvs=0;
			}
			break;
		case FPARAM_PVE:
			if (fp->v.pve){
				pv_elem_free_all(fp->v.pve);
				fp->v.pve=0;
			}
			break;
	}
}
Esempio n. 2
0
int tr_txt_eval_re(struct sip_msg *msg, tr_param_t *tp, int subtype,
		pv_value_t *val)
{
	struct subst_expr *se = NULL;
	int nmatches;
	str* result;
#define TR_TXT_BUF_SIZE	2048
	static char tr_txt_buf[TR_TXT_BUF_SIZE];
	pv_value_t v;

	if(val==NULL || (!(val->flags&PV_VAL_STR)) || val->rs.len<=0)
		return -1;
	
	switch(subtype)
	{
		case TR_TXT_RE_SUBST:
			if (tp->type == TR_PARAM_SUBST) {
				se = (struct subst_expr*)tp->v.data;
				if (se==NULL)
					return 0;
			} else if (tp->type == TR_PARAM_SPEC) {
				if (pv_get_spec_value(msg, (pv_spec_p)tp->v.data, &v)!=0
						|| (!(v.flags&PV_VAL_STR)) || v.rs.len<=0)
				{
					LM_ERR("Can't evaluate regexp\n");
					return -1;
				}
				se=subst_parser(&v.rs);
				if (se==0) {
					LM_ERR("Can't compile regexp\n");
					return -1;
				}
			} else {
				LM_ERR("Unknown parameter type\n");
				return -1;
			}
			if(val->rs.len>=TR_TXT_BUF_SIZE-1)
			{
				LM_ERR("PV value too big %d, increase buffer size\n",
						val->rs.len);
				goto error;
			}
			memcpy(tr_txt_buf, val->rs.s, val->rs.len);
			tr_txt_buf[val->rs.len] = '\0';
			/* pkg malloc'ed result */
			result=subst_str(tr_txt_buf, msg, se, &nmatches);
			if (result == NULL)
			{
				if (nmatches==0)
				{
					LM_DBG("no match for subst expression\n");
					break;
				}
				if (nmatches<0)
					LM_ERR("subst failed\n");
				goto error;
			}
			if(result->len>=TR_TXT_BUF_SIZE-1)
			{
				LM_ERR("subst result too big %d, increase buffer size\n",
						result->len);
				goto error;
			}
			memcpy(tr_txt_buf, result->s, result->len);
			tr_txt_buf[result->len] = '\0';
			memset(val, 0, sizeof(pv_value_t));
			val->flags = PV_VAL_STR;
			val->rs.s = tr_txt_buf;
			val->rs.len = result->len;
			pkg_free(result->s);
			pkg_free(result);
			break;
		default:
			LM_ERR("unknown subtype %d\n", subtype);
			goto error;
	}

	if (tp->type == TR_PARAM_SPEC) {
		subst_expr_free(se);
	}
	return 0;

error:
	if (tp->type == TR_PARAM_SPEC) {
		subst_expr_free(se);
	}
	return -1;
}
Esempio n. 3
0
char* tr_txt_parse_re(str *in, trans_t *t)
{
	char *p;
	str name;
	str tok;
	struct subst_expr *se = NULL;
	tr_param_t *tp = NULL;
	int n;
	pv_spec_t *spec = NULL;


	if(in==NULL || t==NULL)
		return NULL;

	p = in->s;
	name.s = in->s;
	t->type = TR_TXT_RE;
	t->trf = tr_txt_eval_re;

	/* find next token */
	while(is_in_str(p, in) && *p!=TR_PARAM_MARKER && *p!=TR_RBRACKET) p++;
	if(*p=='\0')
		goto error;
	name.len = p - name.s;
	trim(&name);

	if(name.len==5 && strncasecmp(name.s, "subst", 5)==0)
	{
		t->subtype = TR_TXT_RE_SUBST;
		if(*p!=TR_PARAM_MARKER)
			goto error;
		p++;
		if(*p==PV_MARKER) {
			spec = (pv_spec_t*)pkg_malloc(sizeof(pv_spec_t));
			if(spec==NULL)
			{
				LM_ERR("no more private memory!\n");
				return 0;
			}
			tok.s = p; tok.len = in->s + in->len - p;
			p = pv_parse_spec(&tok, spec);
			if(p==NULL)
			{
				LM_ERR("invalid pv spec in transformation: %.*s!\n",
					in->len, in->s);
				pkg_free(spec);
				return 0;
			}

			tp = (tr_param_t*)pkg_malloc(sizeof(tr_param_t));
			if(tp==NULL)
			{
				LM_ERR("no more private memory!\n");
				pkg_free(spec);
				goto error;
			}
			tp->type = TR_PARAM_SPEC;
			tp->v.data = (void*)spec;
		} else {
			/* get trans here */
			n = 0;
			tok.s = p;
			while(is_in_str(p, in))
			{
				if(*p==TR_RBRACKET)
				{
					if(n==0)
							break;
					n--;
				}
				if(*p == TR_LBRACKET)
					n++;
				p++;
			}
			if(!is_in_str(p, in))
				goto error;
			if(p==tok.s)
				goto error;
			tok.len = p - tok.s;
			tp = (tr_param_t*)pkg_malloc(sizeof(tr_param_t));
			if(tp==NULL)
			{
				LM_ERR("no more private memory!\n");
				goto error;
			}

			se=subst_parser(&tok);

			if (se==0)
				goto error;
			tp->type = TR_PARAM_SUBST;
			tp->v.data = (void*)se;
		}
		t->params = tp;

		while(*p && (*p==' ' || *p=='\t' || *p=='\n')) p++;
		if(*p!=TR_RBRACKET)
			goto error;
		goto done;
	}

	LM_ERR("unknown transformation: %.*s/%.*s/%d!\n", in->len, in->s,
			name.len, name.s, name.len);
error:
	LM_ERR("invalid transformation [%.*s] <%d>\n", in->len, in->s,
			(int)(p-in->s));
	if(tp!=NULL)
		pkg_free(tp);
	if(se!=NULL)
		subst_expr_free(se);
	return NULL;
done:
	t->name = name;
	return p;
}
Esempio n. 4
0
/* parse a /regular expression/replacement/flags into a subst_expr structure */
struct subst_expr* subst_parser(str* subst)
{
#define MAX_REPLACE_WITH 100
	char c;
	char* end;
	char* p;
	char* re;
	char* re_end;
	char* repl;
	char* repl_end;
	struct replace_with rw[MAX_REPLACE_WITH];
	int rw_no;
	int escape;
	int cflags; /* regcomp flags */
	int replace_all;
	struct subst_expr* se;
	regex_t* regex;
	int max_pmatch;
	int r;
	
	/* init */
	se=0;
	regex=0;
	cflags=REG_EXTENDED  | REG_NEWLINE; /* don't match newline */
	replace_all=0;
	if (subst->len<3){
		LOG(L_ERR, "ERROR: subst_parser: expression is too short: %.*s\n",
				subst->len, subst->s);
		goto error;
	}
	
	p=subst->s;
	c=*p;
	if (c=='\\'){
		LOG(L_ERR, "ERROR: subst_parser: invalid separator char <%c>"
				" in %.*s\n", c, subst->len, subst->s);
		goto error;
	}
	p++;
	end=subst->s+subst->len;
	/* find re */
	re=p;
	for (;p<end;p++){
		/* if unescaped sep. char */
		if ((*p==c) && (*(p-1)!='\\')) goto found_re;
	}
	LOG(L_ERR, "ERROR: subst_parser: no separator found: %.*s\n", subst->len, 
			subst->s);
	goto error;
found_re:
	re_end=p;
	p++;
	/* parse replacement */
	repl=p;
	rw_no=0;
	max_pmatch=0;
	escape=0;
	for(;p<end; p++){
		if (escape){
			escape=0;
			switch (*p){
				/* special char escapes */
				case '\\':
					rw[rw_no].size=2;
					rw[rw_no].offset=(p-1)-repl;
					rw[rw_no].type=REPLACE_CHAR;
					rw[rw_no].u.c='\\';
					break;
				case 'n':
					rw[rw_no].size=2;
					rw[rw_no].offset=(p-1)-repl;
					rw[rw_no].type=REPLACE_CHAR;
					rw[rw_no].u.c='\n';
					break;
				case 'r':
					rw[rw_no].size=2;
					rw[rw_no].offset=(p-1)-repl;
					rw[rw_no].type=REPLACE_CHAR;
					rw[rw_no].u.c='\r';
					break;
				case 't':
					rw[rw_no].size=2;
					rw[rw_no].offset=(p-1)-repl;
					rw[rw_no].type=REPLACE_CHAR;
					rw[rw_no].u.c='\t';
					break;
				/* special sip msg parts escapes */
				case 'u':
					rw[rw_no].size=2;
					rw[rw_no].offset=(p-1)-repl;
					rw[rw_no].type=REPLACE_URI;
					break;
				/* re matches */
				case '0': /* allow 0, too, reference to the whole match */
				case '1':
				case '2':
				case '3':
				case '4':
				case '5':
				case '6':
				case '7':
				case '8':
				case '9':
					rw[rw_no].size=2;
					rw[rw_no].offset=(p-1)-repl;
					rw[rw_no].type=REPLACE_NMATCH;
					rw[rw_no].u.nmatch=(*p)-'0';/* 0 is the whole matched str*/
					if (max_pmatch<rw[rw_no].u.nmatch) 
						max_pmatch=rw[rw_no].u.nmatch;
					break;
				default: /* just print current char */
					if (*p!=c){
						LOG(L_WARN, "subst_parser: WARNING: \\%c unknown"
								" escape in %.*s\n", *p, subst->len, subst->s);
					}
					rw[rw_no].size=2;
					rw[rw_no].offset=(p-1)-repl;
					rw[rw_no].type=REPLACE_CHAR;
					rw[rw_no].u.c=*p;
					break;
			}
			rw_no++;
			if (rw_no>=MAX_REPLACE_WITH){
				LOG(L_ERR, "ERROR: subst_parser: too many escapes in the"
							" replace part %.*s\n", subst->len, subst->s);
				goto error;
			}
		}else if (*p=='\\') escape=1;
		else  if (*p==c) goto found_repl;
	}
	LOG(L_ERR, "ERROR: subst_parser: missing separator: %.*s\n", subst->len, 
			subst->s);
	goto error;
found_repl:
	repl_end=p;
	p++;
	/* parse flags */
	for(;p<end; p++){
		switch(*p){
			case 'i':
				cflags|=REG_ICASE;
				break;
			case 's':
				cflags&=(~REG_NEWLINE);
				break;
			case 'g':
				replace_all=1;
				break;
			default:
				LOG(L_ERR, "ERROR: subst_parser: unknown flag %c in %.*s\n",
						*p, subst->len, subst->s);
				goto error;
		}
	}

	/* compile the re */
	if ((regex=pkg_malloc(sizeof(regex_t)))==0){
		LOG(L_ERR, "ERROR: subst_parser: out of memory (re)\n");
		goto error;
	}
	c=*re_end; /* regcomp expects null terminated strings -- save */
	*re_end=0;
	if (regcomp(regex, re, cflags)!=0){
		pkg_free(regex);
		*re_end=c; /* restore */
		LOG(L_ERR, "ERROR: subst_parser: bad regular expression %.*s in "
				"%.*s\n", (int)(re_end-re), re, subst->len, subst->s);
		goto error;
	}
	*re_end=c; /* restore */
	/* construct the subst_expr structure */
	se=pkg_malloc(sizeof(struct subst_expr)+
					((rw_no)?(rw_no-1)*sizeof(struct replace_with):0));
		/* 1 replace_with structure is  already included in subst_expr */
	if (se==0){
		LOG(L_ERR, "ERROR: subst_parser: out of memory (subst_expr)\n");
		goto error;
	}
	memset((void*)se, 0, sizeof(struct subst_expr));
	se->replacement.len=repl_end-repl;
	if ((se->replacement.s=pkg_malloc(se->replacement.len))==0){
		LOG(L_ERR, "ERROR: subst_parser: out of memory (replacement)\n");
		goto error;
	}
	/* start copying */
	memcpy(se->replacement.s, repl, se->replacement.len);
	se->re=regex;
	se->replace_all=replace_all;
	se->n_escapes=rw_no;
	se->max_pmatch=max_pmatch;
	for (r=0; r<rw_no; r++) se->replace[r]=rw[r];
	DBG("subst_parser: ok, se is %p\n", se);
	return se;
	
error:
	if (se) { subst_expr_free(se); regex=0; }
	if (regex) { regfree (regex); pkg_free(regex); }
	return 0;
}
Esempio n. 5
0
/*! \brief Parse a /regular expression/replacement/flags into a subst_expr structure 
 */
struct subst_expr* subst_parser(str* subst)
{
	char c;
	char* end;
	char* p;
	char* re;
	char* re_end;
	char* repl;
	char* repl_end;
	struct replace_with rw[MAX_REPLACE_WITH];
	int rw_no;
	//int escape;
	int cflags; /* regcomp flags */
	int replace_all;
	struct subst_expr* se;
	regex_t* regex;
	int max_pmatch;
	int r;
	
	/* init */
	se=0;
	regex=0;
	cflags=REG_EXTENDED  | REG_NEWLINE; /* don't match newline */
	replace_all=0;
	if (subst->len<3){
		LM_ERR("expression is too short: %.*s\n", subst->len, subst->s);
		goto error;
	}
	
	p=subst->s;
	end=subst->s+subst->len;

	c=*p;
	if (c=='\\'){
		LM_ERR("invalid separator char <%c> in %.*s\n", c, 
				subst->len, subst->s);
		goto error;
	}
	p++;
	
	/* find re */
	re=p;
	for (;p<end;p++){
		/* if unescaped sep. char */
		if ((*p==c) && (*(p-1)!='\\')) goto found_re;
	}
	LM_ERR("no separator found: %.*s\n", subst->len, subst->s);
	goto error;
found_re:
	re_end=p;
	if(end< (p+2) ){
		LM_ERR("string too short\n");
		goto error;
	}
	repl=p+1;
	if((rw_no = parse_repl(rw, &p, end, &max_pmatch, WITH_SEP))< 0)
		goto error;
	

	repl_end=p;
	p++;
	/* parse flags */
	for(;p<end; p++){
		switch(*p){
			case 'i':
				cflags|=REG_ICASE;
				break;
			case 's':
				cflags&=(~REG_NEWLINE);
				break;
			case 'g':
				replace_all=1;
				break;
			default:
				LM_ERR("unknown flag %c in %.*s\n",	*p, subst->len, subst->s);
				goto error;
		}
	}

	/* compile the re */
	if ((regex=pkg_malloc(sizeof(regex_t)))==0){
		LM_ERR("out of pkg memory (re)\n");
		goto error;
	}
	c=*re_end; /* regcomp expects null terminated strings -- save */
	*re_end=0;
	if (regcomp(regex, re, cflags)!=0){
		pkg_free(regex);
		*re_end=c; /* restore */
		LM_ERR("bad regular expression %.*s in %.*s\n", 
				(int)(re_end-re), re, subst->len, subst->s);
		goto error;
	}
	*re_end=c; /* restore */
	/* construct the subst_expr structure */
	se=pkg_malloc(sizeof(struct subst_expr)+
					((rw_no)?(rw_no-1)*sizeof(struct replace_with):0));
		/* 1 replace_with structure is  already included in subst_expr */
	if (se==0){
		LM_ERR("out of pkg memory (subst_expr)\n");
		goto error;
	}
	memset((void*)se, 0, sizeof(struct subst_expr));

	se->replacement.len=repl_end-repl;
	if ((se->replacement.s=pkg_malloc(se->replacement.len))==0){
		LM_ERR("out of pkg memory (replacement)\n");
		goto error;
	}

	/* start copying */
	memcpy(se->replacement.s, repl, se->replacement.len);
	se->re=regex;
	se->replace_all=replace_all;
	se->n_escapes=rw_no;
	se->max_pmatch=max_pmatch;
	for (r=0; r<rw_no; r++) se->replace[r]=rw[r];
	LM_DBG("ok, se is %p\n", se);
	return se;
	
error:
	if (se) { subst_expr_free(se); regex=0; }
	if (regex) { regfree (regex); pkg_free(regex); }
	return 0;
}
Esempio n. 6
0
static int fixup_free_substre(void** param)
{
	subst_expr_free(*param);
	return 0;
}