/* rpl.s will be alloc'ed with the proper size & rpl.len set * returns 0 on success, <0 on error*/ static int replace_build(char* match, int nmatch, regmatch_t* pmatch, struct subst_expr* se, struct sip_msg* msg, str* rpl) { int r; str* uri; char* p; char* dest; char* end; int size; rpl->len=replace_len(match, nmatch, pmatch, se, msg); if (rpl->len==0){ rpl->s=0; /* emtpy string */ return 0; } rpl->s=pkg_malloc(rpl->len); if (rpl->s==0){ LOG(L_ERR, "ERROR: replace_build: out of mem (rpl)\n"); goto error; } p=se->replacement.s; end=p+se->replacement.len; dest=rpl->s; for (r=0; r<se->n_escapes; r++){ /* copy the unescaped parts */ size=se->replacement.s+se->replace[r].offset-p; memcpy(dest, p, size); p+=size+se->replace[r].size; dest+=size; switch(se->replace[r].type){ case REPLACE_NMATCH: if ((se->replace[r].u.nmatch<nmatch)&&( pmatch[se->replace[r].u.nmatch].rm_so!=-1)){ /* do the replace */ size=pmatch[se->replace[r].u.nmatch].rm_eo- pmatch[se->replace[r].u.nmatch].rm_so; memcpy(dest, match+pmatch[se->replace[r].u.nmatch].rm_so, size); dest+=size; }; break; case REPLACE_CHAR: *dest=se->replace[r].u.c; dest++; break; case REPLACE_URI: if (msg->first_line.type!=SIP_REQUEST){ LOG(L_CRIT, "BUG: replace_build: uri substitution on" " a reply\n"); break; /* ignore, we can continue */ } uri= (msg->new_uri.s)?(&msg->new_uri): (&msg->first_line.u.request.uri); memcpy(dest, uri->s, uri->len); dest+=uri->len; break; default: LOG(L_CRIT, "BUG: replace_build: unknown type %d\n", se->replace[r].type); /* ignore it */ } } memcpy(dest, p, end-p); return 0; error: return -1; }
/*! \brief Replies will be allocated with the proper size & rpl.len set * \return 0 on success, <0 on error */ static int replace_build(const char* match, int nmatch, regmatch_t* pmatch, struct subst_expr* se, struct sip_msg* msg, str* rpl) { int r; str* uri; pv_value_t sv; char* p; char* dest; char* end; int size; #define REPLACE_BUFFER_SIZE 1024 static char rbuf[REPLACE_BUFFER_SIZE]; #if 0 /* use static bufer now since we cannot easily get the length */ rpl->len=replace_len(match, nmatch, pmatch, se, msg); if (rpl->len==0){ rpl->s=0; /* empty string */ return 0; } rpl->s=pkg_malloc(rpl->len); if (rpl->s==0){ LM_ERR("out of pkg mem (rpl)\n"); goto error; } #endif p=se->replacement.s; end=p+se->replacement.len; dest=rbuf; for (r=0; r<se->n_escapes; r++){ /* copy the unescaped parts */ size=se->replacement.s+se->replace[r].offset-p; if(dest-rbuf+size>=REPLACE_BUFFER_SIZE-1){ LM_ERR("overflow\n"); goto error; } memcpy(dest, p, size); p+=size+se->replace[r].size; dest+=size; switch(se->replace[r].type){ case REPLACE_NMATCH: if ((se->replace[r].u.nmatch<nmatch)&&( pmatch[se->replace[r].u.nmatch].rm_so!=-1)){ /* do the replace */ size=pmatch[se->replace[r].u.nmatch].rm_eo- pmatch[se->replace[r].u.nmatch].rm_so; if(dest-rbuf+size>=REPLACE_BUFFER_SIZE-1){ LM_ERR("overflow\n"); goto error; } memcpy(dest, match+pmatch[se->replace[r].u.nmatch].rm_so, size); dest+=size; }; break; case REPLACE_CHAR: if(dest-rbuf+1>=REPLACE_BUFFER_SIZE-1){ LM_ERR("overflow\n"); goto error; } *dest=se->replace[r].u.c; dest++; break; case REPLACE_URI: if (msg->first_line.type!=SIP_REQUEST){ LM_CRIT("uri substitution on a reply\n"); break; /* ignore, we can continue */ } uri= (msg->new_uri.s)?(&msg->new_uri): (&msg->first_line.u.request.uri); if(dest-rbuf+uri->len>=REPLACE_BUFFER_SIZE-1){ LM_ERR("overflow\n"); goto error; } memcpy(dest, uri->s, uri->len); dest+=uri->len; break; case REPLACE_SPEC: if(pv_get_spec_value(msg, &se->replace[r].u.spec, &sv)!=0) { LM_CRIT("item substitution returned error\n"); break; /* ignore, we can continue */ } if(dest-rbuf+sv.rs.len>=REPLACE_BUFFER_SIZE-1){ LM_ERR("overflow\n"); goto error; } memcpy(dest, sv.rs.s, sv.rs.len); dest+=sv.rs.len; break; default: LM_CRIT("unknown type %d\n", se->replace[r].type); /* ignore it */ } } memcpy(dest, p, end-p); rpl->len = (dest-rbuf)+(end-p); rpl->s=pkg_malloc(rpl->len); if (rpl->s==0){ LM_ERR("out of pkg mem (rpl)\n"); goto error; } memcpy(rpl->s, rbuf, rpl->len); return 0; error: return -1; }