1 /*
2 Copyright (c) 2016 Contributors as noted in the AUTHORS file
3
4 This file is part of libzmq, the ZeroMQ core engine in C++.
5
6 libzmq is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License (LGPL) as published
8 by the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 As a special exception, the Contributors give you permission to link
12 this library with independent modules to produce an executable,
13 regardless of the license terms of these independent modules, and to
14 copy and distribute the resulting executable under terms of your choice,
15 provided that you also meet, for each linked independent module, the
16 terms and conditions of the license of that module. An independent
17 module is a module which is not derived from or based on this library.
18 If you modify this library, you must extend this exception to your
19 version of the library.
20
21 libzmq is distributed in the hope that it will be useful, but WITHOUT
22 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
24 License for more details.
25
26 You should have received a copy of the GNU Lesser General Public License
27 along with this program. If not, see <http://www.gnu.org/licenses/>.
28 */
29
30 #include "testutil.hpp"
31 #include "testutil_unity.hpp"
32
setUp()33 void setUp ()
34 {
35 }
36
tearDown()37 void tearDown ()
38 {
39 }
40
41 // Test vector: rfc.zeromq.org/spec:32/Z85
test__zmq_z85_encode__valid__success()42 void test__zmq_z85_encode__valid__success ()
43 {
44 static const size_t size = 8;
45 static const size_t length = size * 5 / 4;
46 static const uint8_t decoded[size] = {0x86, 0x4F, 0xD2, 0x6F,
47 0xB5, 0x59, 0xF7, 0x5B};
48 static const char expected[length + 1] = "HelloWorld";
49 char out_encoded[length + 1] = {0};
50
51 errno = 0;
52 TEST_ASSERT_NOT_NULL (zmq_z85_encode (out_encoded, decoded, size));
53 TEST_ASSERT_EQUAL_STRING (expected, out_encoded);
54 TEST_ASSERT_EQUAL_INT (0, zmq_errno ());
55 }
56
57 // Buffer length must be evenly divisible by 4 or must fail with EINVAL.
test__zmq_z85_encode__invalid__failure(size_t size_)58 void test__zmq_z85_encode__invalid__failure (size_t size_)
59 {
60 errno = 0;
61 TEST_ASSERT_NULL (zmq_z85_encode (NULL, NULL, size_));
62 TEST_ASSERT_EQUAL_INT (EINVAL, zmq_errno ());
63 }
64
65 // Test vector: rfc.zeromq.org/spec:32/Z85
test__zmq_z85_decode__valid__success()66 void test__zmq_z85_decode__valid__success ()
67 {
68 static const size_t size = 10 * 4 / 5;
69 static const uint8_t expected[size] = {0x86, 0x4F, 0xD2, 0x6F,
70 0xB5, 0x59, 0xF7, 0x5B};
71 static const char *encoded = "HelloWorld";
72 uint8_t out_decoded[size] = {0};
73
74 errno = 0;
75 TEST_ASSERT_NOT_NULL (zmq_z85_decode (out_decoded, encoded));
76 TEST_ASSERT_EQUAL_INT (0, zmq_errno ());
77 TEST_ASSERT_EQUAL_UINT8_ARRAY (expected, out_decoded, size);
78 }
79
80 // Invalid input data must fail with EINVAL.
81 template <size_t SIZE>
test__zmq_z85_decode__invalid__failure(const char (& encoded_)[SIZE])82 void test__zmq_z85_decode__invalid__failure (const char (&encoded_)[SIZE])
83 {
84 uint8_t decoded[SIZE * 4 / 5 + 1];
85 errno = 0;
86 TEST_ASSERT_NULL (zmq_z85_decode (decoded, encoded_));
87 TEST_ASSERT_EQUAL_INT (EINVAL, zmq_errno ());
88 }
89
90
91 // call zmq_z85_encode, then zmq_z85_decode, and compare the results with the original
92 template <size_t SIZE>
test__zmq_z85_encode__zmq_z85_decode__roundtrip(const uint8_t (& test_data_)[SIZE])93 void test__zmq_z85_encode__zmq_z85_decode__roundtrip (
94 const uint8_t (&test_data_)[SIZE])
95 {
96 char test_data_z85[SIZE * 5 / 4 + 1];
97 const char *const res1 = zmq_z85_encode (test_data_z85, test_data_, SIZE);
98 TEST_ASSERT_NOT_NULL (res1);
99
100 uint8_t test_data_decoded[SIZE];
101 const uint8_t *const res2 =
102 zmq_z85_decode (test_data_decoded, test_data_z85);
103 TEST_ASSERT_NOT_NULL (res2);
104
105 TEST_ASSERT_EQUAL_UINT8_ARRAY (test_data_, test_data_decoded, SIZE);
106 }
107
108 // call zmq_z85_encode, then zmq_z85_decode, and compare the results with the original
109 template <size_t SIZE>
test__zmq_z85_decode__zmq_z85_encode__roundtrip(const char (& test_data_)[SIZE])110 void test__zmq_z85_decode__zmq_z85_encode__roundtrip (
111 const char (&test_data_)[SIZE])
112 {
113 const size_t decoded_size = (SIZE - 1) * 4 / 5;
114 uint8_t test_data_decoded[decoded_size];
115 const uint8_t *const res1 = zmq_z85_decode (test_data_decoded, test_data_);
116 TEST_ASSERT_NOT_NULL (res1);
117
118 char test_data_z85[SIZE];
119 const char *const res2 =
120 zmq_z85_encode (test_data_z85, test_data_decoded, decoded_size);
121 TEST_ASSERT_NOT_NULL (res2);
122
123 TEST_ASSERT_EQUAL_UINT8_ARRAY (test_data_, test_data_z85, SIZE);
124 }
125
126 #define def_test__zmq_z85_basename(basename, name, param) \
127 void test__zmq_z85_##basename##_##name () \
128 { \
129 test__zmq_z85_##basename (param); \
130 }
131
132 #define def_test__zmq_z85_encode__invalid__failure(name, param) \
133 def_test__zmq_z85_basename (encode__invalid__failure, name, param)
134
135 def_test__zmq_z85_encode__invalid__failure (1, 1)
136 def_test__zmq_z85_encode__invalid__failure (42, 42)
137
138 #define def_test__zmq_z85_decode__invalid__failure(name, param) \
139 def_test__zmq_z85_basename (decode__invalid__failure, name, param)
140
141 // String length must be evenly divisible by 5 or must fail with EINVAL.
142 def_test__zmq_z85_decode__invalid__failure (indivisble_by_5_multiple_chars,
143 "01234567")
144 def_test__zmq_z85_decode__invalid__failure (indivisble_by_5_one_char, "0")
145
146 // decode invalid data with the maximum representable value
147 def_test__zmq_z85_decode__invalid__failure (max, "#####")
148
149 // decode invalid data with the minimum value beyond the limit
150 // "%nSc0" is 0xffffffff
151 def_test__zmq_z85_decode__invalid__failure (above_limit, "%nSc1")
152
153 // decode invalid data with an invalid character in the range of valid
154 // characters
155 def_test__zmq_z85_decode__invalid__failure (char_within, "####\0047")
156
157 // decode invalid data with an invalid character just below the range of valid
158 // characters
159 def_test__zmq_z85_decode__invalid__failure (char_adjacent_below, "####\0200")
160
161 // decode invalid data with an invalid character just above the range of valid
162 // characters
163 def_test__zmq_z85_decode__invalid__failure (char_adjacent_above, "####\0037")
164
165 #define def_test__encode__zmq_z85_decode__roundtrip(name, param) \
166 def_test__zmq_z85_basename (encode__zmq_z85_decode__roundtrip, name, param)
167
168 const uint8_t test_data_min[] = {0x00, 0x00, 0x00, 0x00};
169 const uint8_t test_data_max[] = {0xff, 0xff, 0xff, 0xff};
170
171 def_test__encode__zmq_z85_decode__roundtrip (min, test_data_min)
172 def_test__encode__zmq_z85_decode__roundtrip (max, test_data_max)
173
174 #define def_test__decode__zmq_z85_encode__roundtrip(name, param) \
175 def_test__zmq_z85_basename (decode__zmq_z85_encode__roundtrip, name, param)
176
177 const char test_data_regular[] = "r^/rM9M=rMToK)63O8dCvd9D<PY<7iGlC+{BiSnG";
178
def_test__decode__zmq_z85_encode__roundtrip(regular,test_data_regular)179 def_test__decode__zmq_z85_encode__roundtrip (regular, test_data_regular)
180
181 int main ()
182 {
183 UNITY_BEGIN ();
184 RUN_TEST (test__zmq_z85_encode__valid__success);
185 RUN_TEST (test__zmq_z85_encode__invalid__failure_1);
186 RUN_TEST (test__zmq_z85_encode__invalid__failure_42);
187
188 RUN_TEST (test__zmq_z85_decode__valid__success);
189 RUN_TEST (
190 test__zmq_z85_decode__invalid__failure_indivisble_by_5_multiple_chars);
191 RUN_TEST (test__zmq_z85_decode__invalid__failure_indivisble_by_5_one_char);
192 RUN_TEST (test__zmq_z85_decode__invalid__failure_max);
193 RUN_TEST (test__zmq_z85_decode__invalid__failure_above_limit);
194 RUN_TEST (test__zmq_z85_decode__invalid__failure_char_within);
195 RUN_TEST (test__zmq_z85_decode__invalid__failure_char_adjacent_below);
196 RUN_TEST (test__zmq_z85_decode__invalid__failure_char_adjacent_above);
197
198 RUN_TEST (test__zmq_z85_encode__zmq_z85_decode__roundtrip_min);
199 RUN_TEST (test__zmq_z85_encode__zmq_z85_decode__roundtrip_max);
200
201 RUN_TEST (test__zmq_z85_decode__zmq_z85_encode__roundtrip_regular);
202
203 return UNITY_END ();
204 }
205