Index: pjproject/trunk/pjlib/build/pjlib.vcproj
===================================================================
--- pjproject/trunk/pjlib/build/pjlib.vcproj	(revision 5681)
+++ pjproject/trunk/pjlib/build/pjlib.vcproj	(revision 5682)
@@ -14971,4 +14971,8 @@
 			</File>
 			<File
+				RelativePath="..\include\pj\limits.h"
+				>
+			</File>
+			<File
 				RelativePath="..\include\pj\list.h"
 				>
@@ -15074,4 +15078,8 @@
 				</File>
 				<File
+					RelativePath="..\include\pj\compat\limits.h"
+					>
+				</File>
+				<File
 					RelativePath="..\include\pj\compat\m_alpha.h"
 					>
Index: pjproject/trunk/pjlib/build/pjlib.vcxproj
===================================================================
--- pjproject/trunk/pjlib/build/pjlib.vcxproj	(revision 5681)
+++ pjproject/trunk/pjlib/build/pjlib.vcxproj	(revision 5682)
@@ -495,5 +495,5 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
     </ClCompile>
-    <ClCompile Include="..\src\pj\file_io_win32.c" />    
+    <ClCompile Include="..\src\pj\file_io_win32.c" />
     <ClCompile Include="..\src\pj\guid.c" />
     <ClCompile Include="..\src\pj\guid_simple.c">
@@ -891,4 +891,5 @@
     <ClInclude Include="..\include\pj\compat\errno.h" />
     <ClInclude Include="..\include\pj\compat\high_precision.h" />
+    <ClInclude Include="..\include\pj\compat\limits.h" />
     <ClInclude Include="..\include\pj\compat\malloc.h" />
     <ClInclude Include="..\include\pj\compat\m_alpha.h" />
@@ -926,4 +927,5 @@
     <ClInclude Include="..\include\pj\ioqueue.h" />
     <ClInclude Include="..\include\pj\ip_helper.h" />
+    <ClInclude Include="..\include\pj\limits.h" />
     <ClInclude Include="..\include\pj\list.h" />
     <ClInclude Include="..\include\pj\list_i.h" />
Index: pjproject/trunk/pjlib/build/pjlib.vcxproj.filters
===================================================================
--- pjproject/trunk/pjlib/build/pjlib.vcxproj.filters	(revision 5681)
+++ pjproject/trunk/pjlib/build/pjlib.vcxproj.filters	(revision 5682)
@@ -440,4 +440,10 @@
       <Filter>Header Files\compat</Filter>
     </ClInclude>
+    <ClInclude Include="..\include\pj\limits.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\include\pj\compat\limits.h">
+      <Filter>Header Files\compat</Filter>
+    </ClInclude>
   </ItemGroup>
 </Project>
Index: pjproject/trunk/pjlib/include/pj/compat/limits.h
===================================================================
--- pjproject/trunk/pjlib/include/pj/compat/limits.h	(revision 5682)
+++ pjproject/trunk/pjlib/include/pj/compat/limits.h	(revision 5682)
@@ -0,0 +1,65 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2017 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2017 George Joseph <gjoseph@digium.com>
+ *
+ * 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 <limits.h>
+#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__ */
Index: pjproject/trunk/pjlib/include/pj/compat/os_win32.h
===================================================================
--- pjproject/trunk/pjlib/include/pj/compat/os_win32.h	(revision 5681)
+++ pjproject/trunk/pjlib/include/pj/compat/os_win32.h	(revision 5682)
@@ -58,4 +58,5 @@
 #define PJ_HAS_TIME_H		    1
 #define PJ_HAS_UNISTD_H		    0
+#define PJ_HAS_LIMITS_H		    1
 
 #define PJ_HAS_MSWSOCK_H	    1
Index: pjproject/trunk/pjlib/include/pj/limits.h
===================================================================
--- pjproject/trunk/pjlib/include/pj/limits.h	(revision 5682)
+++ pjproject/trunk/pjlib/include/pj/limits.h	(revision 5682)
@@ -0,0 +1,51 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2017 Teluu Inc. (http://www.teluu.com)
+ * Copyright (C) 2017 George Joseph <gjoseph@digium.com>
+ *
+ * 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 <pj/compat/limits.h>
+
+/** 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__ */
Index: pjproject/trunk/pjlib/include/pj/string.h
===================================================================
--- pjproject/trunk/pjlib/include/pj/string.h	(revision 5681)
+++ pjproject/trunk/pjlib/include/pj/string.h	(revision 5682)
@@ -28,5 +28,4 @@
 #include <pj/types.h>
 #include <pj/compat/string.h>
-
 
 PJ_BEGIN_DECL
@@ -637,4 +636,27 @@
 
 /**
+ * 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
@@ -663,4 +685,25 @@
 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);
 
 /**
@@ -787,5 +830,4 @@
 }
 
-
 /**
  * @}
Index: pjproject/trunk/pjlib/include/pj/types.h
===================================================================
--- pjproject/trunk/pjlib/include/pj/types.h	(revision 5681)
+++ pjproject/trunk/pjlib/include/pj/types.h	(revision 5682)
@@ -280,7 +280,4 @@
 /** 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
 
 /**
Index: pjproject/trunk/pjlib/src/pj/string.c
===================================================================
--- pjproject/trunk/pjlib/src/pj/string.c	(revision 5681)
+++ pjproject/trunk/pjlib/src/pj/string.c	(revision 5682)
@@ -24,8 +24,11 @@
 #include <pj/rand.h>
 #include <pj/os.h>
+#include <pj/errno.h>
+#include <pj/limits.h>
 
 #if PJ_FUNCTIONS_ARE_INLINED==0
 #  include <pj/string_i.h>
 #endif
+
 
 PJ_DEF(pj_ssize_t) pj_strspn(const pj_str_t *str, const pj_str_t *set_char)
@@ -231,4 +234,53 @@
 }
 
+
+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)
 {
@@ -281,4 +333,69 @@
 
     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;
 }
 
@@ -357,4 +474,2 @@
     return len;
 }
-
-
Index: pjproject/trunk/pjlib/src/pj/timer.c
===================================================================
--- pjproject/trunk/pjlib/src/pj/timer.c	(revision 5681)
+++ pjproject/trunk/pjlib/src/pj/timer.c	(revision 5682)
@@ -37,4 +37,5 @@
 #include <pj/log.h>
 #include <pj/rand.h>
+#include <pj/limits.h>
 
 #define THIS_FILE	"timer.c"
Index: pjproject/trunk/pjsip/include/pjsip/sip_parser.h
===================================================================
--- pjproject/trunk/pjsip/include/pjsip/sip_parser.h	(revision 5681)
+++ pjproject/trunk/pjsip/include/pjsip/sip_parser.h	(revision 5682)
@@ -38,4 +38,24 @@
  * @{
  */
+
+/**
+ * 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
 
 /**
@@ -63,4 +83,9 @@
  */
 extern int PJSIP_SYN_ERR_EXCEPTION;
+
+/**
+ * Invalid value error exception value.
+ */
+extern int PJSIP_EINVAL_ERR_EXCEPTION;
 
 /**
Index: pjproject/trunk/pjsip/src/pjsip/sip_parser.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip/sip_parser.c	(revision 5681)
+++ pjproject/trunk/pjsip/src/pjsip/sip_parser.c	(revision 5682)
@@ -35,4 +35,5 @@
 #include <pj/ctype.h>
 #include <pj/assert.h>
+#include <pj/limits.h>
 
 #define THIS_FILE	    "sip_parser.c"
@@ -94,4 +95,5 @@
  */
 int PJSIP_SYN_ERR_EXCEPTION = -1;
+int PJSIP_EINVAL_ERR_EXCEPTION = -2;
 
 /* Parser constants */
@@ -206,5 +208,4 @@
 #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,
@@ -224,6 +225,4 @@
 }
 
-
-
 /* Syntax error handler for parser. */
 static void on_syntax_error(pj_scanner *scanner)
@@ -231,4 +230,58 @@
     PJ_UNUSED_ARG(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);
 }
 
@@ -286,4 +339,12 @@
 
     /*
+     * 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)
      */
@@ -503,4 +564,7 @@
 	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();
@@ -767,5 +831,5 @@
 
 /* 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)
 {
@@ -777,4 +841,5 @@
     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};
 
@@ -837,7 +902,14 @@
 
 		/* 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;
 	    }
@@ -859,5 +931,5 @@
     /* Found Content-Length? */
     if (content_length == -1) {
-	return PJSIP_EMISSINGHDR;
+	return status;
     }
 
@@ -939,8 +1011,12 @@
 				 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;
@@ -1024,5 +1100,4 @@
 	    }
 	    
-	
 	    /* Single parse of header line can produce multiple headers.
 	     * For example, if one Contact: header contains Contact list
@@ -1268,5 +1343,5 @@
 	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;
@@ -1459,6 +1534,6 @@
 
 	} 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;
@@ -1596,5 +1671,6 @@
     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);
@@ -1781,18 +1857,32 @@
 	    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);
@@ -1891,17 +1981,20 @@
 {
     pj_str_t cseq, method;
-    pjsip_cseq_hdr *hdr;
+    pjsip_cseq_hdr *hdr = NULL;
+    int cseq_val = 0;
+
+    pj_scan_get( ctx->scanner, &pconst.pjsip_DIGIT_SPEC, &cseq);
+    strtoi_validate(&cseq, PJSIP_MIN_CSEQ, PJSIP_MAX_CSEQ, &cseq_val);
 
     hdr = pjsip_cseq_hdr_create(ctx->pool);
-    pj_scan_get( ctx->scanner, &pconst.pjsip_DIGIT_SPEC, &cseq);
-    hdr->cseq = pj_strtoul(&cseq);
+    hdr->cseq = cseq_val;
 
     pj_scan_get( ctx->scanner, &pconst.pjsip_TOKEN_SPEC, &method);
+    parse_hdr_end( ctx->scanner );
+
     pjsip_method_init_np(&hdr->method, &method);
-
-    parse_hdr_end( ctx->scanner );
-
-    if (ctx->rdata)
+    if (ctx->rdata) {
         ctx->rdata->msg_info.cseq = hdr;
+    }
 
     return (pjsip_hdr*)hdr;
@@ -1985,5 +2078,6 @@
     
     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' &&
@@ -2074,5 +2168,6 @@
 
 	} 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) {
@@ -2083,7 +2178,8 @@
 
 	} 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 {
@@ -2214,5 +2310,6 @@
 	    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);
 	}
 	
@@ -2299,7 +2396,8 @@
 {
     enum { STOP_ON_ERROR = 1 };
+    pj_str_t hname;
     pj_scanner scanner;
     pjsip_parse_ctx ctx;
-    pj_str_t hname;
+
     PJ_USE_EXCEPTION;
 
@@ -2324,5 +2422,5 @@
 	    hname.slen = 0;
 
-	    /* Get hname. */
+	    /* Get hname. */            
 	    pj_scan_get( &scanner, &pconst.pjsip_TOKEN_SPEC, &hname);
 	    if (pj_scan_get_char( &scanner ) != ':') {
Index: pjproject/trunk/pjsip/src/pjsip/sip_transaction.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip/sip_transaction.c	(revision 5681)
+++ pjproject/trunk/pjsip/src/pjsip/sip_transaction.c	(revision 5682)
@@ -290,9 +290,9 @@
     /* 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);
Index: pjproject/trunk/pjsip/src/pjsip/sip_transport.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsip/sip_transport.c	(revision 5681)
+++ pjproject/trunk/pjsip/src/pjsip/sip_transport.c	(revision 5682)
@@ -1849,5 +1849,5 @@
 	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;
 
@@ -1863,5 +1863,8 @@
 				       (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;
 		}
