Skip to content

Commit

Permalink
Refactor generic parse_to() to accept multi-value headers.
Browse files Browse the repository at this point in the history
New function parse_multi_to() added to allow parsing of multi-value (comma separated) name-addr/addr-spec headers (like Diversion, PAI, PPI).
Changes are backward compatible in regards to original parse_to() function.

(cherry picked from commit a7e724a)
  • Loading branch information
bogdan-iancu committed Dec 19, 2017
1 parent 781e1b3 commit 25c3056
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 9 deletions.
82 changes: 73 additions & 9 deletions parser/parse_to.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,18 @@ void free_to_params(struct to_body* tb)

void free_to(struct to_body* tb)
{
free_to_params(tb);
pkg_free(tb);
if (tb) {
free_to( tb->next );
free_to_params(tb);
pkg_free(tb);
}
}


static inline char* parse_to_param(char *buffer, char *end,
struct to_body *to_b,
int *returned_status)
int *returned_status,
int multi)
{
struct to_param *param;
int status;
Expand Down Expand Up @@ -197,7 +201,8 @@ static inline char* parse_to_param(char *buffer, char *end,
goto parse_error;
}
break;
case 0:
case 0:
case ',':
switch (status)
{
case PARA_NAME:
Expand All @@ -213,6 +218,8 @@ static inline char* parse_to_param(char *buffer, char *end,
add_param( param , to_b );
case E_PARA_VALUE:
saved_status = status;
if ( !multi && *tmp==',')
goto parse_error;
goto endofheader;
break;
default:
Expand Down Expand Up @@ -475,12 +482,14 @@ static inline char* parse_to_param(char *buffer, char *end,



char* parse_to(char* buffer, char *end, struct to_body *to_b)
static inline char* _parse_to(char* buffer, char *end, struct to_body *to_b,
int multi)
{
int status;
int saved_status;
char *tmp;
char *end_mark;
struct to_body *first_b = to_b;

status=START_TO;
saved_status=START_TO;
Expand All @@ -490,6 +499,7 @@ char* parse_to(char* buffer, char *end, struct to_body *to_b)

for( tmp=buffer; tmp<end; tmp++)
{
LM_DBG("handling char <%c> pos %d in state %d\n",*tmp,(int)(tmp-buffer),status);
switch(*tmp)
{
case ' ':
Expand Down Expand Up @@ -577,6 +587,31 @@ char* parse_to(char* buffer, char *end, struct to_body *to_b)
goto parse_error;
}
break;
case ',':
switch (status)
{
case URI_OR_TOKEN:
case MAYBE_URI_END:
to_b->uri.len = tmp - to_b->uri.s;
case END:
if (multi==0)
goto parse_error;
to_b->next = (struct to_body*)
pkg_malloc(sizeof(struct to_body));
if (to_b->next==NULL) {
LM_ERR("failed to allocate new TO body\n");
goto error;
}
to_b = to_b->next;
memset(to_b, 0, sizeof(struct to_body));
to_b->error = PARSE_OK;
saved_status = status = START_TO;
end_mark=0;
break;
default:
goto parse_error;
}
break;
case '\\':
switch (status)
{
Expand Down Expand Up @@ -669,8 +704,24 @@ char* parse_to(char* buffer, char *end, struct to_body *to_b)
to_b->uri.len = end_mark - to_b->uri.s;
case END:
to_b->body.len = tmp-to_b->body.s;
tmp = parse_to_param(tmp,end,to_b,&saved_status);
goto endofheader;
tmp = parse_to_param(tmp,end,to_b,&saved_status,multi);
if (to_b->error!=PARSE_ERROR && multi && *tmp==',') {
/* continue with a new body instance */
to_b->next = (struct to_body*)
pkg_malloc(sizeof(struct to_body));
if (to_b->next==NULL) {
LM_ERR("failed to allocate new TO body\n");
goto error;
}
to_b = to_b->next;
memset(to_b, 0, sizeof(struct to_body));
to_b->error=PARSE_OK;
saved_status = status = START_TO;
end_mark=0;
break;
} else {
goto endofheader;
}
case F_CRLF:
case F_LF:
case F_CR:
Expand Down Expand Up @@ -739,13 +790,26 @@ char* parse_to(char* buffer, char *end, struct to_body *to_b)
LM_ERR("unexpected char [%c] in status %d: <<%.*s>> .\n",
*tmp,status, (int)(tmp-buffer), buffer);
error:
to_b->error=PARSE_ERROR;
free_to_params(to_b);
first_b->error=PARSE_ERROR;
free_to_params(first_b);
free_to(first_b->next);
return tmp;

}


char* parse_to(char* buffer, char *end, struct to_body *to_b)
{
return _parse_to( buffer, end, to_b, 0/*multi*/);
}


char* parse_multi_to(char* buffer, char *end, struct to_body *to_b)
{
return _parse_to( buffer, end, to_b, 1/*multi*/);
}


/**
*
*/
Expand Down
3 changes: 3 additions & 0 deletions parser/parse_to.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ struct to_body{
struct sip_uri parsed_uri; /* Parsed URI */
struct to_param *param_lst; /* Linked list of parameters */
struct to_param *last_param; /* Last parameter in the list */
struct to_body *next; /* Next body if multi-instance header */
};


Expand All @@ -66,4 +67,6 @@ void free_to(struct to_body* tb);

void free_to_params(struct to_body *tb);

char* parse_multi_to(char* buffer, char *end, struct to_body *to_b);

#endif

0 comments on commit 25c3056

Please sign in to comment.