xref: /freebsd/contrib/libcbor/test/copy_test.c (revision 5d3e7166f6a0187fa3f8831b16a06bd9955c21ff)
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 "assertions.h"
9 #include "cbor.h"
10 #include "test_allocator.h"
11 
12 cbor_item_t *item, *copy, *tmp;
13 
test_uints(void ** _CBOR_UNUSED (_state))14 static void test_uints(void **_CBOR_UNUSED(_state)) {
15   item = cbor_build_uint8(10);
16   assert_uint8(copy = cbor_copy(item), 10);
17   cbor_decref(&item);
18   cbor_decref(&copy);
19 
20   item = cbor_build_uint16(10);
21   assert_uint16(copy = cbor_copy(item), 10);
22   cbor_decref(&item);
23   cbor_decref(&copy);
24 
25   item = cbor_build_uint32(10);
26   assert_uint32(copy = cbor_copy(item), 10);
27   cbor_decref(&item);
28   cbor_decref(&copy);
29 
30   item = cbor_build_uint64(10);
31   assert_uint64(copy = cbor_copy(item), 10);
32   cbor_decref(&item);
33   cbor_decref(&copy);
34 }
35 
test_negints(void ** _CBOR_UNUSED (_state))36 static void test_negints(void **_CBOR_UNUSED(_state)) {
37   item = cbor_build_negint8(10);
38   assert_true(cbor_get_uint8(copy = cbor_copy(item)) == 10);
39   cbor_decref(&item);
40   cbor_decref(&copy);
41 
42   item = cbor_build_negint16(10);
43   assert_true(cbor_get_uint16(copy = cbor_copy(item)) == 10);
44   cbor_decref(&item);
45   cbor_decref(&copy);
46 
47   item = cbor_build_negint32(10);
48   assert_true(cbor_get_uint32(copy = cbor_copy(item)) == 10);
49   cbor_decref(&item);
50   cbor_decref(&copy);
51 
52   item = cbor_build_negint64(10);
53   assert_true(cbor_get_uint64(copy = cbor_copy(item)) == 10);
54   cbor_decref(&item);
55   cbor_decref(&copy);
56 }
57 
test_def_bytestring(void ** _CBOR_UNUSED (_state))58 static void test_def_bytestring(void **_CBOR_UNUSED(_state)) {
59   item = cbor_build_bytestring((cbor_data) "abc", 3);
60   assert_memory_equal(cbor_bytestring_handle(copy = cbor_copy(item)),
61                       cbor_bytestring_handle(item), 3);
62   cbor_decref(&item);
63   cbor_decref(&copy);
64 }
65 
test_indef_bytestring(void ** _CBOR_UNUSED (_state))66 static void test_indef_bytestring(void **_CBOR_UNUSED(_state)) {
67   item = cbor_new_indefinite_bytestring();
68   assert_true(cbor_bytestring_add_chunk(
69       item, cbor_move(cbor_build_bytestring((cbor_data) "abc", 3))));
70   copy = cbor_copy(item);
71 
72   assert_size_equal(cbor_bytestring_chunk_count(item),
73                     cbor_bytestring_chunk_count(copy));
74 
75   assert_memory_equal(
76       cbor_bytestring_handle(cbor_bytestring_chunks_handle(copy)[0]), "abc", 3);
77   cbor_decref(&item);
78   cbor_decref(&copy);
79 }
80 
test_def_string(void ** _CBOR_UNUSED (_state))81 static void test_def_string(void **_CBOR_UNUSED(_state)) {
82   item = cbor_build_string("abc");
83   assert_memory_equal(cbor_string_handle(copy = cbor_copy(item)),
84                       cbor_string_handle(item), 3);
85   cbor_decref(&item);
86   cbor_decref(&copy);
87 }
88 
test_indef_string(void ** _CBOR_UNUSED (_state))89 static void test_indef_string(void **_CBOR_UNUSED(_state)) {
90   item = cbor_new_indefinite_string();
91   assert_true(cbor_string_add_chunk(item, cbor_move(cbor_build_string("abc"))));
92   copy = cbor_copy(item);
93 
94   assert_size_equal(cbor_string_chunk_count(item),
95                     cbor_string_chunk_count(copy));
96 
97   assert_memory_equal(cbor_string_handle(cbor_string_chunks_handle(copy)[0]),
98                       "abc", 3);
99   cbor_decref(&item);
100   cbor_decref(&copy);
101 }
102 
test_def_array(void ** _CBOR_UNUSED (_state))103 static void test_def_array(void **_CBOR_UNUSED(_state)) {
104   item = cbor_new_definite_array(1);
105   assert_true(cbor_array_push(item, cbor_move(cbor_build_uint8(42))));
106 
107   assert_uint8(tmp = cbor_array_get(copy = cbor_copy(item), 0), 42);
108   cbor_decref(&item);
109   cbor_decref(&copy);
110   cbor_decref(&tmp);
111 }
112 
test_indef_array(void ** _CBOR_UNUSED (_state))113 static void test_indef_array(void **_CBOR_UNUSED(_state)) {
114   item = cbor_new_indefinite_array();
115   assert_true(cbor_array_push(item, cbor_move(cbor_build_uint8(42))));
116 
117   assert_uint8(tmp = cbor_array_get(copy = cbor_copy(item), 0), 42);
118   cbor_decref(&item);
119   cbor_decref(&copy);
120   cbor_decref(&tmp);
121 }
122 
test_def_map(void ** _CBOR_UNUSED (_state))123 static void test_def_map(void **_CBOR_UNUSED(_state)) {
124   item = cbor_new_definite_map(1);
125   assert_true(cbor_map_add(item, (struct cbor_pair){
126                                      .key = cbor_move(cbor_build_uint8(42)),
127                                      .value = cbor_move(cbor_build_uint8(43)),
128                                  }));
129 
130   assert_uint8(cbor_map_handle(copy = cbor_copy(item))[0].key, 42);
131 
132   cbor_decref(&item);
133   cbor_decref(&copy);
134 }
135 
test_indef_map(void ** _CBOR_UNUSED (_state))136 static void test_indef_map(void **_CBOR_UNUSED(_state)) {
137   item = cbor_new_indefinite_map();
138   assert_true(cbor_map_add(item, (struct cbor_pair){
139                                      .key = cbor_move(cbor_build_uint8(42)),
140                                      .value = cbor_move(cbor_build_uint8(43)),
141                                  }));
142 
143   assert_uint8(cbor_map_handle(copy = cbor_copy(item))[0].key, 42);
144 
145   cbor_decref(&item);
146   cbor_decref(&copy);
147 }
148 
test_tag(void ** _CBOR_UNUSED (_state))149 static void test_tag(void **_CBOR_UNUSED(_state)) {
150   item = cbor_build_tag(10, cbor_move(cbor_build_uint8(42)));
151 
152   assert_uint8(cbor_move(cbor_tag_item(copy = cbor_copy(item))), 42);
153 
154   cbor_decref(&item);
155   cbor_decref(&copy);
156 }
157 
test_ctrls(void ** _CBOR_UNUSED (_state))158 static void test_ctrls(void **_CBOR_UNUSED(_state)) {
159   item = cbor_new_null();
160   assert_true(cbor_is_null(copy = cbor_copy(item)));
161   cbor_decref(&item);
162   cbor_decref(&copy);
163 }
164 
test_floats(void ** _CBOR_UNUSED (_state))165 static void test_floats(void **_CBOR_UNUSED(_state)) {
166   item = cbor_build_float2(3.14f);
167   assert_true(cbor_float_get_float2(copy = cbor_copy(item)) ==
168               cbor_float_get_float2(item));
169   cbor_decref(&item);
170   cbor_decref(&copy);
171 
172   item = cbor_build_float4(3.14f);
173   assert_true(cbor_float_get_float4(copy = cbor_copy(item)) ==
174               cbor_float_get_float4(item));
175   cbor_decref(&item);
176   cbor_decref(&copy);
177 
178   item = cbor_build_float8(3.14);
179   assert_true(cbor_float_get_float8(copy = cbor_copy(item)) ==
180               cbor_float_get_float8(item));
181   cbor_decref(&item);
182   cbor_decref(&copy);
183 }
184 
test_alloc_failure_simple(void ** _CBOR_UNUSED (_state))185 static void test_alloc_failure_simple(void **_CBOR_UNUSED(_state)) {
186   item = cbor_build_uint8(10);
187 
188   WITH_FAILING_MALLOC({ assert_null(cbor_copy(item)); });
189   assert_size_equal(cbor_refcount(item), 1);
190 
191   cbor_decref(&item);
192 }
193 
test_bytestring_alloc_failure(void ** _CBOR_UNUSED (_state))194 static void test_bytestring_alloc_failure(void **_CBOR_UNUSED(_state)) {
195   item = cbor_new_indefinite_bytestring();
196   assert_true(cbor_bytestring_add_chunk(
197       item, cbor_move(cbor_build_bytestring((cbor_data) "abc", 3))));
198 
199   WITH_FAILING_MALLOC({ assert_null(cbor_copy(item)); });
200   assert_size_equal(cbor_refcount(item), 1);
201 
202   cbor_decref(&item);
203 }
204 
test_bytestring_chunk_alloc_failure(void ** _CBOR_UNUSED (_state))205 static void test_bytestring_chunk_alloc_failure(void **_CBOR_UNUSED(_state)) {
206   item = cbor_new_indefinite_bytestring();
207   assert_true(cbor_bytestring_add_chunk(
208       item, cbor_move(cbor_build_bytestring((cbor_data) "abc", 3))));
209 
210   WITH_MOCK_MALLOC({ assert_null(cbor_copy(item)); }, 2, MALLOC, MALLOC_FAIL);
211   assert_size_equal(cbor_refcount(item), 1);
212 
213   cbor_decref(&item);
214 }
215 
test_bytestring_chunk_append_failure(void ** _CBOR_UNUSED (_state))216 static void test_bytestring_chunk_append_failure(void **_CBOR_UNUSED(_state)) {
217   item = cbor_new_indefinite_bytestring();
218   assert_true(cbor_bytestring_add_chunk(
219       item, cbor_move(cbor_build_bytestring((cbor_data) "abc", 3))));
220 
221   WITH_MOCK_MALLOC({ assert_null(cbor_copy(item)); }, 5,
222                    // New indef string, cbor_indefinite_string_data, chunk item,
223                    // chunk data, extend cbor_indefinite_string_data.chunks
224                    MALLOC, MALLOC, MALLOC, MALLOC, REALLOC_FAIL);
225   assert_size_equal(cbor_refcount(item), 1);
226 
227   cbor_decref(&item);
228 }
229 
test_bytestring_second_chunk_alloc_failure(void ** _CBOR_UNUSED (_state))230 static void test_bytestring_second_chunk_alloc_failure(
231     void **_CBOR_UNUSED(_state)) {
232   item = cbor_new_indefinite_bytestring();
233   assert_true(cbor_bytestring_add_chunk(
234       item, cbor_move(cbor_build_bytestring((cbor_data) "abc", 3))));
235   assert_true(cbor_bytestring_add_chunk(
236       item, cbor_move(cbor_build_bytestring((cbor_data) "def", 3))));
237 
238   WITH_MOCK_MALLOC({ assert_null(cbor_copy(item)); }, 6,
239                    // New indef string, cbor_indefinite_string_data, chunk item,
240                    // chunk data, extend cbor_indefinite_string_data.chunks,
241                    // second chunk item
242                    MALLOC, MALLOC, MALLOC, MALLOC, REALLOC, MALLOC_FAIL);
243   assert_size_equal(cbor_refcount(item), 1);
244 
245   cbor_decref(&item);
246 }
247 
test_string_alloc_failure(void ** _CBOR_UNUSED (_state))248 static void test_string_alloc_failure(void **_CBOR_UNUSED(_state)) {
249   item = cbor_new_indefinite_string();
250   assert_true(cbor_string_add_chunk(item, cbor_move(cbor_build_string("abc"))));
251 
252   WITH_FAILING_MALLOC({ assert_null(cbor_copy(item)); });
253   assert_size_equal(cbor_refcount(item), 1);
254 
255   cbor_decref(&item);
256 }
257 
test_string_chunk_alloc_failure(void ** _CBOR_UNUSED (_state))258 static void test_string_chunk_alloc_failure(void **_CBOR_UNUSED(_state)) {
259   item = cbor_new_indefinite_string();
260   assert_true(cbor_string_add_chunk(item, cbor_move(cbor_build_string("abc"))));
261 
262   WITH_MOCK_MALLOC({ assert_null(cbor_copy(item)); }, 2, MALLOC, MALLOC_FAIL);
263   assert_size_equal(cbor_refcount(item), 1);
264 
265   cbor_decref(&item);
266 }
267 
test_string_chunk_append_failure(void ** _CBOR_UNUSED (_state))268 static void test_string_chunk_append_failure(void **_CBOR_UNUSED(_state)) {
269   item = cbor_new_indefinite_string();
270   assert_true(cbor_string_add_chunk(item, cbor_move(cbor_build_string("abc"))));
271 
272   WITH_MOCK_MALLOC({ assert_null(cbor_copy(item)); }, 5,
273                    // New indef string, cbor_indefinite_string_data, chunk item,
274                    // chunk data, extend cbor_indefinite_string_data.chunks
275                    MALLOC, MALLOC, MALLOC, MALLOC, REALLOC_FAIL);
276   assert_size_equal(cbor_refcount(item), 1);
277 
278   cbor_decref(&item);
279 }
280 
test_string_second_chunk_alloc_failure(void ** _CBOR_UNUSED (_state))281 static void test_string_second_chunk_alloc_failure(
282     void **_CBOR_UNUSED(_state)) {
283   item = cbor_new_indefinite_string();
284   assert_true(cbor_string_add_chunk(item, cbor_move(cbor_build_string("abc"))));
285   assert_true(cbor_string_add_chunk(item, cbor_move(cbor_build_string("def"))));
286 
287   WITH_MOCK_MALLOC({ assert_null(cbor_copy(item)); }, 6,
288                    // New indef string, cbor_indefinite_string_data, chunk item,
289                    // chunk data, extend cbor_indefinite_string_data.chunks,
290                    // second chunk item
291                    MALLOC, MALLOC, MALLOC, MALLOC, REALLOC, MALLOC_FAIL);
292   assert_size_equal(cbor_refcount(item), 1);
293 
294   cbor_decref(&item);
295 }
296 
test_array_alloc_failure(void ** _CBOR_UNUSED (_state))297 static void test_array_alloc_failure(void **_CBOR_UNUSED(_state)) {
298   item = cbor_new_indefinite_array();
299   assert_true(cbor_array_push(item, cbor_move(cbor_build_uint8(42))));
300 
301   WITH_FAILING_MALLOC({ assert_null(cbor_copy(item)); });
302   assert_size_equal(cbor_refcount(item), 1);
303 
304   cbor_decref(&item);
305 }
306 
test_array_item_alloc_failure(void ** _CBOR_UNUSED (_state))307 static void test_array_item_alloc_failure(void **_CBOR_UNUSED(_state)) {
308   item = cbor_new_indefinite_array();
309   assert_true(cbor_array_push(item, cbor_move(cbor_build_uint8(42))));
310 
311   WITH_MOCK_MALLOC({ assert_null(cbor_copy(item)); }, 2,
312                    // New array, item copy
313                    MALLOC, MALLOC_FAIL);
314 
315   assert_size_equal(cbor_refcount(item), 1);
316 
317   cbor_decref(&item);
318 }
319 
test_array_push_failure(void ** _CBOR_UNUSED (_state))320 static void test_array_push_failure(void **_CBOR_UNUSED(_state)) {
321   item = cbor_new_indefinite_array();
322   assert_true(cbor_array_push(item, cbor_move(cbor_build_uint8(42))));
323 
324   WITH_MOCK_MALLOC({ assert_null(cbor_copy(item)); }, 3,
325                    // New array, item copy, array reallocation
326                    MALLOC, MALLOC, REALLOC_FAIL);
327 
328   assert_size_equal(cbor_refcount(item), 1);
329 
330   cbor_decref(&item);
331 }
332 
test_array_second_item_alloc_failure(void ** _CBOR_UNUSED (_state))333 static void test_array_second_item_alloc_failure(void **_CBOR_UNUSED(_state)) {
334   item = cbor_new_indefinite_array();
335   assert_true(cbor_array_push(item, cbor_move(cbor_build_uint8(42))));
336   assert_true(cbor_array_push(item, cbor_move(cbor_build_uint8(43))));
337 
338   WITH_MOCK_MALLOC({ assert_null(cbor_copy(item)); }, 4,
339                    // New array, item copy, array reallocation, second item copy
340                    MALLOC, MALLOC, REALLOC, MALLOC_FAIL);
341 
342   assert_size_equal(cbor_refcount(item), 1);
343 
344   cbor_decref(&item);
345 }
346 
test_map_alloc_failure(void ** _CBOR_UNUSED (_state))347 static void test_map_alloc_failure(void **_CBOR_UNUSED(_state)) {
348   item = cbor_new_indefinite_map();
349   assert_true(
350       cbor_map_add(item, (struct cbor_pair){cbor_move(cbor_build_uint8(42)),
351                                             cbor_move(cbor_build_bool(true))}));
352 
353   WITH_FAILING_MALLOC({ assert_null(cbor_copy(item)); });
354   assert_size_equal(cbor_refcount(item), 1);
355 
356   cbor_decref(&item);
357 }
358 
test_map_key_alloc_failure(void ** _CBOR_UNUSED (_state))359 static void test_map_key_alloc_failure(void **_CBOR_UNUSED(_state)) {
360   item = cbor_new_indefinite_map();
361   assert_true(
362       cbor_map_add(item, (struct cbor_pair){cbor_move(cbor_build_uint8(42)),
363                                             cbor_move(cbor_build_bool(true))}));
364 
365   WITH_MOCK_MALLOC({ assert_null(cbor_copy(item)); }, 2,
366                    // New map, key copy
367                    MALLOC, MALLOC_FAIL);
368   assert_size_equal(cbor_refcount(item), 1);
369 
370   cbor_decref(&item);
371 }
372 
test_map_value_alloc_failure(void ** _CBOR_UNUSED (_state))373 static void test_map_value_alloc_failure(void **_CBOR_UNUSED(_state)) {
374   item = cbor_new_indefinite_map();
375   assert_true(
376       cbor_map_add(item, (struct cbor_pair){cbor_move(cbor_build_uint8(42)),
377                                             cbor_move(cbor_build_bool(true))}));
378 
379   WITH_MOCK_MALLOC({ assert_null(cbor_copy(item)); }, 3,
380                    // New map, key copy, value copy
381                    MALLOC, MALLOC, MALLOC_FAIL);
382   assert_size_equal(cbor_refcount(item), 1);
383 
384   cbor_decref(&item);
385 }
386 
test_map_add_failure(void ** _CBOR_UNUSED (_state))387 static void test_map_add_failure(void **_CBOR_UNUSED(_state)) {
388   item = cbor_new_indefinite_map();
389   assert_true(
390       cbor_map_add(item, (struct cbor_pair){cbor_move(cbor_build_uint8(42)),
391                                             cbor_move(cbor_build_bool(true))}));
392 
393   WITH_MOCK_MALLOC({ assert_null(cbor_copy(item)); }, 4,
394                    // New map, key copy, value copy, add
395                    MALLOC, MALLOC, MALLOC, REALLOC_FAIL);
396   assert_size_equal(cbor_refcount(item), 1);
397 
398   cbor_decref(&item);
399 }
400 
test_map_second_key_failure(void ** _CBOR_UNUSED (_state))401 static void test_map_second_key_failure(void **_CBOR_UNUSED(_state)) {
402   item = cbor_new_indefinite_map();
403   assert_true(
404       cbor_map_add(item, (struct cbor_pair){cbor_move(cbor_build_uint8(42)),
405                                             cbor_move(cbor_build_bool(true))}));
406   assert_true(cbor_map_add(
407       item, (struct cbor_pair){cbor_move(cbor_build_uint8(43)),
408                                cbor_move(cbor_build_bool(false))}));
409 
410   WITH_MOCK_MALLOC({ assert_null(cbor_copy(item)); }, 5,
411                    // New map, key copy, value copy, add, second key copy
412                    MALLOC, MALLOC, MALLOC, REALLOC, MALLOC_FAIL);
413   assert_size_equal(cbor_refcount(item), 1);
414 
415   cbor_decref(&item);
416 }
417 
test_tag_item_alloc_failure(void ** _CBOR_UNUSED (_state))418 static void test_tag_item_alloc_failure(void **_CBOR_UNUSED(_state)) {
419   item = cbor_build_tag(1, cbor_move(cbor_build_uint8(42)));
420 
421   WITH_FAILING_MALLOC({ assert_null(cbor_copy(item)); });
422   assert_size_equal(cbor_refcount(item), 1);
423 
424   cbor_decref(&item);
425 }
426 
test_tag_alloc_failure(void ** _CBOR_UNUSED (_state))427 static void test_tag_alloc_failure(void **_CBOR_UNUSED(_state)) {
428   item = cbor_build_tag(1, cbor_move(cbor_build_uint8(42)));
429 
430   WITH_MOCK_MALLOC({ assert_null(cbor_copy(item)); }, 2,
431                    // Item copy, tag
432                    MALLOC, MALLOC_FAIL);
433   assert_size_equal(cbor_refcount(item), 1);
434 
435   cbor_decref(&item);
436 }
437 
main(void)438 int main(void) {
439   const struct CMUnitTest tests[] = {
440       cmocka_unit_test(test_uints),
441       cmocka_unit_test(test_negints),
442       cmocka_unit_test(test_def_bytestring),
443       cmocka_unit_test(test_indef_bytestring),
444       cmocka_unit_test(test_def_string),
445       cmocka_unit_test(test_indef_string),
446       cmocka_unit_test(test_def_array),
447       cmocka_unit_test(test_indef_array),
448       cmocka_unit_test(test_def_map),
449       cmocka_unit_test(test_indef_map),
450       cmocka_unit_test(test_tag),
451       cmocka_unit_test(test_ctrls),
452       cmocka_unit_test(test_floats),
453       cmocka_unit_test(test_alloc_failure_simple),
454       cmocka_unit_test(test_bytestring_alloc_failure),
455       cmocka_unit_test(test_bytestring_chunk_alloc_failure),
456       cmocka_unit_test(test_bytestring_chunk_append_failure),
457       cmocka_unit_test(test_bytestring_second_chunk_alloc_failure),
458       cmocka_unit_test(test_string_alloc_failure),
459       cmocka_unit_test(test_string_chunk_alloc_failure),
460       cmocka_unit_test(test_string_chunk_append_failure),
461       cmocka_unit_test(test_string_second_chunk_alloc_failure),
462       cmocka_unit_test(test_array_alloc_failure),
463       cmocka_unit_test(test_array_item_alloc_failure),
464       cmocka_unit_test(test_array_push_failure),
465       cmocka_unit_test(test_array_second_item_alloc_failure),
466       cmocka_unit_test(test_map_alloc_failure),
467       cmocka_unit_test(test_map_key_alloc_failure),
468       cmocka_unit_test(test_map_value_alloc_failure),
469       cmocka_unit_test(test_map_add_failure),
470       cmocka_unit_test(test_map_second_key_failure),
471       cmocka_unit_test(test_tag_item_alloc_failure),
472       cmocka_unit_test(test_tag_alloc_failure),
473   };
474   return cmocka_run_group_tests(tests, NULL, NULL);
475 }
476