1 /*
2  * Copyright (c) 2017 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include <string.h>
7 #include <float.h>
8 #include <math.h>
9 #include <zephyr/types.h>
10 #include <stdbool.h>
11 #include <zephyr/ztest.h>
12 #include <zephyr/data/json.h>
13 
14 struct test_nested {
15 	int nested_int;
16 	bool nested_bool;
17 	const char *nested_string;
18 	char nested_string_buf[10];
19 	int8_t nested_int8;
20 	uint8_t nested_uint8;
21 	int64_t nested_int64;
22 	uint64_t nested_uint64;
23 };
24 
25 struct test_struct {
26 	const char *some_string;
27 	char some_string_buf[10];
28 	int some_int;
29 	bool some_bool;
30 	int16_t some_int16;
31 	int64_t some_int64;
32 	int64_t another_int64;
33 	int64_t some_uint64;
34 	int64_t another_uint64;
35 	struct test_nested some_nested_struct;
36 	int some_array[16];
37 	size_t some_array_len;
38 	bool another_bxxl;		 /* JSON field: "another_b!@l" */
39 	bool if_;			 /* JSON: "if" */
40 	int another_array[10];		 /* JSON: "another-array" */
41 	size_t another_array_len;
42 	struct test_nested xnother_nexx; /* JSON: "4nother_ne$+" */
43 	struct test_nested nested_obj_array[2];
44 	size_t obj_array_len;
45 };
46 
47 struct elt {
48 	const char *name;
49 	const char name_buf[10];
50 	int height;
51 };
52 
53 struct obj_array {
54 	struct elt elements[10];
55 	size_t num_elements;
56 };
57 
58 struct test_int_limits {
59 	int int_max;
60 	int int_cero;
61 	int int_min;
62 	int64_t int64_max;
63 	int64_t int64_cero;
64 	int64_t int64_min;
65 	uint64_t uint64_max;
66 	uint64_t uint64_cero;
67 	uint64_t uint64_min;
68 	uint32_t uint32_max;
69 	uint32_t uint32_cero;
70 	uint32_t uint32_min;
71 	int16_t int16_max;
72 	int16_t int16_cero;
73 	int16_t int16_min;
74 	uint16_t uint16_max;
75 	uint16_t uint16_cero;
76 	uint16_t uint16_min;
77 	int8_t int8_max;
78 	int8_t int8_cero;
79 	int8_t int8_min;
80 	uint8_t uint8_max;
81 	uint8_t uint8_cero;
82 	uint8_t uint8_min;
83 };
84 
85 struct test_float {
86 	float some_float;
87 	float another_float;
88 	float some_array[16];
89 	size_t some_array_len;
90 };
91 
92 struct test_float_limits {
93 	float float_max;
94 	float float_cero;
95 	float float_min;
96 };
97 
98 struct test_double {
99 	double some_double;
100 	double another_double;
101 	double some_array[16];
102 	size_t some_array_len;
103 };
104 
105 struct test_double_limits {
106 	double double_max;
107 	double double_cero;
108 	double double_min;
109 };
110 
111 struct escape_test_data {
112 	char string_value[128];
113 	char string_buf[64];
114 	int integer_value;
115 };
116 
117 static const struct json_obj_descr escape_test_descr[] = {
118 	JSON_OBJ_DESCR_PRIM(struct escape_test_data, string_value, JSON_TOK_STRING_BUF),
119 	JSON_OBJ_DESCR_PRIM(struct escape_test_data, string_buf, JSON_TOK_STRING_BUF),
120 	JSON_OBJ_DESCR_PRIM(struct escape_test_data, integer_value, JSON_TOK_NUMBER),
121 };
122 
123 static const struct json_obj_descr nested_descr[] = {
124 	JSON_OBJ_DESCR_PRIM(struct test_nested, nested_int, JSON_TOK_NUMBER),
125 	JSON_OBJ_DESCR_PRIM(struct test_nested, nested_bool, JSON_TOK_TRUE),
126 	JSON_OBJ_DESCR_PRIM(struct test_nested, nested_string,
127 			    JSON_TOK_STRING),
128 	JSON_OBJ_DESCR_PRIM(struct test_nested, nested_string_buf,
129 			    JSON_TOK_STRING_BUF),
130 	JSON_OBJ_DESCR_PRIM(struct test_nested, nested_int8, JSON_TOK_INT),
131 	JSON_OBJ_DESCR_PRIM(struct test_nested, nested_uint8, JSON_TOK_UINT),
132 	JSON_OBJ_DESCR_PRIM(struct test_nested, nested_int64,
133 			    JSON_TOK_INT64),
134 	JSON_OBJ_DESCR_PRIM(struct test_nested, nested_uint64,
135 			    JSON_TOK_UINT64),
136 };
137 
138 static const struct json_obj_descr test_descr[] = {
139 	JSON_OBJ_DESCR_PRIM(struct test_struct, some_string, JSON_TOK_STRING),
140 	JSON_OBJ_DESCR_PRIM(struct test_struct, some_string_buf, JSON_TOK_STRING_BUF),
141 	JSON_OBJ_DESCR_PRIM(struct test_struct, some_int, JSON_TOK_NUMBER),
142 	JSON_OBJ_DESCR_PRIM(struct test_struct, some_bool, JSON_TOK_TRUE),
143 	JSON_OBJ_DESCR_PRIM(struct test_struct, some_int16, JSON_TOK_INT),
144 	JSON_OBJ_DESCR_PRIM(struct test_struct, some_int64,
145 			    JSON_TOK_INT64),
146 	JSON_OBJ_DESCR_PRIM(struct test_struct, another_int64,
147 			    JSON_TOK_INT64),
148 	JSON_OBJ_DESCR_PRIM(struct test_struct, some_uint64,
149 			    JSON_TOK_UINT64),
150 	JSON_OBJ_DESCR_PRIM(struct test_struct, another_uint64,
151 			    JSON_TOK_UINT64),
152 	JSON_OBJ_DESCR_OBJECT(struct test_struct, some_nested_struct,
153 			      nested_descr),
154 	JSON_OBJ_DESCR_ARRAY(struct test_struct, some_array,
155 			     16, some_array_len, JSON_TOK_NUMBER),
156 	JSON_OBJ_DESCR_PRIM_NAMED(struct test_struct, "another_b!@l",
157 				  another_bxxl, JSON_TOK_TRUE),
158 	JSON_OBJ_DESCR_PRIM_NAMED(struct test_struct, "if",
159 				  if_, JSON_TOK_TRUE),
160 	JSON_OBJ_DESCR_ARRAY_NAMED(struct test_struct, "another-array",
161 				   another_array, 10, another_array_len,
162 				   JSON_TOK_NUMBER),
163 	JSON_OBJ_DESCR_OBJECT_NAMED(struct test_struct, "4nother_ne$+",
164 				    xnother_nexx, nested_descr),
165 	JSON_OBJ_DESCR_OBJ_ARRAY(struct test_struct, nested_obj_array, 2,
166 				 obj_array_len, nested_descr, ARRAY_SIZE(nested_descr)),
167 };
168 
169 static const struct json_obj_descr elt_descr[] = {
170 	JSON_OBJ_DESCR_PRIM(struct elt, name, JSON_TOK_STRING),
171 	JSON_OBJ_DESCR_PRIM(struct elt, name_buf, JSON_TOK_STRING_BUF),
172 	JSON_OBJ_DESCR_PRIM(struct elt, height, JSON_TOK_NUMBER),
173 };
174 
175 static const struct json_obj_descr obj_array_descr[] = {
176 	JSON_OBJ_DESCR_OBJ_ARRAY(struct obj_array, elements, 10, num_elements,
177 				 elt_descr, ARRAY_SIZE(elt_descr)),
178 };
179 
180 static const struct json_obj_descr obj_limits_descr[] = {
181 	JSON_OBJ_DESCR_PRIM(struct test_int_limits, int_max, JSON_TOK_NUMBER),
182 	JSON_OBJ_DESCR_PRIM(struct test_int_limits, int_cero, JSON_TOK_NUMBER),
183 	JSON_OBJ_DESCR_PRIM(struct test_int_limits, int_min, JSON_TOK_NUMBER),
184 	JSON_OBJ_DESCR_PRIM(struct test_int_limits, int64_max, JSON_TOK_INT64),
185 	JSON_OBJ_DESCR_PRIM(struct test_int_limits, int64_cero, JSON_TOK_INT64),
186 	JSON_OBJ_DESCR_PRIM(struct test_int_limits, int64_min, JSON_TOK_INT64),
187 	JSON_OBJ_DESCR_PRIM(struct test_int_limits, uint64_max, JSON_TOK_UINT64),
188 	JSON_OBJ_DESCR_PRIM(struct test_int_limits, uint64_cero, JSON_TOK_UINT64),
189 	JSON_OBJ_DESCR_PRIM(struct test_int_limits, uint64_min, JSON_TOK_UINT64),
190 	JSON_OBJ_DESCR_PRIM(struct test_int_limits, uint32_max, JSON_TOK_UINT),
191 	JSON_OBJ_DESCR_PRIM(struct test_int_limits, uint32_cero, JSON_TOK_UINT),
192 	JSON_OBJ_DESCR_PRIM(struct test_int_limits, uint32_min, JSON_TOK_UINT),
193 	JSON_OBJ_DESCR_PRIM(struct test_int_limits, int16_max, JSON_TOK_INT),
194 	JSON_OBJ_DESCR_PRIM(struct test_int_limits, int16_cero, JSON_TOK_INT),
195 	JSON_OBJ_DESCR_PRIM(struct test_int_limits, int16_min, JSON_TOK_INT),
196 	JSON_OBJ_DESCR_PRIM(struct test_int_limits, uint16_max, JSON_TOK_UINT),
197 	JSON_OBJ_DESCR_PRIM(struct test_int_limits, uint16_cero, JSON_TOK_UINT),
198 	JSON_OBJ_DESCR_PRIM(struct test_int_limits, uint16_min, JSON_TOK_UINT),
199 	JSON_OBJ_DESCR_PRIM(struct test_int_limits, int8_max, JSON_TOK_INT),
200 	JSON_OBJ_DESCR_PRIM(struct test_int_limits, int8_cero, JSON_TOK_INT),
201 	JSON_OBJ_DESCR_PRIM(struct test_int_limits, int8_min, JSON_TOK_INT),
202 	JSON_OBJ_DESCR_PRIM(struct test_int_limits, uint8_max, JSON_TOK_UINT),
203 	JSON_OBJ_DESCR_PRIM(struct test_int_limits, uint8_cero, JSON_TOK_UINT),
204 	JSON_OBJ_DESCR_PRIM(struct test_int_limits, uint8_min, JSON_TOK_UINT),
205 };
206 
207 static const struct json_obj_descr obj_float_descr[] = {
208 	JSON_OBJ_DESCR_PRIM(struct test_float, some_float, JSON_TOK_FLOAT_FP),
209 	JSON_OBJ_DESCR_PRIM(struct test_float, another_float, JSON_TOK_FLOAT_FP),
210 	JSON_OBJ_DESCR_ARRAY(struct test_float, some_array,
211 			     16, some_array_len, JSON_TOK_FLOAT_FP),
212 };
213 
214 static const struct json_obj_descr obj_float_limits_descr[] = {
215 	JSON_OBJ_DESCR_PRIM(struct test_float_limits, float_max, JSON_TOK_FLOAT_FP),
216 	JSON_OBJ_DESCR_PRIM(struct test_float_limits, float_cero, JSON_TOK_FLOAT_FP),
217 	JSON_OBJ_DESCR_PRIM(struct test_float_limits, float_min, JSON_TOK_FLOAT_FP),
218 };
219 
220 static const struct json_obj_descr obj_double_descr[] = {
221 	JSON_OBJ_DESCR_PRIM(struct test_double, some_double, JSON_TOK_DOUBLE_FP),
222 	JSON_OBJ_DESCR_PRIM(struct test_double, another_double, JSON_TOK_DOUBLE_FP),
223 	JSON_OBJ_DESCR_ARRAY(struct test_double, some_array,
224 			     16, some_array_len, JSON_TOK_DOUBLE_FP),
225 };
226 
227 static const struct json_obj_descr obj_double_limits_descr[] = {
228 	JSON_OBJ_DESCR_PRIM(struct test_double_limits, double_max, JSON_TOK_DOUBLE_FP),
229 	JSON_OBJ_DESCR_PRIM(struct test_double_limits, double_cero, JSON_TOK_DOUBLE_FP),
230 	JSON_OBJ_DESCR_PRIM(struct test_double_limits, double_min, JSON_TOK_DOUBLE_FP),
231 };
232 
233 struct array {
234 	struct elt objects;
235 };
236 
237 struct obj_array_array {
238 	struct array objects_array[4];
239 	size_t objects_array_len;
240 };
241 
242 static const struct json_obj_descr array_descr[] = {
243 	JSON_OBJ_DESCR_OBJECT(struct array, objects, elt_descr),
244 };
245 
246 static const struct json_obj_descr array_array_descr[] = {
247 	JSON_OBJ_DESCR_ARRAY_ARRAY(struct obj_array_array, objects_array, 4,
248 				   objects_array_len, array_descr,
249 				   ARRAY_SIZE(array_descr)),
250 };
251 
252 struct obj_array_2dim {
253 	struct obj_array objects_array_array[3];
254 	size_t objects_array_array_len;
255 };
256 
257 static const struct json_obj_descr array_2dim_descr[] = {
258 	JSON_OBJ_DESCR_ARRAY_ARRAY(struct obj_array_2dim, objects_array_array, 3,
259 				   objects_array_array_len, obj_array_descr,
260 				   ARRAY_SIZE(obj_array_descr)),
261 };
262 
263 struct obj_array_2dim_extra {
264 	const char *name;
265 	int val;
266 	struct obj_array_2dim obj_array_2dim;
267 };
268 
269 static const struct json_obj_descr array_2dim_extra_descr[] = {
270 	JSON_OBJ_DESCR_PRIM(struct obj_array_2dim_extra, name, JSON_TOK_STRING),
271 	JSON_OBJ_DESCR_PRIM(struct obj_array_2dim_extra, val, JSON_TOK_NUMBER),
272 	JSON_OBJ_DESCR_ARRAY_ARRAY(struct obj_array_2dim_extra, obj_array_2dim, 3,
273 				   obj_array_2dim.objects_array_array_len, obj_array_descr,
274 				   ARRAY_SIZE(obj_array_descr)),
275 };
276 
277 static const struct json_obj_descr array_2dim_extra_named_descr[] = {
278 	JSON_OBJ_DESCR_PRIM(struct obj_array_2dim_extra, name, JSON_TOK_STRING),
279 	JSON_OBJ_DESCR_PRIM(struct obj_array_2dim_extra, val, JSON_TOK_NUMBER),
280 	JSON_OBJ_DESCR_ARRAY_ARRAY_NAMED(struct obj_array_2dim_extra, data, obj_array_2dim, 3,
281 				   obj_array_2dim.objects_array_array_len, obj_array_descr,
282 				   ARRAY_SIZE(obj_array_descr)),
283 };
284 
285 struct test_json_tok_encoded_obj {
286 	const char *encoded_obj;
287 	const char *encoded_obj_array[3];
288 	size_t encoded_obj_array_len;
289 	int ok;
290 };
291 
292 static const struct json_obj_descr test_json_tok_encoded_obj_descr[] = {
293 	JSON_OBJ_DESCR_PRIM(struct test_json_tok_encoded_obj, encoded_obj, JSON_TOK_ENCODED_OBJ),
294 	JSON_OBJ_DESCR_ARRAY(struct test_json_tok_encoded_obj, encoded_obj_array,
295 			     3, encoded_obj_array_len, JSON_TOK_ENCODED_OBJ),
296 	JSON_OBJ_DESCR_PRIM(struct test_json_tok_encoded_obj, ok, JSON_TOK_NUMBER),
297 };
298 
299 struct test_element {
300 	int int1;
301 	int int2;
302 	int int3;
303 };
304 
305 struct test_outer {
306 	struct test_element array[5];
307 	size_t num_elements;
308 };
309 
310 static const struct json_obj_descr element_descr[] = {
311 	JSON_OBJ_DESCR_PRIM(struct test_element, int1, JSON_TOK_NUMBER),
312 	JSON_OBJ_DESCR_PRIM(struct test_element, int2, JSON_TOK_NUMBER),
313 	JSON_OBJ_DESCR_PRIM(struct test_element, int3, JSON_TOK_NUMBER),
314 };
315 
316 static const struct json_obj_descr outer_descr[] = {
317 	JSON_OBJ_DESCR_OBJ_ARRAY(struct test_outer, array, 5,
318 				num_elements, element_descr, ARRAY_SIZE(element_descr))
319 };
320 
321 struct test_alignment_nested {
322 	bool bool1;
323 	int int1;
324 	bool bool2;
325 };
326 
327 struct test_alignment_bool {
328 	struct test_alignment_nested array[3];
329 	size_t num_elements;
330 };
331 
332 static const struct json_obj_descr alignment_nested_descr[] = {
333 	JSON_OBJ_DESCR_PRIM(struct test_alignment_nested, bool1, JSON_TOK_TRUE),
334 	JSON_OBJ_DESCR_PRIM(struct test_alignment_nested, int1, JSON_TOK_NUMBER),
335 	JSON_OBJ_DESCR_PRIM(struct test_alignment_nested, bool2, JSON_TOK_TRUE),
336 };
337 
338 static const struct json_obj_descr alignment_bool_descr[] = {
339 	JSON_OBJ_DESCR_OBJ_ARRAY(struct test_alignment_bool, array, 3, num_elements,
340 				 alignment_nested_descr, ARRAY_SIZE(alignment_nested_descr)) };
341 
342 enum int8_enum { I8_MIN = INT8_MIN, I8_MAX = INT8_MAX };
343 enum uint8_enum { U8_MIN = 0, U8_MAX = UINT8_MAX };
344 enum int16_enum { I16_MIN = INT16_MIN, I16_MAX = INT16_MAX };
345 enum uint16_enum { U16_MIN = 0, U16_MAX = UINT16_MAX };
346 enum int32_enum { I32_MIN = INT32_MIN, I32_MAX = INT32_MAX };
347 enum uint32_enum { U32_MIN = 0, U32_MAX = UINT32_MAX };
348 
349 struct test_enums {
350 	enum int8_enum i8;
351 	enum uint8_enum u8;
352 	enum int16_enum i16;
353 	enum uint16_enum u16;
354 	enum int32_enum i32;
355 	enum uint32_enum u32;
356 };
357 
358 static const struct json_obj_descr enums_descr[] = {
359 	JSON_OBJ_DESCR_PRIM(struct test_enums, i8, JSON_TOK_INT),
360 	JSON_OBJ_DESCR_PRIM(struct test_enums, u8, JSON_TOK_UINT),
361 	JSON_OBJ_DESCR_PRIM(struct test_enums, i16, JSON_TOK_INT),
362 	JSON_OBJ_DESCR_PRIM(struct test_enums, u16, JSON_TOK_UINT),
363 	JSON_OBJ_DESCR_PRIM(struct test_enums, i32, JSON_TOK_INT),
364 	JSON_OBJ_DESCR_PRIM(struct test_enums, u32, JSON_TOK_UINT),
365 };
366 
367 struct test_mixed_arr {
368 	const char *msg_type;
369 	uint64_t dev_id;
370 	struct test_nested nested;
371 	int arr[3];
372 	size_t arr_len;
373 	char status_buf[10];
374 	size_t count;
375 };
376 
377 static const struct json_obj_descr test_mixed_arr_descr_arr[] = {
378 	JSON_OBJ_DESCR_ARRAY(struct test_mixed_arr, arr, 3, arr_len, JSON_TOK_NUMBER),
379 };
380 
381 static const struct json_mixed_arr_descr test_mixed_arr_descr[] = {
382 	JSON_MIXED_ARR_DESCR_PRIM(struct test_mixed_arr, msg_type, JSON_TOK_STRING, count),
383 	JSON_MIXED_ARR_DESCR_PRIM(struct test_mixed_arr, dev_id, JSON_TOK_UINT64, count),
384 	JSON_MIXED_ARR_DESCR_OBJECT(struct test_mixed_arr, nested, nested_descr, count),
385 	JSON_MIXED_ARR_DESCR_ARRAY(struct test_mixed_arr, arr, 3, test_mixed_arr_descr_arr, count),
386 	JSON_MIXED_ARR_DESCR_PRIM(struct test_mixed_arr, status_buf, JSON_TOK_STRING_BUF, count),
387 };
388 
389 
ZTEST(lib_json_test,test_json_encoding)390 ZTEST(lib_json_test, test_json_encoding)
391 {
392 	struct test_struct ts = {
393 		.some_string = "zephyr 123\uABCD",
394 		.some_string_buf = "z 123\uABCD",
395 		.some_int = 42,
396 		.some_int16 = 16,
397 		.some_int64 = 1152921504606846977,
398 		.another_int64 = -2305843009213693937,
399 		.some_uint64 = 18446744073709551615U,
400 		.another_uint64 = 0,
401 		.some_bool = true,
402 		.some_nested_struct = {
403 			.nested_int = -1234,
404 			.nested_bool = false,
405 			.nested_string = "this should be escaped: \t",
406 			.nested_string_buf = "esc: \t",
407 			.nested_int8 = -123,
408 			.nested_uint8 = 231,
409 			.nested_int64 = 4503599627370496,
410 			.nested_uint64 = 18446744073709551610U,
411 		},
412 		.some_array[0] = 1,
413 		.some_array[1] = 4,
414 		.some_array[2] = 8,
415 		.some_array[3] = 16,
416 		.some_array[4] = 32,
417 		.some_array_len = 5,
418 		.another_bxxl = true,
419 		.if_ = false,
420 		.another_array[0] = 2,
421 		.another_array[1] = 3,
422 		.another_array[2] = 5,
423 		.another_array[3] = 7,
424 		.another_array_len = 4,
425 		.xnother_nexx = {
426 			.nested_int = 1234,
427 			.nested_bool = true,
428 			.nested_string = "no escape necessary",
429 			.nested_string_buf = "no escape",
430 			.nested_int8 = 123,
431 			.nested_uint8 = 231,
432 			.nested_int64 = 4503599627370496,
433 			.nested_uint64 = 18446744073709551610U,
434 		},
435 		.nested_obj_array = {
436 			{1, true, "true", "true"},
437 			{0, false, "false", "false"}
438 		},
439 		.obj_array_len = 2
440 	};
441 	char encoded[] = "{\"some_string\":\"zephyr 123\uABCD\","
442 		"\"some_string_buf\":\"z 123\uABCD\","
443 		"\"some_int\":42,\"some_bool\":true,\"some_int16\":16,"
444 		"\"some_int64\":1152921504606846977,"
445 		"\"another_int64\":-2305843009213693937,"
446 		"\"some_uint64\":18446744073709551615,"
447 		"\"another_uint64\":0,"
448 		"\"some_nested_struct\":{\"nested_int\":-1234,"
449 		"\"nested_bool\":false,\"nested_string\":"
450 		"\"this should be escaped: \\t\","
451 		"\"nested_string_buf\":\"esc: \\t\","
452 		"\"nested_int8\":-123,"
453 		"\"nested_uint8\":231,"
454 		"\"nested_int64\":4503599627370496,"
455 		"\"nested_uint64\":18446744073709551610},"
456 		"\"some_array\":[1,4,8,16,32],"
457 		"\"another_b!@l\":true,"
458 		"\"if\":false,"
459 		"\"another-array\":[2,3,5,7],"
460 		"\"4nother_ne$+\":{\"nested_int\":1234,"
461 		"\"nested_bool\":true,"
462 		"\"nested_string\":\"no escape necessary\","
463 		"\"nested_string_buf\":\"no escape\","
464 		"\"nested_int8\":123,"
465 		"\"nested_uint8\":231,"
466 		"\"nested_int64\":4503599627370496,"
467 		"\"nested_uint64\":18446744073709551610},"
468 		"\"nested_obj_array\":["
469 		"{\"nested_int\":1,\"nested_bool\":true,\"nested_string\":\"true\",\"nested_string_buf\":\"true\",\"nested_int8\":0,\"nested_uint8\":0,\"nested_int64\":0,\"nested_uint64\":0},"
470 		"{\"nested_int\":0,\"nested_bool\":false,\"nested_string\":\"false\",\"nested_string_buf\":\"false\",\"nested_int8\":0,\"nested_uint8\":0,\"nested_int64\":0,\"nested_uint64\":0}]"
471 		"}";
472 	char buffer[sizeof(encoded)];
473 	int ret;
474 	ssize_t len;
475 
476 	len = json_calc_encoded_len(test_descr, ARRAY_SIZE(test_descr), &ts);
477 	zassert_equal(len, strlen(encoded), "encoded size mismatch");
478 
479 	ret = json_obj_encode_buf(test_descr, ARRAY_SIZE(test_descr),
480 				  &ts, buffer, sizeof(buffer));
481 	zassert_equal(ret, 0, "Encoding function failed");
482 
483 	ret = strncmp(buffer, encoded, sizeof(encoded) - 1);
484 	zassert_equal(ret, 0, "Encoded contents not consistent");
485 }
486 
ZTEST(lib_json_test,test_json_decoding)487 ZTEST(lib_json_test, test_json_decoding)
488 {
489 	struct test_struct ts;
490 	char encoded[] = "{\"some_string\":\"zephyr 123\\uABCD456\","
491 		"\"some_string_buf\":\"z\\uABCD\","
492 		"\"some_int\":\t42\n,"
493 		"\"some_int16\":\t16\n,"
494 		"\"some_bool\":true    \t  "
495 		"\n"
496 		"\r   ,"
497 		"\"some_int64\":-4611686018427387904,"
498 		"\"another_int64\":-2147483648,"
499 		"\"some_uint64\":18446744073709551615,"
500 		"\"another_uint64\":0,"
501 		"\"some_nested_struct\":{    "
502 		"\"nested_int\":-1234,\n\n"
503 		"\"nested_bool\":false,\t"
504 		"\"nested_string\":\"this should be escaped: \\t\","
505 		"\"nested_string_buf\":\"esc: \\t\","
506 		"\"nested_int8\":123,"
507 		"\"nested_int64\":9223372036854775807,"
508 		"\"extra_nested_array\":[0,-1]},"
509 		"\"extra_struct\":{\"nested_bool\":false},"
510 		"\"extra_bool\":true,"
511 		"\"some_array\":[11,22, 33,\t45,\n299],"
512 		"\"another_b!@l\":true,"
513 		"\"if\":false,"
514 		"\"another-array\":[2,3,5,7],"
515 		"\"4nother_ne$+\":{\"nested_int\":1234,"
516 		"\"nested_bool\":true,"
517 		"\"nested_string\":\"no escape necessary\","
518 		"\"nested_string_buf\":\"no escape\","
519 		"\"nested_int8\":-123,"
520 		"\"nested_int64\":-9223372036854775806},"
521 		"\"nested_obj_array\":["
522 		"{\"nested_int\":1,\"nested_bool\":true,\"nested_string\":\"true\",\"nested_string_buf\":\"true\"},"
523 		"{\"nested_int\":0,\"nested_bool\":false,\"nested_string\":\"false\",\"nested_string_buf\":\"false\"}]"
524 		"}\n";
525 	const int expected_array[] = { 11, 22, 33, 45, 299 };
526 	const int expected_other_array[] = { 2, 3, 5, 7 };
527 	int ret;
528 
529 	ret = json_obj_parse(encoded, sizeof(encoded) - 1, test_descr,
530 			     ARRAY_SIZE(test_descr), &ts);
531 
532 	zassert_equal(ret, (1 << ARRAY_SIZE(test_descr)) - 1,
533 		      "Not all fields decoded correctly");
534 
535 	zassert_str_equal(ts.some_string, "zephyr 123\\uABCD456",
536 			  "String not decoded correctly");
537 	zassert_str_equal(ts.some_string_buf, "z\\uABCD",
538 			  "String (array) not decoded correctly");
539 	zassert_equal(ts.some_int, 42, "Positive integer not decoded correctly");
540 	zassert_equal(ts.some_int16, 16, "Positive integer not decoded correctly");
541 	zassert_equal(ts.some_bool, true, "Boolean not decoded correctly");
542 	zassert_equal(ts.some_int64, -4611686018427387904,
543 		      "int64 not decoded correctly");
544 	zassert_equal(ts.another_int64, -2147483648,
545 		      "int64 not decoded correctly");
546 	zassert_equal(ts.some_nested_struct.nested_int, -1234,
547 		      "Nested negative integer not decoded correctly");
548 	zassert_equal(ts.some_nested_struct.nested_int8, 123,
549 		      "Nested int8 not decoded correctly");
550 	zassert_equal(ts.some_nested_struct.nested_int64, 9223372036854775807,
551 		      "Nested int64 not decoded correctly");
552 	zassert_equal(ts.some_nested_struct.nested_bool, false,
553 		      "Nested boolean value not decoded correctly");
554 	zassert_str_equal(ts.some_nested_struct.nested_string,
555 			  "this should be escaped: \\t",
556 			  "Nested string not decoded correctly");
557 	zassert_str_equal(ts.some_nested_struct.nested_string_buf, "esc: \t",
558 			  "Nested string-array not decoded correctly");
559 	zassert_equal(ts.some_array_len, 5,
560 		      "Array doesn't have correct number of items");
561 	zassert_true(!memcmp(ts.some_array, expected_array,
562 		    sizeof(expected_array)),
563 		    "Array not decoded with expected values");
564 	zassert_true(ts.another_bxxl,
565 		     "Named boolean (special chars) not decoded correctly");
566 	zassert_false(ts.if_,
567 		      "Named boolean (reserved word) not decoded correctly");
568 	zassert_equal(ts.another_array_len, 4,
569 		      "Named array does not have correct number of items");
570 	zassert_true(!memcmp(ts.another_array, expected_other_array,
571 			     sizeof(expected_other_array)),
572 		     "Decoded named array not with expected values");
573 	zassert_equal(ts.xnother_nexx.nested_int, 1234,
574 		      "Named nested integer not decoded correctly");
575 	zassert_equal(ts.xnother_nexx.nested_int8, -123,
576 		      "Named nested int8 not decoded correctly");
577 	zassert_equal(ts.xnother_nexx.nested_int64, -9223372036854775806,
578 		      "Named nested int64 not decoded correctly");
579 	zassert_equal(ts.xnother_nexx.nested_bool, true,
580 		      "Named nested boolean not decoded correctly");
581 	zassert_str_equal(ts.xnother_nexx.nested_string,
582 			  "no escape necessary",
583 			  "Named nested string not decoded correctly");
584 	zassert_str_equal(ts.xnother_nexx.nested_string_buf,
585 			  "no escape",
586 			  "Named nested string-array not decoded correctly");
587 	zassert_equal(ts.obj_array_len, 2,
588 		      "Array of objects does not have correct number of items");
589 	zassert_equal(ts.nested_obj_array[0].nested_int, 1,
590 		      "Integer in first object array element not decoded correctly");
591 	zassert_equal(ts.nested_obj_array[0].nested_bool, true,
592 		      "Boolean value in first object array element not decoded correctly");
593 	zassert_str_equal(ts.nested_obj_array[0].nested_string, "true",
594 			  "String in first object array element not decoded correctly");
595 	zassert_str_equal(ts.nested_obj_array[0].nested_string_buf, "true",
596 			  "String buffer in first object array element not decoded correctly");
597 	zassert_equal(ts.nested_obj_array[1].nested_int, 0,
598 		      "Integer in second object array element not decoded correctly");
599 	zassert_equal(ts.nested_obj_array[1].nested_bool, false,
600 		      "Boolean value in second object array element not decoded correctly");
601 	zassert_str_equal(ts.nested_obj_array[1].nested_string, "false",
602 			  "String in second object array element not decoded correctly");
603 	zassert_str_equal(ts.nested_obj_array[1].nested_string_buf, "false",
604 			  "String buffer in second object array element not decoded correctly");
605 }
606 
ZTEST(lib_json_test,test_json_limits)607 ZTEST(lib_json_test, test_json_limits)
608 {
609 	int ret = 0;
610 	char encoded[] = "{\"int_max\":2147483647,"
611 			 "\"int_cero\":0,"
612 			 "\"int_min\":-2147483648,"
613 			 "\"int64_max\":9223372036854775807,"
614 			 "\"int64_cero\":0,"
615 			 "\"int64_min\":-9223372036854775808,"
616 			 "\"uint64_max\":18446744073709551615,"
617 			 "\"uint64_cero\":0,"
618 			 "\"uint64_min\":0,"
619 			 "\"uint32_max\":4294967295,"
620 			 "\"uint32_cero\":0,"
621 			 "\"uint32_min\":0,"
622 			 "\"int16_max\":32767,"
623 			 "\"int16_cero\":0,"
624 			 "\"int16_min\":-32768,"
625 			 "\"uint16_max\":65535,"
626 			 "\"uint16_cero\":0,"
627 			 "\"uint16_min\":0,"
628 			 "\"int8_max\":127,"
629 			 "\"int8_cero\":0,"
630 			 "\"int8_min\":-128,"
631 			 "\"uint8_max\":255,"
632 			 "\"uint8_cero\":0,"
633 			 "\"uint8_min\":0"
634 			 "}";
635 
636 	struct test_int_limits limits = {0};
637 	struct test_int_limits limits_decoded = {0};
638 
639 	limits.int_max = INT_MAX;
640 	limits.int_cero = 0;
641 	limits.int_min = INT_MIN;
642 	limits.int64_max = INT64_MAX;
643 	limits.int64_cero = 0;
644 	limits.int64_min = INT64_MIN;
645 	limits.uint64_max = UINT64_MAX;
646 	limits.uint64_cero = 0;
647 	limits.uint64_min = 0;
648 	limits.uint32_max = UINT32_MAX;
649 	limits.uint32_cero = 0;
650 	limits.uint32_min = 0;
651 	limits.int16_max = INT16_MAX;
652 	limits.int16_cero = 0;
653 	limits.int16_min = INT16_MIN;
654 	limits.uint16_max = UINT16_MAX;
655 	limits.uint16_cero = 0;
656 	limits.uint16_min = 0;
657 	limits.int8_max = INT8_MAX;
658 	limits.int8_cero = 0;
659 	limits.int8_min = INT8_MIN;
660 	limits.uint8_max = UINT8_MAX;
661 	limits.uint8_cero = 0;
662 	limits.uint8_min = 0;
663 
664 	char buffer[sizeof(encoded)];
665 
666 	ret = json_obj_encode_buf(obj_limits_descr, ARRAY_SIZE(obj_limits_descr),
667 				&limits, buffer, sizeof(buffer));
668 	ret = json_obj_parse(encoded, sizeof(encoded) - 1, obj_limits_descr,
669 			     ARRAY_SIZE(obj_limits_descr), &limits_decoded);
670 
671 	zassert_str_equal(encoded, buffer,
672 			  "Integer limits not encoded correctly");
673 	zassert_true(!memcmp(&limits, &limits_decoded, sizeof(limits)),
674 		     "Integer limits not decoded correctly");
675 }
676 
ZTEST(lib_json_test,test_json_float)677 ZTEST(lib_json_test, test_json_float)
678 {
679 	char encoded[] = "{\"some_float\":-0.000244140625,"
680 			 "\"another_float\":12345600,"
681 			 "\"some_array\":[1.5,2.25]"
682 			 "}";
683 
684 	struct test_float floats = {
685 		.some_float = -0.000244140625,
686 		.another_float = 12345600.0,
687 		.some_array[0] = 1.5,
688 		.some_array[1] = 2.25,
689 		.some_array_len = 2,
690 	};
691 
692 	char buffer[sizeof(encoded)];
693 	struct test_float floats_decoded = {0};
694 	int ret;
695 
696 	ret = json_obj_encode_buf(obj_float_descr, ARRAY_SIZE(obj_float_descr),
697 				&floats, buffer, sizeof(buffer));
698 	zassert_equal(ret, 0, "Encoding of float returned error");
699 	ret = json_obj_parse(encoded, sizeof(encoded), obj_float_descr,
700 			     ARRAY_SIZE(obj_float_descr), &floats_decoded);
701 	zassert_str_equal(encoded, buffer,
702 			  "Float not encoded correctly");
703 	zassert_true(!memcmp(&floats, &floats_decoded, sizeof(floats)),
704 		     "Float not decoded correctly");
705 }
706 
ZTEST(lib_json_test,test_json_float_format)707 ZTEST(lib_json_test, test_json_float_format)
708 {
709 	struct sub_test {
710 		float num;
711 		char *str;
712 	};
713 	struct sub_test encoded[] = {
714 		{ .num = 0, .str = "0" },
715 		{ .num = 0, .str = "0.0" },
716 		{ .num = 0, .str = "0e0" },
717 		{ .num = 0, .str = "0e+0" },
718 		{ .num = 0, .str = "0e-0" },
719 
720 		{ .num = 12345, .str = "12345" },
721 		{ .num = 12345, .str = "1.2345e+4" },
722 		{ .num = 12345, .str = "1.2345e+04" },
723 
724 		{ .num = -12345, .str = "-12345" },
725 		{ .num = -12345, .str = "-1.2345e+4" },
726 		{ .num = -12345, .str = "-1.2345e+04" },
727 
728 		{ .num = 0.03125, .str = "0.03125" },
729 		{ .num = 0.03125, .str = "3.125e-2" },
730 		{ .num = 0.03125, .str = "3.125e-02" },
731 
732 		{ .num = -0.03125, .str = "-0.03125" },
733 		{ .num = -0.03125, .str = "-3.125e-2" },
734 		{ .num = -0.03125, .str = "-3.125e-02" },
735 	};
736 
737 	struct test_float ts;
738 	char str_encoded[32];
739 
740 	for (int i = 0; i < ARRAY_SIZE(encoded); i++) {
741 		snprintf(str_encoded, sizeof(str_encoded), "{\"some_float\":%s}", encoded[i].str);
742 		int ret = json_obj_parse(str_encoded, strlen(str_encoded),
743 			       obj_float_descr, ARRAY_SIZE(obj_float_descr), &ts);
744 		zassert_equal(ret, 1, "Decoding failed: %s result: %d", str_encoded, ret);
745 		zassert_equal(ts.some_float, encoded[i].num,
746 			      "Decoding failed '%s' float: %g exepcted: %g",
747 			      str_encoded, (double)ts.some_float, (double)encoded[i].num);
748 	}
749 }
750 
ZTEST(lib_json_test,test_json_float_nan)751 ZTEST(lib_json_test, test_json_float_nan)
752 {
753 	char encoded[] = "{\"some_float\":NaN,"
754 			 "\"another_float\":NaN,"
755 			 "\"some_array\":[NaN,NaN]"
756 			 "}";
757 
758 	struct test_float floats = {
759 		.some_float = NAN,
760 		.another_float = NAN,
761 		.some_array[0] = NAN,
762 		.some_array[1] = NAN,
763 		.some_array_len = 2,
764 	};
765 
766 	char buffer[sizeof(encoded)];
767 	struct test_float floats_decoded = {0};
768 	int ret;
769 
770 	ret = json_obj_encode_buf(obj_float_descr, ARRAY_SIZE(obj_float_descr),
771 				&floats, buffer, sizeof(buffer));
772 	zassert_equal(ret, 0, "Encoding of float nan returned error");
773 	ret = json_obj_parse(encoded, sizeof(encoded), obj_float_descr,
774 			     ARRAY_SIZE(obj_float_descr), &floats_decoded);
775 	zassert_str_equal(encoded, buffer,
776 			  "Float not encoded correctly");
777 	zassert_true(!memcmp(&floats, &floats_decoded, sizeof(floats)),
778 		     "Float not decoded correctly");
779 }
780 
ZTEST(lib_json_test,test_json_float_infinity)781 ZTEST(lib_json_test, test_json_float_infinity)
782 {
783 	char encoded[] = "{\"some_float\":Infinity,"
784 			 "\"another_float\":-Infinity,"
785 			 "\"some_array\":[Infinity,-Infinity]"
786 			 "}";
787 
788 	struct test_float floats = {
789 		.some_float = INFINITY,
790 		.another_float = -INFINITY,
791 		.some_array[0] = INFINITY,
792 		.some_array[1] = -INFINITY,
793 		.some_array_len = 2,
794 	};
795 
796 	char buffer[sizeof(encoded)];
797 	struct test_float floats_decoded = {0};
798 	int ret;
799 
800 	ret = json_obj_encode_buf(obj_float_descr, ARRAY_SIZE(obj_float_descr),
801 				&floats, buffer, sizeof(buffer));
802 	zassert_equal(ret, 0, "Encoding of float inf returned error");
803 	ret = json_obj_parse(encoded, sizeof(encoded), obj_float_descr,
804 			     ARRAY_SIZE(obj_float_descr), &floats_decoded);
805 	zassert_str_equal(encoded, buffer,
806 			  "Float not encoded correctly");
807 	zassert_true(!memcmp(&floats, &floats_decoded, sizeof(floats)),
808 		     "Float not decoded correctly");
809 }
810 
ZTEST(lib_json_test,test_json_float_limits)811 ZTEST(lib_json_test, test_json_float_limits)
812 {
813 	char encoded[] = "{\"float_max\":3.40282347e+38,"
814 			 "\"float_cero\":0,"
815 			 "\"float_min\":-3.40282347e+38"
816 			 "}";
817 
818 	struct test_float_limits limits = {
819 		.float_max = 3.40282347e+38,
820 		.float_cero = 0,
821 		.float_min = -3.40282347e+38,
822 	};
823 
824 	char buffer[sizeof(encoded)];
825 	struct test_float_limits limits_decoded = {0};
826 	int ret;
827 
828 	ret = json_obj_encode_buf(obj_float_limits_descr, ARRAY_SIZE(obj_float_limits_descr),
829 				&limits, buffer, sizeof(buffer));
830 	zassert_equal(ret, 0, "Encoding of float limits returned error");
831 	ret = json_obj_parse(encoded, sizeof(encoded), obj_float_limits_descr,
832 			     ARRAY_SIZE(obj_float_limits_descr), &limits_decoded);
833 	zassert_str_equal(encoded, buffer,
834 			  "Float limits not encoded correctly");
835 	zassert_true(!memcmp(&limits, &limits_decoded, sizeof(limits)),
836 		     "Float limits not decoded correctly");
837 }
838 
ZTEST(lib_json_test,test_json_double)839 ZTEST(lib_json_test, test_json_double)
840 {
841 	char encoded[] = "{\"some_double\":-0.000244140625,"
842 			 "\"another_double\":1234567890000000,"
843 			 "\"some_array\":[1.5,2.25]"
844 			 "}";
845 
846 	struct test_double doubles = {
847 		.some_double = -0.000244140625,
848 		.another_double = 1234567890000000.0,
849 		.some_array[0] = 1.5,
850 		.some_array[1] = 2.25,
851 		.some_array_len = 2,
852 	};
853 
854 	char buffer[sizeof(encoded)];
855 	struct test_double doubles_decoded = {0};
856 	int ret;
857 
858 	ret = json_obj_encode_buf(obj_double_descr, ARRAY_SIZE(obj_double_descr),
859 				&doubles, buffer, sizeof(buffer));
860 	zassert_equal(ret, 0, "Encoding of double returned error");
861 	ret = json_obj_parse(encoded, sizeof(encoded), obj_double_descr,
862 			     ARRAY_SIZE(obj_double_descr), &doubles_decoded);
863 	zassert_str_equal(encoded, buffer,
864 			  "Double not encoded correctly");
865 	zassert_true(!memcmp(&doubles, &doubles_decoded, sizeof(doubles)),
866 		     "Double not decoded correctly");
867 }
868 
ZTEST(lib_json_test,test_json_double_format)869 ZTEST(lib_json_test, test_json_double_format)
870 {
871 	struct sub_test {
872 		double num;
873 		char *str;
874 	};
875 	struct sub_test encoded[] = {
876 		{ .num = 0, .str = "0" },
877 		{ .num = 0, .str = "0.0" },
878 		{ .num = 0, .str = "0e0" },
879 		{ .num = 0, .str = "0e+0" },
880 		{ .num = 0, .str = "0e-0" },
881 
882 		{ .num = 12345, .str = "12345" },
883 		{ .num = 12345, .str = "1.2345e+4" },
884 		{ .num = 12345, .str = "1.2345e+04" },
885 
886 		{ .num = -12345, .str = "-12345" },
887 		{ .num = -12345, .str = "-1.2345e+4" },
888 		{ .num = -12345, .str = "-1.2345e+04" },
889 
890 		{ .num = 0.03125, .str = "0.03125" },
891 		{ .num = 0.03125, .str = "3.125e-2" },
892 		{ .num = 0.03125, .str = "3.125e-02" },
893 
894 		{ .num = -0.03125, .str = "-0.03125" },
895 		{ .num = -0.03125, .str = "-3.125e-2" },
896 		{ .num = -0.03125, .str = "-3.125e-02" },
897 	};
898 
899 	struct test_double ts;
900 	char str_encoded[32];
901 
902 	for (int i = 0; i < ARRAY_SIZE(encoded); i++) {
903 		snprintf(str_encoded, sizeof(str_encoded), "{\"some_double\":%s}", encoded[i].str);
904 		int ret = json_obj_parse(str_encoded, strlen(str_encoded),
905 					 obj_double_descr, ARRAY_SIZE(obj_double_descr), &ts);
906 		zassert_equal(ret, 1, "Decoding failed: %s result: %d", str_encoded, ret);
907 		zassert_equal(ts.some_double, encoded[i].num,
908 			      "Decoding failed '%s' double: %g exepcted: %g",
909 			      str_encoded, ts.some_double, encoded[i].num);
910 	}
911 }
912 
913 
ZTEST(lib_json_test,test_json_double_nan)914 ZTEST(lib_json_test, test_json_double_nan)
915 {
916 	char encoded[] = "{\"some_double\":NaN,"
917 			 "\"another_double\":NaN,"
918 			 "\"some_array\":[NaN,NaN]"
919 			 "}";
920 
921 	struct test_double doubles = {
922 		.some_double = (double)NAN,
923 		.another_double = (double)NAN,
924 		.some_array[0] = (double)NAN,
925 		.some_array[1] = (double)NAN,
926 		.some_array_len = 2,
927 	};
928 
929 	char buffer[sizeof(encoded)];
930 	struct test_double doubles_decoded = {0};
931 	int ret;
932 
933 	ret = json_obj_encode_buf(obj_double_descr, ARRAY_SIZE(obj_double_descr),
934 				&doubles, buffer, sizeof(buffer));
935 	zassert_equal(ret, 0, "Encoding of double nan returned error");
936 	ret = json_obj_parse(encoded, sizeof(encoded), obj_double_descr,
937 			     ARRAY_SIZE(obj_double_descr), &doubles_decoded);
938 	zassert_str_equal(encoded, buffer,
939 			  "Double not encoded correctly");
940 	zassert_true(!memcmp(&doubles, &doubles_decoded, sizeof(doubles)),
941 		     "Double not decoded correctly");
942 }
943 
ZTEST(lib_json_test,test_json_double_infinity)944 ZTEST(lib_json_test, test_json_double_infinity)
945 {
946 	char encoded[] = "{\"some_double\":Infinity,"
947 			 "\"another_double\":-Infinity,"
948 			 "\"some_array\":[Infinity,-Infinity]"
949 			 "}";
950 
951 	struct test_double doubles = {
952 		.some_double = (double)INFINITY,
953 		.another_double = (double)-INFINITY,
954 		.some_array[0] = (double)INFINITY,
955 		.some_array[1] = (double)-INFINITY,
956 		.some_array_len = 2,
957 	};
958 
959 	char buffer[sizeof(encoded)];
960 	struct test_double doubles_decoded = {0};
961 	int ret;
962 
963 	ret = json_obj_encode_buf(obj_double_descr, ARRAY_SIZE(obj_double_descr),
964 				&doubles, buffer, sizeof(buffer));
965 	zassert_equal(ret, 0, "Encoding of double inf returned error");
966 	ret = json_obj_parse(encoded, sizeof(encoded), obj_double_descr,
967 			     ARRAY_SIZE(obj_double_descr), &doubles_decoded);
968 	zassert_str_equal(encoded, buffer,
969 			  "Double not encoded correctly");
970 	zassert_true(!memcmp(&doubles, &doubles_decoded, sizeof(doubles)),
971 		     "Double not decoded correctly");
972 }
973 
ZTEST(lib_json_test,test_json_doubles_limits)974 ZTEST(lib_json_test, test_json_doubles_limits)
975 {
976 	char encoded[] = "{\"double_max\":1.797693134862315e+308,"
977 			 "\"double_cero\":0,"
978 			 "\"double_min\":-1.797693134862315e+308"
979 			 "}";
980 
981 	struct test_double_limits limits = {
982 		.double_max = 1.797693134862315e+308,
983 		.double_cero = 0,
984 		.double_min = -1.797693134862315e+308,
985 	};
986 
987 	char buffer[sizeof(encoded)];
988 	struct test_double_limits limits_decoded = {0};
989 	int ret;
990 
991 	ret = json_obj_encode_buf(obj_double_limits_descr, ARRAY_SIZE(obj_double_limits_descr),
992 				&limits, buffer, sizeof(buffer));
993 	zassert_equal(ret, 0, "Encoding of double limits returned error");
994 	ret = json_obj_parse(encoded, sizeof(encoded), obj_double_limits_descr,
995 			     ARRAY_SIZE(obj_double_limits_descr), &limits_decoded);
996 	zassert_str_equal(encoded, buffer,
997 			  "Double limits not encoded correctly");
998 	zassert_true(!memcmp(&limits, &limits_decoded, sizeof(limits)),
999 		     "Double limits not decoded correctly");
1000 }
1001 
ZTEST(lib_json_test,test_json_encoding_array_array)1002 ZTEST(lib_json_test, test_json_encoding_array_array)
1003 {
1004 	struct obj_array_array obj_array_array_ts = {
1005 		.objects_array = {
1006 			[0] = {{.name = "Sim\303\263n Bol\303\255var",
1007 				.name_buf = "Sim\303\263n",
1008 				.height = 168}},
1009 			[1] = {{.name = "Pel\303\251",
1010 				.name_buf = "Pel\303\251",
1011 				.height = 173}},
1012 			[2] = {{.name = "Usain Bolt",
1013 				.name_buf = "Usain",
1014 				.height = 195}},
1015 		},
1016 		.objects_array_len = 3,
1017 	};
1018 	char encoded[] = "{\"objects_array\":["
1019 			 "{\"name\":\"Sim\303\263n Bol\303\255var\",\"name_buf\":\"Sim\303\263n\",\"height\":168},"
1020 			 "{\"name\":\"Pel\303\251\",\"name_buf\":\"Pel\303\251\",\"height\":173},"
1021 			 "{\"name\":\"Usain Bolt\",\"name_buf\":\"Usain\",\"height\":195}"
1022 			 "]}";
1023 
1024 	char buffer[sizeof(encoded)];
1025 	int ret;
1026 
1027 	ret = json_obj_encode_buf(array_array_descr, ARRAY_SIZE(array_array_descr),
1028 				  &obj_array_array_ts, buffer, sizeof(buffer));
1029 	zassert_equal(ret, 0, "Encoding array returned error");
1030 	zassert_str_equal(buffer, encoded,
1031 			  "Encoded array of objects is not consistent");
1032 }
1033 
ZTEST(lib_json_test,test_json_decoding_array_array)1034 ZTEST(lib_json_test, test_json_decoding_array_array)
1035 {
1036 	int ret;
1037 	struct obj_array_array obj_array_array_ts;
1038 	char encoded[] = "{\"objects_array\":["
1039 			  "{\"height\":168,\"name\":\"Sim\303\263n Bol\303\255var\",\"name_buf\":\"Sim\303\263n\"},"
1040 			  "{\"height\":173,\"name\":\"Pel\303\251\",\"name_buf\":\"Pel\303\251\"},"
1041 			  "{\"height\":195,\"name\":\"Usain Bolt\",\"name_buf\":\"Usain\"}]"
1042 			  "}";
1043 
1044 	ret = json_obj_parse(encoded, sizeof(encoded),
1045 			     array_array_descr,
1046 			     ARRAY_SIZE(array_array_descr),
1047 			     &obj_array_array_ts);
1048 
1049 	zassert_equal(ret, 1, "Encoding array of objects returned error");
1050 	zassert_equal(obj_array_array_ts.objects_array_len, 3,
1051 		      "Array doesn't have correct number of items");
1052 
1053 	zassert_str_equal(obj_array_array_ts.objects_array[0].objects.name,
1054 			  "Sim\303\263n Bol\303\255var",
1055 			  "String not decoded correctly");
1056 	zassert_str_equal(obj_array_array_ts.objects_array[0].objects.name_buf,
1057 			  "Sim\303\263n",
1058 			  "String buffer not decoded correctly");
1059 	zassert_equal(obj_array_array_ts.objects_array[0].objects.height, 168,
1060 		      "Sim\303\263n Bol\303\255var height not decoded correctly");
1061 
1062 	zassert_str_equal(obj_array_array_ts.objects_array[1].objects.name,
1063 			  "Pel\303\251", "String not decoded correctly");
1064 	zassert_str_equal(obj_array_array_ts.objects_array[1].objects.name_buf,
1065 			  "Pel\303\251", "String buffer not decoded correctly");
1066 	zassert_equal(obj_array_array_ts.objects_array[1].objects.height, 173,
1067 		      "Pel\303\251 height not decoded correctly");
1068 
1069 	zassert_str_equal(obj_array_array_ts.objects_array[2].objects.name,
1070 			  "Usain Bolt", "String not decoded correctly");
1071 	zassert_str_equal(obj_array_array_ts.objects_array[2].objects.name_buf,
1072 			  "Usain", "String buffer not decoded correctly");
1073 	zassert_equal(obj_array_array_ts.objects_array[2].objects.height, 195,
1074 		      "Usain Bolt height not decoded correctly");
1075 }
1076 
ZTEST(lib_json_test,test_json_obj_arr_encoding)1077 ZTEST(lib_json_test, test_json_obj_arr_encoding)
1078 {
1079 	struct obj_array oa = {
1080 		.elements = {
1081 			[0] = {
1082 				.name = "Sim\303\263n Bol\303\255var",
1083 				.name_buf = "Sim\303\263n",
1084 				.height = 168 },
1085 			[1] = {
1086 				.name = "Muggsy Bogues",
1087 				.name_buf = "Muggsy",
1088 				.height = 160 },
1089 			[2] = {
1090 				.name = "Pel\303\251",
1091 				.name_buf = "Pel\303\251",
1092 				.height = 173 },
1093 			[3] = {
1094 				.name = "Hakeem Olajuwon",
1095 				.name_buf = "Hakeem",
1096 				.height = 213 },
1097 			[4] = {
1098 				.name = "Alex Honnold",
1099 				.name_buf = "Alex",
1100 				.height = 180 },
1101 			[5] = {
1102 				.name = "Hazel Findlay",
1103 				.name_buf = "Hazel",
1104 				.height = 157 },
1105 			[6] = {
1106 				.name = "Daila Ojeda",
1107 				.name_buf = "Daila",
1108 				.height = 158 },
1109 			[7] = {
1110 				.name = "Albert Einstein",
1111 				.name_buf = "Albert",
1112 				.height = 172 },
1113 			[8] = {
1114 				.name = "Usain Bolt",
1115 				.name_buf = "Usain",
1116 				.height = 195 },
1117 			[9] = {
1118 				.name = "Paavo Nurmi",
1119 				.name_buf = "Paavo",
1120 				.height = 174 },
1121 		},
1122 		.num_elements = 10,
1123 	};
1124 	char encoded[] = "{\"elements\":["
1125 		"{\"name\":\"Sim\303\263n Bol\303\255var\",\"name_buf\":\"Sim\303\263n\",\"height\":168},"
1126 		"{\"name\":\"Muggsy Bogues\",\"name_buf\":\"Muggsy\",\"height\":160},"
1127 		"{\"name\":\"Pel\303\251\",\"name_buf\":\"Pel\303\251\",\"height\":173},"
1128 		"{\"name\":\"Hakeem Olajuwon\",\"name_buf\":\"Hakeem\",\"height\":213},"
1129 		"{\"name\":\"Alex Honnold\",\"name_buf\":\"Alex\",\"height\":180},"
1130 		"{\"name\":\"Hazel Findlay\",\"name_buf\":\"Hazel\",\"height\":157},"
1131 		"{\"name\":\"Daila Ojeda\",\"name_buf\":\"Daila\",\"height\":158},"
1132 		"{\"name\":\"Albert Einstein\",\"name_buf\":\"Albert\",\"height\":172},"
1133 		"{\"name\":\"Usain Bolt\",\"name_buf\":\"Usain\",\"height\":195},"
1134 		"{\"name\":\"Paavo Nurmi\",\"name_buf\":\"Paavo\",\"height\":174}"
1135 		"]}";
1136 	char buffer[sizeof(encoded)];
1137 	int ret;
1138 
1139 	ret = json_obj_encode_buf(obj_array_descr, ARRAY_SIZE(obj_array_descr),
1140 				  &oa, buffer, sizeof(buffer));
1141 	zassert_equal(ret, 0, "Encoding array of object returned error");
1142 	zassert_str_equal(buffer, encoded,
1143 			  "Encoded array of objects is not consistent");
1144 }
1145 
ZTEST(lib_json_test,test_json_arr_obj_decoding)1146 ZTEST(lib_json_test, test_json_arr_obj_decoding)
1147 {
1148 	int ret;
1149 	struct obj_array obj_array_array_ts;
1150 	char encoded[] = "[{\"height\":168,\"name\":\"Sim\303\263n Bol\303\255var\","
1151 			 "\"name_buf\":\"Sim\303\263n\"},"
1152 			 "{\"height\":173,\"name\":\"Pel\303\251\",\"name_buf\":\"Pel\303\251\"},"
1153 			 "{\"height\":195,\"name\":\"Usain Bolt\",\"name_buf\":\"Usain\"}"
1154 			 "]";
1155 
1156 	ret = json_arr_parse(encoded, sizeof(encoded),
1157 			     obj_array_descr,
1158 			     &obj_array_array_ts);
1159 
1160 	zassert_equal(ret, 0, "Encoding array of objects returned error %d", ret);
1161 	zassert_equal(obj_array_array_ts.num_elements, 3,
1162 		      "Array doesn't have correct number of items");
1163 
1164 	zassert_str_equal(obj_array_array_ts.elements[0].name,
1165 			  "Sim\303\263n Bol\303\255var",
1166 			  "String not decoded correctly");
1167 	zassert_str_equal(obj_array_array_ts.elements[0].name_buf,
1168 			  "Sim\303\263n",
1169 			  "String buffer not decoded correctly");
1170 	zassert_equal(obj_array_array_ts.elements[0].height, 168,
1171 		      "Sim\303\263n Bol\303\255var height not decoded correctly");
1172 
1173 	zassert_str_equal(obj_array_array_ts.elements[1].name, "Pel\303\251",
1174 			  "String not decoded correctly");
1175 	zassert_str_equal(obj_array_array_ts.elements[1].name_buf, "Pel\303\251",
1176 			  "String buffer not decoded correctly");
1177 	zassert_equal(obj_array_array_ts.elements[1].height, 173,
1178 		      "Pel\303\251 height not decoded correctly");
1179 
1180 	zassert_str_equal(obj_array_array_ts.elements[2].name, "Usain Bolt",
1181 			  "String not decoded correctly");
1182 	zassert_str_equal(obj_array_array_ts.elements[2].name_buf, "Usain",
1183 			  "String buffer not decoded correctly");
1184 	zassert_equal(obj_array_array_ts.elements[2].height, 195,
1185 		      "Usain Bolt height not decoded correctly");
1186 }
1187 
ZTEST(lib_json_test,test_json_arr_obj_encoding)1188 ZTEST(lib_json_test, test_json_arr_obj_encoding)
1189 {
1190 	struct obj_array oa = {
1191 		.elements = {
1192 			[0] = {
1193 				.name = "Sim\303\263n Bol\303\255var",
1194 				.name_buf = "Sim\303\263n",
1195 				.height = 168 },
1196 			[1] = {
1197 				.name = "Muggsy Bogues",
1198 				.name_buf = "Muggsy",
1199 				.height = 160 },
1200 			[2] = {
1201 				.name = "Pel\303\251",
1202 				.name_buf = "Pel\303\251",
1203 				.height = 173 },
1204 			[3] = {
1205 				.name = "Hakeem Olajuwon",
1206 				.name_buf = "Hakeem",
1207 				.height = 213 },
1208 			[4] = {
1209 				.name = "Alex Honnold",
1210 				.name_buf = "Alex",
1211 				.height = 180 },
1212 			[5] = {
1213 				.name = "Hazel Findlay",
1214 				.name_buf = "Hazel",
1215 				.height = 157 },
1216 			[6] = {
1217 				.name = "Daila Ojeda",
1218 				.name_buf = "Daila",
1219 				.height = 158 },
1220 			[7] = {
1221 				.name = "Albert Einstein",
1222 				.name_buf = "Albert",
1223 				.height = 172 },
1224 			[8] = {
1225 				.name = "Usain Bolt",
1226 				.name_buf = "Usain",
1227 				.height = 195 },
1228 			[9] = {
1229 				.name = "Paavo Nurmi",
1230 				.name_buf = "Paavo",
1231 				.height = 174 },
1232 		},
1233 		.num_elements = 10,
1234 	};
1235 	char encoded[] = "["
1236 		"{\"name\":\"Sim\303\263n Bol\303\255var\",\"name_buf\":\"Sim\303\263n\",\"height\":168},"
1237 		"{\"name\":\"Muggsy Bogues\",\"name_buf\":\"Muggsy\",\"height\":160},"
1238 		"{\"name\":\"Pel\303\251\",\"name_buf\":\"Pel\303\251\",\"height\":173},"
1239 		"{\"name\":\"Hakeem Olajuwon\",\"name_buf\":\"Hakeem\",\"height\":213},"
1240 		"{\"name\":\"Alex Honnold\",\"name_buf\":\"Alex\",\"height\":180},"
1241 		"{\"name\":\"Hazel Findlay\",\"name_buf\":\"Hazel\",\"height\":157},"
1242 		"{\"name\":\"Daila Ojeda\",\"name_buf\":\"Daila\",\"height\":158},"
1243 		"{\"name\":\"Albert Einstein\",\"name_buf\":\"Albert\",\"height\":172},"
1244 		"{\"name\":\"Usain Bolt\",\"name_buf\":\"Usain\",\"height\":195},"
1245 		"{\"name\":\"Paavo Nurmi\",\"name_buf\":\"Paavo\",\"height\":174}"
1246 		"]";
1247 	char buffer[sizeof(encoded)];
1248 	int ret;
1249 	ssize_t len;
1250 
1251 	len = json_calc_encoded_arr_len(obj_array_descr, &oa);
1252 	zassert_equal(len, strlen(encoded), "encoded size mismatch");
1253 
1254 	ret = json_arr_encode_buf(obj_array_descr, &oa, buffer, sizeof(buffer));
1255 	zassert_equal(ret, 0, "Encoding array of object returned error %d", ret);
1256 	zassert_str_equal(buffer, encoded,
1257 			  "Encoded array of objects is not consistent");
1258 }
1259 
ZTEST(lib_json_test,test_json_obj_arr_decoding)1260 ZTEST(lib_json_test, test_json_obj_arr_decoding)
1261 {
1262 	struct obj_array oa;
1263 	char encoded[] = "{\"elements\":["
1264 		"{\"name\":\"Sim\303\263n Bol\303\255var\",\"name_buf\":\"Sim\303\263n\",\"height\":168},"
1265 		"{\"name\":\"Muggsy Bogues\",\"name_buf\":\"Muggsy\",\"height\":160},"
1266 		"{\"name\":\"Pel\303\251\",\"name_buf\":\"Pel\303\251\",\"height\":173},"
1267 		"{\"name\":\"Hakeem Olajuwon\",\"name_buf\":\"Hakeem\",\"height\":213},"
1268 		"{\"name\":\"Alex Honnold\",\"name_buf\":\"Alex\",\"height\":180},"
1269 		"{\"name\":\"Hazel Findlay\",\"name_buf\":\"Hazel\",\"height\":157},"
1270 		"{\"name\":\"Daila Ojeda\",\"name_buf\":\"Daila\",\"height\":158},"
1271 		"{\"name\":\"Albert Einstein\",\"name_buf\":\"Albert\",\"height\":172},"
1272 		"{\"name\":\"Usain Bolt\",\"name_buf\":\"Usain\",\"height\":195},"
1273 		"{\"name\":\"Paavo Nurmi\",\"name_buf\":\"Paavo\",\"height\":174}"
1274 		"]}";
1275 	const struct obj_array expected = {
1276 		.elements = {
1277 			[0] = {
1278 				.name = "Sim\303\263n Bol\303\255var",
1279 				.name_buf = "Sim\303\263n",
1280 				.height = 168 },
1281 			[1] = {
1282 				.name = "Muggsy Bogues",
1283 				.name_buf = "Muggsy",
1284 				.height = 160 },
1285 			[2] = {
1286 				.name = "Pel\303\251",
1287 				.name_buf = "Pel\303\251",
1288 				.height = 173 },
1289 			[3] = {
1290 				.name = "Hakeem Olajuwon",
1291 				.name_buf = "Hakeem",
1292 				.height = 213 },
1293 			[4] = {
1294 				.name = "Alex Honnold",
1295 				.name_buf = "Alex",
1296 				.height = 180 },
1297 			[5] = {
1298 				.name = "Hazel Findlay",
1299 				.name_buf = "Hazel",
1300 				.height = 157 },
1301 			[6] = {
1302 				.name = "Daila Ojeda",
1303 				.name_buf = "Daila",
1304 				.height = 158 },
1305 			[7] = {
1306 				.name = "Albert Einstein",
1307 				.name_buf = "Albert",
1308 				.height = 172 },
1309 			[8] = {
1310 				.name = "Usain Bolt",
1311 				.name_buf = "Usain",
1312 				.height = 195 },
1313 			[9] = {
1314 				.name = "Paavo Nurmi",
1315 				.name_buf = "Paavo",
1316 				.height = 174 },
1317 		},
1318 		.num_elements = 10,
1319 	};
1320 	int ret;
1321 
1322 	ret = json_obj_parse(encoded, sizeof(encoded) - 1, obj_array_descr,
1323 			     ARRAY_SIZE(obj_array_descr), &oa);
1324 
1325 	zassert_equal(ret, (1 << ARRAY_SIZE(obj_array_descr)) - 1,
1326 		      "Array of object fields not decoded correctly");
1327 	zassert_equal(oa.num_elements, 10,
1328 		      "Number of object fields not decoded correctly");
1329 
1330 	for (int i = 0; i < expected.num_elements; i++) {
1331 		zassert_true(!strcmp(oa.elements[i].name,
1332 				     expected.elements[i].name),
1333 			     "Element %d name not decoded correctly", i);
1334 		zassert_equal(oa.elements[i].height,
1335 			      expected.elements[i].height,
1336 			      "Element %d height not decoded correctly", i);
1337 	}
1338 }
1339 
ZTEST(lib_json_test,test_json_2dim_arr_obj_encoding)1340 ZTEST(lib_json_test, test_json_2dim_arr_obj_encoding)
1341 {
1342 	struct obj_array_2dim obj_array_array_ts = {
1343 		.objects_array_array = {
1344 			[0] = {
1345 				.elements = {
1346 					[0] = {
1347 						.name = "Sim\303\263n Bol\303\255var",
1348 						.name_buf = "Sim\303\263n",
1349 						.height = 168
1350 					},
1351 					[1] = {
1352 						.name = "Pel\303\251",
1353 						.name_buf = "Pel\303\251",
1354 						.height = 173
1355 					},
1356 					[2] = {
1357 						.name = "Usain Bolt",
1358 						.name_buf = "Usain",
1359 						.height = 195
1360 					},
1361 				},
1362 				.num_elements = 3
1363 			},
1364 			[1] = {
1365 				.elements = {
1366 					[0] = {
1367 						.name = "Muggsy Bogues",
1368 						.name_buf = "Muggsy",
1369 						.height = 160
1370 					},
1371 					[1] = {
1372 						.name = "Hakeem Olajuwon",
1373 						.name_buf = "Hakeem",
1374 						.height = 213
1375 					},
1376 				},
1377 				.num_elements = 2
1378 			},
1379 			[2] = {
1380 				.elements = {
1381 					[0] = {
1382 						.name = "Alex Honnold",
1383 						.name_buf = "Alex",
1384 						.height = 180
1385 					},
1386 					[1] = {
1387 						.name = "Hazel Findlay",
1388 						.name_buf = "Hazel",
1389 						.height = 157
1390 					},
1391 					[2] = {
1392 						.name = "Daila Ojeda",
1393 						.name_buf = "Daila",
1394 						.height = 158
1395 					},
1396 					[3] = {
1397 						.name = "Albert Einstein",
1398 						.name_buf = "Albert",
1399 						.height = 172
1400 					},
1401 				},
1402 				.num_elements = 4
1403 			},
1404 		},
1405 		.objects_array_array_len = 3,
1406 	};
1407 	char encoded[] = "{\"objects_array_array\":["
1408 		"[{\"name\":\"Sim\303\263n Bol\303\255var\",\"name_buf\":\"Sim\303\263n\",\"height\":168},"
1409 		 "{\"name\":\"Pel\303\251\",\"name_buf\":\"Pel\303\251\",\"height\":173},"
1410 		 "{\"name\":\"Usain Bolt\",\"name_buf\":\"Usain\",\"height\":195}],"
1411 		"[{\"name\":\"Muggsy Bogues\",\"name_buf\":\"Muggsy\",\"height\":160},"
1412 		 "{\"name\":\"Hakeem Olajuwon\",\"name_buf\":\"Hakeem\",\"height\":213}],"
1413 		"[{\"name\":\"Alex Honnold\",\"name_buf\":\"Alex\",\"height\":180},"
1414 		 "{\"name\":\"Hazel Findlay\",\"name_buf\":\"Hazel\",\"height\":157},"
1415 		 "{\"name\":\"Daila Ojeda\",\"name_buf\":\"Daila\",\"height\":158},"
1416 		 "{\"name\":\"Albert Einstein\",\"name_buf\":\"Albert\",\"height\":172}]"
1417 		"]}";
1418 	char buffer[sizeof(encoded)];
1419 	int ret;
1420 
1421 	ret = json_obj_encode_buf(array_2dim_descr, ARRAY_SIZE(array_2dim_descr),
1422 				  &obj_array_array_ts, buffer, sizeof(buffer));
1423 	zassert_equal(ret, 0, "Encoding two-dimensional array returned error");
1424 	zassert_str_equal(buffer, encoded,
1425 			  "Encoded two-dimensional array is not consistent");
1426 }
1427 
ZTEST(lib_json_test,test_json_2dim_arr_extra_obj_encoding)1428 ZTEST(lib_json_test, test_json_2dim_arr_extra_obj_encoding)
1429 {
1430 	struct obj_array_2dim_extra obj_array_2dim_extra_ts = {
1431 		.name = "Paavo Nurmi",
1432 		.val = 123,
1433 		.obj_array_2dim.objects_array_array = {
1434 			[0] = {
1435 				.elements = {
1436 					[0] = {
1437 						.name = "Sim\303\263n Bol\303\255var",
1438 						.name_buf = "Sim\303\263n",
1439 						.height = 168
1440 					},
1441 					[1] = {
1442 						.name = "Pel\303\251",
1443 						.name_buf = "Pel\303\251",
1444 						.height = 173
1445 					},
1446 					[2] = {
1447 						.name = "Usain Bolt",
1448 						.name_buf = "Usain",
1449 						.height = 195
1450 					},
1451 				},
1452 				.num_elements = 3
1453 			},
1454 			[1] = {
1455 				.elements = {
1456 					[0] = {
1457 						.name = "Muggsy Bogues",
1458 						.name_buf = "Muggsy",
1459 						.height = 160
1460 					},
1461 					[1] = {
1462 						.name = "Hakeem Olajuwon",
1463 						.name_buf = "Hakeem",
1464 						.height = 213
1465 					},
1466 				},
1467 				.num_elements = 2
1468 			},
1469 			[2] = {
1470 				.elements = {
1471 					[0] = {
1472 						.name = "Alex Honnold",
1473 						.name_buf = "Alex",
1474 						.height = 180
1475 					},
1476 					[1] = {
1477 						.name = "Hazel Findlay",
1478 						.name_buf = "Hazel",
1479 						.height = 157
1480 					},
1481 					[2] = {
1482 						.name = "Daila Ojeda",
1483 						.name_buf = "Daila",
1484 						.height = 158
1485 					},
1486 					[3] = {
1487 						.name = "Albert Einstein",
1488 						.name_buf = "Albert",
1489 						.height = 172
1490 					},
1491 				},
1492 				.num_elements = 4
1493 			},
1494 		},
1495 		.obj_array_2dim.objects_array_array_len = 3,
1496 	};
1497 
1498 	char encoded[] = "{\"name\":\"Paavo Nurmi\",\"val\":123,"
1499 		"\"obj_array_2dim\":["
1500 		"[{\"name\":\"Sim\303\263n Bol\303\255var\",\"name_buf\":\"Sim\303\263n\",\"height\":168},"
1501 		 "{\"name\":\"Pel\303\251\",\"name_buf\":\"Pel\303\251\",\"height\":173},"
1502 		 "{\"name\":\"Usain Bolt\",\"name_buf\":\"Usain\",\"height\":195}],"
1503 		"[{\"name\":\"Muggsy Bogues\",\"name_buf\":\"Muggsy\",\"height\":160},"
1504 		 "{\"name\":\"Hakeem Olajuwon\",\"name_buf\":\"Hakeem\",\"height\":213}],"
1505 		"[{\"name\":\"Alex Honnold\",\"name_buf\":\"Alex\",\"height\":180},"
1506 		 "{\"name\":\"Hazel Findlay\",\"name_buf\":\"Hazel\",\"height\":157},"
1507 		 "{\"name\":\"Daila Ojeda\",\"name_buf\":\"Daila\",\"height\":158},"
1508 		 "{\"name\":\"Albert Einstein\",\"name_buf\":\"Albert\",\"height\":172}]"
1509 		"]}";
1510 	char buffer[sizeof(encoded)];
1511 	int ret;
1512 
1513 	ret = json_obj_encode_buf(array_2dim_extra_descr, ARRAY_SIZE(array_2dim_extra_descr),
1514 				  &obj_array_2dim_extra_ts, buffer, sizeof(buffer));
1515 	zassert_equal(ret, 0, "Encoding two-dimensional extra array returned error");
1516 	zassert_str_equal(buffer, encoded,
1517 			  "Encoded two-dimensional extra array is not consistent");
1518 }
1519 
ZTEST(lib_json_test,test_json_2dim_arr_extra_named_obj_encoding)1520 ZTEST(lib_json_test, test_json_2dim_arr_extra_named_obj_encoding)
1521 {
1522 	struct obj_array_2dim_extra obj_array_2dim_extra_ts = {
1523 		.name = "Paavo Nurmi",
1524 		.val = 123,
1525 		.obj_array_2dim.objects_array_array = {
1526 			[0] = {
1527 				.elements = {
1528 					[0] = {
1529 						.name = "Sim\303\263n Bol\303\255var",
1530 						.name_buf = "Sim\303\263n",
1531 						.height = 168
1532 					},
1533 					[1] = {
1534 						.name = "Pel\303\251",
1535 						.name_buf = "Pel\303\251",
1536 						.height = 173
1537 					},
1538 					[2] = {
1539 						.name = "Usain Bolt",
1540 						.name_buf = "Usain",
1541 						.height = 195
1542 					},
1543 				},
1544 				.num_elements = 3
1545 			},
1546 			[1] = {
1547 				.elements = {
1548 					[0] = {
1549 						.name = "Muggsy Bogues",
1550 						.name_buf = "Muggsy",
1551 						.height = 160
1552 					},
1553 					[1] = {
1554 						.name = "Hakeem Olajuwon",
1555 						.name_buf = "Hakeem",
1556 						.height = 213
1557 					},
1558 				},
1559 				.num_elements = 2
1560 			},
1561 			[2] = {
1562 				.elements = {
1563 					[0] = {
1564 						.name = "Alex Honnold",
1565 						.name_buf = "Alex",
1566 						.height = 180
1567 					},
1568 					[1] = {
1569 						.name = "Hazel Findlay",
1570 						.name_buf = "Hazel",
1571 						.height = 157
1572 					},
1573 					[2] = {
1574 						.name = "Daila Ojeda",
1575 						.name_buf = "Daila",
1576 						.height = 158
1577 					},
1578 					[3] = {
1579 						.name = "Albert Einstein",
1580 						.name_buf = "Albert",
1581 						.height = 172
1582 					},
1583 				},
1584 				.num_elements = 4
1585 			},
1586 		},
1587 		.obj_array_2dim.objects_array_array_len = 3,
1588 	};
1589 
1590 	char encoded[] = "{\"name\":\"Paavo Nurmi\",\"val\":123,"
1591 		"\"data\":["
1592 		"[{\"name\":\"Sim\303\263n Bol\303\255var\",\"name_buf\":\"Sim\303\263n\",\"height\":168},"
1593 		 "{\"name\":\"Pel\303\251\",\"name_buf\":\"Pel\303\251\",\"height\":173},"
1594 		 "{\"name\":\"Usain Bolt\",\"name_buf\":\"Usain\",\"height\":195}],"
1595 		"[{\"name\":\"Muggsy Bogues\",\"name_buf\":\"Muggsy\",\"height\":160},"
1596 		 "{\"name\":\"Hakeem Olajuwon\",\"name_buf\":\"Hakeem\",\"height\":213}],"
1597 		"[{\"name\":\"Alex Honnold\",\"name_buf\":\"Alex\",\"height\":180},"
1598 		 "{\"name\":\"Hazel Findlay\",\"name_buf\":\"Hazel\",\"height\":157},"
1599 		 "{\"name\":\"Daila Ojeda\",\"name_buf\":\"Daila\",\"height\":158},"
1600 		 "{\"name\":\"Albert Einstein\",\"name_buf\":\"Albert\",\"height\":172}]"
1601 		"]}";
1602 	char buffer[sizeof(encoded)];
1603 	int ret;
1604 
1605 	ret = json_obj_encode_buf(array_2dim_extra_named_descr,
1606 				  ARRAY_SIZE(array_2dim_extra_named_descr),
1607 				  &obj_array_2dim_extra_ts, buffer, sizeof(buffer));
1608 	zassert_equal(ret, 0, "Encoding two-dimensional extra named array returned error");
1609 	zassert_str_equal(buffer, encoded,
1610 			  "Encoded two-dimensional extra named array is not consistent");
1611 }
1612 
ZTEST(lib_json_test,test_json_2dim_obj_arr_decoding)1613 ZTEST(lib_json_test, test_json_2dim_obj_arr_decoding)
1614 {
1615 	struct obj_array_2dim oaa;
1616 	char encoded[] = "{\"objects_array_array\":["
1617 		"[{\"name\":\"Sim\303\263n Bol\303\255var\",\"name_buf\":\"Sim\303\263n\",\"height\":168},"
1618 		 "{\"name\":\"Pel\303\251\",\"name_buf\":\"Pel\303\251\",\"height\":173},"
1619 		 "{\"name\":\"Usain Bolt\",\"name_buf\":\"Usain\",\"height\":195}],"
1620 		"[{\"name\":\"Muggsy Bogues\",\"name_buf\":\"Muggsy\",\"height\":160},"
1621 		 "{\"name\":\"Hakeem Olajuwon\",\"name_buf\":\"Hakeem\",\"height\":213}],"
1622 		"[{\"name\":\"Alex Honnold\",\"name_buf\":\"Alex\",\"height\":180},"
1623 		 "{\"name\":\"Hazel Findlay\",\"name_buf\":\"Hazel\",\"height\":157},"
1624 		 "{\"name\":\"Daila Ojeda\",\"name_buf\":\"Daila\",\"height\":158},"
1625 		 "{\"name\":\"Albert Einstein\",\"name_buf\":\"Albert\",\"height\":172}]"
1626 		"]}";
1627 	const struct obj_array_2dim expected = {
1628 		.objects_array_array = {
1629 			[0] = {
1630 				.elements = {
1631 					[0] = {
1632 						.name = "Sim\303\263n Bol\303\255var",
1633 						.name_buf = "Sim\303\263n",
1634 						.height = 168
1635 					},
1636 					[1] = {
1637 						.name = "Pel\303\251",
1638 						.name_buf = "Pel\303\251",
1639 						.height = 173
1640 					},
1641 					[2] = {
1642 						.name = "Usain Bolt",
1643 						.name_buf = "Usain",
1644 						.height = 195
1645 					},
1646 				},
1647 				.num_elements = 3
1648 			},
1649 			[1] = {
1650 				.elements = {
1651 					[0] = {
1652 						.name = "Muggsy Bogues",
1653 						.name_buf = "Muggsy",
1654 						.height = 160
1655 					},
1656 					[1] = {
1657 						.name = "Hakeem Olajuwon",
1658 						.name_buf = "Hakeem",
1659 						.height = 213
1660 					},
1661 				},
1662 				.num_elements = 2
1663 			},
1664 			[2] = {
1665 				.elements = {
1666 					[0] = {
1667 						.name = "Alex Honnold",
1668 						.name_buf = "Alex",
1669 						.height = 180
1670 					},
1671 					[1] = {
1672 						.name = "Hazel Findlay",
1673 						.name_buf = "Hazel",
1674 						.height = 157
1675 					},
1676 					[2] = {
1677 						.name = "Daila Ojeda",
1678 						.name_buf = "Daila",
1679 						.height = 158
1680 					},
1681 					[3] = {
1682 						.name = "Albert Einstein",
1683 						.name_buf = "Albert",
1684 						.height = 172
1685 					},
1686 				},
1687 				.num_elements = 4
1688 			},
1689 		},
1690 		.objects_array_array_len = 3,
1691 	};
1692 	int ret;
1693 
1694 	ret = json_obj_parse(encoded, sizeof(encoded),
1695 			     array_2dim_descr,
1696 			     ARRAY_SIZE(array_2dim_descr),
1697 			     &oaa);
1698 
1699 	zassert_equal(ret, 1, "Array of arrays fields not decoded correctly");
1700 	zassert_equal(oaa.objects_array_array_len, 3,
1701 		      "Number of subarrays not decoded correctly");
1702 	zassert_equal(oaa.objects_array_array[0].num_elements, 3,
1703 		      "Number of object fields not decoded correctly");
1704 	zassert_equal(oaa.objects_array_array[1].num_elements, 2,
1705 		      "Number of object fields not decoded correctly");
1706 	zassert_equal(oaa.objects_array_array[2].num_elements, 4,
1707 		      "Number of object fields not decoded correctly");
1708 
1709 	for (int i = 0; i < expected.objects_array_array_len; i++) {
1710 		for (int j = 0; j < expected.objects_array_array[i].num_elements; j++) {
1711 			zassert_true(!strcmp(oaa.objects_array_array[i].elements[j].name,
1712 					     expected.objects_array_array[i].elements[j].name),
1713 				     "Element [%d][%d] name not decoded correctly", i, j);
1714 			zassert_true(!strcmp(oaa.objects_array_array[i].elements[j].name_buf,
1715 					     expected.objects_array_array[i].elements[j].name_buf),
1716 				     "Element [%d][%d] name array not decoded correctly", i, j);
1717 			zassert_equal(oaa.objects_array_array[i].elements[j].height,
1718 				      expected.objects_array_array[i].elements[j].height,
1719 				      "Element [%d][%d] height not decoded correctly", i, j);
1720 		}
1721 	}
1722 }
1723 
ZTEST(lib_json_test,test_json_string_array_size)1724 ZTEST(lib_json_test, test_json_string_array_size)
1725 {
1726 	int ret;
1727 	struct elt elt_ts;
1728 	char encoded[] = "{\"name_buf\":\"a12345678\"}";
1729 
1730 	ret = json_obj_parse(encoded, sizeof(encoded),
1731 			     elt_descr,
1732 			     ARRAY_SIZE(elt_descr),
1733 			     &elt_ts);
1734 
1735 	/* size of name_buf is 10 */
1736 	zassert_str_equal(elt_ts.name_buf,
1737 			  "a12345678", "String not decoded correctly");
1738 }
1739 
ZTEST(lib_json_test,test_json_string_array_empty)1740 ZTEST(lib_json_test, test_json_string_array_empty)
1741 {
1742 	int ret;
1743 	struct elt elt_ts;
1744 	char encoded[] = "{\"name_buf\":\"\"}";
1745 
1746 	ret = json_obj_parse(encoded, sizeof(encoded),
1747 			     elt_descr,
1748 			     ARRAY_SIZE(elt_descr),
1749 			     &elt_ts);
1750 
1751 	/* size of name_buf is 10 */
1752 	zassert_str_equal(elt_ts.name_buf, "", "String not decoded correctly");
1753 }
1754 
ZTEST(lib_json_test,test_json_string_array_max)1755 ZTEST(lib_json_test, test_json_string_array_max)
1756 {
1757 	int ret;
1758 	struct elt elt_ts;
1759 	char encoded[] = "{\"name_buf\":\"a123456789\"}";
1760 
1761 	ret = json_obj_parse(encoded, sizeof(encoded),
1762 			     elt_descr,
1763 			     ARRAY_SIZE(elt_descr),
1764 			     &elt_ts);
1765 
1766 	/* string does not fit into name_buf */
1767 	zassert_equal(ret, -EINVAL, "Decoding has to fail");
1768 }
1769 
1770 struct encoding_test {
1771 	char *str;
1772 	int result;
1773 };
1774 
parse_harness(struct encoding_test encoded[],size_t size)1775 static void parse_harness(struct encoding_test encoded[], size_t size)
1776 {
1777 	struct test_struct ts;
1778 	int ret;
1779 
1780 	for (int i = 0; i < size; i++) {
1781 		ret = json_obj_parse(encoded[i].str, strlen(encoded[i].str),
1782 				     test_descr, ARRAY_SIZE(test_descr), &ts);
1783 		zassert_equal(ret, encoded[i].result,
1784 			      "Decoding '%s' result %d, expected %d",
1785 			      encoded[i].str, ret, encoded[i].result);
1786 	}
1787 }
1788 
ZTEST(lib_json_test,test_json_invalid_string)1789 ZTEST(lib_json_test, test_json_invalid_string)
1790 {
1791 	struct encoding_test encoded[] = {
1792 		{ "{\"some_string\":\"\\u@@@@\"}", -EINVAL },
1793 		{ "{\"some_string\":\"\\uA@@@\"}", -EINVAL },
1794 		{ "{\"some_string\":\"\\uAB@@\"}", -EINVAL },
1795 		{ "{\"some_string\":\"\\uABC@\"}", -EINVAL },
1796 		{ "{\"some_string\":\"\\X\"}", -EINVAL }
1797 	};
1798 
1799 	parse_harness(encoded, ARRAY_SIZE(encoded));
1800 }
1801 
ZTEST(lib_json_test,test_json_invalid_bool)1802 ZTEST(lib_json_test, test_json_invalid_bool)
1803 {
1804 	struct encoding_test encoded[] = {
1805 		{ "{\"some_bool\":truffle }", -EINVAL},
1806 		{ "{\"some_bool\":fallacy }", -EINVAL},
1807 	};
1808 
1809 	parse_harness(encoded, ARRAY_SIZE(encoded));
1810 }
1811 
ZTEST(lib_json_test,test_json_invalid_null)1812 ZTEST(lib_json_test, test_json_invalid_null)
1813 {
1814 	struct encoding_test encoded[] = {
1815 		/* Parser will recognize 'null', but refuse to decode it */
1816 		{ "{\"some_string\":null }", -EINVAL},
1817 		/* Null spelled wrong */
1818 		{ "{\"some_string\":nutella }", -EINVAL},
1819 	};
1820 
1821 	parse_harness(encoded, ARRAY_SIZE(encoded));
1822 }
1823 
ZTEST(lib_json_test,test_json_invalid_number)1824 ZTEST(lib_json_test, test_json_invalid_number)
1825 {
1826 	struct encoding_test encoded[] = {
1827 		{ "{\"some_int\":xxx }", -EINVAL},
1828 	};
1829 
1830 	parse_harness(encoded, ARRAY_SIZE(encoded));
1831 }
1832 
ZTEST(lib_json_test,test_json_missing_quote)1833 ZTEST(lib_json_test, test_json_missing_quote)
1834 {
1835 	struct test_struct ts;
1836 	char encoded[] = "{\"some_string";
1837 	int ret;
1838 
1839 	ret = json_obj_parse(encoded, sizeof(encoded) - 1, test_descr,
1840 			     ARRAY_SIZE(test_descr), &ts);
1841 	zassert_equal(ret, -EINVAL, "Decoding has to fail");
1842 }
1843 
ZTEST(lib_json_test,test_json_wrong_token)1844 ZTEST(lib_json_test, test_json_wrong_token)
1845 {
1846 	struct test_struct ts;
1847 	char encoded[] = "{\"some_string\",}";
1848 	int ret;
1849 
1850 	ret = json_obj_parse(encoded, sizeof(encoded) - 1, test_descr,
1851 			     ARRAY_SIZE(test_descr), &ts);
1852 	zassert_equal(ret, -EINVAL, "Decoding has to fail");
1853 }
1854 
ZTEST(lib_json_test,test_json_item_wrong_type)1855 ZTEST(lib_json_test, test_json_item_wrong_type)
1856 {
1857 	struct test_struct ts;
1858 	char encoded[] = "{\"some_string\":false}";
1859 	int ret;
1860 
1861 	ret = json_obj_parse(encoded, sizeof(encoded) - 1, test_descr,
1862 			     ARRAY_SIZE(test_descr), &ts);
1863 	zassert_equal(ret, -EINVAL, "Decoding has to fail");
1864 }
1865 
ZTEST(lib_json_test,test_json_key_not_in_descr)1866 ZTEST(lib_json_test, test_json_key_not_in_descr)
1867 {
1868 	struct test_struct ts;
1869 	char encoded[] = "{\"key_not_in_descr\":123456}";
1870 	int ret;
1871 
1872 	ret = json_obj_parse(encoded, sizeof(encoded) - 1, test_descr,
1873 			     ARRAY_SIZE(test_descr), &ts);
1874 	zassert_equal(ret, 0, "No items should be decoded");
1875 }
1876 
ZTEST(lib_json_test,test_json_escape)1877 ZTEST(lib_json_test, test_json_escape)
1878 {
1879 	char buf[42];
1880 	char string[] = "\"abc"
1881 			"\\1`23"
1882 			"\bf'oo"
1883 			"\fbar"
1884 			"\nbaz"
1885 			"\rquux"
1886 			"\tfred\"";
1887 	const char *expected = "\\\"abc"
1888 			       "\\\\1`23"
1889 			       "\\bf'oo"
1890 			       "\\fbar"
1891 			       "\\nbaz"
1892 			       "\\rquux"
1893 			       "\\tfred\\\"";
1894 	size_t len;
1895 	ssize_t ret;
1896 
1897 	strncpy(buf, string, sizeof(buf) - 1);
1898 	len = strlen(buf);
1899 
1900 	ret = json_escape(buf, &len, sizeof(buf));
1901 	zassert_equal(ret, 0, "Escape did not succeed");
1902 	zassert_equal(len, sizeof(buf) - 1,
1903 		      "Escaped length not computed correctly");
1904 	zassert_str_equal(buf, expected, "Escaped value is not correct");
1905 }
1906 
1907 /* Edge case: only one character, which must be escaped. */
ZTEST(lib_json_test,test_json_escape_one)1908 ZTEST(lib_json_test, test_json_escape_one)
1909 {
1910 	char buf[3] = {'\t', '\0', '\0'};
1911 	const char *expected = "\\t";
1912 	size_t len = strlen(buf);
1913 	ssize_t ret;
1914 
1915 	ret = json_escape(buf, &len, sizeof(buf));
1916 	zassert_equal(ret, 0,
1917 		      "Escaping one character did not succeed");
1918 	zassert_equal(len, sizeof(buf) - 1,
1919 		      "Escaping one character length is not correct");
1920 	zassert_str_equal(buf, expected, "Escaped value is not correct");
1921 }
1922 
ZTEST(lib_json_test,test_json_escape_empty)1923 ZTEST(lib_json_test, test_json_escape_empty)
1924 {
1925 	char empty[] = "";
1926 	size_t len = sizeof(empty) - 1;
1927 	ssize_t ret;
1928 
1929 	ret = json_escape(empty, &len, sizeof(empty));
1930 	zassert_equal(ret, 0, "Escaping empty string not successful");
1931 	zassert_equal(len, 0, "Length of empty escaped string is not zero");
1932 	zassert_equal(empty[0], '\0', "Empty string does not remain empty");
1933 }
1934 
ZTEST(lib_json_test,test_json_escape_no_op)1935 ZTEST(lib_json_test, test_json_escape_no_op)
1936 {
1937 	char nothing_to_escape[] = "hello,world:!";
1938 	const char *expected = "hello,world:!";
1939 	size_t len = sizeof(nothing_to_escape) - 1;
1940 	ssize_t ret;
1941 
1942 	ret = json_escape(nothing_to_escape, &len, sizeof(nothing_to_escape));
1943 	zassert_equal(ret, 0, "Escape no-op not handled correctly");
1944 	zassert_equal(len, sizeof(nothing_to_escape) - 1,
1945 		      "Changed length of already escaped string");
1946 	zassert_str_equal(nothing_to_escape, expected,
1947 			  "Altered string with nothing to escape");
1948 }
1949 
ZTEST(lib_json_test,test_json_escape_bounds_check)1950 ZTEST(lib_json_test, test_json_escape_bounds_check)
1951 {
1952 	char not_enough_memory[] = "\tfoo";
1953 	size_t len = sizeof(not_enough_memory) - 1;
1954 	ssize_t ret;
1955 
1956 	ret = json_escape(not_enough_memory, &len, sizeof(not_enough_memory));
1957 	zassert_equal(ret, -ENOMEM, "Bounds check failed");
1958 }
1959 
ZTEST(lib_json_test,test_json_encode_bounds_check)1960 ZTEST(lib_json_test, test_json_encode_bounds_check)
1961 {
1962 	struct number {
1963 		uint32_t val;
1964 	} str = { 0 };
1965 	const struct json_obj_descr descr[] = {
1966 		JSON_OBJ_DESCR_PRIM(struct number, val, JSON_TOK_NUMBER),
1967 	};
1968 	/* Encodes to {"val":0}\0 for a total of 10 bytes */
1969 	uint8_t buf[10];
1970 	ssize_t ret = json_obj_encode_buf(descr, ARRAY_SIZE(descr),
1971 					  &str, buf, 10);
1972 	zassert_equal(ret, 0, "Encoding failed despite large enough buffer");
1973 	zassert_equal(strlen(buf), 9, "Encoded string length mismatch");
1974 
1975 	ret = json_obj_encode_buf(descr, ARRAY_SIZE(descr),
1976 				     &str, buf, 9);
1977 	zassert_equal(ret, -ENOMEM, "Bounds check failed");
1978 }
1979 
ZTEST(lib_json_test,test_large_descriptor)1980 ZTEST(lib_json_test, test_large_descriptor)
1981 {
1982 	struct large_struct {
1983 		int int0;
1984 		int int1;
1985 		int int2;
1986 		int int3;
1987 		int int4;
1988 		int int5;
1989 		int int6;
1990 		int int7;
1991 		int int8;
1992 		int int9;
1993 		int int10;
1994 		int int11;
1995 		int int12;
1996 		int int13;
1997 		int int14;
1998 		int int15;
1999 		int int16;
2000 		int int17;
2001 		int int18;
2002 		int int19;
2003 		int int20;
2004 		int int21;
2005 		int int22;
2006 		int int23;
2007 		int int24;
2008 		int int25;
2009 		int int26;
2010 		int int27;
2011 		int int28;
2012 		int int29;
2013 		int int30;
2014 		int int31;
2015 		int int32;
2016 		int int33;
2017 		int int34;
2018 		int int35;
2019 		int int36;
2020 		int int37;
2021 		int int38;
2022 		int int39;
2023 	};
2024 
2025 	static const struct json_obj_descr large_descr[] = {
2026 		JSON_OBJ_DESCR_PRIM(struct large_struct, int0, JSON_TOK_NUMBER),
2027 		JSON_OBJ_DESCR_PRIM(struct large_struct, int1, JSON_TOK_NUMBER),
2028 		JSON_OBJ_DESCR_PRIM(struct large_struct, int2, JSON_TOK_NUMBER),
2029 		JSON_OBJ_DESCR_PRIM(struct large_struct, int3, JSON_TOK_NUMBER),
2030 		JSON_OBJ_DESCR_PRIM(struct large_struct, int4, JSON_TOK_NUMBER),
2031 		JSON_OBJ_DESCR_PRIM(struct large_struct, int5, JSON_TOK_NUMBER),
2032 		JSON_OBJ_DESCR_PRIM(struct large_struct, int6, JSON_TOK_NUMBER),
2033 		JSON_OBJ_DESCR_PRIM(struct large_struct, int7, JSON_TOK_NUMBER),
2034 		JSON_OBJ_DESCR_PRIM(struct large_struct, int8, JSON_TOK_NUMBER),
2035 		JSON_OBJ_DESCR_PRIM(struct large_struct, int9, JSON_TOK_NUMBER),
2036 		JSON_OBJ_DESCR_PRIM(struct large_struct, int10, JSON_TOK_NUMBER),
2037 		JSON_OBJ_DESCR_PRIM(struct large_struct, int11, JSON_TOK_NUMBER),
2038 		JSON_OBJ_DESCR_PRIM(struct large_struct, int12, JSON_TOK_NUMBER),
2039 		JSON_OBJ_DESCR_PRIM(struct large_struct, int13, JSON_TOK_NUMBER),
2040 		JSON_OBJ_DESCR_PRIM(struct large_struct, int14, JSON_TOK_NUMBER),
2041 		JSON_OBJ_DESCR_PRIM(struct large_struct, int15, JSON_TOK_NUMBER),
2042 		JSON_OBJ_DESCR_PRIM(struct large_struct, int16, JSON_TOK_NUMBER),
2043 		JSON_OBJ_DESCR_PRIM(struct large_struct, int17, JSON_TOK_NUMBER),
2044 		JSON_OBJ_DESCR_PRIM(struct large_struct, int18, JSON_TOK_NUMBER),
2045 		JSON_OBJ_DESCR_PRIM(struct large_struct, int19, JSON_TOK_NUMBER),
2046 		JSON_OBJ_DESCR_PRIM(struct large_struct, int20, JSON_TOK_NUMBER),
2047 		JSON_OBJ_DESCR_PRIM(struct large_struct, int21, JSON_TOK_NUMBER),
2048 		JSON_OBJ_DESCR_PRIM(struct large_struct, int22, JSON_TOK_NUMBER),
2049 		JSON_OBJ_DESCR_PRIM(struct large_struct, int23, JSON_TOK_NUMBER),
2050 		JSON_OBJ_DESCR_PRIM(struct large_struct, int24, JSON_TOK_NUMBER),
2051 		JSON_OBJ_DESCR_PRIM(struct large_struct, int25, JSON_TOK_NUMBER),
2052 		JSON_OBJ_DESCR_PRIM(struct large_struct, int26, JSON_TOK_NUMBER),
2053 		JSON_OBJ_DESCR_PRIM(struct large_struct, int27, JSON_TOK_NUMBER),
2054 		JSON_OBJ_DESCR_PRIM(struct large_struct, int28, JSON_TOK_NUMBER),
2055 		JSON_OBJ_DESCR_PRIM(struct large_struct, int29, JSON_TOK_NUMBER),
2056 		JSON_OBJ_DESCR_PRIM(struct large_struct, int30, JSON_TOK_NUMBER),
2057 		JSON_OBJ_DESCR_PRIM(struct large_struct, int31, JSON_TOK_NUMBER),
2058 		JSON_OBJ_DESCR_PRIM(struct large_struct, int32, JSON_TOK_NUMBER),
2059 		JSON_OBJ_DESCR_PRIM(struct large_struct, int33, JSON_TOK_NUMBER),
2060 		JSON_OBJ_DESCR_PRIM(struct large_struct, int34, JSON_TOK_NUMBER),
2061 		JSON_OBJ_DESCR_PRIM(struct large_struct, int35, JSON_TOK_NUMBER),
2062 		JSON_OBJ_DESCR_PRIM(struct large_struct, int36, JSON_TOK_NUMBER),
2063 		JSON_OBJ_DESCR_PRIM(struct large_struct, int37, JSON_TOK_NUMBER),
2064 		JSON_OBJ_DESCR_PRIM(struct large_struct, int38, JSON_TOK_NUMBER),
2065 		JSON_OBJ_DESCR_PRIM(struct large_struct, int39, JSON_TOK_NUMBER),
2066 	};
2067 	char encoded[] = "{"
2068 		"\"int1\": 1,"
2069 		"\"int21\": 21,"
2070 		"\"int31\": 31,"
2071 		"\"int39\": 39"
2072 		"}";
2073 
2074 	struct large_struct ls;
2075 
2076 	int64_t ret = json_obj_parse(encoded, sizeof(encoded) - 1, large_descr,
2077 				     ARRAY_SIZE(large_descr), &ls);
2078 
2079 	zassert_false(ret < 0, "json_obj_parse returned error %lld", ret);
2080 	zassert_false(ret & ((int64_t)1 << 2), "Field int2 erroneously decoded");
2081 	zassert_false(ret & ((int64_t)1 << 35), "Field int35 erroneously decoded");
2082 	zassert_true(ret & ((int64_t)1 << 1), "Field int1 not decoded");
2083 	zassert_true(ret & ((int64_t)1 << 21), "Field int21 not decoded");
2084 	zassert_true(ret & ((int64_t)1 << 31), "Field int31 not decoded");
2085 	zassert_true(ret & ((int64_t)1 << 39), "Field int39 not decoded");
2086 }
2087 
ZTEST(lib_json_test,test_json_encoded_object_tok_encoding)2088 ZTEST(lib_json_test, test_json_encoded_object_tok_encoding)
2089 {
2090 	static const char encoded[] = "{"
2091 		"\"encoded_obj\":{\"test\":{\"nested\":\"yes\"}},"
2092 		"\"encoded_obj_array\":["
2093 		"{\"array_1\":{\"nested\":\"yes\"}},"
2094 		"{\"array_2\":{\"nested\":\"yes\"}},"
2095 		"{\"array_3\":{\"nested\":\"yes\"}}],"
2096 		"\"ok\":1234}";
2097 	const struct test_json_tok_encoded_obj obj = {
2098 		.encoded_obj = "{\"test\":{\"nested\":\"yes\"}}",
2099 		.encoded_obj_array[0] = "{\"array_1\":{\"nested\":\"yes\"}}",
2100 		.encoded_obj_array[1] = "{\"array_2\":{\"nested\":\"yes\"}}",
2101 		.encoded_obj_array[2] = "{\"array_3\":{\"nested\":\"yes\"}}",
2102 		.encoded_obj_array_len = 3,
2103 		.ok = 1234,
2104 	};
2105 	char buffer[sizeof(encoded)];
2106 	int ret;
2107 
2108 	ret = json_obj_encode_buf(test_json_tok_encoded_obj_descr,
2109 				  ARRAY_SIZE(test_json_tok_encoded_obj_descr), &obj, buffer,
2110 				  sizeof(buffer));
2111 
2112 	zassert_equal(ret, 0, "Encoding function failed");
2113 	zassert_mem_equal(buffer, encoded, sizeof(encoded), "Encoded contents not consistent");
2114 }
2115 
ZTEST(lib_json_test,test_json_array_alignment)2116 ZTEST(lib_json_test, test_json_array_alignment)
2117 {
2118 	char encoded[] = "{"
2119 	"\"array\": [ "
2120 	"{ \"int1\": 1, "
2121 	"\"int2\": 2, "
2122 	"\"int3\":  3 }, "
2123 	"{ \"int1\": 4, "
2124 	"\"int2\": 5, "
2125 	"\"int3\": 6 } "
2126 	"] "
2127 	"}";
2128 
2129 	struct test_outer o;
2130 	int64_t ret = json_obj_parse(encoded, sizeof(encoded) - 1, outer_descr,
2131 				     ARRAY_SIZE(outer_descr), &o);
2132 
2133 	zassert_false(ret < 0, "json_obj_parse returned error %lld", ret);
2134 	zassert_equal(o.num_elements, 2, "Number of elements not decoded correctly");
2135 
2136 	zassert_equal(o.array[0].int1, 1, "Element 0 int1 not decoded correctly");
2137 	zassert_equal(o.array[0].int2, 2, "Element 0 int2 not decoded correctly");
2138 	zassert_equal(o.array[0].int3, 3, "Element 0 int3 not decoded correctly");
2139 
2140 	zassert_equal(o.array[1].int1, 4, "Element 1 int1 not decoded correctly");
2141 	zassert_equal(o.array[1].int2, 5, "Element 1 int2 not decoded correctly");
2142 	zassert_equal(o.array[1].int3, 6, "Element 1 int3 not decoded correctly");
2143 }
2144 
ZTEST(lib_json_test,test_json_array_alignment_bool)2145 ZTEST(lib_json_test, test_json_array_alignment_bool)
2146 {
2147 	char encoded[] = "{\"array\":["
2148 			 "{\"bool1\":true,\"int1\":1,\"bool2\":false},"
2149 			 "{\"bool1\":true,\"int1\":2,\"bool2\":false}"
2150 			 "]}";
2151 
2152 	struct test_alignment_bool o = { 0 };
2153 	int64_t ret = json_obj_parse(encoded, sizeof(encoded) - 1, alignment_bool_descr,
2154 				     ARRAY_SIZE(alignment_bool_descr), &o);
2155 
2156 	zassert_false(ret < 0, "json_obj_parse returned error %lld", ret);
2157 	zassert_equal(o.num_elements, 2, "Number of elements not decoded correctly");
2158 
2159 	zassert_equal(o.array[0].bool1, true, "Element 0 bool1 not decoded correctly");
2160 	zassert_equal(o.array[0].int1, 1, "Element 0 int1 not decoded correctly");
2161 	zassert_equal(o.array[0].bool2, false, "Element 0 bool2 not decoded correctly");
2162 
2163 	zassert_equal(o.array[1].bool1, true, "Element 1 bool1 not decoded correctly");
2164 	zassert_equal(o.array[1].int1, 2, "Element 1 int1 not decoded correctly");
2165 	zassert_equal(o.array[1].bool2, false, "Element 1 bool2 not decoded correctly");
2166 }
2167 
ZTEST(lib_json_test,test_json_invalid_int)2168 ZTEST(lib_json_test, test_json_invalid_int)
2169 {
2170 	struct sub_test {
2171 		char str[30];
2172 		int result;
2173 	};
2174 	struct sub_test encoded[] = {
2175 		{ "{\"int8_cero\":128}", -EINVAL },
2176 		{ "{\"int8_cero\":-129}", -EINVAL },
2177 		{ "{\"uint8_cero\":257}", -EINVAL },
2178 		{ "{\"int16_cero\":32768}", -EINVAL },
2179 		{ "{\"int16_cero\":-32769}", -EINVAL },
2180 		{ "{\"uint16_cero\":65536}", -EINVAL },
2181 	};
2182 
2183 	struct test_int_limits ts;
2184 	int ret;
2185 
2186 	for (int i = 0; i < ARRAY_SIZE(encoded); i++) {
2187 		ret = json_obj_parse(encoded[i].str, strlen(encoded[i].str),
2188 				     obj_limits_descr, ARRAY_SIZE(obj_limits_descr), &ts);
2189 		zassert_equal(ret, encoded[i].result,
2190 			      "Decoding '%s' result %d, expected %d",
2191 			      encoded[i].str, ret, encoded[i].result);
2192 	}
2193 }
2194 
ZTEST(lib_json_test,test_json_enums)2195 ZTEST(lib_json_test, test_json_enums)
2196 {
2197 	int ret = 0;
2198 	char encoded[] = "{\"i8\":-128,"
2199 			 "\"u8\":255,"
2200 			 "\"i16\":-32768,"
2201 			 "\"u16\":65535,"
2202 			 "\"i32\":-2147483648,"
2203 			 "\"u32\":4294967295"
2204 			 "}";
2205 	char buffer[sizeof(encoded)];
2206 	struct test_enums enums_decoded = {0};
2207 	struct test_enums enums = {0};
2208 
2209 	enums.i8 = I8_MIN;
2210 	enums.u8 = U8_MAX;
2211 	enums.i16 = I16_MIN;
2212 	enums.u16 = U16_MAX;
2213 	enums.i32 = I32_MIN;
2214 	enums.u32 = U32_MAX;
2215 
2216 	ret = json_obj_encode_buf(enums_descr, ARRAY_SIZE(enums_descr),
2217 				&enums, buffer, sizeof(buffer));
2218 	ret = json_obj_parse(encoded, sizeof(encoded) - 1, enums_descr,
2219 			     ARRAY_SIZE(enums_descr), &enums_decoded);
2220 
2221 	zassert_str_equal(encoded, buffer,
2222 			  "Enums not encoded correctly");
2223 	zassert_true(!memcmp(&enums, &enums_decoded, sizeof(enums)),
2224 		     "Enums not decoded correctly");
2225 }
2226 
ZTEST(lib_json_test,test_json_string_nullptr)2227 ZTEST(lib_json_test, test_json_string_nullptr)
2228 {
2229 	int ret = 0;
2230 
2231 	struct test_struct ts = {0};
2232 	char *buffer;
2233 	size_t len;
2234 
2235 	len = json_calc_encoded_len(test_descr, ARRAY_SIZE(test_descr), &ts);
2236 	zassert(len > 0, "encoded size incorrect");
2237 
2238 	buffer = alloca(len + 1);
2239 	ret = json_obj_encode_buf(test_descr, ARRAY_SIZE(test_descr), &ts, buffer, len + 1);
2240 	zassert_equal(ret, 0, "Encoding function failed");
2241 
2242 	ret = json_obj_parse(buffer, len, test_descr, ARRAY_SIZE(test_descr), &ts);
2243 	zassert_equal(ret, (1 << ARRAY_SIZE(test_descr)) - 1, "Not all fields decoded correctly");
2244 	zassert_str_equal(ts.some_string, "", "String not decoded correctly");
2245 }
2246 
ZTEST(lib_json_test,test_json_mixed_arr_parse)2247 ZTEST(lib_json_test, test_json_mixed_arr_parse)
2248 {
2249 	struct test_mixed_arr arr = {0};
2250 	char json[] = "[\"msg\", 123456, {\"nested_int\":42,\"nested_bool\":true,"
2251 		      "\"nested_string\":\"abc\","
2252 		      "\"nested_string_buf\":\"buf\",\"nested_int8\":1,\"nested_uint8\":2,"
2253 		      "\"nested_int64\":3,\"nested_uint64\":4}, [10,20,30], \"ok\"]";
2254 	int ret = json_mixed_arr_parse(json, strlen(json),
2255 				       test_mixed_arr_descr,
2256 				       ARRAY_SIZE(test_mixed_arr_descr), &arr);
2257 
2258 	zassert_equal(ret, 5, "Should parse 5 elements");
2259 	zassert_str_equal(arr.msg_type, "msg", NULL);
2260 	zassert_equal(arr.dev_id, 123456, NULL);
2261 	zassert_equal(arr.nested.nested_int, 42, NULL);
2262 	zassert_equal(arr.arr_len, 3, NULL);
2263 	zassert_equal(arr.arr[0], 10, NULL);
2264 	zassert_equal(arr.arr[1], 20, NULL);
2265 	zassert_equal(arr.arr[2], 30, NULL);
2266 	zassert_str_equal(arr.status_buf, "ok", NULL);
2267 }
2268 
ZTEST(lib_json_test,test_json_mixed_arr_encode)2269 ZTEST(lib_json_test, test_json_mixed_arr_encode)
2270 {
2271 	char buf[256];
2272 	struct test_mixed_arr pkt = {0};
2273 	struct test_mixed_arr arr = {
2274 		.msg_type = "msg",
2275 		.dev_id = 123456,
2276 		.nested = {
2277 			.nested_int = 42,
2278 			.nested_bool = true,
2279 			.nested_string = "abc",
2280 			.nested_string_buf = "buf",
2281 			.nested_int8 = 1,
2282 			.nested_uint8 = 2,
2283 			.nested_int64 = 3,
2284 			.nested_uint64 = 4,
2285 		},
2286 		.arr = {10, 20, 30},
2287 		.arr_len = 3,
2288 		.status_buf = "ok",
2289 		.count = 5
2290 	};
2291 	int ret = json_mixed_arr_encode_buf(test_mixed_arr_descr,
2292 					    ARRAY_SIZE(test_mixed_arr_descr),
2293 					    &arr, buf, sizeof(buf));
2294 
2295 	zassert_equal(ret, 0, NULL);
2296 
2297 	ret = json_mixed_arr_parse(buf, strlen(buf),
2298 				   test_mixed_arr_descr,
2299 				   ARRAY_SIZE(test_mixed_arr_descr), &pkt);
2300 
2301 	zassert_equal(ret, 5, NULL);
2302 	zassert_str_equal(pkt.msg_type, "msg", NULL);
2303 	zassert_equal(pkt.dev_id, 123456, NULL);
2304 	zassert_equal(pkt.arr[0], 10, NULL);
2305 	zassert_str_equal(pkt.status_buf, "ok", NULL);
2306 }
2307 
ZTEST(lib_json_test,test_json_mixed_arr_empty)2308 ZTEST(lib_json_test, test_json_mixed_arr_empty)
2309 {
2310 	struct test_mixed_arr arr = {0};
2311 	char json[] = "[]";
2312 	int ret = json_mixed_arr_parse(json, strlen(json),
2313 		test_mixed_arr_descr, 0, &arr);
2314 
2315 	zassert_equal(ret, 0, NULL);
2316 }
2317 
ZTEST(lib_json_test,test_json_mixed_arr_calc_len)2318 ZTEST(lib_json_test, test_json_mixed_arr_calc_len)
2319 {
2320 	char buf[256];
2321 	ssize_t calc_len;
2322 	int ret;
2323 	struct test_mixed_arr arr = {
2324 		.msg_type = "msg",
2325 		.dev_id = 123456,
2326 		.nested = {
2327 			.nested_int = 42,
2328 			.nested_bool = true,
2329 			.nested_string = "abc",
2330 			.nested_string_buf = "buf",
2331 			.nested_int8 = 1,
2332 			.nested_uint8 = 2,
2333 			.nested_int64 = 3,
2334 			.nested_uint64 = 4,
2335 		},
2336 		.arr = {10, 20, 30},
2337 		.arr_len = 3,
2338 		.status_buf = "ok",
2339 		.count = 5
2340 	};
2341 
2342 	calc_len = json_calc_mixed_arr_len(test_mixed_arr_descr,
2343 					   ARRAY_SIZE(test_mixed_arr_descr),
2344 					   &arr);
2345 	ret = json_mixed_arr_encode_buf(test_mixed_arr_descr,
2346 					ARRAY_SIZE(test_mixed_arr_descr),
2347 					&arr, buf, sizeof(buf));
2348 	zassert_equal(ret, 0, NULL);
2349 
2350 	zassert_equal(calc_len, (ssize_t)strlen(buf), "Length mismatch");
2351 }
2352 
2353 /**
2354  * @brief Test that escape sequences don't duplicate on encode/decode cycles
2355  *
2356  * This test specifically targets the bug where backslashes in escape sequences
2357  * like \n, \t, etc. get duplicated with each encode/decode cycle.
2358  */
ZTEST(lib_json_test,test_json_escape_sequence_stability)2359 ZTEST(lib_json_test, test_json_escape_sequence_stability)
2360 {
2361 	struct escape_test_data original = {
2362 		.string_value = "Line1\nLine2\tTabbed",
2363 		.integer_value = 42,
2364 	};
2365 	strncpy(original.string_value, "Line1\nLine2\tTabbed", sizeof(original.string_value) - 1);
2366 	strncpy(original.string_buf, "Text with\nnewline and\ttab",
2367 		sizeof(original.string_buf) - 1);
2368 
2369 	char buffer[512];
2370 	struct escape_test_data decoded = {0};
2371 	int ret;
2372 
2373 	/* Encode -> Decode -> Encode -> Decode cycle */
2374 
2375 	/* First encode */
2376 	ret = json_obj_encode_buf(escape_test_descr, ARRAY_SIZE(escape_test_descr), &original,
2377 				  buffer, sizeof(buffer));
2378 	zassert_equal(ret, 0, "First encoding failed");
2379 
2380 	/* First decode */
2381 	ret = json_obj_parse(buffer, strlen(buffer), escape_test_descr,
2382 			     ARRAY_SIZE(escape_test_descr), &decoded);
2383 	zassert_equal(ret, (1 << ARRAY_SIZE(escape_test_descr)) - 1, "First decoding failed");
2384 
2385 	/* Verify first decode matches original */
2386 	zassert_str_equal(decoded.string_value, original.string_value,
2387 			  "String value changed after first decode");
2388 	zassert_str_equal(decoded.string_buf, original.string_buf,
2389 			  "String buffer changed after first decode");
2390 	zassert_equal(decoded.integer_value, original.integer_value,
2391 		      "Integer value changed after first decode");
2392 
2393 	/* Second encode */
2394 	ret = json_obj_encode_buf(escape_test_descr, ARRAY_SIZE(escape_test_descr), &decoded,
2395 				  buffer, sizeof(buffer));
2396 	zassert_equal(ret, 0, "Second encoding failed");
2397 
2398 	/* Second decode */
2399 	struct escape_test_data decoded2 = {0};
2400 
2401 	ret = json_obj_parse(buffer, strlen(buffer), escape_test_descr,
2402 			     ARRAY_SIZE(escape_test_descr), &decoded2);
2403 	zassert_equal(ret, (1 << ARRAY_SIZE(escape_test_descr)) - 1, "Second decoding failed");
2404 
2405 	/* CRITICAL: Verify strings remain unchanged after multiple cycles */
2406 	zassert_str_equal(decoded2.string_value, original.string_value,
2407 			  "String value corrupted after encode/decode cycle");
2408 	zassert_str_equal(decoded2.string_buf, original.string_buf,
2409 			  "String buffer corrupted after encode/decode cycle");
2410 	zassert_equal(decoded2.integer_value, original.integer_value,
2411 		      "Integer value changed after encode/decode cycle");
2412 }
2413 
2414 /**
2415  * @brief Test specific escape sequences individually
2416  */
ZTEST(lib_json_test,test_json_specific_escape_sequences)2417 ZTEST(lib_json_test, test_json_specific_escape_sequences)
2418 {
2419 	struct test_case {
2420 		const char *input;
2421 		const char *description;
2422 	};
2423 
2424 	struct test_case test_cases[] = {
2425 		{"Simple newline\n", "newline"},
2426 		{"Multiple\nnew\nlines\n", "multiple newlines"},
2427 		{"Tab\tseparated", "tab"},
2428 		{"Mixed\n\tboth", "mixed newline and tab"},
2429 		{"Backslash\\character", "backslash"},
2430 		{"Quote\"test", "quote"},
2431 		{"Backspace\btest", "backspace"},
2432 		{"Form\ffeed", "form feed"},
2433 		{"Carriage\rreturn", "carriage return"},
2434 		{"Slash/test", "slash"},
2435 	};
2436 
2437 	for (size_t i = 0; i < ARRAY_SIZE(test_cases); i++) {
2438 		struct escape_test_data test_data = {
2439 			.integer_value = (int)i,
2440 		};
2441 		strncpy(test_data.string_value, test_cases[i].input,
2442 			sizeof(test_data.string_value) - 1);
2443 		strncpy(test_data.string_buf, test_cases[i].input,
2444 			sizeof(test_data.string_buf) - 1);
2445 
2446 		char buffer[256];
2447 		struct escape_test_data decoded = {0};
2448 		int ret;
2449 
2450 		/* Encode */
2451 		ret = json_obj_encode_buf(escape_test_descr, ARRAY_SIZE(escape_test_descr),
2452 					  &test_data, buffer, sizeof(buffer));
2453 		zassert_equal(ret, 0, "Encoding failed for %s", test_cases[i].description);
2454 
2455 		/* Decode */
2456 		ret = json_obj_parse(buffer, strlen(buffer), escape_test_descr,
2457 				     ARRAY_SIZE(escape_test_descr), &decoded);
2458 		zassert_equal(ret, (1 << ARRAY_SIZE(escape_test_descr)) - 1,
2459 			      "Decoding failed for %s", test_cases[i].description);
2460 
2461 		/* Verify string is preserved */
2462 		zassert_str_equal(decoded.string_value, test_data.string_value,
2463 				  "Escape sequence corrupted for %s", test_cases[i].description);
2464 		zassert_str_equal(decoded.string_buf, test_data.string_buf,
2465 				  "String buffer corrupted for %s", test_cases[i].description);
2466 	}
2467 }
2468 
2469 /**
2470  * @brief Test that encoded JSON contains proper escape sequences
2471  */
ZTEST(lib_json_test,test_json_escape_encoding_correctness)2472 ZTEST(lib_json_test, test_json_escape_encoding_correctness)
2473 {
2474 	struct escape_test_data test_data = {
2475 		.string_value = "Test\nLine",
2476 		.integer_value = 123,
2477 	};
2478 	strncpy(test_data.string_buf, "Buffer\tTest", sizeof(test_data.string_buf) - 1);
2479 
2480 	char buffer[256];
2481 	int ret;
2482 
2483 	/* Encode the data */
2484 	ret = json_obj_encode_buf(escape_test_descr, ARRAY_SIZE(escape_test_descr), &test_data,
2485 				  buffer, sizeof(buffer));
2486 	zassert_equal(ret, 0, "Encoding failed");
2487 
2488 	/* Verify the encoded JSON contains proper escape sequences */
2489 	zassert_not_null(strstr(buffer, "\\n"), "Newline not properly escaped in JSON");
2490 	zassert_not_null(strstr(buffer, "\\t"), "Tab not properly escaped in JSON");
2491 
2492 	/* The encoded JSON should NOT contain raw control characters */
2493 	zassert_is_null(strchr(buffer, '\n'), "Raw newline found in encoded JSON");
2494 	zassert_is_null(strchr(buffer, '\t'), "Raw tab found in encoded JSON");
2495 }
2496 
2497 /**
2498  * @brief Test multiple encode/decode cycles to catch gradual corruption
2499  */
ZTEST(lib_json_test,test_json_multiple_cycle_stability)2500 ZTEST(lib_json_test, test_json_multiple_cycle_stability)
2501 {
2502 	struct escape_test_data original = {
2503 		.string_value = "Start\nMiddle\tEnd",
2504 		.integer_value = 99,
2505 	};
2506 	strncpy(original.string_value, "Start\nMiddle\tEnd", sizeof(original.string_value) - 1);
2507 	strncpy(original.string_buf, "Cyclic\ntest\tdata", sizeof(original.string_buf) - 1);
2508 
2509 	char buffer[512];
2510 	struct escape_test_data current = {0};
2511 	int ret;
2512 
2513 	/* Initialize current by copying from original */
2514 	current.integer_value = original.integer_value;
2515 	strncpy(current.string_value, original.string_value, sizeof(current.string_value));
2516 	strncpy(current.string_buf, original.string_buf, sizeof(current.string_buf));
2517 
2518 	/* Run multiple encode/decode cycles */
2519 	for (int cycle = 0; cycle < 5; cycle++) {
2520 		/* Encode */
2521 		ret = json_obj_encode_buf(escape_test_descr, ARRAY_SIZE(escape_test_descr),
2522 					  &current, buffer, sizeof(buffer));
2523 		zassert_equal(ret, 0, "Encoding failed at cycle %d", cycle);
2524 
2525 		/* Decode into a fresh struct */
2526 		struct escape_test_data next = {0};
2527 
2528 		ret = json_obj_parse(buffer, strlen(buffer), escape_test_descr,
2529 				     ARRAY_SIZE(escape_test_descr), &next);
2530 		zassert_equal(ret, (1 << ARRAY_SIZE(escape_test_descr)) - 1,
2531 			      "Decoding failed at cycle %d", cycle);
2532 
2533 		/* Verify no corruption */
2534 		zassert_str_equal(next.string_value, original.string_value,
2535 				  "String corrupted after %d cycles", cycle + 1);
2536 		zassert_str_equal(next.string_buf, original.string_buf,
2537 				  "String buffer corrupted after %d cycles", cycle + 1);
2538 		zassert_equal(next.integer_value, original.integer_value,
2539 			      "Integer corrupted after %d cycles", cycle + 1);
2540 
2541 		/* Prepare for next cycle */
2542 		current.integer_value = next.integer_value;
2543 		strncpy(current.string_value, next.string_value, sizeof(current.string_value));
2544 		strncpy(current.string_buf, next.string_buf, sizeof(current.string_buf));
2545 	}
2546 }
2547 
2548 /**
2549  * @brief Test the exact scenario from the bug report
2550  */
ZTEST(lib_json_test,test_json_escape_sequence_regression)2551 ZTEST(lib_json_test, test_json_escape_sequence_regression)
2552 {
2553 	/* This test reproduces the exact scenario described in GitHub issue #88552 */
2554 	struct escape_test_data config_data = {
2555 		.string_value = "some_string\n",
2556 		.integer_value = 69,
2557 	};
2558 	strncpy(config_data.string_value, "some_string\n", sizeof(config_data.string_value) - 1);
2559 	strncpy(config_data.string_buf, "config\nvalue", sizeof(config_data.string_buf) - 1);
2560 
2561 	char encoded_json[256];
2562 	struct escape_test_data decoded_data = {0};
2563 	int ret;
2564 
2565 	/* Simulate multiple boot cycles with encode/decode - this is where the bug manifests */
2566 	for (int boot_cycle = 0; boot_cycle < 3; boot_cycle++) {
2567 		/* Encode (simulate saving to flash) */
2568 		ret = json_obj_encode_buf(escape_test_descr, ARRAY_SIZE(escape_test_descr),
2569 					  &config_data, encoded_json, sizeof(encoded_json));
2570 		zassert_equal(ret, 0, "Encode failed at boot cycle %d", boot_cycle);
2571 
2572 		/* Decode (simulate reading from flash) */
2573 		ret = json_obj_parse(encoded_json, strlen(encoded_json), escape_test_descr,
2574 				     ARRAY_SIZE(escape_test_descr), &decoded_data);
2575 		zassert_equal(ret, (1 << ARRAY_SIZE(escape_test_descr)) - 1,
2576 			      "Decode failed at boot cycle %d", boot_cycle);
2577 
2578 		/* Update for next cycle (simulate config change) */
2579 		decoded_data.integer_value++;
2580 		config_data = decoded_data;
2581 	}
2582 
2583 	/* After multiple cycles, the string should be unchanged */
2584 	zassert_str_equal(config_data.string_value, "some_string\n",
2585 			  "String value corrupted after multiple boot cycles");
2586 	zassert_str_equal(config_data.string_buf, "config\nvalue",
2587 			  "String buffer corrupted after multiple boot cycles");
2588 
2589 	/* Additional verification: check that backslashes didn't duplicate */
2590 	const char *expected_value = "some_string\n";
2591 	const char *expected_buf = "config\nvalue";
2592 
2593 	zassert_str_equal(config_data.string_value, expected_value,
2594 			  "Escape sequence regression detected in string_value");
2595 	zassert_str_equal(config_data.string_buf, expected_buf,
2596 			  "Escape sequence regression detected in string_buf");
2597 }
2598 
2599 /**
2600  * @brief Test to detect backslash duplication specifically
2601  */
ZTEST(lib_json_test,test_json_backslash_duplication)2602 ZTEST(lib_json_test, test_json_backslash_duplication)
2603 {
2604 	/* This test specifically checks for the backslash duplication bug */
2605 	struct escape_test_data test_data = {
2606 		.string_value = "test\nstring",
2607 		.integer_value = 1,
2608 	};
2609 	strncpy(test_data.string_buf, "buffer\ncontent", sizeof(test_data.string_buf) - 1);
2610 
2611 	char buffer1[256], buffer2[256];
2612 	struct escape_test_data decoded1 = {0}, decoded2 = {0};
2613 	int ret;
2614 
2615 	/* First encode/decode cycle */
2616 	ret = json_obj_encode_buf(escape_test_descr, ARRAY_SIZE(escape_test_descr), &test_data,
2617 				  buffer1, sizeof(buffer1));
2618 	zassert_equal(ret, 0, "First encode failed");
2619 
2620 	ret = json_obj_parse(buffer1, strlen(buffer1), escape_test_descr,
2621 			     ARRAY_SIZE(escape_test_descr), &decoded1);
2622 	zassert_equal(ret, (1 << ARRAY_SIZE(escape_test_descr)) - 1, "First decode failed");
2623 
2624 	/* Second encode/decode cycle */
2625 	ret = json_obj_encode_buf(escape_test_descr, ARRAY_SIZE(escape_test_descr), &decoded1,
2626 				  buffer2, sizeof(buffer2));
2627 	zassert_equal(ret, 0, "Second encode failed");
2628 
2629 	ret = json_obj_parse(buffer2, strlen(buffer2), escape_test_descr,
2630 			     ARRAY_SIZE(escape_test_descr), &decoded2);
2631 	zassert_equal(ret, (1 << ARRAY_SIZE(escape_test_descr)) - 1, "Second decode failed");
2632 
2633 	/* The critical assertion: strings should be identical across cycles */
2634 	zassert_str_equal(decoded1.string_value, decoded2.string_value,
2635 			  "Backslash duplication detected in string_value");
2636 	zassert_str_equal(decoded1.string_buf, decoded2.string_buf,
2637 			  "Backslash duplication detected in string_buf");
2638 	zassert_str_equal(test_data.string_value, decoded2.string_value,
2639 			  "Original string value not preserved");
2640 	zassert_str_equal(test_data.string_buf, decoded2.string_buf,
2641 			  "Original string buffer not preserved");
2642 }
2643 
ZTEST(lib_json_test,test_json_quote_escaping_encoding)2644 ZTEST(lib_json_test, test_json_quote_escaping_encoding)
2645 {
2646 	struct escape_test_data test_data = {
2647 		.integer_value = 42,
2648 	};
2649 	strncpy(test_data.string_value, "Text with \"quotes\" inside",
2650 		sizeof(test_data.string_value) - 1);
2651 	strncpy(test_data.string_buf, "Buffer with \"quotes\"", sizeof(test_data.string_buf) - 1);
2652 
2653 	char buffer[256];
2654 	int ret;
2655 
2656 	/* Encode the data */
2657 	ret = json_obj_encode_buf(escape_test_descr, ARRAY_SIZE(escape_test_descr), &test_data,
2658 				  buffer, sizeof(buffer));
2659 	zassert_equal(ret, 0, "Encoding failed");
2660 
2661 	/* Verify the encoded JSON contains escaped quotes */
2662 	zassert_not_null(strstr(buffer, "\\\""), "Quotes not properly escaped in JSON output");
2663 
2664 	/* The encoded JSON should NOT contain the pattern: "... "..." (unescaped quotes in content)
2665 	 * Look for the specific escaped quote pattern
2666 	 */
2667 	const char *escaped_quote = strstr(buffer, "\\\"");
2668 
2669 	zassert_not_null(escaped_quote, "No escaped quotes found in encoded JSON");
2670 
2671 	/* Make sure we found at least 2 escaped quotes (one for each field) */
2672 	const char *second_escaped_quote = strstr(escaped_quote + 1, "\\\"");
2673 
2674 	zassert_not_null(second_escaped_quote, "Should have multiple escaped quotes in JSON");
2675 
2676 	/* Verify the overall structure looks correct */
2677 	zassert_not_null(strstr(buffer, "\"string_value\""), "string_value field missing");
2678 	zassert_not_null(strstr(buffer, "\"string_buf\""), "string_buf field missing");
2679 	zassert_not_null(strstr(buffer, "\"integer_value\""), "integer_value field missing");
2680 }
2681 
2682 /**
2683  * @brief Test that escaped quotes are properly unescaped during decoding
2684  */
ZTEST(lib_json_test,test_json_quote_unescaping_decoding)2685 ZTEST(lib_json_test, test_json_quote_unescaping_decoding)
2686 {
2687 	/* JSON with escaped quotes */
2688 	char encoded_json[] = "{\"string_value\":\"Text with \\\"quotes\\\" inside\","
2689 			      "\"string_buf\":\"Buffer with \\\"quotes\\\"\","
2690 			      "\"integer_value\":42}";
2691 
2692 	struct escape_test_data decoded = {0};
2693 	int ret;
2694 
2695 	/* Decode the JSON */
2696 	ret = json_obj_parse(encoded_json, strlen(encoded_json), escape_test_descr,
2697 			     ARRAY_SIZE(escape_test_descr), &decoded);
2698 	zassert_equal(ret, (1 << ARRAY_SIZE(escape_test_descr)) - 1, "Decoding failed");
2699 
2700 	/* Verify quotes are properly unescaped */
2701 	zassert_str_equal(decoded.string_value, "Text with \"quotes\" inside",
2702 			  "Quotes not properly unescaped in string_value");
2703 	zassert_str_equal(decoded.string_buf, "Buffer with \"quotes\"",
2704 			  "Quotes not properly unescaped in string_buf");
2705 }
2706 
2707 /**
2708  * @brief Test complete round-trip: quote -> escaped -> unescaped -> original
2709  */
ZTEST(lib_json_test,test_json_quote_round_trip)2710 ZTEST(lib_json_test, test_json_quote_round_trip)
2711 {
2712 	struct escape_test_data original = {
2713 		.string_value = "Start \"middle\" end",
2714 		.integer_value = 123,
2715 	};
2716 	strncpy(original.string_buf, "Quote: \"test\" here", sizeof(original.string_buf) - 1);
2717 
2718 	char buffer[256];
2719 	struct escape_test_data decoded = {0};
2720 	int ret;
2721 
2722 	/* Encode (quotes should become \") */
2723 	ret = json_obj_encode_buf(escape_test_descr, ARRAY_SIZE(escape_test_descr), &original,
2724 				  buffer, sizeof(buffer));
2725 	zassert_equal(ret, 0, "Encoding failed");
2726 
2727 	/* Verify encoding produced escaped quotes */
2728 	zassert_not_null(strstr(buffer, "\\\""), "Quotes not escaped in encoding");
2729 
2730 	/* Decode (\" should become ") */
2731 	ret = json_obj_parse(buffer, strlen(buffer), escape_test_descr,
2732 			     ARRAY_SIZE(escape_test_descr), &decoded);
2733 	zassert_equal(ret, (1 << ARRAY_SIZE(escape_test_descr)) - 1, "Decoding failed");
2734 
2735 	/* Verify we get back the original strings */
2736 	zassert_str_equal(decoded.string_value, original.string_value,
2737 			  "Quote round-trip failed for string_value");
2738 	zassert_str_equal(decoded.string_buf, original.string_buf,
2739 			  "Quote round-trip failed for string_buf");
2740 }
2741 
2742 /**
2743  * @brief Test that backslashes don't get duplicated in quote escaping
2744  */
ZTEST(lib_json_test,test_json_quote_no_backslash_duplication)2745 ZTEST(lib_json_test, test_json_quote_no_backslash_duplication)
2746 {
2747 	struct escape_test_data test_data = {
2748 		.string_value = "Text\"with\"quotes",
2749 		.integer_value = 1,
2750 	};
2751 	strncpy(test_data.string_buf, "More\"quotes\"here", sizeof(test_data.string_buf) - 1);
2752 
2753 	char buffer1[256], buffer2[256];
2754 	struct escape_test_data decoded1 = {0}, decoded2 = {0};
2755 	int ret;
2756 
2757 	/* First encode/decode cycle */
2758 	ret = json_obj_encode_buf(escape_test_descr, ARRAY_SIZE(escape_test_descr), &test_data,
2759 				  buffer1, sizeof(buffer1));
2760 	zassert_equal(ret, 0, "First encode failed");
2761 
2762 	ret = json_obj_parse(buffer1, strlen(buffer1), escape_test_descr,
2763 			     ARRAY_SIZE(escape_test_descr), &decoded1);
2764 	zassert_equal(ret, (1 << ARRAY_SIZE(escape_test_descr)) - 1, "First decode failed");
2765 
2766 	/* Second encode/decode cycle */
2767 	ret = json_obj_encode_buf(escape_test_descr, ARRAY_SIZE(escape_test_descr), &decoded1,
2768 				  buffer2, sizeof(buffer2));
2769 	zassert_equal(ret, 0, "Second encode failed");
2770 
2771 	ret = json_obj_parse(buffer2, strlen(buffer2), escape_test_descr,
2772 			     ARRAY_SIZE(escape_test_descr), &decoded2);
2773 	zassert_equal(ret, (1 << ARRAY_SIZE(escape_test_descr)) - 1, "Second decode failed");
2774 
2775 	/* Critical: No backslash duplication should occur */
2776 	zassert_str_equal(decoded1.string_value, decoded2.string_value,
2777 			  "Backslash duplication detected in string_value after quote handling");
2778 	zassert_str_equal(decoded1.string_buf, decoded2.string_buf,
2779 			  "Backslash duplication detected in string_buf after quote handling");
2780 
2781 	/* Verify original content is preserved */
2782 	zassert_str_equal(test_data.string_value, decoded2.string_value,
2783 			  "Original string with quotes not preserved");
2784 	zassert_str_equal(test_data.string_buf, decoded2.string_buf,
2785 			  "Original string buffer with quotes not preserved");
2786 }
2787 
2788 /**
2789  * @brief Test mixed escape sequences including quotes
2790  */
ZTEST(lib_json_test,test_json_mixed_escape_sequences_with_quotes)2791 ZTEST(lib_json_test, test_json_mixed_escape_sequences_with_quotes)
2792 {
2793 	struct escape_test_data test_data = {
2794 		.string_value = "Line1\nTab\tQuote\"End",
2795 		.integer_value = 999,
2796 	};
2797 	strncpy(test_data.string_buf, "Mix\n\t\"\\chars", sizeof(test_data.string_buf) - 1);
2798 
2799 	char buffer[256];
2800 	struct escape_test_data decoded = {0};
2801 	int ret;
2802 
2803 	/* Encode */
2804 	ret = json_obj_encode_buf(escape_test_descr, ARRAY_SIZE(escape_test_descr), &test_data,
2805 				  buffer, sizeof(buffer));
2806 	zassert_equal(ret, 0, "Encoding failed");
2807 
2808 	/* Verify all escape sequences are present in encoded form */
2809 	zassert_not_null(strstr(buffer, "\\n"), "Newline not escaped");
2810 	zassert_not_null(strstr(buffer, "\\t"), "Tab not escaped");
2811 	zassert_not_null(strstr(buffer, "\\\""), "Quote not escaped");
2812 	zassert_not_null(strstr(buffer, "\\\\"), "Backslash not escaped");
2813 
2814 	/* Decode */
2815 	ret = json_obj_parse(buffer, strlen(buffer), escape_test_descr,
2816 			     ARRAY_SIZE(escape_test_descr), &decoded);
2817 	zassert_equal(ret, (1 << ARRAY_SIZE(escape_test_descr)) - 1, "Decoding failed");
2818 
2819 	/* Verify all sequences are properly unescaped */
2820 	zassert_str_equal(decoded.string_value, "Line1\nTab\tQuote\"End",
2821 			  "Mixed escape sequences corrupted in string_value");
2822 	zassert_str_equal(decoded.string_buf, "Mix\n\t\"\\chars",
2823 			  "Mixed escape sequences corrupted in string_buf");
2824 }
2825 
2826 /**
2827  * @brief Test multiple cycles with quotes to detect gradual corruption
2828  */
ZTEST(lib_json_test,test_json_quote_multiple_cycle_stability)2829 ZTEST(lib_json_test, test_json_quote_multiple_cycle_stability)
2830 {
2831 	struct escape_test_data original = {
2832 		.string_value = "Config\"value\"here",
2833 		.integer_value = 50,
2834 	};
2835 	strncpy(original.string_value, "Config\"value\"here", sizeof(original.string_value) - 1);
2836 	strncpy(original.string_buf, "Setting\"name\"value", sizeof(original.string_buf) - 1);
2837 
2838 	char buffer[256];
2839 	struct escape_test_data current = {0};
2840 	int ret;
2841 
2842 	/* Initialize current by copying from original */
2843 	current.integer_value = original.integer_value;
2844 	strncpy(current.string_value, original.string_value, sizeof(current.string_value));
2845 	strncpy(current.string_buf, original.string_buf, sizeof(current.string_buf));
2846 
2847 	/* Run multiple encode/decode cycles */
2848 	for (int cycle = 0; cycle < 3; cycle++) {
2849 		/* Encode */
2850 		ret = json_obj_encode_buf(escape_test_descr, ARRAY_SIZE(escape_test_descr),
2851 					  &current, buffer, sizeof(buffer));
2852 		zassert_equal(ret, 0, "Encoding failed at cycle %d", cycle);
2853 
2854 		/* Decode into fresh struct */
2855 		struct escape_test_data next = {0};
2856 
2857 		ret = json_obj_parse(buffer, strlen(buffer), escape_test_descr,
2858 				     ARRAY_SIZE(escape_test_descr), &next);
2859 		zassert_equal(ret, (1 << ARRAY_SIZE(escape_test_descr)) - 1,
2860 			      "Decoding failed at cycle %d", cycle);
2861 
2862 		/* Verify no corruption of quotes */
2863 		zassert_str_equal(next.string_value, original.string_value,
2864 				  "Quote string corrupted after %d cycles", cycle + 1);
2865 		zassert_str_equal(next.string_buf, original.string_buf,
2866 				  "Quote string buffer corrupted after %d cycles", cycle + 1);
2867 
2868 		/* Prepare for next cycle */
2869 		current.integer_value = next.integer_value;
2870 		strncpy(current.string_value, next.string_value, sizeof(current.string_value));
2871 		strncpy(current.string_buf, next.string_buf, sizeof(current.string_buf));
2872 		current.integer_value++; /* Change integer to simulate config updates */
2873 	}
2874 }
2875 
2876 /**
2877  * @brief Test edge case: string containing only a quote
2878  */
ZTEST(lib_json_test,test_json_single_quote_string)2879 ZTEST(lib_json_test, test_json_single_quote_string)
2880 {
2881 	struct escape_test_data test_data = {
2882 		.string_value = "\"",
2883 		.integer_value = 1,
2884 	};
2885 	strncpy(test_data.string_buf, "\"", sizeof(test_data.string_buf) - 1);
2886 
2887 	char buffer[256];
2888 	struct escape_test_data decoded = {0};
2889 	int ret;
2890 
2891 	/* Encode */
2892 	ret = json_obj_encode_buf(escape_test_descr, ARRAY_SIZE(escape_test_descr), &test_data,
2893 				  buffer, sizeof(buffer));
2894 	zassert_equal(ret, 0, "Encoding single quote failed");
2895 
2896 	/* Should contain escaped quote */
2897 	zassert_not_null(strstr(buffer, "\\\""), "Single quote not escaped");
2898 
2899 	/* Decode */
2900 	ret = json_obj_parse(buffer, strlen(buffer), escape_test_descr,
2901 			     ARRAY_SIZE(escape_test_descr), &decoded);
2902 	zassert_equal(ret, (1 << ARRAY_SIZE(escape_test_descr)) - 1,
2903 		      "Decoding single quote failed");
2904 
2905 	/* Should get back the single quote */
2906 	zassert_str_equal(decoded.string_value, "\"", "Single quote not preserved");
2907 	zassert_str_equal(decoded.string_buf, "\"", "Single quote in buffer not preserved");
2908 }
2909 
ZTEST(lib_json_test,test_debug_string_types)2910 ZTEST(lib_json_test, test_debug_string_types)
2911 {
2912 	char encoded[] = "{\"string_value\":\"test\\nvalue\",\"string_buf\":\"buffer\\ttab\"}";
2913 	struct escape_test_data decoded = {0};
2914 
2915 	printf("=== DEBUG TEST ===\n");
2916 	printf("Input JSON: %s\n", encoded);
2917 
2918 	int ret = json_obj_parse(encoded, strlen(encoded), escape_test_descr,
2919 				 ARRAY_SIZE(escape_test_descr), &decoded);
2920 
2921 	printf("Parse result: %d\n", ret);
2922 	printf("string_value: '%s'\n", decoded.string_value);
2923 	printf("string_buf: '%s'\n", decoded.string_buf);
2924 	printf("=== END DEBUG ===\n");
2925 
2926 	zassert_str_equal(decoded.string_value, "test\nvalue", "string_value not unescaped");
2927 	zassert_str_equal(decoded.string_buf, "buffer\ttab", "string_buf not unescaped");
2928 }
2929 
2930 ZTEST_SUITE(lib_json_test, NULL, NULL, NULL, NULL, NULL);
2931