Module: sip-router
Branch: andrei/to_parser_fix
Commit: ac7dd1cc97757e60d3d8e0b52767e89e2caa61be
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=ac7dd1c…
Author: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Date: Thu May 28 20:38:37 2009 +0200
core: to parser fix
- parse parameters without value in To/From headers (e.g.:
To: <sip:nils@invalid.com>;foo or
To: <sip:nils@invalid.com>;foo= ). Parameters with an empty
value ('=' followed by nothing) will have their value field
pointing to en empty string (len==0, but s non-null), while
parameters without a value (no '=') will point to a null
string (len==0, s==0).
- better handling of parameters at the end of the string
Reported-and-tested-by: Nils Ohlmeier <nils(a)iptel.org>
---
parser/parse_to.c | 68 +++++++++++++++++++++++++++++++++++++---------------
1 files changed, 48 insertions(+), 20 deletions(-)
diff --git a/parser/parse_to.c b/parser/parse_to.c
index a493820..a8f3883 100644
--- a/parser/parse_to.c
+++ b/parser/parse_to.c
@@ -188,16 +188,17 @@ static /*inline*/ char* parse_to_param(char *buffer, char *end,
case 0:
switch (status)
{
-#ifndef NO_PINGTEL_TAG_HACK
case TAG3:
param->type = TAG_PARAM;
- param->name.len = 3;
+ case PARA_NAME:
+ case TAG1:
+ case TAG2:
+ param->name.len = tmp-param->name.s;
status = S_EQUAL;
case S_EQUAL:
case S_PARA_VALUE:
saved_status=status;
goto endofheader;
-#endif
case PARA_VALUE_TOKEN:
status = E_PARA_VALUE;
param->value.len = tmp-param->value.s;
@@ -261,23 +262,21 @@ static /*inline*/ char* parse_to_param(char *buffer, char *end,
{
case PARA_VALUE_QUOTED:
break;
-#ifndef NO_PINGTEL_TAG_HACK
case TAG3:
param->type = TAG_PARAM;
- param->name.len = 3;
+ case PARA_NAME:
+ case TAG1:
+ case TAG2:
+ param->name.len = tmp-param->name.s;
case S_EQUAL:
+ param->value.s = 0;
+ param->value.len = 0;
+ goto semicolon_add_param;
case S_PARA_VALUE:
- if (param->type==TAG_PARAM)
- param->value.s = tmp;
- else {
- LOG( L_ERR , "ERROR: parse_to_param : unexpected "
- "char [%c] in status %d: <<%.*s>> .\n",
- *tmp,status, (int)(tmp-buffer), ZSW(buffer));
- goto error;
- }
-#endif
+ param->value.s = tmp;
case PARA_VALUE_TOKEN:
param->value.len=tmp-param->value.s;
+semicolon_add_param:
add_param(param,to_b);
case E_PARA_VALUE:
param = (struct to_param*)
@@ -466,18 +465,47 @@ static /*inline*/ char* parse_to_param(char *buffer, char *end,
}
}/*switch*/
}/*for*/
+ if (!(status==F_CR || status==F_LF || status==F_CRLF))
+ saved_status=status;
endofheader:
-#ifndef NO_PINGTEL_TAG_HACK
- if (param->type==TAG_PARAM
- && (saved_status==S_EQUAL||saved_status==S_PARA_VALUE) ) {
- saved_status = E_PARA_VALUE;
- param->value.s= 0;
+ switch(saved_status){
+ case TAG3:
+ param->type = TAG_PARAM; /* tag at the end */
+ /* no break */
+ case PARA_NAME:
+ case TAG1:
+ case TAG2:
+ param->name.len = tmp-param->name.s;
+ /* no break */
+ case S_EQUAL:
+ /* parameter without '=', e.g. foo */
+ param->value.s=0;
param->value.len=0;
add_param(param, to_b);
+ saved_status=E_PARA_VALUE;
+ break;
+ case S_PARA_VALUE:
+ /* parameter with null value, e.g. foo= */
+ param->value.s=tmp;
+ param->value.len=0;
+ add_param(param, to_b);
+ saved_status=E_PARA_VALUE;
+ break;
+ case PARA_VALUE_TOKEN:
+ param->value.len=tmp-param->value.s;
+ add_param(param, to_b);
+ saved_status=E_PARA_VALUE;
+ break;
+ case E_PARA_VALUE:
+ break;
+ default:
+ LOG( L_ERR , "ERROR: parse_to_param : unexpected end of header,"
+ " status %d: <<%.*s>> .\n",
+ saved_status, (int)(tmp-buffer), ZSW(buffer));
+ goto error;
}
-#endif
*returned_status=saved_status;
return tmp;