diff --git a/src/binary.cpp b/src/binary.cpp index d27762a24..f37cd52f7 100644 --- a/src/binary.cpp +++ b/src/binary.cpp @@ -74,7 +74,8 @@ std::vector DecodeBase64(const std::string &input) { unsigned char *out = &ret[0]; unsigned value = 0; - for (std::size_t i = 0, cnt = 0; i < input.size(); i++) { + std::size_t cnt = 0; + for (std::size_t i = 0; i < input.size(); i++) { if (std::isspace(static_cast(input[i]))) { // skip newlines continue; @@ -84,15 +85,20 @@ std::vector DecodeBase64(const std::string &input) { return ret_type(); value = (value << 6) | d; - if (cnt % 4 == 3) { + if (cnt == 3) { *out++ = value >> 16; if (i > 0 && input[i - 1] != '=') *out++ = value >> 8; if (input[i] != '=') *out++ = value; + cnt = 0; + } else { + ++cnt; } - ++cnt; } + // An invalid number of characters were encountered. + if (cnt != 0) + return ret_type(); ret.resize(out - &ret[0]); return ret; diff --git a/test/binary_test.cpp b/test/binary_test.cpp index 7b17823f8..650bc6fb0 100644 --- a/test/binary_test.cpp +++ b/test/binary_test.cpp @@ -12,3 +12,10 @@ TEST(BinaryTest, DecodingNoCrashOnNegative) { const std::vector &result = YAML::DecodeBase64(input); EXPECT_TRUE(result.empty()); } + +TEST(BinaryTest, DecodingIncompleteString) { + // Note: the number of bytes is *not* a multiple of four. + std::string input{90, 71, 86, 104, 90}; + const std::vector &result = YAML::DecodeBase64(input); + EXPECT_TRUE(result.empty()); +}