osip_message_parse.c (libosip2-5.1.0) | : | osip_message_parse.c (libosip2-5.1.1) | ||
---|---|---|---|---|
/* | /* | |||
The oSIP library implements the Session Initiation Protocol (SIP -rfc3261-) | The oSIP library implements the Session Initiation Protocol (SIP -rfc3261-) | |||
Copyright (C) 2001-2015 Aymeric MOIZARD amoizard@antisip.com | Copyright (C) 2001-2020 Aymeric MOIZARD amoizard@antisip.com | |||
This library is free software; you can redistribute it and/or | This library is free software; you can redistribute it and/or | |||
modify it under the terms of the GNU Lesser General Public | modify it under the terms of the GNU Lesser General Public | |||
License as published by the Free Software Foundation; either | License as published by the Free Software Foundation; either | |||
version 2.1 of the License, or (at your option) any later version. | version 2.1 of the License, or (at your option) any later version. | |||
This library is distributed in the hope that it will be useful, | This library is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
Lesser General Public License for more details. | Lesser General Public License for more details. | |||
skipping to change at line 167 | skipping to change at line 167 | |||
osip_free (dest->sip_method); | osip_free (dest->sip_method); | |||
dest->sip_method = NULL; | dest->sip_method = NULL; | |||
osip_uri_free (dest->req_uri); | osip_uri_free (dest->req_uri); | |||
dest->req_uri = NULL; | dest->req_uri = NULL; | |||
return OSIP_NOMEM; | return OSIP_NOMEM; | |||
} | } | |||
osip_strncpy (dest->sip_version, p1 + 1, (hp - p1 - 1)); | osip_strncpy (dest->sip_version, p1 + 1, (hp - p1 - 1)); | |||
if (0 != osip_strcasecmp (dest->sip_version, "SIP/2.0")) { | if (0 != osip_strcasecmp (dest->sip_version, "SIP/2.0")) { | |||
OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Wrong versi on number\n")); | OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_WARNING, NULL, "Wrong ver sion number\n")); | |||
} | } | |||
hp++; | hp++; | |||
if ((*hp) && ('\r' == hp[-1]) && ('\n' == hp[0])) | if ((*hp) && ('\r' == hp[-1]) && ('\n' == hp[0])) | |||
hp++; | hp++; | |||
(*headers) = hp; | (*headers) = hp; | |||
} | } | |||
return OSIP_SUCCESS; | return OSIP_SUCCESS; | |||
} | } | |||
skipping to change at line 192 | skipping to change at line 192 | |||
const char *reasonphrase; | const char *reasonphrase; | |||
dest->req_uri = NULL; | dest->req_uri = NULL; | |||
dest->sip_method = NULL; | dest->sip_method = NULL; | |||
*headers = buf; | *headers = buf; | |||
statuscode = strchr (buf, ' '); /* search for first SPACE */ | statuscode = strchr (buf, ' '); /* search for first SPACE */ | |||
if (statuscode == NULL) | if (statuscode == NULL) | |||
return OSIP_SYNTAXERROR; | return OSIP_SYNTAXERROR; | |||
if (statuscode - (*headers) < 7) /* must be at least "SIP" "/" 1*DIGIT " | ||||
." 1*DIGIT */ | ||||
return OSIP_SYNTAXERROR; | ||||
dest->sip_version = (char *) osip_malloc (statuscode - (*headers) + 1); | dest->sip_version = (char *) osip_malloc (statuscode - (*headers) + 1); | |||
if (dest->sip_version == NULL) | if (dest->sip_version == NULL) | |||
return OSIP_NOMEM; | return OSIP_NOMEM; | |||
osip_strncpy (dest->sip_version, *headers, statuscode - (*headers)); | osip_strncpy (dest->sip_version, *headers, statuscode - (*headers)); | |||
reasonphrase = strchr (statuscode + 1, ' '); | reasonphrase = strchr (statuscode + 1, ' '); | |||
if (reasonphrase == NULL) { | if (reasonphrase == NULL) { | |||
osip_free (dest->sip_version); | osip_free (dest->sip_version); | |||
dest->sip_version = NULL; | dest->sip_version = NULL; | |||
return OSIP_SYNTAXERROR; | return OSIP_SYNTAXERROR; | |||
skipping to change at line 254 | skipping to change at line 256 | |||
if (0 == strncmp ((const char *) buf, (const char *) "SIP/", 4)) | if (0 == strncmp ((const char *) buf, (const char *) "SIP/", 4)) | |||
return __osip_message_startline_parseresp (dest, buf, headers); | return __osip_message_startline_parseresp (dest, buf, headers); | |||
else | else | |||
return __osip_message_startline_parsereq (dest, buf, headers); | return __osip_message_startline_parsereq (dest, buf, headers); | |||
} | } | |||
int | int | |||
__osip_find_next_occurence (const char *str, const char *buf, const char **index _of_str, const char *end_of_buf) | __osip_find_next_occurence (const char *str, const char *buf, const char **index _of_str, const char *end_of_buf) | |||
{ | { | |||
int i; | size_t slen; | |||
*index_of_str = NULL; /* AMD fix */ | *index_of_str = NULL; /* AMD fix */ | |||
if ((NULL == str) || (NULL == buf)) | if (str == NULL || buf == NULL) | |||
return OSIP_BADPARAMETER; | return OSIP_BADPARAMETER; | |||
/* TODO? we may prefer strcasestr instead of strstr? // TODO? with large binar | ||||
y, it will break at 10000 loop with a syntax error */ | slen = strlen (str); | |||
for (i = 0; i < 10000; i++) { | while (slen < (size_t) (end_of_buf - buf)) { | |||
*index_of_str = strstr (buf, str); | if (!memcmp (str, buf, slen)) { | |||
if (NULL == (*index_of_str)) { | *index_of_str = buf; | |||
/* if '\0' (when binary data is used) is located before the separator, | return OSIP_SUCCESS; | |||
then we have to continue searching */ | ||||
const char *ptr = buf + strlen (buf); | ||||
if (end_of_buf - ptr > 0) { | ||||
buf = ptr + 1; | ||||
continue; | ||||
} | ||||
return OSIP_SYNTAXERROR; | ||||
} | } | |||
return OSIP_SUCCESS; | ++buf; | |||
} | } | |||
OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_BUG, NULL, "This was probably an infinite loop?\n")); | ||||
return OSIP_SYNTAXERROR; | return OSIP_SYNTAXERROR; | |||
} | } | |||
/* This method replace all LWS with SP located before the | /* This method replace all LWS with SP located before the | |||
initial CRLFCRLF found or the end of the string. | initial CRLFCRLF found or the end of the string. | |||
*/ | */ | |||
static void | static void | |||
osip_util_replace_all_lws (char *sip_message) | osip_util_replace_all_lws (char *sip_message) | |||
{ | { | |||
/* const char *end_of_message; */ | /* const char *end_of_message; */ | |||
skipping to change at line 319 | skipping to change at line 313 | |||
|| (('\n' == tmp[0]) && ((' ' == tmp[1]) || ('\t' == tmp[1])))) { | || (('\n' == tmp[0]) && ((' ' == tmp[1]) || ('\t' == tmp[1])))) { | |||
/* replace line end and TAB symbols by SP */ | /* replace line end and TAB symbols by SP */ | |||
tmp[0] = ' '; | tmp[0] = ' '; | |||
tmp[1] = ' '; | tmp[1] = ' '; | |||
tmp = tmp + 2; | tmp = tmp + 2; | |||
/* replace all following TAB symbols */ | /* replace all following TAB symbols */ | |||
for (; ('\t' == tmp[0] || ' ' == tmp[0]);) { | for (; ('\t' == tmp[0] || ' ' == tmp[0]);) { | |||
tmp[0] = ' '; | tmp[0] = ' '; | |||
tmp++; | tmp++; | |||
} | } | |||
if (tmp[0] == '\0') /* fixed Janv 13 2020: Heap-buffer-overflow with | ||||
a final LWS without nothing after */ | ||||
return; | ||||
} | } | |||
} | } | |||
} | } | |||
int | int | |||
__osip_find_next_crlf (const char *start_of_header, const char **end_of_header) | __osip_find_next_crlf (const char *start_of_header, const char **end_of_header) | |||
{ | { | |||
const char *soh = start_of_header; | const char *soh = start_of_header; | |||
*end_of_header = NULL; /* AMD fix */ | *end_of_header = NULL; /* AMD fix */ | |||
skipping to change at line 499 | skipping to change at line 495 | |||
if (!inquotes) { | if (!inquotes) { | |||
if (inuri) | if (inuri) | |||
inuri = 0; | inuri = 0; | |||
} | } | |||
break; | break; | |||
case '\0': | case '\0': | |||
/* we discard any validation we tried: no valid uri detected */ | /* we discard any validation we tried: no valid uri detected */ | |||
inquotes = 0; | inquotes = 0; | |||
inuri = 0; | inuri = 0; | |||
// (keep next comment to avoid fall through warning) | ||||
// fall through | ||||
case ',': | case ',': | |||
if (!inquotes && !inuri) { | if (!inquotes && !inuri) { | |||
char *avalue; | char *avalue; | |||
if (beg[0] == '\0') | if (beg[0] == '\0') | |||
return OSIP_SUCCESS; /* empty header */ | return OSIP_SUCCESS; /* empty header */ | |||
end = ptr; | end = ptr; | |||
if (end - beg + 1 < 2) { | if (end - beg + 1 < 2) { | |||
beg = end + 1; | beg = end + 1; | |||
End of changes. 10 change blocks. | ||||
20 lines changed or deleted | 19 lines changed or added |