Browse Source

[trac838] counter proposal to the "dereferencing end iterator" (and related) problem:
- added more detailed comments about the exception
- removed the now unnecessary check for *base_ (against PADDING CHAR) when in_pad_
- handled beginning spaces correctly

JINMEI Tatuya 14 years ago
parent
commit
45fb91884d
2 changed files with 23 additions and 7 deletions
  1. 18 7
      src/lib/util/encode/base_n.cc
  2. 5 0
      src/lib/util/tests/base32hex_unittest.cc

+ 18 - 7
src/lib/util/encode/base_n.cc

@@ -160,23 +160,34 @@ public:
         base_zero_code_(base_zero_code),
         base_(base), base_beginpad_(base_beginpad), base_end_(base_end),
         in_pad_(false)
-    {}
+    {
+        // Skip beginning spaces, if any.  We need do it here because
+        // otherwise the first call to operator*() would be confused.
+        skipSpaces();
+    }
     DecodeNormalizer& operator++() {
         ++base_;
-        while (base_ != base_end_ && (*base_ > 0) && isspace(*base_)) {
-            ++base_;
-        }
+        skipSpaces();
         if (base_ == base_beginpad_) {
             in_pad_ = true;
         }
         return (*this);
     }
+    void skipSpaces() {
+        while (base_ != base_end_ && (*base_ > 0) && isspace(*base_)) {
+            ++base_;
+        }
+    }
     const char& operator*() const {
         if (base_ == base_end_) {
-            isc_throw(BadValue, "dereference the end iterator");
+            // binary_from_baseX calls this operator when it needs more bits
+            // even if the internal iterator (base_) has reached its end
+            // (if that happens it means the input is an incomplete baseX
+            // string and should be rejected).  So this is the only point
+            // we can catch and reject this type of invalid input.
+            isc_throw(BadValue, "Unexpected end of input in BASE decoder");
         }
-
-        if (in_pad_ && *base_ == BASE_PADDING_CHAR) {
+        if (in_pad_) {
             return (base_zero_code_);
         } else {
             return (*base_);

+ 5 - 0
src/lib/util/tests/base32hex_unittest.cc

@@ -79,6 +79,11 @@ TEST_F(Base32HexTest, decode) {
     // whitespace should be allowed
     decodeCheck("CP NM\tUOG=", decoded_data, "foob");
     decodeCheck("CPNMU===\n", decoded_data, "foo");
+    decodeCheck("  CP NM\tUOG=", decoded_data, "foob");
+    decodeCheck(" ", decoded_data, "");
+
+    // Incomplete input
+    EXPECT_THROW(decodeBase32Hex("CPNMUOJ", decoded_data), BadValue);
 
     // invalid number of padding characters
     EXPECT_THROW(decodeBase32Hex("CPNMU0==", decoded_data), BadValue);