Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

keep backup of datastore file, to help recover from corruption #24

Merged
merged 3 commits into from
Apr 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,5 @@ jobs:

- run: sudo apt update && sudo apt install -y cmake

- name: Extract SecretTestValues.h
run: echo ${{ secrets.SECRET_TEST_VALUES }} | base64 -d > ./SecretTestValues.h
shell: bash

- name: test
run: bash ./test.sh
Binary file removed SecretTestValues.h.enc
Binary file not shown.
18 changes: 9 additions & 9 deletions base64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace base64 {

// From https://stackoverflow.com/a/31322410/729729

static const BYTE from_base64[] = {
static const uint8_t from_base64[] = {
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 62, 255, 63,
Expand All @@ -46,13 +46,13 @@ std::string B64Encode(const std::string& buf) {
return B64Encode((const unsigned char*)buf.c_str(), (unsigned int)buf.size());
}

std::string B64Encode(const std::vector<BYTE>& buf) {
std::string B64Encode(const std::vector<uint8_t>& buf) {
if (buf.empty())
return ""; // Avoid dereferencing buf if it's empty
return B64Encode(&buf[0], (unsigned int)buf.size());
}

std::string B64Encode(const BYTE* buf, unsigned int bufLen) {
std::string B64Encode(const uint8_t* buf, unsigned int bufLen) {
// Calculate how many bytes that needs to be added to get a multiple of 3
size_t missing = 0;
size_t ret_size = bufLen;
Expand All @@ -70,13 +70,13 @@ std::string B64Encode(const BYTE* buf, unsigned int bufLen) {
for (unsigned int i = 0; i < ret_size / 4; ++i) {
// Read a group of three bytes (avoid buffer overrun by replacing with 0)
size_t index = i * 3;
BYTE b3[3];
uint8_t b3[3];
b3[0] = (index + 0 < bufLen) ? buf[index + 0] : 0;
b3[1] = (index + 1 < bufLen) ? buf[index + 1] : 0;
b3[2] = (index + 2 < bufLen) ? buf[index + 2] : 0;

// Transform into four base 64 characters
BYTE b4[4];
uint8_t b4[4];
b4[0] = ((b3[0] & 0xfc) >> 2);
b4[1] = ((b3[0] & 0x03) << 4) + ((b3[1] & 0xf0) >> 4);
b4[2] = ((b3[1] & 0x0f) << 2) + ((b3[2] & 0xc0) >> 6);
Expand All @@ -96,27 +96,27 @@ std::string B64Encode(const BYTE* buf, unsigned int bufLen) {
return ret;
}

std::vector<BYTE> B64Decode(const std::string& b64encoded) {
std::vector<uint8_t> B64Decode(const std::string& b64encoded) {
std::string encoded_string = b64encoded;

// Make sure string length is a multiple of 4
while ((encoded_string.size() % 4) != 0)
encoded_string.push_back('=');

size_t encoded_size = encoded_string.size();
std::vector<BYTE> ret;
std::vector<uint8_t> ret;
ret.reserve(3 * encoded_size / 4);

for (size_t i = 0; i < encoded_size; i += 4) {
// Get values for each group of four base 64 characters
BYTE b4[4];
uint8_t b4[4];
b4[0] = (encoded_string[i + 0] <= 'z') ? from_base64[(size_t)encoded_string[i + 0]] : 0xff;
b4[1] = (encoded_string[i + 1] <= 'z') ? from_base64[(size_t)encoded_string[i + 1]] : 0xff;
b4[2] = (encoded_string[i + 2] <= 'z') ? from_base64[(size_t)encoded_string[i + 2]] : 0xff;
b4[3] = (encoded_string[i + 3] <= 'z') ? from_base64[(size_t)encoded_string[i + 3]] : 0xff;

// Transform into a group of three bytes
BYTE b3[3];
uint8_t b3[3];
b3[0] = ((b4[0] & 0x3f) << 2) + ((b4[1] & 0x30) >> 4);
b3[1] = ((b4[1] & 0x0f) << 4) + ((b4[2] & 0x3c) >> 2);
b3[2] = ((b4[2] & 0x03) << 6) + ((b4[3] & 0x3f) >> 0);
Expand Down
8 changes: 3 additions & 5 deletions base64.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,11 @@

namespace base64 {

typedef unsigned char BYTE;

std::string B64Encode(const std::string& buf);
std::string B64Encode(const std::vector<BYTE>& buf);
std::string B64Encode(const BYTE* buf, unsigned int bufLen);
std::string B64Encode(const std::vector<uint8_t>& buf);
std::string B64Encode(const uint8_t* buf, unsigned int bufLen);

std::vector<BYTE> B64Decode(const std::string& b64encoded);
std::vector<uint8_t> B64Decode(const std::string& b64encoded);

std::string TrimPadding(const std::string& s);

Expand Down
41 changes: 30 additions & 11 deletions base64_test.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
/*
* Copyright (c) 2022, Psiphon Inc.
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

#include "gtest/gtest.h"
#include "base64.hpp"

Expand Down Expand Up @@ -29,54 +48,54 @@ TEST(TestBase64, Encode)
ASSERT_EQ(b64, "Zm9vYmFy");

// The vector overload
vector<BYTE> v;
vector<uint8_t> v;
b64 = B64Encode(v);
ASSERT_EQ(b64, "");

BYTE b[] = "f";
v = vector<BYTE>(b, b+1);
uint8_t b[] = "f";
v = vector<uint8_t>(b, b+1);
b64 = B64Encode(v);
ASSERT_EQ(b64, "Zg==");
}

TEST(TestBase64, Decode)
{
vector<BYTE> v, want;
vector<uint8_t> v, want;
string s;

s = "";
want = vector<BYTE>(s.c_str(), s.c_str()+s.size());
want = vector<uint8_t>(s.c_str(), s.c_str()+s.size());
v = B64Decode("");
ASSERT_EQ(v, want);

s = "fo";
want = vector<BYTE>(s.c_str(), s.c_str()+s.size());
want = vector<uint8_t>(s.c_str(), s.c_str()+s.size());
v = B64Decode("Zm8=");
ASSERT_EQ(v, want);

s = "foo";
want = vector<BYTE>(s.c_str(), s.c_str()+s.size());
want = vector<uint8_t>(s.c_str(), s.c_str()+s.size());
v = B64Decode("Zm9v");
ASSERT_EQ(v, want);

s = "foob";
want = vector<BYTE>(s.c_str(), s.c_str()+s.size());
want = vector<uint8_t>(s.c_str(), s.c_str()+s.size());
v = B64Decode("Zm9vYg==");
ASSERT_EQ(v, want);

s = "fooba";
want = vector<BYTE>(s.c_str(), s.c_str()+s.size());
want = vector<uint8_t>(s.c_str(), s.c_str()+s.size());
v = B64Decode("Zm9vYmE=");
ASSERT_EQ(v, want);

s = "foobar";
want = vector<BYTE>(s.c_str(), s.c_str()+s.size());
want = vector<uint8_t>(s.c_str(), s.c_str()+s.size());
v = B64Decode("Zm9vYmFy");
ASSERT_EQ(v, want);

// Not padded
s = "foob";
want = vector<BYTE>(s.c_str(), s.c_str()+s.size());
want = vector<uint8_t>(s.c_str(), s.c_str()+s.size());
v = B64Decode("Zm9vYg");
ASSERT_EQ(v, want);
}
Expand Down
Loading