xref: /freebsd/contrib/libcbor/test/array_test.c (revision 5d3e7166f6a0187fa3f8831b16a06bd9955c21ff)
1*5d3e7166SEd Maste /*
2*5d3e7166SEd Maste  * Copyright (c) 2014-2020 Pavel Kalvoda <me@pavelkalvoda.com>
3*5d3e7166SEd Maste  *
4*5d3e7166SEd Maste  * libcbor is free software; you can redistribute it and/or modify
5*5d3e7166SEd Maste  * it under the terms of the MIT license. See LICENSE for details.
6*5d3e7166SEd Maste  */
7*5d3e7166SEd Maste 
8*5d3e7166SEd Maste #include "assertions.h"
9*5d3e7166SEd Maste #include "cbor.h"
10*5d3e7166SEd Maste #include "test_allocator.h"
11*5d3e7166SEd Maste 
12*5d3e7166SEd Maste cbor_item_t *arr;
13*5d3e7166SEd Maste struct cbor_load_result res;
14*5d3e7166SEd Maste 
15*5d3e7166SEd Maste unsigned char data1[] = {0x80, 0xFF};
16*5d3e7166SEd Maste 
test_empty_array(void ** _CBOR_UNUSED (_state))17*5d3e7166SEd Maste static void test_empty_array(void **_CBOR_UNUSED(_state)) {
18*5d3e7166SEd Maste   arr = cbor_load(data1, 2, &res);
19*5d3e7166SEd Maste   assert_non_null(arr);
20*5d3e7166SEd Maste   assert_true(cbor_typeof(arr) == CBOR_TYPE_ARRAY);
21*5d3e7166SEd Maste   assert_true(cbor_isa_array(arr));
22*5d3e7166SEd Maste   assert_true(cbor_array_size(arr) == 0);
23*5d3e7166SEd Maste   assert_true(res.read == 1);
24*5d3e7166SEd Maste   cbor_decref(&arr);
25*5d3e7166SEd Maste   assert_null(arr);
26*5d3e7166SEd Maste }
27*5d3e7166SEd Maste 
28*5d3e7166SEd Maste unsigned char data2[] = {0x81, 0x01, 0xFF};
29*5d3e7166SEd Maste 
test_simple_array(void ** _CBOR_UNUSED (_state))30*5d3e7166SEd Maste static void test_simple_array(void **_CBOR_UNUSED(_state)) {
31*5d3e7166SEd Maste   arr = cbor_load(data2, 3, &res);
32*5d3e7166SEd Maste   assert_non_null(arr);
33*5d3e7166SEd Maste   assert_true(cbor_typeof(arr) == CBOR_TYPE_ARRAY);
34*5d3e7166SEd Maste   assert_true(cbor_isa_array(arr));
35*5d3e7166SEd Maste   assert_size_equal(cbor_array_size(arr), 1);
36*5d3e7166SEd Maste   assert_true(res.read == 2);
37*5d3e7166SEd Maste   assert_size_equal(cbor_array_allocated(arr), 1);
38*5d3e7166SEd Maste   /* Check the values */
39*5d3e7166SEd Maste   assert_uint8(cbor_array_handle(arr)[0], 1);
40*5d3e7166SEd Maste   cbor_item_t *intermediate = cbor_array_get(arr, 0);
41*5d3e7166SEd Maste   assert_uint8(intermediate, 1);
42*5d3e7166SEd Maste 
43*5d3e7166SEd Maste   cbor_item_t *new_val = cbor_build_uint8(10);
44*5d3e7166SEd Maste   assert_false(cbor_array_set(arr, 1, new_val));
45*5d3e7166SEd Maste   assert_false(cbor_array_set(arr, 3, new_val));
46*5d3e7166SEd Maste   cbor_decref(&new_val);
47*5d3e7166SEd Maste 
48*5d3e7166SEd Maste   cbor_decref(&arr);
49*5d3e7166SEd Maste   cbor_decref(&intermediate);
50*5d3e7166SEd Maste   assert_null(arr);
51*5d3e7166SEd Maste   assert_null(intermediate);
52*5d3e7166SEd Maste }
53*5d3e7166SEd Maste 
54*5d3e7166SEd Maste unsigned char data3[] = {0x82, 0x01, 0x81, 0x01, 0xFF};
55*5d3e7166SEd Maste 
test_nested_arrays(void ** _CBOR_UNUSED (_state))56*5d3e7166SEd Maste static void test_nested_arrays(void **_CBOR_UNUSED(_state)) {
57*5d3e7166SEd Maste   arr = cbor_load(data3, 5, &res);
58*5d3e7166SEd Maste   assert_non_null(arr);
59*5d3e7166SEd Maste   assert_true(cbor_typeof(arr) == CBOR_TYPE_ARRAY);
60*5d3e7166SEd Maste   assert_true(cbor_isa_array(arr));
61*5d3e7166SEd Maste   assert_true(cbor_array_size(arr) == 2);
62*5d3e7166SEd Maste   assert_true(res.read == 4);
63*5d3e7166SEd Maste   /* Check the values */
64*5d3e7166SEd Maste   assert_uint8(cbor_array_handle(arr)[0], 1);
65*5d3e7166SEd Maste 
66*5d3e7166SEd Maste   cbor_item_t *nested = cbor_array_handle(arr)[1];
67*5d3e7166SEd Maste   assert_true(cbor_isa_array(nested));
68*5d3e7166SEd Maste   assert_true(cbor_array_size(nested) == 1);
69*5d3e7166SEd Maste   assert_uint8(cbor_array_handle(nested)[0], 1);
70*5d3e7166SEd Maste 
71*5d3e7166SEd Maste   cbor_decref(&arr);
72*5d3e7166SEd Maste   assert_null(arr);
73*5d3e7166SEd Maste }
74*5d3e7166SEd Maste 
75*5d3e7166SEd Maste unsigned char test_indef_arrays_data[] = {0x9f, 0x01, 0x02, 0xFF};
76*5d3e7166SEd Maste 
test_indef_arrays(void ** _CBOR_UNUSED (_state))77*5d3e7166SEd Maste static void test_indef_arrays(void **_CBOR_UNUSED(_state)) {
78*5d3e7166SEd Maste   arr = cbor_load(test_indef_arrays_data, 4, &res);
79*5d3e7166SEd Maste   assert_non_null(arr);
80*5d3e7166SEd Maste   assert_true(cbor_typeof(arr) == CBOR_TYPE_ARRAY);
81*5d3e7166SEd Maste   assert_true(cbor_isa_array(arr));
82*5d3e7166SEd Maste   assert_true(cbor_array_size(arr) == 2);
83*5d3e7166SEd Maste   assert_true(res.read == 4);
84*5d3e7166SEd Maste   /* Check the values */
85*5d3e7166SEd Maste   assert_uint8(cbor_array_handle(arr)[0], 1);
86*5d3e7166SEd Maste   assert_uint8(cbor_array_handle(arr)[1], 2);
87*5d3e7166SEd Maste 
88*5d3e7166SEd Maste   assert_true(cbor_array_set(arr, 1, cbor_move(cbor_build_uint8(10))));
89*5d3e7166SEd Maste 
90*5d3e7166SEd Maste   cbor_decref(&arr);
91*5d3e7166SEd Maste   assert_null(arr);
92*5d3e7166SEd Maste }
93*5d3e7166SEd Maste 
94*5d3e7166SEd Maste unsigned char test_nested_indef_arrays_data[] = {0x9f, 0x01, 0x9f, 0x02,
95*5d3e7166SEd Maste                                                  0xFF, 0x03, 0xFF};
96*5d3e7166SEd Maste 
test_nested_indef_arrays(void ** _CBOR_UNUSED (_state))97*5d3e7166SEd Maste static void test_nested_indef_arrays(void **_CBOR_UNUSED(_state)) {
98*5d3e7166SEd Maste   arr = cbor_load(test_nested_indef_arrays_data, 7, &res);
99*5d3e7166SEd Maste   assert_non_null(arr);
100*5d3e7166SEd Maste   assert_true(cbor_typeof(arr) == CBOR_TYPE_ARRAY);
101*5d3e7166SEd Maste   assert_true(cbor_isa_array(arr));
102*5d3e7166SEd Maste   assert_size_equal(cbor_array_size(arr), 3);
103*5d3e7166SEd Maste   assert_true(res.read == 7);
104*5d3e7166SEd Maste   /* Check the values */
105*5d3e7166SEd Maste   assert_uint8(cbor_array_handle(arr)[0], 1);
106*5d3e7166SEd Maste 
107*5d3e7166SEd Maste   cbor_item_t *nested = cbor_array_handle(arr)[1];
108*5d3e7166SEd Maste   assert_true(cbor_isa_array(nested));
109*5d3e7166SEd Maste   assert_true(cbor_array_size(nested) == 1);
110*5d3e7166SEd Maste   assert_uint8(cbor_array_handle(nested)[0], 2);
111*5d3e7166SEd Maste 
112*5d3e7166SEd Maste   cbor_decref(&arr);
113*5d3e7166SEd Maste   assert_null(arr);
114*5d3e7166SEd Maste }
115*5d3e7166SEd Maste 
test_array_replace(void ** _CBOR_UNUSED (_state))116*5d3e7166SEd Maste static void test_array_replace(void **_CBOR_UNUSED(_state)) {
117*5d3e7166SEd Maste   cbor_item_t *array = cbor_new_definite_array(2);
118*5d3e7166SEd Maste   assert_size_equal(cbor_array_size(array), 0);
119*5d3e7166SEd Maste   cbor_item_t *one = cbor_build_uint8(1);
120*5d3e7166SEd Maste   cbor_item_t *three = cbor_build_uint8(3);
121*5d3e7166SEd Maste   assert_size_equal(cbor_refcount(one), 1);
122*5d3e7166SEd Maste   assert_size_equal(cbor_refcount(three), 1);
123*5d3e7166SEd Maste 
124*5d3e7166SEd Maste   // No item to replace
125*5d3e7166SEd Maste   assert_false(cbor_array_replace(array, 0, three));
126*5d3e7166SEd Maste   assert_size_equal(cbor_refcount(three), 1);
127*5d3e7166SEd Maste 
128*5d3e7166SEd Maste   // Add items [1, 2]
129*5d3e7166SEd Maste   assert_true(cbor_array_push(array, one));
130*5d3e7166SEd Maste   assert_true(cbor_array_push(array, cbor_move(cbor_build_uint8(2))));
131*5d3e7166SEd Maste   assert_size_equal(cbor_refcount(one), 2);
132*5d3e7166SEd Maste   assert_size_equal(cbor_array_size(array), 2);
133*5d3e7166SEd Maste 
134*5d3e7166SEd Maste   // Array has only two items
135*5d3e7166SEd Maste   assert_false(cbor_array_replace(array, 2, three));
136*5d3e7166SEd Maste   assert_size_equal(cbor_refcount(three), 1);
137*5d3e7166SEd Maste 
138*5d3e7166SEd Maste   // Change [1, 2] to [3, 2]
139*5d3e7166SEd Maste   assert_true(cbor_array_replace(array, 0, three));
140*5d3e7166SEd Maste   assert_size_equal(cbor_refcount(one), 1);
141*5d3e7166SEd Maste   assert_size_equal(cbor_refcount(three), 2);
142*5d3e7166SEd Maste   assert_uint8(cbor_move(cbor_array_get(array, 0)), 3);
143*5d3e7166SEd Maste   assert_uint8(cbor_move(cbor_array_get(array, 1)), 2);
144*5d3e7166SEd Maste 
145*5d3e7166SEd Maste   cbor_decref(&one);
146*5d3e7166SEd Maste   cbor_decref(&three);
147*5d3e7166SEd Maste   cbor_decref(&array);
148*5d3e7166SEd Maste }
149*5d3e7166SEd Maste 
test_array_push_overflow(void ** _CBOR_UNUSED (_state))150*5d3e7166SEd Maste static void test_array_push_overflow(void **_CBOR_UNUSED(_state)) {
151*5d3e7166SEd Maste   cbor_item_t *array = cbor_new_indefinite_array();
152*5d3e7166SEd Maste   cbor_item_t *one = cbor_build_uint8(1);
153*5d3e7166SEd Maste   struct _cbor_array_metadata *metadata =
154*5d3e7166SEd Maste       (struct _cbor_array_metadata *)&array->metadata;
155*5d3e7166SEd Maste   // Pretend we already have a huge block allocated
156*5d3e7166SEd Maste   metadata->allocated = SIZE_MAX;
157*5d3e7166SEd Maste   metadata->end_ptr = SIZE_MAX;
158*5d3e7166SEd Maste 
159*5d3e7166SEd Maste   assert_false(cbor_array_push(array, one));
160*5d3e7166SEd Maste   assert_size_equal(cbor_refcount(one), 1);
161*5d3e7166SEd Maste 
162*5d3e7166SEd Maste   cbor_decref(&one);
163*5d3e7166SEd Maste   metadata->allocated = 0;
164*5d3e7166SEd Maste   metadata->end_ptr = 0;
165*5d3e7166SEd Maste   cbor_decref(&array);
166*5d3e7166SEd Maste }
167*5d3e7166SEd Maste 
test_array_creation(void ** _CBOR_UNUSED (_state))168*5d3e7166SEd Maste static void test_array_creation(void **_CBOR_UNUSED(_state)) {
169*5d3e7166SEd Maste   WITH_FAILING_MALLOC({ assert_null(cbor_new_definite_array(42)); });
170*5d3e7166SEd Maste   WITH_MOCK_MALLOC({ assert_null(cbor_new_definite_array(42)); }, 2, MALLOC,
171*5d3e7166SEd Maste                    MALLOC_FAIL);
172*5d3e7166SEd Maste 
173*5d3e7166SEd Maste   WITH_FAILING_MALLOC({ assert_null(cbor_new_indefinite_array()); });
174*5d3e7166SEd Maste }
175*5d3e7166SEd Maste 
test_array_push(void ** _CBOR_UNUSED (_state))176*5d3e7166SEd Maste static void test_array_push(void **_CBOR_UNUSED(_state)) {
177*5d3e7166SEd Maste   WITH_MOCK_MALLOC(
178*5d3e7166SEd Maste       {
179*5d3e7166SEd Maste         cbor_item_t *array = cbor_new_indefinite_array();
180*5d3e7166SEd Maste         cbor_item_t *string = cbor_build_string("Hello!");
181*5d3e7166SEd Maste 
182*5d3e7166SEd Maste         assert_false(cbor_array_push(array, string));
183*5d3e7166SEd Maste         assert_size_equal(cbor_array_allocated(array), 0);
184*5d3e7166SEd Maste         assert_null(array->data);
185*5d3e7166SEd Maste         assert_size_equal(array->metadata.array_metadata.end_ptr, 0);
186*5d3e7166SEd Maste 
187*5d3e7166SEd Maste         cbor_decref(&string);
188*5d3e7166SEd Maste         cbor_decref(&array);
189*5d3e7166SEd Maste       },
190*5d3e7166SEd Maste       4, MALLOC, MALLOC, MALLOC, REALLOC_FAIL);
191*5d3e7166SEd Maste }
192*5d3e7166SEd Maste 
193*5d3e7166SEd Maste static unsigned char simple_indef_array[] = {0x9F, 0x01, 0x02, 0xFF};
test_indef_array_decode(void ** _CBOR_UNUSED (_state))194*5d3e7166SEd Maste static void test_indef_array_decode(void **_CBOR_UNUSED(_state)) {
195*5d3e7166SEd Maste   WITH_MOCK_MALLOC(
196*5d3e7166SEd Maste       {
197*5d3e7166SEd Maste         cbor_item_t *array;
198*5d3e7166SEd Maste         struct cbor_load_result res;
199*5d3e7166SEd Maste         array = cbor_load(simple_indef_array, 4, &res);
200*5d3e7166SEd Maste 
201*5d3e7166SEd Maste         assert_null(array);
202*5d3e7166SEd Maste         assert_size_equal(res.error.code, CBOR_ERR_MEMERROR);
203*5d3e7166SEd Maste       },
204*5d3e7166SEd Maste       4, MALLOC, MALLOC, MALLOC, REALLOC_FAIL);
205*5d3e7166SEd Maste }
206*5d3e7166SEd Maste 
main(void)207*5d3e7166SEd Maste int main(void) {
208*5d3e7166SEd Maste   const struct CMUnitTest tests[] = {
209*5d3e7166SEd Maste       cmocka_unit_test(test_empty_array),
210*5d3e7166SEd Maste       cmocka_unit_test(test_simple_array),
211*5d3e7166SEd Maste       cmocka_unit_test(test_nested_arrays),
212*5d3e7166SEd Maste       cmocka_unit_test(test_indef_arrays),
213*5d3e7166SEd Maste       cmocka_unit_test(test_nested_indef_arrays),
214*5d3e7166SEd Maste       cmocka_unit_test(test_array_replace),
215*5d3e7166SEd Maste       cmocka_unit_test(test_array_push_overflow),
216*5d3e7166SEd Maste       cmocka_unit_test(test_array_creation),
217*5d3e7166SEd Maste       cmocka_unit_test(test_array_push),
218*5d3e7166SEd Maste       cmocka_unit_test(test_indef_array_decode),
219*5d3e7166SEd Maste   };
220*5d3e7166SEd Maste 
221*5d3e7166SEd Maste   return cmocka_run_group_tests(tests, NULL, NULL);
222*5d3e7166SEd Maste }
223