From 2e7f6cd31b8edafa7d3508a370ac6eb05ea7bf8a Mon Sep 17 00:00:00 2001 From: Ben Ford Date: Mon, 13 Nov 2017 14:35:14 -0600 Subject: bundled_pjproject: Update to 2.7.1 Update from 2.7 to 2.7.1 for bundled pjproject. Changed version and removed patch files included in the update. Change-Id: I55cea8e734b318c2df9daf86aa0802c559ec8357 --- ...ackport-ICE-Use-STUN-FINGERPRINT-attribut.patch | 41 - ...Add-validity-checking-for-numeric-header-.patch | 973 --------------------- third-party/versions.mak | 2 +- 3 files changed, 1 insertion(+), 1015 deletions(-) delete mode 100644 third-party/pjproject/patches/0010-r5665-svn-backport-ICE-Use-STUN-FINGERPRINT-attribut.patch delete mode 100644 third-party/pjproject/patches/0020-sip_parser-Add-validity-checking-for-numeric-header-.patch (limited to 'third-party') diff --git a/third-party/pjproject/patches/0010-r5665-svn-backport-ICE-Use-STUN-FINGERPRINT-attribut.patch b/third-party/pjproject/patches/0010-r5665-svn-backport-ICE-Use-STUN-FINGERPRINT-attribut.patch deleted file mode 100644 index 3c83cc502..000000000 --- a/third-party/pjproject/patches/0010-r5665-svn-backport-ICE-Use-STUN-FINGERPRINT-attribut.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 06bc834969a34d2c60e05beed3051b4a6d34c125 Mon Sep 17 00:00:00 2001 -From: Richard Mudgett -Date: Thu, 28 Sep 2017 10:57:23 -0500 -Subject: [PATCH 3/3] r5665 svn backport ICE: Use STUN FINGERPRINT attribute - when sending keepalives - -Fixed #2046: ICE: Use STUN FINGERPRINT attribute when sending keepalives - -Per RFC 5245 Section 10: - - If STUN is being used for keepalives, a STUN Binding Indication is - used [RFC5389]. The Indication MUST NOT utilize any authentication - mechanism. It SHOULD contain the FINGERPRINT attribute to aid in - demultiplexing, but SHOULD NOT contain any other attributes. ---- - pjnath/src/pjnath/ice_session.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/pjnath/src/pjnath/ice_session.c b/pjnath/src/pjnath/ice_session.c -index 27a2950..63a0d1c 100644 ---- a/pjnath/src/pjnath/ice_session.c -+++ b/pjnath/src/pjnath/ice_session.c -@@ -1217,10 +1217,12 @@ static void ice_keep_alive(pj_ice_sess *ice, pj_bool_t send_now) - msg_data = PJ_POOL_ZALLOC_T(tdata->pool, pj_ice_msg_data); - msg_data->transport_id = the_check->lcand->transport_id; - -- /* Temporarily disable FINGERPRINT. The Binding Indication -- * SHOULD NOT contain any attributes. -+ /* RFC 5245 Section 10: -+ * The Binding Indication SHOULD contain the FINGERPRINT attribute -+ * to aid in demultiplexing, but SHOULD NOT contain any other -+ * attributes. - */ -- saved = pj_stun_session_use_fingerprint(comp->stun_sess, PJ_FALSE); -+ saved = pj_stun_session_use_fingerprint(comp->stun_sess, PJ_TRUE); - - /* Send to session */ - addr_len = pj_sockaddr_get_len(&the_check->rcand->addr); --- -2.7.4 - diff --git a/third-party/pjproject/patches/0020-sip_parser-Add-validity-checking-for-numeric-header-.patch b/third-party/pjproject/patches/0020-sip_parser-Add-validity-checking-for-numeric-header-.patch deleted file mode 100644 index dfee4b2c2..000000000 --- a/third-party/pjproject/patches/0020-sip_parser-Add-validity-checking-for-numeric-header-.patch +++ /dev/null @@ -1,973 +0,0 @@ -From b21042956dc4d3526052d5030953e5c565bb0895 Mon Sep 17 00:00:00 2001 -From: George Joseph -Date: Thu, 2 Nov 2017 08:23:00 -0600 -Subject: [PATCH] sip_parser: Add validity checking for numeric header values - -Parsing the numeric header fields like cseq, ttl, port, etc. all -had the potential to overflow, either causing unintended values to -be captured or, if the values were subsequently converted back to -strings, a buffer overrun. To address this, new "strto" functions -have been created that do range checking and those functions are -used wherever possible in the parser. - - * Created pjlib/include/limits.h and pjlib/include/compat/limits.h - to either include the system limits.h or define common numeric - limits if there is no system limits.h. - - * Created strto*_validate functions in sip_parser that take bounds - and on failure call the on_str_parse_error function which prints - an error message and calls PJ_THROW. - - * Updated sip_parser to validate the numeric fields. - - * Fixed an issue in sip_transport that prevented error messages - from being properly displayed. - - * Added "volatile" to some variables referenced in PJ_CATCH blocks - as the optimizer was sometimes optimizing them away. - - * Fixed length calculation in sip_transaction/create_tsx_key_2543 - to account for signed ints being 11 characters, not 9. - -Reported by: Youngsung Kim at LINE Corporation ---- - pjlib/build/pjlib.vcproj | 14 +++- - pjlib/build/pjlib.vcxproj | 4 +- - pjlib/build/pjlib.vcxproj.filters | 6 ++ - pjlib/include/pj/compat/limits.h | 65 +++++++++++++++ - pjlib/include/pj/compat/os_win32.h | 1 + - pjlib/include/pj/limits.h | 51 ++++++++++++ - pjlib/include/pj/string.h | 46 +++++++++- - pjlib/include/pj/types.h | 3 - - pjlib/src/pj/string.c | 119 +++++++++++++++++++++++++- - pjlib/src/pj/timer.c | 1 + - pjsip/include/pjsip/sip_parser.h | 25 ++++++ - pjsip/src/pjsip/sip_parser.c | 166 +++++++++++++++++++++++++++++-------- - pjsip/src/pjsip/sip_transaction.c | 4 +- - pjsip/src/pjsip/sip_transport.c | 7 +- - 14 files changed, 463 insertions(+), 49 deletions(-) - create mode 100644 pjlib/include/pj/compat/limits.h - create mode 100644 pjlib/include/pj/limits.h - -diff --git a/pjlib/build/pjlib.vcproj b/pjlib/build/pjlib.vcproj -index 6a217a0b7..12592ef94 100644 ---- a/pjlib/build/pjlib.vcproj -+++ b/pjlib/build/pjlib.vcproj -@@ -14967,7 +14967,11 @@ - - -+ > -+ -+ - - - -- -+ > -+ -+ -+ - -diff --git a/pjlib/build/pjlib.vcxproj b/pjlib/build/pjlib.vcxproj -index abf09ec44..e41731e3c 100644 ---- a/pjlib/build/pjlib.vcxproj -+++ b/pjlib/build/pjlib.vcxproj -@@ -494,7 +494,7 @@ - true - true - -- -+ - - - true -@@ -890,6 +890,7 @@ - - - -+ - - - -@@ -925,6 +926,7 @@ - - - -+ - - - -diff --git a/pjlib/build/pjlib.vcxproj.filters b/pjlib/build/pjlib.vcxproj.filters -index 0b5cbf109..6f343b019 100644 ---- a/pjlib/build/pjlib.vcxproj.filters -+++ b/pjlib/build/pjlib.vcxproj.filters -@@ -439,5 +439,11 @@ - - Header Files\compat - -+ -+ Header Files -+ -+ -+ Header Files\compat -+ - - -\ No newline at end of file -diff --git a/pjlib/include/pj/compat/limits.h b/pjlib/include/pj/compat/limits.h -new file mode 100644 -index 000000000..fba0625df ---- /dev/null -+++ b/pjlib/include/pj/compat/limits.h -@@ -0,0 +1,65 @@ -+/* $Id$ */ -+/* -+ * Copyright (C) 2017 Teluu Inc. (http://www.teluu.com) -+ * Copyright (C) 2017 George Joseph -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ */ -+#ifndef __PJ_COMPAT_LIMITS_H__ -+#define __PJ_COMPAT_LIMITS_H__ -+ -+/** -+ * @file limits.h -+ * @brief Provides integer limits normally found in limits.h. -+ */ -+ -+#if defined(PJ_HAS_LIMITS_H) && PJ_HAS_LIMITS_H != 0 -+# include -+#else -+ -+# ifdef _MSC_VER -+# pragma message("limits.h is not found or not supported. LONG_MIN and "\ -+ "LONG_MAX will be defined by the library in "\ -+ "pj/compats/limits.h and overridable in config_site.h") -+# else -+# warning "limits.h is not found or not supported. LONG_MIN and LONG_MAX " \ -+ "will be defined by the library in pj/compats/limits.h and "\ -+ "overridable in config_site.h" -+# endif -+ -+/* Minimum and maximum values a `signed long int' can hold. */ -+# ifndef LONG_MAX -+# if __WORDSIZE == 64 -+# define LONG_MAX 9223372036854775807L -+# else -+# define LONG_MAX 2147483647L -+# endif -+# endif -+ -+# ifndef LONG_MIN -+# define LONG_MIN (-LONG_MAX - 1L) -+# endif -+ -+/* Maximum value an `unsigned long int' can hold. (Minimum is 0.) */ -+# ifndef ULONG_MAX -+# if __WORDSIZE == 64 -+# define ULONG_MAX 18446744073709551615UL -+# else -+# define ULONG_MAX 4294967295UL -+# endif -+# endif -+#endif -+ -+#endif /* __PJ_COMPAT_LIMITS_H__ */ -diff --git a/pjlib/include/pj/compat/os_win32.h b/pjlib/include/pj/compat/os_win32.h -index 4fa8b21ea..9b18e4eb1 100644 ---- a/pjlib/include/pj/compat/os_win32.h -+++ b/pjlib/include/pj/compat/os_win32.h -@@ -57,6 +57,7 @@ - #define PJ_HAS_SYS_TYPES_H 1 - #define PJ_HAS_TIME_H 1 - #define PJ_HAS_UNISTD_H 0 -+#define PJ_HAS_LIMITS_H 1 - - #define PJ_HAS_MSWSOCK_H 1 - #define PJ_HAS_WINSOCK_H 0 -diff --git a/pjlib/include/pj/limits.h b/pjlib/include/pj/limits.h -new file mode 100644 -index 000000000..8b00ae52a ---- /dev/null -+++ b/pjlib/include/pj/limits.h -@@ -0,0 +1,51 @@ -+/* $Id$ */ -+/* -+ * Copyright (C) 2017 Teluu Inc. (http://www.teluu.com) -+ * Copyright (C) 2017 George Joseph -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ */ -+#ifndef __PJ_LIMITS_H__ -+#define __PJ_LIMITS_H__ -+ -+/** -+ * @file limits.h -+ * @brief Common min and max values -+ */ -+ -+#include -+ -+/** Maximum value for signed 32-bit integer. */ -+#define PJ_MAXINT32 0x7fffffff -+ -+/** Minimum value for signed 32-bit integer. */ -+#define PJ_MININT32 0x80000000 -+ -+/** Maximum value for unsigned 16-bit integer. */ -+#define PJ_MAXUINT16 0xffff -+ -+/** Maximum value for unsigned char. */ -+#define PJ_MAXUINT8 0xff -+ -+/** Maximum value for long. */ -+#define PJ_MAXLONG LONG_MAX -+ -+/** Minimum value for long. */ -+#define PJ_MINLONG LONG_MIN -+ -+/** Minimum value for unsigned long. */ -+#define PJ_MAXULONG ULONG_MAX -+ -+#endif /* __PJ_LIMITS_H__ */ -diff --git a/pjlib/include/pj/string.h b/pjlib/include/pj/string.h -index 70a1d6c8c..5de236a65 100644 ---- a/pjlib/include/pj/string.h -+++ b/pjlib/include/pj/string.h -@@ -28,7 +28,6 @@ - #include - #include - -- - PJ_BEGIN_DECL - - /** -@@ -636,6 +635,29 @@ PJ_DECL(char*) pj_create_random_string(char *str, pj_size_t length); - PJ_DECL(long) pj_strtol(const pj_str_t *str); - - /** -+ * Convert string to signed long integer. The conversion will stop as -+ * soon as non-digit character is found or all the characters have -+ * been processed. -+ * -+ * @param str the string. -+ * @param value Pointer to a long to receive the value. -+ * -+ * @return PJ_SUCCESS if successful. Otherwise: -+ * PJ_ETOOSMALL if the value was an impossibly long negative number. -+ * In this case *value will be set to LONG_MIN. -+ * \n -+ * PJ_ETOOBIG if the value was an impossibly long positive number. -+ * In this case, *value will be set to LONG_MAX. -+ * \n -+ * PJ_EINVAL if the input string was NULL, the value pointer was NULL -+ * or the input string could not be parsed at all such as starting with -+ * a character other than a '+', '-' or not in the '0' - '9' range. -+ * In this case, *value will be left untouched. -+ */ -+PJ_DECL(pj_status_t) pj_strtol2(const pj_str_t *str, long *value); -+ -+ -+/** - * Convert string to unsigned integer. The conversion will stop as - * soon as non-digit character is found or all the characters have - * been processed. -@@ -664,6 +686,27 @@ PJ_DECL(unsigned long) pj_strtoul2(const pj_str_t *str, pj_str_t *endptr, - unsigned base); - - /** -+ * Convert string to unsigned long integer. The conversion will stop as -+ * soon as non-digit character is found or all the characters have -+ * been processed. -+ * -+ * @param str The input string. -+ * @param value Pointer to an unsigned long to receive the value. -+ * @param base Number base to use. -+ * -+ * @return PJ_SUCCESS if successful. Otherwise: -+ * PJ_ETOOBIG if the value was an impossibly long positive number. -+ * In this case, *value will be set to ULONG_MAX. -+ * \n -+ * PJ_EINVAL if the input string was NULL, the value pointer was NULL -+ * or the input string could not be parsed at all such as starting -+ * with a character outside the base character range. In this case, -+ * *value will be left untouched. -+ */ -+PJ_DECL(pj_status_t) pj_strtoul3(const pj_str_t *str, unsigned long *value, -+ unsigned base); -+ -+/** - * Convert string to float. - * - * @param str the string. -@@ -786,7 +829,6 @@ PJ_INLINE(void*) pj_memchr(const void *buf, int c, pj_size_t size) - return (void*)memchr((void*)buf, c, size); - } - -- - /** - * @} - */ -diff --git a/pjlib/include/pj/types.h b/pjlib/include/pj/types.h -index 0e0e2d9a7..8c9f78238 100644 ---- a/pjlib/include/pj/types.h -+++ b/pjlib/include/pj/types.h -@@ -280,9 +280,6 @@ typedef int pj_exception_id_t; - /** Utility macro to compute the number of elements in static array. */ - #define PJ_ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) - --/** Maximum value for signed 32-bit integer. */ --#define PJ_MAXINT32 0x7FFFFFFFL -- - /** - * Length of object names. - */ -diff --git a/pjlib/src/pj/string.c b/pjlib/src/pj/string.c -index 307cfb47e..b95f141be 100644 ---- a/pjlib/src/pj/string.c -+++ b/pjlib/src/pj/string.c -@@ -23,11 +23,14 @@ - #include - #include - #include -+#include -+#include - - #if PJ_FUNCTIONS_ARE_INLINED==0 - # include - #endif - -+ - PJ_DEF(pj_ssize_t) pj_strspn(const pj_str_t *str, const pj_str_t *set_char) - { - pj_ssize_t i, j, count = 0; -@@ -230,6 +233,55 @@ PJ_DEF(long) pj_strtol(const pj_str_t *str) - return pj_strtoul(str); - } - -+ -+PJ_DEF(pj_status_t) pj_strtol2(const pj_str_t *str, long *value) -+{ -+ pj_str_t s; -+ unsigned long retval = 0; -+ pj_bool_t is_negative = PJ_FALSE; -+ int rc = 0; -+ -+ PJ_CHECK_STACK(); -+ -+ if (!str || !value) { -+ return PJ_EINVAL; -+ } -+ -+ s = *str; -+ pj_strltrim(&s); -+ -+ if (s.slen == 0) -+ return PJ_EINVAL; -+ -+ if (s.ptr[0] == '+' || s.ptr[0] == '-') { -+ is_negative = (s.ptr[0] == '-'); -+ s.ptr += 1; -+ s.slen -= 1; -+ } -+ -+ rc = pj_strtoul3(&s, &retval, 10); -+ if (rc == PJ_EINVAL) { -+ return rc; -+ } else if (rc != PJ_SUCCESS) { -+ *value = is_negative ? PJ_MINLONG : PJ_MAXLONG; -+ return is_negative ? PJ_ETOOSMALL : PJ_ETOOBIG; -+ } -+ -+ if (retval > PJ_MAXLONG && !is_negative) { -+ *value = PJ_MAXLONG; -+ return PJ_ETOOBIG; -+ } -+ -+ if (retval > (PJ_MAXLONG + 1UL) && is_negative) { -+ *value = PJ_MINLONG; -+ return PJ_ETOOSMALL; -+ } -+ -+ *value = is_negative ? -(long)retval : retval; -+ -+ return PJ_SUCCESS; -+} -+ - PJ_DEF(unsigned long) pj_strtoul(const pj_str_t *str) - { - unsigned long value; -@@ -282,6 +334,71 @@ PJ_DEF(unsigned long) pj_strtoul2(const pj_str_t *str, pj_str_t *endptr, - return value; - } - -+PJ_DEF(pj_status_t) pj_strtoul3(const pj_str_t *str, unsigned long *value, -+ unsigned base) -+{ -+ pj_str_t s; -+ unsigned i; -+ -+ PJ_CHECK_STACK(); -+ -+ if (!str || !value) { -+ return PJ_EINVAL; -+ } -+ -+ s = *str; -+ pj_strltrim(&s); -+ -+ if (s.slen == 0 || s.ptr[0] < '0' || -+ (base <= 10 && (unsigned)s.ptr[0] > ('0' - 1) + base) || -+ (base == 16 && !pj_isxdigit(s.ptr[0]))) -+ { -+ return PJ_EINVAL; -+ } -+ -+ *value = 0; -+ if (base <= 10) { -+ for (i=0; i<(unsigned)s.slen; ++i) { -+ unsigned c = s.ptr[i] - '0'; -+ if (s.ptr[i] < '0' || (unsigned)s.ptr[i] > ('0' - 1) + base) { -+ break; -+ } -+ if (*value > PJ_MAXULONG / base) { -+ *value = PJ_MAXULONG; -+ return PJ_ETOOBIG; -+ } -+ -+ *value *= base; -+ if ((PJ_MAXULONG - *value) < c) { -+ *value = PJ_MAXULONG; -+ return PJ_ETOOBIG; -+ } -+ *value += c; -+ } -+ } else if (base == 16) { -+ for (i=0; i<(unsigned)s.slen; ++i) { -+ unsigned c = pj_hex_digit_to_val(s.ptr[i]); -+ if (!pj_isxdigit(s.ptr[i])) -+ break; -+ -+ if (*value > PJ_MAXULONG / base) { -+ *value = PJ_MAXULONG; -+ return PJ_ETOOBIG; -+ } -+ *value *= base; -+ if ((PJ_MAXULONG - *value) < c) { -+ *value = PJ_MAXULONG; -+ return PJ_ETOOBIG; -+ } -+ *value += c; -+ } -+ } else { -+ pj_assert(!"Unsupported base"); -+ return PJ_EINVAL; -+ } -+ return PJ_SUCCESS; -+} -+ - PJ_DEF(float) pj_strtof(const pj_str_t *str) - { - pj_str_t part; -@@ -356,5 +473,3 @@ PJ_DEF(int) pj_utoa_pad( unsigned long val, char *buf, int min_dig, int pad) - - return len; - } -- -- -diff --git a/pjlib/src/pj/timer.c b/pjlib/src/pj/timer.c -index 225be4498..399e114a8 100644 ---- a/pjlib/src/pj/timer.c -+++ b/pjlib/src/pj/timer.c -@@ -36,6 +36,7 @@ - #include - #include - #include -+#include - - #define THIS_FILE "timer.c" - -diff --git a/pjsip/include/pjsip/sip_parser.h b/pjsip/include/pjsip/sip_parser.h -index 0d767f0ad..5691fed3a 100644 ---- a/pjsip/include/pjsip/sip_parser.h -+++ b/pjsip/include/pjsip/sip_parser.h -@@ -39,6 +39,26 @@ PJ_BEGIN_DECL - */ - - /** -+ * Contants for limit checks -+ */ -+#define PJSIP_MIN_CONTENT_LENGTH 0 -+#define PJSIP_MAX_CONTENT_LENGTH PJ_MAXINT32 -+#define PJSIP_MIN_PORT 0 -+#define PJSIP_MAX_PORT PJ_MAXUINT16 -+#define PJSIP_MIN_TTL 0 -+#define PJSIP_MAX_TTL PJ_MAXUINT8 -+#define PJSIP_MIN_STATUS_CODE 100 -+#define PJSIP_MAX_STATUS_CODE 999 -+#define PJSIP_MIN_Q1000 0 -+#define PJSIP_MAX_Q1000 PJ_MAXINT32 / 1000 -+#define PJSIP_MIN_EXPIRES 0 -+#define PJSIP_MAX_EXPIRES PJ_MAXINT32 -+#define PJSIP_MIN_CSEQ 0 -+#define PJSIP_MAX_CSEQ PJ_MAXINT32 -+#define PJSIP_MIN_RETRY_AFTER 0 -+#define PJSIP_MAX_RETRY_AFTER PJ_MAXINT32 -+ -+/** - * URI Parsing options. - */ - enum -@@ -64,6 +84,11 @@ enum - extern int PJSIP_SYN_ERR_EXCEPTION; - - /** -+ * Invalid value error exception value. -+ */ -+extern int PJSIP_EINVAL_ERR_EXCEPTION; -+ -+/** - * This structure is used to get error reporting from parser. - */ - typedef struct pjsip_parser_err_report -diff --git a/pjsip/src/pjsip/sip_parser.c b/pjsip/src/pjsip/sip_parser.c -index cf3b879f6..f9a0e65b5 100644 ---- a/pjsip/src/pjsip/sip_parser.c -+++ b/pjsip/src/pjsip/sip_parser.c -@@ -34,6 +34,7 @@ - #include - #include - #include -+#include - - #define THIS_FILE "sip_parser.c" - -@@ -93,6 +94,7 @@ static unsigned uri_handler_count; - * Global vars (also extern). - */ - int PJSIP_SYN_ERR_EXCEPTION = -1; -+int PJSIP_EINVAL_ERR_EXCEPTION = -2; - - /* Parser constants */ - static pjsip_parser_const_t pconst = -@@ -205,7 +207,6 @@ static unsigned long pj_strtoul_mindigit(const pj_str_t *str, - /* Case insensitive comparison */ - #define parser_stricmp(s1, s2) (s1.slen!=s2.slen || pj_stricmp_alnum(&s1, &s2)) - -- - /* Get a token and unescape */ - PJ_INLINE(void) parser_get_and_unescape(pj_scanner *scanner, pj_pool_t *pool, - const pj_cis_t *spec, -@@ -223,8 +224,6 @@ PJ_INLINE(void) parser_get_and_unescape(pj_scanner *scanner, pj_pool_t *pool, - #endif - } - -- -- - /* Syntax error handler for parser. */ - static void on_syntax_error(pj_scanner *scanner) - { -@@ -232,6 +231,60 @@ static void on_syntax_error(pj_scanner *scanner) - PJ_THROW(PJSIP_SYN_ERR_EXCEPTION); - } - -+/* Syntax error handler for parser. */ -+static void on_str_parse_error(const pj_str_t *str, int rc) -+{ -+ char *s; -+ -+ switch(rc) { -+ case PJ_EINVAL: -+ s = "NULL input string, invalid input string, or NULL return "\ -+ "value pointer"; -+ break; -+ case PJ_ETOOSMALL: -+ s = "String value was less than the minimum allowed value."; -+ break; -+ case PJ_ETOOBIG: -+ s = "String value was greater than the maximum allowed value."; -+ break; -+ default: -+ s = "Unknown error"; -+ } -+ -+ if (str) { -+ PJ_LOG(1, (THIS_FILE, "Error parsing '%.*s': %s", -+ (int)str->slen, str->ptr, s)); -+ } else { -+ PJ_LOG(1, (THIS_FILE, "Can't parse input string: %s", s)); -+ } -+ PJ_THROW(PJSIP_EINVAL_ERR_EXCEPTION); -+} -+ -+static void strtoi_validate(const pj_str_t *str, int min_val, -+ int max_val, int *value) -+{ -+ long retval; -+ pj_status_t status; -+ -+ if (!str || !value) { -+ on_str_parse_error(str, PJ_EINVAL); -+ } -+ status = pj_strtol2(str, &retval); -+ if (status != PJ_EINVAL) { -+ if (min_val > retval) { -+ *value = min_val; -+ status = PJ_ETOOSMALL; -+ } else if (retval > max_val) { -+ *value = max_val; -+ status = PJ_ETOOBIG; -+ } else -+ *value = (int)retval; -+ } -+ -+ if (status != PJ_SUCCESS) -+ on_str_parse_error(str, status); -+} -+ - /* Get parser constants. */ - PJ_DEF(const pjsip_parser_const_t*) pjsip_parser_const(void) - { -@@ -285,6 +338,14 @@ static pj_status_t init_parser() - PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); - - /* -+ * Invalid value exception. -+ */ -+ pj_assert (PJSIP_EINVAL_ERR_EXCEPTION == -2); -+ status = pj_exception_id_alloc("PJSIP invalid value error", -+ &PJSIP_EINVAL_ERR_EXCEPTION); -+ PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); -+ -+ /* - * Init character input spec (cis) - */ - -@@ -502,6 +563,9 @@ void deinit_sip_parser(void) - /* Deregister exception ID */ - pj_exception_id_free(PJSIP_SYN_ERR_EXCEPTION); - PJSIP_SYN_ERR_EXCEPTION = -1; -+ -+ pj_exception_id_free(PJSIP_EINVAL_ERR_EXCEPTION); -+ PJSIP_EINVAL_ERR_EXCEPTION = -2; - } - pj_leave_critical_section(); - } -@@ -766,7 +830,7 @@ PJ_DEF(pjsip_msg *) pjsip_parse_rdata( char *buf, pj_size_t size, - } - - /* Determine if a message has been received. */ --PJ_DEF(pj_bool_t) pjsip_find_msg( const char *buf, pj_size_t size, -+PJ_DEF(pj_status_t) pjsip_find_msg( const char *buf, pj_size_t size, - pj_bool_t is_datagram, pj_size_t *msg_size) - { - #if PJ_HAS_TCP -@@ -776,6 +840,7 @@ PJ_DEF(pj_bool_t) pjsip_find_msg( const char *buf, pj_size_t size, - const char *line; - int content_length = -1; - pj_str_t cur_msg; -+ pj_status_t status = PJ_SUCCESS; - const pj_str_t end_hdr = { "\n\r\n", 3}; - - *msg_size = size; -@@ -836,9 +901,16 @@ PJ_DEF(pj_bool_t) pjsip_find_msg( const char *buf, pj_size_t size, - pj_scan_get_newline(&scanner); - - /* Found a valid Content-Length header. */ -- content_length = pj_strtoul(&str_clen); -+ strtoi_validate(&str_clen, PJSIP_MIN_CONTENT_LENGTH, -+ PJSIP_MAX_CONTENT_LENGTH, &content_length); - } - PJ_CATCH_ANY { -+ int eid = PJ_GET_EXCEPTION(); -+ if (eid == PJSIP_SYN_ERR_EXCEPTION) { -+ status = PJSIP_EMISSINGHDR; -+ } else if (eid == PJSIP_EINVAL_ERR_EXCEPTION) { -+ status = PJSIP_EINVALIDHDR; -+ } - content_length = -1; - } - PJ_END -@@ -858,7 +930,7 @@ PJ_DEF(pj_bool_t) pjsip_find_msg( const char *buf, pj_size_t size, - - /* Found Content-Length? */ - if (content_length == -1) { -- return PJSIP_EMISSINGHDR; -+ return status; - } - - /* Enough packet received? */ -@@ -938,10 +1010,14 @@ static pj_bool_t is_next_sip_version(pj_scanner *scanner) - static pjsip_msg *int_parse_msg( pjsip_parse_ctx *ctx, - pjsip_parser_err_report *err_list) - { -- pj_bool_t parsing_headers; -- pjsip_msg *msg = NULL; -+ /* These variables require "volatile" so their values get -+ * preserved when re-entering the PJ_TRY block after an error. -+ */ -+ volatile pj_bool_t parsing_headers; -+ pjsip_msg *volatile msg = NULL; -+ pjsip_ctype_hdr *volatile ctype_hdr = NULL; -+ - pj_str_t hname; -- pjsip_ctype_hdr *ctype_hdr = NULL; - pj_scanner *scanner = ctx->scanner; - pj_pool_t *pool = ctx->pool; - PJ_USE_EXCEPTION; -@@ -1023,7 +1099,6 @@ parse_headers: - hdr->name = hdr->sname = hname; - } - -- - /* Single parse of header line can produce multiple headers. - * For example, if one Contact: header contains Contact list - * separated by comma, then these Contacts will be split into -@@ -1267,7 +1342,7 @@ static void int_parse_uri_host_port( pj_scanner *scanner, - pj_str_t port; - pj_scan_get_char(scanner); - pj_scan_get(scanner, &pconst.pjsip_DIGIT_SPEC, &port); -- *p_port = pj_strtoul(&port); -+ strtoi_validate(&port, PJSIP_MIN_PORT, PJSIP_MAX_PORT, p_port); - } else { - *p_port = 0; - } -@@ -1458,8 +1533,8 @@ static void* int_parse_sip_url( pj_scanner *scanner, - url->transport_param = pvalue; - - } else if (!parser_stricmp(pname, pconst.pjsip_TTL_STR) && pvalue.slen) { -- url->ttl_param = pj_strtoul(&pvalue); -- -+ strtoi_validate(&pvalue, PJSIP_MIN_TTL, PJSIP_MAX_TTL, -+ &url->ttl_param); - } else if (!parser_stricmp(pname, pconst.pjsip_MADDR_STR) && pvalue.slen) { - url->maddr_param = pvalue; - -@@ -1595,7 +1670,8 @@ static void int_parse_status_line( pj_scanner *scanner, - - parse_sip_version(scanner); - pj_scan_get( scanner, &pconst.pjsip_DIGIT_SPEC, &token); -- status_line->code = pj_strtoul(&token); -+ strtoi_validate(&token, PJSIP_MIN_STATUS_CODE, PJSIP_MAX_STATUS_CODE, -+ &status_line->code); - if (*scanner->curptr != '\r' && *scanner->curptr != '\n') - pj_scan_get( scanner, &pconst.pjsip_NOT_NEWLINE, &status_line->reason); - else -@@ -1780,20 +1856,34 @@ static void int_parse_contact_param( pjsip_contact_hdr *hdr, - if (!parser_stricmp(pname, pconst.pjsip_Q_STR) && pvalue.slen) { - char *dot_pos = (char*) pj_memchr(pvalue.ptr, '.', pvalue.slen); - if (!dot_pos) { -- hdr->q1000 = pj_strtoul(&pvalue) * 1000; -+ strtoi_validate(&pvalue, PJSIP_MIN_Q1000, PJSIP_MAX_Q1000, -+ &hdr->q1000); -+ hdr->q1000 *= 1000; - } else { - pj_str_t tmp = pvalue; -+ unsigned long qval_frac; - - tmp.slen = dot_pos - pvalue.ptr; -- hdr->q1000 = pj_strtoul(&tmp) * 1000; -+ strtoi_validate(&tmp, PJSIP_MIN_Q1000, PJSIP_MAX_Q1000, -+ &hdr->q1000); -+ hdr->q1000 *= 1000; - - pvalue.slen = (pvalue.ptr+pvalue.slen) - (dot_pos+1); - pvalue.ptr = dot_pos + 1; -- hdr->q1000 += pj_strtoul_mindigit(&pvalue, 3); -+ if (pvalue.slen > 3) { -+ pvalue.slen = 3; -+ } -+ qval_frac = pj_strtoul_mindigit(&pvalue, 3); -+ if ((unsigned)hdr->q1000 > (PJ_MAXINT32 - qval_frac)) { -+ PJ_THROW(PJSIP_SYN_ERR_EXCEPTION); -+ } -+ hdr->q1000 += qval_frac; - } -- } else if (!parser_stricmp(pname, pconst.pjsip_EXPIRES_STR) && pvalue.slen) { -- hdr->expires = pj_strtoul(&pvalue); -- -+ } else if (!parser_stricmp(pname, pconst.pjsip_EXPIRES_STR) && -+ pvalue.slen) -+ { -+ strtoi_validate(&pvalue, PJSIP_MIN_EXPIRES, PJSIP_MAX_EXPIRES, -+ &hdr->expires); - } else { - pjsip_param *p = PJ_POOL_ALLOC_T(pool, pjsip_param); - p->name = pname; -@@ -1890,19 +1980,22 @@ static pjsip_hdr* parse_hdr_content_type( pjsip_parse_ctx *ctx ) - static pjsip_hdr* parse_hdr_cseq( pjsip_parse_ctx *ctx ) - { - pj_str_t cseq, method; -- pjsip_cseq_hdr *hdr; -+ pjsip_cseq_hdr *hdr = NULL; -+ int cseq_val = 0; - -- hdr = pjsip_cseq_hdr_create(ctx->pool); - pj_scan_get( ctx->scanner, &pconst.pjsip_DIGIT_SPEC, &cseq); -- hdr->cseq = pj_strtoul(&cseq); -+ strtoi_validate(&cseq, PJSIP_MIN_CSEQ, PJSIP_MAX_CSEQ, &cseq_val); - -- pj_scan_get( ctx->scanner, &pconst.pjsip_TOKEN_SPEC, &method); -- pjsip_method_init_np(&hdr->method, &method); -+ hdr = pjsip_cseq_hdr_create(ctx->pool); -+ hdr->cseq = cseq_val; - -+ pj_scan_get( ctx->scanner, &pconst.pjsip_TOKEN_SPEC, &method); - parse_hdr_end( ctx->scanner ); - -- if (ctx->rdata) -+ pjsip_method_init_np(&hdr->method, &method); -+ if (ctx->rdata) { - ctx->rdata->msg_info.cseq = hdr; -+ } - - return (pjsip_hdr*)hdr; - } -@@ -1984,7 +2077,8 @@ static pjsip_hdr* parse_hdr_retry_after(pjsip_parse_ctx *ctx) - hdr = pjsip_retry_after_hdr_create(ctx->pool, 0); - - pj_scan_get(scanner, &pconst.pjsip_DIGIT_SPEC, &tmp); -- hdr->ivalue = pj_strtoul(&tmp); -+ strtoi_validate(&tmp, PJSIP_MIN_RETRY_AFTER, PJSIP_MAX_RETRY_AFTER, -+ &hdr->ivalue); - - while (!pj_scan_is_eof(scanner) && *scanner->curptr!='\r' && - *scanner->curptr!='\n') -@@ -2073,7 +2167,8 @@ static void int_parse_via_param( pjsip_via_hdr *hdr, pj_scanner *scanner, - hdr->branch_param = pvalue; - - } else if (!parser_stricmp(pname, pconst.pjsip_TTL_STR) && pvalue.slen) { -- hdr->ttl_param = pj_strtoul(&pvalue); -+ strtoi_validate(&pvalue, PJSIP_MIN_TTL, PJSIP_MAX_TTL, -+ &hdr->ttl_param); - - } else if (!parser_stricmp(pname, pconst.pjsip_MADDR_STR) && pvalue.slen) { - hdr->maddr_param = pvalue; -@@ -2082,9 +2177,10 @@ static void int_parse_via_param( pjsip_via_hdr *hdr, pj_scanner *scanner, - hdr->recvd_param = pvalue; - - } else if (!parser_stricmp(pname, pconst.pjsip_RPORT_STR)) { -- if (pvalue.slen) -- hdr->rport_param = pj_strtoul(&pvalue); -- else -+ if (pvalue.slen) { -+ strtoi_validate(&pvalue, PJSIP_MIN_PORT, PJSIP_MAX_PORT, -+ &hdr->rport_param); -+ } else - hdr->rport_param = 0; - } else { - pjsip_param *p = PJ_POOL_ALLOC_T(pool, pjsip_param); -@@ -2213,7 +2309,8 @@ static pjsip_hdr* parse_hdr_via( pjsip_parse_ctx *ctx ) - pj_str_t digit; - pj_scan_get_char(scanner); - pj_scan_get(scanner, &pconst.pjsip_DIGIT_SPEC, &digit); -- hdr->sent_by.port = pj_strtoul(&digit); -+ strtoi_validate(&digit, PJSIP_MIN_PORT, PJSIP_MAX_PORT, -+ &hdr->sent_by.port); - } - - int_parse_via_param(hdr, scanner, ctx->pool); -@@ -2298,9 +2395,10 @@ PJ_DEF(pj_status_t) pjsip_parse_headers( pj_pool_t *pool, char *input, - unsigned options) - { - enum { STOP_ON_ERROR = 1 }; -+ pj_str_t hname; - pj_scanner scanner; - pjsip_parse_ctx ctx; -- pj_str_t hname; -+ - PJ_USE_EXCEPTION; - - pj_scan_init(&scanner, input, size, PJ_SCAN_AUTOSKIP_WS_HEADER, -@@ -2323,7 +2421,7 @@ retry_parse: - */ - hname.slen = 0; - -- /* Get hname. */ -+ /* Get hname. */ - pj_scan_get( &scanner, &pconst.pjsip_TOKEN_SPEC, &hname); - if (pj_scan_get_char( &scanner ) != ':') { - PJ_THROW(PJSIP_SYN_ERR_EXCEPTION); -diff --git a/pjsip/src/pjsip/sip_transaction.c b/pjsip/src/pjsip/sip_transaction.c -index f3be93beb..7ac3d1b76 100644 ---- a/pjsip/src/pjsip/sip_transaction.c -+++ b/pjsip/src/pjsip/sip_transaction.c -@@ -289,11 +289,11 @@ static pj_status_t create_tsx_key_2543( pj_pool_t *pool, - - /* Calculate length required. */ - len_required = method->name.slen + /* Method */ -- 9 + /* CSeq number */ -+ 11 + /* CSeq number */ - rdata->msg_info.from->tag.slen + /* From tag. */ - rdata->msg_info.cid->id.slen + /* Call-ID */ - host->slen + /* Via host. */ -- 9 + /* Via port. */ -+ 11 + /* Via port. */ - 16; /* Separator+Allowance. */ - key = p = (char*) pj_pool_alloc(pool, len_required); - -diff --git a/pjsip/src/pjsip/sip_transport.c b/pjsip/src/pjsip/sip_transport.c -index 0c338e8fd..b24cbb411 100644 ---- a/pjsip/src/pjsip/sip_transport.c -+++ b/pjsip/src/pjsip/sip_transport.c -@@ -1848,7 +1848,7 @@ PJ_DEF(pj_ssize_t) pjsip_tpmgr_receive_packet( pjsip_tpmgr *mgr, - /* Check for parsing syntax error */ - if (msg==NULL || !pj_list_empty(&rdata->msg_info.parse_err)) { - pjsip_parser_err_report *err; -- char buf[128]; -+ char buf[256]; - pj_str_t tmp; - - /* Gather syntax error information */ -@@ -1862,7 +1862,10 @@ PJ_DEF(pj_ssize_t) pjsip_tpmgr_receive_packet( pjsip_tpmgr *mgr, - pj_exception_id_name(err->except_code), - (int)err->hname.slen, err->hname.ptr, - err->line, err->col); -- if (len > 0 && len < (int) (sizeof(buf)-tmp.slen)) { -+ if (len >= (int)sizeof(buf)-tmp.slen) { -+ len = (int)sizeof(buf)-tmp.slen; -+ } -+ if (len > 0) { - tmp.slen += len; - } - err = err->next; --- -2.13.6 - diff --git a/third-party/versions.mak b/third-party/versions.mak index 4f645f1bb..a90a52348 100644 --- a/third-party/versions.mak +++ b/third-party/versions.mak @@ -1,2 +1,2 @@ -PJPROJECT_VERSION = 2.7 +PJPROJECT_VERSION = 2.7.1 -- cgit v1.2.3