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