1 /*
2 * Copyright (c) 2017 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <string.h>
7 #include <zephyr/types.h>
8 #include <stdbool.h>
9 #include <zephyr/ztest.h>
10 #include <zephyr/data/json.h>
11
12 struct test_nested {
13 int nested_int;
14 bool nested_bool;
15 const char *nested_string;
16 };
17
18 struct test_struct {
19 const char *some_string;
20 int some_int;
21 bool some_bool;
22 struct test_nested some_nested_struct;
23 int some_array[16];
24 size_t some_array_len;
25 bool another_bxxl; /* JSON field: "another_b!@l" */
26 bool if_; /* JSON: "if" */
27 int another_array[10]; /* JSON: "another-array" */
28 size_t another_array_len;
29 struct test_nested xnother_nexx; /* JSON: "4nother_ne$+" */
30 struct test_nested nested_obj_array[2];
31 size_t obj_array_len;
32 };
33
34 struct elt {
35 const char *name;
36 int height;
37 };
38
39 struct obj_array {
40 struct elt elements[10];
41 size_t num_elements;
42 };
43
44 struct test_int_limits {
45 int int_max;
46 int int_cero;
47 int int_min;
48 };
49
50 static const struct json_obj_descr nested_descr[] = {
51 JSON_OBJ_DESCR_PRIM(struct test_nested, nested_int, JSON_TOK_NUMBER),
52 JSON_OBJ_DESCR_PRIM(struct test_nested, nested_bool, JSON_TOK_TRUE),
53 JSON_OBJ_DESCR_PRIM(struct test_nested, nested_string,
54 JSON_TOK_STRING),
55 };
56
57 static const struct json_obj_descr test_descr[] = {
58 JSON_OBJ_DESCR_PRIM(struct test_struct, some_string, JSON_TOK_STRING),
59 JSON_OBJ_DESCR_PRIM(struct test_struct, some_int, JSON_TOK_NUMBER),
60 JSON_OBJ_DESCR_PRIM(struct test_struct, some_bool, JSON_TOK_TRUE),
61 JSON_OBJ_DESCR_OBJECT(struct test_struct, some_nested_struct,
62 nested_descr),
63 JSON_OBJ_DESCR_ARRAY(struct test_struct, some_array,
64 16, some_array_len, JSON_TOK_NUMBER),
65 JSON_OBJ_DESCR_PRIM_NAMED(struct test_struct, "another_b!@l",
66 another_bxxl, JSON_TOK_TRUE),
67 JSON_OBJ_DESCR_PRIM_NAMED(struct test_struct, "if",
68 if_, JSON_TOK_TRUE),
69 JSON_OBJ_DESCR_ARRAY_NAMED(struct test_struct, "another-array",
70 another_array, 10, another_array_len,
71 JSON_TOK_NUMBER),
72 JSON_OBJ_DESCR_OBJECT_NAMED(struct test_struct, "4nother_ne$+",
73 xnother_nexx, nested_descr),
74 JSON_OBJ_DESCR_OBJ_ARRAY(struct test_struct, nested_obj_array, 2,
75 obj_array_len, nested_descr, ARRAY_SIZE(nested_descr)),
76 };
77
78 static const struct json_obj_descr elt_descr[] = {
79 JSON_OBJ_DESCR_PRIM(struct elt, name, JSON_TOK_STRING),
80 JSON_OBJ_DESCR_PRIM(struct elt, height, JSON_TOK_NUMBER),
81 };
82
83 static const struct json_obj_descr obj_array_descr[] = {
84 JSON_OBJ_DESCR_OBJ_ARRAY(struct obj_array, elements, 10, num_elements,
85 elt_descr, ARRAY_SIZE(elt_descr)),
86 };
87
88 static const struct json_obj_descr obj_limits_descr[] = {
89 JSON_OBJ_DESCR_PRIM(struct test_int_limits, int_max, JSON_TOK_NUMBER),
90 JSON_OBJ_DESCR_PRIM(struct test_int_limits, int_cero, JSON_TOK_NUMBER),
91 JSON_OBJ_DESCR_PRIM(struct test_int_limits, int_min, JSON_TOK_NUMBER),
92 };
93
94 struct array {
95 struct elt objects;
96 };
97
98 struct obj_array_array {
99 struct array objects_array[4];
100 size_t objects_array_len;
101 };
102
103 static const struct json_obj_descr array_descr[] = {
104 JSON_OBJ_DESCR_OBJECT(struct array, objects, elt_descr),
105 };
106
107 static const struct json_obj_descr array_array_descr[] = {
108 JSON_OBJ_DESCR_ARRAY_ARRAY(struct obj_array_array, objects_array, 4,
109 objects_array_len, array_descr,
110 ARRAY_SIZE(array_descr)),
111 };
112
113 struct obj_array_2dim {
114 struct obj_array objects_array_array[3];
115 size_t objects_array_array_len;
116 };
117
118 static const struct json_obj_descr array_2dim_descr[] = {
119 JSON_OBJ_DESCR_ARRAY_ARRAY(struct obj_array_2dim, objects_array_array, 3,
120 objects_array_array_len, obj_array_descr,
121 ARRAY_SIZE(obj_array_descr)),
122 };
123
124 struct obj_array_2dim_extra {
125 const char *name;
126 int val;
127 struct obj_array_2dim obj_array_2dim;
128 };
129
130 static const struct json_obj_descr array_2dim_extra_descr[] = {
131 JSON_OBJ_DESCR_PRIM(struct obj_array_2dim_extra, name, JSON_TOK_STRING),
132 JSON_OBJ_DESCR_PRIM(struct obj_array_2dim_extra, val, JSON_TOK_NUMBER),
133 JSON_OBJ_DESCR_ARRAY_ARRAY(struct obj_array_2dim_extra, obj_array_2dim, 3,
134 obj_array_2dim.objects_array_array_len, obj_array_descr,
135 ARRAY_SIZE(obj_array_descr)),
136 };
137
138 static const struct json_obj_descr array_2dim_extra_named_descr[] = {
139 JSON_OBJ_DESCR_PRIM(struct obj_array_2dim_extra, name, JSON_TOK_STRING),
140 JSON_OBJ_DESCR_PRIM(struct obj_array_2dim_extra, val, JSON_TOK_NUMBER),
141 JSON_OBJ_DESCR_ARRAY_ARRAY_NAMED(struct obj_array_2dim_extra, data, obj_array_2dim, 3,
142 obj_array_2dim.objects_array_array_len, obj_array_descr,
143 ARRAY_SIZE(obj_array_descr)),
144 };
145
146 struct test_json_tok_encoded_obj {
147 const char *encoded_obj;
148 int ok;
149 };
150
151 static const struct json_obj_descr test_json_tok_encoded_obj_descr[] = {
152 JSON_OBJ_DESCR_PRIM(struct test_json_tok_encoded_obj, encoded_obj, JSON_TOK_ENCODED_OBJ),
153 JSON_OBJ_DESCR_PRIM(struct test_json_tok_encoded_obj, ok, JSON_TOK_NUMBER),
154 };
155
156 struct test_element {
157 int int1;
158 int int2;
159 int int3;
160 };
161
162 struct test_outer {
163 struct test_element array[5];
164 size_t num_elements;
165 };
166
167 static const struct json_obj_descr element_descr[] = {
168 JSON_OBJ_DESCR_PRIM(struct test_element, int1, JSON_TOK_NUMBER),
169 JSON_OBJ_DESCR_PRIM(struct test_element, int2, JSON_TOK_NUMBER),
170 JSON_OBJ_DESCR_PRIM(struct test_element, int3, JSON_TOK_NUMBER),
171 };
172
173 static const struct json_obj_descr outer_descr[] = {
174 JSON_OBJ_DESCR_OBJ_ARRAY(struct test_outer, array, 5,
175 num_elements, element_descr, ARRAY_SIZE(element_descr))
176 };
177
ZTEST(lib_json_test,test_json_encoding)178 ZTEST(lib_json_test, test_json_encoding)
179 {
180 struct test_struct ts = {
181 .some_string = "zephyr 123\uABCD",
182 .some_int = 42,
183 .some_bool = true,
184 .some_nested_struct = {
185 .nested_int = -1234,
186 .nested_bool = false,
187 .nested_string = "this should be escaped: \t"
188 },
189 .some_array[0] = 1,
190 .some_array[1] = 4,
191 .some_array[2] = 8,
192 .some_array[3] = 16,
193 .some_array[4] = 32,
194 .some_array_len = 5,
195 .another_bxxl = true,
196 .if_ = false,
197 .another_array[0] = 2,
198 .another_array[1] = 3,
199 .another_array[2] = 5,
200 .another_array[3] = 7,
201 .another_array_len = 4,
202 .xnother_nexx = {
203 .nested_int = 1234,
204 .nested_bool = true,
205 .nested_string = "no escape necessary",
206 },
207 .nested_obj_array = {
208 {1, true, "true"},
209 {0, false, "false"}
210 },
211 .obj_array_len = 2
212 };
213 char encoded[] = "{\"some_string\":\"zephyr 123\uABCD\","
214 "\"some_int\":42,\"some_bool\":true,"
215 "\"some_nested_struct\":{\"nested_int\":-1234,"
216 "\"nested_bool\":false,\"nested_string\":"
217 "\"this should be escaped: \\t\"},"
218 "\"some_array\":[1,4,8,16,32],"
219 "\"another_b!@l\":true,"
220 "\"if\":false,"
221 "\"another-array\":[2,3,5,7],"
222 "\"4nother_ne$+\":{\"nested_int\":1234,"
223 "\"nested_bool\":true,"
224 "\"nested_string\":\"no escape necessary\"},"
225 "\"nested_obj_array\":["
226 "{\"nested_int\":1,\"nested_bool\":true,\"nested_string\":\"true\"},"
227 "{\"nested_int\":0,\"nested_bool\":false,\"nested_string\":\"false\"}]"
228 "}";
229 char buffer[sizeof(encoded)];
230 int ret;
231 ssize_t len;
232
233 len = json_calc_encoded_len(test_descr, ARRAY_SIZE(test_descr), &ts);
234 zassert_equal(len, strlen(encoded), "encoded size mismatch");
235
236 ret = json_obj_encode_buf(test_descr, ARRAY_SIZE(test_descr),
237 &ts, buffer, sizeof(buffer));
238 zassert_equal(ret, 0, "Encoding function failed");
239
240 ret = strncmp(buffer, encoded, sizeof(encoded) - 1);
241 zassert_equal(ret, 0, "Encoded contents not consistent");
242 }
243
ZTEST(lib_json_test,test_json_decoding)244 ZTEST(lib_json_test, test_json_decoding)
245 {
246 struct test_struct ts;
247 char encoded[] = "{\"some_string\":\"zephyr 123\\uABCD456\","
248 "\"some_int\":\t42\n,"
249 "\"some_bool\":true \t "
250 "\n"
251 "\r ,"
252 "\"some_nested_struct\":{ "
253 "\"nested_int\":-1234,\n\n"
254 "\"nested_bool\":false,\t"
255 "\"nested_string\":\"this should be escaped: \\t\","
256 "\"extra_nested_array\":[0,-1]},"
257 "\"extra_struct\":{\"nested_bool\":false},"
258 "\"extra_bool\":true,"
259 "\"some_array\":[11,22, 33,\t45,\n299],"
260 "\"another_b!@l\":true,"
261 "\"if\":false,"
262 "\"another-array\":[2,3,5,7],"
263 "\"4nother_ne$+\":{\"nested_int\":1234,"
264 "\"nested_bool\":true,"
265 "\"nested_string\":\"no escape necessary\"},"
266 "\"nested_obj_array\":["
267 "{\"nested_int\":1,\"nested_bool\":true,\"nested_string\":\"true\"},"
268 "{\"nested_int\":0,\"nested_bool\":false,\"nested_string\":\"false\"}]"
269 "}\n";
270 const int expected_array[] = { 11, 22, 33, 45, 299 };
271 const int expected_other_array[] = { 2, 3, 5, 7 };
272 int ret;
273
274 ret = json_obj_parse(encoded, sizeof(encoded) - 1, test_descr,
275 ARRAY_SIZE(test_descr), &ts);
276
277 zassert_equal(ret, (1 << ARRAY_SIZE(test_descr)) - 1,
278 "Not all fields decoded correctly");
279
280 zassert_str_equal(ts.some_string, "zephyr 123\\uABCD456",
281 "String not decoded correctly");
282 zassert_equal(ts.some_int, 42, "Positive integer not decoded correctly");
283 zassert_equal(ts.some_bool, true, "Boolean not decoded correctly");
284 zassert_equal(ts.some_nested_struct.nested_int, -1234,
285 "Nested negative integer not decoded correctly");
286 zassert_equal(ts.some_nested_struct.nested_bool, false,
287 "Nested boolean value not decoded correctly");
288 zassert_str_equal(ts.some_nested_struct.nested_string,
289 "this should be escaped: \\t",
290 "Nested string not decoded correctly");
291 zassert_equal(ts.some_array_len, 5,
292 "Array doesn't have correct number of items");
293 zassert_true(!memcmp(ts.some_array, expected_array,
294 sizeof(expected_array)),
295 "Array not decoded with expected values");
296 zassert_true(ts.another_bxxl,
297 "Named boolean (special chars) not decoded correctly");
298 zassert_false(ts.if_,
299 "Named boolean (reserved word) not decoded correctly");
300 zassert_equal(ts.another_array_len, 4,
301 "Named array does not have correct number of items");
302 zassert_true(!memcmp(ts.another_array, expected_other_array,
303 sizeof(expected_other_array)),
304 "Decoded named array not with expected values");
305 zassert_equal(ts.xnother_nexx.nested_int, 1234,
306 "Named nested integer not decoded correctly");
307 zassert_equal(ts.xnother_nexx.nested_bool, true,
308 "Named nested boolean not decoded correctly");
309 zassert_str_equal(ts.xnother_nexx.nested_string,
310 "no escape necessary",
311 "Named nested string not decoded correctly");
312 zassert_equal(ts.obj_array_len, 2,
313 "Array of objects does not have correct number of items");
314 zassert_equal(ts.nested_obj_array[0].nested_int, 1,
315 "Integer in first object array element not decoded correctly");
316 zassert_equal(ts.nested_obj_array[0].nested_bool, true,
317 "Boolean value in first object array element not decoded correctly");
318 zassert_str_equal(ts.nested_obj_array[0].nested_string, "true",
319 "String in first object array element not decoded correctly");
320 zassert_equal(ts.nested_obj_array[1].nested_int, 0,
321 "Integer in second object array element not decoded correctly");
322 zassert_equal(ts.nested_obj_array[1].nested_bool, false,
323 "Boolean value in second object array element not decoded correctly");
324 zassert_str_equal(ts.nested_obj_array[1].nested_string, "false",
325 "String in second object array element not decoded correctly");
326 }
327
ZTEST(lib_json_test,test_json_limits)328 ZTEST(lib_json_test, test_json_limits)
329 {
330 int ret = 0;
331 char encoded[] = "{\"int_max\":2147483647,"
332 "\"int_cero\":0,"
333 "\"int_min\":-2147483648"
334 "}";
335
336 struct test_int_limits limits = {
337 .int_max = INT_MAX,
338 .int_cero = 0,
339 .int_min = INT_MIN,
340 };
341
342 char buffer[sizeof(encoded)];
343 struct test_int_limits limits_decoded = {0};
344
345 ret = json_obj_encode_buf(obj_limits_descr, ARRAY_SIZE(obj_limits_descr),
346 &limits, buffer, sizeof(buffer));
347 ret = json_obj_parse(encoded, sizeof(encoded) - 1, obj_limits_descr,
348 ARRAY_SIZE(obj_limits_descr), &limits_decoded);
349
350 zassert_str_equal(encoded, buffer,
351 "Integer limits not encoded correctly");
352 zassert_true(!memcmp(&limits, &limits_decoded, sizeof(limits)),
353 "Integer limits not decoded correctly");
354 }
355
ZTEST(lib_json_test,test_json_encoding_array_array)356 ZTEST(lib_json_test, test_json_encoding_array_array)
357 {
358 struct obj_array_array obj_array_array_ts = {
359 .objects_array = {
360 [0] = { { .name = "Sim\303\263n Bol\303\255var", .height = 168 } },
361 [1] = { { .name = "Pel\303\251", .height = 173 } },
362 [2] = { { .name = "Usain Bolt", .height = 195 } },
363 },
364 .objects_array_len = 3,
365 };
366 char encoded[] = "{\"objects_array\":["
367 "{\"name\":\"Sim\303\263n Bol\303\255var\",\"height\":168},"
368 "{\"name\":\"Pel\303\251\",\"height\":173},"
369 "{\"name\":\"Usain Bolt\",\"height\":195}"
370 "]}";
371 char buffer[sizeof(encoded)];
372 int ret;
373
374 ret = json_obj_encode_buf(array_array_descr, ARRAY_SIZE(array_array_descr),
375 &obj_array_array_ts, buffer, sizeof(buffer));
376 zassert_equal(ret, 0, "Encoding array returned error");
377 zassert_str_equal(buffer, encoded,
378 "Encoded array of objects is not consistent");
379 }
380
ZTEST(lib_json_test,test_json_decoding_array_array)381 ZTEST(lib_json_test, test_json_decoding_array_array)
382 {
383 int ret;
384 struct obj_array_array obj_array_array_ts;
385 char encoded[] = "{\"objects_array\":["
386 "{\"height\":168,\"name\":\"Sim\303\263n Bol\303\255var\"},"
387 "{\"height\":173,\"name\":\"Pel\303\251\"},"
388 "{\"height\":195,\"name\":\"Usain Bolt\"}]"
389 "}";
390
391 ret = json_obj_parse(encoded, sizeof(encoded),
392 array_array_descr,
393 ARRAY_SIZE(array_array_descr),
394 &obj_array_array_ts);
395
396 zassert_equal(ret, 1, "Encoding array of objects returned error");
397 zassert_equal(obj_array_array_ts.objects_array_len, 3,
398 "Array doesn't have correct number of items");
399
400 zassert_str_equal(obj_array_array_ts.objects_array[0].objects.name,
401 "Sim\303\263n Bol\303\255var",
402 "String not decoded correctly");
403 zassert_equal(obj_array_array_ts.objects_array[0].objects.height, 168,
404 "Sim\303\263n Bol\303\255var height not decoded correctly");
405
406 zassert_str_equal(obj_array_array_ts.objects_array[1].objects.name,
407 "Pel\303\251", "String not decoded correctly");
408 zassert_equal(obj_array_array_ts.objects_array[1].objects.height, 173,
409 "Pel\303\251 height not decoded correctly");
410
411 zassert_str_equal(obj_array_array_ts.objects_array[2].objects.name,
412 "Usain Bolt", "String not decoded correctly");
413 zassert_equal(obj_array_array_ts.objects_array[2].objects.height, 195,
414 "Usain Bolt height not decoded correctly");
415 }
416
ZTEST(lib_json_test,test_json_obj_arr_encoding)417 ZTEST(lib_json_test, test_json_obj_arr_encoding)
418 {
419 struct obj_array oa = {
420 .elements = {
421 [0] = { .name = "Sim\303\263n Bol\303\255var", .height = 168 },
422 [1] = { .name = "Muggsy Bogues", .height = 160 },
423 [2] = { .name = "Pel\303\251", .height = 173 },
424 [3] = { .name = "Hakeem Olajuwon", .height = 213 },
425 [4] = { .name = "Alex Honnold", .height = 180 },
426 [5] = { .name = "Hazel Findlay", .height = 157 },
427 [6] = { .name = "Daila Ojeda", .height = 158 },
428 [7] = { .name = "Albert Einstein", .height = 172 },
429 [8] = { .name = "Usain Bolt", .height = 195 },
430 [9] = { .name = "Paavo Nurmi", .height = 174 },
431 },
432 .num_elements = 10,
433 };
434 char encoded[] = "{\"elements\":["
435 "{\"name\":\"Sim\303\263n Bol\303\255var\",\"height\":168},"
436 "{\"name\":\"Muggsy Bogues\",\"height\":160},"
437 "{\"name\":\"Pel\303\251\",\"height\":173},"
438 "{\"name\":\"Hakeem Olajuwon\",\"height\":213},"
439 "{\"name\":\"Alex Honnold\",\"height\":180},"
440 "{\"name\":\"Hazel Findlay\",\"height\":157},"
441 "{\"name\":\"Daila Ojeda\",\"height\":158},"
442 "{\"name\":\"Albert Einstein\",\"height\":172},"
443 "{\"name\":\"Usain Bolt\",\"height\":195},"
444 "{\"name\":\"Paavo Nurmi\",\"height\":174}"
445 "]}";
446 char buffer[sizeof(encoded)];
447 int ret;
448
449 ret = json_obj_encode_buf(obj_array_descr, ARRAY_SIZE(obj_array_descr),
450 &oa, buffer, sizeof(buffer));
451 zassert_equal(ret, 0, "Encoding array of object returned error");
452 zassert_str_equal(buffer, encoded,
453 "Encoded array of objects is not consistent");
454 }
455
ZTEST(lib_json_test,test_json_arr_obj_decoding)456 ZTEST(lib_json_test, test_json_arr_obj_decoding)
457 {
458 int ret;
459 struct obj_array obj_array_array_ts;
460 char encoded[] = "[{\"height\":168,\"name\":\"Sim\303\263n Bol\303\255var\"},"
461 "{\"height\":173,\"name\":\"Pel\303\251\"},"
462 "{\"height\":195,\"name\":\"Usain Bolt\"}"
463 "]";
464
465 ret = json_arr_parse(encoded, sizeof(encoded),
466 obj_array_descr,
467 &obj_array_array_ts);
468
469 zassert_equal(ret, 0, "Encoding array of objects returned error %d", ret);
470 zassert_equal(obj_array_array_ts.num_elements, 3,
471 "Array doesn't have correct number of items");
472
473 zassert_str_equal(obj_array_array_ts.elements[0].name,
474 "Sim\303\263n Bol\303\255var",
475 "String not decoded correctly");
476 zassert_equal(obj_array_array_ts.elements[0].height, 168,
477 "Sim\303\263n Bol\303\255var height not decoded correctly");
478
479 zassert_str_equal(obj_array_array_ts.elements[1].name, "Pel\303\251",
480 "String not decoded correctly");
481 zassert_equal(obj_array_array_ts.elements[1].height, 173,
482 "Pel\303\251 height not decoded correctly");
483
484 zassert_str_equal(obj_array_array_ts.elements[2].name, "Usain Bolt",
485 "String not decoded correctly");
486 zassert_equal(obj_array_array_ts.elements[2].height, 195,
487 "Usain Bolt height not decoded correctly");
488 }
489
ZTEST(lib_json_test,test_json_arr_obj_encoding)490 ZTEST(lib_json_test, test_json_arr_obj_encoding)
491 {
492 struct obj_array oa = {
493 .elements = {
494 [0] = { .name = "Sim\303\263n Bol\303\255var", .height = 168 },
495 [1] = { .name = "Muggsy Bogues", .height = 160 },
496 [2] = { .name = "Pel\303\251", .height = 173 },
497 [3] = { .name = "Hakeem Olajuwon", .height = 213 },
498 [4] = { .name = "Alex Honnold", .height = 180 },
499 [5] = { .name = "Hazel Findlay", .height = 157 },
500 [6] = { .name = "Daila Ojeda", .height = 158 },
501 [7] = { .name = "Albert Einstein", .height = 172 },
502 [8] = { .name = "Usain Bolt", .height = 195 },
503 [9] = { .name = "Paavo Nurmi", .height = 174 },
504 },
505 .num_elements = 10,
506 };
507 char encoded[] = "["
508 "{\"name\":\"Sim\303\263n Bol\303\255var\",\"height\":168},"
509 "{\"name\":\"Muggsy Bogues\",\"height\":160},"
510 "{\"name\":\"Pel\303\251\",\"height\":173},"
511 "{\"name\":\"Hakeem Olajuwon\",\"height\":213},"
512 "{\"name\":\"Alex Honnold\",\"height\":180},"
513 "{\"name\":\"Hazel Findlay\",\"height\":157},"
514 "{\"name\":\"Daila Ojeda\",\"height\":158},"
515 "{\"name\":\"Albert Einstein\",\"height\":172},"
516 "{\"name\":\"Usain Bolt\",\"height\":195},"
517 "{\"name\":\"Paavo Nurmi\",\"height\":174}"
518 "]";
519 char buffer[sizeof(encoded)];
520 int ret;
521 ssize_t len;
522
523 len = json_calc_encoded_arr_len(obj_array_descr, &oa);
524 zassert_equal(len, strlen(encoded), "encoded size mismatch");
525
526 ret = json_arr_encode_buf(obj_array_descr, &oa, buffer, sizeof(buffer));
527 zassert_equal(ret, 0, "Encoding array of object returned error %d", ret);
528 zassert_str_equal(buffer, encoded,
529 "Encoded array of objects is not consistent");
530 }
531
ZTEST(lib_json_test,test_json_obj_arr_decoding)532 ZTEST(lib_json_test, test_json_obj_arr_decoding)
533 {
534 struct obj_array oa;
535 char encoded[] = "{\"elements\":["
536 "{\"name\":\"Sim\303\263n Bol\303\255var\",\"height\":168},"
537 "{\"name\":\"Muggsy Bogues\",\"height\":160},"
538 "{\"name\":\"Pel\303\251\",\"height\":173},"
539 "{\"name\":\"Hakeem Olajuwon\",\"height\":213},"
540 "{\"name\":\"Alex Honnold\",\"height\":180},"
541 "{\"name\":\"Hazel Findlay\",\"height\":157},"
542 "{\"name\":\"Daila Ojeda\",\"height\":158},"
543 "{\"name\":\"Albert Einstein\",\"height\":172},"
544 "{\"name\":\"Usain Bolt\",\"height\":195},"
545 "{\"name\":\"Paavo Nurmi\",\"height\":174}"
546 "]}";
547 const struct obj_array expected = {
548 .elements = {
549 [0] = { .name = "Sim\303\263n Bol\303\255var", .height = 168 },
550 [1] = { .name = "Muggsy Bogues", .height = 160 },
551 [2] = { .name = "Pel\303\251", .height = 173 },
552 [3] = { .name = "Hakeem Olajuwon", .height = 213 },
553 [4] = { .name = "Alex Honnold", .height = 180 },
554 [5] = { .name = "Hazel Findlay", .height = 157 },
555 [6] = { .name = "Daila Ojeda", .height = 158 },
556 [7] = { .name = "Albert Einstein", .height = 172 },
557 [8] = { .name = "Usain Bolt", .height = 195 },
558 [9] = { .name = "Paavo Nurmi", .height = 174 },
559 },
560 .num_elements = 10,
561 };
562 int ret;
563
564 ret = json_obj_parse(encoded, sizeof(encoded) - 1, obj_array_descr,
565 ARRAY_SIZE(obj_array_descr), &oa);
566
567 zassert_equal(ret, (1 << ARRAY_SIZE(obj_array_descr)) - 1,
568 "Array of object fields not decoded correctly");
569 zassert_equal(oa.num_elements, 10,
570 "Number of object fields not decoded correctly");
571
572 for (int i = 0; i < expected.num_elements; i++) {
573 zassert_true(!strcmp(oa.elements[i].name,
574 expected.elements[i].name),
575 "Element %d name not decoded correctly", i);
576 zassert_equal(oa.elements[i].height,
577 expected.elements[i].height,
578 "Element %d height not decoded correctly", i);
579 }
580 }
581
ZTEST(lib_json_test,test_json_2dim_arr_obj_encoding)582 ZTEST(lib_json_test, test_json_2dim_arr_obj_encoding)
583 {
584 struct obj_array_2dim obj_array_array_ts = {
585 .objects_array_array = {
586 [0] = {
587 .elements = {
588 [0] = {
589 .name = "Sim\303\263n Bol\303\255var",
590 .height = 168
591 },
592 [1] = {
593 .name = "Pel\303\251",
594 .height = 173
595 },
596 [2] = {
597 .name = "Usain Bolt",
598 .height = 195
599 },
600 },
601 .num_elements = 3
602 },
603 [1] = {
604 .elements = {
605 [0] = {
606 .name = "Muggsy Bogues",
607 .height = 160
608 },
609 [1] = {
610 .name = "Hakeem Olajuwon",
611 .height = 213
612 },
613 },
614 .num_elements = 2
615 },
616 [2] = {
617 .elements = {
618 [0] = {
619 .name = "Alex Honnold",
620 .height = 180
621 },
622 [1] = {
623 .name = "Hazel Findlay",
624 .height = 157
625 },
626 [2] = {
627 .name = "Daila Ojeda",
628 .height = 158
629 },
630 [3] = {
631 .name = "Albert Einstein",
632 .height = 172
633 },
634 },
635 .num_elements = 4
636 },
637 },
638 .objects_array_array_len = 3,
639 };
640 char encoded[] = "{\"objects_array_array\":["
641 "[{\"name\":\"Sim\303\263n Bol\303\255var\",\"height\":168},"
642 "{\"name\":\"Pel\303\251\",\"height\":173},"
643 "{\"name\":\"Usain Bolt\",\"height\":195}],"
644 "[{\"name\":\"Muggsy Bogues\",\"height\":160},"
645 "{\"name\":\"Hakeem Olajuwon\",\"height\":213}],"
646 "[{\"name\":\"Alex Honnold\",\"height\":180},"
647 "{\"name\":\"Hazel Findlay\",\"height\":157},"
648 "{\"name\":\"Daila Ojeda\",\"height\":158},"
649 "{\"name\":\"Albert Einstein\",\"height\":172}]"
650 "]}";
651 char buffer[sizeof(encoded)];
652 int ret;
653
654 ret = json_obj_encode_buf(array_2dim_descr, ARRAY_SIZE(array_2dim_descr),
655 &obj_array_array_ts, buffer, sizeof(buffer));
656 zassert_equal(ret, 0, "Encoding two-dimensional array returned error");
657 zassert_str_equal(buffer, encoded,
658 "Encoded two-dimensional array is not consistent");
659 }
660
ZTEST(lib_json_test,test_json_2dim_arr_extra_obj_encoding)661 ZTEST(lib_json_test, test_json_2dim_arr_extra_obj_encoding)
662 {
663 struct obj_array_2dim_extra obj_array_2dim_extra_ts = {
664 .name = "Paavo Nurmi",
665 .val = 123,
666 .obj_array_2dim.objects_array_array = {
667 [0] = {
668 .elements = {
669 [0] = {
670 .name = "Sim\303\263n Bol\303\255var",
671 .height = 168
672 },
673 [1] = {
674 .name = "Pel\303\251",
675 .height = 173
676 },
677 [2] = {
678 .name = "Usain Bolt",
679 .height = 195
680 },
681 },
682 .num_elements = 3
683 },
684 [1] = {
685 .elements = {
686 [0] = {
687 .name = "Muggsy Bogues",
688 .height = 160
689 },
690 [1] = {
691 .name = "Hakeem Olajuwon",
692 .height = 213
693 },
694 },
695 .num_elements = 2
696 },
697 [2] = {
698 .elements = {
699 [0] = {
700 .name = "Alex Honnold",
701 .height = 180
702 },
703 [1] = {
704 .name = "Hazel Findlay",
705 .height = 157
706 },
707 [2] = {
708 .name = "Daila Ojeda",
709 .height = 158
710 },
711 [3] = {
712 .name = "Albert Einstein",
713 .height = 172
714 },
715 },
716 .num_elements = 4
717 },
718 },
719 .obj_array_2dim.objects_array_array_len = 3,
720 };
721
722 char encoded[] = "{\"name\":\"Paavo Nurmi\",\"val\":123,"
723 "\"obj_array_2dim\":["
724 "[{\"name\":\"Sim\303\263n Bol\303\255var\",\"height\":168},"
725 "{\"name\":\"Pel\303\251\",\"height\":173},"
726 "{\"name\":\"Usain Bolt\",\"height\":195}],"
727 "[{\"name\":\"Muggsy Bogues\",\"height\":160},"
728 "{\"name\":\"Hakeem Olajuwon\",\"height\":213}],"
729 "[{\"name\":\"Alex Honnold\",\"height\":180},"
730 "{\"name\":\"Hazel Findlay\",\"height\":157},"
731 "{\"name\":\"Daila Ojeda\",\"height\":158},"
732 "{\"name\":\"Albert Einstein\",\"height\":172}]"
733 "]}";
734 char buffer[sizeof(encoded)];
735 int ret;
736
737 ret = json_obj_encode_buf(array_2dim_extra_descr, ARRAY_SIZE(array_2dim_extra_descr),
738 &obj_array_2dim_extra_ts, buffer, sizeof(buffer));
739 zassert_equal(ret, 0, "Encoding two-dimensional extra array returned error");
740 zassert_str_equal(buffer, encoded,
741 "Encoded two-dimensional extra array is not consistent");
742 }
743
ZTEST(lib_json_test,test_json_2dim_arr_extra_named_obj_encoding)744 ZTEST(lib_json_test, test_json_2dim_arr_extra_named_obj_encoding)
745 {
746 struct obj_array_2dim_extra obj_array_2dim_extra_ts = {
747 .name = "Paavo Nurmi",
748 .val = 123,
749 .obj_array_2dim.objects_array_array = {
750 [0] = {
751 .elements = {
752 [0] = {
753 .name = "Sim\303\263n Bol\303\255var",
754 .height = 168
755 },
756 [1] = {
757 .name = "Pel\303\251",
758 .height = 173
759 },
760 [2] = {
761 .name = "Usain Bolt",
762 .height = 195
763 },
764 },
765 .num_elements = 3
766 },
767 [1] = {
768 .elements = {
769 [0] = {
770 .name = "Muggsy Bogues",
771 .height = 160
772 },
773 [1] = {
774 .name = "Hakeem Olajuwon",
775 .height = 213
776 },
777 },
778 .num_elements = 2
779 },
780 [2] = {
781 .elements = {
782 [0] = {
783 .name = "Alex Honnold",
784 .height = 180
785 },
786 [1] = {
787 .name = "Hazel Findlay",
788 .height = 157
789 },
790 [2] = {
791 .name = "Daila Ojeda",
792 .height = 158
793 },
794 [3] = {
795 .name = "Albert Einstein",
796 .height = 172
797 },
798 },
799 .num_elements = 4
800 },
801 },
802 .obj_array_2dim.objects_array_array_len = 3,
803 };
804
805 char encoded[] = "{\"name\":\"Paavo Nurmi\",\"val\":123,"
806 "\"data\":["
807 "[{\"name\":\"Sim\303\263n Bol\303\255var\",\"height\":168},"
808 "{\"name\":\"Pel\303\251\",\"height\":173},"
809 "{\"name\":\"Usain Bolt\",\"height\":195}],"
810 "[{\"name\":\"Muggsy Bogues\",\"height\":160},"
811 "{\"name\":\"Hakeem Olajuwon\",\"height\":213}],"
812 "[{\"name\":\"Alex Honnold\",\"height\":180},"
813 "{\"name\":\"Hazel Findlay\",\"height\":157},"
814 "{\"name\":\"Daila Ojeda\",\"height\":158},"
815 "{\"name\":\"Albert Einstein\",\"height\":172}]"
816 "]}";
817 char buffer[sizeof(encoded)];
818 int ret;
819
820 ret = json_obj_encode_buf(array_2dim_extra_named_descr,
821 ARRAY_SIZE(array_2dim_extra_named_descr),
822 &obj_array_2dim_extra_ts, buffer, sizeof(buffer));
823 zassert_equal(ret, 0, "Encoding two-dimensional extra named array returned error");
824 zassert_str_equal(buffer, encoded,
825 "Encoded two-dimensional extra named array is not consistent");
826 }
827
ZTEST(lib_json_test,test_json_2dim_obj_arr_decoding)828 ZTEST(lib_json_test, test_json_2dim_obj_arr_decoding)
829 {
830 struct obj_array_2dim oaa;
831 char encoded[] = "{\"objects_array_array\":["
832 "[{\"name\":\"Sim\303\263n Bol\303\255var\",\"height\":168},"
833 "{\"name\":\"Pel\303\251\",\"height\":173},"
834 "{\"name\":\"Usain Bolt\",\"height\":195}],"
835 "[{\"name\":\"Muggsy Bogues\",\"height\":160},"
836 "{\"name\":\"Hakeem Olajuwon\",\"height\":213}],"
837 "[{\"name\":\"Alex Honnold\",\"height\":180},"
838 "{\"name\":\"Hazel Findlay\",\"height\":157},"
839 "{\"name\":\"Daila Ojeda\",\"height\":158},"
840 "{\"name\":\"Albert Einstein\",\"height\":172}]"
841 "]}";
842 const struct obj_array_2dim expected = {
843 .objects_array_array = {
844 [0] = {
845 .elements = {
846 [0] = {
847 .name = "Sim\303\263n Bol\303\255var",
848 .height = 168
849 },
850 [1] = {
851 .name = "Pel\303\251",
852 .height = 173
853 },
854 [2] = {
855 .name = "Usain Bolt",
856 .height = 195
857 },
858 },
859 .num_elements = 3
860 },
861 [1] = {
862 .elements = {
863 [0] = {
864 .name = "Muggsy Bogues",
865 .height = 160
866 },
867 [1] = {
868 .name = "Hakeem Olajuwon",
869 .height = 213
870 },
871 },
872 .num_elements = 2
873 },
874 [2] = {
875 .elements = {
876 [0] = {
877 .name = "Alex Honnold",
878 .height = 180
879 },
880 [1] = {
881 .name = "Hazel Findlay",
882 .height = 157
883 },
884 [2] = {
885 .name = "Daila Ojeda",
886 .height = 158
887 },
888 [3] = {
889 .name = "Albert Einstein",
890 .height = 172
891 },
892 },
893 .num_elements = 4
894 },
895 },
896 .objects_array_array_len = 3,
897 };
898 int ret;
899
900 ret = json_obj_parse(encoded, sizeof(encoded),
901 array_2dim_descr,
902 ARRAY_SIZE(array_2dim_descr),
903 &oaa);
904
905 zassert_equal(ret, 1, "Array of arrays fields not decoded correctly");
906 zassert_equal(oaa.objects_array_array_len, 3,
907 "Number of subarrays not decoded correctly");
908 zassert_equal(oaa.objects_array_array[0].num_elements, 3,
909 "Number of object fields not decoded correctly");
910 zassert_equal(oaa.objects_array_array[1].num_elements, 2,
911 "Number of object fields not decoded correctly");
912 zassert_equal(oaa.objects_array_array[2].num_elements, 4,
913 "Number of object fields not decoded correctly");
914
915 for (int i = 0; i < expected.objects_array_array_len; i++) {
916 for (int j = 0; j < expected.objects_array_array[i].num_elements; j++) {
917 zassert_true(!strcmp(oaa.objects_array_array[i].elements[j].name,
918 expected.objects_array_array[i].elements[j].name),
919 "Element [%d][%d] name not decoded correctly", i, j);
920 zassert_equal(oaa.objects_array_array[i].elements[j].height,
921 expected.objects_array_array[i].elements[j].height,
922 "Element [%d][%d] height not decoded correctly", i, j);
923 }
924 }
925 }
926
927 struct encoding_test {
928 char *str;
929 int result;
930 };
931
parse_harness(struct encoding_test encoded[],size_t size)932 static void parse_harness(struct encoding_test encoded[], size_t size)
933 {
934 struct test_struct ts;
935 int ret;
936
937 for (int i = 0; i < size; i++) {
938 ret = json_obj_parse(encoded[i].str, strlen(encoded[i].str),
939 test_descr, ARRAY_SIZE(test_descr), &ts);
940 zassert_equal(ret, encoded[i].result,
941 "Decoding '%s' result %d, expected %d",
942 encoded[i].str, ret, encoded[i].result);
943 }
944 }
945
ZTEST(lib_json_test,test_json_invalid_string)946 ZTEST(lib_json_test, test_json_invalid_string)
947 {
948 struct encoding_test encoded[] = {
949 { "{\"some_string\":\"\\u@@@@\"}", -EINVAL },
950 { "{\"some_string\":\"\\uA@@@\"}", -EINVAL },
951 { "{\"some_string\":\"\\uAB@@\"}", -EINVAL },
952 { "{\"some_string\":\"\\uABC@\"}", -EINVAL },
953 { "{\"some_string\":\"\\X\"}", -EINVAL }
954 };
955
956 parse_harness(encoded, ARRAY_SIZE(encoded));
957 }
958
ZTEST(lib_json_test,test_json_invalid_bool)959 ZTEST(lib_json_test, test_json_invalid_bool)
960 {
961 struct encoding_test encoded[] = {
962 { "{\"some_bool\":truffle }", -EINVAL},
963 { "{\"some_bool\":fallacy }", -EINVAL},
964 };
965
966 parse_harness(encoded, ARRAY_SIZE(encoded));
967 }
968
ZTEST(lib_json_test,test_json_invalid_null)969 ZTEST(lib_json_test, test_json_invalid_null)
970 {
971 struct encoding_test encoded[] = {
972 /* Parser will recognize 'null', but refuse to decode it */
973 { "{\"some_string\":null }", -EINVAL},
974 /* Null spelled wrong */
975 { "{\"some_string\":nutella }", -EINVAL},
976 };
977
978 parse_harness(encoded, ARRAY_SIZE(encoded));
979 }
980
ZTEST(lib_json_test,test_json_invalid_number)981 ZTEST(lib_json_test, test_json_invalid_number)
982 {
983 struct encoding_test encoded[] = {
984 { "{\"some_int\":xxx }", -EINVAL},
985 };
986
987 parse_harness(encoded, ARRAY_SIZE(encoded));
988 }
989
ZTEST(lib_json_test,test_json_missing_quote)990 ZTEST(lib_json_test, test_json_missing_quote)
991 {
992 struct test_struct ts;
993 char encoded[] = "{\"some_string";
994 int ret;
995
996 ret = json_obj_parse(encoded, sizeof(encoded) - 1, test_descr,
997 ARRAY_SIZE(test_descr), &ts);
998 zassert_equal(ret, -EINVAL, "Decoding has to fail");
999 }
1000
ZTEST(lib_json_test,test_json_wrong_token)1001 ZTEST(lib_json_test, test_json_wrong_token)
1002 {
1003 struct test_struct ts;
1004 char encoded[] = "{\"some_string\",}";
1005 int ret;
1006
1007 ret = json_obj_parse(encoded, sizeof(encoded) - 1, test_descr,
1008 ARRAY_SIZE(test_descr), &ts);
1009 zassert_equal(ret, -EINVAL, "Decoding has to fail");
1010 }
1011
ZTEST(lib_json_test,test_json_item_wrong_type)1012 ZTEST(lib_json_test, test_json_item_wrong_type)
1013 {
1014 struct test_struct ts;
1015 char encoded[] = "{\"some_string\":false}";
1016 int ret;
1017
1018 ret = json_obj_parse(encoded, sizeof(encoded) - 1, test_descr,
1019 ARRAY_SIZE(test_descr), &ts);
1020 zassert_equal(ret, -EINVAL, "Decoding has to fail");
1021 }
1022
ZTEST(lib_json_test,test_json_key_not_in_descr)1023 ZTEST(lib_json_test, test_json_key_not_in_descr)
1024 {
1025 struct test_struct ts;
1026 char encoded[] = "{\"key_not_in_descr\":123456}";
1027 int ret;
1028
1029 ret = json_obj_parse(encoded, sizeof(encoded) - 1, test_descr,
1030 ARRAY_SIZE(test_descr), &ts);
1031 zassert_equal(ret, 0, "No items should be decoded");
1032 }
1033
ZTEST(lib_json_test,test_json_escape)1034 ZTEST(lib_json_test, test_json_escape)
1035 {
1036 char buf[42];
1037 char string[] = "\"abc"
1038 "\\1`23"
1039 "\bf'oo"
1040 "\fbar"
1041 "\nbaz"
1042 "\rquux"
1043 "\tfred\"";
1044 const char *expected = "\\\"abc"
1045 "\\\\1`23"
1046 "\\bf'oo"
1047 "\\fbar"
1048 "\\nbaz"
1049 "\\rquux"
1050 "\\tfred\\\"";
1051 size_t len;
1052 ssize_t ret;
1053
1054 strncpy(buf, string, sizeof(buf) - 1);
1055 len = strlen(buf);
1056
1057 ret = json_escape(buf, &len, sizeof(buf));
1058 zassert_equal(ret, 0, "Escape did not succeed");
1059 zassert_equal(len, sizeof(buf) - 1,
1060 "Escaped length not computed correctly");
1061 zassert_str_equal(buf, expected, "Escaped value is not correct");
1062 }
1063
1064 /* Edge case: only one character, which must be escaped. */
ZTEST(lib_json_test,test_json_escape_one)1065 ZTEST(lib_json_test, test_json_escape_one)
1066 {
1067 char buf[3] = {'\t', '\0', '\0'};
1068 const char *expected = "\\t";
1069 size_t len = strlen(buf);
1070 ssize_t ret;
1071
1072 ret = json_escape(buf, &len, sizeof(buf));
1073 zassert_equal(ret, 0,
1074 "Escaping one character did not succeed");
1075 zassert_equal(len, sizeof(buf) - 1,
1076 "Escaping one character length is not correct");
1077 zassert_str_equal(buf, expected, "Escaped value is not correct");
1078 }
1079
ZTEST(lib_json_test,test_json_escape_empty)1080 ZTEST(lib_json_test, test_json_escape_empty)
1081 {
1082 char empty[] = "";
1083 size_t len = sizeof(empty) - 1;
1084 ssize_t ret;
1085
1086 ret = json_escape(empty, &len, sizeof(empty));
1087 zassert_equal(ret, 0, "Escaping empty string not successful");
1088 zassert_equal(len, 0, "Length of empty escaped string is not zero");
1089 zassert_equal(empty[0], '\0', "Empty string does not remain empty");
1090 }
1091
ZTEST(lib_json_test,test_json_escape_no_op)1092 ZTEST(lib_json_test, test_json_escape_no_op)
1093 {
1094 char nothing_to_escape[] = "hello,world:!";
1095 const char *expected = "hello,world:!";
1096 size_t len = sizeof(nothing_to_escape) - 1;
1097 ssize_t ret;
1098
1099 ret = json_escape(nothing_to_escape, &len, sizeof(nothing_to_escape));
1100 zassert_equal(ret, 0, "Escape no-op not handled correctly");
1101 zassert_equal(len, sizeof(nothing_to_escape) - 1,
1102 "Changed length of already escaped string");
1103 zassert_str_equal(nothing_to_escape, expected,
1104 "Altered string with nothing to escape");
1105 }
1106
ZTEST(lib_json_test,test_json_escape_bounds_check)1107 ZTEST(lib_json_test, test_json_escape_bounds_check)
1108 {
1109 char not_enough_memory[] = "\tfoo";
1110 size_t len = sizeof(not_enough_memory) - 1;
1111 ssize_t ret;
1112
1113 ret = json_escape(not_enough_memory, &len, sizeof(not_enough_memory));
1114 zassert_equal(ret, -ENOMEM, "Bounds check failed");
1115 }
1116
ZTEST(lib_json_test,test_json_encode_bounds_check)1117 ZTEST(lib_json_test, test_json_encode_bounds_check)
1118 {
1119 struct number {
1120 uint32_t val;
1121 } str = { 0 };
1122 const struct json_obj_descr descr[] = {
1123 JSON_OBJ_DESCR_PRIM(struct number, val, JSON_TOK_NUMBER),
1124 };
1125 /* Encodes to {"val":0}\0 for a total of 10 bytes */
1126 uint8_t buf[10];
1127 ssize_t ret = json_obj_encode_buf(descr, ARRAY_SIZE(descr),
1128 &str, buf, 10);
1129 zassert_equal(ret, 0, "Encoding failed despite large enough buffer");
1130 zassert_equal(strlen(buf), 9, "Encoded string length mismatch");
1131
1132 ret = json_obj_encode_buf(descr, ARRAY_SIZE(descr),
1133 &str, buf, 9);
1134 zassert_equal(ret, -ENOMEM, "Bounds check failed");
1135 }
1136
ZTEST(lib_json_test,test_large_descriptor)1137 ZTEST(lib_json_test, test_large_descriptor)
1138 {
1139 struct large_struct {
1140 int int0;
1141 int int1;
1142 int int2;
1143 int int3;
1144 int int4;
1145 int int5;
1146 int int6;
1147 int int7;
1148 int int8;
1149 int int9;
1150 int int10;
1151 int int11;
1152 int int12;
1153 int int13;
1154 int int14;
1155 int int15;
1156 int int16;
1157 int int17;
1158 int int18;
1159 int int19;
1160 int int20;
1161 int int21;
1162 int int22;
1163 int int23;
1164 int int24;
1165 int int25;
1166 int int26;
1167 int int27;
1168 int int28;
1169 int int29;
1170 int int30;
1171 int int31;
1172 int int32;
1173 int int33;
1174 int int34;
1175 int int35;
1176 int int36;
1177 int int37;
1178 int int38;
1179 int int39;
1180 };
1181
1182 static const struct json_obj_descr large_descr[] = {
1183 JSON_OBJ_DESCR_PRIM(struct large_struct, int0, JSON_TOK_NUMBER),
1184 JSON_OBJ_DESCR_PRIM(struct large_struct, int1, JSON_TOK_NUMBER),
1185 JSON_OBJ_DESCR_PRIM(struct large_struct, int2, JSON_TOK_NUMBER),
1186 JSON_OBJ_DESCR_PRIM(struct large_struct, int3, JSON_TOK_NUMBER),
1187 JSON_OBJ_DESCR_PRIM(struct large_struct, int4, JSON_TOK_NUMBER),
1188 JSON_OBJ_DESCR_PRIM(struct large_struct, int5, JSON_TOK_NUMBER),
1189 JSON_OBJ_DESCR_PRIM(struct large_struct, int6, JSON_TOK_NUMBER),
1190 JSON_OBJ_DESCR_PRIM(struct large_struct, int7, JSON_TOK_NUMBER),
1191 JSON_OBJ_DESCR_PRIM(struct large_struct, int8, JSON_TOK_NUMBER),
1192 JSON_OBJ_DESCR_PRIM(struct large_struct, int9, JSON_TOK_NUMBER),
1193 JSON_OBJ_DESCR_PRIM(struct large_struct, int10, JSON_TOK_NUMBER),
1194 JSON_OBJ_DESCR_PRIM(struct large_struct, int11, JSON_TOK_NUMBER),
1195 JSON_OBJ_DESCR_PRIM(struct large_struct, int12, JSON_TOK_NUMBER),
1196 JSON_OBJ_DESCR_PRIM(struct large_struct, int13, JSON_TOK_NUMBER),
1197 JSON_OBJ_DESCR_PRIM(struct large_struct, int14, JSON_TOK_NUMBER),
1198 JSON_OBJ_DESCR_PRIM(struct large_struct, int15, JSON_TOK_NUMBER),
1199 JSON_OBJ_DESCR_PRIM(struct large_struct, int16, JSON_TOK_NUMBER),
1200 JSON_OBJ_DESCR_PRIM(struct large_struct, int17, JSON_TOK_NUMBER),
1201 JSON_OBJ_DESCR_PRIM(struct large_struct, int18, JSON_TOK_NUMBER),
1202 JSON_OBJ_DESCR_PRIM(struct large_struct, int19, JSON_TOK_NUMBER),
1203 JSON_OBJ_DESCR_PRIM(struct large_struct, int20, JSON_TOK_NUMBER),
1204 JSON_OBJ_DESCR_PRIM(struct large_struct, int21, JSON_TOK_NUMBER),
1205 JSON_OBJ_DESCR_PRIM(struct large_struct, int22, JSON_TOK_NUMBER),
1206 JSON_OBJ_DESCR_PRIM(struct large_struct, int23, JSON_TOK_NUMBER),
1207 JSON_OBJ_DESCR_PRIM(struct large_struct, int24, JSON_TOK_NUMBER),
1208 JSON_OBJ_DESCR_PRIM(struct large_struct, int25, JSON_TOK_NUMBER),
1209 JSON_OBJ_DESCR_PRIM(struct large_struct, int26, JSON_TOK_NUMBER),
1210 JSON_OBJ_DESCR_PRIM(struct large_struct, int27, JSON_TOK_NUMBER),
1211 JSON_OBJ_DESCR_PRIM(struct large_struct, int28, JSON_TOK_NUMBER),
1212 JSON_OBJ_DESCR_PRIM(struct large_struct, int29, JSON_TOK_NUMBER),
1213 JSON_OBJ_DESCR_PRIM(struct large_struct, int30, JSON_TOK_NUMBER),
1214 JSON_OBJ_DESCR_PRIM(struct large_struct, int31, JSON_TOK_NUMBER),
1215 JSON_OBJ_DESCR_PRIM(struct large_struct, int32, JSON_TOK_NUMBER),
1216 JSON_OBJ_DESCR_PRIM(struct large_struct, int33, JSON_TOK_NUMBER),
1217 JSON_OBJ_DESCR_PRIM(struct large_struct, int34, JSON_TOK_NUMBER),
1218 JSON_OBJ_DESCR_PRIM(struct large_struct, int35, JSON_TOK_NUMBER),
1219 JSON_OBJ_DESCR_PRIM(struct large_struct, int36, JSON_TOK_NUMBER),
1220 JSON_OBJ_DESCR_PRIM(struct large_struct, int37, JSON_TOK_NUMBER),
1221 JSON_OBJ_DESCR_PRIM(struct large_struct, int38, JSON_TOK_NUMBER),
1222 JSON_OBJ_DESCR_PRIM(struct large_struct, int39, JSON_TOK_NUMBER),
1223 };
1224 char encoded[] = "{"
1225 "\"int1\": 1,"
1226 "\"int21\": 21,"
1227 "\"int31\": 31,"
1228 "\"int39\": 39"
1229 "}";
1230
1231 struct large_struct ls;
1232
1233 int64_t ret = json_obj_parse(encoded, sizeof(encoded) - 1, large_descr,
1234 ARRAY_SIZE(large_descr), &ls);
1235
1236 zassert_false(ret < 0, "json_obj_parse returned error %d", ret);
1237 zassert_false(ret & ((int64_t)1 << 2), "Field int2 erroneously decoded");
1238 zassert_false(ret & ((int64_t)1 << 35), "Field int35 erroneously decoded");
1239 zassert_true(ret & ((int64_t)1 << 1), "Field int1 not decoded");
1240 zassert_true(ret & ((int64_t)1 << 21), "Field int21 not decoded");
1241 zassert_true(ret & ((int64_t)1 << 31), "Field int31 not decoded");
1242 zassert_true(ret & ((int64_t)1 << 39), "Field int39 not decoded");
1243 }
1244
ZTEST(lib_json_test,test_json_encoded_object_tok_encoding)1245 ZTEST(lib_json_test, test_json_encoded_object_tok_encoding)
1246 {
1247 static const char encoded[] =
1248 "{\"encoded_obj\":{\"test\":{\"nested\":\"yes\"}},\"ok\":1234}";
1249 const struct test_json_tok_encoded_obj obj = {
1250 .encoded_obj = "{\"test\":{\"nested\":\"yes\"}}",
1251 .ok = 1234,
1252 };
1253 char buffer[sizeof(encoded)];
1254 int ret;
1255
1256 ret = json_obj_encode_buf(test_json_tok_encoded_obj_descr,
1257 ARRAY_SIZE(test_json_tok_encoded_obj_descr), &obj, buffer,
1258 sizeof(buffer));
1259
1260 zassert_equal(ret, 0, "Encoding function failed");
1261 zassert_mem_equal(buffer, encoded, sizeof(encoded), "Encoded contents not consistent");
1262 }
1263
ZTEST(lib_json_test,test_json_array_alignment)1264 ZTEST(lib_json_test, test_json_array_alignment)
1265 {
1266 char encoded[] = "{"
1267 "\"array\": [ "
1268 "{ \"int1\": 1, "
1269 "\"int2\": 2, "
1270 "\"int3\": 3 }, "
1271 "{ \"int1\": 4, "
1272 "\"int2\": 5, "
1273 "\"int3\": 6 } "
1274 "] "
1275 "}";
1276
1277 struct test_outer o;
1278 int64_t ret = json_obj_parse(encoded, sizeof(encoded) - 1, outer_descr,
1279 ARRAY_SIZE(outer_descr), &o);
1280
1281 zassert_false(ret < 0, "json_obj_parse returned error %d", ret);
1282 zassert_equal(o.num_elements, 2, "Number of elements not decoded correctly");
1283
1284 zassert_equal(o.array[0].int1, 1, "Element 0 int1 not decoded correctly");
1285 zassert_equal(o.array[0].int2, 2, "Element 0 int2 not decoded correctly");
1286 zassert_equal(o.array[0].int3, 3, "Element 0 int3 not decoded correctly");
1287
1288 zassert_equal(o.array[1].int1, 4, "Element 1 int1 not decoded correctly");
1289 zassert_equal(o.array[1].int2, 5, "Element 1 int2 not decoded correctly");
1290 zassert_equal(o.array[1].int3, 6, "Element 1 int3 not decoded correctly");
1291 }
1292
1293 ZTEST_SUITE(lib_json_test, NULL, NULL, NULL, NULL, NULL);
1294