Repository: mesos
Updated Branches:
  refs/heads/master 1ebb62b7b -> 584301f99


Updated base64::decode to reject forbidden characters.

Review: https://reviews.apache.org/r/37556


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/57e93896
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/57e93896
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/57e93896

Branch: refs/heads/master
Commit: 57e93896c3cc39615c78d80e3a929d9987a6309d
Parents: 1ebb62b
Author: Benjamin Mahler <[email protected]>
Authored: Mon Aug 17 15:10:20 2015 -0700
Committer: Benjamin Mahler <[email protected]>
Committed: Mon Aug 17 17:05:24 2015 -0700

----------------------------------------------------------------------
 .../3rdparty/stout/include/stout/base64.hpp     | 38 +++++++++++++-------
 .../3rdparty/stout/tests/base64_tests.cpp       | 22 ++++++++++--
 2 files changed, 45 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/57e93896/3rdparty/libprocess/3rdparty/stout/include/stout/base64.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/base64.hpp 
b/3rdparty/libprocess/3rdparty/stout/include/stout/base64.hpp
index 110cb49..4893e7b 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/base64.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/base64.hpp
@@ -15,8 +15,13 @@
 #define __STOUT_BASE64_HPP__
 
 #include <cctype>
+#include <functional>
 #include <string>
 
+#include <stout/foreach.hpp>
+#include <stout/stringify.hpp>
+#include <stout/try.hpp>
+
 namespace base64 {
 
 // This slightly modified base64 implementation from
@@ -29,12 +34,6 @@ static const std::string chars =
   "0123456789+/";
 
 
-static inline bool isBase64(unsigned char c)
-{
-  return (isalnum(c) || (c == '+') || (c == '/'));
-}
-
-
 inline std::string encode(const std::string& s)
 {
   std::string result;
@@ -79,19 +78,30 @@ inline std::string encode(const std::string& s)
 }
 
 
-inline std::string decode(const std::string& s)
+inline Try<std::string> decode(const std::string& s)
 {
-  size_t length = s.size();
+  auto isBase64 = [](unsigned char c) -> bool {
+    return (isalnum(c) || (c == '+') || (c == '/'));
+  };
+
   size_t i = 0;
-  size_t j = 0;
-  int index = 0;
   unsigned char array3[3];
   unsigned char array4[4];
   std::string result;
 
-  while (length-- && (s[index] != '=') && isBase64(s[index])) {
-    array4[i++] = s[index];
-    index++;
+  foreach (unsigned char c, s) {
+    if (c == '=') {
+      // TODO(bmahler): Note that this does not validate that
+      // there are the correct number of '=' characters!
+      break; // Reached the padding.
+    }
+
+    if (!isBase64(c)) {
+      return Error("Invalid character '" + stringify(c) + "'");
+    }
+
+    array4[i++] = c;
+
     if (i == 4) {
       for (i = 0; i < 4; i++) {
         array4[i] = static_cast<unsigned char>(chars.find(array4[i]));
@@ -107,6 +117,8 @@ inline std::string decode(const std::string& s)
   }
 
   if (i != 0) {
+    size_t j;
+
     for (j = i; j < 4; j++) {
       array4[j] = 0;
     }

http://git-wip-us.apache.org/repos/asf/mesos/blob/57e93896/3rdparty/libprocess/3rdparty/stout/tests/base64_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/tests/base64_tests.cpp 
b/3rdparty/libprocess/3rdparty/stout/tests/base64_tests.cpp
index ff3d31b..1210f5a 100644
--- a/3rdparty/libprocess/3rdparty/stout/tests/base64_tests.cpp
+++ b/3rdparty/libprocess/3rdparty/stout/tests/base64_tests.cpp
@@ -14,15 +14,33 @@
 #include <gtest/gtest.h>
 
 #include <stout/base64.hpp>
+#include <stout/gtest.hpp>
 
 
 TEST(Base64Test, Encode)
 {
-  EXPECT_EQ("dGVzdHVzZXI6dGVzdHBhc3M=", base64::encode("testuser:testpass"));
+  EXPECT_EQ("dXNlcjpwYXNzd29yZA==", base64::encode("user:password"));
 }
 
 
 TEST(Base64Test, Decode)
 {
-  EXPECT_EQ("testuser:testpass", base64::decode("dGVzdHVzZXI6dGVzdHBhc3M="));
+  // We're able to parse without padding.
+  EXPECT_SOME_EQ("user:password", base64::decode("dXNlcjpwYXNzd29yZA=="));
+  EXPECT_SOME_EQ("user:password", base64::decode("dXNlcjpwYXNzd29yZA="));
+  EXPECT_SOME_EQ("user:password", base64::decode("dXNlcjpwYXNzd29yZA"));
+
+  // Whitespace is not allowed.
+  EXPECT_ERROR(base64::decode("d XNlcjpwYXNzd29yZA=="));
+  EXPECT_ERROR(base64::decode("d\r\nXNlcjpwYXNzd29yZA=="));
+
+  // Invalid characters.
+  EXPECT_ERROR(base64::decode("abc("));
+  EXPECT_ERROR(base64::decode(">abc"));
+  EXPECT_ERROR(base64::decode("ab,="));
+
+  // These cases are not currently validated!
+  //  EXPECT_ERROR(base64::decode("ab="));
+  //  EXPECT_ERROR(base64::decode("ab=,"));
+  //  EXPECT_ERROR(base64::decode("ab==="));
 }

Reply via email to