2015-12-13 14:51:43 +01:00
|
|
|
// Copyright (c) 2012-2015 The Bitcoin Core developers
|
2015-09-08 00:22:23 +02:00
|
|
|
// Distributed under the MIT software license, see the accompanying
|
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
|
2020-03-19 23:46:56 +01:00
|
|
|
#include <streams.h>
|
|
|
|
#include <support/allocators/zeroafterfree.h>
|
|
|
|
#include <test/test_dash.h>
|
2015-09-08 00:22:23 +02:00
|
|
|
|
|
|
|
#include <boost/test/unit_test.hpp>
|
2017-01-05 11:31:56 +01:00
|
|
|
|
2015-09-08 00:22:23 +02:00
|
|
|
BOOST_FIXTURE_TEST_SUITE(streams_tests, BasicTestingSetup)
|
|
|
|
|
2016-11-25 20:01:56 +01:00
|
|
|
BOOST_AUTO_TEST_CASE(streams_vector_writer)
|
|
|
|
{
|
|
|
|
unsigned char a(1);
|
|
|
|
unsigned char b(2);
|
|
|
|
unsigned char bytes[] = { 3, 4, 5, 6 };
|
|
|
|
std::vector<unsigned char> vch;
|
|
|
|
|
|
|
|
// Each test runs twice. Serializing a second time at the same starting
|
|
|
|
// point should yield the same results, even if the first test grew the
|
|
|
|
// vector.
|
|
|
|
|
|
|
|
CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 0, a, b);
|
|
|
|
BOOST_CHECK((vch == std::vector<unsigned char>{{1, 2}}));
|
|
|
|
CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 0, a, b);
|
|
|
|
BOOST_CHECK((vch == std::vector<unsigned char>{{1, 2}}));
|
|
|
|
vch.clear();
|
|
|
|
|
|
|
|
CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, b);
|
|
|
|
BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 1, 2}}));
|
|
|
|
CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, b);
|
|
|
|
BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 1, 2}}));
|
|
|
|
vch.clear();
|
|
|
|
|
|
|
|
vch.resize(5, 0);
|
|
|
|
CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, b);
|
|
|
|
BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 1, 2, 0}}));
|
|
|
|
CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, b);
|
|
|
|
BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 1, 2, 0}}));
|
|
|
|
vch.clear();
|
|
|
|
|
|
|
|
vch.resize(4, 0);
|
|
|
|
CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 3, a, b);
|
|
|
|
BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 0, 1, 2}}));
|
|
|
|
CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 3, a, b);
|
|
|
|
BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 0, 1, 2}}));
|
|
|
|
vch.clear();
|
|
|
|
|
|
|
|
vch.resize(4, 0);
|
|
|
|
CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 4, a, b);
|
|
|
|
BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 0, 0, 1, 2}}));
|
|
|
|
CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 4, a, b);
|
|
|
|
BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 0, 0, 1, 2}}));
|
|
|
|
vch.clear();
|
|
|
|
|
2018-03-30 13:10:00 +02:00
|
|
|
CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 0, bytes);
|
2016-11-25 20:01:56 +01:00
|
|
|
BOOST_CHECK((vch == std::vector<unsigned char>{{3, 4, 5, 6}}));
|
2018-03-30 13:10:00 +02:00
|
|
|
CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 0, bytes);
|
2016-11-25 20:01:56 +01:00
|
|
|
BOOST_CHECK((vch == std::vector<unsigned char>{{3, 4, 5, 6}}));
|
|
|
|
vch.clear();
|
|
|
|
|
|
|
|
vch.resize(4, 8);
|
2018-03-30 13:10:00 +02:00
|
|
|
CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, bytes, b);
|
2016-11-25 20:01:56 +01:00
|
|
|
BOOST_CHECK((vch == std::vector<unsigned char>{{8, 8, 1, 3, 4, 5, 6, 2}}));
|
2018-03-30 13:10:00 +02:00
|
|
|
CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, bytes, b);
|
2016-11-25 20:01:56 +01:00
|
|
|
BOOST_CHECK((vch == std::vector<unsigned char>{{8, 8, 1, 3, 4, 5, 6, 2}}));
|
|
|
|
vch.clear();
|
|
|
|
}
|
|
|
|
|
2018-08-26 16:57:01 +02:00
|
|
|
BOOST_AUTO_TEST_CASE(streams_vector_reader)
|
|
|
|
{
|
|
|
|
std::vector<unsigned char> vch = {1, 255, 3, 4, 5, 6};
|
|
|
|
|
|
|
|
VectorReader reader(SER_NETWORK, INIT_PROTO_VERSION, vch, 0);
|
|
|
|
BOOST_CHECK_EQUAL(reader.size(), 6);
|
|
|
|
BOOST_CHECK(!reader.empty());
|
|
|
|
|
|
|
|
// Read a single byte as an unsigned char.
|
|
|
|
unsigned char a;
|
|
|
|
reader >> a;
|
|
|
|
BOOST_CHECK_EQUAL(a, 1);
|
|
|
|
BOOST_CHECK_EQUAL(reader.size(), 5);
|
|
|
|
BOOST_CHECK(!reader.empty());
|
|
|
|
|
|
|
|
// Read a single byte as a signed char.
|
|
|
|
signed char b;
|
|
|
|
reader >> b;
|
|
|
|
BOOST_CHECK_EQUAL(b, -1);
|
|
|
|
BOOST_CHECK_EQUAL(reader.size(), 4);
|
|
|
|
BOOST_CHECK(!reader.empty());
|
|
|
|
|
|
|
|
// Read a 4 bytes as an unsigned int.
|
|
|
|
unsigned int c;
|
|
|
|
reader >> c;
|
|
|
|
BOOST_CHECK_EQUAL(c, 100992003); // 3,4,5,6 in little-endian base-256
|
|
|
|
BOOST_CHECK_EQUAL(reader.size(), 0);
|
|
|
|
BOOST_CHECK(reader.empty());
|
|
|
|
|
|
|
|
// Reading after end of byte vector throws an error.
|
|
|
|
signed int d;
|
|
|
|
BOOST_CHECK_THROW(reader >> d, std::ios_base::failure);
|
|
|
|
|
|
|
|
// Read a 4 bytes as a signed int from the beginning of the buffer.
|
|
|
|
reader.seek(-6);
|
|
|
|
reader >> d;
|
|
|
|
BOOST_CHECK_EQUAL(d, 67370753); // 1,255,3,4 in little-endian base-256
|
|
|
|
BOOST_CHECK_EQUAL(reader.size(), 2);
|
|
|
|
BOOST_CHECK(!reader.empty());
|
|
|
|
|
|
|
|
// Reading after end of byte vector throws an error even if the reader is
|
|
|
|
// not totally empty.
|
|
|
|
BOOST_CHECK_THROW(reader >> d, std::ios_base::failure);
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(bitstream_reader_writer)
|
|
|
|
{
|
|
|
|
CDataStream data(SER_NETWORK, INIT_PROTO_VERSION);
|
|
|
|
|
|
|
|
BitStreamWriter<CDataStream> bit_writer(data);
|
|
|
|
bit_writer.Write(0, 1);
|
|
|
|
bit_writer.Write(2, 2);
|
|
|
|
bit_writer.Write(6, 3);
|
|
|
|
bit_writer.Write(11, 4);
|
|
|
|
bit_writer.Write(1, 5);
|
|
|
|
bit_writer.Write(32, 6);
|
|
|
|
bit_writer.Write(7, 7);
|
|
|
|
bit_writer.Write(30497, 16);
|
|
|
|
bit_writer.Flush();
|
|
|
|
|
|
|
|
CDataStream data_copy(data);
|
|
|
|
uint32_t serialized_int1;
|
|
|
|
data >> serialized_int1;
|
|
|
|
BOOST_CHECK_EQUAL(serialized_int1, (uint32_t)0x7700C35A); // NOTE: Serialized as LE
|
|
|
|
uint16_t serialized_int2;
|
|
|
|
data >> serialized_int2;
|
|
|
|
BOOST_CHECK_EQUAL(serialized_int2, (uint16_t)0x1072); // NOTE: Serialized as LE
|
|
|
|
|
|
|
|
BitStreamReader<CDataStream> bit_reader(data_copy);
|
|
|
|
BOOST_CHECK_EQUAL(bit_reader.Read(1), 0);
|
|
|
|
BOOST_CHECK_EQUAL(bit_reader.Read(2), 2);
|
|
|
|
BOOST_CHECK_EQUAL(bit_reader.Read(3), 6);
|
|
|
|
BOOST_CHECK_EQUAL(bit_reader.Read(4), 11);
|
|
|
|
BOOST_CHECK_EQUAL(bit_reader.Read(5), 1);
|
|
|
|
BOOST_CHECK_EQUAL(bit_reader.Read(6), 32);
|
|
|
|
BOOST_CHECK_EQUAL(bit_reader.Read(7), 7);
|
|
|
|
BOOST_CHECK_EQUAL(bit_reader.Read(16), 30497);
|
|
|
|
BOOST_CHECK_THROW(bit_reader.Read(8), std::ios_base::failure);
|
|
|
|
}
|
|
|
|
|
2015-09-08 00:22:23 +02:00
|
|
|
BOOST_AUTO_TEST_CASE(streams_serializedata_xor)
|
|
|
|
{
|
|
|
|
std::vector<char> in;
|
|
|
|
std::vector<char> expected_xor;
|
|
|
|
std::vector<unsigned char> key;
|
|
|
|
CDataStream ds(in, 0, 0);
|
|
|
|
|
|
|
|
// Degenerate case
|
2020-07-29 03:23:12 +02:00
|
|
|
|
2018-06-29 12:29:54 +02:00
|
|
|
key.push_back('\x00');
|
|
|
|
key.push_back('\x00');
|
2015-09-08 00:22:23 +02:00
|
|
|
ds.Xor(key);
|
|
|
|
BOOST_CHECK_EQUAL(
|
2020-07-29 03:23:12 +02:00
|
|
|
std::string(expected_xor.begin(), expected_xor.end()),
|
2015-09-08 00:22:23 +02:00
|
|
|
std::string(ds.begin(), ds.end()));
|
|
|
|
|
2018-06-29 12:29:54 +02:00
|
|
|
in.push_back('\x0f');
|
|
|
|
in.push_back('\xf0');
|
|
|
|
expected_xor.push_back('\xf0');
|
|
|
|
expected_xor.push_back('\x0f');
|
2020-07-29 03:23:12 +02:00
|
|
|
|
2015-09-08 00:22:23 +02:00
|
|
|
// Single character key
|
|
|
|
|
|
|
|
ds.clear();
|
|
|
|
ds.insert(ds.begin(), in.begin(), in.end());
|
|
|
|
key.clear();
|
|
|
|
|
2018-06-29 12:29:54 +02:00
|
|
|
key.push_back('\xff');
|
2015-09-08 00:22:23 +02:00
|
|
|
ds.Xor(key);
|
|
|
|
BOOST_CHECK_EQUAL(
|
2020-07-29 03:23:12 +02:00
|
|
|
std::string(expected_xor.begin(), expected_xor.end()),
|
|
|
|
std::string(ds.begin(), ds.end()));
|
|
|
|
|
2015-09-08 00:22:23 +02:00
|
|
|
// Multi character key
|
|
|
|
|
|
|
|
in.clear();
|
|
|
|
expected_xor.clear();
|
2018-06-29 12:29:54 +02:00
|
|
|
in.push_back('\xf0');
|
|
|
|
in.push_back('\x0f');
|
|
|
|
expected_xor.push_back('\x0f');
|
|
|
|
expected_xor.push_back('\x00');
|
2020-07-29 03:23:12 +02:00
|
|
|
|
2015-09-08 00:22:23 +02:00
|
|
|
ds.clear();
|
|
|
|
ds.insert(ds.begin(), in.begin(), in.end());
|
|
|
|
|
|
|
|
key.clear();
|
2018-06-29 12:29:54 +02:00
|
|
|
key.push_back('\xff');
|
|
|
|
key.push_back('\x0f');
|
2015-09-08 00:22:23 +02:00
|
|
|
|
|
|
|
ds.Xor(key);
|
|
|
|
BOOST_CHECK_EQUAL(
|
2020-07-29 03:23:12 +02:00
|
|
|
std::string(expected_xor.begin(), expected_xor.end()),
|
|
|
|
std::string(ds.begin(), ds.end()));
|
|
|
|
}
|
2015-09-08 00:22:23 +02:00
|
|
|
|
|
|
|
BOOST_AUTO_TEST_SUITE_END()
|