=== modified file 'compat/xstrto.cc'
--- compat/xstrto.cc	2012-10-04 11:10:17 +0000
+++ compat/xstrto.cc	2013-01-04 18:08:03 +0000
@@ -59,8 +59,14 @@
     char *my_end;
 
     errno = 0;
-    v = strtoul(s, &my_end, 0);
-
+    
+    long l = strtol(s, &my_end, 0);
+    
+    v = l;
+    
+    if (l < 0)
+        return false;
+    
     if (my_end == s)
         return false;
     if (end != NULL)
@@ -85,8 +91,14 @@
     bool ret;
 
     ret = xstrtoul(s, end, &v, min, max);
+  
     if (value != NULL)
         *value = v;
+
+    if(v != (unsigned long) *value) {
+        return false;     
+    }
+
     return ret;
 }
 

=== modified file 'src/HelperChildConfig.cc'
--- src/HelperChildConfig.cc	2012-08-31 16:57:39 +0000
+++ src/HelperChildConfig.cc	2013-01-04 21:19:42 +0000
@@ -3,6 +3,7 @@
 #include "Debug.h"
 #include "HelperChildConfig.h"
 #include "globals.h"
+#include "Parsing.h"
 
 #include <string.h>
 
@@ -49,24 +50,27 @@
         self_destruct();
 
     /* starts with a bare number for the max... back-compatible */
-    n_max = atoi(token);
+    n_max = xatoui(token);
 
-    if (n_max < 1)
+    if (n_max < 1) {
+        debugs(0, DBG_CRITICAL, "ERROR: The maximum number of processes cannot be less than 1.");
         self_destruct();
+    }
 
     /* Parse extension options */
     for (; (token = strtok(NULL, w_space)) ;) {
         if (strncmp(token, "startup=", 8) == 0) {
-            n_startup = atoi(token + 8);
+            n_startup = xatoui(token + 8);
         } else if (strncmp(token, "idle=", 5) == 0) {
-            n_idle = atoi(token + 5);
+            n_idle = xatoui(token + 5);
             if (n_idle < 1) {
                 debugs(0, DBG_CRITICAL, "WARNING OVERIDE: Using idle=0 for helpers causes request failures. Overiding to use idle=1 instead.");
                 n_idle = 1;
             }
         } else if (strncmp(token, "concurrency=", 12) == 0) {
-            concurrency = atoi(token + 12);
+            concurrency = xatoui(token + 12);
         } else {
+            debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: Undefined option: " << token << ".");
             self_destruct();
         }
     }

=== modified file 'src/Parsing.cc'
--- src/Parsing.cc	2012-12-29 02:52:50 +0000
+++ src/Parsing.cc	2013-01-04 19:29:08 +0000
@@ -34,6 +34,8 @@
 #include "cache_cf.h"
 #include "compat/strtoll.h"
 #include "Parsing.h"
+#include "globals.h"
+#include "Debug.h"
 
 /*
  * These functions is the same as atoi/l/f, except that they check for errors
@@ -45,8 +47,15 @@
     char *end;
     double ret = strtod(token, &end);
 
-    if (ret == 0 && end == token)
-        self_destruct();
+    if (ret == 0 && end == token) {
+        debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: No digits were found in the input value '" << token << "'.");
+        self_destruct();
+    }
+
+    if (*end) {
+        debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The input value '" << token << "' contains unexpected characters.");
+        self_destruct();
+    }
 
     return ret;
 }
@@ -54,19 +63,66 @@
 int
 xatoi(const char *token)
 {
-    return xatol(token);
+    long long input; 
+    int  ret;
+
+    input = xatoll(token, 10);
+    ret = (int) input;
+
+    if (input != (long long) ret) {
+        debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "' is larger than the type 'int'.");
+        self_destruct();
+    }
+
+    return ret;
+}
+
+unsigned int
+xatoui(const char *token)
+{
+    int ret = xatoi(token);
+    if(ret < 0) {
+	debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The input value '" << token << "' cannot be less than 0.");
+        self_destruct();
+    }
+
+    return ret;
 }
 
 long
 xatol(const char *token)
 {
+    long long input;
+    long ret;
+
+    input = xatoll(token, 10);
+    ret = (long) input;
+    
+    if (input != (long long) ret) {
+        debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The input value '" << token << "' is larger than the type 'long'.");
+        self_destruct();
+    }
+
+    return ret;
+}
+
+long long
+xatoll(const char *token, int base)
+{
     char *end;
-    long ret = strtol(token, &end, 10);
-
-    if (end == token || *end)
-        self_destruct();
-
-    return ret;
+    long long ret = strtoll(token, &end, base);
+
+    if (end == token) {
+        debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: No digits were found in the input value '" << token << "'.");
+        self_destruct();
+    }
+
+    if (*end) {
+        debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The input value '" << token << "'contains unexpected characters.");
+        self_destruct();
+    }
+
+    return ret;   
 }
 
 unsigned short
@@ -74,8 +130,15 @@
 {
     long port = xatol(token);
 
-    if (port & ~0xFFFF)
-        self_destruct();
+    if(port < 0) {
+        debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "'cannot be less than 0.");
+        self_destruct();
+    }
+
+    if (port & ~0xFFFF) {
+        debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "'is larger than the type 'short'.");
+        self_destruct();
+    }
 
     return port;
 }
@@ -84,32 +147,77 @@
 GetInteger64(void)
 {
     char *token = strtok(NULL, w_space);
-    int64_t i;
+    int64_t ret;
+    long long input;
 
     if (token == NULL)
         self_destruct();
 
-    i = strtoll(token, NULL, 10);
-
-    return i;
+    input = xatoll(token, 10);
+    ret = (int64_t) input;
+
+    if (input != (long long) ret) {
+        debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "' is larger than the type 'int64_t'.");
+        self_destruct();
+    }
+
+    return ret; 
 }
 
+/*
+ * This function is different from others (e.g., GetInteger64, GetShort) 
+ * because it supports octal and hexadecimal numbers
+ */
 int
 GetInteger(void)
 {
     char *token = strtok(NULL, w_space);
     int i;
-
+    
+    long long ret; 
+    
     if (token == NULL)
         self_destruct();
 
-    // %i honors 0 and 0x prefixes, which are important for things like umask
-    if (sscanf(token, "%i", &i) != 1)
+    ret = xatoll(token, 0);
+    
+    i = (int) ret;
+    if(ret != (long long) i) {
+        debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "' is larger than the type 'int'.");
         self_destruct();
-
+    }
+    
     return i;
 }
 
+/*
+ * This function is similar as GetInteger() but the token might contain 
+ * the percentage symbol (%) and we check whether the value is in the range
+ * of [0, 100]
+ * So, we accept two types of input: 1. XX% or 2. XX , 0<=XX<=100
+ */
+int 
+GetPercentage(void) 
+{
+    int p;
+    char *token = strtok(NULL, w_space);
+    
+    //if there is a % in the end of the digits, we remove it and go on.
+    char* end = &token[strlen(token)-1];
+    if(*end == '%') {
+        *end = '\0';
+    }
+
+    p = xatoi(token);
+
+    if(p < 0 || p > 100) {
+        debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "' is out of range -- a percentage should be within [0, 100].");
+        self_destruct();
+    }
+
+    return p;
+}
+
 unsigned short
 GetShort(void)
 {
@@ -193,6 +301,8 @@
             return false;
     } else if ((port = strtol(token, &tmp, 10)), !*tmp) {
         /* port */
+        port = xatos(token);        
+
     } else {
         host = token;
         port = 0;

=== modified file 'src/Parsing.h'
--- src/Parsing.h	2012-09-21 14:57:30 +0000
+++ src/Parsing.h	2013-01-04 19:33:12 +0000
@@ -38,7 +38,9 @@
 
 double xatof(const char *token);
 int xatoi(const char *token);
+unsigned int xatoui(const char *token);
 long xatol(const char *token);
+long long xatoll(const char *token, int base);
 unsigned short xatos(const char *token);
 
 /**
@@ -52,6 +54,11 @@
  */
 int GetInteger(void);
 
+/**
+ * Parse a percentage value, e.g., 20%
+ */
+int GetPercentage(void);
+
 unsigned short GetShort(void);
 
 // on success, returns true and sets *p (if any) to the end of the integer

=== modified file 'src/cache_cf.cc'
--- src/cache_cf.cc	2012-12-27 18:15:38 +0000
+++ src/cache_cf.cc	2013-01-04 21:29:00 +0000
@@ -1017,6 +1017,13 @@
         self_destruct();
 
     *tptr = static_cast<time_msec_t>(m * d);
+
+    if (static_cast<double>(*tptr) * 2 != m * d * 2) { 
+        debugs(3, DBG_CRITICAL, "ERROR: Invalid value '" << 
+               d << " " << token << ": integer overflow (time_msec_t).");
+        self_destruct();
+    }
+
 }
 
 static uint64_t
@@ -1097,8 +1104,11 @@
 
     *bptr = static_cast<int64_t>(m * d / u);
 
-    if (static_cast<double>(*bptr) * 2 != m * d / u * 2)
+    if (static_cast<double>(*bptr) * 2 != m * d / u * 2) {
+        debugs(3, DBG_CRITICAL, "ERROR: Invalid value '" << 
+               d << " " << token << ": integer overflow (int64_t).");
         self_destruct();
+    }
 }
 
 static void
@@ -1141,8 +1151,11 @@
 
     *bptr = static_cast<size_t>(m * d / u);
 
-    if (static_cast<double>(*bptr) * 2 != m * d / u * 2)
+    if (static_cast<double>(*bptr) * 2 != m * d / u * 2) {
+        debugs(3, DBG_CRITICAL, "ERROR: Invalid value '" << 
+               d << " " << token << ": integer overflow (size_t).");
         self_destruct();
+    }
 }
 
 #if !USE_DNSHELPER
@@ -1184,10 +1197,13 @@
         return;
     }
 
-    *bptr = static_cast<size_t>(m * d / u);
+    *bptr = static_cast<ssize_t>(m * d / u);
 
-    if (static_cast<double>(*bptr) * 2 != m * d / u * 2)
+    if (static_cast<double>(*bptr) * 2 != m * d / u * 2) {
+        debugs(3, DBG_CRITICAL, "ERROR: Invalid value '" << 
+               d << " " << token << ": integer overflow (ssize_t).");
         self_destruct();
+    }
 }
 #endif
 
@@ -2266,7 +2282,7 @@
             safe_free(p->sslkey);
             p->sslkey = xstrdup(token + 7);
         } else if (strncmp(token, "sslversion=", 11) == 0) {
-            p->sslversion = atoi(token + 11);
+            p->sslversion = xatoi(token + 11);
         } else if (strncmp(token, "ssloptions=", 11) == 0) {
             safe_free(p->ssloptions);
             p->ssloptions = xstrdup(token + 11);
@@ -2597,10 +2613,20 @@
     if (token == NULL)
         self_destruct();
 
-    if (!strcasecmp(token, "on") || !strcasecmp(token, "enable"))
-        *var = 1;
-    else
-        *var = 0;
+    if (!strcasecmp(token, "on")) {
+        *var = 1;
+    } else if (!strcasecmp(token, "enable")) {
+        debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "WARNING: 'enable' and 'disable' will be deprecated in future releases. Please update to use value 'on' and 'off'.");
+        *var = 1;
+    } else if (!strcasecmp(token, "off")) {
+        *var = 0;
+    } else if (!strcasecmp(token, "disable")) {
+        debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "WARNING: 'enable' and 'disable' will be deprecated in future releases. Please update to use value 'on' and 'off'.");
+        *var = 0;
+    } else {
+        debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: Invalid option: Boolean options can only be 'on' or 'off'.");
+        self_destruct();
+    }
 }
 
 #define free_onoff free_int
@@ -2628,12 +2654,22 @@
     if (token == NULL)
         self_destruct();
 
-    if (!strcasecmp(token, "on") || !strcasecmp(token, "enable"))
-        *var = 1;
-    else if (!strcasecmp(token, "warn"))
+    if (!strcasecmp(token, "on")) { 
+        *var = 1;
+    } else if (!strcasecmp(token, "enable")) {
+        debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "WARNING: 'enable' and 'disable' will be deprecated in future releases. Please update to use value 'on' and 'off'.");
+        *var = 1;
+    } else if (!strcasecmp(token, "warn")) {
         *var = -1;
-    else
-        *var = 0;
+    } else if (!strcasecmp(token, "off")) {
+        *var = 0;
+    } else if (!strcasecmp(token, "disable")) {
+        debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "WARNING: 'enable' and 'disable' will be deprecated in future releases. Please update to use value 'on' and 'off'.");
+        *var = 0;
+    } else {
+        debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: Invalid option: Tristate options can only be 'on', 'off', or 'warn'.");
+        self_destruct();
+    }
 }
 
 #define free_tristate free_int
@@ -2757,7 +2793,7 @@
 
     min = (time_t) (i * 60);	/* convert minutes to seconds */
 
-    i = GetInteger();		/* token: pct */
+    i = GetPercentage();	/* token: pct */
 
     pct = (double) i / 100.0;
 
@@ -2782,7 +2818,7 @@
         } else if (!strcmp(token, "store-stale")) {
             store_stale = 1;
         } else if (!strncmp(token, "max-stale=", 10)) {
-            max_stale = atoi(token + 10);
+            max_stale = xatoi(token + 10);
 #if USE_HTTP_VIOLATIONS
 
         } else if (!strcmp(token, "override-expire"))
@@ -3223,8 +3259,10 @@
         *var = URI_WHITESPACE_ENCODE;
     else if (!strcasecmp(token, "chop"))
         *var = URI_WHITESPACE_CHOP;
-    else
+    else {
+        debugs(0, DBG_PARSE_NOTE(2), "ERROR: Invalid option '" << token << "': 'uri_whitespace' accepts 'strip', 'deny', 'allow', 'encode', and 'chop'.");
         self_destruct();
+    }
 }
 
 static void
@@ -3334,9 +3372,11 @@
         Config.onoff.memory_cache_disk = 0;
     } else if (strcmp(token, "never") == 0) {
         Config.onoff.memory_cache_first = 0;
-        Config.onoff.memory_cache_disk = 0;
-    } else
+        Config.onoff.memory_cache_disk = 0; 
+    } else {
+        debugs(0, DBG_PARSE_NOTE(2), "ERROR: Invalid option '" << token << "': 'memory_cache_mode' accepts 'always', 'disk', 'network', and 'never'.");
         self_destruct();
+    }
 }
 
 static void
@@ -3475,6 +3515,7 @@
 
     } else if ((port = strtol(token, &junk, 10)), !*junk) {
         /* port */
+        port = xatos(token);
         debugs(3, 3, s->protocol << "_port: found Listen on Port: " << port);
     } else {
         debugs(3, DBG_CRITICAL, s->protocol << "_port: missing Port: " << token);
@@ -3639,16 +3680,16 @@
     } else if (strncmp(token, "tcpkeepalive=", 13) == 0) {
         char *t = token + 13;
         s->tcp_keepalive.enabled = 1;
-        s->tcp_keepalive.idle = atoi(t);
+        s->tcp_keepalive.idle = xatoui(t);
         t = strchr(t, ',');
         if (t) {
             ++t;
-            s->tcp_keepalive.interval = atoi(t);
+            s->tcp_keepalive.interval = xatoui(t);
             t = strchr(t, ',');
         }
         if (t) {
             ++t;
-            s->tcp_keepalive.timeout = atoi(t);
+            s->tcp_keepalive.timeout = xatoui(t);
             // t = strchr(t, ','); // not really needed, left in as documentation
         }
 #if USE_SSL
@@ -3705,6 +3746,7 @@
         parseBytesOptionValue(&s->dynamicCertMemCacheSize, B_BYTES_STR, token + 28);
 #endif
     } else {
+        debugs(0, DBG_PARSE_NOTE(2), "ERROR: Undefined option: " << token << "."); 
         self_destruct();
     }
 }

=== modified file 'src/wccp2.cc'
--- src/wccp2.cc	2012-12-23 18:43:09 +0000
+++ src/wccp2.cc	2013-01-04 22:05:47 +0000
@@ -2249,7 +2249,7 @@
 {
     int i = 0;
     int p;
-    char *tmp, *tmp2, *port, *end;
+    char *tmp, *tmp2, *port;
 
     if (!options) {
         return;
@@ -2261,7 +2261,7 @@
     port = strsep(&tmp2, ",");
 
     while (port && i < WCCP2_NUMPORTS) {
-        p = strtol(port, &end, 0);
+        p = xatoi(port);	
 
         if (p < 1 || p > 65535) {
             fatalf("parse_wccp2_service_ports: port value '%s' isn't valid (1..65535)\n", port);

