]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/Parsing.cc
Enable length configuration for pipeline_prefetch queue
[thirdparty/squid.git] / src / Parsing.cc
index a20ba9efca1754d89f10a81c2939ef3d3ce33195..b180eaa431e2ca2847380d22f902049de2038750 100644 (file)
@@ -1,8 +1,5 @@
-
 /*
- * $Id$
- *
- * DEBUG: section 3     Configuration File Parsing
+ * DEBUG: section 03    Configuration File Parsing
  * AUTHOR: Harvest Derived
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
  *
  */
 
+#include "squid.h"
+#include "cache_cf.h"
+#include "compat/strtoll.h"
+#include "ConfigParser.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
 double
 xatof(const char *token)
 {
-    char *end;
+    char *end = NULL;
     double ret = strtod(token, &end);
 
-    if (ret == 0 && end == token)
+    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: Invalid value: '" << token << "' is supposed to be a number.");
+        self_destruct();
+    }
 
     return ret;
 }
@@ -54,17 +64,64 @@ xatof(const char *token)
 int
 xatoi(const char *token)
 {
-    return xatol(token);
+    int64_t input = xatoll(token, 10);
+    int ret = (int) input;
+
+    if (input != static_cast<int64_t>(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, char eov)
+{
+    int64_t input = xatoll(token, 10, eov);
+    if (input < 0) {
+        debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The input value '" << token << "' cannot be less than 0.");
+        self_destruct();
+    }
+
+    unsigned int ret = (unsigned int) input;
+    if (input != static_cast<int64_t>(ret)) {
+        debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "' is larger than the type 'unsigned int'.");
+        self_destruct();
+    }
+
+    return ret;
 }
 
 long
 xatol(const char *token)
 {
-    char *end;
-    long ret = strtol(token, &end, 10);
+    int64_t input = xatoll(token, 10);
+    long ret = (long) input;
 
-    if (end == token || *end)
+    if (input != static_cast<int64_t>(ret)) {
+        debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "' is larger than the type 'long'.");
         self_destruct();
+    }
+
+    return ret;
+}
+
+int64_t
+xatoll(const char *token, int base, char eov)
+{
+    char *end = NULL;
+    int64_t 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 != eov) {
+        debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: Invalid value: '" << token << "' is supposed to be a number.");
+        self_destruct();
+    }
 
     return ret;
 }
@@ -74,8 +131,15 @@ xatos(const char *token)
 {
     long port = xatol(token);
 
-    if (port & ~0xFFFF)
+    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,33 +148,72 @@ int64_t
 GetInteger64(void)
 {
     char *token = strtok(NULL, w_space);
-    int i;
 
     if (token == NULL)
         self_destruct();
 
-    i = strtoll(token, NULL, 10);
-
-    return i;
+    return xatoll(token, 10);
 }
 
+/*
+ * 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);
+    char *token = ConfigParser::strtokFile();
     int i;
 
     if (token == NULL)
         self_destruct();
 
-    // %i honors 0 and 0x prefixes, which are important for things like umask
-    if (sscanf(token, "%i", &i) != 1)
+    // The conversion must honor 0 and 0x prefixes, which are important for things like umask
+    int64_t ret = xatoll(token, 0);
+
+    i = (int) ret;
+    if (ret != static_cast<int64_t>(i)) {
+        debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "' is larger than the type 'int'.");
         self_destruct();
+    }
 
     return i;
 }
 
-u_short
+/*
+ * 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 (!token) {
+        debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: A percentage value is missing.");
+        self_destruct();
+    }
+
+    //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)
 {
     char *token = strtok(NULL, w_space);
@@ -162,7 +265,7 @@ StringToInt64(const char *s, int64_t &result, const char **p, int base)
 }
 
 bool
-GetHostWithPort(char *token, IpAddress *ipa)
+GetHostWithPort(char *token, Ip::Address *ipa)
 {
     char *t;
     char *host;
@@ -172,33 +275,31 @@ GetHostWithPort(char *token, IpAddress *ipa)
     host = NULL;
     port = 0;
 
-#if USE_IPV6
     if (*token == '[') {
         /* [host]:port */
         host = token + 1;
         t = strchr(host, ']');
         if (!t)
             return false;
-        *t++ = '\0';
+        *t = '\0';
+        ++t;
         if (*t != ':')
             return false;
         port = xatos(t + 1);
-    } else
-#endif
-        if ((t = strchr(token, ':'))) {
-            /* host:port */
-            host = token;
-            *t = '\0';
-            port = xatos(t + 1);
-
-            if (0 == port)
-                return false;
-        } else if ((port = strtol(token, &tmp, 10)), !*tmp) {
-            /* port */
-        } else {
-            host = token;
-            port = 0;
-        }
+    } else if ((t = strchr(token, ':'))) {
+        /* host:port */
+        host = token;
+        *t = '\0';
+        port = xatos(t + 1);
+
+        if (0 == port)
+            return false;
+    } else if (strtol(token, &tmp, 10) && !*tmp) {
+        port = xatos(token);
+    } else {
+        host = token;
+        port = 0;
+    }
 
     if (NULL == host)
         ipa->SetAnyAddr();