1 /*
2  * Copyright (c) 2014-2020 Pavel Kalvoda <me@pavelkalvoda.com>
3  *
4  * libcbor is free software; you can redistribute it and/or modify
5  * it under the terms of the MIT license. See LICENSE for details.
6  */
7 
8 #include <setjmp.h>
9 #include <stdarg.h>
10 #include <stddef.h>
11 
12 #include <cmocka.h>
13 
14 #include <math.h>
15 #include <stdarg.h>
16 #include <string.h>
17 #include <strings.h>
18 #include "cbor.h"
19 
20 unsigned char buffer[512];
21 
22 static void test_serialize_uint8(void **state) {
23   cbor_item_t *item = cbor_new_int8();
24   cbor_set_uint8(item, 0);
25   assert_int_equal(1, cbor_serialize(item, buffer, 512));
26   assert_memory_equal(buffer, (unsigned char[]){0x00}, 1);
27   cbor_decref(&item);
28 }
29 
30 static void test_serialize_uint16(void **state) {
31   cbor_item_t *item = cbor_new_int16();
32   cbor_set_uint16(item, 1000);
33   assert_int_equal(3, cbor_serialize(item, buffer, 512));
34   assert_memory_equal(buffer, ((unsigned char[]){0x19, 0x03, 0xE8}), 3);
35   cbor_decref(&item);
36 }
37 
38 static void test_serialize_uint32(void **state) {
39   cbor_item_t *item = cbor_new_int32();
40   cbor_set_uint32(item, 1000000);
41   assert_int_equal(5, cbor_serialize(item, buffer, 512));
42   assert_memory_equal(buffer, ((unsigned char[]){0x1A, 0x00, 0x0F, 0x42, 0x40}),
43                       5);
44   cbor_decref(&item);
45 }
46 
47 static void test_serialize_uint64(void **state) {
48   cbor_item_t *item = cbor_new_int64();
49   cbor_set_uint64(item, 1000000000000);
50   assert_int_equal(9, cbor_serialize(item, buffer, 512));
51   assert_memory_equal(
52       buffer,
53       ((unsigned char[]){0x1B, 0x00, 0x00, 0x00, 0xE8, 0xD4, 0xA5, 0x10, 0x00}),
54       9);
55   cbor_decref(&item);
56 }
57 
58 static void test_serialize_negint8(void **state) {
59   cbor_item_t *item = cbor_new_int8();
60   cbor_set_uint8(item, 0);
61   cbor_mark_negint(item);
62   assert_int_equal(1, cbor_serialize(item, buffer, 512));
63   assert_memory_equal(buffer, (unsigned char[]){0x20}, 1);
64   cbor_decref(&item);
65 }
66 
67 static void test_serialize_negint16(void **state) {
68   cbor_item_t *item = cbor_new_int16();
69   cbor_set_uint16(item, 1000);
70   cbor_mark_negint(item);
71   assert_int_equal(3, cbor_serialize(item, buffer, 512));
72   assert_memory_equal(buffer, ((unsigned char[]){0x39, 0x03, 0xE8}), 3);
73   cbor_decref(&item);
74 }
75 
76 static void test_serialize_negint32(void **state) {
77   cbor_item_t *item = cbor_new_int32();
78   cbor_set_uint32(item, 1000000);
79   cbor_mark_negint(item);
80   assert_int_equal(5, cbor_serialize(item, buffer, 512));
81   assert_memory_equal(buffer, ((unsigned char[]){0x3A, 0x00, 0x0F, 0x42, 0x40}),
82                       5);
83   cbor_decref(&item);
84 }
85 
86 static void test_serialize_negint64(void **state) {
87   cbor_item_t *item = cbor_new_int64();
88   cbor_set_uint64(item, 1000000000000);
89   cbor_mark_negint(item);
90   assert_int_equal(9, cbor_serialize(item, buffer, 512));
91   assert_memory_equal(
92       buffer,
93       ((unsigned char[]){0x3B, 0x00, 0x00, 0x00, 0xE8, 0xD4, 0xA5, 0x10, 0x00}),
94       9);
95   cbor_decref(&item);
96 }
97 
98 static void test_serialize_definite_bytestring(void **state) {
99   cbor_item_t *item = cbor_new_definite_bytestring();
100   unsigned char *data = malloc(256);
101   bzero(data, 256); /* Prevent undefined behavior in comparison */
102   cbor_bytestring_set_handle(item, data, 256);
103   assert_int_equal(256 + 3, cbor_serialize(item, buffer, 512));
104   assert_memory_equal(buffer, ((unsigned char[]){0x59, 0x01, 0x00}), 3);
105   assert_memory_equal(buffer + 3, data, 256);
106   cbor_decref(&item);
107 }
108 
109 static void test_serialize_indefinite_bytestring(void **state) {
110   cbor_item_t *item = cbor_new_indefinite_bytestring();
111 
112   cbor_item_t *chunk = cbor_new_definite_bytestring();
113   unsigned char *data = malloc(256);
114   bzero(data, 256); /* Prevent undefined behavior in comparison */
115   cbor_bytestring_set_handle(chunk, data, 256);
116 
117   cbor_bytestring_add_chunk(item, cbor_move(chunk));
118   assert_int_equal(cbor_bytestring_chunk_count(item), 1);
119 
120   assert_int_equal(1 + 3 + 256 + 1, cbor_serialize(item, buffer, 512));
121   assert_memory_equal(buffer, ((unsigned char[]){0x5F, 0x59, 0x01, 0x00}), 4);
122   assert_memory_equal(buffer + 4, data, 256);
123   assert_memory_equal(buffer + 4 + 256, ((unsigned char[]){0xFF}), 1);
124   cbor_decref(&item);
125 }
126 
127 static void test_serialize_definite_string(void **state) {
128   cbor_item_t *item = cbor_new_definite_string();
129   unsigned char *data = malloc(12);
130   strncpy((char *)data, "Hello world!", 12);
131   cbor_string_set_handle(item, data, 12);
132   assert_int_equal(1 + 12, cbor_serialize(item, buffer, 512));
133   assert_memory_equal(
134       buffer,
135       ((unsigned char[]){0x6C, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F,
136                          0x72, 0x6C, 0x64, 0x21}),
137       13);
138   cbor_decref(&item);
139 }
140 
141 static void test_serialize_indefinite_string(void **state) {
142   cbor_item_t *item = cbor_new_indefinite_string();
143   cbor_item_t *chunk = cbor_new_definite_string();
144 
145   unsigned char *data = malloc(12);
146   strncpy((char *)data, "Hello world!", 12);
147   cbor_string_set_handle(chunk, data, 12);
148 
149   assert_true(cbor_string_add_chunk(item, cbor_move(chunk)));
150   assert_int_equal(cbor_string_chunk_count(item), 1);
151 
152   assert_int_equal(15, cbor_serialize(item, buffer, 512));
153   assert_memory_equal(
154       buffer,
155       ((unsigned char[]){0x7F, 0x6C, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77,
156                          0x6F, 0x72, 0x6C, 0x64, 0x21, 0xFF}),
157       15);
158   cbor_decref(&item);
159 }
160 
161 static void test_serialize_definite_array(void **state) {
162   cbor_item_t *item = cbor_new_definite_array(2);
163   cbor_item_t *one = cbor_build_uint8(1);
164   cbor_item_t *two = cbor_build_uint8(2);
165 
166   cbor_array_push(item, one);
167   cbor_array_set(item, 1, two);
168   cbor_array_replace(item, 0, one);
169 
170   assert_int_equal(3, cbor_serialize(item, buffer, 512));
171   assert_memory_equal(buffer, ((unsigned char[]){0x82, 0x01, 0x02}), 3);
172   cbor_decref(&item);
173   cbor_decref(&one);
174   cbor_decref(&two);
175 }
176 
177 static void test_serialize_indefinite_array(void **state) {
178   cbor_item_t *item = cbor_new_indefinite_array();
179   cbor_item_t *one = cbor_build_uint8(1);
180   cbor_item_t *two = cbor_build_uint8(2);
181 
182   cbor_array_push(item, one);
183   cbor_array_push(item, two);
184 
185   assert_int_equal(4, cbor_serialize(item, buffer, 512));
186   assert_memory_equal(buffer, ((unsigned char[]){0x9F, 0x01, 0x02, 0xFF}), 4);
187   cbor_decref(&item);
188   cbor_decref(&one);
189   cbor_decref(&two);
190 }
191 
192 static void test_serialize_definite_map(void **state) {
193   cbor_item_t *item = cbor_new_definite_map(2);
194   cbor_item_t *one = cbor_build_uint8(1);
195   cbor_item_t *two = cbor_build_uint8(2);
196 
197   cbor_map_add(item, (struct cbor_pair){.key = one, .value = two});
198   cbor_map_add(item, (struct cbor_pair){.key = two, .value = one});
199 
200   assert_int_equal(5, cbor_serialize(item, buffer, 512));
201   assert_memory_equal(buffer, ((unsigned char[]){0xA2, 0x01, 0x02, 0x02, 0x01}),
202                       5);
203   cbor_decref(&item);
204   cbor_decref(&one);
205   cbor_decref(&two);
206 }
207 
208 static void test_serialize_indefinite_map(void **state) {
209   cbor_item_t *item = cbor_new_indefinite_map(2);
210   cbor_item_t *one = cbor_build_uint8(1);
211   cbor_item_t *two = cbor_build_uint8(2);
212 
213   assert_true(cbor_map_add(item, (struct cbor_pair){.key = one, .value = two}));
214   assert_true(cbor_map_add(item, (struct cbor_pair){.key = two, .value = one}));
215 
216   assert_int_equal(6, cbor_serialize(item, buffer, 512));
217   assert_memory_equal(
218       buffer, ((unsigned char[]){0xBF, 0x01, 0x02, 0x02, 0x01, 0xFF}), 6);
219   cbor_decref(&item);
220   cbor_decref(&one);
221   cbor_decref(&two);
222 }
223 
224 static void test_serialize_tags(void **state) {
225   cbor_item_t *item = cbor_new_tag(21);
226   cbor_item_t *one = cbor_build_uint8(1);
227   cbor_tag_set_item(item, one);
228 
229   assert_int_equal(2, cbor_serialize(item, buffer, 512));
230   assert_memory_equal(buffer, ((unsigned char[]){0xD5, 0x01}), 2);
231   cbor_decref(&item);
232   cbor_decref(&one);
233 }
234 
235 static void test_serialize_half(void **state) {
236   cbor_item_t *item = cbor_new_float2();
237   cbor_set_float2(item, NAN);
238 
239   assert_int_equal(3, cbor_serialize(item, buffer, 512));
240   assert_memory_equal(buffer, ((unsigned char[]){0xF9, 0x7E, 0x00}), 3);
241   cbor_decref(&item);
242 }
243 
244 static void test_serialize_single(void **state) {
245   cbor_item_t *item = cbor_new_float4();
246   cbor_set_float4(item, 100000.0f);
247 
248   assert_int_equal(5, cbor_serialize(item, buffer, 512));
249   assert_memory_equal(buffer, ((unsigned char[]){0xFA, 0x47, 0xC3, 0x50, 0x00}),
250                       5);
251   cbor_decref(&item);
252 }
253 
254 static void test_serialize_double(void **state) {
255   cbor_item_t *item = cbor_new_float8();
256   cbor_set_float8(item, -4.1);
257 
258   assert_int_equal(9, cbor_serialize(item, buffer, 512));
259   assert_memory_equal(
260       buffer,
261       ((unsigned char[]){0xFB, 0xC0, 0x10, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66}),
262       9);
263   cbor_decref(&item);
264 }
265 
266 static void test_serialize_ctrl(void **state) {
267   cbor_item_t *item = cbor_new_undef();
268 
269   assert_int_equal(1, cbor_serialize(item, buffer, 512));
270   assert_memory_equal(buffer, ((unsigned char[]){0xF7}), 1);
271   cbor_decref(&item);
272 }
273 
274 static void test_serialize_long_ctrl(void **state) {
275   cbor_item_t *item = cbor_new_ctrl();
276   cbor_set_ctrl(item, 254);
277 
278   assert_int_equal(2, cbor_serialize(item, buffer, 512));
279   assert_memory_equal(buffer, ((unsigned char[]){0xF8, 0xFE}), 2);
280   cbor_decref(&item);
281 }
282 
283 static void test_auto_serialize(void **state) {
284   cbor_item_t *item = cbor_new_definite_array(4);
285   for (size_t i = 0; i < 4; i++)
286     cbor_array_push(item, cbor_move(cbor_build_uint64(0)));
287 
288   unsigned char *buffer;
289   size_t buffer_size;
290   assert_int_equal(37, cbor_serialize_alloc(item, &buffer, &buffer_size));
291   assert_int_equal(64, buffer_size);
292   assert_memory_equal(buffer, ((unsigned char[]){0x84, 0x1B}), 2);
293   cbor_decref(&item);
294   _CBOR_FREE(buffer);
295 }
296 
297 int main(void) {
298   const struct CMUnitTest tests[] = {
299       cmocka_unit_test(test_serialize_uint8),
300       cmocka_unit_test(test_serialize_uint16),
301       cmocka_unit_test(test_serialize_uint32),
302       cmocka_unit_test(test_serialize_uint64),
303       cmocka_unit_test(test_serialize_negint8),
304       cmocka_unit_test(test_serialize_negint16),
305       cmocka_unit_test(test_serialize_negint32),
306       cmocka_unit_test(test_serialize_negint64),
307       cmocka_unit_test(test_serialize_definite_bytestring),
308       cmocka_unit_test(test_serialize_indefinite_bytestring),
309       cmocka_unit_test(test_serialize_definite_string),
310       cmocka_unit_test(test_serialize_indefinite_string),
311       cmocka_unit_test(test_serialize_definite_array),
312       cmocka_unit_test(test_serialize_indefinite_array),
313       cmocka_unit_test(test_serialize_definite_map),
314       cmocka_unit_test(test_serialize_indefinite_map),
315       cmocka_unit_test(test_serialize_tags),
316       cmocka_unit_test(test_serialize_half),
317       cmocka_unit_test(test_serialize_single),
318       cmocka_unit_test(test_serialize_double),
319       cmocka_unit_test(test_serialize_ctrl),
320       cmocka_unit_test(test_serialize_long_ctrl),
321       cmocka_unit_test(test_auto_serialize)};
322   return cmocka_run_group_tests(tests, NULL, NULL);
323 }
324