Browse Source

[trac998] Fix problems with address strings of "1/" etc.

Stephen Morris 14 years ago
parent
commit
d335ae50bb
2 changed files with 33 additions and 25 deletions
  1. 30 25
      src/lib/acl/ip_check.h
  2. 3 0
      src/lib/acl/tests/ip_check_unittest.cc

+ 30 - 25
src/lib/acl/ip_check.h

@@ -122,41 +122,46 @@ splitIPAddress(const std::string& prefix) {
     // is not known at the point this function is called, the maximum
     // allowable value is also not known.  And the value of 0 is reserved for
     // a "match any address" match.
-    int prefixlen = -1;
-
-    // Split string into its components.  As the tokenising code ignores
-    // leading, trailing and consecutive delimiters, be strict here and ensure
-    // that the string contains at most 0 or 1 slashes.
-    if (std::count(prefix.begin(), prefix.end(), '/') > 1) {
+    int prefix_size = -1;
+
+    // Split string into its components - an address and a prefix length.
+    // We initialize by assuming that there is no slash in the string given.
+    std::string address = prefix;
+    std::string prefixlen = "";
+
+    // Parse the string given after stripping leading and trailing spaces.
+    std::string mod_prefix = isc::util::str::trim(prefix);
+    size_t slashpos = mod_prefix.find('/');
+    if ((mod_prefix.size() == 0) || (slashpos == 0) ||
+        (slashpos == (mod_prefix.size() - 1))) {
+        // Nothing in prefix, or it starts with or ends with a slash.
         isc_throw(isc::InvalidParameter, "address prefix of " << prefix <<
                                          " is not valid");
-    }
 
-    std::vector<std::string> components = isc::util::str::tokens(prefix, "/");
-    if (components.size() == 2) {
+    } else if (slashpos != std::string::npos) {
+        // There is a slash somewhere in the string, split the string on it.
+        // Don't worry about multiple slashes - if there are some, they will
+        // appear in the prefixlen segment and will be detected when an attempt
+        // is made to convert it to a number.
+        address = mod_prefix.substr(0, slashpos);
+        prefixlen = mod_prefix.substr(slashpos + 1);
+    }
 
-        // There appears to be a prefix length, try converting it to a number.
+    // If there is a prefixlength, attempt to convert it.
+    if (!prefixlen.empty()) {
         try {
-            prefixlen = boost::lexical_cast<int>(components[1]);
+            prefix_size = boost::lexical_cast<int>(prefixlen);
+            if (prefix_size < 0) {
+                isc_throw(isc::InvalidParameter, "address prefix of " <<
+                          prefix << " is not valid");
+            }
         } catch (boost::bad_lexical_cast&) {
-            isc_throw(isc::InvalidParameter, "prefix length of " << prefix <<
+            isc_throw(isc::InvalidParameter, "prefix length of " << prefixlen <<
                                              " is not valid");
         }
-
-        // Ensure that it is positive or zero (a prefix length of zero implies
-        // an unconditional match)
-        if (prefixlen < 0) {
-            isc_throw(isc::InvalidParameter,
-                      "prefix length specified in address prefix of " <<
-                      prefix << " must not be negative");
-        }
-
-    } else if (components.size() > 2) {
-        isc_throw(isc::InvalidParameter, "address prefix of " << prefix <<
-                                         " is not valid");
     }
 
-    return (std::make_pair(components[0], prefixlen));
+    return (std::make_pair(address, prefix_size));
 }
 
 } // namespace internal

+ 3 - 0
src/lib/acl/tests/ip_check_unittest.cc

@@ -147,6 +147,9 @@ TEST(IPFunctionCheck, SplitIPAddress) {
     EXPECT_THROW(splitIPAddress("/192.0.2.43/1"), isc::InvalidParameter);
     EXPECT_THROW(splitIPAddress("2001:db8::/xxxx"), isc::InvalidParameter);
     EXPECT_THROW(splitIPAddress("2001:db8::/32/s"), isc::InvalidParameter);
+    EXPECT_THROW(splitIPAddress("1/"), isc::InvalidParameter);
+    EXPECT_THROW(splitIPAddress("/1"), isc::InvalidParameter);
+    EXPECT_THROW(splitIPAddress(" 1/ "), isc::InvalidParameter);
 }
 
 // *** General tests ***