]> git.stg.codes - stg.git/blob - tests/test_bfstream.cpp
Fix build on Darwin.
[stg.git] / tests / test_bfstream.cpp
1 #define BOOST_TEST_MODULE STGBFStream
2
3 #include "longstring.h"
4
5 #include "stg/bfstream.h"
6
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
14
15 #include <algorithm>
16 #include <string>
17 #include <cstring>
18 #include <cstdint>
19
20 namespace
21 {
22
23 class Tracker
24 {
25     public:
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)
29         {
30             delete[] m_lastBlock;
31             if (size > 0)
32             {
33                 m_lastBlock = new char[size];
34                 memcpy(m_lastBlock,  block, size);
35                 m_result.append(m_lastBlock, size);
36             }
37             else
38                 m_lastBlock = NULL;
39             m_lastSize = size;
40             ++m_callCount;
41         }
42         size_t LastSize() const { return m_lastSize; }
43         size_t CallCount() const { return m_callCount; }
44         const void* LastBlock() const { return m_lastBlock; }
45
46         const std::string& Result() const { return m_result; }
47
48     private:
49         size_t m_lastSize;
50         size_t m_callCount;
51         char* m_lastBlock;
52
53         std::string m_result;
54 };
55
56 bool DecryptCallback(const void* block, size_t size, void* data);
57
58 class Decryptor
59 {
60     public:
61         Decryptor(const std::string& key)
62             : m_stream(key, DecryptCallback, this)
63         {}
64
65         void Call(const void* block, size_t size)
66         {
67             m_stream.Put(block, size);
68         }
69
70         void Put(const void* block, size_t size)
71         {
72             const auto* data = static_cast<const char*>(block);
73             size = strnlen(data, size);
74             m_result.append(data, size);
75         }
76
77         void Flush()
78         {
79             m_stream.Put(NULL, 0);
80         }
81
82         const std::string & Result() const { return m_result; }
83
84     private:
85         STG::DECRYPT_STREAM m_stream;
86         std::string m_result;
87 };
88
89 bool EncryptCallback(const void* block, size_t size, void* data)
90 {
91     auto& decryptor = *static_cast<Decryptor*>(data);
92     decryptor.Call(block, size);
93     return true;
94 }
95
96 bool DecryptCallback(const void* block, size_t size, void* data)
97 {
98     auto& decryptor = *static_cast<Decryptor*>(data);
99     decryptor.Put(block, size);
100     return true;
101 }
102
103 bool Callback(const void* block, size_t size, void* data)
104 {
105     auto& tracker = *static_cast<Tracker*>(data);
106     tracker.Call(block, size);
107     return true;
108 }
109
110 }
111
112 BOOST_AUTO_TEST_SUITE(BFStream)
113
114 BOOST_AUTO_TEST_CASE(Mechanics)
115 {
116     Tracker tracker;
117     STG::ENCRYPT_STREAM stream("pr7Hhen", Callback, &tracker);
118     BOOST_CHECK_EQUAL(tracker.CallCount(), 0);
119
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);
125
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);
131 }
132
133 BOOST_AUTO_TEST_CASE(Encryption)
134 {
135     Tracker tracker;
136     STG::ENCRYPT_STREAM stream("pr7Hhen", Callback, &tracker);
137
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);
147
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);
154
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);
160 }
161
162 BOOST_AUTO_TEST_CASE(LongStringProcessing)
163 {
164     Tracker tracker;
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);
168
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()));
173
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()));
179
180     BOOST_CHECK_EQUAL(std::string(buffer.data()), source);
181 }
182
183 BOOST_AUTO_TEST_CASE(VeryLongStringProcessing)
184 {
185     Decryptor decryptor("pr7Hhen");
186     STG::ENCRYPT_STREAM estream("pr7Hhen", EncryptCallback, &decryptor);
187
188     estream.Put(longString.c_str(), longString.length() + 1, true);
189
190     BOOST_CHECK_EQUAL(decryptor.Result(), longString);
191 }
192
193 BOOST_AUTO_TEST_CASE(Mechanics2)
194 {
195     Tracker tracker;
196     STG::ENCRYPT_STREAM stream("pr7Hhen", Callback, &tracker);
197     BOOST_CHECK_EQUAL(tracker.CallCount(), 0);
198
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);
206 }
207
208 BOOST_AUTO_TEST_SUITE_END()