From ec6b754871b25b2e1e04b295bb57ff838f1bbf33 Mon Sep 17 00:00:00 2001 From: Alex Thiessen Date: Sun, 6 Sep 2026 16:59:26 +0200 Subject: [PATCH] Fix Base64 padding separated by whitespace Track the previous non-whitespace Base64 character when deciding whether padding terminates a decoded byte. This preserves YAML 1.1 !!binary decoding when whitespace appears between padding characters. Cover whitespace-separated padding with a focused test that preserves the single-byte result for the canonical padded form. Reference verification: - PyYAML 6.0.3 (YAML 1.1 !!binary, native value): matched 4d. - libyaml 0.2.5 (parser/event layer): matched the yaml-cpp event stream. --- src/binary.cpp | 4 +++- test/binary_test.cpp | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/binary.cpp b/src/binary.cpp index 6c7e687d7..aed36b692 100644 --- a/src/binary.cpp +++ b/src/binary.cpp @@ -75,6 +75,7 @@ std::vector DecodeBase64(const std::string &input) { unsigned value = 0; std::size_t cnt = 0; + bool previous_was_padding = false; for (std::size_t i = 0; i < input.size(); i++) { if (std::isspace(static_cast(input[i]))) { // skip newlines @@ -87,7 +88,7 @@ std::vector DecodeBase64(const std::string &input) { value = (value << 6) | d; if (cnt == 3) { *out++ = value >> 16; - if (i > 0 && input[i - 1] != '=') + if (!previous_was_padding) *out++ = value >> 8; if (input[i] != '=') *out++ = value; @@ -95,6 +96,7 @@ std::vector DecodeBase64(const std::string &input) { } else { ++cnt; } + previous_was_padding = input[i] == '='; } if (cnt != 0) { // An invalid number of characters were encountered. diff --git a/test/binary_test.cpp b/test/binary_test.cpp index 30e0e46b0..93c999bb0 100644 --- a/test/binary_test.cpp +++ b/test/binary_test.cpp @@ -19,6 +19,11 @@ TEST(BinaryTest, DecodingTooShort) { EXPECT_TRUE(result.empty()); } +TEST(BinaryTest, DecodingWhitespaceBetweenPadding) { + const std::vector &result = YAML::DecodeBase64("TQ= ="); + EXPECT_EQ(std::vector{'M'}, result); +} + TEST(BinaryTest, EmptyBinary) { YAML::Binary b; EXPECT_TRUE(b.size() == 0);