libluna: If allowing garbage chars while decoding Base64, skip them after the padding instead of erroring out

This commit is contained in:
apio 2023-04-26 22:32:24 +02:00
parent fb22e14524
commit e1ac9473a2
Signed by: apio
GPG Key ID: B8A7D06E42258954
2 changed files with 32 additions and 3 deletions

View File

@ -97,11 +97,23 @@ namespace Base64
char* padding = strchr(data.chars(), '=');
if (padding)
{
padding++;
// If the string ends with padding, it must be either one or two equals signs.
if (padding[1] != '=' && padding[1] != '\0') return err(EINVAL);
if (padding[1])
if (*padding != '=' && *padding != '\0') return err(EINVAL);
if (*padding) padding++;
// After that, only thing allowed is newline (and garbage characters if those are permitted)
while (*padding)
{
if (padding[strspn(&padding[2], "\n") + 2]) return err(EINVAL);
char c = *padding;
padding++;
if (c == '\n') continue;
if (_isalnum(c) || c == '+' || c == '/' || c == '=') return err(EINVAL);
if (!allow_garbage_chars) return err(EINVAL);
}
}

View File

@ -130,6 +130,22 @@ TestResult test_base64_skip_garbage_chars_if_allowed()
test_success;
}
TestResult test_base64_skip_garbage_chars_if_allowed_after_padding()
{
auto rc = Base64::decode_string("YWJjZA==\n?-"_sv, true);
if (rc.has_error())
{
validate(rc.error() != EINVAL);
return rc.release_error();
}
auto decoded = rc.release_value();
validate(decoded.view() == "abcd"_sv);
test_success;
}
Result<void> test_main()
{
test_prelude;
@ -144,6 +160,7 @@ Result<void> test_main()
run_test(test_base64_disallow_characters_after_padding);
run_test(test_base64_disallow_garbage_chars_by_default);
run_test(test_base64_skip_garbage_chars_if_allowed);
run_test(test_base64_skip_garbage_chars_if_allowed_after_padding);
return {};
}