Compare commits
2 Commits
fb22e14524
...
7c8f195088
Author | SHA1 | Date | |
---|---|---|---|
7c8f195088 | |||
e1ac9473a2 |
@ -12,7 +12,7 @@ Result<int> luna_main(int argc, char** argv)
|
|||||||
parser.add_description("Encode or decode Base64 data. If not given a file, reads from standard input.");
|
parser.add_description("Encode or decode Base64 data. If not given a file, reads from standard input.");
|
||||||
parser.add_positional_argument(path, "file", "-"_sv);
|
parser.add_positional_argument(path, "file", "-"_sv);
|
||||||
parser.add_switch_argument(decode, 'd', "decode", "decode data");
|
parser.add_switch_argument(decode, 'd', "decode", "decode data");
|
||||||
parser.add_switch_argument(allow_garbage, ' ', "allow-garbage", "ignore non-base64 characters");
|
parser.add_switch_argument(allow_garbage, 'i', "ignore-garbage", "when decoding, ignore non-base64 characters");
|
||||||
parser.parse(argc, argv);
|
parser.parse(argc, argv);
|
||||||
|
|
||||||
auto file = TRY(os::File::open_input_file(path));
|
auto file = TRY(os::File::open_input_file(path));
|
||||||
|
@ -97,11 +97,23 @@ namespace Base64
|
|||||||
char* padding = strchr(data.chars(), '=');
|
char* padding = strchr(data.chars(), '=');
|
||||||
if (padding)
|
if (padding)
|
||||||
{
|
{
|
||||||
|
padding++;
|
||||||
// If the string ends with padding, it must be either one or two equals signs.
|
// 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 != '=' && *padding != '\0') return err(EINVAL);
|
||||||
if (padding[1])
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,6 +130,22 @@ TestResult test_base64_skip_garbage_chars_if_allowed()
|
|||||||
test_success;
|
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()
|
Result<void> test_main()
|
||||||
{
|
{
|
||||||
test_prelude;
|
test_prelude;
|
||||||
@ -144,6 +160,7 @@ Result<void> test_main()
|
|||||||
run_test(test_base64_disallow_characters_after_padding);
|
run_test(test_base64_disallow_characters_after_padding);
|
||||||
run_test(test_base64_disallow_garbage_chars_by_default);
|
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);
|
||||||
|
run_test(test_base64_skip_garbage_chars_if_allowed_after_padding);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user