Skip to content

Commit 80ea002

Browse files
jwnimmer-triSeanCurtis-TRI
authored andcommitted
Fix DecodeBase64 to reject truncated input
If the input doesn't have the proper number of encoding characters (a multiple of 4), return an empty result. Co-Authored-By: Sean Curtis <sean.curtis@tri.global>
1 parent 2e6383d commit 80ea002

2 files changed

Lines changed: 16 additions & 3 deletions

File tree

src/binary.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ std::vector<unsigned char> DecodeBase64(const std::string &input) {
7474
unsigned char *out = &ret[0];
7575

7676
unsigned value = 0;
77-
for (std::size_t i = 0, cnt = 0; i < input.size(); i++) {
77+
std::size_t cnt = 0;
78+
for (std::size_t i = 0; i < input.size(); i++) {
7879
if (std::isspace(static_cast<unsigned char>(input[i]))) {
7980
// skip newlines
8081
continue;
@@ -84,14 +85,20 @@ std::vector<unsigned char> DecodeBase64(const std::string &input) {
8485
return ret_type();
8586

8687
value = (value << 6) | d;
87-
if (cnt % 4 == 3) {
88+
if (cnt == 3) {
8889
*out++ = value >> 16;
8990
if (i > 0 && input[i - 1] != '=')
9091
*out++ = value >> 8;
9192
if (input[i] != '=')
9293
*out++ = value;
94+
cnt = 0;
95+
} else {
96+
++cnt;
9397
}
94-
++cnt;
98+
}
99+
if (cnt != 0) {
100+
// An invalid number of characters were encountered.
101+
return ret_type();
95102
}
96103

97104
ret.resize(out - &ret[0]);

test/binary_test.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,9 @@ TEST(BinaryTest, DecodingNoCrashOnNegative) {
1212
const std::vector<unsigned char> &result = YAML::DecodeBase64(input);
1313
EXPECT_TRUE(result.empty());
1414
}
15+
16+
TEST(BinaryTest, DecodingTooShort) {
17+
std::string input{90, 71, 86, 104, 90, 71, 74, 108, 90, 87, 89};
18+
const std::vector<unsigned char> &result = YAML::DecodeBase64(input);
19+
EXPECT_TRUE(result.empty());
20+
}

0 commit comments

Comments
 (0)