Skip to content

Commit

Permalink
Utils: is_base64url.
Browse files Browse the repository at this point in the history
GitOrigin-RevId: b58daeb9fa82d37e9c653d72ef702bcb15a5392b
  • Loading branch information
levlam committed Jan 19, 2018
1 parent c816837 commit 22ad865
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 23 deletions.
44 changes: 31 additions & 13 deletions tdutils/td/utils/base64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,11 +188,8 @@ Result<string> base64url_decode(Slice base64) {
return output;
}

bool is_base64(Slice input) {
if ((input.size() & 3) != 0) {
return false;
}

template <bool is_url>
static bool is_base64_impl(Slice input) {
size_t padding_length = 0;
while (!input.empty() && input.back() == '=') {
input.remove_suffix(1);
Expand All @@ -201,22 +198,35 @@ bool is_base64(Slice input) {
if (padding_length >= 3) {
return false;
}
if ((!is_url || padding_length > 0) && ((input.size() + padding_length) & 3) != 0) {
return false;
}
if (is_url && (input.size() & 3) == 1) {
return false;
}

init_base64_table();
for (size_t i = 0; i < input.size(); i++) {
if (char_to_value[input.ubegin()[i]] == 64) {
unsigned char *table;
if (is_url) {
init_base64url_table();
table = url_char_to_value;
} else {
init_base64_table();
table = char_to_value;
}
for (auto c:input) {
if (table[static_cast<unsigned char>(c)] == 64) {
return false;
}
}

if ((input.size() & 3) == 2) {
auto value = char_to_value[input.back()];
auto value = table[input.back()];
if ((value & 15) != 0) {
return false;
}
}
if ((input.size() & 3) == 3) {
auto value = char_to_value[input.back()];
auto value = table[input.back()];
if ((value & 3) != 0) {
return false;
}
Expand All @@ -225,13 +235,21 @@ bool is_base64(Slice input) {
return true;
}

bool is_base64(Slice input) {
return is_base64_impl<false>(input);
}

bool is_base64url(Slice input) {
return is_base64_impl<true>(input);
}

string base64_filter(Slice input) {
string res;
res.reserve(input.size());
init_base64_table();
for (size_t i = 0; i < input.size(); i++) {
if (char_to_value[input.ubegin()[i]] != 64 || input[i] == '=') {
res += input[i];
for (auto c : input) {
if (char_to_value[static_cast<unsigned char>(c)] != 64 || c == '=') {
res += c;
}
}
return res;
Expand Down
1 change: 1 addition & 0 deletions tdutils/td/utils/base64.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ string base64url_encode(Slice input);
Result<string> base64url_decode(Slice base64);

bool is_base64(Slice input);
bool is_base64url(Slice input);

string base64_filter(Slice input);

Expand Down
34 changes: 24 additions & 10 deletions tdutils/test/misc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,30 @@ TEST(Misc, errno_tls_bug) {
}

TEST(Misc, base64) {
ASSERT_TRUE(is_base64("dGVzdA==") == true);
ASSERT_TRUE(is_base64("dGVzdB==") == false);
ASSERT_TRUE(is_base64("dGVzdA=") == false);
ASSERT_TRUE(is_base64("dGVzdA") == false);
ASSERT_TRUE(is_base64("dGVz") == true);
ASSERT_TRUE(is_base64("") == true);
ASSERT_TRUE(is_base64("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/") == true);
ASSERT_TRUE(is_base64("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=") == false);
ASSERT_TRUE(is_base64("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-/") == false);
ASSERT_TRUE(is_base64("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_") == false);
ASSERT_TRUE(is_base64("====") == false);

ASSERT_TRUE(is_base64url("dGVzdA==") == true);
ASSERT_TRUE(is_base64url("dGVzdB==") == false);
ASSERT_TRUE(is_base64url("dGVzdA=") == false);
ASSERT_TRUE(is_base64url("dGVzdA") == true);
ASSERT_TRUE(is_base64url("dGVz") == true);
ASSERT_TRUE(is_base64url("") == true);
ASSERT_TRUE(is_base64url("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_") == true);
ASSERT_TRUE(is_base64url("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=") == false);
ASSERT_TRUE(is_base64url("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-/") == false);
ASSERT_TRUE(is_base64url("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/") == false);
ASSERT_TRUE(is_base64url("====") == false);

for (int l = 0; l < 300000; l += l / 20 + l / 1000 * 500 + 1) {
for (int t = 0; t < 10; t++) {
string s = rand_string(std::numeric_limits<char>::min(), std::numeric_limits<char>::max(), l);
Expand All @@ -139,16 +163,6 @@ TEST(Misc, base64) {
ASSERT_TRUE(base64_encode(" /'.;.';≤.];,].',[.;/,.;/]/..;!@#!*(%?::;!%\";") ==
"ICAgICAgLycuOy4nO+KJpC5dOyxdLicsWy47LywuOy9dLy4uOyFAIyEqKCU/"
"Ojo7ISUiOw==");
ASSERT_TRUE(is_base64("dGVzdA==") == true);
ASSERT_TRUE(is_base64("dGVzdB==") == false);
ASSERT_TRUE(is_base64("dGVzdA=") == false);
ASSERT_TRUE(is_base64("dGVzdA") == false);
ASSERT_TRUE(is_base64("dGVz") == true);
ASSERT_TRUE(is_base64("") == true);
ASSERT_TRUE(is_base64("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/") == true);
ASSERT_TRUE(is_base64("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=") == false);
ASSERT_TRUE(is_base64("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-/") == false);
ASSERT_TRUE(is_base64("====") == false);
}

TEST(Misc, to_integer) {
Expand Down

0 comments on commit 22ad865

Please sign in to comment.