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===")); }
