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(©);
19
20 item = cbor_build_uint16(10);
21 assert_uint16(copy = cbor_copy(item), 10);
22 cbor_decref(&item);
23 cbor_decref(©);
24
25 item = cbor_build_uint32(10);
26 assert_uint32(copy = cbor_copy(item), 10);
27 cbor_decref(&item);
28 cbor_decref(©);
29
30 item = cbor_build_uint64(10);
31 assert_uint64(copy = cbor_copy(item), 10);
32 cbor_decref(&item);
33 cbor_decref(©);
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(©);
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(©);
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(©);
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(©);
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(©);
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(©);
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(©);
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(©);
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(©);
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(©);
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(©);
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(©);
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(©);
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(©);
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(©);
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(©);
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(©);
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