1 #define BOOST_TEST_MODULE STGBFStream
3 #include "longstring.h"
5 #include "stg/bfstream.h"
7 #pragma GCC diagnostic push
8 #pragma GCC diagnostic ignored "-Wold-style-cast"
9 #pragma GCC diagnostic ignored "-Wunused-parameter"
10 #pragma GCC diagnostic ignored "-Wsign-compare"
11 #pragma GCC diagnostic ignored "-Wparentheses"
12 #include <boost/test/unit_test.hpp>
13 #pragma GCC diagnostic pop
26 Tracker() : m_lastSize(0), m_callCount(0), m_lastBlock(NULL) {}
27 ~Tracker() { delete[] m_lastBlock; }
28 void Call(const void* block, size_t size)
33 m_lastBlock = new char[size];
34 memcpy(m_lastBlock, block, size);
35 m_result.append(m_lastBlock, size);
42 size_t LastSize() const { return m_lastSize; }
43 size_t CallCount() const { return m_callCount; }
44 const void* LastBlock() const { return m_lastBlock; }
46 const std::string& Result() const { return m_result; }
56 bool DecryptCallback(const void* block, size_t size, void* data);
61 Decryptor(const std::string& key)
62 : m_stream(key, DecryptCallback, this)
65 void Call(const void* block, size_t size)
67 m_stream.Put(block, size);
70 void Put(const void* block, size_t size)
72 const auto* data = static_cast<const char*>(block);
73 size = strnlen(data, size);
74 m_result.append(data, size);
79 m_stream.Put(NULL, 0);
82 const std::string & Result() const { return m_result; }
85 STG::DECRYPT_STREAM m_stream;
89 bool EncryptCallback(const void* block, size_t size, void* data)
91 auto& decryptor = *static_cast<Decryptor*>(data);
92 decryptor.Call(block, size);
96 bool DecryptCallback(const void* block, size_t size, void* data)
98 auto& decryptor = *static_cast<Decryptor*>(data);
99 decryptor.Put(block, size);
103 bool Callback(const void* block, size_t size, void* data)
105 auto& tracker = *static_cast<Tracker*>(data);
106 tracker.Call(block, size);
112 BOOST_AUTO_TEST_SUITE(BFStream)
114 BOOST_AUTO_TEST_CASE(Mechanics)
117 STG::ENCRYPT_STREAM stream("pr7Hhen", Callback, &tracker);
118 BOOST_CHECK_EQUAL(tracker.CallCount(), 0);
120 uint32_t block[2] = {0x12345678, 0x87654321};
121 stream.Put(&block[0], sizeof(block[0]));
122 BOOST_CHECK_EQUAL(tracker.CallCount(), 0);
123 stream.Put(&block[1], sizeof(block[1]));
124 BOOST_CHECK_EQUAL(tracker.CallCount(), 1);
126 uint32_t block2[4] = {0x12345678, 0x87654321, 0x12345678, 0x87654321};
127 stream.Put(&block2[0], sizeof(block2[0]) * 3);
128 BOOST_CHECK_EQUAL(tracker.CallCount(), 2);
129 stream.Put(&block2[3], sizeof(block2[3]));
130 BOOST_CHECK_EQUAL(tracker.CallCount(), 3);
133 BOOST_AUTO_TEST_CASE(Encryption)
136 STG::ENCRYPT_STREAM stream("pr7Hhen", Callback, &tracker);
138 uint32_t block[2] = {0x12345678, 0x87654321};
139 stream.Put(&block[0], sizeof(block[0]));
140 BOOST_CHECK_EQUAL(tracker.LastSize(), 0);
141 BOOST_CHECK_EQUAL(tracker.LastBlock(), static_cast<const void *>(NULL));
142 stream.Put(&block[1], sizeof(block[1]));
143 BOOST_CHECK_EQUAL(tracker.LastSize(), 8);
144 const uint32_t * ptr = static_cast<const uint32_t *>(tracker.LastBlock());
145 BOOST_CHECK_EQUAL(ptr[0], 0xd3988cd);
146 BOOST_CHECK_EQUAL(ptr[1], 0x7996c6d6);
148 uint32_t block2[4] = {0x12345678, 0x87654321, 0x12345678, 0x87654321};
149 stream.Put(&block2[0], sizeof(block2[0]) * 3);
150 BOOST_CHECK_EQUAL(tracker.LastSize(), 8);
151 ptr = static_cast<const uint32_t *>(tracker.LastBlock());
152 BOOST_CHECK_EQUAL(ptr[0], 0xd3988cd);
153 BOOST_CHECK_EQUAL(ptr[1], 0x7996c6d6);
155 stream.Put(&block2[3], sizeof(block2[3]));
156 BOOST_CHECK_EQUAL(tracker.LastSize(), 8);
157 ptr = static_cast<const uint32_t *>(tracker.LastBlock());
158 BOOST_CHECK_EQUAL(ptr[0], 0xd3988cd);
159 BOOST_CHECK_EQUAL(ptr[1], 0x7996c6d6);
162 BOOST_AUTO_TEST_CASE(LongStringProcessing)
165 STG::ENCRYPT_STREAM estream("pr7Hhen", Callback, &tracker);
166 const std::string source = "This is a test long string for checking stream encryption/decryption. \"abcdefghijklmnopqrstuvwxyz 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ\"";
167 std::vector<char> buffer(source.length() + 9, 0);
169 estream.Put(source.c_str(), source.length() + 1, true);
170 BOOST_CHECK(tracker.LastSize() >= source.length() + 1);
171 BOOST_CHECK(tracker.LastBlock() != NULL);
172 memcpy(buffer.data(), tracker.LastBlock(), std::min(tracker.LastSize(), buffer.size()));
174 STG::DECRYPT_STREAM dstream("pr7Hhen", Callback, &tracker);
175 dstream.Put(buffer.data(), buffer.size(), true);
176 BOOST_CHECK(tracker.LastSize() >= buffer.size());
177 BOOST_CHECK(tracker.LastBlock() != NULL);
178 memcpy(buffer.data(), tracker.LastBlock(), std::min(tracker.LastSize(), buffer.size()));
180 BOOST_CHECK_EQUAL(std::string(buffer.data()), source);
183 BOOST_AUTO_TEST_CASE(VeryLongStringProcessing)
185 Decryptor decryptor("pr7Hhen");
186 STG::ENCRYPT_STREAM estream("pr7Hhen", EncryptCallback, &decryptor);
188 estream.Put(longString.c_str(), longString.length() + 1, true);
190 BOOST_CHECK_EQUAL(decryptor.Result(), longString);
193 BOOST_AUTO_TEST_CASE(Mechanics2)
196 STG::ENCRYPT_STREAM stream("pr7Hhen", Callback, &tracker);
197 BOOST_CHECK_EQUAL(tracker.CallCount(), 0);
199 uint32_t block[2] = {0x12345678, 0x87654321};
200 stream.Put(&block[0], sizeof(block[0]));
201 BOOST_CHECK_EQUAL(tracker.CallCount(), 0);
202 stream.Put(&block[1], sizeof(block[1]));
203 BOOST_CHECK_EQUAL(tracker.CallCount(), 1);
204 stream.Put(&block[0], 0, true); // Check last callback
205 BOOST_CHECK_EQUAL(tracker.CallCount(), 2);
208 BOOST_AUTO_TEST_SUITE_END()