1 /*
2 * Copyright (c) 2022-2023 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/ztest.h>
8 #include <zcbor_common.h>
9 #include <zcbor_decode.h>
10 #include <zcbor_encode.h>
11 #include "mgmt/mcumgr/util/zcbor_bulk.h"
12
13 #define zcbor_true_put(zse) zcbor_bool_put(zse, true)
14
ZTEST(zcbor_bulk,test_ZCBOR_MAP_DECODE_KEY_DECODER)15 ZTEST(zcbor_bulk, test_ZCBOR_MAP_DECODE_KEY_DECODER)
16 {
17 struct zcbor_string world;
18 struct zcbor_map_decode_key_val map_one[] = {
19 ZCBOR_MAP_DECODE_KEY_DECODER("hello", zcbor_tstr_decode, &world),
20 };
21 /* ZCBOR_MAP_DECODE_KEY_DECODER should not be used but is still provided */
22 struct zcbor_map_decode_key_val map_two[] = {
23 ZCBOR_MAP_DECODE_KEY_VAL(hello, zcbor_tstr_decode, &world),
24 };
25
26 zassert_ok(strcmp(map_one[0].key.value, "hello"));
27 zassert_equal(map_one[0].key.len, sizeof("hello") - 1);
28 zassert_equal((void *)map_one[0].decoder, (void *)&zcbor_tstr_decode);
29 zassert_equal((void *)map_one[0].value_ptr, (void *)&world);
30 /* Both maps should be the same */
31 zassert_ok(strcmp(map_one[0].key.value, map_two[0].key.value));
32 zassert_equal(map_one[0].key.len, map_two[0].key.len);
33 zassert_equal(map_one[0].decoder, map_two[0].decoder);
34 zassert_equal(map_one[0].value_ptr, map_two[0].value_ptr);
35 }
36
ZTEST(zcbor_bulk,test_correct)37 ZTEST(zcbor_bulk, test_correct)
38 {
39 uint8_t buffer[512];
40 struct zcbor_string world;
41 uint32_t one = 0;
42 bool bool_val = false;
43 zcbor_state_t zsd[4] = { 0 };
44 size_t decoded = 0;
45 bool ok;
46 struct zcbor_map_decode_key_val dm[] = {
47 ZCBOR_MAP_DECODE_KEY_DECODER("hello", zcbor_tstr_decode, &world),
48 ZCBOR_MAP_DECODE_KEY_DECODER("one", zcbor_uint32_decode, &one),
49 ZCBOR_MAP_DECODE_KEY_DECODER("bool val", zcbor_bool_decode, &bool_val)
50 };
51
52 zcbor_new_encode_state(zsd, 2, buffer, ARRAY_SIZE(buffer), 0);
53
54 /* { "hello":"world", "one":1, "bool_val":true } */
55 ok = zcbor_map_start_encode(zsd, 10) &&
56 zcbor_tstr_put_lit(zsd, "hello") && zcbor_tstr_put_lit(zsd, "world") &&
57 zcbor_tstr_put_lit(zsd, "one") && zcbor_uint32_put(zsd, 1) &&
58 zcbor_tstr_put_lit(zsd, "bool val") && zcbor_true_put(zsd) &&
59 zcbor_map_end_encode(zsd, 10);
60
61 zassert_true(ok, "Expected to be successful in encoding test pattern");
62
63 zcbor_new_decode_state(zsd, 4, buffer, ARRAY_SIZE(buffer), 1, NULL, 0);
64
65 int rc = zcbor_map_decode_bulk(zsd, dm, ARRAY_SIZE(dm), &decoded);
66
67 zassert_ok(rc, "Expected 0, got %d", rc);
68 zassert_equal(decoded, ARRAY_SIZE(dm), "Expected %d got %d",
69 ARRAY_SIZE(dm), decoded);
70 zassert_equal(one, 1, "Expected 1");
71 zassert_equal(sizeof("world") - 1, world.len, "Expected length %d",
72 sizeof("world") - 1);
73 zassert_equal(0, memcmp(world.value, "world", world.len),
74 "Expected \"world\", got %.*s", (int)world.len, world.value);
75 zassert_true(bool_val, "Expected bool val == true");
76 }
77
ZTEST(zcbor_bulk,test_correct_out_of_order)78 ZTEST(zcbor_bulk, test_correct_out_of_order)
79 {
80 uint8_t buffer[512];
81 struct zcbor_string world;
82 uint32_t one = 0;
83 bool bool_val = false;
84 zcbor_state_t zsd[4] = { 0 };
85 size_t decoded = 0;
86 bool ok;
87 struct zcbor_map_decode_key_val dm[] = {
88 ZCBOR_MAP_DECODE_KEY_DECODER("hello", zcbor_tstr_decode, &world),
89 ZCBOR_MAP_DECODE_KEY_DECODER("one", zcbor_uint32_decode, &one),
90 ZCBOR_MAP_DECODE_KEY_DECODER("bool val", zcbor_bool_decode, &bool_val)
91 };
92
93 zcbor_new_encode_state(zsd, 2, buffer, ARRAY_SIZE(buffer), 0);
94
95 /* { "hello":"world", "one":1, "bool_val":true } */
96 ok = zcbor_map_start_encode(zsd, 10) &&
97 zcbor_tstr_put_lit(zsd, "bool val") && zcbor_true_put(zsd) &&
98 zcbor_tstr_put_lit(zsd, "one") && zcbor_uint32_put(zsd, 1) &&
99 zcbor_tstr_put_lit(zsd, "hello") && zcbor_tstr_put_lit(zsd, "world") &&
100 zcbor_map_end_encode(zsd, 10);
101
102 zassert_true(ok, "Expected to be successful in encoding test pattern");
103
104 zcbor_new_decode_state(zsd, 4, buffer, ARRAY_SIZE(buffer), 1, NULL, 0);
105
106 int rc = zcbor_map_decode_bulk(zsd, dm, ARRAY_SIZE(dm), &decoded);
107
108 zassert_ok(rc, "Expected 0, got %d", rc);
109 zassert_equal(decoded, ARRAY_SIZE(dm), "Expected %d got %d",
110 ARRAY_SIZE(dm), decoded);
111 zassert_equal(one, 1, "Expected 1");
112 zassert_equal(sizeof("world") - 1, world.len, "Expected length %d",
113 sizeof("world") - 1);
114 zassert_equal(0, memcmp(world.value, "world", world.len),
115 "Expected \"world\", got %.*s", (int)world.len, world.value);
116 zassert_true(bool_val, "Expected bool val == true");
117 }
118
ZTEST(zcbor_bulk,test_not_map)119 ZTEST(zcbor_bulk, test_not_map)
120 {
121 uint8_t buffer[512];
122 struct zcbor_string world;
123 uint32_t one = 0;
124 bool bool_val = false;
125 zcbor_state_t zsd[4] = { 0 };
126 size_t decoded = 1111;
127 bool ok;
128 struct zcbor_map_decode_key_val dm[] = {
129 ZCBOR_MAP_DECODE_KEY_DECODER("hello", zcbor_tstr_decode, &world),
130 ZCBOR_MAP_DECODE_KEY_DECODER("one", zcbor_uint32_decode, &one),
131 ZCBOR_MAP_DECODE_KEY_DECODER("bool val", zcbor_bool_decode, &bool_val)
132 };
133
134 zcbor_new_encode_state(zsd, 2, buffer, ARRAY_SIZE(buffer), 0);
135
136 /* List "hello", "world" */
137 ok = zcbor_list_start_encode(zsd, 10) &&
138 zcbor_tstr_put_lit(zsd, "hello") && zcbor_tstr_put_lit(zsd, "world") &&
139 zcbor_list_end_encode(zsd, 10);
140
141 zassert_true(ok, "Expected to be successful in encoding test pattern");
142
143 zcbor_new_decode_state(zsd, 4, buffer, ARRAY_SIZE(buffer), 1, NULL, 0);
144
145 int rc = zcbor_map_decode_bulk(zsd, dm, ARRAY_SIZE(dm), &decoded);
146
147 zassert_equal(rc, -EBADMSG, "Expected -EBADMSG(%d), got %d", -EBADMSG, rc);
148 zassert_equal(decoded, 1111, "Expected decoded value to be unmodified");
149 }
150
ZTEST(zcbor_bulk,test_bad_type)151 ZTEST(zcbor_bulk, test_bad_type)
152 {
153 uint8_t buffer[512];
154 struct zcbor_string world = { 0 };
155 uint32_t one = 0;
156 bool bool_val = false;
157 zcbor_state_t zsd[4] = { 0 };
158 size_t decoded = 0;
159 bool ok;
160 struct zcbor_map_decode_key_val dm[] = {
161 /* First entry has bad decoder given instead of tstr */
162 ZCBOR_MAP_DECODE_KEY_DECODER("hello", zcbor_uint32_decode, &world),
163 ZCBOR_MAP_DECODE_KEY_DECODER("one", zcbor_uint32_decode, &one),
164 ZCBOR_MAP_DECODE_KEY_DECODER("bool val", zcbor_bool_decode, &bool_val)
165 };
166
167 zcbor_new_encode_state(zsd, 2, buffer, ARRAY_SIZE(buffer), 0);
168
169 /* { "hello":"world", "one":1, "bool_val":true } */
170 ok = zcbor_map_start_encode(zsd, 10) &&
171 zcbor_tstr_put_lit(zsd, "hello") && zcbor_tstr_put_lit(zsd, "world") &&
172 zcbor_tstr_put_lit(zsd, "one") && zcbor_uint32_put(zsd, 1) &&
173 zcbor_tstr_put_lit(zsd, "bool val") && zcbor_true_put(zsd) &&
174 zcbor_map_end_encode(zsd, 10);
175
176 zassert_true(ok, "Expected to be successful in encoding test pattern");
177
178 zcbor_new_decode_state(zsd, 4, buffer, ARRAY_SIZE(buffer), 1, NULL, 0);
179
180 int rc = zcbor_map_decode_bulk(zsd, dm, ARRAY_SIZE(dm), &decoded);
181
182 zassert_equal(rc, -ENOMSG, "Expected -ENOMSG, got %d", rc);
183 zassert_equal(decoded, 0, "Expected 0 got %d", decoded);
184 zassert_equal(one, 0, "Expected 0");
185 zassert_equal(0, world.len, "Expected to be unmodified");
186 zassert_false(bool_val, "Expected bool val == false");
187 }
188
ZTEST(zcbor_bulk,test_bad_type_2)189 ZTEST(zcbor_bulk, test_bad_type_2)
190 {
191 uint8_t buffer[512];
192 struct zcbor_string world = { 0 };
193 uint32_t one = 0;
194 bool bool_val = false;
195 zcbor_state_t zsd[4] = { 0 };
196 size_t decoded = 0;
197 bool ok;
198 struct zcbor_map_decode_key_val dm[] = {
199 ZCBOR_MAP_DECODE_KEY_DECODER("hello", zcbor_tstr_decode, &world),
200 ZCBOR_MAP_DECODE_KEY_DECODER("one", zcbor_uint32_decode, &one),
201 /* This is bad decoder for type bool */
202 ZCBOR_MAP_DECODE_KEY_DECODER("bool val", zcbor_tstr_decode, &bool_val)
203 };
204
205 zcbor_new_encode_state(zsd, 2, buffer, ARRAY_SIZE(buffer), 0);
206
207 /* { "hello":"world", "one":1, "bool_val":true } */
208 ok = zcbor_map_start_encode(zsd, 10) &&
209 zcbor_tstr_put_lit(zsd, "hello") && zcbor_tstr_put_lit(zsd, "world") &&
210 zcbor_tstr_put_lit(zsd, "one") && zcbor_uint32_put(zsd, 1) &&
211 zcbor_tstr_put_lit(zsd, "bool val") && zcbor_true_put(zsd) &&
212 zcbor_map_end_encode(zsd, 10);
213
214 zcbor_new_decode_state(zsd, 4, buffer, ARRAY_SIZE(buffer), 1, NULL, 0);
215
216 int rc = zcbor_map_decode_bulk(zsd, dm, ARRAY_SIZE(dm), &decoded);
217
218 zassert_equal(rc, -ENOMSG, "Expected -ENOMSG, got %d", rc);
219 zassert_equal(decoded, ARRAY_SIZE(dm) - 1, "Expected %d got %d",
220 ARRAY_SIZE(dm) - 1, decoded);
221 zassert_equal(one, 1, "Expected 1");
222 zassert_equal(sizeof("world") - 1, world.len, "Expected length %d",
223 sizeof("world") - 1);
224 zassert_equal(0, memcmp(world.value, "world", world.len),
225 "Expected \"world\", got %.*s", (int)world.len, world.value);
226 zassert_false(bool_val, "Expected bool val unmodified");
227 }
228
ZTEST(zcbor_bulk,test_bad_type_encoded)229 ZTEST(zcbor_bulk, test_bad_type_encoded)
230 {
231 uint8_t buffer[512];
232 struct zcbor_string world = { 0 };
233 uint32_t one = 0;
234 bool bool_val = false;
235 zcbor_state_t zsd[4] = { 0 };
236 size_t decoded = 0;
237 bool ok;
238 struct zcbor_map_decode_key_val dm[] = {
239 ZCBOR_MAP_DECODE_KEY_DECODER("hello", zcbor_tstr_decode, &world),
240 ZCBOR_MAP_DECODE_KEY_DECODER("one", zcbor_uint32_decode, &one),
241 ZCBOR_MAP_DECODE_KEY_DECODER("bool val", zcbor_bool_decode, &bool_val)
242 };
243
244 zcbor_new_encode_state(zsd, 2, buffer, ARRAY_SIZE(buffer), 0);
245
246 /* { "hello":"world", "one":1, "bool_val":true } */
247 ok = zcbor_map_start_encode(zsd, 10) &&
248 zcbor_tstr_put_lit(zsd, "hello") && zcbor_uint32_put(zsd, 10) &&
249 zcbor_tstr_put_lit(zsd, "one") && zcbor_uint32_put(zsd, 1) &&
250 zcbor_tstr_put_lit(zsd, "bool val") && zcbor_true_put(zsd) &&
251 zcbor_map_end_encode(zsd, 10);
252
253 zassert_true(ok, "Expected to be successful in encoding test pattern");
254
255 zcbor_new_decode_state(zsd, 4, buffer, ARRAY_SIZE(buffer), 1, NULL, 0);
256
257 int rc = zcbor_map_decode_bulk(zsd, dm, ARRAY_SIZE(dm), &decoded);
258
259 zassert_equal(rc, -ENOMSG, "Expected -ENOMSG, got %d", rc);
260 zassert_equal(decoded, 0, "Expected 0 got %d", decoded);
261 zassert_equal(one, 0, "Expected 0");
262 zassert_equal(0, world.len, "Expected to be unmodified");
263 zassert_false(bool_val, "Expected bool val == false");
264 }
265
ZTEST(zcbor_bulk,test_duplicate)266 ZTEST(zcbor_bulk, test_duplicate)
267 {
268 /* Duplicate key is error and should never happen */
269 uint8_t buffer[512];
270 struct zcbor_string world = { 0 };
271 uint32_t one = 0;
272 bool bool_val = false;
273 zcbor_state_t zsd[4] = { 0 };
274 size_t decoded = 0;
275 bool ok;
276 struct zcbor_map_decode_key_val dm[] = {
277 ZCBOR_MAP_DECODE_KEY_DECODER("hello", zcbor_tstr_decode, &world),
278 ZCBOR_MAP_DECODE_KEY_DECODER("one", zcbor_uint32_decode, &one),
279 ZCBOR_MAP_DECODE_KEY_DECODER("bool val", zcbor_bool_decode, &bool_val)
280 };
281
282 zcbor_new_encode_state(zsd, 2, buffer, ARRAY_SIZE(buffer), 0);
283
284 /* { "hello":"world", "hello":"world" } */
285 ok = zcbor_map_start_encode(zsd, 10) &&
286 zcbor_tstr_put_lit(zsd, "hello") && zcbor_tstr_put_lit(zsd, "world") &&
287 zcbor_tstr_put_lit(zsd, "hello") && zcbor_tstr_put_lit(zsd, "world") &&
288 zcbor_map_end_encode(zsd, 10);
289
290 zcbor_new_decode_state(zsd, 4, buffer, ARRAY_SIZE(buffer), 1, NULL, 0);
291
292 int rc = zcbor_map_decode_bulk(zsd, dm, ARRAY_SIZE(dm), &decoded);
293
294 zassert_equal(rc, -EADDRINUSE, "Expected -EADDRINUSE, got %d", rc);
295 zassert_equal(decoded, 1, "Expected %d got %d",
296 ARRAY_SIZE(dm) - 1, decoded);
297 zassert_equal(one, 0, "Expected unmodified");
298 zassert_equal(sizeof("world") - 1, world.len, "Expected length %d",
299 sizeof("world") - 1);
300 zassert_equal(0, memcmp(world.value, "world", world.len),
301 "Expected \"world\", got %.*s", (int)world.len, world.value);
302 zassert_false(bool_val, "Expected bool val unmodified");
303 }
304
305 struct in_map_decoding {
306 size_t decoded;
307 int ret;
308 uint32_t number;
309 struct zcbor_string str;
310 uint32_t other_number;
311 };
312
in_map_decoder(zcbor_state_t * zsd,struct in_map_decoding * imd)313 static bool in_map_decoder(zcbor_state_t *zsd, struct in_map_decoding *imd)
314 {
315 uint32_t dont_exist = 0x64;
316 struct zcbor_map_decode_key_val in_map[] = {
317 ZCBOR_MAP_DECODE_KEY_VAL(number, zcbor_uint32_decode, &imd->number),
318 ZCBOR_MAP_DECODE_KEY_VAL(str, zcbor_tstr_decode, &imd->str),
319 ZCBOR_MAP_DECODE_KEY_VAL(dont_exist, zcbor_uint32_decode, &dont_exist),
320 };
321
322 imd->ret = zcbor_map_decode_bulk(zsd, in_map, ARRAY_SIZE(in_map), &imd->decoded);
323
324 zassert_equal(dont_exist, 0x64, "dont_exist should not have get modified");
325
326 return (imd->ret == 0);
327 }
328
ZTEST(zcbor_bulk,test_map_in_map_correct)329 ZTEST(zcbor_bulk, test_map_in_map_correct)
330 {
331 uint8_t buffer[512];
332 struct zcbor_string world;
333 uint32_t one = 0;
334 bool bool_val = false;
335 zcbor_state_t zsd[4] = { 0 };
336 size_t decoded = 0;
337 bool ok;
338 struct in_map_decoding imdd = { .ret = -1 };
339 struct zcbor_map_decode_key_val dm[] = {
340 ZCBOR_MAP_DECODE_KEY_VAL(hello, zcbor_tstr_decode, &world),
341 ZCBOR_MAP_DECODE_KEY_VAL(in_map_map, in_map_decoder, &imdd),
342 ZCBOR_MAP_DECODE_KEY_VAL(one, zcbor_uint32_decode, &one),
343 ZCBOR_MAP_DECODE_KEY_VAL(bool_val, zcbor_bool_decode, &bool_val)
344 };
345
346 zcbor_new_encode_state(zsd, 2, buffer, ARRAY_SIZE(buffer), 0);
347
348 /* { "hello":"world",
349 * "in_map" : {
350 * "number" : 30,
351 * "str" : "in_str"
352 * },
353 * "one":1,
354 * "bool_val":true }
355 */
356 ok = zcbor_map_start_encode(zsd, 10) &&
357 zcbor_tstr_put_lit(zsd, "hello") && zcbor_tstr_put_lit(zsd, "world") &&
358 zcbor_tstr_put_lit(zsd, "in_map_map") &&
359 zcbor_map_start_encode(zsd, 10) &&
360 zcbor_tstr_put_lit(zsd, "number") && zcbor_uint32_put(zsd, 30) &&
361 zcbor_tstr_put_lit(zsd, "str") && zcbor_tstr_put_lit(zsd, "in_str") &&
362 zcbor_map_end_encode(zsd, 10) &&
363 zcbor_tstr_put_lit(zsd, "one") && zcbor_uint32_put(zsd, 1) &&
364 zcbor_tstr_put_lit(zsd, "bool_val") && zcbor_true_put(zsd) &&
365 zcbor_map_end_encode(zsd, 10);
366
367 zassert_true(ok, "Expected to be successful in encoding test pattern");
368
369 zcbor_new_decode_state(zsd, 4, buffer, ARRAY_SIZE(buffer), 1, NULL, 0);
370
371 int rc = zcbor_map_decode_bulk(zsd, dm, ARRAY_SIZE(dm), &decoded);
372
373 zassert_ok(rc, "Expected 0, got %d", rc);
374 zassert_equal(decoded, ARRAY_SIZE(dm), "Expected %d got %d",
375 ARRAY_SIZE(dm), decoded);
376 zassert_equal(one, 1, "Expected 1");
377 zassert_equal(sizeof("world") - 1, world.len, "Expected length %d",
378 sizeof("world") - 1);
379 zassert_equal(0, memcmp(world.value, "world", world.len),
380 "Expected \"world\", got %.*s", (int)world.len, world.value);
381 zassert_true(bool_val, "Expected bool_val == true");
382
383 /* Map within map */
384 zassert_equal(imdd.ret, 0, "Expected successful decoding of inner map");
385 zassert_equal(imdd.decoded, 2, "Expected two items in inner map");
386 zassert_equal(imdd.number, 30);
387 zassert_equal(imdd.str.len, sizeof("in_str") - 1);
388 zassert_equal(memcmp("in_str", imdd.str.value, imdd.str.len), 0);
389 }
390
in_map_decoder_bad(zcbor_state_t * zsd,struct in_map_decoding * imd)391 static bool in_map_decoder_bad(zcbor_state_t *zsd, struct in_map_decoding *imd)
392 {
393 uint32_t dont_exist = 0x64;
394 uint32_t wrong_type = 0x34;
395 struct zcbor_map_decode_key_val in_map[] = {
396 ZCBOR_MAP_DECODE_KEY_VAL(number, zcbor_uint32_decode, &imd->number),
397 ZCBOR_MAP_DECODE_KEY_VAL(str, zcbor_uint32_decode, &wrong_type),
398 ZCBOR_MAP_DECODE_KEY_VAL(dont_exist, zcbor_uint32_decode, &dont_exist),
399 };
400
401 imd->ret = zcbor_map_decode_bulk(zsd, in_map, ARRAY_SIZE(in_map), &imd->decoded);
402
403 zassert_equal(dont_exist, 0x64, "dont_exist should not have get modified");
404
405 return (imd->ret == 0);
406 }
407
ZTEST(zcbor_bulk,test_map_in_map_bad)408 ZTEST(zcbor_bulk, test_map_in_map_bad)
409 {
410 uint8_t buffer[512];
411 struct zcbor_string world;
412 uint32_t one = 0;
413 bool bool_val = false;
414 zcbor_state_t zsd[4] = { 0 };
415 size_t decoded = 0;
416 bool ok;
417 struct in_map_decoding imdd = { .ret = -1 };
418 struct zcbor_map_decode_key_val dm[] = {
419 ZCBOR_MAP_DECODE_KEY_VAL(hello, zcbor_tstr_decode, &world),
420 ZCBOR_MAP_DECODE_KEY_VAL(in_map_map, in_map_decoder_bad, &imdd),
421 ZCBOR_MAP_DECODE_KEY_VAL(one, zcbor_uint32_decode, &one),
422 ZCBOR_MAP_DECODE_KEY_VAL(bool_val, zcbor_bool_decode, &bool_val)
423 };
424
425 zcbor_new_encode_state(zsd, 2, buffer, ARRAY_SIZE(buffer), 0);
426
427 /* { "hello":"world",
428 * "in_map" : {
429 * "number" : 30,
430 * "str" : "in_str" # Decoding function will expect str to be int
431 * },
432 * "one":1,
433 * "bool_val":true }
434 */
435 ok = zcbor_map_start_encode(zsd, 10) &&
436 zcbor_tstr_put_lit(zsd, "hello") && zcbor_tstr_put_lit(zsd, "world") &&
437 zcbor_tstr_put_lit(zsd, "in_map_map") &&
438 zcbor_map_start_encode(zsd, 10) &&
439 zcbor_tstr_put_lit(zsd, "number") && zcbor_uint32_put(zsd, 30) &&
440 zcbor_tstr_put_lit(zsd, "str") && zcbor_tstr_put_lit(zsd, "in_str") &&
441 zcbor_map_end_encode(zsd, 10) &&
442 zcbor_tstr_put_lit(zsd, "one") && zcbor_uint32_put(zsd, 1) &&
443 zcbor_tstr_put_lit(zsd, "bool_val") && zcbor_true_put(zsd) &&
444 zcbor_map_end_encode(zsd, 10);
445
446 zassert_true(ok, "Expected to be successful in encoding test pattern");
447
448 zcbor_new_decode_state(zsd, 4, buffer, ARRAY_SIZE(buffer), 1, NULL, 0);
449
450 int rc = zcbor_map_decode_bulk(zsd, dm, ARRAY_SIZE(dm), &decoded);
451
452 /* in_map_decoder_bad should fail */
453 zassert_equal(rc, -ENOMSG, "Expected ENOMSG(-42), got %d", rc);
454 zassert_equal(decoded, 1, "Expected 1 got %d", decoded);
455
456 /* Map within map */
457 zassert_equal(imdd.ret, -ENOMSG, "Expected failure in decoding of inner map");
458 zassert_equal(imdd.decoded, 1, "Expected 1 item before failure");
459 zassert_equal(imdd.number, 30);
460 }
461
ZTEST(zcbor_bulk,test_key_found)462 ZTEST(zcbor_bulk, test_key_found)
463 {
464 uint8_t buffer[512];
465 struct zcbor_string world;
466 uint32_t one = 0;
467 bool bool_val = false;
468 zcbor_state_t zsd[4] = { 0 };
469 size_t decoded = 0;
470 bool ok;
471 struct zcbor_map_decode_key_val dm[] = {
472 ZCBOR_MAP_DECODE_KEY_DECODER("hello", zcbor_tstr_decode, &world),
473 ZCBOR_MAP_DECODE_KEY_DECODER("one", zcbor_uint32_decode, &one),
474 ZCBOR_MAP_DECODE_KEY_DECODER("bool val", zcbor_bool_decode, &bool_val)
475 };
476
477 zcbor_new_encode_state(zsd, 2, buffer, ARRAY_SIZE(buffer), 0);
478
479 /* { "hello":"world", "bool val":true }, "one" is missing and will not be
480 * found.
481 */
482 ok = zcbor_map_start_encode(zsd, 10) &&
483 zcbor_tstr_put_lit(zsd, "hello") && zcbor_tstr_put_lit(zsd, "world") &&
484 zcbor_tstr_put_lit(zsd, "bool val") && zcbor_true_put(zsd) &&
485 zcbor_map_end_encode(zsd, 10);
486
487 zassert_true(ok, "Expected to be successful in encoding test pattern");
488
489 zcbor_new_decode_state(zsd, 4, buffer, ARRAY_SIZE(buffer), 1, NULL, 0);
490
491 int rc = zcbor_map_decode_bulk(zsd, dm, ARRAY_SIZE(dm), &decoded);
492
493 zassert_ok(rc, "Expected 0, got %d", rc);
494 zassert_equal(decoded, ARRAY_SIZE(dm) - 1, "Expected %d got %d",
495 ARRAY_SIZE(dm), decoded);
496
497 zassert_true(zcbor_map_decode_bulk_key_found(dm, ARRAY_SIZE(dm), "hello"),
498 "Expected \"hello\"");
499 zassert_false(zcbor_map_decode_bulk_key_found(dm, ARRAY_SIZE(dm), "one"),
500 "Unexpected \"one\"");
501 zassert_true(zcbor_map_decode_bulk_key_found(dm, ARRAY_SIZE(dm), "bool val"),
502 "Expected \"bool val\"");
503 }
504
ZTEST(zcbor_bulk,test_reset)505 ZTEST(zcbor_bulk, test_reset)
506 {
507 uint8_t buffer[512];
508 struct zcbor_string world;
509 uint32_t one = 0;
510 bool bool_val = false;
511 zcbor_state_t zsd[4] = { 0 };
512 size_t decoded = 0;
513 bool ok;
514 struct zcbor_map_decode_key_val dm[] = {
515 ZCBOR_MAP_DECODE_KEY_DECODER("hello", zcbor_tstr_decode, &world),
516 ZCBOR_MAP_DECODE_KEY_DECODER("one", zcbor_uint32_decode, &one),
517 ZCBOR_MAP_DECODE_KEY_DECODER("bool val", zcbor_bool_decode, &bool_val)
518 };
519
520 zcbor_new_encode_state(zsd, 2, buffer, ARRAY_SIZE(buffer), 0);
521
522 /* { "hello":"world", "one":1, "bool_val":true } */
523 ok = zcbor_map_start_encode(zsd, 10) &&
524 zcbor_tstr_put_lit(zsd, "hello") && zcbor_tstr_put_lit(zsd, "world") &&
525 zcbor_tstr_put_lit(zsd, "one") && zcbor_uint32_put(zsd, 1) &&
526 zcbor_tstr_put_lit(zsd, "bool val") && zcbor_true_put(zsd) &&
527 zcbor_map_end_encode(zsd, 10);
528
529 zassert_true(ok, "Expected to be successful in encoding test pattern");
530
531 zcbor_new_decode_state(zsd, 4, buffer, ARRAY_SIZE(buffer), 1, NULL, 0);
532
533 int rc = zcbor_map_decode_bulk(zsd, dm, ARRAY_SIZE(dm), &decoded);
534
535 zassert_ok(rc, "Expected 0, got %d", rc);
536
537 for (int i = 0; i < ARRAY_SIZE(dm); ++i) {
538 zassert_true(dm[i].found, "Expected found for index %d", i);
539 }
540
541 zcbor_map_decode_bulk_reset(dm, ARRAY_SIZE(dm));
542
543 for (int i = 0; i < ARRAY_SIZE(dm); ++i) {
544 zassert_false(dm[i].found, "Expected state reset for index %d", i);
545 }
546 }
547
548 ZTEST_SUITE(zcbor_bulk, NULL, NULL, NULL, NULL, NULL);
549